[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#442236: please add multipath support



Package: partman-base
Severity: wishlist
Tags: patch

Hi,
the attached patch against current d-i svn adds multipath support in an
(hopefully) unintrusive way. Please apply. This together with the
already posted patches to parted an hw-detect as well as the
parted-multipath udeb will allow the installer to work on multipathed
block devices up to the grub install part.
Cheers,
 -- Guido


-- System Information:
Debian Release: lenny/sid
  APT prefers unstable
  APT policy: (500, 'unstable'), (500, 'testing')
Architecture: powerpc (ppc)

Kernel: Linux 2.6.23-rc5-g3a1bc03a-dirty
Locale: LANG=de_DE.UTF-8, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
diff --git a/packages/partman/partman-base/debian/partman-base.templates b/packages/partman/partman-base/debian/partman-base.templates
index f48d99a..59e12c7 100644
--- a/packages/partman/partman-base/debian/partman-base.templates
+++ b/packages/partman/partman-base/debian/partman-base.templates
@@ -295,6 +295,14 @@ Type: text
 # For example: Serial ATA RAID isw_dhiiedgihc_Volume01 (partition #1)
 _Description: Serial ATA RAID %s (partition #%s)
 
+Template: partman/text/multipath
+Type: text
+_Description: Multipath %s (WWID %s)
+
+Template: partman/text/multipath_partition
+Type: text
+_Description: Multipath %s Partition #%s
+
 Template: partman/text/lvm_lv
 Type: text
 _Description: LVM VG %s, LV %s
diff --git a/packages/partman/partman-base/definitions.sh b/packages/partman/partman-base/definitions.sh
index bedd9d1..e16e453 100644
--- a/packages/partman/partman-base/definitions.sh
+++ b/packages/partman/partman-base/definitions.sh
@@ -478,13 +478,41 @@ log () {
 	echo $0: "$@" >>/var/log/partman
 }
 
+
+# return the device mapper table type
+dm_table ()
+{
+    type=""
+    if [ -x /sbin/dmsetup ]; then
+        type=$(/sbin/dmsetup table "$1" | head -n 1 | cut -d " " -f3)
+    fi
+    echo $type
+}
+
+# Check if a device is the partition on a multipath'ed device by getting the
+# corresponding mp map exists
+multipath_part ()
+{
+	type multipath >/dev/null 2>&1 || return 1
+
+	type=$(dm_table $1)
+	[ "$type" = linear ] || return 1
+	name=$(dmsetup info --noheadings -c -oname "$1")
+
+	mp=${name%-part*}
+	if [ $(multipath -l $mp | wc -l) -gt  0 ]; then
+		return 0
+	fi
+	return 1
+}
+
 ####################################################################
 # The functions below are not yet documented
 ####################################################################
 
 # TODO: this should not be global
 humandev () {
-    local host bus target part lun idenum targtype scsinum linux
+    local host bus target part lun idenum targtype scsinum linux wwid
     case "$1" in
 	/dev/ide/host*/bus[01]/target[01]/lun0/disc)
 	    host=`echo $1 | sed 's,/dev/ide/host\(.*\)/bus.*/target[01]/lun0/disc,\1,'`
@@ -684,10 +712,7 @@ humandev () {
 	    printf "$RET" ${type} ${device}
 	    ;;
 	/dev/mapper/*)
-	    type=""
-	    if [ -x /sbin/dmsetup ]; then
-	        type=$(/sbin/dmsetup table "$1" | head -n 1 | cut -d " " -f3)
-	    fi
+	    type=$(dm_table "$1")
 
 	    # First check for Serial ATA RAID devices
 	    if type dmraid >/dev/null 2>&1; then
@@ -718,6 +743,16 @@ humandev () {
 	        mapping=${1#/dev/mapper/}
 	        db_metaget partman/text/dmcrypt_volume description
 	        printf "$RET" $mapping
+	    elif [ "$type" = multipath ]; then
+	    	device=${1#/dev/mapper/}
+	    	wwid=$(multipath -l ${device} | head -n 1 | sed "s/^${device} \+(\([a-f0-9]\+\)).*/\1/")
+	    	db_metaget partman/text/multipath description
+	    	printf "$RET" ${device} ${wwid}
+	    elif multipath_part $1; then
+	    	part=$(echo "$1" | sed 's%.*-part\([0-9]\+\)$%\1%')
+	    	device=$(echo "$1" | sed 's%/dev/mapper/\(.*\)-part[0-9]\+$%\1%')
+	    	db_metaget partman/text/multipath_partition description
+	    	printf "$RET" ${device} ${part}
 	    else
 	        # LVM2 devices are found as /dev/mapper/<vg>-<lv>.  If the vg
 	        # or lv contains a dash, the dash is replaced by two dashes.
@@ -1079,8 +1114,13 @@ confirm_changes () {
 			filesystem=$(cat $id/visual_filesystem)
 			# Special case d-m devices to use a different description
 			if cat device | grep -q "/dev/mapper" ; then
-				partdesc="partman/text/confirm_unpartitioned_item"
-			else
+				type=$(dm_table $device)
+				# multipath devices are partitioned
+				if [  "$type" != multipath ] -a ! multipath_part $device; then
+					partdesc="partman/text/confirm_unpartitioned_item"
+				fi
+			fi
+			if [ -z "$partdesc" ]; then
 				partdesc="partman/text/confirm_item"
 				db_subst $partdesc PARTITION "$num"
 			fi
diff --git a/packages/partman/partman-base/init.d/parted b/packages/partman/partman-base/init.d/parted
index b7d5c7a..bff8139 100755
--- a/packages/partman/partman-base/init.d/parted
+++ b/packages/partman/partman-base/init.d/parted
@@ -16,6 +16,25 @@ part_of_sataraid () {
 	return 1
 }
 
+part_of_multipath() {
+	local mpdev
+	type multipath >/dev/null 2>&1 || return 1
+
+	if multipath_part $1; then
+		return 0
+	fi
+	# The block devices that make up the multipath:
+	# Output looks like \_ 4:0:0:1 sdc 8:32 ...
+	for mpdev in $(multipath -l | \
+	               grep '_ \([0-9]\+:\)\{3\}[0-9]\+ sd[a-z]\+ [0-9]\+:[0-9]\+' | \
+		       cut -f4 -d' '); do
+		if [ "$(readlink -f /dev/$mpdev)" = $1 ]; then
+			return 0
+		fi
+	done
+	return 1
+}
+
 if [ ! -f /var/run/parted_server.pid ]; then
     mkdir -p /var/run
     parted_server
@@ -50,6 +69,10 @@ if [ ! -f /var/run/parted_server.pid ]; then
 			continue
 		fi
 	fi
+	# Skip devices that are part of a multipathed device
+	if part_of_multipath $partdev; then
+		continue
+	fi
 
 	dirname=$(echo $1 | sed 's:/:=:g')
 	dev=$DEVICES/$dirname

Reply to: