From: RYAN D. MOATS <rmo...@us.ibm.com> Persist local_datapaths across runs so that a change can be used as a trigger to reset incremental flow processing.
Signed-off-by: RYAN D. MOATS <rmo...@us.ibm.com> --- ovn/controller/binding.c | 41 ++++++++++++++++++++++++++++++++++++-- ovn/controller/ovn-controller.c | 15 +++---------- ovn/controller/ovn-controller.h | 1 + ovn/controller/patch.c | 3 +- 4 files changed, 45 insertions(+), 15 deletions(-) diff --git a/ovn/controller/binding.c b/ovn/controller/binding.c index 9087052..585bdac 100644 --- a/ovn/controller/binding.c +++ b/ovn/controller/binding.c @@ -121,9 +121,31 @@ update_ct_zones(struct sset *lports, struct simap *ct_zones, } } +/* Contains "struct local_datpath" nodes whose hash values are the + * ins_seqno of datapaths with at least one local port binding. */ +struct hmap local_datapaths_by_seqno = + HMAP_INITIALIZER(&local_datapaths_by_seqno); + +static struct local_datapath * +local_datapath_lookup_by_seqno(unsigned int ins_seqno) +{ + return hmap_first_with_hash(&local_datapaths_by_seqno, ins_seqno); +} + +static void +remove_local_datapath(struct hmap *local_datapaths, unsigned int ins_seqno) +{ + struct local_datapath *ld = local_datapath_lookup_by_seqno(ins_seqno); + if (ld) { + hmap_remove(local_datapaths, &ld->hmap_node); + hmap_remove(&local_datapaths_by_seqno, &ld->seqno_hmap_node); + } +} + static void add_local_datapath(struct hmap *local_datapaths, - const struct sbrec_port_binding *binding_rec) + const struct sbrec_port_binding *binding_rec, + unsigned int ins_seqno) { if (hmap_first_with_hash(local_datapaths, binding_rec->datapath->tunnel_key)) { @@ -133,6 +155,7 @@ add_local_datapath(struct hmap *local_datapaths, struct local_datapath *ld = xzalloc(sizeof *ld); hmap_insert(local_datapaths, &ld->hmap_node, binding_rec->datapath->tunnel_key); + hmap_insert(&local_datapaths_by_seqno, &ld->seqno_hmap_node, ins_seqno); } static void @@ -184,7 +207,19 @@ binding_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int, /* Run through each binding record to see if it is resident on this * chassis and update the binding accordingly. This includes both * directly connected logical ports and children of those ports. */ - SBREC_PORT_BINDING_FOR_EACH(binding_rec, ctx->ovnsb_idl) { + SBREC_PORT_BINDING_FOR_EACH_TRACKED(binding_rec, ctx->ovnsb_idl) { + unsigned int del_seqno = sbrec_port_binding_row_get_seqno(binding_rec, + OVSDB_IDL_CHANGE_DELETE); + unsigned int ins_seqno = sbrec_port_binding_row_get_seqno(binding_rec, + OVSDB_IDL_CHANGE_INSERT); + + /* 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) */ + if (del_seqno > 0) { + remove_local_datapath(local_datapaths, ins_seqno); + continue; + } + const struct ovsrec_interface *iface_rec = shash_find_and_delete(&lports, binding_rec->logical_port); if (iface_rec @@ -194,7 +229,7 @@ binding_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int, /* Add child logical port to the set of all local ports. */ sset_add(&all_lports, binding_rec->logical_port); } - add_local_datapath(local_datapaths, binding_rec); + add_local_datapath(local_datapaths, binding_rec, ins_seqno); if (iface_rec && ctx->ovs_idl_txn) { update_qos(iface_rec, binding_rec); } diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index 8f3873d..cb8536b 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -198,6 +198,10 @@ get_ovnsb_remote(struct ovsdb_idl *ovs_idl) } } +/* Contains "struct local_datpath" nodes whose hash values are the + * tunnel_key of datapaths with at least one local port binding. */ +struct hmap local_datapaths = HMAP_INITIALIZER(&local_datapaths); + int main(int argc, char *argv[]) { @@ -282,10 +286,6 @@ main(int argc, char *argv[]) .ovnsb_idl_txn = ovsdb_idl_loop_run(&ovnsb_idl_loop), }; - /* Contains "struct local_datpath" nodes whose hash values are the - * tunnel_key of datapaths with at least one local port binding. */ - struct hmap local_datapaths = HMAP_INITIALIZER(&local_datapaths); - const struct ovsrec_bridge *br_int = get_br_int(&ctx); const char *chassis_id = get_chassis_id(ctx.ovs_idl); @@ -312,13 +312,6 @@ main(int argc, char *argv[]) ofctrl_put(); } - struct local_datapath *cur_node, *next_node; - HMAP_FOR_EACH_SAFE (cur_node, next_node, hmap_node, &local_datapaths) { - hmap_remove(&local_datapaths, &cur_node->hmap_node); - free(cur_node); - } - hmap_destroy(&local_datapaths); - unixctl_server_run(unixctl); unixctl_server_wait(unixctl); diff --git a/ovn/controller/ovn-controller.h b/ovn/controller/ovn-controller.h index a3465eb..04faf93 100644 --- a/ovn/controller/ovn-controller.h +++ b/ovn/controller/ovn-controller.h @@ -38,6 +38,7 @@ struct controller_ctx { * the localnet port */ struct local_datapath { struct hmap_node hmap_node; + struct hmap_node seqno_hmap_node; const struct sbrec_port_binding *localnet_port; }; diff --git a/ovn/controller/patch.c b/ovn/controller/patch.c index 753ce3e..9c519b0 100644 --- a/ovn/controller/patch.c +++ b/ovn/controller/patch.c @@ -190,7 +190,8 @@ add_bridge_mappings(struct controller_ctx *ctx, * to create patch ports for it. */ continue; } - if (ld->localnet_port) { + if (ld->localnet_port && strcmp(ld->localnet_port->logical_port, + binding->logical_port)) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); VLOG_WARN_RL(&rl, "localnet port '%s' already set for datapath " "'%"PRId64"', skipping the new port '%s'.", -- 1.7.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev