[ovs-dev,3/3] ovn-controller: Update stale chassis entry at init
diff mbox series

Message ID 20190612103901.18479.52661.stgit@dceara.remote.csb
State Superseded
Headers show
Series
  • ovn-controller: Fix and refactor chassis ovn-sbdb record init
Related show

Commit Message

Dumitru Ceara June 12, 2019, 10:39 a.m. UTC
The first time ovn-controller initializes the Chassis entry (shortly
after start up) we first look if there is a stale Chassis record in the
OVN_Southbound DB by checking if any of the old Encap entries associated
to the Chassis record match the new tunnel configuration. If found it
means that ovn-controller didn't shutdown gracefully last time it was
run so it didn't cleanup the Chassis table. Potentially in the meantime
the OVS system-id was also changed. We then update the stale entry with
the new configuration and store the last configured chassis-id in memory
to avoid walking the Chassis table every time.

Signed-off-by: Dumitru Ceara <dceara@redhat.com>
---
 ovn/controller/chassis.c        |   49 +++++++++++++++++++++++++++++++++++----
 ovn/controller/chassis.h        |    1 +
 ovn/controller/ovn-controller.c |    6 +++--
 3 files changed, 49 insertions(+), 7 deletions(-)

Patch
diff mbox series

diff --git a/ovn/controller/chassis.c b/ovn/controller/chassis.c
index f92084d..bb5627e 100644
--- a/ovn/controller/chassis.c
+++ b/ovn/controller/chassis.c
@@ -419,17 +419,49 @@  chassis_build_encaps(struct ovsdb_idl_txn *ovnsb_idl_txn,
     return encaps;
 }
 
+/*
+ * Returns a pointer to a chassis record from 'chassis_table' that
+ * matches at least one tunnel config.
+ */
+static const struct sbrec_chassis *
+chassis_get_stale_record(const struct sbrec_chassis_table *chassis_table,
+                         const struct ovs_chassis_cfg *ovs_cfg,
+                         const char *chassis_id)
+{
+    const struct sbrec_chassis *chassis_rec;
+
+    SBREC_CHASSIS_TABLE_FOR_EACH (chassis_rec, chassis_table) {
+        for (size_t i = 0; i < chassis_rec->n_encaps; i++) {
+            if (sset_contains(&ovs_cfg->encap_type_set,
+                              chassis_rec->encaps[i]->type) &&
+                    sset_contains(&ovs_cfg->encap_ip_set,
+                                  chassis_rec->encaps[i]->ip)) {
+                return chassis_rec;
+            }
+            if (strcmp(chassis_rec->name, chassis_id) == 0) {
+                return chassis_rec;
+            }
+        }
+    }
+
+    return NULL;
+}
+
 /* If this is a chassis config update after we initialized the record once
  * then we should always be able to find it with the ID we saved in
  * chassis_state.
- * Otherwise (i.e., first time we create the record) we create a new record.
+ * Otherwise (i.e., first time we create the record) then we check if there's
+ * a stale record from a previous controller run that didn't end gracefully
+ * and reuse it. If not then we create a new record.
  */
 static const struct sbrec_chassis *
 chassis_get_record(struct ovsdb_idl_txn *ovnsb_idl_txn,
                    struct ovsdb_idl_index *sbrec_chassis_by_name,
+                   const struct sbrec_chassis_table *chassis_table,
+                   const struct ovs_chassis_cfg *ovs_cfg,
                    const char *chassis_id)
 {
-    const struct sbrec_chassis *chassis_rec = NULL;
+    const struct sbrec_chassis *chassis_rec;
 
     if (chassis_info_id_inited(&chassis_state)) {
         chassis_rec = chassis_lookup_by_name(sbrec_chassis_by_name,
@@ -438,8 +470,13 @@  chassis_get_record(struct ovsdb_idl_txn *ovnsb_idl_txn,
             VLOG_WARN("Could not find Chassis : stored (%s) ovs (%s)",
                       chassis_info_id(&chassis_state), chassis_id);
         }
-    } else if (ovnsb_idl_txn) {
-        chassis_rec = sbrec_chassis_insert(ovnsb_idl_txn);
+    } else {
+        chassis_rec =
+            chassis_get_stale_record(chassis_table, ovs_cfg, chassis_id);
+
+        if (!chassis_rec && ovnsb_idl_txn) {
+            chassis_rec = sbrec_chassis_insert(ovnsb_idl_txn);
+        }
     }
     return chassis_rec;
 }
@@ -504,6 +541,7 @@  const struct sbrec_chassis *
 chassis_run(struct ovsdb_idl_txn *ovnsb_idl_txn,
             struct ovsdb_idl_index *sbrec_chassis_by_name,
             const struct ovsrec_open_vswitch_table *ovs_table,
+            const struct sbrec_chassis_table *chassis_table,
             const char *chassis_id,
             const struct ovsrec_bridge *br_int,
             const struct sset *transport_zones)
@@ -517,7 +555,8 @@  chassis_run(struct ovsdb_idl_txn *ovnsb_idl_txn,
     }
 
     const struct sbrec_chassis *chassis_rec =
-        chassis_get_record(ovnsb_idl_txn, sbrec_chassis_by_name, chassis_id);
+        chassis_get_record(ovnsb_idl_txn, sbrec_chassis_by_name,
+                           chassis_table, &ovs_cfg, chassis_id);
 
     /* If we found (or created) a record, update it with the correct config
      * and store the current chassis_id for fast lookup in case it gets
diff --git a/ovn/controller/chassis.h b/ovn/controller/chassis.h
index 8d57a09..7a4751a 100644
--- a/ovn/controller/chassis.h
+++ b/ovn/controller/chassis.h
@@ -32,6 +32,7 @@  const struct sbrec_chassis *chassis_run(
     struct ovsdb_idl_txn *ovnsb_idl_txn,
     struct ovsdb_idl_index *sbrec_chassis_by_name,
     const struct ovsrec_open_vswitch_table *,
+    const struct sbrec_chassis_table *,
     const char *chassis_id, const struct ovsrec_bridge *br_int,
     const struct sset *transport_zones);
 bool chassis_cleanup(struct ovsdb_idl_txn *ovnsb_idl_txn,
diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c
index f69e49e..07d88c1 100644
--- a/ovn/controller/ovn-controller.c
+++ b/ovn/controller/ovn-controller.c
@@ -1887,14 +1887,16 @@  main(int argc, char *argv[])
                 ovsrec_bridge_table_get(ovs_idl_loop.idl);
             const struct ovsrec_open_vswitch_table *ovs_table =
                 ovsrec_open_vswitch_table_get(ovs_idl_loop.idl);
+            const struct sbrec_chassis_table *chassis_table =
+                sbrec_chassis_table_get(ovnsb_idl_loop.idl);
             const struct ovsrec_bridge *br_int =
                 process_br_int(ovs_idl_txn, bridge_table, ovs_table);
             const char *chassis_id = get_ovs_chassis_id(ovs_table);
             const struct sbrec_chassis *chassis = NULL;
             if (chassis_id) {
                 chassis = chassis_run(ovnsb_idl_txn, sbrec_chassis_by_name,
-                                      ovs_table, chassis_id, br_int,
-                                      &transport_zones);
+                                      ovs_table, chassis_table, chassis_id,
+                                      br_int, &transport_zones);
             }
 
             if (br_int) {