定义
pstore 是 Linux 内核提供的一个持久化存储子系统, 也是以 pstore 为类型名挂载的一个文件系统[1][2]。其启用由内核配置项 CONFIG_PSTORE 控制, 该选项开启后, 平台层驱动可以向 pstore 注册, 由 pstore 提供一层通用接口, 展示在崩溃瞬间被捕获的记录[2]。
它并不自己实现底层存储, 而是把不同平台各自的非易失存储抽象成统一的读写模型, 因此既可用于服务器, 也可用于嵌入式设备与云主机[1]。挂载后典型路径为 /sys/fs/pstore, 早期文档中也写作 /dev/pstore[4]。
原理
pstore 采用前端与后端分离的模型。后端负责实际存储介质, 例如 ACPI ERST、UEFI 变量、RAM 缓冲等, 平台驱动调用 pstore_register() 注册并传入 pstore_info 结构, 其中包含读、写、擦除三类操作入口和一个缓冲区[3]。前端则决定写入什么内容, 包括内核 Oops 处理器、控制台输出, 以及 ftrace 前端, 后者按 CPU 记录并在重启后重建事件[5]。
记录以类型区分, dmesg 表示保存的控制台日志, mce 表示致命硬件错误产生的架构相关数据, 文件名由类型、后端名与记录编号组合而成[4]。挂载参数 kmsg_bytes 控制每次 oops 或 panic 时希望保存的数据量, 默认值为 10 KiB; 文件被读取后删除即通知底层存储回收空间[4]。
同一时刻 pstore 只支持一个后端处于工作状态; 当系统存在多个可用后端时, 可在启动时通过内核参数 pstore.backend= 指定首选后端[4]。数据可采用 deflate、zstd 等算法压缩后写入, 相关压缩接口在 2022 年曾因向后兼容问题被回退[6]。
发展历程
pstore 的构想源于 Tony Luck 与 Thomas Gleixner 在 Linux Plumbers Conference 上的讨论, 目标是借助 ACPI 错误记录序列化表(ERST)把崩溃信息保存到非易失位置, 并跨越重启传递[3]。Luck 没有只为 x86 架构做定制实现, 而是设计了面向各平台的通用框架, 用于把数十到数百 KiB 的崩溃现场数据交给下一次启动的内核[3]。
在 Alan Cox 建议下, 实现方案由最初的固件驱动加 sysfs 接口, 改为更直接的基于文件系统的形式[3]。该子系统在 2011 年的 2.6.39 合并窗口中被并入内核, 同期修改后的 ERST 驱动成为它的第一个内核内使用者[3][4]。
2011 年 6 月出现了以 EFI 变量作为后端的补丁, 使固件管理的非易失区域也能存放 oops 记录[7]。此后 systemd 加入 systemd-pstore 服务, 在启动时把 pstore 内容归档到日志与磁盘目录并清空原存储, 以便后续崩溃仍能写入[1]。
应用
pstore 最主要的用途是事后调试。内核在 panic 或 oops 时把控制台日志尾部连同栈回溯写入持久区域, 重启后由用户空间读取分析[1]。它完全本地化, 不依赖网络与远程文件系统, 因此在 iSCSI、NFS 等远端根文件系统的云环境中, 仍能提供一条保存错误记录的路径, 这一点与依赖网络可用的 kdump 机制不同[1]。
RAM 后端(ramoops)是常见的实现方式, 它把 panic 与 oops 消息写入内存中的环形缓冲区, 借助 Reed-Solomon 纠错码保护数据, 以便在稍后读回, 其内核模块沿用历史名称为 ramoops.ko[2][5]。用户空间消息也可记录, 启用相应选项后内核导出字符设备 /dev/pmsg0, 重启后可从 pstore 文件系统中取回[2]。
systemd 的归档服务在启动时读取 pstore.conf 配置, 处理 /sys/fs/pstore/ 目录内容, 将其写入日志, 并可选地保存到 /var/lib/systemd/pstore/[1]。控制写入时机的两个内核参数分别是 crash_kexec_post_notifiers 与 always_kmsg_dump, 前者用于 panic 时记录日志, 后者用于正常关机与重启时记录[1]。
局限
pstore 后端的持久存储容量通常很小, 例如约 64 KiB, 记录很快会被写满, 一旦空间耗尽, 后续内核崩溃就无法再写入错误信息, 因此需要外部机制及时监控并转存其中的内容[1]。
同一时刻只允许一个后端工作, 是这一子系统的结构性限制; 若系统同时存在多个后端, 只能通过启动参数指定其一, 其余后端会被忽略[4]。在实际设备上也出现过后端选择冲突, 例如日志中出现已注册 efi_pstore 而忽略 ramoops, 或反向忽略 efi 后端的提示[8]。
压缩路径也带来兼容性问题。内核改用 crypto acomp 接口后, efi_pstore 与 ramoops 在使用 zstd、lz4、lzo 等算法时无法正确解压 dmesg, 只有 deflate 正常, 该改动最终被回退[6]。此外, 若崩溃时采用的压缩算法与之后读取时所选算法不一致, 旧记录可能无法解开[9]。
参见
参考资料
- systemd-pstore.service.8.en [引用日期2026-10-14]
- fs/pstore/Kconfig [引用日期2026-10-14]
- lwn.net 上的网页 [引用日期2026-10-14]
- linux/pstore 位于 a787bdaff83a085288b6fc607afb4bb648da3cc9 [引用日期2026-10-14]
- lkml.org 上的网页 [引用日期2026-10-14]
- pstore [引用日期2026-10-14]
- iu.edu 上的网页 [引用日期2026-10-14]
- launchpad.net 上的网页 [引用日期2026-10-14]
- iu.edu 上的网页 [引用日期2026-10-14]