Verwendung von screen mit Start-Stop-Daemon, sysv

Verwendung von screen mit Start-Stop-Daemon, sysv

Ich versuche, ein Programm mit einer Ncurse-Schnittstelle als Daemon über screen auszuführen. Ich möchte den Prozess mit dem Start-Stop-Daemon verwalten, habe aber Probleme beim Erstellen eines SysV-Init-Skripts.

Variablen:

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

Derzeit ist meine Startfunktion diese:

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
}

Aber hier wird die sleepProzess-ID gespeichert. Es ist denkbar, dass der Daemon abstürzt und den sleepProzess weiterlaufen lässt.

Meine Stoppfunktion muss beides stoppen, also habe ich:

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
}

Das sollte funktionieren (noch nicht getestet), besteht aber mit dem Problem, dass dadurch alle anderen Prozesse zum Absturz gebracht werden, die von anderen Benutzern erstellt wurden und $NAMEin deren Namen oder Argumenten „as“ vorkommt.

Ich denke, meine Lösung besteht darin, dass meine psFunktion nur PIDs von Prozessnamen zurückgibt $NAME, die von erstellt wurden $USER. Da dieser Daemon unter einer dedizierten Benutzer-ID ausgeführt wird.

Ich bin nicht sicher, wie ich diese Ausgabe bekomme. ps -C $NAME -u $USER o pid=gibt mir eine Liste für jede Übereinstimmung, aber ich möchte eine Liste für beide Übereinstimmungen. Für den Fall, dass ich entscheide, kann dieser Benutzer später einen anderen Prozess übernehmen.

Und was ist mit dem Neuladen? start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAMEWird der screenProzess neu geladen, wird der Daemon neu geladen? Gibt es einen besseren Weg? Für jede Hilfe bin ich sehr dankbar.

Antwort1

Ich brauchte dasselbe für einen Minecraft Bedrock Server als Daemon, aber meinduckduckgo-fuIch konnte keine Lösung finden ... habe es aber schließlich geschafft, das folgende Init-Skript zu kompilieren.

Der entscheidende Punkt ist, dass start-stop-deamones nicht zum Starten der Bildschirmsitzung verwendet wird. Wir führen es screeninDaemon(getrennter) Modus direkt.

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

verwandte Informationen