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:
Michael Marineau 2013-10-16 18:33:20 -07:00
parent ecca978053
commit 03754b2d62
2 changed files with 20 additions and 2 deletions

View File

@ -36,7 +36,7 @@ def LoadPartitionConfig(filename):
valid_keys = set(('_comment', 'metadata', 'layouts'))
valid_layout_keys = set((
'_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):
raise ConfigNotFound('Partition config %s was not found!' % filename)
@ -45,9 +45,14 @@ def LoadPartitionConfig(filename):
try:
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])
# 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
if unknown_keys:
raise InvalidLayout('Unknown items: %r' % unknown_keys)
@ -67,6 +72,7 @@ def LoadPartitionConfig(filename):
if not s in part:
raise InvalidLayout('Layout "%s" missing "%s"' % (layout_name, s))
part['alignment'] = int(part.get('alignment', metadata['alignment']))
part['blocks'] = int(part['blocks'])
part['bytes'] = part['blocks'] * metadata['block_size']
@ -220,19 +226,30 @@ def WritePartitionTable(options, image_type, layout_filename, disk_filename):
def Cgpt(*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)
metadata = config['metadata']
partitions = GetPartitionTable(options, config, image_type)
disk_block_count = GPT_RESERVED_SECTORS
for partition in partitions:
disk_block_count = Align(disk_block_count, partition['alignment'])
disk_block_count += partition['blocks']
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)
sector = GPT_RESERVED_SECTORS
for partition in partitions:
sector = Align(sector, partition['alignment'])
if partition['type'] != 'blank':
Cgpt('add', '-i', partition['num'],
'-b', sector,

View File

@ -1,6 +1,7 @@
{
"_comment": "See http://www.chromium.org/chromium-os/building-chromium-os/disk-layout-format",
"metadata":{
"alignment": 2048,
"block_size": 512,
"fs_block_size": 4096
},