#!/bin/bash # # Copyright (C) Voltaire Ltd. 2006. ALL RIGHTS RESERVED. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # Author: Dan Bar Dov # iscsi_discovery: # * does a send-targets discovery to the given IP # * set the transport type to the preferred transport (or tcp is -t flag is not used) # * tries to login # * if succeeds, # o logout, # o mark record autmatic (unless -m flag is used) # * else # o reset transport type to TCP # o try to login # o if succeeded # + logout # + mark record automatic (unless -m flag is used) # usage() { echo "Usage: $0 [-p ] [-d] [-t [-f]] [-m] [-l]" echo "Options:" echo "-p set the port number (default is 3260)." echo "-d print debugging information" echo "-t set transport (default is tcp)." echo "-f force specific transport -disable the fallback to tcp (default is fallback enabled)." echo " force the transport specified by the argument of the -t flag." echo "-m manual startup - will set manual startup (default is automatic startup)." echo "-l login to the new discovered nodes (default is false)." } dbg() { $debug && echo $@ } initialize() { trap "exit" 2 debug=false force="0" log_out="1" startup_manual="0" #set default transport to tcp transport=tcp #set default port to 3260 port=3260; } parse_cmdline() { if [ $# -lt 1 ]; then usage exit 1 fi # check if the IP address is valid ip=`echo $1 | awk -F'.' '$1 != "" && $1 <=255 && $2 != "" && $2 <= 255 && $3 != "" && $3 <= 255 && $4 != "" && $4 <= 255 {print $0}'` if [ -z "$ip" ]; then echo "$1 is not a vaild IP address!" exit 1 fi shift while getopts "dfmlt:p:" options; do case $options in d ) debug=true;; f ) force="1";; t ) transport=$OPTARG;; p ) port=$OPTARG;; m ) startup_manual="1";; l ) log_out=0;; \? ) usage exit 1;; * ) usage exit 1;; esac done } discover() { # If open-iscsi is already logged in to the portal, exit if [ $(iscsiadm -m session | grep -c ${ip}:${port}) -ne 0 ]; then echo "Please logout from all targets on ${ip}:${port} before trying to run discovery on that portal" exit 2 fi connected=0 discovered=0 dbg "starting discovery to $ip" disc="$(iscsiadm -m discovery --type sendtargets --portal ${ip}:${port})" echo "${disc}" | while read portal target do portal=${portal%,*} select_transport done discovered=$(echo "${disc}" | wc -l) if [ ${discovered} = 0 ]; then echo "failed to discover targets at ${ip}" exit 2 else echo "discovered ${discovered} targets at ${ip}" fi } try_login() { if [ "$startup_manual" != "1" ]; then iscsiadm -m node --targetname ${target} --portal ${portal} --op update -n node.conn[0].startup -v automatic fi iscsiadm -m node --targetname ${target} --portal ${portal} --login >/dev/null 2>&1 ret=$? if [ ${ret} = 0 ]; then echo "Set target ${target} to automatic login over ${transport} to portal ${portal}" ((connected++)) if [ "$log_out" = "1" ]; then iscsiadm -m node --targetname ${target} --portal ${portal} --logout fi else echo "Cannot login over ${transport} to portal ${portal}" iscsiadm -m node --targetname ${target} --portal ${portal} --op update -n node.conn[0].startup -v manual fi return ${ret} } set_transport() { transport=$1 case "$transport" in iser) # iSER does not use digest iscsiadm -m node --targetname ${target} --portal ${portal} \ --op update -n node.conn[0].iscsi.HeaderDigest -v None iscsiadm -m node --targetname ${target} --portal ${portal} \ --op update -n node.conn[0].iscsi.DataDigest -v None ;; cxgb3i) # cxgb3i supports <= 16K packet (BHS + AHS + pdu payload + digests) iscsiadm -m node --targetname ${target} --portal ${portal} \ --op update -n node.conn[0].iscsi.MaxRecvDataSegmentLength \ -v 8192 ;; esac transport_name=`iscsiadm -m node -p ${portal} -T ${target} |awk '/transport_name/ {print $1}'` iscsiadm -m node --targetname ${target} --portal ${portal} \ --op update -n ${transport_name} -v ${transport} } select_transport() { set_transport $transport dbg "Testing $transport-login to target ${target} portal ${portal}" try_login; if [ $? != 0 -a "$force" = "0" ]; then set_transport tcp dbg "starting to test tcp-login to target ${target} portal ${portal}" try_login; fi } check_iscsid() { #check if iscsid is running pidof iscsid &>/dev/null ret=$? if [ $ret -ne 0 ]; then echo "iscsid is not running" echo "Exiting..." exit 1 fi } check_iscsid initialize parse_cmdline "$@" discover