- 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
This commit is contained in:
parent
fea8b400be
commit
93fd3c01ef
@ -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 @@ static int
|
||||
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 @@ recover_gpt_hdr(gpt_t gpt, int type, off_t last)
|
||||
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 @@ recover_gpt_tbl(gpt_t gpt, int type, off_t start)
|
||||
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 @@ recover(gpt_t gpt, int recoverable)
|
||||
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 @@ recover(gpt_t gpt, int recoverable)
|
||||
|
||||
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 @@ recover(gpt_t gpt, int recoverable)
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user