diff options
Diffstat (limited to 'src/libsystemd/sd-journal/journal-file.c')
-rw-r--r-- | src/libsystemd/sd-journal/journal-file.c | 104 |
1 files changed, 45 insertions, 59 deletions
diff --git a/src/libsystemd/sd-journal/journal-file.c b/src/libsystemd/sd-journal/journal-file.c index 08cbf86..7e941ed 100644 --- a/src/libsystemd/sd-journal/journal-file.c +++ b/src/libsystemd/sd-journal/journal-file.c @@ -20,6 +20,7 @@ #include "fd-util.h" #include "format-util.h" #include "fs-util.h" +#include "gcrypt-util.h" #include "id128-util.h" #include "journal-authenticate.h" #include "journal-def.h" @@ -47,10 +48,6 @@ #define DEFAULT_COMPRESS_THRESHOLD (512ULL) #define MIN_COMPRESS_THRESHOLD (8ULL) -#define U64_KB UINT64_C(1024) -#define U64_MB (UINT64_C(1024) * U64_KB) -#define U64_GB (UINT64_C(1024) * U64_MB) - /* This is the minimum journal file size */ #define JOURNAL_FILE_SIZE_MIN (512 * U64_KB) /* 512 KiB */ #define JOURNAL_COMPACT_SIZE_MAX ((uint64_t) UINT32_MAX) /* 4 GiB */ @@ -285,6 +282,8 @@ JournalFile* journal_file_close(JournalFile *f) { assert(f->newest_boot_id_prioq_idx == PRIOQ_IDX_NULL); + sd_event_source_disable_unref(f->post_change_timer); + if (f->cache_fd) mmap_cache_fd_free(f->cache_fd); @@ -309,7 +308,7 @@ JournalFile* journal_file_close(JournalFile *f) { free(f->fsprg_seed); if (f->hmac) - gcry_md_close(f->hmac); + sym_gcry_md_close(f->hmac); #endif return mfree(f); @@ -2249,7 +2248,6 @@ static int journal_file_link_entry( f->header->tail_entry_monotonic = o->entry.monotonic; if (JOURNAL_HEADER_CONTAINS(f->header, tail_entry_offset)) f->header->tail_entry_offset = htole64(offset); - f->newest_mtime = 0; /* we have a new tail entry now, explicitly invalidate newest boot id/timestamp info */ /* Link up the items */ for (uint64_t i = 0; i < n_items; i++) { @@ -2762,7 +2760,7 @@ static int generic_array_get( Object **ret_object, /* The found object. */ uint64_t *ret_offset) { /* The offset of the found object. */ - uint64_t a, t = 0, k; + uint64_t a, t = 0, k = 0; /* Explicit initialization of k to appease gcc */ ChainCacheItem *ci; Object *o = NULL; int r; @@ -3052,7 +3050,7 @@ static int generic_array_bisect( left = 0; right = m - 1; - if (direction == DIRECTION_UP) { + if (direction == DIRECTION_UP && left < right) { /* If we're going upwards, the last entry of the previous array may pass the test, * and the first entry of the current array may not pass. In that case, the last * entry of the previous array must be returned. Hence, we need to test the first @@ -3167,10 +3165,21 @@ previous: if (direction == DIRECTION_DOWN) return 0; - /* Indicate to go to the previous array later. Note, do not move to the previous array here, - * as that may invalidate the current array object in the mmap cache and - * journal_file_entry_array_item() below may read invalid address. */ - i = UINT64_MAX; + /* Get the last entry of the previous array. */ + r = bump_entry_array(f, NULL, a, first, DIRECTION_UP, &a); + if (r <= 0) + return r; + + r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &array); + if (r < 0) + return r; + + p = journal_file_entry_array_n_items(f, array); + if (p == 0 || t < p) + return -EBADMSG; + + t -= p; + i = p - 1; found: p = journal_file_entry_array_item(f, array, 0); @@ -3180,27 +3189,6 @@ found: /* Let's cache this item for the next invocation */ chain_cache_put(f->chain_cache, ci, first, a, p, t, i); - if (i == UINT64_MAX) { - uint64_t m; - - /* Get the last entry of the previous array. */ - - r = bump_entry_array(f, NULL, a, first, DIRECTION_UP, &a); - if (r <= 0) - return r; - - r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &array); - if (r < 0) - return r; - - m = journal_file_entry_array_n_items(f, array); - if (m == 0 || t < m) - return -EBADMSG; - - t -= m; - i = m - 1; - } - p = journal_file_entry_array_item(f, array, i); if (p == 0) return -EBADMSG; @@ -3267,7 +3255,7 @@ static int generic_array_bisect_for_data( } else { /* If we are going upwards, then we need to return the last object that passes the test. - * When there is no object that passes the test, we need to return the the last object that + * When there is no object that passes the test, we need to return the last object that * test_object() returns TEST_LEFT for. */ if (r == TEST_RIGHT) return 0; /* Not only the 'extra' object, but also all objects in the chained arrays @@ -3554,7 +3542,8 @@ int journal_file_next_entry( p, test_object_offset, direction, - ret_object ? &o : NULL, &q, &i); + NULL, &q, &i); /* Here, do not read entry object, as the result object + * may not be the one we want, and it may be broken. */ if (r <= 0) return r; @@ -3564,12 +3553,11 @@ int journal_file_next_entry( * the same offset, and the index needs to be shifted. Otherwise, use the found object as is, * as it is the nearest entry object from the input offset 'p'. */ - if (p != q) - goto found; - - r = bump_array_index(&i, direction, n); - if (r <= 0) - return r; + if (p == q) { + r = bump_array_index(&i, direction, n); + if (r <= 0) + return r; + } /* And jump to it */ r = generic_array_get(f, le64toh(f->header->entry_array_offset), i, direction, ret_object ? &o : NULL, &q); @@ -3581,7 +3569,7 @@ int journal_file_next_entry( return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), "%s: entry array not properly ordered at entry index %" PRIu64, f->path, i); -found: + if (ret_object) *ret_object = o; if (ret_offset) @@ -3813,35 +3801,35 @@ void journal_file_dump(JournalFile *f) { case OBJECT_ENTRY: 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)); + log_info("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_TAG: assert(s); - printf("Type: %s seqnum=%"PRIu64" epoch=%"PRIu64"\n", - s, - le64toh(o->tag.seqnum), - le64toh(o->tag.epoch)); + log_info("Type: %s seqnum=%"PRIu64" epoch=%"PRIu64"\n", + s, + le64toh(o->tag.seqnum), + le64toh(o->tag.epoch)); break; default: if (s) - printf("Type: %s \n", s); + log_info("Type: %s \n", s); else - printf("Type: unknown (%i)", o->object.type); + log_info("Type: unknown (%i)", o->object.type); break; } c = COMPRESSION_FROM_OBJECT(o); if (c > COMPRESSION_NONE) - printf("Flags: %s\n", - compression_to_string(c)); + log_info("Flags: %s\n", + compression_to_string(c)); if (p == le64toh(f->header->tail_object_offset)) p = 0; @@ -4374,11 +4362,9 @@ int journal_file_archive(JournalFile *f, char **ret_previous_path) { (void) fsync_directory_of_file(f->fd); if (ret_previous_path) - *ret_previous_path = f->path; - else - free(f->path); + *ret_previous_path = TAKE_PTR(f->path); - f->path = TAKE_PTR(p); + free_and_replace(f->path, p); /* Set as archive so offlining commits w/state=STATE_ARCHIVED. Previously we would set old_file->header->state * to STATE_ARCHIVED directly here, but journal_file_set_offline() short-circuits when state != STATE_ONLINE, |