/proc 和 /sys 是内核暴露信息到用户态的两大文件系统——一个历史悠久但混乱,一个设计严谨但有时过于繁琐。
一、先看图
flowchart TD
KERN[内核数据] --> PROCFS[/proc<br/>进程 + 系统信息]
KERN --> SYSFS[/sys<br/>设备 + 子系统]
PROCFS --> PID[/proc/PID/<br/>进程信息]
PROCFS --> SYS_P[/proc/sys/<br/>sysctl]
PROCFS --> MISC[/proc/meminfo<br/>/proc/stat 等]
SYSFS --> CLASS[/sys/class/<br/>设备分类]
SYSFS --> BUS[/sys/bus/<br/>总线]
SYSFS --> FS_S[/sys/fs/<br/>文件系统]
classDef proc fill:#f0883e22,stroke:#f0883e,color:#adbac7;
classDef sys fill:#388bfd22,stroke:#388bfd,color:#adbac7;
class PROCFS,PID,SYS_P,MISC proc
class SYSFS,CLASS,BUS,FS_S sys
二、procfs 设计
2.1 历史
Unix V8(1985)引入 /proc → 最初只有进程信息 → Linux 不断扩展 → 变成”什么都往里塞”。
2.2 常用 /proc/PID 文件
| 文件 | 内容 |
|---|---|
| status | 进程状态、内存、UID/GID |
| maps | 内存映射 |
| fd/ | 打开的文件描述符 |
| cmdline | 命令行参数 |
| stat | 调度统计(格式紧凑) |
| io | I/O 统计 |
| cgroup | cgroup 成员 |
2.3 系统级
cat /proc/meminfo # 内存信息
cat /proc/stat # CPU 统计
cat /proc/loadavg # 负载
cat /proc/interrupts # 中断计数
cat /proc/slabinfo # slab 分配器三、sysfs 设计
3.1 原则
- 每个文件一个值(one value per file)
- 层次结构反映设备拓扑
- 属性由内核子系统注册
3.2 常用路径
/sys/class/net/eth0/speed # 网卡速度
/sys/block/sda/queue/scheduler # I/O 调度器
/sys/devices/system/cpu/cpu0/ # CPU 信息
/sys/fs/cgroup/ # cgroup3.3 kobject
sysfs 的每个目录对应一个 kobject:
struct kobject {
const char *name;
struct kset *kset;
struct kobj_type *ktype;
struct kernfs_node *sd;
// ...
};四、/proc/sys(sysctl)
sysctl -a # 列出所有
sysctl vm.swappiness # 读取
sysctl -w vm.swappiness=10 # 写入对应 /proc/sys/ 目录 → 每个文件是一个 sysctl
参数。
五、pid namespace
# 容器内
cat /proc/1/status # 看到的是容器内的 PID 1
cat /proc/self/status # NSpid 字段显示多级 PIDpid namespace 影响 /proc 看到的进程 → 容器内只能看到自己 namespace 的进程。
六、/proc 的陷阱
6.1 格式不一致
cat /proc/meminfo # "Key: Value kB" 格式
cat /proc/stat # 空格分隔数字
cat /proc/PID/stat # 括号包围的进程名可能含空格6.2 竞态
cat /proc/PID/maps # 进程可能在读取过程中退出读 /proc 不是原子操作 → 长文件可能不一致。
6.3 容器中的误导
/proc/meminfo 在容器中显示宿主机内存 →
应用可能误判可用内存。
解决:LXCFS 或
/sys/fs/cgroup/memory.max。
七、cgroupfs
/sys/fs/cgroup/ # cgroup v2 统一层次
/sys/fs/cgroup/memory.max # 内存限制
/sys/fs/cgroup/cpu.max # CPU 限制cgroup v2 通过 sysfs 风格接口暴露 → 每文件一值。
八、debugfs 与 tracefs
/sys/kernel/debug/ # debugfs(非稳定 ABI)
/sys/kernel/debug/tracing/ # tracefs(非稳定 ABI)仅供调试 → 格式随时可能变化。
九、观察
# 进程详情
cat /proc/self/status
cat /proc/self/maps
ls -la /proc/self/fd/
# 系统概览
cat /proc/meminfo | head -10
cat /proc/stat | head -5
# sysfs 设备
ls /sys/class/net/
cat /sys/block/sda/queue/scheduler
# 检查是否在容器中
cat /proc/1/cgroup十、小结
- /proc 历史悠久 → 混合了进程信息和系统信息
- /sys 设计严谨 → 每文件一值、层次结构
- /proc/sys = sysctl 接口
- pid namespace 影响 /proc 可见性
- 容器中 /proc 可能误导 → 用 cgroup 接口
参考文献
Documentation/filesystems/proc.rstDocumentation/admin-guide/sysfs-rules.rstDocumentation/filesystems/sysfs.rstman 5 proc
工具
cat /proc/...sysctl/sys/...
上一篇:内核日志 下一篇:POSIX capabilities
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【操作系统百科】稳定与不稳定 ABI
sysctl/sysfs/tracefs 哪些能依赖?syscall 反而最稳定。本文讲 Documentation/ABI 框架、sysfs 规则、debugfs/tracefs 非承诺、Linus 的 never break userspace 规则与例外。
【操作系统百科】内存回收
Linux 内存回收是 VM 最复杂的子系统之一。本文讲 active/inactive LRU、kswapd 与 direct reclaim、watermark 三线、swappiness 的真实含义、MGLRU 改造、memcg 回收与 PSI。
【操作系统百科】交换
swap 还值得开吗?本文讲 swap area 基础、swap cache、zram 压缩内存、zswap 前端压缩池、swappiness 的真实含义、容器里的 swap 策略,以及为什么现代 Android 全靠 zram 不靠磁盘。
【操作系统百科】Slab/SLUB 分配器
buddy 只管页粒度(4K+),内核大多数对象只有几十到几百字节。slab/SLUB 在 buddy 之上做对象级缓存。本文讲 slab 历史、SLUB 接手、SLOB 退场、kmem_cache、per-CPU cache、KASAN 集成。