journal: if we encounter a corrupted file, rotate and go on
This commit is contained in:
parent
4d1c38b807
commit
9447a7f1de
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue