#!/bin/sh #=============================================================================== # scstlun, (c) 2013 Navixia SA #------------------------------------------------------------------------------- # $Id$ #------------------------------------------------------------------------------- # This resource agent will configure an iSCSI target and export a single LUN # via that target. The iSCSI implementation being used is SCST, and the RA # requires the SYSFS management interface to be available (not compatible # with the PROCFS management interface). # # OCF instance parameters # OCF_RESKEY_iqn # OCF_RESKEY_path # OCF_RESKEY_iomode # OCF_RESKEY_t10 #------------------------------------------------------------------------------- #=============================================================================== # Initialization #------------------------------------------------------------------------------- : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} . ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs #=============================================================================== # Defaults #------------------------------------------------------------------------------- OCF_RESKEY_iomode_default="fileio" : ${OCF_RESKEY_iomode=${OCF_RESKEY_iomode_default}} #=============================================================================== # Configuration #------------------------------------------------------------------------------- SCST_base="/sys/kernel/scst_tgt" ISCSI_base="${SCST_base}/targets/iscsi" #=============================================================================== # Meta-data #------------------------------------------------------------------------------- scstlun_meta_data() { cat < 0.2 Configures an iSCSI target and export a single LUN (0) via that target. The iSCSI implementation being used is SCST, and the RA requires the SYSFS management interface to be available (not compatible with the PROCFS management interface). Exports a device via an SCST iSCSI Target/Lun pair The iSCSI Qualified Name (IQN) of the target that will be enabled. iSCSI target IQN The path to the block device exposed as LUN0. Block device path that will be exposed SCST IO mode to be used (either fileio or blockio). Defaults to fileio IO mode (either fileio or blockio). Defaults to fileio Define the SCSI T10 device ID T10 device ID END } #=============================================================================== # usage #------------------------------------------------------------------------------- scstlun_usage() { cat <${SCST_base}/handlers/vdisk_${OCF_RESKEY_iomode}/mgmt if [ $? -ne 0 ]; then ocf_log err "start: FAILED to configure backend device ${devname}" return $OCF_ERR_GENERIC fi # Add backend device to target ocf_log debug "start: adding device ${devname} as LUN 0 to target ${OCF_RESKEY_iqn}" echo "add ${devname} 0" >${ISCSI_base}/${OCF_RESKEY_iqn}/luns/mgmt if [ $? -ne 0 ]; then ocf_log err "start: FAILED to add device ${devname} as LUN 0 to target ${OCF_RESKEY_iqn}" return $OCF_ERR_GENERIC fi # If present, configure T10 device ID if [ -n "${OCF_RESKEY_t10}" ]; then ocf_log debug "start: change t10 id for device ${devname} on target ${OCF_RESKEY_iqn} to ${OCF_RESKEY_t10}" echo "${OCF_RESKEY_t10}" >${ISCSI_base}/${OCF_RESKEY_iqn}/luns/0/device/t10_dev_id if [ $? -ne 0 ]; then ocf_log err "start: FAILED to change t10 id for device ${devname} on target ${OCF_RESKEY_iqn} to ${OCF_RESKEY_t10}" return $OCF_ERR_GENERIC fi ocf_log debug "start: change usn id for device ${devname} on target ${OCF_RESKEY_iqn} to ${OCF_RESKEY_t10}" echo "${OCF_RESKEY_t10}" >${ISCSI_base}/${OCF_RESKEY_iqn}/luns/0/device/usn if [ $? -ne 0 ]; then ocf_log err "start: FAILED to change usn id for device ${devname} on target ${OCF_RESKEY_iqn} to ${OCF_RESKEY_t10}" return $OCF_ERR_GENERIC fi fi # Finally, enable the target ocf_log debug "start: enabling target ${OCF_RESKEY_iqn}" echo 1 >${ISCSI_base}/${OCF_RESKEY_iqn}/enabled if [ $? -ne 0 ]; then ocf_log err "start: FAILED to enable target ${OCF_RESKEY_iqn}" return $OCF_ERR_GENERIC fi while ! scstlun_monitor; do ocf_log debug "Resource has not started yet, waiting" sleep 1 done return $OCF_SUCCESS } #=============================================================================== # stop #------------------------------------------------------------------------------- scstlun_stop() { ocf_log debug "stop: entering stop action" scstlun_monitor if [ $? != $OCF_SUCCESS ]; then return $OCF_SUCCESS fi # Build SCST device name from path devname=`basename ${OCF_RESKEY_path}` # Disable the target ocf_log debug "stop: disabling target ${OCF_RESKEY_iqn}" echo 0 >${ISCSI_base}/${OCF_RESKEY_iqn}/enabled if [ $? -ne 0 ]; then ocf_log err "stop: FAILED to disable target ${OCF_RESKEY_iqn}" return $OCF_ERR_GENERIC fi # Close all the existing sessions for s in `ls -1 ${ISCSI_base}/${OCF_RESKEY_iqn}/sessions` ; do ocf_log debug "stop: disabling session $s on target ${OCF_RESKEY_iqn}" echo 1 >${ISCSI_base}/${OCF_RESKEY_iqn}/sessions/$s/force_close if [ $? -ne 0 ]; then ocf_log err "stop: FAILED to disable session $s on target ${OCF_RESKEY_iqn}" return $OCF_ERR_GENERIC fi done # Remove LUN from target ocf_log debug "stop: removing LUN 0 from target ${OCF_RESKEY_iqn}" echo "del 0" >${ISCSI_base}/${OCF_RESKEY_iqn}/luns/mgmt if [ $? -ne 0 ]; then ocf_log err "stop: FAILED to remove LUN 0 from target ${OCF_RESKEY_iqn}" return $OCF_ERR_GENERIC fi ocf_log debug "stop: removing device ${devname}" echo "del_device ${devname}" >${SCST_base}/handlers/vdisk_${OCF_RESKEY_iomode}/mgmt if [ $? -ne 0 ]; then ocf_log err "stop: FAILED to remove device ${devname}" return $OCF_ERR_GENERIC fi while scstlun_monitor; do ocf_log debug "Resource has not stopped yet, waiting" sleep 1 done return $OCF_SUCCESS } #=============================================================================== # monitor #------------------------------------------------------------------------------- scstlun_monitor() { ocf_log debug "monitor: entering monitor action" # Build SCST device name from path devname=`basename ${OCF_RESKEY_path}` ocf_log debug "monitor: checking if ${SCST_base}/handlers/vdisk_${OCF_RESKEY_iomode}/${devname} exists" if [ ! -e "${SCST_base}/handlers/vdisk_${OCF_RESKEY_iomode}/${devname}" ]; then ocf_log debug "monitor: Device ${devname} not configured" return $OCF_NOT_RUNNING fi # Check if device is mapped to LUN ocf_log debug "monitor: checking if ${ISCSI_base}/${OCF_RESKEY_iqn}/luns/0 exists" [ -e "${SCST_base}/targets/iscsi/${OCF_RESKEY_iqn}/luns/0" ] if [ $? -ne 0 ]; then ocf_log debug "monitor: LUN is not configured for target ${OCF_RESKEY_iqn}" return $OCF_NOT_RUNNING fi return $OCF_SUCCESS } #=============================================================================== # validate #------------------------------------------------------------------------------- scstlun_validate_all() { ocf_log debug "validate: entering validate action" ocf_log debug "validate: checking if iscsi-scstd is running" if [ -z "`pidof iscsi-scstd`" ]; then ocf_log err "iscsi-scstd is not running" exit $OCF_ERR_GENERIC fi ocf_log debug "validate: checking if ${SCST_base} exists" if [ ! -e "${SCST_base}" ]; then ocf_log err "${SCST_base} does not exist" exit $OCF_ERR_GENERIC fi ocf_log debug "validate: checking if ${ISCSI_base} exists" if [ ! -e "${ISCSI_base}" ]; then ocf_log err "${ISCSI_base} does not exist" exit $OCF_ERR_GENERIC fi ocf_log debug "validate: checking for required variables" for var in iqn path; do param="OCF_RESKEY_${var}" if [ -z "${!param}" ]; then ocf_log error "Missing resource parameter \"$var\"!" return $OCF_ERR_CONFIGURED fi done ocf_log debug "validate: checking for valid iomode" case "${OCF_RESKEY_iomode}" in fileio|blockio) ;; *) ocf_log error "Invalid iomode. Must be either fileio or blockio" return $OCF_ERR_CONFIGURED ;; esac return $OCF_SUCCESS } #=============================================================================== # main #------------------------------------------------------------------------------- # Make sure meta-data and usage always succeed case $__OCF_ACTION in meta-data) scstlun_meta_data exit $OCF_SUCCESS ;; usage|help) scstlun_usage exit $OCF_SUCCESS ;; esac # Anything other than meta-data and usage must pass validation scstlun_validate_all || exit $? # Translate each action into the appropriate function call case $__OCF_ACTION in start) scstlun_start;; stop) scstlun_stop;; monitor) scstlun_monitor;; validate-all) ;; *) scstlun_usage exit $OCF_ERR_UNIMPLEMENTED ;; esac rc=$? ocf_log debug "${OCF_RESOURCE_INSTANCE} $__OCF_ACTION returned $rc" exit $rc