KVM虚拟机如何直接挂载宿主机目录作为根文件系统(rootfs)


阅读 2 次

需求场景分析

在嵌入式系统开发过程中,我们经常需要在KVM虚拟机中测试根文件系统(rootfs)。传统做法是将rootfs打包成镜像文件(如qcow2或raw格式),每次修改都需要重新打包,开发效率较低。

特别是在以下场景中尤为不便:

  • 频繁修改rootfs中的配置文件
  • 需要实时调试动态库
  • 快速验证脚本修改效果

解决方案原理

KVM/QEMU支持通过virtio-9p或Plan9协议,将宿主机目录共享给虚拟机作为rootfs。这种方式相比镜像文件有以下优势:

1. 修改实时生效,无需重新打包
2. 可以直接使用宿主机工具操作文件
3. 节省磁盘空间(无需多份镜像副本)

具体实现步骤

以Ubuntu 20.04为例,演示如何配置:

# 1. 首先确保内核支持9p文件系统
sudo modprobe 9p
sudo modprobe 9pnet_virtio

# 2. 准备宿主机共享目录
mkdir -p ~/kvm_share/rootfs
sudo chown -R nobody:nogroup ~/kvm_share/rootfs

# 3. 启动QEMU时添加共享参数
qemu-system-x86_64 \
    -enable-kvm \
    -m 2048 \
    -smp 2 \
    -drive file=vm.qcow2,if=virtio \
    -fsdev local,security_model=passthrough,id=fsdev0,path=~/kvm_share/rootfs \
    -device virtio-9p-pci,id=fs0,fsdev=fsdev0,mount_tag=hostshare \
    -net nic -net user

虚拟机内配置

进入虚拟机后,需要挂载共享目录:

# 创建挂载点
mkdir /mnt/hostshare

# 挂载9p文件系统
mount -t 9p -o trans=virtio,version=9p2000.L hostshare /mnt/hostshare

# 如果要作为根文件系统,需要修改init脚本
# 在/etc/init.d/rcS中添加:
mount --bind /mnt/hostshare /root
exec chroot /root /sbin/init

性能优化建议

对于IO密集型场景,可以调整以下参数:

-fsdev local,security_model=passthrough,cache=loose,id=fsdev0,path=~/kvm_share/rootfs

其中cache=loose可以提高性能,但会降低数据一致性保证。

常见问题解决

权限问题:确保宿主机共享目录对nobody用户可读写

启动失败:检查内核是否加载了9p相关模块

性能低下:考虑使用SSD存储或调整cache参数

替代方案比较

方案 优点 缺点
目录共享 修改实时生效,开发效率高 性能略低于原生镜像
qcow2镜像 性能好,隔离性强 修改需要重新打包
NFS挂载 跨网络可用 配置复杂,依赖网络