Is it possible to execute a script as first at shutdown/reboot on Debian?

5,333

Solution 1

The proper way to do what you want to do is to make a custom init script that lists the necessary dependencies. Within that script, you start/stop the service in question, depending on whether the script is called with start or stop as the first parameter.

You can start with a simple script such as /etc/init.d/motd as a template, as it will have all the basic parts to make it all work at all. In your case, you want the script to state

# Required-Stop: $remote_fs $syslog apache2 mysql

because you need the remote_fs and syslog facilities running (but you don't care what exact service provides those facilities), and specifically the apache2 and mysql services running, at the time the stop action is issued. Note that Java isn't a service per se, but using it may have dependencies on services, including file systems.

Should-Stop and Required-Stop are described in the insserv(8) man page as:

In both cases the script system should avoid stopping services which are declared by these two Stop tags until the script including these tags is stopped.

The names are from Provides (literal service names, no $ sign at the beginning) of service init scripts, and from /etc/insserv.conf (facility names, $ sign at the beginning).

When you have the script the way you want it, install it using update-rc.d or directly using insserv.

Solution 2

If you want to execute a script only at shutdown, you don't need:

# Required-Start:    $remote_fs $syslog

You can leave this empty.

Each script has Provides entry which defines names of other scripts that you can use in the Required-Start and Required-Stop directives. The order is reversed in the two fields. If something has to start before the script, you have to put it into Required-Start directive. But if the script has to stop before a certain service, the name of that service has to be placed in Required-Stop.

So, in your example you want to run the script before apache and mysql termination at shutdown. All you have to do is to check the Provides directive in appropriate init files.

$ cat /etc/init.d/apache2
...
# Provides:          apache2
...

and:

$ cat /etc/init.d/mysql
...
# Provides:          mysql
...

Now you just add apache2 and mysql to your script under the Required-Stop directive:

# Required-Stop: apache2 mysql

You can read more about the header of an init script here . There's also some info concerning facility names, for example the mentioned $remote_fsand $syslog:

$local_fs -- all local filesystems are mounted. All scripts that write in /var/ need to depend on this, unless they already depend on $remote_fs.

$network -- low level networking (ethernet card; may imply PCMCIA running)

$named -- daemons which may provide hostname resolution (if present) are running. For example, daemons to query DNS, NIS+, or LDAP.

$portmap -- daemons providing SunRPC/ONCRPC portmapping service as defined in RFC 1833 (if present) are running all remote

$remote_fs -- all filesystems are mounted. In some LSB run-time environments, filesystems such as /usr may be remote. If the script need a mounted /usr/, it needs to depend on $remote_fs. Scripts depending on $remote_fs do not need to depend on $local_fs. During shutdown, scripts that need to run before sendsigs kills all processes should depend on $remote_fs.

$syslog -- system logger is operational

$time -- the system time has been set, for example by using a network-based time program such as ntp or rdate, or via the hardware Real Time Clock. Note that just depending on ntp will not result in an accurate time just after ntp started. It usually takes minutes until ntp actually adjusts the time. Also note that standard insserv.conf just lists hwclock as $time.

$all -- facility supported by insserv to start a script after all the other scripts, at the end of the boot sequence. This only work for start ordering, not stop ordering. It is not possible to depend on a script which depend on $all.

After you change a header in an init script, you have to run update-rc.d and it will set the right order of all scripts based on their headers:

# update-rc.d script defaults 
Share:
5,333

Related videos on Youtube

priyanka -
Author by

priyanka -

Updated on September 18, 2022

Comments

  • priyanka -
    priyanka - over 1 year

    I am currently trying to register a script (located in the /etc/init.d) in a way that makes this script being executed as the first script/programm at shutdown/reboot (change to running level 0 or 6).

    I used update-rc.d stop_servers stop 0 0 6 . to register the script for these two runlevels. It is correctly registered there but has the name K01stop_servers. This makes the script not being executed as the first one.
    I basically need everything still running. That's why I want it to be the first.
    Namely I still need my apache, mysql and (s)ftp servers running and my java still fully functional.

    How do I achieve this?

    The script goes as follows:

    #! /bin/bash
    
    ### BEGIN INIT INFO
    # Provides:          mc_server_safe_shutdown
    # Required-Start:    $remote_fs $syslog
    # Required-Stop:     $remote_fs $syslog
    # Default-Start:
    # Default-Stop:      0 6
    # Description:       Shuts down all Minecraft serves softly
    ### END INIT INFO
    
    /root/.stop_servers
    
    exit 0
    
    • Admin
      Admin over 10 years
      Any reason you cannot use the regular services infrastructure to start and stop the Minecraft servers? Then you can list any dependencies they have, and update-rc.d should take care of the interdependencies.
    • Admin
      Admin over 10 years
      I don't know how to do that. And I really don't know the names of these services. That would help me very much.
    • Admin
      Admin over 10 years
      Well, the Required-Start and Required-Stop parts should be easy to take from the relevant service scripts. And you can use any other service script as a template. Have a look at e.g. /etc/init.d/motd for a simple service script that should be available on almost any Debian installation. Also note that the only difference between K and S links is (1) the parameter they get invoked with (stop vs start) and (2) whether they get invoked when entering (S) or leaving (K) the runlevel.
    • Admin
      Admin over 10 years
      You thing this should work # Required-Stop: $remote_fs $syslog $apache2 $mysql?
    • Admin
      Admin over 10 years
      I think you should have a look at man 8 insserv; it should tell you what those comments actually stand for. For a start, $ or no $ before a literal is significant.
    • Admin
      Admin over 10 years
      It worked with # Required-Stop: $remote_fs $syslog apache2 mysql. Thank you.
  • priyanka -
    priyanka - over 10 years
    I like your answer more but I promissed the other guy.