Page MenuHomeClusterLabs Projects

No OneTemporary

diff --git a/heartbeat/IPaddr.in b/heartbeat/IPaddr.in
index 6c4ca0453..839314fce 100644
--- a/heartbeat/IPaddr.in
+++ b/heartbeat/IPaddr.in
@@ -1,875 +1,879 @@
#!/bin/sh
#
# License: GNU General Public License (GPL)
# Support: linux-ha@lists.linux-ha.org
#
# This script manages IP alias IP addresses
#
# It can add an IP alias, or remove one.
#
# usage: $0 {start|stop|status|monitor|meta-data}
#
# The "start" arg adds an IP alias.
#
# Surprisingly, the "stop" arg removes one. :-)
#
# OCF parameters are as below
# OCF_RESKEY_ip
# OCF_RESKEY_broadcast
# OCF_RESKEY_nic
# OCF_RESKEY_netmask
# OCF_RESKEY_lvs_support ( e.g. true, on, 1 )
# OCF_RESKEY_ARP_INTERVAL_MS
# OCF_RESKEY_ARP_REPEAT
# OCF_RESKEY_ARP_BACKGROUND (e.g. yes )
# OCF_RESKEY_ARP_NETMASK
# OCF_RESKEY_local_start_script
# OCF_RESKEY_local_stop_script
#
#######################################################################
# Initialization:
. @hb_libdir@/ocf-shellfuncs
VARLIB=@localstatedir@/lib/@HB_PKG@
IFCONFIG=@IFCONFIG@
IFCONFIG_A_OPT=@IFCONFIG_A_OPT@
SENDARP=$HA_BIN/send_arp
FINDIF=$HA_BIN/findif
VLDIR=$VARLIB/rsctmp/IPaddr
SENDARPPIDDIR=$VARLIB/rsctmp/send_arp
ROUTE=@ROUTE@
USAGE="usage: $0 {start|stop|status|monitor|meta-data}";
#######################################################################
export LC_ALL=C
prefix=@prefix@
exec_prefix=@exec_prefix@
HA_D=@sysconfdir@/ha.d
. ${HA_D}/shellfuncs
SYSTYPE="`uname -s`"
case "$SYSTYPE" in
SunOS)
# `uname -r` = 5.9 -> SYSVERSION = 9
SYSVERSION="`uname -r | cut -d. -f 2`"
;;
Darwin)
# Treat Darwin the same as the other BSD variants (matched as *BSD)
SYSTYPE="${SYSTYPE}BSD"
;;
*)
;;
esac
meta_data() {
cat <<END
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="IPaddr" version="0.1">
<version>1.0</version>
<parameters>
<parameter name="ip" unique="1">
<longdesc lang="en">
The IPv4 address to be configured in dotted quad notation, for example
"192.168.1.1".
</longdesc>
<shortdesc lang="en">IPv4 address</shortdesc>
<content type="string" default="" />
</parameter>
<parameter name="nic" unique="0">
<longdesc lang="en">
The base network interface on which the IP address will be brought
online.
If left empty, the script will try and determine this from the
routing table.
Do NOT specify an alias interface in the form eth0:1 or anything here;
rather, specify the base interface only.
</longdesc>
<shortdesc lang="en">Network interface</shortdesc>
<content type="string" default="eth0"/>
</parameter>
<parameter name="netmask">
<longdesc lang="en">
The netmask for the interface in CIDR format.
If unspecified, the script will also try to determine this from the
routing table.
</longdesc>
<shortdesc lang="en">CIDR netmask</shortdesc>
<content type="string" default=""/>
</parameter>
<parameter name="broadcast">
<longdesc lang="en">
Broadcast address associated with the IP. If left empty, the script will
determine this from the netmask.
</longdesc>
<shortdesc lang="en">Broadcast address</shortdesc>
<content type="string" default=""/>
</parameter>
<parameter name="iflabel">
<longdesc lang="en">
You can specify an additional label for your IP address here.
</longdesc>
<shortdesc lang="en">Interface label</shortdesc>
<content type="string" default=""/>
</parameter>
<parameter name="lvs_support">
<longdesc lang="en">
Enable support for LVS. Allows stopped IPs to exist on the loopback device or something like that"
</longdesc>
<shortdesc lang="en">Enable support for LVS</shortdesc>
<content type="boolean" default="false"/>
</parameter>
<parameter name="local_stop_script">
<longdesc lang="en">
Script called when the IP is released
</longdesc>
<shortdesc lang="en">Script called when the IP is released</shortdesc>
<content type="string" default=""/>
</parameter>
<parameter name="local_start_script">
<longdesc lang="en">
Script called when the IP is added
</longdesc>
<shortdesc lang="en">Script called when the IP is added</shortdesc>
<content type="string" default=""/>
</parameter>
<parameter name="ARP_INTERVAL_MS">
<longdesc lang="en">
milliseconds between ARPs
</longdesc>
<shortdesc lang="en">milliseconds between ARPs</shortdesc>
<content type="integer" default="500"/>
</parameter>
<parameter name="ARP_REPEAT">
<longdesc lang="en">
repeat count
</longdesc>
<shortdesc lang="en">repeat count</shortdesc>
<content type="integer" default="10"/>
</parameter>
<parameter name="ARP_BACKGROUND">
<longdesc lang="en">
run in background (no longer any reason to do this)
</longdesc>
<shortdesc lang="en">run in background</shortdesc>
<content type="boolean" default="yes"/>
</parameter>
<parameter name="ARP_NETMASK">
<longdesc lang="en">
netmask for ARP
</longdesc>
<shortdesc lang="en">netmask for ARP</shortdesc>
<content type="string" default="ffffffffffff"/>
</parameter>
<parameter name="remove_conflicting_loopback">
<longdesc lang="en">
netmask for ARP
</longdesc>
<shortdesc lang="en">netmask for ARP</shortdesc>
<content type="string" default="ffffffffffff"/>
</parameter>
</parameters>
<actions>
<action name="start" timeout="90" />
<action name="stop" timeout="100" />
<action name="monitor" depth="10" timeout="20s" interval="5s" start-delay="1s" />
<action name="meta-data" timeout="5s" />
<action name="verify-all" timeout="30s" />
</actions>
</resource-agent>
END
exit $OCF_SUCCESS
}
ip_init() {
if [ $UID -ne 0 ]; then
ocf_log err "You must be root."
exit $OCF_ERR_PERM
fi
BASEIP="$OCF_RESKEY_ip"
BRDCAST="$OCF_RESKEY_broadcast"
NIC="$OCF_RESKEY_nic"
NETMASK="$OCF_RESKEY_netmask"
#
# $FINDIF can deal with the condition of empty intermediate parameters.
#
NICINFO=`$FINDIF "$BASEIP/$NETMASK/$NIC/$BRDCAST"`
if [ x"$NIC" = "x" ]; then
NIC=`echo "$NICINFO" | cut -f1`
fi
if [ x"$NETMASK" = "x" ]; then
NETMASK=`echo "$NICINFO" | cut -f2-`
fi
if [ x"$BRDCAST" = "x" ]; then
BRDCAST=`echo "$NICINFO" | cut -f3`
fi
if [ -z ${OCF_RESKEY_lvs_support} ]; then
LVS_SUPPORT=0
elif [ ${OCF_RESKEY_lvs_support} = "true"
-o ${OCF_RESKEY_lvs_support} = "on"
-o ${OCF_RESKEY_lvs_support} = "1" ]; then
LVS_SUPPORT=1
else
LVS_SUPPORT=0
fi
# Set default values (can be overridden as parameters)
: ${OCF_RESKEY_ARP_INTERVAL_MS=500}
: ${OCF_RESKEY_ARP_REPEAT=10}
: ${OCF_RESKEY_ARP_BACKGROUND=yes}
: ${OCF_RESKEY_ARP_NETMASK=ffffffffffff}
SENDARPPIDFILE="$SENDARPPIDDIR/send_arp-$BASEIP"
case $NIC in
*:*)
NIC=`echo $NIC | sed 's/:.*//'`
IFLABEL=`echo $NIC | sed 's/.*://'`
;;
esac
}
#
# Find out which alias serves the given IP address
# The argument is an IP address, and its output
# is an aliased interface name (e.g., "eth0:0").
#
find_interface_solaris() {
$IFCONFIG $IFCONFIG_A_OPT | nawk '{if ($0 ~ /.*: / && NR > 1) {print "\n"$0} else {print}}' |
while read ifname linkstuff
do
: ifname = $ifname
read inet addr junk
: inet = $inet addr = $addr
while
read line && [ "X$line" != "X" ]
do
: Nothing
done
case $ifname in
*:*) ;;
*) continue;;
esac
# This doesn't look right for a box with multiple NICs.
# It looks like it always selects the first interface on
# a machine. Yet, we appear to use the results for this case too...
ifname=`echo "$ifname" | sed s'%:$%%'`
case $addr in
addr:$BASEIP) echo $ifname; return $OCF_SUCCESS;;
$BASEIP) echo $ifname; return $OCF_SUCCESS;;
esac
done
return $OCF_ERR_GENERIC
}
#
# Find out which alias serves the given IP address
# The argument is an IP address, and its output
# is an aliased interface name (e.g., "eth0:0").
#
find_interface_generic() {
$IFCONFIG $IFCONFIG_A_OPT |
while read ifname linkstuff
do
: Read gave us ifname = $ifname
read inet addr junk
: Read gave us inet = $inet addr = $addr
while
read line && [ "X$line" != "X" ]
do
: Nothing
done
case $ifname in
*:*) ;;
*) continue;;
esac
case $SYSTYPE in
*BSD)
$IFCONFIG | grep "$BASEIP" -B4 | grep "UP," | cut -d ":" -f 1
return 0;;
*)
: "comparing $BASEIP to $addr (from ifconfig)"
case $addr in
addr:$BASEIP) echo $ifname; return $OCF_SUCCESS;;
$BASEIP) echo $ifname; return $OCF_SUCCESS;;
esac
continue;;
esac
done
return $OCF_ERR_GENERIC
}
#
# Find out which alias serves the given IP address
# The argument is an IP address, and its output
# is an aliased interface name (e.g., "eth0:0").
#
find_interface() {
case $SYSTYPE in
SunOS)
IF=`find_interface_solaris $BASEIP`
;;
*)
IF=`find_interface_generic $BASEIP`
;;
esac
echo $IF
return $OCF_SUCCESS;
}
#
# This routine should handle any type of interface, but has only been
# tested on ethernet-type NICs.
#
ifconfig2sendarp() {
echo "$1" | sed "s%:%%g"
}
delete_route () {
case $SYSTYPE in
SunOS)
CMD=""
;;
*BSD)
CMD="$ROUTE -n delete -host $BASEIP"
;;
*)
CMD="$ROUTE -n del -host $BASEIP"
;;
esac
ocf_log info "$CMD"
$CMD
return $?
}
delete_interface () {
ifname="$1"
case $SYSTYPE in
SunOS)
if [ "$SYSVERSION" -ge 8 ] ; then
CMD="$IFCONFIG $ifname unplumb"
else
CMD="$IFCONFIG $ifname 0 down"
fi
;;
*BSD)
CMD="$IFCONFIG $ifname inet $BASEIP -alias"
;;
*)
CMD="$IFCONFIG $ifname down"
;;
esac
ocf_log info "$CMD"
$CMD
return $?
}
add_interface () {
ipaddr="$1"
ifinfo="$2"
iface="$3"
#
# On Linux the Alias is named ethx:y
# This will remove the "extra" interface Data
# leaving us with just ethx
#
case $SYSTYPE in
*BSD)
IFEXTRA=""
;;
*)
IFEXTRA=`echo "$ifinfo" | cut -f2-`
;;
esac
case $SYSTYPE in
SunOS)
if [ "$SYSVERSION" -ge 8 ] ; then
$IFCONFIG $iface plumb
rc=$?
if [ $rc -ne 0 ] ; then
echo "ERROR: '$IFCONFIG $iface plumb' failed."
return $rc
fi
fi
CMD="$IFCONFIG $iface inet $ipaddr $IFEXTRA up"
;;
*BSD)
CMD="$IFCONFIG $iface inet $ipaddr netmask 255.255.255.255 alias"
;;
*)
CMD="$IFCONFIG $iface $ipaddr $IFEXTRA"
;;
esac
ocf_log info "$CMD"
$CMD
rc=$?
case $rc in
0)
;;
*)
echo "ERROR: $CMD failed."
;;
esac
return $rc
}
# On Linux systems the (hidden) loopback interface may
# conflict with the requested IP address. If so, this
# unoriginal code will remove the offending loopback address
# and save it in VLDIR so it can be added back in later
# when the IPaddr is released.
#
remove_conflicting_loopback() {
ipaddr="$1"
ifname="$2"
ocf_log info "Removing conflicting loopback $ifname."
if
[ -d "$VLDIR/" ] || mkdir -p "$VLDIR/"
then
: Directory $VLDIR now exists
else
ocf_log err "Could not create \"$VLDIR/\" conflicting" \
" loopback $ifname cannot be restored."
fi
if
echo $ifname > "$VLDIR/$ipaddr"
then
: Saved loopback information in $VLDIR/$ipaddr
else
ocf_log err "Could not save conflicting loopback $ifname." \
"it will not be restored."
fi
delete_interface "$ifname"
# Forcibly remove the route (if it exists) to the loopback.
delete_route "$ipaddr"
}
# On Linux systems the (hidden) loopback interface may
# need to be restored if it has been taken down previously
# by remove_conflicting_loopback()
#
restore_loopback() {
ipaddr="$1"
if [ -s "$VLDIR/$ipaddr" ]; then
ifname=`cat "$VLDIR/$ipaddr"`
ocf_log info "Restoring loopback IP Address " \
"$ipaddr on $ifname."
add_interface "$ipaddr" "netmask 255.255.255.255" "$ifname"
rm -f "$VLDIR/$ipaddr"
fi
}
#
# Remove the IP alias for the requested IP address...
#
ip_stop() {
# BASEIP=`echo $1 | sed s'%/.*%%'`
SENDARPPIDFILE="$SENDARPPIDDIR/send_arp-$BASEIP"
IF=`find_interface $BASEIP`
if test -f "$SENDARPPIDFILE"
then
cat "$SENDARPPIDFILE" | xargs kill
rm -f "$SENDARPPIDFILE"
fi
case $SYSTYPE in
*BSD)
if $IFCONFIG $IFCONFIG_A_OPT | \
grep "inet.*[: ]$BASEIP " >/dev/null 2>&1; then
continue;
else
exit $OCF_SUCCESS
fi;;
Linux|SunOS)
if [ -z "$IF" ]; then
: Requested interface not in use
exit $OCF_SUCCESS
elif [ ${LVS_SUPPORT} = 1 ]; then
case $IF in
lo*)
: Requested interface is on loopback
exit $OCF_SUCCESS
;;
esac
fi;;
*)
if [ -z "$IF" ]; then
: Requested interface not in use
exit $OCF_SUCCESS
fi;;
esac
if [ ! -z ${OCF_RESKEY_local_stop_script} ]; then
if [ -x ${OCF_RESKEY_local_stop_script} ]; then
${OCF_RESKEY_local_stop_script} $*
fi
fi
delete_route "$BASEIP"
delete_interface "$IF"
rc=$?
case $SYSTYPE in
*BSD) ;;
Linux|SunOS)
restore_loopback "$BASEIP"
# remove lock file...
rm -f "$VLDIR/$IF";;
*) # remove lock file...
rm -f "$VLDIR/$IF";;
esac
case $rc in
0)
ocf_log info "IP Address $BASEIP released"
;;
*)
ocf_log warn "IP Address $BASEIP NOT released"
;;
esac
return $rc
}
#
# Find an unused interface/alias name for us to use for new IP alias
# The argument is an IP address, and the output
# is an aliased interface name (e.g., "eth0:0", "dc0", "le0:0").
#
find_free_interface() {
if
[ ! -d $VLDIR ]
then
mkdir -p $VLDIR
fi
if
NICINFO=`$FINDIF $BASEIP`
then
: OK
else
lrc=$?
ocf_log err "Unable to find an interface for $BASEIP"
return $lrc
fi
if
[ "X$NIC" = "X" ]
then
ocf_log err "No interface found for $BASEIP"
return $OCF_ERR_GENERIC;
fi
NICBASE="$VLDIR/$NIC"
touch "$NICBASE"
case $SYSTYPE in
SunOS)
IFLIST=`$IFCONFIG $IFCONFIG_A_OPT | \
grep "^$NIC:[0-9]" | sed 's%: .*%%'`
;;
*)
IFLIST=`$IFCONFIG $IFCONFIG_A_OPT | \
grep "^$NIC:[0-9]" | sed 's% .*%%'`
;;
esac
IFLIST=" `echo $IFLIST` "
case $SYSTYPE in
SunOS)
j=1
;;
*)
j=0
TRYADRCNT=`ls "${NICBASE}:"* | wc -l | tr -d ' ' 2>/dev/null`
if
[ -f "${NICBASE}:${TRYADRCNT}" ]
then
: OK
else
j="${TRYADRCNT}"
fi
;;
esac
case $SYSTYPE in
*BSD)
echo $NIC;
return $OCF_SUCCESS;;
*)
while
[ $j -lt 512 ]
do
case $IFLIST in
*" "$NIC:$j" "*) ;;
*)
NICLINK="$NICBASE:$j"
if
ln "$NICBASE" "$NICLINK" 2>/dev/null
then
echo "$NIC:$j $NETMASK"
return $OCF_SUCCESS
fi;;
esac
j=`expr $j + 1`
done;;
esac
return $OCF_ERR_GENERIC
}
#
# Add an IP alias for the requested IP address...
#
# It could be that we already have taken it, in which case it should
# do nothing.
#
ip_start() {
#
# Do we already service this IP address?
#
CURRENTIF=`ip_status`
rc=$?
if [ $rc = $OCF_SUCCESS ]; then
exit $OCF_SUCCESS;
fi
SENDARPPIDFILE="$SENDARPPIDDIR/send_arp-$BASEIP"
if IFINFO=`find_free_interface `; then
: OK got interface [$IFINFO] for $BASEIP
else
exit $OCF_ERR_GENERIC
fi
IF=`echo "$IFINFO" | cut -f1`
# This logic is mostly to support LVS (If I understand it correctly)
if [ ${LVS_SUPPORT} = 1 ]; then
case $SYSTYPE in
Linux|SunOS)
case $IF in
lo*)
if [ x"$if" = x"$CURRENTIF" ]; then
# Its already "running" and not moving, nothing to do.
ocf_log err "Could not find a non-loopback device to move $BASEIP to"
exit $OCF_ERR_GENERIC
fi;;
*) remove_conflicting_loopback "$BASEIP" "$CURRENTIF";;
esac ;;
*) ;;
esac
fi
if [ ! -z ${OCF_RESKEY_local_start_script} ]; then
if [ -x ${OCF_RESKEY_local_start_script} ]; then
${OCF_RESKEY_local_start_script} $*
fi
fi
add_interface "$BASEIP" "$IFINFO" "$IF"
rc=$?
case $rc in
0)
;;
*)
return $rc
;;
esac
TARGET_INTERFACE=`echo $IF | sed 's%:.*%%'`
ocf_log info "Sending Gratuitous Arp for $BASEIP on $IF [$TARGET_INTERFACE]"
ARGS="-i $OCF_RESKEY_ARP_INTERVAL_MS -r $OCF_RESKEY_ARP_REPEAT -p $SENDARPPIDFILE $TARGET_INTERFACE $BASEIP auto $BASEIP $OCF_RESKEY_ARP_NETMASK"
ocf_log info "$SENDARP $ARGS"
case $OCF_RESKEY_ARP_BACKGROUND in
yes) ($SENDARP $ARGS || ocf_log err "Could not send gratuitous arps. rc=$?" & ) >&2 ;;
*) $SENDARP $ARGS || ocf_log err "Could not send gratuitous arps. rc=$?";;
esac
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
do
ip_monitor
if [ $? = $OCF_SUCCESS ]; then
return $OCF_SUCCESS
fi
sleep 1
done
return $OCF_ERR_GENERIC
}
ip_status() {
case $SYSTYPE in
*BSD)
$IFCONFIG $IFCONFIG_A_OPT | grep "inet.*[: ]$BASEIP " >/dev/null 2>&1
if [ $? = 0 ]; then
return $OCF_SUCCESS
else
return $OCF_NOT_RUNNING
fi;;
Linux|SunOS)
IF=`find_interface "$BASEIP"`
echo $IF
if [ -z "$IF" ]; then
return $OCF_NOT_RUNNING
elif [ ${LVS_SUPPORT} = 1 ]; then
case $IF in
lo*) return $OCF_NOT_RUNNING;;
*) return $OCF_SUCCESS;;
esac
else
return $OCF_SUCCESS
fi;;
*)
if [ -z "$IF" ]; then
return $OCF_NOT_RUNNING
else
return $OCF_SUCCESS
fi;;
esac
}
#
# Determine if this IP address is really being served, or not.
# Note that we must distinguish if *we're* serving it locally...
#
ip_monitor() {
TIMEOUT=1 # seconds
case $SYSTYPE in
Linux)
# -c count -t timetolive -q(uiet) -n(umeric) -W timeout
- PINGARGS="-c 1 -q -n -W $TIMEOUT $BASEIP"
+ PINGARGS="-c 1 -q -n $BASEIP"
;;
SunOS)
PINGARGS="$BASEIP $TIMEOUT"
;;
*)
- PINGARGS="-c 1 @PING_TIMEOUT_OPT@ -q $BASEIP"
+ PINGARGS="-c 1 -q $BASEIP"
;;
esac
for j in 1 2 3
do
if
+ ip_status
+ then
@PING@ $PINGARGS >/dev/null 2>&1
+ if
+ [ $? -eq 0 ]
then
- ip_status
- return $?
+ return $OCF_SUCCESS
+ fi
fi
done
return $OCF_NOT_RUNNING
}
usage() {
echo $USAGE >&2
}
#
# Add or remove IP alias for the given IP address...
#
if
[ $# -eq 1 ]
then
case $1 in
info) cat <<-!INFO
Abstract=IP address takeover
Argument=IP address OR IP address/broadcast address OR IP address/broadcast address/netmaskbits
Description:
An IPaddr resource is an IP address which is to be taken over by \\
the owning node. An argument is required, and is of this form:
nnn.nnn.nnn.nnn/bbb.bbb.bbb.bbb
Where nnn.nnn.nnn.nnn is the IP address to be taken over, and\\
bbb.bbb.bbb.bbb is the broadcast address to be used with this address.
Since IPaddr is the "default" resource type, it is not necessary\\
to prefix the IP address by "IPaddr::".
This allows IPaddr::192.2.4.63 to be abbreviated as 192.2.4.63.
!INFO
exit $OCF_SUCCESS;;
esac
fi
if
[ $# -eq 0 ]
then
usage
exit $OCF_ERR_GENERIC
fi
case $1 in
start) ip_init; ip_start ;;
stop) ip_init; ip_stop ;;
status) ip_init; ip_status ;;
monitor) ip_init; ip_monitor ;;
meta-data) meta_data;;
*) usage
exit 1
;;
esac

File Metadata

Mime Type
text/x-diff
Expires
Wed, Feb 26, 1:36 PM (12 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1465392
Default Alt Text
(19 KB)

Event Timeline