Systemd

Posted 莫孟林

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Systemd相关的知识,希望对你有一定的参考价值。

一、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、服务的常规操作

 

systemctl start httpd 开启某项服务
systemctl stop httpd 停止某项服务
systemctl restart httpd 重启某项服务
systemctl reload httpd 重新加载某项服务的配置文件
systemctl try-restart httpd 已启动才重启,否则不做操作
systemctl reload-or-restart httpd 重载或重启服务:先加载,再启动
systemctl reload-or-try-restart http 重载或条件式重启服务
systemctl mask httpd 禁止httpd服务启动
systemctl umask httpd 解禁httpd服务启动

 

2、服务的查看

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

 

systemctl --failed -t|--type= unit 查看失败的unit
systemctl is-active httpd 显示httpd服务是否是活动状态
systemctl list-unit-files -t|--type= unit 查看unit的启用和禁用状态
systemctl list-units -t | --type= unit -a | --all 列出所有unit单元
systemctl list-units -t |--type= unit 列出活动状态的所有unit单元
systemctl status httpd 查看httpd服务的运行状态

 

服务状态

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)

 

systemctl isolate (multi-user.target|graphical.target) 切换当前的运行目标
systemctl set-default name.target 设置开启启动的默认目标
systemctl list-dependencies graphical.target 查看目标的依赖关系(也可以是服务)

 

4、演示

常规服务的操作:

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

服务的查看:

  1. [[email protected] /]# systemctl --failed -t service #查看失败的服务
  2. UNIT LOAD ACTIVE SUB DESCRIPTION
  3. ● httpd.service loaded failed failed The Apache HTTP Server
  4. LOAD = Reflects whether the unit definition was properly loaded.
  5. ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
  6. SUB = The low-level unit activation state, values depend on unit type.
  7. 1 loaded units listed. Pass --all to see loaded but inactive units, too.
  8. To show all installed unit files use ‘systemctl list-unit-files‘.
  9. [[email protected] /]# systemctl --failed #查看所有启动失败的unit
  10. UNIT LOAD ACTIVE SUB DESCRIPTION
  11. ● httpd.service loaded failed failed The Apache HTTP Server
  12. LOAD = Reflects whether the unit definition was properly loaded.
  13. ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
  14. SUB = The low-level unit activation state, values depend on unit type.
  15. 1 loaded units listed. Pass --all to see loaded but inactive units, too.
  16. To show all installed unit files use ‘systemctl list-unit-files‘.
  17. [[email protected] /]# systemctl stop httpd
  18. [[email protected] /]# systemctl is-active httpd #查看服务状态
  19. unknown
  20. [[email protected] /]# echo $? #值不为0都是未启动
  21. 3
  22. [[email protected] /]# setenforce 0
  23. [[email protected] /]# systemctl start httpd
  24. [[email protected] /]# systemctl is-active httpd
  25. active
  26. [[email protected] /]# echo $? #值为0表示服务正在运行
  27. 0
  1. [[email protected] /]# 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. [[email protected] /]# systemctl list-unit-files #打印所有的unit状态
  17. UNIT FILE STATE
  18. proc-sys-fs-binfmt_misc.automount static
  19. dev-hugepages.mount static
  20. dev-mqueue.mount static
  21. proc-fs-nfsd.mount static
  22. proc-sys-fs-binfmt_misc.mount static
  23. sys-fs-fuse-connections.mount static
  24. sys-kernel-config.mount static
  25. sys-kernel-debug.mount static
  26. tmp.mount disabled
  27. var-lib-nfs-rpc_pipefs.mount static
  28. brandbot.path disabled
  29. cups.path enabled
  30. systemd-ask-password-console.path static
  31. systemd-ask-password-plymouth.path static
  32. systemd-ask-password-wall.path static
  33. session-25.scope static
  34. session-27.scope static
  35. abrt-ccpp.service enabled
  36. abrt-oops.service enabled
  37. abrt-pstoreoops.service disabled
  38. abrt-vmcore.service enabled
  39. abrt-xorg.service enabled
  40. abrtd.service enabled
  41. accounts-daemon.service enabled
  42. [[email protected] /]# systemctl list-unit-files -t service #打印unit为service的服务状态
  43. UNIT FILE STATE
  44. abrt-ccpp.service enabled
  45. abrt-oops.service enabled
  46. abrt-pstoreoops.service disabled
  47. abrt-vmcore.service enabled
  48. abrt-xorg.service enabled
  49. abrtd.service enabled
  50. accounts-daemon.service enabled
  51. alsa-restore.service static
  52. alsa-state.service static
  53. alsa-store.service static
  54. anaconda-direct.service static
  55. anaconda-nm-config.service static
  56. anaconda-noshell.service static
  57. anaconda-pre.service static
  58. [email protected] static
  59. anaconda-sshd.service static
  60. [email protected] static
  61. anaconda.service static
  62. arp-ethers.service disabled
  63. atd.service enabled
  64. auditd.service enabled
  65. auth-rpcgss-module.service static
  66. autofs.service disabled
  67. [email protected] enabled
  68. blk-availability.service disabled
  69. bluetooth.service enabled
  70. brandbot.service static
  71. canberra-system-bootup.service disabled
  72. canberra-system-shutdown-reboot.service disabled
  73. canberra-system-shutdown.service disabled
  74. certmonger.service disabled
  75. cgconfig.service disabled
  76. cgdcbxd.service disabled
  77. cgred.service disabled
  78. [email protected] static
  79. chrony-wait.service disabled
  80. chronyd.service enabled
  81. colord.service static
  82. [email protected] static
  83. console-getty.service disabled
  84. console-shell.service disabled
  85. [email protected] static

 

演示运行级别:

首先,我们先说默认的target,设置方法:systemctl set-default name.target,这里我们就已设置图形界面为例

  1. [[email protected] 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. 它执行的动作,很简单,把"/etc/systemd/system/default.target"这个软连接删除了,建立新的target到/etc/systemd/system/default.target
  5. 现在我们在当前的target切换到其他的target中(当前是字符界面,我们切换到图形界面,因为我没有装图形,所以不会真正的切过去)
  6. [[email protected] default.target.wants]# systemctl isolate graphical.target
  7. [[email protected] default.target.wants]#
  8. 执行成功了?为什么没报错,这个问题后面再讲,马上就讲,请继续看

 

四、服务Unit文件

所有的systemd单元都存放在了”/usr/lib/systemd/system/”这个目录下,不管是target还是service还是socket都在这里。

1、我们查看一个service的unit,来看看它的结构,就以httpd的为例吧

  1. [[email protected] 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. [Service]
  8. Type=notify
  9. EnvironmentFile=/etc/sysconfig/httpd
  10. ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
  11. ExecReload=/usr/sbin/httpd $OPTIONS -k graceful
  12. ExecStop=/bin/kill -WINCH ${MAINPID}
  13. # We want systemd to give httpd some time to finish gracefully, but still want
  14. # it to kill httpd after TimeoutStopSec if something went wrong during the
  15. # graceful stop. Normally, Systemd sends SIGTERM signal right after the
  16. # ExecStop, which would kill httpd. We are sending useless SIGCONT here to give
  17. # httpd time to finish.
  18. KillSignal=SIGCONT
  19. PrivateTmp=true
  20. [Install]
  21. WantedBy=multi-user.target
  22. [[email protected] 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. [[email protected] system]# cat <<EOF >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. [[email protected] system]# systemctl start bak.service
  11. [[email protected] 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. 106 15:17:26 newhostname echo[2832]: ok
  16. 106 15:17:28 newhostname systemd[1]: Started backup /etc.
  17. 106 15:17:28 newhostname systemd[1]: Starting backup /etc...
  18. 106 15:17:28 newhostname echo[2840]: ok
  19. 106 15:17:29 newhostname systemd[1]: Started backup /etc.
  20. 106 15:17:29 newhostname systemd[1]: Starting backup /etc...
  21. 106 15:17:29 newhostname echo[2848]: ok
  22. 106 15:17:29 newhostname systemd[1]: Started backup /etc.
  23. 106 15:17:29 newhostname systemd[1]: Starting backup /etc...
  24. 106 15:17:29 newhostname echo[2856]: ok

 

 

2、socket Unit

Systemd引用了socket这种unit,从而替代了以前系统的超级守护进程xinetd,之前以来xinetd的服务,systemd可以完全接手,下面我们就以telnet服务为例

  1. 首先我们启动telnet服务(telnet是一个socket单元,在systemd中)
  2. [[email protected] /]# systemctl start telnet.socket
  3. [[email protected] /]#
  4. 我们来查看一下链接
  5. [[email protected] /]# ss -antp | grep 23
  6. LISTEN 0 128 :::23 :::* users:(("systemd",pid=1,fd=29))
  7. 我们可以看到数据的最后一列,telent端口是由systemd来管理的

 

其实telent服务平时是不启动的,当有数据接收时才会触发telnet服务启动,而telnet服务也是一个unit单元,命名为[email protected],我们可以再在/usr/lib/systemd/system/下查看一下

  1. [[email protected] /]# cat //usr/lib/systemd/system/[email protected]
  2. [Unit]
  3. Description=Telnet Server
  4. After=local-fs.target
  5. [Service]
  6. ExecStart=-/usr/sbin/in.telnetd
  7. StandardInput=socket

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

2、target单元

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

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

 

systemd-update-utmp-runlevel.service 服务 用于在 SysV 运行级发生变化时,更新 utmp 与 wtmp 文件, 以及记录审计日志。

结合上面的信息,我们得出一个结论,那么就是切换到图形界面,实际上是在原来字符界面的基础上又启动了一个display-manager.service,但它是一个弱依赖,在我的机器上并没有安装图形,但是systemd-update-utmp-runlevel.service又真实运行了,那么我们查看一下一下现在的运行目标

  1. [[email protected] system]# systemctl get-default
  2. multi-user.target #现在的运行目标
  3. [[email protected] system]# runlevel #为了展示兼容以前
  4. N 3
  5. [[email protected] system]# systemctl isolate graphical.target #切换成图形
  6. [[email protected] system]# runlevel
  7. 3 5
  8. 实际上我们并没有启动图形,因为没有安装,但是切换操作影响了systemd-update-utmp-runlevel.service这个服务,所以显示的运行级别出现了变化

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

  1. [[email protected] 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. LOAD = Reflects whether the unit definition was properly loaded.
  23. ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
  24. SUB = The low-level unit activation state, values depend on unit type.
  25. 19 loaded units listed. Pass --all to see loaded but inactive units, too.
  26. To show all installed unit files use ‘systemctl list-unit-files‘.

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

  1. [[email protected] 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. [Unit]
  9. Description=Multi-User System
  10. Documentation=man:systemd.special(7)
  11. Requires=basic.target
  12. Conflicts=rescue.service rescue.target
  13. After=basic.target rescue.service rescue.target
  14. AllowIsolate=yes
  15. 最主要的还是这几行
  16. Requires=basic.target #强依赖
  17. Conflicts=rescue.service rescue.target #与之冲突的目标
  18. After=basic.target rescue.service rescue.target #在这些服务启动之后才会启动
  19. AllowIsolate=yes #表示可以切换

我们查看multi-user.target.wants

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

我们再向上看,basic.target

  1. [[email protected] multi-user.target.wants]# cd ..
  2. [[email protected] 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. [Unit]
  10. Description=Basic System
  11. Documentation=man:systemd.special(7)
  12. Requires=sysinit.target
  13. After=sysinit.target
  14. Wants=sockets.target timers.target paths.target slices.target
  15. After=sockets.target paths.target slices.target
  16. basic.target强制依赖sysinit.target
  17. 再启动basic.target时,希望启动sockets.target timers.target paths.target slices.target(不会影响运行)
  18. 最后一行的After表示启动sockets.target paths.target slices.target启动之后再启动basic.target,如果没有这行After,这些目标将会和basic.target并行启动
  19. 查看wants目录
  20. [[email protected] system]# cd basic.target.wants/
  21. [[email protected] basic.target.wants]# ll
  22. 总用量 0
  23. lrwxrwxrwx. 1 root root 23 117 16:12 alsa-restore.service -> ../alsa-restore.service
  24. lrwxrwxrwx. 1 root root 21 117 16:12 alsa-state.service -> ../alsa-state.service
  25. lrwxrwxrwx. 1 root root 32 117 16:12 rhel-autorelabel-mark.service -> ../rhel-autorelabel-mark.service
  26. lrwxrwxrwx. 1 root root 27 117 16:12 rhel-autorelabel.service -> ../rhel-autorelabel.service
  27. lrwxrwxrwx. 1 root root 25 117 16:12 rhel-configure.service -> ../rhel-configure.service
  28. lrwxrwxrwx. 1 root root 21 117 16:12 rhel-dmesg.service -> ../rhel-dmesg.service
  29. lrwxrwxrwx. 1 root root 27 117 16:12 rhel-loadmodules.service -> ../rhel-loadmodules.service
  30. lrwxrwxrwx. 1 root root 48 11 23:07 [email protected] -> ../[email protected]

再向上看sysinit.target

  1. [[email protected] 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. [[email protected] system]# ll sysinit.target.wants/
  16. 总用量 0
  17. lrwxrwxrwx. 1 root root 20 117 16:12 cryptsetup.target -> ../cryptsetup.target
  18. lrwxrwxrwx. 1 root root 22 117 16:12 dev-hugepages.mount -> ../dev-hugepages.mount
  19. lrwxrwxrwx. 1 root root 19 117 16:12 dev-mqueue.mount -> ../dev-mqueue.mount
  20. lrwxrwxrwx. 1 root root 28 117 16:12 kmod-static-nodes.service -> ../kmod-static-nodes.service
  21. lrwxrwxrwx. 1 root root 30 117 16:12 plymouth-read-write.service -> ../plymouth-read-write.service
  22. lrwxrwxrwx. 1 root root 25 117 16:12 plymouth-start.service -> ../plymouth-start.service
  23. lrwxrwxrwx. 1 root root 36 117 16:12 proc-sys-fs-binfmt_misc.automount -> ../proc-sys-fs-binfmt_misc.automount
  24. lrwxrwxrwx. 1 root root 32 117 16:12 sys-fs-fuse-connections.mount -> ../sys-fs-fuse-connections.mount
  25. lrwxrwxrwx. 1 root root 26 117 16:12 sys-kernel-config.mount -> ../sys-kernel-config.mount
  26. lrwxrwxrwx. 1 root root 25 117 16:12 sys-kernel-debug.mount -> ../sys-kernel-debug.mount
  27. lrwxrwxrwx. 1 root root 36 117 16:12 systemd-ask-password-console.path -> ../systemd-ask-password-console.path
  28. lrwxrwxrwx. 1 root root 25 117 16:12 systemd-binfmt.service -> ../systemd-binfmt.service
  29. lrwxrwxrwx. 1 root root 28 117 16:12 systemd-firstboot.service -> ../systemd-firstboot.service
  30. lrwxrwxrwx. 1 root root 30 117 16:12 systemd-hwdb-update.service -> ../systemd-hwdb-update.service
  31. lrwxrwxrwx. 1 root root 41 117 16:12 systemd-journal-catalog-update.service -> ../systemd-journal-catalog-update.service
  32. lrwxrwxrwx. 1 root root 27 117 16:12 systemd-journald.service -> ../systemd-journald.service
  33. lrwxrwxrwx. 1 root root 32 117 16:12 systemd-journal-flush.service -> ../systemd-journal-flush.service
  34. lrwxrwxrwx. 1 root root 36 117 16:12 systemd-machine-id-commit.service -> ../systemd-machine-id-commit.service
  35. lrwxrwxrwx. 1 root root 31 117 16:12 systemd-modules-load.service -> ../systemd-modules-load.service
  36. lrwxrwxrwx. 1 root root 30 117 16:12 systemd-random-seed.service -> ../systemd-random-seed.service
  37. lrwxrwxrwx. 1 root root 25 117 16:12 systemd-sysctl.service -> ../systemd-sysctl.service
  38. lrwxrwxrwx. 1 root root 37 117 16:12 systemd-tmpfiles-setup-dev.service -> ../systemd-tmpfiles-setup-dev.service
  39. lrwxrwxrwx. 1 root root 33 117 16:12 systemd-tmpfiles-setup.service -> ../systemd-tmpfiles-setup.service
  40. lrwxrwxrwx. 1 root root 24 117 16:12 systemd-udevd.service -> ../systemd-udevd.service
  41. lrwxrwxrwx. 1 root root 31 117 16:12 systemd-udev-trigger.service -> ../systemd-udev-trigger.service
  42. lrwxrwxrwx. 1 root root 30 117 16:12 systemd-update-done.service -> ../systemd-update-done.service
  43. lrwxrwxrwx. 1 root root 30 117 16:12 systemd-update-utmp.service -> ../systemd-update-utmp.service
  44. lrwxrwxrwx. 1 root root 33 117 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

以上是关于Systemd的主要内容,如果未能解决你的问题,请参考以下文章

Node应用的Systemd启动(转)

如何在systemd中添加service

如何通过 python 和 dbus (systemd-run like) 创建 systemd 瞬态计时器和服务?

systemd 使用rc.local 说明

systemd --switched-root --deserialize 参数说明

一个小BUG,引出对Linux启动机制Systemd的代码分析