All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] v1 - Add exclusive locking option to block-iscsi
@ 2016-05-05  2:32 Steven Haigh
  2016-05-05  5:52 ` [PATCH] v2 " Steven Haigh
  0 siblings, 1 reply; 10+ messages in thread
From: Steven Haigh @ 2016-05-05  2:32 UTC (permalink / raw)
  To: xen-devel; +Cc: Roger Pau Monné

[-- Attachment #1: Type: text/plain, Size: 1386 bytes --]

Overview

If you're using iSCSI, you can mount a target by multiple Dom0 machines 
on the same target. For non-cluster aware filesystems, this can lead to 
disk corruption and general bad times by all. The iSCSI protocol allows 
the use of persistent reservations as per the SCSI disk spec. Low level 
SCSI commands for locking are handled by the sg_persist program (bundled 
with sg3_utils package in EL).

The aim of this patch is to create a 'locktarget=y' option specified 
within the disk 'target' command for iSCSI to lock the target in 
exclusive mode on VM start with a key generated from the local systems 
IP, and release this lock on the shutdown of the DomU.

Example Config:
disk            = 
['script=block-iscsi,vdev=xvda,target=iqn=iqn.1986-03.com.sun:02:mytarget,portal=iscsi.example.com,locktarget=y']

In writing this, I have also re-factored parts of the script to put some 
things in what I believe to be a better place to make expansion easier. 
This is mainly in removing functions that purely call other functions 
with no actual code execution.

Signed-off-by: Steven Haigh <netwiz@crc.id.au>

(on a side note, first time I've submitted a patch to the list and I'm 
currently stuck on a webmail client, so apologies in advance if this all 
goes wrong ;)

-- 
Steven Haigh

Email: netwiz@crc.id.au
Web: https://www.crc.id.au
Phone: (03) 9001 6090 - 0412 935 897

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: block-iscsi-locking-v1.patch --]
[-- Type: text/x-diff; name=block-iscsi-locking-v1.patch, Size: 4324 bytes --]

--- block-iscsi 2016-02-10 01:44:19.000000000 +1100
+++ block-iscsi-lock    2016-05-05 12:30:24.831903983 +1000
@@ -31,33 +31,37 @@
     echo $1 | sed "s/^\("$2"\)//"
 }
 
-check_tools()
-{
-    if ! command -v iscsiadm > /dev/null 2>&1; then
-        fatal "Unable to find iscsiadm tool"
-    fi
-    if [ "$multipath" = "y" ] && ! command -v multipath > /dev/null 2>&1; then
-        fatal "Unable to find multipath"
-    fi
-}
-
 # Sets the following global variables based on the params field passed in as
 # a parameter: iqn, portal, auth_method, user, multipath, password
 parse_target()
 {
     # set multipath default value
     multipath="n"
-    for param in $(echo "$1" | tr "," "\n")
-    do
+    for param in $(echo "$1" | tr "," "\n"); do
         case $param in
         iqn=*)
             iqn=$(remove_label $param "iqn=")
+            if ! command -v iscsiadm > /dev/null 2>&1; then
+                fatal "Could not find iscsiadm tool."
+            fi
             ;;
         portal=*)
             portal=$(remove_label $param "portal=")
             ;;
         multipath=*)
             multipath=$(remove_label $param "multipath=")
+            if ! command -v multipath > /dev/null 2>&1; then
+                fatal "Multipath selected, but no multipath tools found"
+            fi
+            ;;
+        locktarget=*)
+            locktarget=$(remove_label $param "locktarget=")
+            if ! command -v sg_persist > /dev/null 2>&1; then
+                fatal "Locking requested but no sg_persist found"
+            fi
+            if ! command -v gethostip > /dev/null 2>&1; then
+                fatal "Locking requested but no gethostip found for key generation"
+            fi
             ;;
         esac
     done
@@ -96,38 +100,29 @@
     fi
 }
 
-# Attaches the target $iqn in $portal and sets $dev to point to the
-# multipath device
-attach()
-{
-    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --login > /dev/null
-    find_device
-}
-
-# Discovers targets in $portal and checks that $iqn is one of those targets
-# Also sets the auth parameters to attach the device
-prepare()
-{
-    # Check if target is already opened
-    iscsiadm -m session 2>&1 | grep -q "$iqn" && fatal "Device already opened"
-    # Discover portal targets
-    iscsiadm -m discovery -t st -p $portal 2>&1 | grep -q "$iqn" || \
-        fatal "No matching target iqn found"
-}

-# Attaches the device and writes xenstore backend entries to connect
-# the device
-add()
+lock_device()
 {
-    attach
-    write_dev $dev
+    ## Lock the iSCSI target as Exclusive Access.
+    key=$(gethostip -x $(uname -n))
+    if ! sg_persist -d ${dev} -o -G -S ${key} > /dev/null; then
+        unlock_device
+        iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
+        fatal "iSCSI LOCK: Failed to register with target"
+    fi
+    if ! sg_persist -d ${dev} -o -R -K ${key} -T 6 > /dev/null; then
+        unlock_device
+        iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
+        fatal "iSCSI LOCK: Failed to set persistent reservation"
+    fi
 }

-# Disconnects the device
-remove()
+unlock_device()
 {
-    find_device
-    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
+    ## Unlock the iSCSI target.
+    key=$(gethostip -x $(uname -n))
+    sg_persist -d ${dev} -o -L -K ${key} -T 6 > /dev/null || true
+    sg_persist -d ${dev} -o -G -K ${key} -S 0 > /dev/null || true
 }

 command=$1
@@ -138,14 +133,27 @@

 parse_target "$target"

-check_tools || exit 1
-
 case $command in
 add)
-    prepare
-    add
+    # Check if target is already opened
+    iscsiadm -m session 2>&1 | grep -q "$iqn" && fatal "Device already opened"
+    # Discover portal targets
+    iscsiadm -m discovery -t st -p $portal 2>&1 | grep -q "$iqn" || \
+        fatal "No matching target iqn found"
+
+    ## Login to the iSCSI target.
+    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --login > /dev/null
+    find_device
+    if [ "$locktarget" = "y" ]; then
+        lock_device
+    fi
+    write_dev $dev
     ;;
 remove)
+    if [ "$locktarget" = "y" ]; then
+        unlock_device
+    fi
+    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
     remove
     ;;
 *)

[-- Attachment #3: Type: text/plain, Size: 126 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH] v2 - Add exclusive locking option to block-iscsi
  2016-05-05  2:32 [PATCH] v1 - Add exclusive locking option to block-iscsi Steven Haigh
@ 2016-05-05  5:52 ` Steven Haigh
  2016-05-06  9:09   ` Roger Pau Monné
  2016-05-09  4:22   ` [PATCH] v3 " Steven Haigh
  0 siblings, 2 replies; 10+ messages in thread
From: Steven Haigh @ 2016-05-05  5:52 UTC (permalink / raw)
  To: xen-devel; +Cc: Roger Pau Monné

[-- Attachment #1: Type: text/plain, Size: 1634 bytes --]

On 2016-05-05 12:32, Steven Haigh wrote:
> Overview
> 
> If you're using iSCSI, you can mount a target by multiple Dom0
> machines on the same target. For non-cluster aware filesystems, this
> can lead to disk corruption and general bad times by all. The iSCSI
> protocol allows the use of persistent reservations as per the SCSI
> disk spec. Low level SCSI commands for locking are handled by the
> sg_persist program (bundled with sg3_utils package in EL).
> 
> The aim of this patch is to create a 'locktarget=y' option specified
> within the disk 'target' command for iSCSI to lock the target in
> exclusive mode on VM start with a key generated from the local systems
> IP, and release this lock on the shutdown of the DomU.
> 
> Example Config:
> disk            =
> ['script=block-iscsi,vdev=xvda,target=iqn=iqn.1986-03.com.sun:02:mytarget,portal=iscsi.example.com,locktarget=y']
> 
> In writing this, I have also re-factored parts of the script to put
> some things in what I believe to be a better place to make expansion
> easier. This is mainly in removing functions that purely call other
> functions with no actual code execution.
> 
> Signed-off-by: Steven Haigh <netwiz@crc.id.au>
> 
> (on a side note, first time I've submitted a patch to the list and I'm
> currently stuck on a webmail client, so apologies in advance if this
> all goes wrong ;)

Changes in v2:
Bugfix: Call find_device to locate the /dev/sdX component of the iSCSI 
target before trying to run unlock_device().

Apologies for this oversight.

-- 
Steven Haigh

Email: netwiz@crc.id.au
Web: https://www.crc.id.au
Phone: (03) 9001 6090 - 0412 935 897

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: block-iscsi-locking-v2.patch --]
[-- Type: text/x-diff; name=block-iscsi-locking-v2.patch, Size: 4355 bytes --]

--- block-iscsi 2016-02-10 01:44:19.000000000 +1100
+++ block-iscsi-lock    2016-05-05 15:42:09.557191235 +1000
@@ -31,33 +31,37 @@
     echo $1 | sed "s/^\("$2"\)//"
 }
 
-check_tools()
-{
-    if ! command -v iscsiadm > /dev/null 2>&1; then
-        fatal "Unable to find iscsiadm tool"
-    fi
-    if [ "$multipath" = "y" ] && ! command -v multipath > /dev/null 2>&1; then
-        fatal "Unable to find multipath"
-    fi
-}
-
 # Sets the following global variables based on the params field passed in as
 # a parameter: iqn, portal, auth_method, user, multipath, password
 parse_target()
 {
     # set multipath default value
     multipath="n"
-    for param in $(echo "$1" | tr "," "\n")
-    do
+    for param in $(echo "$1" | tr "," "\n"); do
         case $param in
         iqn=*)
             iqn=$(remove_label $param "iqn=")
+            if ! command -v iscsiadm > /dev/null 2>&1; then
+                fatal "Could not find iscsiadm tool."
+            fi
             ;;
         portal=*)
             portal=$(remove_label $param "portal=")
             ;;
         multipath=*)
             multipath=$(remove_label $param "multipath=")
+            if ! command -v multipath > /dev/null 2>&1; then
+                fatal "Multipath selected, but no multipath tools found"
+            fi
+            ;;
+        locktarget=*)
+            locktarget=$(remove_label $param "locktarget=")
+            if ! command -v sg_persist > /dev/null 2>&1; then
+                fatal "Locking requested but no sg_persist found"
+            fi
+            if ! command -v gethostip > /dev/null 2>&1; then
+                fatal "Locking requested but no gethostip found for key generation"
+            fi
             ;;
         esac
     done
@@ -96,38 +100,29 @@
     fi
 }
 
-# Attaches the target $iqn in $portal and sets $dev to point to the
-# multipath device
-attach()
-{
-    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --login > /dev/null
-    find_device
-}
 
-# Discovers targets in $portal and checks that $iqn is one of those targets
-# Also sets the auth parameters to attach the device
-prepare()
+lock_device()
 {
-    # Check if target is already opened
-    iscsiadm -m session 2>&1 | grep -q "$iqn" && fatal "Device already opened"
-    # Discover portal targets
-    iscsiadm -m discovery -t st -p $portal 2>&1 | grep -q "$iqn" || \
-        fatal "No matching target iqn found"
-}
-
-# Attaches the device and writes xenstore backend entries to connect
-# the device
-add()
-{
-    attach
-    write_dev $dev
+    ## Lock the iSCSI target as Exclusive Access.
+    key=$(gethostip -x $(uname -n))
+    if ! sg_persist -d ${dev} -o -G -S ${key} > /dev/null; then
+        unlock_device
+        iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
+        fatal "iSCSI LOCK: Failed to register with target"
+    fi
+    if ! sg_persist -d ${dev} -o -R -K ${key} -T 6 > /dev/null; then
+        unlock_device
+        iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
+        fatal "iSCSI LOCK: Failed to set persistent reservation"
+    fi
 }
 
-# Disconnects the device
-remove()
+unlock_device()
 {
-    find_device
-    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
+    ## Unlock the iSCSI target.
+    key=$(gethostip -x $(uname -n))
+    sg_persist -d ${dev} -o -L -K ${key} -T 6 > /dev/null || true
+    sg_persist -d ${dev} -o -G -K ${key} -S 0 > /dev/null || true
 }

 command=$1
@@ -138,15 +133,28 @@

 parse_target "$target"

-check_tools || exit 1
-
 case $command in
 add)
-    prepare
-    add
+    # Check if target is already opened
+    iscsiadm -m session 2>&1 | grep -q "$iqn" && fatal "Device already opened"
+    # Discover portal targets
+    iscsiadm -m discovery -t st -p $portal 2>&1 | grep -q "$iqn" || \
+        fatal "No matching target iqn found"
+
+    ## Login to the iSCSI target.
+    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --login > /dev/null
+    find_device
+    if [ "$locktarget" = "y" ]; then
+        lock_device
+    fi
+    write_dev $dev
     ;;
 remove)
-    remove
+    find_device
+    if [ "$locktarget" = "y" ]; then
+        unlock_device
+    fi
+    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
     ;;
 *)
     exit 1

[-- Attachment #3: Type: text/plain, Size: 126 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] v2 - Add exclusive locking option to block-iscsi
  2016-05-05  5:52 ` [PATCH] v2 " Steven Haigh
@ 2016-05-06  9:09   ` Roger Pau Monné
  2016-05-06  9:44     ` Steven Haigh
  2016-05-09  4:22   ` [PATCH] v3 " Steven Haigh
  1 sibling, 1 reply; 10+ messages in thread
From: Roger Pau Monné @ 2016-05-06  9:09 UTC (permalink / raw)
  To: Steven Haigh; +Cc: xen-devel

On Thu, May 05, 2016 at 03:52:30PM +1000, Steven Haigh wrote:
> On 2016-05-05 12:32, Steven Haigh wrote:
> > Overview
> > 
> > If you're using iSCSI, you can mount a target by multiple Dom0
> > machines on the same target. For non-cluster aware filesystems, this
> > can lead to disk corruption and general bad times by all. The iSCSI
> > protocol allows the use of persistent reservations as per the SCSI
> > disk spec. Low level SCSI commands for locking are handled by the
> > sg_persist program (bundled with sg3_utils package in EL).
> > 
> > The aim of this patch is to create a 'locktarget=y' option specified
> > within the disk 'target' command for iSCSI to lock the target in
> > exclusive mode on VM start with a key generated from the local systems
> > IP, and release this lock on the shutdown of the DomU.
> > 
> > Example Config:
> > disk            =
> > ['script=block-iscsi,vdev=xvda,target=iqn=iqn.1986-03.com.sun:02:mytarget,portal=iscsi.example.com,locktarget=y']
> > 
> > In writing this, I have also re-factored parts of the script to put
> > some things in what I believe to be a better place to make expansion
> > easier. This is mainly in removing functions that purely call other
> > functions with no actual code execution.
> > 
> > Signed-off-by: Steven Haigh <netwiz@crc.id.au>
> > 
> > (on a side note, first time I've submitted a patch to the list and I'm
> > currently stuck on a webmail client, so apologies in advance if this
> > all goes wrong ;)
> 
> Changes in v2:
> Bugfix: Call find_device to locate the /dev/sdX component of the iSCSI
> target before trying to run unlock_device().
> 
> Apologies for this oversight.

Thanks for the patch! A couple of comments below.

> -- 
> Steven Haigh
> 
> Email: netwiz@crc.id.au
> Web: https://www.crc.id.au
> Phone: (03) 9001 6090 - 0412 935 897

> --- block-iscsi 2016-02-10 01:44:19.000000000 +1100
> +++ block-iscsi-lock    2016-05-05 15:42:09.557191235 +1000
> @@ -31,33 +31,37 @@
>      echo $1 | sed "s/^\("$2"\)//"
>  }
>  
> -check_tools()
> -{
> -    if ! command -v iscsiadm > /dev/null 2>&1; then
> -        fatal "Unable to find iscsiadm tool"
> -    fi
> -    if [ "$multipath" = "y" ] && ! command -v multipath > /dev/null 2>&1; then
> -        fatal "Unable to find multipath"
> -    fi
> -}
> -
>  # Sets the following global variables based on the params field passed in as
>  # a parameter: iqn, portal, auth_method, user, multipath, password
>  parse_target()
>  {
>      # set multipath default value
>      multipath="n"
> -    for param in $(echo "$1" | tr "," "\n")
> -    do
> +    for param in $(echo "$1" | tr "," "\n"); do
>          case $param in
>          iqn=*)
>              iqn=$(remove_label $param "iqn=")
> +            if ! command -v iscsiadm > /dev/null 2>&1; then
> +                fatal "Could not find iscsiadm tool."
> +            fi
>              ;;
>          portal=*)
>              portal=$(remove_label $param "portal=")
>              ;;
>          multipath=*)
>              multipath=$(remove_label $param "multipath=")
> +            if ! command -v multipath > /dev/null 2>&1; then
> +                fatal "Multipath selected, but no multipath tools found"
> +            fi
> +            ;;
> +        locktarget=*)
> +            locktarget=$(remove_label $param "locktarget=")
> +            if ! command -v sg_persist > /dev/null 2>&1; then
> +                fatal "Locking requested but no sg_persist found"
> +            fi
> +            if ! command -v gethostip > /dev/null 2>&1; then
> +                fatal "Locking requested but no gethostip found for key generation"
> +            fi

Why don't you just add this to check_tools? In any case, if you want to fold 
check_tools functionality into parse_target I think it should be done in a 
separate patch in order for it to be easier to review.

IMHO, I prefer to have both functions separated, because it's quite clear 
what parse_target and check_tools do. 

>              ;;
>          esac
>      done
> @@ -96,38 +100,29 @@
>      fi
>  }
>  
> -# Attaches the target $iqn in $portal and sets $dev to point to the
> -# multipath device
> -attach()
> -{
> -    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --login > /dev/null
> -    find_device
> -}
>  
> -# Discovers targets in $portal and checks that $iqn is one of those targets
> -# Also sets the auth parameters to attach the device
> -prepare()
> +lock_device()
>  {
> -    # Check if target is already opened
> -    iscsiadm -m session 2>&1 | grep -q "$iqn" && fatal "Device already opened"
> -    # Discover portal targets
> -    iscsiadm -m discovery -t st -p $portal 2>&1 | grep -q "$iqn" || \
> -        fatal "No matching target iqn found"
> -}
> -
> -# Attaches the device and writes xenstore backend entries to connect
> -# the device
> -add()
> -{
> -    attach
> -    write_dev $dev
> +    ## Lock the iSCSI target as Exclusive Access.
> +    key=$(gethostip -x $(uname -n))

Isn't there anything else that can be used as a key? What would happen if 
the host IP changes while the VM is running? Couldn't the iqn (or a hash 
of it) be used as the key?

> +    if ! sg_persist -d ${dev} -o -G -S ${key} > /dev/null; then
> +        unlock_device
> +        iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
> +        fatal "iSCSI LOCK: Failed to register with target"
> +    fi
> +    if ! sg_persist -d ${dev} -o -R -K ${key} -T 6 > /dev/null; then
> +        unlock_device
> +        iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
> +        fatal "iSCSI LOCK: Failed to set persistent reservation"
> +    fi
>  }
>  
> -# Disconnects the device
> -remove()
> +unlock_device()
>  {
> -    find_device
> -    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
> +    ## Unlock the iSCSI target.
> +    key=$(gethostip -x $(uname -n))
> +    sg_persist -d ${dev} -o -L -K ${key} -T 6 > /dev/null || true
> +    sg_persist -d ${dev} -o -G -K ${key} -S 0 > /dev/null || true

I'm not sure whether the return code of those functions shouldn't be 
checked. I know this is the teardown path, so there's not much that can 
be done here on failure, but it seems like at least the script should check 
for the return code '3', and then retry the command. According to 
sg3_utils(8), a '3' means:

"the DEVICE reports that it is not ready for the operation requested. The 
device may be in the process of becoming ready (e.g. spinning up but not at 
speed) so the utility may work after a wait."

>  }
> 
>  command=$1
> @@ -138,15 +133,28 @@
> 
>  parse_target "$target"
> 
> -check_tools || exit 1
> -
>  case $command in
>  add)
> -    prepare
> -    add
> +    # Check if target is already opened
> +    iscsiadm -m session 2>&1 | grep -q "$iqn" && fatal "Device already opened"
> +    # Discover portal targets
> +    iscsiadm -m discovery -t st -p $portal 2>&1 | grep -q "$iqn" || \
> +        fatal "No matching target iqn found"
> +
> +    ## Login to the iSCSI target.
> +    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --login > /dev/null
> +    find_device
> +    if [ "$locktarget" = "y" ]; then
> +        lock_device
> +    fi
> +    write_dev $dev
>      ;;
>  remove)
> -    remove
> +    find_device
> +    if [ "$locktarget" = "y" ]; then
> +        unlock_device
> +    fi
> +    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null

You are doing quite of a rework of the script here (by removing/merging a 
bunch of functions). I think this should be sent as a separate patch, in 
order to ease the review (mixing new features with code cleanup makes it 
quite hard to review).

Roger.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] v2 - Add exclusive locking option to block-iscsi
  2016-05-06  9:09   ` Roger Pau Monné
@ 2016-05-06  9:44     ` Steven Haigh
  0 siblings, 0 replies; 10+ messages in thread
From: Steven Haigh @ 2016-05-06  9:44 UTC (permalink / raw)
  To: Roger Pau Monné; +Cc: xen-devel


[-- Attachment #1.1.1: Type: text/plain, Size: 10239 bytes --]

On 6/05/2016 7:09 PM, Roger Pau Monné wrote:
> On Thu, May 05, 2016 at 03:52:30PM +1000, Steven Haigh wrote:
>> On 2016-05-05 12:32, Steven Haigh wrote:
>>> Overview
>>>
>>> If you're using iSCSI, you can mount a target by multiple Dom0
>>> machines on the same target. For non-cluster aware filesystems, this
>>> can lead to disk corruption and general bad times by all. The iSCSI
>>> protocol allows the use of persistent reservations as per the SCSI
>>> disk spec. Low level SCSI commands for locking are handled by the
>>> sg_persist program (bundled with sg3_utils package in EL).
>>>
>>> The aim of this patch is to create a 'locktarget=y' option specified
>>> within the disk 'target' command for iSCSI to lock the target in
>>> exclusive mode on VM start with a key generated from the local systems
>>> IP, and release this lock on the shutdown of the DomU.
>>>
>>> Example Config:
>>> disk            =
>>> ['script=block-iscsi,vdev=xvda,target=iqn=iqn.1986-03.com.sun:02:mytarget,portal=iscsi.example.com,locktarget=y']
>>>
>>> In writing this, I have also re-factored parts of the script to put
>>> some things in what I believe to be a better place to make expansion
>>> easier. This is mainly in removing functions that purely call other
>>> functions with no actual code execution.
>>>
>>> Signed-off-by: Steven Haigh <netwiz@crc.id.au>
>>>
>>> (on a side note, first time I've submitted a patch to the list and I'm
>>> currently stuck on a webmail client, so apologies in advance if this
>>> all goes wrong ;)
>>
>> Changes in v2:
>> Bugfix: Call find_device to locate the /dev/sdX component of the iSCSI
>> target before trying to run unlock_device().
>>
>> Apologies for this oversight.
> 
> Thanks for the patch! A couple of comments below.
> 
>> -- 
>> Steven Haigh
>>
>> Email: netwiz@crc.id.au
>> Web: https://www.crc.id.au
>> Phone: (03) 9001 6090 - 0412 935 897
> 
>> --- block-iscsi 2016-02-10 01:44:19.000000000 +1100
>> +++ block-iscsi-lock    2016-05-05 15:42:09.557191235 +1000
>> @@ -31,33 +31,37 @@
>>      echo $1 | sed "s/^\("$2"\)//"
>>  }
>>  
>> -check_tools()
>> -{
>> -    if ! command -v iscsiadm > /dev/null 2>&1; then
>> -        fatal "Unable to find iscsiadm tool"
>> -    fi
>> -    if [ "$multipath" = "y" ] && ! command -v multipath > /dev/null 2>&1; then
>> -        fatal "Unable to find multipath"
>> -    fi
>> -}
>> -
>>  # Sets the following global variables based on the params field passed in as
>>  # a parameter: iqn, portal, auth_method, user, multipath, password
>>  parse_target()
>>  {
>>      # set multipath default value
>>      multipath="n"
>> -    for param in $(echo "$1" | tr "," "\n")
>> -    do
>> +    for param in $(echo "$1" | tr "," "\n"); do
>>          case $param in
>>          iqn=*)
>>              iqn=$(remove_label $param "iqn=")
>> +            if ! command -v iscsiadm > /dev/null 2>&1; then
>> +                fatal "Could not find iscsiadm tool."
>> +            fi
>>              ;;
>>          portal=*)
>>              portal=$(remove_label $param "portal=")
>>              ;;
>>          multipath=*)
>>              multipath=$(remove_label $param "multipath=")
>> +            if ! command -v multipath > /dev/null 2>&1; then
>> +                fatal "Multipath selected, but no multipath tools found"
>> +            fi
>> +            ;;
>> +        locktarget=*)
>> +            locktarget=$(remove_label $param "locktarget=")
>> +            if ! command -v sg_persist > /dev/null 2>&1; then
>> +                fatal "Locking requested but no sg_persist found"
>> +            fi
>> +            if ! command -v gethostip > /dev/null 2>&1; then
>> +                fatal "Locking requested but no gethostip found for key generation"
>> +            fi
> 
> Why don't you just add this to check_tools? In any case, if you want to fold 
> check_tools functionality into parse_target I think it should be done in a 
> separate patch in order for it to be easier to review.
> 
> IMHO, I prefer to have both functions separated, because it's quite clear 
> what parse_target and check_tools do. 

My thoughts are that it makes more sense to check that the tool required
is there depending on the options that are provided. It saves multiple
cases that would end up checking if an option is set, then check if the
tool is there.

Leaving the existing structure would mean that you parse out the target
options in parse_target, but then also check which options are set to
then check if the required tools are available for the specific options.

It seems more logical and efficient to me to merge this together and
essentially do the pre-flight checks as we go.

It may be an idea to then rename parse_target to something else as a
function name - maybe prepare (as that function doesn't exist anymore)
to better reflect what it does?

>>              ;;
>>          esac
>>      done
>> @@ -96,38 +100,29 @@
>>      fi
>>  }
>>  
>> -# Attaches the target $iqn in $portal and sets $dev to point to the
>> -# multipath device
>> -attach()
>> -{
>> -    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --login > /dev/null
>> -    find_device
>> -}
>>  
>> -# Discovers targets in $portal and checks that $iqn is one of those targets
>> -# Also sets the auth parameters to attach the device
>> -prepare()
>> +lock_device()
>>  {
>> -    # Check if target is already opened
>> -    iscsiadm -m session 2>&1 | grep -q "$iqn" && fatal "Device already opened"
>> -    # Discover portal targets
>> -    iscsiadm -m discovery -t st -p $portal 2>&1 | grep -q "$iqn" || \
>> -        fatal "No matching target iqn found"
>> -}
>> -
>> -# Attaches the device and writes xenstore backend entries to connect
>> -# the device
>> -add()
>> -{
>> -    attach
>> -    write_dev $dev
>> +    ## Lock the iSCSI target as Exclusive Access.
>> +    key=$(gethostip -x $(uname -n))
> 
> Isn't there anything else that can be used as a key? What would happen if 
> the host IP changes while the VM is running? Couldn't the iqn (or a hash 
> of it) be used as the key?

I thought long and hard about this - as I would like a better method.
The key is used to secure the persistent reservation. If another system
uses the same key, then they can remove the reservation. My testing
seems to indicate that if you provide the same key while asking for a
lock, you get it - even if a previous lock was granted to another system.

The idea here is that each Dom0 would have a different key - therefore
the lock request from a different Dom0 would fail.

>> +    if ! sg_persist -d ${dev} -o -G -S ${key} > /dev/null; then
>> +        unlock_device
>> +        iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
>> +        fatal "iSCSI LOCK: Failed to register with target"
>> +    fi
>> +    if ! sg_persist -d ${dev} -o -R -K ${key} -T 6 > /dev/null; then
>> +        unlock_device
>> +        iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
>> +        fatal "iSCSI LOCK: Failed to set persistent reservation"
>> +    fi
>>  }
>>  
>> -# Disconnects the device
>> -remove()
>> +unlock_device()
>>  {
>> -    find_device
>> -    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
>> +    ## Unlock the iSCSI target.
>> +    key=$(gethostip -x $(uname -n))
>> +    sg_persist -d ${dev} -o -L -K ${key} -T 6 > /dev/null || true
>> +    sg_persist -d ${dev} -o -G -K ${key} -S 0 > /dev/null || true
> 
> I'm not sure whether the return code of those functions shouldn't be 
> checked. I know this is the teardown path, so there's not much that can 
> be done here on failure, but it seems like at least the script should check 
> for the return code '3', and then retry the command. According to 
> sg3_utils(8), a '3' means:
> 
> "the DEVICE reports that it is not ready for the operation requested. The 
> device may be in the process of becoming ready (e.g. spinning up but not at 
> speed) so the utility may work after a wait."

Possibly - however I came across a problem here... pygrub will add &
remove while it gets the grub config file, then add again while firing
up the actual VM.

This causes a lock - unlock - lock - boot - unlock type workflow.

You're right that it may be worthwhile to retry some of these - but I
don't quite have a method in mind to do this that I'd be happy with.

>>  }
>>
>>  command=$1
>> @@ -138,15 +133,28 @@
>>
>>  parse_target "$target"
>>
>> -check_tools || exit 1
>> -
>>  case $command in
>>  add)
>> -    prepare
>> -    add
>> +    # Check if target is already opened
>> +    iscsiadm -m session 2>&1 | grep -q "$iqn" && fatal "Device already opened"
>> +    # Discover portal targets
>> +    iscsiadm -m discovery -t st -p $portal 2>&1 | grep -q "$iqn" || \
>> +        fatal "No matching target iqn found"
>> +
>> +    ## Login to the iSCSI target.
>> +    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --login > /dev/null
>> +    find_device
>> +    if [ "$locktarget" = "y" ]; then
>> +        lock_device
>> +    fi
>> +    write_dev $dev
>>      ;;
>>  remove)
>> -    remove
>> +    find_device
>> +    if [ "$locktarget" = "y" ]; then
>> +        unlock_device
>> +    fi
>> +    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
> 
> You are doing quite of a rework of the script here (by removing/merging a 
> bunch of functions). I think this should be sent as a separate patch, in 
> order to ease the review (mixing new features with code cleanup makes it 
> quite hard to review).

Yeah I know - and I'm kinda new at this (being my first patch sent
here). I also don't have a git clone of the xen repos, or anything else
to base this one right now so I end up doing this manually.

I'll see if I can break this up a bit more - but my time is somewhat
limited atm when I have access to these machines to tinker.

-- 
Steven Haigh

Email: netwiz@crc.id.au
Web: https://www.crc.id.au
Phone: (03) 9001 6090 - 0412 935 897


[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

[-- Attachment #2: Type: text/plain, Size: 126 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH] v3 - Add exclusive locking option to block-iscsi
  2016-05-05  5:52 ` [PATCH] v2 " Steven Haigh
  2016-05-06  9:09   ` Roger Pau Monné
@ 2016-05-09  4:22   ` Steven Haigh
  2016-05-12 11:02     ` Wei Liu
  2016-05-19  1:29     ` Resend: " Steven Haigh
  1 sibling, 2 replies; 10+ messages in thread
From: Steven Haigh @ 2016-05-09  4:22 UTC (permalink / raw)
  To: xen-devel; +Cc: Roger Pau Monné

[-- Attachment #1: Type: text/plain, Size: 1927 bytes --]

On 2016-05-05 15:52, Steven Haigh wrote:
> On 2016-05-05 12:32, Steven Haigh wrote:
>> Overview
>> 
>> If you're using iSCSI, you can mount a target by multiple Dom0
>> machines on the same target. For non-cluster aware filesystems, this
>> can lead to disk corruption and general bad times by all. The iSCSI
>> protocol allows the use of persistent reservations as per the SCSI
>> disk spec. Low level SCSI commands for locking are handled by the
>> sg_persist program (bundled with sg3_utils package in EL).
>> 
>> The aim of this patch is to create a 'locktarget=y' option specified
>> within the disk 'target' command for iSCSI to lock the target in
>> exclusive mode on VM start with a key generated from the local systems
>> IP, and release this lock on the shutdown of the DomU.
>> 
>> Example Config:
>> disk            =
>> ['script=block-iscsi,vdev=xvda,target=iqn=iqn.1986-03.com.sun:02:mytarget,portal=iscsi.example.com,locktarget=y']
>> 
>> In writing this, I have also re-factored parts of the script to put
>> some things in what I believe to be a better place to make expansion
>> easier. This is mainly in removing functions that purely call other
>> functions with no actual code execution.
>> 
>> Signed-off-by: Steven Haigh <netwiz@crc.id.au>
>> 
>> (on a side note, first time I've submitted a patch to the list and I'm
>> currently stuck on a webmail client, so apologies in advance if this
>> all goes wrong ;)
> 
> Changes in v2:
> Bugfix: Call find_device to locate the /dev/sdX component of the iSCSI
> target before trying to run unlock_device().
> 
> Apologies for this oversight.
> 

Changes in v3:
* Split the block-iscsi cleanup into a seperate patch 
(block-iscsi-locking-v3_01_simplify_block-iscsi.patch).
* Add locking in second patch file 
(block-iscsi-locking-v3_02_add_locking.patch)

-- 
Steven Haigh

Email: netwiz@crc.id.au
Web: https://www.crc.id.au
Phone: (03) 9001 6090 - 0412 935 897

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: block-iscsi-locking-v3_01_simplify_block-iscsi.patch --]
[-- Type: text/x-diff; name=block-iscsi-locking-v3_01_simplify_block-iscsi.patch, Size: 2910 bytes --]

--- block-iscsi.orig    2016-05-09 15:12:02.489495212 +1000
+++ block-iscsi 2016-05-09 15:16:35.447480532 +1000
@@ -31,16 +31,6 @@
     echo $1 | sed "s/^\("$2"\)//"
 }
 
-check_tools()
-{
-    if ! command -v iscsiadm > /dev/null 2>&1; then
-        fatal "Unable to find iscsiadm tool"
-    fi
-    if [ "$multipath" = "y" ] && ! command -v multipath > /dev/null 2>&1; then
-        fatal "Unable to find multipath"
-    fi
-}
-
 # Sets the following global variables based on the params field passed in as
 # a parameter: iqn, portal, auth_method, user, multipath, password
 parse_target()
@@ -52,12 +42,18 @@
         case $param in
         iqn=*)
             iqn=$(remove_label $param "iqn=")
+            if ! command -v iscsiadm > /dev/null 2>&1; then
+                fatal "Could not find iscsiadm tool."
+            fi
             ;;
         portal=*)
             portal=$(remove_label $param "portal=")
             ;;
         multipath=*)
             multipath=$(remove_label $param "multipath=")
+            if ! command -v multipath > /dev/null 2>&1; then
+                fatal "Multipath selected, but no multipath tools found"
+            fi
             ;;
         esac
     done
@@ -96,40 +92,6 @@
     fi
 }

-# Attaches the target $iqn in $portal and sets $dev to point to the
-# multipath device
-attach()
-{
-    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --login > /dev/null
-    find_device
-}
-
-# Discovers targets in $portal and checks that $iqn is one of those targets
-# Also sets the auth parameters to attach the device
-prepare()
-{
-    # Check if target is already opened
-    iscsiadm -m session 2>&1 | grep -q "$iqn" && fatal "Device already opened"
-    # Discover portal targets
-    iscsiadm -m discovery -t st -p $portal 2>&1 | grep -q "$iqn" || \
-        fatal "No matching target iqn found"
-}
-
-# Attaches the device and writes xenstore backend entries to connect
-# the device
-add()
-{
-    attach
-    write_dev $dev
-}
-
-# Disconnects the device
-remove()
-{
-    find_device
-    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
-}
-
 command=$1
 target=$(xenstore-read $XENBUS_PATH/params || true)
 if [ -z "$target" ]; then
@@ -138,15 +100,21 @@

 parse_target "$target"

-check_tools || exit 1
-
 case $command in
 add)
-    prepare
-    add
+    # Check if target is already opened
+    iscsiadm -m session 2>&1 | grep -q "$iqn" && fatal "Device already opened"
+    # Discover portal targets
+    iscsiadm -m discovery -t st -p $portal 2>&1 | grep -q "$iqn" || \
+        fatal "No matching target iqn found"
+
+    ## Login to the iSCSI target.
+    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --login > /dev/null
+
+    write_dev $dev
     ;;
 remove)
-    remove
+    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
     ;;
 *)
     exit 1 

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: block-iscsi-locking-v3_02_add_locking.patch --]
[-- Type: text/x-diff; name=block-iscsi-locking-v3_02_add_locking.patch, Size: 2382 bytes --]

--- block-iscsi 2016-05-09 15:16:35.447480532 +1000
+++ block-iscsi-lock    2016-05-05 15:43:58.222159351 +1000
@@ -37,8 +37,7 @@
 {
     # set multipath default value
     multipath="n"
-    for param in $(echo "$1" | tr "," "\n")
-    do
+    for param in $(echo "$1" | tr "," "\n"); do
         case $param in
         iqn=*)
             iqn=$(remove_label $param "iqn=")
@@ -55,6 +54,15 @@
                 fatal "Multipath selected, but no multipath tools found"
             fi
             ;;
+        locktarget=*)
+            locktarget=$(remove_label $param "locktarget=")
+            if ! command -v sg_persist > /dev/null 2>&1; then
+                fatal "Locking requested but no sg_persist found"
+            fi
+            if ! command -v gethostip > /dev/null 2>&1; then
+                fatal "Locking requested but no gethostip found for key generation"
+            fi
+            ;;
         esac
     done
     if [ -z "$iqn" ] || [ -z "$portal" ]; then
@@ -92,6 +100,31 @@
     fi
 }

+
+lock_device()
+{
+    ## Lock the iSCSI target as Exclusive Access.
+    key=$(gethostip -x $(uname -n))
+    if ! sg_persist -d ${dev} -o -G -S ${key} > /dev/null; then
+        unlock_device
+        iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
+        fatal "iSCSI LOCK: Failed to register with target"
+    fi
+    if ! sg_persist -d ${dev} -o -R -K ${key} -T 6 > /dev/null; then
+        unlock_device
+        iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
+        fatal "iSCSI LOCK: Failed to set persistent reservation"
+    fi
+}
+
+unlock_device()
+{
+    ## Unlock the iSCSI target.
+    key=$(gethostip -x $(uname -n))
+    sg_persist -d ${dev} -o -L -K ${key} -T 6 > /dev/null || true
+    sg_persist -d ${dev} -o -G -K ${key} -S 0 > /dev/null || true
+}
+
 command=$1
 target=$(xenstore-read $XENBUS_PATH/params || true)
 if [ -z "$target" ]; then
@@ -110,10 +143,17 @@

     ## Login to the iSCSI target.
     do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --login > /dev/null
-
+    find_device
+    if [ "$locktarget" = "y" ]; then
+        lock_device
+    fi
     write_dev $dev
     ;;
 remove)
+    find_device
+    if [ "$locktarget" = "y" ]; then
+        unlock_device
+    fi
     do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
     ;;
 *) 

[-- Attachment #4: Type: text/plain, Size: 126 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] v3 - Add exclusive locking option to block-iscsi
  2016-05-09  4:22   ` [PATCH] v3 " Steven Haigh
@ 2016-05-12 11:02     ` Wei Liu
  2016-05-16  0:42       ` Steven Haigh
  2016-05-19  1:29     ` Resend: " Steven Haigh
  1 sibling, 1 reply; 10+ messages in thread
From: Wei Liu @ 2016-05-12 11:02 UTC (permalink / raw)
  To: Steven Haigh; +Cc: Roger Pau Monné, Wei Liu, xen-devel

Hi Steven

On Mon, May 09, 2016 at 02:22:48PM +1000, Steven Haigh wrote:
> On 2016-05-05 15:52, Steven Haigh wrote:
> >On 2016-05-05 12:32, Steven Haigh wrote:
> >>Overview
> >>
> >>If you're using iSCSI, you can mount a target by multiple Dom0
> >>machines on the same target. For non-cluster aware filesystems, this
> >>can lead to disk corruption and general bad times by all. The iSCSI
> >>protocol allows the use of persistent reservations as per the SCSI
> >>disk spec. Low level SCSI commands for locking are handled by the
> >>sg_persist program (bundled with sg3_utils package in EL).
> >>
> >>The aim of this patch is to create a 'locktarget=y' option specified
> >>within the disk 'target' command for iSCSI to lock the target in
> >>exclusive mode on VM start with a key generated from the local systems
> >>IP, and release this lock on the shutdown of the DomU.
> >>
> >>Example Config:
> >>disk            =
> >>['script=block-iscsi,vdev=xvda,target=iqn=iqn.1986-03.com.sun:02:mytarget,portal=iscsi.example.com,locktarget=y']

You seem to suggest an extension (locktarget) to disk spec as well but
you patch doesn't contain modification to
docs/txt/misc/xl-disk-configuration.txt.

Wei.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] v3 - Add exclusive locking option to block-iscsi
  2016-05-12 11:02     ` Wei Liu
@ 2016-05-16  0:42       ` Steven Haigh
  0 siblings, 0 replies; 10+ messages in thread
From: Steven Haigh @ 2016-05-16  0:42 UTC (permalink / raw)
  To: Wei Liu; +Cc: Roger Pau Monné, xen-devel

On 2016-05-12 21:02, Wei Liu wrote:
> Hi Steven
> 
> On Mon, May 09, 2016 at 02:22:48PM +1000, Steven Haigh wrote:
>> On 2016-05-05 15:52, Steven Haigh wrote:
>> >On 2016-05-05 12:32, Steven Haigh wrote:
>> >>Overview
>> >>
>> >>If you're using iSCSI, you can mount a target by multiple Dom0
>> >>machines on the same target. For non-cluster aware filesystems, this
>> >>can lead to disk corruption and general bad times by all. The iSCSI
>> >>protocol allows the use of persistent reservations as per the SCSI
>> >>disk spec. Low level SCSI commands for locking are handled by the
>> >>sg_persist program (bundled with sg3_utils package in EL).
>> >>
>> >>The aim of this patch is to create a 'locktarget=y' option specified
>> >>within the disk 'target' command for iSCSI to lock the target in
>> >>exclusive mode on VM start with a key generated from the local systems
>> >>IP, and release this lock on the shutdown of the DomU.
>> >>
>> >>Example Config:
>> >>disk            =
>> >>['script=block-iscsi,vdev=xvda,target=iqn=iqn.1986-03.com.sun:02:mytarget,portal=iscsi.example.com,locktarget=y']
> 
> You seem to suggest an extension (locktarget) to disk spec as well but
> you patch doesn't contain modification to
> docs/txt/misc/xl-disk-configuration.txt.

Correct. There is no documentation for the existing block-iscsi script 
within xl-disk-configuration.txt.

In fact, there is no mention at all regarding block-iscsi in any of the 
documentation that I can see.

-- 
Steven Haigh

Email: netwiz@crc.id.au
Web: https://www.crc.id.au
Phone: (03) 9001 6090 - 0412 935 897

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Resend: [PATCH] v3 - Add exclusive locking option to block-iscsi
  2016-05-09  4:22   ` [PATCH] v3 " Steven Haigh
  2016-05-12 11:02     ` Wei Liu
@ 2016-05-19  1:29     ` Steven Haigh
  2016-05-19 12:10       ` Wei Liu
  2016-05-19 14:23       ` Roger Pau Monné
  1 sibling, 2 replies; 10+ messages in thread
From: Steven Haigh @ 2016-05-19  1:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Roger Pau Monné

[-- Attachment #1: Type: text/plain, Size: 2410 bytes --]

On 2016-05-09 14:22, Steven Haigh wrote:
> On 2016-05-05 15:52, Steven Haigh wrote:
>> On 2016-05-05 12:32, Steven Haigh wrote:
>>> Overview
>>> 
>>> If you're using iSCSI, you can mount a target by multiple Dom0
>>> machines on the same target. For non-cluster aware filesystems, this
>>> can lead to disk corruption and general bad times by all. The iSCSI
>>> protocol allows the use of persistent reservations as per the SCSI
>>> disk spec. Low level SCSI commands for locking are handled by the
>>> sg_persist program (bundled with sg3_utils package in EL).
>>> 
>>> The aim of this patch is to create a 'locktarget=y' option specified
>>> within the disk 'target' command for iSCSI to lock the target in
>>> exclusive mode on VM start with a key generated from the local 
>>> systems
>>> IP, and release this lock on the shutdown of the DomU.
>>> 
>>> Example Config:
>>> disk            =
>>> ['script=block-iscsi,vdev=xvda,target=iqn=iqn.1986-03.com.sun:02:mytarget,portal=iscsi.example.com,locktarget=y']
>>> 
>>> In writing this, I have also re-factored parts of the script to put
>>> some things in what I believe to be a better place to make expansion
>>> easier. This is mainly in removing functions that purely call other
>>> functions with no actual code execution.
>>> 
>>> Signed-off-by: Steven Haigh <netwiz@crc.id.au>
>>> 
>>> (on a side note, first time I've submitted a patch to the list and 
>>> I'm
>>> currently stuck on a webmail client, so apologies in advance if this
>>> all goes wrong ;)
>> 
>> Changes in v2:
>> Bugfix: Call find_device to locate the /dev/sdX component of the iSCSI
>> target before trying to run unlock_device().
>> 
>> Apologies for this oversight.
>> 
> 
> Changes in v3:
> * Split the block-iscsi cleanup into a seperate patch
> (block-iscsi-locking-v3_01_simplify_block-iscsi.patch).
> * Add locking in second patch file 
> (block-iscsi-locking-v3_02_add_locking.patch)

Resend of patches.

There was a mention of having to add further documentation to 
xl-disk-configuration.txt - however there are no mentions of block-iscsi 
script within the documentation to add. As such, it probably would be 
out of place to add things here.

The locktarget option is presented directly to the block-iscsi script 
and not evaluated anywhere outside this script.

-- 
Steven Haigh

Email: netwiz@crc.id.au
Web: https://www.crc.id.au
Phone: (03) 9001 6090 - 0412 935 897

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: block-iscsi-locking-v3_01_simplify_block-iscsi.patch --]
[-- Type: text/x-diff; name=block-iscsi-locking-v3_01_simplify_block-iscsi.patch, Size: 2910 bytes --]

--- block-iscsi.orig    2016-05-09 15:12:02.489495212 +1000
+++ block-iscsi 2016-05-09 15:16:35.447480532 +1000
@@ -31,16 +31,6 @@
     echo $1 | sed "s/^\("$2"\)//"
 }
 
-check_tools()
-{
-    if ! command -v iscsiadm > /dev/null 2>&1; then
-        fatal "Unable to find iscsiadm tool"
-    fi
-    if [ "$multipath" = "y" ] && ! command -v multipath > /dev/null 2>&1; then
-        fatal "Unable to find multipath"
-    fi
-}
-
 # Sets the following global variables based on the params field passed in as
 # a parameter: iqn, portal, auth_method, user, multipath, password
 parse_target()
@@ -52,12 +42,18 @@
         case $param in
         iqn=*)
             iqn=$(remove_label $param "iqn=")
+            if ! command -v iscsiadm > /dev/null 2>&1; then
+                fatal "Could not find iscsiadm tool."
+            fi
             ;;
         portal=*)
             portal=$(remove_label $param "portal=")
             ;;
         multipath=*)
             multipath=$(remove_label $param "multipath=")
+            if ! command -v multipath > /dev/null 2>&1; then
+                fatal "Multipath selected, but no multipath tools found"
+            fi
             ;;
         esac
     done
@@ -96,40 +92,6 @@
     fi
 }

-# Attaches the target $iqn in $portal and sets $dev to point to the
-# multipath device
-attach()
-{
-    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --login > /dev/null
-    find_device
-}
-
-# Discovers targets in $portal and checks that $iqn is one of those targets
-# Also sets the auth parameters to attach the device
-prepare()
-{
-    # Check if target is already opened
-    iscsiadm -m session 2>&1 | grep -q "$iqn" && fatal "Device already opened"
-    # Discover portal targets
-    iscsiadm -m discovery -t st -p $portal 2>&1 | grep -q "$iqn" || \
-        fatal "No matching target iqn found"
-}
-
-# Attaches the device and writes xenstore backend entries to connect
-# the device
-add()
-{
-    attach
-    write_dev $dev
-}
-
-# Disconnects the device
-remove()
-{
-    find_device
-    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
-}
-
 command=$1
 target=$(xenstore-read $XENBUS_PATH/params || true)
 if [ -z "$target" ]; then
@@ -138,15 +100,21 @@

 parse_target "$target"

-check_tools || exit 1
-
 case $command in
 add)
-    prepare
-    add
+    # Check if target is already opened
+    iscsiadm -m session 2>&1 | grep -q "$iqn" && fatal "Device already opened"
+    # Discover portal targets
+    iscsiadm -m discovery -t st -p $portal 2>&1 | grep -q "$iqn" || \
+        fatal "No matching target iqn found"
+
+    ## Login to the iSCSI target.
+    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --login > /dev/null
+
+    write_dev $dev
     ;;
 remove)
-    remove
+    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
     ;;
 *)
     exit 1 

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: block-iscsi-locking-v3_02_add_locking.patch --]
[-- Type: text/x-diff; name=block-iscsi-locking-v3_02_add_locking.patch, Size: 2382 bytes --]

--- block-iscsi.orig 2016-05-09 15:16:35.447480532 +1000
+++ block-iscsi    2016-05-05 15:43:58.222159351 +1000
@@ -37,8 +37,7 @@
 {
     # set multipath default value
     multipath="n"
-    for param in $(echo "$1" | tr "," "\n")
-    do
+    for param in $(echo "$1" | tr "," "\n"); do
         case $param in
         iqn=*)
             iqn=$(remove_label $param "iqn=")
@@ -55,6 +54,15 @@
                 fatal "Multipath selected, but no multipath tools found"
             fi
             ;;
+        locktarget=*)
+            locktarget=$(remove_label $param "locktarget=")
+            if ! command -v sg_persist > /dev/null 2>&1; then
+                fatal "Locking requested but no sg_persist found"
+            fi
+            if ! command -v gethostip > /dev/null 2>&1; then
+                fatal "Locking requested but no gethostip found for key generation"
+            fi
+            ;;
         esac
     done
     if [ -z "$iqn" ] || [ -z "$portal" ]; then
@@ -92,6 +100,31 @@
     fi
 }

+
+lock_device()
+{
+    ## Lock the iSCSI target as Exclusive Access.
+    key=$(gethostip -x $(uname -n))
+    if ! sg_persist -d ${dev} -o -G -S ${key} > /dev/null; then
+        unlock_device
+        iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
+        fatal "iSCSI LOCK: Failed to register with target"
+    fi
+    if ! sg_persist -d ${dev} -o -R -K ${key} -T 6 > /dev/null; then
+        unlock_device
+        iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
+        fatal "iSCSI LOCK: Failed to set persistent reservation"
+    fi
+}
+
+unlock_device()
+{
+    ## Unlock the iSCSI target.
+    key=$(gethostip -x $(uname -n))
+    sg_persist -d ${dev} -o -L -K ${key} -T 6 > /dev/null || true
+    sg_persist -d ${dev} -o -G -K ${key} -S 0 > /dev/null || true
+}
+
 command=$1
 target=$(xenstore-read $XENBUS_PATH/params || true)
 if [ -z "$target" ]; then
@@ -110,10 +143,17 @@

     ## Login to the iSCSI target.
     do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --login > /dev/null
-
+    find_device
+    if [ "$locktarget" = "y" ]; then
+        lock_device
+    fi
     write_dev $dev
     ;;
 remove)
+    find_device
+    if [ "$locktarget" = "y" ]; then
+        unlock_device
+    fi
     do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
     ;;
 *) 

[-- Attachment #4: Type: text/plain, Size: 126 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Resend: [PATCH] v3 - Add exclusive locking option to block-iscsi
  2016-05-19  1:29     ` Resend: " Steven Haigh
@ 2016-05-19 12:10       ` Wei Liu
  2016-05-19 14:23       ` Roger Pau Monné
  1 sibling, 0 replies; 10+ messages in thread
From: Wei Liu @ 2016-05-19 12:10 UTC (permalink / raw)
  To: Steven Haigh; +Cc: Ian Jackson, Roger Pau Monné, Wei Liu, xen-devel

On Thu, May 19, 2016 at 11:29:32AM +1000, Steven Haigh wrote:
> On 2016-05-09 14:22, Steven Haigh wrote:
> >On 2016-05-05 15:52, Steven Haigh wrote:
> >>On 2016-05-05 12:32, Steven Haigh wrote:
> >>>Overview
> >>>
> >>>If you're using iSCSI, you can mount a target by multiple Dom0
> >>>machines on the same target. For non-cluster aware filesystems, this
> >>>can lead to disk corruption and general bad times by all. The iSCSI
> >>>protocol allows the use of persistent reservations as per the SCSI
> >>>disk spec. Low level SCSI commands for locking are handled by the
> >>>sg_persist program (bundled with sg3_utils package in EL).
> >>>
> >>>The aim of this patch is to create a 'locktarget=y' option specified
> >>>within the disk 'target' command for iSCSI to lock the target in
> >>>exclusive mode on VM start with a key generated from the local systems
> >>>IP, and release this lock on the shutdown of the DomU.
> >>>
> >>>Example Config:
> >>>disk            =
> >>>['script=block-iscsi,vdev=xvda,target=iqn=iqn.1986-03.com.sun:02:mytarget,portal=iscsi.example.com,locktarget=y']
> >>>
> >>>In writing this, I have also re-factored parts of the script to put
> >>>some things in what I believe to be a better place to make expansion
> >>>easier. This is mainly in removing functions that purely call other
> >>>functions with no actual code execution.
> >>>
> >>>Signed-off-by: Steven Haigh <netwiz@crc.id.au>
> >>>
> >>>(on a side note, first time I've submitted a patch to the list and I'm
> >>>currently stuck on a webmail client, so apologies in advance if this
> >>>all goes wrong ;)
> >>
> >>Changes in v2:
> >>Bugfix: Call find_device to locate the /dev/sdX component of the iSCSI
> >>target before trying to run unlock_device().
> >>
> >>Apologies for this oversight.
> >>
> >
> >Changes in v3:
> >* Split the block-iscsi cleanup into a seperate patch
> >(block-iscsi-locking-v3_01_simplify_block-iscsi.patch).
> >* Add locking in second patch file
> >(block-iscsi-locking-v3_02_add_locking.patch)
> 
> Resend of patches.
> 
> There was a mention of having to add further documentation to
> xl-disk-configuration.txt - however there are no mentions of block-iscsi
> script within the documentation to add. As such, it probably would be out of
> place to add things here.
> 
> The locktarget option is presented directly to the block-iscsi script and
> not evaluated anywhere outside this script.
> 

Sorry I dropped the ball. I think it would be helpful if you or Roger
can send a patch to document all the knobs for block-iscsi. It doesn't
have to be in that file, we can figure out where to add.

FYI we are in the process of making 4.7 release, so the response here
might take a bit longer. FAOD this patch is not targeting 4.7, right?

I'm not too familiar with block script so I think I will
defer this to Roger.  I've also CC'ed Ian for you.

To make a proper patch, please could you read:

http://wiki.xenproject.org/wiki/Submitting_Xen_Project_Patches

Wei.


> -- 
> Steven Haigh
> 
> Email: netwiz@crc.id.au
> Web: https://www.crc.id.au
> Phone: (03) 9001 6090 - 0412 935 897

> --- block-iscsi.orig    2016-05-09 15:12:02.489495212 +1000
> +++ block-iscsi 2016-05-09 15:16:35.447480532 +1000
> @@ -31,16 +31,6 @@
>      echo $1 | sed "s/^\("$2"\)//"
>  }
>  
> -check_tools()
> -{
> -    if ! command -v iscsiadm > /dev/null 2>&1; then
> -        fatal "Unable to find iscsiadm tool"
> -    fi
> -    if [ "$multipath" = "y" ] && ! command -v multipath > /dev/null 2>&1; then
> -        fatal "Unable to find multipath"
> -    fi
> -}
> -
>  # Sets the following global variables based on the params field passed in as
>  # a parameter: iqn, portal, auth_method, user, multipath, password
>  parse_target()
> @@ -52,12 +42,18 @@
>          case $param in
>          iqn=*)
>              iqn=$(remove_label $param "iqn=")
> +            if ! command -v iscsiadm > /dev/null 2>&1; then
> +                fatal "Could not find iscsiadm tool."
> +            fi
>              ;;
>          portal=*)
>              portal=$(remove_label $param "portal=")
>              ;;
>          multipath=*)
>              multipath=$(remove_label $param "multipath=")
> +            if ! command -v multipath > /dev/null 2>&1; then
> +                fatal "Multipath selected, but no multipath tools found"
> +            fi
>              ;;
>          esac
>      done
> @@ -96,40 +92,6 @@
>      fi
>  }
> 
> -# Attaches the target $iqn in $portal and sets $dev to point to the
> -# multipath device
> -attach()
> -{
> -    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --login > /dev/null
> -    find_device
> -}
> -
> -# Discovers targets in $portal and checks that $iqn is one of those targets
> -# Also sets the auth parameters to attach the device
> -prepare()
> -{
> -    # Check if target is already opened
> -    iscsiadm -m session 2>&1 | grep -q "$iqn" && fatal "Device already opened"
> -    # Discover portal targets
> -    iscsiadm -m discovery -t st -p $portal 2>&1 | grep -q "$iqn" || \
> -        fatal "No matching target iqn found"
> -}
> -
> -# Attaches the device and writes xenstore backend entries to connect
> -# the device
> -add()
> -{
> -    attach
> -    write_dev $dev
> -}
> -
> -# Disconnects the device
> -remove()
> -{
> -    find_device
> -    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
> -}
> -
>  command=$1
>  target=$(xenstore-read $XENBUS_PATH/params || true)
>  if [ -z "$target" ]; then
> @@ -138,15 +100,21 @@
> 
>  parse_target "$target"
> 
> -check_tools || exit 1
> -
>  case $command in
>  add)
> -    prepare
> -    add
> +    # Check if target is already opened
> +    iscsiadm -m session 2>&1 | grep -q "$iqn" && fatal "Device already opened"
> +    # Discover portal targets
> +    iscsiadm -m discovery -t st -p $portal 2>&1 | grep -q "$iqn" || \
> +        fatal "No matching target iqn found"
> +
> +    ## Login to the iSCSI target.
> +    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --login > /dev/null
> +
> +    write_dev $dev
>      ;;
>  remove)
> -    remove
> +    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
>      ;;
>  *)
>      exit 1 

> --- block-iscsi.orig 2016-05-09 15:16:35.447480532 +1000
> +++ block-iscsi    2016-05-05 15:43:58.222159351 +1000
> @@ -37,8 +37,7 @@
>  {
>      # set multipath default value
>      multipath="n"
> -    for param in $(echo "$1" | tr "," "\n")
> -    do
> +    for param in $(echo "$1" | tr "," "\n"); do
>          case $param in
>          iqn=*)
>              iqn=$(remove_label $param "iqn=")
> @@ -55,6 +54,15 @@
>                  fatal "Multipath selected, but no multipath tools found"
>              fi
>              ;;
> +        locktarget=*)
> +            locktarget=$(remove_label $param "locktarget=")
> +            if ! command -v sg_persist > /dev/null 2>&1; then
> +                fatal "Locking requested but no sg_persist found"
> +            fi
> +            if ! command -v gethostip > /dev/null 2>&1; then
> +                fatal "Locking requested but no gethostip found for key generation"
> +            fi
> +            ;;
>          esac
>      done
>      if [ -z "$iqn" ] || [ -z "$portal" ]; then
> @@ -92,6 +100,31 @@
>      fi
>  }
> 
> +
> +lock_device()
> +{
> +    ## Lock the iSCSI target as Exclusive Access.
> +    key=$(gethostip -x $(uname -n))
> +    if ! sg_persist -d ${dev} -o -G -S ${key} > /dev/null; then
> +        unlock_device
> +        iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
> +        fatal "iSCSI LOCK: Failed to register with target"
> +    fi
> +    if ! sg_persist -d ${dev} -o -R -K ${key} -T 6 > /dev/null; then
> +        unlock_device
> +        iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
> +        fatal "iSCSI LOCK: Failed to set persistent reservation"
> +    fi
> +}
> +
> +unlock_device()
> +{
> +    ## Unlock the iSCSI target.
> +    key=$(gethostip -x $(uname -n))
> +    sg_persist -d ${dev} -o -L -K ${key} -T 6 > /dev/null || true
> +    sg_persist -d ${dev} -o -G -K ${key} -S 0 > /dev/null || true
> +}
> +
>  command=$1
>  target=$(xenstore-read $XENBUS_PATH/params || true)
>  if [ -z "$target" ]; then
> @@ -110,10 +143,17 @@
> 
>      ## Login to the iSCSI target.
>      do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --login > /dev/null
> -
> +    find_device
> +    if [ "$locktarget" = "y" ]; then
> +        lock_device
> +    fi
>      write_dev $dev
>      ;;
>  remove)
> +    find_device
> +    if [ "$locktarget" = "y" ]; then
> +        unlock_device
> +    fi
>      do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
>      ;;
>  *) 

> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Resend: [PATCH] v3 - Add exclusive locking option to block-iscsi
  2016-05-19  1:29     ` Resend: " Steven Haigh
  2016-05-19 12:10       ` Wei Liu
@ 2016-05-19 14:23       ` Roger Pau Monné
  1 sibling, 0 replies; 10+ messages in thread
From: Roger Pau Monné @ 2016-05-19 14:23 UTC (permalink / raw)
  To: Steven Haigh; +Cc: wei.liu2, xen-devel

On Thu, May 19, 2016 at 11:29:32AM +1000, Steven Haigh wrote:
> On 2016-05-09 14:22, Steven Haigh wrote:
> > On 2016-05-05 15:52, Steven Haigh wrote:
> > > On 2016-05-05 12:32, Steven Haigh wrote:
> > > > Overview
> > > > 
> > > > If you're using iSCSI, you can mount a target by multiple Dom0
> > > > machines on the same target. For non-cluster aware filesystems, this
> > > > can lead to disk corruption and general bad times by all. The iSCSI
> > > > protocol allows the use of persistent reservations as per the SCSI
> > > > disk spec. Low level SCSI commands for locking are handled by the
> > > > sg_persist program (bundled with sg3_utils package in EL).
> > > > 
> > > > The aim of this patch is to create a 'locktarget=y' option specified
> > > > within the disk 'target' command for iSCSI to lock the target in
> > > > exclusive mode on VM start with a key generated from the local
> > > > systems
> > > > IP, and release this lock on the shutdown of the DomU.
> > > > 
> > > > Example Config:
> > > > disk            =
> > > > ['script=block-iscsi,vdev=xvda,target=iqn=iqn.1986-03.com.sun:02:mytarget,portal=iscsi.example.com,locktarget=y']
> > > > 
> > > > In writing this, I have also re-factored parts of the script to put
> > > > some things in what I believe to be a better place to make expansion
> > > > easier. This is mainly in removing functions that purely call other
> > > > functions with no actual code execution.
> > > > 
> > > > Signed-off-by: Steven Haigh <netwiz@crc.id.au>
> > > > 
> > > > (on a side note, first time I've submitted a patch to the list
> > > > and I'm
> > > > currently stuck on a webmail client, so apologies in advance if this
> > > > all goes wrong ;)
> > > 
> > > Changes in v2:
> > > Bugfix: Call find_device to locate the /dev/sdX component of the iSCSI
> > > target before trying to run unlock_device().
> > > 
> > > Apologies for this oversight.
> > > 
> > 
> > Changes in v3:
> > * Split the block-iscsi cleanup into a seperate patch
> > (block-iscsi-locking-v3_01_simplify_block-iscsi.patch).
> > * Add locking in second patch file
> > (block-iscsi-locking-v3_02_add_locking.patch)
> 
> Resend of patches.

IMHO, if those patches are going to be committed to Xen they need to be 
sent using git, they are (at least) missing a proper changelog.

> There was a mention of having to add further documentation to
> xl-disk-configuration.txt - however there are no mentions of block-iscsi
> script within the documentation to add. As such, it probably would be out of
> place to add things here.

Hm, I don't think we have ever added specific block-scripts configuration 
options to xl-disk-configuration.txt. What I did was to instead add this 
information at the top of the script file itself, and the locktarget option 
should be documented there together with the other options. Sadly I see that 
the 'multipath' option did not add the documentation.

> The locktarget option is presented directly to the block-iscsi script and
> not evaluated anywhere outside this script.
> 
> -- 
> Steven Haigh
> 
> Email: netwiz@crc.id.au
> Web: https://www.crc.id.au
> Phone: (03) 9001 6090 - 0412 935 897

> --- block-iscsi.orig    2016-05-09 15:12:02.489495212 +1000
> +++ block-iscsi 2016-05-09 15:16:35.447480532 +1000
> @@ -31,16 +31,6 @@
>      echo $1 | sed "s/^\("$2"\)//"
>  }
>  
> -check_tools()
> -{
> -    if ! command -v iscsiadm > /dev/null 2>&1; then
> -        fatal "Unable to find iscsiadm tool"
> -    fi
> -    if [ "$multipath" = "y" ] && ! command -v multipath > /dev/null 2>&1; then
> -        fatal "Unable to find multipath"
> -    fi
> -}
> -
>  # Sets the following global variables based on the params field passed in as
>  # a parameter: iqn, portal, auth_method, user, multipath, password
>  parse_target()
> @@ -52,12 +42,18 @@
>          case $param in
>          iqn=*)
>              iqn=$(remove_label $param "iqn=")
> +            if ! command -v iscsiadm > /dev/null 2>&1; then
> +                fatal "Could not find iscsiadm tool."
> +            fi
>              ;;
>          portal=*)
>              portal=$(remove_label $param "portal=")
>              ;;
>          multipath=*)
>              multipath=$(remove_label $param "multipath=")

This is wrong, multipath can have the values 'y' or 'n' only, and there's a 
check below that makes sure of that. Here you would be checking if 
'multipath' is available even if multipath=n has been set.

IMHO, I think that having a separation between the option parser and the 
tools availability check makes sense, and avoids mistakes like this.

> +            if ! command -v multipath > /dev/null 2>&1; then
> +                fatal "Multipath selected, but no multipath tools found"
> +            fi
>              ;;
>          esac
>      done
> @@ -96,40 +92,6 @@
>      fi
>  }
> 
> -# Attaches the target $iqn in $portal and sets $dev to point to the
> -# multipath device
> -attach()
> -{
> -    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --login > /dev/null
> -    find_device
> -}
> -
> -# Discovers targets in $portal and checks that $iqn is one of those targets
> -# Also sets the auth parameters to attach the device
> -prepare()
> -{
> -    # Check if target is already opened
> -    iscsiadm -m session 2>&1 | grep -q "$iqn" && fatal "Device already opened"
> -    # Discover portal targets
> -    iscsiadm -m discovery -t st -p $portal 2>&1 | grep -q "$iqn" || \
> -        fatal "No matching target iqn found"
> -}
> -
> -# Attaches the device and writes xenstore backend entries to connect
> -# the device
> -add()
> -{
> -    attach
> -    write_dev $dev
> -}
> -
> -# Disconnects the device
> -remove()
> -{
> -    find_device
> -    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
> -}
> -
>  command=$1
>  target=$(xenstore-read $XENBUS_PATH/params || true)
>  if [ -z "$target" ]; then
> @@ -138,15 +100,21 @@
> 
>  parse_target "$target"
> 
> -check_tools || exit 1
> -
>  case $command in
>  add)
> -    prepare
> -    add
> +    # Check if target is already opened
> +    iscsiadm -m session 2>&1 | grep -q "$iqn" && fatal "Device already opened"
> +    # Discover portal targets
> +    iscsiadm -m discovery -t st -p $portal 2>&1 | grep -q "$iqn" || \
> +        fatal "No matching target iqn found"
> +
> +    ## Login to the iSCSI target.

Why the double #?

> +    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --login > /dev/null
> +
> +    write_dev $dev
>      ;;
>  remove)
> -    remove
> +    do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
>      ;;
>  *)
>      exit 1 

IMHO, I prefer the script as it is now, probably because I've written it 
myself. I think the functions are clearly documented, and I'm still not sure 
why the locktarget option cannot be added without the refactoring.

> --- block-iscsi.orig 2016-05-09 15:16:35.447480532 +1000
> +++ block-iscsi    2016-05-05 15:43:58.222159351 +1000
> @@ -37,8 +37,7 @@
>  {
>      # set multipath default value
>      multipath="n"
> -    for param in $(echo "$1" | tr "," "\n")
> -    do
> +    for param in $(echo "$1" | tr "," "\n"); do

Spurious change? There doesn't seem to be any need for it.

>          case $param in
>          iqn=*)
>              iqn=$(remove_label $param "iqn=")
> @@ -55,6 +54,15 @@
>                  fatal "Multipath selected, but no multipath tools found"
>              fi
>              ;;
> +        locktarget=*)
> +            locktarget=$(remove_label $param "locktarget=")

Since this is a boolean option, you would have to check that locktarget is 
either 'y' or 'n' only, and bail out on other values. For example see how 
the multipath option does it a couple of lines below.

> +            if ! command -v sg_persist > /dev/null 2>&1; then
> +                fatal "Locking requested but no sg_persist found"
> +            fi
> +            if ! command -v gethostip > /dev/null 2>&1; then
> +                fatal "Locking requested but no gethostip found for key generation"
> +            fi
> +            ;;
>          esac
>      done
>      if [ -z "$iqn" ] || [ -z "$portal" ]; then
> @@ -92,6 +100,31 @@
>      fi
>  }
> 
> +
> +lock_device()

This needs a comment describing what the function is expected to do.

> +{
> +    ## Lock the iSCSI target as Exclusive Access.
> +    key=$(gethostip -x $(uname -n))

I still don't like using the hostip as a key, isn't there anything else more 
suitable? Can't you use something like a host UUID?

> +    if ! sg_persist -d ${dev} -o -G -S ${key} > /dev/null; then
> +        unlock_device
> +        iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
> +        fatal "iSCSI LOCK: Failed to register with target"
> +    fi
> +    if ! sg_persist -d ${dev} -o -R -K ${key} -T 6 > /dev/null; then
> +        unlock_device
> +        iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
> +        fatal "iSCSI LOCK: Failed to set persistent reservation"
> +    fi
> +}
> +
> +unlock_device()

Same here, a small comment would make sense IMHO.

> +{
> +    ## Unlock the iSCSI target.
> +    key=$(gethostip -x $(uname -n))
> +    sg_persist -d ${dev} -o -L -K ${key} -T 6 > /dev/null || true
> +    sg_persist -d ${dev} -o -G -K ${key} -S 0 > /dev/null || true
> +}
> +
>  command=$1
>  target=$(xenstore-read $XENBUS_PATH/params || true)
>  if [ -z "$target" ]; then
> @@ -110,10 +143,17 @@
> 
>      ## Login to the iSCSI target.
>      do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --login > /dev/null
> -
> +    find_device
> +    if [ "$locktarget" = "y" ]; then
> +        lock_device
> +    fi
>      write_dev $dev
>      ;;
>  remove)
> +    find_device
> +    if [ "$locktarget" = "y" ]; then
> +        unlock_device
> +    fi
>      do_or_die iscsiadm -m node --targetname "$iqn" -p "$portal" --logout > /dev/null
>      ;;
>  *) 


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2016-05-19 14:23 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-05  2:32 [PATCH] v1 - Add exclusive locking option to block-iscsi Steven Haigh
2016-05-05  5:52 ` [PATCH] v2 " Steven Haigh
2016-05-06  9:09   ` Roger Pau Monné
2016-05-06  9:44     ` Steven Haigh
2016-05-09  4:22   ` [PATCH] v3 " Steven Haigh
2016-05-12 11:02     ` Wei Liu
2016-05-16  0:42       ` Steven Haigh
2016-05-19  1:29     ` Resend: " Steven Haigh
2016-05-19 12:10       ` Wei Liu
2016-05-19 14:23       ` Roger Pau Monné

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.