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.

Reviewed by:	rpokala
MFC after:	1 month
Differential Revision:	https://reviews.freebsd.org/D4282
This commit is contained in:
Andrey V. Elsukov 2015-12-10 10:35:07 +00:00
parent c70294dc3a
commit af90a87209
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=292057
2 changed files with 22 additions and 16 deletions

View File

@ -301,12 +301,12 @@ ptable_gptread(struct ptable *table, void *dev, diskread_t dread)
}
}
}
DEBUG("GPT detected");
if (pri == 0 && sec == 0) {
/* Both primary and backup tables are invalid. */
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++) {
@ -635,6 +635,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. */

View File

@ -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,