From: Emanuele Giuseppe Esposito Date: Thu, 21 Sep 2023 11:59:24 +0000 (-0400) Subject: bootctl: discover and pring global UKI PE addons X-Git-Tag: v256-rc1~864^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=01fd84111f18c0ef342015402a3b236acae70f3d;p=thirdparty%2Fsystemd.git bootctl: discover and pring global UKI PE addons An UKI final command line is not just made of the content of .cmdline, but also from the addons that are inserted in /boot/efi/EFI/Linux/.efi.extra.d (local addons) and /boot/efi/loader/addons (global addons). Therefore bootclt "status" and "list" should also include these addons when printing the UKI command line. Support for /boot/efi/EFI/Linux/.efi.extra.d is already present, so now cover addons present in /boot/efi/loader/addons (global addons). Example (assume UKI_NAME=devel): $ bootctl ukiCmdline: console=tty0 console=ttyS0 globalAddon: loader/addons/global.addon.efi cmdline: └─quiet localAddon: devel.efi.extra.d/rpm_addon.addon.efi cmdline: └─this is a normal addon finalCmdline: console=tty0 console=ttyS0 quiet this is a normal addon --- diff --git a/src/boot/bootctl-status.c b/src/boot/bootctl-status.c index b8813ec40a6..f8b57c1f9d4 100644 --- a/src/boot/bootctl-status.c +++ b/src/boot/bootctl-status.c @@ -92,6 +92,7 @@ static int status_entries( r = show_boot_entry( boot_config_default_entry(config), + &config->global_addons, /* show_as_default= */ false, /* show_as_selected= */ false, /* show_discovered= */ false); diff --git a/src/shared/bootspec.c b/src/shared/bootspec.c index 16986c79122..b0bf94c7dae 100644 --- a/src/shared/bootspec.c +++ b/src/shared/bootspec.c @@ -445,6 +445,7 @@ void boot_config_free(BootConfig *config) { for (size_t i = 0; i < config->n_entries; i++) boot_entry_free(config->entries + i); free(config->entries); + free(config->global_addons.items); set_free(config->inodes_seen); } @@ -958,6 +959,23 @@ static int boot_entries_find_unified_addons( return 0; } +static int boot_entries_find_unified_global_addons( + BootConfig *config, + const char *root, + const char *d_name) { + + int r; + _cleanup_closedir_ DIR *d = NULL; + + r = chase_and_opendir(root, NULL, CHASE_PROHIBIT_SYMLINKS, NULL, &d); + if (r == -ENOENT) + return 0; + if (r < 0) + return log_error_errno(r, "Failed to open '%s/%s': %m", root, d_name); + + return boot_entries_find_unified_addons(config, dirfd(d), d_name, root, &config->global_addons); +} + static int boot_entries_find_unified_local_addons( BootConfig *config, int d_fd, @@ -1251,6 +1269,7 @@ int boot_config_load( int r; assert(config); + config->global_addons = (BootEntryAddons) {}; if (esp_path) { r = boot_loader_read_conf_path(config, esp_path, "/loader/loader.conf"); @@ -1264,6 +1283,10 @@ int boot_config_load( r = boot_entries_find_unified(config, esp_path, "/EFI/Linux/"); if (r < 0) return r; + + r = boot_entries_find_unified_global_addons(config, esp_path, "/loader/addons/"); + if (r < 0) + return r; } if (xbootldr_path) { @@ -1435,7 +1458,10 @@ static void print_addon( printf(" cmdline: %s%s\n", special_glyph(SPECIAL_GLYPH_TREE_RIGHT), addon->cmdline); } -static int print_cmdline(const BootEntry *e) { +static int print_cmdline( + const BootEntry *e, + const BootEntryAddons *global_arr) { + _cleanup_free_ char *final_cmdline = NULL; assert(e); @@ -1460,6 +1486,12 @@ static int print_cmdline(const BootEntry *e) { final_cmdline = TAKE_PTR(t2); } + FOREACH_ARRAY(addon, global_arr->items, global_arr->count) { + print_addon(addon, "globalAddon"); + if (!strextend(&final_cmdline, " ", addon->cmdline)) + return log_oom(); + } + FOREACH_ARRAY(addon, e->local_addons.items, e->local_addons.count) { /* Add space at the beginning of addon_str to align it correctly */ print_addon(addon, " localAddon"); @@ -1490,7 +1522,11 @@ static int json_addon( return 0; } -static int json_cmdline(const BootEntry *e, JsonVariant **v) { +static int json_cmdline( + const BootEntry *e, + const BootEntryAddons *global_arr, + JsonVariant **v) { + _cleanup_free_ char *final_cmdline = NULL, *def_cmdline = NULL; _cleanup_(json_variant_unrefp) JsonVariant *addons_array = NULL; int r; @@ -1504,6 +1540,14 @@ static int json_cmdline(const BootEntry *e, JsonVariant **v) { final_cmdline = TAKE_PTR(def_cmdline); } + FOREACH_ARRAY(addon, global_arr->items, global_arr->count) { + r = json_addon(addon, "globalAddon", &addons_array); + if (r < 0) + return r; + if (!strextend(&final_cmdline, " ", addon->cmdline)) + return log_oom(); + } + FOREACH_ARRAY(addon, e->local_addons.items, e->local_addons.count) { r = json_addon(addon, "localAddon", &addons_array); if (r < 0) @@ -1524,6 +1568,7 @@ static int json_cmdline(const BootEntry *e, JsonVariant **v) { int show_boot_entry( const BootEntry *e, + const BootEntryAddons *global_addons, bool show_as_default, bool show_as_selected, bool show_reported) { @@ -1607,7 +1652,7 @@ int show_boot_entry( *s, &status); - r = print_cmdline(e); + r = print_cmdline(e, global_addons); if (r < 0) return r; @@ -1655,7 +1700,7 @@ int show_boot_entries(const BootConfig *config, JsonFormatFlags json_format) { if (r < 0) return log_oom(); - r = json_cmdline(e, &v); + r = json_cmdline(e, &config->global_addons, &v); if (r < 0) return log_oom(); @@ -1684,6 +1729,7 @@ int show_boot_entries(const BootConfig *config, JsonFormatFlags json_format) { for (size_t n = 0; n < config->n_entries; n++) { r = show_boot_entry( config->entries + n, + &config->global_addons, /* show_as_default= */ n == (size_t) config->default_entry, /* show_as_selected= */ n == (size_t) config->selected_entry, /* show_discovered= */ true); diff --git a/src/shared/bootspec.h b/src/shared/bootspec.h index 141388143c9..8289325b9e3 100644 --- a/src/shared/bootspec.h +++ b/src/shared/bootspec.h @@ -79,6 +79,8 @@ typedef struct BootConfig { BootEntry *entries; size_t n_entries; + BootEntryAddons global_addons; + ssize_t default_entry; ssize_t selected_entry; @@ -132,6 +134,7 @@ static inline const char* boot_entry_title(const BootEntry *entry) { int show_boot_entry( const BootEntry *e, + const BootEntryAddons *global_addons, bool show_as_default, bool show_as_selected, bool show_reported);