/* saves a service downtime entry */ int add_new_service_downtime(char *host_name, char *service_description, time_t entry_time, char *author, char *comment_data, time_t start_time, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long *downtime_id, int is_in_effect, time_t trigger_time) { int result = OK; if (host_name == NULL || service_description == NULL) return ERROR; /* find the next valid downtime id */ while (find_service_downtime(next_downtime_id) != NULL) next_downtime_id++; /* add downtime to list in memory */ result = add_service_downtime(host_name, service_description, entry_time, author, comment_data, start_time, end_time, fixed, triggered_by, duration, next_downtime_id, is_in_effect, trigger_time); /* save downtime id */ if (downtime_id != NULL) *downtime_id = next_downtime_id; #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_downtime_data(NEBTYPE_DOWNTIME_ADD, NEBFLAG_NONE, NEBATTR_NONE, SERVICE_DOWNTIME, host_name, service_description, entry_time, author, comment_data, start_time, end_time, fixed, triggered_by, duration, next_downtime_id, NULL, is_in_effect, trigger_time); #endif /* increment the downtime id */ next_downtime_id++; return result; }
/* deletes a scheduled host or service downtime entry from the list in memory */ int delete_downtime(int type, unsigned long downtime_id) { scheduled_downtime *this_downtime = NULL; /* find the downtime we should remove */ this_downtime = find_downtime(type, downtime_id); if(!this_downtime) return ERROR; downtime_remove(this_downtime); /* first remove the comment associated with this downtime */ if(this_downtime->type == HOST_DOWNTIME) delete_host_comment(this_downtime->comment_id); else delete_service_comment(this_downtime->comment_id); #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_downtime_data(NEBTYPE_DOWNTIME_DELETE, NEBFLAG_NONE, NEBATTR_NONE, type, this_downtime->host_name, this_downtime->service_description, this_downtime->entry_time, this_downtime->author, this_downtime->comment, this_downtime->start_time, this_downtime->end_time, this_downtime->fixed, this_downtime->triggered_by, this_downtime->duration, downtime_id, NULL); #endif /* free memory */ my_free(this_downtime->host_name); my_free(this_downtime->service_description); my_free(this_downtime->author); my_free(this_downtime->comment); my_free(this_downtime); return OK; }
/* saves a service downtime entry */ int add_new_service_downtime(char *host_name, char *service_description, time_t entry_time, char *author, char *comment_data, time_t start_time, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long *downtime_id, int is_in_effect, int start_notification_sent){ int result = OK; unsigned long new_downtime_id = 0L; log_debug_info(DEBUGL_FUNCTIONS, 0, "add_new_service_downtime()\n"); if(host_name == NULL || service_description == NULL) { log_debug_info(DEBUGL_DOWNTIME, 1, "Host name (%s) or service description (%s) is null\n", ((NULL == host_name) ? "null" : host_name), ((NULL == service_description) ? "null" : service_description)); return ERROR; } new_downtime_id = get_next_downtime_id(); result = add_service_downtime(host_name, service_description, entry_time, author, comment_data, start_time, 0, end_time, fixed, triggered_by, duration, new_downtime_id, is_in_effect, start_notification_sent); /* save downtime id */ if(downtime_id != NULL) *downtime_id = new_downtime_id; #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_downtime_data(NEBTYPE_DOWNTIME_ADD, NEBFLAG_NONE, NEBATTR_NONE, SERVICE_DOWNTIME, host_name, service_description, entry_time, author, comment_data, start_time, end_time, fixed, triggered_by, duration, new_downtime_id, NULL); #endif return result; }
/* deletes a scheduled host or service downtime entry from the list in memory */ int delete_downtime(int type, unsigned long downtime_id) { int result = OK; scheduled_downtime *this_downtime = NULL; scheduled_downtime *last_downtime = NULL; scheduled_downtime *next_downtime = NULL; #ifdef NSCORE pthread_mutex_lock(&icinga_downtime_lock); #endif /* find the downtime we should remove */ for (this_downtime = scheduled_downtime_list, last_downtime = scheduled_downtime_list; this_downtime != NULL; this_downtime = next_downtime) { next_downtime = this_downtime->next; /* we found the downtime we should delete */ if (this_downtime->downtime_id == downtime_id && this_downtime->type == type) break; last_downtime = this_downtime; } /* remove the downtime from the list in memory */ if (this_downtime != NULL) { /* first remove the comment associated with this downtime */ if (this_downtime->type == HOST_DOWNTIME) delete_host_comment(this_downtime->comment_id); else delete_service_comment(this_downtime->comment_id); #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_downtime_data(NEBTYPE_DOWNTIME_DELETE, NEBFLAG_NONE, NEBATTR_NONE, type, this_downtime->host_name, this_downtime->service_description, this_downtime->entry_time, this_downtime->author, this_downtime->comment, this_downtime->start_time, this_downtime->end_time, this_downtime->fixed, this_downtime->triggered_by, this_downtime->duration, downtime_id, NULL, this_downtime->is_in_effect, this_downtime->trigger_time); #endif if (scheduled_downtime_list == this_downtime) scheduled_downtime_list = this_downtime->next; else last_downtime->next = next_downtime; /* free memory */ my_free(this_downtime->host_name); my_free(this_downtime->service_description); my_free(this_downtime->author); my_free(this_downtime->comment); my_free(this_downtime); result = OK; } else result = ERROR; #ifdef NSCORE pthread_mutex_unlock(&icinga_downtime_lock); #endif return result; }
/* saves a host downtime entry */ int add_new_host_downtime(char *host_name, time_t entry_time, char *author, char *comment_data, time_t start_time, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long *downtime_id, int is_in_effect, int start_notification_sent){ int result = OK; unsigned long new_downtime_id = 0L; if(host_name == NULL) return ERROR; log_debug_info(DEBUGL_FUNCTIONS, 0, "cleanup_downtime_data()\n"); new_downtime_id = get_next_downtime_id(); result = add_host_downtime(host_name, entry_time, author, comment_data, start_time, 0, end_time, fixed, triggered_by, duration, new_downtime_id, is_in_effect, start_notification_sent); /* save downtime id */ if(downtime_id != NULL) *downtime_id = new_downtime_id; #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_downtime_data(NEBTYPE_DOWNTIME_ADD, NEBFLAG_NONE, NEBATTR_NONE, HOST_DOWNTIME, host_name, NULL, entry_time, author, comment_data, start_time, end_time, fixed, triggered_by, duration, new_downtime_id, NULL); #endif return result; }
/* saves a service downtime entry */ int add_new_service_downtime(char *host_name, char *service_description, time_t entry_time, char *author, char *comment_data, time_t start_time, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long *downtime_id, int is_in_effect, time_t trigger_time) { int result = OK; unsigned long new_downtime_id = 0L; if (host_name == NULL || service_description == NULL) return ERROR; /**** IMPLEMENTATION-SPECIFIC CALLS ****/ #ifdef USE_XDDDEFAULT result = xdddefault_add_new_service_downtime(host_name, service_description, entry_time, author, comment_data, start_time, end_time, fixed, triggered_by, duration, &new_downtime_id, is_in_effect, trigger_time); #endif /* save downtime id */ if (downtime_id != NULL) *downtime_id = new_downtime_id; #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_downtime_data(NEBTYPE_DOWNTIME_ADD, NEBFLAG_NONE, NEBATTR_NONE, SERVICE_DOWNTIME, host_name, service_description, entry_time, author, comment_data, start_time, end_time, fixed, triggered_by, duration, new_downtime_id, NULL, is_in_effect, trigger_time); #endif return result; }
/* handles scheduled host or service downtime */ int handle_scheduled_downtime(scheduled_downtime *temp_downtime) { scheduled_downtime *this_downtime = NULL; host *hst = NULL; service *svc = NULL; time_t event_time = 0L; time_t current_time = 0L; unsigned long *new_downtime_id = NULL; #ifdef USE_EVENT_BROKER int attr = 0; #endif log_debug_info(DEBUGL_FUNCTIONS, 0, "handle_scheduled_downtime()\n"); if (temp_downtime == 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; } /* if downtime if flexible and host/svc is in an ok state, don't do anything right now (wait for event handler to kick it off) */ /* start_flex_downtime variable is set to TRUE by event handler functions */ if (temp_downtime->fixed == FALSE) { /* we're not supposed to force a start of flex downtime... */ if (temp_downtime->start_flex_downtime == FALSE) { /* host is up or service is ok, so we don't really do anything right now */ if ((temp_downtime->type == HOST_DOWNTIME && hst->current_state == HOST_UP) || (temp_downtime->type == SERVICE_DOWNTIME && svc->current_state == STATE_OK)) { /* increment pending flex downtime counter */ if (temp_downtime->type == HOST_DOWNTIME) hst->pending_flex_downtime++; else svc->pending_flex_downtime++; temp_downtime->incremented_pending_downtime = TRUE; /*** SINCE THE FLEX DOWNTIME MAY NEVER START, WE HAVE TO PROVIDE A WAY OF EXPIRING UNUSED DOWNTIME... ***/ schedule_new_event(EVENT_EXPIRE_DOWNTIME, TRUE, (temp_downtime->end_time + 1), FALSE, 0, NULL, FALSE, NULL, NULL, 0); return OK; } } } time(¤t_time); /* have we come to the end of the scheduled downtime? */ if (temp_downtime->is_in_effect == TRUE && ( /* downtime needs to be in effect and ... */ (temp_downtime->fixed == TRUE && current_time >= temp_downtime->end_time) || /* fixed downtime, endtime means end of downtime */ (temp_downtime->fixed == FALSE && current_time >= (temp_downtime->trigger_time+temp_downtime->duration)) /* flexible downtime, endtime of downtime is trigger_time+duration */ )){ if (temp_downtime->type == HOST_DOWNTIME) log_debug_info(DEBUGL_DOWNTIME, 0, "Host '%s' ending %s scheduled downtime (id=%lu) with depth=%d, starttime=%lu, entrytime=%lu, triggertime=%lu, endtime=%lu, duration=%lu.\n", hst->name, (temp_downtime->fixed == TRUE) ? "fixed" : "flexible", temp_downtime->downtime_id, hst->scheduled_downtime_depth, temp_downtime->start_time, temp_downtime->entry_time, temp_downtime->trigger_time, temp_downtime->end_time, temp_downtime->duration); else log_debug_info(DEBUGL_DOWNTIME, 0, "Service '%s' on host '%s' ending %s scheduled downtime (id=%lu) with depth=%d, starttime=%lu, entrytime=%lu, triggertime=%lu, endtime=%lu, duration=%lu.\n", svc->description, svc->host_name, (temp_downtime->fixed == TRUE) ? "fixed" : "flexible", temp_downtime->downtime_id, svc->scheduled_downtime_depth, temp_downtime->start_time, temp_downtime->entry_time, temp_downtime->trigger_time, temp_downtime->end_time, temp_downtime->duration); #ifdef USE_EVENT_BROKER /* send data to event broker */ attr = NEBATTR_DOWNTIME_STOP_NORMAL; 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 /* decrement the downtime depth variable */ if (temp_downtime->type == HOST_DOWNTIME) hst->scheduled_downtime_depth--; else svc->scheduled_downtime_depth--; if (temp_downtime->type == HOST_DOWNTIME && hst->scheduled_downtime_depth == 0) { log_debug_info(DEBUGL_DOWNTIME, 0, "Host '%s' has exited from a period of scheduled downtime (id=%lu).\n", hst->name, temp_downtime->downtime_id); /* log a notice - this one is parsed by the history CGI */ logit(NSLOG_INFO_MESSAGE, FALSE, "HOST DOWNTIME ALERT: %s;STOPPED; Host has exited from a period of scheduled downtime", hst->name); /* send a notification */ host_notification(hst, NOTIFICATION_DOWNTIMEEND, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE); } else if (temp_downtime->type == SERVICE_DOWNTIME && svc->scheduled_downtime_depth == 0) { log_debug_info(DEBUGL_DOWNTIME, 0, "Service '%s' on host '%s' has exited from a period of scheduled downtime (id=%lu).\n", svc->description, svc->host_name, temp_downtime->downtime_id); /* log a notice - this one is parsed by the history CGI */ logit(NSLOG_INFO_MESSAGE, FALSE, "SERVICE DOWNTIME ALERT: %s;%s;STOPPED; Service has exited from a period of scheduled downtime", svc->host_name, svc->description); /* send a notification */ service_notification(svc, NOTIFICATION_DOWNTIMEEND, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE); } /* update the status data */ if (temp_downtime->type == HOST_DOWNTIME) update_host_status(hst, FALSE); else update_service_status(svc, FALSE); /* decrement pending flex downtime if necessary */ if (temp_downtime->fixed == FALSE && temp_downtime->incremented_pending_downtime == TRUE) { if (temp_downtime->type == HOST_DOWNTIME) { if (hst->pending_flex_downtime > 0) hst->pending_flex_downtime--; } else { if (svc->pending_flex_downtime > 0) svc->pending_flex_downtime--; } } /* handle (stop) downtime that is triggered by this one */ while (1) { /* list contents might change by recursive calls, so we use this inefficient method to prevent segfaults */ for (this_downtime = scheduled_downtime_list; this_downtime != NULL; this_downtime = this_downtime->next) { if (this_downtime->triggered_by == temp_downtime->downtime_id) { handle_scheduled_downtime(this_downtime); break; } } if (this_downtime == NULL) break; } /* delete downtime entry */ if (temp_downtime->type == HOST_DOWNTIME) delete_host_downtime(temp_downtime->downtime_id); else delete_service_downtime(temp_downtime->downtime_id); } /* else we are just starting the scheduled downtime */ else { if (temp_downtime->type == HOST_DOWNTIME) log_debug_info(DEBUGL_DOWNTIME, 0, "Host '%s' starting %s scheduled downtime (id=%lu) with depth=%d, starttime=%lu, entrytime=%lu, endtime=%lu, duration=%lu.\n", hst->name, (temp_downtime->fixed == TRUE) ? "fixed" : "flexible", temp_downtime->downtime_id, hst->scheduled_downtime_depth, temp_downtime->start_time, temp_downtime->entry_time, temp_downtime->end_time, temp_downtime->duration); else log_debug_info(DEBUGL_DOWNTIME, 0, "Service '%s' on host '%s' starting %s scheduled downtime (id=%lu) with depth=%d, starttime=%lu, entrytime=%lu, endtime=%lu, duration=%lu.\n", svc->description, svc->host_name, (temp_downtime->fixed == TRUE) ? "fixed" : "flexible", temp_downtime->downtime_id, svc->scheduled_downtime_depth, temp_downtime->start_time, temp_downtime->entry_time, temp_downtime->end_time, temp_downtime->duration); /* this happens after restart of icinga */ if (temp_downtime->is_in_effect != TRUE) { if (temp_downtime->type == HOST_DOWNTIME && hst->scheduled_downtime_depth == 0) { /* set the trigger time, needed to detect the end of a flexible downtime */ temp_downtime->trigger_time = current_time; log_debug_info(DEBUGL_DOWNTIME, 0, "Host '%s' has entered a period of scheduled downtime (id=%lu) at triggertime=%lu.\n", hst->name, temp_downtime->downtime_id, temp_downtime->trigger_time); /* log a notice - this one is parsed by the history CGI */ logit(NSLOG_INFO_MESSAGE, FALSE, "HOST DOWNTIME ALERT: %s;STARTED; Host has entered a period of scheduled downtime", hst->name); /* send a notification */ host_notification(hst, NOTIFICATION_DOWNTIMESTART, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE); } else if (temp_downtime->type == SERVICE_DOWNTIME && svc->scheduled_downtime_depth == 0) { /* set the trigger time, needed to detect the end of a flexible downtime */ temp_downtime->trigger_time = current_time; log_debug_info(DEBUGL_DOWNTIME, 0, "Service '%s' on host '%s' has entered a period of scheduled downtime (id=%lu) at triggertime=%lu.\n", svc->description, svc->host_name, temp_downtime->downtime_id, temp_downtime->trigger_time); /* log a notice - this one is parsed by the history CGI */ logit(NSLOG_INFO_MESSAGE, FALSE, "SERVICE DOWNTIME ALERT: %s;%s;STARTED; Service has entered a period of scheduled downtime", svc->host_name, svc->description); /* send a notification */ service_notification(svc, NOTIFICATION_DOWNTIMESTART, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE); } } /* increment the downtime depth variable */ if (temp_downtime->type == HOST_DOWNTIME) hst->scheduled_downtime_depth++; else svc->scheduled_downtime_depth++; /* set the in effect flag */ temp_downtime->is_in_effect = TRUE; #ifdef USE_EVENT_BROKER /* send data to broker AFTER we know trigger_time, is_in_effect, and downtime_depth */ broker_downtime_data(NEBTYPE_DOWNTIME_START, NEBFLAG_NONE, NEBATTR_NONE, 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 /* update the status data */ if (temp_downtime->type == HOST_DOWNTIME) update_host_status(hst, FALSE); else update_service_status(svc, FALSE); /* schedule an event */ if (temp_downtime->fixed == FALSE) event_time = (time_t)((unsigned long)time(NULL) + temp_downtime->duration); else event_time = temp_downtime->end_time; if ((new_downtime_id = (unsigned long *)malloc(sizeof(unsigned long *)))) { *new_downtime_id = temp_downtime->downtime_id; schedule_new_event(EVENT_SCHEDULED_DOWNTIME, TRUE, event_time, FALSE, 0, NULL, FALSE, (void *)new_downtime_id, NULL, 0); } /* handle (start) downtime that is triggered by this one */ for (this_downtime = scheduled_downtime_list; this_downtime != NULL; this_downtime = this_downtime->next) { if (this_downtime->triggered_by == temp_downtime->downtime_id) handle_scheduled_downtime(this_downtime); } } return OK; }
/* 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; }
/* adds a host or service downtime entry to the list in memory */ int add_downtime(int downtime_type, char *host_name, char *svc_description, time_t entry_time, char *author, char *comment_data, time_t start_time, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long downtime_id, int is_in_effect, time_t trigger_time) { scheduled_downtime *new_downtime = NULL; scheduled_downtime *last_downtime = NULL; scheduled_downtime *temp_downtime = NULL; int result = OK; /* don't add triggered downtimes that don't have a valid parent */ if (triggered_by > 0 && find_downtime(ANY_DOWNTIME, triggered_by) == NULL) return ERROR; /* we don't have enough info */ if (host_name == NULL || (downtime_type == SERVICE_DOWNTIME && svc_description == NULL)) return ERROR; /* allocate memory for the downtime */ if ((new_downtime = (scheduled_downtime *)calloc(1, sizeof(scheduled_downtime))) == NULL) return ERROR; /* duplicate vars */ if ((new_downtime->host_name = (char *)strdup(host_name)) == NULL) result = ERROR; if (downtime_type == SERVICE_DOWNTIME) { if ((new_downtime->service_description = (char *)strdup(svc_description)) == NULL) result = ERROR; } if (author) { if ((new_downtime->author = (char *)strdup(author)) == NULL) result = ERROR; } if (comment_data) { if ((new_downtime->comment = (char *)strdup(comment_data)) == NULL) result = ERROR; } /* handle errors */ if (result == ERROR) { my_free(new_downtime->comment); my_free(new_downtime->author); my_free(new_downtime->service_description); my_free(new_downtime->host_name); my_free(new_downtime); return ERROR; } new_downtime->type = downtime_type; new_downtime->entry_time = entry_time; new_downtime->start_time = start_time; new_downtime->end_time = end_time; new_downtime->fixed = (fixed > 0) ? TRUE : FALSE; new_downtime->triggered_by = triggered_by; new_downtime->duration = duration; new_downtime->downtime_id = downtime_id; new_downtime->is_in_effect = is_in_effect; new_downtime->trigger_time = trigger_time; if (defer_downtime_sorting) { new_downtime->next = scheduled_downtime_list; scheduled_downtime_list = new_downtime; } else { /* * add new downtime to downtime list, sorted by start time, * but lock the lists first so broker modules fiddling * with them at the same time doesn't crash out. */ #ifdef NSCORE pthread_mutex_lock(&icinga_downtime_lock); #endif last_downtime = scheduled_downtime_list; for (temp_downtime = scheduled_downtime_list; temp_downtime != NULL; temp_downtime = temp_downtime->next) { if (new_downtime->start_time < temp_downtime->start_time) { new_downtime->next = temp_downtime; if (temp_downtime == scheduled_downtime_list) scheduled_downtime_list = new_downtime; else last_downtime->next = new_downtime; break; } else last_downtime = temp_downtime; } if (scheduled_downtime_list == NULL) { new_downtime->next = NULL; scheduled_downtime_list = new_downtime; } else if (temp_downtime == NULL) { new_downtime->next = NULL; last_downtime->next = new_downtime; } #ifdef NSCORE pthread_mutex_unlock(&icinga_downtime_lock); #endif } #ifdef NSCORE #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_downtime_data(NEBTYPE_DOWNTIME_LOAD, NEBFLAG_NONE, NEBATTR_NONE, downtime_type, host_name, svc_description, entry_time, author, comment_data, start_time, end_time, fixed, triggered_by, duration, downtime_id, NULL, is_in_effect, trigger_time); #endif #endif return OK; }
/* handles scheduled host or service downtime */ int handle_scheduled_downtime(scheduled_downtime *temp_downtime) { scheduled_downtime *this_downtime = NULL; host *hst = NULL; service *svc = NULL; time_t event_time = 0L; unsigned long *new_downtime_id = NULL; #ifdef USE_EVENT_BROKER int attr = 0; #endif log_debug_info(DEBUGL_FUNCTIONS, 0, "handle_scheduled_downtime()\n"); if(temp_downtime == 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) { log_debug_info(DEBUGL_DOWNTIME, 1, "Unable to find host (%s) for downtime\n", temp_downtime->host_name); return ERROR; } } else { if((svc = find_service(temp_downtime->host_name, temp_downtime->service_description)) == NULL) { log_debug_info(DEBUGL_DOWNTIME, 1, "Unable to find service (%s) host (%s) for downtime\n", temp_downtime->service_description, temp_downtime->host_name); return ERROR; } } /* have we come to the end of the scheduled downtime? */ if(temp_downtime->is_in_effect == TRUE) { #ifdef USE_EVENT_BROKER /* send data to event broker */ attr = NEBATTR_DOWNTIME_STOP_NORMAL; 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); #endif /* decrement the downtime depth variable */ if(temp_downtime->type == HOST_DOWNTIME && hst->scheduled_downtime_depth > 0) hst->scheduled_downtime_depth--; else if (svc->scheduled_downtime_depth > 0) svc->scheduled_downtime_depth--; if(temp_downtime->type == HOST_DOWNTIME && hst->scheduled_downtime_depth == 0) { log_debug_info(DEBUGL_DOWNTIME, 0, "Host '%s' has exited from a period of scheduled downtime (id=%lu).\n", hst->name, temp_downtime->downtime_id); /* log a notice - this one is parsed by the history CGI */ logit(NSLOG_INFO_MESSAGE, FALSE, "HOST DOWNTIME ALERT: %s;STOPPED; Host has exited from a period of scheduled downtime", hst->name); /* send a notification */ host_notification(hst, NOTIFICATION_DOWNTIMEEND, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE); } else if(temp_downtime->type == SERVICE_DOWNTIME && svc->scheduled_downtime_depth == 0) { log_debug_info(DEBUGL_DOWNTIME, 0, "Service '%s' on host '%s' has exited from a period of scheduled downtime (id=%lu).\n", svc->description, svc->host_name, temp_downtime->downtime_id); /* log a notice - this one is parsed by the history CGI */ logit(NSLOG_INFO_MESSAGE, FALSE, "SERVICE DOWNTIME ALERT: %s;%s;STOPPED; Service has exited from a period of scheduled downtime", svc->host_name, svc->description); /* send a notification */ service_notification(svc, NOTIFICATION_DOWNTIMEEND, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE); } /* update the status data */ if(temp_downtime->type == HOST_DOWNTIME) update_host_status(hst, FALSE); else update_service_status(svc, FALSE); /* decrement pending flex downtime if necessary */ if(temp_downtime->fixed == FALSE && temp_downtime->incremented_pending_downtime == TRUE) { if(temp_downtime->type == HOST_DOWNTIME) { if(hst->pending_flex_downtime > 0) hst->pending_flex_downtime--; } else { if(svc->pending_flex_downtime > 0) svc->pending_flex_downtime--; } } /* handle (stop) downtime that is triggered by this one */ while(1) { /* list contents might change by recursive calls, so we use this inefficient method to prevent segfaults */ for(this_downtime = scheduled_downtime_list; this_downtime != NULL; this_downtime = this_downtime->next) { if(this_downtime->triggered_by == temp_downtime->downtime_id) { handle_scheduled_downtime(this_downtime); break; } } if(this_downtime == NULL) break; } /* delete downtime entry */ if(temp_downtime->type == HOST_DOWNTIME) delete_host_downtime(temp_downtime->downtime_id); else delete_service_downtime(temp_downtime->downtime_id); } /* else we are just starting the scheduled downtime */ else { #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_downtime_data(NEBTYPE_DOWNTIME_START, NEBFLAG_NONE, NEBATTR_NONE, 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); #endif if(temp_downtime->type == HOST_DOWNTIME && hst->scheduled_downtime_depth == 0) { log_debug_info(DEBUGL_DOWNTIME, 0, "Host '%s' has entered a period of scheduled downtime (id=%lu).\n", hst->name, temp_downtime->downtime_id); /* log a notice - this one is parsed by the history CGI */ logit(NSLOG_INFO_MESSAGE, FALSE, "HOST DOWNTIME ALERT: %s;STARTED; Host has entered a period of scheduled downtime", hst->name); /* send a notification */ if( FALSE == temp_downtime->start_notification_sent) { host_notification(hst, NOTIFICATION_DOWNTIMESTART, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE); temp_downtime->start_notification_sent = TRUE; } } else if(temp_downtime->type == SERVICE_DOWNTIME && svc->scheduled_downtime_depth == 0) { log_debug_info(DEBUGL_DOWNTIME, 0, "Service '%s' on host '%s' has entered a period of scheduled downtime (id=%lu).\n", svc->description, svc->host_name, temp_downtime->downtime_id); /* log a notice - this one is parsed by the history CGI */ logit(NSLOG_INFO_MESSAGE, FALSE, "SERVICE DOWNTIME ALERT: %s;%s;STARTED; Service has entered a period of scheduled downtime", svc->host_name, svc->description); /* send a notification */ if( FALSE == temp_downtime->start_notification_sent) { service_notification(svc, NOTIFICATION_DOWNTIMESTART, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE); temp_downtime->start_notification_sent = TRUE; } } /* increment the downtime depth variable */ if(temp_downtime->type == HOST_DOWNTIME) hst->scheduled_downtime_depth++; else svc->scheduled_downtime_depth++; /* set the in effect flag */ temp_downtime->is_in_effect = TRUE; /* update the status data */ if(temp_downtime->type == HOST_DOWNTIME) update_host_status(hst, FALSE); else update_service_status(svc, FALSE); /* schedule an event to end the downtime */ if(temp_downtime->fixed == FALSE) { event_time = (time_t)((unsigned long)temp_downtime->flex_downtime_start + temp_downtime->duration); } else { event_time = temp_downtime->end_time; } if((new_downtime_id = (unsigned long *)malloc(sizeof(unsigned long *)))) { *new_downtime_id = temp_downtime->downtime_id; schedule_new_event(EVENT_SCHEDULED_DOWNTIME, TRUE, event_time, FALSE, 0, NULL, FALSE, (void *)new_downtime_id, NULL, 0); } /* handle (start) downtime that is triggered by this one */ for(this_downtime = scheduled_downtime_list; this_downtime != NULL; this_downtime = this_downtime->next) { if(this_downtime->triggered_by == temp_downtime->downtime_id) handle_scheduled_downtime(this_downtime); } } return OK; }
/* adds a host or service downtime entry to the list in memory */ int add_downtime(int downtime_type, char *host_name, char *svc_description, time_t entry_time, char *author, char *comment_data, time_t start_time, time_t flex_downtime_start, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long downtime_id, int is_in_effect, int start_notification_sent){ scheduled_downtime *new_downtime = NULL; int result = OK; log_debug_info(DEBUGL_FUNCTIONS, 0, "add_downtime()\n"); /* we don't have enough info */ if(host_name == NULL || (downtime_type == SERVICE_DOWNTIME && svc_description == NULL)) { log_debug_info(DEBUGL_DOWNTIME, 1, "Host name (%s) or service description (%s) is null\n", ((NULL == host_name) ? "null" : host_name), ((NULL == svc_description) ? "null" : svc_description)); return ERROR; } /* allocate memory for the downtime */ if((new_downtime = (scheduled_downtime *)calloc(1, sizeof(scheduled_downtime))) == NULL) { log_debug_info(DEBUGL_DOWNTIME, 1, "Unable to allocate memory for new downtime\n"); return ERROR; } /* duplicate vars */ if((new_downtime->host_name = (char *)strdup(host_name)) == NULL) { log_debug_info(DEBUGL_DOWNTIME, 1, "Unable to allocate memory for new downtime's host name\n"); result = ERROR; } if(downtime_type == SERVICE_DOWNTIME) { if((new_downtime->service_description = (char *)strdup(svc_description)) == NULL) { log_debug_info(DEBUGL_DOWNTIME, 1, "Unable to allocate memory for new downtime's service description\n"); result = ERROR; } } if(author) { if((new_downtime->author = (char *)strdup(author)) == NULL) { log_debug_info(DEBUGL_DOWNTIME, 1, "Unable to allocate memory for new downtime's author\n"); result = ERROR; } } if(comment_data) { if((new_downtime->comment = (char *)strdup(comment_data)) == NULL) { log_debug_info(DEBUGL_DOWNTIME, 1, "Unable to allocate memory for new downtime's comment\n"); result = ERROR; } } new_downtime->type = downtime_type; new_downtime->entry_time = entry_time; new_downtime->start_time = start_time; new_downtime->flex_downtime_start = flex_downtime_start; new_downtime->end_time = end_time; new_downtime->fixed = (fixed > 0) ? TRUE : FALSE; new_downtime->triggered_by = triggered_by; new_downtime->duration = duration; new_downtime->downtime_id = downtime_id; new_downtime->is_in_effect=is_in_effect; new_downtime->start_notification_sent=start_notification_sent; #ifdef NSCORE new_downtime->start_event = ( timed_event *)0; new_downtime->stop_event = ( timed_event *)0; #endif result = downtime_add(new_downtime); if (result) { if (new_downtime->type == SERVICE_DOWNTIME) { log_debug_info(DEBUGL_DOWNTIME, 0, "Failed to add downtime for service '%s' on host '%s': %s\n", new_downtime->service_description, new_downtime->host_name, dt_strerror(result)); } else { log_debug_info(DEBUGL_DOWNTIME, 0, "Failed to add downtime for host '%s': %s\n", new_downtime->host_name, dt_strerror(result)); } result = ERROR; } /* handle errors */ if(result == ERROR) { my_free(new_downtime->comment); my_free(new_downtime->author); my_free(new_downtime->service_description); my_free(new_downtime->host_name); my_free(new_downtime); return ERROR; } #ifdef NSCORE #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_downtime_data(NEBTYPE_DOWNTIME_LOAD, NEBFLAG_NONE, NEBATTR_NONE, downtime_type, host_name, svc_description, entry_time, author, comment_data, start_time, end_time, fixed, triggered_by, duration, downtime_id, NULL); #endif #endif return OK; }