-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
+/*
* GPL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
int lcfg_set_devname(char *name)
{
+ char *ptr;
+ int digit = 1;
+
if (name) {
if (lcfg_devname)
free(lcfg_devname);
/* quietly strip the unnecessary '$' */
if (*name == '$' || *name == '%')
name++;
- if (isdigit(*name)) {
+
+ ptr = name;
+ while (*ptr != '\0') {
+ if (!isdigit(*ptr)) {
+ digit = 0;
+ break;
+ }
+ ptr++;
+ }
+
+ if (digit) {
/* We can't translate from dev # to name */
lcfg_devname = NULL;
} else {
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]);
}
int jt_lcfg_set_timeout(int argc, char **argv)
{
+ int rc;
+ struct lustre_cfg_bufs bufs;
+ struct lustre_cfg *lcfg;
+
fprintf(stderr, "%s has been deprecated. Use conf_param instead.\n"
- "e.g. conf_param sys.testfs.obd_timeout=50\n",
+ "e.g. conf_param lustre-MDT0000 obd_timeout=50\n",
jt_cmdname(argv[0]));
return CMD_HELP;
+
+
+ if (argc != 2)
+ return CMD_HELP;
+
+ 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 (rc < 0) {
+ fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
+ strerror(rc = errno));
+ }
+ return rc;
}
int jt_lcfg_add_conn(int argc, char **argv)
return rc;
}
-/* Could this element of a parameter be an obd type?
- * returns boolean
- */
-static int element_could_be_obd(char *el)
-{
- char *ptr = el;
-
- /* Rather than try to enumerate known obd types and risk
- * becoming stale, I'm just going to check for no wacky chars */
- while ((*ptr != '\0') && (*ptr != '.')) {
- if (!isalpha(*ptr++))
- return 0;
- }
- return 1;
-}
+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;
+};
-/* Convert set_param into conf_param format. Examples of differences:
- * conf_param testfs.sys.at_max=1200
- * set_param at_max=1200 -- no fsname, but conf_param needs a valid one
- * conf_param lustre.llite.max_read_ahead_mb=16
- * set_param llite.lustre-ffff81003f157000.max_read_ahead_mb=16
- * conf_param lustre-MDT0000.lov.stripesize=2M
- * set_param lov.lustre-MDT0000-mdtlov.stripesize=2M
- * set_param lov.lustre-clilov-ffff81003f157000.stripesize=2M -- clilov
- * conf_param lustre-OST0001.osc.active=0
- * set_param osc.lustre-OST0000-osc-ffff81003f157000.active=0
- * conf_param lustre-OST0000.osc.max_dirty_mb=29.15
- * set_param osc.lustre-OST0000-osc-ffff81003f157000.max_dirty_mb=16
- * conf_param lustre-OST0001.ost.client_cache_seconds=15
- * set_param obdfilter.lustre-OST0001.client_cache_seconds=15 -- obdfilter/ost
- * conf_param testfs-OST0000.failover.node=1.2.3.4@tcp1
- * no proc, but osc.testfs-OST0000.failover.node -- would be appropriate
+/* 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 rearrange_setparam_syntax(char *in)
+static int jt_lcfg_mgsparam2(int argc, char **argv, struct param_opts *popt)
{
- char buf[MGS_PARAM_MAXLEN];
- char *element[3];
- int elements = 0;
- int dev, obd;
- char *ptr, *value;
- __u32 index;
- int type;
- int rc;
-
- value = strchr(in, '=');
- if (!value)
- return -EINVAL;
- *value = '\0';
-
- /* Separate elements 0.1.all_the_rest */
- element[elements++] = in;
- for (ptr = in; *ptr != '\0' && (elements < 3); ptr++) {
- if (*ptr == '.') {
- *ptr = '\0';
- element[elements++] = ++ptr;
- }
- }
- if (elements != 3) {
- fprintf(stderr, "error: Parameter format is "
- "<obd>.<fsname|devname>.<param>.\n"
- "Wildcards are not supported. Examples:\n"
- "sys.testfs.at_max=1200\n"
- "llite.testfs.max_read_ahead_mb=16\n"
- "lov.testfs-MDT0000.qos_threshold_rr=30\n"
- "mdc.testfs-MDT0000.max_rpcs_in_flight=6\n"
- "osc.testfs-OST0000.active=0\n"
- "osc.testfs-OST0000.max_dirty_mb=16\n"
- "obdfilter.testfs-OST0001.client_cache_seconds=15\n"
- "osc.testfs-OST0000.failover.node=1.2.3.4@tcp\n\n"
- );
- return -EINVAL;
- }
-
- /* e.g. testfs-OST003f-junk.ost.param */
- rc = libcfs_str2server(element[0], &type, &index, &ptr);
- if (rc == 0) {
- *ptr = '\0'; /* trunc the junk */
- goto out0;
- }
- /* e.g. ost.testfs-OST003f-junk.param */
- rc = libcfs_str2server(element[1], &type, &index, &ptr);
- if (rc == 0) {
- *ptr = '\0';
- goto out1;
- }
-
- /* llite.fsname.param or fsname.obd.param */
- if (!element_could_be_obd(element[0]) &&
- element_could_be_obd(element[1]))
- /* fsname-junk.obd.param */
- goto out0;
- if (element_could_be_obd(element[0]) &&
- !element_could_be_obd(element[1]))
- /* obd.fsname-junk.param */
- goto out1;
- if (!element_could_be_obd(element[0]) &&
- !element_could_be_obd(element[1])) {
- fprintf(stderr, "error: Parameter format is "
- "<obd>.<fsname|devname>.<param>\n");
- return -EINVAL;
- }
- /* Either element could be obd. Assume set_param syntax
- * (obd.fsname.param) */
- goto out1;
-
-out0:
- dev = 0;
- obd = 1;
- goto out;
-out1:
- dev = 1;
- obd = 0;
-out:
- /* Don't worry Mom, we'll check it out */
- if (strncmp(element[2], "failover", 8) != 0) { /* no proc for this */
- char *argt[3];
-
- if (strcmp(element[obd], "sys") == 0)
- sprintf(buf, "%s", element[2]);
- else
- sprintf(buf, "%s.%s*.%s", element[obd], element[dev],
- element[2]);
- argt[1] = "-q";
- argt[2] = buf;
- rc = jt_lcfg_listparam(3, argt);
- if (rc)
- fprintf(stderr, "warning: can't find local param '%s'\n"
- "(but that service may not be running locally)."
- "\n", buf);
- }
-
- /* s/obdfilter/ost/ */
- if (strcmp(element[obd], "obdfilter") == 0)
- sprintf(element[obd], "ost");
-
- sprintf(buf, "%s.%s.%s=%s", element[dev], element[obd],
- element[2], value + 1);
- strcpy(in, buf);
-
- return 0;
+ 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 (IS_ERR(lcfg)) {
+ fprintf(stderr, "error: allocating lcfg for %s: %s\n",
+ jt_cmdname(argv[0]), strerror(PTR_ERR(lcfg)));
+ if (rc == 0)
+ rc = PTR_ERR(lcfg);
+ } 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 */
int del = 0;
struct lustre_cfg_bufs bufs;
struct lustre_cfg *lcfg;
- char buf[MGS_PARAM_MAXLEN];
+ char *buf = NULL;
+
+#if LUSTRE_VERSION >= 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))
}
}
+ lustre_cfg_bufs_reset(&bufs, NULL);
if (del) {
char *ptr;
/* for delete, make it "<param>=\0" */
+ buf = malloc(strlen(argv[optind]) + 2);
/* put an '=' on the end in case it doesn't have one */
sprintf(buf, "%s=", argv[optind]);
/* then truncate after the first '=' */
ptr = strchr(buf, '=');
*(++ptr) = '\0';
+ lustre_cfg_bufs_set_string(&bufs, 1, buf);
} else {
- sprintf(buf, "%s", argv[optind]);
+ lustre_cfg_bufs_set_string(&bufs, 1, argv[optind]);
}
- rc = rearrange_setparam_syntax(buf);
- if (rc)
- return CMD_HELP;
-
- lustre_cfg_bufs_reset(&bufs, NULL);
- lustre_cfg_bufs_set_string(&bufs, 1, buf);
-
/* 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 (buf)
+ free(buf);
if (rc < 0) {
fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
strerror(rc = errno));
- if (rc == ENOENT) {
- char *argt[3];
- fprintf(stderr, "Does this filesystem/target exist on "
- "the MGS?\n");
- printf("Known targets:\n");
- sprintf(buf, "mgs.MGS.live.*");
- argt[1] = "-n";
- argt[2] = buf;
- jt_lcfg_getparam(3, argt);
- }
}
return rc;
/* 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;
}
*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))
}
}
-struct param_opts {
- int only_path:1;
- int show_path:1;
- int show_type:1;
- int recursive:1;
-};
+/* Supporting file paths creates perilous behavoir: LU-888.
+ * 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)
+{
+ /* 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"
+#endif
+ warned = 1;
+ }
+ snprintf(buf, buf_size, "%s", path);
+ } else {
+ snprintf(buf, buf_size, "/proc/{fs,sys}/{lnet,lustre}/%s",
+ path);
+ }
+}
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, "FRq")) != -1) {
+ 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;
- break;
- case 'q':
- popt->show_path = 0;
+ popt->po_recursive = 1;
break;
default:
return -1;
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) {
- if (popt->show_path) /* when quiet, don't show errors */
- fprintf(stderr, "error: list_param: %s: %s\n",
- pattern, globerrstr(rc));
+ fprintf(stderr, "error: list_param: %s: %s\n",
+ pattern, globerrstr(rc));
return -ESRCH;
}
- if (popt->show_path) {
- for (i = 0; i < glob_info.gl_pathc; i++) {
- char *valuename = NULL;
- int last;
+ for (i = 0; i < glob_info.gl_pathc; i++) {
+ char *valuename = NULL;
+ int last;
- /* Trailing '/' will indicate recursion into directory */
- last = strlen(glob_info.gl_pathv[i]) - 1;
+ /* Trailing '/' will indicate recursion into directory */
+ last = strlen(glob_info.gl_pathv[i]) - 1;
- /* Remove trailing '/' or it will be converted to '.' */
- if (last > 0 && glob_info.gl_pathv[i][last] == '/')
- glob_info.gl_pathv[i][last] = '\0';
- else
- last = 0;
+ /* Remove trailing '/' or it will be converted to '.' */
+ if (last > 0 && glob_info.gl_pathv[i][last] == '/')
+ glob_info.gl_pathv[i][last] = '\0';
+ else
+ last = 0;
+ strcpy(filename, glob_info.gl_pathv[i]);
+ valuename = display_name(filename, popt->po_show_type);
+ if (valuename)
+ printf("%s\n", valuename);
+ if (last) {
strcpy(filename, glob_info.gl_pathv[i]);
- valuename = display_name(filename, popt->show_type);
- if (valuename)
- printf("%s\n", valuename);
- if (last) {
- strcpy(filename, glob_info.gl_pathv[i]);
- strcat(filename, "/*");
- listparam_display(popt, filename);
- }
+ strcat(filename, "/*");
+ listparam_display(popt, filename);
}
}
int jt_lcfg_listparam(int argc, char **argv)
{
- int fp;
int rc = 0, i;
struct param_opts popt;
char pattern[PATH_MAX];
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) {
clean_path(path);
- /* If the entire path is specified as input */
- fp = open(path, O_RDONLY);
- if (fp < 0) {
- snprintf(pattern, PATH_MAX, "/proc/{fs,sys}/{lnet,lustre}/%s",
- path);
- } else {
- strcpy(pattern, path);
- close(fp);
- }
+ lprocfs_param_pattern(argv[0], path, pattern, sizeof(pattern));
rc = listparam_display(&popt, pattern);
if (rc < 0)
{
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;
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);
}
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",
break;
}
/* Print the output in the format path=value if the
- * value contains no new line character or can be
+ * 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);
int jt_lcfg_getparam(int argc, char **argv)
{
- int fp;
int rc = 0, i;
struct param_opts popt;
char pattern[PATH_MAX];
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];
- /* If the entire path is specified as input */
- fp = open(path, O_RDONLY);
- if (fp < 0) {
- snprintf(pattern, PATH_MAX, "/proc/{fs,sys}/{lnet,lustre}/%s",
- path);
- } else {
- strcpy(pattern, path);
- close(fp);
- }
+ 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;
}
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)
{
- int fp;
int rc = 0, i;
struct param_opts popt;
char pattern[PATH_MAX];
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';
clean_path(path);
- /* If the entire path is specified as input */
- fp = open(path, O_RDONLY);
- if (fp < 0) {
- snprintf(pattern, PATH_MAX, "/proc/{fs,sys}/{lnet,lustre}/%s",
- path);
- } else {
- strcpy(pattern, path);
- close(fp);
- }
+ 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;
- }
+ if (rc2 < 0 && rc == 0)
+ rc = rc2;
+ }
- return 0;
+ return rc;
}
+