]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
shutdown: Bump sysctl kernel.printk log level in order to see info msg
authorBenjamin Robin <dev@benjarobin.fr>
Wed, 3 Apr 2019 19:00:01 +0000 (21:00 +0200)
committerBenjamin Robin <dev@benjarobin.fr>
Wed, 10 Apr 2019 17:27:38 +0000 (19:27 +0200)
src/shutdown/shutdown.c

index 842ba57f1306f466a8624fb065e7bac482c62b75..25a538df5098495f3472ed141ad0ba2795b51f78 100644 (file)
@@ -32,6 +32,7 @@
 #include "signal-util.h"
 #include "string-util.h"
 #include "switch-root.h"
+#include "sysctl-util.h"
 #include "terminal-util.h"
 #include "umount.h"
 #include "util.h"
@@ -255,6 +256,42 @@ static void sync_with_progress(void) {
         (void) kill(pid, SIGKILL);
 }
 
+static int read_current_sysctl_printk_log_level(void) {
+        _cleanup_free_ char *sysctl_printk_vals = NULL, *sysctl_printk_curr = NULL;
+        unsigned current_lvl = 0;
+        const char *p;
+        int r;
+
+        r = sysctl_read("kernel/printk", &sysctl_printk_vals);
+        if (r < 0)
+                return log_debug_errno(r, "Cannot read sysctl kernel.printk: %m");
+
+        p = sysctl_printk_vals;
+        r = extract_first_word(&p, &sysctl_printk_curr, NULL, 0);
+        if (r > 0)
+                r = safe_atou(sysctl_printk_curr, &current_lvl);
+        else if (r == 0)
+                r = -EINVAL;
+
+        if (r < 0)
+                return log_debug_errno(r, "Unexpected sysctl kernel.printk content: %s", sysctl_printk_vals);
+
+        return current_lvl;
+}
+
+static void bump_sysctl_printk_log_level(int min_level) {
+        /* Set the logging level to be able to see messages with log level smaller or equal to min_level */
+
+        int current_lvl = read_current_sysctl_printk_log_level();
+        if (current_lvl >= 0 && current_lvl <= min_level) {
+                char buf[DECIMAL_STR_MAX(int)];
+                xsprintf(buf, "%d", min_level + 1);
+                int r = sysctl_write("kernel/printk", buf);
+                if (r < 0)
+                        log_debug_errno(r, "Failed to bump kernel.printk to %s: %m", buf);
+        }
+}
+
 int main(int argc, char *argv[]) {
         bool need_umount, need_swapoff, need_loop_detach, need_dm_detach;
         bool in_container, use_watchdog = false, can_initrd;
@@ -305,6 +342,16 @@ int main(int argc, char *argv[]) {
         (void) cg_get_root_path(&cgroup);
         in_container = detect_container() > 0;
 
+        /* If the logging messages are going to KMSG, and if we are not running from a container,
+         * then try to update the sysctl kernel.printk current value in order to see "info" messages;
+         * This current log level is not updated if already big enough.
+         */
+        if (!in_container && IN_SET(log_get_target(), LOG_TARGET_AUTO,
+                                                      LOG_TARGET_JOURNAL_OR_KMSG,
+                                                      LOG_TARGET_SYSLOG_OR_KMSG,
+                                                      LOG_TARGET_KMSG))
+                bump_sysctl_printk_log_level(LOG_INFO);
+
         use_watchdog = getenv("WATCHDOG_USEC");
         watchdog_device = getenv("WATCHDOG_DEVICE");
         if (watchdog_device) {