update gpu-switch-mode-indicator.tsx

This commit is contained in:
MacRimi
2026-04-19 12:26:52 +02:00
parent bcca760403
commit 834795d6d9
15 changed files with 1235 additions and 119 deletions

View File

@@ -28,6 +28,11 @@ NVIDIA_VID_DID=""
if [[ -f "$UTILS_FILE" ]]; then
source "$UTILS_FILE"
fi
if [[ -f "$LOCAL_SCRIPTS/global/pci_passthrough_helpers.sh" ]]; then
source "$LOCAL_SCRIPTS/global/pci_passthrough_helpers.sh"
elif [[ -f "$(cd "$(dirname "${BASH_SOURCE[0]}")"/.. && pwd)/global/pci_passthrough_helpers.sh" ]]; then
source "$(cd "$(dirname "${BASH_SOURCE[0]}")"/.. && pwd)/global/pci_passthrough_helpers.sh"
fi
if [[ -f "$LOCAL_SCRIPTS/global/gpu_hook_guard_helpers.sh" ]]; then
source "$LOCAL_SCRIPTS/global/gpu_hook_guard_helpers.sh"
elif [[ -f "$(cd "$(dirname "${BASH_SOURCE[0]}")"/.. && pwd)/global/gpu_hook_guard_helpers.sh" ]]; then
@@ -259,6 +264,67 @@ select_container() {
# ============================================================
# GPU checklist selection
# ============================================================
# ============================================================
# SR-IOV guard — refuse to pass an SR-IOV GPU to an LXC via ProxMenux.
# Although the LXC flow does not rewrite vfio.conf/blacklist (so it is
# not destructive like add_gpu_vm.sh), it blindly globs /dev/dri/card*
# and /dev/dri/renderD* without mapping each node to its BDF. With 7
# VFs the container may end up holding any/all of them, which is not
# the behavior a user asking for "one VF to this LXC" expects. Until a
# VF-aware LXC flow exists, stop and point to manual configuration —
# matching the policy used in switch_gpu_mode.sh and add_gpu_vm.sh.
# ============================================================
check_sriov_and_block_if_needed() {
declare -F _pci_sriov_role >/dev/null 2>&1 || return 0
local gpu_type pci role first_word
local -a offenders=()
for gpu_type in "${SELECTED_GPUS[@]}"; do
case "$gpu_type" in
intel) pci="$INTEL_PCI" ;;
amd) pci="$AMD_PCI" ;;
nvidia) pci="$NVIDIA_PCI" ;;
*) continue ;;
esac
[[ -n "$pci" ]] || continue
role=$(_pci_sriov_role "$pci")
first_word="${role%% *}"
case "$first_word" in
vf)
offenders+=("${pci}|vf|${role#vf }")
;;
pf-active)
offenders+=("${pci}|pf-active|${role#pf-active }")
;;
esac
done
[[ ${#offenders[@]} -eq 0 ]] && return 0
local msg entry bdf kind info
msg="\n\Zb\Z6$(translate 'SR-IOV Configuration Detected')\Zn\n\n"
for entry in "${offenders[@]}"; do
bdf="${entry%%|*}"
kind="${entry#*|}"; kind="${kind%%|*}"
info="${entry##*|}"
if [[ "$kind" == "vf" ]]; then
msg+=" • \Zb${bdf}\Zn — $(translate 'Virtual Function (parent PF:') ${info})\n"
else
msg+=" • \Zb${bdf}\Zn — $(translate 'Physical Function with') ${info} $(translate 'active VFs')\n"
fi
done
msg+="\n$(translate 'To pass SR-IOV Virtual Functions to a container, edit the LXC configuration manually via the Proxmox web interface. The Physical Function will remain bound to the native driver.')"
dialog --backtitle "ProxMenux" --colors \
--title "$(translate 'SR-IOV Configuration Detected')" \
--msgbox "$msg" 16 82
exit 0
}
select_gpus() {
local gpu_items=()
$HAS_INTEL && gpu_items+=("intel" "${INTEL_NAME:-Intel iGPU}" "off")
@@ -927,6 +993,7 @@ main() {
detect_host_gpus
select_container
select_gpus
check_sriov_and_block_if_needed
check_vfio_switch_mode
precheck_existing_lxc_gpu_config

View File

@@ -718,6 +718,48 @@ select_gpu() {
}
# ==========================================================
# SR-IOV guard — refuse to assign a Virtual Function or a Physical
# Function with active VFs. Matches the policy in switch_gpu_mode.sh:
# writing this GPU's vendor:device to /etc/modprobe.d/vfio.conf would
# let vfio-pci claim the PF at next boot and destroy the whole VF
# tree. ProxMenux does not yet manage SR-IOV lifecycle, so we stop
# before touching vfio.conf / blacklist.conf.
# ==========================================================
check_sriov_and_block_if_needed() {
declare -F _pci_sriov_role >/dev/null 2>&1 || return 0
[[ -n "$SELECTED_GPU_PCI" ]] || return 0
local role first_word detail=""
role=$(_pci_sriov_role "$SELECTED_GPU_PCI")
first_word="${role%% *}"
case "$first_word" in
vf)
local parent="${role#vf }"
detail="$(translate 'The selected device') \Zb${SELECTED_GPU_PCI}\Zn $(translate 'is an SR-IOV Virtual Function (VF). Its parent Physical Function is') \Zb${parent}\Zn."
;;
pf-active)
local n="${role#pf-active }"
detail="$(translate 'The selected device') \Zb${SELECTED_GPU_PCI}\Zn $(translate 'is a Physical Function with') \Zb${n}\Zn $(translate 'active Virtual Functions. Changing its driver binding would destroy every VF.')"
;;
*)
return 0
;;
esac
local msg
msg="\n\Zb\Z6$(translate 'SR-IOV Configuration Detected')\Zn\n\n"
msg+="${detail}\n\n"
msg+="$(translate 'To assign VFs to VMs or LXCs, edit the configuration manually via the Proxmox web interface. The Physical Function will remain bound to the native driver.')"
_pmx_msgbox "$(translate 'SR-IOV Configuration Detected')" "$msg" 16 82
[[ "$WIZARD_CALL" == "true" ]] && _set_wizard_result "cancelled"
exit 0
}
# ==========================================================
# Phase 1 — Step 4: Single-GPU warning
# ==========================================================
@@ -1922,6 +1964,7 @@ main() {
detect_host_gpus
check_iommu_enabled
select_gpu
check_sriov_and_block_if_needed
warn_single_gpu
select_vm
ensure_selected_gpu_not_already_in_target_vm

View File

@@ -624,6 +624,75 @@ select_gpus() {
read -ra SELECTED_GPU_IDX <<< "$sel"
}
# ==========================================================
# SR-IOV guard — abort mode switch when SR-IOV is active
# ==========================================================
# Intel i915-sriov-dkms and AMD MxGPU split a Physical Function (PF) into
# multiple Virtual Functions (VFs). Switching the PF's driver destroys
# every VF; switching a VF's driver affects only that VF. ProxMenux does
# not yet manage the SR-IOV lifecycle (create/destroy VFs, track per-VF
# ownership), so operating on a PF with active VFs — or on a VF itself —
# would leave the user's virtualization stack in an inconsistent state.
# We detect the situation early and hand the user back to the Proxmox
# web UI, which understands VFs as first-class PCI devices.
check_sriov_and_block_if_needed() {
declare -F _pci_sriov_role >/dev/null 2>&1 || return 0
local idx pci role first_word pf_bdf active_count
local -a vf_list=()
local -a pf_list=()
for idx in "${SELECTED_GPU_IDX[@]}"; do
pci="${ALL_GPU_PCIS[$idx]}"
role=$(_pci_sriov_role "$pci")
first_word="${role%% *}"
case "$first_word" in
vf)
pf_bdf="${role#vf }"
vf_list+=("${pci}|${pf_bdf}")
;;
pf-active)
active_count="${role#pf-active }"
pf_list+=("${pci}|${active_count}")
;;
esac
done
[[ ${#vf_list[@]} -eq 0 && ${#pf_list[@]} -eq 0 ]] && return 0
local title msg entry bdf parent cnt
title="$(translate 'SR-IOV Configuration Detected')"
msg="\n"
if [[ ${#vf_list[@]} -gt 0 ]]; then
msg+="$(translate 'The following selected device(s) are SR-IOV Virtual Functions (VFs):')\n\n"
for entry in "${vf_list[@]}"; do
bdf="${entry%%|*}"
parent="${entry#*|}"
msg+="${bdf} $(translate '(parent PF:') ${parent})\n"
done
msg+="\n"
fi
if [[ ${#pf_list[@]} -gt 0 ]]; then
msg+="$(translate 'The following selected device(s) are Physical Functions with active Virtual Functions:')\n\n"
for entry in "${pf_list[@]}"; do
bdf="${entry%%|*}"
cnt="${entry#*|}"
msg+="${bdf}${cnt} $(translate 'active VF(s)')\n"
done
msg+="\n"
fi
msg+="$(translate 'To assign VFs to VMs or LXCs, edit the configuration manually via the Proxmox web interface. The Physical Function will remain bound to the native driver.')"
dialog --backtitle "ProxMenux" \
--title "$title" \
--msgbox "$msg" 20 80
exit 0
}
collect_selected_iommu_ids() {
SELECTED_IOMMU_IDS=()
SELECTED_PCI_SLOTS=()
@@ -1164,6 +1233,7 @@ main() {
detect_host_gpus
while true; do
select_gpus
check_sriov_and_block_if_needed
select_target_mode
[[ $? -eq 2 ]] && continue
validate_vm_mode_blocked_ids

View File

@@ -507,6 +507,67 @@ find_gpu_by_slot() {
return 1
}
# ==========================================================
# SR-IOV guard — abort mode switch when SR-IOV is active
# ==========================================================
# Same policy as the interactive switch_gpu_mode.sh: refuse to operate on
# a Virtual Function or on a Physical Function that already has active
# VFs, since flipping drivers in that state collapses the VF tree and
# breaks every guest that was consuming a VF.
check_sriov_and_block_if_needed() {
declare -F _pci_sriov_role >/dev/null 2>&1 || return 0
local idx pci role first_word pf_bdf active_count
local -a vf_list=()
local -a pf_list=()
for idx in "${SELECTED_GPU_IDX[@]}"; do
pci="${ALL_GPU_PCIS[$idx]}"
role=$(_pci_sriov_role "$pci")
first_word="${role%% *}"
case "$first_word" in
vf)
pf_bdf="${role#vf }"
vf_list+=("${pci}|${pf_bdf}")
;;
pf-active)
active_count="${role#pf-active }"
pf_list+=("${pci}|${active_count}")
;;
esac
done
[[ ${#vf_list[@]} -eq 0 && ${#pf_list[@]} -eq 0 ]] && return 0
local msg entry bdf parent cnt
msg="<div style='color:#f0ad4e;font-weight:bold;margin-bottom:10px;'>$(translate 'SR-IOV Configuration Detected')</div>"
if [[ ${#vf_list[@]} -gt 0 ]]; then
msg+="<p>$(translate 'The following selected device(s) are SR-IOV Virtual Functions (VFs):')</p><ul>"
for entry in "${vf_list[@]}"; do
bdf="${entry%%|*}"
parent="${entry#*|}"
msg+="<li><code>${bdf}</code> &mdash; $(translate 'parent PF:') <code>${parent}</code></li>"
done
msg+="</ul>"
fi
if [[ ${#pf_list[@]} -gt 0 ]]; then
msg+="<p>$(translate 'The following selected device(s) are Physical Functions with active Virtual Functions:')</p><ul>"
for entry in "${pf_list[@]}"; do
bdf="${entry%%|*}"
cnt="${entry#*|}"
msg+="<li><code>${bdf}</code> &mdash; ${cnt} $(translate 'active VF(s)')</li>"
done
msg+="</ul>"
fi
msg+="<p>$(translate 'To assign VFs to VMs or LXCs, edit the configuration manually via the Proxmox web interface. The Physical Function will remain bound to the native driver.')</p>"
hybrid_msgbox "$(translate 'SR-IOV Configuration Detected')" "$msg"
return 1
}
validate_vm_mode_blocked_ids() {
[[ "$TARGET_MODE" != "vm" ]] && return 0
@@ -1147,6 +1208,12 @@ main() {
exit 1
fi
# SR-IOV guard: refuse to toggle the driver on a VF or on a PF with
# active VFs. Manual handling via Proxmox web UI is required.
if ! check_sriov_and_block_if_needed; then
exit 1
fi
# Validate if GPU is blocked for VM mode (certain Intel GPUs)
if ! validate_vm_mode_blocked_ids; then
exit 1