diff --git a/etc/newsyslog.conf b/etc/newsyslog.conf index 67aa11726d6a..b750836e421c 100644 --- a/etc/newsyslog.conf +++ b/etc/newsyslog.conf @@ -24,6 +24,7 @@ /var/log/cron 600 3 100 * JC /var/log/daily.log 640 7 * @T00 JN /var/log/debug.log 600 7 100 * JC +/var/log/init.log 644 3 100 * J /var/log/kerberos.log 600 7 100 * J /var/log/lpd-errs 644 7 100 * JC /var/log/maillog 640 7 * @T00 JC diff --git a/sbin/init/init.8 b/sbin/init/init.8 index 1d7bc2e78403..fa9f7f0df8e4 100644 --- a/sbin/init/init.8 +++ b/sbin/init/init.8 @@ -31,7 +31,7 @@ .\" @(#)init.8 8.3 (Berkeley) 4/18/94 .\" $FreeBSD$ .\" -.Dd February 11, 2012 +.Dd March 14, 2012 .Dt INIT 8 .Os .Sh NAME @@ -293,22 +293,22 @@ as follows: file .El .Sh FILES -.Bl -tag -width /etc/rc.shutdown -compact +.Bl -tag -width /var/log/init.log -compact .It Pa /dev/console system console device .It Pa /dev/tty* terminal ports found in .Xr ttys 5 -.It Pa /var/run/utx.active -record of current users on the system -.It Pa /var/log/utx.log -record of all logins and logouts .It Pa /etc/ttys the terminal initialization information file .It Pa /etc/rc system startup commands .It Pa /etc/rc.shutdown system shutdown commands +.It Pa /var/log/init.log +log of +.Xr rc 8 +output if the system console device is not available .El .Sh DIAGNOSTICS .Bl -diag diff --git a/sbin/init/init.c b/sbin/init/init.c index 8ee7a8d51f7e..a24371cbc235 100644 --- a/sbin/init/init.c +++ b/sbin/init/init.c @@ -138,7 +138,7 @@ static void transition(state_t); static state_t requested_transition; static state_t current_state = death_single; -static void setctty(const char *); +static void open_console(void); static const char *get_shell(void); static void write_stderr(const char *message); @@ -568,19 +568,35 @@ transition(state_t s) * Only called by children of init after forking. */ static void -setctty(const char *name) +open_console(void) { int fd; - revoke(name); - if ((fd = open(name, O_RDWR)) == -1) { - stall("can't open %s: %m", name); + /* Try to open /dev/console. */ + revoke(_PATH_CONSOLE); + if ((fd = open(_PATH_CONSOLE, O_RDWR | O_NONBLOCK)) != -1) { + if (login_tty(fd) == 0) + return; + close(fd); + } + + /* No luck. Log output to file if possible. */ + if ((fd = open(_PATH_DEVNULL, O_RDWR)) == -1) { + stall("cannot open null device."); _exit(1); } - if (login_tty(fd) == -1) { - stall("can't get %s for controlling terminal: %m", name); - _exit(1); + if (fd != STDIN_FILENO) { + dup2(fd, STDIN_FILENO); + close(fd); } + fd = open(_PATH_INITLOG, O_WRONLY | O_APPEND | O_CREAT, 0644); + if (fd == -1) + dup2(STDIN_FILENO, STDOUT_FILENO); + else if (fd != STDOUT_FILENO) { + dup2(fd, STDOUT_FILENO); + close(fd); + } + dup2(STDOUT_FILENO, STDERR_FILENO); } static const char * @@ -638,7 +654,7 @@ single_user(void) /* * Start the single user session. */ - setctty(_PATH_CONSOLE); + open_console(); #ifdef SECURE /* @@ -798,7 +814,7 @@ run_script(const char *script) sigaction(SIGTSTP, &sa, (struct sigaction *)0); sigaction(SIGHUP, &sa, (struct sigaction *)0); - setctty(_PATH_CONSOLE); + open_console(); char _sh[] = "sh"; char _autoboot[] = "autoboot"; @@ -1572,7 +1588,7 @@ runshutdown(void) sigaction(SIGTSTP, &sa, (struct sigaction *)0); sigaction(SIGHUP, &sa, (struct sigaction *)0); - setctty(_PATH_CONSOLE); + open_console(); char _sh[] = "sh"; char _reboot[] = "reboot"; diff --git a/sbin/init/pathnames.h b/sbin/init/pathnames.h index 335445bb0634..39eed4c868bb 100644 --- a/sbin/init/pathnames.h +++ b/sbin/init/pathnames.h @@ -35,6 +35,7 @@ #include +#define _PATH_INITLOG "/var/log/init.log" #define _PATH_SLOGGER "/sbin/session_logger" #define _PATH_RUNCOM "/etc/rc" #define _PATH_RUNDOWN "/etc/rc.shutdown"