From 05c90300b1a5d0c21281259866ea71982d7e8353 Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: May 20 2015 15:17:36 +0000 Subject: Fix compilation --- diff --git a/0174-resolved-fix-crash-when-shutting-down.patch b/0174-resolved-fix-crash-when-shutting-down.patch index e4d0963..843224a 100644 --- a/0174-resolved-fix-crash-when-shutting-down.patch +++ b/0174-resolved-fix-crash-when-shutting-down.patch @@ -1,4 +1,4 @@ -From 8851f051210fa9c18ffb94ebe601261bacaf37d4 Mon Sep 17 00:00:00 2001 +From 94fa50b44f5b23a075df80bfd4854865ca0b649b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 18 May 2015 23:23:17 +0200 Subject: [PATCH] resolved: fix crash when shutting down @@ -11,28 +11,25 @@ Reported by Cristian Rodríguez http://lists.freedesktop.org/archives/systemd-devel/2015-May/031626.html (cherry picked from commit cab5b05903096e1c9cf5575ccc73f89d15c8db69) --- - src/resolve/resolved-dns-cache.c | 7 ++----- + src/resolve/resolved-dns-cache.c | 4 +--- src/resolve/resolved-dns-server.c | 15 ++++++++------- src/resolve/resolved-link.c | 6 +++--- src/resolve/resolved-manager.c | 4 ++-- src/shared/prioq.c | 6 ++++-- src/shared/prioq.h | 2 +- - 6 files changed, 20 insertions(+), 20 deletions(-) + 6 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c -index 33ca4d1a45..be52891681 100644 +index 33ca4d1a45..874207cfb8 100644 --- a/src/resolve/resolved-dns-cache.c +++ b/src/resolve/resolved-dns-cache.c -@@ -91,11 +91,8 @@ void dns_cache_flush(DnsCache *c) { - assert(hashmap_size(c->by_key) == 0); - assert(prioq_size(c->by_expiry) == 0); +@@ -93,9 +93,7 @@ void dns_cache_flush(DnsCache *c) { -- hashmap_free(c->by_key); -- c->by_key = NULL; + hashmap_free(c->by_key); + c->by_key = NULL; - - prioq_free(c->by_expiry); - c->by_expiry = NULL; -+ c->by_key = hashmap_free(c->by_key); + c->by_expiry = prioq_free(c->by_expiry); } diff --git a/0175-resolved-allow-DnsAnswer-objects-with-no-space-for-R.patch b/0175-resolved-allow-DnsAnswer-objects-with-no-space-for-R.patch index 1a25038..63c64d6 100644 --- a/0175-resolved-allow-DnsAnswer-objects-with-no-space-for-R.patch +++ b/0175-resolved-allow-DnsAnswer-objects-with-no-space-for-R.patch @@ -1,4 +1,4 @@ -From c374a32aa317517702ee3531f6fa59be52c4a9f0 Mon Sep 17 00:00:00 2001 +From c3c65351593dde09a2d37b571e0737af94386fe6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 18 May 2015 23:38:47 +0200 Subject: [PATCH] resolved: allow DnsAnswer objects with no space for RRs diff --git a/0176-id128-add-new-sd_id128_is_null-call.patch b/0176-id128-add-new-sd_id128_is_null-call.patch new file mode 100644 index 0000000..efda7ed --- /dev/null +++ b/0176-id128-add-new-sd_id128_is_null-call.patch @@ -0,0 +1,25 @@ +From a9303ae3af9bbf482842c084cc7ba49e206538c2 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 24 Feb 2015 00:10:35 +0100 +Subject: [PATCH] id128: add new sd_id128_is_null() call + +(cherry picked from commit 15e80c7b75c3a3188bfaaa0baddccf31ae661a7a) +--- + src/systemd/sd-id128.h | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/systemd/sd-id128.h b/src/systemd/sd-id128.h +index 48fd87671b..9f445278bb 100644 +--- a/src/systemd/sd-id128.h ++++ b/src/systemd/sd-id128.h +@@ -106,6 +106,10 @@ _sd_pure_ static inline int sd_id128_equal(sd_id128_t a, sd_id128_t b) { + return memcmp(&a, &b, 16) == 0; + } + ++_sd_pure_ static inline int sd_id128_is_null(sd_id128_t a) { ++ return a.qwords[0] == 0 && a.qwords[1] == 0; ++} ++ + #define SD_ID128_NULL ((const sd_id128_t) { .qwords = { 0, 0 }}) + + _SD_END_DECLARATIONS; diff --git a/0176-journalctl-Improve-boot-ID-lookup.patch b/0176-journalctl-Improve-boot-ID-lookup.patch deleted file mode 100644 index 1ac0dbf..0000000 --- a/0176-journalctl-Improve-boot-ID-lookup.patch +++ /dev/null @@ -1,400 +0,0 @@ -From a1b1bfdb3e18c69fe7b7665ac9f7256cf4485bbc Mon Sep 17 00:00:00 2001 -From: Jan Janssen -Date: Fri, 1 May 2015 15:15:16 +0200 -Subject: [PATCH] journalctl: Improve boot ID lookup - -This method should greatly improve offset based lookup, by simply jumping -from one boot to the next boot. It starts at the journal head to get the -a boot ID, makes a _BOOT_ID match and then comes from the opposite -journal direction (tail) to get to the end that boot. After flushing the matches -and advancing the journal from that exact position, we arrive at the start -of next boot. Rinse and repeat. - -This is faster than the old method of aggregating the full boot listing just -so we can jump to a specific boot, which can be a real pain on big journals -just for a mere "-b -1" case. - -As an additional benefit --list-boots should improve slightly too, because -it does less seeking. - -Note that there can be a change in boot order with this lookup method -because it will use the order of boots in the journal, not the realtime stamp -stored in them. That's arguably better, though. -Another deficiency is that it will get confused with boots interleaving in the -journal, therefore, it will refuse operation in --merge, --file and --directory mode. - -https://bugs.freedesktop.org/show_bug.cgi?id=72601 -(cherry picked from commit 596a23293d28f93843aef86721b90043e74d3081) ---- - src/journal/journalctl.c | 275 ++++++++++++++++++++++++++++++----------------- - 1 file changed, 174 insertions(+), 101 deletions(-) - -diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c -index 12c869f5af..c26cc00f51 100644 ---- a/src/journal/journalctl.c -+++ b/src/journal/journalctl.c -@@ -131,6 +131,7 @@ typedef struct boot_id_t { - sd_id128_t id; - uint64_t first; - uint64_t last; -+ LIST_FIELDS(struct boot_id_t, boot_list); - } boot_id_t; - - static void pager_open_if_enabled(void) { -@@ -735,6 +736,11 @@ static int parse_argv(int argc, char *argv[]) { - return -EINVAL; - } - -+ if ((arg_boot || arg_action == ACTION_LIST_BOOTS) && (arg_file || arg_directory || arg_merge)) { -+ log_error("Using --boot or --list-boots with --file, --directory or --merge is not supported."); -+ return -EINVAL; -+ } -+ - return 1; - } - -@@ -854,111 +860,203 @@ static int add_matches(sd_journal *j, char **args) { - return 0; - } - --static int boot_id_cmp(const void *a, const void *b) { -- uint64_t _a, _b; -+static int discover_next_boot(sd_journal *j, -+ boot_id_t **boot, -+ bool advance_older, -+ bool read_realtime) { -+ int r; -+ char match[9+32+1] = "_BOOT_ID="; -+ _cleanup_free_ boot_id_t *next_boot = NULL; - -- _a = ((const boot_id_t *)a)->first; -- _b = ((const boot_id_t *)b)->first; -+ assert(j); -+ assert(boot); - -- return _a < _b ? -1 : (_a > _b ? 1 : 0); --} -+ /* We expect the journal to be on the last position of a boot -+ * (in relation to the direction we are going), so that the next -+ * invocation of sd_journal_next/previous will be from a different -+ * boot. We then collect any information we desire and then jump -+ * to the last location of the new boot by using a _BOOT_ID match -+ * coming from the other journal direction. */ - --static int get_boots(sd_journal *j, -- boot_id_t **boots, -- unsigned int *count, -- boot_id_t *query_ref_boot) { -- int r; -- const void *data; -- size_t length, allocated = 0; -+ /* Make sure we aren't restricted by any _BOOT_ID matches, so that -+ * we can actually advance to a *different* boot. */ -+ sd_journal_flush_matches(j); - -- assert(j); -- assert(boots); -- assert(count); -+ if (advance_older) -+ r = sd_journal_previous(j); -+ else -+ r = sd_journal_next(j); -+ if (r < 0) -+ return r; -+ else if (r == 0) -+ return 0; /* End of journal, yay. */ -+ -+ next_boot = new0(boot_id_t, 1); -+ if (!next_boot) -+ return log_oom(); - -- r = sd_journal_query_unique(j, "_BOOT_ID"); -+ r = sd_journal_get_monotonic_usec(j, NULL, &next_boot->id); - if (r < 0) - return r; - -- *count = 0; -- SD_JOURNAL_FOREACH_UNIQUE(j, data, length) { -- boot_id_t *id; -+ if (read_realtime) { -+ r = sd_journal_get_realtime_usec(j, &next_boot->first); -+ if (r < 0) -+ return r; -+ } - -- assert(startswith(data, "_BOOT_ID=")); -+ /* Now seek to the last occurrence of this boot ID. */ -+ sd_id128_to_string(next_boot->id, match + 9); -+ r = sd_journal_add_match(j, match, sizeof(match) - 1); -+ if (r < 0) -+ return r; - -- if (!GREEDY_REALLOC(*boots, allocated, *count + 1)) -- return log_oom(); -+ if (advance_older) -+ r = sd_journal_seek_head(j); -+ else -+ r = sd_journal_seek_tail(j); -+ if (r < 0) -+ return r; - -- id = *boots + *count; -+ if (advance_older) -+ r = sd_journal_next(j); -+ else -+ r = sd_journal_previous(j); -+ if (r < 0) -+ return r; -+ else if (r == 0) -+ return -ENODATA; /* This shouldn't happen. We just came from this very boot ID. */ - -- r = sd_id128_from_string(((const char *)data) + strlen("_BOOT_ID="), &id->id); -+ if (read_realtime) { -+ r = sd_journal_get_realtime_usec(j, &next_boot->last); - if (r < 0) -- continue; -+ return r; -+ } -+ -+ *boot = next_boot; -+ next_boot = NULL; -+ return 0; -+} -+ -+static int get_boots(sd_journal *j, -+ boot_id_t **boots, -+ boot_id_t *query_ref_boot, -+ int ref_boot_offset) { -+ bool skip_once; -+ int r, count = 0; -+ boot_id_t *head = NULL, *tail = NULL; -+ const bool advance_older = query_ref_boot && ref_boot_offset <= 0; -+ -+ assert(j); -+ -+ /* Adjust for the asymmetry that offset 0 is -+ * the last (and current) boot, while 1 is considered the -+ * (chronological) first boot in the journal. */ -+ skip_once = query_ref_boot && sd_id128_is_null(query_ref_boot->id) && ref_boot_offset < 0; -+ -+ /* Advance to the earliest/latest occurrence of our reference -+ * boot ID (taking our lookup direction into account), so that -+ * discover_next_boot() can do its job. -+ * If no reference is given, the journal head/tail will do, -+ * they're "virtual" boots after all. */ -+ if (query_ref_boot && !sd_id128_is_null(query_ref_boot->id)) { -+ char match[9+32+1] = "_BOOT_ID="; -+ -+ sd_journal_flush_matches(j); - -- r = sd_journal_add_match(j, data, length); -+ sd_id128_to_string(query_ref_boot->id, match + 9); -+ r = sd_journal_add_match(j, match, sizeof(match) - 1); - if (r < 0) - return r; - -- r = sd_journal_seek_head(j); -+ if (advance_older) -+ r = sd_journal_seek_head(j); -+ else -+ r = sd_journal_seek_tail(j); - if (r < 0) - return r; - -- r = sd_journal_next(j); -+ if (advance_older) -+ r = sd_journal_next(j); -+ else -+ r = sd_journal_previous(j); - if (r < 0) - return r; - else if (r == 0) -- goto flush; -- -- r = sd_journal_get_realtime_usec(j, &id->first); -+ goto finish; -+ else if (ref_boot_offset == 0) { -+ count = 1; -+ goto finish; -+ } -+ } else { -+ if (advance_older) -+ r = sd_journal_seek_tail(j); -+ else -+ r = sd_journal_seek_head(j); - if (r < 0) - return r; - -- if (query_ref_boot) { -- id->last = 0; -- if (sd_id128_equal(id->id, query_ref_boot->id)) -- *query_ref_boot = *id; -- } else { -- r = sd_journal_seek_tail(j); -- if (r < 0) -- return r; -+ /* No sd_journal_next/previous here. */ -+ } - -- r = sd_journal_previous(j); -- if (r < 0) -- return r; -- else if (r == 0) -- goto flush; -+ while (true) { -+ _cleanup_free_ boot_id_t *current = NULL; - -- r = sd_journal_get_realtime_usec(j, &id->last); -- if (r < 0) -- return r; -+ r = discover_next_boot(j, ¤t, advance_older, !query_ref_boot); -+ if (r < 0) { -+ boot_id_t *id, *id_next; -+ LIST_FOREACH_SAFE(boot_list, id, id_next, head) -+ free(id); -+ return r; - } - -- (*count)++; -- flush: -- sd_journal_flush_matches(j); -+ if (!current) -+ break; -+ -+ if (query_ref_boot) { -+ if (!skip_once) -+ ref_boot_offset += advance_older ? 1 : -1; -+ skip_once = false; -+ -+ if (ref_boot_offset == 0) { -+ count = 1; -+ query_ref_boot->id = current->id; -+ break; -+ } -+ } else { -+ LIST_INSERT_AFTER(boot_list, head, tail, current); -+ tail = current; -+ current = NULL; -+ count++; -+ } - } - -- qsort_safe(*boots, *count, sizeof(boot_id_t), boot_id_cmp); -- return 0; -+finish: -+ if (boots) -+ *boots = head; -+ -+ sd_journal_flush_matches(j); -+ -+ return count; - } - - static int list_boots(sd_journal *j) { -- int r, w, i; -- unsigned int count; -- boot_id_t *id; -- _cleanup_free_ boot_id_t *all_ids = NULL; -+ int w, i, count; -+ boot_id_t *id, *id_next, *all_ids; - - assert(j); - -- r = get_boots(j, &all_ids, &count, NULL); -- if (r < 0) -- return r; -+ count = get_boots(j, &all_ids, NULL, 0); -+ if (count <= 0) -+ return count; - - pager_open_if_enabled(); - - /* numbers are one less, but we need an extra char for the sign */ - w = DECIMAL_STR_WIDTH(count - 1) + 1; - -- for (id = all_ids, i = 0; id < all_ids + count; id++, i++) { -+ i = 0; -+ LIST_FOREACH_SAFE(boot_list, id, id_next, all_ids) { - char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX]; - - printf("% *i " SD_ID128_FORMAT_STR " %s—%s\n", -@@ -966,39 +1064,8 @@ static int list_boots(sd_journal *j) { - SD_ID128_FORMAT_VAL(id->id), - format_timestamp_maybe_utc(a, sizeof(a), id->first), - format_timestamp_maybe_utc(b, sizeof(b), id->last)); -- } -- -- return 0; --} -- --static int get_boot_id_by_offset(sd_journal *j, sd_id128_t *boot_id, int offset) { -- int r; -- unsigned int count; -- boot_id_t ref_boot_id = {}, *id; -- _cleanup_free_ boot_id_t *all_ids = NULL; -- -- assert(j); -- assert(boot_id); -- -- ref_boot_id.id = *boot_id; -- r = get_boots(j, &all_ids, &count, &ref_boot_id); -- if (r < 0) -- return r; -- -- if (sd_id128_equal(*boot_id, SD_ID128_NULL)) { -- if (offset > (int) count || offset <= -(int)count) -- return -EADDRNOTAVAIL; -- -- *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 || -- offset <= 0 ? (id - all_ids) + offset < 0 : -- (id - all_ids) + offset >= (int) count) -- return -EADDRNOTAVAIL; -- -- *boot_id = (id + offset)->id; -+ i++; -+ free(id); - } - - return 0; -@@ -1007,6 +1074,7 @@ static int get_boot_id_by_offset(sd_journal *j, sd_id128_t *boot_id, int offset) - static int add_boot(sd_journal *j) { - char match[9+32+1] = "_BOOT_ID="; - int r; -+ boot_id_t ref_boot_id = {}; - - assert(j); - -@@ -1016,17 +1084,22 @@ 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_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_errno(r, "Failed to look up boot %+i: %m", arg_boot_offset); -+ ref_boot_id.id = arg_boot_id; -+ r = get_boots(j, NULL, &ref_boot_id, arg_boot_offset); -+ assert(r <= 1); -+ if (r <= 0) { -+ const char *reason = (r == 0) ? "No such boot ID in journal" : strerror(-r); -+ -+ if (sd_id128_is_null(arg_boot_id)) -+ log_error("Failed to look up boot %+i: %s", arg_boot_offset, reason); - else - log_error("Failed to look up boot ID "SD_ID128_FORMAT_STR"%+i: %s", -- SD_ID128_FORMAT_VAL(arg_boot_id), arg_boot_offset, strerror(-r)); -- return r; -+ SD_ID128_FORMAT_VAL(arg_boot_id), arg_boot_offset, reason); -+ -+ return r == 0 ? -ENODATA : r; - } - -- sd_id128_to_string(arg_boot_id, match + 9); -+ sd_id128_to_string(ref_boot_id.id, match + 9); - - r = sd_journal_add_match(j, match, sizeof(match) - 1); - if (r < 0) diff --git a/0177-journalctl-Improve-boot-ID-lookup.patch b/0177-journalctl-Improve-boot-ID-lookup.patch new file mode 100644 index 0000000..e183d47 --- /dev/null +++ b/0177-journalctl-Improve-boot-ID-lookup.patch @@ -0,0 +1,400 @@ +From fb2b7ef1b9a4247adae4a9c85516c72674327488 Mon Sep 17 00:00:00 2001 +From: Jan Janssen +Date: Fri, 1 May 2015 15:15:16 +0200 +Subject: [PATCH] journalctl: Improve boot ID lookup + +This method should greatly improve offset based lookup, by simply jumping +from one boot to the next boot. It starts at the journal head to get the +a boot ID, makes a _BOOT_ID match and then comes from the opposite +journal direction (tail) to get to the end that boot. After flushing the matches +and advancing the journal from that exact position, we arrive at the start +of next boot. Rinse and repeat. + +This is faster than the old method of aggregating the full boot listing just +so we can jump to a specific boot, which can be a real pain on big journals +just for a mere "-b -1" case. + +As an additional benefit --list-boots should improve slightly too, because +it does less seeking. + +Note that there can be a change in boot order with this lookup method +because it will use the order of boots in the journal, not the realtime stamp +stored in them. That's arguably better, though. +Another deficiency is that it will get confused with boots interleaving in the +journal, therefore, it will refuse operation in --merge, --file and --directory mode. + +https://bugs.freedesktop.org/show_bug.cgi?id=72601 +(cherry picked from commit 596a23293d28f93843aef86721b90043e74d3081) +--- + src/journal/journalctl.c | 275 ++++++++++++++++++++++++++++++----------------- + 1 file changed, 174 insertions(+), 101 deletions(-) + +diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c +index 12c869f5af..c26cc00f51 100644 +--- a/src/journal/journalctl.c ++++ b/src/journal/journalctl.c +@@ -131,6 +131,7 @@ typedef struct boot_id_t { + sd_id128_t id; + uint64_t first; + uint64_t last; ++ LIST_FIELDS(struct boot_id_t, boot_list); + } boot_id_t; + + static void pager_open_if_enabled(void) { +@@ -735,6 +736,11 @@ static int parse_argv(int argc, char *argv[]) { + return -EINVAL; + } + ++ if ((arg_boot || arg_action == ACTION_LIST_BOOTS) && (arg_file || arg_directory || arg_merge)) { ++ log_error("Using --boot or --list-boots with --file, --directory or --merge is not supported."); ++ return -EINVAL; ++ } ++ + return 1; + } + +@@ -854,111 +860,203 @@ static int add_matches(sd_journal *j, char **args) { + return 0; + } + +-static int boot_id_cmp(const void *a, const void *b) { +- uint64_t _a, _b; ++static int discover_next_boot(sd_journal *j, ++ boot_id_t **boot, ++ bool advance_older, ++ bool read_realtime) { ++ int r; ++ char match[9+32+1] = "_BOOT_ID="; ++ _cleanup_free_ boot_id_t *next_boot = NULL; + +- _a = ((const boot_id_t *)a)->first; +- _b = ((const boot_id_t *)b)->first; ++ assert(j); ++ assert(boot); + +- return _a < _b ? -1 : (_a > _b ? 1 : 0); +-} ++ /* We expect the journal to be on the last position of a boot ++ * (in relation to the direction we are going), so that the next ++ * invocation of sd_journal_next/previous will be from a different ++ * boot. We then collect any information we desire and then jump ++ * to the last location of the new boot by using a _BOOT_ID match ++ * coming from the other journal direction. */ + +-static int get_boots(sd_journal *j, +- boot_id_t **boots, +- unsigned int *count, +- boot_id_t *query_ref_boot) { +- int r; +- const void *data; +- size_t length, allocated = 0; ++ /* Make sure we aren't restricted by any _BOOT_ID matches, so that ++ * we can actually advance to a *different* boot. */ ++ sd_journal_flush_matches(j); + +- assert(j); +- assert(boots); +- assert(count); ++ if (advance_older) ++ r = sd_journal_previous(j); ++ else ++ r = sd_journal_next(j); ++ if (r < 0) ++ return r; ++ else if (r == 0) ++ return 0; /* End of journal, yay. */ ++ ++ next_boot = new0(boot_id_t, 1); ++ if (!next_boot) ++ return log_oom(); + +- r = sd_journal_query_unique(j, "_BOOT_ID"); ++ r = sd_journal_get_monotonic_usec(j, NULL, &next_boot->id); + if (r < 0) + return r; + +- *count = 0; +- SD_JOURNAL_FOREACH_UNIQUE(j, data, length) { +- boot_id_t *id; ++ if (read_realtime) { ++ r = sd_journal_get_realtime_usec(j, &next_boot->first); ++ if (r < 0) ++ return r; ++ } + +- assert(startswith(data, "_BOOT_ID=")); ++ /* Now seek to the last occurrence of this boot ID. */ ++ sd_id128_to_string(next_boot->id, match + 9); ++ r = sd_journal_add_match(j, match, sizeof(match) - 1); ++ if (r < 0) ++ return r; + +- if (!GREEDY_REALLOC(*boots, allocated, *count + 1)) +- return log_oom(); ++ if (advance_older) ++ r = sd_journal_seek_head(j); ++ else ++ r = sd_journal_seek_tail(j); ++ if (r < 0) ++ return r; + +- id = *boots + *count; ++ if (advance_older) ++ r = sd_journal_next(j); ++ else ++ r = sd_journal_previous(j); ++ if (r < 0) ++ return r; ++ else if (r == 0) ++ return -ENODATA; /* This shouldn't happen. We just came from this very boot ID. */ + +- r = sd_id128_from_string(((const char *)data) + strlen("_BOOT_ID="), &id->id); ++ if (read_realtime) { ++ r = sd_journal_get_realtime_usec(j, &next_boot->last); + if (r < 0) +- continue; ++ return r; ++ } ++ ++ *boot = next_boot; ++ next_boot = NULL; ++ return 0; ++} ++ ++static int get_boots(sd_journal *j, ++ boot_id_t **boots, ++ boot_id_t *query_ref_boot, ++ int ref_boot_offset) { ++ bool skip_once; ++ int r, count = 0; ++ boot_id_t *head = NULL, *tail = NULL; ++ const bool advance_older = query_ref_boot && ref_boot_offset <= 0; ++ ++ assert(j); ++ ++ /* Adjust for the asymmetry that offset 0 is ++ * the last (and current) boot, while 1 is considered the ++ * (chronological) first boot in the journal. */ ++ skip_once = query_ref_boot && sd_id128_is_null(query_ref_boot->id) && ref_boot_offset < 0; ++ ++ /* Advance to the earliest/latest occurrence of our reference ++ * boot ID (taking our lookup direction into account), so that ++ * discover_next_boot() can do its job. ++ * If no reference is given, the journal head/tail will do, ++ * they're "virtual" boots after all. */ ++ if (query_ref_boot && !sd_id128_is_null(query_ref_boot->id)) { ++ char match[9+32+1] = "_BOOT_ID="; ++ ++ sd_journal_flush_matches(j); + +- r = sd_journal_add_match(j, data, length); ++ sd_id128_to_string(query_ref_boot->id, match + 9); ++ r = sd_journal_add_match(j, match, sizeof(match) - 1); + if (r < 0) + return r; + +- r = sd_journal_seek_head(j); ++ if (advance_older) ++ r = sd_journal_seek_head(j); ++ else ++ r = sd_journal_seek_tail(j); + if (r < 0) + return r; + +- r = sd_journal_next(j); ++ if (advance_older) ++ r = sd_journal_next(j); ++ else ++ r = sd_journal_previous(j); + if (r < 0) + return r; + else if (r == 0) +- goto flush; +- +- r = sd_journal_get_realtime_usec(j, &id->first); ++ goto finish; ++ else if (ref_boot_offset == 0) { ++ count = 1; ++ goto finish; ++ } ++ } else { ++ if (advance_older) ++ r = sd_journal_seek_tail(j); ++ else ++ r = sd_journal_seek_head(j); + if (r < 0) + return r; + +- if (query_ref_boot) { +- id->last = 0; +- if (sd_id128_equal(id->id, query_ref_boot->id)) +- *query_ref_boot = *id; +- } else { +- r = sd_journal_seek_tail(j); +- if (r < 0) +- return r; ++ /* No sd_journal_next/previous here. */ ++ } + +- r = sd_journal_previous(j); +- if (r < 0) +- return r; +- else if (r == 0) +- goto flush; ++ while (true) { ++ _cleanup_free_ boot_id_t *current = NULL; + +- r = sd_journal_get_realtime_usec(j, &id->last); +- if (r < 0) +- return r; ++ r = discover_next_boot(j, ¤t, advance_older, !query_ref_boot); ++ if (r < 0) { ++ boot_id_t *id, *id_next; ++ LIST_FOREACH_SAFE(boot_list, id, id_next, head) ++ free(id); ++ return r; + } + +- (*count)++; +- flush: +- sd_journal_flush_matches(j); ++ if (!current) ++ break; ++ ++ if (query_ref_boot) { ++ if (!skip_once) ++ ref_boot_offset += advance_older ? 1 : -1; ++ skip_once = false; ++ ++ if (ref_boot_offset == 0) { ++ count = 1; ++ query_ref_boot->id = current->id; ++ break; ++ } ++ } else { ++ LIST_INSERT_AFTER(boot_list, head, tail, current); ++ tail = current; ++ current = NULL; ++ count++; ++ } + } + +- qsort_safe(*boots, *count, sizeof(boot_id_t), boot_id_cmp); +- return 0; ++finish: ++ if (boots) ++ *boots = head; ++ ++ sd_journal_flush_matches(j); ++ ++ return count; + } + + static int list_boots(sd_journal *j) { +- int r, w, i; +- unsigned int count; +- boot_id_t *id; +- _cleanup_free_ boot_id_t *all_ids = NULL; ++ int w, i, count; ++ boot_id_t *id, *id_next, *all_ids; + + assert(j); + +- r = get_boots(j, &all_ids, &count, NULL); +- if (r < 0) +- return r; ++ count = get_boots(j, &all_ids, NULL, 0); ++ if (count <= 0) ++ return count; + + pager_open_if_enabled(); + + /* numbers are one less, but we need an extra char for the sign */ + w = DECIMAL_STR_WIDTH(count - 1) + 1; + +- for (id = all_ids, i = 0; id < all_ids + count; id++, i++) { ++ i = 0; ++ LIST_FOREACH_SAFE(boot_list, id, id_next, all_ids) { + char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX]; + + printf("% *i " SD_ID128_FORMAT_STR " %s—%s\n", +@@ -966,39 +1064,8 @@ static int list_boots(sd_journal *j) { + SD_ID128_FORMAT_VAL(id->id), + format_timestamp_maybe_utc(a, sizeof(a), id->first), + format_timestamp_maybe_utc(b, sizeof(b), id->last)); +- } +- +- return 0; +-} +- +-static int get_boot_id_by_offset(sd_journal *j, sd_id128_t *boot_id, int offset) { +- int r; +- unsigned int count; +- boot_id_t ref_boot_id = {}, *id; +- _cleanup_free_ boot_id_t *all_ids = NULL; +- +- assert(j); +- assert(boot_id); +- +- ref_boot_id.id = *boot_id; +- r = get_boots(j, &all_ids, &count, &ref_boot_id); +- if (r < 0) +- return r; +- +- if (sd_id128_equal(*boot_id, SD_ID128_NULL)) { +- if (offset > (int) count || offset <= -(int)count) +- return -EADDRNOTAVAIL; +- +- *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 || +- offset <= 0 ? (id - all_ids) + offset < 0 : +- (id - all_ids) + offset >= (int) count) +- return -EADDRNOTAVAIL; +- +- *boot_id = (id + offset)->id; ++ i++; ++ free(id); + } + + return 0; +@@ -1007,6 +1074,7 @@ static int get_boot_id_by_offset(sd_journal *j, sd_id128_t *boot_id, int offset) + static int add_boot(sd_journal *j) { + char match[9+32+1] = "_BOOT_ID="; + int r; ++ boot_id_t ref_boot_id = {}; + + assert(j); + +@@ -1016,17 +1084,22 @@ 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_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_errno(r, "Failed to look up boot %+i: %m", arg_boot_offset); ++ ref_boot_id.id = arg_boot_id; ++ r = get_boots(j, NULL, &ref_boot_id, arg_boot_offset); ++ assert(r <= 1); ++ if (r <= 0) { ++ const char *reason = (r == 0) ? "No such boot ID in journal" : strerror(-r); ++ ++ if (sd_id128_is_null(arg_boot_id)) ++ log_error("Failed to look up boot %+i: %s", arg_boot_offset, reason); + else + log_error("Failed to look up boot ID "SD_ID128_FORMAT_STR"%+i: %s", +- SD_ID128_FORMAT_VAL(arg_boot_id), arg_boot_offset, strerror(-r)); +- return r; ++ SD_ID128_FORMAT_VAL(arg_boot_id), arg_boot_offset, reason); ++ ++ return r == 0 ? -ENODATA : r; + } + +- sd_id128_to_string(arg_boot_id, match + 9); ++ sd_id128_to_string(ref_boot_id.id, match + 9); + + r = sd_journal_add_match(j, match, sizeof(match) - 1); + if (r < 0) diff --git a/0177-test-hashmap-fix-an-assert.patch b/0177-test-hashmap-fix-an-assert.patch deleted file mode 100644 index 4484e8c..0000000 --- a/0177-test-hashmap-fix-an-assert.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 094ea5dd03ece57d3162caf33755d76ff2399bb3 Mon Sep 17 00:00:00 2001 -From: Thomas Hindoe Paaboel Andersen -Date: Tue, 19 May 2015 06:33:54 +0200 -Subject: [PATCH] test-hashmap: fix an assert - -CID#1299016 - -(cherry picked from commit b669934fae49c9158c35e612e54e1765edca8584) ---- - src/test/test-hashmap-plain.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/test/test-hashmap-plain.c b/src/test/test-hashmap-plain.c -index 84b508f874..c1a5ccf1f5 100644 ---- a/src/test/test-hashmap-plain.c -+++ b/src/test/test-hashmap-plain.c -@@ -682,7 +682,7 @@ static void test_hashmap_get2(void) { - r = hashmap_get2(m, key_orig, &key_copy); - assert_se(streq(r, val)); - assert_se(key_orig != key_copy); -- assert_se(streq(key_orig, key_orig)); -+ assert_se(streq(key_orig, key_copy)); - - r = hashmap_get2(m, "no such key", NULL); - assert_se(r == NULL); diff --git a/0178-test-hashmap-fix-an-assert.patch b/0178-test-hashmap-fix-an-assert.patch new file mode 100644 index 0000000..a436178 --- /dev/null +++ b/0178-test-hashmap-fix-an-assert.patch @@ -0,0 +1,25 @@ +From 089491f20443a48ad3b65c24b7e98115fe955805 Mon Sep 17 00:00:00 2001 +From: Thomas Hindoe Paaboel Andersen +Date: Tue, 19 May 2015 06:33:54 +0200 +Subject: [PATCH] test-hashmap: fix an assert + +CID#1299016 + +(cherry picked from commit b669934fae49c9158c35e612e54e1765edca8584) +--- + src/test/test-hashmap-plain.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/test/test-hashmap-plain.c b/src/test/test-hashmap-plain.c +index 84b508f874..c1a5ccf1f5 100644 +--- a/src/test/test-hashmap-plain.c ++++ b/src/test/test-hashmap-plain.c +@@ -682,7 +682,7 @@ static void test_hashmap_get2(void) { + r = hashmap_get2(m, key_orig, &key_copy); + assert_se(streq(r, val)); + assert_se(key_orig != key_copy); +- assert_se(streq(key_orig, key_orig)); ++ assert_se(streq(key_orig, key_copy)); + + r = hashmap_get2(m, "no such key", NULL); + assert_se(r == NULL); diff --git a/0178-units-make-sure-systemd-nspawn-.slice-instances-are-.patch b/0178-units-make-sure-systemd-nspawn-.slice-instances-are-.patch deleted file mode 100644 index a108570..0000000 --- a/0178-units-make-sure-systemd-nspawn-.slice-instances-are-.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 97f36b10cbbcc61c6c8194be0af3bb526bab6df2 Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Tue, 19 May 2015 19:47:52 +0200 -Subject: [PATCH] units: make sure systemd-nspawn@.slice instances are actually - located in machine.slice - -https://plus.google.com/112206451048767236518/posts/SYAueyXHeEX -(cherry picked from commit 45d383a3b888195b01b58dbd2c46a11027ff5022) ---- - units/systemd-nspawn@.service.in | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/units/systemd-nspawn@.service.in b/units/systemd-nspawn@.service.in -index 3e26b53fd6..5e86121130 100644 ---- a/units/systemd-nspawn@.service.in -+++ b/units/systemd-nspawn@.service.in -@@ -17,6 +17,7 @@ KillMode=mixed - Type=notify - RestartForceExitStatus=133 - SuccessExitStatus=133 -+Slice=machine.slice - Delegate=yes - - [Install] diff --git a/0179-units-make-sure-systemd-nspawn-.slice-instances-are-.patch b/0179-units-make-sure-systemd-nspawn-.slice-instances-are-.patch new file mode 100644 index 0000000..a664d62 --- /dev/null +++ b/0179-units-make-sure-systemd-nspawn-.slice-instances-are-.patch @@ -0,0 +1,24 @@ +From c1d39ccd066356ef5581081a97acfbe847103de7 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 19 May 2015 19:47:52 +0200 +Subject: [PATCH] units: make sure systemd-nspawn@.slice instances are actually + located in machine.slice + +https://plus.google.com/112206451048767236518/posts/SYAueyXHeEX +(cherry picked from commit 45d383a3b888195b01b58dbd2c46a11027ff5022) +--- + units/systemd-nspawn@.service.in | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/units/systemd-nspawn@.service.in b/units/systemd-nspawn@.service.in +index 3e26b53fd6..5e86121130 100644 +--- a/units/systemd-nspawn@.service.in ++++ b/units/systemd-nspawn@.service.in +@@ -17,6 +17,7 @@ KillMode=mixed + Type=notify + RestartForceExitStatus=133 + SuccessExitStatus=133 ++Slice=machine.slice + Delegate=yes + + [Install] diff --git a/systemd.spec b/systemd.spec index 86f73e2..2f94859 100644 --- a/systemd.spec +++ b/systemd.spec @@ -213,9 +213,10 @@ Patch0172: 0172-zsh-completion-removing-more-pointless-forks.patch Patch0173: 0173-zsh-completion-make-the-arrays-_sys_active_units-_sy.patch Patch0174: 0174-resolved-fix-crash-when-shutting-down.patch Patch0175: 0175-resolved-allow-DnsAnswer-objects-with-no-space-for-R.patch -Patch0176: 0176-journalctl-Improve-boot-ID-lookup.patch -Patch0177: 0177-test-hashmap-fix-an-assert.patch -Patch0178: 0178-units-make-sure-systemd-nspawn-.slice-instances-are-.patch +Patch0176: 0176-id128-add-new-sd_id128_is_null-call.patch +Patch0177: 0177-journalctl-Improve-boot-ID-lookup.patch +Patch0178: 0178-test-hashmap-fix-an-assert.patch +Patch0179: 0179-units-make-sure-systemd-nspawn-.slice-instances-are-.patch # kernel-install patch for grubby, drop if grubby is obsolete @@ -907,6 +908,7 @@ getent passwd systemd-journal-upload >/dev/null 2>&1 || useradd -r -l -g systemd %{_prefix}/lib/sysctl.d/50-coredump.conf %{_prefix}/lib/sysusers.d/basic.conf %{_prefix}/lib/sysusers.d/systemd.conf +%{pkgdir}/system-preset/90-systemd.preset %{pkgdir}/catalog/systemd.catalog %{_prefix}/lib/kernel/install.d/50-depmod.install %{_prefix}/lib/kernel/install.d/90-loaderentry.install