From c4b843473a75fb38ed5bf54e9d3cfb1cb3719efa Mon Sep 17 00:00:00 2001 From: Дамјан Георгиевски Date: Tue, 13 Oct 2020 12:25:59 +0200 Subject: bootctl: add @current/@oneshot/@default targets to set-default/set-oneshot Using `bootctl set-default @current` will set the default loader entry to the currently booted entry as read from the `LoaderEntrySelected` EFI variable. Also `bootctl set-oneshot @current` will set the oneshot loader entry to the current booted entry. Correspondingly `@default` and `@oneshot` can be used to read from the LoaderEntryDefault and LoaderEntryOneshot EFI variables. --- src/boot/bootctl.c | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) (limited to 'src/boot/bootctl.c') diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c index 0e24f0a499..bb8c7398f0 100644 --- a/src/boot/bootctl.c +++ b/src/boot/bootctl.c @@ -1661,6 +1661,31 @@ static int verb_is_installed(int argc, char *argv[], void *userdata) { return EXIT_SUCCESS; } +static int parse_loader_entry_target_arg(const char *arg1, char16_t **ret_target, size_t *ret_target_size) { + int r; + if (streq(arg1, "@current")) { + r = efi_get_variable(EFI_VENDOR_LOADER, "LoaderEntrySelected", NULL, (void *) ret_target, ret_target_size); + if (r < 0) + return log_error_errno(r, "Failed to get EFI variable 'LoaderEntrySelected': %m"); + } else if (streq(arg1, "@oneshot")) { + r = efi_get_variable(EFI_VENDOR_LOADER, "LoaderEntryOneShot", NULL, (void *) ret_target, ret_target_size); + if (r < 0) + return log_error_errno(r, "Failed to get EFI variable 'LoaderEntryOneShot': %m"); + } else if (streq(arg1, "@default")) { + r = efi_get_variable(EFI_VENDOR_LOADER, "LoaderEntryDefault", NULL, (void *) ret_target, ret_target_size); + if (r < 0) + return log_error_errno(r, "Failed to get EFI variable 'LoaderEntryDefault': %m"); + } else { + char16_t *encoded = NULL; + encoded = utf8_to_utf16(arg1, strlen(arg1)); + if (!encoded) + return log_oom(); + *ret_target = encoded; + *ret_target_size = char16_strlen(encoded) * 2 + 2; + } + return 0; +} + static int verb_set_default(int argc, char *argv[], void *userdata) { const char *name; int r; @@ -1693,17 +1718,17 @@ static int verb_set_default(int argc, char *argv[], void *userdata) { if (isempty(argv[1])) { r = efi_set_variable(EFI_VENDOR_LOADER, name, NULL, 0); if (r < 0 && r != -ENOENT) - return log_error_errno(r, "Failed to remove EFI variale: %m"); + return log_error_errno(r, "Failed to remove EFI variable '%s': %m", name); } else { - _cleanup_free_ char16_t *encoded = NULL; - - encoded = utf8_to_utf16(argv[1], strlen(argv[1])); - if (!encoded) - return log_oom(); + _cleanup_free_ char16_t *target = NULL; + size_t target_size = 0; - r = efi_set_variable(EFI_VENDOR_LOADER, name, encoded, char16_strlen(encoded) * 2 + 2); + r = parse_loader_entry_target_arg(argv[1], &target, &target_size); + if (r < 0) + return r; + r = efi_set_variable(EFI_VENDOR_LOADER, name, target, target_size); if (r < 0) - return log_error_errno(r, "Failed to update EFI variable: %m"); + return log_error_errno(r, "Failed to update EFI variable '%s': %m", name); } return 0; -- cgit v1.2.3