svn commit: r333383 - head/usr.sbin/efibootmgr

Warner Losh imp at FreeBSD.org
Tue May 8 19:43:59 UTC 2018


Author: imp
Date: Tue May  8 19:43:57 2018
New Revision: 333383
URL: https://svnweb.freebsd.org/changeset/base/333383

Log:
  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

Modified:
  head/usr.sbin/efibootmgr/efibootmgr.c

Modified: head/usr.sbin/efibootmgr/efibootmgr.c
==============================================================================
--- head/usr.sbin/efibootmgr/efibootmgr.c	Tue May  8 18:48:51 2018	(r333382)
+++ head/usr.sbin/efibootmgr/efibootmgr.c	Tue May  8 19:43:57 2018	(r333383)
@@ -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;
 }


More information about the svn-src-head mailing list