]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
bootctl: make 'random-seed' handle inability to write system token EFI variable grace...
authorLennart Poettering <lennart@poettering.net>
Tue, 19 Nov 2019 15:33:22 +0000 (16:33 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 21 Nov 2019 18:55:17 +0000 (19:55 +0100)
Apparently some firmwares don't allow us to write this token, and refuse
it with EINVAL. We should normally consider that a fatal error, but not
really in the case of "bootctl random-seed" when called from the
systemd-boot-system-token.service since it's called as "best effort"
service after boot on various systems, and hence we shouldn't fail
loudly.

Similar, when we cannot find the ESP don't fail either, since there are
systems (arch install ISOs) that carry a boot loader capable of the
random seed logic but don't mount it after boot.

Fixes: #13603
man/bootctl.xml
src/boot/bootctl.c
units/systemd-boot-system-token.service.in

index fbd6574418114cae9a9dfebea17dcbc9efdb1e7f..c038c4686db696785c315677b8e60d046331c8f8 100644 (file)
         <listitem><para>Do not touch the firmware's boot loader list stored in EFI variables.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>--graceful</option></term>
+        <listitem><para>Ignore failure when the EFI System Partition cannot be found, or when EFI variables
+        cannot be written. Currently only applies to random seed operations.</para></listitem>
+      </varlistentry>
+
       <xi:include href="standard-options.xml" xpointer="no-pager"/>
       <xi:include href="standard-options.xml" xpointer="help"/>
       <xi:include href="standard-options.xml" xpointer="version"/>
index f8845369eca33dcd087bf300df085144b85eda27..a90502b4c36d5be16c783df525188873b08e514c 100644 (file)
@@ -51,6 +51,7 @@ static bool arg_print_esp_path = false;
 static bool arg_print_dollar_boot_path = false;
 static bool arg_touch_variables = true;
 static PagerFlags arg_pager_flags = 0;
+static bool arg_graceful = false;
 
 STATIC_DESTRUCTOR_REGISTER(arg_esp_path, freep);
 STATIC_DESTRUCTOR_REGISTER(arg_xbootldr_path, freep);
@@ -1055,6 +1056,8 @@ static int help(int argc, char *argv[], void *userdata) {
                "  -x --print-boot-path Print path to the $BOOT partition\n"
                "     --no-variables    Don't touch EFI variables\n"
                "     --no-pager        Do not pipe output into a pager\n"
+               "     --graceful        Don't fail when the ESP cannot be found or EFI\n"
+               "                       variables cannot be written\n"
                "\nSee the %s for details.\n"
                , program_invocation_short_name
                , ansi_highlight()
@@ -1071,6 +1074,7 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_VERSION,
                 ARG_NO_VARIABLES,
                 ARG_NO_PAGER,
+                ARG_GRACEFUL,
         };
 
         static const struct option options[] = {
@@ -1084,6 +1088,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "print-boot-path", no_argument,       NULL, 'x'                 },
                 { "no-variables",    no_argument,       NULL, ARG_NO_VARIABLES    },
                 { "no-pager",        no_argument,       NULL, ARG_NO_PAGER        },
+                { "graceful",        no_argument,       NULL, ARG_GRACEFUL        },
                 {}
         };
 
@@ -1136,6 +1141,10 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_pager_flags |= PAGER_DISABLE;
                         break;
 
+                case ARG_GRACEFUL:
+                        arg_graceful = true;
+                        break;
+
                 case '?':
                         return -EINVAL;
 
@@ -1458,11 +1467,18 @@ static int install_random_seed(const char *esp) {
          * state. */
         RUN_WITH_UMASK(0077) {
                 r = efi_set_variable(EFI_VENDOR_LOADER, "LoaderSystemToken", buffer, sz);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to set LoaderSystemToken EFI variable: %m");
+                if (r < 0) {
+                        if (!arg_graceful)
+                                return log_error_errno(r, "Failed to write 'LoaderSystemToken' EFI variable: %m");
+
+                        if (r == -EINVAL)
+                                log_warning_errno(r, "Unable to write 'LoaderSystemToken' EFI variable (firmware problem?), ignoring: %m");
+                        else
+                                log_warning_errno(r, "Unable to write 'LoaderSystemToken' EFI variable, ignoring: %m");
+                } else
+                        log_info("Successfully initialized system token in EFI variable with %zu bytes.", sz);
         }
 
-        log_info("Successfully initialized system token in EFI variable with %zu bytes.", sz);
         return 0;
 }
 
@@ -1704,7 +1720,15 @@ static int verb_set_default(int argc, char *argv[], void *userdata) {
 static int verb_random_seed(int argc, char *argv[], void *userdata) {
         int r;
 
-        r = acquire_esp(false, NULL, NULL, NULL, NULL);
+        r = find_esp_and_warn(arg_esp_path, false, &arg_esp_path, NULL, NULL, NULL, NULL);
+        if (r == -ENOKEY) {
+                /* find_esp_and_warn() doesn't warn about ENOKEY, so let's do that on our own */
+                if (!arg_graceful)
+                        return log_error_errno(r, "Unable to find ESP.");
+
+                log_notice("No ESP found, not initializing random seed.");
+                return 0;
+        }
         if (r < 0)
                 return r;
 
index 5bc29b0cb7b8d9bc5b9805673747c02c63cde09d..e9b742c5c7015b610c8d816e57905659fd4730a4 100644 (file)
@@ -31,4 +31,4 @@ ConditionPathExists=|!/sys/firmware/efi/efivars/LoaderRandomSeed-4a67b082-0a4c-4
 [Service]
 Type=oneshot
 RemainAfterExit=yes
-ExecStart=@bindir@/bootctl random-seed
+ExecStart=@bindir@/bootctl random-seed --graceful