mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-03 10:30:22 +01:00
manager: allow delaying the device activation when the parent is not real
Don't try to realize our device when the parent device is not real. Instead, enqueue the activation and wait until it is active before realizing our device and progressing the device to DISCONNECTED so that it can get connected.
This commit is contained in:
parent
da226ae137
commit
b26159b149
1 changed files with 70 additions and 5 deletions
|
|
@ -226,6 +226,9 @@ static void active_connection_state_changed (NMActiveConnection *active,
|
|||
static void active_connection_default_changed (NMActiveConnection *active,
|
||||
GParamSpec *pspec,
|
||||
NMManager *self);
|
||||
static void active_connection_parent_active (NMActiveConnection *active,
|
||||
NMActiveConnection *parent_ac,
|
||||
NMManager *self);
|
||||
|
||||
/* Returns: whether to notify D-Bus of the removal or not */
|
||||
static gboolean
|
||||
|
|
@ -244,6 +247,7 @@ active_connection_remove (NMManager *self, NMActiveConnection *active)
|
|||
g_signal_emit (self, signals[ACTIVE_CONNECTION_REMOVED], 0, active);
|
||||
g_signal_handlers_disconnect_by_func (active, active_connection_state_changed, self);
|
||||
g_signal_handlers_disconnect_by_func (active, active_connection_default_changed, self);
|
||||
g_signal_handlers_disconnect_by_func (active, active_connection_parent_active, self);
|
||||
|
||||
if ( nm_active_connection_get_assumed (active)
|
||||
&& (connection = nm_active_connection_get_settings_connection (active))
|
||||
|
|
@ -2754,6 +2758,40 @@ unmanaged_to_disconnected (NMDevice *device)
|
|||
}
|
||||
}
|
||||
|
||||
/* The parent connection is ready; we can proceed realizing the device and
|
||||
* progressing the device to disconencted state.
|
||||
*/
|
||||
static void
|
||||
active_connection_parent_active (NMActiveConnection *active,
|
||||
NMActiveConnection *parent_ac,
|
||||
NMManager *self)
|
||||
{
|
||||
NMDevice *device = nm_active_connection_get_device (active);
|
||||
GError *error = NULL;
|
||||
|
||||
g_signal_handlers_disconnect_by_func (active,
|
||||
(GCallback) active_connection_parent_active,
|
||||
self);
|
||||
|
||||
if (parent_ac) {
|
||||
NMSettingsConnection *connection = nm_active_connection_get_settings_connection (active);
|
||||
NMDevice *parent = nm_active_connection_get_device (parent_ac);
|
||||
|
||||
if (nm_device_create_and_realize (device, (NMConnection *) connection, parent, &error)) {
|
||||
/* We can now proceed to disconnected state so that activation proceeds. */
|
||||
unmanaged_to_disconnected (device);
|
||||
} else {
|
||||
nm_log_warn (LOGD_CORE, "Could not realize device '%s': %s",
|
||||
nm_device_get_iface (device), error->message);
|
||||
nm_active_connection_set_state (active, NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);
|
||||
}
|
||||
} else {
|
||||
nm_log_warn (LOGD_CORE, "The parent connection device '%s' depended on disappeared.",
|
||||
nm_device_get_iface (device));
|
||||
nm_active_connection_set_state (active, NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_internal_activate_device (NMManager *self, NMActiveConnection *active, GError **error)
|
||||
{
|
||||
|
|
@ -2813,9 +2851,35 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError *
|
|||
NMDevice *parent;
|
||||
|
||||
parent = find_parent_device_for_connection (self, (NMConnection *) connection, NULL);
|
||||
if (!nm_device_create_and_realize (device, (NMConnection *) connection, parent, error)) {
|
||||
g_prefix_error (error, "%s failed to create resources: ", nm_device_get_iface (device));
|
||||
return FALSE;
|
||||
|
||||
if (parent && !nm_device_is_real (parent)) {
|
||||
NMSettingsConnection *parent_con;
|
||||
NMActiveConnection *parent_ac;
|
||||
|
||||
parent_con = nm_device_get_best_connection (parent, NULL, error);
|
||||
if (!parent_con) {
|
||||
g_prefix_error (error, "%s failed to create parent: ", nm_device_get_iface (device));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
parent_ac = nm_manager_activate_connection (self, parent_con, NULL, parent, subject, error);
|
||||
if (!parent_ac) {
|
||||
g_prefix_error (error, "%s failed to activate parent: ", nm_device_get_iface (device));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* We can't realize now; defer until the parent device is ready. */
|
||||
g_signal_connect (active,
|
||||
NM_ACTIVE_CONNECTION_PARENT_ACTIVE,
|
||||
(GCallback) active_connection_parent_active,
|
||||
self);
|
||||
nm_active_connection_set_parent (active, parent_ac);
|
||||
} else {
|
||||
/* We can realize now; no need to wait for a parent device. */
|
||||
if (!nm_device_create_and_realize (device, (NMConnection *) connection, parent, error)) {
|
||||
g_prefix_error (error, "%s failed to create resources: ", nm_device_get_iface (device));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2877,8 +2941,9 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError *
|
|||
if (existing)
|
||||
nm_device_steal_connection (existing, connection);
|
||||
|
||||
/* Make the device ready for activation. */
|
||||
unmanaged_to_disconnected (device);
|
||||
/* If the device is there, we can ready it for the activation. */
|
||||
if (nm_device_is_real (device))
|
||||
unmanaged_to_disconnected (device);
|
||||
|
||||
/* Export the new ActiveConnection to clients and start it on the device */
|
||||
nm_exported_object_export (NM_EXPORTED_OBJECT (active));
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue