From 3bb2b158cdda573b79a8c209cf25f956e94e9e0d Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 27 Aug 2013 12:16:57 -0500 Subject: [PATCH] core: switch NMActiveConnection master to an NMActiveConnection instead of NMDevice We need to track the master active connection, since it may require authentication or other operations to complete before the device actually starts activating. --- src/devices/nm-device.c | 24 ++++++++++++++--------- src/nm-active-connection.c | 39 ++++++++++++++++++++++++-------------- src/nm-active-connection.h | 5 +++-- src/nm-manager.c | 2 +- 4 files changed, 44 insertions(+), 26 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 294aa9918..5c87525b4 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -3445,7 +3445,8 @@ nm_device_activate_stage3_ip_config_start (gpointer user_data) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); const char *iface; int ifindex; - NMDevice *master; + NMActiveConnection *master; + NMDevice *master_device; /* Clear the activation source ID now that this stage has run */ activation_source_clear (self, FALSE, 0); @@ -3471,11 +3472,12 @@ nm_device_activate_stage3_ip_config_start (gpointer user_data) */ master = nm_active_connection_get_master (NM_ACTIVE_CONNECTION (priv->act_request)); if (master) { - if (priv->enslaved == FALSE) { + master_device = nm_active_connection_get_device (master); + if (master_device && priv->enslaved == FALSE) { nm_log_info (LOGD_DEVICE, "Activation (%s) connection '%s' waiting on master '%s'", nm_device_get_iface (self), nm_connection_get_id (nm_device_get_connection (self)), - nm_device_get_iface (master)); + nm_device_get_iface (master_device)); } goto out; } @@ -4425,7 +4427,8 @@ 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 { - NMDevice *master; + 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 @@ -4437,12 +4440,15 @@ nm_device_activate (NMDevice *self, NMActRequest *req) /* Handle any dependencies this connection might have */ master = nm_active_connection_get_master (NM_ACTIVE_CONNECTION (req)); if (master) { - /* Master should at least already be activating */ - g_assert (nm_device_get_state (master) > NM_DEVICE_STATE_DISCONNECTED); + 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); - nm_device_master_add_slave (master, self); + 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); diff --git a/src/nm-active-connection.c b/src/nm-active-connection.c index 72ee79823..d24c62127 100644 --- a/src/nm-active-connection.c +++ b/src/nm-active-connection.c @@ -51,7 +51,7 @@ typedef struct { gboolean vpn; NMAuthSubject *subject; - NMDevice *master; + NMActiveConnection *master; NMAuthChain *chain; const char *wifi_shared_permission; @@ -257,7 +257,7 @@ nm_active_connection_get_device (NMActiveConnection *self) return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->device; } -NMDevice * +NMActiveConnection * nm_active_connection_get_master (NMActiveConnection *self) { g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), NULL); @@ -269,24 +269,29 @@ nm_active_connection_get_master (NMActiveConnection *self) * nm_active_connection_set_master: * @self: the #NMActiveConnection * @master: if the activation depends on another device (ie, bond or bridge - * master to which this device will be enslaved) pass the #NMDevice that this - * activation request be enslaved to + * master to which this device will be enslaved) pass the #NMActiveConnection + * that this activation request is a child of * - * Sets the master device of the active connection. + * Sets the master active connection of @self. */ void -nm_active_connection_set_master (NMActiveConnection *self, NMDevice *master) +nm_active_connection_set_master (NMActiveConnection *self, NMActiveConnection *master) { NMActiveConnectionPrivate *priv; + NMDevice *master_device; g_return_if_fail (NM_IS_ACTIVE_CONNECTION (self)); - g_return_if_fail (NM_IS_DEVICE (self)); + g_return_if_fail (NM_IS_ACTIVE_CONNECTION (master)); priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); + /* Master is write-once, and must be set before exporting the object */ g_return_if_fail (priv->master == NULL); g_return_if_fail (priv->path == NULL); - g_return_if_fail (master != priv->device); + + master_device = nm_active_connection_get_device (master); + if (master_device) + g_return_if_fail (master_device != priv->device); priv->master = g_object_ref (master); } @@ -413,6 +418,7 @@ set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object); + NMDevice *master_device; const char *tmp; switch (prop_id) { @@ -423,8 +429,10 @@ set_property (GObject *object, guint prop_id, case PROP_INT_DEVICE: g_warn_if_fail (priv->device == NULL); priv->device = g_value_dup_object (value); - if (priv->device) - g_warn_if_fail (priv->device != priv->master); + if (priv->device && priv->master) { + master_device = nm_active_connection_get_device (priv->master); + g_warn_if_fail (priv->device != master_device); + } break; case PROP_INT_SUBJECT: priv->subject = g_value_dup_object (value); @@ -461,6 +469,7 @@ get_property (GObject *object, guint prop_id, { NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object); GPtrArray *devices; + NMDevice *master_device = NULL; switch (prop_id) { case PROP_CONNECTION: @@ -491,7 +500,9 @@ get_property (GObject *object, guint prop_id, g_value_set_boolean (value, priv->vpn); break; case PROP_MASTER: - g_value_set_boxed (value, priv->master ? nm_device_get_path (priv->master) : "/"); + if (priv->master) + master_device = nm_active_connection_get_device (priv->master); + g_value_set_boxed (value, master_device ? nm_device_get_path (master_device) : "/"); break; case PROP_INT_SUBJECT: g_value_set_object (value, priv->subject); @@ -628,9 +639,9 @@ nm_active_connection_class_init (NMActiveConnectionClass *ac_class) g_object_class_install_property (object_class, PROP_INT_MASTER, g_param_spec_object (NM_ACTIVE_CONNECTION_INT_MASTER, - "Internal master device", - "Internal device", - NM_TYPE_DEVICE, + "Internal master active connection", + "Internal active connection", + NM_TYPE_ACTIVE_CONNECTION, G_PARAM_READWRITE)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), diff --git a/src/nm-active-connection.h b/src/nm-active-connection.h index 96c7cba72..93723c904 100644 --- a/src/nm-active-connection.h +++ b/src/nm-active-connection.h @@ -107,8 +107,9 @@ gboolean nm_active_connection_get_user_requested (NMActiveConnection *self) gulong nm_active_connection_get_user_uid (NMActiveConnection *self); -NMDevice * nm_active_connection_get_master (NMActiveConnection *self); +NMActiveConnection *nm_active_connection_get_master (NMActiveConnection *self); -void nm_active_connection_set_master (NMActiveConnection *self, NMDevice *master); +void nm_active_connection_set_master (NMActiveConnection *self, + NMActiveConnection *master); #endif /* NM_ACTIVE_CONNECTION_H */ diff --git a/src/nm-manager.c b/src/nm-manager.c index f8cfa7fc9..f3f223223 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -2561,7 +2561,7 @@ internal_activate_device (NMManager *manager, subject, device); g_assert (req); - nm_active_connection_set_master (NM_ACTIVE_CONNECTION (req), master_device); + nm_active_connection_set_master (NM_ACTIVE_CONNECTION (req), master); nm_device_activate (device, req); return NM_ACTIVE_CONNECTION (req);