X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fjournal%2Fsd-journal.c;h=05a8445b3703f0ad737d12eeee3647cf23ec202e;hb=1dfa7e79a60de680086b1d93fcc3629b463f58bd;hp=b4d35eebafd7612f7b8cd128bc0bc996d810b624;hpb=a1a03e3075316e2376176fc54c74e071adc9d71a;p=elogind.git diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index b4d35eeba..05a8445b3 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -357,15 +357,27 @@ _public_ void sd_journal_flush_matches(sd_journal *j) { detach_location(j); } -static int compare_order(JournalFile *af, Object *ao, - JournalFile *bf, Object *bo) { +static int compare_entry_order(JournalFile *af, Object *_ao, + JournalFile *bf, uint64_t bp) { uint64_t a, b; + Object *ao, *bo; + int r; assert(af); - assert(ao); assert(bf); - assert(bo); + assert(_ao); + + /* The mmap cache might invalidate the object from the first + * file if we look at the one from the second file. Hence + * temporarily copy the header of the first one, and look at + * that only. */ + ao = alloca(offsetof(EntryObject, items)); + memcpy(ao, _ao, offsetof(EntryObject, items)); + + r = journal_file_move_to_object(bf, OBJECT_ENTRY, bp, &bo); + if (r < 0) + return strcmp(af->path, bf->path); /* We operate on two different files here, hence we can access * two objects at the same time, which we normally can't. @@ -808,18 +820,17 @@ static int next_beyond_location(sd_journal *j, JournalFile *f, direction_t direc } static int real_journal_next(sd_journal *j, direction_t direction) { - JournalFile *f, *new_current = NULL; + JournalFile *f, *new_file = NULL; + uint64_t new_offset = 0; + Object *o; + uint64_t p; Iterator i; int r; - uint64_t new_offset = 0; - Object *new_entry = NULL; if (!j) return -EINVAL; HASHMAP_FOREACH(f, j->files, i) { - Object *o; - uint64_t p; bool found; r = next_beyond_location(j, f, direction, &o, &p); @@ -829,12 +840,12 @@ static int real_journal_next(sd_journal *j, direction_t direction) { } else if (r == 0) continue; - if (!new_current) + if (!new_file) found = true; else { int k; - k = compare_order(f, o, new_current, new_entry); + k = compare_entry_order(f, o, new_file, new_offset); if (direction == DIRECTION_DOWN) found = k < 0; @@ -843,16 +854,19 @@ static int real_journal_next(sd_journal *j, direction_t direction) { } if (found) { - new_current = f; - new_entry = o; + new_file = f; new_offset = p; } } - if (!new_current) + if (!new_file) return 0; - set_location(j, new_current, new_entry, new_offset); + r = journal_file_move_to_object(new_file, OBJECT_ENTRY, new_offset, &o); + if (r < 0) + return r; + + set_location(j, new_file, o, new_offset); return 1; } @@ -969,35 +983,35 @@ _public_ int sd_journal_seek_cursor(sd_journal *j, const char *cursor) { case 's': seqnum_id_set = true; - k = sd_id128_from_string(w+2, &seqnum_id); + k = sd_id128_from_string(item+2, &seqnum_id); break; case 'i': seqnum_set = true; - if (sscanf(w+2, "%llx", &seqnum) != 1) + if (sscanf(item+2, "%llx", &seqnum) != 1) k = -EINVAL; break; case 'b': boot_id_set = true; - k = sd_id128_from_string(w+2, &boot_id); + k = sd_id128_from_string(item+2, &boot_id); break; case 'm': monotonic_set = true; - if (sscanf(w+2, "%llx", &monotonic) != 1) + if (sscanf(item+2, "%llx", &monotonic) != 1) k = -EINVAL; break; case 't': realtime_set = true; - if (sscanf(w+2, "%llx", &realtime) != 1) + if (sscanf(item+2, "%llx", &realtime) != 1) k = -EINVAL; break; case 'x': xor_hash_set = true; - if (sscanf(w+2, "%llx", &xor_hash) != 1) + if (sscanf(item+2, "%llx", &xor_hash) != 1) k = -EINVAL; break; } @@ -1242,9 +1256,10 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dirname) } for (;;) { - struct dirent buf, *de; + struct dirent *de; + union dirent_storage buf; - r = readdir_r(d, &buf, &de); + r = readdir_r(d, &buf.de, &de); if (r != 0 || !de) break; @@ -1320,10 +1335,11 @@ static int add_root_directory(sd_journal *j, const char *p) { } for (;;) { - struct dirent buf, *de; + struct dirent *de; + union dirent_storage buf; sd_id128_t id; - r = readdir_r(d, &buf, &de); + r = readdir_r(d, &buf.de, &de); if (r != 0 || !de) break;