[Exim] exim 3.x treatment of failure in transport_filter

Góra strony
Delete this message
Reply to this message
Autor: Chris Lightfoot
Data:  
Dla: exim-users
Temat: [Exim] exim 3.x treatment of failure in transport_filter
If I set the transport_filter for a delivery to some
program which fails, I find that exim delivers a blank
message and drop the input message on the floor. For
instance, with this transport:

  address_pipe:
    driver = pipe
    return_output
    delivery_date_add = true
    envelope_to_add = true
    return_path_add = true
    transport_filter = /usr/bin/does-not-exist


the output of exim -d9 on a test message reads (in part):

    [...]

|  >>>>>> Local deliveries >>>>>>
|  locked /var/spool/exim/db/retry.lockfile
|  opened DB file /var/spool/exim/db/retry: flags=0
|  dbfn_read: key=T:|/usr/bin/procmail -Y .procmailrc-foo@???
|  delivering |/usr/bin/procmail -Y .procmailrc-foo as |/usr/bin/procmail -Y .procmailrc-foo using address_pipe:
|    uid=63601 gid=0 home=/home/chris current=/home/chris


(this is the proper eventual recipient of the message)

|  auxiliary group list: <none>
|  set_process_info: 19125 3.03 delivering 1BZUwY-0004yN-00 to |/usr/bin/procmail -Y .procmailrc-foo using address_pipe
|  direct command:
|    argv[0] = /usr/bin/does/not/exist
|  direct command after expansion:
|    argv[0] = /usr/bin/does/not/exist
|  address_pipe transport entered
|  direct command:
|    argv[0] = /usr/bin/procmail
|    argv[1] = -Y
|    argv[2] = .procmailrc-foo
|  Writing message to pipe
|  writing data block size=50 timeout=3600
|  set_process_info: 19127 3.03 reading output from |/usr/bin/procmail -Y .procmailrc-foo
|  process 19128 running as transport filter
|  process 19129 writing to transport filter
|  copying from the filter
|  Waiting for filter process
|  waiting for writing process
|  writing data block size=638 timeout=3600


(exim writes the data to its child process)

| end of filtering transport writing: yield=0
| errno=32 more_errno=0
| transport error EPIPE ignored


(exim gets EPIPE, because the transport_filter failed and
quit, but ignores it. There's a note in transport/pipe.c
that reads,

/* Handle errors during writing. For timeouts, set the timeout for waiting for
the child process to 1 second. If the process at the far end of the pipe died
without reading all of it, we expect an EPIPE error, which should be ignored.
We used also to ignore WRITEINCOMPLETE but the writing function is now cleverer
at handling OS where the death of a pipe doesn't give EPIPE immediately. See
comments therein. This change made 04-Sep-98. Clean up this code in a year or
so. */

I don't really understand the logic of this. Why should
EPIPE be ignored? In this case it indicates that the
filter has failed!)

| address_pipe transport yielded 0
| address_pipe transport returned OK
| post-process |/usr/bin/procmail -Y .procmailrc-foo
| |/usr/bin/procmail -Y .procmailrc-foo succeeded: adding to nonrecipients list


(exim copies a blank message out of the child process and
delivers it to procmail, which merrily adds a From_ line
and stuffs it onto the end of my mailspool.)

|  chris@???: children all complete
|  chris@???: children all complete
|  LOG: 0 MAIN
|    => |/usr/bin/procmail -Y .procmailrc-foo (chris@???) <chris@???> D=userforward T=address_pipe


(exim concludes that the message has been successfully
delivered and logs this fact.)

| search_tidyup called

    [...]


The same thing seems to happen when the transport filter
is an existing program which fails, or when it takes a
very long time (as can happen with spamc on machines under
heavy load). This behaviour seems, at least,
counterintuitive, and can be a bit of a problem when the
transport_filter command occasionally fails. Any
suggestions?

--
``We apologise for the error in the last edition, in which we stated that
`Mr X is a Defective in the Police Force'. We meant, of course, that 'Mr X
is a Detective in the Police Farce'.'' (correction in small town newspaper)