diff options
author | ae <ae@FreeBSD.org> | 2016-01-10 13:53:57 +0000 |
---|---|---|
committer | ae <ae@FreeBSD.org> | 2016-01-10 13:53:57 +0000 |
commit | 09204e767089d0d9f6f376551f8c1b9a2eade3ee (patch) | |
tree | 51330d250c62d20d1fbc444485aa78943e7ce23d | |
parent | fdecbaeff59263df5ae9b87a90264a9eebdec0a3 (diff) | |
download | FreeBSD-src-09204e767089d0d9f6f376551f8c1b9a2eade3ee.zip FreeBSD-src-09204e767089d0d9f6f376551f8c1b9a2eade3ee.tar.gz |
MFC r292057:
Make detection of GPT a bit more reliable.
When we are detecting a partition table and didn't find PMBR, try to
read backup GPT header from the last sector and if it is correct,
assume that we have GPT.
Differential Revision: https://reviews.freebsd.org/D4282
MFC r292058:
Remove a note about damaged PMBR. Now GPT will be detected automatically
with such corruption.
Relnotes: yes
-rw-r--r-- | sbin/geom/class/part/gpart.8 | 12 | ||||
-rw-r--r-- | sys/boot/common/part.c | 6 | ||||
-rw-r--r-- | sys/geom/part/g_part_gpt.c | 31 |
3 files changed, 23 insertions, 26 deletions
diff --git a/sbin/geom/class/part/gpart.8 b/sbin/geom/class/part/gpart.8 index 3421ba0..ba579bf 100644 --- a/sbin/geom/class/part/gpart.8 +++ b/sbin/geom/class/part/gpart.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 14, 2015 +.Dd December 10, 2015 .Dt GPART 8 .Os .Sh NAME @@ -1107,15 +1107,6 @@ and .Cm recover are the only operations allowed on corrupt tables. .Pp -If the first sector of a provider is corrupt, the kernel can not detect GPT -even if the partition table itself is not corrupt. -The protective MBR can be rewritten using the -.Xr dd 1 -command, to restore the ability to detect the GPT. -The copy of the protective MBR is usually located in the -.Pa /boot/pmbr -file. -.Pp If one GPT header appears to be corrupt but the other copy remains intact, the kernel will log the following: .Bd -literal -offset indent @@ -1330,7 +1321,6 @@ and /sbin/gpart backup ada0 | /sbin/gpart restore -F ada1 ada2 .Ed .Sh SEE ALSO -.Xr dd 1 , .Xr geom 4 , .Xr boot0cfg 8 , .Xr geom 8 , diff --git a/sys/boot/common/part.c b/sys/boot/common/part.c index 4457619..518df1a 100644 --- a/sys/boot/common/part.c +++ b/sys/boot/common/part.c @@ -306,6 +306,7 @@ ptable_gptread(struct ptable *table, void *dev, diskread_t dread) table->type = PTABLE_NONE; goto out; } + DEBUG("GPT detected"); size = MIN(hdr.hdr_entries * hdr.hdr_entsz, MAXTBLSZ * table->sectorsize); for (i = 0; i < size / hdr.hdr_entsz; i++) { @@ -631,6 +632,11 @@ ptable_open(void *dev, off_t sectors, uint16_t sectorsize, if (buf[DOSMAGICOFFSET] != 0x55 || buf[DOSMAGICOFFSET + 1] != 0xaa) { DEBUG("magic sequence not found"); +#if defined(LOADER_GPT_SUPPORT) + /* There is no PMBR, check that we have backup GPT */ + table->type = PTABLE_GPT; + table = ptable_gptread(table, dev, dread); +#endif goto out; } /* Check that we have PMBR. Also do some validation. */ diff --git a/sys/geom/part/g_part_gpt.c b/sys/geom/part/g_part_gpt.c index d7650e9..88a9d12 100644 --- a/sys/geom/part/g_part_gpt.c +++ b/sys/geom/part/g_part_gpt.c @@ -823,22 +823,23 @@ g_part_gpt_probe(struct g_part_table *table, struct g_consumer *cp) return (error); res = le16dec(buf + DOSMAGICOFFSET); pri = G_PART_PROBE_PRI_LOW; - for (index = 0; index < NDOSPART; index++) { - if (buf[DOSPARTOFF + DOSPARTSIZE * index + 4] == 0xee) - pri = G_PART_PROBE_PRI_HIGH; - } - g_free(buf); - if (res != DOSMAGIC) - return (ENXIO); + if (res == DOSMAGIC) { + for (index = 0; index < NDOSPART; index++) { + if (buf[DOSPARTOFF + DOSPARTSIZE * index + 4] == 0xee) + pri = G_PART_PROBE_PRI_HIGH; + } + g_free(buf); - /* Check that there's a primary header. */ - buf = g_read_data(cp, pp->sectorsize, pp->sectorsize, &error); - if (buf == NULL) - return (error); - res = memcmp(buf, GPT_HDR_SIG, 8); - g_free(buf); - if (res == 0) - return (pri); + /* Check that there's a primary header. */ + buf = g_read_data(cp, pp->sectorsize, pp->sectorsize, &error); + if (buf == NULL) + return (error); + res = memcmp(buf, GPT_HDR_SIG, 8); + g_free(buf); + if (res == 0) + return (pri); + } else + g_free(buf); /* No primary? Check that there's a secondary. */ buf = g_read_data(cp, pp->mediasize - pp->sectorsize, pp->sectorsize, |