mirror of
https://github.com/systemd/systemd.git
synced 2025-01-09 01:18:19 +03:00
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.
This commit is contained in:
parent
558e5654a5
commit
c4b843473a
@ -102,6 +102,17 @@
|
||||
<listitem><para>Sets the default boot loader entry. Takes a single boot loader entry ID string 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></listitem>
|
||||
|
||||
<listitem><para>Optionally, the boot loader entry ID may be specified as one of: <option>@default</option>,
|
||||
<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://systemd.io/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></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
@ -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;
|
||||
_cleanup_free_ char16_t *target = NULL;
|
||||
size_t target_size = 0;
|
||||
|
||||
encoded = utf8_to_utf16(argv[1], strlen(argv[1]));
|
||||
if (!encoded)
|
||||
return log_oom();
|
||||
|
||||
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 log_error_errno(r, "Failed to update EFI variable: %m");
|
||||
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 '%s': %m", name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user