Move utmpx handling out of init(8).

This has the following advantages:

- During boot, the BOOT_TIME record is now written right after the file
  systems become writable, but before users are allowed to log in. This
  means that they can't cause `hidden logins' by logging in right before
  init(8) kicks in.

- The pututxline(3) function may potentially block on file locking,
  though this is very rare to occur. By placing it in an rc script, the
  user can still kill it with ^C if needed.

- Most importantly: jails don't use init(8). This means that a force
  reboot of a system running jails will leave stale entries in the
  accounting database of the jails individually.
This commit is contained in:
Ed Schouten 2012-02-11 20:47:16 +00:00
parent fb53b9cf56
commit c21ae3a403
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=231534
5 changed files with 25 additions and 42 deletions

View file

@ -144,6 +144,7 @@ FILES= DAEMON \
tmp \
${_ubthidhci} \
ugidfw \
${_utx} \
var \
virecover \
watchdogd \
@ -177,6 +178,10 @@ _nscd= nscd
_ubthidhci= ubthidhci
.endif
.if ${MK_UTMPX} != "no"
_utx= utx
.endif
FILESDIR= /etc/rc.d
FILESMODE= ${BINMODE}

View file

@ -58,8 +58,6 @@ cleanvar_start ()
{
if [ -d /var/run -a ! -f /var/run/clean_var ]; then
purgedir /var/run
# And an initial utmpx active session file
(cd /var/run && cp /dev/null utx.active && chmod 644 utx.active)
>/var/run/clean_var
fi
if [ -d /var/spool/lock -a ! -f /var/spool/lock/clean_var ]; then

18
etc/rc.d/utx Executable file
View file

@ -0,0 +1,18 @@
#!/bin/sh
#
# $FreeBSD$
#
# PROVIDE: utx
# REQUIRE: DAEMON cleanvar
# BEFORE: LOGIN
# KEYWORD: shutdown
. /etc/rc.subr
name="utx"
start_cmd="utx boot"
stop_cmd="utx shutdown"
load_rc_config $name
run_rc_command "$1"

View file

@ -31,7 +31,7 @@
.\" @(#)init.8 8.3 (Berkeley) 4/18/94
.\" $FreeBSD$
.\"
.Dd January 23, 2011
.Dd February 11, 2012
.Dt INIT 8
.Os
.Sh NAME
@ -146,14 +146,7 @@ executes a shell for that user.
When this shell
dies, either because the user logged out
or an abnormal termination occurred (a signal),
.Nm login
records the logout in the user accounting
database (see
.Xr getutxent 3)
and terminates.
The cycle is
then restarted by
.Nm
the cycle is restarted by
executing a new
.Nm getty
for the line.

View file

@ -66,7 +66,6 @@ static const char rcsid[] =
#include <time.h>
#include <ttyent.h>
#include <unistd.h>
#include <utmpx.h>
#include <sys/reboot.h>
#include <err.h>
@ -181,8 +180,6 @@ static void setprocresources(const char *);
#endif
static int clang;
static void clear_session_logs(session_t *);
static int start_session_db(void);
static void add_session(session_t *);
static void del_session(session_t *);
@ -566,20 +563,6 @@ transition(state_t s)
current_state = (state_t) (*current_state)();
}
/*
* Close out the accounting files for a login session.
* NB: should send a message to the session logger to avoid blocking.
*/
static void
clear_session_logs(session_t *sp __unused)
{
/*
* XXX: Use getutxline() and call pututxline() for each entry.
* Is this safe to do this here? Is it really required anyway?
*/
}
/*
* Start a session and allocate a controlling terminal.
* Only called by children of init after forking.
@ -780,17 +763,12 @@ single_user(void)
static state_func_t
runcom(void)
{
struct utmpx utx;
state_func_t next_transition;
if ((next_transition = run_script(_PATH_RUNCOM)) != 0)
return next_transition;
runcom_mode = AUTOBOOT; /* the default */
/* NB: should send a message to the session logger to avoid blocking. */
utx.ut_type = BOOT_TIME;
gettimeofday(&utx.ut_tv, NULL);
pututxline(&utx);
return (state_func_t) read_ttys;
}
@ -1119,8 +1097,6 @@ read_ttys(void)
* There shouldn't be any, but just in case...
*/
for (sp = sessions; sp; sp = snext) {
if (sp->se_process)
clear_session_logs(sp);
snext = sp->se_next;
free_session(sp);
}
@ -1274,7 +1250,6 @@ collect_child(pid_t pid)
if (! (sp = find_session(pid)))
return;
clear_session_logs(sp);
del_session(sp);
sp->se_process = 0;
@ -1504,14 +1479,8 @@ alrm_handler(int sig)
static state_func_t
death(void)
{
struct utmpx utx;
session_t *sp;
/* NB: should send a message to the session logger to avoid blocking. */
utx.ut_type = SHUTDOWN_TIME;
gettimeofday(&utx.ut_tv, NULL);
pututxline(&utx);
/*
* Also revoke the TTY here. Because runshutdown() may reopen
* the TTY whose getty we're killing here, there is no guarantee