我使用 udev 规则来识别何时插入特定的 USB 记忆棒。当它插入时,会启动一个 bash 脚本来安装一些设备。在我按照描述对 systemd-udev 服务进行一些更改后,效果非常好这里。
然而,其中一个安装失败了。它是一个保险丝合并安装座。命令本身似乎成功了,但是当ls
在安装文件夹上执行操作时,我得到一个奇怪的输出,并且无法访问该文件夹:
d????????? ? ? ? ? ? mountpoint
但如果我从终端手动运行 mount 命令,一切都很好。
无论是在启动期间插入该棒还是在系统启动后插入它都没有关系。当mount
udev 脚本调用时,挂载 fusion-mergerfs 设备不起作用。
你有什么想法?
答案1
[在 udev 规则中使用 RUN] 仅适用于短期脚本,因为如果超时后仍在运行,它们将被杀死。
即实现文件系统的 FUSE 后台进程被杀死。
我想到了一个替代方案:如果您有命令systemd-mount
,您可以尝试使用它来代替您的mount
命令。它将创建一个临时.mount
单元(而不是.service
单元),并mount
在该单元内运行程序。
我引用的来源试图为长时间运行的进程提供更通用的解决方案:
https://yakking.branchable.com/posts/systemd-2-udevd/
如果您需要运行时间更长的服务,那么您应该将其与 systemd 单元集成,方法如下定义该单元:
cat >/etc/systemd/system/[email protected] <<'EOF' [Unit] Description=My Service [Service] Type=simple ExecStart=/path/to/your/script %I EOF
并添加
ENV{SYSTEMD_WANTS}="my-service@%k.service"
到udev规则中。这将运行 /path/to/your/script 并将其传递给刚刚出现的设备的路径。
不幸的是,上述说明不适合您的情况。
您的问题不在于您的脚本本身在返回之前花费了太长时间。问题是你的脚本在启动“后台进程”后返回;实现 FUSE 文件系统的进程。当脚本完成时,systemd
认为它需要清理并终止由脚本启动的所有剩余进程。
这种情况与旧版 sysvinit 脚本非常相似。所以我们可以使用与他们相同的解决方案:
当您将 systemd 服务写入mount
FUSE 文件系统时,请勿使用 Type=simple
或Type=oneshot
。代替使用Type=forking
。