RFE: journal: automatically rotate the file if it is unlinked (#1171719)
This commit is contained in:
parent
b53cf7b99c
commit
f524b4a4be
216
0002-journald-when-we-detect-the-journal-file-we-are-abou.patch
Normal file
216
0002-journald-when-we-detect-the-journal-file-we-are-abou.patch
Normal file
@ -0,0 +1,216 @@
|
||||
From 8ea1f4267bae6b37a4a4d474aec2692a4d211621 Mon Sep 17 00:00:00 2001
|
||||
From: Fedora systemd team <systemd-maint@redhat.com>
|
||||
Date: Wed, 7 Jan 2015 13:34:02 +0100
|
||||
Subject: [PATCH] journald: when we detect the journal file we are about to
|
||||
write to has been deleted, rotate
|
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1171719
|
||||
|
||||
(cherry-picked from 2678031a179a9b91fc799f8ef951a548c66c4b49)
|
||||
---
|
||||
src/journal/journal-file.c | 65 ++++++++++++++++++++++++++++++----------
|
||||
src/journal/journal-file.h | 1 +
|
||||
src/journal/journald-server.c | 6 +++-
|
||||
src/journal/test-journal-flush.c | 3 +-
|
||||
4 files changed, 57 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
|
||||
index c5d2d19..a99265b 100644
|
||||
--- a/src/journal/journal-file.c
|
||||
+++ b/src/journal/journal-file.c
|
||||
@@ -68,6 +68,9 @@
|
||||
/* How much to increase the journal file size at once each time we allocate something new. */
|
||||
#define FILE_SIZE_INCREASE (8ULL*1024ULL*1024ULL) /* 8MB */
|
||||
|
||||
+/* Reread fstat() of the file for detecting deletions at least this often */
|
||||
+#define LAST_STAT_REFRESH_USEC (5*USEC_PER_SEC)
|
||||
+
|
||||
static int journal_file_set_online(JournalFile *f) {
|
||||
assert(f);
|
||||
|
||||
@@ -312,6 +315,22 @@ static int journal_file_verify_header(JournalFile *f) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int journal_file_fstat(JournalFile *f) {
|
||||
+ assert(f);
|
||||
+ assert(f->fd >= 0);
|
||||
+
|
||||
+ if (fstat(f->fd, &f->last_stat) < 0)
|
||||
+ return -errno;
|
||||
+
|
||||
+ f->last_stat_usec = now(CLOCK_MONOTONIC);
|
||||
+
|
||||
+ /* Refuse appending to files that are already deleted */
|
||||
+ if (f->last_stat.st_nlink <= 0)
|
||||
+ return -EIDRM;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int journal_file_allocate(JournalFile *f, uint64_t offset, uint64_t size) {
|
||||
uint64_t old_size, new_size;
|
||||
int r;
|
||||
@@ -330,8 +349,21 @@ static int journal_file_allocate(JournalFile *f, uint64_t offset, uint64_t size)
|
||||
if (new_size < le64toh(f->header->header_size))
|
||||
new_size = le64toh(f->header->header_size);
|
||||
|
||||
- if (new_size <= old_size)
|
||||
- return 0;
|
||||
+ if (new_size <= old_size) {
|
||||
+
|
||||
+ /* We already pre-allocated enough space, but before
|
||||
+ * we write to it, let's check with fstat() if the
|
||||
+ * file got deleted, in order make sure we don't throw
|
||||
+ * away the data immediately. Don't check fstat() for
|
||||
+ * all writes though, but only once ever 10s. */
|
||||
+
|
||||
+ if (f->last_stat_usec + LAST_STAT_REFRESH_USEC > now(CLOCK_MONOTONIC))
|
||||
+ return 0;
|
||||
+
|
||||
+ return journal_file_fstat(f);
|
||||
+ }
|
||||
+
|
||||
+ /* Allocate more space. */
|
||||
|
||||
if (f->metrics.max_size > 0 && new_size > f->metrics.max_size)
|
||||
return -E2BIG;
|
||||
@@ -366,15 +398,14 @@ static int journal_file_allocate(JournalFile *f, uint64_t offset, uint64_t size)
|
||||
if (r != 0)
|
||||
return -r;
|
||||
|
||||
- if (fstat(f->fd, &f->last_stat) < 0)
|
||||
- return -errno;
|
||||
-
|
||||
f->header->arena_size = htole64(new_size - le64toh(f->header->header_size));
|
||||
|
||||
- return 0;
|
||||
+ return journal_file_fstat(f);
|
||||
}
|
||||
|
||||
static int journal_file_move_to(JournalFile *f, int context, bool keep_always, uint64_t offset, uint64_t size, void **ret) {
|
||||
+ int r;
|
||||
+
|
||||
assert(f);
|
||||
assert(ret);
|
||||
|
||||
@@ -386,8 +417,11 @@ static int journal_file_move_to(JournalFile *f, int context, bool keep_always, u
|
||||
/* Hmm, out of range? Let's refresh the fstat() data
|
||||
* first, before we trust that check. */
|
||||
|
||||
- if (fstat(f->fd, &f->last_stat) < 0 ||
|
||||
- offset + size > (uint64_t) f->last_stat.st_size)
|
||||
+ r = journal_file_fstat(f);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ if (offset + size > (uint64_t) f->last_stat.st_size)
|
||||
return -EADDRNOTAVAIL;
|
||||
}
|
||||
|
||||
@@ -2511,10 +2545,9 @@ int journal_file_open(
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- if (fstat(f->fd, &f->last_stat) < 0) {
|
||||
- r = -errno;
|
||||
+ r = journal_file_fstat(f);
|
||||
+ if (r < 0)
|
||||
goto fail;
|
||||
- }
|
||||
|
||||
if (f->last_stat.st_size == 0 && f->writable) {
|
||||
uint64_t crtime;
|
||||
@@ -2546,10 +2579,9 @@ int journal_file_open(
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
- if (fstat(f->fd, &f->last_stat) < 0) {
|
||||
- r = -errno;
|
||||
+ r = journal_file_fstat(f);
|
||||
+ if (r < 0)
|
||||
goto fail;
|
||||
- }
|
||||
|
||||
newly_created = true;
|
||||
}
|
||||
@@ -2657,8 +2689,11 @@ int journal_file_rotate(JournalFile **f, bool compress, bool seal) {
|
||||
if (r < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
+ /* Try to rename the file to the archived version. If the file
|
||||
+ * already was deleted, we'll get ENOENT, let's ignore that
|
||||
+ * case. */
|
||||
r = rename(old_file->path, p);
|
||||
- if (r < 0)
|
||||
+ if (r < 0 && errno != ENOENT)
|
||||
return -errno;
|
||||
|
||||
old_file->header->state = STATE_ARCHIVED;
|
||||
diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h
|
||||
index 211e121..15f1301 100644
|
||||
--- a/src/journal/journal-file.h
|
||||
+++ b/src/journal/journal-file.h
|
||||
@@ -66,6 +66,7 @@ typedef struct JournalFile {
|
||||
|
||||
char *path;
|
||||
struct stat last_stat;
|
||||
+ usec_t last_stat_usec;
|
||||
|
||||
Header *header;
|
||||
HashItem *data_hash_table;
|
||||
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
|
||||
index 80c9736..24c4d3c 100644
|
||||
--- a/src/journal/journald-server.c
|
||||
+++ b/src/journal/journald-server.c
|
||||
@@ -315,6 +315,7 @@ static int do_rotate(Server *s, JournalFile **f, const char* name,
|
||||
name);
|
||||
else
|
||||
server_fix_perms(s, *f, uid);
|
||||
+
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -457,7 +458,8 @@ bool shall_try_append_again(JournalFile *f, int r) {
|
||||
-EPROTONOSUPPORT Unsupported feature
|
||||
-EBADMSG Corrupted
|
||||
-ENODATA Truncated
|
||||
- -ESHUTDOWN Already archived */
|
||||
+ -ESHUTDOWN Already archived
|
||||
+ -EIDRM Journal file has been deleted */
|
||||
|
||||
if (r == -E2BIG || r == -EFBIG || r == -EDQUOT || r == -ENOSPC)
|
||||
log_debug("%s: Allocation limit reached, rotating.", f->path);
|
||||
@@ -469,6 +471,8 @@ bool shall_try_append_again(JournalFile *f, int r) {
|
||||
log_info("%s: Unsupported feature, rotating.", f->path);
|
||||
else if (r == -EBADMSG || r == -ENODATA || r == ESHUTDOWN)
|
||||
log_warning("%s: Journal file corrupted, rotating.", f->path);
|
||||
+ else if (r == -EIDRM)
|
||||
+ log_warning("%s: Journal file has been deleted, rotating.", f->path);
|
||||
else
|
||||
return false;
|
||||
|
||||
diff --git a/src/journal/test-journal-flush.c b/src/journal/test-journal-flush.c
|
||||
index 0ca24e0..40ede4a 100644
|
||||
--- a/src/journal/test-journal-flush.c
|
||||
+++ b/src/journal/test-journal-flush.c
|
||||
@@ -39,8 +39,6 @@ int main(int argc, char *argv[]) {
|
||||
r = journal_file_open(fn, O_CREAT|O_RDWR, 0644, false, false, NULL, NULL, NULL, &new_journal);
|
||||
assert_se(r >= 0);
|
||||
|
||||
- unlink(fn);
|
||||
-
|
||||
r = sd_journal_open(&j, 0);
|
||||
assert_se(r >= 0);
|
||||
|
||||
@@ -68,6 +66,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
journal_file_close(new_journal);
|
||||
|
||||
+ unlink(fn);
|
||||
assert_se(rmdir(dn) == 0);
|
||||
|
||||
return 0;
|
||||
--
|
||||
2.2.0
|
||||
|
@ -42,6 +42,7 @@ Source8: systemd-journal-gatewayd.xml
|
||||
# GIT_DIR=~/src/systemd/.git git format-patch-ab -M -N --no-signature v218..v218-stable
|
||||
# i=1; for p in 0*patch;do printf "Patch%04d: %s\n" $i $p; ((i++));done
|
||||
Patch0001: 0001-nspawn-fix-invocation-of-the-raw-clone-system-call-o.patch
|
||||
Patch0002: 0002-journald-when-we-detect-the-journal-file-we-are-abou.patch
|
||||
|
||||
Patch0998: fedora-disable-resolv.conf-symlink.patch
|
||||
Patch0999: fedora-add-bridge-sysctl-configuration.patch
|
||||
@ -848,6 +849,9 @@ getent passwd systemd-journal-upload >/dev/null 2>&1 || useradd -r -l -g systemd
|
||||
/usr/lib/firewalld/services/*
|
||||
|
||||
%changelog
|
||||
* Wed Jan 7 2015 Jan Synáček <jsynacek@redhat.com> - 218-3
|
||||
- RFE: journal: automatically rotate the file if it is unlinked (#1171719)
|
||||
|
||||
* Mon Jan 05 2015 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 218-3
|
||||
- Add firewall description files (#1176626)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user