]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
journald-kmsg: fix reopening /dev/kmsg
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 13 Jul 2025 14:24:08 +0000 (23:24 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 18 Jul 2025 06:27:37 +0000 (15:27 +0900)
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.

src/journal/journald-config.c
src/journal/journald-kmsg.c
src/journal/journald-kmsg.h

index 42245bf8d0d1cdf8446ac10ff3c8b8b1ab8959ff..a2275a173ef1aad41e375a1badb9393430479389 100644 (file)
@@ -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)
index 1344397cb848e5346a2c818376d76009528bd671..855839113b7a46a93da62ee365a0f0ac782686e4 100644 (file)
@@ -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);
 }
index 5429e9adcd7acc1fe168be094e026c8742af8282..5c2eb1a5d24d7bfdc9f4fe33eb723c170f43160c 100644 (file)
@@ -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);