eficonfig: use efi_get_next_variable_name_int()
eficonfig command reads all possible UEFI load options from 0x0000 to 0xFFFF to construct the menu. This takes too much time in some environment. This commit uses efi_get_next_variable_name_int() to read all existing UEFI load options to significantlly reduce the count of efi_get_var() call. Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org>
This commit is contained in:
parent
3ac026ae46
commit
140a8959d4
141
cmd/eficonfig.c
141
cmd/eficonfig.c
|
@ -1683,7 +1683,8 @@ static efi_status_t eficonfig_show_boot_selection(unsigned int *selected)
|
|||
u32 i;
|
||||
u16 *bootorder;
|
||||
efi_status_t ret;
|
||||
efi_uintn_t num, size;
|
||||
u16 *var_name16 = NULL, *p;
|
||||
efi_uintn_t num, size, buf_size;
|
||||
struct efimenu *efi_menu;
|
||||
struct list_head *pos, *n;
|
||||
struct eficonfig_entry *entry;
|
||||
|
@ -1707,14 +1708,43 @@ static efi_status_t eficonfig_show_boot_selection(unsigned int *selected)
|
|||
}
|
||||
|
||||
/* list the remaining load option not included in the BootOrder */
|
||||
for (i = 0; i <= 0xFFFF; i++) {
|
||||
/* If the index is included in the BootOrder, skip it */
|
||||
if (search_bootorder(bootorder, num, i, NULL))
|
||||
continue;
|
||||
buf_size = 128;
|
||||
var_name16 = malloc(buf_size);
|
||||
if (!var_name16)
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
|
||||
ret = eficonfig_add_boot_selection_entry(efi_menu, i, selected);
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
var_name16[0] = 0;
|
||||
for (;;) {
|
||||
int index;
|
||||
efi_guid_t guid;
|
||||
|
||||
size = buf_size;
|
||||
ret = efi_get_next_variable_name_int(&size, var_name16, &guid);
|
||||
if (ret == EFI_NOT_FOUND)
|
||||
break;
|
||||
if (ret == EFI_BUFFER_TOO_SMALL) {
|
||||
buf_size = size;
|
||||
p = realloc(var_name16, buf_size);
|
||||
if (!p) {
|
||||
free(var_name16);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
var_name16 = p;
|
||||
ret = efi_get_next_variable_name_int(&size, var_name16, &guid);
|
||||
}
|
||||
if (ret != EFI_SUCCESS) {
|
||||
free(var_name16);
|
||||
return ret;
|
||||
}
|
||||
if (efi_varname_is_load_option(var_name16, &index)) {
|
||||
/* If the index is included in the BootOrder, skip it */
|
||||
if (search_bootorder(bootorder, num, index, NULL))
|
||||
continue;
|
||||
|
||||
ret = eficonfig_add_boot_selection_entry(efi_menu, index, selected);
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (efi_menu->count >= EFICONFIG_ENTRY_NUM_MAX - 1)
|
||||
break;
|
||||
|
@ -1732,6 +1762,8 @@ out:
|
|||
}
|
||||
eficonfig_destroy(efi_menu);
|
||||
|
||||
free(var_name16);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1994,6 +2026,8 @@ static efi_status_t eficonfig_create_change_boot_order_entry(struct efimenu *efi
|
|||
u32 i;
|
||||
char *title;
|
||||
efi_status_t ret;
|
||||
u16 *var_name16 = NULL, *p;
|
||||
efi_uintn_t size, buf_size;
|
||||
|
||||
/* list the load option in the order of BootOrder variable */
|
||||
for (i = 0; i < num; i++) {
|
||||
|
@ -2006,17 +2040,45 @@ static efi_status_t eficonfig_create_change_boot_order_entry(struct efimenu *efi
|
|||
}
|
||||
|
||||
/* list the remaining load option not included in the BootOrder */
|
||||
for (i = 0; i < 0xFFFF; i++) {
|
||||
buf_size = 128;
|
||||
var_name16 = malloc(buf_size);
|
||||
if (!var_name16)
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
|
||||
var_name16[0] = 0;
|
||||
for (;;) {
|
||||
int index;
|
||||
efi_guid_t guid;
|
||||
|
||||
if (efi_menu->count >= EFICONFIG_ENTRY_NUM_MAX - 2)
|
||||
break;
|
||||
|
||||
/* If the index is included in the BootOrder, skip it */
|
||||
if (search_bootorder(bootorder, num, i, NULL))
|
||||
continue;
|
||||
|
||||
ret = eficonfig_add_change_boot_order_entry(efi_menu, i, false);
|
||||
size = buf_size;
|
||||
ret = efi_get_next_variable_name_int(&size, var_name16, &guid);
|
||||
if (ret == EFI_NOT_FOUND)
|
||||
break;
|
||||
if (ret == EFI_BUFFER_TOO_SMALL) {
|
||||
buf_size = size;
|
||||
p = realloc(var_name16, buf_size);
|
||||
if (!p) {
|
||||
ret = EFI_OUT_OF_RESOURCES;
|
||||
goto out;
|
||||
}
|
||||
var_name16 = p;
|
||||
ret = efi_get_next_variable_name_int(&size, var_name16, &guid);
|
||||
}
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
|
||||
if (efi_varname_is_load_option(var_name16, &index)) {
|
||||
/* If the index is included in the BootOrder, skip it */
|
||||
if (search_bootorder(bootorder, num, index, NULL))
|
||||
continue;
|
||||
|
||||
ret = eficonfig_add_change_boot_order_entry(efi_menu, index, false);
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* add "Save" and "Quit" entries */
|
||||
|
@ -2035,9 +2097,9 @@ static efi_status_t eficonfig_create_change_boot_order_entry(struct efimenu *efi
|
|||
goto out;
|
||||
|
||||
efi_menu->active = 0;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
out:
|
||||
free(var_name16);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -2270,17 +2332,48 @@ out:
|
|||
efi_status_t eficonfig_delete_invalid_boot_option(struct eficonfig_media_boot_option *opt,
|
||||
efi_status_t count)
|
||||
{
|
||||
u32 i, j;
|
||||
u32 i;
|
||||
efi_uintn_t size;
|
||||
void *load_option;
|
||||
struct efi_load_option lo;
|
||||
u16 *var_name16 = NULL, *p;
|
||||
u16 varname[] = u"Boot####";
|
||||
efi_status_t ret = EFI_SUCCESS;
|
||||
efi_uintn_t varname_size, buf_size;
|
||||
|
||||
for (i = 0; i <= 0xFFFF; i++) {
|
||||
buf_size = 128;
|
||||
var_name16 = malloc(buf_size);
|
||||
if (!var_name16)
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
|
||||
var_name16[0] = 0;
|
||||
for (;;) {
|
||||
int index;
|
||||
efi_guid_t guid;
|
||||
efi_uintn_t tmp;
|
||||
|
||||
efi_create_indexed_name(varname, sizeof(varname), "Boot", i);
|
||||
varname_size = buf_size;
|
||||
ret = efi_get_next_variable_name_int(&varname_size, var_name16, &guid);
|
||||
if (ret == EFI_NOT_FOUND)
|
||||
break;
|
||||
if (ret == EFI_BUFFER_TOO_SMALL) {
|
||||
buf_size = varname_size;
|
||||
p = realloc(var_name16, buf_size);
|
||||
if (!p) {
|
||||
free(var_name16);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
var_name16 = p;
|
||||
ret = efi_get_next_variable_name_int(&varname_size, var_name16, &guid);
|
||||
}
|
||||
if (ret != EFI_SUCCESS) {
|
||||
free(var_name16);
|
||||
return ret;
|
||||
}
|
||||
if (!efi_varname_is_load_option(var_name16, &index))
|
||||
continue;
|
||||
|
||||
efi_create_indexed_name(varname, sizeof(varname), "Boot", index);
|
||||
load_option = efi_get_var(varname, &efi_global_variable_guid, &size);
|
||||
if (!load_option)
|
||||
continue;
|
||||
|
@ -2292,15 +2385,15 @@ efi_status_t eficonfig_delete_invalid_boot_option(struct eficonfig_media_boot_op
|
|||
|
||||
if (size >= sizeof(efi_guid_bootmenu_auto_generated)) {
|
||||
if (guidcmp(lo.optional_data, &efi_guid_bootmenu_auto_generated) == 0) {
|
||||
for (j = 0; j < count; j++) {
|
||||
if (opt[j].size == tmp &&
|
||||
memcmp(opt[j].lo, load_option, tmp) == 0) {
|
||||
opt[j].exist = true;
|
||||
for (i = 0; i < count; i++) {
|
||||
if (opt[i].size == tmp &&
|
||||
memcmp(opt[i].lo, load_option, tmp) == 0) {
|
||||
opt[i].exist = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (j == count) {
|
||||
if (i == count) {
|
||||
ret = delete_boot_option(i);
|
||||
if (ret != EFI_SUCCESS) {
|
||||
free(load_option);
|
||||
|
|
Loading…
Reference in New Issue
Block a user