From 38df8d3f521c8d76c507c092f4a8e4bb84f9f48a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 5 Apr 2019 13:46:33 +0200 Subject: [PATCH 1/8] sd-id128: expose ID128_UUID_FORMAT_STR It is generally useful, and can be made public in the same manner that SD_ID128_FORMAT_STR is. --- man/rules/meson.build | 1 + man/sd-id128.xml | 6 ++++++ src/libsystemd/sd-id128/id128-util.h | 3 --- src/systemd/sd-id128.h | 3 +++ src/test/test-id128.c | 2 +- 5 files changed, 11 insertions(+), 4 deletions(-) diff --git a/man/rules/meson.build b/man/rules/meson.build index d949900ddc..6f9f4c4443 100644 --- a/man/rules/meson.build +++ b/man/rules/meson.build @@ -101,6 +101,7 @@ manpages = [ 'SD_ID128_MAKE', 'SD_ID128_MAKE_STR', 'SD_ID128_NULL', + 'SD_ID128_UUID_FORMAT_STR', 'sd_id128_equal', 'sd_id128_is_null', 'sd_id128_t'], diff --git a/man/sd-id128.xml b/man/sd-id128.xml index 74d838df2e..22d5e0e3ed 100644 --- a/man/sd-id128.xml +++ b/man/sd-id128.xml @@ -24,6 +24,7 @@ SD_ID128_NULL SD_ID128_CONST_STR SD_ID128_FORMAT_STR + SD_ID128_UUID_FORMAT_STR SD_ID128_FORMAT_VAL sd_id128_equal sd_id128_is_null @@ -119,6 +120,11 @@ int main(int argc, char **argv) { return 0; } + SD_ID128_UUID_FORMAT_STR() is similar to + SD_ID128_FORMAT_STR() but includes separating hyphens to conform to the + "canonical representation". + + Use sd_id128_equal() to compare two 128-bit IDs: int main(int argc, char *argv[]) { diff --git a/src/libsystemd/sd-id128/id128-util.h b/src/libsystemd/sd-id128/id128-util.h index 65f14ab252..82a69a77f3 100644 --- a/src/libsystemd/sd-id128/id128-util.h +++ b/src/libsystemd/sd-id128/id128-util.h @@ -10,9 +10,6 @@ char *id128_to_uuid_string(sd_id128_t id, char s[37]); -/* Like SD_ID128_FORMAT_STR, but formats as UUID, not in plain format */ -#define ID128_UUID_FORMAT_STR "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x" - bool id128_is_valid(const char *s) _pure_; typedef enum Id128Format { diff --git a/src/systemd/sd-id128.h b/src/systemd/sd-id128.h index bdf88ed53f..c5fbe0a4f1 100644 --- a/src/systemd/sd-id128.h +++ b/src/systemd/sd-id128.h @@ -63,6 +63,9 @@ int sd_id128_get_boot_app_specific(sd_id128_t app_id, sd_id128_t *ret); #define SD_ID128_FORMAT_STR "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" #define SD_ID128_FORMAT_VAL(x) (x).bytes[0], (x).bytes[1], (x).bytes[2], (x).bytes[3], (x).bytes[4], (x).bytes[5], (x).bytes[6], (x).bytes[7], (x).bytes[8], (x).bytes[9], (x).bytes[10], (x).bytes[11], (x).bytes[12], (x).bytes[13], (x).bytes[14], (x).bytes[15] +/* Like SD_ID128_FORMAT_STR, but formats as UUID, not in plain format */ +#define SD_ID128_UUID_FORMAT_STR "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x" + #define SD_ID128_CONST_STR(x) \ ((const char[SD_ID128_STRING_MAX]) { \ ((x).bytes[0] >> 4) >= 10 ? 'a' + ((x).bytes[0] >> 4) - 10 : '0' + ((x).bytes[0] >> 4), \ diff --git a/src/test/test-id128.c b/src/test/test-id128.c index 8840788310..eea0765b7a 100644 --- a/src/test/test-id128.c +++ b/src/test/test-id128.c @@ -52,7 +52,7 @@ int main(int argc, char *argv[]) { assert_se(streq(q, UUID_WALDI)); b = mfree(b); - assert_se(asprintf(&b, ID128_UUID_FORMAT_STR, SD_ID128_FORMAT_VAL(ID128_WALDI)) == 36); + assert_se(asprintf(&b, SD_ID128_UUID_FORMAT_STR, SD_ID128_FORMAT_VAL(ID128_WALDI)) == 36); printf("waldi4: %s\n", b); assert_se(streq(q, b)); From bd44566c4d504237b25202a1104f67032c826f2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 5 Apr 2019 12:13:44 +0200 Subject: [PATCH 2/8] tree-wide: use SD_ID128_UUID_FORMAT_STR as appropriate --- src/boot/bootctl.c | 10 ++++++---- src/shared/efivars.c | 2 +- src/shared/id128-print.c | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c index a7de3800fc..0595f873f0 100644 --- a/src/boot/bootctl.c +++ b/src/boot/bootctl.c @@ -220,7 +220,7 @@ static int status_binaries(const char *esp_path, sd_id128_t partition) { printf(" ESP: %s", esp_path); if (!sd_id128_is_null(partition)) - printf(" (/dev/disk/by-partuuid/%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x)", SD_ID128_FORMAT_VAL(partition)); + printf(" (/dev/disk/by-partuuid/" SD_ID128_UUID_FORMAT_STR ")", SD_ID128_FORMAT_VAL(partition)); printf("\n"); r = enumerate_binaries(esp_path, "EFI/systemd", NULL); @@ -262,7 +262,8 @@ static int print_efi_option(uint16_t id, bool in_order) { printf(" Title: %s%s%s\n", ansi_highlight(), strna(title), ansi_normal()); printf(" ID: 0x%04X\n", id); printf(" Status: %sactive%s\n", active ? "" : "in", in_order ? ", boot-order" : ""); - printf(" Partition: /dev/disk/by-partuuid/%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", SD_ID128_FORMAT_VAL(partition)); + printf(" Partition: /dev/disk/by-partuuid/" SD_ID128_UUID_FORMAT_STR "\n", + SD_ID128_FORMAT_VAL(partition)); printf(" File: %s%s\n", special_glyph(SPECIAL_GLYPH_TREE_RIGHT), path); printf("\n"); @@ -380,7 +381,8 @@ static int status_entries( printf("Boot Loader Entries:\n" " $BOOT: %s", dollar_boot_path); if (!sd_id128_is_null(dollar_boot_partition_uuid)) - printf(" (/dev/disk/by-partuuid/%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x)", SD_ID128_FORMAT_VAL(dollar_boot_partition_uuid)); + printf(" (/dev/disk/by-partuuid/" SD_ID128_UUID_FORMAT_STR ")", + SD_ID128_FORMAT_VAL(dollar_boot_partition_uuid)); printf("\n\n"); r = boot_entries_load_config(esp_path, xbootldr_path, &config); @@ -1150,7 +1152,7 @@ static int verb_status(int argc, char *argv[], void *userdata) { if (stub) printf(" Stub: %s\n", stub); if (!sd_id128_is_null(loader_part_uuid)) - printf(" ESP: /dev/disk/by-partuuid/%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", + printf(" ESP: /dev/disk/by-partuuid/" SD_ID128_UUID_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(loader_part_uuid)); else printf(" ESP: n/a\n"); diff --git a/src/shared/efivars.c b/src/shared/efivars.c index 4f32163bba..875b8439e1 100644 --- a/src/shared/efivars.c +++ b/src/shared/efivars.c @@ -772,7 +772,7 @@ int efi_loader_get_device_part_uuid(sd_id128_t *u) { if (r < 0) return r; - if (sscanf(p, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + if (sscanf(p, SD_ID128_UUID_FORMAT_STR, &parsed[0], &parsed[1], &parsed[2], &parsed[3], &parsed[4], &parsed[5], &parsed[6], &parsed[7], &parsed[8], &parsed[9], &parsed[10], &parsed[11], diff --git a/src/shared/id128-print.c b/src/shared/id128-print.c index 1b20b8f644..febe3635ba 100644 --- a/src/shared/id128-print.c +++ b/src/shared/id128-print.c @@ -33,7 +33,7 @@ int id128_pretty_print(sd_id128_t id, bool pretty) { printf("As string:\n" "%s" SD_ID128_FORMAT_STR "%s\n\n" "As UUID:\n" - "%s%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x%s\n\n" + "%s" SD_ID128_UUID_FORMAT_STR "%s\n\n" "As %s macro:\n" "%s#define MESSAGE_XYZ SD_ID128_MAKE(", on, SD_ID128_FORMAT_VAL(id), off, From 74b3e52b9934bfaacf445958764180a02a1abb78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 4 Apr 2019 22:07:17 +0200 Subject: [PATCH 3/8] efivars: add helper to format efivarfs path --- src/shared/efivars.c | 21 +++++++++++++++------ src/shared/efivars.h | 1 + 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/shared/efivars.c b/src/shared/efivars.c index 875b8439e1..fc884dedf0 100644 --- a/src/shared/efivars.c +++ b/src/shared/efivars.c @@ -193,6 +193,17 @@ int efi_set_reboot_to_firmware(bool value) { return 0; } +char* efi_variable_path(sd_id128_t vendor, const char *name) { + char *p; + + if (asprintf(&p, + "/sys/firmware/efi/efivars/%s-" SD_ID128_UUID_FORMAT_STR, + name, SD_ID128_FORMAT_VAL(vendor)) < 0) + return NULL; + + return p; +} + int efi_get_variable( sd_id128_t vendor, const char *name, @@ -211,9 +222,8 @@ int efi_get_variable( assert(value); assert(size); - if (asprintf(&p, - "/sys/firmware/efi/efivars/%s-%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", - name, SD_ID128_FORMAT_VAL(vendor)) < 0) + p = efi_variable_path(vendor, name); + if (!p) return -ENOMEM; fd = open(p, O_RDONLY|O_NOCTTY|O_CLOEXEC); @@ -293,9 +303,8 @@ int efi_set_variable( assert(name); assert(value || size == 0); - if (asprintf(&p, - "/sys/firmware/efi/efivars/%s-%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", - name, SD_ID128_FORMAT_VAL(vendor)) < 0) + p = efi_variable_path(vendor, name); + if (!p) return -ENOMEM; /* Newer efivarfs protects variables that are not in a whitelist with FS_IMMUTABLE_FL by default, to protect diff --git a/src/shared/efivars.h b/src/shared/efivars.h index d8f18aae90..49d1b338fb 100644 --- a/src/shared/efivars.h +++ b/src/shared/efivars.h @@ -33,6 +33,7 @@ int efi_reboot_to_firmware_supported(void); int efi_get_reboot_to_firmware(void); int efi_set_reboot_to_firmware(bool value); +char* efi_variable_path(sd_id128_t vendor, const char *name); int efi_get_variable(sd_id128_t vendor, const char *name, uint32_t *attribute, void **value, size_t *size); int efi_get_variable_string(sd_id128_t vendor, const char *name, char **p); int efi_set_variable(sd_id128_t vendor, const char *name, const void *value, size_t size); From ce4c4f810876b2d6e50041c8bbe089e8a9e2576e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 4 Apr 2019 22:20:19 +0200 Subject: [PATCH 4/8] bootctl: replace "type" with "source" in output I think this is more useful (because it's easy to stick the path into an editor command when one wants to change the options or inspect the files), and more self-explanatory. Example output: title: Fedora 30 (Workstation Edition) (4.20.16-200.fc29.x86_64) id: 08a5690a2eed47cf92ac0a5d2e3cf6b0-4.20.16-200.fc29.x86_64 source: /boot/efi/loader/entries/08a5690a2eed47cf92ac0a5d2e3cf6b0-4.20.16-200.fc29.x86_64.conf version: 4.20.16-200.fc29.x86_64 ... title: Fedora 30 (Workstation Edition) id: fedora-30 source: /boot/efi/EFI/Linux/linux-5.0.5-300.fc30.x86_64-08a5690a2eed47cf92ac0a5d2e3cf6b0.efi linux: EFI/Linux/linux-5.0.5-300.fc30.x86_64-08a5690a2eed47cf92ac0a5d2e3cf6b0.efi ... title: Reboot Into Firmware Interface id: auto-reboot-to-firmware-setup source: /sys/firmware/efi/efivars/LoaderEntries-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f --- TODO | 1 - src/boot/bootctl.c | 14 +++++--------- src/shared/bootspec.c | 7 ++++++- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/TODO b/TODO index 663e4fedd8..f9e86677ab 100644 --- a/TODO +++ b/TODO @@ -688,7 +688,6 @@ Features: * bootctl - verify that the files boot entries point to exist - recognize the case when not booted on EFI - - specify paths for boot entries * maybe do not install getty@tty1.service symlink in /etc but in /usr? diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c index 0595f873f0..3257574100 100644 --- a/src/boot/bootctl.c +++ b/src/boot/bootctl.c @@ -313,18 +313,14 @@ static int status_variables(void) { static int boot_entry_show(const BootEntry *e, bool show_as_default) { assert(e); - printf(" title: %s%s%s%s%s%s\n" - " type: %s\n", - ansi_highlight(), - boot_entry_title(e), - ansi_normal(), - ansi_highlight_green(), - show_as_default ? " (default)" : "", - ansi_normal(), - boot_entry_type_to_string(e->type)); + printf(" title: %s%s%s" "%s%s%s\n", + ansi_highlight(), boot_entry_title(e), ansi_normal(), + ansi_highlight_green(), show_as_default ? " (default)" : "", ansi_normal()); if (e->id) printf(" id: %s\n", e->id); + if (e->path) + printf(" source: %s\n", e->path); if (e->version) printf(" version: %s\n", e->version); if (e->machine_id) diff --git a/src/shared/bootspec.c b/src/shared/bootspec.c index 9a0dc29153..b088b04da0 100644 --- a/src/shared/bootspec.c +++ b/src/shared/bootspec.c @@ -755,7 +755,7 @@ int boot_entries_augment_from_loader(BootConfig *config, bool only_auto) { n_allocated = config->n_entries; STRV_FOREACH(i, found_by_loader) { - _cleanup_free_ char *c = NULL, *t = NULL; + _cleanup_free_ char *c = NULL, *t = NULL, *p = NULL; char **a, **b; if (boot_config_has_entry(config, *i)) @@ -776,6 +776,10 @@ int boot_entries_augment_from_loader(BootConfig *config, bool only_auto) { break; } + p = efi_variable_path(EFI_VENDOR_LOADER, "LoaderEntries"); + if (!p) + return log_oom(); + if (!GREEDY_REALLOC0(config->entries, n_allocated, config->n_entries + 1)) return log_oom(); @@ -783,6 +787,7 @@ int boot_entries_augment_from_loader(BootConfig *config, bool only_auto) { .type = BOOT_ENTRY_LOADER, .id = TAKE_PTR(c), .title = TAKE_PTR(t), + .path = TAKE_PTR(p), }; } From 7f42be65b94d284a604517b561ffa2e9a95707bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 4 Apr 2019 22:23:26 +0200 Subject: [PATCH 5/8] bootspec: remove now-unused boot_entry_type_table --- src/shared/bootspec.c | 8 -------- src/shared/bootspec.h | 3 --- 2 files changed, 11 deletions(-) diff --git a/src/shared/bootspec.c b/src/shared/bootspec.c index b088b04da0..3bd14d7372 100644 --- a/src/shared/bootspec.c +++ b/src/shared/bootspec.c @@ -1423,11 +1423,3 @@ found: return 0; } - -static const char* const boot_entry_type_table[_BOOT_ENTRY_MAX] = { - [BOOT_ENTRY_CONF] = "conf", - [BOOT_ENTRY_UNIFIED] = "unified", - [BOOT_ENTRY_LOADER] = "loader", -}; - -DEFINE_STRING_TABLE_LOOKUP(boot_entry_type, BootEntryType); diff --git a/src/shared/bootspec.h b/src/shared/bootspec.h index 45e1fc37c6..b35eaf1110 100644 --- a/src/shared/bootspec.h +++ b/src/shared/bootspec.h @@ -79,6 +79,3 @@ static inline const char* boot_entry_title(const BootEntry *entry) { int find_esp_and_warn(const char *path, bool unprivileged_mode, char **ret_path, uint32_t *ret_part, uint64_t *ret_pstart, uint64_t *ret_psize, sd_id128_t *ret_uuid); int find_xbootldr_and_warn(const char *path, bool unprivileged_mode, char **ret_path,sd_id128_t *ret_uuid); - -const char* boot_entry_type_to_string(BootEntryType t) _const_; -BootEntryType boot_entry_type_from_string(const char *s) _pure_; From 44e6a5ef8253d18d17a98d0fc7242d558559bb40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 4 Apr 2019 22:52:53 +0200 Subject: [PATCH 6/8] bootctl: check if files specified by boot entry exist, and warn if not Example output: title: Fedora 30 (Workstation Edition) (5.0.5-300.fc30.x86_64) id: 08a5690a2eed47cf92ac0a5d2e3cf6b0-5.0.5-bad-300.fc30.x86_64 source: /boot/efi/loader/entries/08a5690a2eed47cf92ac0a5d2e3cf6b0-5.0.5-bad-300.fc30.x86_64.conf version: 5.0.5-300.fc30.x86_64 machine-id: 08a5690a2eed47cf92ac0a5d2e3cf6b0 linux: /08a5690a2eed47cf92ac0a/5.0.5-300.fc30.x86_64/linux (No such file or directory) initrd: /08a5690a2eed47cf92ac0a/5.0.5-300.fc30.x86_64/initrd (No such file or directory) /08a5690a2eed47cf92ac0a/5.0.5-300.fc30.x86_64/initrd2 (No such file or directory) options: ... --- TODO | 1 - src/boot/bootctl.c | 41 +++++++++++++++++++++++++++++++---------- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/TODO b/TODO index f9e86677ab..ae9f066ac6 100644 --- a/TODO +++ b/TODO @@ -686,7 +686,6 @@ Features: - honor timezone efi variables for default timezone selection (if there are any?) - change bootctl to be backed by systemd-bootd to control temporary and persistent default boot goal plus efi variables * bootctl - - verify that the files boot entries point to exist - recognize the case when not booted on EFI * maybe do not install getty@tty1.service symlink in /etc but in /usr? diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c index 3257574100..1cbba94352 100644 --- a/src/boot/bootctl.c +++ b/src/boot/bootctl.c @@ -310,6 +310,30 @@ static int status_variables(void) { return 0; } +static int boot_entry_file_check(const char *root, const char *p) { + _cleanup_free_ char *path; + + path = path_join(root, p); + if (!path) + return log_oom(); + + if (access(path, F_OK) < 0) + return -errno; + + return 0; +} + +static void boot_entry_file_list(const char *field, const char *root, const char *p) { + int status = boot_entry_file_check(root, p); + + printf("%13s%s", strempty(field), field ? ":" : " "); + if (status < 0) { + errno = -status; + printf("%s%s%s (%m)\n", ansi_highlight_red(), p, ansi_normal()); + } else + printf("%s\n", p); +} + static int boot_entry_show(const BootEntry *e, bool show_as_default) { assert(e); @@ -328,16 +352,13 @@ static int boot_entry_show(const BootEntry *e, bool show_as_default) { if (e->architecture) printf(" architecture: %s\n", e->architecture); if (e->kernel) - printf(" linux: %s\n", e->kernel); - if (!strv_isempty(e->initrd)) { - _cleanup_free_ char *t; + boot_entry_file_list("linux", e->root, e->kernel); - t = strv_join(e->initrd, " "); - if (!t) - return log_oom(); - - printf(" initrd: %s\n", t); - } + char **s; + STRV_FOREACH(s, e->initrd) + boot_entry_file_list(s == e->initrd ? "initrd" : NULL, + e->root, + *s); if (!strv_isempty(e->options)) { _cleanup_free_ char *t; @@ -348,7 +369,7 @@ static int boot_entry_show(const BootEntry *e, bool show_as_default) { printf(" options: %s\n", t); } if (e->device_tree) - printf(" devicetree: %s\n", e->device_tree); + boot_entry_file_list("devicetree", e->root, e->device_tree); return 0; } From d3eb60722da215da3f0fe09cfdb65ec1cdc1113e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 4 Apr 2019 23:06:22 +0200 Subject: [PATCH 7/8] bootctl: emit extra warning if the default boot entry is broken Let's make it more obvious for the user if something is badly borked. It does the job, but I'm not too happy with this. --- src/boot/bootctl.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c index 1cbba94352..c26250c60a 100644 --- a/src/boot/bootctl.c +++ b/src/boot/bootctl.c @@ -323,7 +323,7 @@ static int boot_entry_file_check(const char *root, const char *p) { return 0; } -static void boot_entry_file_list(const char *field, const char *root, const char *p) { +static void boot_entry_file_list(const char *field, const char *root, const char *p, int *ret_status) { int status = boot_entry_file_check(root, p); printf("%13s%s", strempty(field), field ? ":" : " "); @@ -332,9 +332,17 @@ static void boot_entry_file_list(const char *field, const char *root, const char printf("%s%s%s (%m)\n", ansi_highlight_red(), p, ansi_normal()); } else printf("%s\n", p); + + if (*ret_status == 0 && status < 0) + *ret_status = status; } static int boot_entry_show(const BootEntry *e, bool show_as_default) { + int status = 0; + + /* Returns 0 on success, negative on processing error, and positive if something is wrong with the + boot entry itself. */ + assert(e); printf(" title: %s%s%s" "%s%s%s\n", @@ -352,13 +360,14 @@ static int boot_entry_show(const BootEntry *e, bool show_as_default) { if (e->architecture) printf(" architecture: %s\n", e->architecture); if (e->kernel) - boot_entry_file_list("linux", e->root, e->kernel); + boot_entry_file_list("linux", e->root, e->kernel, &status); char **s; STRV_FOREACH(s, e->initrd) boot_entry_file_list(s == e->initrd ? "initrd" : NULL, e->root, - *s); + *s, + &status); if (!strv_isempty(e->options)) { _cleanup_free_ char *t; @@ -369,9 +378,9 @@ static int boot_entry_show(const BootEntry *e, bool show_as_default) { printf(" options: %s\n", t); } if (e->device_tree) - boot_entry_file_list("devicetree", e->root, e->device_tree); + boot_entry_file_list("devicetree", e->root, e->device_tree, &status); - return 0; + return -status; } static int status_entries( @@ -411,7 +420,11 @@ static int status_entries( else { printf("Default Boot Loader Entry:\n"); - boot_entry_show(config.entries + config.default_entry, false); + r = boot_entry_show(config.entries + config.default_entry, false); + if (r > 0) + /* < 0 is already logged by the function itself, let's just emit an extra warning if + the default entry is broken */ + printf("\nWARNING: default boot entry is broken\n"); } return 0; From cce9457c70b6bb94213dfba0010b3ae25950b845 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 5 Apr 2019 14:01:35 +0200 Subject: [PATCH 8/8] bootctl: urlify .conf files Just because we can ;) --- src/boot/bootctl.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c index c26250c60a..9df181a10c 100644 --- a/src/boot/bootctl.c +++ b/src/boot/bootctl.c @@ -351,8 +351,16 @@ static int boot_entry_show(const BootEntry *e, bool show_as_default) { if (e->id) printf(" id: %s\n", e->id); - if (e->path) - printf(" source: %s\n", e->path); + if (e->path) { + _cleanup_free_ char *link = NULL; + + /* Let's urlify the link to make it easy to view in an editor, but only if it is a text + * file. Unified images are binary ELFs, and EFI variables are not pure text either. */ + if (e->type == BOOT_ENTRY_CONF) + (void) terminal_urlify_path(e->path, NULL, &link); + + printf(" source: %s\n", link ?: e->path); + } if (e->version) printf(" version: %s\n", e->version); if (e->machine_id)