• 正文
  • 相关推荐
申请入驻 产业图谱

【调试】netconsole的使用

06/30 15:01
663
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

开发环境

客户端

开发板:FireFly-RK3399

Linux 4.4

IP:192.168.137.110

服务端

VMware Workstation Pro16,ubuntu 18.04

IP:192.168.137.100

MAC:00:0c:29:c1:9c:ed

netconsole简介

netconsole模块可以让printk信息(输出到控制台的信息)通过网络(UDP)发送到远程主机。

与串口控制台不同,netconsole不需要串口线和串口。另外,它可以轻易地将多台服务器的内核信息收集到一台服务器上。

当设备上串口无法使用时,使用netconsole将日志信息保存到远程主机更方便、可行。

netconsole模块不能用于获取crash dump,也不能进行一般的控制台输入输出。

netconsole模块不能获得网络相关的kernel panic,以及与操作系统启动到网络和netconsole模块启动之间发生的pnic相关的内核信息。

netconsole编译

netconsole 可以独立编译为模块手动加载,也可以编译进内核自动加载,本例使用的是第一种。

编译为独立模块

netconsole默认是没有编译进内核,需要手动编译到内核或编译成模块。

在内核目录下执行make menuconfig 开启以下选项

Device?Drivers?>?Network?device?support>Network?console?logging?support

将内核重新编译后烧写到开发板上。

手动编译netconsole模块

make?CONFIG_NETCONSOLE=m??-C?/home/zhongyi/code/rk3399_linux_release_v2.5.1_20210301/kernel???M=/home/zhongyi/code/rk3399_linux_release_v2.5.1_20210301/kernel/drivers/net??modules?CROSS_COMPILE=/home/zhongyi/code/rk3399_linux_release_v2.5.1_20210301/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-

之后,就会在模块目录下生成netconsole.ko的文件,这个文件就是我们所需的。

将netconsole编译进内核

如自定义内核启用netconsole只需将以下内核选项打开即可(编译为模块).

CONFIG_NETCONSOLE=m
CONFIG_NETCONSOLE_DYNAMIC=y

如果将netconsole编译进内核自动加载,则需要在内核启动参数中传递进去,并且还要确保网卡驱动在netconsole驱动前加载。

netconsole加载

将netconsole.ko通过共享目录发送到开发板,给予权限,这个需要预先知道服务端的IP地址以及MAC地址

日志服务器在同一内网, 直接通过ping获取服务器目的MAC:

$?ping?-c?1?192.168.1.103?>?/dev/null
$?arp?-n?192.168.1.103
?Address??????????????????HWtype??HWaddress???????????Flags?Mask????????????Iface
?192.168.1.103????????????ether???08:00:46:d4:1d:82???C?????????????????????eth0
1234

日志服务器不在同一内网, 获取网关目的MAC:

$?netstat?-rn?|?grep?^0.0.0.0
?0.0.0.0?????????192.168.1.1?????0.0.0.0?????????UG????????0?0??????????0?eth0
$?ping?-c?1?192.168.1.1?>?/dev/null
$?arp?-n?192.168.1.1
?Address??????????????????HWtype??HWaddress???????????Flags?Mask????????????Iface
?192.168.1.1??????????????ether???00:0f:66:5b:2a:3c???C????????????????

执行加载指令

insmod?netconsole.ko?netconsole=6665@192.168.137.110/eth0,514@192.168.137.100/00:0c:29:c1:9c:ed

各个参数含义如下

netconsole=src-port]@[src-ip]/[],[tgt-port]@/[tgt-macaddr]
where?src-port??????source?for?UDP?packets?(defaults?to?6665)?????#开发板上的端口,省略的话默认为6665
src-ip????????source?IP?to?use?(interface?address)?????????????????#?开发板上的IP地址
dev???????????network?interface?(eth0)?????????????????????????????#开发板上使用的网卡设备名
tgt-port??????port?for?logging?agent?(6666)????????????????????????#目的机器的端口,省略的话默认为6666
tgt-ip????????IP?address?for?logging?agent?????????????????????????#目的机器的IP地址
tgt-macaddr???ethernet?MAC?address?for?logging?agent?(broadcast)???#目的机器的MAC地址

rsyslog服务端设置

开启514端口

客户端设置好了,配置rsyslog以在服务器模式下运行

sudo?vim?/etc/rsyslog.conf

取消注释udp和tcp端口绑定的行:

#?provides?UDP?syslog?reception
module(load="imudp")
input(type="imudp"?port="514")

#?provides?TCP?syslog?reception
module(load="imtcp")
input(type="imtcp"?port="514")

测试端口是否能通

???~?sudo?nc?-vuz?192.168.137.110?514
Connection?to?192.168.137.110?514?port?[udp/syslog]?succeeded!

创建接收模板

创建一个模板,指示rsyslog服务器如何存储传入的syslog消息,在GLOBAL DIRECTIVES部分之前添加模板:

$template?remote-incoming-logs,"/var/log/%HOSTNAME%/%fromhost-ip%-%$YEAR%-%$MONTH%-%$DAY%.log
*.*??remote-incoming-logs
&?~

收到的日志将使用上面的模板进行解析并存储在目录/var/log/中,文件命名遵循约定:%HOSTNAME%/%fromhost-ip%-%$YEAR%-%$MONTH%-%$DAY%.log

日志接收模板参数的含义可参考:https://www.dandelioncloud.cn/article/details/1517852831246839810

完成后保存并关闭文件。然后,使用以下命令检查Rsyslog配置是否存在语法错误:

rsyslogd?-f?/etc/rsyslog.conf?-N1

你应该看到以下输出:

rsyslogd:?version?8.32.0,?config?validation?run?(level?1),?master?config?/etc/rsyslog.conf
rsyslogd:?End?of?config?validation?run.?Bye.

配置启动文件

以root身份修改/etc/default/rsyslog启动配置文件

RSYSLOGD_OPTIONS="-m?0?-r"
    -r 选项以允许接受外来日志消息。-x 禁用掉dns记录项不够齐全或其他的日志中心的日志。-m 修改syslog的内部mark消息写入间隔时间(0为关闭)。例如-m 180,表示每隔180分钟(每天8次)在日志文件里增加一行时间戳消息。-h 默认情况下,syslog不会发送从远端接受过来的消息到其他主机,而使用该选项,则把该开关打开,所有接受到的信息都可根据syslog.conf中定义的@主机转发过去。

重启服务

重新启动rsyslog服务以使更改生效:

sudo?systemctl?restart?rsyslog

确认服务是否正在侦听已配置的端口:

ss?-tunelp?|?grep?514
udp????UNCONN???0????????0?????????????????0.0.0.0:514????????????0.0.0.0:*??????ino:178435?sk:2c?<->???????????????????????????????????????????????????????????
udp????UNCONN???0????????0????????????????????[::]:514???????????????[::]:*??????ino:178436?sk:2d?v6only:1?<->??????????????????????????????????????????
tcp????LISTEN???0????????25????????????????0.0.0.0:514????????????0.0.0.0:*??????ino:178439?sk:2e?<->???????????????????????????????????????????????????????????
tcp????LISTEN???0????????25???????????????????[::]:514???????????????[::]:*??????ino:178440?sk:2f?v6only:1?<->???

配置Rsyslog防火墙

如果你的ufw防火墙服务正在运行,请允许rsyslog防火墙端口:

sudo?ufw?allow?514/tcp
sudo?ufw?allow?514/udp

输出测试

测试使用的是SysRq键在客户端输出内核信息。

在开发板上,修改/etc/sysctl.conf启动SysRq。

kernel.sysrq=1

执行下列命令,使修改生效。

sysctl?-p

执行下列命令向控制台输出内核信息。

root@firefly:~/mnt/module#?echo?h?>?/proc/sysrq-trigger?
[10224.626165]?sysrq:?SysRq?:?HELP?:?loglevel(0-9)?reboot(b)?crash(c)?terminate-all-tasks(e)?memory-full-oom-kill(f)?kill-all-tasks(i)?thaw-filesystems(j)?sak(k)?show-backtrace-all-active-cpus(l)?show-memory-usage(m)?nice-all-RT-tasks(n)?poweroff(o)?show-registers(p)?show-all-timers(q)?unraw(r)?sync(s)?show-task-states(t)?unmount(u)?force-fb(V)?show-blocked-tasks(w)?dump-ftrace-buffer(z)?

在服务器的/var/log/192.168.137.110目录下即可看到生成的日志文件。

???192.168.137.110?cat?192.168.137.110-2022-10-16.log?
2022-10-16T22:35:54.777180+08:00?192.168.137.110??[10224.626165]?sysrq:?SysRq?:?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?loglevel(0-9)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110??[10224.626165]?sysrq:?SysRq?:?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?loglevel(0-9)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?reboot(b)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?crash(c)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?reboot(b)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?crash(c)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?terminate-all-tasks(e)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?terminate-all-tasks(e)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?memory-full-oom-kill(f)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?memory-full-oom-kill(f)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?kill-all-tasks(i)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?kill-all-tasks(i)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?thaw-filesystems(j)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?thaw-filesystems(j)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?sak(k)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?sak(k)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?show-backtrace-all-active-cpus(l)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?show-backtrace-all-active-cpus(l)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?show-memory-usage(m)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?show-memory-usage(m)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?nice-all-RT-tasks(n)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?nice-all-RT-tasks(n)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?poweroff(o)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?poweroff(o)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?show-registers(p)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?show-registers(p)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?show-all-timers(q)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?show-all-timers(q)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?unraw(r)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?unraw(r)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?sync(s)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?sync(s)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?show-task-states(t)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?show-task-states(t)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?unmount(u)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?unmount(u)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?force-fb(V)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?force-fb(V)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?show-blocked-tasks(w)?
2022-10-16T22:35:54.777180+08:00?192.168.137.110?show-blocked-tasks(w)?
2022-10-16T22:35:54.900989+08:00?192.168.137.110?dump-ftrace-buffer(z)?
2022-10-16T22:35:54.900989+08:00?192.168.137.110?dump-ftrace-buffer(z)?
2022-10-16T22:35:54.900989+08:00?192.168.137.110??

若进入192.168.137.110目录无权限,则执行 sudo chmod 777 192.168.137.110 赋予权限。

其他监听方法

netcat

在没有syslogd在运行的主机上可以使用 netcat/socat 接收来自远程主机的消息:

nc?-u?-l?-p?<port>?/?nc?-u?-l?<port>
netcat?-u?-l?-p?<port>?/?netcat?-u?-l?<port>
socat?udp-recv:<port>?-

举例

~?sudo??netcat?-l?-p?514?-u?
[sudo]?password?for?zhongyi:?
[??263.748032]?sysrq:?SysRq?:?HELP?:?[??263.748032]?sysrq:?SysRq?:?HELP?:?loglevel(0-9)?loglevel(0-9)?reboot(b)?reboot(b)?crash(c)?crash(c)?terminate-all-tasks(e)?terminate-all-tasks(e)?memory-full-oom-kill(f)?memory-full-oom-kill(f)?kill-all-tasks(i)?kill-all-tasks(i)?thaw-filesystems(j)?thaw-filesystems(j)?sak(k)?sak(k)?show-backtrace-all-active-cpus(l)?show-backtrace-all-active-cpus(l)?show-memory-usage(m)?show-memory-usage(m)?nice-all-RT-tasks(n)?nice-all-RT-tasks(n)?poweroff(o)?show-registers(p)?poweroff(o)?show-registers(p)?show-all-timers(q)?show-all-timers(q)?unraw(r)?sync(s)?show-task-states(t)?unraw(r)?sync(s)?show-task-states(t)?unmount(u)?force-fb(V)?unmount(u)?force-fb(V)?show-blocked-tasks(w)?show-blocked-tasks(w)?dump-ftrace-buffer(z)?dump-ftrace-buffer(z)?

dmesg

-n/--console-level 控制kernel message console 输出级别, 设置输出level为debug(-n 8):

dmesg?-n?8

uboot中的netconsole

uboot下的netconsole类似于kernel下的telnet等网络终端功能,将网络作为输入输出的终端,这样就便于我们在PC端通过网络登录设备uboot中运行命令。

uboot下netconsole的实现在drivers/net/netconsole.c中,uboot开启netconsole只需要在配置文件configs/firefly-rk3399_defconfig加入CONFIG_NETCONSOLE=y ?即可。重新编译uboot,烧写到设备上。

设置环境变量nc,设置CONFIG_NETCONSOLE_BUFFER_SIZE覆盖默认缓冲区大小,设置环境变量ncip通信对端ip,格式为<ip_addr>:<port><port>不设置时为默认值6666,发送端口和接收端口可以分别设置,ncinportncoutport

setenv?ipaddr?192.168.137.110
setenv?nc?'setenv?stdout?nc;setenv?stdin?nc'
setenv?ncip?192.168.137.100
saveenv
run?nc

uboot进入netonsole模式,此时串口控制台就没有输出了。

在服务器上执行

./tools/netconsole?192.168.137.110

就可以在PC端运行uboot命令了。

相关推荐

登录即可解锁
  • 海量技术文章
  • 设计资源下载
  • 产业链客户资源
  • 写文章/发需求
立即登录

作者就职于某500强公司,担任BSP工程师。具有丰富的嵌入式开发经验。专栏主要分享计算机基础,操作系统,Linux驱动开发,Arm体系与架构,C/C++,数据结构与算法等相关文章。欢迎关注我的公众号【嵌入式与Linux那些事】,一起学习交流。