]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
bootctl: check if files specified by boot entry exist, and warn if not
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 4 Apr 2019 20:52:53 +0000 (22:52 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 5 Apr 2019 11:51:19 +0000 (13:51 +0200)
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
src/boot/bootctl.c

diff --git a/TODO b/TODO
index f9e86677abb57acb8f48bcb69fc7475fada937fb..ae9f066ac6b3152fc3cce6dcdf8dd5ad82b3a53c 100644 (file)
--- 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?
index 32575741008710d4f79dc70baa4a68554d1f1be2..1cbba9435217eae96fa83d01af18ec7c19739837 100644 (file)
@@ -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;
 }