使用服务单元代替安装单元

使用服务单元代替安装单元

我希望用 Systemd 安装单元和 systemctl 调用来表达以下命令序列:

# mount /some/path /some/mountpoint -o ro
# mount /some/mountpoint -o remount,rw
# touch /some/mountpoint/foo # placeholder for write action
# mount /some/mountpoint -o remount,ro

概念问题似乎是 systemd.mount(5) 在安装点上运行。由于单元是通过将完整路径传递到 systemctl 来激活的,因此同一安装点不能有多个安装单元。模板也不适用于安装单元。

那么它是怎样工作的?有可能吗?

答案1

使用服务单元代替安装单元

带有 mount 命令的简单一次性服务单元适用于我的重新安装用例(我认为它也适用于您的用例)。

鉴于挂载通常已在中定义,/etc/fstab并且 systemd 自动生成<mountpoint>.mountfstab 条目,有两种方法:

  1. 只需回退到标准服务单元而不是安装单元并直接控制安装命令。
  2. 尝试使用 systemd 覆盖吗? (未测试,不认为可行)
    • 安装单元有严格的要求,即根据安装点命名该单元,因此可能无法为同一安装点运行两个单独的安装单元(问题中已注明)。
    • 因此,这可能不适用于重新挂载,假设它仅覆盖从 fstab 生成的原始挂载单元定义,并且不会执行两次。
    • 如果尝试,由于重新安装选项应用于尚未安装的内容,原始安装很可能会失败。

例子

我需要类似的东西,并在尝试使用 systemd 安装单元类型时遇到了以下问题(因为我没有根据安装点定义我的单元文件名):

Where= setting doesn't match unit name. Refusing.

给定一个绑定挂载到具有更多空间的数据目录,但是父挂载点设置了 nosuid 和 nodev,我需要在 /var/lib/lxc 为 lxc 添加 suid 和 dev 权限。

服务单位档案/etc/systemd/system/lxc-remount.service

[Unit]
Description=Remount the /var/lib/lxc folder with suid and dev privileges
Requires=var-lib-lxc.mount
After=var-lib-lxc.mount
Before=lxc.service

[Service]
Type=oneshot
ExecStart=/bin/mount -o remount,rw,suid,dev,relatime,discard,data=ordered /var/lib/lxc

[Install]
WantedBy=lxc.service

使其生效的命令:

$ sudo systemctl daemon-reload
$ sudo systemctl enable lxc-remount.service
Created symlink from /etc/systemd/system/lxc.service.wants/lxc-remount.service to /etc/systemd/system/lxc-remount.service.
$ sudo systemctl start lxc-remount.service

答案2

这是技术上systemd可以在安装单元顶部实现此功能。因此我不能简单地回答“不”。这种方法有一些缺点。

另一方面,通过使用命令执行重新安装部分,您可以满足除“使用 systemd 安装单元”之外的所有要求mount。请注意,systemd人们通常很乐意使用该mount命令。例如,如果您使用 临时卸载文件系统umount,则 systemd 挂载单元将被标记为inactive。当您手动mount挂载文件系统时,systemd 会为其创建一个临时挂载单元。 (注意它不会创建一个单位文件)。

所以在实践中我建议使用该mount命令来执行重新安装操作。

如果您正在阅读此问题并且您有其他原因不使用该mount命令,请提出一个新问题并说明具体原因。在不知道任何此类原因的情况下,我不建议实际使用以下方法。它仅用于教育目的。


您需要更改Options=安装单元的设置,然后更改systemctl reload安装单元。

您可以使用一个嵌入式文件来执行此操作,该文件在/run/systemd/system/.因此您不必编辑磁盘配置。如果系统中途崩溃,也不存在留下过时配置的风险。

然而,它并不是很“干净”。它仍然存在风险,您的命令中途被中断,并且您可以在中留下过时的配置place - 内核中挂载的状态以及 systemd 中挂载的状态。无论如何,在使用时第一个问题都会存在mount。但这意味着您可以解决第一个问题并忘记第二个问题。那么第二个问题可能会在以后引起很多混乱。

请注意,当您创建插入文件或编辑单元文件时,您还必须在重新加载安装单元之前运行systemctl daemon-reload以获取新值。Option=

这是第二个问题 - 我真的不建议使用它,至少现在是这样。 systemctl daemon-reload是一个有点重量级的操作:-)。如果你运气不好的话,它也可能会产生不必要的副作用。在某些时候添加了一些代码,以重新加载单个单元文件,但我还没有看到它被记录为可用的功能。

(我还注意到其中一个特殊单元目录 /run/systemd/system.control/被描述为“使用 dbus API 创建的瞬态配置”。我相信这用于跟踪资源控制设置和其他一些设置的更改。我认为这些是特殊情况,可以使用 进行更改systemctl --runtime set-property。我认为它们不需要完全重新加载)。

答案3

为什么不使用脚本?如何让 systemd 暂停以供您编辑?

我认为脚本非常适合您,例如:

#!/bin/bash
mount /some/mountpoint -o remount,rw
bash
# do some editing
# touch /some/mountpoint/foo # placeholder for write action
exit the shell/ctrl-d
mount /some/mountpoint -o remount,ro

相关内容