Use a dedicated struct mbr to hold the GPT protective MBR,
authorkrw <krw@openbsd.org>
Wed, 21 Jul 2021 12:22:54 +0000 (12:22 +0000)
committerkrw <krw@openbsd.org>
Wed, 21 Jul 2021 12:22:54 +0000 (12:22 +0000)
either the one read from disk or the default one created
when initializing GPT.

Simplifies logic, eliminates MBR_init_GPT() and demotes
MBR_protective_mbr() to a helper function called from
GPT_read().

Nuke an unused variable in passing.

No intentional functional change.

sbin/fdisk/cmd.c
sbin/fdisk/fdisk.c
sbin/fdisk/gpt.c
sbin/fdisk/gpt.h
sbin/fdisk/mbr.c
sbin/fdisk/mbr.h
sbin/fdisk/user.c

index bea508e..ea9754c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cmd.c,v 1.133 2021/07/19 19:23:50 krw Exp $   */
+/*     $OpenBSD: cmd.c,v 1.134 2021/07/21 12:22:54 krw Exp $   */
 
 /*
  * Copyright (c) 1997 Tobias Weingartner
@@ -69,7 +69,6 @@ Xreinit(char *args, struct mbr *mbr)
        MBR_parse(&dos_mbr, mbr->mbr_lba_self, mbr->mbr_lba_firstembr, mbr);
 
        if (dogpt) {
-               MBR_init_GPT(mbr);
                GPT_init(GHANDGP);
                GPT_print("s", TERSE);
        } else {
@@ -429,10 +428,7 @@ Xselect(char *args, struct mbr *mbr)
 int
 Xprint(char *args, struct mbr *mbr)
 {
-       int                     efi;
-
-       efi = MBR_protective_mbr(mbr);
-       if (efi != -1 && letoh64(gh.gh_sig) == GPTSIGNATURE)
+       if (letoh64(gh.gh_sig) == GPTSIGNATURE)
                GPT_print(args, VERBOSE);
        else
                MBR_print(mbr, args);
@@ -443,7 +439,7 @@ Xprint(char *args, struct mbr *mbr)
 int
 Xwrite(char *args, struct mbr *mbr)
 {
-       int                     efi, i, n;
+       int                     i, n;
 
        for (i = 0, n = 0; i < NDOSPART; i++)
                if (mbr->mbr_prt[i].prt_id == 0xA6)
@@ -454,20 +450,18 @@ Xwrite(char *args, struct mbr *mbr)
                        return CMD_CONT;
        }
 
-       printf("Writing MBR at offset %lld.\n", (long long)mbr->mbr_lba_self);
-       if (MBR_write(mbr) == -1) {
-               warn("error writing MBR");
-               return CMD_CONT;
-       }
-
        if (letoh64(gh.gh_sig) == GPTSIGNATURE) {
                printf("Writing GPT.\n");
-               efi = MBR_protective_mbr(mbr);
-               if (efi == -1 || GPT_write() == -1) {
+               if (GPT_write() == -1) {
                        warn("error writing GPT");
                        return CMD_CONT;
                }
        } else {
+               printf("Writing MBR at offset %lld.\n", (long long)mbr->mbr_lba_self);
+               if (MBR_write(mbr) == -1) {
+                       warn("error writing MBR");
+                       return CMD_CONT;
+               }
                GPT_zap_headers();
        }
 
index efd9f79..6e9887f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: fdisk.c,v 1.127 2021/07/19 19:46:20 krw Exp $ */
+/*     $OpenBSD: fdisk.c,v 1.128 2021/07/21 12:22:54 krw Exp $ */
 
 /*
  * Copyright (c) 1997 Tobias Weingartner
@@ -163,22 +163,17 @@ main(int argc, char *argv[])
                err(1, "pledge");
 
        get_default_mbr(mbrfile, &initial_mbr);
-       error = MBR_read(0, 0, &mbr);
-       if (error)
-               errx(1, "Can't read MBR!");
 
        query = NULL;
        if (A_flag) {
                if (GPT_read(ANYGPT))
                        errx(1, "-A requires a valid GPT");
                else {
-                       initial_mbr = mbr;      /* Keep current MBR. */
                        GPT_init(GPONLY);
                        query = "Do you wish to write new GPT?";
                }
        } else if (i_flag) {
                if (g_flag) {
-                       MBR_init_GPT(&initial_mbr);
                        GPT_init(GHANDGP);
                        query = "Do you wish to write new GPT?";
                } else {
@@ -187,6 +182,9 @@ main(int argc, char *argv[])
                            "partition table?";
                }
        } else if (u_flag) {
+               error = MBR_read(0, 0, &mbr);
+               if (error)
+                       errx(1, "Can't read MBR!");
                memcpy(initial_mbr.mbr_prt, mbr.mbr_prt,
                    sizeof(initial_mbr.mbr_prt));
                query = "Do you wish to write new MBR?";
index 0252b7f..779b18f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: gpt.c,v 1.46 2021/07/18 15:28:37 krw Exp $    */
+/*     $OpenBSD: gpt.c,v 1.47 2021/07/21 12:22:54 krw Exp $    */
 /*
  * Copyright (c) 2015 Markus Muller <mmu@grummel.net>
  * Copyright (c) 2015 Kenneth R Westerback <krw@openbsd.org>
@@ -23,6 +23,7 @@
 
 #include <errno.h>
 #include <stdio.h>
+#include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
@@ -40,6 +41,7 @@
 #define DPRINTF(x...)
 #endif
 
+struct mbr             gmbr;
 struct gpt_header      gh;
 struct gpt_partition   gp[NGPTPARTITIONS];
 
@@ -52,6 +54,61 @@ int                    get_partition_table(void);
 int                      init_gh(void);
 int                      init_gp(const int);
 uint32_t                 crc32(const u_char *, const uint32_t);
+int                      protective_mbr(const struct mbr *);
+int                      gpt_chk_mbr(struct dos_partition *, uint64_t);
+
+/*
+ * Return the index into dp[] of the EFI GPT (0xEE) partition, or -1 if no such
+ * partition exists.
+ *
+ * Taken from kern/subr_disk.c.
+ *
+ */
+int
+gpt_chk_mbr(struct dos_partition *dp, u_int64_t dsize)
+{
+       struct dos_partition    *dp2;
+       int                      efi, eficnt, found, i;
+       uint32_t                 psize;
+
+       found = efi = eficnt = 0;
+       for (dp2 = dp, i = 0; i < NDOSPART; i++, dp2++) {
+               if (dp2->dp_typ == DOSPTYP_UNUSED)
+                       continue;
+               found++;
+               if (dp2->dp_typ != DOSPTYP_EFI)
+                       continue;
+               if (letoh32(dp2->dp_start) != GPTSECTOR)
+                       continue;
+               psize = letoh32(dp2->dp_size);
+               if (psize <= (dsize - GPTSECTOR) || psize == UINT32_MAX) {
+                       efi = i;
+                       eficnt++;
+               }
+       }
+       if (found == 1 && eficnt == 1)
+               return efi;
+
+       return -1;
+}
+
+int
+protective_mbr(const struct mbr *mbr)
+{
+       struct dos_partition    dp[NDOSPART], dos_partition;
+       int                     i;
+
+       if (mbr->mbr_lba_self != 0)
+               return -1;
+
+       for (i = 0; i < NDOSPART; i++) {
+               PRT_make(&mbr->mbr_prt[i], mbr->mbr_lba_self, mbr->mbr_lba_firstembr,
+                   &dos_partition);
+               memcpy(&dp[i], &dos_partition, sizeof(dp[i]));
+       }
+
+       return gpt_chk_mbr(dp, DL_GETDSIZE(&dl));
+}
 
 int
 get_header(const uint64_t sector)
@@ -206,12 +263,11 @@ get_partition_table(void)
 int
 GPT_read(const int which)
 {
-       struct mbr              mbr;
        int                     error;
 
-       error = MBR_read(0, 0, &mbr);
+       error = MBR_read(0, 0, &gmbr);
        if (error == 0)
-               error = MBR_protective_mbr(&mbr);
+               error = protective_mbr(&gmbr);
        if (error)
                goto done;
 
@@ -237,6 +293,7 @@ GPT_read(const int which)
  done:
        if (error != 0) {
                /* No valid GPT found. Zap any artifacts. */
+               memset(&gmbr, 0, sizeof(gmbr));
                memset(&gh, 0, sizeof(gh));
                memset(&gp, 0, sizeof(gp));
        }
@@ -395,6 +452,15 @@ init_gh(void)
 
        memcpy(&oldgh, &gh, sizeof(oldgh));
        memset(&gh, 0, sizeof(gh));
+       memset(&gmbr, 0, sizeof(gmbr));
+
+       /* XXX Do we need the boot code? UEFI spec & Apple says no. */
+       memcpy(gmbr.mbr_code, initial_mbr.mbr_code, sizeof(gmbr.mbr_code));
+       gmbr.mbr_prt[0].prt_id = DOSPTYP_EFI;
+       gmbr.mbr_prt[0].prt_bs = 1;
+       gmbr.mbr_prt[0].prt_ns = UINT32_MAX;
+       PRT_fix_CHS(&gmbr.mbr_prt[0]);
+       gmbr.mbr_signature = DOSMBR_SIGNATURE;
 
        needed = sizeof(gp) / secsize + 2;
 
@@ -508,6 +574,8 @@ GPT_write(void)
        const int                secsize = unit_types[SECTORS].ut_conversion;
        uint64_t                 altgh, altgp, prigh, prigp, gpbytes;
 
+       MBR_write(&gmbr);
+
        /*
         * XXX Assume size of gp is multiple of sector size.
         */
index ada2b33..e9a7007 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: gpt.h,v 1.17 2021/07/18 15:28:37 krw Exp $    */
+/*     $OpenBSD: gpt.h,v 1.18 2021/07/21 12:22:54 krw Exp $    */
 /*
  * Copyright (c) 2015 Markus Muller <mmu@grummel.net>
  * Copyright (c) 2015 Kenneth R Westerback <krw@openbsd.org>
@@ -27,6 +27,7 @@ void          GPT_print(const char *, const int);
 void           GPT_print_part(const int, const char *, const int);
 void           GPT_print_parthdr(const int);
 
+extern struct mbr              gmbr;
 extern struct gpt_header       gh;
 extern struct gpt_partition    gp[NGPTPARTITIONS];
 
index 3027c75..4aea7b7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mbr.c,v 1.93 2021/07/19 23:24:54 krw Exp $    */
+/*     $OpenBSD: mbr.c,v 1.94 2021/07/21 12:22:54 krw Exp $    */
 
 /*
  * Copyright (c) 1997 Tobias Weingartner
 
 struct mbr             initial_mbr;
 
-static int             gpt_chk_mbr(struct dos_partition *, uint64_t);
-
-int
-MBR_protective_mbr(const struct mbr *mbr)
-{
-       struct dos_partition    dp[NDOSPART], dos_partition;
-       int                     i;
-
-       if (mbr->mbr_lba_self != 0)
-               return -1;
-
-       for (i = 0; i < NDOSPART; i++) {
-               PRT_make(&mbr->mbr_prt[i], mbr->mbr_lba_self, mbr->mbr_lba_firstembr,
-                   &dos_partition);
-               memcpy(&dp[i], &dos_partition, sizeof(dp[i]));
-       }
-
-       return gpt_chk_mbr(dp, DL_GETDSIZE(&dl));
-}
-
-void
-MBR_init_GPT(struct mbr *mbr)
-{
-       memset(&mbr->mbr_prt, 0, sizeof(mbr->mbr_prt));
-
-       /* Use whole disk, starting after MBR.
-        *
-        * Always set the partition size to UINT32_MAX (as MS does). EFI
-        * firmware has been encountered that lies in unpredictable ways
-        * about the size of the disk, thus making it impossible to boot
-        * such devices.
-        */
-       mbr->mbr_prt[0].prt_id = DOSPTYP_EFI;
-       mbr->mbr_prt[0].prt_bs = 1;
-       mbr->mbr_prt[0].prt_ns = UINT32_MAX;
-
-       /* Fix up start/length fields. */
-       PRT_fix_CHS(&mbr->mbr_prt[0]);
-}
-
 void
 MBR_init(struct mbr *mbr)
 {
        uint64_t                adj;
        daddr_t                 daddr;
 
+       memset(&gmbr, 0, sizeof(gmbr));
        memset(&gh, 0, sizeof(gh));
        memset(&gp, 0, sizeof(gp));
 
@@ -243,38 +204,3 @@ MBR_write(const struct mbr *mbr)
 
        return 0;
 }
-
-/*
- * Return the index into dp[] of the EFI GPT (0xEE) partition, or -1 if no such
- * partition exists.
- *
- * Taken from kern/subr_disk.c.
- *
- */
-int
-gpt_chk_mbr(struct dos_partition *dp, u_int64_t dsize)
-{
-       struct dos_partition    *dp2;
-       int                      efi, eficnt, found, i;
-       uint32_t                 psize;
-
-       found = efi = eficnt = 0;
-       for (dp2 = dp, i = 0; i < NDOSPART; i++, dp2++) {
-               if (dp2->dp_typ == DOSPTYP_UNUSED)
-                       continue;
-               found++;
-               if (dp2->dp_typ != DOSPTYP_EFI)
-                       continue;
-               if (letoh32(dp2->dp_start) != GPTSECTOR)
-                       continue;
-               psize = letoh32(dp2->dp_size);
-               if (psize <= (dsize - GPTSECTOR) || psize == UINT32_MAX) {
-                       efi = i;
-                       eficnt++;
-               }
-       }
-       if (found == 1 && eficnt == 1)
-               return efi;
-
-       return -1;
-}
index 1a143c0..5329699 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mbr.h,v 1.39 2021/07/19 19:30:35 krw Exp $    */
+/*     $OpenBSD: mbr.h,v 1.40 2021/07/21 12:22:54 krw Exp $    */
 
 /*
  * Copyright (c) 1997 Tobias Weingartner
@@ -34,9 +34,7 @@ void          MBR_parse(const struct dos_mbr *, const uint64_t,
     const uint64_t, struct mbr *);
 void           MBR_make(const struct mbr *, struct dos_mbr *);
 void           MBR_init(struct mbr *);
-void           MBR_init_GPT(struct mbr *);
 int            MBR_read(const uint64_t, const uint64_t, struct mbr *);
 int            MBR_write(const struct mbr *);
-int            MBR_protective_mbr(const struct mbr *);
 
 #endif /* _MBR_H */
index ae5d1ed..94924c1 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: user.c,v 1.66 2021/07/19 23:24:54 krw Exp $   */
+/*     $OpenBSD: user.c,v 1.67 2021/07/21 12:22:54 krw Exp $   */
 
 /*
  * Copyright (c) 1997 Tobias Weingartner
@@ -62,7 +62,7 @@ USER_edit(const uint64_t lba_self, const uint64_t lba_firstembr)
 {
        struct mbr               mbr;
        char                    *cmd, *args;
-       int                      i, st, efi, error;
+       int                      i, st, error;
        static int               editlevel;
 
        /* One level deeper */