--- /dev/null
+Description: Allow multiple console output
+ When booting a kernel with multiple serial console support, or multuiple
+ console arguments ala "console=tty1 console=ttyS0,9600" the kernel will output
+ messages to all consoles, init however will not. It will only send output to,
+ and accept input from, the last of the consoles.
+ .
+ This patch fixes it.
+Author: Martin Buck <m@rtin-buck.de>
+Origin: other, https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=181756
+Bug-Debian: https://bugs.debian.org/181756
+Forwarded: no
+Last-Update: 2014-07-20
+
+Index: sysvinit-2.88dsf/src/bootlogd.c
+===================================================================
+--- sysvinit-2.88dsf.orig/src/bootlogd.c 2010-03-23 15:37:01.000000000 +0100
++++ sysvinit-2.88dsf/src/bootlogd.c 2013-07-15 09:56:55.953975300 +0200
+@@ -57,6 +57,7 @@
+ char *Version = "@(#) bootlogd 2.86 03-Jun-2004 miquels@cistron.nl";
+
+ #define LOGFILE "/var/log/boot"
++#define MAX_CONSOLES 16
+
+ char ringbuf[32768];
+ char *endptr = ringbuf + sizeof(ringbuf);
+@@ -73,6 +74,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
+@@ -235,10 +241,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;
+@@ -247,34 +253,9 @@
+ char buf[256];
+ char *p;
+ int didmount = 0;
+- int n, r;
++ int n;
+ int fd;
+-
+- fstat(0, &st);
+- if (major(st.st_rdev) != 5 || minor(st.st_rdev) != 1) {
+- /*
+- * Old kernel, can find real device easily.
+- */
+- int r = findtty(res, "/dev", rlen, st.st_rdev);
+- if (0 != r)
+- fprintf(stderr, "bootlogd: cannot find console device "
+- "%d:%d under /dev\n", major(st.st_rdev), minor(st.st_rdev));
+- return r;
+- }
+-
+-#ifdef TIOCGDEV
+-# ifndef ENOIOCTLCMD
+-# define ENOIOCTLCMD 515
+-# endif
+- if (ioctl(0, TIOCGDEV, &kdev) == 0) {
+- int r = findtty(res, "/dev", rlen, (dev_t)kdev);
+- if (0 != r)
+- fprintf(stderr, "bootlogd: cannot find console device "
+- "%d:%d under /dev\n", major(kdev), minor(kdev));
+- return r;
+- }
+- if (errno != ENOIOCTLCMD) return -1;
+-#endif
++ int considx, num_consoles = 0;
+
+ #ifdef __linux__
+ /*
+@@ -283,7 +264,7 @@
+ 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) {
+@@ -293,21 +274,21 @@
+ 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 (n < 0) return 0;
++
+
+- if (r < 0) return r;
+
+ /*
+ * OK, so find console= in /proc/cmdline.
+@@ -315,21 +296,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
+
+ /*
+@@ -337,12 +329,12 @@
+ * 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;
+ }
+
+
+@@ -472,7 +464,6 @@
+ struct timeval tv;
+ fd_set fds;
+ char buf[1024];
+- char realcons[1024];
+ char *p;
+ char *logfile;
+ char *pidfile;
+@@ -485,6 +476,9 @@
+ #ifndef __linux__ /* BSD-style ioctl needs an argument. */
+ int on = 1;
+ #endif
++ int considx;
++ struct real_cons cons[MAX_CONSOLES];
++ int num_consoles, consoles_left;
+
+ fp = NULL;
+ logfile = LOGFILE;
+@@ -531,18 +525,22 @@
+ /*
+ * Open console device directly.
+ */
+- if (consolename(realcons, sizeof(realcons)) < 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));
++ if ((num_consoles = consolenames(cons, MAX_CONSOLES)) <= 0)
+ 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.
+@@ -626,26 +624,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;
+- }
+- /*
+- * Handle EIO (somebody hung
+- * up our filedescriptor)
+- */
+- realfd = write_err(pts, realfd,
+- realcons, errno);
+- if (realfd >= 0) continue;
+- got_signal = 1; /* Not really */
+- break;
++ 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;
++ }
+ }
+
+ /*
+@@ -691,7 +697,9 @@
+
+ close(pts);
+ close(ptm);
+- close(realfd);
++ for (considx = 0; considx < num_consoles; considx++) {
++ close(cons[considx].fd);
++ }
+
+ return 0;
+ }