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 */
60 #include <lustre/lustre_build_version.h>
71 #include <lnet/lnetctl.h>
72 #include <libcfs/libcfsutil.h>
75 static char * lcfg_devname;
77 int lcfg_set_devname(char *name)
85 /* quietly strip the unnecessary '$' */
86 if (*name == '$' || *name == '%')
90 while (*ptr != '\0') {
99 /* We can't translate from dev # to name */
102 lcfg_devname = strdup(name);
110 char * lcfg_get_devname(void)
115 int jt_lcfg_device(int argc, char **argv)
117 return jt_obd_device(argc, argv);
120 int jt_lcfg_attach(int argc, char **argv)
122 struct lustre_cfg_bufs bufs;
123 struct lustre_cfg *lcfg;
129 lustre_cfg_bufs_reset(&bufs, NULL);
131 lustre_cfg_bufs_set_string(&bufs, 1, argv[1]);
132 lustre_cfg_bufs_set_string(&bufs, 0, argv[2]);
133 lustre_cfg_bufs_set_string(&bufs, 2, argv[3]);
135 lcfg = lustre_cfg_new(LCFG_ATTACH, &bufs);
136 rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
137 lustre_cfg_free(lcfg);
139 fprintf(stderr, "error: %s: LCFG_ATTACH %s\n",
140 jt_cmdname(argv[0]), strerror(rc = errno));
142 lcfg_set_devname(argv[2]);
148 int jt_lcfg_setup(int argc, char **argv)
150 struct lustre_cfg_bufs bufs;
151 struct lustre_cfg *lcfg;
155 if (lcfg_devname == NULL) {
156 fprintf(stderr, "%s: please use 'device name' to set the "
157 "device name for config commands.\n",
158 jt_cmdname(argv[0]));
162 lustre_cfg_bufs_reset(&bufs, lcfg_devname);
167 for (i = 1; i < argc; i++) {
168 lustre_cfg_bufs_set_string(&bufs, i, argv[i]);
171 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
172 rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
173 lustre_cfg_free(lcfg);
175 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
176 strerror(rc = errno));
181 int jt_obd_detach(int argc, char **argv)
183 struct lustre_cfg_bufs bufs;
184 struct lustre_cfg *lcfg;
187 if (lcfg_devname == NULL) {
188 fprintf(stderr, "%s: please use 'device name' to set the "
189 "device name for config commands.\n",
190 jt_cmdname(argv[0]));
194 lustre_cfg_bufs_reset(&bufs, lcfg_devname);
199 lcfg = lustre_cfg_new(LCFG_DETACH, &bufs);
200 rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
201 lustre_cfg_free(lcfg);
203 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
204 strerror(rc = errno));
209 int jt_obd_cleanup(int argc, char **argv)
211 struct lustre_cfg_bufs bufs;
212 struct lustre_cfg *lcfg;
215 char flags[3] = { 0 };
219 if (lcfg_devname == NULL) {
220 fprintf(stderr, "%s: please use 'device name' to set the "
221 "device name for config commands.\n",
222 jt_cmdname(argv[0]));
226 lustre_cfg_bufs_reset(&bufs, lcfg_devname);
228 if (argc < 1 || argc > 3)
231 /* we are protected from overflowing our buffer by the argc
234 for (n = 1; n < argc; n++) {
235 if (strcmp(argv[n], "force") == 0) {
236 flags[flag_cnt++] = force;
237 } else if (strcmp(argv[n], "failover") == 0) {
238 flags[flag_cnt++] = failover;
240 fprintf(stderr, "unknown option: %s", argv[n]);
246 lustre_cfg_bufs_set_string(&bufs, 1, flags);
249 lcfg = lustre_cfg_new(LCFG_CLEANUP, &bufs);
250 rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
251 lustre_cfg_free(lcfg);
253 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
254 strerror(rc = errno));
260 int do_add_uuid(char * func, char *uuid, lnet_nid_t nid)
263 struct lustre_cfg_bufs bufs;
264 struct lustre_cfg *lcfg;
266 lustre_cfg_bufs_reset(&bufs, lcfg_devname);
268 lustre_cfg_bufs_set_string(&bufs, 1, uuid);
270 lcfg = lustre_cfg_new(LCFG_ADD_UUID, &bufs);
271 lcfg->lcfg_nid = nid;
272 /* Poison NAL -- pre 1.4.6 will LASSERT on 0 NAL, this way it
273 doesn't work without crashing (bz 10130) */
274 lcfg->lcfg_nal = 0x5a;
277 fprintf(stderr, "adding\tnid: %d\tuuid: %s\n",
278 lcfg->lcfg_nid, uuid);
280 rc = lcfg_ioctl(func, OBD_DEV_ID, lcfg);
281 lustre_cfg_free(lcfg);
283 fprintf(stderr, "IOC_PORTAL_ADD_UUID failed: %s\n",
288 printf ("Added uuid %s: %s\n", uuid, libcfs_nid2str(nid));
292 int jt_lcfg_add_uuid(int argc, char **argv)
300 nid = libcfs_str2nid(argv[2]);
301 if (nid == LNET_NID_ANY) {
302 fprintf (stderr, "Can't parse NID %s\n", argv[2]);
306 return do_add_uuid(argv[0], argv[1], nid);
309 int obd_add_uuid(char *uuid, lnet_nid_t nid)
311 return do_add_uuid("obd_add_uuid", uuid, nid);
314 int jt_lcfg_del_uuid(int argc, char **argv)
317 struct lustre_cfg_bufs bufs;
318 struct lustre_cfg *lcfg;
321 fprintf(stderr, "usage: %s <uuid>\n", argv[0]);
325 lustre_cfg_bufs_reset(&bufs, lcfg_devname);
326 if (strcmp (argv[1], "_all_"))
327 lustre_cfg_bufs_set_string(&bufs, 1, argv[1]);
329 lcfg = lustre_cfg_new(LCFG_DEL_UUID, &bufs);
330 rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
331 lustre_cfg_free(lcfg);
333 fprintf(stderr, "IOC_PORTAL_DEL_UUID failed: %s\n",
340 int jt_lcfg_del_mount_option(int argc, char **argv)
343 struct lustre_cfg_bufs bufs;
344 struct lustre_cfg *lcfg;
349 lustre_cfg_bufs_reset(&bufs, lcfg_devname);
352 lustre_cfg_bufs_set_string(&bufs, 1, argv[1]);
354 lcfg = lustre_cfg_new(LCFG_DEL_MOUNTOPT, &bufs);
355 rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
356 lustre_cfg_free(lcfg);
358 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
359 strerror(rc = errno));
364 int jt_lcfg_set_timeout(int argc, char **argv)
367 struct lustre_cfg_bufs bufs;
368 struct lustre_cfg *lcfg;
370 fprintf(stderr, "%s has been deprecated. Use conf_param instead.\n"
371 "e.g. conf_param lustre-MDT0000 obd_timeout=50\n",
372 jt_cmdname(argv[0]));
379 lustre_cfg_bufs_reset(&bufs, lcfg_devname);
380 lcfg = lustre_cfg_new(LCFG_SET_TIMEOUT, &bufs);
381 lcfg->lcfg_num = atoi(argv[1]);
383 rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
384 //rc = lcfg_mgs_ioctl(argv[0], OBD_DEV_ID, lcfg);
386 lustre_cfg_free(lcfg);
388 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
389 strerror(rc = errno));
394 int jt_lcfg_add_conn(int argc, char **argv)
396 struct lustre_cfg_bufs bufs;
397 struct lustre_cfg *lcfg;
408 if (lcfg_devname == NULL) {
409 fprintf(stderr, "%s: please use 'device name' to set the "
410 "device name for config commands.\n",
411 jt_cmdname(argv[0]));
415 lustre_cfg_bufs_reset(&bufs, lcfg_devname);
417 lustre_cfg_bufs_set_string(&bufs, 1, argv[1]);
419 lcfg = lustre_cfg_new(LCFG_ADD_CONN, &bufs);
420 lcfg->lcfg_num = priority;
422 rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
423 lustre_cfg_free (lcfg);
425 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
426 strerror(rc = errno));
432 int jt_lcfg_del_conn(int argc, char **argv)
434 struct lustre_cfg_bufs bufs;
435 struct lustre_cfg *lcfg;
441 if (lcfg_devname == NULL) {
442 fprintf(stderr, "%s: please use 'device name' to set the "
443 "device name for config commands.\n",
444 jt_cmdname(argv[0]));
448 lustre_cfg_bufs_reset(&bufs, lcfg_devname);
450 /* connection uuid */
451 lustre_cfg_bufs_set_string(&bufs, 1, argv[1]);
453 lcfg = lustre_cfg_new(LCFG_DEL_MOUNTOPT, &bufs);
455 rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
456 lustre_cfg_free(lcfg);
458 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
459 strerror(rc = errno));
465 /* Param set locally, directly on target */
466 int jt_lcfg_param(int argc, char **argv)
469 struct lustre_cfg_bufs bufs;
470 struct lustre_cfg *lcfg;
472 if (argc >= LUSTRE_CFG_MAX_BUFCOUNT)
475 lustre_cfg_bufs_reset(&bufs, NULL);
477 for (i = 1; i < argc; i++) {
478 lustre_cfg_bufs_set_string(&bufs, i, argv[i]);
481 lcfg = lustre_cfg_new(LCFG_PARAM, &bufs);
483 rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg);
484 lustre_cfg_free(lcfg);
486 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
487 strerror(rc = errno));
493 unsigned int po_only_path:1;
494 unsigned int po_show_path:1;
495 unsigned int po_show_type:1;
496 unsigned int po_recursive:1;
497 unsigned int po_params2:1;
498 unsigned int po_delete:1;
501 /* Param set to single log file, used by all clients and servers.
502 * This should be loaded after the individual config logs.
503 * Called from set param with -P option.
505 static int jt_lcfg_mgsparam2(int argc, char **argv, struct param_opts *popt)
509 struct lustre_cfg_bufs bufs;
510 struct lustre_cfg *lcfg;
514 first_param = optind;
515 if (first_param < 0 || first_param >= argc)
518 for (i = first_param, rc = 0; i < argc; i++) {
519 lustre_cfg_bufs_reset(&bufs, NULL);
520 /* This same command would be executed on all nodes, many
521 * of which should fail (silently) because they don't have
522 * that proc file existing locally. There would be no
523 * preprocessing on the MGS to try to figure out which
524 * parameter files to add this to, there would be nodes
525 * processing on the cluster nodes to try to figure out
526 * if they are the intended targets. They will blindly
527 * try to set the parameter, and ENOTFOUND means it wasn't
529 * Target name "general" means call on all targets. It is
530 * left here in case some filtering will be added in
533 lustre_cfg_bufs_set_string(&bufs, 0, "general");
535 len = strlen(argv[i]);
537 /* put an '=' on the end in case it doesn't have one */
538 if (popt->po_delete && argv[i][len - 1] != '=') {
539 buf = malloc(len + 1);
540 sprintf(buf, "%s=", argv[i]);
544 lustre_cfg_bufs_set_string(&bufs, 1, buf);
546 lcfg = lustre_cfg_new(LCFG_SET_PARAM, &bufs);
548 fprintf(stderr, "error: allocating lcfg for %s: %s\n",
549 jt_cmdname(argv[0]), strerror(PTR_ERR(lcfg)));
553 int rc2 = lcfg_mgs_ioctl(argv[0], OBD_DEV_ID, lcfg);
555 fprintf(stderr, "error: executing %s: %s\n",
556 jt_cmdname(argv[0]), strerror(errno));
560 lustre_cfg_free(lcfg);
569 /* Param set in config log on MGS */
570 /* conf_param key=value */
571 /* Note we can actually send mgc conf_params from clients, but currently
572 * that's only done for default file striping (see ll_send_mgc_param),
574 /* After removal of a parameter (-d) Lustre will use the default
575 * AT NEXT REBOOT, not immediately. */
576 int jt_lcfg_mgsparam(int argc, char **argv)
580 struct lustre_cfg_bufs bufs;
581 struct lustre_cfg *lcfg;
584 #if LUSTRE_VERSION_CODE >= OBD_OCD_VERSION(2, 7, 53, 0)
585 fprintf(stderr, "warning: 'lctl conf_param' is deprecated, "
586 "use 'lctl set_param -P' instead\n");
589 /* mgs_setparam processes only lctl buf #1 */
590 if ((argc > 3) || (argc <= 1))
593 while ((rc = getopt(argc, argv, "d")) != -1) {
603 lustre_cfg_bufs_reset(&bufs, NULL);
607 /* for delete, make it "<param>=\0" */
608 buf = malloc(strlen(argv[optind]) + 2);
609 /* put an '=' on the end in case it doesn't have one */
610 sprintf(buf, "%s=", argv[optind]);
611 /* then truncate after the first '=' */
612 ptr = strchr(buf, '=');
614 lustre_cfg_bufs_set_string(&bufs, 1, buf);
616 lustre_cfg_bufs_set_string(&bufs, 1, argv[optind]);
619 /* We could put other opcodes here. */
620 lcfg = lustre_cfg_new(LCFG_PARAM, &bufs);
622 rc = lcfg_mgs_ioctl(argv[0], OBD_DEV_ID, lcfg);
623 lustre_cfg_free(lcfg);
627 fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
628 strerror(rc = errno));
634 /* Display the path in the same format as sysctl
635 * For eg. obdfilter.lustre-OST0000.stats */
636 static char *display_name(char *filename, unsigned int po_show_type)
642 if (lstat(filename, &st) < 0)
646 filename += strlen("/proc/");
647 if (strncmp(filename, "fs/", strlen("fs/")) == 0)
648 filename += strlen("fs/");
650 filename += strlen("sys/");
652 if (strncmp(filename, "lustre/", strlen("lustre/")) == 0)
653 filename += strlen("lustre/");
654 else if (strncmp(filename, "lnet/", strlen("lnet/")) == 0)
655 filename += strlen("lnet/");
657 /* replace '/' with '.' to match conf_param and sysctl */
659 while ((tmp = strchr(tmp, '/')) != NULL)
662 /* append the indicator to entries */
664 if (S_ISDIR(st.st_mode))
665 strcat(filename, "/");
666 else if (S_ISLNK(st.st_mode))
667 strcat(filename, "@");
668 else if (st.st_mode & S_IWUSR)
669 strcat(filename, "=");
675 /* Find a character in a length limited string */
676 /* BEWARE - kernel definition of strnchr has args in different order! */
677 static char *strnchr(const char *p, char c, size_t n)
690 static char *globerrstr(int glob_rc)
694 return "Out of memory";
698 return "Found no match";
700 return "Unknown error";
703 static void clean_path(char *path)
707 /* If the input is in form Eg. obdfilter.*.stats */
708 if (strchr(path, '.')) {
710 while (*tmp != '\0') {
712 (tmp != path) && (*(tmp - 1) != '\\'))
717 /* get rid of '\', glob doesn't like it */
718 if ((tmp = strrchr(path, '\\')) != NULL) {
719 char *tail = path + strlen(path);
720 while (tmp != path) {
722 memmove(tmp, tmp + 1, tail - tmp);
730 /* Supporting file paths creates perilous behavoir: LU-888.
731 * Path support is deprecated.
732 * If a path is supplied it must begin with /proc. */
733 static void lprocfs_param_pattern(const char *cmd, const char *path, char *buf,
736 /* test path to see if it begins with '/proc/' */
737 if (strncmp(path, "/proc/", strlen("/proc/")) == 0) {
740 fprintf(stderr, "%s: specifying parameters via "
741 "full paths is deprecated.\n", cmd);
742 #if LUSTRE_VERSION_CODE >= OBD_OCD_VERSION(2, 6, 50, 0)
743 #warning "remove deprecated full path tunable access"
747 snprintf(buf, buf_size, "%s", path);
749 snprintf(buf, buf_size, "/proc/{fs,sys}/{lnet,lustre}/%s",
754 static int listparam_cmdline(int argc, char **argv, struct param_opts *popt)
758 popt->po_show_path = 1;
759 popt->po_only_path = 1;
760 popt->po_show_type = 0;
761 popt->po_recursive = 0;
763 while ((ch = getopt(argc, argv, "FR")) != -1) {
766 popt->po_show_type = 1;
769 popt->po_recursive = 1;
779 static int listparam_display(struct param_opts *popt, char *pattern)
784 char filename[PATH_MAX + 1]; /* extra 1 byte for file type */
786 rc = glob(pattern, GLOB_BRACE | (popt->po_recursive ? GLOB_MARK : 0),
789 fprintf(stderr, "error: list_param: %s: %s\n",
790 pattern, globerrstr(rc));
794 for (i = 0; i < glob_info.gl_pathc; i++) {
795 char *valuename = NULL;
798 /* Trailing '/' will indicate recursion into directory */
799 last = strlen(glob_info.gl_pathv[i]) - 1;
801 /* Remove trailing '/' or it will be converted to '.' */
802 if (last > 0 && glob_info.gl_pathv[i][last] == '/')
803 glob_info.gl_pathv[i][last] = '\0';
806 strcpy(filename, glob_info.gl_pathv[i]);
807 valuename = display_name(filename, popt->po_show_type);
809 printf("%s\n", valuename);
811 strcpy(filename, glob_info.gl_pathv[i]);
812 strcat(filename, "/*");
813 listparam_display(popt, filename);
817 globfree(&glob_info);
821 int jt_lcfg_listparam(int argc, char **argv)
824 struct param_opts popt;
825 char pattern[PATH_MAX];
828 rc = listparam_cmdline(argc, argv, &popt);
829 if (rc == argc && popt.po_recursive) {
830 rc--; /* we know at least "-R" is a parameter */
832 } else if (rc < 0 || rc >= argc) {
836 for (i = rc; i < argc; i++) {
841 lprocfs_param_pattern(argv[0], path, pattern, sizeof(pattern));
843 rc = listparam_display(&popt, pattern);
851 static int getparam_cmdline(int argc, char **argv, struct param_opts *popt)
855 popt->po_show_path = 1;
856 popt->po_only_path = 0;
857 popt->po_show_type = 0;
858 popt->po_recursive = 0;
860 while ((ch = getopt(argc, argv, "nNF")) != -1) {
863 popt->po_only_path = 1;
866 popt->po_show_path = 0;
868 popt->po_show_type = 1;
878 static int getparam_display(struct param_opts *popt, char *pattern)
885 char filename[PATH_MAX + 1]; /* extra 1 byte for file type */
887 rc = glob(pattern, GLOB_BRACE, NULL, &glob_info);
889 fprintf(stderr, "error: get_param: %s: %s\n",
890 pattern, globerrstr(rc));
894 buf = malloc(PAGE_CACHE_SIZE);
895 for (i = 0; i < glob_info.gl_pathc; i++) {
896 char *valuename = NULL;
898 memset(buf, 0, PAGE_CACHE_SIZE);
899 /* As listparam_display is used to show param name (with type),
900 * here "if (only_path)" is ignored.*/
901 if (popt->po_show_path) {
902 if (strlen(glob_info.gl_pathv[i]) >
903 sizeof(filename)-1) {
907 strncpy(filename, glob_info.gl_pathv[i],
909 valuename = display_name(filename, 0);
912 /* Write the contents of file to stdout */
913 fd = open(glob_info.gl_pathv[i], O_RDONLY);
916 "error: get_param: opening('%s') failed: %s\n",
917 glob_info.gl_pathv[i], strerror(errno));
922 rc = read(fd, buf, PAGE_CACHE_SIZE);
926 fprintf(stderr, "error: get_param: "
927 "read('%s') failed: %s\n",
928 glob_info.gl_pathv[i], strerror(errno));
931 /* Print the output in the format path=value if the
932 * value contains no new line character or cab be
933 * occupied in a line, else print value on new line */
934 if (valuename && popt->po_show_path) {
935 int longbuf = strnchr(buf, rc - 1, '\n') != NULL
937 printf("%s=%s", valuename, longbuf ? "\n" : buf);
943 rc = write(fileno(stdout), buf, rc);
945 fprintf(stderr, "error: get_param: "
946 "write to stdout failed: %s\n",
954 globfree(&glob_info);
959 int jt_lcfg_getparam(int argc, char **argv)
962 struct param_opts popt;
963 char pattern[PATH_MAX];
966 rc = getparam_cmdline(argc, argv, &popt);
967 if (rc < 0 || rc >= argc)
970 for (i = rc, rc = 0; i < argc; i++) {
977 lprocfs_param_pattern(argv[0], path, pattern, sizeof(pattern));
979 if (popt.po_only_path)
980 rc2 = listparam_display(&popt, pattern);
982 rc2 = getparam_display(&popt, pattern);
983 if (rc2 < 0 && rc == 0)
990 static int setparam_cmdline(int argc, char **argv, struct param_opts *popt)
994 popt->po_show_path = 1;
995 popt->po_only_path = 0;
996 popt->po_show_type = 0;
997 popt->po_recursive = 0;
998 popt->po_params2 = 0;
1001 while ((ch = getopt(argc, argv, "nPd")) != -1) {
1004 popt->po_show_path = 0;
1007 popt->po_params2 = 1;
1010 popt->po_delete = 1;
1019 static int setparam_display(struct param_opts *popt, char *pattern, char *value)
1025 char filename[PATH_MAX + 1]; /* extra 1 byte for file type */
1027 rc = glob(pattern, GLOB_BRACE, NULL, &glob_info);
1029 fprintf(stderr, "error: set_param: %s: %s\n",
1030 pattern, globerrstr(rc));
1033 for (i = 0; i < glob_info.gl_pathc; i++) {
1034 char *valuename = NULL;
1036 if (popt->po_show_path) {
1037 if (strlen(glob_info.gl_pathv[i]) > sizeof(filename)-1)
1039 strncpy(filename, glob_info.gl_pathv[i],
1041 valuename = display_name(filename, 0);
1043 printf("%s=%s\n", valuename, value);
1045 /* Write the new value to the file */
1046 fd = open(glob_info.gl_pathv[i], O_WRONLY);
1048 rc = write(fd, value, strlen(value));
1050 fprintf(stderr, "error: set_param: setting "
1051 "%s=%s: %s\n", glob_info.gl_pathv[i],
1052 value, strerror(errno));
1057 fprintf(stderr, "error: set_param: %s opening %s\n",
1058 strerror(rc = errno), glob_info.gl_pathv[i]);
1062 globfree(&glob_info);
1066 int jt_lcfg_setparam(int argc, char **argv)
1069 struct param_opts popt;
1070 char pattern[PATH_MAX];
1071 char *path = NULL, *value = NULL;
1073 rc = setparam_cmdline(argc, argv, &popt);
1074 if (rc < 0 || rc >= argc)
1077 if (popt.po_params2)
1078 /* We can't delete parameters that were
1079 * set with old conf_param interface */
1080 return jt_lcfg_mgsparam2(argc, argv, &popt);
1082 for (i = rc, rc = 0; i < argc; i++) {
1085 if ((value = strchr(argv[i], '=')) != NULL) {
1086 /* format: set_param a=b */
1091 /* format: set_param a b */
1102 lprocfs_param_pattern(argv[0], path, pattern, sizeof(pattern));
1104 rc2 = setparam_display(&popt, pattern, value);
1107 if (rc2 < 0 && rc == 0)