]>
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 | ||
73f860db | 30 | #include "systemd/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 | ||
f4b47811 LP |
51 | typedef struct JournalFile { |
52 | int fd; | |
87011c25 | 53 | |
0ac38b70 | 54 | mode_t mode; |
7560fffc | 55 | |
0ac38b70 | 56 | int flags; |
f4b47811 | 57 | int prot; |
b8e891e6 | 58 | bool writable:1; |
d89c8fdf ZJS |
59 | bool compress_xz:1; |
60 | bool compress_lz4:1; | |
b8e891e6 | 61 | bool seal:1; |
7560fffc | 62 | |
b8e891e6 | 63 | bool tail_entry_monotonic_valid:1; |
f4b47811 | 64 | |
87011c25 ZJS |
65 | direction_t last_direction; |
66 | ||
67 | char *path; | |
68 | struct stat last_stat; | |
69 | ||
f4b47811 | 70 | Header *header; |
de190aef LP |
71 | HashItem *data_hash_table; |
72 | HashItem *field_hash_table; | |
f4b47811 | 73 | |
f4b47811 | 74 | uint64_t current_offset; |
bc85bfee LP |
75 | |
76 | JournalMetrics metrics; | |
16e9f408 | 77 | MMapCache *mmap; |
807e17f0 | 78 | |
a4bcff5b LP |
79 | Hashmap *chain_cache; |
80 | ||
807e17f0 LP |
81 | #ifdef HAVE_XZ |
82 | void *compress_buffer; | |
fa1c4b51 | 83 | size_t compress_buffer_size; |
807e17f0 | 84 | #endif |
7560fffc LP |
85 | |
86 | #ifdef HAVE_GCRYPT | |
87 | gcry_md_hd_t hmac; | |
88 | bool hmac_running; | |
89 | ||
baed47c3 LP |
90 | FSSHeader *fss_file; |
91 | size_t fss_file_size; | |
92 | ||
93 | uint64_t fss_start_usec; | |
94 | uint64_t fss_interval_usec; | |
b7c9ae91 LP |
95 | |
96 | void *fsprg_state; | |
97 | size_t fsprg_state_size; | |
98 | ||
99 | void *fsprg_seed; | |
100 | size_t fsprg_seed_size; | |
7560fffc | 101 | #endif |
f4b47811 LP |
102 | } JournalFile; |
103 | ||
4a92baf3 LP |
104 | int journal_file_open( |
105 | const char *fname, | |
106 | int flags, | |
107 | mode_t mode, | |
7560fffc | 108 | bool compress, |
baed47c3 | 109 | bool seal, |
4a92baf3 | 110 | JournalMetrics *metrics, |
27370278 | 111 | MMapCache *mmap_cache, |
4a92baf3 LP |
112 | JournalFile *template, |
113 | JournalFile **ret); | |
114 | ||
26687bf8 | 115 | int journal_file_set_offline(JournalFile *f); |
87d2c1ff LP |
116 | void journal_file_close(JournalFile *j); |
117 | ||
4a92baf3 LP |
118 | int journal_file_open_reliably( |
119 | const char *fname, | |
120 | int flags, | |
121 | mode_t mode, | |
7560fffc | 122 | bool compress, |
baed47c3 | 123 | bool seal, |
4a92baf3 | 124 | JournalMetrics *metrics, |
27370278 | 125 | MMapCache *mmap_cache, |
4a92baf3 LP |
126 | JournalFile *template, |
127 | JournalFile **ret); | |
9447a7f1 | 128 | |
0284adc6 | 129 | #define ALIGN64(x) (((x) + 7ULL) & ~7ULL) |
db11ac1a | 130 | #define VALID64(x) (((x) & 7ULL) == 0ULL) |
0284adc6 | 131 | |
ae97089d ZJS |
132 | /* Use six characters to cover the offsets common in smallish journal |
133 | * files without adding too many zeros. */ | |
134 | #define OFSfmt "%06"PRIx64 | |
135 | ||
fc89a139 LP |
136 | static inline bool VALID_REALTIME(uint64_t u) { |
137 | /* This considers timestamps until the year 3112 valid. That should be plenty room... */ | |
138 | return u > 0 && u < (1ULL << 55); | |
139 | } | |
140 | ||
141 | static inline bool VALID_MONOTONIC(uint64_t u) { | |
142 | /* This considers timestamps until 1142 years of runtime valid. */ | |
143 | return u < (1ULL << 55); | |
144 | } | |
145 | ||
146 | static inline bool VALID_EPOCH(uint64_t u) { | |
147 | /* This allows changing the key for 1142 years, every usec. */ | |
148 | return u < (1ULL << 55); | |
149 | } | |
150 | ||
0284adc6 LP |
151 | #define JOURNAL_HEADER_CONTAINS(h, field) \ |
152 | (le64toh((h)->header_size) >= offsetof(Header, field) + sizeof((h)->field)) | |
153 | ||
8088cbd3 LP |
154 | #define JOURNAL_HEADER_SEALED(h) \ |
155 | (!!(le32toh((h)->compatible_flags) & HEADER_COMPATIBLE_SEALED)) | |
156 | ||
d89c8fdf ZJS |
157 | #define JOURNAL_HEADER_COMPRESSED_XZ(h) \ |
158 | (!!(le32toh((h)->incompatible_flags) & HEADER_INCOMPATIBLE_COMPRESSED_XZ)) | |
159 | ||
160 | #define JOURNAL_HEADER_COMPRESSED_LZ4(h) \ | |
161 | (!!(le32toh((h)->incompatible_flags) & HEADER_INCOMPATIBLE_COMPRESSED_LZ4)) | |
8088cbd3 | 162 | |
de190aef | 163 | int journal_file_move_to_object(JournalFile *f, int type, uint64_t offset, Object **ret); |
87d2c1ff | 164 | |
44a6b1b6 ZJS |
165 | uint64_t journal_file_entry_n_items(Object *o) _pure_; |
166 | uint64_t journal_file_entry_array_n_items(Object *o) _pure_; | |
167 | uint64_t journal_file_hash_table_n_items(Object *o) _pure_; | |
87d2c1ff | 168 | |
0284adc6 | 169 | int journal_file_append_object(JournalFile *f, int type, uint64_t size, Object **ret, uint64_t *offset); |
c2373f84 | 170 | 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 | 171 | |
de190aef LP |
172 | int journal_file_find_data_object(JournalFile *f, const void *data, uint64_t size, Object **ret, uint64_t *offset); |
173 | 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 | 174 | |
3c1668da LP |
175 | int journal_file_find_field_object(JournalFile *f, const void *field, uint64_t size, Object **ret, uint64_t *offset); |
176 | int journal_file_find_field_object_with_hash(JournalFile *f, const void *field, uint64_t size, uint64_t hash, Object **ret, uint64_t *offset); | |
177 | ||
de190aef LP |
178 | int journal_file_next_entry(JournalFile *f, Object *o, uint64_t p, direction_t direction, Object **ret, uint64_t *offset); |
179 | int journal_file_skip_entry(JournalFile *f, Object *o, uint64_t p, int64_t skip, Object **ret, uint64_t *offset); | |
87d2c1ff | 180 | |
de190aef LP |
181 | 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); |
182 | ||
cbdca852 | 183 | int journal_file_move_to_entry_by_offset(JournalFile *f, uint64_t seqnum, direction_t direction, Object **ret, uint64_t *offset); |
de190aef LP |
184 | int journal_file_move_to_entry_by_seqnum(JournalFile *f, uint64_t seqnum, direction_t direction, Object **ret, uint64_t *offset); |
185 | int journal_file_move_to_entry_by_realtime(JournalFile *f, uint64_t realtime, direction_t direction, Object **ret, uint64_t *offset); | |
186 | 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); | |
187 | ||
cbdca852 | 188 | 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 |
189 | 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); |
190 | 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 | 191 | 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 | 192 | |
cf244689 LP |
193 | int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint64_t p, uint64_t *seqnum, Object **ret, uint64_t *offset); |
194 | ||
87d2c1ff | 195 | void journal_file_dump(JournalFile *f); |
dca6219e | 196 | void journal_file_print_header(JournalFile *f); |
87d2c1ff | 197 | |
baed47c3 | 198 | int journal_file_rotate(JournalFile **f, bool compress, bool seal); |
0ac38b70 | 199 | |
cf244689 LP |
200 | void journal_file_post_change(JournalFile *f); |
201 | ||
babfc091 LP |
202 | void journal_default_metrics(JournalMetrics *m, int fd); |
203 | ||
08984293 LP |
204 | int journal_file_get_cutoff_realtime_usec(JournalFile *f, usec_t *from, usec_t *to); |
205 | int journal_file_get_cutoff_monotonic_usec(JournalFile *f, sd_id128_t boot, usec_t *from, usec_t *to); | |
206 | ||
fb0951b0 | 207 | bool journal_file_rotate_suggested(JournalFile *f, usec_t max_file_usec); |
ae97089d ZJS |
208 | |
209 | ||
210 | static unsigned type_to_context(int type) { | |
211 | /* One context for each type, plus one catch-all for the rest */ | |
212 | return type > 0 && type < _OBJECT_TYPE_MAX ? type : 0; | |
213 | } | |
214 | ||
215 | static inline int journal_file_object_keep(JournalFile *f, Object *o, uint64_t offset) { | |
216 | unsigned context = type_to_context(o->object.type); | |
217 | ||
218 | return mmap_cache_get(f->mmap, f->fd, f->prot, context, true, | |
219 | offset, o->object.size, &f->last_stat, NULL); | |
220 | } | |
221 | ||
222 | static inline int journal_file_object_release(JournalFile *f, Object *o, uint64_t offset) { | |
223 | unsigned context = type_to_context(o->object.type); | |
224 | ||
225 | return mmap_cache_release(f->mmap, f->fd, f->prot, context, | |
226 | offset, o->object.size); | |
227 | } |