1 /* SPDX-License-Identifier: LGPL-2.1+ */
15 #include "journal-def.h"
16 #include "mmap-cache.h"
17 #include "sparse-endian.h"
18 #include "time-util.h"
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 */
30 typedef enum direction
{
35 typedef enum LocationType
{
36 /* The first and last entries, resp. */
40 /* We already read the entry we currently point to, and the
41 * next one to read should probably not be this one again. */
44 /* We should seek to the precise location specified, and
45 * return it, as we haven't read it yet. */
49 typedef enum OfflineState
{
54 OFFLINE_AGAIN_FROM_SYNCING
,
55 OFFLINE_AGAIN_FROM_OFFLINING
,
59 typedef struct JournalFile
{
61 MMapFileDescriptor
*cache_fd
;
72 bool defrag_on_close
:1;
77 direction_t last_direction
;
78 LocationType location_type
;
79 uint64_t last_n_entries
;
82 struct stat last_stat
;
83 usec_t last_stat_usec
;
86 HashItem
*data_hash_table
;
87 HashItem
*field_hash_table
;
89 uint64_t current_offset
;
90 uint64_t current_seqnum
;
91 uint64_t current_realtime
;
92 uint64_t current_monotonic
;
93 sd_id128_t current_boot_id
;
94 uint64_t current_xor_hash
;
96 JournalMetrics metrics
;
99 sd_event_source
*post_change_timer
;
100 usec_t post_change_timer_period
;
102 OrderedHashmap
*chain_cache
;
104 pthread_t offline_thread
;
105 volatile OfflineState offline_state
;
107 unsigned last_seen_generation
;
109 uint64_t compress_threshold_bytes
;
111 void *compress_buffer
;
112 size_t compress_buffer_size
;
120 size_t fss_file_size
;
122 uint64_t fss_start_usec
;
123 uint64_t fss_interval_usec
;
126 size_t fsprg_state_size
;
129 size_t fsprg_seed_size
;
133 int journal_file_open(
139 uint64_t compress_threshold_bytes
,
141 JournalMetrics
*metrics
,
142 MMapCache
*mmap_cache
,
143 Set
*deferred_closes
,
144 JournalFile
*template,
147 int journal_file_set_offline(JournalFile
*f
, bool wait
);
148 bool journal_file_is_offlining(JournalFile
*f
);
149 JournalFile
* journal_file_close(JournalFile
*j
);
150 int journal_file_fstat(JournalFile
*f
);
151 DEFINE_TRIVIAL_CLEANUP_FUNC(JournalFile
*, journal_file_close
);
153 int journal_file_open_reliably(
158 uint64_t compress_threshold_bytes
,
160 JournalMetrics
*metrics
,
161 MMapCache
*mmap_cache
,
162 Set
*deferred_closes
,
163 JournalFile
*template,
166 #define ALIGN64(x) (((x) + 7ULL) & ~7ULL)
167 #define VALID64(x) (((x) & 7ULL) == 0ULL)
169 /* Use six characters to cover the offsets common in smallish journal
170 * files without adding too many zeros. */
171 #define OFSfmt "%06"PRIx64
173 static inline bool VALID_REALTIME(uint64_t u
) {
174 /* This considers timestamps until the year 3112 valid. That should be plenty room... */
175 return u
> 0 && u
< (1ULL << 55);
178 static inline bool VALID_MONOTONIC(uint64_t u
) {
179 /* This considers timestamps until 1142 years of runtime valid. */
180 return u
< (1ULL << 55);
183 static inline bool VALID_EPOCH(uint64_t u
) {
184 /* This allows changing the key for 1142 years, every usec. */
185 return u
< (1ULL << 55);
188 #define JOURNAL_HEADER_CONTAINS(h, field) \
189 (le64toh((h)->header_size) >= offsetof(Header, field) + sizeof((h)->field))
191 #define JOURNAL_HEADER_SEALED(h) \
192 FLAGS_SET(le32toh((h)->compatible_flags), HEADER_COMPATIBLE_SEALED)
194 #define JOURNAL_HEADER_COMPRESSED_XZ(h) \
195 FLAGS_SET(le32toh((h)->incompatible_flags), HEADER_INCOMPATIBLE_COMPRESSED_XZ)
197 #define JOURNAL_HEADER_COMPRESSED_LZ4(h) \
198 FLAGS_SET(le32toh((h)->incompatible_flags), HEADER_INCOMPATIBLE_COMPRESSED_LZ4)
200 #define JOURNAL_HEADER_COMPRESSED_ZSTD(h) \
201 FLAGS_SET(le32toh((h)->incompatible_flags), HEADER_INCOMPATIBLE_COMPRESSED_ZSTD)
203 #define JOURNAL_HEADER_KEYED_HASH(h) \
204 FLAGS_SET(le32toh((h)->incompatible_flags), HEADER_INCOMPATIBLE_KEYED_HASH)
206 int journal_file_move_to_object(JournalFile
*f
, ObjectType type
, uint64_t offset
, Object
**ret
);
208 uint64_t journal_file_entry_n_items(Object
*o
) _pure_
;
209 uint64_t journal_file_entry_array_n_items(Object
*o
) _pure_
;
210 uint64_t journal_file_hash_table_n_items(Object
*o
) _pure_
;
212 int journal_file_append_object(JournalFile
*f
, ObjectType type
, uint64_t size
, Object
**ret
, uint64_t *offset
);
213 int journal_file_append_entry(
215 const dual_timestamp
*ts
,
216 const sd_id128_t
*boot_id
,
217 const struct iovec iovec
[], unsigned n_iovec
,
222 int journal_file_find_data_object(JournalFile
*f
, const void *data
, uint64_t size
, Object
**ret
, uint64_t *offset
);
223 int journal_file_find_data_object_with_hash(JournalFile
*f
, const void *data
, uint64_t size
, uint64_t hash
, Object
**ret
, uint64_t *offset
);
225 int journal_file_find_field_object(JournalFile
*f
, const void *field
, uint64_t size
, Object
**ret
, uint64_t *offset
);
226 int journal_file_find_field_object_with_hash(JournalFile
*f
, const void *field
, uint64_t size
, uint64_t hash
, Object
**ret
, uint64_t *offset
);
228 void journal_file_reset_location(JournalFile
*f
);
229 void journal_file_save_location(JournalFile
*f
, Object
*o
, uint64_t offset
);
230 int journal_file_compare_locations(JournalFile
*af
, JournalFile
*bf
);
231 int journal_file_next_entry(JournalFile
*f
, uint64_t p
, direction_t direction
, Object
**ret
, uint64_t *offset
);
233 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
);
235 int journal_file_move_to_entry_by_seqnum(JournalFile
*f
, uint64_t seqnum
, direction_t direction
, Object
**ret
, uint64_t *offset
);
236 int journal_file_move_to_entry_by_realtime(JournalFile
*f
, uint64_t realtime
, direction_t direction
, Object
**ret
, uint64_t *offset
);
237 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
);
239 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
);
240 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
);
241 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
);
242 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
);
244 int journal_file_copy_entry(JournalFile
*from
, JournalFile
*to
, Object
*o
, uint64_t p
);
246 void journal_file_dump(JournalFile
*f
);
247 void journal_file_print_header(JournalFile
*f
);
249 int journal_file_archive(JournalFile
*f
);
250 JournalFile
* journal_initiate_close(JournalFile
*f
, Set
*deferred_closes
);
251 int journal_file_rotate(JournalFile
**f
, bool compress
, uint64_t compress_threshold_bytes
, bool seal
, Set
*deferred_closes
);
253 int journal_file_dispose(int dir_fd
, const char *fname
);
255 void journal_file_post_change(JournalFile
*f
);
256 int journal_file_enable_post_change_timer(JournalFile
*f
, sd_event
*e
, usec_t t
);
258 void journal_reset_metrics(JournalMetrics
*m
);
259 void journal_default_metrics(JournalMetrics
*m
, int fd
);
261 int journal_file_get_cutoff_realtime_usec(JournalFile
*f
, usec_t
*from
, usec_t
*to
);
262 int journal_file_get_cutoff_monotonic_usec(JournalFile
*f
, sd_id128_t boot
, usec_t
*from
, usec_t
*to
);
264 bool journal_file_rotate_suggested(JournalFile
*f
, usec_t max_file_usec
);
266 int journal_file_map_data_hash_table(JournalFile
*f
);
267 int journal_file_map_field_hash_table(JournalFile
*f
);
269 static inline bool JOURNAL_FILE_COMPRESS(JournalFile
*f
) {
271 return f
->compress_xz
|| f
->compress_lz4
|| f
->compress_zstd
;
274 uint64_t journal_file_hash_data(JournalFile
*f
, const void *data
, size_t sz
);