Discussion:
[PATCH] smtpd_policy_service_(error_sleep_time|max_keepalive)
Markus Benning
2014-06-27 07:12:04 UTC
Permalink
Hi,

attached is a patch which adds the following configuration options
to postfix:

smtpd_policy_service_error_sleep_time=1s
smtpd_policy_service_max_keepalive=0

The first one will make the sleep(1) in attr_clnt_request configurable.
(line with comment /* XXX make configurable */)
In anvil_clnt.c and tls_mgr.c, where attr_clnt is also used, the current default 1 is used.
For check_policy_service (smtpd_check.c) the configuration parameter is used.

The second one will cause postfix to disconnect after the specified
amount of requests made over a policyd connection.
If set to 0 it will be disabled (default and current behaviour).
Also statically set to 0 in anvil_clnt.c and tls_mgr.c and configurable
for check_policy_service (smtpd_check.c).

I wrote this patch because I implemented a prefork policyd with
perl/Net::Server. So my policyd needs one process per connection.
For a test scenario I need to use multiple check_policy_service checks.
The number of connections will grow with smtpd processes * number of
checks.
For this reason I configured my policyd to close the connection after
each request. The documentations says that postfix will reconnect, but
it doesn't mention that it'll sleep(1) before reconnecting.
So it did not perform very well.

The max_keepalive options allows me to set this parameter to the same
value in postfix and the policyd. Then both will drop the connection
after a specified number of requests per connection.

The best solution would be if postfix itself could do some multiplexing
and use a single policyd connection for multiple smtpd like proxymap
does for eg. database tables. Is such a feature planed?
Do you think it would be hard to implement such a feature?

Markus
Wietse Venema
2014-06-27 11:23:03 UTC
Permalink
Why not ONLY have a connection use limit in Postfix that is
less than the limit in the policy daemon?

Wietse
Markus Benning
2014-06-27 11:54:05 UTC
Permalink
Do you mean to limit the smtpd processes or is there an option available
to limit the connections made by postfix to a policyd?

Currently i'm running 5 different checks in a tag&deliver mode.
This requires that every check is a single check_policy_service in
postfix. (each check can only return one action=PREPEND...)

If I use (only) 20 smtpd process postfix will keep 100 connections to the policyd
open which will result in 100 processes on the policyd side.
Which are most of the time just hanging around idle.
Each process eating up memory and keeping up an database connection.
If i configure postfix to close the connection (max_keepalive=1) even under full load
the policyd does not need to fork more that ~10 processes.
Most checks only take about 1-5ms.
Post by Wietse Venema
Why not ONLY have a connection use limit in Postfix that is
less than the limit in the policy daemon?
Wietse
Wietse Venema
2014-06-27 12:08:28 UTC
Permalink
Post by Wietse Venema
Why not ONLY have a connection use limit in Postfix that is
less than the limit in the policy daemon?
Why not patch Postfix ONLY to implement a configurable connection
use limit that is less than the limit in the policy daemon?

Wietse
Markus Benning
2014-06-27 13:04:21 UTC
Permalink
This would require that the connections can be shared across
smtpd server processes and to use a connection pool.

As far as i understood the source each attr_clnt/auto_clnt directly
opens a connection to the remote end. (VSTREAM)

Just limiting the number of connection will result in some smtpd
to hold a connection for very long (max_idle, max_ttl) even if the
connection is idle most of the time and other smtpd to block
till a new connection is allowed?
And you still need some IPC to share the number of total used
connections across smtpd processes?

Markus
Post by Wietse Venema
Post by Wietse Venema
Why not ONLY have a connection use limit in Postfix that is
less than the limit in the policy daemon?
Why not patch Postfix ONLY to implement a configurable connection
use limit that is less than the limit in the policy daemon?
Wietse
Wietse Venema
2014-06-27 13:31:10 UTC
Permalink
Post by Wietse Venema
Why not patch Postfix ONLY to implement a configurable connection
use limit that is less than the limit in the policy daemon?
This would require that the connections can be shared across
smtpd server processes and to use a connection pool.
OK, here is my last attempt. Please pay attention.

You have a policy daemon that wants to disconnect after N requests
(N >= 1) PER POLICY CONNECTION. Why not patch the Postfix policy
client to disconnect after N policy requests AND STOP THERE? Why
do you also have muck with the pause-after-error safety mechanism?

Wietse
Markus Benning
2014-06-27 14:16:44 UTC
Permalink
Post by Wietse Venema
Post by Wietse Venema
Why not patch Postfix ONLY to implement a configurable connection
use limit that is less than the limit in the policy daemon?
This would require that the connections can be shared across
smtpd server processes and to use a connection pool.
OK, here is my last attempt. Please pay attention.
You have a policy daemon that wants to disconnect after N requests
(N >= 1) PER POLICY CONNECTION. Why not patch the Postfix policy
client to disconnect after N policy requests AND STOP THERE? Why
do you also have muck with the pause-after-error safety mechanism?
Wietse
Okay, thats exactly what the max_keepalive part of the patch does.    
I'll remove the error sleep tim
Markus Benning
2014-06-30 07:44:59 UTC
Permalink
Post by Wietse Venema
Post by Wietse Venema
Why not patch Postfix ONLY to implement a configurable connection
use limit that is less than the limit in the policy daemon?
This would require that the connections can be shared across
smtpd server processes and to use a connection pool.
OK, here is my last attempt. Please pay attention.
You have a policy daemon that wants to disconnect after N requests
(N >= 1) PER POLICY CONNECTION. Why not patch the Postfix policy
client to disconnect after N policy requests AND STOP THERE? Why
do you also have muck with the pause-after-error safety mechanism?
Wietse
Okay, thats exactly what the max_keepalive part of the patch does.    
I'll remove the error sleep timer changes on monday and resend the patch.
  Markus
Okay, i reverted the pause after error changes.

The max_keepalive parameter has been renamed to
smtpd_policy_service_reuse_count_limit to be closer to the
naming scheme of the other parameters.

And i added some documentation to the patch.

Markus
Wietse Venema
2014-06-30 20:09:39 UTC
Permalink
This patch adds one argument to the attr_clnt_create() function,
which requires making changes to every program that that invokes
this function.

I will instead use the attr_clnt_control() function:

attr_clnt_control() allows the user to fine tune the behavior
of the specified client. The arguments are a list of (name,
value) terminated with ATTR_CLNT_CTL_END.

Since most programs never limit number of requests per connection,
the attr_clnt_control() function is the better interface to use.

Wietse
Wietse Venema
2014-07-01 13:25:26 UTC
Permalink
Post by Wietse Venema
This patch adds one argument to the attr_clnt_create() function,
which requires making changes to every program that that invokes
this function.
attr_clnt_control() allows the user to fine tune the behavior
of the specified client. The arguments are a list of (name,
value) terminated with ATTR_CLNT_CTL_END.
Since most programs never limit number of requests per connection,
the attr_clnt_control() function is the better interface to use.
I added code that resets the per-session request counter to zero,
and made some minor documentation changes. After validation tests
this is now part of Postfix version 2.12-20140701.

Wietse

smtpd_policy_service_request_limit (default: 0)
The maximal number of requests per Postfix SMTP server policy connec-
tion, or zero (no limit). Once a connection reaches this limit, the
connection is closed and the next request will be sent over a new con-
nection. This is a workaround to avoid error-recovery delays with pol-
icy servers that cannot maintain a persistent connection.

This feature is available in Postfix 2.12 and later.

Loading...