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 <dce...@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 5d4ecbd..04b98d8 100644 --- a/ovn/controller/chassis.c +++ b/ovn/controller/chassis.c @@ -436,17 +436,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, @@ -455,8 +487,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; } @@ -523,6 +560,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) @@ -536,7 +574,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 1366683..16a131a 100644 --- a/ovn/controller/chassis.h +++ b/ovn/controller/chassis.h @@ -33,6 +33,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 7c0c6f6..c4883aa 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -1923,14 +1923,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) { _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev