diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2019-03-03 16:47:41 +0100 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2019-03-04 18:23:44 +0100 |
commit | 30e1c2c3600b6609eea16cc70ecc32e428c824c4 (patch) | |
tree | 025f0a5e5f8d5d7a27066d14a6e258ac25f58c09 | |
parent | 93bbe436958264d5f720ce095b3f390ce50fc732 (diff) | |
download | NetworkManager-bg/wifi-p2p-assertion.tar.gz |
wifi-p2p: fix failed assertion when releasing supplicant interfacebg/wifi-p2p-assertion
Fix the following failed assertion:
<debug> device[0x11dfec0] (p2p-dev-wlp4s0): P2P: Releasing WPA supplicant interface.
<debug> supplicant: setting WFD IEs for P2P operation
(../src/devices/nm-device.c:14769):_set_state_full: runtime check failed: (priv->in_state_changed == FALSE)
<info> device (p2p-dev-wlp4s0): state change: unmanaged -> unavailable (reason 'supplicant-failed', sys-iface-state: 'external')
<debug> device[0x11dfec0] (p2p-dev-wlp4s0): add_pending_action (1): 'waiting-for-supplicant'
supplicant_interfaces_release() can be called during a state change
(for example by device_state_changed()) and so it can't trigger
another state change.
nm_device_wifi_p2p_set_mgmt_iface() now doesn't force an immediate
state change and only schedules a recheck-available. This means that
the device can be in an available state without
priv->mgmt_iface. Adapt the code to deal gracefully with that
situation. In particular, we need to cancel pending timeout sources
(priv->sup_timeout_id) that use the management interface.
Fixes: 27bc2cb22a6bdd3dc0c1ad2a67464939dcf53049
-rw-r--r-- | src/devices/wifi/nm-device-wifi-p2p.c | 29 |
1 files changed, 14 insertions, 15 deletions
diff --git a/src/devices/wifi/nm-device-wifi-p2p.c b/src/devices/wifi/nm-device-wifi-p2p.c index a429539642..83173c851f 100644 --- a/src/devices/wifi/nm-device-wifi-p2p.c +++ b/src/devices/wifi/nm-device-wifi-p2p.c @@ -705,11 +705,10 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface, _set_is_waiting_for_supplicant (self, FALSE); break; case NM_SUPPLICANT_INTERFACE_STATE_DOWN: + supplicant_interfaces_release (self, TRUE); nm_device_queue_recheck_available (device, NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); - - supplicant_interfaces_release (self, TRUE); break; default: break; @@ -931,20 +930,14 @@ supplicant_interfaces_release (NMDeviceWifiP2P *self, gboolean set_is_waiting) if (priv->mgmt_iface) { _LOGD (LOGD_DEVICE | LOGD_WIFI, "P2P: Releasing WPA supplicant interface."); - nm_supplicant_manager_set_wfd_ies (priv->sup_mgr, NULL); - g_signal_handlers_disconnect_by_data (priv->mgmt_iface, self); - g_clear_object (&priv->mgmt_iface); + nm_clear_g_source (&priv->sup_timeout_id); } supplicant_group_interface_release (self); - nm_device_state_changed (NM_DEVICE (self), - NM_DEVICE_STATE_UNAVAILABLE, - NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); - if (set_is_waiting) _set_is_waiting_for_supplicant (self, TRUE); } @@ -970,8 +963,7 @@ device_state_changed (NMDevice *device, supplicant_interfaces_release (self, TRUE); /* TODO: More cleanup needed? */ - } else - nm_assert (priv->mgmt_iface != NULL); + } switch (new_state) { case NM_DEVICE_STATE_UNMANAGED: @@ -1084,6 +1076,14 @@ impl_device_wifi_p2p_stop_find (NMDBusObject *obj, NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (obj); NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self); + if (!priv->mgmt_iface) { + g_dbus_method_invocation_return_error_literal (invocation, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_ACTIVE, + "WPA Supplicant management interface is currently unavailable."); + return; + } + nm_supplicant_interface_p2p_stop_find (priv->mgmt_iface); g_dbus_method_invocation_return_value (invocation, NULL); @@ -1118,7 +1118,8 @@ nm_device_wifi_p2p_set_mgmt_iface (NMDeviceWifiP2P *self, if (!iface) goto done; - _LOGD (LOGD_DEVICE | LOGD_WIFI, "P2P: WPA supplicant management interface changed to %s.", nm_supplicant_interface_get_object_path (iface)); + _LOGD (LOGD_DEVICE | LOGD_WIFI, "P2P: WPA supplicant management interface changed to %s.", + nm_supplicant_interface_get_object_path (iface)); priv->mgmt_iface = g_object_ref (iface); @@ -1134,12 +1135,10 @@ nm_device_wifi_p2p_set_mgmt_iface (NMDeviceWifiP2P *self, g_signal_connect (priv->mgmt_iface, NM_SUPPLICANT_INTERFACE_GROUP_STARTED, G_CALLBACK (supplicant_iface_group_started_cb), self); - +done: nm_device_queue_recheck_available (NM_DEVICE (self), NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); - -done: _set_is_waiting_for_supplicant (self, !priv->mgmt_iface || ( nm_supplicant_interface_get_state (priv->mgmt_iface) |