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);