[Ovirt-devel] [PATCH node 6/6] Added new menu for Multipath configuration

Michael Burns mburns at redhat.com
Sat Sep 26 02:33:58 UTC 2009


Also added new kernel command line arg to setup multipath.
New menu takes user through mpath whitelisting and choosing an
mpath device for installation.

Signed-off-by: Michael Burns <mburns at redhat.com>
---
 scripts/ovirt-config-boot      |    2 +-
 scripts/ovirt-config-storage   |  188 +++++++++++++++++++++++++++++++++++++++-
 scripts/ovirt-config-uninstall |    8 ++
 scripts/ovirt-early            |   16 +++-
 4 files changed, 207 insertions(+), 7 deletions(-)

diff --git a/scripts/ovirt-config-boot b/scripts/ovirt-config-boot
index 87cf832..ed2bb9f 100755
--- a/scripts/ovirt-config-boot
+++ b/scripts/ovirt-config-boot
@@ -218,7 +218,7 @@ set -e\
         cp /sbin/dmsetup.static sbin/dmsetup
         cp /sbin/kpartx.static sbin/kpartx
         for M in /sbin/mpath_prio_*.static ; do
-            cp ${M} $/${M%%.static};
+            cp ${M} .${M%%.static};
         done
     fi

diff --git a/scripts/ovirt-config-storage b/scripts/ovirt-config-storage
index 91662c5..c448aee 100755
--- a/scripts/ovirt-config-storage
+++ b/scripts/ovirt-config-storage
@@ -130,6 +130,172 @@ check_partition_sizes()
     return $rc
 }

+is_multipath_disabled()
+{
+    grep -q "^ *devnode \"\*\"" /etc/multipath.conf
+}
+
+multipath_warn()
+{
+    sp='                                                    '
+    w='!!WARNING'
+    wb="$w"'!!'
+    w8="$w$w$w$w$w$w$w$w"
+    printf '%s!!\n' \
+      "$w8" \
+      "$w8" \
+      "$wb$sp$w" \
+      "$wb$sp$w" \
+      "$wb    Multipath Configurations should only be made    $w" \
+      "$wb    on true multipath devices.  Configuring any     $w" \
+      "$wb    other devices may cause problems with your      $w" \
+      "$wb    system.                                         $w" \
+      "$wb$sp$w" \
+      "$wb    Proceeding from this menu will erase all        $w" \
+      "$wb    previous multipath configurations.              $w" \
+      "$wb$sp$w" \
+      "$wb$sp$w" \
+    "$w8" \
+    "$w8"
+
+}
+
+abort_multipath()
+{
+    printf "Cleaning up multipath configuration\n">&2
+    sed -i 's/^\s*wwid \*$/  devnode "*"/' /etc/multipath.conf
+    sed -i 's/^\s*wwid \w.*$//g' /etc/multipath.conf
+    service multipathd reload >&2
+}
+
+config_multipath_conf()
+{
+    ! is_multipath_disabled && abort_multipath
+    if [[ $OVIRT_MPATH = "ALL" ]]; then
+        sed -i 's/^\s*devnode ".*$/  #devnode "*"/' /etc/multipath.conf
+    else
+        sed -i 's/^\s*devnode ".*$/  wwid */' /etc/multipath.conf
+        test $(grep ^blacklist_exceptions /etc/multipath.conf | wc -l) = 0 \
+          && printf "blacklist_exceptions {\n}" >> /etc/multipath.conf
+        local wwid=""
+        for d in $whitelisted
+        do
+            d=$(basename $d)
+            local scsi_id=$(scsi_id --whitelisted --device=/dev/$d)
+            if [[ -z $scsi_id ]]; then
+                echo "scsi_id failed for device /dev/$d.  Not white listing." >&2
+            else
+                wwid="${wwid} $scsi_id"
+            fi
+        done
+        wwid=$(echo $wwid | sed 's/ /\n/g' | sort -u)
+        for scsi_id in $wwid
+        do
+            sed -i "s/^blacklist_exceptions {$/blacklist_exceptions {\n  wwid $scsi_id"/ /etc/multipath.conf
+        done
+        for d in $OVIRT_MPATH
+        do
+           sed -i "s/^blacklist_exceptions {$/blacklist_exceptions {\n  wwid $d"/ /etc/multipath.conf
+
+        done
+    fi
+    service multipathd reload >&2
+    start_log
+    echo "Generated multipath.conf"
+    cat /etc/multipath.conf
+    echo "Output of multiatph -v6 command"
+    multipath -v6
+    stop_log
+    return 0
+}
+
+
+generate_whitelist()
+{
+    whitelisted=""
+    local devs=$devices
+    local PS3="Please select devices to add or remove from multipath whitelist:  "
+    while true; do
+        local choices=""
+        for d in $devs
+        do
+            get_drive_size $d >&2
+            if [[ $whitelisted =~ $d ]]; then
+                choices="$choices $d-whitelisted"
+            else
+                choices="$choices $d"
+            fi
+        done
+
+        choices="$choices Done Abort"
+        select whitelist in $choices
+        do
+            test "$whitelist" = Abort && return 1
+            test "$whitelist" = Done && return 0
+            #first check if it is already whitelisted
+            #and remove from whitelist
+            if [[ $whitelist =~ "whitelisted"  ]]; then
+               local tmp_whitelist=""
+               whitelist=${whitelist%-whitelisted}
+               for d in $whitelisted
+               do
+                   test $d != $whitelist && tmp_whitelist="$tmp_whitelist $d"
+               done
+               whitelisted=$tmp_whitelist
+            #else add it to whitelist
+            else
+                whitelisted="$whitelisted $whitelist"
+            fi
+            break
+        done
+    done
+}
+
+# Choose a multipathed device for installation
+get_multipath_device()
+{
+    multipath_warn >&2
+    local DRIVE_VAR=$1
+    generate_whitelist
+    test $? = 1 && return 1
+    config_multipath_conf
+    local count=0
+    echo "Detecting Multipath Devices..." >&2
+    while [ $count -lt 60 ]
+    do
+        test ! `ls /dev/mapper/mpath* 2> /dev/null | wc -l` = 0 && break
+        let count=$count+1
+        sleep 1
+    done
+    if [ `ls /dev/mapper/mpath* 2> /dev/null | wc -l` = 0 ]; then
+        echo "No Multipath devices found.  Aborting...">&2
+        abort_multipath
+        return 1
+    fi
+    #need to provide a menu to choose a multipath device
+    while true
+    do
+        local choices=""
+        for dev in $(ls /dev/mapper/mpath* | egrep -v "p[0-9]+$")
+        do
+            choices="$choices $dev"
+            get_drive_size $dev >&2
+        done
+        choices="$choices Abort"
+        local PS3="Select Multipath Device: "
+        select mpath_device in $choices
+        do
+            if [[ $mpath_device = Abort ]]; then
+                abort_multipath
+                return 1
+            elif [[ -e $mpath_device ]]; then
+                eval $DRIVE_VAR=$mpath_device
+                return 0
+            fi
+        done
+    done
+}
+
 # Find a usable/selected storage device.
 # If there are none, give a diagnostic and return nonzero.
 # If there is just one, e.g., /dev/sda, treat it as selected (see below).
@@ -140,6 +306,7 @@ check_partition_sizes()
 get_dev_name()
 {
     local udi_list=$(hal-find-by-capability --capability storage)
+    local DRIVE_VAR=$1
     if test -z "$udi_list"; then
         warn "ERROR: no usable storage devices detected"
         return 1
@@ -152,6 +319,9 @@ get_dev_name()
         local block_dev=$(hal-get-property --udi "$d" --key block.device)
         # Must start with a '/'.
         case $block_dev in
+            '')
+                #if block.device not defined, suppress warning
+                continue;;
             *' '*)
                 # we use space as separator
                 warn "block device name '$block_dev' contains space; skipping";
@@ -189,12 +359,13 @@ get_dev_name()
     for d in $devices; do
         get_drive_size $d >&2
     done
-    local choices="$devices Abort"
+    local choices="$devices Multipath Abort"
     select device in $choices
     do
         test "$device" = Abort && return 1
+        test "$device" = "Multipath" && get_multipath_device device;
         test -z "$device" && continue
-        echo "$device"
+        eval $DRIVE_VAR=$device
         return 0
     done
 }
@@ -202,7 +373,9 @@ get_dev_name()
 do_configure()
 {
     local name_and_size
-    DRIVE=$(get_dev_name) || return 0
+    get_dev_name DRIVE
+    test ! -e $DRIVE && echo "Drive '$DRIVE' is not a valid drive" >&2 \
+        && return 0
     get_drive_size $DRIVE SPACE

     printf "\n\nPlease configure storage partitions.\n\n"
@@ -537,6 +710,15 @@ CONFIG_SIZE=${OVIRT_VOL_CONFIG_SIZE:-$default_config_size}
 LOGGING_SIZE=${OVIRT_VOL_LOGGING_SIZE:-$default_logging_size}
 DATA_SIZE=${OVIRT_VOL_DATA_SIZE:-$default_data_size}

+if [ -n "$OVIRT_MPATH" ]; then
+    #if present then setup multipath.conf with value
+    config_multipath_conf
+    while true
+    do
+        test ! `ls /dev/mapper/mpath* 2> /dev/null | wc -l` = 0 && break
+    done
+fi
+
 if [ -n "$OVIRT_INIT" ]; then
     # if present, use the drive selected with 'ovirt_init' boot parameter
     DRIVE=$OVIRT_INIT
diff --git a/scripts/ovirt-config-uninstall b/scripts/ovirt-config-uninstall
index fd65cbb..20f8c2c 100755
--- a/scripts/ovirt-config-uninstall
+++ b/scripts/ovirt-config-uninstall
@@ -47,6 +47,14 @@ if ask_yes_or_no "Do you wish to continue and uninstall this node ([Y]es/[N]o)?"
 	    log "Unmounting boot partition"
 	    umount $partition
 	    log "Removing partitions"
+            eval $(echo $partition | awk ' {
+                print "drive=" substr($0,1,length($1)-1);
+                print "drive2=" substr($0,1,length($1)-2);
+            }')
+            if [ ! -e "$drive" ]; then
+                # e.g. c0d0p1
+                drive="$drive2"
+            fi
 	    drive=$(echo $partition | awk '{ print substr($0, 1, length($0) - 1) }')
 	    parted -s $drive "rm 1"
 	    parted -s $drive "rm 2"
diff --git a/scripts/ovirt-early b/scripts/ovirt-early
index 8990727..5632fb0 100755
--- a/scripts/ovirt-early
+++ b/scripts/ovirt-early
@@ -148,6 +148,7 @@ start() {
     #   collectd=server[:port]
     #   hostname=fqdn
     #   TBD logrotate maxsize
+    #   mpath format: mpath=wwid:[wwid]

     #   BOOTIF=link|eth*|<MAC> (appended by pxelinux)
     # network boot interface is assumed to be on management network where
@@ -236,6 +237,12 @@ start() {
     collectd_server=
     collectd_port=

+    # mpath=wwid:[wwid...]
+    # set a list of comma or colon separated wwids to allow
+    # for multipath install
+    # Specify ALL to use all devices
+    mpath=
+
     # save boot parameters like console= for local disk boot menu
     bootparams=
     cat /etc/system-release >> $OVIRT_LOGFILE
@@ -286,8 +293,7 @@ start() {
                     =/dev/*)
                     bus=
                     serial=
-                    i=${i#=}
-                    init=$(ls -1 "$i" 2>/dev/null | head -n1)
+                    init=${i#=}
                     ;;
                     *)
                     bus=
@@ -374,6 +380,10 @@ start() {
             console=*)
             bootparams="$bootparams $i"
             ;;
+            mpath=*)
+            i=${i#mpath=}
+            mpath=$(echo $i|tr ",:;" " ")
+            ;;
         esac
     done

@@ -384,7 +394,7 @@ start() {
         ip_gateway=$gateway
     fi
     # save boot parameters as defaults for ovirt-config-*
-    params="bootif init vol_boot_size vol_swap_size vol_root_size vol_config_size vol_logging_size vol_data_size local_boot standalone overcommit ip_address ip_netmask ip_gateway ipv6 dns ntp vlan ssh_pwauth syslog_server syslog_port collectd_server collectd_port bootparams hostname firstboot"
+    params="bootif init vol_boot_size vol_swap_size vol_root_size vol_config_size vol_logging_size vol_data_size local_boot standalone overcommit ip_address ip_netmask ip_gateway ipv6 dns ntp vlan ssh_pwauth syslog_server syslog_port collectd_server collectd_port bootparams hostname firstboot mpath"
     # mount /config unless firstboot is forced
     if [ "$firstboot" != "1" ]; then
         mount_config
-- 
1.6.2.5




More information about the ovirt-devel mailing list