Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:42.2:Ports
efibootmgr
efibootmgr-delete-multiple.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File efibootmgr-delete-multiple.diff of Package efibootmgr
From: Raymund Will <rw@suse.com> Subject: Delete boot entries based on partition UUID. References: bsc#870211, bsc#945705 Signed-off-by: Raymund Will <rw@suse.com> --- src/efibootmgr/efibootmgr.c | 149 +++++++++++++++++++++++++++++++++++++++++++- src/include/efibootmgr.h | 2 2 files changed, 149 insertions(+), 2 deletions(-) --- a/src/efibootmgr/efibootmgr.c +++ b/src/efibootmgr/efibootmgr.c @@ -467,6 +467,109 @@ delete_boot_var(uint16_t num) return EFI_SUCCESS; } +static int +delete_boot_uuid(char *uuid_str) +{ + int count = 0; + list_t *pos, *tmp; + var_entry_t *boot; + char description[80]; + EFI_LOAD_OPTION *load_option; + EFI_DEVICE_PATH *path; + char text_path[1024]; + + list_for_each_safe(pos, tmp, &boot_entry_list) { + boot = list_entry(pos, var_entry_t, list); + load_option = (EFI_LOAD_OPTION *)boot->var_data.Data; + path = load_option_path(load_option); + memset(text_path, 0, sizeof(text_path)); + unparse_path(text_path, path, + load_option->file_path_list_length); + if (strlen(text_path) == 0) + continue; + if (strcasestr(text_path, uuid_str) == NULL) + continue; + /* found! */ + if (opts.verbose) { + efichar_to_char(description, load_option->description, + sizeof(description)); + printf("Delete Boot%04X %s\t%s\n", + boot->num, description, text_path); + } + if (delete_boot_var(boot->num) != EFI_SUCCESS) + return -1; + count++; + } + if (count==0) { + /* Nothing changed => exit early */ + exit(0); + } + return 0; +} + +static int +delete_boot_diskpart(char *disk, uint32_t part) +{ + int fd, rc; + uint64_t start, size; +#define MLEN 80 + char signature[16], sigstr[40], msg[MLEN+1]; + uint8_t mbr_type, signature_type; + + memset(signature, 0, sizeof(signature)); + + fd = open(disk, O_RDONLY|O_DIRECT); + if (fd == -1) { + snprintf(msg, MLEN, "Could not open disk %s", disk); + msg[MLEN] = 0; + perror(msg); + return -1; + } + rc = disk_get_partition_info(fd, part, &start, &size, signature, + &mbr_type, &signature_type); + close(fd); + if (rc) + return -1; + if (mbr_type != 0x02) { + snprintf(msg, MLEN, "Cowardly refusing non-GPT disk %s", disk); + msg[MLEN] = 0; + perror(msg); + return -1; + } + efi_guid_unparse((efi_guid_t *)signature, sigstr); + + if (opts.verbose) { + printf("About to delete all entries referring to UUID %s\n", + sigstr); + } + return delete_boot_uuid(sigstr); +} + +static int +check_uuid(const char *s) +{ + /* algorithm derived from efivar-0.15/src/guid.h */ + int len = 36; + unsigned int i; + if (strlen(s) != len) + return -1; + for (i = 0; i < len; i++) { + if (i == 8 || i == 13 || i == 18 || i == 23) { + if (s[i] != '-') + return -1; + continue; + } + if (s[i] >= '0' && s[i] <= '9') + continue; + /* "| 0x20" is tolower() without having to worry about + * locale concerns, since we know everything here must + * be within traditional ascii space. */ + if ((s[i] | 0x20) >= 'a' && (s[i] | 0x20) <= 'f') + continue; + return -1; + } + return 0; +} static void set_var_nums(const char *pattern, list_t *list) @@ -786,8 +889,10 @@ usage() printf("\t-a | --active sets bootnum active\n"); printf("\t-A | --inactive sets bootnum inactive\n"); printf("\t-b | --bootnum XXXX modify BootXXXX (hex)\n"); - printf("\t-B | --delete-bootnum delete bootnum (hex)\n"); + printf("\t-B | --delete-bootnum delete bootnum (specified with -b)\n"); printf("\t-c | --create create new variable bootnum and add to bootorder\n"); + printf("\t-C | --delete delete entry by bootnum (-b), by UUID (-P)\n"); + printf("\t or by disk+partition (-d -p)\n"); printf("\t-d | --disk disk (defaults to /dev/sda) containing loader\n"); printf("\t-e | --edd [1|3|-1] force EDD 1.0 or 3.0 creation variables, or guess\n"); printf("\t-E | --device num EDD 1.0 device number (defaults to 0x80)\n"); @@ -801,6 +906,7 @@ usage() printf("\t-o | --bootorder XXXX,YYYY,ZZZZ,... explicitly set BootOrder (hex)\n"); printf("\t-O | --delete-bootorder delete BootOrder\n"); printf("\t-p | --part part (defaults to 1) containing loader\n"); + printf("\t-P | --part-uuid UUID select all variables for given partition UUID\n"); printf("\t-q | --quiet be quiet\n"); printf("\t | --test filename don't write to NVRAM, write to filename.\n"); printf("\t-t | --timeout seconds set boot manager timeout waiting for user input.\n"); @@ -829,6 +935,7 @@ set_default_opts() opts.part = 1; opts.acpi_hid = -1; opts.acpi_uid = -1; + opts.part_uuid = NULL; } static void @@ -847,6 +954,7 @@ parse_opts(int argc, char **argv) {"bootnum", required_argument, 0, 'b'}, {"delete-bootnum", no_argument, 0, 'B'}, {"create", no_argument, 0, 'c'}, + {"delete", no_argument, 0, 'C'}, {"disk", required_argument, 0, 'd'}, {"iface", required_argument, 0, 'i'}, {"acpi_hid", required_argument, 0, 'H'}, @@ -860,6 +968,7 @@ parse_opts(int argc, char **argv) {"bootorder", required_argument, 0, 'o'}, {"delete-bootorder", no_argument, 0, 'O'}, {"part", required_argument, 0, 'p'}, + {"part-uuid", required_argument, 0, 'P'}, {"quiet", no_argument, 0, 'q'}, {"test", required_argument, 0, 1}, {"timeout", required_argument, 0, 't'}, @@ -875,7 +984,8 @@ parse_opts(int argc, char **argv) }; c = getopt_long (argc, argv, - "AaBb:cd:e:E:gH:i:l:L:n:No:Op:qt:TuU:v::Vw@:", + "AaBb:cCd:e:E:gH:i:l:L:n:N" + "o:Op:P:qt:TuU:v::Vw@:", long_options, &option_index); if (c == -1) break; @@ -905,8 +1015,12 @@ parse_opts(int argc, char **argv) case 'c': opts.create = 1; break; + case 'C': + opts.delete |= 1; + break; case 'd': opts.disk = optarg; + opts.delete |= 2; break; case 'e': rc = sscanf(optarg, "%d", &num); @@ -968,7 +1082,18 @@ parse_opts(int argc, char **argv) fprintf (stderr,"invalid numeric value %s\n",optarg); exit(1); } + opts.delete |= 4; break; + case 'P': + if ((rc=check_uuid(optarg)) < 0) { + fprintf(stderr, + "malformed partition UUID: %s (%d)\n", + optarg, rc); + exit(1); + } + opts.part_uuid = optarg; + break; + case 'q': opts.quiet = 1; break; @@ -1073,6 +1198,26 @@ main(int argc, char **argv) ret = delete_boot_var(opts.bootnum); } + if (opts.delete & 1) { + if (opts.part_uuid) { + ret = delete_boot_uuid(opts.part_uuid); + if (ret < 0) { + fprintf(stderr, "\nCould not delete boot variables.\n\n"); + return 1; + } + } else if (opts.delete & 6) { + ret = delete_boot_diskpart(opts.disk, opts.part); + if (ret < 0) { + fprintf(stderr, "\nCould not delete boot variables.\n\n"); + return 1; + } + } else if (opts.bootnum != -1) { + ret = delete_boot_var(opts.bootnum); + } else { + fprintf(stderr, "\nYou must specify a boot entry to delete.\n\n"); + return 1; + } + } if (opts.active >= 0) { if (opts.bootnum == -1) { fprintf(stderr, "\nYou must specify a boot entry to delete (see the -b option).\n\n"); --- a/src/include/efibootmgr.h +++ b/src/include/efibootmgr.h @@ -32,6 +32,7 @@ typedef struct { char *bootorder; char *testfile; char *extra_opts_file; + char *part_uuid; uint32_t part; int edd_version; int edd10_devicenum; @@ -39,6 +40,7 @@ typedef struct { int bootnext; int verbose; int active; + int delete; uint32_t acpi_hid; uint32_t acpi_uid; unsigned int delete_boot:1;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor