core: merge branch 'th/auto-activate-rework'

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1597

(cherry picked from commit c07146bd0e)
This commit is contained in:
Thomas Haller 2023-04-27 09:02:12 +02:00
commit c965896038
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
10 changed files with 159 additions and 183 deletions

View file

@ -131,11 +131,6 @@ typedef struct {
bool configure;
} SlaveInfo;
typedef struct {
NMDevice *device;
guint idle_add_id;
} DeleteOnDeactivateData;
typedef struct {
NMDevice *device;
GCancellable *cancellable;
@ -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;
@ -6444,7 +6438,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) {
@ -6768,7 +6762,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) {
@ -7703,7 +7697,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;
}
@ -7725,7 +7719,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);
}
/**
@ -8335,7 +8329,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
@ -9081,9 +9075,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
@ -12614,24 +12608,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
@ -12639,25 +12633,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;
@ -12671,14 +12656,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
@ -17768,6 +17750,7 @@ nm_device_init(NMDevice *self)
c_list_init(&priv->concheck_lst_head);
c_list_init(&self->devices_lst);
c_list_init(&self->policy_auto_activate_lst);
c_list_init(&priv->slaves);
priv->ipdhcp_data_6.v6.mode = NM_NDISC_DHCP_LEVEL_NONE;
@ -17888,6 +17871,8 @@ dispose(GObject *object)
_LOGD(LOGD_DEVICE, "disposing");
nm_assert(c_list_is_empty(&self->devices_lst));
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,
@ -18550,16 +18535,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,

View file

@ -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"
@ -144,6 +143,9 @@ struct _NMDevice {
NMDBusObject parent;
struct _NMDevicePrivate *_priv;
CList devices_lst;
CList policy_auto_activate_lst;
GSource *policy_auto_activate_idle_source;
};
/* The flags have an relaxing meaning, that means, specifying more flags, can make
@ -294,7 +296,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);
@ -705,7 +707,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);

View file

@ -479,7 +479,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

View file

@ -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));
}
@ -1682,7 +1682,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);
@ -2908,7 +2908,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);
}
}

View file

@ -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

View file

@ -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));
}

View file

@ -2666,6 +2666,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)
{
@ -3449,7 +3459,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);
}
/**
@ -7963,6 +7973,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)
{

View file

@ -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);
@ -121,6 +123,8 @@ NMSettingsConnection **nm_manager_get_activatable_connections(NMManager *manager
gboolean sort,
guint *out_len);
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);

View file

@ -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)
{
@ -1332,7 +1314,8 @@ pending_ac_state_changed(NMActiveConnection *ac, guint state, guint reason, NMPo
con,
NM_SETTINGS_AUTO_CONNECT_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 */
@ -1345,7 +1328,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;
@ -1439,7 +1422,7 @@ auto_activate_device(NMPolicy *self, NMDevice *device)
best_connection,
NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED,
TRUE);
schedule_activate_check(self, device);
nm_policy_device_recheck_auto_activate_schedule(self, device);
return;
}
@ -1456,32 +1439,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;
}
/*****************************************************************************/
@ -1683,23 +1667,37 @@ 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;
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;
}
priv = NM_POLICY_GET_PRIVATE(self);
if (nm_manager_get_state(priv->manager) == NM_STATE_ASLEEP)
return;
if (!nm_device_autoconnect_allowed(device))
return;
if (find_pending_activation(self, device))
return;
nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) {
if (nm_active_connection_get_device(ac) == device) {
if (nm_device_sys_iface_state_is_external(device)
@ -1712,11 +1710,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
@ -1729,7 +1724,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();
@ -1749,15 +1744,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
@ -1772,15 +1768,15 @@ _connection_autoconnect_retries_set(NMPolicy *self, NMSettingsConnection *connec
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_settings_connection_autoconnect_retries_blocked_until(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);
}
}
}
@ -1853,7 +1849,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
@ -2126,7 +2122,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:
@ -2248,16 +2244,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
@ -2292,10 +2279,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
@ -2319,16 +2302,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);
@ -2508,39 +2488,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
@ -2608,7 +2592,7 @@ connection_updated(NMSettings *settings,
}
}
schedule_activate_all(self);
nm_policy_device_recheck_auto_activate_all_schedule(self);
}
static void
@ -2657,7 +2641,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);
}
}
@ -2671,7 +2655,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 *
@ -2765,7 +2749,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());
@ -2901,9 +2885,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);
@ -2911,9 +2895,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;
@ -2932,20 +2913,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);

View file

@ -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.