]>
Commit | Line | Data |
---|---|---|
87d2c1ff LP |
1 | /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ |
2 | ||
c2f1db8f | 3 | #pragma once |
87d2c1ff LP |
4 | |
5 | /*** | |
6 | This file is part of systemd. | |
7 | ||
8 | Copyright 2011 Lennart Poettering | |
9 | ||
10 | systemd is free software; you can redistribute it and/or modify it | |
5430f7f2 LP |
11 | under the terms of the GNU Lesser General Public License as published by |
12 | the Free Software Foundation; either version 2.1 of the License, or | |
87d2c1ff LP |
13 | (at your option) any later version. |
14 | ||
15 | systemd is distributed in the hope that it will be useful, but | |
16 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
5430f7f2 | 18 | Lesser General Public License for more details. |
87d2c1ff | 19 | |
5430f7f2 | 20 | You should have received a copy of the GNU Lesser General Public License |
87d2c1ff LP |
21 | along with systemd; If not, see <http://www.gnu.org/licenses/>. |
22 | ***/ | |
23 | ||
24 | #include <inttypes.h> | |
25 | ||
7560fffc LP |
26 | #ifdef HAVE_GCRYPT |
27 | #include <gcrypt.h> | |
28 | #endif | |
29 | ||
fa6ac760 | 30 | #include "sd-id128.h" |
81527be1 | 31 | |
4fd052ae | 32 | #include "sparse-endian.h" |
87d2c1ff LP |
33 | #include "journal-def.h" |
34 | #include "util.h" | |
16e9f408 | 35 | #include "mmap-cache.h" |
a4bcff5b | 36 | #include "hashmap.h" |
de190aef | 37 | |
bc85bfee | 38 | typedef struct JournalMetrics { |
babfc091 | 39 | uint64_t max_use; |
348ced90 | 40 | uint64_t use; |
bc85bfee LP |
41 | uint64_t max_size; |
42 | uint64_t min_size; | |
43 | uint64_t keep_free; | |
44 | } JournalMetrics; | |
45 | ||
87011c25 ZJS |
46 | typedef enum direction { |
47 | DIRECTION_UP, | |
48 | DIRECTION_DOWN | |
49 | } direction_t; | |
50 | ||
99cc7653 MS |
51 | typedef enum LocationType { |
52 | /* The first and last entries, resp. */ | |
53 | LOCATION_HEAD, | |
54 | LOCATION_TAIL, | |
55 | ||
56 | /* We already read the entry we currently point to, and the | |
57 | * next one to read should probably not be this one again. */ | |
58 | LOCATION_DISCRETE, | |
59 | ||
60 | /* We should seek to the precise location specified, and | |
61 | * return it, as we haven't read it yet. */ | |
62 | LOCATION_SEEK | |
63 | } LocationType; | |
64 | ||
f4b47811 LP |
65 | typedef struct JournalFile { |
66 | int fd; | |
87011c25 | 67 | |
0ac38b70 | 68 | mode_t mode; |
7560fffc | 69 | |
0ac38b70 | 70 | int flags; |
f4b47811 | 71 | int prot; |
b8e891e6 | 72 | bool writable:1; |
d89c8fdf ZJS |
73 | bool compress_xz:1; |
74 | bool compress_lz4:1; | |
b8e891e6 | 75 | bool seal:1; |
f27a3864 | 76 | bool defrag_on_close:1; |
7560fffc | 77 | |
b8e891e6 | 78 | bool tail_entry_monotonic_valid:1; |
f4b47811 | 79 | |
87011c25 | 80 | direction_t last_direction; |
6573ef05 | 81 | LocationType location_type; |
6e693b42 | 82 | uint64_t last_n_entries; |
87011c25 ZJS |
83 | |
84 | char *path; | |
85 | struct stat last_stat; | |
2678031a | 86 | usec_t last_stat_usec; |
87011c25 | 87 | |
f4b47811 | 88 | Header *header; |
de190aef LP |
89 | HashItem *data_hash_table; |
90 | HashItem *field_hash_table; | |
f4b47811 | 91 | |
f4b47811 | 92 | uint64_t current_offset; |
6573ef05 MS |
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; | |
bc85bfee LP |
98 | |
99 | JournalMetrics metrics; | |
16e9f408 | 100 | MMapCache *mmap; |
807e17f0 | 101 | |
4743015d | 102 | OrderedHashmap *chain_cache; |
a4bcff5b | 103 | |
10893a5c | 104 | #if defined(HAVE_XZ) || defined(HAVE_LZ4) |
807e17f0 | 105 | void *compress_buffer; |
fa1c4b51 | 106 | size_t compress_buffer_size; |
807e17f0 | 107 | #endif |
7560fffc LP |
108 | |
109 | #ifdef HAVE_GCRYPT | |
110 | gcry_md_hd_t hmac; | |
111 | bool hmac_running; | |
112 | ||
baed47c3 LP |
113 | FSSHeader *fss_file; |
114 | size_t fss_file_size; | |
115 | ||
116 | uint64_t fss_start_usec; | |
117 | uint64_t fss_interval_usec; | |
b7c9ae91 LP |
118 | |
119 | void *fsprg_state; | |
120 | size_t fsprg_state_size; | |
121 | ||
122 | void *fsprg_seed; | |
123 | size_t fsprg_seed_size; | |
7560fffc | 124 | #endif |
f4b47811 LP |
125 | } JournalFile; |
126 | ||
4a92baf3 LP |
127 | int journal_file_open( |
128 | const char *fname, | |
129 | int flags, | |
130 | mode_t mode, | |
7560fffc | 131 | bool compress, |
baed47c3 | 132 | bool seal, |
4a92baf3 | 133 | JournalMetrics *metrics, |
27370278 | 134 | MMapCache *mmap_cache, |
4a92baf3 LP |
135 | JournalFile *template, |
136 | JournalFile **ret); | |
137 | ||
26687bf8 | 138 | int journal_file_set_offline(JournalFile *f); |
87d2c1ff LP |
139 | void journal_file_close(JournalFile *j); |
140 | ||
4a92baf3 LP |
141 | int journal_file_open_reliably( |
142 | const char *fname, | |
143 | int flags, | |
144 | mode_t mode, | |
7560fffc | 145 | bool compress, |
baed47c3 | 146 | bool seal, |
4a92baf3 | 147 | JournalMetrics *metrics, |
27370278 | 148 | MMapCache *mmap_cache, |
4a92baf3 LP |
149 | JournalFile *template, |
150 | JournalFile **ret); | |
9447a7f1 | 151 | |
0284adc6 | 152 | #define ALIGN64(x) (((x) + 7ULL) & ~7ULL) |
db11ac1a | 153 | #define VALID64(x) (((x) & 7ULL) == 0ULL) |
0284adc6 | 154 | |
ae97089d ZJS |
155 | /* Use six characters to cover the offsets common in smallish journal |
156 | * files without adding too many zeros. */ | |
157 | #define OFSfmt "%06"PRIx64 | |
158 | ||
fc89a139 LP |
159 | static inline bool VALID_REALTIME(uint64_t u) { |
160 | /* This considers timestamps until the year 3112 valid. That should be plenty room... */ | |
161 | return u > 0 && u < (1ULL << 55); | |
162 | } | |
163 | ||
164 | static inline bool VALID_MONOTONIC(uint64_t u) { | |
165 | /* This considers timestamps until 1142 years of runtime valid. */ | |
166 | return u < (1ULL << 55); | |
167 | } | |
168 | ||
169 | static inline bool VALID_EPOCH(uint64_t u) { | |
170 | /* This allows changing the key for 1142 years, every usec. */ | |
171 | return u < (1ULL << 55); | |
172 | } | |
173 | ||
0284adc6 LP |
174 | #define JOURNAL_HEADER_CONTAINS(h, field) \ |
175 | (le64toh((h)->header_size) >= offsetof(Header, field) + sizeof((h)->field)) | |
176 | ||
8088cbd3 LP |
177 | #define JOURNAL_HEADER_SEALED(h) \ |
178 | (!!(le32toh((h)->compatible_flags) & HEADER_COMPATIBLE_SEALED)) | |
179 | ||
d89c8fdf ZJS |
180 | #define JOURNAL_HEADER_COMPRESSED_XZ(h) \ |
181 | (!!(le32toh((h)->incompatible_flags) & HEADER_INCOMPATIBLE_COMPRESSED_XZ)) | |
182 | ||
183 | #define JOURNAL_HEADER_COMPRESSED_LZ4(h) \ | |
184 | (!!(le32toh((h)->incompatible_flags) & HEADER_INCOMPATIBLE_COMPRESSED_LZ4)) | |
8088cbd3 | 185 | |
78519831 | 186 | int journal_file_move_to_object(JournalFile *f, ObjectType type, uint64_t offset, Object **ret); |
87d2c1ff | 187 | |
44a6b1b6 ZJS |
188 | uint64_t journal_file_entry_n_items(Object *o) _pure_; |
189 | uint64_t journal_file_entry_array_n_items(Object *o) _pure_; | |
190 | uint64_t journal_file_hash_table_n_items(Object *o) _pure_; | |
87d2c1ff | 191 | |
78519831 | 192 | int journal_file_append_object(JournalFile *f, ObjectType type, uint64_t size, Object **ret, uint64_t *offset); |
c2373f84 | 193 | 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); |
87d2c1ff | 194 | |
de190aef LP |
195 | int journal_file_find_data_object(JournalFile *f, const void *data, uint64_t size, Object **ret, uint64_t *offset); |
196 | int journal_file_find_data_object_with_hash(JournalFile *f, const void *data, uint64_t size, uint64_t hash, Object **ret, uint64_t *offset); | |
87d2c1ff | 197 | |
3c1668da LP |
198 | int journal_file_find_field_object(JournalFile *f, const void *field, uint64_t size, Object **ret, uint64_t *offset); |
199 | int journal_file_find_field_object_with_hash(JournalFile *f, const void *field, uint64_t size, uint64_t hash, Object **ret, uint64_t *offset); | |
200 | ||
1fc605b0 | 201 | void journal_file_reset_location(JournalFile *f); |
6573ef05 | 202 | void journal_file_save_location(JournalFile *f, direction_t direction, Object *o, uint64_t offset); |
d8ae66d7 | 203 | int journal_file_compare_locations(JournalFile *af, JournalFile *bf); |
f534928a | 204 | int journal_file_next_entry(JournalFile *f, uint64_t p, direction_t direction, Object **ret, uint64_t *offset); |
87d2c1ff | 205 | |
de190aef LP |
206 | 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); |
207 | ||
208 | int journal_file_move_to_entry_by_seqnum(JournalFile *f, uint64_t seqnum, direction_t direction, Object **ret, uint64_t *offset); | |
209 | int journal_file_move_to_entry_by_realtime(JournalFile *f, uint64_t realtime, direction_t direction, Object **ret, uint64_t *offset); | |
210 | 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); | |
211 | ||
cbdca852 | 212 | 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); |
de190aef LP |
213 | 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); |
214 | 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); | |
cbdca852 | 215 | 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); |
87d2c1ff | 216 | |
cf244689 LP |
217 | int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint64_t p, uint64_t *seqnum, Object **ret, uint64_t *offset); |
218 | ||
87d2c1ff | 219 | void journal_file_dump(JournalFile *f); |
dca6219e | 220 | void journal_file_print_header(JournalFile *f); |
87d2c1ff | 221 | |
baed47c3 | 222 | int journal_file_rotate(JournalFile **f, bool compress, bool seal); |
0ac38b70 | 223 | |
cf244689 LP |
224 | void journal_file_post_change(JournalFile *f); |
225 | ||
babfc091 LP |
226 | void journal_default_metrics(JournalMetrics *m, int fd); |
227 | ||
08984293 LP |
228 | int journal_file_get_cutoff_realtime_usec(JournalFile *f, usec_t *from, usec_t *to); |
229 | int journal_file_get_cutoff_monotonic_usec(JournalFile *f, sd_id128_t boot, usec_t *from, usec_t *to); | |
230 | ||
fb0951b0 | 231 | bool journal_file_rotate_suggested(JournalFile *f, usec_t max_file_usec); |