4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2011, 2012, Intel Corporation.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * lustre/utils/lustre_cfg.c
38 * Author: Peter J. Braam <braam@clusterfs.com>
39 * Author: Phil Schwan <phil@clusterfs.com>
40 * Author: Andreas Dilger <adilger@clusterfs.com>
41 * Author: Robert Read <rread@clusterfs.com>
45 #include <sys/ioctl.h>
53 #include <liblustre.h>
55 #include <lustre_lib.h>
56 #include <lustre_cfg.h>
57 #include <lustre/lustre_idl.h>
58 #include <lustre_dlm.h>
59 #include <obd.h> /* for struct lov_stripe_md */
61 #include <lustre/lustre_build_version.h>
72 #include <lnet/lnetctl.h>
73 #include <libcfs/libcfsutil.h>
76 static char * lcfg_devname;
78 int lcfg_set_devname(char *name)
86 /* quietly strip the unnecessary '$' */
87 if (*name == '$' || *name == '%')
91 while (*ptr != '\0') {
100 /* We can't translate from dev # to name */
103 lcfg_devname = strdup(name);
111 char * lcfg_get_devname(void)
116 int jt_lcfg_device(int argc, char **argv)
118 return jt_obd_device(argc, argv);
121 int jt_lcfg_attach(int argc, char **argv)
123 struct lustre_cfg_bufs bufs;
124 struct lustre_cfg *lcfg;
130 lustre_cfg_bufs_reset(&bufs, NULL);
132 lustre_cfg_bufs_set_string(&bufs, 1, argv[1]);
133 lustre_cfg_bufs_set_string(&bufs, 0, argv[2]);
134 lustre_cfg_bufs_set_string(&bufs, 2, argv[3]);
136 lcfg = lustre_cfg_new(LCFG_ATTACH, &bufs);
137 rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
138 lustre_cfg_free(lcfg);
140 fprintf(stderr, "error: %s: LCFG_ATTACH %s\n",
141 jt_cmdname(argv[0]), strerror(rc = errno));
143 lcfg_set_devname(argv[2]);
149 int jt_lcfg_setup(int argc, char **argv)
151 struct lustre_cfg_bufs bufs;
152 struct lustre_cfg *lcfg;
156 if (lcfg_devname == NULL) {
157 fprintf(stderr, "%s: please use 'device name' to set the "
158 "device name for config commands.\n",
159 jt_cmdname(argv[0]));
163 lustre_cfg_bufs_reset(&bufs, lcfg_devname);
168 for (i = 1; i < argc; i++) {
169 lustre_cfg_bufs_set_string(&bufs, i, argv[i]);
172 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
173 rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
174 lustre_cfg_free(lcfg);
176 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
177 strerror(rc = errno));
182 int jt_obd_detach(int argc, char **argv)
184 struct lustre_cfg_bufs bufs;
185 struct lustre_cfg *lcfg;
188 if (lcfg_devname == NULL) {
189 fprintf(stderr, "%s: please use 'device name' to set the "
190 "device name for config commands.\n",
191 jt_cmdname(argv[0]));
195 lustre_cfg_bufs_reset(&bufs, lcfg_devname);
200 lcfg = lustre_cfg_new(LCFG_DETACH, &bufs);
201 rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
202 lustre_cfg_free(lcfg);
204 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
205 strerror(rc = errno));
210 int jt_obd_cleanup(int argc, char **argv)
212 struct lustre_cfg_bufs bufs;
213 struct lustre_cfg *lcfg;
216 char flags[3] = { 0 };
220 if (lcfg_devname == NULL) {
221 fprintf(stderr, "%s: please use 'device name' to set the "
222 "device name for config commands.\n",
223 jt_cmdname(argv[0]));
227 lustre_cfg_bufs_reset(&bufs, lcfg_devname);
229 if (argc < 1 || argc > 3)
232 /* we are protected from overflowing our buffer by the argc
235 for (n = 1; n < argc; n++) {
236 if (strcmp(argv[n], "force") == 0) {
237 flags[flag_cnt++] = force;
238 } else if (strcmp(argv[n], "failover") == 0) {
239 flags[flag_cnt++] = failover;
241 fprintf(stderr, "unknown option: %s", argv[n]);
247 lustre_cfg_bufs_set_string(&bufs, 1, flags);
250 lcfg = lustre_cfg_new(LCFG_CLEANUP, &bufs);
251 rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
252 lustre_cfg_free(lcfg);
254 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
255 strerror(rc = errno));
261 int do_add_uuid(char * func, char *uuid, lnet_nid_t nid)
264 struct lustre_cfg_bufs bufs;
265 struct lustre_cfg *lcfg;
267 lustre_cfg_bufs_reset(&bufs, lcfg_devname);
269 lustre_cfg_bufs_set_string(&bufs, 1, uuid);
271 lcfg = lustre_cfg_new(LCFG_ADD_UUID, &bufs);
272 lcfg->lcfg_nid = nid;
273 /* Poison NAL -- pre 1.4.6 will LASSERT on 0 NAL, this way it
274 doesn't work without crashing (bz 10130) */
275 lcfg->lcfg_nal = 0x5a;
278 fprintf(stderr, "adding\tnid: %d\tuuid: %s\n",
279 lcfg->lcfg_nid, uuid);
281 rc = lcfg_ioctl(func, OBD_DEV_ID, lcfg);
282 lustre_cfg_free(lcfg);
284 fprintf(stderr, "IOC_PORTAL_ADD_UUID failed: %s\n",
289 printf ("Added uuid %s: %s\n", uuid, libcfs_nid2str(nid));
293 int jt_lcfg_add_uuid(int argc, char **argv)
301 nid = libcfs_str2nid(argv[2]);
302 if (nid == LNET_NID_ANY) {
303 fprintf (stderr, "Can't parse NID %s\n", argv[2]);
307 return do_add_uuid(argv[0], argv[1], nid);
310 int obd_add_uuid(char *uuid, lnet_nid_t nid)
312 return do_add_uuid("obd_add_uuid", uuid, nid);
315 int jt_lcfg_del_uuid(int argc, char **argv)
318 struct lustre_cfg_bufs bufs;
319 struct lustre_cfg *lcfg;
322 fprintf(stderr, "usage: %s <uuid>\n", argv[0]);
326 lustre_cfg_bufs_reset(&bufs, lcfg_devname);
327 if (strcmp (argv[1], "_all_"))
328 lustre_cfg_bufs_set_string(&bufs, 1, argv[1]);
330 lcfg = lustre_cfg_new(LCFG_DEL_UUID, &bufs);
331 rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
332 lustre_cfg_free(lcfg);
334 fprintf(stderr, "IOC_PORTAL_DEL_UUID failed: %s\n",
341 int jt_lcfg_del_mount_option(int argc, char **argv)
344 struct lustre_cfg_bufs bufs;
345 struct lustre_cfg *lcfg;
350 lustre_cfg_bufs_reset(&bufs, lcfg_devname);
353 lustre_cfg_bufs_set_string(&bufs, 1, argv[1]);
355 lcfg = lustre_cfg_new(LCFG_DEL_MOUNTOPT, &bufs);
356 rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
357 lustre_cfg_free(lcfg);
359 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
360 strerror(rc = errno));
365 int jt_lcfg_set_timeout(int argc, char **argv)
368 struct lustre_cfg_bufs bufs;
369 struct lustre_cfg *lcfg;
371 fprintf(stderr, "%s has been deprecated. Use conf_param instead.\n"
372 "e.g. conf_param lustre-MDT0000 obd_timeout=50\n",
373 jt_cmdname(argv[0]));
380 lustre_cfg_bufs_reset(&bufs, lcfg_devname);
381 lcfg = lustre_cfg_new(LCFG_SET_TIMEOUT, &bufs);
382 lcfg->lcfg_num = atoi(argv[1]);
384 rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
385 //rc = lcfg_mgs_ioctl(argv[0], OBD_DEV_ID, lcfg);
387 lustre_cfg_free(lcfg);
389 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
390 strerror(rc = errno));
395 int jt_lcfg_add_conn(int argc, char **argv)
397 struct lustre_cfg_bufs bufs;
398 struct lustre_cfg *lcfg;
409 if (lcfg_devname == NULL) {
410 fprintf(stderr, "%s: please use 'device name' to set the "
411 "device name for config commands.\n",
412 jt_cmdname(argv[0]));
416 lustre_cfg_bufs_reset(&bufs, lcfg_devname);
418 lustre_cfg_bufs_set_string(&bufs, 1, argv[1]);
420 lcfg = lustre_cfg_new(LCFG_ADD_CONN, &bufs);
421 lcfg->lcfg_num = priority;
423 rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
424 lustre_cfg_free (lcfg);
426 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
427 strerror(rc = errno));
433 int jt_lcfg_del_conn(int argc, char **argv)
435 struct lustre_cfg_bufs bufs;
436 struct lustre_cfg *lcfg;
442 if (lcfg_devname == NULL) {
443 fprintf(stderr, "%s: please use 'device name' to set the "
444 "device name for config commands.\n",
445 jt_cmdname(argv[0]));
449 lustre_cfg_bufs_reset(&bufs, lcfg_devname);
451 /* connection uuid */
452 lustre_cfg_bufs_set_string(&bufs, 1, argv[1]);
454 lcfg = lustre_cfg_new(LCFG_DEL_MOUNTOPT, &bufs);
456 rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
457 lustre_cfg_free(lcfg);
459 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
460 strerror(rc = errno));
466 /* Param set locally, directly on target */
467 int jt_lcfg_param(int argc, char **argv)
470 struct lustre_cfg_bufs bufs;
471 struct lustre_cfg *lcfg;
473 if (argc >= LUSTRE_CFG_MAX_BUFCOUNT)
476 lustre_cfg_bufs_reset(&bufs, NULL);
478 for (i = 1; i < argc; i++) {
479 lustre_cfg_bufs_set_string(&bufs, i, argv[i]);
482 lcfg = lustre_cfg_new(LCFG_PARAM, &bufs);
484 rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
485 lustre_cfg_free(lcfg);
487 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
488 strerror(rc = errno));
494 unsigned int po_only_path:1;
495 unsigned int po_show_path:1;
496 unsigned int po_show_type:1;
497 unsigned int po_recursive:1;
498 unsigned int po_params2:1;
499 unsigned int po_delete:1;
502 /* Param set to single log file, used by all clients and servers.
503 * This should be loaded after the individual config logs.
504 * Called from set param with -P option.
506 static int jt_lcfg_mgsparam2(int argc, char **argv, struct param_opts *popt)
510 struct lustre_cfg_bufs bufs;
511 struct lustre_cfg *lcfg;
515 first_param = optind;
516 if (first_param < 0 || first_param >= argc)
519 for (i = first_param, rc = 0; i < argc; i++) {
520 lustre_cfg_bufs_reset(&bufs, NULL);
521 /* This same command would be executed on all nodes, many
522 * of which should fail (silently) because they don't have
523 * that proc file existing locally. There would be no
524 * preprocessing on the MGS to try to figure out which
525 * parameter files to add this to, there would be nodes
526 * processing on the cluster nodes to try to figure out
527 * if they are the intended targets. They will blindly
528 * try to set the parameter, and ENOTFOUND means it wasn't
530 * Target name "general" means call on all targets. It is
531 * left here in case some filtering will be added in
534 lustre_cfg_bufs_set_string(&bufs, 0, "general");
536 len = strlen(argv[i]);
538 /* put an '=' on the end in case it doesn't have one */
539 if (popt->po_delete && argv[i][len - 1] != '=') {
540 buf = malloc(len + 1);
541 sprintf(buf, "%s=", argv[i]);
545 lustre_cfg_bufs_set_string(&bufs, 1, buf);
547 lcfg = lustre_cfg_new(LCFG_SET_PARAM, &bufs);
549 fprintf(stderr, "error: allocating lcfg for %s: %s\n",
550 jt_cmdname(argv[0]), strerror(PTR_ERR(lcfg)));
554 int rc2 = lcfg_mgs_ioctl(argv[0], OBD_DEV_ID, lcfg);
556 fprintf(stderr, "error: executing %s: %s\n",
557 jt_cmdname(argv[0]), strerror(errno));
561 lustre_cfg_free(lcfg);
570 /* Param set in config log on MGS */
571 /* conf_param key=value */
572 /* Note we can actually send mgc conf_params from clients, but currently
573 * that's only done for default file striping (see ll_send_mgc_param),
575 /* After removal of a parameter (-d) Lustre will use the default
576 * AT NEXT REBOOT, not immediately. */
577 int jt_lcfg_mgsparam(int argc, char **argv)
581 struct lustre_cfg_bufs bufs;
582 struct lustre_cfg *lcfg;
585 #if LUSTRE_VERSION >= OBD_OCD_VERSION(2,7,53,0)
586 fprintf(stderr, "warning: 'lctl conf_param' is deprecated, "
587 "use 'lctl set_param -P' instead\n");
590 /* mgs_setparam processes only lctl buf #1 */
591 if ((argc > 3) || (argc <= 1))
594 while ((rc = getopt(argc, argv, "d")) != -1) {
604 lustre_cfg_bufs_reset(&bufs, NULL);
608 /* for delete, make it "<param>=\0" */
609 buf = malloc(strlen(argv[optind]) + 2);
610 /* put an '=' on the end in case it doesn't have one */
611 sprintf(buf, "%s=", argv[optind]);
612 /* then truncate after the first '=' */
613 ptr = strchr(buf, '=');
615 lustre_cfg_bufs_set_string(&bufs, 1, buf);
617 lustre_cfg_bufs_set_string(&bufs, 1, argv[optind]);
620 /* We could put other opcodes here. */
621 lcfg = lustre_cfg_new(LCFG_PARAM, &bufs);
623 rc = lcfg_mgs_ioctl(argv[0], OBD_DEV_ID, lcfg);
624 lustre_cfg_free(lcfg);
628 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
629 strerror(rc = errno));
635 /* Display the path in the same format as sysctl
636 * For eg. obdfilter.lustre-OST0000.stats */
637 static char *display_name(char *filename, unsigned int po_show_type)
643 if (lstat(filename, &st) < 0)
647 filename += strlen("/proc/");
648 if (strncmp(filename, "fs/", strlen("fs/")) == 0)
649 filename += strlen("fs/");
651 filename += strlen("sys/");
653 if (strncmp(filename, "lustre/", strlen("lustre/")) == 0)
654 filename += strlen("lustre/");
655 else if (strncmp(filename, "lnet/", strlen("lnet/")) == 0)
656 filename += strlen("lnet/");
658 /* replace '/' with '.' to match conf_param and sysctl */
660 while ((tmp = strchr(tmp, '/')) != NULL)
663 /* append the indicator to entries */
665 if (S_ISDIR(st.st_mode))
666 strcat(filename, "/");
667 else if (S_ISLNK(st.st_mode))
668 strcat(filename, "@");
669 else if (st.st_mode & S_IWUSR)
670 strcat(filename, "=");
676 /* Find a character in a length limited string */
677 /* BEWARE - kernel definition of strnchr has args in different order! */
678 static char *strnchr(const char *p, char c, size_t n)
691 static char *globerrstr(int glob_rc)
695 return "Out of memory";
699 return "Found no match";
701 return "Unknown error";
704 static void clean_path(char *path)
708 /* If the input is in form Eg. obdfilter.*.stats */
709 if (strchr(path, '.')) {
711 while (*tmp != '\0') {
713 (tmp != path) && (*(tmp - 1) != '\\'))
718 /* get rid of '\', glob doesn't like it */
719 if ((tmp = strrchr(path, '\\')) != NULL) {
720 char *tail = path + strlen(path);
721 while (tmp != path) {
723 memmove(tmp, tmp + 1, tail - tmp);
731 /* Supporting file paths creates perilous behavoir: LU-888.
732 * Path support is deprecated.
733 * If a path is supplied it must begin with /proc. */
734 static void lprocfs_param_pattern(const char *cmd, const char *path, char *buf,
737 /* test path to see if it begins with '/proc/' */
738 if (strncmp(path, "/proc/", strlen("/proc/")) == 0) {
741 fprintf(stderr, "%s: specifying parameters via "
742 "full paths is deprecated.\n", cmd);
743 #if LUSTRE_VERSION_CODE >= OBD_OCD_VERSION(2, 6, 50, 0)
744 #warning "remove deprecated full path tunable access"
748 snprintf(buf, buf_size, "%s", path);
750 snprintf(buf, buf_size, "/proc/{fs,sys}/{lnet,lustre}/%s",
755 static int listparam_cmdline(int argc, char **argv, struct param_opts *popt)
759 popt->po_show_path = 1;
760 popt->po_only_path = 1;
761 popt->po_show_type = 0;
762 popt->po_recursive = 0;
764 while ((ch = getopt(argc, argv, "FR")) != -1) {
767 popt->po_show_type = 1;
770 popt->po_recursive = 1;
780 static int listparam_display(struct param_opts *popt, char *pattern)
785 char filename[PATH_MAX + 1]; /* extra 1 byte for file type */
787 rc = glob(pattern, GLOB_BRACE | (popt->po_recursive ? GLOB_MARK : 0),
790 fprintf(stderr, "error: list_param: %s: %s\n",
791 pattern, globerrstr(rc));
795 for (i = 0; i < glob_info.gl_pathc; i++) {
796 char *valuename = NULL;
799 /* Trailing '/' will indicate recursion into directory */
800 last = strlen(glob_info.gl_pathv[i]) - 1;
802 /* Remove trailing '/' or it will be converted to '.' */
803 if (last > 0 && glob_info.gl_pathv[i][last] == '/')
804 glob_info.gl_pathv[i][last] = '\0';
807 strcpy(filename, glob_info.gl_pathv[i]);
808 valuename = display_name(filename, popt->po_show_type);
810 printf("%s\n", valuename);
812 strcpy(filename, glob_info.gl_pathv[i]);
813 strcat(filename, "/*");
814 listparam_display(popt, filename);
818 globfree(&glob_info);
822 int jt_lcfg_listparam(int argc, char **argv)
825 struct param_opts popt;
826 char pattern[PATH_MAX];
829 rc = listparam_cmdline(argc, argv, &popt);
830 if (rc == argc && popt.po_recursive) {
831 rc--; /* we know at least "-R" is a parameter */
833 } else if (rc < 0 || rc >= argc) {
837 for (i = rc; i < argc; i++) {
842 lprocfs_param_pattern(argv[0], path, pattern, sizeof(pattern));
844 rc = listparam_display(&popt, pattern);
852 static int getparam_cmdline(int argc, char **argv, struct param_opts *popt)
856 popt->po_show_path = 1;
857 popt->po_only_path = 0;
858 popt->po_show_type = 0;
859 popt->po_recursive = 0;
861 while ((ch = getopt(argc, argv, "nNF")) != -1) {
864 popt->po_only_path = 1;
867 popt->po_show_path = 0;
869 popt->po_show_type = 1;
879 static int getparam_display(struct param_opts *popt, char *pattern)
886 char filename[PATH_MAX + 1]; /* extra 1 byte for file type */
888 rc = glob(pattern, GLOB_BRACE, NULL, &glob_info);
890 fprintf(stderr, "error: get_param: %s: %s\n",
891 pattern, globerrstr(rc));
895 buf = malloc(PAGE_CACHE_SIZE);
896 for (i = 0; i < glob_info.gl_pathc; i++) {
897 char *valuename = NULL;
899 memset(buf, 0, PAGE_CACHE_SIZE);
900 /* As listparam_display is used to show param name (with type),
901 * here "if (only_path)" is ignored.*/
902 if (popt->po_show_path) {
903 if (strlen(glob_info.gl_pathv[i]) >
904 sizeof(filename)-1) {
908 strncpy(filename, glob_info.gl_pathv[i],
910 valuename = display_name(filename, 0);
913 /* Write the contents of file to stdout */
914 fd = open(glob_info.gl_pathv[i], O_RDONLY);
917 "error: get_param: opening('%s') failed: %s\n",
918 glob_info.gl_pathv[i], strerror(errno));
923 rc = read(fd, buf, PAGE_CACHE_SIZE);
927 fprintf(stderr, "error: get_param: "
928 "read('%s') failed: %s\n",
929 glob_info.gl_pathv[i], strerror(errno));
932 /* Print the output in the format path=value if the
933 * value contains no new line character or cab be
934 * occupied in a line, else print value on new line */
935 if (valuename && popt->po_show_path) {
936 int longbuf = strnchr(buf, rc - 1, '\n') != NULL
938 printf("%s=%s", valuename, longbuf ? "\n" : buf);
944 rc = write(fileno(stdout), buf, rc);
946 fprintf(stderr, "error: get_param: "
947 "write to stdout failed: %s\n",
955 globfree(&glob_info);
960 int jt_lcfg_getparam(int argc, char **argv)
963 struct param_opts popt;
964 char pattern[PATH_MAX];
967 rc = getparam_cmdline(argc, argv, &popt);
968 if (rc < 0 || rc >= argc)
971 for (i = rc, rc = 0; i < argc; i++) {
978 lprocfs_param_pattern(argv[0], path, pattern, sizeof(pattern));
980 if (popt.po_only_path)
981 rc2 = listparam_display(&popt, pattern);
983 rc2 = getparam_display(&popt, pattern);
984 if (rc2 < 0 && rc == 0)
991 static int setparam_cmdline(int argc, char **argv, struct param_opts *popt)
995 popt->po_show_path = 1;
996 popt->po_only_path = 0;
997 popt->po_show_type = 0;
998 popt->po_recursive = 0;
999 popt->po_params2 = 0;
1000 popt->po_delete = 0;
1002 while ((ch = getopt(argc, argv, "nPd")) != -1) {
1005 popt->po_show_path = 0;
1008 popt->po_params2 = 1;
1011 popt->po_delete = 1;
1020 static int setparam_display(struct param_opts *popt, char *pattern, char *value)
1026 char filename[PATH_MAX + 1]; /* extra 1 byte for file type */
1028 rc = glob(pattern, GLOB_BRACE, NULL, &glob_info);
1030 fprintf(stderr, "error: set_param: %s: %s\n",
1031 pattern, globerrstr(rc));
1034 for (i = 0; i < glob_info.gl_pathc; i++) {
1035 char *valuename = NULL;
1037 if (popt->po_show_path) {
1038 if (strlen(glob_info.gl_pathv[i]) > sizeof(filename)-1)
1040 strncpy(filename, glob_info.gl_pathv[i],
1042 valuename = display_name(filename, 0);
1044 printf("%s=%s\n", valuename, value);
1046 /* Write the new value to the file */
1047 fd = open(glob_info.gl_pathv[i], O_WRONLY);
1049 rc = write(fd, value, strlen(value));
1051 fprintf(stderr, "error: set_param: setting "
1052 "%s=%s: %s\n", glob_info.gl_pathv[i],
1053 value, strerror(errno));
1058 fprintf(stderr, "error: set_param: %s opening %s\n",
1059 strerror(rc = errno), glob_info.gl_pathv[i]);
1063 globfree(&glob_info);
1067 int jt_lcfg_setparam(int argc, char **argv)
1070 struct param_opts popt;
1071 char pattern[PATH_MAX];
1072 char *path = NULL, *value = NULL;
1074 rc = setparam_cmdline(argc, argv, &popt);
1075 if (rc < 0 || rc >= argc)
1078 if (popt.po_params2)
1079 /* We can't delete parameters that were
1080 * set with old conf_param interface */
1081 return jt_lcfg_mgsparam2(argc, argv, &popt);
1083 for (i = rc, rc = 0; i < argc; i++) {
1086 if ((value = strchr(argv[i], '=')) != NULL) {
1087 /* format: set_param a=b */
1092 /* format: set_param a b */
1103 lprocfs_param_pattern(argv[0], path, pattern, sizeof(pattern));
1105 rc2 = setparam_display(&popt, pattern, value);
1108 if (rc2 < 0 && rc == 0)