Docs / Troubleshooting

文档 / 故障排查

Troubleshooting

故障排查

The failures people actually hit, what causes them, and what to do. When in doubt, re-run with --debug first -- it usually names the problem outright.

pip refuses to install: externally-managed-environment

pip 拒绝安装:externally-managed-environment

Debian and Ubuntu mark the system Python as managed by the distribution (PEP 668), so pip install into it is blocked. This is the distribution's rule, not AnyVM's. Use pipx: Debian 和 Ubuntu 把系统 Python 标记为由发行版管理(PEP 668), 所以往里面 pip install 会被拦住。这是发行版的规矩,不是 AnyVM 的。 改用 pipx:

$ sudo apt-get install -y pipx
$ pipx install anyvm.py
$ pipx ensurepath   # first time only, then reopen the shell

Or a virtualenv, or just run the single file directly:

或者用虚拟环境,再或者直接跑那个单文件:

$ curl -O https://raw.githubusercontent.com/anyvm-org/anyvm/main/anyvm.py
$ python3 anyvm.py --os freebsd

The guest needs a newer QEMU than my distro ships

这个系统需要比发行版更新的 QEMU

Several guest and architecture combinations do not run on QEMU 8.2, which is what current LTS distributions ship. On a Linux x86_64 host AnyVM handles this itself: it detects the too-old system QEMU and downloads a pinned QEMU 10.2.3 for exactly those cases -- Ubuntu on riscv64 26.04, s390x and ppc64le 22.04, and OpenEuler on loongarch64. Nothing to configure. 有几个系统和架构的组合在 QEMU 8.2 上跑不起来,而目前各家 LTS 发行版 自带的正是这个版本。在 Linux x86_64 宿主上 AnyVM 自己会处理:检测到系统 QEMU 太旧,就为这些特定组合下载固定版本的 QEMU 10.2.3 —— 具体是 Ubuntu 的 riscv64 26.04、s390x 和 ppc64le 22.04,以及 OpenEuler 的 loongarch64。你不用配置什么。

On other hosts you need a newer QEMU yourself. The full list of which combination needs what is in guest notes. 其他宿主上就得你自己装新版 QEMU。哪个组合需要什么,完整清单在 系统说明里。

The boot times out and gets killed

启动超时被杀掉了

AnyVM kills QEMU and retries once when a guest does not come up in time. The default window is 600 seconds, already raised to 1200 for OpenBSD on aarch64 and to 1800 whenever no hardware acceleration is available. If you are on a slow host or an emulated architecture, give it more: 虚拟机没能按时起来时,AnyVM 会杀掉 QEMU 并重试一次。默认窗口是 600 秒,OpenBSD aarch64 已经提到 1200 秒,没有硬件加速时提到 1800 秒。如果你的 机器慢,或者跑的是模拟架构,就再给它多一点:

$ anyvm --os solaris --boot-timeout-sec 2400 --debug

An explicit value always overrides the automatic ones. If the guest is genuinely stuck rather than slow, --debug plus --serial will show you where it stopped. 你写死的值永远盖过自动值。如果虚拟机不是慢,而是真的卡住了, --debug 配上 --serial 能让你看到它停在哪。

Everything is slow

整体都很慢

Check whether you are on TCG. Any architecture that is not your host's runs under software emulation, which is roughly 10-50x slower than hardware acceleration -- that is inherent to emulating a foreign CPU, not something to tune away. 先看是不是在跑 TCG。只要不是宿主自己的架构,都得靠软件模拟,比 硬件加速慢 10 到 50 倍 —— 这是模拟异构 CPU 的固有代价,不是调参能解决的。

For a same-architecture guest that is still slow, acceleration is probably not being used. On Linux confirm /dev/kvm exists and is readable, on macOS that HVF is available, on Windows that the Windows Hypervisor Platform is on. --debug reports which accelerator was selected. 如果是同架构的虚拟机还这么慢,多半是加速没用上。Linux 上确认 /dev/kvm 存在且可读,macOS 上确认 HVF 可用,Windows 上确认 Windows Hypervisor Platform 已开启。--debug 会告诉你最后选中的是 哪个加速器。

Windows: QEMU aborts partway through boot

Windows:QEMU 启动到一半中止

Some guests hit instructions the WHPX emulator cannot decode. AnyVM already handles this in two ways: it relaunches the VM under TCG when QEMU aborts mid-boot under auto-enabled WHPX, and it skips WHPX entirely for GhostBSD, which reliably fails with failed to decode instruction f 10. 有些系统会碰到 WHPX 模拟器解不了的指令。AnyVM 已经从两方面处理: 自动启用 WHPX 后 QEMU 若在启动中途中止,就改用 TCG 重开一次;而 GhostBSD 一定会 以 failed to decode instruction f 10 失败,所以直接跳过 WHPX。

Passing --whpx explicitly disables both safety nets. To rule out the accelerator by hand, use --tcg. 显式写 --whpx 会把这两道保险都关掉。想手动排除加速器 的嫌疑,用 --tcg

Guests segfault randomly on a nested AMD host

嵌套 AMD 宿主上虚拟机随机段错误

On a nested AMD KVM host -- KVM running inside WSL2 or Hyper-V -- nested AMD-V corrupts the guest's AVX512 state, which makes modern guests such as Ubuntu 26.04 segfault at random. AnyVM detects this and drops AVX512 from -cpu host automatically. Bare-metal hosts keep the full feature set. Override with --cpu-type if you need to. 在嵌套的 AMD KVM 宿主上 —— 也就是 KVM 跑在 WSL2 或 Hyper-V 里面 —— 嵌套的 AMD-V 会破坏虚拟机的 AVX512 状态,导致 Ubuntu 26.04 这类较新的系统随机 段错误。AnyVM 检测到这种情况会自动从 -cpu host 里去掉 AVX512。裸机 宿主保留完整特性。需要的话用 --cpu-type 覆盖。

NFS fails on a Linux host: port 111 is already in use

Linux 宿主上 NFS 失败:111 端口已被占用

OpenBSD, NetBSD and DragonFly BSD guests are NFSv3-only, so they reach the bundled server through its portmapper on port 111. On Windows and macOS hosts that port is free and unprivileged. On Linux it is usually owned by the system rpcbind, or restricted to root. OpenBSD、NetBSD、DragonFlyBSD 只支持 NFSv3,所以要通过 111 端口上的 portmapper 才能连到自带的服务器。在 Windows 和 macOS 上这个端口是空的,也不需要 特权。在 Linux 上它通常被系统的 rpcbind 占着,或者只有 root 能用。

Use the host's kernel NFS server for those three guests on Linux:

在 Linux 上,这三个系统改用宿主的内核 NFS 服务器:

$ anyvm --os openbsd --sync sys-nfs -v "$PWD:/data"

There is deliberately no automatic fallback between nfs and sys-nfs -- silently switching backends would hide which one you are actually running. nfssys-nfs 之间故意不做自动切换 —— 悄悄换后端会让你搞不清自己实际在用哪个。

The guest wedges when I share a directory

一共享目录,虚拟机就卡死

Most likely NetBSD on sparc64. The QEMU sun4u machine boots only off the CMD646 PCI IDE controller, whose TCG emulation loses interrupts under sustained concurrent network and disk DMA -- which is exactly what a live sshfs or nfs mount produces. That is why -v defaults to scp there. If you overrode --sync, put it back. 多半是 sparc64 上的 NetBSD。QEMU 的 sun4u 机器只能从 CMD646 这块 PCI IDE 控制器启动,而它的 TCG 模拟在网络和磁盘 DMA 持续并发时会丢中断 —— 实时的 sshfsnfs 挂载制造的正是这种压力。所以那里的 -v 默认走 scp。你要是改过 --sync,改回去。

More generally: if a live mount destabilises a guest, a one-shot rsync or scp copies the data in without holding a connection open for the whole session. 更一般地说:只要实时挂载会让某个虚拟机不稳定,就改用一次性的 rsyncscp 把数据拷进去 —— 不用整个会话都挂着连接。

The VNC web UI is not on port 6080

VNC 网页控制台不在 6080 端口

It auto-increments when the port is taken -- 6081, 6082 and so on. The actual URL is printed at startup. --vnc off disables the web UI entirely if you do not want it. 端口被占就自动往后顺延 —— 6081、6082 这样。实际地址在启动时会打印 出来。不想要的话,--vnc off 可以把网页控制台整个关掉。

Downloads fail behind a corporate proxy

在公司代理后面下载失败

AnyVM reads http_proxy, https_proxy and all_proxy from the environment (upper case too) and downloads images and tools through them. Both HTTP proxies and SOCKS5 are supported natively: AnyVM 会从环境变量里读 http_proxyhttps_proxyall_proxy(大写形式也认),并通过它们 下载镜像和工具。HTTP 代理和 SOCKS5 都原生支持:

no_proxy is honoured. SOCKS4 is not supported. no_proxy 会被遵守。SOCKS4 不支持。

Plan 9 boots but ignores -v

Plan 9 能启动,但 -v 没反应

Expected on a Windows or macOS host. Plan 9's sync backend is 9P: the host mounts the guest's exportfs share through the Linux kernel v9fs client (mount -t 9p, needs root or sudo), so it only works from a Linux host. Everything else about the guest -- booting, running commands -- works everywhere; only directory sync is skipped. 在 Windows 或 macOS 宿主上这是预期行为。Plan 9 的同步后端是 9P: 由宿主通过 Linux 内核的 v9fs 客户端去挂载虚拟机的 exportfs 共享 (mount -t 9p,需要 root 或 sudo),所以只有 Linux 宿主能用。这个 系统的其他部分 —— 启动、跑命令 —— 在哪都正常,只是跳过了目录共享。

Filing a bug

提交问题

Issues go to anyvm-org/anyvm. Include the full command, the host OS and architecture, your QEMU version, and the output with --debug. If the guest boots but misbehaves afterwards, the serial log is the useful part: issue 提到 anyvm-org/anyvm。 请附上完整命令、宿主系统和架构、QEMU 版本,以及加了 --debug 的输出。 如果虚拟机能起来但之后行为异常,串口日志才是有用的那部分:

$ anyvm --os netbsd --arch sparc64 --debug --serial 7000

If the problem is in the image rather than the launcher -- a package missing, a service not starting -- the builder repository for that guest is the better place. Guest notes links each one. 如果问题出在镜像而不是启动器 —— 比如少了某个包、某个服务没起来 —— 那更适合去对应系统的 builder 仓库提。系统说明 里有每一个的链接。