ubuntu systemd 启动流程分析(上)
ubuntu 系统启动流程还是比较复杂的,最常见的是分析启动进程init,但是在ubuntu从16.04开始启动进程也从init切换到systemd。作为在SysV系统上被大家广泛熟知的 的启动程序init,相关的分析也比较多。此篇文章也是在制作arm平台Ubuntu、Debian、CentOS等相关文件系统时自己提出的一些疑问和记录。
-
init是什么,为什么会被取代?
init是古老的SystemV系统中内核启动的第一个进程,所以的进程都是可以认为是他fork出来的。可以认为init就是开天辟地的盘古大仙。有关此大仙的资料也是非常的多。但是为啥现在大多数Linux发行版都放弃init而使用其他的启动程序呢?
其实个人感觉,并不是init不够好(niu),而是随着系统的快速发展,init不能满足所有的需求,人们也当然会开发更适合自己的启动程序,例如:
- Upstart – A init replacement daemon implemented in Ubuntu GNU/Linux and designed to start process asynchronously.
- Epoch – A init replacement daemon built around simplicity and service management, designed to start process single-threaded.
- Mudar – A init replacement daemon written in Python, implemented on Pardus GNU/Linux and designed to start process asynchronously.
- systemd – A init replacement daemon designed to start process in parallel, implemented in a number of standard distribution – Fedora, OpenSuSE, Arch, RHEL, CentOS, etc.
-
systemd
systemd是系统服务的管理进程,进程号为1。他就是现代的盘古大仙,只是开天辟地的方式和init有所不同。systemd
其中的‘d’
代表着daemon,是一个守护进程。在ubuntu18.04中通过pstree
可以看到如下的进程树信息:systemd─┬─accounts-daemon─┬─{gdbus} │ └─{gmain} ├─acpid ├─agetty ├─apache2───2*[apache2───26*[{apache2}]] ├─atd ├─cron ├─dbus-daemon ├─dhclient ├─irqbalance ├─2*[iscsid] ├─lvmetad ├─lxcfs───4*[{lxcfs}] ├─mdadm ├─mysql-systemd-s───sleep ├─nmbd ├─php-fpm7.0───2*[php-fpm7.0] ├─polkitd─┬─{gdbus} │ └─{gmain} ├─rsyslogd─┬─{in:imklog} │ ├─{in:imuxsock} │ └─{rs:main Q:Reg}
很明显,systemd替代了我们熟悉的init。
-
systemd 与 init 的比较 (仅供参考)
为了更直观的了解两者的区别,这里降两者的特点进行简单的对比(部分内容参考网络博客):Features init systemd us Dependency – Mandatory No Yes ice based Activation No Yes ice dependency configuration with udev No Yes er based Activation Cron/at Proprietary ta Management No Yes omatic Service Dependency Handling No Yes ls users Process at logout No Yes p Management No Yes inux integration No Yes port for Encrypted HDD No Yes No Yes t all the child processes No Yes v compatible Yes Yes eractive booting No Yes table to non x86 Yes Yes pted on Several Distro Several Distro allel service startup No Yes ource limit per service No Yes y extensible startup script Yes No arate Code and Configuration File Yes No omatic dependency calculation No Yes bose debug Yes No sion N/A V44+ e 560 KB N/A ber of Files 75 files 900 files + glib + DBus es of code – LOC 15000 (Approx) 224000 (Approx) (inc Codes, comments and white space) 125000 (Approx) (acctual code)
-
从上面的比较,明显看出systemd的功能应该是更多、更强。
sysvinit的一个特点是启动服务时为同步阻塞的方式,也就是说开机启动若干服务要一个一个的启动,串行执行。可是很多服务之间并没有依赖关系,现在的硬件性能也比较高,如果就这么等着前面的服务一个个启动,也是让人着急啊。最尴尬的情况就是,前面的服务启动失败,直接就kernel panic了,有的服务还没出场就直接扑街领盒饭。
于是乎,新的机制必然会解决此问题。ubuntu15.04 之前的发行版采用upstart,一个基于事件驱动机制的启动方式,能够让服务并行启动,这样就能提高服务启动速度、也能更灵活地管理系统服务。
sysvinit和upstart的区别,就像我们进景区一样,从前是手里握紧门票排着长长的对,万一前面有个磨叽的人,咱就一个字“等”。现在的方式,你可以拿门票也可以扫二维码,入口也好几个,一下爽多了。
(图片来自网络)
启动流程概览
systemd 框架
systemd框架如下
systemd 启动流程
在systemd管理中,所有服务和功能都被抽象成一个个单元(Unit),根据功能不同,单元类型也不同。systemd正是通过配置这些单元来开关、管理服务的。
systemd定义的单元的文件可以在不同的地方找到,每一个都有不同的优先级和影响。
单元类型
有关systemd单元定义可以参考systemd 官方手册
主要的类型有:
-
Service unit
文件扩展名为.service,用于定义系统服务;
-
Target unit
文件扩展名为.target,用于模拟实现“运行级别”;
-
Device unit
文件扩展名为.device,用于定义内核识别的设备;
-
Mount unit
文件扩展名为.mount,定义文件系统挂载点;
-
Socket unit
文件扩展名为.socket,用于标识进程间通信用到的socket文件;
-
Snapshot unit
文件扩展名为.snapshot, 管理系统快照;
-
Swap unit
文件扩展名为.swap, 用于标识swap设备;
-
Automount unit
文件扩展名为.automount,文件系统自动点设备;
-
Path unit
文件扩展名为.path, 用于定义文件系统中的一文件或目录
所有可用的单元文件存放在不同的路径下,但是不同的路径具有不同的优先级。例如 /usr/lib/systemd/system/ 和 /etc/systemd/system/ 目录(后者优先级更高)
其他目录有:
/etc/systemd/system/*
/run/systemd/system/*
/usr/lib/systemd/system/*
...
~/.config/systemd/user/*
/etc/systemd/user/*
$XDG_RUNTIME_DIR/systemd/user/*
/run/systemd/user/*
~/.local/share/systemd/user/*
/usr/lib/systemd/user/*
...
可以通过systemctl list-unit-files
来查看
参考链接
Systemd Boot Process a Close Look in Linux
Find System Boot-up Performance Statistics in Linux
6 Stages of Linux Boot Process (Startup Sequence)
The Story Behind ‘init’ and ‘systemd’: Why ‘init’ Needed to be Replaced with ‘systemd’ in Linux