Over time, messages may gather in the queue awaiting delivery. They remain there until sendmail performs a queue run to process the queue. The sendmail program can be told either to process the queue periodically (when run as a daemon) or to process the queue once, then exit. Each time sendmail processes the queue, it also performs a series of operations that are intended to improve the efficiency with which it delivers messages.
First the queue directory is opened for reading. If that directory cannot be opened, sendmail syslog(3)'s the following message at LOG_CRIT and exits:
orderq: cannot open "/var/spool/mailq" as "."
This error is usually the result of a user running sendmail
in an unsafe manner, with a -C
command-line argument, for example.
It can also result from sendmail attempting to open an
NFS-mounted queue directory, where root is mapped to nobody.
Next, the qf
files are read to gather their priorities
and times (the P
and T
lines). If a qf
file
cannot be opened, it is quietly ignored unless
the -d41.2
debugging command-line switch (see Section 37.5.145, -d41.2)
is specified.
That switch causes sendmail to print the following error message:
orderq: cannot open qfMAA12345 (reason)
Prior to V8.7 sendmail, there was a hard limit on the number of messages that could be processed at any time. If more than QUEUESIZE (defined in conf.h, typically 1000) messages were in queue, only the first QUEUESIZE (1000) of them would be processed! Ordinarily, this was not a problem. But it could quickly become one if your queue were clogged with a huge number of undeliverable messages (where the first 1000 continued to be deferred). In that case the only solution is to temporarily move the 1000 messages out of the way by hand (see Section 23.7.1, "Handling a Down Site") and clear the queue. The only way to detect this situation is to print the queue (see Section 23.4).
V8.7 and above sendmail dynamically allocates memory to process the queue. If more than QUEUESIZE messages are found, sendmail will print the following notice and process them:
grew WorkQ for queue_directory to bytes
As an alternative to this dynamic behavior, V8.7 and above sendmail
offers a hard limit that is somewhat like the old version but
is site tunable with the MaxQueueRunSize
option (see Section 34.8.38).
After all the qf
files have been gathered, they are sorted
in order of cost.
Messages with the lowest value of the P
line have the highest
priority (lowest cost) and are processed first.
Beginning with V8.7, sendmail also offers the QueueSortOrder
option
(see Section 34.8.51, QueueSortOrder), which allows you
to sort by priority (as before), by priority and host-name, or by date queued.
Once all the messages have been sorted, sendmail processes each
in turn.
A single queued message has a single sender but may have many recipients. When processing a queued message, sendmail attempts to deliver it to all recipients before processing the next queued message.
The first step in processing a queued message is to lock it so that
concurrent runs of sendmail do not attempt to process it simultaneously
(see Section 23.2.3.1, "Current style file locking").
Then the qf
file is opened and read. The sender and all the
recipients are gathered from the corresponding S
and R
lines.
For each recipient, delivery is attempted. If delivery is successful, that recipient's address is removed from the sendmail program's internal list of recipient addresses. If delivery fails, that address is either left in the list or bounced, depending on the nature of the error.
After all recipients have been either delivered, bounced, or left in
the list, sendmail reexamines that list. If there are no recipients
left in it, the message is de-queued (all of the files in the queue
directory that compose it are removed). If any recipients are
left, the M
line is assigned the error message of the last
failed message, and the qf
file is rewritten with the list
of remaining recipients. Finally, the qf
file is closed,
thus freeing its lock.
Under V8 sendmail the CheckpointInterval
(C
) option
(see Section 34.8.7, CheckpointInterval (C)) causes checkpointing of this process.
When this option has a positive value, the qf
file is
rewritten after that value's number of recipients have been processed.
For example, consider a mail message to five recipients. If the
CheckpointInterval
(C
) option
is set to a value of 2, the qf
file is rewritten after
the first two recipients have been processed, then again after four, and again
after they all have been processed.
This keeps the qf
file reasonably up-to-date as protection
against sendmail being improperly killed or the machine crashing.