From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 7CA328E055 for ; Thu, 10 Nov 2022 15:36:15 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 4ABAD28520 for ; Thu, 10 Nov 2022 15:36:15 +0100 (CET) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS for ; Thu, 10 Nov 2022 15:36:11 +0100 (CET) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 1D03044A94 for ; Thu, 10 Nov 2022 15:36:02 +0100 (CET) From: Dominik Csapak To: pve-devel@lists.proxmox.com Date: Thu, 10 Nov 2022 15:36:00 +0100 Message-Id: <20221110143600.258897-10-d.csapak@proxmox.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20221110143600.258897-1-d.csapak@proxmox.com> References: <20221110143600.258897-1-d.csapak@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.065 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pve-devel] [PATCH manager 2/2] ui: qemu: increase available usb ports depending on machine and ostype X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 10 Nov 2022 14:36:15 -0000 in the backend, we allow up to 14 usb ports, but only if the vm can use the qemu-xhci controller which is only possible since machine version 7.1 and if the ostype is l26 or windows > 7 for this we introduce two helpers: * qemu_min_version: modeled after the signature of 'min_version' from qemu-server, expects two arrays of versions and returns true if the first parameter is equal or greater than the second version * get_max_usb_count looks at the given ostype and machine string and returns the proper maximum number since we don't currently have the actual running version of the vm in the gui, this is only a heuristic for running vms. but since the actual running version could only be lower if none is set (e.g. for migrated/long-running vms) we allow more in the gui and the backend will do the proper thing (either hotplug it, or make it a pending change) Signed-off-by: Dominik Csapak --- www/manager6/Utils.js | 53 ++++++++++++++++++++++++++++++- www/manager6/qemu/HardwareView.js | 7 +++- www/manager6/qemu/USBEdit.js | 7 +++- 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/www/manager6/Utils.js b/www/manager6/Utils.js index 7ca6a271b..adcf082ff 100644 --- a/www/manager6/Utils.js +++ b/www/manager6/Utils.js @@ -1569,7 +1569,58 @@ Ext.define('PVE.Utils', { } }, - hardware_counts: { net: 32, usb: 5, hostpci: 16, audio: 1, efidisk: 1, serial: 4, rng: 1, tpmstate: 1 }, + hardware_counts: { + net: 32, + usb: 14, + usb_old: 5, + hostpci: 16, + audio: 1, + efidisk: 1, + serial: 4, + rng: 1, + tpmstate: 1, + }, + + // we can have usb6 and up only for specific machine/ostypes + get_max_usb_count: function(ostype, machine) { + if (!ostype) { + return PVE.Utils.hardware_counts.usb_old; + } + + let match = /-(\d+).(\d+)/.exec(machine ?? ''); + if (!match || PVE.Utils.qemu_min_version([match[1], match[2]], [7, 1])) { + if (ostype === 'l26') { + return PVE.Utils.hardware_counts.usb; + } + let os_match = /^win(\d+)$/.exec(ostype); + if (os_match && os_match[1] > 7) { + return PVE.Utils.hardware_counts.usb; + } + } + + return PVE.Utils.hardware_counts.usb_old; + }, + + // parameters are expected to be arrays, e.g. [7,1], [4,0,1] + // returns true if toCheck is equal or greater than minVersion + qemu_min_version: function(toCheck, minVersion) { + let i; + for (i = 0; i < toCheck.length && i < minVersion.length; i++) { + if (toCheck[i] < minVersion[i]) { + return false; + } + } + + if (minVersion.length > toCheck.length) { + for (; i < minVersion.length; i++) { + if (minVersion[i] !== 0) { + return false; + } + } + } + + return true; + }, cleanEmptyObjectKeys: function(obj) { for (const propName of Object.keys(obj)) { diff --git a/www/manager6/qemu/HardwareView.js b/www/manager6/qemu/HardwareView.js index 6e9d03b4a..96fd37e98 100644 --- a/www/manager6/qemu/HardwareView.js +++ b/www/manager6/qemu/HardwareView.js @@ -544,6 +544,11 @@ Ext.define('PVE.qemu.HardwareView', { let counts = {}; let isAtLimit = (type) => counts[type] >= PVE.Utils.hardware_counts[type]; + let isAtUsbLimit = () => { + let ostype = me.getObjectValue('ostype'); + let machine = me.getObjectValue('machine'); + return counts.usb >= PVE.Utils.get_max_usb_count(ostype, machine); + }; let set_button_status = function() { let selection_model = me.getSelectionModel(); @@ -570,7 +575,7 @@ Ext.define('PVE.qemu.HardwareView', { const noVMConfigNetPerm = !caps.vms['VM.Config.Network']; const noVMConfigDiskPerm = !caps.vms['VM.Config.Disk']; - me.down('#addUsb').setDisabled(noSysConsolePerm || isAtLimit('usb')); + me.down('#addUsb').setDisabled(noSysConsolePerm || isAtUsbLimit()); me.down('#addPci').setDisabled(noSysConsolePerm || isAtLimit('hostpci')); me.down('#addAudio').setDisabled(noVMConfigHWTypePerm || isAtLimit('audio')); me.down('#addSerial').setDisabled(noVMConfigHWTypePerm || isAtLimit('serial')); diff --git a/www/manager6/qemu/USBEdit.js b/www/manager6/qemu/USBEdit.js index 4373f82c3..fe51d186f 100644 --- a/www/manager6/qemu/USBEdit.js +++ b/www/manager6/qemu/USBEdit.js @@ -12,12 +12,17 @@ Ext.define('PVE.qemu.USBInputPanel', { setVMConfig: function(vmconfig) { var me = this; me.vmconfig = vmconfig; + let max_usb = PVE.Utils.get_max_usb_count(me.vmconfig.ostype, me.vmconfig.machine); + if (max_usb > PVE.Utils.hardware_counts.usb_old) { + me.down('field[name=usb3]').setDisabled(true); + } }, onGetValues: function(values) { var me = this; if (!me.confid) { - for (let i = 0; i < PVE.Utils.hardware_counts.usb; i++) { + let max_usb = PVE.Utils.get_max_usb_count(me.vmconfig.ostype, me.vmconfig.machine); + for (let i = 0; i < max_usb; i++) { let id = 'usb' + i.toString(); if (!me.vmconfig[id]) { me.confid = id; -- 2.30.2