mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-05 17:00:29 +01:00
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.
This commit is contained in:
parent
86f8f5a71c
commit
29562a9751
8 changed files with 99 additions and 48 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue