Come aggiungere correttamente un demone personalizzato a init.d?


26

Ho un demone del server delle applicazioni proprietario di terze parti che può essere avviato e arrestato da un paio di righe di comando. Ho bisogno che questo demone si avvii all'avvio del sistema e si fermi correttamente all'arresto del sistema. Come posso implementarlo correttamente? È sufficiente copiare alcuni script all'interno di /etc/init.d e modificarli di conseguenza?

Risposte:


16

init.d è il vecchio sistema deprecato per avviare i demoni; è stato soppiantato da upstart . Upstart ha il vantaggio di essere molto più facile da configurare e consente il corretto sequenziamento dell'inizializzazione delle attività.

I file di configurazione per upstart vivono in / etc / init e se il tuo demone non ha pre-requisiti può essere semplice come tty1.conf:

# tty1 - getty
#
# This service maintains a getty on tty1 from the point the system is
# started until it is shut down again.

start on stopped rc RUNLEVEL=[2345]
stop on runlevel [!2345]

respawn
exec /sbin/getty -8 38400 tty1

nel qual caso puoi copiare quel file e modificarlo a piacere. Configurazioni più complesse sono meglio documentate sul sito upstart e in altre voci in / etc / init.

aggiunto in risposta al commento

Indipendentemente dal fatto che tu usi upstart o init.d, avrai comunque bisogno di un modo per determinare quando Firebird è inizializzato correttamente. Sfortunatamente, lo stesso Firebird non sembra avere un buon modo per verificare che sia installato e in esecuzione . Pertanto, la raccomandazione di inserire il programma in /etc/rc.local è sicuramente la più semplice e su Ubuntu - almeno - è garantito che venga eseguito il più tardi possibile nel processo di avvio.


1
In realtà il mio demone dipende dal server di database Firebird, che utilizza init.d.
Ivan,

12

se non si desidera migrare a UPSTART, ma si desidera l'approccio classico, è necessario:

NOTA: sto salvando il servizio e il programma con lo stesso nome in directory diverse (ma è possibile modificarlo, purché si rifletta nel file di servizio). cambia "myscriptname" e "myprogramname" in nomi reali!

  1. salva il tuo programma che verrà eseguito come servizio in / usr / sbin

    sudo cp myprogramname /usr/sbin/myscriptname

  2. creare uno script di avvio di base (utilizzare /etc/init.d/skeleton come riferimento)

  3. sposta questo script in /etc/init.d

    sudo mv /etc/init.d/myscriptname

  4. autorizzo questo script eseguibile (ho usato 775, ma è possibile impostarlo più in basso)

    sudo chmod 755 /etc/init.d/myscriptname

  5. vai a /etc/init.d

    cd /etc/init.d

  6. includere nell'elenco di avvio con bassa priorità di avvio

    sudo update-rc.d myscriptname defaults 97 03

riavviare il computer e verificare se il servizio è stato avviato correttamente

sudo ps -A --sort cmd

se il tuo servizio non si avvia correttamente, dovresti prima verificare se funziona quando viene chiamato a mano:

cd /etc/init.d
sudo service myscriptname start

di seguito includo un file di servizio di esempio che funziona davvero. confrontalo con il servizio scheletro in modo da capire cosa devi configurare. NOTA: funziona su Ubuntu 12.04 amazon cloud AWS EC2 classica implementazione LAMP (anche su Kubuntu 15.10).

#! /bin/sh
### BEGIN INIT INFO
# Provides:          
# Required-Start:    $remote_fs
# Required-Stop:     $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Sample_GT02 daemon startup script
# Description:       Sample Server for GT02 class 
### END INIT INFO

# Author: Tony Gil 
#

# Do NOT "set -e"

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="Sample Daemon"
NAME=sampleserver_gt02
DAEMON=/usr/sbin/$NAME
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
CHUID=root

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

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

# 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

#
# Function that starts the daemon/service
#
do_start()
{
   # Return
   #   0 if daemon has been started
   #   1 if daemon was already running
   #   2 if daemon could not be started
   start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
      || return 1
   start-stop-daemon --start --quiet --chuid $CHUID --pidfile $PIDFILE --exec $DAEMON -- \
      $DAEMON_ARGS \
      || return 2
}

#
# Function that stops the daemon/service
#
do_stop()
{
   # Return
   #   0 if daemon has been stopped
   #   1 if daemon was already stopped
   #   2 if daemon could not be stopped
   #   other if a failure occurred
   start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
   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 $PIDFILE
   return "$RETVAL"
}

#
# Function that sends a SIGHUP to the daemon/service
#
do_reload() {
   #
   # If the daemon can reload its configuration without
   # restarting (for example, when it is sent a SIGHUP),
   # then implement that here.
   #
   start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
   return 0
}

case "$1" in
  start)
   [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
   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 $DESC" "$NAME"
   do_stop
   case "$?" in
      0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
      2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
   esac
   ;;
  #reload|force-reload)
   #
   # If do_reload() is not implemented then leave this commented out
   # and leave 'force-reload' as an alias for 'restart'.
   #
   #log_daemon_msg "Reloading $DESC" "$NAME"
   #do_reload
   #log_end_msg $?
   #;;
  restart|force-reload)
   #
   # If the "reload" option is implemented then remove the
   # 'force-reload' alias
   #
   log_daemon_msg "Restarting $DESC" "$NAME"
   do_stop
   case "$?" in
     0|1)
      do_start
      case "$?" in
         0) log_end_msg 0 ;;
         1) log_end_msg 1 ;; # Old process is still running
         *) log_end_msg 1 ;; # Failed to start
      esac
      ;;
     *)
        # Failed to stop
      log_end_msg 1
      ;;
   esac
   ;;
  *)
   #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
   echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
   exit 3
   ;;
esac

:

1
@jakeDovresti davvero avuto il tempo di riformattare il "mio" codice. significa che l'hai testato e ha funzionato per te?
tony gil,

1
ha funzionato per me
Mario S

Upstart ora non è a favore di systemd?
Gillespie,

In effetti, upstart non è nemmeno installato sul mio recente Ubuntu. Gli script di init SysV non moriranno mai.
Chris Nadovich,

8

Crea una copia di /etc/init.d/skeleton e modificala nei punti appropriati per avviare / interrompere / riavviare il servizio. È molto ben commentato, quindi dovresti essere in grado di creare uno script init.d funzionante in pochissimo tempo.


Significa che devi anche creare collegamenti simbolici in rcX.d. Tuttavia, un aggiornamento di Ubuntu cancellerà tutti i tuoi collegamenti simbolici personalizzati.
Robin Hsu,

2
  • Aggiungi i tuoi comandi a /etc/rc.local
  • In modo che il tuo demone inizi automaticamente all'avvio del sistema.

1

pleaserunè uno script ruby ​​che tenta di risolvere il problema della creazione automatica di uno script init con un singolo comando. citando dalla sua pagina:

"Con pleaserun, puoi generare i seguenti lanciatori / script / qualunque cosa:

launchd
upstart
systemd
runit
SysV init"

Rileva inoltre quale sistema init è in uso, quindi genera lo script di conseguenza.


non sono sicuro che pleaserun esegua anche la registrazione, ma anche questo ha una registrazione: gist.github.com/naholyr/4275302
Costin Gușă,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.