Commit 27abaa23 authored by antirez's avatar antirez
Browse files

Undo slave-master handshake when SLAVEOF sets a new slave.

Issue #828 shows how Redis was not correctly undoing a non-blocking
connection attempt with the previous master when the master was set to a
new address using the SLAVEOF command.

This was also a result of lack of refactoring, so now there is a
function to cancel the non blocking handshake with the master.
The new function is now used when SLAVEOF NO ONE is called or when
SLAVEOF is used to set the master to a different address.
parent 78b175a2
...@@ -695,6 +695,27 @@ void undoConnectWithMaster(void) { ...@@ -695,6 +695,27 @@ void undoConnectWithMaster(void) {
server.repl_state = REDIS_REPL_CONNECT; server.repl_state = REDIS_REPL_CONNECT;
} }
/* This function aborts a non blocking replication attempt if there is one
* in progress, by canceling the non-blocking connect attempt or
* the initial bulk transfer.
*
* If there was a replication handshake in progress 1 is returned and
* the replication state (server.repl_state) set to REDIS_REPL_CONNECT.
*
* Otherwise zero is returned and no operation is perforemd at all. */
int cancelReplicationHandshake(void) {
if (server.repl_state == REDIS_REPL_TRANSFER) {
replicationAbortSyncTransfer();
} else if (server.repl_state == REDIS_REPL_CONNECTING ||
server.repl_state == REDIS_REPL_RECEIVE_PONG)
{
undoConnectWithMaster();
} else {
return 0;
}
return 1;
}
void slaveofCommand(redisClient *c) { void slaveofCommand(redisClient *c) {
if (!strcasecmp(c->argv[1]->ptr,"no") && if (!strcasecmp(c->argv[1]->ptr,"no") &&
!strcasecmp(c->argv[2]->ptr,"one")) { !strcasecmp(c->argv[2]->ptr,"one")) {
...@@ -702,11 +723,7 @@ void slaveofCommand(redisClient *c) { ...@@ -702,11 +723,7 @@ void slaveofCommand(redisClient *c) {
sdsfree(server.masterhost); sdsfree(server.masterhost);
server.masterhost = NULL; server.masterhost = NULL;
if (server.master) freeClient(server.master); if (server.master) freeClient(server.master);
if (server.repl_state == REDIS_REPL_TRANSFER) cancelReplicationHandshake();
replicationAbortSyncTransfer();
else if (server.repl_state == REDIS_REPL_CONNECTING ||
server.repl_state == REDIS_REPL_RECEIVE_PONG)
undoConnectWithMaster();
server.repl_state = REDIS_REPL_NONE; server.repl_state = REDIS_REPL_NONE;
redisLog(REDIS_NOTICE,"MASTER MODE enabled (user request)"); redisLog(REDIS_NOTICE,"MASTER MODE enabled (user request)");
} }
...@@ -730,8 +747,7 @@ void slaveofCommand(redisClient *c) { ...@@ -730,8 +747,7 @@ void slaveofCommand(redisClient *c) {
server.masterport = port; server.masterport = port;
if (server.master) freeClient(server.master); if (server.master) freeClient(server.master);
disconnectSlaves(); /* Force our slaves to resync with us as well. */ disconnectSlaves(); /* Force our slaves to resync with us as well. */
if (server.repl_state == REDIS_REPL_TRANSFER) cancelReplicationHandshake();
replicationAbortSyncTransfer();
server.repl_state = REDIS_REPL_CONNECT; server.repl_state = REDIS_REPL_CONNECT;
redisLog(REDIS_NOTICE,"SLAVE OF %s:%d enabled (user request)", redisLog(REDIS_NOTICE,"SLAVE OF %s:%d enabled (user request)",
server.masterhost, server.masterport); server.masterhost, server.masterport);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment