diff options
author | Thomas Haller <thaller@redhat.com> | 2019-08-22 10:43:22 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2019-08-28 16:27:00 +0200 |
commit | 29562a9751d97eb56bb5b56f3d36a96345559a5f (patch) | |
tree | 43027ed681c41ca57e440f671eae766ca09b57c5 /src | |
parent | 86f8f5a71c52af36e8e8d73e27612d6588d828c3 (diff) | |
download | NetworkManager-29562a9751d97eb56bb5b56f3d36a96345559a5f.tar.gz |
device: let devices call stage1 again after being ready to proceed
I am about to change the when stage1 gets postponed, then the way to
proceed it is to schedule stage1 again (instead of scheduling stage2).
The reason is that stage1 handling should be reentrant and we should
keep entering it until there is no more reason to postpone it. If
a subclass postpones stage1 and then later progresses it by directly
scheduling stage2, then only the subclass is in control over postponing
stage 2.
Instead, anybody should be able to delay stage2 independently. That can
only work if everybody signals readyness to proceed by scheduling stage1
again.
Diffstat (limited to 'src')
-rw-r--r-- | src/devices/nm-device-ethernet.c | 9 | ||||
-rw-r--r-- | src/devices/nm-device-macsec.c | 6 | ||||
-rw-r--r-- | src/devices/nm-device-wireguard.c | 6 | ||||
-rw-r--r-- | src/devices/team/nm-device-team.c | 26 | ||||
-rw-r--r-- | src/devices/wifi/nm-device-olpc-mesh.c | 6 | ||||
-rw-r--r-- | src/devices/wifi/nm-device-wifi-p2p.c | 36 | ||||
-rw-r--r-- | src/devices/wifi/nm-device-wifi.c | 6 | ||||
-rw-r--r-- | src/devices/wwan/nm-device-modem.c | 52 |
8 files changed, 99 insertions, 48 deletions
diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c index b69669ca6f..360e4d1714 100644 --- a/src/devices/nm-device-ethernet.c +++ b/src/devices/nm-device-ethernet.c @@ -454,8 +454,10 @@ wired_secrets_cb (NMActRequest *req, nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS); - } else - nm_device_activate_schedule_stage1_device_prepare (device); + return; + } + + nm_device_activate_schedule_stage1_device_prepare (device); } static void @@ -851,8 +853,9 @@ pppoe_reconnect_delay (gpointer user_data) NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); priv->pppoe_wait_id = 0; + priv->last_pppoe_time = 0; _LOGI (LOGD_DEVICE, "PPPoE reconnect delay complete, resuming connection..."); - nm_device_activate_schedule_stage2_device_config (NM_DEVICE (self)); + nm_device_activate_schedule_stage1_device_prepare (NM_DEVICE (self)); return G_SOURCE_REMOVE; } diff --git a/src/devices/nm-device-macsec.c b/src/devices/nm-device-macsec.c index e3e3a895b2..c4911eca28 100644 --- a/src/devices/nm-device-macsec.c +++ b/src/devices/nm-device-macsec.c @@ -308,8 +308,10 @@ macsec_secrets_cb (NMActRequest *req, nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS); - } else - nm_device_activate_schedule_stage1_device_prepare (device); + return; + } + + nm_device_activate_schedule_stage1_device_prepare (device); } static void diff --git a/src/devices/nm-device-wireguard.c b/src/devices/nm-device-wireguard.c index 572389b114..e64f33b560 100644 --- a/src/devices/nm-device-wireguard.c +++ b/src/devices/nm-device-wireguard.c @@ -1276,8 +1276,10 @@ _secrets_cb (NMActRequest *req, nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS); - } else - nm_device_activate_schedule_stage1_device_prepare (device); + return; + } + + nm_device_activate_schedule_stage1_device_prepare (device); } static void diff --git a/src/devices/team/nm-device-team.c b/src/devices/team/nm-device-team.c index c02c308bd8..bea756be35 100644 --- a/src/devices/team/nm-device-team.c +++ b/src/devices/team/nm-device-team.c @@ -56,6 +56,7 @@ typedef struct { guint teamd_read_timeout; guint teamd_dbus_watch; bool kill_in_progress:1; + NMDeviceStageState stage1_state:3; } NMDeviceTeamPrivate; struct _NMDeviceTeam { @@ -407,19 +408,20 @@ teamd_dbus_appeared (GDBusConnection *connection, */ success = ensure_teamd_connection (device); - if (nm_device_get_state (device) != NM_DEVICE_STATE_PREPARE) + if ( nm_device_get_state (device) != NM_DEVICE_STATE_PREPARE + || priv->stage1_state != NM_DEVICE_STAGE_STATE_PENDING) return; + if (success) + success = teamd_read_config (self); + if (!success) { - if (!nm_device_sys_iface_state_is_external_or_assume (device)) { - teamd_cleanup (self, TRUE); - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); - } + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); return; } - if (teamd_read_config (self)) - nm_device_activate_schedule_stage2_device_config (device); + priv->stage1_state = NM_DEVICE_STAGE_STATE_COMPLETED; + nm_device_activate_schedule_stage1_device_prepare (device); } static void @@ -658,6 +660,14 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) if (!s_team) g_return_val_if_reached (NM_ACT_STAGE_RETURN_FAILURE); + if (priv->stage1_state == NM_DEVICE_STAGE_STATE_PENDING) + return NM_ACT_STAGE_RETURN_POSTPONE; + + if (priv->stage1_state == NM_DEVICE_STAGE_STATE_COMPLETED) + return NM_ACT_STAGE_RETURN_SUCCESS; + + priv->stage1_state = NM_DEVICE_STAGE_STATE_PENDING; + if (priv->tdc) { /* If the existing teamd config is the same as we're about to use, * then we can proceed. If it's not the same, and we have a PID, @@ -701,6 +711,8 @@ deactivate (NMDevice *device) NMDeviceTeam *self = NM_DEVICE_TEAM (device); NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); + priv->stage1_state = NM_DEVICE_STAGE_STATE_INIT; + if (nm_device_sys_iface_state_is_external (device)) return; diff --git a/src/devices/wifi/nm-device-olpc-mesh.c b/src/devices/wifi/nm-device-olpc-mesh.c index 0a89e5a671..3551a9e486 100644 --- a/src/devices/wifi/nm-device-olpc-mesh.c +++ b/src/devices/wifi/nm-device-olpc-mesh.c @@ -58,7 +58,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceOlpcMesh, typedef struct { NMDevice *companion; NMManager *manager; - gboolean stage1_waiting; + bool stage1_waiting:1; } NMDeviceOlpcMeshPrivate; struct _NMDeviceOlpcMesh { @@ -166,6 +166,7 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) return NM_ACT_STAGE_RETURN_POSTPONE; } + priv->stage1_waiting = FALSE; return NM_ACT_STAGE_RETURN_SUCCESS; } @@ -249,10 +250,9 @@ companion_notify_cb (NMDeviceWifi *companion, GParamSpec *pspec, gpointer user_d return; g_object_get (companion, NM_DEVICE_WIFI_SCANNING, &scanning, NULL); - if (!scanning) { priv->stage1_waiting = FALSE; - nm_device_activate_schedule_stage2_device_config (NM_DEVICE (self)); + nm_device_activate_schedule_stage1_device_prepare (NM_DEVICE (self)); } } diff --git a/src/devices/wifi/nm-device-wifi-p2p.c b/src/devices/wifi/nm-device-wifi-p2p.c index fe2f7bc4d8..5e75e26022 100644 --- a/src/devices/wifi/nm-device-wifi-p2p.c +++ b/src/devices/wifi/nm-device-wifi-p2p.c @@ -63,6 +63,7 @@ typedef struct { CList peers_lst_head; + guint find_peer_timeout_id; guint sup_timeout_id; guint peer_dump_id; guint peer_missing_id; @@ -349,7 +350,7 @@ supplicant_find_timeout_cb (gpointer user_data) NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (user_data); NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self); - priv->sup_timeout_id = 0; + priv->find_peer_timeout_id = 0; nm_supplicant_interface_p2p_cancel_connect (priv->mgmt_iface); @@ -386,10 +387,10 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) peer = nm_wifi_p2p_peers_find_first_compatible (&priv->peers_lst_head, connection); if (!peer) { /* Set up a timeout on the find attempt and run a find for the same period of time */ - if (priv->sup_timeout_id == 0) { - priv->sup_timeout_id = g_timeout_add_seconds (10, - supplicant_find_timeout_cb, - self); + if (priv->find_peer_timeout_id == 0) { + priv->find_peer_timeout_id = g_timeout_add_seconds (10, + supplicant_find_timeout_cb, + self); nm_supplicant_interface_p2p_start_find (priv->mgmt_iface, 10); } @@ -436,7 +437,8 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason) NMWifiP2PPeer *peer; GBytes *wfd_ies; - nm_clear_g_source (&priv->sup_timeout_id); + if (nm_clear_g_source (&priv->find_peer_timeout_id)) + nm_assert_not_reached (); if (!priv->mgmt_iface) { NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); @@ -468,9 +470,11 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason) "pbc", NULL); /* Set up a timeout on the connect attempt */ - priv->sup_timeout_id = g_timeout_add_seconds (45, - supplicant_connection_timeout_cb, - self); + if (priv->sup_timeout_id == 0) { + priv->sup_timeout_id = g_timeout_add_seconds (45, + supplicant_connection_timeout_cb, + self); + } /* We'll get stage3 started when the P2P group has been started */ return NM_ACT_STAGE_RETURN_POSTPONE; @@ -525,17 +529,19 @@ peer_add_remove (NMDeviceWifiP2P *self, if (is_adding) { /* If we are in prepare state, then we are currently runnign a find * to search for the requested peer. */ - if (nm_device_get_state (device) == NM_DEVICE_STATE_PREPARE) { + if (priv->find_peer_timeout_id != 0) { NMConnection *connection; + nm_assert (nm_device_get_state (device) == NM_DEVICE_STATE_PREPARE); + connection = nm_device_get_applied_connection (device); - g_assert (connection); + nm_assert (NM_IS_CONNECTION (connection)); peer = nm_wifi_p2p_peers_find_first_compatible (&priv->peers_lst_head, connection); if (peer) { /* A peer for the connection was found, cancel the timeout and go to configure state. */ - nm_clear_g_source (&priv->sup_timeout_id); - nm_device_activate_schedule_stage2_device_config (device); + nm_clear_g_source (&priv->find_peer_timeout_id); + nm_device_activate_schedule_stage1_device_prepare (device); } } @@ -594,9 +600,10 @@ static void deactivate (NMDevice *device) { NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (device); - NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self); int ifindex = nm_device_get_ip_ifindex (device); + NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self); + nm_clear_g_source (&priv->find_peer_timeout_id); nm_clear_g_source (&priv->sup_timeout_id); nm_clear_g_source (&priv->peer_missing_id); @@ -902,6 +909,7 @@ supplicant_interfaces_release (NMDeviceWifiP2P *self, gboolean set_is_waiting) 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->find_peer_timeout_id); nm_clear_g_source (&priv->sup_timeout_id); } diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index d9394ffdd5..28e8bbefb6 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -1735,8 +1735,10 @@ wifi_secrets_cb (NMActRequest *req, nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS); - } else - nm_device_activate_schedule_stage1_device_prepare (device); + return; + } + + nm_device_activate_schedule_stage1_device_prepare (device); } static void diff --git a/src/devices/wwan/nm-device-modem.c b/src/devices/wwan/nm-device-modem.c index be0993916d..7ba664394a 100644 --- a/src/devices/wwan/nm-device-modem.c +++ b/src/devices/wwan/nm-device-modem.c @@ -48,10 +48,11 @@ typedef struct { NMModem *modem; NMDeviceModemCapabilities caps; NMDeviceModemCapabilities current_caps; - gboolean rf_enabled; char *device_id; char *operator_code; char *apn; + bool rf_enabled:1; + NMDeviceStageState stage1_state:3; } NMDeviceModemPrivate; struct _NMDeviceModem { @@ -119,16 +120,17 @@ modem_prepare_result (NMModem *modem, gpointer user_data) { NMDeviceModem *self = NM_DEVICE_MODEM (user_data); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self); NMDevice *device = NM_DEVICE (self); - NMDeviceState state; NMDeviceStateReason reason = i_reason; - state = nm_device_get_state (device); - g_return_if_fail (state == NM_DEVICE_STATE_PREPARE); + if ( nm_device_get_state (device) != NM_DEVICE_STATE_PREPARE + || priv->stage1_state != NM_DEVICE_STAGE_STATE_PENDING) { + nm_assert_not_reached (); + success = FALSE; + } - if (success) - nm_device_activate_schedule_stage2_device_config (device); - else { + if (!success) { /* There are several reasons to block autoconnection at device level: * * - Wrong SIM-PIN: The device won't autoconnect because it doesn't make sense @@ -164,7 +166,11 @@ modem_prepare_result (NMModem *modem, break; } nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason); + return; } + + priv->stage1_state = NM_DEVICE_STAGE_STATE_COMPLETED; + nm_device_activate_schedule_stage1_device_prepare (device); } static void @@ -187,16 +193,19 @@ static void modem_auth_result (NMModem *modem, GError *error, gpointer user_data) { NMDevice *device = NM_DEVICE (user_data); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device); + + g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_NEED_AUTH); if (error) { nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS); - } else { - /* Otherwise, on success for modem secrets we need to schedule stage1 again */ - g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_NEED_AUTH); - nm_device_activate_schedule_stage1_device_prepare (device); + return; } + + priv->stage1_state = NM_DEVICE_STAGE_STATE_INIT; + nm_device_activate_schedule_stage1_device_prepare (device); } static void @@ -542,7 +551,10 @@ complete_connection (NMDevice *device, static void deactivate (NMDevice *device) { - nm_modem_deactivate (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem, device); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device); + + nm_modem_deactivate (priv->modem, device); + priv->stage1_state = NM_DEVICE_STAGE_STATE_INIT; } /*****************************************************************************/ @@ -583,14 +595,24 @@ deactivate_async (NMDevice *self, static NMActStageReturn act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) { + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device); NMActRequest *req; req = nm_device_get_act_request (device); g_return_val_if_fail (req, NM_ACT_STAGE_RETURN_FAILURE); - return nm_modem_act_stage1_prepare (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem, - req, - out_failure_reason); + if (priv->stage1_state == NM_DEVICE_STAGE_STATE_INIT) { + priv->stage1_state = NM_DEVICE_STAGE_STATE_PENDING; + return nm_modem_act_stage1_prepare (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem, + req, + out_failure_reason); + } + + if (priv->stage1_state == NM_DEVICE_STAGE_STATE_PENDING) + return NM_ACT_STAGE_RETURN_POSTPONE; + + nm_assert (priv->stage1_state == NM_DEVICE_STAGE_STATE_COMPLETED); + return NM_ACT_STAGE_RETURN_SUCCESS; } static NMActStageReturn |