diff options
author | Lennart Poettering <lennart@poettering.net> | 2018-10-25 19:23:23 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2018-10-25 21:43:09 +0200 |
commit | 681276589159fa08e0a8a9ece6f33f34ee0e11a8 (patch) | |
tree | 7aae87f1b240782c50c2c484259f4e818fbf3026 /src/journal | |
parent | journal-file: refactor journal_file_rotate() (diff) | |
download | systemd-681276589159fa08e0a8a9ece6f33f34ee0e11a8.tar.xz systemd-681276589159fa08e0a8a9ece6f33f34ee0e11a8.zip |
journal-file: refactor journal_file_open_reliably()
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.
Diffstat (limited to 'src/journal')
-rw-r--r-- | src/journal/journal-file.c | 59 | ||||
-rw-r--r-- | src/journal/journal-file.h | 2 |
2 files changed, 42 insertions, 19 deletions
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c index 742dff980a..753b8b577f 100644 --- a/src/journal/journal-file.c +++ b/src/journal/journal-file.c @@ -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); } diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h index 570925ec27..09b7ba090d 100644 --- a/src/journal/journal-file.h +++ b/src/journal/journal-file.h @@ -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); |