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: