開發(fā)環(huán)境
客戶端
開發(fā)板:FireFly-RK3399
Linux 4.4
IP:192.168.137.110
服務(wù)端
VMware Workstation Pro16,ubuntu 18.04
IP:192.168.137.100
MAC:00:0c:29:c1:9c:ed
netconsole簡介
netconsole模塊可以讓printk信息(輸出到控制臺的信息)通過網(wǎng)絡(luò)(UDP)發(fā)送到遠(yuǎn)程主機(jī)。
與串口控制臺不同,netconsole不需要串口線和串口。另外,它可以輕易地將多臺服務(wù)器的內(nèi)核信息收集到一臺服務(wù)器上。
當(dāng)設(shè)備上串口無法使用時,使用netconsole將日志信息保存到遠(yuǎn)程主機(jī)更方便、可行。
netconsole模塊不能用于獲取crash dump,也不能進(jìn)行一般的控制臺輸入輸出。
netconsole模塊不能獲得網(wǎng)絡(luò)相關(guān)的kernel panic,以及與操作系統(tǒng)啟動到網(wǎng)絡(luò)和netconsole模塊啟動之間發(fā)生的pnic相關(guān)的內(nèi)核信息。
netconsole編譯
netconsole 可以獨(dú)立編譯為模塊手動加載,也可以編譯進(jìn)內(nèi)核自動加載,本例使用的是第一種。
編譯為獨(dú)立模塊
netconsole默認(rèn)是沒有編譯進(jìn)內(nèi)核,需要手動編譯到內(nèi)核或編譯成模塊。
在內(nèi)核目錄下執(zhí)行make menuconfig 開啟以下選項
Device?Drivers?>?Network?device?support>Network?console?logging?support
將內(nèi)核重新編譯后燒寫到開發(fā)板上。
手動編譯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編譯進(jìn)內(nèi)核
如自定義內(nèi)核啟用netconsole只需將以下內(nèi)核選項打開即可(編譯為模塊).
CONFIG_NETCONSOLE=m
CONFIG_NETCONSOLE_DYNAMIC=y
如果將netconsole編譯進(jìn)內(nèi)核自動加載,則需要在內(nèi)核啟動參數(shù)中傳遞進(jìn)去,并且還要確保網(wǎng)卡驅(qū)動在netconsole驅(qū)動前加載。
netconsole加載
將netconsole.ko通過共享目錄發(fā)送到開發(fā)板,給予權(quán)限,這個需要預(yù)先知道服務(wù)端的IP地址以及MAC地址。
日志服務(wù)器在同一內(nèi)網(wǎng), 直接通過ping獲取服務(wù)器目的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
日志服務(wù)器不在同一內(nèi)網(wǎng), 獲取網(wǎng)關(guān)目的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????????????????
執(zhí)行加載指令
insmod?netconsole.ko?netconsole=6665@192.168.137.110/eth0,514@192.168.137.100/00:0c:29:c1:9c:ed
各個參數(shù)含義如下
netconsole=src-port]@[src-ip]/[],[tgt-port]@/[tgt-macaddr]
where?src-port??????source?for?UDP?packets?(defaults?to?6665)?????#開發(fā)板上的端口,省略的話默認(rèn)為6665
src-ip????????source?IP?to?use?(interface?address)?????????????????#?開發(fā)板上的IP地址
dev???????????network?interface?(eth0)?????????????????????????????#開發(fā)板上使用的網(wǎng)卡設(shè)備名
tgt-port??????port?for?logging?agent?(6666)????????????????????????#目的機(jī)器的端口,省略的話默認(rèn)為6666
tgt-ip????????IP?address?for?logging?agent?????????????????????????#目的機(jī)器的IP地址
tgt-macaddr???ethernet?MAC?address?for?logging?agent?(broadcast)???#目的機(jī)器的MAC地址
rsyslog服務(wù)端設(shè)置
開啟514端口
客戶端設(shè)置好了,配置rsyslog以在服務(wù)器模式下運(yùn)行
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!
創(chuàng)建接收模板
創(chuàng)建一個模板,指示rsyslog服務(wù)器如何存儲傳入的syslog消息,在GLOBAL DIRECTIVES
部分之前添加模板:
$template?remote-incoming-logs,"/var/log/%HOSTNAME%/%fromhost-ip%-%$YEAR%-%$MONTH%-%$DAY%.log
*.*??remote-incoming-logs
&?~
收到的日志將使用上面的模板進(jìn)行解析并存儲在目錄/var/log/中,文件命名遵循約定:%HOSTNAME%/%fromhost-ip%-%$YEAR%-%$MONTH%-%$DAY%.log
。
日志接收模板參數(shù)的含義可參考:https://www.dandelioncloud.cn/article/details/1517852831246839810
完成后保存并關(guān)閉文件。然后,使用以下命令檢查Rsyslog配置是否存在語法錯誤:
rsyslogd?-f?/etc/rsyslog.conf?-N1
你應(yīng)該看到以下輸出:
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的內(nèi)部mark消息寫入間隔時間(0為關(guān)閉)。例如-m 180,表示每隔180分鐘(每天8次)在日志文件里增加一行時間戳消息。-h 默認(rèn)情況下,syslog不會發(fā)送從遠(yuǎn)端接受過來的消息到其他主機(jī),而使用該選項,則把該開關(guān)打開,所有接受到的信息都可根據(jù)syslog.conf中定義的@主機(jī)轉(zhuǎn)發(fā)過去。
重啟服務(wù)
重新啟動rsyslog服務(wù)以使更改生效:
sudo?systemctl?restart?rsyslog
確認(rèn)服務(wù)是否正在偵聽已配置的端口:
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防火墻服務(wù)正在運(yùn)行,請允許rsyslog防火墻端口:
sudo?ufw?allow?514/tcp
sudo?ufw?allow?514/udp
輸出測試
測試使用的是SysRq鍵在客戶端輸出內(nèi)核信息。
在開發(fā)板上,修改/etc/sysctl.conf
啟動SysRq。
kernel.sysrq=1
執(zhí)行下列命令,使修改生效。
sysctl?-p
執(zhí)行下列命令向控制臺輸出內(nèi)核信息。
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)?
在服務(wù)器的/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??
若進(jìn)入192.168.137.110目錄無權(quán)限,則執(zhí)行 sudo chmod 777 192.168.137.110
賦予權(quán)限。
其他監(jiān)聽方法
netcat
在沒有syslogd在運(yùn)行的主機(jī)上可以使用 netcat/socat 接收來自遠(yuǎn)程主機(jī)的消息:
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 輸出級別, 設(shè)置輸出level為debug
(-n 8
):
dmesg?-n?8
uboot中的netconsole
uboot下的netconsole類似于kernel下的telnet等網(wǎng)絡(luò)終端功能,將網(wǎng)絡(luò)作為輸入輸出的終端,這樣就便于我們在PC端通過網(wǎng)絡(luò)登錄設(shè)備uboot中運(yùn)行命令。
uboot下netconsole的實現(xiàn)在drivers/net/netconsole.c中,uboot開啟netconsole只需要在配置文件configs/firefly-rk3399_defconfig
加入CONFIG_NETCONSOLE=y
?即可。重新編譯uboot,燒寫到設(shè)備上。
設(shè)置環(huán)境變量nc
,設(shè)置CONFIG_NETCONSOLE_BUFFER_SIZE
覆蓋默認(rèn)緩沖區(qū)大小,設(shè)置環(huán)境變量ncip
為通信對端ip,格式為<ip_addr>:<port>
,<port>
不設(shè)置時為默認(rèn)值6666
,發(fā)送端口和接收端口可以分別設(shè)置,ncinport
和ncoutport
,
setenv?ipaddr?192.168.137.110
setenv?nc?'setenv?stdout?nc;setenv?stdin?nc'
setenv?ncip?192.168.137.100
saveenv
run?nc
uboot進(jìn)入netonsole模式,此時串口控制臺就沒有輸出了。
在服務(wù)器上執(zhí)行
./tools/netconsole?192.168.137.110
就可以在PC端運(yùn)行uboot命令了。