diff --git a/heartbeat/iSCSILogicalUnit.in b/heartbeat/iSCSILogicalUnit.in index 1f181d92d..efcb3a66d 100644 --- a/heartbeat/iSCSILogicalUnit.in +++ b/heartbeat/iSCSILogicalUnit.in @@ -43,6 +43,8 @@ elif have_binary lio_node; then OCF_RESKEY_implementation_default="lio" elif have_binary targetcli; then OCF_RESKEY_implementation_default="lio-t" +elif have_binary scstadmin; then + OCF_RESKEY_implementation_default="scst" fi : ${OCF_RESKEY_implementation=${OCF_RESKEY_implementation_default}} @@ -104,9 +106,9 @@ an SCSI Target, exported via a daemon that speaks the iSCSI protocol. The iSCSI target daemon implementation. Must be one of "iet", "tgt", -"lio", or "lio-t". If unspecified, an implementation is selected based on the +"lio", "lio-t", or "scst". If unspecified, an implementation is selected based on the availability of management utilities, with "iet" being tried first, -then "tgt", then "lio", then "lio-t". +then "tgt", then "lio", then "lio-t", then "scst". iSCSI target daemon implementation @@ -483,6 +485,23 @@ iSCSILogicalUnit_start() { echo ${OCF_RESKEY_emulate_caw} > ${iblock_attrib_path}/emulate_caw || exit $OCF_ERR_GENERIC fi ;; + scst) + ocf_run scstadmin -open_dev "${OCF_RESOURCE_INSTANCE}" -handler vdisk_blockio -attributes "filename=${OCF_RESKEY_path},nv_cache=0,write_through=1" + if [ -n "${OCF_RESKEY_scsi_sn}" ]; then + ocf_run scstadmin -set_dev_attr "${OCF_RESOURCE_INSTANCE}" -attributes "usn=${OCF_RESKEY_scsi_sn}" -force -noprompt + fi + if [ -n "${OCF_RESKEY_vendor_id}" ]; then + ocf_run scstadmin -set_dev_attr "${OCF_RESOURCE_INSTANCE}" -attributes "t10_vend_id=${OCF_RESKEY_vendor_id}" -force -noprompt + fi + if [ -n "${OCF_RESKEY_product_id}" ]; then + ocf_run scstadmin -set_dev_attr "${OCF_RESOURCE_INSTANCE}" -attributes "t10_dev_id=${OCF_RESKEY_product_id}" -force -noprompt + fi + if [ -d "/sys/kernel/scst_tgt/targets/iscsi/${OCF_RESKEY_target_iqn}/ini_groups/allowed/" ]; then + # if an initiator group exists for the target, add the new LUN to it. + ocf_run scstadmin -add_lun ${OCF_RESKEY_lun} -driver iscsi -target "${OCF_RESKEY_target_iqn}" -device "${OCF_RESOURCE_INSTANCE}" -group allowed -force -noprompt + fi + ocf_run scstadmin -add_lun ${OCF_RESKEY_lun} -driver iscsi -target "${OCF_RESKEY_target_iqn}" -device "${OCF_RESOURCE_INSTANCE}" $group_arg -force -noprompt + ;; esac # Force the monitor operation to pass before start is considered a success. @@ -556,6 +575,10 @@ iSCSILogicalUnit_stop() { # (potentially causing fencing) ocf_run targetcli /backstores/${OCF_RESKEY_liot_bstype} delete ${OCF_RESOURCE_INSTANCE} || exit $OCF_ERR_GENERIC ;; + scst) + ocf_run -warn scstadmin -rem_lun ${OCF_RESKEY_lun} -driver iscsi -target "${OCF_RESKEY_target_iqn}" -force -noprompt + ocf_run scstadmin -close_dev "${OCF_RESOURCE_INSTANCE}" -handler vdisk_blockio -force -noprompt + ;; esac return $OCF_SUCCESS @@ -613,6 +636,12 @@ iSCSILogicalUnit_monitor() { [ -e ${block_configfs_path} ] && ocf_log warn "existing block without an active lun: ${block_configfs_path}" [ -e ${block_configfs_path} ] && return $OCF_ERR_GENERIC ;; + scst) + [ -d /sys/kernel/scst_tgt/devices/${OCF_RESOURCE_INSTANCE} ] || return $OCF_NOT_RUNNING + [ $(cat /sys/kernel/scst_tgt/devices/${OCF_RESOURCE_INSTANCE}/active) -eq 1 ] || return $OCF_NOT_RUNNING + [ $(head -n1 /sys/kernel/scst_tgt/devices/${OCF_RESOURCE_INSTANCE}/filename) = "${OCF_RESKEY_path}" ] || return $OCF_NOT_RUNNING + [ -d /sys/kernel/scst_tgt/targets/iscsi/${OCF_RESKEY_target_iqn}/luns/${OCF_RESKEY_lun} ] && return $OCF_SUCCESS + ;; esac return $OCF_NOT_RUNNING @@ -630,7 +659,7 @@ iSCSILogicalUnit_validate() { # Is the configured implementation supported? case "$OCF_RESKEY_implementation" in - "iet"|"tgt"|"lio"|"lio-t") + "iet"|"tgt"|"lio"|"lio-t"|"scst") ;; "") # The user didn't specify an implementation, and we were @@ -704,6 +733,9 @@ iSCSILogicalUnit_validate() { lio-t) unsupported_params="scsi_id vendor_id tgt_bstype tgt_bsoflags tgt_bsopts tgt_device_type lio_iblock" ;; + scst) + unsupported_params="scsi_id emulate_tpu emulate_3pc emulate_caw" + ;; esac for var in ${unsupported_params}; do @@ -737,6 +769,9 @@ iSCSILogicalUnit_validate() { lio-t) check_binary targetcli ;; + scst) + check_binary scstadmin + ;; esac # Is the required kernel functionality available? @@ -751,6 +786,12 @@ iSCSILogicalUnit_validate() { tgt) # tgt is userland only ;; + scst) + if [ ! -d /sys/kernel/scst_tgt ]; then + ocf_log err "/sys/kernel/scst_tgt does not exist or is not a directory -- check if required modules are loaded." + exit $OCF_ERR_INSTALLED + fi + ;; esac fi diff --git a/heartbeat/iSCSITarget.in b/heartbeat/iSCSITarget.in index 221d48477..2a9ddf067 100644 --- a/heartbeat/iSCSITarget.in +++ b/heartbeat/iSCSITarget.in @@ -41,6 +41,8 @@ elif have_binary lio_node; then OCF_RESKEY_implementation_default="lio" elif have_binary targetcli; then OCF_RESKEY_implementation_default="lio-t" +elif have_binary scstadmin; then + OCF_RESKEY_implementation_default="scst" fi : ${OCF_RESKEY_implementation=${OCF_RESKEY_implementation_default}} @@ -56,6 +58,9 @@ LOCKFILE=${HA_RSCTMP}/iSCSITarget-${OCF_RESKEY_implementation}.lock # targetcli: iSCSITarget and iSCSILogicalUnit must use the same lockfile TARGETLOCKFILE=${HA_RSCTMP}/targetcli.lock + +# Timeout for waiting for initiators to log out (only used in scst) +INIT_LOGOUT_TIMEOUT=20 ####################################################################### meta_data() { @@ -75,12 +80,12 @@ Units (LUs) exported via a daemon that speaks the iSCSI protocol. The iSCSI target daemon implementation. Must be one of "iet", "tgt", -"lio", or "lio-t". If unspecified, an implementation is selected based on the +"lio", "lio-t", or "scst". If unspecified, an implementation is selected based on the availability of management utilities, with "iet" being tried first, -then "tgt", then "lio", then "lio-t". +then "tgt", then "lio", then "lio-t", then "scst". Specifies the iSCSI target implementation -("iet", "tgt", "lio", or "lio-t"). +("iet", "tgt", "lio", "lio-t", or "scst"). @@ -402,6 +407,28 @@ iSCSITarget_start() { fi fi ;; + scst) + ocf_run scstadmin -add_target ${OCF_RESKEY_iqn} -driver iscsi + + for portal in ${OCF_RESKEY_portals}; do + # scst only wants the IP address for some reason, so strip the port + portal_ip="${portal%%:*}" + ocf_run scstadmin -add_tgt_attr ${OCF_RESKEY_iqn} -driver iscsi -attributes "allowed_portal=${portal_ip}" + done + ocf_run scstadmin -add_group allowed -driver iscsi -target ${OCF_RESKEY_iqn} + if [ -n "${OCF_RESKEY_allowed_initiators}" ]; then + for initiator in ${OCF_RESKEY_allowed_initiators}; do + ocf_run scstadmin -add_init ${initiator} -group allowed -driver iscsi -target ${OCF_RESKEY_iqn} + done + fi + + if [ "${OCF_RESKEY_incoming_username}" != "" ]; then + ocf_run scstadmin -add_tgt_attr ${OCF_RESKEY_iqn} -driver iscsi -attributes "IncomingUser ${OCF_RESKEY_incoming_username} ${OCF_RESKEY_incoming_password}" + fi + + ocf_run scstadmin -enable_target ${OCF_RESKEY_iqn} -driver iscsi + echo 1 > /sys/kernel/scst_tgt/targets/iscsi/enabled + ;; esac iSCSITarget_monitor @@ -524,6 +551,24 @@ iSCSITarget_stop() { ocf_release_lock_on_exit $TARGETLOCKFILE ocf_run targetcli /iscsi delete ${OCF_RESKEY_iqn} || exit $OCF_ERR_GENERIC ;; + scst) + ocf_run scstadmin -disable_target ${OCF_RESKEY_iqn} -driver iscsi -force -noprompt + for i in $(find /sys/kernel/scst_tgt/targets/iscsi/${OCF_RESKEY_iqn}/ -name force_close); do + echo 1 > ${i} + done + + timer=0 + while ls -Ad /sys/kernel/scst_tgt/targets/iscsi/${OCF_RESKEY_iqn}/sessions/* > /dev/null 2>&1; do + if [ ${timer} -gt ${INIT_LOGOUT_TIMEOUT} ]; then + ocf_log warn "Some initiators still logged in after ${INIT_LOGOUT_TIMEOUT} seconds. Continuing." + break + fi + timer=$((timer + 1)) + sleep 1 + done + + scstadmin -rem_target ${OCF_RESKEY_iqn} -driver iscsi -force -noprompt + ;; esac return $OCF_SUCCESS @@ -547,6 +592,11 @@ iSCSITarget_monitor() { [ `cat /sys/kernel/config/target/iscsi/${OCF_RESKEY_iqn}/tpgt_1/enable` -eq 1 ] || return $OCF_NOT_RUNNING return $OCF_SUCCESS ;; + scst) + [ -d /sys/kernel/scst_tgt/targets/iscsi/${OCF_RESKEY_iqn} ] || return $OCF_NOT_RUNNING + [ $(cat /sys/kernel/scst_tgt/targets/iscsi/${OCF_RESKEY_iqn}/enabled) -eq 1 ] || return $OCF_NOT_RUNNING + return $OCF_SUCCESS + ;; esac return $OCF_NOT_RUNNING @@ -574,7 +624,7 @@ iSCSITarget_validate() { # Is the configured implementation supported? case "$OCF_RESKEY_implementation" in - "iet"|"tgt"|"lio"|"lio-t") + "iet"|"tgt"|"lio"|"lio-t"|"scst") ;; "") # The user didn't specify an implementation, and we were @@ -604,6 +654,9 @@ iSCSITarget_validate() { lio|lio-t) unsupported_params="tid" ;; + scst) + unsupported_params="tid iser_portals" + ;; esac for var in ${unsupported_params}; do @@ -637,6 +690,9 @@ iSCSITarget_validate() { lio-t) check_binary targetcli ;; + scst) + check_binary scstadmin + ;; esac # Is the required kernel functionality available? @@ -666,6 +722,12 @@ iSCSITarget_validate() { lio-t) #targetcli loads the needed kernel modules ;; + scst) + if [ ! -d /sys/kernel/scst_tgt ]; then + ocf_log err "/sys/kernel/scst_tgt does not exist or is not a directory -- check if required modules are loaded." + exit $OCF_ERR_INSTALLED + fi + ;; esac fi