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
This commit is contained in:
Warner Losh 2018-05-08 19:43:57 +00:00
parent 9669e724d1
commit 51922c697b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=333383

View File

@ -67,7 +67,7 @@ __FBSDID("$FreeBSD$");
#endif #endif
#define BAD_LENGTH ((size_t)-1) #define BAD_LENGTH ((size_t)-1)
typedef struct _bmgr_opts { typedef struct _bmgr_opts {
char *env; char *env;
char *loader; char *loader;
@ -130,7 +130,8 @@ struct entry {
char *name; char *name;
char *label; char *label;
int idx; int idx;
int part; int flags;
#define SEEN 1
LIST_ENTRY(entry) entries; 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. /* Cmd epilogue, or just the default with no args.
* The order is [bootnext] bootcurrent, timeout, order, and the bootvars [-v] * The order is [bootnext] bootcurrent, timeout, order, and the bootvars [-v]
*/ */
@ -770,10 +796,10 @@ print_boot_vars(bool verbose)
*/ */
struct entry *v; struct entry *v;
uint8_t *data; uint8_t *data;
char *d;
size_t size; size_t size;
uint32_t attrs, load_attrs; uint32_t attrs;
int ret; int ret, bolen;
uint16_t *boot_order = NULL, current;
ret = efi_get_variable(EFI_GLOBAL_GUID, "BootNext", &data, &size, &attrs); ret = efi_get_variable(EFI_GLOBAL_GUID, "BootNext", &data, &size, &attrs);
if (ret > 0) { if (ret > 0) {
@ -781,39 +807,58 @@ print_boot_vars(bool verbose)
} }
ret = efi_get_variable(EFI_GLOBAL_GUID, "BootCurrent", &data, &size,&attrs); 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); ret = efi_get_variable(EFI_GLOBAL_GUID, "Timeout", &data, &size, &attrs);
if (ret > 0) { 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 (efi_get_variable(EFI_GLOBAL_GUID, "BootOrder", &data, &size, &attrs) > 0) {
if (size % 2 == 1) if (size % 2 == 1)
warn("Bad BootOrder variable: odd length %d", (int)size); warn("Bad BootOrder variable: odd length %d", (int)size);
printf("BootOrder : "); boot_order = malloc(size);
for (size_t i = 0; i < size; i += 2) bolen = size / 2;
printf("%04x%s", le16dec(data + i), i == size - 2 ? "\n" : ", "); 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 if (boot_order == NULL) {
* which possibly includes a newly created bootvar /*
*/ * now we want to fetch 'em all fresh again
LIST_FOREACH(v, &efivars, entries) { * which possibly includes a newly created bootvar
attrs = 0; */
ret = efi_get_variable(EFI_GLOBAL_GUID, v->name, &data, LIST_FOREACH(v, &efivars, entries) {
&size, &attrs); print_boot_var(v->name, verbose, v->idx == current);
if (ret < 0) }
continue; /* we must have deleted it */ } else {
load_attrs = le32dec(data); LIST_FOREACH(v, &efivars, entries) {
d = get_descr(data); v->flags = 0;
printf("%s%c %s", v->name, }
((load_attrs & LOAD_OPTION_ACTIVE) ? '*': ' '), d); for (int i = 0; i < bolen; i++) {
free(d); char buffer[10];
if (verbose)
print_loadopt_str(data, size); snprintf(buffer, sizeof(buffer), "Boot%04X", boot_order[i]);
else if (!print_boot_var(buffer, verbose, boot_order[i] == current))
printf("\n"); 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; return 0;
} }