11.2 Parts of a Queued Message
When a message is stored in the queue, it is split into pieces. Each
piece is stored as a separate file in the queue directory. That is,
the header and other information about the message are stored in one
file, while the body (the data) is stored in another. All told, six
different types of files can appear in the queue directory. The type
of each is denoted by the first two letters of the filenames. Each
filename begins with a single letter followed by an
f character. The complete list is shown in Table 11-1.
The complete form for each filename is:
Xfident
The X is one of the leading letters shown in
Table 11-1. The f is the
constant letter f. The
ident is a unique queue identifier
associated with each mail message.
In the following sections we first describe the identifier that is
common to all the queue file parts, then describe each file type in
alphabetical order. The internal details of the qf
file can vary depending on the version of
sendmail, so it is discussed separately at the
end of this chapter.
11.2.1 The Queue Identifier
To ensure that new filenames are not the
same as the names of files that might already be in the queue,
sendmail uses the following pattern for each new
ident:
AApid prior to V8.6
hourAApid beginning with V8.6
YMDhmsSEQpid beginning with V8.10
Here,
pid is the process identification number
of the incarnation of sendmail that is trying to
create the file. Because sendmail often
fork(2)s to create queue entries, that
pid is likely to be unique, resulting in a
unique ident. The AA is
used as a clock to prevent duplicate filenames. For V8.6 through V8.9
sendmail an extra letter prefixes the
AA. Shown as hour, it
is an uppercase letter that corresponds to the hour (in a 24-hour
clock) that the identifier was created. For example, a file created
in hour three of the day will have a D prefixed
(the hour begins at midnight with A).
For V8.10 sendmail, the identifier is
constructed differently. Each character stands for (in this order,
reading left to right): the year (minus 1900) modulo 60, the month,
the day, the hour, the minute, the second, and a sequence within the
second that starts at a random value. Each is used as an offset into
a special array that looks like this:
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx
Thus, the following identifier:
gC9GgvB04136
means the year is 2002 (the g), the month is
December (the C), the day is the 9th (the
9), the time is 16:42:57 (the
Ggv), the sequence is 11 (the
B), and the process ID of the process that created
the file was 04136. The advantage to this algorithm is that no two
identifiers will ever be the same during a given 60-year period.
Although this latest method has stayed the same from V8.10 through
V8.12, there is no guarantee that it will remain the same in future
releases.
Prior to V8.10, if sendmail could not create an
exclusive filename because a file with that identifier already
existed, it clocked the second A of the
AA to a B and tried again. It
continued this process, clocking the righthand letter from
A to Z and the lefthand letter
from A to ~ until it succeeded:
AA start
AB second try
AC third try
... and so on
~W
~X
~Y last try
~Z failure
If it never succeeded, the ident became
one like the following and sendmail failed:
hour~Zpid
But this ident was unlikely to ever appear
because the clocking provided for more than 1600 possibilities.
All the files associated with a given mail message share the same
ident as a part of their filenames. The
individual files associated with a single mail message differ only in
the first letter of their names.
11.2.2 The Data (Message Body) File: df
All mail messages are composed of a header
and a body. When queued, the body is stored in the
df file.
Traditionally, the message body could contain only characters that
had the high (most significant) bit turned off (cleared, set to 0).
But under V8 sendmail, with a version 2 or
higher configuration file (Section 17.5), the high
bit is left as is until delivery (whereupon the
F=7 delivery-agent flag, see F=7, determines whether that bit will be stripped
during delivery).
Because the message body can contain sensitive or personal
information, the df file should be protected from
reading by ordinary users. If the queue directory is world-readable,
the TempFileMode option (TempFileMode) should specify minimum permissions (such as
0600) for queued files. But if the queue directory is protected by
both narrow permissions and a secure machine, the
TempFileMode option can be relaxed for easier
administration.
There is currently no plan to provide for encryption of
df files. If you are concerned about the privacy
of your message, you should use an end-to-end encryption package or
an encrypting filesystem (not discussed in this book).
11.2.3 Queue File Locking
When old versions
of sendmail process a queued message (attempt to
redeliver it) they create an empty lock file. That lock file was
needed to signal other running sendmail
processes that the mail message was busy so that they
shouldn't try to deliver the message too. Current
versions simply flock(2) or
fcntl(2) lock the qf file.
11.2.3.1 Current-style file locking
The method that sendmail uses to initially
create an exclusive lock when first queueing a file is twofold. First
it attempts to creat(2) the file with the
argument:
O_CREAT|O_WRONLY|O_EXCL
If that succeeds, it then attempts to lock the file. If HASFLOCK
(HAS...) is defined when
sendmail is compiled, the file is locked with
flock(2). Otherwise, it is locked with a
fcntl(2) F_SETLK argument.
11.2.3.2 Locks shown when printing the queue
When mailq is run (or
the -bp command-line switch is given to
sendmail), the contents of the queue are listed.
In that listing, an asterisk that appears to the right of an
identifier indicates that a lock exists on the message:
/var/spool/mqueue/df (1 request)
----Q-ID---- --Size-- -----Q-Time----- ------------Sender/Recipient------------
dB91UPA04168* 0 Wed Dec 8 17:30 <gw@wash.dc.gov>
<ben@franklin.edu
note
11.2.3.3 Locks can get stuck
Occasionally, a file will become locked
and remain that way for a long time. One indication of a stuck lock
is a series of syslog messages about a given
identifier:
Apr 12 00:33:38 ourhost sendmail[641]: dB91UPA04168: locked
Apr 12 01:22:14 ourhost sendmail[976]: dB91UPA04168: locked
Apr 12 02:49:23 ourhost sendmail[3251]: dB91XUs04170: locked
Apr 12 02:49:51 ourhost sendmail[5977]: dB91UPA04168: locked
Apr 12 03:53:05 ourhost sendmail[9839]: dB91UPA04168: locked
An occasional lock message, such as dB91XUs04170
in the third line in this example, is normal. But when an identifier
is continually reporting as locked (such as the
dB91UPA04168 lines), an orphaned lock might exist
and should be investigated. Use ps(1) to look
for lines that list queue file identifiers:
root 5338 160 -dB91UPA04168 To wash.dc.gov (sendmail)
This shows that the queued mail message, whose identifier is
dB91UPA04168, is currently being processed. If the
lock on that file is stuck, consider killing the
sendmail that is processing it.
11.2.4 The ID Creation File (Obsolete as of V5.62): nf
Old versions of
sendmail used an nf file when
creating a message identifier to avoid race conditions. But contemporary versions of
sendmail create the queue identifier when first
creating the qf file. The nf
file is obsolete.
11.2.5 The Queue Control File: qf
A queued mail
message is composed of two primary parts. The df
file contains the message body. The qf file
contains the message header.
In addition to the header, the qf file also
contains all the information necessary to:
Deliver the message. It contains the sender's
address and a list of recipient addresses.
Order message processing. It contains a priority that determines the
current message's position in a queue run of many
messages.
Expire the message. It contains the date that the message was
originally queued. That date is used to time out a message.
Explain the message. It contains the reason that the message is in
the queue and possibly the error that caused it to be queued.
The qf file is line-oriented, with one item of
information per line. Each line begins with a single uppercase
character (the code letter), which specifies the contents of the
line. Each code letter is then followed by the information
appropriate to the letter. The code letters and their meanings are
shown in Table 11-6 of Section 11.11.
Here is an example of a version 6 (for V8.12
sendmail) qf file:
V6
T944703473
K0
N0
P1
I7/22/19133
Fwbs
$_you@localhost
${daemon_flags}c u
Syou@your.domain
Ayou@your.domain
rRFC822; george@wash.dc.gov
RPFD:george@wash.dc.gov
H?P?Return-Path: <you>
H??Received: (from you@localhost)
by your.domain (8.12.3/8.12.3) id g38DcXCL026713
for george@wash.dc.gov; Fri, 13 Dec 2002 17:37:53 -0800 (PST)
H?D?Date: Fri, 13 Dec 2002 17:37:53 -0800 (PST)
H?F?From: Your Name <you>
H?x?Full-Name: Your Name
H?M?Message-Id: <200204081338.g38DcXCL026713@your.domain>
This fictional qf file shows the information that
will be used to send a mail message from
you@your.domain (the S line) to
one recipient: george@wash.dc.gov (the
R line). It also shows the various headers that
appear in that message (the H lines). We discuss
the individual lines of the qf file at the end of
this chapter.
11.2.6 The Temporary qf Rewrite Image: tf
When processing a
queued message, it is often necessary for
sendmail to modify the contents of the
qf file. This usually occurs if delivery has
failed or if delivery for only a part of the recipient list
succeeded. In either event, at least the message priority needs to be
incremented.
To prevent damage to the original
qf file, sendmail makes
changes to a temporary copy of that file. The temporary copy has the
same queue identifier as the original, but its name begins with a
t.
After the tf file has been successfully written
and closed, sendmail calls
rename(2) to replace the original with the copy.
If the renaming fails, sendmail
syslog(3)s at LOG_CRIT a message such as the
following:
cannot rename(tfdB91brx04175, qfdB91brx04175), df=dfdB91brx04175
Failure to rename is an unusual but serious problem: a queued message
has been processed, but its qf file contains old
and incorrect information. This failure might, for example, indicate
a hardware error, a corrupted queue directory, or that the system
administrator accidentally removed the queue directory.
11.2.7 The Transcript File: xf
A given mail message can be destined for
many recipients, requiring different delivery agents. During the
process of delivery, error messages (such as "User
unknown" and "Permission
denied") can be printed back to
sendmail by each delivery agent.
While calling the necessary delivery agents,
sendmail saves all the error messages it
receives in a temporary file. The name of that temporary file begins
with the letters xf. After all delivery agents
have been called, sendmail returns any collected
error messages to the sender and deletes the temporary
xf file. If there are no errors, the empty
xf file is silently deleted. A
-d51.104 debugging switch setting can be used to
prevent deletion of the xf file.
See Section 11.3.2 for a way to relocate
xf files to a memory-based filesystem.
|