示例#1
0
文件: service.c 项目: rrogers96/finit
/**
 * service_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 service_runlevel(int newlevel)
{
	svc_t *svc;

	if (runlevel == newlevel)
		return;

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

	prevlevel = runlevel;
	runlevel  = newlevel;

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

	/* Make sure to (re)load all *.conf in /etc/finit.d/ */
	conf_reload_dynamic();

	_d("Stopping services services not allowed in new runlevel ...");
	for (svc = svc_iterator(1); svc; svc = svc_iterator(0)) {
		if (!svc_in_runlevel(svc, runlevel)) {
#ifndef INETD_DISABLED
			if (svc_is_inetd(svc))
				inetd_stop(&svc->inetd);
			else
#endif
				service_stop(svc);
		}

		/* ... or disabled/removed services from /etc/finit.d/ */
		if (svc_is_dynamic(svc) && svc_is_changed(svc))
			service_stop(svc);
	}

	/* Prev runlevel services stopped, call hooks before starting new runlevel ... */
	_d("All services have been stoppped, calling runlevel change hooks ...");
	plugin_run_hooks(HOOK_RUNLEVEL_CHANGE);  /* Reconfigure HW/VLANs/etc here */

	_d("Starting services services new to this runlevel ...");
	for (svc = svc_iterator(1); svc; svc = svc_iterator(0)) {
#ifndef INETD_DISABLED
		/* Inetd services have slightly different semantics */
		if (svc_is_inetd(svc)) {
			if (svc_in_runlevel(svc, runlevel))
				inetd_start(&svc->inetd);

			continue;
		}
#endif

		/* All other services consult their callback here */
		svc_dance(svc);
	}

	/* Cleanup stale services */
	svc_clean_dynamic(service_unregister);

	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);
}
示例#2
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);
}