Wietse Venema wrote:
Reid Sutherland:
Hi,
Why does Postfix bounce on command execution failure,
The action depends on the command exit status. If you want Postfix
to retry, return the appropriate status.
Not fair, here was our problem:
Final-Recipient: rfc822; r...@vianet.ca
Original-Recipient: rfc822;sxxxx...@vianet.ca
Action: failed
Status: 5.3.0
Diagnostic-Code: x-unix; Can't load
'/usr/lib/perl5/auto/Unix/Syslog/Syslog.so'
for module Unix::Syslog: /usr/lib/perl5/auto/Unix/Syslog/Syslog.so:
failed
to map segment from shared object: Cannot allocate memory at
/usr/lib/perl/5.14/DynaLoader.pm line 184. at
/usr/local/bin/mailhandler
line 6 Compilation failed in require at /usr/local/bin/mailhandler
line 6.
BEGIN failed--compilation aborted at /usr/local/bin/mailhandler line 6.
This is the result of an out-of-memory condition caused by a failing
disk array. The spawn count was set to high so the OOM condition was
triggered. While this was a mistake on our part, out of admin control
execution failures should defer.
We also had to use the following hack to ensure module load failures do
not result in bounces. I see that Unix::Syslog is absent from the this
list or the above bounce may have been prevented.
eval {
require DBI;
require Email::Simple::FromHandle;
require CDB_File;
require IPC::Open3;
};
my ($exit, $fail_temp, $fail_temp_ex, $fail_perm, $fail_quota_ex,
$fail_loop_ex) = (0, 75, '4.3.0', 69, '5.2.2', '5.4.6');
if (!$@) {
import DBI;
import Email::Simple::FromHandle;
import CDB_File;
import IPC::Open3;
} else {
warn "mailhandler: module load failed: $@";
exit ($fail_temp);
}
or on command timeout?
I don't think that it is a good idea to fill up your machine with
programs that keep timing out again and again and again. Postfix
is not only about performance and security, but also about safety
(mail servers should be able to deal with problems and not require
a human babysitter).
Understood, but if this condition is occurring, there must be delay or
failure in another component of the system. This is assuming the system
is in production and normally functioning. It's too harsh to assume the
timing out program is forever guilty of blocking the message. Deferral
seems reasonable because the admin must locate and correct the source of
the delay.
This isn't a situation for a hard failure, please clarify the
reasoning.
From postfix-2.11.7/src/global/pipe_command.c:672
} else if (write_status && write_errno != EPIPE) {
vstring_prepend(why->reason, "Command failed: ",
sizeof("Command failed: ") - 1);
vstring_sprintf_append(why->reason, ": \"%s\"", args.command);
return (PIPE_STAT_BOUNCE);
That is a write error, and the logfile tells you what the problem
is. The write(2) may fail for a bazillion reasons, some bad and
some not so bad. Returning the mail is the safe action to take.
Sorry, this wasn't the correct snippet, but this was also of concern. I
think a local filesystem error would result in a deferral, I can't see
why a command would be any different.
Here is the correct snippet from
postfix-2.11.7/src/global/pipe_command.c:657:
/*
* No "D.S.N text" or <sysexits.h> compatible status. Fake it.
*/
else {
sp = sys_exits_detail(WEXITSTATUS(wait_status));
dsb_unix(why, sp->dsn,
log_len ? log_buf : sp->text,
"Command died with status %d: \"%s\"%s%s",
WEXITSTATUS(wait_status), args.command,
log_len ? ". Command output: " : "", log_buf);
return (PIPE_STAT_BOUNCE);
}
I think a bounce should only occur if the command explicitly returns it.
If the command cannot respond properly for whatever reason, it should
be assumed something is wrong and defer.
Thank you for your time.