]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
bootctl: display loader features in a pretty way.
authorLennart Poettering <lennart@poettering.net>
Mon, 22 Oct 2018 14:52:57 +0000 (16:52 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 16 Nov 2018 14:52:22 +0000 (15:52 +0100)
src/boot/bootctl.c
src/shared/efivars.c
src/shared/efivars.h

index 7a20965b6a8e61e4b3fe31921213cbe02ced9c1c..427faf8b242ab0708c3e965b72f7fb2368430475 100644 (file)
@@ -968,14 +968,28 @@ static int verb_status(int argc, char *argv[], void *userdata) {
         (void) pager_open(arg_pager_flags);
 
         if (is_efi_boot()) {
+                static const struct {
+                        uint64_t flag;
+                        const char *name;
+                } flags[] = {
+                        { EFI_LOADER_FEATURE_BOOT_COUNTING,           "Boot counting"                 },
+                        { EFI_LOADER_FEATURE_CONFIG_TIMEOUT,          "Menu timeout control"          },
+                        { EFI_LOADER_FEATURE_CONFIG_TIMEOUT_ONE_SHOT, "One-shot menu timeout control" },
+                        { EFI_LOADER_FEATURE_ENTRY_DEFAULT,           "Default entry control"         },
+                        { EFI_LOADER_FEATURE_ENTRY_ONESHOT,           "One-shot entry control"        },
+                };
+
                 _cleanup_free_ char *fw_type = NULL, *fw_info = NULL, *loader = NULL, *loader_path = NULL, *stub = NULL;
                 sd_id128_t loader_part_uuid = SD_ID128_NULL;
+                uint64_t loader_features = 0;
+                size_t i;
 
                 read_loader_efi_var("LoaderFirmwareType", &fw_type);
                 read_loader_efi_var("LoaderFirmwareInfo", &fw_info);
                 read_loader_efi_var("LoaderInfo", &loader);
                 read_loader_efi_var("StubInfo", &stub);
                 read_loader_efi_var("LoaderImageIdentifier", &loader_path);
+                (void) efi_loader_get_features(&loader_features);
 
                 if (loader_path)
                         efi_tilt_backslashes(loader_path);
@@ -992,6 +1006,20 @@ static int verb_status(int argc, char *argv[], void *userdata) {
 
                 printf("Current Boot Loader:\n");
                 printf("      Product: %s%s%s\n", ansi_highlight(), strna(loader), ansi_normal());
+
+                for (i = 0; i < ELEMENTSOF(flags); i++) {
+
+                        if (i == 0)
+                                printf("     Features: ");
+                        else
+                                printf("               ");
+
+                        if (FLAGS_SET(loader_features, flags[i].flag))
+                                printf("%s%s%s %s\n", ansi_highlight_green(), special_glyph(CHECK_MARK), ansi_normal(), flags[i].name);
+                        else
+                                printf("%s%s%s %s\n", ansi_highlight_red(), special_glyph(CROSS_MARK), ansi_normal(), flags[i].name);
+                }
+
                 if (stub)
                         printf("         Stub: %s\n", stub);
                 if (!sd_id128_is_null(loader_part_uuid))
index 7a9754096ce734d83d594f4cd1ef078817d1a1d5..e536f0d94ea8d24fe0532a7340575085f0da5273 100644 (file)
@@ -822,3 +822,53 @@ char *efi_tilt_backslashes(char *s) {
 
         return s;
 }
+
+int efi_loader_get_features(uint64_t *ret) {
+        _cleanup_free_ void *v = NULL;
+        size_t s;
+        int r;
+
+        if (!is_efi_boot()) {
+                *ret = 0;
+                return 0;
+        }
+
+        r = efi_get_variable(EFI_VENDOR_LOADER, "LoaderFeatures", NULL, &v, &s);
+        if (r == -ENOENT) {
+                _cleanup_free_ char *info = NULL;
+
+                /* The new (v240+) LoaderFeatures variable is not supported, let's see if it's systemd-boot at all */
+                r = efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderInfo", &info);
+                if (r < 0) {
+                        if (r != -ENOENT)
+                                return r;
+
+                        /* Variable not set, definitely means not systemd-boot */
+
+                } else if (first_word(info, "systemd-boot")) {
+
+                        /* An older systemd-boot version. Let's hardcode the feature set, since it was pretty
+                         * static in all its versions. */
+
+                        *ret = EFI_LOADER_FEATURE_CONFIG_TIMEOUT |
+                                EFI_LOADER_FEATURE_ENTRY_DEFAULT |
+                                EFI_LOADER_FEATURE_ENTRY_ONESHOT;
+
+                        return 0;
+                }
+
+                /* No features supported */
+                *ret = 0;
+                return 0;
+        }
+        if (r < 0)
+                return r;
+
+        if (s != sizeof(uint64_t)) {
+                log_debug("LoaderFeatures EFI variable doesn't have the right size.");
+                return -EINVAL;
+        }
+
+        memcpy(ret, v, sizeof(uint64_t));
+        return 0;
+}
index 9b5ab39fee2d3616032e3bd2836df7ad000aa729..feedbf91a6577079ab62458d8ae0afaed36f5519 100644 (file)
 #define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002
 #define EFI_VARIABLE_RUNTIME_ACCESS     0x0000000000000004
 
+#define EFI_LOADER_FEATURE_CONFIG_TIMEOUT          (UINT64_C(1) << 0)
+#define EFI_LOADER_FEATURE_CONFIG_TIMEOUT_ONE_SHOT (UINT64_C(1) << 1)
+#define EFI_LOADER_FEATURE_ENTRY_DEFAULT           (UINT64_C(1) << 2)
+#define EFI_LOADER_FEATURE_ENTRY_ONESHOT           (UINT64_C(1) << 3)
+#define EFI_LOADER_FEATURE_BOOT_COUNTING           (UINT64_C(1) << 4)
+
 #if ENABLE_EFI
 
 bool is_efi_boot(void);
@@ -43,6 +49,8 @@ int efi_loader_get_boot_usec(usec_t *firmware, usec_t *loader);
 
 int efi_loader_get_entries(char ***ret);
 
+int efi_loader_get_features(uint64_t *ret);
+
 #else
 
 static inline bool is_efi_boot(void) {
@@ -117,6 +125,10 @@ static inline int efi_loader_get_entries(char ***ret) {
         return -EOPNOTSUPP;
 }
 
+static inline int efi_loader_get_features(uint64_t *ret) {
+        return -EOPNOTSUPP;
+}
+
 #endif
 
 char *efi_tilt_backslashes(char *s);