]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
bootspec: also collect/mark the "selected" boot entry (i.e. the one currently booted)
authorLennart Poettering <lennart@poettering.net>
Fri, 11 Feb 2022 13:41:00 +0000 (14:41 +0100)
committerLennart Poettering <lennart@poettering.net>
Mon, 14 Feb 2022 14:44:07 +0000 (15:44 +0100)
it's helpful and easy, so let's do it

src/boot/bootctl.c
src/shared/bootspec.c
src/shared/bootspec.h

index d94a2a586ba5e88f79d54117a372c15cb1b1dbb3..adc66788f857d1f3b79ed3a52bb0f50fb1b23277 100644 (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;
 
index 65a040f26dd1a7c887636fdd0caa59e374681577..2d1d2b440b26dc1c5c8d571cd58142dc8e81fb3c 100644 (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;
 }
 
index 62b3f6ce5f140f3fb8d8e2d626862c7d5a18e8ff..8649e93bcef84c9132e44cdadc18edf7d8428c16 100644 (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) {