我有一个deamon,其中一次只能运行一个实例。守护程序是更大的应用程序的一部分。我这样做了:
open()
/tmp/prog.pid
O_CREAT | O_RDWR
,权限0666.权限实际上变为0664,可能是因为umask(?)flock()
返回的文件描述符的open()
,LOCK_EX | LOCK_NB
这是我第一次拥有的。我的守护进程退出SIGTERM
和SIGINT
,但事实证明退出后锁没有被释放。我在man 1 flock
的帮助下意识到(奇怪的是不在man 2 flock
中),如果“封闭的命令组可能已经分叉了一个不应该持有锁的后台进程”,则可能需要手动解锁。由于我正在开发一个守护进程,所以这很简单,所以我现在在退出时手动解锁。
现在我的问题是:有几个用户可能正在运行该守护进程。
如果user1正在运行守护程序,我希望user2能够将其终止并重新启动它。
锁定的文件/tmp/prog.pid
拥有权限0664,所有者user1,group user1。
停止脚本prog_stop
会杀死应用程序中涉及的所有进程(它需要超级用户权限,我很好)。它也会杀死守护进程。当user2运行prog_stop
时,锁被释放(我相信),但是user2 无法启动自己的守护进程,因为它既不是锁文件的所有者,也不是其组中的所有者。< / p>
几种可能的解决方案:
newgrp
的帮助。容易忘记,不容易强制人们这样做。可能在用于启动应用程序的脚本中设置当前组?prog_stop
中的锁定文件。缺点:我从C文件中打开文件,其中定义了路径字符串。我需要在stop脚本中使用path编写(并维护!)完全相同的文件名。守护程序的锁定文件必须非常常见。处理这个问题的标准方法是什么?
答案 0 :(得分:1)
锁定文件的标准方法是将守护程序转换为服务,并需要sudo
(或通过其他方式成为root
)来启动和停止它。
现在你可以给文件一个特定的组;然后,该组中的用户可以对其进行修改。他们可以使用newgrp
,但最好将其添加到使用usermod --append --groups=foo bar
的群组中(将用户bar
添加到群组foo
;用户保留原始版本GID和他们拥有的所有其他团体)。重新启动后,您可以使用id bar
验证此内容。
这一切都非常繁琐。当我需要这样的东西时,我会创建一个套接字。套接字会被创建它们的进程终止(因此不需要清理)。套接字也可用于与正在运行的守护进程通信(给我你的状态,关机,甚至重启,......)。
我使用的是我编译到应用程序中的默认端口号,但我也使用环境变量来覆盖默认值。
确保创建一个侦听localhost
的套接字;否则互联网上的任何人都可以与之交谈。