summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sbin/geom/class/part/gpart.812
-rw-r--r--sys/boot/common/part.c6
-rw-r--r--sys/geom/part/g_part_gpt.c31
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,
OpenPOWER on IntegriCloud