前言
本文主要讨论使用QEMU及virt-manager启动本地安装的操作系统的方法
为了测试开源软件在龙芯架构上的适配情况,笔者在最近将自己所使用的虚拟机由VirtualBox切换到了QEMU,这才发现基于QEMU的虚拟机工具竟然如此强大,具有高度的可定制性。
笔者用QEMU及virt-manager实现了将本地安装的操作系统作为虚拟机启动的功能,在某些情况下可以有效避免多系统切换的重启的需要。此外,直接读写磁盘快设备相比于使用虚拟机的镜像文件还具有更小的性能开销,在某些情况下也有一定的实际意义。
笔者利用反复操作的黑魔法,在USB的移动硬盘的同一个Btrfs分区上塞下了Ubuntu 23.04、Linux Mint 21、openSUSE Tumbleweed、CachyOS、Arch Linux等多个小白鼠测试系统,并实现了在本地Arch Linux下使用QEMU和virt-manager启动这些系统的功能。
准备
假设读者已经完成了本地系统的安装。
安装QEMU及virt-manager
在Arch Linux下,可以直接使用pacman
安装:
sudo pacman -S qemu-full virt-manager
配置虚拟机
virt-manager
选择“导入现有磁盘映像” | 选择“本地浏览” |
打开virt-manager程序,选择创建新的虚拟机
-导入现有磁盘映像
,在请提供现有存储路径
中选择浏览
-本地浏览
,在/dev
目录下,找到安装有本地系统的设备,例如/dev/sda
(注意一般需要选择整个磁盘块设备而非某个具体分区),选择打开
,然后选择完成
。后面按照正常的虚拟机配置流程操作即可。
virt-manager会自动处理块设备的使用权限问题,因此不需要sudo
。之后可以正常点击启动进入系统。本地是否挂载有该设备的分区对虚拟机的启动没有影响,但仍建议在启动虚拟机时将本地系统的分区卸载。对于宿主机与虚拟机同时挂载同一设备的操作可能会出现什么问题,笔者的答案正如强基计划的教务一样:暂不能给你明确的答复,这个需要你自己衡量,每个人承担自己的风险。
- 经笔者测试,如果宿主机在虚拟机使用时将虚拟机系统盘挂载为可读写模式,几乎一定会损坏文件系统,但是,某些分区可以很容易地被
fsck
修复,不过仍然不能保证数据的完整性。
QEMU
如果不使用virt-manager,可以直接使用QEMU启动虚拟机,但是读取磁盘块设备需要root权限,因此需要以sudo
执行命令,例如:
sudo qemu-system-x86_64 \
-cpu host \
-enable-kvm \
-m 5G \
-smp 8 \
-vga qxl \
-device virtio-serial-pci \
-net nic -net user \
-device nec-usb-xhci,id=xhci,addr=0x1b \
-device usb-tablet,id=tablet,bus=xhci.0,port=1 \
-device usb-kbd,id=keyboard,bus=xhci.0,port=2 \
-bios /usr/share/ovmf/x64/OVMF.4m.fd \
-hda /dev/sda
由于用sudo
运行QEMU存在权限风险,笔者更推荐使用virt-manager。
内核模块需要
笔者在实际操作中发现,本地环境下所有小白鼠系统均能正常启动,但是在虚拟机中,基于Ubuntu的几个发行版与openSUSE都可以正常启动,而基于Arch Linux的几个发行版则无法找到对应UUID的分区挂载。这是因为Arch Linux的mkinitcpio
在默认情况下没有将virtio
的几个内核模块加载到initramfs
中,因此在虚拟机中无法识别对应的磁盘设备。
为了解决这一问题,需要编辑/etc/mkinitcpio.conf
文件,将MODULES
一行修改为:
MODULES=(virtio virtio_blk virtio_pci virtio_net)
如果还要在USB设备中启动,则还需要添加usbhid
和xhci_hcd
:
MODULES="virtio virtio_blk virtio_pci virtio_net usbhid xhci_hcd"
然后执行mkinitcpio -P
,以生成新的initramfs
。
混乱邪恶的Linux on NTFS启动支持
笔者在上一篇博客中分享了将Linux安装在NTFS分区下的方法。在本地启动时,即使在/etc/mkinitcpio.conf
中没有添加ntfs3
模块,也不会出现问题,但如果想要在QEMU中启动这个系统,则一定要在/etc/mkinitcpio.conf
中额外添加ntfs3
模块,否则无法启动。
MODULES=(ntfs3 virtio virtio_blk virtio_pci virtio_net usbhid xhci_hcd)
展示
感谢Loongarch带我进入了QEMU的世界!