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