static int status_variables(void) { int n_options, n_order; uint16_t *options = NULL, *order = NULL; int r, i; if (!is_efi_boot()) { fprintf(stderr, "Not booted with EFI, not showing EFI variables.\n"); return 0; } n_options = efi_get_boot_options(&options); if (n_options < 0) { if (n_options == -ENOENT) fprintf(stderr, "Failed to access EFI variables, " "efivarfs needs to be available at /sys/firmware/efi/efivars/.\n"); else fprintf(stderr, "Failed to read EFI boot entries: %s\n", strerror(-n_options)); r = n_options; goto finish; } printf("Boot Loader Entries in EFI Variables:\n"); n_order = efi_get_boot_order(&order); if (n_order == -ENOENT) { n_order = 0; } else if (n_order < 0) { fprintf(stderr, "Failed to read EFI boot order.\n"); r = n_order; goto finish; } /* print entries in BootOrder first */ for (i = 0; i < n_order; i++) print_efi_option(order[i], true); /* print remaining entries */ for (i = 0; i < n_options; i++) { int j; bool found = false; for (j = 0; j < n_order; j++) if (options[i] == order[j]) { found = true; break; } if (found) continue; print_efi_option(options[i], false); } r = 0; finish: free(options); free(order); return r; }
static int insert_into_order(uint16_t slot, bool first) { uint16_t *order = NULL; uint16_t *new_order; int n_order; int i; int err = 0; n_order = efi_get_boot_order(&order); if (n_order <= 0) { /* no entry, add us */ err = efi_set_boot_order(&slot, 1); goto finish; } /* are we the first and only one? */ if (n_order == 1 && order[0] == slot) goto finish; /* are we already in the boot order? */ for (i = 0; i < n_order; i++) { if (order[i] != slot) continue; /* we do not require to be the first one, all is fine */ if (!first) goto finish; /* move us to the first slot */ memmove(&order[1], order, i * sizeof(uint16_t)); order[0] = slot; efi_set_boot_order(order, n_order); goto finish; } /* extend array */ new_order = realloc(order, (n_order+1) * sizeof(uint16_t)); if (!new_order) { err = -ENOMEM; goto finish; } order = new_order; /* add us to the top or end of the list */ if (first) { memmove(&order[1], order, n_order * sizeof(uint16_t)); order[0] = slot; } else order[n_order] = slot; efi_set_boot_order(order, n_order+1); finish: free(order); return err; }
static int insert_into_order(uint16_t slot, bool first) { _cleanup_free_ uint16_t *order = NULL; uint16_t *t; int n, i; n = efi_get_boot_order(&order); if (n <= 0) /* no entry, add us */ return efi_set_boot_order(&slot, 1); /* are we the first and only one? */ if (n == 1 && order[0] == slot) return 0; /* are we already in the boot order? */ for (i = 0; i < n; i++) { if (order[i] != slot) continue; /* we do not require to be the first one, all is fine */ if (!first) return 0; /* move us to the first slot */ memmove(order + 1, order, i * sizeof(uint16_t)); order[0] = slot; return efi_set_boot_order(order, n); } /* extend array */ t = realloc(order, (n + 1) * sizeof(uint16_t)); if (!t) return -ENOMEM; order = t; /* add us to the top or end of the list */ if (first) { memmove(order + 1, order, n * sizeof(uint16_t)); order[0] = slot; } else order[n] = slot; return efi_set_boot_order(order, n + 1); }
static int remove_from_order(uint16_t slot) { _cleanup_free_ uint16_t *order = NULL; int n, i; n = efi_get_boot_order(&order); if (n <= 0) return n; for (i = 0; i < n; i++) { if (order[i] != slot) continue; if (i + 1 < n) memmove(order + i, order + i+1, (n - i) * sizeof(uint16_t)); return efi_set_boot_order(order, n - 1); } return 0; }
static int status_variables(void) { int n_options, n_order; _cleanup_free_ uint16_t *options = NULL, *order = NULL; int i; if (!is_efi_boot()) { log_notice("Not booted with EFI, not showing EFI variables."); return 0; } n_options = efi_get_boot_options(&options); if (n_options == -ENOENT) return log_error_errno(ENOENT, "Failed to access EFI variables, efivarfs" " needs to be available at /sys/firmware/efi/efivars/."); else if (n_options < 0) return log_error_errno(n_options, "Failed to read EFI boot entries: %m"); n_order = efi_get_boot_order(&order); if (n_order == -ENOENT) n_order = 0; else if (n_order < 0) return log_error_errno(n_order, "Failed to read EFI boot order."); /* print entries in BootOrder first */ printf("Boot Loader Entries in EFI Variables:\n"); for (i = 0; i < n_order; i++) print_efi_option(order[i], true); /* print remaining entries */ for (i = 0; i < n_options; i++) { int j; for (j = 0; j < n_order; j++) if (options[i] == order[j]) goto next; print_efi_option(options[i], false); next: continue; } return 0; }
static int get_boot_order(struct boot_info *info) { size_t i, k; int r; r = efi_get_boot_order(&info->fw_entries_order); if (r < 0) return r; info->fw_entries_order_count = r; for (i = 0; i < info->fw_entries_order_count; i++) { for (k = 0; k < info->fw_entries_count; k++) { if (info->fw_entries[k].id != info->fw_entries_order[i]) continue; info->fw_entries[k].order = i; break; } } return 0; }
static int remove_from_order(uint16_t slot) { _cleanup_free_ uint16_t *order = NULL; int n_order; int i; int err = 0; n_order = efi_get_boot_order(&order); if (n_order < 0) return n_order; if (n_order == 0) return 0; for (i = 0; i < n_order; i++) { if (order[i] != slot) continue; if (i+1 < n_order) memmove(&order[i], &order[i+1], (n_order - i) * sizeof(uint16_t)); efi_set_boot_order(order, n_order-1); break; } return err; }