Blame SOURCES/bz1189187-redis-agent.patch

5c69fb
From d83b9a9394ef69ca2801c84dee46094a224ca654 Mon Sep 17 00:00:00 2001
5c69fb
From: David Vossel <dvossel@redhat.com>
5c69fb
Date: Thu, 5 Mar 2015 13:47:58 -0600
5c69fb
Subject: [PATCH] redis agent support
5c69fb
5c69fb
---
5c69fb
 doc/man/Makefile.am   |   1 +
5c69fb
 heartbeat/Makefile.am |   1 +
5c69fb
 heartbeat/redis       | 519 ++++++++++++++++++++++++++++++++++++++++++++++++++
5c69fb
 3 files changed, 521 insertions(+)
5c69fb
 create mode 100644 heartbeat/redis
5c69fb
5c69fb
diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am
5c69fb
index 43d60d9..653e818 100644
5c69fb
--- a/doc/man/Makefile.am
5c69fb
+++ b/doc/man/Makefile.am
5c69fb
@@ -125,6 +125,7 @@ man_MANS	       = ocf_heartbeat_AoEtarget.7 \
5c69fb
                           ocf_heartbeat_pound.7 \
5c69fb
                           ocf_heartbeat_proftpd.7 \
5c69fb
                           ocf_heartbeat_rabbitmq-cluster.7 \
5c69fb
+                          ocf_heartbeat_redis.7 \
5c69fb
                           ocf_heartbeat_rsyncd.7 \
5c69fb
                           ocf_heartbeat_rsyslog.7 \
5c69fb
                           ocf_heartbeat_scsi2reservation.7 \
5c69fb
diff --git a/heartbeat/Makefile.am b/heartbeat/Makefile.am
5c69fb
index 3bcf2d9..e4ed4fd 100644
5c69fb
--- a/heartbeat/Makefile.am
5c69fb
+++ b/heartbeat/Makefile.am
5c69fb
@@ -105,6 +105,7 @@ ocf_SCRIPTS	     =  ClusterMon		\
5c69fb
 			rabbitmq-cluster	\
5c69fb
 			Raid1			\
5c69fb
 			Route			\
5c69fb
+			redis			\
5c69fb
 			rsyncd			\
5c69fb
 			rsyslog			\
5c69fb
 			SAPDatabase		\
5c69fb
diff --git a/heartbeat/redis b/heartbeat/redis
5c69fb
new file mode 100644
5c69fb
index 0000000..6b479b2
5c69fb
--- /dev/null
5c69fb
+++ b/heartbeat/redis
5c69fb
@@ -0,0 +1,519 @@
5c69fb
+#!/bin/bash
5c69fb
+
5c69fb
+. ${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs
5c69fb
+
5c69fb
+: ${OCF_RESKEY_bin:=/usr/bin/redis-server}
5c69fb
+: ${OCF_RESKEY_client_bin:=/usr/bin/redis-cli}
5c69fb
+: ${OCF_RESKEY_user:=redis}
5c69fb
+: ${OCF_RESKEY_rundir:=/var/run/redis}
5c69fb
+: ${OCF_RESKEY_pidfile_name:=redis-server.pid}
5c69fb
+: ${OCF_RESKEY_socket_name:=redis.sock}
5c69fb
+: ${OCF_RESKEY_port:=6379}
5c69fb
+
5c69fb
+if [ -z "$OCF_RESKEY_config" ]; then
5c69fb
+	if [ -f "/etc/redis.conf" ]; then
5c69fb
+		OCF_RESKEY_config="/etc/redis.conf"
5c69fb
+	else
5c69fb
+		OCF_RESKEY_config="/etc/redis/redis.conf"
5c69fb
+	fi
5c69fb
+fi
5c69fb
+
5c69fb
+CHECK_SLAVE_STATE=0
5c69fb
+
5c69fb
+REDIS_SERVER="$OCF_RESKEY_bin"
5c69fb
+REDIS_CLIENT="$OCF_RESKEY_client_bin"
5c69fb
+REDIS_CONFIG="$OCF_RESKEY_config"
5c69fb
+REDIS_USER="$OCF_RESKEY_user"
5c69fb
+REDIS_RUNDIR="$OCF_RESKEY_rundir"
5c69fb
+REDIS_PIDFILE="$OCF_RESKEY_rundir/$OCF_RESKEY_pidfile_name"
5c69fb
+REDIS_SOCKET="$OCF_RESKEY_rundir/$OCF_RESKEY_socket_name"
5c69fb
+REDIS_REPLICATION_PORT="$OCF_RESKEY_port"
5c69fb
+
5c69fb
+function meta_data() {
5c69fb
+	cat <
5c69fb
+
5c69fb
+
5c69fb
+<resource-agent name="redis">
5c69fb
+<version>1.0</version>
5c69fb
+
5c69fb
+<longdesc lang="en">
5c69fb
+Resource agent script for redis server. 
5c69fb
+
5c69fb
+This resource fully supports master/slave replication. The master preference of a node is determined by the 'slave_priority' parameter of the redis config.
5c69fb
+When taking the resource from 'unmanaged' to 'managed', the currently active master will be given a priority of 1000 (plus 1 for each active connection). The default 'slave_priority' is 100, so the master will stay master. For a slave to become master after converting the resource to managed, set a slave_priority greater than 1000.
5c69fb
+</longdesc>
5c69fb
+
5c69fb
+<shortdesc lang="en">Redis server</shortdesc>
5c69fb
+
5c69fb
+<parameters>
5c69fb
+<parameter name="bin" unique="0" required="0">
5c69fb
+<longdesc lang="en">
5c69fb
+Path to \`redis-server\`
5c69fb
+</longdesc>
5c69fb
+<shortdesc lang="en">Path to \`redis-server\`</shortdesc>
5c69fb
+<content type="string" default="${OCF_RESKEY_bin}" />
5c69fb
+</parameter>
5c69fb
+
5c69fb
+<parameter name="client_bin" unique="0" required="0">
5c69fb
+<longdesc lang="en">
5c69fb
+Path to \`redis-cli\`
5c69fb
+</longdesc>
5c69fb
+<shortdesc lang="en">Path to \`redis-cli\`</shortdesc>
5c69fb
+<content type="string" default="${OCF_RESKEY_client_bin}" />
5c69fb
+</parameter>
5c69fb
+
5c69fb
+<parameter name="config" unique="1" required="0">
5c69fb
+<longdesc lang="en">
5c69fb
+Path to 'redis.conf'
5c69fb
+</longdesc>
5c69fb
+<shortdesc lang="en">Path to 'redis.conf'</shortdesc>
5c69fb
+<content type="string" default="${OCF_RESKEY_config}" />
5c69fb
+</parameter>
5c69fb
+
5c69fb
+<parameter name="user" unique="0" required="0">
5c69fb
+<longdesc lang="en">
5c69fb
+User to run redis as
5c69fb
+</longdesc>
5c69fb
+<shortdesc lang="en">Redis user</shortdesc>
5c69fb
+<content type="string" default="${OCF_RESKEY_user}" />
5c69fb
+</parameter>
5c69fb
+
5c69fb
+<parameter name="rundir" unique="1" required="0">
5c69fb
+<longdesc lang="en">
5c69fb
+Directory to store socket and pid file in
5c69fb
+</longdesc>
5c69fb
+<shortdesc lang="en">Redis var/run dir</shortdesc>
5c69fb
+<content type="string" default="${OCF_RESKEY_rundir}"/>
5c69fb
+</parameter>
5c69fb
+
5c69fb
+<parameter name="pidfile_name" unique="0" required="0">
5c69fb
+<longdesc lang="en">
5c69fb
+The filename to use for the pidfile. Will be created in the rundir. 
5c69fb
+Should only be a basename, not a full path.
5c69fb
+</longdesc>
5c69fb
+<shortdesc lang="en">Redis pidfile name</shortdesc>
5c69fb
+<content type="string" default="${OCF_RESKEY_pidfile_name}"/>
5c69fb
+</parameter>
5c69fb
+
5c69fb
+<parameter name="socket_name" unique="0" required="0">
5c69fb
+<longdesc lang="en">
5c69fb
+The filename to use for the socket. Will be crated in the rundir. 
5c69fb
+Should only be a basename, not a full path.
5c69fb
+</longdesc>
5c69fb
+<shortdesc lang="en">Redis socket name</shortdesc>
5c69fb
+<content type="string" default="${OCF_RESKEY_socket_name}"/>
5c69fb
+</parameter>
5c69fb
+
5c69fb
+<parameter name="port" unique="0" required="0">
5c69fb
+<longdesc lang="en">
5c69fb
+Port for replication client to connect to on remote server
5c69fb
+</longdesc>
5c69fb
+<shortdesc lang="en">Replication port</shortdesc>
5c69fb
+<content type="string" default="${OCF_RESKEY_port}"/>
5c69fb
+</parameter>
5c69fb
+
5c69fb
+<parameter name="wait_last_known_master" unique="0" required="0">
5c69fb
+<longdesc lang="en">
5c69fb
+During redis cluster bootstrap, wait for the last known master to be
5c69fb
+promoted before allowing any other instances in the cluster to be
5c69fb
+promoted. This lessens the risk of data loss when persistent data
5c69fb
+is in use.
5c69fb
+</longdesc>
5c69fb
+<shortdesc lang="en">Wait for last known master</shortdesc>
5c69fb
+<content type="boolean" default="false"/>
5c69fb
+</parameter>
5c69fb
+</parameters>
5c69fb
+
5c69fb
+<actions>
5c69fb
+<action name="start" timeout="120" />
5c69fb
+<action name="stop" timeout="120" />
5c69fb
+<action name="status" timeout="60" />
5c69fb
+<action name="monitor" depth="0" timeout="60" interval="45" />
5c69fb
+<action name="monitor" role="Master" depth="0" timeout="60" interval="20" />
5c69fb
+<action name="monitor" role="Slave" depth="0" timeout="60" interval="60" />
5c69fb
+<action name="promote" timeout="120" />
5c69fb
+<action name="demote" timeout="120" />
5c69fb
+<action name="notify" timeout="90" />
5c69fb
+<action name="validate-all" timeout="5" />
5c69fb
+<action name="meta-data" timeout="5" />
5c69fb
+</actions>
5c69fb
+</resource-agent>
5c69fb
+EOI
5c69fb
+}
5c69fb
+
5c69fb
+INSTANCE_ATTR_NAME=`echo ${OCF_RESOURCE_INSTANCE}| awk -F : '{print $1}'`
5c69fb
+CRM_ATTR_REPL_INFO="${HA_SBIN_DIR}/crm_attribute --type crm_config --name ${INSTANCE_ATTR_NAME}_REPL_INFO -s redis_replication"
5c69fb
+MASTER_HOST=""
5c69fb
+MASTER_ACTIVE_CACHED=""
5c69fb
+MASTER_ACTIVE=""
5c69fb
+
5c69fb
+master_is_active()
5c69fb
+{
5c69fb
+	if [ -z "$MASTER_ACTIVE_CACHED" ]; then
5c69fb
+		# determine if a master instance is already up and is healthy
5c69fb
+		crm_mon --as-xml | grep "resource.*id=\"${OCF_RESOURCE_INSTANCE}\".*role=\"Master\".*active=\"true\".*orphaned=\"false\".*failed=\"false\"" > /dev/null 2>&1
5c69fb
+		MASTER_ACTIVE=$?
5c69fb
+		MASTER_ACTIVE_CACHED="true"
5c69fb
+	fi
5c69fb
+	return $MASTER_ACTIVE
5c69fb
+}
5c69fb
+
5c69fb
+function set_master()
5c69fb
+{
5c69fb
+	MASTER_HOST="$1"
5c69fb
+	${CRM_ATTR_REPL_INFO} -v "$1" -q
5c69fb
+}
5c69fb
+
5c69fb
+function last_known_master()
5c69fb
+{
5c69fb
+	if [ -z "$MASTER_HOST" ]; then
5c69fb
+		MASTER_HOST="$(${CRM_ATTR_REPL_INFO} --query  -q  2>/dev/null)"
5c69fb
+	fi
5c69fb
+	echo "$MASTER_HOST"
5c69fb
+}
5c69fb
+
5c69fb
+function crm_master_reboot() {
5c69fb
+	"${HA_SBIN_DIR}/crm_master" -l reboot "$@"
5c69fb
+}
5c69fb
+
5c69fb
+function calculate_score()
5c69fb
+{
5c69fb
+	perf_score="$1"
5c69fb
+	connected_clients="$2"
5c69fb
+
5c69fb
+    	if ocf_is_true "$OCF_RESKEY_wait_last_known_master"; then
5c69fb
+		# only set perferred score by slave_priority if
5c69fb
+		# we are not waiting for the last known master. Otherwise
5c69fb
+		# we want the agent to have complete control over the scoring.
5c69fb
+		perf_score=""
5c69fb
+		connected_clients="0"
5c69fb
+	fi
5c69fb
+
5c69fb
+	if [[ -z "$perf_score" ]]; then
5c69fb
+		if [[ "$(last_known_master)" == "$NODENAME" ]]; then
5c69fb
+			perf_score=1000
5c69fb
+		else
5c69fb
+			perf_score=1
5c69fb
+		fi
5c69fb
+	fi
5c69fb
+	perf_score=$(( perf_score + connected_clients ))
5c69fb
+	echo "$perf_score"
5c69fb
+}
5c69fb
+
5c69fb
+function set_score()
5c69fb
+{
5c69fb
+	local score="$1"
5c69fb
+
5c69fb
+    	if ocf_is_true "$OCF_RESKEY_wait_last_known_master" && ! master_is_active; then
5c69fb
+		local last_master="$(last_known_master)"
5c69fb
+		if [ -n "$last_master" ] && [[ "$last_master" != "$NODENAME" ]]; then
5c69fb
+			ocf_log info "Postponing setting master score for ${NODENAME} until last known master instance [${last_master}] is promoted"
5c69fb
+			return
5c69fb
+		fi
5c69fb
+	fi
5c69fb
+
5c69fb
+	ocf_log debug "monitor: Setting master score to '$score'"
5c69fb
+	crm_master_reboot -v "$score"
5c69fb
+}
5c69fb
+
5c69fb
+function redis_client() {
5c69fb
+	ocf_log debug "redis_client: '$REDIS_CLIENT' -s '$REDIS_SOCKET' $@"
5c69fb
+	"$REDIS_CLIENT" -s "$REDIS_SOCKET" "$@" | sed 's/\r//'
5c69fb
+}
5c69fb
+
5c69fb
+function simple_status() {
5c69fb
+	local pid
5c69fb
+
5c69fb
+	if ! [ -f "$REDIS_PIDFILE" ]; then
5c69fb
+		return $OCF_NOT_RUNNING
5c69fb
+	fi
5c69fb
+
5c69fb
+	pid="$(<"$REDIS_PIDFILE")"
5c69fb
+	pidof "$REDIS_SERVER" | grep -q "\<$pid\>" || return $OCF_NOT_RUNNING
5c69fb
+
5c69fb
+	ocf_log debug "monitor: redis-server running under pid $pid"
5c69fb
+
5c69fb
+	return $OCF_SUCCESS
5c69fb
+}
5c69fb
+
5c69fb
+function monitor() {
5c69fb
+	local res
5c69fb
+
5c69fb
+	simple_status
5c69fb
+	res=$?
5c69fb
+	if (( res != OCF_SUCCESS )); then
5c69fb
+		return $res
5c69fb
+	fi
5c69fb
+
5c69fb
+	typeset -A info
5c69fb
+	while read line; do
5c69fb
+		[[ "$line" == "#"* ]] && continue
5c69fb
+		[[ "$line" != *":"* ]] && continue
5c69fb
+		IFS=':' read -r key value <<< "$line"
5c69fb
+		info[$key]="$value"
5c69fb
+	done < <(redis_client info)
5c69fb
+	if [[ -z "${info[role]}" ]]; then
5c69fb
+		ocf_log err "monitor: Could not get role from \`$REDIS_CLIENT -s $REDIS_SOCKET info\`"
5c69fb
+		return $OCF_ERR_GENERIC
5c69fb
+	fi
5c69fb
+
5c69fb
+	if ocf_is_ms; then
5c69fb
+		# Here we see if a score has already been set.
5c69fb
+		# If score isn't set we the redis setting 'slave_priority'.
5c69fb
+		# If that isn't set, we default to 1000 for a master, and 1 for slave.
5c69fb
+		# We then add 1 for each connected client
5c69fb
+		score="$(crm_master_reboot --get-value --quiet 2>/dev/null)"
5c69fb
+		if [[ -z "$score" ]]; then
5c69fb
+			score=$(calculate_score "${info[slave_priority]}" "${info[connected_clients]}")
5c69fb
+			set_score "$score"
5c69fb
+		fi
5c69fb
+
5c69fb
+		if [[ "${info[role]}" == "master" ]]; then
5c69fb
+			if ocf_is_probe; then
5c69fb
+				set_master "$NODENAME"
5c69fb
+			fi
5c69fb
+			return $OCF_RUNNING_MASTER
5c69fb
+		fi
5c69fb
+
5c69fb
+		if [ "$CHECK_SLAVE_STATE" -eq 1 ]; then
5c69fb
+			if [[ "${info[master_link_status]}" != "up" ]]; then
5c69fb
+				ocf_log info "monitor: Slave mode link has not yet been established (link=${info[master_link_status]})"
5c69fb
+				return $OCF_ERR_GENERIC
5c69fb
+			fi
5c69fb
+			if [[ "${info[master_host]}" != "$(last_known_master)" ]]; then
5c69fb
+				ocf_log err "monitor: Slave mode current master does not match running master. current=${info[master_host]}, running=$(last_known_master)"
5c69fb
+				return $OCF_ERR_GENERIC
5c69fb
+			fi
5c69fb
+		fi
5c69fb
+	fi
5c69fb
+	return $OCF_SUCCESS
5c69fb
+}
5c69fb
+
5c69fb
+function start() {
5c69fb
+	monitor
5c69fb
+	status=$?
5c69fb
+
5c69fb
+	if (( status == OCF_SUCCESS )) || (( status == OCF_RUNNING_MASTER )); then
5c69fb
+		ocf_log info "start: redis is already running"
5c69fb
+		return $OCF_SUCCESS
5c69fb
+	fi
5c69fb
+
5c69fb
+	[[ ! -d "$REDIS_RUNDIR" ]] && mkdir -p "$REDIS_RUNDIR"
5c69fb
+	chown -R "$REDIS_USER" "$REDIS_RUNDIR"
5c69fb
+
5c69fb
+	ocf_log info "start: $REDIS_SERVER --daemonize yes --unixsocket '$REDIS_SOCKET' --pidfile '$REDIS_PIDFILE'"
5c69fb
+	output="$(su "$REDIS_USER" -s /bin/sh -c "cd '$REDIS_RUNDIR'; exec '$REDIS_SERVER' '$REDIS_CONFIG' --daemonize yes --unixsocket '$REDIS_SOCKET' --pidfile '$REDIS_PIDFILE'" 2>&1)"
5c69fb
+
5c69fb
+	while true; do
5c69fb
+		# wait for redis to start
5c69fb
+		typeset -A info
5c69fb
+		while read line; do
5c69fb
+			[[ "$line" == "#"* ]] && continue
5c69fb
+			[[ "$line" != *":"* ]] && continue
5c69fb
+			IFS=':' read -r key value <<< "$line"
5c69fb
+			info[$key]="$value"
5c69fb
+		done < <(redis_client info)
5c69fb
+
5c69fb
+		if (( info[loading] == 0 )); then
5c69fb
+			break
5c69fb
+		elif (( info[loading] == 1 )); then
5c69fb
+			sleep "${info[loading_eta_seconds]}"
5c69fb
+		elif pidof "$REDIS_SERVER" >/dev/null; then
5c69fb
+			# unknown error, but the process still exists.
5c69fb
+			# This check is mainly because redis daemonizes before it starts listening, causing `redis-cli` to fail
5c69fb
+			#   See https://github.com/antirez/redis/issues/2368
5c69fb
+			# It's possible that the `pidof` will pick up a different redis, but in that case, the start operation will just time out
5c69fb
+			sleep 1
5c69fb
+		else
5c69fb
+			ocf_log err "start: Unknown error waiting for redis to start"
5c69fb
+			return $OCF_ERR_GENERIC
5c69fb
+		fi
5c69fb
+	done
5c69fb
+
5c69fb
+	ocf_is_ms && demote # pacemaker expects resources to start in slave mode
5c69fb
+
5c69fb
+	monitor
5c69fb
+	status=$?
5c69fb
+	if (( status == OCF_SUCCESS )) || (( status == OCF_RUNNING_MASTER )); then
5c69fb
+		return $OCF_SUCCESS
5c69fb
+	fi
5c69fb
+
5c69fb
+	ocf_log err "start: Unknown error starting redis. output=${output//$'\n'/; }"
5c69fb
+	return $status
5c69fb
+}
5c69fb
+
5c69fb
+function stop() {
5c69fb
+	monitor
5c69fb
+	status=$?
5c69fb
+
5c69fb
+	if (( status == OCF_NOT_RUNNING )); then
5c69fb
+		ocf_log info "stop: redis is already stopped"
5c69fb
+		crm_master_reboot -D
5c69fb
+		return $OCF_SUCCESS
5c69fb
+	fi
5c69fb
+
5c69fb
+	pid="$(<"$REDIS_PIDFILE")"
5c69fb
+	kill -TERM "$pid"
5c69fb
+
5c69fb
+	while true; do
5c69fb
+		simple_status
5c69fb
+		status=$?
5c69fb
+		if (( status == OCF_NOT_RUNNING )); then
5c69fb
+			crm_master_reboot -D
5c69fb
+			return $OCF_SUCCESS
5c69fb
+		fi
5c69fb
+		sleep 1
5c69fb
+	done
5c69fb
+}
5c69fb
+
5c69fb
+function promote() {
5c69fb
+	monitor
5c69fb
+	status=$?
5c69fb
+
5c69fb
+	if (( status == OCF_RUNNING_MASTER )); then
5c69fb
+		ocf_log info "promote: Already running as master"
5c69fb
+		set_master "$NODENAME"
5c69fb
+		return $OCF_SUCCESS
5c69fb
+	elif (( status != OCF_SUCCESS )); then
5c69fb
+		ocf_log err "promote: Node is not running as a slave"
5c69fb
+		return $OCF_ERR_GENERIC
5c69fb
+	fi
5c69fb
+
5c69fb
+	redis_client slaveof no one
5c69fb
+
5c69fb
+	monitor
5c69fb
+	status=$?
5c69fb
+	if (( status == OCF_RUNNING_MASTER )); then
5c69fb
+		set_master "$NODENAME"
5c69fb
+		return $OCF_SUCCESS
5c69fb
+	fi
5c69fb
+
5c69fb
+	ocf_log err "promote: Unknown error while promoting to master (status=$status)"
5c69fb
+	return $OCF_ERR_GENERIC
5c69fb
+}
5c69fb
+
5c69fb
+function demote() {
5c69fb
+	local master_host
5c69fb
+	local master_port
5c69fb
+
5c69fb
+	CHECK_SLAVE_STATE=1
5c69fb
+	monitor
5c69fb
+	status=$?
5c69fb
+
5c69fb
+	if (( status == OCF_SUCCESS )); then
5c69fb
+		ocf_log info "demote: Already running as slave"
5c69fb
+		return $OCF_SUCCESS
5c69fb
+	elif (( status == OCF_NOT_RUNNING )); then
5c69fb
+		ocf_log err "demote: Failed to demote, redis not running."
5c69fb
+		return $OCF_NOT_RUNNING
5c69fb
+	fi
5c69fb
+
5c69fb
+	master_host="$(last_known_master)"
5c69fb
+	master_port="${REDIS_REPLICATION_PORT}"
5c69fb
+
5c69fb
+	# The elected master has to remain a slave during startup.
5c69fb
+	# During this period a placeholder master host is assigned.
5c69fb
+	if [ -z "$master_host" ] || [[ "$master_host" == "$NODENAME" ]]; then
5c69fb
+		CHECK_SLAVE_STATE=0
5c69fb
+		master_host="no-such-master"
5c69fb
+	elif ! master_is_active; then
5c69fb
+		# no master has been promoted yet. we'll be notified when the
5c69fb
+		# master starts.
5c69fb
+		CHECK_SLAVE_STATE=0
5c69fb
+		master_host="no-such-master"
5c69fb
+	fi
5c69fb
+
5c69fb
+	ocf_log info "demote: Setting master to '$master_host'"
5c69fb
+
5c69fb
+	redis_client slaveof "$master_host" "$master_port"
5c69fb
+
5c69fb
+	# wait briefly for the slave to connect to the master	
5c69fb
+	for (( c=1; c <= 20; c++ ))
5c69fb
+	do
5c69fb
+		monitor
5c69fb
+		status=$?
5c69fb
+		if (( status == OCF_SUCCESS )); then
5c69fb
+			return $OCF_SUCCESS
5c69fb
+		fi
5c69fb
+		sleep 1
5c69fb
+	done
5c69fb
+
5c69fb
+	ocf_log err "demote: Unexpected error setting slave mode (status=$status)"
5c69fb
+	return $OCF_ERR_GENERIC
5c69fb
+}
5c69fb
+
5c69fb
+function notify() {
5c69fb
+	mode="${OCF_RESKEY_CRM_meta_notify_type}-${OCF_RESKEY_CRM_meta_notify_operation}"
5c69fb
+	case "$mode" in
5c69fb
+		post-demote|post-promote) # change the master
5c69fb
+			monitor
5c69fb
+			status=$?
5c69fb
+			if (( status == OCF_SUCCESS )); then # were a slave
5c69fb
+				# calling demote updates the slave's connection
5c69fb
+				# to the newly appointed Master instance.
5c69fb
+				demote
5c69fb
+			fi
5c69fb
+			;;
5c69fb
+	esac
5c69fb
+	return $OCF_SUCCESS
5c69fb
+}
5c69fb
+
5c69fb
+function validate() {
5c69fb
+	if [[ -x "$REDIS_SERVER" ]]; then
5c69fb
+		ocf_log err "validate: $REDIS_SERVER does not exist or is not executable"
5c69fb
+		return $OCF_ERR_INSTALLED
5c69fb
+	fi
5c69fb
+	if [[ -x "$REDIS_CLIENT" ]]; then
5c69fb
+		ocf_log err "validate: $REDIS_CLIENT does not exist or is not executable"
5c69fb
+		return $OCF_ERR_INSTALLED
5c69fb
+	fi
5c69fb
+	if [[ -f "$REDIS_CONFIG" ]]; then
5c69fb
+		ocf_log err "validate: $REDIS_CONFIG does not exist"
5c69fb
+		return $OCF_ERR_CONFIGURED
5c69fb
+	fi
5c69fb
+	if !  getent passwd "$REDIS_USER" &>/dev/null; then
5c69fb
+		ocf_log err "validate: $REDIS_USER is not a valid user"
5c69fb
+		return $OCF_ERR_CONFIGURED
5c69fb
+	fi
5c69fb
+}
5c69fb
+
5c69fb
+NODENAME=$(ocf_local_nodename)
5c69fb
+
5c69fb
+ocf_log debug "action=${1:-$__OCF_ACTION} notify_type=${OCF_RESKEY_CRM_meta_notify_type} notify_operation=${OCF_RESKEY_CRM_meta_notify_operation} master_host=${OCF_RESKEY_CRM_meta_notify_master_uname} slave_host=${OCF_RESKEY_CRM_meta_notify_slave_uname} promote_host=${OCF_RESKEY_CRM_meta_notify_promote_uname} demote_host=${OCF_RESKEY_CRM_meta_notify_demote_uname}; params: bin=${OCF_RESKEY_bin} client_bin=${OCF_RESKEY_client_bin} config=${OCF_RESKEY_config} user=${OCF_RESKEY_user} rundir=${OCF_RESKEY_rundir} port=${OCF_RESKEY_port}"
5c69fb
+
5c69fb
+case "${1:-$__OCF_ACTION}" in
5c69fb
+	status|monitor)
5c69fb
+		monitor
5c69fb
+		;;
5c69fb
+	start)
5c69fb
+		start
5c69fb
+		;;
5c69fb
+	stop)
5c69fb
+		stop
5c69fb
+		;;
5c69fb
+	restart)
5c69fb
+		stop && start
5c69fb
+		;;
5c69fb
+	promote)
5c69fb
+		promote
5c69fb
+		;;
5c69fb
+	demote)
5c69fb
+		demote
5c69fb
+		;;
5c69fb
+	notify)
5c69fb
+		notify
5c69fb
+		;;
5c69fb
+	meta-data)
5c69fb
+		meta_data
5c69fb
+		;;
5c69fb
+	validate-all)
5c69fb
+		validate
5c69fb
+		;;
5c69fb
+	*)
5c69fb
+		echo "Usage: $0 {monitor|start|stop|restart|promote|demote|notify|validate-all|meta-data}"
5c69fb
+		exit $OCF_ERR_UNIMPLEMENTED
5c69fb
+		;;
5c69fb
+esac
5c69fb
+status=$?
5c69fb
+ocf_log debug "exit_status=$status"
5c69fb
+exit $status
5c69fb
-- 
5c69fb
1.8.4.2
5c69fb