PERFORCE change 81425 for review

soc-tyler soc-tyler at FreeBSD.org
Thu Aug 4 04:34:34 GMT 2005


http://perforce.freebsd.org/chv.cgi?CH=81425

Change 81425 by soc-tyler at soc-tyler_launchd on 2005/08/04 04:34:03

	Still build problems related to the init code, what to toss, what not to toss...
	I'll have this done this weekend, then i'll fix that stupid unix sockets problem.
	
	I plan to have it running with PID != 1 by the end of next week, else murray@ might start whipping me :-/

Affected files ...

.. //depot/projects/soc2005/launchd/Makefile#10 edit
.. //depot/projects/soc2005/launchd/init.c#7 edit
.. //depot/projects/soc2005/launchd/launchd.c#9 edit

Differences ...

==== //depot/projects/soc2005/launchd/Makefile#10 (text+ko) ====

@@ -15,9 +15,8 @@
 CFLAGS+= -g -Wall -W -Wshadow -Wpadded -Iincludes -D_LAUNCHD_
 # init.c related CFLAGS (from src/sbin/init/Makefile)
 # -DSECURE to make secure single-user logins (enter root passwd, etc)
-CFLAGS+= -DDEBUGSHELL -DLOGIN_CAP -DCOMPAT_SYSV_INIT
-# Do not let launchd(8) have init(8) functionality (or I haven't implemented it yet.. ;))
-CFLAGS+= -D_NO_INIT_
+# -DDEBUGSHELL ? we don't need no stinkin' DEBUGSHELL
+CFLAGS+= -DLOGIN_CAP -DCOMPAT_SYSV_INIT
 
 
 # -lcrypt needed by original FreeBSD init(8) code

==== //depot/projects/soc2005/launchd/init.c#7 (text+ko) ====

@@ -65,6 +65,7 @@
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdbool.h>
 #include <string.h>
 #include <syslog.h>
 #include <time.h>
@@ -118,8 +119,9 @@
 typedef long (*state_func_t)(void);
 typedef state_func_t (*state_t)(void);
 
-state_func_t single_user(void);
-state_func_t runcom(void);
+void single_user(void);
+void runcom(void);
+
 state_func_t read_ttys(void);
 state_func_t multi_user(void);
 state_func_t clean_ttys(void);
@@ -130,13 +132,24 @@
 #define FALSE	0
 #define TRUE	1
 
-int Reboot = FALSE;
+static bool Reboot = false;
 int howto = RB_AUTOBOOT;
 
+/* some launchd(8) related variables */
+static bool runcom_verbose = false;
+static bool runcom_safe = false;
+static bool runcom_fsck = true;
+//static bool runcom_netboot = false;
+static bool single_user_mode = false;
+static bool run_runcom = true;
+static pid_t single_user_pid = 0;
+static pid_t runcom_pid = 0;
+
 int devfs;
 
 void transition(state_t);
-state_t requested_transition = runcom;
+/* this is something of old init.c, the state nonsense */
+//state_t requested_transition = runcom;
 
 void setctty(const char *);
 
@@ -186,176 +199,44 @@
 session_t *find_session(pid_t);
 DB *session_db;
 
-#ifndef _LAUNCHD_
-/*
- * The mother of all processes.
- */
-int
-main(int argc, char *argv[])
-{
-	int c;
-	struct sigaction sa;
-	sigset_t mask;
-
-
-	/* Dispose of random users. */
-	if (getuid() != 0)
-		errx(1, "%s", strerror(EPERM));
-
-	/* System V users like to reexec init. */
-	if (getpid() != 1) {
-#ifdef COMPAT_SYSV_INIT
-		/* So give them what they want */
-		if (argc > 1) {
-			if (strlen(argv[1]) == 1) {
-				char runlevel = *argv[1];
-				int sig;
-
-				switch (runlevel) {
-					case '0': /* halt + poweroff */
-						sig = SIGUSR2;
-						break;
-					case '1': /* single-user */
-						sig = SIGTERM;
-						break;
-					case '6': /* reboot */
-						sig = SIGINT;
-						break;
-					case 'c': /* block further logins */
-						sig = SIGTSTP;
-						break;
-					case 'q': /* rescan /etc/ttys */
-						sig = SIGHUP;
-						break;
-					default:
-						goto invalid;
-				}
-				kill(1, sig);
-				_exit(0);
-			} else
-invalid:
-				errx(1, "invalid run-level ``%s''", argv[1]);
-		} else
-#endif
-			errx(1, "already running");
+/* init_boot() was borrowed from launchd(8)'s original init.c file */
+void init_boot(bool sflag, bool vflag, bool xflag) {
+	if (sflag) {
+		single_user_mode = true;
+		run_runcom = false;
 	}
-	/*
-	 * Note that this does NOT open a file...
-	 * Does 'init' deserve its own facility number?
-	 */
-	openlog("init", LOG_CONS|LOG_ODELAY, LOG_AUTH);
+	if (vflag)
+		runcom_verbose = true;
+	if (xflag)
+		runcom_safe = true;
+}
 
-	/*
-	 * Create an initial session.
-	 */
-	if (setsid() < 0)
-		warning("initial setsid() failed: %m");
+/* init_pre_kevent() was borrowed from launchd(8)'s original init.c file */
+void init_pre_kevent(void) {
+	session_t s;
 
-	/*
-	 * Establish an initial user so that programs running
-	 * single user do not freak out and die (like passwd).
-	 */
-	if (setlogin("root") < 0)
-		warning("setlogin() failed: %m");
+	if (single_user_mode && single_user_pid == 0)
+		single_user();
 
-	/*
-	 * This code assumes that we always get arguments through flags,
-	 * never through bits set in some random machine register.
-	 */
-	while ((c = getopt(argc, argv, "dsf")) != -1)
-		switch (c) {
-		case 'd':
-			devfs = 1;
-			break;
-		case 's':
-			requested_transition = single_user;
-			break;
-		case 'f':
-			runcom_mode = FASTBOOT;
-			break;
-		default:
-			warning("unrecognized flag '-%c'", c);
-			break;
-		}
+	if (run_runcom)
+		runcom();
+		
+	if (!single_user_mode && !run_runcom && runcom_pid == 0) {
+		/*
+		 * If the administrator has not set the security level to -1
+		 * to indicate that the kernel should not run multiuser in secure
+		 * mode, and the run script has not set a higher level of security 
+		 * than level 1, then put the kernel into secure mode.
+		 */
+		if (getsecuritylevel() == 0)
+			setsecuritylevel(1);
 
-	if (optind != argc)
-		warning("ignoring excess arguments");
-
-	if (devfs) {
-		struct iovec iov[4];
-		char *s;
-		int i;
-
-		char _fstype[]	= "fstype";
-		char _devfs[]	= "devfs";
-		char _fspath[]	= "fspath";
-		char _path_dev[]= _PATH_DEV;
-
-		iov[0].iov_base = _fstype;
-		iov[0].iov_len = sizeof(_fstype);
-		iov[1].iov_base = _devfs;
-		iov[1].iov_len = sizeof(_devfs);
-		iov[2].iov_base = _fspath;
-		iov[2].iov_len = sizeof(_fspath);
-		/* 
-		 * Try to avoid the trailing slash in _PATH_DEV.
-		 * Be *very* defensive.
-		 */
-		s = strdup(_PATH_DEV);
-		if (s != NULL) {
-			i = strlen(s);
-			if (i > 0 && s[i - 1] == '/')
-				s[i - 1] = '\0';
-			iov[3].iov_base = s;
-			iov[3].iov_len = strlen(s) + 1;
-		} else {
-			iov[3].iov_base = _path_dev;
-			iov[3].iov_len = sizeof(_path_dev);
+		TAILQ_FOREACH(s, &sessions, tqe) {
+			if (s->se_process == 0)
+				session_launch(s);
 		}
-		nmount(iov, 4, 0);
-		if (s != NULL)
-			free(s);
 	}
-
-	/*
-	 * We catch or block signals rather than ignore them,
-	 * so that they get reset on exec.
-	 */
-	handle(badsys, SIGSYS, 0);
-	handle(disaster, SIGABRT, SIGFPE, SIGILL, SIGSEGV,
-	       SIGBUS, SIGXCPU, SIGXFSZ, 0);
-	handle(transition_handler, SIGHUP, SIGINT, SIGTERM, SIGTSTP,
-		SIGUSR1, SIGUSR2, 0);
-	handle(alrm_handler, SIGALRM, 0);
-	sigfillset(&mask);
-	delset(&mask, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGSYS,
-		SIGXCPU, SIGXFSZ, SIGHUP, SIGINT, SIGTERM, SIGTSTP, SIGALRM, 
-		SIGUSR1, SIGUSR2, 0);
-	sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0);
-	sigemptyset(&sa.sa_mask);
-	sa.sa_flags = 0;
-	sa.sa_handler = SIG_IGN;
-	(void) sigaction(SIGTTIN, &sa, (struct sigaction *)0);
-	(void) sigaction(SIGTTOU, &sa, (struct sigaction *)0);
-
-	/*
-	 * Paranoia.
-	 */
-	close(0);
-	close(1);
-	close(2);
-
-	/*
-	 * Start the state machine.
-	 */
-	transition(requested_transition);
-
-	/*
-	 * Should never reach here.
-	 */
-	return 1;
 }
-#endif
 
 /*
  * Associate a function with a signal handler.
@@ -568,9 +449,7 @@
 /*
  * Bring the system up single user.
  */
-state_func_t
-single_user(void)
-{
+void single_user(void) {
 	pid_t pid, wpid;
 	int status;
 	sigset_t mask;
@@ -579,7 +458,7 @@
 #ifdef SECURE
 	struct ttyent *typ;
 	struct passwd *pp;
-	static const char banner[] =
+	static const char banner[] = 
 		"Enter root password, or ^D to go multi-user\n";
 	char *clear, *password;
 #endif
@@ -671,17 +550,17 @@
 		_exit(1);
 	}
 
+/* We're screwed if we ever get here regardless :/ */
+/*
 	if (pid == -1) {
-		/*
-		 * We are seriously hosed.  Do our best.
-		 */
+		// We are seriously hosed.  Do our best.\
 		emergency("can't fork single-user shell, trying again");
 		while (waitpid(-1, (int *) 0, WNOHANG) > 0)
 			continue;
-		return (state_func_t) single_user;
+		//return (state_func_t) single_user;
 	}
-
 	requested_transition = 0;
+*/
 	do {
 		if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1)
 			collect_child(wpid);
@@ -689,7 +568,7 @@
 			if (errno == EINTR)
 				continue;
 			warning("wait for single-user shell failed: %m; restarting");
-			return (state_func_t) single_user;
+			//return (state_func_t) single_user;
 		}
 		if (wpid == pid && WIFSTOPPED(status)) {
 			warning("init: shell stopped, restarting\n");
@@ -698,8 +577,8 @@
 		}
 	} while (wpid != pid && !requested_transition);
 
-	if (requested_transition)
-		return (state_func_t) requested_transition;
+	//if (requested_transition)
+		//return (state_func_t) requested_transition;
 
 	if (!WIFEXITED(status)) {
 		if (WTERMSIG(status) == SIGKILL) {
@@ -711,20 +590,18 @@
 			_exit(0);
 		} else {
 			warning("single user shell terminated, restarting");
-			return (state_func_t) single_user;
+			//return (state_func_t) single_user;
 		}
 	}
 
 	runcom_mode = FASTBOOT;
-	return (state_func_t) runcom;
+	//return (state_func_t) runcom;
 }
 
 /*
  * Run the system startup script.
  */
-state_func_t
-runcom(void)
-{
+void runcom(void) {
 	pid_t pid, wpid;
 	int status;
 	char *argv[4];
@@ -764,24 +641,25 @@
 		while (waitpid(-1, (int *) 0, WNOHANG) > 0)
 			continue;
 		sleep(STALL_TIMEOUT);
-		return (state_func_t) single_user;
+		//return (state_func_t) single_user;
 	}
 
 	/*
 	 * Copied from single_user().  This is a bit paranoid.
 	 */
-	requested_transition = 0;
+	//requested_transition = 0;
+	
 	do {
 		if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1)
 			collect_child(wpid);
 		if (wpid == -1) {
-			if (requested_transition == death)
-				return (state_func_t) death;
+			//if (requested_transition == death)
+				//return (state_func_t) death;
 			if (errno == EINTR)
 				continue;
 			warning("wait for %s on %s failed: %m; going to single user mode",
 				_PATH_BSHELL, _PATH_RUNCOM);
-			return (state_func_t) single_user;
+			//return (state_func_t) single_user;
 		}
 		if (wpid == pid && WIFSTOPPED(status)) {
 			warning("init: %s on %s stopped, restarting\n",
@@ -804,16 +682,16 @@
 	if (!WIFEXITED(status)) {
 		warning("%s on %s terminated abnormally, going to single user mode",
 			_PATH_BSHELL, _PATH_RUNCOM);
-		return (state_func_t) single_user;
+		//return (state_func_t) single_user;
 	}
 
-	if (WEXITSTATUS(status))
-		return (state_func_t) single_user;
+	//if (WEXITSTATUS(status))
+		//return (state_func_t) single_user;
 
 	runcom_mode = AUTOBOOT;		/* the default */
 	/* NB: should send a message to the session logger to avoid blocking. */
 	logwtmp("~", "reboot", "");
-	return (state_func_t) read_ttys;
+	//return (state_func_t) read_ttys;
 }
 
 /*

==== //depot/projects/soc2005/launchd/launchd.c#9 (text+ko) ====

@@ -360,10 +360,8 @@
 		struct timespec *timeoutp = NULL;
 
 		if (getpid() == 1) {
-#ifndef _NO_INIT_
 			if (readcfg_pid == 0)
 				init_pre_kevent();
-#endif
 		} else {
 			if (TAILQ_EMPTY(&jobs)) {
 				/* launched on demand */


More information about the p4-projects mailing list