]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-boot: add auto-reboot and auto-poweroff entries 29440/head
authorEmil Velikov <emil.velikov@collabora.com>
Wed, 4 Oct 2023 10:51:47 +0000 (11:51 +0100)
committerEmil Velikov <emil.l.velikov@gmail.com>
Fri, 6 Oct 2023 15:21:23 +0000 (16:21 +0100)
Currently only an auto-reboot-to-firmware entry is available. For other
features - like reboot and power off - one needs to press the uppercase
B and O respectively.

Embedded devices may be missing a full fledged keyboard, so allow for
sd-boot to generate those entries.

v2:
 - add to the config parser/man/bootctl/sd-boot info screen
 - keep them off by default
 - add the (O)ff and re(B)oot help text if boot entries are not shown
 - drop irrelevant get_os_indications_supported() comment
 - s/ShutDown/Shutdown/

v3:
 - cast shutdown_system() reboot_system() to void

v4:
 - shutdown -> poweroff
 - add trailing ",ignoring" in parser message
 - drop explicit default state assignment to "false"

Signed-off-by: Emil Velikov <emil.velikov@collabora.com>
man/loader.conf.xml
src/boot/efi/boot.c
src/shared/bootspec.c

index c7794cd195fb74cd410f9644589c330e9bad1dfd..748276c9cfdcccaf1ce4f064a6ed334c2df88f4e 100644 (file)
                 <entry>auto-osx</entry>
                 <entry>macOS</entry>
               </row>
+              <row>
+                <entry>auto-poweroff</entry>
+                <entry>Power Off The System</entry>
+              </row>
+              <row>
+                <entry>auto-reboot</entry>
+                <entry>Reboot The System</entry>
+              </row>
               <row>
                 <entry>auto-reboot-to-firmware-setup</entry>
                 <entry>Reboot Into Firmware Interface</entry>
index 0f61c302a382cf4682ee262eaab8bc44af36ed75..de801ceb37d2d0eaa72e1b3613d44b80b8e8f6de 100644 (file)
@@ -86,6 +86,8 @@ typedef struct {
         bool editor;
         bool auto_entries;
         bool auto_firmware;
+        bool auto_poweroff;
+        bool auto_reboot;
         bool reboot_for_bitlocker;
         secure_boot_enroll secure_boot_enroll;
         bool force_menu;
@@ -512,6 +514,8 @@ static void print_status(Config *config, char16_t *loaded_image_path) {
         printf("                editor: %ls\n", yes_no(config->editor));
         printf("          auto-entries: %ls\n", yes_no(config->auto_entries));
         printf("         auto-firmware: %ls\n", yes_no(config->auto_firmware));
+        printf("         auto-poweroff: %ls\n", yes_no(config->auto_poweroff));
+        printf("           auto-reboot: %ls\n", yes_no(config->auto_reboot));
         printf("                  beep: %ls\n", yes_no(config->beep));
         printf("  reboot-for-bitlocker: %ls\n", yes_no(config->reboot_for_bitlocker));
 
@@ -618,6 +622,16 @@ static EFI_STATUS reboot_into_firmware(void) {
         assert_not_reached();
 }
 
+static EFI_STATUS poweroff_system(void) {
+        RT->ResetSystem(EfiResetShutdown, EFI_SUCCESS, 0, NULL);
+        assert_not_reached();
+}
+
+static EFI_STATUS reboot_system(void) {
+        RT->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL);
+        assert_not_reached();
+}
+
 static bool menu_run(
                 Config *config,
                 ConfigEntry **chosen_entry,
@@ -886,7 +900,9 @@ static bool menu_run(
                 case KEYPRESS(0, 0, 'H'):
                 case KEYPRESS(0, 0, '?'):
                         /* This must stay below 80 characters! Q/v/Ctrl+l/f deliberately not advertised. */
-                        status = xstrdup16(u"(d)efault (t/T)imeout (e)dit (r/R)esolution (p)rint (O)ff re(B)oot (h)elp");
+                        status = xasprintf("(d)efault (t/T)imeout (e)dit (r/R)esolution (p)rint %s%s(h)elp",
+                                           config->auto_poweroff ? "" : "(O)ff ",
+                                           config->auto_reboot ? "" : "re(B)oot ");
                         break;
 
                 case KEYPRESS(0, 0, 'Q'):
@@ -1019,11 +1035,11 @@ static bool menu_run(
                         break;
 
                 case KEYPRESS(0, 0, 'O'): /* Only uppercase, so that it can't be hit so easily fat-fingered, but still works safely over serial */
-                        RT->ResetSystem(EfiResetShutdown, EFI_SUCCESS, 0, NULL);
+                        (void) poweroff_system();
                         break;
 
                 case KEYPRESS(0, 0, 'B'): /* ditto */
-                        RT->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL);
+                        (void) reboot_system();
                         break;
 
                 default:
@@ -1258,6 +1274,20 @@ static void config_defaults_load_from_file(Config *config, char *content) {
                         continue;
                 }
 
+                if (streq8(key, "auto-poweroff")) {
+                        err = parse_boolean(value, &config->auto_poweroff);
+                        if (err != EFI_SUCCESS)
+                                log_error("Error parsing 'auto-poweroff' config option, ignoring: %s", value);
+                        continue;
+                }
+
+                if (streq8(key, "auto-reboot")) {
+                        err = parse_boolean(value, &config->auto_reboot);
+                        if (err != EFI_SUCCESS)
+                                log_error("Error parsing 'auto-reboot' config option, ignoring: %s", value);
+                        continue;
+                }
+
                 if (streq8(key, "beep")) {
                         err = parse_boolean(value, &config->beep);
                         if (err != EFI_SUCCESS)
@@ -2648,6 +2678,30 @@ static void config_load_all_entries(
                 config_add_entry(config, entry);
         }
 
+        if (config->auto_poweroff) {
+                ConfigEntry *entry = xnew(ConfigEntry, 1);
+                *entry = (ConfigEntry) {
+                        .id = xstrdup16(u"auto-poweroff"),
+                        .title = xstrdup16(u"Power Off The System"),
+                        .call = poweroff_system,
+                        .tries_done = -1,
+                        .tries_left = -1,
+                };
+                config_add_entry(config, entry);
+        }
+
+        if (config->auto_reboot) {
+                ConfigEntry *entry = xnew(ConfigEntry, 1);
+                *entry = (ConfigEntry) {
+                        .id = xstrdup16(u"auto-reboot"),
+                        .title = xstrdup16(u"Reboot The System"),
+                        .call = reboot_system,
+                        .tries_done = -1,
+                        .tries_left = -1,
+                };
+                config_add_entry(config, entry);
+        }
+
         /* find if secure boot signing keys exist and autoload them if necessary
         otherwise creates menu entries so that the user can load them manually
         if the secure-boot-enroll variable is set to no (the default), we do not
index 42d5fec754c05576fc7b96d3cc5acb90ff3d7243..f347ccdd8a86b691b44152af6691b9b0dc82dd1f 100644 (file)
@@ -1145,6 +1145,8 @@ int boot_config_augment_from_loader(
                 "auto-windows",                  "Windows Boot Manager",
                 "auto-efi-shell",                "EFI Shell",
                 "auto-efi-default",              "EFI Default Loader",
+                "auto-poweroff",                 "Power Off The System",
+                "auto-reboot",                   "Reboot The System",
                 "auto-reboot-to-firmware-setup", "Reboot Into Firmware Interface",
                 NULL,
         };