struct dnet_node *dnet_server_node_create(struct dnet_config_data *cfg_data) { struct dnet_node *n; struct dnet_config *cfg = &cfg_data->cfg_state; struct dnet_addr *addrs = cfg_data->cfg_addrs; int addr_num = cfg_data->cfg_addr_num; int err = -ENOMEM; sigset_t previous_sigset; sigset_t sigset; sigemptyset(&sigset); sigaddset(&sigset, SIGINT); sigaddset(&sigset, SIGTERM); sigaddset(&sigset, SIGALRM); sigaddset(&sigset, SIGQUIT); pthread_sigmask(SIG_BLOCK, &sigset, &previous_sigset); n = dnet_node_create(cfg); if (!n) goto err_out_exit; n->config_data = cfg_data; err = dnet_server_io_init(n); if (err) goto err_out_node_destroy; err = dnet_monitor_init(n, cfg); if (err) goto err_out_node_destroy; err = dnet_node_check_stack(n); if (err) goto err_out_monitor_destroy; if (!n->notify_hash_size) { n->notify_hash_size = DNET_DEFAULT_NOTIFY_HASH_SIZE; err = dnet_notify_init(n); if (err) goto err_out_monitor_destroy; dnet_log(n, DNET_LOG_NOTICE, "No notify hash size provided, using default %d.", n->notify_hash_size); } err = dnet_local_addr_add(n, addrs, addr_num); if (err) goto err_out_notify_exit; if (cfg->flags & DNET_CFG_JOIN_NETWORK) { int s; struct dnet_addr la; err = dnet_locks_init(n, 1024); if (err) { dnet_log(n, DNET_LOG_ERROR, "failed to init locks: %s %d", strerror(-err), err); goto err_out_addr_cleanup; } n->route = dnet_route_list_create(n); if (!n->route) { dnet_log(n, DNET_LOG_ERROR, "failed to create route list: %s %d", strerror(-err), err); goto err_out_locks_destroy; } err = dnet_create_addr(&la, NULL, cfg->port, cfg->family); if (err < 0) { dnet_log(n, DNET_LOG_ERROR, "Failed to get address info for 0.0.0.0:%d, family: %d, err: %d: %s.", cfg->port, cfg->family, err, strerror(-err)); goto err_out_route_list_destroy; } err = dnet_socket_create_listening(n, &la); if (err < 0) goto err_out_route_list_destroy; s = err; if (s < 0) { err = s; dnet_log(n, DNET_LOG_ERROR, "failed to create socket: %s %d", strerror(-err), err); goto err_out_route_list_destroy; } n->st = dnet_state_create(n, NULL, 0, n->addrs, s, &err, DNET_JOIN, 1, 0, 1, n->addrs, n->addr_num); if (!n->st) { dnet_log(n, DNET_LOG_ERROR, "failed to create state: %s %d", strerror(-err), err); goto err_out_state_destroy; } // @dnet_state_create() returns state pointer which holds 2 references - one for originally created state // and another for caller in case he wants to do something with the state. The first reference is owned // by network thread given state was attached to, and it can already release it. dnet_state_put(n->st); err = dnet_backend_init_all(n); if (err) { dnet_log(n, DNET_LOG_ERROR, "failed to init backends: %s %d", strerror(-err), err); goto err_out_state_destroy; } if (!cfg->srw.config) { dnet_log(n, DNET_LOG_INFO, "srw: no config"); n->srw = NULL; } else { err = dnet_srw_init(n, cfg); if (err) { dnet_log(n, DNET_LOG_ERROR, "srw: initialization failure: %s %d", strerror(-err), err); goto err_out_backends_cleanup; } } } dnet_log(n, DNET_LOG_DEBUG, "New server node has been created at port %d.", cfg->port); pthread_sigmask(SIG_SETMASK, &previous_sigset, NULL); return n; dnet_srw_cleanup(n); err_out_backends_cleanup: dnet_set_need_exit(n); dnet_backend_cleanup_all(n); err_out_state_destroy: dnet_state_put(n->st); err_out_route_list_destroy: dnet_route_list_destroy(n->route); err_out_locks_destroy: dnet_locks_destroy(n); err_out_addr_cleanup: dnet_local_addr_cleanup(n); err_out_notify_exit: n->need_exit = err; dnet_notify_exit(n); err_out_monitor_destroy: dnet_monitor_exit(n); err_out_node_destroy: dnet_node_destroy(n); err_out_exit: pthread_sigmask(SIG_SETMASK, &previous_sigset, NULL); return NULL; }
struct dnet_node *dnet_server_node_create(struct dnet_config_data *cfg_data) { struct dnet_node *n; struct dnet_raw_id *ids = NULL; int id_num = 0; struct dnet_config *cfg = &cfg_data->cfg_state; struct dnet_addr *addrs = cfg_data->cfg_addrs; int addr_num = cfg_data->cfg_addr_num; int err = -ENOMEM; sigset_t previous_sigset; sigset_t sigset; sigemptyset(&sigset); sigaddset(&sigset, SIGINT); sigaddset(&sigset, SIGTERM); sigaddset(&sigset, SIGALRM); sigaddset(&sigset, SIGQUIT); pthread_sigmask(SIG_BLOCK, &sigset, &previous_sigset); n = dnet_node_create(cfg); if (!n) goto err_out_exit; n->config_data = cfg_data; err = dnet_monitor_init(&n->monitor, cfg); if (err) goto err_out_node_destroy; dnet_monitor_init_io_stat_provider(n); dnet_monitor_init_react_stat_provider(n); err = dnet_node_check_stack(n); if (err) goto err_out_monitor_destroy; if (!n->notify_hash_size) { n->notify_hash_size = DNET_DEFAULT_NOTIFY_HASH_SIZE; err = dnet_notify_init(n); if (err) goto err_out_monitor_destroy; dnet_log(n, DNET_LOG_NOTICE, "No notify hash size provided, using default %d.\n", n->notify_hash_size); } err = dnet_backend_stat_provider_init(n); if (err) goto err_out_notify_exit; err = dnet_cache_init(n); if (err) goto err_out_backend_stat_provider_exit; err = dnet_local_addr_add(n, addrs, addr_num); if (err) goto err_out_cache_cleanup; if (cfg->flags & DNET_CFG_JOIN_NETWORK) { int s; struct dnet_addr la; struct dnet_addr_socket *socket; err = dnet_locks_init(n, 1024); if (err) goto err_out_addr_cleanup; ids = dnet_ids_init(n, cfg->history_env, &id_num, cfg->storage_free, cfg_data->cfg_addrs, cfg_data->cfg_remotes); if (!ids) goto err_out_locks_destroy; err = dnet_create_addr(&la, NULL, cfg->port, cfg->family); if (err < 0) { dnet_log(n, DNET_LOG_ERROR, "Failed to get address info for 0.0.0.0:%d, family: %d, err: %d: %s.\n", cfg->port, cfg->family, err, strerror(-err)); goto err_out_ids_cleanup; } err = dnet_socket_create(n, &la, &socket, 1, 1); if (err < 0) goto err_out_ids_cleanup; s = socket->s; free(socket); if (s < 0) { err = s; goto err_out_ids_cleanup; } dnet_setup_id(&n->id, cfg->group_id, ids[0].id); n->st = dnet_state_create(n, cfg->group_id, ids, id_num, &la, s, &err, DNET_JOIN, -1, dnet_state_accept_process); if (!n->st) { goto err_out_state_destroy; } free(ids); ids = NULL; if (!cfg->srw.config) { dnet_log(n, DNET_LOG_INFO, "srw: no config\n"); n->srw = NULL; } else { err = dnet_srw_init(n, cfg); if (err) { dnet_log(n, DNET_LOG_ERROR, "srw: initialization failure: %s %d\n", strerror(-err), err); goto err_out_state_destroy; } } } dnet_log(n, DNET_LOG_DEBUG, "New server node has been created at port %d, ids: %d.\n", cfg->port, id_num); pthread_sigmask(SIG_SETMASK, &previous_sigset, NULL); return n; dnet_srw_cleanup(n); err_out_state_destroy: dnet_state_put(n->st); err_out_ids_cleanup: free(ids); err_out_locks_destroy: dnet_locks_destroy(n); err_out_addr_cleanup: dnet_local_addr_cleanup(n); err_out_cache_cleanup: n->need_exit = err; dnet_cache_cleanup(n); err_out_backend_stat_provider_exit: err_out_notify_exit: dnet_notify_exit(n); err_out_monitor_destroy: dnet_monitor_exit(n); err_out_node_destroy: dnet_node_destroy(n); err_out_exit: pthread_sigmask(SIG_SETMASK, &previous_sigset, NULL); return NULL; }