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.
This commit is contained in:
Jesse Smith 2018-07-07 20:19:03 -03:00
parent 6b26692584
commit 6e8323e9fb
8 changed files with 37 additions and 14 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -57,6 +57,7 @@
#include <stdio.h>
#include <getopt.h>
#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);

View File

@ -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)) {

View File

@ -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);
}

View File

@ -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
}