From 18ce8e5e07f49baaa4cc75fc8c818ffb24d766f2 Mon Sep 17 00:00:00 2001 From: Gilles Chehade Date: Fri, 19 Dec 2008 00:39:06 +0000 Subject: - smtpd handled mbox locking failures as "regular" temporary failures which is not good at all. As a result, under heavy load messages would be kept in queue, and delayed for hours just because we failed locking a few times. This commit makes smtpd distinguish between lock fails and "regular" temporary fails. - delivery scheduler will reschedule immediately a message that couldn't be delivered because of a lock fail. If we fail to lock too many times we fallback to previous "delay increase" logic. "looks sane" jacekm@ --- usr.sbin/smtpd/smtpd.c | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) (limited to 'usr.sbin/smtpd/smtpd.c') diff --git a/usr.sbin/smtpd/smtpd.c b/usr.sbin/smtpd/smtpd.c index 4d9643d57a6..870779b339e 100644 --- a/usr.sbin/smtpd/smtpd.c +++ b/usr.sbin/smtpd/smtpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.c,v 1.15 2008/12/17 18:47:37 jacekm Exp $ */ +/* $OpenBSD: smtpd.c,v 1.16 2008/12/19 00:39:05 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade @@ -801,25 +801,29 @@ parent_open_mailbox(struct batch *batchp, struct path *path) case EMFILE: case ENFILE: case ENOSPC: - case EWOULDBLOCK: batchp->message.status |= S_MESSAGE_TEMPFAILURE; break; + case EWOULDBLOCK: + goto lockfail; default: batchp->message.status |= S_MESSAGE_PERMFAILURE; } - return -1; } - if (flock(fd, LOCK_EX|LOCK_NB) == -1) { - close(fd); - batchp->message.status |= S_MESSAGE_TEMPFAILURE; - return -1; - } + if (flock(fd, LOCK_EX|LOCK_NB) == -1) + goto lockfail; fchown(fd, pw->pw_uid, 0); return fd; + +lockfail: + if (fd != -1) + close(fd); + + batchp->message.status |= S_MESSAGE_TEMPFAILURE|S_MESSAGE_LOCKFAILURE; + return -1; } @@ -1008,22 +1012,27 @@ parent_open_filename(struct batch *batchp, struct path *path) case EMFILE: case ENFILE: case ENOSPC: - case EWOULDBLOCK: batchp->message.status |= S_MESSAGE_TEMPFAILURE; break; + case EWOULDBLOCK: + goto lockfail; default: batchp->message.status |= S_MESSAGE_PERMFAILURE; } return -1; } - if (flock(fd, LOCK_EX|LOCK_NB) == -1) { - close(fd); - batchp->message.status |= S_MESSAGE_TEMPFAILURE; - return -1; - } + if (flock(fd, LOCK_EX|LOCK_NB) == -1) + goto lockfail; return fd; + +lockfail: + if (fd != -1) + close(fd); + + batchp->message.status |= S_MESSAGE_TEMPFAILURE|S_MESSAGE_LOCKFAILURE; + return -1; } int -- cgit v1.2.3