Wie füge ich einen benutzerdefinierten Daemon zu init.d hinzu?

26

Ich habe einen proprietären Application Server-Daemon eines Drittanbieters, der über einige Befehlszeilen gestartet und gestoppt werden kann. Ich brauche diesen Daemon, um zu starten, wenn das System gestartet und beim Herunterfahren des Systems ordnungsgemäß gestoppt wird. Wie setze ich das richtig um? Reicht es aus, ein Skript in /etc/init.d zu kopieren und es entsprechend zu ändern?

Ivan
quelle

Antworten:

16

init.d ist das alte, veraltete System zum Starten von Daemons. Dies wurde durch Emporkömmling ersetzt . Upstart hat den Vorteil, dass es viel einfacher zu konfigurieren ist und eine ordnungsgemäße Abfolge der Task-Initialisierung ermöglicht.

Die Konfigurationsdateien für upstart befinden sich in / etc / init. Wenn Ihr Daemon keine Voraussetzungen hat, kann dies so einfach sein wie 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

In diesem Fall können Sie diese Datei kopieren und nach Belieben ändern. Komplexere Konfigurationen lassen sich am besten auf der Upstart-Site und in anderen Einträgen in / etc / init dokumentieren.

als Antwort auf Kommentar hinzugefügt

Unabhängig davon, ob Sie upstart oder init.d verwenden, müssen Sie noch feststellen, wann Firebird ordnungsgemäß initialisiert wurde. Leider scheint Firebird selbst keine Möglichkeit zu haben, zu überprüfen, ob es installiert ist und ausgeführt wird . Daher ist die Empfehlung, Ihren Programmstart in /etc/rc.local zu speichern, sicherlich die einfachste, und auf Ubuntu wird - zumindest - garantiert so spät wie möglich im Bootprozess ausgeführt.

msw
quelle
1
Eigentlich hängt mein Daemon vom Firebird-Datenbankserver ab, der init.d verwendet.
Ivan
12

Wenn Sie nicht auf UPSTART migrieren möchten, sondern den klassischen Ansatz möchten, müssen Sie:

HINWEIS: Ich speichere den Dienst und das Programm unter demselben Namen in verschiedenen Verzeichnissen (Sie können dies jedoch ändern, sofern dies in Ihrer Dienstdatei enthalten ist). Ändere "myscriptname" und "myprogramname" in echte Namen!

  1. Speichern Sie Ihr Programm, das als Dienst ausgeführt wird, in / usr / sbin

    sudo cp myprogramname /usr/sbin/myscriptname

  2. erstelle ein einfaches Startskript (benutze /etc/init.d/skeleton als Referenz)

  3. Verschieben Sie dieses Skript nach /etc/init.d

    sudo mv /etc/init.d/myscriptname

  4. Gib diesem Skript die ausführbare Berechtigung (ich habe 775 verwendet, aber du kannst es niedriger einstellen)

    sudo chmod 755 /etc/init.d/myscriptname

  5. gehe zu /etc/init.d

    cd /etc/init.d

  6. In Startliste mit niedriger Startpriorität aufnehmen

    sudo update-rc.d myscriptname defaults 97 03

Starten Sie Ihren Computer neu und überprüfen Sie, ob der Dienst ordnungsgemäß gestartet wurde

sudo ps -A --sort cmd

Wenn Ihr Dienst nicht ordnungsgemäß gestartet wird, sollten Sie zunächst prüfen, ob er ausgeführt wird, wenn er von Hand aufgerufen wird:

cd /etc/init.d
sudo service myscriptname start

Unten füge ich eine Beispiel-Service-Datei hinzu, die tatsächlich funktioniert. Vergleichen Sie es mit dem Skeleton-Service, um zu verstehen, was Sie konfigurieren müssen. HINWEIS: Dies funktioniert unter Ubuntu 12.04 Amazon Cloud AWS EC2 Classic LAMP-Implementierung (auch unter 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

:
Tony Gil
quelle
1
@jakeGould Sie haben sich tatsächlich die Zeit genommen, "meinen" Code neu zu formatieren. Bedeutet das, dass Sie es getestet haben und es für Sie funktioniert hat?
Tony Gil
1
es hat bei mir funktioniert
Mario S
Ist Emporkömmling nicht tot zugunsten von Systemd?
Gillespie
In der Tat ist Upstart nicht einmal auf meinem aktuellen Ubuntu installiert. SysV-Init-Skripte werden niemals sterben.
Chris Nadovich
8

Erstellen Sie eine Kopie von /etc/init.d/skeleton und bearbeiten Sie sie an den entsprechenden Stellen, um den Dienst zu starten / stoppen / neu zu starten. Es ist sehr gut kommentiert, so dass Sie in der Lage sein sollten, in kürzester Zeit ein funktionierendes init.d-Skript zu erstellen.

Phuihock
quelle
Dies bedeutet, dass Sie in rcX.d auch symbolische Links erstellen müssen. Ein Ubuntu-Update löscht jedoch alle benutzerdefinierten symbolischen Links.
Robin Hsu
2
  • Fügen Sie Ihre Befehle zu hinzu /etc/rc.local
  • Damit Ihr Daemon beim Systemstart automatisch startet.
karthick87
quelle
1

pleaserunist ein Ruby-Skript, das versucht, das Problem des automatischen Erstellens eines Init-Skripts mit einem einzigen Befehl zu lösen. Zitat von seiner Seite:

"Mit pleaserun können Sie die folgenden Starter / Skripte / was auch immer erzeugen:

launchd
Emporkömmling
systemd
runit
sysv init“

Es erkennt auch, welches Init-System verwendet wird, und generiert das Skript entsprechend.

Costin Gușă
quelle
Ich bin mir nicht sicher, ob pleaserun auch protokolliert, aber dieser andere hat ebenfalls protokolliert: gist.github.com/naholyr/4275302
Costin Gușă