[parted-devel] [PATCH] keep GUID specific attributes

Arvin Schnell aschnell at suse.com
Tue Sep 21 09:26:24 BST 2021


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, <aschnell at 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



More information about the parted-devel mailing list