diff options
author | Дамјан Георгиевски <gdamjan@gmail.com> | 2020-10-13 12:25:59 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2020-10-20 15:02:58 +0200 |
commit | c4b843473a75fb38ed5bf54e9d3cfb1cb3719efa (patch) | |
tree | 5cf4efd0077c38593b21b39b03e9b02be9670bb0 /src/boot/bootctl.c | |
parent | Merge pull request #17401 from mrc0mmand/sempahore-fixups (diff) | |
download | systemd-c4b843473a75fb38ed5bf54e9d3cfb1cb3719efa.tar.xz systemd-c4b843473a75fb38ed5bf54e9d3cfb1cb3719efa.zip |
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.
Diffstat (limited to 'src/boot/bootctl.c')
-rw-r--r-- | src/boot/bootctl.c | 41 |
1 files changed, 33 insertions, 8 deletions
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; |