1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-22 17:35:35 +03:00

bootspec: also collect/mark the "selected" boot entry (i.e. the one currently booted)

it's helpful and easy, so let's do it
This commit is contained in:
Lennart Poettering 2022-02-11 14:41:00 +01:00
parent d403d8f0d6
commit a78e472dfd
3 changed files with 70 additions and 20 deletions

View File

@ -411,7 +411,11 @@ static void boot_entry_file_list(const char *field, const char *root, const char
*ret_status = status;
}
static int boot_entry_show(const BootEntry *e, bool show_as_default) {
static int boot_entry_show(
const BootEntry *e,
bool show_as_default,
bool show_as_selected) {
int status = 0;
/* Returns 0 on success, negative on processing error, and positive if something is wrong with the
@ -419,9 +423,10 @@ static int boot_entry_show(const BootEntry *e, bool show_as_default) {
assert(e);
printf(" title: %s%s%s" "%s%s%s\n",
printf(" title: %s%s%s" "%s%s%s" "%s%s%s\n",
ansi_highlight(), boot_entry_title(e), ansi_normal(),
ansi_highlight_green(), show_as_default ? " (default)" : "", ansi_normal());
ansi_highlight_green(), show_as_default ? " (default)" : "", ansi_normal(),
ansi_highlight_magenta(), show_as_selected ? " (selected)" : "", ansi_normal());
if (e->id)
printf(" id: %s\n", e->id);
@ -519,7 +524,7 @@ static int status_entries(
else {
printf("Default Boot Loader Entry:\n");
r = boot_entry_show(config.entries + config.default_entry, false);
r = boot_entry_show(config.entries + config.default_entry, /* show_as_default= */ false, /* show_as_selected= */ false);
if (r > 0)
/* < 0 is already logged by the function itself, let's just emit an extra warning if
the default entry is broken */
@ -1624,7 +1629,10 @@ static int verb_list(int argc, char *argv[], void *userdata) {
printf("Boot Loader Entries:\n");
for (size_t n = 0; n < config.n_entries; n++) {
r = boot_entry_show(config.entries + n, n == (size_t) config.default_entry);
r = boot_entry_show(
config.entries + n,
n == (size_t) config.default_entry,
n == (size_t) config.selected_entry);
if (r < 0)
return r;

View File

@ -182,6 +182,7 @@ void boot_config_free(BootConfig *config) {
free(config->entry_oneshot);
free(config->entry_default);
free(config->entry_selected);
for (i = 0; i < config->n_entries; i++)
boot_entry_free(config->entries + i);
@ -669,6 +670,55 @@ static int boot_entries_select_default(const BootConfig *config) {
return config->n_entries - 1;
}
static int boot_entries_select_selected(const BootConfig *config) {
assert(config);
assert(config->entries || config->n_entries == 0);
if (!config->entry_selected || config->n_entries == 0)
return -1;
for (int i = config->n_entries - 1; i >= 0; i--)
if (streq(config->entry_selected, config->entries[i].id))
return i;
return -1;
}
static int boot_load_efi_entry_pointers(BootConfig *config) {
int r;
assert(config);
if (!is_efi_boot())
return 0;
/* Loads the three "pointers" to boot loader entries from their EFI variables */
r = efi_get_variable_string(EFI_LOADER_VARIABLE(LoaderEntryOneShot), &config->entry_oneshot);
if (r < 0 && !IN_SET(r, -ENOENT, -ENODATA)) {
log_warning_errno(r, "Failed to read EFI variable \"LoaderEntryOneShot\": %m");
if (r == -ENOMEM)
return r;
}
r = efi_get_variable_string(EFI_LOADER_VARIABLE(LoaderEntryDefault), &config->entry_default);
if (r < 0 && !IN_SET(r, -ENOENT, -ENODATA)) {
log_warning_errno(r, "Failed to read EFI variable \"LoaderEntryDefault\": %m");
if (r == -ENOMEM)
return r;
}
r = efi_get_variable_string(EFI_LOADER_VARIABLE(LoaderEntrySelected), &config->entry_selected);
if (r < 0 && !IN_SET(r, -ENOENT, -ENODATA)) {
log_warning_errno(r, "Failed to read EFI variable \"LoaderEntrySelected\": %m");
if (r == -ENOMEM)
return r;
}
return 1;
}
int boot_entries_load_config(
const char *esp_path,
const char *xbootldr_path,
@ -714,23 +764,13 @@ int boot_entries_load_config(
if (r < 0)
return log_error_errno(r, "Failed to uniquify boot entries: %m");
if (is_efi_boot()) {
r = efi_get_variable_string(EFI_LOADER_VARIABLE(LoaderEntryOneShot), &config->entry_oneshot);
if (r < 0 && !IN_SET(r, -ENOENT, -ENODATA)) {
log_warning_errno(r, "Failed to read EFI variable \"LoaderEntryOneShot\": %m");
if (r == -ENOMEM)
return r;
}
r = efi_get_variable_string(EFI_LOADER_VARIABLE(LoaderEntryDefault), &config->entry_default);
if (r < 0 && !IN_SET(r, -ENOENT, -ENODATA)) {
log_warning_errno(r, "Failed to read EFI variable \"LoaderEntryDefault\": %m");
if (r == -ENOMEM)
return r;
}
}
r = boot_load_efi_entry_pointers(config);
if (r < 0)
return r;
config->default_entry = boot_entries_select_default(config);
config->selected_entry = boot_entries_select_selected(config);
return 0;
}

View File

@ -49,10 +49,12 @@ typedef struct BootConfig {
char *entry_oneshot;
char *entry_default;
char *entry_selected;
BootEntry *entries;
size_t n_entries;
ssize_t default_entry;
ssize_t selected_entry;
} BootConfig;
static inline bool boot_config_has_entry(BootConfig *config, const char *id) {