Browse code

add reference counter to cl_node and improve database reload in clamd

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
Showing 5 changed files
... ...
@@ -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)) {