diff --git a/modules/clusterer/clusterer.c b/modules/clusterer/clusterer.c index 8ebd540002b..464b4a3e453 100644 --- a/modules/clusterer/clusterer.c +++ b/modules/clusterer/clusterer.c @@ -2693,9 +2693,6 @@ int cl_register_cap(str *cap, cl_packet_cb_f packet_cb, cl_event_cb_f event_cb, new_cl_cap->reg.packet_cb = packet_cb; new_cl_cap->reg.event_cb = event_cb; - if (require_sync) - new_cl_cap->flags |= CAP_REQUIRE_SYNC; - if (cluster->current_node->flags & NODE_IS_SEED || !require_sync) new_cl_cap->flags |= CAP_STATE_OK; @@ -2709,40 +2706,45 @@ int cl_register_cap(str *cap, cl_packet_cb_f packet_cb, cl_event_cb_f event_cb, return 0; } -void preserve_reg_caps(cluster_info_t *new_info) +struct local_cap *dup_caps(struct local_cap *caps) +{ + struct local_cap *cap, *ret = NULL; + + for (; caps; caps = caps->next) { + cap = shm_malloc(sizeof *cap); + if (!cap) { + LM_ERR("No more shm memory\n"); + return NULL; + } + memcpy(cap, caps, sizeof *caps); + + cap->next = NULL; + + add_last(cap, ret); + } + + return ret; +} + +int preserve_reg_caps(cluster_info_t *new_info) { cluster_info_t *cl, *new_cl; struct local_cap *cap; - struct buf_bin_pkt *buf_pkt, *tmp; for (cl = *cluster_list; cl; cl = cl->next) for (new_cl = new_info; new_cl; new_cl = new_cl->next) if (new_cl->cluster_id == cl->cluster_id && cl->capabilities) { - new_cl->capabilities = cl->capabilities; - - for (cap = new_cl->capabilities; cap; cap = cap->next) { - if (cap->flags & CAP_STATE_OK) - cap->flags &= ~CAP_STATE_OK; + new_cl->capabilities = dup_caps(cl->capabilities); + if (!new_cl->capabilities) + return -1; - if (new_cl->current_node->flags & NODE_IS_SEED || - !(cap->flags & CAP_REQUIRE_SYNC)) + for (cap = new_cl->capabilities; cap; cap = cap->next) + if (!(cap->flags & CAP_STATE_OK) && + (new_cl->current_node->flags & NODE_IS_SEED)) cap->flags |= CAP_STATE_OK; - - if (cap->flags & CAP_PKT_BUFFERING) { - cap->flags &= ~CAP_PKT_BUFFERING; - - buf_pkt = cap->pkt_q_front; - while (buf_pkt) { - tmp = buf_pkt; - buf_pkt = buf_pkt->next; - shm_free(tmp->buf.s); - shm_free(tmp); - } - cap->pkt_q_front = NULL; - cap->pkt_q_back = NULL; - } - } } + + return 0; } int gen_rcv_evs_init(void) diff --git a/modules/clusterer/clusterer.h b/modules/clusterer/clusterer.h index f5f7cb62fb7..b1453afb4f5 100644 --- a/modules/clusterer/clusterer.h +++ b/modules/clusterer/clusterer.h @@ -51,7 +51,6 @@ #define CAP_STATE_OK (1<<0) #define CAP_SYNC_PENDING (1<<1) #define CAP_PKT_BUFFERING (1<<2) -#define CAP_REQUIRE_SYNC (1<<3) typedef enum { CLUSTERER_PING, CLUSTERER_PONG, @@ -158,8 +157,9 @@ cl_send_all_having(bin_packet_t *packet, int dst_cluster_id, enum cl_node_match_op match_op); int cl_register_cap(str *cap, cl_packet_cb_f packet_cb, cl_event_cb_f event_cb, int cluster_id, int require_sync, enum cl_node_match_op sync_cond); +struct local_cap *dup_caps(struct local_cap *caps); -void preserve_reg_caps(struct cluster_info *new_info); +int preserve_reg_caps(struct cluster_info *new_info); struct mi_root *run_rcv_mi_cmd(str *cmd_name, str *cmd_params, int nr_params); diff --git a/modules/clusterer/clusterer_mod.c b/modules/clusterer/clusterer_mod.c index f52cf104a2f..43648e58bdf 100644 --- a/modules/clusterer/clusterer_mod.c +++ b/modules/clusterer/clusterer_mod.c @@ -456,7 +456,15 @@ static struct mi_root* clusterer_reload(struct mi_root* root, void *param) } lock_start_write(cl_list_lock); - preserve_reg_caps(new_info); + if (preserve_reg_caps(new_info) < 0) { + lock_stop_write(cl_list_lock); + LM_ERR("Failed to preserve registered capabilities\n"); + + if (new_info) + free_info(new_info); + + return init_mi_tree(500, "Failed to reload", 16); + } old_info = *cluster_list; *cluster_list = new_info; lock_stop_write(cl_list_lock);