summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2015-10-09 14:59:10 +0200
committerThomas Haller <thaller@redhat.com>2015-10-09 14:59:10 +0200
commitc71c301c3b34092d8bdac3cec11f85c4fc737143 (patch)
tree05c171d51a2feeefeb1be12cd583dde2107a2172
parentcc6b07c43974bc83b2bc17dce5bbe5934149fb58 (diff)
parent6b0cb77b881ff476cdb12f68c2d3ab1454e18b58 (diff)
downloadNetworkManager-c71c301c3b34092d8bdac3cec11f85c4fc737143.tar.gz
logging: merge branch 'th/logging-keep-bgo756175'
https://bugzilla.gnome.org/show_bug.cgi?id=756175
-rw-r--r--introspection/nm-manager.xml8
-rw-r--r--src/nm-logging.c326
-rw-r--r--src/nm-logging.h1
-rw-r--r--src/platform/nm-linux-platform.c42
-rw-r--r--src/platform/nm-linux-platform.h2
5 files changed, 225 insertions, 154 deletions
diff --git a/introspection/nm-manager.xml b/introspection/nm-manager.xml
index 88f477d62f..36cbee3011 100644
--- a/introspection/nm-manager.xml
+++ b/introspection/nm-manager.xml
@@ -184,7 +184,13 @@
</tp:docstring>
<arg name="level" type="s" direction="in">
<tp:docstring>
- One of [ERR, WARN, INFO, DEBUG, TRACE].
+ One of [ERR, WARN, INFO, DEBUG, TRACE, OFF, KEEP].
+ This level is applied to the domains as specified in the domains
+ argument. Except for the special level "KEEP", all unmentioned
+ domains are disabled entirely. "KEEP" is special and allows
+ not to change the current setting except for the specified
+ domains. E.g. level=KEEP and domains=PLATFORM:DEBUG will only
+ touch the platform domain.
</tp:docstring>
</arg>
<arg name="domains" type="s" direction="in">
diff --git a/src/nm-logging.c b/src/nm-logging.c
index 30c754d163..60ccb5cb2f 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,
@@ -47,18 +48,6 @@ nm_log_handler (const gchar *log_domain,
const gchar *message,
gpointer ignored);
-static NMLogLevel log_level = LOGL_INFO;
-static char *log_domains;
-static NMLogDomain logging[_LOGL_N_REAL];
-static gboolean logging_set_up;
-enum {
- LOG_BACKEND_GLIB,
- LOG_BACKEND_SYSLOG,
- LOG_BACKEND_JOURNAL,
- LOG_BACKEND_JOURNAL_SYSLOG_STYLE,
-} log_backend = LOG_BACKEND_GLIB;
-static char *logging_domains_to_string;
-
typedef struct {
NMLogDomain num;
const char *name;
@@ -72,52 +61,74 @@ typedef struct {
gboolean full_details;
} LogLevelDesc;
-static const LogLevelDesc level_desc[_LOGL_N] = {
- [LOGL_TRACE] = { "TRACE", "<trace>", LOG_DEBUG, G_LOG_LEVEL_DEBUG, TRUE },
- [LOGL_DEBUG] = { "DEBUG", "<debug>", LOG_INFO, G_LOG_LEVEL_DEBUG, TRUE },
- [LOGL_INFO] = { "INFO", "<info>", LOG_INFO, G_LOG_LEVEL_MESSAGE, FALSE },
- [LOGL_WARN] = { "WARN", "<warn>", LOG_WARNING, G_LOG_LEVEL_WARNING, FALSE },
- [LOGL_ERR] = { "ERR", "<error>", LOG_ERR, G_LOG_LEVEL_WARNING, TRUE },
- [_LOGL_OFF] = { "OFF", NULL, 0, 0, FALSE },
-};
-
-static const LogDesc domain_descs[] = {
- { LOGD_PLATFORM, "PLATFORM" },
- { LOGD_RFKILL, "RFKILL" },
- { LOGD_ETHER, "ETHER" },
- { LOGD_WIFI, "WIFI" },
- { LOGD_BT, "BT" },
- { LOGD_MB, "MB" },
- { LOGD_DHCP4, "DHCP4" },
- { LOGD_DHCP6, "DHCP6" },
- { LOGD_PPP, "PPP" },
- { LOGD_WIFI_SCAN, "WIFI_SCAN" },
- { LOGD_IP4, "IP4" },
- { LOGD_IP6, "IP6" },
- { LOGD_AUTOIP4, "AUTOIP4" },
- { LOGD_DNS, "DNS" },
- { LOGD_VPN, "VPN" },
- { LOGD_SHARING, "SHARING" },
- { LOGD_SUPPLICANT,"SUPPLICANT" },
- { LOGD_AGENTS, "AGENTS" },
- { LOGD_SETTINGS, "SETTINGS" },
- { LOGD_SUSPEND, "SUSPEND" },
- { LOGD_CORE, "CORE" },
- { LOGD_DEVICE, "DEVICE" },
- { LOGD_OLPC, "OLPC" },
- { LOGD_INFINIBAND,"INFINIBAND" },
- { LOGD_FIREWALL, "FIREWALL" },
- { LOGD_ADSL, "ADSL" },
- { LOGD_BOND, "BOND" },
- { LOGD_VLAN, "VLAN" },
- { LOGD_BRIDGE, "BRIDGE" },
- { LOGD_DBUS_PROPS,"DBUS_PROPS" },
- { LOGD_TEAM, "TEAM" },
- { LOGD_CONCHECK, "CONCHECK" },
- { LOGD_DCB, "DCB" },
- { LOGD_DISPATCH, "DISPATCH" },
- { LOGD_AUDIT, "AUDIT" },
- { 0, NULL }
+static struct {
+ NMLogLevel log_level;
+ NMLogDomain logging[_LOGL_N_REAL];
+ gboolean logging_set_up;
+ enum {
+ LOG_BACKEND_GLIB,
+ LOG_BACKEND_SYSLOG,
+ LOG_BACKEND_JOURNAL,
+ LOG_BACKEND_JOURNAL_SYSLOG_STYLE,
+ } log_backend;
+ char *logging_domains_to_string;
+ const LogLevelDesc level_desc[_LOGL_N];
+
+#define _DOMAIN_DESC_LEN 36
+ /* Would be nice to use C99 flexible array member here,
+ * but that feature doesn't seem well supported. */
+ const LogDesc domain_desc[_DOMAIN_DESC_LEN];
+} global = {
+ .log_level = LOGL_INFO,
+ .log_backend = LOG_BACKEND_GLIB,
+ .level_desc = {
+ [LOGL_TRACE] = { "TRACE", "<trace>", LOG_DEBUG, G_LOG_LEVEL_DEBUG, TRUE },
+ [LOGL_DEBUG] = { "DEBUG", "<debug>", LOG_INFO, G_LOG_LEVEL_DEBUG, TRUE },
+ [LOGL_INFO] = { "INFO", "<info>", LOG_INFO, G_LOG_LEVEL_MESSAGE, FALSE },
+ [LOGL_WARN] = { "WARN", "<warn>", LOG_WARNING, G_LOG_LEVEL_WARNING, FALSE },
+ [LOGL_ERR] = { "ERR", "<error>", LOG_ERR, G_LOG_LEVEL_WARNING, TRUE },
+ [_LOGL_OFF] = { "OFF", NULL, 0, 0, FALSE },
+ [_LOGL_KEEP] = { "KEEP", NULL, 0, 0, FALSE },
+ },
+ .domain_desc = {
+ { LOGD_PLATFORM, "PLATFORM" },
+ { LOGD_RFKILL, "RFKILL" },
+ { LOGD_ETHER, "ETHER" },
+ { LOGD_WIFI, "WIFI" },
+ { LOGD_BT, "BT" },
+ { LOGD_MB, "MB" },
+ { LOGD_DHCP4, "DHCP4" },
+ { LOGD_DHCP6, "DHCP6" },
+ { LOGD_PPP, "PPP" },
+ { LOGD_WIFI_SCAN, "WIFI_SCAN" },
+ { LOGD_IP4, "IP4" },
+ { LOGD_IP6, "IP6" },
+ { LOGD_AUTOIP4, "AUTOIP4" },
+ { LOGD_DNS, "DNS" },
+ { LOGD_VPN, "VPN" },
+ { LOGD_SHARING, "SHARING" },
+ { LOGD_SUPPLICANT,"SUPPLICANT" },
+ { LOGD_AGENTS, "AGENTS" },
+ { LOGD_SETTINGS, "SETTINGS" },
+ { LOGD_SUSPEND, "SUSPEND" },
+ { LOGD_CORE, "CORE" },
+ { LOGD_DEVICE, "DEVICE" },
+ { LOGD_OLPC, "OLPC" },
+ { LOGD_INFINIBAND,"INFINIBAND" },
+ { LOGD_FIREWALL, "FIREWALL" },
+ { LOGD_ADSL, "ADSL" },
+ { LOGD_BOND, "BOND" },
+ { LOGD_VLAN, "VLAN" },
+ { LOGD_BRIDGE, "BRIDGE" },
+ { LOGD_DBUS_PROPS,"DBUS_PROPS" },
+ { LOGD_TEAM, "TEAM" },
+ { LOGD_CONCHECK, "CONCHECK" },
+ { LOGD_DCB, "DCB" },
+ { LOGD_DISPATCH, "DISPATCH" },
+ { LOGD_AUDIT, "AUDIT" },
+ { 0, NULL }
+ /* keep _DOMAIN_DESC_LEN in sync */
+ },
};
/* We have more then 32 logging domains. Assert that it compiles to a 64 bit sized enum */
@@ -131,11 +142,15 @@ G_STATIC_ASSERT (sizeof (NMLogDomain) >= sizeof (guint64));
/************************************************************************/
+static char *_domains_to_string (gboolean include_level_override);
+
+/************************************************************************/
+
static void
_ensure_initialized (void)
{
- if (G_UNLIKELY (!logging_set_up))
- nm_logging_setup ("INFO", "DEFAULT", NULL, NULL);
+ if (G_UNLIKELY (!global.logging_set_up))
+ nm_logging_setup ("INFO", LOGD_DEFAULT_STRING, NULL, NULL);
}
static gboolean
@@ -145,8 +160,8 @@ match_log_level (const char *level,
{
int i;
- for (i = 0; i < G_N_ELEMENTS (level_desc); i++) {
- if (!g_ascii_strcasecmp (level_desc[i].name, level)) {
+ for (i = 0; i < G_N_ELEMENTS (global.level_desc); i++) {
+ if (!g_ascii_strcasecmp (global.level_desc[i].name, level)) {
*out_level = i;
return TRUE;
}
@@ -164,15 +179,24 @@ nm_logging_setup (const char *level,
GError **error)
{
GString *unrecognized = NULL;
- NMLogDomain new_logging[G_N_ELEMENTS (logging)];
- NMLogLevel new_log_level = log_level;
+ NMLogDomain new_logging[G_N_ELEMENTS (global.logging)];
+ NMLogLevel new_log_level = global.log_level;
char **tmp, **iter;
int i;
+ gboolean had_platform_debug;
+ gs_free char *domains_free = NULL;
g_return_val_if_fail (!bad_domains || !*bad_domains, FALSE);
g_return_val_if_fail (!error || !*error, FALSE);
- logging_set_up = TRUE;
+ /* domains */
+ if (!domains || !*domains) {
+ domains = global.logging_set_up
+ ? (domains_free = _domains_to_string (FALSE))
+ : LOGD_DEFAULT_STRING;
+ }
+
+ global.logging_set_up = TRUE;
for (i = 0; i < G_N_ELEMENTS (new_logging); i++)
new_logging[i] = 0;
@@ -181,12 +205,13 @@ nm_logging_setup (const char *level,
if (level && *level) {
if (!match_log_level (level, &new_log_level, error))
return FALSE;
+ if (new_log_level == _LOGL_KEEP) {
+ new_log_level = global.log_level;
+ for (i = 0; i < G_N_ELEMENTS (new_logging); i++)
+ new_logging[i] = global.logging[i];
+ }
}
- /* domains */
- if (!domains || !*domains)
- domains = log_domains ? log_domains : "DEFAULT";
-
tmp = g_strsplit_set (domains, ", ", 0);
for (iter = tmp; iter && *iter; iter++) {
const LogDesc *diter;
@@ -226,7 +251,7 @@ nm_logging_setup (const char *level,
continue;
else {
- for (diter = &domain_descs[0]; diter->name; diter++) {
+ for (diter = &global.domain_desc[0]; diter->name; diter++) {
if (!g_ascii_strcasecmp (diter->name, *iter)) {
bits = diter->num;
break;
@@ -249,25 +274,35 @@ nm_logging_setup (const char *level,
}
}
- for (i = 0; i < G_N_ELEMENTS (new_logging); i++) {
- if (i < domain_log_level)
- new_logging[i] &= ~bits;
- else
- new_logging[i] |= bits;
+ if (domain_log_level == _LOGL_KEEP) {
+ for (i = 0; i < G_N_ELEMENTS (new_logging); i++)
+ new_logging[i] = (new_logging[i] & ~bits) | (global.logging[i] & bits);
+ } else {
+ for (i = 0; i < G_N_ELEMENTS (new_logging); i++) {
+ if (i < domain_log_level)
+ new_logging[i] &= ~bits;
+ else
+ new_logging[i] |= bits;
+ }
}
}
g_strfreev (tmp);
- if (log_domains != (char *)domains) {
- g_free (log_domains);
- log_domains = g_strdup (domains);
- }
+ g_clear_pointer (&global.logging_domains_to_string, g_free);
- g_clear_pointer (&logging_domains_to_string, g_free);
+ had_platform_debug = nm_logging_enabled (LOGL_DEBUG, LOGD_PLATFORM);
- log_level = new_log_level;
+ global.log_level = new_log_level;
for (i = 0; i < G_N_ELEMENTS (new_logging); i++)
- logging[i] = new_logging[i];
+ global.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);
@@ -278,7 +313,7 @@ nm_logging_setup (const char *level,
const char *
nm_logging_level_to_string (void)
{
- return level_desc[log_level].name;
+ return global.level_desc[global.log_level].name;
}
const char *
@@ -290,10 +325,10 @@ nm_logging_all_levels_to_string (void)
int i;
str = g_string_new (NULL);
- for (i = 0; i < G_N_ELEMENTS (level_desc); i++) {
+ for (i = 0; i < G_N_ELEMENTS (global.level_desc); i++) {
if (str->len)
g_string_append_c (str, ',');
- g_string_append (str, level_desc[i].name);
+ g_string_append (str, global.level_desc[i].name);
}
}
@@ -305,45 +340,54 @@ nm_logging_domains_to_string (void)
{
_ensure_initialized ();
- if (G_UNLIKELY (!logging_domains_to_string)) {
- const LogDesc *diter;
- GString *str;
- int i;
+ if (G_UNLIKELY (!global.logging_domains_to_string))
+ global.logging_domains_to_string = _domains_to_string (TRUE);
- /* We don't just return g_strdup (log_domains) because we want to expand
- * "DEFAULT" and "ALL".
- */
+ return global.logging_domains_to_string;
+}
- str = g_string_sized_new (75);
- for (diter = &domain_descs[0]; diter->name; diter++) {
- /* If it's set for any lower level, it will also be set for LOGL_ERR */
- if (!(diter->num & logging[LOGL_ERR]))
- continue;
+static char *
+_domains_to_string (gboolean include_level_override)
+{
+ const LogDesc *diter;
+ GString *str;
+ int i;
- if (str->len)
- g_string_append_c (str, ',');
- g_string_append (str, diter->name);
+ /* We don't just return g_strdup (global.log_domains) because we want to expand
+ * "DEFAULT" and "ALL".
+ */
- /* Check if it's logging at a lower level than the default. */
- for (i = 0; i < log_level; i++) {
- if (diter->num & logging[i]) {
- g_string_append_printf (str, ":%s", level_desc[i].name);
- break;
- }
+ str = g_string_sized_new (75);
+ for (diter = &global.domain_desc[0]; diter->name; diter++) {
+ /* If it's set for any lower level, it will also be set for LOGL_ERR */
+ if (!(diter->num & global.logging[LOGL_ERR]))
+ continue;
+
+ if (str->len)
+ g_string_append_c (str, ',');
+ g_string_append (str, diter->name);
+
+ if (!include_level_override)
+ continue;
+
+ /* Check if it's logging at a lower level than the default. */
+ for (i = 0; i < global.log_level; i++) {
+ if (diter->num & global.logging[i]) {
+ g_string_append_printf (str, ":%s", global.level_desc[i].name);
+ break;
}
- /* Check if it's logging at a higher level than the default. */
- if (!(diter->num & logging[log_level])) {
- for (i = log_level + 1; i < G_N_ELEMENTS (logging); i++) {
- if (diter->num & logging[i]) {
- g_string_append_printf (str, ":%s", level_desc[i].name);
- break;
- }
+ }
+ /* Check if it's logging at a higher level than the default. */
+ if (!(diter->num & global.logging[global.log_level])) {
+ for (i = global.log_level + 1; i < G_N_ELEMENTS (global.logging); i++) {
+ if (diter->num & global.logging[i]) {
+ g_string_append_printf (str, ":%s", global.level_desc[i].name);
+ break;
}
}
}
- logging_domains_to_string = g_string_free (str, FALSE);
}
- return logging_domains_to_string;
+ return g_string_free (str, FALSE);
}
const char *
@@ -355,7 +399,7 @@ nm_logging_all_domains_to_string (void)
const LogDesc *diter;
str = g_string_new (LOGD_DEFAULT_STRING);
- for (diter = &domain_descs[0]; diter->name; diter++) {
+ for (diter = &global.domain_desc[0]; diter->name; diter++) {
g_string_append_c (str, ',');
g_string_append (str, diter->name);
if (diter->num == LOGD_DHCP6)
@@ -372,12 +416,12 @@ nm_logging_all_domains_to_string (void)
gboolean
nm_logging_enabled (NMLogLevel level, NMLogDomain domain)
{
- if ((guint) level >= G_N_ELEMENTS (logging))
+ if ((guint) level >= G_N_ELEMENTS (global.logging))
g_return_val_if_reached (FALSE);
_ensure_initialized ();
- return !!(logging[level] & domain);
+ return !!(global.logging[level] & domain);
}
#if SYSTEMD_JOURNAL
@@ -422,12 +466,12 @@ _nm_log_impl (const char *file,
char *fullmsg = NULL;
GTimeVal tv;
- if ((guint) level >= G_N_ELEMENTS (logging))
+ if ((guint) level >= G_N_ELEMENTS (global.logging))
g_return_if_reached ();
_ensure_initialized ();
- if (!(logging[level] & domain))
+ if (!(global.logging[level] & domain))
return;
/* Make sure that %m maps to the specified error */
@@ -441,7 +485,7 @@ _nm_log_impl (const char *file,
msg = g_strdup_vprintf (fmt, args);
va_end (args);
- switch (log_backend) {
+ switch (global.log_backend) {
#if SYSTEMD_JOURNAL
case LOG_BACKEND_JOURNAL:
case LOG_BACKEND_JOURNAL_SYSLOG_STYLE:
@@ -456,13 +500,13 @@ _nm_log_impl (const char *file,
now = nm_utils_get_monotonic_timestamp_ns ();
boottime = nm_utils_monotonic_timestamp_as_boottime (now, 1);
- _iovec_set_format (iov, iov_free, i_field++, "PRIORITY=%d", level_desc[level].syslog_level);
- if ( log_backend == LOG_BACKEND_JOURNAL_SYSLOG_STYLE
- && level_desc[level].full_details) {
+ _iovec_set_format (iov, iov_free, i_field++, "PRIORITY=%d", global.level_desc[level].syslog_level);
+ if ( global.log_backend == LOG_BACKEND_JOURNAL_SYSLOG_STYLE
+ && global.level_desc[level].full_details) {
g_get_current_time (&tv);
- _iovec_set_format (iov, iov_free, i_field++, "MESSAGE=%-7s [%ld.%06ld] [%s:%u] %s(): %s", level_desc[level].level_str, tv.tv_sec, tv.tv_usec, file, line, func, msg);
+ _iovec_set_format (iov, iov_free, i_field++, "MESSAGE=%-7s [%ld.%06ld] [%s:%u] %s(): %s", global.level_desc[level].level_str, tv.tv_sec, tv.tv_usec, file, line, func, msg);
} else
- _iovec_set_format (iov, iov_free, i_field++, "MESSAGE=%-7s %s", level_desc[level].level_str, msg);
+ _iovec_set_format (iov, iov_free, i_field++, "MESSAGE=%-7s %s", global.level_desc[level].level_str, msg);
_iovec_set_literal_string (iov, iov_free, i_field++, "SYSLOG_IDENTIFIER=" G_LOG_DOMAIN);
_iovec_set_format (iov, iov_free, i_field++, "SYSLOG_PID=%ld", (long) getpid ());
{
@@ -471,9 +515,9 @@ _nm_log_impl (const char *file,
const char *s_domain_1 = NULL;
GString *s_domain_all = NULL;
NMLogDomain dom_all = domain;
- NMLogDomain dom = dom_all & logging[level];
+ NMLogDomain dom = dom_all & global.logging[level];
- for (diter = &domain_descs[0]; diter->name; diter++) {
+ for (diter = &global.domain_desc[0]; diter->name; diter++) {
if (!NM_FLAGS_HAS (dom_all, diter->num))
continue;
@@ -507,7 +551,7 @@ _nm_log_impl (const char *file,
} else
_iovec_set_format (iov, iov_free, i_field++, "NM_LOG_DOMAINS=%s", s_domain_1);
}
- _iovec_set_format (iov, iov_free, i_field++, "NM_LOG_LEVEL=%s", level_desc[level].name);
+ _iovec_set_format (iov, iov_free, i_field++, "NM_LOG_LEVEL=%s", global.level_desc[level].name);
_iovec_set_format (iov, iov_free, i_field++, "CODE_FUNC=%s", func);
_iovec_set_format (iov, iov_free, i_field++, "CODE_FILE=%s", file);
_iovec_set_format (iov, iov_free, i_field++, "CODE_LINE=%u", line);
@@ -529,16 +573,16 @@ _nm_log_impl (const char *file,
break;
#endif
default:
- if (level_desc[level].full_details) {
+ if (global.level_desc[level].full_details) {
g_get_current_time (&tv);
- fullmsg = g_strdup_printf ("%-7s [%ld.%06ld] [%s:%u] %s(): %s", level_desc[level].level_str, tv.tv_sec, tv.tv_usec, file, line, func, msg);
+ fullmsg = g_strdup_printf ("%-7s [%ld.%06ld] [%s:%u] %s(): %s", global.level_desc[level].level_str, tv.tv_sec, tv.tv_usec, file, line, func, msg);
} else
- fullmsg = g_strdup_printf ("%-7s %s", level_desc[level].level_str, msg);
+ fullmsg = g_strdup_printf ("%-7s %s", global.level_desc[level].level_str, msg);
- if (log_backend == LOG_BACKEND_SYSLOG)
- syslog (level_desc[level].syslog_level, "%s", fullmsg);
+ if (global.log_backend == LOG_BACKEND_SYSLOG)
+ syslog (global.level_desc[level].syslog_level, "%s", fullmsg);
else
- g_log (G_LOG_DOMAIN, level_desc[level].g_log_level, "%s", fullmsg);
+ g_log (G_LOG_DOMAIN, global.level_desc[level].g_log_level, "%s", fullmsg);
break;
}
@@ -578,7 +622,7 @@ nm_log_handler (const gchar *log_domain,
break;
}
- switch (log_backend) {
+ switch (global.log_backend) {
#if SYSTEMD_JOURNAL
case LOG_BACKEND_JOURNAL:
case LOG_BACKEND_JOURNAL_SYSLOG_STYLE:
@@ -610,28 +654,28 @@ nm_log_handler (const gchar *log_domain,
void
nm_logging_syslog_openlog (const char *logging_backend)
{
- if (log_backend != LOG_BACKEND_GLIB)
+ if (global.log_backend != LOG_BACKEND_GLIB)
g_return_if_reached ();
if (!logging_backend)
logging_backend = ""NM_CONFIG_LOGGING_BACKEND_DEFAULT;
if (strcmp (logging_backend, "debug") == 0) {
- log_backend = LOG_BACKEND_SYSLOG;
+ global.log_backend = LOG_BACKEND_SYSLOG;
openlog (G_LOG_DOMAIN, LOG_CONS | LOG_PERROR | LOG_PID, LOG_USER);
#if SYSTEMD_JOURNAL
} else if (strcmp (logging_backend, "syslog") != 0) {
if (strcmp (logging_backend, "journal-syslog-style") != 0)
- log_backend = LOG_BACKEND_JOURNAL;
+ global.log_backend = LOG_BACKEND_JOURNAL;
else
- log_backend = LOG_BACKEND_JOURNAL_SYSLOG_STYLE;
+ global.log_backend = LOG_BACKEND_JOURNAL_SYSLOG_STYLE;
/* ensure we read a monotonic timestamp. Reading the timestamp the first
* time causes a logging message. We don't want to do that during _nm_log_impl. */
nm_utils_get_monotonic_timestamp_ns ();
#endif
} else {
- log_backend = LOG_BACKEND_SYSLOG;
+ global.log_backend = LOG_BACKEND_SYSLOG;
openlog (G_LOG_DOMAIN, LOG_PID, LOG_DAEMON);
}
diff --git a/src/nm-logging.h b/src/nm-logging.h
index db9f0b1557..b54078186e 100644
--- a/src/nm-logging.h
+++ b/src/nm-logging.h
@@ -94,6 +94,7 @@ typedef enum { /*< skip >*/
_LOGL_N_REAL, /* the number of actual logging levels */
_LOGL_OFF = _LOGL_N_REAL, /* special logging level that is always disabled. */
+ _LOGL_KEEP, /* special logging level to indicate that the logging level should not be changed. */
_LOGL_N, /* the number of logging levels including "OFF" */
} NMLogLevel;
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__ */