aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/os-Linux/start_up.c
diff options
context:
space:
mode:
authorJeff Dike <jdike@addtoit.com>2007-02-10 04:44:28 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-11 13:51:24 -0500
commit3a150e1da8bc4e840d5a09fc089052011b5b6503 (patch)
tree2c0471fa0e30e89b7d47026877ae618e50b84477 /arch/um/os-Linux/start_up.c
parent9683da91e2db323ee728041576e29ad7fa9547b9 (diff)
[PATCH] uml: fix error output during early boot
The startup code panics a lot if anything goes wrong early on. This is wrong for several reasons, like the kernel isn't running, so you can't really be calling into it yet, but the harm comes from useful error messages being trapped in the printk ring where no one will ever see them. This patch changes these panics to perror and printf in wrappers which also exit. Normal, informational, prints are also wrapped so that fflush(stdout) is called after each one. This is so the output appears in the correct sequence in the event of an error. Signed-off-by: Jeff Dike <jdike@addtoit.com> Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/um/os-Linux/start_up.c')
-rw-r--r--arch/um/os-Linux/start_up.c154
1 files changed, 92 insertions, 62 deletions
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 735d035a7f33..5178eba9afa5 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -73,6 +73,34 @@ static int ptrace_child(void *arg)
73 _exit(ret); 73 _exit(ret);
74} 74}
75 75
76static void fatal_perror(char *str)
77{
78 perror(str);
79 exit(1);
80}
81
82static void fatal(char *fmt, ...)
83{
84 va_list list;
85
86 va_start(list, fmt);
87 vprintf(fmt, list);
88 va_end(list);
89 fflush(stdout);
90
91 exit(1);
92}
93
94static void non_fatal(char *fmt, ...)
95{
96 va_list list;
97
98 va_start(list, fmt);
99 vprintf(fmt, list);
100 va_end(list);
101 fflush(stdout);
102}
103
76static int start_ptraced_child(void **stack_out) 104static int start_ptraced_child(void **stack_out)
77{ 105{
78 void *stack; 106 void *stack;
@@ -82,16 +110,16 @@ static int start_ptraced_child(void **stack_out)
82 stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, 110 stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
83 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 111 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
84 if(stack == MAP_FAILED) 112 if(stack == MAP_FAILED)
85 panic("check_ptrace : mmap failed, errno = %d", errno); 113 fatal_perror("check_ptrace : mmap failed");
86 sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *); 114 sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
87 pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL); 115 pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL);
88 if(pid < 0) 116 if(pid < 0)
89 panic("start_ptraced_child : clone failed, errno = %d", errno); 117 fatal_perror("start_ptraced_child : clone failed");
90 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); 118 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
91 if(n < 0) 119 if(n < 0)
92 panic("check_ptrace : clone failed, errno = %d", errno); 120 fatal_perror("check_ptrace : clone failed");
93 if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) 121 if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
94 panic("check_ptrace : expected SIGSTOP, got status = %d", 122 fatal("check_ptrace : expected SIGSTOP, got status = %d",
95 status); 123 status);
96 124
97 *stack_out = stack; 125 *stack_out = stack;
@@ -105,31 +133,30 @@ static int start_ptraced_child(void **stack_out)
105 * must work anyway! 133 * must work anyway!
106 */ 134 */
107static int stop_ptraced_child(int pid, void *stack, int exitcode, 135static int stop_ptraced_child(int pid, void *stack, int exitcode,
108 int mustpanic) 136 int mustexit)
109{ 137{
110 int status, n, ret = 0; 138 int status, n, ret = 0;
111 139
112 if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) 140 if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
113 panic("check_ptrace : ptrace failed, errno = %d", errno); 141 fatal_perror("stop_ptraced_child : ptrace failed");
114 CATCH_EINTR(n = waitpid(pid, &status, 0)); 142 CATCH_EINTR(n = waitpid(pid, &status, 0));
115 if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { 143 if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) {
116 int exit_with = WEXITSTATUS(status); 144 int exit_with = WEXITSTATUS(status);
117 if (exit_with == 2) 145 if (exit_with == 2)
118 printf("check_ptrace : child exited with status 2. " 146 non_fatal("check_ptrace : child exited with status 2. "
119 "Serious trouble happening! Try updating your " 147 "Serious trouble happening! Try updating "
120 "host skas patch!\nDisabling SYSEMU support."); 148 "your host skas patch!\nDisabling SYSEMU "
121 printf("check_ptrace : child exited with exitcode %d, while " 149 "support.");
122 "expecting %d; status 0x%x", exit_with, 150 non_fatal("check_ptrace : child exited with exitcode %d, while "
123 exitcode, status); 151 "expecting %d; status 0x%x\n", exit_with,
124 if (mustpanic) 152 exitcode, status);
125 panic("\n"); 153 if (mustexit)
126 else 154 exit(1);
127 printf("\n");
128 ret = -1; 155 ret = -1;
129 } 156 }
130 157
131 if(munmap(stack, PAGE_SIZE) < 0) 158 if(munmap(stack, PAGE_SIZE) < 0)
132 panic("check_ptrace : munmap failed, errno = %d", errno); 159 fatal_perror("check_ptrace : munmap failed");
133 return ret; 160 return ret;
134} 161}
135 162
@@ -184,7 +211,7 @@ static void __init check_sysemu(void)
184 void *stack; 211 void *stack;
185 int pid, n, status, count=0; 212 int pid, n, status, count=0;
186 213
187 printf("Checking syscall emulation patch for ptrace..."); 214 non_fatal("Checking syscall emulation patch for ptrace...");
188 sysemu_supported = 0; 215 sysemu_supported = 0;
189 pid = start_ptraced_child(&stack); 216 pid = start_ptraced_child(&stack);
190 217
@@ -193,31 +220,30 @@ static void __init check_sysemu(void)
193 220
194 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); 221 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
195 if (n < 0) 222 if (n < 0)
196 panic("check_sysemu : wait failed, errno = %d", errno); 223 fatal_perror("check_sysemu : wait failed");
197 if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) 224 if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
198 panic("check_sysemu : expected SIGTRAP, " 225 fatal("check_sysemu : expected SIGTRAP, got status = %d",
199 "got status = %d", status); 226 status);
200 227
201 n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, 228 n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET,
202 os_getpid()); 229 os_getpid());
203 if(n < 0) 230 if(n < 0)
204 panic("check_sysemu : failed to modify system " 231 fatal_perror("check_sysemu : failed to modify system call "
205 "call return, errno = %d", errno); 232 "return");
206 233
207 if (stop_ptraced_child(pid, stack, 0, 0) < 0) 234 if (stop_ptraced_child(pid, stack, 0, 0) < 0)
208 goto fail_stopped; 235 goto fail_stopped;
209 236
210 sysemu_supported = 1; 237 sysemu_supported = 1;
211 printf("OK\n"); 238 non_fatal("OK\n");
212 set_using_sysemu(!force_sysemu_disabled); 239 set_using_sysemu(!force_sysemu_disabled);
213 240
214 printf("Checking advanced syscall emulation patch for ptrace..."); 241 non_fatal("Checking advanced syscall emulation patch for ptrace...");
215 pid = start_ptraced_child(&stack); 242 pid = start_ptraced_child(&stack);
216 243
217 if(ptrace(PTRACE_OLDSETOPTIONS, pid, 0, 244 if((ptrace(PTRACE_OLDSETOPTIONS, pid, 0,
218 (void *) PTRACE_O_TRACESYSGOOD) < 0) 245 (void *) PTRACE_O_TRACESYSGOOD) < 0))
219 panic("check_ptrace: PTRACE_OLDSETOPTIONS failed, errno = %d", 246 fatal_perror("check_ptrace: PTRACE_OLDSETOPTIONS failed");
220 errno);
221 247
222 while(1){ 248 while(1){
223 count++; 249 count++;
@@ -225,29 +251,30 @@ static void __init check_sysemu(void)
225 goto fail; 251 goto fail;
226 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); 252 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
227 if(n < 0) 253 if(n < 0)
228 panic("check_ptrace : wait failed, errno = %d", errno); 254 fatal_perror("check_ptrace : wait failed");
255
229 if(WIFSTOPPED(status) && (WSTOPSIG(status) == (SIGTRAP|0x80))){ 256 if(WIFSTOPPED(status) && (WSTOPSIG(status) == (SIGTRAP|0x80))){
230 if (!count) 257 if (!count)
231 panic("check_ptrace : SYSEMU_SINGLESTEP " 258 fatal("check_ptrace : SYSEMU_SINGLESTEP "
232 "doesn't singlestep"); 259 "doesn't singlestep");
233 n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, 260 n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET,
234 os_getpid()); 261 os_getpid());
235 if(n < 0) 262 if(n < 0)
236 panic("check_sysemu : failed to modify system " 263 fatal_perror("check_sysemu : failed to modify "
237 "call return, errno = %d", errno); 264 "system call return");
238 break; 265 break;
239 } 266 }
240 else if(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP)) 267 else if(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP))
241 count++; 268 count++;
242 else 269 else
243 panic("check_ptrace : expected SIGTRAP or " 270 fatal("check_ptrace : expected SIGTRAP or "
244 "(SIGTRAP|0x80), got status = %d", status); 271 "(SIGTRAP | 0x80), got status = %d", status);
245 } 272 }
246 if (stop_ptraced_child(pid, stack, 0, 0) < 0) 273 if (stop_ptraced_child(pid, stack, 0, 0) < 0)
247 goto fail_stopped; 274 goto fail_stopped;
248 275
249 sysemu_supported = 2; 276 sysemu_supported = 2;
250 printf("OK\n"); 277 non_fatal("OK\n");
251 278
252 if ( !force_sysemu_disabled ) 279 if ( !force_sysemu_disabled )
253 set_using_sysemu(sysemu_supported); 280 set_using_sysemu(sysemu_supported);
@@ -256,7 +283,7 @@ static void __init check_sysemu(void)
256fail: 283fail:
257 stop_ptraced_child(pid, stack, 1, 0); 284 stop_ptraced_child(pid, stack, 1, 0);
258fail_stopped: 285fail_stopped:
259 printf("missing\n"); 286 non_fatal("missing\n");
260} 287}
261 288
262static void __init check_ptrace(void) 289static void __init check_ptrace(void)
@@ -264,22 +291,25 @@ static void __init check_ptrace(void)
264 void *stack; 291 void *stack;
265 int pid, syscall, n, status; 292 int pid, syscall, n, status;
266 293
267 printf("Checking that ptrace can change system call numbers..."); 294 non_fatal("Checking that ptrace can change system call numbers...");
268 pid = start_ptraced_child(&stack); 295 pid = start_ptraced_child(&stack);
269 296
270 if(ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) 297 if((ptrace(PTRACE_OLDSETOPTIONS, pid, 0,
271 panic("check_ptrace: PTRACE_OLDSETOPTIONS failed, errno = %d", errno); 298 (void *) PTRACE_O_TRACESYSGOOD) < 0))
299 fatal_perror("check_ptrace: PTRACE_OLDSETOPTIONS failed");
272 300
273 while(1){ 301 while(1){
274 if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) 302 if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
275 panic("check_ptrace : ptrace failed, errno = %d", 303 fatal_perror("check_ptrace : ptrace failed");
276 errno); 304
277 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); 305 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
278 if(n < 0) 306 if(n < 0)
279 panic("check_ptrace : wait failed, errno = %d", errno); 307 fatal_perror("check_ptrace : wait failed");
280 if(!WIFSTOPPED(status) || (WSTOPSIG(status) != (SIGTRAP|0x80))) 308
281 panic("check_ptrace : expected (SIGTRAP|0x80), " 309 if(!WIFSTOPPED(status) ||
282 "got status = %d", status); 310 (WSTOPSIG(status) != (SIGTRAP | 0x80)))
311 fatal("check_ptrace : expected (SIGTRAP|0x80), "
312 "got status = %d", status);
283 313
284 syscall = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_NR_OFFSET, 314 syscall = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_NR_OFFSET,
285 0); 315 0);
@@ -287,13 +317,13 @@ static void __init check_ptrace(void)
287 n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET, 317 n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET,
288 __NR_getppid); 318 __NR_getppid);
289 if(n < 0) 319 if(n < 0)
290 panic("check_ptrace : failed to modify system " 320 fatal_perror("check_ptrace : failed to modify "
291 "call, errno = %d", errno); 321 "system call");
292 break; 322 break;
293 } 323 }
294 } 324 }
295 stop_ptraced_child(pid, stack, 0, 1); 325 stop_ptraced_child(pid, stack, 0, 1);
296 printf("OK\n"); 326 non_fatal("OK\n");
297 check_sysemu(); 327 check_sysemu();
298} 328}
299 329
@@ -352,22 +382,22 @@ static inline void check_skas3_ptrace_faultinfo(void)
352 void *stack; 382 void *stack;
353 int pid, n; 383 int pid, n;
354 384
355 printf(" - PTRACE_FAULTINFO..."); 385 non_fatal(" - PTRACE_FAULTINFO...");
356 pid = start_ptraced_child(&stack); 386 pid = start_ptraced_child(&stack);
357 387
358 n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi); 388 n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
359 if (n < 0) { 389 if (n < 0) {
360 ptrace_faultinfo = 0; 390 ptrace_faultinfo = 0;
361 if(errno == EIO) 391 if(errno == EIO)
362 printf("not found\n"); 392 non_fatal("not found\n");
363 else 393 else
364 perror("not found"); 394 perror("not found");
365 } 395 }
366 else { 396 else {
367 if (!ptrace_faultinfo) 397 if (!ptrace_faultinfo)
368 printf("found but disabled on command line\n"); 398 non_fatal("found but disabled on command line\n");
369 else 399 else
370 printf("found\n"); 400 non_fatal("found\n");
371 } 401 }
372 402
373 init_registers(pid); 403 init_registers(pid);
@@ -385,13 +415,13 @@ static inline void check_skas3_ptrace_ldt(void)
385 .ptr = ldtbuf, 415 .ptr = ldtbuf,
386 .bytecount = sizeof(ldtbuf)}; 416 .bytecount = sizeof(ldtbuf)};
387 417
388 printf(" - PTRACE_LDT..."); 418 non_fatal(" - PTRACE_LDT...");
389 pid = start_ptraced_child(&stack); 419 pid = start_ptraced_child(&stack);
390 420
391 n = ptrace(PTRACE_LDT, pid, 0, (unsigned long) &ldt_op); 421 n = ptrace(PTRACE_LDT, pid, 0, (unsigned long) &ldt_op);
392 if (n < 0) { 422 if (n < 0) {
393 if(errno == EIO) 423 if(errno == EIO)
394 printf("not found\n"); 424 non_fatal("not found\n");
395 else { 425 else {
396 perror("not found"); 426 perror("not found");
397 } 427 }
@@ -399,9 +429,9 @@ static inline void check_skas3_ptrace_ldt(void)
399 } 429 }
400 else { 430 else {
401 if(ptrace_ldt) 431 if(ptrace_ldt)
402 printf("found\n"); 432 non_fatal("found\n");
403 else 433 else
404 printf("found, but use is disabled\n"); 434 non_fatal("found, but use is disabled\n");
405 } 435 }
406 436
407 stop_ptraced_child(pid, stack, 1, 1); 437 stop_ptraced_child(pid, stack, 1, 1);
@@ -416,22 +446,22 @@ static inline void check_skas3_ptrace_ldt(void)
416 446
417static inline void check_skas3_proc_mm(void) 447static inline void check_skas3_proc_mm(void)
418{ 448{
419 printf(" - /proc/mm..."); 449 non_fatal(" - /proc/mm...");
420 if (access("/proc/mm", W_OK) < 0) { 450 if (access("/proc/mm", W_OK) < 0) {
421 proc_mm = 0; 451 proc_mm = 0;
422 printf("not found\n"); 452 perror("not found");
423 } 453 }
424 else { 454 else {
425 if (!proc_mm) 455 if (!proc_mm)
426 printf("found but disabled on command line\n"); 456 non_fatal("found but disabled on command line\n");
427 else 457 else
428 printf("found\n"); 458 non_fatal("found\n");
429 } 459 }
430} 460}
431 461
432int can_do_skas(void) 462int can_do_skas(void)
433{ 463{
434 printf("Checking for the skas3 patch in the host:\n"); 464 non_fatal("Checking for the skas3 patch in the host:\n");
435 465
436 check_skas3_proc_mm(); 466 check_skas3_proc_mm();
437 check_skas3_ptrace_faultinfo(); 467 check_skas3_ptrace_faultinfo();