ovs-dpctl: Support more than one option for "add-if" command.
[openvswitch] / utilities / ovs-vsctl.c
index 61ff5bbd16d1598655586ec87c6d9055f438df13..4435f41d197e5c7562cc9ede0b423fc18527918a 100644 (file)
@@ -36,6 +36,7 @@
 #include "ovsdb-idl.h"
 #include "poll-loop.h"
 #include "process.h"
+#include "stream.h"
 #include "stream-ssl.h"
 #include "svec.h"
 #include "vswitchd/vswitch-idl.h"
@@ -475,6 +476,10 @@ usage(void)
 %s: ovs-vswitchd management utility\n\
 usage: %s [OPTIONS] COMMAND [ARG...]\n\
 \n\
+Open vSwitch commands:\n\
+  init                        initialize database, if not yet initialized\n\
+  emer-reset                  reset configuration to clean state\n\
+\n\
 Bridge commands:\n\
   add-br BRIDGE               create a new bridge named BRIDGE\n\
   add-br BRIDGE PARENT VLAN   create new fake BRIDGE in PARENT on VLAN\n\
@@ -488,13 +493,12 @@ Bridge commands:\n\
   br-get-external-id BRIDGE KEY  print value of KEY on BRIDGE\n\
   br-get-external-id BRIDGE  list key-value pairs on BRIDGE\n\
 \n\
-Port commands:\n\
+Port commands (a bond is considered to be a single port):\n\
   list-ports BRIDGE           print the names of all the ports on BRIDGE\n\
   add-port BRIDGE PORT        add network device PORT to BRIDGE\n\
   add-bond BRIDGE PORT IFACE...  add bonded port PORT in BRIDGE from IFACES\n\
   del-port [BRIDGE] PORT      delete PORT (which may be bonded) from BRIDGE\n\
   port-to-br PORT             print name of bridge that contains PORT\n\
-A bond is considered to be a single port.\n\
 \n\
 Interface commands (a bond consists of multiple interfaces):\n\
   list-ifaces BRIDGE          print the names of all interfaces on BRIDGE\n\
@@ -537,9 +541,15 @@ Potentially unsafe database commands require --force option.\n\
 Options:\n\
   --db=DATABASE               connect to DATABASE\n\
                               (default: %s)\n\
+  --no-wait                   do not wait for ovs-vswitchd to reconfigure\n\
+  -t, --timeout=SECS          wait at most SECS seconds for ovs-vswitchd\n\
+  --dry-run                   do not commit changes to database\n\
   --oneline                   print exactly one line of output per command\n",
            program_name, program_name, default_db());
     vlog_usage();
+    printf("\
+  --no-syslog             equivalent to --verbose=vsctl:syslog:warn\n");
+    stream_usage("database", true, true, false);
     printf("\n\
 Other options:\n\
   -h, --help                  display this help message\n\
@@ -999,7 +1009,6 @@ cmd_init(struct vsctl_context *ctx OVS_UNUSED)
 static void
 pre_cmd_emer_reset(struct vsctl_context *ctx)
 {
-    ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_managers);
     ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_manager_options);
     ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_ssl);
 
@@ -1034,7 +1043,6 @@ cmd_emer_reset(struct vsctl_context *ctx)
     const struct ovsrec_sflow *sflow, *next_sflow;
 
     /* Reset the Open_vSwitch table. */
-    ovsrec_open_vswitch_set_managers(ctx->ovs, NULL, 0);
     ovsrec_open_vswitch_set_manager_options(ctx->ovs, NULL, 0);
     ovsrec_open_vswitch_set_ssl(ctx->ovs, NULL);
 
@@ -1395,7 +1403,7 @@ get_external_id(char **keys, char **values, size_t n,
         if (!key && !strncmp(keys[i], prefix, prefix_len)) {
             svec_add_nocopy(&svec, xasprintf("%s=%s",
                                              keys[i] + prefix_len, values[i]));
-        } else if (key_matches(keys[i], prefix, prefix_len, key)) {
+        } else if (key && key_matches(keys[i], prefix, prefix_len, key)) {
             svec_add(&svec, values[i]);
             break;
         }
@@ -1888,7 +1896,6 @@ verify_managers(const struct ovsrec_open_vswitch *ovs)
 {
     size_t i;
 
-    ovsrec_open_vswitch_verify_managers(ovs);
     ovsrec_open_vswitch_verify_manager_options(ovs);
 
     for (i = 0; i < ovs->n_manager_options; ++i) {
@@ -1901,7 +1908,6 @@ verify_managers(const struct ovsrec_open_vswitch *ovs)
 static void
 pre_manager(struct vsctl_context *ctx)
 {
-    ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_managers);
     ovsdb_idl_add_column(ctx->idl, &ovsrec_open_vswitch_col_manager_options);
     ovsdb_idl_add_column(ctx->idl, &ovsrec_manager_col_target);
 }
@@ -1918,12 +1924,6 @@ cmd_get_manager(struct vsctl_context *ctx)
     /* Print the targets in sorted order for reproducibility. */
     svec_init(&targets);
 
-    /* First, add all targets found in deprecated 'managers' column. */
-    for (i = 0; i < ovs->n_managers; i++) {
-        svec_add(&targets, ovs->managers[i]);
-    }
-
-    /* Second, add all targets pointed to by 'manager_options' column. */
     for (i = 0; i < ovs->n_manager_options; i++) {
         svec_add(&targets, ovs->manager_options[i]->target);
     }
@@ -1941,9 +1941,6 @@ delete_managers(const struct vsctl_context *ctx)
     const struct ovsrec_open_vswitch *ovs = ctx->ovs;
     size_t i;
 
-    /* Delete manager targets in deprecated 'managers' column. */
-    ovsrec_open_vswitch_set_managers(ovs, NULL, 0);
-
     /* Delete Manager rows pointed to by 'manager_options' column. */
     for (i = 0; i < ovs->n_manager_options; i++) {
         ovsrec_manager_delete(ovs->manager_options[i]);
@@ -1968,9 +1965,6 @@ insert_managers(struct vsctl_context *ctx, char *targets[], size_t n)
     struct ovsrec_manager **managers;
     size_t i;
 
-    /* Store in deprecated 'manager' column. */
-    ovsrec_open_vswitch_set_managers(ctx->ovs, targets, n);
-
     /* Insert each manager in a new row in Manager table. */
     managers = xmalloc(n * sizeof *managers);
     for (i = 0; i < n; i++) {
@@ -2414,13 +2408,12 @@ missing_operator_error(const char *arg, const char **allowed_operators,
 
 /* Breaks 'arg' apart into a number of fields in the following order:
  *
- *      - If 'columnp' is nonnull, the name of a column in 'table'.  The column
- *        is stored into '*columnp'.  The column name may be abbreviated.
+ *      - The name of a column in 'table', stored into '*columnp'.  The column
+ *        name may be abbreviated.
  *
- *      - If 'keyp' is nonnull, optionally a key string.  (If both 'columnp'
- *        and 'keyp' are nonnull, then the column and key names are expected to
- *        be separated by ':').  The key is stored as a malloc()'d string into
- *        '*keyp', or NULL if no key is present in 'arg'.
+ *      - Optionally ':' followed by a key string.  The key is stored as a
+ *        malloc()'d string into '*keyp', or NULL if no key is present in
+ *        'arg'.
  *
  *      - If 'valuep' is nonnull, an operator followed by a value string.  The
  *        allowed operators are the 'n_allowed' string in 'allowed_operators',
@@ -2430,8 +2423,6 @@ missing_operator_error(const char *arg, const char **allowed_operators,
  *        stored as a malloc()'d string into '*valuep', or NULL if no value is
  *        present in 'arg'.
  *
- * At least 'columnp' or 'keyp' must be nonnull.
- *
  * On success, returns NULL.  On failure, returned a malloc()'d string error
  * message and stores NULL into all of the nonnull output arguments. */
 static char * WARN_UNUSED_RESULT
@@ -2443,51 +2434,38 @@ parse_column_key_value(const char *arg,
                        char **valuep)
 {
     const char *p = arg;
+    char *column_name;
     char *error;
 
-    assert(columnp || keyp);
     assert(!(operatorp && !valuep));
-    if (keyp) {
-        *keyp = NULL;
-    }
+    *keyp = NULL;
     if (valuep) {
         *valuep = NULL;
     }
 
     /* Parse column name. */
-    if (columnp) {
-        char *column_name;
-
-        error = ovsdb_token_parse(&p, &column_name);
-        if (error) {
-            goto error;
-        }
-        if (column_name[0] == '\0') {
-            free(column_name);
-            error = xasprintf("%s: missing column name", arg);
-            goto error;
-        }
-        error = get_column(table, column_name, columnp);
+    error = ovsdb_token_parse(&p, &column_name);
+    if (error) {
+        goto error;
+    }
+    if (column_name[0] == '\0') {
         free(column_name);
-        if (error) {
-            goto error;
-        }
+        error = xasprintf("%s: missing column name", arg);
+        goto error;
+    }
+    error = get_column(table, column_name, columnp);
+    free(column_name);
+    if (error) {
+        goto error;
     }
 
     /* Parse key string. */
-    if (*p == ':' || !columnp) {
-        if (columnp) {
-            p++;
-        } else if (!keyp) {
-            error = xasprintf("%s: key not accepted here", arg);
-            goto error;
-        }
+    if (*p == ':') {
+        p++;
         error = ovsdb_token_parse(&p, keyp);
         if (error) {
             goto error;
         }
-    } else if (keyp) {
-        *keyp = NULL;
     }
 
     /* Parse value string. */
@@ -2535,13 +2513,9 @@ parse_column_key_value(const char *arg,
     return NULL;
 
 error:
-    if (columnp) {
-        *columnp = NULL;
-    }
-    if (keyp) {
-        free(*keyp);
-        *keyp = NULL;
-    }
+    *columnp = NULL;
+    free(*keyp);
+    *keyp = NULL;
     if (valuep) {
         free(*valuep);
         *valuep = NULL;
@@ -2875,6 +2849,7 @@ cmd_find(struct vsctl_context *ctx)
 
     next_row: ;
     }
+    free(columns);
 }
 
 static void
@@ -3152,7 +3127,9 @@ post_create(struct vsctl_context *ctx)
     const struct uuid *real;
     struct uuid dummy;
 
-    uuid_from_string(&dummy, ds_cstr(&ctx->output));
+    if (!uuid_from_string(&dummy, ds_cstr(&ctx->output))) {
+        NOT_REACHED();
+    }
     real = ovsdb_idl_txn_get_insert_uuid(ctx->txn, &dummy);
     if (real) {
         ds_clear(&ctx->output);