ovs-vsctl: New "comment" command.
[sliver-openvswitch.git] / utilities / ovs-vsctl.c
index 8516966..df20f06 100644 (file)
@@ -207,19 +207,19 @@ parse_options(int argc, char *argv[])
         TABLE_OPTION_ENUMS
     };
     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'},
-        {"help", no_argument, 0, 'h'},
-        {"version", no_argument, 0, 'V'},
+        {"db", required_argument, NULL, OPT_DB},
+        {"no-syslog", no_argument, NULL, OPT_NO_SYSLOG},
+        {"no-wait", no_argument, NULL, OPT_NO_WAIT},
+        {"dry-run", no_argument, NULL, OPT_DRY_RUN},
+        {"oneline", no_argument, NULL, OPT_ONELINE},
+        {"timeout", required_argument, NULL, 't'},
+        {"help", no_argument, NULL, 'h'},
+        {"version", no_argument, NULL, 'V'},
         VLOG_LONG_OPTIONS,
         TABLE_LONG_OPTIONS,
         STREAM_SSL_LONG_OPTIONS,
-        {"peer-ca-cert", required_argument, 0, OPT_PEER_CA_CERT},
-        {0, 0, 0, 0},
+        {"peer-ca-cert", required_argument, NULL, OPT_PEER_CA_CERT},
+        {NULL, 0, NULL, 0},
     };
     char *tmp, *short_options;
 
@@ -476,6 +476,7 @@ usage: %s [OPTIONS] COMMAND [ARG...]\n\
 \n\
 Open vSwitch commands:\n\
   init                        initialize database, if not yet initialized\n\
+  show                        print overview of database contents\n\
   emer-reset                  reset configuration to clean state\n\
 \n\
 Bridge commands:\n\
@@ -1004,6 +1005,186 @@ cmd_init(struct vsctl_context *ctx OVS_UNUSED)
 {
 }
 
+struct cmd_show_table {
+    const struct ovsdb_idl_table_class *table;
+    const struct ovsdb_idl_column *name_column;
+    const struct ovsdb_idl_column *columns[3];
+    bool recurse;
+};
+
+static struct cmd_show_table cmd_show_tables[] = {
+    {&ovsrec_table_open_vswitch,
+     NULL,
+     {&ovsrec_open_vswitch_col_manager_options,
+      &ovsrec_open_vswitch_col_bridges,
+      &ovsrec_open_vswitch_col_ovs_version},
+     false},
+
+    {&ovsrec_table_bridge,
+     &ovsrec_bridge_col_name,
+     {&ovsrec_bridge_col_controller,
+      &ovsrec_bridge_col_fail_mode,
+      &ovsrec_bridge_col_ports},
+     false},
+
+    {&ovsrec_table_port,
+     &ovsrec_port_col_name,
+     {&ovsrec_port_col_tag,
+      &ovsrec_port_col_trunks,
+      &ovsrec_port_col_interfaces},
+     false},
+
+    {&ovsrec_table_interface,
+     &ovsrec_interface_col_name,
+     {&ovsrec_interface_col_type,
+      &ovsrec_interface_col_options,
+      NULL},
+     false},
+
+    {&ovsrec_table_controller,
+     &ovsrec_controller_col_target,
+     {&ovsrec_controller_col_is_connected,
+      NULL,
+      NULL},
+     false},
+
+    {&ovsrec_table_manager,
+     &ovsrec_manager_col_target,
+     {&ovsrec_manager_col_is_connected,
+      NULL,
+      NULL},
+     false},
+};
+
+static void
+pre_cmd_show(struct vsctl_context *ctx)
+{
+    struct cmd_show_table *show;
+
+    for (show = cmd_show_tables;
+         show < &cmd_show_tables[ARRAY_SIZE(cmd_show_tables)];
+         show++) {
+        size_t i;
+
+        ovsdb_idl_add_table(ctx->idl, show->table);
+        if (show->name_column) {
+            ovsdb_idl_add_column(ctx->idl, show->name_column);
+        }
+        for (i = 0; i < ARRAY_SIZE(show->columns); i++) {
+            const struct ovsdb_idl_column *column = show->columns[i];
+            if (column) {
+                ovsdb_idl_add_column(ctx->idl, column);
+            }
+        }
+    }
+}
+
+static struct cmd_show_table *
+cmd_show_find_table_by_row(const struct ovsdb_idl_row *row)
+{
+    struct cmd_show_table *show;
+
+    for (show = cmd_show_tables;
+         show < &cmd_show_tables[ARRAY_SIZE(cmd_show_tables)];
+         show++) {
+        if (show->table == row->table->class) {
+            return show;
+        }
+    }
+    return NULL;
+}
+
+static struct cmd_show_table *
+cmd_show_find_table_by_name(const char *name)
+{
+    struct cmd_show_table *show;
+
+    for (show = cmd_show_tables;
+         show < &cmd_show_tables[ARRAY_SIZE(cmd_show_tables)];
+         show++) {
+        if (!strcmp(show->table->name, name)) {
+            return show;
+        }
+    }
+    return NULL;
+}
+
+static void
+cmd_show_row(struct vsctl_context *ctx, const struct ovsdb_idl_row *row,
+             int level)
+{
+    struct cmd_show_table *show = cmd_show_find_table_by_row(row);
+    size_t i;
+
+    ds_put_char_multiple(&ctx->output, ' ', level * 4);
+    if (show && show->name_column) {
+        const struct ovsdb_datum *datum;
+
+        ds_put_format(&ctx->output, "%s ", show->table->name);
+        datum = ovsdb_idl_read(row, show->name_column);
+        ovsdb_datum_to_string(datum, &show->name_column->type, &ctx->output);
+    } else {
+        ds_put_format(&ctx->output, UUID_FMT, UUID_ARGS(&row->uuid));
+    }
+    ds_put_char(&ctx->output, '\n');
+
+    if (!show || show->recurse) {
+        return;
+    }
+
+    show->recurse = true;
+    for (i = 0; i < ARRAY_SIZE(show->columns); i++) {
+        const struct ovsdb_idl_column *column = show->columns[i];
+        const struct ovsdb_datum *datum;
+
+        if (!column) {
+            break;
+        }
+
+        datum = ovsdb_idl_read(row, column);
+        if (column->type.key.type == OVSDB_TYPE_UUID &&
+            column->type.key.u.uuid.refTableName) {
+            struct cmd_show_table *ref_show;
+            size_t j;
+
+            ref_show = cmd_show_find_table_by_name(
+                column->type.key.u.uuid.refTableName);
+            if (ref_show) {
+                for (j = 0; j < datum->n; j++) {
+                    const struct ovsdb_idl_row *ref_row;
+
+                    ref_row = ovsdb_idl_get_row_for_uuid(ctx->idl,
+                                                         ref_show->table,
+                                                         &datum->keys[j].uuid);
+                    if (ref_row) {
+                        cmd_show_row(ctx, ref_row, level + 1);
+                    }
+                }
+                continue;
+            }
+        }
+
+        if (!ovsdb_datum_is_default(datum, &column->type)) {
+            ds_put_char_multiple(&ctx->output, ' ', (level + 1) * 4);
+            ds_put_format(&ctx->output, "%s: ", column->name);
+            ovsdb_datum_to_string(datum, &column->type, &ctx->output);
+            ds_put_char(&ctx->output, '\n');
+        }
+    }
+    show->recurse = false;
+}
+
+static void
+cmd_show(struct vsctl_context *ctx)
+{
+    const struct ovsdb_idl_row *row;
+
+    for (row = ovsdb_idl_first_row(ctx->idl, cmd_show_tables[0].table);
+         row; row = ovsdb_idl_next_row(row)) {
+        cmd_show_row(ctx, row, 0);
+    }
+}
+
 static void
 pre_cmd_emer_reset(struct vsctl_context *ctx)
 {
@@ -1111,7 +1292,7 @@ cmd_emer_reset(struct vsctl_context *ctx)
 static void
 cmd_add_br(struct vsctl_context *ctx)
 {
-    bool may_exist = shash_find(&ctx->options, "--may-exist") != 0;
+    bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL;
     const char *br_name, *parent_name;
     struct vsctl_info info;
     int vlan;
@@ -1563,7 +1744,7 @@ add_port(struct vsctl_context *ctx,
 static void
 cmd_add_port(struct vsctl_context *ctx)
 {
-    bool may_exist = shash_find(&ctx->options, "--may-exist") != 0;
+    bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL;
 
     add_port(ctx, ctx->argv[1], ctx->argv[2], may_exist, false,
              &ctx->argv[2], 1, &ctx->argv[3], ctx->argc - 3);
@@ -1572,7 +1753,7 @@ cmd_add_port(struct vsctl_context *ctx)
 static void
 cmd_add_bond(struct vsctl_context *ctx)
 {
-    bool may_exist = shash_find(&ctx->options, "--may-exist") != 0;
+    bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL;
     bool fake_iface = shash_find(&ctx->options, "--fake-iface");
     int n_ifaces;
     int i;
@@ -2115,16 +2296,6 @@ static const struct vsctl_table_class tables[] = {
      {{&ovsrec_table_port, &ovsrec_port_col_name, &ovsrec_port_col_qos},
       {NULL, NULL, NULL}}},
 
-    {&ovsrec_table_monitor,
-     {{&ovsrec_table_interface,
-       &ovsrec_interface_col_name,
-       &ovsrec_interface_col_monitor},
-      {NULL, NULL, NULL}}},
-
-    {&ovsrec_table_maintenance_point,
-     {{NULL, NULL, NULL},
-      {NULL, NULL, NULL}}},
-
     {&ovsrec_table_queue,
      {{NULL, NULL, NULL},
       {NULL, NULL, NULL}}},
@@ -3421,7 +3592,9 @@ do_vsctl(const char *args, struct vsctl_command *commands, size_t n_commands,
         struct vsctl_context ctx;
 
         vsctl_context_init(&ctx, c, idl, txn, ovs, symtab);
-        (c->syntax->run)(&ctx);
+        if (c->syntax->run) {
+            (c->syntax->run)(&ctx);
+        }
         vsctl_context_done(&ctx, c);
 
         if (ctx.try_again) {
@@ -3565,6 +3738,7 @@ try_again:
 static const struct vsctl_command_syntax all_commands[] = {
     /* Open vSwitch commands. */
     {"init", 0, 0, NULL, cmd_init, NULL, "", RW},
+    {"show", 0, 0, pre_cmd_show, cmd_show, NULL, "", RO},
 
     /* Bridge commands. */
     {"add-br", 1, 3, pre_get_info, cmd_add_br, NULL, "--may-exist", RW},
@@ -3614,7 +3788,8 @@ static const struct vsctl_command_syntax all_commands[] = {
     /* Switch commands. */
     {"emer-reset", 0, 0, pre_cmd_emer_reset, cmd_emer_reset, NULL, "", RW},
 
-    /* Parameter commands. */
+    /* Database commands. */
+    {"comment", 0, INT_MAX, NULL, NULL, NULL, "", RO},
     {"get", 2, INT_MAX, pre_cmd_get, cmd_get, NULL, "--if-exists,--id=", RO},
     {"list", 1, INT_MAX, pre_cmd_list, cmd_list, NULL, "--columns=", RO},
     {"find", 1, INT_MAX, pre_cmd_find, cmd_find, NULL, "--columns=", RO},