mirror of
https://github.com/systemd/systemd.git
synced 2024-11-23 18:23:32 +08:00
Merge pull request #20776 from medhefgo/boot-timeout
sd-boot: Allow disabling timeout
This commit is contained in:
commit
5c791053e3
@ -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>
|
||||||
|
|
||||||
|
@ -106,9 +106,10 @@
|
|||||||
will be stored as an EFI variable in that case, overriding this option.
|
will be stored as an EFI variable in that case, overriding this option.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>If the timeout is disabled, the default entry will be booted
|
<para>If set to <literal>menu-hidden</literal> or <literal>0</literal> no menu
|
||||||
immediately. The menu can be shown by pressing and holding a key before
|
is shown and the default entry will be booted immediately. The menu can be shown
|
||||||
systemd-boot is launched.</para>
|
by pressing and holding a key before systemd-boot is launched. Setting this to
|
||||||
|
<literal>menu-force</literal> disables the timeout while always showing the menu.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
@ -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 "$@"
|
||||||
|
@ -1099,6 +1099,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"
|
||||||
@ -1773,6 +1776,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")) {
|
||||||
@ -1798,7 +1832,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())
|
||||||
@ -1821,24 +1855,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);
|
||||||
}
|
}
|
||||||
@ -1943,8 +1992,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 },
|
||||||
|
@ -60,9 +60,9 @@ typedef struct {
|
|||||||
UINTN entry_count;
|
UINTN entry_count;
|
||||||
INTN idx_default;
|
INTN idx_default;
|
||||||
INTN idx_default_efivar;
|
INTN idx_default_efivar;
|
||||||
UINTN timeout_sec;
|
UINT32 timeout_sec; /* Actual timeout used (efi_main() override > efivar > config). */
|
||||||
UINTN timeout_sec_config;
|
UINT32 timeout_sec_config;
|
||||||
INTN timeout_sec_efivar;
|
UINT32 timeout_sec_efivar;
|
||||||
CHAR16 *entry_default_pattern;
|
CHAR16 *entry_default_pattern;
|
||||||
CHAR16 *entry_oneshot;
|
CHAR16 *entry_oneshot;
|
||||||
CHAR16 *options_edit;
|
CHAR16 *options_edit;
|
||||||
@ -75,6 +75,18 @@ typedef struct {
|
|||||||
RandomSeedMode random_seed_mode;
|
RandomSeedMode random_seed_mode;
|
||||||
} Config;
|
} Config;
|
||||||
|
|
||||||
|
/* These values have been chosen so that the transitions the user sees could
|
||||||
|
* employ unsigned over-/underflow like this:
|
||||||
|
* efivar unset ↔ force menu ↔ no timeout/skip menu ↔ 1 s ↔ 2 s ↔ … */
|
||||||
|
enum {
|
||||||
|
TIMEOUT_MIN = 1,
|
||||||
|
TIMEOUT_MAX = UINT32_MAX - 2U,
|
||||||
|
TIMEOUT_UNSET = UINT32_MAX - 1U,
|
||||||
|
TIMEOUT_MENU_FORCE = UINT32_MAX,
|
||||||
|
TIMEOUT_MENU_HIDDEN = 0,
|
||||||
|
TIMEOUT_TYPE_MAX = UINT32_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
static VOID cursor_left(UINTN *cursor, UINTN *first) {
|
static VOID cursor_left(UINTN *cursor, UINTN *first) {
|
||||||
assert(cursor);
|
assert(cursor);
|
||||||
assert(first);
|
assert(first);
|
||||||
@ -366,6 +378,38 @@ static UINTN entry_lookup_key(Config *config, UINTN start, CHAR16 key) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CHAR16 *update_timeout_efivar(UINT32 *t, BOOLEAN inc) {
|
||||||
|
assert(t);
|
||||||
|
|
||||||
|
switch (*t) {
|
||||||
|
case TIMEOUT_MAX:
|
||||||
|
*t = inc ? TIMEOUT_MAX : (*t - 1);
|
||||||
|
break;
|
||||||
|
case TIMEOUT_UNSET:
|
||||||
|
*t = inc ? TIMEOUT_MENU_FORCE : TIMEOUT_UNSET;
|
||||||
|
break;
|
||||||
|
case TIMEOUT_MENU_FORCE:
|
||||||
|
*t = inc ? TIMEOUT_MENU_HIDDEN : TIMEOUT_UNSET;
|
||||||
|
break;
|
||||||
|
case TIMEOUT_MENU_HIDDEN:
|
||||||
|
*t = inc ? TIMEOUT_MIN : TIMEOUT_MENU_FORCE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
*t += inc ? 1 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (*t) {
|
||||||
|
case TIMEOUT_UNSET:
|
||||||
|
return StrDuplicate(L"Menu timeout defined by configuration file.");
|
||||||
|
case TIMEOUT_MENU_FORCE:
|
||||||
|
return StrDuplicate(L"Timeout disabled, menu will always be shown.");
|
||||||
|
case TIMEOUT_MENU_HIDDEN:
|
||||||
|
return StrDuplicate(L"Menu disabled. Hold down key at bootup to show menu.");
|
||||||
|
default:
|
||||||
|
return PoolPrint(L"Menu timeout set to %u s.", *t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static VOID print_status(Config *config, CHAR16 *loaded_image_path) {
|
static VOID print_status(Config *config, CHAR16 *loaded_image_path) {
|
||||||
UINT64 key;
|
UINT64 key;
|
||||||
UINTN timeout;
|
UINTN timeout;
|
||||||
@ -400,10 +444,11 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) {
|
|||||||
Print(L"\n--- press key ---\n\n");
|
Print(L"\n--- press key ---\n\n");
|
||||||
console_key_read(&key, 0);
|
console_key_read(&key, 0);
|
||||||
|
|
||||||
Print(L"timeout: %u\n", config->timeout_sec);
|
Print(L"timeout: %u s\n", config->timeout_sec);
|
||||||
if (config->timeout_sec_efivar >= 0)
|
if (config->timeout_sec_efivar != TIMEOUT_UNSET)
|
||||||
Print(L"timeout (EFI var): %d\n", config->timeout_sec_efivar);
|
Print(L"timeout (EFI var): %u s\n", config->timeout_sec_efivar);
|
||||||
Print(L"timeout (config): %u\n", config->timeout_sec_config);
|
if (config->timeout_sec_config != TIMEOUT_UNSET)
|
||||||
|
Print(L"timeout (config): %u s\n", config->timeout_sec_config);
|
||||||
if (config->entry_default_pattern)
|
if (config->entry_default_pattern)
|
||||||
Print(L"default pattern: '%s'\n", config->entry_default_pattern);
|
Print(L"default pattern: '%s'\n", config->entry_default_pattern);
|
||||||
Print(L"editor: %s\n", yes_no(config->editor));
|
Print(L"editor: %s\n", yes_no(config->editor));
|
||||||
@ -519,7 +564,8 @@ static BOOLEAN menu_run(
|
|||||||
UINTN x_max, y_max;
|
UINTN x_max, y_max;
|
||||||
CHAR16 **lines = NULL;
|
CHAR16 **lines = NULL;
|
||||||
_cleanup_freepool_ CHAR16 *clearline = NULL, *status = NULL;
|
_cleanup_freepool_ CHAR16 *clearline = NULL, *status = NULL;
|
||||||
UINTN timeout_remain = config->timeout_sec;
|
UINT32 timeout_efivar_saved = config->timeout_sec_efivar;
|
||||||
|
UINT32 timeout_remain = config->timeout_sec == TIMEOUT_MENU_FORCE ? 0 : config->timeout_sec;
|
||||||
INT16 idx;
|
INT16 idx;
|
||||||
BOOLEAN exit = FALSE, run = TRUE;
|
BOOLEAN exit = FALSE, run = TRUE;
|
||||||
INT64 console_mode_initial = ST->ConOut->Mode->Mode, console_mode_efivar_saved = config->console_mode_efivar;
|
INT64 console_mode_initial = ST->ConOut->Mode->Mode, console_mode_efivar_saved = config->console_mode_efivar;
|
||||||
@ -640,7 +686,7 @@ static BOOLEAN menu_run(
|
|||||||
|
|
||||||
if (timeout_remain > 0) {
|
if (timeout_remain > 0) {
|
||||||
FreePool(status);
|
FreePool(status);
|
||||||
status = PoolPrint(L"Boot in %d s.", timeout_remain);
|
status = PoolPrint(L"Boot in %u s.", timeout_remain);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* print status at last line of screen */
|
/* print status at last line of screen */
|
||||||
@ -768,44 +814,12 @@ static BOOLEAN menu_run(
|
|||||||
|
|
||||||
case KEYPRESS(0, 0, '-'):
|
case KEYPRESS(0, 0, '-'):
|
||||||
case KEYPRESS(0, 0, 'T'):
|
case KEYPRESS(0, 0, 'T'):
|
||||||
if (config->timeout_sec_efivar > 0) {
|
status = update_timeout_efivar(&config->timeout_sec_efivar, FALSE);
|
||||||
config->timeout_sec_efivar--;
|
|
||||||
efivar_set_uint_string(
|
|
||||||
LOADER_GUID,
|
|
||||||
L"LoaderConfigTimeout",
|
|
||||||
config->timeout_sec_efivar,
|
|
||||||
EFI_VARIABLE_NON_VOLATILE);
|
|
||||||
if (config->timeout_sec_efivar > 0)
|
|
||||||
status = PoolPrint(L"Menu timeout set to %d s.", config->timeout_sec_efivar);
|
|
||||||
else
|
|
||||||
status = StrDuplicate(L"Menu disabled. Hold down key at bootup to show menu.");
|
|
||||||
} else if (config->timeout_sec_efivar <= 0){
|
|
||||||
config->timeout_sec_efivar = -1;
|
|
||||||
efivar_set(
|
|
||||||
LOADER_GUID, L"LoaderConfigTimeout", NULL, EFI_VARIABLE_NON_VOLATILE);
|
|
||||||
if (config->timeout_sec_config > 0)
|
|
||||||
status = PoolPrint(L"Menu timeout of %d s is defined by configuration file.",
|
|
||||||
config->timeout_sec_config);
|
|
||||||
else
|
|
||||||
status = StrDuplicate(L"Menu disabled. Hold down key at bootup to show menu.");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KEYPRESS(0, 0, '+'):
|
case KEYPRESS(0, 0, '+'):
|
||||||
case KEYPRESS(0, 0, 't'):
|
case KEYPRESS(0, 0, 't'):
|
||||||
if (config->timeout_sec_efivar == -1 && config->timeout_sec_config == 0)
|
status = update_timeout_efivar(&config->timeout_sec_efivar, TRUE);
|
||||||
config->timeout_sec_efivar++;
|
|
||||||
config->timeout_sec_efivar++;
|
|
||||||
efivar_set_uint_string(
|
|
||||||
LOADER_GUID,
|
|
||||||
L"LoaderConfigTimeout",
|
|
||||||
config->timeout_sec_efivar,
|
|
||||||
EFI_VARIABLE_NON_VOLATILE);
|
|
||||||
if (config->timeout_sec_efivar > 0)
|
|
||||||
status = PoolPrint(L"Menu timeout set to %d s.",
|
|
||||||
config->timeout_sec_efivar);
|
|
||||||
else
|
|
||||||
status = StrDuplicate(L"Menu disabled. Hold down key at bootup to show menu.");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KEYPRESS(0, 0, 'e'):
|
case KEYPRESS(0, 0, 'e'):
|
||||||
@ -888,9 +902,8 @@ static BOOLEAN menu_run(
|
|||||||
|
|
||||||
*chosen_entry = config->entries[idx_highlight];
|
*chosen_entry = config->entries[idx_highlight];
|
||||||
|
|
||||||
/* The user is likely to cycle through several modes before
|
/* Update EFI vars after we left the menu to reduce NVRAM writes. */
|
||||||
* deciding to keep one. Therefore, we update the EFI var after
|
|
||||||
* we left the menu to reduce nvram writes. */
|
|
||||||
if (console_mode_efivar_saved != config->console_mode_efivar) {
|
if (console_mode_efivar_saved != config->console_mode_efivar) {
|
||||||
if (config->console_mode_efivar == CONSOLE_MODE_KEEP)
|
if (config->console_mode_efivar == CONSOLE_MODE_KEEP)
|
||||||
efivar_set(LOADER_GUID, L"LoaderConfigConsoleMode", NULL, EFI_VARIABLE_NON_VOLATILE);
|
efivar_set(LOADER_GUID, L"LoaderConfigConsoleMode", NULL, EFI_VARIABLE_NON_VOLATILE);
|
||||||
@ -899,6 +912,14 @@ static BOOLEAN menu_run(
|
|||||||
config->console_mode_efivar, EFI_VARIABLE_NON_VOLATILE);
|
config->console_mode_efivar, EFI_VARIABLE_NON_VOLATILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (timeout_efivar_saved != config->timeout_sec_efivar) {
|
||||||
|
if (config->timeout_sec_efivar == TIMEOUT_UNSET)
|
||||||
|
efivar_set(LOADER_GUID, L"LoaderConfigTimeout", NULL, EFI_VARIABLE_NON_VOLATILE);
|
||||||
|
else
|
||||||
|
efivar_set_uint_string(LOADER_GUID, L"LoaderConfigTimeout",
|
||||||
|
config->timeout_sec_efivar, EFI_VARIABLE_NON_VOLATILE);
|
||||||
|
}
|
||||||
|
|
||||||
for (UINTN i = 0; i < config->entry_count; i++)
|
for (UINTN i = 0; i < config->entry_count; i++)
|
||||||
FreePool(lines[i]);
|
FreePool(lines[i]);
|
||||||
FreePool(lines);
|
FreePool(lines);
|
||||||
@ -1023,10 +1044,16 @@ static VOID config_defaults_load_from_file(Config *config, CHAR8 *content) {
|
|||||||
|
|
||||||
while ((line = line_get_key_value(content, (CHAR8 *)" \t", &pos, &key, &value))) {
|
while ((line = line_get_key_value(content, (CHAR8 *)" \t", &pos, &key, &value))) {
|
||||||
if (strcmpa((CHAR8 *)"timeout", key) == 0) {
|
if (strcmpa((CHAR8 *)"timeout", key) == 0) {
|
||||||
_cleanup_freepool_ CHAR16 *s = NULL;
|
if (strcmpa((CHAR8*) "menu-force", value) == 0)
|
||||||
|
config->timeout_sec_config = TIMEOUT_MENU_FORCE;
|
||||||
|
else if (strcmpa((CHAR8*) "menu-hidden", value) == 0)
|
||||||
|
config->timeout_sec_config = TIMEOUT_MENU_HIDDEN;
|
||||||
|
else {
|
||||||
|
_cleanup_freepool_ CHAR16 *s = NULL;
|
||||||
|
|
||||||
s = stra_to_str(value);
|
s = stra_to_str(value);
|
||||||
config->timeout_sec_config = Atoi(s);
|
config->timeout_sec_config = MIN(Atoi(s), TIMEOUT_TYPE_MAX);
|
||||||
|
}
|
||||||
config->timeout_sec = config->timeout_sec_config;
|
config->timeout_sec = config->timeout_sec_config;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1439,6 +1466,8 @@ static VOID config_load_defaults(Config *config, EFI_FILE *root_dir) {
|
|||||||
.idx_default_efivar = -1,
|
.idx_default_efivar = -1,
|
||||||
.console_mode = CONSOLE_MODE_KEEP,
|
.console_mode = CONSOLE_MODE_KEEP,
|
||||||
.console_mode_efivar = CONSOLE_MODE_KEEP,
|
.console_mode_efivar = CONSOLE_MODE_KEEP,
|
||||||
|
.timeout_sec_config = TIMEOUT_UNSET,
|
||||||
|
.timeout_sec_efivar = TIMEOUT_UNSET,
|
||||||
};
|
};
|
||||||
|
|
||||||
err = file_read(root_dir, L"\\loader\\loader.conf", 0, 0, &content, NULL);
|
err = file_read(root_dir, L"\\loader\\loader.conf", 0, 0, &content, NULL);
|
||||||
@ -1447,17 +1476,16 @@ static VOID config_load_defaults(Config *config, EFI_FILE *root_dir) {
|
|||||||
|
|
||||||
err = efivar_get_uint_string(LOADER_GUID, L"LoaderConfigTimeout", &value);
|
err = efivar_get_uint_string(LOADER_GUID, L"LoaderConfigTimeout", &value);
|
||||||
if (!EFI_ERROR(err)) {
|
if (!EFI_ERROR(err)) {
|
||||||
config->timeout_sec_efivar = value > INTN_MAX ? INTN_MAX : value;
|
config->timeout_sec_efivar = MIN(value, TIMEOUT_TYPE_MAX);
|
||||||
config->timeout_sec = value;
|
config->timeout_sec = config->timeout_sec_efivar;
|
||||||
} else
|
}
|
||||||
config->timeout_sec_efivar = -1;
|
|
||||||
|
|
||||||
err = efivar_get_uint_string(LOADER_GUID, L"LoaderConfigTimeoutOneShot", &value);
|
err = efivar_get_uint_string(LOADER_GUID, L"LoaderConfigTimeoutOneShot", &value);
|
||||||
if (!EFI_ERROR(err)) {
|
if (!EFI_ERROR(err)) {
|
||||||
/* Unset variable now, after all it's "one shot". */
|
/* Unset variable now, after all it's "one shot". */
|
||||||
(void) efivar_set(LOADER_GUID, L"LoaderConfigTimeoutOneShot", NULL, EFI_VARIABLE_NON_VOLATILE);
|
(void) efivar_set(LOADER_GUID, L"LoaderConfigTimeoutOneShot", NULL, EFI_VARIABLE_NON_VOLATILE);
|
||||||
|
|
||||||
config->timeout_sec = value;
|
config->timeout_sec = MIN(value, TIMEOUT_TYPE_MAX);
|
||||||
config->force_menu = TRUE; /* force the menu when this is set */
|
config->force_menu = TRUE; /* force the menu when this is set */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user