mirror of
https://github.com/systemd/systemd.git
synced 2025-01-25 10:04:04 +03:00
parent
52b6b35643
commit
39ddc32a86
@ -116,6 +116,21 @@
|
|||||||
</para></listitem>
|
</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>set-timeout</option> <replaceable>TIMEOUT</replaceable></term>
|
||||||
|
<term><option>set-timeout-oneshot</option> <replaceable>TIMEOUT</replaceable></term>
|
||||||
|
|
||||||
|
<listitem><para>Sets the boot loader menu timeout in seconds. The <option>set-timeout-oneshot</option>
|
||||||
|
command will set the timeout only for the next boot. See
|
||||||
|
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>
|
||||||
|
for details about the syntax of time spans.</para>
|
||||||
|
|
||||||
|
<para>If this is set to <option>menu-hidden</option> or <option>0</option> no menu is shown and
|
||||||
|
the default entry will be booted immediately, while setting this to <option>menu-force</option>
|
||||||
|
disables the timeout while always showing the menu. When an empty string ("") is specified the
|
||||||
|
bootloader will revert to its default menu timeout.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ _bootctl() {
|
|||||||
|
|
||||||
local -A VERBS=(
|
local -A VERBS=(
|
||||||
# systemd-efi-options takes an argument, but it is free-form, so we cannot complete it
|
# systemd-efi-options takes an argument, but it is free-form, so we cannot complete it
|
||||||
[STANDALONE]='help status install update remove is-installed random-seed systemd-efi-options list'
|
[STANDALONE]='help status install update remove is-installed random-seed systemd-efi-options list set-timeout set-timeout-oneshot'
|
||||||
[BOOTENTRY]='set-default set-oneshot'
|
[BOOTENTRY]='set-default set-oneshot'
|
||||||
[BOOLEAN]='reboot-to-firmware'
|
[BOOLEAN]='reboot-to-firmware'
|
||||||
)
|
)
|
||||||
|
@ -46,6 +46,8 @@ _bootctl_reboot-to-firmware() {
|
|||||||
"list:List boot loader entries"
|
"list:List boot loader entries"
|
||||||
"set-default:Set the default boot loader entry"
|
"set-default:Set the default boot loader entry"
|
||||||
"set-oneshot:Set the default boot loader entry only for the next boot"
|
"set-oneshot:Set the default boot loader entry only for the next boot"
|
||||||
|
"set-timeout:Set the menu timeout"
|
||||||
|
"set-timeout-oneshot:Set the menu timeout for the next boot only"
|
||||||
)
|
)
|
||||||
if (( CURRENT == 1 )); then
|
if (( CURRENT == 1 )); then
|
||||||
_describe -t commands 'bootctl command' _bootctl_cmds || compadd "$@"
|
_describe -t commands 'bootctl command' _bootctl_cmds || compadd "$@"
|
||||||
|
@ -1100,6 +1100,9 @@ static int help(int argc, char *argv[], void *userdata) {
|
|||||||
" list List boot loader entries\n"
|
" list List boot loader entries\n"
|
||||||
" set-default ID Set default boot loader entry\n"
|
" set-default ID Set default boot loader entry\n"
|
||||||
" set-oneshot ID Set default boot loader entry, for next boot only\n"
|
" set-oneshot ID Set default boot loader entry, for next boot only\n"
|
||||||
|
" set-timeout SECONDS Set the menu timeout\n"
|
||||||
|
" set-timeout-oneshot SECONDS\n"
|
||||||
|
" Set the menu timeout for the next boot only\n"
|
||||||
"\n%3$ssystemd-boot Commands:%4$s\n"
|
"\n%3$ssystemd-boot Commands:%4$s\n"
|
||||||
" install Install systemd-boot to the ESP and EFI variables\n"
|
" install Install systemd-boot to the ESP and EFI variables\n"
|
||||||
" update Update systemd-boot in the ESP and EFI variables\n"
|
" update Update systemd-boot in the ESP and EFI variables\n"
|
||||||
@ -1774,6 +1777,37 @@ static int verb_is_installed(int argc, char *argv[], void *userdata) {
|
|||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int parse_timeout(const char *arg1, char16_t **ret_timeout, size_t *ret_timeout_size) {
|
||||||
|
char utf8[DECIMAL_STR_MAX(usec_t)];
|
||||||
|
char16_t *encoded;
|
||||||
|
usec_t timeout;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(arg1);
|
||||||
|
assert(ret_timeout);
|
||||||
|
assert(ret_timeout_size);
|
||||||
|
|
||||||
|
if (streq(arg1, "menu-force"))
|
||||||
|
timeout = USEC_INFINITY;
|
||||||
|
else if (streq(arg1, "menu-hidden"))
|
||||||
|
timeout = 0;
|
||||||
|
else {
|
||||||
|
r = parse_time(arg1, &timeout, USEC_PER_SEC);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to parse timeout '%s': %m", arg1);
|
||||||
|
if (timeout != USEC_INFINITY && timeout > UINT32_MAX * USEC_PER_SEC)
|
||||||
|
log_warning("Timeout is too long and will be treated as 'menu-force' instead.");
|
||||||
|
}
|
||||||
|
|
||||||
|
xsprintf(utf8, USEC_FMT, MIN(timeout / USEC_PER_SEC, UINT32_MAX));
|
||||||
|
encoded = utf8_to_utf16(utf8, strlen(utf8));
|
||||||
|
if (!encoded)
|
||||||
|
return log_oom();
|
||||||
|
*ret_timeout = encoded;
|
||||||
|
*ret_timeout_size = char16_strlen(encoded) * 2 + 2;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int parse_loader_entry_target_arg(const char *arg1, char16_t **ret_target, size_t *ret_target_size) {
|
static int parse_loader_entry_target_arg(const char *arg1, char16_t **ret_target, size_t *ret_target_size) {
|
||||||
int r;
|
int r;
|
||||||
if (streq(arg1, "@current")) {
|
if (streq(arg1, "@current")) {
|
||||||
@ -1799,7 +1833,7 @@ static int parse_loader_entry_target_arg(const char *arg1, char16_t **ret_target
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int verb_set_default(int argc, char *argv[], void *userdata) {
|
static int verb_set_efivar(int argc, char *argv[], void *userdata) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (!is_efi_boot())
|
if (!is_efi_boot())
|
||||||
@ -1822,24 +1856,39 @@ static int verb_set_default(int argc, char *argv[], void *userdata) {
|
|||||||
|
|
||||||
if (!arg_touch_variables)
|
if (!arg_touch_variables)
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
"'%s' operation cannot be combined with --touch-variables=no.",
|
"'%s' operation cannot be combined with --no-variables.",
|
||||||
argv[0]);
|
argv[0]);
|
||||||
|
|
||||||
const char *variable = streq(argv[0], "set-default") ?
|
const char *variable;
|
||||||
EFI_LOADER_VARIABLE(LoaderEntryDefault) : EFI_LOADER_VARIABLE(LoaderEntryOneShot);
|
int (* arg_parser)(const char *, char16_t **, size_t *);
|
||||||
|
|
||||||
|
if (streq(argv[0], "set-default")) {
|
||||||
|
variable = EFI_LOADER_VARIABLE(LoaderEntryDefault);
|
||||||
|
arg_parser = parse_loader_entry_target_arg;
|
||||||
|
} else if (streq(argv[0], "set-oneshot")) {
|
||||||
|
variable = EFI_LOADER_VARIABLE(LoaderEntryOneShot);
|
||||||
|
arg_parser = parse_loader_entry_target_arg;
|
||||||
|
} else if (streq(argv[0], "set-timeout")) {
|
||||||
|
variable = EFI_LOADER_VARIABLE(LoaderConfigTimeout);
|
||||||
|
arg_parser = parse_timeout;
|
||||||
|
} else if (streq(argv[0], "set-timeout-oneshot")) {
|
||||||
|
variable = EFI_LOADER_VARIABLE(LoaderConfigTimeoutOneShot);
|
||||||
|
arg_parser = parse_timeout;
|
||||||
|
} else
|
||||||
|
assert_not_reached();
|
||||||
|
|
||||||
if (isempty(argv[1])) {
|
if (isempty(argv[1])) {
|
||||||
r = efi_set_variable(variable, NULL, 0);
|
r = efi_set_variable(variable, NULL, 0);
|
||||||
if (r < 0 && r != -ENOENT)
|
if (r < 0 && r != -ENOENT)
|
||||||
return log_error_errno(r, "Failed to remove EFI variable '%s': %m", variable);
|
return log_error_errno(r, "Failed to remove EFI variable '%s': %m", variable);
|
||||||
} else {
|
} else {
|
||||||
_cleanup_free_ char16_t *target = NULL;
|
_cleanup_free_ char16_t *value = NULL;
|
||||||
size_t target_size = 0;
|
size_t value_size = 0;
|
||||||
|
|
||||||
r = parse_loader_entry_target_arg(argv[1], &target, &target_size);
|
r = arg_parser(argv[1], &value, &value_size);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
r = efi_set_variable(variable, target, target_size);
|
r = efi_set_variable(variable, value, value_size);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to update EFI variable '%s': %m", variable);
|
return log_error_errno(r, "Failed to update EFI variable '%s': %m", variable);
|
||||||
}
|
}
|
||||||
@ -1944,8 +1993,10 @@ static int bootctl_main(int argc, char *argv[]) {
|
|||||||
{ "remove", VERB_ANY, 1, 0, verb_remove },
|
{ "remove", VERB_ANY, 1, 0, verb_remove },
|
||||||
{ "is-installed", VERB_ANY, 1, 0, verb_is_installed },
|
{ "is-installed", VERB_ANY, 1, 0, verb_is_installed },
|
||||||
{ "list", VERB_ANY, 1, 0, verb_list },
|
{ "list", VERB_ANY, 1, 0, verb_list },
|
||||||
{ "set-default", 2, 2, 0, verb_set_default },
|
{ "set-default", 2, 2, 0, verb_set_efivar },
|
||||||
{ "set-oneshot", 2, 2, 0, verb_set_default },
|
{ "set-oneshot", 2, 2, 0, verb_set_efivar },
|
||||||
|
{ "set-timeout", 2, 2, 0, verb_set_efivar },
|
||||||
|
{ "set-timeout-oneshot", 2, 2, 0, verb_set_efivar },
|
||||||
{ "random-seed", VERB_ANY, 1, 0, verb_random_seed },
|
{ "random-seed", VERB_ANY, 1, 0, verb_random_seed },
|
||||||
{ "systemd-efi-options", VERB_ANY, 2, 0, verb_systemd_efi_options },
|
{ "systemd-efi-options", VERB_ANY, 2, 0, verb_systemd_efi_options },
|
||||||
{ "reboot-to-firmware", VERB_ANY, 2, 0, verb_reboot_to_firmware },
|
{ "reboot-to-firmware", VERB_ANY, 2, 0, verb_reboot_to_firmware },
|
||||||
|
Loading…
x
Reference in New Issue
Block a user