]>
Commit | Line | Data |
---|---|---|
52ad194e | 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
663996b3 MS |
2 | #pragma once |
3 | ||
663996b3 MS |
4 | #include <inttypes.h> |
5 | ||
f5e65279 | 6 | #if HAVE_GCRYPT |
6e866b33 | 7 | # include <gcrypt.h> |
663996b3 MS |
8 | #endif |
9 | ||
6e866b33 | 10 | #include "sd-event.h" |
e735f4d4 | 11 | #include "sd-id128.h" |
663996b3 | 12 | |
4c89c718 | 13 | #include "hashmap.h" |
663996b3 | 14 | #include "journal-def.h" |
e735f4d4 | 15 | #include "macro.h" |
663996b3 | 16 | #include "mmap-cache.h" |
4c89c718 | 17 | #include "sparse-endian.h" |
663996b3 MS |
18 | |
19 | typedef struct JournalMetrics { | |
6300502b MP |
20 | /* For all these: -1 means "pick automatically", and 0 means "no limit enforced" */ |
21 | uint64_t max_size; /* how large journal files grow at max */ | |
22 | uint64_t min_size; /* how large journal files grow at least */ | |
23 | uint64_t max_use; /* how much disk space to use in total at max, keep_free permitting */ | |
24 | uint64_t min_use; /* how much disk space to use in total at least, even if keep_free says not to */ | |
25 | uint64_t keep_free; /* how much to keep free on disk */ | |
26 | uint64_t n_max_files; /* how many files to keep around at max */ | |
663996b3 MS |
27 | } JournalMetrics; |
28 | ||
14228c0d MB |
29 | typedef enum direction { |
30 | DIRECTION_UP, | |
31 | DIRECTION_DOWN | |
32 | } direction_t; | |
33 | ||
e735f4d4 MP |
34 | typedef enum LocationType { |
35 | /* The first and last entries, resp. */ | |
36 | LOCATION_HEAD, | |
37 | LOCATION_TAIL, | |
38 | ||
39 | /* We already read the entry we currently point to, and the | |
40 | * next one to read should probably not be this one again. */ | |
41 | LOCATION_DISCRETE, | |
42 | ||
43 | /* We should seek to the precise location specified, and | |
44 | * return it, as we haven't read it yet. */ | |
45 | LOCATION_SEEK | |
46 | } LocationType; | |
47 | ||
aa27b158 MP |
48 | typedef enum OfflineState { |
49 | OFFLINE_JOINED, | |
50 | OFFLINE_SYNCING, | |
51 | OFFLINE_OFFLINING, | |
52 | OFFLINE_CANCEL, | |
53 | OFFLINE_AGAIN_FROM_SYNCING, | |
54 | OFFLINE_AGAIN_FROM_OFFLINING, | |
55 | OFFLINE_DONE | |
56 | } OfflineState; | |
57 | ||
663996b3 MS |
58 | typedef struct JournalFile { |
59 | int fd; | |
81c58355 | 60 | MMapFileDescriptor *cache_fd; |
14228c0d | 61 | |
663996b3 MS |
62 | mode_t mode; |
63 | ||
64 | int flags; | |
65 | int prot; | |
60f067b4 | 66 | bool writable:1; |
5eef597e MP |
67 | bool compress_xz:1; |
68 | bool compress_lz4:1; | |
60f067b4 | 69 | bool seal:1; |
e735f4d4 | 70 | bool defrag_on_close:1; |
aa27b158 MP |
71 | bool close_fd:1; |
72 | bool archive:1; | |
663996b3 | 73 | |
14228c0d | 74 | direction_t last_direction; |
e735f4d4 MP |
75 | LocationType location_type; |
76 | uint64_t last_n_entries; | |
14228c0d MB |
77 | |
78 | char *path; | |
79 | struct stat last_stat; | |
e735f4d4 | 80 | usec_t last_stat_usec; |
14228c0d | 81 | |
663996b3 MS |
82 | Header *header; |
83 | HashItem *data_hash_table; | |
84 | HashItem *field_hash_table; | |
85 | ||
86 | uint64_t current_offset; | |
e735f4d4 MP |
87 | uint64_t current_seqnum; |
88 | uint64_t current_realtime; | |
89 | uint64_t current_monotonic; | |
90 | sd_id128_t current_boot_id; | |
91 | uint64_t current_xor_hash; | |
663996b3 MS |
92 | |
93 | JournalMetrics metrics; | |
94 | MMapCache *mmap; | |
95 | ||
4c89c718 MP |
96 | sd_event_source *post_change_timer; |
97 | usec_t post_change_timer_period; | |
98 | ||
5eef597e | 99 | OrderedHashmap *chain_cache; |
663996b3 | 100 | |
aa27b158 MP |
101 | pthread_t offline_thread; |
102 | volatile OfflineState offline_state; | |
103 | ||
98393f85 MB |
104 | unsigned last_seen_generation; |
105 | ||
b012e921 | 106 | uint64_t compress_threshold_bytes; |
f5e65279 | 107 | #if HAVE_XZ || HAVE_LZ4 |
663996b3 | 108 | void *compress_buffer; |
5eef597e | 109 | size_t compress_buffer_size; |
663996b3 MS |
110 | #endif |
111 | ||
f5e65279 | 112 | #if HAVE_GCRYPT |
663996b3 MS |
113 | gcry_md_hd_t hmac; |
114 | bool hmac_running; | |
115 | ||
116 | FSSHeader *fss_file; | |
117 | size_t fss_file_size; | |
118 | ||
119 | uint64_t fss_start_usec; | |
120 | uint64_t fss_interval_usec; | |
121 | ||
122 | void *fsprg_state; | |
123 | size_t fsprg_state_size; | |
124 | ||
125 | void *fsprg_seed; | |
126 | size_t fsprg_seed_size; | |
127 | #endif | |
128 | } JournalFile; | |
129 | ||
663996b3 | 130 | int journal_file_open( |
aa27b158 | 131 | int fd, |
663996b3 MS |
132 | const char *fname, |
133 | int flags, | |
134 | mode_t mode, | |
135 | bool compress, | |
b012e921 | 136 | uint64_t compress_threshold_bytes, |
663996b3 MS |
137 | bool seal, |
138 | JournalMetrics *metrics, | |
139 | MMapCache *mmap_cache, | |
aa27b158 | 140 | Set *deferred_closes, |
663996b3 MS |
141 | JournalFile *template, |
142 | JournalFile **ret); | |
143 | ||
aa27b158 MP |
144 | int journal_file_set_offline(JournalFile *f, bool wait); |
145 | bool journal_file_is_offlining(JournalFile *f); | |
6300502b | 146 | JournalFile* journal_file_close(JournalFile *j); |
663996b3 MS |
147 | |
148 | int journal_file_open_reliably( | |
149 | const char *fname, | |
150 | int flags, | |
151 | mode_t mode, | |
152 | bool compress, | |
b012e921 | 153 | uint64_t compress_threshold_bytes, |
663996b3 MS |
154 | bool seal, |
155 | JournalMetrics *metrics, | |
156 | MMapCache *mmap_cache, | |
aa27b158 | 157 | Set *deferred_closes, |
663996b3 MS |
158 | JournalFile *template, |
159 | JournalFile **ret); | |
160 | ||
161 | #define ALIGN64(x) (((x) + 7ULL) & ~7ULL) | |
162 | #define VALID64(x) (((x) & 7ULL) == 0ULL) | |
163 | ||
60f067b4 JS |
164 | /* Use six characters to cover the offsets common in smallish journal |
165 | * files without adding too many zeros. */ | |
166 | #define OFSfmt "%06"PRIx64 | |
167 | ||
663996b3 MS |
168 | static inline bool VALID_REALTIME(uint64_t u) { |
169 | /* This considers timestamps until the year 3112 valid. That should be plenty room... */ | |
170 | return u > 0 && u < (1ULL << 55); | |
171 | } | |
172 | ||
173 | static inline bool VALID_MONOTONIC(uint64_t u) { | |
174 | /* This considers timestamps until 1142 years of runtime valid. */ | |
175 | return u < (1ULL << 55); | |
176 | } | |
177 | ||
178 | static inline bool VALID_EPOCH(uint64_t u) { | |
179 | /* This allows changing the key for 1142 years, every usec. */ | |
180 | return u < (1ULL << 55); | |
181 | } | |
182 | ||
183 | #define JOURNAL_HEADER_CONTAINS(h, field) \ | |
184 | (le64toh((h)->header_size) >= offsetof(Header, field) + sizeof((h)->field)) | |
185 | ||
186 | #define JOURNAL_HEADER_SEALED(h) \ | |
187 | (!!(le32toh((h)->compatible_flags) & HEADER_COMPATIBLE_SEALED)) | |
188 | ||
5eef597e MP |
189 | #define JOURNAL_HEADER_COMPRESSED_XZ(h) \ |
190 | (!!(le32toh((h)->incompatible_flags) & HEADER_INCOMPATIBLE_COMPRESSED_XZ)) | |
191 | ||
192 | #define JOURNAL_HEADER_COMPRESSED_LZ4(h) \ | |
193 | (!!(le32toh((h)->incompatible_flags) & HEADER_INCOMPATIBLE_COMPRESSED_LZ4)) | |
663996b3 | 194 | |
e735f4d4 | 195 | int journal_file_move_to_object(JournalFile *f, ObjectType type, uint64_t offset, Object **ret); |
663996b3 MS |
196 | |
197 | uint64_t journal_file_entry_n_items(Object *o) _pure_; | |
198 | uint64_t journal_file_entry_array_n_items(Object *o) _pure_; | |
199 | uint64_t journal_file_hash_table_n_items(Object *o) _pure_; | |
200 | ||
e735f4d4 | 201 | int journal_file_append_object(JournalFile *f, ObjectType type, uint64_t size, Object **ret, uint64_t *offset); |
b012e921 MB |
202 | int journal_file_append_entry( |
203 | JournalFile *f, | |
204 | const dual_timestamp *ts, | |
205 | const sd_id128_t *boot_id, | |
206 | const struct iovec iovec[], unsigned n_iovec, | |
207 | uint64_t *seqno, | |
208 | Object **ret, | |
209 | uint64_t *offset); | |
663996b3 MS |
210 | |
211 | int journal_file_find_data_object(JournalFile *f, const void *data, uint64_t size, Object **ret, uint64_t *offset); | |
212 | int journal_file_find_data_object_with_hash(JournalFile *f, const void *data, uint64_t size, uint64_t hash, Object **ret, uint64_t *offset); | |
213 | ||
214 | int journal_file_find_field_object(JournalFile *f, const void *field, uint64_t size, Object **ret, uint64_t *offset); | |
215 | int journal_file_find_field_object_with_hash(JournalFile *f, const void *field, uint64_t size, uint64_t hash, Object **ret, uint64_t *offset); | |
216 | ||
e735f4d4 | 217 | void journal_file_reset_location(JournalFile *f); |
e3bff60a | 218 | void journal_file_save_location(JournalFile *f, Object *o, uint64_t offset); |
e735f4d4 MP |
219 | int journal_file_compare_locations(JournalFile *af, JournalFile *bf); |
220 | int journal_file_next_entry(JournalFile *f, uint64_t p, direction_t direction, Object **ret, uint64_t *offset); | |
663996b3 MS |
221 | |
222 | int journal_file_next_entry_for_data(JournalFile *f, Object *o, uint64_t p, uint64_t data_offset, direction_t direction, Object **ret, uint64_t *offset); | |
223 | ||
663996b3 MS |
224 | int journal_file_move_to_entry_by_seqnum(JournalFile *f, uint64_t seqnum, direction_t direction, Object **ret, uint64_t *offset); |
225 | int journal_file_move_to_entry_by_realtime(JournalFile *f, uint64_t realtime, direction_t direction, Object **ret, uint64_t *offset); | |
226 | int journal_file_move_to_entry_by_monotonic(JournalFile *f, sd_id128_t boot_id, uint64_t monotonic, direction_t direction, Object **ret, uint64_t *offset); | |
227 | ||
228 | int journal_file_move_to_entry_by_offset_for_data(JournalFile *f, uint64_t data_offset, uint64_t p, direction_t direction, Object **ret, uint64_t *offset); | |
229 | int journal_file_move_to_entry_by_seqnum_for_data(JournalFile *f, uint64_t data_offset, uint64_t seqnum, direction_t direction, Object **ret, uint64_t *offset); | |
230 | int journal_file_move_to_entry_by_realtime_for_data(JournalFile *f, uint64_t data_offset, uint64_t realtime, direction_t direction, Object **ret, uint64_t *offset); | |
231 | int journal_file_move_to_entry_by_monotonic_for_data(JournalFile *f, uint64_t data_offset, sd_id128_t boot_id, uint64_t monotonic, direction_t direction, Object **ret, uint64_t *offset); | |
232 | ||
b012e921 | 233 | int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint64_t p); |
663996b3 MS |
234 | |
235 | void journal_file_dump(JournalFile *f); | |
236 | void journal_file_print_header(JournalFile *f); | |
237 | ||
6e866b33 MB |
238 | int journal_file_archive(JournalFile *f); |
239 | JournalFile* journal_initiate_close(JournalFile *f, Set *deferred_closes); | |
b012e921 | 240 | int journal_file_rotate(JournalFile **f, bool compress, uint64_t compress_threshold_bytes, bool seal, Set *deferred_closes); |
663996b3 | 241 | |
6e866b33 MB |
242 | int journal_file_dispose(int dir_fd, const char *fname); |
243 | ||
663996b3 | 244 | void journal_file_post_change(JournalFile *f); |
4c89c718 | 245 | int journal_file_enable_post_change_timer(JournalFile *f, sd_event *e, usec_t t); |
663996b3 | 246 | |
6300502b | 247 | void journal_reset_metrics(JournalMetrics *m); |
663996b3 MS |
248 | void journal_default_metrics(JournalMetrics *m, int fd); |
249 | ||
250 | int journal_file_get_cutoff_realtime_usec(JournalFile *f, usec_t *from, usec_t *to); | |
251 | int journal_file_get_cutoff_monotonic_usec(JournalFile *f, sd_id128_t boot, usec_t *from, usec_t *to); | |
252 | ||
253 | bool journal_file_rotate_suggested(JournalFile *f, usec_t max_file_usec); | |
7035cd9e MP |
254 | |
255 | int journal_file_map_data_hash_table(JournalFile *f); | |
256 | int journal_file_map_field_hash_table(JournalFile *f); | |
db2df898 MP |
257 | |
258 | static inline bool JOURNAL_FILE_COMPRESS(JournalFile *f) { | |
259 | assert(f); | |
260 | return f->compress_xz || f->compress_lz4; | |
261 | } |