Esempio n. 1
0
void
server_pool_deinit(struct array *server_pool)
{
	uint32_t i, npool;

	for (i = 0, npool = array_n(server_pool); i < npool; i++) {
		struct server_pool *sp;

		sp = array_pop(server_pool);
		ASSERT(sp->p_conn == NULL);
		ASSERT(TAILQ_EMPTY(&sp->c_conn_q) && sp->dn_conn_q == 0);

		server_deinit(&sp->server);
		if (array_n(&sp->racks) != 0)
		  array_each(&sp->racks, rack_deinit, NULL);
		array_deinit(&sp->racks);

		sp->nlive_server = 0;

		log_debug(LOG_DEBUG, "deinit pool %"PRIu32" '%.*s'", sp->idx,
				sp->name.len, sp->name.data);
	}

	array_deinit(server_pool);

	log_debug(LOG_DEBUG, "deinit %"PRIu32" pools", npool);
}
Esempio n. 2
0
void
conf_destroy(struct conf *cf)
{
    while (array_n(&cf->arg) != 0) {
        conf_pop_scalar(cf);
    }
    array_deinit(&cf->arg);

    while (array_n(&cf->pool) != 0) {
        conf_pool_deinit(array_pop(&cf->pool));
    }
    array_deinit(&cf->pool);

    nc_free(cf);
}
Esempio n. 3
0
void
server_pool_deinit(struct array *server_pool)
{
    uint32_t i, npool;

    for (i = 0, npool = array_n(server_pool); i < npool; i++) {
        struct server_pool *sp;

        sp = array_pop(server_pool);
        ASSERT(sp->p_conn == NULL);
        ASSERT(TAILQ_EMPTY(&sp->c_conn_q) && sp->nc_conn_q == 0);

        if (sp->continuum != NULL) {
            nc_free(sp->continuum);
            sp->ncontinuum = 0;
            sp->nserver_continuum = 0;
            sp->nlive_server = 0;
        }

        server_deinit(&sp->server);

        log_debug(LOG_DEBUG, "deinit pool %"PRIu32" '%.*s'", sp->idx,
                  sp->name.len, sp->name.data);
    }

    array_deinit(server_pool);

    log_debug(LOG_DEBUG, "deinit %"PRIu32" pools", npool);
}
Esempio n. 4
0
void
dnode_peer_pool_deinit(struct array *server_pool)
{
	uint32_t i, npool;

	for (i = 0, npool = array_n(server_pool); i < npool; i++) {
		struct server_pool *sp;

		sp = array_pop(server_pool);
		ASSERT(sp->p_conn == NULL);
		//fixe me to use different variables
		ASSERT(TAILQ_EMPTY(&sp->c_conn_q) && sp->dn_conn_q == 0);


		dnode_peer_deinit(&sp->peers);
		array_each(&sp->datacenters, datacenter_destroy, NULL);
		array_deinit(&sp->datacenters);

		log_debug(LOG_DEBUG, "dyn: deinit peer pool %"PRIu32" '%.*s'", sp->idx,
				sp->name.len, sp->name.data);
	}

	//array_deinit(server_pool);

	log_debug(LOG_DEBUG, "deinit %"PRIu32" peer pools", npool);
}
Esempio n. 5
0
static rstatus_t
conf_pool_init(struct conf_pool *cp, struct string *name)
{
    rstatus_t status;

    string_init(&cp->name);

    string_init(&cp->listen.pname);
    string_init(&cp->listen.name);
    cp->listen.port = 0;
    memset(&cp->listen.info, 0, sizeof(cp->listen.info));
    cp->listen.valid = 0;

    cp->hash = CONF_UNSET_HASH;
    string_init(&cp->hash_tag);
    cp->distribution = CONF_UNSET_DIST;

    cp->timeout = CONF_UNSET_NUM;
    cp->backlog = CONF_UNSET_NUM;

    cp->client_connections = CONF_UNSET_NUM;

    cp->tcpkeepalive = CONF_UNSET_NUM;
    string_init(&cp->redis_auth);
    cp->redis_db = CONF_UNSET_NUM;
    cp->server_connections = CONF_UNSET_NUM;

    array_null(&cp->groups);

    cp->sentinel_heartbeat = CONF_UNSET_NUM;
    array_null(&cp->sentinels);

    cp->valid = 0;

    status = string_duplicate(&cp->name, name);
    if (status != NC_OK) {
        return status;
    }

    status = array_init(&cp->groups, CONF_DEFAULT_GROUPS,
                        sizeof(struct string));
    if (status != NC_OK) {
        string_deinit(&cp->name);
        return status;
    }

    status = array_init(&cp->sentinels, CONF_DEFAULT_SENTINELS,
                        sizeof(struct conf_server));
    if (status != NC_OK) {
        array_deinit(&cp->groups);
        string_deinit(&cp->name);
        return status;
    }

    log_debug(LOG_VVERB, "init conf pool %p, '%.*s'", cp, name->len, name->data);

    return NC_OK;
}
Esempio n. 6
0
void
server_deinit(struct array *server)
{
	uint32_t i, nserver;

	for (i = 0, nserver = array_n(server); i < nserver; i++) {
		struct server *s = array_pop(server);
		ASSERT(TAILQ_EMPTY(&s->s_conn_q) && s->ns_conn_q == 0);
	}
	array_deinit(server);
}
Esempio n. 7
0
static void
stats_metric_deinit(struct array *metric)
{
    uint32_t i, nmetric;

    nmetric = array_n(metric);
    for (i = 0; i < nmetric; i++) {
        array_pop(metric);
    }
    array_deinit(metric);
}
Esempio n. 8
0
void
dnode_peer_deinit(struct array *nodes)
{
	uint32_t i, nnode;

	for (i = 0, nnode = array_n(nodes); i < nnode; i++) {
		struct server *s;

		s = array_pop(nodes);
		ASSERT(TAILQ_EMPTY(&s->s_conn_q) && s->ns_conn_q == 0);
	}
	array_deinit(nodes);
}
Esempio n. 9
0
static struct conf *
conf_open(char *filename)
{
    rstatus_t status;
    struct conf *cf;
    FILE *fh;

    fh = fopen(filename, "r");
    if (fh == NULL) {
        log_error("conf: failed to open configuration '%s': %s", filename,
                  strerror(errno));
        return NULL;
    }

    cf = nc_alloc(sizeof(*cf));
    if (cf == NULL) {
        fclose(fh);
        return NULL;
    }

    status = array_init(&cf->arg, CONF_DEFAULT_ARGS, sizeof(struct string));
    if (status != NC_OK) {
        nc_free(cf);
        fclose(fh);
        return NULL;
    }

    status = array_init(&cf->pool, CONF_DEFAULT_POOL, sizeof(struct conf_pool));
    if (status != NC_OK) {
        array_deinit(&cf->arg);
        nc_free(cf);
        fclose(fh);
        return NULL;
    }

    cf->fname = filename;
    cf->fh = fh;
    cf->depth = 0;
    /* parser, event, and token are initialized later */
    cf->seq = 0;
    cf->valid_parser = 0;
    cf->valid_event = 0;
    cf->valid_token = 0;
    cf->sound = 0;
    cf->parsed = 0;
    cf->valid = 0;

    log_debug(LOG_VVERB, "opened conf '%s'", filename);

    return cf;
}
Esempio n. 10
0
static void
conf_pool_deinit(struct conf_pool *cp)
{
    string_deinit(&cp->name);

    string_deinit(&cp->listen.pname);
    string_deinit(&cp->listen.name);

    while (array_n(&cp->server) != 0) {
        conf_server_deinit(array_pop(&cp->server));
    }
    array_deinit(&cp->server);

    log_debug(LOG_VVERB, "deinit conf pool %p", cp);
}
Esempio n. 11
0
static void
conf_pool_deinit(struct conf_pool *cp)
{
    string_deinit(&cp->name);

    string_deinit(&cp->listen.pname);
    string_deinit(&cp->listen.name);

    if (cp->redis_auth.len > 0) {
        string_deinit(&cp->redis_auth);
    }

    while (array_n(&cp->groups) != 0) {
        string_deinit(array_pop(&cp->groups));
    }
    array_deinit(&cp->groups);

    while (array_n(&cp->sentinels) != 0) {
        conf_server_deinit(array_pop(&cp->sentinels));
    }
    array_deinit(&cp->sentinels);

    log_debug(LOG_VVERB, "deinit conf pool %p", cp);
}
Esempio n. 12
0
static void
stats_server_unmap(struct array *stats_server)
{
    uint32_t i, nserver;

    nserver = array_n(stats_server);

    for (i = 0; i < nserver; i++) {
        struct stats_server *sts = array_pop(stats_server);
        stats_metric_deinit(&sts->metric);
    }
    array_deinit(stats_server);

    log_debug(LOG_VVVERB, "unmap %"PRIu32" stats servers", nserver);
}
Esempio n. 13
0
static void
stats_pool_unmap(struct array *stats_pool)
{
    uint32_t i, npool;

    npool = array_n(stats_pool);

    for (i = 0; i < npool; i++) {
        struct stats_pool *stp = array_pop(stats_pool);
        stats_metric_deinit(&stp->metric);
        stats_server_unmap(&stp->server);
    }
    array_deinit(stats_pool);

    log_debug(LOG_VVVERB, "unmap %"PRIu32" stats pool", npool);
}
Esempio n. 14
0
void shell_run_command(shell *s, cmd *c) {
	if (c->command == NULL
		|| c->command->string == NULL
		|| strcmp(c->command->string, "") == 0) {
			return;
	}
	
	if (strcmp(c->command->string, "exit") == 0) {
		exit(0);
	}
	
	if (strcmp(c->command->string, "(╯°□°)╯︵┻━┻") == 0) {
		printf("┬─┬ ノ( ゜-゜ノ)\n");
		return;
	}
	
	if (strcmp(c->command->string, "cd") == 0 && c->command->next != NULL) {
		const char *newdir = c->command->next->string;
		int error = chdir(newdir);
		
		switch (error) {
			case 0:
				break;
			case EACCES:
				fprintf(stderr, "%s: access denied.\n", newdir); break;
			case ENOENT:
				fprintf(stderr, "%s: no such file or directory.\n", newdir);
				break;
			case ENOTDIR:
				fprintf(stderr, "%s: not a directory.\n", newdir); break;
			default:
				fprintf(stderr, "%s: error %i\n", newdir, error); break;
		}
		
		return;
	}
	
	shell_run_command_with_pipe(s, c, 0);
	
	array_deinit(&s->running_processes);
	array_init_with_element_size(&s->running_processes, sizeof(pid_t));
}
Esempio n. 15
0
void
stats_pool_copy_deinit(struct stats_pool *stp, struct hash_table **sit)
{
    uint32_t nserver;
    uint32_t i;
    struct stats_server *sts;

    stats_metric_deinit(&stp->metric);
    string_deinit(&stp->name);

    nserver = array_n(&stp->server);
    for (i = 0;i < nserver;i++) {
        sts = array_pop(&stp->server);
        string_deinit(&stp->name);

        stats_metric_deinit(&sts->metric);
    }
    array_deinit(&stp->server);

    assoc_destroy_table(*sit);
    (*sit) = NULL;
}
Esempio n. 16
0
/**
 * Destroys a memoization map.
 */
static void memo_map_destroy(memo_map_t *map)
{
    int i;

    assert(map);

    for (i = 0; i < PEG_NUM_NODE_TYPES; ++i)
    {
        int j, count = array_size(&map->records[i]);
        for (j = 0; j < count; ++j)
        {
            memo_rec_t *mr = (memo_rec_t *) array_item(&map->records[i], j);

            if (mr->parse_tree)
                syntax_node_destroy(mr->parse_tree);
        }

        array_deinit(&map->records[i]);
    }

    free(map);
} /* memo_map_destroy() */
Esempio n. 17
0
static int check_response(redis_node *rnode, struct msg *r)
{
    int ret;
    rmtContext *ctx = rnode->ctx;
    struct msg *resp, *msg = NULL;
    check_data *chdata;
    check_unit *cunit;
    char extra_err[50];
    struct array args;
    sds *arg;
    struct array *bulks1 = NULL, *bulks2 = NULL;
    sds *bulk1, *bulk2;

    if (r == NULL) {
        return RMT_ERROR;
    }

    extra_err[0] = '\0';

    resp = r->peer;
    r->peer = NULL;
    array_init(&args, 3, sizeof(sds));

    ASSERT(r->request && r->sent);
    ASSERT(resp != NULL && resp->request == 0);

    cunit = (check_unit *)r->ptr;
    chdata = cunit->cdata->data;

    if(resp->type == MSG_RSP_REDIS_ERROR){
        log_warn("Response from node[%s] for %s is error",
            rnode->addr, msg_type_string(r->type));
        goto error;
    }

    if (cunit->state == CHECK_UNIT_STATE_GET_KEY) {
        ASSERT(cunit->key == NULL);
        ASSERT(cunit->key_type == -1);
        ASSERT(cunit->result1 == NULL && cunit->result2 == NULL);
        ASSERT(cunit->srnode == rnode);

        if (resp->type != MSG_RSP_REDIS_BULK) {
            log_error("ERROR: the response type for command 'randomkey' from node[%s] is error: %s", 
                rnode->addr, msg_type_string(resp->type));
            goto error;
        }

        if (msg_cmp_str(resp, (const uint8_t*)REDIS_REPLY_BULK_NULL, 
            rmt_strlen(REDIS_REPLY_BULK_NULL)) == 0) {
            /* source group may have no keys, stop it */
            cunit->cdata->keys_count --;
            goto done;
        }

        cunit->key = redis_msg_response_get_bulk_string(resp);
        if (cunit->key == NULL) {
            log_error("ERROR: get bulk string from response of node[%s] failed, "
                "bulk_len: %"PRIu32", bulk_start: %p", 
                rnode->addr, resp->bulk_len, resp->bulk_start);
            goto error;
        }

        if (ctx->filter != NULL && !stringmatchlen(ctx->filter, sdslen(ctx->filter), 
            cunit->key, sdslen(cunit->key), 0)) {
            goto done;
        }

        ASSERT(sdslen(cunit->key) == resp->bulk_len);

        msg = msg_get(r->mb, 1, REDIS_DATA_TYPE_CMD);
        if (msg == NULL) {
            log_error("ERROR: out of memory.");
            goto error;
        }

        arg = array_push(&args);
        *arg = sdsnew("type");
        arg = array_push(&args);
        *arg = sdsdup(cunit->key);
        ret = redis_msg_append_command_full_safe(msg, &args);
        if (ret != RMT_OK) {
            log_error("ERROR: msg append multi bulk len failed.");
            goto error;
        }
        while (array_n(&args) > 0) {
            arg = array_pop(&args);
            sdsfree(*arg);
        }
        
        msg->ptr = cunit;
        msg->resp_check = check_response;

        ret = prepare_send_msg(rnode, msg, rnode);
        if (ret != RMT_OK) {
            log_error("ERROR: prepare send msg node[%s] failed.", rnode->addr);
            goto error;
        }

        cunit->state = CHECK_UNIT_STATE_GET_TYPE;
        goto next_step;
    }

    if (cunit->state == CHECK_UNIT_STATE_GET_TYPE) {
        ASSERT(cunit->key != NULL);
        ASSERT(cunit->key_type == -1);
        ASSERT(cunit->result1 == NULL && cunit->result2 == NULL);
        ASSERT(cunit->srnode == rnode);
        
        if (resp->type != MSG_RSP_REDIS_STATUS) {
            log_error("ERROR: the response type for command 'type' from node[%s] is error: %s", 
                rnode->addr, msg_type_string(resp->type));
            goto error;
        }

        if (msg_cmp_str(resp, (const uint8_t*)REDIS_REPLY_STATUS_NONE, 
            rmt_strlen(REDIS_REPLY_STATUS_NONE)) == 0) {
            /* This key doesn't exit, may be expired or evicted */
            goto done;
        }

        msg = msg_get(r->mb, 1, REDIS_DATA_TYPE_CMD);
        if (msg == NULL) {
            log_error("ERROR: out of memory.");
            goto error;
        }

        if (msg_cmp_str(resp, (const uint8_t*)REDIS_REPLY_STATUS_STRING, 
            rmt_strlen(REDIS_REPLY_STATUS_STRING)) == 0) {
            cunit->key_type = REDIS_STRING;

            arg = array_push(&args);
            *arg = sdsnew("get");
            arg = array_push(&args);
            *arg = sdsdup(cunit->key);
            ret = redis_msg_append_command_full_safe(msg, &args);
            if (ret != RMT_OK) {
                log_error("ERROR: msg append multi bulk len failed.");
                goto error;
            }
            while (array_n(&args) > 0) {
                arg = array_pop(&args);
                sdsfree(*arg);
            }
        } else if (msg_cmp_str(resp, (const uint8_t*)REDIS_REPLY_STATUS_LIST, 
            rmt_strlen(REDIS_REPLY_STATUS_LIST)) == 0) {
            cunit->key_type = REDIS_LIST;

            arg = array_push(&args);
            *arg = sdsnew("lrange");
            arg = array_push(&args);
            *arg = sdsdup(cunit->key);
            arg = array_push(&args);
            *arg = sdsnew("0");
            arg = array_push(&args);
            *arg = sdsnew("-1");
            ret = redis_msg_append_command_full_safe(msg, &args);
            if (ret != RMT_OK) {
                log_error("ERROR: msg append multi bulk len failed.");
                goto error;
            }
            while (array_n(&args) > 0) {
                arg = array_pop(&args);
                sdsfree(*arg);
            }
        } else if (msg_cmp_str(resp, (const uint8_t*)REDIS_REPLY_STATUS_SET, 
            rmt_strlen(REDIS_REPLY_STATUS_SET)) == 0) {
            cunit->key_type = REDIS_SET;

            arg = array_push(&args);
            *arg = sdsnew("smembers");
            arg = array_push(&args);
            *arg = sdsdup(cunit->key);
            ret = redis_msg_append_command_full_safe(msg, &args);
            if (ret != RMT_OK) {
                log_error("ERROR: msg append multi bulk len failed.");
                goto error;
            }
            while (array_n(&args) > 0) {
                arg = array_pop(&args);
                sdsfree(*arg);
            }
        } else if (msg_cmp_str(resp, (const uint8_t*)REDIS_REPLY_STATUS_ZSET, 
            rmt_strlen(REDIS_REPLY_STATUS_ZSET)) == 0) {
            cunit->key_type = REDIS_ZSET;

            arg = array_push(&args);
            *arg = sdsnew("zrange");
            arg = array_push(&args);
            *arg = sdsdup(cunit->key);
            arg = array_push(&args);
            *arg = sdsnew("0");
            arg = array_push(&args);
            *arg = sdsnew("-1");
            ret = redis_msg_append_command_full_safe(msg, &args);
            if (ret != RMT_OK) {
                log_error("ERROR: msg append multi bulk len failed.");
                goto error;
            }
            while (array_n(&args) > 0) {
                arg = array_pop(&args);
                sdsfree(*arg);
            }
        } else if (msg_cmp_str(resp, (const uint8_t*)REDIS_REPLY_STATUS_HASH, 
            rmt_strlen(REDIS_REPLY_STATUS_HASH)) == 0) {
            cunit->key_type = REDIS_HASH;

            arg = array_push(&args);
            *arg = sdsnew("hgetall");
            arg = array_push(&args);
            *arg = sdsdup(cunit->key);
            ret = redis_msg_append_command_full_safe(msg, &args);
            if (ret != RMT_OK) {
                log_error("ERROR: msg append multi bulk len failed.");
                goto error;
            }
            while (array_n(&args) > 0) {
                arg = array_pop(&args);
                sdsfree(*arg);
            }
        } else {
            log_error("ERROR: response key type from node[%s] is error: ",
                rnode->addr);
            goto error;
        }

        msg->ptr = cunit;
        msg->resp_check = check_response;
        
        ret = send_msg_to_all(cunit, msg);
        if (ret != RMT_OK) {
            log_error("ERROR: send msg to source and target group failed.");
            goto error;
        }

        cunit->state = CHECK_UNIT_STATE_GET_VALUE;
        goto next_step;
    }

    if (cunit->state == CHECK_UNIT_STATE_GET_VALUE) {
        ASSERT(cunit->key != NULL);
        ASSERT(cunit->key_type >= 0);
        ASSERT(cunit->result1 == NULL || cunit->result2 == NULL);
        
        if (cunit->key_type == REDIS_STRING) {
            if (resp->type != MSG_RSP_REDIS_BULK) {
                log_error("ERROR: the response type for %s from node[%s] is error: %s", 
                    rnode->addr, msg_type_string(r->type), msg_type_string(resp->type));
                goto error;
            }
        } else if (cunit->key_type == REDIS_LIST) {

        } else if (cunit->key_type == REDIS_SET) {
            
        } else if (cunit->key_type == REDIS_ZSET) {
            
        } else if (cunit->key_type == REDIS_HASH) {
            
        } else {
            NOT_REACHED();
        }

        if (cunit->result1 == NULL) {
            cunit->result1 = resp;
            resp = NULL;
        } else if (cunit->result2 == NULL) {
            cunit->result2 = resp;
            resp = NULL;
        } else {
            NOT_REACHED();
        }
    
        if (cunit->result1 != NULL && cunit->result2 != NULL) {
            if (cunit->key_type == REDIS_SET) {
                uint32_t j;

                bulks1 = get_multi_bulk_array_from_mbuf_list(cunit->result1->data);
                bulks2 = get_multi_bulk_array_from_mbuf_list(cunit->result2->data);
                if (bulks1 == NULL || bulks2 == NULL) {
                    log_error("ERROR: get multi bulk array from mbufs failed");
                    goto error;
                }

                if (array_n(bulks1) != array_n(bulks2)) {
                    chdata->err_inconsistent_value_keys_count ++;
                    rmt_safe_snprintf(extra_err, 50, ", value is inconsistent\0");
                    goto error;
                }
                
                array_sort(bulks1, string_binary_cmp);
                array_sort(bulks2, string_binary_cmp);

                for (j = 0; j < array_n(bulks1); j ++) {
                    bulk1 = array_get(bulks1, j);
                    bulk2 = array_get(bulks2, j);
                    if (string_binary_cmp(bulk1, bulk2) != 0) {
                        chdata->err_inconsistent_value_keys_count ++;
                        rmt_safe_snprintf(extra_err, 50, ", value is inconsistent\0");
                        goto error;
                    }
                }
            } else if (cunit->key_type == REDIS_HASH) {
                struct array *hash_datas1, *hash_datas2;
                uint32_t hash_len;
                uint32_t j;
                struct hash_data *hd1, *hd2;

                hash_datas1 = hash_datas2 = NULL;
            
                bulks1 = get_multi_bulk_array_from_mbuf_list(cunit->result1->data);
                bulks2 = get_multi_bulk_array_from_mbuf_list(cunit->result2->data);
                if (bulks1 == NULL || bulks2 == NULL) {
                    log_error("ERROR: get multi bulk array from mbufs failed");
                    goto error;
                }

                if (array_n(bulks1)%2 != 0 || array_n(bulks2)%2 != 0) {
                    log_error("ERROR: bad hash value");
                    goto error;
                }

                if (array_n(bulks1) != array_n(bulks2)) {
                    chdata->err_inconsistent_value_keys_count ++;
                    rmt_safe_snprintf(extra_err, 50, ", value is inconsistent\0");
                    goto error;
                }

                hash_len = array_n(bulks1)/2;
                hash_datas1 = array_create(hash_len, sizeof(struct hash_data));
                hash_datas2 = array_create(hash_len, sizeof(struct hash_data));

                for (j = 0; j < hash_len; j ++) {
                    hd1 = array_push(hash_datas1);
                    hd2 = array_push(hash_datas2);

                    bulk1 = array_pop(bulks1);
                    bulk2 = array_pop(bulks1);
                    hd1->field = *bulk1;
                    hd1->value = *bulk2;

                    bulk1 = array_pop(bulks2);
                    bulk2 = array_pop(bulks2);
                    hd2->field = *bulk1;
                    hd2->value = *bulk2;
                }

                array_sort(hash_datas1, hash_data_field_cmp);
                array_sort(hash_datas2, hash_data_field_cmp);

                for (j = 0; j < array_n(bulks1); j ++) {
                    hd1 = array_get(hash_datas1, j);
                    hd2 = array_get(hash_datas2, j);
                    if (string_binary_cmp(hd1->field, hd2->field) != 0) {
                        chdata->err_inconsistent_value_keys_count ++;
                        rmt_safe_snprintf(extra_err, 50, ", value is inconsistent\0");
                        if (hash_datas1 != NULL) {
                            while (array_n(hash_datas1) > 0) {
                                hd1 = array_pop(hash_datas1);
                                sdsfree(hd1->field);
                                sdsfree(hd1->value);
                            }
                            array_destroy(hash_datas1);
                            hash_datas1 = NULL;
                        }
                        if (hash_datas2 != NULL) {
                            while (array_n(hash_datas2) > 0) {
                                hd2 = array_pop(hash_datas2);
                                sdsfree(hd2->field);
                                sdsfree(hd2->value);
                            }
                            array_destroy(hash_datas2);
                            hash_datas2 = NULL;
                        }
                        goto error;
                    }
                    if (string_binary_cmp(hd1->value, hd2->value) != 0) {
                        chdata->err_inconsistent_value_keys_count ++;
                        rmt_safe_snprintf(extra_err, 50, ", value is inconsistent\0");
                        if (hash_datas1 != NULL) {
                            while (array_n(hash_datas1) > 0) {
                                hd1 = array_pop(hash_datas1);
                                sdsfree(hd1->field);
                                sdsfree(hd1->value);
                            }
                            array_destroy(hash_datas1);
                            hash_datas1 = NULL;
                        }
                        if (hash_datas2 != NULL) {
                            while (array_n(hash_datas2) > 0) {
                                hd2 = array_pop(hash_datas2);
                                sdsfree(hd2->field);
                                sdsfree(hd2->value);
                            }
                            array_destroy(hash_datas2);
                            hash_datas2 = NULL;
                        }
                        goto error;
                    }
                }

                if (hash_datas1 != NULL) {
                    while (array_n(hash_datas1) > 0) {
                        hd1 = array_pop(hash_datas1);
                        sdsfree(hd1->field);
                        sdsfree(hd1->value);
                    }
                    array_destroy(hash_datas1);
                    hash_datas1 = NULL;
                }
                if (hash_datas2 != NULL) {
                    while (array_n(hash_datas2) > 0) {
                        hd2 = array_pop(hash_datas2);
                        sdsfree(hd2->field);
                        sdsfree(hd2->value);
                    }
                    array_destroy(hash_datas2);
                    hash_datas2 = NULL;
                }
            } else if (msg_data_compare(cunit->result1, cunit->result2) != 0) {
                chdata->err_inconsistent_value_keys_count ++;
                rmt_safe_snprintf(extra_err, 50, ", value is inconsistent\0");
                goto error;
            }

            msg_put(cunit->result1);
            msg_free(cunit->result1);
            cunit->result1 = NULL;
            msg_put(cunit->result2);
            msg_free(cunit->result2);
            cunit->result2 = NULL;

            if (bulks1 != NULL) {
                while (array_n(bulks1) > 0) {
                    bulk1 = array_pop(bulks1);
                    sdsfree(*bulk1);
                }
                array_destroy(bulks1);
                bulks1 = NULL;
            }
            if (bulks2 != NULL) {
                while (array_n(bulks2) > 0) {
                    bulk2 = array_pop(bulks2);
                    sdsfree(*bulk2);
                }
                array_destroy(bulks2);
                bulks2 = NULL;
            }

            msg = msg_get(r->mb, 1, REDIS_DATA_TYPE_CMD);
            if (msg == NULL) {
                log_error("ERROR: out of memory.");
                goto error;
            }

            arg = array_push(&args);
            *arg = sdsnew("ttl");
            arg = array_push(&args);
            *arg = sdsdup(cunit->key);
            ret = redis_msg_append_command_full_safe(msg, &args);
            if (ret != RMT_OK) {
                log_error("ERROR: msg append multi bulk len failed.");
                goto error;
            }
            while (array_n(&args) > 0) {
                arg = array_pop(&args);
                sdsfree(*arg);
            }
            
            msg->ptr = cunit;
            msg->resp_check = check_response;
            
            ret = send_msg_to_all(cunit, msg);
            if (ret != RMT_OK) {
                log_error("ERROR: send msg to source and target group failed.");
                goto error;
            }
            cunit->state = CHECK_UNIT_STATE_GET_EXPIRE;
        }

        goto next_step;
    }

    if (cunit->state == CHECK_UNIT_STATE_GET_EXPIRE) {
        ASSERT(cunit->key != NULL);
        ASSERT(cunit->key_type >= 0);
        ASSERT(cunit->result1 == NULL || cunit->result2 == NULL);

        if (resp->type != MSG_RSP_REDIS_INTEGER) {
            log_error("ERROR: the response type for command 'ttl' from node[%s] is error: %s", 
                rnode->addr, msg_type_string(resp->type));
            goto error;
        }

        if (cunit->result1 == NULL) {
            cunit->result1 = resp;
            resp = NULL;
        } else if (cunit->result2 == NULL) {
            cunit->result2 = resp;
            resp = NULL;
        } else {
            NOT_REACHED();
        }

        if (cunit->result1 != NULL && cunit->result2 != NULL) {
            if (msg_data_compare(cunit->result1, cunit->result2) != 0) { 
                int mistake = (int)cunit->result1->integer - (int)cunit->result2->integer;
                ASSERT(mistake != 0);

                if (abs(mistake) > TTL_MISTAKE_CAN_BE_ACCEPT) {
                    chdata->err_inconsistent_expire_keys_count ++;
                    rmt_safe_snprintf(extra_err, 50, 
                        ", remaining time are %"PRIu32" and %"PRIu32"\0", 
                        cunit->result1->integer, cunit->result2->integer);
                    goto error;
                }
            }

            /* OK, this key is consistent between source group and target group */
            goto done;
        }

        goto next_step;
    }

done:

    check_unit_destroy(cunit);

next_step:
    
    msg_put(r);
    msg_free(r);
    if (resp != NULL) {
        msg_put(resp);
        msg_free(resp);
    }

    array_deinit(&args);
    
    return RMT_OK;

error:

    chdata->err_check_keys_count ++;

    if (cunit->key != NULL) {        
        log_error("ERROR: key checked failed: %s%s. key(len:%zu, type:%s): %.*s",  
            get_check_error(cunit), extra_err, 
            sdslen(cunit->key), get_redis_type_string(cunit->key_type),
            sdslen(cunit->key), cunit->key);
    } else {
        log_error("ERROR: key checked failed: %s%s.", 
            get_check_error(cunit), extra_err);
    }
    MSG_DUMP(r, LOG_ERR, 1);
    msg_put(r);
    msg_free(r);
    if (resp != NULL) {
        MSG_DUMP(resp, LOG_ERR, 1);
        msg_put(resp);
        msg_free(resp);
    }

    if (msg != NULL) {
        msg_put(msg);
        msg_free(msg);
    }

    check_unit_destroy(cunit);
    
    while (array_n(&args) > 0) {
        arg = array_pop(&args);
        sdsfree(*arg);
    }
    array_deinit(&args);

    if (bulks1 != NULL) {
        while (array_n(bulks1) > 0) {
            bulk1 = array_pop(bulks1);
            sdsfree(*bulk1);
        }
        array_destroy(bulks1);
        bulks1 = NULL;
    }
    if (bulks2 != NULL) {
        while (array_n(bulks2) > 0) {
            bulk2 = array_pop(bulks2);
            sdsfree(*bulk2);
        }
        array_destroy(bulks2);
        bulks2 = NULL;
    }
    
    return RMT_OK;
}
Esempio n. 18
0
File: array.c Progetto: cabrilo/ripe
void array_delete(Array* arr)
{
  array_deinit(arr);
  mem_free(arr);
}