mirror of https://github.com/sipwise/heartbeat.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
343 lines
6.4 KiB
343 lines
6.4 KiB
#!/bin/sh
|
|
#
|
|
#
|
|
# LVM
|
|
#
|
|
# Description: Manages an LVM volume as an HA resource
|
|
#
|
|
#
|
|
# Author: Alan Robertson
|
|
# Support: linux-ha@lists.linux-ha.org
|
|
# License: GNU General Public License (GPL)
|
|
# Copyright: (C) 2002 - 2005 International Business Machines, Inc.
|
|
#
|
|
# This code significantly inspired by the LVM resource
|
|
# in FailSafe by Lars Marowsky-Bree
|
|
#
|
|
#
|
|
# An example usage in /etc/ha.d/haresources:
|
|
# node1 10.0.0.170 ServeRAID::1::1 LVM::myvolname
|
|
#
|
|
# See usage() function below for more details...
|
|
#
|
|
# OCF parameters are as below:
|
|
# OCF_RESKEY_volgrpname
|
|
#
|
|
#######################################################################
|
|
# Initialization:
|
|
|
|
. ${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs
|
|
|
|
#######################################################################
|
|
|
|
|
|
usage() {
|
|
methods=`LVM_methods`
|
|
methods=`echo $methods | tr ' ' '|'`
|
|
cat <<-!
|
|
usage: $0 $methods
|
|
|
|
$0 manages an Linux Volume Manager volume (LVM) as an HA resource
|
|
|
|
The 'start' operation brings the given volume online
|
|
The 'stop' operation takes the given volume offline
|
|
The 'status' operation reports whether the volume is available
|
|
The 'monitor' operation reports whether the volume seems present
|
|
The 'validate-all' operation checks whether the OCF parameters are valid
|
|
The 'methods' operation reports on the methods $0 supports
|
|
|
|
!
|
|
exit $OCF_ERR_GENERIC
|
|
|
|
}
|
|
|
|
meta_data() {
|
|
cat <<END
|
|
<?xml version="1.0"?>
|
|
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
|
|
<resource-agent name="LVM">
|
|
<version>1.0</version>
|
|
|
|
<longdesc lang="en">
|
|
Resource script for LVM. It manages an Linux Volume Manager volume (LVM)
|
|
as an HA resource.
|
|
</longdesc>
|
|
<shortdesc lang="en">LVM resource agent</shortdesc>
|
|
|
|
<parameters>
|
|
<parameter name="volgrpname" unique="0" required="1">
|
|
<longdesc lang="en">
|
|
The name of volume group.
|
|
</longdesc>
|
|
<shortdesc lang="en">Volume group name</shortdesc>
|
|
<content type="string" default="" />
|
|
</parameter>
|
|
</parameters>
|
|
|
|
<actions>
|
|
<action name="start" timeout="30" />
|
|
<action name="stop" timeout="30" />
|
|
<action name="status" timeout="30" />
|
|
<action name="monitor" depth="0" timeout="30" interval="10" start-delay="10" />
|
|
<action name="methods" timeout="5" />
|
|
<action name="meta-data" timeout="5" />
|
|
<action name="validate-all" timeout="5" />
|
|
</actions>
|
|
</resource-agent>
|
|
END
|
|
}
|
|
|
|
#
|
|
# methods: What methods/operations do we support?
|
|
#
|
|
LVM_methods() {
|
|
cat <<-!
|
|
start
|
|
stop
|
|
status
|
|
monitor
|
|
methods
|
|
validate-all
|
|
usage
|
|
!
|
|
}
|
|
|
|
#
|
|
# Return LVM status (silently)
|
|
#
|
|
LVM_status() {
|
|
|
|
if
|
|
[ "$LVM_MAJOR" -eq "1" ]
|
|
then
|
|
vgdisplay $1 | grep -i 'Status.*available' >/dev/null
|
|
return $?
|
|
else
|
|
vgdisplay -v $1 | grep -i 'Status[ \t]*available' >/dev/null
|
|
return $?
|
|
fi
|
|
|
|
}
|
|
|
|
#
|
|
# Report on LVM volume status to stdout...
|
|
#
|
|
LVM_report_status() {
|
|
|
|
if
|
|
[ "$LVM_MAJOR" -eq "1" ]
|
|
then
|
|
VGOUT=`vgdisplay $1 2>&1`
|
|
echo "$VGOUT" | grep -i 'Status.*available' >/dev/null
|
|
rc=$?
|
|
else
|
|
VGOUT=`vgdisplay -v $1 2>&1`
|
|
echo "$VGOUT" | grep -i 'Status[ \t]*available' >/dev/null
|
|
rc=$?
|
|
fi
|
|
|
|
if
|
|
[ $rc -eq 0 ]
|
|
then
|
|
: Volume $1 is available
|
|
else
|
|
ocf_log debug "LVM Volume $1 is not available (stopped)"
|
|
return $OCF_NOT_RUNNING
|
|
fi
|
|
|
|
if
|
|
echo "$VGOUT" | grep -i 'Access.*read/write' >/dev/null
|
|
then
|
|
ocf_log debug "Volume $1 is available read/write (running)"
|
|
else
|
|
ocf_log debug "Volume $1 is available read-only (running)"
|
|
fi
|
|
|
|
return $OCF_SUCCESS
|
|
}
|
|
|
|
#
|
|
# Monitor the volume - does it really seem to be working?
|
|
#
|
|
#
|
|
LVM_monitor() {
|
|
|
|
if
|
|
LVM_status $1
|
|
then
|
|
: OK
|
|
else
|
|
ocf_log info "LVM Volume $1 is offline"
|
|
return $OCF_NOT_RUNNING
|
|
fi
|
|
|
|
ocf_run vgck $1
|
|
|
|
return $?
|
|
}
|
|
|
|
#
|
|
# Enable LVM volume
|
|
#
|
|
LVM_start() {
|
|
|
|
# TODO: This MUST run vgimport as well
|
|
|
|
ocf_log info "Activating volume group $1"
|
|
|
|
if
|
|
[ "$LVM_MAJOR" -eq "1" ]
|
|
then
|
|
ocf_run vgscan $1
|
|
else
|
|
ocf_run vgscan
|
|
fi
|
|
|
|
# TODO: For v2, this MUST use --refresh
|
|
ocf_run vgchange -a y $1 || return $OCF_ERR_GENERIC
|
|
|
|
if
|
|
LVM_status $1
|
|
then
|
|
: OK Volume $1 activated just fine!
|
|
return $OCF_SUCCESS
|
|
else
|
|
ocf_log err "LVM: $1 did not activate correctly"
|
|
return $OCF_ERR_GENERIC
|
|
fi
|
|
}
|
|
|
|
#
|
|
# Disable the LVM volume
|
|
#
|
|
LVM_stop() {
|
|
|
|
ocf_log info "Deactivating volume group $1"
|
|
ocf_run vgchange -a n $1 || return 1
|
|
|
|
if
|
|
LVM_status $1
|
|
then
|
|
ocf_log err "LVM: $1 did not stop correctly"
|
|
return $OCF_ERR_GENERIC
|
|
fi
|
|
|
|
# TODO: This MUST run vgexport as well
|
|
|
|
return $OCF_SUCCESS
|
|
}
|
|
|
|
#
|
|
# Check whether the OCF instance parameters are valid
|
|
#
|
|
LVM_validate_all() {
|
|
check_binary $AWK
|
|
|
|
# Off-the-shelf tests...
|
|
vgck "$VOLUME" >/dev/nulll 2>&1
|
|
|
|
if [ $? -ne 0 ]; then
|
|
ocf_log err "Volume group [$VOLUME] does not exist or contains error!"
|
|
exit $OCF_ERR_GENERIC
|
|
fi
|
|
|
|
# Double-check
|
|
if
|
|
[ "$LVM_MAJOR" -eq "1" ]
|
|
then
|
|
vgdisplay "$VOLUME" >/dev/null 2>&1
|
|
else
|
|
vgdisplay -v "$VOLUME" >/dev/null 2>&1
|
|
fi
|
|
|
|
if [ $? -ne 0 ]; then
|
|
ocf_log err "Volume group [$VOLUME] does not exist or contains error!"
|
|
exit $OCF_ERR_GENERIC
|
|
fi
|
|
|
|
return $OCF_SUCCESS
|
|
}
|
|
#
|
|
# 'main' starts here...
|
|
#
|
|
|
|
if
|
|
( [ $# -ne 1 ] )
|
|
then
|
|
usage
|
|
exit $OCF_ERR_ARGS
|
|
fi
|
|
|
|
case $1 in
|
|
meta-data) meta_data
|
|
exit $OCF_SUCCESS;;
|
|
|
|
methods) LVM_methods
|
|
exit $?;;
|
|
|
|
usage) usage
|
|
exit $OCF_SUCCESS;;
|
|
*) ;;
|
|
esac
|
|
|
|
if
|
|
[ -z "$OCF_RESKEY_volgrpname" ]
|
|
then
|
|
# echo "You must identify the volume group name!"
|
|
ocf_log err "You must identify the volume group name!"
|
|
# usage
|
|
exit $OCF_ERR_ARGS
|
|
fi
|
|
|
|
# Get the LVM version number, for this to work we assume(thanks to panjiam):
|
|
#
|
|
# LVM1 outputs like this
|
|
#
|
|
# # vgchange --version
|
|
# vgchange: Logical Volume Manager 1.0.3
|
|
# Heinz Mauelshagen, Sistina Software 19/02/2002 (IOP 10)
|
|
#
|
|
# LVM2 and higher versions output in this format
|
|
#
|
|
# # vgchange --version
|
|
# LVM version: 2.00.15 (2004-04-19)
|
|
# Library version: 1.00.09-ioctl (2004-03-31)
|
|
# Driver version: 4.1.0
|
|
|
|
LVM_VERSION=`vgchange --version 2>&1 | \
|
|
$AWK '/Logical Volume Manager/ {print $5"\n"; exit; }
|
|
/LVM version:/ {printf $3"\n"; exit;}'`
|
|
rc=$?
|
|
|
|
if
|
|
( [ $rc -ne 0 ] || [ -z "$LVM_VERSION" ] )
|
|
then
|
|
ocf_log err "LVM: $1 could not determine LVM version. Try 'vgchange --version' manually and modify $0 ?"
|
|
exit $OCF_ERR_GENERIC
|
|
fi
|
|
LVM_MAJOR="${LVM_VERSION%%.*}"
|
|
|
|
VOLUME=$OCF_RESKEY_volgrpname
|
|
|
|
# What kind of method was invoked?
|
|
case "$1" in
|
|
|
|
start) LVM_start $VOLUME
|
|
exit $?;;
|
|
|
|
stop) LVM_stop $VOLUME
|
|
exit $?;;
|
|
|
|
status) LVM_report_status $VOLUME
|
|
exit $?;;
|
|
|
|
monitor) LVM_monitor $VOLUME
|
|
exit $?;;
|
|
|
|
validate-all) LVM_validate_all
|
|
;;
|
|
|
|
*) usage
|
|
exit $OCF_ERR_AEGS;;
|
|
esac
|