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.
This commit is contained in:
Dan Williams
2013-08-27 12:16:57 -05:00
parent 4237df8c21
commit 3bb2b158cd
4 changed files with 44 additions and 26 deletions

View File

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

View File

@@ -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 (),

View File

@@ -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 */

View File

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