/* 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; }
void game_frame() { static char cbak; static int8_t gpx, gpy; // mouse vram[cy / 8][cx / 8] = cbak; cy += mouse_y; mouse_y=0; if (cy < 0) cy = VGA_V_PIXELS; else if (cy >= VGA_V_PIXELS) cy = 0; cx += mouse_x; mouse_x=0; if (cx < 0) cx = VGA_H_PIXELS; else if (cx >= VGA_H_PIXELS) cx = 0; printhex(11,6,cx/8); printhex(16,6,cy/8); cbak = vram[cy / 8][cx / 8]; vram[cy / 8][cx / 8] = 127; vram[6][19]=mouse_buttons & mousebut_left?'L':'l'; vram[6][20]=mouse_buttons & mousebut_middle?'M':'m'; vram[6][21]=mouse_buttons & mousebut_right?'R':'r'; printhex(23,6,mouse_buttons); // gamepad buttons update_controller(PAD_X, PAD_Y,gamepad_buttons[0]); update_controller(PAD_X, PAD_Y2,gamepad_buttons[1]); // analog gamepad printhex(40,PAD_Y-2,gamepad_x[0]); printhex(43,PAD_Y-2,gamepad_y[0]); vram[15 + gpy / 32][36 + gpx / 16] = ' '; gpx = gamepad_x[0]; gpy = gamepad_y[0]; vram[15 + gpy / 32][36 + gpx / 16] = '+'; // KB codes for (int i=0;i<6;i++) { printhex(5+i*3,KB_Y+2,keyboard_key[0][i]); } // KB mods for (int i=0;i<8;i++) vram[KB_Y+3][5+i]=keyboard_mod[0] & (1<<i) ? KBMOD[i] : '-' ; // low level stuff update_host_status(); }
/* handles the details for a host when flap detection is disabled (globally or per-host) */ void handle_host_flap_detection_disabled(host *hst) { log_debug_info(DEBUGL_FUNCTIONS, 0, "handle_host_flap_detection_disabled()\n"); if (hst == NULL) return; /* if the host was flapping, remove the flapping indicator */ if (hst->is_flapping == TRUE) { hst->is_flapping = FALSE; /* delete the original comment we added earlier */ if (hst->flapping_comment_id != 0) delete_host_comment(hst->flapping_comment_id); hst->flapping_comment_id = 0; /* log a notice - this one is parsed by the history CGI */ logit(NSLOG_INFO_MESSAGE, FALSE, "HOST FLAPPING ALERT: %s;DISABLED; Flap detection has been disabled\n", hst->name); #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_flapping_data(NEBTYPE_FLAPPING_STOP, NEBFLAG_NONE, NEBATTR_FLAPPING_STOP_DISABLED, HOST_FLAPPING, hst, hst->percent_state_change, 0.0, 0.0, NULL); #endif /* send a notification */ host_notification(hst, NOTIFICATION_FLAPPINGDISABLED, 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; } /* update host status */ update_host_status(hst, FALSE); return; }
/* attempts to compensate for a change in the system time */ void compensate_for_system_time_change(unsigned long last_time, unsigned long current_time) { unsigned long time_difference = 0L; service *temp_service = NULL; host *temp_host = NULL; int days = 0; int hours = 0; int minutes = 0; int seconds = 0; int delta = 0; log_debug_info(DEBUGL_FUNCTIONS, 0, "compensate_for_system_time_change() start\n"); /* * if current_time < last_time, delta will be negative so we can * still use addition to all effected timestamps */ delta = current_time - last_time; /* we moved back in time... */ if (last_time > current_time) { time_difference = last_time - current_time; get_time_breakdown(time_difference, &days, &hours, &minutes, &seconds); log_debug_info(DEBUGL_EVENTS, 0, "Detected a backwards time change of %dd %dh %dm %ds.\n", days, hours, minutes, seconds); } /* we moved into the future... */ else { time_difference = current_time - last_time; get_time_breakdown(time_difference, &days, &hours, &minutes, &seconds); log_debug_info(DEBUGL_EVENTS, 0, "Detected a forwards time change of %dd %dh %dm %ds.\n", days, hours, minutes, seconds); } /* log the time change */ logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_WARNING, TRUE, "Warning: A system time change of %d seconds (%dd %dh %dm %ds %s in time) has been detected. Compensating...\n", delta, days, hours, minutes, seconds, (last_time > current_time) ? "backwards" : "forwards"); adjust_squeue_for_time_change(&nagios_squeue, delta); /* adjust service timestamps */ for (temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) { adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_service->last_notification); adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_service->last_check); adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_service->next_check); adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_service->last_state_change); adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_service->last_hard_state_change); /* recalculate next re-notification time */ temp_service->next_notification = get_next_service_notification_time(temp_service, temp_service->last_notification); /* update the status data */ update_service_status(temp_service, FALSE); } /* adjust host timestamps */ for (temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_host->last_notification); adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_host->last_check); adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_host->next_check); adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_host->last_state_change); adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_host->last_hard_state_change); adjust_timestamp_for_time_change(last_time, current_time, time_difference, &temp_host->last_state_history_update); /* recalculate next re-notification time */ temp_host->next_notification = get_next_host_notification_time(temp_host, temp_host->last_notification); /* update the status data */ update_host_status(temp_host, FALSE); } /* adjust program timestamps */ adjust_timestamp_for_time_change(last_time, current_time, time_difference, &program_start); adjust_timestamp_for_time_change(last_time, current_time, time_difference, &event_start); /* update the status data */ update_program_status(FALSE); return; }
/* initialize the event timing loop before we start monitoring */ void init_timing_loop(void) { host *temp_host = NULL; service *temp_service = NULL; time_t current_time = 0L; struct timeval tv[9]; double runtime[9]; struct timeval now; log_debug_info(DEBUGL_FUNCTIONS, 0, "init_timing_loop() start\n"); /* get the time and seed the prng */ gettimeofday(&now, NULL); current_time = now.tv_sec; srand((now.tv_sec << 10) ^ now.tv_usec); /******** GET BASIC HOST/SERVICE INFO ********/ memset(&scheduling_info, 0, sizeof(scheduling_info)); if (test_scheduling == TRUE) gettimeofday(&tv[0], NULL); /* get info on service checks to be scheduled */ for (temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) { scheduling_info.total_services++; /* maybe we shouldn't schedule this check */ if (temp_service->check_interval == 0 || !temp_service->checks_enabled) { log_debug_info(DEBUGL_EVENTS, 1, "Service '%s' on host '%s' should not be scheduled.\n", temp_service->description, temp_service->host_name); temp_service->should_be_scheduled = FALSE; continue; } scheduling_info.total_scheduled_services++; } if (test_scheduling == TRUE) gettimeofday(&tv[1], NULL); /* get info on host checks to be scheduled */ for (temp_host = host_list; temp_host; temp_host = temp_host->next) { scheduling_info.total_hosts++; /* host has no check interval */ if (temp_host->check_interval == 0 || !temp_host->checks_enabled) { log_debug_info(DEBUGL_EVENTS, 1, "Host '%s' should not be scheduled.\n", temp_host->name); temp_host->should_be_scheduled = FALSE; continue; } scheduling_info.total_scheduled_hosts++; } if (test_scheduling == TRUE) gettimeofday(&tv[2], NULL); scheduling_info.average_services_per_host = (double)((double)scheduling_info.total_services / (double)scheduling_info.total_hosts); scheduling_info.average_scheduled_services_per_host = (double)((double)scheduling_info.total_scheduled_services / (double)scheduling_info.total_hosts); /* adjust the check interval total to correspond to the interval length */ scheduling_info.service_check_interval_total = (scheduling_info.service_check_interval_total * interval_length); /* calculate the average check interval for services */ scheduling_info.average_service_check_interval = (double)((double)scheduling_info.service_check_interval_total / (double)scheduling_info.total_scheduled_services); if (test_scheduling == TRUE) gettimeofday(&tv[3], NULL); /******** SCHEDULE SERVICE CHECKS ********/ log_debug_info(DEBUGL_EVENTS, 2, "Scheduling service checks..."); for (temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) { log_debug_info(DEBUGL_EVENTS, 2, "Service '%s' on host '%s'\n", temp_service->description, temp_service->host_name); /* skip this service if it shouldn't be scheduled */ if (temp_service->should_be_scheduled == FALSE) { continue; } temp_service->next_check = current_time + ranged_urand(0, check_window(temp_service)); if (scheduling_info.last_service_check < temp_service->next_check) scheduling_info.last_service_check = temp_service->next_check; if (!scheduling_info.first_service_check || scheduling_info.first_service_check > temp_service->next_check) scheduling_info.first_service_check = temp_service->next_check; log_debug_info(DEBUGL_EVENTS, 2, "Check Time: %lu --> %s", (unsigned long)temp_service->next_check, ctime(&temp_service->next_check)); } if (test_scheduling == TRUE) gettimeofday(&tv[4], NULL); /* add scheduled service checks to event queue */ for (temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) { /* update status of all services (scheduled or not) */ update_service_status(temp_service, FALSE); /* skip most services that shouldn't be scheduled */ if (temp_service->should_be_scheduled == FALSE) { /* passive checks are an exception if a forced check was scheduled before we restarted */ if (!(temp_service->checks_enabled == FALSE && temp_service->next_check != (time_t)0L && (temp_service->check_options & CHECK_OPTION_FORCE_EXECUTION))) continue; } /* create a new service check event */ temp_service->next_check_event = schedule_new_event(EVENT_SERVICE_CHECK, FALSE, temp_service->next_check, FALSE, 0, NULL, TRUE, (void *)temp_service, NULL, temp_service->check_options); } if (test_scheduling == TRUE) gettimeofday(&tv[5], NULL); if (test_scheduling == TRUE) gettimeofday(&tv[6], NULL); /******** SCHEDULE HOST CHECKS ********/ log_debug_info(DEBUGL_EVENTS, 2, "Scheduling host checks..."); /* determine check times for host checks */ for (temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { log_debug_info(DEBUGL_EVENTS, 2, "Host '%s'\n", temp_host->name); /* skip hosts that shouldn't be scheduled */ if (temp_host->should_be_scheduled == FALSE) { continue; } temp_host->next_check = current_time + ranged_urand(0, check_window(temp_host)); log_debug_info(DEBUGL_EVENTS, 2, "Check Time: %lu --> %s", (unsigned long)temp_host->next_check, ctime(&temp_host->next_check)); if (temp_host->next_check > scheduling_info.last_host_check) scheduling_info.last_host_check = temp_host->next_check; if (!scheduling_info.first_host_check || scheduling_info.first_host_check > temp_host->next_check) scheduling_info.first_host_check = temp_host->next_check; } if (test_scheduling == TRUE) gettimeofday(&tv[7], NULL); /* add scheduled host checks to event queue */ for (temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { /* update status of all hosts (scheduled or not) */ update_host_status(temp_host, FALSE); /* skip most hosts that shouldn't be scheduled */ if (temp_host->should_be_scheduled == FALSE) { /* passive checks are an exception if a forced check was scheduled before Nagios was restarted */ if (!(temp_host->checks_enabled == FALSE && temp_host->next_check != (time_t)0L && (temp_host->check_options & CHECK_OPTION_FORCE_EXECUTION))) continue; } /* schedule a new host check event */ temp_host->next_check_event = schedule_new_event(EVENT_HOST_CHECK, FALSE, temp_host->next_check, FALSE, 0, NULL, TRUE, (void *)temp_host, NULL, temp_host->check_options); } if (test_scheduling == TRUE) gettimeofday(&tv[8], NULL); /******** SCHEDULE MISC EVENTS ********/ /* add a check result reaper event */ schedule_new_event(EVENT_CHECK_REAPER, TRUE, current_time + check_reaper_interval, TRUE, check_reaper_interval, NULL, TRUE, NULL, NULL, 0); /* add an orphaned check event */ if (check_orphaned_services == TRUE || check_orphaned_hosts == TRUE) schedule_new_event(EVENT_ORPHAN_CHECK, TRUE, current_time + DEFAULT_ORPHAN_CHECK_INTERVAL, TRUE, DEFAULT_ORPHAN_CHECK_INTERVAL, NULL, TRUE, NULL, NULL, 0); /* add a service result "freshness" check event */ if (check_service_freshness == TRUE) schedule_new_event(EVENT_SFRESHNESS_CHECK, TRUE, current_time + service_freshness_check_interval, TRUE, service_freshness_check_interval, NULL, TRUE, NULL, NULL, 0); /* add a host result "freshness" check event */ if (check_host_freshness == TRUE) schedule_new_event(EVENT_HFRESHNESS_CHECK, TRUE, current_time + host_freshness_check_interval, TRUE, host_freshness_check_interval, NULL, TRUE, NULL, NULL, 0); /* add a status save event */ schedule_new_event(EVENT_STATUS_SAVE, TRUE, current_time + status_update_interval, TRUE, status_update_interval, NULL, TRUE, NULL, NULL, 0); /* add a retention data save event if needed */ if (retain_state_information == TRUE && retention_update_interval > 0) schedule_new_event(EVENT_RETENTION_SAVE, TRUE, current_time + (retention_update_interval * 60), TRUE, (retention_update_interval * 60), NULL, TRUE, NULL, NULL, 0); if (test_scheduling == TRUE) { runtime[0] = (double)((double)(tv[1].tv_sec - tv[0].tv_sec) + (double)((tv[1].tv_usec - tv[0].tv_usec) / 1000.0) / 1000.0); runtime[1] = (double)((double)(tv[2].tv_sec - tv[1].tv_sec) + (double)((tv[2].tv_usec - tv[1].tv_usec) / 1000.0) / 1000.0); runtime[2] = (double)((double)(tv[3].tv_sec - tv[2].tv_sec) + (double)((tv[3].tv_usec - tv[2].tv_usec) / 1000.0) / 1000.0); runtime[3] = (double)((double)(tv[4].tv_sec - tv[3].tv_sec) + (double)((tv[4].tv_usec - tv[3].tv_usec) / 1000.0) / 1000.0); runtime[4] = (double)((double)(tv[5].tv_sec - tv[4].tv_sec) + (double)((tv[5].tv_usec - tv[4].tv_usec) / 1000.0) / 1000.0); runtime[5] = (double)((double)(tv[6].tv_sec - tv[5].tv_sec) + (double)((tv[6].tv_usec - tv[5].tv_usec) / 1000.0) / 1000.0); runtime[6] = (double)((double)(tv[7].tv_sec - tv[6].tv_sec) + (double)((tv[7].tv_usec - tv[6].tv_usec) / 1000.0) / 1000.0); runtime[7] = (double)((double)(tv[8].tv_sec - tv[7].tv_sec) + (double)((tv[8].tv_usec - tv[7].tv_usec) / 1000.0) / 1000.0); runtime[8] = (double)((double)(tv[8].tv_sec - tv[0].tv_sec) + (double)((tv[8].tv_usec - tv[0].tv_usec) / 1000.0) / 1000.0); printf("EVENT SCHEDULING TIMES\n"); printf("-------------------------------------\n"); printf("Get service info: %.6lf sec\n", runtime[0]); printf("Get host info info: %.6lf sec\n", runtime[1]); printf("Get service params: %.6lf sec\n", runtime[2]); printf("Schedule service times: %.6lf sec\n", runtime[3]); printf("Schedule service events: %.6lf sec\n", runtime[4]); printf("Get host params: %.6lf sec\n", runtime[5]); printf("Schedule host times: %.6lf sec\n", runtime[6]); printf("Schedule host events: %.6lf sec\n", runtime[7]); printf(" ============\n"); printf("TOTAL: %.6lf sec\n", runtime[8]); printf("\n\n"); } log_debug_info(DEBUGL_FUNCTIONS, 0, "init_timing_loop() end\n"); return; }
static int should_run_event(timed_event *temp_event) { int run_event = TRUE; /* default action is to execute the event */ int nudge_seconds = 0; /* we only care about jobs that cause processes to run */ if (temp_event->event_type != EVENT_HOST_CHECK && temp_event->event_type != EVENT_SERVICE_CHECK) { return TRUE; } /* if we can't spawn any more jobs, don't bother */ if (!wproc_can_spawn(&loadctl)) { wproc_reap(100, 3000); return FALSE; } /* run a few checks before executing a service check... */ if (temp_event->event_type == EVENT_SERVICE_CHECK) { service *temp_service = (service *)temp_event->event_data; /* forced checks override normal check logic */ if ((temp_service->check_options & CHECK_OPTION_FORCE_EXECUTION)) return TRUE; /* don't run a service check if we're already maxed out on the number of parallel service checks... */ if (max_parallel_service_checks != 0 && (currently_running_service_checks >= max_parallel_service_checks)) { nudge_seconds = ranged_urand(5, 17); logit(NSLOG_RUNTIME_WARNING, TRUE, "\tMax concurrent service checks (%d) has been reached. Nudging %s:%s by %d seconds...\n", max_parallel_service_checks, temp_service->host_name, temp_service->description, nudge_seconds); run_event = FALSE; } /* don't run a service check if active checks are disabled */ if (execute_service_checks == FALSE) { log_debug_info(DEBUGL_EVENTS | DEBUGL_CHECKS, 1, "We're not executing service checks right now, so we'll skip check event for service '%s;%s'.\n", temp_service->host_name, temp_service->description); run_event = FALSE; } /* reschedule the check if we can't run it now */ if (run_event == FALSE) { remove_event(nagios_squeue, temp_event); if (nudge_seconds) { /* We nudge the next check time when it is due to too many concurrent service checks */ temp_service->next_check = (time_t)(temp_service->next_check + nudge_seconds); } else { temp_service->next_check += check_window(temp_service); } temp_event->run_time = temp_service->next_check; reschedule_event(nagios_squeue, temp_event); update_service_status(temp_service, FALSE); run_event = FALSE; } } /* run a few checks before executing a host check... */ else if (temp_event->event_type == EVENT_HOST_CHECK) { host *temp_host = (host *)temp_event->event_data; /* forced checks override normal check logic */ if ((temp_host->check_options & CHECK_OPTION_FORCE_EXECUTION)) return TRUE; /* don't run a host check if active checks are disabled */ if (execute_host_checks == FALSE) { log_debug_info(DEBUGL_EVENTS | DEBUGL_CHECKS, 1, "We're not executing host checks right now, so we'll skip host check event for host '%s'.\n", temp_host->name); run_event = FALSE; } /* reschedule the host check if we can't run it right now */ if (run_event == FALSE) { remove_event(nagios_squeue, temp_event); temp_host->next_check += check_window(temp_host); temp_event->run_time = temp_host->next_check; reschedule_event(nagios_squeue, temp_event); update_host_status(temp_host, FALSE); run_event = FALSE; } } return run_event; }
/* 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; }
/* 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; }
void poll_host(int host_id) { char query1[BUFSIZE]; char query2[BUFSIZE]; char *query3; char query4[BUFSIZE]; char errstr[512]; int num_rows; int host_status; int assert_fail = 0; char *poll_result = NULL; char logmessage[LOGSIZE]; char update_sql[BUFSIZE]; reindex_t *reindex; target_t *entry; host_t *host; ping_t *ping; MYSQL mysql; MYSQL_RES *result; MYSQL_ROW row; /* allocate host and ping structures with appropriate values */ host = (host_t *) malloc(sizeof(host_t)); ping = (ping_t *) malloc(sizeof(ping_t)); #ifndef OLD_MYSQL mysql_thread_init(); #endif snprintf(query1, sizeof(query1), "select action,hostname,snmp_community,snmp_version,snmp_username,snmp_password,rrd_name,rrd_path,arg1,arg2,arg3,local_data_id,rrd_num,snmp_port,snmp_timeout from poller_item where host_id=%i order by rrd_path,rrd_name", host_id); snprintf(query2, sizeof(query2), "select id, hostname,snmp_community,snmp_version,snmp_port,snmp_timeout,status,status_event_count,status_fail_date,status_rec_date,status_last_error,min_time,max_time,cur_time,avg_time,total_polls,failed_polls,availability from host where id=%i", host_id); snprintf(query4, sizeof(query4), "select data_query_id,action,op,assert_value,arg1 from poller_reindex where host_id=%i", host_id); db_connect(set.dbdb, &mysql); /* get data about this host */ result = db_query(&mysql, query2); num_rows = (int)mysql_num_rows(result); if (num_rows != 1) { snprintf(logmessage, LOGSIZE, "Host[%i] ERROR: Unknown Host ID", host_id); cacti_log(logmessage); return; } row = mysql_fetch_row(result); /* populate host structure */ host->id = atoi(row[0]); if (row[1] != NULL) snprintf(host->hostname, sizeof(host->hostname), "%s", row[1]); if (row[2] != NULL) snprintf(host->snmp_community, sizeof(host->snmp_community), "%s", row[2]); host->snmp_version = atoi(row[3]); host->snmp_port = atoi(row[4]); host->snmp_timeout = atoi(row[5]); if (row[6] != NULL) host->status = atoi(row[6]); host->status_event_count = atoi(row[7]); snprintf(host->status_fail_date, sizeof(host->status_fail_date), "%s", row[8]); snprintf(host->status_rec_date, sizeof(host->status_rec_date), "%s", row[9]); snprintf(host->status_last_error, sizeof(host->status_last_error), "%s", row[10]); host->min_time = atof(row[11]); host->max_time = atof(row[12]); host->cur_time = atof(row[13]); host->avg_time = atof(row[14]); host->total_polls = atoi(row[15]); host->failed_polls = atoi(row[16]); host->availability = atof(row[17]); host->ignore_host = 0; /* initialize SNMP */ snmp_host_init(host); /* perform a check to see if the host is alive by polling it's SysDesc * if the host down from an snmp perspective, don't poll it. * function sets the ignore_host bit */ if ((set.availability_method == AVAIL_SNMP) && (host->snmp_community == "")) { update_host_status(HOST_UP, host, ping, set.availability_method); if (set.verbose >= POLLER_VERBOSITY_MEDIUM) { snprintf(logmessage, LOGSIZE, "Host[%s] No host availability check possible for '%s'\n", host->id, host->hostname); cacti_log(logmessage); } } else { if (ping_host(host, ping) == HOST_UP) { update_host_status(HOST_UP, host, ping, set.availability_method); } else { host->ignore_host = 1; update_host_status(HOST_DOWN, host, ping, set.availability_method); } } /* update host table */ snprintf(update_sql, sizeof(update_sql), "update host set status='%i',status_event_count='%i', status_fail_date='%s',status_rec_date='%s',status_last_error='%s',min_time='%f',max_time='%f',cur_time='%f',avg_time='%f',total_polls='%i',failed_polls='%i',availability='%.4f' where id='%i'\n", host->status, host->status_event_count, host->status_fail_date, host->status_rec_date, host->status_last_error, host->min_time, host->max_time, host->cur_time, host->avg_time, host->total_polls, host->failed_polls, host->availability, host->id); db_insert(&mysql, update_sql); /* do the reindex check for this host */ if (!host->ignore_host) { reindex = (reindex_t *) malloc(sizeof(reindex_t)); result = db_query(&mysql, query4); num_rows = (int)mysql_num_rows(result); if (num_rows > 0) { if (set.verbose == POLLER_VERBOSITY_DEBUG) { snprintf(logmessage, LOGSIZE, "Host[%i] RECACHE: Processing %i items in the auto reindex cache for '%s'\n", host->id, num_rows, host->hostname); cacti_log(logmessage); } while ((row = mysql_fetch_row(result))) { assert_fail = 0; reindex->data_query_id = atoi(row[0]); reindex->action = atoi(row[1]); if (row[2] != NULL) snprintf(reindex->op, sizeof(reindex->op), "%s", row[2]); if (row[3] != NULL) snprintf(reindex->assert_value, sizeof(reindex->assert_value), "%s", row[3]); if (row[4] != NULL) snprintf(reindex->arg1, sizeof(reindex->arg1), "%s", row[4]); switch(reindex->action) { case POLLER_ACTION_SNMP: /* snmp */ poll_result = snmp_get(host, reindex->arg1); break; case POLLER_ACTION_SCRIPT: /* script (popen) */ poll_result = exec_poll(host, reindex->arg1); break; } /* assume ok if host is up and result wasn't obtained */ if (!strcmp(poll_result,"U")) { assert_fail = 0; } else if ((!strcmp(reindex->op, "=")) && (strcmp(reindex->assert_value,poll_result) != 0)) { snprintf(logmessage, LOGSIZE, "ASSERT: '%s=%s' failed. Recaching host '%s', data query #%i\n", reindex->assert_value, poll_result, host->hostname, reindex->data_query_id); cacti_log(logmessage); query3 = (char *)malloc(128); snprintf(query3, 128, "insert into poller_command (poller_id,time,action,command) values (0,NOW(),%i,'%i:%i')", POLLER_COMMAND_REINDEX, host_id, reindex->data_query_id); db_insert(&mysql, query3); free(query3); assert_fail = 1; } else if ((!strcmp(reindex->op, ">")) && (strtoll(reindex->assert_value, (char **)NULL, 10) <= strtoll(poll_result, (char **)NULL, 10))) { snprintf(logmessage, LOGSIZE, "ASSERT: '%s>%s' failed. Recaching host '%s', data query #%i\n", reindex->assert_value, poll_result, host->hostname, reindex->data_query_id); cacti_log(logmessage); query3 = (char *)malloc(128); snprintf(query3, 128, "insert into poller_command (poller_id,time,action,command) values (0,NOW(),%i,'%i:%i')", POLLER_COMMAND_REINDEX, host_id, reindex->data_query_id); db_insert(&mysql, query3); free(query3); assert_fail = 1; } else if ((!strcmp(reindex->op, "<")) && (strtoll(reindex->assert_value, (char **)NULL, 10) >= strtoll(poll_result, (char **)NULL, 10))) { snprintf(logmessage, LOGSIZE, "ASSERT: '%s<%s' failed. Recaching host '%s', data query #%i\n", reindex->assert_value, poll_result, host->hostname, reindex->data_query_id); cacti_log(logmessage); query3 = (char *)malloc(128); snprintf(query3, 128, "insert into poller_command (poller_id,time,action,command) values (0,NOW(),%i,'%i:%i')", POLLER_COMMAND_REINDEX, host_id, reindex->data_query_id); db_insert(&mysql, query3); free(query3); assert_fail = 1; } /* update 'poller_reindex' with the correct information if: * 1) the assert fails * 2) the OP code is > or < meaning the current value could have changed without causing * the assert to fail */ if ((assert_fail == 1) || (!strcmp(reindex->op, ">")) || (!strcmp(reindex->op, ">"))) { query3 = (char *)malloc(255); snprintf(query3, 255, "update poller_reindex set assert_value='%s' where host_id='%i' and data_query_id='%i' and arg1='%s'", poll_result, host_id, reindex->data_query_id, reindex->arg1); db_insert(&mysql, query3); free(query3); } free(poll_result); } } } /* retreive each hosts polling items from poller cache */ entry = (target_t *) malloc(sizeof(target_t)); result = db_query(&mysql, query1); num_rows = (int)mysql_num_rows(result); while ((row = mysql_fetch_row(result)) && (!host->ignore_host)) { /* initialize monitored object */ entry->target_id = 0; entry->action = atoi(row[0]); if (row[1] != NULL) snprintf(entry->hostname, sizeof(entry->hostname), "%s", row[1]); if (row[2] != NULL) { snprintf(entry->snmp_community, sizeof(entry->snmp_community), "%s", row[2]); } else { snprintf(entry->snmp_community, sizeof(entry->snmp_community), "%s", ""); } entry->snmp_version = atoi(row[3]); if (row[4] != NULL) snprintf(entry->snmp_username, sizeof(entry->snmp_username), "%s", row[4]); if (row[5] != NULL) snprintf(entry->snmp_password, sizeof(entry->snmp_password), "%s", row[5]); if (row[6] != NULL) snprintf(entry->rrd_name, sizeof(entry->rrd_name), "%s", row[6]); if (row[7] != NULL) snprintf(entry->rrd_path, sizeof(entry->rrd_path), "%s", row[7]); if (row[8] != NULL) snprintf(entry->arg1, sizeof(entry->arg1), "%s", row[8]); if (row[9] != NULL) snprintf(entry->arg2, sizeof(entry->arg2), "%s", row[9]); if (row[10] != NULL) snprintf(entry->arg3, sizeof(entry->arg3), "%s", row[10]); entry->local_data_id = atoi(row[11]); entry->rrd_num = atoi(row[12]); entry->snmp_port = atoi(row[13]); entry->snmp_timeout = atoi(row[14]); snprintf(entry->result, sizeof(entry->result), "%s", "U"); if (!host->ignore_host) { switch(entry->action) { case POLLER_ACTION_SNMP: /* raw SNMP poll */ poll_result = snmp_get(host, entry->arg1); snprintf(entry->result, sizeof(entry->result), "%s", poll_result); free(poll_result); if (host->ignore_host) { snprintf(logmessage, LOGSIZE, "Host[%i] ERROR: SNMP timeout detected [%i milliseconds], ignoring host '%s'\n", host_id, host->snmp_timeout, host->hostname); cacti_log(logmessage); snprintf(entry->result, sizeof(entry->result), "%s", "U"); } else { /* remove double or single quotes from string */ strncpy(entry->result, strip_quotes(entry->result), sizeof(entry->result)); /* detect erroneous non-numeric result */ if (!is_numeric(entry->result)) { strncpy(errstr, entry->result,sizeof(errstr)); snprintf(logmessage, LOGSIZE, "Host[%i] WARNING: Result from SNMP not valid. Partial Result: %.20s...\n", host_id, errstr); cacti_log(logmessage); strncpy(entry->result, "U", sizeof(entry->result)); } } if (set.verbose >= POLLER_VERBOSITY_MEDIUM) { snprintf(logmessage, LOGSIZE, "Host[%i] SNMP: v%i: %s, dsname: %s, oid: %s, value: %s\n", host_id, host->snmp_version, host->hostname, entry->rrd_name, entry->arg1, entry->result); cacti_log(logmessage); } break; case POLLER_ACTION_SCRIPT: /* execute script file */ poll_result = exec_poll(host, entry->arg1); snprintf(entry->result, sizeof(entry->result), "%s", poll_result); free(poll_result); /* remove double or single quotes from string */ strncpy(entry->result, strip_quotes(entry->result), sizeof(entry->result)); /* detect erroneous result. can be non-numeric */ if (!validate_result(entry->result)) { strncpy(errstr, (char *) strip_string_crlf(entry->result),sizeof(errstr)); snprintf(logmessage, LOGSIZE, "Host[%i] WARNING: Result from SCRIPT not valid. Partial Result: %.20s...\n", host_id, errstr); cacti_log(logmessage); strncpy(entry->result, "U", sizeof(entry->result)); } if (set.verbose >= POLLER_VERBOSITY_MEDIUM) { snprintf(logmessage, LOGSIZE, "Host[%i] SCRIPT: %s, output: %s\n", host_id, entry->arg1, entry->result); cacti_log(logmessage); } break; case POLLER_ACTION_PHP_SCRIPT_SERVER: /* execute script server */ poll_result = php_cmd(entry->arg1); snprintf(entry->result, sizeof(entry->result), "%s", poll_result); free(poll_result); /* remove double or single quotes from string */ strncpy(entry->result, strip_quotes(entry->result), sizeof(entry->result)); /* detect erroneous result. can be non-numeric */ if (!validate_result(entry->result)) { strncpy(errstr, entry->result, sizeof(errstr)); snprintf(logmessage, LOGSIZE, "Host[%i] WARNING: Result from SERVER not valid. Partial Result: %.20s...\n", host_id, errstr); cacti_log(logmessage); strncpy(entry->result, "U", sizeof(entry->result)); } if (set.verbose >= POLLER_VERBOSITY_MEDIUM) { snprintf(logmessage, LOGSIZE, "Host[%i] SERVER: %s, output: %s\n", host_id, entry->arg1, entry->result); cacti_log(logmessage); } break; default: /* unknown action, generate error */ snprintf(logmessage, LOGSIZE, "Host[%i] ERROR: Unknown Poller Action: %s\n", host_id, entry->arg1); cacti_log(logmessage); break; } } if (entry->result != NULL) { /* format database insert string */ query3 = (char *)malloc(sizeof(entry->result) + sizeof(entry->local_data_id) + 128); snprintf(query3, (sizeof(entry->result) + sizeof(entry->local_data_id) + 128), "insert into poller_output (local_data_id,rrd_name,time,output) values (%i,'%s','%s','%s')", entry->local_data_id, entry->rrd_name, start_datetime, entry->result); db_insert(&mysql, query3); free(query3); } } /* cleanup memory and prepare for function exit */ snmp_host_cleanup(host); free(entry); free(host); free(ping); mysql_free_result(result); #ifndef OLD_MYSQL mysql_thread_end(); #endif mysql_close(&mysql); if (set.verbose == POLLER_VERBOSITY_DEBUG) { snprintf(logmessage, LOGSIZE, "Host[%i] DEBUG: HOST COMPLETE: About to Exit Host Polling Thread Function\n", host_id); cacti_log(logmessage); } }