|
|
9219d1 |
From 59103ff841797ad399e1679bfecfb6256bb6a0c4 Mon Sep 17 00:00:00 2001
|
|
|
9219d1 |
From: Dumitru Ceara <dceara@redhat.com>
|
|
|
9219d1 |
Date: Thu, 3 Sep 2020 17:04:01 +0200
|
|
|
9219d1 |
Subject: [PATCH 2/2] chassis: Fix chassis_private record updates when the
|
|
|
9219d1 |
system-id changes.
|
|
|
9219d1 |
|
|
|
9219d1 |
Also:
|
|
|
9219d1 |
- Change conditional monitoring for Chassis_Private to use the chassis uuid
|
|
|
9219d1 |
instead of chassis name. Using the chassis->name field does not work
|
|
|
9219d1 |
because this is the old value of the field and would cause ovsdb-server
|
|
|
9219d1 |
to inform ovn-controller that the updated Chassis_Private record was
|
|
|
9219d1 |
"deleted" because it doesn't match the monitor condition anymore.
|
|
|
9219d1 |
- Allow ovn-sbctl to access Chassis_Private records by name.
|
|
|
9219d1 |
|
|
|
9219d1 |
Reported-at: https://bugzilla.redhat.com/1873032
|
|
|
9219d1 |
Reported-by: Ying Xu <yinxu@redhat.com>
|
|
|
9219d1 |
CC: Han Zhou <hzhou@ovn.org>
|
|
|
9219d1 |
Fixes: 4adc10f58127 ("Avoid nb_cfg update notification flooding")
|
|
|
9219d1 |
Signed-off-by: Dumitru Ceara <dceara@redhat.com>
|
|
|
9219d1 |
Signed-off-by: Numan Siddique <numans@ovn.org>
|
|
|
9219d1 |
(cherry picked from upstream commit dce1af31b550a9fb57b01cbe0b4139b6768f2521)
|
|
|
9219d1 |
|
|
|
9219d1 |
Change-Id: Ic5f7f0b820b43715e1f1cf68b215374daf237fd5
|
|
|
9219d1 |
---
|
|
|
9219d1 |
controller/chassis.c | 92 +++++++++++++++++++++++++++++++++++++++------
|
|
|
9219d1 |
controller/chassis.h | 2 +
|
|
|
9219d1 |
controller/ovn-controller.c | 13 ++++---
|
|
|
9219d1 |
tests/ovn-controller.at | 18 +++++++++
|
|
|
9219d1 |
utilities/ovn-sbctl.c | 3 ++
|
|
|
9219d1 |
5 files changed, 112 insertions(+), 16 deletions(-)
|
|
|
9219d1 |
|
|
|
9219d1 |
diff --git a/controller/chassis.c b/controller/chassis.c
|
|
|
9219d1 |
index 773d966..8231169 100644
|
|
|
9219d1 |
--- a/controller/chassis.c
|
|
|
9219d1 |
+++ b/controller/chassis.c
|
|
|
9219d1 |
@@ -633,6 +633,77 @@ chassis_update(const struct sbrec_chassis *chassis_rec,
|
|
|
9219d1 |
return true;
|
|
|
9219d1 |
}
|
|
|
9219d1 |
|
|
|
9219d1 |
+/*
|
|
|
9219d1 |
+ * Returns a pointer to a chassis_private record from 'chassis_pvt_table' that
|
|
|
9219d1 |
+ * matches the chassis record.
|
|
|
9219d1 |
+ */
|
|
|
9219d1 |
+static const struct sbrec_chassis_private *
|
|
|
9219d1 |
+chassis_private_get_stale_record(
|
|
|
9219d1 |
+ const struct sbrec_chassis_private_table *chassis_pvt_table,
|
|
|
9219d1 |
+ const struct sbrec_chassis *chassis)
|
|
|
9219d1 |
+{
|
|
|
9219d1 |
+ const struct sbrec_chassis_private *chassis_pvt_rec;
|
|
|
9219d1 |
+
|
|
|
9219d1 |
+ SBREC_CHASSIS_PRIVATE_TABLE_FOR_EACH (chassis_pvt_rec, chassis_pvt_table) {
|
|
|
9219d1 |
+ if (chassis_pvt_rec->chassis == chassis) {
|
|
|
9219d1 |
+ return chassis_pvt_rec;
|
|
|
9219d1 |
+ }
|
|
|
9219d1 |
+ }
|
|
|
9219d1 |
+
|
|
|
9219d1 |
+ return NULL;
|
|
|
9219d1 |
+}
|
|
|
9219d1 |
+
|
|
|
9219d1 |
+/* If this is a chassis_private config update after we initialized the record
|
|
|
9219d1 |
+ * once then we should always be able to find it with the ID we saved in
|
|
|
9219d1 |
+ * chassis_state.
|
|
|
9219d1 |
+ * Otherwise (i.e., first time we created the chassis record or if the
|
|
|
9219d1 |
+ * system-id changed) then we check if there's a stale record from a previous
|
|
|
9219d1 |
+ * controller run that didn't end gracefully and reuse it. If not then we
|
|
|
9219d1 |
+ * create a new record.
|
|
|
9219d1 |
+ *
|
|
|
9219d1 |
+ * Returns the local chassis record.
|
|
|
9219d1 |
+ */
|
|
|
9219d1 |
+static const struct sbrec_chassis_private *
|
|
|
9219d1 |
+chassis_private_get_record(
|
|
|
9219d1 |
+ struct ovsdb_idl_txn *ovnsb_idl_txn,
|
|
|
9219d1 |
+ struct ovsdb_idl_index *sbrec_chassis_pvt_by_name,
|
|
|
9219d1 |
+ const struct sbrec_chassis_private_table *chassis_pvt_table,
|
|
|
9219d1 |
+ const struct sbrec_chassis *chassis)
|
|
|
9219d1 |
+{
|
|
|
9219d1 |
+ const struct sbrec_chassis_private *chassis_p = NULL;
|
|
|
9219d1 |
+
|
|
|
9219d1 |
+ if (chassis_info_id_inited(&chassis_state)) {
|
|
|
9219d1 |
+ chassis_p =
|
|
|
9219d1 |
+ chassis_private_lookup_by_name(sbrec_chassis_pvt_by_name,
|
|
|
9219d1 |
+ chassis_info_id(&chassis_state));
|
|
|
9219d1 |
+ }
|
|
|
9219d1 |
+
|
|
|
9219d1 |
+ if (!chassis_p) {
|
|
|
9219d1 |
+ chassis_p = chassis_private_get_stale_record(chassis_pvt_table,
|
|
|
9219d1 |
+ chassis);
|
|
|
9219d1 |
+ }
|
|
|
9219d1 |
+
|
|
|
9219d1 |
+ if (!chassis_p && ovnsb_idl_txn) {
|
|
|
9219d1 |
+ return sbrec_chassis_private_insert(ovnsb_idl_txn);
|
|
|
9219d1 |
+ }
|
|
|
9219d1 |
+
|
|
|
9219d1 |
+ return chassis_p;
|
|
|
9219d1 |
+}
|
|
|
9219d1 |
+
|
|
|
9219d1 |
+static void
|
|
|
9219d1 |
+chassis_private_update(const struct sbrec_chassis_private *chassis_pvt,
|
|
|
9219d1 |
+ const struct sbrec_chassis *chassis,
|
|
|
9219d1 |
+ const char *chassis_id)
|
|
|
9219d1 |
+{
|
|
|
9219d1 |
+ if (!chassis_pvt->name || strcmp(chassis_pvt->name, chassis_id)) {
|
|
|
9219d1 |
+ sbrec_chassis_private_set_name(chassis_pvt, chassis_id);
|
|
|
9219d1 |
+ }
|
|
|
9219d1 |
+
|
|
|
9219d1 |
+ if (chassis_pvt->chassis != chassis) {
|
|
|
9219d1 |
+ sbrec_chassis_private_set_chassis(chassis_pvt, chassis);
|
|
|
9219d1 |
+ }
|
|
|
9219d1 |
+}
|
|
|
9219d1 |
+
|
|
|
9219d1 |
/* Returns this chassis's Chassis record, if it is available. */
|
|
|
9219d1 |
const struct sbrec_chassis *
|
|
|
9219d1 |
chassis_run(struct ovsdb_idl_txn *ovnsb_idl_txn,
|
|
|
9219d1 |
@@ -640,6 +711,7 @@ chassis_run(struct ovsdb_idl_txn *ovnsb_idl_txn,
|
|
|
9219d1 |
struct ovsdb_idl_index *sbrec_chassis_private_by_name,
|
|
|
9219d1 |
const struct ovsrec_open_vswitch_table *ovs_table,
|
|
|
9219d1 |
const struct sbrec_chassis_table *chassis_table,
|
|
|
9219d1 |
+ const struct sbrec_chassis_private_table *chassis_pvt_table,
|
|
|
9219d1 |
const char *chassis_id,
|
|
|
9219d1 |
const struct ovsrec_bridge *br_int,
|
|
|
9219d1 |
const struct sset *transport_zones,
|
|
|
9219d1 |
@@ -668,7 +740,6 @@ chassis_run(struct ovsdb_idl_txn *ovnsb_idl_txn,
|
|
|
9219d1 |
bool updated = chassis_update(chassis_rec, ovnsb_idl_txn, &ovs_cfg,
|
|
|
9219d1 |
chassis_id, transport_zones);
|
|
|
9219d1 |
|
|
|
9219d1 |
- chassis_info_set_id(&chassis_state, chassis_id);
|
|
|
9219d1 |
if (!existed || updated) {
|
|
|
9219d1 |
ovsdb_idl_txn_add_comment(ovnsb_idl_txn,
|
|
|
9219d1 |
"ovn-controller: %s chassis '%s'",
|
|
|
9219d1 |
@@ -676,17 +747,16 @@ chassis_run(struct ovsdb_idl_txn *ovnsb_idl_txn,
|
|
|
9219d1 |
chassis_id);
|
|
|
9219d1 |
}
|
|
|
9219d1 |
|
|
|
9219d1 |
- const struct sbrec_chassis_private *chassis_private_rec =
|
|
|
9219d1 |
- chassis_private_lookup_by_name(sbrec_chassis_private_by_name,
|
|
|
9219d1 |
- chassis_id);
|
|
|
9219d1 |
- if (!chassis_private_rec && ovnsb_idl_txn) {
|
|
|
9219d1 |
- chassis_private_rec = sbrec_chassis_private_insert(ovnsb_idl_txn);
|
|
|
9219d1 |
- sbrec_chassis_private_set_name(chassis_private_rec,
|
|
|
9219d1 |
- chassis_id);
|
|
|
9219d1 |
- sbrec_chassis_private_set_chassis(chassis_private_rec,
|
|
|
9219d1 |
- chassis_rec);
|
|
|
9219d1 |
+ *chassis_private =
|
|
|
9219d1 |
+ chassis_private_get_record(ovnsb_idl_txn,
|
|
|
9219d1 |
+ sbrec_chassis_private_by_name,
|
|
|
9219d1 |
+ chassis_pvt_table, chassis_rec);
|
|
|
9219d1 |
+
|
|
|
9219d1 |
+ if (*chassis_private) {
|
|
|
9219d1 |
+ chassis_private_update(*chassis_private, chassis_rec, chassis_id);
|
|
|
9219d1 |
}
|
|
|
9219d1 |
- *chassis_private = chassis_private_rec;
|
|
|
9219d1 |
+
|
|
|
9219d1 |
+ chassis_info_set_id(&chassis_state, chassis_id);
|
|
|
9219d1 |
}
|
|
|
9219d1 |
|
|
|
9219d1 |
ovs_chassis_cfg_destroy(&ovs_cfg);
|
|
|
9219d1 |
diff --git a/controller/chassis.h b/controller/chassis.h
|
|
|
9219d1 |
index 81055b4..220f726 100644
|
|
|
9219d1 |
--- a/controller/chassis.h
|
|
|
9219d1 |
+++ b/controller/chassis.h
|
|
|
9219d1 |
@@ -26,6 +26,7 @@ struct ovsrec_bridge;
|
|
|
9219d1 |
struct ovsrec_open_vswitch_table;
|
|
|
9219d1 |
struct sbrec_chassis;
|
|
|
9219d1 |
struct sbrec_chassis_table;
|
|
|
9219d1 |
+struct sbrec_chassis_private_table;
|
|
|
9219d1 |
struct sset;
|
|
|
9219d1 |
struct eth_addr;
|
|
|
9219d1 |
struct smap;
|
|
|
9219d1 |
@@ -37,6 +38,7 @@ const struct sbrec_chassis *chassis_run(
|
|
|
9219d1 |
struct ovsdb_idl_index *sbrec_chassis_private_by_name,
|
|
|
9219d1 |
const struct ovsrec_open_vswitch_table *,
|
|
|
9219d1 |
const struct sbrec_chassis_table *,
|
|
|
9219d1 |
+ const struct sbrec_chassis_private_table *,
|
|
|
9219d1 |
const char *chassis_id, const struct ovsrec_bridge *br_int,
|
|
|
9219d1 |
const struct sset *transport_zones,
|
|
|
9219d1 |
const struct sbrec_chassis_private **chassis_private);
|
|
|
9219d1 |
diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
|
|
|
9219d1 |
index 28ca7a8..6aeeb15 100644
|
|
|
9219d1 |
--- a/controller/ovn-controller.c
|
|
|
9219d1 |
+++ b/controller/ovn-controller.c
|
|
|
9219d1 |
@@ -179,7 +179,7 @@ update_sb_monitors(struct ovsdb_idl *ovnsb_idl,
|
|
|
9219d1 |
* chassis */
|
|
|
9219d1 |
sbrec_port_binding_add_clause_type(&pb, OVSDB_F_EQ, "chassisredirect");
|
|
|
9219d1 |
sbrec_port_binding_add_clause_type(&pb, OVSDB_F_EQ, "external");
|
|
|
9219d1 |
- if (chassis) {
|
|
|
9219d1 |
+ if (chassis && !sbrec_chassis_is_new(chassis)) {
|
|
|
9219d1 |
/* This should be mostly redundant with the other clauses for port
|
|
|
9219d1 |
* bindings, but it allows us to catch any ports that are assigned to
|
|
|
9219d1 |
* us but should not be. That way, we can clear their chassis
|
|
|
9219d1 |
@@ -202,9 +202,9 @@ update_sb_monitors(struct ovsdb_idl *ovnsb_idl,
|
|
|
9219d1 |
sbrec_igmp_group_add_clause_chassis(&igmp, OVSDB_F_EQ,
|
|
|
9219d1 |
&chassis->header_.uuid);
|
|
|
9219d1 |
|
|
|
9219d1 |
- /* Monitors Chassis_Private record for current chassis only */
|
|
|
9219d1 |
- sbrec_chassis_private_add_clause_name(&chprv, OVSDB_F_EQ,
|
|
|
9219d1 |
- chassis->name);
|
|
|
9219d1 |
+ /* Monitors Chassis_Private record for current chassis only. */
|
|
|
9219d1 |
+ sbrec_chassis_private_add_clause_chassis(&chprv, OVSDB_F_EQ,
|
|
|
9219d1 |
+ &chassis->header_.uuid);
|
|
|
9219d1 |
} else {
|
|
|
9219d1 |
/* During initialization, we monitor all records in Chassis_Private so
|
|
|
9219d1 |
* that we don't try to recreate existing ones. */
|
|
|
9219d1 |
@@ -2402,6 +2402,8 @@ main(int argc, char *argv[])
|
|
|
9219d1 |
ovsrec_open_vswitch_table_get(ovs_idl_loop.idl);
|
|
|
9219d1 |
const struct sbrec_chassis_table *chassis_table =
|
|
|
9219d1 |
sbrec_chassis_table_get(ovnsb_idl_loop.idl);
|
|
|
9219d1 |
+ const struct sbrec_chassis_private_table *chassis_pvt_table =
|
|
|
9219d1 |
+ sbrec_chassis_private_table_get(ovnsb_idl_loop.idl);
|
|
|
9219d1 |
const struct ovsrec_bridge *br_int =
|
|
|
9219d1 |
process_br_int(ovs_idl_txn, bridge_table, ovs_table);
|
|
|
9219d1 |
const char *chassis_id = get_ovs_chassis_id(ovs_table);
|
|
|
9219d1 |
@@ -2410,7 +2412,8 @@ main(int argc, char *argv[])
|
|
|
9219d1 |
if (chassis_id) {
|
|
|
9219d1 |
chassis = chassis_run(ovnsb_idl_txn, sbrec_chassis_by_name,
|
|
|
9219d1 |
sbrec_chassis_private_by_name,
|
|
|
9219d1 |
- ovs_table, chassis_table, chassis_id,
|
|
|
9219d1 |
+ ovs_table, chassis_table,
|
|
|
9219d1 |
+ chassis_pvt_table, chassis_id,
|
|
|
9219d1 |
br_int, &transport_zones,
|
|
|
9219d1 |
&chassis_private);
|
|
|
9219d1 |
}
|
|
|
9219d1 |
diff --git a/tests/ovn-controller.at b/tests/ovn-controller.at
|
|
|
9219d1 |
index f2faf1f..812946b 100644
|
|
|
9219d1 |
--- a/tests/ovn-controller.at
|
|
|
9219d1 |
+++ b/tests/ovn-controller.at
|
|
|
9219d1 |
@@ -195,6 +195,15 @@ OVS_WAIT_UNTIL([
|
|
|
9219d1 |
chassis_id=$(ovn-sbctl get Chassis "${sysid}" name)
|
|
|
9219d1 |
test "${sysid}" = "${chassis_id}"
|
|
|
9219d1 |
])
|
|
|
9219d1 |
+OVS_WAIT_UNTIL([
|
|
|
9219d1 |
+ chassis_id=$(ovn-sbctl get Chassis_Private "${sysid}" name)
|
|
|
9219d1 |
+ test "${sysid}" = "${chassis_id}"
|
|
|
9219d1 |
+])
|
|
|
9219d1 |
+
|
|
|
9219d1 |
+# Only one Chassis_Private record should exist.
|
|
|
9219d1 |
+OVS_WAIT_UNTIL([
|
|
|
9219d1 |
+ test $(ovn-sbctl --columns _uuid list chassis_private | wc -l) -eq 1
|
|
|
9219d1 |
+])
|
|
|
9219d1 |
|
|
|
9219d1 |
# Simulate system-id changing while ovn-controller is disconnected from the
|
|
|
9219d1 |
# SB.
|
|
|
9219d1 |
@@ -212,6 +221,15 @@ OVS_WAIT_UNTIL([
|
|
|
9219d1 |
chassis_id=$(ovn-sbctl get Chassis "${sysid}" name)
|
|
|
9219d1 |
test "${sysid}" = "${chassis_id}"
|
|
|
9219d1 |
])
|
|
|
9219d1 |
+OVS_WAIT_UNTIL([
|
|
|
9219d1 |
+ chassis_id=$(ovn-sbctl get Chassis_Private "${sysid}" name)
|
|
|
9219d1 |
+ test "${sysid}" = "${chassis_id}"
|
|
|
9219d1 |
+])
|
|
|
9219d1 |
+
|
|
|
9219d1 |
+# Only one Chassis_Private record should exist.
|
|
|
9219d1 |
+OVS_WAIT_UNTIL([
|
|
|
9219d1 |
+ test $(ovn-sbctl --columns _uuid list chassis_private | wc -l) -eq 1
|
|
|
9219d1 |
+])
|
|
|
9219d1 |
|
|
|
9219d1 |
# Gracefully terminate daemons
|
|
|
9219d1 |
OVN_CLEANUP_SBOX([hv])
|
|
|
9219d1 |
diff --git a/utilities/ovn-sbctl.c b/utilities/ovn-sbctl.c
|
|
|
9219d1 |
index 04e082c..d3eec91 100644
|
|
|
9219d1 |
--- a/utilities/ovn-sbctl.c
|
|
|
9219d1 |
+++ b/utilities/ovn-sbctl.c
|
|
|
9219d1 |
@@ -1391,6 +1391,9 @@ cmd_set_ssl(struct ctl_context *ctx)
|
|
|
9219d1 |
static const struct ctl_table_class tables[SBREC_N_TABLES] = {
|
|
|
9219d1 |
[SBREC_TABLE_CHASSIS].row_ids[0] = {&sbrec_chassis_col_name, NULL, NULL},
|
|
|
9219d1 |
|
|
|
9219d1 |
+ [SBREC_TABLE_CHASSIS_PRIVATE].row_ids[0]
|
|
|
9219d1 |
+ = {&sbrec_chassis_private_col_name, NULL, NULL},
|
|
|
9219d1 |
+
|
|
|
9219d1 |
[SBREC_TABLE_DATAPATH_BINDING].row_ids
|
|
|
9219d1 |
= {{&sbrec_datapath_binding_col_external_ids, "name", NULL},
|
|
|
9219d1 |
{&sbrec_datapath_binding_col_external_ids, "name2", NULL},
|
|
|
9219d1 |
--
|
|
|
9219d1 |
1.8.3.1
|
|
|
9219d1 |
|