From 2446472f9ac9246f2ee25a92e8ebb17c54b923bd Mon Sep 17 00:00:00 2001 From: Adrian Vovk Date: Fri, 9 May 2025 14:44:24 -0400 Subject: [PATCH 1/3] utils: Don't lose log level when silencing kmsg Once we disable kmsg logging to the console, the kernel will set the console log level to the minimum log level (i.e. only logging kernel panics). However the unintended side effect is that our own kmsg-reader will start filtering out all kernel log messages, since we also respect the kernel's console log level. This change make it so that we keep using the original console log level whenever we disable the kernel's output. This lets us keep forwarding the kernel's kmsg output --- src/libply/ply-utils.c | 79 +++++++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 32 deletions(-) diff --git a/src/libply/ply-utils.c b/src/libply/ply-utils.c index 6fa64975..782fadd8 100644 --- a/src/libply/ply-utils.c +++ b/src/libply/ply-utils.c @@ -89,6 +89,10 @@ static int overridden_device_scale = 0; static char kernel_command_line[PLY_MAX_COMMAND_LINE_SIZE]; static bool kernel_command_line_is_set; +static int cached_current_log_level = 0; +static int cached_default_log_level = 0; +static double log_level_update_time = 0.0; + bool ply_open_unidirectional_pipe (int *sender_fd, int *receiver_fd) @@ -673,20 +677,6 @@ ply_create_file_link (const char *source, return true; } -void -ply_show_new_kernel_messages (bool should_show) -{ - int type; - - if (should_show) - type = PLY_ENABLE_CONSOLE_PRINTK; - else - type = PLY_DISABLE_CONSOLE_PRINTK; - - if (klogctl (type, NULL, 0) < 0) - ply_trace ("could not toggle printk visibility: %m"); -} - ply_daemon_handle_t * ply_create_daemon (void) { @@ -1118,26 +1108,14 @@ int ply_guess_device_scale (uint32_t width, return get_device_scale (width, height, 0, 0, true); } -void -ply_get_kmsg_log_levels (int *current_log_level, - int *default_log_level) +static void +ply_get_kmsg_log_levels_uncached (int *current_log_level, + int *default_log_level) { - static double last_update_time = 0; - static int cached_current_log_level = 0; - static int cached_default_log_level = 0; char log_levels[4096] = ""; - double current_time; char *field, *fields; int fd; - current_time = ply_get_timestamp (); - - if ((current_time - last_update_time) < 1.0) { - *current_log_level = cached_current_log_level; - *default_log_level = cached_default_log_level; - return; - } - ply_trace ("opening /proc/sys/kernel/printk"); fd = open ("/proc/sys/kernel/printk", O_RDONLY); @@ -1171,11 +1149,48 @@ ply_get_kmsg_log_levels (int *current_log_level, } *default_log_level = atoi (field); +} - cached_current_log_level = *current_log_level; - cached_default_log_level = *default_log_level; +void +ply_get_kmsg_log_levels (int *current_log_level, + int *default_log_level) +{ + double current_time; + bool no_cache; + bool cache_expired; + + no_cache = cached_current_log_level == 0 || cached_default_log_level == 0; + current_time = ply_get_timestamp (); + cache_expired = log_level_update_time > 0.0 && (current_time - log_level_update_time) >= 1.0; + + if (no_cache || cache_expired) { + ply_get_kmsg_log_levels_uncached (&cached_current_log_level, &cached_default_log_level); + log_level_update_time = current_time; + } + + *current_log_level = cached_current_log_level; + *default_log_level = cached_default_log_level; +} + +void +ply_show_new_kernel_messages (bool should_show) +{ + int type; + + if (should_show) { + type = PLY_ENABLE_CONSOLE_PRINTK; + + cached_current_log_level = cached_default_log_level = 0; + log_level_update_time = 0.0; + } else { + type = PLY_DISABLE_CONSOLE_PRINTK; + + ply_get_kmsg_log_levels_uncached (&cached_current_log_level, &cached_default_log_level); + log_level_update_time = -1.0; /* Disable expiration */ + } - last_update_time = current_time; + if (klogctl (type, NULL, 0) < 0) + ply_trace ("could not toggle printk visibility: %m"); } static const char * -- GitLab From 6d7b3c3342e80f94410165c72bb2d907624e3fff Mon Sep 17 00:00:00 2001 From: Adrian Vovk Date: Fri, 9 May 2025 15:17:48 -0400 Subject: [PATCH 2/3] details: Suppress kernel's own kmsg console output Plymouth forwards /dev/console and /dev/kmsg to all consoles (and to the graphical splash). With the details plugin, we would do this without suppressing the kernel's own output first. This would lead to duplicate log entries --- src/plugins/splash/details/plugin.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/plugins/splash/details/plugin.c b/src/plugins/splash/details/plugin.c index 9e150b5c..c7674fc0 100644 --- a/src/plugins/splash/details/plugin.c +++ b/src/plugins/splash/details/plugin.c @@ -308,6 +308,8 @@ show_splash_screen (ply_boot_splash_plugin_t *plugin, detach_from_event_loop, plugin); + ply_show_new_kernel_messages (false); + if (boot_buffer) { plugin->boot_buffer = boot_buffer; @@ -350,6 +352,8 @@ hide_splash_screen (ply_boot_splash_plugin_t *plugin, detach_from_event_loop, plugin); detach_from_event_loop (plugin); + + ply_show_new_kernel_messages (true); } static void -- GitLab From a53065d0ce0b28a214b9088afc9d4d769c030d3b Mon Sep 17 00:00:00 2001 From: Adrian Vovk Date: Fri, 9 May 2025 15:35:38 -0400 Subject: [PATCH 3/3] kmsg-reader: Seek to the end of the ringbuffer Otherwise, whenever plymouth starts we'd replay all previous kmsg entries, even if they've already been logged to the console. This leads to duplicated log entires, and makes it hard to debug things. With /dev/console, we only log what we capture while Plymouth is running. Let's do the same with /dev/kmsg --- src/libply-splash-core/ply-kmsg-reader.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libply-splash-core/ply-kmsg-reader.c b/src/libply-splash-core/ply-kmsg-reader.c index 439da415..9e9de214 100644 --- a/src/libply-splash-core/ply-kmsg-reader.c +++ b/src/libply-splash-core/ply-kmsg-reader.c @@ -204,6 +204,8 @@ ply_kmsg_reader_start (ply_kmsg_reader_t *kmsg_reader) if (kmsg_reader->kmsg_fd < 0) return; + lseek (kmsg_reader->kmsg_fd, 0, SEEK_END); + kmsg_reader->fd_watch = ply_event_loop_watch_fd (ply_event_loop_get_default (), kmsg_reader->kmsg_fd, PLY_EVENT_LOOP_FD_STATUS_HAS_DATA, (ply_event_handler_t) handle_kmsg_message, NULL, -- GitLab