From 534ba684da93d72e8f737affee6ee75570b4af37 Mon Sep 17 00:00:00 2001 From: krw Date: Sat, 12 Jun 2021 14:10:01 +0000 Subject: [PATCH] Create add_partition() and use in GPT_init() to initialize GPT with EFI SYS and OpenBSD partitions. Replaces some barbarian direct whacking of GPT. ok kettenis@ --- sbin/fdisk/gpt.c | 105 +++++++++++++++++++++++++++++++---------------- 1 file changed, 69 insertions(+), 36 deletions(-) diff --git a/sbin/fdisk/gpt.c b/sbin/fdisk/gpt.c index 77df94898b5..434071bc4c2 100644 --- a/sbin/fdisk/gpt.c +++ b/sbin/fdisk/gpt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gpt.c,v 1.21 2021/06/12 00:47:29 krw Exp $ */ +/* $OpenBSD: gpt.c,v 1.22 2021/06/12 14:10:01 krw Exp $ */ /* * Copyright (c) 2015 Markus Muller * Copyright (c) 2015 Kenneth R Westerback @@ -45,6 +45,7 @@ struct gpt_partition gp[NGPTPARTITIONS]; struct gpt_partition **sort_gpt(void); int lba_start_cmp(const void *e1, const void *e2); int lba_free(uint64_t *, uint64_t *); +int add_partition(const uint8_t *, const char *, uint64_t); int GPT_get_header(off_t where) @@ -302,13 +303,74 @@ GPT_print_part(int n, char *units, int verbosity) } } +int +add_partition(const uint8_t *beuuid, const char *name, uint64_t sectors) +{ + struct uuid uuid, gp_type; + int rslt; + uint64_t end, freesectors, start; + uint32_t status, pn, pncnt; + + uuid_dec_be(beuuid, &uuid); + uuid_enc_le(&gp_type, &uuid); + + pncnt = letoh32(gh.gh_part_num); + for (pn = 0; pn < pncnt; pn++) { + if (uuid_is_nil(&gp[pn].gp_type, NULL)) + break; + } + if (pn == pncnt) + goto done; + + rslt = lba_free(&start, &end); + if (rslt == -1) + goto done; + + if (start % 64) + start += (64 - start % 64); + if (start >= end) + goto done; + + freesectors = end - start + 1; + + if (sectors == 0) + sectors = freesectors; + + if (freesectors < sectors) + goto done; + else if (freesectors > sectors) + end = start + sectors - 1; + + gp[pn].gp_type = gp_type; + gp[pn].gp_lba_start = htole64(start); + gp[pn].gp_lba_end = htole64(end); + memcpy(gp[pn].gp_name, string_to_utf16le(name), + sizeof(gp[pn].gp_name)); + + uuid_create(&uuid, &status); + if (status != uuid_s_ok) + goto done; + + uuid_enc_le(&gp[pn].gp_guid, &uuid); + gh.gh_part_csum = crc32((unsigned char *)&gp, sizeof(gp)); + gh.gh_csum = crc32((unsigned char *)&gh, sizeof(gh)); + + return 0; + + done: + if (pn != pncnt) + memset(&gp[pn], 0, sizeof(gp[pn])); + printf("unable to add %s\n", name); + return 1; +} + int GPT_init(void) { extern uint32_t b_arg; const int secsize = unit_types[SECTORS].conversion; struct uuid guid; - int needed; + int needed, rslt; uint32_t status; const uint8_t gpt_uuid_efi_system[] = GPT_UUID_EFI_SYSTEM; const uint8_t gpt_uuid_openbsd[] = GPT_UUID_OPENBSD; @@ -339,46 +401,17 @@ GPT_init(void) return (1); uuid_enc_le(&gh.gh_guid, &guid); + rslt = 0; #if defined(__i386__) || defined(__amd64__) if (b_arg > 0) { - /* Add an EFI system partition on i386/amd64. */ - uuid_dec_be(gpt_uuid_efi_system, &guid); - uuid_enc_le(&gp[1].gp_type, &guid); - uuid_create(&guid, &status); - if (status != uuid_s_ok) - return (1); - uuid_enc_le(&gp[1].gp_guid, &guid); - gp[1].gp_lba_start = gh.gh_lba_start; - gp[1].gp_lba_end = htole64(letoh64(gh.gh_lba_start)+b_arg - 1); - memcpy(gp[1].gp_name, string_to_utf16le("EFI System Area"), - sizeof(gp[1].gp_name)); - } -#endif - uuid_dec_be(gpt_uuid_openbsd, &guid); - uuid_enc_le(&gp[3].gp_type, &guid); - uuid_create(&guid, &status); - if (status != uuid_s_ok) - return (1); - uuid_enc_le(&gp[3].gp_guid, &guid); - gp[3].gp_lba_start = gh.gh_lba_start; -#if defined(__i386__) || defined(__amd64__) - if (b_arg > 0) { - gp[3].gp_lba_start = htole64(letoh64(gp[3].gp_lba_start) + + rslt = add_partition(gpt_uuid_efi_system, "EFI System Area", b_arg); - if (letoh64(gp[3].gp_lba_start) % 64) - gp[3].gp_lba_start = - htole64(letoh64(gp[3].gp_lba_start) + - (64 - letoh64(gp[3].gp_lba_start) % 64)); } #endif - gp[3].gp_lba_end = gh.gh_lba_end; - memcpy(gp[3].gp_name, string_to_utf16le("OpenBSD Area"), - sizeof(gp[3].gp_name)); + if (rslt == 0) + rslt = add_partition(gpt_uuid_openbsd, "OpenBSD Area", 0); - gh.gh_part_csum = crc32((unsigned char *)&gp, sizeof(gp)); - gh.gh_csum = crc32((unsigned char *)&gh, sizeof(gh)); - - return 0; + return rslt; } int -- 2.20.1