summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAn-Cheng Huang <ancheng@vyatta.com>2008-03-31 16:44:09 -0700
committerAn-Cheng Huang <ancheng@vyatta.com>2008-03-31 16:44:09 -0700
commit3e1a8fb1e9b1ed7c61ea1f7b9f160778837102d1 (patch)
treef91af1d76910fa16f63d2312831161623c83deac
parent073a7246d555555a6137139fc9545e2b48f870cb (diff)
downloadvyatta-cluster-3e1a8fb1e9b1ed7c61ea1f7b9f160778837102d1.tar.gz
vyatta-cluster-3e1a8fb1e9b1ed7c61ea1f7b9f160778837102d1.zip
import IPaddr2 scripts from heartbeat 2.1.3-2
-rwxr-xr-xscripts/etc-IPaddr2-vyatta70
-rwxr-xr-xscripts/ocf-IPaddr2-vyatta805
2 files changed, 875 insertions, 0 deletions
diff --git a/scripts/etc-IPaddr2-vyatta b/scripts/etc-IPaddr2-vyatta
new file mode 100755
index 0000000..134d00c
--- /dev/null
+++ b/scripts/etc-IPaddr2-vyatta
@@ -0,0 +1,70 @@
+#!/bin/sh
+#
+#
+# Description: wrapper of OCF RA IPaddr2, based on original heartbeat RA.
+# See OCF RA IPaddr2 for more information.
+#
+# Author: Xun Sun <xunsun@cn.ibm.com>
+# Support: linux-ha@lists.linux-ha.org
+# License: GNU General Public License (GPL)
+# Copyright: (C) 2005 International Business Machines
+#
+# This script manages IP alias IP addresses
+#
+# It can add an IP alias, or remove one.
+#
+# usage: $0 ip-address[/netmaskbits[/interface[:label][/broadcast]]] \
+# {start|stop|status|monitor}
+#
+# The "start" arg adds an IP alias.
+#
+# Surprisingly, the "stop" arg removes one. :-)
+#
+unset LANG; export LANG
+LC_ALL=C
+export LC_ALL
+
+. /etc/ha.d/resource.d//hto-mapfuncs
+
+# We need to split the argument into pieces that IPaddr OCF RA can
+# recognize, sed is prefered over Bash specific builtin functions
+# for portability.
+
+usage() {
+ echo "usage: $0 ip-address[/netmaskbits[/interface[:label][/broadcast]]] $LEGAL_ACTIONS"
+}
+
+if [ $# != 2 ]; then
+ usage
+ exit 1
+fi
+
+BASEIP=`echo $1 | sed 's%/.*%%'`
+OCF_RESKEY_ip=$BASEIP; export OCF_RESKEY_ip
+
+str=`echo $1 | sed 's%^'$BASEIP'/*%%'`
+if [ ! -z "$str" ]; then
+ NETMASK=`echo $str | sed 's%/.*%%'`
+ OCF_RESKEY_cidr_netmask=$NETMASK; export OCF_RESKEY_cidr_netmask
+
+ str=`echo $str | sed 's%^'$NETMASK'/*%%'`
+ NIC=`echo $str | sed 's%/.*%%'`
+ case $NIC in
+ [0-9]*) BROADCAST=$NIC
+ OCF_RESKEY_broadcast=$BROADCAST; export OCF_RESKEY_broadcast
+ NIC=
+ ;;
+ "") ;;
+ *) BROADCAST=`echo $str | sed -e 's%^'$NIC'/*%%' -e 's%/.*%%'`
+ OCF_RESKEY_nic=$NIC; export OCF_RESKEY_nic
+ OCF_RESKEY_broadcast=$BROADCAST; export OCF_RESKEY_broadcast
+ ;;
+ esac
+fi
+
+OCF_TYPE=IPaddr2
+OCF_RESKEY_lvs_support=1
+OCF_RESOURCE_INSTANCE=${OCF_TYPE}_$BASEIP
+export OCF_TYPE OCF_RESOURCE_INSTANCE OCF_RESKEY_lvs_support
+
+ra_execocf $2
diff --git a/scripts/ocf-IPaddr2-vyatta b/scripts/ocf-IPaddr2-vyatta
new file mode 100755
index 0000000..0d1101c
--- /dev/null
+++ b/scripts/ocf-IPaddr2-vyatta
@@ -0,0 +1,805 @@
+#!/bin/sh
+#
+# $Id: IPaddr2.in,v 1.24 2006/08/09 13:01:54 lars Exp $
+#
+# OCF Resource Agent compliant IPaddr2 script.
+#
+# Based on work by Tuomo Soini, ported to the OCF RA API by Lars
+# Marowsky-Brée. Implements Cluster Alias IP functionality too.
+#
+# Cluster Alias IP cleanup, fixes and testing by Michael Schwartzkopff
+#
+#
+# Copyright (c) 2003 Tuomo Soini
+# Copyright (c) 2004-2006 SUSE LINUX AG, Lars Marowsky-Brée
+# All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+#
+
+
+# TODO:
+# - There ought to be an ocf_run_cmd function which does all logging,
+# timeout handling etc for us
+# - Make this the standard IP address agent on Linux; the other
+# platforms simply should ignore the additional parameters OR can use
+# the legacy heartbeat resource script...
+# - Check LVS <-> clusterip incompatibilities.
+#
+# OCF parameters are as below
+# OCF_RESKEY_ip
+# OCF_RESKEY_broadcast
+# OCF_RESKEY_nic
+# OCF_RESKEY_cidr_netmask
+# OCF_RESKEY_iflabel
+# OCF_RESKEY_mac
+# OCF_RESKEY_clusterip_hash
+# OCF_RESKEY_arp_interval
+# OCF_RESKEY_arp_count
+# OCF_RESKEY_arp_bg
+# OCF_RESKEY_arp_mac
+#
+# OCF_RESKEY_CRM_meta_clone
+# OCF_RESKEY_CRM_meta_clone_max
+
+
+#######################################################################
+# Initialization:
+
+. ${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs
+
+SENDARP=$HA_BIN/send_arp
+FINDIF=$HA_BIN/findif
+VLDIR=$HA_RSCTMP/IPaddr
+SENDARPPIDDIR=$HA_RSCTMP/send_arp
+CIP_lockfile=$HA_RSCTMP/IPaddr2-CIP-${OCF_RESKEY_ip}
+
+#######################################################################
+
+meta_data() {
+ cat <<END
+<?xml version="1.0"?>
+<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
+<resource-agent name="IPaddr2">
+<version>1.0</version>
+
+<longdesc lang="en">
+This Linux-specific resource manages IP alias IP addresses.
+It can add an IP alias, or remove one.
+In addition, it can implement Cluster Alias IP functionality
+if invoked as a clone resource.
+</longdesc>
+
+<shortdesc lang="en">Manages virtual IPv4 addresses</shortdesc>
+
+<parameters>
+<parameter name="ip" unique="1" required="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="cidr_netmask">
+<longdesc lang="en">
+The netmask for the interface in CIDR format
+(e.g., 24 and not 255.255.255.0)
+
+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.
+This label is appended to your interface name.
+If a label is specified in nic name, this parameter has no effect.
+</longdesc>
+<shortdesc lang="en">Interface label</shortdesc>
+<content type="string" default=""/>
+</parameter>
+
+<parameter name="lvs_support">
+<longdesc lang="en">
+Enable support for LVS Direct Routing configurations. In case a IP
+address is stopped, only move it to the loopback device to allow the
+local node to continue to service requests, but no longer advertise it
+on the network.
+</longdesc>
+<shortdesc lang="en">Enable support for LVS DR</shortdesc>
+<content type="boolean" default="false"/>
+</parameter>
+
+<parameter name="mac">
+<longdesc lang="en">
+Set the interface MAC address explicitly. Currently only used in case of
+the Cluster IP Alias. Leave empty to chose automatically.
+
+</longdesc>
+<shortdesc lang="en">Cluster IP MAC address</shortdesc>
+<content type="string" default=""/>
+</parameter>
+
+<parameter name="clusterip_hash">
+<longdesc lang="en">
+Specify the hashing algorithm used for the Cluster IP functionality.
+
+</longdesc>
+<shortdesc lang="en">Cluster IP hashing function</shortdesc>
+<content type="string" default="sourceip-sourceport-destport"/>
+</parameter>
+
+<parameter name="arp_interval">
+<longdesc lang="en">
+Specify the interval between unsolicited ARP packets in milliseconds.
+</longdesc>
+<shortdesc lang="en">ARP packet interval in ms</shortdesc>
+<content type="integer" default="200"/>
+</parameter>
+
+<parameter name="arp_count">
+<longdesc lang="en">
+Number of unsolicited ARP packets to send.
+</longdesc>
+<shortdesc lang="en">ARP packet count</shortdesc>
+<content type="integer" default="5"/>
+</parameter>
+
+<parameter name="arp_bg">
+<longdesc lang="en">
+Whether or not to send the arp packets in the background.
+</longdesc>
+<shortdesc lang="en">ARP from background</shortdesc>
+<content type="string" default="yes"/>
+</parameter>
+
+<parameter name="arp_mac">
+<longdesc lang="en">
+MAC address to send the ARP packets too.
+
+You really shouldn't be touching this.
+
+</longdesc>
+<shortdesc lang="en">ARP MAC</shortdesc>
+<content type="string" default="ffffffffffff"/>
+</parameter>
+
+</parameters>
+
+<actions>
+<action name="start" timeout="90" />
+<action name="stop" timeout="100" />
+<action name="status" depth="10" timeout="20s" interval="10s" start-delay="5s" />
+<action name="monitor" depth="10" timeout="20s" interval="10s" start-delay="5s" />
+<action name="meta-data" timeout="5s" />
+<action name="validate-all" timeout="20s" />
+</actions>
+</resource-agent>
+END
+
+ exit $OCF_SUCCESS
+}
+
+ip_init() {
+ if [ X`uname -s` != "XLinux" ]; then
+ ocf_log err "IPaddr2 only supported Linux."
+ exit $OCF_ERR_INSTALLED
+ fi
+
+ if
+ case $__OCF_ACTION in
+ start|stop) ocf_is_root;;
+ *) true;;
+ esac
+ then
+ : YAY!
+ else
+ ocf_log err "You must be root for $__OCF_ACTION operation."
+ exit $OCF_ERR_PERM
+ fi
+
+ BASEIP="$OCF_RESKEY_ip"
+ BRDCAST="$OCF_RESKEY_broadcast"
+ NIC="$OCF_RESKEY_nic"
+ # Note: We had a version out there for a while which used
+ # netmask instead of cidr_netmask. Don't remove this aliasing code!
+ if
+ [ ! -z "$OCF_RESKEY_netmask" -a -z "$OCF_RESKEY_cidr_netmask" ]
+ then
+ OCF_RESKEY_cidr_netmask=$OCF_RESKEY_netmask
+ export OCF_RESKEY_cidr_netmask
+ fi
+ NETMASK="$OCF_RESKEY_cidr_netmask"
+ IFLABEL="$OCF_RESKEY_iflabel"
+ IF_MAC="$OCF_RESKEY_mac"
+
+ LVS_SUPPORT=0
+ if [ x"${OCF_RESKEY_lvs_support}" = x"true" \
+ -o x"${OCF_RESKEY_lvs_support}" = x"on" \
+ -o x"${OCF_RESKEY_lvs_support}" = x"1" ]; then
+ LVS_SUPPORT=1
+ fi
+
+ IP_INC_GLOBAL=${OCF_RESKEY_CRM_meta_clone_max:-1}
+ IP_INC_NO=`expr $OCF_RESKEY_CRM_meta_clone + 1`
+ IP_CIP_HASH="${OCF_RESKEY_clusterip_hash}"
+
+ if [ $LVS_SUPPORT -gt 0 ] && [ $IP_INC_GLOBAL -gt 1 ]; then
+ ocf_log err "LVS and load sharing do not go together well"
+ exit OCF_ERR_ARGS
+ fi
+
+ ARP_INTERVAL_MS=${OCF_RESKEY_arp_interval:-200}
+ ARP_REPEAT=${OCF_RESKEY_arp_count:-5}
+ ARP_BACKGROUND=${OCF_RESKEY_arp_bg:-yes}
+ ARP_NETMASK=${OCF_RESKEY_arp_mac:-ffffffffffff}
+
+ if ocf_is_decimal "$IP_INC_GLOBAL" && [ $IP_INC_GLOBAL -gt 0 ]; then
+ :
+ else
+ ocf_log err "Invalid OCF_RESKEY_incarnations_max_global [$IP_INC_GLOBAL], should be positive integer"
+ exit $OCF_ERR_ARGS
+ fi
+
+
+ # Validation is performed in ip_validate()...
+ #
+ # $FINDIF now takes its parameters from the environment
+ #
+ if
+ NICINFO=`$FINDIF -C`
+ then
+ NICINFO=`echo $NICINFO | sed -e 's/netmask\ //;s/broadcast\ //'`
+ NIC=`echo "$NICINFO" | cut -d" " -f1`
+ NETMASK=`echo "$NICINFO" | cut -d" " -f2`
+ BRDCAST=`echo "$NICINFO" | cut -d" " -f3`
+ else
+ ocf_log err "[$FINDIF -C] failed"
+ exit $OCF_ERR_ARGS
+ fi
+
+ SENDARPPIDFILE="$SENDARPPIDDIR/send_arp-$BASEIP"
+
+ case $NIC in
+ *:*)
+ IFLABEL=$NIC
+ NIC=`echo $NIC | sed 's/:.*//'`
+ ;;
+ *)
+ if [ -n "$IFLABEL" ]; then
+ IFLABEL=${NIC}:${IFLABEL}
+ fi
+ ;;
+ esac
+
+ IP_CIP=
+
+ if [ "$IP_INC_GLOBAL" -gt 1 ]; then
+ IP_CIP="yes"
+ if [ -z "$IF_MAC" ]; then
+ # Choose a MAC
+ # 1. Concatenate some input together
+ # 2. This doesn't need to be a cryptographically
+ # secure hash.
+ # 3. Drop everything after the first 6 octets (12 chars)
+ # 4. Delimit the octets with ':'
+ # 5. Make sure the first octet is odd,
+ # so the result is a multicast MAC
+ IF_MAC=`echo $BASEIP $NETMASK $BRDCAST | \
+ md5sum | \
+ sed -e 's#\(............\).*#\1#' \
+ -e 's#..#&:#g; s#:$##' \
+ -e 's#^\(.\)[02468aAcCeE]#\11#'`
+ fi
+ IP_CIP_FILE="/proc/net/ipt_CLUSTERIP/$BASEIP"
+ fi
+}
+
+#
+# Find out which interface serves the given IP address
+# The argument is an IP address, and its output
+# is an interface name (e.g., "eth0").
+#
+find_interface() {
+ #
+ # List interfaces but exclude FreeS/WAN ipsecN virtual interfaces
+ #
+ local iface=`$IP2UTIL -o -f inet addr show | grep "\ $BASEIP/" \
+ | cut -d ' ' -f2 | grep -v '^ipsec[0-9][0-9]*$'`
+ echo $iface
+ return 0
+}
+
+#
+# Delete an interface
+#
+delete_interface () {
+ ipaddr="$1"
+ iface="$2"
+ netmask="$3"
+
+ CMD="$IP2UTIL -f inet addr delete $ipaddr/$netmask dev $iface"
+
+ ocf_log info "$CMD"
+ $CMD
+
+ if [ $? -ne 0 ]; then
+ return $OCF_ERR_GENERIC
+ fi
+
+ CMD="$IP2UTIL -o -f inet addr show $iface"
+
+ ocf_log info "$CMD"
+ ADDR=`$CMD`
+
+ if [ $? -ne 0 -o ! -z "$ADDR" ]; then
+ return $?
+ fi
+
+ CMD="$IP2UTIL link set $iface down"
+
+ ocf_log info "$CMD"
+ $CMD
+ return $?
+}
+
+#
+# Add an interface
+#
+add_interface () {
+ ipaddr="$1"
+ netmask="$2"
+ broadcast="$3"
+ iface="$4"
+ label="$5"
+
+ CMD="$IP2UTIL -f inet addr add $ipaddr/$netmask brd $broadcast dev $iface"
+
+ if [ ! -z "$label" ]; then
+ CMD="$CMD label $label"
+ fi
+
+ ocf_log info "$CMD"
+ $CMD
+
+ if [ $? -ne 0 ]; then
+ return $OCF_ERR_GENERIC
+ fi
+
+ CMD="$IP2UTIL link set $iface up"
+
+ ocf_log info "$CMD"
+ $CMD
+
+ return $?
+}
+
+#
+# Delete a route
+#
+delete_route () {
+ prefix="$1"
+ iface="$2"
+
+ CMD="$IP2UTIL route delete $prefix dev $iface"
+
+ ocf_log info "$CMD"
+ $CMD
+
+ return $?
+}
+
+# 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.
+#
+# TODO: This is very ugly and should be controlled by an additional
+# instance parameter. Or even: multi-state, with the IP only being
+# "active" on the master!?
+#
+remove_conflicting_loopback() {
+ ipaddr="$1"
+ netmask="$2"
+ broadcast="$3"
+ ifname="$4"
+
+ 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 "$ipaddr $netmask $broadcast $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 "$ipaddr" "$ifname" "$netmask"
+ # Forcibly remove the route (if it exists) to the loopback.
+ delete_route "$ipaddr" "$ifname"
+}
+
+#
+# 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
+ ifinfo=`cat "$VLDIR/$ipaddr"`
+ ocf_log info "Restoring loopback IP Address " \
+ "$ifinfo."
+ add_interface $ifinfo
+ rm -f "$VLDIR/$ipaddr"
+ fi
+}
+
+#
+# Run send_arp to note peers about new mac address
+#
+run_send_arp() {
+ ARGS="-i $ARP_INTERVAL_MS -r $ARP_REPEAT -p $SENDARPPIDFILE $NIC $BASEIP auto not_used not_used"
+ if [ "x$IP_CIP" = "xyes" ] ; then
+ if [ x = "x$IF_MAC" ] ; then
+ MY_MAC=auto
+ else
+ MY_MAC=`echo ${IF_MAC} | sed -e 's/://'`
+ fi
+ ARGS="-i $ARP_INTERVAL_MS -r $ARP_REPEAT -p $SENDARPPIDFILE $NIC $BASEIP $MY_MAC not_used not_used"
+ fi
+ ocf_log info "$SENDARP $ARGS"
+ case $ARP_BACKGROUND in
+ yes)
+ ($SENDARP $ARGS || ocf_log err "Could not send gratuitous arps" &) >&2
+ ;;
+ *)
+ $SENDARP $ARGS || ocf_log err "Could not send gratuitous arps"
+ ;;
+ esac
+}
+
+# Do we already serve this IP address?
+#
+# returns:
+# ok = served (for CIP: + hash bucket)
+# partial = served and no hash bucket (CIP only)
+# no = nothing
+#
+ip_served() {
+ cur_nic="`find_interface $BASEIP`"
+
+ if [ -z "$cur_nic" ]; then
+ echo "no"
+ return 0
+ fi
+
+ if [ -z "$IP_CIP" ]; then
+ case $cur_nic in
+ lo*) if [ "$LVS_SUPPORT" = "1" ]; then
+ echo "no"
+ return 0
+ fi
+ ;;
+ esac
+
+ echo "ok"
+ return 0
+ fi
+
+ # Special handling for the CIP:
+ if grep -q "^${IP_INC_NO},\|,${IP_INC_NO},\|,${IP_INC_NO}$\|^${IP_INC_NO}$" $IP_CIP_FILE ; then
+ echo "ok"
+ return 0
+ else
+ echo "partial"
+ return 0
+ fi
+
+ exit $OCF_ERR_GENERIC
+}
+
+#######################################################################
+
+ip_usage() {
+ cat <<END
+usage: $0 {start|stop|status|monitor|validate-all|meta-data}
+
+Expects to have a fully populated OCF RA-compliant environment set.
+END
+}
+
+ip_start() {
+ if [ -n "$IP_CIP" ]; then
+ # Cluster IPs need special processing when the first bucket
+ # is added to the node... take a lock to make sure only one
+ # process executes that code
+ ocf_take_lock $CIP_lockfile
+ ocf_release_lock_on_exit $CIP_lockfile
+ fi
+
+ ip_init
+
+ #
+ # Do we already service this IP address?
+ #
+ local ip_status=`ip_served`
+
+ if [ "$ip_status" = "ok" ]; then
+ exit $OCF_SUCCESS
+ fi
+
+ if [ -n "$IP_CIP" ] && [ $ip_status = "no" ]; then
+ $MODPROBE ip_conntrack
+ $IPTABLES -I INPUT -d $BASEIP -i $NIC -j CLUSTERIP \
+ --new \
+ --clustermac $IF_MAC \
+ --total-nodes $IP_INC_GLOBAL \
+ --local-node $IP_INC_NO \
+ --hashmode $IP_CIP_HASH
+ if [ $? -ne 0 ]; then
+ ocf_log err "iptables failed"
+ exit $OCF_ERR_GENERIC
+ fi
+ fi
+
+ if [ -n "$IP_CIP" ] && [ $ip_status = "partial" ]; then
+ echo "+$IP_INC_NO" >$IP_CIP_FILE
+ fi
+
+ if [ "$ip_status" = "no" ]; then
+ if [ "$LVS_SUPPORT" = "1" ]; then
+ case `find_interface $BASEIP` in
+ lo*)
+ remove_conflicting_loopback $BASEIP 32 255.255.255.255 lo
+ ;;
+ esac
+ fi
+
+ add_interface $BASEIP $NETMASK $BRDCAST $NIC $IFLABEL
+
+ if [ $? -ne 0 ]; then
+ ocf_log err "$CMD failed."
+ exit $OCF_ERR_GENERIC
+ fi
+ fi
+
+ case $NIC in
+ lo*)
+ : no need to run send_arp on loopback
+ ;;
+ *)
+ run_send_arp
+ ;;
+ esac
+ exit $OCF_SUCCESS
+}
+
+ip_stop() {
+ ip_init
+ local ip_del_if="yes"
+ if [ -n "$IP_CIP" ]; then
+ # Cluster IPs need special processing when the last bucket
+ # is removed from the node... take a lock to make sure only one
+ # process executes that code
+ ocf_take_lock $CIP_lockfile
+ ocf_release_lock_on_exit $CIP_lockfile
+ fi
+
+ if [ -f "$SENDARPPIDFILE" ] ; then
+ kill `cat "$SENDARPPIDFILE"`
+ if [ $? -ne 0 ]; then
+ ocf_log warn "Could not kill previously running send_arp for $BASEIP"
+ else
+ ocf_log info "killed previously running send_arp for $BASEIP"
+ rm -f "$SENDARPPIDFILE"
+ fi
+ fi
+ local ip_status=`ip_served`
+
+ if [ $ip_status = "no" ]; then
+ : Requested interface not in use
+ exit $OCF_SUCCESS
+ fi
+
+ if [ -n "$IP_CIP" ]; then
+ if [ $ip_status = "partial" ]; then
+ exit $OCF_SUCCESS
+ fi
+ echo "-$IP_INC_NO" >$IP_CIP_FILE
+ if [ "x$(cat $IP_CIP_FILE)" = "x" ]; then
+ ocf_log info $BASEIP, $IP_CIP_HASH
+ i=1
+ while [ $i -le $IP_INC_GLOBAL ]; do
+ ocf_log info $i
+ $IPTABLES -D INPUT -d $BASEIP -i $NIC -j CLUSTERIP \
+ --new \
+ --clustermac $IF_MAC \
+ --total-nodes $IP_INC_GLOBAL \
+ --local-node $i \
+ --hashmode $IP_CIP_HASH
+ i=`expr $i + 1`
+ done
+ else
+ ip_del_if="no"
+ fi
+ fi
+
+ if [ "$ip_del_if" = "yes" ]; then
+ delete_interface $BASEIP $NIC $NETMASK
+ if [ $? -ne 0 ]; then
+ exit $OCF_ERR_GENERIC
+ fi
+
+ if [ "$LVS_SUPPORT" = 1 ]; then
+ restore_loopback "$BASEIP"
+ fi
+ fi
+
+ exit $OCF_SUCCESS
+}
+
+ip_monitor() {
+ ip_init
+ # TODO: Implement more elaborate monitoring like checking for
+ # interface health maybe via a daemon like FailSafe etc...
+
+ local ip_status=`ip_served`
+ case $ip_status in
+ ok)
+ return $OCF_SUCCESS
+ ;;
+ partial|no)
+ exit $OCF_NOT_RUNNING
+ ;;
+ *)
+ # Errors on this interface?
+ return $OCF_ERR_GENERIC
+ ;;
+ esac
+}
+
+ip_validate() {
+ check_binary $IP2UTIL
+ if [ -n "$IP_CIP" ]; then
+ check_binary $IPTABLES
+ check_binary $MODPROBE
+ fi
+
+ ip_init
+
+# $BASEIP, $NETMASK, $NIC , $IP_INC_GLOBAL, and $BRDCAST have been checked within ip_init,
+# do not bother here.
+
+ if ocf_is_decimal "$ARP_INTERVAL_MS" && [ $ARP_INTERVAL_MS -gt 0 ]; then
+ :
+ else
+ ocf_log err "Invalid OCF_RESKEY_arp_interval [$ARP_INTERVAL_MS]"
+ exit $OCF_ERR_ARGS
+ fi
+
+ if ocf_is_decimal "$ARP_REPEAT" && [ $ARP_REPEAT -gt 0 ]; then
+ :
+ else
+ ocf_log err "Invalid OCF_RESKEY_arp_count [$ARP_REPEAT]"
+ exit $OCF_ERR_ARGS
+ fi
+
+ if [ -n "$IP_CIP" ]; then
+
+ local valid=1
+
+ case $IP_CIP_HASH in
+ sourceip|sourceip-sourceport|sourceip-sourceport-destport)
+ ;;
+ *)
+ ocf_log err "Invalid OCF_RESKEY_clusterip_hash [$IP_CIP_HASH]"
+ exit $OCF_ERR_ARGS
+ ;;
+ esac
+
+ if [ "$LVS_SUPPORT" = 1 ]; then
+ ecf_log err "LVS and load sharing not advised to try"
+ exit $OCF_ERR_ARGS
+ fi
+
+ case $IF_MAC in
+ [0-9a-zA-Z][1379bBdDfF][^0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z][^0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z][^0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z][^0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z][^0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z])
+ ;;
+ *)
+ valid=0
+ ;;
+ esac
+
+ if [ $valid -eq 0 ]; then
+ ocf_log err "Invalid IF_MAC [$IF_MAC]"
+ exit $OCF_ERR_ARGS
+ fi
+
+ fi
+
+ exit $OCF_SUCCESS
+}
+
+case $__OCF_ACTION in
+meta-data) meta_data
+ ;;
+start) ip_start
+ ;;
+stop) ip_stop
+ ;;
+status) ip_init
+ ip_status=`ip_served`
+ if [ $ip_status = "ok" ]; then
+ echo "running"
+ exit $OCF_SUCCESS
+ else
+ echo "stopped"
+ exit $OCF_NOT_RUNNING
+ fi
+ ;;
+monitor) ip_monitor
+ ;;
+validate-all) ip_validate
+ ;;
+usage|help) ip_usage
+ exit $OCF_SUCCESS
+ ;;
+*) ip_usage
+ exit $OCF_ERR_UNIMPLEMENTED
+ ;;
+esac