From 008bcf0b24596e8a3a5a49391bafc6da4145938b Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Fri, 12 Mar 2021 16:41:53 +0100 Subject: [PATCH 1/2] run.py: prepare for compressed initramfs In preparation for supporting using a compressed initramfs, refactor the code to send the initramfs data through a subprocess. --- virtme/commands/run.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/virtme/commands/run.py b/virtme/commands/run.py index f9ee4dd..80709d4 100644 --- a/virtme/commands/run.py +++ b/virtme/commands/run.py @@ -551,9 +551,14 @@ def do_script(shellcmd: str, use_exec=False, show_boot_console=False) -> None: else: initramfsfd,tmpname = tempfile.mkstemp('irfs') os.unlink(tmpname) - initramfsfile = os.fdopen(initramfsfd, 'r+b') - mkinitramfs.mkinitramfs(initramfsfile, config) - initramfsfile.flush() + + compressor = subprocess.Popen(['cat'], stdin=subprocess.PIPE, stdout=initramfsfd) + mkinitramfs.mkinitramfs(compressor.stdin, config) + compressor.stdin.close() + if compressor.wait() != 0: + print("writing initramfs failed", file=sys.stderr) + return 1 + if args.save_initramfs is not None: initrdpath = args.save_initramfs else: From 673d6e1d7ee384898e41f4ff0c6573a7946a3662 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Fri, 12 Mar 2021 17:11:09 +0100 Subject: [PATCH 2/2] run.py: support different initramfs compression methods In order to test/debug/benchmark various initramfs decompression methods, it is useful to be able to let virtme provide a compressed initramfs. --- virtme/commands/run.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/virtme/commands/run.py b/virtme/commands/run.py index 80709d4..edf7963 100644 --- a/virtme/commands/run.py +++ b/virtme/commands/run.py @@ -110,6 +110,9 @@ def make_parser() -> argparse.ArgumentParser: help='Show the VM command line') g.add_argument('--save-initramfs', action='store', help='Save the generated initramfs to the specified path') + g.add_argument('--initramfs-compression', action='store', default='none', + choices=['none', 'gz', 'lz4', 'xz', 'zstd'], + help='Compression method to use for initramfs') g.add_argument('--show-boot-console', action='store_true', help='Show the boot console when running scripts') @@ -272,6 +275,14 @@ def sanitize_disk_args(func: str, arg: str) -> Tuple[str, str]: return name, fn +def initramfs_compress_cmd(method: str) -> List[str]: + if method == 'none': return ['cat'] + if method == 'gz': return ['gzip', '-n', '-9', '-f'] + if method == 'lz4': return ['lz4', '-l', '-9', '-f'] + if method == 'xz': return ['xz', '--check=crc32', '--lzma2=dict=1MiB'] + if method == 'zstd': return ['zstd', '-19'] + arg_fail("Unsupported initramfs compression method %s" % (method)) + # Allowed characters in mount paths. We can extend this over time if needed. _SAFE_PATH_PATTERN = '[a-zA-Z0-9_+ /.-]+' _RWDIR_RE = re.compile('^(%s)(?:=(%s))?$' % @@ -552,7 +563,8 @@ def do_script(shellcmd: str, use_exec=False, show_boot_console=False) -> None: initramfsfd,tmpname = tempfile.mkstemp('irfs') os.unlink(tmpname) - compressor = subprocess.Popen(['cat'], stdin=subprocess.PIPE, stdout=initramfsfd) + compress_cmd = initramfs_compress_cmd(args.initramfs_compression) + compressor = subprocess.Popen(compress_cmd, stdin=subprocess.PIPE, stdout=initramfsfd) mkinitramfs.mkinitramfs(compressor.stdin, config) compressor.stdin.close() if compressor.wait() != 0: