summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOran Agra <oran@redislabs.com>2022-02-08 19:10:13 +0200
committerOran Agra <oran@redislabs.com>2022-04-27 16:31:52 +0300
commita06f10b009610d5d60c98305329a788c4a545b82 (patch)
tree95ae179cd4be5774a35bb3a120a13d22cdb1b50e
parent0a26869a1331dff01643f457e83a1edc2a94b6c9 (diff)
downloadredis-a06f10b009610d5d60c98305329a788c4a545b82.tar.gz
Attempt to fix a rare crash in cluster tests. (#10265)
The theory is that a replica gets disconnected from within REPLCONF ACK, so when we go up the stack, we'll crash when attempting to access c->cmd->flags (cherry picked from commit aa9beaca7727993d7d996348ea1fe9699b0fd90a)
-rw-r--r--src/replication.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/src/replication.c b/src/replication.c
index 9228a247f..7d1929e0a 100644
--- a/src/replication.c
+++ b/src/replication.c
@@ -1305,6 +1305,9 @@ void updateSlavesWaitingBgsave(int bgsaveerr, int type) {
listNode *ln;
listIter li;
+ /* Note: there's a chance we got here from within the REPLCONF ACK command
+ * so we must avoid using freeClient, otherwise we'll crash on our way up. */
+
listRewind(server.slaves,&li);
while((ln = listNext(&li))) {
client *slave = ln->value;
@@ -1313,7 +1316,7 @@ void updateSlavesWaitingBgsave(int bgsaveerr, int type) {
struct redis_stat buf;
if (bgsaveerr != C_OK) {
- freeClient(slave);
+ freeClientAsync(slave);
serverLog(LL_WARNING,"SYNC failed. BGSAVE child returned an error");
continue;
}
@@ -1358,7 +1361,7 @@ void updateSlavesWaitingBgsave(int bgsaveerr, int type) {
} else {
if ((slave->repldbfd = open(server.rdb_filename,O_RDONLY)) == -1 ||
redis_fstat(slave->repldbfd,&buf) == -1) {
- freeClient(slave);
+ freeClientAsync(slave);
serverLog(LL_WARNING,"SYNC failed. Can't open/stat DB after BGSAVE: %s", strerror(errno));
continue;
}
@@ -1370,7 +1373,7 @@ void updateSlavesWaitingBgsave(int bgsaveerr, int type) {
connSetWriteHandler(slave->conn,NULL);
if (connSetWriteHandler(slave->conn,sendBulkToSlave) == C_ERR) {
- freeClient(slave);
+ freeClientAsync(slave);
continue;
}
}