ovn-controller: Tolerate missing integration bridge.
authorBen Pfaff <blp@nicira.com>
Wed, 29 Jul 2015 16:02:09 +0000 (09:02 -0700)
committerBen Pfaff <blp@nicira.com>
Thu, 30 Jul 2015 17:11:53 +0000 (10:11 -0700)
Until now, if the integration bridge was missing, ovn-controller exited.
This commit makes it wait until the integration bridge is created.

Signed-off-by: Ben Pfaff <blp@nicira.com>
Acked-by: Justin Pettit <jpettit@nicira.com>
ovn/controller/binding.c
ovn/controller/encaps.c
ovn/controller/ofctrl.c
ovn/controller/ovn-controller.c

index 2cb0b42..849dddf 100644 (file)
@@ -91,7 +91,12 @@ binding_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int,
 
     sset_init(&lports);
     sset_init(&all_lports);
-    get_local_iface_ids(br_int, &lports);
+    if (br_int) {
+        get_local_iface_ids(br_int, &lports);
+    } else {
+        /* We have no integration bridge, therefore no local logical ports.
+         * We'll remove our chassis from all port binding records below. */
+    }
     sset_clone(&all_lports, &lports);
 
     ovsdb_idl_txn_add_comment(ctx->ovnsb_idl_txn,
index 7aa523f..5ae9267 100644 (file)
@@ -231,7 +231,7 @@ void
 encaps_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int,
            const char *chassis_id)
 {
-    if (!ctx->ovs_idl_txn) {
+    if (!ctx->ovs_idl_txn || !br_int) {
         return;
     }
 
@@ -298,6 +298,10 @@ encaps_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int,
 bool
 encaps_cleanup(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int)
 {
+    if (!br_int) {
+        return true;
+    }
+
     /* Delete all the OVS-created tunnels from the integration bridge. */
     struct ovsrec_port **ports
         = xmalloc(sizeof *br_int->ports * br_int->n_ports);
index e701f8b..7b3772d 100644 (file)
@@ -92,13 +92,17 @@ ofctrl_init(void)
 void
 ofctrl_run(const struct ovsrec_bridge *br_int, struct hmap *flow_table)
 {
-    char *target;
-    target = xasprintf("unix:%s/%s.mgmt", ovs_rundir(), br_int->name);
-    if (strcmp(target, rconn_get_target(swconn))) {
-        VLOG_INFO("%s: connecting to switch", target);
-        rconn_connect(swconn, target, target);
+    if (br_int) {
+        char *target;
+        target = xasprintf("unix:%s/%s.mgmt", ovs_rundir(), br_int->name);
+        if (strcmp(target, rconn_get_target(swconn))) {
+            VLOG_INFO("%s: connecting to switch", target);
+            rconn_connect(swconn, target, target);
+        }
+        free(target);
+    } else {
+        rconn_disconnect(swconn);
     }
-    free(target);
 
     rconn_run(swconn);
 
index b7b1599..594c384 100644 (file)
@@ -83,6 +83,8 @@ get_bridge(struct controller_ctx *ctx, const char *name)
         }
     }
 
+    static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
+    VLOG_WARN_RL(&rl, "%s: integration bridge does not exist", name);
     return NULL;
 }
 
@@ -108,7 +110,6 @@ get_core_config(struct controller_ctx *ctx, char **br_int_namep,
             exit(EXIT_FAILURE);
         }
 
-        const struct ovsrec_bridge *br_int;
         const char *remote, *system_id, *br_int_name;
 
         br_int_name = smap_get(&cfg->external_ids, "ovn-bridge");
@@ -116,13 +117,6 @@ get_core_config(struct controller_ctx *ctx, char **br_int_namep,
             br_int_name = DEFAULT_BRIDGE_NAME;
         }
 
-        br_int = get_bridge(ctx, br_int_name);
-        if (!br_int) {
-            VLOG_INFO("Integration bridge '%s' does not exist.  Waiting...",
-                      br_int_name);
-            goto try_again;
-        }
-
         remote = smap_get(&cfg->external_ids, "ovn-remote");
         if (!remote) {
             VLOG_INFO("OVN OVSDB remote not specified.  Waiting...");
@@ -292,24 +286,19 @@ main(int argc, char *argv[])
         ctx.ovnsb_idl_txn = idl_loop_run(&ovnsb_idl_loop);
         ctx.ovs_idl_txn = idl_loop_run(&ovs_idl_loop);
 
-        /* xxx If run into any surprising changes, we exit.  We should
-         * xxx handle this more gracefully. */
         const struct ovsrec_bridge *br_int = get_bridge(&ctx, br_int_name);
-        if (!br_int) {
-            VLOG_ERR("Integration bridge '%s' disappeared", br_int_name);
-            retval = EXIT_FAILURE;
-            goto exit;
-        }
 
         chassis_run(&ctx, chassis_id);
         encaps_run(&ctx, br_int, chassis_id);
         binding_run(&ctx, br_int, chassis_id);
 
-        struct hmap flow_table = HMAP_INITIALIZER(&flow_table);
-        pipeline_run(&ctx, &flow_table);
-        physical_run(&ctx, br_int, chassis_id, &flow_table);
-        ofctrl_run(br_int, &flow_table);
-        hmap_destroy(&flow_table);
+        if (br_int) {
+            struct hmap flow_table = HMAP_INITIALIZER(&flow_table);
+            pipeline_run(&ctx, &flow_table);
+            physical_run(&ctx, br_int, chassis_id, &flow_table);
+            ofctrl_run(br_int, &flow_table);
+            hmap_destroy(&flow_table);
+        }
 
         unixctl_server_run(unixctl);
 
@@ -321,7 +310,9 @@ main(int argc, char *argv[])
         idl_loop_commit_and_wait(&ovnsb_idl_loop);
         idl_loop_commit_and_wait(&ovs_idl_loop);
 
-        ofctrl_wait();
+        if (br_int) {
+            ofctrl_wait();
+        }
         poll_block();
     }
 
@@ -331,14 +322,7 @@ main(int argc, char *argv[])
         ctx.ovnsb_idl_txn = idl_loop_run(&ovnsb_idl_loop);
         ctx.ovs_idl_txn = idl_loop_run(&ovs_idl_loop);
 
-        /* xxx If run into any surprising changes, we exit.  We should
-         * xxx handle this more gracefully. */
         const struct ovsrec_bridge *br_int = get_bridge(&ctx, br_int_name);
-        if (!br_int) {
-            VLOG_ERR("Integration bridge '%s' disappeared", br_int_name);
-            retval = EXIT_FAILURE;
-            goto exit;
-        }
 
         /* Run all of the cleanup functions, even if one of them returns false.
          * We're done if all of them return true. */
@@ -354,7 +338,6 @@ main(int argc, char *argv[])
         poll_block();
     }
 
-exit:
     unixctl_server_destroy(unixctl);
     pipeline_destroy(&ctx);
     ofctrl_destroy();