Vote for the node asking for our vote if there are the conditions. */
| 2950 | |
| 2951 | /* Vote for the node asking for our vote if there are the conditions. */ |
| 2952 | void clusterSendFailoverAuthIfNeeded(clusterNode *node, clusterMsg *request) { |
| 2953 | clusterNode *master = node->slaveof; |
| 2954 | uint64_t requestCurrentEpoch = ntohu64(request->currentEpoch); |
| 2955 | uint64_t requestConfigEpoch = ntohu64(request->configEpoch); |
| 2956 | unsigned char *claimed_slots = request->myslots; |
| 2957 | int force_ack = request->mflags[0] & CLUSTERMSG_FLAG0_FORCEACK; |
| 2958 | int j; |
| 2959 | |
| 2960 | /* IF we are not a master serving at least 1 slot, we don't have the |
| 2961 | * right to vote, as the cluster size in Redis Cluster is the number |
| 2962 | * of masters serving at least one slot, and quorum is the cluster |
| 2963 | * size + 1 */ |
| 2964 | if (nodeIsSlave(myself) || myself->numslots == 0) return; |
| 2965 | |
| 2966 | /* Request epoch must be >= our currentEpoch. |
| 2967 | * Note that it is impossible for it to actually be greater since |
| 2968 | * our currentEpoch was updated as a side effect of receiving this |
| 2969 | * request, if the request epoch was greater. */ |
| 2970 | if (requestCurrentEpoch < g_pserver->cluster->currentEpoch) { |
| 2971 | serverLog(LL_WARNING, |
| 2972 | "Failover auth denied to %.40s: reqEpoch (%llu) < curEpoch(%llu)", |
| 2973 | node->name, |
| 2974 | (unsigned long long) requestCurrentEpoch, |
| 2975 | (unsigned long long) g_pserver->cluster->currentEpoch); |
| 2976 | return; |
| 2977 | } |
| 2978 | |
| 2979 | /* I already voted for this epoch? Return ASAP. */ |
| 2980 | if (g_pserver->cluster->lastVoteEpoch == g_pserver->cluster->currentEpoch) { |
| 2981 | serverLog(LL_WARNING, |
| 2982 | "Failover auth denied to %.40s: already voted for epoch %llu", |
| 2983 | node->name, |
| 2984 | (unsigned long long) g_pserver->cluster->currentEpoch); |
| 2985 | return; |
| 2986 | } |
| 2987 | |
| 2988 | /* Node must be a slave and its master down. |
| 2989 | * The master can be non failing if the request is flagged |
| 2990 | * with CLUSTERMSG_FLAG0_FORCEACK (manual failover). */ |
| 2991 | if (nodeIsMaster(node) || master == NULL || |
| 2992 | (!nodeFailed(master) && !force_ack)) |
| 2993 | { |
| 2994 | if (nodeIsMaster(node)) { |
| 2995 | serverLog(LL_WARNING, |
| 2996 | "Failover auth denied to %.40s: it is a master node", |
| 2997 | node->name); |
| 2998 | } else if (master == NULL) { |
| 2999 | serverLog(LL_WARNING, |
| 3000 | "Failover auth denied to %.40s: I don't know its master", |
| 3001 | node->name); |
| 3002 | } else if (!nodeFailed(master)) { |
| 3003 | serverLog(LL_WARNING, |
| 3004 | "Failover auth denied to %.40s: its master is up", |
| 3005 | node->name); |
| 3006 | } |
| 3007 | return; |
| 3008 | } |
| 3009 |
no test coverage detected