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; }
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; }
static rstatus_t stats_listen(struct stats *st) { rstatus_t status; struct sockinfo si; status = dn_resolve(&st->addr, st->port, &si); if (status < 0) { return status; } st->sd = socket(si.family, SOCK_STREAM, 0); if (st->sd < 0) { log_error("socket failed: %s", strerror(errno)); return DN_ERROR; } status = dn_set_reuseaddr(st->sd); if (status < 0) { log_error("set reuseaddr on m %d failed: %s", st->sd, strerror(errno)); return DN_ERROR; } status = bind(st->sd, (struct sockaddr *)&si.addr, si.addrlen); if (status < 0) { log_error("bind on m %d to addr '%.*s:%u' failed: %s", st->sd, st->addr.len, st->addr.data, st->port, strerror(errno)); return DN_ERROR; } status = listen(st->sd, SOMAXCONN); if (status < 0) { log_error("listen on m %d failed: %s", st->sd, strerror(errno)); return DN_ERROR; } log_debug(LOG_NOTICE, "m %d listening on '%.*s:%u'", st->sd, st->addr.len, st->addr.data, st->port); return DN_OK; }