[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: switching from exim to postfix



On Monday 30 April 2012 12:58:18 Carsten Hey wrote:

Hi,

> The rest of this mail is likely not interesting for most of you since it
> only tries to answer the natural follow up question "Why does it need
> a cronjob then?" and explains why I don't think anymore that a switch to
> incron should be considered.
> 
> 
> Two reasons for running dma -q via cronjob in my own words but stolen
> from README.Debian are:
>  * If the queue is not empty after reboot, dma -q needs to be run at
>    least once to start delivering these mails.  A @reboot cronjob or an
>    init script would also to this job.

This still holds.

>  * Delivery processes might die for various reasons, but the mails still
>    need to be delivered in a timely manner.

Then 'dma -q' will exit with non-zero status, and could be retried 
chronologically (every 5 min.) until it succeeds.

> If dma would be the default MTA, then it should IMHO be as reliable as
> possible and even try to prevent user errors.  If a user would
> unintentionally enables deferred mode (which is useful if you are behind
> a dial-up line) but would not set up dma -q to run periodically, then
> the mails would not be delivered without such a default cronjob.
> A comment that reminds users to adapt the cronjob if needed should be
> added to the config file.  If dma -q is run every 5 minutes be default
> anyway, the option -bq does not make that much sense anymore; this can
> possibly be solved by implementing different ways of processing queued
> mails.  All in all, enabling the cronjob by default, as it is already
> done in Debian, seems to be sane.
> 
> > I think that was Carsten's point about switching to incron, which
> > would then do the right thing for new outgoing mail.
> 
> This is a reasonable and logical assumption, but it is wrong ;)
> 
> Actually the reason to mention incron was that I thought that running
> dma -q if triggered by inotify could be a bit cheaper than running it
> every five minutes.  For a default MTA, the amount of systems that run
> it could make considering even minimal differences in efficiency
> worthwhile.
> 
> The idea was to use incron to restart failed delivery processes, if this
> would be possible at all depends on details of dma and incron/inotify
> I'm not aware off.  An additional reason to the explanation above not to
> use incron is that in rare cases dma might fail for example with ENOMEM
> whilst reading its configuration file before it is able to open any file
> in the spool dir, which would render running it by incron to be not 100%
> bullet proof anyway.

Actually, I still think that your idea of utilizing incron to trigger mail 
queue flushing actions (inotify event-based), makes sense. We just need to 
complete the chronological part (for the failed attempts) of the whole task.

While it is true that incron will not restart a failed dma run (AFAICT looking 
at its current code; the failure will only be registered in the syslog and not 
re-tried), it is also true that this task could be offloaded to a wrapper which 
is to be started by incron when a file creation event happens for the mail 
spool directory. The fact is that 'dma -q' will only exit with zero status if 
it successfully and fully has flushed the mail queue. Having this in mind, I 
think that some idempotent wrapper script around dma -q, which is to be 
started by incron, should take a decent care of the whole job of flushing new 
and failed mail found in spool.

It is of course not at the stage of 'verified design' and probably racy.

#!/bin/sh

SELF=`basename ${0}`
DELAY=300
RUNNING=1

is_running() {
        # check for any dma instances
        pidof dma >/dev/null
        case $? in
                0)
                        echo -n "dma is already running..."
                        RUNNING=1
                        return
                        ;;
        esac

        # check for any instances of $SELF, excluding ourselves
        pidof -o %PPID -x ${SELF} >/dev/null
        case $? in
                0)
                        echo -n "$SELF is already running..."
                        RUNNING=1
                        return
                        ;;
        esac
        RUNNING=0
}

while true; do
        echo -n "Attempting to flush..."
        is_running
        if test $RUNNING = 1; then
                echo "Retrying in $DELAY seconds."
                sleep $DELAY
                continue
        fi
        /usr/sbin/dma -D -q 2>/dev/null
        if test $? = 0; then
                echo "ok."
                break;
        fi
        echo "FAIL. Retrying in $DELAY seconds."
        sleep $DELAY
done


-- 
pub 4096R/0E4BD0AB <people.fccf.net/danchev/key pgp.mit.edu>


Reply to: