From 9ccc1fb58b8e77dc766c79cb93d7ad4bd5928cf2 Mon Sep 17 00:00:00 2001 From: tallicamike Date: Mon, 3 Nov 2014 18:14:36 +0200 Subject: [PATCH] [qrouting] QR aware of DR partitions; qr_status modified to recognize partitions --- modules/drouting/dr_cb.c | 2 +- modules/drouting/dr_load.c | 4 +- modules/drouting/dr_load.h | 3 +- modules/drouting/dr_sorting_cbs.h | 14 +- modules/drouting/drouting.c | 52 ++++--- modules/drouting/routing.c | 8 +- modules/drouting/routing.h | 4 +- modules/qrouting/qr_stats.c | 97 ++++++++++--- modules/qrouting/qr_stats.h | 13 +- modules/qrouting/qrouting.c | 219 ++++++++++++++++++++---------- 10 files changed, 297 insertions(+), 119 deletions(-) diff --git a/modules/drouting/dr_cb.c b/modules/drouting/dr_cb.c index 48fc4f6028..4a1fbbea56 100644 --- a/modules/drouting/dr_cb.c +++ b/modules/drouting/dr_cb.c @@ -176,7 +176,7 @@ int register_dr_cb(enum drcb_types type, dr_cb f, void *param, } else if(types & (DRCB_REG_INIT_RULE | DRCB_REG_GW | DRCB_REG_CR | DRCB_REG_ADD_RULE | DRCB_REG_MARK_AS_RULE_LIST | DRCB_REG_LINK_LISTS - | DRCB_REG_FREE_LIST)) { + | DRCB_REG_FREE_LIST | DRCB_REG_CREATE_PARTS_LIST)) { if(insert_drcb(&dr_reg_cbs, cb, types) == -1) goto error; } else if(types & (DRCB_SET_PROFILE)) { diff --git a/modules/drouting/dr_load.c b/modules/drouting/dr_load.c index 06e5e4a980..7a0ebdb212 100644 --- a/modules/drouting/dr_load.c +++ b/modules/drouting/dr_load.c @@ -305,7 +305,7 @@ void dr_update_head_cache(struct head_db *head) */ rt_data_t* dr_load_routing_info(struct head_db *current_partition - , int persistent_state, void **part_rule_list) + , int persistent_state, void *qr_parts, int part_index, str part_name) { int int_vals[5]; char * str_vals[7]; @@ -728,7 +728,7 @@ rt_data_t* dr_load_routing_info(struct head_db *current_partition str_vals[STR_VALS_SORT_ALG_DRR_COL], int_vals[INT_VALS_SORT_PROFILE_DRR_COL], str_vals[STR_VALS_ATTRS_DRR_COL], rdata, - part_rule_list, + qr_parts, part_index, part_name, current_partition->malloc, current_partition->free))== 0 ) { LM_ERR("failed to add routing info for rule id %d -> " diff --git a/modules/drouting/dr_load.h b/modules/drouting/dr_load.h index 09ccf22c11..b0792142a3 100644 --- a/modules/drouting/dr_load.h +++ b/modules/drouting/dr_load.h @@ -37,6 +37,7 @@ #include "routing.h" void dr_update_head_cache(struct head_db *head); -rt_data_t* dr_load_routing_info(struct head_db * ,int persistent_state, void** part_rule_list); +rt_data_t* dr_load_routing_info(struct head_db * ,int persistent_state, + void* qr_parts, int part_index, str part_name); #endif diff --git a/modules/drouting/dr_sorting_cbs.h b/modules/drouting/dr_sorting_cbs.h index 2358367757..8021693f83 100644 --- a/modules/drouting/dr_sorting_cbs.h +++ b/modules/drouting/dr_sorting_cbs.h @@ -43,6 +43,7 @@ #define DRCB_REG_MARK_AS_RULE_LIST (1<<7) #define DRCB_REG_LINK_LISTS (1<<8) #define DRCB_REG_FREE_LIST (1<<9) +#define DRCB_REG_CREATE_PARTS_LIST (1<<10) /* create a qr partitions list */ struct dr_head_cbl *dr_reg_cbs, *dr_acc_cbs, *dr_set_profile_cbs; @@ -96,8 +97,10 @@ struct dr_set_profile_params { }; struct dr_add_rule_params { + int part_index; /* partition index */ + str part_name; void *qr_rule; /* rule to be added to list */ - void **rule_list; /* the list to which the rule will be added */ + void *qr_parts; /* the partitions list to which the rule will be added */ }; struct dr_link_rule_list_params { @@ -106,14 +109,19 @@ struct dr_link_rule_list_params { }; struct dr_mark_as_main_list_params{ - void *new_list; /* list to become qr rules list */ - void **old_list; /* old list: to be freed */ + void *qr_parts_new_list; /* list to become qr rules list */ + void **qr_parts_old_list; /* old list: to be freed */ }; struct dr_free_qr_list_params { void *old_list; }; +struct dr_create_partition_list_params { + void **part_list; /* the list of partitions created at QR returned for DR */ + int n_parts; /* the number of partitions:provided by dr */ +}; + #endif diff --git a/modules/drouting/drouting.c b/modules/drouting/drouting.c index a677715cad..b71790b988 100644 --- a/modules/drouting/drouting.c +++ b/modules/drouting/drouting.c @@ -176,7 +176,10 @@ static struct head_config { str rule_attrs_avp_spec; /* extracted from database - has default value */ str carrier_attrs_avp_spec; /* extracted from database - has default value */ struct head_config *next; -}* head_start = NULL; +}* head_start = NULL,* head_end = NULL; +int *n_partitions; /* the number of partitions accepted by modules init */ + +struct head_db * head_db_start = NULL,* head_db_end = NULL; struct head_db * head_db_start = NULL; @@ -960,7 +963,7 @@ static void dr_state_timer(unsigned int ticks, void* param) */ static inline int dr_reload_data_head( struct head_db *hd, - void **part_rule_list ) + void *qr_parts, int part_index, str part_name) { rt_data_t *new_data; rt_data_t *old_data; @@ -990,7 +993,8 @@ static inline int dr_reload_data_head( struct head_db *hd, } LM_INFO("loading drouting data!\n"); - new_data = dr_load_routing_info(hd, dr_persistent_state, part_rule_list); + new_data = dr_load_routing_info(hd, dr_persistent_state, qr_parts, + part_index, part_name); if ( new_data==0 ) { LM_CRIT("failed to load routing info\n"); goto error; @@ -1069,36 +1073,37 @@ static inline int dr_reload_data_head( struct head_db *hd, static inline int dr_reload_data(int initial) { struct head_db * it_head_db; int ret_val = 0; - void *qr_main_list = NULL; - struct dr_link_rule_list_params *link_lists_param; - void *part_rule_list = NULL; - void *old_list = NULL; + void *old_list = NULL; /* list to be freed */ + void *qr_parts_data = NULL; /* all the partitions */ + int part_index; struct dr_mark_as_main_list_params * mark_as_main_list; struct dr_free_qr_list_params *free_list_params; + struct dr_create_partition_list_params *create_parts_list_params; - link_lists_param = (struct dr_link_rule_list_params*)pkg_malloc( - sizeof(struct dr_link_rule_list_params)); - if(link_lists_param == NULL) { - LM_ERR("No more pkg memory"); + + create_parts_list_params = (struct dr_create_partition_list_params*) + pkg_malloc(sizeof(struct dr_create_partition_list_params)); + + if(create_parts_list_params == NULL) { + LM_ERR("no more pkg memory"); ret_val = -1; } - link_lists_param->first_list = &qr_main_list; + create_parts_list_params->part_list = &qr_parts_data; + create_parts_list_params->n_parts = *n_partitions; + run_callbacks(dr_reg_cbs, DRCB_REG_CREATE_PARTS_LIST, + create_parts_list_params ); /* create the QR list for + all the partitions */ /* TODO will atomize operations under lock (rt_info_t vector) */ lock_start_write(reload_lock); for( it_head_db=head_db_start; it_head_db!=NULL; it_head_db=it_head_db->next ) { - if( dr_reload_data_head(it_head_db, initial, &part_rule_list)!=0 ) + if( dr_reload_data_head(it_head_db, initial, qr_parts_data, part_index, + it_head_db->partition)!=0 ) ret_val = -1; - link_lists_param->second_list = part_rule_list; - - run_callbacks(dr_reg_cbs, DRCB_REG_LINK_LISTS, - (void*)link_lists_param); /* link the lists for the partitions */ } - pkg_free(link_lists_param); - mark_as_main_list = (struct dr_mark_as_main_list_params*) pkg_malloc(sizeof(struct dr_mark_as_main_list_params)); @@ -1107,8 +1112,8 @@ static inline int dr_reload_data(int initial) { ret_val = -1; /* TODO */ } /* TODO: only this should be under lock */ - mark_as_main_list->new_list = qr_main_list; - mark_as_main_list->old_list = &old_list; + mark_as_main_list->qr_parts_new_list = qr_parts_data; + mark_as_main_list->qr_parts_old_list = &old_list; /* make the new list the main list used by the QR */ run_callbacks(dr_reg_cbs, DRCB_REG_MARK_AS_RULE_LIST, mark_as_main_list); lock_stop_write(reload_lock); @@ -1442,6 +1447,8 @@ static int dr_init(void) if(reload_lock == NULL) { LM_ERR("failed to init rw lock for dr_reload\n"); } + n_partitions = (int*)shm_malloc(sizeof(int)); + *n_partitions = 0; drd_table.len = strlen(drd_table.s); drg_table.len = strlen(drg_table.s); @@ -2092,6 +2099,7 @@ mi_response_t *dr_reload_cmd_1(const mi_params_t *params, { struct head_db * part; mi_response_t *resp; + str x; void *rule_list; LM_INFO("dr_reload MI command received!\n"); @@ -2100,7 +2108,7 @@ mi_response_t *dr_reload_cmd_1(const mi_params_t *params, if (resp) return resp; - if( dr_reload_data_head(part, 0, &rule_list)<0 ) { + if( dr_reload_data_head(part, 0, &rule_list, 0, x)<0 ) { LM_CRIT("Failed to load data head\n"); return init_mi_error(500, MI_SSTR("Failed to reload")); } diff --git a/modules/drouting/routing.c b/modules/drouting/routing.c index 49af8fbc2d..23490f3c1c 100644 --- a/modules/drouting/routing.c +++ b/modules/drouting/routing.c @@ -341,7 +341,9 @@ build_rt_info( int sort_profile, char* attrs, rt_data_t* rd, - void **qr_rule_list, + void *qr_parts_data, + int part_index, + str part_name, osips_malloc_f mf, osips_free_f ff ) @@ -488,7 +490,9 @@ build_rt_info( } add_rule_params->qr_rule = qr_rule; - add_rule_params->rule_list = qr_rule_list; + add_rule_params->qr_parts = qr_parts_data; + add_rule_params->part_name = part_name; + add_rule_params->part_index = part_index; run_callbacks(dr_reg_cbs, DRCB_REG_ADD_RULE, add_rule_params); pkg_free(add_rule_params); } diff --git a/modules/drouting/routing.h b/modules/drouting/routing.h index 467a5486d9..e27204eeb3 100644 --- a/modules/drouting/routing.h +++ b/modules/drouting/routing.h @@ -142,7 +142,9 @@ build_rt_info( int sort_profile, char* attr, rt_data_t* rd, - void **qr_rule_list, + void *qr_parts, + int part_index, + str part_name, osips_malloc_f mf, osips_free_f ff ); diff --git a/modules/qrouting/qr_stats.c b/modules/qrouting/qr_stats.c index c9dab233d1..c57608d934 100644 --- a/modules/qrouting/qr_stats.c +++ b/modules/qrouting/qr_stats.c @@ -178,18 +178,27 @@ void qr_free_rule(qr_rule_t *rule) { } -void free_qr_list(qr_rule_t *list) { +void free_qr_list(qr_partitions_t *qr_parts) { qr_rule_t * rule_it, *next; + int i; - /* free the rules from the given list */ - rule_it = list; - - while(rule_it != NULL) { - next = rule_it->next; - qr_free_rule(rule_it); - rule_it->next = NULL; - rule_it = next; + if(qr_parts == NULL) { + return ; + } + for(i = 0; i < qr_parts->n_parts; i++) { + rule_it = qr_parts->qr_rules_start[i]; + /* free the rules from the given list */ + while(rule_it != NULL) { + next = rule_it->next; + qr_free_rule(rule_it); + rule_it->next = NULL; + rule_it = next; + } } + if(qr_parts->rw_lock != NULL) + lock_destroy_rw(qr_parts->rw_lock); + shm_free(qr_parts->qr_rules_start); + shm_free(qr_parts); } @@ -198,7 +207,7 @@ void free_qr_cb(int type, struct dr_cb_params *param) { *param->param; LM_DBG("freeing the old rules...\n"); - qr_rule_t * old_list = free_params->old_list; + qr_partitions_t * old_list = free_params->old_list; free_qr_list(old_list); } @@ -283,21 +292,74 @@ void qr_dst_is_grp(int type, struct dr_cb_params *params) { shm_free(rule->dest[n_dst].dst.grp.gw); } +void qr_create_partition_list(int type, struct dr_cb_params *param) { + struct dr_create_partition_list_params *partition_list_params; + partition_list_params = (struct dr_create_partition_list_params*)*param->param; + qr_partitions_t **part_list = + (qr_partitions_t**)partition_list_params->part_list; + int n_partitions = partition_list_params->n_parts; + + *part_list = (qr_partitions_t*)shm_malloc(sizeof(qr_partitions_t)); + memset(*part_list, 0, sizeof(qr_partitions_t)); + if (part_list == NULL) { + LM_ERR("no more shm memory"); + return; + } + if(((*part_list)->rw_lock = lock_init_rw()) == NULL) { + LM_ERR("failed to init rw lock"); + goto error; + } + (*part_list)->qr_rules_start = (qr_rule_t**)shm_malloc( + n_partitions * sizeof(qr_rule_t*)); + if((*part_list)->qr_rules_start == NULL) { + LM_ERR("no more shm memory"); + goto error; + } + + (*part_list)->part_name = (str*)shm_malloc(n_partitions*sizeof(str)); + (*part_list)->n_parts = n_partitions; + + memset((*part_list)->part_name, 0, n_partitions*sizeof(str)); + memset((*part_list)->qr_rules_start, 0,n_partitions*sizeof(qr_rule_t*)); + + return ; +error: + if((*part_list)->rw_lock != NULL) { + lock_destroy_rw((*part_list)->rw_lock); + + } + + if((*part_list)->qr_rules_start) { + shm_free((*part_list)->qr_rules_start); + } + + if(part_list != NULL) { + shm_free(part_list); + part_list = NULL; + } + +} + /* add rule to list. if the list is NULL a new list is created */ void qr_add_rule_to_list(int type, struct dr_cb_params * param) { struct dr_add_rule_params *add_rule_params = (struct dr_add_rule_params*)*param->param; - qr_rule_t **rule_list = (qr_rule_t**)add_rule_params->rule_list; + qr_partitions_t *qr_parts = (qr_partitions_t*)add_rule_params->qr_parts; qr_rule_t *new = add_rule_params->qr_rule; + int part_index = add_rule_params->part_index; + qr_rule_t **rule_list = &qr_parts->qr_rules_start[part_index]; + str part_name = add_rule_params->part_name; if(new != NULL) { if(*rule_list == NULL) { *rule_list = new; + qr_parts->part_name[part_index] = part_name; } else { new->next = *rule_list; *rule_list = new; } - LM_DBG("rule '%d' added to qr rule list \n", new->r_id); + LM_DBG("rule '%d' added to qr rule list for partition index '%d' \n", + new->r_id, part_index); } } @@ -307,11 +369,14 @@ void qr_add_rule_to_list(int type, struct dr_cb_params * param) { void qr_mark_as_main_list(int type, struct dr_cb_params * param) { struct dr_mark_as_main_list_params * mark_as_main_list = (struct dr_mark_as_main_list_params*) *param->param; - qr_rule_t *rule_list = (qr_rule_t*)mark_as_main_list->new_list; + qr_partitions_t *qr_parts_new = (qr_partitions_t*)mark_as_main_list + ->qr_parts_new_list; LM_DBG("Mark main QR rule list\n"); - *mark_as_main_list->old_list = *qr_rules_start; /* save old list so it can be freed */ - *qr_rules_start = rule_list; /* the new list that the QR will work with */ + *mark_as_main_list->qr_parts_old_list = *qr_main_list; /* save old list so it can be freed */ + lock_start_write(*rw_lock_qr); + *qr_main_list = qr_parts_new; /* the new list that the QR will work with */ + lock_stop_write(*rw_lock_qr); } /* copy link two rule lists together => used for dr_reload and partitions @@ -328,7 +393,7 @@ void qr_link_rule_list(int type, struct dr_cb_params *param) { } else { for(rule_it = *first_list; rule_it->next != NULL; rule_it = rule_it->next) { /* go to the last rule from the first - list */ + list */ } rule_it->next = second_list; /* link it to the second list */ } diff --git a/modules/qrouting/qr_stats.h b/modules/qrouting/qr_stats.h index d7eaf95f09..09c1f9488f 100644 --- a/modules/qrouting/qr_stats.h +++ b/modules/qrouting/qr_stats.h @@ -127,9 +127,19 @@ typedef struct qr_rule { struct qr_rule *next; } qr_rule_t; +typedef struct qr_partitions { + qr_rule_t **qr_rules_start; /* an array of partition - each partition + contains rules */ + int n_parts; /* the number of partitions */ + str *part_name; + rw_lock_t *rw_lock; /* protect the partitions for reloading */ +}qr_partitions_t; + extern qr_rule_t ** qr_rules_start; /* used when updating statistics */ +extern rw_lock_t ** rw_lock_qr; extern qr_thresholds_t **qr_profiles;/* profiles from db */ extern int *n_qr_profiles; /* the number of profiles from db */ +extern qr_partitions_t **qr_main_list; qr_gw_t * qr_create_gw(void *); void qr_free_gw(qr_gw_t *); @@ -141,8 +151,9 @@ void qr_dst_is_gw(int type, struct dr_cb_params *param); void qr_search_profile(int type, struct dr_cb_params *param); void qr_mark_as_main_list(int type, struct dr_cb_params * param); void qr_link_rule_list(int type, struct dr_cb_params *param); +void qr_create_partition_list(int type, struct dr_cb_params *param); void free_qr_cb(int type, struct dr_cb_params *param); -void free_qr_list(qr_rule_t *list); +void free_qr_list(qr_partitions_t *qr_parts); #endif diff --git a/modules/qrouting/qrouting.c b/modules/qrouting/qrouting.c index 0dce5ad5e9..70de7d6118 100644 --- a/modules/qrouting/qrouting.c +++ b/modules/qrouting/qrouting.c @@ -45,11 +45,12 @@ #define MAX_HISTORY 1000 /* TODO:*/ /* modparam */ -rw_lock_t **rw_lock_qr; +rw_lock_t **rw_lock_qr; /* used to protect the qr_main_list */ static int history = 30; /* the history span in minutes */ static int sampling_interval = 5; /* the sampling interval in seconds */ str db_url; int *n_qr_profiles = 0; +qr_partitions_t **qr_main_list; /* the history itself */ qr_thresholds_t **qr_profiles = 0; int * qr_n; int * n_sampled; @@ -113,12 +114,22 @@ static int qr_init(void){ db_func_t qr_dbf; db_con_t *qr_db_hdl = 0; + /* TODO: should become obsolete */ /* lock to protect from reloading */ rw_lock_qr = (rw_lock_t**)shm_malloc(sizeof(rw_lock_t*)); if ((*rw_lock_qr = lock_init_rw()) == NULL) { LM_ERR("failed to init rw lock\n"); } + qr_main_list = (qr_partitions_t**)shm_malloc(sizeof(qr_partitions_t*)); + + if(qr_main_list == NULL) { + LM_ERR("no more shm memory\n"); + return -1; + } + + *qr_main_list = NULL; /* mark main list as empty */ + register_timer_process(T_PROC_LABEL, (void*)timer_func, NULL, sampling_interval, 0); @@ -233,6 +244,12 @@ static int qr_init(void){ return -1; } + if(drb.register_drcb(DRCB_REG_CREATE_PARTS_LIST, &qr_create_partition_list, + NULL, NULL) < 0) { + LM_ERR("[QR] failed to register DRCB_REG_CREATE_PARTS_LIST callback to DR\n"); + return -1; + } + LM_DBG("[QR] callbacks in DR were registered\n"); qr_profiles = (qr_thresholds_t**) shm_malloc(sizeof(qr_thresholds_t *)); @@ -288,7 +305,7 @@ static int qr_child_init(int rank) { } static int qr_exit(void) { - free_qr_list(*qr_rules_start); + free_qr_list(*qr_main_list); /* free the thresholds */ *n_qr_profiles = 0; @@ -301,29 +318,37 @@ static int qr_exit(void) { static void timer_func(void) { qr_rule_t *it; - int i; + int i, j; if(*n_sampled < *qr_n) { ++(*n_sampled); /* the number of intervals sampled */ } - for(it = *qr_rules_start; it != NULL; it = it->next) { - for(i = 0; i < it->n; i++) { - if(it->dest[i].type == QR_DST_GW) { - update_gw_stats(it->dest[i].dst.gw); - } else { - update_grp_stats(it->dest[i].dst.grp); + + lock_start_read(*rw_lock_qr); + if(*qr_main_list != NULL) { /* if there is a list */ + for(j = 0; j < (*qr_main_list)->n_parts; j++) { /* for every partition */ + for(it = (*qr_main_list)->qr_rules_start[j]; + it != NULL; it = it->next) { /* for every rule */ + for(i = 0; i < it->n; i++) { /* for every destination */ + if(it->dest[i].type == QR_DST_GW) { + update_gw_stats(it->dest[i].dst.gw); + } else { + update_grp_stats(it->dest[i].dst.grp); + } + } } } } + lock_stop_read(*rw_lock_qr); } /* searches for a given rule in the QR list */ -static qr_rule_t * qr_search_rule(int r_id) { +static qr_rule_t * qr_search_rule(qr_rule_t *list, int r_id) { qr_rule_t * rule_it; - for(rule_it = *qr_rules_start; rule_it != NULL; rule_it = rule_it->next) { + for(rule_it = list; rule_it != NULL; rule_it = rule_it->next) { if(rule_it->r_id == r_id) { return rule_it; } @@ -331,6 +356,19 @@ static qr_rule_t * qr_search_rule(int r_id) { return NULL; } +/* returns the linked list of rules for a certain partition */ +static qr_rule_t * qr_search_partition(str part_name) { + int i; + for(i = 0; i < (*qr_main_list)->n_parts; i++) { + if(part_name.len == (*qr_main_list)->part_name[i].len && + memcmp(part_name.s, (*qr_main_list)->part_name[i].s, + part_name.len) == 0){ + return (*qr_main_list)->qr_rules_start[i]; + } + } + return NULL; +} + static str * qr_get_dst_name(qr_dst_t * dst) { if(dst->type == QR_DST_GW) { return drb.get_gw_name(dst->dst.gw->dr_gw); @@ -409,11 +447,11 @@ static void qr_gw_attr(struct mi_node **node, qr_gw_t *gw) { *node = NULL; } -static void qr_grp_attr(struct mi_node **node, qr_grp_t * grp) { +static void qr_grp_attr(struct mi_node **node, qr_grp_t * grp, str *group_name) { int i; struct mi_node *gw_node; - gw_node = add_mi_node_child(*node, 0, "Group", 5, "group_name", - strlen("group_name")); + gw_node = add_mi_node_child(*node, 0, "Group", 5, group_name->s, + group_name->len); if(*node == NULL) goto error; for(i = 0; in; i++) { @@ -432,21 +470,23 @@ static void qr_dst_attr(struct mi_node ** node, qr_dst_t * dst) { if(dst->type == QR_DST_GW) { qr_gw_attr(node, dst->dst.gw); } else { - qr_grp_attr(node, &dst->dst.grp); + qr_grp_attr(node, &dst->dst.grp, qr_get_dst_name(dst)); } } - static struct mi_root* qr_status_cmd(struct mi_root *cmd_tree, void *param) { /* TODO protected from adding */ - int i; + int i,j; qr_rule_t *rule_it, *rule; qr_dst_t *dst; - str rule_name, gw_name, error_str; + str part_name, rule_name, gw_name, error_str; unsigned int rule_id; - struct mi_node * node = NULL, *rule_node = NULL; + qr_rule_t * qr_part; + struct mi_node * node = NULL, *rule_node = NULL, *partition_node = NULL; struct mi_root *rpl_tree = NULL, *error_tree = NULL; + memset(&part_name, 0, sizeof(str)); + LM_INFO("qr_status command received\n"); @@ -462,70 +502,109 @@ static struct mi_root* qr_status_cmd(struct mi_root *cmd_tree, void *param) { rpl_tree->node.flags |= MI_IS_ARRAY; if(node == NULL) { /* mi_tree with all the destinations (and rules) */ - for(rule_it = *qr_rules_start; rule_it != NULL; rule_it = rule_it->next) { - LM_INFO("RULE#INFO\n"); - if(rule_it->r_id != 0) { /* TODO: maybe -1 */ - rule_name.s = (char*)shm_malloc(10*sizeof(char)); - if(rule_name.s == NULL) { - LM_ERR("no more shm memory\n"); - goto error; + for(j = 0; j < (*qr_main_list)->n_parts; j++) { /* for every partition */ + partition_node = add_mi_node_child(&rpl_tree->node, MI_DUP_VALUE, + "Partition", 9, (*qr_main_list)->part_name[j].s, + (*qr_main_list)->part_name[j].len); + + for(rule_it = (*qr_main_list)->qr_rules_start[j]; rule_it != NULL; + rule_it = rule_it->next) { + if(rule_it->r_id != 0) { /* TODO: maybe -1 */ + rule_name.s = (char*)shm_malloc(10*sizeof(char)); + if(rule_name.s == NULL) { + LM_ERR("no more shm memory\n"); + goto error; + } + memset(rule_name.s, 0, 10*sizeof(char)); + rule_name.len = snprintf(rule_name.s, 10,"%d", rule_it->r_id); + rule_node = add_mi_node_child(partition_node, 0, + "Rule", 4, rule_name.s, rule_name.len); + } else { + rule_node = add_mi_node_child(partition_node, 0, + "Rule", 4, 0, 0); + + } + for(i = 0;i < rule_it->n; i++) { + qr_dst_attr(&rule_node, &rule_it->dest[i]); } - memset(rule_name.s, 0, 10*sizeof(char)); - rule_name.len = snprintf(rule_name.s, 10,"%d", rule_it->r_id); - rule_node = add_mi_node_child(&rpl_tree->node, 0, - "Rule", 4, rule_name.s, rule_name.len); - } else { - rule_node = add_mi_node_child(&rpl_tree->node, 0, - "Rule", 4, 0, 0); } - for(i = 0;i < rule_it->n; i++) { - LM_INFO("adding dst to rule\n"); - qr_dst_attr(&rule_node, &rule_it->dest[i]); - } - } } else { /* mi_tree with a single destination (group/gateway) */ - rule_name = node->value; - if(str2int(&node->value, &rule_id) < 0) { - error_str.len = rule_name.len + 36; - error_str.s = (char *)shm_malloc(error_str.len*sizeof(char)); - snprintf(error_str.s, error_str.len, - "Failed to parse rule name '%.*s' to int", rule_name.len, - rule_name.s); - error_tree = init_mi_tree(500,error_str.s, error_str.len); - goto error; + if((*qr_main_list)->n_parts > 1) { /*=> the first parameter should be + the partition */ + part_name = node->value; + qr_part = qr_search_partition(part_name); + node = node->next; + + } else { + qr_part = (*qr_main_list)->qr_rules_start[0]; /* use the default + partition */ + part_name = (*qr_main_list)->part_name[0]; } - LM_DBG("searching for rule_id %d\n", rule_id); - rule = qr_search_rule(rule_id); - if(rule == NULL) { - error_str.len = rule_name.len + 18; - error_str.s = shm_malloc(error_str.len*sizeof(char)); - snprintf(error_str.s, error_str.len, "Rule '%.*s' not found", - rule_name.len, rule_name.s); - error_tree = init_mi_tree(400, error_str.s, error_str.len); + if(qr_part == NULL) { + error_str.len = part_name.len + 23; + error_str.s = (char*)shm_malloc(error_str.len*sizeof(char)); + snprintf(error_str.s, error_str.len, + "Partition '%.*s' not found", part_name.len, part_name.s); goto error; } - rule_node = add_mi_node_child(&rpl_tree->node, 0, - "Rule", 4, rule_name.s, rule_name.len); - - if(node->next != NULL) { - node = node->next; - gw_name = node->value; - dst = qr_search_dst(rule, &gw_name); - if(dst == NULL) { - error_str.len = gw_name.len+21; + partition_node = add_mi_node_child(&rpl_tree->node, 0, + "Partition", 9, part_name.s, part_name.len); + if(node!= NULL) { + rule_name = node->value; + if(str2int(&node->value, &rule_id) < 0) { + error_str.len = rule_name.len + 36; + error_str.s = (char *)shm_malloc(error_str.len*sizeof(char)); + snprintf(error_str.s, error_str.len, + "Failed to parse rule name '%.*s' to int", rule_name.len, + rule_name.s); + error_tree = init_mi_tree(500,error_str.s, error_str.len); + goto error; + } + LM_DBG("searching for rule_id %d\n", rule_id); + rule = qr_search_rule(qr_part, rule_id); + if(rule == NULL) { + error_str.len = rule_name.len + 18; error_str.s = shm_malloc(error_str.len*sizeof(char)); - snprintf(error_str.s, error_str.len, "Gateway '%.*s' not found", - gw_name.len, gw_name.s); + snprintf(error_str.s, error_str.len, "Rule '%.*s' not found", + rule_name.len, rule_name.s); error_tree = init_mi_tree(400, error_str.s, error_str.len); goto error; } - qr_dst_attr(&rule_node, dst); + rule_node = add_mi_node_child(partition_node, 0, + "Rule", 4, rule_name.s, rule_name.len); + + if(node->next != NULL) { + node = node->next; + gw_name = node->value; + dst = qr_search_dst(rule, &gw_name); + if(dst == NULL) { + error_str.len = gw_name.len+21; + error_str.s = shm_malloc(error_str.len*sizeof(char)); + snprintf(error_str.s, error_str.len, "Gateway '%.*s' not found", + gw_name.len, gw_name.s); + error_tree = init_mi_tree(400, error_str.s, error_str.len); + goto error; + } + qr_dst_attr(&rule_node, dst); - } else { /* mi_tree with all the destinations for a rule */ - for(i = 0; i < rule->n; i++) { - qr_dst_attr(&rule_node, &rule->dest[i]); + } else { /* mi_tree with all the destinations for a rule */ + for(i = 0; i < rule->n; i++) { + qr_dst_attr(&rule_node, &rule->dest[i]); + } + //qr_rule_attr(&rule_node, rule); + } + } else { + for(rule_it = qr_part; rule_it != NULL; rule_it = rule_it->next) { + rule_name.len = 0; + rule_name.s = (char*)shm_malloc(10*sizeof(char)); + rule_name.len = snprintf(rule_name.s, 10,"%d", rule_it->r_id); + rule_node = add_mi_node_child(partition_node, 0, "Rule", 4, + rule_name.s, rule_name.len); + for(i = 0; i < rule_it->n; i++) { + qr_dst_attr(&rule_node, &rule_it->dest[i]); + } } } }