1 Submitted By: Jim Gifford (jim at cross-lfs dot org)
3 Initial Package Version: 2.86
5 Upstream Status: Unknown
6 Description: Fixes to Major issues in Sysvinit -- listed Below
7 IPV6 Displayed Incorrectly
8 On 64bit which have 32bit multilib support, the utmp struct is the same
9 Fix bug where proc names are truncated
10 Fixed support for POSIX capabilite
11 All halt/reboot to handle being called by login correctly
12 Preserve waiting state across re-exec
13 Allow failed console opens some time to resolve themselves
18 diff -Naur sysvinit-2.86.orig/man/halt.8 sysvinit-2.86/man/halt.8
19 --- sysvinit-2.86.orig/man/halt.8 2001-11-21 13:11:22.000000000 -0800
20 +++ sysvinit-2.86/man/halt.8 2009-01-07 11:07:06.000000000 -0800
31 When halting the system, do a poweroff. This is the default when halt is
32 called as \fBpoweroff\fP.
34 +Try to reboot using \fBkexec\fP, if kernel supports it.
38 diff -Naur sysvinit-2.86.orig/man/init.8 sysvinit-2.86/man/init.8
39 --- sysvinit-2.86.orig/man/init.8 2004-07-29 04:21:31.000000000 -0700
40 +++ sysvinit-2.86/man/init.8 2009-01-07 11:23:45.000000000 -0800
43 Runlevel \fBS\fP or \fBs\fP bring the system to single user mode
44 and do not require an \fB/etc/inittab\fP file. In single user mode,
45 -\fB/sbin/sulogin\fP is invoked on \fB/dev/console\fP.
46 +a root shell is opened on \fB/dev/console\fP.
48 When entering single user mode, \fBinit\fP initializes the consoles
49 \fBstty\fP settings to sane values. Clocal mode is set. Hardware
50 diff -Naur sysvinit-2.86.orig/man/last.1 sysvinit-2.86/man/last.1
51 --- sysvinit-2.86.orig/man/last.1 2004-07-30 04:39:18.000000000 -0700
52 +++ sysvinit-2.86/man/last.1 2009-01-07 11:23:45.000000000 -0800
54 useful, e.g., to determine easily who was logged in at a particular
55 time -- specify that time with \fB\-t\fP and look for "still logged
57 +.IP "\fB\-f\fP \fIfile\fP"
58 +Specifies a file to search other than \fB/var/log/wtmp\fP.
60 Suppresses the display of the hostname field.
62 diff -Naur sysvinit-2.86.orig/man/pidof.8 sysvinit-2.86/man/pidof.8
63 --- sysvinit-2.86.orig/man/pidof.8 1998-09-02 05:49:33.000000000 -0700
64 +++ sysvinit-2.86/man/pidof.8 2009-01-07 11:22:28.000000000 -0800
76 Single shot - this instructs the program to only return one \fIpid\fP.
78 +Only return process ids that are running with the same root directory.
79 +This option is ignored for non-root users, as they will be unable to check
80 +the current root directory of processes they do not own.
82 Scripts too - this causes the program to also return process id's of
83 shells running the named scripts.
84 diff -Naur sysvinit-2.86.orig/man/shutdown.8 sysvinit-2.86/man/shutdown.8
85 --- sysvinit-2.86.orig/man/shutdown.8 2004-06-09 05:47:45.000000000 -0700
86 +++ sysvinit-2.86/man/shutdown.8 2009-01-07 11:08:22.000000000 -0800
96 -.RI [ warning-message ]
97 +.RI [ "warning message" ]
103 Use \fB/etc/shutdown.allow\fP.
106 -.IP "\fB\-t\fP \fIsec\fP"
107 -Tell \fBinit\fP(8) to wait \fIsec\fP seconds between sending processes the
108 -warning and the kill signal, before changing to another runlevel.
112 Don't really shutdown; only send the warning messages to everybody.
115 Halt or poweroff after shutdown.
119 -Halt action is to halt or drop into boot monitor on systems that
124 Halt action is to turn off the power.
128 -[DEPRECATED] Don't call \fBinit\fP(8) to do the shutdown but do it ourself.
129 -The use of this option is discouraged, and its results are not always what
133 +Halt action is to halt or drop into boot monitor on systems that
140 Force fsck on reboot.
144 +[DEPRECATED] Don't call \fBinit\fP(8) to do the shutdown but do it ourself.
145 +The use of this option is discouraged, and its results are not always what
150 Cancel an already running shutdown. With this option it is of course
151 not possible to give the \fBtime\fP argument, but you can enter a
152 explanatory message on the command line that will be sent to all users.
155 +.IP "\fB\-t\fP \fIsec\fP"
156 +Tell \fBinit\fP(8) to wait \fIsec\fP seconds between sending processes the
157 +warning and the kill signal, before changing to another runlevel.
163 .\"{{{ warning-message
164 -.IP \fIwarning-message\fP
165 +.IP "\fIwarning message\fP"
166 Message to send to all users.
169 diff -Naur sysvinit-2.86.orig/man/sulogin.8 sysvinit-2.86/man/sulogin.8
170 --- sysvinit-2.86.orig/man/sulogin.8 2004-06-09 05:47:45.000000000 -0700
171 +++ sysvinit-2.86/man/sulogin.8 2009-01-07 11:23:45.000000000 -0800
173 .RB [ " tty-device " ]
176 -is invoked by \fBinit(8)\fP when the system goes into single user mode
177 +can be invoked by \fBinit(8)\fP when the system goes into single user mode
178 (this is done through an entry in \fIinittab(5)\fP). \fBInit\fP also
179 tries to execute \fIsulogin\fP when it is passed the \fB-b\fP flag
180 from the bootmonitor (eg, LILO).
181 diff -Naur sysvinit-2.86.orig/src/bootlogd.c sysvinit-2.86/src/bootlogd.c
182 --- sysvinit-2.86.orig/src/bootlogd.c 2004-06-09 05:47:45.000000000 -0700
183 +++ sysvinit-2.86/src/bootlogd.c 2009-01-07 11:34:12.000000000 -0800
186 todo = endptr - outptr;
188 - writelog(fp, outptr, todo);
189 + writelog(fp, (unsigned char *)outptr, todo);
193 diff -Naur sysvinit-2.86.orig/src/halt.c sysvinit-2.86/src/halt.c
194 --- sysvinit-2.86.orig/src/halt.c 2004-07-30 05:16:18.000000000 -0700
195 +++ sysvinit-2.86/src/halt.c 2009-01-07 11:25:19.000000000 -0800
197 * execute an "shutdown -r". This is for compatibility with
200 - * Usage: halt [-n] [-w] [-d] [-f] [-h] [-i] [-p]
201 + * Usage: halt [-n] [-w] [-d] [-f] [-h] [-i] [-p] [-k]
202 * -n: don't sync before halting the system
203 * -w: only write a wtmp reboot record and exit.
204 * -d: don't write a wtmp record.
206 * -h: put harddisks in standby mode
207 * -i: shut down all network interfaces.
208 * -p: power down the system (if possible, otherwise halt).
209 + * -k: reboot the system using kexec.
211 * Reboot and halt are both this program. Reboot
212 * is just a link to halt. Invoking the program
217 - fprintf(stderr, "usage: %s [-n] [-w] [-d] [-f] [-h] [-i]%s\n",
218 - progname, strcmp(progname, "halt") ? "" : " [-p]");
219 + fprintf(stderr, "usage: %s [-n] [-w] [-d] [-f] [-h] [-i]%s%s\n",
221 + strcmp(progname, "halt") ? "" : " [-p]",
222 + strcmp(progname, "reboot") ? "" : " [-k]");
223 fprintf(stderr, "\t-n: don't sync before halting the system\n");
224 fprintf(stderr, "\t-w: only write a wtmp reboot record and exit.\n");
225 fprintf(stderr, "\t-d: don't write a wtmp record.\n");
227 fprintf(stderr, "\t-i: shut down all network interfaces.\n");
228 if (!strcmp(progname, "halt"))
229 fprintf(stderr, "\t-p: power down the system (if possible, otherwise halt).\n");
230 + if (!strcmp(progname, "reboot"))
231 + fprintf(stderr, "\t-k: reboot the system using kexec.\n");
235 @@ -172,12 +177,14 @@
244 * Find out who we are
246 + if (argv[0][0] == '-') argv[0]++;
247 if ((progname = strrchr(argv[0], '/')) != NULL)
254 - while((c = getopt(argc, argv, ":ihdfnpwt:")) != EOF) {
255 + while((c = getopt(argc, argv, ":ihdfnpwkt:")) != EOF) {
269 @@ -230,12 +240,37 @@
272 if (!do_hard && !do_nothing) {
273 + c = get_runlevel();
276 + * We can't reboot using kexec through this path.
278 + if (c != '6' && do_reboot && do_kexec) {
279 + fprintf(stderr, "ERROR: using -k at this"
280 + " runlevel requires also -f\n"
281 + " (You probably want instead to reboot"
282 + " normally and let your reboot\n"
283 + " script, usually /etc/init.d/reboot,"
289 * See if we are in runlevel 0 or 6.
291 - c = get_runlevel();
292 - if (c != '0' && c != '6')
293 - do_shutdown(do_reboot ? "-r" : "-h", tm);
294 + if (c != '0' && c != '6') {
298 + file = strdup("/poweroff");
300 + file = strdup("/halt");
302 + close(open(file, O_CREAT|O_RDWR, 0644));
305 + do_shutdown(do_reboot ? "-r" : "-h", tm);
311 if (do_nothing) exit(0);
318 + init_reboot(BMAGIC_KEXEC);
322 + * Fall through if failed
324 init_reboot(BMAGIC_REBOOT);
327 diff -Naur sysvinit-2.86.orig/src/init.c sysvinit-2.86/src/init.c
328 --- sysvinit-2.86.orig/src/init.c 2004-07-30 05:16:20.000000000 -0700
329 +++ sysvinit-2.86/src/init.c 2009-01-07 14:02:51.000000000 -0800
340 if (maxproclen > 2) {
341 memset(argv0, 0, maxproclen);
342 - strncpy(argv0, buf, maxproclen - 2);
343 + strncpy(argv0, buf, maxproclen - 1);
349 * Retry the open five times.
351 - for(f = 0; f < 5; f++)
352 + for(f = 0; f < 5; f++) {
353 if ((fd = open(console_dev, m)) >= 0) break;
357 if (fd < 0) return fd;
359 @@ -949,11 +952,30 @@
360 sigprocmask(SIG_SETMASK, &omask, NULL);
363 + * Update utmp/wtmp file prior to starting
364 + * any child. This MUST be done right here in
365 + * the child process in order to prevent a race
366 + * condition that occurs when the child
367 + * process' time slice executes before the
368 + * parent (can and does happen in a uniprocessor
369 + * environment). If the child is a getty and
370 + * the race condition happens, then init's utmp
371 + * update will happen AFTER the getty runs
372 + * and expects utmp to be updated already!
374 + * Do NOT log if process field starts with '+'
375 + * FIXME: that's for compatibility with *very*
376 + * old getties - probably it can be taken out.
378 + if (ch->action == RESPAWN && ch->process[0] != '+')
379 + write_utmp_wtmp("", ch->id, getpid(), INIT_PROCESS, "");
382 * In sysinit, boot, bootwait or single user mode:
383 * for any wait-type subprocess we _force_ the console
384 * to be its controlling tty.
386 - if (strchr("*#sS", runlevel) && ch->flags & WAITING) {
387 + if ((strchr("*#sS", runlevel) || (ch->id[0] == 'l' && isdigit(ch->id[1]))) && ch->flags & WAITING) {
389 * We fork once extra. This is so that we can
390 * wait and change the process group and session
391 @@ -1088,15 +1110,7 @@
394 ch->flags |= RUNNING;
395 - if (spawn(ch, &(ch->pid)) < 0) break;
397 - * Do NOT log if process field starts with '+'
398 - * FIXME: that's for compatibility with *very*
399 - * old getties - probably it can be taken out.
401 - if (ch->process[0] != '+')
402 - write_utmp_wtmp("", ch->id, ch->pid,
404 + (void)spawn(ch, &(ch->pid));
408 @@ -1373,14 +1387,14 @@
409 case 0: /* Send TERM signal */
412 - "Sending processes the TERM signal");
413 + "Sending processes started by init the TERM signal");
414 kill(-(ch->pid), SIGTERM);
417 case 1: /* Send KILL signal and collect status */
420 - "Sending processes the KILL signal");
421 + "Sending processes started by init the KILL signal");
422 kill(-(ch->pid), SIGKILL);
425 @@ -1884,7 +1898,7 @@
426 * The existing init process execs a new init binary.
428 env = init_buildenv(0);
429 - execl(myname, myname, "--init", NULL, env);
430 + execle(myname, myname, "--init", NULL, env);
433 * We shouldn't be here, something failed.
434 diff -Naur sysvinit-2.86.orig/src/killall5.c sysvinit-2.86/src/killall5.c
435 --- sysvinit-2.86.orig/src/killall5.c 2004-07-30 05:16:23.000000000 -0700
436 +++ sysvinit-2.86/src/killall5.c 2009-01-07 14:10:41.000000000 -0800
438 char *argv0base; /* `basename argv[1]` */
439 char *argv1; /* Name as found out from argv[1] */
440 char *argv1base; /* `basename argv[1]` */
441 + char *pathname; /* full path to executable */
442 char *statname; /* the statname without braces */
443 - ino_t ino; /* Inode number */
444 - dev_t dev; /* Device it is on */
445 pid_t pid; /* Process ID. */
446 int sid; /* Session ID. */
447 int kernel; /* Kernel thread or zombie. */
458 if (p->argv0) free(p->argv0);
459 if (p->argv1) free(p->argv1);
460 + if (p->pathname) free(p->pathname);
461 + if (p->statname) free(p->statname);
467 nsyslog(LOG_ERR, "can't read sid from %s\n",
469 + if (p->statname) free(p->statname);
473 @@ -300,15 +301,18 @@
476 /* Process disappeared.. */
477 + if (p->statname) free(p->statname);
482 /* Try to stat the executable. */
483 snprintf(path, sizeof(path), "/proc/%s/exe", d->d_name);
484 - if (stat(path, &st) == 0) {
485 - p->dev = st.st_dev;
486 - p->ino = st.st_ino;
487 + p->pathname = (char *)xmalloc(PATH_MAX);
488 + if (readlink(path, p->pathname, PATH_MAX) == -1) {
489 + p->pathname = NULL;
491 + p->pathname[PATH_MAX-1] = '\0';
494 /* Link it into the list. */
495 @@ -372,14 +376,14 @@
506 /* Try to stat the executable. */
507 - if (prog[0] == '/' && stat(prog, &st) == 0) dostat++;
508 + if (prog[0] == '/' && (real_path = canonicalize_file_name(prog))) dostat++;
510 /* Get basename of program. */
511 if ((s = strrchr(prog, '/')) == NULL)
512 @@ -390,10 +394,10 @@
513 q = (PIDQ_HEAD *)xmalloc(sizeof(PIDQ_HEAD));
516 - /* First try to find a match based on dev/ino pair. */
517 + /* First try to find a match based on pathname. */
519 for (p = plist; p; p = p->next) {
520 - if (p->dev == st.st_dev && p->ino == st.st_ino) {
521 + if (p->pathname && strcmp(real_path, p->pathname) == 0) {
525 @@ -408,11 +412,14 @@
526 ok += (p->argv0 && strcmp(p->argv0, prog) == 0);
527 ok += (p->argv0 && strcmp(p->argv0base, s) == 0);
529 + if (prog[0] == '/' && p->pathname && strcmp(prog, p->pathname))
532 /* For scripts, compare argv[1] as well. */
533 if (scripts_too && p->argv1 &&
534 !strncmp(p->statname, p->argv1base, STATNAMELEN)) {
535 ok += (strcmp(p->argv1, prog) == 0);
536 - ok += (strcmp(p->argv1base, s) == 0);
537 + if (prog[0] != '/') ok += (strcmp(p->argv1base, s) == 0);
541 @@ -476,16 +483,22 @@
544 int i, oind, opt, flags = 0;
545 + int chroot_check = 0;
549 for (oind = PIDOF_OMITSZ-1; oind > 0; oind--)
553 - while ((opt = getopt(argc,argv,"ho:sx")) != EOF) switch (opt) {
554 + while ((opt = getopt(argc,argv,"hco:sx")) != EOF) switch (opt) {
556 nsyslog(LOG_ERR,"invalid options on command line!\n");
560 + if (geteuid() == 0) chroot_check = 1;
563 if (oind >= PIDOF_OMITSZ -1) {
564 nsyslog(LOG_ERR,"omit pid buffer size %d "
569 + /* Check if we are in a chroot */
570 + if (chroot_check) {
571 + snprintf(tmp, 512, "/proc/%d/root", getpid());
572 + if (stat(tmp, &st) < 0) {
573 + nsyslog(LOG_ERR, "stat failed for %s!\n", tmp);
579 /* Print out process-ID's one by one. */
581 for(f = 0; f < argc; f++) {
586 + if (chroot_check) {
588 + snprintf(tmp, 512, "/proc/%d/root",
590 + if (stat(tmp, &st2) < 0 ||
591 + st.st_dev != st2.st_dev ||
592 + st.st_ino != st2.st_ino) {
598 printf("%d", p->pid);
599 diff -Naur sysvinit-2.86.orig/src/last.c sysvinit-2.86/src/last.c
600 --- sysvinit-2.86.orig/src/last.c 2004-07-30 05:16:26.000000000 -0700
601 +++ sysvinit-2.86/src/last.c 2009-01-07 11:18:38.000000000 -0800
602 @@ -307,14 +307,15 @@
605 unsigned int topnibble;
606 + unsigned int azero = 0, sitelocal = 0;
609 flags = useip ? NI_NUMERICHOST : 0;
612 * IPv4 or IPv6 ? We use 2 heuristics:
613 - * 1. Current IPv6 range uses 2000-3fff. Outside of
614 - * that is illegal and must be IPv4.
615 + * 1. Current IPv6 range uses 2000-3fff or fec0-feff.
616 + * Outside of that is illegal and must be IPv4.
617 * 2. If last 3 bytes are 0, must be IPv4
618 * 3. If IPv6 in IPv4, handle as IPv4
621 if (a[0] == 0 && a[1] == 0 && a[2] == htonl (0xffff))
623 topnibble = ntohl((unsigned int)a[0]) >> 28;
624 - if (topnibble < 2 || topnibble > 3 || mapped ||
626 + azero = ntohl((unsigned int)a[0]) >> 16;
627 + sitelocal = (azero >= 0xfec0 && azero <= 0xfeff) ? 1 : 0;
629 + if (((topnibble < 2 || topnibble > 3) && (!sitelocal)) || mapped ||
630 (a[1] == 0 && a[2] == 0 && a[3] == 0)) {
632 sin.sin_family = AF_INET;
633 diff -Naur sysvinit-2.86.orig/src/reboot.h sysvinit-2.86/src/reboot.h
634 --- sysvinit-2.86.orig/src/reboot.h 2004-06-09 05:47:45.000000000 -0700
635 +++ sysvinit-2.86/src/reboot.h 2009-01-07 11:07:06.000000000 -0800
637 # define BMAGIC_POWEROFF BMAGIC_HALT
640 +/* for kexec support */
641 +#define BMAGIC_KEXEC 0x45584543
643 #define init_reboot(magic) reboot(magic)
645 diff -Naur sysvinit-2.86.orig/src/shutdown.c sysvinit-2.86/src/shutdown.c
646 --- sysvinit-2.86.orig/src/shutdown.c 2004-07-30 04:59:04.000000000 -0700
647 +++ sysvinit-2.86/src/shutdown.c 2009-01-07 11:09:43.000000000 -0800
652 - "Usage:\t shutdown [-akrhHPfnc] [-t secs] time [warning message]\n"
653 + "Usage:\t shutdown [-akrhPHfFnc] [-t sec] time [warning message]\n"
654 "\t\t -a: use /etc/shutdown.allow\n"
655 "\t\t -k: don't really shutdown, only warn.\n"
656 "\t\t -r: reboot after shutdown.\n"
660 fprintf(stderr, "shutdown: you must be root to do that!\n");
664 strcpy(down_level, "1");
665 diff -Naur sysvinit-2.86.orig/src/utmp.c sysvinit-2.86/src/utmp.c
666 --- sysvinit-2.86.orig/src/utmp.c 1999-06-09 04:11:33.000000000 -0700
667 +++ sysvinit-2.86/src/utmp.c 2009-01-07 11:11:29.000000000 -0800
671 struct utsname uname_buf;
675 * Try to open the wtmp file. Note that we even try
678 memset(&utmp, 0, sizeof(utmp));
679 #if defined(__GLIBC__)
680 - gettimeofday(&utmp.ut_tv, NULL);
681 + gettimeofday(&tv, NULL);
682 + utmp.ut_tv.tv_sec = tv.tv_sec;
683 + utmp.ut_tv.tv_usec = tv.tv_usec;
694 * Can't do much if UTMP_FILE is not present.
697 strncpy(utmp.ut_id, id, sizeof(utmp.ut_id));
698 #if defined(__GLIBC__)
699 - gettimeofday(&utmp.ut_tv, NULL);
700 + gettimeofday(&tv, NULL);
701 + utmp.ut_tv.tv_sec = tv.tv_sec;
702 + utmp.ut_tv.tv_usec = tv.tv_usec;