The sendmail program recognizes three signals that cause it to perform certain actions. SIGINT causes sendmail to clean up after itself and exit. Beginning with V8.7, SIGHUP causes sendmail to re-execute itself (thus restarting and reading its configuration file anew). Also beginning with V8.7, SIGUSR1 causes sendmail to log its file descriptors and other information.
Whenever sendmail gets a SIGINT signal (as would be the case if the system were being shut down), it tries to exit cleanly.
First it unlocks any queued file it is processing. This has the effect of canceling delivery so that the message will be tried again when the system comes back up. Then sendmail resets its identity to the identity it originally ran under. This causes accounting records to correctly show that the same user sendmail started as has exited. Finally, sendmail exits with EX_OK, no matter what, so that errors will not be produced during shutdown.
As a final note, beginning with V8.7, SIGINT is ignored when
sendmail
is running in rule-testing mode with
-bt
.
Beginning with V8.7, a SIGHUP signal will cause
sendmail
to re-execute itself with its original command line. This works only if it is running in daemon mode (with
-bd
; see
Section 36.7.5, -bd
). For example, consider initially running
sendmail
like this:
#/usr/lib/sendmail -bd -q1h
Then imagine that you changed something in the configuration file and wanted the running daemon to reread that file. You could cause that to happen by killing the currently running daemon with a SIGHUP signal:
#kill -HUP `head -1 /etc/sendmail.pid`
This will cause sendmail to execute the command
/usr/lib/sendmail -bd -q1h
The original daemon exits, and the newly executed daemon replaces it.
Be aware that this works only if you run sendmail using a full pathname. If you use a relative path, an attempt to restart sendmail with SIGHUP will fail, and the following warning will be logged at LOG_ALERT:
could not exec bad command line here : reason
This is a very serious situation because it means that your original daemon has exited and no new daemon ran to replace it.
Beginning with V8.6.5, sendmail responds to a SIGUSR1 signal. This signal causes sendmail to syslog at LOG_DEBUG the several items that define its state. [2] That syslog output begins with a line that looks like this:
[2] This same information is syslog 'd if the daemon looses track of
$j
in$=w
and if$j
becomes or is not fully qualified.
-- dumping state onreason
: $j =val
--
where
reason
can be any one of the following:
siguser1
The information has been logged because
sendmail
received a SIGUSR1 signal. In this instance the daemon logs the information and continues to run.
daemon lost $j
The information has been logged because a running daemon discovered that the value in
$j
(the canonical name of this host; see
Section 31.10.20, $j
) disappeared from the class
$=w
(the list of all names by which the local host is known; see
Section 32.5.8, $=w
). This test is made and this information is logged only if
sendmail
was compiled with XDEBUG defined (see
Section 18.8.57, XDEBUG
). In this instance the daemon logs the information and aborts.
daemon $j lost dot
The information has been logged because a running daemon discovered that the value in
$j
(the canonical name of this host; see
Section 31.10.20
) was no longer canonical (no longer contained a dot inside it). This test is made and this information is logged only if
sendmail
was compiled with XDEBUG defined (see
Section 18.8.57
). In this instance the daemon logs the information and aborts.
Whichever the reason, the information that is logged for each looks pretty much the same; for example,
-- dumping state onwhen
: $j =val
-- CurChildren =num
-- open file descriptors: -- output of dumpfd() here -- connection cache: -- output of mci_dump() here -- ruleset debug_dumpstate returns statret
, pv: -- output of rule set debug_dumpstate here -- end of state dump --
We have described the first line already. If for some reason
$j
is missing from
$=w
, that line will be followed by
*** $j not in $=w ***
The second line simply shows the number of children the daemon has forked and currently has out doing other work in parallel with itself. That line is followed by three sections of information. The first two sections are always output; the third is output only if rule set
debug_dumpstate
exists.
Each open file descriptor is displayed along with its current properties. These lines of output can be numerous. In general form, they look like this:
num
: fl=flags
mode=mode type stats
Here, the
num
is the number of the open file descriptor. The other information in this line is described in detail in our discussion of the
-d2.9
debugging switch (see
Section 37.5.13, -d2.9
).
When sending mail, outgoing connections are maintained for efficiency, and information about those connections is cached. Before connecting to a remote host, for example, sendmail checks its cache to see whether that host is down. If it is, it skips connecting to that host.
This output is highly detailed and very complicated. See the
-d11.1
debugging switch (
Section 37.5.44, -d11.1
) for a full description.
If rule set
debug_dumpstate
[3] is defined in your configuration file, it will be called here, and the above line of output will be printed. The
stat
is the numeric representation of the code returned by
sendmail
's internal
rewrite
() routine. That code will be either EX_OK (0) if there were no parsing errors, EX_CONFIG (78) if there were, or EX_DATAERR (65) if there was a fatal error (such as too much recursion or a replacement was out of bounds). Text describing the error is also logged and will appear in this output.
[3] In V8.7 sendmail this is rule set 89. Beginning with V8.8 sendmail , rule sets 80 through 89 are reserved for use by vendors, such as Sun Microsystems.
Rule set
debug_dumpstate
is called with an empty workspace. After rule set
debug_dumpstate
is done, each token in the resulting new workspace is printed one per line. This gives you a hook into the internals of
sendmail
, enabling you to display information that might otherwise be invisible. For example, consider the desire to display
identd
information, the current sender's address, and the current queue identifier:
Sdebug_dumpstate R$* $@ $&_ $&s $&i
Here, the
$*
in the LHS matches the zero tokens passed to rule set
debug_dumpstate
. The
$@
prefix in the RHS suppresses recursion. Each of the three macros that follows is stated with a
$&
prefix (see
Section 31.5.3, "Use Value as Is with $&"
) that prevents each from being prematurely expanded when the configuration file is first read.
Another example might involve the need to look up the current recipient's host with DNS:
Sdebug_dumpstate R$* $@ $[ $&h $]
The
$[
and
$]
operators (see
Section 28.6.6, "Canonicalize Hostname: $[ and $]"
) cause the hostname appearing between them to be looked up with DNS and replaced with its full canonical name. Again, the macro
h
is prefixed with
$&
to prevent premature expansion.
In general, rule set
debug_dumpstate
should be excluded from your configuration file. When a problem does appear, you can define it, restart the daemon, and then wait for the problem to reoccur. When it does, kill
sendmail
with a SIG_USR1 and examine the
syslog
result.
Do not be tempted to use rule set
debug_dumpstate
for routine logging of specialty information. Forcing rules to be processed with a signal is fraught with danger. The current active rule set can, for example, be clobbered in possibly unrecoverable ways. Use this rule set
debug_dumpstate
technique only to solve specific problems, then erase it when the problem is solved.