core: merge branch 'th/prune-device-state-files'
https://bugzilla.redhat.com/show_bug.cgi?id=1810153 https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/429
This commit is contained in:
@@ -2299,6 +2299,8 @@ _config_device_state_data_new (int ifindex, GKeyFile *kf)
|
|||||||
return device_state;
|
return device_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DEVICE_STATE_FILENAME_LEN_MAX 60
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nm_config_device_state_load:
|
* nm_config_device_state_load:
|
||||||
* @ifindex: the ifindex for which the state is to load
|
* @ifindex: the ifindex for which the state is to load
|
||||||
@@ -2310,7 +2312,7 @@ NMConfigDeviceStateData *
|
|||||||
nm_config_device_state_load (int ifindex)
|
nm_config_device_state_load (int ifindex)
|
||||||
{
|
{
|
||||||
NMConfigDeviceStateData *device_state;
|
NMConfigDeviceStateData *device_state;
|
||||||
char path[NM_STRLEN (NM_CONFIG_DEVICE_STATE_DIR) + 60];
|
char path[NM_STRLEN (NM_CONFIG_DEVICE_STATE_DIR"/") + DEVICE_STATE_FILENAME_LEN_MAX + 1];
|
||||||
gs_unref_keyfile GKeyFile *kf = NULL;
|
gs_unref_keyfile GKeyFile *kf = NULL;
|
||||||
const char *nm_owned_str;
|
const char *nm_owned_str;
|
||||||
|
|
||||||
@@ -2394,7 +2396,7 @@ nm_config_device_state_write (int ifindex,
|
|||||||
const char *next_server,
|
const char *next_server,
|
||||||
const char *root_path)
|
const char *root_path)
|
||||||
{
|
{
|
||||||
char path[NM_STRLEN (NM_CONFIG_DEVICE_STATE_DIR) + 60];
|
char path[NM_STRLEN (NM_CONFIG_DEVICE_STATE_DIR"/") + DEVICE_STATE_FILENAME_LEN_MAX + 1];
|
||||||
GError *local = NULL;
|
GError *local = NULL;
|
||||||
gs_unref_keyfile GKeyFile *kf = NULL;
|
gs_unref_keyfile GKeyFile *kf = NULL;
|
||||||
|
|
||||||
@@ -2477,35 +2479,43 @@ nm_config_device_state_write (int ifindex,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nm_config_device_state_prune_unseen (GHashTable *seen_ifindexes)
|
nm_config_device_state_prune_stale (GHashTable *preserve_ifindexes,
|
||||||
|
NMPlatform *preserve_in_platform)
|
||||||
{
|
{
|
||||||
GDir *dir;
|
GDir *dir;
|
||||||
const char *fn;
|
const char *fn;
|
||||||
int ifindex;
|
char buf[NM_STRLEN (NM_CONFIG_DEVICE_STATE_DIR"/") + DEVICE_STATE_FILENAME_LEN_MAX + 1] = NM_CONFIG_DEVICE_STATE_DIR"/";
|
||||||
gsize fn_len;
|
|
||||||
char buf[NM_STRLEN (NM_CONFIG_DEVICE_STATE_DIR"/") + 30 + 3] = NM_CONFIG_DEVICE_STATE_DIR"/";
|
|
||||||
char *buf_p = &buf[NM_STRLEN (NM_CONFIG_DEVICE_STATE_DIR"/")];
|
char *buf_p = &buf[NM_STRLEN (NM_CONFIG_DEVICE_STATE_DIR"/")];
|
||||||
|
|
||||||
g_return_if_fail (seen_ifindexes);
|
|
||||||
|
|
||||||
dir = g_dir_open (NM_CONFIG_DEVICE_STATE_DIR, 0, NULL);
|
dir = g_dir_open (NM_CONFIG_DEVICE_STATE_DIR, 0, NULL);
|
||||||
if (!dir)
|
if (!dir)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
while ((fn = g_dir_read_name (dir))) {
|
while ((fn = g_dir_read_name (dir))) {
|
||||||
|
int ifindex;
|
||||||
|
gsize fn_len;
|
||||||
|
|
||||||
ifindex = _device_state_parse_filename (fn);
|
ifindex = _device_state_parse_filename (fn);
|
||||||
if (ifindex <= 0)
|
if (ifindex <= 0)
|
||||||
continue;
|
continue;
|
||||||
if (g_hash_table_contains (seen_ifindexes, GINT_TO_POINTER (ifindex)))
|
|
||||||
|
if ( preserve_ifindexes
|
||||||
|
&& g_hash_table_contains (preserve_ifindexes, GINT_TO_POINTER (ifindex)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
fn_len = strlen (fn) + 1;
|
if ( preserve_in_platform
|
||||||
|
&& nm_platform_link_get (preserve_in_platform, ifindex))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
fn_len = strlen (fn);
|
||||||
|
nm_assert (fn_len > 0);
|
||||||
nm_assert (&buf_p[fn_len] < &buf[G_N_ELEMENTS (buf)]);
|
nm_assert (&buf_p[fn_len] < &buf[G_N_ELEMENTS (buf)]);
|
||||||
memcpy (buf_p, fn, fn_len);
|
memcpy (buf_p, fn, fn_len + 1u);
|
||||||
nm_assert (({
|
nm_assert (({
|
||||||
char bb[30];
|
char bb[30];
|
||||||
nm_sprintf_buf (bb, "%d", ifindex);
|
|
||||||
nm_streq0 (bb, buf_p);
|
nm_streq0 (nm_sprintf_buf (bb, "%d", ifindex),
|
||||||
|
buf_p);
|
||||||
}));
|
}));
|
||||||
_LOGT ("device-state: prune #%d (%s)", ifindex, buf);
|
_LOGT ("device-state: prune #%d (%s)", ifindex, buf);
|
||||||
(void) unlink (buf);
|
(void) unlink (buf);
|
||||||
|
@@ -258,7 +258,8 @@ gboolean nm_config_device_state_write (int ifindex,
|
|||||||
const char *next_server,
|
const char *next_server,
|
||||||
const char *root_path);
|
const char *root_path);
|
||||||
|
|
||||||
void nm_config_device_state_prune_unseen (GHashTable *seen_ifindexes);
|
void nm_config_device_state_prune_stale (GHashTable *preserve_ifindexes,
|
||||||
|
NMPlatform *preserve_in_platform);
|
||||||
|
|
||||||
const GHashTable *nm_config_device_state_get_all (NMConfig *self);
|
const GHashTable *nm_config_device_state_get_all (NMConfig *self);
|
||||||
const NMConfigDeviceStateData *nm_config_device_state_get (NMConfig *self,
|
const NMConfigDeviceStateData *nm_config_device_state_get (NMConfig *self,
|
||||||
|
@@ -50,6 +50,8 @@
|
|||||||
#include "nm-dispatcher.h"
|
#include "nm-dispatcher.h"
|
||||||
#include "NetworkManagerUtils.h"
|
#include "NetworkManagerUtils.h"
|
||||||
|
|
||||||
|
#define DEVICE_STATE_PRUNE_RATELIMIT_MAX 100u
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -191,6 +193,8 @@ typedef struct {
|
|||||||
|
|
||||||
NMConnectivityState connectivity_state;
|
NMConnectivityState connectivity_state;
|
||||||
|
|
||||||
|
guint8 device_state_prune_ratelimit_count;
|
||||||
|
|
||||||
bool startup:1;
|
bool startup:1;
|
||||||
bool devices_inited:1;
|
bool devices_inited:1;
|
||||||
|
|
||||||
@@ -1515,8 +1519,22 @@ manager_device_state_changed (NMDevice *device,
|
|||||||
if (NM_IN_SET (new_state,
|
if (NM_IN_SET (new_state,
|
||||||
NM_DEVICE_STATE_UNMANAGED,
|
NM_DEVICE_STATE_UNMANAGED,
|
||||||
NM_DEVICE_STATE_DISCONNECTED,
|
NM_DEVICE_STATE_DISCONNECTED,
|
||||||
NM_DEVICE_STATE_ACTIVATED))
|
NM_DEVICE_STATE_ACTIVATED)) {
|
||||||
nm_manager_write_device_state (self, device);
|
nm_manager_write_device_state (self, device, NULL);
|
||||||
|
|
||||||
|
G_STATIC_ASSERT_EXPR (DEVICE_STATE_PRUNE_RATELIMIT_MAX < G_MAXUINT8);
|
||||||
|
if (priv->device_state_prune_ratelimit_count++ > DEVICE_STATE_PRUNE_RATELIMIT_MAX) {
|
||||||
|
/* We write the device state to /run. The state files are named after the
|
||||||
|
* ifindex (which is assumed to be unique and not repeat -- in practice
|
||||||
|
* it may repeat). So from time to time, we prune device state files
|
||||||
|
* for interfaces that no longer exist.
|
||||||
|
*
|
||||||
|
* Otherwise, the files might pile up if you create (and destroy) a large
|
||||||
|
* number of software devices. */
|
||||||
|
priv->device_state_prune_ratelimit_count = 0;
|
||||||
|
nm_config_device_state_prune_stale (NULL, priv->platform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (NM_IN_SET (new_state,
|
if (NM_IN_SET (new_state,
|
||||||
NM_DEVICE_STATE_UNAVAILABLE,
|
NM_DEVICE_STATE_UNAVAILABLE,
|
||||||
@@ -6484,7 +6502,7 @@ start_factory (NMDeviceFactory *factory, gpointer user_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
nm_manager_write_device_state (NMManager *self, NMDevice *device)
|
nm_manager_write_device_state (NMManager *self, NMDevice *device, int *out_ifindex)
|
||||||
{
|
{
|
||||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||||
int ifindex;
|
int ifindex;
|
||||||
@@ -6500,6 +6518,8 @@ nm_manager_write_device_state (NMManager *self, NMDevice *device)
|
|||||||
const char *next_server = NULL;
|
const char *next_server = NULL;
|
||||||
const char *root_path = NULL;
|
const char *root_path = NULL;
|
||||||
|
|
||||||
|
NM_SET_OUT (out_ifindex, 0);
|
||||||
|
|
||||||
ifindex = nm_device_get_ip_ifindex (device);
|
ifindex = nm_device_get_ip_ifindex (device);
|
||||||
if (ifindex <= 0)
|
if (ifindex <= 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -6540,34 +6560,40 @@ nm_manager_write_device_state (NMManager *self, NMDevice *device)
|
|||||||
next_server = nm_dhcp_config_get_option (dhcp_config, "next_server");
|
next_server = nm_dhcp_config_get_option (dhcp_config, "next_server");
|
||||||
}
|
}
|
||||||
|
|
||||||
return nm_config_device_state_write (ifindex,
|
if (!nm_config_device_state_write (ifindex,
|
||||||
managed_type,
|
managed_type,
|
||||||
perm_hw_addr_fake,
|
perm_hw_addr_fake,
|
||||||
uuid,
|
uuid,
|
||||||
nm_owned,
|
nm_owned,
|
||||||
route_metric_default_aspired,
|
route_metric_default_aspired,
|
||||||
route_metric_default_effective,
|
route_metric_default_effective,
|
||||||
next_server,
|
next_server,
|
||||||
root_path);
|
root_path))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
NM_SET_OUT (out_ifindex, ifindex);
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nm_manager_write_device_state_all (NMManager *self)
|
nm_manager_write_device_state_all (NMManager *self)
|
||||||
{
|
{
|
||||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||||
gs_unref_hashtable GHashTable *seen_ifindexes = NULL;
|
gs_unref_hashtable GHashTable *preserve_ifindexes = NULL;
|
||||||
NMDevice *device;
|
NMDevice *device;
|
||||||
|
|
||||||
seen_ifindexes = g_hash_table_new (nm_direct_hash, NULL);
|
preserve_ifindexes = g_hash_table_new (nm_direct_hash, NULL);
|
||||||
|
|
||||||
c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) {
|
c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) {
|
||||||
if (nm_manager_write_device_state (self, device)) {
|
int ifindex;
|
||||||
g_hash_table_add (seen_ifindexes,
|
|
||||||
GINT_TO_POINTER (nm_device_get_ip_ifindex (device)));
|
if (nm_manager_write_device_state (self, device, &ifindex)) {
|
||||||
|
g_hash_table_add (preserve_ifindexes,
|
||||||
|
GINT_TO_POINTER (ifindex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nm_config_device_state_prune_unseen (seen_ifindexes);
|
nm_config_device_state_prune_stale (preserve_ifindexes, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@@ -103,7 +103,7 @@ NMSettingsConnection **nm_manager_get_activatable_connections (NMManager *manage
|
|||||||
guint *out_len);
|
guint *out_len);
|
||||||
|
|
||||||
void nm_manager_write_device_state_all (NMManager *manager);
|
void nm_manager_write_device_state_all (NMManager *manager);
|
||||||
gboolean nm_manager_write_device_state (NMManager *manager, NMDevice *device);
|
gboolean nm_manager_write_device_state (NMManager *manager, NMDevice *device, int *out_ifindex);
|
||||||
|
|
||||||
/* Device handling */
|
/* Device handling */
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user