From e15e518a674ce75ada1badb3e4fe11c18c255016 Mon Sep 17 00:00:00 2001
From: antirez <antirez@gmail.com>
Date: Fri, 8 Jan 2016 15:04:16 +0100
Subject: [PATCH] Allow MIGRATE to always be called on local keys for open
 slots.

Extend the MIGRATE extra freedom to be able to be called in the context
of the local slot, anytime there is a slot open in one or the other
direction (importing or migrating). This is useful for redis-trib to fix
the cluster when it has in an odd state.

Thix fix allows "redis-trib fix" to make its work in certain cases where
previously an error was reported.
---
 src/cluster.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/src/cluster.c b/src/cluster.c
index 2f798dda..c0a79d9f 100644
--- a/src/cluster.c
+++ b/src/cluster.c
@@ -4989,14 +4989,15 @@ clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, in
     /* Return the hashslot by reference. */
     if (hashslot) *hashslot = slot;
 
-    /* This request is about a slot we are migrating into another instance?
-     * Then if we have all the keys. */
+    /* MIGRATE always works in the context of the local node if the slot
+     * is open (migrating or importing state). We need to be able to freely
+     * move keys among instances in this case. */
+    if ((migrating_slot || importing_slot) && cmd->proc == migrateCommand)
+        return myself;
 
     /* If we don't have all the keys and we are migrating the slot, send
-     * an ASK redirection. With the exception of the MIGRATE command, that
-     * should just ignore non existing keys when moving keys from a node
-     * to another. */
-    if (migrating_slot && missing_keys && cmd->proc != migrateCommand) {
+     * an ASK redirection. */
+    if (migrating_slot && missing_keys) {
         if (error_code) *error_code = CLUSTER_REDIR_ASK;
         return server.cluster->migrating_slots_to[slot];
     }