On Thu, Aug 11, 2016 at 05:20:33PM -0700, Jesse Gross wrote: > Originally, processing of encapsulations simply iterated over all tables on > every wakeup and would replace anything that changed. This is somewhat > inefficient but it captured all changes. > > Incremental processing avoided the need to do so much work but it could > miss several types of changes. In particular, it only monitored the chassis > table in the southbound database, so other changes (particularly in the > encap table) were not reflected. In addition, while it corrected some > changes to its data in OVS, others could go unnoticed. > > This attempts to fix those issues by reflecting the most recent updates > to the southbound database in OVS at all times. It also increases safety > by avoiding the possibility of dangling pointers to old database rows and > eliminates the need to traverse the OVS database at all during most wakeups. > > Fixes: 1d45d5a9 ("ovn-controller: Change encaps_run to work incrementally.") > Signed-off-by: Jesse Gross <je...@kernel.org>
Thanks for working on this. This could use a few more high-level code comments. It's a little hard to follow encaps_run(). I had to study it. I'm still not entirely sure I understand all of it. Usually, your code is super-robust, so some of this is on faith: Acked-by: Ben Pfaff <b...@ovn.org> I'm appending some suggestions. diff --git a/ovn/controller/encaps.c b/ovn/controller/encaps.c index 52348c3..94290a7 100644 --- a/ovn/controller/encaps.c +++ b/ovn/controller/encaps.c @@ -119,10 +119,9 @@ insert_encap_uuid(const struct uuid *uuid, { struct encap_hash_node *hash_node = xmalloc(sizeof *hash_node); - memcpy(&hash_node->encap_uuid, uuid, sizeof hash_node->encap_uuid); + hash_node->encap_uuid = *uuid; hash_node->chassis_id = xstrdup(chassis_rec->name); - memcpy(&hash_node->chassis_uuid, &chassis_rec->header_.uuid, - sizeof hash_node->chassis_uuid); + hash_node->chassis_uuid = chassis_rec->header_.uuid; hmap_insert(&tc.encap_chassis_hmap, &hash_node->node, uuid_hash(&hash_node->encap_uuid)); } @@ -165,12 +164,11 @@ insert_chassis_id(const char *chassis_id, const char *port_name, hash_node->chassis_id = xstrdup(chassis_id); hash_node->port_name = xstrdup(port_name); - memcpy(&hash_node->chassis_uuid, chassis_uuid, - sizeof hash_node->chassis_uuid); + hash_node->chassis_uuid = *chassis_uuid; /* We don't know the port's UUID until it has been inserted into the * database, store zeros for now. It will get updated the next time we * wake up. */ - memset(&hash_node->port_uuid, 0, sizeof hash_node->port_uuid); + uuid_zero(&hash_node->port_uuid); hmap_insert(&tc.chassis_hmap, &hash_node->node, hash_string(chassis_id, 0)); } @@ -350,6 +348,8 @@ encaps_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int, process_full_bridge = false; sset_clear(&tc.port_names); + /* Find all of the tunnel ports to remote chassis. + * Delete the tunnel ports fro unknown remote chassis. */ OVSREC_PORT_FOR_EACH (port_rec, ctx->ovs_idl) { sset_add(&tc.port_names, port_rec->name); for (int i = 0; i < port_rec->n_interfaces; i++) { @@ -362,9 +362,7 @@ encaps_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int, chassis_node = lookup_chassis_id(chassis_id); if (chassis_node) { if (uuid_is_zero(&chassis_node->port_uuid)) { - memcpy(&chassis_node->port_uuid, - &port_rec->header_.uuid, - sizeof chassis_node->port_uuid); + chassis_node->port_uuid = port_rec->header_.uuid; } } else { for (int i = 0; i < port_rec->n_interfaces; i++) { @@ -384,14 +382,17 @@ encaps_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int, &chassis_node->port_uuid); if (!chassis_rec) { + /* Delete tunnel port (if present) for missing chassis. */ bridge_delete_port(tc.br_int, port_rec, chassis_node); continue; } if (!port_rec) { + /* Delete our representation of the chassis, then add back. */ bridge_delete_port(tc.br_int, NULL, chassis_node); check_and_add_tunnel(chassis_rec, local_chassis_id); } else { + /* Update tunnel. */ check_and_update_tunnel(port_rec, chassis_rec); } } @@ -420,6 +421,7 @@ encaps_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int, } } + /* Update tunnels based on changes to the Encap table. */ SBREC_ENCAP_FOR_EACH_TRACKED (encap_rec, ctx->ovnsb_idl) { struct encap_hash_node *encap_hash_node; struct chassis_hash_node *chassis_hash_node; _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev