layout: post
title: Systemd
date: 2018-01-06
tags: [“Linux”,”系统的启动和内核的管理”]


一、Systemd简介

1、Systemd是一个新兴的系统启动和服务器守护进程管理器,负责在系统启动或运行时,激活系统资源,服务器进程和其他进程。systemd由红帽公司开发,用以代替Upstart,”系统的第一个进程init”。

2、Systemd的新特性

系统引导时实现服务并行启动
按需启动守护进程
自动化的服务依赖关系管理
同时采用socket式与D-Bus总线式激活服务 (socket与服务程序分离,由systemd来监控,代替了xinetd)
系统状态快照

二、核心概念:Unit

所谓Unit(单元),就是systemd的管理对象,以下是各种unit类型。

Service:用来定义系统服务
Target:用来模拟实现系统运行级别(systemd中实际已经没有了运行级别这么一个说法)
Device:用来定义内核是别的设备
Mount:用来定义文件系统的挂载点
Socket:用于表示进程间通信用的socket文件,也可以在系统启动时,延迟启动服务,系统按需启动(systemd的新特性,后面会做介绍)
Snapshot:管理系统快照
Swap:用于表示swap设备
Automount:文件系统的自动挂载点
Path:用于定义文件系统中的一个文件或目录使用,常用于文件系统变化时,延迟激活服务,如:spool目录

 

配置文件:
/usr/lib/systemd/system:每个服务最主要的启动脚本设置,类似于之前的/etc/init.d/
/run/systemd/system:系统执行过程中所产生的服务脚本,比上面目录优先运行
/etc/systemd/system:管理员建立的执行脚本,类似于/etc/rc.d/rcN.d/Sxx类的功能,比上面目录优先运行(实际就是/usr/lib/systemd/system下的各个文件的软连接

三、使用Systemd来管理服务(这里只列出单独的命令,后面会演示)

1、服务的常规操作

[table id=4 /]

2、服务的查看

注意:一下的unit代表service’target’device….

[table id=5 /]

服务状态

systemctl list-unit-files —type service —all显示状态
loaded:Unit配置文件已处理
active(running):一次或多次持续处理的运行
active(exited):成功完成一次性的配置
active(waiting):运行中,等待一个事件
inactive:不运行
enabled:开机启动
disabled:开机不启动
static:开机不启动,但可被另一个启用的服务激活

systemctl status services 查看的服务,当服务状态有问题的时候,可以使用journalctl -xe 来查看问题日志,journal可以为我们提供部分服务的解决方案。

 

3、运行级别(systemd的运行级别不再是0-6了,或者说systemd没有运行级别,而是target,我们完全可以设定适合我们的target)

[table id=6 /]

4、演示

常规服务的操作:

  1. [root@newhostname /]# systemctl start httpd #当命令成功时不会提示
  2. [root@newhostname /]# systemctl status httpd #查看服务状态
  3. httpd.service - The Apache HTTP Server
  4. Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
  5. Active: active (running) since 2018-01-06 00:43:58 CST; 9s ago #Active:active(running)表示激活的
  6. Docs: man:httpd(8)
  7. man:apachectl(8)
  8. Process: 3535 ExecStop=/bin/kill -WINCH ${MAINPID} (code=exited, status=1/FAILURE)
  9. Process: 3237 ExecReload=/usr/sbin/httpd $OPTIONS -k graceful (code=exited, status=0/SUCCESS)
  10. Main PID: 3568 (httpd)
  11. Status: "Total requests: 0; Current requests/sec: 0; Current traffic: 0 B/sec"
  12. CGroup: /system.slice/httpd.service
  13. ├─3568 /usr/sbin/httpd -DFOREGROUND
  14. ├─3571 /usr/sbin/httpd -DFOREGROUND
  15. ├─3572 /usr/sbin/httpd -DFOREGROUND
  16. ├─3573 /usr/sbin/httpd -DFOREGROUND
  17. ├─3574 /usr/sbin/httpd -DFOREGROUND
  18. └─3575 /usr/sbin/httpd -DFOREGROUND
  19.  
  20. [root@newhostname /]# systemctl stop httpd #同start,命令成功不糊提示
  21. [root@newhostname /]# systemctl status httpd
  22. httpd.service - The Apache HTTP Server
  23. Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
  24. Active: inactive (dead) #inactive目标服务未启动
  25. Docs: man:httpd(8)
  26. man:apachectl(8)
  27.  
  28. 1 06 00:43:35 newhostname kill[3535]: kill: cannot find process ""
  29. 1 06 00:43:35 newhostname systemd[1]: httpd.service: control process exited, code=exited status=1
  30. 1 06 00:43:35 newhostname systemd[1]: Failed to start The Apache HTTP Server.
  31. 1 06 00:43:35 newhostname systemd[1]: Unit httpd.service entered failed state.
  32. 1 06 00:43:35 newhostname systemd[1]: httpd.service failed.
  33. 1 06 00:43:58 newhostname systemd[1]: Starting The Apache HTTP Server...
  34. 1 06 00:43:58 newhostname httpd[3568]: AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::20...s message
  35. 1月 06 00:43:58 newhostname systemd[1]: Started The Apache HTTP Server.
  36. 1月 06 00:44:21 newhostname systemd[1]: Stopping The Apache HTTP Server...
  37. 1月 06 00:44:22 newhostname systemd[1]: Stopped The Apache HTTP Server.
  38. Hint: Some lines were ellipsized, use -l to show in full.
  39.  
  40. 我们现在把selinux打开,再启动一次httpd服务(因为我之前已经把http端口的端口改了,selinux内并没有添加相应的策略,所以启动服务肯定会失败)
  41.  
  42. [root@newhostname /]# setenforce 1
  43. [root@newhostname /]# systemctl start httpd
  44. Job for httpd.service failed because the control process exited with error code. See "systemctl status httpd.service" and "journalctl -xe" for details.
  45.  
  46. [root@newhostname /]# systemctl status httpd #我们查看一下启动失败后的状态信息
  47. ● httpd.service - The Apache HTTP Server
  48. Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
  49. Active: failed (Result: exit-code) since 六 2018-01-06 00:50:51 CST; 17s ago #failed为启动失败状态
  50. Docs: man:httpd(8)
  51. man:apachectl(8)
  52. Process: 3616 ExecStop=/bin/kill -WINCH ${MAINPID} (code=exited, status=1/FAILURE)
  53. Process: 3615 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=exited, status=1/FAILURE)
  54. Main PID: 3615 (code=exited, status=1/FAILURE)
  55.  
  56. 1月 06 00:50:51 newhostname httpd[3615]: (13)Permission denied: AH00072: make_sock: could not bind to address [::]:3
  57. 1月 06 00:50:51 newhostname httpd[3615]: (13)Permission denied: AH00072: make_sock: could not bind to address 0.0.0.0:3
  58. 1月 06 00:50:51 newhostname httpd[3615]: no listening sockets available, shutting down
  59. 1月 06 00:50:51 newhostname httpd[3615]: AH00015: Unable to open logs
  60. 1月 06 00:50:51 newhostname systemd[1]: httpd.service: main process exited, code=exited, status=1/FAILURE
  61. 1月 06 00:50:51 newhostname kill[3616]: kill: cannot find process ""
  62. 1月 06 00:50:51 newhostname systemd[1]: httpd.service: control process exited, code=exited status=1
  63. 1月 06 00:50:51 newhostname systemd[1]: Failed to start The Apache HTTP Server.
  64. 1月 06 00:50:51 newhostname systemd[1]: Unit httpd.service entered failed state.
  65. 1月 06 00:50:51 newhostname systemd[1]: httpd.service failed.
  66.  
  67. 现在我们使用"journalctl -xe"查看详细信息。
  68.  
  69. [root@newhostname /]# journalctl -xe
  70. 1月 06 00:50:51 newhostname dbus-daemon[808]: dbus[808]: [system] Successfully activated service 'org.fedoraproject.Setroubleshootd'
  71. 1月 06 00:50:52 newhostname setroubleshoot[3622]: SELinux is preventing /usr/sbin/httpd from name_bind access on the tcp_socket port 3. For complete SELinu
  72. 1月 06 00:50:52 newhostname python[3622]: SELinux is preventing /usr/sbin/httpd from name_bind access on the tcp_socket port 3.
  73.  
  74. ***** Plugin bind_ports (99.5 confidence) suggests ************************
  75.  
  76. If you want to allow /usr/sbin/httpd to bind to network port 3
  77. Then you need to modify the port type.
  78. Do
  79. # semanage port -a -t PORT_TYPE -p tcp 3
  80. where PORT_TYPE is one of the following: http_cache_port_t, http_port_t, jboss_management_port_t, jboss_mess
  81.  
  82. ***** Plugin catchall (1.49 confidence) suggests **************************
  83.  
  84. If you believe that httpd should be allowed name_bind access on the port 3 tcp_socket by default.
  85. Then you should report this as a bug.
  86. You can generate a local policy module to allow this access.
  87. Do
  88. allow this access for now by executing:
  89. # ausearch -c 'httpd' --raw ' audit2allow -M my-httpd
  90. # semodule -i my-httpd.pp
  91.  
  92. 1 06 00:50:52 newhostname setroubleshoot[3622]: SELinux is preventing /usr/sbin/httpd from name_bind access on the tcp_socket port 3. For complete SELinu
  93. 1 06 00:50:52 newhostname python[3622]: SELinux is preventing /usr/sbin/httpd from name_bind access on the tcp_socket port 3.
  94.  
  95. ***** Plugin bind_ports (99.5 confidence) suggests ************************
  96.  
  97. If you want to allow /usr/sbin/httpd to bind to network port 3
  98. Then you need to modify the port type.
  99. Do
  100. # semanage port -a -t PORT_TYPE -p tcp 3
  101. where PORT_TYPE is one of the following: http_cache_port_t, http_port_t, jboss_management_port_t, jboss_mess
  102.  
  103. ***** Plugin catchall (1.49 confidence) suggests **************************
  104.  
  105. If you believe that httpd should be allowed name_bind access on the port 3 tcp_socket by default.
  106. Then you should report this as a bug.
  107. You can generate a local policy module to allow this access.
  108. Do
  109. allow this access for now by executing:
  110. # ausearch -c 'httpd' --raw ' audit2allow -M my-httpd
  111. # semodule -i my-httpd.pp
  112.  
  113. journal 直接告诉了我们,是selinux出了问题,可以通过"semanage port -a -t PORT_TYPE -p tcp 3"来解决问题
  114.  
  115. 关于服务的常规操作,其他的几个操作就不再演示了,能理解意思就行

服务的查看:

  1. [root@newhostname /]# systemctl --failed -t service #查看失败的服务
  2. UNIT LOAD ACTIVE SUB DESCRIPTION
  3. httpd.service loaded failed failed The Apache HTTP Server
  4.  
  5. LOAD = Reflects whether the unit definition was properly loaded.
  6. ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
  7. SUB = The low-level unit activation state, values depend on unit type.
  8.  
  9. 1 loaded units listed. Pass --all to see loaded but inactive units, too.
  10. To show all installed unit files use 'systemctl list-unit-files'.
  11.  
  12. [root@newhostname /]# systemctl --failed #查看所有启动失败的unit
  13. UNIT LOAD ACTIVE SUB DESCRIPTION
  14. httpd.service loaded failed failed The Apache HTTP Server
  15.  
  16. LOAD = Reflects whether the unit definition was properly loaded.
  17. ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
  18. SUB = The low-level unit activation state, values depend on unit type.
  19.  
  20. 1 loaded units listed. Pass --all to see loaded but inactive units, too.
  21. To show all installed unit files use 'systemctl list-unit-files'.
  22.  
  23. [root@newhostname /]# systemctl stop httpd
  24. [root@newhostname /]# systemctl is-active httpd #查看服务状态
  25. unknown
  26. [root@newhostname /]# echo $? #值不为0都是未启动
  27. 3
  28. [root@newhostname /]# setenforce 0
  29. [root@newhostname /]# systemctl start httpd
  30. [root@newhostname /]# systemctl is-active httpd
  31. active
  32. [root@newhostname /]# echo $? #值为0表示服务正在运行
  33. 0
  1. [root@newhostname /]# systemctl list-units -t service #如果不加 -t service 默认会打印出所有的unit单元
  2. UNIT LOAD ACTIVE SUB DESCRIPTION #这里我只粘贴了少量的一部分,因为service的unit太多了
  3. abrt-ccpp.service loaded active exited Install ABRT coredump hook
  4. abrt-oops.service loaded active running ABRT kernel log watcher
  5. abrt-xorg.service loaded active running ABRT Xorg log watcher
  6. abrtd.service loaded active running ABRT Automated Bug Reporting Tool
  7. alsa-state.service loaded active running Manage Sound Card State (restore and store)
  8. atd.service loaded active running Job spooling tools
  9. auditd.service loaded active running Security Auditing Service
  10. blk-availability.service loaded active exited Availability of block devices
  11. bluetooth.service loaded active running Bluetooth service
  12. chronyd.service loaded active running NTP client/server
  13. crond.service loaded active running Command Scheduler
  14. cups.service loaded active running CUPS Printing Service
  15. dbus.service loaded active running D-Bus System Message Bus
  16.  
  17. [root@newhostname /]# systemctl list-unit-files #打印所有的unit状态
  18. UNIT FILE STATE
  19. proc-sys-fs-binfmt_misc.automount static
  20. dev-hugepages.mount static
  21. dev-mqueue.mount static
  22. proc-fs-nfsd.mount static
  23. proc-sys-fs-binfmt_misc.mount static
  24. sys-fs-fuse-connections.mount static
  25. sys-kernel-config.mount static
  26. sys-kernel-debug.mount static
  27. tmp.mount disabled
  28. var-lib-nfs-rpc_pipefs.mount static
  29. brandbot.path disabled
  30. cups.path enabled
  31. systemd-ask-password-console.path static
  32. systemd-ask-password-plymouth.path static
  33. systemd-ask-password-wall.path static
  34. session-25.scope static
  35. session-27.scope static
  36. abrt-ccpp.service enabled
  37. abrt-oops.service enabled
  38. abrt-pstoreoops.service disabled
  39. abrt-vmcore.service enabled
  40. abrt-xorg.service enabled
  41. abrtd.service enabled
  42. accounts-daemon.service enabled
  43.  
  44. [root@newhostname /]# systemctl list-unit-files -t service #打印unit为service的服务状态
  45. UNIT FILE STATE
  46. abrt-ccpp.service enabled
  47. abrt-oops.service enabled
  48. abrt-pstoreoops.service disabled
  49. abrt-vmcore.service enabled
  50. abrt-xorg.service enabled
  51. abrtd.service enabled
  52. accounts-daemon.service enabled
  53. alsa-restore.service static
  54. alsa-state.service static
  55. alsa-store.service static
  56. anaconda-direct.service static
  57. anaconda-nm-config.service static
  58. anaconda-noshell.service static
  59. anaconda-pre.service static
  60. anaconda-shell@.service static
  61. anaconda-sshd.service static
  62. anaconda-tmux@.service static
  63. anaconda.service static
  64. arp-ethers.service disabled
  65. atd.service enabled
  66. auditd.service enabled
  67. auth-rpcgss-module.service static
  68. autofs.service disabled
  69. autovt@.service enabled
  70. blk-availability.service disabled
  71. bluetooth.service enabled
  72. brandbot.service static
  73. canberra-system-bootup.service disabled
  74. canberra-system-shutdown-reboot.service disabled
  75. canberra-system-shutdown.service disabled
  76. certmonger.service disabled
  77. cgconfig.service disabled
  78. cgdcbxd.service disabled
  79. cgred.service disabled
  80. chrony-dnssrv@.service static
  81. chrony-wait.service disabled
  82. chronyd.service enabled
  83. colord.service static
  84. configure-printer@.service static
  85. console-getty.service disabled
  86. console-shell.service disabled
  87. container-getty@.service static
  演示运行级别: 首先,我们先说默认的target,设置方法:systemctl set-default name.target,这里我们就已设置图形界面为例
  1. [root@newhostname system]# systemctl set-default graphical.target #这是图形界面为启动机器之后的默认target
  2. Removed symlink /etc/systemd/system/default.target.
  3. Created symlink from /etc/systemd/system/default.target to /usr/lib/systemd/system/graphical.target. /etc/systemd/system/default.target
  4.  
  5. 它执行的动作,很简单,把"/etc/systemd/system/default.target"这个软连接删除了,建立新的target到/etc/systemd/system/default.target
  6.  
  7. 现在我们在当前的target切换到其他的target中(当前是字符界面,我们切换到图形界面,因为我没有装图形,所以不会真正的切过去)
  8. [root@newhostname default.target.wants]# systemctl isolate graphical.target
  9. [root@newhostname default.target.wants]#
  10.  
  11. 执行成功了?为什么没报错,这个问题后面再讲,马上就讲,请继续看
  ### 四、服务Unit文件 所有的systemd单元都存放在了"/usr/lib/systemd/system/"这个目录下,不管是target还是service还是socket都在这里。 1、我们查看一个service的unit,来看看它的结构,就以httpd的为例吧
  1. [root@newhostname multi-user.target.wants]# cat /usr/lib/systemd/system/httpd.service
  2. [Unit]
  3. Description=The Apache HTTP Server
  4. After=network.target remote-fs.target nss-lookup.target
  5. Documentation=man:httpd(8)
  6. Documentation=man:apachectl(8)
  7.  
  8. [Service]
  9. Type=notify
  10. EnvironmentFile=/etc/sysconfig/httpd
  11. ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
  12. ExecReload=/usr/sbin/httpd $OPTIONS -k graceful
  13. ExecStop=/bin/kill -WINCH ${MAINPID}
  14. # We want systemd to give httpd some time to finish gracefully, but still want
  15. # it to kill httpd after TimeoutStopSec if something went wrong during the
  16. # graceful stop. Normally, Systemd sends SIGTERM signal right after the
  17. # ExecStop, which would kill httpd. We are sending useless SIGCONT here to give
  18. # httpd time to finish.
  19. KillSignal=SIGCONT
  20. PrivateTmp=true
  21.  
  22. [Install]
  23. WantedBy=multi-user.target
  24. [root@newhostname multi-user.target.wants]#

可以看出service的unit是由3大块组成,即[Unit]、[Service]、[Install]

[Unit]:定义与Unit类型无关的通用选项;用于提供unit的描述信息、unit行为及依赖关系等;Unit段的常用选项:

Description:描述信息
After:定义unit的启动次序,表示当前unit应该晚于哪些unit启动,其功能与Before相反
Requires:依赖到的其它units,强依赖,被依赖的units无法激活时,当前unit也无法激活
Wants:依赖到的其它units,弱依赖
Conflicts:定义units间的冲突关系

[Service]:与特定类型相关的专用选项;Service段的常用选项:

EnvironmentFile:环境配置文件
ExecStart:指明启动unit要运行命令或脚本的绝对路径
ExecStartPre: ExecStart前运行
ExecStartPost: ExecStart后运行
ExecStop:指明停止unit要运行的命令或脚本
Restart:当设定Restart=1 时,则当次daemon服务意外终止后,会再次自动启动此服务
KillSignal:执行systemctl kill service 时,发送的信号
Type:定义影响ExecStart及相关参数的功能的unit进程启动类型

• simple:默认值,这个daemon主要由ExecStart接的指令串来启动,启动后常驻于内存中
• forking:由ExecStart启动的程序透过spawns延伸出其他子程序来作为此daemon的主要服务。原生父程序在启动结束后就会终止
• oneshot:与simple类似,不过这个程序在工作完毕后就结束了,不会常驻在内存中
• dbus:与simple类似,但这个daemon必须要在取得一个D-Bus的名称后,才会继续运作.因此通常也要同时设定BusNname= 才行
• notify:在启动完成后会发送一个通知消息。还需要配合NotifyAccess 来让 Systemd 接收消息
• idle:与simple类似,要执行这个daemon必须要所有的工作都顺利执行完毕后才会执行。这类的daemon通常是开机到最后才执行即可的服务

[Install]: 定义由”systemctl enable”以及”systemctl disable”命令在实现服务启用或禁用时用到的一些选项;Install段的常用选项:

Alias:别名,可使用systemctl command Alias.service
RequiredBy:被哪些units所依赖,强依赖
WantedBy:被哪些units所依赖,弱依赖
Also:安装本服务的时候还要安装别的相关服务

那么我们现在编写一个服务脚本

  1. [root@newhostname system]# cat <bak.service #编写简单脚本
  2. [Unit]
  3. Description=backup /etc
  4. Requires=atd.service
  5. [Service]
  6. Type=simple
  7. ExecStart=/usr/bin/echo "ok"
  8. [Install]
  9. WantedBy=multi-user.target
  10. [root@newhostname system]# systemctl start bak.service
  11. [root@newhostname system]# systemctl status bak.service
  12. bak.service - backup /etc
  13. Loaded: loaded (/usr/lib/systemd/system/bak.service; disabled; vendor preset: disabled)
  14. Active: inactive (dead)
  15. 1 06 15:17:26 newhostname echo[2832]: ok
  16. 1 06 15:17:28 newhostname systemd[1]: Started backup /etc.
  17. 1 06 15:17:28 newhostname systemd[1]: Starting backup /etc...
  18. 1 06 15:17:28 newhostname echo[2840]: ok
  19. 1 06 15:17:29 newhostname systemd[1]: Started backup /etc.
  20. 1 06 15:17:29 newhostname systemd[1]: Starting backup /etc...
  21. 1 06 15:17:29 newhostname echo[2848]: ok
  22. 1 06 15:17:29 newhostname systemd[1]: Started backup /etc.
  23. 1 06 15:17:29 newhostname systemd[1]: Starting backup /etc...
  24. 1 06 15:17:29 newhostname echo[2856]: ok
    2、socket Unit Systemd引用了socket这种unit,从而替代了以前系统的超级守护进程xinetd,之前以来xinetd的服务,systemd可以完全接手,下面我们就以telnet服务为例
  1. 首先我们启动telnet服务(telnet是一个socket单元,在systemd中)
  2. [root@newhostname /]# systemctl start telnet.socket
  3. [root@newhostname /]#
  4.  
  5. 我们来查看一下链接
  6. [root@newhostname /]# ss -antp ' grep 23
  7. LISTEN 0 128 :::23 :::* users:(("systemd",pid=1,fd=29))
  8.  
  9. 我们可以看到数据的最后一列,telent端口是由systemd来管理的
  其实telent服务平时是不启动的,当有数据接收时才会触发telnet服务启动,而telnet服务也是一个unit单元,命名为telnet@.service,我们可以再在/usr/lib/systemd/system/下查看一下
  1. [root@newhostname /]# cat //usr/lib/systemd/system/telnet@.service
  2. [Unit]
  3. Description=Telnet Server
  4. After=local-fs.target
  5.  
  6. [Service]
  7. ExecStart=-/usr/sbin/in.telnetd
  8. StandardInput=socket

带有@的服务是不能够被systemctl start直接启动的,其由systemd直接来监管。

2、target单元

在redhat7之前第一个进程是init,自redhat7开始使用systemd作为所有进程的父进程,而之前所使用的运行级别,到这里则变成了target概念,那么什么是tareget,target就是一组服务或某特殊功能的一个指针,我们就先已graphical.target为例

  1. [root@newhostname system]# ll ' grep graphical.target
  2. lrwxrwxrwx. 1 root root 16 11月 7 16:12 default.target -> graphical.target
  3. -rw-r--r--. 1 root root 558 8月 5 14:38 graphical.target
  4. drwxr-xr-x. 2 root root 50 11月 7 16:12 graphical.target.wants
  5. lrwxrwxrwx. 1 root root 16 11月 7 16:12 runlevel5.target -> graphical.target
  6.  
  7. default.target默认的启动目标,联想一下/etc/systemd/system/default.target 很容易理解
  8. runlevel5.target 这个其实也很好理解,为了兼容以前的版本么,之前的 init 5实际指向了 graphical.target
  9.  
  10. 在这里我们真正要说的是这两个
  11. -rw-r--r--. 1 root root 558 8月 5 14:38 graphical.target
  12. drwxr-xr-x. 2 root root 50 11月 7 16:12 graphical.target.wants
  13.  
  14. 我们查看一下graphical.target这个文件
  15. [root@newhostname system]# cat graphical.target
  16. # This file is part of systemd.
  17. #
  18. # systemd is free software; you can redistribute it and/or modify it
  19. # under the terms of the GNU Lesser General Public License as published by
  20. # the Free Software Foundation; either version 2.1 of the License, or
  21. # (at your option) any later version.
  22.  
  23. [Unit]
  24. Description=Graphical Interface
  25. Documentation=man:systemd.special(7)
  26. Requires=multi-user.target
  27. Wants=display-manager.service
  28. Conflicts=rescue.service rescue.target
  29. After=multi-user.target rescue.service rescue.target display-manager.service
  30. AllowIsolate=yes

这个是不是已经很眼熟了,好像service的 Unit,其实他们的选项配置基本一样,下面我们来细细的分析一下,此[Unit]的各个标签的含义
Description 这个是描述
Requires 这个是强依赖,”看来图形界面也是以来字符界面的”
Wants display-manager,很显然是图形界面管理器么,但这是个弱依赖,这也就是为什么,
之前我们使用systemctl isolate graphical.target 不会报错的原因
Conflicts 定义了与之冲突的目标,这里定义的是 rescue救援模式
After 表示需要在multi-user.target rescue.service rescue.target display-manager.service这些单元启动之后启动
AllowIsolate 这个是一个beloon值,也是和service_unit区分的地方,它代表是否可以切换目标

*.target.wants的意义:表示切换了运行目标想要操作的unit,这个是弱依赖
我们接着看graphical.target.wants这个目录下都有些什么

  1. [root@newhostname system]# cd graphical.target.wants/
  2. [root@newhostname graphical.target.wants]# ls
  3. systemd-update-utmp-runlevel.service
  4.  
  5. 只有这个一个服务
  `systemd-update-utmp-runlevel.service` 服务 用于在 SysV 运行级发生变化时,更新 utmp 与 wtmp 文件, 以及记录审计日志。 结合上面的信息,我们得出一个结论,那么就是切换到图形界面,实际上是在原来字符界面的基础上又启动了一个display-manager.service,但它是一个弱依赖,在我的机器上并没有安装图形,但是systemd-update-utmp-runlevel.service又真实运行了,那么我们查看一下一下现在的运行目标
  1. [root@newhostname system]# systemctl get-default
  2. multi-user.target #现在的运行目标
  3. [root@newhostname system]# runlevel #为了展示兼容以前
  4. N 3
  5. [root@newhostname system]# systemctl isolate graphical.target #切换成图形
  6. [root@newhostname system]# runlevel
  7. 3 5
  8.  
  9. 实际上我们并没有启动图形,因为没有安装,但是切换操作影响了systemd-update-utmp-runlevel.service这个服务,所以显示的运行级别出现了变化

在Systemd中兼容了之前的init,但是像runlevel这样的命令,其实都是即将废弃的命令,我们可以通过 systemctl list-units —type=target 来查看运行目标

  1. [root@newhostname system]# systemctl list-units --type=target
  2. UNIT LOAD ACTIVE SUB DESCRIPTION
  3. basic.target loaded active active Basic System
  4. cryptsetup.target loaded active active Encrypted Volumes
  5. getty.target loaded active active Login Prompts
  6. graphical.target loaded active active Graphical Interface
  7. local-fs-pre.target loaded active active Local File Systems (Pre)
  8. local-fs.target loaded active active Local File Systems
  9. multi-user.target loaded active active Multi-User System
  10. network-online.target loaded active active Network is Online
  11. network.target loaded active active Network
  12. nfs-client.target loaded active active NFS client services
  13. nss-user-lookup.target loaded active active User and Group Name Lookups
  14. paths.target loaded active active Paths
  15. remote-fs-pre.target loaded active active Remote File Systems (Pre)
  16. remote-fs.target loaded active active Remote File Systems
  17. slices.target loaded active active Slices
  18. sockets.target loaded active active Sockets
  19. swap.target loaded active active Swap
  20. sysinit.target loaded active active System Initialization
  21. timers.target loaded active active Timers
  22.  
  23. LOAD = Reflects whether the unit definition was properly loaded.
  24. ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
  25. SUB = The low-level unit activation state, values depend on unit type.
  26.  
  27. 19 loaded units listed. Pass --all to see loaded but inactive units, too.
  28. To show all installed unit files use 'systemctl list-unit-files'.

我们一级一级向上看,我们接下来看一下multi-user.target

  1. [root@newhostname system]# cat multi-user.target
  2. # This file is part of systemd.
  3. #
  4. # systemd is free software; you can redistribute it and/or modify it
  5. # under the terms of the GNU Lesser General Public License as published by
  6. # the Free Software Foundation; either version 2.1 of the License, or
  7. # (at your option) any later version.
  8.  
  9. [Unit]
  10. Description=Multi-User System
  11. Documentation=man:systemd.special(7)
  12. Requires=basic.target
  13. Conflicts=rescue.service rescue.target
  14. After=basic.target rescue.service rescue.target
  15. AllowIsolate=yes
  16.  
  17. 最主要的还是这几行
  18. Requires=basic.target #强依赖
  19. Conflicts=rescue.service rescue.target #与之冲突的目标
  20. After=basic.target rescue.service rescue.target #在这些服务启动之后才会启动
  21. AllowIsolate=yes #表示可以切换

我们查看multi-user.target.wants

  1. [root@newhostname system]# cd multi-user.target.wants/
  2. [root@newhostname multi-user.target.wants]# ll
  3. 总用量 0
  4. lrwxrwxrwx. 1 root root 16 11 7 16:12 brandbot.path -> ../brandbot.path
  5. lrwxrwxrwx. 1 root root 15 11 7 16:12 dbus.service -> ../dbus.service
  6. lrwxrwxrwx. 1 root root 15 11 7 16:12 getty.target -> ../getty.target
  7. lrwxrwxrwx. 1 root root 24 11 7 16:12 plymouth-quit.service -> ../plymouth-quit.service
  8. lrwxrwxrwx. 1 root root 29 11 7 16:12 plymouth-quit-wait.service -> ../plymouth-quit-wait.service
  9. lrwxrwxrwx. 1 root root 33 11 7 16:12 systemd-ask-password-wall.path -> ../systemd-ask-password-wall.path
  10. lrwxrwxrwx. 1 root root 25 11 7 16:12 systemd-logind.service -> ../systemd-logind.service
  11. lrwxrwxrwx. 1 root root 39 11 7 16:12 systemd-update-utmp-runlevel.service -> ../systemd-update-utmp-runlevel.service
  12. lrwxrwxrwx. 1 root root 32 11 7 16:12 systemd-user-sessions.service -> ../systemd-user-sessions.service
  13.  
  14. 切换运行目标到multi-user会启动这些unit

我们再向上看,basic.target

  1. [root@newhostname multi-user.target.wants]# cd ..
  2. [root@newhostname system]# cat basic.target
  3. # This file is part of systemd.
  4. #
  5. # systemd is free software; you can redistribute it and/or modify it
  6. # under the terms of the GNU Lesser General Public License as published by
  7. # the Free Software Foundation; either version 2.1 of the License, or
  8. # (at your option) any later version.
  9.  
  10. [Unit]
  11. Description=Basic System
  12. Documentation=man:systemd.special(7)
  13.  
  14. Requires=sysinit.target
  15. After=sysinit.target
  16. Wants=sockets.target timers.target paths.target slices.target
  17. After=sockets.target paths.target slices.target
  18.  
  19. basic.target强制依赖sysinit.target
  20. 再启动basic.target时,希望启动sockets.target timers.target paths.target slices.target(不会影响运行)
  21. 最后一行的After表示启动sockets.target paths.target slices.target启动之后再启动basic.target,如果没有这行After,这些目标将会和basic.target并行启动
  22.  
  23. 查看wants目录
  24. [root@newhostname system]# cd basic.target.wants/
  25. [root@newhostname basic.target.wants]# ll
  26. 总用量 0
  27. lrwxrwxrwx. 1 root root 23 11 7 16:12 alsa-restore.service -> ../alsa-restore.service
  28. lrwxrwxrwx. 1 root root 21 11 7 16:12 alsa-state.service -> ../alsa-state.service
  29. lrwxrwxrwx. 1 root root 32 11 7 16:12 rhel-autorelabel-mark.service -> ../rhel-autorelabel-mark.service
  30. lrwxrwxrwx. 1 root root 27 11 7 16:12 rhel-autorelabel.service -> ../rhel-autorelabel.service
  31. lrwxrwxrwx. 1 root root 25 11 7 16:12 rhel-configure.service -> ../rhel-configure.service
  32. lrwxrwxrwx. 1 root root 21 11 7 16:12 rhel-dmesg.service -> ../rhel-dmesg.service
  33. lrwxrwxrwx. 1 root root 27 11 7 16:12 rhel-loadmodules.service -> ../rhel-loadmodules.service
  34. lrwxrwxrwx. 1 root root 48 1 1 23:07 selinux-policy-migrate-local-changes@targeted.service -> ../selinux-policy-migrate-local-changes@.service
  35.  

再向上看sysinit.target

  1. [root@newhostname system]# cat sysinit.target
  2. # This file is part of systemd.
  3. #
  4. # systemd is free software; you can redistribute it and/or modify it
  5. # under the terms of the GNU Lesser General Public License as published by
  6. # the Free Software Foundation; either version 2.1 of the License, or
  7. # (at your option) any later version.
  8. [Unit]
  9. Description=System Initialization
  10. Documentation=man:systemd.special(7)
  11. Conflicts=emergency.service emergency.target
  12. Wants=local-fs.target swap.target
  13. After=local-fs.target swap.target emergency.service emergency.target
  14. 这是systemd的第一个运行目标
  15. [root@newhostname system]# ll sysinit.target.wants/
  16. 总用量 0
  17. lrwxrwxrwx. 1 root root 20 11 7 16:12 cryptsetup.target -> ../cryptsetup.target
  18. lrwxrwxrwx. 1 root root 22 11 7 16:12 dev-hugepages.mount -> ../dev-hugepages.mount
  19. lrwxrwxrwx. 1 root root 19 11 7 16:12 dev-mqueue.mount -> ../dev-mqueue.mount
  20. lrwxrwxrwx. 1 root root 28 11 7 16:12 kmod-static-nodes.service -> ../kmod-static-nodes.service
  21. lrwxrwxrwx. 1 root root 30 11 7 16:12 plymouth-read-write.service -> ../plymouth-read-write.service
  22. lrwxrwxrwx. 1 root root 25 11 7 16:12 plymouth-start.service -> ../plymouth-start.service
  23. lrwxrwxrwx. 1 root root 36 11 7 16:12 proc-sys-fs-binfmt_misc.automount -> ../proc-sys-fs-binfmt_misc.automount
  24. lrwxrwxrwx. 1 root root 32 11 7 16:12 sys-fs-fuse-connections.mount -> ../sys-fs-fuse-connections.mount
  25. lrwxrwxrwx. 1 root root 26 11 7 16:12 sys-kernel-config.mount -> ../sys-kernel-config.mount
  26. lrwxrwxrwx. 1 root root 25 11 7 16:12 sys-kernel-debug.mount -> ../sys-kernel-debug.mount
  27. lrwxrwxrwx. 1 root root 36 11 7 16:12 systemd-ask-password-console.path -> ../systemd-ask-password-console.path
  28. lrwxrwxrwx. 1 root root 25 11 7 16:12 systemd-binfmt.service -> ../systemd-binfmt.service
  29. lrwxrwxrwx. 1 root root 28 11 7 16:12 systemd-firstboot.service -> ../systemd-firstboot.service
  30. lrwxrwxrwx. 1 root root 30 11 7 16:12 systemd-hwdb-update.service -> ../systemd-hwdb-update.service
  31. lrwxrwxrwx. 1 root root 41 11 7 16:12 systemd-journal-catalog-update.service -> ../systemd-journal-catalog-update.service
  32. lrwxrwxrwx. 1 root root 27 11 7 16:12 systemd-journald.service -> ../systemd-journald.service
  33. lrwxrwxrwx. 1 root root 32 11 7 16:12 systemd-journal-flush.service -> ../systemd-journal-flush.service
  34. lrwxrwxrwx. 1 root root 36 11 7 16:12 systemd-machine-id-commit.service -> ../systemd-machine-id-commit.service
  35. lrwxrwxrwx. 1 root root 31 11 7 16:12 systemd-modules-load.service -> ../systemd-modules-load.service
  36. lrwxrwxrwx. 1 root root 30 11 7 16:12 systemd-random-seed.service -> ../systemd-random-seed.service
  37. lrwxrwxrwx. 1 root root 25 11 7 16:12 systemd-sysctl.service -> ../systemd-sysctl.service
  38. lrwxrwxrwx. 1 root root 37 11 7 16:12 systemd-tmpfiles-setup-dev.service -> ../systemd-tmpfiles-setup-dev.service
  39. lrwxrwxrwx. 1 root root 33 11 7 16:12 systemd-tmpfiles-setup.service -> ../systemd-tmpfiles-setup.service
  40. lrwxrwxrwx. 1 root root 24 11 7 16:12 systemd-udevd.service -> ../systemd-udevd.service
  41. lrwxrwxrwx. 1 root root 31 11 7 16:12 systemd-udev-trigger.service -> ../systemd-udev-trigger.service
  42. lrwxrwxrwx. 1 root root 30 11 7 16:12 systemd-update-done.service -> ../systemd-update-done.service
  43. lrwxrwxrwx. 1 root root 30 11 7 16:12 systemd-update-utmp.service -> ../systemd-update-utmp.service
  44. lrwxrwxrwx. 1 root root 33 11 7 16:12 systemd-vconsole-setup.service -> ../systemd-vconsole-setup.service
  45. 启动sysinit.target之后会启动的服务

在systemd中,target其实就是一组unit的集合

五、其他的一些操作

切换至紧急救援模式:
systemctl rescue 相当于 systemctl isolate rescue.target
切换至emergency模式:
systemctl emergency 相当于 systemctl isolate emergency.target

 

参考文献:https://wiki.archlinux.org/index.php/systemd_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)
http://blog.csdn.net/dubendi/article/details/78792169

 

文档更新时间: 2018-12-13 18:37   作者:张尚