You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1536 lines
54 KiB

From d4a36f47b36f47a847795660653b7fbc5baab706 Mon Sep 17 00:00:00 2001
From: David Vossel <dvossel@redhat.com>
Date: Mon, 25 Aug 2014 14:55:50 -0500
Subject: [PATCH 1/4] iscsi agent updates
---
heartbeat/iSCSILogicalUnit | 573 ++++++++++++++++++++++-----------------
heartbeat/iSCSITarget | 661 +++++++++++++++++++++++++--------------------
2 files changed, 690 insertions(+), 544 deletions(-)
diff --git a/heartbeat/iSCSILogicalUnit b/heartbeat/iSCSILogicalUnit
index 0ab4722..c4cee0d 100755
--- a/heartbeat/iSCSILogicalUnit
+++ b/heartbeat/iSCSILogicalUnit
@@ -3,10 +3,10 @@
#
# iSCSILogicalUnit OCF RA. Exports and manages iSCSI Logical Units.
#
-# (c) 2013 LINBIT, Lars Ellenberg
+# (c) 2013 LINBIT, Lars Ellenberg
# (c) 2009-2010 Florian Haas, Dejan Muhamedagic,
-# and Linux-HA contributors
-#
+# and Linux-HA contributors
+#
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as
@@ -36,11 +36,13 @@
# Defaults
# Set a default implementation based on software installed
if have_binary ietadm; then
- OCF_RESKEY_implementation_default="iet"
+ OCF_RESKEY_implementation_default="iet"
elif have_binary tgtadm; then
- OCF_RESKEY_implementation_default="tgt"
+ OCF_RESKEY_implementation_default="tgt"
elif have_binary lio_node; then
- OCF_RESKEY_implementation_default="lio"
+ OCF_RESKEY_implementation_default="lio"
+elif have_binary targetcli; then
+ OCF_RESKEY_implementation_default="lio-t"
fi
: ${OCF_RESKEY_implementation=${OCF_RESKEY_implementation_default}}
@@ -91,9 +93,9 @@ an SCSI Target, exported via a daemon that speaks the iSCSI protocol.
<parameter name="implementation" required="0" unique="0">
<longdesc lang="en">
The iSCSI target daemon implementation. Must be one of "iet", "tgt",
-or "lio". If unspecified, an implementation is selected based on the
+"lio", or "lio-t". If unspecified, an implementation is selected based on the
availability of management utilities, with "iet" being tried first,
-then "tgt", then "lio".
+then "tgt", then "lio", then "lio-t".
</longdesc>
<shortdesc lang="en">iSCSI target daemon implementation</shortdesc>
<content type="string" default="${OCF_RESKEY_implementation_default}"/>
@@ -228,12 +230,12 @@ in /sys/kernel/config/target/core/.
</parameters>
<actions>
-<action name="start" timeout="10" />
-<action name="stop" timeout="10" />
-<action name="status" timeout="10" interval="10" depth="0" />
-<action name="monitor" timeout="10" interval="10" depth="0" />
-<action name="meta-data" timeout="5" />
-<action name="validate-all" timeout="10" />
+<action name="start" timeout="10" />
+<action name="stop" timeout="10" />
+<action name="status" timeout="10" interval="10" depth="0" />
+<action name="monitor" timeout="10" interval="10" depth="0" />
+<action name="meta-data" timeout="5" />
+<action name="validate-all" timeout="10" />
</actions>
</resource-agent>
END
@@ -250,108 +252,150 @@ END
}
iSCSILogicalUnit_start() {
- iSCSILogicalUnit_monitor
- if [ $? = $OCF_SUCCESS ]; then
- return $OCF_SUCCESS
- fi
+ iSCSILogicalUnit_monitor
+ if [ $? = $OCF_SUCCESS ]; then
+ return $OCF_SUCCESS
+ fi
- local params
+ local params
- case $OCF_RESKEY_implementation in
+ case $OCF_RESKEY_implementation in
iet)
- params="Path=${OCF_RESKEY_path}"
- # use blockio if path points to a block device, fileio
- # otherwise.
- if [ -b "${OCF_RESKEY_path}" ]; then
- params="${params} Type=blockio"
- else
- params="${params} Type=fileio"
- fi
- # in IET, we have to set LU parameters on creation
- if [ -n "${OCF_RESKEY_scsi_id}" ]; then
- params="${params} ScsiId=${OCF_RESKEY_scsi_id}"
- fi
- if [ -n "${OCF_RESKEY_scsi_sn}" ]; then
- params="${params} ScsiSN=${OCF_RESKEY_scsi_sn}"
- fi
- params="${params} ${OCF_RESKEY_additional_parameters}"
- ocf_run ietadm --op new \
- --tid=${TID} \
- --lun=${OCF_RESKEY_lun} \
- --params ${params// /,} || exit $OCF_ERR_GENERIC
- ;;
+ params="Path=${OCF_RESKEY_path}"
+ # use blockio if path points to a block device, fileio
+ # otherwise.
+ if [ -b "${OCF_RESKEY_path}" ]; then
+ params="${params} Type=blockio"
+ else
+ params="${params} Type=fileio"
+ fi
+ # in IET, we have to set LU parameters on creation
+ if [ -n "${OCF_RESKEY_scsi_id}" ]; then
+ params="${params} ScsiId=${OCF_RESKEY_scsi_id}"
+ fi
+ if [ -n "${OCF_RESKEY_scsi_sn}" ]; then
+ params="${params} ScsiSN=${OCF_RESKEY_scsi_sn}"
+ fi
+ params="${params} ${OCF_RESKEY_additional_parameters}"
+ ocf_run ietadm --op new \
+ --tid=${TID} \
+ --lun=${OCF_RESKEY_lun} \
+ --params ${params// /,} || exit $OCF_ERR_GENERIC
+ ;;
tgt)
- # tgt requires that we create the LU first, then set LU
- # parameters
- params=""
- local var
- local envar
- for var in scsi_id scsi_sn vendor_id product_id; do
- envar="OCF_RESKEY_${var}"
- if [ -n "${!envar}" ]; then
- params="${params} ${var}=${!envar}"
+ # tgt requires that we create the LU first, then set LU
+ # parameters
+ params=""
+ local var
+ local envar
+ for var in scsi_id scsi_sn vendor_id product_id; do
+ envar="OCF_RESKEY_${var}"
+ if [ -n "${!envar}" ]; then
+ params="${params} ${var}=${!envar}"
+ fi
+ done
+ params="${params} ${OCF_RESKEY_additional_parameters}"
+
+ # cleanup: tgt (as of tgtadm version 1.0.24) does not like an explicit "bsoflags=direct"
+ # when used with "bstype=aio" (which always uses O_DIRECT)
+ [[ $OCF_RESKEY_tgt_bstype/$OCF_RESKEY_tgt_bsoflags = "aio/direct" ]] && OCF_RESKEY_tgt_bsoflags=""
+
+ tgt_args=""
+ [[ $OCF_RESKEY_tgt_bstype ]] && tgt_args="$tgt_args --bstype=$OCF_RESKEY_tgt_bstype"
+ [[ $OCF_RESKEY_tgt_bsoflags ]] && tgt_args="$tgt_args --bsoflags=$OCF_RESKEY_tgt_bsoflags"
+ [[ $OCF_RESKEY_tgt_device_type ]] && tgt_args="$tgt_args --device-type=$OCF_RESKEY_tgt_device_type"
+
+ ocf_run tgtadm --lld iscsi --op new --mode logicalunit \
+ --tid=${TID} \
+ --lun=${OCF_RESKEY_lun} \
+ $tgt_args \
+ --backing-store ${OCF_RESKEY_path} || exit $OCF_ERR_GENERIC
+ if [ -z "$params" ]; then
+ return $OCF_SUCCESS
+ else
+ ocf_run tgtadm --lld iscsi --op update --mode logicalunit \
+ --tid=${TID} \
+ --lun=${OCF_RESKEY_lun} \
+ --params ${params// /,} || exit $OCF_ERR_GENERIC
+ fi
+ ;;
+ lio)
+ # For lio, we first have to create a target device, then
+ # add it to the Target Portal Group as an LU.
+
+ block_configfs_path="/sys/kernel/config/target/core/iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESOURCE_INSTANCE}/udev_path"
+ if [ ! -e "${block_configfs_path}" ]; then
+ ocf_run tcm_node --createdev=iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESOURCE_INSTANCE} \
+ ${OCF_RESKEY_path} || exit $OCF_ERR_GENERIC
+ elif [ -e "$block_configfs_path" ] && [ $(cat "$block_configfs_path") != "${OCF_RESKEY_path}" ]; then
+ ocf_exit_reason "Existing iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESOURCE_INSTANCE} has incorrect path: $(cat "$block_configfs_path") != ${OCF_RESKEY_path}"
+ exit $OCF_ERR_GENERIC
+ else
+ ocf_log info "iscsi iblock already exists: ${block_configfs_path}"
fi
- done
- params="${params} ${OCF_RESKEY_additional_parameters}"
- # cleanup: tgt (as of tgtadm version 1.0.24) does not like an explicit "bsoflags=direct"
- # when used with "bstype=aio" (which always uses O_DIRECT)
- [[ $OCF_RESKEY_tgt_bstype/$OCF_RESKEY_tgt_bsoflags = "aio/direct" ]] && OCF_RESKEY_tgt_bsoflags=""
+ if [ -n "${OCF_RESKEY_scsi_sn}" ]; then
+ ocf_run tcm_node --setunitserial=iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESOURCE_INSTANCE} \
+ ${OCF_RESKEY_scsi_sn} || exit $OCF_ERR_GENERIC
+ fi
- tgt_args=""
- [[ $OCF_RESKEY_tgt_bstype ]] && tgt_args="$tgt_args --bstype=$OCF_RESKEY_tgt_bstype"
- [[ $OCF_RESKEY_tgt_bsoflags ]] && tgt_args="$tgt_args --bsoflags=$OCF_RESKEY_tgt_bsoflags"
- [[ $OCF_RESKEY_tgt_device_type ]] && tgt_args="$tgt_args --device-type=$OCF_RESKEY_tgt_device_type"
+ lun_configfs_path="/sys/kernel/config/target/iscsi/${OCF_RESKEY_target_iqn}/tpgt_1/lun/lun_${OCF_RESKEY_lun}/${OCF_RESOURCE_INSTANCE}/udev_path"
+ if [ ! -e "${lun_configfs_path}" ]; then
+ ocf_run lio_node --addlun=${OCF_RESKEY_target_iqn} 1 ${OCF_RESKEY_lun} \
+ ${OCF_RESOURCE_INSTANCE} iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESOURCE_INSTANCE} || exit $OCF_ERR_GENERIC
+ else
+ ocf_log info "iscsi lun already exists: ${lun_configfs_path}"
+ fi
- ocf_run tgtadm --lld iscsi --op new --mode logicalunit \
- --tid=${TID} \
- --lun=${OCF_RESKEY_lun} \
- $tgt_args \
- --backing-store ${OCF_RESKEY_path} || exit $OCF_ERR_GENERIC
- if [ -z "$params" ]; then
- return $OCF_SUCCESS
- else
- ocf_run tgtadm --lld iscsi --op update --mode logicalunit \
- --tid=${TID} \
- --lun=${OCF_RESKEY_lun} \
- --params ${params// /,} || exit $OCF_ERR_GENERIC
- fi
- ;;
- lio)
- # For lio, we first have to create a target device, then
- # add it to the Target Portal Group as an LU.
- ocf_run tcm_node --createdev=iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESOURCE_INSTANCE} \
- ${OCF_RESKEY_path} || exit $OCF_ERR_GENERIC
- if [ -n "${OCF_RESKEY_scsi_sn}" ]; then
- ocf_run tcm_node --setunitserial=iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESOURCE_INSTANCE} \
- ${OCF_RESKEY_scsi_sn} || exit $OCF_ERR_GENERIC
- fi
- ocf_run lio_node --addlun=${OCF_RESKEY_target_iqn} 1 ${OCF_RESKEY_lun} \
- ${OCF_RESOURCE_INSTANCE} iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESOURCE_INSTANCE} || exit $OCF_ERR_GENERIC
-
- if [ -n "${OCF_RESKEY_allowed_initiators}" ]; then
- for initiator in ${OCF_RESKEY_allowed_initiators}; do
- ocf_run lio_node --addlunacl=${OCF_RESKEY_target_iqn} 1 \
- ${initiator} ${OCF_RESKEY_lun} ${OCF_RESKEY_lun} || exit $OCF_ERR_GENERIC
- done
- fi
- ;;
- esac
-
- return $OCF_SUCCESS
+ if [ -n "${OCF_RESKEY_allowed_initiators}" ]; then
+ for initiator in ${OCF_RESKEY_allowed_initiators}; do
+ acl_configfs_path="/sys/kernel/config/target/iscsi/${OCF_RESKEY_target_iqn}/tpgt_1/acls/${initiator}/lun_${OCF_RESKEY_lun}"
+ if [ ! -e "${acl_configfs_path}" ]; then
+ ocf_run lio_node --addlunacl=${OCF_RESKEY_target_iqn} 1 \
+ ${initiator} ${OCF_RESKEY_lun} ${OCF_RESKEY_lun} || exit $OCF_ERR_GENERIC
+ else
+ ocf_log info "iscsi acl already exists: ${acl_configfs_path}"
+ fi
+ done
+ fi
+ ;;
+ lio-t)
+ # For lio, we first have to create a target device, then
+ # add it to the Target Portal Group as an LU.
+ ocf_run targetcli /backstores/block create name=${OCF_RESOURCE_INSTANCE} dev=${OCF_RESKEY_path} write_back=False || exit $OCF_ERR_GENERIC
+ if [ -n "${OCF_RESKEY_scsi_sn}" ]; then
+ echo ${OCF_RESKEY_scsi_sn} > /sys/kernel/config/target/core/iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESOURCE_INSTANCE}/wwn/vpd_unit_serial
+ fi
+ ocf_run targetcli /iscsi/${OCF_RESKEY_target_iqn}/tpg1/luns create /backstores/block/${OCF_RESOURCE_INSTANCE} ${OCF_RESKEY_lun} || exit $OCF_ERR_GENERIC
+
+ if [ -n "${OCF_RESKEY_allowed_initiators}" ]; then
+ for initiator in ${OCF_RESKEY_allowed_initiators}; do
+ ocf_run targetcli /iscsi/${OCF_RESKEY_target_iqn}/tpg1/acls create ${initiator} add_mapped_luns=False || exit $OCF_ERR_GENERIC
+ ocf_run targetcli /iscsi/${OCF_RESKEY_target_iqn}/tpg1/acls/${initiator} create ${OCF_RESKEY_lun} ${OCF_RESKEY_lun} || exit $OCF_ERR_GENERIC
+ done
+ fi
+ ;;
+ esac
+
+ # Force the monitor operation to pass before start is considered a success.
+ iSCSILogicalUnit_monitor
}
iSCSILogicalUnit_stop() {
- iSCSILogicalUnit_monitor
- if [ $? = $OCF_SUCCESS ]; then
+ iSCSILogicalUnit_monitor
+ if [ $? -eq $OCF_NOT_RUNNING ]; then
+ return $OCF_SUCCESS
+ fi
+
case $OCF_RESKEY_implementation in
- iet)
- # IET allows us to remove LUs while they are in use
- ocf_run ietadm --op delete \
- --tid=${TID} \
- --lun=${OCF_RESKEY_lun} || exit $OCF_ERR_GENERIC
+
+ iet)
+ # IET allows us to remove LUs while they are in use
+ ocf_run ietadm --op delete \
+ --tid=${TID} \
+ --lun=${OCF_RESKEY_lun} || exit $OCF_ERR_GENERIC
;;
- tgt)
+ tgt)
# tgt will fail to remove an LU while it is in use,
# but at the same time does not allow us to
# selectively shut down a connection that is using a
@@ -359,202 +403,240 @@ iSCSILogicalUnit_stop() {
# decides that the LU is no longer in use, or we get
# timed out by the LRM.
while ! ocf_run -warn tgtadm --lld iscsi --op delete --mode logicalunit \
- --tid ${TID} \
- --lun=${OCF_RESKEY_lun}; do
- sleep 1
+ --tid ${TID} \
+ --lun=${OCF_RESKEY_lun}; do
+ sleep 1
+ done
+ ;;
+ lio)
+
+ acls_configfs_path="/sys/kernel/config/target/iscsi/${OCF_RESKEY_target_iqn}/tpgt_1/acls"
+ for initiatorpath in ${acls_configfs_path}/*; do
+ initiator=$(basename "${initiatorpath}")
+ if [ -e "${initiatorpath}/lun_${OCF_RESKEY_lun}" ]; then
+ ocf_log info "deleting acl at ${initiatorpath}/lun_${OCF_RESKEY_lun}"
+ ocf_run lio_node --dellunacl=${OCF_RESKEY_target_iqn} 1 \
+ ${initiator} ${OCF_RESKEY_lun} || exit $OCF_ERR_GENERIC
+ fi
done
+ lun_configfs_path="/sys/kernel/config/target/iscsi/${OCF_RESKEY_target_iqn}/tpgt_1/lun/lun_#{${OCF_RESKEY_lun}/"
+ if [ -e "${lun_configfs_path}" ]; then
+ ocf_run lio_node --dellun=${OCF_RESKEY_target_iqn} 1 ${OCF_RESKEY_lun} || exit $OCF_ERR_GENERIC
+ fi
+ block_configfs_path="/sys/kernel/config/target/core/iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESKEY_INSTANCE}/udev_path"
+ if [ -e "${block_configfs_path}" ]; then
+ ocf_run tcm_node --freedev=iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESOURCE_INSTANCE} || exit $OCF_ERR_GENERIC
+ fi
+ ;;
+ lio-t)
+ ocf_run targetcli /iscsi/${OCF_RESKEY_target_iqn}/tpg1/luns delete ${OCF_RESKEY_lun} || exit $OCF_ERR_GENERIC
+ if [ -n "${OCF_RESKEY_allowed_initiators}" ]; then
+ for initiator in ${OCF_RESKEY_allowed_initiators}; do
+ if targetcli /iscsi/${OCF_RESKEY_target_iqn}/tpg1/acls/${initiator} status | grep "Mapped LUNs: 0" >/dev/null ; then
+ ocf_run targetcli /iscsi/${OCF_RESKEY_target_iqn}/tpg1/acls/ delete ${initiator}
+ fi
+ done
+ fi
+
+ ocf_run targetcli /backstores/block delete ${OCF_RESOURCE_INSTANCE} || exit $OCF_ERR_GENERIC
;;
- lio)
- if [ -n "${OCF_RESKEY_allowed_initiators}" ]; then
- for initiator in ${OCF_RESKEY_allowed_initiators}; do
- ocf_run lio_node --dellunacl=${OCF_RESKEY_target_iqn} 1 \
- ${initiator} ${OCF_RESKEY_lun} || exit $OCF_ERR_GENERIC
- done
- fi
- ocf_run lio_node --dellun=${OCF_RESKEY_target_iqn} 1 ${OCF_RESKEY_lun} || exit $OCF_ERR_GENERIC
- ocf_run tcm_node --freedev=iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESOURCE_INSTANCE} || exit $OCF_ERR_GENERIC
esac
- fi
-
- return $OCF_SUCCESS
+
+ return $OCF_SUCCESS
}
iSCSILogicalUnit_monitor() {
- case $OCF_RESKEY_implementation in
+ case $OCF_RESKEY_implementation in
iet)
- # Figure out and set the target ID
- TID=`sed -ne "s/tid:\([[:digit:]]\+\) name:${OCF_RESKEY_target_iqn}$/\1/p" < /proc/net/iet/volume`
- if [ -z "${TID}" ]; then
- # Our target is not configured, thus we're not
- # running.
- return $OCF_NOT_RUNNING
- fi
- # FIXME: this looks for a matching LUN and path, but does
- # not actually test for the correct target ID.
- grep -E -q "[[:space:]]+lun:${OCF_RESKEY_lun}.*path:${OCF_RESKEY_path}$" /proc/net/iet/volume && return $OCF_SUCCESS
- ;;
+ # Figure out and set the target ID
+ TID=`sed -ne "s/tid:\([[:digit:]]\+\) name:${OCF_RESKEY_target_iqn}$/\1/p" < /proc/net/iet/volume`
+ if [ -z "${TID}" ]; then
+ # Our target is not configured, thus we're not
+ # running.
+ return $OCF_NOT_RUNNING
+ fi
+ # FIXME: this looks for a matching LUN and path, but does
+ # not actually test for the correct target ID.
+ grep -E -q "[[:space:]]+lun:${OCF_RESKEY_lun}.*path:${OCF_RESKEY_path}$" /proc/net/iet/volume && return $OCF_SUCCESS
+ ;;
tgt)
- # Figure out and set the target ID
- TID=`tgtadm --lld iscsi --op show --mode target \
- | sed -ne "s/^Target \([[:digit:]]\+\): ${OCF_RESKEY_target_iqn}$/\1/p"`
- if [ -z "$TID" ]; then
- # Our target is not configured, thus we're not
- # running.
- return $OCF_NOT_RUNNING
- fi
- # This only looks for the backing store, but does not test
- # for the correct target ID and LUN.
- tgtadm --lld iscsi --op show --mode target \
- | grep -E -q "[[:space:]]+Backing store.*: ${OCF_RESKEY_path}$" && return $OCF_SUCCESS
- ;;
+ # Figure out and set the target ID
+ TID=`tgtadm --lld iscsi --op show --mode target \
+ | sed -ne "s/^Target \([[:digit:]]\+\): ${OCF_RESKEY_target_iqn}$/\1/p"`
+ if [ -z "$TID" ]; then
+ # Our target is not configured, thus we're not
+ # running.
+ return $OCF_NOT_RUNNING
+ fi
+ # This only looks for the backing store, but does not test
+ # for the correct target ID and LUN.
+ tgtadm --lld iscsi --op show --mode target \
+ | grep -E -q "[[:space:]]+Backing store.*: ${OCF_RESKEY_path}$" && return $OCF_SUCCESS
+ ;;
lio)
- configfs_path="/sys/kernel/config/target/iscsi/${OCF_RESKEY_target_iqn}/tpgt_1/lun/lun_${OCF_RESKEY_lun}/${OCF_RESOURCE_INSTANCE}/udev_path"
- [ -e ${configfs_path} ] && [ `cat ${configfs_path}` = "${OCF_RESKEY_path}" ] && return $OCF_SUCCESS
- ;;
- esac
-
- return $OCF_NOT_RUNNING
+ configfs_path="/sys/kernel/config/target/iscsi/${OCF_RESKEY_target_iqn}/tpgt_1/lun/lun_${OCF_RESKEY_lun}/${OCF_RESOURCE_INSTANCE}/udev_path"
+ [ -e ${configfs_path} ] && [ `cat ${configfs_path}` = "${OCF_RESKEY_path}" ] && return $OCF_SUCCESS
+
+ # if we aren't activated, is a block device still left over?
+ block_configfs_path="/sys/kernel/config/target/core/iblock_${OCF_RESKEY_lio_iblock}/${OCF_RESKEY_INSTANCE}/udev_path"
+ [ -e ${block_configfs_path} ] && ocf_log warn "existing block without an active lun: ${block_configfs_path}"
+ [ -e ${block_configfs_path} ] && return $OCF_ERR_GENERIC
+
+ ;;
+ lio-t)
+ configfs_path="/sys/kernel/config/target/iscsi/${OCF_RESKEY_target_iqn}/tpgt_1/lun/lun_${OCF_RESKEY_lun}/*/udev_path"
+ [ -e ${configfs_path} ] && [ `cat ${configfs_path}` = "${OCF_RESKEY_path}" ] && return $OCF_SUCCESS
+ ;;
+ esac
+
+ return $OCF_NOT_RUNNING
}
iSCSILogicalUnit_validate() {
- # Do we have all required variables?
- for var in target_iqn lun path; do
+ # Do we have all required variables?
+ for var in target_iqn lun path; do
param="OCF_RESKEY_${var}"
if [ -z "${!param}" ]; then
- ocf_log error "Missing resource parameter \"$var\"!"
- exit $OCF_ERR_CONFIGURED
+ ocf_exit_reason "Missing resource parameter \"$var\"!"
+ exit $OCF_ERR_CONFIGURED
fi
- done
+ done
- # Is the configured implementation supported?
- case "$OCF_RESKEY_implementation" in
- "iet"|"tgt"|"lio")
- ;;
+ # Is the configured implementation supported?
+ case "$OCF_RESKEY_implementation" in
+ "iet"|"tgt"|"lio"|"lio-t")
+ ;;
"")
- # The user didn't specify an implementation, and we were
- # unable to determine one from installed binaries (in
- # other words: no binaries for any supported
- # implementation could be found)
- ocf_log error "Undefined iSCSI target implementation"
- exit $OCF_ERR_INSTALLED
- ;;
+ # The user didn't specify an implementation, and we were
+ # unable to determine one from installed binaries (in
+ # other words: no binaries for any supported
+ # implementation could be found)
+ ocf_exit_reason "Undefined iSCSI target implementation"
+ exit $OCF_ERR_INSTALLED
+ ;;
*)
- ocf_log error "Unsupported iSCSI target implementation \"$OCF_RESKEY_implementation\"!"
- exit $OCF_ERR_CONFIGURED
- ;;
- esac
+ ocf_exit_reason "Unsupported iSCSI target implementation \"$OCF_RESKEY_implementation\"!"
+ exit $OCF_ERR_CONFIGURED
+ ;;
+ esac
- # Do we have a valid LUN?
- case $OCF_RESKEY_implementation in
+ # Do we have a valid LUN?
+ case $OCF_RESKEY_implementation in
iet)
- # IET allows LUN 0 and up
- [ $OCF_RESKEY_lun -ge 0 ]
- case $? in
+ # IET allows LUN 0 and up
+ [ $OCF_RESKEY_lun -ge 0 ]
+ case $? in
0)
- # OK
- ;;
+ # OK
+ ;;
1)
- ocf_log err "Invalid LUN $OCF_RESKEY_lun (must be a non-negative integer)."
- exit $OCF_ERR_CONFIGURED
- ;;
+ ocf_log err "Invalid LUN $OCF_RESKEY_lun (must be a non-negative integer)."
+ exit $OCF_ERR_CONFIGURED
+ ;;
*)
- ocf_log err "Invalid LUN $OCF_RESKEY_lun (must be an integer)."
- exit $OCF_ERR_CONFIGURED
- ;;
- esac
- ;;
+ ocf_log err "Invalid LUN $OCF_RESKEY_lun (must be an integer)."
+ exit $OCF_ERR_CONFIGURED
+ ;;
+ esac
+ ;;
tgt)
- # tgt reserves LUN 0 for its own purposes
- [ $OCF_RESKEY_lun -ge 1 ]
- case $? in
+ # tgt reserves LUN 0 for its own purposes
+ [ $OCF_RESKEY_lun -ge 1 ]
+ case $? in
0)
- # OK
- ;;
+ # OK
+ ;;
1)
- ocf_log err "Invalid LUN $OCF_RESKEY_lun (must be greater than 0)."
- exit $OCF_ERR_CONFIGURED
- ;;
+ ocf_log err "Invalid LUN $OCF_RESKEY_lun (must be greater than 0)."
+ exit $OCF_ERR_CONFIGURED
+ ;;
*)
- ocf_log err "Invalid LUN $OCF_RESKEY_lun (must be an integer)."
- exit $OCF_ERR_CONFIGURED
- ;;
- esac
- ;;
- esac
-
- # Do we have any configuration parameters that the current
- # implementation does not support?
- local unsupported_params
- local var
- local envar
- case $OCF_RESKEY_implementation in
+ ocf_log err "Invalid LUN $OCF_RESKEY_lun (must be an integer)."
+ exit $OCF_ERR_CONFIGURED
+ ;;
+ esac
+ ;;
+ esac
+
+ # Do we have any configuration parameters that the current
+ # implementation does not support?
+ local unsupported_params
+ local var
+ local envar
+ case $OCF_RESKEY_implementation in
iet)
- # IET does not support setting the vendor and product ID
- # (it always uses "IET" and "VIRTUAL-DISK")
- unsupported_params="vendor_id product_id allowed_initiators lio_iblock tgt_bstype tgt_bsoflags tgt_device_type"
- ;;
+ # IET does not support setting the vendor and product ID
+ # (it always uses "IET" and "VIRTUAL-DISK")
+ unsupported_params="vendor_id product_id allowed_initiators lio_iblock tgt_bstype tgt_bsoflags tgt_device_type"
+ ;;
tgt)
- unsupported_params="allowed_initiators lio_iblock"
- ;;
+ unsupported_params="allowed_initiators lio_iblock"
+ ;;
lio)
- unsupported_params="scsi_id vendor_id product_id tgt_bstype tgt_bsoflags tgt_device_type"
- ;;
- esac
- for var in ${unsupported_params}; do
- envar=OCF_RESKEY_${var}
- defvar=OCF_RESKEY_${var}_default
- if [ -n "${!envar}" ]; then
- if [[ "${!envar}" != "${!defvar}" ]];then
- case "$__OCF_ACTION" in
- start|validate-all)
- ocf_log warn "Configuration parameter \"${var}\"" \
- "is not supported by the iSCSI implementation" \
- "and will be ignored." ;;
- esac
- fi
- fi
- done
+ unsupported_params="scsi_id vendor_id product_id tgt_bstype tgt_bsoflags tgt_device_type"
+ ;;
+ lio-t)
+ unsupported_params="scsi_id vendor_id product_id tgt_bstype tgt_bsoflags tgt_device_type lio_iblock"
+ ;;
+ esac
+
+ for var in ${unsupported_params}; do
+ envar=OCF_RESKEY_${var}
+ defvar=OCF_RESKEY_${var}_default
+ if [ -n "${!envar}" ]; then
+ if [[ "${!envar}" != "${!defvar}" ]];then
+ case "$__OCF_ACTION" in
+ start|validate-all)
+ ocf_log warn "Configuration parameter \"${var}\"" \
+ "is not supported by the iSCSI implementation" \
+ "and will be ignored." ;;
+ esac
+ fi
+ fi
+ done
- if ! ocf_is_probe; then
- # Do we have all required binaries?
+ if ! ocf_is_probe; then
+ # Do we have all required binaries?
case $OCF_RESKEY_implementation in
- iet)
+ iet)
check_binary ietadm
;;
- tgt)
+ tgt)
check_binary tgtadm
;;
- lio)
+ lio)
check_binary tcm_node
check_binary lio_node
;;
+ lio-t)
+ check_binary targetcli
+ ;;
esac
- # Is the required kernel functionality available?
+ # Is the required kernel functionality available?
case $OCF_RESKEY_implementation in
- iet)
+ iet)
[ -d /proc/net/iet ]
if [ $? -ne 0 ]; then
- ocf_log err "/proc/net/iet does not exist or is not a directory -- check if required modules are loaded."
- exit $OCF_ERR_INSTALLED
+ ocf_log err "/proc/net/iet does not exist or is not a directory -- check if required modules are loaded."
+ exit $OCF_ERR_INSTALLED
fi
;;
- tgt)
- # tgt is userland only
+ tgt)
+ # tgt is userland only
;;
esac
- fi
+ fi
- return $OCF_SUCCESS
+ return $OCF_SUCCESS
}
-
case $1 in
- meta-data)
+meta-data)
meta_data
exit $OCF_SUCCESS
;;
- usage|help)
+usage|help)
iSCSILogicalUnit_usage
exit $OCF_SUCCESS
;;
@@ -568,13 +650,14 @@ start) iSCSILogicalUnit_start;;
stop) iSCSILogicalUnit_stop;;
monitor|status) iSCSILogicalUnit_monitor;;
reload) ocf_log err "Reloading..."
- iSCSILogicalUnit_start
+ iSCSILogicalUnit_start
;;
validate-all) ;;
*) iSCSILogicalUnit_usage
exit $OCF_ERR_UNIMPLEMENTED
;;
esac
+
rc=$?
ocf_log debug "${OCF_RESOURCE_INSTANCE} $__OCF_ACTION : $rc"
exit $rc
diff --git a/heartbeat/iSCSITarget b/heartbeat/iSCSITarget
index a988fb2..72ec64a 100755
--- a/heartbeat/iSCSITarget
+++ b/heartbeat/iSCSITarget
@@ -1,7 +1,7 @@
#!/bin/bash
#
#
-# iSCSITarget OCF RA. Exports and manages iSCSI targets.
+# iSCSITarget OCF RA. Exports and manages iSCSI targets.
#
# (c) 2009-2010 Florian Haas, Dejan Muhamedagic,
# and Linux-HA contributors
@@ -34,11 +34,13 @@
# Defaults
# Set a default implementation based on software installed
if have_binary ietadm; then
- OCF_RESKEY_implementation_default="iet"
+ OCF_RESKEY_implementation_default="iet"
elif have_binary tgtadm; then
- OCF_RESKEY_implementation_default="tgt"
+ OCF_RESKEY_implementation_default="tgt"
elif have_binary lio_node; then
- OCF_RESKEY_implementation_default="lio"
+ OCF_RESKEY_implementation_default="lio"
+elif have_binary targetcli; then
+ OCF_RESKEY_implementation_default="lio-t"
fi
: ${OCF_RESKEY_implementation=${OCF_RESKEY_implementation_default}}
@@ -67,12 +69,12 @@ Units (LUs) exported via a daemon that speaks the iSCSI protocol.
<parameter name="implementation" required="0" unique="0">
<longdesc lang="en">
The iSCSI target daemon implementation. Must be one of "iet", "tgt",
-or "lio". If unspecified, an implementation is selected based on the
+"lio", or "lio-t". If unspecified, an implementation is selected based on the
availability of management utilities, with "iet" being tried first,
-then "tgt", then "lio".
+then "tgt", then "lio", then "lio-t".
</longdesc>
<shortdesc lang="en">Specifies the iSCSI target implementation
-("iet", "tgt" or "lio").</shortdesc>
+("iet", "tgt", "lio", or "lio-t").</shortdesc>
<content type="string" default="${OCF_RESKEY_implementation_default}"/>
</parameter>
@@ -148,11 +150,11 @@ dependent. Neither the name nor the value may contain whitespace.
</parameters>
<actions>
-<action name="start" timeout="10" />
-<action name="stop" timeout="10" />
-<action name="status" timeout="10" interval="10" depth="0" />
-<action name="monitor" timeout="10" interval="10" depth="0" />
-<action name="meta-data" timeout="5" />
+<action name="start" timeout="10" />
+<action name="stop" timeout="10" />
+<action name="status" timeout="10" interval="10" depth="0" />
+<action name="monitor" timeout="10" interval="10" depth="0" />
+<action name="meta-data" timeout="5" />
<action name="validate-all" timeout="10" />
</actions>
</resource-agent>
@@ -170,182 +172,233 @@ END
}
iSCSITarget_start() {
- iSCSITarget_monitor
- if [ $? = $OCF_SUCCESS ]; then
- return $OCF_SUCCESS
- fi
+ iSCSITarget_monitor
+ if [ $? = $OCF_SUCCESS ]; then
+ return $OCF_SUCCESS
+ fi
- local param
- local name
- local value
- local initiator
- local portal
+ local param
+ local name
+ local value
+ local initiator
+ local portal
- case $OCF_RESKEY_implementation in
+ case $OCF_RESKEY_implementation in
iet)
- local lasttid
- local tid
- if [ "${OCF_RESKEY_tid}" ]; then
- tid="${OCF_RESKEY_tid}"
- else
- # Figure out the last used target ID, add 1 to get the new
- # target ID.
- ocf_take_lock $LOCKFILE
- ocf_release_lock_on_exit $LOCKFILE
- lasttid=`sed -ne "s/tid:\([[:digit:]]\+\) name:.*/\1/p" < /proc/net/iet/volume | sort -n | tail -n1`
- [ -z "${lasttid}" ] && lasttid=0
- tid=$((++lasttid))
- fi
- # Create the target.
- ocf_run ietadm --op new \
- --tid=${tid} \
- --params Name=${OCF_RESKEY_iqn} || exit $OCF_ERR_GENERIC
- # Set additional parameters.
- for param in ${OCF_RESKEY_additional_parameters}; do
- name=${param%=*}
- value=${param#*=}
- ocf_run ietadm --op update \
- --tid=${tid} \
- --params ${name}=${value} || exit $OCF_ERR_GENERIC
- done
- # Legacy versions of IET allow targets by default, current
- # versions deny. To be safe we manage both the .allow and
- # .deny files.
- if [ -n "${OCF_RESKEY_allowed_initiators}" ]; then
- echo "${OCF_RESKEY_iqn} ALL" >> /etc/initiators.deny
- echo "${OCF_RESKEY_iqn} ${OCF_RESKEY_allowed_initiators// /,}" >> /etc/initiators.allow
- else
- echo "${OCF_RESKEY_iqn} ALL" >> /etc/initiators.allow
- fi
- # In iet, adding a new user and assigning it to a target
- # is one operation.
- if [ -n "${OCF_RESKEY_incoming_username}" ]; then
- ocf_run ietadm --op new --user \
- --tid=${tid} \
- --params=IncomingUser=${OCF_RESKEY_incoming_username},Password=${OCF_RESKEY_incoming_password} \
- || exit $OCF_ERR_GENERIC
- fi
- ;;
+ local lasttid
+ local tid
+ if [ "${OCF_RESKEY_tid}" ]; then
+ tid="${OCF_RESKEY_tid}"
+ else
+ # Figure out the last used target ID, add 1 to get the new
+ # target ID.
+ ocf_take_lock $LOCKFILE
+ ocf_release_lock_on_exit $LOCKFILE
+ lasttid=`sed -ne "s/tid:\([[:digit:]]\+\) name:.*/\1/p" < /proc/net/iet/volume | sort -n | tail -n1`
+ [ -z "${lasttid}" ] && lasttid=0
+ tid=$((++lasttid))
+ fi
+
+ # Create the target.
+ ocf_run ietadm --op new \
+ --tid=${tid} \
+ --params Name=${OCF_RESKEY_iqn} || exit $OCF_ERR_GENERIC
+
+ # Set additional parameters.
+ for param in ${OCF_RESKEY_additional_parameters}; do
+ name=${param%=*}
+ value=${param#*=}
+ ocf_run ietadm --op update \
+ --tid=${tid} \
+ --params ${name}=${value} || exit $OCF_ERR_GENERIC
+ done
+
+ # Legacy versions of IET allow targets by default, current
+ # versions deny. To be safe we manage both the .allow and
+ # .deny files.
+ if [ -n "${OCF_RESKEY_allowed_initiators}" ]; then
+ echo "${OCF_RESKEY_iqn} ALL" >> /etc/initiators.deny
+ echo "${OCF_RESKEY_iqn} ${OCF_RESKEY_allowed_initiators// /,}" >> /etc/initiators.allow
+ else
+ echo "${OCF_RESKEY_iqn} ALL" >> /etc/initiators.allow
+ fi
+ # In iet, adding a new user and assigning it to a target
+ # is one operation.
+ if [ -n "${OCF_RESKEY_incoming_username}" ]; then
+ ocf_run ietadm --op new --user \
+ --tid=${tid} \
+ --params=IncomingUser=${OCF_RESKEY_incoming_username},Password=${OCF_RESKEY_incoming_password} \
+ || exit $OCF_ERR_GENERIC
+ fi
+ ;;
tgt)
- local tid
- tid="${OCF_RESKEY_tid}"
- # Create the target.
- ocf_run tgtadm --lld iscsi --op new --mode target \
- --tid=${tid} \
- --targetname ${OCF_RESKEY_iqn} || exit $OCF_ERR_GENERIC
- # Set parameters.
- for param in ${OCF_RESKEY_additional_parameters}; do
- name=${param%=*}
- value=${param#*=}
- ocf_run tgtadm --lld iscsi --op update --mode target \
- --tid=${tid} \
- --name=${name} --value=${value} || exit $OCF_ERR_GENERIC
- done
- # For tgt, we always have to add access per initiator;
- # access to targets is denied by default. If
- # "allowed_initiators" is unset, we must use the special
- # keyword ALL.
- for initiator in ${OCF_RESKEY_allowed_initiators=ALL}; do
- ocf_run tgtadm --lld iscsi --op bind --mode target \
- --tid=${tid} \
- --initiator-address=${initiator} || exit $OCF_ERR_GENERIC
- done
- # In tgt, we must first create a user account, then assign
- # it to a target using the "bind" operation.
- if [ -n "${OCF_RESKEY_incoming_username}" ]; then
- ocf_run tgtadm --lld iscsi --mode account --op new \
- --user=${OCF_RESKEY_incoming_username} \
- --password=${OCF_RESKEY_incoming_password} || exit $OCF_ERR_GENERIC
- ocf_run tgtadm --lld iscsi --mode account --op bind \
- --tid=${tid} \
- --user=${OCF_RESKEY_incoming_username} || exit $OCF_ERR_GENERIC
- fi
- ;;
+ local tid
+ tid="${OCF_RESKEY_tid}"
+ # Create the target.
+ ocf_run tgtadm --lld iscsi --op new --mode target \
+ --tid=${tid} \
+ --targetname ${OCF_RESKEY_iqn} || exit $OCF_ERR_GENERIC
+
+ # Set parameters.
+ for param in ${OCF_RESKEY_additional_parameters}; do
+ name=${param%=*}
+ value=${param#*=}
+ ocf_run tgtadm --lld iscsi --op update --mode target \
+ --tid=${tid} \
+ --name=${name} --value=${value} || exit $OCF_ERR_GENERIC
+ done
+
+ # For tgt, we always have to add access per initiator;
+ # access to targets is denied by default. If
+ # "allowed_initiators" is unset, we must use the special
+ # keyword ALL.
+ for initiator in ${OCF_RESKEY_allowed_initiators=ALL}; do
+ ocf_run tgtadm --lld iscsi --op bind --mode target \
+ --tid=${tid} \
+ --initiator-address=${initiator} || exit $OCF_ERR_GENERIC
+ done
+
+ # In tgt, we must first create a user account, then assign
+ # it to a target using the "bind" operation.
+ if [ -n "${OCF_RESKEY_incoming_username}" ]; then
+ ocf_run tgtadm --lld iscsi --mode account --op new \
+ --user=${OCF_RESKEY_incoming_username} \
+ --password=${OCF_RESKEY_incoming_password} || exit $OCF_ERR_GENERIC
+ ocf_run tgtadm --lld iscsi --mode account --op bind \
+ --tid=${tid} \
+ --user=${OCF_RESKEY_incoming_username} || exit $OCF_ERR_GENERIC
+ fi
+ ;;
lio)
- # lio distinguishes between targets and target portal
- # groups (TPGs). We will always create one TPG, with the
- # number 1. In lio, creating a network portal
- # automatically creates the corresponding target if it
- # doesn't already exist.
- for portal in ${OCF_RESKEY_portals}; do
- ocf_run lio_node --addnp ${OCF_RESKEY_iqn} 1 \
- ${portal} || exit $OCF_ERR_GENERIC
- done
- # in lio, we can set target parameters by manipulating
- # the appropriate configfs entries
- for param in ${OCF_RESKEY_additional_parameters}; do
- name=${param%=*}
- value=${param#*=}
- configfs_path="/sys/kernel/config/target/iscsi/${OCF_RESKEY_iqn}/tpgt_1/param/${name}"
- if [ -e ${configfs_path} ]; then
- echo ${value} > ${configfs_path} || exit $OCF_ERR_GENERIC
+ # lio distinguishes between targets and target portal
+ # groups (TPGs). We will always create one TPG, with the
+ # number 1. In lio, creating a network portal
+ # automatically creates the corresponding target if it
+ # doesn't already exist.
+ for portal in ${OCF_RESKEY_portals}; do
+ ocf_run lio_node --addnp ${OCF_RESKEY_iqn} 1 \
+ ${portal} || exit $OCF_ERR_GENERIC
+ done
+
+ # in lio, we can set target parameters by manipulating
+ # the appropriate configfs entries
+ for param in ${OCF_RESKEY_additional_parameters}; do
+ name=${param%=*}
+ value=${param#*=}
+ configfs_path="/sys/kernel/config/target/iscsi/${OCF_RESKEY_iqn}/tpgt_1/param/${name}"
+ if [ -e ${configfs_path} ]; then
+ echo ${value} > ${configfs_path} || exit $OCF_ERR_GENERIC
+ else
+ ocf_log warn "Unsupported iSCSI target parameter ${name}: will be ignored."
+ fi
+ done
+
+ # lio does per-initiator filtering by default. To disable
+ # this, we need to switch the target to "permissive mode".
+ if [ -n "${OCF_RESKEY_allowed_initiators}" ]; then
+ for initiator in ${OCF_RESKEY_allowed_initiators}; do
+ ocf_run lio_node --addnodeacl ${OCF_RESKEY_iqn} 1 \
+ ${initiator} || exit $OCF_ERR_GENERIC
+ done
else
- ocf_log warn "Unsupported iSCSI target parameter ${name}: will be ignored."
+ ocf_run lio_node --permissive ${OCF_RESKEY_iqn} 1 || exit $OCF_ERR_GENERIC
+ # permissive mode enables read-only access by default,
+ # so we need to change that to RW to be in line with
+ # the other implementations.
+ echo 0 > "/sys/kernel/config/target/iscsi/${OCF_RESKEY_iqn}/tpgt_1/attrib/demo_mode_write_protect"
+ if [ `cat /sys/kernel/config/target/iscsi/${OCF_RESKEY_iqn}/tpgt_1/attrib/demo_mode_write_protect` -ne 0 ]; then
+ ocf_log err "Failed to disable write protection for target ${OCF_RESKEY_iqn}."
+ exit $OCF_ERR_GENERIC
+ fi
fi
- done
- # lio does per-initiator filtering by default. To disable
- # this, we need to switch the target to "permissive mode".
- if [ -n "${OCF_RESKEY_allowed_initiators}" ]; then
- for initiator in ${OCF_RESKEY_allowed_initiators}; do
- ocf_run lio_node --addnodeacl ${OCF_RESKEY_iqn} 1 \
- ${initiator} || exit $OCF_ERR_GENERIC
+
+ # TODO: add CHAP authentication support when it gets added
+ # back into LIO
+ ocf_run lio_node --disableauth ${OCF_RESKEY_iqn} 1 || exit $OCF_ERR_GENERIC
+ # Finally, we need to enable the target to allow
+ # initiators to connect
+ ocf_run lio_node --enabletpg=${OCF_RESKEY_iqn} 1 || exit $OCF_ERR_GENERIC
+ ;;
+ lio-t)
+ # lio distinguishes between targets and target portal
+ # groups (TPGs). We will always create one TPG, with the
+ # number 1. In lio, creating a network portal
+ # automatically creates the corresponding target if it
+ # doesn't already exist.
+ for portal in ${OCF_RESKEY_portals}; do
+ ocf_run targetcli /iscsi create ${OCF_RESKEY_iqn} || exit $OCF_ERR_GENERIC
+ if [ $portal != ${OCF_RESKEY_portals_default} ] ; then
+ IFS=':' read -a sep_portal <<< "$portal"
+ ocf_run targetcli /iscsi/${OCF_RESKEY_iqn}/tpg1/portals create "${sep_portal[0]}" "${sep_portal[1]}" || exit $OCF_ERR_GENERIC
+ fi
done
- else
- ocf_run lio_node --permissive ${OCF_RESKEY_iqn} 1 || exit $OCF_ERR_GENERIC
- # permissive mode enables read-only access by default,
- # so we need to change that to RW to be in line with
- # the other implementations.
- echo 0 > "/sys/kernel/config/target/iscsi/${OCF_RESKEY_iqn}/tpgt_1/attrib/demo_mode_write_protect"
- if [ `cat /sys/kernel/config/target/iscsi/${OCF_RESKEY_iqn}/tpgt_1/attrib/demo_mode_write_protect` -ne 0 ]; then
- ocf_log err "Failed to disable write protection for target ${OCF_RESKEY_iqn}."
- exit $OCF_ERR_GENERIC
+ # in lio, we can set target parameters by manipulating
+ # the appropriate configfs entries
+ for param in ${OCF_RESKEY_additional_parameters}; do
+ name=${param%=*}
+ value=${param#*=}
+ configfs_path="/sys/kernel/config/target/iscsi/${OCF_RESKEY_iqn}/tpgt_1/param/${name}"
+ if [ -e ${configfs_path} ]; then
+ echo ${value} > ${configfs_path} || exit $OCF_ERR_GENERIC
+ else
+ ocf_log warn "Unsupported iSCSI target parameter ${name}: will be ignored."
+ fi
+ done
+ # lio does per-initiator filtering by default. To disable
+ # this, we need to switch the target to "permissive mode".
+ if [ -n "${OCF_RESKEY_allowed_initiators}" ]; then
+ for initiator in ${OCF_RESKEY_allowed_initiators}; do
+ ocf_run targetcli /iscsi/${OCF_RESKEY_iqn}/tpg1/acls create ${initiator} || exit $OCF_ERR_GENERIC
+ done
+ else
+ ocf_run targetcli /iscsi/${OCF_RESKEY_iqn}/tpg1/ set attribute authentication=0 demo_mode_write_protect=0 generate_node_acls=1 cache_dynamic_acls=1 || exit $OCF_ERR_GENERIC
fi
- fi
- # TODO: add CHAP authentication support when it gets added
- # back into LIO
- ocf_run lio_node --disableauth ${OCF_RESKEY_iqn} 1 || exit $OCF_ERR_GENERIC
- # Finally, we need to enable the target to allow
- # initiators to connect
- ocf_run lio_node --enabletpg=${OCF_RESKEY_iqn} 1 || exit $OCF_ERR_GENERIC
- ;;
- esac
-
- return $OCF_SUCCESS
+ # TODO: add CHAP authentication support when it gets added
+ # back into LIO
+ ocf_run targetcli /iscsi/${OCF_RESKEY_iqn}/tpg1/ set attribute authentication=0 || exit $OCF_ERR_GENERIC
+# ocf_run targetcli /iscsi
+ ;;
+ esac
+
+ iSCSITarget_monitor
}
iSCSITarget_stop() {
- iSCSITarget_monitor
- if [ $? = $OCF_SUCCESS ]; then
+ iSCSITarget_monitor
+ if [ $? -eq $OCF_NOT_RUNNING ]; then
+ return $OCF_SUCCESS
+ fi
+
local tid
case $OCF_RESKEY_implementation in
- iet)
+ iet)
# Figure out the target ID
tid=`sed -ne "s/tid:\([[:digit:]]\+\) name:${OCF_RESKEY_iqn}/\1/p" < /proc/net/iet/volume`
if [ -z "${tid}" ]; then
- ocf_log err "Failed to retrieve target ID for IQN ${OCF_RESKEY_iqn}"
- exit $OCF_ERR_GENERIC
+ ocf_log err "Failed to retrieve target ID for IQN ${OCF_RESKEY_iqn}"
+ exit $OCF_ERR_GENERIC
fi
# Close existing connections. There is no other way to
# do this in IET than to parse the contents of
# /proc/net/iet/session.
set -- $(sed -ne '/^tid:'${tid}' /,/^tid/ {
- /^[[:space:]]*sid:\([0-9]\+\)/ {
- s/^[[:space:]]*sid:\([0-9]*\).*/--sid=\1/; h;
- };
- /^[[:space:]]*cid:\([0-9]\+\)/ {
- s/^[[:space:]]*cid:\([0-9]*\).*/--cid=\1/; G; p;
- };
- }' < /proc/net/iet/session)
+ /^[[:space:]]*sid:\([0-9]\+\)/ {
+ s/^[[:space:]]*sid:\([0-9]*\).*/--sid=\1/; h;
+ };
+ /^[[:space:]]*cid:\([0-9]\+\)/ {
+ s/^[[:space:]]*cid:\([0-9]*\).*/--cid=\1/; G; p;
+ };
+ }' < /proc/net/iet/session)
while [[ -n $2 ]]; do
- # $2 $1 looks like "--sid=X --cid=Y"
- ocf_run ietadm --op delete \
- --tid=${tid} $2 $1
- shift 2
+ # $2 $1 looks like "--sid=X --cid=Y"
+ ocf_run ietadm --op delete \
+ --tid=${tid} $2 $1
+ shift 2
done
- # In iet, unassigning a user from a target and
+ # In iet, unassigning a user from a target and
# deleting the user account is one operation.
if [ -n "${OCF_RESKEY_incoming_username}" ]; then
- ocf_run ietadm --op delete --user \
+ ocf_run ietadm --op delete --user \
--tid=${tid} \
--params=IncomingUser=${OCF_RESKEY_incoming_username} \
|| exit $OCF_ERR_GENERIC
@@ -353,216 +406,226 @@ iSCSITarget_stop() {
# Loop on delete. Keep trying until we time out, if
# necessary.
while true; do
- if ietadm --op delete --tid=${tid}; then
- ocf_log debug "Removed target ${OCF_RESKEY_iqn}."
- break
- else
- ocf_log warn "Failed to remove target ${OCF_RESKEY_iqn}, retrying."
- sleep 1
- fi
+ if ietadm --op delete --tid=${tid}; then
+ ocf_log debug "Removed target ${OCF_RESKEY_iqn}."
+ break
+ else
+ ocf_log warn "Failed to remove target ${OCF_RESKEY_iqn}, retrying."
+ sleep 1
+ fi
done
# Avoid stale /etc/initiators.{allow,deny} entries
# for this target
if [ -e /etc/initiators.deny ]; then
- ocf_run sed -e "/^${OCF_RESKEY_iqn}[[:space:]]/d" \
+ ocf_run sed -e "/^${OCF_RESKEY_iqn}[[:space:]]/d" \
-i /etc/initiators.deny
fi
if [ -e /etc/initiators.allow ]; then
- ocf_run sed -e "/^${OCF_RESKEY_iqn}[[:space:]]/d" \
+ ocf_run sed -e "/^${OCF_RESKEY_iqn}[[:space:]]/d" \
-i /etc/initiators.allow
fi
;;
- tgt)
+ tgt)
tid="${OCF_RESKEY_tid}"
# Close existing connections. There is no other way to
# do this in tgt than to parse the output of "tgtadm --op
# show".
set -- $(tgtadm --lld iscsi --op show --mode target \
- | sed -ne '/^Target '${tid}':/,/^Target/ {
- /^[[:space:]]*I_T nexus: \([0-9]\+\)/ {
- s/^.*: \([0-9]*\).*/--sid=\1/; h;
- };
- /^[[:space:]]*Connection: \([0-9]\+\)/ {
- s/^.*: \([0-9]*\).*/--cid=\1/; G; p;
- };
- /^[[:space:]]*LUN information:/ q;
- }')
+ | sed -ne '/^Target '${tid}':/,/^Target/ {
+ /^[[:space:]]*I_T nexus: \([0-9]\+\)/ {
+ s/^.*: \([0-9]*\).*/--sid=\1/; h;
+ };
+ /^[[:space:]]*Connection: \([0-9]\+\)/ {
+ s/^.*: \([0-9]*\).*/--cid=\1/; G; p;
+ };
+ /^[[:space:]]*LUN information:/ q;
+ }')
while [[ -n $2 ]]; do
- # $2 $1 looks like "--sid=X --cid=Y"
- ocf_run tgtadm --lld iscsi --op delete --mode connection \
+ # $2 $1 looks like "--sid=X --cid=Y"
+ ocf_run tgtadm --lld iscsi --op delete --mode connection \
--tid=${tid} $2 $1
- shift 2
+ shift 2
done
- # In tgt, we must first unbind the user account from
+ # In tgt, we must first unbind the user account from
# the target, then remove the account itself.
if [ -n "${OCF_RESKEY_incoming_username}" ]; then
- ocf_run tgtadm --lld iscsi --mode account --op unbind \
- --tid=${tid} \
- --user=${OCF_RESKEY_incoming_username} || exit $OCF_ERR_GENERIC
- ocf_run tgtadm --lld iscsi --mode account --op delete \
- --user=${OCF_RESKEY_incoming_username} || exit $OCF_ERR_GENERIC
+ ocf_run tgtadm --lld iscsi --mode account --op unbind \
+ --tid=${tid} \
+ --user=${OCF_RESKEY_incoming_username} || exit $OCF_ERR_GENERIC
+ ocf_run tgtadm --lld iscsi --mode account --op delete \
+ --user=${OCF_RESKEY_incoming_username} || exit $OCF_ERR_GENERIC
fi
# Loop on delete. Keep trying until we time out, if
# necessary.
while true; do
- if tgtadm --lld iscsi --op delete --mode target --tid=${tid}; then
- ocf_log debug "Removed target ${OCF_RESKEY_iqn}."
- break
- else
- ocf_log warn "Failed to remove target ${OCF_RESKEY_iqn}, retrying."
- sleep 1
- fi
+ if tgtadm --lld iscsi --op delete --mode target --tid=${tid}; then
+ ocf_log debug "Removed target ${OCF_RESKEY_iqn}."
+ break
+ else
+ ocf_log warn "Failed to remove target ${OCF_RESKEY_iqn}, retrying."
+ sleep 1
+ fi
done
# In tgt, we don't have to worry about our ACL
# entries. They are automatically removed upon target
# deletion.
;;
- lio)
+ lio)
# In lio, removing a target automatically removes all
# associated TPGs, network portals, and LUNs.
ocf_run lio_node --deliqn ${OCF_RESKEY_iqn} || exit $OCF_ERR_GENERIC
;;
+ lio-t)
+ ocf_run targetcli /iscsi delete ${OCF_RESKEY_iqn} || exit $OCF_ERR_GENERIC
+ ;;
esac
- fi
- return $OCF_SUCCESS
+ return $OCF_SUCCESS
}
iSCSITarget_monitor() {
- case $OCF_RESKEY_implementation in
+ case $OCF_RESKEY_implementation in
iet)
- grep -Eq "tid:[0-9]+ name:${OCF_RESKEY_iqn}" /proc/net/iet/volume && return $OCF_SUCCESS
- ;;
+ grep -Eq "tid:[0-9]+ name:${OCF_RESKEY_iqn}" /proc/net/iet/volume && return $OCF_SUCCESS
+ ;;
tgt)
- tgtadm --lld iscsi --op show --mode target \
+ tgtadm --lld iscsi --op show --mode target \
| grep -Eq "Target [0-9]+: ${OCF_RESKEY_iqn}" && return $OCF_SUCCESS
- ;;
- lio)
- # if we have no configfs entry for the target, it's
- # definitely stopped
- [ -d /sys/kernel/config/target/iscsi/${OCF_RESKEY_iqn} ] || return $OCF_NOT_RUNNING
- # if the target is there, but its TPG is not enabled, then
- # we also consider it stopped
- [ `cat /sys/kernel/config/target/iscsi/${OCF_RESKEY_iqn}/tpgt_1/enable` -eq 1 ] || return $OCF_NOT_RUNNING
- return $OCF_SUCCESS
- ;;
- esac
-
- return $OCF_NOT_RUNNING
+ ;;
+ lio | lio-t)
+ # if we have no configfs entry for the target, it's
+ # definitely stopped
+ [ -d /sys/kernel/config/target/iscsi/${OCF_RESKEY_iqn} ] || return $OCF_NOT_RUNNING
+ # if the target is there, but its TPG is not enabled, then
+ # we also consider it stopped
+ [ `cat /sys/kernel/config/target/iscsi/${OCF_RESKEY_iqn}/tpgt_1/enable` -eq 1 ] || return $OCF_NOT_RUNNING
+ return $OCF_SUCCESS
+ ;;
+ esac
+
+ return $OCF_NOT_RUNNING
}
iSCSITarget_validate() {
- # Do we have all required variables?
- local required_vars
- case $OCF_RESKEY_implementation in
+ # Do we have all required variables?
+ local required_vars
+ case $OCF_RESKEY_implementation in
iet)
- required_vars="iqn"
- ;;
+ required_vars="iqn"
+ ;;
tgt)
- required_vars="iqn tid"
- ;;
- esac
- for var in ${required_vars}; do
- param="OCF_RESKEY_${var}"
- if [ -z "${!param}" ]; then
- ocf_log error "Missing resource parameter \"$var\"!"
- exit $OCF_ERR_CONFIGURED
- fi
- done
+ required_vars="iqn tid"
+ ;;
+ esac
+
+ for var in ${required_vars}; do
+ param="OCF_RESKEY_${var}"
+ if [ -z "${!param}" ]; then
+ ocf_exit_reason "Missing resource parameter \"$var\"!"
+ exit $OCF_ERR_CONFIGURED
+ fi
+ done
- # Is the configured implementation supported?
- case "$OCF_RESKEY_implementation" in
- "iet"|"tgt"|"lio")
- ;;
+ # Is the configured implementation supported?
+ case "$OCF_RESKEY_implementation" in
+ "iet"|"tgt"|"lio"|"lio-t")
+ ;;
"")
- # The user didn't specify an implementation, and we were
- # unable to determine one from installed binaries (in
- # other words: no binaries for any supported
- # implementation could be found)
- ocf_log error "Undefined iSCSI target implementation"
- exit $OCF_ERR_INSTALLED
- ;;
+ # The user didn't specify an implementation, and we were
+ # unable to determine one from installed binaries (in
+ # other words: no binaries for any supported
+ # implementation could be found)
+ ocf_exit_reason "Undefined iSCSI target implementation"
+ exit $OCF_ERR_INSTALLED
+ ;;
*)
- ocf_log error "Unsupported iSCSI target implementation \"$OCF_RESKEY_implementation\"!"
- exit $OCF_ERR_CONFIGURED
- ;;
- esac
-
- # Do we have any configuration parameters that the current
- # implementation does not support?
- local unsupported_params
- local var
- local envar
- case $OCF_RESKEY_implementation in
+ ocf_exit_reason "Unsupported iSCSI target implementation \"$OCF_RESKEY_implementation\"!"
+ exit $OCF_ERR_CONFIGURED
+ ;;
+ esac
+
+ # Do we have any configuration parameters that the current
+ # implementation does not support?
+ local unsupported_params
+ local var
+ local envar
+ case $OCF_RESKEY_implementation in
iet|tgt)
- # IET and tgt do not support binding a target portal to a
- # specific IP address.
- unsupported_params="portals"
- ;;
- lio)
- # TODO: Remove incoming_username and incoming_password
- # from this check when LIO 3.0 gets CHAP authentication
- unsupported_params="tid incoming_username incoming_password"
- ;;
- esac
- for var in ${unsupported_params}; do
- envar=OCF_RESKEY_${var}
- defvar=OCF_RESKEY_${var}_default
- if [ -n "${!envar}" ]; then
- if [[ "${!envar}" != "${!defvar}" ]];then
- case "$__OCF_ACTION" in
- start|validate-all)
- ocf_log warn "Configuration parameter \"${var}\"" \
- "is not supported by the iSCSI implementation" \
- "and will be ignored." ;;
- esac
- fi
- fi
- done
+ # IET and tgt do not support binding a target portal to a
+ # specific IP address.
+ unsupported_params="portals"
+ ;;
+ lio|lio-t)
+ # TODO: Remove incoming_username and incoming_password
+ # from this check when LIO 3.0 gets CHAP authentication
+ unsupported_params="tid incoming_username incoming_password"
+ ;;
+ esac
- if ! ocf_is_probe; then
- # Do we have all required binaries?
+ for var in ${unsupported_params}; do
+ envar=OCF_RESKEY_${var}
+ defvar=OCF_RESKEY_${var}_default
+ if [ -n "${!envar}" ]; then
+ if [[ "${!envar}" != "${!defvar}" ]];then
+ case "$__OCF_ACTION" in
+ start|validate-all)
+ ocf_log warn "Configuration parameter \"${var}\"" \
+ "is not supported by the iSCSI implementation" \
+ "and will be ignored." ;;
+ esac
+ fi
+ fi
+ done
+
+ if ! ocf_is_probe; then
+ # Do we have all required binaries?
case $OCF_RESKEY_implementation in
- iet)
+ iet)
check_binary ietadm
;;
- tgt)
+ tgt)
check_binary tgtadm
;;
- lio)
+ lio)
check_binary tcm_node
check_binary lio_node
;;
+ lio-t)
+ check_binary targetcli
+ ;;
esac
- # Is the required kernel functionality available?
+ # Is the required kernel functionality available?
case $OCF_RESKEY_implementation in
- iet)
+ iet)
[ -d /proc/net/iet ]
if [ $? -ne 0 ]; then
- ocf_log err "/proc/net/iet does not exist or is not a directory -- check if required modules are loaded."
- exit $OCF_ERR_INSTALLED
+ ocf_log err "/proc/net/iet does not exist or is not a directory -- check if required modules are loaded."
+ exit $OCF_ERR_INSTALLED
fi
;;
- tgt)
- # tgt is userland only
+ tgt)
+ # tgt is userland only
;;
- lio)
- # lio needs configfs to be mounted
+ lio)
+ # lio needs configfs to be mounted
if ! grep -Eq "^.*/sys/kernel/config[[:space:]]+configfs" /proc/mounts; then
- ocf_log err "configfs not mounted at /sys/kernel/config -- check if required modules are loaded."
- exit $OCF_ERR_INSTALLED
+ ocf_log err "configfs not mounted at /sys/kernel/config -- check if required modules are loaded."
+ exit $OCF_ERR_INSTALLED
fi
- # check for configfs entries created by target_core_mod
+ # check for configfs entries created by target_core_mod
if [ ! -d /sys/kernel/config/target ]; then
- ocf_log err "/sys/kernel/config/target does not exist or is not a directory -- check if required modules are loaded."
- exit $OCF_ERR_INSTALLED
+ ocf_log err "/sys/kernel/config/target does not exist or is not a directory -- check if required modules are loaded."
+ exit $OCF_ERR_INSTALLED
fi
;;
+ lio-t)
+ #targetcli loads the needed kernel modules
+ ;;
esac
- fi
+ fi
- return $OCF_SUCCESS
+ return $OCF_SUCCESS
}
@@ -585,7 +648,7 @@ start) iSCSITarget_start;;
stop) iSCSITarget_stop;;
monitor|status) iSCSITarget_monitor;;
reload) ocf_log err "Reloading..."
- iSCSITarget_start
+ iSCSITarget_start
;;
validate-all) ;;
*) iSCSITarget_usage
--
1.8.4.2