Get the hash for the values of the specified keys in *keys_reply for the * specified nodes *n1 and *n2, by calling DEBUG DIGEST-VALUE redis command * on both nodes. Every key with same name on both nodes but having different * values will be added to the *diffs list. Return 0 in case of reply * error. */
| 3609 | * values will be added to the *diffs list. Return 0 in case of reply |
| 3610 | * error. */ |
| 3611 | static int clusterManagerCompareKeysValues(clusterManagerNode *n1, |
| 3612 | clusterManagerNode *n2, |
| 3613 | redisReply *keys_reply, |
| 3614 | list *diffs) |
| 3615 | { |
| 3616 | size_t i, argc = keys_reply->elements + 2; |
| 3617 | static const char *hash_zero = "0000000000000000000000000000000000000000"; |
| 3618 | char **argv = zcalloc(argc * sizeof(char *)); |
| 3619 | size_t *argv_len = zcalloc(argc * sizeof(size_t)); |
| 3620 | argv[0] = "DEBUG"; |
| 3621 | argv_len[0] = 5; |
| 3622 | argv[1] = "DIGEST-VALUE"; |
| 3623 | argv_len[1] = 12; |
| 3624 | for (i = 0; i < keys_reply->elements; i++) { |
| 3625 | redisReply *entry = keys_reply->element[i]; |
| 3626 | int idx = i + 2; |
| 3627 | argv[idx] = entry->str; |
| 3628 | argv_len[idx] = entry->len; |
| 3629 | } |
| 3630 | int success = 0; |
| 3631 | void *_reply1 = NULL, *_reply2 = NULL; |
| 3632 | redisReply *r1 = NULL, *r2 = NULL; |
| 3633 | redisAppendCommandArgv(n1->context,argc, (const char**)argv,argv_len); |
| 3634 | success = (redisGetReply(n1->context, &_reply1) == REDIS_OK); |
| 3635 | if (!success) goto cleanup; |
| 3636 | r1 = (redisReply *) _reply1; |
| 3637 | redisAppendCommandArgv(n2->context,argc, (const char**)argv,argv_len); |
| 3638 | success = (redisGetReply(n2->context, &_reply2) == REDIS_OK); |
| 3639 | if (!success) goto cleanup; |
| 3640 | r2 = (redisReply *) _reply2; |
| 3641 | success = (r1->type != REDIS_REPLY_ERROR && r2->type != REDIS_REPLY_ERROR); |
| 3642 | if (r1->type == REDIS_REPLY_ERROR) { |
| 3643 | CLUSTER_MANAGER_PRINT_REPLY_ERROR(n1, r1->str); |
| 3644 | success = 0; |
| 3645 | } |
| 3646 | if (r2->type == REDIS_REPLY_ERROR) { |
| 3647 | CLUSTER_MANAGER_PRINT_REPLY_ERROR(n2, r2->str); |
| 3648 | success = 0; |
| 3649 | } |
| 3650 | if (!success) goto cleanup; |
| 3651 | assert(keys_reply->elements == r1->elements && |
| 3652 | keys_reply->elements == r2->elements); |
| 3653 | for (i = 0; i < keys_reply->elements; i++) { |
| 3654 | char *key = keys_reply->element[i]->str; |
| 3655 | char *hash1 = r1->element[i]->str; |
| 3656 | char *hash2 = r2->element[i]->str; |
| 3657 | /* Ignore keys that don't exist in both nodes. */ |
| 3658 | if (strcmp(hash1, hash_zero) == 0 || strcmp(hash2, hash_zero) == 0) |
| 3659 | continue; |
| 3660 | if (strcmp(hash1, hash2) != 0) listAddNodeTail(diffs, key); |
| 3661 | } |
| 3662 | cleanup: |
| 3663 | if (r1) freeReplyObject(r1); |
| 3664 | if (r2) freeReplyObject(r2); |
| 3665 | zfree(argv); |
| 3666 | zfree(argv_len); |
| 3667 | return success; |
| 3668 | } |
no test coverage detected