summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2015-10-02 18:48:29 +0200
committerThomas Haller <thaller@redhat.com>2015-10-02 18:48:29 +0200
commit18b20c4f6f9f2961ea79c96b9a56116d556103c9 (patch)
treeaa9accd342e8360f3849a39477780940d4ad0e2e
parent6f9a7a8daa4a945410636c1bc90bf3b6ad14d738 (diff)
parent85ac903bb8010409c4010ba09c621780b385b9b5 (diff)
code: merge branch 'th/enslave-team-rh1183444'
https://bugzilla.redhat.com/show_bug.cgi?id=1183444
-rw-r--r--include/nm-macros-internal.h13
-rw-r--r--src/devices/nm-device.c71
2 files changed, 54 insertions, 30 deletions
diff --git a/include/nm-macros-internal.h b/include/nm-macros-internal.h
index 7ae08bf727..4ee5499f22 100644
--- a/include/nm-macros-internal.h
+++ b/include/nm-macros-internal.h
@@ -198,6 +198,19 @@ nm_clear_g_source (guint *id)
return FALSE;
}
+static inline gboolean
+nm_clear_g_signal_handler (gpointer self, guint *id)
+{
+ g_return_val_if_fail (G_IS_OBJECT (self), FALSE);
+
+ if (id && *id) {
+ g_signal_handler_disconnect (self, *id);
+ *id = 0;
+ return TRUE;
+ }
+ return FALSE;
+}
+
/*****************************************************************************/
/* Determine whether @x is a power of two (@x being an integer type).
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index a6808bdee5..b15515b790 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -335,6 +335,7 @@ typedef struct {
/* master interface for bridge/bond/team slave */
NMDevice * master;
gboolean enslaved;
+ gboolean master_ready_handled;
guint master_ready_id;
/* slave management */
@@ -2855,19 +2856,22 @@ get_ip_config_may_fail (NMDevice *self, int family)
}
static void
-master_ready_cb (NMActiveConnection *active,
- GParamSpec *pspec,
- NMDevice *self)
+master_ready (NMDevice *self,
+ NMActiveConnection *active)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMActiveConnection *master;
- g_assert (priv->state == NM_DEVICE_STATE_PREPARE);
+ g_return_if_fail (priv->state == NM_DEVICE_STATE_PREPARE);
+ g_return_if_fail (!priv->master_ready_handled);
/* Notify a master device that it has a new slave */
- g_assert (nm_active_connection_get_master_ready (active));
+ g_return_if_fail (nm_active_connection_get_master_ready (active));
master = nm_active_connection_get_master (active);
+ priv->master_ready_handled = TRUE;
+ nm_clear_g_signal_handler (active, &priv->master_ready_id);
+
priv->master = g_object_ref (nm_active_connection_get_device (master));
nm_device_master_add_slave (priv->master,
self,
@@ -2876,11 +2880,14 @@ master_ready_cb (NMActiveConnection *active,
_LOGD (LOGD_DEVICE, "master connection ready; master device %s",
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;
- }
+}
+static void
+master_ready_cb (NMActiveConnection *active,
+ GParamSpec *pspec,
+ NMDevice *self)
+{
+ master_ready (self, active);
nm_device_activate_schedule_stage2_device_config (self);
}
@@ -2928,23 +2935,7 @@ nm_device_activate_stage1_device_prepare (gpointer user_data)
g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
}
- 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 {
- _LOGD (LOGD_DEVICE, "waiting for master connection to become ready");
-
- /* 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);
- /* Postpone */
- }
- } else
- nm_device_activate_schedule_stage2_device_config (self);
+ nm_device_activate_schedule_stage2_device_config (self);
out:
_LOGD (LOGD_DEVICE, "Activation: Stage 1 of 5 (Device Prepare) complete.");
@@ -2998,6 +2989,28 @@ nm_device_activate_stage2_device_config (gpointer user_data)
NMActiveConnection *active = NM_ACTIVE_CONNECTION (priv->act_request);
GSList *iter;
+ 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;
+ }
+ }
+ }
+
/* Clear the activation source ID now that this stage has run */
activation_source_clear (self, FALSE, 0);
@@ -6184,10 +6197,8 @@ 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;
- }
+ priv->master_ready_handled = FALSE;
+ nm_clear_g_signal_handler (priv->act_request, &priv->master_ready_id);
g_clear_object (&priv->act_request);
g_object_notify (G_OBJECT (self), NM_DEVICE_ACTIVE_CONNECTION);