]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
journal-file: refactor journal_file_open_reliably()
authorLennart Poettering <lennart@poettering.net>
Thu, 25 Oct 2018 17:23:23 +0000 (19:23 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 25 Oct 2018 19:43:09 +0000 (21:43 +0200)
Let's split out the part that actually renames the file in case we can't
open it into a new function journal_file_dispose().

This way we can reuse the function in other cases where we want to open
a file but can't.

src/journal/journal-file.c
src/journal/journal-file.h

index 742dff980a8d79cc4a934cb9c08f93a70ca7e97d..753b8b577fd8b4cdcd605e3537d98b891a4edd9a 100644 (file)
@@ -3541,6 +3541,41 @@ int journal_file_rotate(
         return r;
 }
 
+int journal_file_dispose(int dir_fd, const char *fname) {
+        _cleanup_free_ char *p = NULL;
+        _cleanup_close_ int fd = -1;
+
+        assert(fname);
+
+        /* Renames a journal file to *.journal~, i.e. to mark it as corruped or otherwise uncleanly shutdown. Note that
+         * this is done without looking into the file or changing any of its contents. The idea is that this is called
+         * whenever something is suspicious and we want to move the file away and make clear that it is not accessed
+         * for writing anymore. */
+
+        if (!endswith(fname, ".journal"))
+                return -EINVAL;
+
+        if (asprintf(&p, "%.*s@%016" PRIx64 "-%016" PRIx64 ".journal~",
+                     (int) strlen(fname) - 8, fname,
+                     now(CLOCK_REALTIME),
+                     random_u64()) < 0)
+                return -ENOMEM;
+
+        if (renameat(dir_fd, fname, dir_fd, p) < 0)
+                return -errno;
+
+        /* btrfs doesn't cope well with our write pattern and fragments heavily. Let's defrag all files we rotate */
+        fd = openat(dir_fd, p, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
+        if (fd < 0)
+                log_debug_errno(errno, "Failed to open file for defragmentation/FS_NOCOW_FL, ignoring: %m");
+        else {
+                (void) chattr_fd(fd, 0, FS_NOCOW_FL, NULL);
+                (void) btrfs_defrag_fd(fd);
+        }
+
+        return 0;
+}
+
 int journal_file_open_reliably(
                 const char *fname,
                 int flags,
@@ -3554,9 +3589,8 @@ int journal_file_open_reliably(
                 JournalFile *template,
                 JournalFile **ret) {
 
-        int r;
-        size_t l;
         _cleanup_free_ char *p = NULL;
+        int r;
 
         r = journal_file_open(-1, fname, flags, mode, compress, compress_threshold_bytes, seal, metrics, mmap_cache,
                               deferred_closes, template, ret);
@@ -3582,25 +3616,12 @@ int journal_file_open_reliably(
                 return r;
 
         /* The file is corrupted. Rotate it away and try it again (but only once) */
-
-        l = strlen(fname);
-        if (asprintf(&p, "%.*s@%016"PRIx64 "-%016"PRIx64 ".journal~",
-                     (int) l - 8, fname,
-                     now(CLOCK_REALTIME),
-                     random_u64()) < 0)
-                return -ENOMEM;
-
-        if (rename(fname, p) < 0)
-                return -errno;
-
-        /* btrfs doesn't cope well with our write pattern and
-         * fragments heavily. Let's defrag all files we rotate */
-
-        (void) chattr_path(p, 0, FS_NOCOW_FL, NULL);
-        (void) btrfs_defrag(p);
-
         log_warning_errno(r, "File %s corrupted or uncleanly shut down, renaming and replacing.", fname);
 
+        r = journal_file_dispose(AT_FDCWD, fname);
+        if (r < 0)
+                return r;
+
         return journal_file_open(-1, fname, flags, mode, compress, compress_threshold_bytes, seal, metrics, mmap_cache,
                                  deferred_closes, template, ret);
 }
index 570925ec27993979aec38c9122367664ecf020cd..09b7ba090d3cd7a484b7e0e0a20cace2b32bd779 100644 (file)
@@ -239,6 +239,8 @@ int journal_file_archive(JournalFile *f);
 JournalFile* journal_initiate_close(JournalFile *f, Set *deferred_closes);
 int journal_file_rotate(JournalFile **f, bool compress, uint64_t compress_threshold_bytes, bool seal, Set *deferred_closes);
 
+int journal_file_dispose(int dir_fd, const char *fname);
+
 void journal_file_post_change(JournalFile *f);
 int journal_file_enable_post_change_timer(JournalFile *f, sd_event *e, usec_t t);