我需要在 systemd 启动用户之后运行一个脚本dbus.service
,并在 systemd 尝试停止之前运行另一个脚本dbus.service
。我不想修改现有的服务文件。该脚本应该在重新启动时保存和恢复加载的 CDEmu 映像。称为 cdemu 的全球服务--bus system
几年前已停止工作,因为在现代发行版中,每个用户都有自己的一组加载的虚拟映像。
我当前的解决方案是拥有两个用户服务:the-pre.service
WantedBy=dbus.service
和 the -post.service
thatRequires=dbus.service
后者随 一起自动停止dbus.service
。必须为每个需要它的用户手动启用第一项服务。它通过在后台启动来启动第二个服务systemctl start
以避免死锁。此外,第一个服务在启动后立即停止,以正确处理 dbus 重新启动。
我想知道是否有可能将服务数量减少到仅一个,可能的话使用StopWhenUnneeded
。
为了进行测试,我退出 X 会话并执行以下操作:
$ systemctl --user stop dbus
$ systemctl --user start dbus
_
# /etc/systemd/user/dbus-pre.service
[Service]
ExecStart=/usr/local/bin/dbus-hook pre-start
# will be started again when dbus restarts
RemainAfterExit=false
[Install]
# systemctl --user enable dbus-pre
WantedBy=dbus.service
_
# /etc/systemd/user/dbus-post.service
[Service]
ExecStart=/usr/local/bin/dbus-hook post-start
ExecStop=/usr/local/bin/dbus-hook pre-stop
# oneshot supposed to spare dbus until ExecStop finishes
Type=oneshot
# RemainAfterExit=true prevents immediate stop of our service
RemainAfterExit=true
[Unit]
# Requires= supposed to stop us when dbus stops
Requires=dbus.service
# After= supposed to spare dbus until our service stops
After=dbus.service
_
#!/bin/bash
# /usr/local/bin/dbus-hook
echo "$1"
case $1 in
pre-start)
echo "starting dbus-post.service..."
/usr/bin/systemctl --user start dbus-post.service >/dev/null 2>&1
;;
post-start)
echo "restoring cdemu mounts..."
if [ -f ~/.config/cdemu.save ]; then
{
read -r x
read -r x
while read -r n b f; do
if [ x"True" = x"$b" ]; then
/usr/bin/cdemu load "$n" "$f"
fi
done
} <~/.config/cdemu.save
fi
;;
pre-stop)
echo "saving cdemu mounts..."
#echo "DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS"
if /usr/bin/pgrep -u "${USER:?}" -x cdemu-daemon >/dev/null; then
mkdir -p ~/.config
/usr/bin/cdemu status >~/.config/cdemu.save
fi
;;
esac