From owner-svn-src-head@freebsd.org Tue May 8 19:43:58 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C8ECCFC7FF8; Tue, 8 May 2018 19:43:58 +0000 (UTC) (envelope-from imp@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 7A130842BC; Tue, 8 May 2018 19:43:58 +0000 (UTC) (envelope-from imp@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 5B9372EBF3; Tue, 8 May 2018 19:43:58 +0000 (UTC) (envelope-from imp@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w48JhwhX014351; Tue, 8 May 2018 19:43:58 GMT (envelope-from imp@FreeBSD.org) Received: (from imp@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w48JhwSc014350; Tue, 8 May 2018 19:43:58 GMT (envelope-from imp@FreeBSD.org) Message-Id: <201805081943.w48JhwSc014350@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: imp set sender to imp@FreeBSD.org using -f From: Warner Losh Date: Tue, 8 May 2018 19:43:58 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r333383 - head/usr.sbin/efibootmgr X-SVN-Group: head X-SVN-Commit-Author: imp X-SVN-Commit-Paths: head/usr.sbin/efibootmgr X-SVN-Commit-Revision: 333383 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 08 May 2018 19:43:59 -0000 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; }