- The data file is broken down into transactions, which are composed of one or more records. - Atomic transactions are ensured by the initial "data flag" on each transaction. - Each transaction consists of a control header followed by zero or more records, followed by a check code. - The transaction immediately following the last one is marked as empty. - Data from multiple records may be concatenated into one transaction. - Check code is 64-bit CRC (8 bytes); polynomial is x64 + x4 + x3 + x1 + 1. File Header Format: - Constant string (8 bytes): "journald" - Version (2) - Page size (maximum of OS page size and FS block size) - First global record number - Option bytes - Option data (variable size) - Check code - NUL padding to the end of the first page Option Data: - NUL seperated list of ASCII strings? Options: - Writer concurrency Transaction Format: - Zero or more records (empty transaction marks the end of journal) - One NUL byte - NUL padding to the end of the page (should be ignored by reader) Record Format: - Record type/flags: 0xf TYPE: mask for valid type bits; all other bits are flags 0x0 EOT: end of transaction; all flags must be zero 0x1 INFO: stream information 0x2 DATA: data record for the stream 0x4 EOS: end of the records for the stream (both DATA and EOS may be set at once) 0x8 ABORT: abort record - Global record number - Stream number - Local (per-stream) record number - Record data length - Record data - Check code on all the data from the record type flag to the last byte of the record data. Stream Information Data Format: - Current stream offset - Identifier string - All record types may contain data. Data for ABORT records, and records without the DATA flag is ignored. - The global record number is a sequential marker that is incremented on each record that does not mark the end of a transaction. - The stream number is a sequential marker that starts at zero when the server starts up, and could be non-zero for the first record in the file. - The record number is a sequential marker that starts at zero for each new stream. - Possible sequences of record types within a stream: INFO DATA|EOS INFO DATA* EOS INFO DATA* ABORT - Unless otherwise noted, all the above numbers are represented as a 4-byte binary value, MSB first. - All strings are prefixed with their length - The stream information record always has a record number of zero, and do not affect the record numbering of other records. - The stream information record for a given stream will always precede any data records for that stream within an individual journal file. - The following "magic" entries can be used to identify journald files: 0 string journald Journald file >8 belong x version %d >12 belong x page size %d