你的位置:
问答吧
-> Linux 内核
-> 问题详情
如何在伪终端(通过ssh远程登录)显示内核打印信息
我通过ssh远程登录linux主机,但内核打印信息却只能打印在主机的控制台上,如何让打印信息在我的个人电脑登录终端上打印啊,希望高手赐教。
作者: linuxer_lhw
发布时间: 2010-07-13
如果打印启动信息的话,可以考虑修改内核参数
作者: Godbach
发布时间: 2010-07-13
回复 Godbach
不是启动信息,自己编写的内核模块的printk信息,比如模块手动加载或运行时产生的信息。以前做嵌入式开发的时候,修改内核参数可以把信息打印到串口终端上,不知道能不能用什么方法打印到这种远程登录的客户端上,有个netconsole方法不知道行不行
作者: linuxer_lhw
发布时间: 2010-07-13
netconsole主要是配置把内核信息传输到其他机器上的日志文件中。
作者: Godbach
发布时间: 2010-07-13
既然有终端登陆,查看日志也是一种不错的方式啊
作者: Godbach
发布时间: 2010-07-13
/etc/issue.net 这个吧
作者: vermouth
发布时间: 2010-07-13
我有个思路,不知道可不可行,明天试试
作者: lmarsin
发布时间: 2010-07-13
回复 Godbach
我的终端是windows下的,没法看日志。呵呵。其实一般可以查看dmesg 或者/var/log/message ,主要是有时后oops死机时要查看瞬间的信息。
作者: linuxer_lhw
发布时间: 2010-07-13
QUOTE:
回复 Godbach
我的终端是windows下的,没法看日志。呵呵。其实一般可以查看dmesg 或者/var/log/ ...
linuxer_lhw 发表于 2010-07-13 19:25
查看日志看文件/var/log/messages就可以了。
你通过终端同样也可查看该文件啊
作者: Godbach
发布时间: 2010-07-13
回复 lmarsin
如果可以的话给大家说说哈。谢谢
作者: linuxer_lhw
发布时间: 2010-07-13
回复 Godbach
没死机可以,但调试时出oops一般就死机了就没法看了,重启后就没了。死机前oops倾泄出来的信息会打印到控制台上,但我每次都得跑到服务器那边看,很麻烦,所以我想能不能将prink信息直接打印到本地机器的终端上,我本地机器是windows,通过SecureCRT远程登录
作者: linuxer_lhw
发布时间: 2010-07-13
那就用netconsole传递到另外一台Linux上好了。
BTW,你的系统重启之后就没有以前的日志信息了吗,用的是硬盘吗?
作者: Godbach
发布时间: 2010-07-13
解决办法1:dmesg
解决方法2:
void print_string(char *str)
{
struct tty_struct *my_tty;
my_tty = current->tty;
if (my_tty != NULL) {
(*(my_tty->driver).write)( my_tty, 0, str,strlen(str));
(*(my_tty->driver).write)( my_tty, 0, "" "", 2);
}
}
作者: unbutun
发布时间: 2010-07-13
你也可以再封一层,用va_start封成printf的形式,就更完美了
作者: unbutun
发布时间: 2010-07-13
本帖最后由 lmarsin 于 2010-07-14 15:26 编辑
回复 linuxer_lhw
花了半天的时间,对昨天的想法做了验证,基本实现了,并贴上代码。以下代码只是验证我的思路而已,请大牛们拍砖。
我们知道,当通过ssh连接主机时,linux会在/dev/pts/下创建对应的终端设备文件,通过写此文件即可向对应的终端发送信息,以下图示例:
下载 (57.01 KB)
2010-07-14 14:52
首先通过SecureCRT登录到linux主机,可以看到/dev/pts下有设备文件0。
然后,在虚拟机的命令行上输入echo "123456789" > /dev/pts/0 回车后,便在ssh的虚拟终端上输出123456789。
我们知道printk最终是输出到console,只要我们创建一个自己的console并注册到系统中,这样当调用printk时,我们可以很容易的得到printk输出的信息,此时再将此信息输向到/dev/pts/xxx即可。
代码
ptyconsole.rar (1.98 KB)
下载次数: 10
2010-07-14 14:58
在虚拟机的窗口操作效果如下:通过printk打印的内容同时输出到了终端上。
下载 (79.75 KB)
2010-07-14 15:01
作者: lmarsin
发布时间: 2010-07-14
多谢lmarsin兄的分享。刚刚测试了一下,是可以打印远程登录的终端上。
不过我本地出现了一下错误,应该是oops信息:
QUOTE:
ptyfile:/dev/pts/1
np.pty_file:cd068900
open file: 0
BUG: sleeping function called from invalid context at include/asm/uaccess_32.h:512
in_atomic():0, irqs_disabled():1
Pid: 5112, comm: insmod Not tainted 2.6.24.4 #2
[] __might_sleep+0xa4/0xa9
[] copy_from_user+0x2d/0x60
[] tty_write+0x132/0x1c7
[] write_chan+0x0/0x1b3
[] vfs_write+0xac/0x12c
[] write_msg+0x4b/0x73 [ptyconsole]
[] write_msg+0x0/0x73 [ptyconsole]
[] __call_console_drivers+0x51/0x5b
[] call_console_drivers+0xb2/0xd4
[] release_console_sem+0x70/0xb0
[] init_ptyconsole+0x40/0x54 [ptyconsole]
[] sys_init_module+0x91/0x11b
[] sysenter_past_esp+0x5f/0x85
=======================
ptyconsole: network logging started
作者: Godbach:
发布时间: 2010-07-14
本帖最后由 lmarsin 于 2010-07-14 15:38 编辑
回复 Godbach
你的系统打开了CONFIG_DEBUG_SPINLOCK_SLEEP功能,应该是在中断或软中断上下文的输出过程中睡眠了,printk在中断或软中断以及进程上下文中都可以被调用。
代码只是验证了我的思路,没有进行中断调用的测试。
作者: Godbach
发布时间: 2010-07-14
另外,lmarsin兄测试发生oops的情况了吗。如果oops发生了,可能一些write操作都不能保证了,还有可能输出到终端吗
作者: lmarsin
发布时间: 2010-07-14
本帖最后由 lmarsin 于 2010-07-14 15:43 编辑
回复 Godbach
这种情况没有测试。
对于你上面发生的问题,可以在write_msg函数中,注释掉
local_irq_save(flags);
local_irq_restore(flags);
之后测试下看看
static void write_msg(struct console *con, const char *msg, unsigned int len)
{
#if USE_SYS_CALL
unsigned long flags;
mm_segment_t old_fs;
old_fs = get_fs();
set_fs(KERNEL_DS);
sys_write(np.pty_fd, msg, len);
set_fs(old_fs);
#else
unsigned long flags;
ssize_t ret = -EBADF;
mm_segment_t old_fs;
if (np.pty_file) {
old_fs = get_fs();
set_fs(KERNEL_DS);
loff_t pos = np.pty_file->f_pos;
ret = vfs_write(np.pty_file, msg, len, &pos);
np.pty_file->f_pos = pos;
set_fs(old_fs);
}
#endif
}
作者: Godbach
发布时间: 2010-07-14
你的代码中定义USE_SYS_CALL为0.也就是不走这个分支吧。
注释掉了local_irq_save(flags);
对应的local_irq_restore(flags);也需要注释掉啊
作者: lmarsin
发布时间: 2010-07-14
回复 Godbach
那是应该的。
本来我是直接调用系统调用的,但不知为何加载时链接不到sys_open符号,所以用filp_open等方法了,用USE_SYS_CALL来区分两种方法。
作者: Godbach
发布时间: 2010-07-14
用filp_open挺好的。
作者: lmarsin
发布时间: 2010-07-14
改过后的这块代码为:
static void write_msg(struct console *con, const char *msg, unsigned int len)
{
#if USE_SYS_CALL
unsigned long flags;
mm_segment_t old_fs;
// local_irq_save(flags);
old_fs = get_fs();
set_fs(KERNEL_DS);
sys_write(np.pty_fd, msg, len);
set_fs(old_fs);
// local_irq_restore(flags);
#else
unsigned long flags;
ssize_t ret = -EBADF;
mm_segment_t old_fs;
if (np.pty_file) {
local_irq_save(flags);
old_fs = get_fs();
set_fs(KERNEL_DS);
loff_t pos = np.pty_file->f_pos;
ret = vfs_write(np.pty_file, msg, len, &pos);
np.pty_file->f_pos = pos;
set_fs(old_fs);
// local_irq_restore(flags);
}
#endif
}复制代码加载模块情况为
QUOTE:
[root@localhost ~]# ptyfile:/dev/pts/2
np.pty_file:d59e3780
open file: 0
BUG: sleeping function called from invalid context at include/asm/uaccess_32.h:512
in_atomic():0, irqs_disabled():1
Pid: 6590, comm: insmod Not tainted 2.6.24.4 #2
[] __might_sleep+0xa4/0xa9
[] copy_from_user+0x2d/0x60
[] tty_write+0x132/0x1c7
[] write_chan+0x0/0x1b3
[] vfs_write+0xac/0x12c
[] write_msg+0x4a/0x6f [ptyconsole]
[] write_msg+0x0/0x6f [ptyconsole]
[] __call_console_drivers+0x51/0x5b
[] call_console_drivers+0xb2/0xd4
[] release_console_sem+0x70/0xb0
[] init_ptyconsole+0x40/0x54 [ptyconsole]
[] sys_init_module+0x91/0x11b
[] sysenter_past_esp+0x5f/0x85
=======================
ptyconsole: network logging started
作者: Godbach
发布时间: 2010-07-14
本帖最后由 lmarsin 于 2010-07-14 15:57 编辑
回复 Godbach
好像你还漏改了一个地方,你贴代码的20行
作者: Godbach
发布时间: 2010-07-14
回复 lmarsin
惭愧,这个关键的地方漏掉了。
作者: lmarsin
发布时间: 2010-07-14
改了之后,好像还和前面的信息一样:
QUOTE:
[root@localhost ~]# ptyfile:/dev/pts/2
np.pty_file:c6d48b40
open file: 0
BUG: sleeping function called from invalid context at include/asm/uaccess_32.h:512
in_atomic():0, irqs_disabled():1
Pid: 7481, comm: insmod Not tainted 2.6.24.4 #2
[] __might_sleep+0xa4/0xa9
[] copy_from_user+0x2d/0x60
[] tty_write+0x132/0x1c7
[] write_chan+0x0/0x1b3
[] vfs_write+0xac/0x12c
[] write_msg+0x41/0x66 [ptyconsole]
[] write_msg+0x0/0x66 [ptyconsole]
[] __call_console_drivers+0x51/0x5b
[] call_console_drivers+0xb2/0xd4
[] release_console_sem+0x70/0xb0
[] init_ptyconsole+0x40/0x54 [ptyconsole]
[] sys_init_module+0x91/0x11b
[] sysenter_past_esp+0x5f/0x85
=======================
ptyconsole: network logging started
作者: Godbach
发布时间: 2010-07-14
我这里设置USE_SYS_CALL为1的,编译时也提示sys_open和sys_write的问题
作者: Godbach
发布时间: 2010-07-14
我这边只提示sys_open
作者: Godbach
发布时间: 2010-07-14
回复 Godbach
系统会挂掉吗?
作者: lmarsin
发布时间: 2010-07-14
系统不会挂掉。就是报错的信息还是一样的。
作者: lmarsin
发布时间: 2010-07-14