[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.<reversed domain name>[: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