core: watch master ActiveConnections and follow master deactivation

This commit is contained in:
Dan Williams
2013-08-28 09:08:43 -05:00
parent 3bb2b158cd
commit 8252357dd1
4 changed files with 69 additions and 0 deletions

View File

@@ -334,6 +334,28 @@ device_state_changed (NMDevice *device, GParamSpec *pspec, NMActRequest *self)
nm_active_connection_set_state (NM_ACTIVE_CONNECTION (self), ac_state); nm_active_connection_set_state (NM_ACTIVE_CONNECTION (self), ac_state);
} }
static void
master_failed (NMActiveConnection *self)
{
NMDevice *device;
NMDeviceState device_state;
/* If the connection has an active device, fail it */
device = nm_active_connection_get_device (self);
if (device) {
device_state = nm_device_get_state (device);
if (nm_device_is_activating (device) || (device_state == NM_DEVICE_STATE_ACTIVATED)) {
nm_device_state_changed (device,
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED);
return;
}
}
/* If no device, or the device wasn't active, just move to deactivated state */
nm_active_connection_set_state (self, NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);
}
/********************************************************************/ /********************************************************************/
/** /**
@@ -426,11 +448,13 @@ static void
nm_act_request_class_init (NMActRequestClass *req_class) nm_act_request_class_init (NMActRequestClass *req_class)
{ {
GObjectClass *object_class = G_OBJECT_CLASS (req_class); GObjectClass *object_class = G_OBJECT_CLASS (req_class);
NMActiveConnectionClass *active_class = NM_ACTIVE_CONNECTION_CLASS (req_class);
g_type_class_add_private (req_class, sizeof (NMActRequestPrivate)); g_type_class_add_private (req_class, sizeof (NMActRequestPrivate));
/* virtual methods */ /* virtual methods */
object_class->constructed = constructed; object_class->constructed = constructed;
object_class->dispose = dispose; object_class->dispose = dispose;
active_class->master_failed = master_failed;
} }

View File

@@ -265,6 +265,26 @@ nm_active_connection_get_master (NMActiveConnection *self)
return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->master; return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->master;
} }
static void
master_state_cb (NMActiveConnection *master,
GParamSpec *pspec,
gpointer user_data)
{
NMActiveConnection *self = NM_ACTIVE_CONNECTION (user_data);
NMActiveConnectionState self_state = nm_active_connection_get_state (self);
NMActiveConnectionState master_state = nm_active_connection_get_state (master);
/* Master is deactivating, so this active connection must also deactivate */
if (self_state < NM_ACTIVE_CONNECTION_STATE_DEACTIVATING &&
master_state >= NM_ACTIVE_CONNECTION_STATE_DEACTIVATING) {
g_signal_handlers_disconnect_by_func (master,
(GCallback) master_state_cb,
self);
if (NM_ACTIVE_CONNECTION_GET_CLASS (self)->master_failed)
NM_ACTIVE_CONNECTION_GET_CLASS (self)->master_failed (self);
}
}
/** /**
* nm_active_connection_set_master: * nm_active_connection_set_master:
* @self: the #NMActiveConnection * @self: the #NMActiveConnection
@@ -294,6 +314,10 @@ nm_active_connection_set_master (NMActiveConnection *self, NMActiveConnection *m
g_return_if_fail (master_device != priv->device); g_return_if_fail (master_device != priv->device);
priv->master = g_object_ref (master); priv->master = g_object_ref (master);
g_signal_connect (priv->master,
"notify::" NM_ACTIVE_CONNECTION_STATE,
(GCallback) master_state_cb,
self);
} }
/****************************************************************/ /****************************************************************/
@@ -530,6 +554,12 @@ dispose (GObject *object)
g_clear_object (&priv->connection); g_clear_object (&priv->connection);
g_clear_object (&priv->device); g_clear_object (&priv->device);
if (priv->master) {
g_signal_handlers_disconnect_by_func (priv->master,
(GCallback) master_state_cb,
NM_ACTIVE_CONNECTION (object));
}
g_clear_object (&priv->master); g_clear_object (&priv->master);
g_clear_object (&priv->subject); g_clear_object (&priv->subject);

View File

@@ -56,6 +56,8 @@ typedef struct {
typedef struct { typedef struct {
GObjectClass parent; GObjectClass parent;
void (*master_failed) (NMActiveConnection *connection);
} NMActiveConnectionClass; } NMActiveConnectionClass;
GType nm_active_connection_get_type (void); GType nm_active_connection_get_type (void);

View File

@@ -295,6 +295,17 @@ device_state_changed (NMDevice *device,
} }
} }
static void
master_failed (NMActiveConnection *self)
{
NMVPNConnection *connection = NM_VPN_CONNECTION (self);
/* Master failure fails the VPN */
nm_vpn_connection_set_vpn_state (connection,
NM_VPN_CONNECTION_STATE_FAILED,
NM_VPN_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED);
}
static void static void
add_ip4_vpn_gateway_route (NMDevice *parent_device, guint32 vpn_gw) add_ip4_vpn_gateway_route (NMDevice *parent_device, guint32 vpn_gw)
{ {
@@ -1768,6 +1779,7 @@ static void
nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class) nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class)
{ {
GObjectClass *object_class = G_OBJECT_CLASS (connection_class); GObjectClass *object_class = G_OBJECT_CLASS (connection_class);
NMActiveConnectionClass *active_class = NM_ACTIVE_CONNECTION_CLASS (connection_class);
g_type_class_add_private (connection_class, sizeof (NMVPNConnectionPrivate)); g_type_class_add_private (connection_class, sizeof (NMVPNConnectionPrivate));
@@ -1776,6 +1788,7 @@ nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class)
object_class->constructed = constructed; object_class->constructed = constructed;
object_class->dispose = dispose; object_class->dispose = dispose;
object_class->finalize = finalize; object_class->finalize = finalize;
active_class->master_failed = master_failed;
g_object_class_override_property (object_class, PROP_MASTER, NM_ACTIVE_CONNECTION_MASTER); g_object_class_override_property (object_class, PROP_MASTER, NM_ACTIVE_CONNECTION_MASTER);