[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Cluster-devel] scsi_reserve fix for multipath devices



Here is a patch for the scsi_reserve init scrip what should fix
problems when using dm-multipath devices.

When creating a list of devices to use, we check to see if any of
those devices are dm-multipath devices. If so, the script will get the
underlying paths for the multipath devices. A second list is
maintained (sg_devices) contains a list of devices that must be
registered. The original list (pv_devices) is still used for creating
reservations. The idea is that we want to create a registrations for
every path (IT nexus) and a reservation for every LUN.

Ryan

diff --git a/fence/agents/scsi/scsi_reserve b/fence/agents/scsi/scsi_reserve
index 34f25e5..3662b02 100755
--- a/fence/agents/scsi/scsi_reserve
+++ b/fence/agents/scsi/scsi_reserve
@@ -22,7 +22,7 @@ if ! fence_scsi_test -t fence ; then
     exit 1
 fi
 
-# check for nodeids in config file
+# check for nodeid in config file
 #
 if ! fence_scsi_test -t nodes ; then
     logger -t scsi_reserve \
@@ -48,16 +48,49 @@ fi
 
 # get physical volumes (devices) that are part of cluster volumes
 #
-scsi_devices=$( vgs --config 'global { locking_type = 0 }' \
-                    --noheadings -o vg_attr,pv_name 2> /dev/null \
-              | awk ' $1 ~ /.*c$/ { print $2 } ' )
+pv_devices=$( vgs --noheadings --options vg_attr,pv_name \
+                  --config 'devices { preferred_names = [ "^/dev/dm" ] }
+                            global { locking_type = 0 }' 2> /dev/null \
+            | awk ' $1 ~ /.*c$/ { print $2 } ' )
 
-if [ -z "$scsi_devices" ] ; then
+if [ -z "$pv_devices" ] ; then
     logger -t scsi_reserve \
 	"[error] did not find devices in cluster volumes"
     exit 1
 fi
 
+for pv_dev in $pv_devices
+do
+    if [[ $pv_dev =~ "/dev/dm-[0-9]*" ]];
+    then
+	# get major and minor numbers for device-mapper device
+	#
+	major=$( cat /sys/block/${pv_dev:5}/dev | awk -F':' '{ print $1 }' )
+	minor=$( cat /sys/block/${pv_dev:5}/dev | awk -F':' '{ print $2 }' )
+
+	# get uuid for device-mapper device
+	#
+	dm_uuid=$( dmsetup info -c --noheadings -o uuid -j $major -m $minor )
+
+	# check if device-mapper device is multipath
+	#
+	if [[ $dm_uuid =~ "^mpath-*" ]]; then
+	    dm_devices="$dm_devices $( ls /sys/block/${pv_dev:5}/slaves/ )"
+	else
+	    logger -t scsi_reserve \
+	    "[error] $dev is not a multipath device"
+	exit 1
+	fi
+    else
+	sg_devices="$sg_devices $pv_dev"
+    fi
+done
+
+for dm_dev in $dm_devices
+do
+    sg_devices="$sg_devices /dev/$dm_dev"
+done
+
 # get the cluster id from cman
 #
 cluster_id=$( cman_tool status | grep -i "Cluster ID" \
@@ -101,44 +134,42 @@ case $1 in
 
 	echo -n "Starting scsi_reserve:"
 
-	for dev in $scsi_devices
+	for dev in $sg_devices
 	do
-	  # check if our key is already resgistered with this device
-	  #
-	  if sg_persist -n -d $dev -i -k | grep -qiE "^[[:space:]]*0x$key" ; then
-	      logger -t scsi_reserve \
-		"[info] already registered with $dev (key=0x$key)"
-	      continue
-	  fi
-
-	  # create the scsi registration
-	  #
-	  if ! sg_persist -n -d $dev -o -I -S $key &> /dev/null ; then
-	      logger -t scsi_reserve \
-		"[error] unable to register device $dev (key=0x$key)"
-	      : $[ count = $count + 1 ]
-	      error=1
-	  else
-	      logger -t scsi_reserve \
-		"[info] registered with device $dev (key=0x$key)"
-	  fi
-
-	  # check to see if reservation already exists
-	  #
-	  if sg_persist -n -d $dev -i -r | grep -qiE "^[[:space:]]*Key=0x" ; then
-	      logger -t scsi_reserve \
-		"[info] reservation already exists on $dev"
-	      continue
-	  fi
-
-	  # create the scsi reservation
-	  #
-	  if ! sg_persist -n -d $dev -o -R -K $key -T 5 &> /dev/null ; then
-	      logger -t scsi_reserver \
-		"[error] unable to create reservation on $dev (key=0x$key)"
-	      : $[ count = $count + 1 ]
-	      error=1
-	  fi
+	    # create the scsi registration
+	    #
+	    if ! sg_persist -n -d $dev -o -I -S $key &> /dev/null ; then
+		logger -t scsi_reserve \
+		    "[error] unable to register device $dev (key=0x$key)"
+		: $[ count = $count + 1 ]
+		error=1
+	    else
+		logger -t scsi_reserve \
+		    "[info] registered with device $dev (key=0x$key)"
+	    fi
+	done
+
+	for dev in $pv_devices
+	do
+	    # check to see if reservation already exists
+	    #
+	    if sg_persist -n -d $dev -i -r | grep -qiE "^[[:space:]]*Key=0x" ; then
+		logger -t scsi_reserve \
+		    "[info] reservation already exists on $dev"
+		continue
+	    fi
+
+	    # create the scsi reservation
+	    #
+	    if ! sg_persist -n -d $dev -o -R -K $key -T 5 &> /dev/null ; then
+		logger -t scsi_reserve \
+		    "[error] unable to create reservation on $dev (key=0x$key)"
+		: $[ count = $count + 1 ]
+		error=1
+	    else
+		logger -t scsi_reserve \
+		    "[info] reservation created on $dev (key=0x$key)"
+	    fi
 	done
 
 	# leave fence domain if any errors occured during registration
@@ -150,7 +181,7 @@ case $1 in
 		"[info] $count errors during registration"
 	    logger -t scsi_reserve \
 		"[info] leaving the fence domain"
-	    fence_tool leave
+	    # fence_tool leave
 	    failure
 	fi
 
@@ -165,44 +196,31 @@ case $1 in
 
 	echo -n "Stopping scsi_reserve:"
 
-	for dev in $scsi_devices
+	for dev in $sg_devices
 	do
-	  # get list of keys registered with this device
-	  #
-	  key_list=$( sg_persist -n -d $dev -i -k | grep -iE "^[[:space:]]*0x" )
-
-	  # check that our key is registered with this device
-	  #
-	  if ! sg_persist -d $dev -i -k | grep -qiE "^[[:space:]]*0x$key" ; then
-	      logger -t scsi_reserve \
-		"[info] not registered with $dev (key=0x$key)"
-	      continue
-	  fi
-
-	  # check if our key is the reservation holder
-	  #
-	  if sg_persist -n -d $dev -i -r 2>/dev/null | grep -qiE "$key" ; then
-	      if echo "$key_list" | grep -qivE "$key" ; then
-		  logger -t scsi_reserve \
-		      "[error] unable to remove registration on $dev (key=0x$key)"
-		  : $[ count = $count + 1 ]
-		  error=1
-		  continue
-	      fi
-	  fi
-
-	  # remove registration for this device
-	  #
-	  if ! sg_persist -n -d $dev -o -G -K $key -S 0 &> /dev/null ; then
-	      logger -t scsi_reserve \
-		"[error] failed to remove registration on $dev (key=0x$key)"
-	      : $[ count = $count + 1 ]
-	      error=1
-	  else
-	      logger -t scsi_reserve \
-		"[info] removed registration on $dev (key=0x$key)"
-	  fi
-
+	    # check if our key is the reservation holder
+	    #
+	    if sg_persist -n -d $dev -i -r 2>/dev/null | grep -qiE "$key" ; then
+		logger -t scsi_reserve \
+		    "[info] unable to remove registration on $dev (key=0x$key)"
+		continue
+	    else
+		# check if our key is registered with the device
+		#
+		if ! sg_persist -n -d $dev -i -k 2>/dev/null | grep -qiE "$key" ; then
+		    continue
+		else
+		    if ! sg_persist -n -d $dev -o -G -K $key -S 0 &> /dev/null ; then
+			logger -t scsi_reserve \
+			    "[error] failed to remove registration on $dev (key=0x$key)"
+			: $[ count = $count + 1 ]
+			error=1
+		    else
+			logger -t scsi_reserve \
+			    "[info] removed registration on $dev (key=0x$key)"
+		    fi
+		fi
+	    fi
 	done
 
 	# report success or failure
@@ -222,39 +240,46 @@ case $1 in
     restart)
 
 	error=0
+	count=0
 
 	echo -n "Retarting scsi_reserve:"
 
-	for dev in $scsi_devices
+	for dev in $sg_devices
 	do
-	  # recreate the scsi registration
-	  #
-	  if ! sg_persist -n -d $dev -o -I -S $key &> /dev/null ; then
-	      logger -t scsi_reserve \
-		"[error] unable to register device $dev (key=0x$key)"
-	      : $[ count = $count + 1 ]
-	      error=1
-	  else
-	      logger -t scsi_reserve \
-		"[info] registered with device $dev (key=0x$key)"
-	  fi
-
-	  # check to see if reservation already exists
-	  #
-	  if sg_persist -n -d $dev -i -r | grep -qiE "^[[:space:]]*Key=0x" ; then
-	      logger -t scsi_reserve \
-		"[info] reservation already exists on $dev"
-	      continue
-	  fi
-
-	  # recreate the scsi reservation
-	  #
-	  if ! sg_persist -n -d $dev -o -R -K $key -T 5 &> /dev/null ; then
-	      logger -t scsi_reserver \
-		"[error] unable to create reservation on $dev (key=0x$key)"
-	      : $[ count = $count + 1 ]
-	      error=1
-	  fi
+	    # create the scsi registration
+	    #
+	    if ! sg_persist -n -d $dev -o -I -S $key &> /dev/null ; then
+		logger -t scsi_reserve \
+		    "[error] unable to register device $dev (key=0x$key)"
+		: $[ count = $count + 1 ]
+		error=1
+	    else
+		logger -t scsi_reserve \
+		    "[info] registered with device $dev (key=0x$key)"
+	    fi
+	done
+
+	for dev in $pv_devices
+	do
+	    # check to see if reservation already exists
+	    #
+	    if sg_persist -n -d $dev -i -r | grep -qiE "^[[:space:]]*Key=0x" ; then
+		logger -t scsi_reserve \
+		    "[info] reservation already exists on $dev"
+		continue
+	    fi
+
+	    # create the scsi reservation
+	    #
+	    if ! sg_persist -n -d $dev -o -R -K $key -T 5 &> /dev/null ; then
+		logger -t scsi_reserve \
+		    "[error] unable to create reservation on $dev (key=0x$key)"
+		: $[ count = $count + 1 ]
+		error=1
+	    else
+		logger -t scsi_reserve \
+		    "[info] reservation created on $dev (key=0x$key)"
+	    fi
 	done
 
 	# leave fence domain if any errors occured during registration
@@ -266,7 +291,7 @@ case $1 in
 		"[info] $count errors during registration"
 	    logger -t scsi_reserve \
 		"[info] leaving the fence domain"
-	    fence_tool leave
+	    # fence_tool leave
 	    failure
 	fi
 
@@ -277,12 +302,13 @@ case $1 in
     status)
 
 	error=0
+	count=0
 
-	for dev in $scsi_devices
+	for dev in $pv_devices
 	do
-	  if sg_persist -n -d $dev -i -k | grep -qiE "$key" ; then
-	      devices[${#devices[ ]}]=$dev
-	  fi
+	    if sg_persist -n -d $dev -i -k | grep -qiE "$key" ; then
+		devices[${#devices[ ]}]=$dev
+	    fi
 	done
 
 	if [ -z "$devices" ] ; then

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]