Permalink
Browse files

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

…rs are already running)
  • Loading branch information...
1 parent 5b8a4a2 commit 8358cd14d0a59f748130144600db78f8671f6286 @michael-dev committed Aug 30, 2012
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

0 comments on commit 8358cd1

Please sign in to comment.