Skip to content

Commit 811be45

Browse files
authored
Merge pull request #2910 from DaanDeMeyer/qemu
Look up qemu and virt-fw-vars in extra search paths
2 parents a876e0a + 93a2bc7 commit 811be45

3 files changed

Lines changed: 36 additions & 40 deletions

File tree

mkosi/kmod.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ def filter_kernel_modules(root: Path, kver: str, *, include: Iterable[str], excl
2929
for m in modules:
3030
rel = os.fspath(Path(*m.parts[1:]))
3131
if regex.search(rel):
32-
logging.debug(f"Including module {rel}")
3332
keep.add(rel)
3433

3534
if exclude:
@@ -38,7 +37,6 @@ def filter_kernel_modules(root: Path, kver: str, *, include: Iterable[str], excl
3837
for m in modules:
3938
rel = os.fspath(Path(*m.parts[1:]))
4039
if rel not in keep and regex.search(rel):
41-
logging.debug(f"Excluding module {rel}")
4240
remove.add(m)
4341

4442
modules -= remove
@@ -221,7 +219,6 @@ def process_kernel_modules(
221219

222220
p = root / m
223221
if p.is_file() or p.is_symlink():
224-
logging.debug(f"Removing module {m}")
225222
p.unlink()
226223
else:
227224
p.rmdir()
@@ -235,7 +232,6 @@ def process_kernel_modules(
235232

236233
p = root / fw
237234
if p.is_file() or p.is_symlink():
238-
logging.debug(f"Removing firmware {fw}")
239235
p.unlink()
240236
else:
241237
p.rmdir()

mkosi/qemu.py

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -170,16 +170,6 @@ def identify(cls, config: Config, path: Path) -> "KernelType":
170170
return KernelType.unknown
171171

172172

173-
def find_qemu_binary(config: Config) -> str:
174-
binaries = [f"qemu-system-{config.architecture.to_qemu()}"]
175-
binaries += ["qemu", "qemu-kvm"] if config.architecture.is_native() else []
176-
for binary in binaries:
177-
if config.find_binary(binary) is not None:
178-
return binary
179-
180-
die("Couldn't find QEMU/KVM binary")
181-
182-
183173
@dataclasses.dataclass(frozen=True)
184174
class OvmfConfig:
185175
description: Path
@@ -189,13 +179,15 @@ class OvmfConfig:
189179
vars_format: str
190180

191181

192-
def find_ovmf_firmware(config: Config, firmware: QemuFirmware) -> Optional[OvmfConfig]:
182+
def find_ovmf_firmware(config: Config, qemu: Path, firmware: QemuFirmware) -> Optional[OvmfConfig]:
193183
if not firmware.is_uefi():
194184
return None
195185

196-
desc = list((config.tools() / "usr/share/qemu/firmware").glob("*"))
197-
if config.tools() == Path("/"):
198-
desc += list((config.tools() / "etc/qemu/firmware").glob("*"))
186+
tools = Path("/") if any(qemu.is_relative_to(d) for d in config.extra_search_paths) else config.tools()
187+
188+
desc = list((tools / "usr/share/qemu/firmware").glob("*"))
189+
if tools == Path("/"):
190+
desc += list((tools / "etc/qemu/firmware").glob("*"))
199191

200192
arch = config.architecture.to_qemu()
201193
machine = config.architecture.default_qemu_machine()
@@ -243,7 +235,7 @@ def find_ovmf_firmware(config: Config, firmware: QemuFirmware) -> Optional[OvmfC
243235
logging.debug(f"Using {p.name} firmware description")
244236

245237
return OvmfConfig(
246-
description=Path("/") / p.relative_to(config.tools()),
238+
description=Path("/") / p.relative_to(tools),
247239
firmware=Path(j["mapping"]["executable"]["filename"]),
248240
format=j["mapping"]["executable"]["format"],
249241
vars=Path(j["mapping"]["nvram-template"]["filename"]),
@@ -567,8 +559,7 @@ def rm() -> None:
567559
fork_and_wait(rm)
568560

569561

570-
def qemu_version(config: Config) -> GenericVersion:
571-
binary = find_qemu_binary(config)
562+
def qemu_version(config: Config, binary: Path) -> GenericVersion:
572563
return GenericVersion(
573564
run(
574565
[binary, "--version"],
@@ -620,7 +611,12 @@ def finalize_qemu_firmware(config: Config, kernel: Optional[Path]) -> QemuFirmwa
620611
return config.qemu_firmware
621612

622613

623-
def finalize_firmware_variables(config: Config, ovmf: OvmfConfig, stack: contextlib.ExitStack) -> tuple[Path, str]:
614+
def finalize_firmware_variables(
615+
config: Config,
616+
qemu: Path,
617+
ovmf: OvmfConfig,
618+
stack: contextlib.ExitStack,
619+
) -> tuple[Path, str]:
624620
ovmf_vars = stack.enter_context(tempfile.NamedTemporaryFile(prefix="mkosi-ovmf-vars-"))
625621
if config.qemu_firmware_variables in (None, Path("custom"), Path("microsoft")):
626622
ovmf_vars_format = ovmf.vars_format
@@ -641,16 +637,17 @@ def finalize_firmware_variables(config: Config, ovmf: OvmfConfig, stack: context
641637
"--loglevel", "WARNING",
642638
],
643639
sandbox=config.sandbox(
644-
binary=None,
640+
binary=qemu,
645641
mounts=[
646642
Mount(ovmf_vars.name, ovmf_vars.name),
647643
Mount(config.secure_boot_certificate, config.secure_boot_certificate, ro=True),
648644
],
649645
),
650646
)
651647
else:
648+
tools = Path("/") if any(qemu.is_relative_to(d) for d in config.extra_search_paths) else config.tools()
652649
vars = (
653-
config.tools() / ovmf.vars.relative_to("/")
650+
tools / ovmf.vars.relative_to("/")
654651
if config.qemu_firmware_variables == Path("microsoft") or not config.qemu_firmware_variables
655652
else config.qemu_firmware_variables
656653
)
@@ -833,8 +830,11 @@ def run_qemu(args: Args, config: Config) -> None:
833830
if d.feature(config) != ConfigFeature.disabled and d.available(log=True)
834831
}
835832

836-
have_kvm = ((qemu_version(config) < QEMU_KVM_DEVICE_VERSION and QemuDeviceNode.kvm.available()) or
837-
(qemu_version(config) >= QEMU_KVM_DEVICE_VERSION and QemuDeviceNode.kvm in qemu_device_fds))
833+
if not (qemu := config.find_binary(f"qemu-system-{config.architecture.to_qemu()}")):
834+
die("qemu not found.", hint=f"Is qemu-system-{config.architecture.to_qemu()} installed on the host system?")
835+
836+
have_kvm = ((qemu_version(config, qemu) < QEMU_KVM_DEVICE_VERSION and QemuDeviceNode.kvm.available()) or
837+
(qemu_version(config, qemu) >= QEMU_KVM_DEVICE_VERSION and QemuDeviceNode.kvm in qemu_device_fds))
838838
if config.qemu_kvm == ConfigFeature.enabled and not have_kvm:
839839
die("KVM acceleration requested but cannot access /dev/kvm")
840840

@@ -877,7 +877,7 @@ def run_qemu(args: Args, config: Config) -> None:
877877
"or provide a -kernel argument to mkosi qemu"
878878
)
879879

880-
ovmf = find_ovmf_firmware(config, firmware)
880+
ovmf = find_ovmf_firmware(config, qemu, firmware)
881881

882882
# A shared memory backend might increase ram usage so only add one if actually necessary for virtiofsd.
883883
shm = []
@@ -891,7 +891,7 @@ def run_qemu(args: Args, config: Config) -> None:
891891
machine += ",memory-backend=mem"
892892

893893
cmdline: list[PathString] = [
894-
find_qemu_binary(config),
894+
qemu,
895895
"-machine", machine,
896896
"-smp", str(config.qemu_smp or os.cpu_count()),
897897
"-m", f"{config.qemu_mem // 1024**2}M",
@@ -914,7 +914,7 @@ def run_qemu(args: Args, config: Config) -> None:
914914

915915
if config.qemu_kvm != ConfigFeature.disabled and have_kvm and config.architecture.can_kvm():
916916
accel = "kvm"
917-
if qemu_version(config) >= QEMU_KVM_DEVICE_VERSION:
917+
if qemu_version(config, qemu) >= QEMU_KVM_DEVICE_VERSION:
918918
index = list(qemu_device_fds.keys()).index(QemuDeviceNode.kvm)
919919
cmdline += ["--add-fd", f"fd={SD_LISTEN_FDS_START + index},set=1,opaque=/dev/kvm"]
920920
accel += ",device=/dev/fdset/1"
@@ -967,7 +967,7 @@ def run_qemu(args: Args, config: Config) -> None:
967967
with contextlib.ExitStack() as stack:
968968
if firmware.is_uefi():
969969
assert ovmf
970-
ovmf_vars, ovmf_vars_format = finalize_firmware_variables(config, ovmf, stack)
970+
ovmf_vars, ovmf_vars_format = finalize_firmware_variables(config, qemu, ovmf, stack)
971971

972972
cmdline += ["-drive", f"file={ovmf_vars},if=pflash,format={ovmf_vars_format}"]
973973
if firmware == QemuFirmware.uefi_secure_boot:
@@ -1215,7 +1215,7 @@ def add_virtiofs_mount(
12151215
env=os.environ | config.environment,
12161216
log=False,
12171217
foreground=True,
1218-
sandbox=config.sandbox(binary=None, network=True, devices=True, relaxed=True),
1218+
sandbox=config.sandbox(binary=qemu, network=True, devices=True, relaxed=True),
12191219
scope=scope_cmd(
12201220
name=name,
12211221
description=f"mkosi Virtual Machine {name}",

mkosi/run.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,31 +59,31 @@ def uncaught_exception_handler(exit: Callable[[int], NoReturn] = sys.exit) -> It
5959
try:
6060
yield
6161
except SystemExit as e:
62+
rc = e.code if isinstance(e.code, int) else 1
63+
6264
if ARG_DEBUG.get():
6365
sys.excepthook(*ensure_exc_info())
64-
65-
rc = e.code if isinstance(e.code, int) else 1
6666
except KeyboardInterrupt:
67+
rc = 1
68+
6769
if ARG_DEBUG.get():
6870
sys.excepthook(*ensure_exc_info())
6971
else:
7072
logging.error("Interrupted")
71-
72-
rc = 1
7373
except subprocess.CalledProcessError as e:
74+
# We always log when subprocess.CalledProcessError is raised, so we don't log again here.
75+
rc = e.returncode
76+
7477
# Failures from qemu, ssh and systemd-nspawn are expected and we won't log stacktraces for those.
7578
# Failures from self come from the forks we spawn to build images in a user namespace. We've already done all
7679
# the logging for those failures so we don't log stacktraces for those either.
7780
if (
7881
ARG_DEBUG.get() and
7982
e.cmd and
80-
e.cmd[0] not in ("self", "ssh", "systemd-nspawn") and
81-
not e.cmd[0].startswith("qemu")
83+
str(e.cmd[0]) not in ("self", "ssh", "systemd-nspawn") and
84+
"qemu-system" not in str(e.cmd[0])
8285
):
8386
sys.excepthook(*ensure_exc_info())
84-
85-
# We always log when subprocess.CalledProcessError is raised, so we don't log again here.
86-
rc = e.returncode
8787
except BaseException:
8888
sys.excepthook(*ensure_exc_info())
8989
rc = 1

0 commit comments

Comments
 (0)