[pve-devel] [PATCH 1/2] Add multipath handling

Dmitry Petuhov mityapetuhov at gmail.com
Sat Aug 6 09:23:15 CEST 2016


Add 2 functions to enable-disable multipath devices based on WWN
to PVE::Storage::Plugin and helper script. Script is simplified
and parallelized version of /sbin/rescan-scsi-bus from sg3-utils.
rescan-scsi-bus is too slow and noisy.

Signed-off-by: Dmitry Petuhov <mityapetuhov at gmail.com>
---
 Makefile              |   1 +
 PVE/Storage/Plugin.pm |  44 +++++++++++++++++
 control.in            |   2 +-
 scsi-scan.sh          | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 180 insertions(+), 1 deletion(-)
 create mode 100755 scsi-scan.sh

diff --git a/Makefile b/Makefile
index 2caf6e2..005836c 100644
--- a/Makefile
+++ b/Makefile
@@ -39,6 +39,7 @@ pvesm.bash-completion:
 install: pvesm.1 pvesm.bash-completion
 	install -d ${DESTDIR}${SBINDIR}
 	install -m 0755 pvesm ${DESTDIR}${SBINDIR}
+	install -m 0755 scsi-scan.sh ${DESTDIR}${SBINDIR}
 	make -C PVE install
 	install -d ${DESTDIR}/usr/share/man/man1
 	install -m 0644 pvesm.1 ${DESTDIR}/usr/share/man/man1/
diff --git a/PVE/Storage/Plugin.pm b/PVE/Storage/Plugin.pm
index 8089302..e4f1a08 100644
--- a/PVE/Storage/Plugin.pm
+++ b/PVE/Storage/Plugin.pm
@@ -65,6 +65,50 @@ sub content_hash_to_string {
     return join(',', @cta);
 }
 
+sub multipath_enable {
+    my ($class, $scfg, $wwn) = @_;
+    open my $mpd, '<', '/etc/multipath.conf';
+    open my $mpdt, '>', '/etc/multipath.conf.new';
+
+    # Scan storage bus for new paths. Linux SCSI subsystem is not automatic,
+    # so it doesn't know when new LUNS appear|disappear, and we need to kick it.
+    run_command(['/usr/sbin/scsi-scan.sh', '--rescan-all']);
+
+    #Copy contents and insert line just afer exceptions block beginning
+    while (my $line = <$mpd>) {
+	print $mpdt $line;
+	print $mpdt "\twwid \"0x$wwn\"\n" if $line =~ m/^blacklist_exceptions \{/;
+    }
+
+    close $mpdt;
+    close $mpd;
+    unlink '/etc/multipath.conf';
+    rename '/etc/multipath.conf.new','/etc/multipath.conf';
+
+    #force devmap reload to connect new device
+    system('/sbin/multipath', '-r');
+}
+
+sub multipath_disable {
+    my ($class, $scfg, $wwn) = @_;
+
+    open my $mpd, '<', '/etc/multipath.conf';
+    open my $mpdt, '>', '/etc/multipath.conf.new';
+
+    #Just copy contents except requested wwn
+    while (my $line = <$mpd>) {
+	print $mpdt $line unless $line =~ m/wwid "0x$wwn"/;
+    }
+
+    close $mpdt;
+    close $mpd;
+    unlink '/etc/multipath.conf';
+    rename '/etc/multipath.conf.new','/etc/multipath.conf';
+
+    #disable selected wwn multipathing
+    system('/sbin/multipath', '-f', "0x$wwn");
+}
+
 sub valid_content_types {
     my ($type) = @_;
 
diff --git a/control.in b/control.in
index d5e2c3f..9722be7 100644
--- a/control.in
+++ b/control.in
@@ -3,7 +3,7 @@ Version: @@VERSION@@-@@PKGRELEASE@@
 Section: perl
 Priority: optional
 Architecture: @@ARCH@@
-Depends: perl (>= 5.6.0-16), nfs-common, udev, libpve-common-perl, lvm2, thin-provisioning-tools, libfile-chdir-perl, glusterfs-client (>= 3.4.0-2), cstream, libnet-dbus-perl
+Depends: perl (>= 5.6.0-16), nfs-common, udev, libpve-common-perl, lvm2, thin-provisioning-tools, libfile-chdir-perl, glusterfs-client (>= 3.4.0-2), cstream, libnet-dbus-perl, sg3-utils, multipath-tools
 Maintainer: Proxmox Support Team <support at proxmox.com>
 Description: Proxmox VE storage management library
  This package contains the storage management library used by Proxmox VE.
diff --git a/scsi-scan.sh b/scsi-scan.sh
new file mode 100755
index 0000000..8f13c64
--- /dev/null
+++ b/scsi-scan.sh
@@ -0,0 +1,134 @@
+#!/bin/bash
+
+scan_host ()
+{
+    host=$1
+    echo - - - > /sys/class/scsi_host/$host/scan 
+}
+
+scan_all_hosts ()
+{
+    # Run scans in parallel
+    for i in `ls /sys/class/scsi_host`
+    do
+	scan_host $i &
+    done
+    # wait scans to end
+    wait
+}
+
+# Test if SCSI device is still responding to commands
+testonline ()
+{
+    SGDEV=$1
+    RC=0
+    if test ! -x /usr/bin/sg_turs; then echo "sg3-utils not installed"; exit 1; fi
+    if test -z "$SGDEV"; then return 0; fi
+    sg_turs /dev/$SGDEV >/dev/null 2>&1
+    RC=$?
+    # Handle in progress of becoming ready and unit attention -- wait at max 11s
+    declare -i ctr=0
+    while test $RC = 2 -o $RC = 6 && test $ctr -le 8; do
+	if test $RC = 2 
+	then 
+	    let $LN+=1
+	    sleep 1
+	else 
+	    sleep 0.02
+	fi
+	let ctr+=1
+	sg_turs /dev/$SGDEV >/dev/null 2>&1
+	RC=$?
+    done
+    return $RC
+}
+
+try_delete_lun ()
+{
+    DEV=$1
+    testonline $DEV
+    RC=$?
+    if [ $RC -ne 0 ]
+    then
+        echo 1 > /sys/block/$DEV/device/delete
+	#echo deleting lun $DEV
+    fi
+}
+
+delete_offline_luns ()
+{
+    for dev in  /dev/sd*[a-z]
+    do
+	dev=`echo $dev | sed 's/\/dev\///'`;
+	try_delete_lun $dev &
+    done
+    wait
+}
+
+rescan_mpdev ()
+{
+    WWN=$1
+    DMDEV=`readlink /dev/disk/by-id/dm-uuid-mpath-0x$WWN | grep -P -o 'dm-\d+'`
+    [ -z "$DMDEV" ] && exit 0
+
+    for dev in `ls /sys/block/$DMDEV/slaves`
+    do
+	echo 1 > /sys/block/$dev/device/rescan &
+    done
+    wait
+}
+
+delete_mpdev ()
+{
+    WWN=$1
+    DMDEV=`readlink /dev/disk/by-id/dm-uuid-mpath-0x$WWN | grep -P -o 'dm-\d+'`
+    [ -z "$DMDEV" ] && exit 0
+    devs=`ls /sys/block/$DMDEV/slaves`
+
+    multipath -f 0x$WWN
+
+    for dev in $devs
+    do
+	echo 1 > /sys/block/$dev/device/delete &
+    done
+    wait
+}
+
+case "$1" in
+    --scan-new)
+	scan_all_hosts
+	;;
+     --remove-offline)
+	delete_offline_luns
+	;;
+     --rescan-all)
+	delete_offline_luns
+	scan_all_hosts
+	;;
+    --rescan-wwid)
+	if [ -z "$2" ]
+	then
+	    echo "This command needs 2nd argument: device's WWID"
+	    exit 2
+	fi
+	rescan_mpdev $2
+	;;
+    --delete-wwid)
+	if [ -z "$2" ]
+	then
+	    echo "This command needs 2nd argument: device's WWID"
+	    exit 2
+	fi
+	delete_mpdev $2
+	;;
+    *)
+	echo "Need one of commands:"
+	echo "	--scan-new		Scans all SCSHI hosts for new|changed devices."
+	echo "	--remove-offline	Removes stale offline devices."
+	echo "	--resca-nall		Combo of two above."
+	echo "	--rescan-wwid <WWID>	Rescan slaves of single multipath device WWID"
+	echo "				for changes."
+	echo "	--delete-wwid <WWID>	Remove sinddle multipath device WWID and its slaves"
+	;;
+esac
+
-- 
2.1.4




More information about the pve-devel mailing list