[ovs-dev] [PATCH v12 3/9] Persist lport and mcgroup indexes
Ryan Moats
rmoats at us.ibm.com
Wed Mar 30 21:36:00 UTC 2016
From: RYAN D. MOATS <rmoats at us.ibm.com>
Persisting these entries is a pre-requisite for incremental
processing.
Signed-off-by: RYAN D. MOATS <rmoats at us.ibm.com>
---
ovn/controller/lport.c | 139 ++++++++++++++++++++++++++++++++++----
ovn/controller/lport.h | 20 +++++-
ovn/controller/ovn-controller.c | 14 ++--
3 files changed, 150 insertions(+), 23 deletions(-)
diff --git a/ovn/controller/lport.c b/ovn/controller/lport.c
index e09930a..5bcc05a 100644
--- a/ovn/controller/lport.c
+++ b/ovn/controller/lport.c
@@ -25,23 +25,52 @@ VLOG_DEFINE_THIS_MODULE(lport);
/* A logical port. */
struct lport {
- struct hmap_node name_node; /* Index by name. */
- struct hmap_node key_node; /* Index by (dp_key, port_key). */
+ struct hmap_node name_node; /* Index by name. */
+ struct hmap_node key_node; /* Index by (dp_key, port_key). */
+ struct hmap_node uuid_node; /* Index by row uuid. */
+ const struct uuid *uuid;
const struct sbrec_port_binding *pb;
};
void
-lport_index_init(struct lport_index *lports, struct ovsdb_idl *ovnsb_idl)
+lport_index_init(struct lport_index *lports)
{
hmap_init(&lports->by_name);
hmap_init(&lports->by_key);
+ hmap_init(&lports->by_uuid);
+}
+
+void
+lport_index_remove(struct lport_index *lports, const struct uuid *uuid)
+{
+ const struct lport *port = lport_lookup_by_uuid(lports, uuid);
+ if (port) {
+ hmap_remove(&lports->by_name, &port->name_node);
+ hmap_remove(&lports->by_key, &port->key_node);
+ hmap_remove(&lports->by_uuid, &port->uuid_node);
+ free(port);
+ }
+}
+void
+lport_index_fill(struct lport_index *lports, struct ovsdb_idl *ovnsb_idl)
+{
const struct sbrec_port_binding *pb;
- SBREC_PORT_BINDING_FOR_EACH (pb, ovnsb_idl) {
+ SBREC_PORT_BINDING_FOR_EACH_TRACKED (pb, ovnsb_idl) {
+ unsigned int del_seqno = sbrec_port_binding_row_get_seqno(pb,
+ OVSDB_IDL_CHANGE_DELETE);
+
+ /* if the row has a del_seqno > 0, then trying to process the
+ * row isn't going to work (as it has already been freed).
+ * What we can do is pass the row uuid to lport_index_remove()
+ * to remove the port. */
+ if (del_seqno > 0) {
+ lport_index_remove(lports, &pb->header_.uuid);
+ reset_flow_processing();
+ continue;
+ }
+
if (lport_lookup_by_name(lports, pb->logical_port)) {
- static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
- VLOG_WARN_RL(&rl, "duplicate logical port name '%s'",
- pb->logical_port);
continue;
}
@@ -50,25 +79,38 @@ lport_index_init(struct lport_index *lports, struct ovsdb_idl *ovnsb_idl)
hash_string(pb->logical_port, 0));
hmap_insert(&lports->by_key, &p->key_node,
hash_int(pb->tunnel_key, pb->datapath->tunnel_key));
+ hmap_insert(&lports->by_uuid, &p->uuid_node,
+ uuid_hash(&pb->header_.uuid));
+ p->uuid = &pb->header_.uuid;
p->pb = pb;
reset_flow_processing();
}
}
void
-lport_index_destroy(struct lport_index *lports)
+lport_index_clear(struct lport_index *lports)
{
/* Destroy all of the "struct lport"s.
*
- * We don't have to remove the node from both indexes. */
+ * We have to remove the node from all indexes. */
struct lport *port, *next;
HMAP_FOR_EACH_SAFE (port, next, name_node, &lports->by_name) {
hmap_remove(&lports->by_name, &port->name_node);
+ hmap_remove(&lports->by_key, &port->key_node);
+ hmap_remove(&lports->by_uuid, &port->uuid_node);
free(port);
}
+ reset_flow_processing();
+}
+
+void
+lport_index_destroy(struct lport_index *lports)
+{
+ lport_index_clear(lports);
hmap_destroy(&lports->by_name);
hmap_destroy(&lports->by_key);
+ hmap_destroy(&lports->by_uuid);
}
/* Finds and returns the lport with the given 'name', or NULL if no such lport
@@ -86,6 +128,20 @@ lport_lookup_by_name(const struct lport_index *lports, const char *name)
return NULL;
}
+const struct lport *
+lport_lookup_by_uuid(const struct lport_index *lports,
+ const struct uuid *uuid)
+{
+ const struct lport *lport;
+ HMAP_FOR_EACH_WITH_HASH (lport, uuid_node, uuid_hash(uuid),
+ &lports->by_uuid) {
+ if (uuid_equals(uuid, lport->uuid)) {
+ return lport;
+ }
+ }
+ return NULL;
+}
+
const struct sbrec_port_binding *
lport_lookup_by_key(const struct lport_index *lports,
uint32_t dp_key, uint16_t port_key)
@@ -103,44 +159,97 @@ lport_lookup_by_key(const struct lport_index *lports,
struct mcgroup {
struct hmap_node dp_name_node; /* Index by (logical datapath, name). */
+ struct hmap_node uuid_node; /* Index by insert uuid. */
+ const struct uuid *uuid;
const struct sbrec_multicast_group *mg;
};
void
-mcgroup_index_init(struct mcgroup_index *mcgroups, struct ovsdb_idl *ovnsb_idl)
+mcgroup_index_init(struct mcgroup_index *mcgroups)
{
hmap_init(&mcgroups->by_dp_name);
+ hmap_init(&mcgroups->by_uuid);
+}
+
+void
+mcgroup_index_remove(struct mcgroup_index *mcgroups, const struct uuid *uuid)
+{
+ const struct mcgroup *mcgroup = mcgroup_lookup_by_uuid(mcgroups, uuid);
+ if (mcgroup) {
+ hmap_remove(&mcgroups->by_dp_name, &mcgroup->dp_name_node);
+ hmap_remove(&mcgroups->by_uuid, &mcgroup->uuid_node);
+ free(mcgroup);
+ }
+}
+void
+mcgroup_index_fill(struct mcgroup_index *mcgroups, struct ovsdb_idl *ovnsb_idl)
+{
const struct sbrec_multicast_group *mg;
- SBREC_MULTICAST_GROUP_FOR_EACH (mg, ovnsb_idl) {
+ SBREC_MULTICAST_GROUP_FOR_EACH_TRACKED (mg, ovnsb_idl) {
+ unsigned int del_seqno = sbrec_multicast_group_row_get_seqno(mg,
+ OVSDB_IDL_CHANGE_DELETE);
+
+ /* if the row has a del_seqno > 0, then trying to process the
+ * row isn't going to work (as it has already been freed).
+ * What we can do is pass the row uuid to mcgroup_index_remove()
+ * to remove the port. */
+ if (del_seqno > 0) {
+ mcgroup_index_remove(mcgroups, &mg->header_.uuid);
+ reset_flow_processing();
+ continue;
+ }
+
const struct uuid *dp_uuid = &mg->datapath->header_.uuid;
if (mcgroup_lookup_by_dp_name(mcgroups, mg->datapath, mg->name)) {
- static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
- VLOG_WARN_RL(&rl, "datapath "UUID_FMT" contains duplicate "
- "multicast group '%s'", UUID_ARGS(dp_uuid), mg->name);
continue;
}
struct mcgroup *m = xmalloc(sizeof *m);
hmap_insert(&mcgroups->by_dp_name, &m->dp_name_node,
hash_string(mg->name, uuid_hash(dp_uuid)));
+ hmap_insert(&mcgroups->by_uuid, &m->uuid_node,
+ uuid_hash(&mg->header_.uuid));
+ m->uuid = &mg->header_.uuid;
m->mg = mg;
reset_flow_processing();
}
}
void
-mcgroup_index_destroy(struct mcgroup_index *mcgroups)
+mcgroup_index_clear(struct mcgroup_index *mcgroups)
{
struct mcgroup *mcgroup, *next;
HMAP_FOR_EACH_SAFE (mcgroup, next, dp_name_node, &mcgroups->by_dp_name) {
hmap_remove(&mcgroups->by_dp_name, &mcgroup->dp_name_node);
+ hmap_remove(&mcgroups->by_uuid, &mcgroup->uuid_node);
free(mcgroup);
}
+ reset_flow_processing();
+}
+
+void
+mcgroup_index_destroy(struct mcgroup_index *mcgroups)
+{
+ mcgroup_index_clear(mcgroups);
hmap_destroy(&mcgroups->by_dp_name);
}
+const struct mcgroup *
+mcgroup_lookup_by_uuid(const struct mcgroup_index *mcgroups,
+ const struct uuid *uuid)
+{
+ const struct mcgroup *mcgroup;
+ HMAP_FOR_EACH_WITH_HASH (mcgroup, uuid_node, uuid_hash(uuid),
+ &mcgroups->by_uuid) {
+ if (uuid_equals(mcgroup->uuid, uuid)) {
+ return mcgroup;
+ }
+ }
+ return NULL;
+}
+
const struct sbrec_multicast_group *
mcgroup_lookup_by_dp_name(const struct mcgroup_index *mcgroups,
const struct sbrec_datapath_binding *dp,
diff --git a/ovn/controller/lport.h b/ovn/controller/lport.h
index f09e2eb..350325a 100644
--- a/ovn/controller/lport.h
+++ b/ovn/controller/lport.h
@@ -18,6 +18,7 @@
#include <stdint.h>
#include "hmap.h"
+#include "uuid.h"
struct ovsdb_idl;
struct sbrec_datapath_binding;
@@ -32,15 +33,23 @@ struct sbrec_datapath_binding;
struct lport_index {
struct hmap by_name;
struct hmap by_key;
+ struct hmap by_uuid;
};
-void lport_index_init(struct lport_index *, struct ovsdb_idl *);
+void lport_index_init(struct lport_index *);
+void lport_index_fill(struct lport_index *, struct ovsdb_idl *);
+void lport_index_remove(struct lport_index *, const struct uuid *);
+void lport_index_clear(struct lport_index *);
void lport_index_destroy(struct lport_index *);
const struct sbrec_port_binding *lport_lookup_by_name(
const struct lport_index *, const char *name);
const struct sbrec_port_binding *lport_lookup_by_key(
const struct lport_index *, uint32_t dp_key, uint16_t port_key);
+
+const struct lport *lport_lookup_by_uuid(
+ const struct lport_index *, const struct uuid *uuid);
+
/* Multicast group index
* =====================
@@ -54,9 +63,13 @@ const struct sbrec_port_binding *lport_lookup_by_key(
struct mcgroup_index {
struct hmap by_dp_name;
+ struct hmap by_uuid;
};
-void mcgroup_index_init(struct mcgroup_index *, struct ovsdb_idl *);
+void mcgroup_index_init(struct mcgroup_index *);
+void mcgroup_index_fill(struct mcgroup_index *, struct ovsdb_idl *);
+void mcgroup_index_remove(struct mcgroup_index *, const struct uuid *);
+void mcgroup_index_clear(struct mcgroup_index *);
void mcgroup_index_destroy(struct mcgroup_index *);
const struct sbrec_multicast_group *mcgroup_lookup_by_dp_name(
@@ -64,4 +77,7 @@ const struct sbrec_multicast_group *mcgroup_lookup_by_dp_name(
const struct sbrec_datapath_binding *,
const char *name);
+const struct mcgroup *mcgroup_lookup_by_uuid(
+ const struct mcgroup_index *, const struct uuid *uuid);
+
#endif /* ovn/lport.h */
diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c
index c7cbd50..6edc04c 100644
--- a/ovn/controller/ovn-controller.c
+++ b/ovn/controller/ovn-controller.c
@@ -198,6 +198,9 @@ get_ovnsb_remote(struct ovsdb_idl *ovs_idl)
}
}
+struct lport_index lports;
+struct mcgroup_index mcgroups;
+
int
main(int argc, char *argv[])
{
@@ -228,6 +231,9 @@ main(int argc, char *argv[])
pinctrl_init();
lflow_init();
+ lport_index_init(&lports);
+ mcgroup_index_init(&mcgroups);
+
/* Connect to OVS OVSDB instance. We do not monitor all tables by
* default, so modules must register their interest explicitly. */
struct ovsdb_idl_loop ovs_idl_loop = OVSDB_IDL_LOOP_INITIALIZER(
@@ -299,10 +305,8 @@ main(int argc, char *argv[])
if (br_int) {
patch_run(&ctx, br_int, &local_datapaths);
- struct lport_index lports;
- struct mcgroup_index mcgroups;
- lport_index_init(&lports, ctx.ovnsb_idl);
- mcgroup_index_init(&mcgroups, ctx.ovnsb_idl);
+ lport_index_fill(&lports, ctx.ovnsb_idl);
+ mcgroup_index_fill(&mcgroups, ctx.ovnsb_idl);
enum mf_field_id mff_ovn_geneve = ofctrl_run(br_int);
@@ -316,8 +320,6 @@ main(int argc, char *argv[])
&local_datapaths);
}
ofctrl_put();
- mcgroup_index_destroy(&mcgroups);
- lport_index_destroy(&lports);
}
struct local_datapath *cur_node, *next_node;
--
1.7.1
More information about the dev
mailing list