Netconsole实例源代码分析

来源:互联网 发布:学位英语考试题库软件 编辑:程序博客网 时间:2024/06/06 02:28
目录

1.前言        - 2 -
2.实例配置        - 2 -
2.1 监控主机的配置        - 2 -
2.2 被监控主机的配置        - 2 -
2.3 实例测试        - 3 -
3.Netconsole内核源码分析        - 4 -
3.1 几个重要的数据结构        - 4 -
3.1.1 struct console        - 4 -
3.1.2 struct netpoll        - 5 -
3.1.3 struct net_device        - 5 -
3.1.4 struct netpoll_info        - 6 -
3.2 实现分析        - 6 -
3.2.1 Netconsole初始化        - 7 -
3.2.2 具体运行实现        - 11 -










1.前言

Netconsole是Linux2.6版内核的一个新的特性。它允许将本机的dmesg系统信息,通过网络的方式传送到另一台主机上。这样,就可以实现远程监控某台机子的kernel panic信息了。使用起来非常方便,也给开发人员调试内核提供了更加便捷的途径。


1.1 menuconfig选项

File systems -> Pseudo filesystems中 
< M > Userspace-driven configuration filesystem

Device Drivers -> Network device support中 
< M > Network console logging support 
[ * ] Dynamic reconfiguration of logging targets

[*]   Netpoll traffic trapping 



2.实例配置

由于2.6版本的内核本身已经支持Netconsole,并以模块形式编译进了内核。所以,下面的介绍都是基于2.6版内核,且本身在内核编译的时候,已经选择了将Netconsole以模块进行编译的方式。如果内核本身并没有编译Netconsole这个模块,那就需要重新编译内核了(笔者暂时没有找到其他的解决方案)。


2.1 监控主机的配置
监控主机有两种配置方式:使用本身的syslogd和利用netcat这个工具。Syslogd使用了514这个特定的UDP端口,而netcat工具可以指定任意未被使用的UDP端口进行监视。我这里使用的是netcat的方式进行监视的。安装好netcat后,执行shell命令:
# netcat -l -p 30000 –u

这里使用了端口30000来进行接收,这个端口是任意制定的,只要不发生冲突即可。


2.2 被监控主机的配置
在需要被监控的主机上加载运行netconsole模块,由于netconsole模块需要许多其他模块的依赖,以及在加载时必须配置相关的端口,IP地址等信息,所以shell执行命令如下:
#modprobe netconsole netconsole=6666@10.14.0.225/eth7,30000@10.14.0.220/00:0C:29:E2:87:E8
我们来分析一下这段加载命令。
Modprobe 这个模块加载命令是指在加载该模块时,同时加载其依赖的其它模块;
第一个@前的6666是本地端口,这个我们可以在源码中看到,是一个源代码中默认的本地端口;
10.14.0.225/eth7:这里指配本机的IP地址及网卡名称(通常我们可以用ifconfig –a来查看到);

30000@10.14.0.220/00:0C:29:E2:87:E8:三个位段分别是,远端监控端口,远端IP地址及远端机子的MAC地址。也就是我们在2.1节中指定的监控端口30000,以及其IP地址和MAC地址了。


2.3 实例测试
以上配置就算完成了,让我来看一个实例吧。在被监控的主机上运行一个简单的hello world模块,看看我们的printk信息是怎样被发送到监控主机上去的。
模块helloworld源码:
hello.c
  1 /*hello.c*/
  2 #include <linux/kernel.h>
  3 #include <linux/init.h>
  4 #include <linux/module.h>
  5 MODULE_LICENSE("Dual BSD/GPL");
  6
  7 static int hello_init(void)
  8 {
  9         printk(KERN_ALERT "Hello World\n" );
10         return 0;
11 }
12 static void hello_exit(void)
13 {
14         printk(KERN_ALERT "Goodbye World\n" );
15 }
16
17 module_init(hello_init);
18 module_exit(hello_exit);


Makefile:
  1 obj-m:=hello.o
  2 KDIR:=/lib/modules/$(shell uname -r)/build
  3 PWD:=$(shell pwd)
  4
  5 default:
  6         $(MAKE) -C $(KDIR) M=$(PWD) modules
  7
  8 clean:
  9         $(RM) *.o *.mod.c *.ko *.symvers

执行:
# make
# insmod hello.ko
在监控机的终端上,我们看到以下信息:
netconsole: network logging started
Hello World
第一条是我们先前加载netconsole模块时收到的,第二条是我们加载helloworld模块时收到的。
再运行rmmod hello
监控机终端上将看到:
netconsole: network logging started
Hello World
Goodbye World

OK,以上测试顺利完成,当然,我们也可以测试kernel panic的情况,例如操作一个内核的非法地址等。下面,我们开始来分析内核源码的netconsole的实现。
0 0
原创粉丝点击