tags 181756 patch thanks Even though this is not mentioned anywhere in the bug report, I assume this bug is about bootlogd (since init itself doesn't produce any particularly interesting boot messages). If so, the following patch should fix the bug by implementing multiple console support in bootlogd. With this patch, bootlogd will send its output to up to 16 consoles specified on the kernel command line using console=...
Please note that I've tested this patch only with the sarge version of sysvinit (2.86.ds1-1), but it applied cleanly to 2.86.ds1-33 as well, so I don't see a reason why it shouldn't work there. Martin --- sysvinit-2.86.ds1/src/bootlogd.c.orig 2004-06-09 14:47:45.000000000 +0200 +++ sysvinit-2.86.ds1/src/bootlogd.c 2006-10-30 17:30:50.000000000 +0100 @@ -48,6 +48,7 @@ char *Version = "@(#) bootlogd 2.86 03-Jun-2004 [EMAIL PROTECTED]"; #define LOGFILE "/var/log/boot" +#define MAX_CONSOLES 16 char ringbuf[32768]; char *endptr = ringbuf + sizeof(ringbuf); @@ -62,6 +63,11 @@ int pos; } line; +struct real_cons { + char name[1024]; + int fd; +}; + /* * Console devices as listed on the kernel command line and * the mapping to actual devices in /dev @@ -204,10 +210,10 @@ } /* - * Find out the _real_ console. Assume that stdin is connected to + * Find out the _real_ console(s). Assume that stdin is connected to * the console device (/dev/console). */ -int consolename(char *res, int rlen) +int consolenames(struct real_cons *cons, int max_consoles) { #ifdef TIOCGDEV unsigned int kdev; @@ -216,21 +222,25 @@ char buf[256]; char *p; int didmount = 0; - int n, r; + int n; int fd; + int considx, num_consoles = 0; fstat(0, &st); if (major(st.st_rdev) != 5 || minor(st.st_rdev) != 1) { /* * Old kernel, can find real device easily. */ - return findtty(res, rlen, st.st_rdev); + cons[0].fd = findtty(cons[0].name, sizeof(cons[0].name), st.st_rdev); + return (cons[0].fd >= 0) ? 1 : 0; } #ifdef TIOCGDEV - if (ioctl(0, TIOCGDEV, &kdev) == 0) - return findtty(res, rlen, (dev_t)kdev); - if (errno != ENOIOCTLCMD) return -1; + if (ioctl(0, TIOCGDEV, &kdev) == 0) { + cons[0].fd = findtty(cons[0].name, sizeof(cons[0].name), (dev_t)kdev); + return (cons[0].fd >= 0) ? 1 : 0; + } + if (errno != ENOIOCTLCMD) return 0; #endif #ifdef __linux__ @@ -240,31 +250,28 @@ stat("/", &st); if (stat("/proc", &st2) < 0) { perror("bootlogd: /proc"); - return -1; + return 0; } if (st.st_dev == st2.st_dev) { if (mount("proc", "/proc", "proc", 0, NULL) < 0) { perror("bootlogd: mount /proc"); - return -1; + return 0; } didmount = 1; } - n = 0; - r = -1; + n = -1; if ((fd = open("/proc/cmdline", O_RDONLY)) < 0) { perror("bootlogd: /proc/cmdline"); } else { buf[0] = 0; - if ((n = read(fd, buf, sizeof(buf) - 1)) >= 0) - r = 0; - else + if ((n = read(fd, buf, sizeof(buf) - 1)) < 0) perror("bootlogd: /proc/cmdline"); close(fd); } if (didmount) umount("/proc"); - if (r < 0) return r; + if (n < 0) return 0; /* * OK, so find console= in /proc/cmdline. @@ -274,21 +281,32 @@ */ p = buf + n; *p-- = 0; - r = -1; while (p >= buf) { if (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') { *p-- = 0; continue; } if (strncmp(p, "console=", 8) == 0 && - isconsole(p + 8, res, rlen)) { - r = 0; - break; + isconsole(p + 8, cons[num_consoles].name, sizeof(cons[num_consoles].name))) { + /* + * Suppress duplicates + */ + for (considx = 0; considx < num_consoles; considx++) { + if (!strcmp(cons[num_consoles].name, cons[considx].name)) { + goto dontuse; + } + } + + num_consoles++; + if (num_consoles >= max_consoles) { + break; + } } +dontuse: p--; } - if (r == 0) return r; + if (num_consoles > 0) return num_consoles; #endif /* @@ -296,12 +314,13 @@ * guess the default console. */ for (n = 0; defcons[n]; n++) - if (isconsole(defcons[n], res, rlen)) - return 0; + if (isconsole(defcons[n], cons[0].name, sizeof(cons[0].name))) { + return 1; + } fprintf(stderr, "bootlogd: cannot deduce real console device\n"); - return -1; + return 0; } @@ -429,16 +448,17 @@ struct timeval tv; fd_set fds; char buf[1024]; - char realcons[1024]; char *p; char *logfile; char *pidfile; int rotate; int dontfork; int ptm, pts; - int realfd; int n, m, i; int todo; + int considx; + struct real_cons cons[MAX_CONSOLES]; + int num_consoles, consoles_left; fp = NULL; logfile = LOGFILE; @@ -479,18 +499,23 @@ /* * Open console device directly. */ - if (consolename(realcons, sizeof(realcons)) < 0) + if ((num_consoles = consolenames(cons, MAX_CONSOLES)) <= 0) return 1; - if (strcmp(realcons, "/dev/tty0") == 0) - strcpy(realcons, "/dev/tty1"); - if (strcmp(realcons, "/dev/vc/0") == 0) - strcpy(realcons, "/dev/vc/1"); - - if ((realfd = open_nb(realcons)) < 0) { - fprintf(stderr, "bootlogd: %s: %s\n", buf, strerror(errno)); - return 1; + consoles_left = num_consoles; + for (considx = 0; considx < num_consoles; considx++) { + if (strcmp(cons[considx].name, "/dev/tty0") == 0) + strcpy(cons[considx].name, "/dev/tty1"); + if (strcmp(cons[considx].name, "/dev/vc/0") == 0) + strcpy(cons[considx].name, "/dev/vc/1"); + + if ((cons[considx].fd = open_nb(cons[considx].name)) < 0) { + fprintf(stderr, "bootlogd: %s: %s\n", cons[considx].name, strerror(errno)); + consoles_left--; + } } + if (!consoles_left) + return 1; /* * Grab a pty, and redirect console messages to it. @@ -558,26 +583,34 @@ if ((n = read(ptm, inptr, endptr - inptr)) >= 0) { /* * Write data (in chunks if needed) - * to the real output device. + * to the real output devices. */ - m = n; - p = inptr; - while (m > 0) { - i = write(realfd, p, m); - if (i >= 0) { - m -= i; - p += i; - continue; + for (considx = 0; considx < num_consoles; considx++) { + if (cons[considx].fd < 0) continue; + m = n; + p = inptr; + while (m > 0) { + i = write(cons[considx].fd, p, m); + if (i >= 0) { + m -= i; + p += i; + continue; + } + /* + * Handle EIO (somebody hung + * up our filedescriptor) + */ + cons[considx].fd = write_err(pts, + cons[considx].fd, + cons[considx].name, errno); + if (cons[considx].fd >= 0) continue; + /* + * If this was the last console, + * generate a fake signal + */ + if (--consoles_left <= 0) got_signal = 1; + break; } - /* - * Handle EIO (somebody hung - * up our filedescriptor) - */ - realfd = write_err(pts, realfd, - realcons, errno); - if (realfd >= 0) continue; - got_signal = 1; /* Not really */ - break; } /* @@ -619,7 +652,9 @@ close(pts); close(ptm); - close(realfd); + for (considx = 0; considx < num_consoles; considx++) { + close(cons[considx].fd); + } return 0; } -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]