文章目录
团队博客: 汽车电子社区
1. 源码结构和文件组织
1.1 核心目录结构
src/core/
├── 主程序入口
│ ├── main.c (147.96 KB) # 主程序入口点
│ └── main.h # 主程序头文件
├── 管理器核心
│ ├── manager.c (192.34 KB) # 核心管理器实现
│ ├── manager.h (25.26 KB) # 管理器定义
│ └── manager-*.c # 管理器辅助功能
├── 单元管理系统
│ ├── unit.c (243.1 KB) # 单元核心实现
│ ├── unit.h (53.09 KB) # 单元定义
│ └── unit-*.c # 单元相关功能
├── 任务调度系统
│ ├── job.c (61.09 KB) # 任务调度实现
│ ├── job.h (7.68 KB) # 任务定义
│ └── transaction.c (50.54 KB) # 事务处理
├── 进程执行器
│ ├── execute.c (109.21 KB) # 进程执行核心
│ ├── execute.h (25.25 KB) # 执行上下文定义
│ └── exec-*.c # 执行相关功能
├── D-Bus接口
│ ├── dbus.c (39.3 KB) # D-Bus核心
│ ├── dbus-*.c (多个文件) # 各种D-Bus接口
│ └── dbus-*.h # D-Bus接口定义
├── 配置解析
│ ├── load-fragment.c (229.68 KB) # 配置文件解析
│ ├── load-fragment.h (8.88 KB) # 解析器定义
│ └── load-*.c # 加载相关功能
├── cgroup集成
│ ├── cgroup.c (171.83 KB) # cgroup核心实现
│ └── cgroup.h (18.53 KB) # cgroup定义
└── 服务类型实现
├── service.c (237.64 KB) # 服务单元
├── socket.c (130.48 KB) # 套接字单元
├── mount.c (91.3 KB) # 挂载单元
└── 其他单元类型...
1.2 文件功能分类
核心管理文件
- main.c: 系统启动入口,参数解析,初始化序列
- manager.c: 核心管理器,事件循环,状态管理
- unit.c: 单元抽象层,生命周期管理
- job.c: 任务调度,队列管理
功能实现文件
- execute.c: 进程执行,环境设置,安全限制
- cgroup.c: 资源管理,限制应用,监控
- load-fragment.c: 配置解析,语法验证,加载
接口文件
- dbus-*.c: D-Bus API实现,信号处理,属性管理
- bus-*.c: 总线连接,消息处理,错误处理
2. 核心功能和架构设计
2.1 系统架构概览
systemd 核心采用事件驱动架构,主要组件包括:
2.2 主程序启动流程
主程序 main.c 实现了完整的启动序列:
int main(int argc, char *argv[]) {
// 1. 解析命令行参数和内核参数
parse_configuration();
// 2. 创建管理器实例
manager_new(&m);
// 3. 初始化D-Bus连接
bus_open_system();
// 4. 启动系统事件循环
manager_startup(m);
// 5. 进入主事件循环
manager_loop(m);
}
默认目标选择
- 初始RAM盘:initrd.target
- 正常启动:default.target
- 运行级兼容:自动映射runlevel到target
2.3 事件驱动架构
// 主事件循环
int manager_loop(Manager *m) {
for (;;) {
int r = sd_event_run(m->event, UINT64_MAX);
if (r < 0)
return log_error_errno(r, "Event loop failed: %m");
}
}
// 信号处理
static int manager_setup_signal_handlers(Manager *m) {
// SIGCHLD: 子进程状态变化
sigprocmask_many(SIG_BLOCK, SIGCHLD, SIGTERM, SIGINT, -1);
// 注册信号源
sd_event_add_signal(m->event, &m->sigchld_event_source,
SIGCHLD, manager_dispatch_sigchld, m);
}
3. 关键数据结构和算法
3.1 核心数据结构
Manager 结构(核心管理器)
struct Manager {
// 事件循环
sd_event *event;
// 单元管理
Hashmap *units; // 单元名称 -> Unit对象
Hashmap *jobs; // 任务ID -> Job对象
// 依赖关系
Hashmap *dependencies[_UNIT_DEPENDENCY_MAX];
// 运行时状态
ManagerState state;
ManagerObjective objective;
// D-Bus接口
sd_bus *api_bus; // 系统总线
sd_bus *private_bus; // 私有总线
// cgroup集成
char *cgroup_root;
CGroupMask cgroup_supported;
// 事件源
sd_event_source *signal_event_source;
sd_event_source *time_change_event_source;
};
Unit 结构(单元基类)
struct Unit {
// 基本属性
Manager *manager;
UnitType type;
char *id; // 单元名称
// 状态管理
UnitLoadState load_state;
UnitActiveState active_state;
// 依赖关系
Hashmap *dependencies[_UNIT_DEPENDENCY_MAX];
// 任务管理
Job *job; // 当前运行的任务
// 执行上下文
ExecContext *exec_context;
CGroupContext *cgroup_context;
// 虚函数表
const UnitVTable *vtable;
};
Job 结构(任务对象)
struct Job {
Manager *manager;
Unit *unit;
JobType type;
JobState state;
uint32_t id;
// 事务链接
LIST_FIELDS(Job, transaction);
// 依赖关系
LIST_HEAD(JobDependency, subject_list);
LIST_HEAD(JobDependency, object_list);
// 运行时队列
bool in_run_queue;
bool in_dbus_queue;
// 定时器
sd_event_source *timer_event_source;
};
3.2 依赖原子化算法
systemd 采用创新的依赖原子化设计,将复杂依赖关系分解为原子操作:
typedef enum UnitDependencyAtom {
// 拉入任务
UNIT_ATOM_PULL_IN_START, // 强制启动
UNIT_ATOM_PULL_IN_START_IGNORED, // 忽略失败启动
UNIT_ATOM_PULL_IN_VERIFY, // 验证状态
// 传播控制
UNIT_ATOM_PROPAGATE_START_FAILURE, // 传播启动失败
UNIT_ATOM_PROPAGATE_STOP_FAILURE, // 传播停止失败
UNIT_ATOM_PROPAGATE_STOP_GRACEFUL, // 优雅传播停止
// 顺序控制
UNIT_ATOM_BEFORE, // 在...之前
UNIT_ATOM_AFTER, // 在...之后
UNIT_ATOM_TRIGGERS, // 触发
UNIT_ATOM_TRIGGERED_BY, // 被触发
// 资源管理
UNIT_ATOM_CANNOT_BE_ACTIVE_WITHOUT, // 不能在没有...时激活
UNIT_ATOM_PINS_STOP_WHEN_UNNEEDED, // 固定停止当不需要时
} UnitDependencyAtom;
4. 单元管理系统
4.1 单元类型层次结构
systemd 支持多种单元类型,采用虚函数表模式实现多态:
const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = {
[UNIT_SERVICE] = &service_vtable,
[UNIT_SOCKET] = &socket_vtable,
[UNIT_TARGET] = &target_vtable,
[UNIT_DEVICE] = &device_vtable,
[UNIT_MOUNT] = &mount_vtable,
[UNIT_AUTOMOUNT] = &automount_vtable,
[UNIT_SWAP] = &swap_vtable,
[UNIT_TIMER] = &timer_vtable,
[UNIT_PATH] = &path_vtable,
[UNIT_SLICE] = &slice_vtable,
[UNIT_SCOPE] = &scope_vtable,
};
4.2 单元状态机
每个单元类型都有独立的状态机,以服务单元为例:
4.3 单元生命周期管理
// 单元创建
Unit* unit_new(Manager *m, size_t size) {
Unit *u = malloc0(size);
u->manager = m;
u->default_dependencies = true;
return u;
}
// 单元加载
int unit_load(Unit *u) {
// 1. 检查是否已加载
if (u->load_state != UNIT_STUB)
return 0;
// 2. 调用类型特定的加载函数
r = UNIT_VTABLE(u)->load(u);
if (r < 0)
return r;
// 3. 加载drop-in配置
unit_load_dropin(u);
// 4. 添加默认依赖
unit_add_default_dependencies(u);
return 0;
}
5. 任务调度系统
5.1 任务类型定义
typedef enum JobType {
JOB_START, // 启动任务
JOB_STOP, // 停止任务
JOB_RELOAD, // 重载任务
JOB_RESTART, // 重启任务
JOB_VERIFY_ACTIVE, // 验证激活状态
// 特殊任务类型
JOB_TRY_RESTART, // 尝试重启
JOB_TRY_RELOAD, // 尝试重载
JOB_RELOAD_OR_START, // 重载或启动
JOB_NOP, // 无操作
} JobType;
5.2 任务合并算法
systemd 实现了智能的任务合并机制,避免冲突:
static JobType job_type_merge(JobType a, JobType b) {
// 任务合并表:定义不同类型任务的合并规则
static const JobType job_merging_table[_JOB_TYPE_MAX][_JOB_TYPE_MAX] = {
[JOB_START][JOB_START] = JOB_START,
[JOB_START][JOB_RESTART] = JOB_RESTART,
[JOB_STOP][JOB_RESTART] = JOB_RESTART,
// ... 更多合并规则
};
return job_merging_table[a][b];
}
5.3 事务处理机制
typedef struct Transaction {
Hashmap *jobs; // 包含的任务
Job *anchor_job; // 锚定任务
bool irreversible; // 是否不可逆
uint64_t id; // 事务ID
} Transaction;
// 事务激活
int transaction_activate(Transaction *tr, Manager *m, JobMode mode, Set *affected) {
// 1. 检查事务可行性
r = transaction_apply(tr, m);
if (r < 0)
return r;
// 2. 拓扑排序确定执行顺序
r = transaction_order(tr);
if (r < 0)
return r;
// 3. 执行任务
LIST_FOREACH(transaction, job, tr->anchor_job) {
job_install_and_start(job);
}
return 0;
}
6. D-Bus接口实现
6.1 D-Bus接口架构
systemd 提供完整的 D-Bus API,主要接口包括:
- Manager接口:系统级管理操作
- Unit接口:单元级别的操作
- Job接口:任务管理操作
// Manager接口vtable
extern const sd_bus_vtable bus_manager_vtable[];
// Unit接口vtable
extern const sd_bus_vtable bus_unit_vtable[];
// Job接口vtable
extern const sd_bus_vtable bus_job_vtable[];
6.2 D-Bus方法实现
// 启动单元的D-Bus方法
int bus_unit_method_start_generic(
sd_bus_message *message,
Unit *u,
JobType job_type,
bool reload_if_possible,
sd_bus_error *error) {
// 1. 参数验证
r = bus_unit_validate_load_state(u, error);
if (r < 0)
return r;
// 2. 创建任务
r = manager_add_job(u->manager, job_type, u, mode, &error, &ret_job);
if (r < 0)
return r;
// 3. 返回任务对象路径
return sd_bus_reply_method_return(message, "o", job->object_path);
}
6.3 信号通知机制
// 单元状态变化信号
void bus_unit_send_change_signal(Unit *u) {
sd_bus *bus = u->manager->api_bus;
if (!bus)
return;
sd_bus_emit_signal(bus,
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
"UnitNew",
"so", u->id, u->object_path);
}
7. 进程执行器
7.1 执行上下文
typedef struct ExecContext {
// 基本执行参数
char **argv;
char **environment;
char *working_directory;
// 权限控制
uid_t uid;
gid_t gid;
char *user;
char *group;
char *supplementary_groups;
// 资源限制
uint64_t memory_limit;
uint64_t cpu_quota_per_sec_usec;
// 安全设置
char **capability_bounding_set;
char **ambient_capabilities;
char **syscall_filter;
// 文件系统隔离
TemporaryFileSystem *temporary_filesystems;
BindMount *bind_mounts;
MountImage *mount_images;
// 网络配置
bool private_network;
char **network_namespace_path;
} ExecContext;
7.2 进程执行流程
int exec_spawn(ExecCommand *command, ExecParameters *params, ExecRuntime *runtime) {
pid_t pid;
// 1. fork子进程
pid = fork();
if (pid == 0) {
// 2. 子进程设置
setup_exec_environment(params, runtime);
// 3. 应用安全策略
apply_security_restrictions(params);
// 4. 执行命令
execve(command->path, command->argv, environ);
_exit(EXIT_FAILURE);
}
// 5. 父进程记录
runtime->pid = pid;
return 0;
}
7.3 进程监控
static int manager_dispatch_sigchld(sd_event_source *source, void *userdata) {
Manager *m = userdata;
// 1. 获取子进程状态
for (;;) {
siginfo_t si;
r = waitid(P_ALL, 0, &si, WEXITED | WNOHANG);
if (r < 0)
break;
// 2. 查找对应的单元
Unit *u = manager_get_unit_by_pid(m, si.si_pid);
if (!u)
continue;
// 3. 处理进程退出
UNIT_VTABLE(u)->sigchld_event(u, &si);
}
return 0;
}
8. cgroup集成
8.1 CGroup上下文
typedef struct CGroupContext {
// CPU控制
uint64_t cpu_weight;
uint64_t cpu_quota_per_sec_usec;
uint64_t cpu_quota_period_usec;
// 内存控制
uint64_t memory_max;
uint64_t memory_high;
uint64_t memory_low;
uint64_t memory_swap_max;
// IO控制
uint64_t io_weight;
LIST_HEAD(CGroupIODeviceWeight, io_device_weights);
LIST_HEAD(CGroupIODeviceLimit, io_device_limits);
// 设备访问控制
CGroupDevicePolicy device_policy;
LIST_HEAD(CGroupDeviceAllow, device_allow);
// 任务限制
CGroupTasksMax tasks_max;
// 进程数限制
uint64_t pids_max;
} CGroupContext;
8.2 cgroup应用
int unit_apply_cgroup(Unit *u) {
CGroupContext *c = unit_get_cgroup_context(u);
CGroupRuntime *rt = unit_get_cgroup_runtime(u);
// 1. 创建cgroup路径
r = create_cgroup_path(u, rt->cgroup_path);
if (r < 0)
return r;
// 2. 应用CPU设置
if (c->cpu_weight != CGROUP_WEIGHT_INVALID)
cg_set_attribute(rt->cgroup_path, "cpu.weight",
format_cpu_weight(c->cpu_weight));
// 3. 应用内存设置
if (c->memory_max != CGROUP_LIMIT_MAX)
cg_set_attribute(rt->cgroup_path, "memory.max",
format_uint64(c->memory_max));
// 4. 应用设备限制
apply_device_restrictions(u);
// 5. 将进程加入cgroup
cg_attach(rt->cgroup_path, pid);
return 0;
}
9. 软件架构图
9.1 Core 模块分层架构
9.2 模块依赖关系图
10. 接口调用流程
10.1 系统启动流程
10.2 单元启动流程
10.3 D-Bus操作流程
11. 源码分析
11.1 主程序核心逻辑
// src/core/main.c:1780-1879
int main(int argc, char *argv[]) {
Manager *m = NULL;
int r;
// 1. 早期初始化
r = initialize_logging();
if (r < 0)
goto finish;
// 2. 解析命令行参数
r = parse_argv(argc, argv);
if (r < 0)
goto finish;
// 3. 检测是否为reexec
if (arg_reexec) {
// 重新执行自身
execv(SYSTEMD_BINARY_PATH, argv);
_exit(EXIT_FAILURE);
}
// 4. 创建管理器实例
r = manager_new(&m);
if (r < 0)
goto finish;
// 5. 启动管理器
r = manager_startup(m);
if (r < 0)
goto finish;
// 6. 进入主事件循环
r = manager_loop(m);
finish:
manager_free(m);
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
11.2 管理器启动逻辑
// src/core/manager.c:3500-3700
int manager_startup(Manager *m) {
int r;
// 1. 连接D-Bus
r = bus_init(m);
if (r < 0)
return r;
// 2. 初始化信号处理
r = manager_setup_signal_handlers(m);
if (r < 0)
return r;
// 3. 加载特殊单元
r = manager_load_special_units(m);
if (r < 0)
return r;
// 4. 解析内核参数
r = manager_parse_kernel_command_line(m);
if (r < 0)
return r;
// 5. 确定默认单元
r = manager_determine_default_unit(m);
if (r < 0)
return r;
// 6. 启动默认目标
r = manager_add_job(m, JOB_START, m->default_unit,
JOB_REPLACE, NULL, NULL);
if (r < 0)
return r;
return 0;
}
11.3 单元核心实现
// src/core/unit.c:2500-2600
int unit_add_dependency(Unit *u, UnitDependency d, Unit *other,
bool add_reference, UnitDependencyMask mask) {
UnitDependencyInfo info;
int r;
// 1. 参数验证
if (!u || !other)
return -EINVAL;
if (u == other)
return -EINVAL;
// 2. 检查循环依赖
if (would_create_cycle(u, d, other))
return -EINVAL;
// 3. 初始化依赖信息
info = (UnitDependencyInfo){
.mask = mask,
.origin = u,
.destination = other,
};
// 4. 添加正向依赖
r = hashmap_put(u->dependencies[d], other->id, &info);
if (r < 0)
return r;
// 5. 添加反向依赖
UnitDependency rd = unit_dependency_reverse(d);
if (rd >= 0) {
r = unit_add_dependency(other, rd, u, false, mask);
if (r < 0)
goto fail;
}
// 6. 应用依赖原子效果
apply_dependency_atoms(u, d, other, mask);
// 7. 添加引用计数
if (add_reference)
unit_ref_set(&u->refs_by_dependency[rd], other);
return 0;
}
11.4 任务调度算法
// src/core/job.c:1000-1100
static int job_run_and_invalidate(Job *j) {
Unit *u = j->unit;
int r;
assert(j);
assert(j->installed);
// 1. 检查任务状态
if (j->state != JOB_WAITING)
return -EALREADY;
// 2. 更新任务状态
job_set_state(j, JOB_RUNNING);
// 3. 根据任务类型执行操作
switch (j->type) {
case JOB_START:
r = unit_start(u);
break;
case JOB_STOP:
r = unit_stop(u);
break;
case JOB_RELOAD:
r = unit_reload(u);
break;
case JOB_RESTART:
r = unit_restart(u);
break;
default:
r = -EINVAL;
break;
}
// 4. 处理执行结果
if (r < 0) {
job_finish_and_invalidate(j, JOB_FAILED, r);
return r;
}
return 0;
}
11.5 进程执行核心
// src/core/execute.c:2800-3000
static int exec_spawn(ExecCommand *command,
ExecParameters *params,
ExecRuntime *runtime,
pid_t *ret_pid) {
pid_t pid;
int r;
// 1. 创建管道用于错误报告
int error_fd[2];
if (pipe2(error_fd, O_CLOEXEC) < 0)
return -errno;
// 2. fork子进程
pid = fork();
if (pid < 0) {
close_many(error_fd, 2);
return -errno;
}
if (pid == 0) {
// 子进程
close(error_fd[0]);
// 3. 设置进程属性
r = setup_exec_params(params, runtime);
if (r < 0)
goto child_fail;
// 4. 应用安全限制
r = apply_security_restrictions(params);
if (r < 0)
goto child_fail;
// 5. 执行命令
execve(command->path, command->argv, environ);
child_fail:
// 6. 错误报告
write(error_fd[1], &r, sizeof(r));
_exit(EXIT_FAILURE);
}
// 父进程
close(error_fd[1]);
// 7. 检查子进程错误
ssize_t n = read(error_fd[0], &r, sizeof(r));
close(error_fd[0]);
if (n == sizeof(r))
return r; // 子进程启动失败
// 8. 记录成功启动的进程
runtime->pid = pid;
*ret_pid = pid;
return 0;
}
12. 系统启动流程
12.1 特殊目标依赖
// src/basic/special.h
#define SPECIAL_BASIC_TARGET "basic.target" // 基础系统
#define SPECIAL_SYSINIT_TARGET "sysinit.target" // 系统初始化
#define SPECIAL_LOCAL_FS_TARGET "local-fs.target" // 本地文件系统
#define SPECIAL_NETWORK_TARGET "network.target" // 网络
#define SPECIAL_MULTI_USER_TARGET "multi-user.target" // 多用户模式
#define SPECIAL_GRAPHICAL_TARGET "graphical.target" // 图形界面
12.2 启动阶段划分
1. sysinit阶段:
- 挂载基本文件系统
- 启动udev服务
- 设置系统时钟
2. basic阶段:
- 启动基础服务
- 配置网络
- 启动日志系统
3. multi-user阶段:
- 启动网络服务
- 启动用户服务
- 启动定时任务
4. graphical阶段:
- 启动显示管理器
- 启动桌面环境
12.3 依赖解析机制
typedef enum UnitDependency {
// 强依赖
UNIT_REQUIRES, // 强制依赖
UNIT_REQUISITE, // 必须已激活
UNIT_BINDS_TO, // 绑定依赖
// 弱依赖
UNIT_WANTS, // 期望依赖
UNIT_RECOMMENDS, // 推荐依赖
// 顺序依赖
UNIT_BEFORE, // 在...之前
UNIT_AFTER, // 在...之后
// 冲突依赖
UNIT_CONFLICTS, // 冲突
// 其他依赖
UNIT_ON_FAILURE, // 失败时启动
UNIT_PROPAGATES_RELOAD_TO, // 传播重载
} UnitDependency;
13. 性能优化策略
13.1 并行启动优化
- 依赖解析并行化:同时解析多个单元的依赖关系
- 任务并行执行:无依赖关系的任务并行执行
- 预加载机制:提前加载常用单元配置
13.2 内存管理优化
- 对象池:重用Unit和Job对象
- 延迟加载:按需加载单元配置
- 内存映射:配置文件使用mmap
13.3 系统调用优化
- 批量操作:合并多个系统调用
- 事件驱动:基于epoll的事件模型
- 异步I/O:非阻塞文件操作
14. 总结
systemd 的核心管理器(PID 1)是一个高度复杂和精密的系统,其设计具有以下特点:
1. 事件驱动架构:基于 sd-event 的事件循环提供高效的异步处理
2. 依赖原子化:创新的依赖原子机制实现精确的依赖控制
3. 事务化操作:任务调度采用事务机制确保操作原子性
4. 资源隔离:深度集成 cgroup 提供细粒度的资源控制
5. 接口标准化:完整的 D-Bus API 提供统一的管理接口
6. 模块化设计:虚函数表模式支持灵活的单元类型扩展
这种设计使得 systemd 能够可靠地管理现代 Linux 系统的启动过程和服务生命周期,同时提供丰富的管理功能和配置选项。通过精心设计的架构和高效的实现,systemd 成为现代 Linux 发行版的标准 init 系统。

1183

被折叠的 条评论
为什么被折叠?



