File zfcp_disk_configure of Package s390-tools

#!/bin/sh
#
# zfcp_disk_configure
#
# Configures a zfcp disk
#
# Usage:
#   zfcp_disk_configure <ccwid> <wwpn> <lun> <online>
#
# Return codes
#   1  sysfs not mounted
#   2  invalid value for <online>
#   3  device <ccwid> does not exist
#   4  WWPN invalid
#   5  Could not activate WWPN for adapter
#   6  Could not activate ZFCP disk 
#   7  SCSI disk could not be deactivated
#   8  ZFCP LUN could not be deregistered
#   9  ZFCP WWPN could not be deregistered
#


mesg () {
    echo "$@"
}

debug_mesg () {
    case "$DEBUG" in
        yes) mesg "$@" ;;
        *) ;;
    esac
}

if [ $# -ne 4 ] ; then
    echo "Usage: $0  <ccwid> <wwpn> <lun> <online>"
    exit 1
fi

# Get the mount point for sysfs
while read MNTPT MNTDIR MNTSYS MNTTYPE; do
    if test "$MNTSYS" = "sysfs"; then
	SYSFS="$MNTDIR"
	break;
    fi 
done </proc/mounts

if [ -z "$SYSFS" ]; then
    exit 1
fi

CCW_CHAN_ID=$1
FCP_WWPN=${2#0x*}
FCP_LUN=${3#0x*}
ONLINE=$4
# normalise to lower case
FCP_WWPN=`echo $FCP_WWPN | sed 's/A/a/g;s/B/b/g;s/C/c/g;s/D/d/g;s/E/e/g;s/F/f/g'`
FCP_LUN=`echo $FCP_LUN | sed 's/A/a/g;s/B/b/g;s/C/c/g;s/D/d/g;s/E/e/g;s/F/f/g'`

DEBUG="yes"

if [ -z "$CCW_CHAN_ID" ] ; then
    debug_mesg "No CCW device specified"
    exit 1
fi

if [ -z "$ONLINE" ] || [ "$ONLINE" -ne "1" -a "$ONLINE" -ne "0" ]; then
    debug_mesg "Invalid device status $ONLINE"
    exit 2
fi

_ccw_dir=${SYSFS}/bus/ccw/devices

_zfcp_dir="$_ccw_dir/$CCW_CHAN_ID"

if test ! -d "$_zfcp_dir" ; then
    debug_mesg "No device ${CCW_CHAN_ID}"
    exit 3
fi

RULES_DIR=/etc/udev/rules.d
RULES_FILE=51-zfcp-${CCW_CHAN_ID}.rules

if [ ! -f ${RULES_DIR}/${RULES_FILE} ]; then
    debug_mesg "No configuration file for adapter ${CCW_CHAN_ID}"
fi

# Check whether we need to do something
if [ -d ${_zfcp_dir}/0x${FCP_WWPN}/0x${FCP_LUN} ]; then
    if [ "$ONLINE" -eq "1" ]; then
	debug_mesg "FCP disk ${FCP_WWPN}:${FCP_LUN} already configured"
	exit 0
    fi
else
    if [ "$ONLINE" -eq "0" ]; then
	debug_mesg "FCP disk ${FCP_WWPN}:${FCP_LUN} does not exist"
	exit 0
    fi
fi

debug_mesg "Configuring FCP disk ${FCP_WWPN}:${FCP_LUN}"

if [ "$ONLINE" -eq "1" ]; then
    # Check whether the wwpn exists
    _zfcp_wwpn_dir="${_zfcp_dir}/0x${FCP_WWPN}"
    if [ ! -d "${_zfcp_wwpn_dir}" ] ; then
	mesg "WWPN ${FCP_WWPN} for adapter ${CCW_CHAN_ID} not found"
	exit 5
    else
        # Check whether the WWPN is activated
        if [ `cat ${_zfcp_wwpn_dir}/failed` -eq "1" ] ; then
          mesg "WWPN ${FCP_WWPN} invalid."
          debug_mesg "WWPN ${FCP_WWPN} invalid."
          exit 4 
        fi
        # Check and configure the zfcp-lun
	if [ ! -d "${_zfcp_wwpn_dir}/0x${FCP_LUN}" ] ; then
	    echo "0x${FCP_LUN}" > ${_zfcp_wwpn_dir}/unit_add
	fi
	# Re-check whether the disk could be activated
	if [ ! -d "${_zfcp_wwpn_dir}/0x${FCP_LUN}" ] ; then
	    debug_mesg "Could not activate FCP disk ${FCP_WWPN}:${FCP_LUN}"
	    exit 6
	fi
    fi
else
    _zfcp_wwpn_dir="${_zfcp_dir}/0x${FCP_WWPN}"
    # Find the correspondig SCSI disk
    for host_dir in $_zfcp_dir/host*; do
	if [ -d $host_dir ] ; then
	    _zfcp_scsi_host_dir=$host_dir
	    break;
	fi
    done
    if [ -d "$_zfcp_scsi_host_dir" ] ; then
        # Deregister the disk from SCSI layer
	for target in $_zfcp_scsi_host_dir/rport-*/target*/* ; do
	    if [ -d $target ] ; then
		_zfcp_tmp_targid=${target##*/}
		read _zfcp_tmp_hba < ${target}/hba_id
		read _zfcp_tmp_wwpn < ${target}/wwpn
		read _zfcp_tmp_lun < ${target}/fcp_lun
		if [ "0x${FCP_LUN}" = "$_zfcp_tmp_lun" -a "0x${FCP_WWPN}" = "$_zfcp_tmp_wwpn" ] ; then
		    echo 1 > $target/delete
		    _zfcp_scsi_dir=$target
		    break;
		fi
	    fi
	done
	/sbin/udevadm settle
    else
	debug_mesg "No SCSI disk found for FCP disk ${FCP_WWPN}:${FCP_LUN}"
    fi

    # Re-check whether the SCSI disk is gone
    if [ -d "${_zfcp_scsi_dir}" ]; then
	debug_mesg "Could not deactivate SCSI disk ${_zfcp_scsi_id}"
	exit 7
    fi

    # Deconfigure the FCP_LUN
    echo "0x${FCP_LUN}" > ${_zfcp_wwpn_dir}/unit_remove
    if [ -d "${_zfcp_wwpn_dir}/0x${FCP_LUN}" ]; then
	debug_mesg "Could not deregister FCP LUN ${FCP_LUN}"
	exit 8
    fi

    # Find all remaining activated disks
    ZFCP_LUNS=
    for _tmp_wwpn_dir in ${_zfcp_dir}/0x*; do
	if [ -d "$_tmp_wwpn_dir" ]; then
	    tmp_wwpn=$(basename $_tmp_wwpn_dir)
	    # Find all luns
	    for _tmp_lun_dir in ${_tmp_wwpn_dir}/0x*; do
		if [ -d "$_tmp_lun_dir" ]; then
		    tmp_lun=$(basename $_tmp_lun_dir)
		    tmp_port="${tmp_wwpn}:${tmp_lun}"
		    ZFCP_LUNS="$ZFCP_LUNS
$tmp_port"
		fi
	    done
	fi
    done
fi

# And now update the rules file
if test -d ${RULES_DIR}; then
    # Find all WWPNs

    read online < ${_zfcp_dir}/online;
    if [ $online -eq 0 ] ; then
	exit 0
    fi

    for port in ${_zfcp_dir}/0x* ; do
	[ -d $port ] || continue;
	[ -w $port/unit_remove ] || continue;
	port_list="$port_list ${port##*/}"
    done

    cat > ${RULES_DIR}/${RULES_FILE} <<EOF
# Configure zFCP device at ${CCW_CHAN_ID}
ACTION=="add", SUBSYSTEM=="ccw", KERNEL=="$CCW_CHAN_ID", IMPORT{program}="collect $CCW_CHAN_ID %k $CCW_CHAN_ID zfcp"
ACTION=="add", SUBSYSTEM=="drivers", KERNEL=="zfcp", IMPORT{program}="collect $CCW_CHAN_ID %k $CCW_CHAN_ID zfcp"
ACTION=="add", ENV{COLLECT_$CCW_CHAN_ID}=="0", ATTR{[ccw/$CCW_CHAN_ID]online}="1"
EOF
    for port in $port_list; do
	for lun in ${_zfcp_dir}/$port/0x* ; do
	    [ -d $lun ] || continue;
	    [ -r $lun/status ] || continue;
	    cat >> ${RULES_DIR}/${RULES_FILE} <<EOF
ACTION=="add", KERNEL=="rport-*", ATTR{port_name}=="$port", SUBSYSTEMS=="ccw", KERNELS=="$CCW_CHAN_ID", ATTR{[ccw/$CCW_CHAN_ID]$port/unit_add}="${lun##*/}"
EOF
	done
    done
fi

# EOF