文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Linux pstore 实现自动“抓捕”内核崩溃日志

2024-12-11 21:59

关注

[[329610]]

简介

pstore文件系统(是的,这是个文件系统)是Persistent Storage的缩写,最早在2010年由 Tony Luck 设计并合入Linux主分支,设计的初衷是在内核Panic/Oops时能自动转存内核日志(log_buf),在Panic重启后,把转存的日志以文件形式呈现到用户空间以分析内核崩溃问题。

这对分析那种小概率且没办法抓到现场的问题非常实用,尤其是现在智能互联网的设备逐渐普及的时候,远端的设备可以自己捕抓崩溃日志再通过网络传输到服务器,维护人员就可以根据收集来的日志定位和解决问题,然后通过OTA让设备升级迭代。

根据网上搜寻的资料,在pstore文件系统之前其实有不少类似的实现。

Android最早的panic信息记录的方案。在linux 2.6的安卓的内核中找到,却没有提交到社区,后来被放弃维护了。网上找不到放弃的原因,我自己猜测是因为其只适用于mtd nand,然而现在的Android基本用的都是emmc。apanic应该是Android Panic的缩写吧,可以实现在内核崩溃时,把日志转存到mtd nand。

这里指的是最早的ramoops实现,在最新代码已经整合入pstore中,以pstore/ram的后端形式存在。ramoops可以把日志转存到重启不掉电的ram中。这里对ram有一点要求,即使重启ram的数据也不能丢失。

这是openwrt提供的内核patch,并没有提交到内核社区。它也是基于ram,只能转存Panic/Oops的日志。

MTD子系统支持的功能,与pstore非常相似,只支持转存Panic/Oops日志,不能以文件呈现,需要用户自行解析整个MTD分区。(因为功能的相似,我实现了mtdpstore用于替代mtdoops)

如果说pstore是个轻量级的内核崩溃日志转存的方案,kdump则是一个重量级的问题分析工具。在崩溃时,由kdump产生一个用于捕抓当前信息的内核,该内核会收集内存所有信息到dump core文件中。在重启后,捕抓到的信息保存在特定的文件中。类似的还有netdump和diskdump。kdump的方案适用于服务器这种有大量资源的设备,功能也非常强大,但对嵌入式设备非常不友好。

pstore经过长期迭代,除了转存Panic/Oops的日志之外(dmesg前端),还支持pmsg、console和ftrace的前端,除了pstore/ram的后端之外,还有我设计的pstore/blk后端,除了支持转存到ram之外,还有block device和mtd device。

pstore的前端,是指转存的日志类型,pstore的后端,是指转存到什么类型的设备。

目前支持以下几个前端:

目前支持以下几种后端:

怎么用

就像把大象装入冰箱只需要打开冰箱,把大象放进去,关上冰箱门的3个步骤,使用pstore也只需要3个步骤:

详细的说明可以看源码上的文档,本文只做基本功能的介绍。

Documentation/admin-guide/ramoops.rst

Documentation/admin-guide/pstore-blk.rst

使能

在menuconfig中选择内核pstore模块

  1. $ make menuconfig 
  2.   |-> File systems 
  3.     |-> Miscellaneous filesystems 
  4.       |-> Persistent store support 
  5.         |-> Log kernel console messages    # console 前端 
  6.         |-> Log user space messages      # pmsg 前端 
  7.         |-> Persistent function tracer      # ftrace 前端 
  8.         |-> Log panic/oops to a RAM buffer     # pstore/ram 后端 
  9.         |-> Log panic/oops to a block device   # pstore/blk 后端 

上述两个后端2选1即可,前端就根据自己的需求选择,至于dmesg前端,默认使能没得选。如果希望用在mtd设备上,还需要选择mtdpstore模块:

  1. $ make menuconfig 
  2.   |-> Device Drivers 
  3.     |-> Memory Technology Device (MTD) support 
  4.       |-> Log panic/oops to an MTD buffer based on pstore 

选上就可以用了?虽然我非常想说“是的”,但事实却有点“骨感”。即使所有前端都使用默认配置,pstore/ram至少也需要知道可用的内存范围吧?pstore/blk至少也需要知道使用哪个块设备吧?

pstore/ram支持 模块参数(cmdline)、设备树、和Platform Data的3种配置方式,从代码来看,优先级关系是:模块参数 > Platform Data > 设备树。

pstore/blk支持 Kconfig和 模块参数(cmdline)的两种配置方式,且模块参数比Kconfig有更高的优先级。

pstore/ram我接触也不多,直接介绍pstore/blk的使用方法。对新同学来说,请忽略一大堆乱七八糟的属性配置(使用默认值),只需要告诉pstore/blk后端使用哪个块设备即可。

在Kconfig中配置:

  1. $ make menuconfig 
  2.   |-> File systems 
  3.     |-> Miscellaneous filesystems 
  4.       |-> Persistent store support 
  5.         |-> Log panic/oops to a block device   # pstore/blk 后端 
  6.           |-> () block device identifier      # 使用哪个块设备? 

如果使用cmdline,可以这么写:

  1. pstore_blk.blkdev=XXXX 

或者以模块加载:

  1. $ sudo insmod pstore_blk.ko blkdev=XXX 

这里的块设备可以是代表整个磁盘的sda,也可以是代表某个分区的mmcblk0p4。虽然支持7种变体,但常用的还是两种:

形式大概是这样:

  1. $ sudo insmod pstore_blk.ko blkdev=/dev/sdb2 

或者

  1. $ cat /proc/cmdline 
  2. .... pstore_blk.blkdev=179:6 ... 

如果是mtd设备,可以直接指定mtd分区名或者编号,例如:

  1. pstore_blk.blkdev=pstore  # 假设存在名为pstore的MTD分区 

OK,对新同学来说,到这里配置就够了。可以从我的github(见参考链接[2])上看到我之前是怎么测试的。如果需要知道每个配置项的作用,还是看内核文档吧(ramoops.rst 或 pstore_blk.rst),或者在Kconfig中按h显示相关配置项的说明。

挂载

在使能且正确配置设备后,启动的时候应该会有这样的日志:

  1. pstore_zone: registered pstore_blk as backend for kmsg(Oops,panic_write) 
  2. pstore: Registered pstore_blk as persistent store backend 

这代表pstore找到了设备且正常注册。接下来,我们还需要通过挂载的形式触发pstore从设备读取数据。常见的挂载是这样的:

  1. mount -t pstore pstore /sys/fs/pstore 

挂载后,通过mount能看到类似这样的信息:

  1. # mount 
  2. ... 
  3. pstore on /sys/fs/pstore type pstore (rw,relatime) 
  4. ... 

如果曾经触发过崩溃日志,在挂载点应该有类似这样的文件:

  1. # ll /sys/fs/pstore 
  2. ... 
  3. -r--r--r--    1 root     root         15521 Jan  1 00:06 dmesg-pstore_blk-0 
  4. ... 

如果需要验证,咱们可以这样主动触发内核崩溃:

  1. # echo c > /proc/sysrq-trigger 

我是在U盘、SD卡、mmc、nand上验证的,maintainer Kees Cook 提供了另外一种基于loop的验证方法,实现用文件模拟块设备。当然这方法不适用于转存Panic日志,只能用于Oops或者其他前端:

  1. # insmod pstore.ko compress=off 
  2. # insmod pstore_zone.ko 
  3. truncate pstore-blk.raw --size 100M 
  4. # losetup -f --show pstore-blk.raw 
  5. /dev/loop0 
  6. # insmod pstore_blk.ko blkdev=/dev/loop0 kmsg_size=16 console_size=64 best_effort=on 

读取

经过上述的挂载后,可以在挂载点看到转存的日志文件。既然是文件,肯定支持文件的一系列操作,例如读取、删除。

  1. root@TinaLinux:/sys/fs/pstore# head -n 10 dmesg-pstore_blk-1 
  2. Oops: Total 2 times 
  3. Oops#1 Part1 
  4. <6>[    2.743794] Bluetooth: RFCOMM socket layer initialized 
  5. <6>[    2.743813] Bluetooth: RFCOMM ver 1.11 
  6. <6>[    2.743822] 8021q: 802.1Q VLAN Support v1.8 
  7. <3>[    2.751766] reg-virt-consumer reg-virt-consumer.1: Failed to obtain supply 'drivevbus': -517 
  8. <3>[    2.752330] reg-virt-consumer reg-virt-consumer.1: Failed to obtain supply 'drivevbus': -517 
  9. <5>[    2.752742] ubi0: attaching mtd4 
  10. <5>[    2.890302] random: crng init done 
  11. <5>[    2.965927] ubi0: scanning is finished 
  12.  
  13. root@TinaLinux:/sys/fs/pstore# ll 
  14. drwxr-x---    2 root     root             0 Jan  1 00:11 . 
  15. drwxr-xr-x    5 root     root             0 Jan  1 00:11 .. 
  16. -r--r--r--    1 root     root         15521 Jan  1 00:06 dmesg-pstore_blk-0 
  17. -r--r--r--    1 root     root         15128 Jan  1 00:11 dmesg-pstore_blk-1 
  18.  
  19. root@TinaLinux:/sys/fs/pstore# rm dmesg-pstore_blk-1 
  20.  
  21. root@TinaLinux:/sys/fs/pstore# ll 
  22. drwxr-x---    2 root     root             0 Jan  1 00:13 . 
  23. drwxr-xr-x    5 root     root             0 Jan  1 00:11 .. 
  24. -r--r--r--    1 root     root         15521 Jan  1 00:06 dmesg-pstore_blk-0 

对dmesg前端的Panic/Oops日志,pstore会自动添加两行统计信息。例如:

  1. Oops: Total 2 times      # 表示触发了Oops,且是自系统安装后第一次启动以来第2次触发Oops。 
  2. Oops#1 Part1        # 表示这是上一次运行期间第1次触发Oops的日志。 

可以发现,第一行是累计总的触发次数,第二行是上一次启动触发的次数。

每个文件名的格式都是<前端名>-<后端名>-,例如dmesg-pstore_blk-1表示dmesg前端,pstore_blk后端以及是dmesg前端的第1个zone的日志。

当然,除了dmesg前端外,其他前端的名字大概是这样的:

  1. # ll 
  2. -r--r--r-- 1 root root    31 1月  15 11:53 console-pstore-blk-0 
  3. -r--r--r-- 1 root root  3666 1月  15 11:53 demsg-pstore-blk-0 
  4. -r--r--r-- 1 root root 65524 1月  15 11:53 ftrace-pstore-blk-0 
  5. -r--r--r-- 1 root root     9 1月  15 11:53 pmsg-pstore-blk-0 

除此之外,每个文件的时间戳表示 崩溃触发的时间。上例中,由于系统并没有实现同步更新系统时间,所以时间戳不合理。

展望未来

正如我前文说的,pstore在物联网设备逐渐普及的现在,能发挥很大的作用,例如智能音箱和扫地机已经用起来了。

全功能支持

到目前为止,不管是块设备还是mtd设备,社区的代码都没能做到pstore的全部前端的支持。

设备 dmesg(Oops) dmesg(Panic) pmsg console ftrace
块设备 Y N Y Y Y
MTD设备 Y Y N N N
ram设备 Y Y Y Y Y

块设备如果需要记录Panic日志,需要提供一个在Panic时写块设备的接口。我在全志的mmc和nand驱动中实现了这样的接口,却因为种种原因不适合提交到社区。社区块驱动的适配寄希望于更多同学的努力了。

MTD设备很早前就有了panic_write()的定义,因此可以支持Panic日志转存。不支持其他前端,则是因为其擦写的物理特性。对pmsg,console,ftrace等这些不能页对齐写入的前端,还需要更多的适配工作。

迁移pstore/ram

在当前pstore的目录结构是这样的:

  1. $ tree fs/pstore 
  2. fs/pstore/ 
  3. ├── blk.c      # pstore/blk 后端的实现 
  4. ├── ftrace.c    # ftrace 前端的实现 
  5. ├── inode.c    # pstore 文件系统的注册与操作 
  6. ├── internal.h 
  7. ├── Kconfig 
  8. ├── Makefile 
  9. ├── platform.c    # pstore 前后端功能的核心 
  10. ├── pmsg.c    # pmsg 前端的实现 
  11. ├── ram.c      # pstore/ram 后端的实现 
  12. ├── ram_core.c    # pstore/ram 后端的实现 
  13. └── zone.c      # pstore/zone 实现存储空间的分配和管理 

在我的补丁之前,只支持转存日志到ram,因此如果研读代码,我们会发现ram.c和ram_core.c实现了两部分功能:

  1. dram空间分配与管理
  2. dram的读写操作

我实现的blk.c支持了转存到块设备。但是后来发现不管pstore/ram还是pstore/blk,他们对于存储空间的分配和管理极度相似,我就提炼出了pstore/zone。于是乎,期望的代码层次应该是这样的:

 

 

 

 

pstore/ram要整合入pstore/zone已经与maintainer达成共识,但还需要更多同学一同努力做更多兼容,例如ecc的支持。

参考

https://git.kernel.org/torvalds/c/829f3b9401fe7cc3c1f3642bb2520751a42a87dfhttps://github.com/gmpy/articles/blob/master/pstore/Test-Pstore-Block.md

本文转载自微信公众号「 Linux阅码场」,可以通过以下二维码关注。转载本文请联系 Linux阅码场公众号。

 

来源:Linux阅码场内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯