From: Yu Watanabe Date: Sun, 13 Jul 2025 14:24:08 +0000 (+0900) Subject: journald-kmsg: fix reopening /dev/kmsg X-Git-Tag: v258-rc1~34^2~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7bc133fe5628c9decc7c768d2ab189eb5b308398;p=thirdparty%2Fsystemd.git journald-kmsg: fix reopening /dev/kmsg The previous logic was completely broken: - the access mode comparison is broken, - flushing kmsg did not work, as the configuration is already disabled, - seqnum file is not opened when previously disabled, - failure in reopening /dev/kmsg should not be critical. This fixes the above issues. --- diff --git a/src/journal/journald-config.c b/src/journal/journald-config.c index 42245bf8d0d..a2275a173ef 100644 --- a/src/journal/journald-config.c +++ b/src/journal/journald-config.c @@ -359,11 +359,11 @@ int manager_dispatch_reload_signal(sd_event_source *s, const struct signalfd_sig (void) notify_reloading(); + _cleanup_(journal_config_done) JournalConfig old = TAKE_STRUCT(m->config); + manager_reload_config(m); - r = manager_reload_dev_kmsg(m); - if (r < 0) - return r; + (void) manager_reopen_dev_kmsg(m, old.read_kmsg); r = manager_reload_journals(m); if (r < 0) diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c index 1344397cb84..855839113b7 100644 --- a/src/journal/journald-kmsg.c +++ b/src/journal/journald-kmsg.c @@ -451,32 +451,46 @@ void manager_close_kernel_seqnum(Manager *m) { m->kernel_seqnum = NULL; } -int manager_reload_dev_kmsg(Manager *m) { +static int manager_unlink_kernel_seqnum(Manager *m) { + assert(m); + assert(!m->kernel_seqnum); /* The file must not be mmap()ed. */ + + return manager_unlink_seqnum_file(m, "kernel-seqnum"); +} + +int manager_reopen_dev_kmsg(Manager *m, bool old_read_kmsg) { int r; assert(m); - /* Check if the fd has not yet been initialized. If so, open /dev/kmsg. */ + /* If the fd has not yet been initialized, let's shortcut and simply open /dev/kmsg. */ if (m->dev_kmsg_fd < 0) return manager_open_dev_kmsg(m); - mode_t mode = manager_kmsg_mode(m->config.read_kmsg); - int flags = fcntl(m->dev_kmsg_fd, F_GETFL); - if (flags < 0) - /* Proceed with reload in case the flags have changed. */ - log_warning_errno(errno, "Failed to get flags for /dev/kmsg, ignoring: %m"); - else if ((flags & O_ACCMODE_STRICT) == mode) - /* Mode is the same. No-op. */ - return 0; + if (m->config.read_kmsg == old_read_kmsg) + return 0; /* Setting is unchanged. */ - /* Flush kmsg. */ - r = manager_flush_dev_kmsg(m); - if (r < 0) - log_warning_errno(r, "Failed to flush /dev/kmsg on reload, ignoring: %m"); + if (!m->config.read_kmsg) { + /* If reading kmsg was enabled but now disable, let's flush the buffer before disabling it. */ + m->config.read_kmsg = true; + (void) manager_flush_dev_kmsg(m); + m->config.read_kmsg = false; + + /* seqnum file is not necessary anymore. Let's close it. */ + manager_close_kernel_seqnum(m); + + /* Also, unlink the file name as we will not warn some kmsg are lost when reading kmsg is + * re-enabled later. */ + manager_unlink_kernel_seqnum(m); + } - /* Set kmsg values to default. */ + /* Close previously configured event source and opened file descriptor. */ m->dev_kmsg_event_source = sd_event_source_disable_unref(m->dev_kmsg_event_source); m->dev_kmsg_fd = safe_close(m->dev_kmsg_fd); - return manager_open_dev_kmsg(m); + r = manager_open_dev_kmsg(m); + if (r < 0) + return r; + + return manager_open_kernel_seqnum(m); } diff --git a/src/journal/journald-kmsg.h b/src/journal/journald-kmsg.h index 5429e9adcd7..5c2eb1a5d24 100644 --- a/src/journal/journald-kmsg.h +++ b/src/journal/journald-kmsg.h @@ -5,7 +5,7 @@ int manager_open_dev_kmsg(Manager *m); int manager_flush_dev_kmsg(Manager *m); -int manager_reload_dev_kmsg(Manager *m); +int manager_reopen_dev_kmsg(Manager *m, bool old_read_kmsg); void manager_forward_kmsg(Manager *m, int priority, const char *identifier, const char *message, const struct ucred *ucred);