summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2023-04-27 09:02:12 +0200
committerThomas Haller <thaller@redhat.com>2023-04-27 09:02:12 +0200
commitc07146bd0e9d1c4959697ccb332f423775889493 (patch)
treeb889f765f0e949c577692fd57a56ac57c17abbcb
parente66b93b01e23a57090550b28eb5e34c88886fcbd (diff)
parentb48c31432864f4e075f74b2e68710404d8c74049 (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.c83
-rw-r--r--src/core/devices/nm-device.h8
-rw-r--r--src/core/devices/ovs/nm-device-ovs-interface.c2
-rw-r--r--src/core/devices/wifi/nm-device-iwd.c10
-rw-r--r--src/core/devices/wifi/nm-device-olpc-mesh.c2
-rw-r--r--src/core/devices/wifi/nm-device-wifi.c4
-rw-r--r--src/core/nm-manager.c20
-rw-r--r--src/core/nm-manager.h4
-rw-r--r--src/core/nm-policy.c207
-rw-r--r--src/core/nm-policy.h2
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.