File block-npiv of Package xen

#!/bin/bash

# Usage: block-npiv [add npiv | remove dev]

dir=$(dirname "$0")
. "$dir/block-npiv-common.sh"
. "$dir/block-common.sh"

#set -x
#command=$1

case "$command" in
  add)
    # Params is one big arg, with fields separated by hyphens:
    # single path: 
    #    VPWWPN-TGTWWPN-LUN#
    # multipath: 
    #    {VPWWPN1.VPWWPN2....VPWWPNx}-{TGTWWPN1.TGTWWPN2....TGTWWPNx}-LUN#
    #    arg 1 - VPORT's WWPN
    #    arg 2 - Target's WWPN
    #    arg 3 - LUN # on Target
    # no wwn contains a leading 0x - it is a 16 character hex value
    # You may want to optionally pick a specific adapter ?
    par=`xenstore-read $XENBUS_PATH/params` || true
    NPIVARGS=(${par//-/ })
    wc=${#NPIVARGS[@]}
    if [ $wc -eq 5 ]; then
      # support old syntax
      # FABRIC-VPWWPN-VPWWNN-TGTWWPN-LUN
      VPORTWWPNS=${NPIVARGS[1]}
      VPORTWWNNS=${NPIVARGS[2]}
      TGTWWPNS=${NPIVARGS[3]}
      LUN=${NPIVARGS[4]}
    elif [ $wc -eq 3 ]; then
      # new syntax
      VPORTWWPNS=${NPIVARGS[0]}
      TGTWWPNS=${NPIVARGS[1]}
      LUN=${NPIVARGS[2]}
    else
      # wrong syntax
      exit 1
    fi

    # Ensure we compare everything using lower-case hex characters
    TGTWWPNS=`echo $TGTWWPNS | tr A-Z a-z |sed 's/[{.}]/ /g'`
    VPORTWWPNS=`echo $VPORTWWPNS | tr A-Z a-z |sed 's/[{.}]/ /g'`
    # Only one VPWWNN is supported
    VPORTWWNN=`echo $VPORTWWNNS | tr A-Z a-z | sed -e 's/\..*//g' -e 's/{//'`

    claim_lock "npiv"
    paths=0
    for VPORTWWPN in $VPORTWWPNS; do
      find_vhost $VPORTWWPN
      if test -z "$vhost" ; then
        create_vport $VPORTWWPN $VPORTWWNN
        if [ $? -ne 0 ] ; then exit 2; fi
        sleep 8
        find_vhost $VPORTWWPN
        if test -z "$vhost" ; then exit 3; fi
      fi
      for TGTWWPN in $TGTWWPNS; do
        find_sdev $vhost $TGTWWPN $LUN
        if test -z "$dev"; then
          echo "- - -" > /sys/class/scsi_host/$vhost/scan
          sleep 2
          find_sdev $vhost $TGTWWPN $LUN
        fi
        if test -z "$dev"; then
          exit 4
	fi
        paths=$(($paths+1))
      done
    done
    release_lock "npiv"

    if test $paths -gt 1; then
      xenstore-write $XENBUS_PATH/multipath 1
      /etc/init.d/multipathd start
      if test $? -ne 0 ; then exit 4; fi
      dm=`multipath -l /dev/$dev | grep dm | cut -f2 -d' '`
    else
      xenstore-write $XENBUS_PATH/multipath 0
      dm=$dev
    fi
    
    if test ! -z "$dm"; then
      xenstore-write $XENBUS_PATH/node /dev/$dm
      write_dev /dev/$dm
      exit 0
    fi

    exit 4
    ;;

  remove)
    node=`xenstore-read $XENBUS_PATH/node` || true
    multipath=`xenstore-read $XENBUS_PATH/multipath` || true
    # this is really screwy. the first delete of a lun will
    # terminate the entire vport (all luns)
    if test $multipath = 1; then
      par=`xenstore-read $XENBUS_PATH/params` || true
      NPIVARGS=(${par//-/ })
      wc=${#NPIVARGS[@]}
      if [ $wc -eq 5 ]; then
        # old syntax
        # FABRIC-VPWWPN-VPWWNN-TGTWWPN-LUN
        VPORTWWPNS=${NPIVARGS[1]}
      elif [ $wc -eq 3 ]; then
        # new syntax
        VPORTWWPNS=${NPIVARGS[0]}
      fi
      VPORTWWPNS=`echo $VPORTWWPNS | tr A-Z a-z |sed 's/[{.}]/ /g'`
      for VPORTWWPN in $VPORTWWPNS; do
        find_vhost $VPORTWWPN
        if test -z "$vhost" ; then exit 5; fi
        flush_nodes_on_vhost $vhost
        delete_vhost $vhost
      done
    else
      dev=$node; dev=${dev#/dev/}
      find_vhost_from_dev $dev
      if test -z "$vhost" ; then exit 5; fi
      flush_nodes_on_vhost $vhost
      delete_vhost $vhost
    fi

    exit 0
    ;;
esac
openSUSE Build Service is sponsored by