mirror of
https://github.com/systemd/systemd.git
synced 2025-03-19 22:50:17 +03:00
journal: Use header macros everywhere instead of JournalFile fields
Let's standardize on the journal header as a single source of truth and remove redundant information from the JournalFile struct.
This commit is contained in:
parent
bdb2d3c688
commit
4374d7eaac
@ -73,7 +73,7 @@ static int managed_journal_file_entry_array_punch_hole(JournalFile *f, uint64_t
|
||||
if (sz < MINIMUM_HOLE_SIZE)
|
||||
return 0;
|
||||
|
||||
if (p == le64toh(f->header->tail_object_offset) && !f->seal) {
|
||||
if (p == le64toh(f->header->tail_object_offset) && !JOURNAL_HEADER_SEALED(f->header)) {
|
||||
ssize_t n;
|
||||
|
||||
o.object.size = htole64(offset - p);
|
||||
@ -292,7 +292,7 @@ int managed_journal_file_set_offline(ManagedJournalFile *f, bool wait) {
|
||||
|
||||
assert(f);
|
||||
|
||||
if (!f->file->writable)
|
||||
if (!journal_file_writable(f->file))
|
||||
return -EPERM;
|
||||
|
||||
if (f->file->fd < 0 || !f->file->header)
|
||||
@ -367,7 +367,7 @@ ManagedJournalFile* managed_journal_file_close(ManagedJournalFile *f) {
|
||||
|
||||
#if HAVE_GCRYPT
|
||||
/* Write the final tag */
|
||||
if (f->file->seal && f->file->writable) {
|
||||
if (JOURNAL_HEADER_SEALED(f->file->header) && journal_file_writable(f->file)) {
|
||||
int r;
|
||||
|
||||
r = journal_file_append_tag(f->file);
|
||||
|
@ -31,7 +31,7 @@ int journal_file_append_tag(JournalFile *f) {
|
||||
|
||||
assert(f);
|
||||
|
||||
if (!f->seal)
|
||||
if (!JOURNAL_HEADER_SEALED(f->header))
|
||||
return 0;
|
||||
|
||||
if (!f->hmac_running)
|
||||
@ -69,7 +69,7 @@ int journal_file_hmac_start(JournalFile *f) {
|
||||
|
||||
assert(f);
|
||||
|
||||
if (!f->seal)
|
||||
if (!JOURNAL_HEADER_SEALED(f->header))
|
||||
return 0;
|
||||
|
||||
if (f->hmac_running)
|
||||
@ -94,7 +94,7 @@ static int journal_file_get_epoch(JournalFile *f, uint64_t realtime, uint64_t *e
|
||||
|
||||
assert(f);
|
||||
assert(epoch);
|
||||
assert(f->seal);
|
||||
assert(JOURNAL_HEADER_SEALED(f->header));
|
||||
|
||||
if (f->fss_start_usec == 0 ||
|
||||
f->fss_interval_usec == 0)
|
||||
@ -115,7 +115,7 @@ static int journal_file_fsprg_need_evolve(JournalFile *f, uint64_t realtime) {
|
||||
int r;
|
||||
assert(f);
|
||||
|
||||
if (!f->seal)
|
||||
if (!JOURNAL_HEADER_SEALED(f->header))
|
||||
return 0;
|
||||
|
||||
r = journal_file_get_epoch(f, realtime, &goal);
|
||||
@ -135,7 +135,7 @@ int journal_file_fsprg_evolve(JournalFile *f, uint64_t realtime) {
|
||||
|
||||
assert(f);
|
||||
|
||||
if (!f->seal)
|
||||
if (!JOURNAL_HEADER_SEALED(f->header))
|
||||
return 0;
|
||||
|
||||
r = journal_file_get_epoch(f, realtime, &goal);
|
||||
@ -163,7 +163,7 @@ int journal_file_fsprg_seek(JournalFile *f, uint64_t goal) {
|
||||
|
||||
assert(f);
|
||||
|
||||
if (!f->seal)
|
||||
if (!JOURNAL_HEADER_SEALED(f->header))
|
||||
return 0;
|
||||
|
||||
assert(f->fsprg_seed);
|
||||
@ -199,7 +199,7 @@ int journal_file_maybe_append_tag(JournalFile *f, uint64_t realtime) {
|
||||
|
||||
assert(f);
|
||||
|
||||
if (!f->seal)
|
||||
if (!JOURNAL_HEADER_SEALED(f->header))
|
||||
return 0;
|
||||
|
||||
if (realtime <= 0)
|
||||
@ -225,7 +225,7 @@ int journal_file_hmac_put_object(JournalFile *f, ObjectType type, Object *o, uin
|
||||
|
||||
assert(f);
|
||||
|
||||
if (!f->seal)
|
||||
if (!JOURNAL_HEADER_SEALED(f->header))
|
||||
return 0;
|
||||
|
||||
r = journal_file_hmac_start(f);
|
||||
@ -285,7 +285,7 @@ int journal_file_hmac_put_header(JournalFile *f) {
|
||||
|
||||
assert(f);
|
||||
|
||||
if (!f->seal)
|
||||
if (!JOURNAL_HEADER_SEALED(f->header))
|
||||
return 0;
|
||||
|
||||
r = journal_file_hmac_start(f);
|
||||
@ -316,8 +316,8 @@ int journal_file_fss_load(JournalFile *f) {
|
||||
|
||||
assert(f);
|
||||
|
||||
if (!f->seal)
|
||||
return 0;
|
||||
/* This function is used to determine whether sealing should be enabled in the journal header so we
|
||||
* can't check the header to check if sealing is enabled here. */
|
||||
|
||||
r = sd_id128_get_machine(&machine);
|
||||
if (r < 0)
|
||||
@ -418,7 +418,7 @@ finish:
|
||||
int journal_file_hmac_setup(JournalFile *f) {
|
||||
gcry_error_t e;
|
||||
|
||||
if (!f->seal)
|
||||
if (!JOURNAL_HEADER_SEALED(f->header))
|
||||
return 0;
|
||||
|
||||
initialize_libgcrypt(true);
|
||||
@ -434,7 +434,7 @@ int journal_file_append_first_tag(JournalFile *f) {
|
||||
int r;
|
||||
uint64_t p;
|
||||
|
||||
if (!f->seal)
|
||||
if (!JOURNAL_HEADER_SEALED(f->header))
|
||||
return 0;
|
||||
|
||||
log_debug("Calculating first tag...");
|
||||
@ -530,7 +530,7 @@ bool journal_file_next_evolve_usec(JournalFile *f, usec_t *u) {
|
||||
assert(f);
|
||||
assert(u);
|
||||
|
||||
if (!f->seal)
|
||||
if (!JOURNAL_HEADER_SEALED(f->header))
|
||||
return false;
|
||||
|
||||
epoch = FSPRG_GetEpoch(f->fsprg_state);
|
||||
|
@ -191,7 +191,7 @@ static int journal_file_set_online(JournalFile *f) {
|
||||
|
||||
assert(f);
|
||||
|
||||
if (!f->writable)
|
||||
if (!journal_file_writable(f))
|
||||
return -EPERM;
|
||||
|
||||
if (f->fd < 0 || !f->header)
|
||||
@ -285,24 +285,38 @@ JournalFile* journal_file_close(JournalFile *f) {
|
||||
return mfree(f);
|
||||
}
|
||||
|
||||
static int journal_file_init_header(JournalFile *f, JournalFile *template) {
|
||||
static int journal_file_init_header(JournalFile *f, JournalFileFlags file_flags, JournalFile *template) {
|
||||
Header h = {};
|
||||
ssize_t k;
|
||||
bool keyed_hash, seal = false;
|
||||
int r;
|
||||
|
||||
assert(f);
|
||||
|
||||
/* We turn on keyed hashes by default, but provide an environment variable to turn them off, if
|
||||
* people really want that */
|
||||
r = getenv_bool("SYSTEMD_JOURNAL_KEYED_HASH");
|
||||
if (r < 0) {
|
||||
if (r != -ENXIO)
|
||||
log_debug_errno(r, "Failed to parse $SYSTEMD_JOURNAL_KEYED_HASH environment variable, ignoring: %m");
|
||||
keyed_hash = true;
|
||||
} else
|
||||
keyed_hash = r;
|
||||
|
||||
#if HAVE_GCRYPT
|
||||
/* Try to load the FSPRG state, and if we can't, then just don't do sealing */
|
||||
seal = FLAGS_SET(file_flags, JOURNAL_SEAL) && journal_file_fss_load(f) >= 0;
|
||||
#endif
|
||||
|
||||
memcpy(h.signature, HEADER_SIGNATURE, 8);
|
||||
h.header_size = htole64(ALIGN64(sizeof(h)));
|
||||
|
||||
h.incompatible_flags |= htole32(
|
||||
f->compress_xz * HEADER_INCOMPATIBLE_COMPRESSED_XZ |
|
||||
f->compress_lz4 * HEADER_INCOMPATIBLE_COMPRESSED_LZ4 |
|
||||
f->compress_zstd * HEADER_INCOMPATIBLE_COMPRESSED_ZSTD |
|
||||
f->keyed_hash * HEADER_INCOMPATIBLE_KEYED_HASH);
|
||||
FLAGS_SET(file_flags, JOURNAL_COMPRESS) *
|
||||
COMPRESSION_TO_HEADER_INCOMPATIBLE_FLAG(DEFAULT_COMPRESSION) |
|
||||
keyed_hash * HEADER_INCOMPATIBLE_KEYED_HASH);
|
||||
|
||||
h.compatible_flags = htole32(
|
||||
f->seal * HEADER_COMPATIBLE_SEALED);
|
||||
h.compatible_flags = htole32(seal * HEADER_COMPATIBLE_SEALED);
|
||||
|
||||
r = sd_id128_randomize(&h.file_id);
|
||||
if (r < 0)
|
||||
@ -409,7 +423,7 @@ static int journal_file_verify_header(JournalFile *f) {
|
||||
return -EPROTONOSUPPORT;
|
||||
|
||||
/* When open for writing we refuse to open files with compatible flags, too. */
|
||||
if (f->writable && warn_wrong_flags(f, true))
|
||||
if (journal_file_writable(f) && warn_wrong_flags(f, true))
|
||||
return -EPROTONOSUPPORT;
|
||||
|
||||
if (f->header->state >= _STATE_MAX)
|
||||
@ -438,7 +452,7 @@ static int journal_file_verify_header(JournalFile *f) {
|
||||
!VALID64(le64toh(f->header->entry_array_offset)))
|
||||
return -ENODATA;
|
||||
|
||||
if (f->writable) {
|
||||
if (journal_file_writable(f)) {
|
||||
sd_id128_t machine_id;
|
||||
uint8_t state;
|
||||
int r;
|
||||
@ -475,14 +489,6 @@ static int journal_file_verify_header(JournalFile *f) {
|
||||
f->path);
|
||||
}
|
||||
|
||||
f->compress_xz = JOURNAL_HEADER_COMPRESSED_XZ(f->header);
|
||||
f->compress_lz4 = JOURNAL_HEADER_COMPRESSED_LZ4(f->header);
|
||||
f->compress_zstd = JOURNAL_HEADER_COMPRESSED_ZSTD(f->header);
|
||||
|
||||
f->seal = JOURNAL_HEADER_SEALED(f->header);
|
||||
|
||||
f->keyed_hash = JOURNAL_HEADER_KEYED_HASH(f->header);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1240,7 +1246,7 @@ static int next_hash_offset(
|
||||
(*depth)++;
|
||||
|
||||
/* If the depth of this hash chain is larger than all others we have seen so far, record it */
|
||||
if (header_max_depth && f->writable)
|
||||
if (header_max_depth && journal_file_writable(f))
|
||||
*header_max_depth = htole64(MAX(*depth, le64toh(*header_max_depth)));
|
||||
}
|
||||
|
||||
@ -1589,7 +1595,7 @@ static int journal_file_append_data(
|
||||
compression = compress_blob(data, size, o->data.payload, size - 1, &rsize);
|
||||
if (compression > COMPRESSION_NONE) {
|
||||
o->object.size = htole64(offsetof(Object, data.payload) + rsize);
|
||||
o->object.flags |= COMPRESSION_TO_MASK(compression);
|
||||
o->object.flags |= COMPRESSION_TO_OBJECT_FLAG(compression);
|
||||
|
||||
log_debug("Compressed data object %"PRIu64" -> %zu using %s",
|
||||
size, rsize, compression_to_string(compression));
|
||||
@ -3372,54 +3378,12 @@ int journal_file_open(
|
||||
*f = (JournalFile) {
|
||||
.fd = fd,
|
||||
.mode = mode,
|
||||
|
||||
.open_flags = open_flags,
|
||||
.writable = (open_flags & O_ACCMODE) != O_RDONLY,
|
||||
|
||||
.compress_threshold_bytes = compress_threshold_bytes == UINT64_MAX ?
|
||||
DEFAULT_COMPRESS_THRESHOLD :
|
||||
MAX(MIN_COMPRESS_THRESHOLD, compress_threshold_bytes),
|
||||
#if HAVE_GCRYPT
|
||||
.seal = FLAGS_SET(file_flags, JOURNAL_SEAL),
|
||||
#endif
|
||||
};
|
||||
|
||||
if (DEFAULT_COMPRESSION == COMPRESSION_ZSTD)
|
||||
f->compress_zstd = FLAGS_SET(file_flags, JOURNAL_COMPRESS);
|
||||
else if (DEFAULT_COMPRESSION == COMPRESSION_LZ4)
|
||||
f->compress_lz4 = FLAGS_SET(file_flags, JOURNAL_COMPRESS);
|
||||
else if (DEFAULT_COMPRESSION == COMPRESSION_XZ)
|
||||
f->compress_xz = FLAGS_SET(file_flags, JOURNAL_COMPRESS);
|
||||
|
||||
/* We turn on keyed hashes by default, but provide an environment variable to turn them off, if
|
||||
* people really want that */
|
||||
r = getenv_bool("SYSTEMD_JOURNAL_KEYED_HASH");
|
||||
if (r < 0) {
|
||||
if (r != -ENXIO)
|
||||
log_debug_errno(r, "Failed to parse $SYSTEMD_JOURNAL_KEYED_HASH environment variable, ignoring: %m");
|
||||
f->keyed_hash = true;
|
||||
} else
|
||||
f->keyed_hash = r;
|
||||
|
||||
if (DEBUG_LOGGING) {
|
||||
static int last_seal = -1, last_compress = -1, last_keyed_hash = -1;
|
||||
static uint64_t last_bytes = UINT64_MAX;
|
||||
|
||||
if (last_seal != f->seal ||
|
||||
last_keyed_hash != f->keyed_hash ||
|
||||
last_compress != JOURNAL_FILE_COMPRESS(f) ||
|
||||
last_bytes != f->compress_threshold_bytes) {
|
||||
|
||||
log_debug("Journal effective settings seal=%s keyed_hash=%s compress=%s compress_threshold_bytes=%s",
|
||||
yes_no(f->seal), yes_no(f->keyed_hash), yes_no(JOURNAL_FILE_COMPRESS(f)),
|
||||
FORMAT_BYTES(f->compress_threshold_bytes));
|
||||
last_seal = f->seal;
|
||||
last_keyed_hash = f->keyed_hash;
|
||||
last_compress = JOURNAL_FILE_COMPRESS(f);
|
||||
last_bytes = f->compress_threshold_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
if (fname) {
|
||||
f->path = strdup(fname);
|
||||
if (!f->path) {
|
||||
@ -3471,7 +3435,7 @@ int journal_file_open(
|
||||
goto fail;
|
||||
|
||||
/* If we just got the fd passed in, we don't really know if we created the file anew */
|
||||
newly_created = f->last_stat.st_size == 0 && f->writable;
|
||||
newly_created = f->last_stat.st_size == 0 && journal_file_writable(f);
|
||||
}
|
||||
|
||||
f->cache_fd = mmap_cache_add_fd(mmap_cache, f->fd, prot_from_flags(open_flags));
|
||||
@ -3490,17 +3454,7 @@ int journal_file_open(
|
||||
* solely on mtime/atime/ctime of the file. */
|
||||
(void) fd_setcrtime(f->fd, 0);
|
||||
|
||||
#if HAVE_GCRYPT
|
||||
/* Try to load the FSPRG state, and if we can't, then
|
||||
* just don't do sealing */
|
||||
if (f->seal) {
|
||||
r = journal_file_fss_load(f);
|
||||
if (r < 0)
|
||||
f->seal = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
r = journal_file_init_header(f, template);
|
||||
r = journal_file_init_header(f, file_flags, template);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
@ -3534,14 +3488,14 @@ int journal_file_open(
|
||||
}
|
||||
|
||||
#if HAVE_GCRYPT
|
||||
if (!newly_created && f->writable) {
|
||||
if (!newly_created && journal_file_writable(f) && JOURNAL_HEADER_SEALED(f->header)) {
|
||||
r = journal_file_fss_load(f);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (f->writable) {
|
||||
if (journal_file_writable(f)) {
|
||||
if (metrics) {
|
||||
journal_default_metrics(metrics, f->fd);
|
||||
f->metrics = *metrics;
|
||||
@ -3593,6 +3547,25 @@ int journal_file_open(
|
||||
/* The file is opened now successfully, thus we take possession of any passed in fd. */
|
||||
f->close_fd = true;
|
||||
|
||||
if (DEBUG_LOGGING) {
|
||||
static int last_seal = -1, last_compress = -1, last_keyed_hash = -1;
|
||||
static uint64_t last_bytes = UINT64_MAX;
|
||||
|
||||
if (last_seal != JOURNAL_HEADER_SEALED(f->header) ||
|
||||
last_keyed_hash != JOURNAL_HEADER_KEYED_HASH(f->header) ||
|
||||
last_compress != JOURNAL_FILE_COMPRESS(f) ||
|
||||
last_bytes != f->compress_threshold_bytes) {
|
||||
|
||||
log_debug("Journal effective settings seal=%s keyed_hash=%s compress=%s compress_threshold_bytes=%s",
|
||||
yes_no(JOURNAL_HEADER_SEALED(f->header)), yes_no(JOURNAL_HEADER_KEYED_HASH(f->header)),
|
||||
yes_no(JOURNAL_FILE_COMPRESS(f)), FORMAT_BYTES(f->compress_threshold_bytes));
|
||||
last_seal = JOURNAL_HEADER_SEALED(f->header);
|
||||
last_keyed_hash = JOURNAL_HEADER_KEYED_HASH(f->header);
|
||||
last_compress = JOURNAL_FILE_COMPRESS(f);
|
||||
last_bytes = f->compress_threshold_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
*ret = f;
|
||||
return 0;
|
||||
|
||||
@ -3613,7 +3586,7 @@ int journal_file_archive(JournalFile *f, char **ret_previous_path) {
|
||||
|
||||
assert(f);
|
||||
|
||||
if (!f->writable)
|
||||
if (!journal_file_writable(f))
|
||||
return -EINVAL;
|
||||
|
||||
/* Is this a journal file that was passed to us as fd? If so, we synthesized a path name for it, and we refuse
|
||||
@ -3693,7 +3666,7 @@ int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint6
|
||||
assert(o);
|
||||
assert(p);
|
||||
|
||||
if (!to->writable)
|
||||
if (!journal_file_writable(to))
|
||||
return -EPERM;
|
||||
|
||||
ts = (dual_timestamp) {
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
@ -64,14 +65,8 @@ typedef struct JournalFile {
|
||||
mode_t mode;
|
||||
|
||||
int open_flags;
|
||||
bool writable:1;
|
||||
bool compress_xz:1;
|
||||
bool compress_lz4:1;
|
||||
bool compress_zstd:1;
|
||||
bool seal:1;
|
||||
bool close_fd:1;
|
||||
bool archive:1;
|
||||
bool keyed_hash:1;
|
||||
|
||||
direction_t last_direction;
|
||||
LocationType location_type;
|
||||
@ -258,7 +253,8 @@ int journal_file_map_field_hash_table(JournalFile *f);
|
||||
|
||||
static inline bool JOURNAL_FILE_COMPRESS(JournalFile *f) {
|
||||
assert(f);
|
||||
return f->compress_xz || f->compress_lz4 || f->compress_zstd;
|
||||
return JOURNAL_HEADER_COMPRESSED_XZ(f->header) || JOURNAL_HEADER_COMPRESSED_LZ4(f->header) ||
|
||||
JOURNAL_HEADER_COMPRESSED_ZSTD(f->header);
|
||||
}
|
||||
|
||||
uint64_t journal_file_hash_data(JournalFile *f, const void *data, size_t sz);
|
||||
@ -284,7 +280,7 @@ static inline Compression COMPRESSION_FROM_OBJECT(const Object *o) {
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint8_t COMPRESSION_TO_MASK(Compression c) {
|
||||
static inline uint8_t COMPRESSION_TO_OBJECT_FLAG(Compression c) {
|
||||
switch (c) {
|
||||
case COMPRESSION_XZ:
|
||||
return OBJECT_COMPRESSED_XZ;
|
||||
@ -296,3 +292,21 @@ static inline uint8_t COMPRESSION_TO_MASK(Compression c) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t COMPRESSION_TO_HEADER_INCOMPATIBLE_FLAG(Compression c) {
|
||||
switch (c) {
|
||||
case COMPRESSION_XZ:
|
||||
return HEADER_INCOMPATIBLE_COMPRESSED_XZ;
|
||||
case COMPRESSION_LZ4:
|
||||
return HEADER_INCOMPATIBLE_COMPRESSED_LZ4;
|
||||
case COMPRESSION_ZSTD:
|
||||
return HEADER_INCOMPATIBLE_COMPRESSED_ZSTD;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool journal_file_writable(JournalFile *f) {
|
||||
assert(f);
|
||||
return (f->open_flags & O_ACCMODE) != O_RDONLY;
|
||||
}
|
||||
|
@ -842,7 +842,7 @@ int journal_file_verify(
|
||||
#else
|
||||
return -EOPNOTSUPP;
|
||||
#endif
|
||||
} else if (f->seal)
|
||||
} else if (JOURNAL_HEADER_SEALED(f->header))
|
||||
return -ENOKEY;
|
||||
|
||||
r = var_tmp_dir(&tmp_dir);
|
||||
@ -1130,7 +1130,7 @@ int journal_file_verify(
|
||||
}
|
||||
|
||||
#if HAVE_GCRYPT
|
||||
if (f->seal) {
|
||||
if (JOURNAL_HEADER_SEALED(f->header)) {
|
||||
uint64_t q, rt;
|
||||
|
||||
debug(p, "Checking tag %"PRIu64"...", le64toh(o->tag.seqnum));
|
||||
|
Loading…
x
Reference in New Issue
Block a user