aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um
diff options
context:
space:
mode:
authorJeff Dike <jdike@addtoit.com>2006-01-06 03:19:04 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-06 11:33:48 -0500
commit6f517d3fc862d3c8d8ba65c0b2472d399aceb9ed (patch)
treed8062920a60939dd2dda3b2deb39a4e206e0ae06 /arch/um
parent7b033e1fdeef3d8bacac3cd5cfa53c9d670d1f3d (diff)
[PATCH] uml: capture printk output for mconsole stack
The stack command now sends the printk output back to the mconsole client. This is done by registering a special console for the mconsole driver. This receives all printk output. Normally, it is ignored, but when a stack command is issued, any printk output will be sent back to the client. This will capture any printk output, whether it is stack output or not, since we can't tell the difference. Signed-off-by: Jeff Dike <jdike@addtoit.com> Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/um')
-rw-r--r--arch/um/drivers/mconsole_kern.c87
1 files changed, 81 insertions, 6 deletions
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index b5217bd7bc41..e9bbc14f3655 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -20,6 +20,7 @@
20#include "linux/namei.h" 20#include "linux/namei.h"
21#include "linux/proc_fs.h" 21#include "linux/proc_fs.h"
22#include "linux/syscalls.h" 22#include "linux/syscalls.h"
23#include "linux/console.h"
23#include "asm/irq.h" 24#include "asm/irq.h"
24#include "asm/uaccess.h" 25#include "asm/uaccess.h"
25#include "user_util.h" 26#include "user_util.h"
@@ -480,6 +481,82 @@ void mconsole_sysrq(struct mc_request *req)
480} 481}
481#endif 482#endif
482 483
484static DEFINE_SPINLOCK(console_lock);
485static LIST_HEAD(clients);
486static char console_buf[MCONSOLE_MAX_DATA];
487static int console_index = 0;
488
489static void console_write(struct console *console, const char *string,
490 unsigned len)
491{
492 struct list_head *ele;
493 int n;
494
495 if(list_empty(&clients))
496 return;
497
498 while(1){
499 n = min(len, ARRAY_SIZE(console_buf) - console_index);
500 strncpy(&console_buf[console_index], string, n);
501 console_index += n;
502 string += n;
503 len -= n;
504 if(len == 0)
505 return;
506
507 list_for_each(ele, &clients){
508 struct mconsole_entry *entry;
509
510 entry = list_entry(ele, struct mconsole_entry, list);
511 mconsole_reply_len(&entry->request, console_buf,
512 console_index, 0, 1);
513 }
514
515 console_index = 0;
516 }
517}
518
519static struct console mc_console = { .name = "mc",
520 .write = console_write,
521 .flags = CON_PRINTBUFFER | CON_ENABLED,
522 .index = -1 };
523
524static int mc_add_console(void)
525{
526 register_console(&mc_console);
527 return 0;
528}
529
530late_initcall(mc_add_console);
531
532static void with_console(struct mc_request *req, void (*proc)(void *),
533 void *arg)
534{
535 struct mconsole_entry entry;
536 unsigned long flags;
537
538 INIT_LIST_HEAD(&entry.list);
539 entry.request = *req;
540 list_add(&entry.list, &clients);
541 spin_lock_irqsave(&console_lock, flags);
542
543 (*proc)(arg);
544
545 mconsole_reply_len(req, console_buf, console_index, 0, 0);
546 console_index = 0;
547
548 spin_unlock_irqrestore(&console_lock, flags);
549 list_del(&entry.list);
550}
551
552static void stack_proc(void *arg)
553{
554 struct task_struct *from = current, *to = arg;
555
556 to->thread.saved_task = from;
557 switch_to(from, to, from);
558}
559
483/* Mconsole stack trace 560/* Mconsole stack trace
484 * Added by Allan Graves, Jeff Dike 561 * Added by Allan Graves, Jeff Dike
485 * Dumps a stacks registers to the linux console. 562 * Dumps a stacks registers to the linux console.
@@ -489,7 +566,7 @@ void do_stack(struct mc_request *req)
489{ 566{
490 char *ptr = req->request.data; 567 char *ptr = req->request.data;
491 int pid_requested= -1; 568 int pid_requested= -1;
492 struct task_struct *from = NULL; 569 struct task_struct *from = NULL;
493 struct task_struct *to = NULL; 570 struct task_struct *to = NULL;
494 571
495 /* Would be nice: 572 /* Would be nice:
@@ -507,17 +584,15 @@ void do_stack(struct mc_request *req)
507 return; 584 return;
508 } 585 }
509 586
510 from = current; 587 from = current;
511 to = find_task_by_pid(pid_requested);
512 588
589 to = find_task_by_pid(pid_requested);
513 if((to == NULL) || (pid_requested == 0)) { 590 if((to == NULL) || (pid_requested == 0)) {
514 mconsole_reply(req, "Couldn't find that pid", 1, 0); 591 mconsole_reply(req, "Couldn't find that pid", 1, 0);
515 return; 592 return;
516 } 593 }
517 to->thread.saved_task = current;
518 594
519 switch_to(from, to, from); 595 with_console(req, stack_proc, to);
520 mconsole_reply(req, "Stack Dumped to console and message log", 0, 0);
521} 596}
522 597
523void mconsole_stack(struct mc_request *req) 598void mconsole_stack(struct mc_request *req)