From 04c4fb0a6ed719cfaa6b28c7daae51c0ccb549a2 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 6 Oct 2015 10:40:45 +0200 Subject: [PATCH 1/3] device: fix activating master/slave devices during stage2 During stage2, if the slave detected that it would need to wait for the master, it would return FALSE (which removes the g-idle-handler). However, it would not clear the activation-source, so later, when the master becomes ready, its attempt to schedule stage2 again would result in an error-log and the idle-handler would not be scheduled again. Fixes: 85ac903bb8010409c4010ba09c621780b385b9b5 https://bugzilla.redhat.com/show_bug.cgi?id=1268797 https://bugzilla.redhat.com/show_bug.cgi?id=1183444 (cherry picked from commit c5210b322dd3d5d26d3a3adb6d2ca67a3fc387e0) (cherry picked from commit 5c20dd9ea36a4bc84d1a32b0e30c8906570d5b02) --- src/devices/nm-device.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 148bef4..7aa9bb5 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -2792,6 +2792,9 @@ nm_device_activate_stage2_device_config (gpointer user_data) NMActiveConnection *active = NM_ACTIVE_CONNECTION (priv->act_request); GSList *iter; + /* Clear the activation source ID now that this stage has run */ + activation_source_clear (self, FALSE, 0); + if (!priv->master_ready_handled) { if (!nm_active_connection_get_master (active)) priv->master_ready_handled = TRUE; @@ -2814,9 +2817,6 @@ nm_device_activate_stage2_device_config (gpointer user_data) } } - /* Clear the activation source ID now that this stage has run */ - activation_source_clear (self, FALSE, 0); - _LOGD (LOGD_DEVICE, "Activation: Stage 2 of 5 (Device Configure) starting..."); nm_device_state_changed (self, NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_REASON_NONE); -- 2.4.3 From 3d8da19339a3fa5d5e7b66e821d0115ef18b7f17 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 6 Oct 2015 12:03:51 +0200 Subject: [PATCH 2/3] device: handle master-ready before scheduling stage2 Don't handle master-ready at the beginning of stage2, but instead while scheduling (and then possibly delaying the scheduling of stage2). This seems more idiomatic: When inside a stage and your part is done: call schedule-next-stage. That is, always schedule the next stage, not the current one. schedule-next-stage then might delay to really scheduling until the device is ready for the next state. Fixes: 85ac903bb8010409c4010ba09c621780b385b9b5 (cherry picked from commit 7bbc090387d6a1c519c92d957f5746faffb9325c) (cherry picked from commit 7828003bf8bd21dd821ce448ebd18b8c55cc931d) --- src/devices/nm-device.c | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 7aa9bb5..53a702d 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -2795,28 +2795,6 @@ nm_device_activate_stage2_device_config (gpointer user_data) /* Clear the activation source ID now that this stage has run */ activation_source_clear (self, FALSE, 0); - if (!priv->master_ready_handled) { - if (!nm_active_connection_get_master (active)) - priv->master_ready_handled = TRUE; - else { - /* If the master connection is ready for slaves, attach ourselves */ - if (nm_active_connection_get_master_ready (active)) - master_ready (self, active); - else { - _LOGD (LOGD_DEVICE, "waiting for master connection to become ready"); - - if (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); - } - /* Postpone */ - return FALSE; - } - } - } - _LOGD (LOGD_DEVICE, "Activation: Stage 2 of 5 (Device Configure) starting..."); nm_device_state_changed (self, NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_REASON_NONE); @@ -2878,6 +2856,30 @@ nm_device_activate_schedule_stage2_device_config (NMDevice *self) priv = NM_DEVICE_GET_PRIVATE (self); g_return_if_fail (priv->act_request); + if (!priv->master_ready_handled) { + NMActiveConnection *active = NM_ACTIVE_CONNECTION (priv->act_request); + + if (!nm_active_connection_get_master (active)) + priv->master_ready_handled = TRUE; + else { + /* If the master connection is ready for slaves, attach ourselves */ + if (nm_active_connection_get_master_ready (active)) + master_ready (self, active); + else { + _LOGD (LOGD_DEVICE, "waiting for master connection to become ready"); + + if (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); + } + /* Postpone */ + return; + } + } + } + activation_source_schedule (self, nm_device_activate_stage2_device_config, 0); _LOGD (LOGD_DEVICE, "Activation: Stage 2 of 5 (Device Configure) scheduled..."); -- 2.4.3 From bb73d0a828186ecd7af22fbb56a7faa88cbf71eb Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 6 Oct 2015 14:18:48 +0200 Subject: [PATCH 3/3] device: assert that master-ready handler is not scheduled in schedule_stage2_device_config() (cherry picked from commit c41be469ab107ea2b4813bf28a1618572b78aa6a) (cherry picked from commit 4e0882e9239bffd89fe84df74fb2f0663624fc17) --- src/devices/nm-device.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 53a702d..d566b24 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -2859,9 +2859,10 @@ nm_device_activate_schedule_stage2_device_config (NMDevice *self) if (!priv->master_ready_handled) { NMActiveConnection *active = NM_ACTIVE_CONNECTION (priv->act_request); - if (!nm_active_connection_get_master (active)) + if (!nm_active_connection_get_master (active)) { + g_warn_if_fail (!priv->master_ready_id); priv->master_ready_handled = TRUE; - else { + } else { /* If the master connection is ready for slaves, attach ourselves */ if (nm_active_connection_get_master_ready (active)) master_ready (self, active); -- 2.4.3