mirror of
https://github.com/flatcar/scripts.git
synced 2025-08-09 05:56:58 +02:00
feat(disk_util): Switch to btrfs for root filesystem in /usr images
This is all that is required to swap out ext4 for btrfs. No btrfs user space tools or auto-resize support yet.
This commit is contained in:
parent
2aa3571e45
commit
4dbdb391a4
@ -42,9 +42,10 @@ get_uuid() {
|
|||||||
|
|
||||||
# Filesystem args differ between the old and new usr layouts.
|
# Filesystem args differ between the old and new usr layouts.
|
||||||
if [[ "${FLAGS_disk_layout}" == *-usr ]]; then
|
if [[ "${FLAGS_disk_layout}" == *-usr ]]; then
|
||||||
gptprio_args="root=LABEL=ROOT usr=gptprio:"
|
root_args="root=LABEL=ROOT rootflags=subvol=root"
|
||||||
slot_a_args="root=LABEL=ROOT usr=PARTUUID=$(get_uuid USR-A)"
|
gptprio_args="${root_args} usr=gptprio:"
|
||||||
slot_b_args="root=LABEL=ROOT usr=PARTUUID=$(get_uuid USR-B)"
|
slot_a_args="${root_args} usr=PARTUUID=$(get_uuid USR-A)"
|
||||||
|
slot_b_args="${root_args} usr=PARTUUID=$(get_uuid USR-B)"
|
||||||
else
|
else
|
||||||
gptprio_args="root=gptprio:"
|
gptprio_args="root=gptprio:"
|
||||||
slot_a_args="root=PARTUUID=$(get_uuid ROOT-A)"
|
slot_a_args="root=PARTUUID=$(get_uuid ROOT-A)"
|
||||||
|
@ -83,6 +83,8 @@
|
|||||||
},
|
},
|
||||||
"9":{
|
"9":{
|
||||||
"label":"ROOT",
|
"label":"ROOT",
|
||||||
|
"fs_type":"btrfs",
|
||||||
|
"fs_subvolume":"root",
|
||||||
"mount":"/",
|
"mount":"/",
|
||||||
"binds":{}
|
"binds":{}
|
||||||
}
|
}
|
||||||
@ -103,6 +105,8 @@
|
|||||||
},
|
},
|
||||||
"9":{
|
"9":{
|
||||||
"label":"ROOT",
|
"label":"ROOT",
|
||||||
|
"fs_type":"btrfs",
|
||||||
|
"fs_subvolume":"root",
|
||||||
"mount":"/",
|
"mount":"/",
|
||||||
"binds":{},
|
"binds":{},
|
||||||
"blocks":"6291456"
|
"blocks":"6291456"
|
||||||
@ -124,6 +128,8 @@
|
|||||||
},
|
},
|
||||||
"9":{
|
"9":{
|
||||||
"label":"ROOT",
|
"label":"ROOT",
|
||||||
|
"fs_type":"btrfs",
|
||||||
|
"fs_subvolume":"root",
|
||||||
"mount":"/",
|
"mount":"/",
|
||||||
"binds":{},
|
"binds":{},
|
||||||
"blocks":"33587200"
|
"blocks":"33587200"
|
||||||
|
@ -38,7 +38,7 @@ def LoadPartitionConfig(options):
|
|||||||
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', 'fs_type', 'features', 'uuid', 'alignment', 'mount',
|
'fs_block_size', 'fs_type', 'features', 'uuid', 'alignment', 'mount',
|
||||||
'binds'))
|
'binds', 'fs_subvolume'))
|
||||||
integer_layout_keys = set((
|
integer_layout_keys = set((
|
||||||
'blocks', 'block_size', 'fs_blocks', 'fs_block_size', 'alignment'))
|
'blocks', 'block_size', 'fs_blocks', 'fs_block_size', 'alignment'))
|
||||||
required_layout_keys = set(('type', 'num', 'label', 'blocks'))
|
required_layout_keys = set(('type', 'num', 'label', 'blocks'))
|
||||||
@ -99,9 +99,12 @@ def LoadPartitionConfig(options):
|
|||||||
raise InvalidLayout('Invalid uuid %r: %s' % (part['uuid'], e))
|
raise InvalidLayout('Invalid uuid %r: %s' % (part['uuid'], e))
|
||||||
|
|
||||||
if 'fs_type' in part:
|
if 'fs_type' in part:
|
||||||
if part['fs_type'] not in ('ext2', 'ext4', 'vfat'):
|
if part['fs_type'] not in ('btrfs', 'ext2', 'ext4', 'vfat'):
|
||||||
raise InvalidLayout('Invalid fs_type: %r' % part['fs_type'])
|
raise InvalidLayout('Invalid fs_type: %r' % part['fs_type'])
|
||||||
|
|
||||||
|
if 'fs_subvolume' in part:
|
||||||
|
if part.get('fs_type', None) != 'btrfs':
|
||||||
|
raise InvalidLayout('Invalid fs: only btrfs supports subvolumes')
|
||||||
|
|
||||||
def Align(count, alignment):
|
def Align(count, alignment):
|
||||||
offset = count % alignment
|
offset = count % alignment
|
||||||
@ -300,6 +303,33 @@ def Sudo(cmd, stdout_null=False):
|
|||||||
null.close()
|
null.close()
|
||||||
|
|
||||||
|
|
||||||
|
def FormatBtrfs(part, device):
|
||||||
|
"""Format an ext2 or ext4 filesystem.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
part: dict defining the partition
|
||||||
|
device: name of the block device to format
|
||||||
|
"""
|
||||||
|
Sudo(['mkfs.btrfs', '--byte-count', part['fs_bytes'],
|
||||||
|
'--label', part['label'],
|
||||||
|
# must use mixed chunks at this point because
|
||||||
|
# the filesystem size is too small.
|
||||||
|
'--data', 'single',
|
||||||
|
'--metadata', 'single',
|
||||||
|
'--mixed',
|
||||||
|
device])
|
||||||
|
|
||||||
|
if part.get('fs_subvolume', None):
|
||||||
|
btrfs_mount = tempfile.mkdtemp()
|
||||||
|
subvol_path = '%s/%s' % (btrfs_mount, part['fs_subvolume'])
|
||||||
|
Sudo(['mount', '-t', 'btrfs', device, btrfs_mount])
|
||||||
|
try:
|
||||||
|
Sudo(['btrfs', 'subvolume', 'create', subvol_path])
|
||||||
|
finally:
|
||||||
|
Sudo(['umount', btrfs_mount])
|
||||||
|
os.rmdir(btrfs_mount)
|
||||||
|
|
||||||
|
|
||||||
def FormatExt(part, device):
|
def FormatExt(part, device):
|
||||||
"""Format an ext2 or ext4 filesystem.
|
"""Format an ext2 or ext4 filesystem.
|
||||||
|
|
||||||
@ -394,12 +424,41 @@ def Format(options):
|
|||||||
with PartitionLoop(options, part) as loop_dev:
|
with PartitionLoop(options, part) as loop_dev:
|
||||||
if part['fs_type'] in ('ext2', 'ext4'):
|
if part['fs_type'] in ('ext2', 'ext4'):
|
||||||
FormatExt(part, loop_dev)
|
FormatExt(part, loop_dev)
|
||||||
|
elif part['fs_type'] == 'btrfs':
|
||||||
|
FormatBtrfs(part, loop_dev)
|
||||||
elif part['fs_type'] == 'vfat':
|
elif part['fs_type'] == 'vfat':
|
||||||
FormatFat(part, loop_dev)
|
FormatFat(part, loop_dev)
|
||||||
else:
|
else:
|
||||||
raise Exception("Unhandled fs type %s" % part['fs_type'])
|
raise Exception("Unhandled fs type %s" % part['fs_type'])
|
||||||
|
|
||||||
|
|
||||||
|
def ResizeExt(part, device):
|
||||||
|
"""Resize ext[234] filesystems.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
part: dict defining the partition
|
||||||
|
device: name of the block device
|
||||||
|
"""
|
||||||
|
Sudo(['e2fsck', '-p', '-f', loop_dev], stdout_null=True)
|
||||||
|
Sudo(['resize2fs', loop_dev, str(part['fs_blocks'])])
|
||||||
|
|
||||||
|
|
||||||
|
def ResizeBtrfs(part, device):
|
||||||
|
"""Resize btrfs filesystems.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
part: dict defining the partition
|
||||||
|
device: name of the block device
|
||||||
|
"""
|
||||||
|
btrfs_mount = tempfile.mkdtemp()
|
||||||
|
Sudo(['mount', '-t', 'btrfs', device, btrfs_mount])
|
||||||
|
try:
|
||||||
|
Sudo(['btrfs', 'filesystem', 'resize', part['fs_bytes'], btrfs_mount])
|
||||||
|
finally:
|
||||||
|
Sudo(['umount', btrfs_mount])
|
||||||
|
os.rmdir(btrfs_mount)
|
||||||
|
|
||||||
|
|
||||||
def Resize(options):
|
def Resize(options):
|
||||||
"""Writes the given partition table and resize ext[234] filesystems.
|
"""Writes the given partition table and resize ext[234] filesystems.
|
||||||
|
|
||||||
@ -411,19 +470,23 @@ def Resize(options):
|
|||||||
WritePartitionTable(options, config, partitions)
|
WritePartitionTable(options, config, partitions)
|
||||||
|
|
||||||
for part in partitions.itervalues():
|
for part in partitions.itervalues():
|
||||||
if part.get('fs_type', None) not in ('ext2', 'ext4'):
|
resize_func = None
|
||||||
|
if not part.get('fs_type', None):
|
||||||
continue
|
continue
|
||||||
elif part['bytes'] == part['image_bytes']:
|
elif part['bytes'] == part['image_bytes']:
|
||||||
continue
|
continue
|
||||||
elif not IsE2fsReadWrite(options, part):
|
elif part['fs_type'] in ('ext2', 'ext4') and IsE2fsReadWrite(options, part):
|
||||||
|
resize_func = ResizeExt
|
||||||
|
elif part.get('fs_type', None) == 'btrfs':
|
||||||
|
resize_func = ResizeBtrfs
|
||||||
|
else:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
print "Resizing partition %s (%s) to %s bytes" % (
|
print "Resizing partition %s (%s) to %s bytes" % (
|
||||||
part['num'], part['label'], part['fs_bytes'])
|
part['num'], part['label'], part['fs_bytes'])
|
||||||
|
|
||||||
with PartitionLoop(options, part) as loop_dev:
|
with PartitionLoop(options, part) as loop_dev:
|
||||||
Sudo(['e2fsck', '-p', '-f', loop_dev], stdout_null=True)
|
resize_func(part, loop_dev)
|
||||||
Sudo(['resize2fs', loop_dev, str(part['fs_blocks'])])
|
|
||||||
|
|
||||||
|
|
||||||
def Mount(options):
|
def Mount(options):
|
||||||
@ -463,6 +526,9 @@ def Mount(options):
|
|||||||
not IsE2fsReadWrite(options, mount)):
|
not IsE2fsReadWrite(options, mount)):
|
||||||
mount_opts.append('ro')
|
mount_opts.append('ro')
|
||||||
|
|
||||||
|
if mount.get('fs_subvolume', None):
|
||||||
|
mount_opts.append('subvol=%s' % mount['fs_subvolume'])
|
||||||
|
|
||||||
Sudo(['mkdir', '-p', full_path])
|
Sudo(['mkdir', '-p', full_path])
|
||||||
Sudo(['mount', '-t', mount.get('fs_type', 'auto'),
|
Sudo(['mount', '-t', mount.get('fs_type', 'auto'),
|
||||||
'-o', ','.join(mount_opts),
|
'-o', ','.join(mount_opts),
|
||||||
|
Loading…
Reference in New Issue
Block a user