程序my_prog
将在启动后启动。它创建了一个由root:root
拥有的Unix域套接字/tmp/my_prog.sock
。如何设计systemd路径单元?
我尝试做如下:
- 更改套接字文件的所有者
www-data:www-data
在创建后。 - 程序退出后删除套接字文件。
这是我单位的文件my_prog.service
的第一个版本:
[Unit]
Description=My Program
After=network.target
[Service]
ExecStart=/usr/local/bin/my_prog
ExecStartPost=chmod www-data:www-data /tmp/my_prog.sock
ExecStopPost=rm -f /tmp/my_prog.sock
[Install]
WantedBy=multi-user.target
这个版本有两个问题:
的
/tmp/my_prog.sock
所有者是从来没有改变 - 总是root:root
。/tmp/my_prog.sock
在此服务停止后不会被删除。
我想这是命令chmod
和rm
得到执行的太快,让我这样意外的结果:
chmod
运行之前my_prog
完成创建套接字文件,并运行之前rm
my_program
退出(my_program
禁止其套接字文件在运行时被删除?)。
什么跟随是我的第二个版本,它没有给我正确的结果,无论是:
文件my_prog.service
:
[Unit]
Description=My Program
After=network.target
[Service]
ExecStart=/usr/local/bin/my_prog
[Install]
WantedBy=multi-user.target
文件my_prog-socket.path
:
[Unit]
Description=My program - notify socket existence
[Path]
PathExists=/tmp/my_prog.sock
文件my_prog-socket.service
:
[Unit]
Description=My program - change owner and remove socket
[Service]
ExecStart=chown www-data:www-data /tmp/my_prog.sock
ExecStopPost=rm -f /tmp/my_prog.sock
我已经用尽了所有的技巧。 我的单元文件有什么问题? 有没有比上面更优雅的设计?
谢谢!
P.S.:对于那些有兴趣谁,这个旧版本/etc/init.d/my-prog
作品如预期,至少:
#!/bin/sh
### BEGIN INIT INFO
# Provides: my-program
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: My Program
# Description: My Program
### END INIT INFO
PATH=/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/local/bin/my_prog
NAME=my-program
DESC="My Program"
SCRIPTNAME=/etc/init.d/$NAME
PIDFILE=/var/run/my-prog.pid
SOCKET_FILE="/tmp/my-prog.sock"
test -x $DAEMON || exit 0
grant_socket_access()
{
#Wait program to create socket.
count=1
while [ "$count" -lt "50" ]
do
if [ -S $SOCKET_FILE ]
then
chown www-data:www-data $SOCKET_FILE
return 0
fi
sleep 0.2
count=`expr $count + 1`
done
echo >&2 "$NAME fails to grant access to Unix socket file: $SOCKET_FILE"
return 1
}
. /lib/lsb/init-functions
case "$1" in
start)
log_daemon_msg "Starting $DESC" $NAME
rm -f $SOCKET_FILE
if start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -b -m
then
grant_socket_access
else
rm -f $SOCKET_FILE
fi
log_end_msg $?
;;
stop)
log_daemon_msg "Stopping $DESC" $NAME
rm -f $SOCKET_FILE
if start-stop-daemon --stop --retry TERM/10/KILL/5 --quiet --pidfile $PIDFILE --exec $DAEMON --remove-pidfile
then
log_daemon_msg "$DESC" "$NAME stopped"
log_end_msg 0
else
log_end_msg 1
fi
;;
reload|force-reload)
log_daemon_msg "Reloading $DESC" $NAME
rm -f $SOCKET_FILE
if start-stop-daemon --stop --signal HUP --quiet --pidfile $PIDFILE --exec $DAEMON
then
grant_socket_access
log_end_msg $?
else
log_end_msg 1
fi
;;
restart)
log_daemon_msg "Restarting $DESC" $NAME
$0 stop
$0 start
;;
status)
status_of_proc -p "$PIDFILE" "$DAEMON" "$NAME" && exit 0 || exit $?
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload|status}" >&2
exit 1
;;
esac
exit 0
编辑
继@马克Stosberg友情提供的食谱,我已经修改了我原来的第一个版本刚刚有/bin/chown
和/bin/rm
。
我从新版本的ExecStopPost=/bin/rm -f /tmp/my_prog.sock
行中得到了期望的结果。然而,ExecStart=/bin/chown www-data:www-data /tmp/my_prog.sock
输出这样的错误:
chown[8388]: /bin/chown: connot access '/tmp/my_prog.socket'
谢谢!绝对可执行文件路径解决了我的第二个问题。我的第一个问题依旧。 –
查看更新的答案。 –
'.socket'在编辑期间是一个错字。 'User ='和'Group ='解决了我的问题,我认为这是最优雅的设计。非常感谢! –