From: Lennart Poettering Date: Fri, 28 Jun 2024 17:56:55 +0000 (+0200) Subject: boot: split out inner part of config_load_type2_entries() X-Git-Tag: v257-rc1~967^2~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=76c8c0b2647c8aff23b9ecbd5b93637994688666;p=thirdparty%2Fsystemd.git boot: split out inner part of config_load_type2_entries() Let's simplify the code a bit, and parse Type 2 entries in a function of its own, separate from the directory enumeration. This closely follows a similar split we did a long time ago for Type 1. This is just refactoring, no real code change. --- diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index aca34a5145f..1d31f9097fe 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -2088,6 +2088,139 @@ static void config_add_entry_windows(Config *config, EFI_HANDLE *device, EFI_FIL #endif } +static void boot_entry_add_type2( + Config *config, + EFI_HANDLE *device, + EFI_FILE *dir, + const uint16_t *filename) { + + enum { + SECTION_CMDLINE, + SECTION_OSREL, + _SECTION_MAX, + }; + static const char * const section_names[_SECTION_MAX + 1] = { + [SECTION_CMDLINE] = ".cmdline", + [SECTION_OSREL] = ".osrel", + NULL, + }; + + EFI_STATUS err; + + assert(config); + assert(device); + assert(dir); + assert(filename); + + /* Look for .osrel and .cmdline sections in the .efi binary */ + PeSectionVector sections[_SECTION_MAX] = {}; + err = pe_file_locate_sections(dir, filename, section_names, sections); + if (err != EFI_SUCCESS || !PE_SECTION_VECTOR_IS_SET(sections + SECTION_OSREL)) + return; + + _cleanup_free_ char *content = NULL; + err = file_read(dir, + filename, + sections[SECTION_OSREL].file_offset, + sections[SECTION_OSREL].size, + &content, + /* ret_size= */ NULL); + if (err != EFI_SUCCESS) + return; + + _cleanup_free_ char16_t *os_pretty_name = NULL, *os_image_id = NULL, *os_name = NULL, *os_id = NULL, + *os_image_version = NULL, *os_version = NULL, *os_version_id = NULL, *os_build_id = NULL; + char *line, *key, *value; + size_t pos = 0; + + /* read properties from the embedded os-release file */ + 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); + + } else if (streq8(key, "IMAGE_ID")) { + free(os_image_id); + os_image_id = xstr8_to_16(value); + + } else if (streq8(key, "NAME")) { + free(os_name); + os_name = xstr8_to_16(value); + + } else if (streq8(key, "ID")) { + free(os_id); + os_id = xstr8_to_16(value); + + } else if (streq8(key, "IMAGE_VERSION")) { + free(os_image_version); + os_image_version = xstr8_to_16(value); + + } else if (streq8(key, "VERSION")) { + free(os_version); + os_version = xstr8_to_16(value); + + } else if (streq8(key, "VERSION_ID")) { + free(os_version_id); + os_version_id = xstr8_to_16(value); + + } else if (streq8(key, "BUILD_ID")) { + free(os_build_id); + os_build_id = xstr8_to_16(value); + } + + const char16_t *good_name, *good_version, *good_sort_key; + if (!bootspec_pick_name_version_sort_key( + os_pretty_name, + os_image_id, + os_name, + os_id, + os_image_version, + os_version, + os_version_id, + os_build_id, + &good_name, + &good_version, + &good_sort_key)) + return; + + BootEntry *entry = xnew(BootEntry, 1); + *entry = (BootEntry) { + .id = xstrdup16(filename), + .type = LOADER_UNIFIED_LINUX, + .title = xstrdup16(good_name), + .version = xstrdup16(good_version), + .device = device, + .loader = xasprintf("\\EFI\\Linux\\%ls", filename), + .sort_key = xstrdup16(good_sort_key), + .key = 'l', + .tries_done = -1, + .tries_left = -1, + }; + + strtolower16(entry->id); + config_add_entry(config, entry); + boot_entry_parse_tries(entry, u"\\EFI\\Linux", filename, u".efi"); + + if (!PE_SECTION_VECTOR_IS_SET(sections + SECTION_CMDLINE)) + return; + + content = mfree(content); + + /* read the embedded cmdline file */ + size_t cmdline_len; + err = file_read(dir, + filename, + sections[SECTION_CMDLINE].file_offset, + sections[SECTION_CMDLINE].size, + &content, + &cmdline_len); + if (err == EFI_SUCCESS) { + entry->options = xstrn8_to_16(content, cmdline_len); + mangle_stub_cmdline(entry->options); + entry->options_implied = true; + } +} + static void config_load_type2_entries( Config *config, EFI_HANDLE *device, @@ -2109,26 +2242,6 @@ static void config_load_type2_entries( return; for (;;) { - enum { - SECTION_CMDLINE, - SECTION_OSREL, - _SECTION_MAX, - }; - - static const char * const section_names[_SECTION_MAX + 1] = { - [SECTION_CMDLINE] = ".cmdline", - [SECTION_OSREL] = ".osrel", - NULL, - }; - - _cleanup_free_ char16_t *os_pretty_name = NULL, *os_image_id = NULL, *os_name = NULL, *os_id = NULL, - *os_image_version = NULL, *os_version = NULL, *os_version_id = NULL, *os_build_id = NULL; - const char16_t *good_name, *good_version, *good_sort_key; - _cleanup_free_ char *content = NULL; - PeSectionVector sections[_SECTION_MAX] = {}; - char *line, *key, *value; - size_t pos = 0; - err = readdir(linux_dir, &f, &f_size); if (err != EFI_SUCCESS || !f) break; @@ -2142,105 +2255,7 @@ static void config_load_type2_entries( if (startswith(f->FileName, u"auto-")) continue; - /* look for .osrel and .cmdline sections in the .efi binary */ - err = pe_file_locate_sections(linux_dir, f->FileName, section_names, sections); - if (err != EFI_SUCCESS || !PE_SECTION_VECTOR_IS_SET(sections + SECTION_OSREL)) - continue; - - err = file_read(linux_dir, - f->FileName, - sections[SECTION_OSREL].file_offset, - sections[SECTION_OSREL].size, - &content, - NULL); - if (err != EFI_SUCCESS) - continue; - - /* read properties from the embedded os-release file */ - 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); - - } else if (streq8(key, "IMAGE_ID")) { - free(os_image_id); - os_image_id = xstr8_to_16(value); - - } else if (streq8(key, "NAME")) { - free(os_name); - os_name = xstr8_to_16(value); - - } else if (streq8(key, "ID")) { - free(os_id); - os_id = xstr8_to_16(value); - - } else if (streq8(key, "IMAGE_VERSION")) { - free(os_image_version); - os_image_version = xstr8_to_16(value); - - } else if (streq8(key, "VERSION")) { - free(os_version); - os_version = xstr8_to_16(value); - - } else if (streq8(key, "VERSION_ID")) { - free(os_version_id); - os_version_id = xstr8_to_16(value); - - } else if (streq8(key, "BUILD_ID")) { - free(os_build_id); - os_build_id = xstr8_to_16(value); - } - - if (!bootspec_pick_name_version_sort_key( - os_pretty_name, - os_image_id, - os_name, - os_id, - os_image_version, - os_version, - os_version_id, - os_build_id, - &good_name, - &good_version, - &good_sort_key)) - continue; - - BootEntry *entry = xnew(BootEntry, 1); - *entry = (BootEntry) { - .id = xstrdup16(f->FileName), - .type = LOADER_UNIFIED_LINUX, - .title = xstrdup16(good_name), - .version = xstrdup16(good_version), - .device = device, - .loader = xasprintf("\\EFI\\Linux\\%ls", f->FileName), - .sort_key = xstrdup16(good_sort_key), - .key = 'l', - .tries_done = -1, - .tries_left = -1, - }; - - strtolower16(entry->id); - config_add_entry(config, entry); - boot_entry_parse_tries(entry, u"\\EFI\\Linux", f->FileName, u".efi"); - - if (!PE_SECTION_VECTOR_IS_SET(sections + SECTION_CMDLINE)) - continue; - - content = mfree(content); - - /* read the embedded cmdline file */ - size_t cmdline_len; - err = file_read(linux_dir, - f->FileName, - sections[SECTION_CMDLINE].file_offset, - sections[SECTION_CMDLINE].size, - &content, - &cmdline_len); - if (err == EFI_SUCCESS) { - entry->options = xstrn8_to_16(content, cmdline_len); - mangle_stub_cmdline(entry->options); - entry->options_implied = true; - } + boot_entry_add_type2(config, device, linux_dir, f->FileName); } }