| 4472 | } |
| 4473 | |
| 4474 | static list *clusterManagerGetDisconnectedLinks(clusterManagerNode *node) { |
| 4475 | list *links = NULL; |
| 4476 | redisReply *reply = CLUSTER_MANAGER_COMMAND(node, "CLUSTER NODES"); |
| 4477 | if (!clusterManagerCheckRedisReply(node, reply, NULL)) goto cleanup; |
| 4478 | links = listCreate(); |
| 4479 | char *lines = reply->str, *p, *line; |
| 4480 | while ((p = strstr(lines, "\n")) != NULL) { |
| 4481 | int i = 0; |
| 4482 | *p = '\0'; |
| 4483 | line = lines; |
| 4484 | lines = p + 1; |
| 4485 | char *nodename = NULL, *addr = NULL, *flags = NULL, *link_status = NULL; |
| 4486 | while ((p = strchr(line, ' ')) != NULL) { |
| 4487 | *p = '\0'; |
| 4488 | char *token = line; |
| 4489 | line = p + 1; |
| 4490 | if (i == 0) nodename = token; |
| 4491 | else if (i == 1) addr = token; |
| 4492 | else if (i == 2) flags = token; |
| 4493 | else if (i == 7) link_status = token; |
| 4494 | else if (i == 8) break; |
| 4495 | i++; |
| 4496 | } |
| 4497 | if (i == 7) link_status = line; |
| 4498 | if (nodename == NULL || addr == NULL || flags == NULL || |
| 4499 | link_status == NULL) continue; |
| 4500 | if (strstr(flags, "myself") != NULL) continue; |
| 4501 | int disconnected = ((strstr(flags, "disconnected") != NULL) || |
| 4502 | (strstr(link_status, "disconnected"))); |
| 4503 | int handshaking = (strstr(flags, "handshake") != NULL); |
| 4504 | if (disconnected || handshaking) { |
| 4505 | clusterManagerLink *link = zmalloc(sizeof(*link)); |
| 4506 | link->node_name = sdsnew(nodename); |
| 4507 | link->node_addr = sdsnew(addr); |
| 4508 | link->connected = 0; |
| 4509 | link->handshaking = handshaking; |
| 4510 | listAddNodeTail(links, link); |
| 4511 | } |
| 4512 | } |
| 4513 | cleanup: |
| 4514 | if (reply != NULL) freeReplyObject(reply); |
| 4515 | return links; |
| 4516 | } |
| 4517 | |
| 4518 | /* Check for disconnected cluster links. It returns a dict whose keys |
| 4519 | * are the unreachable node addresses and the values are lists of |
no test coverage detected