diff options
author | Philip Hazel <ph10@hermes.cam.ac.uk> | 2007-06-27 11:01:51 +0000 |
---|---|---|
committer | Philip Hazel <ph10@hermes.cam.ac.uk> | 2007-06-27 11:01:51 +0000 |
commit | 8669f003e82e39e578787d9ebc1b40f36c024332 (patch) | |
tree | bcd91f47d13080c262f73ae9da0f2f86ea212dea /src | |
parent | 4d9c3e57c7decda537f4dab71b4d0880514334f6 (diff) |
Add queue_only_load_latch.
Diffstat (limited to 'src')
-rw-r--r-- | src/src/daemon.c | 62 | ||||
-rw-r--r-- | src/src/exim.c | 58 | ||||
-rw-r--r-- | src/src/expand.c | 4 | ||||
-rw-r--r-- | src/src/globals.c | 6 | ||||
-rw-r--r-- | src/src/globals.h | 4 | ||||
-rw-r--r-- | src/src/macros.h | 8 | ||||
-rw-r--r-- | src/src/readconf.c | 3 |
7 files changed, 90 insertions, 55 deletions
diff --git a/src/src/daemon.c b/src/src/daemon.c index e844403a4..55701f080 100644 --- a/src/src/daemon.c +++ b/src/src/daemon.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/daemon.c,v 1.23 2007/03/14 12:15:56 ph10 Exp $ */ +/* $Cambridge: exim/src/src/daemon.c,v 1.24 2007/06/27 11:01:51 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -241,7 +241,7 @@ subprocess because it might take time. */ if (smtp_load_reserve >= 0) { - load_average = os_getloadavg(); + load_average = OS_GETLOADAVG(); if (smtp_reserve_hosts == NULL && load_average > smtp_load_reserve) { DEBUG(D_any) debug_printf("rejecting SMTP connection: load average = %.2f\n", @@ -365,6 +365,7 @@ if (pid == 0) int old_pool = store_pool; int save_debug_selector = debug_selector; BOOL local_queue_only; + BOOL session_local_queue_only; #ifdef SA_NOCLDWAIT struct sigaction act; #endif @@ -413,7 +414,7 @@ if (pid == 0) /* Initialize the queueing flags */ queue_check_only(); - local_queue_only = queue_only; + session_local_queue_only = queue_only; /* Close the listening sockets, and set the SIGCHLD handler to SIG_IGN. We also attempt to set things up so that children are automatically reaped, @@ -457,13 +458,15 @@ if (pid == 0) if (debug_daemon) debug_selector = 0; /* If there are too many child processes for immediate delivery, - set the local_queue_only flag, which is initialized from the + set the session_local_queue_only flag, which is initialized from the configured value and may therefore already be TRUE. Leave logging - till later so it will have a message id attached. */ + till later so it will have a message id attached. Note that there is no + possibility of re-calculating this per-message, because the value of + smtp_accept_count does not change in this subprocess. */ if (smtp_accept_queue > 0 && smtp_accept_count > smtp_accept_queue) { - local_queue_only = TRUE; + session_local_queue_only = TRUE; queue_only_reason = 1; } @@ -550,26 +553,37 @@ if (pid == 0) store_reset(reset_point); /* If queue_only is set or if there are too many incoming connections in - existence, local_queue_only will be TRUE. If it is not, check whether we - have received too many messages in this session for immediate delivery. If - not, and queue_only_load is set, check that the load average is below it. - Note that, once set, local_queue_only remains set for any subsequent - messages on the same SMTP connection. This is a deliberate choice; even - though the load average may fall, it doesn't seem right to deliver later - messages on the same call when not delivering earlier ones. */ - - if (!local_queue_only) + existence, session_local_queue_only will be TRUE. If it is not, check + whether we have received too many messages in this session for immediate + delivery. */ + + if (!session_local_queue_only && + smtp_accept_queue_per_connection > 0 && + receive_messagecount > smtp_accept_queue_per_connection) { - if (smtp_accept_queue_per_connection > 0 && - receive_messagecount > smtp_accept_queue_per_connection) - { - local_queue_only = TRUE; - queue_only_reason = 2; - } - else if (queue_only_load >= 0) + session_local_queue_only = TRUE; + queue_only_reason = 2; + } + + /* Initialize local_queue_only from session_local_queue_only. If it is not + true, and queue_only_load is set, check that the load average is below it. + If local_queue_only is set by this means, we also set if for the session if + queue_only_load_latch is true (the default). This means that, once set, + local_queue_only remains set for any subsequent messages on the same SMTP + connection. This is a deliberate choice; even though the load average may + fall, it doesn't seem right to deliver later messages on the same call when + not delivering earlier ones. However, the are special circumstances such as + very long-lived connections from scanning appliances where this is not the + best strategy. In such cases, queue_only_load_latch should be set false. */ + + local_queue_only = session_local_queue_only; + if (!local_queue_only && queue_only_load >= 0) + { + local_queue_only = (load_average = OS_GETLOADAVG()) > queue_only_load; + if (local_queue_only) { - local_queue_only = (load_average = os_getloadavg()) > queue_only_load; - if (local_queue_only) queue_only_reason = 3; + queue_only_reason = 3; + if (queue_only_load_latch) session_local_queue_only = TRUE; } } diff --git a/src/src/exim.c b/src/src/exim.c index 3a89d8b91..12f61a20d 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/exim.c,v 1.56 2007/06/19 14:41:31 ph10 Exp $ */ +/* $Cambridge: exim/src/src/exim.c,v 1.57 2007/06/27 11:01:51 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -1291,6 +1291,7 @@ BOOL one_msg_action = FALSE; BOOL queue_only_set = FALSE; BOOL receiving_message = TRUE; BOOL sender_ident_set = FALSE; +BOOL session_local_queue_only; BOOL unprivileged; BOOL removed_privilege = FALSE; BOOL verify_address_mode = FALSE; @@ -3643,7 +3644,7 @@ if (receiving_message && (is_inetd && smtp_load_reserve >= 0) )) { - load_average = os_getloadavg(); + load_average = OS_GETLOADAVG(); } #endif @@ -4528,11 +4529,11 @@ else sender_address); } -/* Initialize the local_queue-only flag (this will be ignored if mua_wrapper is -set) */ +/* Initialize the session_local_queue-only flag (this will be ignored if +mua_wrapper is set) */ queue_check_only(); -local_queue_only = queue_only; +session_local_queue_only = queue_only; /* For non-SMTP and for batched SMTP input, check that there is enough space on the spool if so configured. On failure, we must not attempt to send an error @@ -4891,27 +4892,36 @@ while (more) } /* Else act on the result of message reception. We should not get here unless - message_id[0] is non-zero. If queue_only is set, local_queue_only will be - TRUE. If it is not, check on the number of messages received in this - connection. If that's OK and queue_only_load is set, check that the load - average is below it. If it is not, set local_queue_only TRUE. Note that it - then remains this way for any subsequent messages on the same SMTP connection. - This is a deliberate choice; even though the load average may fall, it - doesn't seem right to deliver later messages on the same call when not - delivering earlier ones. */ - - if (!local_queue_only) + message_id[0] is non-zero. If queue_only is set, session_local_queue_only + will be TRUE. If it is not, check on the number of messages received in this + connection. */ + + if (!session_local_queue_only && + smtp_accept_queue_per_connection > 0 && + receive_messagecount > smtp_accept_queue_per_connection) { - if (smtp_accept_queue_per_connection > 0 && - receive_messagecount > smtp_accept_queue_per_connection) - { - local_queue_only = TRUE; - queue_only_reason = 2; - } - else if (queue_only_load >= 0) + session_local_queue_only = TRUE; + queue_only_reason = 2; + } + + /* Initialize local_queue_only from session_local_queue_only. If it is false, + and queue_only_load is set, check that the load average is below it. If it is + not, set local_queue_only TRUE. If queue_only_load_latch is true (the + default), we put the whole session into queue_only mode. It then remains this + way for any subsequent messages on the same SMTP connection. This is a + deliberate choice; even though the load average may fall, it doesn't seem + right to deliver later messages on the same call when not delivering earlier + ones. However, there are odd cases where this is not wanted, so this can be + changed by setting queue_only_load_latch false. */ + + local_queue_only = session_local_queue_only; + if (!local_queue_only && queue_only_load >= 0) + { + local_queue_only = (load_average = OS_GETLOADAVG()) > queue_only_load; + if (local_queue_only) { - local_queue_only = (load_average = os_getloadavg()) > queue_only_load; - if (local_queue_only) queue_only_reason = 3; + queue_only_reason = 3; + if (queue_only_load_latch) session_local_queue_only = TRUE; } } diff --git a/src/src/expand.c b/src/src/expand.c index e56f86678..d86ea4658 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/expand.c,v 1.87 2007/06/22 14:38:58 ph10 Exp $ */ +/* $Cambridge: exim/src/src/expand.c,v 1.88 2007/06/27 11:01:51 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -1446,7 +1446,7 @@ while (last > first) return var_buffer; case vtype_load_avg: - sprintf(CS var_buffer, "%d", os_getloadavg()); /* load_average */ + sprintf(CS var_buffer, "%d", OS_GETLOADAVG()); /* load_average */ return var_buffer; case vtype_host_lookup: /* Lookup if not done so */ diff --git a/src/src/globals.c b/src/src/globals.c index f12e8eb34..4a75aed7c 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/globals.c,v 1.75 2007/06/22 14:38:58 ph10 Exp $ */ +/* $Cambridge: exim/src/src/globals.c,v 1.76 2007/06/27 11:01:52 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -828,6 +828,7 @@ BOOL queue_list_requires_admin = TRUE; BOOL queue_only = FALSE; uschar *queue_only_file = NULL; int queue_only_load = -1; +BOOL queue_only_load_latch = TRUE; BOOL queue_only_override = TRUE; BOOL queue_only_policy = FALSE; BOOL queue_run_first_delivery = FALSE; @@ -1006,7 +1007,7 @@ script that sets up a copy of Exim for running in the test harness. It seems that compilers are now clever, and share constant strings if they can. Elsewhere in Exim the string "<" is used. The compiler optimization seems to make use of the end of this string in order to save space. So the patching then -wrecks this. We default this optimization by adding some additional characters +wrecks this. We defeat this optimization by adding some additional characters onto the end of the string. */ uschar *running_status = US">>>running<<<" "\0EXTRA"; @@ -1163,6 +1164,7 @@ BOOL system_filter_uid_set = FALSE; BOOL system_filtering = FALSE; BOOL tcp_nodelay = TRUE; +int test_harness_load_avg = 0; int thismessage_size_limit = 0; int timeout_frozen_after = 0; BOOL timestamps_utc = FALSE; diff --git a/src/src/globals.h b/src/src/globals.h index f80e88b7b..920267d9d 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/globals.h,v 1.55 2007/06/22 14:38:58 ph10 Exp $ */ +/* $Cambridge: exim/src/src/globals.h,v 1.56 2007/06/27 11:01:52 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -527,6 +527,7 @@ extern int queue_run_pipe; /* Pipe for synchronizing */ extern int queue_interval; /* Queue running interval */ extern BOOL queue_only; /* TRUE to disable immediate delivery */ extern int queue_only_load; /* Max load before auto-queue */ +extern BOOL queue_only_load_latch; /* Latch queue_only_load TRUE */ extern uschar *queue_only_file; /* Queue if file exists/not-exists */ extern BOOL queue_only_override; /* Allow override from command line */ extern BOOL queue_only_policy; /* ACL or local_scan wants queue_only */ @@ -735,6 +736,7 @@ extern BOOL system_filter_uid_set; /* TRUE if uid set */ extern BOOL system_filtering; /* TRUE when running system filter */ extern BOOL tcp_nodelay; /* Controls TCP_NODELAY on daemon */ +extern int test_harness_load_avg; /* For use when testing */ extern int thismessage_size_limit; /* Limit for this message */ extern int timeout_frozen_after; /* Max time to keep frozen messages */ extern BOOL timestamps_utc; /* Use UTC for all times */ diff --git a/src/src/macros.h b/src/src/macros.h index 00f9f8eb2..f33ac7475 100644 --- a/src/src/macros.h +++ b/src/src/macros.h @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/macros.h,v 1.34 2007/06/19 14:41:31 ph10 Exp $ */ +/* $Cambridge: exim/src/src/macros.h,v 1.35 2007/06/27 11:01:52 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -15,6 +15,12 @@ a string as a text string. This is sometimes useful for debugging output. */ #define mac_expanded_string(s) mac_string(s) +/* When running in the test harness, the load average is fudged. */ + +#define OS_GETLOADAVG() \ + (running_in_test_harness? (test_harness_load_avg += 10) : os_getloadavg()) + + /* The address_item structure has a word full of 1-bit flags. These macros manipulate them. */ diff --git a/src/src/readconf.c b/src/src/readconf.c index a599ea81f..660a5bf8a 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/readconf.c,v 1.29 2007/02/06 11:11:40 ph10 Exp $ */ +/* $Cambridge: exim/src/src/readconf.c,v 1.30 2007/06/27 11:01:52 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -302,6 +302,7 @@ static optionlist optionlist_config[] = { { "queue_only", opt_bool, &queue_only }, { "queue_only_file", opt_stringptr, &queue_only_file }, { "queue_only_load", opt_fixed, &queue_only_load }, + { "queue_only_load_latch", opt_bool, &queue_only_load_latch }, { "queue_only_override", opt_bool, &queue_only_override }, { "queue_run_in_order", opt_bool, &queue_run_in_order }, { "queue_run_max", opt_int, &queue_run_max }, |