Como adicionar corretamente um daemon personalizado ao init.d?

25

Eu tenho um daemon de servidor de aplicativos proprietários de terceiros que pode ser iniciado e interrompido por algumas linhas de comando. Eu preciso que este daemon inicie quando o sistema for inicializado e corretamente parado no desligamento do sistema. Como faço para implementar corretamente isso? É suficiente copiar algum script dentro de /etc/init.d e modificá-lo de acordo?

    
por Ivan 25.12.2010 / 09:01

5 respostas

16

init.d é o sistema antigo e obsoleto para iniciar daemons; é suplantado por upstart . O Upstart tem a vantagem de ser muito mais fácil de configurar e permite o sequenciamento adequado da inicialização da tarefa.

Os arquivos de configuração para o upstart vivem em / etc / init e, se o seu daemon não tiver pré-requisitos, pode ser tão simples quanto o 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

caso em que você pode copiar esse arquivo e modificar a gosto. Configurações mais complexas são melhor documentadas no site upstart e em outras entradas em / etc / init.

adicionado em resposta ao comentário

Se você usa o upstart ou init.d, você ainda precisará de alguma maneira de determinar quando o Firebird é inicializado corretamente. Infelizmente, o próprio Firebird não parece ter uma boa maneira de verificar se o está instalado e executando . Portanto, a recomendação para colocar o seu programa em /etc/rc.local é certamente a mais fácil, e no Ubuntu - pelo menos - é garantido que funcionará o mais tarde possível no processo de inicialização.

    
por msw 25.12.2010 / 10:45
12

se você não quiser migrar para o UPSTART, mas quiser a abordagem clássica, deverá:

NOTA: Estou salvando o serviço e o programa com o mesmo nome em diretórios diferentes (mas você pode alterá-lo, desde que seja refletido em seu arquivo de serviço). altere "myscriptname" e "myprogramname" para nomes reais!

  1. salve seu programa que será executado como um serviço em / usr / sbin

    sudo cp myprogramname /usr/sbin/myscriptname

  2. crie um script de inicialização básico (use /etc/init.d/skeleton como referência)

  3. mova este script para /etc/init.d

    sudo mv /etc/init.d/myscriptname

  4. dê esta permissão executável de script (eu usei 775, mas você pode configurá-lo mais baixo)

    sudo chmod 755 /etc/init.d/myscriptname

  5. goto /etc/init.d

    cd /etc/init.d

  6. incluir na lista de inicialização com baixa prioridade de inicialização

    sudo update-rc.d myscriptname defaults 97 03

reinicie sua máquina e verifique se o serviço foi iniciado corretamente

sudo ps -A --sort cmd

se o seu serviço não está sendo iniciado corretamente, você deve primeiro verificar se ele é executado quando solicitado manualmente:

cd /etc/init.d
sudo service myscriptname start

abaixo eu incluo um arquivo de serviço de amostra que realmente funciona. compare-o ao serviço esqueleto para entender o que você precisa configurar. NOTA: isso funciona no Ubuntu 12.04 amazon cloud AWS EC2 classic LAMP (também no 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 "" 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

:
    
por tony gil 15.09.2012 / 19:13
7

Faça uma cópia de /etc/init.d/skeleton e edite-a nos locais apropriados para iniciar / parar / reiniciar seu serviço. É muito bem comentado, então você deve ser capaz de criar um script init.d de trabalho em pouco tempo.

    
por phuihock 18.04.2011 / 05:09
2
  • Adicione seus comandos a /etc/rc.local
  • Para que seu daemon seja iniciado automaticamente na inicialização do sistema.
por karthick87 25.12.2010 / 11:39
1

pleaserun é um Ruby script que tenta resolver o problema de criar automaticamente um script de inicialização com um único comando. citando a página:

"Com o pleaserun, você pode gerar os seguintes lançadores / scripts / o que quer que seja:

launchd
upstart
systemd
runit
sysv init "

Ele também detecta qual sistema init está em uso, portanto, gera o script de acordo.

    
por Costin Gușă 17.09.2014 / 00:31