Commit 10dc1aa8 authored by David Johnson's avatar David Johnson

Fix DHCP/OS metadata flow setup locking issues from issue #6.

The DHCP and OS meta flow setup functions were locking in the wrong
order.  They would try to grab the cn_node_t lock associated with the
dhcp server cn_node_t and the osmeta server cn_node_t first, then do
some flow setup work that would result in the csw lock associated with
both of those nodes being taken.  The order is always csw, cport,
cnode.  So now these functions follow that convention, and things are
happy.

This would typically manifest when a new node was entering from the
metadata server (always from the pending list, as I saw it), and
conflicting with a packet in msg (i.e., an ARP involving the DHCP server
or the OS metadata server).
parent a60345d8
Pipeline #1903 passed with stage
in 30 seconds
......@@ -1332,6 +1332,8 @@ static void __cnc_domain_setup_dhcp_flows(cn_switch_t *csw,cn_port_t *cport,
GHashTableIter iter;
gpointer gp;
cn_ownerdomain_t *odomain;
cn_port_t *dport = NULL;
cn_switch_t *dsw = NULL;
domain = __cnc_domain_lookup(cnode->domainid);
if (!domain) {
......@@ -1344,7 +1346,10 @@ static void __cnc_domain_setup_dhcp_flows(cn_switch_t *csw,cn_port_t *cport,
goto finish;
}
cn_obj_lock(dhcpnode);
if (cn_unordered_acquire_node_switch_lock(dhcpnode,&dport,&dsw) != 0) {
cncerr("could not lock dhcpnode!");
goto finish;
}
/*
* XXX: really need to hold a tmp ref to dhcpnode!
......@@ -1392,7 +1397,10 @@ static void __cnc_domain_setup_dhcp_flows(cn_switch_t *csw,cn_port_t *cport,
__cnc_domain_setup_node_dhcp_flows(dhcpnode,cnode);
}
cn_obj_unlock(dhcpnode);
cn_obj_unlock(dport);
cn_obj_unlock(dsw);
finish:
cn_obj_unlock(cnode);
cn_obj_unlock(cport);
......@@ -1415,6 +1423,8 @@ static void __cnc_domain_setup_osmeta_flows(cn_switch_t *csw,cn_port_t *cport,
GHashTableIter iter;
gpointer gp;
cn_ownerdomain_t *odomain;
cn_port_t *omport = NULL;
cn_switch_t *omsw = NULL;
domain = __cnc_domain_lookup(cnode->domainid);
if (!domain) {
......@@ -1425,7 +1435,11 @@ static void __cnc_domain_setup_osmeta_flows(cn_switch_t *csw,cn_port_t *cport,
osmetanode = domain->osmeta_server;
if (!osmetanode)
goto finish;
cn_obj_lock(osmetanode);
if (cn_unordered_acquire_node_switch_lock(osmetanode,&omport,&omsw) != 0) {
cncerr("could not lock osmetanode!");
goto finish;
}
if (osmetanode && osmetanode == cnode) {
g_hash_table_iter_init(&iter,domain->ownerdomains);
......@@ -1441,6 +1455,8 @@ static void __cnc_domain_setup_osmeta_flows(cn_switch_t *csw,cn_port_t *cport,
}
cn_obj_unlock(osmetanode);
cn_obj_unlock(omport);
cn_obj_unlock(omsw);
finish:
cn_obj_unlock(cnode);
cn_obj_unlock(cport);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment