第二百零八章:维护者之道
飞升期涉及内核源码:
一
林小源从沙漏天地继续前行,来到一座巍峨的宫殿群。宫殿的每一座大殿都代表一个子系统——网络殿、文件系统殿、内存殿、驱动殿。每座大殿的门口都站着一位守卫,他们审查着进出的每一份补丁。
宫殿群的中央矗立着一块巨大的石碑,上面密密麻麻地刻着名字和路径。林小源走近一看,碑顶刻着三个大字——"MAINTAINERS"。
"这是内核的地图,"一位守卫从石碑旁走来,他的铠甲上刻着 net/ 的路径标记,"每个子系统都有维护者。MAINTAINERS 文件记录了谁负责什么,邮箱是什么,代码在哪个路径。你要提交补丁,先看这个文件,找到对的人。"
林小源浏览着石碑上的条目。"NETWORKING — David S. Miller"、"EXT4 FILESYSTEM — Theodore Ts'o"、"ALSA SOUND — Takashi Iwai"、"USB SUBSYSTEM — Greg Kroah-Hartman"——每一个名字都对应着一位守护者。
"维护者是子系统的守护者,"守卫的语气中带着敬意,"他们审查每一个补丁,测试每一个改动,决定什么能合并、什么不能。他们的判断,直接影响着子系统的健康。"
/*
* 维护者:
*
* 角色:
* 审查补丁
* 合并代码
* 维护子系统
* 发布 pull request
*
* 维护者层级:
* Linus Torvalds — 内核维护者
* 子系统维护者 — 子系统守护者
* 驱动维护者 — 驱动守护者
*
* MAINTAINERS 文件:
* 记录每个子系统的维护者
* 记录邮件列表
* 记录代码路径
*
* 维护者职责:
* 1. 审查补丁
* 2. 测试补丁
* 3. 合并补丁
* 4. 发布 pull request
* 5. 维护代码质量
*
* 成为维护者:
* 贡献代码
* 审查补丁
* 积累信任
* 被任命
*/
/* 模拟 MAINTAINERS 条目 */
struct maintainer_entry {
char subsystem[64];
char maintainer[64];
char email[64];
char status[32];
char path[128];
};
struct maintainer_entry entries[] = {
{"NETWORKING", "David S. Miller", "davem@davemloft.net", "Maintained", "net/"},
{"EXT4 FILESYSTEM", "Theodore Ts'o", "tytso@mit.edu", "Maintained", "fs/ext4/"},
{"ALSA SOUND", "Takashi Iwai", "tiwai@suse.de", "Maintained", "sound/"},
{"USB SUBSYSTEM", "Greg Kroah-Hartman", "gregkh@linuxfoundation.org", "Maintained", "drivers/usb/"},
};
printf("=== 维护者之道 — 内核的守护者 ===\n\n");
printf("维护者是内核子系统的守护者:\n\n");
printf("--- MAINTAINERS 文件 ---\n");
int n = sizeof(entries) / sizeof(entries[0]);
for (int i = 0; i < n; i++) {
printf("%s:\n", entries[i].subsystem);
printf(" 维护者: %s\n", entries[i].maintainer);
printf(" 邮箱: %s\n", entries[i].email);
printf(" 状态: %s\n", entries[i].status);
printf(" 路径: %s\n\n", entries[i].path);
}
printf("--- 维护者层级 ---\n");
printf("Linus Torvalds:\n");
printf(" 内核维护者\n");
printf(" 最终决策者\n\n");
printf("子系统维护者:\n");
printf(" 子系统守护者\n");
printf(" 审查和合并补丁\n\n");
printf("驱动维护者:\n");
printf(" 驱动守护者\n");
printf(" 维护特定驱动\n\n");
printf("--- 维护者职责 ---\n");
printf("1. 审查补丁:\n");
printf(" 检查代码质量\n\n");
printf("2. 测试补丁:\n");
printf(" 确保不引入回归\n\n");
printf("3. 合并补丁:\n");
printf(" 合并到子系统树\n\n");
printf("4. 发布 pull request:\n");
printf(" 向 Linus 请求合并\n\n");
printf("5. 维护代码质量:\n");
printf(" 保持子系统健康\n\n");
printf("--- 成为维护者 ---\n");
printf("1. 贡献代码:\n");
printf(" 提交高质量补丁\n\n");
printf("2. 审查补丁:\n");
printf(" 帮助审查他人补丁\n\n");
printf("3. 积累信任:\n");
printf(" 持续贡献\n\n");
printf("4. 被任命:\n");
printf(" 现任维护者任命\n\n");
printf("--- 查找维护者 ---\n");
printf("scripts/get_maintainer.pl:\n");
printf(" 自动查找补丁的维护者\n");
printf(" scripts/get_maintainer.pl patch.patch\n");#include <stdio.h>
#include <string.h>
/*
* 维护者:
*
* 角色:
* 审查补丁
* 合并代码
* 维护子系统
* 发布 pull request
*
* 维护者层级:
* Linus Torvalds — 内核维护者
* 子系统维护者 — 子系统守护者
* 驱动维护者 — 驱动守护者
*
* MAINTAINERS 文件:
* 记录每个子系统的维护者
* 记录邮件列表
* 记录代码路径
*
* 维护者职责:
* 1. 审查补丁
* 2. 测试补丁
* 3. 合并补丁
* 4. 发布 pull request
* 5. 维护代码质量
*
* 成为维护者:
* 贡献代码
* 审查补丁
* 积累信任
* 被任命
*/
/* 模拟 MAINTAINERS 条目 */
struct maintainer_entry {
char subsystem[64];
char maintainer[64];
char email[64];
char status[32];
char path[128];
};
struct maintainer_entry entries[] = {
{"NETWORKING", "David S. Miller", "davem@davemloft.net", "Maintained", "net/"},
{"EXT4 FILESYSTEM", "Theodore Ts'o", "tytso@mit.edu", "Maintained", "fs/ext4/"},
{"ALSA SOUND", "Takashi Iwai", "tiwai@suse.de", "Maintained", "sound/"},
{"USB SUBSYSTEM", "Greg Kroah-Hartman", "gregkh@linuxfoundation.org", "Maintained", "drivers/usb/"},
};
int main() {
printf("=== 维护者之道 — 内核的守护者 ===\n\n");
printf("维护者是内核子系统的守护者:\n\n");
printf("--- MAINTAINERS 文件 ---\n");
int n = sizeof(entries) / sizeof(entries[0]);
for (int i = 0; i < n; i++) {
printf("%s:\n", entries[i].subsystem);
printf(" 维护者: %s\n", entries[i].maintainer);
printf(" 邮箱: %s\n", entries[i].email);
printf(" 状态: %s\n", entries[i].status);
printf(" 路径: %s\n\n", entries[i].path);
}
printf("--- 维护者层级 ---\n");
printf("Linus Torvalds:\n");
printf(" 内核维护者\n");
printf(" 最终决策者\n\n");
printf("子系统维护者:\n");
printf(" 子系统守护者\n");
printf(" 审查和合并补丁\n\n");
printf("驱动维护者:\n");
printf(" 驱动守护者\n");
printf(" 维护特定驱动\n\n");
printf("--- 维护者职责 ---\n");
printf("1. 审查补丁:\n");
printf(" 检查代码质量\n\n");
printf("2. 测试补丁:\n");
printf(" 确保不引入回归\n\n");
printf("3. 合并补丁:\n");
printf(" 合并到子系统树\n\n");
printf("4. 发布 pull request:\n");
printf(" 向 Linus 请求合并\n\n");
printf("5. 维护代码质量:\n");
printf(" 保持子系统健康\n\n");
printf("--- 成为维护者 ---\n");
printf("1. 贡献代码:\n");
printf(" 提交高质量补丁\n\n");
printf("2. 审查补丁:\n");
printf(" 帮助审查他人补丁\n\n");
printf("3. 积累信任:\n");
printf(" 持续贡献\n\n");
printf("4. 被任命:\n");
printf(" 现任维护者任命\n\n");
printf("--- 查找维护者 ---\n");
printf("scripts/get_maintainer.pl:\n");
printf(" 自动查找补丁的维护者\n");
printf(" scripts/get_maintainer.pl patch.patch\n");
return 0;
}二
林小源围着 MAINTAINERS 石碑转了一圈,发现石碑背面还刻着使用说明。
"MAINTAINERS 不只是一个名字列表,"守卫走过来,指着碑文,"每个条目包含子系统名称、维护者姓名、维护者邮箱、维护状态、邮件列表、代码路径。你拿到一个补丁,运行 ,它会自动分析补丁修改了哪些文件,然后告诉你应该发给哪个维护者。"
林小源试着在脑海中运行这个脚本——输入一个修改 的补丁,脚本会返回 Theodore Ts'o 的邮箱和 ext4 的邮件列表。
"发错了维护者会怎样?"林小源问。
守卫苦笑一声:"你的补丁会石沉大海。维护者每天收到几百封邮件,他不会去搜索发错列表的补丁。所以,提交之前一定要确认:补丁发对了人,发对了列表。"
三
林小源注意到宫殿群的高处有一座空置的大殿,门口的守卫席位空无一人。
"那是前任维护者留下的空位,"守卫的声音变得感慨,"他曾经是那个子系统的守护者,但因为工作变动离开了。现在那个子系统缺少维护者,补丁堆积如山。"
林小源望着那座空荡荡的大殿,心中涌起一个问题:"怎样才能成为维护者?"
守卫转身面对林小源,目光深沉:"不是谁任命你成为维护者,是你自己赢得这个位置。你持续贡献高质量的代码,你帮助审查别人的补丁,你在社区中建立信任——慢慢地,当维护者需要交接的时候,你的名字就会被提出来。"
守卫指了指自己的铠甲:"我成为网络子系统的守卫之前,提交了三年的补丁,审查了上千个他人的补丁。信任不是一天建立的,但它是一切的基础。没有信任,你写的代码再好,也没有人敢把它合入主线。"
林小源默默记下:维护者不是头衔,是责任。信任不是给予的,是挣来的。
道藏笔记
内核启示
维护者是内核子系统的守护者。
维护者层级:
- Linus Torvalds — 内核维护者
- 子系统维护者 — 子系统守护者
- 驱动维护者 — 驱动守护者
维护者职责:
- 审查补丁
- 测试补丁
- 合并补丁
- 发布 pull request
- 维护代码质量
成为维护者:
- 贡献代码
- 审查补丁
- 积累信任
查找维护者:
- scripts/get_maintainer.pl
维护者是守护者——守护内核的质量。
维护者之试
提交前想知道补丁该发给谁,本章让你查询哪一个维护者清单文件?