mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-27 17:30:42 +01:00
ovs: wait that link disappears before continuing with deactivation
When we deactivate a virtual device, we usually schedule the deletion of the link in an idle handler. That action will be executed at a later time when the device is already in the disconnected state. Similarly, for ovs interfaces we send the deletion command to the ovsdb and then proceed to the disconnected state. However, in the first case there is the guarantee that the link will be deleted at some point, while for ovs interfaces it may happen that ovs decides to reuse the same link if there is an addition queued. Since reusing the same link confuses NM, let's implement deactivate_async() for ovs-interfaces and wait that the link actually goes away before proceeding. https://bugzilla.redhat.com/show_bug.cgi?id=1782701 https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/402 (cherry picked from commit623a1e1f99) (cherry picked from commita1b0edd24b) (cherry picked from commitcb7c7c29bd)
This commit is contained in:
parent
c68d401df4
commit
b0aad945b4
1 changed files with 115 additions and 0 deletions
|
|
@ -35,6 +35,7 @@ _LOG_DECLARE_SELF(NMDeviceOvsInterface);
|
|||
|
||||
typedef struct {
|
||||
bool waiting_for_interface:1;
|
||||
int link_ifindex;
|
||||
} NMDeviceOvsInterfacePrivate;
|
||||
|
||||
struct _NMDeviceOvsInterface {
|
||||
|
|
@ -111,6 +112,9 @@ link_changed (NMDevice *device,
|
|||
{
|
||||
NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE (device);
|
||||
|
||||
if (pllink)
|
||||
priv->link_ifindex = pllink->ifindex;
|
||||
|
||||
if ( pllink
|
||||
&& priv->waiting_for_interface
|
||||
&& nm_device_get_state (device) == NM_DEVICE_STATE_IP_CONFIG) {
|
||||
|
|
@ -166,6 +170,116 @@ deactivate (NMDevice *device)
|
|||
priv->waiting_for_interface = FALSE;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
NMDeviceOvsInterface *self;
|
||||
GCancellable *cancellable;
|
||||
NMDeviceDeactivateCallback callback;
|
||||
gpointer callback_user_data;
|
||||
gulong link_changed_id;
|
||||
gulong cancelled_id;
|
||||
} DeactivateData;
|
||||
|
||||
static void
|
||||
deactivate_invoke_cb (DeactivateData *data, GError *error)
|
||||
{
|
||||
data->callback (NM_DEVICE (data->self),
|
||||
error,
|
||||
data->callback_user_data);
|
||||
|
||||
nm_clear_g_signal_handler (nm_device_get_platform (NM_DEVICE (data->self)),
|
||||
&data->link_changed_id);
|
||||
nm_clear_g_signal_handler (data->cancellable,
|
||||
&data->cancelled_id);
|
||||
g_object_unref (data->self);
|
||||
g_object_unref (data->cancellable);
|
||||
nm_g_slice_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
link_changed_cb (NMPlatform *platform,
|
||||
int obj_type_i,
|
||||
int ifindex,
|
||||
NMPlatformLink *info,
|
||||
int change_type_i,
|
||||
DeactivateData *data)
|
||||
{
|
||||
NMDeviceOvsInterface *self = data->self;
|
||||
NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE (self);
|
||||
const NMPlatformSignalChangeType change_type = change_type_i;
|
||||
|
||||
if ( change_type == NM_PLATFORM_SIGNAL_REMOVED
|
||||
&& ifindex == priv->link_ifindex) {
|
||||
_LOGT (LOGD_DEVICE,
|
||||
"link %d gone, proceeding with deactivation",
|
||||
priv->link_ifindex);
|
||||
priv->link_ifindex = 0;
|
||||
deactivate_invoke_cb (data, NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
deactivate_cancelled_cb (GCancellable *cancellable,
|
||||
gpointer user_data)
|
||||
{
|
||||
gs_free_error GError *error = NULL;
|
||||
|
||||
nm_utils_error_set_cancelled (&error, FALSE, NULL);
|
||||
deactivate_invoke_cb ((DeactivateData *) user_data, error);
|
||||
}
|
||||
|
||||
static void
|
||||
deactivate_cb_on_idle (gpointer user_data,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
DeactivateData *data = user_data;
|
||||
gs_free_error GError *cancelled_error = NULL;
|
||||
|
||||
g_cancellable_set_error_if_cancelled (data->cancellable, &cancelled_error);
|
||||
deactivate_invoke_cb (data, cancelled_error);
|
||||
}
|
||||
|
||||
static void
|
||||
deactivate_async (NMDevice *device,
|
||||
GCancellable *cancellable,
|
||||
NMDeviceDeactivateCallback callback,
|
||||
gpointer callback_user_data) {
|
||||
|
||||
NMDeviceOvsInterface *self = NM_DEVICE_OVS_INTERFACE (device);
|
||||
NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE (self);
|
||||
DeactivateData *data;
|
||||
|
||||
priv->waiting_for_interface = FALSE;
|
||||
|
||||
data = g_slice_new (DeactivateData);
|
||||
*data = (DeactivateData) {
|
||||
.self = g_object_ref (self),
|
||||
.cancellable = g_object_ref (cancellable),
|
||||
.callback = callback,
|
||||
.callback_user_data = callback_user_data,
|
||||
};
|
||||
|
||||
if ( !priv->link_ifindex
|
||||
|| !nm_platform_link_get (nm_device_get_platform (device), priv->link_ifindex)) {
|
||||
priv->link_ifindex = 0;
|
||||
nm_utils_invoke_on_idle (deactivate_cb_on_idle, data, cancellable);
|
||||
return;
|
||||
}
|
||||
|
||||
_LOGT (LOGD_DEVICE,
|
||||
"async deactivation: waiting for link %d to disappear",
|
||||
priv->link_ifindex);
|
||||
|
||||
data->cancelled_id = g_cancellable_connect (cancellable,
|
||||
G_CALLBACK (deactivate_cancelled_cb),
|
||||
data,
|
||||
NULL);
|
||||
data->link_changed_id = g_signal_connect (nm_device_get_platform (device),
|
||||
NM_PLATFORM_SIGNAL_LINK_CHANGED,
|
||||
G_CALLBACK (link_changed_cb),
|
||||
data);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
|
|
@ -196,6 +310,7 @@ nm_device_ovs_interface_class_init (NMDeviceOvsInterfaceClass *klass)
|
|||
device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_OPENVSWITCH);
|
||||
|
||||
device_class->deactivate = deactivate;
|
||||
device_class->deactivate_async = deactivate_async;
|
||||
device_class->get_type_description = get_type_description;
|
||||
device_class->create_and_realize = create_and_realize;
|
||||
device_class->get_generic_capabilities = get_generic_capabilities;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue