diff options
author | Arvin Schnell <aschnell@suse.com> | 2021-09-23 16:31:42 +0000 |
---|---|---|
committer | Brian C. Lane <bcl@redhat.com> | 2021-09-23 16:17:54 -0700 |
commit | 9d1ac5015340aa7a4cc71cb7f63bae8c1718b8ee (patch) | |
tree | fef2c3be198b3ff837a075c2fedf2775d30f2628 | |
parent | c16cb23bf91cf3255e2cf8ea596fe5e1b4ea1ad5 (diff) | |
download | parted-9d1ac5015340aa7a4cc71cb7f63bae8c1718b8ee.tar.gz |
keep GUID specific attributes
Keep GUID specific attributes when writing GPT.
Signed-off-by: Brian C. Lane <bcl@redhat.com>
-rw-r--r-- | libparted/labels/gpt.c | 30 | ||||
-rw-r--r-- | tests/Makefile.am | 3 | ||||
-rwxr-xr-x | tests/gpt-attrs | 72 | ||||
-rw-r--r-- | tests/t0215-gpt-attrs.sh | 46 |
4 files changed, 129 insertions, 22 deletions
diff --git a/libparted/labels/gpt.c b/libparted/labels/gpt.c index 9b987c1..ba9a71a 100644 --- a/libparted/labels/gpt.c +++ b/libparted/labels/gpt.c @@ -297,18 +297,17 @@ 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; int msftrecv; - int legacy_boot; int prep; int irst; int chromeos_kernel; @@ -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)) @@ -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,12 +1377,10 @@ 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; gpt_part_data->atvrecv = 0; - gpt_part_data->legacy_boot = 0; gpt_part_data->prep = 0; gpt_part_data->translated_name = 0; gpt_part_data->irst = 0; @@ -1402,6 +1389,7 @@ gpt_partition_new (const PedDisk *disk, 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: @@ -1911,10 +1899,10 @@ 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; + gpt_part_data->attributes.LegacyBIOSBootable = state; return 1; case PED_PARTITION_ROOT: case PED_PARTITION_LBA: @@ -1953,9 +1941,9 @@ 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; + return gpt_part_data->attributes.LegacyBIOSBootable; case PED_PARTITION_PREP: return gpt_part_data->prep; case PED_PARTITION_IRST: diff --git a/tests/Makefile.am b/tests/Makefile.am index f9340aa..3dc6e72 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -26,6 +26,7 @@ TESTS = \ t0211-gpt-rewrite-header.sh \ t0212-gpt-many-partitions.sh \ t0213-mkpart-start-negative.sh \ + t0215-gpt-attrs.sh \ t0220-gpt-msftres.sh \ t0250-gpt.sh \ t0251-gpt-unicode.sh \ @@ -98,7 +99,7 @@ TESTS = \ EXTRA_DIST = \ $(TESTS) t-local.sh t-lvm.sh \ init.cfg init.sh t-lib-helpers.sh gpt-header-munge \ - gpt-header-move msdos-overlap + gpt-header-move msdos-overlap gpt-attrs check_PROGRAMS = print-align print-flags print-max dup-clobber duplicate \ fs-resize diff --git a/tests/gpt-attrs b/tests/gpt-attrs new file mode 100755 index 0000000..0a01447 --- /dev/null +++ b/tests/gpt-attrs @@ -0,0 +1,72 @@ +#!/usr/bin/python3 + +# Copyright (C) 2021 SUSE LLC + +# program to show gpt partition attributes or set attributes of +# partition 1 + +# only works with 512 sectors and standard GPT header layout (128 +# partition entires with 128 bytes each, secondary header at end of +# device) + + +from struct import unpack_from, pack_into +from zipfile import crc32 +import array +import sys + + +class Gpt: + + # Calculate and insert the CRCs of the partition entires and the + # header. + def calc_crcs(self, header, entries): + # compute crc of partition entries + crc2 = crc32(entries) & 0xFFFFFFFF + pack_into('<L', header, 88, crc2) + + # compute crc of header + pack_into('<L', header, 16, 0) + crc1 = crc32(header[:92]) & 0xFFFFFFFF + pack_into('<L', header, 16, crc1) + + def read(self, name): + self.name = name + + file = open(name, 'rb+') + + file.seek(512) + self.primary_header = array.array('B', file.read(512)) + self.primary_entries = array.array('B', file.read(32 * 512)) + + file.seek(-33 * 512, 2) + self.secondary_entries = array.array('B', file.read(32 * 512)) + self.secondary_header = array.array('B', file.read(512)) + + def write(self): + file = open(self.name, 'rb+') + + self.calc_crcs(self.primary_header, self.primary_entries) + file.seek(512) + file.write(self.primary_header) + file.write(self.primary_entries) + + self.calc_crcs(self.secondary_header, self.secondary_entries) + file.seek(-33 * 512, 2) + file.write(self.secondary_entries) + file.write(self.secondary_header) + + +gpt = Gpt() + +gpt.read(sys.argv[1]) + +if sys.argv[2] == "show": + attrs = unpack_from('<Q', gpt.primary_entries, 48)[0] + print(hex(attrs)) + +if sys.argv[2] == "set": + attrs = int(sys.argv[3], 0) + pack_into('<Q', gpt.primary_entries, 48, attrs) + pack_into('<Q', gpt.secondary_entries, 48, attrs) + gpt.write() diff --git a/tests/t0215-gpt-attrs.sh b/tests/t0215-gpt-attrs.sh new file mode 100644 index 0000000..216a966 --- /dev/null +++ b/tests/t0215-gpt-attrs.sh @@ -0,0 +1,46 @@ +#!/bin/sh + +# Test that GUID specific bits are preserved + +# Copyright (C) 2021 SUSE LLC + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +. "${srcdir=.}/init.sh"; path_prepend_ ../parted $srcdir +require_512_byte_sector_size_ + +dev=loop-file + +# create device +truncate --size 50MiB "$dev" || fail=1 + +# create gpt label and one partitions +parted --script "$dev" mklabel gpt > out 2>&1 || fail=1 +parted --script "$dev" mkpart "test1" ext4 0% 10% > out 2>&1 || fail=1 + +# set guid specific bit +gpt-attrs "$dev" set 0x100000000000000 || fail=1 + +# create additional partition +parted --script "$dev" mkpart "test2" ext4 10% 20% > out 2>&1 || fail=1 + +cat <<EOF > exp || fail=1 +0x100000000000000 +EOF + +# check guid specific bit +gpt-attrs "$dev" show > out || fail=1 +compare exp out || fail=1 + +Exit $fail |