在 systemd 中停止服务之前卸载文件系统

san*_*dra 9 linux system-dependent system-shutdown systemd

我正在调试 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.**
Run Code Online (Sandbox Code Playgroud)

我们如何在 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
Run Code Online (Sandbox Code Playgroud)

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

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

Phi*_* A. 8

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

\n
BindsTo=mymount.mount\nAfter=mymount.mount\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

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

\n

添加了重点的相关文档。该医生没有提及停止期间发生的情况,但我确认它按我们的预期工作。

\n
\n

绑定到=

\n

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

\n

当在同一单元上与 After= 结合使用时,\nBindsTo= 的行为甚至更强。在这种情况下,严格绑定到的单元必须处于活动状态,该单元也处于活动状态。\n这不仅意味着绑定到另一个单元的单元突然进入\n活动状态,还意味着绑定到另一个单元的单元由于条件检查失败而\n被跳过(例如 ConditionPathExists=、\nConditionPathIsSymbolicLink=、\xe2\ x80\xa6 \xe2\x80\x94 见下文)将被停止,\n应该正在运行。因此,在许多情况下,最好将 BindsTo=\n 与 After= 结合起来。

\n

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

\n
\n