summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/journal/journal-file.c43
-rw-r--r--src/journal/journal-file.h2
-rw-r--r--src/journal/journald.c24
3 files changed, 58 insertions, 11 deletions
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index 8c17620ed3..1e6d78cfa4 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -1727,6 +1727,9 @@ int journal_file_open(
(flags & O_ACCMODE) != O_RDWR)
return -EINVAL;
+ if (!endswith(fname, ".journal"))
+ return -EINVAL;
+
f = new0(JournalFile, 1);
if (!f)
return -ENOMEM;
@@ -1840,7 +1843,7 @@ int journal_file_rotate(JournalFile **f) {
l = strlen(old_file->path);
- p = new(char, l + 1 + 16 + 1 + 32 + 1 + 16 + 1);
+ p = new(char, l + 1 + 32 + 1 + 16 + 1 + 16 + 1);
if (!p)
return -ENOMEM;
@@ -1867,6 +1870,44 @@ int journal_file_rotate(JournalFile **f) {
return r;
}
+int journal_file_open_reliably(
+ const char *fname,
+ int flags,
+ mode_t mode,
+ JournalFile *template,
+ JournalFile **ret) {
+
+ int r;
+ size_t l;
+ char *p;
+
+ r = journal_file_open(fname, flags, mode, template, ret);
+ if (r != -EBADMSG)
+ return r;
+
+ if ((flags & O_ACCMODE) == O_RDONLY)
+ return r;
+
+ if (!(flags & O_CREAT))
+ return r;
+
+ l = strlen(fname);
+ if (asprintf(&p, "%.*s@%016llx-%016llx.journal~",
+ (int) (l-8), fname,
+ (unsigned long long) now(CLOCK_REALTIME),
+ random_ull()) < 0)
+ return -ENOMEM;
+
+ r = rename(fname, p);
+ free(p);
+ if (r < 0)
+ return -errno;
+
+ log_warning("File %s corrupted, renaming and replacing.", fname);
+
+ return journal_file_open(fname, flags, mode, template, ret);
+}
+
struct vacuum_info {
off_t usage;
char *filename;
diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h
index 4ef4a14479..4d6e140771 100644
--- a/src/journal/journal-file.h
+++ b/src/journal/journal-file.h
@@ -89,6 +89,8 @@ typedef enum direction {
int journal_file_open(const char *fname, int flags, mode_t mode, JournalFile *template, JournalFile **ret);
void journal_file_close(JournalFile *j);
+int journal_file_open_reliably(const char *fname, int flags, mode_t mode, JournalFile *template, JournalFile **ret);
+
int journal_file_move_to_object(JournalFile *f, int type, uint64_t offset, Object **ret);
uint64_t journal_file_entry_n_items(Object *o);
diff --git a/src/journal/journald.c b/src/journal/journald.c
index 37e6484f4b..e9ac897de7 100644
--- a/src/journal/journald.c
+++ b/src/journal/journald.c
@@ -301,7 +301,7 @@ static JournalFile* find_journal(Server *s, uid_t uid) {
journal_file_close(f);
}
- r = journal_file_open(p, O_RDWR|O_CREAT, 0640, s->system_journal, &f);
+ r = journal_file_open_reliably(p, O_RDWR|O_CREAT, 0640, s->system_journal, &f);
free(p);
if (r < 0)
@@ -604,8 +604,12 @@ retry:
else {
r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL);
- if (r == -E2BIG && !vacuumed) {
- log_info("Allocation limit reached.");
+ if ((r == -EBADMSG || r == -E2BIG) && !vacuumed) {
+
+ if (r == -E2BIG)
+ log_info("Allocation limit reached, rotating.");
+ else
+ log_warning("Journal file corrupted, rotating.");
server_rotate(s);
server_vacuum(s);
@@ -1875,7 +1879,7 @@ static int system_journal_open(Server *s) {
if (!fn)
return -ENOMEM;
- r = journal_file_open(fn, O_RDWR|O_CREAT, 0640, NULL, &s->system_journal);
+ r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, NULL, &s->system_journal);
free(fn);
if (r >= 0) {
@@ -1906,7 +1910,7 @@ static int system_journal_open(Server *s) {
* if it already exists, so that we can flush
* it into the system journal */
- r = journal_file_open(fn, O_RDWR, 0640, NULL, &s->runtime_journal);
+ r = journal_file_open_reliably(fn, O_RDWR, 0640, NULL, &s->runtime_journal);
free(fn);
if (r < 0) {
@@ -1922,7 +1926,7 @@ static int system_journal_open(Server *s) {
* it if necessary. */
(void) mkdir_parents(fn, 0755);
- r = journal_file_open(fn, O_RDWR|O_CREAT, 0640, NULL, &s->runtime_journal);
+ r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, NULL, &s->runtime_journal);
free(fn);
if (r < 0) {
@@ -2666,10 +2670,6 @@ static int server_init(Server *s) {
if (r < 0)
return r;
- r = system_journal_open(s);
- if (r < 0)
- return r;
-
r = open_signalfd(s);
if (r < 0)
return r;
@@ -2678,6 +2678,10 @@ static int server_init(Server *s) {
if (!s->rate_limit)
return -ENOMEM;
+ r = system_journal_open(s);
+ if (r < 0)
+ return r;
+
return 0;
}