久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

Linux pstore實現自動“抓捕”內核崩潰日志實例分析

234次閱讀
沒有評論

共計 6862 個字符,預計需要花費 18 分鐘才能閱讀完成。

今天就跟大家聊聊有關 Linux pstore 實現自動“抓捕”內核崩潰日志實例分析,可能很多人都不太了解,為了讓大家更加了解,丸趣 TV 小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。

簡介

pstore 文件系統 (是的,這是個文件系統) 是 Persistent Storage 的縮寫,最早在 2010 年由 Tony Luck   設計并合入 Linux 主分支,設計的初衷是在內核 Panic/Oops 時能自動轉存內核日志(log_buf),在 Panic 重啟后,把轉存的日志以文件形式呈現到用戶空間以分析內核崩潰問題。

這對分析那種小概率且沒辦法抓到現場的問題非常實用,尤其是現在智能互聯網的設備逐漸普及的時候,遠端的設備可以自己捕抓崩潰日志再通過網絡傳輸到服務器,維護人員就可以根據收集來的日志定位和解決問題,然后通過 OTA 讓設備升級迭代。

根據網上搜尋的資料,在 pstore 文件系統之前其實有不少類似的實現。

apanic

Android 最早的 panic 信息記錄的方案。在 linux  2.6 的安卓的內核中找到,卻沒有提交到社區,后來被放棄維護了。網上找不到放棄的原因,我自己猜測是因為其只適用于 mtd  nand,然而現在的 Android 基本用的都是 emmc。apanic 應該是 Android Panic 的縮寫吧,可以實現在內核崩潰時,把日志轉存到 mtd  nand。

ramoops

這里指的是最早的 ramoops 實現,在最新代碼已經整合入 pstore 中,以 pstore/ram 的后端形式存在。ramoops 可以把日志轉存到重啟不掉電的 ram 中。這里對 ram 有一點要求,即使重啟 ram 的數據也不能丟失。

crashlog

這是 openwrt 提供的內核 patch,并沒有提交到內核社區。它也是基于 ram,只能轉存 Panic/Oops 的日志。

mtdoops

MTD 子系統支持的功能,與 pstore 非常相似,只支持轉存 Panic/Oops 日志,不能以文件呈現,需要用戶自行解析整個 MTD 分區。(因為功能的相似,我實現了 mtdpstore 用于替代 mtdoops)

kdump

如果說 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 的后端,是指轉存到什么類型的設備。

目前支持以下幾個前端:

dmesg:主要是轉存 Panic/Oops 時 log_buf 里面的內核日志

pmsg:提供給用戶空間存儲日志的入口,在 Android 里有看到被用于存儲系統的日志。

console:終端日志

ftrace:function trace 的信息

目前支持以下幾種后端:

pstore/ram:Persistent Ram,重啟不會丟數據的內存

pstore/blk:(v5.8 以后的版本)所有可寫的塊設備,例如磁盤、U 盤、emmc、NFTL nand 等

mtd device:(v5.8 以后的版本)mtd 設備,例如 mtd nand。(mtd 設備的支持依賴于 pstore/blk   后端,準確來說不是一種獨立后端)

怎么用

就像把大象裝入冰箱只需要打開冰箱,把大象放進去,關上冰箱門的 3 個步驟,使用 pstore 也只需要 3 個步驟:

使能 pstore

掛載 pstore 文件系統

讀取 轉存的日志文件

詳細的說明可以看源碼上的文檔,本文只做基本功能的介紹。

Documentation/admin-guide/ramoops.rst

Documentation/admin-guide/pstore-blk.rst

使能

在 menuconfig 中選擇內核 pstore 模塊

$ make menuconfig |-  File systems |-  Miscellaneous filesystems |-  Persistent store support |-  Log kernel console messages # console  前端  |-  Log user space messages # pmsg  前端  |-  Persistent function tracer # ftrace  前端  |-  Log panic/oops to a RAM buffer # pstore/ram  后端  |-  Log panic/oops to a block device # pstore/blk  后端

上述兩個后端 2 選 1 即可,前端就根據自己的需求選擇,至于 dmesg 前端,默認使能沒得選。如果希望用在 mtd 設備上,還需要選擇 mtdpstore 模塊:

$ make menuconfig |-  Device Drivers |-  Memory Technology Device (MTD) support |-  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 中配置:

$ make menuconfig |-  File systems |-  Miscellaneous filesystems |-  Persistent store support |-  Log panic/oops to a block device # pstore/blk  后端  |-  () block device identifier #  使用哪個塊設備?

如果使用 cmdline,可以這么寫:

pstore_blk.blkdev=XXXX

或者以模塊加載:

$ sudo insmod pstore_blk.ko blkdev=XXX

這里的塊設備可以是代表整個磁盤的 sda,也可以是代表某個分區的 mmcblk0p4。雖然支持 7 種變體,但常用的還是兩種:

/dev/ disk_name : 例如,使用 U 盤的第 2 個分區,則是 /dev/sdb2

major : minor:例如,mmc 設備第 6 個分區,則是 179:6

形式大概是這樣:

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

或者

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

如果是 mtd 設備,可以直接指定 mtd 分區名或者編號,例如:

pstore_blk.blkdev=pstore #  假設存在名為 pstore 的 MTD 分區

OK,對新同學來說,到這里配置就夠了。可以從我的 github(見參考鏈接 [2]) 上看到我之前是怎么測試的。如果需要知道每個配置項的作用,還是看內核文檔吧(ramoops.rst   或 pstore_blk.rst),或者在 Kconfig 中按 h 顯示相關配置項的說明。

掛載

在使能且正確配置設備后,啟動的時候應該會有這樣的日志:

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

這代表 pstore 找到了設備且正常注冊。接下來,我們還需要通過掛載的形式觸發 pstore 從設備讀取數據。常見的掛載是這樣的:

mount -t pstore pstore /sys/fs/pstore

掛載后,通過 mount 能看到類似這樣的信息:

# mount ... pstore on /sys/fs/pstore type pstore (rw,relatime) ...

如果曾經觸發過崩潰日志,在掛載點應該有類似這樣的文件:

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

如果需要驗證,咱們可以這樣主動觸發內核崩潰:

# echo c   /proc/sysrq-trigger

我是在 U 盤、SD 卡、mmc、nand 上驗證的,maintainer Kees Cook   提供了另外一種基于 loop 的驗證方法,實現用文件模擬塊設備。當然這方法不適用于轉存 Panic 日志,只能用于 Oops 或者其他前端:

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

讀取

經過上述的掛載后,可以在掛載點看到轉存的日志文件。既然是文件,肯定支持文件的一系列操作,例如讀取、刪除。

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

對 dmesg 前端的 Panic/Oops 日志,pstore 會自動添加兩行統計信息。例如:

Oops: Total 2 times #  表示觸發了 Oops,且是自系統安裝后第一次啟動以來第 2 次觸發 Oops。 Oops#1 Part1 #  表示這是上一次運行期間第 1 次觸發 Oops 的日志。

可以發現,第一行是累計總的觸發次數,第二行是上一次啟動觸發的次數。

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

當然,除了 dmesg 前端外,其他前端的名字大概是這樣的:

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

除此之外,每個文件的時間戳表示 崩潰觸發的時間。上例中,由于系統并沒有實現同步更新系統時間,所以時間戳不合理。

展望未來

正如我前文說的,pstore 在物聯網設備逐漸普及的現在,能發揮很大的作用,例如智能音箱和掃地機已經用起來了。

全功能支持

到目前為止,不管是塊設備還是 mtd 設備,社區的代碼都沒能做到 pstore 的全部前端的支持。

設備 dmesg(Oops)dmesg(Panic)pmsgconsoleftrace 塊設備 YNYYYMTD 設備 YYNNNram 設備 YYYYY

塊設備如果需要記錄 Panic 日志,需要提供一個在 Panic 時寫塊設備的接口。我在全志的 mmc 和 nand 驅動中實現了這樣的接口,卻因為種種原因不適合提交到社區。社區塊驅動的適配寄希望于更多同學的努力了。

MTD 設備很早前就有了 panic_write()的定義,因此可以支持 Panic 日志轉存。不支持其他前端,則是因為其擦寫的物理特性。對 pmsg,console,ftrace 等這些不能頁對齊寫入的前端,還需要更多的適配工作。

遷移 pstore/ram

在當前 pstore 的目錄結構是這樣的:

$ tree fs/pstore fs/pstore/ ├── blk.c # pstore/blk  后端的實現  ├── ftrace.c # ftrace  前端的實現  ├── inode.c # pstore  文件系統的注冊與操作  ├── internal.h ├── Kconfig ├── Makefile ├── platform.c # pstore  前后端功能的核心  ├── pmsg.c # pmsg  前端的實現  ├── ram.c # pstore/ram  后端的實現  ├── ram_core.c # pstore/ram  后端的實現  └── zone.c # pstore/zone  實現存儲空間的分配和管理

在我的補丁之前,只支持轉存日志到 ram,因此如果研讀代碼,我們會發現 ram.c 和 ram_core.c 實現了兩部分功能:

dram 空間分配與管理

dram 的讀寫操作

我實現的 blk.c 支持了轉存到塊設備。但是后來發現不管 pstore/ram 還是 pstore/blk,他們對于存儲空間的分配和管理極度相似,我就提煉出了 pstore/zone。于是乎,期望的代碼層次應該是這樣的:

pstore/ram 要整合入 pstore/zone 已經與 maintainer 達成共識,但還需要更多同學一同努力做更多兼容,例如 ecc 的支持。

看完上述內容,你們對 Linux pstore 實現自動“抓捕”內核崩潰日志實例分析有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注丸趣 TV 行業資訊頻道,感謝大家的支持。

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-08-04發表,共計6862字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 礼泉县| 苏尼特右旗| 兴化市| 鹰潭市| 盐源县| 和田县| 张家口市| 土默特右旗| 洛宁县| 张家界市| 弥勒县| 大余县| 平乡县| 华蓥市| 瓦房店市| 花莲市| 漠河县| 松滋市| 长治县| 泰和县| 资阳市| 霸州市| 博兴县| 博罗县| 中超| 新巴尔虎左旗| 内黄县| 汶上县| 梅州市| 宜兴市| 邛崃市| 钟祥市| 修文县| 湖南省| 上饶县| 新乡县| 汉中市| 阳江市| 手游| 和林格尔县| 平谷区|