[prev in list] [next in list] [prev in thread] [next in thread] 

List:       linux-ha-dev
Subject:    Re: [Linux-ha-dev] [PATCH] RA: iSCSITarget,
From:       Dejan Muhamedagic <dejanmm () fastmail ! fm>
Date:       2009-07-07 16:41:13
Message-ID: 20090707164112.GF5220 () rondo ! homenet
[Download RAW message or body]

Applied.

Cheers,

Dejan

On Mon, Jul 06, 2009 at 07:58:39AM +0200, Florian Haas wrote:
> # HG changeset patch
> # User Florian Haas <florian.haas@linbit.com>
> # Date 1246859908 -7200
> # Node ID 8132bf3e995fe0cc6f5124985d864f82a1d88ee0
> # Parent  ed09fd5d12fb494f94026bf01a5e3f16cbde5470
> RA: iSCSITarget, iSCSILogicalUnit: identify targets by IQN
> 
> While implementing LIO functionality for these RAs, I noticed a design
> flaw in the existing RAs: They identify a target by a numeric "target
> ID", which is actually IET/stgt specific and not supported in LIO (and
> presumably, other target implementations). So, I've rewritten these
> agents to identify and reference targets by iSCSI Qualified Name
> (IQN).
> 
> As a consequence:
> 
> - the iSCSITarget parameter previously named "name" (which was stupid
> and ambigious, anyway) is now named "iqn";
> 
> - the iSCSITarget parameter "tid" has gone away. Instead, where the
> implementation requires it, a "target ID" is discerned on the fly;
> 
> - the iSCSILogicalUnit resource parameter "tid" has also gone away;
> 
> - iSCSILogicalUnit now has a required parameter "target_iqn", which is
> to hold the target IQN and is, of course, used to assign the LU to
> an existing target.
> 
> Sorry for not realizing this design flaw sooner; this makes the patch
> much more disruptive than the incremental patches I usually try to
> submit. On the plus side, at least this hasn't yet been rolled into an
> official release, so shouldn't be affecting any production systems.
> 
> Cheers,
> Florian
> 
> diff -r ed09fd5d12fb -r 8132bf3e995f resources/OCF/iSCSILogicalUnit
> --- a/resources/OCF/iSCSILogicalUnit	Thu Jul 02 16:48:03 2009 +0200
> +++ b/resources/OCF/iSCSILogicalUnit	Mon Jul 06 07:58:28 2009 +0200
> @@ -67,12 +67,12 @@
> <content type="string" default="${OCF_RESKEY_implementation_default}"/>
> </parameter>
> 
> -<parameter name="tid" required="1" unique="0">
> +<parameter name="target_iqn" required="1" unique="0">
> <longdesc lang="en">
> -The numeric target ID. Must not be zero.
> +The iSCSI Qualified Name (IQN) that this Logical Unit belongs to.
> </longdesc>
> -<shortdesc lang="en">iSCSI target ID</shortdesc>
> -<content type="integer" />
> +<shortdesc lang="en">iSCSI target IQN</shortdesc>
> +<content type="string" />
> </parameter>
> 
> <parameter name="lun" required="1" unique="0">
> @@ -193,8 +193,15 @@
> 
> 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
> -	    params="Path=${OCF_RESKEY_path}"
> 	    if [ -n "${OCF_RESKEY_scsi_id}" ]; then
> 		params="${params} ScsiId=${OCF_RESKEY_scsi_id}"
> 	    fi
> @@ -203,7 +210,7 @@
> 	    fi
> 	    params="${params} ${OCF_RESKEY_additional_parameters}"
> 	    do_cmd ietadm --op new \
> -		--tid=${OCF_RESKEY_tid} \
> +		--tid=${TID} \
> 		--lun=${OCF_RESKEY_lun} \
> 		--params ${params// /,} && return $OCF_SUCCESS
> 	    ;;
> @@ -221,14 +228,14 @@
> 	    done
> 	    params="${params} ${OCF_RESKEY_additional_parameters}"
> 	    do_cmd tgtadm --lld iscsi --op new --mode logicalunit \
> -		--tid=${OCF_RESKEY_tid} \
> +		--tid=${TID} \
> 		--lun=${OCF_RESKEY_lun} \
> 	    	--backing-store ${OCF_RESKEY_path} || return $OCF_ERR_GENERIC
> 	    if [ -z "$params" ]; then
> 		return $OCF_SUCCESS
> 	    else
> 		do_cmd tgtadm --lld iscsi --op update --mode logicalunit \
> -		    --tid=${OCF_RESKEY_tid} \
> +		    --tid=${TID} \
> 		    --lun=${OCF_RESKEY_lun} \
> 		    --params ${params// /,} && return $OCF_SUCCESS
> 	    fi
> @@ -244,7 +251,7 @@
> 	    iet)
> 		# IET allows us to remove LUs while they are in use
> 		do_cmd ietadm --op delete \
> -		    --tid=${OCF_RESKEY_tid} \
> +		    --tid=${TID} \
> 		    --lun=${OCF_RESKEY_lun} && return $OCF_SUCCESS
> 		;;
> 	    tgt)
> @@ -255,7 +262,7 @@
> 		# decides that the LU is no longer in use, or we get
> 		# timed out by the LRM.
> 		while ! do_cmd tgtadm --lld iscsi --op delete --mode logicalunit \
> -		    --tid ${OCF_RESKEY_tid} \
> +		    --tid ${TID} \
> 		    --lun=${OCF_RESKEY_lun}; do
> 		    sleep 1
> 		done
> @@ -271,11 +278,26 @@
> iSCSILogicalUnit_monitor() {
> 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  ;;
> 	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 \
> @@ -288,7 +310,7 @@
> 
> iSCSILogicalUnit_validate() {
> # Do we have all required variables?
> -    for var in implementation tid lun path; do
> +    for var in implementation target_iqn lun path; do
> 	param="OCF_RESKEY_${var}"
> 	if [ -z "${!param}" ]; then
> 	    ocf_log error "Missing resource parameter \"$var\"!"
> @@ -310,21 +332,6 @@
> 	    return $OCF_ERR_CONFIGURED
> esac
> 
> -    # Do we have a valid target ID?
> -    [ $OCF_RESKEY_tid -ge 1 ]
> -    case $? in
> -	0)
> -	    # OK
> -	    ;;
> -	1)
> -	    ocf_log err "Invalid target ID $OCF_RESKEY_tid (must be greater than 0)."
> -	    return $OCF_ERR_CONFIGURED
> -	    ;;
> -	*)
> -	    ocf_log err "Invalid target ID $OCF_RESKEY_tid (must be an integer)."
> -	    return $OCF_ERR_CONFIGURED
> -    esac
> -
> # Do we have a valid LUN?
> case $OCF_RESKEY_implementation in
> 	iet)
> diff -r ed09fd5d12fb -r 8132bf3e995f resources/OCF/iSCSITarget
> --- a/resources/OCF/iSCSITarget	Thu Jul 02 16:48:03 2009 +0200
> +++ b/resources/OCF/iSCSITarget	Mon Jul 06 07:58:28 2009 +0200
> @@ -67,20 +67,12 @@
> <content type="string" default="${OCF_RESKEY_implementation_default}"/>
> </parameter>
> 
> -<parameter name="tid" required="1" unique="0">
> +<parameter name="iqn" required="1" unique="1">
> <longdesc lang="en">
> -The numeric target ID. Must not be zero.
> -</longdesc>
> -<shortdesc lang="en">iSCSI target ID</shortdesc>
> -<content type="integer" />
> -</parameter>
> -
> -<parameter name="name" required="1" unique="1">
> -<longdesc lang="en">
> -The logical target name. Should follow the conventional
> +The target iSCSI Qualified Name (IQN). Should follow the conventional
> "iqn.yyyy-mm.&lt;reversed domain name&gt;[:identifier]" syntax.
> </longdesc>
> -<shortdesc lang="en">iSCSI target name</shortdesc>
> +<shortdesc lang="en">iSCSI target IQN</shortdesc>
> <content type="string" />
> </parameter>
> 
> @@ -185,43 +177,62 @@
> 
> case $OCF_RESKEY_implementation in
> 	iet)
> +	    local lasttid
> +	    local tid
> +	    # Figure out the last used target ID, add 1 to get the new
> +	    # target ID.
> +	    lasttid=`sed -ne "s/tid:\([[:digit:]]\+\) name:.*/\1/p" < \
> /proc/net/iet/volume | sort -n | tail -n1` +	    [ -z "${lasttid}" ] && lasttid=0
> +	    tid=$((++lasttid))
> +	    # Create the target.
> 	    do_cmd ietadm --op new \
> -		--tid=${OCF_RESKEY_tid} \
> -		--params Name=${OCF_RESKEY_name} || return $OCF_ERR_GENERIC
> +		--tid=${tid} \
> +		--params Name=${OCF_RESKEY_iqn} || return $OCF_ERR_GENERIC
> +	    # Set additional parameters.
> 	    for param in ${OCF_RESKEY_additional_parameters}; do
> 		name=${param%=*}
> 		value=${param#*=}
> 		do_cmd ietadm --op update \
> -		    --tid=${OCF_RESKEY_tid} \
> +		    --tid=${tid} \
> 		    --params ${name}=${value} || return $OCF_ERR_GENERIC
> 	    done
> 	    # For iet, access to new targets is allowed by default. To
> 	    # specifically enable access based on initiator address,
> 	    # we must first deny access to the target globally, then
> 	    # re-enable by specific initiator.
> -	    if [ -n ${OCF_RESKEY_allowed_initiators} ]; then
> -		echo "${OCF_RESKEY_name} ALL" >> /etc/initiators.deny
> -		echo "${OCF_RESKEY_name} ${OCF_RESKEY_initiators// /,}" >> /etc/initiators.allow
> +	    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  fi
> 	    # In iet, adding a new user and assigning it to a target
> 	    # is one operation.
> 	    if [ -n "${OCF_RESKEY_username}" ]; then
> 		do_cmd ietadm --op new --user \
> -		    --tid=${OCF_RESKEY_tid} \
> +		    --tid=${tid} \
> 		    --params=IncomingUser=${OCF_RESKEY_username},Password=${OCF_RESKEY_password} \
> \  || return $OCF_ERR_GENERIC
> 	    fi
> 	    return $OCF_SUCCESS
> 	    ;;
> 	tgt)
> +	    local lasttid
> +	    local tid
> +	    # Figure out the last used target ID, add 1 to get the new
> +	    # target ID.
> +	    lasttid=`tgtadm --lld iscsi --op show --mode target \
> +                | sed -ne "s/^Target \([[:digit:]]\+\): .*/\1/p" | sort -n | tail \
> -n1` +	    [ -z "${lasttid}" ] && lasttid=0
> +	    tid=$((++lasttid))
> +	    # Create the target.
> 	    do_cmd tgtadm --lld iscsi --op new --mode target \
> -		--tid=${OCF_RESKEY_tid} \
> -		--targetname ${OCF_RESKEY_name} || return $OCF_ERR_GENERIC
> +		--tid=${tid} \
> +		--targetname ${OCF_RESKEY_iqn} || return $OCF_ERR_GENERIC
> +	    # Set parameters.
> 	    for param in ${OCF_RESKEY_additional_parameters}; do
> 		name=${param%=*}
> 		value=${param#*=}
> 		do_cmd tgtadm --lld iscsi --op update --mode target \
> -		    --tid=${OCF_RESKEY_tid} \
> +		    --tid=${tid} \
> 		    --name=${name} --value=${value} || return $OCF_ERR_GENERIC
> 	    done
> 	    # For tgt, we always have to add access per initiator;
> @@ -230,7 +241,7 @@
> 	    # keyword ALL.
> 	    for initiator in ${OCF_RESKEY_allowed_initiators=ALL}; do
> 		do_cmd tgtadm --lld iscsi --op bind --mode target \
> -		    --tid=${OCF_RESKEY_tid} \
> +		    --tid=${tid} \
> 		    --initiator-address=${initiator} || return $OCF_ERR_GENERIC
> 	    done
> 	    # In tgt, we must first create a user account, then assign
> @@ -240,7 +251,7 @@
> 		    --user=${OCF_RESKEY_username} \
> 		    --password=${OCF_RESKEY_password} || return	$OCF_ERR_GENERIC
> 		do_cmd tgtadm --lld iscsi --mode account --op bind \
> -		    --tid=${OCF_RESKEY_tid} \
> +		    --tid=${tid} \
> 		    --user=${OCF_RESKEY_username} || return $OCF_ERR_GENERIC
> 	    fi
> 	    return $OCF_SUCCESS
> @@ -252,12 +263,19 @@
> iSCSITarget_stop() {
> iSCSITarget_monitor
> if [ $? =  $OCF_SUCCESS ]; then
> +	local tid
> 	case $OCF_RESKEY_implementation in
> 	    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}"
> +		    return $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:'${OCF_RESKEY_tid}' /,/^tid/ {
> +		set -- $(sed -ne '/^tid:'${tid}' /,/^tid/ {
> /^[[:space:]]*sid:\([0-9]\+\)/ {
> s/^[[:space:]]*sid:\([0-9]*\).*/--sid=\1/; h;
> };
> @@ -268,35 +286,40 @@
> 		while [[ -n $2 ]]; do
> # $2 $1 looks like "--sid=X --cid=Y"
> 		    do_cmd ietadm --op delete \
> -			     --tid=${OCF_RESKEY_tid} $2 $1
> +			     --tid=${tid} $2 $1
> 		    shift 2
> 		done
> 	        # In iet, unassigning a user from a target and
> 		# deleting the user account is one operation.
> 		if [ -n "${OCF_RESKEY_username}" ]; then
> 		    do_cmd ietadm --op delete --user \
> -			--tid=${OCF_RESKEY_tid} \
> +			--tid=${tid} \
> 			--params=IncomingUser=${OCF_RESKEY_username} \
> 			|| return $OCF_ERR_GENERIC
> 		fi
> 		do_cmd ietadm --op delete \
> -		    --tid=${OCF_RESKEY_tid} || return $OCF_ERR_GENERIC
> -		if [ -n ${OCF_RESKEY_allowed_initiators} ]; then
> -		    # Avoid stale /etc/initiators.{allow,deny} entries
> -		    # for this target
> -		    do_cmd sed -e "/^${OCF_RESKEY_name}[[:space:]]/d" \
> -			-i /etc/initiators.deny
> -		    do_cmd sed -e "/^${OCF_RESKEY_name}[[:space:]]/d" \
> -			-i /etc/initiators.allow
> -		fi
> +		    --tid=${tid} || return $OCF_ERR_GENERIC
> +		# Avoid stale /etc/initiators.{allow,deny} entries
> +		# for this target
> +		do_cmd sed -e "/^${OCF_RESKEY_iqn}[[:space:]]/d" \
> +		    -i /etc/initiators.deny
> +		do_cmd sed -e "/^${OCF_RESKEY_iqn}[[:space:]]/d" \
> +		    -i /etc/initiators.allow
> 		return $OCF_SUCCESS
> 		;;
> 	    tgt)
> +		# Figure out the target ID
> +		tid=`tgtadm --lld iscsi --op show --mode target \
> +		    | sed -ne "s/^Target \([[:digit:]]\+\): ${OCF_RESKEY_iqn}/\1/p"`
> +		if [ -z "$tid" ]; then
> +		    ocf_log err "Failed to retrieve target ID for IQN ${OCF_RESKEY_iqn}"
> +		    return $OCF_ERR_GENERIC
> +		fi
> 		# 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 '${OCF_RESKEY_tid}':/,/^Target/ {
> +		    | sed -ne '/^Target '${tid}':/,/^Target/ {
> /^[[:space:]]*I_T nexus: \([0-9]\+\)/ {
> s/^.*: \([0-9]*\).*/--sid=\1/; h;
> };
> @@ -308,20 +331,20 @@
> 		while [[ -n $2 ]]; do
> # $2 $1 looks like "--sid=X --cid=Y"
> 		    do_cmd tgtadm --lld iscsi --op delete --mode connection \
> -			--tid=${OCF_RESKEY_tid} $2 $1
> +			--tid=${tid} $2 $1
> 		    shift 2
> 		done
> 	        # In tgt, we must first unbind the user account from
> 		# the target, then remove the account itself.
> 		if [ -n "${OCF_RESKEY_username}" ]; then
> 		    do_cmd tgtadm --lld iscsi --mode account --op unbind \
> -			--tid=${OCF_RESKEY_tid} \
> +			--tid=${tid} \
> 			--user=${OCF_RESKEY_username} || return $OCF_ERR_GENERIC
> 		    do_cmd tgtadm --lld iscsi --mode account --op delete \
> 			--user=${OCF_RESKEY_username} || return $OCF_ERR_GENERIC
> 		fi
> 		do_cmd tgtadm --lld iscsi --op delete --mode target \
> -		    --tid=${OCF_RESKEY_tid} && return $OCF_SUCCESS
> +		    --tid=${tid} && return $OCF_SUCCESS
> 		# In tgt, we don't have to worry about our ACL
> 		# entries. They are automatically removed upon target
> 		# deletion.
> @@ -336,11 +359,11 @@
> iSCSITarget_monitor() {
> case $OCF_RESKEY_implementation in
> 	iet)
> -	    grep -q "tid:${OCF_RESKEY_tid} name:${OCF_RESKEY_name}" /proc/net/iet/volume \
> && return $OCF_SUCCESS +	    grep -Eq "tid:[0-9]+ name:${OCF_RESKEY_iqn}" \
> /proc/net/iet/volume && return $OCF_SUCCESS  ;;
> 	tgt)
> -	    do_cmd tgtadm --lld iscsi --op show --mode target \
> -		| grep -q "Target ${OCF_RESKEY_tid}: ${OCF_RESKEY_name}" && return $OCF_SUCCESS
> +	    tgtadm --lld iscsi --op show --mode target \
> +		| grep -Eq "Target [0-9]+: ${OCF_RESKEY_iqn}" && return $OCF_SUCCESS
> 	    ;;
> esac
> 
> @@ -349,7 +372,7 @@
> 
> iSCSITarget_validate() {
> # Do we have all required variables?
> -    for var in implementation tid name; do
> +    for var in implementation iqn; do
> 	param="OCF_RESKEY_${var}"
> 	if [ -z "${!param}" ]; then
> 	    ocf_log error "Missing resource parameter \"$var\"!"
> @@ -371,21 +394,6 @@
> 	    return $OCF_ERR_CONFIGURED
> esac
> 
> -    # Do we have a valid target ID?
> -    [ $OCF_RESKEY_tid -ge 1 ]
> -    case $? in
> -	0)
> -	    # OK
> -	    ;;
> -	1)
> -	    ocf_log err "Invalid target ID $OCF_RESKEY_tid (must be greater than 0)."
> -	    return $OCF_ERR_CONFIGURED
> -	    ;;
> -	*)
> -	    ocf_log err "Invalid target ID $OCF_RESKEY_tid (must be an integer)."
> -	    return $OCF_ERR_CONFIGURED
> -    esac
> -
> # Is the required kernel functionality available?
> case $OCF_RESKEY_implementation in
> 	iet)
> _______________________________________________________
> Linux-HA-Dev: Linux-HA-Dev@lists.linux-ha.org
> http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
> Home Page: http://linux-ha.org/
_______________________________________________________
Linux-HA-Dev: Linux-HA-Dev@lists.linux-ha.org
http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
Home Page: http://linux-ha.org/


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic