29

I've got a 3-rd party proprietary application server daemon which can be started and stopped by couple of command lines. I need this daemon to start when the system starts up and correctly stopped on system shutting down. How do I correctly implement this? Is it enough to copy some script inside /etc/init.d and modify it accordingly?

0

6 Answers 6

19

init.d is the old, deprecated system for starting daemons; is has been supplanted by upstart. Upstart has the advantage of being far easier to configure and allows proper sequencing of task initialization.

The configuration files for upstart live in /etc/init and if your daemon has no pre-requisites it can be as simple as 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 which case you can copy that file and modify to taste. More complex configurations are best documented at the upstart site and in other entries in /etc/init.

added in response to comment

Whether you use upstart or init.d, you'll still need some way of determining when Firebird is properly initialized. Unfortunately, Firebird itself doesn't seem to have a good way of verifying that it is installed and running. Therefore, the recommendation to stick your program start into /etc/rc.local is certainly the easiest, and on Ubuntu - at least - is guaranteed to run about as late as possible in the boot process.

1
  • 1
    Actually my daemon depends on Firebird database server, which uses init.d.
    – Ivan
    Dec 25, 2010 at 9:59
12

if you do not want to migrate to UPSTART, but want the classic approach, you must:

NOTE: i am saving the service and the program with the same name in different directories (but you can change this, as long as it is reflected in your service file). change "myscriptname" and "myprogramname" to real names!

  1. save your program that will run as a service in /usr/sbin

    sudo cp myprogramname /usr/sbin/myscriptname

  2. create a basic startup script (use /etc/init.d/skeleton as reference)

  3. move this script to /etc/init.d

    sudo mv /etc/init.d/myscriptname

  4. give this script executable permission (i used 775, but you can set it lower)

    sudo chmod 755 /etc/init.d/myscriptname

  5. goto /etc/init.d

    cd /etc/init.d

  6. include in startup list with low startup priority

    sudo update-rc.d myscriptname defaults 97 03

reboot your machine and check if the service has started properly

sudo ps -A --sort cmd

if your service is not starting properly, you should first check if it runs when called by hand:

cd /etc/init.d
sudo service myscriptname start

below i include a sample service file that actually works. compare it to skeleton service so as to understand what you need to configure. NOTE: this works on Ubuntu 12.04 amazon cloud AWS EC2 classic LAMP implementation (also on 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

:
4
  • 1
    @jakeGould you actually took the time to reformat "my" code. does that mean that you tested it and it worked for you?
    – tony gil
    Aug 2, 2014 at 12:42
  • 1
    it worked for me
    – Mario S
    Mar 14, 2016 at 7:31
  • 1
    Isn't upstart dead now in favor of systemd?
    – Gillespie
    Jan 31, 2018 at 20:07
  • Indeed, upstart isn't even installed on my recent Ubuntu. SysV init scripts will never die. Aug 29, 2019 at 21:37
8

Make a copy of /etc/init.d/skeleton and edit it at appropriate places to start/stop/restart your service. It is very well commented so you should be able to create a working init.d script in no time.

1
  • It means you need also to create symbolic links in rcX.d. However a Ubuntu update will wipe out all your custom symbolic links.
    – Robin Hsu
    Sep 20, 2016 at 1:02
2
  • Add your commands to /etc/rc.local
  • So that your daemon will get start automatically on system startup.
2

2020 April

Some good answers here. For up-to-date instruction:

  1. init.d services were replaced by upstart (which uses /etc/init instead of /etc/init.d)
  2. upstart had a very brief existence and was replaced with systemd

Making a systemd service

Supposing you decide to name your service myservice, create a file /etc/systemd/system/myservice.service:

[Unit]
Description=A service that I made

[Service]
Type=simple
ExecStart=/bin/bash /home/myuser/myservice.sh

[Install]
WantedBy=multi-user.target

3 useful commands:

  1. sudo systemctl enable myservice makes the service alwasy begin on system startup
  2. sudo systemctl start myservice manually starts the service
  3. sudo systemctl stop myservice manually stops the service

For additional config options and legal values that you can put into your service file, see https://www.freedesktop.org/software/systemd/man/systemd.service.html#Options

1

pleaserun is a ruby script that attempts to solve the issue of automatically creating an init script with a single command. quoting from it's page:

"With pleaserun, you can generate the following launchers/scripts/whatever:

launchd
upstart
systemd
runit
sysv init"

It also detects which init system is in use so it generates the script accordingly.

1

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .