diff -up mkinitrd-5.1.19.6/mkinitrd.multipath mkinitrd-5.1.19.6/mkinitrd --- mkinitrd-5.1.19.6/mkinitrd.multipath 2007-07-18 13:39:44.000000000 -0400 +++ mkinitrd-5.1.19.6/mkinitrd 2007-07-18 13:40:46.000000000 -0400 @@ -42,7 +42,6 @@ VERSION=5.1.19.6 PROBE="yes" MODULES="" PREMODS="" -DMDEVS="" NET_LIST="" CFG_DIR=${MKINITRD_CONFIG_DIR:-/etc/sysconfig/mkinitrd} @@ -64,11 +63,8 @@ img_vers="" builtins="" modulefile=/etc/modules.conf withusb=1 -if [ "$MULTIPATH" == "no" ]; then - withmpath=0 -else - withmpath=1 -fi +[ "$MULTIPATH" == "no" ] && withmpath=0 || withmpath=1 +[ "$DMRAID" == "no" ] && withdmraid=0 || withdmraid=1 rc=0 IMAGESIZE=8000 @@ -109,7 +105,8 @@ usage () { $cmd " [--force-ide-probe] [--force-scsi-probe | --omit-scsi-modules]" $cmd " [--image-version] [--force-raid-probe | --omit-raid-modules]" $cmd " [--with=] [--force-lvm-probe | --omit-lvm-modules]" - $cmd " [--builtin=] [--omit-dmraid] [--net-dev=]" + $cmd " [--builtin=] [--net-dev=]" + $cmd " [--without-usb] [--without-multipath] [--without-dmraid]" $cmd " [--fstab=] [--nocompress] " $cmd "" $cmd " (ex: `basename $0` /boot/initrd-2.2.5-15.img 2.2.5-15)" @@ -136,14 +133,63 @@ findall() { echo nash-find "$@" | /sbin/nash --force --quiet } -dm_get_uuid() { - echo nash-dm get_uuid "$1" | /sbin/nash --force --quiet -} - resolve_device_name() { echo nash-resolveDevice "$1" | /sbin/nash --forcequiet } +find_dm_in_sysblock() { + devname=$(resolve_device_name $1) + [ -z "$devname" ] && return 1 + majmin=$(get_numeric_dev dec $devname) + [ -z "$majmin" ] && return 1 + findall /sys/block -name dev | while read device ; do \ + echo "$majmin" | cmp -s $device && echo $device ; done \ + | sed -e 's,/dev$,,' +} + +is_mpath() { + major=$(echo $1 | cut -d: -f1) + minor=$(echo $1 | cut -d: -f2) + for target in $(dmsetup -C -j $major -m $minor table 2>/dev/null | \ + grep -v "No devices found" | awk ' { print $3 }') ; do + [ "$target" == "multipath" ] && return 0 + done + return 1 +} + +# this sucks; we need a generic way to get the hardware handler +is_emc() { + major=$(echo $1 | cut -d: -f1) + minor=$(echo $1 | cut -d: -f2) + if dmsetup -C -j $major -m $minor table 2>/dev/null | \ + grep -v "No devices found" | grep -q " emc " ; then + return 0 + fi + return 1 +} + +find_mpath_deps() { + local devpath="/dev/$(echo $1 | sed -e 's,.*/\([^/]\+\),\1,' )" + local arg2="$2" + local majmin=$(cat $1/dev) + local ret=1 + if is_mpath ${majmin} ; then + arg2=yes + if is_emc ${majmin} ; then + ret=0 + fi + fi + slaves="$1/slaves/*" + for slave in $slaves ; do + [ -e $slave ] || continue + find_mpath_deps $(readlink $slave) ${arg2} && ret=0 + done + if [ "$2" == "yes" ]; then + echo $devpath + fi + return $ret +} + findmodule() { skiperrors="" @@ -259,38 +305,13 @@ findmodule() { fi } -finddmmods() { - line=$(/sbin/dmsetup table "$1" 2>/dev/null) - [ -z "$line" ] && return 1 - type=$(echo "$line" | awk '{ print $3 }') - [ -z "$type" ] && return 1 - case "$type" in - mirror) - findmodule -dm-mirror - ;; - emc) - findmodule -dm-emc - findmodule -dm-round-robin - ;; - multipath) - findmodule -dm-multipath - findmodule -dm-round-robin - ;; - crypt) - findmodule -dm-crypt - ;; - zero) - findmodule -dm-zero - ;; - esac -} - inst() { if [ "$#" != "2" ];then echo "usage: inst " return fi vecho "$1 -> $2" + mkdir -p $(dirname $2) cp $1 $2 } @@ -569,7 +590,6 @@ handlenfs() { addnetdev $netdev } - while [ $# -gt 0 ]; do case $1 in --fstab*) @@ -595,6 +615,14 @@ while [ $# -gt 0 ]; do withusb=0 ;; + --without-multipath) + withmpath=0 + ;; + + --without-dmraid) + withdmraid=0 + ;; + --with*) if [ "$1" != "${1##--with=}" ]; then modname=${1##--with=} @@ -664,9 +692,6 @@ while [ $# -gt 0 ]; do --omit-lvm-modules) nolvm=1 ;; - --omit-dmraid) - nodmraid=1 - ;; --force-ide-probe) forceide=1 ;; @@ -933,17 +958,61 @@ if [ -n "${loopfs}" ] || [[ "$rootopts" fi # If we use LVM or dm-based raid, include dm-mod -# XXX: dm not really supported yet. testdm="" [ -n "$vg_list" ] && testdm="yes" [ -n "$forceraid" -o -n "$forcelvm" ] && testdm="yes" [ -z "$nolvm" -o -z "$noraid" ] && testdm="yes" [ "x$PROBE" != "xyes" ] && testdm="" +use_multipath=0 +use_emc=0 if [ -n "$testdm" -a -x /sbin/dmsetup -a -e /dev/mapper/control ]; then dmout=$(/sbin/dmsetup ls 2>/dev/null) if [ "$dmout" != "No devices found" -a "$dmout" != "" ]; then - + sysroot=$(find_dm_in_sysblock ${rootdev}) + rootdevs="" + if [ "${withmpath}" -eq 1 -a -n "${sysroot}" ]; then + for rd in ${sysroot} ; do + somedeps=$(find_mpath_deps ${rd}) + [ "$?" == "0" ] && use_emc=1 + [ -z "$somedeps" ] && continue + for dep in ${somedeps} ; do + majmin=$(get_numeric_dev dec ${dep}) + [[ ${majmin} =~ ^9: ]] && continue + [[ ${dep} =~ ^/dev/xvd.+ ]] && continue + case " ${rootdevs} " in + *" ${dep} "*) continue ;; + *) rootdevs="${rootdevs} ${dep}" ;; + esac + done + done + fi + + if [ -z "$rootdevs" ]; then + rootdevs="$rootdev" + fi + + root_wwids="" + if [ "${withmpath}" -eq "1" ]; then + for rootdev in ${rootdevs} ; do + disk=$(find_dm_in_sysblock ${rootdev} | sed -e 's,^/sys,,') + wwid=$(/sbin/scsi_id -g -u -s ${disk}) + if [ -z "${wwid}" ]; then + # Could be EMC unit requiring special option + wwid=$(/sbin/scsi_id -g -ppre-spc3-83 -u -s ${disk}) + fi + if [ -n "${wwid}" ]; then + case " ${root_wwids} " in + *" ${wwid} "*) continue ;; + *) root_wwids="${root_wwids} ${wwid}" ;; + esac + fi + done + if [ -n "$root_wwids" ]; then + use_multipath=1 + fi + fi + findmodule -dm-mod # DM requires all of these to be there in case someone used the @@ -951,58 +1020,15 @@ if [ -n "$testdm" -a -x /sbin/dmsetup -a findmodule -dm-mirror findmodule -dm-zero findmodule -dm-snapshot - - RAIDS=$(/sbin/dmraid -s -craidname 2>/dev/null | grep -vi "no raid disks") - # I fucking hate shell. - lineno=1 - PREV="" - LINE="" - while :; do - PREV="$LINE" - LINE=$(/sbin/dmsetup table | head -$lineno | tail -1) - if [ "$LINE" == "$PREV" ]; then - break; + # If we use dm-multipath devices, include the needed modules + if [ "$use_multipath" == "1" ]; then + findmodule -dm-multipath + findmodule -dm-round-robin + if [ "$use_emc" == "1" ]; then + findmodule -dm-emc fi - - eval $(echo $LINE | \ - while read NAME START END TYPE TABLE ; do - echo NAME=\"$(sed 's/:$//'<<< "$NAME")\" - echo START=\"$START\" - echo END=\"$END\" - echo TYPE=\"$TYPE\" - echo TABLE=\"$TABLE\" - done) - - case "$TYPE" in - multipath|emc) - [ "$withmpath" == "0" ] && continue - # ugggh. We could try to fish the module name out, but it - # requires real parsing... - # XXX also covered by #132001 - for mod in $TABLE ; do - DMMODS="$DMMODS $([[ "$mod" =~ "[[:alpha:]]" ]] && echo "$mod")" - done - DMDEVS="$DMDEVS $NAME" - ;; - *) - for raid in $RAIDS ; do - if [ "$raid" == "$NAME" ]; then - dmname=$(resolve_dm_name $NAME) - DMDEVS="$DMDEVS $dmname" - RAIDS=$(sed 's/ $NAME //' <<< "$RAIDS") - break - fi - done - ;; - esac - lineno=$(($lineno + 1)) - done - - for mod in $(tr ' ' '\n' <<< $DMMODS | sort -u) ; do - findmodule -dm-$mod - done - DMDEVS=$(tr ' ' '\n' <<< $DMDEVS | sort -u) + fi fi fi @@ -1014,8 +1040,6 @@ for n in $CONFMODS; do findmodule $n done -finddmmods - vecho "Using modules: $MODULES" MNTIMAGE=`mktemp -d ${TMPDIR}/initrd.XXXXXX` @@ -1037,34 +1061,6 @@ emit() echo $NONL "$@" >> $RCFILE } -emitdm() -{ - vecho "Adding dm map \"$1\"" - UUID=$(dm_get_uuid "$1") - if [ -n "$UUID" ]; then - UUID="--uuid $UUID" - fi - emit dm create "$1" $UUID $(/sbin/dmsetup table "$1") -} - -emitdms() -{ - [ -z "$DMDEVS" ] && return 0 - echo dm list $DMDEVS | nash --force --quiet | while read ACTION NAME ; do - case $ACTION in - rmparts) - emit rmparts "$NAME" - ;; - create) - emitdm "$NAME" - ;; - part) - emit dm partadd "$NAME" - ;; - esac - done -} - if [ -z "$MNTIMAGE" -o -z "$IMAGE" ]; then error "Error creating temporaries. Try again" exit 1 @@ -1136,6 +1132,39 @@ if [ -n "$vg_list" ]; then fi fi +if [ "$use_multipath" == "1" ]; then + # For multipath command + inst /sbin/multipath.static $MNTIMAGE/bin/multipath + if [ -f /etc/multipath.conf ]; then + inst /etc/multipath.conf $MNTIMAGE/etc/multipath.conf + fi + if [ -f /var/lib/multipath/bindings ]; then + inst /var/lib/multipath/bindings $MNTIMAGE/var/lib/multipath/bindings + fi + inst /sbin/scsi_id $MNTIMAGE/bin/scsi_id + inst /etc/scsi_id.config $MNTIMAGE/etc/scsi_id.config + # This includes all mpath_prio checkers in the image (~2.5M) + # Alternately we can only include those that are used by the + # current mpath config. This would require users to rebuild + # the initrd if migrating/adding controllers from different + # storage vendors + for M in /sbin/mpath_prio_*.static ; do + inst ${M} $MNTIMAGE/${M%%.static}; + done + mkdir -p $MNTIMAGE/tmp + + # For kpartx command which creates device maps for disk partitions + # and creates device files + inst /sbin/dmsetup.static $MNTIMAGE/bin/dmsetup + inst /sbin/kpartx.static $MNTIMAGE/bin/kpartx +fi + +if [ "$withdmraid" == "1" ]; then + # Only dmraid is needed to set up dmraid volume + inst /sbin/dmraid.static "$MNTIMAGE/bin/dmraid" + inst /sbin/kpartx.static "$MNTIMAGE/bin/kpartx" +fi + echo -n >| $RCFILE cemit << EOF #!/bin/nash @@ -1247,17 +1276,6 @@ EOF done unset usb_mounted -if [ -n "$scsi" ]; then - emit "echo Waiting for driver initialization." - emit "stabilized --hash --interval 250 /proc/scsi/scsi" -fi - - -if [ -n "$vg_list" ]; then - emit "echo Making device-mapper control node" - emit "mkdmnod" -fi - if [ -n "$net_list" ]; then for netdev in $net_list; do emit "echo Bringing up $netdev" @@ -1268,12 +1286,39 @@ fi emit_iscsi +if [ -n "$scsi" ]; then + emit "echo Waiting for driver initialization." + emit "stabilized --hash --interval 250 /proc/scsi/scsi" +fi + # HACK: module loading + device creation isn't necessarily synchronous... # this will make sure that we have all of our devices before trying # things like RAID or LVM emit "mkblkdevs" -emitdms +#if [ -n "$vg_list" ]; then +# emit "echo Making device-mapper control node" +# emit "mkdmnod" +#fi + +if [ "$use_multipath" == "1" ]; then + emit "echo Creating multipath devices" + for wwid in $root_wwids ; do + emit "/bin/multipath -v 0 $wwid" + done + emit "dmsetup ls --target multipath --exec 'kpartx -a -p p'" +fi + +if [ "$withdmraid" == "1" ]; then + emit "echo Scanning and configuring dmraid supported devices" + for x in $(/sbin/dmraid.static -ay -i -p -t 2>/dev/null | \ + egrep -iv "^no " | awk -F ':' '{ print $1 }') ; do + dmname=$(resolve_dm_name $x) + [ -z "$dmname" ] && continue + emit "dmraid -ay -i -p \"$dmname\"" + emit "kpartx -a -p p \"/dev/mapper/$dmname\"" + done +fi if [ -n "$raiddevices" ]; then for dev in $raiddevices; do