From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [IPv6:2a0f:8001:1:32::40]) by lore.proxmox.com (Postfix) with ESMTPS id 2E7481FF0AF for ; Fri, 06 Nov 2026 01:58:09 +0100 (CET) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 1EB7E21470; Fri, 06 Nov 2026 01:51:20 +0100 (CET) From: Thomas Lamprecht To: pve-devel@lists.proxmox.com Subject: [PATCH v3 manager 65/76] ui: storage: iscsi: add the multipath option Date: Fri, 6 Nov 2026 00:31:40 +0100 Message-ID: <20261105233336.2178064-66-t.lamprecht@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20261105233336.2178064-1-t.lamprecht@proxmox.com> References: <20261105233336.2178064-1-t.lamprecht@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1793926182007 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.302 Adjusted score from AWL reputation of From: address DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: RZEIS5WE55Y4CFZ2TU4ZVFOQRYAEIZ7C X-Message-ID-Hash: RZEIS5WE55Y4CFZ2TU4ZVFOQRYAEIZ7C X-MailFrom: t.lamprecht@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Let an iSCSI storage request multipath maps for its LUNs. Existing path-based LVM base volumes wait for their map when activated, but enabling the option does not move logical volumes that are already active on individual paths. Explain that limit in the edit dialog and link to the device-dependency checks before relying on redundancy. Signed-off-by: Thomas Lamprecht --- www/manager6/SANUtils.js | 18 +++++++++++++++ www/manager6/storage/IScsiEdit.js | 38 +++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/www/manager6/SANUtils.js b/www/manager6/SANUtils.js index c101ebb75..ee75b5abb 100644 --- a/www/manager6/SANUtils.js +++ b/www/manager6/SANUtils.js @@ -168,6 +168,24 @@ Ext.define('PVE.SANUtils', { return { counts, summary: true }; }, + multipath_activation_hint: function (pathUsers = []) { + let text = Ext.String.format( + gettext( + 'Existing users of individual paths, such as active logical volumes or a guest that uses a path device directly, do not switch to the map when you enable multipath. Check their device dependencies before you rely on path redundancy. See the documentation.', + ), + Ext.htmlEncode(Proxmox.Utils.get_help_link('storage_multipath')), + ); + if (pathUsers.length) { + let found = pathUsers.map(({ node, users }) => `${node}: ${users}`).join('; '); + text += + '
' + + Ext.htmlEncode( + Ext.String.format(gettext('Currently using individual paths: {0}.'), found), + ); + } + return text; + }, + render_san_lun_device: function (value, metaData, rec) { let text = Ext.htmlEncode(value); // only multipath mapped devices report their path count diff --git a/www/manager6/storage/IScsiEdit.js b/www/manager6/storage/IScsiEdit.js index c005eeb15..76ac85714 100644 --- a/www/manager6/storage/IScsiEdit.js +++ b/www/manager6/storage/IScsiEdit.js @@ -75,6 +75,16 @@ Ext.define('PVE.storage.IScsiInputPanel', { onlineHelp: 'storage_open_iscsi', + // show the activation warning only when enabling multipath on an existing storage; use the + // dirty state, as loading sets the field before its original value + updateMultipathActivation: function () { + let me = this; + let field = me.down('field[name=multipath]'); + me.lookup('multipathActivation').setHidden( + me.isCreate || !field.getValue() || !field.isDirty(), + ); + }, + onGetValues: function (values) { let me = this; @@ -149,5 +159,33 @@ Ext.define('PVE.storage.IScsiInputPanel', { checked: true, fieldLabel: gettext('Use LUNs directly'), }, + { + xtype: 'proxmoxcheckbox', + name: 'multipath', + fieldLabel: gettext('Multipath'), + // unset instead of stored as 0, a node with an older release does not know the option + cbind: { + deleteEmpty: '{!isCreate}', + }, + autoEl: { + tag: 'div', + 'data-qtip': gettext( + 'Combine the paths of each LUN into one device on every node using the storage.', + ), + }, + listeners: { + change: (field) => field.up('inputpanel').updateMultipathActivation(), + dirtychange: (field) => field.up('inputpanel').updateMultipathActivation(), + }, + }, + { + xtype: 'displayfield', + reference: 'multipathActivation', + userCls: 'pmx-hint', + hidden: true, + cbind: { + value: () => PVE.SANUtils.multipath_activation_hint(), + }, + }, ], }); -- 2.47.3