diff options
-rw-r--r-- | src/libsystemd/sd-journal/journal-def.h | 22 | ||||
-rw-r--r-- | src/libsystemd/sd-journal/journal-file.c | 80 | ||||
-rw-r--r-- | src/libsystemd/sd-journal/journal-file.h | 2 | ||||
-rw-r--r-- | src/libsystemd/sd-journal/journal-verify.c | 84 |
4 files changed, 104 insertions, 84 deletions
diff --git a/src/libsystemd/sd-journal/journal-def.h b/src/libsystemd/sd-journal/journal-def.h index bd924bda8a..d64c70cbe6 100644 --- a/src/libsystemd/sd-journal/journal-def.h +++ b/src/libsystemd/sd-journal/journal-def.h @@ -161,23 +161,11 @@ enum { HEADER_INCOMPATIBLE_KEYED_HASH | \ HEADER_INCOMPATIBLE_COMPRESSED_ZSTD) -#if HAVE_XZ && HAVE_LZ4 && HAVE_ZSTD -# define HEADER_INCOMPATIBLE_SUPPORTED HEADER_INCOMPATIBLE_ANY -#elif HAVE_XZ && HAVE_LZ4 -# define HEADER_INCOMPATIBLE_SUPPORTED (HEADER_INCOMPATIBLE_COMPRESSED_XZ|HEADER_INCOMPATIBLE_COMPRESSED_LZ4|HEADER_INCOMPATIBLE_KEYED_HASH) -#elif HAVE_XZ && HAVE_ZSTD -# define HEADER_INCOMPATIBLE_SUPPORTED (HEADER_INCOMPATIBLE_COMPRESSED_XZ|HEADER_INCOMPATIBLE_COMPRESSED_ZSTD|HEADER_INCOMPATIBLE_KEYED_HASH) -#elif HAVE_LZ4 && HAVE_ZSTD -# define HEADER_INCOMPATIBLE_SUPPORTED (HEADER_INCOMPATIBLE_COMPRESSED_LZ4|HEADER_INCOMPATIBLE_COMPRESSED_ZSTD|HEADER_INCOMPATIBLE_KEYED_HASH) -#elif HAVE_XZ -# define HEADER_INCOMPATIBLE_SUPPORTED (HEADER_INCOMPATIBLE_COMPRESSED_XZ|HEADER_INCOMPATIBLE_KEYED_HASH) -#elif HAVE_LZ4 -# define HEADER_INCOMPATIBLE_SUPPORTED (HEADER_INCOMPATIBLE_COMPRESSED_LZ4|HEADER_INCOMPATIBLE_KEYED_HASH) -#elif HAVE_ZSTD -# define HEADER_INCOMPATIBLE_SUPPORTED (HEADER_INCOMPATIBLE_COMPRESSED_ZSTD|HEADER_INCOMPATIBLE_KEYED_HASH) -#else -# define HEADER_INCOMPATIBLE_SUPPORTED HEADER_INCOMPATIBLE_KEYED_HASH -#endif +#define HEADER_INCOMPATIBLE_SUPPORTED \ + ((HAVE_XZ ? HEADER_INCOMPATIBLE_COMPRESSED_XZ : 0) | \ + (HAVE_LZ4 ? HEADER_INCOMPATIBLE_COMPRESSED_LZ4 : 0) | \ + (HAVE_ZSTD ? HEADER_INCOMPATIBLE_COMPRESSED_ZSTD : 0) | \ + HEADER_INCOMPATIBLE_KEYED_HASH) enum { HEADER_COMPATIBLE_SEALED = 1 << 0, diff --git a/src/libsystemd/sd-journal/journal-file.c b/src/libsystemd/sd-journal/journal-file.c index b4052ad417..2b36c03c38 100644 --- a/src/libsystemd/sd-journal/journal-file.c +++ b/src/libsystemd/sd-journal/journal-file.c @@ -30,6 +30,7 @@ #include "set.h" #include "sort-util.h" #include "stat-util.h" +#include "string-table.h" #include "string-util.h" #include "strv.h" #include "sync-util.h" @@ -497,7 +498,7 @@ static bool warn_wrong_flags(const JournalFile *f, bool compatible) { flags = (flags & any) & ~supported; if (flags) { const char* strv[5]; - unsigned n = 0; + size_t n = 0; _cleanup_free_ char *t = NULL; if (compatible) { @@ -2148,7 +2149,7 @@ int journal_file_append_entry( items = newa(EntryItem, n_iovec); - for (unsigned i = 0; i < n_iovec; i++) { + for (size_t i = 0; i < n_iovec; i++) { uint64_t p; Object *o; @@ -2170,8 +2171,10 @@ int journal_file_append_entry( else xor_hash ^= le64toh(o->data.hash); - items[i].object_offset = htole64(p); - items[i].hash = o->data.hash; + items[i] = (EntryItem) { + .object_offset = htole64(p), + .hash = o->data.hash, + }; } /* Order by the position on disk, in order to improve seek @@ -3204,51 +3207,41 @@ void journal_file_dump(JournalFile *f) { p = le64toh(READ_NOW(f->header->header_size)); while (p != 0) { + const char *s; + r = journal_file_move_to_object(f, OBJECT_UNUSED, p, &o); if (r < 0) goto fail; - switch (o->object.type) { - - case OBJECT_UNUSED: - printf("Type: OBJECT_UNUSED\n"); - break; - - case OBJECT_DATA: - printf("Type: OBJECT_DATA\n"); - break; + s = journal_object_type_to_string(o->object.type); - case OBJECT_FIELD: - printf("Type: OBJECT_FIELD\n"); - break; + switch (o->object.type) { case OBJECT_ENTRY: - printf("Type: OBJECT_ENTRY seqnum=%"PRIu64" monotonic=%"PRIu64" realtime=%"PRIu64"\n", + assert(s); + + printf("Type: %s seqnum=%"PRIu64" monotonic=%"PRIu64" realtime=%"PRIu64"\n", + s, le64toh(o->entry.seqnum), le64toh(o->entry.monotonic), le64toh(o->entry.realtime)); break; - case OBJECT_FIELD_HASH_TABLE: - printf("Type: OBJECT_FIELD_HASH_TABLE\n"); - break; - - case OBJECT_DATA_HASH_TABLE: - printf("Type: OBJECT_DATA_HASH_TABLE\n"); - break; - - case OBJECT_ENTRY_ARRAY: - printf("Type: OBJECT_ENTRY_ARRAY\n"); - break; - case OBJECT_TAG: - printf("Type: OBJECT_TAG seqnum=%"PRIu64" epoch=%"PRIu64"\n", + assert(s); + + printf("Type: %s seqnum=%"PRIu64" epoch=%"PRIu64"\n", + s, le64toh(o->tag.seqnum), le64toh(o->tag.epoch)); break; default: - printf("Type: unknown (%i)\n", o->object.type); + if (s) + printf("Type: %s \n", s); + else + printf("Type: unknown (%i)", o->object.type); + break; } @@ -3867,8 +3860,10 @@ int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint6 if (!to->writable) return -EPERM; - ts.monotonic = le64toh(o->entry.monotonic); - ts.realtime = le64toh(o->entry.realtime); + ts = (dual_timestamp) { + .monotonic = le64toh(o->entry.monotonic), + .realtime = le64toh(o->entry.realtime), + }; boot_id = &o->entry.boot_id; n = journal_file_entry_n_items(o); @@ -3931,8 +3926,10 @@ int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint6 else xor_hash ^= le64toh(u->data.hash); - items[i].object_offset = htole64(h); - items[i].hash = u->data.hash; + items[i] = (EntryItem) { + .object_offset = htole64(h), + .hash = u->data.hash, + }; r = journal_file_move_to_object(from, OBJECT_ENTRY, p, &o); if (r < 0) @@ -4189,3 +4186,16 @@ bool journal_file_rotate_suggested(JournalFile *f, usec_t max_file_usec, int log return false; } + +static const char * const journal_object_type_table[] = { + [OBJECT_UNUSED] = "unused", + [OBJECT_DATA] = "data", + [OBJECT_FIELD] = "field", + [OBJECT_ENTRY] = "entry", + [OBJECT_DATA_HASH_TABLE] = "data hash table", + [OBJECT_FIELD_HASH_TABLE] = "field hash table", + [OBJECT_ENTRY_ARRAY] = "entry array", + [OBJECT_TAG] = "tag", +}; + +DEFINE_STRING_TABLE_LOOKUP_TO_STRING(journal_object_type, ObjectType); diff --git a/src/libsystemd/sd-journal/journal-file.h b/src/libsystemd/sd-journal/journal-file.h index b4488259ad..92784337c2 100644 --- a/src/libsystemd/sd-journal/journal-file.h +++ b/src/libsystemd/sd-journal/journal-file.h @@ -272,3 +272,5 @@ static inline bool JOURNAL_FILE_COMPRESS(JournalFile *f) { uint64_t journal_file_hash_data(JournalFile *f, const void *data, size_t sz); bool journal_field_valid(const char *p, size_t l, bool allow_protected); + +const char* journal_object_type_to_string(ObjectType type) _const_; diff --git a/src/libsystemd/sd-journal/journal-verify.c b/src/libsystemd/sd-journal/journal-verify.c index dbea50fd70..acb1b4c7e8 100644 --- a/src/libsystemd/sd-journal/journal-verify.c +++ b/src/libsystemd/sd-journal/journal-verify.c @@ -591,7 +591,7 @@ static int verify_data( return 0; } -static int verify_hash_table( +static int verify_data_hash_table( JournalFile *f, MMapFileDescriptor *cache_data_fd, uint64_t n_data, MMapFileDescriptor *cache_entry_fd, uint64_t n_entries, @@ -824,6 +824,43 @@ static int verify_entry_array( return 0; } +static int verify_hash_table( + Object *o, uint64_t p, uint64_t *n_hash_tables, uint64_t header_offset, uint64_t header_size) { + + assert(o); + assert(n_hash_tables); + + if (*n_hash_tables > 1) { + error(p, + "More than one %s: %" PRIu64, + journal_object_type_to_string(o->object.type), + *n_hash_tables); + return -EBADMSG; + } + + if (header_offset != p + offsetof(HashTableObject, items)) { + error(p, + "Header offset for %s invalid (%" PRIu64 " != %" PRIu64 ")", + journal_object_type_to_string(o->object.type), + header_offset, + p + offsetof(HashTableObject, items)); + return -EBADMSG; + } + + if (header_size != le64toh(o->object.size) - offsetof(HashTableObject, items)) { + error(p, + "Header size for %s invalid (%" PRIu64 " != %" PRIu64 ")", + journal_object_type_to_string(o->object.type), + header_size, + le64toh(o->object.size) - offsetof(HashTableObject, items)); + return -EBADMSG; + } + + (*n_hash_tables)++; + + return 0; +} + int journal_file_verify( JournalFile *f, const char *key, @@ -1069,37 +1106,20 @@ int journal_file_verify( break; case OBJECT_DATA_HASH_TABLE: - if (n_data_hash_tables > 1) { - error(p, "More than one data hash table"); - r = -EBADMSG; - goto fail; - } - - if (le64toh(f->header->data_hash_table_offset) != p + offsetof(HashTableObject, items) || - le64toh(f->header->data_hash_table_size) != le64toh(o->object.size) - offsetof(HashTableObject, items)) { - error(p, "header fields for data hash table invalid"); - r = -EBADMSG; + r = verify_hash_table(o, p, &n_data_hash_tables, + le64toh(f->header->data_hash_table_offset), + le64toh(f->header->data_hash_table_size)); + if (r < 0) goto fail; - } - - n_data_hash_tables++; break; case OBJECT_FIELD_HASH_TABLE: - if (n_field_hash_tables > 1) { - error(p, "More than one field hash table"); - r = -EBADMSG; - goto fail; - } - - if (le64toh(f->header->field_hash_table_offset) != p + offsetof(HashTableObject, items) || - le64toh(f->header->field_hash_table_size) != le64toh(o->object.size) - offsetof(HashTableObject, items)) { - error(p, "Header fields for field hash table invalid"); - r = -EBADMSG; + r = verify_hash_table(o, p, &n_field_hash_tables, + le64toh(f->header->field_hash_table_offset), + le64toh(f->header->field_hash_table_size)); + if (r < 0) goto fail; - } - n_field_hash_tables++; break; case OBJECT_ENTRY_ARRAY: @@ -1325,12 +1345,12 @@ int journal_file_verify( if (r < 0) goto fail; - r = verify_hash_table(f, - cache_data_fd, n_data, - cache_entry_fd, n_entries, - cache_entry_array_fd, n_entry_arrays, - &last_usec, - show_progress); + r = verify_data_hash_table(f, + cache_data_fd, n_data, + cache_entry_fd, n_entries, + cache_entry_array_fd, n_entry_arrays, + &last_usec, + show_progress); if (r < 0) goto fail; |