Commit dfa9147b authored by David Johnson's avatar David Johnson

Handle race: server may send port bind msg before wfagent/port is bound.

This is caused by a multithreaded separation of concerns.  The generic
agent main thread notices when ports are plugged on OVS switches, and
notifies the neutron server of the dpid/ofport for the newly-plugged
port_id.

But, when the agent creates and plugs a port for a new wfagent, it
wasn't sending its wfagent/port binding msg (which tells neutron that a
given wfagent has been bound to a port on some client node) until after
the wfapp was running.  The main thread saw the new port plug and sent
and received generic port binding info that did not have the wfagent
part of the binding because it hadn't been made yet.

So now we just send a wfagent bind notification prior to plugging the
device for the new port; and then later on send another wfagent bind
notification to update status once the wfapp is running.
parent 49143728
Pipeline #1168 skipped
......@@ -1021,6 +1021,33 @@ class CapnetWorkflowAgentManager(object):
namespace=wfagent.namespace):
LOG.debug('Reusing existing device: %s.',interface_name)
else:
#
# NB: this little bit of code ensures that the wfagent/port
# binding is sent to the server *BEFORE* the port is
# plugged. This is important, because when the agent main
# thread sees a new port plugged into the switch, it will
# send a binding_update to the server, and server will send
# back a binding notification that the metadata service
# handles. If the binding update hits the server before the
# wfagent update hits it, the biding notification will hit
# the agent *without* the important little bit of 'wfagent'
# field in it -- and the metadata manager will write the
# role of the node as simply 'node', when perhaps it should
# have been 'master'!
#
# This solution costs an extra RPC, but it's all right. The
# alternative is for the metadata manager and workflow agent
# manager to collaborate (i.e. metadata manager would see
# device owner neutron:capnet-wfagent, but no wfagent in the
# notification, and then call over here to the wfagent
# manager who would know the binding).
#
wfagent.port_id = port['id']
wfagent.status = 'plugging'
LOG.debug("calling wfagent_update (plugging): %s" % (str(wfagent),))
self.agent.capnet_ext_plugin_rpc.wfagent_update(wfagent)
self.ifdriver.plug(network.id,port.id,interface_name,
port.mac_address,namespace=wfagent.namespace)
pass
......
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