From: Lennart Poettering Date: Tue, 10 Feb 2026 14:13:02 +0000 (+0100) Subject: bootspec: generalize "addon" logic for all kinds of extra sidecars X-Git-Tag: v261-rc1~324^2~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e7128bb795949da6b785f2c78f75c8442ffb0b77;p=thirdparty%2Fsystemd.git bootspec: generalize "addon" logic for all kinds of extra sidecars Let's pick up all kinds of sidecars and show them, not just addons This also fixes some issues regarding "root" directory handling. In one context we'd resolve a directory claiming it was a "root", but it wasn't. Implements: https://github.com/uapi-group/specifications/pull/212 --- diff --git a/src/shared/bootspec.c b/src/shared/bootspec.c index c0111d1f9c4..a167e19a90b 100644 --- a/src/shared/bootspec.c +++ b/src/shared/bootspec.c @@ -14,10 +14,12 @@ #include "efi-loader.h" #include "efivars.h" #include "env-file.h" +#include "errno-util.h" #include "extract-word.h" #include "fd-util.h" #include "fileio.h" #include "find-esp.h" +#include "json-util.h" #include "log.h" #include "parse-util.h" #include "path-util.h" @@ -65,15 +67,65 @@ static const char* const boot_entry_source_table[_BOOT_ENTRY_SOURCE_MAX] = { DEFINE_STRING_TABLE_LOOKUP_TO_STRING(boot_entry_source, BootEntrySource); -static void boot_entry_addons_done(BootEntryAddons *addons) { - assert(addons); +static BootEntryExtraType boot_entry_extra_type_from_filename(const char *path) { + if (!path) + return _BOOT_ENTRY_EXTRA_TYPE_INVALID; - FOREACH_ARRAY(addon, addons->items, addons->n_items) { - free(addon->cmdline); - free(addon->location); + if (endswith_no_case(path, ".addon.efi")) + return BOOT_ENTRY_ADDON; + if (endswith_no_case(path, ".confext.raw")) + return BOOT_ENTRY_CONFEXT; + if (endswith_no_case(path, ".sysext.raw")) + return BOOT_ENTRY_SYSEXT; + if (endswith_no_case(path, ".cred")) + return BOOT_ENTRY_CREDENTIAL; + + return _BOOT_ENTRY_EXTRA_TYPE_INVALID; +} + +static void boot_entry_extras_done(BootEntryExtras *extras) { + assert(extras); + + FOREACH_ARRAY(extra, extras->items, extras->n_items) { + free(extra->location); + free(extra->cmdline); + } + extras->items = mfree(extras->items); + extras->n_items = 0; +} + +static int boot_entry_extras_add( + BootEntryExtras *extras, + BootEntryExtraType type, + const char *path, + const char *cmdline) { + + assert(extras); + assert(type >= 0); + assert(type < _BOOT_ENTRY_EXTRA_TYPE_MAX); + assert(path); + + _cleanup_free_ char *p = strdup(path); + if (!p) + return -ENOMEM; + + _cleanup_free_ char *c = NULL; + if (cmdline) { + c = strdup(cmdline); + if (!c) + return -ENOMEM; } - addons->items = mfree(addons->items); - addons->n_items = 0; + + if (!GREEDY_REALLOC(extras->items, extras->n_items + 1)) + return -ENOMEM; + + extras->items[extras->n_items++] = (BootEntryExtra) { + .type = type, + .location = TAKE_PTR(p), + .cmdline = TAKE_PTR(c), + }; + + return 0; } static void boot_entry_free(BootEntry *entry) { @@ -91,7 +143,7 @@ static void boot_entry_free(BootEntry *entry) { free(entry->machine_id); free(entry->architecture); strv_free(entry->options); - boot_entry_addons_done(&entry->local_addons); + boot_entry_extras_done(&entry->local_extras); free(entry->kernel); free(entry->efi); free(entry->uki); @@ -213,6 +265,50 @@ static int parse_path_many( return strv_extend_strv_consume(s, TAKE_PTR(f), /* filter_duplicates= */ false); } +static int parse_extra( + const char *fname, + unsigned line, + const char *field, + BootEntryExtras *extras, + const char *p) { + + int r; + + assert(extras); + + _cleanup_strv_free_ char **l = strv_split(p, NULL); + if (!l) + return -ENOMEM; + + STRV_FOREACH(i, l) { + _cleanup_free_ char *c = NULL; + r = mangle_path(fname, line, field, *i, &c); + if (r < 0) + return r; + if (r == 0) + continue; + + BootEntryExtraType type = boot_entry_extra_type_from_filename(c); + if (type < 0) { + log_debug_errno(type, "Failed to determine boot entry extra type of '%s', skipping: %m", c); + continue; + } + + /* Let's filter out EFI addons for now. We have no protocol for passing them from sd-boot to + * sd-stub, hence supporting them would require major plumbing first. */ + if (type == BOOT_ENTRY_ADDON) { + log_debug("EFI addons are currently not supported for Type #1 entries, skipping '%s'.", c); + continue; + } + + r = boot_entry_extras_add(extras, type, c, /* cmdline= */ NULL); + if (r < 0) + return r; + } + + return 0; +} + static int parse_tries(const char *fname, const char **p, unsigned *ret) { _cleanup_free_ char *d = NULL; unsigned tries; @@ -421,6 +517,8 @@ static int boot_entry_load_type1( r = parse_path_one(tmp.path, line, field, &tmp.device_tree, p); else if (streq(field, "devicetree-overlay")) r = parse_path_many(tmp.path, line, field, &tmp.device_tree_overlay, p); + else if (streq(field, "extra")) + r = parse_extra(tmp.path, line, field, &tmp.local_extras, p); else { log_syntax(NULL, LOG_WARNING, tmp.path, line, 0, "Unknown line '%s', ignoring.", field); continue; @@ -458,7 +556,7 @@ int boot_config_load_type1( return r; config->n_entries++; - entry->global_addons = &config->global_addons[source]; + entry->global_extras = &config->global_extras[source]; return 0; } @@ -479,8 +577,8 @@ void boot_config_free(BootConfig *config) { boot_entry_free(i); free(config->entries); - FOREACH_ELEMENT(i, config->global_addons) - boot_entry_addons_done(i); + FOREACH_ELEMENT(i, config->global_extras) + boot_entry_extras_done(i); set_free(config->inodes_seen); } @@ -1188,126 +1286,140 @@ nothing: return 0; } -static int insert_boot_entry_addon( - BootEntryAddons *addons, - char *location, - char *cmdline) { - - assert(addons); - - if (!GREEDY_REALLOC(addons->items, addons->n_items + 1)) - return log_oom(); - - addons->items[addons->n_items++] = (BootEntryAddon) { - .location = location, - .cmdline = cmdline, - }; - - return 0; -} - -static int boot_entries_find_unified_addons( +static int boot_entries_find_unified_extras( BootConfig *config, int d_fd, - const char *addon_dir, - const char *root, - BootEntryAddons *ret_addons) { + const char *extra_dir, + BootEntryExtraType only_type, + const char *where, + bool suppress_seen, + BootEntryExtras *extras) { - _cleanup_closedir_ DIR *d = NULL; - _cleanup_free_ char *full = NULL; - _cleanup_(boot_entry_addons_done) BootEntryAddons addons = {}; int r; - assert(ret_addons); assert(config); + assert(extras); - r = chase_and_opendirat(d_fd, d_fd, addon_dir, /* chase_flags= */ 0, &full, &d); + _cleanup_closedir_ DIR *d = NULL; + r = chase_and_opendirat( + /* root_fd= */ d_fd, + /* dir_fd= */ d_fd, + extra_dir, + /* chase_flags= */ 0, + /* ret_path= */ NULL, + &d); if (r == -ENOENT) return 0; if (r < 0) - return log_error_errno(r, "Failed to open '%s/%s': %m", root, skip_leading_slash(addon_dir)); - - FOREACH_DIRENT(de, d, return log_error_errno(errno, "Failed to read %s: %m", full)) { - _cleanup_free_ char *j = NULL, *cmdline = NULL, *location = NULL; - _cleanup_close_ int fd = -EBADF; + return log_error_errno(r, "Failed to open '%s/%s': %m", where, skip_leading_slash(extra_dir)); + FOREACH_DIRENT(de, d, return log_error_errno(errno, "Failed to read '%s': %m", extra_dir)) { if (!dirent_is_file(de)) continue; - if (!endswith_no_case(de->d_name, ".addon.efi")) + BootEntryExtraType type = boot_entry_extra_type_from_filename(de->d_name); + if (type < 0) { + log_debug_errno(type, "Unrecognized extra file '%s', skipping.", de->d_name); continue; + } + if (only_type >= 0 && type != only_type) { + log_debug("Extra file '%s' type not permitted in '%s', skipping.", de->d_name, extra_dir); + continue; + } - fd = openat(dirfd(d), de->d_name, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOFOLLOW|O_NOCTTY); - if (fd < 0) { - log_warning_errno(errno, "Failed to open %s/%s, ignoring: %m", full, de->d_name); + _cleanup_free_ char *location = path_join(extra_dir, de->d_name); + if (!location) + return log_oom(); + + _cleanup_close_ int pin_fd = openat(dirfd(d), de->d_name, O_PATH|O_CLOEXEC|O_NOFOLLOW); + if (pin_fd < 0) { + log_debug_errno(errno, "Failed to pin '%s', ignoring: %m", location); continue; } - r = config_check_inode_relevant_and_unseen(config, fd, de->d_name); - if (r < 0) - return r; - if (r == 0) /* inode already seen or otherwise not relevant */ + r = fd_verify_regular(pin_fd); + if (r < 0) { + log_debug_errno(r, "Unrecognized inode type of '%s', skipping.", location); continue; + } - j = path_join(full, de->d_name); - if (!j) - return log_oom(); + if (suppress_seen) { + r = config_check_inode_relevant_and_unseen(config, pin_fd, location); + if (r < 0) + return r; + if (r == 0) /* inode already seen or otherwise not relevant */ + continue; + } - if (pe_find_addon_sections(fd, j, &cmdline) <= 0) - continue; + _cleanup_free_ char *cmdline = NULL; + if (type == BOOT_ENTRY_ADDON) { + _cleanup_close_ int fd = fd_reopen(pin_fd, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); + if (fd < 0) { + log_debug_errno(fd, "Failed to open '%s', ignoring: %m", location); + continue; + } - location = strdup(j); - if (!location) - return log_oom(); + /* Try to extract the command line, but let's handle any failures gracefully, but + * still mention the extra file exists. */ + (void) pe_find_addon_sections(fd, location, &cmdline); + } - r = insert_boot_entry_addon(&addons, location, cmdline); + r = boot_entry_extras_add(extras, type, location, cmdline); if (r < 0) return r; - - TAKE_PTR(location); - TAKE_PTR(cmdline); } - *ret_addons = TAKE_STRUCT(addons); return 0; } -static int boot_entries_find_unified_global_addons( +static int boot_entries_find_unified_global_extras( BootConfig *config, - const char *root, - const char *d_name, - BootEntryAddons *ret_addons) { - - int r; - _cleanup_closedir_ DIR *d = NULL; + const char *where, + const char *extra_dir, + BootEntryExtraType only_type, + BootEntryExtras *extras) { - assert(ret_addons); + assert(extras); - r = chase_and_opendir(root, NULL, CHASE_PROHIBIT_SYMLINKS, NULL, &d); - if (r == -ENOENT) + _cleanup_close_ int where_fd = RET_NERRNO(open(where, O_DIRECTORY|O_CLOEXEC)); + if (where_fd == -ENOENT) return 0; - if (r < 0) - return log_error_errno(r, "Failed to open '%s/%s': %m", root, skip_leading_slash(d_name)); - - return boot_entries_find_unified_addons(config, dirfd(d), d_name, root, ret_addons); + if (where_fd < 0) + return log_error_errno(where_fd, "Failed to open '%s': %m", where); + + return boot_entries_find_unified_extras( + config, + where_fd, + extra_dir, + only_type, + where, + /* suppress_seen= */ true, + extras); } -static int boot_entries_find_unified_local_addons( +static int boot_entries_find_unified_local_extras( BootConfig *config, int d_fd, - const char *d_name, - const char *root, + const char *uki, + const char *where, BootEntry *ret) { - _cleanup_free_ char *addon_dir = NULL; + _cleanup_free_ char *extra_dir = NULL; assert(ret); - addon_dir = strjoin(d_name, ".extra.d"); - if (!addon_dir) + extra_dir = strjoin(uki, ".extra.d"); + if (!extra_dir) return log_oom(); - return boot_entries_find_unified_addons(config, d_fd, addon_dir, root, &ret->local_addons); + return boot_entries_find_unified_extras( + config, + d_fd, + extra_dir, + /* only_type= */ _BOOT_ENTRY_EXTRA_TYPE_INVALID, + where, + /* suppress_seen= */ false, + &ret->local_extras); } static int boot_entries_find_unified( @@ -1369,11 +1481,11 @@ static int boot_entries_find_unified( if (boot_entry_load_unified(root, source, j, p, osrelease, profile, cmdline, entry) < 0) continue; - /* look for .efi.extra.d */ - (void) boot_entries_find_unified_local_addons(config, dirfd(d), de->d_name, full, entry); + /* Look for .efi.extra.d/ */ + (void) boot_entries_find_unified_local_extras(config, dirfd(d), de->d_name, full, entry); - /* Set up the backpointer, so that we can find the global addons */ - entry->global_addons = &config->global_addons[source]; + /* Set up the backpointer, so that we can find the global extras */ + entry->global_extras = &config->global_extras[source]; config->n_entries++; } @@ -1614,45 +1726,73 @@ int boot_config_finalize(BootConfig *config) { return 0; } -int boot_config_load( +static int boot_entries_load( BootConfig *config, - const char *esp_path, - const char *xbootldr_path) { + BootEntrySource source, + const char *where) { /* Mount point of ESP/XBOOTLDR */ int r; assert(config); + assert(source >= 0); + assert(source < _BOOT_ENTRY_SOURCE_MAX); - if (esp_path) { - r = boot_loader_read_conf_path(config, esp_path, "/loader/loader.conf"); - if (r < 0) - return r; + if (!where) + return 0; - r = boot_entries_find_type1(config, esp_path, BOOT_ENTRY_ESP, "/loader/entries"); - if (r < 0) - return r; + r = boot_entries_find_type1(config, where, source, "/loader/entries"); + if (r < 0) + return r; - r = boot_entries_find_unified(config, esp_path, BOOT_ENTRY_ESP, "/EFI/Linux/"); - if (r < 0) - return r; + r = boot_entries_find_unified(config, where, source, "/EFI/Linux/"); + if (r < 0) + return r; - r = boot_entries_find_unified_global_addons(config, esp_path, "/loader/addons/", - &config->global_addons[BOOT_ENTRY_ESP]); + static const struct { + BootEntryExtraType extra_type; + const char *directory; + } table[] = { + { BOOT_ENTRY_ADDON, "/loader/addons/" }, + { BOOT_ENTRY_CONFEXT, "/loader/extensions/" }, + { BOOT_ENTRY_SYSEXT, "/loader/extensions/" }, + { BOOT_ENTRY_CREDENTIAL, "/loader/credentials/" }, + }; + + FOREACH_ELEMENT(i, table) { + r = boot_entries_find_unified_global_extras( + config, + where, + i->directory, + i->extra_type, + &config->global_extras[source]); if (r < 0) return r; } - if (xbootldr_path) { - r = boot_entries_find_type1(config, xbootldr_path, BOOT_ENTRY_XBOOTLDR, "/loader/entries"); + return 0; +} + +int boot_config_load( + BootConfig *config, + const char *esp_path, + const char *xbootldr_path) { + + int r; + + assert(config); + + if (esp_path) { + r = boot_loader_read_conf_path(config, esp_path, "/loader/loader.conf"); if (r < 0) return r; - r = boot_entries_find_unified(config, xbootldr_path, BOOT_ENTRY_XBOOTLDR, "/EFI/Linux/"); + r = boot_entries_load(config, BOOT_ENTRY_ESP, esp_path); if (r < 0) return r; + } - r = boot_entries_find_unified_global_addons(config, xbootldr_path, "/loader/addons/", - &config->global_addons[BOOT_ENTRY_XBOOTLDR]); + if (xbootldr_path) { + r = boot_entries_load(config, BOOT_ENTRY_XBOOTLDR, xbootldr_path); if (r < 0) return r; } @@ -1724,7 +1864,7 @@ int boot_config_augment_from_loader( char **found_by_loader, bool auto_only) { - static const BootEntryAddons no_addons = (BootEntryAddons) {}; + static const BootEntryExtras no_extras = (BootEntryExtras) {}; static const char *const title_table[] = { /* Pretty names for a few well-known automatically discovered entries. */ "auto-osx", "macOS", @@ -1783,7 +1923,7 @@ int boot_config_augment_from_loader( .tries_left = UINT_MAX, .tries_done = UINT_MAX, .profile = UINT_MAX, - .global_addons = &no_addons, + .global_extras = &no_extras, }; } @@ -1806,10 +1946,10 @@ static void boot_entry_file_list( const char *field, const char *root, const char *p, - int *ret_status) { + int *pstatus) { assert(p); - assert(ret_status); + assert(pstatus); int status = chase_and_access(p, root, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS, F_OK, NULL); @@ -1824,16 +1964,23 @@ static void boot_entry_file_list( } else printf("%s\n", p); - if (*ret_status == 0 && status < 0) - *ret_status = status; + if (*pstatus == 0 && status < 0) + *pstatus = status; } -static void print_addon( - BootEntryAddon *addon, - const char *addon_str) { +static void print_extra( + const BootEntry *e, + const BootEntryExtra *extra, + const char *field, + int *status) { + + assert(e); + assert(extra); + + boot_entry_file_list(field, e->root, extra->location, status); - printf(" %s: %s\n", addon_str, addon->location); - printf(" options: %s%s\n", glyph(GLYPH_TREE_RIGHT), addon->cmdline); + if (extra->cmdline) + printf(" options: %s%s\n", glyph(GLYPH_TREE_RIGHT), extra->cmdline); } static int indent_embedded_newlines(char *cmdline, char **ret_cmdline) { @@ -1851,12 +1998,10 @@ static int indent_embedded_newlines(char *cmdline, char **ret_cmdline) { return -ENOMEM; *ret_cmdline = TAKE_PTR(t); - return 0; } -static int print_cmdline(const BootEntry *e) { - +static int print_cmdline(const BootEntry *e, int *status) { _cleanup_free_ char *options = NULL, *combined_cmdline = NULL, *t2 = NULL; assert(e); @@ -1877,17 +2022,20 @@ static int print_cmdline(const BootEntry *e) { return log_oom(); } - FOREACH_ARRAY(addon, e->global_addons->items, e->global_addons->n_items) { - print_addon(addon, "global-addon"); - if (!strextend(&t2, " ", addon->cmdline)) - return log_oom(); + FOREACH_ARRAY(extra, e->global_extras->items, e->global_extras->n_items) { + print_extra(e, extra, "extra", status); + + if (extra->cmdline) + if (!strextend(&t2, " ", extra->cmdline)) + return log_oom(); } - FOREACH_ARRAY(addon, e->local_addons.items, e->local_addons.n_items) { - /* Add space at the beginning of addon_str to align it correctly */ - print_addon(addon, " local-addon"); - if (!strextend(&t2, " ", addon->cmdline)) - return log_oom(); + FOREACH_ARRAY(extra, e->local_extras.items, e->local_extras.n_items) { + print_extra(e, extra, "extra", status); + + if (extra->cmdline) + if (!strextend(&t2, " ", extra->cmdline)) + return log_oom(); } /* Don't print the combined cmdline if it's same as options. */ @@ -1904,19 +2052,19 @@ static int print_cmdline(const BootEntry *e) { } static int json_addon( - BootEntryAddon *addon, - const char *addon_str, + const BootEntryExtra *extra, + const char *extra_str, sd_json_variant **array) { int r; - assert(addon); - assert(addon_str); + assert(extra); + assert(extra_str); r = sd_json_variant_append_arraybo( array, - SD_JSON_BUILD_PAIR_STRING(addon_str, addon->location), - SD_JSON_BUILD_PAIR_STRING("options", addon->cmdline)); + SD_JSON_BUILD_PAIR_STRING(extra_str, extra->location), + JSON_BUILD_PAIR_STRING_NON_EMPTY("options", extra->cmdline)); if (r < 0) return log_oom(); @@ -1940,20 +2088,31 @@ static int json_cmdline( return log_oom(); } - FOREACH_ARRAY(addon, e->global_addons->items, e->global_addons->n_items) { - r = json_addon(addon, "globalAddon", &addons_array); + /* NB: these JSON fields are kinda obsolete, we want the more generic 'extra' ones to be used. */ + FOREACH_ARRAY(extra, e->global_extras->items, e->global_extras->n_items) { + if (extra->type != BOOT_ENTRY_ADDON) + continue; + + r = json_addon(extra, "globalAddon", &addons_array); if (r < 0) return r; - if (!strextend(&combined_cmdline, " ", addon->cmdline)) - return log_oom(); + + if (extra->cmdline) + if (!strextend(&combined_cmdline, " ", extra->cmdline)) + return log_oom(); } - FOREACH_ARRAY(addon, e->local_addons.items, e->local_addons.n_items) { - r = json_addon(addon, "localAddon", &addons_array); + FOREACH_ARRAY(extra, e->local_extras.items, e->local_extras.n_items) { + if (extra->type != BOOT_ENTRY_ADDON) + continue; + + r = json_addon(extra, "localAddon", &addons_array); if (r < 0) return r; - if (!strextend(&combined_cmdline, " ", addon->cmdline)) - return log_oom(); + + if (extra->cmdline) + if (!strextend(&combined_cmdline, " ", extra->cmdline)) + return log_oom(); } r = sd_json_variant_merge_objectbo( @@ -2064,7 +2223,7 @@ int show_boot_entry( *s, &status); - r = print_cmdline(e); + r = print_cmdline(e, &status); if (r < 0) return r; @@ -2144,6 +2303,24 @@ int boot_entry_to_json(const BootConfig *c, size_t i, sd_json_variant **ret) { if (r < 0) return log_oom(); + _cleanup_(sd_json_variant_unrefp) sd_json_variant *jextras = NULL; + FOREACH_ARRAY(extra, e->global_extras->items, e->global_extras->n_items) { + r = sd_json_variant_append_arrayb(&jextras, SD_JSON_BUILD_STRING(extra->location)); + if (r < 0) + return log_oom(); + } + FOREACH_ARRAY(extra, e->local_extras.items, e->local_extras.n_items) { + r = sd_json_variant_append_arrayb(&jextras, SD_JSON_BUILD_STRING(extra->location)); + if (r < 0) + return log_oom(); + } + + r = sd_json_variant_merge_objectbo( + &v, + SD_JSON_BUILD_PAIR_CONDITION(!!jextras, "extras", SD_JSON_BUILD_VARIANT(jextras))); + if (r < 0) + return log_oom(); + *ret = TAKE_PTR(v); return 1; } diff --git a/src/shared/bootspec.h b/src/shared/bootspec.h index d5f6930be99..677667383c9 100644 --- a/src/shared/bootspec.h +++ b/src/shared/bootspec.h @@ -20,15 +20,25 @@ typedef enum BootEntrySource { _BOOT_ENTRY_SOURCE_INVALID = -EINVAL, } BootEntrySource; -typedef struct BootEntryAddon { +typedef enum BootEntryExtraType { + BOOT_ENTRY_ADDON, + BOOT_ENTRY_CONFEXT, + BOOT_ENTRY_SYSEXT, + BOOT_ENTRY_CREDENTIAL, + _BOOT_ENTRY_EXTRA_TYPE_MAX, + _BOOT_ENTRY_EXTRA_TYPE_INVALID = -EINVAL, +} BootEntryExtraType; + +typedef struct BootEntryExtra { + BootEntryExtraType type; char *location; - char *cmdline; -} BootEntryAddon; + char *cmdline; /* only for BOOT_ENTRY_ADDON */ +} BootEntryExtra; -typedef struct BootEntryAddons { - BootEntryAddon *items; +typedef struct BootEntryExtras { + BootEntryExtra *items; size_t n_items; -} BootEntryAddons; +} BootEntryExtras; typedef struct BootEntry { BootEntryType type; @@ -46,8 +56,8 @@ typedef struct BootEntry { char *machine_id; char *architecture; char **options; - BootEntryAddons local_addons; - const BootEntryAddons *global_addons; /* Backpointer into the BootConfig; we don't own this here */ + BootEntryExtras local_extras; + const BootEntryExtras *global_extras; /* Backpointer into the BootConfig; we don't own this here */ char *kernel; /* linux is #defined to 1, yikes! */ char *efi; char *uki; @@ -84,7 +94,7 @@ typedef struct BootConfig { BootEntry *entries; size_t n_entries; - BootEntryAddons global_addons[_BOOT_ENTRY_SOURCE_MAX]; + BootEntryExtras global_extras[_BOOT_ENTRY_SOURCE_MAX]; ssize_t default_entry; ssize_t selected_entry; diff --git a/src/shared/varlink-io.systemd.BootControl.c b/src/shared/varlink-io.systemd.BootControl.c index c16a295d897..920b9479db0 100644 --- a/src/shared/varlink-io.systemd.BootControl.c +++ b/src/shared/varlink-io.systemd.BootControl.c @@ -80,6 +80,8 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE( SD_VARLINK_DEFINE_FIELD(isSelected, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE), SD_VARLINK_FIELD_COMMENT("Addon images of the entry."), SD_VARLINK_DEFINE_FIELD_BY_TYPE(addons, BootEntryAddon, SD_VARLINK_NULLABLE|SD_VARLINK_ARRAY), + SD_VARLINK_FIELD_COMMENT("Extra files associated with the entry."), + SD_VARLINK_DEFINE_FIELD(extras, SD_VARLINK_STRING, SD_VARLINK_NULLABLE|SD_VARLINK_ARRAY), SD_VARLINK_FIELD_COMMENT("Command line options of the entry."), SD_VARLINK_DEFINE_FIELD(cmdline, SD_VARLINK_STRING, SD_VARLINK_NULLABLE)); diff --git a/test/units/TEST-87-AUX-UTILS-VM.bootctl.sh b/test/units/TEST-87-AUX-UTILS-VM.bootctl.sh index 440c3e5edfb..668c0cfac45 100755 --- a/test/units/TEST-87-AUX-UTILS-VM.bootctl.sh +++ b/test/units/TEST-87-AUX-UTILS-VM.bootctl.sh @@ -374,7 +374,7 @@ testcase_00_secureboot() { bootctl status | grep "Secure Boot: enabled" >/dev/null # Ensure the addon is fully loaded and parsed - bootctl status | grep "global-addon: loader/addons/test.addon.efi" >/dev/null + bootctl status | grep "extra: /boot//loader/addons/test.addon.efi" >/dev/null bootctl status | grep "cmdline" | grep addonfoobar >/dev/null grep -q addonfoobar /proc/cmdline }