From 3be6ab5c117c00e02b5d62a97c34c4a9290c21ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 6 Oct 2023 17:58:41 +0200 Subject: [PATCH 1/9] basic/macro.h: move a bunch of stuff to macro-fundamental.h We should start using this functionality in src/boot/efi/ too. --- src/basic/macro.h | 74 +---------------------------- src/fundamental/macro-fundamental.h | 72 ++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 73 deletions(-) diff --git a/src/basic/macro.h b/src/basic/macro.h index 7f650d0719..dcd1ca96fd 100644 --- a/src/basic/macro.h +++ b/src/basic/macro.h @@ -30,31 +30,6 @@ #define _function_no_sanitize_float_cast_overflow_ #endif -/* Temporarily disable some warnings */ -#define DISABLE_WARNING_DEPRECATED_DECLARATIONS \ - _Pragma("GCC diagnostic push"); \ - _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") - -#define DISABLE_WARNING_FORMAT_NONLITERAL \ - _Pragma("GCC diagnostic push"); \ - _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"") - -#define DISABLE_WARNING_MISSING_PROTOTYPES \ - _Pragma("GCC diagnostic push"); \ - _Pragma("GCC diagnostic ignored \"-Wmissing-prototypes\"") - -#define DISABLE_WARNING_NONNULL \ - _Pragma("GCC diagnostic push"); \ - _Pragma("GCC diagnostic ignored \"-Wnonnull\"") - -#define DISABLE_WARNING_SHADOW \ - _Pragma("GCC diagnostic push"); \ - _Pragma("GCC diagnostic ignored \"-Wshadow\"") - -#define DISABLE_WARNING_INCOMPATIBLE_POINTER_TYPES \ - _Pragma("GCC diagnostic push"); \ - _Pragma("GCC diagnostic ignored \"-Wincompatible-pointer-types\"") - #if HAVE_WSTRINGOP_TRUNCATION # define DISABLE_WARNING_STRINGOP_TRUNCATION \ _Pragma("GCC diagnostic push"); \ @@ -64,18 +39,7 @@ _Pragma("GCC diagnostic push") #endif -#define DISABLE_WARNING_TYPE_LIMITS \ - _Pragma("GCC diagnostic push"); \ - _Pragma("GCC diagnostic ignored \"-Wtype-limits\"") - -#define DISABLE_WARNING_ADDRESS \ - _Pragma("GCC diagnostic push"); \ - _Pragma("GCC diagnostic ignored \"-Waddress\"") - -#define REENABLE_WARNING \ - _Pragma("GCC diagnostic pop") - -/* automake test harness */ +/* test harness */ #define EXIT_TEST_SKIP 77 /* builtins */ @@ -310,42 +274,6 @@ static inline int __coverity_check_and_return__(int condition) { #define FOREACH_ARRAY(i, array, num) \ _FOREACH_ARRAY(i, array, num, UNIQ_T(m, UNIQ), UNIQ_T(end, UNIQ)) -/* A wrapper for 'func' to return void. - * Only useful when a void-returning function is required by some API. */ -#define DEFINE_TRIVIAL_DESTRUCTOR(name, type, func) \ - static inline void name(type *p) { \ - func(p); \ - } - -/* When func() returns the void value (NULL, -1, …) of the appropriate type */ -#define DEFINE_TRIVIAL_CLEANUP_FUNC(type, func) \ - static inline void func##p(type *p) { \ - if (*p) \ - *p = func(*p); \ - } - -/* When func() doesn't return the appropriate type, set variable to empty afterwards. - * The func() may be provided by a dynamically loaded shared library, hence add an assertion. */ -#define DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(type, func, empty) \ - static inline void func##p(type *p) { \ - if (*p != (empty)) { \ - DISABLE_WARNING_ADDRESS; \ - assert(func); \ - REENABLE_WARNING; \ - func(*p); \ - *p = (empty); \ - } \ - } - -/* When func() doesn't return the appropriate type, and is also a macro, set variable to empty afterwards. */ -#define DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_MACRO(type, func, empty) \ - static inline void func##p(type *p) { \ - if (*p != (empty)) { \ - func(*p); \ - *p = (empty); \ - } \ - } - #define _DEFINE_TRIVIAL_REF_FUNC(type, name, scope) \ scope type *name##_ref(type *p) { \ if (!p) \ diff --git a/src/fundamental/macro-fundamental.h b/src/fundamental/macro-fundamental.h index 8063f020f8..fa9aeafb98 100644 --- a/src/fundamental/macro-fundamental.h +++ b/src/fundamental/macro-fundamental.h @@ -11,6 +11,42 @@ #include #include +/* Temporarily disable some warnings */ +#define DISABLE_WARNING_DEPRECATED_DECLARATIONS \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") + +#define DISABLE_WARNING_FORMAT_NONLITERAL \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"") + +#define DISABLE_WARNING_MISSING_PROTOTYPES \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wmissing-prototypes\"") + +#define DISABLE_WARNING_NONNULL \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wnonnull\"") + +#define DISABLE_WARNING_SHADOW \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wshadow\"") + +#define DISABLE_WARNING_INCOMPATIBLE_POINTER_TYPES \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wincompatible-pointer-types\"") + +#define DISABLE_WARNING_TYPE_LIMITS \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wtype-limits\"") + +#define DISABLE_WARNING_ADDRESS \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Waddress\"") + +#define REENABLE_WARNING \ + _Pragma("GCC diagnostic pop") + #define _align_(x) __attribute__((__aligned__(x))) #define _alignas_(x) __attribute__((__aligned__(alignof(x)))) #define _alignptr_ __attribute__((__aligned__(sizeof(void *)))) @@ -384,6 +420,42 @@ static inline size_t ALIGN_TO(size_t l, size_t ali) { #define FLAGS_SET(v, flags) \ ((~(v) & (flags)) == 0) +/* A wrapper for 'func' to return void. + * Only useful when a void-returning function is required by some API. */ +#define DEFINE_TRIVIAL_DESTRUCTOR(name, type, func) \ + static inline void name(type *p) { \ + func(p); \ + } + +/* When func() returns the void value (NULL, -1, …) of the appropriate type */ +#define DEFINE_TRIVIAL_CLEANUP_FUNC(type, func) \ + static inline void func##p(type *p) { \ + if (*p) \ + *p = func(*p); \ + } + +/* When func() doesn't return the appropriate type, set variable to empty afterwards. + * The func() may be provided by a dynamically loaded shared library, hence add an assertion. */ +#define DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(type, func, empty) \ + static inline void func##p(type *p) { \ + if (*p != (empty)) { \ + DISABLE_WARNING_ADDRESS; \ + assert(func); \ + REENABLE_WARNING; \ + func(*p); \ + *p = (empty); \ + } \ + } + +/* When func() doesn't return the appropriate type, and is also a macro, set variable to empty afterwards. */ +#define DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_MACRO(type, func, empty) \ + static inline void func##p(type *p) { \ + if (*p != (empty)) { \ + func(*p); \ + *p = (empty); \ + } \ + } + /* Declare a flexible array usable in a union. * This is essentially a work-around for a pointless constraint in C99 * and might go away in some future version of the standard. From c650bbb8a3296fc4a60bb77d8c417948526621b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 6 Oct 2023 18:11:03 +0200 Subject: [PATCH 2/9] efi/boot: use DEFINE_TRIVIAL_CLEANUP_FUNC() in one more place No functional change. --- src/boot/efi/boot.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index de801ceb37..f04971ebd6 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -1117,9 +1117,9 @@ static void config_add_entry(Config *config, ConfigEntry *entry) { config->entries[config->n_entries++] = entry; } -static void config_entry_free(ConfigEntry *entry) { +static ConfigEntry* config_entry_free(ConfigEntry *entry) { if (!entry) - return; + return NULL; free(entry->id); free(entry->title_show); @@ -1134,12 +1134,11 @@ static void config_entry_free(ConfigEntry *entry) { free(entry->path); free(entry->current_name); free(entry->next_name); - free(entry); + + return mfree(entry); } -static void config_entry_freep(ConfigEntry **entry) { - config_entry_free(*entry); -} +DEFINE_TRIVIAL_CLEANUP_FUNC(ConfigEntry *, config_entry_free); static char *line_get_key_value( char *content, From 6ad3dc409b5121bc5ec3a949001b8eab3405993c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 6 Oct 2023 18:46:28 +0200 Subject: [PATCH 3/9] man: use consistent label for "Reboot Into Firmware Interface" That is what sd-boot actually displays. --- NEWS | 3 ++- man/loader.conf.xml | 6 +++--- man/systemd-boot.xml | 3 ++- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index 6cf2a0d937..7ab2c88db9 100644 --- a/NEWS +++ b/NEWS @@ -5764,7 +5764,8 @@ CHANGES WITH 246: started automatically as part of the desktop session. * "bootctl" gained a new verb "reboot-to-firmware" that may be used - to query and change the firmware's 'reboot into firmware' setup flag. + to query and change the firmware's 'Reboot Into Firmware Interface' + setup flag. * systemd-firstboot gained a new switch --kernel-command-line= that may be used to initialize the /etc/kernel/cmdline file of the image. It diff --git a/man/loader.conf.xml b/man/loader.conf.xml index 748276c9cf..a94f09c1ad 100644 --- a/man/loader.conf.xml +++ b/man/loader.conf.xml @@ -243,9 +243,9 @@ auto-firmware - A boolean controlling the presence of the "Reboot into firmware" entry - (enabled by default). If this is disabled, the firmware interface may still be reached - by using the f key. + A boolean controlling the presence of the Reboot Into Firmware + Interface entry (enabled by default). If this is disabled, the firmware interface may still + be reached by using the f key. diff --git a/man/systemd-boot.xml b/man/systemd-boot.xml index b6efd8927c..2b0ea9be34 100644 --- a/man/systemd-boot.xml +++ b/man/systemd-boot.xml @@ -54,7 +54,8 @@ The EFI Shell binary, if installed. - A reboot into the UEFI firmware setup option, if supported by the firmware. + A Reboot Into Firmware Interface option, if supported by the UEFI + firmware. Secure Boot variables enrollment if the UEFI firmware is in setup-mode and files are provided on the ESP. From 56747a1f13e4c7314aeb31f2da30f7ddac175105 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 7 Oct 2023 14:00:42 +0200 Subject: [PATCH 4/9] sd-boot: when rebooting or powering off, save config state The menu_run() function allows the user to set/unset default entry, or to increase/decrease menu timeout. After a keypress, status like "Menu timeout set to 5 s" is printed, but there actually isn't any immediate effect. The value is only written right right before booting a menu entry to avoid unnecessary wear&tear on the nvram storage. This delayed write is supposed to be invisible to the user. Nevertheless, operations like reboot into firmware, reboot, or shutdown were done immediately. We need to exit the loop first, save the state, and only do the op afterwards. Fixup for f6531b11d21931b3952d566ceded672ba21681cc and e6cab77eca8f6556f381c348b0452b526a752ab7. Also reverts 498d0cc426afc13fdadb0a385fd16c005645e0cf. --- src/boot/efi/boot.c | 89 ++++++++++++++++++++++++++++++--------------- 1 file changed, 60 insertions(+), 29 deletions(-) diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index f04971ebd6..2adfb5b722 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -139,6 +139,8 @@ static bool line_edit(char16_t **line_in, size_t x_max, size_t y_pos) { _cleanup_free_ char16_t *line = NULL, *print = NULL; size_t size, len, first = 0, cursor = 0, clear = 0; + /* Edit the line and return true if it should be executed, false if not. */ + assert(line_in); len = strlen16(*line_in); @@ -604,34 +606,39 @@ static void print_status(Config *config, char16_t *loaded_image_path) { } } -static EFI_STATUS reboot_into_firmware(void) { +static EFI_STATUS set_reboot_into_firmware(void) { uint64_t osind = 0; EFI_STATUS err; - if (!FLAGS_SET(get_os_indications_supported(), EFI_OS_INDICATIONS_BOOT_TO_FW_UI)) - return log_error_status(EFI_UNSUPPORTED, "Reboot to firmware interface not supported."); - (void) efivar_get_uint64_le(MAKE_GUID_PTR(EFI_GLOBAL_VARIABLE), u"OsIndications", &osind); osind |= EFI_OS_INDICATIONS_BOOT_TO_FW_UI; err = efivar_set_uint64_le(MAKE_GUID_PTR(EFI_GLOBAL_VARIABLE), u"OsIndications", osind, EFI_VARIABLE_NON_VOLATILE); if (err != EFI_SUCCESS) - return log_error_status(err, "Error setting OsIndications: %m"); - - RT->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL); - assert_not_reached(); + log_error_status(err, "Error setting OsIndications: %m"); + return err; } -static EFI_STATUS poweroff_system(void) { +_noreturn_ static EFI_STATUS poweroff_system(void) { RT->ResetSystem(EfiResetShutdown, EFI_SUCCESS, 0, NULL); assert_not_reached(); } -static EFI_STATUS reboot_system(void) { +_noreturn_ static EFI_STATUS reboot_system(void) { RT->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL); assert_not_reached(); } +static EFI_STATUS reboot_into_firmware(void) { + EFI_STATUS err; + + err = set_reboot_into_firmware(); + if (err != EFI_SUCCESS) + return err; + + return reboot_system(); +} + static bool menu_run( Config *config, ConfigEntry **chosen_entry, @@ -651,10 +658,18 @@ static bool menu_run( _cleanup_free_ char16_t *clearline = NULL, *separator = NULL, *status = NULL; uint32_t timeout_efivar_saved = config->timeout_sec_efivar; uint32_t timeout_remain = config->timeout_sec == TIMEOUT_MENU_FORCE ? 0 : config->timeout_sec; - bool exit = false, run = true, firmware_setup = false; int64_t console_mode_initial = ST->ConOut->Mode->Mode, console_mode_efivar_saved = config->console_mode_efivar; size_t default_efivar_saved = config->idx_default_efivar; + enum { + ACTION_CONTINUE, /* Continue with loop over user input */ + ACTION_FIRMWARE_SETUP, /* Ask for confirmation and reboot into firmware setup */ + ACTION_POWEROFF, /* Power off the machine */ + ACTION_REBOOT, /* Reboot the machine */ + ACTION_RUN, /* Execute a boot entry */ + ACTION_QUIT, /* Return to the firmware */ + } action = ACTION_CONTINUE; + graphics_mode(false); ST->ConIn->Reset(ST->ConIn, false); ST->ConOut->EnableCursor(ST->ConOut, false); @@ -670,7 +685,7 @@ static bool menu_run( } size_t line_width = 0, entry_padding = 3; - while (!exit) { + while (IN_SET(action, ACTION_CONTINUE, ACTION_FIRMWARE_SETUP)) { uint64_t key; if (new_mode) { @@ -817,7 +832,7 @@ static bool menu_run( assert(timeout_remain > 0); timeout_remain--; if (timeout_remain == 0) { - exit = true; + action = ACTION_RUN; break; } @@ -825,7 +840,7 @@ static bool menu_run( continue; } if (err != EFI_SUCCESS) { - exit = true; + action = ACTION_RUN; break; } @@ -836,10 +851,13 @@ static bool menu_run( idx_highlight_prev = idx_highlight; - if (firmware_setup) { - firmware_setup = false; - if (IN_SET(key, KEYPRESS(0, 0, '\r'), KEYPRESS(0, 0, '\n'))) - (void) reboot_into_firmware(); + if (action == ACTION_FIRMWARE_SETUP) { + if (IN_SET(key, KEYPRESS(0, 0, '\r'), KEYPRESS(0, 0, '\n')) && + set_reboot_into_firmware() == EFI_SUCCESS) + break; + + /* Any key other than newline or a failed attempt cancel the request. */ + action = ACTION_CONTINUE; continue; } @@ -892,7 +910,7 @@ static bool menu_run( case KEYPRESS(0, SCAN_F3, 0): /* EZpad Mini 4s firmware sends malformed events */ case KEYPRESS(0, SCAN_F3, '\r'): /* Teclast X98+ II firmware sends malformed events */ case KEYPRESS(0, SCAN_RIGHT, 0): - exit = true; + action = ACTION_RUN; break; case KEYPRESS(0, SCAN_F1, 0): @@ -906,8 +924,7 @@ static bool menu_run( break; case KEYPRESS(0, 0, 'Q'): - exit = true; - run = false; + action = ACTION_QUIT; break; case KEYPRESS(0, 0, 'd'): @@ -961,7 +978,8 @@ static bool menu_run( * Since we cannot paint the last character of the edit line, we simply start * at x-offset 1 for symmetry. */ print_at(1, y_status, COLOR_EDIT, clearline + 2); - exit = line_edit(&config->entries[idx_highlight]->options, x_max - 2, y_status); + if (line_edit(&config->entries[idx_highlight]->options, x_max - 2, y_status)) + action = ACTION_RUN; print_at(1, y_status, COLOR_NORMAL, clearline + 2); /* The options string was now edited, hence we have to pass it to the invoked @@ -1027,19 +1045,20 @@ static bool menu_run( case KEYPRESS(0, SCAN_DELETE, 0): /* Same as F2. */ case KEYPRESS(0, SCAN_ESC, 0): /* HP. */ if (FLAGS_SET(get_os_indications_supported(), EFI_OS_INDICATIONS_BOOT_TO_FW_UI)) { - firmware_setup = true; + action = ACTION_FIRMWARE_SETUP; /* Let's make sure the user really wants to do this. */ status = xstrdup16(u"Press Enter to reboot into firmware interface."); } else status = xstrdup16(u"Reboot into firmware interface not supported."); break; - case KEYPRESS(0, 0, 'O'): /* Only uppercase, so that it can't be hit so easily fat-fingered, but still works safely over serial */ - (void) poweroff_system(); + case KEYPRESS(0, 0, 'O'): /* Only uppercase, so that it can't be hit so easily fat-fingered, + * but still works safely over serial. */ + action = ACTION_POWEROFF; break; case KEYPRESS(0, 0, 'B'): /* ditto */ - (void) reboot_system(); + action = ACTION_REBOOT; break; default: @@ -1065,8 +1084,6 @@ static bool menu_run( highlight = true; } - *chosen_entry = config->entries[idx_highlight]; - /* Update EFI vars after we left the menu to reduce NVRAM writes. */ if (default_efivar_saved != config->idx_default_efivar) @@ -1097,8 +1114,22 @@ static bool menu_run( } } + switch (action) { + case ACTION_CONTINUE: + assert_not_reached(); + case ACTION_POWEROFF: + poweroff_system(); + case ACTION_REBOOT: + case ACTION_FIRMWARE_SETUP: + reboot_system(); + case ACTION_RUN: + case ACTION_QUIT: + break; + } + + *chosen_entry = config->entries[idx_highlight]; clear_screen(COLOR_NORMAL); - return run; + return action == ACTION_RUN; } static void config_add_entry(Config *config, ConfigEntry *entry) { From 1f6dbf7021856a6d5c87dc52baf0534d93f28806 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 8 Oct 2023 12:24:29 +0200 Subject: [PATCH 5/9] efi/boot: split out helper to reduce duplicate formatting code No functional change. --- src/boot/efi/boot.c | 40 +++++++++++++++------------------------- 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index 2adfb5b722..6c0d41c684 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -442,6 +442,19 @@ static bool ps_continue(void) { !IN_SET(key, KEYPRESS(0, SCAN_ESC, 0), KEYPRESS(0, 0, 'q'), KEYPRESS(0, 0, 'Q')); } +static void print_timeout_status(const char *label, uint32_t t) { + switch (t) { + case TIMEOUT_UNSET: + return; + case TIMEOUT_MENU_FORCE: + return (void) printf("%s: menu-force\n", label); + case TIMEOUT_MENU_HIDDEN: + return (void) printf("%s: menu-hidden\n", label); + default: + return (void) printf("%s: %u s\n", label, t); + } +} + static void print_status(Config *config, char16_t *loaded_image_path) { size_t x_max, y_max; uint32_t screen_width = 0, screen_height = 0; @@ -479,31 +492,8 @@ static void print_status(Config *config, char16_t *loaded_image_path) { if (!ps_continue()) return; - switch (config->timeout_sec_config) { - case TIMEOUT_UNSET: - break; - case TIMEOUT_MENU_FORCE: - printf(" timeout (config): menu-force\n"); - break; - case TIMEOUT_MENU_HIDDEN: - printf(" timeout (config): menu-hidden\n"); - break; - default: - printf(" timeout (config): %u s\n", config->timeout_sec_config); - } - - switch (config->timeout_sec_efivar) { - case TIMEOUT_UNSET: - break; - case TIMEOUT_MENU_FORCE: - printf(" timeout (EFI var): menu-force\n"); - break; - case TIMEOUT_MENU_HIDDEN: - printf(" timeout (EFI var): menu-hidden\n"); - break; - default: - printf(" timeout (EFI var): %u s\n", config->timeout_sec_efivar); - } + print_timeout_status(" timeout (config)", config->timeout_sec_config); + print_timeout_status(" timeout (EFI var)", config->timeout_sec_efivar); if (config->entry_default_config) printf(" default (config): %ls\n", config->entry_default_config); From 1cd26e5e56e1b407d62374f98bab2dd0a531a486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 8 Oct 2023 12:33:43 +0200 Subject: [PATCH 6/9] efi/boot: make timeout changes relative to current value When the user pressed + or -, we would set the efivar override, starting from the default of 0. Instead, set an override that starts at the current value. This means that when user has e.g. a configured override of 5 s, and they press +, they get an override of 6 s. I think this is leads to a much smoother experience for a user, who does not necessarilly need to know that we have three levels of overrides, they just want to easily configure the timeout with keys. If they press +, the timeout should increase, and not jump to some low value. Also, once an override has been set via the boot menu, i.e. the efivar is set, do not allow unsetting the efivar from the boot menu. This way we also avoid an unexpected "jump" to whatever the other sources of configuration specify. The user can configure any value with the keys that they want, so we don't need to allow unsetting. --- src/boot/efi/boot.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index 6c0d41c684..403858ba1e 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -390,27 +390,29 @@ static size_t entry_lookup_key(Config *config, size_t start, char16_t key) { return IDX_INVALID; } -static char16_t *update_timeout_efivar(uint32_t *t, bool inc) { - assert(t); +static char16_t* update_timeout_efivar(Config *config, bool inc) { + assert(config); - switch (*t) { + switch (config->timeout_sec) { case TIMEOUT_MAX: - *t = inc ? TIMEOUT_MAX : (*t - 1); + config->timeout_sec = inc ? TIMEOUT_MAX : config->timeout_sec - 1; break; case TIMEOUT_UNSET: - *t = inc ? TIMEOUT_MENU_FORCE : TIMEOUT_UNSET; + config->timeout_sec = inc ? TIMEOUT_MENU_FORCE : TIMEOUT_UNSET; break; case TIMEOUT_MENU_FORCE: - *t = inc ? TIMEOUT_MENU_HIDDEN : TIMEOUT_UNSET; + config->timeout_sec = inc ? TIMEOUT_MENU_HIDDEN : TIMEOUT_MENU_FORCE; break; case TIMEOUT_MENU_HIDDEN: - *t = inc ? TIMEOUT_MIN : TIMEOUT_MENU_FORCE; + config->timeout_sec = inc ? TIMEOUT_MIN : TIMEOUT_MENU_FORCE; break; default: - *t += inc ? 1 : -1; + config->timeout_sec = config->timeout_sec + (inc ? 1 : -1); } - switch (*t) { + config->timeout_sec_efivar = config->timeout_sec; + + switch (config->timeout_sec) { case TIMEOUT_UNSET: return xstrdup16(u"Menu timeout defined by configuration file."); case TIMEOUT_MENU_FORCE: @@ -418,7 +420,7 @@ static char16_t *update_timeout_efivar(uint32_t *t, bool inc) { case TIMEOUT_MENU_HIDDEN: return xstrdup16(u"Menu disabled. Hold down key at bootup to show menu."); default: - return xasprintf("Menu timeout set to %u s.", *t); + return xasprintf("Menu timeout set to %u s.", config->timeout_sec_efivar); } } @@ -935,12 +937,12 @@ static bool menu_run( case KEYPRESS(0, 0, '-'): case KEYPRESS(0, 0, 'T'): - status = update_timeout_efivar(&config->timeout_sec_efivar, false); + status = update_timeout_efivar(config, false); break; case KEYPRESS(0, 0, '+'): case KEYPRESS(0, 0, 't'): - status = update_timeout_efivar(&config->timeout_sec_efivar, true); + status = update_timeout_efivar(config, true); break; case KEYPRESS(0, 0, 'e'): From a7af63f1307bf7bde7428afaa63df67915a86f98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 8 Oct 2023 13:10:47 +0200 Subject: [PATCH 7/9] efi/boot: use "else if" instead of explicit "continue" No functional change. --- src/boot/efi/boot.c | 127 ++++++++++++-------------------------------- 1 file changed, 34 insertions(+), 93 deletions(-) diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index 403858ba1e..e9a0060c33 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -1246,7 +1246,7 @@ static void config_defaults_load_from_file(Config *config, char *content) { assert(config); assert(content); - while ((line = line_get_key_value(content, " \t", &pos, &key, &value))) { + while ((line = line_get_key_value(content, " \t", &pos, &key, &value))) if (streq8(key, "timeout")) { if (streq8( value, "menu-force")) config->timeout_sec_config = TIMEOUT_MENU_FORCE; @@ -1262,69 +1262,52 @@ static void config_defaults_load_from_file(Config *config, char *content) { config->timeout_sec_config = u; } config->timeout_sec = config->timeout_sec_config; - continue; - } - if (streq8(key, "default")) { + } else if (streq8(key, "default")) { if (value[0] == '@' && !strcaseeq8(value, "@saved")) { log_error("Unsupported special entry identifier, ignoring: %s", value); continue; } free(config->entry_default_config); config->entry_default_config = xstr8_to_16(value); - continue; - } - if (streq8(key, "editor")) { + } else if (streq8(key, "editor")) { err = parse_boolean(value, &config->editor); if (err != EFI_SUCCESS) log_error("Error parsing 'editor' config option, ignoring: %s", value); - continue; - } - if (streq8(key, "auto-entries")) { + } else if (streq8(key, "auto-entries")) { err = parse_boolean(value, &config->auto_entries); if (err != EFI_SUCCESS) log_error("Error parsing 'auto-entries' config option, ignoring: %s", value); - continue; - } - if (streq8(key, "auto-firmware")) { + } else if (streq8(key, "auto-firmware")) { err = parse_boolean(value, &config->auto_firmware); if (err != EFI_SUCCESS) log_error("Error parsing 'auto-firmware' config option, ignoring: %s", value); - continue; - } - if (streq8(key, "auto-poweroff")) { + } else if (streq8(key, "auto-poweroff")) { err = parse_boolean(value, &config->auto_poweroff); if (err != EFI_SUCCESS) log_error("Error parsing 'auto-poweroff' config option, ignoring: %s", value); - continue; - } - if (streq8(key, "auto-reboot")) { + } else if (streq8(key, "auto-reboot")) { err = parse_boolean(value, &config->auto_reboot); if (err != EFI_SUCCESS) log_error("Error parsing 'auto-reboot' config option, ignoring: %s", value); - continue; - } - if (streq8(key, "beep")) { + } else if (streq8(key, "beep")) { err = parse_boolean(value, &config->beep); if (err != EFI_SUCCESS) log_error("Error parsing 'beep' config option, ignoring: %s", value); - continue; - } - if (streq8(key, "reboot-for-bitlocker")) { + } else if (streq8(key, "reboot-for-bitlocker")) { err = parse_boolean(value, &config->reboot_for_bitlocker); if (err != EFI_SUCCESS) log_error("Error parsing 'reboot-for-bitlocker' config option, ignoring: %s", value); - } - if (streq8(key, "secure-boot-enroll")) { + } else if (streq8(key, "secure-boot-enroll")) { if (streq8(value, "manual")) config->secure_boot_enroll = ENROLL_MANUAL; else if (streq8(value, "force")) @@ -1336,10 +1319,8 @@ static void config_defaults_load_from_file(Config *config, char *content) { else log_error("Error parsing 'secure-boot-enroll' config option, ignoring: %s", value); - continue; - } - if (streq8(key, "console-mode")) { + } else if (streq8(key, "console-mode")) { if (streq8(value, "auto")) config->console_mode = CONSOLE_MODE_AUTO; else if (streq8(value, "max")) @@ -1355,9 +1336,7 @@ static void config_defaults_load_from_file(Config *config, char *content) { } config->console_mode = u; } - continue; } - } } static void config_entry_parse_tries( @@ -1508,40 +1487,30 @@ static void config_entry_add_type1( .tries_left = -1, }; - while ((line = line_get_key_value(content, " \t", &pos, &key, &value))) { + while ((line = line_get_key_value(content, " \t", &pos, &key, &value))) if (streq8(key, "title")) { free(entry->title); entry->title = xstr8_to_16(value); - continue; - } - if (streq8(key, "sort-key")) { + } else if (streq8(key, "sort-key")) { free(entry->sort_key); entry->sort_key = xstr8_to_16(value); - continue; - } - if (streq8(key, "version")) { + } else if (streq8(key, "version")) { free(entry->version); entry->version = xstr8_to_16(value); - continue; - } - if (streq8(key, "machine-id")) { + } else if (streq8(key, "machine-id")) { free(entry->machine_id); entry->machine_id = xstr8_to_16(value); - continue; - } - if (streq8(key, "linux")) { + } else if (streq8(key, "linux")) { free(entry->loader); entry->type = LOADER_LINUX; entry->loader = xstr8_to_path(value); entry->key = 'l'; - continue; - } - if (streq8(key, "efi")) { + } else if (streq8(key, "efi")) { entry->type = LOADER_EFI; free(entry->loader); entry->loader = xstr8_to_path(value); @@ -1551,35 +1520,27 @@ static void config_entry_add_type1( entry->type = LOADER_UNDEFINED; break; } - continue; - } - if (streq8(key, "architecture")) { + } else if (streq8(key, "architecture")) { /* do not add an entry for an EFI image of architecture not matching with that of the image */ if (!streq8(value, EFI_MACHINE_TYPE_NAME)) { entry->type = LOADER_UNDEFINED; break; } - continue; - } - if (streq8(key, "devicetree")) { + } else if (streq8(key, "devicetree")) { free(entry->devicetree); entry->devicetree = xstr8_to_path(value); - continue; - } - if (streq8(key, "initrd")) { + } else if (streq8(key, "initrd")) { entry->initrd = xrealloc( entry->initrd, n_initrd == 0 ? 0 : (n_initrd + 1) * sizeof(uint16_t *), (n_initrd + 2) * sizeof(uint16_t *)); entry->initrd[n_initrd++] = xstr8_to_path(value); entry->initrd[n_initrd] = NULL; - continue; - } - if (streq8(key, "options")) { + } else if (streq8(key, "options")) { _cleanup_free_ char16_t *new = NULL; new = xstr8_to_16(value); @@ -1589,10 +1550,7 @@ static void config_entry_add_type1( entry->options = s; } else entry->options = TAKE_PTR(new); - - continue; } - } if (entry->type == LOADER_UNDEFINED) return; @@ -1843,12 +1801,11 @@ static void config_default_entry_select(Config *config) { } /* select the first suitable entry */ - for (i = 0; i < config->n_entries; i++) { - if (config->entries[i]->type == LOADER_AUTO || config->entries[i]->call) - continue; - config->idx_default = i; - return; - } + for (i = 0; i < config->n_entries; i++) + if (config->entries[i]->type != LOADER_AUTO && !config->entries[i]->call) { + config->idx_default = i; + return; + } /* If no configured entry to select from was found, enable the menu. */ config->idx_default = 0; @@ -2219,55 +2176,39 @@ static void config_entry_add_unified( continue; /* read properties from the embedded os-release file */ - while ((line = line_get_key_value(content, "=", &pos, &key, &value))) { + while ((line = line_get_key_value(content, "=", &pos, &key, &value))) if (streq8(key, "PRETTY_NAME")) { free(os_pretty_name); os_pretty_name = xstr8_to_16(value); - continue; - } - if (streq8(key, "IMAGE_ID")) { + } else if (streq8(key, "IMAGE_ID")) { free(os_image_id); os_image_id = xstr8_to_16(value); - continue; - } - if (streq8(key, "NAME")) { + } else if (streq8(key, "NAME")) { free(os_name); os_name = xstr8_to_16(value); - continue; - } - if (streq8(key, "ID")) { + } else if (streq8(key, "ID")) { free(os_id); os_id = xstr8_to_16(value); - continue; - } - if (streq8(key, "IMAGE_VERSION")) { + } else if (streq8(key, "IMAGE_VERSION")) { free(os_image_version); os_image_version = xstr8_to_16(value); - continue; - } - if (streq8(key, "VERSION")) { + } else if (streq8(key, "VERSION")) { free(os_version); os_version = xstr8_to_16(value); - continue; - } - if (streq8(key, "VERSION_ID")) { + } else if (streq8(key, "VERSION_ID")) { free(os_version_id); os_version_id = xstr8_to_16(value); - continue; - } - if (streq8(key, "BUILD_ID")) { + } else if (streq8(key, "BUILD_ID")) { free(os_build_id); os_build_id = xstr8_to_16(value); - continue; } - } if (!bootspec_pick_name_version_sort_key( os_pretty_name, From 64381611871fc5cba9041eb10f4d64f34571293d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 9 Oct 2023 11:14:11 +0200 Subject: [PATCH 8/9] efi/boot: adjust grammar and punctuation in comments --- src/boot/efi/boot.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index e9a0060c33..e9099a7284 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -2389,7 +2389,8 @@ static EFI_STATUS image_start( return log_error_status(err, "Error loading %ls: %m", entry->loader); /* DTBs are loaded by the kernel before ExitBootServices, and they can be used to map and assign - * arbitrary memory ranges, so skip it when secure boot is enabled as the DTB here is unverified. */ + * arbitrary memory ranges, so skip them when secure boot is enabled as the DTB here is unverified. + */ if (entry->devicetree && !secure_boot_enabled()) { err = devicetree_install(&dtstate, image_root, entry->devicetree); if (err != EFI_SUCCESS) @@ -2406,8 +2407,8 @@ static EFI_STATUS image_start( if (err != EFI_SUCCESS) return log_error_status(err, "Error getting LoadedImageProtocol handle: %m"); - /* If we had to append an initrd= entry to the command line, we have to pass it, and measure - * it. Otherwise, only pass/measure it if it is not implicit anyway (i.e. embedded into the UKI or + /* If we had to append an initrd= entry to the command line, we have to pass it, and measure it. + * Otherwise, only pass/measure it if it is not implicit anyway (i.e. embedded into the UKI or * so). */ char16_t *options = options_initrd ?: entry->options_implied ? NULL : entry->options; if (options) { @@ -2544,8 +2545,8 @@ static EFI_STATUS secure_boot_discover_keys(Config *config, EFI_FILE *root_dir) if (IN_SET(config->secure_boot_enroll, ENROLL_IF_SAFE, ENROLL_FORCE) && strcaseeq16(dirent->FileName, u"auto")) - /* if we auto enroll successfully this call does not return, if it fails we still - * want to add other potential entries to the menu */ + /* If we auto enroll successfully this call does not return. + * If it fails we still want to add other potential entries to the menu. */ secure_boot_enroll_at(root_dir, entry->path, config->secure_boot_enroll == ENROLL_FORCE); } @@ -2609,19 +2610,19 @@ static void config_load_all_entries( config_load_defaults(config, root_dir); - /* scan /EFI/Linux/ directory */ + /* Scan /EFI/Linux/ directory */ config_entry_add_unified(config, loaded_image->DeviceHandle, root_dir); - /* scan /loader/entries/\*.conf files */ + /* Scan /loader/entries/\*.conf files */ config_load_entries(config, loaded_image->DeviceHandle, root_dir, loaded_image_path); /* Similar, but on any XBOOTLDR partition */ config_load_xbootldr(config, loaded_image->DeviceHandle); - /* sort entries after version number */ + /* Sort entries after version number */ sort_pointer_array((void **) config->entries, config->n_entries, (compare_pointer_func_t) config_entry_compare); - /* if we find some well-known loaders, add them to the end of the list */ + /* If we find some well-known loaders, add them to the end of the list */ config_entry_add_osx(config); config_entry_add_windows(config, loaded_image->DeviceHandle, root_dir); config_entry_add_loader_auto(config, loaded_image->DeviceHandle, root_dir, NULL, @@ -2665,10 +2666,10 @@ static void config_load_all_entries( config_add_entry(config, entry); } - /* find if secure boot signing keys exist and autoload them if necessary - otherwise creates menu entries so that the user can load them manually - if the secure-boot-enroll variable is set to no (the default), we do not - even search for keys on the ESP */ + /* Find secure boot signing keys and autoload them if configured. + * Otherwise, create menu entries so that the user can load them manually. + * If the secure-boot-enroll variable is set to no (the default), we do not + * even search for keys on the ESP */ if (config->secure_boot_enroll != ENROLL_OFF) secure_boot_discover_keys(config, root_dir); @@ -2679,7 +2680,7 @@ static void config_load_all_entries( config_title_generate(config); - /* select entry by configured pattern or EFI LoaderDefaultEntry= variable */ + /* Select entry by configured pattern or EFI LoaderDefaultEntry= variable */ config_default_entry_select(config); } From 0502bd7e5e916f54d2032fe2f2d900d26c12b90b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 10 Oct 2023 09:52:14 +0200 Subject: [PATCH 9/9] efi/boot: rename ConfigEntry to BootEntry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some of the entries are really configured, but we also have a bunch of automatic entries. Calling them "config entries" is misleading, let's use the more natural "boot entry". While at it, rename: config_load_entries() → config_load_type1_entries() config_entry_add_unified() → config_load_type2_entries() config_title_generate() → generate_boot_entry_titles() config_entry_add_() → config_add_entry_() No functional change. --- src/boot/efi/boot.c | 138 ++++++++++++++++++++++---------------------- 1 file changed, 69 insertions(+), 69 deletions(-) diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index e9099a7284..9abb856748 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -69,10 +69,10 @@ typedef struct { char16_t *path; char16_t *current_name; char16_t *next_name; -} ConfigEntry; +} BootEntry; typedef struct { - ConfigEntry **entries; + BootEntry **entries; size_t n_entries; size_t idx_default; size_t idx_default_efivar; @@ -378,7 +378,7 @@ static size_t entry_lookup_key(Config *config, size_t start, char16_t key) { return i-1; } - /* find matching key in config entries */ + /* find matching key in boot entries */ for (size_t i = start; i < config->n_entries; i++) if (config->entries[i]->key == key) return i; @@ -553,7 +553,7 @@ static void print_status(Config *config, char16_t *loaded_image_path) { return; for (size_t i = 0; i < config->n_entries; i++) { - ConfigEntry *entry = config->entries[i]; + BootEntry *entry = config->entries[i]; EFI_DEVICE_PATH *dp = NULL; _cleanup_free_ char16_t *dp_str = NULL; @@ -562,7 +562,7 @@ static void print_status(Config *config, char16_t *loaded_image_path) { EFI_SUCCESS) (void) device_path_to_str(dp, &dp_str); - printf(" config entry: %zu/%zu\n", i + 1, config->n_entries); + printf(" boot entry: %zu/%zu\n", i + 1, config->n_entries); printf(" id: %ls\n", entry->id); if (entry->title) printf(" title: %ls\n", entry->title); @@ -633,7 +633,7 @@ static EFI_STATUS reboot_into_firmware(void) { static bool menu_run( Config *config, - ConfigEntry **chosen_entry, + BootEntry **chosen_entry, char16_t *loaded_image_path) { assert(config); @@ -1124,7 +1124,7 @@ static bool menu_run( return action == ACTION_RUN; } -static void config_add_entry(Config *config, ConfigEntry *entry) { +static void config_add_entry(Config *config, BootEntry *entry) { assert(config); assert(entry); @@ -1140,7 +1140,7 @@ static void config_add_entry(Config *config, ConfigEntry *entry) { config->entries[config->n_entries++] = entry; } -static ConfigEntry* config_entry_free(ConfigEntry *entry) { +static BootEntry* boot_entry_free(BootEntry *entry) { if (!entry) return NULL; @@ -1161,7 +1161,7 @@ static ConfigEntry* config_entry_free(ConfigEntry *entry) { return mfree(entry); } -DEFINE_TRIVIAL_CLEANUP_FUNC(ConfigEntry *, config_entry_free); +DEFINE_TRIVIAL_CLEANUP_FUNC(BootEntry *, boot_entry_free); static char *line_get_key_value( char *content, @@ -1339,8 +1339,8 @@ static void config_defaults_load_from_file(Config *config, char *content) { } } -static void config_entry_parse_tries( - ConfigEntry *entry, +static void boot_entry_parse_tries( + BootEntry *entry, const char16_t *path, const char16_t *file, const char16_t *suffix) { @@ -1403,7 +1403,7 @@ static void config_entry_parse_tries( suffix); } -static EFI_STATUS config_entry_bump_counters(ConfigEntry *entry) { +static EFI_STATUS boot_entry_bump_counters(BootEntry *entry) { _cleanup_free_ char16_t* old_path = NULL, *new_path = NULL; _cleanup_(file_closep) EFI_FILE *handle = NULL; _cleanup_free_ EFI_FILE_INFO *file_info = NULL; @@ -1459,7 +1459,7 @@ static EFI_STATUS config_entry_bump_counters(ConfigEntry *entry) { return EFI_SUCCESS; } -static void config_entry_add_type1( +static void boot_entry_add_type1( Config *config, EFI_HANDLE *device, EFI_FILE *root_dir, @@ -1468,7 +1468,7 @@ static void config_entry_add_type1( char *content, const char16_t *loaded_image_path) { - _cleanup_(config_entry_freep) ConfigEntry *entry = NULL; + _cleanup_(boot_entry_freep) BootEntry *entry = NULL; char *line; size_t pos = 0, n_initrd = 0; char *key, *value; @@ -1481,8 +1481,8 @@ static void config_entry_add_type1( assert(file); assert(content); - entry = xnew(ConfigEntry, 1); - *entry = (ConfigEntry) { + entry = xnew(BootEntry, 1); + *entry = (BootEntry) { .tries_done = -1, .tries_left = -1, }; @@ -1567,7 +1567,7 @@ static void config_entry_add_type1( config_add_entry(config, entry); - config_entry_parse_tries(entry, path, file, u".conf"); + boot_entry_parse_tries(entry, path, file, u".conf"); TAKE_PTR(entry); } @@ -1659,7 +1659,7 @@ static void config_load_defaults(Config *config, EFI_FILE *root_dir) { (void) efivar_get(MAKE_GUID_PTR(LOADER), u"LoaderEntryLastBooted", &config->entry_saved); } -static void config_load_entries( +static void config_load_type1_entries( Config *config, EFI_HANDLE *device, EFI_FILE *root_dir, @@ -1699,11 +1699,11 @@ static void config_load_entries( err = file_read(entries_dir, f->FileName, 0, 0, &content, NULL); if (err == EFI_SUCCESS) - config_entry_add_type1(config, device, root_dir, u"\\loader\\entries", f->FileName, content, loaded_image_path); + boot_entry_add_type1(config, device, root_dir, u"\\loader\\entries", f->FileName, content, loaded_image_path); } } -static int config_entry_compare(const ConfigEntry *a, const ConfigEntry *b) { +static int boot_entry_compare(const BootEntry *a, const BootEntry *b) { int r; assert(a); @@ -1757,7 +1757,7 @@ static int config_entry_compare(const ConfigEntry *a, const ConfigEntry *b) { return CMP(a->tries_done, b->tries_done); } -static size_t config_entry_find(Config *config, const char16_t *pattern) { +static size_t config_find_entry(Config *config, const char16_t *pattern) { assert(config); /* We expect pattern and entry IDs to be already case folded. */ @@ -1772,18 +1772,18 @@ static size_t config_entry_find(Config *config, const char16_t *pattern) { return IDX_INVALID; } -static void config_default_entry_select(Config *config) { +static void config_select_default_entry(Config *config) { size_t i; assert(config); - i = config_entry_find(config, config->entry_oneshot); + i = config_find_entry(config, config->entry_oneshot); if (i != IDX_INVALID) { config->idx_default = i; return; } - i = config_entry_find(config, config->use_saved_entry_efivar ? config->entry_saved : config->entry_default_efivar); + i = config_find_entry(config, config->use_saved_entry_efivar ? config->entry_saved : config->entry_default_efivar); if (i != IDX_INVALID) { config->idx_default = i; config->idx_default_efivar = i; @@ -1792,9 +1792,9 @@ static void config_default_entry_select(Config *config) { if (config->use_saved_entry) /* No need to do the same thing twice. */ - i = config->use_saved_entry_efivar ? IDX_INVALID : config_entry_find(config, config->entry_saved); + i = config->use_saved_entry_efivar ? IDX_INVALID : config_find_entry(config, config->entry_saved); else - i = config_entry_find(config, config->entry_default_config); + i = config_find_entry(config, config->entry_default_config); if (i != IDX_INVALID) { config->idx_default = i; return; @@ -1813,7 +1813,7 @@ static void config_default_entry_select(Config *config) { config->timeout_sec = 10; } -static bool entries_unique(ConfigEntry **entries, bool *unique, size_t n_entries) { +static bool entries_unique(BootEntry **entries, bool *unique, size_t n_entries) { bool is_unique = true; assert(entries); @@ -1830,8 +1830,8 @@ static bool entries_unique(ConfigEntry **entries, bool *unique, size_t n_entries return is_unique; } -/* generate a unique title, avoiding non-distinguishable menu entries */ -static void config_title_generate(Config *config) { +/* generate unique titles, avoiding non-distinguishable menu entries */ +static void generate_boot_entry_titles(Config *config) { assert(config); bool unique[config->n_entries]; @@ -1913,7 +1913,7 @@ static bool is_sd_boot(EFI_FILE *root_dir, const char16_t *loader_path) { return memcmp(content, SD_MAGIC, sizeof(SD_MAGIC)) == 0; } -static ConfigEntry *config_entry_add_loader_auto( +static BootEntry* config_add_entry_loader_auto( Config *config, EFI_HANDLE *device, EFI_FILE *root_dir, @@ -1952,8 +1952,8 @@ static ConfigEntry *config_entry_add_loader_auto( if (err != EFI_SUCCESS) return NULL; - ConfigEntry *entry = xnew(ConfigEntry, 1); - *entry = (ConfigEntry) { + BootEntry *entry = xnew(BootEntry, 1); + *entry = (BootEntry) { .id = xstrdup16(id), .type = LOADER_AUTO, .title = xstrdup16(title), @@ -1968,7 +1968,7 @@ static ConfigEntry *config_entry_add_loader_auto( return entry; } -static void config_entry_add_osx(Config *config) { +static void config_add_entry_osx(Config *config) { EFI_STATUS err; size_t n_handles = 0; _cleanup_free_ EFI_HANDLE *handles = NULL; @@ -1989,7 +1989,7 @@ static void config_entry_add_osx(Config *config) { if (open_volume(handles[i], &root) != EFI_SUCCESS) continue; - if (config_entry_add_loader_auto( + if (config_add_entry_loader_auto( config, handles[i], root, @@ -2085,7 +2085,7 @@ static EFI_STATUS boot_windows_bitlocker(void) { } #endif -static void config_entry_add_windows(Config *config, EFI_HANDLE *device, EFI_FILE *root_dir) { +static void config_add_entry_windows(Config *config, EFI_HANDLE *device, EFI_FILE *root_dir) { #if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) _cleanup_free_ char *bcd = NULL; char16_t *title = NULL; @@ -2104,16 +2104,16 @@ static void config_entry_add_windows(Config *config, EFI_HANDLE *device, EFI_FIL if (err == EFI_SUCCESS) title = get_bcd_title((uint8_t *) bcd, len); - ConfigEntry *e = config_entry_add_loader_auto(config, device, root_dir, NULL, - u"auto-windows", 'w', title ?: u"Windows Boot Manager", - u"\\EFI\\Microsoft\\Boot\\bootmgfw.efi"); + BootEntry *e = config_add_entry_loader_auto(config, device, root_dir, NULL, + u"auto-windows", 'w', title ?: u"Windows Boot Manager", + u"\\EFI\\Microsoft\\Boot\\bootmgfw.efi"); if (config->reboot_for_bitlocker) e->call = boot_windows_bitlocker; #endif } -static void config_entry_add_unified( +static void config_load_type2_entries( Config *config, EFI_HANDLE *device, EFI_FILE *root_dir) { @@ -2224,8 +2224,8 @@ static void config_entry_add_unified( &good_sort_key)) continue; - ConfigEntry *entry = xnew(ConfigEntry, 1); - *entry = (ConfigEntry) { + BootEntry *entry = xnew(BootEntry, 1); + *entry = (BootEntry) { .id = xstrdup16(f->FileName), .type = LOADER_UNIFIED_LINUX, .title = xstrdup16(good_name), @@ -2240,7 +2240,7 @@ static void config_entry_add_unified( strtolower16(entry->id); config_add_entry(config, entry); - config_entry_parse_tries(entry, u"\\EFI\\Linux", f->FileName, u".efi"); + boot_entry_parse_tries(entry, u"\\EFI\\Linux", f->FileName, u".efi"); if (szs[SECTION_CMDLINE] == 0) continue; @@ -2273,13 +2273,13 @@ static void config_load_xbootldr( if (err != EFI_SUCCESS) return; - config_entry_add_unified(config, new_device, root_dir); - config_load_entries(config, new_device, root_dir, NULL); + config_load_type2_entries(config, new_device, root_dir); + config_load_type1_entries(config, new_device, root_dir, NULL); } static EFI_STATUS initrd_prepare( EFI_FILE *root, - const ConfigEntry *entry, + const BootEntry *entry, char16_t **ret_options, void **ret_initrd, size_t *ret_initrd_size) { @@ -2355,7 +2355,7 @@ static EFI_STATUS initrd_prepare( static EFI_STATUS image_start( EFI_HANDLE parent_image, - const ConfigEntry *entry) { + const BootEntry *entry) { _cleanup_(devicetree_cleanup) struct devicetree_state dtstate = {}; _cleanup_(unload_imagep) EFI_HANDLE image = NULL; @@ -2451,7 +2451,7 @@ static EFI_STATUS image_start( static void config_free(Config *config) { assert(config); for (size_t i = 0; i < config->n_entries; i++) - config_entry_free(config->entries[i]); + boot_entry_free(config->entries[i]); free(config->entries); free(config->entry_default_config); free(config->entry_default_efivar); @@ -2480,7 +2480,7 @@ static void config_write_entries_to_variable(Config *config) { (void) efivar_set_raw(MAKE_GUID_PTR(LOADER), u"LoaderEntries", buffer, sz, 0); } -static void save_selected_entry(const Config *config, const ConfigEntry *entry) { +static void save_selected_entry(const Config *config, const BootEntry *entry) { assert(config); assert(entry); assert(entry->loader || !entry->call); @@ -2520,7 +2520,7 @@ static EFI_STATUS secure_boot_discover_keys(Config *config, EFI_FILE *root_dir) for (;;) { _cleanup_free_ EFI_FILE_INFO *dirent = NULL; size_t dirent_size = 0; - ConfigEntry *entry = NULL; + BootEntry *entry = NULL; err = readdir(keys_basedir, &dirent, &dirent_size); if (err != EFI_SUCCESS || !dirent) @@ -2532,8 +2532,8 @@ static EFI_STATUS secure_boot_discover_keys(Config *config, EFI_FILE *root_dir) if (!FLAGS_SET(dirent->Attribute, EFI_FILE_DIRECTORY)) continue; - entry = xnew(ConfigEntry, 1); - *entry = (ConfigEntry) { + entry = xnew(BootEntry, 1); + *entry = (BootEntry) { .id = xasprintf("secure-boot-keys-%ls", dirent->FileName), .title = xasprintf("Enroll Secure Boot keys: %ls", dirent->FileName), .path = xasprintf("\\loader\\keys\\%ls", dirent->FileName), @@ -2611,28 +2611,28 @@ static void config_load_all_entries( config_load_defaults(config, root_dir); /* Scan /EFI/Linux/ directory */ - config_entry_add_unified(config, loaded_image->DeviceHandle, root_dir); + config_load_type2_entries(config, loaded_image->DeviceHandle, root_dir); /* Scan /loader/entries/\*.conf files */ - config_load_entries(config, loaded_image->DeviceHandle, root_dir, loaded_image_path); + config_load_type1_entries(config, loaded_image->DeviceHandle, root_dir, loaded_image_path); /* Similar, but on any XBOOTLDR partition */ config_load_xbootldr(config, loaded_image->DeviceHandle); /* Sort entries after version number */ - sort_pointer_array((void **) config->entries, config->n_entries, (compare_pointer_func_t) config_entry_compare); + sort_pointer_array((void **) config->entries, config->n_entries, (compare_pointer_func_t) boot_entry_compare); /* If we find some well-known loaders, add them to the end of the list */ - config_entry_add_osx(config); - config_entry_add_windows(config, loaded_image->DeviceHandle, root_dir); - config_entry_add_loader_auto(config, loaded_image->DeviceHandle, root_dir, NULL, + config_add_entry_osx(config); + config_add_entry_windows(config, loaded_image->DeviceHandle, root_dir); + config_add_entry_loader_auto(config, loaded_image->DeviceHandle, root_dir, NULL, u"auto-efi-shell", 's', u"EFI Shell", u"\\shell" EFI_MACHINE_TYPE_NAME ".efi"); - config_entry_add_loader_auto(config, loaded_image->DeviceHandle, root_dir, loaded_image_path, + config_add_entry_loader_auto(config, loaded_image->DeviceHandle, root_dir, loaded_image_path, u"auto-efi-default", '\0', u"EFI Default Loader", NULL); if (config->auto_firmware && FLAGS_SET(get_os_indications_supported(), EFI_OS_INDICATIONS_BOOT_TO_FW_UI)) { - ConfigEntry *entry = xnew(ConfigEntry, 1); - *entry = (ConfigEntry) { + BootEntry *entry = xnew(BootEntry, 1); + *entry = (BootEntry) { .id = xstrdup16(u"auto-reboot-to-firmware-setup"), .title = xstrdup16(u"Reboot Into Firmware Interface"), .call = reboot_into_firmware, @@ -2643,8 +2643,8 @@ static void config_load_all_entries( } if (config->auto_poweroff) { - ConfigEntry *entry = xnew(ConfigEntry, 1); - *entry = (ConfigEntry) { + BootEntry *entry = xnew(BootEntry, 1); + *entry = (BootEntry) { .id = xstrdup16(u"auto-poweroff"), .title = xstrdup16(u"Power Off The System"), .call = poweroff_system, @@ -2655,8 +2655,8 @@ static void config_load_all_entries( } if (config->auto_reboot) { - ConfigEntry *entry = xnew(ConfigEntry, 1); - *entry = (ConfigEntry) { + BootEntry *entry = xnew(BootEntry, 1); + *entry = (BootEntry) { .id = xstrdup16(u"auto-reboot"), .title = xstrdup16(u"Reboot The System"), .call = reboot_system, @@ -2678,10 +2678,10 @@ static void config_load_all_entries( config_write_entries_to_variable(config); - config_title_generate(config); + generate_boot_entry_titles(config); /* Select entry by configured pattern or EFI LoaderDefaultEntry= variable */ - config_default_entry_select(config); + config_select_default_entry(config); } static EFI_STATUS discover_root_dir(EFI_LOADED_IMAGE_PROTOCOL *loaded_image, EFI_FILE **ret_dir) { @@ -2736,7 +2736,7 @@ static EFI_STATUS run(EFI_HANDLE image) { /* Block up to 100ms to give firmware time to get input working. */ err = console_key_read(&key, 100 * 1000); if (err == EFI_SUCCESS) { - /* find matching key in config entries */ + /* find matching key in boot entries */ size_t idx = entry_lookup_key(&config, config.idx_default, KEYCHAR(key)); if (idx != IDX_INVALID) config.idx_default = idx; @@ -2746,7 +2746,7 @@ static EFI_STATUS run(EFI_HANDLE image) { } for (;;) { - ConfigEntry *entry; + BootEntry *entry; entry = config.entries[config.idx_default]; if (menu) { @@ -2770,7 +2770,7 @@ static EFI_STATUS run(EFI_HANDLE image) { continue; } - (void) config_entry_bump_counters(entry); + (void) boot_entry_bump_counters(entry); save_selected_entry(&config, entry); /* Optionally, read a random seed off the ESP and pass it to the OS */