systemctl服务systemd-notify无法与非root用户一起使用

6

我有一个在Red Hat Enterprise Linux 7上使用Type=notify的服务单元和bash脚本的简单例子,我正在尝试让它工作。

当服务单元配置为以root身份启动脚本时,一切正常。但是加入User=testuser后,就会失败。虽然脚本最初会启动(如进程列表中所见),但systemctl服务从未收到指示已准备就绪的通知消息,因此它会挂起并最终超时。

[Unit]
Description=My Test
[Service]
Type=notify
User=testuser
ExecStart=/home/iatf/test.sh
[Install]
WantedBy=multi-user.target

Test.sh(由testuser拥有并具有执行权限)

#!/bin/bash

systemd-notify --status="Starting..."
sleep 5
systemd-notify --ready --status="Started"

while [ 1 ] ; do
  systemd-notify --status="Processing..."
  sleep 3
  systemd-notify --status="Waiting..."
  sleep 3
done

运行为root时,systemctl status test会显示正确的状态和从test.sh bash脚本发送的状态信息。当User=testuser时,服务挂起并超时,journalctl -xe报告如下:
Jul 15 13:37:25 tstcs03.ingdev systemd[1]: Cannot find unit for notify message of PID 7193.
Jul 15 13:37:28 tstcs03.ingdev systemd[1]: Cannot find unit for notify message of PID 7290.
Jul 15 13:37:31 tstcs03.ingdev systemd[1]: Cannot find unit for notify message of PID 7388.
Jul 15 13:37:34 tstcs03.ingdev systemd[1]: Cannot find unit for notify message of PID 7480.

我不确定这些PID是什么,因为它们在ps -ef列表中没有出现

3个回答

3

这似乎是 notify 服务类型的已知限制。

来自对 systemd 手册的拉取请求

    Due to current limitations of the Linux kernel and the systemd, this
    command requires CAP_SYS_ADMIN privileges to work
    reliably. I.e. it's useful only in shell scripts running as a root
    user.

我尝试过一些使用sudo等方法的hacky解决方案,但它们无法在systemd上运行——通常会失败。

No status data could be sent: $NOTIFY_SOCKET was not set

这是指systemd-notify试图向其发送数据的套接字 - 它在服务环境中定义,但我无法可靠地将其暴露给sudo环境。您也可以尝试使用此处描述的Python解决方法。
python -c "import systemd.daemon, time; systemd.daemon.notify('READY=1'); time.sleep(5)"

这基本上只是一种不可靠的休眠方式,而使用notify 的整个目的是为了实现可靠的服务。

在我的情况下,我只是重构了使用root作为用户的方法 - 实际服务作为主服务下所需用户的子服务。


在手册页中找不到这个了。这个问题已经解决了吗? - adrelanos
@adrelanos,我昨晚的研究表明,这个问题在systemd 246中已经得到解决(尽管它还没有在ubuntu 20.04中实现)。特别是,修复该问题的此PR首次出现在246-rc1中。 - djsavvy
2
@djsavvy 很有可能 systemd 246 永远不会出现在 20.04 中 - 鉴于 systemd 是 init 系统,它基本上被锁定在操作系统的生命周期中。如果这是你想要的东西,我建议你看看更新的操作系统。 - Andrew Lipscomb
我不明白为什么在Python解决方法中会有time.sleep(5)。我将其删除后发现有时通知无法正常工作,因为超时发生了。我很困惑是否是因为删除了sleep导致的。sleep真的必要吗? - Mariusz

0

sudo -u USERACCOUNT_LOGGED notify-send "hello"

使用sudo -u USERACCOUNT_LOGGED命令发送通知消息"hello"


-1

这与现在非常老的发行版和systemd版本无关,这个问题是关于一个单独的(现在已解决的)错误,即使没有SELinux的参与,也会导致无法正确运行。考虑提出一个新的、与SELinux相关的问题,并将这个作为答案发布。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接