From 6e8323e9fbdc1e9e5e8483ab497775a4b3feacc1 Mon Sep 17 00:00:00 2001 From: Jesse Smith Date: Sat, 7 Jul 2018 20:19:03 -0300 Subject: [PATCH] The init process now writes the current runlevel to /var/run/runlevel. This information can be read by the "runlevel" command as well as "halt" and "reboot". Having the information logged in /var/run/runlevel as well as the utmp file means systems without utmp (like those running the musl C library) can still check the current runlevel. This is useful when running halt/reboot as these programs want to check the runlevel. Updated the changelog, and manual pages for halt and runlevel. --- doc/Changelog | 8 +++++++- man/halt.8 | 3 ++- man/runlevel.8 | 4 +++- src/Makefile | 8 ++++---- src/halt.c | 9 +++++++++ src/init.c | 6 ++++++ src/runlevel.c | 4 ++-- src/runlevellog.c | 9 ++++----- 8 files changed, 37 insertions(+), 14 deletions(-) diff --git a/doc/Changelog b/doc/Changelog index 1e6c29b..e9716f9 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -9,7 +9,13 @@ sysvinit (2.91) UNRELEASED; urgency=low Updated manual page for init.8 to match. * Version information is now fetched and defined by the Makefile. No more need to update the version manually in the init.c source. - + * The init process now writes the current runlevel to /var/run/runlevel. + This information can be read by the "runlevel" command as well as "halt" + and "reboot". Having the information logged in /var/run/runlevel as + well as the utmp file means systems without utmp (like those running + the musl C library) can still check the current runlevel. This is + useful when running halt/reboot as these programs want to check the + runlevel. sysvinit (2.90) world; urgency=low diff --git a/man/halt.8 b/man/halt.8 index 9f326f6..beea730 100644 --- a/man/halt.8 +++ b/man/halt.8 @@ -95,7 +95,8 @@ never be called directly. From release 2.74 on \fBhalt\fP and \fBreboot\fP invoke \fBshutdown\fP(8) if the system is not in runlevel 0 or 6. This means that if \fBhalt\fP or \fBreboot\fP cannot find out the current runlevel (for example, when \fI/var/run/utmp\fP hasn't been initialized -correctly) \fBshutdown\fP will be called, which might not be what you want. +correctly and /var/run/runlevel does not exist) \fBshutdown\fP will be called, +which might not be what you want. Use the \fB-f\fP flag if you want to do a hard \fBhalt\fP or \fBreboot\fP. .PP The \fB-h\fP flag puts all hard disks in standby mode just before halt diff --git a/man/runlevel.8 b/man/runlevel.8 index 1e4ea77..3f8d3d2 100644 --- a/man/runlevel.8 +++ b/man/runlevel.8 @@ -34,7 +34,9 @@ runlevel, the letter \fBN\fP will be printed instead. .PP If no .I utmp -file exists, or if no runlevel record can be found, +file exists, and if no runlevel record can be found in the +.I /var/run/runlevel +file, .B runlevel prints the word \fBunknown\fP and exits with an error. .PP diff --git a/src/Makefile b/src/Makefile index f5dcc2e..b21d147 100644 --- a/src/Makefile +++ b/src/Makefile @@ -107,10 +107,10 @@ all: $(BIN) $(SBIN) $(USRBIN) # $(CC) $(CFLAGS) $(CPPFLAGS) -c $^ -o $@ init: LDLIBS += $(INITLIBS) $(STATIC) -init: init.o init_utmp.o +init: init.o init_utmp.o runlevellog.o halt: LDLIBS += $(STATIC) -halt: halt.o ifdown.o hddown.o utmp.o +halt: halt.o ifdown.o hddown.o utmp.o runlevellog.o last: LDLIBS += $(STATIC) last: last.o @@ -148,7 +148,7 @@ sulogin.o: sulogin.c runlevellog.o: runlevellog.h runlevellog.c paths.h init.o: CPPFLAGS += $(SELINUX_DEF) -init.o: init.c init.h initreq.h paths.h reboot.h set.h +init.o: init.c init.h initreq.h paths.h reboot.h runlevellog.h runlevellog.c set.h paths.h utmp.o: @@ -160,7 +160,7 @@ utmpdump.o: utmpdump.c oldutmp.h shutdown.o: shutdown.c paths.h reboot.h initreq.h init.h -halt.o: halt.c reboot.h +halt.o: halt.c reboot.h paths.h runlevellog.c runlevellog.h last.o: last.c oldutmp.h diff --git a/src/halt.c b/src/halt.c index 7dbafa2..98bdadf 100644 --- a/src/halt.c +++ b/src/halt.c @@ -57,6 +57,7 @@ #include #include #include "reboot.h" +#include "runlevellog.h" char *Version = "@(#)halt 2.86 31-Jul-2004 miquels@cistron.nl"; char *progname; @@ -90,11 +91,14 @@ void usage(void) /* * See if we were started directly from init. * Get the runlevel from /var/run/utmp or the environment. + * Or the /var/run/runlevel log. */ int get_runlevel(void) { struct utmp *ut; char *r; + int runlevel, status; + #if RUNLVL_PICKY time_t boottime; #endif @@ -134,6 +138,11 @@ int get_runlevel(void) } endutent(); + /* Did not find utmp entry, try to read from log file */ + status = Read_Runlevel_Log(&runlevel); + if (status) + return runlevel; + /* This should not happen but warn the user! */ fprintf(stderr, "WARNING: could not determine runlevel" " - doing soft %s\n", progname); diff --git a/src/init.c b/src/init.c index edbc856..3d6f3ab 100644 --- a/src/init.c +++ b/src/init.c @@ -80,6 +80,7 @@ Version information is not placed in the top-level Makefile by default #include "initreq.h" #include "paths.h" #include "reboot.h" +#include "runlevellog.h" #include "set.h" #ifndef SIGPWR @@ -1905,6 +1906,7 @@ int get_init_default(void) /* * Log the fact that we have a runlevel now. */ + Write_Runlevel_Log(lvl); return lvl; } @@ -2020,6 +2022,7 @@ int read_level(int arg) write_utmp_wtmp("runlevel", "~~", foo + 256*runlevel, RUN_LVL, "~"); thislevel = foo; prevlevel = runlevel; + Write_Runlevel_Log(runlevel); return foo; } @@ -2284,6 +2287,7 @@ void fifo_new_level(int level) setproctitle("init [%c]", (int)runlevel); } } + Write_Runlevel_Log(runlevel); } @@ -2572,6 +2576,7 @@ void boot_transitions() prevlevel = oldlevel; setproctitle("init [%c]", (int)runlevel); } + Write_Runlevel_Log(runlevel); } } @@ -2683,6 +2688,7 @@ void process_signals() setproctitle("init [%c]", (int)runlevel); DELSET(got_signals, SIGHUP); } + Write_Runlevel_Log(runlevel); } } if (ISMEMBER(got_signals, SIGUSR1)) { diff --git a/src/runlevel.c b/src/runlevel.c index 3dd8df3..e5fa037 100644 --- a/src/runlevel.c +++ b/src/runlevel.c @@ -52,10 +52,10 @@ char **argv; status = Read_Runlevel_Log(&runlevel); if (status) { - printf("%c\n", runlevel); + printf("N %c\n", runlevel); return 0; } - printf("Unknown.\n"); + printf("unknown\n"); return(1); } diff --git a/src/runlevellog.c b/src/runlevellog.c index 363ce7d..ea85d20 100644 --- a/src/runlevellog.c +++ b/src/runlevellog.c @@ -42,7 +42,7 @@ int Write_Runlevel_Log(int new_runlevel) if (status < 1) return FALSE; return TRUE; -} // end of writing to log function +} /* @@ -60,12 +60,11 @@ int Read_Runlevel_Log(int *runlevel) if (! log_file) return FALSE; - status = fscanf(log_file, "%c", runlevel); + status = fscanf(log_file, "%c", (char *) runlevel); fclose(log_file); - if (status == EOF) + if (status < 1) return FALSE; return TRUE; -} // end of reading from log function - +}