From: <ag...@us...> - 2012-08-26 20:10:08
|
Revision: 2113 http://nagios.svn.sourceforge.net/nagios/?rev=2113&view=rev Author: ageric Date: 2012-08-26 20:10:01 +0000 (Sun, 26 Aug 2012) Log Message: ----------- Attach escalations to their parent objects It makes absolutely no sense to keep them in a skiplist and access them with complicated accessor-functions when we know we'll only ever be interested in them when we're already looking at a host or a service. With this patch we cut the number of skiplists down to the object types that actually have to be indexed, which is good. We can also simplify a lot of algorithms and reduce runtime when we hit problems in networks where escalations are configured, which is even better. Less memory usage and less cpu spent. Win, win and win. Signed-off-by: Andreas Ericsson <ae...@op...> Modified Paths: -------------- nagioscore/trunk/base/notifications.c nagioscore/trunk/common/objects.c nagioscore/trunk/include/objects.h Modified: nagioscore/trunk/base/notifications.c =================================================================== --- nagioscore/trunk/base/notifications.c 2012-08-26 20:09:26 UTC (rev 2112) +++ nagioscore/trunk/base/notifications.c 2012-08-26 20:10:01 UTC (rev 2113) @@ -32,8 +32,6 @@ extern notification *notification_list; extern contact *contact_list; -extern serviceescalation *serviceescalation_list; -extern hostescalation *hostescalation_list; extern time_t program_start; @@ -902,13 +900,13 @@ /* checks to see whether a service notification should be escalation */ int should_service_notification_be_escalated(service *svc) { - serviceescalation *temp_se = NULL; - void *ptr = NULL; + objectlist *list; log_debug_info(DEBUGL_FUNCTIONS, 0, "should_service_notification_be_escalated()\n"); /* search the service escalation list */ - for(temp_se = get_first_serviceescalation_by_service(svc->host_name, svc->description, &ptr); temp_se != NULL; temp_se = get_next_serviceescalation_by_service(svc->host_name, svc->description, &ptr)) { + for (list = svc->escalation_list; list; list = list->next) { + serviceescalation *temp_se = (serviceescalation *)list->object_ptr; /* we found a matching entry, so escalate this notification! */ if(is_valid_escalation_for_service_notification(svc, temp_se, NOTIFICATION_OPTION_NONE) == TRUE) { @@ -931,7 +929,6 @@ contactgroupsmember *temp_contactgroupsmember = NULL; contactgroup *temp_contactgroup = NULL; int escalate_notification = FALSE; - void *ptr = NULL; log_debug_info(DEBUGL_FUNCTIONS, 0, "create_notification_list_from_service()\n"); @@ -953,11 +950,13 @@ /* use escalated contacts for this notification */ if(escalate_notification == TRUE || (options & NOTIFICATION_OPTION_BROADCAST)) { + objectlist *list; log_debug_info(DEBUGL_NOTIFICATIONS, 1, "Adding contacts from service escalation(s) to notification list.\n"); /* search all the escalation entries for valid matches */ - for(temp_se = get_first_serviceescalation_by_service(svc->host_name, svc->description, &ptr); temp_se != NULL; temp_se = get_next_serviceescalation_by_service(svc->host_name, svc->description, &ptr)) { + for(list = svc->escalation_list; list; list = list->next) { + temp_se = (serviceescalation *)list->object_ptr; /* skip this entry if it isn't appropriate */ if(is_valid_escalation_for_service_notification(svc, temp_se, options) == FALSE) @@ -1827,8 +1826,7 @@ /* checks to see whether a host notification should be escalation */ int should_host_notification_be_escalated(host *hst) { - hostescalation *temp_he = NULL; - void *ptr = NULL; + objectlist *list; log_debug_info(DEBUGL_FUNCTIONS, 0, "should_host_notification_be_escalated()\n"); @@ -1836,8 +1834,8 @@ return FALSE; /* search the host escalation list */ - for(temp_he = get_first_hostescalation_by_host(hst->name, &ptr); temp_he != NULL; temp_he = get_next_hostescalation_by_host(hst->name, &ptr)) { - + for (list = hst->escalation_list; list; list = list->next) { + hostescalation *temp_he = (hostescalation *)list->object_ptr; /* we found a matching entry, so escalate this notification! */ if(is_valid_escalation_for_host_notification(hst, temp_he, NOTIFICATION_OPTION_NONE) == TRUE) return TRUE; @@ -1857,7 +1855,6 @@ contactgroupsmember *temp_contactgroupsmember = NULL; contactgroup *temp_contactgroup = NULL; int escalate_notification = FALSE; - void *ptr = NULL; log_debug_info(DEBUGL_FUNCTIONS, 0, "create_notification_list_from_host()\n"); @@ -1878,11 +1875,13 @@ /* use escalated contacts for this notification */ if(escalate_notification == TRUE || (options & NOTIFICATION_OPTION_BROADCAST)) { + objectlist *list; log_debug_info(DEBUGL_NOTIFICATIONS, 1, "Adding contacts from host escalation(s) to notification list.\n"); /* check all the host escalation entries */ - for(temp_he = get_first_hostescalation_by_host(hst->name, &ptr); temp_he != NULL; temp_he = get_next_hostescalation_by_host(hst->name, &ptr)) { + for(list = hst->escalation_list; list; list = list->next) { + temp_he = (hostescalation *)list->object_ptr; /* see if this escalation if valid for this notification */ if(is_valid_escalation_for_host_notification(hst, temp_he, options) == FALSE) @@ -1974,7 +1973,7 @@ time_t get_next_service_notification_time(service *svc, time_t offset) { time_t next_notification = 0L; double interval_to_use = 0.0; - serviceescalation *temp_se = NULL; + objectlist *list; int have_escalated_interval = FALSE; log_debug_info(DEBUGL_FUNCTIONS, 0, "get_next_service_notification_time()\n"); @@ -1987,7 +1986,8 @@ log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Default interval: %f\n", interval_to_use); /* search all the escalation entries for valid matches for this service (at its current notification number) */ - for(temp_se = serviceescalation_list; temp_se != NULL; temp_se = temp_se->next) { + for(list = svc->escalation_list; list; list = list->next) { + serviceescalation *temp_se = (serviceescalation *)list->object_ptr; /* interval < 0 means to use non-escalated interval */ if(temp_se->notification_interval < 0.0) @@ -2032,7 +2032,7 @@ time_t get_next_host_notification_time(host *hst, time_t offset) { time_t next_notification = 0L; double interval_to_use = 0.0; - hostescalation *temp_he = NULL; + objectlist *list; int have_escalated_interval = FALSE; @@ -2046,7 +2046,8 @@ log_debug_info(DEBUGL_NOTIFICATIONS, 2, "Default interval: %f\n", interval_to_use); /* check all the host escalation entries for valid matches for this host (at its current notification number) */ - for(temp_he = hostescalation_list; temp_he != NULL; temp_he = temp_he->next) { + for(list = hst->escalation_list; list; list = list->next) { + hostescalation *temp_he = (hostescalation *)list->object_ptr; /* interval < 0 means to use non-escalated interval */ if(temp_he->notification_interval < 0.0) Modified: nagioscore/trunk/common/objects.c =================================================================== --- nagioscore/trunk/common/objects.c 2012-08-26 20:09:26 UTC (rev 2112) +++ nagioscore/trunk/common/objects.c 2012-08-26 20:10:01 UTC (rev 2113) @@ -1901,7 +1901,6 @@ serviceescalation *new_serviceescalation = NULL; service *svc; timeperiod *tp; - int result = OK; /* make sure we have the data we need */ if(host_name == NULL || !*host_name || description == NULL || !*description) { @@ -1911,7 +1910,7 @@ if(!(svc = find_service(host_name, description))) { logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Service '%s' on host '%s' has an escalation but is not defined anywhere!\n", host_name, description); - return NULL ; + return NULL; } if (escalation_period && !(tp = find_timeperiod(escalation_period))) { logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Escalation period '%s' specified in service escalation for service '%s' on host '%s' is not defined anywhere!\n", @@ -1923,6 +1922,13 @@ if((new_serviceescalation = calloc(1, sizeof(serviceescalation))) == NULL) return NULL; + if(add_object_to_objectlist(&svc->escalation_list, new_serviceescalation) != OK) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Could not add escalation to service '%s' on host '%s'\n", + svc->host_name, svc->description); + my_free(new_serviceescalation); + return NULL; + } + /* assign vars. object names are immutable, so no need to copy */ new_serviceescalation->host_name = svc->host_name; new_serviceescalation->description = svc->description; @@ -1941,26 +1947,6 @@ new_serviceescalation->escalate_on_unknown = (escalate_on_unknown > 0) ? TRUE : FALSE; new_serviceescalation->escalate_on_critical = (escalate_on_critical > 0) ? TRUE : FALSE; - /* add new serviceescalation to skiplist */ - if(result == OK) { - result = skiplist_insert(object_skiplists[SERVICEESCALATION_SKIPLIST], (void *)new_serviceescalation); - switch(result) { - case SKIPLIST_OK: - result = OK; - break; - default: - logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add escalation for service '%s' on host '%s' to skiplist\n", description, host_name); - result = ERROR; - break; - } - } - - /* handle errors */ - if(result == ERROR) { - my_free(new_serviceescalation); - return NULL; - } - /* service escalations are sorted alphabetically, so add new items to tail of list */ if(serviceescalation_list == NULL) { serviceescalation_list = new_serviceescalation; @@ -2191,7 +2177,6 @@ hostescalation *new_hostescalation = NULL; host *h; timeperiod *tp = NULL; - int result = OK; /* make sure we have the data we need */ if(host_name == NULL || !*host_name) { @@ -2211,6 +2196,12 @@ if((new_hostescalation = calloc(1, sizeof(hostescalation))) == NULL) return NULL; + /* add the escalation to its host */ + if (add_object_to_objectlist(&h->escalation_list, new_hostescalation) != OK) { + logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add hostescalation to host '%s'\n", host_name); + my_free(new_hostescalation); + return NULL; + } /* assign vars. Object names are immutable, so no need to copy */ new_hostescalation->host_name = h->name; @@ -2225,26 +2216,6 @@ new_hostescalation->escalate_on_down = (escalate_on_down > 0) ? TRUE : FALSE; new_hostescalation->escalate_on_unreachable = (escalate_on_unreachable > 0) ? TRUE : FALSE; - /* add new hostescalation to skiplist */ - if(result == OK) { - result = skiplist_insert(object_skiplists[HOSTESCALATION_SKIPLIST], (void *)new_hostescalation); - switch(result) { - case SKIPLIST_OK: - result = OK; - break; - default: - logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add hostescalation '%s' to skiplist\n", host_name); - result = ERROR; - break; - } - } - - /* handle errors */ - if(result == ERROR) { - my_free(new_hostescalation); - return NULL; - } - /* host escalations are sorted alphabetically, so add new items to tail of list */ if(hostescalation_list == NULL) { hostescalation_list = new_hostescalation; @@ -2501,61 +2472,6 @@ - -/******************************************************************/ -/******************* OBJECT TRAVERSAL FUNCTIONS *******************/ -/******************************************************************/ - -hostescalation *get_first_hostescalation_by_host(char *host_name, void **ptr) { - hostescalation temp_hostescalation; - - if(host_name == NULL) - return NULL; - - temp_hostescalation.host_name = host_name; - - return skiplist_find_first(object_skiplists[HOSTESCALATION_SKIPLIST], &temp_hostescalation, ptr); - } - - -hostescalation *get_next_hostescalation_by_host(char *host_name, void **ptr) { - hostescalation temp_hostescalation; - - if(host_name == NULL) - return NULL; - - temp_hostescalation.host_name = host_name; - - return skiplist_find_next(object_skiplists[HOSTESCALATION_SKIPLIST], &temp_hostescalation, ptr); - } - - -serviceescalation *get_first_serviceescalation_by_service(char *host_name, char *svc_description, void **ptr) { - serviceescalation temp_serviceescalation; - - if(host_name == NULL || svc_description == NULL) - return NULL; - - temp_serviceescalation.host_name = host_name; - temp_serviceescalation.description = svc_description; - - return skiplist_find_first(object_skiplists[SERVICEESCALATION_SKIPLIST], &temp_serviceescalation, ptr); - } - - -serviceescalation *get_next_serviceescalation_by_service(char *host_name, char *svc_description, void **ptr) { - serviceescalation temp_serviceescalation; - - if(host_name == NULL || svc_description == NULL) - return NULL; - - temp_serviceescalation.host_name = host_name; - temp_serviceescalation.description = svc_description; - - return skiplist_find_next(object_skiplists[SERVICEESCALATION_SKIPLIST], &temp_serviceescalation, ptr); - } - - /* adds a object to a list of objects */ int add_object_to_objectlist(objectlist **list, void *object_ptr) { objectlist *temp_item = NULL; @@ -2862,11 +2778,11 @@ hostescalation *temp_hostescalation = NULL; contactgroupsmember *temp_contactgroupsmember = NULL; contactgroup *temp_contactgroup = NULL; - void *ptr = NULL; + objectlist *list; - /* search all host escalations */ - for(temp_hostescalation = get_first_hostescalation_by_host(hst->name, &ptr); temp_hostescalation != NULL; temp_hostescalation = get_next_hostescalation_by_host(hst->name, &ptr)) { + for(list = hst->escalation_list; list; list = list->next) { + temp_hostescalation = (hostescalation *)list->object_ptr; /* search all contacts of this host escalation */ for(temp_contactsmember = temp_hostescalation->contacts; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) { @@ -2948,10 +2864,11 @@ contact *temp_contact = NULL; contactgroupsmember *temp_contactgroupsmember = NULL; contactgroup *temp_contactgroup = NULL; - void *ptr = NULL; + objectlist *list; /* search all the service escalations */ - for(temp_serviceescalation = get_first_serviceescalation_by_service(svc->host_name, svc->description, &ptr); temp_serviceescalation != NULL; temp_serviceescalation = get_next_serviceescalation_by_service(svc->host_name, svc->description, &ptr)) { + for(list = svc->escalation_list; list; list = list->next) { + temp_serviceescalation = (serviceescalation *)list->object_ptr; /* search all contacts of this service escalation */ for(temp_contactsmember = temp_serviceescalation->contacts; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) { @@ -3151,6 +3068,7 @@ #endif free_objectlist(&this_host->notify_deps); free_objectlist(&this_host->exec_deps); + free_objectlist(&this_host->escalation_list); my_free(this_host->host_check_command); my_free(this_host->event_handler); my_free(this_host->failure_prediction_options); @@ -3350,6 +3268,7 @@ #endif free_objectlist(&this_service->notify_deps); free_objectlist(&this_service->exec_deps); + free_objectlist(&this_service->escalation_list); my_free(this_service->event_handler); my_free(this_service->failure_prediction_options); my_free(this_service->notes); Modified: nagioscore/trunk/include/objects.h =================================================================== --- nagioscore/trunk/include/objects.h 2012-08-26 20:09:26 UTC (rev 2112) +++ nagioscore/trunk/include/objects.h 2012-08-26 20:10:01 UTC (rev 2113) @@ -379,6 +379,7 @@ #endif /* objects we depend upon */ objectlist *exec_deps, *notify_deps; + objectlist *escalation_list; struct host_struct *next; void *next_check_event; }; @@ -512,6 +513,7 @@ objectlist *servicegroups_ptr; #endif objectlist *exec_deps, *notify_deps; + objectlist *escalation_list; struct service_struct *next; void *next_check_event; }; @@ -689,11 +691,6 @@ service *find_service(char *, char *); /* finds a service object */ -/**** Object Traversal Functions ****/ -hostescalation *get_first_hostescalation_by_host(char *, void **); -hostescalation *get_next_hostescalation_by_host(char *, void **); -serviceescalation *get_first_serviceescalation_by_service(char *, char *, void **); -serviceescalation *get_next_serviceescalation_by_service(char *, char *, void **); int add_object_to_objectlist(objectlist **, void *); int free_objectlist(objectlist **); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |