summaryrefslogtreecommitdiffstats
path: root/src/boot/bootctl.c
diff options
context:
space:
mode:
authorДамјан Георгиевски <gdamjan@gmail.com>2020-10-13 12:25:59 +0200
committerLennart Poettering <lennart@poettering.net>2020-10-20 15:02:58 +0200
commitc4b843473a75fb38ed5bf54e9d3cfb1cb3719efa (patch)
tree5cf4efd0077c38593b21b39b03e9b02be9670bb0 /src/boot/bootctl.c
parentMerge pull request #17401 from mrc0mmand/sempahore-fixups (diff)
downloadsystemd-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.c41
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;