summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sbin/fdisk/fdisk.817
-rw-r--r--sbin/fdisk/fdisk.c8
-rw-r--r--sbin/fdisk/gpt.c35
-rw-r--r--sbin/fdisk/part.c36
4 files changed, 82 insertions, 14 deletions
diff --git a/sbin/fdisk/fdisk.8 b/sbin/fdisk/fdisk.8
index b3ca9c5ec01..11083f06a55 100644
--- a/sbin/fdisk/fdisk.8
+++ b/sbin/fdisk/fdisk.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: fdisk.8,v 1.109 2022/02/03 13:24:04 visa Exp $
+.\" $OpenBSD: fdisk.8,v 1.110 2022/03/11 22:29:55 krw Exp $
.\"
.\"
.\" Copyright (c) 1997 Tobias Weingartner
@@ -15,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: February 3 2022 $
+.Dd $Mdocdate: March 11 2022 $
.Dt FDISK 8
.Os
.Sh NAME
@@ -69,6 +69,19 @@ all existing partitions except the boot partitions
.Sq HiFive FSBL
and
.Sq HiFive BBL .
+.Pp
+If one of
+.Sq APFS ISC ,
+.Sq APFS ,
+.Sq APFS Recovry
+is detected then any existing
+.Sq EFI system
+will also be preserved.
+If the preserved
+.Sq EFI system
+partition has fewer blocks than the number requested with
+.Fl b
+the modification of the GPT is aborted.
.It Fl b Ar blocks Ns Op @ Ns Ar offset Ns Op : Ns Ar type
Configures a special boot partition of the specified number of blocks, offset
and type.
diff --git a/sbin/fdisk/fdisk.c b/sbin/fdisk/fdisk.c
index 6df24f5a2d6..0a68b197e29 100644
--- a/sbin/fdisk/fdisk.c
+++ b/sbin/fdisk/fdisk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fdisk.c,v 1.142 2022/02/04 23:32:17 krw Exp $ */
+/* $OpenBSD: fdisk.c,v 1.143 2022/03/11 22:29:55 krw Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
@@ -167,14 +167,16 @@ main(int argc, char *argv[])
switch (init) {
case INIT_GPT:
- GPT_init(GHANDGP);
+ if (GPT_init(GHANDGP))
+ errx(1, "-g could not create valid GPT");
if (ask_yn("Do you wish to write new GPT?"))
Xwrite(NULL, &gmbr);
break;
case INIT_GPTPARTITIONS:
if (GPT_read(ANYGPT))
errx(1, "-A requires a valid GPT");
- GPT_init(GPONLY);
+ if (GPT_init(GPONLY))
+ errx(1, "-A could not create valid GPT");
if (ask_yn("Do you wish to write new GPT?"))
Xwrite(NULL, &gmbr);
break;
diff --git a/sbin/fdisk/gpt.c b/sbin/fdisk/gpt.c
index 1cb681ae6f0..61f2d6fd1ca 100644
--- a/sbin/fdisk/gpt.c
+++ b/sbin/fdisk/gpt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gpt.c,v 1.58 2022/02/04 23:32:17 krw Exp $ */
+/* $OpenBSD: gpt.c,v 1.59 2022/03/11 22:29:55 krw Exp $ */
/*
* Copyright (c) 2015 Markus Muller <mmu@grummel.net>
* Copyright (c) 2015 Kenneth R Westerback <krw@openbsd.org>
@@ -49,6 +49,7 @@ 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 find_partition(const uint8_t *);
int get_header(const uint64_t);
int get_partition_table(void);
int init_gh(void);
@@ -414,6 +415,23 @@ GPT_print_part(const int n, const char *units, const int verbosity)
}
int
+find_partition(const uint8_t *beuuid)
+{
+ struct uuid uuid, gp_type;
+ unsigned int 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_compare(&gp[pn].gp_type, &gp_type, NULL) == 0)
+ return pn;
+ }
+ return -1;
+}
+
+int
add_partition(const uint8_t *beuuid, const char *name, uint64_t sectors)
{
struct uuid uuid, gp_type;
@@ -529,6 +547,7 @@ init_gp(const int how)
struct gpt_partition oldgp[NGPTPARTITIONS];
const uint8_t gpt_uuid_efi_system[] = GPT_UUID_EFI_SYSTEM;
const uint8_t gpt_uuid_openbsd[] = GPT_UUID_OPENBSD;
+ uint64_t prt_ns;
int pn, rslt;
memcpy(&oldgp, &gp, sizeof(oldgp));
@@ -544,8 +563,18 @@ init_gp(const int how)
rslt = 0;
if (disk.dk_bootprt.prt_ns > 0) {
- rslt = add_partition(gpt_uuid_efi_system, "EFI System Area",
- disk.dk_bootprt.prt_ns);
+ pn = find_partition(gpt_uuid_efi_system);
+ if (pn == -1) {
+ rslt = add_partition(gpt_uuid_efi_system,
+ "EFI System Area", disk.dk_bootprt.prt_ns);
+ } else {
+ prt_ns = gp[pn].gp_lba_end - gp[pn].gp_lba_start + 1;
+ if (prt_ns < disk.dk_bootprt.prt_ns) {
+ printf("EFI System Area < %llu sectors\n",
+ disk.dk_bootprt.prt_ns);
+ rslt = -1;
+ }
+ }
}
if (rslt == 0)
rslt = add_partition(gpt_uuid_openbsd, "OpenBSD Area", 0);
diff --git a/sbin/fdisk/part.c b/sbin/fdisk/part.c
index cc10cda98af..32348cc551b 100644
--- a/sbin/fdisk/part.c
+++ b/sbin/fdisk/part.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: part.c,v 1.116 2022/02/04 23:32:17 krw Exp $ */
+/* $OpenBSD: part.c,v 1.117 2022/03/11 22:29:55 krw Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
@@ -29,6 +29,7 @@
#include "part.h"
#include "disk.h"
#include "misc.h"
+#include "gpt.h"
const char *ascii_id(const int);
@@ -183,26 +184,49 @@ const struct gpt_type gpt_types[] = {
int
PRT_protected_guid(const struct uuid *uuid)
{
- char *str = NULL;
+ const uint8_t gpt_uuid_efi_system[] = GPT_UUID_EFI_SYSTEM;
+ struct uuid uuid_efi_system;
+ char *efistr = NULL, *str = NULL;
+ char *typename;
int rslt = 0;
unsigned int i;
uint32_t status;
+ uuid_dec_be(gpt_uuid_efi_system, &uuid_efi_system);
+
+ uuid_to_string(&uuid_efi_system, &efistr, &status);
+ if (status != uuid_s_ok) {
+ rslt = -1;
+ goto done;
+ }
uuid_to_string(uuid, &str, &status);
if (status != uuid_s_ok) {
rslt = -1;
goto done;
}
- for(i = 0; i < nitems(gpt_types); i++) {
- if (strncmp(str, gpt_types[i].gt_guid, UUID_STR_LEN) == 0) {
- if (gpt_types[i].gt_protected)
- rslt = -1;
+ if (strncmp(str, efistr, UUID_STR_LEN) == 0) {
+ /* Look for partitions indicating a need to preserve EFI Sys */
+ for (i = 0; i < NGPTPARTITIONS; i++) {
+ typename = PRT_uuid_to_typename(&gp[i].gp_type);
+ if (strncmp(typename, "APFS ", 5))
+ continue;
+ rslt = -1;
break;
}
+ } else {
+ for(i = 0; i < nitems(gpt_types); i++) {
+ if (strncmp(str, gpt_types[i].gt_guid, UUID_STR_LEN))
+ continue;
+ if (gpt_types[i].gt_protected) {
+ rslt = -1;
+ break;
+ }
+ }
}
done:
+ free(efistr);
free(str);
return rslt;
}