diff options
author | Karel Zak | 2013-10-23 16:59:45 +0200 |
---|---|---|
committer | Karel Zak | 2013-10-23 16:59:45 +0200 |
commit | 433d05ff9afeb4a374943cb35d1b8b19613c8039 (patch) | |
tree | 8309076ac324b0882fb92484aa58c6a835d3432a | |
parent | libfdisk: (gpt) improve and cleanup recovery code (diff) | |
download | kernel-qcow2-util-linux-433d05ff9afeb4a374943cb35d1b8b19613c8039.tar.gz kernel-qcow2-util-linux-433d05ff9afeb4a374943cb35d1b8b19613c8039.tar.xz kernel-qcow2-util-linux-433d05ff9afeb4a374943cb35d1b8b19613c8039.zip |
libfdisk: (gpt) allow to work with hybrid GPT
Notes:
* fdisk don't sync hybrid MBR with GPT
* hybrid MBR is ignored and not overwritten by PBMR
* users is informed about expert command 'M' to toggle between MBR
and GPT mode. It's possible to manually modify hybrid MBR.
Signed-off-by: Karel Zak <kzak@redhat.com>
-rw-r--r-- | fdisks/fdisk.c | 6 | ||||
-rw-r--r-- | libfdisk/src/dos.c | 6 | ||||
-rw-r--r-- | libfdisk/src/gpt.c | 18 | ||||
-rw-r--r-- | libfdisk/src/libfdisk.h | 1 |
4 files changed, 24 insertions, 7 deletions
diff --git a/fdisks/fdisk.c b/fdisks/fdisk.c index ca49606a5..874f9d138 100644 --- a/fdisks/fdisk.c +++ b/fdisks/fdisk.c @@ -546,7 +546,11 @@ int main(int argc, char **argv) if (!fdisk_dev_has_disklabel(cxt)) { fdisk_info(cxt, _("Device does not contain a recognized partition table.")); fdisk_create_disklabel(cxt, NULL); - } + + } else if (fdisk_is_disklabel(cxt, GPT) && fdisk_gpt_is_hybrid(cxt)) + fdisk_warnx(cxt, _( + "The hybrid GPT detected. You have to sync " + "the hybrid MBR manually (expert command 'M').")); while (1) process_fdisk_menu(&cxt); diff --git a/libfdisk/src/dos.c b/libfdisk/src/dos.c index 11d3c71f4..8b51b8c53 100644 --- a/libfdisk/src/dos.c +++ b/libfdisk/src/dos.c @@ -815,7 +815,11 @@ static int add_partition(struct fdisk_context *cxt, size_t n, struct fdisk_partt } fill_bounds(cxt, first, last); if (n < 4) { - start = cxt->first_lba; + if (cxt->parent && fdisk_is_disklabel(cxt->parent, GPT)) + start = 1; /* Bad boy modifies hybrid MBR */ + else + start = cxt->first_lba; + if (fdisk_context_use_cylinders(cxt) || !cxt->total_sectors) limit = cxt->geom.heads * cxt->geom.sectors * cxt->geom.cylinders - 1; else diff --git a/libfdisk/src/gpt.c b/libfdisk/src/gpt.c index 68eddeb80..f4c46b94d 100644 --- a/libfdisk/src/gpt.c +++ b/libfdisk/src/gpt.c @@ -1476,16 +1476,14 @@ fail: static int gpt_write_disklabel(struct fdisk_context *cxt) { struct fdisk_gpt_label *gpt; + int mbr_type; assert(cxt); assert(cxt->label); assert(fdisk_is_disklabel(cxt, GPT)); gpt = self_label(cxt); - - /* we do not want to mess up hybrid MBRs by creating a valid pmbr */ - if (valid_pmbr(cxt) == GPT_MBR_HYBRID) - goto err0; + mbr_type = valid_pmbr(cxt); /* check that disk is big enough to handle the backup header */ if (le64_to_cpu(gpt->pheader->alternative_lba) > cxt->total_sectors) @@ -1522,7 +1520,11 @@ static int gpt_write_disklabel(struct fdisk_context *cxt) goto err1; if (gpt_write_header(cxt, gpt->pheader, GPT_PRIMARY_PARTITION_TABLE_LBA) != 0) goto err1; - if (gpt_write_pmbr(cxt) != 0) + + if (mbr_type == GPT_MBR_HYBRID) + fdisk_warnx(cxt, _("The device contains hybrid MBR -- writing GPT only. " + "You have to sync the MBR manually.")); + else if (gpt_write_pmbr(cxt) != 0) goto err1; DBG(LABEL, dbgprint("GPT write success")); @@ -2164,6 +2166,12 @@ int fdisk_gpt_partition_set_name(struct fdisk_context *cxt, size_t i) return 0; } +int fdisk_gpt_is_hybrid(struct fdisk_context *cxt) +{ + assert(cxt); + return valid_pmbr(cxt) == GPT_MBR_HYBRID; +} + static int gpt_toggle_partition_flag( struct fdisk_context *cxt, size_t i, diff --git a/libfdisk/src/libfdisk.h b/libfdisk/src/libfdisk.h index 77892d271..f653b48b1 100644 --- a/libfdisk/src/libfdisk.h +++ b/libfdisk/src/libfdisk.h @@ -199,6 +199,7 @@ enum { extern int fdisk_gpt_partition_set_uuid(struct fdisk_context *cxt, size_t i); extern int fdisk_gpt_partition_set_name(struct fdisk_context *cxt, size_t i); +extern int fdisk_gpt_is_hybrid(struct fdisk_context *cxt); /* dos.c */ extern struct dos_partition *fdisk_dos_get_partition( |