| 5068 | } |
| 5069 | |
| 5070 | static int clusterManagerCommandDeleteNode(int argc, char **argv) { |
| 5071 | UNUSED(argc); |
| 5072 | int success = 1; |
| 5073 | int port = 0; |
| 5074 | char *ip = NULL; |
| 5075 | if (!getClusterHostFromCmdArgs(1, argv, &ip, &port)) goto invalid_args; |
| 5076 | char *node_id = argv[1]; |
| 5077 | clusterManagerLogInfo(">>> Removing node %s from cluster %s:%d\n", |
| 5078 | node_id, ip, port); |
| 5079 | clusterManagerNode *ref_node = clusterManagerNewNode(ip, port); |
| 5080 | clusterManagerNode *node = NULL; |
| 5081 | |
| 5082 | // Load cluster information |
| 5083 | if (!clusterManagerLoadInfoFromNode(ref_node, 0)) return 0; |
| 5084 | |
| 5085 | // Check if the node exists and is not empty |
| 5086 | node = clusterManagerNodeByName(node_id); |
| 5087 | if (node == NULL) { |
| 5088 | clusterManagerLogErr("[ERR] No such node ID %s\n", node_id); |
| 5089 | return 0; |
| 5090 | } |
| 5091 | if (node->slots_count != 0) { |
| 5092 | clusterManagerLogErr("[ERR] Node %s:%d is not empty! Reshard data " |
| 5093 | "away and try again.\n", node->ip, node->port); |
| 5094 | return 0; |
| 5095 | } |
| 5096 | |
| 5097 | // Send CLUSTER FORGET to all the nodes but the node to remove |
| 5098 | clusterManagerLogInfo(">>> Sending CLUSTER FORGET messages to the " |
| 5099 | "cluster...\n"); |
| 5100 | listIter li; |
| 5101 | listNode *ln; |
| 5102 | listRewind(cluster_manager.nodes, &li); |
| 5103 | while ((ln = listNext(&li)) != NULL) { |
| 5104 | clusterManagerNode *n = ln->value; |
| 5105 | if (n == node) continue; |
| 5106 | if (n->replicate && !strcasecmp(n->replicate, node_id)) { |
| 5107 | // Reconfigure the slave to replicate with some other node |
| 5108 | clusterManagerNode *master = clusterManagerNodeWithLeastReplicas(); |
| 5109 | assert(master != NULL); |
| 5110 | clusterManagerLogInfo(">>> %s:%d as replica of %s:%d\n", |
| 5111 | n->ip, n->port, master->ip, master->port); |
| 5112 | redisReply *r = CLUSTER_MANAGER_COMMAND(n, "CLUSTER REPLICATE %s", |
| 5113 | master->name); |
| 5114 | success = clusterManagerCheckRedisReply(n, r, NULL); |
| 5115 | if (r) freeReplyObject(r); |
| 5116 | if (!success) return 0; |
| 5117 | } |
| 5118 | redisReply *r = CLUSTER_MANAGER_COMMAND(n, "CLUSTER FORGET %s", |
| 5119 | node_id); |
| 5120 | success = clusterManagerCheckRedisReply(n, r, NULL); |
| 5121 | if (r) freeReplyObject(r); |
| 5122 | if (!success) return 0; |
| 5123 | } |
| 5124 | |
| 5125 | /* Finally send CLUSTER RESET to the node. */ |
| 5126 | clusterManagerLogInfo(">>> Sending CLUSTER RESET SOFT to the " |
| 5127 | "deleted node.\n"); |
nothing calls this directly
no test coverage detected