summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2013-06-24 21:00:28 -0400
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2013-06-24 21:06:06 -0400
commit9d64774057400ee15e7ffb159294f73bb665eb84 (patch)
tree569b7730f8146a78abb45481bde6813e2990fc56 /src
parent670b110c3b59dfa335ac43065b2038400d1d04a9 (diff)
journald: always vacuum empty offline files
Corrupted empty files are relatively common. I think they are created when a coredump for a user who never logged anything before is attempted to be written, but the write does not succeed because the coredump is too big, but there are probably other ways to create those, especially if the machine crashes at the right time. Non-corrupted empty files can also happen, e.g. if a journal file is opened, but nothing is ever successfully written to it and it is rotated because of MaxFileSec=. Either way, each "empty" journal file costs around 3 MB, and there's little point in keeping them around.
Diffstat (limited to 'src')
-rw-r--r--src/journal/journal-vacuum.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/journal/journal-vacuum.c b/src/journal/journal-vacuum.c
index 1ddb043e2c..79572f1fb6 100644
--- a/src/journal/journal-vacuum.c
+++ b/src/journal/journal-vacuum.c
@@ -128,6 +128,24 @@ static void patch_realtime(
#endif
}
+static int journal_file_empty(int dir_fd, const char *name) {
+ int fd, r;
+ le64_t n_entries;
+
+ fd = openat(dir_fd, name, O_RDONLY|O_CLOEXEC|O_NOFOLLOW|O_NONBLOCK);
+ if (fd < 0)
+ return -errno;
+
+ if (lseek(fd, offsetof(Header, n_entries), SEEK_SET) < 0)
+ return -errno;
+
+ r = read(fd, &n_entries, sizeof(n_entries));
+ if (r != sizeof(n_entries))
+ return r == 0 ? -EINVAL : -errno;
+
+ return le64toh(n_entries) == 0;
+}
+
int journal_directory_vacuum(
const char *directory,
uint64_t max_use,
@@ -247,6 +265,17 @@ int journal_directory_vacuum(
/* We do not vacuum active files or unknown files! */
continue;
+ if (journal_file_empty(dirfd(d), de->d_name)) {
+
+ /* Always vacuum empty non-online files. */
+
+ if (unlinkat(dirfd(d), de->d_name, 0) >= 0)
+ log_debug("Deleted empty journal %s/%s.", directory, de->d_name);
+ else if (errno != ENOENT)
+ log_warning("Failed to delete %s/%s: %m", directory, de->d_name);
+ continue;
+ }
+
patch_realtime(directory, de->d_name, &st, &realtime);
GREEDY_REALLOC(list, n_allocated, n_list + 1);