gpu: nvidia install drops VFIO autoload; GPU flows self-repair stale vfio.conf

The nvidia driver installer now writes only `nvidia` and `nvidia_uvm` into `/etc/modules-load.d/nvidia-vfio.conf`, leaving the vfio-pci modules for `switch_gpu_mode.sh` to add and remove when the user explicitly transitions between LXC and VM mode. A host with residual `/etc/modprobe.d/vfio.conf` entries from an earlier VM passthrough setup no longer has vfio-pci racing nvidia at boot and capturing the GPU by ID.

All three GPU-facing entry points also detect a stale `vfio.conf` entry whose vid:did belongs to a GPU currently bound to a non-vfio driver, and offer to clean it in place. `nvidia_installer.sh` runs the check as a pre-flight before install. `switch_gpu_mode.sh` presents an interactive dialog and rebuilds initramfs. `switch_gpu_mode_direct.sh` performs the same cleanup transparently for the Monitor web variant. Once cleaned, "Add GPU to LXC", the driver install and Switch Mode all proceed without any manual intervention.

The two supporting helpers `_pci_driver_of` and `_clean_vfio_conf_ids` previously local to `add_gpu_lxc.sh` move to `scripts/global/pci_passthrough_helpers.sh`, so every GPU-related script resolves them from a single source without duplication.
This commit is contained in:
MacRimi
2026-08-17 12:05:40 +02:00
parent 11e030b9de
commit b5476c75fa
5 changed files with 199 additions and 62 deletions
-57
View File
@@ -930,63 +930,6 @@ _remove_vfio_modules() {
sed -i '/^vfio_virqfd$/d' "$modules_file"
}
# Return the kernel driver bound to a PCI slot, or empty if none.
_pci_driver_of() {
local pci="$1"
[[ -z "$pci" ]] && return
local pci_full="$pci"
[[ "$pci_full" != 0000:* ]] && pci_full="0000:${pci_full}"
local link="/sys/bus/pci/devices/${pci_full}/driver"
[[ -L "$link" ]] && basename "$(readlink "$link")"
}
# Remove one or more `vid:did` tokens from the `ids=` list in
# /etc/modprobe.d/vfio.conf. Preserves any remaining tokens and any
# trailing options on the line. Returns 0 when the file changes.
_clean_vfio_conf_ids() {
local vfio_conf="/etc/modprobe.d/vfio.conf"
[[ ! -f "$vfio_conf" ]] && return 1
local -a targets=("$@")
[[ ${#targets[@]} -eq 0 ]] && return 1
local before after tmp
before=$(cat "$vfio_conf")
tmp=$(mktemp)
awk -v targets="${targets[*]}" '
BEGIN {
n = split(targets, a, " ")
for (i = 1; i <= n; i++) drop[a[i]] = 1
}
/^options vfio-pci ids=/ {
# Split "options vfio-pci ids=A,B,C key=val …" preserving order.
pre = ""; ids = ""; post = ""
match($0, /ids=[^ \t]+/)
pre = substr($0, 1, RSTART - 1)
idsp = substr($0, RSTART, RLENGTH)
post = substr($0, RSTART + RLENGTH)
sub(/^ids=/, "", idsp)
m = split(idsp, tok, ",")
out = ""
for (i = 1; i <= m; i++) {
t = tok[i]
if (!(t in drop)) {
out = (out == "" ? t : out "," t)
}
}
if (out == "") next # drop the whole line if no ids left
print pre "ids=" out post
next
}
{ print }
' "$vfio_conf" > "$tmp"
after=$(cat "$tmp")
if [[ "$before" == "$after" ]]; then
rm -f "$tmp"
return 1
fi
mv "$tmp" "$vfio_conf"
return 0
}
# Return live VFIO state for each selected GPU:
# sets ACTIVE_VFIO_* arrays for GPUs whose PCI slot is currently
# bound to vfio-pci (real VFIO passthrough right now).