6.7 Tune the Kernel

Device I/O under Unix is handled by the kernel. The default device settings for most kernels provide somewhat equal performance for a wide range of possible applications. But no kernel, supplied off the shelf, is tuned for best TCP/IP and email performance.

In this section we outline considerations for tuning your kernel. Unfortunately, we cannot give specific tuning instructions because tuning is as widely varied as the varieties and versions of Unix itself. Some versions of Unix, for example, are tuned by running special programs, others are tuned by editing boot-time files, and yet others are tuned by editing source files and compiling a new kernel.

In general, the tuning items of highest concern for best email performance are:

  • Maximize file descriptor limits.

  • Disable source-routed packets.

  • Maximize the number of simultaneous possible TCP/IP connections.

  • Maximize TCP/IP buffer sizes.

  • Decrease TCP/IP keepalive intervals.

Other items of concern are, for example, disk I/O, the number of inodes supported on a disk, the bandwidth of your Internet connection, and the throughput guaranteed by your ISP. As we said at the beginning of this chapter, the topic of performance tuning in sendmail is so complex that it deserves a book of its own.

In the discussions that follow, first change kernel settings by hand to make sure nothing breaks. Only when proven, add those settings to boot-time scripts and document what you did.

6.7.1 Maximize File Descriptor Limits

A file descriptor is the item that associates an open file or device to your program's input and output. Each open file or device consumes one descriptor. A program such as sendmail can consume many file descriptors because it uses so many possible files and devices. If sendmail runs out of file descriptors, it can pause and retry the file-open a brief while later. Too low a file descriptor limit can significantly slow sendmail's performance.

The default number of file descriptors available varies, based on the variation of Unix you are running. SunOS, for example, defaults to 64 file descriptors. FreeBSD, on the other hand, defaults to 1064.

In general, a limit of 4096 is desirable on a busy mail-handling machine. On Solaris, for example, one way to increase the default limit might be to add a line such as this to the /etc/system file, and reboot:

set rlim_fd_max=4096

For BSD-derived versions of Unix you will need to edit the proper kernel configuration file, change the appropriate setting, and build a new kernel. See your system documentation and contact your vendor for help.

6.7.2 Disable Source-Routed Packets

Normally, TCP/IP packets (blocks of information and data) are sent from one endpoint to another in a single hop.[15] The information that tells the kernel that a packet is a single-hop packet is encoded in the information part of the packet. It is legal for that packet to contain instructions to take it through multiple hops. A packet can be sent that carries the instructions, for example, to go first from hostA to hostB, and then from hostB to hostC. Such packets are called source-routed packets.

[15] This is a simplification for the purpose of discussion. A single such hop might traverse many routers and hubs along the way. The important distinction is that a packet goes from one host to another in a single conceptual hop.

Source-routed packets allow anyone outside your site to funnel packets through your site to another site, without your permission. Aside from the security and trust issues, any unauthorized traffic consumes kernel bandwidth that sendmail is then denied the use of. For many good reasons, it is desirable to disable source-routed packets on all of your Internet-connected hosts.

On Solaris you disable source routes with the ndd(1) program. Simply execute the following command as root:

# ndd -set /dev/ip ip_forward_src_routed 0

For FreeBSD, you run the following command as root:[16]

[16] This is an example only. The default value for FreeBSD is zero.

# /sbin/sysctl -w net.inet.ip.sourceroute=0

See your system documentation for help disabling source-routed packets. If documentation is lacking, contact your vendor.

6.7.3 Maximize TCP/IP Connections

The sendmail program tries to keep connections to remote hosts open on the assumption that more mail will soon be sent that is destined for that host. This behavior is desirable when sending a great deal of email, but requires many simultaneous TCP/IP connections.

The number of simultaneous TCP/IP connections that your kernel can support is determined by a complex combination of factors. Connections are serviced by a buffer, so the limit is often set by the size of that buffer. The buffer might be hashed for speed, and so you might want to increase the size of the hash. With some kernels the maximum number of TCP/IP connections is a scaled factor of the maximum number of users, so increasing that value will increase the number of connections.

To illustrate, consider a Solaris machine that uses a hashed buffer. To increase the size of that buffer, edit the /etc/system file, add the following line, and reboot:

set tcp:tcp_conn_hash_size=16384

Here, 16K is sufficient to allow more than enough connections for sendmail.

For other systems, see your system documentation for help in increasing the number of simultaneous TCP/IP connections. If documentation is lacking, contact your vendor.

6.7.4 Maximize TCP/IP Buffer Sizes

When TCP/IP packets arrive destined for sendmail they are buffered by the kernel until sendmail requests them. Inbound packets can sometimes arrive faster than sendmail can ask for and process them. When this happens, the buffer fills to capacity, and no more packets can be accepted. The sending side hangs until the buffer can start to drain.

To even the inbound flow and prevent the buffer from filling, you should maximize the size of that buffer. On FreeBSD, for example, you can increase the size of the buffer like this:

# /sbin/sysctl kern.ipc.maxsockbuf
kern.ipc.maxsockbuf: 262144
# /sbin/sysctl -w kern.ipc.maxsockbuf=524288
kern.ipc.maxsockbuf: 262144 -> 524288

Here, root first ran the sysctl(1) program to find out how big the buffer was. The sysctl(1) program was run a second time to double the size of the buffer.

For other systems, see your system documentation for help in increasing the size of the TCP/IP buffer. If documentation is lacking, contact your vendor.

6.7.5 Decrease TCP/IP Keepalive Intervals

There are a few kernel-based TCP/IP timeouts that are of interest in tuning sendmail's performance. When decreasing these, cut each in half, at most. Reducing timeouts too much will lead to other network problems.

After a connection is established, it might go idle for a while. Generally, such idle connections are kept alive for a predetermined interval. During that keepalive interval the status of the connection is checked to see if it is still idle. Under FreeBSD the defaults for these two values can be found with the sysctl(1) program:

% /sbin/sysctl net.inet.tcp.keepidle
% /sbin/sysctl net.inet.tcp.keepintvl

These two values can be reasonably halved with the following sysctl(1) command-line arguments:

# /sbin/sysctl -w net.inet.tcp.keepidle=3600000
net.inet.tcp.keepidle: 7200000 -> 3600000
# /sbin/sysctl -w net.inet.tcp.keepintvl=75000
net.inet.tcp.keepintvl: 75000 -> 37500

See your system documentation for help in reducing the keepalive time for idle connections. If documentation is lacking, contact your vendor.

    Part I: Build and Install
    Part II: Administration
    Part III: The Configuration File