#!/bin/bash

ZFS_BASE=mpool/clients/iscsi
DEFAULT_TPG=TPG

function ask_yn {
    while true; do
        echo -n "$1 [Yes/No] "
        read yn
        case $yn in
        y* | Y* ) return 1 ; break ;;
        [nN]* )   return 0 ; break ;;
q* ) exit ;;
* )  ;;
esac;
done;
}

function zfs_exists {
  zfs list -rH $1 &> /dev/null
  if [ $? -eq 0 ]; then
    return 1;
  else
    return 0;
  fi;
}

function iqn_is_valid {
  stmfadm list-target $1 &> /dev/null
  if [ $? -eq 0 ]; then
    return 1;
  else
    return 0;
  fi;
}

function get_tg_by_iqn {
  IQN=$1
  TGS=`stmfadm list-tg | awk {'print $3'}`
  for TG in $TGS; do
    LINE_COUNT=`stmfadm list-tg -v $TG | grep $IQN | wc -l 2> /dev/null`
    if [ $LINE_COUNT -gt 0 ]; then
      SELECTED_TG=$TG
      return 0
    fi
  done
  return 1
}


function die {
  echo -e "\nERROR: $1\n       Will now exit.\n"
  exit
}

echo -e "\n"
echo "-----------------------------------------------------------------"
echo "ZFS / iSCSI / COMSTAR Simple Management Toolset"
echo "(c)Copyright 2009 Thoughtspace Ltd. Developed by Timothy Creswick"
echo "-----------------------------------------------------------------"
echo ""
echo "Please specify the name for the new ZFS backing store."
echo "Your new store will be created inside $ZFS_BASE"
echo -e "\nExisting backing stores are:"
zfs list -r $ZFS_BASE
echo -en "\nNew backing store: $ZFS_BASE/"
read ZFS_NAME
ZFS_FULL_NAME=$ZFS_BASE/$ZFS_NAME

zfs_exists $ZFS_FULL_NAME
if [ $? -eq 1 ]; then die "The ZFS name you specified is already in use."; fi

echo ""
ask_yn "Should the backing store be created as a sparse volume?";
if [ $? -eq 1 ]; then
  ZFLAGS=" -s"
  SPARSE_TXT=Yes
else
  ZFLAGS=""
  SPARSE_TXT=No
fi

echo -en "\nPlease enter the size of the backing store: ";
read ZFS_SIZE

echo -e "\nWill create a ZFS store with the following details:"
echo "  Name:    $ZFS_FULL_NAME"
echo "  Size:    $ZFS_SIZE"
echo "  Sparse:  $SPARSE_TXT"
echo ""
ask_yn "Proceed?";
if [ $? -eq 0 ]; then die "User cancelled."; fi

echo -en "\nCreating ZFS backing store... "
zfs create -V $ZFS_SIZE $ZFLAGS $ZFS_FULL_NAME
if [ $? -gt 0 ]; then die "Unable to create ZFS store. Check your parameters and try again."; fi
echo "OK";

echo -en "\nCreating the STMF LU... "
sbdadm create-lu /dev/zvol/rdsk/$ZFS_FULL_NAME &> /dev/null
if [ $? -gt 0 ]; then die "Unable to create the LU."; fi
sleep 2;
LUNAME=`sbdadm list-lu | grep /dev/zvol/rdsk/$ZFS_FULL_NAME | awk {'print $1'}`
echo "OK (GUID is $LUNAME)";

echo -e "\nYou can either attach this LU / device to an existing iSCSI target as a new LUN,"
echo      "or you can create a new iSCSI target and STMF target group for this ZFS backing"
echo      "store."
echo -e "\nIn general, you want to have a single iSCSI target per Virtual Machine, so if the"
echo      "virtual machine requires multiple disks, then you should attach each additional"
echo      "disk as a new LUN on an existing target."
echo -e "\nIf this is the first disk that you are attaching via iSCSI to the Virtual Machine"
echo      "you should create a new iSCSI / STMF target."
echo ""
ask_yn "Create a new iSCSI target?"
if [ $? -eq 1 ]; then

  echo -en "\nCreating iSCSI target... "
  ISCSI_TARGET=`itadm create-target -t $DEFAULT_TPG -l $ZFS_NAME  2> /dev/null | awk {'print $2'}`
  if [ "$ISCSI_TARGET" = "" ]; then die "Unable to create the iSCSI target, check the DEFAULT_TPG setting."; fi
  echo "OK ($ISCSI_TARGET)"

  echo -en "\nCreating STMF target group... "
  stmfadm create-tg $ZFS_NAME-tg &> /dev/null
  if [ $? -gt 0 ]; then die "Unable to create STMF target group."; fi
  echo "OK";

  echo -e "\nAssigning new iSCSI target to target group:"
  echo -n "  Waiting for STMF service to terminate..."
  svcadm disable stmf
  while [ `svcs -H system/stmf | awk {'print $1'}` != "disabled" ]; do sleep 1; echo -n "."; done
  echo " OK"
  echo -n "  Adding TG member... "
  stmfadm add-tg-member -g $ZFS_NAME-tg $ISCSI_TARGET &> /dev/null
  if [ $? -gt 0 ]; then die "Unable to add $ISCSI_TARGET to $ZFS_NAME-tg target group."; fi
  echo "OK";
  echo -n "  Starting STMF service..."
  svcadm enable stmf
  while [ `svcs -H system/stmf | awk {'print $1'}` != "online" ]; do sleep 1; echo -n "."; done
  echo " OK"

  SELECTED_TG=$ZFS_NAME-tg

else

  ISCSI_INVALID=1
  while [ $ISCSI_INVALID -gt 0 ]; do
    echo "Available targets are:"
    stmfadm list-target | awk {'print "  "$2'}
    echo -en "\nPlease specify target: "
    read ISCSI_TARGET
    if [ "$ISCSI_TARGET" != "" ]; then
      iqn_is_valid $ISCSI_TARGET
      if [ $? -eq 1 ]; then ISCSI_INVALID=0; else echo "ERROR: Invalid IQN specified. Please try again."; fi
    fi
  done

  echo -en "\nLocating specified IQN in target groups... "
  SELECTED_TG=0
  get_tg_by_iqn $ISCSI_TARGET
  if [ $? -gt 0 ]; then die "iSCSI target IQN $ISCSI_TARGET is not a member of any target groups."; fi
  echo "OK"

fi

echo -ne "\nAdding LU view to target group... "
stmfadm add-view -t $SELECTED_TG $LUNAME
if [ $? -gt 0 ]; then die "Unable to add LU $LUNAME to target group $SELECTED_TG."; fi

echo "OK";

echo -e "\nAll done. Your ZFS device should be available on target $ISCSI_TARGET.";

echo -e "\n\n"

