From: <ag...@us...> - 2013-02-22 14:55:27
|
Revision: 2620 http://nagios.svn.sourceforge.net/nagios/?rev=2620&view=rev Author: ageric Date: 2013-02-22 14:55:15 +0000 (Fri, 22 Feb 2013) Log Message: ----------- downtime: Fix crash when using distributable downtime commands The function that implements the distributable downtime commands kept a pointer to the next downtime, which is a rubbish idea when the unschedule_downtime deletes any triggered_by downtimes, and scheduled downtimes triggered by this one typically start at the first element right after this one. To get nagios to crash using the old code, get a configuration with a few hosts, make all of them depend on one single host, schedule and propagate a triggered host downtime on the parent, and then unschedule the downtime on the parent using, for example, DEL_DOWNTIME_BY_HOST_NAME. This prevents the crash by first locating any matching downtimes and copying the information about the downtime type and id to a separate downtime list, and only then try to unschedule anything. This might lead to unschedule_downtime having to look for downtimes that no longer exist, which is slow, but it should only really happen for DEL_DOWNTIME_BY_START_TIME_COMMENT. I can see no easy way around this without breaking API and/or ABI. Signed-off-by: Robin Sonefors <rob...@op...> Signed-off-by: Andreas Ericsson <ae...@op...> Modified Paths: -------------- nagioscore/trunk/common/downtime.c Modified: nagioscore/trunk/common/downtime.c =================================================================== --- nagioscore/trunk/common/downtime.c 2013-02-22 14:47:43 UTC (rev 2619) +++ nagioscore/trunk/common/downtime.c 2013-02-22 14:55:15 UTC (rev 2620) @@ -898,7 +898,9 @@ int delete_downtime_by_hostname_service_description_start_time_comment(char *hostname, char *service_description, time_t start_time, char *comment) { scheduled_downtime *temp_downtime; scheduled_downtime *next_downtime; + void *downtime_cpy; int deleted = 0; + objectlist *matches = NULL, *tmp_match = NULL; /* Do not allow deletion of everything - must have at least 1 filter on */ if(hostname == NULL && service_description == NULL && start_time == 0 && comment == NULL) @@ -925,10 +927,20 @@ continue; } - unschedule_downtime(temp_downtime->type, temp_downtime->downtime_id); + downtime_cpy = malloc(sizeof(scheduled_downtime)); + memcpy(downtime_cpy, temp_downtime, sizeof(scheduled_downtime)); + prepend_object_to_objectlist(&matches, downtime_cpy); deleted++; } + for(tmp_match = matches; tmp_match != NULL; tmp_match = tmp_match->next) { + temp_downtime = (scheduled_downtime *)tmp_match->object_ptr; + unschedule_downtime(temp_downtime->type, temp_downtime->downtime_id); + my_free(temp_downtime); + } + + free_objectlist(&matches); + return deleted; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |