Marcus Meissner
50f51f372a
OBS-URL: https://build.opensuse.org/package/show/Base:System/sysvinit?expand=0&rev=14
210 lines
6.5 KiB
Diff
210 lines
6.5 KiB
Diff
Index: src/init.c
|
|
===================================================================
|
|
--- src/init.c.orig
|
|
+++ src/init.c
|
|
@@ -107,6 +107,8 @@ sig_atomic_t got_signals; /* Set if we r
|
|
int emerg_shell = 0; /* Start emergency shell? */
|
|
int wrote_wtmp_reboot = 1; /* Set when we wrote the reboot record */
|
|
int wrote_utmp_reboot = 1; /* Set when we wrote the reboot record */
|
|
+int wrote_wtmp_rlevel = 1; /* Set when we wrote the runlevel record */
|
|
+int wrote_utmp_rlevel = 1; /* Set when we wrote the runlevel record */
|
|
int sltime = 5; /* Sleep time between TERM and KILL */
|
|
char *argv0; /* First arguments; show up in ps listing */
|
|
int maxproclen; /* Maximal length of argv[0] with \0 */
|
|
@@ -176,6 +178,8 @@ struct {
|
|
{ "-WU", D_WROTE_UTMP_REBOOT},
|
|
{ "-ST", D_SLTIME },
|
|
{ "-DB", D_DIDBOOT },
|
|
+ { "-LW", D_WROTE_WTMP_RLEVEL},
|
|
+ { "-LU", D_WROTE_UTMP_RLEVEL},
|
|
{ "", 0 }
|
|
};
|
|
struct {
|
|
@@ -371,6 +375,12 @@ static CHILD *get_record(FILE *f)
|
|
case D_DIDBOOT:
|
|
fscanf(f, "%d\n", &did_boot);
|
|
break;
|
|
+ case D_WROTE_WTMP_RLEVEL:
|
|
+ fscanf(f, "%d\n", &wrote_wtmp_rlevel);
|
|
+ break;
|
|
+ case D_WROTE_UTMP_RLEVEL:
|
|
+ fscanf(f, "%d\n", &wrote_utmp_rlevel);
|
|
+ break;
|
|
default:
|
|
if (cmd > 0 || cmd == C_EOF) {
|
|
oops_error = -1;
|
|
@@ -1697,6 +1707,8 @@ int read_level(int arg)
|
|
}
|
|
|
|
/* Store both the old and the new runlevel. */
|
|
+ wrote_utmp_rlevel = 0;
|
|
+ wrote_wtmp_rlevel = 0;
|
|
write_utmp_wtmp("runlevel", "~~", foo + 256*runlevel, RUN_LVL, "~");
|
|
thislevel = foo;
|
|
prevlevel = runlevel;
|
|
@@ -1897,6 +1909,25 @@ void re_exec(void)
|
|
initlog(L_CO, "Attempt to re-exec failed");
|
|
}
|
|
|
|
+/*
|
|
+ * Redo utmp/wtmp entries if required or requested
|
|
+ * Check for written records and size of utmp
|
|
+ */
|
|
+static
|
|
+void redo_utmp_wtmp(void)
|
|
+{
|
|
+ struct stat ustat;
|
|
+ const int ret = stat(UTMP_FILE, &ustat);
|
|
+
|
|
+ if ((ret < 0) || (ustat.st_size == 0))
|
|
+ wrote_utmp_rlevel = wrote_utmp_reboot = 0;
|
|
+
|
|
+ if ((wrote_wtmp_reboot == 0) || (wrote_utmp_reboot == 0))
|
|
+ write_utmp_wtmp("reboot", "~~", 0, BOOT_TIME, "~");
|
|
+
|
|
+ if ((wrote_wtmp_rlevel == 0) || (wrote_wtmp_rlevel == 0))
|
|
+ write_utmp_wtmp("runlevel", "~~", thislevel + 256 * prevlevel, RUN_LVL, "~");
|
|
+}
|
|
|
|
/*
|
|
* We got a change runlevel request through the
|
|
@@ -1928,6 +1959,7 @@ void fifo_new_level(int level)
|
|
if (oldlevel != 'S' && runlevel == 'S') console_stty();
|
|
if (runlevel == '6' || runlevel == '0' ||
|
|
runlevel == '1') console_stty();
|
|
+ if (runlevel > '1' && runlevel < '6') redo_utmp_wtmp();
|
|
read_inittab();
|
|
fail_cancel();
|
|
setproctitle("init [%c]", runlevel);
|
|
@@ -2223,6 +2255,8 @@ void boot_transitions()
|
|
}
|
|
if (loglevel > 0) {
|
|
initlog(L_VB, "Entering runlevel: %c", runlevel);
|
|
+ wrote_utmp_rlevel = 0;
|
|
+ wrote_wtmp_rlevel = 0;
|
|
write_utmp_wtmp("runlevel", "~~", runlevel + 256 * oldlevel, RUN_LVL, "~");
|
|
thislevel = runlevel;
|
|
prevlevel = oldlevel;
|
|
@@ -2401,6 +2435,7 @@ int init_main()
|
|
console_init();
|
|
|
|
if (!reload) {
|
|
+ int fd;
|
|
|
|
/* Close whatever files are open, and reset the console. */
|
|
close(0);
|
|
@@ -2418,7 +2453,8 @@ int init_main()
|
|
* Initialize /var/run/utmp (only works if /var is on
|
|
* root and mounted rw)
|
|
*/
|
|
- (void) close(open(UTMP_FILE, O_WRONLY|O_CREAT|O_TRUNC, 0644));
|
|
+ if ((fd = open(UTMP_FILE, O_WRONLY|O_CREAT|O_TRUNC, 0644)) >= 0)
|
|
+ close(fd);
|
|
|
|
/*
|
|
* Say hello to the world
|
|
Index: src/init.h
|
|
===================================================================
|
|
--- src/init.h.orig
|
|
+++ src/init.h
|
|
@@ -99,6 +99,10 @@ typedef struct _child_ {
|
|
extern CHILD *family;
|
|
extern int wrote_wtmp_reboot;
|
|
extern int wrote_utmp_reboot;
|
|
+extern int wrote_wtmp_rlevel;
|
|
+extern int wrote_utmp_rlevel;
|
|
+extern char thislevel;
|
|
+extern char prevlevel;
|
|
|
|
/* Tokens in state parser */
|
|
#define C_VER 1
|
|
@@ -120,4 +124,6 @@ extern int wrote_utmp_reboot;
|
|
#define D_WROTE_UTMP_REBOOT -7
|
|
#define D_SLTIME -8
|
|
#define D_DIDBOOT -9
|
|
+#define D_WROTE_WTMP_RLEVEL -16
|
|
+#define D_WROTE_UTMP_RLEVEL -17
|
|
|
|
Index: src/utmp.c
|
|
===================================================================
|
|
--- src/utmp.c.orig
|
|
+++ src/utmp.c
|
|
@@ -49,6 +49,12 @@ char *line) /* Which line is this */
|
|
struct utsname uname_buf;
|
|
|
|
/*
|
|
+ * Can't do much if WTMP_FILE is not present or not writable.
|
|
+ */
|
|
+ if (access(WTMP_FILE, W_OK) < 0)
|
|
+ return;
|
|
+
|
|
+ /*
|
|
* Try to open the wtmp file. Note that we even try
|
|
* this if we have updwtmp() so we can see if the
|
|
* wtmp file is accessible.
|
|
@@ -69,6 +75,23 @@ char *line) /* Which line is this */
|
|
*/
|
|
if (wrote_wtmp_reboot == 0 && type != BOOT_TIME)
|
|
write_wtmp("reboot", "~~", 0, BOOT_TIME, "~");
|
|
+
|
|
+ /*
|
|
+ * Note if we are going to write a runlevel record.
|
|
+ */
|
|
+ if (type == RUN_LVL) wrote_wtmp_rlevel++;
|
|
+
|
|
+ /*
|
|
+ * See if we need to write a runlevel record. The reason that
|
|
+ * we are being so paranoid is that when we first tried to
|
|
+ * write the reboot record, /var was possibly not mounted
|
|
+ * yet. As soon as we can open WTMP we write a delayed runlevel record.
|
|
+ */
|
|
+ if (wrote_wtmp_rlevel == 0 && type != RUN_LVL) {
|
|
+ int runlevel = thislevel;
|
|
+ int oldlevel = prevlevel;
|
|
+ write_wtmp("runlevel", "~~", runlevel + 256 * oldlevel, RUN_LVL, "~");
|
|
+ }
|
|
#endif
|
|
|
|
/*
|
|
@@ -115,9 +138,9 @@ char *oldline) /* Line of old utmp ent
|
|
struct utmp *utmptr;
|
|
|
|
/*
|
|
- * Can't do much if UTMP_FILE is not present.
|
|
+ * Can't do much if UTMP_FILE is not present or not writable.
|
|
*/
|
|
- if (access(UTMP_FILE, F_OK) < 0)
|
|
+ if (access(UTMP_FILE, W_OK) < 0)
|
|
return;
|
|
|
|
#ifdef INIT_MAIN
|
|
@@ -130,10 +153,27 @@ char *oldline) /* Line of old utmp ent
|
|
* See if we need to write a reboot record. The reason that
|
|
* we are being so paranoid is that when we first tried to
|
|
* write the reboot record, /var was possibly not mounted
|
|
- * yet. As soon as we can open WTMP we write a delayed boot record.
|
|
+ * yet. As soon as we can open UTMP we write a delayed boot record.
|
|
*/
|
|
if (wrote_utmp_reboot == 0 && type != BOOT_TIME)
|
|
write_utmp("reboot", "~~", 0, BOOT_TIME, "~", NULL);
|
|
+
|
|
+ /*
|
|
+ * Note if we are going to write a runlevel record.
|
|
+ */
|
|
+ if (type == RUN_LVL) wrote_utmp_rlevel++;
|
|
+
|
|
+ /*
|
|
+ * See if we need to write a runlevel record. The reason that
|
|
+ * we are being so paranoid is that when we first tried to
|
|
+ * write the reboot record, /var was possibly not mounted
|
|
+ * yet. As soon as we can open UTMP we write a delayed runlevel record.
|
|
+ */
|
|
+ if (wrote_utmp_rlevel == 0 && type != RUN_LVL) {
|
|
+ int runlevel = thislevel;
|
|
+ int oldlevel = prevlevel;
|
|
+ write_utmp("runlevel", "~~", runlevel + 256 * oldlevel, RUN_LVL, "~", NULL);
|
|
+ }
|
|
#endif
|
|
|
|
/*
|