mirror of
https://github.com/systemd/systemd.git
synced 2024-12-01 06:13:38 +08:00
journal: when iterating through entry arrays and we hit an invalid one keep going
When iterating through partially synced journal files we need to be prepared
for hitting with invalid entries (specifically: non-initialized). Instead of
generated an error and giving up, let's simply try to preceed with the next one
that is valid (and debug log about this).
This reworks the logic introduced with caeab8f626
to iteration in both directions, and tries to look for valid entries located
after the invalid one. It also extends the behaviour to both iterating through
the global entry array and per-data object entry arrays.
Fixes: #4088
This commit is contained in:
parent
1c69f0966a
commit
989793d341
@ -2555,18 +2555,24 @@ int journal_file_next_entry(
|
||||
}
|
||||
|
||||
/* And jump to it */
|
||||
r = generic_array_get(f,
|
||||
le64toh(f->header->entry_array_offset),
|
||||
i,
|
||||
ret, &ofs);
|
||||
if (r == -EBADMSG && direction == DIRECTION_DOWN) {
|
||||
/* Special case: when we iterate throught the journal file linearly, and hit an entry we can't read,
|
||||
* consider this the end of the journal file. */
|
||||
log_debug_errno(r, "Encountered entry we can't read while iterating through journal file. Considering this the end of the file.");
|
||||
return 0;
|
||||
for (;;) {
|
||||
r = generic_array_get(f,
|
||||
le64toh(f->header->entry_array_offset),
|
||||
i,
|
||||
ret, &ofs);
|
||||
if (r > 0)
|
||||
break;
|
||||
if (r != -EBADMSG)
|
||||
return r;
|
||||
|
||||
/* OK, so this entry is borked. Most likely some entry didn't get synced to disk properly, let's see if
|
||||
* the next one might work for us instead. */
|
||||
log_debug_errno(r, "Entry item %" PRIu64 " is bad, skipping over it.", i);
|
||||
|
||||
r = bump_array_index(&i, direction, n);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
}
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
/* Ensure our array is properly ordered. */
|
||||
if (p > 0 && !check_properly_ordered(ofs, p, direction)) {
|
||||
@ -2588,8 +2594,8 @@ int journal_file_next_entry_for_data(
|
||||
Object **ret, uint64_t *offset) {
|
||||
|
||||
uint64_t i, n, ofs;
|
||||
int r;
|
||||
Object *d;
|
||||
int r;
|
||||
|
||||
assert(f);
|
||||
assert(p > 0 || !o);
|
||||
@ -2626,13 +2632,23 @@ int journal_file_next_entry_for_data(
|
||||
return r;
|
||||
}
|
||||
|
||||
r = generic_array_get_plus_one(f,
|
||||
le64toh(d->data.entry_offset),
|
||||
le64toh(d->data.entry_array_offset),
|
||||
i,
|
||||
ret, &ofs);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
for (;;) {
|
||||
r = generic_array_get_plus_one(f,
|
||||
le64toh(d->data.entry_offset),
|
||||
le64toh(d->data.entry_array_offset),
|
||||
i,
|
||||
ret, &ofs);
|
||||
if (r > 0)
|
||||
break;
|
||||
if (r != -EBADMSG)
|
||||
return r;
|
||||
|
||||
log_debug_errno(r, "Data entry item %" PRIu64 " is bad, skipping over it.", i);
|
||||
|
||||
r = bump_array_index(&i, direction, n);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Ensure our array is properly ordered. */
|
||||
if (p > 0 && check_properly_ordered(ofs, p, direction)) {
|
||||
|
Loading…
Reference in New Issue
Block a user