summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cluster.c12
-rw-r--r--src/cluster.h2
2 files changed, 12 insertions, 2 deletions
diff --git a/src/cluster.c b/src/cluster.c
index 604110f68..faa0eebc0 100644
--- a/src/cluster.c
+++ b/src/cluster.c
@@ -1896,6 +1896,10 @@ void clusterRequestFailoverAuth(void) {
uint32_t totlen;
clusterBuildMessageHdr(hdr,CLUSTERMSG_TYPE_FAILOVER_AUTH_REQUEST);
+ /* If this is a manual failover, set the CLUSTERMSG_FLAG0_FORCEACK bit
+ * in the header to communicate the nodes receiving the message that
+ * they should authorized the failover even if the master is working. */
+ if (server.cluster->mf_end) hdr->mflags[0] |= CLUSTERMSG_FLAG0_FORCEACK;
totlen = sizeof(clusterMsg)-sizeof(union clusterMsgData);
hdr->totlen = htonl(totlen);
clusterBroadcastMessage(buf,totlen);
@@ -1933,6 +1937,7 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) {
uint64_t requestCurrentEpoch = ntohu64(request->currentEpoch);
uint64_t requestConfigEpoch = ntohu64(request->configEpoch);
unsigned char *claimed_slots = request->myslots;
+ int force_ack = request->mflags[0] & CLUSTERMSG_FLAG0_FORCEACK;
int j;
/* IF we are not a master serving at least 1 slot, we don't have the
@@ -1947,8 +1952,11 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) {
/* I already voted for this epoch? Return ASAP. */
if (server.cluster->last_vote_epoch == server.cluster->currentEpoch) return;
- /* Node must be a slave and its master down. */
- if (nodeIsMaster(node) || master == NULL || !nodeFailed(master)) return;
+ /* Node must be a slave and its master down.
+ * The master can be non failing if the request is flagged
+ * with CLUSTERMSG_FLAG0_FORCEACK (manual failover). */
+ if (nodeIsMaster(node) || master == NULL ||
+ (!nodeFailed(master) && !force_ack)) return;
/* We did not voted for a slave about this master for two
* times the node timeout. This is not strictly needed for correctness
diff --git a/src/cluster.h b/src/cluster.h
index 52edbf780..cbda08987 100644
--- a/src/cluster.h
+++ b/src/cluster.h
@@ -220,6 +220,8 @@ typedef struct {
/* Message flags better specify the packet content or are used to
* provide some information about the node state. */
#define CLUSTERMSG_FLAG0_PAUSED (1<<0) /* Master paused for manual failover. */
+#define CLUSTERMSG_FLAG0_FORCEACK (1<<1) /* Give ACK to AUTH_REQUEST even if
+ master is up. */
/* ---------------------- API exported outside cluster.c -------------------- */
clusterNode *getNodeByQuery(redisClient *c, struct redisCommand *cmd, robj **argv, int argc, int *hashslot, int *ask);