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