public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Dietmar Maurer <dietmar@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [RFC pve-storage 09/27] disks: lvm: allow creating volume groups on multipath devices
Date: Fri, 31 Jul 2026 12:21:38 +0200	[thread overview]
Message-ID: <20260731102156.3947857-10-dietmar@proxmox.com> (raw)
In-Reply-To: <20260731102156.3947857-1-dietmar@proxmox.com>

The device checks resolved the mapper symlink to the dm device, which
get_disks does not know, so creating a volume group on a multipath
mapped SAN LUN was rejected with 'not a valid local disk'. Accept
multipath devices that are not in use, so the storage wizard can
initialize a shared LVM volume group directly on a multipath LUN.

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
---
 src/PVE/API2/Disks/LVM.pm |  8 +++++---
 src/PVE/Diskmanage.pm     | 27 +++++++++++++++++++++++----
 src/test/disklist_test.pm | 19 +++++++++++++++++++
 3 files changed, 47 insertions(+), 7 deletions(-)

diff --git a/src/PVE/API2/Disks/LVM.pm b/src/PVE/API2/Disks/LVM.pm
index 9f8f951..35051fd 100644
--- a/src/PVE/API2/Disks/LVM.pm
+++ b/src/PVE/API2/Disks/LVM.pm
@@ -131,7 +131,8 @@ __PACKAGE__->register_method({
             name => get_standard_option('pve-storage-id'),
             device => {
                 type => 'string',
-                description => 'The block device you want to create the volume group on',
+                description => 'The block device you want to create the volume group on.'
+                    . ' Multipath mapped devices are supported.',
             },
             add_storage => {
                 description => "Configure storage using the Volume Group",
@@ -153,7 +154,8 @@ __PACKAGE__->register_method({
         my $node = $param->{node};
 
         $dev = PVE::Diskmanage::verify_blockdev_path($dev);
-        PVE::Diskmanage::assert_disk_unused($dev);
+
+        PVE::Diskmanage::assert_disk_unused($dev, 1);
 
         my $storage_params = {
             type => 'lvm',
@@ -176,7 +178,7 @@ __PACKAGE__->register_method({
 
         my $worker = sub {
             PVE::Diskmanage::locked_disk_action(sub {
-                PVE::Diskmanage::assert_disk_unused($dev);
+                PVE::Diskmanage::assert_disk_unused($dev, 1);
                 die "volume group with name '${name}' already exists on node '${node}'\n"
                     if PVE::Storage::LVMPlugin::lvm_vgs()->{$name};
 
diff --git a/src/PVE/Diskmanage.pm b/src/PVE/Diskmanage.pm
index 5ac04dd..ab5db06 100644
--- a/src/PVE/Diskmanage.pm
+++ b/src/PVE/Diskmanage.pm
@@ -74,14 +74,22 @@ sub init_disk {
 }
 
 sub disk_is_used {
-    my ($disk) = @_;
+    my ($disk, $allow_multipath) = @_;
 
     my $dev = $disk;
     $dev =~ s|^/dev/||;
 
     my $disklist = get_disks($dev, 1, 1);
 
-    die "'$disk' is not a valid local disk\n" if !defined($disklist->{$dev});
+    if (!defined($disklist->{$dev})) {
+        if ($allow_multipath) {
+            my $multipath = lookup_multipath_map($disk);
+            return defined($multipath->{used}) ? 1 : 0 if defined($multipath);
+        }
+
+        die "'$disk' is not a valid local disk\n";
+    }
+
     return 1 if $disklist->{$dev}->{used};
 
     return 0;
@@ -904,6 +912,17 @@ sub get_multipath_disks {
     return $disklist;
 }
 
+# Returns the multipath device entry if the given path refers to a multipath mapped device.
+sub lookup_multipath_map {
+    my ($devpath) = @_;
+
+    my $path = abs_path($devpath) // $devpath;
+    my $dev = strip_dev($path);
+    return undef if $dev !~ m/^dm-\d+$/;
+
+    return get_multipath_disks()->{$dev};
+}
+
 sub get_partnum {
     my ($part_path) = @_;
 
@@ -958,8 +977,8 @@ sub locked_disk_action {
 }
 
 sub assert_disk_unused {
-    my ($dev) = @_;
-    die "device '$dev' is already in use\n" if disk_is_used($dev);
+    my ($dev, $allow_multipath) = @_;
+    die "device '$dev' is already in use\n" if disk_is_used($dev, $allow_multipath);
     return;
 }
 
diff --git a/src/test/disklist_test.pm b/src/test/disklist_test.pm
index dc84510..d2ea3b2 100644
--- a/src/test/disklist_test.pm
+++ b/src/test/disklist_test.pm
@@ -236,6 +236,25 @@ sub test_disk_list {
             print Dumper($multipath) if $print;
             $testcount++;
             is_deeply($multipath, $expected_multipath, 'multipath list should be the same');
+
+            eval { PVE::Diskmanage::assert_disk_unused('/dev/dm-0'); };
+            $testcount++;
+            like($@, qr/not a valid local disk/,
+                'multipath devices require an explicit opt-in');
+
+            eval { PVE::Diskmanage::assert_disk_unused('/dev/mapper/mpatha', 1); };
+            $testcount++;
+            is($@, '', 'unused multipath alias should pass');
+
+            for my $dev (qw(dm-1 dm-2 dm-3 dm-4)) {
+                eval { PVE::Diskmanage::assert_disk_unused("/dev/$dev", 1); };
+                $testcount++;
+                like($@, qr/already in use/, "used multipath device $dev should fail");
+            }
+
+            eval { PVE::Diskmanage::assert_disk_unused('/dev/dm-99', 1); };
+            $testcount++;
+            like($@, qr/not a valid local disk/, 'unknown device mapper device should fail');
         }
 
         done_testing($testcount);
-- 
2.47.3




  parent reply	other threads:[~2026-07-31 10:22 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-31 10:21 [RFC pve-storage/proxmox-widget-toolkit/pve-manager 00/27] add guided remote storage setup and SAN visibility Dietmar Maurer
2026-07-31 10:21 ` [RFC pve-storage 01/27] diskmanage: collect disk transport type from lsblk Dietmar Maurer
2026-07-31 10:21 ` [RFC pve-storage 02/27] diskmanage: add helper to list multipath devices Dietmar Maurer
2026-07-31 10:21 ` [RFC pve-storage 03/27] diskmanage: qualify NVMe over fabrics transport Dietmar Maurer
2026-07-31 10:21 ` [RFC pve-storage 04/27] disks: list: add include-remote parameter Dietmar Maurer
2026-07-31 10:21 ` [RFC pve-storage 05/27] diskmanage: include iSCSI session devices in disk enumeration Dietmar Maurer
2026-07-31 10:21 ` [RFC pve-storage 06/27] diskmanage: link multipath member disks to their map device Dietmar Maurer
2026-07-31 10:21 ` [RFC pve-storage 07/27] iscsi: factor out session device map from device list Dietmar Maurer
2026-07-31 10:21 ` [RFC pve-storage 08/27] api: scan: add san-luns method listing SAN LUN candidates Dietmar Maurer
2026-07-31 10:21 ` Dietmar Maurer [this message]
2026-07-31 10:21 ` [RFC pve-storage 10/27] diskmanage: add helper querying multipath path state Dietmar Maurer
2026-07-31 10:21 ` [RFC pve-storage 11/27] diskmanage: add helper querying NVMe native " Dietmar Maurer
2026-07-31 10:21 ` [RFC pve-storage 12/27] api: scan: san-luns: report " Dietmar Maurer
2026-07-31 10:21 ` [RFC pve-storage 13/27] iscsi plugin: list sessions of all transports and capture transport Dietmar Maurer
2026-07-31 10:21 ` [RFC pve-storage 14/27] api: add node-level iSCSI initiator target and session API Dietmar Maurer
2026-07-31 10:21 ` [RFC proxmox-widget-toolkit 15/27] disk selectors: allow opting into remote devices Dietmar Maurer
2026-07-31 10:21 ` [RFC pve-manager 16/27] ui: storage: allow switching the scan node of the NFS/CIFS scan combos Dietmar Maurer
2026-07-31 10:21 ` [RFC pve-manager 17/27] ui: storage: add guided remote storage wizard with NFS support Dietmar Maurer
2026-07-31 10:21 ` [RFC pve-manager 18/27] ui: storage wizard: add SMB/CIFS support Dietmar Maurer
2026-07-31 10:21 ` [RFC pve-manager 19/27] ui: storage wizard: add iSCSI support Dietmar Maurer
2026-07-31 10:21 ` [RFC pve-manager 20/27] ui: storage wizard: add FC-attached SAN (shared LVM) support Dietmar Maurer
2026-07-31 10:21 ` [RFC pve-manager 21/27] ui: storage wizard: add ZFS over iSCSI support Dietmar Maurer
2026-07-31 10:21 ` [RFC pve-manager 22/27] ui: dc: storage: add remote storage wizard entry to the add menu Dietmar Maurer
2026-07-31 10:21 ` [RFC pve-manager 23/27] ui: node: add SAN LUNs panel Dietmar Maurer
2026-07-31 10:21 ` [RFC pve-manager 24/27] ui: san luns: show multipath path state Dietmar Maurer
2026-07-31 10:21 ` [RFC pve-manager 25/27] api: nodes: add iSCSI initiator API endpoint Dietmar Maurer
2026-07-31 10:21 ` [RFC pve-manager 26/27] pvenode: add iscsi commands Dietmar Maurer
2026-07-31 10:21 ` [RFC pve-manager 27/27] ui: san luns: show iSCSI targets and sessions Dietmar Maurer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260731102156.3947857-10-dietmar@proxmox.com \
    --to=dietmar@proxmox.com \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal