]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
Use Initrds= for qemu direct kernel boot as a fallback
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Tue, 21 Jan 2025 15:03:28 +0000 (16:03 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Tue, 21 Jan 2025 16:04:55 +0000 (17:04 +0100)
Fixes #3180

mkosi/__init__.py
mkosi/qemu.py

index dad8609d81e5a2b8669a0b205103974454d96d02..3a13440c02d5e35357a71cb95a2eb50aa1c6f68f 100644 (file)
@@ -5,7 +5,6 @@ import dataclasses
 import datetime
 import functools
 import hashlib
-import io
 import itertools
 import json
 import logging
@@ -92,6 +91,7 @@ from mkosi.qemu import (
     copy_ephemeral,
     finalize_credentials,
     finalize_kernel_command_line_extra,
+    join_initrds,
     run_qemu,
     run_ssh,
     start_journal_remote,
@@ -137,7 +137,6 @@ from mkosi.util import (
     make_executable,
     one_zero,
     read_env_file,
-    round_up,
     scopedenv,
 )
 from mkosi.versioncomp import GenericVersion
@@ -1499,25 +1498,6 @@ def find_devicetree(context: Context, kver: str) -> Path:
     die(f"Requested devicetree {context.config.devicetree} not found")
 
 
-def join_initrds(initrds: Sequence[Path], output: Path) -> Path:
-    assert initrds
-
-    if len(initrds) == 1:
-        shutil.copy2(initrds[0], output)
-        return output
-
-    seq = io.BytesIO()
-    for p in initrds:
-        initrd = p.read_bytes()
-        n = len(initrd)
-        padding = b"\0" * (round_up(n, 4) - n)  # pad to 32 bit alignment
-        seq.write(initrd)
-        seq.write(padding)
-
-    output.write_bytes(seq.getbuffer())
-    return output
-
-
 def want_signed_pcrs(config: Config) -> bool:
     return config.sign_expected_pcr == ConfigFeature.enabled or (
         config.sign_expected_pcr == ConfigFeature.auto
@@ -2338,7 +2318,7 @@ def copy_initrd(context: Context) -> None:
         if context.config.kernel_modules_initrd:
             kver = next(gen_kernel_images(context))[0]
             initrds += [build_kernel_modules_initrd(context, kver)]
-        join_initrds(initrds, context.staging / context.config.output_split_initrd)
+        join_initrds(context.config, initrds, context.staging / context.config.output_split_initrd)
         break
 
 
index bef8d7c663196fadc96638e7fe564e781c42bfaf..84bfad8184212076858a6cfb9b9a0b5305776f5a 100644 (file)
@@ -7,6 +7,7 @@ import enum
 import errno
 import fcntl
 import hashlib
+import io
 import json
 import logging
 import os
@@ -638,6 +639,25 @@ def copy_ephemeral(config: Config, src: Path) -> Iterator[Path]:
         fork_and_wait(rm)
 
 
+def join_initrds(config: Config, initrds: Sequence[Path], output: Path) -> Path:
+    assert initrds
+
+    if len(initrds) == 1:
+        copy_tree(initrds[0], output, sandbox=config.sandbox)
+        return output
+
+    seq = io.BytesIO()
+    for p in initrds:
+        initrd = p.read_bytes()
+        n = len(initrd)
+        padding = b"\0" * (round_up(n, 4) - n)  # pad to 32 bit alignment
+        seq.write(initrd)
+        seq.write(padding)
+
+    output.write_bytes(seq.getbuffer())
+    return output
+
+
 def qemu_version(config: Config, binary: Path) -> GenericVersion:
     return GenericVersion(
         run(
@@ -1343,9 +1363,14 @@ def run_qemu(args: Args, config: Config) -> None:
             kernel
             and KernelType.identify(config, kernel) != KernelType.uki
             and "-initrd" not in args.cmdline
-            and (config.output_dir_or_cwd() / config.output_split_initrd).exists()
         ):
-            cmdline += ["-initrd", config.output_dir_or_cwd() / config.output_split_initrd]
+            if (config.output_dir_or_cwd() / config.output_split_initrd).exists():
+                cmdline += ["-initrd", config.output_dir_or_cwd() / config.output_split_initrd]
+            elif config.initrds:
+                initrd = config.output_dir_or_cwd() / f"initrd-{uuid.uuid4().hex}"
+                join_initrds(config, config.initrds, initrd)
+                stack.callback(lambda: initrd.unlink())
+                cmdline += ["-initrd", fname]
 
         if config.output_format in (OutputFormat.disk, OutputFormat.esp):
             direct = fname.stat().st_size % resource.getpagesize() == 0