Hi,
when modifying a GPT parted clears all GUID specific attributes. This happens even when modifying unrelated partitions, e.g. adding a new partition. According to the UEFI standard these bits must be preserved (see Table 24 of the UEFI spec[1]) even when only modifying the other attributes. The attached patch solves the problem by having the full attributes instead of the two flags hidden and bls_boot in GPTPartitionData and modifying the full attributes directly. A test case is a bit tricky since parted cannot be used to verify the result. So either some other tool (fdisk and sfdisk are fine) or some low-level program (something like gpt-header-move/munge) is needed. I can add whatever is preferred. Thanks, Arvin [1] https://uefi.org/sites/default/files/resources/UEFI%20Spec%202.8B%20May%202020.pdf --- libparted/labels/gpt.c | 56 +++++++++++++++++------------------------- 1 file changed, 22 insertions(+), 34 deletions(-) diff --git a/libparted/labels/gpt.c b/libparted/labels/gpt.c index 9b987c1..82e3e7c 100644 --- a/libparted/labels/gpt.c +++ b/libparted/labels/gpt.c @@ -297,13 +297,13 @@ typedef struct _GPTPartitionData efi_guid_t uuid; efi_char16_t name[37]; char *translated_name; + GuidPartitionEntryAttributes_t attributes; int lvm; int swap; int raid; int boot; int bios_grub; int hp_service; - int hidden; int msftres; int msftdata; int atvrecv; @@ -312,7 +312,6 @@ typedef struct _GPTPartitionData int prep; int irst; int chromeos_kernel; - int bls_boot; } GPTPartitionData; static PedDiskType gpt_disk_type; @@ -826,25 +825,20 @@ _parse_part_entry (PedDisk *disk, GuidPartitionEntry_t *pte) gpt_part_data->name[i] = (efi_char16_t) pte->PartitionName[i]; gpt_part_data->name[i] = 0; gpt_part_data->translated_name = 0; + gpt_part_data->attributes = pte->Attributes; gpt_part_data->lvm = gpt_part_data->swap = gpt_part_data->raid = gpt_part_data->boot = gpt_part_data->hp_service - = gpt_part_data->hidden = gpt_part_data->msftres + = gpt_part_data->msftres = gpt_part_data->msftdata = gpt_part_data->msftrecv = gpt_part_data->legacy_boot = gpt_part_data->prep = gpt_part_data->irst = gpt_part_data->chromeos_kernel - = gpt_part_data->bls_boot = gpt_part_data->bios_grub = gpt_part_data->atvrecv = 0; - if (pte->Attributes.RequiredToFunction & 0x1) - gpt_part_data->hidden = 1; - if (pte->Attributes.LegacyBIOSBootable & 0x1) - gpt_part_data->legacy_boot = 1; - if (!guid_cmp (gpt_part_data->type, PARTITION_SYSTEM_GUID)) gpt_part_data->boot = 1; else if (!guid_cmp (gpt_part_data->type, PARTITION_BIOS_GRUB_GUID)) @@ -872,7 +866,7 @@ _parse_part_entry (PedDisk *disk, GuidPartitionEntry_t *pte) else if (!guid_cmp (gpt_part_data->type, PARTITION_CHROMEOS_KERNEL_GUID)) gpt_part_data->chromeos_kernel = 1; else if (!guid_cmp (gpt_part_data->type, PARTITION_BLS_BOOT_GUID)) - gpt_part_data->bls_boot = 1; + gpt_part_data->attributes.LegacyBIOSBootable = 1; return part; } @@ -1241,12 +1235,7 @@ _partition_generate_part_entry (PedPartition *part, GuidPartitionEntry_t *pte) pte->UniquePartitionGuid = gpt_part_data->uuid; pte->StartingLBA = PED_CPU_TO_LE64 (part->geom.start); pte->EndingLBA = PED_CPU_TO_LE64 (part->geom.end); - memset (&pte->Attributes, 0, sizeof (GuidPartitionEntryAttributes_t)); - - if (gpt_part_data->hidden) - pte->Attributes.RequiredToFunction = 1; - if (gpt_part_data->legacy_boot) - pte->Attributes.LegacyBIOSBootable = 1; + pte->Attributes = gpt_part_data->attributes; for (i = 0; i < 36; i++) pte->PartitionName[i] = gpt_part_data->name[i]; @@ -1388,7 +1377,6 @@ gpt_partition_new (const PedDisk *disk, gpt_part_data->boot = 0; gpt_part_data->bios_grub = 0; gpt_part_data->hp_service = 0; - gpt_part_data->hidden = 0; gpt_part_data->msftres = 0; gpt_part_data->msftdata = 0; gpt_part_data->msftrecv = 0; @@ -1398,10 +1386,10 @@ gpt_partition_new (const PedDisk *disk, gpt_part_data->translated_name = 0; gpt_part_data->irst = 0; gpt_part_data->chromeos_kernel = 0; - gpt_part_data->bls_boot = 0; uuid_generate ((unsigned char *) &gpt_part_data->uuid); swap_uuid_and_efi_guid (&gpt_part_data->uuid); memset (gpt_part_data->name, 0, sizeof gpt_part_data->name); + memset (&gpt_part_data->attributes, 0, sizeof gpt_part_data->attributes); return part; error_free_part: @@ -1534,7 +1522,7 @@ gpt_partition_set_system (PedPartition *part, gpt_part_data->type = PARTITION_CHROMEOS_KERNEL_GUID; return 1; } - if (gpt_part_data->bls_boot) + if (gpt_part_data->attributes.LegacyBIOSBootable) { gpt_part_data->type = PARTITION_BLS_BOOT_GUID; return 1; @@ -1686,7 +1674,7 @@ gpt_partition_set_flag (PedPartition *part, PedPartitionFlag flag, int state) = gpt_part_data->prep = gpt_part_data->irst = gpt_part_data->chromeos_kernel - = gpt_part_data->bls_boot + = gpt_part_data->attributes.LegacyBIOSBootable = gpt_part_data->atvrecv = 0; return gpt_partition_set_system (part, part->fs_type); case PED_PARTITION_BIOS_GRUB: @@ -1703,7 +1691,7 @@ gpt_partition_set_flag (PedPartition *part, PedPartitionFlag flag, int state) = gpt_part_data->prep = gpt_part_data->irst = gpt_part_data->chromeos_kernel - = gpt_part_data->bls_boot + = gpt_part_data->attributes.LegacyBIOSBootable = gpt_part_data->atvrecv = 0; return gpt_partition_set_system (part, part->fs_type); case PED_PARTITION_RAID: @@ -1720,7 +1708,7 @@ gpt_partition_set_flag (PedPartition *part, PedPartitionFlag flag, int state) = gpt_part_data->prep = gpt_part_data->irst = gpt_part_data->chromeos_kernel - = gpt_part_data->bls_boot + = gpt_part_data->attributes.LegacyBIOSBootable = gpt_part_data->atvrecv = 0; return gpt_partition_set_system (part, part->fs_type); case PED_PARTITION_LVM: @@ -1737,7 +1725,7 @@ gpt_partition_set_flag (PedPartition *part, PedPartitionFlag flag, int state) = gpt_part_data->prep = gpt_part_data->irst = gpt_part_data->chromeos_kernel - = gpt_part_data->bls_boot + = gpt_part_data->attributes.LegacyBIOSBootable = gpt_part_data->atvrecv = 0; return gpt_partition_set_system (part, part->fs_type); case PED_PARTITION_SWAP: @@ -1754,7 +1742,7 @@ gpt_partition_set_flag (PedPartition *part, PedPartitionFlag flag, int state) = gpt_part_data->prep = gpt_part_data->irst = gpt_part_data->chromeos_kernel - = gpt_part_data->bls_boot + = gpt_part_data->attributes.LegacyBIOSBootable = gpt_part_data->atvrecv = 0; return gpt_partition_set_system (part, part->fs_type); case PED_PARTITION_HPSERVICE: @@ -1771,7 +1759,7 @@ gpt_partition_set_flag (PedPartition *part, PedPartitionFlag flag, int state) = gpt_part_data->prep = gpt_part_data->irst = gpt_part_data->chromeos_kernel - = gpt_part_data->bls_boot + = gpt_part_data->attributes.LegacyBIOSBootable = gpt_part_data->atvrecv = 0; return gpt_partition_set_system (part, part->fs_type); case PED_PARTITION_MSFT_RESERVED: @@ -1788,7 +1776,7 @@ gpt_partition_set_flag (PedPartition *part, PedPartitionFlag flag, int state) = gpt_part_data->prep = gpt_part_data->irst = gpt_part_data->chromeos_kernel - = gpt_part_data->bls_boot + = gpt_part_data->attributes.LegacyBIOSBootable = gpt_part_data->atvrecv = 0; return gpt_partition_set_system (part, part->fs_type); case PED_PARTITION_MSFT_DATA: @@ -1805,7 +1793,7 @@ gpt_partition_set_flag (PedPartition *part, PedPartitionFlag flag, int state) = gpt_part_data->prep = gpt_part_data->irst = gpt_part_data->chromeos_kernel - = gpt_part_data->bls_boot + = gpt_part_data->attributes.LegacyBIOSBootable = gpt_part_data->atvrecv = 0; gpt_part_data->msftdata = 1; } else { @@ -1856,7 +1844,7 @@ gpt_partition_set_flag (PedPartition *part, PedPartitionFlag flag, int state) = gpt_part_data->irst = gpt_part_data->atvrecv = gpt_part_data->chromeos_kernel - = gpt_part_data->bls_boot + = gpt_part_data->attributes.LegacyBIOSBootable = gpt_part_data->msftrecv = 0; return gpt_partition_set_system (part, part->fs_type); case PED_PARTITION_IRST: @@ -1873,7 +1861,7 @@ gpt_partition_set_flag (PedPartition *part, PedPartitionFlag flag, int state) = gpt_part_data->msftrecv = gpt_part_data->prep = gpt_part_data->chromeos_kernel - = gpt_part_data->bls_boot + = gpt_part_data->attributes.LegacyBIOSBootable = gpt_part_data->atvrecv = 0; return gpt_partition_set_system (part, part->fs_type); case PED_PARTITION_CHROMEOS_KERNEL: @@ -1891,10 +1879,10 @@ gpt_partition_set_flag (PedPartition *part, PedPartitionFlag flag, int state) = gpt_part_data->atvrecv = gpt_part_data->prep = gpt_part_data->irst - = gpt_part_data->bls_boot = 0; + = gpt_part_data->attributes.LegacyBIOSBootable = 0; return gpt_partition_set_system (part, part->fs_type); case PED_PARTITION_BLS_BOOT: - gpt_part_data->bls_boot = state; + gpt_part_data->attributes.LegacyBIOSBootable = state; if (state) gpt_part_data->boot = gpt_part_data->raid @@ -1911,7 +1899,7 @@ gpt_partition_set_flag (PedPartition *part, PedPartitionFlag flag, int state) = gpt_part_data->atvrecv = 0; return gpt_partition_set_system (part, part->fs_type); case PED_PARTITION_HIDDEN: - gpt_part_data->hidden = state; + gpt_part_data->attributes.RequiredToFunction = state; return 1; case PED_PARTITION_LEGACY_BOOT: gpt_part_data->legacy_boot = state; @@ -1953,7 +1941,7 @@ gpt_partition_get_flag (const PedPartition *part, PedPartitionFlag flag) case PED_PARTITION_APPLE_TV_RECOVERY: return gpt_part_data->atvrecv; case PED_PARTITION_HIDDEN: - return gpt_part_data->hidden; + return gpt_part_data->attributes.RequiredToFunction; case PED_PARTITION_LEGACY_BOOT: return gpt_part_data->legacy_boot; case PED_PARTITION_PREP: @@ -1961,7 +1949,7 @@ gpt_partition_get_flag (const PedPartition *part, PedPartitionFlag flag) case PED_PARTITION_IRST: return gpt_part_data->irst; case PED_PARTITION_BLS_BOOT: - return gpt_part_data->bls_boot; + return gpt_part_data->attributes.LegacyBIOSBootable; case PED_PARTITION_SWAP: return gpt_part_data->swap; case PED_PARTITION_CHROMEOS_KERNEL: -- Arvin Schnell, <aschn...@suse.com> Senior Software Engineer, Research & Development SUSE Software Solutions Germany GmbH Maxfeldstraße 5 90409 Nürnberg Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer