- 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;