改完 /etc/libvirt/qemu/*.xml 没用?飞牛 NAS 虚拟机配置热更新实战
改完 /etc/libvirt/qemu/*.xml 没用?飞牛 NAS 虚拟机配置热更新实战
折腾环境:FnOS / libvirt + QEMU · 2026-09-02
最近在飞牛 NAS 里调虚拟机配置,改完 /etc/libvirt/qemu/*.xml 发现停止虚拟机服务再启动也死活不生效,一度以为是文件没保存。后来才搞明白:XML 只是 libvirt 的存档,真正生效的是守护进程内存里的配置。
本文把这个坑讲清楚,并给出不重启 NAS 就能让配置生效的完整流程。
一、为什么改了 XML 不生效?
FnOS 底层是 Linux + libvirt + QEMU。/etc/libvirt/qemu/ 下的 XML 是持久化存档,真正在跑的是 libvirtd 内存里的那份配置。
vi 改了文件 → 磁盘文件变了 → 但 libvirtd 不 care,它只在启动时把文件读进内存,之后的修改对它透明。
要让改动生效,路径只有一条:用 virsh 把文件重新载入到 libvirtd 内存。
二、正确流程(3 步搞定)
1. 看一眼当前状态
virsh list --all
输出示例:
Id Name State
------------------------
- vm-1 shut off
- vm-2 shut off
- vm-3 shut off
记下每台 VM 的状态——这决定后面怎么操作。
2. 重新载入 XML
⚠️ 很多人会这么写:
virsh define /etc/libvirt/qemu/*.xml # ❌ 报错
virsh define 一次只接受一个文件参数,通配符展开后它只认第一个,其余被当成未知选项直接报错。
✅ 正确写法:循环逐个 define
for f in /etc/libvirt/qemu/*.xml; do
echo "==> $f"
virsh define "$f"
done
注:执行前最好先关闭所有虚拟机及虚拟机服务
成功的输出形如:
==> /etc/libvirt/qemu/vm-1.xml
Domain 'vm-1' defined from /etc/libvirt/qemu/vm-1.xml
==> /etc/libvirt/qemu/vm-2.xml
Domain 'vm-2' defined from /etc/libvirt/qemu/vm-2.xml
...
全部出现 defined from ... 就 OK 了。哪台报错了就单独修那一台再 define,不影响其他。
3. 让配置真正生效
VM 状态不同,操作也不同:
| VM 状态 | 操作 |
|---|---|
| 关机 (shut off) | define 即生效,下次 virsh start 用新配置 |
| 运行中 (running) | define 只更新持久化配置,必须重启这台 VM |
(注:可以在web界面操作)重启运行中的 VM(不是重启 NAS):
virsh shutdown <vm-name> # 优雅关机(推荐)
# 或
virsh destroy <vm-name> # 强制关机,等同拔电源,会丢未保存数据
virsh start <vm-name>
三、容易踩的几个坑
① 网络配置不在这条命令里/etc/libvirt/qemu/networks/*.xml 是另一套,要单独处理:
virsh net-define /etc/libvirt/qemu/networks/default.xml
virsh net-destroy default
virsh net-start default
② define 报错一般是 XML 语法错
标签没闭合、属性写错、缺 </domain> 等常见。修一下重跑 define 那一个文件即可。
③ 只是想调 CPU/内存?不用改 XML
直接 virsh setvcpus / virsh setmem 更轻量,部分场景支持热生效。
④ 以后改配置,更稳的姿势是 virsh edit
virsh edit <vm-name>
它会调用你配置的编辑器打开 XML,保存时自动校验并 define,避免手滑写错 XML 导致全部 VM 起不来。我这次是因为已经手动改完文件了才退而求其次用 for 循环 define,下次直接 virsh edit 改更省心。
四、总结
改 XML →
virsh define让libvirtd重新载入 → 关机态 define 即生效 / 运行态需重启那台 VM → 整台 NAS 一动不动。
下次再遇到「配置改了不生效」的老毛病,先 virsh list --all 看状态,再决定走 define 路径还是直接 virsh edit。



