diff options
-rw-r--r-- | src/nm-logging.c | 12 | ||||
-rw-r--r-- | src/platform/nm-linux-platform.c | 42 | ||||
-rw-r--r-- | src/platform/nm-linux-platform.h | 2 |
3 files changed, 44 insertions, 12 deletions
diff --git a/src/nm-logging.c b/src/nm-logging.c index e58a5de384..6476d7664f 100644 --- a/src/nm-logging.c +++ b/src/nm-logging.c @@ -40,6 +40,7 @@ #include "nm-default.h" #include "nm-errors.h" #include "NetworkManagerUtils.h" +#include "nm-linux-platform.h" static void nm_log_handler (const gchar *log_domain, @@ -169,6 +170,7 @@ nm_logging_setup (const char *level, NMLogLevel new_log_level = log_level; char **tmp, **iter; int i; + gboolean had_platform_debug; g_return_val_if_fail (!bad_domains || !*bad_domains, FALSE); g_return_val_if_fail (!error || !*error, FALSE); @@ -276,10 +278,20 @@ nm_logging_setup (const char *level, g_clear_pointer (&logging_domains_to_string, g_free); + had_platform_debug = nm_logging_enabled (LOGL_DEBUG, LOGD_PLATFORM); + log_level = new_log_level; for (i = 0; i < G_N_ELEMENTS (new_logging); i++) logging[i] = new_logging[i]; + if ( had_platform_debug + && !nm_logging_enabled (LOGL_DEBUG, LOGD_PLATFORM)) { + /* when debug logging is enabled, platform will cache all access to + * sysctl. When the user disables debug-logging, we want to clear that + * cache right away. */ + _nm_linux_platform_sysctl_clear_cache (); + } + if (unrecognized) *bad_domains = g_string_free (unrecognized, FALSE); diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 2daa1aec46..76d74da0bd 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -731,6 +731,7 @@ struct _NMLinuxPlatformPrivate { GIOChannel *event_channel; guint event_id; + gboolean sysctl_get_warned; GHashTable *sysctl_get_prev_values; GUdevClient *udev_client; @@ -2546,15 +2547,32 @@ sysctl_set (NMPlatform *platform, const char *path, const char *value) return (nwrote == len); } +static GSList *sysctl_clear_cache_list; + +void +_nm_linux_platform_sysctl_clear_cache (void) +{ + while (sysctl_clear_cache_list) { + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (sysctl_clear_cache_list->data); + + sysctl_clear_cache_list = g_slist_delete_link (sysctl_clear_cache_list, sysctl_clear_cache_list); + + g_hash_table_destroy (priv->sysctl_get_prev_values); + priv->sysctl_get_prev_values = NULL; + priv->sysctl_get_warned = FALSE; + } +} + static void _log_dbg_sysctl_get_impl (NMPlatform *platform, const char *path, const char *contents) { NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); const char *prev_value = NULL; - if (!priv->sysctl_get_prev_values) + if (!priv->sysctl_get_prev_values) { + sysctl_clear_cache_list = g_slist_prepend (sysctl_clear_cache_list, platform); priv->sysctl_get_prev_values = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - else + } else prev_value = g_hash_table_lookup (priv->sysctl_get_prev_values, path); if (prev_value) { @@ -2574,20 +2592,18 @@ _log_dbg_sysctl_get_impl (NMPlatform *platform, const char *path, const char *co g_free (contents_escaped); g_hash_table_insert (priv->sysctl_get_prev_values, g_strdup (path), g_strdup (contents)); } + + if ( !priv->sysctl_get_warned + && g_hash_table_size (priv->sysctl_get_prev_values) > 50000) { + _LOGW ("sysctl: the internal cache for debug-logging of sysctl values grew pretty large. You can clear it by disabling debug-logging: `nmcli general logging level KEEP domains PLATFORM:INFO`."); + priv->sysctl_get_warned = TRUE; + } } #define _log_dbg_sysctl_get(platform, path, contents) \ G_STMT_START { \ - if (_LOGD_ENABLED ()) { \ + if (_LOGD_ENABLED ()) \ _log_dbg_sysctl_get_impl (platform, path, contents); \ - } else { \ - NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); \ - \ - if (priv->sysctl_get_prev_values) { \ - g_hash_table_destroy (priv->sysctl_get_prev_values); \ - priv->sysctl_get_prev_values = NULL; \ - } \ - } \ } G_STMT_END static char * @@ -5029,8 +5045,10 @@ nm_linux_platform_finalize (GObject *object) g_object_unref (priv->udev_client); g_hash_table_unref (priv->wifi_data); - if (priv->sysctl_get_prev_values) + if (priv->sysctl_get_prev_values) { + sysctl_clear_cache_list = g_slist_remove (sysctl_clear_cache_list, object); g_hash_table_destroy (priv->sysctl_get_prev_values); + } G_OBJECT_CLASS (nm_linux_platform_parent_class)->finalize (object); } diff --git a/src/platform/nm-linux-platform.h b/src/platform/nm-linux-platform.h index a9e2cd82f9..81f9c73871 100644 --- a/src/platform/nm-linux-platform.h +++ b/src/platform/nm-linux-platform.h @@ -50,4 +50,6 @@ GType nm_linux_platform_get_type (void); void nm_linux_platform_setup (void); +void _nm_linux_platform_sysctl_clear_cache (void); + #endif /* __NETWORKMANAGER_LINUX_PLATFORM_H__ */ |