Skip to content

第九十一章:procfs

斩灵期

涉及内核源码:

林小源走进一片由半透明光膜构成的林间空地。这里的树不是真的树——树干是光柱,叶片是流动的符文,整棵树都在不断闪烁变化,仿佛有什么东西在它体内飞速运转。

"这……这棵树是活的?"林小源伸手触碰树干,手指穿过了光膜,什么也没摸到。

"我可不是树。"一个声音从四面八方传来,像是无数个窗口同时开口说话。光膜凝聚成一个模糊的人形,面容不断切换——时而是一串数字,时而是一段文字,时而是一张表格。"我叫 procfs。你看到的这些,都是我从内核各处收集来的信息。"

林小源后退一步:"你不是真正的文件系统?"

"聪明。"procfs 的声音里带着一丝自嘲,"我没有磁盘,没有数据块,不存储任何东西。我只是……一扇窗。"它挥了挥手,面前浮现出密密麻麻的光幕——/proc/cpuinfo/proc/meminfo/proc/[pid]/status,每一个都在实时刷新数据。

"用户空间想看内核的什么信息,就来读我的文件。"procfs 说,"但那些文件不是真的文件——它们是函数。你读 /proc/cpuinfo 的时候,我调用一个函数,把 CPU 信息拼成文本返回给你。"

林小源看着光幕上滚动的 CPU 信息,若有所思:"那写入呢?我看到 /proc/sys/ 下有好多文件……"

procfs 的表情变得严肃起来:"那是我的另一面。/proc/sys/ 下的文件对应 参数——你写入一个值,就能改变内核的行为。比如 echo 1 > /proc/sys/net/ipv4/ip_forward,就能开启 IP 转发。"

"一个窗口,既能看,又能改?"

"双向的窗口。"procfs 说,"但要小心——改错了参数,整个系统都可能出问题。"

林小源跟着 procfs 走进它的内部世界。这里没有文件,没有目录,只有无数条光线在空中交织,每条光线的末端都连接着内核中的某个数据结构。

"你看到的 /proc/1/status,"procfs 指着一条光线说,"那不是存储在磁盘上的文件。当有人读它的时候,我去找进程 1 的 ,把它的状态、内存、PID 等信息拼成一段文本返回。"

林小源沿着光线看去,果然看到一个进程结构体在光线末端闪烁。"那 /proc/1/fd/ 呢?"

"那是进程打开的文件描述符。"procfs 打开一个光幕,上面列出了进程 1 打开的所有文件,"每个数字对应一个 结构体。我遍历进程的文件描述符表,动态生成这个列表。"

"所以你本质上是一个……翻译器?"林小源问。

procfs 笑了:"你可以这么理解。内核的数据结构对用户空间来说太复杂了—— 有几百个字段,普通人根本看不懂。我把它们翻译成人类可读的文本,通过文件接口暴露出去。"

"那为什么用文件接口?"

"因为 Linux 中一切都是文件。"procfs 说,"用户空间只需要 openreadwriteclose,不需要学习新的 API。这是最简单的接口。"

林小源注意到 procfs 的身体在微微颤抖——某些光线变得暗淡,另一些则异常明亮。

"你怎么了?"他问。

"我在承受压力。"procfs 的声音有些疲惫,"每秒钟有成千上万的进程在读取 /proc 下的文件——ps,它们都在不停地访问我。每次访问,我都要调用函数、生成文本、返回数据。"

林小源皱眉:"那你不会崩溃吗?"

"不会,但我需要小心。"procfs 说,"如果某个读取函数耗时太长,会阻塞其他访问。如果返回的数据太多,会占用太多内核内存。我必须在信息量和性能之间找到平衡。"

"那你和 sysfs 呢?"林小源想起了另一个虚拟文件系统,"你们有什么区别?"

procfs 的表情变得微妙:"sysfs 是设备模型的文件系统,专门暴露设备、驱动、总线的信息。而我更全面——进程信息、内核参数、硬件信息,什么都有。但我们有一个共同点:都不是真正的文件系统,都不存储数据,都是内核向用户空间说话的嘴巴。"

"两扇不同的窗户。"

"对。"procfs 说,"一扇看进程和内核,一扇看设备和驱动。"

c
/*
 * procfs 的结构:
 *
 *   /proc/
 *   ├── [pid]/           — 进程信息
 *   │   ├── status       — 进程状态
 *   │   ├── maps         — 内存映射
 *   │   ├── fd/          — 打开的文件描述符
 *   │   └── cmdline      — 命令行参数
 *   ├── cpuinfo          — CPU 信息
 *   ├── meminfo          — 内存信息
 *   ├── mounts           — 挂载信息
 *   ├── version          — 内核版本
 *   └── sys/             — 内核参数
 *
 * procfs 的特点:
 *   - 不占用磁盘空间
 *   - 内核动态生成内容
 *   - 可以通过写入修改内核参数
 */

printf("=== procfs — 内核的信息窗口 ===\n\n");

printf("procfs 目录结构:\n");
printf("  /proc/\n");
printf("  ├── [pid]/           进程信息\n");
printf("  │   ├── status       进程状态\n");
printf("  │   ├── maps         内存映射\n");
printf("  │   ├── fd/          文件描述符\n");
printf("  │   └── cmdline      命令行参数\n");
printf("  ├── cpuinfo          CPU 信息\n");
printf("  ├── meminfo          内存信息\n");
printf("  ├── mounts           挂载信息\n");
printf("  ├── version          内核版本\n");
printf("  └── sys/             内核参数\n\n");

printf("--- 进程信息 ---\n");
printf("/proc/[pid]/status:\n");
printf("  Name: bash\n");
printf("  State: S (sleeping)\n");
printf("  Pid: 1234\n");
printf("  PPid: 1\n");
printf("  VmSize: 12345 kB\n\n");

printf("/proc/[pid]/maps:\n");
printf("  7f0000000-7f0010000 r-xp /lib/libc.so\n");
printf("  7fff00000-7fff002000 rw-p [stack]\n\n");

printf("--- 系统信息 ---\n");
printf("/proc/cpuinfo:\n");
printf("  processor: 0\n");
printf("  model name: Intel Core i7\n");
printf("  cpu MHz: 3000.000\n\n");

printf("/proc/meminfo:\n");
printf("  MemTotal: 16384000 kB\n");
printf("  MemFree: 8192000 kB\n");
printf("  MemAvailable: 12288000 kB\n\n");

printf("--- 内核参数 ---\n");
printf("/proc/sys/:\n");
printf("  kernel/hostname\n");
printf("  net/ipv4/ip_forward\n");
printf("  vm/swappiness\n\n");
printf("修改内核参数:\n");
printf("  echo 1 > /proc/sys/net/ipv4/ip_forward\n");
printf("  sysctl -w kernel.hostname=myhost\n");

道藏笔记

内核启示

procfs 不是一个真正的文件系统——它没有磁盘,不存储数据。它是一扇窗户,让内核把信息暴露给用户空间。

你读 /proc/cpuinfo,procfs 调用一个函数,把 CPU 信息拼成文本返回给你。你读 /proc/[pid]/status,它去找对应进程的 task_struct,把状态、内存、PID 等信息翻译成人类可读的文本。文件在磁盘上吗?不在。它们是函数,读的时候才生成内容。

/proc/sys/ 下的文件更有意思——你写入一个值就能改变内核行为。比如 echo 1 > /proc/sys/net/ipv4/ip_forward 就能开启 IP 转发。双向的窗户,既能看,又能改。

为什么用文件接口?因为 Linux 中一切都是文件。用户空间只需要 open、read、write、close,不需要学新的 API。top、ps、free、htop 这些工具全靠 procfs 活着。


破关试炼

procfs 之试

本章举例通过 procfs 修改内核参数时,开启 IPv4 转发写入的是哪条命令?

答对后才能继续滑动和进入下一章。

以修仙之名,悟内核之道