标签 sendmail 下的文章

最近准备重新回归运维,很好。前一阵子易先生打电话说服务器上 session 失效,他在公司又不方便 ssh 上去看。于是我为了自己的博客勉为其难上去看了一下,结果发现 /var 下面居然爆满溢出了。

www# df -h
Filesystem     Size    Used   Avail Capacity  Mounted on
/dev/ad0s1a    989M     59M    851M     7%    /
devfs          1.0K    1.0K      0B   100%    /dev
/dev/ad0s1d    989M    2.2M    908M     0%    /tmp
/dev/ad0s1e     19G    1.6G     16G     9%    /usr
/dev/ad0s1f    989M    910M   -384K   100%    /var
/dev/ad0s1g    124G    1.7G    113G     2%    /www
/dev/ad2s1d    9.7G    1.4G    7.5G    16%    /database
/dev/ad2s1e    139G     42G     85G    33%    /backup
在啧啧称赞之外,准备找出在 /var 下面所有大于 1MB 的文件:

www# find /var -xdev -size +2048 -ls| sort -r +6 这个搜索结果是相当的恐怖,可以用眼花缭乱来形容当时的屏幕滚动。强行中止后发现绝大部分文件都集中在 /var/spool/clientmqueue 这个目录下面。那么这到底是个什么目录呢?

原来,当使用 sendmail 发邮件,或者系统默认要发邮件(譬如 crontab)的时候,首先会把邮件复制到这个目录里,然后等待 MTA 处理。MTA 做的事情就是把这个目录中的邮件转移到 /var/spool/mqueue,然后再发往目的地。

在 /var/spool/clientmqueue 下产生大量文件的情况,通常是因为没有合适的 MTA 来发送邮件,于是都堆积在这里了。假如这里的邮件并不是你需要的,比如由 crontab 产生的信,你可以简单地删除。

还有一种情况,当这个目录下面的文件数量足够多的时候,直接 rm -f * 的话会被提示 Argument list too long。没事,下面两个命令会帮助你搞定问题:

find /var/spool/clientmqueue/ -type f –delete 或者

find /var/spool/clientmqueue/ -type f -exec rm {} \+ 不过这两条命令要求 find 的版本较新,如果你的文件版本较低,可尝试:

find /var/spool/clientmqueue/ -type f -exec rm {} \; 到这里,我们已经搞明白 /var 爆满的原因。可以判断的是,易先生服务器的问题就在于系统中有用户启用了 crontab,且 crontab 中执行的程序有输出内容。这些内容会以邮件形式发给 crontab 的用户,而 sendmail 又没有启动,所以就大量产生了这些队列文件。

解决的办法很简单,在 crontab 中命令的最后加上:

>/dev/null 2>&1 这样输出的内容会被直接抛弃,问题就得以解决了。

最后也顺便提一下禁用 sendmail 的事情。本地 MTA 正确工作是 Unix 系统正确工作的一个必要条件。盲目禁止 sendmail 意味着对安全的不关注。如果你不打算启动任何邮件服务,就不应该使用 sendmail_enable="NONE",而应使用 sendmail_enable="NO"。

当然,你也可以考虑用下面的办法来彻底消除其影响,但我认为没什么必要。在 /etc/make.conf 中加入:

NO_SENDMAIL=yes
INSTALL=install
然后 make buildworld installworld,然后用 find 删除 lib、libexec、usr/bin、usr/sbin 等目录中没有被碰过的文件,最后删除 /etc/mail、/etc/rc.d/sendmail 等文件。这个方法来源于网络,没有亲自实验,请谨慎操作。