Пример #1
0
static int
check_respawn_thread(thread_t * thread)
{
	pid_t pid;

	/* Fetch thread args */
	pid = THREAD_CHILD_PID(thread);

	/* Restart respawning thread */
	if (thread->type == THREAD_CHILD_TIMEOUT) {
		thread_add_child(master, check_respawn_thread, NULL,
				 pid, RESPAWN_TIMER);
		return 0;
	}

	/* We catch a SIGCHLD, handle it */
	if (!__test_bit(DONT_RESPAWN_BIT, &debug)) {
		log_message(LOG_ALERT, "Healthcheck child process(%d) died: Respawning", pid);
		start_check_child();
	} else {
		log_message(LOG_ALERT, "Healthcheck child process(%d) died: Exiting", pid);
		raise(SIGTERM);
	}
	return 0;
}
Пример #2
0
/* VRRP Child respawning thread */
int
vrrp_respawn_thread(thread_t * thread)
{
	pid_t pid;

	/* Fetch thread args */
	pid = THREAD_CHILD_PID(thread);

	/* Restart respawning thread */
	if (thread->type == THREAD_CHILD_TIMEOUT) {
		thread_add_child(master, vrrp_respawn_thread, NULL,
				 pid, RESPAWN_TIMER);
		return 0;
	}

	/* We catch a SIGCHLD, handle it */
	if (!(debug & 64)) {
		log_message(LOG_ALERT, "VRRP child process(%d) died: Respawning", pid);
		start_vrrp_child();
	} else {
		log_message(LOG_ALERT, "VRRP child process(%d) died: Exiting", pid);
		raise(SIGTERM);
	}
	return 0;
}
Пример #3
0
/* VRRP Child respawning thread */
int
vrrp_respawn_thread(thread * thread_obj)
{
	pid_t pid;

	/* Fetch thread args */
	pid = THREAD_CHILD_PID(thread_obj);

	/* Restart respawning thread */
	if (thread_obj->type == THREAD_CHILD_TIMEOUT) {
		thread_add_child(master, vrrp_respawn_thread, NULL,
				 pid, RESPAWN_TIMER);
		return 0;
	}

	/* We catch a SIGCHLD, handle it */
	log_message(LOG_INFO, "VRRP child process(%d) died: Respawning", pid);
	start_vrrp_child();
	return 0;
}
Пример #4
0
/* Register CHECK thread */
int
start_check_child(void)
{
#ifndef _DEBUG_
	pid_t pid;
	int ret;
	char *syslog_ident;

	/* Initialize child process */
	pid = fork();

	if (pid < 0) {
		log_message(LOG_INFO, "Healthcheck child process: fork error(%s)"
			       , strerror(errno));
		return -1;
	} else if (pid) {
		checkers_child = pid;
		log_message(LOG_INFO, "Starting Healthcheck child process, pid=%d"
			       , pid);

		/* Start respawning thread */
		thread_add_child(master, check_respawn_thread, NULL,
				 pid, RESPAWN_TIMER);
		return 0;
	}

	if ((instance_name
#if HAVE_DECL_CLONE_NEWNET
			   || network_namespace
#endif
					       ) &&
	     (check_syslog_ident = make_syslog_ident(PROG_CHECK)))
		syslog_ident = check_syslog_ident;
	else
		syslog_ident = PROG_CHECK;

	/* Opening local CHECK syslog channel */
	openlog(syslog_ident, LOG_PID | ((__test_bit(LOG_CONSOLE_BIT, &debug)) ? LOG_CONS : 0)
			    , (log_facility==LOG_DAEMON) ? LOG_LOCAL2 : log_facility);

#ifdef _MEM_CHECK_
	mem_log_init(PROG_CHECK, "Healthcheck child process");
#endif

	free_parent_mallocs_startup(true);

	/* Child process part, write pidfile */
	if (!pidfile_write(checkers_pidfile, getpid())) {
		log_message(LOG_INFO, "Healthcheck child process: cannot write pidfile");
		exit(KEEPALIVED_EXIT_FATAL);
	}

	/* Create the new master thread */
	signal_handler_destroy();
	thread_destroy_master(master);	/* This destroys any residual settings from the parent */
	master = thread_make_master();

	/* change to / dir */
	ret = chdir("/");
	if (ret < 0) {
		log_message(LOG_INFO, "Healthcheck child process: error chdir");
	}

	/* Set mask */
	umask(0);
#endif

	/* If last process died during a reload, we can get there and we
	 * don't want to loop again, because we're not reloading anymore.
	 */
	UNSET_RELOAD;

	/* Signal handling initialization */
	check_signal_init();

	/* Start Healthcheck daemon */
	start_check();

	/* Launch the scheduling I/O multiplexer */
	launch_scheduler();

	/* Finish healthchecker daemon process */
	stop_check(EXIT_SUCCESS);

	/* unreachable */
	exit(EXIT_SUCCESS);
}
Пример #5
0
/* Register VRRP thread */
int
start_vrrp_child(void)
{
#ifndef _DEBUG_
	pid_t pid;
	int ret;

	/* Initialize child process */
	pid = fork();

	if (pid < 0) {
		log_message(LOG_INFO, "VRRP child process: fork error(%s)"
			       , strerror(errno));
		return -1;
	} else if (pid) {
		vrrp_child = pid;
		log_message(LOG_INFO, "Starting VRRP child process, pid=%d"
			       , pid);

		/* Start respawning thread */
		thread_add_child(master, vrrp_respawn_thread, NULL,
				 pid, RESPAWN_TIMER);
		return 0;
	}

	signal_handler_destroy();

	/* Opening local VRRP syslog channel */
	openlog(PROG_VRRP, LOG_PID | ((__test_bit(LOG_CONSOLE_BIT, &debug)) ? LOG_CONS : 0)
			 , (log_facility==LOG_DAEMON) ? LOG_LOCAL1 : log_facility);

	/* Child process part, write pidfile */
	if (!pidfile_write(vrrp_pidfile, getpid())) {
		/* Fatal error */
		log_message(LOG_INFO, "VRRP child process: cannot write pidfile");
		exit(0);
	}

	/* Create the new master thread */
	thread_destroy_master(master);
	master = thread_make_master();

	/* change to / dir */
	ret = chdir("/");
	if (ret < 0) {
		log_message(LOG_INFO, "VRRP child process: error chdir");
	}

	/* Set mask */
	umask(0);
#endif

	/* If last process died during a reload, we can get there and we
	 * don't want to loop again, because we're not reloading anymore.
	 */
	UNSET_RELOAD;

	/* Signal handling initialization */
	vrrp_signal_init();

	/* Start VRRP daemon */
	start_vrrp();

	/* Launch the scheduling I/O multiplexer */
	launch_scheduler();

	/* Finish VRRP daemon process */
	stop_vrrp();
	exit(0);
}
Пример #6
0
int
misc_check_child_thread(thread * thread_obj)
{
	int wait_status;
	checker *checker_obj;
	misc_checker *misc_chk;

	checker_obj = THREAD_ARG(thread_obj);
	misc_chk = CHECKER_ARG(checker_obj);

	if (thread_obj->type == THREAD_CHILD_TIMEOUT) {
		pid_t pid;

		pid = THREAD_CHILD_PID(thread_obj);

		/* The child hasn't responded. Kill it off. */
		if (svr_checker_up(checker_obj->id, checker_obj->rs)) {
			log_message(LOG_INFO, "Misc check to [%s] for [%s] timed out",
			       inet_ntop2(CHECKER_RIP(checker_obj)),
			       misc_chk->path);
			smtp_alert(checker_obj->rs, NULL, NULL,
				   "DOWN",
				   "=> MISC CHECK script timeout on service <=");
			update_svr_checker_state(DOWN, checker_obj->id
						     , checker_obj->vs
						     , checker_obj->rs);
		}

		kill(pid, SIGTERM);
		thread_add_child(thread_obj->master, misc_check_child_timeout_thread,
				 checker_obj, pid, 2);
		return 0;
	}

	wait_status = THREAD_CHILD_STATUS(thread_obj);

	if (WIFEXITED(wait_status)) {
		int status;
		status = WEXITSTATUS(wait_status);
		if (status == 0 ||
                    (misc_chk->dynamic == 1 && status >= 2 && status <= 255)) {
			/*
			 * The actual weight set when using misc_dynamic is two less than
			 * the exit status returned.  Effective range is 0..253.
			 * Catch legacy case of status being 0 but misc_dynamic being set.
			 */
			if (misc_chk->dynamic == 1 && status != 0)
				update_svr_wgt(status - 2, checker_obj->vs, checker_obj->rs);

			/* everything is good */
			if (!svr_checker_up(checker_obj->id, checker_obj->rs)) {
				log_message(LOG_INFO, "Misc check to [%s] for [%s] success.",
				       inet_ntop2(CHECKER_RIP(checker_obj)),
				       misc_chk->path);
				smtp_alert(checker_obj->rs, NULL, NULL,
					   "UP",
					   "=> MISC CHECK succeed on service <=");
				update_svr_checker_state(UP, checker_obj->id
							   , checker_obj->vs
							   , checker_obj->rs);
			}
		} else {
			if (svr_checker_up(checker_obj->id, checker_obj->rs)) {
				log_message(LOG_INFO, "Misc check to [%s] for [%s] failed.",
				       inet_ntop2(CHECKER_RIP(checker_obj)),
				       misc_chk->path);
				smtp_alert(checker_obj->rs, NULL, NULL,
					   "DOWN",
					   "=> MISC CHECK failed on service <=");
				update_svr_checker_state(DOWN, checker_obj->id
							     , checker_obj->vs
							     , checker_obj->rs);
			}
		}
	}

	return 0;
}
Пример #7
0
int
misc_check_thread(thread * thread_obj)
{
	checker *checker_obj;
	misc_checker *misc_chk;
	int status, ret;
	pid_t pid;

	checker_obj = THREAD_ARG(thread_obj);
	misc_chk = CHECKER_ARG(checker_obj);

	/*
	 * Register a new checker thread & return
	 * if checker is disabled
	 */
	if (!CHECKER_ENABLED(checker_obj)) {
		/* Register next timer checker */
		thread_add_timer(thread_obj->master, misc_check_thread, checker_obj,
				 checker_obj->vs->delay_loop);
		return 0;
	}

	/* Register next timer checker */
	thread_add_timer(thread_obj->master, misc_check_thread, checker_obj,
			 checker_obj->vs->delay_loop);

	/* Daemonization to not degrade our scheduling timer */
	pid = fork();

	/* In case of fork is error. */
	if (pid < 0) {
		log_message(LOG_INFO, "Failed fork process");
		return -1;
	}

	/* In case of this is parent process */
	if (pid) {
		long timeout;
		timeout = (misc_chk->timeout) ? misc_chk->timeout : checker_obj->vs->delay_loop;

		thread_add_child(thread_obj->master, misc_check_child_thread,
				 checker_obj, pid, timeout);
		return 0;
	}

	/* Child part */
	signal_handler_destroy();
	closeall(0);

	open("/dev/null", O_RDWR);
	ret = dup(0);
	ret = dup(0);

	status = system_call(misc_chk->path);

	if (status < 0 || !WIFEXITED(status))
		status = 0; /* Script errors aren't server errors */
	else
		status = WEXITSTATUS(status);

	exit(status);
}