#!/bin/bash

# Usage: block-iscsi [add tgtname | remove dev]
#
# This assumes you're running a correctly configured 
# iscsi target (server) at the other end!
# Note that we assume that the passwords for discovery (if needed)
# are in /etc/iscsid.conf
# and the node session passwords (if required) in the
# open-iscsi database below /var/lib/open-iscsi/node.db
#
# (c) Kurt Garloff <kurt@garloff.de>, 2006-09-04, GNU GPL

dir=$(dirname "$0")
. "$dir/block-common.sh"
#command=$1

#echo "DBG:xen/scripts/block-iscsi $1 $2 XENBUS_PATH=$XENBUS_PATH $par $node"

#write_dev()
#{
#  echo "$1"
#}

sess_lun_to_bdev()
{
  unset dev
  cnt=`ls -d $1/device/target*/*:0:*:$2/block* | wc -l`
  nm=`ls -d $1/device/target*/*:0:*:$2/block*`
  for n in $nm; do
    d=`readlink $n`
    d=${d##*/}
    if test -z "$dev"; then dev=$d; else dev="$dev $d"; fi
  done
}

# Arguments: IQN name, LUN
find_sdev()
{
  unset dev
  lun=${2:-0}
  for session in /sys/class/iscsi_session/session*; do
    if ! test -e $session; then return; fi
    if test $1 = `cat $session/targetname`; then
      sess_lun_to_bdev $session $lun
      echo "fs: $1[$lun] ($cnt) -> $dev" 1>&2
      return
    fi
  done
} 

find_sdev_rev()
{
  unset tgt
  for session in /sys/class/iscsi_session/session*; do
    if ! test -e $session; then return; fi
    sess_lun_to_bdev $session "*"
    for d in $dev; do
      if test "$d" = "$1"; then
        tgt=`cat $session/targetname`
        echo "fsr: $2 -> $tgt ($cnt)" 1>&2
        return
      fi
    done
  done
}

case "$command" in
  add)
    # load modules and start iscsid
    /etc/init.d/open-iscsi status >/dev/null 2>&1 ||
      { /etc/init.d/open-iscsi start >/dev/null 2>&1; sleep 1; }
    # list of targets on node
    par=`xenstore-read $XENBUS_PATH/params` || true
    TGTID=$par; TGTID=${TGTID//@/:}
    LUN=${TGTID##*,}; TGTID=${TGTID%,*}
    if test $LUN = $TGTID; then unset LUN; fi
    #echo "add $TGTID lun $LUN" 1>&2
    while read rec port uuid; do
      if test $uuid = $TGTID; then
	rec=${rec%]}; rec=${rec#[}
	find_sdev $TGTID $LUN
	if test -z "$dev"; then
	  iscsiadm -m node -r $rec -l || exit 2
	  usleep 100000
	  find_sdev $TGTID $LUN
	fi
	xenstore-write $XENBUS_PATH/node /dev/$dev
        write_dev /dev/$dev
	exit 0
      fi
    done < <(iscsiadm -m node)
    exit 1
    ;;
  remove)
    node=`xenstore-read $XENBUS_PATH/node` || true
    dev=$node; dev=${dev#/dev/}
    find_sdev_rev $dev
    #echo $tgt
    if test -x /sbin/blockdev -a -n "$node"; then blockdev --flushbufs $node; fi
    test -z "$tgt" && exit 2
    while read rec port uuid; do
      if test $uuid = $tgt; then
	rec=${rec%]}; rec=${rec#[}
	iscsiadm -m node -r $rec -u
	exit 0
      fi
    done < <(iscsiadm -m node)
    exit 1
    ;;
esac
