summaryrefslogtreecommitdiff
path: root/usr.sbin/efibootmgr
diff options
context:
space:
mode:
authorWarner Losh <imp@FreeBSD.org>2018-05-08 19:43:57 +0000
committerWarner Losh <imp@FreeBSD.org>2018-05-08 19:43:57 +0000
commit51922c697be9ecd5e5674c60effc76750eaec250 (patch)
tree6994dce6bb600addf5b84317839d3b7392150bef /usr.sbin/efibootmgr
parent9669e724d18429d6a9c246c0fbe4de755e99c417 (diff)
downloadsrc-test2-51922c697be9ecd5e5674c60effc76750eaec250.tar.gz
src-test2-51922c697be9ecd5e5674c60effc76750eaec250.zip
Improve printing the boot variables.
Print the boot variables in the order in the BootOrder variable, if it exists, and then in verbose mode print any unreferneced BootXXXX variables. If BootOrder isn't set, fall back to printing all the variables. Sponsored by: Netflix
Notes
Notes: svn path=/head/; revision=333383
Diffstat (limited to 'usr.sbin/efibootmgr')
-rw-r--r--usr.sbin/efibootmgr/efibootmgr.c101
1 files changed, 73 insertions, 28 deletions
diff --git a/usr.sbin/efibootmgr/efibootmgr.c b/usr.sbin/efibootmgr/efibootmgr.c
index 0137fd9fb158..ef8b7f80cc6e 100644
--- a/usr.sbin/efibootmgr/efibootmgr.c
+++ b/usr.sbin/efibootmgr/efibootmgr.c
@@ -67,7 +67,7 @@ __FBSDID("$FreeBSD$");
#endif
#define BAD_LENGTH ((size_t)-1)
-
+
typedef struct _bmgr_opts {
char *env;
char *loader;
@@ -130,7 +130,8 @@ struct entry {
char *name;
char *label;
int idx;
- int part;
+ int flags;
+#define SEEN 1
LIST_ENTRY(entry) entries;
};
@@ -758,6 +759,31 @@ get_descr(uint8_t *data)
}
+static bool
+print_boot_var(const char *name, bool verbose, bool curboot)
+{
+ size_t size;
+ uint32_t load_attrs;
+ uint8_t *data;
+ int ret;
+ char *d;
+
+ ret = efi_get_variable(EFI_GLOBAL_GUID, name, &data, &size, NULL);
+ if (ret < 0)
+ return false;
+ load_attrs = le32dec(data);
+ d = get_descr(data);
+ printf("%c%s%c %s", curboot ? '+' : ' ', name,
+ ((load_attrs & LOAD_OPTION_ACTIVE) ? '*': ' '), d);
+ free(d);
+ if (verbose)
+ print_loadopt_str(data, size);
+ else
+ printf("\n");
+ return true;
+}
+
+
/* Cmd epilogue, or just the default with no args.
* The order is [bootnext] bootcurrent, timeout, order, and the bootvars [-v]
*/
@@ -770,10 +796,10 @@ print_boot_vars(bool verbose)
*/
struct entry *v;
uint8_t *data;
- char *d;
size_t size;
- uint32_t attrs, load_attrs;
- int ret;
+ uint32_t attrs;
+ int ret, bolen;
+ uint16_t *boot_order = NULL, current;
ret = efi_get_variable(EFI_GLOBAL_GUID, "BootNext", &data, &size, &attrs);
if (ret > 0) {
@@ -781,39 +807,58 @@ print_boot_vars(bool verbose)
}
ret = efi_get_variable(EFI_GLOBAL_GUID, "BootCurrent", &data, &size,&attrs);
- printf("BootCurrent: %04x\n", le16dec(data));
+ current = le16dec(data);
+ printf("BootCurrent: %04x\n", current);
ret = efi_get_variable(EFI_GLOBAL_GUID, "Timeout", &data, &size, &attrs);
if (ret > 0) {
- printf("Timeout : %d seconds\n", le16dec(data));
+ printf("Timeout : %d seconds\n", le16dec(data));
}
if (efi_get_variable(EFI_GLOBAL_GUID, "BootOrder", &data, &size, &attrs) > 0) {
if (size % 2 == 1)
warn("Bad BootOrder variable: odd length %d", (int)size);
- printf("BootOrder : ");
- for (size_t i = 0; i < size; i += 2)
- printf("%04x%s", le16dec(data + i), i == size - 2 ? "\n" : ", ");
+ boot_order = malloc(size);
+ bolen = size / 2;
+ printf("BootOrder : ");
+ for (size_t i = 0; i < size; i += 2) {
+ boot_order[i / 2] = le16dec(data + i);
+ printf("%04X%s", boot_order[i / 2], i == size - 2 ? "\n" : ", ");
+ }
}
- /* now we want to fetch 'em all fresh again
- * which possibly includes a newly created bootvar
- */
- LIST_FOREACH(v, &efivars, entries) {
- attrs = 0;
- ret = efi_get_variable(EFI_GLOBAL_GUID, v->name, &data,
- &size, &attrs);
- if (ret < 0)
- continue; /* we must have deleted it */
- load_attrs = le32dec(data);
- d = get_descr(data);
- printf("%s%c %s", v->name,
- ((load_attrs & LOAD_OPTION_ACTIVE) ? '*': ' '), d);
- free(d);
- if (verbose)
- print_loadopt_str(data, size);
- else
- printf("\n");
+ if (boot_order == NULL) {
+ /*
+ * now we want to fetch 'em all fresh again
+ * which possibly includes a newly created bootvar
+ */
+ LIST_FOREACH(v, &efivars, entries) {
+ print_boot_var(v->name, verbose, v->idx == current);
+ }
+ } else {
+ LIST_FOREACH(v, &efivars, entries) {
+ v->flags = 0;
+ }
+ for (int i = 0; i < bolen; i++) {
+ char buffer[10];
+
+ snprintf(buffer, sizeof(buffer), "Boot%04X", boot_order[i]);
+ if (!print_boot_var(buffer, verbose, boot_order[i] == current))
+ printf("%s: MISSING!\n", buffer);
+ LIST_FOREACH(v, &efivars, entries) {
+ if (v->idx == boot_order[i]) {
+ v->flags |= SEEN;
+ break;
+ }
+ }
+ }
+ if (verbose) {
+ printf("\n\nUnreferenced Variables:\n");
+ LIST_FOREACH(v, &efivars, entries) {
+ if (v->flags == 0)
+ print_boot_var(v->name, verbose, v->idx == current);
+ }
+ }
}
return 0;
}