summaryrefslogtreecommitdiffstats
path: root/heartbeat/conntrackd.in
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--heartbeat/conntrackd.in335
1 files changed, 335 insertions, 0 deletions
diff --git a/heartbeat/conntrackd.in b/heartbeat/conntrackd.in
new file mode 100644
index 0000000..1c2ee95
--- /dev/null
+++ b/heartbeat/conntrackd.in
@@ -0,0 +1,335 @@
+#!@BASH_SHELL@
+#
+#
+# An OCF RA for conntrackd
+# http://conntrack-tools.netfilter.org/
+#
+# Copyright (c) 2011 Dominik Klein
+#
+# 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.
+#
+
+#######################################################################
+# Initialization:
+
+: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
+. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
+
+#######################################################################
+
+OCF_RESKEY_binary_default=conntrackd
+OCF_RESKEY_config_default=/etc/conntrackd/conntrackd.conf
+
+# For users of versions prior to 1.2:
+# Map renamed parameter "conntrackd" to "binary" if in use
+: ${OCF_RESKEY_binary=${OCF_RESKEY_conntrackd-${OCF_RESKEY_binary_default}}}
+: ${OCF_RESKEY_config=${OCF_RESKEY_config_default}}
+
+meta_data() {
+ cat <<END
+<?xml version="1.0"?>
+<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
+<resource-agent name="conntrackd" version="1.2">
+<version>1.0</version>
+
+<longdesc lang="en">
+Promotable OCF Resource Agent for conntrackd
+</longdesc>
+
+<shortdesc lang="en">This resource agent manages conntrackd</shortdesc>
+
+<parameters>
+<parameter name="binary">
+<longdesc lang="en">Name of the conntrackd executable.
+If conntrackd is installed and available in the default PATH, it is sufficient to configure the name of the binary
+For example "my-conntrackd-binary-version-0.9.14"
+If conntrackd is installed somewhere else, you may also give a full path
+For example "/packages/conntrackd-0.9.14/sbin/conntrackd"
+</longdesc>
+<shortdesc lang="en">Name of the conntrackd executable</shortdesc>
+<content type="string" default="$OCF_RESKEY_binary_default"/>
+</parameter>
+
+<parameter name="config">
+<longdesc lang="en">Full path to the conntrackd.conf file.
+For example "/packages/conntrackd-0.9.14/etc/conntrackd/conntrackd.conf"</longdesc>
+<shortdesc lang="en">Path to conntrackd.conf</shortdesc>
+<content type="string" default="$OCF_RESKEY_config_default"/>
+</parameter>
+</parameters>
+
+<actions>
+<action name="start" timeout="30s" />
+<action name="promote" timeout="30s" />
+<action name="demote" timeout="30s" />
+<action name="notify" timeout="30s" />
+<action name="stop" timeout="30s" />
+<action name="monitor" timeout="20s" interval="20s" role="Unpromoted" />
+<action name="monitor" timeout="20s" interval="10s" role="Promoted" />
+<action name="meta-data" timeout="5s" />
+<action name="validate-all" timeout="30s" />
+</actions>
+</resource-agent>
+END
+}
+
+meta_expect_eq()
+{
+ local what=$1 whatvar=OCF_RESKEY_CRM_meta_${1//-/_} expect=$2
+ local val=${!whatvar}
+ if [[ -n $val ]]; then
+ # [, not [[, or it won't work ;)
+ [ $val = $expect ] && return
+ fi
+ ocf_exit_reason "meta parameter misconfigured, expected $what $op $expect, but found ${val:-unset}."
+ exit $OCF_ERR_CONFIGURED
+}
+
+conntrackd_is_master() {
+ # You can't query conntrackd whether it is master or slave. It can be both at the same time.
+ # This RA creates a statefile during promote and enforces master-max=1 and clone-node-max=1
+ ha_pseudo_resource $statefile monitor
+}
+
+conntrackd_set_master_score() {
+ ${HA_SBIN_DIR}/crm_master -Q -l reboot -v $1
+}
+
+conntrackd_monitor() {
+ rc=$OCF_NOT_RUNNING
+ # It does not write a PID file, so check the socket exists after
+ # extracting its path from the configuration file
+ local conntrack_socket=$(awk '/^[ \t]*UNIX[ \t]*{/,/^[ \t]*}/ { if ($1 == "Path") { print $2 } }' $OCF_RESKEY_config)
+ [ -S "$conntrack_socket" ] && rc=$OCF_SUCCESS
+ if [ "$rc" -eq "$OCF_SUCCESS" ]; then
+ # conntrackd is running
+ # now see if it acceppts queries
+ if ! $OCF_RESKEY_binary -C $OCF_RESKEY_config -s > /dev/null 2>&1; then
+ rc=$OCF_ERR_GENERIC
+ ocf_exit_reason "conntrackd is running but not responding to queries"
+ fi
+ if conntrackd_is_master; then
+ rc=$OCF_RUNNING_MASTER
+ # Restore master setting on probes
+ if [ $OCF_RESKEY_CRM_meta_interval -eq 0 ]; then
+ conntrackd_set_master_score $master_score
+ fi
+ else
+ # Restore master setting on probes
+ if [ $OCF_RESKEY_CRM_meta_interval -eq 0 ]; then
+ conntrackd_set_master_score $slave_score
+ fi
+ fi
+ fi
+ return $rc
+}
+
+conntrackd_start() {
+ rc=$OCF_ERR_GENERIC
+
+ # Keep trying to start the resource;
+ # wait for the CRM to time us out if this fails
+ while :; do
+ conntrackd_monitor
+ status=$?
+ case "$status" in
+ $OCF_SUCCESS)
+ conntrackd_set_master_score $slave_score
+ # -n = request resync from the others
+ if ! $OCF_RESKEY_binary -C $OCF_RESKEY_config -n; then
+ ocf_exit_reason "$OCF_RESKEY_binary -C $OCF_RESKEY_config -n failed during start."
+ rc=$OCF_ERR_GENERIC
+ else
+ rc=$OCF_SUCCESS
+ fi
+ break
+ ;;
+ $OCF_NOT_RUNNING)
+ ocf_log info "Starting conntrackd"
+ $OCF_RESKEY_binary -C $OCF_RESKEY_config -d
+ ;;
+ $OCF_RUNNING_MASTER)
+ ocf_log warn "conntrackd already in master mode, demoting."
+ ha_pseudo_resource $statefile stop
+ ;;
+ $OCF_ERR_GENERIC)
+ ocf_exit_reason "conntrackd start failed"
+ rc=$OCF_ERR_GENERIC
+ break
+ ;;
+ esac
+ done
+ return $rc
+}
+
+conntrackd_stop() {
+ rc=$OCF_ERR_GENERIC
+
+ # Keep trying to bring down the resource;
+ # wait for the CRM to time us out if this fails
+ while :; do
+ conntrackd_monitor
+ status=$?
+ case "$status" in
+ $OCF_SUCCESS|$OCF_ERR_GENERIC)
+ ocf_log info "Stopping conntrackd"
+ $OCF_RESKEY_binary -C $OCF_RESKEY_config -k
+ ;;
+ $OCF_NOT_RUNNING)
+ rc=$OCF_SUCCESS
+ break
+ ;;
+ $OCF_RUNNING_MASTER)
+ ocf_log warn "conntrackd still master"
+ ;;
+ esac
+ done
+ return $rc
+
+}
+
+conntrackd_validate_all() {
+ check_binary "$OCF_RESKEY_binary"
+ if ! [ -e "$OCF_RESKEY_config" ]; then
+ ocf_exit_reason "Config FILE $OCF_RESKEY_config does not exist"
+ return $OCF_ERR_INSTALLED
+ fi
+ meta_expect_eq master-node-max 1
+ meta_expect_eq master-max 1
+ meta_expect_eq clone-node-max 1
+
+ return $OCF_SUCCESS
+}
+
+conntrackd_promote() {
+ rc=$OCF_SUCCESS
+ if ! conntrackd_is_master; then
+ # -c = Commit the external cache to the kernel
+ # -f = Flush internal and external cache
+ # -R = resync with the kernel table
+ # -B = send a bulk update on the line
+ for parm in c f R B; do
+ if ! $OCF_RESKEY_binary -C $OCF_RESKEY_config -$parm; then
+ ocf_exit_reason "$OCF_RESKEY_binary -C $OCF_RESKEY_config -$parm failed during promote."
+ rc=$OCF_ERR_GENERIC
+ break
+ fi
+ done
+ ha_pseudo_resource $statefile start
+ conntrackd_set_master_score $master_score
+ fi
+ return $rc
+}
+
+conntrackd_demote() {
+ rc=$OCF_SUCCESS
+ if conntrackd_is_master; then
+ # -t = shorten kernel timers to remove zombies
+ # -n = request a resync from the others
+ for parm in t n; do
+ if ! $OCF_RESKEY_binary -C $OCF_RESKEY_config -$parm; then
+ ocf_exit_reason "$OCF_RESKEY_binary -C $OCF_RESKEY_config -$parm failed during demote."
+ rc=$OCF_ERR_GENERIC
+ break
+ fi
+ done
+ ha_pseudo_resource $statefile stop
+ conntrackd_set_master_score $slave_score
+ fi
+ return $rc
+}
+
+conntrackd_notify() {
+ hostname=$(hostname)
+ # OCF_RESKEY_CRM_meta_notify_master_uname is a whitespace separated list of master hostnames
+ for master in $OCF_RESKEY_CRM_meta_notify_master_uname; do
+ # if we are the master and an instance was just started on another node:
+ # send a bulk update to allow failback
+ if [ "$hostname" = "$master" -a "$OCF_RESKEY_CRM_meta_notify_type" = "post" -a "$OCF_RESKEY_CRM_meta_notify_operation" = "start" -a "$OCF_RESKEY_CRM_meta_notify_start_uname" != "$hostname" ]; then
+ ocf_log info "Sending bulk update in post start to peers to allow failback"
+ $OCF_RESKEY_binary -C $OCF_RESKEY_config -B
+ fi
+ done
+ for tobepromoted in $OCF_RESKEY_CRM_meta_notify_promote_uname; do
+ # if there is a promote action to be executed on another node:
+ # send a bulk update to allow failback
+ if [ "$hostname" != "$tobepromoted" -a "$OCF_RESKEY_CRM_meta_notify_type" = "pre" -a "$OCF_RESKEY_CRM_meta_notify_operation" = "promote" ]; then
+ ocf_log info "Sending bulk update in pre promote to peers to allow failback"
+ $OCF_RESKEY_binary -C $OCF_RESKEY_config -B
+ fi
+ done
+}
+
+conntrackd_usage() {
+ cat <<EOF
+usage: $0 {start|stop|promote|demote|monitor|validate-all|meta-data}
+Expects to have a fully populated OCF RA-compliant environment set.
+EOF
+}
+
+statefile=conntrackd.${OCF_RESOURCE_INSTANCE//:[0-9]*}.master
+
+master_score=1000
+slave_score=100
+
+if [ $# -ne 1 ]; then
+ conntrackd_usage
+ exit $OCF_ERR_ARGS
+fi
+
+case $__OCF_ACTION in
+meta-data)
+ meta_data
+ exit $OCF_SUCCESS
+ ;;
+usage)
+ conntrackd_usage
+ exit $OCF_SUCCESS
+esac
+
+# Everything except usage and meta-data must pass the validate test
+conntrackd_validate_all || exit
+
+case $__OCF_ACTION in
+start)
+ conntrackd_start
+ ;;
+stop)
+ conntrackd_stop
+ ;;
+promote)
+ conntrackd_promote
+ ;;
+demote)
+ conntrackd_demote
+ ;;
+status|monitor)
+ conntrackd_monitor
+ ;;
+notify)
+ conntrackd_notify
+ ;;
+validate-all)
+ ;;
+*)
+ conntrackd_usage
+ exit $OCF_ERR_UNIMPLEMENTED
+esac
+# exit code is the exit code (return code) of the last command (shell function)