ovs-vsctl: Add -t or --timeout option to limit runtime.
[openvswitch] / utilities / ovs-vsctl.c
index 8de6ae112a3fdcce4baf8a9c17e583410459f7aa..1ec497926a85afc638d8221cc47c9054a2a15a7a 100644 (file)
@@ -45,6 +45,9 @@ static const char *db;
 /* --oneline: Write each command's output as a single line? */
 static bool oneline;
 
+/* --dry-run: Do not commit any changes. */
+static bool dry_run;
+
 static void vsctl_fatal(const char *, ...) PRINTF_FORMAT(1, 2) NO_RETURN;
 static char *default_db(void);
 static void usage(void) NO_RETURN;
@@ -94,7 +97,7 @@ main(int argc, char *argv[])
         vsctl_fatal("missing command name (use --help for help)");
     }
 
-    /* Now execut the commands. */
+    /* Now execute the commands. */
     idl = ovsdb_idl_create(db, &ovsrec_idl_class);
     seqno = ovsdb_idl_get_seqno(idl);
     trials = 0;
@@ -138,23 +141,28 @@ parse_options(int argc, char *argv[])
         OPT_DB = UCHAR_MAX + 1,
         OPT_ONELINE,
         OPT_NO_SYSLOG,
-        OPT_NO_WAIT
+        OPT_NO_WAIT,
+        OPT_DRY_RUN
     };
     static struct option long_options[] = {
         {"db", required_argument, 0, OPT_DB},
         {"no-syslog", no_argument, 0, OPT_NO_SYSLOG},
         {"no-wait", no_argument, 0, OPT_NO_WAIT},
+        {"dry-run", no_argument, 0, OPT_DRY_RUN},
         {"oneline", no_argument, 0, OPT_ONELINE},
+        {"timeout", required_argument, 0, 't'},
         {"verbose", optional_argument, 0, 'v'},
         {"help", no_argument, 0, 'h'},
         {"version", no_argument, 0, 'V'},
         {0, 0, 0, 0},
     };
 
+
     for (;;) {
+        unsigned long int timeout;
         int c;
 
-        c = getopt_long(argc, argv, "+v::hV", long_options, NULL);
+        c = getopt_long(argc, argv, "+v::hVt:", long_options, NULL);
         if (c == -1) {
             break;
         }
@@ -176,6 +184,10 @@ parse_options(int argc, char *argv[])
             /* XXX not yet implemented */
             break;
 
+        case OPT_DRY_RUN:
+            dry_run = true;
+            break;
+
         case 'h':
             usage();
 
@@ -183,6 +195,16 @@ parse_options(int argc, char *argv[])
             OVS_PRINT_VERSION(0, 0);
             exit(EXIT_SUCCESS);
 
+        case 't':
+            timeout = strtoul(optarg, NULL, 10);
+            if (timeout <= 0) {
+                ovs_fatal(0, "value %s on -t or --timeout is not at least 1",
+                          optarg);
+            } else {
+                time_alarm(timeout);
+            }
+            break;
+
         case 'v':
             vlog_set_verbosity(optarg);
             break;
@@ -623,6 +645,11 @@ ovs_delete_bridge(const struct ovsrec_open_vswitch *ovs,
     free(bridges);
 }
 
+static void
+cmd_init(struct vsctl_context *ctx UNUSED)
+{
+}
+
 static void
 cmd_add_br(struct vsctl_context *ctx)
 {
@@ -1186,15 +1213,17 @@ do_vsctl(int argc, char *argv[], struct ovsdb_idl *idl)
     int n_output;
     int i, start;
 
+    txn = ovsdb_idl_txn_create(idl);
+    if (dry_run) {
+        ovsdb_idl_txn_set_dry_run(txn);
+    }
+
     ovs = ovsrec_open_vswitch_first(idl);
     if (!ovs) {
-        /* XXX it would be more user-friendly to create a record ourselves
-         * (while verifying that the table is empty before doing so). */
-        vsctl_fatal("%s: database does not contain any Open vSwitch "
-                    "configuration", db);
+        /* XXX add verification that table is empty */
+        ovs = ovsrec_open_vswitch_insert(txn);
     }
 
-    txn = ovsdb_idl_txn_create(idl);
     output = xmalloc(argc * sizeof *output);
     n_output = 0;
     for (start = i = 0; i <= argc; i++) {
@@ -1273,6 +1302,9 @@ static vsctl_handler_func *
 get_vsctl_handler(int argc, char *argv[], struct vsctl_context *ctx)
 {
     static const struct vsctl_command all_commands[] = {
+        /* Open vSwitch commands. */
+        {"init", 0, 0, cmd_init, ""},
+
         /* Bridge commands. */
         {"add-br", 1, 3, cmd_add_br, ""},
         {"del-br", 1, 1, cmd_del_br, "--if-exists"},