2.3. The Mail Queues A mail message may be queued for these reasons: + If a mail message is temporarily undeliverable, it is queued and delivery is attempted later. If the message is addressed to multiple recipients, it is queued only for those recipients to whom delivery is not immediately possible. + If the SuperSafe option is set to true, all mail messages are queued while delivery is attempted. + If the DeliveryMode option is set to queue-only or defer, all mail is queued, and no immediate deliv- ery is attempted. + If the load average becomes higher than the value of the QueueLA option and the QueueFactor (q) option divided by the difference in the current load average and the QueueLA option plus one is less than the priority of the message, messages are queued rather than immediately delivered. + One or more addresses are marked as expensive and delivery is postponed until the next queue run or one or more address are marked as held via mailer which uses the hold mailer flag. + The mail message has been marked as quarantined via a mail filter or rulesets. 2.3.1. Queue Groups and Queue Directories There are one or more mail queues. Each mail queue belongs to a queue group. There is always a default queue group that is called ``mqueue'' (which is where messages go by default unless oth- erwise specified). The directory or directories which comprise the default queue group are speci- fied by the QueueDirectory option. There are zero or more additional named queue groups declared using the Q command in the configuration file. By default, a queued message is placed in the queue group associated with the first recipient in the recipient list. A recipient address is mapped to a queue group as follows. First, if there is a ruleset called ``queuegroup'', and if this ruleset maps the address to a queue group name, then that queue group is chosen. That is, the argument for the ruleset is the recipient address and the result should be $# followed by the name of a queue group. Otherwise, if the mailer associated with the address specifies a queue group, then that queue group is chosen. Otherwise, the default queue group is chosen. A message with multiple recipients will be split if different queue groups are chosen by the mapping of recipients to queue groups. When a message is placed in a queue group, and the queue group has more than one queue, a queue is selected randomly. If a message with multiple recipients is placed into a queue group with the 'r' option (max- imum number of recipients per message) set to a positive value N, and if there are more than N recipients in the message, then the message will be split into multiple messages, each of which have at most N recipients. Notice: if multiple queue groups are used, do not move queue files around, e.g., into a different queue directory. This may have weird effects and can cause mail not to be delivered. Queue files and directories should be treated as opaque and should not be manipulated directly. 2.3.2. Queue Runs sendmail has two different ways to process the queue(s). The first one is to start queue runners after certain intervals (``normal'' queue runners), the second one is to keep queue runner processes around (``persistent'' queue runners). How to select either of these types is discussed in the appendix ``COMMAND LINE FLAGS''. Persistent queue runners have the advantage that no new processes need to be spawned at certain intervals; they just sleep for a specified time after they finished a queue run. Another advantage of persistent queue runners is that only one process belonging to a workgroup (a workgroup is a set of queue groups) collects the data for a queue run and then multiple queue runner may go ahead using that data. This can significantly reduce the disk I/O necessary to read the queue files compared to starting multiple queue runners directly. Their disadvantage is that a new queue run is only started after all queue runners belonging to a group finished their tasks. In case one of the queue runners tries delivery to a slow recipient site at the end of a queue run, the next queue run may be substantially delayed. In general this should be smoothed out due to the distribution of those slow jobs, however, for sites with small number of queue entries this might introduce noticable delays. In general, persistent queue runners are only useful for sites with big queues. 2.3.3. Manual Intervention Under normal conditions the mail queue will be processed transparently. However, you may find that manual intervention is sometimes necessary. For example, if a major host is down for a period of time the queue may become clogged. Although sendmail ought to recover gracefully when the host comes up, you may find performance unacceptably bad in the meantime. In that case you want to check the content of the queue and manipulate it as explained in the next two sections. 2.3.4. Printing the queue The contents of the queue(s) can be printed using the mailq command (or by specifying the -bp flag to sendmail): mailq This will produce a listing of the queue id's, the size of the message, the date the message entered the queue, and the sender and recipients. If shared memory support is compiled in, the flag -bP can be used to print the number of entries in the queue(s), provided a process updates the data. However, as explained earlier, the output might be slightly wrong, since access to the shared memory is not locked. For example, ``unknown number of entries'' might be shown. The internal counters are updated after each queue run to the correct value again. 2.3.5. Forcing the queue Sendmail should run the queue automatically at intervals. When using multiple queues, a separate process will by default be created to run each of the queues unless the queue run is initiated by a user with the verbose flag. The algorithm is to read and sort the queue, and then to attempt to process all jobs in order. When it attempts to run the job, sendmail first checks to see if the job is locked. If so, it ignores the job. There is no attempt to insure that only one queue processor exists at any time, since there is no guarantee that a job cannot take forever to pro- cess (however, sendmail does include heuristics to try to abort jobs that are taking absurd amounts of time; technically, this violates RFC 821, but is blessed by RFC 1123). Due to the locking algo- rithm, it is impossible for one job to freeze the entire queue. However, an uncooperative recipient host or a program recipient that never returns can accumulate many processes in your system. Unfortu- nately, there is no completely general way to solve this. In some cases, you may find that a major host going down for a couple of days may create a pro- hibitively large queue. This will result in send- mail spending an inordinate amount of time sorting the queue. This situation can be fixed by moving the queue to a temporary place and creating a new queue. The old queue can be run later when the offending host returns to service. To do this, it is acceptable to move the entire queue directory: cd /var/spool mv mqueue omqueue; mkdir mqueue; chmod 0700 mqueue You should then kill the existing daemon (since it will still be processing in the old queue direc- tory) and create a new daemon. To run the old mail queue, issue the following command: /usr/sbin/sendmail -C /etc/mail/queue.cf -q The -C flag specifies an alternate configuration file queue.cf which should refer to the moved queue directory O QueueDirectory=/var/spool/omqueue and the -q flag says to just run every job in the queue. You can also specify the moved queue direc- tory on the command line /usr/sbin/sendmail -oQ/var/spool/omqueue -q but this requires that you do not have queue groups in the configuration file, because those are not subdirectories of the moved directory. See the section about ``Queue Group Declaration'' for details; you most likely need a different configu- ration file to correctly deal with this problem. However, a proper configuration of queue groups should avoid filling up queue directories, so you shouldn't run into this problem. If you have a tendency toward voyeurism, you can use the -v flag to watch what is going on. When the queue is finally emptied, you can remove the directory: rmdir /var/spool/omqueue 2.3.6. Quarantined Queue Items It is possible to "quarantine" mail messages, otherwise known as envelopes. Envelopes (queue files) are stored but not considered for delivery or display unless the "quarantine" state of the envelope is undone or delivery or display of quar- antined items is requested. Quarantined messages are tagged by using a different name for the queue file, 'hf' instead of 'qf', and by adding the quar- antine reason to the queue file. Delivery or display of quarantined items can be requested using the -qQ flag to sendmail or mailq. Additionally, messages already in the queue can be quarantined or unquarantined using the new -Q flag to sendmail. For example, sendmail -Qreason -q[!][I|R|S][matchstring] Quarantines the normal queue items matching the criteria specified by the -q[!][I|R|S][matchstring] using the reason given on the -Q flag. Likewise, sendmail -qQ -Q[reason] -q[!][I|R|S|Q][matchstring] Change the quarantine reason for the quarantined items matching the criteria specified by the -q[!][I|R|S|Q][matchstring] using the reason given on the -Q flag. If there is no reason, unquarantine the matching items and make them nor- mal queue items. Note that the -qQ flag tells sendmail to operate on quarantined items instead of normal items. ... 3.1. Queue Interval The amount of time between forking a process to run through the queue is defined by the -q flag. If you run with delivery mode set to i or b this can be relatively large, since it will only be relevant when a host that was down comes back up. If you run in q mode it should be relatively short, since it defines the maximum amount of time that a message may sit in the queue. (See also the MinQueueAge option.) RFC 1123 section 5.3.1.1 says that this value should be at least 30 minutes (although that probably doesn't make sense if you use ``queue-only'' mode). Notice: the meaning of the interval time depends on whether normal queue runners or persistent queue runners are used. For the former, it is the time between subsequent starts of a queue run. For the latter, it is the time sendmail waits after a persis- tent queue runner has finished its work to start the next one. Hence for persistent queue runners this interval should be very low, typically no more than two minutes. ... 4.1.1. Queue interval The argument to the -q flag specifies how often a sub-daemon will run the queue. This is typically set to between fifteen minutes and one hour. If not set, or set to zero, the queue will not be run automatically. RFC 1123 section 5.3.1.1 recommends that this be at least 30 minutes. Should you need to terminate the queue jobs cur- rently active then a SIGTERM to the parent of the process (or processes) will cleanly stop the jobs. ... 4.3. Queue Priorities Every message is assigned a priority when it is first instantiated, consisting of the message size (in bytes) offset by the message class (which is deter- mined from the Precedence: header) times the "work class factor" and the number of recipients times the "work recipient factor." The priority is used to order the queue. Higher numbers for the priority mean that the message will be processed later when running the queue. The message size is included so that large mes- sages are penalized relative to small messages. The message class allows users to send "high priority" messages by including a "Precedence:" field in their message; the value of this field is looked up in the P lines of the configuration file. Since the number of recipients affects the amount of load a message presents to the system, this is also included into the priority. The recipient and class factors can be set in the configuration file using the RecipientFactor (y) and ClassFactor (z) options respectively. They default to 30000 (for the recipient factor) and 1800 (for the class factor). The initial priority is: pri=msgsize-(classxClassFactor)+(nrcptxRecipientFactor) (Remember, higher values for this parameter actually mean that the job will be treated with lower prior- ity.) The priority of a job can also be adjusted each time it is processed (that is, each time an attempt is made to deliver it) using the "work time factor," set by the RetryFactor (Z) option. This is added to the priority, so it normally decreases the precedence of the job, on the grounds that jobs that have failed many times will tend to fail again in the future. The RetryFactor option defaults to 90000.