]> git.saurik.com Git - redis.git/commitdiff
slave with attached slaves now close the conection to all the slaves when the connect...
authorantirez <antirez@gmail.com>
Tue, 24 Aug 2010 14:04:13 +0000 (16:04 +0200)
committerantirez <antirez@gmail.com>
Tue, 24 Aug 2010 14:04:13 +0000 (16:04 +0200)
src/networking.c
src/replication.c

index 10b9580ee45430fc0024b6b5b33ccf2a8a77b7ed..a39be7c4ea8b81ead00a145cdc7a2dcec516d9c7 100644 (file)
@@ -255,7 +255,8 @@ void freeClient(redisClient *c) {
         server.vm_blocked_clients--;
     }
     listRelease(c->io_keys);
         server.vm_blocked_clients--;
     }
     listRelease(c->io_keys);
-    /* Master/slave cleanup */
+    /* Master/slave cleanup.
+     * Case 1: we lost the connection with a slave. */
     if (c->flags & REDIS_SLAVE) {
         if (c->replstate == REDIS_REPL_SEND_BULK && c->repldbfd != -1)
             close(c->repldbfd);
     if (c->flags & REDIS_SLAVE) {
         if (c->replstate == REDIS_REPL_SEND_BULK && c->repldbfd != -1)
             close(c->repldbfd);
@@ -264,9 +265,20 @@ void freeClient(redisClient *c) {
         redisAssert(ln != NULL);
         listDelNode(l,ln);
     }
         redisAssert(ln != NULL);
         listDelNode(l,ln);
     }
+
+    /* Case 2: we lost the connection with the master. */
     if (c->flags & REDIS_MASTER) {
         server.master = NULL;
         server.replstate = REDIS_REPL_CONNECT;
     if (c->flags & REDIS_MASTER) {
         server.master = NULL;
         server.replstate = REDIS_REPL_CONNECT;
+        /* Since we lost the connection with the master, we should also
+         * close the connection with all our slaves if we have any, so
+         * when we'll resync with the master the other slaves will sync again
+         * with us as well. Note that also when the slave is not connected
+         * to the master it will keep refusing connections by other slaves. */
+        while (listLength(server.slaves)) {
+            ln = listFirst(server.slaves);
+            freeClient((redisClient*)ln->value);
+        }
     }
     /* Release memory */
     zfree(c->argv);
     }
     /* Release memory */
     zfree(c->argv);
index 5387db913cc39719bc820a0d066e0c326fc6fca5..8937582019fe367d5809aeea3065b1476411af1b 100644 (file)
@@ -176,6 +176,13 @@ void syncCommand(redisClient *c) {
     /* ignore SYNC if aleady slave or in monitor mode */
     if (c->flags & REDIS_SLAVE) return;
 
     /* ignore SYNC if aleady slave or in monitor mode */
     if (c->flags & REDIS_SLAVE) return;
 
+    /* Refuse SYNC requests if we are a slave but the link with our master
+     * is not ok... */
+    if (server.masterhost && server.replstate != REDIS_REPL_CONNECTED) {
+        addReplySds(c,sdsnew("-ERR Can't SYNC while not connected with my master\r\n"));
+        return;
+    }
+
     /* SYNC can't be issued when the server has pending data to send to
      * the client about already issued commands. We need a fresh reply
      * buffer registering the differences between the BGSAVE and the current
     /* SYNC can't be issued when the server has pending data to send to
      * the client about already issued commands. We need a fresh reply
      * buffer registering the differences between the BGSAVE and the current
@@ -392,7 +399,12 @@ int syncWithMaster(void) {
             strerror(errno));
         return REDIS_ERR;
     }
             strerror(errno));
         return REDIS_ERR;
     }
-    if (buf[0] != '$') {
+    if (buf[0] == '-') {
+        close(fd);
+        redisLog(REDIS_WARNING,"MASTER aborted replication with an error: %s",
+            buf+1);
+        return REDIS_ERR;
+    } else if (buf[0] != '$') {
         close(fd);
         redisLog(REDIS_WARNING,"Bad protocol from MASTER, the first byte is not '$', are you sure the host and port are right?");
         return REDIS_ERR;
         close(fd);
         redisLog(REDIS_WARNING,"Bad protocol from MASTER, the first byte is not '$', are you sure the host and port are right?");
         return REDIS_ERR;