[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>
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 735d035..5178eba 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -73,6 +73,34 @@
 	_exit(ret);
 }
 
+static void fatal_perror(char *str)
+{
+	perror(str);
+	exit(1);
+}
+
+static void fatal(char *fmt, ...)
+{
+	va_list list;
+
+	va_start(list, fmt);
+	vprintf(fmt, list);
+	va_end(list);
+	fflush(stdout);
+
+	exit(1);
+}
+
+static void non_fatal(char *fmt, ...)
+{
+	va_list list;
+
+	va_start(list, fmt);
+	vprintf(fmt, list);
+	va_end(list);
+	fflush(stdout);
+}
+
 static int start_ptraced_child(void **stack_out)
 {
 	void *stack;
@@ -82,16 +110,16 @@
 	stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
 		     MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
 	if(stack == MAP_FAILED)
-		panic("check_ptrace : mmap failed, errno = %d", errno);
+		fatal_perror("check_ptrace : mmap failed");
 	sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
 	pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL);
 	if(pid < 0)
-		panic("start_ptraced_child : clone failed, errno = %d", errno);
+		fatal_perror("start_ptraced_child : clone failed");
 	CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
 	if(n < 0)
-		panic("check_ptrace : clone failed, errno = %d", errno);
+		fatal_perror("check_ptrace : clone failed");
 	if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
-		panic("check_ptrace : expected SIGSTOP, got status = %d",
+		fatal("check_ptrace : expected SIGSTOP, got status = %d",
 		      status);
 
 	*stack_out = stack;
@@ -105,31 +133,30 @@
  * must work anyway!
  */
 static int stop_ptraced_child(int pid, void *stack, int exitcode,
-			      int mustpanic)
+			      int mustexit)
 {
 	int status, n, ret = 0;
 
 	if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
-		panic("check_ptrace : ptrace failed, errno = %d", errno);
+		fatal_perror("stop_ptraced_child : ptrace failed");
 	CATCH_EINTR(n = waitpid(pid, &status, 0));
 	if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) {
 		int exit_with = WEXITSTATUS(status);
 		if (exit_with == 2)
-			printf("check_ptrace : child exited with status 2. "
-			       "Serious trouble happening! Try updating your "
-			       "host skas patch!\nDisabling SYSEMU support.");
-		printf("check_ptrace : child exited with exitcode %d, while "
-		      "expecting %d; status 0x%x", exit_with,
-		      exitcode, status);
-		if (mustpanic)
-			panic("\n");
-		else
-			printf("\n");
+			non_fatal("check_ptrace : child exited with status 2. "
+				  "Serious trouble happening! Try updating "
+				  "your host skas patch!\nDisabling SYSEMU "
+				  "support.");
+		non_fatal("check_ptrace : child exited with exitcode %d, while "
+			  "expecting %d; status 0x%x\n", exit_with,
+			  exitcode, status);
+		if (mustexit)
+			exit(1);
 		ret = -1;
 	}
 
 	if(munmap(stack, PAGE_SIZE) < 0)
-		panic("check_ptrace : munmap failed, errno = %d", errno);
+		fatal_perror("check_ptrace : munmap failed");
 	return ret;
 }
 
@@ -184,7 +211,7 @@
 	void *stack;
 	int pid, n, status, count=0;
 
-	printf("Checking syscall emulation patch for ptrace...");
+	non_fatal("Checking syscall emulation patch for ptrace...");
 	sysemu_supported = 0;
 	pid = start_ptraced_child(&stack);
 
@@ -193,31 +220,30 @@
 
 	CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
 	if (n < 0)
-		panic("check_sysemu : wait failed, errno = %d", errno);
+		fatal_perror("check_sysemu : wait failed");
 	if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
-		panic("check_sysemu : expected SIGTRAP, "
-		      "got status = %d", status);
+		fatal("check_sysemu : expected SIGTRAP, got status = %d",
+		      status);
 
 	n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET,
 		   os_getpid());
 	if(n < 0)
-		panic("check_sysemu : failed to modify system "
-		      "call return, errno = %d", errno);
+		fatal_perror("check_sysemu : failed to modify system call "
+			     "return");
 
 	if (stop_ptraced_child(pid, stack, 0, 0) < 0)
 		goto fail_stopped;
 
 	sysemu_supported = 1;
-	printf("OK\n");
+	non_fatal("OK\n");
 	set_using_sysemu(!force_sysemu_disabled);
 
-	printf("Checking advanced syscall emulation patch for ptrace...");
+	non_fatal("Checking advanced syscall emulation patch for ptrace...");
 	pid = start_ptraced_child(&stack);
 
-	if(ptrace(PTRACE_OLDSETOPTIONS, pid, 0,
-		  (void *) PTRACE_O_TRACESYSGOOD) < 0)
-		panic("check_ptrace: PTRACE_OLDSETOPTIONS failed, errno = %d",
-		      errno);
+	if((ptrace(PTRACE_OLDSETOPTIONS, pid, 0,
+		   (void *) PTRACE_O_TRACESYSGOOD) < 0))
+		fatal_perror("check_ptrace: PTRACE_OLDSETOPTIONS failed");
 
 	while(1){
 		count++;
@@ -225,29 +251,30 @@
 			goto fail;
 		CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
 		if(n < 0)
-			panic("check_ptrace : wait failed, errno = %d", errno);
+			fatal_perror("check_ptrace : wait failed");
+
 		if(WIFSTOPPED(status) && (WSTOPSIG(status) == (SIGTRAP|0x80))){
 			if (!count)
-				panic("check_ptrace : SYSEMU_SINGLESTEP "
+				fatal("check_ptrace : SYSEMU_SINGLESTEP "
 				      "doesn't singlestep");
 			n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET,
 				   os_getpid());
 			if(n < 0)
-				panic("check_sysemu : failed to modify system "
-				      "call return, errno = %d", errno);
+				fatal_perror("check_sysemu : failed to modify "
+					     "system call return");
 			break;
 		}
 		else if(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP))
 			count++;
 		else
-			panic("check_ptrace : expected SIGTRAP or "
-			      "(SIGTRAP|0x80), got status = %d", status);
+			fatal("check_ptrace : expected SIGTRAP or "
+			      "(SIGTRAP | 0x80), got status = %d", status);
 	}
 	if (stop_ptraced_child(pid, stack, 0, 0) < 0)
 		goto fail_stopped;
 
 	sysemu_supported = 2;
-	printf("OK\n");
+	non_fatal("OK\n");
 
 	if ( !force_sysemu_disabled )
 		set_using_sysemu(sysemu_supported);
@@ -256,7 +283,7 @@
 fail:
 	stop_ptraced_child(pid, stack, 1, 0);
 fail_stopped:
-	printf("missing\n");
+	non_fatal("missing\n");
 }
 
 static void __init check_ptrace(void)
@@ -264,22 +291,25 @@
 	void *stack;
 	int pid, syscall, n, status;
 
-	printf("Checking that ptrace can change system call numbers...");
+	non_fatal("Checking that ptrace can change system call numbers...");
 	pid = start_ptraced_child(&stack);
 
-	if(ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0)
-		panic("check_ptrace: PTRACE_OLDSETOPTIONS failed, errno = %d", errno);
+	if((ptrace(PTRACE_OLDSETOPTIONS, pid, 0,
+		   (void *) PTRACE_O_TRACESYSGOOD) < 0))
+		fatal_perror("check_ptrace: PTRACE_OLDSETOPTIONS failed");
 
 	while(1){
 		if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
-			panic("check_ptrace : ptrace failed, errno = %d",
-			      errno);
+			fatal_perror("check_ptrace : ptrace failed");
+
 		CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
 		if(n < 0)
-			panic("check_ptrace : wait failed, errno = %d", errno);
-		if(!WIFSTOPPED(status) || (WSTOPSIG(status) != (SIGTRAP|0x80)))
-			panic("check_ptrace : expected (SIGTRAP|0x80), "
-			      "got status = %d", status);
+			fatal_perror("check_ptrace : wait failed");
+
+		if(!WIFSTOPPED(status) ||
+		   (WSTOPSIG(status) != (SIGTRAP | 0x80)))
+			fatal("check_ptrace : expected (SIGTRAP|0x80), "
+			       "got status = %d", status);
 
 		syscall = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_NR_OFFSET,
 				 0);
@@ -287,13 +317,13 @@
 			n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET,
 				   __NR_getppid);
 			if(n < 0)
-				panic("check_ptrace : failed to modify system "
-				      "call, errno = %d", errno);
+				fatal_perror("check_ptrace : failed to modify "
+					     "system call");
 			break;
 		}
 	}
 	stop_ptraced_child(pid, stack, 0, 1);
-	printf("OK\n");
+	non_fatal("OK\n");
 	check_sysemu();
 }
 
@@ -352,22 +382,22 @@
 	void *stack;
 	int pid, n;
 
-	printf("  - PTRACE_FAULTINFO...");
+	non_fatal("  - PTRACE_FAULTINFO...");
 	pid = start_ptraced_child(&stack);
 
 	n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
 	if (n < 0) {
 		ptrace_faultinfo = 0;
 		if(errno == EIO)
-			printf("not found\n");
+			non_fatal("not found\n");
 		else
 			perror("not found");
 	}
 	else {
 		if (!ptrace_faultinfo)
-			printf("found but disabled on command line\n");
+			non_fatal("found but disabled on command line\n");
 		else
-			printf("found\n");
+			non_fatal("found\n");
 	}
 
 	init_registers(pid);
@@ -385,13 +415,13 @@
 		.ptr = ldtbuf,
 		.bytecount = sizeof(ldtbuf)};
 
-	printf("  - PTRACE_LDT...");
+	non_fatal("  - PTRACE_LDT...");
 	pid = start_ptraced_child(&stack);
 
 	n = ptrace(PTRACE_LDT, pid, 0, (unsigned long) &ldt_op);
 	if (n < 0) {
 		if(errno == EIO)
-			printf("not found\n");
+			non_fatal("not found\n");
 		else {
 			perror("not found");
 		}
@@ -399,9 +429,9 @@
 	}
 	else {
 		if(ptrace_ldt)
-			printf("found\n");
+			non_fatal("found\n");
 		else
-			printf("found, but use is disabled\n");
+			non_fatal("found, but use is disabled\n");
 	}
 
 	stop_ptraced_child(pid, stack, 1, 1);
@@ -416,22 +446,22 @@
 
 static inline void check_skas3_proc_mm(void)
 {
-	printf("  - /proc/mm...");
+	non_fatal("  - /proc/mm...");
 	if (access("/proc/mm", W_OK) < 0) {
 		proc_mm = 0;
-		printf("not found\n");
+		perror("not found");
 	}
 	else {
 		if (!proc_mm)
-			printf("found but disabled on command line\n");
+			non_fatal("found but disabled on command line\n");
 		else
-			printf("found\n");
+			non_fatal("found\n");
 	}
 }
 
 int can_do_skas(void)
 {
-	printf("Checking for the skas3 patch in the host:\n");
+	non_fatal("Checking for the skas3 patch in the host:\n");
 
 	check_skas3_proc_mm();
 	check_skas3_ptrace_faultinfo();