summaryrefslogtreecommitdiffstats
path: root/src/journal
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2018-10-25 19:23:23 +0200
committerLennart Poettering <lennart@poettering.net>2018-10-25 21:43:09 +0200
commit681276589159fa08e0a8a9ece6f33f34ee0e11a8 (patch)
tree7aae87f1b240782c50c2c484259f4e818fbf3026 /src/journal
parentjournal-file: refactor journal_file_rotate() (diff)
downloadsystemd-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.c59
-rw-r--r--src/journal/journal-file.h2
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);