|
|
1ff636 |
From 99ea430346f3f8ffba504cd3de1a269ab4eac8e6 Mon Sep 17 00:00:00 2001
|
|
|
1ff636 |
From: Jan Janssen <medhefgo@web.de>
|
|
|
1ff636 |
Date: Fri, 1 May 2015 15:15:16 +0200
|
|
|
1ff636 |
Subject: [PATCH] journalctl: Improve boot ID lookup
|
|
|
1ff636 |
|
|
|
1ff636 |
This method should greatly improve offset based lookup, by simply jumping
|
|
|
1ff636 |
from one boot to the next boot. It starts at the journal head to get the
|
|
|
1ff636 |
a boot ID, makes a _BOOT_ID match and then comes from the opposite
|
|
|
1ff636 |
journal direction (tail) to get to the end that boot. After flushing the matches
|
|
|
1ff636 |
and advancing the journal from that exact position, we arrive at the start
|
|
|
1ff636 |
of next boot. Rinse and repeat.
|
|
|
1ff636 |
|
|
|
1ff636 |
This is faster than the old method of aggregating the full boot listing just
|
|
|
1ff636 |
so we can jump to a specific boot, which can be a real pain on big journals
|
|
|
1ff636 |
just for a mere "-b -1" case.
|
|
|
1ff636 |
|
|
|
1ff636 |
As an additional benefit --list-boots should improve slightly too, because
|
|
|
1ff636 |
it does less seeking.
|
|
|
1ff636 |
|
|
|
1ff636 |
Note that there can be a change in boot order with this lookup method
|
|
|
1ff636 |
because it will use the order of boots in the journal, not the realtime stamp
|
|
|
1ff636 |
stored in them. That's arguably better, though.
|
|
|
1ff636 |
Another deficiency is that it will get confused with boots interleaving in the
|
|
|
1ff636 |
journal, therefore, it will refuse operation in --merge, --file and --directory mode.
|
|
|
1ff636 |
|
|
|
1ff636 |
https://bugs.freedesktop.org/show_bug.cgi?id=72601
|
|
|
1ff636 |
(cherry picked from commit 596a23293d28f93843aef86721b90043e74d3081)
|
|
|
1ff636 |
|
|
|
1ff636 |
Cherry-picked from: 596a232
|
|
|
1ff636 |
Resolves: #1222517
|
|
|
1ff636 |
---
|
|
|
1ff636 |
src/journal/journalctl.c | 275 ++++++++++++++++++++++++++++++-----------------
|
|
|
1ff636 |
1 file changed, 174 insertions(+), 101 deletions(-)
|
|
|
1ff636 |
|
|
|
1ff636 |
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
|
|
|
1ff636 |
index 12c869f..c26cc00 100644
|
|
|
1ff636 |
--- a/src/journal/journalctl.c
|
|
|
1ff636 |
+++ b/src/journal/journalctl.c
|
|
|
1ff636 |
@@ -131,6 +131,7 @@ typedef struct boot_id_t {
|
|
|
1ff636 |
sd_id128_t id;
|
|
|
1ff636 |
uint64_t first;
|
|
|
1ff636 |
uint64_t last;
|
|
|
1ff636 |
+ LIST_FIELDS(struct boot_id_t, boot_list);
|
|
|
1ff636 |
} boot_id_t;
|
|
|
1ff636 |
|
|
|
1ff636 |
static void pager_open_if_enabled(void) {
|
|
|
1ff636 |
@@ -735,6 +736,11 @@ static int parse_argv(int argc, char *argv[]) {
|
|
|
1ff636 |
return -EINVAL;
|
|
|
1ff636 |
}
|
|
|
1ff636 |
|
|
|
1ff636 |
+ if ((arg_boot || arg_action == ACTION_LIST_BOOTS) && (arg_file || arg_directory || arg_merge)) {
|
|
|
1ff636 |
+ log_error("Using --boot or --list-boots with --file, --directory or --merge is not supported.");
|
|
|
1ff636 |
+ return -EINVAL;
|
|
|
1ff636 |
+ }
|
|
|
1ff636 |
+
|
|
|
1ff636 |
return 1;
|
|
|
1ff636 |
}
|
|
|
1ff636 |
|
|
|
1ff636 |
@@ -854,111 +860,203 @@ static int add_matches(sd_journal *j, char **args) {
|
|
|
1ff636 |
return 0;
|
|
|
1ff636 |
}
|
|
|
1ff636 |
|
|
|
1ff636 |
-static int boot_id_cmp(const void *a, const void *b) {
|
|
|
1ff636 |
- uint64_t _a, _b;
|
|
|
1ff636 |
+static int discover_next_boot(sd_journal *j,
|
|
|
1ff636 |
+ boot_id_t **boot,
|
|
|
1ff636 |
+ bool advance_older,
|
|
|
1ff636 |
+ bool read_realtime) {
|
|
|
1ff636 |
+ int r;
|
|
|
1ff636 |
+ char match[9+32+1] = "_BOOT_ID=";
|
|
|
1ff636 |
+ _cleanup_free_ boot_id_t *next_boot = NULL;
|
|
|
1ff636 |
|
|
|
1ff636 |
- _a = ((const boot_id_t *)a)->first;
|
|
|
1ff636 |
- _b = ((const boot_id_t *)b)->first;
|
|
|
1ff636 |
+ assert(j);
|
|
|
1ff636 |
+ assert(boot);
|
|
|
1ff636 |
|
|
|
1ff636 |
- return _a < _b ? -1 : (_a > _b ? 1 : 0);
|
|
|
1ff636 |
-}
|
|
|
1ff636 |
+ /* We expect the journal to be on the last position of a boot
|
|
|
1ff636 |
+ * (in relation to the direction we are going), so that the next
|
|
|
1ff636 |
+ * invocation of sd_journal_next/previous will be from a different
|
|
|
1ff636 |
+ * boot. We then collect any information we desire and then jump
|
|
|
1ff636 |
+ * to the last location of the new boot by using a _BOOT_ID match
|
|
|
1ff636 |
+ * coming from the other journal direction. */
|
|
|
1ff636 |
|
|
|
1ff636 |
-static int get_boots(sd_journal *j,
|
|
|
1ff636 |
- boot_id_t **boots,
|
|
|
1ff636 |
- unsigned int *count,
|
|
|
1ff636 |
- boot_id_t *query_ref_boot) {
|
|
|
1ff636 |
- int r;
|
|
|
1ff636 |
- const void *data;
|
|
|
1ff636 |
- size_t length, allocated = 0;
|
|
|
1ff636 |
+ /* Make sure we aren't restricted by any _BOOT_ID matches, so that
|
|
|
1ff636 |
+ * we can actually advance to a *different* boot. */
|
|
|
1ff636 |
+ sd_journal_flush_matches(j);
|
|
|
1ff636 |
|
|
|
1ff636 |
- assert(j);
|
|
|
1ff636 |
- assert(boots);
|
|
|
1ff636 |
- assert(count);
|
|
|
1ff636 |
+ if (advance_older)
|
|
|
1ff636 |
+ r = sd_journal_previous(j);
|
|
|
1ff636 |
+ else
|
|
|
1ff636 |
+ r = sd_journal_next(j);
|
|
|
1ff636 |
+ if (r < 0)
|
|
|
1ff636 |
+ return r;
|
|
|
1ff636 |
+ else if (r == 0)
|
|
|
1ff636 |
+ return 0; /* End of journal, yay. */
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ next_boot = new0(boot_id_t, 1);
|
|
|
1ff636 |
+ if (!next_boot)
|
|
|
1ff636 |
+ return log_oom();
|
|
|
1ff636 |
|
|
|
1ff636 |
- r = sd_journal_query_unique(j, "_BOOT_ID");
|
|
|
1ff636 |
+ r = sd_journal_get_monotonic_usec(j, NULL, &next_boot->id);
|
|
|
1ff636 |
if (r < 0)
|
|
|
1ff636 |
return r;
|
|
|
1ff636 |
|
|
|
1ff636 |
- *count = 0;
|
|
|
1ff636 |
- SD_JOURNAL_FOREACH_UNIQUE(j, data, length) {
|
|
|
1ff636 |
- boot_id_t *id;
|
|
|
1ff636 |
+ if (read_realtime) {
|
|
|
1ff636 |
+ r = sd_journal_get_realtime_usec(j, &next_boot->first);
|
|
|
1ff636 |
+ if (r < 0)
|
|
|
1ff636 |
+ return r;
|
|
|
1ff636 |
+ }
|
|
|
1ff636 |
|
|
|
1ff636 |
- assert(startswith(data, "_BOOT_ID="));
|
|
|
1ff636 |
+ /* Now seek to the last occurrence of this boot ID. */
|
|
|
1ff636 |
+ sd_id128_to_string(next_boot->id, match + 9);
|
|
|
1ff636 |
+ r = sd_journal_add_match(j, match, sizeof(match) - 1);
|
|
|
1ff636 |
+ if (r < 0)
|
|
|
1ff636 |
+ return r;
|
|
|
1ff636 |
|
|
|
1ff636 |
- if (!GREEDY_REALLOC(*boots, allocated, *count + 1))
|
|
|
1ff636 |
- return log_oom();
|
|
|
1ff636 |
+ if (advance_older)
|
|
|
1ff636 |
+ r = sd_journal_seek_head(j);
|
|
|
1ff636 |
+ else
|
|
|
1ff636 |
+ r = sd_journal_seek_tail(j);
|
|
|
1ff636 |
+ if (r < 0)
|
|
|
1ff636 |
+ return r;
|
|
|
1ff636 |
|
|
|
1ff636 |
- id = *boots + *count;
|
|
|
1ff636 |
+ if (advance_older)
|
|
|
1ff636 |
+ r = sd_journal_next(j);
|
|
|
1ff636 |
+ else
|
|
|
1ff636 |
+ r = sd_journal_previous(j);
|
|
|
1ff636 |
+ if (r < 0)
|
|
|
1ff636 |
+ return r;
|
|
|
1ff636 |
+ else if (r == 0)
|
|
|
1ff636 |
+ return -ENODATA; /* This shouldn't happen. We just came from this very boot ID. */
|
|
|
1ff636 |
|
|
|
1ff636 |
- r = sd_id128_from_string(((const char *)data) + strlen("_BOOT_ID="), &id->id);
|
|
|
1ff636 |
+ if (read_realtime) {
|
|
|
1ff636 |
+ r = sd_journal_get_realtime_usec(j, &next_boot->last);
|
|
|
1ff636 |
if (r < 0)
|
|
|
1ff636 |
- continue;
|
|
|
1ff636 |
+ return r;
|
|
|
1ff636 |
+ }
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ *boot = next_boot;
|
|
|
1ff636 |
+ next_boot = NULL;
|
|
|
1ff636 |
+ return 0;
|
|
|
1ff636 |
+}
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+static int get_boots(sd_journal *j,
|
|
|
1ff636 |
+ boot_id_t **boots,
|
|
|
1ff636 |
+ boot_id_t *query_ref_boot,
|
|
|
1ff636 |
+ int ref_boot_offset) {
|
|
|
1ff636 |
+ bool skip_once;
|
|
|
1ff636 |
+ int r, count = 0;
|
|
|
1ff636 |
+ boot_id_t *head = NULL, *tail = NULL;
|
|
|
1ff636 |
+ const bool advance_older = query_ref_boot && ref_boot_offset <= 0;
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ assert(j);
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ /* Adjust for the asymmetry that offset 0 is
|
|
|
1ff636 |
+ * the last (and current) boot, while 1 is considered the
|
|
|
1ff636 |
+ * (chronological) first boot in the journal. */
|
|
|
1ff636 |
+ skip_once = query_ref_boot && sd_id128_is_null(query_ref_boot->id) && ref_boot_offset < 0;
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ /* Advance to the earliest/latest occurrence of our reference
|
|
|
1ff636 |
+ * boot ID (taking our lookup direction into account), so that
|
|
|
1ff636 |
+ * discover_next_boot() can do its job.
|
|
|
1ff636 |
+ * If no reference is given, the journal head/tail will do,
|
|
|
1ff636 |
+ * they're "virtual" boots after all. */
|
|
|
1ff636 |
+ if (query_ref_boot && !sd_id128_is_null(query_ref_boot->id)) {
|
|
|
1ff636 |
+ char match[9+32+1] = "_BOOT_ID=";
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ sd_journal_flush_matches(j);
|
|
|
1ff636 |
|
|
|
1ff636 |
- r = sd_journal_add_match(j, data, length);
|
|
|
1ff636 |
+ sd_id128_to_string(query_ref_boot->id, match + 9);
|
|
|
1ff636 |
+ r = sd_journal_add_match(j, match, sizeof(match) - 1);
|
|
|
1ff636 |
if (r < 0)
|
|
|
1ff636 |
return r;
|
|
|
1ff636 |
|
|
|
1ff636 |
- r = sd_journal_seek_head(j);
|
|
|
1ff636 |
+ if (advance_older)
|
|
|
1ff636 |
+ r = sd_journal_seek_head(j);
|
|
|
1ff636 |
+ else
|
|
|
1ff636 |
+ r = sd_journal_seek_tail(j);
|
|
|
1ff636 |
if (r < 0)
|
|
|
1ff636 |
return r;
|
|
|
1ff636 |
|
|
|
1ff636 |
- r = sd_journal_next(j);
|
|
|
1ff636 |
+ if (advance_older)
|
|
|
1ff636 |
+ r = sd_journal_next(j);
|
|
|
1ff636 |
+ else
|
|
|
1ff636 |
+ r = sd_journal_previous(j);
|
|
|
1ff636 |
if (r < 0)
|
|
|
1ff636 |
return r;
|
|
|
1ff636 |
else if (r == 0)
|
|
|
1ff636 |
- goto flush;
|
|
|
1ff636 |
-
|
|
|
1ff636 |
- r = sd_journal_get_realtime_usec(j, &id->first);
|
|
|
1ff636 |
+ goto finish;
|
|
|
1ff636 |
+ else if (ref_boot_offset == 0) {
|
|
|
1ff636 |
+ count = 1;
|
|
|
1ff636 |
+ goto finish;
|
|
|
1ff636 |
+ }
|
|
|
1ff636 |
+ } else {
|
|
|
1ff636 |
+ if (advance_older)
|
|
|
1ff636 |
+ r = sd_journal_seek_tail(j);
|
|
|
1ff636 |
+ else
|
|
|
1ff636 |
+ r = sd_journal_seek_head(j);
|
|
|
1ff636 |
if (r < 0)
|
|
|
1ff636 |
return r;
|
|
|
1ff636 |
|
|
|
1ff636 |
- if (query_ref_boot) {
|
|
|
1ff636 |
- id->last = 0;
|
|
|
1ff636 |
- if (sd_id128_equal(id->id, query_ref_boot->id))
|
|
|
1ff636 |
- *query_ref_boot = *id;
|
|
|
1ff636 |
- } else {
|
|
|
1ff636 |
- r = sd_journal_seek_tail(j);
|
|
|
1ff636 |
- if (r < 0)
|
|
|
1ff636 |
- return r;
|
|
|
1ff636 |
+ /* No sd_journal_next/previous here. */
|
|
|
1ff636 |
+ }
|
|
|
1ff636 |
|
|
|
1ff636 |
- r = sd_journal_previous(j);
|
|
|
1ff636 |
- if (r < 0)
|
|
|
1ff636 |
- return r;
|
|
|
1ff636 |
- else if (r == 0)
|
|
|
1ff636 |
- goto flush;
|
|
|
1ff636 |
+ while (true) {
|
|
|
1ff636 |
+ _cleanup_free_ boot_id_t *current = NULL;
|
|
|
1ff636 |
|
|
|
1ff636 |
- r = sd_journal_get_realtime_usec(j, &id->last);
|
|
|
1ff636 |
- if (r < 0)
|
|
|
1ff636 |
- return r;
|
|
|
1ff636 |
+ r = discover_next_boot(j, ¤t, advance_older, !query_ref_boot);
|
|
|
1ff636 |
+ if (r < 0) {
|
|
|
1ff636 |
+ boot_id_t *id, *id_next;
|
|
|
1ff636 |
+ LIST_FOREACH_SAFE(boot_list, id, id_next, head)
|
|
|
1ff636 |
+ free(id);
|
|
|
1ff636 |
+ return r;
|
|
|
1ff636 |
}
|
|
|
1ff636 |
|
|
|
1ff636 |
- (*count)++;
|
|
|
1ff636 |
- flush:
|
|
|
1ff636 |
- sd_journal_flush_matches(j);
|
|
|
1ff636 |
+ if (!current)
|
|
|
1ff636 |
+ break;
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ if (query_ref_boot) {
|
|
|
1ff636 |
+ if (!skip_once)
|
|
|
1ff636 |
+ ref_boot_offset += advance_older ? 1 : -1;
|
|
|
1ff636 |
+ skip_once = false;
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ if (ref_boot_offset == 0) {
|
|
|
1ff636 |
+ count = 1;
|
|
|
1ff636 |
+ query_ref_boot->id = current->id;
|
|
|
1ff636 |
+ break;
|
|
|
1ff636 |
+ }
|
|
|
1ff636 |
+ } else {
|
|
|
1ff636 |
+ LIST_INSERT_AFTER(boot_list, head, tail, current);
|
|
|
1ff636 |
+ tail = current;
|
|
|
1ff636 |
+ current = NULL;
|
|
|
1ff636 |
+ count++;
|
|
|
1ff636 |
+ }
|
|
|
1ff636 |
}
|
|
|
1ff636 |
|
|
|
1ff636 |
- qsort_safe(*boots, *count, sizeof(boot_id_t), boot_id_cmp);
|
|
|
1ff636 |
- return 0;
|
|
|
1ff636 |
+finish:
|
|
|
1ff636 |
+ if (boots)
|
|
|
1ff636 |
+ *boots = head;
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ sd_journal_flush_matches(j);
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ return count;
|
|
|
1ff636 |
}
|
|
|
1ff636 |
|
|
|
1ff636 |
static int list_boots(sd_journal *j) {
|
|
|
1ff636 |
- int r, w, i;
|
|
|
1ff636 |
- unsigned int count;
|
|
|
1ff636 |
- boot_id_t *id;
|
|
|
1ff636 |
- _cleanup_free_ boot_id_t *all_ids = NULL;
|
|
|
1ff636 |
+ int w, i, count;
|
|
|
1ff636 |
+ boot_id_t *id, *id_next, *all_ids;
|
|
|
1ff636 |
|
|
|
1ff636 |
assert(j);
|
|
|
1ff636 |
|
|
|
1ff636 |
- r = get_boots(j, &all_ids, &count, NULL);
|
|
|
1ff636 |
- if (r < 0)
|
|
|
1ff636 |
- return r;
|
|
|
1ff636 |
+ count = get_boots(j, &all_ids, NULL, 0);
|
|
|
1ff636 |
+ if (count <= 0)
|
|
|
1ff636 |
+ return count;
|
|
|
1ff636 |
|
|
|
1ff636 |
pager_open_if_enabled();
|
|
|
1ff636 |
|
|
|
1ff636 |
/* numbers are one less, but we need an extra char for the sign */
|
|
|
1ff636 |
w = DECIMAL_STR_WIDTH(count - 1) + 1;
|
|
|
1ff636 |
|
|
|
1ff636 |
- for (id = all_ids, i = 0; id < all_ids + count; id++, i++) {
|
|
|
1ff636 |
+ i = 0;
|
|
|
1ff636 |
+ LIST_FOREACH_SAFE(boot_list, id, id_next, all_ids) {
|
|
|
1ff636 |
char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX];
|
|
|
1ff636 |
|
|
|
1ff636 |
printf("% *i " SD_ID128_FORMAT_STR " %s—%s\n",
|
|
|
1ff636 |
@@ -966,39 +1064,8 @@ static int list_boots(sd_journal *j) {
|
|
|
1ff636 |
SD_ID128_FORMAT_VAL(id->id),
|
|
|
1ff636 |
format_timestamp_maybe_utc(a, sizeof(a), id->first),
|
|
|
1ff636 |
format_timestamp_maybe_utc(b, sizeof(b), id->last));
|
|
|
1ff636 |
- }
|
|
|
1ff636 |
-
|
|
|
1ff636 |
- return 0;
|
|
|
1ff636 |
-}
|
|
|
1ff636 |
-
|
|
|
1ff636 |
-static int get_boot_id_by_offset(sd_journal *j, sd_id128_t *boot_id, int offset) {
|
|
|
1ff636 |
- int r;
|
|
|
1ff636 |
- unsigned int count;
|
|
|
1ff636 |
- boot_id_t ref_boot_id = {}, *id;
|
|
|
1ff636 |
- _cleanup_free_ boot_id_t *all_ids = NULL;
|
|
|
1ff636 |
-
|
|
|
1ff636 |
- assert(j);
|
|
|
1ff636 |
- assert(boot_id);
|
|
|
1ff636 |
-
|
|
|
1ff636 |
- ref_boot_id.id = *boot_id;
|
|
|
1ff636 |
- r = get_boots(j, &all_ids, &count, &ref_boot_id);
|
|
|
1ff636 |
- if (r < 0)
|
|
|
1ff636 |
- return r;
|
|
|
1ff636 |
-
|
|
|
1ff636 |
- if (sd_id128_equal(*boot_id, SD_ID128_NULL)) {
|
|
|
1ff636 |
- if (offset > (int) count || offset <= -(int)count)
|
|
|
1ff636 |
- return -EADDRNOTAVAIL;
|
|
|
1ff636 |
-
|
|
|
1ff636 |
- *boot_id = all_ids[(offset <= 0)*count + offset - 1].id;
|
|
|
1ff636 |
- } else {
|
|
|
1ff636 |
- id = bsearch(&ref_boot_id, all_ids, count, sizeof(boot_id_t), boot_id_cmp);
|
|
|
1ff636 |
-
|
|
|
1ff636 |
- if (!id ||
|
|
|
1ff636 |
- offset <= 0 ? (id - all_ids) + offset < 0 :
|
|
|
1ff636 |
- (id - all_ids) + offset >= (int) count)
|
|
|
1ff636 |
- return -EADDRNOTAVAIL;
|
|
|
1ff636 |
-
|
|
|
1ff636 |
- *boot_id = (id + offset)->id;
|
|
|
1ff636 |
+ i++;
|
|
|
1ff636 |
+ free(id);
|
|
|
1ff636 |
}
|
|
|
1ff636 |
|
|
|
1ff636 |
return 0;
|
|
|
1ff636 |
@@ -1007,6 +1074,7 @@ static int get_boot_id_by_offset(sd_journal *j, sd_id128_t *boot_id, int offset)
|
|
|
1ff636 |
static int add_boot(sd_journal *j) {
|
|
|
1ff636 |
char match[9+32+1] = "_BOOT_ID=";
|
|
|
1ff636 |
int r;
|
|
|
1ff636 |
+ boot_id_t ref_boot_id = {};
|
|
|
1ff636 |
|
|
|
1ff636 |
assert(j);
|
|
|
1ff636 |
|
|
|
1ff636 |
@@ -1016,17 +1084,22 @@ static int add_boot(sd_journal *j) {
|
|
|
1ff636 |
if (arg_boot_offset == 0 && sd_id128_equal(arg_boot_id, SD_ID128_NULL))
|
|
|
1ff636 |
return add_match_this_boot(j, arg_machine);
|
|
|
1ff636 |
|
|
|
1ff636 |
- r = get_boot_id_by_offset(j, &arg_boot_id, arg_boot_offset);
|
|
|
1ff636 |
- if (r < 0) {
|
|
|
1ff636 |
- if (sd_id128_equal(arg_boot_id, SD_ID128_NULL))
|
|
|
1ff636 |
- log_error_errno(r, "Failed to look up boot %+i: %m", arg_boot_offset);
|
|
|
1ff636 |
+ ref_boot_id.id = arg_boot_id;
|
|
|
1ff636 |
+ r = get_boots(j, NULL, &ref_boot_id, arg_boot_offset);
|
|
|
1ff636 |
+ assert(r <= 1);
|
|
|
1ff636 |
+ if (r <= 0) {
|
|
|
1ff636 |
+ const char *reason = (r == 0) ? "No such boot ID in journal" : strerror(-r);
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ if (sd_id128_is_null(arg_boot_id))
|
|
|
1ff636 |
+ log_error("Failed to look up boot %+i: %s", arg_boot_offset, reason);
|
|
|
1ff636 |
else
|
|
|
1ff636 |
log_error("Failed to look up boot ID "SD_ID128_FORMAT_STR"%+i: %s",
|
|
|
1ff636 |
- SD_ID128_FORMAT_VAL(arg_boot_id), arg_boot_offset, strerror(-r));
|
|
|
1ff636 |
- return r;
|
|
|
1ff636 |
+ SD_ID128_FORMAT_VAL(arg_boot_id), arg_boot_offset, reason);
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ return r == 0 ? -ENODATA : r;
|
|
|
1ff636 |
}
|
|
|
1ff636 |
|
|
|
1ff636 |
- sd_id128_to_string(arg_boot_id, match + 9);
|
|
|
1ff636 |
+ sd_id128_to_string(ref_boot_id.id, match + 9);
|
|
|
1ff636 |
|
|
|
1ff636 |
r = sd_journal_add_match(j, match, sizeof(match) - 1);
|
|
|
1ff636 |
if (r < 0)
|