diff options
Diffstat (limited to 'src/nm-manager.c')
| -rw-r--r-- | src/nm-manager.c | 115 |
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); |