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