add parted-gpt-sync-mbr-label.patch (bnc#710402) (this patch implements support for special label 'gpt-sync-mbr')

OBS-URL: https://build.opensuse.org/package/show/Base:System/parted?expand=0&rev=45
This commit is contained in:
Petr Uzel 2011-08-25 10:50:39 +00:00 committed by Git OBS Bridge
parent 871502e6e4
commit 0f475813e0
3 changed files with 281 additions and 0 deletions

View File

@ -0,0 +1,273 @@
Index: parted-2.4/libparted/labels/gpt.c
===================================================================
--- parted-2.4.orig/libparted/labels/gpt.c
+++ parted-2.4/libparted/labels/gpt.c
@@ -51,11 +51,6 @@
# define _(String) (String)
#endif /* ENABLE_NLS */
-/* IA64 always has a properly working EFI implementation */
-#ifndef __ia64__
-#define GPT_SYNC_MBR
-#endif
-
#define EFI_PMBR_OSTYPE_EFI 0xEE
#define MSDOS_MBR_SIGNATURE 0xaa55
@@ -290,6 +285,7 @@ typedef struct _GPTPartitionData
} GPTPartitionData;
static PedDiskType gpt_disk_type;
+static PedDiskType gpt_sync_mbr_disk_type;
static inline uint32_t
pth_get_size (const PedDevice *dev)
@@ -458,8 +454,50 @@ _pmbr_is_valid (const LegacyMBR_t *mbr)
return 0;
}
+/* checks if device has a hybrid protective MBR partition table
+ *
+ * If the 1st partition has type 0xEE that spans the entire
+ * size of the disk from sector 1 to the last sector
+ * (or 2 TiB, whichever is smaller), we consider it 'normal' GPT.
+ * Otherwise it is synced GPT with hybridized pMBR.
+ */
+static inline int
+_has_hybrid_pmbr (const PedDevice *dev)
+{
+ int has_hybrid_pmbr = 1;
+
+ PED_ASSERT (dev != NULL);
+
+ void *label;
+ if (!ptt_read_sector (dev, 0, &label))
+ return 0;
+
+ LegacyMBR_t mbr;
+ memcpy(&mbr, label, sizeof(mbr));
+
+ if (mbr.Signature != PED_CPU_TO_LE16 (MSDOS_MBR_SIGNATURE)) {
+ free(label);
+ return 0;
+ }
+
+ uint32_t efi_gpt_expected_size;
+ if ((dev->length - 1ULL) > 0xFFFFFFFFULL)
+ efi_gpt_expected_size = 0xFFFFFFFF;
+ else
+ efi_gpt_expected_size = dev->length - 1UL;
+
+ if ((mbr.PartitionRecord[0].OSType == EFI_PMBR_OSTYPE_EFI) &&
+ (mbr.PartitionRecord[0].StartingLBA == PED_CPU_TO_LE32(1)) &&
+ (mbr.PartitionRecord[0].SizeInLBA == PED_CPU_TO_LE32(efi_gpt_expected_size)))
+ /* pMBR is not hybrid */
+ has_hybrid_pmbr = 0;
+
+ free(label);
+ return has_hybrid_pmbr;
+}
+
static int
-gpt_probe (const PedDevice *dev)
+_gpt_probe_generic(const PedDevice *dev)
{
GuidPartitionTableHeader_t *gpt = NULL;
int gpt_sig_found = 0;
@@ -512,6 +550,19 @@ gpt_probe (const PedDevice *dev)
return ok;
}
+static int
+gpt_probe (const PedDevice *dev)
+{
+ return _gpt_probe_generic(dev) && !_has_hybrid_pmbr(dev);
+}
+
+
+static int
+gpt_sync_mbr_probe (const PedDevice *dev)
+{
+ return _gpt_probe_generic(dev) && _has_hybrid_pmbr(dev);
+}
+
static PedDisk *
gpt_alloc (const PedDevice *dev)
{
@@ -543,6 +594,36 @@ error:
}
static PedDisk *
+gpt_sync_mbr_alloc (const PedDevice *dev)
+{
+ PedDisk *disk;
+ GPTDiskData *gpt_disk_data;
+ PedSector data_start, data_end;
+
+ disk = _ped_disk_alloc ((PedDevice *) dev, &gpt_sync_mbr_disk_type);
+ if (!disk)
+ goto error;
+ disk->disk_specific = gpt_disk_data = ped_malloc (sizeof (GPTDiskData));
+ if (!disk->disk_specific)
+ goto error_free_disk;
+
+ data_start = 2 + GPT_DEFAULT_PARTITION_ENTRY_ARRAY_SIZE / dev->sector_size;
+ data_end = dev->length - 2
+ - GPT_DEFAULT_PARTITION_ENTRY_ARRAY_SIZE / dev->sector_size;
+ ped_geometry_init (&gpt_disk_data->data_area, dev, data_start,
+ data_end - data_start + 1);
+ gpt_disk_data->entry_count = GPT_DEFAULT_PARTITION_ENTRIES;
+ uuid_generate ((unsigned char *) &gpt_disk_data->uuid);
+ swap_uuid_and_efi_guid ((unsigned char *) (&gpt_disk_data->uuid));
+ return disk;
+
+error_free_disk:
+ free (disk);
+error:
+ return NULL;
+}
+
+static PedDisk *
gpt_duplicate (const PedDisk *disk)
{
PedDisk *new_disk;
@@ -920,7 +1001,7 @@ gpt_read (PedDisk *disk)
/* motivation: let the user decide about the pmbr... during
ped_disk_probe(), they probably didn't get a choice... */
- if (!gpt_probe (disk->dev))
+ if (!gpt_probe (disk->dev) && !gpt_sync_mbr_probe(disk->dev))
goto error;
GuidPartitionTableHeader_t *gpt = NULL;
@@ -1078,7 +1159,6 @@ error:
}
-#ifdef GPT_SYNC_MBR
static inline unsigned char
_part_to_ostype (PedPartition* part)
{
@@ -1116,7 +1196,6 @@ _part_32bitmax (uint64_t in)
else
return (uint32_t)in;
}
-#endif
#ifndef DISCOVER_ONLY
@@ -1126,10 +1205,11 @@ _write_pmbr (const PedDisk *disk)
{
PedDevice * dev = disk->dev;
-#ifdef GPT_SYNC_MBR
+ /* need sync GPT -> hybrid pMBR ? */
+ int sync_pmbr = !strcmp(disk->type->name, "gpt_sync_mbr") ? 1 : 0;
+
int i, pmbr_id, first_entry = 0, last_entry = 3;
PedPartition *part = NULL, *esp;
-#endif
/* The UEFI spec is not clear about what to do with the following
elements of the Protective MBR (pmbr): BootCode (0-440B),
@@ -1140,13 +1220,12 @@ _write_pmbr (const PedDisk *disk)
return 0;
LegacyMBR_t *pmbr = s0;
-#ifndef GPT_SYNC_MBR
/* Zero out the legacy partitions. */
memset (pmbr->PartitionRecord, 0, sizeof pmbr->PartitionRecord);
-#endif
pmbr->Signature = PED_CPU_TO_LE16 (MSDOS_MBR_SIGNATURE);
-#ifndef GPT_SYNC_MBR
+
+ if (!sync_pmbr) {
pmbr->PartitionRecord[0].OSType = EFI_PMBR_OSTYPE_EFI;
pmbr->PartitionRecord[0].StartSector = 1;
pmbr->PartitionRecord[0].EndHead = 0xFE;
@@ -1157,7 +1236,7 @@ _write_pmbr (const PedDisk *disk)
pmbr->PartitionRecord[0].SizeInLBA = PED_CPU_TO_LE32 (0xFFFFFFFF);
else
pmbr->PartitionRecord[0].SizeInLBA = PED_CPU_TO_LE32 (dev->length - 1UL);
-#else
+ } else {
/* Search for an EFI System Partition */
esp = _find_first_part(disk);
if (!esp || !esp->fs_type || strncmp (esp->fs_type->name, "fat", 3) != 0)
@@ -1203,8 +1282,7 @@ _write_pmbr (const PedDisk *disk)
pmbr->PartitionRecord[i].BootIndicator = 0x80;
pmbr->PartitionRecord[i].SizeInLBA = _part_32bitmax(part->geom.end - part->geom.start + 1);
}
-#endif
-
+ }
int write_ok = ped_device_write (dev, pmbr, GPT_PMBR_LBA,
GPT_PMBR_SECTORS);
free (s0);
@@ -1902,6 +1980,38 @@ static PedDiskOps gpt_disk_ops =
PT_op_function_initializers (gpt)
};
+static PedDiskOps gpt_sync_mbr_disk_ops =
+{
+ clobber: NULL,
+ write: NULL_IF_DISCOVER_ONLY (gpt_write),
+
+ partition_set_name: gpt_partition_set_name,
+ partition_get_name: gpt_partition_get_name,
+
+ /* probe function redefined */
+ probe: gpt_sync_mbr_probe,
+ /* alloc function redefined */
+ alloc: gpt_sync_mbr_alloc,
+ duplicate: gpt_duplicate,
+ free: gpt_free,
+ read: gpt_read,
+ partition_new: gpt_partition_new,
+ partition_duplicate: gpt_partition_duplicate,
+ partition_set_flag: gpt_partition_set_flag,
+ partition_get_flag: gpt_partition_get_flag,
+ partition_set_system: gpt_partition_set_system,
+ partition_is_flag_available: gpt_partition_is_flag_available,
+ partition_align: gpt_partition_align,
+ partition_destroy: gpt_partition_destroy,
+ partition_enumerate: gpt_partition_enumerate,
+ alloc_metadata: gpt_alloc_metadata,
+ get_max_primary_partition_count: gpt_get_max_primary_partition_count,
+ get_max_supported_partition_count: gpt_get_max_supported_partition_count,
+ partition_check: gpt_partition_check,
+ max_length: gpt_partition_max_length,
+ max_start_sector: gpt_partition_max_start_sector
+};
+
static PedDiskType gpt_disk_type =
{
next: NULL,
@@ -1910,16 +2020,26 @@ static PedDiskType gpt_disk_type =
features: PED_DISK_TYPE_PARTITION_NAME
};
+static PedDiskType gpt_sync_mbr_disk_type =
+{
+ next: NULL,
+ name: "gpt_sync_mbr",
+ ops: &gpt_sync_mbr_disk_ops,
+ features: PED_DISK_TYPE_PARTITION_NAME
+};
+
void
ped_disk_gpt_init ()
{
ped_disk_type_register (&gpt_disk_type);
+ ped_disk_type_register (&gpt_sync_mbr_disk_type);
}
void
ped_disk_gpt_done ()
{
ped_disk_type_unregister (&gpt_disk_type);
+ ped_disk_type_unregister (&gpt_sync_mbr_disk_type);
}
verify (sizeof (GuidPartitionEntryAttributes_t) == 8);

View File

@ -1,3 +1,9 @@
-------------------------------------------------------------------
Thu Aug 25 10:22:09 UTC 2011 - puzel@novell.com
- add parted-gpt-sync-mbr-label.patch (bnc#710402)
- this patch implements support for special label 'gpt-sync-mbr'
-------------------------------------------------------------------
Tue Aug 16 09:07:50 UTC 2011 - puzel@novell.com

View File

@ -40,6 +40,7 @@ Patch11: do-not-create-dm-nodes.patch
#PATCH-FEATURE-OPENSUSE more-reliable-informing-the-kernel.patch bnc#657360 petr.uzel@suse.cz
Patch12: more-reliable-informing-the-kernel.patch
Patch13: parted-2.4-ncursesw6.patch
Patch14: parted-gpt-sync-mbr-label.patch
Requires: /sbin/udevadm
BuildRequires: check-devel
BuildRequires: device-mapper-devel >= 1.02.33
@ -103,6 +104,7 @@ to develop applications that require these.
%patch11 -p1
%patch12 -p1
%patch13
%patch14 -p1
%build
export CFLAGS="%{optflags} `ncursesw6-config --cflags`"