diff options
author | Franck Bui <fbui@suse.com> | 2018-05-30 17:57:23 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2018-06-13 18:52:27 +0200 |
commit | a6ecbf836c1e70cdf05a1ad6b78c86c5aef4dca3 (patch) | |
tree | 291745679323a6cf89cd4f4045d62aae8688394b /src/core/manager.c | |
parent | 6f8a8b84f28be7a6133bbde1479dee9abad6cee8 (diff) | |
download | systemd-a6ecbf836c1e70cdf05a1ad6b78c86c5aef4dca3.tar.gz |
pid1: preserve current value of log level across re-{load,execution}
To make debugging easier, this patches allows one to change the log level and
do reload/reexec without modifying configuration permanently, which makes
debugging easier.
Indeed if one changed the log max level at runtime (via the bus or via
signals), the change was lost on the next daemon reload/reexecution.
In order to restore the original value back (set via system.conf, environment
variables or any other means), the empty string in the "LogLevel" property is
now supported as well as sending SIGRTMIN+23 signal.
Diffstat (limited to 'src/core/manager.c')
-rw-r--r-- | src/core/manager.c | 49 |
1 files changed, 45 insertions, 4 deletions
diff --git a/src/core/manager.c b/src/core/manager.c index e1ce9229a3..92d5a0fff6 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -74,6 +74,7 @@ #include "string-util.h" #include "strv.h" #include "strxcpyx.h" +#include "syslog-util.h" #include "terminal-util.h" #include "time-util.h" #include "transaction.h" @@ -735,6 +736,7 @@ int manager_new(UnitFileScope scope, unsigned test_run_flags, Manager **_m) { m->default_timeout_start_usec = DEFAULT_TIMEOUT_USEC; m->default_timeout_stop_usec = DEFAULT_TIMEOUT_USEC; m->default_restart_usec = DEFAULT_RESTART_USEC; + m->original_log_level = -1; #if ENABLE_EFI if (MANAGER_IS_SYSTEM(m) && detect_container() <= 0) @@ -2626,13 +2628,11 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t break; case 22: - log_set_max_level(LOG_DEBUG); - log_info("Setting log level to debug."); + manager_override_log_level(m, LOG_DEBUG); break; case 23: - log_set_max_level(LOG_INFO); - log_info("Setting log level to info."); + manager_restore_original_log_level(m); break; case 24: @@ -3027,6 +3027,9 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) { fprintf(f, "taint-logged=%s\n", yes_no(m->taint_logged)); fprintf(f, "service-watchdogs=%s\n", yes_no(m->service_watchdogs)); + if (m->log_level_overridden) + fprintf(f, "log-level-override=%i\n", log_get_max_level()); + for (q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) { /* The userspace and finish timestamps only apply to the host system, hence only serialize them there */ if (in_initrd() && IN_SET(q, MANAGER_TIMESTAMP_USERSPACE, MANAGER_TIMESTAMP_FINISH)) @@ -3210,6 +3213,15 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) { else m->service_watchdogs = b; + } else if ((val = startswith(l, "log-level-override="))) { + int level; + + level = log_level_from_string(val); + if (level < 0) + log_notice("Failed to parse log-level-override value '%s', ignoring.", val); + else + manager_override_log_level(m, level); + } else if (startswith(l, "env=")) { r = deserialize_environment(&m->environment, l); if (r == -ENOMEM) @@ -4448,6 +4460,35 @@ void manager_unref_console(Manager *m) { m->no_console_output = false; /* unset no_console_output flag, since the console is definitely free now */ } +void manager_override_log_level(Manager *m, int level) { + _cleanup_free_ char *s = NULL; + assert(m); + + if (!m->log_level_overridden) { + m->original_log_level = log_get_max_level(); + m->log_level_overridden = true; + } + + (void) log_level_to_string_alloc(level, &s); + log_info("Setting log level to %s.", strna(s)); + + log_set_max_level(level); +} + +void manager_restore_original_log_level(Manager *m) { + _cleanup_free_ char *s = NULL; + assert(m); + + if (!m->log_level_overridden) + return; + + (void) log_level_to_string_alloc(m->original_log_level, &s); + log_info("Restoring log level to original (%s).", strna(s)); + + log_set_max_level(m->original_log_level); + m->log_level_overridden = false; +} + static const char *const manager_state_table[_MANAGER_STATE_MAX] = { [MANAGER_INITIALIZING] = "initializing", [MANAGER_STARTING] = "starting", |