#!/bin/bash # # scsi_reserve: # # chkconfig: - 25 75 # description: start/stop persistent reservation service for lvm # config: /etc/sysconfig/scsi_reserve . /etc/init.d/functions case $1 in start) echo -n "Starting scsi_reserve:" ;; stop) echo -n "Stopping scsi_reserve:" ;; restart) echo -n "Restarting scsi_reserve:" ;; status) ;; *) echo $"Usage: $0 {start|stop|restart|status}" exit 1 ;; esac # read in config file if it exists # if [ -f /etc/sysconfig/scsi_reserve ] ; then . /etc/sysconfig/scsi_reserve fi # check for sg_persist command provided by sg3_utils package # if ! sg_persist -V &> /dev/null ; then logger -t scsi_reserve \ "[error] unable to exec sg_persist" failure echo exit 1 fi # check if cluster is configured for fence_scsi # if ! fence_scsi_test -t fence ; then logger -t scsi_reserve \ "[error] cluster not configured for scsi reservations" failure echo exit 1 fi # check for nodeid in config file # if ! fence_scsi_test -t nodes ; then logger -t scsi_reserve \ "[error] cluster must define nodeid for all nodes" failure echo exit 1 fi # check that cman is running # if ! cman_tool status &> /dev/null ; then logger -t scsi_reserve \ "[error] cman does not appear to be running" failure echo exit 1 fi # get physical volumes (devices) that are part of cluster volumes # 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 "$pv_devices" ] ; then logger -t scsi_reserve \ "[error] did not find devices in cluster volumes" failure echo 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/ )" elif [[ $dm_uuid =~ "^part[0-9]*-mpath" ]]; then dm_slave=$( ls /sys/block/${pv_dev:5}/slaves/ ) dm_devices="$dm_devices $( ls /sys/block/${dm_slave}/slaves/ )" else logger -t scsi_reserve \ "[error] $pv_dev is not a multipath device" failure echo 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" \ | awk -F": " '{ print $2 }' ) if [ -z "$cluster_id" ] ; then logger -s -t scsi_reserve \ "[error] unable to determine cluster id" failure echo exit 1 fi # get the node id from cman # node_id=$( cman_tool status | grep -i "Node ID" \ | awk -F": " '{ print $2 }' ) if [ -z "$node_id" ] ; then logger -t scsi_reserve \ "[error] unable to determine node id" failure echo exit 1 fi # generate unique key using cluster_id and node_id # key=$( printf "%x%.4x" $cluster_id $node_id ) if [ -z "$key" ] ; then logger -t scsi_reserve \ "[error] unable to generate key" failure echo exit 1 fi ################################################################################ case $1 in start) error=0 count=0 # echo -n "Starting scsi_reserve:" for dev in $sg_devices do # 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 # if [ $error -eq 0 ] ; then success else logger -t scsi_reserve \ "[info] $count errors during registration" logger -t scsi_reserve \ "[info] leaving the fence domain" fence_tool leave failure fi echo ;; # end of start stop) error=0 count=0 # echo -n "Stopping scsi_reserve:" for dev in $sg_devices do # 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 # if [ $error -eq 0 ] ; then success else logger -t scsi_reserve \ "[info] $count errors occured during unregistration" failure fi echo ;; # end of stop restart) error=0 count=0 # echo -n "Restarting scsi_reserve:" for dev in $sg_devices do # 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 # if [ $error -eq 0 ] ; then success else logger -t scsi_reserve \ "[info] $count errors during registration" logger -t scsi_reserve \ "[info] leaving the fence domain" # fence_tool leave failure fi echo ;; # end of restart status) error=0 count=0 for dev in $pv_devices do if sg_persist -n -d $dev -i -k | grep -qiE "$key" ; then devices[${#devices[@]}]=$dev fi done if [ -z "$devices" ] ; then echo "No registered devices found." else echo "Found ${#devices[@]} registered device(s):" for i in "${devices[@]}" do echo $i done fi ;; # end of status esac exit $error