pve直通设备的虚拟机关机后pve重新驱动

背景

在 PVE (Proxmox VE) 中使用 PCI 直通(Passthrough)时,设备会被绑定到 vfio-pci 驱动以供虚拟机独占使用。但当虚拟机停止后,宿主机无法再使用该设备。

本文以 ASMedia ASM1061 SATA 控制器 为例,演示如何在 vfio-pciahci 之间手动切换,并通过 hookscript 实现自动化。

一、查看当前驱动绑定

lspci -k -s 06:00.0

输出示例:

06:00.0 SATA controller: ASMedia Technology Inc. ASM1061/ASM1062 Serial ATA Controller (rev 02)
        Subsystem: ASUSTeK Computer Inc. ASM1061/ASM1062 Serial ATA Controller
        Kernel driver in use: vfio-pci
        Kernel modules: ahci

Kernel driver in use 显示当前使用的驱动,Kernel modules 列出该设备可用的驱动模块。

二、手动切换驱动

2.1 解绑 vfio-pci

有两种方式,效果相同:

# 方式一:通过设备路径解绑
echo 0000:06:00.0 > /sys/bus/pci/devices/0000:06:00.0/driver/unbind

# 方式二:通过驱动路径解绑
echo 0000:06:00.0 > /sys/bus/pci/drivers/vfio-pci/unbind

验证解绑成功——Kernel driver in use 行消失:

lspci -k -s 06:00.0

06:00.0 SATA controller: ASMedia Technology Inc. ASM1061/ASM1062 Serial ATA Controller (rev 02)
        Subsystem: ASUSTeK Computer Inc. ASM1061/ASM1062 Serial ATA Controller
        Kernel modules: ahci

2.2 绑定到 ahci

echo 0000:06:00.0 > /sys/bus/pci/drivers/ahci/bind

验证绑定成功:

lspci -k -s 06:00.0

06:00.0 SATA controller: ASMedia Technology Inc. ASM1061/ASM1062 Serial ATA Controller (rev 02)
        Subsystem: ASUSTeK Computer Inc. ASM1061/ASM1062 Serial ATA Controller
        Kernel driver in use: ahci
        Kernel modules: ahci

至此,宿主机已重新接管该 SATA 控制器。

三、使用 Hookscript 自动切换

手动切换太麻烦?PVE 支持为虚拟机绑定 hookscript,在 VM 启动/停止时自动执行脚本。

3.1 创建脚本

PVE 的 hookscript 存放在 /var/lib/vz/snippets/ 目录下,支持 Bash、Perl、Python 等格式。

nano /var/lib/vz/snippets/bind-ahci.sh

写入以下内容(将 100 替换为你的虚拟机 ID):

#!/bin/bash
# PVE hookscript: ASM1061 驱动自动切换
# 用法:虚拟机启动前绑定 vfio-pci,停止后归还 ahci

vmid=$1
phase=$2

# 只处理指定虚拟机
if [ "$vmid" != "100" ]; then
    exit 0
fi

case "$phase" in
    pre-start)
        # 启动前:从宿主机收回设备,交给虚拟机
        echo 0000:06:00.0 > /sys/bus/pci/drivers/ahci/unbind 2>/dev/null
        echo 0000:06:00.0 > /sys/bus/pci/drivers/vfio-pci/bind 2>/dev/null
        logger "Hook: ASM1061 → vfio-pci (VM $vmid starting)"
        ;;
    post-stop)
        # 停止后:从虚拟机归还设备给宿主机
        echo 0000:06:00.0 > /sys/bus/pci/drivers/vfio-pci/unbind 2>/dev/null
        echo 0000:06:00.0 > /sys/bus/pci/drivers/ahci/bind 2>/dev/null
        logger "Hook: ASM1061 → ahci (VM $vmid stopped)"
        ;;
esac

exit 0

3.2 赋予执行权限

chmod +x /var/lib/vz/snippets/bind-ahci.sh

3.3 绑定到虚拟机

qm set 100 --hookscript local:snippets/bind-ahci.sh

说明local:snippets/bind-ahci.sh 是 PVE 存储卷路径语法,local 对应 /var/lib/vz。如果你的环境没有 local 存储,可通过 pvesm status 确认,或在 /etc/pve/storage.cfg 中添加。

3.4 验证配置

qm config 100 | grep hookscript

输出应为:

hookscript: local:snippets/bind-ahci.sh

四、移除 Hookscript

不再需要自动切换时,按顺序清理:

# 1. 取消虚拟机的 hookscript 绑定
qm set 100 --delete hookscript

# 2. 验证已移除(输出为空即成功)
qm config 100 | grep hookscript

# 3. 可选:删除脚本文件
rm /var/lib/vz/snippets/bind-ahci.sh

注意:先取消绑定再删除脚本,避免 PVE 找不到脚本而报错。

上一篇 在Proxmox VE 7.1 中开启vGPU_unlock,实现显卡虚拟化 (自定义vgpu参数)
下一篇 linux清除终端历史命令记录