예제 #1
0
파일: svc.c 프로젝트: cmatsuoka/finit
/**
 * svc_runlevel - Change to a new runlevel
 * @newlevel: New runlevel to activate
 *
 * Stops all services not in @newlevel and starts, or lets continue to run,
 * those in @newlevel.  Also updates @prevlevel and active @runlevel.
 */
void svc_runlevel (int newlevel)
{
	svc_t *svc;

	if (runlevel == newlevel)
		return;

	if (newlevel > 5 || newlevel < 1)
		return;

	prevlevel = runlevel;
	runlevel = newlevel;

	for (svc = svc_iterator(1); svc; svc = svc_iterator(0)) {
		int run = svc_enabled(svc, 0, NULL);

		if (svc->pid) {
			if (run == SVC_STOP)
				svc_stop(svc);
		} else {
			if (run == SVC_START)
				svc_start(svc);
		}
	}

	if (runlevel == 1)
		touch("/etc/nologin");	/* Disable login in single-user mode */
	else
		remove("/etc/nologin");
}
예제 #2
0
파일: svc.c 프로젝트: carriercomm/finit
void svc_monitor(pid_t lost)
{
	svc_t *svc;

	if (was_stopped && !is_norespawn()) {
		was_stopped = 0;
		restart_any_lost_procs();
		return;
	}

	if (fexist(SYNC_SHUTDOWN) || lost <= 1)
		return;

	/* Power user at the console, don't respawn tasks. */
	if (is_norespawn()) {
		was_stopped = 1;
		return;
	}

	if (tty_respawn(lost))
		return;

#ifndef INETD_DISABLED
	if (inetd_respawn(lost))
		return;
#endif

	for (svc = svc_iterator(1); svc; svc = svc_iterator(0)) {
		if (lost != svc->pid)
			continue;

		if (SVC_CMD_SERVICE != svc->type) {
			svc->pid = 0;
			continue;
		}

		_d("Ouch, lost pid %d - %s(%d)", lost, basename(svc->cmd), svc->pid);

		/* No longer running, update books. */
		svc->pid = 0;

		if (sig_stopped()) {
			_e("Stopped, not respawning killed processes.");
			break;
		}

		/* Cleanup any lingering or semi-restarting tasks before respawning */
		_d("Sending SIGTERM to service group %s", basename(svc->cmd));
		procname_kill(basename(svc->cmd), SIGTERM);

		/* Restarting lost service. */
		if (svc_enabled(svc, 0, NULL)) {
			svc->restart_counter++;
			svc_start(svc);
		}

		break;
	}
}
예제 #3
0
파일: svc.c 프로젝트: cmatsuoka/finit
int svc_start_by_name(char *name)
{
	svc_t *svc = svc_find(name);

	if (svc && svc_enabled(svc, 0, NULL))
		return svc_start(svc);

	return 1;
}
예제 #4
0
파일: svc.c 프로젝트: cmatsuoka/finit
void svc_start_all(void)
{
	svc_t *svc;
	svc_cmd_t cmd;

	for (svc = svc_iterator(1); svc; svc = svc_iterator(0)) {
		cmd = svc_enabled(svc, 0, NULL);
		if (SVC_START == cmd  || (SVC_RELOAD == cmd && svc->pid == 0))
			svc_start(svc);
		else if (SVC_RELOAD == cmd)
			svc_reload(svc);
	}

	_d("Running svc up hooks ...");
	plugin_run_hooks(HOOK_SVC_UP);
}
예제 #5
0
파일: svc.c 프로젝트: carriercomm/finit
/**
 * svc_bootstrap - Start bootstrap services and tasks
 *
 * System startup, runlevel S, where only services, tasks and
 * run commands absolutely essential to bootstrap are located.
 */
void svc_bootstrap(void)
{
	svc_t *svc;

	_d("Bootstrapping all services in runlevel S from %s", FINIT_CONF);
	for (svc = svc_iterator(1); svc; svc = svc_iterator(0)) {
		svc_cmd_t cmd;

		/* Inetd services cannot be part of bootstrap currently. */
		if (svc->type == SVC_CMD_INETD)
			continue;

		cmd = svc_enabled(svc, 0, NULL);
		if (SVC_START == cmd  || (SVC_RELOAD == cmd))
			svc_start(svc);
	}
}
예제 #6
0
파일: svc.c 프로젝트: cmatsuoka/finit
void svc_monitor(void)
{
	pid_t lost;
	svc_t *svc;

	lost = waitpid(-1, NULL, WNOHANG);
	if (lost < 1)
		return;

	if (fexist(SYNC_SHUTDOWN) || lost <= 1)
		return;

	/* Power user at the console, don't respawn tasks. */
	if (is_norespawn())
		return;

	for (svc = svc_iterator(1); svc; svc = svc_iterator(0)) {
		char *name = basename(svc->cmd);

		if (lost != svc->pid)
			continue;

		_d("Ouch, lost pid %d - %s(%d)", lost, name, svc->pid);

		/* No longer running, update books. */
		svc->pid = 0;

		if (sig_stopped()) {
			_e("Stopped, not respawning killed processes.");
			break;
		}

		/* Cleanup any lingering or semi-restarting tasks before respawning */
		_d("Sending SIGTERM to service group %s", name);
		procname_kill(name, SIGTERM);

		/* Restarting lost service. */
		if (svc_enabled(svc, 0, NULL)) {
			svc->stat_restart_counter++;
			svc_start(svc);
		}

		break;
	}
}
예제 #7
0
파일: svc.c 프로젝트: carriercomm/finit
/**
 * svc_runlevel - Change to a new runlevel
 * @newlevel: New runlevel to activate
 *
 * Stops all services not in @newlevel and starts, or lets continue to run,
 * those in @newlevel.  Also updates @prevlevel and active @runlevel.
 */
void svc_runlevel(int newlevel)
{
	svc_t *svc;

	if (runlevel == newlevel)
		return;

	if (newlevel < 0 || newlevel > 9)
		return;

	prevlevel = runlevel;
	runlevel  = newlevel;
	utmp_save(prevlevel, newlevel);

	_d("Setting new runlevel --> %d <-- previous %d", runlevel, prevlevel);

	for (svc = svc_iterator(1); svc; svc = svc_iterator(0)) {
		svc_cmd_t cmd;

		/* Inetd services have slightly different semantics */
#ifndef INETD_DISABLED
		if (svc->type == SVC_CMD_INETD) {
			if (!ISSET(svc->runlevels, runlevel))
				inetd_stop(&svc->inetd);
			else
				inetd_start(&svc->inetd);

			continue;
		}
#endif

		/* All other services consult their callback here */
		cmd = svc_enabled(svc, 0, NULL);
		if (svc->pid) {
			if (cmd == SVC_STOP)
				svc_stop(svc);
			else if (cmd == SVC_RELOAD)
				svc_reload(svc);
		} else {
			if (cmd == SVC_START)
				svc_start(svc);
		}
	}

	if (0 == runlevel) {
		do_shutdown(SIGUSR2);
		return;
	}
	if (6 == runlevel) {
		do_shutdown(SIGUSR1);
		return;
	}

	if (runlevel == 1)
		touch("/etc/nologin");	/* Disable login in single-user mode */
	else
		erase("/etc/nologin");

	if (0 != prevlevel)
		tty_runlevel(runlevel);
}