From: Karel Zak Date: Tue, 1 Oct 2019 10:51:04 +0000 (+0200) Subject: libfdisk: (gpt) fix hybrid MBR detection, fix 'w' X-Git-Tag: v2.35-rc1~183 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1d84470388cb6b101a4ce1ecc079af9404bf052d;p=thirdparty%2Futil-linux.git libfdisk: (gpt) fix hybrid MBR detection, fix 'w' * current code overwrites hybrid MBR because EE partition is expected from fist sector, this is not true for hybrid MBR * print "The partition table has been altered." message also for nested contexts * remove "You have to sync the MBR manually" message Addresses: https://github.com/karelzak/util-linux/issues/851 Signed-off-by: Karel Zak --- diff --git a/disk-utils/fdisk-menu.c b/disk-utils/fdisk-menu.c index 3aba661fbe..71355f6848 100644 --- a/disk-utils/fdisk-menu.c +++ b/disk-utils/fdisk-menu.c @@ -595,9 +595,10 @@ static int generic_menu_cb(struct fdisk_context **cxt0, rc = fdisk_write_disklabel(cxt); if (rc) err(EXIT_FAILURE, _("failed to write disklabel")); + + fdisk_info(cxt, _("The partition table has been altered.")); if (fdisk_get_parent(cxt)) break; /* nested PT, don't leave */ - fdisk_info(cxt, _("The partition table has been altered.")); if (device_is_used) rc = fdisk_reread_changes(cxt, original_layout); diff --git a/libfdisk/src/context.c b/libfdisk/src/context.c index cbcadcf592..cb2164c2e6 100644 --- a/libfdisk/src/context.c +++ b/libfdisk/src/context.c @@ -537,12 +537,15 @@ static void reset_context(struct fdisk_context *cxt) if (cxt->parent) { /* the first sector may be independent on parent */ - if (cxt->parent->firstsector != cxt->firstsector) + if (cxt->parent->firstsector != cxt->firstsector) { + DBG(CXT, ul_debugobj(cxt, " firstsector independent on parent (freeing)")); free(cxt->firstsector); + } } else { /* we close device only in primary context */ if (cxt->dev_fd > -1 && cxt->private_fd) close(cxt->dev_fd); + DBG(CXT, ul_debugobj(cxt, " freeing firstsector")); free(cxt->firstsector); } diff --git a/libfdisk/src/gpt.c b/libfdisk/src/gpt.c index f705791690..b5caab965d 100644 --- a/libfdisk/src/gpt.c +++ b/libfdisk/src/gpt.c @@ -870,17 +870,20 @@ static int valid_pmbr(struct fdisk_context *cxt) if (ret != GPT_MBR_PROTECTIVE) goto done; - /* LBA of the GPT partition header */ - if (pmbr->partition_record[part].starting_lba != - cpu_to_le32(GPT_PRIMARY_PARTITION_TABLE_LBA)) - goto done; for (i = 0 ; i < 4; i++) { if ((pmbr->partition_record[i].os_type != EFI_PMBR_OSTYPE) && - (pmbr->partition_record[i].os_type != 0x00)) + (pmbr->partition_record[i].os_type != 0x00)) { ret = GPT_MBR_HYBRID; + goto done; + } } + /* LBA of the GPT partition header */ + if (pmbr->partition_record[part].starting_lba != + cpu_to_le32(GPT_PRIMARY_PARTITION_TABLE_LBA)) + goto done; + /* * Protective MBRs take up the lesser of the whole disk * or 2 TiB (32bit LBA), ignoring the rest of the disk. @@ -909,6 +912,9 @@ static int valid_pmbr(struct fdisk_context *cxt) } } done: + DBG(LABEL, ul_debug("PMBR type: %s", + ret == GPT_MBR_PROTECTIVE ? "protective" : + ret == GPT_MBR_HYBRID ? "hybrid" : "???" )); return ret; } @@ -1576,9 +1582,6 @@ static int gpt_probe_label(struct fdisk_context *cxt) if (!mbr_type) goto failed; - DBG(LABEL, ul_debug("found a %s MBR", mbr_type == GPT_MBR_PROTECTIVE ? - "protective" : "hybrid")); - /* primary header */ gpt->pheader = gpt_read_header(cxt, GPT_PRIMARY_PARTITION_TABLE_LBA, &gpt->ents); @@ -2028,6 +2031,7 @@ static int gpt_write_pmbr(struct fdisk_context *cxt) assert(cxt); assert(cxt->firstsector); + DBG(LABEL, ul_debug("(over)writing PMBR")); pmbr = (struct gpt_legacy_mbr *) cxt->firstsector; /* zero out the legacy partitions */ @@ -2116,8 +2120,7 @@ static int gpt_write_disklabel(struct fdisk_context *cxt) goto err1; if (mbr_type == GPT_MBR_HYBRID) - fdisk_warnx(cxt, _("The device contains hybrid MBR -- writing GPT only. " - "You have to sync the MBR manually.")); + fdisk_warnx(cxt, _("The device contains hybrid MBR -- writing GPT only.")); else if (gpt_write_pmbr(cxt) != 0) goto err1;