X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fjournal%2Fsd-journal.c;h=74abac88af74ad262d4649518fea1e8109ca570d;hp=1f4ad0ff649d73eb7ac5478bb5b2765a851e431a;hb=7210bfb3706f8cbb2b35403f916dace1824c516c;hpb=161e54f8719c4a11440d762276cbccbeb1736f8c diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index 1f4ad0ff6..74abac88a 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -43,6 +43,7 @@ struct sd_journal { Hashmap *files; JournalFile *current_file; + uint64_t current_field; LIST_HEAD(Match, matches); }; @@ -87,10 +88,13 @@ void sd_journal_flush_matches(sd_journal *j) { } static int compare_order(JournalFile *af, Object *ao, uint64_t ap, - JournalFile *bf, Object *bo, uint64_t bp) { + JournalFile *bf, Object *bo, uint64_t bp) { uint64_t a, b; + /* We operate on two different files here, hence we can access + * two objects at the same time, which we normally can't */ + if (sd_id128_equal(af->header->seqnum_id, bf->header->seqnum_id)) { /* If this is from the same seqnum source, compare @@ -98,23 +102,43 @@ static int compare_order(JournalFile *af, Object *ao, uint64_t ap, a = le64toh(ao->entry.seqnum); b = le64toh(bo->entry.seqnum); + if (a < b) + return -1; + if (a > b) + return 1; + } - } else if (sd_id128_equal(ao->entry.boot_id, bo->entry.boot_id)) { + if (sd_id128_equal(ao->entry.boot_id, bo->entry.boot_id)) { /* If the boot id matches compare monotonic time */ a = le64toh(ao->entry.monotonic); b = le64toh(bo->entry.monotonic); - } else { - - /* Otherwise compare UTC time */ - a = le64toh(ao->entry.realtime); - b = le64toh(ao->entry.realtime); + if (a < b) + return -1; + if (a > b) + return 1; } - return - a < b ? -1 : - a > b ? +1 : 0; + /* Otherwise compare UTC time */ + a = le64toh(ao->entry.realtime); + b = le64toh(ao->entry.realtime); + + if (a < b) + return -1; + if (a > b) + return 1; + + /* Finally, compare by contents */ + a = le64toh(ao->entry.xor_hash); + b = le64toh(ao->entry.xor_hash); + + if (a < b) + return -1; + if (a > b) + return 1; + + return 0; } int sd_journal_next(sd_journal *j) { @@ -143,7 +167,8 @@ int sd_journal_next(sd_journal *j) { else if (r == 0) continue; - if (!new_current || compare_order(new_current, new_entry, new_offset, f, o, p) > 0) { + if (!new_current || + compare_order(new_current, new_entry, new_offset, f, o, p) > 0) { new_current = f; new_entry = o; new_offset = p; @@ -153,7 +178,34 @@ int sd_journal_next(sd_journal *j) { if (new_current) { j->current_file = new_current; j->current_file->current_offset = new_offset; - j->current_file->current_field = 0; + j->current_field = 0; + + /* Skip over any identical entries in the other files too */ + + HASHMAP_FOREACH(f, j->files, i) { + Object *o; + uint64_t p; + + if (j->current_file == f) + continue; + + if (f->current_offset > 0) { + r = journal_file_move_to_object(f, f->current_offset, OBJECT_ENTRY, &o); + if (r < 0) + return r; + } else + o = NULL; + + r = journal_file_next_entry(f, o, &o, &p); + if (r < 0) + return r; + else if (r == 0) + continue; + + if (compare_order(new_current, new_entry, new_offset, f, o, p) == 0) + f->current_offset = p; + } + return 1; } @@ -196,7 +248,34 @@ int sd_journal_previous(sd_journal *j) { if (new_current) { j->current_file = new_current; j->current_file->current_offset = new_offset; - j->current_file->current_field = 0; + j->current_field = 0; + + /* Skip over any identical entries in the other files too */ + + HASHMAP_FOREACH(f, j->files, i) { + Object *o; + uint64_t p; + + if (j->current_file == f) + continue; + + if (f->current_offset > 0) { + r = journal_file_move_to_object(f, f->current_offset, OBJECT_ENTRY, &o); + if (r < 0) + return r; + } else + o = NULL; + + r = journal_file_prev_entry(f, o, &o, &p); + if (r < 0) + return r; + else if (r == 0) + continue; + + if (compare_order(new_current, new_entry, new_offset, f, o, p) == 0) + f->current_offset = p; + } + return 1; } @@ -539,10 +618,10 @@ int sd_journal_iterate_fields(sd_journal *j, const void **data, size_t *size) { return r; n = journal_file_entry_n_items(o); - if (f->current_field >= n) + if (j->current_field >= n) return 0; - p = le64toh(o->entry.items[f->current_field].object_offset); + p = le64toh(o->entry.items[j->current_field].object_offset); r = journal_file_move_to_object(f, p, OBJECT_DATA, &o); if (r < 0) return r; @@ -557,7 +636,17 @@ int sd_journal_iterate_fields(sd_journal *j, const void **data, size_t *size) { *data = o->data.payload; *size = t; - f->current_field ++; + j->current_field ++; return 1; } + +int sd_journal_seek_head(sd_journal *j) { + assert(j); + return -EINVAL; +} + +int sd_journal_seek_tail(sd_journal *j) { + assert(j); + return -EINVAL; +}