summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2014-05-23 18:25:05 -0500
committerDan Williams <dcbw@redhat.com>2014-06-06 13:43:46 -0500
commit7eaaa6a475b3d73e0967c9fa928268c1498f6b50 (patch)
tree80e084502b2abc868e4f00a53252f1a0c9de4046
parent38e6b7387fd8a1ecf8e539428dab2aea3713220a (diff)
downloadNetworkManager-7eaaa6a475b3d73e0967c9fa928268c1498f6b50.tar.gz
core: block on dispatcher scripts when quitting
Like VPN connections, block on dispatcher scripts when quitting. Since the event loop is no longer running we can't schedule callbacks.
-rw-r--r--src/devices/nm-device.c67
-rw-r--r--src/devices/nm-device.h1
-rw-r--r--src/nm-manager.c8
3 files changed, 60 insertions, 16 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index a543c6f740..a6b4b548f0 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -321,6 +321,11 @@ static void addrconf6_start_with_link_ready (NMDevice *self);
static gboolean nm_device_get_default_unmanaged (NMDevice *device);
+static void _set_state_full (NMDevice *device,
+ NMDeviceState state,
+ NMDeviceStateReason reason,
+ gboolean quitting);
+
/***********************************************************/
static GQuark
@@ -5944,6 +5949,21 @@ nm_device_set_unmanaged (NMDevice *device,
}
}
+void
+nm_device_set_unmanaged_quitting (NMDevice *device)
+{
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
+
+ /* It's OK to block here because we're quitting */
+ if (nm_device_is_activating (device) || priv->state == NM_DEVICE_STATE_ACTIVATED)
+ _set_state_full (device, NM_DEVICE_STATE_DEACTIVATING, NM_DEVICE_STATE_REASON_REMOVED, TRUE);
+
+ nm_device_set_unmanaged (device,
+ NM_UNMANAGED_INTERNAL,
+ TRUE,
+ NM_DEVICE_STATE_REASON_REMOVED);
+}
+
/**
* nm_device_set_initial_unmanaged_flag():
* @device: the #NMDevice
@@ -6536,10 +6556,11 @@ notify_ip_properties (NMDevice *device)
g_object_notify (G_OBJECT (device), NM_DEVICE_DHCP6_CONFIG);
}
-void
-nm_device_state_changed (NMDevice *device,
- NMDeviceState state,
- NMDeviceStateReason reason)
+static void
+_set_state_full (NMDevice *device,
+ NMDeviceState state,
+ NMDeviceStateReason reason,
+ gboolean quitting)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
NMDeviceState old_state;
@@ -6677,14 +6698,20 @@ nm_device_state_changed (NMDevice *device,
}
break;
case NM_DEVICE_STATE_DEACTIVATING:
- if (!nm_dispatcher_call (DISPATCHER_ACTION_PRE_DOWN,
- nm_act_request_get_connection (req),
- device,
- dispatcher_pre_down_done,
- device,
- &priv->dispatcher_id)) {
- /* Just proceed on errors */
- dispatcher_pre_down_done (0, device);
+ if (quitting) {
+ nm_dispatcher_call_sync (DISPATCHER_ACTION_PRE_DOWN,
+ nm_act_request_get_connection (req),
+ device);
+ } else {
+ if (!nm_dispatcher_call (DISPATCHER_ACTION_PRE_DOWN,
+ nm_act_request_get_connection (req),
+ device,
+ dispatcher_pre_down_done,
+ device,
+ &priv->dispatcher_id)) {
+ /* Just proceed on errors */
+ dispatcher_pre_down_done (0, device);
+ }
}
break;
case NM_DEVICE_STATE_DISCONNECTED:
@@ -6752,8 +6779,12 @@ nm_device_state_changed (NMDevice *device,
delete_on_deactivate_unschedule (device);
if ( (old_state == NM_DEVICE_STATE_ACTIVATED || old_state == NM_DEVICE_STATE_DEACTIVATING)
- && (state != NM_DEVICE_STATE_DEACTIVATING))
- nm_dispatcher_call (DISPATCHER_ACTION_DOWN, nm_act_request_get_connection (req), device, NULL, NULL, NULL);
+ && (state != NM_DEVICE_STATE_DEACTIVATING)) {
+ if (quitting)
+ nm_dispatcher_call_sync (DISPATCHER_ACTION_DOWN, nm_act_request_get_connection (req), device);
+ else
+ nm_dispatcher_call (DISPATCHER_ACTION_DOWN, nm_act_request_get_connection (req), device, NULL, NULL, NULL);
+ }
/* IP-related properties are only valid when the device has IP configuration.
* If it no longer does, ensure their change notifications are emitted.
@@ -6768,6 +6799,14 @@ nm_device_state_changed (NMDevice *device,
priv->in_state_changed = FALSE;
}
+void
+nm_device_state_changed (NMDevice *device,
+ NMDeviceState state,
+ NMDeviceStateReason reason)
+{
+ _set_state_full (device, state, reason, FALSE);
+}
+
static gboolean
queued_set_state (gpointer user_data)
{
diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h
index 3241bceafa..f74486e6fc 100644
--- a/src/devices/nm-device.h
+++ b/src/devices/nm-device.h
@@ -312,6 +312,7 @@ void nm_device_set_unmanaged (NMDevice *device,
NMUnmanagedFlags flag,
gboolean unmanaged,
NMDeviceStateReason reason);
+void nm_device_set_unmanaged_quitting (NMDevice *device);
void nm_device_set_initial_unmanaged_flag (NMDevice *device,
NMUnmanagedFlags flag,
gboolean unmanaged);
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 14e071e0bb..6fc74df14a 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -742,8 +742,12 @@ remove_device (NMManager *manager, NMDevice *device, gboolean quitting)
else if (!req)
unmanage = TRUE;
- if (unmanage)
- nm_device_set_unmanaged (device, NM_UNMANAGED_INTERNAL, TRUE, NM_DEVICE_STATE_REASON_REMOVED);
+ if (unmanage) {
+ if (quitting)
+ nm_device_set_unmanaged_quitting (device);
+ else
+ nm_device_set_unmanaged (device, NM_UNMANAGED_INTERNAL, TRUE, NM_DEVICE_STATE_REASON_REMOVED);
+ }
}
g_signal_handlers_disconnect_matched (device, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, manager);