Apache performs certain actions in response to the KILL, TERM, HUP, and USR1 signals (as arguments to kill). All Apache system administrators should be familiar with the use of these signals to control the Apache web server.

By referring to the signal.h file, we learn the numerical equivalents of these signals:

#define SIGHUP     1    /* hangup, generated when terminal disconnects */
#define SIGKILL    9    /* last resort */
#define SIGTERM   15    /* software termination signal */
#define SIGUSR1   30    /* user defined signal 1 */

The four types of signal are:

KILL signal: forcefully shutdown
The KILL (9) signal should never be used unless absolutely necessary, because it will unconditionally kill Apache, without allowing it to clean up properly. For example, the httpd.pid file will not be deleted, and any existing requests will simply be terminated halfway through. Although failure to delete httpd.pid is harmless, if code was registered to run upon child exit but was not executed because Apache was sent the KILL signal, you may have problems. For example, a database connection may be closed incorrectly, leaving the database in an inconsistent state.

The three other signals have safe and legitimate uses, and the next sections will explain what happens when each of them is sent to an Apache server process.

It should be noted that these signals should be sent only to the parent process, not to any of the child processes. The parent process PID may be found either by using ps auxc | grep apache (where it will usually be the lowest-numbered Apache process) or by executing cat on the httpd.pid file. See Section 5.3.3, later in this chapter, for more information.

TERM signal: stop now
Sending the TERM signal to the parent causes it to attempt to kill off all its children immediately. Any requests in progress are terminated, and no further requests are accepted. This operation may take tens of seconds to complete. To stop a child, the parent sends it an HUP signal. If the child does not die before a predetermined amount of time, the parent sends a second HUP signal. If the child fails to respond to the second HUP, the parent then sends a TERM signal, and if the child still does not die, the parent sends the KILL signal as a last resort. Each failed attempt to kill a child generates an entry in the error_log file.

Before each process is terminated, the Perl cleanup stage happens, in which Perl END blocks and global objects' DESTROY methods are run.

When all child processes have been terminated, all open log files are closed and the parent itself exits.

Unless an explicit signal name is provided, kill sends the TERM signal by default. Therefore:

panic# kill -TERM 1640

and:

panic# kill 1640

will do the same thing.

HUP signal: restart now
Sending the HUP signal to the parent causes it to kill off its children as if the TERM signal had been sent. That is, any requests in progress are terminated, but the parent does not exit. Instead, the parent rereads its configuration files, spawns a new set of child processes, and continues to serve requests. It is almost equivalent to stopping and then restarting the server.

If the configuration files contain errors when restart is signaled, the parent will exit, so it is important to check the configuration files for errors before issuing a restart. We'll cover how to check for errors shortly.

Using this approach to restart mod_perl-enabled Apache may cause the processes' memory consumption to grow after each restart. This happens when Perl code loaded in memory is not completely torn down, leading to a memory leak.

USR1 signal: gracefully restart now
The USR1 signal causes the parent process to advise the children to exit after serving their current requests, or to exit immediately if they are not serving a request. The parent rereads its configuration files and reopens its log files. As each child dies off, the parent replaces it with a child from the new generation (the new children use the new configuration) and the new child processes begin serving new requests immediately.

The only difference between USR1 and HUP is that USR1 allows the children to complete any current requests prior to terminating. There is no interruption in the service, unlike with the HUP signal, where service is interrupted for the few (and sometimes more) seconds it takes for a restart to complete.

By default, if a server is restarted using the USR1 or the HUP signal and mod_perl is not compiled as a DSO, Perl scripts and modules are not reloaded. To reload modules pulled in via PerlRequire, PerlModule, or use, and to flush the Apache::Registry cache, either completely stop the server and then start it again, or use this directive in httpd.conf:

PerlFreshRestart On

(This directive is not always recommended. See Chapter 22 for further details.)