diff options
author | Thomas Haller <thaller@redhat.com> | 2023-04-27 09:02:12 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2023-04-27 09:02:12 +0200 |
commit | c07146bd0e9d1c4959697ccb332f423775889493 (patch) | |
tree | b889f765f0e949c577692fd57a56ac57c17abbcb | |
parent | e66b93b01e23a57090550b28eb5e34c88886fcbd (diff) | |
parent | b48c31432864f4e075f74b2e68710404d8c74049 (diff) |
core: merge branch 'th/auto-activate-rework'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1597
-rw-r--r-- | src/core/devices/nm-device.c | 83 | ||||
-rw-r--r-- | src/core/devices/nm-device.h | 8 | ||||
-rw-r--r-- | src/core/devices/ovs/nm-device-ovs-interface.c | 2 | ||||
-rw-r--r-- | src/core/devices/wifi/nm-device-iwd.c | 10 | ||||
-rw-r--r-- | src/core/devices/wifi/nm-device-olpc-mesh.c | 2 | ||||
-rw-r--r-- | src/core/devices/wifi/nm-device-wifi.c | 4 | ||||
-rw-r--r-- | src/core/nm-manager.c | 20 | ||||
-rw-r--r-- | src/core/nm-manager.h | 4 | ||||
-rw-r--r-- | src/core/nm-policy.c | 207 | ||||
-rw-r--r-- | src/core/nm-policy.h | 2 |
10 files changed, 159 insertions, 183 deletions
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c index c69bb44804..c7d9f9d89b 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -132,11 +132,6 @@ typedef struct { } SlaveInfo; typedef struct { - NMDevice *device; - guint idle_add_id; -} DeleteOnDeactivateData; - -typedef struct { NMDevice *device; GCancellable *cancellable; NMPlatformAsyncCallback callback; @@ -335,7 +330,6 @@ enum { IP6_PREFIX_DELEGATED, IP6_SUBNET_NEEDED, REMOVED, - RECHECK_AUTO_ACTIVATE, RECHECK_ASSUME, DNS_LOOKUP_DONE, PLATFORM_ADDRESS_CHANGED, @@ -513,8 +507,8 @@ typedef struct _NMDevicePrivate { NMUnmanagedFlags unmanaged_mask; NMUnmanagedFlags unmanaged_flags; - DeleteOnDeactivateData - *delete_on_deactivate_data; /* data for scheduled cleanup when deleting link (g_idle_add) */ + + GSource *delete_on_deactivate_idle_source; GCancellable *deactivating_cancellable; @@ -6606,7 +6600,7 @@ carrier_changed(NMDevice *self, gboolean carrier) * when the carrier appears, auto connections are rechecked for * the device. */ - nm_device_emit_recheck_auto_activate(self); + nm_device_recheck_auto_activate_schedule(self); } } else { if (priv->state == NM_DEVICE_STATE_UNAVAILABLE) { @@ -6930,7 +6924,7 @@ device_link_changed(gpointer user_data) /* Let any connections that use the new interface name have a chance * to auto-activate on the device. */ - nm_device_emit_recheck_auto_activate(self); + nm_device_recheck_auto_activate_schedule(self); } if (priv->ipac6_data.ndisc && pllink->inet6_token.id) { @@ -7862,7 +7856,7 @@ nm_device_unrealize(NMDevice *self, gboolean remove_resources, GError **error) /* In case the unrealized device is not going away, it may need to * autoactivate. Schedule also a check for that. */ - nm_device_emit_recheck_auto_activate(self); + nm_device_recheck_auto_activate_schedule(self); return TRUE; } @@ -7884,7 +7878,7 @@ nm_device_notify_availability_maybe_changed(NMDevice *self) * available. */ nm_device_recheck_available_connections(self); if (g_hash_table_size(priv->available_connections) > 0) - nm_device_emit_recheck_auto_activate(self); + nm_device_recheck_auto_activate_schedule(self); } /** @@ -8494,7 +8488,7 @@ nm_device_autoconnect_allowed(NMDevice *self) return FALSE; } - if (priv->delete_on_deactivate_data) + if (priv->delete_on_deactivate_idle_source) return FALSE; /* The 'autoconnect-allowed' signal is emitted on a device to allow @@ -9249,9 +9243,9 @@ nm_device_queue_recheck_available(NMDevice *self, } void -nm_device_emit_recheck_auto_activate(NMDevice *self) +nm_device_recheck_auto_activate_schedule(NMDevice *self) { - g_signal_emit(self, signals[RECHECK_AUTO_ACTIVATE], 0); + nm_manager_device_recheck_auto_activate_schedule(nm_device_get_manager(self), self); } void @@ -12774,24 +12768,24 @@ nm_device_is_nm_owned(NMDevice *self) static gboolean delete_on_deactivate_link_delete(gpointer user_data) { - DeleteOnDeactivateData *data = user_data; - nm_auto_unref_object NMDevice *self = data->device; + nm_auto_unref_object NMDevice *self = user_data; NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); gs_free_error GError *error = NULL; - _LOGD(LOGD_DEVICE, - "delete_on_deactivate: cleanup and delete virtual link (id=%u)", - data->idle_add_id); + _LOGD(LOGD_DEVICE, "delete_on_deactivate: cleanup and delete virtual link"); - priv->delete_on_deactivate_data = NULL; + nm_clear_g_source_inst(&priv->delete_on_deactivate_idle_source); if (!nm_device_unrealize(self, TRUE, &error)) _LOGD(LOGD_DEVICE, "delete_on_deactivate: unrealizing failed (%s)", error->message); - nm_device_emit_recheck_auto_activate(self); + if (nm_dbus_object_is_exported(NM_DBUS_OBJECT(self))) { + /* The device is still alive. We may need to autoactivate virtual + * devices again. */ + nm_device_recheck_auto_activate_schedule(self); + } - g_free(data); - return FALSE; + return G_SOURCE_CONTINUE; } static void @@ -12799,25 +12793,16 @@ delete_on_deactivate_unschedule(NMDevice *self) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - if (priv->delete_on_deactivate_data) { - DeleteOnDeactivateData *data = priv->delete_on_deactivate_data; - - priv->delete_on_deactivate_data = NULL; - - g_source_remove(data->idle_add_id); - _LOGD(LOGD_DEVICE, - "delete_on_deactivate: cancel cleanup and delete virtual link (id=%u)", - data->idle_add_id); - g_object_unref(data->device); - g_free(data); + if (nm_clear_g_source_inst(&priv->delete_on_deactivate_idle_source)) { + _LOGD(LOGD_DEVICE, "delete_on_deactivate: cancel cleanup and delete virtual link"); + g_object_unref(self); } } static void delete_on_deactivate_check_and_schedule(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - DeleteOnDeactivateData *data; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); if (!priv->nm_owned) return; @@ -12831,14 +12816,11 @@ delete_on_deactivate_check_and_schedule(NMDevice *self) return; delete_on_deactivate_unschedule(self); /* always cancel and reschedule */ - data = g_new(DeleteOnDeactivateData, 1); - data->device = g_object_ref(self); - data->idle_add_id = g_idle_add(delete_on_deactivate_link_delete, data); - priv->delete_on_deactivate_data = data; + g_object_ref(self); + priv->delete_on_deactivate_idle_source = + nm_g_idle_add_source(delete_on_deactivate_link_delete, self); - _LOGD(LOGD_DEVICE, - "delete_on_deactivate: schedule cleanup and delete virtual link (id=%u)", - data->idle_add_id); + _LOGD(LOGD_DEVICE, "delete_on_deactivate: schedule cleanup and delete virtual link"); } static void @@ -17942,6 +17924,7 @@ nm_device_init(NMDevice *self) c_list_init(&priv->concheck_lst_head); c_list_init(&self->devices_lst); c_list_init(&self->devcon_dev_lst_head); + c_list_init(&self->policy_auto_activate_lst); c_list_init(&priv->slaves); priv->ipdhcp_data_6.v6.mode = NM_NDISC_DHCP_LEVEL_NONE; @@ -18063,6 +18046,8 @@ dispose(GObject *object) nm_assert(c_list_is_empty(&self->devices_lst)); nm_assert(c_list_is_empty(&self->devcon_dev_lst_head)); + nm_assert(c_list_is_empty(&self->policy_auto_activate_lst)); + nm_assert(!self->policy_auto_activate_idle_source); while ((con_handle = c_list_first_entry(&priv->concheck_lst_head, NMDeviceConnectivityHandle, @@ -18725,16 +18710,6 @@ nm_device_class_init(NMDeviceClass *klass) G_TYPE_NONE, 0); - signals[RECHECK_AUTO_ACTIVATE] = g_signal_new(NM_DEVICE_RECHECK_AUTO_ACTIVATE, - G_OBJECT_CLASS_TYPE(object_class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, - NULL, - NULL, - G_TYPE_NONE, - 0); - signals[RECHECK_ASSUME] = g_signal_new(NM_DEVICE_RECHECK_ASSUME, G_OBJECT_CLASS_TYPE(object_class), G_SIGNAL_RUN_FIRST, diff --git a/src/core/devices/nm-device.h b/src/core/devices/nm-device.h index 4794d9af87..d32b77dc83 100644 --- a/src/core/devices/nm-device.h +++ b/src/core/devices/nm-device.h @@ -75,7 +75,6 @@ #define NM_DEVICE_IP6_PREFIX_DELEGATED "ip6-prefix-delegated" #define NM_DEVICE_IP6_SUBNET_NEEDED "ip6-subnet-needed" #define NM_DEVICE_REMOVED "removed" -#define NM_DEVICE_RECHECK_AUTO_ACTIVATE "recheck-auto-activate" #define NM_DEVICE_RECHECK_ASSUME "recheck-assume" #define NM_DEVICE_STATE_CHANGED "state-changed" #define NM_DEVICE_LINK_INITIALIZED "link-initialized" @@ -145,6 +144,9 @@ struct _NMDevice { struct _NMDevicePrivate *_priv; CList devices_lst; CList devcon_dev_lst_head; + + CList policy_auto_activate_lst; + GSource *policy_auto_activate_idle_source; }; /* The flags have an relaxing meaning, that means, specifying more flags, can make @@ -295,7 +297,7 @@ typedef struct _NMDeviceClass { GPtrArray *(*get_extra_rules)(NMDevice *self); /* allow derived classes to override the result of nm_device_autoconnect_allowed(). - * If the value changes, the class should call nm_device_emit_recheck_auto_activate(), + * If the value changes, the class should call nm_device_recheck_auto_activate_schedule(), * which emits NM_DEVICE_RECHECK_AUTO_ACTIVATE signal. */ gboolean (*get_autoconnect_allowed)(NMDevice *self); @@ -717,7 +719,7 @@ nm_device_autoconnect_blocked_unset(NMDevice *device, NMDeviceAutoconnectBlocked nm_device_autoconnect_blocked_set_full(device, mask, NM_DEVICE_AUTOCONNECT_BLOCKED_NONE); } -void nm_device_emit_recheck_auto_activate(NMDevice *device); +void nm_device_recheck_auto_activate_schedule(NMDevice *device); NMDeviceSysIfaceState nm_device_sys_iface_state_get(NMDevice *device); diff --git a/src/core/devices/ovs/nm-device-ovs-interface.c b/src/core/devices/ovs/nm-device-ovs-interface.c index 41bcffa16d..fd48c2fd0f 100644 --- a/src/core/devices/ovs/nm-device-ovs-interface.c +++ b/src/core/devices/ovs/nm-device-ovs-interface.c @@ -486,7 +486,7 @@ ovsdb_ready(NMOvsdb *ovsdb, NMDeviceOvsInterface *self) NM_DEVICE_STATE_REASON_NONE, NM_DEVICE_STATE_REASON_NONE); nm_device_recheck_available_connections(device); - nm_device_emit_recheck_auto_activate(device); + nm_device_recheck_auto_activate_schedule(device); } static void diff --git a/src/core/devices/wifi/nm-device-iwd.c b/src/core/devices/wifi/nm-device-iwd.c index 74e75f7216..12a827fde3 100644 --- a/src/core/devices/wifi/nm-device-iwd.c +++ b/src/core/devices/wifi/nm-device-iwd.c @@ -159,7 +159,7 @@ ap_add_remove(NMDeviceIwd *self, } if (priv->enabled && !priv->iwd_autoconnect) - nm_device_emit_recheck_auto_activate(NM_DEVICE(self)); + nm_device_recheck_auto_activate_schedule(NM_DEVICE(self)); if (recheck_available_connections) nm_device_recheck_available_connections(NM_DEVICE(self)); @@ -208,7 +208,7 @@ remove_all_aps(NMDeviceIwd *self) ap_add_remove(self, FALSE, ap, FALSE); if (!priv->iwd_autoconnect) - nm_device_emit_recheck_auto_activate(NM_DEVICE(self)); + nm_device_recheck_auto_activate_schedule(NM_DEVICE(self)); nm_device_recheck_available_connections(NM_DEVICE(self)); } @@ -401,7 +401,7 @@ get_ordered_networks_cb(GObject *source, GAsyncResult *res, gpointer user_data) if (changed) { if (!priv->iwd_autoconnect) - nm_device_emit_recheck_auto_activate(NM_DEVICE(self)); + nm_device_recheck_auto_activate_schedule(NM_DEVICE(self)); nm_device_recheck_available_connections(NM_DEVICE(self)); } @@ -1685,7 +1685,7 @@ failed: if (!priv->nm_autoconnect) { priv->nm_autoconnect = true; - nm_device_emit_recheck_auto_activate(device); + nm_device_recheck_auto_activate_schedule(device); } } g_variant_unref(value); @@ -2912,7 +2912,7 @@ state_changed(NMDeviceIwd *self, const char *new_state) if (!priv->iwd_autoconnect && NM_IN_STRSET(new_state, "disconnected")) { priv->nm_autoconnect = TRUE; if (!can_connect) - nm_device_emit_recheck_auto_activate(device); + nm_device_recheck_auto_activate_schedule(device); } } diff --git a/src/core/devices/wifi/nm-device-olpc-mesh.c b/src/core/devices/wifi/nm-device-olpc-mesh.c index 4705f75ce3..436c7847ab 100644 --- a/src/core/devices/wifi/nm-device-olpc-mesh.c +++ b/src/core/devices/wifi/nm-device-olpc-mesh.c @@ -270,7 +270,7 @@ companion_state_changed_cb(NMDeviceWifi *companion, NMDeviceState self_state = nm_device_get_state(NM_DEVICE(self)); if (old_state > NM_DEVICE_STATE_DISCONNECTED && state <= NM_DEVICE_STATE_DISCONNECTED) { - nm_device_emit_recheck_auto_activate(NM_DEVICE(self)); + nm_device_recheck_auto_activate_schedule(NM_DEVICE(self)); } if (self_state < NM_DEVICE_STATE_PREPARE || self_state > NM_DEVICE_STATE_ACTIVATED diff --git a/src/core/devices/wifi/nm-device-wifi.c b/src/core/devices/wifi/nm-device-wifi.c index 91e0554499..40fdfa9041 100644 --- a/src/core/devices/wifi/nm-device-wifi.c +++ b/src/core/devices/wifi/nm-device-wifi.c @@ -483,7 +483,7 @@ _scan_notify_is_scanning(NMDeviceWifi *self) if (!_scan_is_scanning_eval(priv)) { if (state <= NM_DEVICE_STATE_DISCONNECTED || state > NM_DEVICE_STATE_ACTIVATED) - nm_device_emit_recheck_auto_activate(NM_DEVICE(self)); + nm_device_recheck_auto_activate_schedule(NM_DEVICE(self)); nm_device_remove_pending_action(NM_DEVICE(self), NM_PENDING_ACTION_WIFI_SCAN, FALSE); } @@ -843,7 +843,7 @@ ap_add_remove(NMDeviceWifi *self, nm_dbus_object_clear_and_unexport(&ap); } - nm_device_emit_recheck_auto_activate(NM_DEVICE(self)); + nm_device_recheck_auto_activate_schedule(NM_DEVICE(self)); if (recheck_available_connections) nm_device_recheck_available_connections(NM_DEVICE(self)); } diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c index f6902b9786..02dabaf6fe 100644 --- a/src/core/nm-manager.c +++ b/src/core/nm-manager.c @@ -3105,6 +3105,16 @@ _rfkill_update_from_user(NMManager *self, NMRfkillType rtype, gboolean enabled) /*****************************************************************************/ +void +nm_manager_device_recheck_auto_activate_schedule(NMManager *self, NMDevice *device) +{ + g_return_if_fail(NM_IS_MANAGER(self)); + + nm_policy_device_recheck_auto_activate_schedule(NM_MANAGER_GET_PRIVATE(self)->policy, device); +} + +/*****************************************************************************/ + static void device_auth_done_cb(NMAuthChain *chain, GDBusMethodInvocation *context, gpointer user_data) { @@ -3890,7 +3900,7 @@ _device_realize_finish(NMManager *self, NMDevice *device, const NMPlatformLink * nm_device_state_changed(device, NM_DEVICE_STATE_UNAVAILABLE, NM_DEVICE_STATE_REASON_NOW_MANAGED); - nm_device_emit_recheck_auto_activate(device); + nm_manager_device_recheck_auto_activate_schedule(self, device); } /** @@ -8453,6 +8463,14 @@ nm_settings_get(void) return NM_MANAGER_GET_PRIVATE(singleton_instance)->settings; } +NMPolicy * +nm_manager_get_policy(NMManager *self) +{ + g_return_val_if_fail(NM_IS_MANAGER(self), NULL); + + return NM_MANAGER_GET_PRIVATE(self)->policy; +} + NMManager * nm_manager_setup(void) { diff --git a/src/core/nm-manager.h b/src/core/nm-manager.h index fe78eb2687..caa83e4546 100644 --- a/src/core/nm-manager.h +++ b/src/core/nm-manager.h @@ -69,6 +69,8 @@ NMManager *nm_manager_setup(void); NMManager *nm_manager_get(void); #define NM_MANAGER_GET (nm_manager_get()) +NMPolicy *nm_manager_get_policy(NMManager *self); + gboolean nm_manager_start(NMManager *manager, GError **error); void nm_manager_stop(NMManager *manager); NMState nm_manager_get_state(NMManager *manager); @@ -123,6 +125,8 @@ NMSettingsConnection **nm_manager_get_activatable_connections(NMManager *manager void nm_manager_deactivate_ac(NMManager *self, NMSettingsConnection *connection); +void nm_manager_device_recheck_auto_activate_schedule(NMManager *self, NMDevice *device); + void nm_manager_write_device_state_all(NMManager *manager); gboolean nm_manager_write_device_state(NMManager *manager, NMDevice *device, int *out_ifindex); diff --git a/src/core/nm-policy.c b/src/core/nm-policy.c index b2ccb16478..9309026e56 100644 --- a/src/core/nm-policy.c +++ b/src/core/nm-policy.c @@ -51,7 +51,7 @@ typedef struct { NMManager *manager; NMNetns *netns; NMFirewalldManager *firewalld_manager; - CList pending_activation_checks; + CList policy_auto_activate_lst_head; NMAgentManager *agent_mgr; @@ -62,6 +62,10 @@ typedef struct { NMSettings *settings; + GSource *device_recheck_auto_activate_all_idle_source; + + GSource *reset_connections_retries_idle_source; + NMHostnameManager *hostname_manager; NMActiveConnection *default_ac4, *activating_ac4; @@ -70,10 +74,6 @@ typedef struct { NMDnsManager *dns_manager; gulong config_changed_id; - guint reset_retries_id; /* idle handler for resetting the retries count */ - - guint schedule_activate_all_id; /* idle handler for schedule_activate_all(). */ - NMPolicyHostnameMode hostname_mode; char *orig_hostname; /* hostname at NM start time */ char *cur_hostname; /* hostname we want to assign */ @@ -135,8 +135,7 @@ _PRIV_TO_SELF(NMPolicyPrivate *priv) /*****************************************************************************/ static void update_system_hostname(NMPolicy *self, const char *msg); -static void schedule_activate_all(NMPolicy *self); -static void schedule_activate_check(NMPolicy *self, NMDevice *device); +static void nm_policy_device_recheck_auto_activate_all_schedule(NMPolicy *self); static NMDevice *get_default_device(NMPolicy *self, int addr_family); /*****************************************************************************/ @@ -1283,23 +1282,6 @@ check_activating_active_connections(NMPolicy *self) g_object_thaw_notify(G_OBJECT(self)); } -typedef struct { - CList pending_lst; - NMPolicy *policy; - NMDevice *device; - guint autoactivate_id; -} ActivateData; - -static void -activate_data_free(ActivateData *data) -{ - nm_device_remove_pending_action(data->device, NM_PENDING_ACTION_AUTOACTIVATE, TRUE); - c_list_unlink_stale(&data->pending_lst); - nm_clear_g_source(&data->autoactivate_id); - g_object_unref(data->device); - g_slice_free(ActivateData, data); -} - static void pending_ac_gone(gpointer data, GObject *where_the_object_was) { @@ -1335,7 +1317,8 @@ pending_ac_state_changed(NMActiveConnection *ac, guint state, guint reason, NMPo con, NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_FAILED, TRUE); - schedule_activate_check(self, nm_active_connection_get_device(ac)); + nm_policy_device_recheck_auto_activate_schedule(self, + nm_active_connection_get_device(ac)); } /* Cleanup */ @@ -1348,7 +1331,7 @@ pending_ac_state_changed(NMActiveConnection *ac, guint state, guint reason, NMPo } static void -auto_activate_device(NMPolicy *self, NMDevice *device) +_auto_activate_device(NMPolicy *self, NMDevice *device) { NMPolicyPrivate *priv; NMSettingsConnection *best_connection; @@ -1444,7 +1427,7 @@ auto_activate_device(NMPolicy *self, NMDevice *device) best_connection, NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_FAILED, TRUE); - schedule_activate_check(self, device); + nm_policy_device_recheck_auto_activate_schedule(self, device); return; } @@ -1461,32 +1444,33 @@ auto_activate_device(NMPolicy *self, NMDevice *device) } } -static gboolean -auto_activate_device_cb(gpointer user_data) +static void +_auto_activate_device_clear(NMPolicy *self, NMDevice *device, gboolean do_activate) { - ActivateData *data = user_data; + nm_assert(NM_IS_DEVICE(device)); + nm_assert(NM_IS_POLICY(self)); + nm_assert(c_list_is_linked(&device->policy_auto_activate_lst)); + nm_assert(c_list_contains(&NM_POLICY_GET_PRIVATE(self)->policy_auto_activate_lst_head, + &device->policy_auto_activate_lst)); - g_assert(data); - g_assert(NM_IS_POLICY(data->policy)); - g_assert(NM_IS_DEVICE(data->device)); + c_list_unlink(&device->policy_auto_activate_lst); + nm_clear_g_source_inst(&device->policy_auto_activate_idle_source); - data->autoactivate_id = 0; - auto_activate_device(data->policy, data->device); - activate_data_free(data); - return G_SOURCE_REMOVE; + if (do_activate) + _auto_activate_device(self, device); + + nm_device_remove_pending_action(device, NM_PENDING_ACTION_AUTOACTIVATE, TRUE); } -static ActivateData * -find_pending_activation(NMPolicy *self, NMDevice *device) +static gboolean +_auto_activate_idle_cb(gpointer user_data) { - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); - ActivateData *data; + NMDevice *device = user_data; - c_list_for_each_entry (data, &priv->pending_activation_checks, pending_lst) { - if (data->device == device) - return data; - } - return NULL; + nm_assert(NM_IS_DEVICE(device)); + + _auto_activate_device_clear(nm_manager_get_policy(nm_device_get_manager(device)), device, TRUE); + return G_SOURCE_CONTINUE; } /*****************************************************************************/ @@ -1669,21 +1653,35 @@ sleeping_changed(NMManager *manager, GParamSpec *pspec, gpointer user_data) reset_autoconnect_all(self, NULL, FALSE); } -static void -schedule_activate_check(NMPolicy *self, NMDevice *device) +void +nm_policy_device_recheck_auto_activate_schedule(NMPolicy *self, NMDevice *device) { - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); - ActivateData *data; + NMPolicyPrivate *priv; NMActiveConnection *ac; const CList *tmp_list; - if (nm_manager_get_state(priv->manager) == NM_STATE_ASLEEP) + g_return_if_fail(NM_IS_POLICY(self)); + g_return_if_fail(NM_IS_DEVICE(device)); + nm_assert(g_signal_handler_find(device, + G_SIGNAL_MATCH_DATA, + 0, + 0, + NULL, + NULL, + NM_POLICY_GET_PRIVATE(self)) + != 0); + + if (!c_list_is_empty(&device->policy_auto_activate_lst)) { + /* already queued. Return. */ return; + } - if (!nm_device_autoconnect_allowed(device)) + priv = NM_POLICY_GET_PRIVATE(self); + + if (nm_manager_get_state(priv->manager) == NM_STATE_ASLEEP) return; - if (find_pending_activation(self, device)) + if (!nm_device_autoconnect_allowed(device)) return; nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) { @@ -1698,11 +1696,8 @@ schedule_activate_check(NMPolicy *self, NMDevice *device) nm_device_add_pending_action(device, NM_PENDING_ACTION_AUTOACTIVATE, TRUE); - data = g_slice_new0(ActivateData); - data->policy = self; - data->device = g_object_ref(device); - data->autoactivate_id = g_idle_add(auto_activate_device_cb, data); - c_list_link_tail(&priv->pending_activation_checks, &data->pending_lst); + c_list_link_tail(&priv->policy_auto_activate_lst_head, &device->policy_auto_activate_lst); + device->policy_auto_activate_idle_source = nm_g_idle_add_source(_auto_activate_idle_cb, device); } static gboolean @@ -1715,7 +1710,7 @@ reset_connections_retries(gpointer user_data) gint32 con_stamp, min_stamp, now; gboolean changed = FALSE; - priv->reset_retries_id = 0; + nm_clear_g_source_inst(&priv->reset_connections_retries_idle_source); min_stamp = 0; now = nm_utils_get_monotonic_timestamp_sec(); @@ -1736,15 +1731,16 @@ reset_connections_retries(gpointer user_data) } /* Schedule the handler again if there are some stamps left */ - if (min_stamp != 0) - priv->reset_retries_id = - g_timeout_add_seconds(min_stamp - now, reset_connections_retries, self); + if (min_stamp != 0) { + priv->reset_connections_retries_idle_source = + nm_g_timeout_add_seconds_source(min_stamp - now, reset_connections_retries, self); + } /* If anything changed, try to activate the newly re-enabled connections */ if (changed) - schedule_activate_all(self); + nm_policy_device_recheck_auto_activate_all_schedule(self); - return FALSE; + return G_SOURCE_CONTINUE; } static void @@ -1761,16 +1757,16 @@ _connection_autoconnect_retries_set(NMPolicy *self, if (tries == 0) { /* Schedule a handler to reset retries count */ - if (!priv->reset_retries_id) { + if (!priv->reset_connections_retries_idle_source) { gint32 retry_time = nm_manager_devcon_autoconnect_retries_blocked_until(priv->manager, device, connection); g_warn_if_fail(retry_time != 0); - priv->reset_retries_id = - g_timeout_add_seconds(MAX(0, retry_time - nm_utils_get_monotonic_timestamp_sec()), - reset_connections_retries, - self); + priv->reset_connections_retries_idle_source = nm_g_timeout_add_seconds_source( + MAX(0, retry_time - nm_utils_get_monotonic_timestamp_sec()), + reset_connections_retries, + self); } } } @@ -1846,7 +1842,7 @@ activate_slave_connections(NMPolicy *self, NMDevice *device) } if (changed) - schedule_activate_all(self); + nm_policy_device_recheck_auto_activate_all_schedule(self); } static gboolean @@ -2138,7 +2134,7 @@ device_state_changed(NMDevice *device, update_routing_and_dns(self, FALSE, device); /* Device is now available for auto-activation */ - schedule_activate_check(self, device); + nm_policy_device_recheck_auto_activate_schedule(self, device); break; case NM_DEVICE_STATE_PREPARE: @@ -2262,16 +2258,7 @@ device_autoconnect_changed(NMDevice *device, GParamSpec *pspec, gpointer user_da NMPolicyPrivate *priv = user_data; NMPolicy *self = _PRIV_TO_SELF(priv); - schedule_activate_check(self, device); -} - -static void -device_recheck_auto_activate(NMDevice *device, gpointer user_data) -{ - NMPolicyPrivate *priv = user_data; - NMPolicy *self = _PRIV_TO_SELF(priv); - - schedule_activate_check(self, device); + nm_policy_device_recheck_auto_activate_schedule(self, device); } static void @@ -2306,10 +2293,6 @@ devices_list_register(NMPolicy *self, NMDevice *device) "notify::" NM_DEVICE_AUTOCONNECT, G_CALLBACK(device_autoconnect_changed), priv); - g_signal_connect(device, - NM_DEVICE_RECHECK_AUTO_ACTIVATE, - G_CALLBACK(device_recheck_auto_activate), - priv); } static void @@ -2333,16 +2316,13 @@ device_removed(NMManager *manager, NMDevice *device, gpointer user_data) { NMPolicyPrivate *priv = user_data; NMPolicy *self = _PRIV_TO_SELF(priv); - ActivateData *data; /* TODO: is this needed? The delegations are cleaned up * on transition to deactivated too. */ ip6_remove_device_prefix_delegations(self, device); - /* Clear any idle callbacks for this device */ - data = find_pending_activation(self, device); - if (data && data->autoactivate_id) - activate_data_free(data); + if (c_list_is_linked(&device->policy_auto_activate_lst)) + _auto_activate_device_clear(self, device, FALSE); if (g_hash_table_remove(priv->devices, device)) devices_list_unregister(self, device); @@ -2522,39 +2502,43 @@ active_connection_removed(NMManager *manager, NMActiveConnection *active, gpoint /*****************************************************************************/ static gboolean -schedule_activate_all_cb(gpointer user_data) +_device_recheck_auto_activate_all_cb(gpointer user_data) { NMPolicy *self = user_data; NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); const CList *tmp_lst; NMDevice *device; - priv->schedule_activate_all_id = 0; + nm_clear_g_source_inst(&priv->device_recheck_auto_activate_all_idle_source); nm_manager_for_each_device (priv->manager, device, tmp_lst) - schedule_activate_check(self, device); + nm_policy_device_recheck_auto_activate_schedule(self, device); - return G_SOURCE_REMOVE; + return G_SOURCE_CONTINUE; } static void -schedule_activate_all(NMPolicy *self) +nm_policy_device_recheck_auto_activate_all_schedule(NMPolicy *self) { NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); /* always restart the idle handler. That way, we settle * all other events before restarting to activate them. */ - nm_clear_g_source(&priv->schedule_activate_all_id); - priv->schedule_activate_all_id = g_idle_add(schedule_activate_all_cb, self); + nm_clear_g_source_inst(&priv->device_recheck_auto_activate_all_idle_source); + + priv->device_recheck_auto_activate_all_idle_source = + nm_g_idle_add_source(_device_recheck_auto_activate_all_cb, self); } +/*****************************************************************************/ + static void connection_added(NMSettings *settings, NMSettingsConnection *connection, gpointer user_data) { NMPolicyPrivate *priv = user_data; NMPolicy *self = _PRIV_TO_SELF(priv); - schedule_activate_all(self); + nm_policy_device_recheck_auto_activate_all_schedule(self); } static void @@ -2622,7 +2606,7 @@ connection_updated(NMSettings *settings, } } - schedule_activate_all(self); + nm_policy_device_recheck_auto_activate_all_schedule(self); } static void @@ -2642,7 +2626,7 @@ connection_flags_changed(NMSettings *settings, NMSettingsConnection *connection, if (NM_FLAGS_HAS(nm_settings_connection_get_flags(connection), NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE)) { if (!nm_settings_connection_autoconnect_is_blocked(connection)) - schedule_activate_all(self); + nm_policy_device_recheck_auto_activate_all_schedule(self); } } @@ -2656,7 +2640,7 @@ secret_agent_registered(NMSettings *settings, NMSecretAgent *agent, gpointer use * connections failed due to missing secrets may re-try auto-connection. */ if (reset_autoconnect_all(self, NULL, TRUE)) - schedule_activate_all(self); + nm_policy_device_recheck_auto_activate_all_schedule(self); } NMActiveConnection * @@ -2750,7 +2734,7 @@ nm_policy_init(NMPolicy *self) NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); gs_free char *hostname_mode = NULL; - c_list_init(&priv->pending_activation_checks); + c_list_init(&priv->policy_auto_activate_lst_head); priv->netns = g_object_ref(nm_netns_get()); @@ -2886,9 +2870,9 @@ dispose(GObject *object) { NMPolicy *self = NM_POLICY(object); NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); - GHashTableIter h_iter; - NMDevice *device; - ActivateData *data, *data_safe; + + nm_assert(!c_list_is_empty(&priv->policy_auto_activate_lst_head)); + nm_assert(g_hash_table_size(priv->devices) == 0); nm_clear_g_object(&priv->default_ac4); nm_clear_g_object(&priv->default_ac6); @@ -2896,9 +2880,6 @@ dispose(GObject *object) nm_clear_g_object(&priv->activating_ac6); nm_clear_pointer(&priv->pending_active_connections, g_hash_table_unref); - c_list_for_each_entry_safe (data, data_safe, &priv->pending_activation_checks, pending_lst) - activate_data_free(data); - g_slist_free_full(priv->pending_secondaries, (GDestroyNotify) pending_secondary_data_free); priv->pending_secondaries = NULL; @@ -2917,20 +2898,14 @@ dispose(GObject *object) g_clear_object(&priv->dns_manager); } - g_hash_table_iter_init(&h_iter, priv->devices); - while (g_hash_table_iter_next(&h_iter, (gpointer *) &device, NULL)) { - g_hash_table_iter_remove(&h_iter); - devices_list_unregister(self, device); - } - /* The manager should have disposed of ActiveConnections already, which * will have called active_connection_removed() and thus we don't need * to clean anything up. Assert that this is TRUE. */ nm_assert(c_list_is_empty(nm_manager_get_active_connections(priv->manager))); - nm_clear_g_source(&priv->reset_retries_id); - nm_clear_g_source(&priv->schedule_activate_all_id); + nm_clear_g_source_inst(&priv->reset_connections_retries_idle_source); + nm_clear_g_source_inst(&priv->device_recheck_auto_activate_all_idle_source); nm_clear_g_free(&priv->orig_hostname); nm_clear_g_free(&priv->cur_hostname); diff --git a/src/core/nm-policy.h b/src/core/nm-policy.h index f2b98dbd34..9cfb0b2448 100644 --- a/src/core/nm-policy.h +++ b/src/core/nm-policy.h @@ -34,6 +34,8 @@ NMActiveConnection *nm_policy_get_activating_ip6_ac(NMPolicy *policy); void nm_policy_unblock_failed_ovs_interfaces(NMPolicy *self); +void nm_policy_device_recheck_auto_activate_schedule(NMPolicy *self, NMDevice *device); + /** * NMPolicyHostnameMode * @NM_POLICY_HOSTNAME_MODE_NONE: never update the transient hostname. |