From addc21bdf6537068cb113fb4a79518566935b68e Mon Sep 17 00:00:00 2001 From: Joachim Nilsson Date: Mon, 8 Aug 2016 19:06:35 +0200 Subject: [PATCH] UTMP: Set BOOT_TIME record and add shutdown This patch adds support for initializing /var/run/utmp with the initial reboot as well as a shutdown record in the UTMP db. Also, the run level change now properly records ~ and ~~ as line and id, respectively, and the kernel release and time of each UTMP record is now set properly. Signed-off-by: Joachim Nilsson --- finit.c | 6 +++++- sig.c | 4 ++++ utmp-api.c | 32 ++++++++++++++++++++++++++++++-- utmp-api.h | 6 ++++-- 4 files changed, 43 insertions(+), 5 deletions(-) diff --git a/finit.c b/finit.c index 346744f4..fc48c7ab 100644 --- a/finit.c +++ b/finit.c @@ -42,8 +42,9 @@ #include "plugin.h" #include "service.h" #include "sig.h" -#include "tty.h" #include "sm.h" +#include "tty.h" +#include "utmp-api.h" int debug = 0; int quiet = QUIET_MODE; /* Delayed disable of silent mode. */ @@ -269,6 +270,9 @@ int main(int argc, char* argv[]) mount("tmpfs", "/run", "tmpfs", MS_NODEV, "mode=0755,size=10%"); umask(022); + /* Set BOOT_TIME UTMP entry */ + utmp_set_boot(); + /* * Parse kernel parameters */ diff --git a/sig.c b/sig.c index 01149183..3fa7efef 100644 --- a/sig.c +++ b/sig.c @@ -78,6 +78,7 @@ #include "private.h" #include "sig.h" #include "service.h" +#include "utmp-api.h" static int stopped = 0; static uev_t sigterm_watcher, sigusr1_watcher, sigusr2_watcher; @@ -105,6 +106,9 @@ void do_shutdown(shutop_t op) /* Call all shutdown hooks before rebooting... */ plugin_run_hooks(HOOK_SHUTDOWN); + /* Update UTMP db */ + utmp_set_halt(); + /* Here is where we signal watchdogd to do a forced reset for us */ _d("Sending SIGTERM to all processes."); kill(-1, SIGTERM); diff --git a/utmp-api.c b/utmp-api.c index 1b140df5..34956440 100644 --- a/utmp-api.c +++ b/utmp-api.c @@ -24,17 +24,35 @@ #include #include #include +#include #include -int utmp_set(int type, int pid, char *user) +int utmp_set(int type, int pid, char *user, char *line, char *id) { int result; struct utmp ut; + struct utsname uts; + + switch (type) { + case RUN_LVL: + case BOOT_TIME: + line = "~"; + id = "~~"; + break; + + default: + break; + } memset(&ut, 0, sizeof(ut)); ut.ut_type = type; ut.ut_pid = pid; strlcpy(ut.ut_user, user, sizeof(ut.ut_user)); + strlcpy(ut.ut_line, line, sizeof(ut.ut_line)); + strlcpy(ut.ut_id, id, sizeof(ut.ut_id)); + if (!uname(&uts)) + strncpy(ut.ut_host, uts.release, sizeof(ut.ut_host)); + ut.ut_tv.tv_sec = time(NULL); setutent(); result = pututline(&ut) ? 0 : 1;; @@ -51,7 +69,17 @@ static int encode(int lvl) int utmp_set_runlevel(int pre, int now) { - return utmp_set(RUN_LVL, (encode(pre) << 8) | (encode(now) & 0xFF), "runlevel"); + return utmp_set(RUN_LVL, (encode(pre) << 8) | (encode(now) & 0xFF), "runlevel", NULL, NULL); +} + +int utmp_set_boot(void) +{ + return utmp_set(BOOT_TIME, 0, "reboot", NULL, NULL); +} + +int utmp_set_halt(void) +{ + return utmp_set(RUN_LVL, 0, "shutdown", NULL, NULL); } int utmp_show(char *file) diff --git a/utmp-api.h b/utmp-api.h index 5df60503..8c819f32 100644 --- a/utmp-api.h +++ b/utmp-api.h @@ -21,9 +21,11 @@ * THE SOFTWARE. */ -int utmp_set (int type, int pid, char *user); +int utmp_set (int type, int pid, char *user, char *line, char *id); +int utmp_set_boot (void); +int utmp_set_halt (void); int utmp_set_runlevel(int pre, int now); -int utmp_show(char *file); +int utmp_show (char *file); /** * Local Variables: