From 0f0d99a3e5ba428f2a54ba9610dc0db3cd7d0ff8 Mon Sep 17 00:00:00 2001 From: Stoiko Ivanov Date: Fri, 5 Jun 2020 15:24:56 +0200 Subject: [PATCH] fix #2777 create zpools with stable dev paths when compiling the disk list add a property with a stable /dev/disk/by-id/ path for a block device when available. This is needed to create zpools with the stable by-id links The /dev/disk/by-id/ directory can contain multiple links to the same device (e.g. when it's used as a LVM PV, or one for the wwn/nvme-eui in addition to the one with vendor and serial). We take the first one which matches the bus where the disk is attached. For nvme disks we exclude the one containing the nvme-eui. The patch assumes that not all disks need to have such a link (e.g. virtio-block devices as we pass them to guests). Additionally the tests were adapted to run successfully. Signed-off-by: Stoiko Ivanov --- PVE/API2/Disks/ZFS.pm | 3 +++ PVE/Diskmanage.pm | 8 ++++++++ test/disk_tests/sas/disklist_expected.json | 3 ++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/PVE/API2/Disks/ZFS.pm b/PVE/API2/Disks/ZFS.pm index 551f21a..7a633a7 100644 --- a/PVE/API2/Disks/ZFS.pm +++ b/PVE/API2/Disks/ZFS.pm @@ -343,6 +343,9 @@ __PACKAGE__->register_method ({ foreach my $dev (@$devs) { $dev = PVE::Diskmanage::verify_blockdev_path($dev); PVE::Diskmanage::assert_disk_unused($dev); + my $sysfsdev = $dev =~ s!^/dev/!/sys/block/!r; + my $udevinfo = PVE::Diskmanage::get_udev_info($sysfsdev); + $dev = $udevinfo->{by_id_link} if defined($udevinfo->{by_id_link}); } PVE::Storage::assert_sid_unused($name) if $param->{add_storage}; diff --git a/PVE/Diskmanage.pm b/PVE/Diskmanage.pm index cac944d..267da08 100644 --- a/PVE/Diskmanage.pm +++ b/PVE/Diskmanage.pm @@ -359,6 +359,11 @@ sub get_udev_info { $data->{wwn} = $1; } + if ($info =~ m/^E: DEVLINKS=(.+)$/m) { + my @devlinks = grep(m#^/dev/disk/by-id/(ata|scsi|nvme(?!-eui))#, split (/ /, $1)); + $data->{by_id_link} = $devlinks[0] if defined($devlinks[0]); + } + return $data; } @@ -584,6 +589,9 @@ sub get_disks { wearout => $wearout, }; + my $by_id_link = $data->{by_id_link}; + $disklist->{$dev}->{by_id_link} = $by_id_link if defined($by_id_link); + my $osdid = -1; my $bluestore = 0; my $osdencrypted = 0; diff --git a/test/disk_tests/sas/disklist_expected.json b/test/disk_tests/sas/disklist_expected.json index 7814765..39b14a5 100644 --- a/test/disk_tests/sas/disklist_expected.json +++ b/test/disk_tests/sas/disklist_expected.json @@ -11,6 +11,7 @@ "rpm" : -1, "size" : 5120000, "serial" : "SER2", - "wearout" : "N/A" + "wearout" : "N/A", + "by_id_link" : "/dev/disk/by-id/scsi-00000000000000000" } } -- 2.39.2