From c48f49ef69e6a61b2342f07b7b586021ef3a2e83 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Mon, 27 Sep 2021 17:00:23 -0400 Subject: [PATCH 01/79] Add hostname variable --- src/cluster.c | 16 ++++++++++++++++ src/cluster.h | 1 + 2 files changed, 17 insertions(+) diff --git a/src/cluster.c b/src/cluster.c index 87a965d961e..07acbbec96e 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -930,6 +930,22 @@ unsigned int keyHashSlot(char *key, int keylen) { * CLUSTER node API * -------------------------------------------------------------------------- */ +/* Assign a human readable name to nodes for clusters*/ +void setClusterNodeName(clusterNode *node){ + char *name; + int post_digits; + if (node->port == 0){ + post_digits = 0; + } + else{ + floor(log10(abs(node->port))) + 1; + } + int allocate_len = sizeof(node->ip) + post_digits + 2; + name = zmalloc(allocate_len); + sprintf(name, "%s%s%d", node->ip, "_", node->port); + node->hname = name; +} + /* Create a new cluster node, with the specified flags. * If "nodename" is NULL this is considered a first handshake and a random * node name is assigned to this node (it will be fixed later when we'll diff --git a/src/cluster.h b/src/cluster.h index 8b76ed19e9c..40ced7a67ea 100644 --- a/src/cluster.h +++ b/src/cluster.h @@ -115,6 +115,7 @@ typedef struct clusterNodeFailReport { typedef struct clusterNode { mstime_t ctime; /* Node object creation time. */ char name[CLUSTER_NAMELEN]; /* Node name, hex string, sha1-size */ + char* hname; /* Human readable name for node */ int flags; /* CLUSTER_NODE_... */ uint64_t configEpoch; /* Last configEpoch observed for this node */ unsigned char slots[CLUSTER_SLOTS/8]; /* slots handled by this node */ From 6ac7e6543d67d2759771532113dd9e0351566d7a Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Mon, 27 Sep 2021 17:02:18 -0400 Subject: [PATCH 02/79] Update cluster.c --- src/cluster.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cluster.c b/src/cluster.c index 07acbbec96e..c8e925587bc 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -938,7 +938,7 @@ void setClusterNodeName(clusterNode *node){ post_digits = 0; } else{ - floor(log10(abs(node->port))) + 1; + post_digits = floor(log10(abs(node->port))) + 1; } int allocate_len = sizeof(node->ip) + post_digits + 2; name = zmalloc(allocate_len); @@ -1610,6 +1610,7 @@ int clusterStartHandshake(char *ip, int port, int cport) { memcpy(n->ip,norm_ip,sizeof(n->ip)); n->port = port; n->cport = cport; + setClusterNodeName(n); clusterAddNode(n); return 1; } From bd01e10d18e0bc5638a69882d7e034b1e2b48d35 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Mon, 27 Sep 2021 17:04:26 -0400 Subject: [PATCH 03/79] Update cluster.c --- src/cluster.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cluster.c b/src/cluster.c index c8e925587bc..50e8eb97341 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -48,6 +48,7 @@ clusterNode *myself = NULL; clusterNode *createClusterNode(char *nodename, int flags); void clusterAddNode(clusterNode *node); +void setClusterNodeName(clusterNode *node); void clusterAcceptHandler(aeEventLoop *el, int fd, void *privdata, int mask); void clusterReadHandler(connection *conn); void clusterSendPing(clusterLink *link, int type); @@ -1702,6 +1703,7 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { node->pport = ntohs(g->pport); node->cport = ntohs(g->cport); node->flags &= ~CLUSTER_NODE_NOADDR; + setClusterNodeName(node); } } else { /* If it's not in NOADDR state and we don't have it, we @@ -1723,6 +1725,7 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { node->port = ntohs(g->port); node->pport = ntohs(g->pport); node->cport = ntohs(g->cport); + setClusterNodeName(node); clusterAddNode(node); } } @@ -1781,6 +1784,7 @@ int nodeUpdateAddressIfNeeded(clusterNode *node, clusterLink *link, node->port = port; node->pport = pport; node->cport = cport; + setClusterNodeName(node); if (node->link) freeClusterLink(node->link); node->flags &= ~CLUSTER_NODE_NOADDR; serverLog(LL_WARNING,"Address updated for node %.40s, now %s:%d", From 1ade627044c3b0e0f3c40f23e62ead602a176877 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Mon, 27 Sep 2021 17:05:32 -0400 Subject: [PATCH 04/79] Update cluster.c --- src/cluster.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cluster.c b/src/cluster.c index 50e8eb97341..ba9e20b603c 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -2205,6 +2205,7 @@ int clusterProcessPacket(clusterLink *link) { strcmp(ip,myself->ip)) { memcpy(myself->ip,ip,NET_IP_STR_LEN); + setClusterNodeName(myself); serverLog(LL_WARNING,"IP address for this node updated to %s", myself->ip); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG); @@ -2223,6 +2224,7 @@ int clusterProcessPacket(clusterLink *link) { node->port = ntohs(hdr->port); node->pport = ntohs(hdr->pport); node->cport = ntohs(hdr->cport); + setClusterNodeName(node); clusterAddNode(node); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG); } From 6946471d593b5980f83f61cd1c879961e6f6a9c8 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 10:09:24 -0400 Subject: [PATCH 05/79] Update cluster.c --- src/cluster.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/cluster.c b/src/cluster.c index ba9e20b603c..ebe12e35dfd 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -1208,7 +1208,19 @@ clusterNode *clusterLookupNode(const char *name) { de = dictFind(server.cluster->nodes,s); sdsfree(s); - if (de == NULL) return NULL; + if (de == NULL){ + dictIterator *di; + dictEntry *de2; + + di = dictGetSafeIterator(server.cluster->nodes); + while((de2 = dictNext(di)) != NULL) { + clusterNode *node = dictGetVal(de2); + if (strcmp(node->hname,name ) == 0) + return node; + } + dictReleaseIterator(di); + return NULL; + } return dictGetVal(de); } From 3a2912697fbb759e742712e88baf7776c63612b5 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 10:14:18 -0400 Subject: [PATCH 06/79] Update cluster.c --- src/cluster.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index ebe12e35dfd..2bc52b8a42a 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -1215,8 +1215,10 @@ clusterNode *clusterLookupNode(const char *name) { di = dictGetSafeIterator(server.cluster->nodes); while((de2 = dictNext(di)) != NULL) { clusterNode *node = dictGetVal(de2); - if (strcmp(node->hname,name ) == 0) - return node; + if (node->hname){ + if (strcmp(node->hname,name ) == 0) + return node; + } } dictReleaseIterator(di); return NULL; From bc6f455d1f08cf41f06de1827dd08c4dc1420d0a Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 10:32:32 -0400 Subject: [PATCH 07/79] Update cluster.c --- src/cluster.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/cluster.c b/src/cluster.c index 2bc52b8a42a..fbaec857b7b 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -1209,6 +1209,7 @@ clusterNode *clusterLookupNode(const char *name) { de = dictFind(server.cluster->nodes,s); sdsfree(s); if (de == NULL){ + /* Check if any node has the same human readable name*/ dictIterator *di; dictEntry *de2; @@ -4756,6 +4757,10 @@ sds clusterGenNodesDescription(int filter, int use_pport) { if (node->flags & filter) continue; ni = clusterGenNodeDescription(node, use_pport); + + if (node->hname) + ni = sdscatfmt(ni," %s ",node->hname); + ci = sdscatsds(ci,ni); sdsfree(ni); ci = sdscatlen(ci,"\n",1); From 493d38c3291d5daca98091e92d440be19f64c563 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 10:33:55 -0400 Subject: [PATCH 08/79] Update cluster.c --- src/cluster.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index fbaec857b7b..c09ceda5548 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -4757,10 +4757,6 @@ sds clusterGenNodesDescription(int filter, int use_pport) { if (node->flags & filter) continue; ni = clusterGenNodeDescription(node, use_pport); - - if (node->hname) - ni = sdscatfmt(ni," %s ",node->hname); - ci = sdscatsds(ci,ni); sdsfree(ni); ci = sdscatlen(ci,"\n",1); From 8e3b3c066d9b771211aea67e7a49d7e96e61d7d4 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 14:32:35 -0400 Subject: [PATCH 09/79] Check node name --- src/cluster.c | 3 +++ src/help.h | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/src/cluster.c b/src/cluster.c index c09ceda5548..b19f56c8d22 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -5125,6 +5125,9 @@ NULL } else if (!strcasecmp(c->argv[1]->ptr,"myid") && c->argc == 2) { /* CLUSTER MYID */ addReplyBulkCBuffer(c,myself->name, CLUSTER_NAMELEN); + } else if (!strcasecmp(c->argv[1]->ptr,"myname") && c->argc == 2) { + /* CLUSTER MYID */ + addReplyBulkCBuffer(c,myself->hname, sizeof(myself->hname)); } else if (!strcasecmp(c->argv[1]->ptr,"slots") && c->argc == 2) { /* CLUSTER SLOTS */ clusterReplyMultiBulkSlots(c); diff --git a/src/help.h b/src/help.h index e7cd003913c..00638330c97 100644 --- a/src/help.h +++ b/src/help.h @@ -293,6 +293,11 @@ struct commandHelp { "Return the node id", 12, "3.0.0" }, + { "CLUSTER MYNAME", + "", + "Return the node name", + 12, + "3.0.0" }, { "CLUSTER NODES", "", "Get Cluster config for the node", From 28ff415cc9e00c9ae6ecc389602b35750c847b24 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 14:35:38 -0400 Subject: [PATCH 10/79] Update cluster.c --- src/cluster.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cluster.c b/src/cluster.c index b19f56c8d22..fa3de38167a 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -5127,7 +5127,10 @@ NULL addReplyBulkCBuffer(c,myself->name, CLUSTER_NAMELEN); } else if (!strcasecmp(c->argv[1]->ptr,"myname") && c->argc == 2) { /* CLUSTER MYID */ - addReplyBulkCBuffer(c,myself->hname, sizeof(myself->hname)); + if (myself->hname) + addReplyBulkCBuffer(c,myself->hname, sizeof(myself->hname)); + else + addReplyError(c,"Node is not assigned name yet."); } else if (!strcasecmp(c->argv[1]->ptr,"slots") && c->argc == 2) { /* CLUSTER SLOTS */ clusterReplyMultiBulkSlots(c); From 526196dfe3c1c31d08ad39142e44965929309fe6 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 14:37:02 -0400 Subject: [PATCH 11/79] Update cluster.c --- src/cluster.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cluster.c b/src/cluster.c index fa3de38167a..029839f3371 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -5128,7 +5128,7 @@ NULL } else if (!strcasecmp(c->argv[1]->ptr,"myname") && c->argc == 2) { /* CLUSTER MYID */ if (myself->hname) - addReplyBulkCBuffer(c,myself->hname, sizeof(myself->hname)); + addReplyBulkCBuffer(c,myself->hname, strlen(myself->hname)); else addReplyError(c,"Node is not assigned name yet."); } else if (!strcasecmp(c->argv[1]->ptr,"slots") && c->argc == 2) { From 67a5fea673d84463650978b150e2ca88daa7dbe2 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 14:39:39 -0400 Subject: [PATCH 12/79] Add help for nodename --- src/cluster.c | 2 ++ src/help.h | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index 029839f3371..0f85e4efbd9 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -5061,6 +5061,8 @@ void clusterCommand(client *c) { " Connect nodes into a working cluster.", "MYID", " Return the node id.", +"MYNAME", +" Return the node name.", "NODES", " Return cluster configuration seen by node. Output format:", " ...", diff --git a/src/help.h b/src/help.h index 00638330c97..89694109a43 100644 --- a/src/help.h +++ b/src/help.h @@ -293,9 +293,9 @@ struct commandHelp { "Return the node id", 12, "3.0.0" }, - { "CLUSTER MYNAME", + { "CLUSTER MYID", "", - "Return the node name", + "Return the node id", 12, "3.0.0" }, { "CLUSTER NODES", From ae11782b257497f0ef82b32aefd7e5c966eb29e2 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 15:59:46 -0400 Subject: [PATCH 13/79] Update cluster.c --- src/cluster.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cluster.c b/src/cluster.c index 0f85e4efbd9..4cc996a9e8c 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -932,7 +932,7 @@ unsigned int keyHashSlot(char *key, int keylen) { * -------------------------------------------------------------------------- */ /* Assign a human readable name to nodes for clusters*/ -void setClusterNodeName(clusterNode *node){ +void setClusterNodeName(clusterNode *node) { char *name; int post_digits; if (node->port == 0){ From d9ef49da3405e6dfe6fde445e48f5944b6d81249 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 5 Oct 2021 11:21:58 -0400 Subject: [PATCH 14/79] Added support for hname in CLUSTER NODES --- src/cluster.c | 20 ++++++++++---------- src/redis-cli.c | 22 ++++++++++++---------- tests/cluster/cluster.tcl | 17 +++++++++-------- tests/support/cluster.tcl | 4 ++-- 4 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index 4cc996a9e8c..abf4aea88dd 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -220,12 +220,12 @@ int clusterLoadConfig(char *filename) { * ip:port[@cport][,hostname] */ /* Address and port */ - if ((p = strrchr(argv[1],':')) == NULL) { + if ((p = strrchr(argv[offset + 1],':')) == NULL) { sdsfreesplitres(argv,argc); goto fmterr; } *p = '\0'; - memcpy(n->ip,argv[1],strlen(argv[1])+1); + memcpy(n->ip,argv[offset + 1],strlen(argv[offset + 1])+1); char *port = p+1; char *busp = strchr(port,'@'); if (busp) { @@ -254,7 +254,7 @@ int clusterLoadConfig(char *filename) { * stored in nodes.conf. It is received later over the bus protocol. */ /* Parse flags */ - p = s = argv[2]; + p = s = argv[offset + 2]; while(p) { p = strchr(s,','); if (p) *p = '\0'; @@ -287,10 +287,10 @@ int clusterLoadConfig(char *filename) { /* Get master if any. Set the master and populate master's * slave list. */ - if (argv[3][0] != '-') { - master = clusterLookupNode(argv[3]); + if (argv[offset + 3][0] != '-') { + master = clusterLookupNode(argv[offset + 3]); if (!master) { - master = createClusterNode(argv[3],0); + master = createClusterNode(argv[offset + 3],0); clusterAddNode(master); } n->slaveof = master; @@ -298,14 +298,14 @@ int clusterLoadConfig(char *filename) { } /* Set ping sent / pong received timestamps */ - if (atoi(argv[4])) n->ping_sent = mstime(); - if (atoi(argv[5])) n->pong_received = mstime(); + if (atoi(argv[offset + 4])) n->ping_sent = mstime(); + if (atoi(argv[offset + 5])) n->pong_received = mstime(); /* Set configEpoch for this node. */ - n->configEpoch = strtoull(argv[6],NULL,10); + n->configEpoch = strtoull(argv[offset + 6],NULL,10); /* Populate hash slots served by this instance. */ - for (j = 8; j < argc; j++) { + for (j = offset + 8; j < argc; j++) { int start, stop; if (argv[j][0] == '[') { diff --git a/src/redis-cli.c b/src/redis-cli.c index 8ef67f67a9c..25353af3561 100644 --- a/src/redis-cli.c +++ b/src/redis-cli.c @@ -4178,8 +4178,9 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, lines = p + 1; char *name = NULL, *addr = NULL, *flags = NULL, *master_id = NULL, *ping_sent = NULL, *ping_recv = NULL, *config_epoch = NULL, - *link_status = NULL; + *link_status = NULL, *hname = NULL; UNUSED(link_status); + UNUSED(hname); int i = 0; while ((p = strchr(line, ' ')) != NULL) { *p = '\0'; @@ -4187,15 +4188,16 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, line = p + 1; switch(i++){ case 0: name = token; break; - case 1: addr = token; break; - case 2: flags = token; break; - case 3: master_id = token; break; - case 4: ping_sent = token; break; - case 5: ping_recv = token; break; - case 6: config_epoch = token; break; - case 7: link_status = token; break; + case 1: hname = token; break; + case 2: addr = token; break; + case 3: flags = token; break; + case 4: master_id = token; break; + case 5: ping_sent = token; break; + case 6: ping_recv = token; break; + case 7: config_epoch = token; break; + case 8: link_status = token; break; } - if (i == 8) break; // Slots + if (i == 9) break; // Slots } if (!flags) { success = 0; @@ -4207,7 +4209,7 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, node->flags |= CLUSTER_MANAGER_FLAG_MYSELF; currentNode = node; clusterManagerNodeResetSlots(node); - if (i == 8) { + if (i == 9) { int remaining = strlen(line); while (remaining > 0) { p = strchr(line, ' '); diff --git a/tests/cluster/cluster.tcl b/tests/cluster/cluster.tcl index 531e90d6ca4..379db48a5d0 100644 --- a/tests/cluster/cluster.tcl +++ b/tests/cluster/cluster.tcl @@ -18,14 +18,15 @@ proc get_cluster_nodes id { set args [split $l] set node [dict create \ id [lindex $args 0] \ - addr [lindex $args 1] \ - flags [split [lindex $args 2] ,] \ - slaveof [lindex $args 3] \ - ping_sent [lindex $args 4] \ - pong_recv [lindex $args 5] \ - config_epoch [lindex $args 6] \ - linkstate [lindex $args 7] \ - slots [lrange $args 8 end] \ + name [lindex $args 1] \ + addr [lindex $args 2] \ + flags [split [lindex $args 3] ,] \ + slaveof [lindex $args 4] \ + ping_sent [lindex $args 5] \ + pong_recv [lindex $args 6] \ + config_epoch [lindex $args 7] \ + linkstate [lindex $args 8] \ + slots [lrange $args 9 end] \ ] lappend nodes $node } diff --git a/tests/support/cluster.tcl b/tests/support/cluster.tcl index 081ef6a9522..8c628dcd3f1 100644 --- a/tests/support/cluster.tcl +++ b/tests/support/cluster.tcl @@ -104,8 +104,8 @@ proc ::redis_cluster::__method__refresh_nodes_map {id} { set line [string trim $line] if {$line eq {}} continue set args [split $line " "] - lassign $args nodeid addr flags slaveof pingsent pongrecv configepoch linkstate - set slots [lrange $args 8 end] + lassign $args nodeid name addr flags slaveof pingsent pongrecv configepoch linkstate + set slots [lrange $args 9 end] set addr [lindex [split $addr @] 0] if {$addr eq {:0}} { set addr $start_host:$start_port From 67357a6e8d2030f1127e9e42eb460584c213c442 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Mon, 1 Nov 2021 16:23:43 -0400 Subject: [PATCH 15/79] Add gossip and custom name support --- src/cluster.c | 218 ++++++++++++++++++++++---------------- src/cluster.h | 8 +- src/redis-cli.c | 20 ++-- tests/cluster/cluster.tcl | 11 +- tests/support/cluster.tcl | 5 +- 5 files changed, 156 insertions(+), 106 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index abf4aea88dd..e4ac54555d5 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -220,12 +220,12 @@ int clusterLoadConfig(char *filename) { * ip:port[@cport][,hostname] */ /* Address and port */ - if ((p = strrchr(argv[offset + 1],':')) == NULL) { + if ((p = strrchr(argv[1],':')) == NULL) { sdsfreesplitres(argv,argc); goto fmterr; } *p = '\0'; - memcpy(n->ip,argv[offset + 1],strlen(argv[offset + 1])+1); + memcpy(n->ip,argv[1],strlen(argv[1])+1); char *port = p+1; char *busp = strchr(port,'@'); if (busp) { @@ -254,7 +254,7 @@ int clusterLoadConfig(char *filename) { * stored in nodes.conf. It is received later over the bus protocol. */ /* Parse flags */ - p = s = argv[offset + 2]; + p = s = argv[3]; while(p) { p = strchr(s,','); if (p) *p = '\0'; @@ -287,25 +287,28 @@ int clusterLoadConfig(char *filename) { /* Get master if any. Set the master and populate master's * slave list. */ - if (argv[offset + 3][0] != '-') { - master = clusterLookupNode(argv[offset + 3]); + if (argv[4][0] != '-') { + master = clusterLookupNode(argv[4]); if (!master) { - master = createClusterNode(argv[offset + 3],0); + master = createClusterNode(argv[4],0); clusterAddNode(master); } n->slaveof = master; clusterNodeAddSlave(master,n); } + /* Custom nodename */ + n->has_human_readable_name = atoi(argv[5]); + /* Set ping sent / pong received timestamps */ - if (atoi(argv[offset + 4])) n->ping_sent = mstime(); - if (atoi(argv[offset + 5])) n->pong_received = mstime(); + if (atoi(argv[6])) n->ping_sent = mstime(); + if (atoi(argv[7])) n->pong_received = mstime(); /* Set configEpoch for this node. */ - n->configEpoch = strtoull(argv[offset + 6],NULL,10); + n->configEpoch = strtoull(argv[8],NULL,10); /* Populate hash slots served by this instance. */ - for (j = offset + 8; j < argc; j++) { + for (j = 10; j < argc; j++) { int start, stop; if (argv[j][0] == '[') { @@ -359,7 +362,7 @@ int clusterLoadConfig(char *filename) { zfree(line); fclose(fp); - serverLog(LL_NOTICE,"Node configuration loaded, I'm %.40s", myself->name); + serverLog(LL_NOTICE,"Node configuration loaded, I'm %.40s %s", myself->name, myself->human_readable_name); /* Something that should never happen: currentEpoch smaller than * the max epoch found in the nodes configuration. However we handle this @@ -636,8 +639,8 @@ void clusterInit(void) { * by the createClusterNode() function. */ myself = server.cluster->myself = createClusterNode(NULL,CLUSTER_NODE_MYSELF|CLUSTER_NODE_MASTER); - serverLog(LL_NOTICE,"No cluster configuration found, I'm %.40s", - myself->name); + serverLog(LL_NOTICE,"No cluster configuration found, I'm %.40s %s", + myself->name, myself->human_readable_name); clusterAddNode(myself); saveconf = 1; } @@ -744,7 +747,7 @@ void clusterReset(int hard) { sdsfree(oldname); getRandomHexChars(myself->name, CLUSTER_NAMELEN); clusterAddNode(myself); - serverLog(LL_NOTICE,"Node hard reset, now I'm %.40s", myself->name); + serverLog(LL_NOTICE,"Node hard reset, now I'm %.40s %s", myself->name, myself->human_readable_name); } /* Make sure to persist the new config and update the state. */ @@ -933,18 +936,21 @@ unsigned int keyHashSlot(char *key, int keylen) { /* Assign a human readable name to nodes for clusters*/ void setClusterNodeName(clusterNode *node) { - char *name; - int post_digits; - if (node->port == 0){ - post_digits = 0; - } - else{ - post_digits = floor(log10(abs(node->port))) + 1; - } - int allocate_len = sizeof(node->ip) + post_digits + 2; - name = zmalloc(allocate_len); - sprintf(name, "%s%s%d", node->ip, "_", node->port); - node->hname = name; + if (node->has_human_readable_name == 1) + return; + char ip[NET_IP_STR_LEN]; + strcpy(ip,node->ip); + sprintf(node->human_readable_name, "%s_%u", ip,(unsigned int)node->port); +} + +/* Manually assign a human readable name to nodes for clusters*/ +int setManualClusterNodeName(clusterNode *node, char * newname) { + if (newname == NULL) + return 0; + memcpy(node->human_readable_name, newname, strlen(newname) + 1); + node->has_human_readable_name = 1; + clusterSaveConfig(1); + return 1; } /* Create a new cluster node, with the specified flags. @@ -967,6 +973,7 @@ clusterNode *createClusterNode(char *nodename, int flags) { memset(node->slots,0,sizeof(node->slots)); node->slots_info = NULL; node->numslots = 0; + node->has_human_readable_name = 0; node->numslaves = 0; node->slaves = NULL; node->slaveof = NULL; @@ -1208,7 +1215,7 @@ clusterNode *clusterLookupNode(const char *name) { de = dictFind(server.cluster->nodes,s); sdsfree(s); - if (de == NULL){ + if (de == NULL) { /* Check if any node has the same human readable name*/ dictIterator *di; dictEntry *de2; @@ -1216,14 +1223,12 @@ clusterNode *clusterLookupNode(const char *name) { di = dictGetSafeIterator(server.cluster->nodes); while((de2 = dictNext(di)) != NULL) { clusterNode *node = dictGetVal(de2); - if (node->hname){ - if (strcmp(node->hname,name ) == 0) - return node; - } + if (strcmp(node->human_readable_name,name) == 0) + return node; } dictReleaseIterator(di); return NULL; - } + } return dictGetVal(de); } @@ -1381,9 +1386,9 @@ void clusterHandleConfigEpochCollision(clusterNode *sender) { myself->configEpoch = server.cluster->currentEpoch; clusterSaveConfigOrDie(1); serverLog(LL_VERBOSE, - "WARNING: configEpoch collision with node %.40s." + "WARNING: configEpoch collision with node %.40s %s." " configEpoch set to %llu", - sender->name, + sender->name, sender->human_readable_name, (unsigned long long) myself->configEpoch); } @@ -1499,7 +1504,7 @@ void markNodeAsFailingIfNeeded(clusterNode *node) { if (failures < needed_quorum) return; /* No weak agreement from masters. */ serverLog(LL_NOTICE, - "Marking node %.40s as failing (quorum reached).", node->name); + "Marking node %.40s %s as failing (quorum reached).", node->name, node ->human_readable_name); /* Mark the node as failing. */ node->flags &= ~CLUSTER_NODE_PFAIL; @@ -1527,8 +1532,8 @@ void clearNodeFailureIfNeeded(clusterNode *node) { * node again. */ if (nodeIsSlave(node) || node->numslots == 0) { serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s: %s is reachable again.", - node->name, + "Clear FAIL state for node %.40s %s: %s is reachable again.", + node->name, node->human_readable_name, nodeIsSlave(node) ? "replica" : "master without slots"); node->flags &= ~CLUSTER_NODE_FAIL; clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); @@ -1543,8 +1548,8 @@ void clearNodeFailureIfNeeded(clusterNode *node) { (server.cluster_node_timeout * CLUSTER_FAIL_UNDO_TIME_MULT)) { serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s: is reachable again and nobody is serving its slots after some time.", - node->name); + "Clear FAIL state for node %.40s %s: is reachable again and nobody is serving its slots after some time.", + node->name, node->human_readable_name); node->flags &= ~CLUSTER_NODE_FAIL; clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); } @@ -1665,15 +1670,15 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { if (flags & (CLUSTER_NODE_FAIL|CLUSTER_NODE_PFAIL)) { if (clusterNodeAddFailureReport(node,sender)) { serverLog(LL_VERBOSE, - "Node %.40s reported node %.40s as not reachable.", - sender->name, node->name); + "Node %.40s %s reported node %.40s %s as not reachable.", + sender->name, sender->human_readable_name, node->name, node->human_readable_name); } markNodeAsFailingIfNeeded(node); } else { if (clusterNodeDelFailureReport(node,sender)) { serverLog(LL_VERBOSE, - "Node %.40s reported node %.40s is back online.", - sender->name, node->name); + "Node %.40s %s reported node %.40s %s is back online.", + sender->name, sender->human_readable_name, node->name, node->human_readable_name); } } } @@ -1718,7 +1723,10 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { node->pport = ntohs(g->pport); node->cport = ntohs(g->cport); node->flags &= ~CLUSTER_NODE_NOADDR; - setClusterNodeName(node); + if (hdr->has_human_readable_name) + setManualClusterNodeName(node, hdr->human_readable_name); + else + setClusterNodeName(node); } } else { /* If it's not in NOADDR state and we don't have it, we @@ -1740,7 +1748,10 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { node->port = ntohs(g->port); node->pport = ntohs(g->pport); node->cport = ntohs(g->cport); - setClusterNodeName(node); + if (hdr->has_human_readable_name) + setManualClusterNodeName(node, hdr->human_readable_name); + else + setClusterNodeName(node); clusterAddNode(node); } } @@ -1799,11 +1810,14 @@ int nodeUpdateAddressIfNeeded(clusterNode *node, clusterLink *link, node->port = port; node->pport = pport; node->cport = cport; - setClusterNodeName(node); + if (hdr->has_human_readable_name) + setManualClusterNodeName(node, hdr->human_readable_name); + else + setClusterNodeName(node); if (node->link) freeClusterLink(node->link); node->flags &= ~CLUSTER_NODE_NOADDR; - serverLog(LL_WARNING,"Address updated for node %.40s, now %s:%d", - node->name, node->ip, node->port); + serverLog(LL_WARNING,"Address updated for node %.40s %s, now %s:%d", + node->name, node->human_readable_name, node->ip, node->port); /* Check if this is our master and we have to change the * replication target as well. */ @@ -1932,7 +1946,7 @@ void clusterUpdateSlotsConfigWith(clusterNode *sender, uint64_t senderConfigEpoc sender_slots == migrated_our_slots)) { serverLog(LL_WARNING, "Configuration change detected. Reconfiguring myself " - "as a replica of %.40s", sender->name); + "as a replica of %.40s %s", sender->name, sender->human_readable_name); clusterSetMaster(sender); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| CLUSTER_TODO_UPDATE_STATE| @@ -2227,6 +2241,10 @@ int clusterProcessPacket(clusterLink *link) { } } + if (sender && strcmp(sender->human_readable_name,hdr->human_readable_name) != 0) { + strncpy(sender->human_readable_name, hdr->human_readable_name, CLUSTER_HUMAN_NAMELEN); + } + /* Add this node if it is new for us and the msg type is MEET. * In this stage we don't try to add the node with the right * flags, slaveof pointer, and so forth, as this details will be @@ -2267,8 +2285,15 @@ int clusterProcessPacket(clusterLink *link) { * IP/port of the node with the new one. */ if (sender) { serverLog(LL_VERBOSE, - "Handshake: we already know node %.40s, " - "updating the address if needed.", sender->name); + "Handshake: we already know node %.40s %s, " + "updating the address if needed.", sender->name, sender->human_readable_name); + + if (hdr->has_human_readable_name) { + setManualClusterNodeName(sender, hdr->human_readable_name); + } + else + setClusterNodeName(sender); + if (nodeUpdateAddressIfNeeded(sender,link,hdr)) { clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| @@ -2283,8 +2308,8 @@ int clusterProcessPacket(clusterLink *link) { /* First thing to do is replacing the random name with the * right node name if this was a handshake stage. */ clusterRenameNode(link->node, hdr->sender); - serverLog(LL_DEBUG,"Handshake with node %.40s completed.", - link->node->name); + serverLog(LL_DEBUG,"Handshake with node %.40s %s completed.", + link->node->name, link->node->human_readable_name); link->node->flags &= ~CLUSTER_NODE_HANDSHAKE; link->node->flags |= flags&(CLUSTER_NODE_MASTER|CLUSTER_NODE_SLAVE); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG); @@ -2294,8 +2319,8 @@ int clusterProcessPacket(clusterLink *link) { /* If the reply has a non matching node ID we * disconnect this node and set it as not having an associated * address. */ - serverLog(LL_DEBUG,"PONG contains mismatching sender ID. About node %.40s added %d ms ago, having flags %d", - link->node->name, + serverLog(LL_DEBUG,"PONG contains mismatching sender ID. About node %.40s %s added %d ms ago, having flags %d", + link->node->name, link->node->human_readable_name, (int)(now-(link->node->ctime)), link->node->flags); link->node->flags |= CLUSTER_NODE_NOADDR; @@ -2441,9 +2466,10 @@ int clusterProcessPacket(clusterLink *link) { senderConfigEpoch) { serverLog(LL_VERBOSE, - "Node %.40s has old slots configuration, sending " - "an UPDATE message about %.40s", - sender->name, server.cluster->slots[j]->name); + "Node %.40s %s has old slots configuration, sending " + "an UPDATE message about %.40s %s", + sender->name, sender->human_readable_name, + server.cluster->slots[j]->name, server.cluster->slots[j]->human_readable_name); clusterSendUpdate(sender->link, server.cluster->slots[j]); @@ -2631,8 +2657,8 @@ void clusterLinkConnectHandler(connection *conn) { /* Check if connection succeeded */ if (connGetState(conn) != CONN_STATE_CONNECTED) { - serverLog(LL_VERBOSE, "Connection with Node %.40s at %s:%d failed: %s", - node->name, node->ip, node->cport, + serverLog(LL_VERBOSE, "Connection with Node %.40s %s at %s:%d failed: %s", + node->name, node->human_readable_name, node->ip, node->cport, connGetLastError(conn)); freeClusterLink(link); return; @@ -2663,8 +2689,8 @@ void clusterLinkConnectHandler(connection *conn) { * normal PING packets. */ node->flags &= ~CLUSTER_NODE_MEET; - serverLog(LL_DEBUG,"Connecting with Node %.40s at %s:%d", - node->name, node->ip, node->cport); + serverLog(LL_DEBUG,"Connecting with Node %.40s %s at %s:%d", + node->name, node->human_readable_name, node->ip, node->cport); } /* Read data. Try to read the first field of the header first to check the @@ -2804,6 +2830,8 @@ void clusterBuildMessageHdr(clusterMsg *hdr, int type) { hdr->sig[3] = 'b'; hdr->type = htons(type); memcpy(hdr->sender,myself->name,CLUSTER_NAMELEN); + strncpy(hdr->human_readable_name,myself->human_readable_name,CLUSTER_HUMAN_NAMELEN); + hdr->has_human_readable_name = myself->has_human_readable_name; /* If cluster-announce-ip option is enabled, force the receivers of our * packets to use the specified address for this node. Otherwise if the @@ -2882,6 +2910,7 @@ void clusterSetGossipEntry(clusterMsg *hdr, int i, clusterNode *n) { gossip->cport = htons(n->cport); gossip->flags = htons(n->flags); gossip->pport = htons(n->pport); + gossip->has_human_readable_name = n->has_human_readable_name; gossip->notused1 = 0; } @@ -3306,8 +3335,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * request, if the request epoch was greater. */ if (requestCurrentEpoch < server.cluster->currentEpoch) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: reqEpoch (%llu) < curEpoch(%llu)", - node->name, + "Failover auth denied to %.40s %s: reqEpoch (%llu) < curEpoch(%llu)", + node->name, node->human_readable_name, (unsigned long long) requestCurrentEpoch, (unsigned long long) server.cluster->currentEpoch); return; @@ -3316,8 +3345,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { /* I already voted for this epoch? Return ASAP. */ if (server.cluster->lastVoteEpoch == server.cluster->currentEpoch) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: already voted for epoch %llu", - node->name, + "Failover auth denied to %.40s %s: already voted for epoch %llu", + node->name, node->human_readable_name, (unsigned long long) server.cluster->currentEpoch); return; } @@ -3330,16 +3359,16 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { { if (nodeIsMaster(node)) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: it is a master node", - node->name); + "Failover auth denied to %.40s %s: it is a master node", + node->name, node->human_readable_name); } else if (master == NULL) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: I don't know its master", - node->name); + "Failover auth denied to %.40s %s: I don't know its master", + node->name, node->human_readable_name); } else if (!nodeFailed(master)) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: its master is up", - node->name); + "Failover auth denied to %.40s %s: its master is up", + node->name, node->human_readable_name); } return; } @@ -3350,9 +3379,9 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { if (mstime() - node->slaveof->voted_time < server.cluster_node_timeout * 2) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: " + "Failover auth denied to %.40s %s: " "can't vote about this master before %lld milliseconds", - node->name, + node->name, node->human_readable_name, (long long) ((server.cluster_node_timeout*2)- (mstime() - node->slaveof->voted_time))); return; @@ -3372,9 +3401,9 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * is served by a master with a greater configEpoch than the one claimed * by the slave requesting our vote. Refuse to vote for this slave. */ serverLog(LL_WARNING, - "Failover auth denied to %.40s: " + "Failover auth denied to %.40s %s: " "slot %d epoch (%llu) > reqEpoch (%llu)", - node->name, j, + node->name, node->human_readable_name, j, (unsigned long long) server.cluster->slots[j]->configEpoch, (unsigned long long) requestConfigEpoch); return; @@ -3385,8 +3414,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { node->slaveof->voted_time = mstime(); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG|CLUSTER_TODO_FSYNC_CONFIG); clusterSendFailoverAuth(node); - serverLog(LL_WARNING, "Failover auth granted to %.40s for epoch %llu", - node->name, (unsigned long long) server.cluster->currentEpoch); + serverLog(LL_WARNING, "Failover auth granted to %.40s %s for epoch %llu", + node->name, node->human_readable_name, (unsigned long long) server.cluster->currentEpoch); } /* This function returns the "rank" of this instance, a slave, in the context @@ -3614,7 +3643,7 @@ void clusterHandleSlaveFailover(void) { if (server.cluster->mf_end) { server.cluster->failover_auth_time = mstime(); server.cluster->failover_auth_rank = 0; - clusterDoBeforeSleep(CLUSTER_TODO_HANDLE_FAILOVER); + clusterDoBeforeSleep(CLUSTER_TODO_HANDLE_FAILOVER); } serverLog(LL_WARNING, "Start of election delayed for %lld milliseconds " @@ -3803,8 +3832,8 @@ void clusterHandleSlaveMigration(int max_slaves) { (mstime()-target->orphaned_time) > CLUSTER_SLAVE_MIGRATION_DELAY && !(server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_FAILOVER)) { - serverLog(LL_WARNING,"Migrating to orphaned master %.40s", - target->name); + serverLog(LL_WARNING,"Migrating to orphaned master %.40s %s", + target->name, target->human_readable_name); clusterSetMaster(target); } } @@ -4050,7 +4079,7 @@ void clusterCron(void) { } } if (min_pong_node) { - serverLog(LL_DEBUG,"Pinging node %.40s", min_pong_node->name); + serverLog(LL_DEBUG,"Pinging node %.40s %s", min_pong_node->name, min_pong_node->human_readable_name); clusterSendPing(min_pong_node->link, CLUSTERMSG_TYPE_PING); } } @@ -4150,8 +4179,8 @@ void clusterCron(void) { /* Timeout reached. Set the node as possibly failing if it is * not already in this state. */ if (!(node->flags & (CLUSTER_NODE_PFAIL|CLUSTER_NODE_FAIL))) { - serverLog(LL_DEBUG,"*** NODE %.40s possibly failing", - node->name); + serverLog(LL_DEBUG,"*** NODE %.40s %s possibly failing", + node->name, node->human_readable_name); node->flags |= CLUSTER_NODE_PFAIL; update_state = 1; } @@ -4639,6 +4668,9 @@ sds clusterGenNodeDescription(clusterNode *node, int use_pport) { else ci = sdscatlen(ci,"-",1); + /* Adding has human readable name */ + ci = sdscatfmt(ci," %i",node->has_human_readable_name); + unsigned long long nodeEpoch = node->configEpoch; if (nodeIsSlave(node) && node->slaveof) { nodeEpoch = node->slaveof->configEpoch; @@ -5062,10 +5094,12 @@ void clusterCommand(client *c) { "MYID", " Return the node id.", "MYNAME", -" Return the node name.", +" Return the human readable node name.", +"SETNAME ", +" Sets the human-readable node name.", "NODES", " Return cluster configuration seen by node. Output format:", -" ...", +" ...", "REPLICATE ", " Configure current node as replica to .", "RESET [HARD|SOFT]", @@ -5128,11 +5162,17 @@ NULL /* CLUSTER MYID */ addReplyBulkCBuffer(c,myself->name, CLUSTER_NAMELEN); } else if (!strcasecmp(c->argv[1]->ptr,"myname") && c->argc == 2) { - /* CLUSTER MYID */ - if (myself->hname) - addReplyBulkCBuffer(c,myself->hname, strlen(myself->hname)); + /* CLUSTER MYNAME */ + if (myself->human_readable_name[0] != '\0') + addReplyBulkCBuffer(c,myself->human_readable_name, strlen(myself->human_readable_name)); else addReplyError(c,"Node is not assigned name yet."); + } else if (!strcasecmp(c->argv[1]->ptr,"setname") && c->argc == 3) { + /* CLUSTER SETNAME */ + if (setManualClusterNodeName(myself,c->argv[2]->ptr)) + addReply(c,shared.ok); + else + addReplyError(c,"Error setting the name of the node."); } else if (!strcasecmp(c->argv[1]->ptr,"slots") && c->argc == 2) { /* CLUSTER SLOTS */ clusterReplyMultiBulkSlots(c); diff --git a/src/cluster.h b/src/cluster.h index 40ced7a67ea..1396ea47ed9 100644 --- a/src/cluster.h +++ b/src/cluster.h @@ -9,6 +9,7 @@ #define CLUSTER_OK 0 /* Everything looks ok */ #define CLUSTER_FAIL 1 /* The cluster can't work */ #define CLUSTER_NAMELEN 40 /* sha1 hex length */ +#define CLUSTER_HUMAN_NAMELEN 64 /* Max length of human readable node name */ #define CLUSTER_PORT_INCR 10000 /* Cluster port = baseport + PORT_INCR */ /* The following defines are amount of time, sometimes expressed as @@ -115,7 +116,7 @@ typedef struct clusterNodeFailReport { typedef struct clusterNode { mstime_t ctime; /* Node object creation time. */ char name[CLUSTER_NAMELEN]; /* Node name, hex string, sha1-size */ - char* hname; /* Human readable name for node */ + char human_readable_name[CLUSTER_HUMAN_NAMELEN]; /* Human readable name for node */ int flags; /* CLUSTER_NODE_... */ uint64_t configEpoch; /* Last configEpoch observed for this node */ unsigned char slots[CLUSTER_SLOTS/8]; /* slots handled by this node */ @@ -144,6 +145,7 @@ typedef struct clusterNode { clusterLink *link; /* TCP/IP link established toward this node */ clusterLink *inbound_link; /* TCP/IP link accepted from this node */ list *fail_reports; /* List of nodes signaling this as failing */ + int has_human_readable_name; /* Indicates whether custom nodename is used */ } clusterNode; /* Slot to keys for a single slot. The keys in the same slot are linked together @@ -217,11 +219,13 @@ typedef struct { uint32_t ping_sent; uint32_t pong_received; char ip[NET_IP_STR_LEN]; /* IP address last time it was seen */ + char human_readable_name[CLUSTER_HUMAN_NAMELEN]; /* Human readable name for node */ uint16_t port; /* base port last time it was seen */ uint16_t cport; /* cluster port last time it was seen */ uint16_t flags; /* node->flags copy */ uint16_t pport; /* plaintext-port, when base port is TLS */ uint16_t notused1; + int has_human_readable_name; /* Indicates whether custom nodename is used */ } clusterMsgDataGossip; typedef struct { @@ -321,6 +325,7 @@ typedef struct { unsigned char myslots[CLUSTER_SLOTS/8]; char slaveof[CLUSTER_NAMELEN]; char myip[NET_IP_STR_LEN]; /* Sender IP, if not all zeroed. */ + char human_readable_name[CLUSTER_HUMAN_NAMELEN]; uint16_t extensions; /* Number of extensions sent along with this packet. */ char notused1[16]; /* 16 bytes reserved for future usage. */ uint16_t pport; /* Sender TCP plaintext port, if base port is TLS */ @@ -329,6 +334,7 @@ typedef struct { unsigned char state; /* Cluster state from the POV of the sender */ unsigned char mflags[3]; /* Message flags: CLUSTERMSG_FLAG[012]_... */ union clusterMsgData data; + int has_human_readable_name; /* Indicates whether custom nodename is used */ } clusterMsg; #define CLUSTERMSG_MIN_LEN (sizeof(clusterMsg)-sizeof(union clusterMsgData)) diff --git a/src/redis-cli.c b/src/redis-cli.c index 25353af3561..c4e944b3e2a 100644 --- a/src/redis-cli.c +++ b/src/redis-cli.c @@ -4178,9 +4178,10 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, lines = p + 1; char *name = NULL, *addr = NULL, *flags = NULL, *master_id = NULL, *ping_sent = NULL, *ping_recv = NULL, *config_epoch = NULL, - *link_status = NULL, *hname = NULL; + *link_status = NULL, *human_readable_name = NULL, *has_human_readable_name = NULL; UNUSED(link_status); - UNUSED(hname); + UNUSED(human_readable_name); + UNUSED(has_human_readable_name); int i = 0; while ((p = strchr(line, ' ')) != NULL) { *p = '\0'; @@ -4188,16 +4189,17 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, line = p + 1; switch(i++){ case 0: name = token; break; - case 1: hname = token; break; + case 1: human_readable_name = token; break; case 2: addr = token; break; case 3: flags = token; break; case 4: master_id = token; break; - case 5: ping_sent = token; break; - case 6: ping_recv = token; break; - case 7: config_epoch = token; break; - case 8: link_status = token; break; + case 5: has_human_readable_name = token; break; + case 6: ping_sent = token; break; + case 7: ping_recv = token; break; + case 8: config_epoch = token; break; + case 9: link_status = token; break; } - if (i == 9) break; // Slots + if (i == 10) break; // Slots } if (!flags) { success = 0; @@ -4209,7 +4211,7 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, node->flags |= CLUSTER_MANAGER_FLAG_MYSELF; currentNode = node; clusterManagerNodeResetSlots(node); - if (i == 9) { + if (i == 10) { int remaining = strlen(line); while (remaining > 0) { p = strchr(line, ' '); diff --git a/tests/cluster/cluster.tcl b/tests/cluster/cluster.tcl index 379db48a5d0..4862021626e 100644 --- a/tests/cluster/cluster.tcl +++ b/tests/cluster/cluster.tcl @@ -22,11 +22,12 @@ proc get_cluster_nodes id { addr [lindex $args 2] \ flags [split [lindex $args 3] ,] \ slaveof [lindex $args 4] \ - ping_sent [lindex $args 5] \ - pong_recv [lindex $args 6] \ - config_epoch [lindex $args 7] \ - linkstate [lindex $args 8] \ - slots [lrange $args 9 end] \ + customName [lindex $args 5] \ + ping_sent [lindex $args 6] \ + pong_recv [lindex $args 7] \ + config_epoch [lindex $args 8] \ + linkstate [lindex $args 9] \ + slots [lrange $args 10 end] \ ] lappend nodes $node } diff --git a/tests/support/cluster.tcl b/tests/support/cluster.tcl index 8c628dcd3f1..2ead91f43d1 100644 --- a/tests/support/cluster.tcl +++ b/tests/support/cluster.tcl @@ -104,8 +104,8 @@ proc ::redis_cluster::__method__refresh_nodes_map {id} { set line [string trim $line] if {$line eq {}} continue set args [split $line " "] - lassign $args nodeid name addr flags slaveof pingsent pongrecv configepoch linkstate - set slots [lrange $args 9 end] + lassign $args nodeid name addr flags slaveof customname pingsent pongrecv configepoch linkstate + set slots [lrange $args 10 end] set addr [lindex [split $addr @] 0] if {$addr eq {:0}} { set addr $start_host:$start_port @@ -126,6 +126,7 @@ proc ::redis_cluster::__method__refresh_nodes_map {id} { port $port \ flags $flags \ slaveof $slaveof \ + customname $customname \ slots $slots \ link $link \ ] From b1161cb7bdb26c61294dae36d4a28c208cde41f6 Mon Sep 17 00:00:00 2001 From: hwware Date: Wed, 12 Jan 2022 14:08:57 -0500 Subject: [PATCH 16/79] update codes to fix error in rebase --- src/cluster.c | 210 ++++++++++++-------------------------- src/cluster.h | 7 -- src/help.h | 5 - src/redis-cli.c | 24 ++--- tests/cluster/cluster.tcl | 18 ++-- tests/support/cluster.tcl | 5 +- 6 files changed, 84 insertions(+), 185 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index e4ac54555d5..096b0c55f29 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -48,7 +48,6 @@ clusterNode *myself = NULL; clusterNode *createClusterNode(char *nodename, int flags); void clusterAddNode(clusterNode *node); -void setClusterNodeName(clusterNode *node); void clusterAcceptHandler(aeEventLoop *el, int fd, void *privdata, int mask); void clusterReadHandler(connection *conn); void clusterSendPing(clusterLink *link, int type); @@ -254,7 +253,7 @@ int clusterLoadConfig(char *filename) { * stored in nodes.conf. It is received later over the bus protocol. */ /* Parse flags */ - p = s = argv[3]; + p = s = argv[2]; while(p) { p = strchr(s,','); if (p) *p = '\0'; @@ -287,28 +286,25 @@ int clusterLoadConfig(char *filename) { /* Get master if any. Set the master and populate master's * slave list. */ - if (argv[4][0] != '-') { - master = clusterLookupNode(argv[4]); + if (argv[3][0] != '-') { + master = clusterLookupNode(argv[3]); if (!master) { - master = createClusterNode(argv[4],0); + master = createClusterNode(argv[3],0); clusterAddNode(master); } n->slaveof = master; clusterNodeAddSlave(master,n); } - /* Custom nodename */ - n->has_human_readable_name = atoi(argv[5]); - /* Set ping sent / pong received timestamps */ - if (atoi(argv[6])) n->ping_sent = mstime(); - if (atoi(argv[7])) n->pong_received = mstime(); + if (atoi(argv[4])) n->ping_sent = mstime(); + if (atoi(argv[5])) n->pong_received = mstime(); /* Set configEpoch for this node. */ - n->configEpoch = strtoull(argv[8],NULL,10); + n->configEpoch = strtoull(argv[6],NULL,10); /* Populate hash slots served by this instance. */ - for (j = 10; j < argc; j++) { + for (j = 8; j < argc; j++) { int start, stop; if (argv[j][0] == '[') { @@ -362,7 +358,7 @@ int clusterLoadConfig(char *filename) { zfree(line); fclose(fp); - serverLog(LL_NOTICE,"Node configuration loaded, I'm %.40s %s", myself->name, myself->human_readable_name); + serverLog(LL_NOTICE,"Node configuration loaded, I'm %.40s", myself->name); /* Something that should never happen: currentEpoch smaller than * the max epoch found in the nodes configuration. However we handle this @@ -639,8 +635,8 @@ void clusterInit(void) { * by the createClusterNode() function. */ myself = server.cluster->myself = createClusterNode(NULL,CLUSTER_NODE_MYSELF|CLUSTER_NODE_MASTER); - serverLog(LL_NOTICE,"No cluster configuration found, I'm %.40s %s", - myself->name, myself->human_readable_name); + serverLog(LL_NOTICE,"No cluster configuration found, I'm %.40s", + myself->name); clusterAddNode(myself); saveconf = 1; } @@ -747,7 +743,7 @@ void clusterReset(int hard) { sdsfree(oldname); getRandomHexChars(myself->name, CLUSTER_NAMELEN); clusterAddNode(myself); - serverLog(LL_NOTICE,"Node hard reset, now I'm %.40s %s", myself->name, myself->human_readable_name); + serverLog(LL_NOTICE,"Node hard reset, now I'm %.40s", myself->name); } /* Make sure to persist the new config and update the state. */ @@ -934,25 +930,6 @@ unsigned int keyHashSlot(char *key, int keylen) { * CLUSTER node API * -------------------------------------------------------------------------- */ -/* Assign a human readable name to nodes for clusters*/ -void setClusterNodeName(clusterNode *node) { - if (node->has_human_readable_name == 1) - return; - char ip[NET_IP_STR_LEN]; - strcpy(ip,node->ip); - sprintf(node->human_readable_name, "%s_%u", ip,(unsigned int)node->port); -} - -/* Manually assign a human readable name to nodes for clusters*/ -int setManualClusterNodeName(clusterNode *node, char * newname) { - if (newname == NULL) - return 0; - memcpy(node->human_readable_name, newname, strlen(newname) + 1); - node->has_human_readable_name = 1; - clusterSaveConfig(1); - return 1; -} - /* Create a new cluster node, with the specified flags. * If "nodename" is NULL this is considered a first handshake and a random * node name is assigned to this node (it will be fixed later when we'll @@ -973,7 +950,6 @@ clusterNode *createClusterNode(char *nodename, int flags) { memset(node->slots,0,sizeof(node->slots)); node->slots_info = NULL; node->numslots = 0; - node->has_human_readable_name = 0; node->numslaves = 0; node->slaves = NULL; node->slaveof = NULL; @@ -1216,17 +1192,6 @@ clusterNode *clusterLookupNode(const char *name) { de = dictFind(server.cluster->nodes,s); sdsfree(s); if (de == NULL) { - /* Check if any node has the same human readable name*/ - dictIterator *di; - dictEntry *de2; - - di = dictGetSafeIterator(server.cluster->nodes); - while((de2 = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de2); - if (strcmp(node->human_readable_name,name) == 0) - return node; - } - dictReleaseIterator(di); return NULL; } return dictGetVal(de); @@ -1386,9 +1351,9 @@ void clusterHandleConfigEpochCollision(clusterNode *sender) { myself->configEpoch = server.cluster->currentEpoch; clusterSaveConfigOrDie(1); serverLog(LL_VERBOSE, - "WARNING: configEpoch collision with node %.40s %s." + "WARNING: configEpoch collision with node %.40s." " configEpoch set to %llu", - sender->name, sender->human_readable_name, + sender->name, (unsigned long long) myself->configEpoch); } @@ -1504,7 +1469,7 @@ void markNodeAsFailingIfNeeded(clusterNode *node) { if (failures < needed_quorum) return; /* No weak agreement from masters. */ serverLog(LL_NOTICE, - "Marking node %.40s %s as failing (quorum reached).", node->name, node ->human_readable_name); + "Marking node %.40s as failing (quorum reached).", node->name); /* Mark the node as failing. */ node->flags &= ~CLUSTER_NODE_PFAIL; @@ -1532,8 +1497,8 @@ void clearNodeFailureIfNeeded(clusterNode *node) { * node again. */ if (nodeIsSlave(node) || node->numslots == 0) { serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s %s: %s is reachable again.", - node->name, node->human_readable_name, + "Clear FAIL state for node %.40s : %s is reachable again.", + node->name, nodeIsSlave(node) ? "replica" : "master without slots"); node->flags &= ~CLUSTER_NODE_FAIL; clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); @@ -1548,8 +1513,8 @@ void clearNodeFailureIfNeeded(clusterNode *node) { (server.cluster_node_timeout * CLUSTER_FAIL_UNDO_TIME_MULT)) { serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s %s: is reachable again and nobody is serving its slots after some time.", - node->name, node->human_readable_name); + "Clear FAIL state for node %.40s : is reachable again and nobody is serving its slots after some time.", + node->name); node->flags &= ~CLUSTER_NODE_FAIL; clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); } @@ -1631,7 +1596,6 @@ int clusterStartHandshake(char *ip, int port, int cport) { memcpy(n->ip,norm_ip,sizeof(n->ip)); n->port = port; n->cport = cport; - setClusterNodeName(n); clusterAddNode(n); return 1; } @@ -1670,15 +1634,15 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { if (flags & (CLUSTER_NODE_FAIL|CLUSTER_NODE_PFAIL)) { if (clusterNodeAddFailureReport(node,sender)) { serverLog(LL_VERBOSE, - "Node %.40s %s reported node %.40s %s as not reachable.", - sender->name, sender->human_readable_name, node->name, node->human_readable_name); + "Node %.40s reported node %.40s as not reachable.", + sender->name, node->name); } markNodeAsFailingIfNeeded(node); } else { if (clusterNodeDelFailureReport(node,sender)) { serverLog(LL_VERBOSE, - "Node %.40s %s reported node %.40s %s is back online.", - sender->name, sender->human_readable_name, node->name, node->human_readable_name); + "Node %.40s reported node %.40s is back online.", + sender->name, node->name); } } } @@ -1723,10 +1687,6 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { node->pport = ntohs(g->pport); node->cport = ntohs(g->cport); node->flags &= ~CLUSTER_NODE_NOADDR; - if (hdr->has_human_readable_name) - setManualClusterNodeName(node, hdr->human_readable_name); - else - setClusterNodeName(node); } } else { /* If it's not in NOADDR state and we don't have it, we @@ -1748,10 +1708,6 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { node->port = ntohs(g->port); node->pport = ntohs(g->pport); node->cport = ntohs(g->cport); - if (hdr->has_human_readable_name) - setManualClusterNodeName(node, hdr->human_readable_name); - else - setClusterNodeName(node); clusterAddNode(node); } } @@ -1810,14 +1766,10 @@ int nodeUpdateAddressIfNeeded(clusterNode *node, clusterLink *link, node->port = port; node->pport = pport; node->cport = cport; - if (hdr->has_human_readable_name) - setManualClusterNodeName(node, hdr->human_readable_name); - else - setClusterNodeName(node); if (node->link) freeClusterLink(node->link); node->flags &= ~CLUSTER_NODE_NOADDR; - serverLog(LL_WARNING,"Address updated for node %.40s %s, now %s:%d", - node->name, node->human_readable_name, node->ip, node->port); + serverLog(LL_WARNING,"Address updated for node %.40s , now %s:%d", + node->name, node->ip, node->port); /* Check if this is our master and we have to change the * replication target as well. */ @@ -1946,7 +1898,7 @@ void clusterUpdateSlotsConfigWith(clusterNode *sender, uint64_t senderConfigEpoc sender_slots == migrated_our_slots)) { serverLog(LL_WARNING, "Configuration change detected. Reconfiguring myself " - "as a replica of %.40s %s", sender->name, sender->human_readable_name); + "as a replica of %.40s ", sender->name); clusterSetMaster(sender); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| CLUSTER_TODO_UPDATE_STATE| @@ -2234,17 +2186,12 @@ int clusterProcessPacket(clusterLink *link) { strcmp(ip,myself->ip)) { memcpy(myself->ip,ip,NET_IP_STR_LEN); - setClusterNodeName(myself); serverLog(LL_WARNING,"IP address for this node updated to %s", myself->ip); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG); } } - if (sender && strcmp(sender->human_readable_name,hdr->human_readable_name) != 0) { - strncpy(sender->human_readable_name, hdr->human_readable_name, CLUSTER_HUMAN_NAMELEN); - } - /* Add this node if it is new for us and the msg type is MEET. * In this stage we don't try to add the node with the right * flags, slaveof pointer, and so forth, as this details will be @@ -2257,7 +2204,6 @@ int clusterProcessPacket(clusterLink *link) { node->port = ntohs(hdr->port); node->pport = ntohs(hdr->pport); node->cport = ntohs(hdr->cport); - setClusterNodeName(node); clusterAddNode(node); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG); } @@ -2285,14 +2231,8 @@ int clusterProcessPacket(clusterLink *link) { * IP/port of the node with the new one. */ if (sender) { serverLog(LL_VERBOSE, - "Handshake: we already know node %.40s %s, " - "updating the address if needed.", sender->name, sender->human_readable_name); - - if (hdr->has_human_readable_name) { - setManualClusterNodeName(sender, hdr->human_readable_name); - } - else - setClusterNodeName(sender); + "Handshake: we already know node %.40s , " + "updating the address if needed.", sender->name); if (nodeUpdateAddressIfNeeded(sender,link,hdr)) { @@ -2308,8 +2248,8 @@ int clusterProcessPacket(clusterLink *link) { /* First thing to do is replacing the random name with the * right node name if this was a handshake stage. */ clusterRenameNode(link->node, hdr->sender); - serverLog(LL_DEBUG,"Handshake with node %.40s %s completed.", - link->node->name, link->node->human_readable_name); + serverLog(LL_DEBUG,"Handshake with node %.40s completed.", + link->node->name); link->node->flags &= ~CLUSTER_NODE_HANDSHAKE; link->node->flags |= flags&(CLUSTER_NODE_MASTER|CLUSTER_NODE_SLAVE); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG); @@ -2319,8 +2259,8 @@ int clusterProcessPacket(clusterLink *link) { /* If the reply has a non matching node ID we * disconnect this node and set it as not having an associated * address. */ - serverLog(LL_DEBUG,"PONG contains mismatching sender ID. About node %.40s %s added %d ms ago, having flags %d", - link->node->name, link->node->human_readable_name, + serverLog(LL_DEBUG,"PONG contains mismatching sender ID. About node %.40s added %d ms ago, having flags %d", + link->node->name, (int)(now-(link->node->ctime)), link->node->flags); link->node->flags |= CLUSTER_NODE_NOADDR; @@ -2466,10 +2406,10 @@ int clusterProcessPacket(clusterLink *link) { senderConfigEpoch) { serverLog(LL_VERBOSE, - "Node %.40s %s has old slots configuration, sending " - "an UPDATE message about %.40s %s", - sender->name, sender->human_readable_name, - server.cluster->slots[j]->name, server.cluster->slots[j]->human_readable_name); + "Node %.40s has old slots configuration, sending " + "an UPDATE message about %.40s ", + sender->name, + server.cluster->slots[j]->name); clusterSendUpdate(sender->link, server.cluster->slots[j]); @@ -2657,8 +2597,8 @@ void clusterLinkConnectHandler(connection *conn) { /* Check if connection succeeded */ if (connGetState(conn) != CONN_STATE_CONNECTED) { - serverLog(LL_VERBOSE, "Connection with Node %.40s %s at %s:%d failed: %s", - node->name, node->human_readable_name, node->ip, node->cport, + serverLog(LL_VERBOSE, "Connection with Node %.40s at %s:%d failed: %s", + node->name, node->ip, node->cport, connGetLastError(conn)); freeClusterLink(link); return; @@ -2689,8 +2629,8 @@ void clusterLinkConnectHandler(connection *conn) { * normal PING packets. */ node->flags &= ~CLUSTER_NODE_MEET; - serverLog(LL_DEBUG,"Connecting with Node %.40s %s at %s:%d", - node->name, node->human_readable_name, node->ip, node->cport); + serverLog(LL_DEBUG,"Connecting with Node %.40s at %s:%d", + node->name, node->ip, node->cport); } /* Read data. Try to read the first field of the header first to check the @@ -2830,9 +2770,7 @@ void clusterBuildMessageHdr(clusterMsg *hdr, int type) { hdr->sig[3] = 'b'; hdr->type = htons(type); memcpy(hdr->sender,myself->name,CLUSTER_NAMELEN); - strncpy(hdr->human_readable_name,myself->human_readable_name,CLUSTER_HUMAN_NAMELEN); - hdr->has_human_readable_name = myself->has_human_readable_name; - + /* If cluster-announce-ip option is enabled, force the receivers of our * packets to use the specified address for this node. Otherwise if the * first byte is zero, they'll do auto discovery. */ @@ -2910,7 +2848,6 @@ void clusterSetGossipEntry(clusterMsg *hdr, int i, clusterNode *n) { gossip->cport = htons(n->cport); gossip->flags = htons(n->flags); gossip->pport = htons(n->pport); - gossip->has_human_readable_name = n->has_human_readable_name; gossip->notused1 = 0; } @@ -3335,8 +3272,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * request, if the request epoch was greater. */ if (requestCurrentEpoch < server.cluster->currentEpoch) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: reqEpoch (%llu) < curEpoch(%llu)", - node->name, node->human_readable_name, + "Failover auth denied to %.40s : reqEpoch (%llu) < curEpoch(%llu)", + node->name, (unsigned long long) requestCurrentEpoch, (unsigned long long) server.cluster->currentEpoch); return; @@ -3345,8 +3282,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { /* I already voted for this epoch? Return ASAP. */ if (server.cluster->lastVoteEpoch == server.cluster->currentEpoch) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: already voted for epoch %llu", - node->name, node->human_readable_name, + "Failover auth denied to %.40s : already voted for epoch %llu", + node->name, (unsigned long long) server.cluster->currentEpoch); return; } @@ -3359,16 +3296,16 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { { if (nodeIsMaster(node)) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: it is a master node", - node->name, node->human_readable_name); + "Failover auth denied to %.40s : it is a master node", + node->name); } else if (master == NULL) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: I don't know its master", - node->name, node->human_readable_name); + "Failover auth denied to %.40s : I don't know its master", + node->name); } else if (!nodeFailed(master)) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: its master is up", - node->name, node->human_readable_name); + "Failover auth denied to %.40s : its master is up", + node->name); } return; } @@ -3379,9 +3316,9 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { if (mstime() - node->slaveof->voted_time < server.cluster_node_timeout * 2) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: " + "Failover auth denied to %.40s : " "can't vote about this master before %lld milliseconds", - node->name, node->human_readable_name, + node->name, (long long) ((server.cluster_node_timeout*2)- (mstime() - node->slaveof->voted_time))); return; @@ -3401,9 +3338,9 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * is served by a master with a greater configEpoch than the one claimed * by the slave requesting our vote. Refuse to vote for this slave. */ serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: " + "Failover auth denied to %.40s : " "slot %d epoch (%llu) > reqEpoch (%llu)", - node->name, node->human_readable_name, j, + node->name, j, (unsigned long long) server.cluster->slots[j]->configEpoch, (unsigned long long) requestConfigEpoch); return; @@ -3414,8 +3351,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { node->slaveof->voted_time = mstime(); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG|CLUSTER_TODO_FSYNC_CONFIG); clusterSendFailoverAuth(node); - serverLog(LL_WARNING, "Failover auth granted to %.40s %s for epoch %llu", - node->name, node->human_readable_name, (unsigned long long) server.cluster->currentEpoch); + serverLog(LL_WARNING, "Failover auth granted to %.40s for epoch %llu", + node->name, (unsigned long long) server.cluster->currentEpoch); } /* This function returns the "rank" of this instance, a slave, in the context @@ -3832,8 +3769,8 @@ void clusterHandleSlaveMigration(int max_slaves) { (mstime()-target->orphaned_time) > CLUSTER_SLAVE_MIGRATION_DELAY && !(server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_FAILOVER)) { - serverLog(LL_WARNING,"Migrating to orphaned master %.40s %s", - target->name, target->human_readable_name); + serverLog(LL_WARNING,"Migrating to orphaned master %.40s ", + target->name); clusterSetMaster(target); } } @@ -4079,7 +4016,7 @@ void clusterCron(void) { } } if (min_pong_node) { - serverLog(LL_DEBUG,"Pinging node %.40s %s", min_pong_node->name, min_pong_node->human_readable_name); + serverLog(LL_DEBUG,"Pinging node %.40s ", min_pong_node->name); clusterSendPing(min_pong_node->link, CLUSTERMSG_TYPE_PING); } } @@ -4179,8 +4116,8 @@ void clusterCron(void) { /* Timeout reached. Set the node as possibly failing if it is * not already in this state. */ if (!(node->flags & (CLUSTER_NODE_PFAIL|CLUSTER_NODE_FAIL))) { - serverLog(LL_DEBUG,"*** NODE %.40s %s possibly failing", - node->name, node->human_readable_name); + serverLog(LL_DEBUG,"*** NODE %.40s possibly failing", + node->name); node->flags |= CLUSTER_NODE_PFAIL; update_state = 1; } @@ -4666,10 +4603,7 @@ sds clusterGenNodeDescription(clusterNode *node, int use_pport) { if (node->slaveof) ci = sdscatlen(ci,node->slaveof->name,CLUSTER_NAMELEN); else - ci = sdscatlen(ci,"-",1); - - /* Adding has human readable name */ - ci = sdscatfmt(ci," %i",node->has_human_readable_name); + ci = sdscatlen(ci,"-",1); unsigned long long nodeEpoch = node->configEpoch; if (nodeIsSlave(node) && node->slaveof) { @@ -5093,13 +5027,9 @@ void clusterCommand(client *c) { " Connect nodes into a working cluster.", "MYID", " Return the node id.", -"MYNAME", -" Return the human readable node name.", -"SETNAME ", -" Sets the human-readable node name.", "NODES", " Return cluster configuration seen by node. Output format:", -" ...", +" ...", "REPLICATE ", " Configure current node as replica to .", "RESET [HARD|SOFT]", @@ -5161,18 +5091,6 @@ NULL } else if (!strcasecmp(c->argv[1]->ptr,"myid") && c->argc == 2) { /* CLUSTER MYID */ addReplyBulkCBuffer(c,myself->name, CLUSTER_NAMELEN); - } else if (!strcasecmp(c->argv[1]->ptr,"myname") && c->argc == 2) { - /* CLUSTER MYNAME */ - if (myself->human_readable_name[0] != '\0') - addReplyBulkCBuffer(c,myself->human_readable_name, strlen(myself->human_readable_name)); - else - addReplyError(c,"Node is not assigned name yet."); - } else if (!strcasecmp(c->argv[1]->ptr,"setname") && c->argc == 3) { - /* CLUSTER SETNAME */ - if (setManualClusterNodeName(myself,c->argv[2]->ptr)) - addReply(c,shared.ok); - else - addReplyError(c,"Error setting the name of the node."); } else if (!strcasecmp(c->argv[1]->ptr,"slots") && c->argc == 2) { /* CLUSTER SLOTS */ clusterReplyMultiBulkSlots(c); diff --git a/src/cluster.h b/src/cluster.h index 1396ea47ed9..8b76ed19e9c 100644 --- a/src/cluster.h +++ b/src/cluster.h @@ -9,7 +9,6 @@ #define CLUSTER_OK 0 /* Everything looks ok */ #define CLUSTER_FAIL 1 /* The cluster can't work */ #define CLUSTER_NAMELEN 40 /* sha1 hex length */ -#define CLUSTER_HUMAN_NAMELEN 64 /* Max length of human readable node name */ #define CLUSTER_PORT_INCR 10000 /* Cluster port = baseport + PORT_INCR */ /* The following defines are amount of time, sometimes expressed as @@ -116,7 +115,6 @@ typedef struct clusterNodeFailReport { typedef struct clusterNode { mstime_t ctime; /* Node object creation time. */ char name[CLUSTER_NAMELEN]; /* Node name, hex string, sha1-size */ - char human_readable_name[CLUSTER_HUMAN_NAMELEN]; /* Human readable name for node */ int flags; /* CLUSTER_NODE_... */ uint64_t configEpoch; /* Last configEpoch observed for this node */ unsigned char slots[CLUSTER_SLOTS/8]; /* slots handled by this node */ @@ -145,7 +143,6 @@ typedef struct clusterNode { clusterLink *link; /* TCP/IP link established toward this node */ clusterLink *inbound_link; /* TCP/IP link accepted from this node */ list *fail_reports; /* List of nodes signaling this as failing */ - int has_human_readable_name; /* Indicates whether custom nodename is used */ } clusterNode; /* Slot to keys for a single slot. The keys in the same slot are linked together @@ -219,13 +216,11 @@ typedef struct { uint32_t ping_sent; uint32_t pong_received; char ip[NET_IP_STR_LEN]; /* IP address last time it was seen */ - char human_readable_name[CLUSTER_HUMAN_NAMELEN]; /* Human readable name for node */ uint16_t port; /* base port last time it was seen */ uint16_t cport; /* cluster port last time it was seen */ uint16_t flags; /* node->flags copy */ uint16_t pport; /* plaintext-port, when base port is TLS */ uint16_t notused1; - int has_human_readable_name; /* Indicates whether custom nodename is used */ } clusterMsgDataGossip; typedef struct { @@ -325,7 +320,6 @@ typedef struct { unsigned char myslots[CLUSTER_SLOTS/8]; char slaveof[CLUSTER_NAMELEN]; char myip[NET_IP_STR_LEN]; /* Sender IP, if not all zeroed. */ - char human_readable_name[CLUSTER_HUMAN_NAMELEN]; uint16_t extensions; /* Number of extensions sent along with this packet. */ char notused1[16]; /* 16 bytes reserved for future usage. */ uint16_t pport; /* Sender TCP plaintext port, if base port is TLS */ @@ -334,7 +328,6 @@ typedef struct { unsigned char state; /* Cluster state from the POV of the sender */ unsigned char mflags[3]; /* Message flags: CLUSTERMSG_FLAG[012]_... */ union clusterMsgData data; - int has_human_readable_name; /* Indicates whether custom nodename is used */ } clusterMsg; #define CLUSTERMSG_MIN_LEN (sizeof(clusterMsg)-sizeof(union clusterMsgData)) diff --git a/src/help.h b/src/help.h index 89694109a43..e7cd003913c 100644 --- a/src/help.h +++ b/src/help.h @@ -293,11 +293,6 @@ struct commandHelp { "Return the node id", 12, "3.0.0" }, - { "CLUSTER MYID", - "", - "Return the node id", - 12, - "3.0.0" }, { "CLUSTER NODES", "", "Get Cluster config for the node", diff --git a/src/redis-cli.c b/src/redis-cli.c index c4e944b3e2a..8ef67f67a9c 100644 --- a/src/redis-cli.c +++ b/src/redis-cli.c @@ -4178,10 +4178,8 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, lines = p + 1; char *name = NULL, *addr = NULL, *flags = NULL, *master_id = NULL, *ping_sent = NULL, *ping_recv = NULL, *config_epoch = NULL, - *link_status = NULL, *human_readable_name = NULL, *has_human_readable_name = NULL; + *link_status = NULL; UNUSED(link_status); - UNUSED(human_readable_name); - UNUSED(has_human_readable_name); int i = 0; while ((p = strchr(line, ' ')) != NULL) { *p = '\0'; @@ -4189,17 +4187,15 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, line = p + 1; switch(i++){ case 0: name = token; break; - case 1: human_readable_name = token; break; - case 2: addr = token; break; - case 3: flags = token; break; - case 4: master_id = token; break; - case 5: has_human_readable_name = token; break; - case 6: ping_sent = token; break; - case 7: ping_recv = token; break; - case 8: config_epoch = token; break; - case 9: link_status = token; break; + case 1: addr = token; break; + case 2: flags = token; break; + case 3: master_id = token; break; + case 4: ping_sent = token; break; + case 5: ping_recv = token; break; + case 6: config_epoch = token; break; + case 7: link_status = token; break; } - if (i == 10) break; // Slots + if (i == 8) break; // Slots } if (!flags) { success = 0; @@ -4211,7 +4207,7 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, node->flags |= CLUSTER_MANAGER_FLAG_MYSELF; currentNode = node; clusterManagerNodeResetSlots(node); - if (i == 10) { + if (i == 8) { int remaining = strlen(line); while (remaining > 0) { p = strchr(line, ' '); diff --git a/tests/cluster/cluster.tcl b/tests/cluster/cluster.tcl index 4862021626e..531e90d6ca4 100644 --- a/tests/cluster/cluster.tcl +++ b/tests/cluster/cluster.tcl @@ -18,16 +18,14 @@ proc get_cluster_nodes id { set args [split $l] set node [dict create \ id [lindex $args 0] \ - name [lindex $args 1] \ - addr [lindex $args 2] \ - flags [split [lindex $args 3] ,] \ - slaveof [lindex $args 4] \ - customName [lindex $args 5] \ - ping_sent [lindex $args 6] \ - pong_recv [lindex $args 7] \ - config_epoch [lindex $args 8] \ - linkstate [lindex $args 9] \ - slots [lrange $args 10 end] \ + addr [lindex $args 1] \ + flags [split [lindex $args 2] ,] \ + slaveof [lindex $args 3] \ + ping_sent [lindex $args 4] \ + pong_recv [lindex $args 5] \ + config_epoch [lindex $args 6] \ + linkstate [lindex $args 7] \ + slots [lrange $args 8 end] \ ] lappend nodes $node } diff --git a/tests/support/cluster.tcl b/tests/support/cluster.tcl index 2ead91f43d1..081ef6a9522 100644 --- a/tests/support/cluster.tcl +++ b/tests/support/cluster.tcl @@ -104,8 +104,8 @@ proc ::redis_cluster::__method__refresh_nodes_map {id} { set line [string trim $line] if {$line eq {}} continue set args [split $line " "] - lassign $args nodeid name addr flags slaveof customname pingsent pongrecv configepoch linkstate - set slots [lrange $args 10 end] + lassign $args nodeid addr flags slaveof pingsent pongrecv configepoch linkstate + set slots [lrange $args 8 end] set addr [lindex [split $addr @] 0] if {$addr eq {:0}} { set addr $start_host:$start_port @@ -126,7 +126,6 @@ proc ::redis_cluster::__method__refresh_nodes_map {id} { port $port \ flags $flags \ slaveof $slaveof \ - customname $customname \ slots $slots \ link $link \ ] From 47e07ad96276c06db87efdef319d23f1ff344b8e Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Wed, 19 Jan 2022 14:52:26 -0500 Subject: [PATCH 17/79] Added nodename support to extension (#61) * Added nodename extension --- src/cluster.c | 154 +++++++++++++++++++++++++++++++++++++++++--------- src/cluster.h | 8 +++ src/config.c | 8 +++ src/server.h | 2 + 4 files changed, 146 insertions(+), 26 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index 096b0c55f29..99b21a2861a 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -216,7 +216,7 @@ int clusterLoadConfig(char *filename) { clusterAddNode(n); } /* Format for the node address information: - * ip:port[@cport][,hostname] */ + * ip:port[@cport][,hostname][-nodename] */ /* Address and port */ if ((p = strrchr(argv[1],':')) == NULL) { @@ -248,6 +248,16 @@ int clusterLoadConfig(char *filename) { } else { n->hostname = NULL; } + /* Nodename is an optional argument */ + char *nodename = strchr(p, '-'); + if (nodename) { + *nodename = '\0'; + nodename++; + zfree(n->nodename); + n->nodename = zstrdup(nodename); + } else { + n->nodename = NULL; + } /* The plaintext port for client in a TLS cluster (n->pport) is not * stored in nodes.conf. It is received later over the bus protocol. */ @@ -587,12 +597,36 @@ static void updateAnnouncedHostname(clusterNode *node, char *new) { } } +/* Update the nodename for the specified node with the provided C string. */ +static void updateAnnouncedNodename(clusterNode *node, char *new) { + if (!node->nodename && !new) { + return; + } + + /* Previous and new nodename are the same, no need to update. */ + if (new && node->nodename && !strcmp(new, node->nodename)) { + return; + } + + if (node->nodename) zfree(node->nodename); + if (new) { + node->nodename = zstrdup(new); + } else { + node->nodename = NULL; + } +} + /* Update my hostname based on server configuration values */ void clusterUpdateMyselfHostname(void) { if (!myself) return; updateAnnouncedHostname(myself, server.cluster_announce_hostname); } +void clusterUpdateMyselfNodename(void) { + if (!myself) return; + updateAnnouncedNodename(myself, server.cluster_announce_nodename); +} + void clusterInit(void) { int saveconf = 0; @@ -687,6 +721,7 @@ void clusterInit(void) { clusterUpdateMyselfFlags(); clusterUpdateMyselfIp(); clusterUpdateMyselfHostname(); + clusterUpdateMyselfNodename(); } /* Reset a node performing a soft or hard reset: @@ -960,6 +995,7 @@ clusterNode *createClusterNode(char *nodename, int flags) { node->inbound_link = NULL; memset(node->ip,0,sizeof(node->ip)); node->hostname = NULL; + node->nodename = NULL; node->port = 0; node->cport = 0; node->pport = 0; @@ -1126,6 +1162,7 @@ void freeClusterNode(clusterNode *n) { serverAssert(dictDelete(server.cluster->nodes,nodename) == DICT_OK); sdsfree(nodename); zfree(n->hostname); + zfree(n->nodename); /* Release links and associated data structures. */ if (n->link) freeClusterLink(n->link); @@ -1353,7 +1390,7 @@ void clusterHandleConfigEpochCollision(clusterNode *sender) { serverLog(LL_VERBOSE, "WARNING: configEpoch collision with node %.40s." " configEpoch set to %llu", - sender->name, + sender->name, (unsigned long long) myself->configEpoch); } @@ -1497,8 +1534,8 @@ void clearNodeFailureIfNeeded(clusterNode *node) { * node again. */ if (nodeIsSlave(node) || node->numslots == 0) { serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s : %s is reachable again.", - node->name, + "Clear FAIL state for node %.40s: %s is reachable again.", + node->name, nodeIsSlave(node) ? "replica" : "master without slots"); node->flags &= ~CLUSTER_NODE_FAIL; clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); @@ -1513,7 +1550,7 @@ void clearNodeFailureIfNeeded(clusterNode *node) { (server.cluster_node_timeout * CLUSTER_FAIL_UNDO_TIME_MULT)) { serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s : is reachable again and nobody is serving its slots after some time.", + "Clear FAIL state for node %.40s: is reachable again and nobody is serving its slots after some time.", node->name); node->flags &= ~CLUSTER_NODE_FAIL; clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); @@ -1635,7 +1672,7 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { if (clusterNodeAddFailureReport(node,sender)) { serverLog(LL_VERBOSE, "Node %.40s reported node %.40s as not reachable.", - sender->name, node->name); + sender->name, node->name); } markNodeAsFailingIfNeeded(node); } else { @@ -1898,7 +1935,7 @@ void clusterUpdateSlotsConfigWith(clusterNode *sender, uint64_t senderConfigEpoc sender_slots == migrated_our_slots)) { serverLog(LL_WARNING, "Configuration change detected. Reconfiguring myself " - "as a replica of %.40s ", sender->name); + "as a replica of %.40s", sender->name); clusterSetMaster(sender); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| CLUSTER_TODO_UPDATE_STATE| @@ -1955,6 +1992,16 @@ int getHostnamePingExtSize() { return totlen; } +/* Returns the exact size needed to store the nodename. The returned value + * will be 8 byte padded. */ +int getNodenamePingExtSize() { + /* If nodename is not set, we don't send this extension */ + if (!myself->nodename) return 0; + + int totlen = sizeof(clusterMsgPingExt) + EIGHT_BYTE_ALIGN(strlen(myself->nodename) + 1); + return totlen; +} + /* Write the hostname ping extension at the start of the cursor. This function * will update the cursor to point to the end of the written extension and * will return the amount of bytes written. */ @@ -1976,19 +2023,44 @@ int writeHostnamePingExt(clusterMsgPingExt **cursor) { return extension_size; } +/* Write the nodename ping extension at the start of the cursor. This function + * will update the cursor to point to the end of the written extension and + * will return the amount of bytes written. */ +int writeNodenamePingExt(clusterMsgPingExt **cursor) { + /* If nodename is not set, we don't send this extension */ + if (!myself->nodename) return 0; + + /* Add the nodename information at the extension cursor */ + clusterMsgPingExtNodename *ext = &(*cursor)->ext[1].nodename; + size_t nodename_len = strlen(myself->nodename); + memcpy(ext->nodename, myself->nodename, nodename_len); + uint32_t extension_size = getNodenamePingExtSize(); + + /* Move the write cursor */ + (*cursor)->type = CLUSTERMSG_EXT_TYPE_NODENAME; + (*cursor)->length = htonl(extension_size); + /* Make sure the string is NULL terminated by adding 1 */ + *cursor = (clusterMsgPingExt *) (ext->nodename + EIGHT_BYTE_ALIGN(strlen(myself->nodename) + 1)); + return extension_size; +} + /* We previously validated the extensions, so this function just needs to * handle the extensions. */ void clusterProcessPingExtensions(clusterMsg *hdr, clusterLink *link) { clusterNode *sender = link->node ? link->node : clusterLookupNode(hdr->sender); char *ext_hostname = NULL; + char *ext_nodename = NULL; uint16_t extensions = ntohs(hdr->extensions); /* Loop through all the extensions and process them */ clusterMsgPingExt *ext = getInitialPingExt(hdr, ntohs(hdr->count)); while (extensions--) { - uint16_t type = ntohs(ext->type); + uint16_t type = ext->type; if (type == CLUSTERMSG_EXT_TYPE_HOSTNAME) { clusterMsgPingExtHostname *hostname_ext = (clusterMsgPingExtHostname *) &(ext->ext[0].hostname); ext_hostname = hostname_ext->hostname; + } else if (type == CLUSTERMSG_EXT_TYPE_NODENAME) { + clusterMsgPingExtNodename *nodename_ext = (clusterMsgPingExtNodename *) &(ext->ext[1].nodename); + ext_nodename = nodename_ext->nodename; } else { /* Unknown type, we will ignore it but log what happened. */ serverLog(LL_WARNING, "Received unknown extension type %d", type); @@ -2001,6 +2073,7 @@ void clusterProcessPingExtensions(clusterMsg *hdr, clusterLink *link) { * they don't have an announced hostname. Otherwise, we'll * set it now. */ updateAnnouncedHostname(sender, ext_hostname); + updateAnnouncedNodename(sender, ext_nodename); } static clusterNode *getNodeFromLinkAndMsg(clusterLink *link, clusterMsg *hdr) { @@ -2231,7 +2304,7 @@ int clusterProcessPacket(clusterLink *link) { * IP/port of the node with the new one. */ if (sender) { serverLog(LL_VERBOSE, - "Handshake: we already know node %.40s , " + "Handshake: we already know node %.40s, " "updating the address if needed.", sender->name); if (nodeUpdateAddressIfNeeded(sender,link,hdr)) @@ -2260,7 +2333,7 @@ int clusterProcessPacket(clusterLink *link) { * disconnect this node and set it as not having an associated * address. */ serverLog(LL_DEBUG,"PONG contains mismatching sender ID. About node %.40s added %d ms ago, having flags %d", - link->node->name, + link->node->name, (int)(now-(link->node->ctime)), link->node->flags); link->node->flags |= CLUSTER_NODE_NOADDR; @@ -2408,8 +2481,7 @@ int clusterProcessPacket(clusterLink *link) { serverLog(LL_VERBOSE, "Node %.40s has old slots configuration, sending " "an UPDATE message about %.40s ", - sender->name, - server.cluster->slots[j]->name); + sender->name, server.cluster->slots[j]->name); clusterSendUpdate(sender->link, server.cluster->slots[j]); @@ -2904,7 +2976,7 @@ void clusterSendPing(clusterLink *link, int type) { * to put inside the packet. */ estlen = sizeof(clusterMsg) - sizeof(union clusterMsgData); estlen += (sizeof(clusterMsgDataGossip)*(wanted + pfail_wanted)); - estlen += sizeof(clusterMsgPingExt) + getHostnamePingExtSize(); + estlen += sizeof(clusterMsgPingExt) + getHostnamePingExtSize() + getNodenamePingExtSize(); /* Note: clusterBuildMessageHdr() expects the buffer to be always at least * sizeof(clusterMsg) or more. */ @@ -2985,6 +3057,12 @@ void clusterSendPing(clusterLink *link, int type) { extensions++; } + if (myself->nodename) { + hdr->mflags[0] |= CLUSTERMSG_FLAG0_EXT_DATA; + totlen += writeNodenamePingExt(&cursor); + extensions++; + } + /* Compute the actual total length and send! */ totlen += sizeof(clusterMsg)-sizeof(union clusterMsgData); totlen += (sizeof(clusterMsgDataGossip)*gossipcount); @@ -3272,8 +3350,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * request, if the request epoch was greater. */ if (requestCurrentEpoch < server.cluster->currentEpoch) { serverLog(LL_WARNING, - "Failover auth denied to %.40s : reqEpoch (%llu) < curEpoch(%llu)", - node->name, + "Failover auth denied to %.40s: reqEpoch (%llu) < curEpoch(%llu)", + node->name, (unsigned long long) requestCurrentEpoch, (unsigned long long) server.cluster->currentEpoch); return; @@ -3282,8 +3360,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { /* I already voted for this epoch? Return ASAP. */ if (server.cluster->lastVoteEpoch == server.cluster->currentEpoch) { serverLog(LL_WARNING, - "Failover auth denied to %.40s : already voted for epoch %llu", - node->name, + "Failover auth denied to %.40s: already voted for epoch %llu", + node->name, (unsigned long long) server.cluster->currentEpoch); return; } @@ -3296,15 +3374,15 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { { if (nodeIsMaster(node)) { serverLog(LL_WARNING, - "Failover auth denied to %.40s : it is a master node", + "Failover auth denied to %.40s: it is a master node", node->name); } else if (master == NULL) { serverLog(LL_WARNING, - "Failover auth denied to %.40s : I don't know its master", + "Failover auth denied to %.40s: I don't know its master", node->name); } else if (!nodeFailed(master)) { serverLog(LL_WARNING, - "Failover auth denied to %.40s : its master is up", + "Failover auth denied to %.40s: its master is up", node->name); } return; @@ -3316,7 +3394,7 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { if (mstime() - node->slaveof->voted_time < server.cluster_node_timeout * 2) { serverLog(LL_WARNING, - "Failover auth denied to %.40s : " + "Failover auth denied to %.40s: " "can't vote about this master before %lld milliseconds", node->name, (long long) ((server.cluster_node_timeout*2)- @@ -3338,7 +3416,7 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * is served by a master with a greater configEpoch than the one claimed * by the slave requesting our vote. Refuse to vote for this slave. */ serverLog(LL_WARNING, - "Failover auth denied to %.40s : " + "Failover auth denied to %.40s: " "slot %d epoch (%llu) > reqEpoch (%llu)", node->name, j, (unsigned long long) server.cluster->slots[j]->configEpoch, @@ -3769,7 +3847,7 @@ void clusterHandleSlaveMigration(int max_slaves) { (mstime()-target->orphaned_time) > CLUSTER_SLAVE_MIGRATION_DELAY && !(server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_FAILOVER)) { - serverLog(LL_WARNING,"Migrating to orphaned master %.40s ", + serverLog(LL_WARNING,"Migrating to orphaned master %.40s", target->name); clusterSetMaster(target); } @@ -3964,6 +4042,7 @@ void clusterCron(void) { iteration++; /* Number of times this function was called so far. */ updateAnnouncedHostname(myself, server.cluster_announce_hostname); + updateAnnouncedNodename(myself, server.cluster_announce_nodename); /* The handshake timeout is the time after which a handshake node that was * not turned into a normal node is removed from the nodes. Usually it is * just the NODE_TIMEOUT value, but when NODE_TIMEOUT is too small we use @@ -4016,7 +4095,7 @@ void clusterCron(void) { } } if (min_pong_node) { - serverLog(LL_DEBUG,"Pinging node %.40s ", min_pong_node->name); + serverLog(LL_DEBUG,"Pinging node %.40s", min_pong_node->name); clusterSendPing(min_pong_node->link, CLUSTERMSG_TYPE_PING); } } @@ -4582,12 +4661,25 @@ sds clusterGenNodeDescription(clusterNode *node, int use_pport) { /* Node coordinates */ ci = sdscatlen(sdsempty(),node->name,CLUSTER_NAMELEN); - if (node->hostname) { + if (node->hostname && node->nodename) { + ci = sdscatfmt(ci," %s:%i@%i,%s-%s ", + node->ip, + port, + node->cport, + node->hostname, + node->nodename); + } else if (node->hostname) { ci = sdscatfmt(ci," %s:%i@%i,%s ", node->ip, port, node->cport, node->hostname); + } else if (node->nodename) { + ci = sdscatfmt(ci," %s:%i@%i-%s ", + node->ip, + port, + node->cport, + node->nodename); } else { ci = sdscatfmt(ci," %s:%i@%i ", node->ip, @@ -4603,7 +4695,7 @@ sds clusterGenNodeDescription(clusterNode *node, int use_pport) { if (node->slaveof) ci = sdscatlen(ci,node->slaveof->name,CLUSTER_NAMELEN); else - ci = sdscatlen(ci,"-",1); + ci = sdscatlen(ci,"-",1); unsigned long long nodeEpoch = node->configEpoch; if (nodeIsSlave(node) && node->slaveof) { @@ -4809,6 +4901,7 @@ const char *getPreferredEndpoint(clusterNode *n) { switch(server.cluster_preferred_endpoint_type) { case CLUSTER_ENDPOINT_TYPE_IP: return n->ip; case CLUSTER_ENDPOINT_TYPE_HOSTNAME: return n->hostname ? n->hostname : "?"; + case CLUSTER_ENDPOINT_TYPE_NODENAME: return n->nodename ? n->nodename : "?"; case CLUSTER_ENDPOINT_TYPE_UNKNOWN_ENDPOINT: return ""; } return "unknown"; @@ -4903,6 +4996,8 @@ void addNodeToNodeReply(client *c, clusterNode *node) { addReplyBulkCString(c, node->ip); } else if (server.cluster_preferred_endpoint_type == CLUSTER_ENDPOINT_TYPE_HOSTNAME) { addReplyBulkCString(c, node->hostname ? node->hostname : "?"); + } else if (server.cluster_preferred_endpoint_type == CLUSTER_ENDPOINT_TYPE_NODENAME) { + addReplyBulkCString(c, node->nodename ? node->nodename : "?"); } else if (server.cluster_preferred_endpoint_type == CLUSTER_ENDPOINT_TYPE_UNKNOWN_ENDPOINT) { addReplyNull(c); } else { @@ -4931,6 +5026,13 @@ void addNodeToNodeReply(client *c, clusterNode *node) { addReplyBulkCString(c, node->hostname); length++; } + if (server.cluster_preferred_endpoint_type != CLUSTER_ENDPOINT_TYPE_NODENAME + && node->nodename) + { + addReplyBulkCString(c, "nodename"); + addReplyBulkCString(c, node->nodename); + length++; + } setDeferredMapLen(c, deflen, length); } diff --git a/src/cluster.h b/src/cluster.h index 8b76ed19e9c..732f2cb2dd4 100644 --- a/src/cluster.h +++ b/src/cluster.h @@ -136,6 +136,7 @@ typedef struct clusterNode { long long repl_offset; /* Last known repl offset for this node. */ char ip[NET_IP_STR_LEN]; /* Latest known IP address of this node */ char *hostname; /* The known hostname for this node */ + char *nodename; /* The known human readable nodename for this node */ int port; /* Latest known clients port (TLS or plain). */ int pport; /* Latest known clients plaintext port. Only used if the main clients port is for TLS. */ @@ -251,6 +252,7 @@ typedef struct { * consistent manner. */ typedef enum { CLUSTERMSG_EXT_TYPE_HOSTNAME, + CLUSTERMSG_EXT_TYPE_NODENAME, } clusterMsgPingtypes; /* Helper function for making sure extensions are eight byte aligned. */ @@ -260,12 +262,17 @@ typedef struct { char hostname[1]; /* The announced hostname, ends with \0. */ } clusterMsgPingExtHostname; +typedef struct { + char nodename[1]; /* The announced nodename, ends with \0. */ +} clusterMsgPingExtNodename; + typedef struct { uint32_t length; /* Total length of this extension message (including this header) */ uint16_t type; /* Type of this extension message (see clusterMsgPingExtTypes) */ uint16_t unused; /* 16 bits of padding to make this structure 8 byte aligned. */ union { clusterMsgPingExtHostname hostname; + clusterMsgPingExtNodename nodename; } ext[]; /* Actual extension information, formatted so that the data is 8 * byte aligned, regardless of its content. */ } clusterMsgPingExt; @@ -365,5 +372,6 @@ void clusterUpdateMyselfIp(void); void slotToChannelAdd(sds channel); void slotToChannelDel(sds channel); void clusterUpdateMyselfHostname(void); +void clusterUpdateMyselfNodename(void); #endif /* __CLUSTER_H */ diff --git a/src/config.c b/src/config.c index f206bcc8c04..f079610caf2 100644 --- a/src/config.c +++ b/src/config.c @@ -144,6 +144,7 @@ configEnum protected_action_enum[] = { configEnum cluster_preferred_endpoint_type_enum[] = { {"ip", CLUSTER_ENDPOINT_TYPE_IP}, {"hostname", CLUSTER_ENDPOINT_TYPE_HOSTNAME}, + {"nodename", CLUSTER_ENDPOINT_TYPE_NODENAME}, {"unknown-endpoint", CLUSTER_ENDPOINT_TYPE_UNKNOWN_ENDPOINT}, {NULL, 0} }; @@ -2371,6 +2372,12 @@ int updateClusterHostname(const char **err) { return 1; } +int updateClusterNodename(const char **err) { + UNUSED(err); + clusterUpdateMyselfNodename(); + return 1; +} + #ifdef USE_OPENSSL static int applyTlsCfg(const char **err) { UNUSED(err); @@ -2790,6 +2797,7 @@ standardConfig configs[] = { createStringConfig("cluster-announce-ip", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.cluster_announce_ip, NULL, NULL, updateClusterIp), createStringConfig("cluster-config-file", NULL, IMMUTABLE_CONFIG, ALLOW_EMPTY_STRING, server.cluster_configfile, "nodes.conf", NULL, NULL), createStringConfig("cluster-announce-hostname", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.cluster_announce_hostname, NULL, isValidAnnouncedHostname, updateClusterHostname), + createStringConfig("cluster-announce-nodename", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.cluster_announce_nodename, NULL, isValidAnnouncedHostname, updateClusterNodename), createStringConfig("syslog-ident", NULL, IMMUTABLE_CONFIG, ALLOW_EMPTY_STRING, server.syslog_ident, "redis", NULL, NULL), createStringConfig("dbfilename", NULL, MODIFIABLE_CONFIG | PROTECTED_CONFIG, ALLOW_EMPTY_STRING, server.rdb_filename, "dump.rdb", isValidDBfilename, NULL), createStringConfig("appendfilename", NULL, IMMUTABLE_CONFIG, ALLOW_EMPTY_STRING, server.aof_filename, "appendonly.aof", isValidAOFfilename, NULL), diff --git a/src/server.h b/src/server.h index b98883b3321..bd478fcec69 100644 --- a/src/server.h +++ b/src/server.h @@ -537,6 +537,7 @@ typedef struct { typedef enum { CLUSTER_ENDPOINT_TYPE_IP = 0, /* Show IP address */ CLUSTER_ENDPOINT_TYPE_HOSTNAME, /* Show hostname */ + CLUSTER_ENDPOINT_TYPE_NODENAME, /* Show nodename */ CLUSTER_ENDPOINT_TYPE_UNKNOWN_ENDPOINT /* Show NULL or empty */ } cluster_endpoint_type; @@ -1817,6 +1818,7 @@ struct redisServer { if the master is in failure state. */ char *cluster_announce_ip; /* IP address to announce on cluster bus. */ char *cluster_announce_hostname; /* IP address to announce on cluster bus. */ + char *cluster_announce_nodename; /* Human readable name assigned to a node. */ int cluster_preferred_endpoint_type; /* Use the announced hostname when available. */ int cluster_announce_port; /* base port to announce on cluster bus. */ int cluster_announce_tls_port; /* TLS port to announce on cluster bus. */ From d40ea57b05fb0bbed10c5b513d74ddd3317da278 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Thu, 24 Feb 2022 09:55:14 -0500 Subject: [PATCH 18/79] Update src/cluster.c Co-authored-by: Madelyn Olson <34459052+madolson@users.noreply.github.com> --- src/cluster.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cluster.c b/src/cluster.c index 99b21a2861a..ea8676a3311 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -2059,7 +2059,7 @@ void clusterProcessPingExtensions(clusterMsg *hdr, clusterLink *link) { clusterMsgPingExtHostname *hostname_ext = (clusterMsgPingExtHostname *) &(ext->ext[0].hostname); ext_hostname = hostname_ext->hostname; } else if (type == CLUSTERMSG_EXT_TYPE_NODENAME) { - clusterMsgPingExtNodename *nodename_ext = (clusterMsgPingExtNodename *) &(ext->ext[1].nodename); + clusterMsgPingExtNodename *nodename_ext = (clusterMsgPingExtNodename *) &(ext->ext[0].nodename); ext_nodename = nodename_ext->nodename; } else { /* Unknown type, we will ignore it but log what happened. */ From 3b61ebd2d16a952ec84b8ce2e686d4c3c7d4d0e0 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Thu, 24 Feb 2022 09:59:15 -0500 Subject: [PATCH 19/79] Update cluster.c Fix indentation --- src/cluster.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cluster.c b/src/cluster.c index ea8676a3311..f5c549ddd98 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -3658,7 +3658,7 @@ void clusterHandleSlaveFailover(void) { if (server.cluster->mf_end) { server.cluster->failover_auth_time = mstime(); server.cluster->failover_auth_rank = 0; - clusterDoBeforeSleep(CLUSTER_TODO_HANDLE_FAILOVER); + clusterDoBeforeSleep(CLUSTER_TODO_HANDLE_FAILOVER); } serverLog(LL_WARNING, "Start of election delayed for %lld milliseconds " From 799fef2fb30c0ef7092ee6be5d30256531f85efd Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Mon, 27 Sep 2021 17:00:23 -0400 Subject: [PATCH 20/79] Add hostname variable --- src/cluster.c | 16 ++++++++++++++++ src/cluster.h | 1 + 2 files changed, 17 insertions(+) diff --git a/src/cluster.c b/src/cluster.c index ef381f29aea..4a2bfdc7e54 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -924,6 +924,22 @@ unsigned int keyHashSlot(char *key, int keylen) { * CLUSTER node API * -------------------------------------------------------------------------- */ +/* Assign a human readable name to nodes for clusters*/ +void setClusterNodeName(clusterNode *node){ + char *name; + int post_digits; + if (node->port == 0){ + post_digits = 0; + } + else{ + floor(log10(abs(node->port))) + 1; + } + int allocate_len = sizeof(node->ip) + post_digits + 2; + name = zmalloc(allocate_len); + sprintf(name, "%s%s%d", node->ip, "_", node->port); + node->hname = name; +} + /* Create a new cluster node, with the specified flags. * If "nodename" is NULL this is considered a first handshake and a random * node name is assigned to this node (it will be fixed later when we'll diff --git a/src/cluster.h b/src/cluster.h index 314b747bea4..1a8cace98ac 100644 --- a/src/cluster.h +++ b/src/cluster.h @@ -115,6 +115,7 @@ typedef struct clusterNodeFailReport { typedef struct clusterNode { mstime_t ctime; /* Node object creation time. */ char name[CLUSTER_NAMELEN]; /* Node name, hex string, sha1-size */ + char* hname; /* Human readable name for node */ int flags; /* CLUSTER_NODE_... */ uint64_t configEpoch; /* Last configEpoch observed for this node */ unsigned char slots[CLUSTER_SLOTS/8]; /* slots handled by this node */ From 1bb500ff7f21c03181bd613de979a09f6306739b Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Mon, 27 Sep 2021 17:02:18 -0400 Subject: [PATCH 21/79] Update cluster.c --- src/cluster.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cluster.c b/src/cluster.c index 4a2bfdc7e54..6fc7aac4c3f 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -932,7 +932,7 @@ void setClusterNodeName(clusterNode *node){ post_digits = 0; } else{ - floor(log10(abs(node->port))) + 1; + post_digits = floor(log10(abs(node->port))) + 1; } int allocate_len = sizeof(node->ip) + post_digits + 2; name = zmalloc(allocate_len); @@ -1604,6 +1604,7 @@ int clusterStartHandshake(char *ip, int port, int cport) { memcpy(n->ip,norm_ip,sizeof(n->ip)); n->port = port; n->cport = cport; + setClusterNodeName(n); clusterAddNode(n); return 1; } From 9fedeb5e181c0eb74a959bc81a48ad1470be2a24 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Mon, 27 Sep 2021 17:04:26 -0400 Subject: [PATCH 22/79] Update cluster.c --- src/cluster.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cluster.c b/src/cluster.c index 6fc7aac4c3f..e4cde545771 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -48,6 +48,7 @@ clusterNode *myself = NULL; clusterNode *createClusterNode(char *nodename, int flags); void clusterAddNode(clusterNode *node); +void setClusterNodeName(clusterNode *node); void clusterAcceptHandler(aeEventLoop *el, int fd, void *privdata, int mask); void clusterReadHandler(connection *conn); void clusterSendPing(clusterLink *link, int type); @@ -1696,6 +1697,7 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { node->pport = ntohs(g->pport); node->cport = ntohs(g->cport); node->flags &= ~CLUSTER_NODE_NOADDR; + setClusterNodeName(node); } } else { /* If it's not in NOADDR state and we don't have it, we @@ -1717,6 +1719,7 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { node->port = ntohs(g->port); node->pport = ntohs(g->pport); node->cport = ntohs(g->cport); + setClusterNodeName(node); clusterAddNode(node); } } @@ -1775,6 +1778,7 @@ int nodeUpdateAddressIfNeeded(clusterNode *node, clusterLink *link, node->port = port; node->pport = pport; node->cport = cport; + setClusterNodeName(node); if (node->link) freeClusterLink(node->link); node->flags &= ~CLUSTER_NODE_NOADDR; serverLog(LL_WARNING,"Address updated for node %.40s, now %s:%d", From 45fd965b6b190b60d9844ccb9f084af09737d297 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Mon, 27 Sep 2021 17:05:32 -0400 Subject: [PATCH 23/79] Update cluster.c --- src/cluster.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cluster.c b/src/cluster.c index e4cde545771..3deecf9fd4c 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -2198,6 +2198,7 @@ int clusterProcessPacket(clusterLink *link) { strcmp(ip,myself->ip)) { memcpy(myself->ip,ip,NET_IP_STR_LEN); + setClusterNodeName(myself); serverLog(LL_WARNING,"IP address for this node updated to %s", myself->ip); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG); @@ -2216,6 +2217,7 @@ int clusterProcessPacket(clusterLink *link) { node->port = ntohs(hdr->port); node->pport = ntohs(hdr->pport); node->cport = ntohs(hdr->cport); + setClusterNodeName(node); clusterAddNode(node); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG); } From 80ecf81d768d6f3fad0da490e9b46e16bc0f2133 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 10:09:24 -0400 Subject: [PATCH 24/79] Update cluster.c --- src/cluster.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/cluster.c b/src/cluster.c index 3deecf9fd4c..2f7efcf46d6 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -1202,7 +1202,19 @@ clusterNode *clusterLookupNode(const char *name) { de = dictFind(server.cluster->nodes,s); sdsfree(s); - if (de == NULL) return NULL; + if (de == NULL){ + dictIterator *di; + dictEntry *de2; + + di = dictGetSafeIterator(server.cluster->nodes); + while((de2 = dictNext(di)) != NULL) { + clusterNode *node = dictGetVal(de2); + if (strcmp(node->hname,name ) == 0) + return node; + } + dictReleaseIterator(di); + return NULL; + } return dictGetVal(de); } From 91c27af7cc4c4aeb53bfd3b8fc8c5008d029af11 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 10:14:18 -0400 Subject: [PATCH 25/79] Update cluster.c --- src/cluster.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index 2f7efcf46d6..c13d1005192 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -1209,8 +1209,10 @@ clusterNode *clusterLookupNode(const char *name) { di = dictGetSafeIterator(server.cluster->nodes); while((de2 = dictNext(di)) != NULL) { clusterNode *node = dictGetVal(de2); - if (strcmp(node->hname,name ) == 0) - return node; + if (node->hname){ + if (strcmp(node->hname,name ) == 0) + return node; + } } dictReleaseIterator(di); return NULL; From f6c8be39981e8a19ef4911d591831717f4b51a9e Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 10:32:32 -0400 Subject: [PATCH 26/79] Update cluster.c --- src/cluster.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/cluster.c b/src/cluster.c index c13d1005192..df3ed667979 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -1203,6 +1203,7 @@ clusterNode *clusterLookupNode(const char *name) { de = dictFind(server.cluster->nodes,s); sdsfree(s); if (de == NULL){ + /* Check if any node has the same human readable name*/ dictIterator *di; dictEntry *de2; @@ -4750,6 +4751,10 @@ sds clusterGenNodesDescription(int filter, int use_pport) { if (node->flags & filter) continue; ni = clusterGenNodeDescription(node, use_pport); + + if (node->hname) + ni = sdscatfmt(ni," %s ",node->hname); + ci = sdscatsds(ci,ni); sdsfree(ni); ci = sdscatlen(ci,"\n",1); From 6613b72a03cd1e3311211b143135bad445f68841 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 10:33:55 -0400 Subject: [PATCH 27/79] Update cluster.c --- src/cluster.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index df3ed667979..bd1a1f314b3 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -4751,10 +4751,6 @@ sds clusterGenNodesDescription(int filter, int use_pport) { if (node->flags & filter) continue; ni = clusterGenNodeDescription(node, use_pport); - - if (node->hname) - ni = sdscatfmt(ni," %s ",node->hname); - ci = sdscatsds(ci,ni); sdsfree(ni); ci = sdscatlen(ci,"\n",1); From fc9051679f1583cece4936687a91b7bf445f3f01 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 14:32:35 -0400 Subject: [PATCH 28/79] Check node name --- src/cluster.c | 3 +++ src/help.h | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/src/cluster.c b/src/cluster.c index bd1a1f314b3..8db149f7eef 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -5119,6 +5119,9 @@ NULL } else if (!strcasecmp(c->argv[1]->ptr,"myid") && c->argc == 2) { /* CLUSTER MYID */ addReplyBulkCBuffer(c,myself->name, CLUSTER_NAMELEN); + } else if (!strcasecmp(c->argv[1]->ptr,"myname") && c->argc == 2) { + /* CLUSTER MYID */ + addReplyBulkCBuffer(c,myself->hname, sizeof(myself->hname)); } else if (!strcasecmp(c->argv[1]->ptr,"slots") && c->argc == 2) { /* CLUSTER SLOTS */ clusterReplyMultiBulkSlots(c); diff --git a/src/help.h b/src/help.h index 56368c57106..7dd01e52e27 100644 --- a/src/help.h +++ b/src/help.h @@ -364,6 +364,11 @@ struct commandHelp { "Return the node id", 12, "3.0.0" }, + { "CLUSTER MYNAME", + "", + "Return the node name", + 12, + "3.0.0" }, { "CLUSTER NODES", "", "Get Cluster config for the node", From 5b78f87283dbe87699d4167246e0945df5007185 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 14:35:38 -0400 Subject: [PATCH 29/79] Update cluster.c --- src/cluster.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cluster.c b/src/cluster.c index 8db149f7eef..b12e3d41fea 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -5121,7 +5121,10 @@ NULL addReplyBulkCBuffer(c,myself->name, CLUSTER_NAMELEN); } else if (!strcasecmp(c->argv[1]->ptr,"myname") && c->argc == 2) { /* CLUSTER MYID */ - addReplyBulkCBuffer(c,myself->hname, sizeof(myself->hname)); + if (myself->hname) + addReplyBulkCBuffer(c,myself->hname, sizeof(myself->hname)); + else + addReplyError(c,"Node is not assigned name yet."); } else if (!strcasecmp(c->argv[1]->ptr,"slots") && c->argc == 2) { /* CLUSTER SLOTS */ clusterReplyMultiBulkSlots(c); From 9c96f69f1d8b2ab792a9b191964e832259c7b2a9 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 14:37:02 -0400 Subject: [PATCH 30/79] Update cluster.c --- src/cluster.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cluster.c b/src/cluster.c index b12e3d41fea..1a5b0e47e58 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -5122,7 +5122,7 @@ NULL } else if (!strcasecmp(c->argv[1]->ptr,"myname") && c->argc == 2) { /* CLUSTER MYID */ if (myself->hname) - addReplyBulkCBuffer(c,myself->hname, sizeof(myself->hname)); + addReplyBulkCBuffer(c,myself->hname, strlen(myself->hname)); else addReplyError(c,"Node is not assigned name yet."); } else if (!strcasecmp(c->argv[1]->ptr,"slots") && c->argc == 2) { From 6568eaa6c66a8b5359f626b1fd390ff6088a702d Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 14:39:39 -0400 Subject: [PATCH 31/79] Add help for nodename --- src/cluster.c | 2 ++ src/help.h | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index 1a5b0e47e58..18b0c201530 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -5055,6 +5055,8 @@ void clusterCommand(client *c) { " Connect nodes into a working cluster.", "MYID", " Return the node id.", +"MYNAME", +" Return the node name.", "NODES", " Return cluster configuration seen by node. Output format:", " ...", diff --git a/src/help.h b/src/help.h index 7dd01e52e27..73b6234f748 100644 --- a/src/help.h +++ b/src/help.h @@ -364,9 +364,9 @@ struct commandHelp { "Return the node id", 12, "3.0.0" }, - { "CLUSTER MYNAME", + { "CLUSTER MYID", "", - "Return the node name", + "Return the node id", 12, "3.0.0" }, { "CLUSTER NODES", From 3f9940142f037ac79a00e3e52692fcbd665a0098 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 15:59:46 -0400 Subject: [PATCH 32/79] Update cluster.c --- src/cluster.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cluster.c b/src/cluster.c index 18b0c201530..cb4d30d883a 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -926,7 +926,7 @@ unsigned int keyHashSlot(char *key, int keylen) { * -------------------------------------------------------------------------- */ /* Assign a human readable name to nodes for clusters*/ -void setClusterNodeName(clusterNode *node){ +void setClusterNodeName(clusterNode *node) { char *name; int post_digits; if (node->port == 0){ From a2d06c42b500f8ab49ca830742d091e5e583d07a Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 5 Oct 2021 11:21:58 -0400 Subject: [PATCH 33/79] Added support for hname in CLUSTER NODES --- src/cluster.c | 20 ++++++++++---------- src/redis-cli.c | 22 ++++++++++++---------- tests/cluster/cluster.tcl | 17 +++++++++-------- tests/support/cluster.tcl | 4 ++-- 4 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index cb4d30d883a..cdb50b6bc63 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -220,12 +220,12 @@ int clusterLoadConfig(char *filename) { * ip:port[@cport][,hostname] */ /* Address and port */ - if ((p = strrchr(argv[1],':')) == NULL) { + if ((p = strrchr(argv[offset + 1],':')) == NULL) { sdsfreesplitres(argv,argc); goto fmterr; } *p = '\0'; - memcpy(n->ip,argv[1],strlen(argv[1])+1); + memcpy(n->ip,argv[offset + 1],strlen(argv[offset + 1])+1); char *port = p+1; char *busp = strchr(port,'@'); if (busp) { @@ -253,7 +253,7 @@ int clusterLoadConfig(char *filename) { * stored in nodes.conf. It is received later over the bus protocol. */ /* Parse flags */ - p = s = argv[2]; + p = s = argv[offset + 2]; while(p) { p = strchr(s,','); if (p) *p = '\0'; @@ -286,10 +286,10 @@ int clusterLoadConfig(char *filename) { /* Get master if any. Set the master and populate master's * slave list. */ - if (argv[3][0] != '-') { - master = clusterLookupNode(argv[3]); + if (argv[offset + 3][0] != '-') { + master = clusterLookupNode(argv[offset + 3]); if (!master) { - master = createClusterNode(argv[3],0); + master = createClusterNode(argv[offset + 3],0); clusterAddNode(master); } n->slaveof = master; @@ -297,14 +297,14 @@ int clusterLoadConfig(char *filename) { } /* Set ping sent / pong received timestamps */ - if (atoi(argv[4])) n->ping_sent = mstime(); - if (atoi(argv[5])) n->pong_received = mstime(); + if (atoi(argv[offset + 4])) n->ping_sent = mstime(); + if (atoi(argv[offset + 5])) n->pong_received = mstime(); /* Set configEpoch for this node. */ - n->configEpoch = strtoull(argv[6],NULL,10); + n->configEpoch = strtoull(argv[offset + 6],NULL,10); /* Populate hash slots served by this instance. */ - for (j = 8; j < argc; j++) { + for (j = offset + 8; j < argc; j++) { int start, stop; if (argv[j][0] == '[') { diff --git a/src/redis-cli.c b/src/redis-cli.c index bbbe6d6ece8..e4d0afe8359 100644 --- a/src/redis-cli.c +++ b/src/redis-cli.c @@ -4514,8 +4514,9 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, lines = p + 1; char *name = NULL, *addr = NULL, *flags = NULL, *master_id = NULL, *ping_sent = NULL, *ping_recv = NULL, *config_epoch = NULL, - *link_status = NULL; + *link_status = NULL, *hname = NULL; UNUSED(link_status); + UNUSED(hname); int i = 0; while ((p = strchr(line, ' ')) != NULL) { *p = '\0'; @@ -4523,15 +4524,16 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, line = p + 1; switch(i++){ case 0: name = token; break; - case 1: addr = token; break; - case 2: flags = token; break; - case 3: master_id = token; break; - case 4: ping_sent = token; break; - case 5: ping_recv = token; break; - case 6: config_epoch = token; break; - case 7: link_status = token; break; + case 1: hname = token; break; + case 2: addr = token; break; + case 3: flags = token; break; + case 4: master_id = token; break; + case 5: ping_sent = token; break; + case 6: ping_recv = token; break; + case 7: config_epoch = token; break; + case 8: link_status = token; break; } - if (i == 8) break; // Slots + if (i == 9) break; // Slots } if (!flags) { success = 0; @@ -4543,7 +4545,7 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, node->flags |= CLUSTER_MANAGER_FLAG_MYSELF; currentNode = node; clusterManagerNodeResetSlots(node); - if (i == 8) { + if (i == 9) { int remaining = strlen(line); while (remaining > 0) { p = strchr(line, ' '); diff --git a/tests/cluster/cluster.tcl b/tests/cluster/cluster.tcl index 531e90d6ca4..379db48a5d0 100644 --- a/tests/cluster/cluster.tcl +++ b/tests/cluster/cluster.tcl @@ -18,14 +18,15 @@ proc get_cluster_nodes id { set args [split $l] set node [dict create \ id [lindex $args 0] \ - addr [lindex $args 1] \ - flags [split [lindex $args 2] ,] \ - slaveof [lindex $args 3] \ - ping_sent [lindex $args 4] \ - pong_recv [lindex $args 5] \ - config_epoch [lindex $args 6] \ - linkstate [lindex $args 7] \ - slots [lrange $args 8 end] \ + name [lindex $args 1] \ + addr [lindex $args 2] \ + flags [split [lindex $args 3] ,] \ + slaveof [lindex $args 4] \ + ping_sent [lindex $args 5] \ + pong_recv [lindex $args 6] \ + config_epoch [lindex $args 7] \ + linkstate [lindex $args 8] \ + slots [lrange $args 9 end] \ ] lappend nodes $node } diff --git a/tests/support/cluster.tcl b/tests/support/cluster.tcl index 081ef6a9522..8c628dcd3f1 100644 --- a/tests/support/cluster.tcl +++ b/tests/support/cluster.tcl @@ -104,8 +104,8 @@ proc ::redis_cluster::__method__refresh_nodes_map {id} { set line [string trim $line] if {$line eq {}} continue set args [split $line " "] - lassign $args nodeid addr flags slaveof pingsent pongrecv configepoch linkstate - set slots [lrange $args 8 end] + lassign $args nodeid name addr flags slaveof pingsent pongrecv configepoch linkstate + set slots [lrange $args 9 end] set addr [lindex [split $addr @] 0] if {$addr eq {:0}} { set addr $start_host:$start_port From f6af3f6cfe2d6c21cdfbe9149150400766bab887 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Mon, 1 Nov 2021 16:23:43 -0400 Subject: [PATCH 34/79] Add gossip and custom name support --- src/cluster.c | 218 ++++++++++++++++++++++---------------- src/cluster.h | 8 +- src/redis-cli.c | 20 ++-- tests/cluster/cluster.tcl | 11 +- tests/support/cluster.tcl | 5 +- 5 files changed, 156 insertions(+), 106 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index cdb50b6bc63..07acec63223 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -220,12 +220,12 @@ int clusterLoadConfig(char *filename) { * ip:port[@cport][,hostname] */ /* Address and port */ - if ((p = strrchr(argv[offset + 1],':')) == NULL) { + if ((p = strrchr(argv[1],':')) == NULL) { sdsfreesplitres(argv,argc); goto fmterr; } *p = '\0'; - memcpy(n->ip,argv[offset + 1],strlen(argv[offset + 1])+1); + memcpy(n->ip,argv[1],strlen(argv[1])+1); char *port = p+1; char *busp = strchr(port,'@'); if (busp) { @@ -253,7 +253,7 @@ int clusterLoadConfig(char *filename) { * stored in nodes.conf. It is received later over the bus protocol. */ /* Parse flags */ - p = s = argv[offset + 2]; + p = s = argv[3]; while(p) { p = strchr(s,','); if (p) *p = '\0'; @@ -286,25 +286,28 @@ int clusterLoadConfig(char *filename) { /* Get master if any. Set the master and populate master's * slave list. */ - if (argv[offset + 3][0] != '-') { - master = clusterLookupNode(argv[offset + 3]); + if (argv[4][0] != '-') { + master = clusterLookupNode(argv[4]); if (!master) { - master = createClusterNode(argv[offset + 3],0); + master = createClusterNode(argv[4],0); clusterAddNode(master); } n->slaveof = master; clusterNodeAddSlave(master,n); } + /* Custom nodename */ + n->has_human_readable_name = atoi(argv[5]); + /* Set ping sent / pong received timestamps */ - if (atoi(argv[offset + 4])) n->ping_sent = mstime(); - if (atoi(argv[offset + 5])) n->pong_received = mstime(); + if (atoi(argv[6])) n->ping_sent = mstime(); + if (atoi(argv[7])) n->pong_received = mstime(); /* Set configEpoch for this node. */ - n->configEpoch = strtoull(argv[offset + 6],NULL,10); + n->configEpoch = strtoull(argv[8],NULL,10); /* Populate hash slots served by this instance. */ - for (j = offset + 8; j < argc; j++) { + for (j = 10; j < argc; j++) { int start, stop; if (argv[j][0] == '[') { @@ -358,7 +361,7 @@ int clusterLoadConfig(char *filename) { zfree(line); fclose(fp); - serverLog(LL_NOTICE,"Node configuration loaded, I'm %.40s", myself->name); + serverLog(LL_NOTICE,"Node configuration loaded, I'm %.40s %s", myself->name, myself->human_readable_name); /* Something that should never happen: currentEpoch smaller than * the max epoch found in the nodes configuration. However we handle this @@ -630,8 +633,8 @@ void clusterInit(void) { * by the createClusterNode() function. */ myself = server.cluster->myself = createClusterNode(NULL,CLUSTER_NODE_MYSELF|CLUSTER_NODE_MASTER); - serverLog(LL_NOTICE,"No cluster configuration found, I'm %.40s", - myself->name); + serverLog(LL_NOTICE,"No cluster configuration found, I'm %.40s %s", + myself->name, myself->human_readable_name); clusterAddNode(myself); saveconf = 1; } @@ -738,7 +741,7 @@ void clusterReset(int hard) { sdsfree(oldname); getRandomHexChars(myself->name, CLUSTER_NAMELEN); clusterAddNode(myself); - serverLog(LL_NOTICE,"Node hard reset, now I'm %.40s", myself->name); + serverLog(LL_NOTICE,"Node hard reset, now I'm %.40s %s", myself->name, myself->human_readable_name); } /* Make sure to persist the new config and update the state. */ @@ -927,18 +930,21 @@ unsigned int keyHashSlot(char *key, int keylen) { /* Assign a human readable name to nodes for clusters*/ void setClusterNodeName(clusterNode *node) { - char *name; - int post_digits; - if (node->port == 0){ - post_digits = 0; - } - else{ - post_digits = floor(log10(abs(node->port))) + 1; - } - int allocate_len = sizeof(node->ip) + post_digits + 2; - name = zmalloc(allocate_len); - sprintf(name, "%s%s%d", node->ip, "_", node->port); - node->hname = name; + if (node->has_human_readable_name == 1) + return; + char ip[NET_IP_STR_LEN]; + strcpy(ip,node->ip); + sprintf(node->human_readable_name, "%s_%u", ip,(unsigned int)node->port); +} + +/* Manually assign a human readable name to nodes for clusters*/ +int setManualClusterNodeName(clusterNode *node, char * newname) { + if (newname == NULL) + return 0; + memcpy(node->human_readable_name, newname, strlen(newname) + 1); + node->has_human_readable_name = 1; + clusterSaveConfig(1); + return 1; } /* Create a new cluster node, with the specified flags. @@ -961,6 +967,7 @@ clusterNode *createClusterNode(char *nodename, int flags) { memset(node->slots,0,sizeof(node->slots)); node->slots_info = NULL; node->numslots = 0; + node->has_human_readable_name = 0; node->numslaves = 0; node->slaves = NULL; node->slaveof = NULL; @@ -1202,7 +1209,7 @@ clusterNode *clusterLookupNode(const char *name) { de = dictFind(server.cluster->nodes,s); sdsfree(s); - if (de == NULL){ + if (de == NULL) { /* Check if any node has the same human readable name*/ dictIterator *di; dictEntry *de2; @@ -1210,14 +1217,12 @@ clusterNode *clusterLookupNode(const char *name) { di = dictGetSafeIterator(server.cluster->nodes); while((de2 = dictNext(di)) != NULL) { clusterNode *node = dictGetVal(de2); - if (node->hname){ - if (strcmp(node->hname,name ) == 0) - return node; - } + if (strcmp(node->human_readable_name,name) == 0) + return node; } dictReleaseIterator(di); return NULL; - } + } return dictGetVal(de); } @@ -1375,9 +1380,9 @@ void clusterHandleConfigEpochCollision(clusterNode *sender) { myself->configEpoch = server.cluster->currentEpoch; clusterSaveConfigOrDie(1); serverLog(LL_VERBOSE, - "WARNING: configEpoch collision with node %.40s." + "WARNING: configEpoch collision with node %.40s %s." " configEpoch set to %llu", - sender->name, + sender->name, sender->human_readable_name, (unsigned long long) myself->configEpoch); } @@ -1493,7 +1498,7 @@ void markNodeAsFailingIfNeeded(clusterNode *node) { if (failures < needed_quorum) return; /* No weak agreement from masters. */ serverLog(LL_NOTICE, - "Marking node %.40s as failing (quorum reached).", node->name); + "Marking node %.40s %s as failing (quorum reached).", node->name, node ->human_readable_name); /* Mark the node as failing. */ node->flags &= ~CLUSTER_NODE_PFAIL; @@ -1521,8 +1526,8 @@ void clearNodeFailureIfNeeded(clusterNode *node) { * node again. */ if (nodeIsSlave(node) || node->numslots == 0) { serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s: %s is reachable again.", - node->name, + "Clear FAIL state for node %.40s %s: %s is reachable again.", + node->name, node->human_readable_name, nodeIsSlave(node) ? "replica" : "master without slots"); node->flags &= ~CLUSTER_NODE_FAIL; clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); @@ -1537,8 +1542,8 @@ void clearNodeFailureIfNeeded(clusterNode *node) { (server.cluster_node_timeout * CLUSTER_FAIL_UNDO_TIME_MULT)) { serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s: is reachable again and nobody is serving its slots after some time.", - node->name); + "Clear FAIL state for node %.40s %s: is reachable again and nobody is serving its slots after some time.", + node->name, node->human_readable_name); node->flags &= ~CLUSTER_NODE_FAIL; clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); } @@ -1659,15 +1664,15 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { if (flags & (CLUSTER_NODE_FAIL|CLUSTER_NODE_PFAIL)) { if (clusterNodeAddFailureReport(node,sender)) { serverLog(LL_VERBOSE, - "Node %.40s reported node %.40s as not reachable.", - sender->name, node->name); + "Node %.40s %s reported node %.40s %s as not reachable.", + sender->name, sender->human_readable_name, node->name, node->human_readable_name); } markNodeAsFailingIfNeeded(node); } else { if (clusterNodeDelFailureReport(node,sender)) { serverLog(LL_VERBOSE, - "Node %.40s reported node %.40s is back online.", - sender->name, node->name); + "Node %.40s %s reported node %.40s %s is back online.", + sender->name, sender->human_readable_name, node->name, node->human_readable_name); } } } @@ -1712,7 +1717,10 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { node->pport = ntohs(g->pport); node->cport = ntohs(g->cport); node->flags &= ~CLUSTER_NODE_NOADDR; - setClusterNodeName(node); + if (hdr->has_human_readable_name) + setManualClusterNodeName(node, hdr->human_readable_name); + else + setClusterNodeName(node); } } else { /* If it's not in NOADDR state and we don't have it, we @@ -1734,7 +1742,10 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { node->port = ntohs(g->port); node->pport = ntohs(g->pport); node->cport = ntohs(g->cport); - setClusterNodeName(node); + if (hdr->has_human_readable_name) + setManualClusterNodeName(node, hdr->human_readable_name); + else + setClusterNodeName(node); clusterAddNode(node); } } @@ -1793,11 +1804,14 @@ int nodeUpdateAddressIfNeeded(clusterNode *node, clusterLink *link, node->port = port; node->pport = pport; node->cport = cport; - setClusterNodeName(node); + if (hdr->has_human_readable_name) + setManualClusterNodeName(node, hdr->human_readable_name); + else + setClusterNodeName(node); if (node->link) freeClusterLink(node->link); node->flags &= ~CLUSTER_NODE_NOADDR; - serverLog(LL_WARNING,"Address updated for node %.40s, now %s:%d", - node->name, node->ip, node->port); + serverLog(LL_WARNING,"Address updated for node %.40s %s, now %s:%d", + node->name, node->human_readable_name, node->ip, node->port); /* Check if this is our master and we have to change the * replication target as well. */ @@ -1926,7 +1940,7 @@ void clusterUpdateSlotsConfigWith(clusterNode *sender, uint64_t senderConfigEpoc sender_slots == migrated_our_slots)) { serverLog(LL_WARNING, "Configuration change detected. Reconfiguring myself " - "as a replica of %.40s", sender->name); + "as a replica of %.40s %s", sender->name, sender->human_readable_name); clusterSetMaster(sender); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| CLUSTER_TODO_UPDATE_STATE| @@ -2220,6 +2234,10 @@ int clusterProcessPacket(clusterLink *link) { } } + if (sender && strcmp(sender->human_readable_name,hdr->human_readable_name) != 0) { + strncpy(sender->human_readable_name, hdr->human_readable_name, CLUSTER_HUMAN_NAMELEN); + } + /* Add this node if it is new for us and the msg type is MEET. * In this stage we don't try to add the node with the right * flags, slaveof pointer, and so forth, as this details will be @@ -2260,8 +2278,15 @@ int clusterProcessPacket(clusterLink *link) { * IP/port of the node with the new one. */ if (sender) { serverLog(LL_VERBOSE, - "Handshake: we already know node %.40s, " - "updating the address if needed.", sender->name); + "Handshake: we already know node %.40s %s, " + "updating the address if needed.", sender->name, sender->human_readable_name); + + if (hdr->has_human_readable_name) { + setManualClusterNodeName(sender, hdr->human_readable_name); + } + else + setClusterNodeName(sender); + if (nodeUpdateAddressIfNeeded(sender,link,hdr)) { clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| @@ -2276,8 +2301,8 @@ int clusterProcessPacket(clusterLink *link) { /* First thing to do is replacing the random name with the * right node name if this was a handshake stage. */ clusterRenameNode(link->node, hdr->sender); - serverLog(LL_DEBUG,"Handshake with node %.40s completed.", - link->node->name); + serverLog(LL_DEBUG,"Handshake with node %.40s %s completed.", + link->node->name, link->node->human_readable_name); link->node->flags &= ~CLUSTER_NODE_HANDSHAKE; link->node->flags |= flags&(CLUSTER_NODE_MASTER|CLUSTER_NODE_SLAVE); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG); @@ -2287,8 +2312,8 @@ int clusterProcessPacket(clusterLink *link) { /* If the reply has a non matching node ID we * disconnect this node and set it as not having an associated * address. */ - serverLog(LL_DEBUG,"PONG contains mismatching sender ID. About node %.40s added %d ms ago, having flags %d", - link->node->name, + serverLog(LL_DEBUG,"PONG contains mismatching sender ID. About node %.40s %s added %d ms ago, having flags %d", + link->node->name, link->node->human_readable_name, (int)(now-(link->node->ctime)), link->node->flags); link->node->flags |= CLUSTER_NODE_NOADDR; @@ -2434,9 +2459,10 @@ int clusterProcessPacket(clusterLink *link) { senderConfigEpoch) { serverLog(LL_VERBOSE, - "Node %.40s has old slots configuration, sending " - "an UPDATE message about %.40s", - sender->name, server.cluster->slots[j]->name); + "Node %.40s %s has old slots configuration, sending " + "an UPDATE message about %.40s %s", + sender->name, sender->human_readable_name, + server.cluster->slots[j]->name, server.cluster->slots[j]->human_readable_name); clusterSendUpdate(sender->link, server.cluster->slots[j]); @@ -2624,8 +2650,8 @@ void clusterLinkConnectHandler(connection *conn) { /* Check if connection succeeded */ if (connGetState(conn) != CONN_STATE_CONNECTED) { - serverLog(LL_VERBOSE, "Connection with Node %.40s at %s:%d failed: %s", - node->name, node->ip, node->cport, + serverLog(LL_VERBOSE, "Connection with Node %.40s %s at %s:%d failed: %s", + node->name, node->human_readable_name, node->ip, node->cport, connGetLastError(conn)); freeClusterLink(link); return; @@ -2656,8 +2682,8 @@ void clusterLinkConnectHandler(connection *conn) { * normal PING packets. */ node->flags &= ~CLUSTER_NODE_MEET; - serverLog(LL_DEBUG,"Connecting with Node %.40s at %s:%d", - node->name, node->ip, node->cport); + serverLog(LL_DEBUG,"Connecting with Node %.40s %s at %s:%d", + node->name, node->human_readable_name, node->ip, node->cport); } /* Read data. Try to read the first field of the header first to check the @@ -2797,6 +2823,8 @@ void clusterBuildMessageHdr(clusterMsg *hdr, int type) { hdr->sig[3] = 'b'; hdr->type = htons(type); memcpy(hdr->sender,myself->name,CLUSTER_NAMELEN); + strncpy(hdr->human_readable_name,myself->human_readable_name,CLUSTER_HUMAN_NAMELEN); + hdr->has_human_readable_name = myself->has_human_readable_name; /* If cluster-announce-ip option is enabled, force the receivers of our * packets to use the specified address for this node. Otherwise if the @@ -2875,6 +2903,7 @@ void clusterSetGossipEntry(clusterMsg *hdr, int i, clusterNode *n) { gossip->cport = htons(n->cport); gossip->flags = htons(n->flags); gossip->pport = htons(n->pport); + gossip->has_human_readable_name = n->has_human_readable_name; gossip->notused1 = 0; } @@ -3299,8 +3328,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * request, if the request epoch was greater. */ if (requestCurrentEpoch < server.cluster->currentEpoch) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: reqEpoch (%llu) < curEpoch(%llu)", - node->name, + "Failover auth denied to %.40s %s: reqEpoch (%llu) < curEpoch(%llu)", + node->name, node->human_readable_name, (unsigned long long) requestCurrentEpoch, (unsigned long long) server.cluster->currentEpoch); return; @@ -3309,8 +3338,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { /* I already voted for this epoch? Return ASAP. */ if (server.cluster->lastVoteEpoch == server.cluster->currentEpoch) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: already voted for epoch %llu", - node->name, + "Failover auth denied to %.40s %s: already voted for epoch %llu", + node->name, node->human_readable_name, (unsigned long long) server.cluster->currentEpoch); return; } @@ -3323,16 +3352,16 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { { if (nodeIsMaster(node)) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: it is a master node", - node->name); + "Failover auth denied to %.40s %s: it is a master node", + node->name, node->human_readable_name); } else if (master == NULL) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: I don't know its master", - node->name); + "Failover auth denied to %.40s %s: I don't know its master", + node->name, node->human_readable_name); } else if (!nodeFailed(master)) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: its master is up", - node->name); + "Failover auth denied to %.40s %s: its master is up", + node->name, node->human_readable_name); } return; } @@ -3343,9 +3372,9 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { if (mstime() - node->slaveof->voted_time < server.cluster_node_timeout * 2) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: " + "Failover auth denied to %.40s %s: " "can't vote about this master before %lld milliseconds", - node->name, + node->name, node->human_readable_name, (long long) ((server.cluster_node_timeout*2)- (mstime() - node->slaveof->voted_time))); return; @@ -3365,9 +3394,9 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * is served by a master with a greater configEpoch than the one claimed * by the slave requesting our vote. Refuse to vote for this slave. */ serverLog(LL_WARNING, - "Failover auth denied to %.40s: " + "Failover auth denied to %.40s %s: " "slot %d epoch (%llu) > reqEpoch (%llu)", - node->name, j, + node->name, node->human_readable_name, j, (unsigned long long) server.cluster->slots[j]->configEpoch, (unsigned long long) requestConfigEpoch); return; @@ -3378,8 +3407,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { node->slaveof->voted_time = mstime(); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG|CLUSTER_TODO_FSYNC_CONFIG); clusterSendFailoverAuth(node); - serverLog(LL_WARNING, "Failover auth granted to %.40s for epoch %llu", - node->name, (unsigned long long) server.cluster->currentEpoch); + serverLog(LL_WARNING, "Failover auth granted to %.40s %s for epoch %llu", + node->name, node->human_readable_name, (unsigned long long) server.cluster->currentEpoch); } /* This function returns the "rank" of this instance, a slave, in the context @@ -3607,7 +3636,7 @@ void clusterHandleSlaveFailover(void) { if (server.cluster->mf_end) { server.cluster->failover_auth_time = mstime(); server.cluster->failover_auth_rank = 0; - clusterDoBeforeSleep(CLUSTER_TODO_HANDLE_FAILOVER); + clusterDoBeforeSleep(CLUSTER_TODO_HANDLE_FAILOVER); } serverLog(LL_WARNING, "Start of election delayed for %lld milliseconds " @@ -3796,8 +3825,8 @@ void clusterHandleSlaveMigration(int max_slaves) { (mstime()-target->orphaned_time) > CLUSTER_SLAVE_MIGRATION_DELAY && !(server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_FAILOVER)) { - serverLog(LL_WARNING,"Migrating to orphaned master %.40s", - target->name); + serverLog(LL_WARNING,"Migrating to orphaned master %.40s %s", + target->name, target->human_readable_name); clusterSetMaster(target); } } @@ -4044,7 +4073,7 @@ void clusterCron(void) { } } if (min_pong_node) { - serverLog(LL_DEBUG,"Pinging node %.40s", min_pong_node->name); + serverLog(LL_DEBUG,"Pinging node %.40s %s", min_pong_node->name, min_pong_node->human_readable_name); clusterSendPing(min_pong_node->link, CLUSTERMSG_TYPE_PING); } } @@ -4144,8 +4173,8 @@ void clusterCron(void) { /* Timeout reached. Set the node as possibly failing if it is * not already in this state. */ if (!(node->flags & (CLUSTER_NODE_PFAIL|CLUSTER_NODE_FAIL))) { - serverLog(LL_DEBUG,"*** NODE %.40s possibly failing", - node->name); + serverLog(LL_DEBUG,"*** NODE %.40s %s possibly failing", + node->name, node->human_readable_name); node->flags |= CLUSTER_NODE_PFAIL; update_state = 1; } @@ -4633,6 +4662,9 @@ sds clusterGenNodeDescription(clusterNode *node, int use_pport) { else ci = sdscatlen(ci,"-",1); + /* Adding has human readable name */ + ci = sdscatfmt(ci," %i",node->has_human_readable_name); + unsigned long long nodeEpoch = node->configEpoch; if (nodeIsSlave(node) && node->slaveof) { nodeEpoch = node->slaveof->configEpoch; @@ -5056,10 +5088,12 @@ void clusterCommand(client *c) { "MYID", " Return the node id.", "MYNAME", -" Return the node name.", +" Return the human readable node name.", +"SETNAME ", +" Sets the human-readable node name.", "NODES", " Return cluster configuration seen by node. Output format:", -" ...", +" ...", "REPLICATE ", " Configure current node as replica to .", "RESET [HARD|SOFT]", @@ -5122,11 +5156,17 @@ NULL /* CLUSTER MYID */ addReplyBulkCBuffer(c,myself->name, CLUSTER_NAMELEN); } else if (!strcasecmp(c->argv[1]->ptr,"myname") && c->argc == 2) { - /* CLUSTER MYID */ - if (myself->hname) - addReplyBulkCBuffer(c,myself->hname, strlen(myself->hname)); + /* CLUSTER MYNAME */ + if (myself->human_readable_name[0] != '\0') + addReplyBulkCBuffer(c,myself->human_readable_name, strlen(myself->human_readable_name)); else addReplyError(c,"Node is not assigned name yet."); + } else if (!strcasecmp(c->argv[1]->ptr,"setname") && c->argc == 3) { + /* CLUSTER SETNAME */ + if (setManualClusterNodeName(myself,c->argv[2]->ptr)) + addReply(c,shared.ok); + else + addReplyError(c,"Error setting the name of the node."); } else if (!strcasecmp(c->argv[1]->ptr,"slots") && c->argc == 2) { /* CLUSTER SLOTS */ clusterReplyMultiBulkSlots(c); diff --git a/src/cluster.h b/src/cluster.h index 1a8cace98ac..816591166d9 100644 --- a/src/cluster.h +++ b/src/cluster.h @@ -9,6 +9,7 @@ #define CLUSTER_OK 0 /* Everything looks ok */ #define CLUSTER_FAIL 1 /* The cluster can't work */ #define CLUSTER_NAMELEN 40 /* sha1 hex length */ +#define CLUSTER_HUMAN_NAMELEN 64 /* Max length of human readable node name */ #define CLUSTER_PORT_INCR 10000 /* Cluster port = baseport + PORT_INCR */ /* The following defines are amount of time, sometimes expressed as @@ -115,7 +116,7 @@ typedef struct clusterNodeFailReport { typedef struct clusterNode { mstime_t ctime; /* Node object creation time. */ char name[CLUSTER_NAMELEN]; /* Node name, hex string, sha1-size */ - char* hname; /* Human readable name for node */ + char human_readable_name[CLUSTER_HUMAN_NAMELEN]; /* Human readable name for node */ int flags; /* CLUSTER_NODE_... */ uint64_t configEpoch; /* Last configEpoch observed for this node */ unsigned char slots[CLUSTER_SLOTS/8]; /* slots handled by this node */ @@ -144,6 +145,7 @@ typedef struct clusterNode { clusterLink *link; /* TCP/IP link established toward this node */ clusterLink *inbound_link; /* TCP/IP link accepted from this node */ list *fail_reports; /* List of nodes signaling this as failing */ + int has_human_readable_name; /* Indicates whether custom nodename is used */ } clusterNode; /* Slot to keys for a single slot. The keys in the same slot are linked together @@ -217,11 +219,13 @@ typedef struct { uint32_t ping_sent; uint32_t pong_received; char ip[NET_IP_STR_LEN]; /* IP address last time it was seen */ + char human_readable_name[CLUSTER_HUMAN_NAMELEN]; /* Human readable name for node */ uint16_t port; /* base port last time it was seen */ uint16_t cport; /* cluster port last time it was seen */ uint16_t flags; /* node->flags copy */ uint16_t pport; /* plaintext-port, when base port is TLS */ uint16_t notused1; + int has_human_readable_name; /* Indicates whether custom nodename is used */ } clusterMsgDataGossip; typedef struct { @@ -321,6 +325,7 @@ typedef struct { unsigned char myslots[CLUSTER_SLOTS/8]; char slaveof[CLUSTER_NAMELEN]; char myip[NET_IP_STR_LEN]; /* Sender IP, if not all zeroed. */ + char human_readable_name[CLUSTER_HUMAN_NAMELEN]; uint16_t extensions; /* Number of extensions sent along with this packet. */ char notused1[30]; /* 30 bytes reserved for future usage. */ uint16_t pport; /* Sender TCP plaintext port, if base port is TLS */ @@ -329,6 +334,7 @@ typedef struct { unsigned char state; /* Cluster state from the POV of the sender */ unsigned char mflags[3]; /* Message flags: CLUSTERMSG_FLAG[012]_... */ union clusterMsgData data; + int has_human_readable_name; /* Indicates whether custom nodename is used */ } clusterMsg; /* clusterMsg defines the gossip wire protocol exchanged among Redis cluster diff --git a/src/redis-cli.c b/src/redis-cli.c index e4d0afe8359..987fdd252b1 100644 --- a/src/redis-cli.c +++ b/src/redis-cli.c @@ -4514,9 +4514,10 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, lines = p + 1; char *name = NULL, *addr = NULL, *flags = NULL, *master_id = NULL, *ping_sent = NULL, *ping_recv = NULL, *config_epoch = NULL, - *link_status = NULL, *hname = NULL; + *link_status = NULL, *human_readable_name = NULL, *has_human_readable_name = NULL; UNUSED(link_status); - UNUSED(hname); + UNUSED(human_readable_name); + UNUSED(has_human_readable_name); int i = 0; while ((p = strchr(line, ' ')) != NULL) { *p = '\0'; @@ -4524,16 +4525,17 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, line = p + 1; switch(i++){ case 0: name = token; break; - case 1: hname = token; break; + case 1: human_readable_name = token; break; case 2: addr = token; break; case 3: flags = token; break; case 4: master_id = token; break; - case 5: ping_sent = token; break; - case 6: ping_recv = token; break; - case 7: config_epoch = token; break; - case 8: link_status = token; break; + case 5: has_human_readable_name = token; break; + case 6: ping_sent = token; break; + case 7: ping_recv = token; break; + case 8: config_epoch = token; break; + case 9: link_status = token; break; } - if (i == 9) break; // Slots + if (i == 10) break; // Slots } if (!flags) { success = 0; @@ -4545,7 +4547,7 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, node->flags |= CLUSTER_MANAGER_FLAG_MYSELF; currentNode = node; clusterManagerNodeResetSlots(node); - if (i == 9) { + if (i == 10) { int remaining = strlen(line); while (remaining > 0) { p = strchr(line, ' '); diff --git a/tests/cluster/cluster.tcl b/tests/cluster/cluster.tcl index 379db48a5d0..4862021626e 100644 --- a/tests/cluster/cluster.tcl +++ b/tests/cluster/cluster.tcl @@ -22,11 +22,12 @@ proc get_cluster_nodes id { addr [lindex $args 2] \ flags [split [lindex $args 3] ,] \ slaveof [lindex $args 4] \ - ping_sent [lindex $args 5] \ - pong_recv [lindex $args 6] \ - config_epoch [lindex $args 7] \ - linkstate [lindex $args 8] \ - slots [lrange $args 9 end] \ + customName [lindex $args 5] \ + ping_sent [lindex $args 6] \ + pong_recv [lindex $args 7] \ + config_epoch [lindex $args 8] \ + linkstate [lindex $args 9] \ + slots [lrange $args 10 end] \ ] lappend nodes $node } diff --git a/tests/support/cluster.tcl b/tests/support/cluster.tcl index 8c628dcd3f1..2ead91f43d1 100644 --- a/tests/support/cluster.tcl +++ b/tests/support/cluster.tcl @@ -104,8 +104,8 @@ proc ::redis_cluster::__method__refresh_nodes_map {id} { set line [string trim $line] if {$line eq {}} continue set args [split $line " "] - lassign $args nodeid name addr flags slaveof pingsent pongrecv configepoch linkstate - set slots [lrange $args 9 end] + lassign $args nodeid name addr flags slaveof customname pingsent pongrecv configepoch linkstate + set slots [lrange $args 10 end] set addr [lindex [split $addr @] 0] if {$addr eq {:0}} { set addr $start_host:$start_port @@ -126,6 +126,7 @@ proc ::redis_cluster::__method__refresh_nodes_map {id} { port $port \ flags $flags \ slaveof $slaveof \ + customname $customname \ slots $slots \ link $link \ ] From 1f7a365deecc958962ab007aa4ba0dbb1e3153ad Mon Sep 17 00:00:00 2001 From: hwware Date: Wed, 12 Jan 2022 14:08:57 -0500 Subject: [PATCH 35/79] update codes to fix error in rebase --- src/cluster.c | 210 ++++++++++++-------------------------- src/cluster.h | 7 -- src/help.h | 5 - src/redis-cli.c | 26 ++--- tests/cluster/cluster.tcl | 18 ++-- tests/support/cluster.tcl | 5 +- 6 files changed, 85 insertions(+), 186 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index 07acec63223..51b54d10037 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -48,7 +48,6 @@ clusterNode *myself = NULL; clusterNode *createClusterNode(char *nodename, int flags); void clusterAddNode(clusterNode *node); -void setClusterNodeName(clusterNode *node); void clusterAcceptHandler(aeEventLoop *el, int fd, void *privdata, int mask); void clusterReadHandler(connection *conn); void clusterSendPing(clusterLink *link, int type); @@ -253,7 +252,7 @@ int clusterLoadConfig(char *filename) { * stored in nodes.conf. It is received later over the bus protocol. */ /* Parse flags */ - p = s = argv[3]; + p = s = argv[2]; while(p) { p = strchr(s,','); if (p) *p = '\0'; @@ -286,28 +285,25 @@ int clusterLoadConfig(char *filename) { /* Get master if any. Set the master and populate master's * slave list. */ - if (argv[4][0] != '-') { - master = clusterLookupNode(argv[4]); + if (argv[3][0] != '-') { + master = clusterLookupNode(argv[3]); if (!master) { - master = createClusterNode(argv[4],0); + master = createClusterNode(argv[3],0); clusterAddNode(master); } n->slaveof = master; clusterNodeAddSlave(master,n); } - /* Custom nodename */ - n->has_human_readable_name = atoi(argv[5]); - /* Set ping sent / pong received timestamps */ - if (atoi(argv[6])) n->ping_sent = mstime(); - if (atoi(argv[7])) n->pong_received = mstime(); + if (atoi(argv[4])) n->ping_sent = mstime(); + if (atoi(argv[5])) n->pong_received = mstime(); /* Set configEpoch for this node. */ - n->configEpoch = strtoull(argv[8],NULL,10); + n->configEpoch = strtoull(argv[6],NULL,10); /* Populate hash slots served by this instance. */ - for (j = 10; j < argc; j++) { + for (j = 8; j < argc; j++) { int start, stop; if (argv[j][0] == '[') { @@ -361,7 +357,7 @@ int clusterLoadConfig(char *filename) { zfree(line); fclose(fp); - serverLog(LL_NOTICE,"Node configuration loaded, I'm %.40s %s", myself->name, myself->human_readable_name); + serverLog(LL_NOTICE,"Node configuration loaded, I'm %.40s", myself->name); /* Something that should never happen: currentEpoch smaller than * the max epoch found in the nodes configuration. However we handle this @@ -633,8 +629,8 @@ void clusterInit(void) { * by the createClusterNode() function. */ myself = server.cluster->myself = createClusterNode(NULL,CLUSTER_NODE_MYSELF|CLUSTER_NODE_MASTER); - serverLog(LL_NOTICE,"No cluster configuration found, I'm %.40s %s", - myself->name, myself->human_readable_name); + serverLog(LL_NOTICE,"No cluster configuration found, I'm %.40s", + myself->name); clusterAddNode(myself); saveconf = 1; } @@ -741,7 +737,7 @@ void clusterReset(int hard) { sdsfree(oldname); getRandomHexChars(myself->name, CLUSTER_NAMELEN); clusterAddNode(myself); - serverLog(LL_NOTICE,"Node hard reset, now I'm %.40s %s", myself->name, myself->human_readable_name); + serverLog(LL_NOTICE,"Node hard reset, now I'm %.40s", myself->name); } /* Make sure to persist the new config and update the state. */ @@ -928,25 +924,6 @@ unsigned int keyHashSlot(char *key, int keylen) { * CLUSTER node API * -------------------------------------------------------------------------- */ -/* Assign a human readable name to nodes for clusters*/ -void setClusterNodeName(clusterNode *node) { - if (node->has_human_readable_name == 1) - return; - char ip[NET_IP_STR_LEN]; - strcpy(ip,node->ip); - sprintf(node->human_readable_name, "%s_%u", ip,(unsigned int)node->port); -} - -/* Manually assign a human readable name to nodes for clusters*/ -int setManualClusterNodeName(clusterNode *node, char * newname) { - if (newname == NULL) - return 0; - memcpy(node->human_readable_name, newname, strlen(newname) + 1); - node->has_human_readable_name = 1; - clusterSaveConfig(1); - return 1; -} - /* Create a new cluster node, with the specified flags. * If "nodename" is NULL this is considered a first handshake and a random * node name is assigned to this node (it will be fixed later when we'll @@ -967,7 +944,6 @@ clusterNode *createClusterNode(char *nodename, int flags) { memset(node->slots,0,sizeof(node->slots)); node->slots_info = NULL; node->numslots = 0; - node->has_human_readable_name = 0; node->numslaves = 0; node->slaves = NULL; node->slaveof = NULL; @@ -1210,17 +1186,6 @@ clusterNode *clusterLookupNode(const char *name) { de = dictFind(server.cluster->nodes,s); sdsfree(s); if (de == NULL) { - /* Check if any node has the same human readable name*/ - dictIterator *di; - dictEntry *de2; - - di = dictGetSafeIterator(server.cluster->nodes); - while((de2 = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de2); - if (strcmp(node->human_readable_name,name) == 0) - return node; - } - dictReleaseIterator(di); return NULL; } return dictGetVal(de); @@ -1380,9 +1345,9 @@ void clusterHandleConfigEpochCollision(clusterNode *sender) { myself->configEpoch = server.cluster->currentEpoch; clusterSaveConfigOrDie(1); serverLog(LL_VERBOSE, - "WARNING: configEpoch collision with node %.40s %s." + "WARNING: configEpoch collision with node %.40s." " configEpoch set to %llu", - sender->name, sender->human_readable_name, + sender->name, (unsigned long long) myself->configEpoch); } @@ -1498,7 +1463,7 @@ void markNodeAsFailingIfNeeded(clusterNode *node) { if (failures < needed_quorum) return; /* No weak agreement from masters. */ serverLog(LL_NOTICE, - "Marking node %.40s %s as failing (quorum reached).", node->name, node ->human_readable_name); + "Marking node %.40s as failing (quorum reached).", node->name); /* Mark the node as failing. */ node->flags &= ~CLUSTER_NODE_PFAIL; @@ -1526,8 +1491,8 @@ void clearNodeFailureIfNeeded(clusterNode *node) { * node again. */ if (nodeIsSlave(node) || node->numslots == 0) { serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s %s: %s is reachable again.", - node->name, node->human_readable_name, + "Clear FAIL state for node %.40s : %s is reachable again.", + node->name, nodeIsSlave(node) ? "replica" : "master without slots"); node->flags &= ~CLUSTER_NODE_FAIL; clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); @@ -1542,8 +1507,8 @@ void clearNodeFailureIfNeeded(clusterNode *node) { (server.cluster_node_timeout * CLUSTER_FAIL_UNDO_TIME_MULT)) { serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s %s: is reachable again and nobody is serving its slots after some time.", - node->name, node->human_readable_name); + "Clear FAIL state for node %.40s : is reachable again and nobody is serving its slots after some time.", + node->name); node->flags &= ~CLUSTER_NODE_FAIL; clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); } @@ -1625,7 +1590,6 @@ int clusterStartHandshake(char *ip, int port, int cport) { memcpy(n->ip,norm_ip,sizeof(n->ip)); n->port = port; n->cport = cport; - setClusterNodeName(n); clusterAddNode(n); return 1; } @@ -1664,15 +1628,15 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { if (flags & (CLUSTER_NODE_FAIL|CLUSTER_NODE_PFAIL)) { if (clusterNodeAddFailureReport(node,sender)) { serverLog(LL_VERBOSE, - "Node %.40s %s reported node %.40s %s as not reachable.", - sender->name, sender->human_readable_name, node->name, node->human_readable_name); + "Node %.40s reported node %.40s as not reachable.", + sender->name, node->name); } markNodeAsFailingIfNeeded(node); } else { if (clusterNodeDelFailureReport(node,sender)) { serverLog(LL_VERBOSE, - "Node %.40s %s reported node %.40s %s is back online.", - sender->name, sender->human_readable_name, node->name, node->human_readable_name); + "Node %.40s reported node %.40s is back online.", + sender->name, node->name); } } } @@ -1717,10 +1681,6 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { node->pport = ntohs(g->pport); node->cport = ntohs(g->cport); node->flags &= ~CLUSTER_NODE_NOADDR; - if (hdr->has_human_readable_name) - setManualClusterNodeName(node, hdr->human_readable_name); - else - setClusterNodeName(node); } } else { /* If it's not in NOADDR state and we don't have it, we @@ -1742,10 +1702,6 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { node->port = ntohs(g->port); node->pport = ntohs(g->pport); node->cport = ntohs(g->cport); - if (hdr->has_human_readable_name) - setManualClusterNodeName(node, hdr->human_readable_name); - else - setClusterNodeName(node); clusterAddNode(node); } } @@ -1804,14 +1760,10 @@ int nodeUpdateAddressIfNeeded(clusterNode *node, clusterLink *link, node->port = port; node->pport = pport; node->cport = cport; - if (hdr->has_human_readable_name) - setManualClusterNodeName(node, hdr->human_readable_name); - else - setClusterNodeName(node); if (node->link) freeClusterLink(node->link); node->flags &= ~CLUSTER_NODE_NOADDR; - serverLog(LL_WARNING,"Address updated for node %.40s %s, now %s:%d", - node->name, node->human_readable_name, node->ip, node->port); + serverLog(LL_WARNING,"Address updated for node %.40s , now %s:%d", + node->name, node->ip, node->port); /* Check if this is our master and we have to change the * replication target as well. */ @@ -1940,7 +1892,7 @@ void clusterUpdateSlotsConfigWith(clusterNode *sender, uint64_t senderConfigEpoc sender_slots == migrated_our_slots)) { serverLog(LL_WARNING, "Configuration change detected. Reconfiguring myself " - "as a replica of %.40s %s", sender->name, sender->human_readable_name); + "as a replica of %.40s ", sender->name); clusterSetMaster(sender); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| CLUSTER_TODO_UPDATE_STATE| @@ -2227,17 +2179,12 @@ int clusterProcessPacket(clusterLink *link) { strcmp(ip,myself->ip)) { memcpy(myself->ip,ip,NET_IP_STR_LEN); - setClusterNodeName(myself); serverLog(LL_WARNING,"IP address for this node updated to %s", myself->ip); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG); } } - if (sender && strcmp(sender->human_readable_name,hdr->human_readable_name) != 0) { - strncpy(sender->human_readable_name, hdr->human_readable_name, CLUSTER_HUMAN_NAMELEN); - } - /* Add this node if it is new for us and the msg type is MEET. * In this stage we don't try to add the node with the right * flags, slaveof pointer, and so forth, as this details will be @@ -2250,7 +2197,6 @@ int clusterProcessPacket(clusterLink *link) { node->port = ntohs(hdr->port); node->pport = ntohs(hdr->pport); node->cport = ntohs(hdr->cport); - setClusterNodeName(node); clusterAddNode(node); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG); } @@ -2278,14 +2224,8 @@ int clusterProcessPacket(clusterLink *link) { * IP/port of the node with the new one. */ if (sender) { serverLog(LL_VERBOSE, - "Handshake: we already know node %.40s %s, " - "updating the address if needed.", sender->name, sender->human_readable_name); - - if (hdr->has_human_readable_name) { - setManualClusterNodeName(sender, hdr->human_readable_name); - } - else - setClusterNodeName(sender); + "Handshake: we already know node %.40s , " + "updating the address if needed.", sender->name); if (nodeUpdateAddressIfNeeded(sender,link,hdr)) { @@ -2301,8 +2241,8 @@ int clusterProcessPacket(clusterLink *link) { /* First thing to do is replacing the random name with the * right node name if this was a handshake stage. */ clusterRenameNode(link->node, hdr->sender); - serverLog(LL_DEBUG,"Handshake with node %.40s %s completed.", - link->node->name, link->node->human_readable_name); + serverLog(LL_DEBUG,"Handshake with node %.40s completed.", + link->node->name); link->node->flags &= ~CLUSTER_NODE_HANDSHAKE; link->node->flags |= flags&(CLUSTER_NODE_MASTER|CLUSTER_NODE_SLAVE); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG); @@ -2312,8 +2252,8 @@ int clusterProcessPacket(clusterLink *link) { /* If the reply has a non matching node ID we * disconnect this node and set it as not having an associated * address. */ - serverLog(LL_DEBUG,"PONG contains mismatching sender ID. About node %.40s %s added %d ms ago, having flags %d", - link->node->name, link->node->human_readable_name, + serverLog(LL_DEBUG,"PONG contains mismatching sender ID. About node %.40s added %d ms ago, having flags %d", + link->node->name, (int)(now-(link->node->ctime)), link->node->flags); link->node->flags |= CLUSTER_NODE_NOADDR; @@ -2459,10 +2399,10 @@ int clusterProcessPacket(clusterLink *link) { senderConfigEpoch) { serverLog(LL_VERBOSE, - "Node %.40s %s has old slots configuration, sending " - "an UPDATE message about %.40s %s", - sender->name, sender->human_readable_name, - server.cluster->slots[j]->name, server.cluster->slots[j]->human_readable_name); + "Node %.40s has old slots configuration, sending " + "an UPDATE message about %.40s ", + sender->name, + server.cluster->slots[j]->name); clusterSendUpdate(sender->link, server.cluster->slots[j]); @@ -2650,8 +2590,8 @@ void clusterLinkConnectHandler(connection *conn) { /* Check if connection succeeded */ if (connGetState(conn) != CONN_STATE_CONNECTED) { - serverLog(LL_VERBOSE, "Connection with Node %.40s %s at %s:%d failed: %s", - node->name, node->human_readable_name, node->ip, node->cport, + serverLog(LL_VERBOSE, "Connection with Node %.40s at %s:%d failed: %s", + node->name, node->ip, node->cport, connGetLastError(conn)); freeClusterLink(link); return; @@ -2682,8 +2622,8 @@ void clusterLinkConnectHandler(connection *conn) { * normal PING packets. */ node->flags &= ~CLUSTER_NODE_MEET; - serverLog(LL_DEBUG,"Connecting with Node %.40s %s at %s:%d", - node->name, node->human_readable_name, node->ip, node->cport); + serverLog(LL_DEBUG,"Connecting with Node %.40s at %s:%d", + node->name, node->ip, node->cport); } /* Read data. Try to read the first field of the header first to check the @@ -2823,9 +2763,7 @@ void clusterBuildMessageHdr(clusterMsg *hdr, int type) { hdr->sig[3] = 'b'; hdr->type = htons(type); memcpy(hdr->sender,myself->name,CLUSTER_NAMELEN); - strncpy(hdr->human_readable_name,myself->human_readable_name,CLUSTER_HUMAN_NAMELEN); - hdr->has_human_readable_name = myself->has_human_readable_name; - + /* If cluster-announce-ip option is enabled, force the receivers of our * packets to use the specified address for this node. Otherwise if the * first byte is zero, they'll do auto discovery. */ @@ -2903,7 +2841,6 @@ void clusterSetGossipEntry(clusterMsg *hdr, int i, clusterNode *n) { gossip->cport = htons(n->cport); gossip->flags = htons(n->flags); gossip->pport = htons(n->pport); - gossip->has_human_readable_name = n->has_human_readable_name; gossip->notused1 = 0; } @@ -3328,8 +3265,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * request, if the request epoch was greater. */ if (requestCurrentEpoch < server.cluster->currentEpoch) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: reqEpoch (%llu) < curEpoch(%llu)", - node->name, node->human_readable_name, + "Failover auth denied to %.40s : reqEpoch (%llu) < curEpoch(%llu)", + node->name, (unsigned long long) requestCurrentEpoch, (unsigned long long) server.cluster->currentEpoch); return; @@ -3338,8 +3275,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { /* I already voted for this epoch? Return ASAP. */ if (server.cluster->lastVoteEpoch == server.cluster->currentEpoch) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: already voted for epoch %llu", - node->name, node->human_readable_name, + "Failover auth denied to %.40s : already voted for epoch %llu", + node->name, (unsigned long long) server.cluster->currentEpoch); return; } @@ -3352,16 +3289,16 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { { if (nodeIsMaster(node)) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: it is a master node", - node->name, node->human_readable_name); + "Failover auth denied to %.40s : it is a master node", + node->name); } else if (master == NULL) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: I don't know its master", - node->name, node->human_readable_name); + "Failover auth denied to %.40s : I don't know its master", + node->name); } else if (!nodeFailed(master)) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: its master is up", - node->name, node->human_readable_name); + "Failover auth denied to %.40s : its master is up", + node->name); } return; } @@ -3372,9 +3309,9 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { if (mstime() - node->slaveof->voted_time < server.cluster_node_timeout * 2) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: " + "Failover auth denied to %.40s : " "can't vote about this master before %lld milliseconds", - node->name, node->human_readable_name, + node->name, (long long) ((server.cluster_node_timeout*2)- (mstime() - node->slaveof->voted_time))); return; @@ -3394,9 +3331,9 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * is served by a master with a greater configEpoch than the one claimed * by the slave requesting our vote. Refuse to vote for this slave. */ serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: " + "Failover auth denied to %.40s : " "slot %d epoch (%llu) > reqEpoch (%llu)", - node->name, node->human_readable_name, j, + node->name, j, (unsigned long long) server.cluster->slots[j]->configEpoch, (unsigned long long) requestConfigEpoch); return; @@ -3407,8 +3344,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { node->slaveof->voted_time = mstime(); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG|CLUSTER_TODO_FSYNC_CONFIG); clusterSendFailoverAuth(node); - serverLog(LL_WARNING, "Failover auth granted to %.40s %s for epoch %llu", - node->name, node->human_readable_name, (unsigned long long) server.cluster->currentEpoch); + serverLog(LL_WARNING, "Failover auth granted to %.40s for epoch %llu", + node->name, (unsigned long long) server.cluster->currentEpoch); } /* This function returns the "rank" of this instance, a slave, in the context @@ -3825,8 +3762,8 @@ void clusterHandleSlaveMigration(int max_slaves) { (mstime()-target->orphaned_time) > CLUSTER_SLAVE_MIGRATION_DELAY && !(server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_FAILOVER)) { - serverLog(LL_WARNING,"Migrating to orphaned master %.40s %s", - target->name, target->human_readable_name); + serverLog(LL_WARNING,"Migrating to orphaned master %.40s ", + target->name); clusterSetMaster(target); } } @@ -4073,7 +4010,7 @@ void clusterCron(void) { } } if (min_pong_node) { - serverLog(LL_DEBUG,"Pinging node %.40s %s", min_pong_node->name, min_pong_node->human_readable_name); + serverLog(LL_DEBUG,"Pinging node %.40s ", min_pong_node->name); clusterSendPing(min_pong_node->link, CLUSTERMSG_TYPE_PING); } } @@ -4173,8 +4110,8 @@ void clusterCron(void) { /* Timeout reached. Set the node as possibly failing if it is * not already in this state. */ if (!(node->flags & (CLUSTER_NODE_PFAIL|CLUSTER_NODE_FAIL))) { - serverLog(LL_DEBUG,"*** NODE %.40s %s possibly failing", - node->name, node->human_readable_name); + serverLog(LL_DEBUG,"*** NODE %.40s possibly failing", + node->name); node->flags |= CLUSTER_NODE_PFAIL; update_state = 1; } @@ -4660,10 +4597,7 @@ sds clusterGenNodeDescription(clusterNode *node, int use_pport) { if (node->slaveof) ci = sdscatlen(ci,node->slaveof->name,CLUSTER_NAMELEN); else - ci = sdscatlen(ci,"-",1); - - /* Adding has human readable name */ - ci = sdscatfmt(ci," %i",node->has_human_readable_name); + ci = sdscatlen(ci,"-",1); unsigned long long nodeEpoch = node->configEpoch; if (nodeIsSlave(node) && node->slaveof) { @@ -5087,13 +5021,9 @@ void clusterCommand(client *c) { " Connect nodes into a working cluster.", "MYID", " Return the node id.", -"MYNAME", -" Return the human readable node name.", -"SETNAME ", -" Sets the human-readable node name.", "NODES", " Return cluster configuration seen by node. Output format:", -" ...", +" ...", "REPLICATE ", " Configure current node as replica to .", "RESET [HARD|SOFT]", @@ -5155,18 +5085,6 @@ NULL } else if (!strcasecmp(c->argv[1]->ptr,"myid") && c->argc == 2) { /* CLUSTER MYID */ addReplyBulkCBuffer(c,myself->name, CLUSTER_NAMELEN); - } else if (!strcasecmp(c->argv[1]->ptr,"myname") && c->argc == 2) { - /* CLUSTER MYNAME */ - if (myself->human_readable_name[0] != '\0') - addReplyBulkCBuffer(c,myself->human_readable_name, strlen(myself->human_readable_name)); - else - addReplyError(c,"Node is not assigned name yet."); - } else if (!strcasecmp(c->argv[1]->ptr,"setname") && c->argc == 3) { - /* CLUSTER SETNAME */ - if (setManualClusterNodeName(myself,c->argv[2]->ptr)) - addReply(c,shared.ok); - else - addReplyError(c,"Error setting the name of the node."); } else if (!strcasecmp(c->argv[1]->ptr,"slots") && c->argc == 2) { /* CLUSTER SLOTS */ clusterReplyMultiBulkSlots(c); diff --git a/src/cluster.h b/src/cluster.h index 816591166d9..314b747bea4 100644 --- a/src/cluster.h +++ b/src/cluster.h @@ -9,7 +9,6 @@ #define CLUSTER_OK 0 /* Everything looks ok */ #define CLUSTER_FAIL 1 /* The cluster can't work */ #define CLUSTER_NAMELEN 40 /* sha1 hex length */ -#define CLUSTER_HUMAN_NAMELEN 64 /* Max length of human readable node name */ #define CLUSTER_PORT_INCR 10000 /* Cluster port = baseport + PORT_INCR */ /* The following defines are amount of time, sometimes expressed as @@ -116,7 +115,6 @@ typedef struct clusterNodeFailReport { typedef struct clusterNode { mstime_t ctime; /* Node object creation time. */ char name[CLUSTER_NAMELEN]; /* Node name, hex string, sha1-size */ - char human_readable_name[CLUSTER_HUMAN_NAMELEN]; /* Human readable name for node */ int flags; /* CLUSTER_NODE_... */ uint64_t configEpoch; /* Last configEpoch observed for this node */ unsigned char slots[CLUSTER_SLOTS/8]; /* slots handled by this node */ @@ -145,7 +143,6 @@ typedef struct clusterNode { clusterLink *link; /* TCP/IP link established toward this node */ clusterLink *inbound_link; /* TCP/IP link accepted from this node */ list *fail_reports; /* List of nodes signaling this as failing */ - int has_human_readable_name; /* Indicates whether custom nodename is used */ } clusterNode; /* Slot to keys for a single slot. The keys in the same slot are linked together @@ -219,13 +216,11 @@ typedef struct { uint32_t ping_sent; uint32_t pong_received; char ip[NET_IP_STR_LEN]; /* IP address last time it was seen */ - char human_readable_name[CLUSTER_HUMAN_NAMELEN]; /* Human readable name for node */ uint16_t port; /* base port last time it was seen */ uint16_t cport; /* cluster port last time it was seen */ uint16_t flags; /* node->flags copy */ uint16_t pport; /* plaintext-port, when base port is TLS */ uint16_t notused1; - int has_human_readable_name; /* Indicates whether custom nodename is used */ } clusterMsgDataGossip; typedef struct { @@ -325,7 +320,6 @@ typedef struct { unsigned char myslots[CLUSTER_SLOTS/8]; char slaveof[CLUSTER_NAMELEN]; char myip[NET_IP_STR_LEN]; /* Sender IP, if not all zeroed. */ - char human_readable_name[CLUSTER_HUMAN_NAMELEN]; uint16_t extensions; /* Number of extensions sent along with this packet. */ char notused1[30]; /* 30 bytes reserved for future usage. */ uint16_t pport; /* Sender TCP plaintext port, if base port is TLS */ @@ -334,7 +328,6 @@ typedef struct { unsigned char state; /* Cluster state from the POV of the sender */ unsigned char mflags[3]; /* Message flags: CLUSTERMSG_FLAG[012]_... */ union clusterMsgData data; - int has_human_readable_name; /* Indicates whether custom nodename is used */ } clusterMsg; /* clusterMsg defines the gossip wire protocol exchanged among Redis cluster diff --git a/src/help.h b/src/help.h index 73b6234f748..56368c57106 100644 --- a/src/help.h +++ b/src/help.h @@ -364,11 +364,6 @@ struct commandHelp { "Return the node id", 12, "3.0.0" }, - { "CLUSTER MYID", - "", - "Return the node id", - 12, - "3.0.0" }, { "CLUSTER NODES", "", "Get Cluster config for the node", diff --git a/src/redis-cli.c b/src/redis-cli.c index 987fdd252b1..bbbe6d6ece8 100644 --- a/src/redis-cli.c +++ b/src/redis-cli.c @@ -4514,10 +4514,8 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, lines = p + 1; char *name = NULL, *addr = NULL, *flags = NULL, *master_id = NULL, *ping_sent = NULL, *ping_recv = NULL, *config_epoch = NULL, - *link_status = NULL, *human_readable_name = NULL, *has_human_readable_name = NULL; + *link_status = NULL; UNUSED(link_status); - UNUSED(human_readable_name); - UNUSED(has_human_readable_name); int i = 0; while ((p = strchr(line, ' ')) != NULL) { *p = '\0'; @@ -4525,17 +4523,15 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, line = p + 1; switch(i++){ case 0: name = token; break; - case 1: human_readable_name = token; break; - case 2: addr = token; break; - case 3: flags = token; break; - case 4: master_id = token; break; - case 5: has_human_readable_name = token; break; - case 6: ping_sent = token; break; - case 7: ping_recv = token; break; - case 8: config_epoch = token; break; - case 9: link_status = token; break; - } - if (i == 10) break; // Slots + case 1: addr = token; break; + case 2: flags = token; break; + case 3: master_id = token; break; + case 4: ping_sent = token; break; + case 5: ping_recv = token; break; + case 6: config_epoch = token; break; + case 7: link_status = token; break; + } + if (i == 8) break; // Slots } if (!flags) { success = 0; @@ -4547,7 +4543,7 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, node->flags |= CLUSTER_MANAGER_FLAG_MYSELF; currentNode = node; clusterManagerNodeResetSlots(node); - if (i == 10) { + if (i == 8) { int remaining = strlen(line); while (remaining > 0) { p = strchr(line, ' '); diff --git a/tests/cluster/cluster.tcl b/tests/cluster/cluster.tcl index 4862021626e..531e90d6ca4 100644 --- a/tests/cluster/cluster.tcl +++ b/tests/cluster/cluster.tcl @@ -18,16 +18,14 @@ proc get_cluster_nodes id { set args [split $l] set node [dict create \ id [lindex $args 0] \ - name [lindex $args 1] \ - addr [lindex $args 2] \ - flags [split [lindex $args 3] ,] \ - slaveof [lindex $args 4] \ - customName [lindex $args 5] \ - ping_sent [lindex $args 6] \ - pong_recv [lindex $args 7] \ - config_epoch [lindex $args 8] \ - linkstate [lindex $args 9] \ - slots [lrange $args 10 end] \ + addr [lindex $args 1] \ + flags [split [lindex $args 2] ,] \ + slaveof [lindex $args 3] \ + ping_sent [lindex $args 4] \ + pong_recv [lindex $args 5] \ + config_epoch [lindex $args 6] \ + linkstate [lindex $args 7] \ + slots [lrange $args 8 end] \ ] lappend nodes $node } diff --git a/tests/support/cluster.tcl b/tests/support/cluster.tcl index 2ead91f43d1..081ef6a9522 100644 --- a/tests/support/cluster.tcl +++ b/tests/support/cluster.tcl @@ -104,8 +104,8 @@ proc ::redis_cluster::__method__refresh_nodes_map {id} { set line [string trim $line] if {$line eq {}} continue set args [split $line " "] - lassign $args nodeid name addr flags slaveof customname pingsent pongrecv configepoch linkstate - set slots [lrange $args 10 end] + lassign $args nodeid addr flags slaveof pingsent pongrecv configepoch linkstate + set slots [lrange $args 8 end] set addr [lindex [split $addr @] 0] if {$addr eq {:0}} { set addr $start_host:$start_port @@ -126,7 +126,6 @@ proc ::redis_cluster::__method__refresh_nodes_map {id} { port $port \ flags $flags \ slaveof $slaveof \ - customname $customname \ slots $slots \ link $link \ ] From 913c6d5c630bd460ba1960aaacad4754c4d1ad33 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Wed, 19 Jan 2022 14:52:26 -0500 Subject: [PATCH 36/79] Added nodename support to extension (#61) * Added nodename extension --- src/cluster.c | 154 +++++++++++++++++++++++++++++++++++++++++--------- src/cluster.h | 8 +++ src/config.c | 8 +++ src/server.h | 2 + 4 files changed, 146 insertions(+), 26 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index 51b54d10037..d4c10fcec41 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -216,7 +216,7 @@ int clusterLoadConfig(char *filename) { clusterAddNode(n); } /* Format for the node address information: - * ip:port[@cport][,hostname] */ + * ip:port[@cport][,hostname][-nodename] */ /* Address and port */ if ((p = strrchr(argv[1],':')) == NULL) { @@ -247,6 +247,16 @@ int clusterLoadConfig(char *filename) { } else if (sdslen(n->hostname) != 0) { sdsclear(n->hostname); } + /* Nodename is an optional argument */ + char *nodename = strchr(p, '-'); + if (nodename) { + *nodename = '\0'; + nodename++; + zfree(n->nodename); + n->nodename = zstrdup(nodename); + } else { + n->nodename = NULL; + } /* The plaintext port for client in a TLS cluster (n->pport) is not * stored in nodes.conf. It is received later over the bus protocol. */ @@ -581,12 +591,36 @@ static void updateAnnouncedHostname(clusterNode *node, char *new) { } } +/* Update the nodename for the specified node with the provided C string. */ +static void updateAnnouncedNodename(clusterNode *node, char *new) { + if (!node->nodename && !new) { + return; + } + + /* Previous and new nodename are the same, no need to update. */ + if (new && node->nodename && !strcmp(new, node->nodename)) { + return; + } + + if (node->nodename) zfree(node->nodename); + if (new) { + node->nodename = zstrdup(new); + } else { + node->nodename = NULL; + } +} + /* Update my hostname based on server configuration values */ void clusterUpdateMyselfHostname(void) { if (!myself) return; updateAnnouncedHostname(myself, server.cluster_announce_hostname); } +void clusterUpdateMyselfNodename(void) { + if (!myself) return; + updateAnnouncedNodename(myself, server.cluster_announce_nodename); +} + void clusterInit(void) { int saveconf = 0; @@ -681,6 +715,7 @@ void clusterInit(void) { clusterUpdateMyselfFlags(); clusterUpdateMyselfIp(); clusterUpdateMyselfHostname(); + clusterUpdateMyselfNodename(); } /* Reset a node performing a soft or hard reset: @@ -954,6 +989,7 @@ clusterNode *createClusterNode(char *nodename, int flags) { node->inbound_link = NULL; memset(node->ip,0,sizeof(node->ip)); node->hostname = sdsempty(); + node->nodename = NULL; node->port = 0; node->cport = 0; node->pport = 0; @@ -1120,6 +1156,7 @@ void freeClusterNode(clusterNode *n) { serverAssert(dictDelete(server.cluster->nodes,nodename) == DICT_OK); sdsfree(nodename); sdsfree(n->hostname); + zfree(n->nodename); /* Release links and associated data structures. */ if (n->link) freeClusterLink(n->link); @@ -1347,7 +1384,7 @@ void clusterHandleConfigEpochCollision(clusterNode *sender) { serverLog(LL_VERBOSE, "WARNING: configEpoch collision with node %.40s." " configEpoch set to %llu", - sender->name, + sender->name, (unsigned long long) myself->configEpoch); } @@ -1491,8 +1528,8 @@ void clearNodeFailureIfNeeded(clusterNode *node) { * node again. */ if (nodeIsSlave(node) || node->numslots == 0) { serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s : %s is reachable again.", - node->name, + "Clear FAIL state for node %.40s: %s is reachable again.", + node->name, nodeIsSlave(node) ? "replica" : "master without slots"); node->flags &= ~CLUSTER_NODE_FAIL; clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); @@ -1507,7 +1544,7 @@ void clearNodeFailureIfNeeded(clusterNode *node) { (server.cluster_node_timeout * CLUSTER_FAIL_UNDO_TIME_MULT)) { serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s : is reachable again and nobody is serving its slots after some time.", + "Clear FAIL state for node %.40s: is reachable again and nobody is serving its slots after some time.", node->name); node->flags &= ~CLUSTER_NODE_FAIL; clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); @@ -1629,7 +1666,7 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { if (clusterNodeAddFailureReport(node,sender)) { serverLog(LL_VERBOSE, "Node %.40s reported node %.40s as not reachable.", - sender->name, node->name); + sender->name, node->name); } markNodeAsFailingIfNeeded(node); } else { @@ -1892,7 +1929,7 @@ void clusterUpdateSlotsConfigWith(clusterNode *sender, uint64_t senderConfigEpoc sender_slots == migrated_our_slots)) { serverLog(LL_WARNING, "Configuration change detected. Reconfiguring myself " - "as a replica of %.40s ", sender->name); + "as a replica of %.40s", sender->name); clusterSetMaster(sender); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| CLUSTER_TODO_UPDATE_STATE| @@ -1949,6 +1986,16 @@ int getHostnamePingExtSize() { return totlen; } +/* Returns the exact size needed to store the nodename. The returned value + * will be 8 byte padded. */ +int getNodenamePingExtSize() { + /* If nodename is not set, we don't send this extension */ + if (!myself->nodename) return 0; + + int totlen = sizeof(clusterMsgPingExt) + EIGHT_BYTE_ALIGN(strlen(myself->nodename) + 1); + return totlen; +} + /* Write the hostname ping extension at the start of the cursor. This function * will update the cursor to point to the end of the written extension and * will return the amount of bytes written. */ @@ -1969,19 +2016,44 @@ int writeHostnamePingExt(clusterMsgPingExt **cursor) { return extension_size; } +/* Write the nodename ping extension at the start of the cursor. This function + * will update the cursor to point to the end of the written extension and + * will return the amount of bytes written. */ +int writeNodenamePingExt(clusterMsgPingExt **cursor) { + /* If nodename is not set, we don't send this extension */ + if (!myself->nodename) return 0; + + /* Add the nodename information at the extension cursor */ + clusterMsgPingExtNodename *ext = &(*cursor)->ext[1].nodename; + size_t nodename_len = strlen(myself->nodename); + memcpy(ext->nodename, myself->nodename, nodename_len); + uint32_t extension_size = getNodenamePingExtSize(); + + /* Move the write cursor */ + (*cursor)->type = CLUSTERMSG_EXT_TYPE_NODENAME; + (*cursor)->length = htonl(extension_size); + /* Make sure the string is NULL terminated by adding 1 */ + *cursor = (clusterMsgPingExt *) (ext->nodename + EIGHT_BYTE_ALIGN(strlen(myself->nodename) + 1)); + return extension_size; +} + /* We previously validated the extensions, so this function just needs to * handle the extensions. */ void clusterProcessPingExtensions(clusterMsg *hdr, clusterLink *link) { clusterNode *sender = link->node ? link->node : clusterLookupNode(hdr->sender); char *ext_hostname = NULL; + char *ext_nodename = NULL; uint16_t extensions = ntohs(hdr->extensions); /* Loop through all the extensions and process them */ clusterMsgPingExt *ext = getInitialPingExt(hdr, ntohs(hdr->count)); while (extensions--) { - uint16_t type = ntohs(ext->type); + uint16_t type = ext->type; if (type == CLUSTERMSG_EXT_TYPE_HOSTNAME) { clusterMsgPingExtHostname *hostname_ext = (clusterMsgPingExtHostname *) &(ext->ext[0].hostname); ext_hostname = hostname_ext->hostname; + } else if (type == CLUSTERMSG_EXT_TYPE_NODENAME) { + clusterMsgPingExtNodename *nodename_ext = (clusterMsgPingExtNodename *) &(ext->ext[1].nodename); + ext_nodename = nodename_ext->nodename; } else { /* Unknown type, we will ignore it but log what happened. */ serverLog(LL_WARNING, "Received unknown extension type %d", type); @@ -1994,6 +2066,7 @@ void clusterProcessPingExtensions(clusterMsg *hdr, clusterLink *link) { * they don't have an announced hostname. Otherwise, we'll * set it now. */ updateAnnouncedHostname(sender, ext_hostname); + updateAnnouncedNodename(sender, ext_nodename); } static clusterNode *getNodeFromLinkAndMsg(clusterLink *link, clusterMsg *hdr) { @@ -2224,7 +2297,7 @@ int clusterProcessPacket(clusterLink *link) { * IP/port of the node with the new one. */ if (sender) { serverLog(LL_VERBOSE, - "Handshake: we already know node %.40s , " + "Handshake: we already know node %.40s, " "updating the address if needed.", sender->name); if (nodeUpdateAddressIfNeeded(sender,link,hdr)) @@ -2253,7 +2326,7 @@ int clusterProcessPacket(clusterLink *link) { * disconnect this node and set it as not having an associated * address. */ serverLog(LL_DEBUG,"PONG contains mismatching sender ID. About node %.40s added %d ms ago, having flags %d", - link->node->name, + link->node->name, (int)(now-(link->node->ctime)), link->node->flags); link->node->flags |= CLUSTER_NODE_NOADDR; @@ -2401,8 +2474,7 @@ int clusterProcessPacket(clusterLink *link) { serverLog(LL_VERBOSE, "Node %.40s has old slots configuration, sending " "an UPDATE message about %.40s ", - sender->name, - server.cluster->slots[j]->name); + sender->name, server.cluster->slots[j]->name); clusterSendUpdate(sender->link, server.cluster->slots[j]); @@ -2897,7 +2969,7 @@ void clusterSendPing(clusterLink *link, int type) { * to put inside the packet. */ estlen = sizeof(clusterMsg) - sizeof(union clusterMsgData); estlen += (sizeof(clusterMsgDataGossip)*(wanted + pfail_wanted)); - estlen += sizeof(clusterMsgPingExt) + getHostnamePingExtSize(); + estlen += sizeof(clusterMsgPingExt) + getHostnamePingExtSize() + getNodenamePingExtSize(); /* Note: clusterBuildMessageHdr() expects the buffer to be always at least * sizeof(clusterMsg) or more. */ @@ -2978,6 +3050,12 @@ void clusterSendPing(clusterLink *link, int type) { extensions++; } + if (myself->nodename) { + hdr->mflags[0] |= CLUSTERMSG_FLAG0_EXT_DATA; + totlen += writeNodenamePingExt(&cursor); + extensions++; + } + /* Compute the actual total length and send! */ totlen += sizeof(clusterMsg)-sizeof(union clusterMsgData); totlen += (sizeof(clusterMsgDataGossip)*gossipcount); @@ -3265,8 +3343,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * request, if the request epoch was greater. */ if (requestCurrentEpoch < server.cluster->currentEpoch) { serverLog(LL_WARNING, - "Failover auth denied to %.40s : reqEpoch (%llu) < curEpoch(%llu)", - node->name, + "Failover auth denied to %.40s: reqEpoch (%llu) < curEpoch(%llu)", + node->name, (unsigned long long) requestCurrentEpoch, (unsigned long long) server.cluster->currentEpoch); return; @@ -3275,8 +3353,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { /* I already voted for this epoch? Return ASAP. */ if (server.cluster->lastVoteEpoch == server.cluster->currentEpoch) { serverLog(LL_WARNING, - "Failover auth denied to %.40s : already voted for epoch %llu", - node->name, + "Failover auth denied to %.40s: already voted for epoch %llu", + node->name, (unsigned long long) server.cluster->currentEpoch); return; } @@ -3289,15 +3367,15 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { { if (nodeIsMaster(node)) { serverLog(LL_WARNING, - "Failover auth denied to %.40s : it is a master node", + "Failover auth denied to %.40s: it is a master node", node->name); } else if (master == NULL) { serverLog(LL_WARNING, - "Failover auth denied to %.40s : I don't know its master", + "Failover auth denied to %.40s: I don't know its master", node->name); } else if (!nodeFailed(master)) { serverLog(LL_WARNING, - "Failover auth denied to %.40s : its master is up", + "Failover auth denied to %.40s: its master is up", node->name); } return; @@ -3309,7 +3387,7 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { if (mstime() - node->slaveof->voted_time < server.cluster_node_timeout * 2) { serverLog(LL_WARNING, - "Failover auth denied to %.40s : " + "Failover auth denied to %.40s: " "can't vote about this master before %lld milliseconds", node->name, (long long) ((server.cluster_node_timeout*2)- @@ -3331,7 +3409,7 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * is served by a master with a greater configEpoch than the one claimed * by the slave requesting our vote. Refuse to vote for this slave. */ serverLog(LL_WARNING, - "Failover auth denied to %.40s : " + "Failover auth denied to %.40s: " "slot %d epoch (%llu) > reqEpoch (%llu)", node->name, j, (unsigned long long) server.cluster->slots[j]->configEpoch, @@ -3762,7 +3840,7 @@ void clusterHandleSlaveMigration(int max_slaves) { (mstime()-target->orphaned_time) > CLUSTER_SLAVE_MIGRATION_DELAY && !(server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_FAILOVER)) { - serverLog(LL_WARNING,"Migrating to orphaned master %.40s ", + serverLog(LL_WARNING,"Migrating to orphaned master %.40s", target->name); clusterSetMaster(target); } @@ -3958,6 +4036,7 @@ void clusterCron(void) { clusterUpdateMyselfHostname(); + updateAnnouncedNodename(myself, server.cluster_announce_nodename); /* The handshake timeout is the time after which a handshake node that was * not turned into a normal node is removed from the nodes. Usually it is * just the NODE_TIMEOUT value, but when NODE_TIMEOUT is too small we use @@ -4010,7 +4089,7 @@ void clusterCron(void) { } } if (min_pong_node) { - serverLog(LL_DEBUG,"Pinging node %.40s ", min_pong_node->name); + serverLog(LL_DEBUG,"Pinging node %.40s", min_pong_node->name); clusterSendPing(min_pong_node->link, CLUSTERMSG_TYPE_PING); } } @@ -4576,12 +4655,25 @@ sds clusterGenNodeDescription(clusterNode *node, int use_pport) { /* Node coordinates */ ci = sdscatlen(sdsempty(),node->name,CLUSTER_NAMELEN); - if (sdslen(node->hostname) != 0) { + if (sdslen(node->hostname) != 0 && node->nodename) { + ci = sdscatfmt(ci," %s:%i@%i,%s-%s ", + node->ip, + port, + node->cport, + node->hostname, + node->nodename); + } else if (sdslen(node->hostname) != 0) { ci = sdscatfmt(ci," %s:%i@%i,%s ", node->ip, port, node->cport, node->hostname); + } else if (node->nodename) { + ci = sdscatfmt(ci," %s:%i@%i-%s ", + node->ip, + port, + node->cport, + node->nodename); } else { ci = sdscatfmt(ci," %s:%i@%i ", node->ip, @@ -4597,7 +4689,7 @@ sds clusterGenNodeDescription(clusterNode *node, int use_pport) { if (node->slaveof) ci = sdscatlen(ci,node->slaveof->name,CLUSTER_NAMELEN); else - ci = sdscatlen(ci,"-",1); + ci = sdscatlen(ci,"-",1); unsigned long long nodeEpoch = node->configEpoch; if (nodeIsSlave(node) && node->slaveof) { @@ -4803,6 +4895,7 @@ const char *getPreferredEndpoint(clusterNode *n) { switch(server.cluster_preferred_endpoint_type) { case CLUSTER_ENDPOINT_TYPE_IP: return n->ip; case CLUSTER_ENDPOINT_TYPE_HOSTNAME: return (sdslen(n->hostname) != 0) ? n->hostname : "?"; + case CLUSTER_ENDPOINT_TYPE_NODENAME: return n->nodename ? n->nodename : "?"; case CLUSTER_ENDPOINT_TYPE_UNKNOWN_ENDPOINT: return ""; } return "unknown"; @@ -4897,6 +4990,8 @@ void addNodeToNodeReply(client *c, clusterNode *node) { addReplyBulkCString(c, node->ip); } else if (server.cluster_preferred_endpoint_type == CLUSTER_ENDPOINT_TYPE_HOSTNAME) { addReplyBulkCString(c, sdslen(node->hostname) != 0 ? node->hostname : "?"); + } else if (server.cluster_preferred_endpoint_type == CLUSTER_ENDPOINT_TYPE_NODENAME) { + addReplyBulkCString(c, node->nodename ? node->nodename : "?"); } else if (server.cluster_preferred_endpoint_type == CLUSTER_ENDPOINT_TYPE_UNKNOWN_ENDPOINT) { addReplyNull(c); } else { @@ -4925,6 +5020,13 @@ void addNodeToNodeReply(client *c, clusterNode *node) { addReplyBulkCString(c, node->hostname); length++; } + if (server.cluster_preferred_endpoint_type != CLUSTER_ENDPOINT_TYPE_NODENAME + && node->nodename) + { + addReplyBulkCString(c, "nodename"); + addReplyBulkCString(c, node->nodename); + length++; + } setDeferredMapLen(c, deflen, length); } diff --git a/src/cluster.h b/src/cluster.h index 314b747bea4..b9edb8c27ed 100644 --- a/src/cluster.h +++ b/src/cluster.h @@ -136,6 +136,7 @@ typedef struct clusterNode { long long repl_offset; /* Last known repl offset for this node. */ char ip[NET_IP_STR_LEN]; /* Latest known IP address of this node */ sds hostname; /* The known hostname for this node */ + char *nodename; /* The known human readable nodename for this node */ int port; /* Latest known clients port (TLS or plain). */ int pport; /* Latest known clients plaintext port. Only used if the main clients port is for TLS. */ @@ -251,6 +252,7 @@ typedef struct { * consistent manner. */ typedef enum { CLUSTERMSG_EXT_TYPE_HOSTNAME, + CLUSTERMSG_EXT_TYPE_NODENAME, } clusterMsgPingtypes; /* Helper function for making sure extensions are eight byte aligned. */ @@ -260,12 +262,17 @@ typedef struct { char hostname[1]; /* The announced hostname, ends with \0. */ } clusterMsgPingExtHostname; +typedef struct { + char nodename[1]; /* The announced nodename, ends with \0. */ +} clusterMsgPingExtNodename; + typedef struct { uint32_t length; /* Total length of this extension message (including this header) */ uint16_t type; /* Type of this extension message (see clusterMsgPingExtTypes) */ uint16_t unused; /* 16 bits of padding to make this structure 8 byte aligned. */ union { clusterMsgPingExtHostname hostname; + clusterMsgPingExtNodename nodename; } ext[]; /* Actual extension information, formatted so that the data is 8 * byte aligned, regardless of its content. */ } clusterMsgPingExt; @@ -396,5 +403,6 @@ void clusterUpdateMyselfIp(void); void slotToChannelAdd(sds channel); void slotToChannelDel(sds channel); void clusterUpdateMyselfHostname(void); +void clusterUpdateMyselfNodename(void); #endif /* __CLUSTER_H */ diff --git a/src/config.c b/src/config.c index a52e00f66e8..d446aea0a60 100644 --- a/src/config.c +++ b/src/config.c @@ -144,6 +144,7 @@ configEnum protected_action_enum[] = { configEnum cluster_preferred_endpoint_type_enum[] = { {"ip", CLUSTER_ENDPOINT_TYPE_IP}, {"hostname", CLUSTER_ENDPOINT_TYPE_HOSTNAME}, + {"nodename", CLUSTER_ENDPOINT_TYPE_NODENAME}, {"unknown-endpoint", CLUSTER_ENDPOINT_TYPE_UNKNOWN_ENDPOINT}, {NULL, 0} }; @@ -2367,6 +2368,12 @@ int updateClusterHostname(const char **err) { return 1; } +int updateClusterNodename(const char **err) { + UNUSED(err); + clusterUpdateMyselfNodename(); + return 1; +} + #ifdef USE_OPENSSL static int applyTlsCfg(const char **err) { UNUSED(err); @@ -2786,6 +2793,7 @@ standardConfig configs[] = { createStringConfig("cluster-announce-ip", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.cluster_announce_ip, NULL, NULL, updateClusterIp), createStringConfig("cluster-config-file", NULL, IMMUTABLE_CONFIG, ALLOW_EMPTY_STRING, server.cluster_configfile, "nodes.conf", NULL, NULL), createStringConfig("cluster-announce-hostname", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.cluster_announce_hostname, NULL, isValidAnnouncedHostname, updateClusterHostname), + createStringConfig("cluster-announce-nodename", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.cluster_announce_nodename, NULL, isValidAnnouncedHostname, updateClusterNodename), createStringConfig("syslog-ident", NULL, IMMUTABLE_CONFIG, ALLOW_EMPTY_STRING, server.syslog_ident, "redis", NULL, NULL), createStringConfig("dbfilename", NULL, MODIFIABLE_CONFIG | PROTECTED_CONFIG, ALLOW_EMPTY_STRING, server.rdb_filename, "dump.rdb", isValidDBfilename, NULL), createStringConfig("appendfilename", NULL, IMMUTABLE_CONFIG, ALLOW_EMPTY_STRING, server.aof_filename, "appendonly.aof", isValidAOFfilename, NULL), diff --git a/src/server.h b/src/server.h index 30c40f9461c..b77dd8375b0 100644 --- a/src/server.h +++ b/src/server.h @@ -583,6 +583,7 @@ typedef struct { typedef enum { CLUSTER_ENDPOINT_TYPE_IP = 0, /* Show IP address */ CLUSTER_ENDPOINT_TYPE_HOSTNAME, /* Show hostname */ + CLUSTER_ENDPOINT_TYPE_NODENAME, /* Show nodename */ CLUSTER_ENDPOINT_TYPE_UNKNOWN_ENDPOINT /* Show NULL or empty */ } cluster_endpoint_type; @@ -1849,6 +1850,7 @@ struct redisServer { if the master is in failure state. */ char *cluster_announce_ip; /* IP address to announce on cluster bus. */ char *cluster_announce_hostname; /* IP address to announce on cluster bus. */ + char *cluster_announce_nodename; /* Human readable name assigned to a node. */ int cluster_preferred_endpoint_type; /* Use the announced hostname when available. */ int cluster_announce_port; /* base port to announce on cluster bus. */ int cluster_announce_tls_port; /* TLS port to announce on cluster bus. */ From bfb98c20c2c0ac272524a18e5098a69732264857 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Thu, 24 Feb 2022 09:55:14 -0500 Subject: [PATCH 37/79] Update src/cluster.c Co-authored-by: Madelyn Olson <34459052+madolson@users.noreply.github.com> --- src/cluster.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cluster.c b/src/cluster.c index d4c10fcec41..4d3d9d4121f 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -2052,7 +2052,7 @@ void clusterProcessPingExtensions(clusterMsg *hdr, clusterLink *link) { clusterMsgPingExtHostname *hostname_ext = (clusterMsgPingExtHostname *) &(ext->ext[0].hostname); ext_hostname = hostname_ext->hostname; } else if (type == CLUSTERMSG_EXT_TYPE_NODENAME) { - clusterMsgPingExtNodename *nodename_ext = (clusterMsgPingExtNodename *) &(ext->ext[1].nodename); + clusterMsgPingExtNodename *nodename_ext = (clusterMsgPingExtNodename *) &(ext->ext[0].nodename); ext_nodename = nodename_ext->nodename; } else { /* Unknown type, we will ignore it but log what happened. */ From a2d047145aa9698a196b4a71abcbde7d6be3675f Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Thu, 24 Feb 2022 09:59:15 -0500 Subject: [PATCH 38/79] Update cluster.c Fix indentation --- src/cluster.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cluster.c b/src/cluster.c index 4d3d9d4121f..26d18f4d189 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -3651,7 +3651,7 @@ void clusterHandleSlaveFailover(void) { if (server.cluster->mf_end) { server.cluster->failover_auth_time = mstime(); server.cluster->failover_auth_rank = 0; - clusterDoBeforeSleep(CLUSTER_TODO_HANDLE_FAILOVER); + clusterDoBeforeSleep(CLUSTER_TODO_HANDLE_FAILOVER); } serverLog(LL_WARNING, "Start of election delayed for %lld milliseconds " From b7837ae9c4739fc2a9820fe8d84892e4ae6f9519 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Thu, 24 Feb 2022 16:11:36 -0500 Subject: [PATCH 39/79] Cluster nodename feature add sds option (#67) * Add sds option --- redis.conf | 4 + src/cluster.c | 242 ++++++++++++++++++++------------------------------ src/cluster.h | 2 +- 3 files changed, 102 insertions(+), 146 deletions(-) diff --git a/redis.conf b/redis.conf index d018c8824f2..5a1cc03b6bc 100644 --- a/redis.conf +++ b/redis.conf @@ -1684,6 +1684,10 @@ aof-timestamp-enabled no # # cluster-announce-hostname "" +# Clusters can configure their announced nodename using this config. The nodename can be a human-readable name +# which will be exposed in places like info and logging for debugging purposes. +# cluster-announce-nodename "" + # Clusters can advertise how clients should connect to them using either their IP address, # a user defined hostname, or by declaring they have no endpoint. Which endpoint is # shown as the preferred endpoint is set by using the cluster-preferred-endpoint-type diff --git a/src/cluster.c b/src/cluster.c index 238796f0e39..54420b6845c 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -253,19 +253,9 @@ int clusterLoadConfig(char *filename) { *nodename = '\0'; nodename++; zfree(n->nodename); - n->nodename = zstrdup(nodename); - } else { - n->nodename = NULL; - } - /* Nodename is an optional argument */ - char *nodename = strchr(p, '-'); - if (nodename) { - *nodename = '\0'; - nodename++; - zfree(n->nodename); - n->nodename = zstrdup(nodename); - } else { - n->nodename = NULL; + n->nodename = sdscpy(n->nodename, nodename); + } else if (sdslen(n->nodename) != 0) { + sdsclear(n->nodename); } /* The plaintext port for client in a TLS cluster (n->pport) is not @@ -603,39 +593,15 @@ static void updateAnnouncedHostname(clusterNode *node, char *new) { /* Update the nodename for the specified node with the provided C string. */ static void updateAnnouncedNodename(clusterNode *node, char *new) { - if (!node->nodename && !new) { - return; - } - - /* Previous and new nodename are the same, no need to update. */ - if (new && node->nodename && !strcmp(new, node->nodename)) { - return; - } - - if (node->nodename) zfree(node->nodename); - if (new) { - node->nodename = zstrdup(new); - } else { - node->nodename = NULL; - } -} - -/* Update the nodename for the specified node with the provided C string. */ -static void updateAnnouncedNodename(clusterNode *node, char *new) { - if (!node->nodename && !new) { - return; - } - /* Previous and new nodename are the same, no need to update. */ - if (new && node->nodename && !strcmp(new, node->nodename)) { + if (new && !strcmp(new, node->nodename)) { return; } - if (node->nodename) zfree(node->nodename); if (new) { - node->nodename = zstrdup(new); - } else { - node->nodename = NULL; + node->nodename = sdscpy(node->nodename, new); + } else if (sdslen(node->nodename) != 0) { + sdsclear(node->nodename); } } @@ -1018,7 +984,7 @@ clusterNode *createClusterNode(char *nodename, int flags) { node->inbound_link = NULL; memset(node->ip,0,sizeof(node->ip)); node->hostname = sdsempty(); - node->nodename = NULL; + node->nodename = sdsempty(); node->port = 0; node->cport = 0; node->pport = 0; @@ -1185,7 +1151,7 @@ void freeClusterNode(clusterNode *n) { serverAssert(dictDelete(server.cluster->nodes,nodename) == DICT_OK); sdsfree(nodename); sdsfree(n->hostname); - zfree(n->nodename); + sdsfree(n->nodename); /* Release links and associated data structures. */ if (n->link) freeClusterLink(n->link); @@ -1411,9 +1377,9 @@ void clusterHandleConfigEpochCollision(clusterNode *sender) { myself->configEpoch = server.cluster->currentEpoch; clusterSaveConfigOrDie(1); serverLog(LL_VERBOSE, - "WARNING: configEpoch collision with node %.40s." + "WARNING: configEpoch collision with node %.40s %s." " configEpoch set to %llu", - sender->name, + sender->name, sender->nodename, (unsigned long long) myself->configEpoch); } @@ -1529,7 +1495,7 @@ void markNodeAsFailingIfNeeded(clusterNode *node) { if (failures < needed_quorum) return; /* No weak agreement from masters. */ serverLog(LL_NOTICE, - "Marking node %.40s as failing (quorum reached).", node->name); + "Marking node %.40s %s as failing (quorum reached).", node->name, node->nodename); /* Mark the node as failing. */ node->flags &= ~CLUSTER_NODE_PFAIL; @@ -1557,8 +1523,8 @@ void clearNodeFailureIfNeeded(clusterNode *node) { * node again. */ if (nodeIsSlave(node) || node->numslots == 0) { serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s: %s is reachable again.", - node->name, + "Clear FAIL state for node %.40s %s: %s is reachable again.", + node->name, node->nodename, nodeIsSlave(node) ? "replica" : "master without slots"); node->flags &= ~CLUSTER_NODE_FAIL; clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); @@ -1573,8 +1539,8 @@ void clearNodeFailureIfNeeded(clusterNode *node) { (server.cluster_node_timeout * CLUSTER_FAIL_UNDO_TIME_MULT)) { serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s: is reachable again and nobody is serving its slots after some time.", - node->name); + "Clear FAIL state for node %.40s %s: is reachable again and nobody is serving its slots after some time.", + node->name, node->nodename); node->flags &= ~CLUSTER_NODE_FAIL; clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); } @@ -1694,15 +1660,17 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { if (flags & (CLUSTER_NODE_FAIL|CLUSTER_NODE_PFAIL)) { if (clusterNodeAddFailureReport(node,sender)) { serverLog(LL_VERBOSE, - "Node %.40s reported node %.40s as not reachable.", - sender->name, node->name); + "Node %.40s %s reported node %.40s %s as not reachable.", + sender->name, sender->nodename, + node->name, node->nodename); } markNodeAsFailingIfNeeded(node); } else { if (clusterNodeDelFailureReport(node,sender)) { serverLog(LL_VERBOSE, - "Node %.40s reported node %.40s is back online.", - sender->name, node->name); + "Node %.40s %s reported node %.40s %s is back online.", + sender->name, sender->nodename, + node->name, node->nodename); } } } @@ -2019,17 +1987,7 @@ int getHostnamePingExtSize() { * will be 8 byte padded. */ int getNodenamePingExtSize() { /* If nodename is not set, we don't send this extension */ - if (!myself->nodename) return 0; - - int totlen = sizeof(clusterMsgPingExt) + EIGHT_BYTE_ALIGN(strlen(myself->nodename) + 1); - return totlen; -} - -/* Returns the exact size needed to store the nodename. The returned value - * will be 8 byte padded. */ -int getNodenamePingExtSize() { - /* If nodename is not set, we don't send this extension */ - if (!myself->nodename) return 0; + if (sdslen(myself->nodename) == 0) return 0; int totlen = sizeof(clusterMsgPingExt) + EIGHT_BYTE_ALIGN(strlen(myself->nodename) + 1); return totlen; @@ -2060,40 +2018,18 @@ int writeHostnamePingExt(clusterMsgPingExt **cursor) { * will return the amount of bytes written. */ int writeNodenamePingExt(clusterMsgPingExt **cursor) { /* If nodename is not set, we don't send this extension */ - if (!myself->nodename) return 0; - - /* Add the nodename information at the extension cursor */ - clusterMsgPingExtNodename *ext = &(*cursor)->ext[1].nodename; - size_t nodename_len = strlen(myself->nodename); - memcpy(ext->nodename, myself->nodename, nodename_len); - uint32_t extension_size = getNodenamePingExtSize(); - - /* Move the write cursor */ - (*cursor)->type = CLUSTERMSG_EXT_TYPE_NODENAME; - (*cursor)->length = htonl(extension_size); - /* Make sure the string is NULL terminated by adding 1 */ - *cursor = (clusterMsgPingExt *) (ext->nodename + EIGHT_BYTE_ALIGN(strlen(myself->nodename) + 1)); - return extension_size; -} - -/* Write the nodename ping extension at the start of the cursor. This function - * will update the cursor to point to the end of the written extension and - * will return the amount of bytes written. */ -int writeNodenamePingExt(clusterMsgPingExt **cursor) { - /* If nodename is not set, we don't send this extension */ - if (!myself->nodename) return 0; + if (sdslen(myself->nodename) == 0) return 0; /* Add the nodename information at the extension cursor */ - clusterMsgPingExtNodename *ext = &(*cursor)->ext[1].nodename; - size_t nodename_len = strlen(myself->nodename); - memcpy(ext->nodename, myself->nodename, nodename_len); + clusterMsgPingExtNodename *ext = &(*cursor)->ext[0].nodename; + memcpy(ext->nodename, myself->nodename, sdslen(myself->nodename)); uint32_t extension_size = getNodenamePingExtSize(); /* Move the write cursor */ (*cursor)->type = CLUSTERMSG_EXT_TYPE_NODENAME; (*cursor)->length = htonl(extension_size); /* Make sure the string is NULL terminated by adding 1 */ - *cursor = (clusterMsgPingExt *) (ext->nodename + EIGHT_BYTE_ALIGN(strlen(myself->nodename) + 1)); + *cursor = (clusterMsgPingExt *) (ext->nodename + EIGHT_BYTE_ALIGN(sdslen(myself->nodename) + 1)); return extension_size; } @@ -2357,8 +2293,8 @@ int clusterProcessPacket(clusterLink *link) { * IP/port of the node with the new one. */ if (sender) { serverLog(LL_VERBOSE, - "Handshake: we already know node %.40s, " - "updating the address if needed.", sender->name); + "Handshake: we already know node %.40s %s, " + "updating the address if needed.", sender->name, sender->nodename); if (nodeUpdateAddressIfNeeded(sender,link,hdr)) { @@ -2385,8 +2321,9 @@ int clusterProcessPacket(clusterLink *link) { /* If the reply has a non matching node ID we * disconnect this node and set it as not having an associated * address. */ - serverLog(LL_DEBUG,"PONG contains mismatching sender ID. About node %.40s added %d ms ago, having flags %d", + serverLog(LL_DEBUG,"PONG contains mismatching sender ID. About node %.40s %s added %d ms ago, having flags %d", link->node->name, + link->node->nodename, (int)(now-(link->node->ctime)), link->node->flags); link->node->flags |= CLUSTER_NODE_NOADDR; @@ -2533,8 +2470,9 @@ int clusterProcessPacket(clusterLink *link) { { serverLog(LL_VERBOSE, "Node %.40s has old slots configuration, sending " - "an UPDATE message about %.40s ", - sender->name, server.cluster->slots[j]->name); + "an UPDATE message about %.40s %s", + sender->name, server.cluster->slots[j]->name, + sender->nodename); clusterSendUpdate(sender->link, server.cluster->slots[j]); @@ -2570,8 +2508,8 @@ int clusterProcessPacket(clusterLink *link) { !(failing->flags & (CLUSTER_NODE_FAIL|CLUSTER_NODE_MYSELF))) { serverLog(LL_NOTICE, - "FAIL message received from %.40s about %.40s", - hdr->sender, hdr->data.fail.about.nodename); + "FAIL message received from %.40s about %.40s %s", + hdr->sender, hdr->data.fail.about.nodename, failing->nodename); failing->flags |= CLUSTER_NODE_FAIL; failing->fail_time = now; failing->flags &= ~CLUSTER_NODE_PFAIL; @@ -2722,8 +2660,8 @@ void clusterLinkConnectHandler(connection *conn) { /* Check if connection succeeded */ if (connGetState(conn) != CONN_STATE_CONNECTED) { - serverLog(LL_VERBOSE, "Connection with Node %.40s at %s:%d failed: %s", - node->name, node->ip, node->cport, + serverLog(LL_VERBOSE, "Connection with Node %.40s %s at %s:%d failed: %s", + node->name, node->nodename, node->ip, node->cport, connGetLastError(conn)); freeClusterLink(link); return; @@ -3110,7 +3048,7 @@ void clusterSendPing(clusterLink *link, int type) { extensions++; } - if (myself->nodename) { + if (sdslen(myself->nodename) != 0) { hdr->mflags[0] |= CLUSTERMSG_FLAG0_EXT_DATA; totlen += writeNodenamePingExt(&cursor); extensions++; @@ -3403,8 +3341,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * request, if the request epoch was greater. */ if (requestCurrentEpoch < server.cluster->currentEpoch) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: reqEpoch (%llu) < curEpoch(%llu)", - node->name, + "Failover auth denied to %.40s %s: reqEpoch (%llu) < curEpoch(%llu)", + node->name, node->nodename, (unsigned long long) requestCurrentEpoch, (unsigned long long) server.cluster->currentEpoch); return; @@ -3413,8 +3351,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { /* I already voted for this epoch? Return ASAP. */ if (server.cluster->lastVoteEpoch == server.cluster->currentEpoch) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: already voted for epoch %llu", - node->name, + "Failover auth denied to %.40s %s: already voted for epoch %llu", + node->name, node->nodename, (unsigned long long) server.cluster->currentEpoch); return; } @@ -3427,16 +3365,16 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { { if (nodeIsMaster(node)) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: it is a master node", - node->name); + "Failover auth denied to %.40s %s: it is a master node", + node->name, node->nodename); } else if (master == NULL) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: I don't know its master", - node->name); + "Failover auth denied to %.40s %s: I don't know its master", + node->name, node->nodename); } else if (!nodeFailed(master)) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: its master is up", - node->name); + "Failover auth denied to %.40s %s: its master is up", + node->name, node->nodename); } return; } @@ -3447,9 +3385,9 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { if (mstime() - node->slaveof->voted_time < server.cluster_node_timeout * 2) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: " + "Failover auth denied to %.40s %s: " "can't vote about this master before %lld milliseconds", - node->name, + node->name, node->nodename, (long long) ((server.cluster_node_timeout*2)- (mstime() - node->slaveof->voted_time))); return; @@ -3469,9 +3407,9 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * is served by a master with a greater configEpoch than the one claimed * by the slave requesting our vote. Refuse to vote for this slave. */ serverLog(LL_WARNING, - "Failover auth denied to %.40s: " + "Failover auth denied to %.40s %s: " "slot %d epoch (%llu) > reqEpoch (%llu)", - node->name, j, + node->name, node->nodename, j, (unsigned long long) server.cluster->slots[j]->configEpoch, (unsigned long long) requestConfigEpoch); return; @@ -4095,7 +4033,9 @@ void clusterCron(void) { iteration++; /* Number of times this function was called so far. */ clusterUpdateMyselfHostname(); - updateAnnouncedNodename(myself, server.cluster_announce_nodename); + clusterUpdateMyselfNodename(); + // updateAnnouncedNodename(myself, server.cluster_announce_nodename); REMOVE THIS + /* The handshake timeout is the time after which a handshake node that was * not turned into a normal node is removed from the nodes. Usually it is * just the NODE_TIMEOUT value, but when NODE_TIMEOUT is too small we use @@ -4248,8 +4188,8 @@ void clusterCron(void) { /* Timeout reached. Set the node as possibly failing if it is * not already in this state. */ if (!(node->flags & (CLUSTER_NODE_PFAIL|CLUSTER_NODE_FAIL))) { - serverLog(LL_DEBUG,"*** NODE %.40s possibly failing", - node->name); + serverLog(LL_DEBUG,"*** NODE %.40s %s possibly failing", + node->name, node->nodename); node->flags |= CLUSTER_NODE_PFAIL; update_state = 1; } @@ -4714,31 +4654,43 @@ sds clusterGenNodeDescription(clusterNode *node, int use_pport) { /* Node coordinates */ ci = sdscatlen(sdsempty(),node->name,CLUSTER_NAMELEN); - if (sdslen(node->hostname) != 0 && node->nodename) { - ci = sdscatfmt(ci," %s:%i@%i,%s-%s ", - node->ip, - port, - node->cport, - node->hostname, - node->nodename); - } else if (sdslen(node->hostname) != 0) { - ci = sdscatfmt(ci," %s:%i@%i,%s ", - node->ip, - port, - node->cport, - node->hostname); - } else if (node->nodename) { - ci = sdscatfmt(ci," %s:%i@%i-%s ", - node->ip, - port, - node->cport, - node->nodename); - } else { - ci = sdscatfmt(ci," %s:%i@%i ", - node->ip, - port, - node->cport); + ci = sdscatfmt(ci," %s:%i@%i", + node->ip, + port, + node->cport); + if (sdslen(node->hostname) != 0) { + ci = sdscatfmt(ci,",%s", node->hostname); } + if (sdslen(node->nodename) != 0) { + ci = sdscatfmt(ci,"-%s", node->nodename); + } + ci = sdscatlen(ci," ",1); + + // if (sdslen(node->hostname) != 0 && sdslen(node->nodename) != 0) { + // ci = sdscatfmt(ci," %s:%i@%i,%s-%s ", + // node->ip, + // port, + // node->cport, + // node->hostname, + // node->nodename); + // } else if (sdslen(node->hostname) != 0) { + // ci = sdscatfmt(ci," %s:%i@%i,%s ", + // node->ip, + // port, + // node->cport, + // node->hostname); + // } else if (sdslen(node->nodename) != 0) { + // ci = sdscatfmt(ci," %s:%i@%i-%s ", + // node->ip, + // port, + // node->cport, + // node->nodename); + // } else { + // ci = sdscatfmt(ci," %s:%i@%i ", + // node->ip, + // port, + // node->cport); + // } /* Flags */ ci = representClusterNodeFlags(ci, node->flags); @@ -4954,7 +4906,7 @@ const char *getPreferredEndpoint(clusterNode *n) { switch(server.cluster_preferred_endpoint_type) { case CLUSTER_ENDPOINT_TYPE_IP: return n->ip; case CLUSTER_ENDPOINT_TYPE_HOSTNAME: return (sdslen(n->hostname) != 0) ? n->hostname : "?"; - case CLUSTER_ENDPOINT_TYPE_NODENAME: return n->nodename ? n->nodename : "?"; + case CLUSTER_ENDPOINT_TYPE_NODENAME: return (sdslen(n->nodename) != 0) ? n->nodename : "?"; case CLUSTER_ENDPOINT_TYPE_UNKNOWN_ENDPOINT: return ""; } return "unknown"; @@ -5050,7 +5002,7 @@ void addNodeToNodeReply(client *c, clusterNode *node) { } else if (server.cluster_preferred_endpoint_type == CLUSTER_ENDPOINT_TYPE_HOSTNAME) { addReplyBulkCString(c, sdslen(node->hostname) != 0 ? node->hostname : "?"); } else if (server.cluster_preferred_endpoint_type == CLUSTER_ENDPOINT_TYPE_NODENAME) { - addReplyBulkCString(c, node->nodename ? node->nodename : "?"); + addReplyBulkCString(c, sdslen(node->nodename) != 0 ? node->nodename : "?"); } else if (server.cluster_preferred_endpoint_type == CLUSTER_ENDPOINT_TYPE_UNKNOWN_ENDPOINT) { addReplyNull(c); } else { @@ -5080,7 +5032,7 @@ void addNodeToNodeReply(client *c, clusterNode *node) { length++; } if (server.cluster_preferred_endpoint_type != CLUSTER_ENDPOINT_TYPE_NODENAME - && node->nodename) + && sdslen(node->nodename) != 0) { addReplyBulkCString(c, "nodename"); addReplyBulkCString(c, node->nodename); diff --git a/src/cluster.h b/src/cluster.h index b9edb8c27ed..3c03f8d8243 100644 --- a/src/cluster.h +++ b/src/cluster.h @@ -136,7 +136,7 @@ typedef struct clusterNode { long long repl_offset; /* Last known repl offset for this node. */ char ip[NET_IP_STR_LEN]; /* Latest known IP address of this node */ sds hostname; /* The known hostname for this node */ - char *nodename; /* The known human readable nodename for this node */ + sds nodename; /* The known human readable nodename for this node */ int port; /* Latest known clients port (TLS or plain). */ int pport; /* Latest known clients plaintext port. Only used if the main clients port is for TLS. */ From 3c6c05e56b3184110cc08ae9dca14b37009bb367 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Fri, 25 Feb 2022 16:15:43 -0500 Subject: [PATCH 40/79] Cluster nodename feature rebase (#68) Update code according to comments --- src/cluster.c | 37 ------------------------------------- src/cluster.h | 2 +- src/config.c | 1 - src/server.h | 1 - 4 files changed, 1 insertion(+), 40 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index 54420b6845c..5660fec0462 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -4034,7 +4034,6 @@ void clusterCron(void) { clusterUpdateMyselfHostname(); clusterUpdateMyselfNodename(); - // updateAnnouncedNodename(myself, server.cluster_announce_nodename); REMOVE THIS /* The handshake timeout is the time after which a handshake node that was * not turned into a normal node is removed from the nodes. Usually it is @@ -4666,32 +4665,6 @@ sds clusterGenNodeDescription(clusterNode *node, int use_pport) { } ci = sdscatlen(ci," ",1); - // if (sdslen(node->hostname) != 0 && sdslen(node->nodename) != 0) { - // ci = sdscatfmt(ci," %s:%i@%i,%s-%s ", - // node->ip, - // port, - // node->cport, - // node->hostname, - // node->nodename); - // } else if (sdslen(node->hostname) != 0) { - // ci = sdscatfmt(ci," %s:%i@%i,%s ", - // node->ip, - // port, - // node->cport, - // node->hostname); - // } else if (sdslen(node->nodename) != 0) { - // ci = sdscatfmt(ci," %s:%i@%i-%s ", - // node->ip, - // port, - // node->cport, - // node->nodename); - // } else { - // ci = sdscatfmt(ci," %s:%i@%i ", - // node->ip, - // port, - // node->cport); - // } - /* Flags */ ci = representClusterNodeFlags(ci, node->flags); @@ -4906,7 +4879,6 @@ const char *getPreferredEndpoint(clusterNode *n) { switch(server.cluster_preferred_endpoint_type) { case CLUSTER_ENDPOINT_TYPE_IP: return n->ip; case CLUSTER_ENDPOINT_TYPE_HOSTNAME: return (sdslen(n->hostname) != 0) ? n->hostname : "?"; - case CLUSTER_ENDPOINT_TYPE_NODENAME: return (sdslen(n->nodename) != 0) ? n->nodename : "?"; case CLUSTER_ENDPOINT_TYPE_UNKNOWN_ENDPOINT: return ""; } return "unknown"; @@ -5001,8 +4973,6 @@ void addNodeToNodeReply(client *c, clusterNode *node) { addReplyBulkCString(c, node->ip); } else if (server.cluster_preferred_endpoint_type == CLUSTER_ENDPOINT_TYPE_HOSTNAME) { addReplyBulkCString(c, sdslen(node->hostname) != 0 ? node->hostname : "?"); - } else if (server.cluster_preferred_endpoint_type == CLUSTER_ENDPOINT_TYPE_NODENAME) { - addReplyBulkCString(c, sdslen(node->nodename) != 0 ? node->nodename : "?"); } else if (server.cluster_preferred_endpoint_type == CLUSTER_ENDPOINT_TYPE_UNKNOWN_ENDPOINT) { addReplyNull(c); } else { @@ -5031,13 +5001,6 @@ void addNodeToNodeReply(client *c, clusterNode *node) { addReplyBulkCString(c, node->hostname); length++; } - if (server.cluster_preferred_endpoint_type != CLUSTER_ENDPOINT_TYPE_NODENAME - && sdslen(node->nodename) != 0) - { - addReplyBulkCString(c, "nodename"); - addReplyBulkCString(c, node->nodename); - length++; - } setDeferredMapLen(c, deflen, length); } diff --git a/src/cluster.h b/src/cluster.h index 3c03f8d8243..76c757f2cd7 100644 --- a/src/cluster.h +++ b/src/cluster.h @@ -136,7 +136,7 @@ typedef struct clusterNode { long long repl_offset; /* Last known repl offset for this node. */ char ip[NET_IP_STR_LEN]; /* Latest known IP address of this node */ sds hostname; /* The known hostname for this node */ - sds nodename; /* The known human readable nodename for this node */ + sds nodename; /* The known human readable nodename for this node */ int port; /* Latest known clients port (TLS or plain). */ int pport; /* Latest known clients plaintext port. Only used if the main clients port is for TLS. */ diff --git a/src/config.c b/src/config.c index d446aea0a60..b0f8a911bcb 100644 --- a/src/config.c +++ b/src/config.c @@ -144,7 +144,6 @@ configEnum protected_action_enum[] = { configEnum cluster_preferred_endpoint_type_enum[] = { {"ip", CLUSTER_ENDPOINT_TYPE_IP}, {"hostname", CLUSTER_ENDPOINT_TYPE_HOSTNAME}, - {"nodename", CLUSTER_ENDPOINT_TYPE_NODENAME}, {"unknown-endpoint", CLUSTER_ENDPOINT_TYPE_UNKNOWN_ENDPOINT}, {NULL, 0} }; diff --git a/src/server.h b/src/server.h index b77dd8375b0..1252c5dea21 100644 --- a/src/server.h +++ b/src/server.h @@ -583,7 +583,6 @@ typedef struct { typedef enum { CLUSTER_ENDPOINT_TYPE_IP = 0, /* Show IP address */ CLUSTER_ENDPOINT_TYPE_HOSTNAME, /* Show hostname */ - CLUSTER_ENDPOINT_TYPE_NODENAME, /* Show nodename */ CLUSTER_ENDPOINT_TYPE_UNKNOWN_ENDPOINT /* Show NULL or empty */ } cluster_endpoint_type; From a1535a91339fc8aadce3e92c3e30768381166094 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Mon, 27 Sep 2021 17:00:23 -0400 Subject: [PATCH 41/79] Add hostname variable --- src/cluster.c | 16 ++++++++++++++++ src/cluster.h | 1 + 2 files changed, 17 insertions(+) diff --git a/src/cluster.c b/src/cluster.c index 2f37b241b9a..0c3bd7dbc1c 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -925,6 +925,22 @@ unsigned int keyHashSlot(char *key, int keylen) { * CLUSTER node API * -------------------------------------------------------------------------- */ +/* Assign a human readable name to nodes for clusters*/ +void setClusterNodeName(clusterNode *node){ + char *name; + int post_digits; + if (node->port == 0){ + post_digits = 0; + } + else{ + floor(log10(abs(node->port))) + 1; + } + int allocate_len = sizeof(node->ip) + post_digits + 2; + name = zmalloc(allocate_len); + sprintf(name, "%s%s%d", node->ip, "_", node->port); + node->hname = name; +} + /* Create a new cluster node, with the specified flags. * If "nodename" is NULL this is considered a first handshake and a random * node name is assigned to this node (it will be fixed later when we'll diff --git a/src/cluster.h b/src/cluster.h index a944056eb96..b9f579264ae 100644 --- a/src/cluster.h +++ b/src/cluster.h @@ -115,6 +115,7 @@ typedef struct clusterNodeFailReport { typedef struct clusterNode { mstime_t ctime; /* Node object creation time. */ char name[CLUSTER_NAMELEN]; /* Node name, hex string, sha1-size */ + char* hname; /* Human readable name for node */ int flags; /* CLUSTER_NODE_... */ uint64_t configEpoch; /* Last configEpoch observed for this node */ unsigned char slots[CLUSTER_SLOTS/8]; /* slots handled by this node */ From 310530528661f9015794dadaa22cb71478b5e25b Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Mon, 27 Sep 2021 17:02:18 -0400 Subject: [PATCH 42/79] Update cluster.c --- src/cluster.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cluster.c b/src/cluster.c index 0c3bd7dbc1c..e7f32d75c5e 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -933,7 +933,7 @@ void setClusterNodeName(clusterNode *node){ post_digits = 0; } else{ - floor(log10(abs(node->port))) + 1; + post_digits = floor(log10(abs(node->port))) + 1; } int allocate_len = sizeof(node->ip) + post_digits + 2; name = zmalloc(allocate_len); @@ -1605,6 +1605,7 @@ int clusterStartHandshake(char *ip, int port, int cport) { memcpy(n->ip,norm_ip,sizeof(n->ip)); n->port = port; n->cport = cport; + setClusterNodeName(n); clusterAddNode(n); return 1; } From 7dca410519b11e56c40ae85b4c4d2af247215b9a Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Mon, 27 Sep 2021 17:04:26 -0400 Subject: [PATCH 43/79] Update cluster.c --- src/cluster.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cluster.c b/src/cluster.c index e7f32d75c5e..89add5961a9 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -48,6 +48,7 @@ clusterNode *myself = NULL; clusterNode *createClusterNode(char *nodename, int flags); void clusterAddNode(clusterNode *node); +void setClusterNodeName(clusterNode *node); void clusterAcceptHandler(aeEventLoop *el, int fd, void *privdata, int mask); void clusterReadHandler(connection *conn); void clusterSendPing(clusterLink *link, int type); @@ -1697,6 +1698,7 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { node->pport = ntohs(g->pport); node->cport = ntohs(g->cport); node->flags &= ~CLUSTER_NODE_NOADDR; + setClusterNodeName(node); } } else { /* If it's not in NOADDR state and we don't have it, we @@ -1718,6 +1720,7 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { node->port = ntohs(g->port); node->pport = ntohs(g->pport); node->cport = ntohs(g->cport); + setClusterNodeName(node); clusterAddNode(node); } } @@ -1776,6 +1779,7 @@ int nodeUpdateAddressIfNeeded(clusterNode *node, clusterLink *link, node->port = port; node->pport = pport; node->cport = cport; + setClusterNodeName(node); if (node->link) freeClusterLink(node->link); node->flags &= ~CLUSTER_NODE_NOADDR; serverLog(LL_WARNING,"Address updated for node %.40s, now %s:%d", From 6728cd34f1142971e5b55f3e92f43c511eb4dacc Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Mon, 27 Sep 2021 17:05:32 -0400 Subject: [PATCH 44/79] Update cluster.c --- src/cluster.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cluster.c b/src/cluster.c index 89add5961a9..8ac66315ffa 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -2199,6 +2199,7 @@ int clusterProcessPacket(clusterLink *link) { strcmp(ip,myself->ip)) { memcpy(myself->ip,ip,NET_IP_STR_LEN); + setClusterNodeName(myself); serverLog(LL_WARNING,"IP address for this node updated to %s", myself->ip); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG); @@ -2217,6 +2218,7 @@ int clusterProcessPacket(clusterLink *link) { node->port = ntohs(hdr->port); node->pport = ntohs(hdr->pport); node->cport = ntohs(hdr->cport); + setClusterNodeName(node); clusterAddNode(node); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG); } From 68c4e108c65392596bf13485ba2ac74b8e92ae1a Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 10:09:24 -0400 Subject: [PATCH 45/79] Update cluster.c --- src/cluster.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/cluster.c b/src/cluster.c index 8ac66315ffa..ad3f13c9dea 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -1203,7 +1203,19 @@ clusterNode *clusterLookupNode(const char *name) { de = dictFind(server.cluster->nodes,s); sdsfree(s); - if (de == NULL) return NULL; + if (de == NULL){ + dictIterator *di; + dictEntry *de2; + + di = dictGetSafeIterator(server.cluster->nodes); + while((de2 = dictNext(di)) != NULL) { + clusterNode *node = dictGetVal(de2); + if (strcmp(node->hname,name ) == 0) + return node; + } + dictReleaseIterator(di); + return NULL; + } return dictGetVal(de); } From f25755c42dbf2ca08af7e35b893a75da07d42b35 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 10:14:18 -0400 Subject: [PATCH 46/79] Update cluster.c --- src/cluster.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index ad3f13c9dea..fc090ad2c03 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -1210,8 +1210,10 @@ clusterNode *clusterLookupNode(const char *name) { di = dictGetSafeIterator(server.cluster->nodes); while((de2 = dictNext(di)) != NULL) { clusterNode *node = dictGetVal(de2); - if (strcmp(node->hname,name ) == 0) - return node; + if (node->hname){ + if (strcmp(node->hname,name ) == 0) + return node; + } } dictReleaseIterator(di); return NULL; From 4643299c5ce59f8e64ccb6174a7a3c8862f0ddad Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 10:32:32 -0400 Subject: [PATCH 47/79] Update cluster.c --- src/cluster.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/cluster.c b/src/cluster.c index fc090ad2c03..848dbc54e44 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -1204,6 +1204,7 @@ clusterNode *clusterLookupNode(const char *name) { de = dictFind(server.cluster->nodes,s); sdsfree(s); if (de == NULL){ + /* Check if any node has the same human readable name*/ dictIterator *di; dictEntry *de2; @@ -4772,6 +4773,10 @@ sds clusterGenNodesDescription(int filter, int use_pport) { if (node->flags & filter) continue; ni = clusterGenNodeDescription(node, use_pport); + + if (node->hname) + ni = sdscatfmt(ni," %s ",node->hname); + ci = sdscatsds(ci,ni); sdsfree(ni); ci = sdscatlen(ci,"\n",1); From 15d4f971e49e830e5a712456b9f0c3514bd7c741 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 10:33:55 -0400 Subject: [PATCH 48/79] Update cluster.c --- src/cluster.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index 848dbc54e44..41452211c3f 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -4773,10 +4773,6 @@ sds clusterGenNodesDescription(int filter, int use_pport) { if (node->flags & filter) continue; ni = clusterGenNodeDescription(node, use_pport); - - if (node->hname) - ni = sdscatfmt(ni," %s ",node->hname); - ci = sdscatsds(ci,ni); sdsfree(ni); ci = sdscatlen(ci,"\n",1); From be36fadb55dd31edfde4396ed74f53e320f21c15 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 14:32:35 -0400 Subject: [PATCH 49/79] Check node name --- src/cluster.c | 3 +++ src/help.h | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/src/cluster.c b/src/cluster.c index 41452211c3f..34151774849 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -5285,6 +5285,9 @@ NULL } else if (!strcasecmp(c->argv[1]->ptr,"myid") && c->argc == 2) { /* CLUSTER MYID */ addReplyBulkCBuffer(c,myself->name, CLUSTER_NAMELEN); + } else if (!strcasecmp(c->argv[1]->ptr,"myname") && c->argc == 2) { + /* CLUSTER MYID */ + addReplyBulkCBuffer(c,myself->hname, sizeof(myself->hname)); } else if (!strcasecmp(c->argv[1]->ptr,"slots") && c->argc == 2) { /* CLUSTER SLOTS */ clusterReplyMultiBulkSlots(c); diff --git a/src/help.h b/src/help.h index edeb9b26e5f..0c36e12446c 100644 --- a/src/help.h +++ b/src/help.h @@ -364,6 +364,11 @@ struct commandHelp { "Return the node id", 12, "3.0.0" }, + { "CLUSTER MYNAME", + "", + "Return the node name", + 12, + "3.0.0" }, { "CLUSTER NODES", "", "Get Cluster config for the node", From 096e388b532e08c3d14ab530e496d6f4f766ea69 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 14:35:38 -0400 Subject: [PATCH 50/79] Update cluster.c --- src/cluster.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cluster.c b/src/cluster.c index 34151774849..339d521ec1a 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -5287,7 +5287,10 @@ NULL addReplyBulkCBuffer(c,myself->name, CLUSTER_NAMELEN); } else if (!strcasecmp(c->argv[1]->ptr,"myname") && c->argc == 2) { /* CLUSTER MYID */ - addReplyBulkCBuffer(c,myself->hname, sizeof(myself->hname)); + if (myself->hname) + addReplyBulkCBuffer(c,myself->hname, sizeof(myself->hname)); + else + addReplyError(c,"Node is not assigned name yet."); } else if (!strcasecmp(c->argv[1]->ptr,"slots") && c->argc == 2) { /* CLUSTER SLOTS */ clusterReplyMultiBulkSlots(c); From 5cb5388515d8f4fa017d2f8e765fd8fbfcbfc6f8 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 14:37:02 -0400 Subject: [PATCH 51/79] Update cluster.c --- src/cluster.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cluster.c b/src/cluster.c index 339d521ec1a..2be414b39c4 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -5288,7 +5288,7 @@ NULL } else if (!strcasecmp(c->argv[1]->ptr,"myname") && c->argc == 2) { /* CLUSTER MYID */ if (myself->hname) - addReplyBulkCBuffer(c,myself->hname, sizeof(myself->hname)); + addReplyBulkCBuffer(c,myself->hname, strlen(myself->hname)); else addReplyError(c,"Node is not assigned name yet."); } else if (!strcasecmp(c->argv[1]->ptr,"slots") && c->argc == 2) { From f6c1c4500e76cece9776c9567a000f33276dacd6 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 14:39:39 -0400 Subject: [PATCH 52/79] Add help for nodename --- src/cluster.c | 2 ++ src/help.h | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index 2be414b39c4..916b0ebe701 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -5219,6 +5219,8 @@ void clusterCommand(client *c) { " Connect nodes into a working cluster.", "MYID", " Return the node id.", +"MYNAME", +" Return the node name.", "NODES", " Return cluster configuration seen by node. Output format:", " ...", diff --git a/src/help.h b/src/help.h index 0c36e12446c..6ad21ebd2c1 100644 --- a/src/help.h +++ b/src/help.h @@ -364,9 +364,9 @@ struct commandHelp { "Return the node id", 12, "3.0.0" }, - { "CLUSTER MYNAME", + { "CLUSTER MYID", "", - "Return the node name", + "Return the node id", 12, "3.0.0" }, { "CLUSTER NODES", From b62a01adde02d4a39b9c0a246142be2ac90f6fc1 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 15:59:46 -0400 Subject: [PATCH 53/79] Update cluster.c --- src/cluster.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cluster.c b/src/cluster.c index 916b0ebe701..7f9c53fcce3 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -927,7 +927,7 @@ unsigned int keyHashSlot(char *key, int keylen) { * -------------------------------------------------------------------------- */ /* Assign a human readable name to nodes for clusters*/ -void setClusterNodeName(clusterNode *node){ +void setClusterNodeName(clusterNode *node) { char *name; int post_digits; if (node->port == 0){ From 5f08f5cb3f2291a752db12ac8beab0316d1da86c Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 5 Oct 2021 11:21:58 -0400 Subject: [PATCH 54/79] Added support for hname in CLUSTER NODES --- src/cluster.c | 20 ++++++++++---------- src/redis-cli.c | 22 ++++++++++++---------- tests/cluster/cluster.tcl | 17 +++++++++-------- tests/support/cluster.tcl | 4 ++-- 4 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index 7f9c53fcce3..a517e16d98d 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -232,12 +232,12 @@ int clusterLoadConfig(char *filename) { } /* Address and port */ - if ((p = strrchr(argv[1],':')) == NULL) { + if ((p = strrchr(argv[offset + 1],':')) == NULL) { sdsfreesplitres(argv,argc); goto fmterr; } *p = '\0'; - memcpy(n->ip,argv[1],strlen(argv[1])+1); + memcpy(n->ip,argv[offset + 1],strlen(argv[offset + 1])+1); char *port = p+1; char *busp = strchr(port,'@'); if (busp) { @@ -254,7 +254,7 @@ int clusterLoadConfig(char *filename) { * stored in nodes.conf. It is received later over the bus protocol. */ /* Parse flags */ - p = s = argv[2]; + p = s = argv[offset + 2]; while(p) { p = strchr(s,','); if (p) *p = '\0'; @@ -287,10 +287,10 @@ int clusterLoadConfig(char *filename) { /* Get master if any. Set the master and populate master's * slave list. */ - if (argv[3][0] != '-') { - master = clusterLookupNode(argv[3]); + if (argv[offset + 3][0] != '-') { + master = clusterLookupNode(argv[offset + 3]); if (!master) { - master = createClusterNode(argv[3],0); + master = createClusterNode(argv[offset + 3],0); clusterAddNode(master); } n->slaveof = master; @@ -298,14 +298,14 @@ int clusterLoadConfig(char *filename) { } /* Set ping sent / pong received timestamps */ - if (atoi(argv[4])) n->ping_sent = mstime(); - if (atoi(argv[5])) n->pong_received = mstime(); + if (atoi(argv[offset + 4])) n->ping_sent = mstime(); + if (atoi(argv[offset + 5])) n->pong_received = mstime(); /* Set configEpoch for this node. */ - n->configEpoch = strtoull(argv[6],NULL,10); + n->configEpoch = strtoull(argv[offset + 6],NULL,10); /* Populate hash slots served by this instance. */ - for (j = 8; j < argc; j++) { + for (j = offset + 8; j < argc; j++) { int start, stop; if (argv[j][0] == '[') { diff --git a/src/redis-cli.c b/src/redis-cli.c index 0c003a0dc6c..051ab94e9d9 100644 --- a/src/redis-cli.c +++ b/src/redis-cli.c @@ -4585,8 +4585,9 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, lines = p + 1; char *name = NULL, *addr = NULL, *flags = NULL, *master_id = NULL, *ping_sent = NULL, *ping_recv = NULL, *config_epoch = NULL, - *link_status = NULL; + *link_status = NULL, *hname = NULL; UNUSED(link_status); + UNUSED(hname); int i = 0; while ((p = strchr(line, ' ')) != NULL) { *p = '\0'; @@ -4594,15 +4595,16 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, line = p + 1; switch(i++){ case 0: name = token; break; - case 1: addr = token; break; - case 2: flags = token; break; - case 3: master_id = token; break; - case 4: ping_sent = token; break; - case 5: ping_recv = token; break; - case 6: config_epoch = token; break; - case 7: link_status = token; break; + case 1: hname = token; break; + case 2: addr = token; break; + case 3: flags = token; break; + case 4: master_id = token; break; + case 5: ping_sent = token; break; + case 6: ping_recv = token; break; + case 7: config_epoch = token; break; + case 8: link_status = token; break; } - if (i == 8) break; // Slots + if (i == 9) break; // Slots } if (!flags) { success = 0; @@ -4614,7 +4616,7 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, node->flags |= CLUSTER_MANAGER_FLAG_MYSELF; currentNode = node; clusterManagerNodeResetSlots(node); - if (i == 8) { + if (i == 9) { int remaining = strlen(line); while (remaining > 0) { p = strchr(line, ' '); diff --git a/tests/cluster/cluster.tcl b/tests/cluster/cluster.tcl index 9c669e12854..802b5b6f573 100644 --- a/tests/cluster/cluster.tcl +++ b/tests/cluster/cluster.tcl @@ -18,14 +18,15 @@ proc get_cluster_nodes id { set args [split $l] set node [dict create \ id [lindex $args 0] \ - addr [lindex $args 1] \ - flags [split [lindex $args 2] ,] \ - slaveof [lindex $args 3] \ - ping_sent [lindex $args 4] \ - pong_recv [lindex $args 5] \ - config_epoch [lindex $args 6] \ - linkstate [lindex $args 7] \ - slots [lrange $args 8 end] \ + name [lindex $args 1] \ + addr [lindex $args 2] \ + flags [split [lindex $args 3] ,] \ + slaveof [lindex $args 4] \ + ping_sent [lindex $args 5] \ + pong_recv [lindex $args 6] \ + config_epoch [lindex $args 7] \ + linkstate [lindex $args 8] \ + slots [lrange $args 9 end] \ ] lappend nodes $node } diff --git a/tests/support/cluster.tcl b/tests/support/cluster.tcl index 081ef6a9522..8c628dcd3f1 100644 --- a/tests/support/cluster.tcl +++ b/tests/support/cluster.tcl @@ -104,8 +104,8 @@ proc ::redis_cluster::__method__refresh_nodes_map {id} { set line [string trim $line] if {$line eq {}} continue set args [split $line " "] - lassign $args nodeid addr flags slaveof pingsent pongrecv configepoch linkstate - set slots [lrange $args 8 end] + lassign $args nodeid name addr flags slaveof pingsent pongrecv configepoch linkstate + set slots [lrange $args 9 end] set addr [lindex [split $addr @] 0] if {$addr eq {:0}} { set addr $start_host:$start_port From 9a0ee62864380a40056ebb18543dea9196117efa Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Mon, 1 Nov 2021 16:23:43 -0400 Subject: [PATCH 55/79] Add gossip and custom name support --- src/cluster.c | 218 ++++++++++++++++++++++---------------- src/cluster.h | 8 +- src/redis-cli.c | 20 ++-- tests/cluster/cluster.tcl | 11 +- tests/support/cluster.tcl | 5 +- 5 files changed, 156 insertions(+), 106 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index a517e16d98d..49f3aba7e4f 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -232,12 +232,12 @@ int clusterLoadConfig(char *filename) { } /* Address and port */ - if ((p = strrchr(argv[offset + 1],':')) == NULL) { + if ((p = strrchr(argv[1],':')) == NULL) { sdsfreesplitres(argv,argc); goto fmterr; } *p = '\0'; - memcpy(n->ip,argv[offset + 1],strlen(argv[offset + 1])+1); + memcpy(n->ip,argv[1],strlen(argv[1])+1); char *port = p+1; char *busp = strchr(port,'@'); if (busp) { @@ -254,7 +254,7 @@ int clusterLoadConfig(char *filename) { * stored in nodes.conf. It is received later over the bus protocol. */ /* Parse flags */ - p = s = argv[offset + 2]; + p = s = argv[3]; while(p) { p = strchr(s,','); if (p) *p = '\0'; @@ -287,25 +287,28 @@ int clusterLoadConfig(char *filename) { /* Get master if any. Set the master and populate master's * slave list. */ - if (argv[offset + 3][0] != '-') { - master = clusterLookupNode(argv[offset + 3]); + if (argv[4][0] != '-') { + master = clusterLookupNode(argv[4]); if (!master) { - master = createClusterNode(argv[offset + 3],0); + master = createClusterNode(argv[4],0); clusterAddNode(master); } n->slaveof = master; clusterNodeAddSlave(master,n); } + /* Custom nodename */ + n->has_human_readable_name = atoi(argv[5]); + /* Set ping sent / pong received timestamps */ - if (atoi(argv[offset + 4])) n->ping_sent = mstime(); - if (atoi(argv[offset + 5])) n->pong_received = mstime(); + if (atoi(argv[6])) n->ping_sent = mstime(); + if (atoi(argv[7])) n->pong_received = mstime(); /* Set configEpoch for this node. */ - n->configEpoch = strtoull(argv[offset + 6],NULL,10); + n->configEpoch = strtoull(argv[8],NULL,10); /* Populate hash slots served by this instance. */ - for (j = offset + 8; j < argc; j++) { + for (j = 10; j < argc; j++) { int start, stop; if (argv[j][0] == '[') { @@ -359,7 +362,7 @@ int clusterLoadConfig(char *filename) { zfree(line); fclose(fp); - serverLog(LL_NOTICE,"Node configuration loaded, I'm %.40s", myself->name); + serverLog(LL_NOTICE,"Node configuration loaded, I'm %.40s %s", myself->name, myself->human_readable_name); /* Something that should never happen: currentEpoch smaller than * the max epoch found in the nodes configuration. However we handle this @@ -631,8 +634,8 @@ void clusterInit(void) { * by the createClusterNode() function. */ myself = server.cluster->myself = createClusterNode(NULL,CLUSTER_NODE_MYSELF|CLUSTER_NODE_MASTER); - serverLog(LL_NOTICE,"No cluster configuration found, I'm %.40s", - myself->name); + serverLog(LL_NOTICE,"No cluster configuration found, I'm %.40s %s", + myself->name, myself->human_readable_name); clusterAddNode(myself); saveconf = 1; } @@ -739,7 +742,7 @@ void clusterReset(int hard) { sdsfree(oldname); getRandomHexChars(myself->name, CLUSTER_NAMELEN); clusterAddNode(myself); - serverLog(LL_NOTICE,"Node hard reset, now I'm %.40s", myself->name); + serverLog(LL_NOTICE,"Node hard reset, now I'm %.40s %s", myself->name, myself->human_readable_name); } /* Make sure to persist the new config and update the state. */ @@ -928,18 +931,21 @@ unsigned int keyHashSlot(char *key, int keylen) { /* Assign a human readable name to nodes for clusters*/ void setClusterNodeName(clusterNode *node) { - char *name; - int post_digits; - if (node->port == 0){ - post_digits = 0; - } - else{ - post_digits = floor(log10(abs(node->port))) + 1; - } - int allocate_len = sizeof(node->ip) + post_digits + 2; - name = zmalloc(allocate_len); - sprintf(name, "%s%s%d", node->ip, "_", node->port); - node->hname = name; + if (node->has_human_readable_name == 1) + return; + char ip[NET_IP_STR_LEN]; + strcpy(ip,node->ip); + sprintf(node->human_readable_name, "%s_%u", ip,(unsigned int)node->port); +} + +/* Manually assign a human readable name to nodes for clusters*/ +int setManualClusterNodeName(clusterNode *node, char * newname) { + if (newname == NULL) + return 0; + memcpy(node->human_readable_name, newname, strlen(newname) + 1); + node->has_human_readable_name = 1; + clusterSaveConfig(1); + return 1; } /* Create a new cluster node, with the specified flags. @@ -962,6 +968,7 @@ clusterNode *createClusterNode(char *nodename, int flags) { memset(node->slots,0,sizeof(node->slots)); node->slot_info_pairs = NULL; node->numslots = 0; + node->has_human_readable_name = 0; node->numslaves = 0; node->slaves = NULL; node->slaveof = NULL; @@ -1203,7 +1210,7 @@ clusterNode *clusterLookupNode(const char *name) { de = dictFind(server.cluster->nodes,s); sdsfree(s); - if (de == NULL){ + if (de == NULL) { /* Check if any node has the same human readable name*/ dictIterator *di; dictEntry *de2; @@ -1211,14 +1218,12 @@ clusterNode *clusterLookupNode(const char *name) { di = dictGetSafeIterator(server.cluster->nodes); while((de2 = dictNext(di)) != NULL) { clusterNode *node = dictGetVal(de2); - if (node->hname){ - if (strcmp(node->hname,name ) == 0) - return node; - } + if (strcmp(node->human_readable_name,name) == 0) + return node; } dictReleaseIterator(di); return NULL; - } + } return dictGetVal(de); } @@ -1376,9 +1381,9 @@ void clusterHandleConfigEpochCollision(clusterNode *sender) { myself->configEpoch = server.cluster->currentEpoch; clusterSaveConfigOrDie(1); serverLog(LL_VERBOSE, - "WARNING: configEpoch collision with node %.40s." + "WARNING: configEpoch collision with node %.40s %s." " configEpoch set to %llu", - sender->name, + sender->name, sender->human_readable_name, (unsigned long long) myself->configEpoch); } @@ -1494,7 +1499,7 @@ void markNodeAsFailingIfNeeded(clusterNode *node) { if (failures < needed_quorum) return; /* No weak agreement from masters. */ serverLog(LL_NOTICE, - "Marking node %.40s as failing (quorum reached).", node->name); + "Marking node %.40s %s as failing (quorum reached).", node->name, node ->human_readable_name); /* Mark the node as failing. */ node->flags &= ~CLUSTER_NODE_PFAIL; @@ -1522,8 +1527,8 @@ void clearNodeFailureIfNeeded(clusterNode *node) { * node again. */ if (nodeIsSlave(node) || node->numslots == 0) { serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s: %s is reachable again.", - node->name, + "Clear FAIL state for node %.40s %s: %s is reachable again.", + node->name, node->human_readable_name, nodeIsSlave(node) ? "replica" : "master without slots"); node->flags &= ~CLUSTER_NODE_FAIL; clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); @@ -1538,8 +1543,8 @@ void clearNodeFailureIfNeeded(clusterNode *node) { (server.cluster_node_timeout * CLUSTER_FAIL_UNDO_TIME_MULT)) { serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s: is reachable again and nobody is serving its slots after some time.", - node->name); + "Clear FAIL state for node %.40s %s: is reachable again and nobody is serving its slots after some time.", + node->name, node->human_readable_name); node->flags &= ~CLUSTER_NODE_FAIL; clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); } @@ -1660,15 +1665,15 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { if (flags & (CLUSTER_NODE_FAIL|CLUSTER_NODE_PFAIL)) { if (clusterNodeAddFailureReport(node,sender)) { serverLog(LL_VERBOSE, - "Node %.40s reported node %.40s as not reachable.", - sender->name, node->name); + "Node %.40s %s reported node %.40s %s as not reachable.", + sender->name, sender->human_readable_name, node->name, node->human_readable_name); } markNodeAsFailingIfNeeded(node); } else { if (clusterNodeDelFailureReport(node,sender)) { serverLog(LL_VERBOSE, - "Node %.40s reported node %.40s is back online.", - sender->name, node->name); + "Node %.40s %s reported node %.40s %s is back online.", + sender->name, sender->human_readable_name, node->name, node->human_readable_name); } } } @@ -1713,7 +1718,10 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { node->pport = ntohs(g->pport); node->cport = ntohs(g->cport); node->flags &= ~CLUSTER_NODE_NOADDR; - setClusterNodeName(node); + if (hdr->has_human_readable_name) + setManualClusterNodeName(node, hdr->human_readable_name); + else + setClusterNodeName(node); } } else { /* If it's not in NOADDR state and we don't have it, we @@ -1735,7 +1743,10 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { node->port = ntohs(g->port); node->pport = ntohs(g->pport); node->cport = ntohs(g->cport); - setClusterNodeName(node); + if (hdr->has_human_readable_name) + setManualClusterNodeName(node, hdr->human_readable_name); + else + setClusterNodeName(node); clusterAddNode(node); } } @@ -1794,11 +1805,14 @@ int nodeUpdateAddressIfNeeded(clusterNode *node, clusterLink *link, node->port = port; node->pport = pport; node->cport = cport; - setClusterNodeName(node); + if (hdr->has_human_readable_name) + setManualClusterNodeName(node, hdr->human_readable_name); + else + setClusterNodeName(node); if (node->link) freeClusterLink(node->link); node->flags &= ~CLUSTER_NODE_NOADDR; - serverLog(LL_WARNING,"Address updated for node %.40s, now %s:%d", - node->name, node->ip, node->port); + serverLog(LL_WARNING,"Address updated for node %.40s %s, now %s:%d", + node->name, node->human_readable_name, node->ip, node->port); /* Check if this is our master and we have to change the * replication target as well. */ @@ -1927,7 +1941,7 @@ void clusterUpdateSlotsConfigWith(clusterNode *sender, uint64_t senderConfigEpoc sender_slots == migrated_our_slots)) { serverLog(LL_WARNING, "Configuration change detected. Reconfiguring myself " - "as a replica of %.40s", sender->name); + "as a replica of %.40s %s", sender->name, sender->human_readable_name); clusterSetMaster(sender); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| CLUSTER_TODO_UPDATE_STATE| @@ -2221,6 +2235,10 @@ int clusterProcessPacket(clusterLink *link) { } } + if (sender && strcmp(sender->human_readable_name,hdr->human_readable_name) != 0) { + strncpy(sender->human_readable_name, hdr->human_readable_name, CLUSTER_HUMAN_NAMELEN); + } + /* Add this node if it is new for us and the msg type is MEET. * In this stage we don't try to add the node with the right * flags, slaveof pointer, and so forth, as this details will be @@ -2261,8 +2279,15 @@ int clusterProcessPacket(clusterLink *link) { * IP/port of the node with the new one. */ if (sender) { serverLog(LL_VERBOSE, - "Handshake: we already know node %.40s, " - "updating the address if needed.", sender->name); + "Handshake: we already know node %.40s %s, " + "updating the address if needed.", sender->name, sender->human_readable_name); + + if (hdr->has_human_readable_name) { + setManualClusterNodeName(sender, hdr->human_readable_name); + } + else + setClusterNodeName(sender); + if (nodeUpdateAddressIfNeeded(sender,link,hdr)) { clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| @@ -2277,8 +2302,8 @@ int clusterProcessPacket(clusterLink *link) { /* First thing to do is replacing the random name with the * right node name if this was a handshake stage. */ clusterRenameNode(link->node, hdr->sender); - serverLog(LL_DEBUG,"Handshake with node %.40s completed.", - link->node->name); + serverLog(LL_DEBUG,"Handshake with node %.40s %s completed.", + link->node->name, link->node->human_readable_name); link->node->flags &= ~CLUSTER_NODE_HANDSHAKE; link->node->flags |= flags&(CLUSTER_NODE_MASTER|CLUSTER_NODE_SLAVE); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG); @@ -2288,8 +2313,8 @@ int clusterProcessPacket(clusterLink *link) { /* If the reply has a non matching node ID we * disconnect this node and set it as not having an associated * address. */ - serverLog(LL_DEBUG,"PONG contains mismatching sender ID. About node %.40s added %d ms ago, having flags %d", - link->node->name, + serverLog(LL_DEBUG,"PONG contains mismatching sender ID. About node %.40s %s added %d ms ago, having flags %d", + link->node->name, link->node->human_readable_name, (int)(now-(link->node->ctime)), link->node->flags); link->node->flags |= CLUSTER_NODE_NOADDR; @@ -2435,9 +2460,10 @@ int clusterProcessPacket(clusterLink *link) { senderConfigEpoch) { serverLog(LL_VERBOSE, - "Node %.40s has old slots configuration, sending " - "an UPDATE message about %.40s", - sender->name, server.cluster->slots[j]->name); + "Node %.40s %s has old slots configuration, sending " + "an UPDATE message about %.40s %s", + sender->name, sender->human_readable_name, + server.cluster->slots[j]->name, server.cluster->slots[j]->human_readable_name); clusterSendUpdate(sender->link, server.cluster->slots[j]); @@ -2625,8 +2651,8 @@ void clusterLinkConnectHandler(connection *conn) { /* Check if connection succeeded */ if (connGetState(conn) != CONN_STATE_CONNECTED) { - serverLog(LL_VERBOSE, "Connection with Node %.40s at %s:%d failed: %s", - node->name, node->ip, node->cport, + serverLog(LL_VERBOSE, "Connection with Node %.40s %s at %s:%d failed: %s", + node->name, node->human_readable_name, node->ip, node->cport, connGetLastError(conn)); freeClusterLink(link); return; @@ -2657,8 +2683,8 @@ void clusterLinkConnectHandler(connection *conn) { * normal PING packets. */ node->flags &= ~CLUSTER_NODE_MEET; - serverLog(LL_DEBUG,"Connecting with Node %.40s at %s:%d", - node->name, node->ip, node->cport); + serverLog(LL_DEBUG,"Connecting with Node %.40s %s at %s:%d", + node->name, node->human_readable_name, node->ip, node->cport); } /* Read data. Try to read the first field of the header first to check the @@ -2798,6 +2824,8 @@ void clusterBuildMessageHdr(clusterMsg *hdr, int type) { hdr->sig[3] = 'b'; hdr->type = htons(type); memcpy(hdr->sender,myself->name,CLUSTER_NAMELEN); + strncpy(hdr->human_readable_name,myself->human_readable_name,CLUSTER_HUMAN_NAMELEN); + hdr->has_human_readable_name = myself->has_human_readable_name; /* If cluster-announce-ip option is enabled, force the receivers of our * packets to use the specified address for this node. Otherwise if the @@ -2876,6 +2904,7 @@ void clusterSetGossipEntry(clusterMsg *hdr, int i, clusterNode *n) { gossip->cport = htons(n->cport); gossip->flags = htons(n->flags); gossip->pport = htons(n->pport); + gossip->has_human_readable_name = n->has_human_readable_name; gossip->notused1 = 0; } @@ -3300,8 +3329,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * request, if the request epoch was greater. */ if (requestCurrentEpoch < server.cluster->currentEpoch) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: reqEpoch (%llu) < curEpoch(%llu)", - node->name, + "Failover auth denied to %.40s %s: reqEpoch (%llu) < curEpoch(%llu)", + node->name, node->human_readable_name, (unsigned long long) requestCurrentEpoch, (unsigned long long) server.cluster->currentEpoch); return; @@ -3310,8 +3339,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { /* I already voted for this epoch? Return ASAP. */ if (server.cluster->lastVoteEpoch == server.cluster->currentEpoch) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: already voted for epoch %llu", - node->name, + "Failover auth denied to %.40s %s: already voted for epoch %llu", + node->name, node->human_readable_name, (unsigned long long) server.cluster->currentEpoch); return; } @@ -3324,16 +3353,16 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { { if (nodeIsMaster(node)) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: it is a master node", - node->name); + "Failover auth denied to %.40s %s: it is a master node", + node->name, node->human_readable_name); } else if (master == NULL) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: I don't know its master", - node->name); + "Failover auth denied to %.40s %s: I don't know its master", + node->name, node->human_readable_name); } else if (!nodeFailed(master)) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: its master is up", - node->name); + "Failover auth denied to %.40s %s: its master is up", + node->name, node->human_readable_name); } return; } @@ -3344,9 +3373,9 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { if (mstime() - node->slaveof->voted_time < server.cluster_node_timeout * 2) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: " + "Failover auth denied to %.40s %s: " "can't vote about this master before %lld milliseconds", - node->name, + node->name, node->human_readable_name, (long long) ((server.cluster_node_timeout*2)- (mstime() - node->slaveof->voted_time))); return; @@ -3366,9 +3395,9 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * is served by a master with a greater configEpoch than the one claimed * by the slave requesting our vote. Refuse to vote for this slave. */ serverLog(LL_WARNING, - "Failover auth denied to %.40s: " + "Failover auth denied to %.40s %s: " "slot %d epoch (%llu) > reqEpoch (%llu)", - node->name, j, + node->name, node->human_readable_name, j, (unsigned long long) server.cluster->slots[j]->configEpoch, (unsigned long long) requestConfigEpoch); return; @@ -3379,8 +3408,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { node->slaveof->voted_time = mstime(); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG|CLUSTER_TODO_FSYNC_CONFIG); clusterSendFailoverAuth(node); - serverLog(LL_WARNING, "Failover auth granted to %.40s for epoch %llu", - node->name, (unsigned long long) server.cluster->currentEpoch); + serverLog(LL_WARNING, "Failover auth granted to %.40s %s for epoch %llu", + node->name, node->human_readable_name, (unsigned long long) server.cluster->currentEpoch); } /* This function returns the "rank" of this instance, a slave, in the context @@ -3608,7 +3637,7 @@ void clusterHandleSlaveFailover(void) { if (server.cluster->mf_end) { server.cluster->failover_auth_time = mstime(); server.cluster->failover_auth_rank = 0; - clusterDoBeforeSleep(CLUSTER_TODO_HANDLE_FAILOVER); + clusterDoBeforeSleep(CLUSTER_TODO_HANDLE_FAILOVER); } serverLog(LL_WARNING, "Start of election delayed for %lld milliseconds " @@ -3797,8 +3826,8 @@ void clusterHandleSlaveMigration(int max_slaves) { (mstime()-target->orphaned_time) > CLUSTER_SLAVE_MIGRATION_DELAY && !(server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_FAILOVER)) { - serverLog(LL_WARNING,"Migrating to orphaned master %.40s", - target->name); + serverLog(LL_WARNING,"Migrating to orphaned master %.40s %s", + target->name, target->human_readable_name); clusterSetMaster(target); } } @@ -4045,7 +4074,7 @@ void clusterCron(void) { } } if (min_pong_node) { - serverLog(LL_DEBUG,"Pinging node %.40s", min_pong_node->name); + serverLog(LL_DEBUG,"Pinging node %.40s %s", min_pong_node->name, min_pong_node->human_readable_name); clusterSendPing(min_pong_node->link, CLUSTERMSG_TYPE_PING); } } @@ -4145,8 +4174,8 @@ void clusterCron(void) { /* Timeout reached. Set the node as possibly failing if it is * not already in this state. */ if (!(node->flags & (CLUSTER_NODE_PFAIL|CLUSTER_NODE_FAIL))) { - serverLog(LL_DEBUG,"*** NODE %.40s possibly failing", - node->name); + serverLog(LL_DEBUG,"*** NODE %.40s %s possibly failing", + node->name, node->human_readable_name); node->flags |= CLUSTER_NODE_PFAIL; update_state = 1; } @@ -4656,6 +4685,9 @@ sds clusterGenNodeDescription(clusterNode *node, int use_pport) { else ci = sdscatlen(ci,"-",1); + /* Adding has human readable name */ + ci = sdscatfmt(ci," %i",node->has_human_readable_name); + unsigned long long nodeEpoch = node->configEpoch; if (nodeIsSlave(node) && node->slaveof) { nodeEpoch = node->slaveof->configEpoch; @@ -5220,10 +5252,12 @@ void clusterCommand(client *c) { "MYID", " Return the node id.", "MYNAME", -" Return the node name.", +" Return the human readable node name.", +"SETNAME ", +" Sets the human-readable node name.", "NODES", " Return cluster configuration seen by node. Output format:", -" ...", +" ...", "REPLICATE ", " Configure current node as replica to .", "RESET [HARD|SOFT]", @@ -5288,11 +5322,17 @@ NULL /* CLUSTER MYID */ addReplyBulkCBuffer(c,myself->name, CLUSTER_NAMELEN); } else if (!strcasecmp(c->argv[1]->ptr,"myname") && c->argc == 2) { - /* CLUSTER MYID */ - if (myself->hname) - addReplyBulkCBuffer(c,myself->hname, strlen(myself->hname)); + /* CLUSTER MYNAME */ + if (myself->human_readable_name[0] != '\0') + addReplyBulkCBuffer(c,myself->human_readable_name, strlen(myself->human_readable_name)); else addReplyError(c,"Node is not assigned name yet."); + } else if (!strcasecmp(c->argv[1]->ptr,"setname") && c->argc == 3) { + /* CLUSTER SETNAME */ + if (setManualClusterNodeName(myself,c->argv[2]->ptr)) + addReply(c,shared.ok); + else + addReplyError(c,"Error setting the name of the node."); } else if (!strcasecmp(c->argv[1]->ptr,"slots") && c->argc == 2) { /* CLUSTER SLOTS */ clusterReplyMultiBulkSlots(c); diff --git a/src/cluster.h b/src/cluster.h index b9f579264ae..6bc0e26c27f 100644 --- a/src/cluster.h +++ b/src/cluster.h @@ -9,6 +9,7 @@ #define CLUSTER_OK 0 /* Everything looks ok */ #define CLUSTER_FAIL 1 /* The cluster can't work */ #define CLUSTER_NAMELEN 40 /* sha1 hex length */ +#define CLUSTER_HUMAN_NAMELEN 64 /* Max length of human readable node name */ #define CLUSTER_PORT_INCR 10000 /* Cluster port = baseport + PORT_INCR */ /* The following defines are amount of time, sometimes expressed as @@ -115,7 +116,7 @@ typedef struct clusterNodeFailReport { typedef struct clusterNode { mstime_t ctime; /* Node object creation time. */ char name[CLUSTER_NAMELEN]; /* Node name, hex string, sha1-size */ - char* hname; /* Human readable name for node */ + char human_readable_name[CLUSTER_HUMAN_NAMELEN]; /* Human readable name for node */ int flags; /* CLUSTER_NODE_... */ uint64_t configEpoch; /* Last configEpoch observed for this node */ unsigned char slots[CLUSTER_SLOTS/8]; /* slots handled by this node */ @@ -144,6 +145,7 @@ typedef struct clusterNode { clusterLink *link; /* TCP/IP link established toward this node */ clusterLink *inbound_link; /* TCP/IP link accepted from this node */ list *fail_reports; /* List of nodes signaling this as failing */ + int has_human_readable_name; /* Indicates whether custom nodename is used */ } clusterNode; /* Slot to keys for a single slot. The keys in the same slot are linked together @@ -217,11 +219,13 @@ typedef struct { uint32_t ping_sent; uint32_t pong_received; char ip[NET_IP_STR_LEN]; /* IP address last time it was seen */ + char human_readable_name[CLUSTER_HUMAN_NAMELEN]; /* Human readable name for node */ uint16_t port; /* base port last time it was seen */ uint16_t cport; /* cluster port last time it was seen */ uint16_t flags; /* node->flags copy */ uint16_t pport; /* plaintext-port, when base port is TLS */ uint16_t notused1; + int has_human_readable_name; /* Indicates whether custom nodename is used */ } clusterMsgDataGossip; typedef struct { @@ -321,6 +325,7 @@ typedef struct { unsigned char myslots[CLUSTER_SLOTS/8]; char slaveof[CLUSTER_NAMELEN]; char myip[NET_IP_STR_LEN]; /* Sender IP, if not all zeroed. */ + char human_readable_name[CLUSTER_HUMAN_NAMELEN]; uint16_t extensions; /* Number of extensions sent along with this packet. */ char notused1[30]; /* 30 bytes reserved for future usage. */ uint16_t pport; /* Sender TCP plaintext port, if base port is TLS */ @@ -329,6 +334,7 @@ typedef struct { unsigned char state; /* Cluster state from the POV of the sender */ unsigned char mflags[3]; /* Message flags: CLUSTERMSG_FLAG[012]_... */ union clusterMsgData data; + int has_human_readable_name; /* Indicates whether custom nodename is used */ } clusterMsg; /* clusterMsg defines the gossip wire protocol exchanged among Redis cluster diff --git a/src/redis-cli.c b/src/redis-cli.c index 051ab94e9d9..b6b66a0612c 100644 --- a/src/redis-cli.c +++ b/src/redis-cli.c @@ -4585,9 +4585,10 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, lines = p + 1; char *name = NULL, *addr = NULL, *flags = NULL, *master_id = NULL, *ping_sent = NULL, *ping_recv = NULL, *config_epoch = NULL, - *link_status = NULL, *hname = NULL; + *link_status = NULL, *human_readable_name = NULL, *has_human_readable_name = NULL; UNUSED(link_status); - UNUSED(hname); + UNUSED(human_readable_name); + UNUSED(has_human_readable_name); int i = 0; while ((p = strchr(line, ' ')) != NULL) { *p = '\0'; @@ -4595,16 +4596,17 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, line = p + 1; switch(i++){ case 0: name = token; break; - case 1: hname = token; break; + case 1: human_readable_name = token; break; case 2: addr = token; break; case 3: flags = token; break; case 4: master_id = token; break; - case 5: ping_sent = token; break; - case 6: ping_recv = token; break; - case 7: config_epoch = token; break; - case 8: link_status = token; break; + case 5: has_human_readable_name = token; break; + case 6: ping_sent = token; break; + case 7: ping_recv = token; break; + case 8: config_epoch = token; break; + case 9: link_status = token; break; } - if (i == 9) break; // Slots + if (i == 10) break; // Slots } if (!flags) { success = 0; @@ -4616,7 +4618,7 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, node->flags |= CLUSTER_MANAGER_FLAG_MYSELF; currentNode = node; clusterManagerNodeResetSlots(node); - if (i == 9) { + if (i == 10) { int remaining = strlen(line); while (remaining > 0) { p = strchr(line, ' '); diff --git a/tests/cluster/cluster.tcl b/tests/cluster/cluster.tcl index 802b5b6f573..7f6b7e71ab6 100644 --- a/tests/cluster/cluster.tcl +++ b/tests/cluster/cluster.tcl @@ -22,11 +22,12 @@ proc get_cluster_nodes id { addr [lindex $args 2] \ flags [split [lindex $args 3] ,] \ slaveof [lindex $args 4] \ - ping_sent [lindex $args 5] \ - pong_recv [lindex $args 6] \ - config_epoch [lindex $args 7] \ - linkstate [lindex $args 8] \ - slots [lrange $args 9 end] \ + customName [lindex $args 5] \ + ping_sent [lindex $args 6] \ + pong_recv [lindex $args 7] \ + config_epoch [lindex $args 8] \ + linkstate [lindex $args 9] \ + slots [lrange $args 10 end] \ ] lappend nodes $node } diff --git a/tests/support/cluster.tcl b/tests/support/cluster.tcl index 8c628dcd3f1..2ead91f43d1 100644 --- a/tests/support/cluster.tcl +++ b/tests/support/cluster.tcl @@ -104,8 +104,8 @@ proc ::redis_cluster::__method__refresh_nodes_map {id} { set line [string trim $line] if {$line eq {}} continue set args [split $line " "] - lassign $args nodeid name addr flags slaveof pingsent pongrecv configepoch linkstate - set slots [lrange $args 9 end] + lassign $args nodeid name addr flags slaveof customname pingsent pongrecv configepoch linkstate + set slots [lrange $args 10 end] set addr [lindex [split $addr @] 0] if {$addr eq {:0}} { set addr $start_host:$start_port @@ -126,6 +126,7 @@ proc ::redis_cluster::__method__refresh_nodes_map {id} { port $port \ flags $flags \ slaveof $slaveof \ + customname $customname \ slots $slots \ link $link \ ] From 413dca04c3d3311f62681265a91a1470d96b9e5c Mon Sep 17 00:00:00 2001 From: hwware Date: Wed, 12 Jan 2022 14:08:57 -0500 Subject: [PATCH 56/79] update codes to fix error in rebase --- src/cluster.c | 210 ++++++++++++-------------------------- src/cluster.h | 7 -- src/help.h | 5 - src/redis-cli.c | 26 ++--- tests/cluster/cluster.tcl | 18 ++-- tests/support/cluster.tcl | 5 +- 6 files changed, 85 insertions(+), 186 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index 49f3aba7e4f..b03a8dc305c 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -48,7 +48,6 @@ clusterNode *myself = NULL; clusterNode *createClusterNode(char *nodename, int flags); void clusterAddNode(clusterNode *node); -void setClusterNodeName(clusterNode *node); void clusterAcceptHandler(aeEventLoop *el, int fd, void *privdata, int mask); void clusterReadHandler(connection *conn); void clusterSendPing(clusterLink *link, int type); @@ -254,7 +253,7 @@ int clusterLoadConfig(char *filename) { * stored in nodes.conf. It is received later over the bus protocol. */ /* Parse flags */ - p = s = argv[3]; + p = s = argv[2]; while(p) { p = strchr(s,','); if (p) *p = '\0'; @@ -287,28 +286,25 @@ int clusterLoadConfig(char *filename) { /* Get master if any. Set the master and populate master's * slave list. */ - if (argv[4][0] != '-') { - master = clusterLookupNode(argv[4]); + if (argv[3][0] != '-') { + master = clusterLookupNode(argv[3]); if (!master) { - master = createClusterNode(argv[4],0); + master = createClusterNode(argv[3],0); clusterAddNode(master); } n->slaveof = master; clusterNodeAddSlave(master,n); } - /* Custom nodename */ - n->has_human_readable_name = atoi(argv[5]); - /* Set ping sent / pong received timestamps */ - if (atoi(argv[6])) n->ping_sent = mstime(); - if (atoi(argv[7])) n->pong_received = mstime(); + if (atoi(argv[4])) n->ping_sent = mstime(); + if (atoi(argv[5])) n->pong_received = mstime(); /* Set configEpoch for this node. */ - n->configEpoch = strtoull(argv[8],NULL,10); + n->configEpoch = strtoull(argv[6],NULL,10); /* Populate hash slots served by this instance. */ - for (j = 10; j < argc; j++) { + for (j = 8; j < argc; j++) { int start, stop; if (argv[j][0] == '[') { @@ -362,7 +358,7 @@ int clusterLoadConfig(char *filename) { zfree(line); fclose(fp); - serverLog(LL_NOTICE,"Node configuration loaded, I'm %.40s %s", myself->name, myself->human_readable_name); + serverLog(LL_NOTICE,"Node configuration loaded, I'm %.40s", myself->name); /* Something that should never happen: currentEpoch smaller than * the max epoch found in the nodes configuration. However we handle this @@ -634,8 +630,8 @@ void clusterInit(void) { * by the createClusterNode() function. */ myself = server.cluster->myself = createClusterNode(NULL,CLUSTER_NODE_MYSELF|CLUSTER_NODE_MASTER); - serverLog(LL_NOTICE,"No cluster configuration found, I'm %.40s %s", - myself->name, myself->human_readable_name); + serverLog(LL_NOTICE,"No cluster configuration found, I'm %.40s", + myself->name); clusterAddNode(myself); saveconf = 1; } @@ -742,7 +738,7 @@ void clusterReset(int hard) { sdsfree(oldname); getRandomHexChars(myself->name, CLUSTER_NAMELEN); clusterAddNode(myself); - serverLog(LL_NOTICE,"Node hard reset, now I'm %.40s %s", myself->name, myself->human_readable_name); + serverLog(LL_NOTICE,"Node hard reset, now I'm %.40s", myself->name); } /* Make sure to persist the new config and update the state. */ @@ -929,25 +925,6 @@ unsigned int keyHashSlot(char *key, int keylen) { * CLUSTER node API * -------------------------------------------------------------------------- */ -/* Assign a human readable name to nodes for clusters*/ -void setClusterNodeName(clusterNode *node) { - if (node->has_human_readable_name == 1) - return; - char ip[NET_IP_STR_LEN]; - strcpy(ip,node->ip); - sprintf(node->human_readable_name, "%s_%u", ip,(unsigned int)node->port); -} - -/* Manually assign a human readable name to nodes for clusters*/ -int setManualClusterNodeName(clusterNode *node, char * newname) { - if (newname == NULL) - return 0; - memcpy(node->human_readable_name, newname, strlen(newname) + 1); - node->has_human_readable_name = 1; - clusterSaveConfig(1); - return 1; -} - /* Create a new cluster node, with the specified flags. * If "nodename" is NULL this is considered a first handshake and a random * node name is assigned to this node (it will be fixed later when we'll @@ -968,7 +945,6 @@ clusterNode *createClusterNode(char *nodename, int flags) { memset(node->slots,0,sizeof(node->slots)); node->slot_info_pairs = NULL; node->numslots = 0; - node->has_human_readable_name = 0; node->numslaves = 0; node->slaves = NULL; node->slaveof = NULL; @@ -1211,17 +1187,6 @@ clusterNode *clusterLookupNode(const char *name) { de = dictFind(server.cluster->nodes,s); sdsfree(s); if (de == NULL) { - /* Check if any node has the same human readable name*/ - dictIterator *di; - dictEntry *de2; - - di = dictGetSafeIterator(server.cluster->nodes); - while((de2 = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de2); - if (strcmp(node->human_readable_name,name) == 0) - return node; - } - dictReleaseIterator(di); return NULL; } return dictGetVal(de); @@ -1381,9 +1346,9 @@ void clusterHandleConfigEpochCollision(clusterNode *sender) { myself->configEpoch = server.cluster->currentEpoch; clusterSaveConfigOrDie(1); serverLog(LL_VERBOSE, - "WARNING: configEpoch collision with node %.40s %s." + "WARNING: configEpoch collision with node %.40s." " configEpoch set to %llu", - sender->name, sender->human_readable_name, + sender->name, (unsigned long long) myself->configEpoch); } @@ -1499,7 +1464,7 @@ void markNodeAsFailingIfNeeded(clusterNode *node) { if (failures < needed_quorum) return; /* No weak agreement from masters. */ serverLog(LL_NOTICE, - "Marking node %.40s %s as failing (quorum reached).", node->name, node ->human_readable_name); + "Marking node %.40s as failing (quorum reached).", node->name); /* Mark the node as failing. */ node->flags &= ~CLUSTER_NODE_PFAIL; @@ -1527,8 +1492,8 @@ void clearNodeFailureIfNeeded(clusterNode *node) { * node again. */ if (nodeIsSlave(node) || node->numslots == 0) { serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s %s: %s is reachable again.", - node->name, node->human_readable_name, + "Clear FAIL state for node %.40s : %s is reachable again.", + node->name, nodeIsSlave(node) ? "replica" : "master without slots"); node->flags &= ~CLUSTER_NODE_FAIL; clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); @@ -1543,8 +1508,8 @@ void clearNodeFailureIfNeeded(clusterNode *node) { (server.cluster_node_timeout * CLUSTER_FAIL_UNDO_TIME_MULT)) { serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s %s: is reachable again and nobody is serving its slots after some time.", - node->name, node->human_readable_name); + "Clear FAIL state for node %.40s : is reachable again and nobody is serving its slots after some time.", + node->name); node->flags &= ~CLUSTER_NODE_FAIL; clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); } @@ -1626,7 +1591,6 @@ int clusterStartHandshake(char *ip, int port, int cport) { memcpy(n->ip,norm_ip,sizeof(n->ip)); n->port = port; n->cport = cport; - setClusterNodeName(n); clusterAddNode(n); return 1; } @@ -1665,15 +1629,15 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { if (flags & (CLUSTER_NODE_FAIL|CLUSTER_NODE_PFAIL)) { if (clusterNodeAddFailureReport(node,sender)) { serverLog(LL_VERBOSE, - "Node %.40s %s reported node %.40s %s as not reachable.", - sender->name, sender->human_readable_name, node->name, node->human_readable_name); + "Node %.40s reported node %.40s as not reachable.", + sender->name, node->name); } markNodeAsFailingIfNeeded(node); } else { if (clusterNodeDelFailureReport(node,sender)) { serverLog(LL_VERBOSE, - "Node %.40s %s reported node %.40s %s is back online.", - sender->name, sender->human_readable_name, node->name, node->human_readable_name); + "Node %.40s reported node %.40s is back online.", + sender->name, node->name); } } } @@ -1718,10 +1682,6 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { node->pport = ntohs(g->pport); node->cport = ntohs(g->cport); node->flags &= ~CLUSTER_NODE_NOADDR; - if (hdr->has_human_readable_name) - setManualClusterNodeName(node, hdr->human_readable_name); - else - setClusterNodeName(node); } } else { /* If it's not in NOADDR state and we don't have it, we @@ -1743,10 +1703,6 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { node->port = ntohs(g->port); node->pport = ntohs(g->pport); node->cport = ntohs(g->cport); - if (hdr->has_human_readable_name) - setManualClusterNodeName(node, hdr->human_readable_name); - else - setClusterNodeName(node); clusterAddNode(node); } } @@ -1805,14 +1761,10 @@ int nodeUpdateAddressIfNeeded(clusterNode *node, clusterLink *link, node->port = port; node->pport = pport; node->cport = cport; - if (hdr->has_human_readable_name) - setManualClusterNodeName(node, hdr->human_readable_name); - else - setClusterNodeName(node); if (node->link) freeClusterLink(node->link); node->flags &= ~CLUSTER_NODE_NOADDR; - serverLog(LL_WARNING,"Address updated for node %.40s %s, now %s:%d", - node->name, node->human_readable_name, node->ip, node->port); + serverLog(LL_WARNING,"Address updated for node %.40s , now %s:%d", + node->name, node->ip, node->port); /* Check if this is our master and we have to change the * replication target as well. */ @@ -1941,7 +1893,7 @@ void clusterUpdateSlotsConfigWith(clusterNode *sender, uint64_t senderConfigEpoc sender_slots == migrated_our_slots)) { serverLog(LL_WARNING, "Configuration change detected. Reconfiguring myself " - "as a replica of %.40s %s", sender->name, sender->human_readable_name); + "as a replica of %.40s ", sender->name); clusterSetMaster(sender); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| CLUSTER_TODO_UPDATE_STATE| @@ -2228,17 +2180,12 @@ int clusterProcessPacket(clusterLink *link) { strcmp(ip,myself->ip)) { memcpy(myself->ip,ip,NET_IP_STR_LEN); - setClusterNodeName(myself); serverLog(LL_WARNING,"IP address for this node updated to %s", myself->ip); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG); } } - if (sender && strcmp(sender->human_readable_name,hdr->human_readable_name) != 0) { - strncpy(sender->human_readable_name, hdr->human_readable_name, CLUSTER_HUMAN_NAMELEN); - } - /* Add this node if it is new for us and the msg type is MEET. * In this stage we don't try to add the node with the right * flags, slaveof pointer, and so forth, as this details will be @@ -2251,7 +2198,6 @@ int clusterProcessPacket(clusterLink *link) { node->port = ntohs(hdr->port); node->pport = ntohs(hdr->pport); node->cport = ntohs(hdr->cport); - setClusterNodeName(node); clusterAddNode(node); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG); } @@ -2279,14 +2225,8 @@ int clusterProcessPacket(clusterLink *link) { * IP/port of the node with the new one. */ if (sender) { serverLog(LL_VERBOSE, - "Handshake: we already know node %.40s %s, " - "updating the address if needed.", sender->name, sender->human_readable_name); - - if (hdr->has_human_readable_name) { - setManualClusterNodeName(sender, hdr->human_readable_name); - } - else - setClusterNodeName(sender); + "Handshake: we already know node %.40s , " + "updating the address if needed.", sender->name); if (nodeUpdateAddressIfNeeded(sender,link,hdr)) { @@ -2302,8 +2242,8 @@ int clusterProcessPacket(clusterLink *link) { /* First thing to do is replacing the random name with the * right node name if this was a handshake stage. */ clusterRenameNode(link->node, hdr->sender); - serverLog(LL_DEBUG,"Handshake with node %.40s %s completed.", - link->node->name, link->node->human_readable_name); + serverLog(LL_DEBUG,"Handshake with node %.40s completed.", + link->node->name); link->node->flags &= ~CLUSTER_NODE_HANDSHAKE; link->node->flags |= flags&(CLUSTER_NODE_MASTER|CLUSTER_NODE_SLAVE); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG); @@ -2313,8 +2253,8 @@ int clusterProcessPacket(clusterLink *link) { /* If the reply has a non matching node ID we * disconnect this node and set it as not having an associated * address. */ - serverLog(LL_DEBUG,"PONG contains mismatching sender ID. About node %.40s %s added %d ms ago, having flags %d", - link->node->name, link->node->human_readable_name, + serverLog(LL_DEBUG,"PONG contains mismatching sender ID. About node %.40s added %d ms ago, having flags %d", + link->node->name, (int)(now-(link->node->ctime)), link->node->flags); link->node->flags |= CLUSTER_NODE_NOADDR; @@ -2460,10 +2400,10 @@ int clusterProcessPacket(clusterLink *link) { senderConfigEpoch) { serverLog(LL_VERBOSE, - "Node %.40s %s has old slots configuration, sending " - "an UPDATE message about %.40s %s", - sender->name, sender->human_readable_name, - server.cluster->slots[j]->name, server.cluster->slots[j]->human_readable_name); + "Node %.40s has old slots configuration, sending " + "an UPDATE message about %.40s ", + sender->name, + server.cluster->slots[j]->name); clusterSendUpdate(sender->link, server.cluster->slots[j]); @@ -2651,8 +2591,8 @@ void clusterLinkConnectHandler(connection *conn) { /* Check if connection succeeded */ if (connGetState(conn) != CONN_STATE_CONNECTED) { - serverLog(LL_VERBOSE, "Connection with Node %.40s %s at %s:%d failed: %s", - node->name, node->human_readable_name, node->ip, node->cport, + serverLog(LL_VERBOSE, "Connection with Node %.40s at %s:%d failed: %s", + node->name, node->ip, node->cport, connGetLastError(conn)); freeClusterLink(link); return; @@ -2683,8 +2623,8 @@ void clusterLinkConnectHandler(connection *conn) { * normal PING packets. */ node->flags &= ~CLUSTER_NODE_MEET; - serverLog(LL_DEBUG,"Connecting with Node %.40s %s at %s:%d", - node->name, node->human_readable_name, node->ip, node->cport); + serverLog(LL_DEBUG,"Connecting with Node %.40s at %s:%d", + node->name, node->ip, node->cport); } /* Read data. Try to read the first field of the header first to check the @@ -2824,9 +2764,7 @@ void clusterBuildMessageHdr(clusterMsg *hdr, int type) { hdr->sig[3] = 'b'; hdr->type = htons(type); memcpy(hdr->sender,myself->name,CLUSTER_NAMELEN); - strncpy(hdr->human_readable_name,myself->human_readable_name,CLUSTER_HUMAN_NAMELEN); - hdr->has_human_readable_name = myself->has_human_readable_name; - + /* If cluster-announce-ip option is enabled, force the receivers of our * packets to use the specified address for this node. Otherwise if the * first byte is zero, they'll do auto discovery. */ @@ -2904,7 +2842,6 @@ void clusterSetGossipEntry(clusterMsg *hdr, int i, clusterNode *n) { gossip->cport = htons(n->cport); gossip->flags = htons(n->flags); gossip->pport = htons(n->pport); - gossip->has_human_readable_name = n->has_human_readable_name; gossip->notused1 = 0; } @@ -3329,8 +3266,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * request, if the request epoch was greater. */ if (requestCurrentEpoch < server.cluster->currentEpoch) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: reqEpoch (%llu) < curEpoch(%llu)", - node->name, node->human_readable_name, + "Failover auth denied to %.40s : reqEpoch (%llu) < curEpoch(%llu)", + node->name, (unsigned long long) requestCurrentEpoch, (unsigned long long) server.cluster->currentEpoch); return; @@ -3339,8 +3276,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { /* I already voted for this epoch? Return ASAP. */ if (server.cluster->lastVoteEpoch == server.cluster->currentEpoch) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: already voted for epoch %llu", - node->name, node->human_readable_name, + "Failover auth denied to %.40s : already voted for epoch %llu", + node->name, (unsigned long long) server.cluster->currentEpoch); return; } @@ -3353,16 +3290,16 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { { if (nodeIsMaster(node)) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: it is a master node", - node->name, node->human_readable_name); + "Failover auth denied to %.40s : it is a master node", + node->name); } else if (master == NULL) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: I don't know its master", - node->name, node->human_readable_name); + "Failover auth denied to %.40s : I don't know its master", + node->name); } else if (!nodeFailed(master)) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: its master is up", - node->name, node->human_readable_name); + "Failover auth denied to %.40s : its master is up", + node->name); } return; } @@ -3373,9 +3310,9 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { if (mstime() - node->slaveof->voted_time < server.cluster_node_timeout * 2) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: " + "Failover auth denied to %.40s : " "can't vote about this master before %lld milliseconds", - node->name, node->human_readable_name, + node->name, (long long) ((server.cluster_node_timeout*2)- (mstime() - node->slaveof->voted_time))); return; @@ -3395,9 +3332,9 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * is served by a master with a greater configEpoch than the one claimed * by the slave requesting our vote. Refuse to vote for this slave. */ serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: " + "Failover auth denied to %.40s : " "slot %d epoch (%llu) > reqEpoch (%llu)", - node->name, node->human_readable_name, j, + node->name, j, (unsigned long long) server.cluster->slots[j]->configEpoch, (unsigned long long) requestConfigEpoch); return; @@ -3408,8 +3345,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { node->slaveof->voted_time = mstime(); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG|CLUSTER_TODO_FSYNC_CONFIG); clusterSendFailoverAuth(node); - serverLog(LL_WARNING, "Failover auth granted to %.40s %s for epoch %llu", - node->name, node->human_readable_name, (unsigned long long) server.cluster->currentEpoch); + serverLog(LL_WARNING, "Failover auth granted to %.40s for epoch %llu", + node->name, (unsigned long long) server.cluster->currentEpoch); } /* This function returns the "rank" of this instance, a slave, in the context @@ -3826,8 +3763,8 @@ void clusterHandleSlaveMigration(int max_slaves) { (mstime()-target->orphaned_time) > CLUSTER_SLAVE_MIGRATION_DELAY && !(server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_FAILOVER)) { - serverLog(LL_WARNING,"Migrating to orphaned master %.40s %s", - target->name, target->human_readable_name); + serverLog(LL_WARNING,"Migrating to orphaned master %.40s ", + target->name); clusterSetMaster(target); } } @@ -4074,7 +4011,7 @@ void clusterCron(void) { } } if (min_pong_node) { - serverLog(LL_DEBUG,"Pinging node %.40s %s", min_pong_node->name, min_pong_node->human_readable_name); + serverLog(LL_DEBUG,"Pinging node %.40s ", min_pong_node->name); clusterSendPing(min_pong_node->link, CLUSTERMSG_TYPE_PING); } } @@ -4174,8 +4111,8 @@ void clusterCron(void) { /* Timeout reached. Set the node as possibly failing if it is * not already in this state. */ if (!(node->flags & (CLUSTER_NODE_PFAIL|CLUSTER_NODE_FAIL))) { - serverLog(LL_DEBUG,"*** NODE %.40s %s possibly failing", - node->name, node->human_readable_name); + serverLog(LL_DEBUG,"*** NODE %.40s possibly failing", + node->name); node->flags |= CLUSTER_NODE_PFAIL; update_state = 1; } @@ -4683,10 +4620,7 @@ sds clusterGenNodeDescription(clusterNode *node, int use_pport) { if (node->slaveof) ci = sdscatlen(ci,node->slaveof->name,CLUSTER_NAMELEN); else - ci = sdscatlen(ci,"-",1); - - /* Adding has human readable name */ - ci = sdscatfmt(ci," %i",node->has_human_readable_name); + ci = sdscatlen(ci,"-",1); unsigned long long nodeEpoch = node->configEpoch; if (nodeIsSlave(node) && node->slaveof) { @@ -5251,13 +5185,9 @@ void clusterCommand(client *c) { " Connect nodes into a working cluster.", "MYID", " Return the node id.", -"MYNAME", -" Return the human readable node name.", -"SETNAME ", -" Sets the human-readable node name.", "NODES", " Return cluster configuration seen by node. Output format:", -" ...", +" ...", "REPLICATE ", " Configure current node as replica to .", "RESET [HARD|SOFT]", @@ -5321,18 +5251,6 @@ NULL } else if (!strcasecmp(c->argv[1]->ptr,"myid") && c->argc == 2) { /* CLUSTER MYID */ addReplyBulkCBuffer(c,myself->name, CLUSTER_NAMELEN); - } else if (!strcasecmp(c->argv[1]->ptr,"myname") && c->argc == 2) { - /* CLUSTER MYNAME */ - if (myself->human_readable_name[0] != '\0') - addReplyBulkCBuffer(c,myself->human_readable_name, strlen(myself->human_readable_name)); - else - addReplyError(c,"Node is not assigned name yet."); - } else if (!strcasecmp(c->argv[1]->ptr,"setname") && c->argc == 3) { - /* CLUSTER SETNAME */ - if (setManualClusterNodeName(myself,c->argv[2]->ptr)) - addReply(c,shared.ok); - else - addReplyError(c,"Error setting the name of the node."); } else if (!strcasecmp(c->argv[1]->ptr,"slots") && c->argc == 2) { /* CLUSTER SLOTS */ clusterReplyMultiBulkSlots(c); diff --git a/src/cluster.h b/src/cluster.h index 6bc0e26c27f..a944056eb96 100644 --- a/src/cluster.h +++ b/src/cluster.h @@ -9,7 +9,6 @@ #define CLUSTER_OK 0 /* Everything looks ok */ #define CLUSTER_FAIL 1 /* The cluster can't work */ #define CLUSTER_NAMELEN 40 /* sha1 hex length */ -#define CLUSTER_HUMAN_NAMELEN 64 /* Max length of human readable node name */ #define CLUSTER_PORT_INCR 10000 /* Cluster port = baseport + PORT_INCR */ /* The following defines are amount of time, sometimes expressed as @@ -116,7 +115,6 @@ typedef struct clusterNodeFailReport { typedef struct clusterNode { mstime_t ctime; /* Node object creation time. */ char name[CLUSTER_NAMELEN]; /* Node name, hex string, sha1-size */ - char human_readable_name[CLUSTER_HUMAN_NAMELEN]; /* Human readable name for node */ int flags; /* CLUSTER_NODE_... */ uint64_t configEpoch; /* Last configEpoch observed for this node */ unsigned char slots[CLUSTER_SLOTS/8]; /* slots handled by this node */ @@ -145,7 +143,6 @@ typedef struct clusterNode { clusterLink *link; /* TCP/IP link established toward this node */ clusterLink *inbound_link; /* TCP/IP link accepted from this node */ list *fail_reports; /* List of nodes signaling this as failing */ - int has_human_readable_name; /* Indicates whether custom nodename is used */ } clusterNode; /* Slot to keys for a single slot. The keys in the same slot are linked together @@ -219,13 +216,11 @@ typedef struct { uint32_t ping_sent; uint32_t pong_received; char ip[NET_IP_STR_LEN]; /* IP address last time it was seen */ - char human_readable_name[CLUSTER_HUMAN_NAMELEN]; /* Human readable name for node */ uint16_t port; /* base port last time it was seen */ uint16_t cport; /* cluster port last time it was seen */ uint16_t flags; /* node->flags copy */ uint16_t pport; /* plaintext-port, when base port is TLS */ uint16_t notused1; - int has_human_readable_name; /* Indicates whether custom nodename is used */ } clusterMsgDataGossip; typedef struct { @@ -325,7 +320,6 @@ typedef struct { unsigned char myslots[CLUSTER_SLOTS/8]; char slaveof[CLUSTER_NAMELEN]; char myip[NET_IP_STR_LEN]; /* Sender IP, if not all zeroed. */ - char human_readable_name[CLUSTER_HUMAN_NAMELEN]; uint16_t extensions; /* Number of extensions sent along with this packet. */ char notused1[30]; /* 30 bytes reserved for future usage. */ uint16_t pport; /* Sender TCP plaintext port, if base port is TLS */ @@ -334,7 +328,6 @@ typedef struct { unsigned char state; /* Cluster state from the POV of the sender */ unsigned char mflags[3]; /* Message flags: CLUSTERMSG_FLAG[012]_... */ union clusterMsgData data; - int has_human_readable_name; /* Indicates whether custom nodename is used */ } clusterMsg; /* clusterMsg defines the gossip wire protocol exchanged among Redis cluster diff --git a/src/help.h b/src/help.h index 6ad21ebd2c1..edeb9b26e5f 100644 --- a/src/help.h +++ b/src/help.h @@ -364,11 +364,6 @@ struct commandHelp { "Return the node id", 12, "3.0.0" }, - { "CLUSTER MYID", - "", - "Return the node id", - 12, - "3.0.0" }, { "CLUSTER NODES", "", "Get Cluster config for the node", diff --git a/src/redis-cli.c b/src/redis-cli.c index b6b66a0612c..0c003a0dc6c 100644 --- a/src/redis-cli.c +++ b/src/redis-cli.c @@ -4585,10 +4585,8 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, lines = p + 1; char *name = NULL, *addr = NULL, *flags = NULL, *master_id = NULL, *ping_sent = NULL, *ping_recv = NULL, *config_epoch = NULL, - *link_status = NULL, *human_readable_name = NULL, *has_human_readable_name = NULL; + *link_status = NULL; UNUSED(link_status); - UNUSED(human_readable_name); - UNUSED(has_human_readable_name); int i = 0; while ((p = strchr(line, ' ')) != NULL) { *p = '\0'; @@ -4596,17 +4594,15 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, line = p + 1; switch(i++){ case 0: name = token; break; - case 1: human_readable_name = token; break; - case 2: addr = token; break; - case 3: flags = token; break; - case 4: master_id = token; break; - case 5: has_human_readable_name = token; break; - case 6: ping_sent = token; break; - case 7: ping_recv = token; break; - case 8: config_epoch = token; break; - case 9: link_status = token; break; - } - if (i == 10) break; // Slots + case 1: addr = token; break; + case 2: flags = token; break; + case 3: master_id = token; break; + case 4: ping_sent = token; break; + case 5: ping_recv = token; break; + case 6: config_epoch = token; break; + case 7: link_status = token; break; + } + if (i == 8) break; // Slots } if (!flags) { success = 0; @@ -4618,7 +4614,7 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, node->flags |= CLUSTER_MANAGER_FLAG_MYSELF; currentNode = node; clusterManagerNodeResetSlots(node); - if (i == 10) { + if (i == 8) { int remaining = strlen(line); while (remaining > 0) { p = strchr(line, ' '); diff --git a/tests/cluster/cluster.tcl b/tests/cluster/cluster.tcl index 7f6b7e71ab6..9c669e12854 100644 --- a/tests/cluster/cluster.tcl +++ b/tests/cluster/cluster.tcl @@ -18,16 +18,14 @@ proc get_cluster_nodes id { set args [split $l] set node [dict create \ id [lindex $args 0] \ - name [lindex $args 1] \ - addr [lindex $args 2] \ - flags [split [lindex $args 3] ,] \ - slaveof [lindex $args 4] \ - customName [lindex $args 5] \ - ping_sent [lindex $args 6] \ - pong_recv [lindex $args 7] \ - config_epoch [lindex $args 8] \ - linkstate [lindex $args 9] \ - slots [lrange $args 10 end] \ + addr [lindex $args 1] \ + flags [split [lindex $args 2] ,] \ + slaveof [lindex $args 3] \ + ping_sent [lindex $args 4] \ + pong_recv [lindex $args 5] \ + config_epoch [lindex $args 6] \ + linkstate [lindex $args 7] \ + slots [lrange $args 8 end] \ ] lappend nodes $node } diff --git a/tests/support/cluster.tcl b/tests/support/cluster.tcl index 2ead91f43d1..081ef6a9522 100644 --- a/tests/support/cluster.tcl +++ b/tests/support/cluster.tcl @@ -104,8 +104,8 @@ proc ::redis_cluster::__method__refresh_nodes_map {id} { set line [string trim $line] if {$line eq {}} continue set args [split $line " "] - lassign $args nodeid name addr flags slaveof customname pingsent pongrecv configepoch linkstate - set slots [lrange $args 10 end] + lassign $args nodeid addr flags slaveof pingsent pongrecv configepoch linkstate + set slots [lrange $args 8 end] set addr [lindex [split $addr @] 0] if {$addr eq {:0}} { set addr $start_host:$start_port @@ -126,7 +126,6 @@ proc ::redis_cluster::__method__refresh_nodes_map {id} { port $port \ flags $flags \ slaveof $slaveof \ - customname $customname \ slots $slots \ link $link \ ] From 5bd7e3e1ca83a65527dc8d4884a108e067aecffd Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Wed, 19 Jan 2022 14:52:26 -0500 Subject: [PATCH 57/79] Added nodename support to extension (#61) * Added nodename extension --- src/cluster.c | 151 +++++++++++++++++++++++++++++++++++++++++--------- src/cluster.h | 7 +++ src/config.c | 8 +++ src/server.h | 4 +- 4 files changed, 144 insertions(+), 26 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index b03a8dc305c..18be2a76a9e 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -217,7 +217,7 @@ int clusterLoadConfig(char *filename) { clusterAddNode(n); } /* Format for the node address information: - * ip:port[@cport][,hostname] */ + * ip:port[@cport][,hostname][-nodename] */ /* Hostname is an optional argument that defines the endpoint * that can be reported to clients instead of IP. */ @@ -249,6 +249,28 @@ int clusterLoadConfig(char *filename) { * base port. */ n->cport = busp ? atoi(busp) : n->port + CLUSTER_PORT_INCR; + /* Hostname is an optional argument that defines the endpoint + * that can be reported to clients instead of IP. */ + char *hostname = strchr(p, ','); + if (hostname) { + *hostname = '\0'; + hostname++; + zfree(n->hostname); + n->hostname = zstrdup(hostname); + } else { + n->hostname = NULL; + } + /* Nodename is an optional argument */ + char *nodename = strchr(p, '-'); + if (nodename) { + *nodename = '\0'; + nodename++; + zfree(n->nodename); + n->nodename = zstrdup(nodename); + } else { + n->nodename = NULL; + } + /* The plaintext port for client in a TLS cluster (n->pport) is not * stored in nodes.conf. It is received later over the bus protocol. */ @@ -582,12 +604,36 @@ static void updateAnnouncedHostname(clusterNode *node, char *new) { } } +/* Update the nodename for the specified node with the provided C string. */ +static void updateAnnouncedNodename(clusterNode *node, char *new) { + if (!node->nodename && !new) { + return; + } + + /* Previous and new nodename are the same, no need to update. */ + if (new && node->nodename && !strcmp(new, node->nodename)) { + return; + } + + if (node->nodename) zfree(node->nodename); + if (new) { + node->nodename = zstrdup(new); + } else { + node->nodename = NULL; + } +} + /* Update my hostname based on server configuration values */ void clusterUpdateMyselfHostname(void) { if (!myself) return; updateAnnouncedHostname(myself, server.cluster_announce_hostname); } +void clusterUpdateMyselfNodename(void) { + if (!myself) return; + updateAnnouncedNodename(myself, server.cluster_announce_nodename); +} + void clusterInit(void) { int saveconf = 0; @@ -682,6 +728,7 @@ void clusterInit(void) { clusterUpdateMyselfFlags(); clusterUpdateMyselfIp(); clusterUpdateMyselfHostname(); + clusterUpdateMyselfNodename(); } /* Reset a node performing a soft or hard reset: @@ -1348,7 +1395,7 @@ void clusterHandleConfigEpochCollision(clusterNode *sender) { serverLog(LL_VERBOSE, "WARNING: configEpoch collision with node %.40s." " configEpoch set to %llu", - sender->name, + sender->name, (unsigned long long) myself->configEpoch); } @@ -1492,8 +1539,8 @@ void clearNodeFailureIfNeeded(clusterNode *node) { * node again. */ if (nodeIsSlave(node) || node->numslots == 0) { serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s : %s is reachable again.", - node->name, + "Clear FAIL state for node %.40s: %s is reachable again.", + node->name, nodeIsSlave(node) ? "replica" : "master without slots"); node->flags &= ~CLUSTER_NODE_FAIL; clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); @@ -1508,7 +1555,7 @@ void clearNodeFailureIfNeeded(clusterNode *node) { (server.cluster_node_timeout * CLUSTER_FAIL_UNDO_TIME_MULT)) { serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s : is reachable again and nobody is serving its slots after some time.", + "Clear FAIL state for node %.40s: is reachable again and nobody is serving its slots after some time.", node->name); node->flags &= ~CLUSTER_NODE_FAIL; clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); @@ -1630,7 +1677,7 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { if (clusterNodeAddFailureReport(node,sender)) { serverLog(LL_VERBOSE, "Node %.40s reported node %.40s as not reachable.", - sender->name, node->name); + sender->name, node->name); } markNodeAsFailingIfNeeded(node); } else { @@ -1893,7 +1940,7 @@ void clusterUpdateSlotsConfigWith(clusterNode *sender, uint64_t senderConfigEpoc sender_slots == migrated_our_slots)) { serverLog(LL_WARNING, "Configuration change detected. Reconfiguring myself " - "as a replica of %.40s ", sender->name); + "as a replica of %.40s", sender->name); clusterSetMaster(sender); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| CLUSTER_TODO_UPDATE_STATE| @@ -1950,6 +1997,16 @@ int getHostnamePingExtSize() { return totlen; } +/* Returns the exact size needed to store the nodename. The returned value + * will be 8 byte padded. */ +int getNodenamePingExtSize() { + /* If nodename is not set, we don't send this extension */ + if (!myself->nodename) return 0; + + int totlen = sizeof(clusterMsgPingExt) + EIGHT_BYTE_ALIGN(strlen(myself->nodename) + 1); + return totlen; +} + /* Write the hostname ping extension at the start of the cursor. This function * will update the cursor to point to the end of the written extension and * will return the amount of bytes written. */ @@ -1970,19 +2027,44 @@ int writeHostnamePingExt(clusterMsgPingExt **cursor) { return extension_size; } +/* Write the nodename ping extension at the start of the cursor. This function + * will update the cursor to point to the end of the written extension and + * will return the amount of bytes written. */ +int writeNodenamePingExt(clusterMsgPingExt **cursor) { + /* If nodename is not set, we don't send this extension */ + if (!myself->nodename) return 0; + + /* Add the nodename information at the extension cursor */ + clusterMsgPingExtNodename *ext = &(*cursor)->ext[1].nodename; + size_t nodename_len = strlen(myself->nodename); + memcpy(ext->nodename, myself->nodename, nodename_len); + uint32_t extension_size = getNodenamePingExtSize(); + + /* Move the write cursor */ + (*cursor)->type = CLUSTERMSG_EXT_TYPE_NODENAME; + (*cursor)->length = htonl(extension_size); + /* Make sure the string is NULL terminated by adding 1 */ + *cursor = (clusterMsgPingExt *) (ext->nodename + EIGHT_BYTE_ALIGN(strlen(myself->nodename) + 1)); + return extension_size; +} + /* We previously validated the extensions, so this function just needs to * handle the extensions. */ void clusterProcessPingExtensions(clusterMsg *hdr, clusterLink *link) { clusterNode *sender = link->node ? link->node : clusterLookupNode(hdr->sender); char *ext_hostname = NULL; + char *ext_nodename = NULL; uint16_t extensions = ntohs(hdr->extensions); /* Loop through all the extensions and process them */ clusterMsgPingExt *ext = getInitialPingExt(hdr, ntohs(hdr->count)); while (extensions--) { - uint16_t type = ntohs(ext->type); + uint16_t type = ext->type; if (type == CLUSTERMSG_EXT_TYPE_HOSTNAME) { clusterMsgPingExtHostname *hostname_ext = (clusterMsgPingExtHostname *) &(ext->ext[0].hostname); ext_hostname = hostname_ext->hostname; + } else if (type == CLUSTERMSG_EXT_TYPE_NODENAME) { + clusterMsgPingExtNodename *nodename_ext = (clusterMsgPingExtNodename *) &(ext->ext[1].nodename); + ext_nodename = nodename_ext->nodename; } else { /* Unknown type, we will ignore it but log what happened. */ serverLog(LL_WARNING, "Received unknown extension type %d", type); @@ -1995,6 +2077,7 @@ void clusterProcessPingExtensions(clusterMsg *hdr, clusterLink *link) { * they don't have an announced hostname. Otherwise, we'll * set it now. */ updateAnnouncedHostname(sender, ext_hostname); + updateAnnouncedNodename(sender, ext_nodename); } static clusterNode *getNodeFromLinkAndMsg(clusterLink *link, clusterMsg *hdr) { @@ -2225,7 +2308,7 @@ int clusterProcessPacket(clusterLink *link) { * IP/port of the node with the new one. */ if (sender) { serverLog(LL_VERBOSE, - "Handshake: we already know node %.40s , " + "Handshake: we already know node %.40s, " "updating the address if needed.", sender->name); if (nodeUpdateAddressIfNeeded(sender,link,hdr)) @@ -2254,7 +2337,7 @@ int clusterProcessPacket(clusterLink *link) { * disconnect this node and set it as not having an associated * address. */ serverLog(LL_DEBUG,"PONG contains mismatching sender ID. About node %.40s added %d ms ago, having flags %d", - link->node->name, + link->node->name, (int)(now-(link->node->ctime)), link->node->flags); link->node->flags |= CLUSTER_NODE_NOADDR; @@ -2402,8 +2485,7 @@ int clusterProcessPacket(clusterLink *link) { serverLog(LL_VERBOSE, "Node %.40s has old slots configuration, sending " "an UPDATE message about %.40s ", - sender->name, - server.cluster->slots[j]->name); + sender->name, server.cluster->slots[j]->name); clusterSendUpdate(sender->link, server.cluster->slots[j]); @@ -2898,7 +2980,7 @@ void clusterSendPing(clusterLink *link, int type) { * to put inside the packet. */ estlen = sizeof(clusterMsg) - sizeof(union clusterMsgData); estlen += (sizeof(clusterMsgDataGossip)*(wanted + pfail_wanted)); - estlen += sizeof(clusterMsgPingExt) + getHostnamePingExtSize(); + estlen += sizeof(clusterMsgPingExt) + getHostnamePingExtSize() + getNodenamePingExtSize(); /* Note: clusterBuildMessageHdr() expects the buffer to be always at least * sizeof(clusterMsg) or more. */ @@ -2979,6 +3061,12 @@ void clusterSendPing(clusterLink *link, int type) { extensions++; } + if (myself->nodename) { + hdr->mflags[0] |= CLUSTERMSG_FLAG0_EXT_DATA; + totlen += writeNodenamePingExt(&cursor); + extensions++; + } + /* Compute the actual total length and send! */ totlen += sizeof(clusterMsg)-sizeof(union clusterMsgData); totlen += (sizeof(clusterMsgDataGossip)*gossipcount); @@ -3266,8 +3354,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * request, if the request epoch was greater. */ if (requestCurrentEpoch < server.cluster->currentEpoch) { serverLog(LL_WARNING, - "Failover auth denied to %.40s : reqEpoch (%llu) < curEpoch(%llu)", - node->name, + "Failover auth denied to %.40s: reqEpoch (%llu) < curEpoch(%llu)", + node->name, (unsigned long long) requestCurrentEpoch, (unsigned long long) server.cluster->currentEpoch); return; @@ -3276,8 +3364,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { /* I already voted for this epoch? Return ASAP. */ if (server.cluster->lastVoteEpoch == server.cluster->currentEpoch) { serverLog(LL_WARNING, - "Failover auth denied to %.40s : already voted for epoch %llu", - node->name, + "Failover auth denied to %.40s: already voted for epoch %llu", + node->name, (unsigned long long) server.cluster->currentEpoch); return; } @@ -3290,15 +3378,15 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { { if (nodeIsMaster(node)) { serverLog(LL_WARNING, - "Failover auth denied to %.40s : it is a master node", + "Failover auth denied to %.40s: it is a master node", node->name); } else if (master == NULL) { serverLog(LL_WARNING, - "Failover auth denied to %.40s : I don't know its master", + "Failover auth denied to %.40s: I don't know its master", node->name); } else if (!nodeFailed(master)) { serverLog(LL_WARNING, - "Failover auth denied to %.40s : its master is up", + "Failover auth denied to %.40s: its master is up", node->name); } return; @@ -3310,7 +3398,7 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { if (mstime() - node->slaveof->voted_time < server.cluster_node_timeout * 2) { serverLog(LL_WARNING, - "Failover auth denied to %.40s : " + "Failover auth denied to %.40s: " "can't vote about this master before %lld milliseconds", node->name, (long long) ((server.cluster_node_timeout*2)- @@ -3332,7 +3420,7 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * is served by a master with a greater configEpoch than the one claimed * by the slave requesting our vote. Refuse to vote for this slave. */ serverLog(LL_WARNING, - "Failover auth denied to %.40s : " + "Failover auth denied to %.40s: " "slot %d epoch (%llu) > reqEpoch (%llu)", node->name, j, (unsigned long long) server.cluster->slots[j]->configEpoch, @@ -3763,7 +3851,7 @@ void clusterHandleSlaveMigration(int max_slaves) { (mstime()-target->orphaned_time) > CLUSTER_SLAVE_MIGRATION_DELAY && !(server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_FAILOVER)) { - serverLog(LL_WARNING,"Migrating to orphaned master %.40s ", + serverLog(LL_WARNING,"Migrating to orphaned master %.40s", target->name); clusterSetMaster(target); } @@ -4011,7 +4099,7 @@ void clusterCron(void) { } } if (min_pong_node) { - serverLog(LL_DEBUG,"Pinging node %.40s ", min_pong_node->name); + serverLog(LL_DEBUG,"Pinging node %.40s", min_pong_node->name); clusterSendPing(min_pong_node->link, CLUSTERMSG_TYPE_PING); } } @@ -4605,6 +4693,12 @@ sds clusterGenNodeDescription(clusterNode *node, int use_pport) { port, node->cport, node->hostname); + } else if (node->nodename) { + ci = sdscatfmt(ci," %s:%i@%i-%s ", + node->ip, + port, + node->cport, + node->nodename); } else { ci = sdscatfmt(ci," %s:%i@%i ", node->ip, @@ -4620,7 +4714,7 @@ sds clusterGenNodeDescription(clusterNode *node, int use_pport) { if (node->slaveof) ci = sdscatlen(ci,node->slaveof->name,CLUSTER_NAMELEN); else - ci = sdscatlen(ci,"-",1); + ci = sdscatlen(ci,"-",1); unsigned long long nodeEpoch = node->configEpoch; if (nodeIsSlave(node) && node->slaveof) { @@ -4947,6 +5041,13 @@ void addNodeToNodeReply(client *c, clusterNode *node) { addReplyBulkCString(c, node->hostname); length++; } + if (server.cluster_preferred_endpoint_type != CLUSTER_ENDPOINT_TYPE_NODENAME + && node->nodename) + { + addReplyBulkCString(c, "nodename"); + addReplyBulkCString(c, node->nodename); + length++; + } setDeferredMapLen(c, deflen, length); } diff --git a/src/cluster.h b/src/cluster.h index a944056eb96..475b4bf5ca8 100644 --- a/src/cluster.h +++ b/src/cluster.h @@ -251,6 +251,7 @@ typedef struct { * consistent manner. */ typedef enum { CLUSTERMSG_EXT_TYPE_HOSTNAME, + CLUSTERMSG_EXT_TYPE_NODENAME, } clusterMsgPingtypes; /* Helper function for making sure extensions are eight byte aligned. */ @@ -260,12 +261,17 @@ typedef struct { char hostname[1]; /* The announced hostname, ends with \0. */ } clusterMsgPingExtHostname; +typedef struct { + char nodename[1]; /* The announced nodename, ends with \0. */ +} clusterMsgPingExtNodename; + typedef struct { uint32_t length; /* Total length of this extension message (including this header) */ uint16_t type; /* Type of this extension message (see clusterMsgPingExtTypes) */ uint16_t unused; /* 16 bits of padding to make this structure 8 byte aligned. */ union { clusterMsgPingExtHostname hostname; + clusterMsgPingExtNodename nodename; } ext[]; /* Actual extension information, formatted so that the data is 8 * byte aligned, regardless of its content. */ } clusterMsgPingExt; @@ -396,5 +402,6 @@ void clusterUpdateMyselfIp(void); void slotToChannelAdd(sds channel); void slotToChannelDel(sds channel); void clusterUpdateMyselfHostname(void); +void clusterUpdateMyselfNodename(void); #endif /* __CLUSTER_H */ diff --git a/src/config.c b/src/config.c index e36315743af..1863bf13139 100644 --- a/src/config.c +++ b/src/config.c @@ -144,6 +144,7 @@ configEnum protected_action_enum[] = { configEnum cluster_preferred_endpoint_type_enum[] = { {"ip", CLUSTER_ENDPOINT_TYPE_IP}, {"hostname", CLUSTER_ENDPOINT_TYPE_HOSTNAME}, + {"nodename", CLUSTER_ENDPOINT_TYPE_NODENAME}, {"unknown-endpoint", CLUSTER_ENDPOINT_TYPE_UNKNOWN_ENDPOINT}, {NULL, 0} }; @@ -2409,6 +2410,12 @@ int updateClusterHostname(const char **err) { return 1; } +int updateClusterNodename(const char **err) { + UNUSED(err); + clusterUpdateMyselfNodename(); + return 1; +} + #ifdef USE_OPENSSL static int applyTlsCfg(const char **err) { UNUSED(err); @@ -2828,6 +2835,7 @@ standardConfig static_configs[] = { createStringConfig("cluster-announce-ip", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.cluster_announce_ip, NULL, NULL, updateClusterIp), createStringConfig("cluster-config-file", NULL, IMMUTABLE_CONFIG, ALLOW_EMPTY_STRING, server.cluster_configfile, "nodes.conf", NULL, NULL), createStringConfig("cluster-announce-hostname", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.cluster_announce_hostname, NULL, isValidAnnouncedHostname, updateClusterHostname), + createStringConfig("cluster-announce-nodename", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.cluster_announce_nodename, NULL, isValidAnnouncedHostname, updateClusterNodename), createStringConfig("syslog-ident", NULL, IMMUTABLE_CONFIG, ALLOW_EMPTY_STRING, server.syslog_ident, "redis", NULL, NULL), createStringConfig("dbfilename", NULL, MODIFIABLE_CONFIG | PROTECTED_CONFIG, ALLOW_EMPTY_STRING, server.rdb_filename, "dump.rdb", isValidDBfilename, NULL), createStringConfig("appendfilename", NULL, IMMUTABLE_CONFIG, ALLOW_EMPTY_STRING, server.aof_filename, "appendonly.aof", isValidAOFfilename, NULL), diff --git a/src/server.h b/src/server.h index 5f5417de169..031a2e65df1 100644 --- a/src/server.h +++ b/src/server.h @@ -581,6 +581,7 @@ typedef struct { typedef enum { CLUSTER_ENDPOINT_TYPE_IP = 0, /* Show IP address */ CLUSTER_ENDPOINT_TYPE_HOSTNAME, /* Show hostname */ + CLUSTER_ENDPOINT_TYPE_NODENAME, /* Show nodename */ CLUSTER_ENDPOINT_TYPE_UNKNOWN_ENDPOINT /* Show NULL or empty */ } cluster_endpoint_type; @@ -1848,7 +1849,8 @@ struct redisServer { int cluster_slave_no_failover; /* Prevent slave from starting a failover if the master is in failure state. */ char *cluster_announce_ip; /* IP address to announce on cluster bus. */ - char *cluster_announce_hostname; /* hostname to announce on cluster bus. */ + char *cluster_announce_hostname; /* IP address to announce on cluster bus. */ + char *cluster_announce_nodename; /* Human readable name assigned to a node. */ int cluster_preferred_endpoint_type; /* Use the announced hostname when available. */ int cluster_announce_port; /* base port to announce on cluster bus. */ int cluster_announce_tls_port; /* TLS port to announce on cluster bus. */ From b46cacd9773a9e5a1cd56b3a5f5276c0b44fee17 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Thu, 24 Feb 2022 09:55:14 -0500 Subject: [PATCH 58/79] Update src/cluster.c Co-authored-by: Madelyn Olson <34459052+madolson@users.noreply.github.com> --- src/cluster.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cluster.c b/src/cluster.c index 18be2a76a9e..cd85f2db64f 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -2063,7 +2063,7 @@ void clusterProcessPingExtensions(clusterMsg *hdr, clusterLink *link) { clusterMsgPingExtHostname *hostname_ext = (clusterMsgPingExtHostname *) &(ext->ext[0].hostname); ext_hostname = hostname_ext->hostname; } else if (type == CLUSTERMSG_EXT_TYPE_NODENAME) { - clusterMsgPingExtNodename *nodename_ext = (clusterMsgPingExtNodename *) &(ext->ext[1].nodename); + clusterMsgPingExtNodename *nodename_ext = (clusterMsgPingExtNodename *) &(ext->ext[0].nodename); ext_nodename = nodename_ext->nodename; } else { /* Unknown type, we will ignore it but log what happened. */ From e69266d9ba1afd51bb616b13125606f1497e1f62 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Thu, 24 Feb 2022 09:59:15 -0500 Subject: [PATCH 59/79] Update cluster.c Fix indentation --- src/cluster.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cluster.c b/src/cluster.c index cd85f2db64f..dc149a674e5 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -3662,7 +3662,7 @@ void clusterHandleSlaveFailover(void) { if (server.cluster->mf_end) { server.cluster->failover_auth_time = mstime(); server.cluster->failover_auth_rank = 0; - clusterDoBeforeSleep(CLUSTER_TODO_HANDLE_FAILOVER); + clusterDoBeforeSleep(CLUSTER_TODO_HANDLE_FAILOVER); } serverLog(LL_WARNING, "Start of election delayed for %lld milliseconds " From f8b1acf6f24d4e377b5d09f60e41f0125e3b01c9 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Mon, 27 Sep 2021 17:00:23 -0400 Subject: [PATCH 60/79] Add hostname variable --- src/cluster.c | 16 ++++++++++++++++ src/cluster.h | 1 + 2 files changed, 17 insertions(+) diff --git a/src/cluster.c b/src/cluster.c index dc149a674e5..0b333d913d9 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -972,6 +972,22 @@ unsigned int keyHashSlot(char *key, int keylen) { * CLUSTER node API * -------------------------------------------------------------------------- */ +/* Assign a human readable name to nodes for clusters*/ +void setClusterNodeName(clusterNode *node){ + char *name; + int post_digits; + if (node->port == 0){ + post_digits = 0; + } + else{ + floor(log10(abs(node->port))) + 1; + } + int allocate_len = sizeof(node->ip) + post_digits + 2; + name = zmalloc(allocate_len); + sprintf(name, "%s%s%d", node->ip, "_", node->port); + node->hname = name; +} + /* Create a new cluster node, with the specified flags. * If "nodename" is NULL this is considered a first handshake and a random * node name is assigned to this node (it will be fixed later when we'll diff --git a/src/cluster.h b/src/cluster.h index 475b4bf5ca8..2e6b6d97062 100644 --- a/src/cluster.h +++ b/src/cluster.h @@ -115,6 +115,7 @@ typedef struct clusterNodeFailReport { typedef struct clusterNode { mstime_t ctime; /* Node object creation time. */ char name[CLUSTER_NAMELEN]; /* Node name, hex string, sha1-size */ + char* hname; /* Human readable name for node */ int flags; /* CLUSTER_NODE_... */ uint64_t configEpoch; /* Last configEpoch observed for this node */ unsigned char slots[CLUSTER_SLOTS/8]; /* slots handled by this node */ From 691483945f1d36c7dc96e4f788b922f998c4a9d5 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Mon, 27 Sep 2021 17:02:18 -0400 Subject: [PATCH 61/79] Update cluster.c --- src/cluster.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cluster.c b/src/cluster.c index 0b333d913d9..9bb460943a9 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -980,7 +980,7 @@ void setClusterNodeName(clusterNode *node){ post_digits = 0; } else{ - floor(log10(abs(node->port))) + 1; + post_digits = floor(log10(abs(node->port))) + 1; } int allocate_len = sizeof(node->ip) + post_digits + 2; name = zmalloc(allocate_len); @@ -1654,6 +1654,7 @@ int clusterStartHandshake(char *ip, int port, int cport) { memcpy(n->ip,norm_ip,sizeof(n->ip)); n->port = port; n->cport = cport; + setClusterNodeName(n); clusterAddNode(n); return 1; } From 21a21c1c430b7a0e64db6640c0877b757ca1cb41 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Mon, 27 Sep 2021 17:04:26 -0400 Subject: [PATCH 62/79] Update cluster.c --- src/cluster.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cluster.c b/src/cluster.c index 9bb460943a9..31470a62269 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -48,6 +48,7 @@ clusterNode *myself = NULL; clusterNode *createClusterNode(char *nodename, int flags); void clusterAddNode(clusterNode *node); +void setClusterNodeName(clusterNode *node); void clusterAcceptHandler(aeEventLoop *el, int fd, void *privdata, int mask); void clusterReadHandler(connection *conn); void clusterSendPing(clusterLink *link, int type); @@ -1746,6 +1747,7 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { node->pport = ntohs(g->pport); node->cport = ntohs(g->cport); node->flags &= ~CLUSTER_NODE_NOADDR; + setClusterNodeName(node); } } else { /* If it's not in NOADDR state and we don't have it, we @@ -1767,6 +1769,7 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { node->port = ntohs(g->port); node->pport = ntohs(g->pport); node->cport = ntohs(g->cport); + setClusterNodeName(node); clusterAddNode(node); } } @@ -1825,6 +1828,7 @@ int nodeUpdateAddressIfNeeded(clusterNode *node, clusterLink *link, node->port = port; node->pport = pport; node->cport = cport; + setClusterNodeName(node); if (node->link) freeClusterLink(node->link); node->flags &= ~CLUSTER_NODE_NOADDR; serverLog(LL_WARNING,"Address updated for node %.40s , now %s:%d", From 4d2f3bcc9fc1a1b8a06e413a06969261d82a9dbe Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Mon, 27 Sep 2021 17:05:32 -0400 Subject: [PATCH 63/79] Update cluster.c --- src/cluster.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cluster.c b/src/cluster.c index 31470a62269..0aa925089aa 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -2284,6 +2284,7 @@ int clusterProcessPacket(clusterLink *link) { strcmp(ip,myself->ip)) { memcpy(myself->ip,ip,NET_IP_STR_LEN); + setClusterNodeName(myself); serverLog(LL_WARNING,"IP address for this node updated to %s", myself->ip); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG); @@ -2302,6 +2303,7 @@ int clusterProcessPacket(clusterLink *link) { node->port = ntohs(hdr->port); node->pport = ntohs(hdr->pport); node->cport = ntohs(hdr->cport); + setClusterNodeName(node); clusterAddNode(node); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG); } From 23c8f0357df532052aab4421f3de3e526ec580c4 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 10:32:32 -0400 Subject: [PATCH 64/79] Update cluster.c --- src/cluster.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cluster.c b/src/cluster.c index 0aa925089aa..7bfaa651ead 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -4856,6 +4856,10 @@ sds clusterGenNodesDescription(int filter, int use_pport) { if (node->flags & filter) continue; ni = clusterGenNodeDescription(node, use_pport); + + if (node->hname) + ni = sdscatfmt(ni," %s ",node->hname); + ci = sdscatsds(ci,ni); sdsfree(ni); ci = sdscatlen(ci,"\n",1); From 34879c3b5d7cdbb22b7b5c03c82006d27d8acebe Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 10:33:55 -0400 Subject: [PATCH 65/79] Update cluster.c --- src/cluster.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index 7bfaa651ead..0aa925089aa 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -4856,10 +4856,6 @@ sds clusterGenNodesDescription(int filter, int use_pport) { if (node->flags & filter) continue; ni = clusterGenNodeDescription(node, use_pport); - - if (node->hname) - ni = sdscatfmt(ni," %s ",node->hname); - ci = sdscatsds(ci,ni); sdsfree(ni); ci = sdscatlen(ci,"\n",1); From 620c7c4367042f0198c58fa519297e453f7357ce Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 14:32:35 -0400 Subject: [PATCH 66/79] Check node name --- src/cluster.c | 3 +++ src/help.h | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/src/cluster.c b/src/cluster.c index 0aa925089aa..43bb408631f 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -5375,6 +5375,9 @@ NULL } else if (!strcasecmp(c->argv[1]->ptr,"myid") && c->argc == 2) { /* CLUSTER MYID */ addReplyBulkCBuffer(c,myself->name, CLUSTER_NAMELEN); + } else if (!strcasecmp(c->argv[1]->ptr,"myname") && c->argc == 2) { + /* CLUSTER MYID */ + addReplyBulkCBuffer(c,myself->hname, sizeof(myself->hname)); } else if (!strcasecmp(c->argv[1]->ptr,"slots") && c->argc == 2) { /* CLUSTER SLOTS */ clusterReplyMultiBulkSlots(c); diff --git a/src/help.h b/src/help.h index edeb9b26e5f..0c36e12446c 100644 --- a/src/help.h +++ b/src/help.h @@ -364,6 +364,11 @@ struct commandHelp { "Return the node id", 12, "3.0.0" }, + { "CLUSTER MYNAME", + "", + "Return the node name", + 12, + "3.0.0" }, { "CLUSTER NODES", "", "Get Cluster config for the node", From 579a90ad1bfa6139e174bbac386a36bd95557497 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 14:35:38 -0400 Subject: [PATCH 67/79] Update cluster.c --- src/cluster.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cluster.c b/src/cluster.c index 43bb408631f..9ec21c1f9a7 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -5377,7 +5377,10 @@ NULL addReplyBulkCBuffer(c,myself->name, CLUSTER_NAMELEN); } else if (!strcasecmp(c->argv[1]->ptr,"myname") && c->argc == 2) { /* CLUSTER MYID */ - addReplyBulkCBuffer(c,myself->hname, sizeof(myself->hname)); + if (myself->hname) + addReplyBulkCBuffer(c,myself->hname, sizeof(myself->hname)); + else + addReplyError(c,"Node is not assigned name yet."); } else if (!strcasecmp(c->argv[1]->ptr,"slots") && c->argc == 2) { /* CLUSTER SLOTS */ clusterReplyMultiBulkSlots(c); From 9206bbb6e05eaa36a78b5b4719a110415746191f Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 14:37:02 -0400 Subject: [PATCH 68/79] Update cluster.c --- src/cluster.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cluster.c b/src/cluster.c index 9ec21c1f9a7..8a9ac9eb937 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -5378,7 +5378,7 @@ NULL } else if (!strcasecmp(c->argv[1]->ptr,"myname") && c->argc == 2) { /* CLUSTER MYID */ if (myself->hname) - addReplyBulkCBuffer(c,myself->hname, sizeof(myself->hname)); + addReplyBulkCBuffer(c,myself->hname, strlen(myself->hname)); else addReplyError(c,"Node is not assigned name yet."); } else if (!strcasecmp(c->argv[1]->ptr,"slots") && c->argc == 2) { From 1284aebde6618a3518060f5091a3976cc5a54d8b Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 14:39:39 -0400 Subject: [PATCH 69/79] Add help for nodename --- src/cluster.c | 2 ++ src/help.h | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index 8a9ac9eb937..139e764fc9d 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -5309,6 +5309,8 @@ void clusterCommand(client *c) { " Connect nodes into a working cluster.", "MYID", " Return the node id.", +"MYNAME", +" Return the node name.", "NODES", " Return cluster configuration seen by node. Output format:", " ...", diff --git a/src/help.h b/src/help.h index 0c36e12446c..6ad21ebd2c1 100644 --- a/src/help.h +++ b/src/help.h @@ -364,9 +364,9 @@ struct commandHelp { "Return the node id", 12, "3.0.0" }, - { "CLUSTER MYNAME", + { "CLUSTER MYID", "", - "Return the node name", + "Return the node id", 12, "3.0.0" }, { "CLUSTER NODES", From 34b7ced282b34ebc14eaf11536ba4acdbe10551e Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 28 Sep 2021 15:59:46 -0400 Subject: [PATCH 70/79] Update cluster.c --- src/cluster.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cluster.c b/src/cluster.c index 139e764fc9d..e1d0795dfde 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -974,7 +974,7 @@ unsigned int keyHashSlot(char *key, int keylen) { * -------------------------------------------------------------------------- */ /* Assign a human readable name to nodes for clusters*/ -void setClusterNodeName(clusterNode *node){ +void setClusterNodeName(clusterNode *node) { char *name; int post_digits; if (node->port == 0){ From 9d9b96d2af6fd7ef137727d0481da3d33703e384 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Tue, 5 Oct 2021 11:21:58 -0400 Subject: [PATCH 71/79] Added support for hname in CLUSTER NODES --- src/cluster.c | 20 ++++++++++---------- src/redis-cli.c | 22 ++++++++++++---------- tests/cluster/cluster.tcl | 17 +++++++++-------- tests/support/cluster.tcl | 4 ++-- 4 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index e1d0795dfde..cfa181ec355 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -232,12 +232,12 @@ int clusterLoadConfig(char *filename) { } /* Address and port */ - if ((p = strrchr(argv[1],':')) == NULL) { + if ((p = strrchr(argv[offset + 1],':')) == NULL) { sdsfreesplitres(argv,argc); goto fmterr; } *p = '\0'; - memcpy(n->ip,argv[1],strlen(argv[1])+1); + memcpy(n->ip,argv[offset + 1],strlen(argv[offset + 1])+1); char *port = p+1; char *busp = strchr(port,'@'); if (busp) { @@ -276,7 +276,7 @@ int clusterLoadConfig(char *filename) { * stored in nodes.conf. It is received later over the bus protocol. */ /* Parse flags */ - p = s = argv[2]; + p = s = argv[offset + 2]; while(p) { p = strchr(s,','); if (p) *p = '\0'; @@ -309,10 +309,10 @@ int clusterLoadConfig(char *filename) { /* Get master if any. Set the master and populate master's * slave list. */ - if (argv[3][0] != '-') { - master = clusterLookupNode(argv[3]); + if (argv[offset + 3][0] != '-') { + master = clusterLookupNode(argv[offset + 3]); if (!master) { - master = createClusterNode(argv[3],0); + master = createClusterNode(argv[offset + 3],0); clusterAddNode(master); } n->slaveof = master; @@ -320,14 +320,14 @@ int clusterLoadConfig(char *filename) { } /* Set ping sent / pong received timestamps */ - if (atoi(argv[4])) n->ping_sent = mstime(); - if (atoi(argv[5])) n->pong_received = mstime(); + if (atoi(argv[offset + 4])) n->ping_sent = mstime(); + if (atoi(argv[offset + 5])) n->pong_received = mstime(); /* Set configEpoch for this node. */ - n->configEpoch = strtoull(argv[6],NULL,10); + n->configEpoch = strtoull(argv[offset + 6],NULL,10); /* Populate hash slots served by this instance. */ - for (j = 8; j < argc; j++) { + for (j = offset + 8; j < argc; j++) { int start, stop; if (argv[j][0] == '[') { diff --git a/src/redis-cli.c b/src/redis-cli.c index 0c003a0dc6c..051ab94e9d9 100644 --- a/src/redis-cli.c +++ b/src/redis-cli.c @@ -4585,8 +4585,9 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, lines = p + 1; char *name = NULL, *addr = NULL, *flags = NULL, *master_id = NULL, *ping_sent = NULL, *ping_recv = NULL, *config_epoch = NULL, - *link_status = NULL; + *link_status = NULL, *hname = NULL; UNUSED(link_status); + UNUSED(hname); int i = 0; while ((p = strchr(line, ' ')) != NULL) { *p = '\0'; @@ -4594,15 +4595,16 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, line = p + 1; switch(i++){ case 0: name = token; break; - case 1: addr = token; break; - case 2: flags = token; break; - case 3: master_id = token; break; - case 4: ping_sent = token; break; - case 5: ping_recv = token; break; - case 6: config_epoch = token; break; - case 7: link_status = token; break; + case 1: hname = token; break; + case 2: addr = token; break; + case 3: flags = token; break; + case 4: master_id = token; break; + case 5: ping_sent = token; break; + case 6: ping_recv = token; break; + case 7: config_epoch = token; break; + case 8: link_status = token; break; } - if (i == 8) break; // Slots + if (i == 9) break; // Slots } if (!flags) { success = 0; @@ -4614,7 +4616,7 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, node->flags |= CLUSTER_MANAGER_FLAG_MYSELF; currentNode = node; clusterManagerNodeResetSlots(node); - if (i == 8) { + if (i == 9) { int remaining = strlen(line); while (remaining > 0) { p = strchr(line, ' '); diff --git a/tests/cluster/cluster.tcl b/tests/cluster/cluster.tcl index 9c669e12854..802b5b6f573 100644 --- a/tests/cluster/cluster.tcl +++ b/tests/cluster/cluster.tcl @@ -18,14 +18,15 @@ proc get_cluster_nodes id { set args [split $l] set node [dict create \ id [lindex $args 0] \ - addr [lindex $args 1] \ - flags [split [lindex $args 2] ,] \ - slaveof [lindex $args 3] \ - ping_sent [lindex $args 4] \ - pong_recv [lindex $args 5] \ - config_epoch [lindex $args 6] \ - linkstate [lindex $args 7] \ - slots [lrange $args 8 end] \ + name [lindex $args 1] \ + addr [lindex $args 2] \ + flags [split [lindex $args 3] ,] \ + slaveof [lindex $args 4] \ + ping_sent [lindex $args 5] \ + pong_recv [lindex $args 6] \ + config_epoch [lindex $args 7] \ + linkstate [lindex $args 8] \ + slots [lrange $args 9 end] \ ] lappend nodes $node } diff --git a/tests/support/cluster.tcl b/tests/support/cluster.tcl index 081ef6a9522..8c628dcd3f1 100644 --- a/tests/support/cluster.tcl +++ b/tests/support/cluster.tcl @@ -104,8 +104,8 @@ proc ::redis_cluster::__method__refresh_nodes_map {id} { set line [string trim $line] if {$line eq {}} continue set args [split $line " "] - lassign $args nodeid addr flags slaveof pingsent pongrecv configepoch linkstate - set slots [lrange $args 8 end] + lassign $args nodeid name addr flags slaveof pingsent pongrecv configepoch linkstate + set slots [lrange $args 9 end] set addr [lindex [split $addr @] 0] if {$addr eq {:0}} { set addr $start_host:$start_port From 9a67ded07ef7e2024b48d1b218903e070c49e39d Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Mon, 1 Nov 2021 16:23:43 -0400 Subject: [PATCH 72/79] Add gossip and custom name support --- src/cluster.c | 182 ++++++++++++++++++++++---------------- src/cluster.h | 8 +- src/redis-cli.c | 20 +++-- tests/cluster/cluster.tcl | 11 +-- tests/support/cluster.tcl | 5 +- 5 files changed, 134 insertions(+), 92 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index cfa181ec355..08a4753f7eb 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -232,12 +232,12 @@ int clusterLoadConfig(char *filename) { } /* Address and port */ - if ((p = strrchr(argv[offset + 1],':')) == NULL) { + if ((p = strrchr(argv[1],':')) == NULL) { sdsfreesplitres(argv,argc); goto fmterr; } *p = '\0'; - memcpy(n->ip,argv[offset + 1],strlen(argv[offset + 1])+1); + memcpy(n->ip,argv[1],strlen(argv[1])+1); char *port = p+1; char *busp = strchr(port,'@'); if (busp) { @@ -276,7 +276,7 @@ int clusterLoadConfig(char *filename) { * stored in nodes.conf. It is received later over the bus protocol. */ /* Parse flags */ - p = s = argv[offset + 2]; + p = s = argv[3]; while(p) { p = strchr(s,','); if (p) *p = '\0'; @@ -309,25 +309,28 @@ int clusterLoadConfig(char *filename) { /* Get master if any. Set the master and populate master's * slave list. */ - if (argv[offset + 3][0] != '-') { - master = clusterLookupNode(argv[offset + 3]); + if (argv[4][0] != '-') { + master = clusterLookupNode(argv[4]); if (!master) { - master = createClusterNode(argv[offset + 3],0); + master = createClusterNode(argv[4],0); clusterAddNode(master); } n->slaveof = master; clusterNodeAddSlave(master,n); } + /* Custom nodename */ + n->has_human_readable_name = atoi(argv[5]); + /* Set ping sent / pong received timestamps */ - if (atoi(argv[offset + 4])) n->ping_sent = mstime(); - if (atoi(argv[offset + 5])) n->pong_received = mstime(); + if (atoi(argv[6])) n->ping_sent = mstime(); + if (atoi(argv[7])) n->pong_received = mstime(); /* Set configEpoch for this node. */ - n->configEpoch = strtoull(argv[offset + 6],NULL,10); + n->configEpoch = strtoull(argv[8],NULL,10); /* Populate hash slots served by this instance. */ - for (j = offset + 8; j < argc; j++) { + for (j = 10; j < argc; j++) { int start, stop; if (argv[j][0] == '[') { @@ -381,7 +384,7 @@ int clusterLoadConfig(char *filename) { zfree(line); fclose(fp); - serverLog(LL_NOTICE,"Node configuration loaded, I'm %.40s", myself->name); + serverLog(LL_NOTICE,"Node configuration loaded, I'm %.40s %s", myself->name, myself->human_readable_name); /* Something that should never happen: currentEpoch smaller than * the max epoch found in the nodes configuration. However we handle this @@ -677,8 +680,8 @@ void clusterInit(void) { * by the createClusterNode() function. */ myself = server.cluster->myself = createClusterNode(NULL,CLUSTER_NODE_MYSELF|CLUSTER_NODE_MASTER); - serverLog(LL_NOTICE,"No cluster configuration found, I'm %.40s", - myself->name); + serverLog(LL_NOTICE,"No cluster configuration found, I'm %.40s %s", + myself->name, myself->human_readable_name); clusterAddNode(myself); saveconf = 1; } @@ -786,7 +789,7 @@ void clusterReset(int hard) { sdsfree(oldname); getRandomHexChars(myself->name, CLUSTER_NAMELEN); clusterAddNode(myself); - serverLog(LL_NOTICE,"Node hard reset, now I'm %.40s", myself->name); + serverLog(LL_NOTICE,"Node hard reset, now I'm %.40s %s", myself->name, myself->human_readable_name); } /* Make sure to persist the new config and update the state. */ @@ -975,18 +978,21 @@ unsigned int keyHashSlot(char *key, int keylen) { /* Assign a human readable name to nodes for clusters*/ void setClusterNodeName(clusterNode *node) { - char *name; - int post_digits; - if (node->port == 0){ - post_digits = 0; - } - else{ - post_digits = floor(log10(abs(node->port))) + 1; - } - int allocate_len = sizeof(node->ip) + post_digits + 2; - name = zmalloc(allocate_len); - sprintf(name, "%s%s%d", node->ip, "_", node->port); - node->hname = name; + if (node->has_human_readable_name == 1) + return; + char ip[NET_IP_STR_LEN]; + strcpy(ip,node->ip); + sprintf(node->human_readable_name, "%s_%u", ip,(unsigned int)node->port); +} + +/* Manually assign a human readable name to nodes for clusters*/ +int setManualClusterNodeName(clusterNode *node, char * newname) { + if (newname == NULL) + return 0; + memcpy(node->human_readable_name, newname, strlen(newname) + 1); + node->has_human_readable_name = 1; + clusterSaveConfig(1); + return 1; } /* Create a new cluster node, with the specified flags. @@ -1009,6 +1015,7 @@ clusterNode *createClusterNode(char *nodename, int flags) { memset(node->slots,0,sizeof(node->slots)); node->slot_info_pairs = NULL; node->numslots = 0; + node->has_human_readable_name = 0; node->numslaves = 0; node->slaves = NULL; node->slaveof = NULL; @@ -1410,9 +1417,9 @@ void clusterHandleConfigEpochCollision(clusterNode *sender) { myself->configEpoch = server.cluster->currentEpoch; clusterSaveConfigOrDie(1); serverLog(LL_VERBOSE, - "WARNING: configEpoch collision with node %.40s." + "WARNING: configEpoch collision with node %.40s %s." " configEpoch set to %llu", - sender->name, + sender->name, sender->human_readable_name, (unsigned long long) myself->configEpoch); } @@ -1528,7 +1535,7 @@ void markNodeAsFailingIfNeeded(clusterNode *node) { if (failures < needed_quorum) return; /* No weak agreement from masters. */ serverLog(LL_NOTICE, - "Marking node %.40s as failing (quorum reached).", node->name); + "Marking node %.40s %s as failing (quorum reached).", node->name, node ->human_readable_name); /* Mark the node as failing. */ node->flags &= ~CLUSTER_NODE_PFAIL; @@ -1556,8 +1563,8 @@ void clearNodeFailureIfNeeded(clusterNode *node) { * node again. */ if (nodeIsSlave(node) || node->numslots == 0) { serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s: %s is reachable again.", - node->name, + "Clear FAIL state for node %.40s %s: %s is reachable again.", + node->name, node->human_readable_name, nodeIsSlave(node) ? "replica" : "master without slots"); node->flags &= ~CLUSTER_NODE_FAIL; clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); @@ -1572,8 +1579,8 @@ void clearNodeFailureIfNeeded(clusterNode *node) { (server.cluster_node_timeout * CLUSTER_FAIL_UNDO_TIME_MULT)) { serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s: is reachable again and nobody is serving its slots after some time.", - node->name); + "Clear FAIL state for node %.40s %s: is reachable again and nobody is serving its slots after some time.", + node->name, node->human_readable_name); node->flags &= ~CLUSTER_NODE_FAIL; clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); } @@ -1694,15 +1701,15 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { if (flags & (CLUSTER_NODE_FAIL|CLUSTER_NODE_PFAIL)) { if (clusterNodeAddFailureReport(node,sender)) { serverLog(LL_VERBOSE, - "Node %.40s reported node %.40s as not reachable.", - sender->name, node->name); + "Node %.40s %s reported node %.40s %s as not reachable.", + sender->name, sender->human_readable_name, node->name, node->human_readable_name); } markNodeAsFailingIfNeeded(node); } else { if (clusterNodeDelFailureReport(node,sender)) { serverLog(LL_VERBOSE, - "Node %.40s reported node %.40s is back online.", - sender->name, node->name); + "Node %.40s %s reported node %.40s %s is back online.", + sender->name, sender->human_readable_name, node->name, node->human_readable_name); } } } @@ -1747,7 +1754,10 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { node->pport = ntohs(g->pport); node->cport = ntohs(g->cport); node->flags &= ~CLUSTER_NODE_NOADDR; - setClusterNodeName(node); + if (hdr->has_human_readable_name) + setManualClusterNodeName(node, hdr->human_readable_name); + else + setClusterNodeName(node); } } else { /* If it's not in NOADDR state and we don't have it, we @@ -1769,7 +1779,10 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { node->port = ntohs(g->port); node->pport = ntohs(g->pport); node->cport = ntohs(g->cport); - setClusterNodeName(node); + if (hdr->has_human_readable_name) + setManualClusterNodeName(node, hdr->human_readable_name); + else + setClusterNodeName(node); clusterAddNode(node); } } @@ -1828,7 +1841,10 @@ int nodeUpdateAddressIfNeeded(clusterNode *node, clusterLink *link, node->port = port; node->pport = pport; node->cport = cport; - setClusterNodeName(node); + if (hdr->has_human_readable_name) + setManualClusterNodeName(node, hdr->human_readable_name); + else + setClusterNodeName(node); if (node->link) freeClusterLink(node->link); node->flags &= ~CLUSTER_NODE_NOADDR; serverLog(LL_WARNING,"Address updated for node %.40s , now %s:%d", @@ -1961,7 +1977,7 @@ void clusterUpdateSlotsConfigWith(clusterNode *sender, uint64_t senderConfigEpoc sender_slots == migrated_our_slots)) { serverLog(LL_WARNING, "Configuration change detected. Reconfiguring myself " - "as a replica of %.40s", sender->name); + "as a replica of %.40s %s", sender->name, sender->human_readable_name); clusterSetMaster(sender); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| CLUSTER_TODO_UPDATE_STATE| @@ -2291,6 +2307,10 @@ int clusterProcessPacket(clusterLink *link) { } } + if (sender && strcmp(sender->human_readable_name,hdr->human_readable_name) != 0) { + strncpy(sender->human_readable_name, hdr->human_readable_name, CLUSTER_HUMAN_NAMELEN); + } + /* Add this node if it is new for us and the msg type is MEET. * In this stage we don't try to add the node with the right * flags, slaveof pointer, and so forth, as this details will be @@ -2348,8 +2368,8 @@ int clusterProcessPacket(clusterLink *link) { /* First thing to do is replacing the random name with the * right node name if this was a handshake stage. */ clusterRenameNode(link->node, hdr->sender); - serverLog(LL_DEBUG,"Handshake with node %.40s completed.", - link->node->name); + serverLog(LL_DEBUG,"Handshake with node %.40s %s completed.", + link->node->name, link->node->human_readable_name); link->node->flags &= ~CLUSTER_NODE_HANDSHAKE; link->node->flags |= flags&(CLUSTER_NODE_MASTER|CLUSTER_NODE_SLAVE); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG); @@ -2359,8 +2379,8 @@ int clusterProcessPacket(clusterLink *link) { /* If the reply has a non matching node ID we * disconnect this node and set it as not having an associated * address. */ - serverLog(LL_DEBUG,"PONG contains mismatching sender ID. About node %.40s added %d ms ago, having flags %d", - link->node->name, + serverLog(LL_DEBUG,"PONG contains mismatching sender ID. About node %.40s %s added %d ms ago, having flags %d", + link->node->name, link->node->human_readable_name, (int)(now-(link->node->ctime)), link->node->flags); link->node->flags |= CLUSTER_NODE_NOADDR; @@ -2696,8 +2716,8 @@ void clusterLinkConnectHandler(connection *conn) { /* Check if connection succeeded */ if (connGetState(conn) != CONN_STATE_CONNECTED) { - serverLog(LL_VERBOSE, "Connection with Node %.40s at %s:%d failed: %s", - node->name, node->ip, node->cport, + serverLog(LL_VERBOSE, "Connection with Node %.40s %s at %s:%d failed: %s", + node->name, node->human_readable_name, node->ip, node->cport, connGetLastError(conn)); freeClusterLink(link); return; @@ -2728,8 +2748,8 @@ void clusterLinkConnectHandler(connection *conn) { * normal PING packets. */ node->flags &= ~CLUSTER_NODE_MEET; - serverLog(LL_DEBUG,"Connecting with Node %.40s at %s:%d", - node->name, node->ip, node->cport); + serverLog(LL_DEBUG,"Connecting with Node %.40s %s at %s:%d", + node->name, node->human_readable_name, node->ip, node->cport); } /* Read data. Try to read the first field of the header first to check the @@ -2947,6 +2967,7 @@ void clusterSetGossipEntry(clusterMsg *hdr, int i, clusterNode *n) { gossip->cport = htons(n->cport); gossip->flags = htons(n->flags); gossip->pport = htons(n->pport); + gossip->has_human_readable_name = n->has_human_readable_name; gossip->notused1 = 0; } @@ -3377,8 +3398,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * request, if the request epoch was greater. */ if (requestCurrentEpoch < server.cluster->currentEpoch) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: reqEpoch (%llu) < curEpoch(%llu)", - node->name, + "Failover auth denied to %.40s %s: reqEpoch (%llu) < curEpoch(%llu)", + node->name, node->human_readable_name, (unsigned long long) requestCurrentEpoch, (unsigned long long) server.cluster->currentEpoch); return; @@ -3387,8 +3408,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { /* I already voted for this epoch? Return ASAP. */ if (server.cluster->lastVoteEpoch == server.cluster->currentEpoch) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: already voted for epoch %llu", - node->name, + "Failover auth denied to %.40s %s: already voted for epoch %llu", + node->name, node->human_readable_name, (unsigned long long) server.cluster->currentEpoch); return; } @@ -3401,16 +3422,16 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { { if (nodeIsMaster(node)) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: it is a master node", - node->name); + "Failover auth denied to %.40s %s: it is a master node", + node->name, node->human_readable_name); } else if (master == NULL) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: I don't know its master", - node->name); + "Failover auth denied to %.40s %s: I don't know its master", + node->name, node->human_readable_name); } else if (!nodeFailed(master)) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: its master is up", - node->name); + "Failover auth denied to %.40s %s: its master is up", + node->name, node->human_readable_name); } return; } @@ -3421,7 +3442,7 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { if (mstime() - node->slaveof->voted_time < server.cluster_node_timeout * 2) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: " + "Failover auth denied to %.40s %s: " "can't vote about this master before %lld milliseconds", node->name, (long long) ((server.cluster_node_timeout*2)- @@ -3443,9 +3464,9 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * is served by a master with a greater configEpoch than the one claimed * by the slave requesting our vote. Refuse to vote for this slave. */ serverLog(LL_WARNING, - "Failover auth denied to %.40s: " + "Failover auth denied to %.40s %s: " "slot %d epoch (%llu) > reqEpoch (%llu)", - node->name, j, + node->name, node->human_readable_name, j, (unsigned long long) server.cluster->slots[j]->configEpoch, (unsigned long long) requestConfigEpoch); return; @@ -3456,8 +3477,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { node->slaveof->voted_time = mstime(); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG|CLUSTER_TODO_FSYNC_CONFIG); clusterSendFailoverAuth(node); - serverLog(LL_WARNING, "Failover auth granted to %.40s for epoch %llu", - node->name, (unsigned long long) server.cluster->currentEpoch); + serverLog(LL_WARNING, "Failover auth granted to %.40s %s for epoch %llu", + node->name, node->human_readable_name, (unsigned long long) server.cluster->currentEpoch); } /* This function returns the "rank" of this instance, a slave, in the context @@ -3685,7 +3706,7 @@ void clusterHandleSlaveFailover(void) { if (server.cluster->mf_end) { server.cluster->failover_auth_time = mstime(); server.cluster->failover_auth_rank = 0; - clusterDoBeforeSleep(CLUSTER_TODO_HANDLE_FAILOVER); + clusterDoBeforeSleep(CLUSTER_TODO_HANDLE_FAILOVER); } serverLog(LL_WARNING, "Start of election delayed for %lld milliseconds " @@ -3874,8 +3895,8 @@ void clusterHandleSlaveMigration(int max_slaves) { (mstime()-target->orphaned_time) > CLUSTER_SLAVE_MIGRATION_DELAY && !(server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_FAILOVER)) { - serverLog(LL_WARNING,"Migrating to orphaned master %.40s", - target->name); + serverLog(LL_WARNING,"Migrating to orphaned master %.40s %s", + target->name, target->human_readable_name); clusterSetMaster(target); } } @@ -4122,7 +4143,7 @@ void clusterCron(void) { } } if (min_pong_node) { - serverLog(LL_DEBUG,"Pinging node %.40s", min_pong_node->name); + serverLog(LL_DEBUG,"Pinging node %.40s %s", min_pong_node->name, min_pong_node->human_readable_name); clusterSendPing(min_pong_node->link, CLUSTERMSG_TYPE_PING); } } @@ -4222,8 +4243,8 @@ void clusterCron(void) { /* Timeout reached. Set the node as possibly failing if it is * not already in this state. */ if (!(node->flags & (CLUSTER_NODE_PFAIL|CLUSTER_NODE_FAIL))) { - serverLog(LL_DEBUG,"*** NODE %.40s possibly failing", - node->name); + serverLog(LL_DEBUG,"*** NODE %.40s %s possibly failing", + node->name, node->human_readable_name); node->flags |= CLUSTER_NODE_PFAIL; update_state = 1; } @@ -4739,6 +4760,9 @@ sds clusterGenNodeDescription(clusterNode *node, int use_pport) { else ci = sdscatlen(ci,"-",1); + /* Adding has human readable name */ + ci = sdscatfmt(ci," %i",node->has_human_readable_name); + unsigned long long nodeEpoch = node->configEpoch; if (nodeIsSlave(node) && node->slaveof) { nodeEpoch = node->slaveof->configEpoch; @@ -5310,10 +5334,12 @@ void clusterCommand(client *c) { "MYID", " Return the node id.", "MYNAME", -" Return the node name.", +" Return the human readable node name.", +"SETNAME ", +" Sets the human-readable node name.", "NODES", " Return cluster configuration seen by node. Output format:", -" ...", +" ...", "REPLICATE ", " Configure current node as replica to .", "RESET [HARD|SOFT]", @@ -5378,11 +5404,17 @@ NULL /* CLUSTER MYID */ addReplyBulkCBuffer(c,myself->name, CLUSTER_NAMELEN); } else if (!strcasecmp(c->argv[1]->ptr,"myname") && c->argc == 2) { - /* CLUSTER MYID */ - if (myself->hname) - addReplyBulkCBuffer(c,myself->hname, strlen(myself->hname)); + /* CLUSTER MYNAME */ + if (myself->human_readable_name[0] != '\0') + addReplyBulkCBuffer(c,myself->human_readable_name, strlen(myself->human_readable_name)); else addReplyError(c,"Node is not assigned name yet."); + } else if (!strcasecmp(c->argv[1]->ptr,"setname") && c->argc == 3) { + /* CLUSTER SETNAME */ + if (setManualClusterNodeName(myself,c->argv[2]->ptr)) + addReply(c,shared.ok); + else + addReplyError(c,"Error setting the name of the node."); } else if (!strcasecmp(c->argv[1]->ptr,"slots") && c->argc == 2) { /* CLUSTER SLOTS */ clusterReplyMultiBulkSlots(c); diff --git a/src/cluster.h b/src/cluster.h index 2e6b6d97062..b39f5e940ad 100644 --- a/src/cluster.h +++ b/src/cluster.h @@ -9,6 +9,7 @@ #define CLUSTER_OK 0 /* Everything looks ok */ #define CLUSTER_FAIL 1 /* The cluster can't work */ #define CLUSTER_NAMELEN 40 /* sha1 hex length */ +#define CLUSTER_HUMAN_NAMELEN 64 /* Max length of human readable node name */ #define CLUSTER_PORT_INCR 10000 /* Cluster port = baseport + PORT_INCR */ /* The following defines are amount of time, sometimes expressed as @@ -115,7 +116,7 @@ typedef struct clusterNodeFailReport { typedef struct clusterNode { mstime_t ctime; /* Node object creation time. */ char name[CLUSTER_NAMELEN]; /* Node name, hex string, sha1-size */ - char* hname; /* Human readable name for node */ + char human_readable_name[CLUSTER_HUMAN_NAMELEN]; /* Human readable name for node */ int flags; /* CLUSTER_NODE_... */ uint64_t configEpoch; /* Last configEpoch observed for this node */ unsigned char slots[CLUSTER_SLOTS/8]; /* slots handled by this node */ @@ -144,6 +145,7 @@ typedef struct clusterNode { clusterLink *link; /* TCP/IP link established toward this node */ clusterLink *inbound_link; /* TCP/IP link accepted from this node */ list *fail_reports; /* List of nodes signaling this as failing */ + int has_human_readable_name; /* Indicates whether custom nodename is used */ } clusterNode; /* Slot to keys for a single slot. The keys in the same slot are linked together @@ -217,11 +219,13 @@ typedef struct { uint32_t ping_sent; uint32_t pong_received; char ip[NET_IP_STR_LEN]; /* IP address last time it was seen */ + char human_readable_name[CLUSTER_HUMAN_NAMELEN]; /* Human readable name for node */ uint16_t port; /* base port last time it was seen */ uint16_t cport; /* cluster port last time it was seen */ uint16_t flags; /* node->flags copy */ uint16_t pport; /* plaintext-port, when base port is TLS */ uint16_t notused1; + int has_human_readable_name; /* Indicates whether custom nodename is used */ } clusterMsgDataGossip; typedef struct { @@ -327,6 +331,7 @@ typedef struct { unsigned char myslots[CLUSTER_SLOTS/8]; char slaveof[CLUSTER_NAMELEN]; char myip[NET_IP_STR_LEN]; /* Sender IP, if not all zeroed. */ + char human_readable_name[CLUSTER_HUMAN_NAMELEN]; uint16_t extensions; /* Number of extensions sent along with this packet. */ char notused1[30]; /* 30 bytes reserved for future usage. */ uint16_t pport; /* Sender TCP plaintext port, if base port is TLS */ @@ -335,6 +340,7 @@ typedef struct { unsigned char state; /* Cluster state from the POV of the sender */ unsigned char mflags[3]; /* Message flags: CLUSTERMSG_FLAG[012]_... */ union clusterMsgData data; + int has_human_readable_name; /* Indicates whether custom nodename is used */ } clusterMsg; /* clusterMsg defines the gossip wire protocol exchanged among Redis cluster diff --git a/src/redis-cli.c b/src/redis-cli.c index 051ab94e9d9..b6b66a0612c 100644 --- a/src/redis-cli.c +++ b/src/redis-cli.c @@ -4585,9 +4585,10 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, lines = p + 1; char *name = NULL, *addr = NULL, *flags = NULL, *master_id = NULL, *ping_sent = NULL, *ping_recv = NULL, *config_epoch = NULL, - *link_status = NULL, *hname = NULL; + *link_status = NULL, *human_readable_name = NULL, *has_human_readable_name = NULL; UNUSED(link_status); - UNUSED(hname); + UNUSED(human_readable_name); + UNUSED(has_human_readable_name); int i = 0; while ((p = strchr(line, ' ')) != NULL) { *p = '\0'; @@ -4595,16 +4596,17 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, line = p + 1; switch(i++){ case 0: name = token; break; - case 1: hname = token; break; + case 1: human_readable_name = token; break; case 2: addr = token; break; case 3: flags = token; break; case 4: master_id = token; break; - case 5: ping_sent = token; break; - case 6: ping_recv = token; break; - case 7: config_epoch = token; break; - case 8: link_status = token; break; + case 5: has_human_readable_name = token; break; + case 6: ping_sent = token; break; + case 7: ping_recv = token; break; + case 8: config_epoch = token; break; + case 9: link_status = token; break; } - if (i == 9) break; // Slots + if (i == 10) break; // Slots } if (!flags) { success = 0; @@ -4616,7 +4618,7 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, node->flags |= CLUSTER_MANAGER_FLAG_MYSELF; currentNode = node; clusterManagerNodeResetSlots(node); - if (i == 9) { + if (i == 10) { int remaining = strlen(line); while (remaining > 0) { p = strchr(line, ' '); diff --git a/tests/cluster/cluster.tcl b/tests/cluster/cluster.tcl index 802b5b6f573..7f6b7e71ab6 100644 --- a/tests/cluster/cluster.tcl +++ b/tests/cluster/cluster.tcl @@ -22,11 +22,12 @@ proc get_cluster_nodes id { addr [lindex $args 2] \ flags [split [lindex $args 3] ,] \ slaveof [lindex $args 4] \ - ping_sent [lindex $args 5] \ - pong_recv [lindex $args 6] \ - config_epoch [lindex $args 7] \ - linkstate [lindex $args 8] \ - slots [lrange $args 9 end] \ + customName [lindex $args 5] \ + ping_sent [lindex $args 6] \ + pong_recv [lindex $args 7] \ + config_epoch [lindex $args 8] \ + linkstate [lindex $args 9] \ + slots [lrange $args 10 end] \ ] lappend nodes $node } diff --git a/tests/support/cluster.tcl b/tests/support/cluster.tcl index 8c628dcd3f1..2ead91f43d1 100644 --- a/tests/support/cluster.tcl +++ b/tests/support/cluster.tcl @@ -104,8 +104,8 @@ proc ::redis_cluster::__method__refresh_nodes_map {id} { set line [string trim $line] if {$line eq {}} continue set args [split $line " "] - lassign $args nodeid name addr flags slaveof pingsent pongrecv configepoch linkstate - set slots [lrange $args 9 end] + lassign $args nodeid name addr flags slaveof customname pingsent pongrecv configepoch linkstate + set slots [lrange $args 10 end] set addr [lindex [split $addr @] 0] if {$addr eq {:0}} { set addr $start_host:$start_port @@ -126,6 +126,7 @@ proc ::redis_cluster::__method__refresh_nodes_map {id} { port $port \ flags $flags \ slaveof $slaveof \ + customname $customname \ slots $slots \ link $link \ ] From b96090f28a6bfe5bc3f5e4b26e5061ff97ba1101 Mon Sep 17 00:00:00 2001 From: hwware Date: Wed, 12 Jan 2022 14:08:57 -0500 Subject: [PATCH 73/79] update codes to fix error in rebase --- src/cluster.c | 171 ++++++++++++-------------------------- src/cluster.h | 7 -- src/help.h | 5 -- src/redis-cli.c | 26 +++--- tests/cluster/cluster.tcl | 18 ++-- tests/support/cluster.tcl | 5 +- 6 files changed, 75 insertions(+), 157 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index 08a4753f7eb..7b590751cf0 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -48,7 +48,6 @@ clusterNode *myself = NULL; clusterNode *createClusterNode(char *nodename, int flags); void clusterAddNode(clusterNode *node); -void setClusterNodeName(clusterNode *node); void clusterAcceptHandler(aeEventLoop *el, int fd, void *privdata, int mask); void clusterReadHandler(connection *conn); void clusterSendPing(clusterLink *link, int type); @@ -276,7 +275,7 @@ int clusterLoadConfig(char *filename) { * stored in nodes.conf. It is received later over the bus protocol. */ /* Parse flags */ - p = s = argv[3]; + p = s = argv[2]; while(p) { p = strchr(s,','); if (p) *p = '\0'; @@ -309,28 +308,25 @@ int clusterLoadConfig(char *filename) { /* Get master if any. Set the master and populate master's * slave list. */ - if (argv[4][0] != '-') { - master = clusterLookupNode(argv[4]); + if (argv[3][0] != '-') { + master = clusterLookupNode(argv[3]); if (!master) { - master = createClusterNode(argv[4],0); + master = createClusterNode(argv[3],0); clusterAddNode(master); } n->slaveof = master; clusterNodeAddSlave(master,n); } - /* Custom nodename */ - n->has_human_readable_name = atoi(argv[5]); - /* Set ping sent / pong received timestamps */ - if (atoi(argv[6])) n->ping_sent = mstime(); - if (atoi(argv[7])) n->pong_received = mstime(); + if (atoi(argv[4])) n->ping_sent = mstime(); + if (atoi(argv[5])) n->pong_received = mstime(); /* Set configEpoch for this node. */ - n->configEpoch = strtoull(argv[8],NULL,10); + n->configEpoch = strtoull(argv[6],NULL,10); /* Populate hash slots served by this instance. */ - for (j = 10; j < argc; j++) { + for (j = 8; j < argc; j++) { int start, stop; if (argv[j][0] == '[') { @@ -384,7 +380,7 @@ int clusterLoadConfig(char *filename) { zfree(line); fclose(fp); - serverLog(LL_NOTICE,"Node configuration loaded, I'm %.40s %s", myself->name, myself->human_readable_name); + serverLog(LL_NOTICE,"Node configuration loaded, I'm %.40s", myself->name); /* Something that should never happen: currentEpoch smaller than * the max epoch found in the nodes configuration. However we handle this @@ -680,8 +676,8 @@ void clusterInit(void) { * by the createClusterNode() function. */ myself = server.cluster->myself = createClusterNode(NULL,CLUSTER_NODE_MYSELF|CLUSTER_NODE_MASTER); - serverLog(LL_NOTICE,"No cluster configuration found, I'm %.40s %s", - myself->name, myself->human_readable_name); + serverLog(LL_NOTICE,"No cluster configuration found, I'm %.40s", + myself->name); clusterAddNode(myself); saveconf = 1; } @@ -789,7 +785,7 @@ void clusterReset(int hard) { sdsfree(oldname); getRandomHexChars(myself->name, CLUSTER_NAMELEN); clusterAddNode(myself); - serverLog(LL_NOTICE,"Node hard reset, now I'm %.40s %s", myself->name, myself->human_readable_name); + serverLog(LL_NOTICE,"Node hard reset, now I'm %.40s", myself->name); } /* Make sure to persist the new config and update the state. */ @@ -976,25 +972,6 @@ unsigned int keyHashSlot(char *key, int keylen) { * CLUSTER node API * -------------------------------------------------------------------------- */ -/* Assign a human readable name to nodes for clusters*/ -void setClusterNodeName(clusterNode *node) { - if (node->has_human_readable_name == 1) - return; - char ip[NET_IP_STR_LEN]; - strcpy(ip,node->ip); - sprintf(node->human_readable_name, "%s_%u", ip,(unsigned int)node->port); -} - -/* Manually assign a human readable name to nodes for clusters*/ -int setManualClusterNodeName(clusterNode *node, char * newname) { - if (newname == NULL) - return 0; - memcpy(node->human_readable_name, newname, strlen(newname) + 1); - node->has_human_readable_name = 1; - clusterSaveConfig(1); - return 1; -} - /* Create a new cluster node, with the specified flags. * If "nodename" is NULL this is considered a first handshake and a random * node name is assigned to this node (it will be fixed later when we'll @@ -1015,7 +992,6 @@ clusterNode *createClusterNode(char *nodename, int flags) { memset(node->slots,0,sizeof(node->slots)); node->slot_info_pairs = NULL; node->numslots = 0; - node->has_human_readable_name = 0; node->numslaves = 0; node->slaves = NULL; node->slaveof = NULL; @@ -1417,9 +1393,9 @@ void clusterHandleConfigEpochCollision(clusterNode *sender) { myself->configEpoch = server.cluster->currentEpoch; clusterSaveConfigOrDie(1); serverLog(LL_VERBOSE, - "WARNING: configEpoch collision with node %.40s %s." + "WARNING: configEpoch collision with node %.40s." " configEpoch set to %llu", - sender->name, sender->human_readable_name, + sender->name, (unsigned long long) myself->configEpoch); } @@ -1535,7 +1511,7 @@ void markNodeAsFailingIfNeeded(clusterNode *node) { if (failures < needed_quorum) return; /* No weak agreement from masters. */ serverLog(LL_NOTICE, - "Marking node %.40s %s as failing (quorum reached).", node->name, node ->human_readable_name); + "Marking node %.40s as failing (quorum reached).", node->name); /* Mark the node as failing. */ node->flags &= ~CLUSTER_NODE_PFAIL; @@ -1563,8 +1539,8 @@ void clearNodeFailureIfNeeded(clusterNode *node) { * node again. */ if (nodeIsSlave(node) || node->numslots == 0) { serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s %s: %s is reachable again.", - node->name, node->human_readable_name, + "Clear FAIL state for node %.40s : %s is reachable again.", + node->name, nodeIsSlave(node) ? "replica" : "master without slots"); node->flags &= ~CLUSTER_NODE_FAIL; clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); @@ -1579,8 +1555,8 @@ void clearNodeFailureIfNeeded(clusterNode *node) { (server.cluster_node_timeout * CLUSTER_FAIL_UNDO_TIME_MULT)) { serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s %s: is reachable again and nobody is serving its slots after some time.", - node->name, node->human_readable_name); + "Clear FAIL state for node %.40s : is reachable again and nobody is serving its slots after some time.", + node->name); node->flags &= ~CLUSTER_NODE_FAIL; clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); } @@ -1662,7 +1638,6 @@ int clusterStartHandshake(char *ip, int port, int cport) { memcpy(n->ip,norm_ip,sizeof(n->ip)); n->port = port; n->cport = cport; - setClusterNodeName(n); clusterAddNode(n); return 1; } @@ -1701,15 +1676,15 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { if (flags & (CLUSTER_NODE_FAIL|CLUSTER_NODE_PFAIL)) { if (clusterNodeAddFailureReport(node,sender)) { serverLog(LL_VERBOSE, - "Node %.40s %s reported node %.40s %s as not reachable.", - sender->name, sender->human_readable_name, node->name, node->human_readable_name); + "Node %.40s reported node %.40s as not reachable.", + sender->name, node->name); } markNodeAsFailingIfNeeded(node); } else { if (clusterNodeDelFailureReport(node,sender)) { serverLog(LL_VERBOSE, - "Node %.40s %s reported node %.40s %s is back online.", - sender->name, sender->human_readable_name, node->name, node->human_readable_name); + "Node %.40s reported node %.40s is back online.", + sender->name, node->name); } } } @@ -1754,10 +1729,6 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { node->pport = ntohs(g->pport); node->cport = ntohs(g->cport); node->flags &= ~CLUSTER_NODE_NOADDR; - if (hdr->has_human_readable_name) - setManualClusterNodeName(node, hdr->human_readable_name); - else - setClusterNodeName(node); } } else { /* If it's not in NOADDR state and we don't have it, we @@ -1779,10 +1750,6 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { node->port = ntohs(g->port); node->pport = ntohs(g->pport); node->cport = ntohs(g->cport); - if (hdr->has_human_readable_name) - setManualClusterNodeName(node, hdr->human_readable_name); - else - setClusterNodeName(node); clusterAddNode(node); } } @@ -1841,10 +1808,6 @@ int nodeUpdateAddressIfNeeded(clusterNode *node, clusterLink *link, node->port = port; node->pport = pport; node->cport = cport; - if (hdr->has_human_readable_name) - setManualClusterNodeName(node, hdr->human_readable_name); - else - setClusterNodeName(node); if (node->link) freeClusterLink(node->link); node->flags &= ~CLUSTER_NODE_NOADDR; serverLog(LL_WARNING,"Address updated for node %.40s , now %s:%d", @@ -1977,7 +1940,7 @@ void clusterUpdateSlotsConfigWith(clusterNode *sender, uint64_t senderConfigEpoc sender_slots == migrated_our_slots)) { serverLog(LL_WARNING, "Configuration change detected. Reconfiguring myself " - "as a replica of %.40s %s", sender->name, sender->human_readable_name); + "as a replica of %.40s ", sender->name); clusterSetMaster(sender); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| CLUSTER_TODO_UPDATE_STATE| @@ -2300,17 +2263,12 @@ int clusterProcessPacket(clusterLink *link) { strcmp(ip,myself->ip)) { memcpy(myself->ip,ip,NET_IP_STR_LEN); - setClusterNodeName(myself); serverLog(LL_WARNING,"IP address for this node updated to %s", myself->ip); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG); } } - if (sender && strcmp(sender->human_readable_name,hdr->human_readable_name) != 0) { - strncpy(sender->human_readable_name, hdr->human_readable_name, CLUSTER_HUMAN_NAMELEN); - } - /* Add this node if it is new for us and the msg type is MEET. * In this stage we don't try to add the node with the right * flags, slaveof pointer, and so forth, as this details will be @@ -2323,7 +2281,6 @@ int clusterProcessPacket(clusterLink *link) { node->port = ntohs(hdr->port); node->pport = ntohs(hdr->pport); node->cport = ntohs(hdr->cport); - setClusterNodeName(node); clusterAddNode(node); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG); } @@ -2368,8 +2325,8 @@ int clusterProcessPacket(clusterLink *link) { /* First thing to do is replacing the random name with the * right node name if this was a handshake stage. */ clusterRenameNode(link->node, hdr->sender); - serverLog(LL_DEBUG,"Handshake with node %.40s %s completed.", - link->node->name, link->node->human_readable_name); + serverLog(LL_DEBUG,"Handshake with node %.40s completed.", + link->node->name); link->node->flags &= ~CLUSTER_NODE_HANDSHAKE; link->node->flags |= flags&(CLUSTER_NODE_MASTER|CLUSTER_NODE_SLAVE); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG); @@ -2379,8 +2336,8 @@ int clusterProcessPacket(clusterLink *link) { /* If the reply has a non matching node ID we * disconnect this node and set it as not having an associated * address. */ - serverLog(LL_DEBUG,"PONG contains mismatching sender ID. About node %.40s %s added %d ms ago, having flags %d", - link->node->name, link->node->human_readable_name, + serverLog(LL_DEBUG,"PONG contains mismatching sender ID. About node %.40s added %d ms ago, having flags %d", + link->node->name, (int)(now-(link->node->ctime)), link->node->flags); link->node->flags |= CLUSTER_NODE_NOADDR; @@ -2716,8 +2673,8 @@ void clusterLinkConnectHandler(connection *conn) { /* Check if connection succeeded */ if (connGetState(conn) != CONN_STATE_CONNECTED) { - serverLog(LL_VERBOSE, "Connection with Node %.40s %s at %s:%d failed: %s", - node->name, node->human_readable_name, node->ip, node->cport, + serverLog(LL_VERBOSE, "Connection with Node %.40s at %s:%d failed: %s", + node->name, node->ip, node->cport, connGetLastError(conn)); freeClusterLink(link); return; @@ -2748,8 +2705,8 @@ void clusterLinkConnectHandler(connection *conn) { * normal PING packets. */ node->flags &= ~CLUSTER_NODE_MEET; - serverLog(LL_DEBUG,"Connecting with Node %.40s %s at %s:%d", - node->name, node->human_readable_name, node->ip, node->cport); + serverLog(LL_DEBUG,"Connecting with Node %.40s at %s:%d", + node->name, node->ip, node->cport); } /* Read data. Try to read the first field of the header first to check the @@ -2967,7 +2924,6 @@ void clusterSetGossipEntry(clusterMsg *hdr, int i, clusterNode *n) { gossip->cport = htons(n->cport); gossip->flags = htons(n->flags); gossip->pport = htons(n->pport); - gossip->has_human_readable_name = n->has_human_readable_name; gossip->notused1 = 0; } @@ -3398,8 +3354,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * request, if the request epoch was greater. */ if (requestCurrentEpoch < server.cluster->currentEpoch) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: reqEpoch (%llu) < curEpoch(%llu)", - node->name, node->human_readable_name, + "Failover auth denied to %.40s : reqEpoch (%llu) < curEpoch(%llu)", + node->name, (unsigned long long) requestCurrentEpoch, (unsigned long long) server.cluster->currentEpoch); return; @@ -3408,8 +3364,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { /* I already voted for this epoch? Return ASAP. */ if (server.cluster->lastVoteEpoch == server.cluster->currentEpoch) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: already voted for epoch %llu", - node->name, node->human_readable_name, + "Failover auth denied to %.40s : already voted for epoch %llu", + node->name, (unsigned long long) server.cluster->currentEpoch); return; } @@ -3422,16 +3378,16 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { { if (nodeIsMaster(node)) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: it is a master node", - node->name, node->human_readable_name); + "Failover auth denied to %.40s : it is a master node", + node->name); } else if (master == NULL) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: I don't know its master", - node->name, node->human_readable_name); + "Failover auth denied to %.40s : I don't know its master", + node->name); } else if (!nodeFailed(master)) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: its master is up", - node->name, node->human_readable_name); + "Failover auth denied to %.40s : its master is up", + node->name); } return; } @@ -3442,7 +3398,7 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { if (mstime() - node->slaveof->voted_time < server.cluster_node_timeout * 2) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: " + "Failover auth denied to %.40s : " "can't vote about this master before %lld milliseconds", node->name, (long long) ((server.cluster_node_timeout*2)- @@ -3464,9 +3420,9 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * is served by a master with a greater configEpoch than the one claimed * by the slave requesting our vote. Refuse to vote for this slave. */ serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: " + "Failover auth denied to %.40s : " "slot %d epoch (%llu) > reqEpoch (%llu)", - node->name, node->human_readable_name, j, + node->name, j, (unsigned long long) server.cluster->slots[j]->configEpoch, (unsigned long long) requestConfigEpoch); return; @@ -3477,8 +3433,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { node->slaveof->voted_time = mstime(); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG|CLUSTER_TODO_FSYNC_CONFIG); clusterSendFailoverAuth(node); - serverLog(LL_WARNING, "Failover auth granted to %.40s %s for epoch %llu", - node->name, node->human_readable_name, (unsigned long long) server.cluster->currentEpoch); + serverLog(LL_WARNING, "Failover auth granted to %.40s for epoch %llu", + node->name, (unsigned long long) server.cluster->currentEpoch); } /* This function returns the "rank" of this instance, a slave, in the context @@ -3895,8 +3851,8 @@ void clusterHandleSlaveMigration(int max_slaves) { (mstime()-target->orphaned_time) > CLUSTER_SLAVE_MIGRATION_DELAY && !(server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_FAILOVER)) { - serverLog(LL_WARNING,"Migrating to orphaned master %.40s %s", - target->name, target->human_readable_name); + serverLog(LL_WARNING,"Migrating to orphaned master %.40s ", + target->name); clusterSetMaster(target); } } @@ -4143,7 +4099,7 @@ void clusterCron(void) { } } if (min_pong_node) { - serverLog(LL_DEBUG,"Pinging node %.40s %s", min_pong_node->name, min_pong_node->human_readable_name); + serverLog(LL_DEBUG,"Pinging node %.40s ", min_pong_node->name); clusterSendPing(min_pong_node->link, CLUSTERMSG_TYPE_PING); } } @@ -4243,8 +4199,8 @@ void clusterCron(void) { /* Timeout reached. Set the node as possibly failing if it is * not already in this state. */ if (!(node->flags & (CLUSTER_NODE_PFAIL|CLUSTER_NODE_FAIL))) { - serverLog(LL_DEBUG,"*** NODE %.40s %s possibly failing", - node->name, node->human_readable_name); + serverLog(LL_DEBUG,"*** NODE %.40s possibly failing", + node->name); node->flags |= CLUSTER_NODE_PFAIL; update_state = 1; } @@ -4758,10 +4714,7 @@ sds clusterGenNodeDescription(clusterNode *node, int use_pport) { if (node->slaveof) ci = sdscatlen(ci,node->slaveof->name,CLUSTER_NAMELEN); else - ci = sdscatlen(ci,"-",1); - - /* Adding has human readable name */ - ci = sdscatfmt(ci," %i",node->has_human_readable_name); + ci = sdscatlen(ci,"-",1); unsigned long long nodeEpoch = node->configEpoch; if (nodeIsSlave(node) && node->slaveof) { @@ -5333,13 +5286,9 @@ void clusterCommand(client *c) { " Connect nodes into a working cluster.", "MYID", " Return the node id.", -"MYNAME", -" Return the human readable node name.", -"SETNAME ", -" Sets the human-readable node name.", "NODES", " Return cluster configuration seen by node. Output format:", -" ...", +" ...", "REPLICATE ", " Configure current node as replica to .", "RESET [HARD|SOFT]", @@ -5403,18 +5352,6 @@ NULL } else if (!strcasecmp(c->argv[1]->ptr,"myid") && c->argc == 2) { /* CLUSTER MYID */ addReplyBulkCBuffer(c,myself->name, CLUSTER_NAMELEN); - } else if (!strcasecmp(c->argv[1]->ptr,"myname") && c->argc == 2) { - /* CLUSTER MYNAME */ - if (myself->human_readable_name[0] != '\0') - addReplyBulkCBuffer(c,myself->human_readable_name, strlen(myself->human_readable_name)); - else - addReplyError(c,"Node is not assigned name yet."); - } else if (!strcasecmp(c->argv[1]->ptr,"setname") && c->argc == 3) { - /* CLUSTER SETNAME */ - if (setManualClusterNodeName(myself,c->argv[2]->ptr)) - addReply(c,shared.ok); - else - addReplyError(c,"Error setting the name of the node."); } else if (!strcasecmp(c->argv[1]->ptr,"slots") && c->argc == 2) { /* CLUSTER SLOTS */ clusterReplyMultiBulkSlots(c); diff --git a/src/cluster.h b/src/cluster.h index b39f5e940ad..475b4bf5ca8 100644 --- a/src/cluster.h +++ b/src/cluster.h @@ -9,7 +9,6 @@ #define CLUSTER_OK 0 /* Everything looks ok */ #define CLUSTER_FAIL 1 /* The cluster can't work */ #define CLUSTER_NAMELEN 40 /* sha1 hex length */ -#define CLUSTER_HUMAN_NAMELEN 64 /* Max length of human readable node name */ #define CLUSTER_PORT_INCR 10000 /* Cluster port = baseport + PORT_INCR */ /* The following defines are amount of time, sometimes expressed as @@ -116,7 +115,6 @@ typedef struct clusterNodeFailReport { typedef struct clusterNode { mstime_t ctime; /* Node object creation time. */ char name[CLUSTER_NAMELEN]; /* Node name, hex string, sha1-size */ - char human_readable_name[CLUSTER_HUMAN_NAMELEN]; /* Human readable name for node */ int flags; /* CLUSTER_NODE_... */ uint64_t configEpoch; /* Last configEpoch observed for this node */ unsigned char slots[CLUSTER_SLOTS/8]; /* slots handled by this node */ @@ -145,7 +143,6 @@ typedef struct clusterNode { clusterLink *link; /* TCP/IP link established toward this node */ clusterLink *inbound_link; /* TCP/IP link accepted from this node */ list *fail_reports; /* List of nodes signaling this as failing */ - int has_human_readable_name; /* Indicates whether custom nodename is used */ } clusterNode; /* Slot to keys for a single slot. The keys in the same slot are linked together @@ -219,13 +216,11 @@ typedef struct { uint32_t ping_sent; uint32_t pong_received; char ip[NET_IP_STR_LEN]; /* IP address last time it was seen */ - char human_readable_name[CLUSTER_HUMAN_NAMELEN]; /* Human readable name for node */ uint16_t port; /* base port last time it was seen */ uint16_t cport; /* cluster port last time it was seen */ uint16_t flags; /* node->flags copy */ uint16_t pport; /* plaintext-port, when base port is TLS */ uint16_t notused1; - int has_human_readable_name; /* Indicates whether custom nodename is used */ } clusterMsgDataGossip; typedef struct { @@ -331,7 +326,6 @@ typedef struct { unsigned char myslots[CLUSTER_SLOTS/8]; char slaveof[CLUSTER_NAMELEN]; char myip[NET_IP_STR_LEN]; /* Sender IP, if not all zeroed. */ - char human_readable_name[CLUSTER_HUMAN_NAMELEN]; uint16_t extensions; /* Number of extensions sent along with this packet. */ char notused1[30]; /* 30 bytes reserved for future usage. */ uint16_t pport; /* Sender TCP plaintext port, if base port is TLS */ @@ -340,7 +334,6 @@ typedef struct { unsigned char state; /* Cluster state from the POV of the sender */ unsigned char mflags[3]; /* Message flags: CLUSTERMSG_FLAG[012]_... */ union clusterMsgData data; - int has_human_readable_name; /* Indicates whether custom nodename is used */ } clusterMsg; /* clusterMsg defines the gossip wire protocol exchanged among Redis cluster diff --git a/src/help.h b/src/help.h index 6ad21ebd2c1..edeb9b26e5f 100644 --- a/src/help.h +++ b/src/help.h @@ -364,11 +364,6 @@ struct commandHelp { "Return the node id", 12, "3.0.0" }, - { "CLUSTER MYID", - "", - "Return the node id", - 12, - "3.0.0" }, { "CLUSTER NODES", "", "Get Cluster config for the node", diff --git a/src/redis-cli.c b/src/redis-cli.c index b6b66a0612c..0c003a0dc6c 100644 --- a/src/redis-cli.c +++ b/src/redis-cli.c @@ -4585,10 +4585,8 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, lines = p + 1; char *name = NULL, *addr = NULL, *flags = NULL, *master_id = NULL, *ping_sent = NULL, *ping_recv = NULL, *config_epoch = NULL, - *link_status = NULL, *human_readable_name = NULL, *has_human_readable_name = NULL; + *link_status = NULL; UNUSED(link_status); - UNUSED(human_readable_name); - UNUSED(has_human_readable_name); int i = 0; while ((p = strchr(line, ' ')) != NULL) { *p = '\0'; @@ -4596,17 +4594,15 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, line = p + 1; switch(i++){ case 0: name = token; break; - case 1: human_readable_name = token; break; - case 2: addr = token; break; - case 3: flags = token; break; - case 4: master_id = token; break; - case 5: has_human_readable_name = token; break; - case 6: ping_sent = token; break; - case 7: ping_recv = token; break; - case 8: config_epoch = token; break; - case 9: link_status = token; break; - } - if (i == 10) break; // Slots + case 1: addr = token; break; + case 2: flags = token; break; + case 3: master_id = token; break; + case 4: ping_sent = token; break; + case 5: ping_recv = token; break; + case 6: config_epoch = token; break; + case 7: link_status = token; break; + } + if (i == 8) break; // Slots } if (!flags) { success = 0; @@ -4618,7 +4614,7 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, node->flags |= CLUSTER_MANAGER_FLAG_MYSELF; currentNode = node; clusterManagerNodeResetSlots(node); - if (i == 10) { + if (i == 8) { int remaining = strlen(line); while (remaining > 0) { p = strchr(line, ' '); diff --git a/tests/cluster/cluster.tcl b/tests/cluster/cluster.tcl index 7f6b7e71ab6..9c669e12854 100644 --- a/tests/cluster/cluster.tcl +++ b/tests/cluster/cluster.tcl @@ -18,16 +18,14 @@ proc get_cluster_nodes id { set args [split $l] set node [dict create \ id [lindex $args 0] \ - name [lindex $args 1] \ - addr [lindex $args 2] \ - flags [split [lindex $args 3] ,] \ - slaveof [lindex $args 4] \ - customName [lindex $args 5] \ - ping_sent [lindex $args 6] \ - pong_recv [lindex $args 7] \ - config_epoch [lindex $args 8] \ - linkstate [lindex $args 9] \ - slots [lrange $args 10 end] \ + addr [lindex $args 1] \ + flags [split [lindex $args 2] ,] \ + slaveof [lindex $args 3] \ + ping_sent [lindex $args 4] \ + pong_recv [lindex $args 5] \ + config_epoch [lindex $args 6] \ + linkstate [lindex $args 7] \ + slots [lrange $args 8 end] \ ] lappend nodes $node } diff --git a/tests/support/cluster.tcl b/tests/support/cluster.tcl index 2ead91f43d1..081ef6a9522 100644 --- a/tests/support/cluster.tcl +++ b/tests/support/cluster.tcl @@ -104,8 +104,8 @@ proc ::redis_cluster::__method__refresh_nodes_map {id} { set line [string trim $line] if {$line eq {}} continue set args [split $line " "] - lassign $args nodeid name addr flags slaveof customname pingsent pongrecv configepoch linkstate - set slots [lrange $args 10 end] + lassign $args nodeid addr flags slaveof pingsent pongrecv configepoch linkstate + set slots [lrange $args 8 end] set addr [lindex [split $addr @] 0] if {$addr eq {:0}} { set addr $start_host:$start_port @@ -126,7 +126,6 @@ proc ::redis_cluster::__method__refresh_nodes_map {id} { port $port \ flags $flags \ slaveof $slaveof \ - customname $customname \ slots $slots \ link $link \ ] From b3a8b70e7fea52a411f7968520a59175463b4049 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Wed, 19 Jan 2022 14:52:26 -0500 Subject: [PATCH 74/79] Added nodename support to extension (#61) * Added nodename extension --- src/cluster.c | 74 ++++++++++++++++++++++++++++++--------------------- src/cluster.h | 1 + 2 files changed, 44 insertions(+), 31 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index 7b590751cf0..2b3f1a3edab 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -219,17 +219,6 @@ int clusterLoadConfig(char *filename) { /* Format for the node address information: * ip:port[@cport][,hostname][-nodename] */ - /* Hostname is an optional argument that defines the endpoint - * that can be reported to clients instead of IP. */ - char *hostname = strchr(argv[1], ','); - if (hostname) { - *hostname = '\0'; - hostname++; - n->hostname = sdscpy(n->hostname, hostname); - } else if (sdslen(n->hostname) != 0) { - sdsclear(n->hostname); - } - /* Address and port */ if ((p = strrchr(argv[1],':')) == NULL) { sdsfreesplitres(argv,argc); @@ -270,6 +259,16 @@ int clusterLoadConfig(char *filename) { } else { n->nodename = NULL; } + /* Nodename is an optional argument */ + char *nodename = strchr(p, '-'); + if (nodename) { + *nodename = '\0'; + nodename++; + zfree(n->nodename); + n->nodename = zstrdup(nodename); + } else { + n->nodename = NULL; + } /* The plaintext port for client in a TLS cluster (n->pport) is not * stored in nodes.conf. It is received later over the bus protocol. */ @@ -1002,6 +1001,7 @@ clusterNode *createClusterNode(char *nodename, int flags) { node->inbound_link = NULL; memset(node->ip,0,sizeof(node->ip)); node->hostname = sdsempty(); + node->nodename = NULL; node->port = 0; node->cport = 0; node->pport = 0; @@ -1168,6 +1168,7 @@ void freeClusterNode(clusterNode *n) { serverAssert(dictDelete(server.cluster->nodes,nodename) == DICT_OK); sdsfree(nodename); sdsfree(n->hostname); + zfree(n->nodename); /* Release links and associated data structures. */ if (n->link) freeClusterLink(n->link); @@ -1395,7 +1396,7 @@ void clusterHandleConfigEpochCollision(clusterNode *sender) { serverLog(LL_VERBOSE, "WARNING: configEpoch collision with node %.40s." " configEpoch set to %llu", - sender->name, + sender->name, (unsigned long long) myself->configEpoch); } @@ -1539,8 +1540,8 @@ void clearNodeFailureIfNeeded(clusterNode *node) { * node again. */ if (nodeIsSlave(node) || node->numslots == 0) { serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s : %s is reachable again.", - node->name, + "Clear FAIL state for node %.40s: %s is reachable again.", + node->name, nodeIsSlave(node) ? "replica" : "master without slots"); node->flags &= ~CLUSTER_NODE_FAIL; clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); @@ -1555,7 +1556,7 @@ void clearNodeFailureIfNeeded(clusterNode *node) { (server.cluster_node_timeout * CLUSTER_FAIL_UNDO_TIME_MULT)) { serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s : is reachable again and nobody is serving its slots after some time.", + "Clear FAIL state for node %.40s: is reachable again and nobody is serving its slots after some time.", node->name); node->flags &= ~CLUSTER_NODE_FAIL; clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); @@ -1677,7 +1678,7 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { if (clusterNodeAddFailureReport(node,sender)) { serverLog(LL_VERBOSE, "Node %.40s reported node %.40s as not reachable.", - sender->name, node->name); + sender->name, node->name); } markNodeAsFailingIfNeeded(node); } else { @@ -1940,7 +1941,7 @@ void clusterUpdateSlotsConfigWith(clusterNode *sender, uint64_t senderConfigEpoc sender_slots == migrated_our_slots)) { serverLog(LL_WARNING, "Configuration change detected. Reconfiguring myself " - "as a replica of %.40s ", sender->name); + "as a replica of %.40s", sender->name); clusterSetMaster(sender); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG| CLUSTER_TODO_UPDATE_STATE| @@ -2337,7 +2338,7 @@ int clusterProcessPacket(clusterLink *link) { * disconnect this node and set it as not having an associated * address. */ serverLog(LL_DEBUG,"PONG contains mismatching sender ID. About node %.40s added %d ms ago, having flags %d", - link->node->name, + link->node->name, (int)(now-(link->node->ctime)), link->node->flags); link->node->flags |= CLUSTER_NODE_NOADDR; @@ -3354,8 +3355,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * request, if the request epoch was greater. */ if (requestCurrentEpoch < server.cluster->currentEpoch) { serverLog(LL_WARNING, - "Failover auth denied to %.40s : reqEpoch (%llu) < curEpoch(%llu)", - node->name, + "Failover auth denied to %.40s: reqEpoch (%llu) < curEpoch(%llu)", + node->name, (unsigned long long) requestCurrentEpoch, (unsigned long long) server.cluster->currentEpoch); return; @@ -3364,8 +3365,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { /* I already voted for this epoch? Return ASAP. */ if (server.cluster->lastVoteEpoch == server.cluster->currentEpoch) { serverLog(LL_WARNING, - "Failover auth denied to %.40s : already voted for epoch %llu", - node->name, + "Failover auth denied to %.40s: already voted for epoch %llu", + node->name, (unsigned long long) server.cluster->currentEpoch); return; } @@ -3378,15 +3379,15 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { { if (nodeIsMaster(node)) { serverLog(LL_WARNING, - "Failover auth denied to %.40s : it is a master node", + "Failover auth denied to %.40s: it is a master node", node->name); } else if (master == NULL) { serverLog(LL_WARNING, - "Failover auth denied to %.40s : I don't know its master", + "Failover auth denied to %.40s: I don't know its master", node->name); } else if (!nodeFailed(master)) { serverLog(LL_WARNING, - "Failover auth denied to %.40s : its master is up", + "Failover auth denied to %.40s: its master is up", node->name); } return; @@ -3398,7 +3399,7 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { if (mstime() - node->slaveof->voted_time < server.cluster_node_timeout * 2) { serverLog(LL_WARNING, - "Failover auth denied to %.40s : " + "Failover auth denied to %.40s: " "can't vote about this master before %lld milliseconds", node->name, (long long) ((server.cluster_node_timeout*2)- @@ -3420,7 +3421,7 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * is served by a master with a greater configEpoch than the one claimed * by the slave requesting our vote. Refuse to vote for this slave. */ serverLog(LL_WARNING, - "Failover auth denied to %.40s : " + "Failover auth denied to %.40s: " "slot %d epoch (%llu) > reqEpoch (%llu)", node->name, j, (unsigned long long) server.cluster->slots[j]->configEpoch, @@ -3851,7 +3852,7 @@ void clusterHandleSlaveMigration(int max_slaves) { (mstime()-target->orphaned_time) > CLUSTER_SLAVE_MIGRATION_DELAY && !(server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_FAILOVER)) { - serverLog(LL_WARNING,"Migrating to orphaned master %.40s ", + serverLog(LL_WARNING,"Migrating to orphaned master %.40s", target->name); clusterSetMaster(target); } @@ -4047,6 +4048,7 @@ void clusterCron(void) { clusterUpdateMyselfHostname(); + updateAnnouncedNodename(myself, server.cluster_announce_nodename); /* The handshake timeout is the time after which a handshake node that was * not turned into a normal node is removed from the nodes. Usually it is * just the NODE_TIMEOUT value, but when NODE_TIMEOUT is too small we use @@ -4099,7 +4101,7 @@ void clusterCron(void) { } } if (min_pong_node) { - serverLog(LL_DEBUG,"Pinging node %.40s ", min_pong_node->name); + serverLog(LL_DEBUG,"Pinging node %.40s", min_pong_node->name); clusterSendPing(min_pong_node->link, CLUSTERMSG_TYPE_PING); } } @@ -4687,7 +4689,14 @@ sds clusterGenNodeDescription(clusterNode *node, int use_pport) { /* Node coordinates */ ci = sdscatlen(sdsempty(),node->name,CLUSTER_NAMELEN); - if (sdslen(node->hostname) != 0) { + if (sdslen(node->hostname) != 0 && node->nodename) { + ci = sdscatfmt(ci," %s:%i@%i,%s-%s ", + node->ip, + port, + node->cport, + node->hostname, + node->nodename); + } else if (sdslen(node->hostname) != 0) { ci = sdscatfmt(ci," %s:%i@%i,%s ", node->ip, port, @@ -4714,7 +4723,7 @@ sds clusterGenNodeDescription(clusterNode *node, int use_pport) { if (node->slaveof) ci = sdscatlen(ci,node->slaveof->name,CLUSTER_NAMELEN); else - ci = sdscatlen(ci,"-",1); + ci = sdscatlen(ci,"-",1); unsigned long long nodeEpoch = node->configEpoch; if (nodeIsSlave(node) && node->slaveof) { @@ -4919,6 +4928,7 @@ const char *getPreferredEndpoint(clusterNode *n) { switch(server.cluster_preferred_endpoint_type) { case CLUSTER_ENDPOINT_TYPE_IP: return n->ip; case CLUSTER_ENDPOINT_TYPE_HOSTNAME: return (sdslen(n->hostname) != 0) ? n->hostname : "?"; + case CLUSTER_ENDPOINT_TYPE_NODENAME: return n->nodename ? n->nodename : "?"; case CLUSTER_ENDPOINT_TYPE_UNKNOWN_ENDPOINT: return ""; } return "unknown"; @@ -5013,6 +5023,8 @@ void addNodeToNodeReply(client *c, clusterNode *node) { addReplyBulkCString(c, node->ip); } else if (server.cluster_preferred_endpoint_type == CLUSTER_ENDPOINT_TYPE_HOSTNAME) { addReplyBulkCString(c, sdslen(node->hostname) != 0 ? node->hostname : "?"); + } else if (server.cluster_preferred_endpoint_type == CLUSTER_ENDPOINT_TYPE_NODENAME) { + addReplyBulkCString(c, node->nodename ? node->nodename : "?"); } else if (server.cluster_preferred_endpoint_type == CLUSTER_ENDPOINT_TYPE_UNKNOWN_ENDPOINT) { addReplyNull(c); } else { diff --git a/src/cluster.h b/src/cluster.h index 475b4bf5ca8..9b0ec5e0c6e 100644 --- a/src/cluster.h +++ b/src/cluster.h @@ -136,6 +136,7 @@ typedef struct clusterNode { long long repl_offset; /* Last known repl offset for this node. */ char ip[NET_IP_STR_LEN]; /* Latest known IP address of this node */ sds hostname; /* The known hostname for this node */ + char *nodename; /* The known human readable nodename for this node */ int port; /* Latest known clients port (TLS or plain). */ int pport; /* Latest known clients plaintext port. Only used if the main clients port is for TLS. */ From 85abd358056ff0d882da756aad315117527600c1 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Thu, 24 Feb 2022 09:59:15 -0500 Subject: [PATCH 75/79] Update cluster.c Fix indentation --- src/cluster.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cluster.c b/src/cluster.c index 2b3f1a3edab..d26706265c6 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -3663,7 +3663,7 @@ void clusterHandleSlaveFailover(void) { if (server.cluster->mf_end) { server.cluster->failover_auth_time = mstime(); server.cluster->failover_auth_rank = 0; - clusterDoBeforeSleep(CLUSTER_TODO_HANDLE_FAILOVER); + clusterDoBeforeSleep(CLUSTER_TODO_HANDLE_FAILOVER); } serverLog(LL_WARNING, "Start of election delayed for %lld milliseconds " From 943aaa2c3eefc9651afbb70e153fbff3a0894521 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Thu, 24 Feb 2022 16:11:36 -0500 Subject: [PATCH 76/79] Cluster nodename feature add sds option (#67) * Add sds option --- redis.conf | 4 ++ src/cluster.c | 190 +++++++++++++++++++++++++------------------------- src/cluster.h | 2 +- 3 files changed, 100 insertions(+), 96 deletions(-) diff --git a/redis.conf b/redis.conf index 1b8a62b6025..de1d322834f 100644 --- a/redis.conf +++ b/redis.conf @@ -1684,6 +1684,10 @@ aof-timestamp-enabled no # # cluster-announce-hostname "" +# Clusters can configure their announced nodename using this config. The nodename can be a human-readable name +# which will be exposed in places like info and logging for debugging purposes. +# cluster-announce-nodename "" + # Clusters can advertise how clients should connect to them using either their IP address, # a user defined hostname, or by declaring they have no endpoint. Which endpoint is # shown as the preferred endpoint is set by using the cluster-preferred-endpoint-type diff --git a/src/cluster.c b/src/cluster.c index d26706265c6..bd9e9eab6e6 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -255,19 +255,9 @@ int clusterLoadConfig(char *filename) { *nodename = '\0'; nodename++; zfree(n->nodename); - n->nodename = zstrdup(nodename); - } else { - n->nodename = NULL; - } - /* Nodename is an optional argument */ - char *nodename = strchr(p, '-'); - if (nodename) { - *nodename = '\0'; - nodename++; - zfree(n->nodename); - n->nodename = zstrdup(nodename); - } else { - n->nodename = NULL; + n->nodename = sdscpy(n->nodename, nodename); + } else if (sdslen(n->nodename) != 0) { + sdsclear(n->nodename); } /* The plaintext port for client in a TLS cluster (n->pport) is not @@ -605,20 +595,15 @@ static void updateAnnouncedHostname(clusterNode *node, char *new) { /* Update the nodename for the specified node with the provided C string. */ static void updateAnnouncedNodename(clusterNode *node, char *new) { - if (!node->nodename && !new) { - return; - } - /* Previous and new nodename are the same, no need to update. */ - if (new && node->nodename && !strcmp(new, node->nodename)) { + if (new && !strcmp(new, node->nodename)) { return; } - if (node->nodename) zfree(node->nodename); if (new) { - node->nodename = zstrdup(new); - } else { - node->nodename = NULL; + node->nodename = sdscpy(node->nodename, new); + } else if (sdslen(node->nodename) != 0) { + sdsclear(node->nodename); } } @@ -1001,7 +986,7 @@ clusterNode *createClusterNode(char *nodename, int flags) { node->inbound_link = NULL; memset(node->ip,0,sizeof(node->ip)); node->hostname = sdsempty(); - node->nodename = NULL; + node->nodename = sdsempty(); node->port = 0; node->cport = 0; node->pport = 0; @@ -1168,7 +1153,7 @@ void freeClusterNode(clusterNode *n) { serverAssert(dictDelete(server.cluster->nodes,nodename) == DICT_OK); sdsfree(nodename); sdsfree(n->hostname); - zfree(n->nodename); + sdsfree(n->nodename); /* Release links and associated data structures. */ if (n->link) freeClusterLink(n->link); @@ -1394,9 +1379,9 @@ void clusterHandleConfigEpochCollision(clusterNode *sender) { myself->configEpoch = server.cluster->currentEpoch; clusterSaveConfigOrDie(1); serverLog(LL_VERBOSE, - "WARNING: configEpoch collision with node %.40s." + "WARNING: configEpoch collision with node %.40s %s." " configEpoch set to %llu", - sender->name, + sender->name, sender->nodename, (unsigned long long) myself->configEpoch); } @@ -1512,7 +1497,7 @@ void markNodeAsFailingIfNeeded(clusterNode *node) { if (failures < needed_quorum) return; /* No weak agreement from masters. */ serverLog(LL_NOTICE, - "Marking node %.40s as failing (quorum reached).", node->name); + "Marking node %.40s %s as failing (quorum reached).", node->name, node->nodename); /* Mark the node as failing. */ node->flags &= ~CLUSTER_NODE_PFAIL; @@ -1540,8 +1525,8 @@ void clearNodeFailureIfNeeded(clusterNode *node) { * node again. */ if (nodeIsSlave(node) || node->numslots == 0) { serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s: %s is reachable again.", - node->name, + "Clear FAIL state for node %.40s %s: %s is reachable again.", + node->name, node->nodename, nodeIsSlave(node) ? "replica" : "master without slots"); node->flags &= ~CLUSTER_NODE_FAIL; clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); @@ -1556,8 +1541,8 @@ void clearNodeFailureIfNeeded(clusterNode *node) { (server.cluster_node_timeout * CLUSTER_FAIL_UNDO_TIME_MULT)) { serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s: is reachable again and nobody is serving its slots after some time.", - node->name); + "Clear FAIL state for node %.40s %s: is reachable again and nobody is serving its slots after some time.", + node->name, node->nodename); node->flags &= ~CLUSTER_NODE_FAIL; clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); } @@ -1677,15 +1662,17 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { if (flags & (CLUSTER_NODE_FAIL|CLUSTER_NODE_PFAIL)) { if (clusterNodeAddFailureReport(node,sender)) { serverLog(LL_VERBOSE, - "Node %.40s reported node %.40s as not reachable.", - sender->name, node->name); + "Node %.40s %s reported node %.40s %s as not reachable.", + sender->name, sender->nodename, + node->name, node->nodename); } markNodeAsFailingIfNeeded(node); } else { if (clusterNodeDelFailureReport(node,sender)) { serverLog(LL_VERBOSE, - "Node %.40s reported node %.40s is back online.", - sender->name, node->name); + "Node %.40s %s reported node %.40s %s is back online.", + sender->name, sender->nodename, + node->name, node->nodename); } } } @@ -2002,7 +1989,7 @@ int getHostnamePingExtSize() { * will be 8 byte padded. */ int getNodenamePingExtSize() { /* If nodename is not set, we don't send this extension */ - if (!myself->nodename) return 0; + if (sdslen(myself->nodename) == 0) return 0; int totlen = sizeof(clusterMsgPingExt) + EIGHT_BYTE_ALIGN(strlen(myself->nodename) + 1); return totlen; @@ -2033,19 +2020,18 @@ int writeHostnamePingExt(clusterMsgPingExt **cursor) { * will return the amount of bytes written. */ int writeNodenamePingExt(clusterMsgPingExt **cursor) { /* If nodename is not set, we don't send this extension */ - if (!myself->nodename) return 0; + if (sdslen(myself->nodename) == 0) return 0; /* Add the nodename information at the extension cursor */ - clusterMsgPingExtNodename *ext = &(*cursor)->ext[1].nodename; - size_t nodename_len = strlen(myself->nodename); - memcpy(ext->nodename, myself->nodename, nodename_len); + clusterMsgPingExtNodename *ext = &(*cursor)->ext[0].nodename; + memcpy(ext->nodename, myself->nodename, sdslen(myself->nodename)); uint32_t extension_size = getNodenamePingExtSize(); /* Move the write cursor */ (*cursor)->type = CLUSTERMSG_EXT_TYPE_NODENAME; (*cursor)->length = htonl(extension_size); /* Make sure the string is NULL terminated by adding 1 */ - *cursor = (clusterMsgPingExt *) (ext->nodename + EIGHT_BYTE_ALIGN(strlen(myself->nodename) + 1)); + *cursor = (clusterMsgPingExt *) (ext->nodename + EIGHT_BYTE_ALIGN(sdslen(myself->nodename) + 1)); return extension_size; } @@ -2309,8 +2295,8 @@ int clusterProcessPacket(clusterLink *link) { * IP/port of the node with the new one. */ if (sender) { serverLog(LL_VERBOSE, - "Handshake: we already know node %.40s, " - "updating the address if needed.", sender->name); + "Handshake: we already know node %.40s %s, " + "updating the address if needed.", sender->name, sender->nodename); if (nodeUpdateAddressIfNeeded(sender,link,hdr)) { @@ -2337,8 +2323,9 @@ int clusterProcessPacket(clusterLink *link) { /* If the reply has a non matching node ID we * disconnect this node and set it as not having an associated * address. */ - serverLog(LL_DEBUG,"PONG contains mismatching sender ID. About node %.40s added %d ms ago, having flags %d", + serverLog(LL_DEBUG,"PONG contains mismatching sender ID. About node %.40s %s added %d ms ago, having flags %d", link->node->name, + link->node->nodename, (int)(now-(link->node->ctime)), link->node->flags); link->node->flags |= CLUSTER_NODE_NOADDR; @@ -2485,8 +2472,9 @@ int clusterProcessPacket(clusterLink *link) { { serverLog(LL_VERBOSE, "Node %.40s has old slots configuration, sending " - "an UPDATE message about %.40s ", - sender->name, server.cluster->slots[j]->name); + "an UPDATE message about %.40s %s", + sender->name, server.cluster->slots[j]->name, + sender->nodename); clusterSendUpdate(sender->link, server.cluster->slots[j]); @@ -2522,8 +2510,8 @@ int clusterProcessPacket(clusterLink *link) { !(failing->flags & (CLUSTER_NODE_FAIL|CLUSTER_NODE_MYSELF))) { serverLog(LL_NOTICE, - "FAIL message received from %.40s about %.40s", - hdr->sender, hdr->data.fail.about.nodename); + "FAIL message received from %.40s about %.40s %s", + hdr->sender, hdr->data.fail.about.nodename, failing->nodename); failing->flags |= CLUSTER_NODE_FAIL; failing->fail_time = now; failing->flags &= ~CLUSTER_NODE_PFAIL; @@ -2674,8 +2662,8 @@ void clusterLinkConnectHandler(connection *conn) { /* Check if connection succeeded */ if (connGetState(conn) != CONN_STATE_CONNECTED) { - serverLog(LL_VERBOSE, "Connection with Node %.40s at %s:%d failed: %s", - node->name, node->ip, node->cport, + serverLog(LL_VERBOSE, "Connection with Node %.40s %s at %s:%d failed: %s", + node->name, node->nodename, node->ip, node->cport, connGetLastError(conn)); freeClusterLink(link); return; @@ -3062,7 +3050,7 @@ void clusterSendPing(clusterLink *link, int type) { extensions++; } - if (myself->nodename) { + if (sdslen(myself->nodename) != 0) { hdr->mflags[0] |= CLUSTERMSG_FLAG0_EXT_DATA; totlen += writeNodenamePingExt(&cursor); extensions++; @@ -3355,8 +3343,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * request, if the request epoch was greater. */ if (requestCurrentEpoch < server.cluster->currentEpoch) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: reqEpoch (%llu) < curEpoch(%llu)", - node->name, + "Failover auth denied to %.40s %s: reqEpoch (%llu) < curEpoch(%llu)", + node->name, node->nodename, (unsigned long long) requestCurrentEpoch, (unsigned long long) server.cluster->currentEpoch); return; @@ -3365,8 +3353,8 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { /* I already voted for this epoch? Return ASAP. */ if (server.cluster->lastVoteEpoch == server.cluster->currentEpoch) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: already voted for epoch %llu", - node->name, + "Failover auth denied to %.40s %s: already voted for epoch %llu", + node->name, node->nodename, (unsigned long long) server.cluster->currentEpoch); return; } @@ -3379,16 +3367,16 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { { if (nodeIsMaster(node)) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: it is a master node", - node->name); + "Failover auth denied to %.40s %s: it is a master node", + node->name, node->nodename); } else if (master == NULL) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: I don't know its master", - node->name); + "Failover auth denied to %.40s %s: I don't know its master", + node->name, node->nodename); } else if (!nodeFailed(master)) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: its master is up", - node->name); + "Failover auth denied to %.40s %s: its master is up", + node->name, node->nodename); } return; } @@ -3399,9 +3387,9 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { if (mstime() - node->slaveof->voted_time < server.cluster_node_timeout * 2) { serverLog(LL_WARNING, - "Failover auth denied to %.40s: " + "Failover auth denied to %.40s %s: " "can't vote about this master before %lld milliseconds", - node->name, + node->name, node->nodename, (long long) ((server.cluster_node_timeout*2)- (mstime() - node->slaveof->voted_time))); return; @@ -3421,9 +3409,9 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * is served by a master with a greater configEpoch than the one claimed * by the slave requesting our vote. Refuse to vote for this slave. */ serverLog(LL_WARNING, - "Failover auth denied to %.40s: " + "Failover auth denied to %.40s %s: " "slot %d epoch (%llu) > reqEpoch (%llu)", - node->name, j, + node->name, node->nodename, j, (unsigned long long) server.cluster->slots[j]->configEpoch, (unsigned long long) requestConfigEpoch); return; @@ -4047,8 +4035,8 @@ void clusterCron(void) { iteration++; /* Number of times this function was called so far. */ clusterUpdateMyselfHostname(); + clusterUpdateMyselfNodename(); - updateAnnouncedNodename(myself, server.cluster_announce_nodename); /* The handshake timeout is the time after which a handshake node that was * not turned into a normal node is removed from the nodes. Usually it is * just the NODE_TIMEOUT value, but when NODE_TIMEOUT is too small we use @@ -4201,8 +4189,8 @@ void clusterCron(void) { /* Timeout reached. Set the node as possibly failing if it is * not already in this state. */ if (!(node->flags & (CLUSTER_NODE_PFAIL|CLUSTER_NODE_FAIL))) { - serverLog(LL_DEBUG,"*** NODE %.40s possibly failing", - node->name); + serverLog(LL_DEBUG,"*** NODE %.40s %s possibly failing", + node->name, node->nodename); node->flags |= CLUSTER_NODE_PFAIL; update_state = 1; } @@ -4689,31 +4677,43 @@ sds clusterGenNodeDescription(clusterNode *node, int use_pport) { /* Node coordinates */ ci = sdscatlen(sdsempty(),node->name,CLUSTER_NAMELEN); - if (sdslen(node->hostname) != 0 && node->nodename) { - ci = sdscatfmt(ci," %s:%i@%i,%s-%s ", - node->ip, - port, - node->cport, - node->hostname, - node->nodename); - } else if (sdslen(node->hostname) != 0) { - ci = sdscatfmt(ci," %s:%i@%i,%s ", - node->ip, - port, - node->cport, - node->hostname); - } else if (node->nodename) { - ci = sdscatfmt(ci," %s:%i@%i-%s ", - node->ip, - port, - node->cport, - node->nodename); - } else { - ci = sdscatfmt(ci," %s:%i@%i ", - node->ip, - port, - node->cport); + ci = sdscatfmt(ci," %s:%i@%i", + node->ip, + port, + node->cport); + if (sdslen(node->hostname) != 0) { + ci = sdscatfmt(ci,",%s", node->hostname); + } + if (sdslen(node->nodename) != 0) { + ci = sdscatfmt(ci,"-%s", node->nodename); } + ci = sdscatlen(ci," ",1); + + // if (sdslen(node->hostname) != 0 && sdslen(node->nodename) != 0) { + // ci = sdscatfmt(ci," %s:%i@%i,%s-%s ", + // node->ip, + // port, + // node->cport, + // node->hostname, + // node->nodename); + // } else if (sdslen(node->hostname) != 0) { + // ci = sdscatfmt(ci," %s:%i@%i,%s ", + // node->ip, + // port, + // node->cport, + // node->hostname); + // } else if (sdslen(node->nodename) != 0) { + // ci = sdscatfmt(ci," %s:%i@%i-%s ", + // node->ip, + // port, + // node->cport, + // node->nodename); + // } else { + // ci = sdscatfmt(ci," %s:%i@%i ", + // node->ip, + // port, + // node->cport); + // } /* Flags */ ci = representClusterNodeFlags(ci, node->flags); @@ -4928,7 +4928,7 @@ const char *getPreferredEndpoint(clusterNode *n) { switch(server.cluster_preferred_endpoint_type) { case CLUSTER_ENDPOINT_TYPE_IP: return n->ip; case CLUSTER_ENDPOINT_TYPE_HOSTNAME: return (sdslen(n->hostname) != 0) ? n->hostname : "?"; - case CLUSTER_ENDPOINT_TYPE_NODENAME: return n->nodename ? n->nodename : "?"; + case CLUSTER_ENDPOINT_TYPE_NODENAME: return (sdslen(n->nodename) != 0) ? n->nodename : "?"; case CLUSTER_ENDPOINT_TYPE_UNKNOWN_ENDPOINT: return ""; } return "unknown"; @@ -5024,7 +5024,7 @@ void addNodeToNodeReply(client *c, clusterNode *node) { } else if (server.cluster_preferred_endpoint_type == CLUSTER_ENDPOINT_TYPE_HOSTNAME) { addReplyBulkCString(c, sdslen(node->hostname) != 0 ? node->hostname : "?"); } else if (server.cluster_preferred_endpoint_type == CLUSTER_ENDPOINT_TYPE_NODENAME) { - addReplyBulkCString(c, node->nodename ? node->nodename : "?"); + addReplyBulkCString(c, sdslen(node->nodename) != 0 ? node->nodename : "?"); } else if (server.cluster_preferred_endpoint_type == CLUSTER_ENDPOINT_TYPE_UNKNOWN_ENDPOINT) { addReplyNull(c); } else { @@ -5054,7 +5054,7 @@ void addNodeToNodeReply(client *c, clusterNode *node) { length++; } if (server.cluster_preferred_endpoint_type != CLUSTER_ENDPOINT_TYPE_NODENAME - && node->nodename) + && sdslen(node->nodename) != 0) { addReplyBulkCString(c, "nodename"); addReplyBulkCString(c, node->nodename); diff --git a/src/cluster.h b/src/cluster.h index 9b0ec5e0c6e..fd251180f5e 100644 --- a/src/cluster.h +++ b/src/cluster.h @@ -136,7 +136,7 @@ typedef struct clusterNode { long long repl_offset; /* Last known repl offset for this node. */ char ip[NET_IP_STR_LEN]; /* Latest known IP address of this node */ sds hostname; /* The known hostname for this node */ - char *nodename; /* The known human readable nodename for this node */ + sds nodename; /* The known human readable nodename for this node */ int port; /* Latest known clients port (TLS or plain). */ int pport; /* Latest known clients plaintext port. Only used if the main clients port is for TLS. */ From 799846a93108171234ed4adb75ba588a887f48d8 Mon Sep 17 00:00:00 2001 From: Wen Hui Date: Fri, 25 Feb 2022 16:15:43 -0500 Subject: [PATCH 77/79] Cluster nodename feature rebase (#68) Update code according to comments --- src/cluster.c | 36 ------------------------------------ src/cluster.h | 2 +- src/config.c | 1 - src/server.h | 1 - 4 files changed, 1 insertion(+), 39 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index bd9e9eab6e6..9f4beaa482b 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -4689,32 +4689,6 @@ sds clusterGenNodeDescription(clusterNode *node, int use_pport) { } ci = sdscatlen(ci," ",1); - // if (sdslen(node->hostname) != 0 && sdslen(node->nodename) != 0) { - // ci = sdscatfmt(ci," %s:%i@%i,%s-%s ", - // node->ip, - // port, - // node->cport, - // node->hostname, - // node->nodename); - // } else if (sdslen(node->hostname) != 0) { - // ci = sdscatfmt(ci," %s:%i@%i,%s ", - // node->ip, - // port, - // node->cport, - // node->hostname); - // } else if (sdslen(node->nodename) != 0) { - // ci = sdscatfmt(ci," %s:%i@%i-%s ", - // node->ip, - // port, - // node->cport, - // node->nodename); - // } else { - // ci = sdscatfmt(ci," %s:%i@%i ", - // node->ip, - // port, - // node->cport); - // } - /* Flags */ ci = representClusterNodeFlags(ci, node->flags); @@ -4928,7 +4902,6 @@ const char *getPreferredEndpoint(clusterNode *n) { switch(server.cluster_preferred_endpoint_type) { case CLUSTER_ENDPOINT_TYPE_IP: return n->ip; case CLUSTER_ENDPOINT_TYPE_HOSTNAME: return (sdslen(n->hostname) != 0) ? n->hostname : "?"; - case CLUSTER_ENDPOINT_TYPE_NODENAME: return (sdslen(n->nodename) != 0) ? n->nodename : "?"; case CLUSTER_ENDPOINT_TYPE_UNKNOWN_ENDPOINT: return ""; } return "unknown"; @@ -5023,8 +4996,6 @@ void addNodeToNodeReply(client *c, clusterNode *node) { addReplyBulkCString(c, node->ip); } else if (server.cluster_preferred_endpoint_type == CLUSTER_ENDPOINT_TYPE_HOSTNAME) { addReplyBulkCString(c, sdslen(node->hostname) != 0 ? node->hostname : "?"); - } else if (server.cluster_preferred_endpoint_type == CLUSTER_ENDPOINT_TYPE_NODENAME) { - addReplyBulkCString(c, sdslen(node->nodename) != 0 ? node->nodename : "?"); } else if (server.cluster_preferred_endpoint_type == CLUSTER_ENDPOINT_TYPE_UNKNOWN_ENDPOINT) { addReplyNull(c); } else { @@ -5053,13 +5024,6 @@ void addNodeToNodeReply(client *c, clusterNode *node) { addReplyBulkCString(c, node->hostname); length++; } - if (server.cluster_preferred_endpoint_type != CLUSTER_ENDPOINT_TYPE_NODENAME - && sdslen(node->nodename) != 0) - { - addReplyBulkCString(c, "nodename"); - addReplyBulkCString(c, node->nodename); - length++; - } setDeferredMapLen(c, deflen, length); } diff --git a/src/cluster.h b/src/cluster.h index fd251180f5e..1eb32e76ca3 100644 --- a/src/cluster.h +++ b/src/cluster.h @@ -136,7 +136,7 @@ typedef struct clusterNode { long long repl_offset; /* Last known repl offset for this node. */ char ip[NET_IP_STR_LEN]; /* Latest known IP address of this node */ sds hostname; /* The known hostname for this node */ - sds nodename; /* The known human readable nodename for this node */ + sds nodename; /* The known human readable nodename for this node */ int port; /* Latest known clients port (TLS or plain). */ int pport; /* Latest known clients plaintext port. Only used if the main clients port is for TLS. */ diff --git a/src/config.c b/src/config.c index 1863bf13139..6034321b95f 100644 --- a/src/config.c +++ b/src/config.c @@ -144,7 +144,6 @@ configEnum protected_action_enum[] = { configEnum cluster_preferred_endpoint_type_enum[] = { {"ip", CLUSTER_ENDPOINT_TYPE_IP}, {"hostname", CLUSTER_ENDPOINT_TYPE_HOSTNAME}, - {"nodename", CLUSTER_ENDPOINT_TYPE_NODENAME}, {"unknown-endpoint", CLUSTER_ENDPOINT_TYPE_UNKNOWN_ENDPOINT}, {NULL, 0} }; diff --git a/src/server.h b/src/server.h index 031a2e65df1..f3b7d545e04 100644 --- a/src/server.h +++ b/src/server.h @@ -581,7 +581,6 @@ typedef struct { typedef enum { CLUSTER_ENDPOINT_TYPE_IP = 0, /* Show IP address */ CLUSTER_ENDPOINT_TYPE_HOSTNAME, /* Show hostname */ - CLUSTER_ENDPOINT_TYPE_NODENAME, /* Show nodename */ CLUSTER_ENDPOINT_TYPE_UNKNOWN_ENDPOINT /* Show NULL or empty */ } cluster_endpoint_type; From 63940d0604620d4c0c60e4af464cb70047d0ad05 Mon Sep 17 00:00:00 2001 From: hwware Date: Thu, 24 Mar 2022 20:46:47 +0000 Subject: [PATCH 78/79] Rebase --- src/cluster.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index 27f6a128b27..c3e7deb1569 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -244,20 +244,9 @@ int clusterLoadConfig(char *filename) { if (hostname) { *hostname = '\0'; hostname++; - zfree(n->hostname); - n->hostname = zstrdup(hostname); - } else { - n->hostname = NULL; - } - /* Nodename is an optional argument */ - char *nodename = strchr(p, '-'); - if (nodename) { - *nodename = '\0'; - nodename++; - zfree(n->nodename); - n->nodename = sdscpy(n->nodename, nodename); - } else if (sdslen(n->nodename) != 0) { - sdsclear(n->nodename); + n->hostname = sdscpy(n->hostname, hostname); + } else if (sdslen(n->hostname) != 0) { + sdsclear(n->hostname); } /* Nodename is an optional argument */ char *nodename = strchr(p, '-'); From 239a78ffa35de74ece18cb8f4dc01ec5960bd46d Mon Sep 17 00:00:00 2001 From: hwware Date: Wed, 13 Apr 2022 19:45:16 +0000 Subject: [PATCH 79/79] Add tests and change lof format --- src/cluster.c | 44 ++++++++++++++-------------- tests/cluster/cluster.tcl | 11 +++++++ tests/cluster/tests/27-endpoints.tcl | 37 +++++++++++++++++++++++ 3 files changed, 70 insertions(+), 22 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index c3e7deb1569..ebc9724e2b8 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -1378,7 +1378,7 @@ void clusterHandleConfigEpochCollision(clusterNode *sender) { myself->configEpoch = server.cluster->currentEpoch; clusterSaveConfigOrDie(1); serverLog(LL_VERBOSE, - "WARNING: configEpoch collision with node %.40s %s." + "WARNING: configEpoch collision with node %.40s (%s)." " configEpoch set to %llu", sender->name, sender->nodename, (unsigned long long) myself->configEpoch); @@ -1496,7 +1496,7 @@ void markNodeAsFailingIfNeeded(clusterNode *node) { if (failures < needed_quorum) return; /* No weak agreement from masters. */ serverLog(LL_NOTICE, - "Marking node %.40s %s as failing (quorum reached).", node->name, node->nodename); + "Marking node %.40s (%s) as failing (quorum reached).", node->name, node->nodename); /* Mark the node as failing. */ node->flags &= ~CLUSTER_NODE_PFAIL; @@ -1524,7 +1524,7 @@ void clearNodeFailureIfNeeded(clusterNode *node) { * node again. */ if (nodeIsSlave(node) || node->numslots == 0) { serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s %s: %s is reachable again.", + "Clear FAIL state for node %.40s (%s): %s is reachable again.", node->name, node->nodename, nodeIsSlave(node) ? "replica" : "master without slots"); node->flags &= ~CLUSTER_NODE_FAIL; @@ -1540,7 +1540,7 @@ void clearNodeFailureIfNeeded(clusterNode *node) { (server.cluster_node_timeout * CLUSTER_FAIL_UNDO_TIME_MULT)) { serverLog(LL_NOTICE, - "Clear FAIL state for node %.40s %s: is reachable again and nobody is serving its slots after some time.", + "Clear FAIL state for node %.40s (%s): is reachable again and nobody is serving its slots after some time.", node->name, node->nodename); node->flags &= ~CLUSTER_NODE_FAIL; clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); @@ -1661,7 +1661,7 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { if (flags & (CLUSTER_NODE_FAIL|CLUSTER_NODE_PFAIL)) { if (clusterNodeAddFailureReport(node,sender)) { serverLog(LL_VERBOSE, - "Node %.40s %s reported node %.40s %s as not reachable.", + "Node %.40s (%s) reported node %.40s (%s) as not reachable.", sender->name, sender->nodename, node->name, node->nodename); } @@ -1669,7 +1669,7 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { } else { if (clusterNodeDelFailureReport(node,sender)) { serverLog(LL_VERBOSE, - "Node %.40s %s reported node %.40s %s is back online.", + "Node %.40s (%s) reported node %.40s (%s) is back online.", sender->name, sender->nodename, node->name, node->nodename); } @@ -1797,8 +1797,8 @@ int nodeUpdateAddressIfNeeded(clusterNode *node, clusterLink *link, node->cport = cport; if (node->link) freeClusterLink(node->link); node->flags &= ~CLUSTER_NODE_NOADDR; - serverLog(LL_WARNING,"Address updated for node %.40s , now %s:%d", - node->name, node->ip, node->port); + serverLog(LL_WARNING,"Address updated for node %.40s (%s), now %s:%d", + node->name, node->nodename, node->ip, node->port); /* Check if this is our master and we have to change the * replication target as well. */ @@ -1990,7 +1990,7 @@ int getNodenamePingExtSize() { /* If nodename is not set, we don't send this extension */ if (sdslen(myself->nodename) == 0) return 0; - int totlen = sizeof(clusterMsgPingExt) + EIGHT_BYTE_ALIGN(strlen(myself->nodename) + 1); + int totlen = sizeof(clusterMsgPingExt) + EIGHT_BYTE_ALIGN(sdslen(myself->nodename) + 1); return totlen; } @@ -2294,7 +2294,7 @@ int clusterProcessPacket(clusterLink *link) { * IP/port of the node with the new one. */ if (sender) { serverLog(LL_VERBOSE, - "Handshake: we already know node %.40s %s, " + "Handshake: we already know node %.40s (%s), " "updating the address if needed.", sender->name, sender->nodename); if (nodeUpdateAddressIfNeeded(sender,link,hdr)) @@ -2322,7 +2322,7 @@ int clusterProcessPacket(clusterLink *link) { /* If the reply has a non matching node ID we * disconnect this node and set it as not having an associated * address. */ - serverLog(LL_DEBUG,"PONG contains mismatching sender ID. About node %.40s %s added %d ms ago, having flags %d", + serverLog(LL_DEBUG,"PONG contains mismatching sender ID. About node %.40s (%s) added %d ms ago, having flags %d", link->node->name, link->node->nodename, (int)(now-(link->node->ctime)), @@ -2471,7 +2471,7 @@ int clusterProcessPacket(clusterLink *link) { { serverLog(LL_VERBOSE, "Node %.40s has old slots configuration, sending " - "an UPDATE message about %.40s %s", + "an UPDATE message about %.40s (%s)", sender->name, server.cluster->slots[j]->name, sender->nodename); clusterSendUpdate(sender->link, @@ -2509,7 +2509,7 @@ int clusterProcessPacket(clusterLink *link) { !(failing->flags & (CLUSTER_NODE_FAIL|CLUSTER_NODE_MYSELF))) { serverLog(LL_NOTICE, - "FAIL message received from %.40s about %.40s %s", + "FAIL message received from %.40s about %.40s (%s)", hdr->sender, hdr->data.fail.about.nodename, failing->nodename); failing->flags |= CLUSTER_NODE_FAIL; failing->fail_time = now; @@ -2661,7 +2661,7 @@ void clusterLinkConnectHandler(connection *conn) { /* Check if connection succeeded */ if (connGetState(conn) != CONN_STATE_CONNECTED) { - serverLog(LL_VERBOSE, "Connection with Node %.40s %s at %s:%d failed: %s", + serverLog(LL_VERBOSE, "Connection with Node %.40s (%s) at %s:%d failed: %s", node->name, node->nodename, node->ip, node->cport, connGetLastError(conn)); freeClusterLink(link); @@ -3342,7 +3342,7 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * request, if the request epoch was greater. */ if (requestCurrentEpoch < server.cluster->currentEpoch) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: reqEpoch (%llu) < curEpoch(%llu)", + "Failover auth denied to %.40s (%s): reqEpoch (%llu) < curEpoch(%llu)", node->name, node->nodename, (unsigned long long) requestCurrentEpoch, (unsigned long long) server.cluster->currentEpoch); @@ -3352,7 +3352,7 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { /* I already voted for this epoch? Return ASAP. */ if (server.cluster->lastVoteEpoch == server.cluster->currentEpoch) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: already voted for epoch %llu", + "Failover auth denied to %.40s (%s): already voted for epoch %llu", node->name, node->nodename, (unsigned long long) server.cluster->currentEpoch); return; @@ -3366,15 +3366,15 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { { if (nodeIsMaster(node)) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: it is a master node", + "Failover auth denied to %.40s (%s): it is a master node", node->name, node->nodename); } else if (master == NULL) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: I don't know its master", + "Failover auth denied to %.40s (%s): I don't know its master", node->name, node->nodename); } else if (!nodeFailed(master)) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: its master is up", + "Failover auth denied to %.40s (%s): its master is up", node->name, node->nodename); } return; @@ -3386,7 +3386,7 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { if (mstime() - node->slaveof->voted_time < server.cluster_node_timeout * 2) { serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: " + "Failover auth denied to %.40s (%s): " "can't vote about this master before %lld milliseconds", node->name, node->nodename, (long long) ((server.cluster_node_timeout*2)- @@ -3408,7 +3408,7 @@ void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { * is served by a master with a greater configEpoch than the one claimed * by the slave requesting our vote. Refuse to vote for this slave. */ serverLog(LL_WARNING, - "Failover auth denied to %.40s %s: " + "Failover auth denied to %.40s (%s): " "slot %d epoch (%llu) > reqEpoch (%llu)", node->name, node->nodename, j, (unsigned long long) server.cluster->slots[j]->configEpoch, @@ -4188,7 +4188,7 @@ void clusterCron(void) { /* Timeout reached. Set the node as possibly failing if it is * not already in this state. */ if (!(node->flags & (CLUSTER_NODE_PFAIL|CLUSTER_NODE_FAIL))) { - serverLog(LL_DEBUG,"*** NODE %.40s %s possibly failing", + serverLog(LL_DEBUG,"*** NODE %.40s (%s) possibly failing", node->name, node->nodename); node->flags |= CLUSTER_NODE_PFAIL; update_state = 1; diff --git a/tests/cluster/cluster.tcl b/tests/cluster/cluster.tcl index 9c669e12854..a2b0c287588 100644 --- a/tests/cluster/cluster.tcl +++ b/tests/cluster/cluster.tcl @@ -218,6 +218,17 @@ proc are_hostnames_propagated {match_string} { return 1 } +# Check if cluster's view of nodename is consistent +proc are_nodenames_propagated {match_string} { + for {set j 0} {$j < $::cluster_master_nodes + $::cluster_replica_nodes} {incr j} { + set cfg [R $j cluster nodes] + if {! [string match $match_string $cfg]} { + return 0 + } + return 1 + } +} + # Returns a parsed CLUSTER LINKS output of the instance identified # by the given `id` as a list of dictionaries, with each dictionary # corresponds to a link. diff --git a/tests/cluster/tests/27-endpoints.tcl b/tests/cluster/tests/27-endpoints.tcl index 32e3e794db9..c5a8a261c8f 100644 --- a/tests/cluster/tests/27-endpoints.tcl +++ b/tests/cluster/tests/27-endpoints.tcl @@ -40,6 +40,21 @@ test "Set cluster hostnames and verify they are propagated" { wait_for_cluster_propagation } +test "Set cluster nodenames and verify they are propagated" { + for {set j 0} {$j < $::cluster_master_nodes + $::cluster_replica_nodes} {incr j} { + R $j config set cluster-announce-nodename "node-$j.com" + } + + wait_for_condition 50 100 { + [are_nodenames_propagated "*node-*.com*"] eq 1 + } else { + fail "cluster nodenames were not propagated" + } + + # Now that everything is propagated, assert everyone agrees + wait_for_cluster_propagation +} + test "Update hostnames and make sure they are all eventually propagated" { for {set j 0} {$j < $::cluster_master_nodes + $::cluster_replica_nodes} {incr j} { R $j config set cluster-announce-hostname "host-updated-$j.com" @@ -55,6 +70,21 @@ test "Update hostnames and make sure they are all eventually propagated" { wait_for_cluster_propagation } +test "Update nodenames and make sure they are all eventually propagated" { + for {set j 0} {$j < $::cluster_master_nodes + $::cluster_replica_nodes} {incr j} { + R $j config set cluster-announce-nodename "node-updated-$j.com" + } + + wait_for_condition 50 100 { + [are_nodenames_propagated "*node-updated-*.com*"] eq 1 + } else { + fail "cluster nodenames were not propagated" + } + + # Now that everything is propagated, assert everyone agrees + wait_for_cluster_propagation +} + test "Remove hostnames and make sure they are all eventually propagated" { for {set j 0} {$j < $::cluster_master_nodes + $::cluster_replica_nodes} {incr j} { R $j config set cluster-announce-hostname "" @@ -216,4 +246,11 @@ test "Test hostname validation" { # Note this isn't a valid hostname, but it passes our internal validation R 0 config set cluster-announce-hostname "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-." +} + +test "Test nodename validation" { + catch {R 0 config set cluster-announce-nodename [string repeat x 256]} err + assert_match "*must be less than 256 characters*" $err + catch {R 0 config set cluster-announce-nodename "?.com"} err + assert_match "*may only contain alphanumeric characters, hyphens or dots*" $err } \ No newline at end of file