Qmail Architecture

Qmail is a tight, well-designed architecture. The existing documentation does not really talk much about how it all works together; not system administrators know to just install it and sit back. Okay, it never that easy to just sit back! Still, knowing how Qmail works is important to understand what it can and can not do; to know its limitations and strengths.

I certainly take my hat off to Dan Bernstein, the author and architect of Qmail. He has put together a system that is elegant, simple, relying on basic Unix services, and always with an eye on efficiency and security!

Basics

Qmail is divided into two main parts: the delivery mechanism, and the delivery requestors. Everythign revolves around the Qmail Queue which houses all messages. The queue resides on disk on a directory, usually $QMAIL_HOME/queue.

All messages are inserted into the queue, and the delivery process, qmail-send schedules and orchestres them for delivery. Qmail-send is the main server process. It does not actually deliver the messages itself... it has its minions do the dirty work. Instead, it maintains the list of message to deliver and retry failed deliveries. Since Qmail-send keeps the pointers to the queue in memory, the queue can not be shared with other processes or with other machines (via NFS). This can be considered a major drawback for a Qmail system, but it also offers its primary advantage: speed.

The other component is essentially the qmail-queue process, which is used to place messages into the Qmail queue. Qmail-queue adds messages directly into the queue, but is invoked from other programs, such as qmail-inject and qmail-smtpd to do the grunt work. Messages arriving in the system are usually handled my qmail-smtpd which inserts them into the queue (or my qmail-qmqpd which does the same thing, only using the QMQP protocol. Mail-based applications can also call qmail-queue to insert messges into the queue. Qmail even has a wrapper for Sendmail to allow other applications think they are still dealing with sendmail.

The Queue

The Queue hold all the messages in the system in its structures. Each message has 2 delivery parts to it: the local and the remote. Local deliveries occur to users, mailboxes, or addresses on the same server. Remote deliveries occur to addresses on other servers that have to be sent using SMTP. If the host name of the recipient address is found the the control/locals file, then it is scheduled for local delivery, else it is scheduled for remote delivery.

Once a message is inserted into the queue, the named pipe $QMAIL_HOME/queue/lock/trigger is written to to “wake up” qmail-send (if it is sleeping) to process new messages in the “to do” queue.

The Other Players

Qmail-send is the main delivery mechanism, but it relies on a few other daemon processes to to the actual mail delivery and clean-up. When Qmail-start initiates qmail, it spawns all these processes and creates the pipes that allow them to communicate.

Qmail-LSpawn listens at its pipe for local delivery commands from qmail-send. It looks up the receiver and spawns a Qmail-Local instance to perform the actual delivery. It then reports back the qmail-send (via the pipe) the status if the delivery, which qmail-send updates in the queue and possibly schedules a retry later on.

Qmail-RSpawn does pretty much the same thing as qmail-lspawn. It receives remote message delivery commands from its pipe from qmail-send. It then spawns a

Qmail-Remote process to perform the actual delivery. As with lspawn, it returns the status to qmail-send which then updates the queue.

Qmail-Clean has the job of removing old messages from the queue. Once messages are “done” processing, qmail-send sends a clean-up command via the pipe to qmail-clean, which then removes the message components from the queue. Non-Mail components Qmail also relies on a few non-mail components to due its job. As it turns out, these too were designed my Bernstein to create a more efficient and secure system. Some people may wonder it he won’t stop until he has re-configured the entire operating system!

Tcpserver is a replacement for INETD and is a daemon that listens for incoming TCP connections, opens then and spawns a program (like qmail-smtpd or qmail-qmqpd) to read from the connection and handle the request.

Splogger is his replacement for syslog. It handles the process and integrity of logging much easier.

Supervise is the process that monitors, brings up and brings down the qmail (or other) server

 
qmail/architecture.txt · Last modified: 2005/07/17 14:43 by allen