mirror of
https://github.com/flatcar/scripts.git
synced 2025-09-23 14:41:31 +02:00
fix(cgpt.py): Add support for aligning partitions
When using anything other than classic spinning disks with 512 sectors it is generally best to maintain some alignment with the underlying physical sector or erase block size. The default alignment most partitioning tools use these days is 1MB (2048 sectors). Also sometimes qemu-img requires disk sizes to be aligned to 64KB.
This commit is contained in:
parent
ecca978053
commit
03754b2d62
@ -36,7 +36,7 @@ def LoadPartitionConfig(filename):
|
|||||||
valid_keys = set(('_comment', 'metadata', 'layouts'))
|
valid_keys = set(('_comment', 'metadata', 'layouts'))
|
||||||
valid_layout_keys = set((
|
valid_layout_keys = set((
|
||||||
'_comment', 'type', 'num', 'label', 'blocks', 'block_size', 'fs_blocks',
|
'_comment', 'type', 'num', 'label', 'blocks', 'block_size', 'fs_blocks',
|
||||||
'fs_block_size', 'features', 'uuid'))
|
'fs_block_size', 'features', 'uuid', 'alignment'))
|
||||||
|
|
||||||
if not os.path.exists(filename):
|
if not os.path.exists(filename):
|
||||||
raise ConfigNotFound('Partition config %s was not found!' % filename)
|
raise ConfigNotFound('Partition config %s was not found!' % filename)
|
||||||
@ -45,9 +45,14 @@ def LoadPartitionConfig(filename):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
metadata = config['metadata']
|
metadata = config['metadata']
|
||||||
for key in ('block_size', 'fs_block_size'):
|
for key in ('alignment', 'block_size', 'fs_block_size'):
|
||||||
metadata[key] = int(metadata[key])
|
metadata[key] = int(metadata[key])
|
||||||
|
|
||||||
|
# Sometimes qemu-img expects disks sizes aligned to 64k
|
||||||
|
align_bytes = metadata['alignment'] * metadata['block_size']
|
||||||
|
if align_bytes < 65536 or align_bytes % 65536 != 0:
|
||||||
|
raise InvalidLayout('Invalid alignment, 64KB or better required')
|
||||||
|
|
||||||
unknown_keys = set(config.keys()) - valid_keys
|
unknown_keys = set(config.keys()) - valid_keys
|
||||||
if unknown_keys:
|
if unknown_keys:
|
||||||
raise InvalidLayout('Unknown items: %r' % unknown_keys)
|
raise InvalidLayout('Unknown items: %r' % unknown_keys)
|
||||||
@ -67,6 +72,7 @@ def LoadPartitionConfig(filename):
|
|||||||
if not s in part:
|
if not s in part:
|
||||||
raise InvalidLayout('Layout "%s" missing "%s"' % (layout_name, s))
|
raise InvalidLayout('Layout "%s" missing "%s"' % (layout_name, s))
|
||||||
|
|
||||||
|
part['alignment'] = int(part.get('alignment', metadata['alignment']))
|
||||||
part['blocks'] = int(part['blocks'])
|
part['blocks'] = int(part['blocks'])
|
||||||
part['bytes'] = part['blocks'] * metadata['block_size']
|
part['bytes'] = part['blocks'] * metadata['block_size']
|
||||||
|
|
||||||
@ -220,19 +226,30 @@ def WritePartitionTable(options, image_type, layout_filename, disk_filename):
|
|||||||
def Cgpt(*args):
|
def Cgpt(*args):
|
||||||
subprocess.check_call(['cgpt'] + [str(a) for a in args])
|
subprocess.check_call(['cgpt'] + [str(a) for a in args])
|
||||||
|
|
||||||
|
def Align(count, alignment):
|
||||||
|
offset = count % alignment
|
||||||
|
if offset:
|
||||||
|
count += alignment - offset
|
||||||
|
return count
|
||||||
|
|
||||||
config = LoadPartitionConfig(layout_filename)
|
config = LoadPartitionConfig(layout_filename)
|
||||||
|
metadata = config['metadata']
|
||||||
partitions = GetPartitionTable(options, config, image_type)
|
partitions = GetPartitionTable(options, config, image_type)
|
||||||
disk_block_count = GPT_RESERVED_SECTORS
|
disk_block_count = GPT_RESERVED_SECTORS
|
||||||
|
|
||||||
for partition in partitions:
|
for partition in partitions:
|
||||||
|
disk_block_count = Align(disk_block_count, partition['alignment'])
|
||||||
disk_block_count += partition['blocks']
|
disk_block_count += partition['blocks']
|
||||||
|
|
||||||
disk_block_count += GPT_RESERVED_SECTORS
|
disk_block_count += GPT_RESERVED_SECTORS
|
||||||
|
# Sometimes qemu-img expects disks sizes aligned to 64k
|
||||||
|
disk_block_count = Align(disk_block_count, config['metadata']['alignment'])
|
||||||
|
|
||||||
Cgpt('create', '-c', '-s', disk_block_count, disk_filename)
|
Cgpt('create', '-c', '-s', disk_block_count, disk_filename)
|
||||||
|
|
||||||
sector = GPT_RESERVED_SECTORS
|
sector = GPT_RESERVED_SECTORS
|
||||||
for partition in partitions:
|
for partition in partitions:
|
||||||
|
sector = Align(sector, partition['alignment'])
|
||||||
if partition['type'] != 'blank':
|
if partition['type'] != 'blank':
|
||||||
Cgpt('add', '-i', partition['num'],
|
Cgpt('add', '-i', partition['num'],
|
||||||
'-b', sector,
|
'-b', sector,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"_comment": "See http://www.chromium.org/chromium-os/building-chromium-os/disk-layout-format",
|
"_comment": "See http://www.chromium.org/chromium-os/building-chromium-os/disk-layout-format",
|
||||||
"metadata":{
|
"metadata":{
|
||||||
|
"alignment": 2048,
|
||||||
"block_size": 512,
|
"block_size": 512,
|
||||||
"fs_block_size": 4096
|
"fs_block_size": 4096
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user