<varlistentry>
<term><option>set-default</option> <replaceable>ID</replaceable></term>
<term><option>set-oneshot</option> <replaceable>ID</replaceable></term>
+ <term><option>set-sysfail</option> <replaceable>ID</replaceable></term>
<listitem><para>Sets the default boot loader entry. Takes a single boot loader entry ID string or a glob
pattern as argument. The <option>set-oneshot</option> command will set the default entry only for the next boot,
- the <option>set-default</option> will set it persistently for all future boots.</para>
+ the <option>set-default</option> will set it persistently for all future boots. The <option>set-sysfail</option> command
+ will set the boot loader entry to be used in case of a system failure. System failure (SysFail) boot entries can
+ optionally modify the automatic selection order in the event of a failure, such as a boot firmware update failure with
+ the failure status recorded in the EFI system table.</para>
<para><command>bootctl list</command> can be used to list available boot loader entries and their
IDs.</para>
<option>@oneshot</option> or <option>@current</option>, which correspond to the current default boot loader
entry for all future boots, the current default boot loader entry for the next boot, and the currently booted
boot loader entry. These special IDs are resolved to the current values of the EFI variables
- <varname>LoaderEntryDefault</varname>, <varname>LoaderEntryOneShot</varname> and <varname>LoaderEntrySelected</varname>,
- see <ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">Boot Loader Specification</ulink> for details.
+ <varname>LoaderEntryDefault</varname>, <varname>LoaderEntrySysFail</varname>, <varname>LoaderEntryOneShot</varname>
+ and <varname>LoaderEntrySelected</varname>, see <ulink url="https://uapi-group.org/specifications/specs/boot_loader_specification">
+ Boot Loader Specification</ulink> for details.
These special IDs are primarily useful as a quick way to persistently make the currently booted boot loader
entry the default choice, or to upgrade the default boot loader entry for the next boot to the default boot
loader entry for all future boots, but may be used for other operations too.</para>
--- /dev/null
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+ "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
+
+<refentry id="systemd-boot-clear-sysfail.service" conditional='ENABLE_BOOTLOADER'
+ xmlns:xi="http://www.w3.org/2001/XInclude">
+
+ <refentryinfo>
+ <title>systemd-boot-clear-sysfail.service</title>
+ <productname>systemd</productname>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle>systemd-boot-clear-sysfail.service</refentrytitle>
+ <manvolnum>8</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>systemd-boot-clear-sysfail.service</refname>
+ <refpurpose>Clear LoaderEntrySysFail entry </refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <para><filename>systemd-boot-clear-sysfail.service</filename></para>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><filename>systemd-boot-clear-sysfail.service</filename> is a system service that automatically clears the
+ 'LoaderEntrySysFail' boot loader entry if the boot was successful and the 'LoaderSysFailReason' EFI variable,
+ which indicates the reason for the system failure, is not set. </para>
+
+ <para>The <filename>systemd-boot-random-seed.service</filename> unit invokes the <command>bootctl --graceful
+ set-sysfail ""</command> command, which clears the LoaderEntrySysFail entry. The service is conditionalized
+ so that it is run only when a LoaderSysFailReason entry is not set.</para><para>For further details see
+ <citerefentry><refentrytitle>bootctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>, regarding
+ the command this service invokes.</para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+ <para><simplelist type="inline">
+ <member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
+ <member><citerefentry><refentrytitle>bootctl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
+ <member><citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry></member>
+ </simplelist></para>
+ </refsect1>
+
+</refentry>
enable getty@.service
+enable systemd-boot-clear-sysfail.service
enable systemd-boot-update.service
enable systemd-confext.service
enable systemd-homed.service
'secure-boot.c',
'shim.c',
'smbios.c',
+ 'sysfail.c',
'ticks.c',
'url-discovery.c',
'util.c',
EFI_LOADER_VARIABLE_STR("LoaderConfigTimeout"),
EFI_LOADER_VARIABLE_STR("LoaderConfigTimeoutOneShot"),
EFI_LOADER_VARIABLE_STR("LoaderEntryDefault"),
+ EFI_LOADER_VARIABLE_STR("LoaderEntrySysFail"),
EFI_LOADER_VARIABLE_STR("LoaderEntryLastBooted"),
EFI_LOADER_VARIABLE_STR("LoaderEntryOneShot"),
EFI_LOADER_VARIABLE_STR("LoaderSystemToken")) {
if (r < 0)
return log_error_errno(r, "Failed to get EFI variable 'LoaderEntryDefault': %m");
+ } else if (streq(arg1, "@sysfail")) {
+ r = efi_get_variable(EFI_LOADER_VARIABLE_STR("LoaderEntrySysFail"), NULL, (void *) ret_target, ret_target_size);
+ if (r < 0)
+ return log_error_errno(r, "Failed to get EFI variable 'LoaderEntrySysFail': %m");
+
} else if (arg1[0] == '@' && !streq(arg1, "@saved"))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unsupported special entry identifier: %s", arg1);
else {
if (streq(argv[0], "set-default")) {
variable = EFI_LOADER_VARIABLE_STR("LoaderEntryDefault");
arg_parser = parse_loader_entry_target_arg;
+ } else if (streq(argv[0], "set-sysfail")) {
+ variable = EFI_LOADER_VARIABLE_STR("LoaderEntrySysFail");
+ arg_parser = parse_loader_entry_target_arg;
} else if (streq(argv[0], "set-oneshot")) {
variable = EFI_LOADER_VARIABLE_STR("LoaderEntryOneShot");
arg_parser = parse_loader_entry_target_arg;
{ EFI_STUB_FEATURE_MULTI_PROFILE_UKI, "Stub understands profile selector" },
};
_cleanup_free_ char *fw_type = NULL, *fw_info = NULL, *loader = NULL, *loader_path = NULL, *stub = NULL, *stub_path = NULL,
- *current_entry = NULL, *oneshot_entry = NULL, *default_entry = NULL;
+ *current_entry = NULL, *oneshot_entry = NULL, *default_entry = NULL, *sysfail_entry = NULL, *sysfail_reason = NULL;
uint64_t loader_features = 0, stub_features = 0;
int have;
(void) efi_get_variable_string_and_warn(EFI_LOADER_VARIABLE_STR("LoaderEntrySelected"), ¤t_entry);
(void) efi_get_variable_string_and_warn(EFI_LOADER_VARIABLE_STR("LoaderEntryOneShot"), &oneshot_entry);
(void) efi_get_variable_string_and_warn(EFI_LOADER_VARIABLE_STR("LoaderEntryDefault"), &default_entry);
+ (void) efi_get_variable_string_and_warn(EFI_LOADER_VARIABLE_STR("LoaderEntrySysFail"), &sysfail_entry);
+ (void) efi_get_variable_string_and_warn(EFI_LOADER_VARIABLE_STR("LoaderSysFailReason"), &sysfail_reason);
SecureBootMode secure = efi_get_secure_boot_mode();
printf("%sSystem:%s\n", ansi_underline(), ansi_normal());
if (loader) {
printf("%sCurrent Boot Loader:%s\n", ansi_underline(), ansi_normal());
- printf(" Product: %s%s%s\n", ansi_highlight(), loader, ansi_normal());
+ printf(" Product: %s%s%s\n", ansi_highlight(), loader, ansi_normal());
for (size_t i = 0; i < ELEMENTSOF(loader_flags); i++)
print_yes_no_line(i == 0, FLAGS_SET(loader_features, loader_flags[i].flag), loader_flags[i].name);
SD_ID128_FORMAT_VAL(loader_partition_uuid),
SD_ID128_FORMAT_VAL(esp_uuid));
- printf(" Partition: /dev/disk/by-partuuid/" SD_ID128_UUID_FORMAT_STR "\n",
+ printf(" Partition: /dev/disk/by-partuuid/" SD_ID128_UUID_FORMAT_STR "\n",
SD_ID128_FORMAT_VAL(loader_partition_uuid));
} else if (loader_path)
- printf(" Partition: n/a\n");
+ printf(" Partition: n/a\n");
if (loader_path)
- printf(" Loader: %s%s\n", glyph(GLYPH_TREE_RIGHT), strna(loader_path));
+ printf(" Loader: %s%s\n", glyph(GLYPH_TREE_RIGHT), strna(loader_path));
if (loader_url)
- printf(" Net Boot URL: %s\n", loader_url);
+ printf(" Net Boot URL: %s\n", loader_url);
+
+ if (sysfail_entry)
+ printf("SysFail Reason: %s\n", sysfail_reason);
if (current_entry)
- printf("Current Entry: %s\n", current_entry);
+ printf(" Current Entry: %s\n", current_entry);
if (default_entry)
- printf("Default Entry: %s\n", default_entry);
+ printf(" Default Entry: %s\n", default_entry);
if (oneshot_entry && !streq_ptr(oneshot_entry, default_entry))
- printf("OneShot Entry: %s\n", oneshot_entry);
+ printf(" OneShot Entry: %s\n", oneshot_entry);
+ if (sysfail_entry)
+ printf(" SysFail Entry: %s\n", sysfail_entry);
printf("\n");
}
"\n%3$sBoot Loader Interface Commands:%4$s\n"
" set-default ID Set default boot loader entry\n"
" set-oneshot ID Set default boot loader entry, for next boot only\n"
+ " set-sysfail ID Set boot loader entry used in case of a system failure\n"
" set-timeout SECONDS Set the menu timeout\n"
" set-timeout-oneshot SECONDS\n"
" Set the menu timeout for the next boot only\n"
{ "set-oneshot", 2, 2, 0, verb_set_efivar },
{ "set-timeout", 2, 2, 0, verb_set_efivar },
{ "set-timeout-oneshot", 2, 2, 0, verb_set_efivar },
+ { "set-sysfail", 2, 2, 0, verb_set_efivar },
{ "random-seed", VERB_ANY, 1, 0, verb_random_seed },
{ "reboot-to-firmware", VERB_ANY, 2, 0, verb_reboot_to_firmware },
{}
'conditions' : ['ENABLE_BOOTLOADER'],
'symlinks' : ['sysinit.target.wants/'],
},
+ {
+ 'file' : 'systemd-boot-clear-sysfail.service',
+ 'conditions' : ['ENABLE_BOOTLOADER'],
+ },
{
'file' : 'systemd-boot-update.service',
'conditions' : ['ENABLE_BOOTLOADER'],
--- /dev/null
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+
+[Unit]
+Description=Clear SysFail Entry If The Boot Is Successful
+Documentation=man:systemd-boot-sysfail.service(8)
+
+DefaultDependencies=no
+Conflicts=shutdown.target
+Before=sysinit.target shutdown.target
+
+ConditionPathExists=!/etc/initrd-release
+# If LoaderSysFailReason is set we should not clear SysFail entry
+ConditionPathExists=!/sys/firmware/efi/efivars/LoaderSysFailReason-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
+ConditionPathExists=/sys/firmware/efi/efivars/LoaderEntrySysFail-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=bootctl --graceful set-sysfail ""
+
+[Install]
+WantedBy=sysinit.target