summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2016-07-04 18:45:24 +0200
committerantirez <antirez@gmail.com>2016-07-04 18:50:40 +0200
commit026f9fc7b066b155bf07c58676da41b0f4e70853 (patch)
treebc131c04aa923a4d19c80aca9e93ffbdd9ccfbad
parent11523b3e0e53dd56c1caac39865bba4c7615aaa7 (diff)
downloadredis-026f9fc7b066b155bf07c58676da41b0f4e70853.tar.gz
Sentinel: fix cross-master Sentinel address update.
This commit both fixes the crash reported with issue #3364 and also properly closes the old links after the Sentinel address for the other masters gets updated. The two problems where: 1. The Sentinel that switched address may not monitor all the masters, it is possible that there is no match, and the 'match' variable is NULL. Now we check for no match and 'continue' to the next master. 2. By ispecting the code because of issue "1" I noticed that there was a problem in the code that disconnects the link of the Sentinel that needs the address update. Basically link->disconnected is non-zero even if just *a single link* (cc -- command link or pc -- pubsub link) are disconnected, so to check with if (link->disconnected) in order to close the links risks to leave one link connected. I was able to manually reproduce the crash at "1" and verify that the commit resolves the issue. Close #3364.
-rw-r--r--src/sentinel.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/src/sentinel.c b/src/sentinel.c
index f8ebd0c6f..baf6f9cbd 100644
--- a/src/sentinel.c
+++ b/src/sentinel.c
@@ -1062,11 +1062,18 @@ int sentinelUpdateSentinelAddressInAllMasters(sentinelRedisInstance *ri) {
sentinelRedisInstance *master = dictGetVal(de), *match;
match = getSentinelRedisInstanceByAddrAndRunID(master->sentinels,
NULL,0,ri->runid);
- if (match->link->disconnected == 0) {
+ /* If there is no match, this master does not know about this
+ * Sentinel, try with the next one. */
+ if (match == NULL) continue;
+
+ /* Disconnect the old links if connected. */
+ if (match->link->cc != NULL)
instanceLinkCloseConnection(match->link,match->link->cc);
+ if (match->link->pc != NULL)
instanceLinkCloseConnection(match->link,match->link->pc);
- }
+
if (match == ri) continue; /* Address already updated for it. */
+
/* Update the address of the matching Sentinel by copying the address
* of the Sentinel object that received the address update. */
releaseSentinelAddr(match->addr);