コード例 #1
0
void 
rack_init(struct rack *rack)
{
	rack->continuum = NULL;
	rack->ncontinuum = 0;
	rack->nserver_continuum = 0;
	rack->name = dn_alloc(sizeof(struct string));
	string_init(rack->name);

	rack->dc = dn_alloc(sizeof(struct string));
	string_init(rack->dc);
}
コード例 #2
0
ファイル: dyn_gossip.c プロジェクト: amimimor/dynomite
static struct string *token_to_string(struct dyn_token *token) {
	uint32_t num = token->mag[0];
    int len = num_len(num);
    struct string *result = dn_alloc(sizeof(*result));
    string_init(result);

    result->data = dn_alloc(sizeof(uint8_t) * len);
    result->len = len;

    string_write_uint32(result, num, result->len - 1);
    return result;
}
コード例 #3
0
ファイル: dyn_server.c プロジェクト: kangkot/dynomite
rstatus_t
rack_init(struct rack *rack)
{
	rack->continuum = dn_alloc(sizeof(struct continuum));
	rack->ncontinuum = 0;
	rack->nserver_continuum = 0;
	rack->name = dn_alloc(sizeof(struct string));
	string_init(rack->name);

	rack->dc = dn_alloc(sizeof(struct string));
	string_init(rack->dc);

	return DN_OK;
}
コード例 #4
0
ファイル: dyn_dnode_msg.c プロジェクト: bpoweski/dynomite
struct dmsg *
dmsg_get(void)
{
    struct dmsg *dmsg;

    if (!TAILQ_EMPTY(&free_dmsgq)) {
        ASSERT(nfree_dmsgq > 0);

        dmsg = TAILQ_FIRST(&free_dmsgq);
        nfree_dmsgq--;
        TAILQ_REMOVE(&free_dmsgq, dmsg, m_tqe);
        goto done;
    }

    dmsg = dn_alloc(sizeof(*dmsg));
    if (dmsg == NULL) {
        return NULL;
    }

done:
   // STAILQ_INIT(&dmsg->mhdr);
    dmsg->mlen = 0;
    dmsg->data = NULL;

    dmsg->plen = 0;
    dmsg->payload = NULL;

    dmsg->type = DMSG_UNKNOWN;
    dmsg->version = VERSION_10;
    dmsg->id = 0;
    dmsg->source_address = NULL;
    dmsg->owner = NULL;
    
    return dmsg;
}
コード例 #5
0
static char *hostname_to_ip(char * hostname)
{
    struct hostent *he;
    struct in_addr **addr_list;
    int i;

    if ((he = gethostbyname(hostname)) == NULL)
    {
        return NULL;
    }

    addr_list = (struct in_addr **) he->h_addr_list;
    for(i = 0; addr_list[i] != NULL; i++);

    char *ip = dn_alloc(i);

    for(i = 0; addr_list[i] != NULL; i++)
    {
        //Return the first one;
        strcpy(ip , inet_ntoa(*(0 + addr_list[i])) );
        return ip;
    }

    return NULL;
}
コード例 #6
0
ファイル: dyn_dnode_peer.c プロジェクト: chrholme/dynomite
static rstatus_t
dnode_peer_add_node(struct server_pool *sp, struct node *node)
{
	rstatus_t status;
	struct array *peers = &sp->peers;
	struct server *s = array_push(peers);

	s->owner = sp;

	uint32_t i,nelem;
	s->idx = array_idx(peers, s);

	//log_debug(LOG_VERB, "node rack_name         : '%.*s'", node->rack.len, node->rack.data);
	//log_debug(LOG_VERB, "node dc_name        : '%.*s'", node->dc.len, node->dc.data);
	//log_debug(LOG_VERB, "node address          : '%.*s'", node->pname.len, node->pname.data);
	//log_debug(LOG_VERB, "node ip         : '%.*s'", node->name.len, node->name.data);


	string_copy(&s->pname, node->pname.data, node->pname.len);
	string_copy(&s->name, node->name.data, node->name.len);
	string_copy(&s->rack, node->rack.data, node->rack.len);
	string_copy(&s->dc, node->dc.data, node->dc.len);

	s->port = (uint16_t) node->port;
	s->is_local = node->is_local;
	s->state = node->state;
	s->processed = 0;

	array_init(&s->tokens, 1, sizeof(struct dyn_token));
	struct dyn_token *src_token = &node->token;
	struct dyn_token *dst_token = array_push(&s->tokens);
	copy_dyn_token(src_token, dst_token);

	struct sockinfo  *info =  dn_alloc(sizeof(*info)); //need to free this
	dn_resolve(&s->name, s->port, info);
	s->family = info->family;
	s->addrlen = info->addrlen;
	s->addr = (struct sockaddr *)&info->addr;  //TODOs: fix this by copying, not reference
	s->ns_conn_q = 0;
	TAILQ_INIT(&s->s_conn_q);

	s->next_retry = 0LL;
	s->failure_count = 0;
	s->is_seed = node->is_seed;

	log_debug(LOG_VERB, "add a node to peer %"PRIu32" '%.*s'",
			s->idx, s->pname.len, s->pname.data);

	dnode_peer_relink_conn_owner(sp);

	status = dnode_peer_pool_run(sp);
	if (status != DN_OK)
		return status;

	status = dnode_peer_each_preconnect(s, NULL);

	return status;
}
コード例 #7
0
rstatus_t
dnode_peer_replace(void *rmsg)
{
	//rstatus_t status;
	struct ring_msg *msg = rmsg;
	struct server_pool *sp = msg->sp;
	struct node *node = array_get(&msg->nodes, 0);
	log_debug(LOG_VVERB, "dyn: peer has a replaced message '%.*s'", node->name.len, node->name.data);
	struct array *peers = &sp->peers;
	struct server *s = NULL;

	uint32_t i,nelem;
	//bool node_exist = false;
	//TODOs: use hash table here
	for (i=1, nelem = array_n(peers); i< nelem; i++) {
		struct server * peer = (struct server *) array_get(peers, i);
		if (string_compare(&peer->rack, &node->rack) == 0) {
			//TODOs: now only compare 1st token and support vnode later - use hash string on a tokens for comparison
			struct dyn_token *ptoken = (struct dyn_token *) array_get(&peer->tokens, 0);
			struct dyn_token *ntoken = &node->token;

			if (cmp_dyn_token(ptoken, ntoken) == 0) {
				s = peer; //found a node to replace
			}
		}
	}


	if (s != NULL) {
		log_debug(LOG_INFO, "Found an old node to replace '%.*s'", s->name.len, s->name.data);
		log_debug(LOG_INFO, "Replace with address '%.*s'", node->name.len, node->name.data);

		string_deinit(&s->pname);
		string_deinit(&s->name);
		string_copy(&s->pname, node->pname.data, node->pname.len);
		string_copy(&s->name, node->name.data, node->name.len);

		//TODOs: need to free the previous s->addr?
		//if (s->addr != NULL) {
		//   dn_free(s->addr);
		//}

		struct sockinfo  *info =  dn_alloc(sizeof(*info)); //need to free this
		dn_resolve(&s->name, s->port, info);
		s->family = info->family;
		s->addrlen = info->addrlen;
		s->addr = (struct sockaddr *)&info->addr;  //TODOs: fix this by copying, not reference


		dnode_peer_each_disconnect(s, NULL);
		dnode_peer_each_preconnect(s, NULL);
	} else {
		log_debug(LOG_INFO, "Unable to find any node matched the token");
	}

	return DN_OK;
}
コード例 #8
0
ファイル: dyn_stats.c プロジェクト: logikal/dynomite
static rstatus_t
stats_msg_to_core(stats_cmd_t cmd, void *cb, void *post_cb)
{
    struct stat_msg *msg = dn_alloc(sizeof(*msg));
    msg->cmd = cmd;
    msg->data = NULL;
    msg->cb = cb;
    msg->post_cb = post_cb;
    CBUF_Push(C2S_OutQ, msg);
	return DN_OK;
}
コード例 #9
0
ファイル: dyn_mbuf.c プロジェクト: Aidanie/dynomite
static struct mbuf *
_mbuf_get(void)
{
    struct mbuf *mbuf;
    uint8_t *buf;

    //loga("_mbuf_get, nfree_mbufq = %d", nfree_mbufq);

    if (!STAILQ_EMPTY(&free_mbufq)) {
        ASSERT(nfree_mbufq > 0);

        mbuf = STAILQ_FIRST(&free_mbufq);
        nfree_mbufq--;
        STAILQ_REMOVE_HEAD(&free_mbufq, next);

        ASSERT(mbuf->magic == MBUF_MAGIC);
        goto done;
    }

    buf = dn_alloc(mbuf_chunk_size);
    if (buf == NULL) {
        return NULL;
    }
    mbuf_alloc_count++;

    /*
     * mbuf header is at the tail end of the mbuf. This enables us to catch
     * buffer overrun early by asserting on the magic value during get or
     * put operations
     *
     *   <------------- mbuf_chunk_size ------------------------->
     *   +-------------------------------------------------------+
     *   |       mbuf data                      |  mbuf header   |
     *   |     (mbuf_offset)                    | (struct mbuf)  |
     *   +-------------------------------------------------------+
     *   ^           ^        ^      ^          ^^
     *   |           |        |      |          ||
     *   |           |        |      |          \ \mbuf->end_extra (one byte past valid bound)
     *   \           |        |      \           \
     *   mbuf->start \        |      mbuf->end    mbuf
     *             mbuf->pos  |
     *                        \
     *                       mbuf->last (one byte past valid byte)
     *
     */
    mbuf = (struct mbuf *)(buf + mbuf_offset);
    mbuf->magic = MBUF_MAGIC;
    mbuf->chunk_size = mbuf_chunk_size;

done:
    STAILQ_NEXT(mbuf, next) = NULL;
    return mbuf;
}
コード例 #10
0
ファイル: dyn_server.c プロジェクト: kangkot/dynomite
rstatus_t dc_init(struct datacenter *dc)
{
	rstatus_t status;

	dc->dict_rack = dictCreate(&dc_string_dict_type, NULL);
	dc->name = dn_alloc(sizeof(struct string));
	string_init(dc->name);

	status = array_init(&dc->racks, 3, sizeof(struct rack));

	return status;
}
コード例 #11
0
ファイル: dyn_epoll.c プロジェクト: amimimor/dynomite
struct event_base *
event_base_create(int nevent, event_cb_t cb)
{
    struct event_base *evb;
    int status, ep;
    struct epoll_event *event;

    ASSERT(nevent > 0);

    ep = epoll_create(nevent);
    if (ep < 0) {
        log_error("epoll create of size %d failed: %s", nevent, strerror(errno));
        return NULL;
    }

    event = dn_calloc(nevent, sizeof(*event));
    if (event == NULL) {
        status = close(ep);
        if (status < 0) {
            log_error("close e %d failed, ignored: %s", ep, strerror(errno));
        }
        return NULL;
    }

    evb = dn_alloc(sizeof(*evb));
    if (evb == NULL) {
        dn_free(event);
        status = close(ep);
        if (status < 0) {
            log_error("close e %d failed, ignored: %s", ep, strerror(errno));
        }
        return NULL;
    }

    evb->ep = ep;
    evb->event = event;
    evb->nevent = nevent;
    evb->cb = cb;

    log_debug(LOG_INFO, "e %d with nevent %d", evb->ep, evb->nevent);

    return evb;
}
コード例 #12
0
static struct dyn_token *
dnode_peer_pool_hash(struct server_pool *pool, uint8_t *key, uint32_t keylen)
{
	ASSERT(array_n(&pool->peers) != 0);
	ASSERT(key != NULL && keylen != 0);

	struct dyn_token *token = dn_alloc(sizeof(struct dyn_token));
	if (token == NULL) {
		return NULL;
	}
	init_dyn_token(token);

	rstatus_t status = pool->key_hash((char *)key, keylen, token);
	if (status != DN_OK) {
		dn_free(token);
		return NULL;
	}

	return token;
}
コード例 #13
0
ファイル: dyn_mbuf.c プロジェクト: Aidanie/dynomite
//allocate an arbitrary size mbuf for a general purpose operation
struct mbuf *
mbuf_alloc(size_t size)
{
   uint8_t *buf = dn_alloc(size + MBUF_HSIZE);
   if (buf == NULL) {
       return NULL;
   }

   size_t mbuf_offset = size;
   struct mbuf *mbuf = (struct mbuf *)(buf + mbuf_offset);
   mbuf->magic = MBUF_MAGIC;
   mbuf->chunk_size = size;

   STAILQ_NEXT(mbuf, next) = NULL;

   mbuf->start = buf;
   mbuf->end = buf + mbuf_offset - MBUF_ESIZE;
   mbuf->end_extra = buf + mbuf_offset;

   mbuf->pos = mbuf->start;
   mbuf->last = mbuf->start;

   return mbuf;
}
コード例 #14
0
ファイル: dyn_core.c プロジェクト: kangkot/dynomite
static struct context *
core_ctx_create(struct instance *nci)
{
	rstatus_t status;
	struct context *ctx;

	srand((unsigned) time(NULL));

	ctx = dn_alloc(sizeof(*ctx));
	if (ctx == NULL) {
		return NULL;
	}
	ctx->id = ++ctx_id;
	ctx->cf = NULL;
	ctx->stats = NULL;
	ctx->evb = NULL;
	array_null(&ctx->pool);
	ctx->max_timeout = nci->stats_interval;
	ctx->timeout = ctx->max_timeout;
	ctx->dyn_state = INIT;

	/* parse and create configuration */
	ctx->cf = conf_create(nci->conf_filename);
	if (ctx->cf == NULL) {
		loga("Failed to create context!!!");
		dn_free(ctx);
		return NULL;
	}

	/* initialize server pool from configuration */
	status = server_pool_init(&ctx->pool, &ctx->cf->pool, ctx);
	if (status != DN_OK) {
		loga("Failed to initialize server pool!!!");
		conf_destroy(ctx->cf);
		dn_free(ctx);
		return NULL;
	}


	/* crypto init */
    status = crypto_init(ctx);
    if (status != DN_OK) {
   	loga("Failed to initialize crypto!!!");
    	dn_free(ctx);
    	return NULL;
    }


	/* create stats per server pool */
	ctx->stats = stats_create(nci->stats_port, nci->stats_addr, nci->stats_interval,
			                  nci->hostname, &ctx->pool, ctx);
	if (ctx->stats == NULL) {
		loga("Failed to create stats!!!");
		crypto_deinit();
		server_pool_deinit(&ctx->pool);
		conf_destroy(ctx->cf);
		dn_free(ctx);
		return NULL;
	}

	/* initialize event handling for client, proxy and server */
	ctx->evb = event_base_create(EVENT_SIZE, &core_core);
	if (ctx->evb == NULL) {
		loga("Failed to create socket event handling!!!");
		crypto_deinit();
		stats_destroy(ctx->stats);
		server_pool_deinit(&ctx->pool);
		conf_destroy(ctx->cf);
		dn_free(ctx);
		return NULL;
	}

	/* preconnect? servers in server pool */
	status = server_pool_preconnect(ctx);
	if (status != DN_OK) {
		loga("Failed to preconnect for server pool!!!");
		crypto_deinit();
		server_pool_disconnect(ctx);
		event_base_destroy(ctx->evb);
		stats_destroy(ctx->stats);
		server_pool_deinit(&ctx->pool);
		conf_destroy(ctx->cf);
		dn_free(ctx);
		return NULL;
	}

	/* initialize proxy per server pool */
	status = proxy_init(ctx);
	if (status != DN_OK) {
		loga("Failed to initialize proxy!!!");
		crypto_deinit();
		server_pool_disconnect(ctx);
		event_base_destroy(ctx->evb);
		stats_destroy(ctx->stats);
		server_pool_deinit(&ctx->pool);
		conf_destroy(ctx->cf);
		dn_free(ctx);
		return NULL;
	}

	/* initialize dnode listener per server pool */
	status = dnode_init(ctx);
	if (status != DN_OK) {
		loga("Failed to initialize dnode!!!");
		crypto_deinit();
		server_pool_disconnect(ctx);
		event_base_destroy(ctx->evb);
		stats_destroy(ctx->stats);
		server_pool_deinit(&ctx->pool);
		conf_destroy(ctx->cf);
		dn_free(ctx);
		return NULL;
	}

	ctx->dyn_state = JOINING;  //TODOS: change this to JOINING

	/* initialize peers */
	status = dnode_peer_init(&ctx->pool, ctx);
	if (status != DN_OK) {
		loga("Failed to initialize dnode peers!!!");
		crypto_deinit();
		dnode_deinit(ctx);
		server_pool_disconnect(ctx);
		event_base_destroy(ctx->evb);
		stats_destroy(ctx->stats);
		server_pool_deinit(&ctx->pool);
		conf_destroy(ctx->cf);
		dn_free(ctx);
		return NULL;
	}

	core_debug(ctx);

	/* preconntect peers - probably start gossip here */
	status = dnode_peer_pool_preconnect(ctx);
	if (status != DN_OK) {
		loga("Failed to preconnect dnode peers!!!");
		crypto_deinit();
		dnode_peer_deinit(&ctx->pool);
		dnode_deinit(ctx);
		server_pool_disconnect(ctx);
		event_base_destroy(ctx->evb);
		stats_destroy(ctx->stats);
		server_pool_deinit(&ctx->pool);
		conf_destroy(ctx->cf);
		dn_free(ctx);
		return NULL;
	}

	//init ring msg queue
	CBUF_Init(C2G_InQ);
	CBUF_Init(C2G_OutQ);

	//init stats msg queue
	CBUF_Init(C2S_InQ);
	CBUF_Init(C2S_OutQ);

	gossip_pool_init(ctx);

	log_debug(LOG_VVERB, "created ctx %p id %"PRIu32"", ctx, ctx->id);

	return ctx;
}
コード例 #15
0
ファイル: dyn_stats.c プロジェクト: logikal/dynomite
static rstatus_t
stats_create_buf(struct stats *st)
{
    uint32_t int64_max_digits = 20; /* INT64_MAX = 9223372036854775807 */
    uint32_t int32_max_digits = 10; /* INT32_MAX = 4294967294 */
    uint32_t key_value_extra = 8;   /* "key": "value", */
    uint32_t pool_extra = 8;        /* '"pool_name": { ' + ' }' */
    uint32_t server_extra = 8;      /* '"server_name": { ' + ' }' */
    size_t size = 0;
    uint32_t i;

    ASSERT(st->buf.data == NULL && st->buf.size == 0);

    /* header */
    size += 1;

    size += st->service_str.len;
    size += st->service.len;
    size += key_value_extra;

    size += st->source_str.len;
    size += st->source.len;
    size += key_value_extra;

    size += st->version_str.len;
    size += st->version.len;
    size += key_value_extra;

    size += st->uptime_str.len;
    size += int64_max_digits;
    size += key_value_extra;

    size += st->timestamp_str.len;
    size += int64_max_digits;
    size += key_value_extra;

    size += st->rack_str.len;
    size += st->rack.len;
    size += key_value_extra;

    size += st->dc_str.len;
    size += st->dc.len;
    size += key_value_extra;

    size += st->latency_999th_str.len;
    size += int64_max_digits;
    size += key_value_extra;

    size += st->latency_99th_str.len;
    size += int64_max_digits;
    size += key_value_extra;

    size += st->latency_95th_str.len;
    size += int64_max_digits;
    size += key_value_extra;

    size += st->latency_mean_str.len;
    size += int64_max_digits;
    size += key_value_extra;

    size += st->latency_max_str.len;
    size += int64_max_digits;
    size += key_value_extra;


    size += st->payload_size_999th_str.len;
    size += int32_max_digits;
    size += key_value_extra;

    size += st->payload_size_99th_str.len;
    size += int32_max_digits;
    size += key_value_extra;

    size += st->payload_size_95th_str.len;
    size += int32_max_digits;
    size += key_value_extra;

    size += st->payload_size_mean_str.len;
    size += int32_max_digits;
    size += key_value_extra;

    size += st->payload_size_max_str.len;
    size += int32_max_digits;
    size += key_value_extra;

    size += st->alloc_msgs_str.len;
    size += int32_max_digits;
    size += key_value_extra;

    /* server pools */
    for (i = 0; i < array_n(&st->sum); i++) {
        struct stats_pool *stp = array_get(&st->sum, i);
        uint32_t j;

        size += stp->name.len;
        size += pool_extra;

        for (j = 0; j < array_n(&stp->metric); j++) {
            struct stats_metric *stm = array_get(&stp->metric, j);

            size += stm->name.len;
            size += int64_max_digits;
            size += key_value_extra;
        }

        /* servers per pool */
        for (j = 0; j < array_n(&stp->server); j++) {
            struct stats_server *sts = array_get(&stp->server, j);
            uint32_t k;

            size += sts->name.len;
            size += server_extra;

            for (k = 0; k < array_n(&sts->metric); k++) {
                struct stats_metric *stm = array_get(&sts->metric, k);

                size += stm->name.len;
                size += int64_max_digits;
                size += key_value_extra;
            }
        }

    }

    /* footer */
    size += 2;

    size = DN_ALIGN(size, DN_ALIGNMENT);

    st->buf.data = dn_alloc(size);
    if (st->buf.data == NULL) {
        log_error("create stats buffer of size %zu failed: %s", size,
                   strerror(errno));
        return DN_ENOMEM;
    }
    st->buf.size = size;

    log_debug(LOG_DEBUG, "stats buffer size %zu", size);

    return DN_OK;
}
コード例 #16
0
ファイル: dyn_stats.c プロジェクト: logikal/dynomite
struct stats *
stats_create(uint16_t stats_port, char *stats_ip, int stats_interval,
             char *source, struct array *server_pool, struct context *ctx)
{
    rstatus_t status;
    struct stats *st;

    st = dn_alloc(sizeof(*st));
    if (st == NULL) {
        return NULL;
    }

    st->port = stats_port;
    st->interval = stats_interval;
    string_set_raw(&st->addr, stats_ip);

    st->start_ts = (int64_t)time(NULL);

    st->buf.len = 0;
    st->buf.data = NULL;
    st->buf.size = 0;

    array_null(&st->current);
    array_null(&st->shadow);
    array_null(&st->sum);

    st->tid = (pthread_t) -1;
    st->sd = -1;

    string_set_text(&st->service_str, "service");
    string_set_text(&st->service, "dynomite");

    string_set_text(&st->source_str, "source");
    string_set_raw(&st->source, source);

    string_set_text(&st->version_str, "version");
    string_set_text(&st->version, DN_VERSION_STRING);

    string_set_text(&st->uptime_str, "uptime");
    string_set_text(&st->timestamp_str, "timestamp");

    //for latency histo
    string_set_text(&st->latency_999th_str, "latency_999th");
    string_set_text(&st->latency_99th_str, "latency_99th");
    string_set_text(&st->latency_95th_str, "latency_95th");
    string_set_text(&st->latency_mean_str, "latency_mean");
    string_set_text(&st->latency_max_str, "latency_max");

    //for payload size histo
    string_set_text(&st->payload_size_999th_str, "payload_size_999th");
    string_set_text(&st->payload_size_99th_str, "payload_size_99th");
    string_set_text(&st->payload_size_95th_str, "payload_size_95th");
    string_set_text(&st->payload_size_mean_str, "payload_size_mean");
    string_set_text(&st->payload_size_max_str, "payload_size_max");

    string_set_text(&st->alloc_msgs_str, "alloc_msgs");

    //only display the first pool
    struct server_pool *sp = (struct server_pool*) array_get(server_pool, 0);

    string_set_text(&st->rack_str, "rack");

    string_copy(&st->rack, sp->rack.data, sp->rack.len);

    string_set_text(&st->dc_str, "dc");
    string_copy(&st->dc, sp->dc.data, sp->dc.len);

    st->updated = 0;
    st->aggregate = 0;

    histo_init(&st->latency_histo);
    histo_init(&st->payload_size_histo);

    st->alloc_msgs = 0;

    /* map server pool to current (a), shadow (b) and sum (c) */

    status = stats_pool_map(&st->current, server_pool);
    if (status != DN_OK) {
        goto error;
    }

    status = stats_pool_map(&st->shadow, server_pool);
    if (status != DN_OK) {
        goto error;
    }

    status = stats_pool_map(&st->sum, server_pool);
    if (status != DN_OK) {
        goto error;
    }

    status = stats_create_buf(st);
    if (status != DN_OK) {
        goto error;
    }

    status = stats_start_aggregator(st);
    if (status != DN_OK) {
        goto error;
    }

    st->ctx = ctx;
    return st;

error:
    stats_destroy(st);
    return NULL;
}