Debian

將 socat 初始化腳本遷移到 systemd

  • September 21, 2018

我在帶有 sysVinit 的 debian 7.2 上使用 socat 和以下 init 腳本。它完美地工作:

#!/bin/bash
DESC=socat
DAEMON=/usr/bin/socat
LIB=/usr/lib/socat
SOCAT_ARGS="-d -d -lf /var/log/socat.log"

[ ! -f /etc/default/socat.conf ] || . /etc/default/socat.conf

. /lib/lsb/init-functions

PATH=/bin:/usr/bin:/sbin:/usr/sbin

[ -x $DAEMON ] || exit 0

#
#       Try to increase the # of filedescriptors we can open.
#
maxfds () {
       [ -n "$SOCAT_MAXFD" ] || return
       [ -f /proc/sys/fs/file-max ] || return 0
       [ $SOCAT_MAXFD -le 4096 ] || SQUID_MAXFD=4096
       global_file_max=`cat /proc/sys/fs/file-max`
       minimal_file_max=$(($SOCAT_MAXFD + 4096))
       if [ "$global_file_max" -lt $minimal_file_max ]
       then
               echo $minimal_file_max > /proc/sys/fs/file-max
       fi
       ulimit -n $SOCAT_MAXFD
}

start_socat() {
       start-stop-daemon --quiet --start \
               --pidfile /var/run/socat.$NAME.pid \
               --background --make-pidfile \
               --exec $DAEMON -- $SOCAT_ARGS $ARGS < /dev/null
}

stop_socat() {
       start-stop-daemon --stop --quiet --pidfile /var/run/socat.$NAME.pid --exec $DAEMON
       rm -f /var/run/socat.$NAME.pid
}

start () {
       echo "Starting $DESC:"

       maxfds
       umask 027
       cd /tmp
       if test "x$AUTOSTART" = "xnone" -o -z "x$AUTOSTART" ; then
               echo "Autostart disabled."
               exit 0
       fi
       for NAME in $AUTOSTART ; do
               ARGS=`eval echo \\\$SOCAT_$NAME`
               echo $ARGS
               start_socat
               echo " $NAME $ARGS"
       done
       return $?
}

stop () {
       echo -n "Stopping $DESC:"

       for PIDFILE in `ls /var/run/socat.*.pid 2> /dev/null`; do
               NAME=`echo $PIDFILE | cut -c16-`
               NAME=${NAME%%.pid}
               stop_socat
               echo -n " $NAME"
       done
}

case "$1" in
   start)
       log_daemon_msg "Starting socat" "socat"
       if start ; then
               log_end_msg $?
       else
               log_end_msg $?
       fi
       ;;
   stop)
       log_daemon_msg "Stopping socat" "socat"
       if stop ; then
               log_end_msg $?
       else
               log_end_msg $?
       fi
       ;;
   reload|force-reload|restart)
       log_daemon_msg "Restarting socat" "socat"
       stop
       if start ; then
               log_end_msg $?
       else
               log_end_msg $?
       fi
       ;;
       *)
       echo "Usage: /etc/init.d/$NAME {start|stop|reload|force-reload|restart}"
       exit 3
       ;;
esac

exit 0

然而,在升級到 debian 7.4 後,系統更改為 systemd。因此,為了在 systemd 上執行相同的腳本,我添加了一個包裝 /etc/init.d/socat 腳本的服務:

[Unit]
Description=Socat

[Service]
ExecStart=/etc/init.d/socat start
ExecStop=/etc/init.d/socat stop

[Install]
WantedBy=multi-user.target

當我啟動服務時,它會啟動但直接停止:

已載入:已載入(/usr/lib/systemd/system/socat.service;已啟用)

活動:自 2014 年 4 月 18 日星期五 14:09:46 +0200 以來處於非活動狀態(已死);4s 前 程序:5334 ExecStart=/etc/init.d/socat start (code=exited, status=0/SUCCESS) CGroup: name=systemd:/system/socat.service

我錯過了什麼嗎?

剛剛發現我必須使用

Type=forking

http://www.freedesktop.org/software/systemd/man/systemd.service.html中所述。

如果設置為分叉,則預計使用 ExecStart= 配置的程序將呼叫 fork() 作為其啟動的一部分。當啟動完成並設置所有通信通道時,父程序將退出。子程序繼續作為主守護程序執行。這是傳統 UNIX 守護程序的行為。如果使用此設置,建議也使用 PIDFile= 選項,以便 systemd 可以辨識守護程序的主程序。一旦父程序退出,systemd 將繼續啟動後續單元。

引用自:https://unix.stackexchange.com/questions/125382