[Mimedefang] Open filedescriptors warning on a busy server

Martin Blapp mb at imp.ch
Thu Apr 14 05:02:16 EDT 2005


Hi David,

> Each slave is single-threaded, so that shouldn't happen.  I honestly
> don't know what it could be.
>
> Is there a way under FreeBSD to see a process's open file descriptors?
> (In Linux, it's under /proc/PID/fd)  Maybe that would give us a clue?

There is lsof - and I was only able to see some fd's open on /dev/null
and the usual stuff.

1 of 100 mimedefang reloads kills the multiplexer here, could this be
related to the open FD's ?

Also a nice error we see is that the bayes yournal of spamassassin does
sometimes belong to 'root' ! instead of the mimedefang user after a reload
which makes bayes updates failing then.

We use now a bit modified startup skript to check and prevent this. And
we also check the validity of mimedefang-filter and spamassassin conf
at the beginning to prevent shooting yourself in your feet :-)

Feel free to add parts of this to the default mimedefang skript.

Martin

#!/bin/sh
#
# Generic start/stop script for MIMEDefang.  Should work on most
# flavors of UNIX.

cd /tmp
PREFIX=%%PREFIX%%

LANG=C
export LANG=C
LC_ALL=C
export LC_ALL

RETVAL=0
prog='mimedefang'
SPOOLDIR='/var/spool/MIMEDefang'
PID="$SPOOLDIR/$prog.pid"
MXPID="$SPOOLDIR/$prog-multiplexor.pid"
_MXPIDNO=`cat $MXPID`;

# Is the program executable?  We search in /usr/bin and /usr/local/bin.

if [ -x /$PREFIX/bin/$prog ] ; then
     PROGDIR=/$PREFIX/bin
elif [ -x /usr/bin/$prog ] ; then
     PROGDIR=/usr/bin
elif [ -x /usr/local/bin/$prog ] ; then
     PROGDIR=/usr/local/bin
else
     exit 0
fi

MX_EMBED_PERL=yes
MX_RECIPIENT_CHECK=yes

SOCKET=%%SOMESOCKET%%
MX_MIN_SLAVE_DELAY=0
MX_USER=mimedefang
SYSLOG_FACILITY=mail
MX_LOG=yes
MX_REQUESTS=100
MX_MINIMUM=20
MX_MAXIMUM=30
MX_IDLE=300
MX_BUSY=600
MX_BACKLOG=200
MX_QUEUE_SIZE=128
MX_QUEUE_TIMEOUT=60
MX_MAX_RSS=100000
MX_MAX_AS=120000
# Source configuration
if [ -f /$PREFIX/etc/mimedefang/$prog.conf ] ; then
     . /$PREFIX/etc/mimedefang/$prog.conf
fi

# Make sure required vars are set
SOCKET=${SOCKET:=$SPOOLDIR/$prog.sock}
MX_SOCKET=${MX_SOCKET:=$SPOOLDIR/$prog-multiplexor.sock}

start_it() {
     if test -r $PID ; then
 	if kill -0 `cat $PID` > /dev/null 2>&1 ; then
 	    echo "mimedefang (`cat $PID`) seems to be running."
 	    return 1
 	fi
     fi
     if test -r $MXPID ; then
 	if kill -0 `cat $MXPID` > /dev/null 2>&1 ; then
 	    echo "mimedefang-multiplexor (`cat $MXPID`) seems to be running."
 	    return 1
 	fi
     fi

     printf "%-60s" "Starting $prog-multiplexor: "
     rm -f $MX_SOCKET > /dev/null 2>&1
     if [ "$MX_EMBED_PERL" = "yes" ] ; then
 	EMBEDFLAG=-E
     else
 	EMBEDFLAG=""
     fi
     $PROGDIR/$prog-multiplexor -p $MXPID \
 	$EMBEDFLAG \
 	`[ -n "$FILTER" ] && echo "-f $FILTER"` \
 	`[ -n "$SYSLOG_FACILITY" ] && echo "-S $SYSLOG_FACILITY"` \
 	`[ -n "$SUBFILTER" ] && echo "-F $SUBFILTER"` \
 	`[ -n "$MX_MINIMUM" ] && echo "-m $MX_MINIMUM"` \
 	`[ -n "$MX_MAXIMUM" ] && echo "-x $MX_MAXIMUM"` \
 	`[ -n "$MX_LOG_SLAVE_STATUS_INTERVAL" ] && echo "-L $MX_LOG_SLAVE_STATUS_INTERVAL"` \
 	`[ -n "$MX_USER" ] && echo "-U $MX_USER"` \
 	`[ -n "$MX_IDLE" ] && echo "-i $MX_IDLE"` \
 	`[ -n "$MX_BACKLOG" ] && echo "-I $MX_BACKLOG"` \
 	`[ -n "$MX_BUSY" ] && echo "-b $MX_BUSY"` \
 	`[ -n "$MX_REQUESTS" ] && echo "-r $MX_REQUESTS"` \
 	`[ -n "$MX_SLAVE_DELAY" ] && echo "-w $MX_SLAVE_DELAY"` \
 	`[ -n "$MX_MIN_SLAVE_DELAY" ] && echo "-W $MX_MIN_SLAVE_DELAY"` \
 	`[ -n "$MX_MAX_RSS" ] && echo "-R $MX_MAX_RSS"` \
 	`[ -n "$MX_MAX_AS" ] && echo "-M $MX_MAX_AS"` \
 	`[ "$MX_LOG" = "yes" ] && echo "-l"` \
 	`[ "$MX_STATS" = "yes" ] && echo "-t /var/log/mimedefang/stats"` \
 	`[ "$MX_STATS" = "yes" -a "$MX_FLUSH_STATS" = "yes" ] && echo "-u"` \
 	`[ "$MX_STATS_SYSLOG" = "yes" ] && echo "-T"` \
 	`[ -n "$MX_QUEUE_SIZE" ] && echo "-q $MX_QUEUE_SIZE"` \
 	`[ -n "$MX_QUEUE_TIMEOUT" ] && echo "-Q $MX_QUEUE_TIMEOUT"` \
 	`[ -n "$MX_NOTIFIER" ] && echo "-O $MX_NOTIFIER"` \
 	-s $MX_SOCKET
     RETVAL=$?
     if [ $RETVAL = 0 ] ; then
 	echo "[  OK  ]"
     else
 	echo "[FAILED]"
 	return 1
     fi

     # Start mimedefang
     printf "%-60s" "Starting $prog: "
     $PROGDIR/$prog -P $PID \
 	-m $MX_SOCKET \
 	`[ -n "$MX_USER" ] && echo "-U $MX_USER"` \
 	`[ -n "$SYSLOG_FACILITY" ] && echo "-S $SYSLOG_FACILITY"` \
 	`[ "$MX_RELAY_CHECK" = "yes" ] && echo "-r"` \
 	`[ "$MX_SENDER_CHECK" = "yes" ] && echo "-s"` \
 	`[ "$MX_RECIPIENT_CHECK" = "yes" ] && echo "-t"` \
 	`[ "$KEEP_FAILED_DIRECTORIES" = "yes" ] && echo "-k"` \
 	`[ "$ALLOW_NEW_CONNECTIONS_TO_QUEUE" = "yes" ] && echo "-q"` \
 	`[ "$MD_EXTRA" != "" ] && echo $MD_EXTRA` \
 	-p $SOCKET
     RETVAL=$?
     if [ $RETVAL = 0 ] ; then
 	echo "[  OK  ]"
     else
 	echo "[FAILED]"
 	kill `cat $MXPID`
 	return 1
     fi
     return 0
}

stop_it() {
     # Stop daemon
     printf "%-60s" "Shutting down $prog: "
     if test -f "$PID" ; then
 	kill `cat $PID`
 	RETVAL=$?
     else
 	RETVAL=1
     fi
     if [ $RETVAL = 0 ] ; then
 	echo "[  OK  ]"
     else
 	echo "[FAILED]"
     fi

     rm -f $PID > /dev/null 2>&1

     # Stop daemon
     printf "%-60s" "Shutting down $prog-multiplexor: "
     if test -f "$MXPID" ; then
 	kill `cat $MXPID`
 	RETVAL=$?
     else
 	RETVAL=1
     fi
     if [ $RETVAL = 0 ] ; then
 	echo "[  OK  ]"
     else
 	echo "[FAILED]"
     fi

     rm -f $MX_SOCKET > /dev/null 2>&1
     rm -f $MXPID > /dev/null 2>&1
}

check_sa() {
     #
     # Check for valid spamassassin config
     #
     SPAMOUTPUT=`/$PREFIX/bin/spamassassin --lint 2>&1`;
     SRETVAL=$?
     if [ $SRETVAL -ne 0 ]; then
 	echo "SpamAssassin Config is incorrect, please run spamassassin --lint and fix the error.";
 	RETVAL=1;
 	exit $RETVAL;
     fi;
}

check_md() {
     #
     # Check for a valid mimedefang config
     #
     MDEFOUT=`$PREFIX/bin/mimedefang.pl -test 2>&1`;
     MRETVAL=$?
     if [ $MRETVAL -ne 0 ]; then
 	echo "The File mimedefang-filter has a config error, please run mimedefang.pl -test and fix the error";
 	RETVAL=1;
 	exit $RETVAL;
     fi
}

# See how we were called.
case "$1" in
   start)
   start_it
     ;;

   stop)
   stop_it
     ;;

   restart)
     check_sa
     check_md
     if [ -r $MXPID ] ; then
     	stop_it
     fi
     sleep 1;
     start_it
     RETVAL=$?
     ;;

   reread|reload)
     check_sa
     check_md
     if [ -r $MXPID ] ; then
 	kill -INT `cat $MXPID`
 	RETVAL=$?
 	if [ $RETVAL = 0 ] ; then
 	    echo "Told $prog-multiplexor to force reread of filter rules."
 	else
 	    echo "Could not signal $prog-multiplexor"
 	fi
 	sleep 5;
 	#
 	# Check for mimedefang crashes after reload.
 	#
 	OUTPUT=`ps -auxwww | egrep "^$MX_USER +$_MXPIDNO"`
     	RETVAL=$?
     	if [ $MRETVAL -ne 0 ]; then
 		stop_it
 		start_it
 		RETVAL=$?
 	fi
 	if [ ! -r $MXPID ] ; then
 		stop_it
 		start_it
 		RETVAL=$?
 	fi
 	chown -R $MX_USER /$PREFIX/var/bayes
     else
 	echo "Could not find process-ID of $prog-multiplexor"
 	start_it
 	RETVAL=$?
 	exit $RETVAL
     fi
     ;;

   *)
     echo "Usage: $0 {start|stop|restart|reread|reload}"
     exit 1
esac

exit $RETVAL



More information about the MIMEDefang mailing list