summary refs log tree commit diff
path: root/src/nm-manager.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2020-03-13 00:44:14 +0100
committerMichael Biebl <biebl@debian.org>2020-03-13 00:44:14 +0100
commitb012fa6e1d808e0736c009799c62d835cbfcc1dd (patch)
treeff9a3777f6740e91b55f0a566914bfe4ab37935f /src/nm-manager.c
parente536d40eaea5dcdc0743b0a5e8e17faa46608a50 (diff)
New upstream version 1.22.10 upstream/1.22.10
Diffstat (limited to 'src/nm-manager.c')
-rw-r--r--src/nm-manager.c115
1 files changed, 47 insertions, 68 deletions
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 6d3a5ddb..d7b2211e 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -50,6 +50,8 @@
 #include "nm-dispatcher.h"
 #include "NetworkManagerUtils.h"
 
+#define DEVICE_STATE_PRUNE_RATELIMIT_MAX 100u
+
 /*****************************************************************************/
 
 typedef struct {
@@ -168,9 +170,6 @@ typedef struct {
 
 	NMSettings *settings;
 
-	CList connection_changed_on_idle_lst;
-	guint connection_changed_on_idle_id;
-
 	RadioState radio_states[RFKILL_TYPE_MAX];
 	NMVpnManager *vpn_manager;
 
@@ -194,6 +193,8 @@ typedef struct {
 
 	NMConnectivityState connectivity_state;
 
+	guint8 device_state_prune_ratelimit_count;
+
 	bool startup:1;
 	bool devices_inited:1;
 
@@ -1517,8 +1518,22 @@ manager_device_state_changed (NMDevice *device,
 	if (NM_IN_SET (new_state,
 	               NM_DEVICE_STATE_UNMANAGED,
 	               NM_DEVICE_STATE_DISCONNECTED,
-	               NM_DEVICE_STATE_ACTIVATED))
-		nm_manager_write_device_state (self, device);
+	               NM_DEVICE_STATE_ACTIVATED)) {
+		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,
 	               NM_DEVICE_STATE_UNAVAILABLE,
@@ -2098,7 +2113,6 @@ static void
 connection_changed (NMManager *self,
                     NMSettingsConnection *sett_conn)
 {
-	NMManagerPrivate *priv;
 	NMConnection *connection;
 	NMDevice *device;
 
@@ -2106,11 +2120,6 @@ connection_changed (NMManager *self,
 	                  NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE))
 		return;
 
-	priv = NM_MANAGER_GET_PRIVATE (self);
-
-	if (!nm_settings_has_connection (priv->settings, sett_conn))
-		return;
-
 	connection = nm_settings_connection_get_connection (sett_conn);
 
 	if (!nm_connection_is_virtual (connection))
@@ -2126,46 +2135,12 @@ connection_changed (NMManager *self,
 	retry_connections_for_parent_device (self, device);
 }
 
-static gboolean
-connection_changed_on_idle_cb (gpointer user_data)
-{
-	NMManager *self = user_data;
-	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
-	NMCListElem *elem;
-
-	priv->connection_changed_on_idle_id = 0;
-
-	while ((elem = c_list_first_entry (&priv->connection_changed_on_idle_lst, NMCListElem, lst))) {
-		gs_unref_object NMSettingsConnection *sett_conn = NULL;
-
-		sett_conn = nm_c_list_elem_free_steal (elem);
-		connection_changed (self, sett_conn);
-	}
-
-	return G_SOURCE_REMOVE;
-}
-
-static void
-connection_changed_on_idle (NMManager *self,
-                            NMSettingsConnection *sett_conn)
-{
-	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
-
-	if (priv->connection_changed_on_idle_id == 0)
-		priv->connection_changed_on_idle_id = g_idle_add (connection_changed_on_idle_cb, self);
-
-	if (!nm_c_list_elem_find_first_ptr (&priv->connection_changed_on_idle_lst, sett_conn)) {
-		c_list_link_tail (&priv->connection_changed_on_idle_lst,
-		                  &nm_c_list_elem_new_stale (g_object_ref (sett_conn))->lst);
-	}
-}
-
 static void
 connection_added_cb (NMSettings *settings,
                      NMSettingsConnection *sett_conn,
                      NMManager *self)
 {
-	connection_changed_on_idle (self, sett_conn);
+	connection_changed (self, sett_conn);
 }
 
 static void
@@ -2174,7 +2149,7 @@ connection_updated_cb (NMSettings *settings,
                        guint update_reason_u,
                        NMManager *self)
 {
-	connection_changed_on_idle (self, sett_conn);
+	connection_changed (self, sett_conn);
 }
 
 /*****************************************************************************/
@@ -3377,7 +3352,7 @@ add:
 			_LOGI (LOGD_PLATFORM, "(%s): '%s' plugin not available; creating generic device",
 			       plink->name, nm_link_type_to_string (plink->type));
 			nm_plugin_missing = TRUE;
-			/* fall through */
+			/* fall-through */
 		default:
 			device = nm_device_generic_new (plink, nm_plugin_missing);
 			break;
@@ -6557,7 +6532,7 @@ start_factory (NMDeviceFactory *factory, gpointer user_data)
 }
 
 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);
 	int ifindex;
@@ -6573,6 +6548,8 @@ nm_manager_write_device_state (NMManager *self, NMDevice *device)
 	const char *next_server = NULL;
 	const char *root_path = NULL;
 
+	NM_SET_OUT (out_ifindex, 0);
+
 	ifindex = nm_device_get_ip_ifindex (device);
 	if (ifindex <= 0)
 		return FALSE;
@@ -6613,34 +6590,40 @@ nm_manager_write_device_state (NMManager *self, NMDevice *device)
 		next_server = nm_dhcp4_config_get_option (dhcp4_config, "next_server");
 	}
 
-	return nm_config_device_state_write (ifindex,
-	                                     managed_type,
-	                                     perm_hw_addr_fake,
-	                                     uuid,
-	                                     nm_owned,
-	                                     route_metric_default_aspired,
-	                                     route_metric_default_effective,
-	                                     next_server,
-	                                     root_path);
+	if (!nm_config_device_state_write (ifindex,
+	                                   managed_type,
+	                                   perm_hw_addr_fake,
+	                                   uuid,
+	                                   nm_owned,
+	                                   route_metric_default_aspired,
+	                                   route_metric_default_effective,
+	                                   next_server,
+	                                   root_path))
+		return FALSE;
+
+	NM_SET_OUT (out_ifindex, ifindex);
+	return TRUE;
 }
 
 void
 nm_manager_write_device_state_all (NMManager *self)
 {
 	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
-	gs_unref_hashtable GHashTable *seen_ifindexes = NULL;
+	gs_unref_hashtable GHashTable *preserve_ifindexes = NULL;
 	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) {
-		if (nm_manager_write_device_state (self, device)) {
-			g_hash_table_add (seen_ifindexes,
-			                  GINT_TO_POINTER (nm_device_get_ip_ifindex (device)));
+		int ifindex;
+
+		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
@@ -7511,7 +7494,6 @@ nm_manager_init (NMManager *self)
 	c_list_init (&priv->active_connections_lst_head);
 	c_list_init (&priv->async_op_lst_head);
 	c_list_init (&priv->delete_volatile_connection_lst_head);
-	c_list_init (&priv->connection_changed_on_idle_lst);
 
 	priv->platform = g_object_ref (NM_PLATFORM_GET);
 
@@ -7817,9 +7799,6 @@ dispose (GObject *object)
 		g_clear_object (&priv->policy);
 	}
 
-	nm_clear_g_source (&priv->connection_changed_on_idle_id);
-	nm_c_list_elem_free_all (&priv->connection_changed_on_idle_lst, g_object_unref);
-
 	if (priv->settings) {
 		g_signal_handlers_disconnect_by_func (priv->settings, settings_startup_complete_changed, self);
 		g_signal_handlers_disconnect_by_func (priv->settings, system_unmanaged_devices_changed_cb, self);