1
0
mirror of https://github.com/systemd/systemd.git synced 2025-03-21 02:50:18 +03:00

boot: add reboot-on-error config option

Enabling this option will cause the system to reboot in case the selected
entry fails to load.
This commit is contained in:
nkraetzschmar 2025-03-11 13:23:14 +01:00 committed by Lennart Poettering
parent d54196a4cd
commit 0bdf94e588
3 changed files with 73 additions and 1 deletions

View File

@ -399,6 +399,36 @@ sbvarsign --attr "${attr}" --key KEK.key --cert KEK.pem --output db.auth db db.e
<xi:include href="version-info.xml" xpointer="v251"/></listitem>
</varlistentry>
<varlistentry>
<term>reboot-on-error</term>
<listitem><para>Controls auto reboot in case the selected entry fails to start.
<variablelist>
<varlistentry>
<term><option>yes</option></term>
<listitem><para>Reboot the system if the selected boot entry failed to start.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>no</option></term>
<listitem><para>Don't reboot - pass control back to EFI firmware.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>auto</option></term>
<listitem>
<para>Perform the reboot if and only if boot counting is enabled for this entry and the tries left counter wasn't already at 0.</para>
<para>This is the default, as it is typically a safe option, that ensures a clean measurement log on each boot attempt, but also does not risk an unbounded reboot loop.</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<xi:include href="version-info.xml" xpointer="v258"/></listitem>
</varlistentry>
</variablelist>
</refsect1>

View File

@ -79,6 +79,12 @@ typedef enum LoaderType {
/* Whether to persistently save the selected entry in an EFI variable, if that's requested. */
#define LOADER_TYPE_SAVE_ENTRY(t) IN_SET(t, LOADER_EFI, LOADER_LINUX, LOADER_UKI, LOADER_UKI_URL, LOADER_TYPE2_UKI)
typedef enum {
REBOOT_NO,
REBOOT_YES,
REBOOT_AUTO,
} RebootOnError;
typedef struct BootEntry {
char16_t *id; /* The unique identifier for this entry (typically the filename of the file defining the entry, possibly suffixed with a profile id) */
char16_t *id_without_profile; /* same, but without any profile id suffixed */
@ -123,6 +129,7 @@ typedef struct {
bool auto_poweroff;
bool auto_reboot;
bool reboot_for_bitlocker;
RebootOnError reboot_on_error;
secure_boot_enroll secure_boot_enroll;
bool force_menu;
bool use_saved_entry;
@ -317,6 +324,20 @@ static void print_status(Config *config, char16_t *loaded_image_path) {
printf(" beep: %ls\n", yes_no(config->beep));
printf(" reboot-for-bitlocker: %ls\n", yes_no(config->reboot_for_bitlocker));
switch (config->reboot_on_error) {
case REBOOT_NO:
printf(" reboot-on-error: no\n");
break;
case REBOOT_YES:
printf(" reboot-on-error: yes\n");
break;
case REBOOT_AUTO:
printf(" reboot-on-error: auto\n");
break;
default:
assert_not_reached();
}
switch (config->secure_boot_enroll) {
case ENROLL_OFF:
printf(" secure-boot-enroll: off\n");
@ -1055,6 +1076,17 @@ static void config_defaults_load_from_file(Config *config, char *content) {
log_error("Error parsing 'reboot-for-bitlocker' config option, ignoring: %s",
value);
} else if (streq8(key, "reboot-on-error")) {
if (streq8(value, "auto"))
config->reboot_on_error = REBOOT_AUTO;
else {
bool reboot_yes_no;
if (!parse_boolean(value, &reboot_yes_no))
log_error("Error parsing 'reboot-on-error' config option, ignoring: %s", value);
config->reboot_on_error = reboot_yes_no ? REBOOT_YES : REBOOT_NO;
}
} else if (streq8(key, "secure-boot-enroll")) {
if (streq8(value, "manual"))
config->secure_boot_enroll = ENROLL_MANUAL;
@ -1421,6 +1453,7 @@ static void config_load_defaults(Config *config, EFI_FILE *root_dir) {
.editor = true,
.auto_entries = true,
.auto_firmware = true,
.reboot_on_error = REBOOT_AUTO,
.secure_boot_enroll = ENROLL_IF_SAFE,
.idx_default_efivar = IDX_INVALID,
.console_mode = CONSOLE_MODE_KEEP,
@ -2998,8 +3031,14 @@ static EFI_STATUS run(EFI_HANDLE image) {
(void) process_random_seed(root_dir);
err = ASSERT_PTR(entry->call)(entry, root_dir, image);
if (err != EFI_SUCCESS)
if (err != EFI_SUCCESS) {
if (config.reboot_on_error == REBOOT_YES || (config.reboot_on_error == REBOOT_AUTO && entry->tries_left > 0)) {
printf("Failed to start boot entry. Rebooting in 5s.\n");
BS->Stall(5 * 1000 * 1000);
(void) call_reboot_system(/* entry= */ NULL, /* root_dir= */ NULL, /* parent_image= */ NULL);
}
return err;
}
menu = true;
config.timeout_sec = 0;

View File

@ -578,3 +578,6 @@ file-hierarchy.xml /refsect1[title="Home Directory"]/variablelist/varlistentry[t
systemd-measure.xml /refsect1[title="Options"]/variablelist/varlistentry[term="--linux=PATH"]
systemd-nspawn.xml /refsect1[title="Hotkeys"]/variablelist/varlistentry[term="Ctrl-] Ctrl-] Ctrl-]"]
run0.xml /refsect1[title="Options"]/variablelist/varlistentry[term="--pty"]
loader.conf.xml /refsect1[title="Options"]/variablelist/varlistentry[term="reboot-on-error"]/listitem/para/variablelist/varlistentry[term="yes"]
loader.conf.xml /refsect1[title="Options"]/variablelist/varlistentry[term="reboot-on-error"]/listitem/para/variablelist/varlistentry[term="no"]
loader.conf.xml /refsect1[title="Options"]/variablelist/varlistentry[term="reboot-on-error"]/listitem/para/variablelist/varlistentry[term="auto"]