Migrer le script socat init vers systemd

8

J'utilise socat avec le script init suivant sur debian 7.2 avec sysVinit. Cela fonctionne parfaitement:

#!/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

Cependant, après une mise à niveau vers Debian 7.4, le système est passé à systemd. Donc, pour exécuter le même script sur systemd, j'ai ajouté un service qui enveloppe le script /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

Lorsque je démarre le service, il démarre mais s'arrête directement:

Chargé: chargé (/usr/lib/systemd/system/socat.service; activé)
Actif: inactif (mort) depuis vendredi 18 avril 2014 14:09:46 +0200; Il y a 4s Processus: 5334 ExecStart = / etc / init.d / socat start (code = exit, status = 0 / SUCCESS) CGroup: name = systemd: /system/socat.service

Suis-je en train de manquer quelque chose?

Perdu dans OWL
la source
Suis-je en train de manquer quelque chose? Oui, vous avez manqué la migration du script init.d vers systemd :)
Piotr Dobrogost

Réponses:

8

Je viens de comprendre que je dois utiliser

Type=forking

comme décrit dans http://www.freedesktop.org/software/systemd/man/systemd.service.html .

S'il est défini sur forking, le processus configuré avec ExecStart = appellera fork () dans le cadre de son démarrage. Le processus parent devrait se terminer lorsque le démarrage est terminé et que tous les canaux de communication sont configurés. L'enfant continue de s'exécuter en tant que processus démon principal. C'est le comportement des démons UNIX traditionnels. Si ce paramètre est utilisé, il est recommandé d'utiliser également l'option PIDFile =, afin que systemd puisse identifier le processus principal du démon. systemd procédera au démarrage des unités de suivi dès la fin du processus parent.

Perdu dans OWL
la source
1

Pour socat , j'utilise une approche systemd pure . Voici un exemple de bouclage série:

[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

Cela peut être écrit dans /etc/systemd/system/socat-serial-lo.service(dans Ubuntu 16.04+), puis:

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

Un avantage de cette méthode est que la ligne de commande définie par ExecStartpeut être testée directement depuis la ligne de commande sans altérations, afin de tester la commande.

jjmontes
la source