View file File name : mpathconf Content :#!/bin/bash # # Copyright (C) 2010 Red Hat, Inc. All rights reserved. # # This file is part of the device-mapper-multipath package. # # This copyrighted material is made available to anyone wishing to use, # modify, copy, or redistribute it subject to the terms and conditions # of the GNU General Public License v.2. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Simple editting of /etc/multipath.conf # This program was largely ripped off from lvmconf # unset ENABLE FIND FRIENDLY PROPERTY FOREIGN MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_PROPERTY HAVE_FOREIGN HAVE_MULTIPATHD HAVE_MODULE HAVE_OUTFILE SHOW_STATUS CHANGED_CONFIG WWID_LIST HAVE_OPTION OPTION_NAME OPTION_VALUE DEFAULT_CONFIG="# device-mapper-multipath configuration file # For a complete list of the default configuration values, run either: # # multipath -t # or # # multipathd show config # For a list of configuration options with descriptions, see the # multipath.conf man page. defaults { user_friendly_names yes find_multipaths yes enable_foreign \"^$\" } blacklist_exceptions { property \"(SCSI_IDENT_|ID_WWN)\" }" CONFIGFILE="/etc/multipath.conf" OUTPUTFILE="/etc/multipath.conf" MULTIPATHDIR="/etc/multipath" TMPFILE="/etc/multipath/.multipath.conf.tmp" WWIDS=0 function usage { echo "usage: $0 <command>" echo "" echo "Commands:" echo "Enable: --enable " echo "Disable: --disable" echo "Only allow certain wwids (instead of enable): --allow <WWID>" echo "Set user_friendly_names (Default y): --user_friendly_names <y|n>" echo "Set find_multipaths (Default y): --find_multipaths <yes|no|strict|greedy|smart>" echo "Set default property blacklist (Default y): --property_blacklist <y|n>" echo "Set enable_foreign to show foreign devices (Default n): --enable_foreign <y|n>" echo "Add/Change/Remove option in defaults section: --option <option_name>:<value>" echo "Load the dm-multipath modules on enable (Default y): --with_module <y|n>" echo "start/stop/reload multipathd (Default n): --with_multipathd <y|n>" echo "select output file (Default /etc/multipath.conf): --outfile <FILE>" echo "" } function add_wwid { INDEX=0 while [ "$INDEX" -lt "$WWIDS" ] ; do if [ "$1" = "${WWID_LIST[$INDEX]}" ] ; then return fi ((INDEX++)) done WWID_LIST[$WWIDS]="$1" ((WWIDS++)) } function get_dm_deps { shift 3 while [ -n "$1" -a -n "$2" ]; do MAJOR=$(echo $1 | tr -d '(,') MINOR=$(echo $2 | tr -d ')') UUID=`dmsetup info -c --noheadings -o uuid -j $MAJOR -m $MINOR 2> /dev/null` if [ -n "$UUID" ] ; then set_dm_wwid $UUID fi shift 2 done } function set_dm_wwid { if [[ "$1" =~ ^part[[:digit:]]+-mpath- ]] ; then add_wwid "${1##part*-mpath-}" elif [[ "$1" =~ ^mpath- ]] ; then add_wwid "${1##mpath-}" else get_dm_deps `dmsetup deps -u $1` fi } function set_wwid { UUID="" if [[ "$1" =~ ^[[:digit:]]+:[[:digit:]]+$ ]] ; then MAJOR=${1%%:*} MINOR=${1##*:} UUID=`dmsetup info -c --noheadings -o uuid -j $MAJOR -m $MINOR 2> /dev/null` else UUID=`dmsetup info -c --noheadings -o uuid $1 2> /dev/null` fi if [ -n "$UUID" ] ; then set_dm_wwid $UUID else add_wwid "$1" fi } function parse_args { while [ -n "$1" ]; do case $1 in --enable) ENABLE=1 shift ;; --disable) ENABLE=0 shift ;; --allow) ENABLE=2 if [ -n "$2" ]; then set_wwid $2 shift 2 else usage exit 1 fi ;; --user_friendly_names) if [ -n "$2" ]; then FRIENDLY=$2 shift 2 else usage exit 1 fi ;; --find_multipaths) if [ -n "$2" ]; then FIND=$2 shift 2 else usage exit 1 fi ;; --property_blacklist) if [ -n "$2" ]; then PROPERTY=$2 shift 2 else usage exit 1 fi ;; --option) if [ -n "$2" ]; then OPTION_NAME=$(echo $2 | cut -s -f1 -d:) OPTION_VALUE=$(echo $2 | cut -s -f2 -d:) if [ -z "$OPTION_NAME" ]; then usage exit 1 fi shift 2 else usage exit 1 fi ;; --enable_foreign) if [ -n "$2" ]; then FOREIGN=$2 shift 2 else usage exit 1 fi ;; --with_module) if [ -n "$2" ]; then MODULE=$2 shift 2 else usage exit 1 fi ;; --with_multipathd) if [ -n "$2" ]; then MULTIPATHD=$2 shift 2 else usage exit 1 fi ;; --outfile) if [ -n "$2" ]; then OUTPUTFILE=$2 HAVE_OUTFILE=1 shift 2 else usage exit 1 fi ;; *) usage exit esac done } function validate_args { if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" -o -n "$FOREIGN" -o -n "$OPTION_NAME" ]; then echo "ignoring extra parameters on disable" FRIENDLY="" FIND="" PROPERTY="" MODULE="" FOREIGN="" OPTION_NAME="" OPTION_VALUE="" fi if [ -n "$FRIENDLY" ] && [ "$FRIENDLY" != "y" -a "$FRIENDLY" != "n" ]; then echo "--user_friendly_names must be either 'y' or 'n'" exit 1 fi if [ "$FIND" = "y" ]; then FIND="yes" elif [ "$FIND" = "n" ]; then FIND="no" elif [ -n "$FIND" ] && [ "$FIND" != "yes" -a "$FIND" != "no" -a "$FIND" != "strict" -a "$FIND" != "greedy" -a "$FIND" != "smart" ]; then echo "--find_multipaths must be one of 'yes' 'no' 'strict' 'greedy' or 'smart'" exit 1 fi if [ -n "$PROPERTY" ] && [ "$PROPERTY" != "y" -a "$PROPERTY" != "n" ]; then echo "--property_blacklist must be either 'y' or 'n'" exit 1 fi if [ -n "$FOREIGN" ] && [ "$FOREIGN" != "y" -a "$FOREIGN" != "n" ]; then echo "--enable_foreign must be either 'y' or 'n'" exit 1 fi if [ -n "$OPTION_NAME" ]; then if [[ $OPTION_NAME =~ [[:space:]]|#|\"|!|\{|\} ]]; then echo "--option name \"$OPTION_NAME\" is invalid" exit 1 elif [[ $OPTION_VALUE =~ \"|#|!|\{|\} ]]; then echo "--option value \"$OPTION_VALUE\" is invalid" exit 1 fi if [[ $OPTION_VALUE =~ [[:space:]] ]]; then OPTION_VALUE=\"$OPTION_VALUE\" fi fi if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" -a -z "$FOREIGN" -a -z "$OPTION_NAME" ]; then SHOW_STATUS=1 fi if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then echo "--with_module must be either 'y' or 'n'" exit 1 fi if [ -n "$MULTIPATHD" ] && [ "$MULTIPATHD" != "y" -a "$MULTIPATHD" != "n" ]; then echo "--with_multipathd must be either 'y' or 'n'" exit 1 fi if [ "$ENABLE" = 2 -a -z "$HAVE_OUTFILE" ]; then echo "Because --allow makes changes that cannot be automatically reversed," echo "you must set --outfile when you set --allow" exit 1 fi } function add_blacklist_exceptions { INDEX=0 while [ "$INDEX" -lt "$WWIDS" ] ; do sed -i '/^blacklist_exceptions[[:space:]]*{/ a\ wwid '"\"${WWID_LIST[$INDEX]}\""' ' $TMPFILE ((INDEX++)) done } umask 0077 parse_args "$@" validate_args if [ ! -d "$MULTIPATHDIR" ]; then echo "/etc/multipath/ does not exist. failing" exit 1 fi rm $TMPFILE 2> /dev/null echo "$DEFAULT_CONFIG" > $TMPFILE if [ -f "$CONFIGFILE" ]; then cp $CONFIGFILE $TMPFILE fi if grep -q "^blacklist[[:space:]]*{" $TMPFILE ; then HAVE_BLACKLIST=1 fi if grep -q "^blacklist_exceptions[[:space:]]*{" $TMPFILE ; then HAVE_EXCEPTIONS=1 fi if grep -q "^defaults[[:space:]]*{" $TMPFILE ; then HAVE_DEFAULTS=1 fi if [ -z "$MODULE" -o "$MODULE" = "y" ]; then if lsmod | grep -q "dm_multipath" ; then HAVE_MODULE=1 else HAVE_MODULE=0 fi fi if [ "$MULTIPATHD" = "y" ]; then if /bin/systemctl status multipathd.service > /dev/null 2>&1 ; then HAVE_MULTIPATHD=1 else HAVE_MULTIPATHD=0 fi fi if [ "$HAVE_BLACKLIST" = "1" ]; then if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"" ; then HAVE_DISABLE=1 elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"" ; then HAVE_DISABLE=0 fi fi if [ "$HAVE_BLACKLIST" = "1" ]; then if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*wwid[[:space:]][[:space:]]*\"\.\?\*\"" ; then HAVE_WWID_DISABLE=1 elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*wwid[[:space:]][[:space:]]*\"\.\?\*\"" ; then HAVE_WWID_DISABLE=0 fi fi if [ "$HAVE_DEFAULTS" = "1" ]; then HAVE_FIND=`sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | sed -n 's/^[[:blank:]]*find_multipaths[[:blank:]][[:blank:]]*\([^[:blank:]]*\).*$/\1/p' | sed -n 1p` if [ "$HAVE_FIND" = "1" ]; then HAVE_FIND="yes" elif [ "$HAVE_FIND" = "0" ]; then HAVE_FIND="no" fi if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(yes\|1\)" ; then HAVE_FRIENDLY=1 elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(no\|0\)" ; then HAVE_FRIENDLY=0 fi if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*enable_foreign" ; then HAVE_FOREIGN=0 elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]][[:space:]]*\"\^\$\"" ; then HAVE_FOREIGN=1 elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign" ; then HAVE_FOREIGN=2 fi if [ -n "$OPTION_NAME" ]; then if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q '^[[:space:]]*'"$OPTION_NAME"'[[:space:]][[:space:]]*'"$OPTION_VALUE" ; then HAVE_OPTION=1 elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q '^[[:space:]]*'"$OPTION_NAME"'\([[:space:]].*\)\?$' ; then HAVE_OPTION=0 fi fi fi if [ "$HAVE_EXCEPTIONS" = "1" ]; then if sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then HAVE_PROPERTY=1 elif sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then HAVE_PROPERTY=0 fi fi if [ -n "$SHOW_STATUS" ]; then if [ -z "$HAVE_DISABLE" -o "$HAVE_DISABLE" = 0 ]; then echo "multipath is enabled" else echo "multipath is disabled" fi if [ -z "$HAVE_FIND" ]; then echo "find_multipaths is no" else echo "find_multipaths is $HAVE_FIND" fi if [ -z "$HAVE_FRIENDLY" -o "$HAVE_FRIENDLY" = 0 ]; then echo "user_friendly_names is disabled" else echo "user_friendly_names is enabled" fi if [ -z "$HAVE_PROPERTY" -o "$HAVE_PROPERTY" = 0 ]; then echo "default property blacklist is disabled" else echo "default property blacklist is enabled" fi if [ -z "$HAVE_FOREIGN" -o "$HAVE_FOREIGN" = 0 ]; then echo "enable_foreign is not set (all foreign multipath devices will be shown)" elif [ "$HAVE_FOREIGN" = 1 ]; then echo "enable_foreign is set (no foreign multipath devices will be shown)" else echo "enable_foreign is set (foreign multipath devices may not be shown)" fi if [ -n "$HAVE_MODULE" ]; then if [ "$HAVE_MODULE" = 1 ]; then echo "dm_multipath module is loaded" else echo "dm_multipath module is not loaded" fi fi if [ -z "$HAVE_MULTIPATHD" ]; then if /bin/systemctl status multipathd.service > /dev/null 2>&1 ; then HAVE_MULTIPATHD=1 else HAVE_MULTIPATHD=0 fi fi if [ "$HAVE_MULTIPATHD" = 1 ]; then echo "multipathd is running" else echo "multipathd is not running" fi exit 0 fi if [ -z "$HAVE_BLACKLIST" ]; then cat >> $TMPFILE <<- _EOF_ blacklist { } _EOF_ fi if [ -z "$HAVE_DEFAULTS" ]; then cat >> $TMPFILE <<- _EOF_ defaults { } _EOF_ fi if [ "$ENABLE" = 2 ]; then if [ "$HAVE_DISABLE" = 1 ]; then sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"/# devnode ".*"/' $TMPFILE fi if [ -z "$HAVE_WWID_DISABLE" ]; then sed -i '/^blacklist[[:space:]]*{/ a\ wwid ".*" ' $TMPFILE elif [ "$HAVE_WWID_DISABLE" = 0 ]; then sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*wwid[[:space:]][[:space:]]*\"\.\?\*\"/ wwid ".*"/' $TMPFILE fi if [ "$HAVE_EXCEPTIONS" = 1 ]; then sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ {/^[[:space:]]*wwid/ d}' $TMPFILE else cat >> $TMPFILE <<- _EOF_ blacklist_exceptions { } _EOF_ fi add_blacklist_exceptions elif [ "$ENABLE" = 1 ]; then if [ "$HAVE_DISABLE" = 1 ]; then sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"/# devnode ".*"/' $TMPFILE fi elif [ "$ENABLE" = 0 ]; then if [ -z "$HAVE_DISABLE" ]; then sed -i '/^blacklist[[:space:]]*{/ a\ devnode ".*" ' $TMPFILE elif [ "$HAVE_DISABLE" = 0 ]; then sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"/ devnode ".*"/' $TMPFILE fi fi if [ -n "$FIND" ]; then if [ -z "$HAVE_FIND" ]; then sed -i '/^defaults[[:space:]]*{/ a\ find_multipaths '"$FIND"' ' $TMPFILE CHANGED_CONFIG=1 elif [ "$FIND" != "$HAVE_FIND" ]; then sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:blank:]]*find_multipaths[[:blank:]][[:blank:]]*[^[:blank:]]*/ find_multipaths '"$FIND"'/' $TMPFILE CHANGED_CONFIG=1 fi fi if [ "$FRIENDLY" = "n" ]; then if [ "$HAVE_FRIENDLY" = 1 ]; then sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(yes\|1\)/ user_friendly_names no/' $TMPFILE CHANGED_CONFIG=1 fi elif [ "$FRIENDLY" = "y" ]; then if [ -z "$HAVE_FRIENDLY" ]; then sed -i '/^defaults[[:space:]]*{/ a\ user_friendly_names yes ' $TMPFILE CHANGED_CONFIG=1 elif [ "$HAVE_FRIENDLY" = 0 ]; then sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(no\|0\)/ user_friendly_names yes/' $TMPFILE CHANGED_CONFIG=1 fi fi if [ "$PROPERTY" = "n" ]; then if [ "$HAVE_PROPERTY" = 1 ]; then sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/# property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE CHANGED_CONFIG=1 fi elif [ "$PROPERTY" = "y" ]; then if [ -z "$HAVE_PROPERTY" ]; then sed -i '/^blacklist_exceptions[[:space:]]*{/ a\ property "(SCSI_IDENT_|ID_WWN)" ' $TMPFILE CHANGED_CONFIG=1 elif [ "$HAVE_PROPERTY" = 0 ]; then sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/ property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE CHANGED_CONFIG=1 fi fi if [ "$FOREIGN" = "y" ]; then if [ "$HAVE_FOREIGN" = 1 -o "$HAVE_FOREIGN" = 2 ]; then sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*enable_foreign/# enable_foreign/' $TMPFILE CHANGED_CONFIG=1 fi elif [ "$FOREIGN" = "n" ]; then if [ -z "$HAVE_FOREIGN" ]; then sed -i '/^defaults[[:space:]]*{/ a\ enable_foreign "^$" ' $TMPFILE CHANGED_CONFIG=1 elif [ "$HAVE_FOREIGN" = 0 -o "$HAVE_FOREIGN" = 2 ]; then sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*#\?[[:space:]]*enable_foreign.*$/ enable_foreign "^$"/' $TMPFILE CHANGED_CONFIG=1 fi fi if [ -n "$OPTION_NAME" -a -n "$OPTION_VALUE" ]; then if [ -z "$HAVE_OPTION" ]; then sed -i '/^defaults[[:space:]]*{/ a\ '"$OPTION_NAME"' '"$OPTION_VALUE"' ' $TMPFILE CHANGED_CONFIG=1 elif [ "$HAVE_OPTION" = 0 ]; then sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*'"$OPTION_NAME"'\([[:space:]].*\)\?$/ '"$OPTION_NAME"' '"$OPTION_VALUE"'/' $TMPFILE CHANGED_CONFIG=1 fi elif [ -n "$OPTION_NAME" -a -n "$HAVE_OPTION" ]; then sed -i '/^defaults[[:space:]]*{/,/^}/{/^[[:space:]]*'"$OPTION_NAME"'\([[:space:]].*\)\?$/d}' $TMPFILE CHANGED_CONFIG=1 fi if [ -f "$OUTPUTFILE" ]; then cp $OUTPUTFILE $OUTPUTFILE.old if [ $? != 0 ]; then echo "failed to backup old config file, $OUTPUTFILE not updated" exit 1 fi fi cp $TMPFILE $OUTPUTFILE if [ $? != 0 ]; then echo "failed to copy new config file into place, check $OUTPUTFILE is still OK" exit 1 fi rm -f $TMPFILE if [ "$ENABLE" = 1 ]; then if [ "$HAVE_MODULE" = 0 ]; then modprobe dm_multipath fi if [ "$HAVE_MULTIPATHD" = 0 ]; then systemctl start multipathd.service fi elif [ "$ENABLE" = 0 ]; then if [ "$HAVE_MULTIPATHD" = 1 ]; then systemctl stop multipathd.service fi elif [ -n "$CHANGED_CONFIG" -a "$HAVE_MULTIPATHD" = 1 ]; then systemctl reload multipathd.service fi