core: watch master ActiveConnections and follow master deactivation
This commit is contained in:
@@ -334,6 +334,28 @@ device_state_changed (NMDevice *device, GParamSpec *pspec, NMActRequest *self)
|
||||
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)
|
||||
{
|
||||
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));
|
||||
|
||||
/* virtual methods */
|
||||
object_class->constructed = constructed;
|
||||
object_class->dispose = dispose;
|
||||
active_class->master_failed = master_failed;
|
||||
}
|
||||
|
||||
|
@@ -265,6 +265,26 @@ nm_active_connection_get_master (NMActiveConnection *self)
|
||||
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:
|
||||
* @self: the #NMActiveConnection
|
||||
@@ -294,6 +314,10 @@ nm_active_connection_set_master (NMActiveConnection *self, NMActiveConnection *m
|
||||
g_return_if_fail (master_device != priv->device);
|
||||
|
||||
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->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->subject);
|
||||
|
||||
|
@@ -56,6 +56,8 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
GObjectClass parent;
|
||||
|
||||
void (*master_failed) (NMActiveConnection *connection);
|
||||
} NMActiveConnectionClass;
|
||||
|
||||
GType nm_active_connection_get_type (void);
|
||||
|
@@ -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
|
||||
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)
|
||||
{
|
||||
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));
|
||||
|
||||
@@ -1776,6 +1788,7 @@ nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class)
|
||||
object_class->constructed = constructed;
|
||||
object_class->dispose = dispose;
|
||||
object_class->finalize = finalize;
|
||||
active_class->master_failed = master_failed;
|
||||
|
||||
g_object_class_override_property (object_class, PROP_MASTER, NM_ACTIVE_CONNECTION_MASTER);
|
||||
|
||||
|
Reference in New Issue
Block a user