mirror of
https://github.com/flatcar/scripts.git
synced 2025-08-11 06:56:58 +02:00
Merge pull request #131 from kinvolk/kai/btrfs-usr-oem
disk_util: support compressed btrfs filesystems, use btrfs for the OEM partition
This commit is contained in:
commit
b892315775
@ -532,7 +532,7 @@ start_image() {
|
|||||||
assert_image_size "${disk_img}" raw
|
assert_image_size "${disk_img}" raw
|
||||||
|
|
||||||
"${BUILD_LIBRARY_DIR}/disk_util" --disk_layout="${disk_layout}" \
|
"${BUILD_LIBRARY_DIR}/disk_util" --disk_layout="${disk_layout}" \
|
||||||
mount "${disk_img}" "${root_fs_dir}"
|
mount --writable_verity "${disk_img}" "${root_fs_dir}"
|
||||||
trap "cleanup_mounts '${root_fs_dir}' && delete_prompt" EXIT
|
trap "cleanup_mounts '${root_fs_dir}' && delete_prompt" EXIT
|
||||||
|
|
||||||
# First thing first, install baselayout to create a working filesystem.
|
# First thing first, install baselayout to create a working filesystem.
|
||||||
|
@ -51,7 +51,8 @@
|
|||||||
"fs_label":"OEM",
|
"fs_label":"OEM",
|
||||||
"type":"data",
|
"type":"data",
|
||||||
"blocks":"262144",
|
"blocks":"262144",
|
||||||
"fs_type":"ext4",
|
"fs_type":"btrfs",
|
||||||
|
"fs_compression":"zlib",
|
||||||
"mount":"/usr/share/oem"
|
"mount":"/usr/share/oem"
|
||||||
},
|
},
|
||||||
"7":{
|
"7":{
|
||||||
|
@ -39,7 +39,8 @@ 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', 'part_alignment', 'mount',
|
'fs_block_size', 'fs_type', 'features', 'uuid', 'part_alignment', 'mount',
|
||||||
'binds', 'fs_subvolume', 'fs_bytes_per_inode', 'fs_inode_size', 'fs_label'))
|
'binds', 'fs_subvolume', 'fs_bytes_per_inode', 'fs_inode_size', 'fs_label',
|
||||||
|
'fs_compression'))
|
||||||
integer_layout_keys = set((
|
integer_layout_keys = set((
|
||||||
'blocks', 'block_size', 'fs_blocks', 'fs_block_size', 'part_alignment',
|
'blocks', 'block_size', 'fs_blocks', 'fs_block_size', 'part_alignment',
|
||||||
'fs_bytes_per_inode', 'fs_inode_size'))
|
'fs_bytes_per_inode', 'fs_inode_size'))
|
||||||
@ -349,7 +350,7 @@ def BtrfsSubvolId(path):
|
|||||||
|
|
||||||
out = subprocess.check_output(
|
out = subprocess.check_output(
|
||||||
['sudo', 'btrfs', 'subvolume', 'show', path])
|
['sudo', 'btrfs', 'subvolume', 'show', path])
|
||||||
m = re.search(r'^\s*Object ID:\s*(\d+)$', out, re.MULTILINE)
|
m = re.search(r'^\s*Subvolume ID:\s*(\d+)$', out, re.MULTILINE)
|
||||||
if not m:
|
if not m:
|
||||||
raise Exception('Failed to parse btrfs output: %r', out)
|
raise Exception('Failed to parse btrfs output: %r', out)
|
||||||
|
|
||||||
@ -363,17 +364,27 @@ def FormatBtrfs(part, device):
|
|||||||
part: dict defining the partition
|
part: dict defining the partition
|
||||||
device: name of the block device to format
|
device: name of the block device to format
|
||||||
"""
|
"""
|
||||||
cmd = ['mkfs.btrfs', '--byte-count', part['fs_bytes']]
|
cmd = ['mkfs.btrfs', '--mixed', '-m', 'single', '-d', 'single', '--byte-count', part['fs_bytes']]
|
||||||
if 'fs_label' in part:
|
if 'fs_label' in part:
|
||||||
cmd += ['--label', part['fs_label']]
|
cmd += ['--label', part['fs_label']]
|
||||||
Sudo(cmd + [device])
|
Sudo(cmd + [device])
|
||||||
|
|
||||||
|
if part.get('fs_compression', None):
|
||||||
|
btrfs_mount = tempfile.mkdtemp()
|
||||||
|
Sudo(['mount', '-t', 'btrfs', device, btrfs_mount])
|
||||||
|
try:
|
||||||
|
Sudo(['btrfs', 'property', 'set', btrfs_mount, 'compression', part['fs_compression']])
|
||||||
|
finally:
|
||||||
|
Sudo(['umount', btrfs_mount])
|
||||||
|
os.rmdir(btrfs_mount)
|
||||||
if part.get('fs_subvolume', None):
|
if part.get('fs_subvolume', None):
|
||||||
btrfs_mount = tempfile.mkdtemp()
|
btrfs_mount = tempfile.mkdtemp()
|
||||||
subvol_path = '%s/%s' % (btrfs_mount, part['fs_subvolume'])
|
subvol_path = '%s/%s' % (btrfs_mount, part['fs_subvolume'])
|
||||||
Sudo(['mount', '-t', 'btrfs', device, btrfs_mount])
|
Sudo(['mount', '-t', 'btrfs', device, btrfs_mount])
|
||||||
try:
|
try:
|
||||||
Sudo(['btrfs', 'subvolume', 'create', subvol_path])
|
Sudo(['btrfs', 'subvolume', 'create', subvol_path])
|
||||||
|
if part.get('fs_compression', None):
|
||||||
|
Sudo(['btrfs', 'property', 'set', subvol_path, 'compression', part['fs_compression']])
|
||||||
subvol_id = BtrfsSubvolId(subvol_path)
|
subvol_id = BtrfsSubvolId(subvol_path)
|
||||||
Sudo(['btrfs', 'subvolume', 'set-default', subvol_id, btrfs_mount])
|
Sudo(['btrfs', 'subvolume', 'set-default', subvol_id, btrfs_mount])
|
||||||
finally:
|
finally:
|
||||||
@ -543,9 +554,9 @@ def Update(options):
|
|||||||
continue
|
continue
|
||||||
elif part['bytes'] == part['image_bytes']:
|
elif part['bytes'] == part['image_bytes']:
|
||||||
continue
|
continue
|
||||||
elif part['fs_type'] in ('ext2', 'ext4') and IsE2fsReadWrite(options, part):
|
elif part['fs_type'] in ('ext2', 'ext4') and 'verity' not in part.get('features', []):
|
||||||
resize_func = ResizeExt
|
resize_func = ResizeExt
|
||||||
elif part.get('fs_type', None) == 'btrfs':
|
elif part.get('fs_type', None) == 'btrfs' and 'verity' not in part.get('features', []):
|
||||||
resize_func = ResizeBtrfs
|
resize_func = ResizeBtrfs
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
@ -588,11 +599,10 @@ def Mount(options):
|
|||||||
mount_opts = ['loop',
|
mount_opts = ['loop',
|
||||||
'offset=%d' % mount['image_first_byte'],
|
'offset=%d' % mount['image_first_byte'],
|
||||||
'sizelimit=%d' % mount['image_bytes']]
|
'sizelimit=%d' % mount['image_bytes']]
|
||||||
if options.read_only:
|
if options.read_only or ('verity' in mount.get('features', []) and not options.writable_verity):
|
||||||
mount_opts.append('ro')
|
|
||||||
elif (mount.get('fs_type', None) in ('ext2', 'ext4') and
|
|
||||||
not IsE2fsReadWrite(options, mount)):
|
|
||||||
mount_opts.append('ro')
|
mount_opts.append('ro')
|
||||||
|
if mount.get('fs_type', None) == 'btrfs':
|
||||||
|
mount_opts.append('norecovery')
|
||||||
|
|
||||||
if mount.get('fs_subvolume', None):
|
if mount.get('fs_subvolume', None):
|
||||||
mount_opts.append('subvol=%s' % mount['fs_subvolume'])
|
mount_opts.append('subvol=%s' % mount['fs_subvolume'])
|
||||||
@ -635,6 +645,27 @@ def Umount(options):
|
|||||||
Sudo(['umount', '--recursive', '--detach-loop', options.mount_dir])
|
Sudo(['umount', '--recursive', '--detach-loop', options.mount_dir])
|
||||||
|
|
||||||
|
|
||||||
|
def ReadWriteSubvol(options, partition, disable_rw):
|
||||||
|
"""btrfs: enable/disable read-only flag for default subvolume
|
||||||
|
"""
|
||||||
|
|
||||||
|
if disable_rw:
|
||||||
|
print "Disabling read-write on default subvolume of partition %s (%s)" % (
|
||||||
|
partition['num'], partition['label'])
|
||||||
|
else:
|
||||||
|
print "Enabling read-write on default subvolume of partition %s (%s)" % (
|
||||||
|
partition['num'], partition['label'])
|
||||||
|
|
||||||
|
with PartitionLoop(options, partition) as loop_dev:
|
||||||
|
btrfs_mount = tempfile.mkdtemp()
|
||||||
|
Sudo(['mount', '-t', 'btrfs', loop_dev, btrfs_mount])
|
||||||
|
try:
|
||||||
|
Sudo(['btrfs', 'property', 'set', '-ts', btrfs_mount, 'ro', 'true' if disable_rw else 'false'])
|
||||||
|
finally:
|
||||||
|
Sudo(['umount', btrfs_mount])
|
||||||
|
os.rmdir(btrfs_mount)
|
||||||
|
|
||||||
|
|
||||||
def Tune2fsReadWrite(options, partition, disable_rw):
|
def Tune2fsReadWrite(options, partition, disable_rw):
|
||||||
"""Enable/Disable read-only hack.
|
"""Enable/Disable read-only hack.
|
||||||
|
|
||||||
@ -716,9 +747,12 @@ def Tune(options):
|
|||||||
raise InvalidLayout("Disk layout is incompatible with existing image")
|
raise InvalidLayout("Disk layout is incompatible with existing image")
|
||||||
|
|
||||||
if options.disable2fs_rw is not None:
|
if options.disable2fs_rw is not None:
|
||||||
if part.get('fs_type', None) not in ('ext2', 'ext4'):
|
if part.get('fs_type', None) in ('ext2', 'ext4'):
|
||||||
raise Exception("Partition %s is not a ext2 or ext4" % options.partition)
|
Tune2fsReadWrite(options, part, options.disable2fs_rw)
|
||||||
Tune2fsReadWrite(options, part, options.disable2fs_rw)
|
elif part.get('fs_type', None) == 'btrfs':
|
||||||
|
ReadWriteSubvol(options, part, options.disable2fs_rw)
|
||||||
|
else:
|
||||||
|
raise Exception("Partition %s is not a ext2 or ext4 or btrfs" % options.partition)
|
||||||
else:
|
else:
|
||||||
raise Exception("No options specified!")
|
raise Exception("No options specified!")
|
||||||
|
|
||||||
@ -742,6 +776,8 @@ def Verity(options):
|
|||||||
|
|
||||||
if part.get('fs_type', None) in ('ext2', 'ext4'):
|
if part.get('fs_type', None) in ('ext2', 'ext4'):
|
||||||
Tune2fsReadWrite(options, part, disable_rw=True)
|
Tune2fsReadWrite(options, part, disable_rw=True)
|
||||||
|
elif part.get('fs_type', None) == 'btrfs':
|
||||||
|
ReadWriteSubvol(options, part, disable_rw=True)
|
||||||
|
|
||||||
with PartitionLoop(options, part) as loop_dev:
|
with PartitionLoop(options, part) as loop_dev:
|
||||||
verityout = SudoOutput(['veritysetup', 'format', '--hash=sha256',
|
verityout = SudoOutput(['veritysetup', 'format', '--hash=sha256',
|
||||||
@ -1005,8 +1041,10 @@ def main(argv):
|
|||||||
a.set_defaults(func=Update, create=False)
|
a.set_defaults(func=Update, create=False)
|
||||||
|
|
||||||
a = actions.add_parser('mount', help='mount filesystems in image')
|
a = actions.add_parser('mount', help='mount filesystems in image')
|
||||||
|
a.add_argument('--writable_verity', '-w', action='store_true',
|
||||||
|
help='mount verity-protected filesystems writable')
|
||||||
a.add_argument('--read_only', '-r', action='store_true',
|
a.add_argument('--read_only', '-r', action='store_true',
|
||||||
help='mount filesystems read-only')
|
help='mount filesystems read-only (takes precedence over --writable_verity)')
|
||||||
a.add_argument('disk_image', help='path to disk image file')
|
a.add_argument('disk_image', help='path to disk image file')
|
||||||
a.add_argument('mount_dir', help='path to root filesystem mount point')
|
a.add_argument('mount_dir', help='path to root filesystem mount point')
|
||||||
a.set_defaults(func=Mount)
|
a.set_defaults(func=Mount)
|
||||||
|
Loading…
Reference in New Issue
Block a user