diff options
author | Dan Williams <dcbw@redhat.com> | 2014-05-23 18:25:05 -0500 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2014-06-06 13:43:46 -0500 |
commit | 7eaaa6a475b3d73e0967c9fa928268c1498f6b50 (patch) | |
tree | 80e084502b2abc868e4f00a53252f1a0c9de4046 | |
parent | 38e6b7387fd8a1ecf8e539428dab2aea3713220a (diff) | |
download | NetworkManager-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.c | 67 | ||||
-rw-r--r-- | src/devices/nm-device.h | 1 | ||||
-rw-r--r-- | src/nm-manager.c | 8 |
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); |