On Wed, Mar 27, 2019 at 11:24 PM Han Zhou <zhou...@gmail.com> wrote: > On Wed, Mar 27, 2019 at 3:00 AM Numan Siddique <nusid...@redhat.com> > wrote: > > > > > > > > On Wed, Mar 27, 2019 at 12:32 AM Han Zhou <zhou...@gmail.com> wrote: > >> > >> On Tue, Mar 26, 2019 at 11:08 AM Numan Siddique <nusid...@redhat.com> > wrote: > >> > > >> > > >> > > >> > On Tue, Mar 26, 2019 at 11:21 PM Han Zhou <zhou...@gmail.com> wrote: > >> >> > >> >> On Tue, Mar 26, 2019 at 9:59 AM Numan Siddique <nusid...@redhat.com> > wrote: > >> >> > > >> >> > > >> >> > Thanks Han for the review. I will address them > >> >> > Please see comments inline > >> >> > > >> >> > Thanks > >> >> > Numan > >> >> > > >> >> > > >> >> > On Tue, Mar 26, 2019 at 8:07 AM Han Zhou <zhou...@gmail.com> > wrote: > >> >> >> > >> >> >> Mostly looks good to me, just minor comments. > >> >> >> > >> >> >> On Thu, Mar 14, 2019 at 12:32 PM <nusid...@redhat.com> wrote: > >> >> >> > > >> >> >> > +static void > >> >> >> > +build_lrouter_groups__(struct hmap *ports, struct ovn_datapath > *od) > >> >> >> > +{ > >> >> >> > + ovs_assert((od && od->nbr && od->lr_group)); > >> >> >> > + > >> >> >> > + if (od->l3dgw_port && od->l3redirect_port) { > >> >> >> > + /* It's a logical router with gateway port. If it > >> >> >> > + * has HA_Chassis_Group associated to it in SB DB, > then store the > >> >> >> > + * ha chassis group name. */ > >> >> >> > + if (od->l3redirect_port->sb->ha_chassis_group) { > >> >> >> > + sset_add(&od->lr_group->ha_chassis_groups, > >> >> >> > + > od->l3redirect_port->sb->ha_chassis_group->name); > >> >> >> > + } > >> >> >> > + } > >> >> >> > + > >> >> >> > + for (size_t i = 0; i < od->nbr->n_ports; i++) { > >> >> >> > + struct ovn_port *router_port = > >> >> >> > + ovn_port_find(ports, od->nbr->ports[i]->name); > >> >> >> > + > >> >> >> > + if (!router_port || !router_port->peer) { > >> >> >> > + continue; > >> >> >> > + } > >> >> >> > + > >> >> >> > + /* Get the peer logical switch/logical router > datapath. */ > >> >> >> > + struct ovn_datapath *peer_dp = router_port->peer->od; > >> >> >> > + if (peer_dp->nbr) { > >> >> >> > + if (!peer_dp->lr_group) { > >> >> >> > + peer_dp->lr_group = od->lr_group; > >> >> >> > + > od->lr_group->router_dps[od->lr_group->n_router_dps++] > >> >> >> > + = peer_dp; > >> >> >> > + build_lrouter_groups__(ports, peer_dp); > >> >> >> > + } > >> >> >> > + } else { > >> >> >> > + for (size_t j = 0; j < peer_dp->n_router_ports; > j++) { > >> >> >> > + if (!peer_dp->router_ports[j]->peer) { > >> >> >> > + /* If there is no peer port connecting to > the > >> >> >> > + * router datapath, ignore it. */ > >> >> >> > >> >> >> s/router datapath/router port > >> >> >> > >> >> >> > + continue; > >> >> >> > + } > >> >> >> > + > >> >> >> > >> >> >> > +static void > >> >> >> > +build_lrouter_groups(struct hmap *ports, struct ovs_list > *lr_list) > >> >> >> > +{ > >> >> >> > + struct ovn_datapath *od; > >> >> >> > + size_t n_router_dps = ovs_list_size(lr_list); > >> >> >> > + > >> >> >> > + LIST_FOR_EACH (od, lr_list, lr_list) { > >> >> >> > + if (!od->lr_group) { > >> >> >> > + od->lr_group = xzalloc(sizeof *od->lr_group); > >> >> >> > + /* Each logical router group can have max > >> >> >> > + * 'n_router_dps'. So allocate enough memory. */ > >> >> >> > + od->lr_group->router_dps = xcalloc(sizeof *od, > n_router_dps); > >> >> >> > + > od->lr_group->router_dps[od->lr_group->n_router_dps] = od; > >> >> >> > >> >> >> Here it is more clear to be: od->lr_group->router_dps[0] = od; > >> >> >> > >> >> >> > + od->lr_group->n_router_dps = 1; > >> >> >> > + sset_init(&od->lr_group->ha_chassis_groups); > >> >> >> > + build_lrouter_groups__(ports, od); > >> >> >> > + } > >> >> >> > + } > >> >> >> > +} > >> >> >> > + > >> >> >> > >> >> >> > static void > >> >> >> > -destroy_datapaths_and_ports(struct hmap *datapaths, struct > hmap *ports) > >> >> >> > +destroy_datapaths_and_ports(struct hmap *datapaths, struct > hmap *ports, > >> >> >> > + struct ovs_list *lr_list) > >> >> >> > { > >> >> >> > + struct ovn_datapath *router_dp; > >> >> >> > + LIST_FOR_EACH_POP (router_dp, lr_list, lr_list) { > >> >> >> > + if (router_dp->lr_group) { > >> >> >> > + struct lrouter_group *lr_group = > router_dp->lr_group; > >> >> >> > + > >> >> >> > + for (size_t i = 0; i < > router_dp->lr_group->n_router_dps; i++) { > >> >> >> > + if (router_dp->lr_group->router_dps[i] != > router_dp) { > >> >> >> > >> >> >> This if-condition seems not needed. > > > > > > Actually it is needed. I first thought the same. But there were crashes > because of NULL pointer deference. > > If we don't have this check, then the check "i < > router_dp->lr_group->n_router_dps" in the for loop would > > result in the NULL pointer dereference.
> > > It seems there shouldn't be NULL pointer deference any more after > address the below comment, because you already have the local var > lr_group saved the pointer. > Thanks. I will try this out. I think it should work now. > > > > >> > >> >> >> > >> >> >> > + > router_dp->lr_group->router_dps[i]->lr_group = NULL; > >> >> >> > + } > >> >> >> > + } > >> >> >> > >> >> >> s/router_dp->lr_group/lr_group in above for-loop. > >> >> >> > >> >> >> > + > >> >> >> > + free(lr_group->router_dps); > >> >> >> > + sset_destroy(&lr_group->ha_chassis_groups); > >> >> >> > + free(lr_group); > >> >> >> > + router_dp->lr_group = NULL; > >> >> >> > + } > >> >> >> > + } > >> >> >> > + > > > > >> >> >> > diff --git a/ovn/ovn-nb.ovsschema b/ovn/ovn-nb.ovsschema > >> >> >> > index 10a59649a..48d27b960 100644 > >> >> >> > --- a/ovn/ovn-nb.ovsschema > >> >> >> > +++ b/ovn/ovn-nb.ovsschema > >> >> >> > @@ -1,7 +1,7 @@ > >> >> >> > { > >> >> >> > "name": "OVN_Northbound", > >> >> >> > - "version": "5.14.1", > >> >> >> > - "cksum": "3758097843 20509", > >> >> >> > + "version": "5.15.0", > >> >> >> > + "cksum": "1078795414 21917", > >> >> >> > "tables": { > >> >> >> > "NB_Global": { > >> >> >> > "columns": { > >> >> >> > @@ -271,6 +271,12 @@ > >> >> >> > "refType": "strong"}, > >> >> >> > "min": 0, > >> >> >> > "max": "unlimited"}}, > >> >> >> > + "ha_chassis_group": { > >> >> >> > + "type": {"key": {"type": "uuid", > >> >> >> > + "refTable": > "HA_Chassis_Group", > >> >> >> > + "refType": "weak"}, > >> >> >> > >> >> >> Shall this be strong ref instead? In normal case logical ports > hosted > >> >> >> by a HA-chassis-group should be deleted before the > HA-chassis-group is > >> >> >> removed. (same for SB schema) > >> >> > > >> >> > > >> >> > I would prefer weak ref because it would be easier for CMS to > manage the references. > >> >> > It doesn't need to keep track of the ref count before deleting the > HA_Chassis_Group row. > >> >> > > >> >> > >> >> Sorry that I don't understand why it requires ref count. With strong > >> >> reference, it just prevents operators to delete HA_Chassis_Group by > >> >> mistake (i.e. when they are still used by routers). CMS can just > >> >> simply return an error in this case, without any ref counter > >> >> maintenance. Otherwise, if it is weak reference, an operator can > >> >> delete HA_Chassis_Group even if it is still in use, which causes the > >> >> related logical router ports being converted from centralized to > >> >> distributed, implicitly, which I think is not good. > >> >> > >> > > >> > Agree that operator can delete HA_Chassis_Group by mistake even if > >> > logical ports/logical router ports are still referencing the > HA_Chassis_Group. > >> > > >> > What I mean is, CMS cannot delete the HA_Chassis_Group rows unless > >> > it clears all the references to HA_Chassis_Group. > >> > > >> > In a recent commit, we changed the logical switches and logical > routers > >> > referencing the Load_Balancer to weak mainly because of this. > >> > - > https://github.com/openvswitch/ovs/commit/612f80fa8ebf88dad2e204364c6c02b451dca36c > >> > > >> > That's why I thought to have a weak reference. > >> > You still think its good to change to strong ? > >> > > >> > >> Yes I am well aware of the LB change - in fact we are working on a > >> workaround in go-ovn project for older version of OVN that still has > >> strong reference for LB. > >> However, I think that is a different scenario. For a logical switch, a > >> LB is something additionally added, and from an operators point of > >> view it is pretty common to add/remove LB(s) to/from a logical switch. > >> However, for a logical router port, it is usually pre-defined that it > >> is a GW port or distributed port, when the deployment model is > >> decided. Although it is possible to convert a GW port to a distributed > >> port, it is uncommon. If it is really what the operator wants to do, > >> it should be handled explicitly by updating the logical router port, > >> rather than implicitly by removing the HA_Chassis_Group. Does this > >> make sense? > >> > > > > CMS could use an HA_Chassis_Group both for associating it with multiple > > logical router ports and also with multiple "external" ports. > > > > I am still little concerned from CMS point of view. > > > > Eg. > > ovn-nbctl ha-chassis-group-add-chassis hagrp1 ch1 30 > > ovn-nbctl ha-chassis-group-add-chassis hagrp1 ch2 20 > > ovn-nbctl ha-chassis-group-add-chassis hagrp1 ch3 10 > > > > ovn-nbctl set logical_router_port lr0-public > ha_chassis_group=<HAGRP1_UUID> > > ovn-nbctl set logical_router_port lr1-public > ha_chassis_group=<HAGRP1_UUID> > > ovn-nbctl set logical_router_port lr2-public > ha_chassis_group=<HAGRP1_UUID> > > > > ovn-nbctl set logical_switch_port ext-p1 ha_chasssi_group=<HAGRP1_UUID> > > ovn-nbctl set logical_switch_port ext-p2 ha_chasssi_group=<HAGRP1_UUID> > > ovn-nbctl set logical_switch_port ext-p3 ha_chasssi_group=<HAGRP1_UUID> > > .. > > ovn-nbctl set logical_switch_port ext-pn ha_chasssi_group=<HAGRP1_UUID> > > > > In the above case, CMS should know the list of logical router > ports/logical switch ports > > and can delete the "hagrp1" only when all the references are cleared. > > > > But I agree with your point that unlike load balancer which can be > independently created > > or deleted that's not the case with HA_Chassis_Group. > > > > I will go ahead and change it to "strong". We can probably revert it to > "false" later if > > it is hard for CMS to manage the references. > > > > Thanks Numan. I'd like to clarify more about it. For external ports, > missing HA_Chassis_Group is an error situation, because an external > port without HA_Chassis_Group cannot work. It is not something we > want. With weak reference, it can happen if HA_Chassis_Group is > deleted (by mistake) before deleting/updating the external ports. To > prevent this, CMS would have to do some validation, so that it can > warn the user and prevent this error situation to happen. To do such > validation, CMS would have to keep track of the references by itself. > However, with strong reference, the burden of the validation is moved > to OVSDB integrity check, which is free, and CMS simply return error, > without keeping tracking anything. I don't think there is a normal > scenario that *requires* deleting a HA_Chassis_Group before > deleting/updating the ports that references it. So I think strong > reference actually ensures correctness and it is also more convenient > from CMS point of view. > Thanks for the detailed explanation. The p5 of this series is setting "weak" reference. I will change it to strong and submit v6. Thanks Numan > > Thanks, > Han > _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev