systemd详解1-启动 systemd-run
liebian365 2024-10-27 13:21 30 浏览 0 评论
平常工作经常涉及systemd,之前掌握更多的是使用方法。源码走读了很久,准备系统的整理下,供其他人参考和交流。systemd提供的不仅仅是一个简单的启动管理系统,而是一个高度集成、功能丰富的操作系统基础架构解决方案,一套协同管理Linux系统各个方面的大规模软件套件,旨在简化系统配置、提高系统启动速度和整体性能。由于本人知识有限,梳理会有所侧重,其他未能覆盖到的地方可以参考其他文章。unti以service为主,源码梳理主路线:main->service ExecStart。
linux启动时序
在介绍systemd之前,有必要介绍下系统启动从上电到systemd的流程,有助于把握systemd在整个系统中的位置。
- 上电后启动ROMCode,做开机自检(POST)。
- 选择启动设备,从磁盘加载引导程序bootloader到内存。
- bootloader加载kernel镜像到内存,执行各个内核模块初始化和driver初始化,如mm_init、sched_init、init_IRQ等。
- kernel完成初始化进入用户空间,执行第一个用户空间init程序。
- 对于使用systemd的系统,内核不再寻找传统的/sbin/init,而是查找配置为init的程序,通常指向/usr/lib/systemd/systemd。
systemd管理方式
用户空间进程众多,systemd充当管理者的角色按照一定的时序高效并行启动各个进程。systemd用单元(unit)的概念来描述待管理的结构,每个单元都是系统的一个组件,具有特定的配置和行为,根据要实现的功能或作用划分为:service、mount、device、timer、socket、scope、target等[1]。
需要简单介绍下target单元类型,以便后面介绍sytemd分段启动做铺垫。它代表了系统的runlevel或者一组相关service的目标状态。target本身并不执行任何服务,而是作为一个容器,定义了一组需要同时激活的service集合。每个target unit文件(通常以.target为扩展名)包含所依赖的其他service和target单元。当系统切换到某个target时,systemd会确保所有该target依赖的service都被加载并启动成功,从而实现特定级别的系统功能。在Linux系统中常见的几个target units包括:
- sysinit.target:系统初始化阶段,完成系统底层服务及设备挂载等操作;
- basic.target:包含了基本系统服务,是许多其他target的基础。
- multi-user.target:代表多用户命令行模式,不包含图形界面。
- graphical.target:代表带有图形桌面环境的多用户模式。
default.target是一个特殊的unit,systemd在启动系统时始终使用default.target作为起点。default.target默认情况下会软连接到multi-user.target(服务器系统)或graphical.target(GUI)其中之一。可以通过下面命令查看和修改默认值:
root@localhost:~# ls -l /usr/lib/systemd/system/default.target
lrwxrwxrwx 1 root root 16 Jan 5 14:27 /usr/lib/systemd/system/default.target -> graphical.target
// 查看default.target
root@localhost:~# systemctl get-default
graphical.target
// 修改default.target
root@localhost:~# systemctl set-default multi-user.target
Created symlink /etc/systemd/system/default.target → /usr/lib/systemd/system/multi-user.target.
systemd分层启动
上图是参考systemd bootup,进行了缩减以便清晰说明systemd分层启动的流程。
systemd以default.target为启动开始点,default.target软连接到graphical.target(以GUI系统为例),因为graphical.target配置了After=multi-user.target和Requires=multi-user.target,会先等待multi-user.target启动完成,依次类推到sysinit.target,最终会以sysinit.target以及依赖项为最早启动项,而graphical.target为最终达到的目标状态。
// graphical.target
[Unit]
Requires=multi-user.target
Wants=display-manager.service
After=multi-user.target rescue.service rescue.target display-manager.service
// multi-user.target
[Unit]
Requires=basic.target
After=basic.target rescue.service rescue.target
//basic-user.target
[Unit]
Requires=sysinit.target
Wants=sockets.target timers.target paths.target slices.target
After=sysinit.target sockets.target paths.target slices.target tmp.mount
//sysinit.target
[Unit]
Wants=local-fs.target swap.target
After=local-fs.target swap.target emergency.service emergency.target
Requires、Wants和After的区别
从上面给出的配置中可以看到使用了三个关键字,用来定义和管理unit之间的依赖关系,根据不同的需求选择不同的关键字,为了达到更好的效果有时候也需要组合使用:
- Requires: 侧重于业务之间的强依赖。如A.service Requires B.service,systemd会保证A启动前B处于启动状态(start)或者已经启动完成状态(running),所以如果A启动时发现B未启动,systemd会拉起B,这样A和B就同时启动了。如果B启动失败或者运行中出现异常退出,那么A同样也会退出,体现了2者的强绑定。场景举例:web服务器依赖于mysql数据库才能正常工作,依赖关系必须使用Requires。
- wants: 同Requires,区别在于依赖关系弱依赖,即被依赖者(B)不存在或者异常退出,依赖者(A)不受影响,依然正常运行。场景举例:系统大多service都需要收集log用于定位,弱依赖log service,即使log service未能启动,其他service也能正常运行。
- after: 侧重于启动顺序,解决的是时间上的依赖问题,而非功能上的依赖。如A.service After B.service,A必须等待B启动完成,B启动完成表示B处于active状态或者启动完成后正常退出。
启动完成的概念有必要解释下,即服务有start状态转为active状态。对于Type=notify类型的service来说开发者可以根据功能流程通过sd_notify(0, "READY=1")通知systemd已经启动完成。
用下面2个实验说明下Requires和After的区别:
- 实验1: A After B.service
- 实验2: A Requires B.service
// A.c
#include <stdio.h>
#include <unistd.h>
int main() {
while (1) {}
return 0;
}
// /etc/systemd/system/A.service
[Unit]
After=B.service //实验1
# Requires=B.service //实验2
[Service]
ExecStart=/home/xxx/Desktop/A
[Install]
WantedBy=multi-user.target
// B.c
#include <stdio.h>
#include <unistd.h>
#include <systemd/sd-daemon.h>
#include <sys/wait.h>
int main() {
// sleep 200ms后通知systemd ready
usleep(200000);
sd_notify(0, "READY=1");
while (1) {}
return 0;
}
// /etc/systemd/system/B.service
[Unit]
Description=B
[Service]
Type=notify
ExecStart=/home/xxx/Desktop/B
[Install]
WantedBy=multi-user.target
最常见的场景是当A.service需要在启动前确保B.service已经运行,在A.service中同时配置"Requires=B"和"After=B"。
注解
[1]:
systemd Unit | Description |
.automount | 用于实现启动时按需(即插即用)并行挂载文件系统单元。当访问特定的挂载点时,对应的文件系统会自动挂载。 |
.device | 定义在/dev/目录下暴露给系统管理员的硬件和虚拟设备。并非所有设备都有unit文件;通常,硬盘、网络设备等块设备会有相应的unit文件。 |
.mount | 定义Linux文件系统结构中的一个挂载点,用于管理文件系统的挂载操作。 |
.scope | .scope单元用于定义和管理一组系统进程集合。此类单元不由unit文件配置,而是通过程序方式创建。主要用于组织和管理服务工作者进程资源。 |
.service | .service unit文件定义由systemd管理的进程,包括cron定时任务服务、CUPS打印系统、iptables防火墙规则、逻辑卷管理服务(如LVM)、NetworkManager网络管理服务以及其他更多服务。 |
.slice | .slice单元定义了一个“切片”,它是系统资源的一个概念性划分,与一组进程相关联。可以将所有系统资源视为一个整体,而“切片”则代表从这个整体中划分出来的一部分资源。 |
.socket | .socket单元定义了进程间通信套接字,如网络套接字。当有连接请求到达时,systemd可以根据此单元来激活对应的服务。 |
.swap | .swap单元定义交换设备或交换文件,用于管理系统中的虚拟内存空间。 |
.target | .target单元定义了一组unit文件集合,它们表示启动同步点、运行级别和服务组。目标单元确定为了成功启动必须处于活动状态的服务和其他单元。 |
.timer | .timer单元定义了可以在指定时间触发程序执行的计时器 |
相关推荐
- 4万多吨豪华游轮遇险 竟是因为这个原因……
-
(观察者网讯)4.7万吨豪华游轮搁浅,竟是因为油量太低?据观察者网此前报道,挪威游轮“维京天空”号上周六(23日)在挪威近海发生引擎故障搁浅。船上载有1300多人,其中28人受伤住院。经过数天的调...
- “菜鸟黑客”必用兵器之“渗透测试篇二”
-
"菜鸟黑客"必用兵器之"渗透测试篇二"上篇文章主要针对伙伴们对"渗透测试"应该如何学习?"渗透测试"的基本流程?本篇文章继续上次的分享,接着介绍一下黑客们常用的渗透测试工具有哪些?以及用实验环境让大家...
- 科幻春晚丨《震动羽翼说“Hello”》两万年星间飞行,探测器对地球的最终告白
-
作者|藤井太洋译者|祝力新【编者按】2021年科幻春晚的最后一篇小说,来自大家喜爱的日本科幻作家藤井太洋。小说将视角放在一颗太空探测器上,延续了他一贯的浪漫风格。...
- 麦子陪你做作业(二):KEGG通路数据库的正确打开姿势
-
作者:麦子KEGG是通路数据库中最庞大的,涵盖基因组网络信息,主要注释基因的功能和调控关系。当我们选到了合适的候选分子,单变量研究也已做完,接着研究机制的时便可使用到它。你需要了解你的分子目前已有哪些...
- 知存科技王绍迪:突破存储墙瓶颈,详解存算一体架构优势
-
智东西(公众号:zhidxcom)编辑|韦世玮智东西6月5日消息,近日,在落幕不久的GTIC2021嵌入式AI创新峰会上,知存科技CEO王绍迪博士以《存算一体AI芯片:AIoT设备的算力新选择》...
- 每日新闻播报(September 14)_每日新闻播报英文
-
AnOscarstatuestandscoveredwithplasticduringpreparationsleadinguptothe87thAcademyAward...
- 香港新巴城巴开放实时到站数据 供科技界研发使用
-
中新网3月22日电据香港《明报》报道,香港特区政府致力推动智慧城市,鼓励公私营机构开放数据,以便科技界研发使用。香港运输署21日与新巴及城巴(两巴)公司签署谅解备忘录,两巴将于2019年第3季度,开...
- 5款不容错过的APP: Red Bull Alert,Flipagram,WifiMapper
-
本周有不少非常出色的app推出,鸵鸟电台做了一个小合集。亮相本周榜单的有WifiMapper's安卓版的app,其中包含了RedBull的一款新型闹钟,还有一款可爱的怪物主题益智游戏。一起来看看我...
- Qt动画效果展示_qt显示图片
-
今天在这篇博文中,主要实践Qt动画,做一个实例来讲解Qt动画使用,其界面如下图所示(由于没有录制为gif动画图片,所以请各位下载查看效果):该程序使用应用程序单窗口,主窗口继承于QMainWindow...
- 如何从0到1设计实现一门自己的脚本语言
-
作者:dong...
- 三年级语文上册 仿写句子 需要的直接下载打印吧
-
描写秋天的好句好段1.秋天来了,山野变成了美丽的图画。苹果露出红红的脸庞,梨树挂起金黄的灯笼,高粱举起了燃烧的火把。大雁在天空一会儿写“人”字,一会儿写“一”字。2.花园里,菊花争奇斗艳,红的似火,粉...
- C++|那些一看就很简洁、优雅、经典的小代码段
-
目录0等概率随机洗牌:1大小写转换2字符串复制...
- 二年级上册语文必考句子仿写,家长打印,孩子照着练
-
二年级上册语文必考句子仿写,家长打印,孩子照着练。具体如下:...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- wireshark怎么抓包 (75)
- qt sleep (64)
- cs1.6指令代码大全 (55)
- factory-method (60)
- sqlite3_bind_blob (52)
- hibernate update (63)
- c++ base64 (70)
- nc 命令 (52)
- wm_close (51)
- epollin (51)
- sqlca.sqlcode (57)
- lua ipairs (60)
- tv_usec (64)
- 命令行进入文件夹 (53)
- postgresql array (57)
- statfs函数 (57)
- .project文件 (54)
- lua require (56)
- for_each (67)
- c#工厂模式 (57)
- wxsqlite3 (66)
- dmesg -c (58)
- fopen参数 (53)
- tar -zxvf -c (55)
- 速递查询 (52)