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/<UKI_NAME>.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/<UKI_NAME>.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
This commit is contained in:
Emanuele Giuseppe Esposito
2024-02-14 04:58:28 -05:00
parent 122650b4a0
commit 01fd84111f
3 changed files with 54 additions and 4 deletions
+1
View File
@@ -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);
+50 -4
View File
@@ -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);
+3
View File
@@ -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);