在 QEMU 中运行 Debian 5.10,我使用 9pfs 文件系统来访问存储在主机系统上的文件,因为 Debian 带有内置支持,并且 QEMU 本身支持该文件系统。
启动时,我可以使用以下命令轻松挂载系统
sudo mount -t 9p -o trans=virtio,msize=131072 hostfs /mnt/host
工作正常。对于那些不熟悉其工作原理的人:您需要告诉 QEMUhostfs
实际含义,例如通过添加类似
-virtfs local,path="$HOME/Documents",mount_tag=hostfs,security_model=mapped-file
这样,我的 Documents 文件夹就会公开,hostfs
并且一旦安装,便可在 Debian 客户系统中完全使用。
由于我一直想访问主机系统,因此我修改/etc/fstab
并添加了以下行:
hostfs /mnt/host 9p defaults,trans=virtio,msize=131072 0 0
当我运行时sudo mount -a
,它也会按预期工作。
systemd
但是,当我重新启动 Debian 客户系统时,尝试挂载该条目时启动失败。它会动态生成一个mnt-host.mount
,当我尝试挂载它时,我得到
mount: /mnt/host: bad option
mnt-host.mount: Mount process existed, code=exited, status=32/n/a
这会导致启动过程停止。我必须按 CTRL+D 才能继续启动。
疯狂的是,一旦启动完成,/mnt/host
已安装!
这是因为显然systemd
正在尝试再次安装它。稍后在日志中,有另一个mnt-host.mount
作业正在执行,这次正如预期的那样成功了。
我有点不明白为什么systemd
要尝试挂载该条目两次,以及为什么尽管使用了两次相同的选项,第一次尝试却从未成功。
答案1
首先,向 Tom Yan 表示敬意,他在这个问题的评论中建议:
也许存在某种竞争。作为一种解决方法,请尝试将
x-systemd.automount
(作为选项)添加到 fstab 条目中。
虽然这不能解释问题的根源,但它确实解决了问题。使用此选项,系统不会在启动时立即尝试挂载共享(因此启动成功),但是它会在任何进程尝试访问挂载目标目录时立即挂载它(因此您永远不必自己挂载它,只要您尝试使用它,它就会在那里)。
尽管这个解决方案非常好,但我通常不会放弃解决问题,直到我完全了解发生了什么,所以我不断挖掘并找到了问题的真正原因。
当说 时bad option
,这实际上是指trans=virtio
挂载请求中的 。要使用这种传输方式,需要一个内核模块:9pnet_virtio.ko
。此时systemd
正在处理/etc/fstab
,它还无法访问/lib/modules
,因此无法加载该模块,这就是挂载失败的原因。显然,在稍后的某个时间,其他一些启动脚本会触发另一个启动脚本mount -a
(直接或间接通过重新启动systemd
服务),当这种情况发生时/lib/modules
可用,因此挂载现在成功。
因此,这个问题的真正解决方案如下:
编辑
/etc/initramfs-tools/modules
并添加一行内容9pnet_virtio
执行
sudo update-initramfs -u
系统将重建 initramfs 并确保包含此特定模块,以修复启动错误。
还有其他方法可以修复它,例如,可以确保在共享/lib/modules
完全可用之前不安装共享,但是,如果/lib/modules
由于某种原因无法安装包含共享的设备,所有这些解决方案都将失败。通过将模块放到 initramfs 上,我现在甚至可以从恢复控制台访问此共享(我只需要将其安装在其他地方),这可以帮助我修复损坏的系统,因为这样我就可以访问我可能需要修复的文件,方法是将它们放在我的主机系统上,在我看来这非常巧妙。