stages/sfdisk: support changing GPT partition attribute bits

util-linux 2.38.1, at least, does not accept raw bit indexes for the
reserved bits (Bit0-2). The undefined ones are out of reach as well and
will have sfdisk throw an error. Only the GUID specific ones can be
passed as raw indexes. This can be verified with the --part-attrs
option. It replicates the format of the --dump output:

$ dd if=/dev/zero of=disk.img bs=$((4<<10)) count=$((32<<10)
$ sgdisk disk.img -n 0:0:+64M -t 0:0FC63DAF-8483-4772-8E79-3D69D8477DE4 -c 0:root
$ sgdisk disk.img -A1:set:{0,1,2,3,48}
$ sfdisk --dump disk.img
label: gpt
label-id: 7484F730-3429-47BF-8A72-3A7AE1F2D86C
device: disk.img
unit: sectors
first-lba: 34
last-lba: 262110
sector-size: 512

disk.img1 : start=        2048, size=      131072, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=404694AC-247D-43B3-9907-A468E5C038A3, name="root", attrs="RequiredPartition NoBlockIOProtocol LegacyBIOSBootable GUID:48"

$ sfdisk --part-attrs disk.img 1 0
unsupported GPT attribute bit '0'
sfdisk: disk.img: partition 1: failed to set partition attributes

While the --dump output prefixes the GUID specific bits with "GUID:",
that is not necessary for setting them, which is consistent with the
man-page.

Signed-off-by: Eric Chanudet <echanude@redhat.com>
This commit is contained in:
Eric Chanudet 2023-04-27 13:18:30 -04:00 committed by Achilleas Koutsou
parent 9a42ce04ac
commit 267f3909bd

View file

@ -149,12 +149,22 @@ class PartitionTable:
fields = []
for field in ["start", "size", "type", "name", "uuid", "attrs"]:
value = getattr(partition, field)
if value:
if field == "attrs":
# make a list into a comma-separated string
attr_list = [str(element) for element in value]
value = ",".join(attr_list)
fields += [f'{field}="{value}"']
if not value:
continue
if field == "attrs":
resv = {
0: "RequiredPartition",
1: "NoBlockIOProtocol",
2: "LegacyBIOSBootable"
}
attrs = []
for bit in value:
if bit in resv:
attrs.append(resv[bit])
elif 48 <= bit <= 63:
attrs.append(str(bit))
value = ",".join(attrs)
fields += [f'{field}="{value}"']
if partition.bootable:
fields += ["bootable"]
command += "\n" + ", ".join(fields)