From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 16 Oct 2014 15:49:01 -0500 Subject: [PATCH] RH: add mpathconf mpathconf is a program (largely based on lvmcomf) to help users configure /etc/multipath.conf and enable or disable multipathing. It has a couple of built-in options that can be set directly from the command line. But, mostly it is used to get a multipath.conf file with the OS defaults, and to enable and disable multipathing via a single command. Co-authored-by: Paul Donohue Signed-off-by: Benjamin Marzinski --- libmultipath/config.c | 2 + multipath/Makefile | 4 + multipath/mpathconf | 658 ++++++++++++++++++++++++++++++++++++++++++ multipath/mpathconf.8 | 151 ++++++++++ 4 files changed, 815 insertions(+) create mode 100644 multipath/mpathconf create mode 100644 multipath/mpathconf.8 diff --git a/libmultipath/config.c b/libmultipath/config.c index 002027a7..3d5943d3 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c @@ -961,6 +961,8 @@ int _init_config (const char *file, struct config *conf) validate_pctable(conf->overrides, 0, file); } else { condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); + condlog(0, "You can run \"/sbin/mpathconf --enable\" to create"); + condlog(0, "/etc/multipath.conf. See man mpathconf(8) for more details"); if (conf->blist_devnode == NULL) { conf->blist_devnode = vector_alloc(); if (!conf->blist_devnode) { diff --git a/multipath/Makefile b/multipath/Makefile index 2ea9e528..3dc241cc 100644 --- a/multipath/Makefile +++ b/multipath/Makefile @@ -24,6 +24,7 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so install: $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ + $(Q)$(INSTALL_PROGRAM) -m 755 mpathconf $(DESTDIR)$(bindir)/ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) $(Q)$(INSTALL_PROGRAM) -m 644 99-z-dm-mpath-late.rules $(DESTDIR)$(udevrulesdir) @@ -32,6 +33,7 @@ install: $(Q)$(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 + $(Q)$(INSTALL_PROGRAM) -m 644 mpathconf.8 $(DESTDIR)$(mandir)/man8 $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man5 $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(mandir)/man5 $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(modulesloaddir) @@ -46,12 +48,14 @@ endif uninstall: $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) + $(Q)$(RM) $(DESTDIR)$(bindir)/mpathconf $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/99-z-dm-mpath-late.rules $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 + $(Q)$(RM) $(DESTDIR)$(mandir)/man8/mpathconf.8 $(Q)$(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5 $(Q)$(RM) $(DESTDIR)$(tmpfilesdir)/multipath.conf diff --git a/multipath/mpathconf b/multipath/mpathconf new file mode 100644 index 00000000..ce430075 --- /dev/null +++ b/multipath/mpathconf @@ -0,0 +1,658 @@ +#!/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 HAVE_RECHECK_WWID RECHECK_WWID + +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 on +}" + +CONFIGFILE="/etc/multipath.conf" +OUTPUTFILE="/etc/multipath.conf" +MULTIPATHDIR="/etc/multipath" +TMPFILE="/etc/multipath/.multipath.conf.tmp" +WWIDS=0 + +function usage +{ + echo "usage: $0 " + echo "" + echo "Commands:" + echo "Enable: --enable " + echo "Disable: --disable" + echo "Only allow certain wwids (instead of enable): --allow " + echo "Set user_friendly_names (Default y): --user_friendly_names " + echo "Set find_multipaths (Default on): --find_multipaths " + echo "Set default property blacklist (Default n): --property_blacklist " + echo "Set enable_foreign to show foreign devices (Default n): --enable_foreign " + echo "Set recheck_wwid (Defaut n): --recheck_wwid " + echo "Add/Change/Remove option in defaults section: --option :" + echo "Load the dm-multipath modules on enable (Default y): --with_module " + echo "start/stop/reload multipathd (Default n): --with_multipathd " + echo "select output file (Default /etc/multipath.conf): --outfile " + 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 + ;; + --recheck_wwid) + if [ -n "$2" ]; then + RECHECK_WWID=$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" -o -n "$RECHECK_WWID" ]; then + echo "ignoring extra parameters on disable" + FRIENDLY="" + FIND="" + PROPERTY="" + MODULE="" + FOREIGN="" + OPTION_NAME="" + OPTION_VALUE="" + RECHECK_WWID="" + fi + if [ -n "$FRIENDLY" ] && [ "$FRIENDLY" != "y" -a "$FRIENDLY" != "n" ]; then + echo "--user_friendly_names must be either 'y' or 'n'" + exit 1 + fi + if [ -n "$RECHECK_WWID" ] && [ "$RECHECK_WWID" != "y" -a "$RECHECK_WWID" != "n" ]; then + echo "--recheck_wwid must be either 'y' or 'n'" + exit 1 + fi + if [ "$FIND" = "y" ]; then + FIND="on" + elif [ "$FIND" = "n" ]; then + FIND="off" + elif [ -n "$FIND" ] && [ "$FIND" != "on" -a "$FIND" != "yes" -a "$FIND" != "off" -a "$FIND" != "no" -a "$FIND" != "strict" -a "$FIND" != "greedy" -a "$FIND" != "smart" ]; then + echo "--find_multipaths must be one of 'on' 'yes' 'y' 'off' 'no' 'n' '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" -a -z "$RECHECK_WWID" ]; 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:]]*recheck_wwid[[:space:]][[:space:]]*\(yes\|1\)" ; then + HAVE_RECHECK_WWID=1 + elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*recheck_wwid[[:space:]][[:space:]]*\(no\|0\)" ; then + HAVE_RECHECK_WWID=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[[:space:]][[:space:]]*\"\^\$\"" ; then + HAVE_FOREIGN=2 + elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]][[:space:]]*\"NONE\"" ; then + HAVE_FOREIGN=2 + elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign" ; then + HAVE_FOREIGN=3 + 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 off" + 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_RECHECK_WWID" -o "$HAVE_RECHECK_WWID" = 0 ]; then + echo "recheck_wwid is disabled" + else + echo "recheck_wwid 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 (no foreign multipath devices will be shown)" + elif [ "$HAVE_FOREIGN" = 1 ]; then + echo "enable_foreign is set (all foreign multipath devices will be shown)" + elif [ "$HAVE_FOREIGN" = 2 ]; 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 [ "$RECHECK_WWID" = "n" ]; then + if [ "$HAVE_RECHECK_WWID" = 1 ]; then + sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*recheck_wwid[[:space:]][[:space:]]*\(yes\|1\)/ recheck_wwid no/' $TMPFILE + CHANGED_CONFIG=1 + fi +elif [ "$RECHECK_WWID" = "y" ]; then + if [ -z "$HAVE_RECHECK_WWID" ]; then + sed -i '/^defaults[[:space:]]*{/ a\ + recheck_wwid yes +' $TMPFILE + CHANGED_CONFIG=1 + elif [ "$HAVE_RECHECK_WWID" = 0 ]; then + sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*recheck_wwid[[:space:]][[:space:]]*\(no\|0\)/ recheck_wwid 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" -a -z "$HAVE_EXCEPTIONS" ]; then + cat >> $TMPFILE << _EOF_ + +blacklist_exceptions { + property "(SCSI_IDENT_|ID_WWN)" +} +_EOF_ + CHANGED_CONFIG=1 + elif [ -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" = "n" ]; then + if [ "$HAVE_FOREIGN" = 1 -o "$HAVE_FOREIGN" = 3 ]; then + sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*enable_foreign/# enable_foreign/' $TMPFILE + CHANGED_CONFIG=1 + fi +elif [ "$FOREIGN" = "y" ]; 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 -o "$HAVE_FOREIGN" = 3 ]; 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 diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8 new file mode 100644 index 00000000..ea025f31 --- /dev/null +++ b/multipath/mpathconf.8 @@ -0,0 +1,151 @@ +.TH MPATHCONF 8 "June 2010" "" "Linux Administrator's Manual" +.SH NAME +mpathconf - A tool for configuring device-mapper-multipath +.SH SYNOPSIS +.B mpathconf +.RB [\| commands \|] +.RB [\| options \|] +.SH DESCRIPTION +.B mpathconf +is a utility that creates or modifies +.B /etc/multipath.conf. +It can enable or disable multipathing and configure some common options. +.B mpathconf +can also load the +.B dm_multipath +module, start and stop the +.B multipathd +daemon, and configure the +.B multipathd +service to start automatically or not. If +.B mpathconf +is called with no commands, it will display the current configuration, but +will not create of modify +.B /etc/multipath.conf + +The default options for mpathconf are +.B --with_module +The +.B --with_multipathd +option is not set by default. Enabling multipathing will load the +.B dm_multipath +module but it will not immediately start it. This is so +that users can manually edit their config file if necessary, before starting +.B multipathd. + +If +.B /etc/multipath.conf +already exists, mpathconf will edit it. If it does not exist, mpathconf will +create a default file with +.B user_friendly_names +set and +.B find_multipaths +set to \fBon\fP. To disable these, use the +.B --user_friendly_names n +and +.B --find_multipaths off +options +.SH COMMANDS +.TP +.B --enable +Removes any line that blacklists all device nodes from the +.B /etc/multipath.conf +blacklist section. Also, creates +.B /etc/multipath.conf +if it doesn't exist. +.TP +.B --disable +Adds a line that blacklists all device nodes to the +.B /etc/multipath.conf +blacklist section. If no blacklist section exists, it will create one. +.TP +.B --allow \fB\fP +Modifies the \fB/etc/multipath/conf\fP blacklist to blacklist all +wwids and the blacklist_exceptions to whitelist \fB\fP. \fB\fP +can be in the form of MAJOR:MINOR, a wwid, or the name of a device-mapper +device, either a multipath device, or any device on stacked on top of one or +more multipath devices. This command can be used multiple times to allow +multiple devices. \fBNOTE:\fP This action will create a configuration file that +mpathconf will not be able to revert back to its previous state. Because +of this, \fB--outfile\fP is required when using \fB--allow\fP. +.TP +.B --user_friendly_names \fP { \fBy\fP | \fBn\fP } +If set to \fBy\fP, this adds the line +.B user_friendly_names yes +to the +.B /etc/multipath.conf +defaults section. If set to \fBn\fP, this removes the line, if present. This +command can be used along with any other command. +.TP +.B --recheck_wwid \fP { \fBy\fP | \fBn\fP } +If set to \fBy\fP, this adds the line +.B recheck_wwid yes +to the +.B /etc/multipath.conf +defaults section, or sets an existing line to \fByes\fP. If set to \fBn\fP, this +sets an existing \fBrecheck_wwid\fP line to \fBno\fP. This command can be used +along with any other command. +.TP +.B --find_multipaths\fP { \fBon\fP | \fByes\fP | \fBy\fP | \fBoff\fP | \fBno\fP | \fBn\fP | \fBstrict\fP | \fBgreedy\fP | \fBsmart\fP } +If set to \fB\fP, this adds the line +.B find_multipaths +to the +.B /etc/multipath.conf +defaults section. This command can be used along with any other command. +\fBy\fP and \fBn\fP can be used instead of \fByes\fP and \fBno\fP. +.TP +.B --property_blacklist \fP { \fBy\fP | \fBn\fP } +If set to \fBy\fP, this adds the line +.B property "(SCSI_IDENT_|ID_WWN)" +to the +.B /etc/multipath.conf +blacklist_exceptions section. If set to \fBn\fP, this removes the line, if +present. This command can be used along with any other command. +.TP +.B --enable_foreign\fP { \fBy\fP | \fBn\fP } +If set to \fBy\fP, this adds the line +.B enable_foreign ".*" +to the +.B /etc/multipath.conf +defaults section. if set to \fBn\fP, this removes the line, if present. This +command can be used along with any other command. +.TP +.B --option \fB:[]\fP +Sets the defaults section option \fB\fP to \fB\fP. If the +option was not previously set in the defaults section, it is added. If it was +set, its value is changed to \fB\fP. If \fB\fP is left blank, +then the option is removed from the defaults section, if was set there. This +command can be used along with any other command. +.TP +.B --outfile \fB\fP +Write the resulting multipath configuration to \fB\fP instead of +\fB/etc/multipath.conf\fP. +.SH OPTIONS +.TP +.B --with_module\fP { \fBy\fP | \fBn\fP } +If set to \fBy\fP, this runs +.B modprobe dm_multipath +to install the multipath modules. This option only works with the +.B --enable +command. This option is set to \fBy\fP by default. +.TP +.B --with_multipathd { \fBy\fP | \fBn\fP } +If set to \fBy\fP, this runs +.B service multipathd start +to start the multipathd daemon on \fB--enable\fP, +.B service multipathd stop +to stop the multipathd daemon on \fB--disable\fP, and +.B service multipathd reload +to reconfigure multipathd on \fB--user_frindly_names\fP and +\fB--find_multipaths\fP. +This option is set to \fBn\fP by default. +.SH FILES +.BR /etc/multipath.conf +.SH "SEE ALSO" +.BR multipath.conf (5), +.BR modprobe (8), +.BR multipath (8), +.BR multipathd (8), +.BR service (8), +.SH AUTHOR +Benjamin Marzinski