]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libfdisk: (gpt) fix hybrid MBR detection, fix 'w'
authorKarel Zak <kzak@redhat.com>
Tue, 1 Oct 2019 10:51:04 +0000 (12:51 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 1 Oct 2019 10:51:04 +0000 (12:51 +0200)
* 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 <kzak@redhat.com>
disk-utils/fdisk-menu.c
libfdisk/src/context.c
libfdisk/src/gpt.c

index 3aba661fbed7ac64d1554c5c333ca185413efe93..71355f684833968b9dc0e216789067d78d3b9f82 100644 (file)
@@ -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);
index cbcadcf592d1202bf6735c10845a8a53409f8cf1..cb2164c2e6fd72b5fc33a0d33d02de4ced110777 100644 (file)
@@ -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);
        }
 
index f7057916907186ce146227386b5903c07baec8ce..b5caab965df439dd17a1c713eaeafbe905e76e74 100644 (file)
@@ -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;