Samuel Benzaquen wrote:
Hello all,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.
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
Thaty would be my guess. Why dont you try testing with a null-milter and see if you get the same results?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.
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. */