From owner-p4-projects@FreeBSD.ORG Thu Aug 4 04:34:33 2005 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 3427B16A421; Thu, 4 Aug 2005 04:34:33 +0000 (GMT) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id EB0F916A41F for ; Thu, 4 Aug 2005 04:34:32 +0000 (GMT) (envelope-from soc-tyler@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 9FC9043D45 for ; Thu, 4 Aug 2005 04:34:32 +0000 (GMT) (envelope-from soc-tyler@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id j744YWHg044970 for ; Thu, 4 Aug 2005 04:34:32 GMT (envelope-from soc-tyler@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id j744YWLr044967 for perforce@freebsd.org; Thu, 4 Aug 2005 04:34:32 GMT (envelope-from soc-tyler@freebsd.org) Date: Thu, 4 Aug 2005 04:34:32 GMT Message-Id: <200508040434.j744YWLr044967@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to soc-tyler@freebsd.org using -f From: soc-tyler To: Perforce Change Reviews Cc: Subject: PERFORCE change 81425 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 04 Aug 2005 04:34:34 -0000 http://perforce.freebsd.org/chv.cgi?CH=81425 Change 81425 by soc-tyler@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 #include #include +#include #include #include #include @@ -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 */