#!/bin/ksh
# This program takes a list of wwwn's and using those will disable/enable all paths for all the hdisks
# this program is designed to work with AIX PCM/MPIO only. It uses the chpath command so the paths
# will still show up in lspath but they will be disabled. Inflight i/o will be allowed to complete
# new i/o will not be sent down.  You can never disable your last good path.

# useful commands:
# This command shows the path connection for one hdisk
# lspath -l hdisk4 -F"connection parent path_status path_id status" -H
#    connection         parent path_status path_id status

#    500507680140f263,0 fscsi1 Available   0       Enabled
#    500507680130f243,0 fscsi1 Available   1       Enabled
#    500507680120f263,0 fscsi1 Available   2       Enabled
#    500507680110f243,0 fscsi1 Available   3       Enabled

# Written by : Wayne Willcox
# Written on: Jan 2019
# Version:   1.2

#set -x

usage () {
   cat << EOF
      This program takes a list of wwwn's and using those will disable/enable all paths for all the hdisks
      this program is designed to work with AIX PCM/MPIO only. I use the chpath command so the paths
      will still show up in lspath but they will be disabled. Inflight i/o will be allowed to complete
      new i/o will not be sent down.  You can never disable your last good path.

      $0 [ -d ] [-e] [-t] [-a] [-D]
         -d is to disable the paths for all hdisks using paths to the list of targets
         -e is to enable the paths for all hdisks using paths to the list of targets
         -t is to show which paths and luns will be affected but will not actually change anything.
         -a to select an algorithm type.  This will require a reboot.
         -D This will instead of disabling the paths delete the paths.
 
      Here is an example of how to use this command.  
      If you don't know which target wwn you're going to remove you can run this command
          lspath -l hdisk4 -F"connection parent path_status path_id status" -H
      output:
          connection         parent path_status path_id status

          500507680140f263,0 fscsi1 Available   0       Enabled
          500507680130f243,0 fscsi1 Available   1       Enabled
          500507680120f263,0 fscsi1 Available   2       Enabled
          500507680110f243,0 fscsi1 Available   3       Enabled

      When you run the command the output will look like the following:
      # ./manage_paths -d 500507680140f263
      If this is what you want press y
      y
      going to disable all paths for these target wwwn's
             -- 500507680140f263
      chpath -l hdisk3 -s D -p fscsi0 -w 500507680140f263,2000000000000
      paths Changed
      chpath -l hdisk4 -s D -p fscsi1 -w 500507680140f263,0
      paths Changed
      chpath -l hdisk5 -s D -p fscsi1 -w 500507680140f263,1000000000000
      paths Changed
      chpath -l hdisk6 -s D -p fscsi1 -w 500507680140f263,2000000000000
      paths Changed

      You can verify that this command did disable the targets paths to all the luns with this command
      # lspath -l hdisk4 -F"connection parent path_status path_id status" -H              
      connection         parent path_status path_id status

      500507680140f263,0 fscsi1 Available   0       Disabled
      500507680130f243,0 fscsi1 Available   1       Enabled
      500507680120f263,0 fscsi1 Available   2       Enabled
      500507680110f243,0 fscsi1 Available   3       Enabled

      This command will take a list of wwn's so you can disable more then one target path at a time.
      disable or enable all paths for these target wwwns that use AIX PCM/MPIO.
      $0 takes a list of wwwn's and using those will disable/enable all paths for all the hdisks
      
      disable 2 targets:
      $0 -d disable 500507680140f263 500507680130f243

      to test which paths will be disabled for 2 targets:
      $0 -t -d 500507680140f263 500507680130f243
  
      re-enable the targets:
      $0 -e 500507680140f263 500507680130f243

      to test which paths will be enabled for 2 targets:
      $0 -t -e 500507680140f263 500507680130f243

      To set your algorythm you do the following:
      $0  -a shortest_queue -e 500507680140f263 500507680130f243
      

EOF
exit

}
DISABLE=0
ENABLE=0
DELETE=0
TEST=0

set -- `getopt dehtaD: $*`
for opt; do
    case "$opt" in
         -d) DISABLE=1;shift;;
         -D) DELETE=1;shift;;
         -e) ENABLE=1;shift;;
         -t) TEST=1; shift;;
         -a) QTYPE=$2;shift;;
         -h) usage;;
    esac
done

if [ ${DISABLE} -eq 0 ] && [ ${ENABLE} -eq 0 ] && [ ${TEST} -eq 0 ] && [ ${DELETE} -eq 0 ];then
    usage
fi

wwnpns=$@

echo "If this is what you want press y"
read answer
if [ ${answer} != "y" ];then
    echo "ok exiting without doing anything"
    exit
fi

> /tmp/wwwnfile

# get the list of paths and their connections.
lspath -HF "name path_id parent connection path_status status" >> /tmp/wwwnfile

#To disable the paths using the AIX PCM/MPIO:

if [ ${DISABLE} -eq 1 ];then
   echo "going to disable all paths for these target wwwn's"
   echo "       ${wwnpns}"
   for f in ${wwnpns};do
     while read name path_id parent connection path_status status;do
         echo "${connection}" |grep "${f}"  > /dev/null 2>&1

         if [ $? -eq 0 ];then
             if [ "${QTYPE}" != "" ];then
                 echo "chdev -l ${name} -a algorithm="${QTYPE}" -P"
                 if [ ${TEST} -ne 1 ];then
                     chdev -l ${name} -a algorithm="${QTYPE}" -P
                 fi
             fi
             echo chpath -l $name -s D -p $parent -w $connection

             # This will actually run the command 
              if [ ${TEST} -ne 1 ];then
                  echo "Now run the command and disable the path."
                  # only run the command if they are not testing the command
                  chpath -l $name -s D -p $parent -w $connection
              fi
         fi
     done < /tmp/wwwnfile
   done
   if [ ${TEST} -ne 0 ];then
       echo "	This was a test none of your paths were actually changed"
   fi
fi

#To remove the paths using the AIX PCM/MPIO:
if [ ${DELETE} -eq 1 ];then
   echo "going to delete all paths for these target wwwn's"
   echo "       ${wwnpns}"
   for f in ${wwnpns};do
       while read name path_id parent connection path_status status;do
         echo "${connection}" |grep "${f}"  > /dev/null 2>&1
         if [ $? -eq 0 ];then
             echo rmpath -dl $name -p $parent -w $connection -i $path_id

             # This will actually run the command 
              if [ ${TEST} -ne 1 ];then
                  echo "Now run the command and delete the path."
                  # only run the command if they are not testing the command
                  rmpath -dl $name -p $parent -w $connection -i $path_id
              fi
         fi
    
       done < /tmp/wwwnfile
   done
   if [ ${TEST} -ne 0 ];then
       echo "	This was a test none of your paths were actually changed"
   fi
fi

#To enable the paths using the AIX PCM/MPIO after the dimm replacement is done:
if [ ${ENABLE} -eq 1 ];then
   echo "going to enable all paths for these target wwwn's"
   echo "       ${wwnpns}"
   for f in ${wwnpns};do
      while read name path_id parent connection path_status status ;do
         echo ${connection} |grep "${f}"  > /dev/null 2>&1
         if [ $? -eq 0 ];then
             if [ "${QTYPE}" != "" ];then
                 echo "chdev -l ${name} -a algorithm="${QTYPE}" -P"
                 if [ ${TEST} -ne 1 ];then
                     chdev -l ${name} -a algorithm="${QTYPE}" -P
                 fi
             fi
             echo chpath -l $name -s E -p $parent -w $connection
             # uncomment the next line to disable the paths
              if [ ${TEST} -ne 1 ];then
                  # only run the command if they are not testing the command
                  chpath -l $name -s E -p $parent -w $connection
              fi
         fi
       done  < /tmp/wwwnfile
   done
fi


rm -f /tmp/wwwnfile
