On Tue, Feb 26, 2008 at 06:38:27PM +0100, Frans Pop wrote: > On Tuesday 26 February 2008, Guido Günther wrote: > > I've attached an updated patch. Thanks for the comments. > > Thanks for the update, but I'm afraid I have one more. > > Please define variables used inside functions with 'local', especially when > defining variables with common names like "type". Make sense. Updated patch attached, it also fixes a call to is_multipath_part. I just tested it with some hackery in qemu and with a patched parted (#440675) things look quiet well already. Would be nice if this could be applied. Cheers, -- Guido
diff --git a/packages/partman/partman-base/debian/partman-base.templates b/packages/partman/partman-base/debian/partman-base.templates index 5bd5e87..001301e 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 # :sl3: _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 # :sl3: diff --git a/packages/partman/partman-base/init.d/parted b/packages/partman/partman-base/init.d/parted index b10781b..d30ce1a 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 is_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 @@ -24,6 +43,10 @@ if [ ! -f /var/run/parted_server.pid ]; then # TODO: How do we signal we couldn't start parted_server properly? exit $RET fi + # Skip devices that are part of a multipathed device + if part_of_multipath $partdev; then + continue + fi rm -rf /var/lib/partman/old_devices if [ -d $DEVICES ]; then diff --git a/packages/partman/partman-base/lib/base.sh b/packages/partman/partman-base/lib/base.sh index 1d973cd..a62a099 100644 --- a/packages/partman/partman-base/lib/base.sh +++ b/packages/partman/partman-base/lib/base.sh @@ -496,9 +496,36 @@ memfree () { fi } +# return the device mapper table type +dm_table () { + local 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 a partition on a multipath'ed device by checking if +# the corresponding multipath map exists +is_multipath_part () { + local type mp name + + 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 +} + # 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,'` @@ -698,10 +725,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 @@ -732,6 +756,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 is_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. diff --git a/packages/partman/partman-base/lib/commit.sh b/packages/partman/partman-base/lib/commit.sh index 6ab7ede..f5ccfe9 100644 --- a/packages/partman/partman-base/lib/commit.sh +++ b/packages/partman/partman-base/lib/commit.sh @@ -52,8 +52,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 ] && ! is_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