#!/bin/sh #=============================================================================== # scst, (c) 2010 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_allowed_portals #------------------------------------------------------------------------------- #=============================================================================== # Initialization #------------------------------------------------------------------------------- . ${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs export LANG=C LANGUAGE=C LC_ALL=C #=============================================================================== # Configuration #------------------------------------------------------------------------------- SCST_base="/sys/kernel/scst_tgt" #=============================================================================== # Meta-data #------------------------------------------------------------------------------- meta_data() { cat < 0.1 Configures 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). Exports a device via an SCST iSCSI Target/Lun pair The iSCSI Qualified Name (IQN) of the target that will be configured. iSCSI target IQN The path to the block device exposed. Block device path IncomingUser iSCSI CHAP username. IncomingUser iSCSI CHAP username IncomingUser iSCSI CHAP password. IncomingUser iSCSI CHAP password iSCSI network portal addresses that the initiators will be able to use (ex: "10.0.0.1"). By default, SCST will allow connections to all the listening IP addresses. NOTE, the format "IP:port" is not supported. iSCSI allowed portal addresses END } #=============================================================================== # usage #------------------------------------------------------------------------------- scst_usage() { cat <${SCST_base}/handlers/vdisk_fileio/mgmt if [ $? -ne 0 ]; then ocf_log err "FAILED to configure backend device ${devname}" return $OCF_ERR_GENERIC fi # Create the target ocf_log debug "creating target ${OCF_RESKEY_iqn}" echo "add_target ${OCF_RESKEY_iqn}" >${SCST_base}/targets/iscsi/mgmt if [ $? -ne 0 ]; then ocf_log err "FAILED to create target ${OCF_RESKEY_iqn}" return $OCF_ERR_GENERIC fi # Add allowed portals for portal in ${OCF_RESKEY_allowed_portals}; do ocf_log debug "adding allowed portal $portal to target ${OCF_RESKEY_iqn}" echo "add_target_attribute ${OCF_RESKEY_iqn} allowed_portal ${portal}" >${SCST_base}/targets/iscsi/mgmt if [ $? -ne 0 ]; then ocf_log debug "ERROR !!!" ocf_log err "FAILED to add portal ${portal} to target ${OCF_RESKEY_iqn}" return $OCF_ERR_GENERIC fi done # Configure target authentication ocf_log debug "adding CHAP credentials (${OCF_RESKEY_chap_username},${OCF_RESKEY_chap_password}) to target ${OCF_RESKEY_iqn}" echo "add_target_attribute ${OCF_RESKEY_iqn} IncomingUser ${OCF_RESKEY_chap_username} ${OCF_RESKEY_chap_password}" >${SCST_base}/targets/iscsi/mgmt if [ $? -ne 0 ]; then ocf_log err "FAILED to add CHAP credentials (${OCF_RESKEY_chap_username},${OCF_RESKEY_chap_password}) to target ${OCF_RESKEY_iqn}" return $OCF_ERR_GENERIC fi # Add backend device to target ocf_log debug "adding device ${devname} as LUN 0 to target ${OCF_RESKEY_iqn}" echo "add ${devname} 0" >${SCST_base}/targets/iscsi/${OCF_RESKEY_iqn}/luns/mgmt if [ $? -ne 0 ]; then ocf_log err "FAILED to add device ${devname} as LUN 0 to target ${OCF_RESKEY_iqn}" return $OCF_ERR_GENERIC fi # Finally, enable the target ocf_log debug "enabling target ${OCF_RESKEY_iqn}" echo 1 >${SCST_base}/targets/iscsi/${OCF_RESKEY_iqn}/enabled if [ $? -ne 0 ]; then ocf_log err "FAILED to enable target ${OCF_RESKEY_iqn}" return $OCF_ERR_GENERIC fi return $OCF_SUCCESS } #=============================================================================== # stop #------------------------------------------------------------------------------- scst_stop() { scst_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 "disabling target ${OCF_RESKEY_iqn}" echo 0 >${SCST_base}/targets/iscsi/${OCF_RESKEY_iqn}/enabled if [ $? -ne 0 ]; then ocf_log err "FAILED to disable target ${OCF_RESKEY_iqn}" return $OCF_ERR_GENERIC fi # Close all the existing sessions for s in `ls -1 ${SCST_base}/targets/iscsi/${OCF_RESKEY_iqn}/sessions` ; do ocf_log debug "disabling session $s on target ${OCF_RESKEY_iqn}" echo 1 >${SCST_base}/targets/iscsi/${OCF_RESKEY_iqn}/sessions/$s/force_close if [ $? -ne 0 ]; then ocf_log err "FAILED to disable session $s on target ${OCF_RESKEY_iqn}" return $OCF_ERR_GENERIC fi done # Wait a bit #sleep 5 # Remove LUN from target ocf_log debug "removing LUN 0 from target ${OCF_RESKEY_iqn}" echo "del 0" >${SCST_base}/targets/iscsi/${OCF_RESKEY_iqn}/luns/mgmt if [ $? -ne 0 ]; then ocf_log err "FAILED to remove LUN 0 from target ${OCF_RESKEY_iqn}" return $OCF_ERR_GENERIC fi # Wait a bit sleep 3 ocf_log debug "removing target ${OCF_RESKEY_iqn}" echo "del_target ${OCF_RESKEY_iqn}" >${SCST_base}/targets/iscsi/mgmt if [ $? -ne 0 ]; then ocf_log err "FAILED to remove target ${OCF_RESKEY_iqn}" return $OCF_ERR_GENERIC fi ocf_log debug "removing device ${devname}" echo "del_device ${devname}" >${SCST_base}/handlers/vdisk_fileio/mgmt if [ $? -ne 0 ]; then ocf_log err "FAILED to remove device ${devname}" return $OCF_ERR_GENERIC fi return $OCF_SUCCESS } #=============================================================================== # monitor #------------------------------------------------------------------------------- scst_monitor() { # Build SCST device name from path devname=`basename ${OCF_RESKEY_path}` # Check if underlying device is configured ocf_log debug "checking existence of ${SCST_base}/handlers/vdisk_fileio/${devname}" [ -e "${SCST_base}/handlers/vdisk_fileio/${devname}" ] if [ $? -ne 0 ]; then ocf_log debug "Device ${devname} not configured" return $OCF_NOT_RUNNING fi # Check if target iqn exists ocf_log debug "checking existence of ${SCST_base}/targets/iscsi/${OCF_RESKEY_iqn}" [ -d "${SCST_base}/targets/iscsi/${OCF_RESKEY_iqn}" ] if [ $? -ne 0 ]; then ocf_log debug "Target ${OCF_RESKEY_iqn} not found" return $OCF_NOT_RUNNING fi # Check if device is mapped to LUN ocf_log debug "checking existence of ${SCST_base}/targets/iscsi/${OCF_RESKEY_iqn}/luns/0" [ -e "${SCST_base}/targets/iscsi/${OCF_RESKEY_iqn}/luns/0" ] if [ $? -ne 0 ]; then ocf_log debug "LUN is not configured for target ${OCF_RESKEY_iqn}" return $OCF_NOT_RUNNING fi ocf_log debug "Monitor success" return $OCF_SUCCESS } #=============================================================================== # validate #------------------------------------------------------------------------------- scst_validate() { # Do we have all required variables? for var in iqn path chap_username chap_password; do param="OCF_RESKEY_${var}" if [ -z "${!param}" ]; then ocf_log error "Missing resource parameter \"$var\"!" return $OCF_ERR_CONFIGURED fi done # Is the required kernel functionality available? [ -d ${SCST_base}/targets/iscsi ] if [ $? -ne 0 ]; then ocf_log err "${SCST_base}/targets/iscsi does not exist or is not a directory -- check if required modules are loaded." return $OCF_ERR_INSTALLED fi return $OCF_SUCCESS } #=============================================================================== # main #------------------------------------------------------------------------------- case $1 in meta-data) meta_data exit $OCF_SUCCESS ;; usage|help) scst_usage exit $OCF_SUCCESS ;; esac # Everything except usage and meta-data must pass the validate test scst_validate || exit $? case $__OCF_ACTION in start) scst_start;; stop) scst_stop;; monitor) scst_monitor;; reload) ocf_log err "Reloading..." scst_start ;; validate-all) ;; *) scst_usage exit $OCF_ERR_UNIMPLEMENTED ;; esac rc=$? ocf_log debug "${OCF_RESOURCE_INSTANCE} $__OCF_ACTION : $rc" exit $rc