[ovs-dev] [PATCH 3/3] ovn-controller: Update stale chassis entry at init
Dumitru Ceara
dceara at redhat.com
Wed Jun 12 10:39:01 UTC 2019
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 at 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(-)
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) {
More information about the dev
mailing list