--- block-iscsi 2016-02-10 01:44:19.000000000 +1100 +++ block-iscsi-lock 2016-05-05 12:30:24.831903983 +1000 @@ -31,33 +31,37 @@ echo $1 | sed "s/^\("$2"\)//" } -check_tools() -{ - if ! command -v iscsiadm > /dev/null 2>&1; then - fatal "Unable to find iscsiadm tool" - fi - if [ "$multipath" = "y" ] && ! command -v multipath > /dev/null 2>&1; then - fatal "Unable to find multipath" - fi -} - # Sets the following global variables based on the params field passed in as # a parameter: iqn, portal, auth_method, user, multipath, password parse_target() { # set multipath default value multipath="n" - for param in $(echo "$1" | tr "," "\n") - do + for param in $(echo "$1" | tr "," "\n"); do case $param in iqn=*) iqn=$(remove_label $param "iqn=") + if ! command -v iscsiadm > /dev/null 2>&1; then + fatal "Could not find iscsiadm tool." + fi ;; portal=*) portal=$(remove_label $param "portal=") ;; multipath=*) multipath=$(remove_label $param "multipath=") + if ! command -v multipath > /dev/null 2>&1; then + fatal "Multipath selected, but no multipath tools found" + fi + ;; + locktarget=*) + locktarget=$(remove_label $param "locktarget=") + if ! command -v sg_persist > /dev/null 2>&1; then + fatal "Locking requested but no sg_persist found" + fi + if ! command -v gethostip > /dev/null 2>&1; then + fatal "Locking requested but no gethostip found for key generation" + fi ;; esac done @@ -96,38 +100,29 @@ fi } -# Attaches the target $iqn in $portal and sets $dev to point to the -# multipath device -attach() -{ - do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --login > /dev/null - find_device -} - -# Discovers targets in $portal and checks that $iqn is one of those targets -# Also sets the auth parameters to attach the device -prepare() -{ - # Check if target is already opened - iscsiadm -m session 2>&1 | grep -q "$iqn" && fatal "Device already opened" - # Discover portal targets - iscsiadm -m discovery -t st -p $portal 2>&1 | grep -q "$iqn" || \ - fatal "No matching target iqn found" -} -# Attaches the device and writes xenstore backend entries to connect -# the device -add() +lock_device() { - attach - write_dev $dev + ## Lock the iSCSI target as Exclusive Access. + key=$(gethostip -x $(uname -n)) + if ! sg_persist -d ${dev} -o -G -S ${key} > /dev/null; then + unlock_device + iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null + fatal "iSCSI LOCK: Failed to register with target" + fi + if ! sg_persist -d ${dev} -o -R -K ${key} -T 6 > /dev/null; then + unlock_device + iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null + fatal "iSCSI LOCK: Failed to set persistent reservation" + fi } -# Disconnects the device -remove() +unlock_device() { - find_device - do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null + ## Unlock the iSCSI target. + key=$(gethostip -x $(uname -n)) + sg_persist -d ${dev} -o -L -K ${key} -T 6 > /dev/null || true + sg_persist -d ${dev} -o -G -K ${key} -S 0 > /dev/null || true } command=$1 @@ -138,14 +133,27 @@ parse_target "$target" -check_tools || exit 1 - case $command in add) - prepare - add + # Check if target is already opened + iscsiadm -m session 2>&1 | grep -q "$iqn" && fatal "Device already opened" + # Discover portal targets + iscsiadm -m discovery -t st -p $portal 2>&1 | grep -q "$iqn" || \ + fatal "No matching target iqn found" + + ## Login to the iSCSI target. + do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --login > /dev/null + find_device + if [ "$locktarget" = "y" ]; then + lock_device + fi + write_dev $dev ;; remove) + if [ "$locktarget" = "y" ]; then + unlock_device + fi + do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null remove ;; *)