device: fix bug when deactivating port connections asynchronously
Summary
When the attach_port()
/detach_port()
methods do not return immediately
(currently, only for OVS ports), the following situation can arise:
-
nm_device_controller_attach_port()
starts the attachment uby sending the command to ovsdb. Note that here we don't setPortInfo->port_is_attached
to TRUE yet; that happens only after the asynchronous command returns; -
the activation of the port gets interrupted because the connection is deleted;
-
the port device enters the deactivating state, triggering function
port_state_changed()
-
the function calls
nm_device_controller_release_port()
which checks whether the port is already attached; sincePortInfo->port_is_attached
is not set yet, it assumes the port doesn't need to be detached; -
in the meantime, the ovsdb operation succeeds. As a consequence, the kernel link is created even if the connection no longer exists.
Fix this by turning port_is_attached
into a tri-state variable that
also tracks when the port is attaching. When it is, we need to perform
an explicit detach during deactivation.
Fixes: 9fcbc6b3 ('device: make attach_port() asynchronous')