From 002914e6887571388e84a7753bd4deca925ab064 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 27 May 2020 17:22:29 +0200 Subject: [PATCH] bootctl: add simple, low-level reboot-to-firmware verb for controlling the flag --- man/bootctl.xml | 13 ++++++++++++- src/boot/bootctl.c | 41 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/man/bootctl.xml b/man/bootctl.xml index c038c4686d..6db048b63b 100644 --- a/man/bootctl.xml +++ b/man/bootctl.xml @@ -102,7 +102,7 @@ - VALUE + STRING When called without the optional argument, prints the current value of the SystemdOptions EFI variable. When called with an argument, sets the @@ -111,6 +111,17 @@ for the meaning of that variable. + + BOOL + + Query or set the "Reboot-Into-Firmware-Setup" flag of the EFI firmware. Takes a + boolean argument which controls whether to show the firmware setup on next system reboot. If the + argument is omitted shows the current status of the flag, or whether the flag is supported. This + controls the same flag as systemctl reboot --firmware-setup, but is more + low-level and allows setting the flag independently from actually requesting a + reboot. + + diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c index 11563fc2de..a663fc5c2d 100644 --- a/src/boot/bootctl.c +++ b/src/boot/bootctl.c @@ -1041,7 +1041,10 @@ static int help(int argc, char *argv[], void *userdata) { " remove Remove systemd-boot from the ESP and EFI variables\n" " is-installed Test whether systemd-boot is installed in the ESP\n" " random-seed Initialize random seed in ESP and EFI variables\n" - " systemd-efi-options Query or set system options string in EFI variable\n" + " systemd-efi-options [STRING]\n" + " Query or set system options string in EFI variable\n" + " reboot-to-firmware [BOOL]\n" + " Query or set reboot-to-firmware EFI flag\n" "\nBoot Loader Entries Commands:\n" " list List boot loader entries\n" " set-default ID Set default boot loader entry\n" @@ -1785,6 +1788,39 @@ static int verb_systemd_efi_options(int argc, char *argv[], void *userdata) { return 0; } +static int verb_reboot_to_firmware(int argc, char *argv[], void *userdata) { + int r; + + if (argc < 2) { + r = efi_get_reboot_to_firmware(); + if (r > 0) { + puts("active"); + return EXIT_SUCCESS; /* success */ + } + if (r == 0) { + puts("supported"); + return 1; /* recognizable error #1 */ + } + if (r == -EOPNOTSUPP) { + puts("not supported"); + return 2; /* recognizable error #2 */ + } + + log_error_errno(r, "Failed to query reboot-to-firmware state: %m"); + return 3; /* other kind of error */ + } else { + r = parse_boolean(argv[1]); + if (r < 0) + return log_error_errno(r, "Failed to parse argument: %s", argv[1]); + + r = efi_set_reboot_to_firmware(r); + if (r < 0) + return log_error_errno(r, "Failed to set reboot-to-firmware option: %m"); + + return 0; + } +} + static int bootctl_main(int argc, char *argv[]) { static const Verb verbs[] = { { "help", VERB_ANY, VERB_ANY, 0, help }, @@ -1798,6 +1834,7 @@ static int bootctl_main(int argc, char *argv[]) { { "set-oneshot", 2, 2, 0, verb_set_default }, { "random-seed", VERB_ANY, 1, 0, verb_random_seed }, { "systemd-efi-options", VERB_ANY, 2, 0, verb_systemd_efi_options }, + { "reboot-to-firmware", VERB_ANY, 2, 0, verb_reboot_to_firmware }, {} }; @@ -1821,4 +1858,4 @@ static int run(int argc, char *argv[]) { return bootctl_main(argc, argv); } -DEFINE_MAIN_FUNCTION(run); +DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(run);