ovs-vsctl: Add commands to get/delete/set manager connections.
[openvswitch] / utilities / ovs-vsctl.c
index c55818bd29c201f592e3932020d754956693c0c4..911d8fe822db11fb0bdc7c97a3dace09652ab5e1 100644 (file)
@@ -493,6 +493,11 @@ Controller commands:\n\
   del-fail-mode BRIDGE       delete the fail-mode for BRIDGE\n\
   set-fail-mode BRIDGE MODE  set the fail-mode for BRIDGE to MODE\n\
 \n\
+Manager commands:\n\
+  get-manager                print all manager(s)\n\
+  del-manager                delete all manager(s)\n\
+  set-manager TARGET...      set the list of manager(s) to TARGET(s)\n\
+\n\
 SSL commands:\n\
   get-ssl                     print the SSL configuration\n\
   del-ssl                     delete the SSL configuration\n\
@@ -978,9 +983,11 @@ 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);
 
     ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_controller);
+    ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_fail_mode);
     ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_mirrors);
     ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_netflow);
     ovsdb_idl_add_column(ctx->idl, &ovsrec_bridge_col_sflow);
@@ -1004,12 +1011,14 @@ cmd_emer_reset(struct vsctl_context *ctx)
     const struct ovsrec_interface *iface;
     const struct ovsrec_mirror *mirror, *next_mirror;
     const struct ovsrec_controller *ctrl, *next_ctrl;
+    const struct ovsrec_manager *mgr, *next_mgr;
     const struct ovsrec_netflow *nf, *next_nf;
     const struct ovsrec_ssl *ssl, *next_ssl;
     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);
 
     OVSREC_BRIDGE_FOR_EACH (br, idl) {
@@ -1018,6 +1027,7 @@ cmd_emer_reset(struct vsctl_context *ctx)
         char *hw_val = NULL;
 
         ovsrec_bridge_set_controller(br, NULL, 0);
+        ovsrec_bridge_set_fail_mode(br, NULL);
         ovsrec_bridge_set_mirrors(br, NULL, 0);
         ovsrec_bridge_set_netflow(br, NULL);
         ovsrec_bridge_set_sflow(br, NULL);
@@ -1058,6 +1068,10 @@ cmd_emer_reset(struct vsctl_context *ctx)
         ovsrec_controller_delete(ctrl);
     }
 
+    OVSREC_MANAGER_FOR_EACH_SAFE (mgr, next_mgr, idl) {
+        ovsrec_manager_delete(mgr);
+    }
+
     OVSREC_NETFLOW_FOR_EACH_SAFE (nf, next_nf, idl) {
         ovsrec_netflow_delete(nf);
     }
@@ -1852,6 +1866,116 @@ cmd_set_fail_mode(struct vsctl_context *ctx)
     free_info(&info);
 }
 
+static void
+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) {
+        const struct ovsrec_manager *mgr = ovs->manager_options[i];
+
+        ovsrec_manager_verify_target(mgr);
+    }
+}
+
+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);
+}
+
+static void
+cmd_get_manager(struct vsctl_context *ctx)
+{
+    const struct ovsrec_open_vswitch *ovs = ctx->ovs;
+    struct svec targets;
+    size_t i;
+
+    verify_managers(ovs);
+
+    /* 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);
+    }
+
+    svec_sort_unique(&targets);
+    for (i = 0; i < targets.n; i++) {
+        ds_put_format(&ctx->output, "%s\n", targets.names[i]);
+    }
+    svec_destroy(&targets);
+}
+
+static void
+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]);
+    }
+
+    /* Delete 'Manager' row refs in 'manager_options' column. */
+    ovsrec_open_vswitch_set_manager_options(ovs, NULL, 0);
+}
+
+static void
+cmd_del_manager(struct vsctl_context *ctx)
+{
+    const struct ovsrec_open_vswitch *ovs = ctx->ovs;
+
+    verify_managers(ovs);
+    delete_managers(ctx);
+}
+
+static void
+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++) {
+        managers[i] = ovsrec_manager_insert(ctx->txn);
+        ovsrec_manager_set_target(managers[i], targets[i]);
+    }
+
+    /* Store uuids of new Manager rows in 'manager_options' column. */
+    ovsrec_open_vswitch_set_manager_options(ctx->ovs, managers, n);
+    free(managers);
+}
+
+static void
+cmd_set_manager(struct vsctl_context *ctx)
+{
+    const size_t n = ctx->argc - 1;
+
+    verify_managers(ctx->ovs);
+    delete_managers(ctx);
+    insert_managers(ctx, &ctx->argv[1], n);
+}
+
 static void
 pre_cmd_get_ssl(struct vsctl_context *ctx)
 {
@@ -3178,7 +3302,6 @@ do_vsctl(const char *args, struct vsctl_command *commands, size_t n_commands,
 
     for (c = commands; c < &commands[n_commands]; c++) {
         struct ds *ds = &c->output;
-        struct shash_node *node;
 
         if (oneline) {
             size_t j;
@@ -3205,10 +3328,7 @@ do_vsctl(const char *args, struct vsctl_command *commands, size_t n_commands,
         }
         ds_destroy(&c->output);
 
-        SHASH_FOR_EACH (node, &c->options) {
-            free(node->data);
-        }
-        shash_destroy(&c->options);
+        smap_destroy(&c->options);
     }
     free(commands);
 
@@ -3282,6 +3402,11 @@ static const struct vsctl_command_syntax all_commands[] = {
     {"del-fail-mode", 1, 1, pre_get_info, cmd_del_fail_mode, NULL, "", RW},
     {"set-fail-mode", 2, 2, pre_get_info, cmd_set_fail_mode, NULL, "", RW},
 
+    /* Manager commands. */
+    {"get-manager", 0, 0, pre_manager, cmd_get_manager, NULL, "", RO},
+    {"del-manager", 0, INT_MAX, pre_manager, cmd_del_manager, NULL, "", RW},
+    {"set-manager", 1, INT_MAX, pre_manager, cmd_set_manager, NULL, "", RW},
+
     /* SSL commands. */
     {"get-ssl", 0, 0, pre_cmd_get_ssl, cmd_get_ssl, NULL, "", RO},
     {"del-ssl", 0, 0, pre_cmd_del_ssl, cmd_del_ssl, NULL, "", RW},