mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-04-25 08:56:21 +00:00
add_controller_nvme_vm.sh
This commit is contained in:
@@ -137,6 +137,135 @@ function _vm_is_q35() {
|
||||
[[ "$machine_line" == *q35* ]]
|
||||
}
|
||||
|
||||
function _vm_storage_enable_iommu_cmdline() {
|
||||
local cpu_vendor iommu_param
|
||||
cpu_vendor=$(grep -m1 "vendor_id" /proc/cpuinfo 2>/dev/null | awk '{print $3}')
|
||||
|
||||
if [[ "$cpu_vendor" == "GenuineIntel" ]]; then
|
||||
iommu_param="intel_iommu=on"
|
||||
elif [[ "$cpu_vendor" == "AuthenticAMD" ]]; then
|
||||
iommu_param="amd_iommu=on"
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
|
||||
local cmdline_file="/etc/kernel/cmdline"
|
||||
local grub_file="/etc/default/grub"
|
||||
|
||||
if [[ -f "$cmdline_file" ]] && grep -qE 'root=ZFS=|root=ZFS/' "$cmdline_file" 2>/dev/null; then
|
||||
if ! grep -q "$iommu_param" "$cmdline_file"; then
|
||||
cp "$cmdline_file" "${cmdline_file}.bak.$(date +%Y%m%d_%H%M%S)"
|
||||
sed -i "s|\\s*$| ${iommu_param} iommu=pt|" "$cmdline_file"
|
||||
proxmox-boot-tool refresh >/dev/null 2>&1 || true
|
||||
fi
|
||||
elif [[ -f "$grub_file" ]]; then
|
||||
if ! grep -q "$iommu_param" "$grub_file"; then
|
||||
cp "$grub_file" "${grub_file}.bak.$(date +%Y%m%d_%H%M%S)"
|
||||
sed -i "/GRUB_CMDLINE_LINUX_DEFAULT=/ s|\"$| ${iommu_param} iommu=pt\"|" "$grub_file"
|
||||
update-grub >/dev/null 2>&1 || true
|
||||
fi
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
function _vm_storage_ensure_iommu_or_offer() {
|
||||
if declare -F _pci_is_iommu_active >/dev/null 2>&1 && _pci_is_iommu_active; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if grep -qE 'intel_iommu=on|amd_iommu=on' /proc/cmdline 2>/dev/null && \
|
||||
[[ -d /sys/kernel/iommu_groups ]] && \
|
||||
[[ -n "$(ls /sys/kernel/iommu_groups/ 2>/dev/null)" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
local prompt
|
||||
prompt="$(translate "IOMMU is not active on this system.")\n\n"
|
||||
prompt+="$(translate "Controller/NVMe passthrough to VMs requires IOMMU enabled in BIOS/UEFI and kernel.")\n\n"
|
||||
prompt+="$(translate "Do you want to enable IOMMU now?")\n\n"
|
||||
prompt+="$(translate "A host reboot is required after this change.")"
|
||||
|
||||
whiptail --title "IOMMU Required" --yesno "$prompt" 14 78
|
||||
[[ $? -ne 0 ]] && return 1
|
||||
|
||||
if ! _vm_storage_enable_iommu_cmdline; then
|
||||
whiptail --title "IOMMU" --msgbox \
|
||||
"$(translate "Failed to configure IOMMU automatically.")\n\n$(translate "Please configure it manually and reboot.")" \
|
||||
10 72
|
||||
return 1
|
||||
fi
|
||||
|
||||
local reboot_policy="${VM_STORAGE_IOMMU_REBOOT_POLICY:-ask_now}"
|
||||
if [[ "$reboot_policy" == "defer" ]]; then
|
||||
VM_STORAGE_IOMMU_PENDING_REBOOT=1
|
||||
export VM_STORAGE_IOMMU_PENDING_REBOOT
|
||||
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 "Controller/NVMe passthrough will be available after reboot.")" \
|
||||
12 78
|
||||
return 1
|
||||
fi
|
||||
|
||||
if whiptail --title "Reboot Required" --yesno \
|
||||
"$(translate "IOMMU configured successfully.")\n\n$(translate "Do you want to reboot now?")" 10 68; then
|
||||
reboot
|
||||
else
|
||||
whiptail --title "Reboot Required" --msgbox \
|
||||
"$(translate "Please reboot manually and run the passthrough step again.")" 9 68
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
function _vm_storage_confirm_controller_passthrough_risk() {
|
||||
local vmid="${1:-}"
|
||||
local vm_name="${2:-}"
|
||||
local title="${3:-Controller + NVMe}"
|
||||
local vm_label=""
|
||||
if [[ -n "$vmid" ]]; then
|
||||
vm_label="$vmid"
|
||||
[[ -n "$vm_name" ]] && vm_label="${vm_label} (${vm_name})"
|
||||
fi
|
||||
|
||||
local msg
|
||||
msg="$(translate "Important compatibility notice")\n\n"
|
||||
msg+="$(translate "Not all motherboards support physical Controller/NVMe passthrough to VMs reliably, especially systems with old platforms or limited BIOS/UEFI firmware.")\n\n"
|
||||
msg+="$(translate "On some systems, the VM may fail to start or the host may freeze when the VM boots.")\n\n"
|
||||
|
||||
local reinforce_limited_firmware="no"
|
||||
local bios_date bios_year current_year cpu_model
|
||||
bios_date=$(cat /sys/class/dmi/id/bios_date 2>/dev/null)
|
||||
bios_year=$(echo "$bios_date" | grep -oE '[0-9]{4}' | tail -n1)
|
||||
current_year=$(date +%Y 2>/dev/null)
|
||||
if [[ -n "$bios_year" && -n "$current_year" ]]; then
|
||||
if (( current_year - bios_year >= 7 )); then
|
||||
reinforce_limited_firmware="yes"
|
||||
fi
|
||||
fi
|
||||
cpu_model=$(grep -m1 'model name' /proc/cpuinfo 2>/dev/null | cut -d: -f2- | xargs)
|
||||
if echo "$cpu_model" | grep -qiE 'J4[0-9]{3}|J3[0-9]{3}|N4[0-9]{3}|N3[0-9]{3}|Apollo Lake'; then
|
||||
reinforce_limited_firmware="yes"
|
||||
fi
|
||||
|
||||
if [[ "$reinforce_limited_firmware" == "yes" ]]; then
|
||||
msg+="$(translate "Detected risk factor: this host may use an older or limited firmware platform, which increases passthrough instability risk.")\n\n"
|
||||
fi
|
||||
|
||||
if [[ -n "$vm_label" ]]; then
|
||||
msg+="$(translate "Target VM"): ${vm_label}\n\n"
|
||||
fi
|
||||
msg+="$(translate "If this happens after assignment"):\n"
|
||||
msg+=" - $(translate "Power cycle the host if it is frozen.")\n"
|
||||
msg+=" - $(translate "Remove the hostpci controller/NVMe entries from the VM config file.")\n"
|
||||
msg+=" /etc/pve/qemu-server/${vmid:-<VMID>}.conf\n"
|
||||
msg+=" - $(translate "Start the VM again without that passthrough device.")\n\n"
|
||||
msg+="$(translate "Do you want to continue with this assignment?")"
|
||||
|
||||
whiptail --title "$title" --yesno "$msg" 21 96
|
||||
}
|
||||
|
||||
function _shorten_text() {
|
||||
local text="$1"
|
||||
local max_len="${2:-42}"
|
||||
|
||||
@@ -68,6 +68,7 @@ function header_info() {
|
||||
|
||||
VM_WIZARD_CAPTURE_FILE=""
|
||||
VM_WIZARD_CAPTURE_ACTIVE=0
|
||||
VM_STORAGE_IOMMU_PENDING_REBOOT=0
|
||||
|
||||
function start_vm_wizard_capture() {
|
||||
[[ "${VM_WIZARD_CAPTURE_ACTIVE:-0}" -eq 1 ]] && return 0
|
||||
@@ -132,6 +133,7 @@ function start_vm_configuration() {
|
||||
|
||||
|
||||
while true; do
|
||||
VM_STORAGE_IOMMU_PENDING_REBOOT=0
|
||||
OS_TYPE=$(dialog --backtitle "ProxMenux" \
|
||||
--title "$(translate "Select System Type")" \
|
||||
--menu "\n$(translate "Choose the type of virtual system to install:")" 20 70 10 \
|
||||
|
||||
@@ -56,6 +56,100 @@ set_title() {
|
||||
msg_title "$(translate "Add Controller or NVMe PCIe to VM")"
|
||||
}
|
||||
|
||||
enable_iommu_cmdline() {
|
||||
local cpu_vendor iommu_param
|
||||
cpu_vendor=$(grep -m1 "vendor_id" /proc/cpuinfo 2>/dev/null | awk '{print $3}')
|
||||
|
||||
if [[ "$cpu_vendor" == "GenuineIntel" ]]; then
|
||||
iommu_param="intel_iommu=on"
|
||||
msg_info "$(translate "Intel CPU detected")"
|
||||
elif [[ "$cpu_vendor" == "AuthenticAMD" ]]; then
|
||||
iommu_param="amd_iommu=on"
|
||||
msg_info "$(translate "AMD CPU detected")"
|
||||
else
|
||||
msg_error "$(translate "Unknown CPU vendor. Cannot determine IOMMU parameter.")"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local cmdline_file="/etc/kernel/cmdline"
|
||||
local grub_file="/etc/default/grub"
|
||||
|
||||
if [[ -f "$cmdline_file" ]] && grep -qE 'root=ZFS=|root=ZFS/' "$cmdline_file" 2>/dev/null; then
|
||||
if ! grep -q "$iommu_param" "$cmdline_file"; then
|
||||
cp "$cmdline_file" "${cmdline_file}.bak.$(date +%Y%m%d_%H%M%S)"
|
||||
sed -i "s|\\s*$| ${iommu_param} iommu=pt|" "$cmdline_file"
|
||||
proxmox-boot-tool refresh >/dev/null 2>&1 || true
|
||||
msg_ok "$(translate "IOMMU parameters added to /etc/kernel/cmdline")"
|
||||
else
|
||||
msg_ok "$(translate "IOMMU already configured in /etc/kernel/cmdline")"
|
||||
fi
|
||||
elif [[ -f "$grub_file" ]]; then
|
||||
if ! grep -q "$iommu_param" "$grub_file"; then
|
||||
cp "$grub_file" "${grub_file}.bak.$(date +%Y%m%d_%H%M%S)"
|
||||
sed -i "/GRUB_CMDLINE_LINUX_DEFAULT=/ s|\"$| ${iommu_param} iommu=pt\"|" "$grub_file"
|
||||
update-grub >/dev/null 2>&1 || true
|
||||
msg_ok "$(translate "IOMMU parameters added to GRUB")"
|
||||
else
|
||||
msg_ok "$(translate "IOMMU already configured in GRUB")"
|
||||
fi
|
||||
else
|
||||
msg_error "$(translate "Neither /etc/kernel/cmdline nor /etc/default/grub found.")"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_iommu_or_offer_enable() {
|
||||
if declare -F _pci_is_iommu_active >/dev/null 2>&1 && _pci_is_iommu_active; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if grep -qE 'intel_iommu=on|amd_iommu=on' /proc/cmdline 2>/dev/null && \
|
||||
[[ -d /sys/kernel/iommu_groups ]] && \
|
||||
[[ -n "$(ls /sys/kernel/iommu_groups/ 2>/dev/null)" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
local msg
|
||||
msg="\n$(translate "IOMMU is not active on this system.")\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 "Note: A system reboot will be required after enabling IOMMU.")\n"
|
||||
msg+="$(translate "You must run this option again after rebooting.")"
|
||||
|
||||
dialog --backtitle "ProxMenux" \
|
||||
--title "$(translate "IOMMU Required")" \
|
||||
--yesno "$msg" 15 74
|
||||
local response=$?
|
||||
clear
|
||||
|
||||
[[ $response -ne 0 ]] && return 1
|
||||
|
||||
set_title
|
||||
msg_title "$(translate "Enabling IOMMU")"
|
||||
echo
|
||||
if ! enable_iommu_cmdline; then
|
||||
echo
|
||||
msg_error "$(translate "Failed to configure IOMMU automatically.")"
|
||||
msg_success "$(translate "Press Enter to continue...")"
|
||||
read -r
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo
|
||||
msg_success "$(translate "IOMMU configured. Reboot required before using Controller/NVMe passthrough.")"
|
||||
echo
|
||||
if whiptail --title "$(translate "Reboot Required")" \
|
||||
--yesno "$(translate "Do you want to reboot now?")" 10 64; then
|
||||
msg_warn "$(translate "Rebooting the system...")"
|
||||
reboot
|
||||
else
|
||||
msg_info2 "$(translate "Please reboot manually and run this option again.")"
|
||||
msg_success "$(translate "Press Enter to continue...")"
|
||||
read -r
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
select_target_vm() {
|
||||
local -a vm_menu=()
|
||||
local line vmid vmname vmstatus vm_machine status_label
|
||||
@@ -71,7 +165,6 @@ select_target_vm() {
|
||||
status_label="${vmstatus}, ${vm_machine}"
|
||||
vm_menu+=("$vmid" "${vmname} [${status_label}]")
|
||||
done < <(qm list 2>/dev/null)
|
||||
|
||||
if [[ ${#vm_menu[@]} -eq 0 ]]; then
|
||||
dialog --backtitle "ProxMenux" \
|
||||
--title "$(translate "Add Controller or NVMe PCIe to VM")" \
|
||||
@@ -107,14 +200,7 @@ validate_vm_requirements() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
if declare -F _pci_is_iommu_active >/dev/null 2>&1; then
|
||||
if ! _pci_is_iommu_active; then
|
||||
dialog --backtitle "ProxMenux" --colors \
|
||||
--title "$(translate "IOMMU Required")" \
|
||||
--msgbox "\n\Zb\Z1$(translate "IOMMU is not active on this host.")\Zn\n\n$(translate "PCIe passthrough requires IOMMU enabled in kernel and firmware.")\n\n$(translate "Enable IOMMU, reboot the host, and run again.")" 12 80
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
check_iommu_or_offer_enable || return 1
|
||||
|
||||
return 0
|
||||
}
|
||||
@@ -236,6 +322,12 @@ select_controller_nvme() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
if declare -F _vm_storage_confirm_controller_passthrough_risk >/dev/null 2>&1; then
|
||||
if ! _vm_storage_confirm_controller_passthrough_risk "$SELECTED_VMID" "$SELECTED_VM_NAME" "$(translate "Controller + NVMe")"; then
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
@@ -175,7 +175,7 @@ function select_virtual_disk() {
|
||||
fi
|
||||
|
||||
local DISK_SIZE
|
||||
cleanup
|
||||
stop_spinner
|
||||
DISK_SIZE=$(whiptail --backtitle "ProxMenuX" --inputbox "$(translate "System Disk Size (GB)")" 8 58 32 --title "VIRTUAL DISK" --cancel-button Cancel 3>&1 1>&2 2>&3)
|
||||
if [ $? -ne 0 ]; then
|
||||
return 0
|
||||
@@ -229,7 +229,7 @@ function select_import_disk() {
|
||||
done < <(lsblk -dn -e 7,11 -o PATH)
|
||||
|
||||
if [[ "${#FREE_DISKS[@]}" -eq 0 ]]; then
|
||||
cleanup
|
||||
stop_spinner
|
||||
whiptail --title "Error" --msgbox "$(translate "No importable disks available. System disks and protected disks are hidden.")" 9 70
|
||||
return 1
|
||||
fi
|
||||
@@ -265,6 +265,21 @@ function select_passthrough_disk() {
|
||||
}
|
||||
|
||||
function select_controller_nvme() {
|
||||
local VM_STORAGE_IOMMU_REBOOT_POLICY="defer"
|
||||
|
||||
if declare -F _vm_storage_ensure_iommu_or_offer >/dev/null 2>&1; then
|
||||
if ! _vm_storage_ensure_iommu_or_offer; then
|
||||
return 1
|
||||
fi
|
||||
elif declare -F _pci_is_iommu_active >/dev/null 2>&1; then
|
||||
if ! _pci_is_iommu_active; then
|
||||
whiptail --title "Controller + NVMe" --msgbox \
|
||||
"$(translate "IOMMU is not active on this host.")\n\n$(translate "Controller/NVMe passthrough requires IOMMU enabled in BIOS/UEFI and kernel.")\n\n$(translate "Enable IOMMU, reboot the host, and try again.")" \
|
||||
14 90
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
msg_info "$(translate "Detecting PCI storage controllers and NVMe devices...")"
|
||||
|
||||
_refresh_host_storage_cache
|
||||
@@ -384,6 +399,14 @@ function select_controller_nvme() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
if declare -F _vm_storage_confirm_controller_passthrough_risk >/dev/null 2>&1; then
|
||||
local vm_name_for_notice="${HN:-}"
|
||||
if ! _vm_storage_confirm_controller_passthrough_risk "${VMID:-}" "$vm_name_for_notice" "Controller + NVMe"; then
|
||||
CONTROLLER_NVME_PCIS=()
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
export CONTROLLER_NVME_PCIS
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -79,6 +79,7 @@ WIZARD_ADD_GPU="no"
|
||||
WIZARD_GPU_RESULT="not_requested"
|
||||
VM_WIZARD_CAPTURE_FILE=""
|
||||
VM_WIZARD_CAPTURE_ACTIVE=0
|
||||
VM_STORAGE_IOMMU_PENDING_REBOOT=0
|
||||
|
||||
|
||||
|
||||
@@ -599,6 +600,7 @@ function select_import_disk() {
|
||||
fi
|
||||
done < <(lsblk -dn -e 7,11 -o PATH)
|
||||
|
||||
stop_spinner
|
||||
if [[ ${#FREE_DISKS[@]} -eq 0 ]]; then
|
||||
whiptail --title "Error" --msgbox "$(translate "No importable disks available. System disks and protected disks are hidden.")" 9 70
|
||||
return 1
|
||||
@@ -618,7 +620,23 @@ function select_import_disk() {
|
||||
}
|
||||
|
||||
function select_controller_nvme() {
|
||||
local VM_STORAGE_IOMMU_REBOOT_POLICY="defer"
|
||||
|
||||
if declare -F _vm_storage_ensure_iommu_or_offer >/dev/null 2>&1; then
|
||||
if ! _vm_storage_ensure_iommu_or_offer; then
|
||||
return 1
|
||||
fi
|
||||
elif declare -F _pci_is_iommu_active >/dev/null 2>&1; then
|
||||
if ! _pci_is_iommu_active; then
|
||||
whiptail --title "Controller + NVMe" --msgbox \
|
||||
"$(translate "IOMMU is not active on this host.")\n\n$(translate "Controller/NVMe passthrough requires IOMMU enabled in BIOS/UEFI and kernel.")\n\n$(translate "Enable IOMMU, reboot the host, and try again.")" \
|
||||
14 90
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
msg_info "$(translate "Detecting PCI storage controllers and NVMe devices...")"
|
||||
|
||||
_refresh_host_storage_cache
|
||||
|
||||
local menu_items=()
|
||||
@@ -721,6 +739,15 @@ function select_controller_nvme() {
|
||||
for pci in $(echo "$selected" | tr -d '"'); do
|
||||
CONTROLLER_NVME_PCIS+=("$pci")
|
||||
done
|
||||
|
||||
if [[ ${#CONTROLLER_NVME_PCIS[@]} -gt 0 ]] && declare -F _vm_storage_confirm_controller_passthrough_risk >/dev/null 2>&1; then
|
||||
local vm_name_for_notice="${HN:-$NAME}"
|
||||
if ! _vm_storage_confirm_controller_passthrough_risk "${VMID:-}" "$vm_name_for_notice" "Controller + NVMe"; then
|
||||
CONTROLLER_NVME_PCIS=()
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
export CONTROLLER_NVME_PCIS
|
||||
}
|
||||
|
||||
@@ -1056,9 +1083,12 @@ function select_storage_volume() {
|
||||
function create_vm() {
|
||||
|
||||
# Create the VM
|
||||
qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1${BIOS_TYPE}${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \
|
||||
if ! qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1${BIOS_TYPE}${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \
|
||||
-name $HN -tags proxmenux,nas -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci \
|
||||
-serial0 socket
|
||||
-serial0 socket; then
|
||||
msg_error "Failed to create base VM. Check VM ID and host configuration."
|
||||
return 1
|
||||
fi
|
||||
msg_ok "Create a $NAME"
|
||||
|
||||
|
||||
@@ -1279,7 +1309,15 @@ if [[ ${#EFFECTIVE_IMPORT_DISKS[@]} -gt 0 ]]; then
|
||||
fi
|
||||
|
||||
if [[ ${#CONTROLLER_NVME_PCIS[@]} -gt 0 ]]; then
|
||||
if ! _vm_is_q35 "$VMID"; 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
|
||||
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.")"
|
||||
else
|
||||
msg_error "$(translate "IOMMU is not active. Skipping Controller + NVMe assignment.")"
|
||||
ERROR_FLAG=true
|
||||
fi
|
||||
elif ! _vm_is_q35 "$VMID"; then
|
||||
msg_error "$(translate "Controller + NVMe passthrough requires machine type q35. Skipping controller assignment.")"
|
||||
ERROR_FLAG=true
|
||||
else
|
||||
@@ -1440,6 +1478,10 @@ if [[ "$WIZARD_GPU_RESULT" == "applied" ]]; then
|
||||
echo -e "${TAB}• $(translate "First complete DSM setup and verify Web UI/SSH access.")"
|
||||
echo -e "${TAB}• $(translate "Then change the VM display to none (vga: none) when the system is stable.")"
|
||||
fi
|
||||
if [[ "${VM_STORAGE_IOMMU_PENDING_REBOOT:-0}" == "1" ]]; then
|
||||
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
|
||||
echo -e
|
||||
|
||||
#msg_success "$(translate "Press Enter to return to the main menu...")"
|
||||
|
||||
@@ -60,6 +60,7 @@ fi
|
||||
|
||||
load_language
|
||||
initialize_cache
|
||||
VM_STORAGE_IOMMU_PENDING_REBOOT="${VM_STORAGE_IOMMU_PENDING_REBOOT:-0}"
|
||||
|
||||
# ==========================================================
|
||||
# Mont ISOs
|
||||
@@ -284,7 +285,7 @@ function create_vm() {
|
||||
# $( [[ -n "$SERIAL_PORT" ]] && echo "-serial0 $SERIAL_PORT" ) >/dev/null 2>&1
|
||||
|
||||
|
||||
qm create "$VMID" \
|
||||
if ! qm create "$VMID" \
|
||||
-agent 1${MACHINE:+ $MACHINE} \
|
||||
-localtime 1${BIOS_TYPE:+ $BIOS_TYPE}${CPU_TYPE:+ $CPU_TYPE} \
|
||||
-cores "$CORE_COUNT" \
|
||||
@@ -295,7 +296,10 @@ qm create "$VMID" \
|
||||
-ostype "$GUEST_OS_TYPE" \
|
||||
-scsihw virtio-scsi-pci \
|
||||
$( [[ -n "$SERIAL_PORT" ]] && echo "-serial0 $SERIAL_PORT" ) \
|
||||
>/dev/null 2>&1
|
||||
>/dev/null 2>&1; then
|
||||
msg_error "$(translate "Failed to create base VM. Check VM ID and host configuration.")"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ "$OS_TYPE" == "2" ]]; then
|
||||
qm set "$VMID" -tablet 1 >/dev/null 2>&1
|
||||
@@ -465,7 +469,14 @@ fi
|
||||
fi
|
||||
|
||||
if [[ ${#CONTROLLER_NVME_PCIS[@]} -gt 0 ]]; then
|
||||
if ! _vm_is_q35 "$VMID"; 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
|
||||
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.")"
|
||||
else
|
||||
msg_error "$(translate "IOMMU is not active. Skipping Controller + NVMe assignment.")"
|
||||
fi
|
||||
elif ! _vm_is_q35 "$VMID"; then
|
||||
msg_error "$(translate "Controller + NVMe passthrough requires machine type q35. Skipping controller assignment.")"
|
||||
else
|
||||
local hostpci_idx=0
|
||||
@@ -737,6 +748,10 @@ if [[ "${WIZARD_ADD_GPU:-no}" == "yes" ]]; then
|
||||
fi
|
||||
echo -e
|
||||
fi
|
||||
if [[ "${VM_STORAGE_IOMMU_PENDING_REBOOT:-0}" == "1" ]]; then
|
||||
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
|
||||
msg_success "$(translate "Press Enter to return to the main menu...")"
|
||||
read -r
|
||||
bash "$LOCAL_SCRIPTS/menus/create_vm_menu.sh"
|
||||
@@ -761,6 +776,11 @@ elif [[ "$OS_TYPE" == "3" ]]; then
|
||||
echo -e
|
||||
fi
|
||||
|
||||
if [[ "${VM_STORAGE_IOMMU_PENDING_REBOOT:-0}" == "1" ]]; then
|
||||
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
|
||||
|
||||
msg_success "$(translate "Press Enter to return to the main menu...")"
|
||||
read -r
|
||||
bash "$LOCAL_SCRIPTS/menus/create_vm_menu.sh"
|
||||
|
||||
@@ -72,6 +72,7 @@ WIZARD_ADD_GPU="no"
|
||||
WIZARD_GPU_RESULT="not_requested"
|
||||
VM_WIZARD_CAPTURE_FILE=""
|
||||
VM_WIZARD_CAPTURE_ACTIVE=0
|
||||
VM_STORAGE_IOMMU_PENDING_REBOOT=0
|
||||
|
||||
|
||||
|
||||
@@ -613,7 +614,7 @@ function select_import_disk() {
|
||||
FREE_DISKS+=("$DISK" "$DESCRIPTION" "OFF")
|
||||
fi
|
||||
done < <(lsblk -dn -e 7,11 -o PATH)
|
||||
|
||||
stop_spinner
|
||||
if [[ ${#FREE_DISKS[@]} -eq 0 ]]; then
|
||||
whiptail --title "Error" --msgbox "$(translate "No importable disks available. System disks and protected disks are hidden.")" 9 70
|
||||
return 1
|
||||
@@ -633,7 +634,23 @@ function select_import_disk() {
|
||||
}
|
||||
|
||||
function select_controller_nvme() {
|
||||
local VM_STORAGE_IOMMU_REBOOT_POLICY="defer"
|
||||
|
||||
if declare -F _vm_storage_ensure_iommu_or_offer >/dev/null 2>&1; then
|
||||
if ! _vm_storage_ensure_iommu_or_offer; then
|
||||
return 1
|
||||
fi
|
||||
elif declare -F _pci_is_iommu_active >/dev/null 2>&1; then
|
||||
if ! _pci_is_iommu_active; then
|
||||
whiptail --title "Controller + NVMe" --msgbox \
|
||||
"$(translate "IOMMU is not active on this host.")\n\n$(translate "Controller/NVMe passthrough requires IOMMU enabled in BIOS/UEFI and kernel.")\n\n$(translate "Enable IOMMU, reboot the host, and try again.")" \
|
||||
14 90
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
msg_info "$(translate "Detecting PCI storage controllers and NVMe devices...")"
|
||||
|
||||
_refresh_host_storage_cache
|
||||
|
||||
local menu_items=()
|
||||
@@ -736,6 +753,15 @@ function select_controller_nvme() {
|
||||
for pci in $(echo "$selected" | tr -d '"'); do
|
||||
CONTROLLER_NVME_PCIS+=("$pci")
|
||||
done
|
||||
|
||||
if [[ ${#CONTROLLER_NVME_PCIS[@]} -gt 0 ]] && declare -F _vm_storage_confirm_controller_passthrough_risk >/dev/null 2>&1; then
|
||||
local vm_name_for_notice="${HN:-$NAME}"
|
||||
if ! _vm_storage_confirm_controller_passthrough_risk "${VMID:-}" "$vm_name_for_notice" "Controller + NVMe"; then
|
||||
CONTROLLER_NVME_PCIS=()
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
export CONTROLLER_NVME_PCIS
|
||||
}
|
||||
|
||||
@@ -1092,9 +1118,12 @@ function select_storage_volume() {
|
||||
function create_vm() {
|
||||
|
||||
# Create the VM
|
||||
qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1${BIOS_TYPE}${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \
|
||||
if ! qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1${BIOS_TYPE}${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \
|
||||
-name $HN -tags proxmenux,nas -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci \
|
||||
-serial0 socket
|
||||
-serial0 socket; then
|
||||
msg_error "Failed to create base VM. Check VM ID and host configuration."
|
||||
return 1
|
||||
fi
|
||||
msg_ok "Create a $NAME"
|
||||
|
||||
BOOT_ORDER_LIST=() # Array to store boot order for all disks
|
||||
@@ -1294,7 +1323,15 @@ function create_vm() {
|
||||
fi
|
||||
|
||||
if [[ ${#CONTROLLER_NVME_PCIS[@]} -gt 0 ]]; then
|
||||
if ! _vm_is_q35 "$VMID"; 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
|
||||
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.")"
|
||||
else
|
||||
msg_error "$(translate "IOMMU is not active. Skipping Controller + NVMe assignment.")"
|
||||
ERROR_FLAG=true
|
||||
fi
|
||||
elif ! _vm_is_q35 "$VMID"; then
|
||||
msg_error "$(translate "Controller + NVMe passthrough requires machine type q35. Skipping controller assignment.")"
|
||||
ERROR_FLAG=true
|
||||
else
|
||||
@@ -1466,6 +1503,10 @@ else
|
||||
echo -e "${TAB}• $(translate "First complete ZimaOS setup and verify remote access (web/SSH).")"
|
||||
echo -e "${TAB}• $(translate "Then change the VM display to none (vga: none) when the system is stable.")"
|
||||
fi
|
||||
if [[ "${VM_STORAGE_IOMMU_PENDING_REBOOT:-0}" == "1" ]]; then
|
||||
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
|
||||
echo -e
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user