update vm_storage_helpers.sh

This commit is contained in:
MacRimi
2026-04-06 19:13:31 +02:00
parent c5b01b4bb7
commit d7c04ebbc7
8 changed files with 97 additions and 22 deletions

View File

@@ -210,7 +210,7 @@ function _vm_storage_ensure_iommu_or_offer() {
VM_STORAGE_IOMMU_PENDING_REBOOT=1 VM_STORAGE_IOMMU_PENDING_REBOOT=1
export VM_STORAGE_IOMMU_PENDING_REBOOT export VM_STORAGE_IOMMU_PENDING_REBOOT
whiptail --title "Reboot Required" --msgbox \ whiptail --title "Reboot Required" --msgbox \
"$(translate "IOMMU configured successfully.")\n\n$(translate "Continue the VM wizard and reboot the host at the end.")\n\n$(translate "You can now select Controller/NVMe devices in Storage Plan.")\n$(translate "Controller/NVMe passthrough will be applied after reboot.")" \ "$(translate "IOMMU configured successfully.")\n\n$(translate "Continue the VM wizard and reboot the host at the end.")\n\n$(translate "You can now select Controller/NVMe devices in Storage Plan.")\n$(translate "Device assignments will be written now and become active after reboot.")" \
12 78 12 78
return 0 return 0
fi fi

View File

@@ -705,12 +705,12 @@ install_drivers() {
for gpu_type in "${SELECTED_GPUS[@]}"; do for gpu_type in "${SELECTED_GPUS[@]}"; do
case "$gpu_type" in case "$gpu_type" in
intel) intel)
msg_info "$(translate 'Installing Intel VA-API drivers in container...')" #msg_info "$(translate 'Installing Intel VA-API drivers in container...')"
_install_intel_drivers "$ctid" "$ct_distro" _install_intel_drivers "$ctid" "$ct_distro"
msg_ok "$(translate 'Intel VA-API drivers installed.')" | tee -a "$screen_capture" msg_ok "$(translate 'Intel VA-API drivers installed.')" | tee -a "$screen_capture"
;; ;;
amd) amd)
msg_info "$(translate 'Installing AMD mesa drivers in container...')" #msg_info "$(translate 'Installing AMD mesa drivers in container...')"
_install_amd_drivers "$ctid" "$ct_distro" _install_amd_drivers "$ctid" "$ct_distro"
msg_ok "$(translate 'AMD mesa drivers installed.')" | tee -a "$screen_capture" msg_ok "$(translate 'AMD mesa drivers installed.')" | tee -a "$screen_capture"
;; ;;

View File

@@ -71,6 +71,7 @@ declare -a IOMMU_DEVICES=() # all PCI addrs in IOMMU group (endpoint device
declare -a IOMMU_VFIO_IDS=() # vendor:device for vfio-pci ids= declare -a IOMMU_VFIO_IDS=() # vendor:device for vfio-pci ids=
declare -a EXTRA_AUDIO_DEVICES=() # sibling audio function(s), typically *.1 declare -a EXTRA_AUDIO_DEVICES=() # sibling audio function(s), typically *.1
IOMMU_GROUP="" IOMMU_GROUP=""
IOMMU_PENDING_REBOOT=false
SELECTED_VMID="" SELECTED_VMID=""
VM_NAME="" VM_NAME=""
@@ -194,6 +195,11 @@ _file_has_exact_line() {
} }
evaluate_host_reboot_requirement() { evaluate_host_reboot_requirement() {
if [[ "$IOMMU_PENDING_REBOOT" == "true" ]]; then
PREFLIGHT_HOST_REBOOT_REQUIRED=true
return 0
fi
# Fast path for VM-to-VM reassignment where GPU is already bound to vfio # Fast path for VM-to-VM reassignment where GPU is already bound to vfio
if [[ "$VM_SWITCH_ALREADY_VFIO" == "true" ]]; then if [[ "$VM_SWITCH_ALREADY_VFIO" == "true" ]]; then
PREFLIGHT_HOST_REBOOT_REQUIRED=false PREFLIGHT_HOST_REBOOT_REQUIRED=false
@@ -491,9 +497,19 @@ check_iommu_enabled() {
return 0 return 0
fi fi
if grep -qE 'intel_iommu=on|amd_iommu=on' /proc/cmdline 2>/dev/null && \ local configured_next_boot=false
[[ -d /sys/kernel/iommu_groups ]] && \ if grep -qE 'intel_iommu=on|amd_iommu=on' /etc/kernel/cmdline 2>/dev/null || \
[[ -n "$(ls /sys/kernel/iommu_groups/ 2>/dev/null)" ]]; then grep -qE 'intel_iommu=on|amd_iommu=on' /etc/default/grub 2>/dev/null; then
configured_next_boot=true
fi
if [[ "$configured_next_boot" == "true" ]]; then
IOMMU_PENDING_REBOOT=true
HOST_CONFIG_CHANGED=true
dialog --backtitle "ProxMenux" \
--title "$(translate 'IOMMU Pending Reboot')" \
--msgbox "\n$(translate 'IOMMU is already configured for next boot, but it is not active yet.')\n\n$(translate 'GPU passthrough configuration will continue now and will become effective after host reboot.')" \
11 78
return 0 return 0
fi fi
@@ -502,7 +518,7 @@ check_iommu_enabled() {
msg+="$(translate 'GPU passthrough to VMs requires IOMMU to be enabled in the kernel.')\n\n" msg+="$(translate 'GPU passthrough to VMs requires IOMMU to be enabled in the kernel.')\n\n"
msg+="$(translate 'Do you want to enable IOMMU now?')\n\n" msg+="$(translate 'Do you want to enable IOMMU now?')\n\n"
msg+="$(translate 'Note: A system reboot will be required after enabling IOMMU.')\n" msg+="$(translate 'Note: A system reboot will be required after enabling IOMMU.')\n"
msg+="$(translate 'You must run this option again after rebooting.')" msg+="$(translate 'Configuration will continue now and be effective after reboot.')"
dialog --backtitle "ProxMenux" \ dialog --backtitle "ProxMenux" \
--title "$(translate 'IOMMU Required')" \ --title "$(translate 'IOMMU Required')" \
@@ -514,12 +530,24 @@ check_iommu_enabled() {
if [[ $response -eq 0 ]]; then if [[ $response -eq 0 ]]; then
[[ "$WIZARD_CALL" != "true" ]] && show_proxmenux_logo [[ "$WIZARD_CALL" != "true" ]] && show_proxmenux_logo
msg_title "$(translate 'Enabling IOMMU')" msg_title "$(translate 'Enabling IOMMU')"
_enable_iommu_cmdline if ! _enable_iommu_cmdline; then
echo echo
msg_success "$(translate 'IOMMU configured. Please reboot and run GPU passthrough to VM again.')" msg_error "$(translate 'Failed to configure IOMMU automatically.')"
echo echo
msg_success "$(translate 'Press Enter to continue...')" msg_success "$(translate 'Press Enter to continue...')"
read -r read -r
exit 0
fi
IOMMU_PENDING_REBOOT=true
HOST_CONFIG_CHANGED=true
echo
msg_success "$(translate 'IOMMU configured. GPU passthrough setup will continue now and will be effective after reboot.')"
echo
if [[ "$WIZARD_CALL" != "true" ]]; then
msg_success "$(translate 'Press Enter to continue...')"
read -r
fi
return 0
fi fi
exit 0 exit 0
} }
@@ -914,6 +942,23 @@ analyze_iommu_group() {
local group_link="/sys/bus/pci/devices/${pci_full}/iommu_group" local group_link="/sys/bus/pci/devices/${pci_full}/iommu_group"
if [[ ! -L "$group_link" ]]; then if [[ ! -L "$group_link" ]]; then
if [[ "$IOMMU_PENDING_REBOOT" == "true" ]]; then
IOMMU_GROUP="pending-reboot"
IOMMU_DEVICES=("$pci_full")
IOMMU_VFIO_IDS=()
local vid did
vid=$(cat "/sys/bus/pci/devices/${pci_full}/vendor" 2>/dev/null | sed 's/0x//')
did=$(cat "/sys/bus/pci/devices/${pci_full}/device" 2>/dev/null | sed 's/0x//')
[[ -n "$vid" && -n "$did" ]] && IOMMU_VFIO_IDS+=("${vid}:${did}")
dialog --backtitle "ProxMenux" --colors \
--title "$(translate 'IOMMU Group Pending')" \
--msgbox "\n$(translate 'IOMMU groups are not available yet because reboot is pending.')\n\n$(translate 'The script will preconfigure the selected GPU now and finalize hardware binding after reboot.')\n\n$(translate 'Selected GPU function'):\n • ${pci_full}" \
14 82
return 0
fi
dialog --backtitle "ProxMenux" \ dialog --backtitle "ProxMenux" \
--title "$(translate 'IOMMU Group Error')" \ --title "$(translate 'IOMMU Group Error')" \
--msgbox "\n$(translate 'Could not determine the IOMMU group for the selected GPU.')\n\n$(translate 'Make sure IOMMU is properly enabled and the system has been rebooted after activation.')" \ --msgbox "\n$(translate 'Could not determine the IOMMU group for the selected GPU.')\n\n$(translate 'Make sure IOMMU is properly enabled and the system has been rebooted after activation.')" \
@@ -1249,7 +1294,11 @@ confirm_summary() {
msg+="\n ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n" msg+="\n ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
msg+=" $(translate 'GPU') : ${SELECTED_GPU_NAME}\n" msg+=" $(translate 'GPU') : ${SELECTED_GPU_NAME}\n"
msg+=" $(translate 'PCI Address') : ${SELECTED_GPU_PCI}\n" msg+=" $(translate 'PCI Address') : ${SELECTED_GPU_PCI}\n"
if [[ "$IOMMU_PENDING_REBOOT" == "true" ]]; then
msg+=" $(translate 'IOMMU Group') : $(translate 'pending (reboot required to enumerate full group)')\n"
else
msg+=" $(translate 'IOMMU Group') : ${IOMMU_GROUP} (${#IOMMU_DEVICES[@]} $(translate 'devices'))\n" msg+=" $(translate 'IOMMU Group') : ${IOMMU_GROUP} (${#IOMMU_DEVICES[@]} $(translate 'devices'))\n"
fi
msg+=" $(translate 'Target VM') : ${VM_NAME:-VM-${SELECTED_VMID}} (${SELECTED_VMID})\n" msg+=" $(translate 'Target VM') : ${VM_NAME:-VM-${SELECTED_VMID}} (${SELECTED_VMID})\n"
msg+=" ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n" msg+=" ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n"
msg+=" \Zb$(translate 'Host'):\Zn\n" msg+=" \Zb$(translate 'Host'):\Zn\n"
@@ -1272,7 +1321,11 @@ confirm_summary() {
[[ "$TARGET_VM_ALREADY_HAS_GPU" == "true" ]] && \ [[ "$TARGET_VM_ALREADY_HAS_GPU" == "true" ]] && \
msg+="$(translate 'Existing hostpci entries detected — they will be reused')\n" msg+="$(translate 'Existing hostpci entries detected — they will be reused')\n"
msg+="$(translate 'Virtual display normalized to vga: std (compatibility)')\n" msg+="$(translate 'Virtual display normalized to vga: std (compatibility)')\n"
if [[ "$IOMMU_PENDING_REBOOT" == "true" ]]; then
msg+="$(translate 'hostpci entries for selected GPU functions (full IOMMU group will be enforced after reboot)')\n"
else
msg+="$(translate 'hostpci entries for all IOMMU group devices')\n" msg+="$(translate 'hostpci entries for all IOMMU group devices')\n"
fi
[[ ${#EXTRA_AUDIO_DEVICES[@]} -gt 0 ]] && \ [[ ${#EXTRA_AUDIO_DEVICES[@]} -gt 0 ]] && \
msg+="$(translate 'Additional GPU audio function will be added'): ${EXTRA_AUDIO_DEVICES[*]}\n" msg+="$(translate 'Additional GPU audio function will be added'): ${EXTRA_AUDIO_DEVICES[*]}\n"
[[ "$SELECTED_GPU" == "nvidia" ]] && \ [[ "$SELECTED_GPU" == "nvidia" ]] && \

View File

@@ -225,7 +225,7 @@ complete_nvidia_uninstall() {
unload_nvidia_modules unload_nvidia_modules
if command -v nvidia-uninstall >/dev/null 2>&1; then if command -v nvidia-uninstall >/dev/null 2>&1; then
msg_info "$(translate 'Running NVIDIA uninstaller...')" #msg_info "$(translate 'Running NVIDIA uninstaller...')"
nvidia-uninstall --silent >>"$LOG_FILE" 2>&1 || true nvidia-uninstall --silent >>"$LOG_FILE" 2>&1 || true
msg_ok "$(translate 'NVIDIA uninstaller completed.')" msg_ok "$(translate 'NVIDIA uninstaller completed.')"
fi fi

View File

@@ -104,6 +104,14 @@ check_iommu_or_offer_enable() {
return 0 return 0
fi fi
if grep -qE 'intel_iommu=on|amd_iommu=on' /etc/kernel/cmdline 2>/dev/null || \
grep -qE 'intel_iommu=on|amd_iommu=on' /etc/default/grub 2>/dev/null; then
IOMMU_PENDING_REBOOT=1
msg_warn "$(translate "IOMMU is configured for next boot, but not active yet.")"
msg_info2 "$(translate "Controller/NVMe assignment can continue now and will be effective after reboot.")"
return 0
fi
if declare -F _pci_is_iommu_active >/dev/null 2>&1 && _pci_is_iommu_active; then if declare -F _pci_is_iommu_active >/dev/null 2>&1 && _pci_is_iommu_active; then
return 0 return 0
fi fi
@@ -119,7 +127,7 @@ check_iommu_or_offer_enable() {
msg+="$(translate "Controller/NVMe passthrough to VMs requires IOMMU to be enabled in the kernel.")\n\n" msg+="$(translate "Controller/NVMe passthrough to VMs requires IOMMU to be enabled in the kernel.")\n\n"
msg+="$(translate "Do you want to enable IOMMU now?")\n\n" msg+="$(translate "Do you want to enable IOMMU now?")\n\n"
msg+="$(translate "Note: A system reboot will be required after enabling IOMMU.")\n" msg+="$(translate "Note: A system reboot will be required after enabling IOMMU.")\n"
msg+="$(translate "You must run this option again after rebooting.")" msg+="$(translate "Configuration can continue now and will be effective after reboot.")"
dialog --backtitle "ProxMenux" \ dialog --backtitle "ProxMenux" \
--title "$(translate "IOMMU Required")" \ --title "$(translate "IOMMU Required")" \

View File

@@ -1309,14 +1309,20 @@ if [[ ${#EFFECTIVE_IMPORT_DISKS[@]} -gt 0 ]]; then
fi fi
if [[ ${#CONTROLLER_NVME_PCIS[@]} -gt 0 ]]; then if [[ ${#CONTROLLER_NVME_PCIS[@]} -gt 0 ]]; then
local CONTROLLER_CAN_STAGE=true
if declare -F _pci_is_iommu_active >/dev/null 2>&1 && ! _pci_is_iommu_active; then if declare -F _pci_is_iommu_active >/dev/null 2>&1 && ! _pci_is_iommu_active; then
if [[ "${VM_STORAGE_IOMMU_PENDING_REBOOT:-0}" == "1" ]]; then if [[ "${VM_STORAGE_IOMMU_PENDING_REBOOT:-0}" == "1" ]]; then
msg_warn "$(translate "IOMMU was configured during this wizard and a reboot is pending.")" msg_warn "$(translate "IOMMU was configured during this wizard and a reboot is pending.")"
msg_warn "$(translate "Controller + NVMe assignment is postponed until after host reboot.")" msg_warn "$(translate "Controller + NVMe assignment will be written now and become active after host reboot.")"
else else
msg_error "$(translate "IOMMU is not active. Skipping Controller + NVMe assignment.")" msg_error "$(translate "IOMMU is not active. Skipping Controller + NVMe assignment.")"
ERROR_FLAG=true ERROR_FLAG=true
CONTROLLER_CAN_STAGE=false
fi fi
fi
if [[ "$CONTROLLER_CAN_STAGE" != "true" ]]; then
:
elif ! _vm_is_q35 "$VMID"; then elif ! _vm_is_q35 "$VMID"; then
msg_error "$(translate "Controller + NVMe passthrough requires machine type q35. Skipping controller assignment.")" msg_error "$(translate "Controller + NVMe passthrough requires machine type q35. Skipping controller assignment.")"
ERROR_FLAG=true ERROR_FLAG=true
@@ -1497,7 +1503,6 @@ local HOST_REBOOT_REQUIRED="no"
if [[ "${VM_STORAGE_IOMMU_PENDING_REBOOT:-0}" == "1" ]]; then if [[ "${VM_STORAGE_IOMMU_PENDING_REBOOT:-0}" == "1" ]]; then
HOST_REBOOT_REQUIRED="yes" HOST_REBOOT_REQUIRED="yes"
msg_warn "$(translate "IOMMU was enabled during this wizard. Reboot the host to apply it.")" msg_warn "$(translate "IOMMU was enabled during this wizard. Reboot the host to apply it.")"
echo -e "${TAB}$(translate "After reboot, run: Storage -> Add Controller or NVMe PCIe to VM, and select VM") ${VMID}."
fi fi
if [[ "$GPU_WIZARD_REBOOT_REQUIRED" == "yes" ]]; then if [[ "$GPU_WIZARD_REBOOT_REQUIRED" == "yes" ]]; then
HOST_REBOOT_REQUIRED="yes" HOST_REBOOT_REQUIRED="yes"

View File

@@ -469,13 +469,19 @@ fi
fi fi
if [[ ${#CONTROLLER_NVME_PCIS[@]} -gt 0 ]]; then if [[ ${#CONTROLLER_NVME_PCIS[@]} -gt 0 ]]; then
local CONTROLLER_CAN_STAGE=true
if declare -F _pci_is_iommu_active >/dev/null 2>&1 && ! _pci_is_iommu_active; then if declare -F _pci_is_iommu_active >/dev/null 2>&1 && ! _pci_is_iommu_active; then
if [[ "${VM_STORAGE_IOMMU_PENDING_REBOOT:-0}" == "1" ]]; then if [[ "${VM_STORAGE_IOMMU_PENDING_REBOOT:-0}" == "1" ]]; then
msg_warn "$(translate "IOMMU was configured during this wizard and a reboot is pending.")" msg_warn "$(translate "IOMMU was configured during this wizard and a reboot is pending.")"
msg_warn "$(translate "Controller + NVMe assignment is postponed until after host reboot.")" msg_warn "$(translate "Controller + NVMe assignment will be written now and become active after host reboot.")"
else else
msg_error "$(translate "IOMMU is not active. Skipping Controller + NVMe assignment.")" msg_error "$(translate "IOMMU is not active. Skipping Controller + NVMe assignment.")"
CONTROLLER_CAN_STAGE=false
fi fi
fi
if [[ "$CONTROLLER_CAN_STAGE" != "true" ]]; then
:
elif ! _vm_is_q35 "$VMID"; then elif ! _vm_is_q35 "$VMID"; then
msg_error "$(translate "Controller + NVMe passthrough requires machine type q35. Skipping controller assignment.")" msg_error "$(translate "Controller + NVMe passthrough requires machine type q35. Skipping controller assignment.")"
else else
@@ -766,7 +772,6 @@ if [[ "${WIZARD_ADD_GPU:-no}" == "yes" ]]; then
if [[ "${VM_STORAGE_IOMMU_PENDING_REBOOT:-0}" == "1" ]]; then if [[ "${VM_STORAGE_IOMMU_PENDING_REBOOT:-0}" == "1" ]]; then
HOST_REBOOT_REQUIRED="yes" HOST_REBOOT_REQUIRED="yes"
msg_warn "$(translate "IOMMU was enabled during this wizard. Reboot the host to apply it.")" msg_warn "$(translate "IOMMU was enabled during this wizard. Reboot the host to apply it.")"
echo -e "${TAB}$(translate "After reboot, run: Storage -> Add Controller or NVMe PCIe to VM, and select VM") ${VMID}."
fi fi
if [[ "$GPU_WIZARD_REBOOT_REQUIRED" == "yes" ]]; then if [[ "$GPU_WIZARD_REBOOT_REQUIRED" == "yes" ]]; then
HOST_REBOOT_REQUIRED="yes" HOST_REBOOT_REQUIRED="yes"
@@ -804,7 +809,6 @@ fi
if [[ "${VM_STORAGE_IOMMU_PENDING_REBOOT:-0}" == "1" ]]; then if [[ "${VM_STORAGE_IOMMU_PENDING_REBOOT:-0}" == "1" ]]; then
msg_warn "$(translate "IOMMU was enabled during this wizard. Reboot the host to apply it.")" msg_warn "$(translate "IOMMU was enabled during this wizard. Reboot the host to apply it.")"
echo -e "${TAB}$(translate "After reboot, run: Storage -> Add Controller or NVMe PCIe to VM, and select VM") ${VMID}."
fi fi
msg_success "$(translate "Press Enter to return to the main menu...")" msg_success "$(translate "Press Enter to return to the main menu...")"

View File

@@ -1323,14 +1323,20 @@ function create_vm() {
fi fi
if [[ ${#CONTROLLER_NVME_PCIS[@]} -gt 0 ]]; then if [[ ${#CONTROLLER_NVME_PCIS[@]} -gt 0 ]]; then
local CONTROLLER_CAN_STAGE=true
if declare -F _pci_is_iommu_active >/dev/null 2>&1 && ! _pci_is_iommu_active; then if declare -F _pci_is_iommu_active >/dev/null 2>&1 && ! _pci_is_iommu_active; then
if [[ "${VM_STORAGE_IOMMU_PENDING_REBOOT:-0}" == "1" ]]; then if [[ "${VM_STORAGE_IOMMU_PENDING_REBOOT:-0}" == "1" ]]; then
msg_warn "$(translate "IOMMU was configured during this wizard and a reboot is pending.")" msg_warn "$(translate "IOMMU was configured during this wizard and a reboot is pending.")"
msg_warn "$(translate "Controller + NVMe assignment is postponed until after host reboot.")" msg_warn "$(translate "Controller + NVMe assignment will be written now and become active after host reboot.")"
else else
msg_error "$(translate "IOMMU is not active. Skipping Controller + NVMe assignment.")" msg_error "$(translate "IOMMU is not active. Skipping Controller + NVMe assignment.")"
ERROR_FLAG=true ERROR_FLAG=true
CONTROLLER_CAN_STAGE=false
fi fi
fi
if [[ "$CONTROLLER_CAN_STAGE" != "true" ]]; then
:
elif ! _vm_is_q35 "$VMID"; then elif ! _vm_is_q35 "$VMID"; then
msg_error "$(translate "Controller + NVMe passthrough requires machine type q35. Skipping controller assignment.")" msg_error "$(translate "Controller + NVMe passthrough requires machine type q35. Skipping controller assignment.")"
ERROR_FLAG=true ERROR_FLAG=true
@@ -1522,7 +1528,6 @@ else
if [[ "${VM_STORAGE_IOMMU_PENDING_REBOOT:-0}" == "1" ]]; then if [[ "${VM_STORAGE_IOMMU_PENDING_REBOOT:-0}" == "1" ]]; then
HOST_REBOOT_REQUIRED="yes" HOST_REBOOT_REQUIRED="yes"
msg_warn "$(translate "IOMMU was enabled during this wizard. Reboot the host to apply it.")" msg_warn "$(translate "IOMMU was enabled during this wizard. Reboot the host to apply it.")"
echo -e "${TAB}$(translate "After reboot, run: Storage -> Add Controller or NVMe PCIe to VM, and select VM") ${VMID}."
fi fi
if [[ "$GPU_WIZARD_REBOOT_REQUIRED" == "yes" ]]; then if [[ "$GPU_WIZARD_REBOOT_REQUIRED" == "yes" ]]; then
HOST_REBOOT_REQUIRED="yes" HOST_REBOOT_REQUIRED="yes"