ovn-nbd: Match bindings on lport name.
authorRussell Bryant <rbryant@redhat.com>
Wed, 15 Apr 2015 01:52:52 +0000 (21:52 -0400)
committerBen Pfaff <blp@nicira.com>
Thu, 16 Apr 2015 17:52:07 +0000 (10:52 -0700)
When ovn-nbd is looking through bindings to figure out if any logical
ports in the northbound DB need to have their 'up' state changed, it
should be using the logical port's name instead of UUID for matching
up to rows in the OVN db.

The switch to using the name instead of UUID means we don't have a
quick lookup so we use the same approach that's used for handling
updates in the other direction.  We start by hashing all of the
logical ports by name.  As we iterate through the bindings, we can
then look up ports by name quickly.

Signed-off-by: Russell Bryant <rbryant@redhat.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
ovn/ovn-nbd.c

index 230437e..a6390a3 100644 (file)
@@ -209,35 +209,57 @@ ovnnb_db_changed(struct nbd_context *ctx)
 static void
 ovnsb_db_changed(struct nbd_context *ctx)
 {
-    const struct sbrec_bindings *bindings;
+    struct hmap lports_hmap;
+    const struct sbrec_bindings *binding;
+    const struct nbrec_logical_port *lport;
+
+    struct lport_hash_node {
+        struct hmap_node node;
+        const struct nbrec_logical_port *lport;
+    } *hash_node, *hash_node_next;
 
     VLOG_DBG("Recalculating port up states for ovn-nb db.");
 
-    SBREC_BINDINGS_FOR_EACH(bindings, ctx->ovnsb_idl) {
-        const struct nbrec_logical_port *lport;
-        struct uuid lport_uuid;
+    hmap_init(&lports_hmap);
 
-        if (!uuid_from_string(&lport_uuid, bindings->logical_port)) {
-            VLOG_WARN("Invalid logical port UUID '%s' in Bindings table.",
-                    bindings->logical_port);
-            continue;
+    NBREC_LOGICAL_PORT_FOR_EACH(lport, ctx->ovnnb_idl) {
+        hash_node = xzalloc(sizeof *hash_node);
+        hash_node->lport = lport;
+        hmap_insert(&lports_hmap, &hash_node->node,
+                hash_string(lport->name, 0));
+    }
+
+    SBREC_BINDINGS_FOR_EACH(binding, ctx->ovnsb_idl) {
+        lport = NULL;
+        HMAP_FOR_EACH_WITH_HASH(hash_node, node,
+                hash_string(binding->logical_port, 0), &lports_hmap) {
+            if (!strcmp(binding->logical_port, hash_node->lport->name)) {
+                lport = hash_node->lport;
+                break;
+            }
         }
 
-        lport = nbrec_logical_port_get_for_uuid(ctx->ovnnb_idl, &lport_uuid);
         if (!lport) {
-            VLOG_WARN("No logical port '%s' found in OVN-nb db.",
-                    bindings->logical_port);
+            /* The logical port doesn't exist for this binding.  This can happen
+             * under normal circumstances when ovn-nbd hasn't gotten around to
+             * pruning the Binding yet. */
             continue;
         }
 
-        if (*bindings->chassis && (!lport->up || !*lport->up)) {
+        if (*binding->chassis && (!lport->up || !*lport->up)) {
             bool up = true;
             nbrec_logical_port_set_up(lport, &up, 1);
-        } else if (!*bindings->chassis && (!lport->up || *lport->up)) {
+        } else if (!*binding->chassis && (!lport->up || *lport->up)) {
             bool up = false;
             nbrec_logical_port_set_up(lport, &up, 1);
         }
     }
+
+    HMAP_FOR_EACH_SAFE(hash_node, hash_node_next, node, &lports_hmap) {
+        hmap_remove(&lports_hmap, &hash_node->node);
+        free(hash_node);
+    }
+    hmap_destroy(&lports_hmap);
 }
 \f
 static const char *