mirror of
https://github.com/systemd/systemd
synced 2024-07-21 10:17:21 +00:00
boot: Avoid magic values in timeout EFI vars
This commit is contained in:
parent
28fda21c85
commit
97f077df05
|
@ -31,7 +31,11 @@ variables. All EFI variables use the vendor UUID
|
|||
* The EFI variable `LoaderConfigTimeout` contains the boot menu timeout
|
||||
currently in use. It may be modified both by the boot loader and by the
|
||||
host. The value should be formatted as numeric, NUL-terminated, decimal
|
||||
string, in UTF-16. The time is specified in µs.
|
||||
string, in UTF-16. The time is specified in seconds. A value of `menu-force`
|
||||
will disable the timeout and show the menu indefinitely. If set to `0` or
|
||||
`menu-hidden` the default entry is booted immediately without showing a menu.
|
||||
The boot loader should provide a way to interrupt this by for example
|
||||
listening for key presses for a brief moment before booting.
|
||||
|
||||
* Similarly, the EFI variable `LoaderConfigTimeoutOneShot` contains a boot menu
|
||||
timeout for a single following boot. It is set by the OS in order to request
|
||||
|
|
|
@ -1037,11 +1037,20 @@ static bool menu_run(
|
|||
}
|
||||
|
||||
if (timeout_efivar_saved != config->timeout_sec_efivar) {
|
||||
if (config->timeout_sec_efivar == TIMEOUT_UNSET)
|
||||
switch (config->timeout_sec_efivar) {
|
||||
case TIMEOUT_UNSET:
|
||||
efivar_set(LOADER_GUID, L"LoaderConfigTimeout", NULL, EFI_VARIABLE_NON_VOLATILE);
|
||||
else
|
||||
break;
|
||||
case TIMEOUT_MENU_FORCE:
|
||||
efivar_set(LOADER_GUID, u"LoaderConfigTimeout", u"menu-force", EFI_VARIABLE_NON_VOLATILE);
|
||||
break;
|
||||
case TIMEOUT_MENU_HIDDEN:
|
||||
efivar_set(LOADER_GUID, u"LoaderConfigTimeout", u"menu-hidden", EFI_VARIABLE_NON_VOLATILE);
|
||||
break;
|
||||
default:
|
||||
efivar_set_uint_string(LOADER_GUID, L"LoaderConfigTimeout",
|
||||
config->timeout_sec_efivar, EFI_VARIABLE_NON_VOLATILE);
|
||||
}
|
||||
}
|
||||
|
||||
clear_screen(COLOR_NORMAL);
|
||||
|
@ -1532,6 +1541,34 @@ static void config_entry_add_type1(
|
|||
TAKE_PTR(entry);
|
||||
}
|
||||
|
||||
static EFI_STATUS efivar_get_timeout(const char16_t *var, uint32_t *ret_value) {
|
||||
_cleanup_free_ char16_t *value = NULL;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(var);
|
||||
assert(ret_value);
|
||||
|
||||
err = efivar_get(LOADER_GUID, var, &value);
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
if (streq16(value, u"menu-force")) {
|
||||
*ret_value = TIMEOUT_MENU_FORCE;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
if (streq16(value, u"menu-hidden")) {
|
||||
*ret_value = TIMEOUT_MENU_HIDDEN;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
uint64_t timeout;
|
||||
if (!parse_number16(value, &timeout, NULL))
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
*ret_value = MIN(timeout, TIMEOUT_TYPE_MAX);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
static void config_load_defaults(Config *config, EFI_FILE *root_dir) {
|
||||
_cleanup_free_ char *content = NULL;
|
||||
UINTN value;
|
||||
|
@ -1557,20 +1594,20 @@ static void config_load_defaults(Config *config, EFI_FILE *root_dir) {
|
|||
if (err == EFI_SUCCESS)
|
||||
config_defaults_load_from_file(config, content);
|
||||
|
||||
err = efivar_get_uint_string(LOADER_GUID, L"LoaderConfigTimeout", &value);
|
||||
if (err == EFI_SUCCESS) {
|
||||
config->timeout_sec_efivar = MIN(value, TIMEOUT_TYPE_MAX);
|
||||
err = efivar_get_timeout(u"LoaderConfigTimeout", &config->timeout_sec_efivar);
|
||||
if (err == EFI_SUCCESS)
|
||||
config->timeout_sec = config->timeout_sec_efivar;
|
||||
}
|
||||
else if (err != EFI_NOT_FOUND)
|
||||
log_error_stall(u"Error reading LoaderConfigTimeout EFI variable: %r", err);
|
||||
|
||||
err = efivar_get_uint_string(LOADER_GUID, L"LoaderConfigTimeoutOneShot", &value);
|
||||
err = efivar_get_timeout(u"LoaderConfigTimeoutOneShot", &config->timeout_sec);
|
||||
if (err == EFI_SUCCESS) {
|
||||
/* Unset variable now, after all it's "one shot". */
|
||||
(void) efivar_set(LOADER_GUID, L"LoaderConfigTimeoutOneShot", NULL, EFI_VARIABLE_NON_VOLATILE);
|
||||
|
||||
config->timeout_sec = MIN(value, TIMEOUT_TYPE_MAX);
|
||||
config->force_menu = true; /* force the menu when this is set */
|
||||
}
|
||||
} else if (err != EFI_NOT_FOUND)
|
||||
log_error_stall(u"Error reading LoaderConfigTimeoutOneShot EFI variable: %r", err);
|
||||
|
||||
err = efivar_get_uint_string(LOADER_GUID, L"LoaderConfigConsoleMode", &value);
|
||||
if (err == EFI_SUCCESS)
|
||||
|
|
Loading…
Reference in a new issue