usando la pantalla con start-stop-daemon, sysv

usando la pantalla con start-stop-daemon, sysv

Estoy intentando ejecutar un programa con una interfaz ncurse como demonio usando la pantalla. Quiero usar start-stop-daemon para administrar el proceso, pero tengo problemas para crear un script de inicio SysV.

Variables:

NAME=rtorrent
CHDIR=/opt/$NAME
DAEMON=$NAME
DAEMON_ARGS="-d -m -S $NAME $DAEMON &> /dev/null"
USER=media
GROUP=media
PIDFILE=/var/run/$NAME.pid

Actualmente, mi función de inicio es esta:

do_start()
{
    # Return
    #   0 if daemon has been started
    #   1 if daemon was already running
    #   2 if daemon could not be started
    pgrep -F $PIDFILE > /dev/null 2>&1 || return 1
    start-stop-daemon --start --quiet --make-pidfile --pidfile $PIDFILE --chuid $USER:$GROUP --chdir $CHDIR --background --exec screen -- $DAEMON_ARGS || return 2
}

Pero esto está almacenando la sleepID del proceso. Posiblemente, el demonio podría caer y dejar el sleepproceso en ejecución.

Mi función de parada necesita detener ambos, entonces tengo:

do_stop()
{
    # Return
    #   0 if daemon has been stopped
    #   1 if daemon was already stopped
    #   2 if daemon could not be stopped
    pgrep -F $PIDFILE > /dev/null 2>&1 || return 1
    for i in `ps -C $NAME -o pid=` ; do kill $i ; done
    pgrep -F $PIDFILE > /dev/null 2>&1 || return 2

    # Many daemons don't delete their pidfiles when they exit.
    rm -f $PIDFILE
}

Lo cual debería funcionar (aún no probado), pero con el problema de que desactivará cualquier otro proceso creado por cualquier otro usuario con $NAMEcomo en su nombre o argumentos.

Creo que mi solución es hacer que mi psfunción devuelva solo pids de nombres de procesos $NAMEque fueron creados por $USER. Dado que este demonio se ejecutará con un ID de usuario dedicado.

No estoy seguro de cómo obtener este resultado. ps -C $NAME -u $USER o pid=me da una lista para cada partido, pero quiero una lista para ambos partidos. En caso de que decida que este usuario puede manejar algún otro proceso más adelante.

Además, ¿qué pasa con la recarga? start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME¿Recargará el screenproceso, recargará el demonio? ¿Existe una mejor manera? Cualquier ayuda es muy apreciada.

Respuesta1

Necesitaba lo mismo para un servidor Bedrock de Minecraft como demonio, pero mipatopatogo-fuNo pude encontrar una solución... finalmente armé el siguiente script de inicio.

El punto clave a tener en cuenta es que start-stop-deamonno se utiliza para iniciar la sesión de pantalla, ejecutamos screenendemoniomodo (separado) directamente.

#!/bin/sh
### BEGIN INIT INFO
# Provides: PocketMine-MP
# Required-Start: $network $remote_fs $local_fs
# Required-Stop: $network $remote_fs $local_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: PocketMine-MP (Minecraft Bedrock/PE).
# Description: PocketMine-MP (Minecraft Bedrock/PE) Server for my children and tribe.
### END INIT INFO

# Auhtor: Daniel Sokolowski <[email protected]>

# Install by typing update-rc.d <FILEsNAME> defaults

sPATH=/sbin:/usr/sbin:/bin:/usr/bin
sNAME=PocketMine-MP
sDAEMON=/usr/local/PocketMine-MP/start.sh
sDAEMON_ARGS=""
sUSER=$sNAME # can't have - in usernmae
sCONFFILE=/usr/local/PocketMine-MP/server.properties
sPIDFILE=/var/run/$sNAME.pid
sCHDIR=/var/lib/$sNAME

# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions

# Check if user exists
if ! id -u $sUSER > /dev/null 2>&1; then
    echo "The user does not exist; adapt and execute below commands to create it:"
    echo ""
    echo "root@sh1:~# adduser --home /usr/local/$sNAME/ --shell /bin/false --no-create-home --ingroup daemon --disabled-password --disabled-login $sUSER"
    echo "..."
    echo "root@sh1:~# chown $sNAME:daemon /usr/local/$sNAME/ -R"
    exit 1
fi

# Exit if the package is not installed
[ -x $sDAEMON ] || exit 0

# Read configuration variable file if it is present
# [ -r /etc/default/$sNAME ] && . /etc/default/$sNAME

# do_start()
# =========
# Function that starts the deamon/service
# Returns: 
#    0 if daemon has been started
#    1 if daemon was already running
#    2 if daemon could not be started
do_start() {
    if ! [ -f $sCONFFILE ]; then
        echo "$sNAME is not configured so not starting. Please create configuration file `$sCONFFILE`.">&2
        return 2
    fi

    # Directory in /var/run may disappear on reboot (e.g. when tmpfs used for /var/run).
    #mkdir -p $sRUNDIR
    #chown -R $sUSER: $sRUNDIR
    #chmod -R ug=rwX,o= $sRUNDIR

    # If using `start-stop-deamon` uncomment the below and comment `screen`
<<'COMMENT' # see https://unix.stackexchange.com/questions/37411/multiline-shell-script-comments-how-does-this-work
    start-stop-daemon --start --verbose --pidfile $sPIDFILE --exec $sDAEMON --name $sNAME --user $sUSER --test || return 1 # deamon is already running
    start-stop-daemon --start --verbose --pidfile $sPIDFILE --exec $sDAEMON --name $sNAME --user $sUSER --chdir $sCHDIR -- $sDAEMON_ARGS $sDAEMON_OPTS || return 2 # deamon could not be started
    return 0 # things worked
COMMENT

    # if using screen , #NOTE,2019-feb-26: using "" after user will error out as it treats it as a "command foo - bar" command
    sudo --user=$sUSER /usr/bin/screen -d -m -S $sNAME $sDAEMON $sDAEMON_ARGS

    sleep 5
    pgrep -f PocketMine-MP | tail -1 > $sPIDFILE 

}

# do_stop()
# =========
# Function that stops the daemon/service
# Reeturns:
#    0 if daemon has been stopped
#    1 if daemon was already stopped
#    2 if daemon could not be stopped
#    other if a failure occurred    
do_stop()
{
    # if using start-stop-deamon
#<<'COMMENT'
    #start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $sPIDFILE
    start-stop-daemon --stop --verbose --retry=TERM/30/KILL/5 --pidfile $sPIDFILE
    RETVAL="$?"
    [ "$RETVAL" = 2 ] && return 2
    # Wait for children to finish too if this is a daemon that forks
    # and if the daemon is only ever run from this initscript.
    # If the above conditions are not satisfied then add some other code
    # that waits for the process to drop all resources that could be
    # needed by services started subsequently.  A last resort is to
    # sleep for some time.
    #start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
    #[ "$?" = 2 ] && return 2

    # Many daemons don\'t delete their pidfiles when they exit.
    rm -f $sPIDFILE
    sleep 5s
    return "$RETVAL"
#COMMENT

    # if using `screen` for interactive programs
}

# do_reload()
# ===========
# Function that sends a SIGHUP to the daemon/service
#
# If the daemon can reload its configuration without restarting (for example, when it is sent a SIGHUP), then implement that here.
do_reload() {

    # PocketMine does support SIGHUP https://github.com/PocketMine/PocketMine-MP/blob/master/src/pocketmine/Server.php#L2026
    #start-stop-daemon --stop --quiet --pidfile $sPIDFILE --name $sNAME --user $sUSER --signal HUP
    start-stop-daemon --stop --verbose --pidfile $sPIDFILE --name $sNAME --user $sUSER --signal HUP
}


case "$1" in
    start)
        [ "$VERBOSE" != no ] && log_daemon_msg "Starting \`$sDAEMON\` " "$sNAME"
        do_start
        case "$?" in
            0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
            2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
        esac
        ;;
    stop)
        [ "$VERBOSE" != no ] && log_daemon_msg "Stopping \`$sDAEMON\`" "$sNAME"
        do_stop
        case "$?" in
            0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
            2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
        esac
        ;;
    status)
        status_of_proc "$sDAEMON" "$sNAME" && exit 0 || exit $?
        ;;
    reload|force-reload)
        log_daemon_msg "Reloading \`$sDAEMON\`" "$sNAME"
        do_reload
        log_end_msg $?
        ;;
    restart)
        log_daemon_msg "Restarting \`$sDAEMON\`" "$sNAME"
        do_stop
        case "$?" in
            0|1)
                do_start
                case "$?" in
                    0) log_end_msg 0 ;;
                    1|*) log_end_msg 1 ;;
                esac
                ;;
            *) log_end_msg 1 ;;
        esac
        ;;
    *)
        echo "Usage: \`/etc/init.d/`basename "$0"` {start|stop|status|restart|force-reload}\`" >&2
        exit 3
        ;;
esac

exit 0

información relacionada