X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Futils%2Flustre_cfg.c;h=29b3ae1be35082392ddb05a6c484bd925968b93f;hp=93adfb3075088cb21166122726f0ffcc587619be;hb=12e311012ae337276dc3e7da3e7ad8d85d11e764;hpb=e3a7c58aebafce40323db54bf6056029e5af4a70 diff --git a/lustre/utils/lustre_cfg.c b/lustre/utils/lustre_cfg.c index 93adfb3..29b3ae1 100644 --- a/lustre/utils/lustre_cfg.c +++ b/lustre/utils/lustre_cfg.c @@ -27,7 +27,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Whamcloud, Inc. + * Copyright (c) 2011, 2012, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -49,15 +49,9 @@ #include #include -#ifndef __KERNEL__ -#include -#endif -#include +#include #include #include -#include -#include /* for struct lov_stripe_md */ -#include #include #include @@ -134,24 +128,15 @@ int jt_lcfg_attach(int argc, char **argv) lustre_cfg_bufs_set_string(&bufs, 2, argv[3]); lcfg = lustre_cfg_new(LCFG_ATTACH, &bufs); - rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg); - lustre_cfg_free(lcfg); + if (lcfg == NULL) { + rc = -ENOMEM; + } else { + rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg); + lustre_cfg_free(lcfg); + } if (rc < 0) { fprintf(stderr, "error: %s: LCFG_ATTACH %s\n", jt_cmdname(argv[0]), strerror(rc = errno)); - } else if (argc == 3) { - char name[1024]; - - lcfg_set_devname(argv[2]); - if (strlen(argv[2]) > 128) { - printf("Name too long to set environment\n"); - return -EINVAL; - } - snprintf(name, 512, "LUSTRE_DEV_%s", argv[2]); - rc = setenv(name, argv[1], 1); - if (rc) { - printf("error setting env variable %s\n", name); - } } else { lcfg_set_devname(argv[2]); } @@ -183,8 +168,12 @@ int jt_lcfg_setup(int argc, char **argv) } lcfg = lustre_cfg_new(LCFG_SETUP, &bufs); - rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg); - lustre_cfg_free(lcfg); + if (lcfg == NULL) { + rc = -ENOMEM; + } else { + rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg); + lustre_cfg_free(lcfg); + } if (rc < 0) fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), strerror(rc = errno)); @@ -211,8 +200,12 @@ int jt_obd_detach(int argc, char **argv) return CMD_HELP; lcfg = lustre_cfg_new(LCFG_DETACH, &bufs); - rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg); - lustre_cfg_free(lcfg); + if (lcfg == NULL) { + rc = -ENOMEM; + } else { + rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg); + lustre_cfg_free(lcfg); + } if (rc < 0) fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), strerror(rc = errno)); @@ -250,19 +243,23 @@ int jt_obd_cleanup(int argc, char **argv) flags[flag_cnt++] = force; } else if (strcmp(argv[n], "failover") == 0) { flags[flag_cnt++] = failover; - } else { - fprintf(stderr, "unknown option: %s", argv[n]); - return CMD_HELP; - } - } + } else { + fprintf(stderr, "unknown option: %s\n", argv[n]); + return CMD_HELP; + } + } if (flag_cnt) { lustre_cfg_bufs_set_string(&bufs, 1, flags); } lcfg = lustre_cfg_new(LCFG_CLEANUP, &bufs); - rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg); - lustre_cfg_free(lcfg); + if (lcfg == NULL) { + rc = -ENOMEM; + } else { + rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg); + lustre_cfg_free(lcfg); + } if (rc < 0) fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), strerror(rc = errno)); @@ -273,34 +270,33 @@ int jt_obd_cleanup(int argc, char **argv) static int do_add_uuid(char * func, char *uuid, lnet_nid_t nid) { - int rc; - struct lustre_cfg_bufs bufs; - struct lustre_cfg *lcfg; + int rc; + struct lustre_cfg_bufs bufs; + struct lustre_cfg *lcfg; - lustre_cfg_bufs_reset(&bufs, lcfg_devname); - if (uuid) - lustre_cfg_bufs_set_string(&bufs, 1, uuid); + lustre_cfg_bufs_reset(&bufs, lcfg_devname); + if (uuid != NULL) + lustre_cfg_bufs_set_string(&bufs, 1, uuid); lcfg = lustre_cfg_new(LCFG_ADD_UUID, &bufs); - lcfg->lcfg_nid = nid; - /* Poison NAL -- pre 1.4.6 will LASSERT on 0 NAL, this way it - doesn't work without crashing (bz 10130) */ - lcfg->lcfg_nal = 0x5a; - -#if 0 - fprintf(stderr, "adding\tnid: %d\tuuid: %s\n", - lcfg->lcfg_nid, uuid); -#endif - rc = lcfg_ioctl(func, OBD_DEV_ID, lcfg); - lustre_cfg_free(lcfg); + if (lcfg == NULL) { + rc = -ENOMEM; + } else { + lcfg->lcfg_nid = nid; + + rc = lcfg_ioctl(func, OBD_DEV_ID, lcfg); + lustre_cfg_free(lcfg); + } if (rc) { fprintf(stderr, "IOC_PORTAL_ADD_UUID failed: %s\n", strerror(errno)); return -1; } - printf ("Added uuid %s: %s\n", uuid, libcfs_nid2str(nid)); - return 0; + if (uuid != NULL) + printf("Added uuid %s: %s\n", uuid, libcfs_nid2str(nid)); + + return 0; } int jt_lcfg_add_uuid(int argc, char **argv) @@ -320,11 +316,6 @@ int jt_lcfg_add_uuid(int argc, char **argv) return do_add_uuid(argv[0], argv[1], nid); } -int obd_add_uuid(char *uuid, lnet_nid_t nid) -{ - return do_add_uuid("obd_add_uuid", uuid, nid); -} - int jt_lcfg_del_uuid(int argc, char **argv) { int rc; @@ -341,8 +332,12 @@ int jt_lcfg_del_uuid(int argc, char **argv) lustre_cfg_bufs_set_string(&bufs, 1, argv[1]); lcfg = lustre_cfg_new(LCFG_DEL_UUID, &bufs); - rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg); - lustre_cfg_free(lcfg); + if (lcfg == NULL) { + rc = -ENOMEM; + } else { + rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg); + lustre_cfg_free(lcfg); + } if (rc) { fprintf(stderr, "IOC_PORTAL_DEL_UUID failed: %s\n", strerror(errno)); @@ -366,8 +361,12 @@ int jt_lcfg_del_mount_option(int argc, char **argv) lustre_cfg_bufs_set_string(&bufs, 1, argv[1]); lcfg = lustre_cfg_new(LCFG_DEL_MOUNTOPT, &bufs); - rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg); - lustre_cfg_free(lcfg); + if (lcfg == NULL) { + rc = -ENOMEM; + } else { + rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg); + lustre_cfg_free(lcfg); + } if (rc < 0) { fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), strerror(rc = errno)); @@ -392,12 +391,14 @@ int jt_lcfg_set_timeout(int argc, char **argv) lustre_cfg_bufs_reset(&bufs, lcfg_devname); lcfg = lustre_cfg_new(LCFG_SET_TIMEOUT, &bufs); - lcfg->lcfg_num = atoi(argv[1]); - - rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg); - //rc = lcfg_mgs_ioctl(argv[0], OBD_DEV_ID, lcfg); - - lustre_cfg_free(lcfg); + if (lcfg == NULL) { + rc = -ENOMEM; + } else { + lcfg->lcfg_num = atoi(argv[1]); + + rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg); + lustre_cfg_free(lcfg); + } if (rc < 0) { fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), strerror(rc = errno)); @@ -431,10 +432,14 @@ int jt_lcfg_add_conn(int argc, char **argv) lustre_cfg_bufs_set_string(&bufs, 1, argv[1]); lcfg = lustre_cfg_new(LCFG_ADD_CONN, &bufs); - lcfg->lcfg_num = priority; - - rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg); - lustre_cfg_free (lcfg); + if (lcfg == NULL) { + rc = -ENOMEM; + } else { + lcfg->lcfg_num = priority; + + rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg); + lustre_cfg_free(lcfg); + } if (rc < 0) { fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), strerror(rc = errno)); @@ -465,9 +470,12 @@ int jt_lcfg_del_conn(int argc, char **argv) lustre_cfg_bufs_set_string(&bufs, 1, argv[1]); lcfg = lustre_cfg_new(LCFG_DEL_MOUNTOPT, &bufs); - - rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg); - lustre_cfg_free(lcfg); + if (lcfg == NULL) { + rc = -ENOMEM; + } else { + rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg); + lustre_cfg_free(lcfg); + } if (rc < 0) { fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), strerror(rc = errno)); @@ -493,9 +501,12 @@ int jt_lcfg_param(int argc, char **argv) } lcfg = lustre_cfg_new(LCFG_PARAM, &bufs); - - rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg); - lustre_cfg_free(lcfg); + if (lcfg == NULL) { + rc = -ENOMEM; + } else { + rc = lcfg_ioctl(argv[0], OBD_DEV_ID, lcfg); + lustre_cfg_free(lcfg); + } if (rc < 0) { fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]), strerror(rc = errno)); @@ -503,6 +514,83 @@ int jt_lcfg_param(int argc, char **argv) return rc; } +struct param_opts { + unsigned int po_only_path:1; + unsigned int po_show_path:1; + unsigned int po_show_type:1; + unsigned int po_recursive:1; + unsigned int po_params2:1; + unsigned int po_delete:1; +}; + +/* Param set to single log file, used by all clients and servers. + * This should be loaded after the individual config logs. + * Called from set param with -P option. + */ +static int jt_lcfg_mgsparam2(int argc, char **argv, struct param_opts *popt) +{ + int rc, i; + int first_param; + struct lustre_cfg_bufs bufs; + struct lustre_cfg *lcfg; + char *buf = NULL; + int len; + + first_param = optind; + if (first_param < 0 || first_param >= argc) + return CMD_HELP; + + for (i = first_param, rc = 0; i < argc; i++) { + lustre_cfg_bufs_reset(&bufs, NULL); + /* This same command would be executed on all nodes, many + * of which should fail (silently) because they don't have + * that proc file existing locally. There would be no + * preprocessing on the MGS to try to figure out which + * parameter files to add this to, there would be nodes + * processing on the cluster nodes to try to figure out + * if they are the intended targets. They will blindly + * try to set the parameter, and ENOTFOUND means it wasn't + * for them. + * Target name "general" means call on all targets. It is + * left here in case some filtering will be added in + * future. + */ + lustre_cfg_bufs_set_string(&bufs, 0, "general"); + + len = strlen(argv[i]); + + /* put an '=' on the end in case it doesn't have one */ + if (popt->po_delete && argv[i][len - 1] != '=') { + buf = malloc(len + 1); + sprintf(buf, "%s=", argv[i]); + } else { + buf = argv[i]; + } + lustre_cfg_bufs_set_string(&bufs, 1, buf); + + lcfg = lustre_cfg_new(LCFG_SET_PARAM, &bufs); + if (lcfg == NULL) { + fprintf(stderr, "error: allocating lcfg for %s: %s\n", + jt_cmdname(argv[0]), strerror(-ENOMEM)); + if (rc == 0) + rc = -ENOMEM; + } else { + int rc2 = lcfg_mgs_ioctl(argv[0], OBD_DEV_ID, lcfg); + if (rc2 != 0) { + fprintf(stderr, "error: executing %s: %s\n", + jt_cmdname(argv[0]), strerror(errno)); + if (rc == 0) + rc = rc2; + } + lustre_cfg_free(lcfg); + } + if (buf != argv[i]) + free(buf); + } + + return rc; +} + /* Param set in config log on MGS */ /* conf_param key=value */ /* Note we can actually send mgc conf_params from clients, but currently @@ -512,11 +600,16 @@ int jt_lcfg_param(int argc, char **argv) * AT NEXT REBOOT, not immediately. */ int jt_lcfg_mgsparam(int argc, char **argv) { - int rc; - int del = 0; - struct lustre_cfg_bufs bufs; - struct lustre_cfg *lcfg; - char *buf = NULL; + int rc; + int del = 0; + struct lustre_cfg_bufs bufs; + struct lustre_cfg *lcfg; + char *buf = NULL; + +#if LUSTRE_VERSION_CODE >= OBD_OCD_VERSION(2, 7, 53, 0) + fprintf(stderr, "warning: 'lctl conf_param' is deprecated, " + "use 'lctl set_param -P' instead\n"); +#endif /* mgs_setparam processes only lctl buf #1 */ if ((argc > 3) || (argc <= 1)) @@ -550,9 +643,12 @@ int jt_lcfg_mgsparam(int argc, char **argv) /* We could put other opcodes here. */ lcfg = lustre_cfg_new(LCFG_PARAM, &bufs); - - rc = lcfg_mgs_ioctl(argv[0], OBD_DEV_ID, lcfg); - lustre_cfg_free(lcfg); + if (lcfg == NULL) { + rc = -ENOMEM; + } else { + rc = lcfg_mgs_ioctl(argv[0], OBD_DEV_ID, lcfg); + lustre_cfg_free(lcfg); + } if (buf) free(buf); if (rc < 0) { @@ -565,12 +661,12 @@ int jt_lcfg_mgsparam(int argc, char **argv) /* Display the path in the same format as sysctl * For eg. obdfilter.lustre-OST0000.stats */ -static char *display_name(char *filename, int show_type) +static char *display_name(char *filename, unsigned int po_show_type) { char *tmp; struct stat st; - if (show_type) { + if (po_show_type) { if (lstat(filename, &st) < 0) return NULL; } @@ -592,7 +688,7 @@ static char *display_name(char *filename, int show_type) *tmp = '.'; /* append the indicator to entries */ - if (show_type) { + if (po_show_type) { if (S_ISDIR(st.st_mode)) strcat(filename, "/"); else if (S_ISLNK(st.st_mode)) @@ -663,49 +759,39 @@ static void clean_path(char *path) * Path support is deprecated. * If a path is supplied it must begin with /proc. */ static void lprocfs_param_pattern(const char *cmd, const char *path, char *buf, - size_t buf_size) + size_t buf_size) { - /* test path to see if it begins with '/proc/' */ - if (strncmp(path, "/proc/", strlen("/proc/")) == 0) { - static int warned; - if (!warned) { - fprintf(stderr, "%s: specifying parameters via " - "full paths is deprecated.\n", cmd); -#if LUSTRE_VERSION_CODE >= OBD_OCD_VERSION(2,6,50,0) -#warning "remove deprecated full path tunable access" +#if LUSTRE_VERSION_CODE >= OBD_OCD_VERSION(2, 6, 53, 0) + /* test path to see if it begins with '/proc/' */ + if (strncmp(path, "/proc/", strlen("/proc/")) == 0) { + static int warned; + if (!warned) { + fprintf(stderr, "%s: specifying parameters via " + "full paths is deprecated.\n", cmd); + warned = 1; + } + snprintf(buf, buf_size, "%s", path); + } else #endif - warned = 1; - } - snprintf(buf, buf_size, "%s", path); - } else { - snprintf(buf, buf_size, "/proc/{fs,sys}/{lnet,lustre}/%s", - path); - } + snprintf(buf, buf_size, "/proc/{fs,sys}/{lnet,lustre}/%s", path); } -struct param_opts { - int only_path:1; - int show_path:1; - int show_type:1; - int recursive:1; -}; - static int listparam_cmdline(int argc, char **argv, struct param_opts *popt) { int ch; - popt->show_path = 1; - popt->only_path = 1; - popt->show_type = 0; - popt->recursive = 0; + popt->po_show_path = 1; + popt->po_only_path = 1; + popt->po_show_type = 0; + popt->po_recursive = 0; while ((ch = getopt(argc, argv, "FR")) != -1) { switch (ch) { case 'F': - popt->show_type = 1; + popt->po_show_type = 1; break; case 'R': - popt->recursive = 1; + popt->po_recursive = 1; break; default: return -1; @@ -722,7 +808,7 @@ static int listparam_display(struct param_opts *popt, char *pattern) glob_t glob_info; char filename[PATH_MAX + 1]; /* extra 1 byte for file type */ - rc = glob(pattern, GLOB_BRACE | (popt->recursive ? GLOB_MARK : 0), + rc = glob(pattern, GLOB_BRACE | (popt->po_recursive ? GLOB_MARK : 0), NULL, &glob_info); if (rc) { fprintf(stderr, "error: list_param: %s: %s\n", @@ -743,7 +829,7 @@ static int listparam_display(struct param_opts *popt, char *pattern) else last = 0; strcpy(filename, glob_info.gl_pathv[i]); - valuename = display_name(filename, popt->show_type); + valuename = display_name(filename, popt->po_show_type); if (valuename) printf("%s\n", valuename); if (last) { @@ -765,7 +851,7 @@ int jt_lcfg_listparam(int argc, char **argv) char *path; rc = listparam_cmdline(argc, argv, &popt); - if (rc == argc && popt.recursive) { + if (rc == argc && popt.po_recursive) { rc--; /* we know at least "-R" is a parameter */ argv[rc] = "*"; } else if (rc < 0 || rc >= argc) { @@ -791,20 +877,20 @@ static int getparam_cmdline(int argc, char **argv, struct param_opts *popt) { int ch; - popt->show_path = 1; - popt->only_path = 0; - popt->show_type = 0; - popt->recursive = 0; + popt->po_show_path = 1; + popt->po_only_path = 0; + popt->po_show_type = 0; + popt->po_recursive = 0; while ((ch = getopt(argc, argv, "nNF")) != -1) { switch (ch) { case 'N': - popt->only_path = 1; + popt->po_only_path = 1; break; case 'n': - popt->show_path = 0; + popt->po_show_path = 0; case 'F': - popt->show_type = 1; + popt->po_show_type = 1; break; default: return -1; @@ -830,15 +916,21 @@ static int getparam_display(struct param_opts *popt, char *pattern) return -ESRCH; } - buf = malloc(CFS_PAGE_SIZE); - for (i = 0; i < glob_info.gl_pathc; i++) { - char *valuename = NULL; + buf = malloc(PAGE_CACHE_SIZE); + for (i = 0; i < glob_info.gl_pathc; i++) { + char *valuename = NULL; - memset(buf, 0, CFS_PAGE_SIZE); + memset(buf, 0, PAGE_CACHE_SIZE); /* As listparam_display is used to show param name (with type), * here "if (only_path)" is ignored.*/ - if (popt->show_path) { - strcpy(filename, glob_info.gl_pathv[i]); + if (popt->po_show_path) { + if (strlen(glob_info.gl_pathv[i]) > + sizeof(filename)-1) { + free(buf); + return -E2BIG; + } + strncpy(filename, glob_info.gl_pathv[i], + sizeof(filename)); valuename = display_name(filename, 0); } @@ -851,10 +943,10 @@ static int getparam_display(struct param_opts *popt, char *pattern) continue; } - do { - rc = read(fd, buf, CFS_PAGE_SIZE); - if (rc == 0) - break; + do { + rc = read(fd, buf, PAGE_CACHE_SIZE); + if (rc == 0) + break; if (rc < 0) { fprintf(stderr, "error: get_param: " "read('%s') failed: %s\n", @@ -864,7 +956,7 @@ static int getparam_display(struct param_opts *popt, char *pattern) /* Print the output in the format path=value if the * value contains no new line character or cab be * occupied in a line, else print value on new line */ - if (valuename && popt->show_path) { + if (valuename && popt->po_show_path) { int longbuf = strnchr(buf, rc - 1, '\n') != NULL || rc > 60; printf("%s=%s", valuename, longbuf ? "\n" : buf); @@ -900,38 +992,48 @@ int jt_lcfg_getparam(int argc, char **argv) if (rc < 0 || rc >= argc) return CMD_HELP; - for (i = rc; i < argc; i++) { - path = argv[i]; + for (i = rc, rc = 0; i < argc; i++) { + int rc2; - clean_path(path); + path = argv[i]; - lprocfs_param_pattern(argv[0], path, pattern, sizeof(pattern)); + clean_path(path); - if (popt.only_path) - rc = listparam_display(&popt, pattern); - else - rc = getparam_display(&popt, pattern); - if (rc < 0) - return rc; - } + lprocfs_param_pattern(argv[0], path, pattern, sizeof(pattern)); - return 0; + if (popt.po_only_path) + rc2 = listparam_display(&popt, pattern); + else + rc2 = getparam_display(&popt, pattern); + if (rc2 < 0 && rc == 0) + rc = rc2; + } + + return rc; } static int setparam_cmdline(int argc, char **argv, struct param_opts *popt) { int ch; - popt->show_path = 1; - popt->only_path = 0; - popt->show_type = 0; - popt->recursive = 0; + popt->po_show_path = 1; + popt->po_only_path = 0; + popt->po_show_type = 0; + popt->po_recursive = 0; + popt->po_params2 = 0; + popt->po_delete = 0; - while ((ch = getopt(argc, argv, "n")) != -1) { + while ((ch = getopt(argc, argv, "nPd")) != -1) { switch (ch) { case 'n': - popt->show_path = 0; + popt->po_show_path = 0; break; + case 'P': + popt->po_params2 = 1; + break; + case 'd': + popt->po_delete = 1; + break; default: return -1; } @@ -953,34 +1055,37 @@ static int setparam_display(struct param_opts *popt, char *pattern, char *value) pattern, globerrstr(rc)); return -ESRCH; } - for (i = 0; i < glob_info.gl_pathc; i++) { - char *valuename = NULL; - - if (popt->show_path) { - strcpy(filename, glob_info.gl_pathv[i]); - valuename = display_name(filename, 0); - if (valuename) - printf("%s=%s\n", valuename, value); - } - /* Write the new value to the file */ - fd = open(glob_info.gl_pathv[i], O_WRONLY); - if (fd > 0) { - rc = write(fd, value, strlen(value)); - if (rc < 0) - fprintf(stderr, "error: set_param: " - "writing to file %s: %s\n", - glob_info.gl_pathv[i], strerror(errno)); - else - rc = 0; - close(fd); - } else { - fprintf(stderr, "error: set_param: %s opening %s\n", - strerror(rc = errno), glob_info.gl_pathv[i]); - } - } - - globfree(&glob_info); - return rc; + for (i = 0; i < glob_info.gl_pathc; i++) { + char *valuename = NULL; + + if (popt->po_show_path) { + if (strlen(glob_info.gl_pathv[i]) > sizeof(filename)-1) + return -E2BIG; + strncpy(filename, glob_info.gl_pathv[i], + sizeof(filename)); + valuename = display_name(filename, 0); + if (valuename) + printf("%s=%s\n", valuename, value); + } + /* Write the new value to the file */ + fd = open(glob_info.gl_pathv[i], O_WRONLY); + if (fd >= 0) { + rc = write(fd, value, strlen(value)); + if (rc < 0) + fprintf(stderr, "error: set_param: setting " + "%s=%s: %s\n", glob_info.gl_pathv[i], + value, strerror(errno)); + else + rc = 0; + close(fd); + } else { + fprintf(stderr, "error: set_param: %s opening %s\n", + strerror(rc = errno), glob_info.gl_pathv[i]); + } + } + + globfree(&glob_info); + return rc; } int jt_lcfg_setparam(int argc, char **argv) @@ -994,12 +1099,21 @@ int jt_lcfg_setparam(int argc, char **argv) if (rc < 0 || rc >= argc) return CMD_HELP; - for (i = rc; i < argc; i++) { + if (popt.po_params2) + /* We can't delete parameters that were + * set with old conf_param interface */ + return jt_lcfg_mgsparam2(argc, argv, &popt); + + for (i = rc, rc = 0; i < argc; i++) { + int rc2; + if ((value = strchr(argv[i], '=')) != NULL) { /* format: set_param a=b */ *value = '\0'; value ++; path = argv[i]; + if (*value == '\0') + break; } else { /* format: set_param a b */ if (path == NULL) { @@ -1014,13 +1128,16 @@ int jt_lcfg_setparam(int argc, char **argv) lprocfs_param_pattern(argv[0], path, pattern, sizeof(pattern)); - rc = setparam_display(&popt, pattern, value); + rc2 = setparam_display(&popt, pattern, value); path = NULL; value = NULL; - if (rc < 0) - return rc; - } - - return 0; + if (rc2 < 0 && rc == 0) + rc = rc2; + } + if (path != NULL && (value == NULL || *value == '\0')) + fprintf(stderr, "error: %s: setting %s=: %s\n", + jt_cmdname(argv[0]), path, strerror(rc = EINVAL)); + + return rc; }