summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/boot/bootctl.c54
-rw-r--r--src/login/logind-dbus.c6
-rw-r--r--src/shared/bootspec.c11
-rw-r--r--src/shared/bootspec.h33
4 files changed, 75 insertions, 29 deletions
diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c
index adc66788f8..ab514d28ee 100644
--- a/src/boot/bootctl.c
+++ b/src/boot/bootctl.c
@@ -36,6 +36,7 @@
#include "rm-rf.h"
#include "stat-util.h"
#include "stdio-util.h"
+#include "string-table.h"
#include "string-util.h"
#include "strv.h"
#include "sync-util.h"
@@ -411,10 +412,20 @@ static void boot_entry_file_list(const char *field, const char *root, const char
*ret_status = status;
}
+static const char* const boot_entry_type_table[_BOOT_ENTRY_TYPE_MAX] = {
+ [BOOT_ENTRY_CONF] = "Boot Loader Specification Type #1 (.conf)",
+ [BOOT_ENTRY_UNIFIED] = "Boot Loader Specification Type #2 (.efi)",
+ [BOOT_ENTRY_LOADER] = "Reported by Boot Loader",
+ [BOOT_ENTRY_LOADER_AUTO] = "Automatic",
+};
+
+DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(boot_entry_type, BootEntryType);
+
static int boot_entry_show(
const BootEntry *e,
bool show_as_default,
- bool show_as_selected) {
+ bool show_as_selected,
+ bool show_reported) {
int status = 0;
@@ -423,10 +434,30 @@ static int boot_entry_show(
assert(e);
- 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_magenta(), show_as_selected ? " (selected)" : "", ansi_normal());
+ printf(" type: %s\n",
+ boot_entry_type_to_string(e->type));
+
+ printf(" title: %s%s%s",
+ ansi_highlight(), boot_entry_title(e), ansi_normal());
+
+ if (show_as_default)
+ printf(" %s(default)%s",
+ ansi_highlight_green(), ansi_normal());
+
+ if (show_as_selected)
+ printf(" %s(selected)%s",
+ ansi_highlight_magenta(), ansi_normal());
+
+ if (show_reported) {
+ if (e->type == BOOT_ENTRY_LOADER)
+ printf(" %s(reported/absent)%s",
+ ansi_highlight_red(), ansi_normal());
+ else if (!e->reported_by_loader && e->type != BOOT_ENTRY_LOADER_AUTO)
+ printf(" %s(not reported/new)%s",
+ ansi_highlight_green(), ansi_normal());
+ }
+
+ putchar('\n');
if (e->id)
printf(" id: %s\n", e->id);
@@ -524,7 +555,11 @@ static int status_entries(
else {
printf("Default Boot Loader Entry:\n");
- r = boot_entry_show(config.entries + config.default_entry, /* show_as_default= */ false, /* show_as_selected= */ false);
+ r = boot_entry_show(
+ config.entries + config.default_entry,
+ /* show_as_default= */ false,
+ /* show_as_selected= */ false,
+ /* show_discovered= */ 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 */
@@ -1619,7 +1654,7 @@ static int verb_list(int argc, char *argv[], void *userdata) {
else if (r < 0)
log_warning_errno(r, "Failed to determine entries reported by boot loader, ignoring: %m");
else
- (void) boot_entries_augment_from_loader(&config, efi_entries, false);
+ (void) boot_entries_augment_from_loader(&config, efi_entries, /* only_auto= */ false);
if (config.n_entries == 0)
log_info("No boot loader entries found.");
@@ -1631,8 +1666,9 @@ static int verb_list(int argc, char *argv[], void *userdata) {
for (size_t n = 0; n < config.n_entries; n++) {
r = boot_entry_show(
config.entries + n,
- n == (size_t) config.default_entry,
- n == (size_t) config.selected_entry);
+ /* show_as_default= */ n == (size_t) config.default_entry,
+ /* show_as_selected= */ n == (size_t) config.selected_entry,
+ /* show_discovered= */ true);
if (r < 0)
return r;
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 72de58631a..32d619eecf 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -2923,9 +2923,9 @@ static int boot_loader_entry_exists(Manager *m, const char *id) {
r = manager_read_efi_boot_loader_entries(m);
if (r >= 0)
- (void) boot_entries_augment_from_loader(&config, m->efi_boot_loader_entries, true);
+ (void) boot_entries_augment_from_loader(&config, m->efi_boot_loader_entries, /* auto_only= */ true);
- return boot_config_has_entry(&config, id);
+ return !!boot_config_find_entry(&config, id);
}
static int method_set_reboot_to_boot_loader_entry(
@@ -3081,7 +3081,7 @@ static int property_get_boot_loader_entries(
r = manager_read_efi_boot_loader_entries(m);
if (r >= 0)
- (void) boot_entries_augment_from_loader(&config, m->efi_boot_loader_entries, true);
+ (void) boot_entries_augment_from_loader(&config, m->efi_boot_loader_entries, /* auto_only= */ true);
r = sd_bus_message_open_container(reply, 'a', "s");
if (r < 0)
diff --git a/src/shared/bootspec.c b/src/shared/bootspec.c
index 2d1d2b440b..15b77f01b2 100644
--- a/src/shared/bootspec.c
+++ b/src/shared/bootspec.c
@@ -561,7 +561,7 @@ static int boot_entries_find_unified(
return 0;
}
-static bool find_nonunique(BootEntry *entries, size_t n_entries, bool *arr) {
+static bool find_nonunique(const BootEntry *entries, size_t n_entries, bool arr[]) {
size_t i, j;
bool non_unique = false;
@@ -833,11 +833,15 @@ int boot_entries_augment_from_loader(
* already included there. */
STRV_FOREACH(i, found_by_loader) {
+ BootEntry *existing;
_cleanup_free_ char *c = NULL, *t = NULL, *p = NULL;
char **a, **b;
- if (boot_config_has_entry(config, *i))
+ existing = boot_config_find_entry(config, *i);
+ if (existing) {
+ existing->reported_by_loader = true;
continue;
+ }
if (only_auto && !startswith(*i, "auto-"))
continue;
@@ -862,10 +866,11 @@ int boot_entries_augment_from_loader(
return log_oom();
config->entries[config->n_entries++] = (BootEntry) {
- .type = BOOT_ENTRY_LOADER,
+ .type = startswith(*i, "auto-") ? BOOT_ENTRY_LOADER_AUTO : BOOT_ENTRY_LOADER,
.id = TAKE_PTR(c),
.title = TAKE_PTR(t),
.path = TAKE_PTR(p),
+ .reported_by_loader = true,
};
}
diff --git a/src/shared/bootspec.h b/src/shared/bootspec.h
index 8649e93bce..6f1014db4a 100644
--- a/src/shared/bootspec.h
+++ b/src/shared/bootspec.h
@@ -11,15 +11,17 @@
#include "string-util.h"
typedef enum BootEntryType {
- BOOT_ENTRY_CONF, /* Type #1 entries: *.conf files */
- BOOT_ENTRY_UNIFIED, /* Type #2 entries: *.efi files */
- BOOT_ENTRY_LOADER, /* Additional entries augmented from LoaderEntries EFI var */
- _BOOT_ENTRY_MAX,
- _BOOT_ENTRY_INVALID = -EINVAL,
+ BOOT_ENTRY_CONF, /* Boot Loader Specification Type #1 entries: *.conf files */
+ BOOT_ENTRY_UNIFIED, /* Boot Loader Specification Type #2 entries: *.efi files */
+ BOOT_ENTRY_LOADER, /* Additional entries augmented from LoaderEntries EFI variable (regular entries) */
+ BOOT_ENTRY_LOADER_AUTO, /* Additional entries augmented from LoaderEntries EFI variable (special "automatic" entries) */
+ _BOOT_ENTRY_TYPE_MAX,
+ _BOOT_ENTRY_TYPE_INVALID = -EINVAL,
} BootEntryType;
typedef struct BootEntry {
BootEntryType type;
+ bool reported_by_loader;
char *id; /* This is the file basename (including extension!) */
char *id_old; /* Old-style ID, for deduplication purposes. */
char *path; /* This is the full path to the drop-in file */
@@ -57,20 +59,21 @@ typedef struct BootConfig {
ssize_t selected_entry;
} BootConfig;
-static inline bool boot_config_has_entry(BootConfig *config, const char *id) {
- size_t j;
+static inline BootEntry* boot_config_find_entry(BootConfig *config, const char *id) {
+ assert(config);
+ assert(id);
- for (j = 0; j < config->n_entries; j++) {
- const char* entry_id_old = config->entries[j].id_old;
- if (streq(config->entries[j].id, id) ||
- (entry_id_old && streq(entry_id_old, id)))
- return true;
- }
+ for (size_t j = 0; j < config->n_entries; j++)
+ if (streq_ptr(config->entries[j].id, id) ||
+ streq_ptr(config->entries[j].id_old, id))
+ return config->entries + j;
- return false;
+ return NULL;
}
static inline BootEntry* boot_config_default_entry(BootConfig *config) {
+ assert(config);
+
if (config->default_entry < 0)
return NULL;
@@ -83,6 +86,8 @@ int boot_entries_load_config_auto(const char *override_esp_path, const char *ove
int boot_entries_augment_from_loader(BootConfig *config, char **list, bool only_auto);
static inline const char* boot_entry_title(const BootEntry *entry) {
+ assert(entry);
+
return entry->show_title ?: entry->title ?: entry->id;
}