/* * Copy n bytes from memory area pos to mbuf. * * The memory areas should not overlap and the mbuf should have * enough space for n bytes. */ void mbuf_copy(struct mbuf *mbuf, uint8_t *pos, size_t n) { if (n == 0) { return; } /* mbuf has space for n bytes */ ASSERT(!mbuf_full(mbuf) && n <= mbuf_size(mbuf)); /* no overlapping copy */ ASSERT(pos < mbuf->start || pos >= mbuf->end); dn_memcpy(mbuf->last, pos, n); mbuf->last += n; }
static rstatus_t gossip_forward_state(struct server_pool *sp) { //assume each record needs maximum 256 bytes struct ring_msg *msg = create_ring_msg_with_data(256 * node_count); uint8_t *data = msg->data; //dn_zalloc(sizeof(uint8_t) * 256 * node_count);//msg->data; uint8_t *pos = data; dictIterator *dc_it; dictEntry *dc_de; dc_it = dictGetIterator(gn_pool.dict_dc); while ((dc_de = dictNext(dc_it)) != NULL) { struct gossip_dc *g_dc = dictGetVal(dc_de); //log_debug(LOG_VERB, "\tDC name : '%.*s'", g_dc->name.len, g_dc->name.data); dictIterator *rack_it = dictGetIterator(g_dc->dict_rack); dictEntry *rack_de; while ((rack_de = dictNext(rack_it)) != NULL) { struct gossip_rack *g_rack = dictGetVal(rack_de); //log_debug(LOG_VERB, "\tRack name : '%.*s'", g_rack->name.len, g_rack->name.data); dictIterator *node_it = dictGetIterator(g_rack->dict_token_nodes); dictEntry *node_de; int i = 0; while ((node_de = dictNext(node_it)) != NULL) { struct node *gnode = dictGetVal(node_de); //log_debug(LOG_VERB, "\tNode name : '%.*s'", gnode->name.len, gnode->name.data); if (i++ > 0) { //pipe separator *pos = '|'; pos += 1; } //write dc name dn_memcpy(pos, g_dc->name.data, g_dc->name.len); pos += g_dc->name.len; //$ separator *pos = '$'; pos += 1; //write rack name dn_memcpy(pos, g_rack->name.data, g_rack->name.len); pos += g_rack->name.len; //$ separator *pos = '$'; pos += 1; //write node token struct string *token_str = dictGetKey(node_de); //log_debug(LOG_VERB, "\tToken string : '%.*s'", token_str->len, token_str->data); int k; for(k=0; k<token_str->len;k++, pos++) { *pos = *(token_str->data + k); } //comma separator *pos = ','; pos += 1; //write ts int count = 0; uint64_t ts; if (gnode->is_local) //only update my own timestamp ts = (uint64_t) time(NULL); else ts = gnode->ts; count = 0; write_number(pos, ts, &count); pos += count; //comma separator *pos = ','; pos += 1; //write state uint8_t new_state = gossip_failure_detector(gnode); gnode->state = new_state; count = 0; write_number(pos, gnode->state, &count); pos += count; //comma separator *pos = ','; pos += 1; //write addresss for(k=0; k<gnode->name.len; k++, pos++) { *pos = *(gnode->name.data + k); } } dictReleaseIterator(node_it); } dictReleaseIterator(rack_it); } msg->len = pos-data; log_debug(LOG_VERB, "\tForwarding my current gossip states : '%.*s'", (pos-data), data); dictReleaseIterator(dc_it); return gossip_ring_msg_to_core(sp, msg, dnode_peer_forward_state); }