]>
Commit | Line | Data |
---|---|---|
db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
c2f1db8f | 2 | #pragma once |
87d2c1ff | 3 | |
3ffd4af2 | 4 | #include "sd-id128.h" |
81527be1 | 5 | |
87d2c1ff | 6 | #include "macro.h" |
3ffd4af2 | 7 | #include "sparse-endian.h" |
87d2c1ff | 8 | |
0962e09e LP |
9 | /* |
10 | * If you change this file you probably should also change its documentation: | |
11 | * | |
bbcd38e4 | 12 | * https://systemd.io/JOURNAL_FILE_FORMAT |
0962e09e LP |
13 | */ |
14 | ||
87d2c1ff | 15 | typedef struct Header Header; |
8144056f | 16 | |
87d2c1ff LP |
17 | typedef struct ObjectHeader ObjectHeader; |
18 | typedef union Object Object; | |
8144056f | 19 | |
87d2c1ff | 20 | typedef struct DataObject DataObject; |
de190aef | 21 | typedef struct FieldObject FieldObject; |
87d2c1ff LP |
22 | typedef struct EntryObject EntryObject; |
23 | typedef struct HashTableObject HashTableObject; | |
de190aef | 24 | typedef struct EntryArrayObject EntryArrayObject; |
7560fffc | 25 | typedef struct TagObject TagObject; |
8144056f | 26 | |
87d2c1ff LP |
27 | typedef struct EntryItem EntryItem; |
28 | typedef struct HashItem HashItem; | |
29 | ||
baed47c3 | 30 | typedef struct FSSHeader FSSHeader; |
7560fffc | 31 | |
87d2c1ff | 32 | /* Object types */ |
78519831 | 33 | typedef enum ObjectType { |
d05089d8 | 34 | OBJECT_UNUSED, /* also serves as "any type" or "additional context" */ |
0962e09e | 35 | OBJECT_DATA, |
de190aef | 36 | OBJECT_FIELD, |
87d2c1ff | 37 | OBJECT_ENTRY, |
de190aef LP |
38 | OBJECT_DATA_HASH_TABLE, |
39 | OBJECT_FIELD_HASH_TABLE, | |
0962e09e | 40 | OBJECT_ENTRY_ARRAY, |
7560fffc | 41 | OBJECT_TAG, |
de190aef | 42 | _OBJECT_TYPE_MAX |
78519831 | 43 | } ObjectType; |
87d2c1ff | 44 | |
807e17f0 LP |
45 | /* Object flags */ |
46 | enum { | |
e9ece6a0 LP |
47 | OBJECT_COMPRESSED_XZ = 1 << 0, |
48 | OBJECT_COMPRESSED_LZ4 = 1 << 1, | |
8653185a LP |
49 | OBJECT_COMPRESSED_ZSTD = 1 << 2, |
50 | OBJECT_COMPRESSION_MASK = (OBJECT_COMPRESSED_XZ | OBJECT_COMPRESSED_LZ4 | OBJECT_COMPRESSED_ZSTD), | |
e9ece6a0 | 51 | _OBJECT_COMPRESSED_MAX = OBJECT_COMPRESSION_MASK, |
807e17f0 LP |
52 | }; |
53 | ||
80701564 | 54 | struct ObjectHeader { |
87d2c1ff | 55 | uint8_t type; |
807e17f0 LP |
56 | uint8_t flags; |
57 | uint8_t reserved[6]; | |
4fd052ae | 58 | le64_t size; |
87d2c1ff | 59 | uint8_t payload[]; |
80701564 | 60 | } _packed_; |
87d2c1ff | 61 | |
62353f69 ZJS |
62 | #define DataObject__contents { \ |
63 | ObjectHeader object; \ | |
64 | le64_t hash; \ | |
65 | le64_t next_hash_offset; \ | |
66 | le64_t next_field_offset; \ | |
67 | le64_t entry_offset; /* the first array entry we store inline */ \ | |
68 | le64_t entry_array_offset; \ | |
69 | le64_t n_entries; \ | |
70 | uint8_t payload[]; \ | |
71 | } | |
72 | ||
73 | struct DataObject DataObject__contents; | |
74 | struct DataObject__packed DataObject__contents _packed_; | |
75 | assert_cc(sizeof(struct DataObject) == sizeof(struct DataObject__packed)); | |
de190aef | 76 | |
0dbe57ee LP |
77 | #define FieldObject__contents { \ |
78 | ObjectHeader object; \ | |
79 | le64_t hash; \ | |
80 | le64_t next_hash_offset; \ | |
81 | le64_t head_data_offset; \ | |
82 | uint8_t payload[]; \ | |
83 | } | |
84 | ||
85 | struct FieldObject FieldObject__contents; | |
86 | struct FieldObject__packed FieldObject__contents _packed_; | |
87 | assert_cc(sizeof(struct FieldObject) == sizeof(struct FieldObject__packed)); | |
87d2c1ff | 88 | |
80701564 | 89 | struct EntryItem { |
4fd052ae FC |
90 | le64_t object_offset; |
91 | le64_t hash; | |
80701564 | 92 | } _packed_; |
87d2c1ff | 93 | |
62353f69 ZJS |
94 | #define EntryObject__contents { \ |
95 | ObjectHeader object; \ | |
96 | le64_t seqnum; \ | |
97 | le64_t realtime; \ | |
98 | le64_t monotonic; \ | |
99 | sd_id128_t boot_id; \ | |
100 | le64_t xor_hash; \ | |
101 | EntryItem items[]; \ | |
102 | } | |
103 | ||
104 | struct EntryObject EntryObject__contents; | |
105 | struct EntryObject__packed EntryObject__contents _packed_; | |
106 | assert_cc(sizeof(struct EntryObject) == sizeof(struct EntryObject__packed)); | |
107 | ||
80701564 | 108 | struct HashItem { |
4fd052ae FC |
109 | le64_t head_hash_offset; |
110 | le64_t tail_hash_offset; | |
80701564 | 111 | } _packed_; |
87d2c1ff | 112 | |
80701564 | 113 | struct HashTableObject { |
87d2c1ff | 114 | ObjectHeader object; |
de190aef | 115 | HashItem items[]; |
80701564 | 116 | } _packed_; |
87d2c1ff | 117 | |
80701564 | 118 | struct EntryArrayObject { |
87d2c1ff | 119 | ObjectHeader object; |
4fd052ae FC |
120 | le64_t next_entry_array_offset; |
121 | le64_t items[]; | |
80701564 | 122 | } _packed_; |
87d2c1ff | 123 | |
7560fffc | 124 | #define TAG_LENGTH (256/8) |
8144056f | 125 | |
80701564 | 126 | struct TagObject { |
8144056f | 127 | ObjectHeader object; |
e8c61d7b LP |
128 | le64_t seqnum; |
129 | le64_t epoch; | |
7560fffc | 130 | uint8_t tag[TAG_LENGTH]; /* SHA-256 HMAC */ |
80701564 | 131 | } _packed_; |
8144056f | 132 | |
87d2c1ff LP |
133 | union Object { |
134 | ObjectHeader object; | |
135 | DataObject data; | |
de190aef | 136 | FieldObject field; |
87d2c1ff LP |
137 | EntryObject entry; |
138 | HashTableObject hash_table; | |
de190aef | 139 | EntryArrayObject entry_array; |
7560fffc | 140 | TagObject tag; |
87d2c1ff LP |
141 | }; |
142 | ||
143 | enum { | |
db11ac1a LP |
144 | STATE_OFFLINE = 0, |
145 | STATE_ONLINE = 1, | |
146 | STATE_ARCHIVED = 2, | |
147 | _STATE_MAX | |
87d2c1ff LP |
148 | }; |
149 | ||
807e17f0 LP |
150 | /* Header flags */ |
151 | enum { | |
e9ece6a0 LP |
152 | HEADER_INCOMPATIBLE_COMPRESSED_XZ = 1 << 0, |
153 | HEADER_INCOMPATIBLE_COMPRESSED_LZ4 = 1 << 1, | |
4ce534f4 | 154 | HEADER_INCOMPATIBLE_KEYED_HASH = 1 << 2, |
8653185a | 155 | HEADER_INCOMPATIBLE_COMPRESSED_ZSTD = 1 << 3, |
807e17f0 LP |
156 | }; |
157 | ||
8653185a LP |
158 | #define HEADER_INCOMPATIBLE_ANY \ |
159 | (HEADER_INCOMPATIBLE_COMPRESSED_XZ | \ | |
160 | HEADER_INCOMPATIBLE_COMPRESSED_LZ4 | \ | |
161 | HEADER_INCOMPATIBLE_KEYED_HASH | \ | |
162 | HEADER_INCOMPATIBLE_COMPRESSED_ZSTD) | |
d89c8fdf | 163 | |
8653185a | 164 | #if HAVE_XZ && HAVE_LZ4 && HAVE_ZSTD |
d89c8fdf | 165 | # define HEADER_INCOMPATIBLE_SUPPORTED HEADER_INCOMPATIBLE_ANY |
8653185a LP |
166 | #elif HAVE_XZ && HAVE_LZ4 |
167 | # define HEADER_INCOMPATIBLE_SUPPORTED (HEADER_INCOMPATIBLE_COMPRESSED_XZ|HEADER_INCOMPATIBLE_COMPRESSED_LZ4|HEADER_INCOMPATIBLE_KEYED_HASH) | |
168 | #elif HAVE_XZ && HAVE_ZSTD | |
169 | # define HEADER_INCOMPATIBLE_SUPPORTED (HEADER_INCOMPATIBLE_COMPRESSED_XZ|HEADER_INCOMPATIBLE_COMPRESSED_ZSTD|HEADER_INCOMPATIBLE_KEYED_HASH) | |
170 | #elif HAVE_LZ4 && HAVE_ZSTD | |
171 | # define HEADER_INCOMPATIBLE_SUPPORTED (HEADER_INCOMPATIBLE_COMPRESSED_LZ4|HEADER_INCOMPATIBLE_COMPRESSED_ZSTD|HEADER_INCOMPATIBLE_KEYED_HASH) | |
349cc4a5 | 172 | #elif HAVE_XZ |
4ce534f4 | 173 | # define HEADER_INCOMPATIBLE_SUPPORTED (HEADER_INCOMPATIBLE_COMPRESSED_XZ|HEADER_INCOMPATIBLE_KEYED_HASH) |
349cc4a5 | 174 | #elif HAVE_LZ4 |
4ce534f4 | 175 | # define HEADER_INCOMPATIBLE_SUPPORTED (HEADER_INCOMPATIBLE_COMPRESSED_LZ4|HEADER_INCOMPATIBLE_KEYED_HASH) |
8653185a LP |
176 | #elif HAVE_ZSTD |
177 | # define HEADER_INCOMPATIBLE_SUPPORTED (HEADER_INCOMPATIBLE_COMPRESSED_ZSTD|HEADER_INCOMPATIBLE_KEYED_HASH) | |
d89c8fdf | 178 | #else |
4ce534f4 | 179 | # define HEADER_INCOMPATIBLE_SUPPORTED HEADER_INCOMPATIBLE_KEYED_HASH |
d89c8fdf ZJS |
180 | #endif |
181 | ||
8144056f | 182 | enum { |
e9ece6a0 | 183 | HEADER_COMPATIBLE_SEALED = 1 << 0, |
8144056f LP |
184 | }; |
185 | ||
d89c8fdf | 186 | #define HEADER_COMPATIBLE_ANY HEADER_COMPATIBLE_SEALED |
349cc4a5 | 187 | #if HAVE_GCRYPT |
d89c8fdf ZJS |
188 | # define HEADER_COMPATIBLE_SUPPORTED HEADER_COMPATIBLE_SEALED |
189 | #else | |
190 | # define HEADER_COMPATIBLE_SUPPORTED 0 | |
191 | #endif | |
192 | ||
7851ec66 LP |
193 | #define HEADER_SIGNATURE \ |
194 | ((const char[]) { 'L', 'P', 'K', 'S', 'H', 'H', 'R', 'H' }) | |
7560fffc | 195 | |
62353f69 ZJS |
196 | #define struct_Header__contents { \ |
197 | uint8_t signature[8]; /* "LPKSHHRH" */ \ | |
198 | le32_t compatible_flags; \ | |
199 | le32_t incompatible_flags; \ | |
200 | uint8_t state; \ | |
201 | uint8_t reserved[7]; \ | |
202 | sd_id128_t file_id; \ | |
203 | sd_id128_t machine_id; \ | |
204 | sd_id128_t boot_id; /* last writer */ \ | |
205 | sd_id128_t seqnum_id; \ | |
206 | le64_t header_size; \ | |
207 | le64_t arena_size; \ | |
208 | le64_t data_hash_table_offset; \ | |
209 | le64_t data_hash_table_size; \ | |
210 | le64_t field_hash_table_offset; \ | |
211 | le64_t field_hash_table_size; \ | |
212 | le64_t tail_object_offset; \ | |
213 | le64_t n_objects; \ | |
214 | le64_t n_entries; \ | |
215 | le64_t tail_entry_seqnum; \ | |
216 | le64_t head_entry_seqnum; \ | |
217 | le64_t entry_array_offset; \ | |
218 | le64_t head_entry_realtime; \ | |
219 | le64_t tail_entry_realtime; \ | |
220 | le64_t tail_entry_monotonic; \ | |
221 | /* Added in 187 */ \ | |
222 | le64_t n_data; \ | |
223 | le64_t n_fields; \ | |
224 | /* Added in 189 */ \ | |
225 | le64_t n_tags; \ | |
226 | le64_t n_entry_arrays; \ | |
0dbe57ee LP |
227 | /* Added in 246 */ \ |
228 | le64_t data_hash_chain_depth; \ | |
229 | le64_t field_hash_chain_depth; \ | |
62353f69 ZJS |
230 | } |
231 | ||
232 | struct Header struct_Header__contents; | |
233 | struct Header__packed struct_Header__contents _packed_; | |
234 | assert_cc(sizeof(struct Header) == sizeof(struct Header__packed)); | |
0dbe57ee | 235 | assert_cc(sizeof(struct Header) == 256); |
7560fffc | 236 | |
7851ec66 LP |
237 | #define FSS_HEADER_SIGNATURE \ |
238 | ((const char[]) { 'K', 'S', 'H', 'H', 'R', 'H', 'L', 'P' }) | |
7560fffc | 239 | |
80701564 | 240 | struct FSSHeader { |
7560fffc LP |
241 | uint8_t signature[8]; /* "KSHHRHLP" */ |
242 | le32_t compatible_flags; | |
243 | le32_t incompatible_flags; | |
244 | sd_id128_t machine_id; | |
245 | sd_id128_t boot_id; /* last writer */ | |
246 | le64_t header_size; | |
baed47c3 LP |
247 | le64_t start_usec; |
248 | le64_t interval_usec; | |
249 | le16_t fsprg_secpar; | |
7560fffc | 250 | le16_t reserved[3]; |
baed47c3 | 251 | le64_t fsprg_state_size; |
80701564 | 252 | } _packed_; |