我希望用 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>.mount
fstab 条目,有两种方法:
- 只需回退到标准服务单元而不是安装单元并直接控制安装命令。
- 尝试使用 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