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] 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; }