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