virtio驱动缺失导致启动失败的根因是virtio_blk和virtio_net未进入initramfs:先用grep -i virtio /boot/config-$(uname -r)确认内核支持(config_virtio_blk/net为m),再用lsinitrd或lsinitramfs检查initramfs是否包含virtio_blk.ko、virtio_pci.ko、virtio_net.ko,若缺失则需按发行版修复initramfs并更新grub。

迁移后虚拟机直接蓝屏或无法启动,基本就是 virtio_blk 和 virtio_net 驱动没进 initramfs —— 不是内核不支持,而是启动早期根本没加载进去。
怎么快速确认是不是 VirtIO 驱动缺失导致的启动失败
在源系统(迁移前的物理机或旧虚拟机)上执行以下检查,别等迁完再救火:
- 运行
grep -i virtio /boot/config-$(uname -r),确认CONFIG_VIRTIO_BLK和CONFIG_VIRTIO_NET至少是m(模块),不是n或完全没出现 - 如果值为
m,必须进一步查 initramfs:
— CentOS/RHEL 7+:用lsinitrd /boot/initramfs-$(uname -r).img | grep -i "virtio"
— Ubuntu/Debian:用lsinitramfs /boot/initrd.img-$(uname -r) | grep -i "virtio" - 若输出为空,或只看到
virtio.ko但没有virtio_blk.ko、virtio_pci.ko、virtio_net.ko,说明驱动虽存在,但没打进启动镜像里 —— 这就是蓝屏的根因
不同发行版修复 initramfs 的实操命令
修复不是重装内核,而是把已有的 VirtIO 模块强制塞进 initramfs。注意路径和命令因发行版差异极大,错一个参数就白干:
- CentOS/RHEL 7/8:
dracut -f -v --regenerate-all(推荐)
或手动指定模块:dracut -f -v --force --include /lib/modules/$(uname -r)/kernel/drivers/virtio/ virtio - CentOS/RHEL 6:
mkinitrd /boot/initramfs-$(uname -r).img $(uname -r) -f --with=virtio_blk --with=virtio_pci --with=virtio_net - Ubuntu/Debian:
先往配置里追加模块:echo -e "virtio_blk\nvirtio_pci\nvirtio_net" >> /etc/initramfs-tools/modules
再重建:update-initramfs -u -k all(-k all很关键,避免只更新当前运行内核) - 注意:不要用
mkinitrd在新版 Ubuntu 上,它早已被弃用,会静默失败
为什么有些系统明明有 VirtIO 驱动还是蓝屏
常见但容易被忽略的三个硬坑:
-
initramfs重建后没更新 GRUB 配置:某些老系统(如 CentOS 6)不会自动同步新镜像路径,需手动检查/boot/grub/grub.conf或/boot/grub2/grub.cfg中initrd行是否指向刚生成的文件名 - 多内核共存时修错了版本:
uname -r显示的是当前运行内核,但迁移目标可能用的是另一个未启动过的内核(比如带.el7.x86_64后缀的旧版),得挨个检查并修复所有待用内核的 initramfs - 镜像打包时没包含
/lib/firmware下的固件:部分 VirtIO 设备(如virtio-pci)依赖virtio_pci.ko+ 对应固件,缺一不可;可查ls /lib/firmware | grep -i virtio,空则需补全
最麻烦的不是驱动没装,而是驱动装了但没进 initramfs;最隐蔽的不是命令没跑,而是跑对了内核却没更新 GRUB 引导项 —— 迁移前务必在源系统里验证 lsinitrd 输出含完整 VirtIO 模块链,并且重启过一次确认能进系统。











