From 61c44dad91733bc09e20752915476a7678a73b90 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Thu, 16 Jul 2020 11:57:14 +0200 Subject: [PATCH 1/2] manager: fix race condition when resuming from sleep If the device state change (to disconnected or unmanaged) triggered by a sleep event happens after the wake, the devices becomes wrongly unmanaged and it's necessary to manually manage it again, or restart NM. During the wake event we should disconnect the device_sleep_cb() callback for all devices because we don't want to react to state changes anymore; in particular we don't need to detect when the device becomes disconnected to unmanage it. (cherry picked from commit fe2d93980bd5b61c55a8b65a55f7aad35042e691) (cherry picked from commit 971897195a8218cb0ec08ae95a7210fce73f0b03) (cherry picked from commit 7913275b02c60803f21609168f9c16d2f2a4be2f) (cherry picked from commit 6d0e8a2acfa6b7b6a2af1834d8873fc18fc2c55a) --- src/nm-manager.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/nm-manager.c b/src/nm-manager.c index 96ca4e2abe..3c2df3d38a 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -5950,8 +5950,9 @@ do_sleep_wake (NMManager *self, gboolean sleeping_changed) } else { _LOGD (LOGD_SUSPEND, "sleep: %s...", waking_from_suspend ? "waking up" : "re-enabling"); + sleep_devices_clear (self); + if (waking_from_suspend) { - sleep_devices_clear (self); c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) { if (nm_device_is_software (device)) continue; From 70c642325f90f767954aa86079b1bc6a4946f15f Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Thu, 16 Jul 2020 11:58:20 +0200 Subject: [PATCH 2/2] policy: block connection from autoconnect in case of failed dependency A connection that fails due to dependency-failed is not able to reconnect until the master connection activates again; when this happens, the master clears the blocked reason for all its slaves in activate_slave_connections() and tries to reconnect them. For this to work, the slave should be marked as blocked when it fails with dependency-failed. (cherry picked from commit 725fed01cf7c8508cf426897340b2a4113406aab) (cherry picked from commit e1755048e35aca682c7d0d233122d4ddaf3bb089) (cherry picked from commit ecb134ac349a0bf6582833253b6d453d6bf997de) (cherry picked from commit bb4781cc581a3c9fcefbfc1ea0be5e95aa3e287b) --- src/nm-policy.c | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/src/nm-policy.c b/src/nm-policy.c index 559babed3a..9f4fe668a3 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -1806,7 +1806,7 @@ device_state_changed (NMDevice *device, if ( sett_conn && old_state >= NM_DEVICE_STATE_PREPARE && old_state <= NM_DEVICE_STATE_ACTIVATED) { - gboolean block_no_secrets = FALSE; + gboolean blocked = FALSE; int tries; guint64 con_v; @@ -1826,15 +1826,32 @@ device_state_changed (NMDevice *device, */ con_v = nm_settings_connection_get_last_secret_agent_version_id (sett_conn); if ( con_v == 0 - || con_v == nm_agent_manager_get_agent_version_id (priv->agent_mgr)) - block_no_secrets = TRUE; + || con_v == nm_agent_manager_get_agent_version_id (priv->agent_mgr)) { + _LOGD (LOGD_DEVICE, "connection '%s' now blocked from autoconnect due to no secrets", + nm_settings_connection_get_id (sett_conn)); + nm_settings_connection_autoconnect_blocked_reason_set (sett_conn, + NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS, + TRUE); + blocked = TRUE; + } + } else if (nm_device_state_reason_check (reason) == NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED) { + /* A connection that fails due to dependency-failed is not + * able to reconnect until the master connection activates + * again; when this happens, the master clears the blocked + * reason for all its slaves in activate_slave_connections() + * and tries to reconnect them. For this to work, the slave + * should be marked as blocked when it fails with + * dependency-failed. + */ + _LOGD (LOGD_DEVICE, "connection '%s' now blocked from autoconnect due to failed dependency", + nm_settings_connection_get_id (sett_conn)); + nm_settings_connection_autoconnect_blocked_reason_set (sett_conn, + NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED, + TRUE); + blocked = TRUE; } - if (block_no_secrets) { - _LOGD (LOGD_DEVICE, "connection '%s' now blocked from autoconnect due to no secrets", - nm_settings_connection_get_id (sett_conn)); - nm_settings_connection_autoconnect_blocked_reason_set (sett_conn, NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS, TRUE); - } else { + if (!blocked) { tries = nm_settings_connection_autoconnect_retries_get (sett_conn); if (tries > 0) { _LOGD (LOGD_DEVICE, "connection '%s' failed to autoconnect; %d tries left",