diff options
author | Bernhard Walle <bernhard@bwalle.de> | 2009-12-14 21:00:43 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-15 11:53:28 -0500 |
commit | 5ada918b82399eef3afd6a71e3637697d6bd719f (patch) | |
tree | 9bff5251d9d21960726078c2117a0ab19ca25956 | |
parent | c95d1e53ed89b75a4d7b68d1cbae4607b1479243 (diff) |
vt: introduce and use vt_kmsg_redirect() function
The kernel offers with TIOCL_GETKMSGREDIRECT ioctl() the possibility to
redirect the kernel messages to a specific console.
However, since it's not possible to switch to the kernel message console
after a panic(), it would be nice if the kernel would print the panic
message on the current console.
This patch series adds a new interface to access the global kmsg_redirect
variable by a function to be able to use it in code where
CONFIG_VT_CONSOLE is not set (kernel/panic.c).
This patch:
Instead of using and exporting a global value kmsg_redirect, introduce a
function vt_kmsg_redirect() that both can set and return the console where
messages are printed.
Change all users of kmsg_redirect (the VT code itself and kernel/power.c)
to the new interface.
The main advantage is that vt_kmsg_redirect() can also be used when
CONFIG_VT_CONSOLE is not set.
Signed-off-by: Bernhard Walle <bernhard@bwalle.de>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/char/vt.c | 43 | ||||
-rw-r--r-- | include/linux/tty.h | 2 | ||||
-rw-r--r-- | include/linux/vt.h | 15 | ||||
-rw-r--r-- | kernel/power/console.c | 7 |
4 files changed, 55 insertions, 12 deletions
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 1e3d728dbf7e..e43fbc66aef0 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -184,12 +184,10 @@ static DECLARE_WORK(console_work, console_callback); | |||
184 | * fg_console is the current virtual console, | 184 | * fg_console is the current virtual console, |
185 | * last_console is the last used one, | 185 | * last_console is the last used one, |
186 | * want_console is the console we want to switch to, | 186 | * want_console is the console we want to switch to, |
187 | * kmsg_redirect is the console for kernel messages, | ||
188 | */ | 187 | */ |
189 | int fg_console; | 188 | int fg_console; |
190 | int last_console; | 189 | int last_console; |
191 | int want_console = -1; | 190 | int want_console = -1; |
192 | int kmsg_redirect; | ||
193 | 191 | ||
194 | /* | 192 | /* |
195 | * For each existing display, we have a pointer to console currently visible | 193 | * For each existing display, we have a pointer to console currently visible |
@@ -2434,6 +2432,37 @@ struct tty_driver *console_driver; | |||
2434 | 2432 | ||
2435 | #ifdef CONFIG_VT_CONSOLE | 2433 | #ifdef CONFIG_VT_CONSOLE |
2436 | 2434 | ||
2435 | /** | ||
2436 | * vt_kmsg_redirect() - Sets/gets the kernel message console | ||
2437 | * @new: The new virtual terminal number or -1 if the console should stay | ||
2438 | * unchanged | ||
2439 | * | ||
2440 | * By default, the kernel messages are always printed on the current virtual | ||
2441 | * console. However, the user may modify that default with the | ||
2442 | * TIOCL_SETKMSGREDIRECT ioctl call. | ||
2443 | * | ||
2444 | * This function sets the kernel message console to be @new. It returns the old | ||
2445 | * virtual console number. The virtual terminal number 0 (both as parameter and | ||
2446 | * return value) means no redirection (i.e. always printed on the currently | ||
2447 | * active console). | ||
2448 | * | ||
2449 | * The parameter -1 means that only the current console is returned, but the | ||
2450 | * value is not modified. You may use the macro vt_get_kmsg_redirect() in that | ||
2451 | * case to make the code more understandable. | ||
2452 | * | ||
2453 | * When the kernel is compiled without CONFIG_VT_CONSOLE, this function ignores | ||
2454 | * the parameter and always returns 0. | ||
2455 | */ | ||
2456 | int vt_kmsg_redirect(int new) | ||
2457 | { | ||
2458 | static int kmsg_con; | ||
2459 | |||
2460 | if (new != -1) | ||
2461 | return xchg(&kmsg_con, new); | ||
2462 | else | ||
2463 | return kmsg_con; | ||
2464 | } | ||
2465 | |||
2437 | /* | 2466 | /* |
2438 | * Console on virtual terminal | 2467 | * Console on virtual terminal |
2439 | * | 2468 | * |
@@ -2448,6 +2477,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count) | |||
2448 | const ushort *start; | 2477 | const ushort *start; |
2449 | ushort cnt = 0; | 2478 | ushort cnt = 0; |
2450 | ushort myx; | 2479 | ushort myx; |
2480 | int kmsg_console; | ||
2451 | 2481 | ||
2452 | /* console busy or not yet initialized */ | 2482 | /* console busy or not yet initialized */ |
2453 | if (!printable) | 2483 | if (!printable) |
@@ -2455,8 +2485,9 @@ static void vt_console_print(struct console *co, const char *b, unsigned count) | |||
2455 | if (!spin_trylock(&printing_lock)) | 2485 | if (!spin_trylock(&printing_lock)) |
2456 | return; | 2486 | return; |
2457 | 2487 | ||
2458 | if (kmsg_redirect && vc_cons_allocated(kmsg_redirect - 1)) | 2488 | kmsg_console = vt_get_kmsg_redirect(); |
2459 | vc = vc_cons[kmsg_redirect - 1].d; | 2489 | if (kmsg_console && vc_cons_allocated(kmsg_console - 1)) |
2490 | vc = vc_cons[kmsg_console - 1].d; | ||
2460 | 2491 | ||
2461 | /* read `x' only after setting currcons properly (otherwise | 2492 | /* read `x' only after setting currcons properly (otherwise |
2462 | the `x' macro will read the x of the foreground console). */ | 2493 | the `x' macro will read the x of the foreground console). */ |
@@ -2613,7 +2644,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) | |||
2613 | ret = set_vesa_blanking(p); | 2644 | ret = set_vesa_blanking(p); |
2614 | break; | 2645 | break; |
2615 | case TIOCL_GETKMSGREDIRECT: | 2646 | case TIOCL_GETKMSGREDIRECT: |
2616 | data = kmsg_redirect; | 2647 | data = vt_get_kmsg_redirect(); |
2617 | ret = __put_user(data, p); | 2648 | ret = __put_user(data, p); |
2618 | break; | 2649 | break; |
2619 | case TIOCL_SETKMSGREDIRECT: | 2650 | case TIOCL_SETKMSGREDIRECT: |
@@ -2623,7 +2654,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) | |||
2623 | if (get_user(data, p+1)) | 2654 | if (get_user(data, p+1)) |
2624 | ret = -EFAULT; | 2655 | ret = -EFAULT; |
2625 | else | 2656 | else |
2626 | kmsg_redirect = data; | 2657 | vt_kmsg_redirect(data); |
2627 | } | 2658 | } |
2628 | break; | 2659 | break; |
2629 | case TIOCL_GETFGCONSOLE: | 2660 | case TIOCL_GETFGCONSOLE: |
diff --git a/include/linux/tty.h b/include/linux/tty.h index 405a9035fe40..ef3a2947b102 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
@@ -350,8 +350,6 @@ extern void tty_write_flush(struct tty_struct *); | |||
350 | 350 | ||
351 | extern struct ktermios tty_std_termios; | 351 | extern struct ktermios tty_std_termios; |
352 | 352 | ||
353 | extern int kmsg_redirect; | ||
354 | |||
355 | extern void console_init(void); | 353 | extern void console_init(void); |
356 | extern int vcs_init(void); | 354 | extern int vcs_init(void); |
357 | 355 | ||
diff --git a/include/linux/vt.h b/include/linux/vt.h index 7ffa11f06232..3fb9944e50a6 100644 --- a/include/linux/vt.h +++ b/include/linux/vt.h | |||
@@ -84,4 +84,19 @@ struct vt_setactivate { | |||
84 | 84 | ||
85 | #define VT_SETACTIVATE 0x560F /* Activate and set the mode of a console */ | 85 | #define VT_SETACTIVATE 0x560F /* Activate and set the mode of a console */ |
86 | 86 | ||
87 | #ifdef CONFIG_VT_CONSOLE | ||
88 | |||
89 | extern int vt_kmsg_redirect(int new); | ||
90 | |||
91 | #else | ||
92 | |||
93 | static inline int vt_kmsg_redirect(int new) | ||
94 | { | ||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | #endif | ||
99 | |||
100 | #define vt_get_kmsg_redirect() vt_kmsg_redirect(-1) | ||
101 | |||
87 | #endif /* _LINUX_VT_H */ | 102 | #endif /* _LINUX_VT_H */ |
diff --git a/kernel/power/console.c b/kernel/power/console.c index 5187136fe1de..218e5af90156 100644 --- a/kernel/power/console.c +++ b/kernel/power/console.c | |||
@@ -6,7 +6,7 @@ | |||
6 | 6 | ||
7 | #include <linux/vt_kern.h> | 7 | #include <linux/vt_kern.h> |
8 | #include <linux/kbd_kern.h> | 8 | #include <linux/kbd_kern.h> |
9 | #include <linux/console.h> | 9 | #include <linux/vt.h> |
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include "power.h" | 11 | #include "power.h" |
12 | 12 | ||
@@ -21,8 +21,7 @@ int pm_prepare_console(void) | |||
21 | if (orig_fgconsole < 0) | 21 | if (orig_fgconsole < 0) |
22 | return 1; | 22 | return 1; |
23 | 23 | ||
24 | orig_kmsg = kmsg_redirect; | 24 | orig_kmsg = vt_kmsg_redirect(SUSPEND_CONSOLE); |
25 | kmsg_redirect = SUSPEND_CONSOLE; | ||
26 | return 0; | 25 | return 0; |
27 | } | 26 | } |
28 | 27 | ||
@@ -30,7 +29,7 @@ void pm_restore_console(void) | |||
30 | { | 29 | { |
31 | if (orig_fgconsole >= 0) { | 30 | if (orig_fgconsole >= 0) { |
32 | vt_move_to_console(orig_fgconsole, 0); | 31 | vt_move_to_console(orig_fgconsole, 0); |
33 | kmsg_redirect = orig_kmsg; | 32 | vt_kmsg_redirect(orig_kmsg); |
34 | } | 33 | } |
35 | } | 34 | } |
36 | #endif | 35 | #endif |