Samuel Benzaquen wrote:

Hello all,

We've installed clamav / clamav-milter on a sendmail server with HIGH
trafic. It worked well most of the time, but on peak hours (more than 400
concurrent connections per server and 150K mail per hour) the clamav-milter
thorws these errors on the syslog and slows down the process:

May 7 09:27:41 rs25s8 clamav-milter[6926]: ClamAv: thread_create() failed:
11, try again


This is a libmilter error. Specificaly it occurs in listener.c when libmilter tries to spawn a thread to call the apropriate functions from your milter.

The CPU never went over 70% (1 Xeon with HT).
The RAM never went over 80% (1 Gb total + 1,5 Gb SWAP)
It just can create the thread!

This is always when it tries to create the 257th concurrent thread of
clamav-milter. When this happens you can see thru 'ps' near 256 threads of
clamav-milter (between 250 and 256, never more).
I'm guessing it is a limit on the kernel/libraries/implementation.


Thaty would be my guess. Why dont you try testing with a null-milter and see if you get the same results?

The system is a RedHat 7.3, kernel 2.4.20-19.7smp compiled by RedHat,
glibc-2.2.5-43.
We also tried on a Fedora Core 1, kernel 2.6.4 (downloaded and compiled),
glibc-2.3.2-101.1.

Any help would be appreciated,




/*
                                A Sample Filter

   The  following  sample logs each message to a separate temporary file,
   adds  a  recipient  given  with  the -a flag, and rejects a disallowed
   recipient  address given with the -r flag. It recognizes the following
   options:

     -p port The port through which the MTA will connect to the filter.
     -t sec  The timeout value.
     -r addr A recipient to reject.
     -a addr A recipient to add.
     _________________________________________________________________
*/

#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
#include <syslog.h>

#include "libmilter/mfapi.h"

#ifndef bool
# define bool   int
# define TRUE   1
# define FALSE  0
#endif /* ! bool */


struct mlfiPriv
{
        char    *mlfi_fname;
        char    *mlfi_connectfrom;
        char    *mlfi_helofrom;
        FILE    *mlfi_fp;
};

#define MLFIPRIV        ((struct mlfiPriv *) smfi_getpriv(ctx))

extern sfsistat         mlfi_cleanup(SMFICTX *, bool);

/* recipients to add and reject (set with -a and -r options) */
char *add = NULL;
char *reject = NULL;

sfsistat
mlfi_connect(ctx, hostname, hostaddr)
         SMFICTX *ctx;
         char *hostname;
         _SOCK_ADDR *hostaddr;
{

        /* continue processing */
        return SMFIS_CONTINUE;
}

sfsistat
mlfi_helo(ctx, helohost)
         SMFICTX *ctx;
         char *helohost;
{
        return SMFIS_CONTINUE;
}

sfsistat
mlfi_envfrom(ctx, argv)
         SMFICTX *ctx;
         char **argv;
{
        /* continue processing */
        return SMFIS_CONTINUE;
}

sfsistat
mlfi_envrcpt(ctx, argv)
         SMFICTX *ctx;
         char **argv;
{
        /* continue processing */
        return SMFIS_CONTINUE;
}

sfsistat
mlfi_header(ctx, headerf, headerv)
         SMFICTX *ctx;
         char *headerf;
         unsigned char *headerv;
{
        /* continue processing */
        return SMFIS_CONTINUE;
}

sfsistat
mlfi_eoh(ctx)
         SMFICTX *ctx;
{
        /* continue processing */
        return SMFIS_CONTINUE;
}

sfsistat
mlfi_body(ctx, bodyp, bodylen)
         SMFICTX *ctx;
         unsigned char *bodyp;
         size_t bodylen;
{
        /* continue processing */
        return SMFIS_CONTINUE;
}

sfsistat
mlfi_eom(ctx)
         SMFICTX *ctx;
{
        return SMFIS_ACCEPT;
}

sfsistat
mlfi_abort(ctx)
         SMFICTX *ctx;
{
        return SMFIS_CONTINUE;
}

sfsistat
mlfi_close(ctx)
         SMFICTX *ctx;
{
        return SMFIS_CONTINUE;
}

struct smfiDesc smfilter =
{
        "Null-Milter", /* filter name */
        SMFI_VERSION,   /* version code -- do not change */
        SMFIF_ADDHDRS,  /* flags */
        mlfi_connect,       /* connection info filter */
        mlfi_helo,  /* SMTP HELO command filter */
        mlfi_envfrom,       /* envelope sender filter */
        mlfi_envrcpt,       /* envelope recipient filter */
        mlfi_header,        /* header filter */
        mlfi_eoh,   /* end of header */
        mlfi_body,  /* body block filter */
        mlfi_eom,   /* end of message */
        mlfi_abort, /* message aborted */
        mlfi_close, /* connection cleanup */
};

static void
usage(prog)
        char *prog;
{
        fprintf(stderr,
                "Usage: %s -p socket-addr [-t timeout]\n",
                prog);
}

int
main(argc, argv)
         int argc;
         char **argv;
{
        bool setconn = FALSE;
        int c;
        const char *args = "p:t:h";
        extern char *optarg;

        /* Process command line options */
        while ((c = getopt(argc, argv, args)) != -1)
        {
                switch (c)
                {
                  case 'p':
                        if (optarg == NULL || *optarg == '\0')
                        {
                                (void) fprintf(stderr, "Illegal conn: %s\n",
                                               optarg);
                                exit(EX_USAGE);
                        }
                        if (smfi_setconn(optarg) == MI_FAILURE)
                        {
                                (void) fprintf(stderr,
                                               "smfi_setconn failed\n");
                                exit(EX_SOFTWARE);
                        }

                        /*
                        **  If we're using a local socket, make sure it
                        **  doesn't already exist.  Don't ever run this
                        **  code as root!!
                        */

                        if (strncasecmp(optarg, "unix:", 5) == 0)
                                unlink(optarg + 5);
                        else if (strncasecmp(optarg, "local:", 6) == 0)
                                unlink(optarg + 6);
                        setconn = TRUE;
                        break;

                  case 't':
                        if (optarg == NULL || *optarg == '\0')
                        {
                                (void) fprintf(stderr, "Illegal timeout: %s\n",
                                               optarg);
                                exit(EX_USAGE);
                        }
                        if (smfi_settimeout(atoi(optarg)) == MI_FAILURE)
                        {
                                (void) fprintf(stderr,
                                               "smfi_settimeout failed\n");
                                exit(EX_SOFTWARE);
                        }
                        break;

                  case 'h':
                  default:
                        usage(argv[0]);
                        exit(EX_USAGE);
                }
        }
        if (!setconn)
        {
                fprintf(stderr, "%s: Missing required -p argument\n", argv[0]);
                usage(argv[0]);
                exit(EX_USAGE);
        }
        if (smfi_register(smfilter) == MI_FAILURE)
        {
                fprintf(stderr, "smfi_register failed\n");
                exit(EX_UNAVAILABLE);
        }
        openlog("null-milter",LOG_PID,LOG_MAIL);
        return smfi_main();
}

/* eof */

/*
     _________________________________________________________________

   Copyright  (c)  2000-2003 Sendmail, Inc. and its suppliers. All rights
   reserved.
   By using this file, you agree to the terms and conditions set forth in
   the LICENSE.

 */

Reply via email to