Перенос сценария инициализации socat в systemd


8

Я использую socat со следующим скриптом инициализации на Debian 7.2 с sysVinit. Работает отлично:

#!/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; включен)
Активен: неактивен (мертв) с пятницы, 18 апреля 2014 г. 14:09:46 +0200; 4s ago Процесс: 5334 ExecStart = / etc / init.d / запуск socat (код = выход, состояние = 0 / УСПЕХ) CGroup: name = systemd: /system/socat.service

Я что-то пропустил?


Я что-то пропустил? Да, вы фактически пропустили перенос сценария init.d в systemd :)
Петр Доброгост,

Ответы:


8

Просто понял, что я должен использовать

Type=forking

как описано в http://www.freedesktop.org/software/systemd/man/systemd.service.html .

Если установлено значение разветвления, ожидается, что процесс, настроенный с помощью ExecStart =, будет вызывать fork () как часть своего запуска. Ожидается, что родительский процесс завершится после завершения запуска и настройки всех каналов связи. Дочерний объект продолжает работать как основной процесс демона. Это поведение традиционных демонов UNIX. Если используется этот параметр, рекомендуется также использовать параметр PIDFile =, чтобы systemd мог определить основной процесс демона. systemd продолжит запуск последующих модулей, как только завершится родительский процесс.


1

Для socat я использую чисто системный подход. Это пример для последовательной обратной связи:

[Unit]
Description=Socat Serial Loopback
#Before=my-other.service

[Service]
Type=simple
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=socat-serial-lo

ExecStart=/usr/bin/socat -d -d pty,raw,echo=0,link=/tmp/seriallo-a pty,raw,echo=0,link=/tmp/seriallo-b
Restart=always

[Install]
WantedBy=multi-user.target

Это можно записать /etc/systemd/system/socat-serial-lo.service(в Ubuntu 16.04+), а затем:

systemctl daemon-reload
systemctl start socat-serial-lo
systemctl enable socat-serial-lo  # (to start it during bootup)

Одним из преимуществ этого метода является то, что определенная команда ExecStartможет быть протестирована непосредственно из командной строки без изменений, чтобы протестировать команду.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.