]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
journald: also remove runtime journal directories with a different machine ID
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 3 Dec 2023 12:56:26 +0000 (21:56 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 4 Dec 2023 06:14:25 +0000 (15:14 +0900)
Otherwise, even if the journal files in the directories are flushed to
the persistent storage, still they are opened by e.g. journalctl, and it
may show duplicated entries.
Also, the journal files may be flushed to the persistent storage more
than once.

src/journal/journald-server.c
src/libsystemd/sd-journal/journal-internal.h
src/libsystemd/sd-journal/sd-journal.c

index d7c8095d7954fb34081c58db95a62d533a51f16d..cfa4b5ffbfb9d9dc1bb6253c3485d39c3f4e5043 100644 (file)
@@ -1353,6 +1353,10 @@ finish:
         if (s->system_journal)
                 journal_file_post_change(s->system_journal);
 
+        /* Save parent directories of runtime journals before closing runtime journals. */
+        _cleanup_strv_free_ char **dirs = NULL;
+        (void) journal_get_directories(j, &dirs);
+
         /* First, close all runtime journals opened in the above. */
         sd_journal_close(j);
 
@@ -1360,9 +1364,19 @@ finish:
         s->runtime_journal = journal_file_offline_close(s->runtime_journal);
 
         /* Remove the runtime directory if the all entries are successfully flushed to /var/. */
-        if (r >= 0)
+        if (r >= 0) {
                 (void) rm_rf(s->runtime_storage.path, REMOVE_ROOT);
 
+                /* The initrd may have a different machine ID from the host's one. Typically, that happens
+                 * when our tests running on qemu, as the host's initrd is picked as is without updating
+                 * the machine ID in the initrd with the one used in the image. Even in such the case, the
+                 * runtime journals in the subdirectory named with the initrd's machine ID are flushed to
+                 * the persistent journal. To make not the runtime journal flushed multiple times, let's
+                 * also remove the runtime directories. */
+                STRV_FOREACH(p, dirs)
+                        (void) rm_rf(*p, REMOVE_ROOT);
+        }
+
         server_driver_message(s, 0, NULL,
                               LOG_MESSAGE("Time spent on flushing to %s is %s for %u entries.",
                                           s->system_storage.path,
index 259aac847d6645488960b41901657d7c1ae26636..85d5d32f9659a34aeb6398ab62af043d1fbcbd24 100644 (file)
@@ -128,6 +128,7 @@ struct sd_journal {
 
 char *journal_make_match_string(sd_journal *j);
 void journal_print_header(sd_journal *j);
+int journal_get_directories(sd_journal *j, char ***ret);
 
 #define JOURNAL_FOREACH_DATA_RETVAL(j, data, l, retval)                     \
         for (sd_journal_restart_data(j); ((retval) = sd_journal_enumerate_data((j), &(data), &(l))) > 0; )
index 6b9ff0a4ed880557b940a9d37b79ca88119c6b6b..6e33c06d634fb574da73d16f556f91228ce09379 100644 (file)
@@ -1494,6 +1494,41 @@ error:
         return r;
 }
 
+int journal_get_directories(sd_journal *j, char ***ret) {
+        _cleanup_strv_free_ char **paths = NULL;
+        JournalFile *f;
+        const char *p;
+        size_t n = SIZE_MAX;
+        int r;
+
+        assert(j);
+        assert(ret);
+
+        /* This returns parent directories of opened journal files. */
+
+        ORDERED_HASHMAP_FOREACH_KEY(f, p, j->files) {
+                _cleanup_free_ char *d = NULL;
+
+                /* Ignore paths generated from fd. */
+                if (path_startswith(p, "/proc/"))
+                        continue;
+
+                r = path_extract_directory(p, &d);
+                if (r < 0)
+                        return r;
+
+                if (path_strv_contains(paths, d))
+                        continue;
+
+                r = strv_extend_with_size(&paths, &n, d);
+                if (r < 0)
+                        return r;
+        }
+
+        *ret = TAKE_PTR(paths);
+        return 0;
+}
+
 static int add_file_by_name(
                 sd_journal *j,
                 const char *prefix,