Codebase list sysvinit / a4f7bab
Add patch to log on multiple consoles (Closes: #181756). Thomas Goirand 9 years ago
3 changed file(s) with 298 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
2222 sysvinit-core. Closes: #751589.
2323 * Confirm SRU fixing circular dependency of mountnfs ifupdown hook when
2424 running with systemd. Closes: #746587.
25
26 [ Thomas Goirand ]
27 * Add patch to log on multiple consoles (Closes: #181756).
2528
2629 -- Dimitri John Ledkov <xnox@ubuntu.com> Tue, 22 Apr 2014 14:41:18 +0100
2730
0 Description: Allow multiple console output
1 When booting a kernel with multiple serial console support, or multuiple
2 console arguments ala "console=tty1 console=ttyS0,9600" the kernel will output
3 messages to all consoles, init however will not. It will only send output to,
4 and accept input from, the last of the consoles.
5 .
6 This patch fixes it.
7 Author: Martin Buck <m@rtin-buck.de>
8 Origin: other, https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=181756
9 Bug-Debian: https://bugs.debian.org/181756
10 Forwarded: no
11 Last-Update: 2014-07-20
12
13 Index: sysvinit-2.88dsf/src/bootlogd.c
14 ===================================================================
15 --- sysvinit-2.88dsf.orig/src/bootlogd.c 2010-03-23 15:37:01.000000000 +0100
16 +++ sysvinit-2.88dsf/src/bootlogd.c 2013-07-15 09:56:55.953975300 +0200
17 @@ -57,6 +57,7 @@
18 char *Version = "@(#) bootlogd 2.86 03-Jun-2004 miquels@cistron.nl";
19
20 #define LOGFILE "/var/log/boot"
21 +#define MAX_CONSOLES 16
22
23 char ringbuf[32768];
24 char *endptr = ringbuf + sizeof(ringbuf);
25 @@ -73,6 +74,11 @@
26 int pos;
27 } line;
28
29 +struct real_cons {
30 + char name[1024];
31 + int fd;
32 +};
33 +
34 /*
35 * Console devices as listed on the kernel command line and
36 * the mapping to actual devices in /dev
37 @@ -235,10 +241,10 @@
38 }
39
40 /*
41 - * Find out the _real_ console. Assume that stdin is connected to
42 + * Find out the _real_ console(s). Assume that stdin is connected to
43 * the console device (/dev/console).
44 */
45 -int consolename(char *res, int rlen)
46 +int consolenames(struct real_cons *cons, int max_consoles)
47 {
48 #ifdef TIOCGDEV
49 unsigned int kdev;
50 @@ -247,34 +253,9 @@
51 char buf[256];
52 char *p;
53 int didmount = 0;
54 - int n, r;
55 + int n;
56 int fd;
57 -
58 - fstat(0, &st);
59 - if (major(st.st_rdev) != 5 || minor(st.st_rdev) != 1) {
60 - /*
61 - * Old kernel, can find real device easily.
62 - */
63 - int r = findtty(res, "/dev", rlen, st.st_rdev);
64 - if (0 != r)
65 - fprintf(stderr, "bootlogd: cannot find console device "
66 - "%d:%d under /dev\n", major(st.st_rdev), minor(st.st_rdev));
67 - return r;
68 - }
69 -
70 -#ifdef TIOCGDEV
71 -# ifndef ENOIOCTLCMD
72 -# define ENOIOCTLCMD 515
73 -# endif
74 - if (ioctl(0, TIOCGDEV, &kdev) == 0) {
75 - int r = findtty(res, "/dev", rlen, (dev_t)kdev);
76 - if (0 != r)
77 - fprintf(stderr, "bootlogd: cannot find console device "
78 - "%d:%d under /dev\n", major(kdev), minor(kdev));
79 - return r;
80 - }
81 - if (errno != ENOIOCTLCMD) return -1;
82 -#endif
83 + int considx, num_consoles = 0;
84
85 #ifdef __linux__
86 /*
87 @@ -283,7 +264,7 @@
88 stat("/", &st);
89 if (stat("/proc", &st2) < 0) {
90 perror("bootlogd: /proc");
91 - return -1;
92 + return 0;
93 }
94 if (st.st_dev == st2.st_dev) {
95 if (mount("proc", "/proc", "proc", 0, NULL) < 0) {
96 @@ -293,21 +274,21 @@
97 didmount = 1;
98 }
99
100 - n = 0;
101 - r = -1;
102 + n = -1;
103 if ((fd = open("/proc/cmdline", O_RDONLY)) < 0) {
104 perror("bootlogd: /proc/cmdline");
105 } else {
106 buf[0] = 0;
107 - if ((n = read(fd, buf, sizeof(buf) - 1)) >= 0)
108 - r = 0;
109 - else
110 + if ((n = read(fd, buf, sizeof(buf) - 1)) < 0)
111 perror("bootlogd: /proc/cmdline");
112 close(fd);
113 }
114 if (didmount) umount("/proc");
115 +
116 +
117 + if (n < 0) return 0;
118 +
119
120 - if (r < 0) return r;
121
122 /*
123 * OK, so find console= in /proc/cmdline.
124 @@ -315,21 +296,32 @@
125 */
126 p = buf + n;
127 *p-- = 0;
128 - r = -1;
129 while (p >= buf) {
130 if (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') {
131 *p-- = 0;
132 continue;
133 }
134 if (strncmp(p, "console=", 8) == 0 &&
135 - isconsole(p + 8, res, rlen)) {
136 - r = 0;
137 - break;
138 + isconsole(p + 8, cons[num_consoles].name, sizeof(cons[num_consoles].name))) {
139 + /*
140 + * Suppress duplicates
141 + */
142 + for (considx = 0; considx < num_consoles; considx++) {
143 + if (!strcmp(cons[num_consoles].name, cons[considx].name)) {
144 + goto dontuse;
145 + }
146 + }
147 +
148 + num_consoles++;
149 + if (num_consoles >= max_consoles) {
150 + break;
151 + }
152 }
153 +dontuse:
154 p--;
155 }
156
157 - if (r == 0) return r;
158 + if (num_consoles > 0) return num_consoles;
159 #endif
160
161 /*
162 @@ -337,12 +329,12 @@
163 * guess the default console.
164 */
165 for (n = 0; defcons[n]; n++)
166 - if (isconsole(defcons[n], res, rlen))
167 - return 0;
168 + if (isconsole(defcons[n], cons[0].name, sizeof(cons[0].name)))
169 + return 1;
170
171 fprintf(stderr, "bootlogd: cannot deduce real console device\n");
172
173 - return -1;
174 + return 0;
175 }
176
177
178 @@ -472,7 +464,6 @@
179 struct timeval tv;
180 fd_set fds;
181 char buf[1024];
182 - char realcons[1024];
183 char *p;
184 char *logfile;
185 char *pidfile;
186 @@ -485,6 +476,9 @@
187 #ifndef __linux__ /* BSD-style ioctl needs an argument. */
188 int on = 1;
189 #endif
190 + int considx;
191 + struct real_cons cons[MAX_CONSOLES];
192 + int num_consoles, consoles_left;
193
194 fp = NULL;
195 logfile = LOGFILE;
196 @@ -531,18 +525,22 @@
197 /*
198 * Open console device directly.
199 */
200 - if (consolename(realcons, sizeof(realcons)) < 0)
201 - return 1;
202 -
203 - if (strcmp(realcons, "/dev/tty0") == 0)
204 - strcpy(realcons, "/dev/tty1");
205 - if (strcmp(realcons, "/dev/vc/0") == 0)
206 - strcpy(realcons, "/dev/vc/1");
207 -
208 - if ((realfd = open_nb(realcons)) < 0) {
209 - fprintf(stderr, "bootlogd: %s: %s\n", buf, strerror(errno));
210 + if ((num_consoles = consolenames(cons, MAX_CONSOLES)) <= 0)
211 return 1;
212 + consoles_left = num_consoles;
213 + for (considx = 0; considx < num_consoles; considx++) {
214 + if (strcmp(cons[considx].name, "/dev/tty0") == 0)
215 + strcpy(cons[considx].name, "/dev/tty1");
216 + if (strcmp(cons[considx].name, "/dev/vc/0") == 0)
217 + strcpy(cons[considx].name, "/dev/vc/1");
218 +
219 + if ((cons[considx].fd = open_nb(cons[considx].name)) < 0) {
220 + fprintf(stderr, "bootlogd: %s: %s\n", cons[considx].name, strerror(errno));
221 + consoles_left--;
222 + }
223 }
224 + if (!consoles_left)
225 + return 1;
226
227 /*
228 * Grab a pty, and redirect console messages to it.
229 @@ -626,26 +624,34 @@
230 if ((n = read(ptm, inptr, endptr - inptr)) >= 0) {
231 /*
232 * Write data (in chunks if needed)
233 - * to the real output device.
234 + * to the real output devices.
235 */
236 - m = n;
237 - p = inptr;
238 - while (m > 0) {
239 - i = write(realfd, p, m);
240 - if (i >= 0) {
241 - m -= i;
242 - p += i;
243 - continue;
244 - }
245 - /*
246 - * Handle EIO (somebody hung
247 - * up our filedescriptor)
248 - */
249 - realfd = write_err(pts, realfd,
250 - realcons, errno);
251 - if (realfd >= 0) continue;
252 - got_signal = 1; /* Not really */
253 - break;
254 + for (considx = 0; considx < num_consoles; considx++) {
255 + if (cons[considx].fd < 0) continue;
256 + m = n;
257 + p = inptr;
258 + while (m > 0) {
259 + i = write(cons[considx].fd, p, m);
260 + if (i >= 0) {
261 + m -= i;
262 + p += i;
263 + continue;
264 + }
265 + /*
266 + * Handle EIO (somebody hung
267 + * up our filedescriptor)
268 + */
269 + cons[considx].fd = write_err(pts,
270 + cons[considx].fd,
271 + cons[considx].name, errno);
272 + if (cons[considx].fd >= 0) continue;
273 + /*
274 + * If this was the last console,
275 + * generate a fake signal
276 + */
277 + if (--consoles_left <= 0) got_signal = 1;
278 + break;
279 + }
280 }
281
282 /*
283 @@ -691,7 +697,9 @@
284
285 close(pts);
286 close(ptm);
287 - close(realfd);
288 + for (considx = 0; considx < num_consoles; considx++) {
289 + close(cons[considx].fd);
290 + }
291
292 return 0;
293 }
1414 93_run_initctl.patch
1515 94_kfreebsd_xterm.patch
1616 95_kfreebsd_bootlogd.patch
17 96_allow_multiple_console_output.patch