git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@1381 77e5149b-7576-45b1-b177-96237e5ba77b
Tomasz Kojm authored on 2005/03/07 09:34:04... | ... |
@@ -1,3 +1,9 @@ |
1 |
+Mon Mar 7 01:28:44 CET 2005 (tk) |
|
2 |
+--------------------------------- |
|
3 |
+ * libclamav, clamd: add reference counter to cl_node and improve database |
|
4 |
+ reload method in clamd (patch by Mark Pizzolato |
|
5 |
+ <clamav-devel*subscriptions.pizzolato.net>) |
|
6 |
+ |
|
1 | 7 |
Mon Mar 7 00:37:34 CET 2005 (tk) |
2 | 8 |
--------------------------------- |
3 | 9 |
* libclamav: add MD5 based false positive eliminator |
... | ... |
@@ -48,6 +48,7 @@ |
48 | 48 |
int progexit = 0; |
49 | 49 |
pthread_mutex_t exit_mutex; |
50 | 50 |
int reload = 0; |
51 |
+time_t reloaded_time = 0; |
|
51 | 52 |
pthread_mutex_t reload_mutex; |
52 | 53 |
int sighup = 0; |
53 | 54 |
|
... | ... |
@@ -55,7 +56,8 @@ typedef struct client_conn_tag { |
55 | 55 |
int sd; |
56 | 56 |
int options; |
57 | 57 |
const struct cfgstruct *copt; |
58 |
- const struct cl_node *root; |
|
58 |
+ struct cl_node *root; |
|
59 |
+ time_t root_timestamp; |
|
59 | 60 |
const struct cl_limits *limits; |
60 | 61 |
pid_t mainpid; |
61 | 62 |
} client_conn_t; |
... | ... |
@@ -117,7 +119,7 @@ void scanner_thread(void *arg) |
117 | 117 |
} |
118 | 118 |
pthread_mutex_unlock(&exit_mutex); |
119 | 119 |
pthread_mutex_lock(&reload_mutex); |
120 |
- if(reload) { |
|
120 |
+ if (conn->root_timestamp != reloaded_time) { |
|
121 | 121 |
session = FALSE; |
122 | 122 |
} |
123 | 123 |
pthread_mutex_unlock(&reload_mutex); |
... | ... |
@@ -125,6 +127,7 @@ void scanner_thread(void *arg) |
125 | 125 |
} while (session); |
126 | 126 |
|
127 | 127 |
close(conn->sd); |
128 |
+ cl_free(conn->root); |
|
128 | 129 |
free(conn); |
129 | 130 |
return; |
130 | 131 |
} |
... | ... |
@@ -517,7 +520,8 @@ int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *cop |
517 | 517 |
client_conn->sd = new_sd; |
518 | 518 |
client_conn->options = options; |
519 | 519 |
client_conn->copt = copt; |
520 |
- client_conn->root = root; |
|
520 |
+ client_conn->root = cl_dup(root); |
|
521 |
+ client_conn->root_timestamp = reloaded_time; |
|
521 | 522 |
client_conn->limits = &limits; |
522 | 523 |
client_conn->mainpid = mainpid; |
523 | 524 |
if (!thrmgr_dispatch(thr_pool, client_conn)) { |
... | ... |
@@ -552,18 +556,10 @@ int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *cop |
552 | 552 |
pthread_mutex_lock(&reload_mutex); |
553 | 553 |
if(reload) { |
554 | 554 |
pthread_mutex_unlock(&reload_mutex); |
555 |
- /* Destroy the thread manager. |
|
556 |
- * This waits for all current tasks to end |
|
557 |
- */ |
|
558 |
- thrmgr_destroy(thr_pool); |
|
559 | 555 |
root = reload_db(root, copt, FALSE); |
560 |
- if((thr_pool=thrmgr_new(max_threads, idletimeout, scanner_thread)) == NULL) { |
|
561 |
- logg("!thrmgr_new failed\n"); |
|
562 |
- pthread_mutex_unlock(&reload_mutex); |
|
563 |
- exit(-1); |
|
564 |
- } |
|
565 | 556 |
pthread_mutex_lock(&reload_mutex); |
566 | 557 |
reload = 0; |
558 |
+ time(&reloaded_time); |
|
567 | 559 |
pthread_mutex_unlock(&reload_mutex); |
568 | 560 |
#ifdef CLAMUKO |
569 | 561 |
if(cfgopt(copt, "ClamukoScanOnLine") || cfgopt(copt, "ClamukoScanOnAccess")) { |
... | ... |
@@ -579,6 +575,10 @@ int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *cop |
579 | 579 |
} |
580 | 580 |
} |
581 | 581 |
|
582 |
+ /* Destroy the thread manager. |
|
583 |
+ * This waits for all current tasks to end |
|
584 |
+ */ |
|
585 |
+ thrmgr_destroy(thr_pool); |
|
582 | 586 |
#ifdef CLAMUKO |
583 | 587 |
if(cfgopt(copt, "ClamukoScanOnLine") || cfgopt(copt, "ClamukoScanOnAccess")) { |
584 | 588 |
logg("Stopping Clamuko.\n"); |
... | ... |
@@ -586,6 +586,7 @@ int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *cop |
586 | 586 |
pthread_join(clamuko_pid, NULL); |
587 | 587 |
} |
588 | 588 |
#endif |
589 |
+ cl_free(root); |
|
589 | 590 |
logg("*Shutting down the main socket.\n"); |
590 | 591 |
shutdown(socketd, 2); |
591 | 592 |
logg("*Closing the main socket.\n"); |
... | ... |
@@ -128,6 +128,7 @@ struct cli_zip_node { |
128 | 128 |
}; |
129 | 129 |
|
130 | 130 |
struct cl_node { |
131 |
+ unsigned int refcount; |
|
131 | 132 |
unsigned int maxpatlen; /* maximal length of pattern in db */ |
132 | 133 |
|
133 | 134 |
/* Extended Boyer-Moore */ |
... | ... |
@@ -190,6 +191,7 @@ extern const char *cl_retver(void); |
190 | 190 |
extern int cl_loaddb(const char *filename, struct cl_node **root, unsigned int *signo); |
191 | 191 |
extern int cl_loaddbdir(const char *dirname, struct cl_node **root, unsigned int *signo); |
192 | 192 |
extern const char *cl_retdbdir(void); |
193 |
+extern struct cl_node *cl_dup(struct cl_node *root); |
|
193 | 194 |
|
194 | 195 |
/* CVD */ |
195 | 196 |
extern struct cl_cvd *cl_cvdhead(const char *file); |
... | ... |
@@ -43,6 +43,11 @@ static int targettab[TARGET_TABLE_SIZE] = { 0, CL_TYPE_MSEXE, CL_TYPE_MSOLE2, CL |
43 | 43 |
|
44 | 44 |
extern short cli_debug_flag; |
45 | 45 |
|
46 |
+#ifdef CL_THREAD_SAFE |
|
47 |
+# include <pthread.h> |
|
48 |
+pthread_mutex_t cli_ref_mutex = PTHREAD_MUTEX_INITIALIZER; |
|
49 |
+#endif |
|
50 |
+ |
|
46 | 51 |
int cli_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cl_node *root, unsigned short ftype) |
47 | 52 |
{ |
48 | 53 |
int ret, *partcnt; |
... | ... |
@@ -361,6 +366,26 @@ int cl_build(struct cl_node *root) |
361 | 361 |
return cli_ac_buildtrie(root); |
362 | 362 |
} |
363 | 363 |
|
364 |
+struct cl_node *cl_dup(struct cl_node *root) |
|
365 |
+{ |
|
366 |
+ if(!root) { |
|
367 |
+ cli_errmsg("cl_dup: root == NULL\n"); |
|
368 |
+ return NULL; |
|
369 |
+ } |
|
370 |
+ |
|
371 |
+#ifdef CL_THREAD_SAFE |
|
372 |
+ pthread_mutex_lock(&cli_ref_mutex); |
|
373 |
+#endif |
|
374 |
+ |
|
375 |
+ root->refcount++; |
|
376 |
+ |
|
377 |
+#ifdef CL_THREAD_SAFE |
|
378 |
+ pthread_mutex_unlock(&cli_ref_mutex); |
|
379 |
+#endif |
|
380 |
+ |
|
381 |
+ return root; |
|
382 |
+} |
|
383 |
+ |
|
364 | 384 |
void cl_free(struct cl_node *root) |
365 | 385 |
{ |
366 | 386 |
int i; |
... | ... |
@@ -372,6 +397,22 @@ void cl_free(struct cl_node *root) |
372 | 372 |
return; |
373 | 373 |
} |
374 | 374 |
|
375 |
+#ifdef CL_THREAD_SAFE |
|
376 |
+ pthread_mutex_lock(&cli_ref_mutex); |
|
377 |
+#endif |
|
378 |
+ |
|
379 |
+ root->refcount--; |
|
380 |
+ if (root->refcount) { |
|
381 |
+#ifdef CL_THREAD_SAFE |
|
382 |
+ pthread_mutex_unlock(&cli_ref_mutex); |
|
383 |
+#endif |
|
384 |
+ return; |
|
385 |
+ } |
|
386 |
+ |
|
387 |
+#ifdef CL_THREAD_SAFE |
|
388 |
+ pthread_mutex_unlock(&cli_ref_mutex); |
|
389 |
+#endif |
|
390 |
+ |
|
375 | 391 |
cli_ac_free(root); |
376 | 392 |
cli_bm_free(root); |
377 | 393 |
|
... | ... |
@@ -433,6 +433,7 @@ static int cli_loaddb(FILE *fd, struct cl_node **root, unsigned int *signo) |
433 | 433 |
*root = (struct cl_node *) cli_calloc(1, sizeof(struct cl_node)); |
434 | 434 |
if(!*root) |
435 | 435 |
return CL_EMEM; |
436 |
+ (*root)->refcount = 1; |
|
436 | 437 |
} |
437 | 438 |
|
438 | 439 |
if(!(*root)->ac_root) { |
... | ... |
@@ -506,6 +507,7 @@ static int cli_loadndb(FILE *fd, struct cl_node **root, unsigned int *signo) |
506 | 506 |
*root = (struct cl_node *) cli_calloc(1, sizeof(struct cl_node)); |
507 | 507 |
if(!*root) |
508 | 508 |
return CL_EMEM; |
509 |
+ (*root)->refcount = 1; |
|
509 | 510 |
} |
510 | 511 |
|
511 | 512 |
if(!(*root)->ac_root) { |
... | ... |
@@ -624,6 +626,7 @@ static int cli_loadhdb(FILE *fd, struct cl_node **root, unsigned int *signo, uns |
624 | 624 |
*root = (struct cl_node *) cli_calloc(1, sizeof(struct cl_node)); |
625 | 625 |
if(!*root) |
626 | 626 |
return CL_EMEM; |
627 |
+ (*root)->refcount = 1; |
|
627 | 628 |
} |
628 | 629 |
|
629 | 630 |
while(fgets(buffer, FILEBUFF, fd)) { |