wifi-p2p: fix failed assertion when releasing supplicant interface
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: 27bc2cb22a
https://github.com/NetworkManager/NetworkManager/pull/302
This commit is contained in:
@@ -462,6 +462,11 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason)
|
|||||||
|
|
||||||
nm_clear_g_source (&priv->sup_timeout_id);
|
nm_clear_g_source (&priv->sup_timeout_id);
|
||||||
|
|
||||||
|
if (!priv->mgmt_iface) {
|
||||||
|
NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
|
||||||
|
return NM_ACT_STAGE_RETURN_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
connection = nm_device_get_applied_connection (device);
|
connection = nm_device_get_applied_connection (device);
|
||||||
g_return_val_if_fail (connection, NM_ACT_STAGE_RETURN_FAILURE);
|
g_return_val_if_fail (connection, NM_ACT_STAGE_RETURN_FAILURE);
|
||||||
|
|
||||||
@@ -685,11 +690,10 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface,
|
|||||||
_set_is_waiting_for_supplicant (self, FALSE);
|
_set_is_waiting_for_supplicant (self, FALSE);
|
||||||
break;
|
break;
|
||||||
case NM_SUPPLICANT_INTERFACE_STATE_DOWN:
|
case NM_SUPPLICANT_INTERFACE_STATE_DOWN:
|
||||||
|
supplicant_interfaces_release (self, TRUE);
|
||||||
nm_device_queue_recheck_available (device,
|
nm_device_queue_recheck_available (device,
|
||||||
NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE,
|
NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE,
|
||||||
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
|
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
|
||||||
|
|
||||||
supplicant_interfaces_release (self, TRUE);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -911,20 +915,14 @@ supplicant_interfaces_release (NMDeviceWifiP2P *self, gboolean set_is_waiting)
|
|||||||
|
|
||||||
if (priv->mgmt_iface) {
|
if (priv->mgmt_iface) {
|
||||||
_LOGD (LOGD_DEVICE | LOGD_WIFI, "P2P: Releasing WPA supplicant interface.");
|
_LOGD (LOGD_DEVICE | LOGD_WIFI, "P2P: Releasing WPA supplicant interface.");
|
||||||
|
|
||||||
nm_supplicant_manager_set_wfd_ies (priv->sup_mgr, NULL);
|
nm_supplicant_manager_set_wfd_ies (priv->sup_mgr, NULL);
|
||||||
|
|
||||||
g_signal_handlers_disconnect_by_data (priv->mgmt_iface, self);
|
g_signal_handlers_disconnect_by_data (priv->mgmt_iface, self);
|
||||||
|
|
||||||
g_clear_object (&priv->mgmt_iface);
|
g_clear_object (&priv->mgmt_iface);
|
||||||
|
nm_clear_g_source (&priv->sup_timeout_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
supplicant_group_interface_release (self);
|
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)
|
if (set_is_waiting)
|
||||||
_set_is_waiting_for_supplicant (self, TRUE);
|
_set_is_waiting_for_supplicant (self, TRUE);
|
||||||
}
|
}
|
||||||
@@ -950,8 +948,7 @@ device_state_changed (NMDevice *device,
|
|||||||
supplicant_interfaces_release (self, TRUE);
|
supplicant_interfaces_release (self, TRUE);
|
||||||
|
|
||||||
/* TODO: More cleanup needed? */
|
/* TODO: More cleanup needed? */
|
||||||
} else
|
}
|
||||||
nm_assert (priv->mgmt_iface != NULL);
|
|
||||||
|
|
||||||
switch (new_state) {
|
switch (new_state) {
|
||||||
case NM_DEVICE_STATE_UNMANAGED:
|
case NM_DEVICE_STATE_UNMANAGED:
|
||||||
@@ -1064,6 +1061,14 @@ impl_device_wifi_p2p_stop_find (NMDBusObject *obj,
|
|||||||
NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (obj);
|
NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (obj);
|
||||||
NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self);
|
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);
|
nm_supplicant_interface_p2p_stop_find (priv->mgmt_iface);
|
||||||
|
|
||||||
g_dbus_method_invocation_return_value (invocation, NULL);
|
g_dbus_method_invocation_return_value (invocation, NULL);
|
||||||
@@ -1098,7 +1103,8 @@ nm_device_wifi_p2p_set_mgmt_iface (NMDeviceWifiP2P *self,
|
|||||||
if (!iface)
|
if (!iface)
|
||||||
goto done;
|
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);
|
priv->mgmt_iface = g_object_ref (iface);
|
||||||
|
|
||||||
@@ -1114,12 +1120,10 @@ nm_device_wifi_p2p_set_mgmt_iface (NMDeviceWifiP2P *self,
|
|||||||
g_signal_connect (priv->mgmt_iface, NM_SUPPLICANT_INTERFACE_GROUP_STARTED,
|
g_signal_connect (priv->mgmt_iface, NM_SUPPLICANT_INTERFACE_GROUP_STARTED,
|
||||||
G_CALLBACK (supplicant_iface_group_started_cb),
|
G_CALLBACK (supplicant_iface_group_started_cb),
|
||||||
self);
|
self);
|
||||||
|
done:
|
||||||
nm_device_queue_recheck_available (NM_DEVICE (self),
|
nm_device_queue_recheck_available (NM_DEVICE (self),
|
||||||
NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE,
|
NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE,
|
||||||
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
|
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
|
||||||
|
|
||||||
done:
|
|
||||||
_set_is_waiting_for_supplicant (self,
|
_set_is_waiting_for_supplicant (self,
|
||||||
!priv->mgmt_iface
|
!priv->mgmt_iface
|
||||||
|| ( nm_supplicant_interface_get_state (priv->mgmt_iface)
|
|| ( nm_supplicant_interface_get_state (priv->mgmt_iface)
|
||||||
|
Reference in New Issue
Block a user