diff mbox

[3/4] xl: rework vif config parsing code

Message ID 1453463454-4114-4-git-send-email-wei.liu2@citrix.com
State New, archived
Headers show

Commit Message

Wei Liu Jan. 22, 2016, 11:50 a.m. UTC
The original parse_nic_config was in fact only parsing tokens.
main_networkattach erroneously used it to parse raw config string, which
led to xl network-attach not respecting network configuration syntax.

Rework vif config parser:

1. Extract the snippet in parse_config_data to parse_nic_config_one.
2. Rename original parse_nic_config to parse_nic_config_token.
3. Provide _multistring variant.
4. Implement parse_nic_config with _multistring variant.
5. Use _multistring variant in main_networkattach.

Finally the call chain becomes: parse_nic_config ->
parse_nic_config_multistring -> parse_nic_config_one ->
parse_nic_config_token.

Some other less important changes:

1. Change prototypes of parse_nic_config functions to match
   block counterpart.
2. parse_nic_config will now exit if parsing failed.
3. main_networkattach doesn't call set_default_nic_values anymore.

Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
 tools/libxl/xl_cmdimpl.c | 82 +++++++++++++++++++++++++++++++++++-------------
 1 file changed, 60 insertions(+), 22 deletions(-)
diff mbox

Patch

diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index ff561c3..f736f95 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -1000,8 +1000,9 @@  static int match_option_size(const char *prefix, size_t len,
 /* Parses network data and adds info into nic
  * Returns 1 if the input token does not match one of the keys
  * or parsed values are not correct. Successful parse returns 0 */
-static int parse_nic_config(libxl_device_nic *nic, XLU_Config **config,
-                            char *token)
+static int parse_nic_config_token(XLU_Config **config,
+                                  char *token,
+                                  libxl_device_nic *nic)
 {
     char *endptr, *oparg;
     int i;
@@ -1056,6 +1057,59 @@  static int parse_nic_config(libxl_device_nic *nic, XLU_Config **config,
     return 0;
 }
 
+static int parse_nic_config_one(XLU_Config **config,
+                                const char *config_str,
+                                libxl_device_nic *nic)
+{
+    char *buf = xstrdup(config_str);
+    char *p;
+    int ret;
+
+    set_default_nic_values(nic);
+
+    p = strtok(buf, ",");
+    if (!p) {
+        ret = 0;
+        goto out;
+    }
+
+    do {
+        while (*p == ' ')
+            p++;
+        ret = parse_nic_config_token(config, p, nic);
+    } while ((p = strtok(NULL, ",")) != NULL && ret == 0);
+
+out:
+    free(buf);
+
+    return ret;
+}
+
+static void parse_nic_config_multistring(XLU_Config **config,
+                                         int nspecs, const char *const *specs,
+                                         libxl_device_nic *nic)
+{
+    int i;
+
+    libxl_device_nic_init(nic);
+
+    if (!*config) {
+        *config = xlu_cfg_init(stderr, "command line");
+        if (!*config) { perror("xlu_cfg_init"); exit(-1); }
+    }
+
+    for (i = 0; i < nspecs; i++) {
+        if (parse_nic_config_one(config, specs[i], nic))
+            exit(EXIT_FAILURE);
+    }
+}
+
+static void parse_nic_config(XLU_Config **config, const char *buf,
+                             libxl_device_nic *nic)
+{
+    parse_nic_config_multistring(config, 1, &buf, nic);
+}
+
 static unsigned long parse_ulong(const char *str)
 {
     char *endptr;
@@ -1928,24 +1982,10 @@  static void parse_config_data(const char *config_source,
         while ((buf = xlu_cfg_get_listitem (nics, d_config->num_nics))
                != NULL) {
             libxl_device_nic *nic;
-            char *buf2 = strdup(buf);
-            char *p;
-
             nic = ARRAY_EXTEND_INIT(d_config->nics,
                                     d_config->num_nics,
                                     libxl_device_nic_init);
-            set_default_nic_values(nic);
-
-            p = strtok(buf2, ",");
-            if (!p)
-                goto skip_nic;
-            do {
-                while (*p == ' ')
-                    p++;
-                parse_nic_config(nic, &config, p);
-            } while ((p = strtok(NULL, ",")) != NULL);
-skip_nic:
-            free(buf2);
+            parse_nic_config(&config, buf, nic);
         }
     }
 
@@ -6532,12 +6572,10 @@  int main_networkattach(int argc, char **argv)
     }
 
     libxl_device_nic_init(&nic);
-    set_default_nic_values(&nic);
 
-    for (argv += optind+1, argc -= optind+1; argc > 0; ++argv, --argc) {
-        if (parse_nic_config(&nic, &config, *argv))
-            return 1;
-    }
+    optind++;
+    parse_nic_config_multistring(&config, argc-optind,
+                                 (const char* const*) argv + optind, &nic);
 
     if (dryrun_only) {
         char *json = libxl_device_nic_to_json(ctx, &nic);