1 /* SPDX-License-Identifier: LGPL-2.1+ */
5 This file is part of systemd.
7 Copyright 2011 Lennart Poettering
19 #include "journal-def.h"
21 #include "mmap-cache.h"
23 #include "sparse-endian.h"
25 typedef struct JournalMetrics
{
26 /* For all these: -1 means "pick automatically", and 0 means "no limit enforced" */
27 uint64_t max_size
; /* how large journal files grow at max */
28 uint64_t min_size
; /* how large journal files grow at least */
29 uint64_t max_use
; /* how much disk space to use in total at max, keep_free permitting */
30 uint64_t min_use
; /* how much disk space to use in total at least, even if keep_free says not to */
31 uint64_t keep_free
; /* how much to keep free on disk */
32 uint64_t n_max_files
; /* how many files to keep around at max */
35 typedef enum direction
{
40 typedef enum LocationType
{
41 /* The first and last entries, resp. */
45 /* We already read the entry we currently point to, and the
46 * next one to read should probably not be this one again. */
49 /* We should seek to the precise location specified, and
50 * return it, as we haven't read it yet. */
54 typedef enum OfflineState
{
59 OFFLINE_AGAIN_FROM_SYNCING
,
60 OFFLINE_AGAIN_FROM_OFFLINING
,
64 typedef struct JournalFile
{
66 MMapFileDescriptor
*cache_fd
;
76 bool defrag_on_close
:1;
80 direction_t last_direction
;
81 LocationType location_type
;
82 uint64_t last_n_entries
;
85 struct stat last_stat
;
86 usec_t last_stat_usec
;
89 HashItem
*data_hash_table
;
90 HashItem
*field_hash_table
;
92 uint64_t current_offset
;
93 uint64_t current_seqnum
;
94 uint64_t current_realtime
;
95 uint64_t current_monotonic
;
96 sd_id128_t current_boot_id
;
97 uint64_t current_xor_hash
;
99 JournalMetrics metrics
;
102 sd_event_source
*post_change_timer
;
103 usec_t post_change_timer_period
;
105 OrderedHashmap
*chain_cache
;
107 pthread_t offline_thread
;
108 volatile OfflineState offline_state
;
110 unsigned last_seen_generation
;
112 uint64_t compress_threshold_bytes
;
113 #if HAVE_XZ || HAVE_LZ4
114 void *compress_buffer
;
115 size_t compress_buffer_size
;
123 size_t fss_file_size
;
125 uint64_t fss_start_usec
;
126 uint64_t fss_interval_usec
;
129 size_t fsprg_state_size
;
132 size_t fsprg_seed_size
;
136 int journal_file_open(
142 uint64_t compress_threshold_bytes
,
144 JournalMetrics
*metrics
,
145 MMapCache
*mmap_cache
,
146 Set
*deferred_closes
,
147 JournalFile
*template,
150 int journal_file_set_offline(JournalFile
*f
, bool wait
);
151 bool journal_file_is_offlining(JournalFile
*f
);
152 JournalFile
* journal_file_close(JournalFile
*j
);
154 int journal_file_open_reliably(
159 uint64_t compress_threshold_bytes
,
161 JournalMetrics
*metrics
,
162 MMapCache
*mmap_cache
,
163 Set
*deferred_closes
,
164 JournalFile
*template,
167 #define ALIGN64(x) (((x) + 7ULL) & ~7ULL)
168 #define VALID64(x) (((x) & 7ULL) == 0ULL)
170 /* Use six characters to cover the offsets common in smallish journal
171 * files without adding too many zeros. */
172 #define OFSfmt "%06"PRIx64
174 static inline bool VALID_REALTIME(uint64_t u
) {
175 /* This considers timestamps until the year 3112 valid. That should be plenty room... */
176 return u
> 0 && u
< (1ULL << 55);
179 static inline bool VALID_MONOTONIC(uint64_t u
) {
180 /* This considers timestamps until 1142 years of runtime valid. */
181 return u
< (1ULL << 55);
184 static inline bool VALID_EPOCH(uint64_t u
) {
185 /* This allows changing the key for 1142 years, every usec. */
186 return u
< (1ULL << 55);
189 #define JOURNAL_HEADER_CONTAINS(h, field) \
190 (le64toh((h)->header_size) >= offsetof(Header, field) + sizeof((h)->field))
192 #define JOURNAL_HEADER_SEALED(h) \
193 (!!(le32toh((h)->compatible_flags) & HEADER_COMPATIBLE_SEALED))
195 #define JOURNAL_HEADER_COMPRESSED_XZ(h) \
196 (!!(le32toh((h)->incompatible_flags) & HEADER_INCOMPATIBLE_COMPRESSED_XZ))
198 #define JOURNAL_HEADER_COMPRESSED_LZ4(h) \
199 (!!(le32toh((h)->incompatible_flags) & HEADER_INCOMPATIBLE_COMPRESSED_LZ4))
201 int journal_file_move_to_object(JournalFile
*f
, ObjectType type
, uint64_t offset
, Object
**ret
);
203 uint64_t journal_file_entry_n_items(Object
*o
) _pure_
;
204 uint64_t journal_file_entry_array_n_items(Object
*o
) _pure_
;
205 uint64_t journal_file_hash_table_n_items(Object
*o
) _pure_
;
207 int journal_file_append_object(JournalFile
*f
, ObjectType type
, uint64_t size
, Object
**ret
, uint64_t *offset
);
208 int journal_file_append_entry(JournalFile
*f
, const dual_timestamp
*ts
, const struct iovec iovec
[], unsigned n_iovec
, uint64_t *seqno
, Object
**ret
, uint64_t *offset
);
210 int journal_file_find_data_object(JournalFile
*f
, const void *data
, uint64_t size
, Object
**ret
, uint64_t *offset
);
211 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 int journal_file_find_field_object(JournalFile
*f
, const void *field
, uint64_t size
, Object
**ret
, uint64_t *offset
);
214 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 void journal_file_reset_location(JournalFile
*f
);
217 void journal_file_save_location(JournalFile
*f
, Object
*o
, uint64_t offset
);
218 int journal_file_compare_locations(JournalFile
*af
, JournalFile
*bf
);
219 int journal_file_next_entry(JournalFile
*f
, uint64_t p
, direction_t direction
, Object
**ret
, uint64_t *offset
);
221 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 int journal_file_move_to_entry_by_seqnum(JournalFile
*f
, uint64_t seqnum
, direction_t direction
, Object
**ret
, uint64_t *offset
);
224 int journal_file_move_to_entry_by_realtime(JournalFile
*f
, uint64_t realtime
, direction_t direction
, Object
**ret
, uint64_t *offset
);
225 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 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
);
228 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
);
229 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
);
230 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 int journal_file_copy_entry(JournalFile
*from
, JournalFile
*to
, Object
*o
, uint64_t p
, uint64_t *seqnum
, Object
**ret
, uint64_t *offset
);
234 void journal_file_dump(JournalFile
*f
);
235 void journal_file_print_header(JournalFile
*f
);
237 int journal_file_rotate(JournalFile
**f
, bool compress
, uint64_t compress_threshold_bytes
, bool seal
, Set
*deferred_closes
);
239 void journal_file_post_change(JournalFile
*f
);
240 int journal_file_enable_post_change_timer(JournalFile
*f
, sd_event
*e
, usec_t t
);
242 void journal_reset_metrics(JournalMetrics
*m
);
243 void journal_default_metrics(JournalMetrics
*m
, int fd
);
245 int journal_file_get_cutoff_realtime_usec(JournalFile
*f
, usec_t
*from
, usec_t
*to
);
246 int journal_file_get_cutoff_monotonic_usec(JournalFile
*f
, sd_id128_t boot
, usec_t
*from
, usec_t
*to
);
248 bool journal_file_rotate_suggested(JournalFile
*f
, usec_t max_file_usec
);
250 int journal_file_map_data_hash_table(JournalFile
*f
);
251 int journal_file_map_field_hash_table(JournalFile
*f
);
253 static inline bool JOURNAL_FILE_COMPRESS(JournalFile
*f
) {
255 return f
->compress_xz
|| f
->compress_lz4
;