Applied.

Cheers,

Dejan

On Mon, Jul 06, 2009 at 07:58:39AM +0200, Florian Haas wrote:
> # HG changeset patch
> # User Florian Haas <florian.h...@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/

Reply via email to