]>
Commit | Line | Data |
---|---|---|
663996b3 MS |
1 | /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ |
2 | ||
3 | #pragma once | |
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 | |
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 | |
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 | |
18 | Lesser General Public License for more details. | |
19 | ||
20 | You should have received a copy of the GNU Lesser General Public License | |
21 | along with systemd; If not, see <http://www.gnu.org/licenses/>. | |
22 | ***/ | |
23 | ||
24 | #include <inttypes.h> | |
25 | ||
26 | #ifdef HAVE_GCRYPT | |
27 | #include <gcrypt.h> | |
28 | #endif | |
29 | ||
e735f4d4 | 30 | #include "sd-id128.h" |
663996b3 MS |
31 | |
32 | #include "sparse-endian.h" | |
33 | #include "journal-def.h" | |
e735f4d4 | 34 | #include "macro.h" |
663996b3 MS |
35 | #include "mmap-cache.h" |
36 | #include "hashmap.h" | |
37 | ||
38 | typedef struct JournalMetrics { | |
6300502b MP |
39 | /* For all these: -1 means "pick automatically", and 0 means "no limit enforced" */ |
40 | uint64_t max_size; /* how large journal files grow at max */ | |
41 | uint64_t min_size; /* how large journal files grow at least */ | |
42 | uint64_t max_use; /* how much disk space to use in total at max, keep_free permitting */ | |
43 | uint64_t min_use; /* how much disk space to use in total at least, even if keep_free says not to */ | |
44 | uint64_t keep_free; /* how much to keep free on disk */ | |
45 | uint64_t n_max_files; /* how many files to keep around at max */ | |
663996b3 MS |
46 | } JournalMetrics; |
47 | ||
14228c0d MB |
48 | typedef enum direction { |
49 | DIRECTION_UP, | |
50 | DIRECTION_DOWN | |
51 | } direction_t; | |
52 | ||
e735f4d4 MP |
53 | typedef enum LocationType { |
54 | /* The first and last entries, resp. */ | |
55 | LOCATION_HEAD, | |
56 | LOCATION_TAIL, | |
57 | ||
58 | /* We already read the entry we currently point to, and the | |
59 | * next one to read should probably not be this one again. */ | |
60 | LOCATION_DISCRETE, | |
61 | ||
62 | /* We should seek to the precise location specified, and | |
63 | * return it, as we haven't read it yet. */ | |
64 | LOCATION_SEEK | |
65 | } LocationType; | |
66 | ||
663996b3 MS |
67 | typedef struct JournalFile { |
68 | int fd; | |
14228c0d | 69 | |
663996b3 MS |
70 | mode_t mode; |
71 | ||
72 | int flags; | |
73 | int prot; | |
60f067b4 | 74 | bool writable:1; |
5eef597e MP |
75 | bool compress_xz:1; |
76 | bool compress_lz4:1; | |
60f067b4 | 77 | bool seal:1; |
e735f4d4 | 78 | bool defrag_on_close:1; |
663996b3 | 79 | |
60f067b4 | 80 | bool tail_entry_monotonic_valid:1; |
663996b3 | 81 | |
14228c0d | 82 | direction_t last_direction; |
e735f4d4 MP |
83 | LocationType location_type; |
84 | uint64_t last_n_entries; | |
14228c0d MB |
85 | |
86 | char *path; | |
87 | struct stat last_stat; | |
e735f4d4 | 88 | usec_t last_stat_usec; |
14228c0d | 89 | |
663996b3 MS |
90 | Header *header; |
91 | HashItem *data_hash_table; | |
92 | HashItem *field_hash_table; | |
93 | ||
94 | uint64_t current_offset; | |
e735f4d4 MP |
95 | uint64_t current_seqnum; |
96 | uint64_t current_realtime; | |
97 | uint64_t current_monotonic; | |
98 | sd_id128_t current_boot_id; | |
99 | uint64_t current_xor_hash; | |
663996b3 MS |
100 | |
101 | JournalMetrics metrics; | |
102 | MMapCache *mmap; | |
103 | ||
5eef597e | 104 | OrderedHashmap *chain_cache; |
663996b3 | 105 | |
5eef597e | 106 | #if defined(HAVE_XZ) || defined(HAVE_LZ4) |
663996b3 | 107 | void *compress_buffer; |
5eef597e | 108 | size_t compress_buffer_size; |
663996b3 MS |
109 | #endif |
110 | ||
111 | #ifdef HAVE_GCRYPT | |
112 | gcry_md_hd_t hmac; | |
113 | bool hmac_running; | |
114 | ||
115 | FSSHeader *fss_file; | |
116 | size_t fss_file_size; | |
117 | ||
118 | uint64_t fss_start_usec; | |
119 | uint64_t fss_interval_usec; | |
120 | ||
121 | void *fsprg_state; | |
122 | size_t fsprg_state_size; | |
123 | ||
124 | void *fsprg_seed; | |
125 | size_t fsprg_seed_size; | |
126 | #endif | |
127 | } JournalFile; | |
128 | ||
663996b3 MS |
129 | int journal_file_open( |
130 | const char *fname, | |
131 | int flags, | |
132 | mode_t mode, | |
133 | bool compress, | |
134 | bool seal, | |
135 | JournalMetrics *metrics, | |
136 | MMapCache *mmap_cache, | |
137 | JournalFile *template, | |
138 | JournalFile **ret); | |
139 | ||
140 | int journal_file_set_offline(JournalFile *f); | |
6300502b | 141 | JournalFile* journal_file_close(JournalFile *j); |
663996b3 MS |
142 | |
143 | int journal_file_open_reliably( | |
144 | const char *fname, | |
145 | int flags, | |
146 | mode_t mode, | |
147 | bool compress, | |
148 | bool seal, | |
149 | JournalMetrics *metrics, | |
150 | MMapCache *mmap_cache, | |
151 | JournalFile *template, | |
152 | JournalFile **ret); | |
153 | ||
154 | #define ALIGN64(x) (((x) + 7ULL) & ~7ULL) | |
155 | #define VALID64(x) (((x) & 7ULL) == 0ULL) | |
156 | ||
60f067b4 JS |
157 | /* Use six characters to cover the offsets common in smallish journal |
158 | * files without adding too many zeros. */ | |
159 | #define OFSfmt "%06"PRIx64 | |
160 | ||
663996b3 MS |
161 | static inline bool VALID_REALTIME(uint64_t u) { |
162 | /* This considers timestamps until the year 3112 valid. That should be plenty room... */ | |
163 | return u > 0 && u < (1ULL << 55); | |
164 | } | |
165 | ||
166 | static inline bool VALID_MONOTONIC(uint64_t u) { | |
167 | /* This considers timestamps until 1142 years of runtime valid. */ | |
168 | return u < (1ULL << 55); | |
169 | } | |
170 | ||
171 | static inline bool VALID_EPOCH(uint64_t u) { | |
172 | /* This allows changing the key for 1142 years, every usec. */ | |
173 | return u < (1ULL << 55); | |
174 | } | |
175 | ||
176 | #define JOURNAL_HEADER_CONTAINS(h, field) \ | |
177 | (le64toh((h)->header_size) >= offsetof(Header, field) + sizeof((h)->field)) | |
178 | ||
179 | #define JOURNAL_HEADER_SEALED(h) \ | |
180 | (!!(le32toh((h)->compatible_flags) & HEADER_COMPATIBLE_SEALED)) | |
181 | ||
5eef597e MP |
182 | #define JOURNAL_HEADER_COMPRESSED_XZ(h) \ |
183 | (!!(le32toh((h)->incompatible_flags) & HEADER_INCOMPATIBLE_COMPRESSED_XZ)) | |
184 | ||
185 | #define JOURNAL_HEADER_COMPRESSED_LZ4(h) \ | |
186 | (!!(le32toh((h)->incompatible_flags) & HEADER_INCOMPATIBLE_COMPRESSED_LZ4)) | |
663996b3 | 187 | |
e735f4d4 | 188 | int journal_file_move_to_object(JournalFile *f, ObjectType type, uint64_t offset, Object **ret); |
663996b3 MS |
189 | |
190 | uint64_t journal_file_entry_n_items(Object *o) _pure_; | |
191 | uint64_t journal_file_entry_array_n_items(Object *o) _pure_; | |
192 | uint64_t journal_file_hash_table_n_items(Object *o) _pure_; | |
193 | ||
e735f4d4 | 194 | int journal_file_append_object(JournalFile *f, ObjectType type, uint64_t size, Object **ret, uint64_t *offset); |
663996b3 MS |
195 | 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); |
196 | ||
197 | int journal_file_find_data_object(JournalFile *f, const void *data, uint64_t size, Object **ret, uint64_t *offset); | |
198 | int journal_file_find_data_object_with_hash(JournalFile *f, const void *data, uint64_t size, uint64_t hash, Object **ret, uint64_t *offset); | |
199 | ||
200 | int journal_file_find_field_object(JournalFile *f, const void *field, uint64_t size, Object **ret, uint64_t *offset); | |
201 | int journal_file_find_field_object_with_hash(JournalFile *f, const void *field, uint64_t size, uint64_t hash, Object **ret, uint64_t *offset); | |
202 | ||
e735f4d4 | 203 | void journal_file_reset_location(JournalFile *f); |
e3bff60a | 204 | void journal_file_save_location(JournalFile *f, Object *o, uint64_t offset); |
e735f4d4 MP |
205 | int journal_file_compare_locations(JournalFile *af, JournalFile *bf); |
206 | int journal_file_next_entry(JournalFile *f, uint64_t p, direction_t direction, Object **ret, uint64_t *offset); | |
663996b3 MS |
207 | |
208 | 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); | |
209 | ||
663996b3 MS |
210 | int journal_file_move_to_entry_by_seqnum(JournalFile *f, uint64_t seqnum, direction_t direction, Object **ret, uint64_t *offset); |
211 | int journal_file_move_to_entry_by_realtime(JournalFile *f, uint64_t realtime, direction_t direction, Object **ret, uint64_t *offset); | |
212 | 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); | |
213 | ||
214 | 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); | |
215 | 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); | |
216 | 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); | |
217 | 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); | |
218 | ||
219 | int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint64_t p, uint64_t *seqnum, Object **ret, uint64_t *offset); | |
220 | ||
221 | void journal_file_dump(JournalFile *f); | |
222 | void journal_file_print_header(JournalFile *f); | |
223 | ||
224 | int journal_file_rotate(JournalFile **f, bool compress, bool seal); | |
225 | ||
226 | void journal_file_post_change(JournalFile *f); | |
227 | ||
6300502b | 228 | void journal_reset_metrics(JournalMetrics *m); |
663996b3 MS |
229 | void journal_default_metrics(JournalMetrics *m, int fd); |
230 | ||
231 | int journal_file_get_cutoff_realtime_usec(JournalFile *f, usec_t *from, usec_t *to); | |
232 | int journal_file_get_cutoff_monotonic_usec(JournalFile *f, sd_id128_t boot, usec_t *from, usec_t *to); | |
233 | ||
234 | bool journal_file_rotate_suggested(JournalFile *f, usec_t max_file_usec); | |
7035cd9e MP |
235 | |
236 | int journal_file_map_data_hash_table(JournalFile *f); | |
237 | int journal_file_map_field_hash_table(JournalFile *f); |