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