/* enables flap detection for a specific host */ void enable_host_flap_detection(host *hst) { unsigned long attr = MODATTR_FLAP_DETECTION_ENABLED; log_debug_info(DEBUGL_FUNCTIONS, 0, "enable_host_flap_detection()\n"); if (hst == NULL) return; log_debug_info(DEBUGL_FLAPPING, 1, "Enabling flap detection for host '%s'.\n", hst->name); /* nothing to do... */ if (hst->flap_detection_enabled == TRUE) return; /* set the attribute modified flag */ hst->modified_attributes |= attr; /* set the flap detection enabled flag */ hst->flap_detection_enabled = TRUE; #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_adaptive_host_data(NEBTYPE_ADAPTIVEHOST_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, hst, CMD_NONE, attr, hst->modified_attributes, NULL); #endif /* check for flapping */ check_for_host_flapping(hst, FALSE, FALSE, TRUE); /* update host status */ update_host_status(hst, FALSE); return; }
/* disables flap detection for a specific host */ void disable_host_flap_detection(host *hst) { unsigned long attr = MODATTR_FLAP_DETECTION_ENABLED; log_debug_info(DEBUGL_FUNCTIONS, 0, "disable_host_flap_detection()\n"); if (hst == NULL) return; log_debug_info(DEBUGL_FLAPPING, 1, "Disabling flap detection for host '%s'.\n", hst->name); /* nothing to do... */ if (hst->flap_detection_enabled == FALSE) return; /* set the attribute modified flag */ hst->modified_attributes |= attr; /* set the flap detection enabled flag */ hst->flap_detection_enabled = FALSE; #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_adaptive_host_data(NEBTYPE_ADAPTIVEHOST_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, hst, CMD_NONE, attr, hst->modified_attributes, NULL); #endif /* handle the details... */ handle_host_flap_detection_disabled(hst); return; }
/* disables flap detection for a specific service */ void disable_service_flap_detection(service *svc){ unsigned long attr=MODATTR_FLAP_DETECTION_ENABLED; log_debug_info(DEBUGL_FUNCTIONS,0,"disable_service_flap_detection()\n"); if(svc==NULL) return; log_debug_info(DEBUGL_FLAPPING,1,"Disabling flap detection for service '%s' on host '%s'.\n",svc->description,svc->host_name); /* nothing to do... */ if(svc->flap_detection_enabled==FALSE) return; /* set the attribute modified flag */ svc->modified_attributes|=attr; /* set the flap detection enabled flag */ svc->flap_detection_enabled=FALSE; #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_adaptive_service_data(NEBTYPE_ADAPTIVESERVICE_UPDATE,NEBFLAG_NONE,NEBATTR_NONE,svc,CMD_NONE,attr,svc->modified_attributes,NULL); #endif /* handle the details... */ handle_service_flap_detection_disabled(svc); return; }
/* handles host check results in an obsessive compulsive manner... */ int obsessive_compulsive_host_check_processor(host *hst) { char *raw_command = NULL; char *processed_command = NULL; int early_timeout = FALSE; double exectime = 0.0; int macro_options = STRIP_ILLEGAL_MACRO_CHARS | ESCAPE_MACRO_CHARS; icinga_macros mac; log_debug_info(DEBUGL_FUNCTIONS, 0, "obsessive_compulsive_host_check_processor()\n"); if (hst == NULL) return ERROR; /* bail out if we shouldn't be obsessing */ if (obsess_over_hosts == FALSE) return OK; if (hst->obsess_over_host == FALSE) return OK; /* if there is no valid command, exit */ if (ochp_command == NULL) return ERROR; /* update macros */ memset(&mac, 0, sizeof(mac)); grab_host_macros_r(&mac, hst); /* get the raw command line */ get_raw_command_line_r(&mac, ochp_command_ptr, ochp_command, &raw_command, macro_options); if (raw_command == NULL) { clear_volatile_macros_r(&mac); return ERROR; } log_debug_info(DEBUGL_CHECKS, 2, "Raw obsessive compulsive host processor command line: %s\n", raw_command); /* process any macros in the raw command line */ process_macros_r(&mac, raw_command, &processed_command, macro_options); if (processed_command == NULL) { clear_volatile_macros_r(&mac); return ERROR; } log_debug_info(DEBUGL_CHECKS, 2, "Processed obsessive compulsive host processor command line: %s\n", processed_command); /* run the command */ my_system_r(&mac, processed_command, ochp_timeout, &early_timeout, &exectime, NULL, 0); clear_volatile_macros_r(&mac); /* check to see if the command timed out */ if (early_timeout == TRUE) logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: OCHP command '%s' for host '%s' timed out after %d seconds\n", processed_command, hst->name, ochp_timeout); /* free memory */ my_free(raw_command); my_free(processed_command); return OK; }
/* handles service check results in an obsessive compulsive manner... */ int obsessive_compulsive_service_check_processor(service *svc) { char *raw_command = NULL; char *processed_command = NULL; int macro_options = STRIP_ILLEGAL_MACRO_CHARS | ESCAPE_MACRO_CHARS; nagios_macros mac; struct obsessive_compulsive_job *ocj; if (svc == NULL) return ERROR; /* bail out if we shouldn't be obsessing */ if (obsess_over_services == FALSE || svc->obsess == FALSE) return OK; /* if there is no valid command, exit */ if (ocsp_command == NULL) return ERROR; /* update service macros */ memset(&mac, 0, sizeof(mac)); grab_service_macros_r(&mac, svc); get_raw_command_line_r(&mac, ocsp_command_ptr, ocsp_command, &raw_command, macro_options); if (raw_command == NULL) { clear_volatile_macros_r(&mac); return ERROR; } log_debug_info(DEBUGL_CHECKS, 2, "Raw obsessive compulsive service processor command line: %s\n", raw_command); /* process any macros in the raw command line */ process_macros_r(&mac, raw_command, &processed_command, macro_options); nm_free(raw_command); if (processed_command == NULL) { clear_volatile_macros_r(&mac); return ERROR; } log_debug_info(DEBUGL_CHECKS, 2, "Processed obsessive compulsive service processor command line: %s\n", processed_command); /* run the command through a worker */ ocj = nm_calloc(1,sizeof(struct obsessive_compulsive_job)); ocj->hst = svc->host_ptr; ocj->svc = svc; if(ERROR == wproc_run_callback(processed_command, ocsp_timeout, obsessive_compulsive_job_handler, ocj, &mac)) { nm_log(NSLOG_RUNTIME_ERROR, "Unable to start OCSP job for service '%s on host '%s' to worker\n", svc->description, svc->host_ptr->name); free(ocj); } clear_volatile_macros_r(&mac); nm_free(processed_command); return OK; }
/* checks for flexible (non-fixed) service downtime that should start now */ int check_pending_flex_service_downtime(service *svc) { scheduled_downtime *temp_downtime = NULL; time_t current_time = 0L; unsigned long * new_downtime_id = NULL; log_debug_info(DEBUGL_FUNCTIONS, 0, "check_pending_flex_service_downtime()\n"); if(svc == NULL) return ERROR; time(¤t_time); /* if service is currently ok, nothing to do */ if(svc->current_state == STATE_OK) return OK; /* check all downtime entries */ for(temp_downtime = scheduled_downtime_list; temp_downtime != NULL; temp_downtime = temp_downtime->next) { if(temp_downtime->type != SERVICE_DOWNTIME) continue; if(temp_downtime->fixed == TRUE) continue; if(temp_downtime->is_in_effect == TRUE) continue; /* triggered downtime entries should be ignored here */ if(temp_downtime->triggered_by != 0) continue; /* this entry matches our service! */ if(find_service(temp_downtime->host_name, temp_downtime->service_description) == svc) { /* if the time boundaries are okay, start this scheduled downtime */ if(temp_downtime->start_time <= current_time && current_time <= temp_downtime->end_time) { log_debug_info(DEBUGL_DOWNTIME, 0, "Flexible downtime (id=%lu) for service '%s' on host '%s' starting now...\n", temp_downtime->downtime_id, svc->description, svc->host_name); temp_downtime->flex_downtime_start = current_time; if((new_downtime_id = (unsigned long *)malloc(sizeof(unsigned long *)))) { *new_downtime_id = temp_downtime->downtime_id; temp_downtime->start_event = schedule_new_event(EVENT_SCHEDULED_DOWNTIME, TRUE, temp_downtime->flex_downtime_start, FALSE, 0, NULL, FALSE, (void *)new_downtime_id, NULL, 0); } } } } return OK; }
/* checks for flexible (non-fixed) host downtime that should start now */ int check_pending_flex_host_downtime(host *hst) { scheduled_downtime *temp_downtime = NULL; time_t current_time = 0L; unsigned long * new_downtime_id = NULL; log_debug_info(DEBUGL_FUNCTIONS, 0, "check_pending_flex_host_downtime()\n"); if(hst == NULL) return ERROR; time(¤t_time); /* if host is currently up, nothing to do */ if(hst->current_state == HOST_UP) return OK; /* check all downtime entries */ for(temp_downtime = scheduled_downtime_list; temp_downtime != NULL; temp_downtime = temp_downtime->next) { if(temp_downtime->type != HOST_DOWNTIME) continue; if(temp_downtime->fixed == TRUE) continue; if(temp_downtime->is_in_effect == TRUE) continue; /* triggered downtime entries should be ignored here */ if(temp_downtime->triggered_by != 0) continue; /* this entry matches our host! */ if(find_host(temp_downtime->host_name) == hst) { /* if the time boundaries are okay, start this scheduled downtime */ if(temp_downtime->start_time <= current_time && current_time <= temp_downtime->end_time) { log_debug_info(DEBUGL_DOWNTIME, 0, "Flexible downtime (id=%lu) for host '%s' starting now...\n", temp_downtime->downtime_id, hst->name); temp_downtime->flex_downtime_start = current_time; if((new_downtime_id = (unsigned long *)malloc(sizeof(unsigned long)))) { *new_downtime_id = temp_downtime->downtime_id; temp_downtime->start_event = schedule_new_event(EVENT_SCHEDULED_DOWNTIME, TRUE, temp_downtime->flex_downtime_start, FALSE, 0, NULL, FALSE, (void *)new_downtime_id, NULL, 0); } } } } return OK; }
/* close (unload) a particular module */ int neb_unload_module(nebmodule *mod, int flags, int reason) { int (*deinitfunc)(int, int); int result = OK; if(mod == NULL) return ERROR; log_debug_info(DEBUGL_EVENTBROKER, 0, "Attempting to unload module '%s': flags=%d, reason=%d\n", mod->filename, flags, reason); /* remove the module's demand-loaded file */ if(daemon_dumps_core == TRUE && mod->dl_file) { (void)unlink(mod->dl_file); my_free(mod->dl_file); } /* call the de-initialization function if available (and the module was initialized) */ if(mod->deinit_func && reason != NEBMODULE_ERROR_BAD_INIT) { deinitfunc = mod->deinit_func; /* module can opt to not be unloaded */ result = (*deinitfunc)(flags, reason); /* if module doesn't want to be unloaded, exit with error (unless its being forced) */ if(result != OK && !(flags & NEBMODULE_FORCE_UNLOAD)) return ERROR; } /* deregister all of the module's callbacks */ neb_deregister_module_callbacks(mod); if(mod->core_module == FALSE) { /* unload the module */ result = dlclose(mod->module_handle); if (result != 0) { logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Could not unload module '%s' -> %s\n", mod->filename, dlerror()); return ERROR; } } /* mark the module as being unloaded */ mod->is_currently_loaded = FALSE; log_debug_info(DEBUGL_EVENTBROKER, 0, "Module '%s' unloaded successfully.\n", mod->filename); logit(NSLOG_INFO_MESSAGE, FALSE, "Event broker module '%s' deinitialized successfully.\n", mod->filename); return OK; }
/* handles a host that has stopped flapping */ void clear_host_flap(host *hst, double percent_change, double high_threshold, double low_threshold) { if (hst == NULL) return; log_debug_info(DEBUGL_FLAPPING, 1, "Host '%s' stopped flapping.\n", hst->name); /* log a notice - this one is parsed by the history CGI */ nm_log(NSLOG_INFO_MESSAGE, "HOST FLAPPING ALERT: %s;STOPPED; Host appears to have stopped flapping (%2.1f%% change < %2.1f%% threshold)\n", hst->name, percent_change, low_threshold); /* delete the comment we added earlier */ if (hst->flapping_comment_id != 0) delete_host_comment(hst->flapping_comment_id); hst->flapping_comment_id = 0; /* clear the flapping indicator */ hst->is_flapping = FALSE; broker_flapping_data(NEBTYPE_FLAPPING_STOP, NEBFLAG_NONE, NEBATTR_FLAPPING_STOP_NORMAL, HOST_FLAPPING, hst, percent_change, high_threshold, low_threshold); /* send a notification */ host_notification(hst, NOTIFICATION_FLAPPINGSTOP, NULL, NULL, NOTIFICATION_OPTION_NONE); /* should we send a recovery notification? */ if (hst->check_flapping_recovery_notification == TRUE && hst->current_state == STATE_UP) host_notification(hst, NOTIFICATION_NORMAL, NULL, NULL, NOTIFICATION_OPTION_NONE); /* clear the recovery notification flag */ hst->check_flapping_recovery_notification = FALSE; return; }
/* handles a host that is flapping */ void set_host_flap(host *hst, double percent_change, double high_threshold, double low_threshold) { char *temp_buffer = NULL; if (hst == NULL) return; log_debug_info(DEBUGL_FLAPPING, 1, "Host '%s' started flapping!\n", hst->name); /* log a notice - this one is parsed by the history CGI */ nm_log(NSLOG_RUNTIME_WARNING, "HOST FLAPPING ALERT: %s;STARTED; Host appears to have started flapping (%2.1f%% change > %2.1f%% threshold)\n", hst->name, percent_change, high_threshold); /* add a non-persistent comment to the host */ nm_asprintf(&temp_buffer, "Notifications for this host are being suppressed because it was detected as having been flapping between different states (%2.1f%% change > %2.1f%% threshold). When the host state stabilizes and the flapping stops, notifications will be re-enabled.", percent_change, high_threshold); add_new_host_comment(FLAPPING_COMMENT, hst->name, time(NULL), "(Naemon Process)", temp_buffer, 0, COMMENTSOURCE_INTERNAL, FALSE, (time_t)0, &(hst->flapping_comment_id)); nm_free(temp_buffer); /* set the flapping indicator */ hst->is_flapping = TRUE; broker_flapping_data(NEBTYPE_FLAPPING_START, NEBFLAG_NONE, NEBATTR_NONE, HOST_FLAPPING, hst, percent_change, high_threshold, low_threshold); /* see if we should check to send a recovery notification out when flapping stops */ if (hst->current_state != STATE_UP && hst->current_notification_number > 0) hst->check_flapping_recovery_notification = TRUE; else hst->check_flapping_recovery_notification = FALSE; /* send a notification */ host_notification(hst, NOTIFICATION_FLAPPINGSTART, NULL, NULL, NOTIFICATION_OPTION_NONE); return; }
/* handles a service that has stopped flapping */ void clear_service_flap(service *svc, double percent_change, double high_threshold, double low_threshold) { if (svc == NULL) return; log_debug_info(DEBUGL_FLAPPING, 1, "Service '%s' on host '%s' stopped flapping.\n", svc->description, svc->host_name); /* log a notice - this one is parsed by the history CGI */ nm_log(NSLOG_INFO_MESSAGE, "SERVICE FLAPPING ALERT: %s;%s;STOPPED; Service appears to have stopped flapping (%2.1f%% change < %2.1f%% threshold)\n", svc->host_name, svc->description, percent_change, low_threshold); /* delete the comment we added earlier */ if (svc->flapping_comment_id != 0) delete_service_comment(svc->flapping_comment_id); svc->flapping_comment_id = 0; /* clear the flapping indicator */ svc->is_flapping = FALSE; broker_flapping_data(NEBTYPE_FLAPPING_STOP, NEBFLAG_NONE, NEBATTR_FLAPPING_STOP_NORMAL, SERVICE_FLAPPING, svc, percent_change, high_threshold, low_threshold); /* send a notification */ service_notification(svc, NOTIFICATION_FLAPPINGSTOP, NULL, NULL, NOTIFICATION_OPTION_NONE); /* should we send a recovery notification? */ if (svc->check_flapping_recovery_notification == TRUE && svc->current_state == STATE_OK) service_notification(svc, NOTIFICATION_NORMAL, NULL, NULL, NOTIFICATION_OPTION_NONE); /* clear the recovery notification flag */ svc->check_flapping_recovery_notification = FALSE; return; }
int is_service_in_pending_flex_downtime(struct service *temp_service) { scheduled_downtime *temp_downtime = NULL; time_t current_time = 0L; log_debug_info(DEBUGL_FUNCTIONS, 0, "is_service_in_pending_flex_downtime()\n"); if(temp_service == NULL) return FALSE; time(¤t_time); /* check all downtime entries */ for(temp_downtime = scheduled_downtime_list; temp_downtime != NULL; temp_downtime = temp_downtime->next) { if(temp_downtime->type != SERVICE_DOWNTIME) continue; if(temp_downtime->fixed == TRUE) continue; if(temp_downtime->is_in_effect == TRUE) continue; /* triggered downtime entries should be ignored here */ if(temp_downtime->triggered_by != 0) continue; /* this entry matches our service! */ if(find_service(temp_downtime->host_name, temp_downtime->service_description) == temp_service) { /* if the time boundaries are okay, start this scheduled downtime */ if(temp_downtime->start_time <= current_time && current_time <= temp_downtime->end_time) return TRUE; } } return FALSE; }
/* enables flap detection for a specific service */ void enable_service_flap_detection(service *svc) { unsigned long attr = MODATTR_FLAP_DETECTION_ENABLED; if (svc == NULL) return; log_debug_info(DEBUGL_FLAPPING, 1, "Enabling flap detection for service '%s' on host '%s'.\n", svc->description, svc->host_name); /* nothing to do... */ if (svc->flap_detection_enabled == TRUE) return; /* set the attribute modified flag */ svc->modified_attributes |= attr; /* set the flap detection enabled flag */ svc->flap_detection_enabled = TRUE; broker_adaptive_service_data(NEBTYPE_ADAPTIVESERVICE_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, svc, CMD_NONE, attr, svc->modified_attributes); /* check for flapping */ check_for_service_flapping(svc, FALSE); /* update service status */ update_service_status(svc, FALSE); return; }
/* handles a change in the status of a host */ int handle_host_event(host *hst) { icinga_macros mac; log_debug_info(DEBUGL_FUNCTIONS, 0, "handle_host_event()\n"); if (hst == NULL) return ERROR; #ifdef USE_EVENT_BROKER /* send event data to broker */ broker_statechange_data(NEBTYPE_STATECHANGE_END, NEBFLAG_NONE, NEBATTR_NONE, HOST_STATECHANGE, (void *)hst, hst->current_state, hst->state_type, hst->current_attempt, hst->max_attempts, NULL); #endif /* bail out if we shouldn't be running event handlers */ if (enable_event_handlers == FALSE) return OK; if (hst->event_handler_enabled == FALSE) return OK; /* update host macros */ memset(&mac, 0, sizeof(mac)); grab_host_macros_r(&mac, hst); /* run the global host event handler */ run_global_host_event_handler(&mac, hst); /* run the event handler command if there is one */ if (hst->event_handler != NULL) run_host_event_handler(&mac, hst); /* check for external commands - the event handler may have given us some directives... */ check_for_external_commands(); return OK; }
/* add a new module to module list */ int neb_add_module(char *filename, char *args, int should_be_loaded) { nebmodule *new_module = NULL; int x = OK; if (filename == NULL) return ERROR; /* allocate memory */ new_module = (nebmodule *)malloc(sizeof(nebmodule)); if (new_module == NULL) return ERROR; /* initialize vars */ new_module->filename = (char *)strdup(filename); new_module->args = (args == NULL) ? NULL : (char *)strdup(args); new_module->should_be_loaded = should_be_loaded; new_module->is_currently_loaded = FALSE; for (x = 0; x < NEBMODULE_MODINFO_NUMITEMS; x++) new_module->info[x] = NULL; new_module->module_handle = NULL; new_module->init_func = NULL; new_module->deinit_func = NULL; #ifdef HAVE_PTHREAD_H new_module->thread_id = (pthread_t)NULL; #endif /* add module to head of list */ new_module->next = neb_module_list; neb_module_list = new_module; log_debug_info(DEBUGL_EVENTBROKER, 0, "Added module: name='%s', args='%s', should_be_loaded='%d'\n", filename, args, should_be_loaded); return OK; }
static struct wproc_list *get_wproc_list(const char *cmd) { struct wproc_list *wp_list; char *cmd_name = NULL, *slash = NULL, *space; if (!specialized_workers) return &workers; /* first, look for a specialized worker for this command */ if ((space = strchr(cmd, ' ')) != NULL) { int namelen = (unsigned long)space - (unsigned long)cmd; cmd_name = calloc(1, namelen + 1); /* not exactly optimal, but what the hells */ if (!cmd_name) return &workers; memcpy(cmd_name, cmd, namelen); slash = strrchr(cmd_name, '/'); } wp_list = dkhash_get(specialized_workers, cmd_name ? cmd_name : cmd, NULL); if (!wp_list && slash) { wp_list = dkhash_get(specialized_workers, ++slash, NULL); } if (wp_list != NULL) { log_debug_info(DEBUGL_CHECKS, 1, "Found specialized worker(s) for '%s'", (slash && *slash != '/') ? slash : cmd_name); } if (cmd_name) free(cmd_name); return wp_list ? wp_list : &workers; }
/* add an event to list ordered by execution time */ void add_event(squeue_t *sq, timed_event *event) { log_debug_info(DEBUGL_FUNCTIONS, 0, "add_event()\n"); if (event->sq_event) { logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Adding %s event that seems to already be scheduled\n", EVENT_TYPE_STR(event->event_type)); remove_event(sq, event); } if (event->priority) { event->sq_event = squeue_add_usec(sq, event->run_time, event->priority - 1, event); } else { event->sq_event = squeue_add(sq, event->run_time, event); } if (!event->sq_event) { logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Failed to add event to squeue '%p' with prio %u: %s\n", sq, event->priority, strerror(errno)); } if (sq == nagios_squeue) track_events(event->event_type, +1); #ifdef USE_EVENT_BROKER else { /* send event data to broker */ broker_timed_event(NEBTYPE_TIMEDEVENT_ADD, NEBFLAG_NONE, NEBATTR_NONE, event, NULL); } #endif return; }
/* disables flap detection on a program wide basis */ void disable_flap_detection_routines(void) { host *temp_host = NULL; service *temp_service = NULL; unsigned long attr = MODATTR_FLAP_DETECTION_ENABLED; log_debug_info(DEBUGL_FUNCTIONS, 0, "disable_flap_detection_routines()\n"); /* bail out if we're already set */ if (enable_flap_detection == FALSE) return; /* set the attribute modified flag */ modified_host_process_attributes |= attr; modified_service_process_attributes |= attr; /* set flap detection flag */ enable_flap_detection = FALSE; #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_adaptive_program_data(NEBTYPE_ADAPTIVEPROGRAM_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, CMD_NONE, attr, modified_host_process_attributes, attr, modified_service_process_attributes, NULL); #endif /* update program status */ update_program_status(FALSE); /* handle the details... */ for (temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) handle_host_flap_detection_disabled(temp_host); for (temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) handle_service_flap_detection_disabled(temp_service); return; }
/* reschedule an event in order of execution time */ void reschedule_event(squeue_t *sq, timed_event *event) { time_t current_time = 0L; time_t (*timingfunc)(void); log_debug_info(DEBUGL_FUNCTIONS, 0, "reschedule_event()\n"); /* reschedule recurring events... */ if (event->recurring == TRUE) { /* use custom timing function */ if (event->timing_func != NULL) { timingfunc = event->timing_func; event->run_time = (*timingfunc)(); } /* normal recurring events */ else { event->run_time = event->run_time + event->event_interval; time(¤t_time); if (event->run_time < current_time) event->run_time = current_time; } } /* add the event to the event list */ add_event(sq, event); return; }
/* adjusts a timestamp variable in accordance with a system time change */ void adjust_timestamp_for_time_change(time_t last_time, time_t current_time, unsigned long time_difference, time_t *ts) { log_debug_info(DEBUGL_FUNCTIONS, 0, "adjust_timestamp_for_time_change()\n"); /* we shouldn't do anything with epoch values */ if (*ts == (time_t)0) return; /* we moved back in time... */ if (last_time > current_time) { /* we can't precede the UNIX epoch */ if (time_difference > (unsigned long)*ts) *ts = (time_t)0; else *ts = (time_t)(*ts - time_difference); } /* we moved into the future... */ else *ts = (time_t)(*ts + time_difference); return; }
/* enables flap detection on a program wide basis */ void enable_flap_detection_routines(void) { unsigned int i; unsigned long attr = MODATTR_FLAP_DETECTION_ENABLED; log_debug_info(DEBUGL_FUNCTIONS, 0, "enable_flap_detection_routines()\n"); /* bail out if we're already set */ if (enable_flap_detection == TRUE) return; /* set the attribute modified flag */ modified_host_process_attributes |= attr; modified_service_process_attributes |= attr; /* set flap detection flag */ enable_flap_detection = TRUE; #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_adaptive_program_data(NEBTYPE_ADAPTIVEPROGRAM_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, CMD_NONE, attr, modified_host_process_attributes, attr, modified_service_process_attributes, NULL); #endif /* update program status */ update_program_status(FALSE); /* check for flapping */ for (i = 0; i < num_objects.hosts; i++) check_for_host_flapping(host_ary[i], FALSE, FALSE, TRUE); for (i = 0; i < num_objects.services; i++) check_for_service_flapping(service_ary[i], FALSE, TRUE); }
/* schedule a new timed event */ timed_event *schedule_new_event(int event_type, int high_priority, time_t run_time, int recurring, unsigned long event_interval, void *timing_func, int compensate_for_time_change, void *event_data, void *event_args, int event_options) { timed_event *new_event; char run_time_string[MAX_DATETIME_LENGTH] = ""; log_debug_info(DEBUGL_FUNCTIONS, 0, "schedule_new_event()\n"); get_datetime_string(&run_time, run_time_string, MAX_DATETIME_LENGTH, SHORT_DATE_TIME); log_debug_info(DEBUGL_EVENTS, 0, "New Event Details:\n"); log_debug_info(DEBUGL_EVENTS, 0, " Type: EVENT_%s\n", EVENT_TYPE_STR(event_type)); log_debug_info(DEBUGL_EVENTS, 0, " High Priority: %s\n", (high_priority ? "Yes" : "No")); log_debug_info(DEBUGL_EVENTS, 0, " Run Time: %s\n", run_time_string); log_debug_info(DEBUGL_EVENTS, 0, " Recurring: %s\n", (recurring ? "Yes" : "No")); log_debug_info(DEBUGL_EVENTS, 0, " Event Interval: %lu\n", event_interval); log_debug_info(DEBUGL_EVENTS, 0, " Compensate for Time Change: %s\n", (compensate_for_time_change ? "Yes" : "No")); log_debug_info(DEBUGL_EVENTS, 0, " Event Options: %d\n", event_options); new_event = nm_calloc(1, sizeof(timed_event)); if (new_event != NULL) { new_event->event_type = event_type; new_event->event_data = event_data; new_event->event_args = event_args; new_event->event_options = event_options; new_event->run_time = run_time; new_event->recurring = recurring; new_event->event_interval = event_interval; new_event->timing_func = timing_func; new_event->compensate_for_time_change = compensate_for_time_change; new_event->priority = high_priority; } else return NULL; log_debug_info(DEBUGL_EVENTS, 0, " Event ID: %p\n", new_event); /* add the event to the event list */ add_event(nagios_squeue, new_event); return new_event; }
/* runs the host performance data command */ int xpddefault_run_host_performance_data_command(nagios_macros *mac, host *hst) { char *raw_command_line = NULL; char *processed_command_line = NULL; int early_timeout = FALSE; double exectime; int result = OK; int macro_options = STRIP_ILLEGAL_MACRO_CHARS | ESCAPE_MACRO_CHARS; log_debug_info(DEBUGL_FUNCTIONS, 0, "run_host_performance_data_command()\n"); if(hst == NULL) return ERROR; /* we don't have a command */ if(xpddefault_host_perfdata_command == NULL) return OK; /* get the raw command line */ get_raw_command_line_r(mac, xpddefault_host_perfdata_command_ptr, xpddefault_host_perfdata_command, &raw_command_line, macro_options); if(raw_command_line == NULL) return ERROR; log_debug_info(DEBUGL_PERFDATA, 2, "Raw host performance data command line: %s\n", raw_command_line); /* process any macros in the raw command line */ process_macros_r(mac, raw_command_line, &processed_command_line, macro_options); my_free(raw_command_line); if (!processed_command_line) return ERROR; log_debug_info(DEBUGL_PERFDATA, 2, "Processed host performance data command line: %s\n", processed_command_line); /* run the command */ my_system_r(mac, processed_command_line, xpddefault_perfdata_timeout, &early_timeout, &exectime, NULL, 0); if(processed_command_line == NULL) return ERROR; /* check to see if the command timed out */ if(early_timeout == TRUE) logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: Host performance data command '%s' for host '%s' timed out after %d seconds\n", processed_command_line, hst->name, xpddefault_perfdata_timeout); /* free memory */ my_free(processed_command_line); return result; }
/* handles a host that has stopped flapping */ void clear_host_flap(host *hst, double percent_change, double high_threshold, double low_threshold, int is_disabled) { log_debug_info(DEBUGL_FUNCTIONS, 0, "clear_host_flap()\n"); if(hst == NULL) return; if (is_disabled == 0) { log_debug_info(DEBUGL_FLAPPING, 1, "Host '%s' stopped flapping.\n", hst->name); /* log a notice - this one is parsed by the history CGI */ logit(NSLOG_INFO_MESSAGE, FALSE, "HOST FLAPPING ALERT: %s;STOPPED; Host appears to have stopped flapping (%2.1f%% change < %2.1f%% threshold)\n", hst->name, percent_change, low_threshold); } else { log_debug_info(DEBUGL_FLAPPING, 1, "Disabled flap detection for host '%s'.\n", hst->name); /* log a notice - this one is parsed by the history CGI */ logit(NSLOG_INFO_MESSAGE, FALSE, "HOST FLAPPING ALERT: %s;STOPPED; Disabled flap detection\n", hst->name); } /* delete the comment we added earlier */ if(hst->flapping_comment_id != 0) delete_host_comment(hst->flapping_comment_id); hst->flapping_comment_id = 0; /* clear the flapping indicator */ hst->is_flapping = FALSE; #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_flapping_data(NEBTYPE_FLAPPING_STOP, NEBFLAG_NONE, NEBATTR_FLAPPING_STOP_NORMAL, HOST_FLAPPING, hst, percent_change, high_threshold, low_threshold, NULL); #endif if (is_disabled == 0) { /* send a notification */ host_notification(hst, NOTIFICATION_FLAPPINGSTOP, NULL, NULL, NOTIFICATION_OPTION_NONE); /* should we send a recovery notification? */ if(hst->check_flapping_recovery_notification == TRUE && hst->current_state == HOST_UP) host_notification(hst, NOTIFICATION_NORMAL, NULL, NULL, NOTIFICATION_OPTION_NONE); } /* clear the recovery notification flag */ hst->check_flapping_recovery_notification = FALSE; return; }
/* finds a specific downtime entry */ scheduled_downtime *find_downtime(int type, unsigned long downtime_id) { scheduled_downtime *dt = NULL; log_debug_info(DEBUGL_FUNCTIONS, 0, "find_downtime()\n"); dt = fanout_get(dt_fanout, downtime_id); if (dt && (type == ANY_DOWNTIME || type == dt->type)) return dt; return NULL; }
/* close (unload) a particular module */ int neb_unload_module(nebmodule *mod, int flags, int reason) { int (*deinitfunc)(int, int); int result = OK; if (mod == NULL) return ERROR; log_debug_info(DEBUGL_EVENTBROKER, 0, "Attempting to unload module '%s': flags=%d, reason=%d\n", mod->filename, flags, reason); /* call the de-initialization function if available (and the module was initialized) */ if (mod->deinit_func && reason != NEBMODULE_ERROR_BAD_INIT) { deinitfunc = mod->deinit_func; /* module can opt to not be unloaded */ result = (*deinitfunc)(flags, reason); /* if module doesn't want to be unloaded, exit with error (unless its being forced) */ if (result != OK && !(flags & NEBMODULE_FORCE_UNLOAD)) return ERROR; } /* deregister all of the module's callbacks */ neb_deregister_module_callbacks(mod); /* unload the module */ #ifdef USE_LTDL result = lt_dlclose(mod->module_handle); #else result = dlclose(mod->module_handle); #endif /* mark the module as being unloaded */ mod->is_currently_loaded = FALSE; log_debug_info(DEBUGL_EVENTBROKER, 0, "Module '%s' unloaded successfully.\n", mod->filename); logit(NSLOG_INFO_MESSAGE, FALSE, "Event broker module '%s' deinitialized successfully.\n", mod->filename); return OK; }
/* make callbacks to modules */ int neb_make_callbacks(int callback_type, void *data) { nebcallback *temp_callback = NULL, *next_callback = NULL; int (*callbackfunc)(int, void *); register int cbresult = 0; int total_callbacks = 0; /* make sure callback list is initialized */ if (neb_callback_list == NULL) return ERROR; /* make sure the callback type is within bounds */ if (callback_type < 0 || callback_type >= NEBCALLBACK_NUMITEMS) return ERROR; log_debug_info(DEBUGL_EVENTBROKER, 1, "Making callbacks (type %d)...\n", callback_type); /* make the callbacks... */ for (temp_callback = neb_callback_list[callback_type]; temp_callback; temp_callback = next_callback) { /* Save temp_callback->next because if the callback function de-registers itself temp_callback's */ /* pointer isn't guaranteed to be usable anymore (neb_deregister_callback will free() it) */ next_callback = temp_callback->next; callbackfunc = temp_callback->callback_func; cbresult = callbackfunc(callback_type, data); temp_callback = next_callback; total_callbacks++; log_debug_info(DEBUGL_EVENTBROKER, 2, "Callback #%d (type %d) return code = %d\n", total_callbacks, callback_type, cbresult); /* module wants to cancel callbacks to other modules (and potentially cancel the default Icinga handling of an event) */ if (cbresult == NEBERROR_CALLBACKCANCEL) break; /* module wants to override default Icinga handling of an event */ /* not sure if we should bail out here just because one module wants to override things - what about other modules? EG 12/11/2006 */ else if (cbresult == NEBERROR_CALLBACKOVERRIDE) break; } return cbresult; }
/* handles a service that is flapping */ void set_service_flap(service *svc, double percent_change, double high_threshold, double low_threshold, int allow_flapstart_notification) { char *temp_buffer = NULL; log_debug_info(DEBUGL_FUNCTIONS, 0, "set_service_flap()\n"); if(svc == NULL) return; log_debug_info(DEBUGL_FLAPPING, 1, "Service '%s' on host '%s' started flapping!\n", svc->description, svc->host_name); /* log a notice - this one is parsed by the history CGI */ logit(NSLOG_RUNTIME_WARNING, FALSE, "SERVICE FLAPPING ALERT: %s;%s;STARTED; Service appears to have started flapping (%2.1f%% change >= %2.1f%% threshold)\n", svc->host_name, svc->description, percent_change, high_threshold); if (svc->flapping_comment_id == 0) { /* add a non-persistent comment to the service */ asprintf(&temp_buffer, "Notifications for this service are being suppressed because it was detected as having been flapping between different states (%2.1f%% change >= %2.1f%% threshold). When the service state stabilizes and the flapping stops, notifications will be re-enabled.", percent_change, high_threshold); add_new_service_comment(FLAPPING_COMMENT, svc->host_name, svc->description, time(NULL), "(Nagios Process)", temp_buffer, 0, COMMENTSOURCE_INTERNAL, FALSE, (time_t)0, &(svc->flapping_comment_id)); my_free(temp_buffer); } /* set the flapping indicator */ svc->is_flapping = TRUE; #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_flapping_data(NEBTYPE_FLAPPING_START, NEBFLAG_NONE, NEBATTR_NONE, SERVICE_FLAPPING, svc, percent_change, high_threshold, low_threshold, NULL); #endif /* see if we should check to send a recovery notification out when flapping stops */ if(svc->current_state != STATE_OK && svc->current_notification_number > 0) svc->check_flapping_recovery_notification = TRUE; else svc->check_flapping_recovery_notification = FALSE; /* send a notification */ if(allow_flapstart_notification == TRUE) service_notification(svc, NOTIFICATION_FLAPPINGSTART, NULL, NULL, NOTIFICATION_OPTION_NONE); return; }
/* runs the host performance data command */ int xpddefault_run_host_performance_data_command(nagios_macros *mac, host *hst) { char *raw_command_line = NULL; char *processed_command_line = NULL; int result = OK; int macro_options = STRIP_ILLEGAL_MACRO_CHARS | ESCAPE_MACRO_CHARS; log_debug_info(DEBUGL_FUNCTIONS, 0, "run_host_performance_data_command()\n"); if (hst == NULL) return ERROR; /* we don't have a command */ if (host_perfdata_command == NULL) return OK; /* get the raw command line */ get_raw_command_line_r(mac, host_perfdata_command_ptr, host_perfdata_command, &raw_command_line, macro_options); if (raw_command_line == NULL) return ERROR; log_debug_info(DEBUGL_PERFDATA, 2, "Raw host performance data command line: %s\n", raw_command_line); /* process any macros in the raw command line */ process_macros_r(mac, raw_command_line, &processed_command_line, macro_options); my_free(raw_command_line); if (!processed_command_line) return ERROR; log_debug_info(DEBUGL_PERFDATA, 2, "Processed host performance data command line: %s\n", processed_command_line); /* run the command */ wproc_run_callback(processed_command_line, perfdata_timeout, xpddefault_perfdata_job_handler, NULL, mac); /* free memory */ my_free(processed_command_line); return result; }
/* handles scheduled downtime (id passed from timed event queue) */ int handle_scheduled_downtime_by_id(unsigned long downtime_id) { scheduled_downtime *temp_downtime = NULL; log_debug_info(DEBUGL_FUNCTIONS, 0, "handle_scheduled_downtime_by_id()\n"); /* find the downtime entry */ if((temp_downtime = find_downtime(ANY_DOWNTIME, downtime_id)) == NULL) { log_debug_info(DEBUGL_DOWNTIME, 1, "Unable to find downtime id: %lu\n", downtime_id); return ERROR; } /* NULL out this event's start time since the calling function, handle_timed_event(), will free the event, this will prevent unschedule_downtime from freeing something that has already been freed. The start event is not needed within handle_scheduled_downtime(). */ temp_downtime->start_event = NULL; /* handle the downtime */ return handle_scheduled_downtime(temp_downtime); }