Hello Florian, Your question is fully justified - I sincerely apologize for ignoring that comprehensive documentation.
I rewrote the patch trying to adhere to the requirements given in the documentation. Best Regards, Christian --- AUTHORS | 1 + doc/man/Makefile.am | 1 + heartbeat/Makefile.am | 1 + heartbeat/proxyarp | 381 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 384 insertions(+) create mode 100755 heartbeat/proxyarp diff --git a/AUTHORS b/AUTHORS index ee0169a..f39b565 100644 --- a/AUTHORS +++ b/AUTHORS @@ -11,6 +11,7 @@ Andrew Price <andy at andrewprice.me.uk> Benjamin Marzinski <bmarzins at redhat.com> Bob Peterson <rpeterso at redhat.com> Chris Feist <cfeist at redhat.com> +Christian Franke <nobody at nowhere dot ws> Christian Rishoj <[email protected]> Christine Caulfield <ccaulfie at redhat.com> Daiki Matsuda <[email protected]> diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am index a7dae80..56169a2 100644 --- a/doc/man/Makefile.am +++ b/doc/man/Makefile.am @@ -120,6 +120,7 @@ man_MANS = ocf_heartbeat_AoEtarget.7 \ ocf_heartbeat_postfix.7 \ ocf_heartbeat_pound.7 \ ocf_heartbeat_proftpd.7 \ + ocf_heartbeat_proxyarp.7 \ ocf_heartbeat_rsyncd.7 \ ocf_heartbeat_rsyslog.7 \ ocf_heartbeat_scsi2reservation.7 \ diff --git a/heartbeat/Makefile.am b/heartbeat/Makefile.am index adfd97c..cb33cb2 100644 --- a/heartbeat/Makefile.am +++ b/heartbeat/Makefile.am @@ -87,6 +87,7 @@ ocf_SCRIPTS = ClusterMon \ pound \ pgsql \ proftpd \ + proxyarp \ Pure-FTPd \ Raid1 \ Route \ diff --git a/heartbeat/proxyarp b/heartbeat/proxyarp new file mode 100755 index 0000000..bed0273 --- /dev/null +++ b/heartbeat/proxyarp @@ -0,0 +1,381 @@ +#!/bin/sh +# +# OCF Resource Agent for Proxy ARP on Linux +# Copyright (c) 2012 Christian Franke <[email protected]> +# +# Based on: +# +# 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. +# +# + +# OCF parameters are as below +# OCF_RESKEY_ip +# OCF_RESKEY_nic +# OCF_RESKEY_arp_interval +# OCF_RESKEY_arp_count +# OCF_RESKEY_arp_mac +# OCF_RESKEY_arp_insist + +####################################################################### +# Initialization: + +: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} +. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs + +# Defaults +OCF_RESKEY_arp_interval_default=200 +OCF_RESKEY_arp_count_default=5 +OCF_RESKEY_arp_mac_default="ffffffffffff" +OCF_RESKEY_arp_insist_default=false + +: ${OCF_RESKEY_arp_interval=${OCF_RESKEY_arp_interval_default}} +: ${OCF_RESKEY_arp_count=${OCF_RESKEY_arp_count_default}} +: ${OCF_RESKEY_arp_mac=${OCF_RESKEY_arp_mac_default}} +: ${OCF_RESKEY_arp_insist=${OCF_RESKEY_arp_insist_default}} +####################################################################### + +SENDARP=$HA_BIN/send_arp +PIDDIR=$HA_RSCTMP + +####################################################################### + +meta_data() { + cat <<END +<?xml version="1.0"?> +<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd"> +<resource-agent name="proxyarp"> +<version>1.0</version> + +<longdesc lang="en"> +This Linux specific resource maintains a proxy arp entry. +It also supports sending gratuitous arp when the resource +starts up. +</longdesc> + +<shortdesc lang="en">Manages proxy arp (Linux specific version)</shortdesc> + +<parameters> +<parameter name="ip" 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" /> +</parameter> +<parameter name="nic" required="1"> +<longdesc lang="en"> +The base network interface on which questions for arp will be replied to. +</longdesc> +<shortdesc lang="en">Network interface</shortdesc> +<content type="string"/> +</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="${OCF_RESKEY_arp_interval_default}"/> +</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="${OCF_RESKEY_arp_count_default}"/> +</parameter> + +<parameter name="arp_mac"> +<longdesc lang="en"> +MAC address to send the ARP packets to. + +You really shouldn't be touching this. + +</longdesc> +<shortdesc lang="en">ARP MAC</shortdesc> +<content type="string" default="${OCF_RESKEY_arp_mac_default}"/> +</parameter> + +<parameter name="arp_insist"> +<longdesc lang="en"> +Whether or not to insist on successful gratuitous arp. + +In some setups, gratuitous arp is very important, because +its failure would cause huge service disruptions. For those +cases, it is wise to insist on gratuitous arp to run successfuly +for the start operation to report success. +</longdesc> +<shortdesc lang="en">Insist on gratuitous ARP</shortdesc> +<content type="string" default="${OCF_RESKEY_arp_insist_default}"/> +</parameter> + +</parameters> +<actions> +<action name="start" timeout="20s" /> +<action name="stop" timeout="20s" /> +<action name="status" depth="0" timeout="20s" interval="10s" /> +<action name="monitor" depth="0" timeout="20s" interval="10s" /> +<action name="meta-data" timeout="5s" /> +<action name="validate-all" timeout="20s" /> +</actions> +</resource-agent> +END + + exit $OCF_SUCCESS +} + +proxy_arp_init() { + if [ X`uname -s` != "XLinux" ]; then + ocf_log err "proxyarp only supported on Linux." + exit $OCF_ERR_INSTALLED + fi + + if [ X"$OCF_RESKEY_ip" = "X" ]; then + ocf_log err "IP address (the ip parameter) is mandatory" + exit $OCF_ERR_CONFIGURED + fi + + if [ X"$OCF_RESKEY_nic" = "X" ]; then + ocf_log err "Interface (the nic parameter) is mandatory" + exit $OCF_ERR_CONFIGURED + 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 + + IP="$OCF_RESKEY_ip" + NIC="$OCF_RESKEY_nic" + SENDARPPIDFILE="$PIDDIR/send_arp-$IP" +} + +# +# Removes a proxy arp entry from the arp table +# +remove_proxy_arp () { + local ipaddr iface + + ipaddr="$1" + iface="$2" + + CMD="$IP2UTIL neigh del proxy $ipaddr dev $iface" + + ocf_run $CMD || return $OCF_ERR_GENERIC + + return $OCF_SUCCESS +} + +# +# Adds a proxy arp entry to the arp table +# +add_proxy_arp () { + local msg ipaddr iface + + ipaddr="$1" + iface="$2" + + CMD="$IP2UTIL neigh add proxy $ipaddr dev $iface" + msg="Adding proxy arp for $ipaddr on $iface" + + ocf_log info "$msg" + ocf_run $CMD || return $OCF_ERR_GENERIC + + return $OCF_SUCCESS +} + +# +# Run send_arp to note peers about new mac address +# +run_send_arp() { + local args + + args="-i $OCF_RESKEY_arp_interval -r $OCF_RESKEY_arp_count -p $SENDARPPIDFILE $NIC $IP auto not_used not_used" + ocf_log info "$SENDARP $args" + + $SENDARP $args + if [ $? -ne 0 ]; then + ocf_log err "gratuitous arp failed." + return $OCF_ERR_GENERIC + fi + + return $OCF_SUCCESS +} + +####################################################################### + +proxy_arp_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 +} + +proxy_arp_monitor() { + local proxy_entries + + if ! ha_pseudo_resource "${OCF_RESOURCE_INSTANCE}" monitor; then + return $OCF_NOT_RUNNING + fi + + proxy_entries=`grep ' 0xc ' /proc/net/arp | grep -c -F "$IP"` + if [ $proxy_entries -gt 0 ]; then + return $OCF_SUCCESS + else + return $OCF_GENERIC_ERROR + fi +} + +proxy_arp_installed() { + check_binary $IP2UTIL + + if ocf_is_true "$OCF_RESKEY_arp_insist"; then + check_binary $SENDARP + elif ! have_binary $SENDARP; then + ocf_log warn "$SENDARP not found - gratuitous arp will not work" + fi +} + +proxy_arp_start() { + if [ -z "$NIC" ] || [ -z "$IP" ]; then + return $OCF_ERR_CONFIGURED + fi + + proxy_arp_monitor + if [ $? -eq $OCF_SUCCESS ]; then + return $OCF_SUCCESS + fi + + proxy_arp_installed + ha_pseudo_resource "${OCF_RESOURCE_INSTANCE}" start + + add_proxy_arp $IP $NIC + if [ $? -ne $OCF_SUCCESS ]; then + ocf_log err "$CMD failed." + return $OCF_ERR_GENERIC + fi + + # the proxy arp entry is inserted synchronously, so it should have been + # inserted successfully at this point + proxy_arp_monitor + if [ $? -ne $OCF_SUCCESS ]; then + return $OCF_ERR_GENERIC + fi + + run_send_arp + if [ $? -ne $OCF_SUCCESS ] && ocf_is_true "$OCF_RESKEY_arp_insist"; then + # gratuitous arp failed - but we insist it should succeed + return $OCF_ERR_GENERIC + fi + + return $OCF_SUCCESS +} + +proxy_arp_stop() { + proxy_arp_monitor + if [ $? -eq $OCF_NOT_RUNNING ]; then + return $OCF_SUCCESS + fi + + if [ -f "$SENDARPPIDFILE" ] ; then + kill `cat "$SENDARPPIDFILE"` + if [ $? -ne 0 ]; then + ocf_log warn "Could not kill previously running send_arp for $IP" + else + ocf_log info "killed previously running send_arp for $IP" + rm -f "$SENDARPPIDFILE" + fi + fi + + remove_proxy_arp $IP $NIC + proxy_arp_monitor + if [ $? -ne $OCF_ERR_GENERIC ]; then + ocf_log err "Removal of proxy arp entry for $IP failed" + return $OCF_ERR_GENERIC + fi + + ha_pseudo_resource "${OCF_RESOURCE_INSTANCE}" stop + return $OCF_SUCCESS +} + +proxy_arp_validate() { + proxy_arp_init + + if ocf_is_decimal "$OCF_RESKEY_arp_interval" && [ $OCF_RESKEY_arp_interval -gt 0 ]; then + : + else + ocf_log err "Invalid OCF_RESKEY_arp_interval [$OCF_RESKEY_arp_interval]" + exit $OCF_ERR_CONFIGURED + fi + + if ocf_is_decimal "$OCF_RESKEY_arp_count" && [ $OCF_RESKEY_arp_count -gt 0 ]; then + : + else + ocf_log err "Invalid OCF_RESKEY_arp_count [$OCF_RESKEY_arp_count]" + exit $OCF_ERR_CONFIGURED + fi +} + +case $__OCF_ACTION in +meta-data) meta_data + ;; +usage|help) proxy_arp_usage + exit $OCF_SUCCESS + ;; +esac + +proxy_arp_validate + +case $__OCF_ACTION in +start) proxy_arp_start + ;; +stop) proxy_arp_stop + ;; +monitor) proxy_arp_monitor + ;; +validate-all) proxy_arp_installed + ;; +*) proxy_arp_usage + exit $OCF_ERR_UNIMPLEMENTED + ;; +esac -- 1.7.9.2 _______________________________________________________ Linux-HA-Dev: [email protected] http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev Home Page: http://linux-ha.org/
