summaryrefslogtreecommitdiff
path: root/src/journal/journal-file.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/journal/journal-file.c')
-rw-r--r--src/journal/journal-file.c106
1 files changed, 64 insertions, 42 deletions
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index d3e0214731..ef87b176fa 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -42,6 +42,7 @@
#include "sd-event.h"
#include "set.h"
#include "string-util.h"
+#include "strv.h"
#include "xattr-util.h"
#define DEFAULT_DATA_HASH_TABLE_SIZE (2047ULL*sizeof(HashItem))
@@ -285,7 +286,7 @@ static int journal_file_set_online(JournalFile *f) {
continue;
/* Canceled restart from offlining, must wait for offlining to complete however. */
- /* fall through to wait */
+ /* fall through */
default: {
int r;
@@ -507,42 +508,58 @@ static int journal_file_refresh_header(JournalFile *f) {
return r;
}
-static int journal_file_verify_header(JournalFile *f) {
+static bool warn_wrong_flags(const JournalFile *f, bool compatible) {
+ const uint32_t any = compatible ? HEADER_COMPATIBLE_ANY : HEADER_INCOMPATIBLE_ANY,
+ supported = compatible ? HEADER_COMPATIBLE_SUPPORTED : HEADER_INCOMPATIBLE_SUPPORTED;
+ const char *type = compatible ? "compatible" : "incompatible";
uint32_t flags;
+ flags = le32toh(compatible ? f->header->compatible_flags : f->header->incompatible_flags);
+
+ if (flags & ~supported) {
+ if (flags & ~any)
+ log_debug("Journal file %s has unknown %s flags 0x%"PRIx32,
+ f->path, type, flags & ~any);
+ flags = (flags & any) & ~supported;
+ if (flags) {
+ const char* strv[3];
+ unsigned n = 0;
+ _cleanup_free_ char *t = NULL;
+
+ if (compatible && (flags & HEADER_COMPATIBLE_SEALED))
+ strv[n++] = "sealed";
+ if (!compatible && (flags & HEADER_INCOMPATIBLE_COMPRESSED_XZ))
+ strv[n++] = "xz-compressed";
+ if (!compatible && (flags & HEADER_INCOMPATIBLE_COMPRESSED_LZ4))
+ strv[n++] = "lz4-compressed";
+ strv[n] = NULL;
+ assert(n < ELEMENTSOF(strv));
+
+ t = strv_join((char**) strv, ", ");
+ log_debug("Journal file %s uses %s %s %s disabled at compilation time.",
+ f->path, type, n > 1 ? "flags" : "flag", strnull(t));
+ }
+ return true;
+ }
+
+ return false;
+}
+
+static int journal_file_verify_header(JournalFile *f) {
assert(f);
assert(f->header);
if (memcmp(f->header->signature, HEADER_SIGNATURE, 8))
return -EBADMSG;
- /* In both read and write mode we refuse to open files with
- * incompatible flags we don't know */
- flags = le32toh(f->header->incompatible_flags);
- if (flags & ~HEADER_INCOMPATIBLE_SUPPORTED) {
- if (flags & ~HEADER_INCOMPATIBLE_ANY)
- log_debug("Journal file %s has unknown incompatible flags %"PRIx32,
- f->path, flags & ~HEADER_INCOMPATIBLE_ANY);
- flags = (flags & HEADER_INCOMPATIBLE_ANY) & ~HEADER_INCOMPATIBLE_SUPPORTED;
- if (flags)
- log_debug("Journal file %s uses incompatible flags %"PRIx32
- " disabled at compilation time.", f->path, flags);
+ /* In both read and write mode we refuse to open files with incompatible
+ * flags we don't know. */
+ if (warn_wrong_flags(f, false))
return -EPROTONOSUPPORT;
- }
- /* When open for writing we refuse to open files with
- * compatible flags, too */
- flags = le32toh(f->header->compatible_flags);
- if (f->writable && (flags & ~HEADER_COMPATIBLE_SUPPORTED)) {
- if (flags & ~HEADER_COMPATIBLE_ANY)
- log_debug("Journal file %s has unknown compatible flags %"PRIx32,
- f->path, flags & ~HEADER_COMPATIBLE_ANY);
- flags = (flags & HEADER_COMPATIBLE_ANY) & ~HEADER_COMPATIBLE_SUPPORTED;
- if (flags)
- log_debug("Journal file %s uses compatible flags %"PRIx32
- " disabled at compilation time.", f->path, flags);
+ /* When open for writing we refuse to open files with compatible flags, too. */
+ if (f->writable && warn_wrong_flags(f, true))
return -EPROTONOSUPPORT;
- }
if (f->header->state >= _STATE_MAX)
return -EBADMSG;
@@ -580,12 +597,12 @@ static int journal_file_verify_header(JournalFile *f) {
state = f->header->state;
- if (state == STATE_ONLINE) {
+ if (state == STATE_ARCHIVED)
+ return -ESHUTDOWN; /* Already archived */
+ else if (state == STATE_ONLINE) {
log_debug("Journal file %s is already online. Assuming unclean closing.", f->path);
return -EBUSY;
- } else if (state == STATE_ARCHIVED)
- return -ESHUTDOWN;
- else if (state != STATE_OFFLINE) {
+ } else if (state != STATE_OFFLINE) {
log_debug("Journal file %s has unknown state %i.", f->path, state);
return -EBUSY;
}
@@ -3087,13 +3104,18 @@ int journal_file_open(
}
}
- if (fname)
+ if (fname) {
f->path = strdup(fname);
- else /* If we don't know the path, fill in something explanatory and vaguely useful */
- asprintf(&f->path, "/proc/self/%i", fd);
- if (!f->path) {
- r = -ENOMEM;
- goto fail;
+ if (!f->path) {
+ r = -ENOMEM;
+ goto fail;
+ }
+ } else {
+ /* If we don't know the path, fill in something explanatory and vaguely useful */
+ if (asprintf(&f->path, "/proc/self/%i", fd) < 0) {
+ r = -ENOMEM;
+ goto fail;
+ }
}
f->chain_cache = ordered_hashmap_new(&uint64_hash_ops);
@@ -3330,12 +3352,12 @@ int journal_file_open_reliably(
r = journal_file_open(-1, fname, flags, mode, compress, seal, metrics, mmap_cache, deferred_closes, template, ret);
if (!IN_SET(r,
- -EBADMSG, /* corrupted */
- -ENODATA, /* truncated */
- -EHOSTDOWN, /* other machine */
- -EPROTONOSUPPORT, /* incompatible feature */
- -EBUSY, /* unclean shutdown */
- -ESHUTDOWN, /* already archived */
+ -EBADMSG, /* Corrupted */
+ -ENODATA, /* Truncated */
+ -EHOSTDOWN, /* Other machine */
+ -EPROTONOSUPPORT, /* Incompatible feature */
+ -EBUSY, /* Unclean shutdown */
+ -ESHUTDOWN, /* Already archived */
-EIO, /* IO error, including SIGBUS on mmap */
-EIDRM, /* File has been deleted */
-ETXTBSY)) /* File is from the future */