mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-26 06:30:08 +01:00
core: add slave to master in stage1_prepare, not nm_device_activate()
When ActiveConnections take over authentication, it may mean that the master active connection is still handling authentication when the slave starts to activate. Thus the master device may still be in DISCONNECTED state and not ready to enslave the slave.
This commit is contained in:
parent
f95bca2dcf
commit
1768b3abd5
1 changed files with 59 additions and 18 deletions
|
|
@ -288,6 +288,7 @@ typedef struct {
|
|||
/* master interface for bridge/bond/team slave */
|
||||
NMDevice * master;
|
||||
gboolean enslaved;
|
||||
guint master_ready_id;
|
||||
|
||||
/* slave management */
|
||||
gboolean is_master;
|
||||
|
|
@ -1935,10 +1936,61 @@ nm_device_ip_config_should_fail (NMDevice *self, gboolean ip6)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
master_ready_cb (NMActiveConnection *active,
|
||||
GParamSpec *pspec,
|
||||
NMDevice *self)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
NMActiveConnection *master;
|
||||
|
||||
g_assert (priv->state == NM_DEVICE_STATE_PREPARE);
|
||||
|
||||
/* Notify a master device that it has a new slave */
|
||||
g_assert (nm_active_connection_get_master_ready (active));
|
||||
master = nm_active_connection_get_master (active);
|
||||
|
||||
priv->master = g_object_ref (nm_active_connection_get_device (master));
|
||||
nm_device_master_add_slave (priv->master, self);
|
||||
|
||||
nm_log_dbg (LOGD_DEVICE, "(%s): master connection ready; master device %s",
|
||||
nm_device_get_iface (self),
|
||||
nm_device_get_iface (priv->master));
|
||||
|
||||
if (priv->master_ready_id) {
|
||||
g_signal_handler_disconnect (active, priv->master_ready_id);
|
||||
priv->master_ready_id = 0;
|
||||
}
|
||||
|
||||
nm_device_activate_schedule_stage2_device_config (self);
|
||||
}
|
||||
|
||||
static NMActStageReturn
|
||||
act_stage1_prepare (NMDevice *self, NMDeviceStateReason *reason)
|
||||
{
|
||||
return NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
NMActiveConnection *active = NM_ACTIVE_CONNECTION (priv->act_request);
|
||||
|
||||
if (nm_active_connection_get_master (active)) {
|
||||
/* If the master connection is ready for slaves, attach ourselves */
|
||||
if (nm_active_connection_get_master_ready (active))
|
||||
master_ready_cb (active, NULL, self);
|
||||
else {
|
||||
nm_log_dbg (LOGD_DEVICE, "(%s): waiting for master connection to become ready",
|
||||
nm_device_get_iface (self));
|
||||
|
||||
/* Attach a signal handler and wait for the master connection to begin activating */
|
||||
g_assert (priv->master_ready_id == 0);
|
||||
priv->master_ready_id = g_signal_connect (active,
|
||||
"notify::" NM_ACTIVE_CONNECTION_INT_MASTER_READY,
|
||||
(GCallback) master_ready_cb,
|
||||
self);
|
||||
ret = NM_ACT_STAGE_RETURN_POSTPONE;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -4024,6 +4076,11 @@ clear_act_request (NMDevice *self)
|
|||
|
||||
nm_active_connection_set_default (NM_ACTIVE_CONNECTION (priv->act_request), FALSE);
|
||||
|
||||
if (priv->master_ready_id) {
|
||||
g_signal_handler_disconnect (priv->act_request, priv->master_ready_id);
|
||||
priv->master_ready_id = 0;
|
||||
}
|
||||
|
||||
g_object_unref (priv->act_request);
|
||||
priv->act_request = NULL;
|
||||
}
|
||||
|
|
@ -4427,9 +4484,6 @@ nm_device_activate (NMDevice *self, NMActRequest *req)
|
|||
nm_device_state_changed (self, NM_DEVICE_STATE_IP_CONFIG, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
|
||||
nm_device_activate_schedule_stage3_ip_config_start (self);
|
||||
} else {
|
||||
NMActiveConnection *master;
|
||||
NMDevice *master_device;
|
||||
|
||||
/* HACK: update the state a bit early to avoid a race between the
|
||||
* scheduled stage1 handler and nm_policy_device_change_check() thinking
|
||||
* that the activation request isn't deferred because the deferred bit
|
||||
|
|
@ -4437,20 +4491,6 @@ nm_device_activate (NMDevice *self, NMActRequest *req)
|
|||
*/
|
||||
nm_device_state_changed (self, NM_DEVICE_STATE_PREPARE, NM_DEVICE_STATE_REASON_NONE);
|
||||
|
||||
/* Handle any dependencies this connection might have */
|
||||
master = nm_active_connection_get_master (NM_ACTIVE_CONNECTION (req));
|
||||
if (master) {
|
||||
master_device = nm_active_connection_get_device (master);
|
||||
if (master_device) {
|
||||
/* Master should at least already be activating */
|
||||
g_assert (nm_device_get_state (master_device) > NM_DEVICE_STATE_DISCONNECTED);
|
||||
|
||||
g_assert (priv->master == NULL);
|
||||
priv->master = g_object_ref (master_device);
|
||||
nm_device_master_add_slave (master_device, self);
|
||||
}
|
||||
}
|
||||
|
||||
nm_device_activate_schedule_stage1_device_prepare (self);
|
||||
}
|
||||
}
|
||||
|
|
@ -5033,6 +5073,7 @@ dispose (GObject *object)
|
|||
dnsmasq_cleanup (self);
|
||||
|
||||
g_warn_if_fail (priv->slaves == NULL);
|
||||
g_assert (priv->master_ready_id == 0);
|
||||
|
||||
/* Take the device itself down and clear its IPv4 configuration */
|
||||
if (nm_device_get_managed (self) && deconfigure) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue