On Fri, Aug 29, 2014 at 06:11:35PM +0200, Jan Janssen wrote: > For some reason, sd_journal_query_unique() and sd_journal_add_match() don't > work as they used to. There's a chance boots will be skipped; in my > case only 60 of 393 boots show up. Therefore, do sd_journal_query_unique() > first > and then iterate over those to query their timespec. We should fix the underlying problem, since query_unique and add_match weren't supposed to change at all. Looking at the journal client code has been on my TODO list for a long while...
Zbyszek > > https://bugs.freedesktop.org/show_bug.cgi?id=79380 > --- > src/journal/journalctl.c | 124 > ++++++++++++++++++++--------------------------- > 1 file changed, 53 insertions(+), 71 deletions(-) > > diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c > index f3680d1..0aec5fb 100644 > --- a/src/journal/journalctl.c > +++ b/src/journal/journalctl.c > @@ -804,33 +804,45 @@ static int boot_id_cmp(const void *a, const void *b) { > return _a < _b ? -1 : (_a > _b ? 1 : 0); > } > > -static int list_boots(sd_journal *j) { > +static int get_boots(sd_journal *j, boot_id_t **boot_ids, unsigned int > *count, boot_id_t *query_ref_boot_id) { > int r; > + boot_id_t *id; > const void *data; > - unsigned int count = 0; > - int w, i; > size_t length, allocated = 0; > - boot_id_t *id; > - _cleanup_free_ boot_id_t *all_ids = NULL; > + > + assert(j); > + assert(boot_ids); > + assert(count); > > r = sd_journal_query_unique(j, "_BOOT_ID"); > if (r < 0) > return r; > > + *count = 0; > SD_JOURNAL_FOREACH_UNIQUE(j, data, length) { > if (length < strlen("_BOOT_ID=")) > continue; > > - if (!GREEDY_REALLOC(all_ids, allocated, count + 1)) > + if (!GREEDY_REALLOC(*boot_ids, allocated, *count + 1)) > return log_oom(); > > - id = &all_ids[count]; > + id = *boot_ids + *count; > > r = sd_id128_from_string(((const char *)data) + > strlen("_BOOT_ID="), &id->id); > if (r < 0) > continue; > > - r = sd_journal_add_match(j, data, length); > + (*count)++; > + id->first = id->last = 0; > + } > + > + for (id = *boot_ids; id < *boot_ids + *count; id++) { > + char boot_id_str[9+32+1] = "_BOOT_ID="; > + > + sd_journal_flush_matches(j); > + sd_id128_to_string(id->id, boot_id_str + 9); > + > + r = sd_journal_add_match(j, boot_id_str, > strlen(boot_id_str)); > if (r < 0) > return r; > > @@ -839,35 +851,47 @@ static int list_boots(sd_journal *j) { > return r; > > r = sd_journal_next(j); > - if (r < 0) > + if (r <= 0) > return r; > - else if (r == 0) > - goto flush; > > r = sd_journal_get_realtime_usec(j, &id->first); > if (r < 0) > return r; > > + if (query_ref_boot_id) { > + if (sd_id128_equal(id->id, query_ref_boot_id->id)) > + *query_ref_boot_id = *id; > + continue; > + } > + > r = sd_journal_seek_tail(j); > if (r < 0) > return r; > > r = sd_journal_previous(j); > - if (r < 0) > + if (r <= 0) > return r; > - else if (r == 0) > - goto flush; > > r = sd_journal_get_realtime_usec(j, &id->last); > if (r < 0) > return r; > - > - count++; > - flush: > - sd_journal_flush_matches(j); > } > > - qsort_safe(all_ids, count, sizeof(boot_id_t), boot_id_cmp); > + sd_journal_flush_matches(j); > + qsort_safe(*boot_ids, *count, sizeof(boot_id_t), boot_id_cmp); > + > + return 0; > +} > + > +static int list_boots(sd_journal *j) { > + int r, w, i; > + unsigned int count = 0; > + boot_id_t *id; > + _cleanup_free_ boot_id_t *all_ids = NULL; > + > + r = get_boots(j, &all_ids, &count, NULL); > + if (r < 0) > + return r; > > /* numbers are one less, but we need an extra char for the sign */ > w = DECIMAL_STR_WIDTH(count - 1) + 1; > @@ -885,76 +909,34 @@ static int list_boots(sd_journal *j) { > return 0; > } > > -static int get_relative_boot_id(sd_journal *j, sd_id128_t *boot_id, int > relative) { > +static int get_boot_id_by_offset(sd_journal *j, sd_id128_t *boot_id, int > offset) { > int r; > - const void *data; > unsigned int count = 0; > - size_t length, allocated = 0; > - boot_id_t ref_boot_id = {SD_ID128_NULL}, *id; > + boot_id_t ref_boot_id = {}, *id; > _cleanup_free_ boot_id_t *all_ids = NULL; > > assert(j); > assert(boot_id); > > - r = sd_journal_query_unique(j, "_BOOT_ID"); > + ref_boot_id.id = *boot_id; > + r = get_boots(j, &all_ids, &count, &ref_boot_id); > if (r < 0) > return r; > > - SD_JOURNAL_FOREACH_UNIQUE(j, data, length) { > - if (length < strlen("_BOOT_ID=")) > - continue; > - > - if (!GREEDY_REALLOC(all_ids, allocated, count + 1)) > - return log_oom(); > - > - id = &all_ids[count]; > - > - r = sd_id128_from_string(((const char *)data) + > strlen("_BOOT_ID="), &id->id); > - if (r < 0) > - continue; > - > - r = sd_journal_add_match(j, data, length); > - if (r < 0) > - return r; > - > - r = sd_journal_seek_head(j); > - if (r < 0) > - return r; > - > - r = sd_journal_next(j); > - if (r < 0) > - return r; > - else if (r == 0) > - goto flush; > - > - r = sd_journal_get_realtime_usec(j, &id->first); > - if (r < 0) > - return r; > - > - if (sd_id128_equal(id->id, *boot_id)) > - ref_boot_id = *id; > - > - count++; > - flush: > - sd_journal_flush_matches(j); > - } > - > - qsort_safe(all_ids, count, sizeof(boot_id_t), boot_id_cmp); > - > if (sd_id128_equal(*boot_id, SD_ID128_NULL)) { > - if (relative > (int) count || relative <= -(int)count) > + if (offset > (int) count || offset <= -(int)count) > return -EADDRNOTAVAIL; > > - *boot_id = all_ids[(relative <= 0)*count + relative - 1].id; > + *boot_id = all_ids[(offset <= 0)*count + offset - 1].id; > } else { > id = bsearch(&ref_boot_id, all_ids, count, > sizeof(boot_id_t), boot_id_cmp); > > if (!id || > - relative <= 0 ? (id - all_ids) + relative < 0 : > - (id - all_ids) + relative >= (int) count) > + offset <= 0 ? (id - all_ids) + offset < 0 : > + (id - all_ids) + offset >= (int) count) > return -EADDRNOTAVAIL; > > - *boot_id = (id + relative)->id; > + *boot_id = (id + offset)->id; > } > > return 0; > @@ -972,7 +954,7 @@ static int add_boot(sd_journal *j) { > if (arg_boot_offset == 0 && sd_id128_equal(arg_boot_id, > SD_ID128_NULL)) > return add_match_this_boot(j, arg_machine); > > - r = get_relative_boot_id(j, &arg_boot_id, arg_boot_offset); > + r = get_boot_id_by_offset(j, &arg_boot_id, arg_boot_offset); > if (r < 0) { > if (sd_id128_equal(arg_boot_id, SD_ID128_NULL)) > log_error("Failed to look up boot %+i: %s", > arg_boot_offset, strerror(-r)); > -- > 2.1.0 > > _______________________________________________ > systemd-devel mailing list > [email protected] > http://lists.freedesktop.org/mailman/listinfo/systemd-devel > _______________________________________________ systemd-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/systemd-devel
