4

我正在调试 systemd 关机问题。这里的问题是一些文件系统在服务仍在运行时被卸载。

一般来说,我们希望 systemd 先关闭服务,然后卸载挂载点。

但是在这里,卸载和停止服务是并行发生的。(见下文)。首先还要卸载根文件系统。

#        Unmounting /root...
         Unmounting /var/lib/ntp...
         Unmounting /etc/cron.d/local...
[  OK  ] Stopped Apply Kernel Variables.
         Unmounting /proc/fs/nfsd...
         Unmounting /tmp/rshell/trace...
         Stopping Availability of block devices...
         Unmounting /etc/timestamp...
         Unmounting /var/lib/nfs/rpc_pipefs...
         Unmounting /etc/sysconfig/clock...
[  OK  ] Removed slice system-getty.slice.
[  OK  ] Stopped Load Kernel Modules.
         Unmounting /etc/ssh/ssh_external_host_rsa_key...
[  OK  ] Stopped Create Static Device Nodes in /dev.
         Unmounting /mnt/log...
[  OK  ] Stopped Resets System Activity Logs.
         Stopping Crond Periodic Command Scheduler...
[  OK  ] Stopped Mount Restricted SFTP Jail Folders.
[  OK  ] Stopped Mount Restricted Shell Folders.
         Stopping Runs processtat...
         Unmounting /etc/ssh/ssh_external_host_ecdsa_key.pub...
[  OK  ] Stopped target RPC Port Mapper.
         Unmounting /boot...
         Unmounting /srv...
         Stopping Initializes network console logging...
[  OK  ] Stopped Crond Periodic Command Scheduler.
[FAILED] Failed unmounting /root.
[  OK  ] Unmounted /var/lib/ntp.
[  OK  ] Unmounted /etc/cron.d/local.
**[FAILED] Failed unmounting /mnt/sysimg.**
[  OK  ] Unmounted /etc/sysconfig/clock.
[  OK  ] Unmounted /usr/share/cracklib.
**[FAILED] Failed unmounting /run/netns.**
[  OK  ] Unmounted /tftpboot/state.
**[FAILED] Failed unmounting /tmp/ldap.**

我们如何在 systemd 中同步它?

一般来说,systemd-reboot.service 依赖于 final.target、shutdown.target 和 umount.target。

看起来,umount.target 和 shutdown.target 是并行执行的。

# cat /usr/lib/systemd/system/systemd-reboot.service 
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

[Unit]
Description=Reboot
Documentation=man:systemd-halt.service(8)
DefaultDependencies=no
Requires=shutdown.target umount.target final.target
After=shutdown.target umount.target final.target

[Service]
Type=oneshot
ExecStart=/usr/bin/systemctl --force reboot

我试过了, umount.target 依赖于 shutdown.target 但这没有帮助。这些卸载和服务关闭似乎总是并行发生。如果我的理解有误请指正。

请提供一些提示/建议以先正确关闭服务,然后再卸载挂载点。

4

1 回答 1

4

在您的服务单位中,尝试以下操作

BindsTo=mymount.mount
After=mymount.mount

mymount.mount必须已经存在。就我而言,我让 systemd/var/run/systemd/generator/mymount.mount根据/etc/fstab内容生成。

BindsTo=表示必须启动挂载才能启动服务,如果挂载停止则必须停止服务。但是两个单元仍然可以(几乎)并行启动和停止。你需要另一个约束。在服务可以启动之前,挂载必须达到活动状态。您将使用After=. 与其他 systemd 指令After=一样,在启动期间执行的操作在停止期间反转:必须在挂载停止之前完全停止服务。

添加了重点的相关文档。文档没有提到停止期间发生的事情,但我确认它按我们预期的那样工作..

绑定到=

配置需求依赖,风格与 Requires= 非常相似。但是,这种依赖类型更强:除了 Requires= 的效果外,它还声明如果绑定到的单元停止,则该单元也将停止。这意味着绑定到另一个单元的单元突然进入非活动状态也将被停止。单元可能由于不同的原因突然、意外地进入非活动状态:服务单元的主进程可能会自行终止,设备单元的后备设备可能被拔出,或者挂载单元的挂载点可能在没有涉及的情况下被卸载系统和服务管理器。

当在同一单元上与 After= 结合使用时,BindsTo= 的行为会更加强大。在这种情况下,严格绑定到的单元必须处于活动状态才能使该单元也处于活动状态。 这不仅意味着一个绑定到另一个单元的单元突然进入非活动状态,而且一个绑定到另一个单元的单元由于条件检查失败(例如 ConditionPathExists=、ConditionPathIsSymbolicLink=、……见下文)将被跳过停止,它应该正在运行。因此,在许多情况下,最好将 BindsTo= 与 After= 结合使用。

当在 a.service 上使用 BindsTo=b.service 时,此依赖关系将在 b.service 的属性列表中显示为 BoundBy=a.service。BoundBy= 不能直接指定依赖。

于 2018-10-18T20:29:16.673 回答