
PVE通过Hookscript脚本实现开关虚拟机切换pcie设备绑定状态
🔧 一、创建Hookscript脚本
脚本位置
将脚本存放在PVE可识别的存储目录中(如local
存储的snippets
子目录):bash
# 创建存储目录(若不存在) mkdir -p /var/lib/vz/snippets/ # 创建脚本文件(示例命名为vm-hook-nvme.sh) nano /var/lib/vz/snippets/vm-hook-nvme.sh
脚本内容(参考增强版)1
bash
#!/bin/bash DEV="0000:05:00.0" # 替换为实际PCI设备ID(通过lspci查看) HOST_DRIVER="nvme" # 宿主机驱动名(用lspci -k确认) VFIO_DRIVER="vfio-pci" STATUS_FILE="/tmp/vm_$1_running" # 异常状态恢复:若设备残留VFIO绑定且无运行标记,则强制绑回宿主机 CURRENT_DRIVER=$(lspci -n -s $DEV | awk -F': ' '{print $2}' | cut -d' ' -f1) if [ "$CURRENT_DRIVER" == "$VFIO_DRIVER" ] && [ ! -f "$STATUS_FILE" ]; then echo "$DEV" > /sys/bus/pci/drivers/$VFIO_DRIVER/unbind 2>/dev/null echo "$DEV" > /sys/bus/pci/drivers/$HOST_DRIVER/bind 2>/dev/null fi case "$2" in pre-start) touch "$STATUS_FILE" echo "$DEV" > /sys/bus/pci/drivers/$HOST_DRIVER/unbind || echo "解绑宿主机驱动失败" echo "$DEV" > /sys/bus/pci/drivers/$VFIO_DRIVER/bind || echo "绑定VFIO失败" ;; post-stop) echo "$DEV" > /sys/bus/pci/drivers/$VFIO_DRIVER/unbind || echo "解绑VFIO失败" echo "$DEV" > /sys/bus/pci/drivers/$HOST_DRIVER/bind || echo "绑回宿主机失败" rm -f "$STATUS_FILE" ;; esac exit 0
⚠️ 注意点:
DEV
:替换为设备PCI ID(如0000:0B:00.0
)HOST_DRIVER
:通过lspci -k -s <PCI-ID>
查询实际驱动名(可能为nvme
、ahci
等)
赋予执行权限
bash
chmod +x /var/lib/vz/snippets/vm-hook-nvme.sh
⚙️ 二、配置虚拟机Hookscript属性
通过CLI绑定脚本到虚拟机
将脚本关联到目标虚拟机(假设VMID为100
):bash
qm set 100 -hookscript local:snippets/vm-hook-nvme.sh
local:snippets/
: 指定PVE的local
存储下snippets
目录1成功后输出:
update VM 100: -hookscript local:snippets/vm-hook-nvme.sh
验证配置
检查虚拟机配置文件/etc/pve/qemu-server/100.conf
,应包含:conf
hookscript: local:snippets/vm-hook-nvme.sh
🔍 三、测试与验证
启动虚拟机(触发
pre-start
钩子)bash
qm start 100 # 检查设备驱动状态 lspci -k -s 05:00.0 | grep driver # 应显示vfio-pci
停止虚拟机(触发
post-stop
钩子)bash
qm stop 100 # 检查设备是否回归宿主机 lspci -k -s 05:00.0 | grep driver # 应显示nvme(或原驱动)
⚠️ 四、关键注意事项
权限问题
脚本需以root权限执行,PVE自动以root调用钩子,无需额外配置。
驱动兼容性
宿主机驱动名必须准确(通过
lspci -k -s <PCI-ID>
确认)1。
设备冲突
若设备已被宿主机占用(如挂载文件系统),
unbind
操作会失败。需确保设备未被使用:bash
umount /dev/nvme0n1p1 # 示例:卸载分区
调试日志
可追加日志记录到文件(调试时在脚本开头添加):
bash
exec &>> /var/log/vm-hook.log echo "[$(date)] VM $1: $2 phase executed"
📜 五、生命周期钩子说明
PVE支持的钩子阶段与脚本调用逻辑:
此配置实现了设备直通的自动化管理,覆盖正常开关机及异常恢复场景 ✅。
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 达达
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果