Whamcloud - gitweb
LU-4939 utils: allow configuration through yaml files 46/31846/13
authorBen Evans <bevans@cray.com>
Wed, 21 Mar 2018 20:57:18 +0000 (16:57 -0400)
committerOleg Drokin <green@whamcloud.com>
Fri, 2 Nov 2018 07:17:34 +0000 (07:17 +0000)
add -F option to lctl set_param
file must be in yaml format.  Will accept either set_param
or conf_param formats and issue the appropriate commands

Reorganize set_param and conf_param infrastructures to allow
for shared code.

rename jt_lcfg_mgsparam to jt_lcfg_confparam
rename jt_lcfg_mgsparam2 to jt_lcfg_setparam_perm

Add test_806 to test reconfigure after writeconf

Test-Parameters: trivial testlist=conf-sanity
Signed-off-by: Ben Evans <bevans@cray.com>
Change-Id: I8c36ea9be162112e75412fbd990a4f21e108d000
Reviewed-on: https://review.whamcloud.com/31846
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Alexey Lyashkov <c17817@cray.com>
Reviewed-by: James Simmons <uja.ornl@yahoo.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/doc/lctl.8
lustre/tests/conf-sanity.sh
lustre/utils/Makefile.am
lustre/utils/lctl.c
lustre/utils/lustre_cfg.c
lustre/utils/obdctl.h

index 0820d85..7954b7c 100644 (file)
@@ -229,6 +229,15 @@ Remove the permanent setting (only with -P option)
 # lctl set_param -P osc.*.max_dirty_mb=32
 .br
 .TP
 # lctl set_param -P osc.*.max_dirty_mb=32
 .br
 .TP
+.BI "set_param -F " <filename>
+.br
+Apply configuration file specified by <filename>
+.br
+File is in YAML format, created as an output from
+\fBlctl --device MGS llog_print <fsname>-client\fR or any other valid
+llog_file from the output of \fBlctl --device MGS llog_catlist\fR
+.br
+.TP
 .BI conf_param " [-d] <device|fsname>.<parameter>=<value>"
 Set a permanent configuration parameter for any device via the MGS.  This
 command must be run on the MGS node.
 .BI conf_param " [-d] <device|fsname>.<parameter>=<value>"
 Set a permanent configuration parameter for any device via the MGS.  This
 command must be run on the MGS node.
index 50361a1..4ed9e77 100644 (file)
@@ -8199,6 +8199,45 @@ test_122() {
 }
 run_test 122 "Check OST sequence update"
 
 }
 run_test 122 "Check OST sequence update"
 
+test_123() {
+       setupall
+       local yaml_file="$TMP/$tfile.yaml"
+       do_facet mgs rm "$yaml_file"
+       local cfgfiles=$(do_facet mgs "lctl --device MGS llog_catlist |"\
+                       " sed 's/config_log://'")
+
+       # set jobid_var to a different value for test
+       local orig_val=$(do_facet mgs $LCTL get_param jobid_var)
+       do_facet mgs $LCTL set_param -P jobid_var="testname"
+
+       for i in params $cfgfiles; do
+               do_facet mgs "lctl --device MGS llog_print ${i} >> $yaml_file"
+       done
+
+       echo "Unmounting FS"
+       stopall
+       echo "Writeconf"
+       writeconf_all
+       echo "Remounting"
+       mountmgs
+       mountmds
+       mountoss
+       mountcli
+
+       # Reapply the config from before
+       echo "Setting configuration parameters"
+       do_facet mgs "lctl set_param -F $yaml_file"
+
+       local set_val=$(do_facet mgs $LCTL get_param jobid_var)
+       do_facet mgs $LCTL set_param -P $orig_val
+
+       [ $set_val == "jobid_var=testname" ] ||
+               error "$set_val is not testname"
+
+       do_facet mgs rm "$yaml_file"
+}
+run_test 123 "clear and reset all parameters using set_param -F"
+
 if ! combined_mgs_mds ; then
        stop mgs
 fi
 if ! combined_mgs_mds ; then
        stop mgs
 fi
index 5fd9d94..c7dd164 100644 (file)
@@ -57,7 +57,7 @@ lctl_SOURCES = portals.c debug.c obd.c lustre_cfg.c lctl.c obdctl.h
 if SERVER
 lctl_SOURCES += lustre_lfsck.c lsnapshot.c
 endif
 if SERVER
 lctl_SOURCES += lustre_lfsck.c lsnapshot.c
 endif
-lctl_LDADD :=  liblustreapi.la $(PTHREAD_LIBS)
+lctl_LDADD :=  liblustreapi.la $(PTHREAD_LIBS) -lyaml
 lctl_DEPENDENCIES := liblustreapi.la
 
 lfs_SOURCES = lfs.c lfs_project.c lfs_project.h
 lctl_DEPENDENCIES := liblustreapi.la
 
 lfs_SOURCES = lfs.c lfs_project.c lfs_project.h
index 2a2939b..381a427 100644 (file)
@@ -164,7 +164,8 @@ command_t cmdlist[] = {
        {"set_timeout", jt_lcfg_set_timeout, 0,
         "usage: conf_param obd_timeout=<secs>\n"},
 #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0)
        {"set_timeout", jt_lcfg_set_timeout, 0,
         "usage: conf_param obd_timeout=<secs>\n"},
 #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0)
-       {"conf_param", jt_lcfg_mgsparam, 0,"set a permanent config parameter.\n"
+       {"conf_param", jt_lcfg_confparam, 0,
+        "set a permanent config parameter.\n"
         "This command must be run on the MGS node\n"
         "usage: conf_param [-d] <target.keyword=val>\n"
         "  -d  Delete the permanent setting from the configuration."},
         "This command must be run on the MGS node\n"
         "usage: conf_param [-d] <target.keyword=val>\n"
         "  -d  Delete the permanent setting from the configuration."},
@@ -182,12 +183,13 @@ command_t cmdlist[] = {
         "      (Especially useful when using patterns.)\n"
         "  -R  Get parameters recursively from the specified entry.\n"},
        {"set_param", jt_lcfg_setparam, 0, "set the Lustre or LNET parameter\n"
         "      (Especially useful when using patterns.)\n"
         "  -R  Get parameters recursively from the specified entry.\n"},
        {"set_param", jt_lcfg_setparam, 0, "set the Lustre or LNET parameter\n"
-        "usage: set_param [-n] [-P] [-d]"
+        "usage: set_param [-n] [-P] [-d] [-F]"
         "<param_path1=value1 param_path2=value2 ...>\n"
         "Set the value of the Lustre or LNET parameter at the specified path.\n"
         "  -n  Disable printing of the key name when printing values.\n"
         "  -P  Set the parameter permanently, filesystem-wide.\n"
         "<param_path1=value1 param_path2=value2 ...>\n"
         "Set the value of the Lustre or LNET parameter at the specified path.\n"
         "  -n  Disable printing of the key name when printing values.\n"
         "  -P  Set the parameter permanently, filesystem-wide.\n"
-        "  -d  Remove the permanent setting (only with -P option).\n"},
+        "  -d  Remove the permanent setting (only with -P option).\n"
+        "  -F  Read permanent configuration from a YAML file.\n"},
        {"list_param", jt_lcfg_listparam, 0,
         "list the Lustre or LNET parameter name\n"
         "usage: list_param [-F|-R|-D] <param_path1 param_path2 ...>\n"
        {"list_param", jt_lcfg_listparam, 0,
         "list the Lustre or LNET parameter name\n"
         "usage: list_param [-F|-R|-D] <param_path1 param_path2 ...>\n"
index 9879bf4..a29aae7 100644 (file)
@@ -68,6 +68,7 @@
 
 #include "obdctl.h"
 #include <stdio.h>
 
 #include "obdctl.h"
 #include <stdio.h>
+#include <yaml.h>
 
 static char * lcfg_devname;
 
 
 static char * lcfg_devname;
 
@@ -441,47 +442,79 @@ struct param_opts {
        unsigned int po_show_path:1;
        unsigned int po_show_type:1;
        unsigned int po_recursive: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_perm:1;
        unsigned int po_delete:1;
        unsigned int po_only_dir:1;
        unsigned int po_delete:1;
        unsigned int po_only_dir:1;
+       unsigned int po_file:1;
 };
 
 };
 
+int lcfg_setparam_perm(char *func, char *buf)
+{
+       int     rc = 0;
+       struct lustre_cfg_bufs bufs;
+       struct lustre_cfg *lcfg;
+
+       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");
+
+       lustre_cfg_bufs_set_string(&bufs, 1, buf);
+
+
+       lcfg = malloc(lustre_cfg_len(bufs.lcfg_bufcount,
+                                    bufs.lcfg_buflen));
+       if (lcfg == NULL) {
+               rc = -ENOMEM;
+               fprintf(stderr, "error: allocating lcfg for %s: %s\n",
+                       jt_cmdname(func), strerror(rc));
+
+       } else {
+               lustre_cfg_init(lcfg, LCFG_SET_PARAM, &bufs);
+               rc = lcfg_mgs_ioctl(func, OBD_DEV_ID, lcfg);
+               if (rc != 0)
+                       fprintf(stderr, "error: executing %s: %s\n",
+                               jt_cmdname(func), strerror(errno));
+               free(lcfg);
+       }
+
+       return rc;
+}
+
 /* 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.
  */
 /* 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)
+static int jt_lcfg_setparam_perm(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;
+       int rc;
+       int i;
+       int first_param;
+       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++) {
 
        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]);
 
 
                len = strlen(argv[i]);
 
+               buf = 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);
                /* put an '=' on the end in case it doesn't have one */
                if (popt->po_delete && argv[i][len - 1] != '=') {
                        buf = malloc(len + 1);
@@ -490,32 +523,10 @@ static int jt_lcfg_mgsparam2(int argc, char **argv, struct param_opts *popt)
                                break;
                        }
                        sprintf(buf, "%s=", argv[i]);
                                break;
                        }
                        sprintf(buf, "%s=", argv[i]);
-               } else {
-                       buf = argv[i];
                }
                }
-               lustre_cfg_bufs_set_string(&bufs, 1, buf);
 
 
+               rc = lcfg_setparam_perm(argv[0], buf);
 
 
-               lcfg = malloc(lustre_cfg_len(bufs.lcfg_bufcount,
-                             bufs.lcfg_buflen));
-               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;
-
-                       lustre_cfg_init(lcfg, LCFG_SET_PARAM, &bufs);
-                       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;
-                       }
-                       free(lcfg);
-               }
                if (buf != argv[i])
                        free(buf);
        }
                if (buf != argv[i])
                        free(buf);
        }
@@ -523,6 +534,30 @@ static int jt_lcfg_mgsparam2(int argc, char **argv, struct param_opts *popt)
        return rc;
 }
 
        return rc;
 }
 
+int lcfg_conf_param(char *func, char *buf)
+{
+       int rc;
+       struct lustre_cfg_bufs bufs;
+       struct lustre_cfg *lcfg;
+
+       lustre_cfg_bufs_reset(&bufs, NULL);
+       lustre_cfg_bufs_set_string(&bufs, 1, buf);
+
+       /* We could put other opcodes here. */
+       lcfg = malloc(lustre_cfg_len(bufs.lcfg_bufcount, bufs.lcfg_buflen));
+       if (lcfg == NULL) {
+               rc = -ENOMEM;
+       } else {
+               lustre_cfg_init(lcfg, LCFG_PARAM, &bufs);
+               rc = lcfg_mgs_ioctl(func, OBD_DEV_ID, lcfg);
+               if (rc < 0)
+                       rc = -errno;
+               free(lcfg);
+       }
+
+       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
 /* Param set in config log on MGS */
 /* conf_param key=value */
 /* Note we can actually send mgc conf_params from clients, but currently
@@ -530,60 +565,47 @@ static int jt_lcfg_mgsparam2(int argc, char **argv, struct param_opts *popt)
  * and not here. */
 /* After removal of a parameter (-d) Lustre will use the default
  * AT NEXT REBOOT, not immediately. */
  * and not here. */
 /* After removal of a parameter (-d) Lustre will use the default
  * AT NEXT REBOOT, not immediately. */
-int jt_lcfg_mgsparam(int argc, char **argv)
+int jt_lcfg_confparam(int argc, char **argv)
 {
        int rc;
        int del = 0;
 {
        int rc;
        int del = 0;
-       struct lustre_cfg_bufs bufs;
-       struct lustre_cfg *lcfg;
        char *buf = NULL;
 
        char *buf = NULL;
 
-        /* mgs_setparam processes only lctl buf #1 */
-        if ((argc > 3) || (argc <= 1))
-                return CMD_HELP;
+       /* mgs_setparam processes only lctl buf #1 */
+       if ((argc > 3) || (argc <= 1))
+               return CMD_HELP;
 
 
-        while ((rc = getopt(argc, argv, "d")) != -1) {
-                switch (rc) {
-                        case 'd':
-                                del = 1;
-                                break;
-                        default:
-                                return CMD_HELP;
-                }
-        }
+       while ((rc = getopt(argc, argv, "d")) != -1) {
+               switch (rc) {
+               case 'd':
+                       del = 1;
+                       break;
+               default:
+                       return CMD_HELP;
+               }
+       }
 
 
-        lustre_cfg_bufs_reset(&bufs, NULL);
-        if (del) {
-                char *ptr;
+       buf = argv[optind];
 
 
-                /* for delete, make it "<param>=\0" */
-                buf = malloc(strlen(argv[optind]) + 2);
+       if (del) {
+               char *ptr;
+
+               /* for delete, make it "<param>=\0" */
+               buf = malloc(strlen(argv[optind]) + 2);
                if (buf == NULL) {
                        rc = -ENOMEM;
                        goto out;
                }
                if (buf == NULL) {
                        rc = -ENOMEM;
                        goto out;
                }
-                /* 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 {
-                lustre_cfg_bufs_set_string(&bufs, 1, argv[optind]);
-        }
-
-       /* We could put other opcodes here. */
-       lcfg = malloc(lustre_cfg_len(bufs.lcfg_bufcount, bufs.lcfg_buflen));
-       if (lcfg == NULL) {
-               rc = -ENOMEM;
-       } else {
-               lustre_cfg_init(lcfg, LCFG_PARAM, &bufs);
-               rc = lcfg_mgs_ioctl(argv[0], OBD_DEV_ID, lcfg);
-               if (rc < 0)
-                       rc = -errno;
-               free(lcfg);
+               /* 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';
        }
        }
-       if (buf)
+
+       rc = lcfg_conf_param(argv[0], buf);
+
+       if (buf != argv[optind])
                free(buf);
 out:
        if (rc < 0) {
                free(buf);
 out:
        if (rc < 0) {
@@ -1298,20 +1320,24 @@ static int setparam_cmdline(int argc, char **argv, struct param_opts *popt)
         popt->po_only_path = 0;
         popt->po_show_type = 0;
         popt->po_recursive = 0;
         popt->po_only_path = 0;
         popt->po_show_type = 0;
         popt->po_recursive = 0;
-       popt->po_params2 = 0;
+       popt->po_perm = 0;
        popt->po_delete = 0;
        popt->po_delete = 0;
+       popt->po_file = 0;
 
 
-       while ((ch = getopt(argc, argv, "nPd")) != -1) {
+       while ((ch = getopt(argc, argv, "nPdF")) != -1) {
                 switch (ch) {
                 case 'n':
                         popt->po_show_path = 0;
                         break;
                case 'P':
                 switch (ch) {
                 case 'n':
                         popt->po_show_path = 0;
                         break;
                case 'P':
-                       popt->po_params2 = 1;
+                       popt->po_perm = 1;
                        break;
                case 'd':
                        popt->po_delete = 1;
                        break;
                        break;
                case 'd':
                        popt->po_delete = 1;
                        break;
+               case 'F':
+                       popt->po_file = 1;
+                       break;
                 default:
                         return -1;
                 }
                 default:
                         return -1;
                 }
@@ -1319,6 +1345,198 @@ static int setparam_cmdline(int argc, char **argv, struct param_opts *popt)
         return optind;
 }
 
         return optind;
 }
 
+enum paramtype {
+       PT_NONE = 0,
+       PT_SETPARAM,
+       PT_CONFPARAM
+};
+
+
+#define PS_NONE 0
+#define PS_PARAM_FOUND 1
+#define PS_PARAM_SET 2
+#define PS_VAL_FOUND 4
+#define PS_VAL_SET 8
+#define PS_DEVICE_FOUND 16
+#define PS_DEVICE_SET 32
+
+#define PARAM_SZ 256
+
+static struct cfg_type_data {
+       enum paramtype ptype;
+       char *type_name;
+} cfg_type_table[] = {
+       { PT_SETPARAM, "set_param" },
+       { PT_CONFPARAM, "conf_param" },
+       { PT_NONE, "none" }
+};
+
+static struct cfg_stage_data {
+       int pstage;
+       char *stage_name;
+} cfg_stage_table[] = {
+       { PS_PARAM_FOUND, "parameter" },
+       { PS_VAL_FOUND, "value" },
+       { PS_DEVICE_FOUND, "device" },
+       { PS_NONE, "none" }
+};
+
+
+void conf_to_set_param(enum paramtype confset, const char *param,
+                      const char *device, char *buf,
+                      int bufsize)
+{
+       char *tmp;
+
+       if (confset == PT_SETPARAM) {
+               strncpy(buf, param, bufsize);
+               return;
+       }
+
+       /*
+        * sys.* params are top level, we just need to trim the sys.
+        */
+       tmp = strstr(param, "sys.");
+       if (tmp != NULL) {
+               tmp += 4;
+               strncpy(buf, tmp, bufsize);
+               return;
+       }
+
+       /*
+        * parameters look like type.parameter, we need to stick the device
+        * in the middle.  Example combine mdt.identity_upcall with device
+        * lustre-MDT0000 for mdt.lustre-MDT0000.identity_upcall
+        */
+
+       tmp = strchrnul(param, '.');
+       snprintf(buf, tmp - param + 1, "%s", param);
+       buf += tmp - param;
+       bufsize -= tmp - param;
+       snprintf(buf, bufsize, ".%s%s", device, tmp);
+}
+
+int lcfg_setparam_yaml(char *func, char *filename)
+{
+       FILE *file;
+       yaml_parser_t parser;
+       yaml_token_t token;
+       int rc = 0;
+
+       enum paramtype confset = PT_NONE;
+       int param = PS_NONE;
+       char *tmp;
+       char parameter[PARAM_SZ];
+       char value[PARAM_SZ];
+       char device[PARAM_SZ];
+
+       file = fopen(filename, "rb");
+       yaml_parser_initialize(&parser);
+       yaml_parser_set_input_file(&parser, file);
+
+       /*
+        * Search tokens for conf_param or set_param
+        * The token after "parameter" goes into parameter
+        * The token after "value" goes into value
+        * when we have all 3, create param=val and call the
+        * appropriate function for set/conf param
+        */
+       while (token.type != YAML_STREAM_END_TOKEN && rc == 0) {
+               int i;
+
+               yaml_token_delete(&token);
+               if (!yaml_parser_scan(&parser, &token)) {
+                       rc = 1;
+                       break;
+               }
+
+               if (token.type != YAML_SCALAR_TOKEN)
+                       continue;
+
+               for (i = 0; cfg_type_table[i].ptype != PT_NONE; i++) {
+                       if (!strncmp((char *)token.data.alias.value,
+                                    cfg_type_table[i].type_name,
+                                    strlen(cfg_type_table[i].type_name))) {
+                               confset = cfg_type_table[i].ptype;
+                               break;
+                       }
+               }
+
+               if (confset == PT_NONE)
+                       continue;
+
+               for (i = 0; cfg_stage_table[i].pstage != PS_NONE; i++) {
+                       if (!strncmp((char *)token.data.alias.value,
+                                    cfg_stage_table[i].stage_name,
+                                    strlen(cfg_stage_table[i].stage_name))) {
+                               param |= cfg_stage_table[i].pstage;
+                               break;
+                       }
+               }
+
+               if (cfg_stage_table[i].pstage != PS_NONE)
+                       continue;
+
+               if (param & PS_PARAM_FOUND) {
+                       conf_to_set_param(confset,
+                                         (char *)token.data.alias.value,
+                                         device, parameter, PARAM_SZ);
+                       param |= PS_PARAM_SET;
+                       param &= ~PS_PARAM_FOUND;
+
+                       /*
+                        * we're getting parameter: param=val
+                        * copy val and mark that we've got it in case
+                        * there is no value: tag
+                        */
+                       tmp = strchrnul(parameter, '=');
+                       if (*tmp == '=') {
+                               strncpy(value, tmp+1, sizeof(value));
+                               *tmp = '\0';
+                               param |= PS_VAL_SET;
+                       } else {
+                               continue;
+                       }
+               } else if (param & PS_VAL_FOUND) {
+                       strncpy(value, (char *)token.data.alias.value,
+                               PARAM_SZ);
+                       param |= PS_VAL_SET;
+                       param &= ~PS_VAL_FOUND;
+               } else if (param & PS_DEVICE_FOUND) {
+                       strncpy(device, (char *)token.data.alias.value,
+                               PARAM_SZ);
+                       param |= PS_DEVICE_SET;
+                       param &= ~PS_DEVICE_FOUND;
+               }
+
+               if (confset && param & PS_VAL_SET && param & PS_PARAM_SET) {
+                       int size = strlen(parameter) + strlen(value) + 2;
+                       char *buf = malloc(size);
+
+                       if (buf == NULL) {
+                               rc = 2;
+                               break;
+                       }
+                       snprintf(buf, size, "%s=%s", parameter, value);
+
+                       printf("set_param: %s\n", buf);
+                       rc = lcfg_setparam_perm(func, buf);
+
+                       confset = PT_NONE;
+                       param = PS_NONE;
+                       parameter[0] = '\0';
+                       value[0] = '\0';
+                       device[0] = '\0';
+                       free(buf);
+               }
+       }
+
+       yaml_parser_delete(&parser);
+       fclose(file);
+
+       return rc;
+}
+
 int jt_lcfg_setparam(int argc, char **argv)
 {
        int rc = 0, index, i;
 int jt_lcfg_setparam(int argc, char **argv)
 {
        int rc = 0, index, i;
@@ -1330,21 +1548,23 @@ int jt_lcfg_setparam(int argc, char **argv)
        if (index < 0 || index >= argc)
                return CMD_HELP;
 
        if (index < 0 || index >= argc)
                return CMD_HELP;
 
-       if (popt.po_params2)
+       if (popt.po_perm)
                /* We can't delete parameters that were
                 * set with old conf_param interface */
                /* We can't delete parameters that were
                 * set with old conf_param interface */
-               return jt_lcfg_mgsparam2(argc, argv, &popt);
+               return jt_lcfg_setparam_perm(argc, argv, &popt);
+
+       if (popt.po_file)
+               return lcfg_setparam_yaml(argv[0], argv[index]);
 
        for (i = index; i < argc; i++) {
                int rc2;
 
        for (i = index; i < argc; i++) {
                int rc2;
-               path = NULL;
+               path = argv[i];
 
 
-               value = strchr(argv[i], '=');
+               value = strchr(path, '=');
                if (value != NULL) {
                        /* format: set_param a=b */
                        *value = '\0';
                        value++;
                if (value != NULL) {
                        /* format: set_param a=b */
                        *value = '\0';
                        value++;
-                       path = argv[i];
                        if (*value == '\0') {
                                fprintf(stderr,
                                        "error: %s: setting %s: no value\n",
                        if (*value == '\0') {
                                fprintf(stderr,
                                        "error: %s: setting %s: no value\n",
@@ -1355,7 +1575,6 @@ int jt_lcfg_setparam(int argc, char **argv)
                        }
                } else {
                        /* format: set_param a b */
                        }
                } else {
                        /* format: set_param a b */
-                       path = argv[i];
                        i++;
                        if (i >= argc) {
                                fprintf(stderr,
                        i++;
                        if (i >= argc) {
                                fprintf(stderr,
index ddef2e4..a028c24 100644 (file)
@@ -160,7 +160,7 @@ int jt_lcfg_set_timeout(int argc, char **argv);
 int jt_lcfg_add_conn(int argc, char **argv);
 int jt_lcfg_del_conn(int argc, char **argv);
 int jt_lcfg_param(int argc, char **argv);
 int jt_lcfg_add_conn(int argc, char **argv);
 int jt_lcfg_del_conn(int argc, char **argv);
 int jt_lcfg_param(int argc, char **argv);
-int jt_lcfg_mgsparam(int argc, char **argv);
+int jt_lcfg_confparam(int argc, char **argv);
 int jt_lcfg_getparam(int argc, char **argv);
 int jt_lcfg_setparam(int argc, char **argv);
 int jt_lcfg_listparam(int argc, char **argv);
 int jt_lcfg_getparam(int argc, char **argv);
 int jt_lcfg_setparam(int argc, char **argv);
 int jt_lcfg_listparam(int argc, char **argv);