/* Deletes all host and service downtimes on a host by hostname, optionally filtered by service description, start time and comment. All char* must be set or NULL - "" will silently fail to match Returns number deleted */ 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; int deleted = 0; /* Do not allow deletion of everything - must have at least 1 filter on */ if (hostname == NULL && service_description == NULL && start_time == 0 && comment == NULL) return deleted; /* * lock while traversing the list * so that other threads cannot modify */ #ifdef NSCORE pthread_mutex_lock(&icinga_downtime_lock); #endif for (temp_downtime = scheduled_downtime_list; temp_downtime != NULL; temp_downtime = next_downtime) { next_downtime = temp_downtime->next; if (start_time != 0 && temp_downtime->start_time != start_time) { continue; } if (comment != NULL && strcmp(temp_downtime->comment, comment) != 0) continue; if (temp_downtime->type == HOST_DOWNTIME) { /* If service is specified, then do not delete the host downtime */ if (service_description != NULL) continue; if (hostname != NULL && strcmp(temp_downtime->host_name, hostname) != 0) continue; } else if (temp_downtime->type == SERVICE_DOWNTIME) { if (hostname != NULL && strcmp(temp_downtime->host_name, hostname) != 0) continue; if (service_description != NULL && strcmp(temp_downtime->service_description, service_description) != 0) continue; } #ifdef NSCORE /* unlock here, because delete_*_downtime will try to lock itsself */ pthread_mutex_unlock(&icinga_downtime_lock); #endif unschedule_downtime(temp_downtime->type, temp_downtime->downtime_id); #ifdef NSCORE pthread_mutex_lock(&icinga_downtime_lock); #endif deleted++; } #ifdef NSCORE pthread_mutex_unlock(&icinga_downtime_lock); #endif return deleted; }
/* * Deletes all host and service downtimes on a host by hostname, * optionally filtered by service description, start time and comment. * All char* must be set or NULL - "" will silently fail to match * Returns number deleted */ int delete_downtime_by_hostname_service_description_start_time_comment(char *hostname, char *service_description, time_t start_time, char *cmnt) { 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 && cmnt == NULL) return deleted; for(temp_downtime = scheduled_downtime_list; temp_downtime != NULL; temp_downtime = next_downtime) { next_downtime = temp_downtime->next; if(start_time != 0 && temp_downtime->start_time != start_time) { continue; } if(cmnt != NULL && strcmp(temp_downtime->comment, cmnt) != 0) continue; if(temp_downtime->type == HOST_DOWNTIME) { /* If service is specified, then do not delete the host downtime */ if(service_description != NULL) continue; if(hostname != NULL && strcmp(temp_downtime->host_name, hostname) != 0) continue; } else if(temp_downtime->type == SERVICE_DOWNTIME) { if(hostname != NULL && strcmp(temp_downtime->host_name, hostname) != 0) continue; if(service_description != NULL && strcmp(temp_downtime->service_description, service_description) != 0) continue; } 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; }
/* unschedules a host or service downtime */ int unschedule_downtime(int type, unsigned long downtime_id) { scheduled_downtime *temp_downtime = NULL; scheduled_downtime *next_downtime = NULL; host *hst = NULL; service *svc = NULL; timed_event *temp_event = NULL; #ifdef USE_EVENT_BROKER int attr = 0; #endif log_debug_info(DEBUGL_FUNCTIONS, 0, "unschedule_downtime()\n"); /* find the downtime entry in the list in memory */ if ((temp_downtime = find_downtime(type, downtime_id)) == NULL) return ERROR; /* find the host or service associated with this downtime */ if (temp_downtime->type == HOST_DOWNTIME) { if ((hst = find_host(temp_downtime->host_name)) == NULL) return ERROR; } else { if ((svc = find_service(temp_downtime->host_name, temp_downtime->service_description)) == NULL) return ERROR; } /* decrement pending flex downtime if necessary ... */ if (temp_downtime->fixed == FALSE && temp_downtime->incremented_pending_downtime == TRUE) { if (temp_downtime->type == HOST_DOWNTIME) hst->pending_flex_downtime--; else svc->pending_flex_downtime--; } log_debug_info(DEBUGL_DOWNTIME, 0, "Cancelling %s downtime (id=%lu)\n", temp_downtime->type == HOST_DOWNTIME ? "host" : "service", temp_downtime->downtime_id); /* decrement the downtime depth variable and update status data if necessary */ if (temp_downtime->is_in_effect == TRUE) { #ifdef USE_EVENT_BROKER /* send data to event broker */ attr = NEBATTR_DOWNTIME_STOP_CANCELLED; broker_downtime_data(NEBTYPE_DOWNTIME_STOP, NEBFLAG_NONE, attr, temp_downtime->type, temp_downtime->host_name, temp_downtime->service_description, temp_downtime->entry_time, temp_downtime->author, temp_downtime->comment, temp_downtime->start_time, temp_downtime->end_time, temp_downtime->fixed, temp_downtime->triggered_by, temp_downtime->duration, temp_downtime->downtime_id, NULL, temp_downtime->is_in_effect, temp_downtime->trigger_time); #endif if (temp_downtime->type == HOST_DOWNTIME) { hst->scheduled_downtime_depth--; update_host_status(hst, FALSE); /* log a notice - this is parsed by the history CGI */ if (hst->scheduled_downtime_depth == 0) { logit(NSLOG_INFO_MESSAGE, FALSE, "HOST DOWNTIME ALERT: %s;CANCELLED; Scheduled downtime for host has been cancelled.\n", hst->name); /* send a notification */ host_notification(hst, NOTIFICATION_DOWNTIMECANCELLED, NULL, NULL, NOTIFICATION_OPTION_NONE); } } else { svc->scheduled_downtime_depth--; update_service_status(svc, FALSE); /* log a notice - this is parsed by the history CGI */ if (svc->scheduled_downtime_depth == 0) { logit(NSLOG_INFO_MESSAGE, FALSE, "SERVICE DOWNTIME ALERT: %s;%s;CANCELLED; Scheduled downtime for service has been cancelled.\n", svc->host_name, svc->description); /* send a notification */ service_notification(svc, NOTIFICATION_DOWNTIMECANCELLED, NULL, NULL, NOTIFICATION_OPTION_NONE); } } } /* remove scheduled entry from event queue */ for (temp_event = event_list_high; temp_event != NULL; temp_event = temp_event->next) { if (temp_event->event_type != EVENT_SCHEDULED_DOWNTIME) continue; if (((unsigned long)temp_event->event_data) == downtime_id) break; } if (temp_event != NULL) { remove_event(temp_event, &event_list_high, &event_list_high_tail); my_free(temp_event->event_data); my_free(temp_event); } /* delete downtime entry */ if (temp_downtime->type == HOST_DOWNTIME) delete_host_downtime(downtime_id); else delete_service_downtime(downtime_id); /* unschedule all downtime entries that were triggered by this one */ while (1) { for (temp_downtime = scheduled_downtime_list; temp_downtime != NULL; temp_downtime = next_downtime) { next_downtime = temp_downtime->next; if (temp_downtime->triggered_by == downtime_id) { unschedule_downtime(ANY_DOWNTIME, temp_downtime->downtime_id); break; } } if (temp_downtime == NULL) break; } return OK; }
int main(int argc, char **argv) { time_t now = 0L; time_t temp_start_time = 1234567890L; time_t temp_end_time = 2134567890L; unsigned long downtime_id = 0L; scheduled_downtime *temp_downtime; int i = 0; plan_tests(38); time(&now); schedule_downtime(HOST_DOWNTIME, "host1", NULL, temp_start_time, "user", "test comment", temp_start_time, temp_end_time, 0, 0, 0, &downtime_id); ok(downtime_id == 1L, "Got host1 downtime: %lu", downtime_id); schedule_downtime(HOST_DOWNTIME, "host2", NULL, temp_start_time, "user", "test comment", temp_start_time, temp_end_time, 0, 0, 0, &downtime_id); ok(downtime_id == 2L, "Got host2 downtime: %lu", downtime_id); schedule_downtime(HOST_DOWNTIME, "host3", NULL, temp_start_time, "user", "diff comment", temp_start_time, temp_end_time, 0, 0, 0, &downtime_id); ok(downtime_id == 3L, "Got host3 downtime: %lu", downtime_id); schedule_downtime(HOST_DOWNTIME, "host4", NULL, temp_start_time, "user", "test comment", temp_start_time + 1, temp_end_time, 0, 0, 0, &downtime_id); ok(downtime_id == 4L, "Got host4 downtime: %lu", downtime_id); schedule_downtime(SERVICE_DOWNTIME, "host1", "svc", temp_start_time, "user", "svc comment", temp_start_time, temp_end_time, 0, 0, 0, &downtime_id); ok(downtime_id == 5L, "Got host1::svc downtime: %lu", downtime_id); schedule_downtime(SERVICE_DOWNTIME, "host2", "svc", temp_start_time, "user", "diff comment", temp_start_time, temp_end_time, 0, 0, 0, &downtime_id); ok(downtime_id == 6L, "Got host2::svc downtime: %lu", downtime_id); schedule_downtime(SERVICE_DOWNTIME, "host3", "svc", temp_start_time, "user", "svc comment", temp_start_time + 1, temp_end_time, 0, 0, 0, &downtime_id); ok(downtime_id == 7L, "Got host3::svc downtime: %lu", downtime_id); schedule_downtime(SERVICE_DOWNTIME, "host4", "svc", temp_start_time, "user", "uniq comment", temp_start_time, temp_end_time, 0, 0, 0, &downtime_id); ok(downtime_id == 8L, "Got host4::svc downtime: %lu", downtime_id); for(temp_downtime = scheduled_downtime_list, i = 0; temp_downtime != NULL; temp_downtime = temp_downtime->next, i++) {} ok(i == 8, "Got 8 downtimes: %d", i); i = delete_downtime_by_hostname_service_description_start_time_comment(NULL, NULL, 0, NULL); ok(i == 0, "No deletions") || diag("%d", i); i = delete_downtime_by_hostname_service_description_start_time_comment(NULL, NULL, 0, NULL); ok(i == 0, "No deletions"); i = delete_downtime_by_hostname_service_description_start_time_comment(NULL, NULL, temp_start_time, "test comment"); ok(i == 2, "Deleted 2 downtimes"); for(temp_downtime = scheduled_downtime_list, i = 0; temp_downtime != NULL; temp_downtime = temp_downtime->next, i++) {} ok(i == 6, "Got 6 downtimes left: %d", i); i = delete_downtime_by_hostname_service_description_start_time_comment(NULL, NULL, temp_start_time + 200, "test comment"); ok(i == 0, "Nothing matched, so 0 downtimes deleted"); i = delete_downtime_by_hostname_service_description_start_time_comment(NULL, NULL, temp_start_time + 1, NULL); ok(i == 2, "Deleted 2 by start_time only: %d", i); i = delete_downtime_by_hostname_service_description_start_time_comment(NULL, NULL, 0, "uniq comment"); ok(i == 1, "Deleted 1 by unique comment: %d", i); for(temp_downtime = scheduled_downtime_list, i = 0; temp_downtime != NULL; temp_downtime = temp_downtime->next, i++) { diag("downtime id: %d", temp_downtime->downtime_id); } ok(i == 3, "Got 3 downtimes left: %d", i); unschedule_downtime(HOST_DOWNTIME, 3); unschedule_downtime(SERVICE_DOWNTIME, 5); unschedule_downtime(SERVICE_DOWNTIME, 6); for(temp_downtime = scheduled_downtime_list, i = 0; temp_downtime != NULL; temp_downtime = temp_downtime->next, i++) {} ok(i == 0, "No downtimes left"); /* Set all downtimes up again */ schedule_downtime(HOST_DOWNTIME, "host1", NULL, temp_start_time, "user", "test comment", temp_start_time, temp_end_time, 0, 0, 0, &downtime_id); ok(downtime_id == 9L, "Got host1 downtime: %lu", downtime_id); schedule_downtime(HOST_DOWNTIME, "host2", NULL, temp_start_time, "user", "test comment", temp_start_time, temp_end_time, 0, 0, 0, &downtime_id); ok(downtime_id == 10L, "Got host2 downtime: %lu", downtime_id); schedule_downtime(HOST_DOWNTIME, "host3", NULL, temp_start_time, "user", "diff comment", temp_start_time + 1, temp_end_time, 0, 0, 0, &downtime_id); ok(downtime_id == 11L, "Got host3 downtime: %lu", downtime_id); schedule_downtime(HOST_DOWNTIME, "host4", NULL, temp_start_time, "user", "test comment", temp_start_time + 1, temp_end_time, 0, 0, 0, &downtime_id); ok(downtime_id == 12L, "Got host4 downtime: %lu", downtime_id); schedule_downtime(SERVICE_DOWNTIME, "host1", "svc", temp_start_time, "user", "svc comment", temp_start_time, temp_end_time, 0, 0, 0, &downtime_id); ok(downtime_id == 13L, "Got host1::svc downtime: %lu", downtime_id); schedule_downtime(SERVICE_DOWNTIME, "host2", "svc", temp_start_time, "user", "diff comment", temp_start_time, temp_end_time, 0, 0, 0, &downtime_id); ok(downtime_id == 14L, "Got host2::svc downtime: %lu", downtime_id); schedule_downtime(SERVICE_DOWNTIME, "host3", "svc", temp_start_time, "user", "svc comment", temp_start_time, temp_end_time, 0, 0, 0, &downtime_id); ok(downtime_id == 15L, "Got host3::svc downtime: %lu", downtime_id); schedule_downtime(SERVICE_DOWNTIME, "host4", "svc", temp_start_time, "user", "uniq comment", temp_start_time, temp_end_time, 0, 0, 0, &downtime_id); ok(downtime_id == 16L, "Got host4::svc downtime: %lu", downtime_id); schedule_downtime(SERVICE_DOWNTIME, "host1", "svc2", temp_start_time, "user", "svc2 comment", temp_start_time, temp_end_time, 0, 0, 0, &downtime_id); ok(downtime_id == 17L, "Got host1::svc2 downtime: %lu", downtime_id); schedule_downtime(SERVICE_DOWNTIME, "host2", "svc2", temp_start_time, "user", "test comment", temp_start_time, temp_end_time, 0, 0, 0, &downtime_id); ok(downtime_id == 18L, "Got host2::svc2 downtime: %lu", downtime_id); schedule_downtime(SERVICE_DOWNTIME, "host3", "svc2", temp_start_time, "user", "svc2 comment", temp_start_time + 1, temp_end_time, 0, 0, 0, &downtime_id); ok(downtime_id == 19L, "Got host3::svc2 downtime: %lu", downtime_id); schedule_downtime(SERVICE_DOWNTIME, "host4", "svc2", temp_start_time, "user", "test comment", temp_start_time, temp_end_time, 0, 0, 0, &downtime_id); ok(downtime_id == 20L, "Got host4::svc2 downtime: %lu", downtime_id); i = delete_downtime_by_hostname_service_description_start_time_comment("host2", NULL, 0, "test comment"); ok(i == 2, "Deleted 2"); i = delete_downtime_by_hostname_service_description_start_time_comment("host1", "svc", 0, NULL); ok(i == 1, "Deleted 1") || diag("Actually deleted: %d", i); i = delete_downtime_by_hostname_service_description_start_time_comment("host3", NULL, temp_start_time + 1, NULL); ok(i == 2, "Deleted 2"); i = delete_downtime_by_hostname_service_description_start_time_comment(NULL, "svc2", 0, NULL); ok(i == 2, "Deleted 2") || diag("Actually deleted: %d", i); i = delete_downtime_by_hostname_service_description_start_time_comment("host4", NULL, 0, "test comment"); ok(i == 1, "Deleted 1") || diag("Actually deleted: %d", i); i = delete_downtime_by_hostname_service_description_start_time_comment("host4", NULL, 0, "svc comment"); ok(i == 0, "Deleted 0") || diag("Actually deleted: %d", i); for(temp_downtime = scheduled_downtime_list, i = 0; temp_downtime != NULL; temp_downtime = temp_downtime->next, i++) { diag("downtime id: %d", temp_downtime->downtime_id); } ok(i == 4, "Got 4 downtimes left: %d", i); unschedule_downtime(HOST_DOWNTIME, 9); unschedule_downtime(SERVICE_DOWNTIME, 14); unschedule_downtime(SERVICE_DOWNTIME, 15); unschedule_downtime(SERVICE_DOWNTIME, 16); for(temp_downtime = scheduled_downtime_list, i = 0; temp_downtime != NULL; temp_downtime = temp_downtime->next, i++) {} ok(i == 0, "No downtimes left") || diag("Left: %d", i); return exit_status(); }