Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sbin/gpt - fix setting of hdr_lba_alt which was broken in re...



details:   https://anonhg.NetBSD.org/src/rev/f8eeb74c9639
branches:  trunk
changeset: 816014:f8eeb74c9639
user:      jnemeth <jnemeth%NetBSD.org@localhost>
date:      Sun Jun 12 12:48:32 2016 +0000

description:
- fix setting of hdr_lba_alt which was broken in revision 1.10 on 2015/12/2
- switch to using gpt_last
- PR/51230 -- recreate the PMBR if it was lost

diffstat:

 sbin/gpt/recover.c |  46 ++++++++++++++++++++++++++++++++++++----------
 1 files changed, 36 insertions(+), 10 deletions(-)

diffs (104 lines):

diff -r d2ae89ac0159 -r f8eeb74c9639 sbin/gpt/recover.c
--- a/sbin/gpt/recover.c        Sun Jun 12 10:14:12 2016 +0000
+++ b/sbin/gpt/recover.c        Sun Jun 12 12:48:32 2016 +0000
@@ -33,7 +33,7 @@
 __FBSDID("$FreeBSD: src/sbin/gpt/recover.c,v 1.8 2005/08/31 01:47:19 marcel Exp $");
 #endif
 #ifdef __RCSID
-__RCSID("$NetBSD: recover.c,v 1.15 2015/12/04 16:46:24 christos Exp $");
+__RCSID("$NetBSD: recover.c,v 1.16 2016/06/12 12:48:32 jnemeth Exp $");
 #endif
 
 #include <sys/types.h>
@@ -68,7 +68,7 @@
 recover_gpt_hdr(gpt_t gpt, int type, off_t last)
 {
        const char *name, *origname;
-       map_t *dgpt, dtbl, sgpt, stbl;
+       map_t *dgpt, dtbl, sgpt, stbl __unused;
        struct gpt_hdr *hdr;
 
        if (gpt_add_hdr(gpt, type, last) == -1)
@@ -99,7 +99,7 @@
        memcpy((*dgpt)->map_data, sgpt->map_data, gpt->secsz);
        hdr = (*dgpt)->map_data;
        hdr->hdr_lba_self = htole64((uint64_t)(*dgpt)->map_start);
-       hdr->hdr_lba_alt = htole64((uint64_t)stbl->map_start);
+       hdr->hdr_lba_alt = htole64((uint64_t)sgpt->map_start);
        hdr->hdr_lba_table = htole64((uint64_t)dtbl->map_start);
        hdr->hdr_crc_self = 0;
        hdr->hdr_crc_self = htole32(crc32(hdr, le32toh(hdr->hdr_size)));
@@ -151,7 +151,9 @@
 static int
 recover(gpt_t gpt, int recoverable)
 {
-       uint64_t last;
+       off_t last = gpt_last(gpt);
+       map_t map;
+       struct mbr *mbr;
 
        if (map_find(gpt, MAP_TYPE_MBR) != NULL) {
                gpt_warnx(gpt, "Device contains an MBR");
@@ -174,10 +176,9 @@
                return -1;
        }
 
-       last = (uint64_t)(gpt->mediasz / gpt->secsz - 1LL);
-
        if (gpt->gpt != NULL &&
-           ((struct gpt_hdr *)(gpt->gpt->map_data))->hdr_lba_alt != last) {
+           ((struct gpt_hdr *)(gpt->gpt->map_data))->hdr_lba_alt !=
+           (uint64_t)last) {
                gpt_warnx(gpt, "Media size has changed, please use "
                   "'%s resizedisk'", getprogname());
                return -1;
@@ -185,7 +186,7 @@
 
        if (gpt->tbl != NULL && gpt->lbt == NULL) {
                if (recover_gpt_tbl(gpt, MAP_TYPE_SEC_GPT_TBL,
-                   (off_t)last - gpt->tbl->map_size) == -1)
+                   last - gpt->tbl->map_size) == -1)
                        return -1;
        } else if (gpt->tbl == NULL && gpt->lbt != NULL) {
                if (recover_gpt_tbl(gpt, MAP_TYPE_PRI_GPT_TBL, 2LL) == -1)
@@ -193,13 +194,38 @@
        }
 
        if (gpt->gpt != NULL && gpt->tpg == NULL) {
-               if (recover_gpt_hdr(gpt, MAP_TYPE_SEC_GPT_HDR,
-                   (off_t)last) == -1)
+               if (recover_gpt_hdr(gpt, MAP_TYPE_SEC_GPT_HDR, last) == -1)
                        return -1;
        } else if (gpt->gpt == NULL && gpt->tpg != NULL) {
                if (recover_gpt_hdr(gpt, MAP_TYPE_PRI_GPT_HDR, 1LL) == -1)
                        return -1;
        }
+
+       /*
+        * Create PMBR if it doesn't already exist.
+        */
+       if (map_find(gpt, MAP_TYPE_PMBR) == NULL) {
+               if (map_free(gpt, 0LL, 1LL) == 0) {
+                       gpt_warnx(gpt, "No room for the PMBR");
+                       return -1;
+               }
+               mbr = gpt_read(gpt, 0LL, 1);
+               if (mbr == NULL) {
+                       gpt_warnx(gpt, "Error reading MBR");
+                       return -1;
+               }
+               memset(mbr, 0, sizeof(*mbr));
+               mbr->mbr_sig = htole16(MBR_SIG);
+               gpt_create_pmbr_part(mbr->mbr_part, last, 0);
+
+               map = map_add(gpt, 0LL, 1LL, MAP_TYPE_PMBR, mbr, 1);
+               if (gpt_write(gpt, map) == -1) {
+                       gpt_warn(gpt, "Can't write PMBR");
+                       return -1;
+               }
+               gpt_msg(gpt,
+                   "Recreated PMBR (you may need to rerun 'gpt biosboot'");
+       }
        return 0;
 }
 



Home | Main Index | Thread Index | Old Index