From c982683ac8c2de64f69c5f47727242c65e00df90 Mon Sep 17 00:00:00 2001
From: David Vossel <dvossel@redhat.com>
Date: Mon, 29 Jun 2015 13:07:14 -0500
Subject: [PATCH 2/3] bz1231032-redis-update.patch
---
heartbeat/redis | 51 ++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 46 insertions(+), 5 deletions(-)
diff --git a/heartbeat/redis b/heartbeat/redis
index 6b479b2..b63a2b9 100644
--- a/heartbeat/redis
+++ b/heartbeat/redis
@@ -20,6 +20,7 @@ fi
CHECK_SLAVE_STATE=0
+REDIS_CHECK_DUMP="/usr/bin/redis-check-dump"
REDIS_SERVER="$OCF_RESKEY_bin"
REDIS_CLIENT="$OCF_RESKEY_client_bin"
REDIS_CONFIG="$OCF_RESKEY_config"
@@ -29,6 +30,17 @@ REDIS_PIDFILE="$OCF_RESKEY_rundir/$OCF_RESKEY_pidfile_name"
REDIS_SOCKET="$OCF_RESKEY_rundir/$OCF_RESKEY_socket_name"
REDIS_REPLICATION_PORT="$OCF_RESKEY_port"
+if ! [ -f $REDIS_CHECK_DUMP ]; then
+ REDIS_CHECK_DUMP="$(which redis-check-dump 2>/dev/null)"
+fi
+
+if [ -f "$REDIS_CONFIG" ]; then
+ REDIS_DUMP_DIR="$(cat $REDIS_CONFIG | grep "^\s*dir\s" | awk '{ print $2 }' 2>/dev/null)"
+ REDIS_DUMP_FILE="$(cat $REDIS_CONFIG | grep "^\s*dbfilename\s" | awk '{ print $2 }' 2>/dev/null)"
+fi
+: ${REDIS_DUMP_DIR:=/var/lib/redis/}
+: ${REDIS_DUMP_FILE:=dump.rdb}
+
function meta_data() {
cat <<EOI
<?xml version="1.0"?>
@@ -289,6 +301,14 @@ function monitor() {
return $OCF_SUCCESS
}
+function check_dump_file()
+{
+ if ! have_binary "$REDIS_CHECK_DUMP"; then
+ return 0
+ fi
+ $REDIS_CHECK_DUMP ${REDIS_DUMP_DIR}/${REDIS_DUMP_FILE} 2>&1
+}
+
function start() {
monitor
status=$?
@@ -301,6 +321,16 @@ function start() {
[[ ! -d "$REDIS_RUNDIR" ]] && mkdir -p "$REDIS_RUNDIR"
chown -R "$REDIS_USER" "$REDIS_RUNDIR"
+ # check for 0 byte database dump file. This is an unrecoverable start
+ # condition that we can avoid by deleting the 0 byte database file.
+ if [ -f "${REDIS_DUMP_DIR}/${REDIS_DUMP_FILE}" ]; then
+ local size="$(stat --format "%s" ${REDIS_DUMP_DIR}/${REDIS_DUMP_FILE})"
+ if [ "$?" -eq "0" ] && [ "$size" -eq "0" ]; then
+ ocf_log notice "Detected 0 byte ${REDIS_DUMP_FILE}, deleting zero length file to avoid start failure."
+ rm -f ${REDIS_DUMP_DIR}/${REDIS_DUMP_FILE}
+ fi
+ fi
+
ocf_log info "start: $REDIS_SERVER --daemonize yes --unixsocket '$REDIS_SOCKET' --pidfile '$REDIS_PIDFILE'"
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)"
@@ -325,7 +355,8 @@ function start() {
# It's possible that the `pidof` will pick up a different redis, but in that case, the start operation will just time out
sleep 1
else
- ocf_log err "start: Unknown error waiting for redis to start"
+ check_output="$(check_dump_file)"
+ ocf_log err "start: Unknown error waiting for redis to start. redis-check-dump output=${check_output//$'\n'/; }"
return $OCF_ERR_GENERIC
fi
done
@@ -338,7 +369,8 @@ function start() {
return $OCF_SUCCESS
fi
- ocf_log err "start: Unknown error starting redis. output=${output//$'\n'/; }"
+ check_output="$(check_dump_file)"
+ ocf_log err "start: Unknown error starting redis. redis-server output=${output//$'\n'/; } redis-check-dump output=${check_output//$'\n'/; }"
return $status
}
@@ -427,14 +459,23 @@ function demote() {
redis_client slaveof "$master_host" "$master_port"
- # wait briefly for the slave to connect to the master
- for (( c=1; c <= 20; c++ ))
- do
+ # Wait forever for the slave to connect to the master and finish the
+ # sync. Timeout is controlled by Pacemaker "op start timeout=XX".
+ #
+ # hint: redis master_link_status will only come "up" when
+ # the SYNC with the master has completed.
+ # This can take an arbitraty time (data) and should
+ # only be parametrized by the start operation timeout
+ # by the administrator, not by this resource agent code
+ while true; do
+ # Wait infinite if replication is syncing
+ # Then start/demote operation timeout determines timeout
monitor
status=$?
if (( status == OCF_SUCCESS )); then
return $OCF_SUCCESS
fi
+
sleep 1
done
--
1.8.4.2