예제 #1
0
/* 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;
	}
예제 #2
0
/* handles scheduled downtime (id passed from timed event queue) */
int handle_scheduled_downtime_by_id(unsigned long downtime_id) {
	scheduled_downtime *temp_downtime = NULL;

	/* find the downtime entry */
	if ((temp_downtime = find_downtime(ANY_DOWNTIME, downtime_id)) == NULL)
		return ERROR;

	/* handle the downtime */
	return handle_scheduled_downtime(temp_downtime);
}
예제 #3
0
static unsigned long get_next_downtime_id(void) {
	unsigned long new_dt_id;
	for (;;) {
		new_dt_id = next_downtime_id++;
		if (!find_downtime(ANY_DOWNTIME, next_downtime_id)) {
			return new_dt_id;
			}
		}
	return 0;
	}
예제 #4
0
/* 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);
	}
예제 #5
0
/* registers scheduled downtime (schedules it, adds comments, etc.) */
int register_downtime(int type, unsigned long downtime_id) {
	char *temp_buffer = NULL;
	char start_time_string[MAX_DATETIME_LENGTH] = "";
	char end_time_string[MAX_DATETIME_LENGTH] = "";
	scheduled_downtime *temp_downtime = NULL;
	host *hst = NULL;
	service *svc = NULL;
	char *type_string = NULL;
	int hours = 0;
	int minutes = 0;
	int seconds = 0;
	unsigned long *new_downtime_id = NULL;

	log_debug_info(DEBUGL_FUNCTIONS, 0, "register_downtime()\n");

	/* find the downtime entry in memory */
	temp_downtime = find_downtime(type, downtime_id);
	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;
	}

	/* create the comment */
	get_datetime_string(&(temp_downtime->start_time), start_time_string, MAX_DATETIME_LENGTH, SHORT_DATE_TIME);
	get_datetime_string(&(temp_downtime->end_time), end_time_string, MAX_DATETIME_LENGTH, SHORT_DATE_TIME);
	hours = temp_downtime->duration / 3600;
	minutes = ((temp_downtime->duration - (hours * 3600)) / 60);
	seconds = temp_downtime->duration - (hours * 3600) - (minutes * 60);
	if (temp_downtime->type == HOST_DOWNTIME)
		type_string = "host";
	else
		type_string = "service";
	if (temp_downtime->fixed == TRUE)
		asprintf(&temp_buffer, "This %s has been scheduled for fixed downtime from %s to %s.  Notifications for the %s will not be sent out during that time period.", type_string, start_time_string, end_time_string, type_string);
	else
		asprintf(&temp_buffer, "This %s has been scheduled for flexible downtime starting between %s and %s and lasting for a period of %d hours and %d minutes.  Notifications for the %s will not be sent out during that time period.", type_string, start_time_string, end_time_string, hours, minutes, type_string);


	log_debug_info(DEBUGL_DOWNTIME, 0, "Scheduled Downtime Details:\n");
	if (temp_downtime->type == HOST_DOWNTIME) {
		log_debug_info(DEBUGL_DOWNTIME, 0, " Type:        Host Downtime\n");
		log_debug_info(DEBUGL_DOWNTIME, 0, " Host:        %s\n", hst->name);
	} else {
		log_debug_info(DEBUGL_DOWNTIME, 0, " Type:        Service Downtime\n");
		log_debug_info(DEBUGL_DOWNTIME, 0, " Host:        %s\n", svc->host_name);
		log_debug_info(DEBUGL_DOWNTIME, 0, " Service:     %s\n", svc->description);
	}
	log_debug_info(DEBUGL_DOWNTIME, 0, " Fixed/Flex:  %s\n", (temp_downtime->fixed == TRUE) ? "Fixed" : "Flexible");
	log_debug_info(DEBUGL_DOWNTIME, 0, " Start:       %s\n", start_time_string);
	log_debug_info(DEBUGL_DOWNTIME, 0, " End:         %s\n", end_time_string);
	log_debug_info(DEBUGL_DOWNTIME, 0, " Duration:    %dh %dm %ds\n", hours, minutes, seconds);
	log_debug_info(DEBUGL_DOWNTIME, 0, " Downtime ID: %lu\n", temp_downtime->downtime_id);
	log_debug_info(DEBUGL_DOWNTIME, 0, " Trigger ID:  %lu\n", temp_downtime->triggered_by);
	log_debug_info(DEBUGL_DOWNTIME, 0, " Author:      %s\n", (temp_downtime->author != NULL ? temp_downtime->author : "(Icinga Process)"));


	/* add a non-persistent comment to the host or service regarding the scheduled outage */
	if (temp_downtime->type == SERVICE_DOWNTIME)
		add_new_comment(SERVICE_COMMENT, DOWNTIME_COMMENT, svc->host_name, svc->description, time(NULL), (temp_downtime->author != NULL ? temp_downtime->author : "(Icinga Process)"), temp_buffer, 0, COMMENTSOURCE_INTERNAL, FALSE, (time_t)0, &(temp_downtime->comment_id));
	else
		add_new_comment(HOST_COMMENT, DOWNTIME_COMMENT, hst->name, NULL, time(NULL), (temp_downtime->author != NULL ? temp_downtime->author : "(Icinga Process)"), temp_buffer, 0, COMMENTSOURCE_INTERNAL, FALSE, (time_t)0, &(temp_downtime->comment_id));

	/* free comment buffer */
	my_free(temp_buffer);

	/*** SCHEDULE DOWNTIME - FLEXIBLE (NON-FIXED) DOWNTIME IS HANDLED AT A LATER POINT ***/

	/* only non-triggered downtime is scheduled... */
	if (temp_downtime->triggered_by == 0) {
		if ((new_downtime_id = (unsigned long *)malloc(sizeof(unsigned long *)))) {
			*new_downtime_id = downtime_id;
			schedule_new_event(EVENT_SCHEDULED_DOWNTIME, TRUE, temp_downtime->start_time, FALSE, 0, NULL, FALSE, (void *)new_downtime_id, NULL, 0);
		}
	}

#ifdef PROBABLY_NOT_NEEDED
	/*** FLEXIBLE DOWNTIME SANITY CHECK - ADDED 02/17/2008 ****/

	/* if host/service is in a non-OK/UP state right now, see if we should start flexible time immediately */
	/* this is new logic added in 3.0rc3 */
	if (temp_downtime->fixed == FALSE) {
		if (temp_downtime->type == HOST_DOWNTIME)
			check_pending_flex_host_downtime(hst);
		else
			check_pending_flex_service_downtime(svc);
	}
#endif

	return OK;
}
예제 #6
0
/* 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;
}
예제 #7
0
/* finds a specific service downtime entry */
scheduled_downtime *find_service_downtime(unsigned long downtime_id) {

	return find_downtime(SERVICE_DOWNTIME, downtime_id);
}
예제 #8
0
/* finds a specific host downtime entry */
scheduled_downtime *find_host_downtime(unsigned long downtime_id) {

	return find_downtime(HOST_DOWNTIME, downtime_id);
}
예제 #9
0
/* 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;
}
예제 #10
0
/* registers scheduled downtime (schedules it, adds comments, etc.) */
int register_downtime(int type, unsigned long downtime_id) {
	char *temp_buffer = NULL;
	char start_time_string[MAX_DATETIME_LENGTH] = "";
	char flex_start_string[MAX_DATETIME_LENGTH] = "";
	char end_time_string[MAX_DATETIME_LENGTH] = "";
	scheduled_downtime *temp_downtime = NULL;
	host *hst = NULL;
	service *svc = NULL;
	const char *type_string = NULL;
	int hours = 0;
	int minutes = 0;
	int seconds = 0;
	unsigned long *new_downtime_id = NULL;
	int was_in_effect = FALSE;

	log_debug_info(DEBUGL_FUNCTIONS, 0, "register_downtime( %d, %lu)\n", type,
			downtime_id);

	/* find the downtime entry in memory */
	temp_downtime = find_downtime(type, downtime_id);
	if(temp_downtime == NULL) {
		log_debug_info(DEBUGL_DOWNTIME, 0, "Cannot find downtime ID: %lu\n", downtime_id);
		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,
					"Cannot find host (%s) for downtime ID: %lu\n",
					temp_downtime->host_name, downtime_id);
			return ERROR;
			}
		}
	else {
		if((svc = find_service(temp_downtime->host_name, temp_downtime->service_description)) == NULL) {
			log_debug_info(DEBUGL_DOWNTIME, 1,
					"Cannot find service (%s) for host (%s) for downtime ID: %lu\n",
					temp_downtime->service_description, temp_downtime->host_name,
					downtime_id);
			return ERROR;
			}
		}

	/* create the comment */
	get_datetime_string(&(temp_downtime->start_time), start_time_string, MAX_DATETIME_LENGTH, SHORT_DATE_TIME);
	get_datetime_string(&(temp_downtime->flex_downtime_start), flex_start_string, MAX_DATETIME_LENGTH, SHORT_DATE_TIME);
	get_datetime_string(&(temp_downtime->end_time), end_time_string, MAX_DATETIME_LENGTH, SHORT_DATE_TIME);
	hours = temp_downtime->duration / 3600;
	minutes = ((temp_downtime->duration - (hours * 3600)) / 60);
	seconds = temp_downtime->duration - (hours * 3600) - (minutes * 60);
	if(temp_downtime->type == HOST_DOWNTIME)
		type_string = "host";
	else
		type_string = "service";
	if(temp_downtime->fixed == TRUE)
		asprintf(&temp_buffer, "This %s has been scheduled for fixed downtime from %s to %s.  Notifications for the %s will not be sent out during that time period.", type_string, start_time_string, end_time_string, type_string);
	else
		asprintf(&temp_buffer, "This %s has been scheduled for flexible downtime starting between %s and %s and lasting for a period of %d hours and %d minutes.  Notifications for the %s will not be sent out during that time period.", type_string, start_time_string, end_time_string, hours, minutes, type_string);


	log_debug_info(DEBUGL_DOWNTIME, 0, "Scheduled Downtime Details:\n");
	if(temp_downtime->type == HOST_DOWNTIME) {
		log_debug_info(DEBUGL_DOWNTIME, 0, " Type:        Host Downtime\n");
		log_debug_info(DEBUGL_DOWNTIME, 0, " Host:        %s\n", hst->name);
		}
	else {
		log_debug_info(DEBUGL_DOWNTIME, 0, " Type:        Service Downtime\n");
		log_debug_info(DEBUGL_DOWNTIME, 0, " Host:        %s\n", svc->host_name);
		log_debug_info(DEBUGL_DOWNTIME, 0, " Service:     %s\n", svc->description);
		}
	log_debug_info(DEBUGL_DOWNTIME, 0, " Fixed/Flex:  %s\n", (temp_downtime->fixed == TRUE) ? "Fixed" : "Flexible");
	log_debug_info(DEBUGL_DOWNTIME, 0, " Start:       %s\n", start_time_string);
	if( temp_downtime->flex_downtime_start) {
		log_debug_info(DEBUGL_DOWNTIME, 0, " Flex Start:  %s\n", flex_start_string);
		}
	log_debug_info(DEBUGL_DOWNTIME, 0, " End:         %s\n", end_time_string);
	log_debug_info(DEBUGL_DOWNTIME, 0, " Duration:    %dh %dm %ds\n", hours, minutes, seconds);
	log_debug_info(DEBUGL_DOWNTIME, 0, " Downtime ID: %lu\n", temp_downtime->downtime_id);
	log_debug_info(DEBUGL_DOWNTIME, 0, " Trigger ID:  %lu\n", temp_downtime->triggered_by);


	/* add a non-persistent comment to the host or service regarding the scheduled outage */
	if(temp_downtime->type == SERVICE_DOWNTIME)
		add_new_comment(SERVICE_COMMENT, DOWNTIME_COMMENT, svc->host_name, svc->description, time(NULL), ( NULL == temp_downtime->author ? "(Nagios Process)" : temp_downtime->author), temp_buffer, 0, COMMENTSOURCE_INTERNAL, FALSE, (time_t)0, &(temp_downtime->comment_id));
	else
		add_new_comment(HOST_COMMENT, DOWNTIME_COMMENT, hst->name, NULL, time(NULL), ( NULL == temp_downtime->author ? "(Nagios Process)" : temp_downtime->author), temp_buffer, 0, COMMENTSOURCE_INTERNAL, FALSE, (time_t)0, &(temp_downtime->comment_id));

	my_free(temp_buffer);

	/* only non-triggered downtime is scheduled... */
	if((temp_downtime->triggered_by == 0) && ((TRUE == temp_downtime->fixed) ||
			((FALSE == temp_downtime->fixed) &&
			(TRUE == temp_downtime->is_in_effect)))) {
		/* If this is a fixed downtime, schedule the event to start it. If this
			is a flexible downtime, normally we wait for one of the
			check_pending_flex_*_downtime() functions to start it, but if the
			downtime is already in effect, this means that we are restarting
			Nagios and the downtime was in effect when we last shutdown
			Nagios, so we should restart the flexible downtime now. This
			should work even if the downtime has ended because the
			handle_scheduled_dowtime() function will immediately schedule
			another downtime event which will end the downtime. */
		if((new_downtime_id = (unsigned long *)malloc(sizeof(unsigned long *)))) {
			*new_downtime_id = downtime_id;
			temp_downtime->start_event = schedule_new_event(EVENT_SCHEDULED_DOWNTIME, TRUE, temp_downtime->start_time, FALSE, 0, NULL, FALSE, (void *)new_downtime_id, NULL, 0);
			/* Turn off is_in_effect flag so handle_scheduled_downtime() will
				handle it correctly */
			was_in_effect = temp_downtime->is_in_effect;
			temp_downtime->is_in_effect = FALSE;
			}
		}

	/* If the downtime is triggered and was in effect, mark it as not in 
		effect so it gets scheduled correctly */
	if((temp_downtime->triggered_by != 0) && 
			(TRUE == temp_downtime->is_in_effect)) {
		was_in_effect = temp_downtime->is_in_effect;
		temp_downtime->is_in_effect = FALSE;
		}

	if((FALSE == temp_downtime->fixed) && (FALSE == was_in_effect)) {
		/* 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 a flex downtime may never start, schedule an expiring event in
			case the event is never triggered. The expire event will NOT cancel
			a downtime event that is in effect */
		log_debug_info(DEBUGL_DOWNTIME, 1, "Scheduling downtime expire event in case flexible downtime is never triggered\n");
		temp_downtime->stop_event = schedule_new_event(EVENT_EXPIRE_DOWNTIME, TRUE, (temp_downtime->end_time + 1), FALSE, 0, NULL, FALSE, NULL, NULL, 0);
		}

#ifdef PROBABLY_NOT_NEEDED
	/*** FLEXIBLE DOWNTIME SANITY CHECK - ADDED 02/17/2008 ****/

	/* if host/service is in a non-OK/UP state right now, see if we should start flexible time immediately */
	/* this is new logic added in 3.0rc3 */
	if(temp_downtime->fixed == FALSE) {
		if(temp_downtime->type == HOST_DOWNTIME)
			check_pending_flex_host_downtime(hst);
		else
			check_pending_flex_service_downtime(svc);
		}
#endif

	return OK;
	}
예제 #11
0
static int downtime_add(scheduled_downtime *dt)
{
	unsigned long prev_downtime_id;
	scheduled_downtime *trigger = NULL;
	struct host *h;
	struct service *s;

	if (!dt)
		return DT_ENULL;

	log_debug_info(DEBUGL_DOWNTIME, 0, "downtime_add(): id=%lu; type=%s; host=%s; service=%s\n",
				   dt->downtime_id,
				   dt->type == HOST_DOWNTIME ? "host" : "service",
				   dt->host_name, dt->service_description);
	/*
	 * check for errors.
	 * host_name must always be set
	 */
	if (!dt->host_name)
		return DT_EHOST;

	/* service_description should only be set for service downtime */
	if ((dt->type == HOST_DOWNTIME) != (!dt->service_description))
		return DT_ETYPE;
	/* type must be either SERVICE_DOWNTIME or HOST_DOWNTIME */
	if (dt->type != SERVICE_DOWNTIME && dt->type != HOST_DOWNTIME)
		return DT_ETYPE;
	/* triggered downtime must be triggered by an existing downtime */
	if (dt->triggered_by && !(trigger = find_downtime(ANY_DOWNTIME, dt->triggered_by)))
		return DT_ETRIGGER;
	/* non-triggered downtime must have start_time < end_time */
	if (!trigger && dt->start_time >= dt->end_time)
		return DT_ETIME;
	/* flexible downtime must have a duration */
	if (!dt->fixed && !dt->duration)
		return DT_ETIME;

	/* the object we're adding downtime for must exist */
	if (!dt->service_description) {
		if (!(h = find_host(dt->host_name)))
			return DT_EHOST;
	} else if (!(s = find_service(dt->host_name, dt->service_description))) {
		return DT_ESERVICE;
	}

	/* set downtime_id if not already set */
	prev_downtime_id = next_downtime_id;
	if (!dt->downtime_id) {
		dt->downtime_id = next_downtime_id++;
	} else if (dt->downtime_id > next_downtime_id) {
		next_downtime_id = dt->downtime_id + 1;
	}

	if (fanout_add(dt_fanout, dt->downtime_id, dt) < 0) {
		next_downtime_id = prev_downtime_id;
		return errno;
	}

	if(defer_downtime_sorting || !scheduled_downtime_list ||
	   downtime_compar(&dt, &scheduled_downtime_list) < 0)
	{
		if (scheduled_downtime_list) {
			scheduled_downtime_list->prev = dt;
		}
		dt->next = scheduled_downtime_list;
		dt->prev = NULL;
		scheduled_downtime_list = dt;
		}
	else {
		scheduled_downtime *cur;

		/* add new downtime to downtime list, sorted by start time */
		for(cur = scheduled_downtime_list; cur; cur = cur->next) {
			if(downtime_compar(&dt, &cur) < 0) {
				dt->prev = cur->prev;
				if (cur->prev)
					cur->prev->next = dt;
				dt->next = cur;
				cur->prev = dt;
				break;
				}
			if (!cur->next) {
				dt->next = NULL;
				cur->next = dt;
				dt->prev = cur;
				break;
			}
		}
	}
	return OK;
}