Subject: Re: sendmail configuration
To: None <current-users@NetBSD.ORG>
From: Richard Todd <rmtodd@servalan.servalan.com>
List: current-users
Date: 11/03/1995 17:16:00
In servalan.mailinglist.netbsd-current-users you write:
>locks to limit the number of queue runners to some (low) number. The
>trouble with the '-q30m' argument to the daemon process is that if your
>queue gets large, you can have a potentially unlimited number of queue
>runner processes, and that's not good for overall system throughput. As

Indeed.  This is one of the major things (the unlimited queueruns) that
caused me to switch away from sendmail on the systems I run.  Another thing
was the next problem you mention:

>You still have that danger with sendmail -bd (unlimited children), but
>there's no way to fix that without hacking on the sendmail sources. Well,

Yeah.  Fortunately, smail 3 comes with support for monitoring and limiting
the number of simultaneous listener children (or, optionally, having a lower
cutoff beyond which the new listener children do 'queue_only' --- I don't think
this is particularly useful, because I prefer my mailer daemons to always queue
mail for delivery by a later queuerun process.)  Hacking in the other 
functionality on my own, limiting the total number of queueruns, was fairly
straightforward.  In case someone with a fondness for sendmail's source wants
a new programming project, this is how the smail code does it:
	Each time the daemon gets ready to fork a new listener process, check
	an array the daemon keeps of child process ids (of listeners) and see
	if there are any empty slots.  If not, then there are too many 
	incoming mail messages at the moment, so give the new connection a
	nasty message saying 'try again later' and close the connection. 
	Otherwise, go ahead and fork the listener and have the parent 
	make a note of its pid in the array.

	Similarly, the daemon keeps an array of child pids for queuerun 
	processes, and every time that queuerun time comes around again, it
	checks to see if there are any empty slots in the array, and either 
	skips the queuerun (if there are too many running), or forks a 
	queuerun and makes a note of the child's pid.

	Now all you need is a SIGCHLD handler to note when child processes die
	and do the appropriate wait() on them and clear their pids from the 
	appropriate array.  Oh, and some code to interface with the config 
	file code so you've got some way of specifying how many queueruns/
	listeners are allowed. 

>port, and only allowed some N children to be running at a time (sendmail
>-bs), and withdrew the SMTP listener socket when that limit was hit or
>exceeded (resulting in ICMP port unreachables to peers, i.e. "connection
>refused").

Yeah, this is basically what the code I mentioned does, only instead of closing
the SMTP listener socket, it just answers all new connections with a reject
message (the actual one used by smail is '421 Too many connections; try again later.')