git-svn: trunk@5023
Török Edvin authored on 2009/04/06 18:26:11... | ... |
@@ -1,3 +1,9 @@ |
1 |
+Mon Apr 6 12:02:38 EEST 2009 (edwin) |
|
2 |
+------------------------------------- |
|
3 |
+ * clamd/server-th.c, shared/optparser.c: set timeout to readtimeout |
|
4 |
+ after receiving a chunk (bb #1540). better checks and documentation |
|
5 |
+ for MaxQueue (bb #1521). |
|
6 |
+ |
|
1 | 7 |
Fri Apr 3 15:30:34 CEST 2009 (tk) |
2 | 8 |
---------------------------------- |
3 | 9 |
* freshclam: short-term blacklisting of faulty mirrors; |
... | ... |
@@ -603,13 +603,16 @@ static const unsigned char* parse_dispatch_cmd(client_conn_t *conn, struct fd_bu |
603 | 603 |
} |
604 | 604 |
|
605 | 605 |
//static const unsigned char* parse_dispatch_cmd(client_conn_t *conn, struct fd_buf *buf, size_t *ppos, int *error, const struct optstruct *opts, int readtimeout) |
606 |
-static int handle_stream(client_conn_t *conn, struct fd_buf *buf, const struct optstruct *opts, int *error, size_t *ppos) |
|
606 |
+static int handle_stream(client_conn_t *conn, struct fd_buf *buf, const struct optstruct *opts, int *error, size_t *ppos, int readtimeout) |
|
607 | 607 |
{ |
608 | 608 |
int rc; |
609 | 609 |
size_t pos = *ppos; |
610 | 610 |
size_t cmdlen; |
611 | 611 |
|
612 | 612 |
logg("$mode == MODE_STREAM\n"); |
613 |
+ /* we received a chunk, set readtimeout */ |
|
614 |
+ time(&buf->timeout_at); |
|
615 |
+ buf->timeout_at += readtimeout; |
|
613 | 616 |
if (!buf->chunksize) { |
614 | 617 |
/* read chunksize */ |
615 | 618 |
if (buf->off >= 4) { |
... | ... |
@@ -941,22 +944,40 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi |
941 | 941 |
|
942 | 942 |
#if !defined(C_WINDOWS) && defined(RLIMIT_NOFILE) |
943 | 943 |
if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) { |
944 |
- if (max_queue*4 > rlim.rlim_cur) { |
|
945 |
- max_queue = rlim.rlim_cur / 4; |
|
946 |
- logg("^MaxQueue value too high, lowering to: %d\n", max_queue); |
|
947 |
- } else if (max_queue < 2*max_threads) { |
|
948 |
- /* increase it but only if it doesn't exceed limit otherwise */ |
|
949 |
- int newmax = 2*max_threads; |
|
950 |
- if (newmax*4 > rlim.rlim_cur) |
|
951 |
- newmax = rlim.rlim_cur/4; |
|
952 |
- if (max_queue < newmax) { |
|
953 |
- max_queue = newmax; |
|
954 |
- logg("^MaxQueue is lower than twice MaxThreads, increasing to: %d\n", max_queue); |
|
955 |
- } |
|
944 |
+ /* don't warn if default value is too high, silently fix it */ |
|
945 |
+ unsigned warn = optget(opts, "MaxQueue")->active; |
|
946 |
+ const unsigned clamdfiles = 6; |
|
947 |
+ /* Condition to not run out of file descriptors: |
|
948 |
+ * MaxThreads * MaxRecursion + (MaxQueue - MaxThreads) + CLAMDFILES < RLIMIT_NOFILE |
|
949 |
+ * CLAMDFILES is 6: 3 standard FD + logfile + 2 FD for reloading the DB |
|
950 |
+ * */ |
|
951 |
+ opt = optget(opts,"MaxRecursion"); |
|
952 |
+ unsigned maxrec = opt->numarg; |
|
953 |
+ int max_max_queue = rlim.rlim_cur - maxrec * max_threads - clamdfiles + max_threads; |
|
954 |
+ if (max_queue < max_threads) { |
|
955 |
+ max_queue = max_threads; |
|
956 |
+ if (warn) |
|
957 |
+ logg("^MaxQueue value too low, increasing to: %d\n", max_queue); |
|
958 |
+ } |
|
959 |
+ if (max_max_queue < max_threads) { |
|
960 |
+ logg("^MaxThreads * MaxRecursion is too high: %d, open file descriptor limit is: %d\n", |
|
961 |
+ maxrec*max_threads, rlim.rlim_cur); |
|
962 |
+ max_max_queue = max_threads; |
|
963 |
+ } |
|
964 |
+ if (max_queue > max_max_queue) { |
|
965 |
+ max_queue = max_max_queue; |
|
966 |
+ if (warn) |
|
967 |
+ logg("^MaxQueue value too high, lowering to: %d\n", max_queue); |
|
968 |
+ } else if (max_queue < 2*max_threads && max_queue < max_max_queue) { |
|
969 |
+ max_queue = 2*max_threads; |
|
970 |
+ if (max_queue > max_max_queue) |
|
971 |
+ max_queue = max_max_queue; |
|
972 |
+ /* always warn here */ |
|
973 |
+ logg("^MaxQueue is lower than twice MaxThreads, increasing to: %d\n", max_queue); |
|
956 | 974 |
} |
957 | 975 |
} |
958 | 976 |
#endif |
959 |
- |
|
977 |
+ logg("*MaxQueue set to: %d\n", max_queue); |
|
960 | 978 |
acceptdata.max_queue = max_queue; |
961 | 979 |
|
962 | 980 |
if(optget(opts, "ClamukoScanOnAccess")->enabled) |
... | ... |
@@ -1156,7 +1177,7 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi |
1156 | 1156 |
logg("$Garbage: %s\n", buf->buffer); |
1157 | 1157 |
error = 1; |
1158 | 1158 |
} else if (buf->mode == MODE_STREAM) { |
1159 |
- rc = handle_stream(&conn, buf, opts, &error, &pos); |
|
1159 |
+ rc = handle_stream(&conn, buf, opts, &error, &pos, readtimeout); |
|
1160 | 1160 |
if (rc == -1) |
1161 | 1161 |
break; |
1162 | 1162 |
else |
... | ... |
@@ -197,7 +197,7 @@ const struct clam_option clam_options[] = { |
197 | 197 |
|
198 | 198 |
{ "ReadTimeout", NULL, 0, TYPE_NUMBER, MATCH_NUMBER, 120, NULL, 0, OPT_MILTER, "Waiting for data from clamd will timeout after this time (seconds).\nValue of 0 disables the timeout.", "300" }, |
199 | 199 |
|
200 |
- { "MaxQueue", NULL, 0, TYPE_NUMBER, MATCH_NUMBER, 100, NULL, 0, OPT_CLAMD, "Maximum number of queued items (including those being processed)\nWARNING: you shouldn't increase this beyond 512, since you may run out of\nfile descriptors (usual max is 1024)\n", "200" }, |
|
200 |
+ { "MaxQueue", NULL, 0, TYPE_NUMBER, MATCH_NUMBER, 100, NULL, 0, OPT_CLAMD, "Maximum number of queued items (including those being processed by MaxThreads threads)\nIt is recommended to have this value at least twice MaxThreads if possible.\nWARNING: you shouldn't increase this too much to avoid running out of file descriptors, the following condition should hold: MaxThreads*MaxRecursion + MaxQueue < RLIMIT_NOFILE (usual max is 1024)\n", "200" }, |
|
201 | 201 |
|
202 | 202 |
{ "IdleTimeout", NULL, 0, TYPE_NUMBER, MATCH_NUMBER, 30, NULL, 0, OPT_CLAMD, "This option specifies how long (in seconds) the process should wait\nfor a new job.", "60" }, |
203 | 203 |
|