core: ensure 'activation' pending action encompasses full activation process

The NMActiveConnection class tracks the full activation request, and internal
activation requests go through the same process as external ones, including
some authentication.  Sometimes that means activation is scheduled, control
returns to the mainloop, and then the activation proceeds from an idle
handler.

Unfortunately, that means that adding a pending "activation" action from
nm-device.c doesn't always work, since there is a short window between when
the activation is started in nm-manager.c (in nm_manager_activate_connection())
and when the device actually changes state.  Inside that window, the pending
actions may drop to zero, and startup will be declared complete before the
device actually starts activating.

Instead, ensure that the pending action is added when the internal activation
is actually started (eg, when NMActiveConnection receives the NMDevice object).
This commit is contained in:
Dan Williams 2013-12-10 22:11:09 -06:00
parent 61463ed2ab
commit 2556aa32ed
2 changed files with 8 additions and 15 deletions

View file

@ -6135,13 +6135,6 @@ reason_to_string (NMDeviceStateReason reason)
return "unknown";
}
static inline gboolean
state_implies_pending_action (NMDeviceState state)
{
return ( state >= NM_DEVICE_STATE_PREPARE
&& state < NM_DEVICE_STATE_ACTIVATED);
}
static void
notify_ip_properties (NMDevice *device)
{
@ -6183,10 +6176,6 @@ nm_device_state_changed (NMDevice *device,
priv->state = state;
priv->state_reason = reason;
if ( state_implies_pending_action (state)
&& !state_implies_pending_action (old_state))
nm_device_add_pending_action (device, "activation");
nm_log_info (LOGD_DEVICE, "(%s): device state change: %s -> %s (reason '%s') [%d %d %d]",
nm_device_get_iface (device),
state_to_string (old_state),
@ -6352,10 +6341,6 @@ nm_device_state_changed (NMDevice *device,
if (req)
g_object_unref (req);
if ( state_implies_pending_action (old_state)
&& !state_implies_pending_action (state))
nm_device_remove_pending_action (device, "activation");
priv->in_state_changed = FALSE;
}

View file

@ -139,6 +139,12 @@ nm_active_connection_set_state (NMActiveConnection *self,
(guint64) time (NULL), TRUE);
}
if (priv->device) {
if ( old_state < NM_ACTIVE_CONNECTION_STATE_ACTIVATED
&& new_state >= NM_ACTIVE_CONNECTION_STATE_ACTIVATED)
nm_device_remove_pending_action (priv->device, "activation");
}
if (priv->state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) {
/* Device is no longer relevant when deactivated; emit property change
* notification so clients re-read the value, which will be NULL due to
@ -352,6 +358,8 @@ nm_active_connection_set_device (NMActiveConnection *self, NMDevice *device)
"state-changed",
G_CALLBACK (device_state_changed),
self);
nm_device_add_pending_action (device, "activation");
}
return TRUE;
}