Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

fix bringing up if no master has already been promoted (but two maste…

…rs are already running)
  • Loading branch information...
commit 8358cd14d0a59f748130144600db78f8671f6286 1 parent 5b8a4a2
@michael-dev authored
Showing with 82 additions and 26 deletions.
  1. +82 −26 heartbeat/redis
View
108 heartbeat/redis
@@ -13,7 +13,8 @@
# Marian Marinov,
# Florian Haas: MySQL script
# Martin Walter: rewrite as redis
-# Jose Junior: tweaks to the redis version
+# Jose Junior: tweaks to the redis version
+# Michael Braun: properly bringup as slave (even if no master has already been promoted)
#
# Support: linux-ha@lists.linux-ha.org
# License: GNU General Public License (GPL)
@@ -52,9 +53,11 @@ OCF_RESKEY_user_default=redis
OCF_RESKEY_group_default=redis
OCF_RESKEY_log_default=/var/log/redis/redis-server.log
OCF_RESKEY_pid_default=/var/run/redis.pid
+OCF_RESKEY_tmp_default=/var/run/
: ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}}
-REDIS_SERVER_NAME=${OCF_RESKEY_binary}
+REDIS_SERVER_NAME=${OCF_RESOURCE_INSTANCE}
+: ${REDIS_SERVER_NAME=${OCF_RESKEY_binary}}
: ${OCF_RESKEY_client_binary=${OCF_RESKEY_client_binary_default}}
: ${OCF_RESKEY_config=${OCF_RESKEY_config_default}}
@@ -63,6 +66,7 @@ REDIS_SERVER_NAME=${OCF_RESKEY_binary}
: ${OCF_RESKEY_group=${OCF_RESKEY_group_default}}
: ${OCF_RESKEY_log=${OCF_RESKEY_log_default}}
: ${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}}
+: ${OCF_RESKEY_tmp=${OCF_RESKEY_tmp_default}}
#######################################################################
@@ -162,6 +166,14 @@ The pidfile to be used for redis-server.
<content type="string" default="${OCF_RESKEY_pid_default}"/>
</parameter>
+<parameter name="tmp" unique="0" required="0">
+<longdesc lang="en">
+The tmpdir to be used for pacemaker managing.
+</longdesc>
+<shortdesc lang="en">pacemaker redis tmp file</shortdesc>
+<content type="string" default="${OCF_RESKEY_tmp_default}"/>
+</parameter>
+
</parameters>
<actions>
@@ -195,9 +207,10 @@ read_ms_status() {
local has_slave_role
local master_host
local master_host_value
+ local should_be_slave
tmp=$(mktemp -p $HA_RSCTMP)
- redis-cli info >$tmp
+ $OCF_RESKEY_client_binary -p $OCF_RESKEY_port info >$tmp
if [ $? -ne 0 ]; then
ocf_log info "Could not determine master/slave status";
rm -f $tmp
@@ -213,11 +226,17 @@ read_ms_status() {
master_host_value=$(echo $master_host | cut -d':' -f2 | tr -d " ")
fi
+ test_slave
+ should_be_slave=$?
+
rm -f $tmp
if [ $has_slave_role -eq 0 -a "x$master_host_value" != "x" ]; then
ocf_log info "$REDIS_SERVER_NAME is running (as slave)";
return $OCF_SUCCESS;
+ elif [ $should_be_slave -eq 0 ]; then
+ ocf_log info "$REDIS_SERVER_NAME is running (as master, becoming slave when possible)";
+ return $OCF_SUCCESS;
else
ocf_log info "$REDIS_SERVER_NAME is running (as master)";
return $OCF_RUNNING_MASTER;
@@ -249,19 +268,32 @@ remove_pid() {
rm -f $OCF_RESKEY_pid
}
+mark_slave() {
+ ocf_log info "Mark $OCS_RESOURCE_INSTANCE to be a slave";
+ touch $OCF_RESKEY_tmp/$OCF_RESOURCE_INSTANCE.slave
+}
+
+unmark_slave() {
+ ocf_log info "Mark $OCS_RESOURCE_INSTANCE to be a master";
+ rm -f $OCF_RESKEY_tmp/$OCF_RESOURCE_INSTANCE.slave
+}
+
+test_slave() {
+ [ -e $OCF_RESKEY_tmp/$OCF_RESOURCE_INSTANCE.slave ]
+ return $?
+}
+
set_master() {
local master_host=$1
ocf_log info "Set $REDIS_SERVER_NAME to be a slave of $master_host";
- ocf_run $OCF_RESKEY_client_binary slaveof $master_host $OCF_RESKEY_port
+ ocf_run $OCF_RESKEY_client_binary -p $OCF_RESKEY_port slaveof $master_host $OCF_RESKEY_port
return $?
}
unset_master() {
- local rc
-
ocf_log info "Set $REDIS_SERVER_NAME to become a slave of no one";
- ocf_run $OCF_RESKEY_client_binary slaveof no one
+ ocf_run $OCF_RESKEY_client_binary -p $OCF_RESKEY_port slaveof no one
return $?
}
@@ -330,22 +362,22 @@ redis_start() {
if [ $rc -eq $OCF_RUNNING_MASTER -o $rc -eq $OCF_SUCCESS ]; then
ocf_log info "$REDIS_SERVER_NAME is already running"
- return $OCF_SUCCESS
- fi
-
- touch $OCF_RESKEY_log
- chown $OCF_RESKEY_user:$OCF_RESKEY_group $OCF_RESKEY_log
- chmod 0640 $OCF_RESKEY_log
-
- touch $OCF_RESKEY_pid
- chown $OCF_RESKEY_user:$OCF_RESKEY_group $OCF_RESKEY_pid
-
- start-stop-daemon --start --quiet --umask 007 --pidfile $OCF_RESKEY_pid --make-pidfile --chuid $OCF_RESKEY_user:$OCF_RESKEY_group --exec /usr/local/bin/redis-server -- $OCF_RESKEY_config
- rc=$?
-
- if [ $rc -ne 0 ]; then
- ocf_log err "$OCF_RESKEY_binary start command failed: $rc"
- return $OCF_NOT_RUNNING
+ else
+ touch $OCF_RESKEY_log
+ chown $OCF_RESKEY_user:$OCF_RESKEY_group $OCF_RESKEY_log
+ chmod 0640 $OCF_RESKEY_log
+
+ touch $OCF_RESKEY_pid
+ chown $OCF_RESKEY_user:$OCF_RESKEY_group $OCF_RESKEY_pid
+
+ start-stop-daemon --start --quiet --umask 007 --pidfile $OCF_RESKEY_pid --make-pidfile --chuid $OCF_RESKEY_user:$OCF_RESKEY_group --exec $OCF_RESKEY_binary -- $OCF_RESKEY_config
+ rc=$?
+
+ if [ $rc -ne 0 ]; then
+ ocf_log err "$OCF_RESKEY_binary start command failed: $rc"
+ return $OCF_NOT_RUNNING
+ fi
+ ocf_log info "$REDIS_SERVER_NAME started"
fi
if ocf_is_ms; then
@@ -356,7 +388,7 @@ redis_start() {
if [ ! -z "$master_host" -a "$master_host" != $(uname -n) ]; then
ocf_log info "Changing redis configuration to replicate from host: $master_host"
while true; do
- $OCF_RESKEY_client_binary info |grep 'loading:0'
+ $OCF_RESKEY_client_binary -p $OCF_RESKEY_port info |grep 'loading:0'
if [ $? -eq 0 ]; then
break
else
@@ -366,6 +398,7 @@ redis_start() {
done
set_master $master_host
fi
+ mark_slave
# We also need to set a master preference, otherwise Pacemaker
# won't ever promote us in the absence of any explicit
@@ -374,7 +407,6 @@ redis_start() {
$CRM_MASTER -v 1
fi
- ocf_log info "$REDIS_SERVER_NAME started"
return $OCF_SUCCESS
}
@@ -404,6 +436,7 @@ redis_stop() {
ocf_log info "$REDIS_SERVER_NAME stopped";
remove_pid
+ unmark_slave
return $OCF_SUCCESS
}
@@ -417,6 +450,9 @@ redis_promote() {
return $OCF_NOT_RUNNING
fi
+ unmark_slave
+ unset_master
+
# Existing master gets a higher-than-default master preference, so
# the cluster manager does not shuffle the master role around
# unnecessarily
@@ -427,6 +463,7 @@ redis_promote() {
redis_demote() {
local rc
+ local master_host
redis_status
rc=$?
@@ -435,6 +472,25 @@ redis_demote() {
return $OCF_NOT_RUNNING
fi
+ # Now, let's see whether there is a master. We might be a new
+ # node that is just joining the cluster, and the CRM may have
+ # promoted a master before.
+ master_host=$(echo $OCF_RESKEY_CRM_meta_notify_master_uname | tr -d " ")
+ if [ ! -z "$master_host" -a "$master_host" != $(uname -n) ]; then
+ ocf_log info "Changing redis configuration to replicate from host: $master_host"
+ while true; do
+ $OCF_RESKEY_client_binary -p $OCF_RESKEY_port info |grep 'loading:0'
+ if [ $? -eq 0 ]; then
+ break
+ else
+ ocf_log err "Redis still loading data, giving it a second to finish"
+ sleep 1
+ fi
+ done
+ set_master $master_host
+ fi
+ mark_slave
+
# Return master preference to default, so the cluster manager gets
# a chance to select a new master
$CRM_MASTER -v 1
@@ -542,4 +598,4 @@ rc=$?
# The resource agent may optionally log a debug message
ocf_log debug "${OCF_RESOURCE_INSTANCE} $__OCF_ACTION returned $rc"
-exit $rc
+exit $rc
Please sign in to comment.
Something went wrong with that request. Please try again.