diff --git a/docs/JOURNAL_FILE_FORMAT.md b/docs/JOURNAL_FILE_FORMAT.md index 712f3bce36..ede9d923a4 100644 --- a/docs/JOURNAL_FILE_FORMAT.md +++ b/docs/JOURNAL_FILE_FORMAT.md @@ -178,8 +178,10 @@ _packed_ struct Header { le64_t data_hash_chain_depth; le64_t field_hash_chain_depth; /* Added in 252 */ - le32_t tail_entry_array_offset; \ - le32_t tail_entry_array_n_entries; \ + le32_t tail_entry_array_offset; + le32_t tail_entry_array_n_entries; + /* Added in 254 */ + le64_t tail_entry_offset; }; ``` @@ -252,6 +254,9 @@ field hash table, minus one. **tail_entry_array_offset** and **tail_entry_array_n_entries** allow immediate access to the last entry array in the global entry array chain. +**tail_entry_offset** allow immediate access to the last entry in the journal +file. + ## Extensibility The format is supposed to be extensible in order to enable future additions of diff --git a/src/libsystemd/sd-journal/journal-def.h b/src/libsystemd/sd-journal/journal-def.h index fb22fc45f3..2f048c0198 100644 --- a/src/libsystemd/sd-journal/journal-def.h +++ b/src/libsystemd/sd-journal/journal-def.h @@ -239,12 +239,14 @@ enum { /* Added in 252 */ \ le32_t tail_entry_array_offset; \ le32_t tail_entry_array_n_entries; \ + /* Added in 254 */ \ + le64_t tail_entry_offset; \ } struct Header struct_Header__contents; struct Header__packed struct_Header__contents _packed_; assert_cc(sizeof(struct Header) == sizeof(struct Header__packed)); -assert_cc(sizeof(struct Header) == 264); +assert_cc(sizeof(struct Header) == 272); #define FSS_HEADER_SIGNATURE \ ((const char[]) { 'K', 'S', 'H', 'H', 'R', 'H', 'L', 'P' }) diff --git a/src/libsystemd/sd-journal/journal-file.c b/src/libsystemd/sd-journal/journal-file.c index e6b31d4e7c..e92e351809 100644 --- a/src/libsystemd/sd-journal/journal-file.c +++ b/src/libsystemd/sd-journal/journal-file.c @@ -505,6 +505,11 @@ static int journal_file_verify_header(JournalFile *f) { !VALID64(le64toh(f->header->entry_array_offset))) return -ENODATA; + if (JOURNAL_HEADER_CONTAINS(f->header, tail_entry_offset) && + le64toh(f->header->tail_entry_offset) != 0 && + !VALID64(le64toh(f->header->tail_entry_offset))) + return -ENODATA; + if (journal_file_writable(f)) { sd_id128_t machine_id; uint8_t state; @@ -2053,6 +2058,7 @@ static int journal_file_link_entry( f->header->tail_entry_realtime = o->entry.realtime; f->header->tail_entry_monotonic = o->entry.monotonic; + f->header->tail_entry_offset = offset; /* Link up the items */ for (uint64_t i = 0; i < n_items; i++) {