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