OSDN Git Service

#443 fix
[ultramonkey-l7/ultramonkey-l7-v3.git] / l7vsd / src / l7vsd.cpp
1 /*!
2  *    @file    l7vsd.cpp
3  *    @brief    l7vsd main class
4  *
5  * L7VSD: Linux Virtual Server for Layer7 Load Balancing
6  * Copyright (C) 2009  NTT COMWARE Corporation.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21  * 02110-1301 USA
22  *
23  **********************************************************************/
24 #include <sys/mman.h>
25 #include <signal.h>
26 #include <pthread.h>
27 #include <stdlib.h>
28 #include <errno.h>
29 #include <sys/time.h>
30 #include <sys/resource.h>
31 #include <boost/shared_ptr.hpp>
32 #include <sched.h>
33
34 #include "l7vsd.h"
35 #include "error_code.h"
36
37 #define    PARAM_SCHED_ALGORITHM    "task_scheduler_algorithm"
38 #define PARAM_SCHED_PRIORITY    "task_scheduler_priority"
39
40 namespace l7vs{
41
42 //! constructor
43 l7vsd::l7vsd()
44     :    help(false),
45         exit_requested(0),
46         received_sig(0){
47     Logger    logger( LOG_CAT_L7VSD_MAINTHREAD, 1, "l7vsd::l7vsd", __FILE__, __LINE__ );
48
49     option_dic["-h"]        = boost::bind( &l7vsd::parse_help, this, _1, _2, _3 );
50     option_dic["--help"]    = boost::bind( &l7vsd::parse_help, this, _1, _2, _3 );
51
52     starttime = boost::posix_time::second_clock::local_time();
53 }
54
55 //! destructor
56 l7vsd::~l7vsd(){
57     Logger    logger( LOG_CAT_L7VSD_MAINTHREAD, 2, "l7vsd::~l7vsd", __FILE__, __LINE__ );
58 }
59
60 //! virtual_service list command
61 //! @param[out]    arry of vs_element
62 //! @param[out]    error_code
63 void    l7vsd::list_virtual_service( vselist_type* out_vslist, error_code& err ){
64     Logger    logger( LOG_CAT_L7VSD_MAINTHREAD, 3, "l7vsd::list_virtual_service", __FILE__, __LINE__ );
65
66     boost::mutex::scoped_lock command_lock( command_mutex );
67     boost::mutex::scoped_lock vslist_lock( vslist_mutex );
68
69     if( !out_vslist ){
70         std::string msg("out_vslist pointer is null.");
71         Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 1, msg, __FILE__, __LINE__);
72         err.setter( true, msg );
73         return;
74     }
75
76     // make vselement list
77     for( vslist_type::iterator itr = vslist.begin();
78          itr != vslist.end();
79          ++itr ){
80         out_vslist->push_back( (*itr)->get_element() );
81     }
82
83     /*-------- DEBUG LOG --------*/
84     if( LOG_LV_DEBUG == Logger::getLogLevel( LOG_CAT_L7VSD_MAINTHREAD ) ){
85         std::stringstream    debugstr;
86         debugstr << "l7vsd::list_virtual_service return value:";
87         unsigned int i = 0;
88         BOOST_FOREACH( virtualservice_element vs_elem, *out_vslist ){
89             debugstr << boost::format( "*out_vslist[%d]=" ) % i;
90             debugstr << vs_elem;
91             debugstr << ": ";
92             ++i;
93         }
94         Logger::putLogDebug( LOG_CAT_L7VSD_MAINTHREAD, 4, debugstr.str(), __FILE__, __LINE__ );
95     }
96     /*------ DEBUG LOG END ------*/
97
98 }
99
100 //! virtual_service list verbose command
101 //! @param[out]    arry of vs_element
102 //! @param[out]    error_code
103 void    l7vsd::list_virtual_service_verbose( l7vsd_response* response, error_code& err ){
104     Logger    logger( LOG_CAT_L7VSD_MAINTHREAD, 5, "l7vsd::list_virtual_service_verbose", __FILE__, __LINE__ );
105
106     boost::mutex::scoped_lock command_lock( command_mutex );
107     boost::mutex::scoped_lock vslist_lock( vslist_mutex );
108
109     if( !response ){
110         std::string msg("response pointer is null.");
111         Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 2, msg, __FILE__, __LINE__);
112         err.setter( true, msg );
113         return;
114     }
115     if( !bridge ){
116         std::string msg("bridge pointer is null.");
117         Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 3, msg, __FILE__, __LINE__);
118         err.setter( true, msg );
119         return;
120     }
121     if( !rep ){
122         std::string msg("rep pointer is null.");
123         Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 4, msg, __FILE__, __LINE__);
124         err.setter( true, msg );
125         return;
126     }
127
128     unsigned long long    total_client_recv_byte = 0ULL;
129     unsigned long long    total_client_send_byte = 0ULL;
130     unsigned long long    total_realserver_recv_byte = 0ULL;
131     unsigned long long    total_realserver_send_byte = 0ULL;
132
133     // make vselement list
134     for( vslist_type::iterator itr = vslist.begin();
135          itr != vslist.end();
136          ++itr ){
137         response->virtualservice_status_list.push_back( (*itr)->get_element() );
138         // calc send recv bytes
139         total_client_recv_byte += (*itr)->get_up_recv_size();
140         total_client_send_byte += (*itr)->get_down_send_size();
141         total_realserver_recv_byte += (*itr)->get_down_recv_size();
142         total_realserver_send_byte += (*itr)->get_up_send_size();
143     }
144
145     // get_replication_mode
146     response->replication_mode_status = rep->get_status();
147
148     // get all category log level
149     Logger::getLogLevelAll( response->log_status_list );
150
151     // get snmp connect status
152     response->snmp_connection_status = bridge->get_connectionstate();
153
154     // get snmp all category log level
155     typedef std::map< LOG_CATEGORY_TAG, LOG_LEVEL_TAG > snmplogmap_type; 
156     snmplogmap_type snmplogmap;
157     bridge->get_loglevel_allcategory( snmplogmap );
158     for( snmplogmap_type::iterator itr = snmplogmap.begin();
159          itr != snmplogmap.end();
160          ++itr ){
161         response->snmp_log_status_list.push_back( *itr );
162     }
163
164     // calc total bps
165     unsigned long long    total_bytes =
166         total_client_recv_byte +
167         total_client_send_byte +
168         total_realserver_recv_byte +
169         total_realserver_send_byte;
170
171     boost::posix_time::ptime    now =
172         boost::posix_time::second_clock::local_time();
173     boost::posix_time::time_duration    dur = ( now - starttime );
174     if( 0ULL != dur.total_seconds() )
175         response->total_bps = ( total_bytes / dur.total_seconds() );
176     else
177         response->total_bps = 0ULL;
178
179     response->total_client_recv_byte = total_client_recv_byte;
180     response->total_client_send_byte = total_client_send_byte;
181     response->total_realserver_recv_byte = total_realserver_recv_byte;
182     response->total_realserver_send_byte = total_realserver_send_byte;
183
184     /*-------- DEBUG LOG --------*/
185     if( LOG_LV_DEBUG == Logger::getLogLevel( LOG_CAT_L7VSD_MAINTHREAD ) ){
186         std::stringstream    debugstr;
187         debugstr << boost::format( "l7vsd::list_virtual_service_verbose return value:%s" ) % *response;
188         Logger::putLogDebug( LOG_CAT_L7VSD_MAINTHREAD, 6, debugstr.str(), __FILE__, __LINE__ );
189     }
190     /*------ DEBUG LOG END ------*/
191
192 }
193
194 //! virtual_service add command
195 //! @param[in]    vs_element
196 //! @param[out]    error_code
197 void    l7vsd::add_virtual_service( const virtualservice_element* in_vselement, error_code& err ){
198     Logger    logger( LOG_CAT_L7VSD_MAINTHREAD, 7, "l7vsd::add_virtual_service", __FILE__, __LINE__ );
199
200     boost::mutex::scoped_lock command_lock( command_mutex );
201     boost::mutex::scoped_lock vslist_lock( vslist_mutex );
202
203     if( !in_vselement ){
204         std::string msg("in_vselement pointer is null.");
205         Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 5, msg, __FILE__, __LINE__);
206         err.setter( true, msg );
207         return;
208     }
209
210     /*-------- DEBUG LOG --------*/
211     if( LOG_LV_DEBUG == Logger::getLogLevel( LOG_CAT_L7VSD_MAINTHREAD ) ){
212         std::stringstream    debugstr;
213         debugstr << "l7vsd::add_virtual_service arguments:";
214         debugstr << boost::format( "*in_vselement=%s" ) % *in_vselement;
215         Logger::putLogDebug( LOG_CAT_L7VSD_MAINTHREAD, 8, debugstr.str(), __FILE__, __LINE__ );
216     }
217     /*------ DEBUG LOG END ------*/
218
219     if( vslist.end() == search_vslist( *in_vselement ) ){
220         // replication null check
221         if( NULL == rep ){
222             std::string msg("replication pointer is null.");
223             Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 6, msg, __FILE__, __LINE__);
224     
225             err.setter( true, msg );
226             return;
227         }
228         // create virtualservice
229         virtualservice_ptr    vsptr;
230         try{
231             vsptr.reset( new virtual_service( *this, *rep, *in_vselement ) );
232         }
233         catch( std::bad_alloc& ){
234             std::string msg("virtualservice create failed.");
235             Logger::putLogError(LOG_CAT_L7VSD_MAINTHREAD, 1, msg, __FILE__, __LINE__);
236             err.setter( true, msg );
237             return;
238         }
239         if( NULL == vsptr ){
240             std::string msg("virtualservice pointer is null.");
241             Logger::putLogError(LOG_CAT_L7VSD_MAINTHREAD, 2, msg, __FILE__, __LINE__);
242             err.setter( true, msg );
243             return;
244         }
245
246         // vs initialize
247         vsptr->initialize( err );
248         if( err )    return;
249
250         // set virtualservice
251         vsptr->set_virtualservice( *in_vselement, err );
252         if( err )    return;
253
254         try{
255         
256             // create thread and run
257             vs_threads.create_thread( boost::bind( &virtual_service::run, vsptr ) );
258
259         }
260         catch( ... ){
261             std::stringstream    buf;
262             buf << "virtualservice thread initialize failed.";
263             Logger::putLogError(LOG_CAT_L7VSD_MAINTHREAD, 8, buf.str(), __FILE__, __LINE__);
264             err.setter( true, buf.str() );
265             
266             vsptr->stop();
267             l7vs::error_code finalize_err;
268             vsptr->finalize( finalize_err );
269             
270             /*-------- DEBUG LOG --------*/
271             if( LOG_LV_DEBUG == Logger::getLogLevel( LOG_CAT_L7VSD_MAINTHREAD ) ){
272                 Logger::putLogDebug( LOG_CAT_L7VSD_MAINTHREAD, 41, "out l7vsd::add_virtual_service", __FILE__, __LINE__ );
273             }
274             /*------ DEBUG LOG END ------*/
275             
276             return;
277         }
278             
279         // add to vslist
280         vslist.push_back( vsptr );
281
282         // when first vs, replication switch to master
283         if( 1U == vslist.size() ){
284             rep->switch_to_master();
285         }
286     }
287     else {
288         std::string msg("virtual service already exist.");
289         Logger::putLogWarn(LOG_CAT_L7VSD_VIRTUALSERVICE, 23, msg, __FILE__, __LINE__);
290
291         err.setter( true, msg );
292         return;
293     }
294 }
295
296 //! virtual_service del command
297 //! @param[in]    vs_element
298 //! @param[out]    error_code
299 void    l7vsd::del_virtual_service( const virtualservice_element* in_vselement, error_code& err ){
300     Logger    logger( LOG_CAT_L7VSD_MAINTHREAD, 9, "l7vsd::del_virtual_service", __FILE__, __LINE__ );
301
302     boost::mutex::scoped_lock command_lock( command_mutex );
303     boost::mutex::scoped_lock vslist_lock( vslist_mutex );
304
305     if( !in_vselement ){
306         std::string msg("in_vselement pointer is null.");
307         Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 7, msg, __FILE__, __LINE__);
308         err.setter( true, msg );
309         return;
310     }
311
312     /*-------- DEBUG LOG --------*/
313     if( LOG_LV_DEBUG == Logger::getLogLevel( LOG_CAT_L7VSD_MAINTHREAD ) ){
314         std::stringstream    debugstr;
315         debugstr << "l7vsd::del_virtual_service arguments:";
316         debugstr << boost::format( "*in_vselement=%s" ) % *in_vselement;
317         Logger::putLogDebug( LOG_CAT_L7VSD_MAINTHREAD, 10, debugstr.str(), __FILE__, __LINE__ );
318     }
319     /*------ DEBUG LOG END ------*/
320
321     vslist_type::iterator vsitr = search_vslist( *in_vselement ,true);
322     if( vslist.end() !=  vsitr ){
323         // vs stop
324         (*vsitr)->stop();
325         // vs finalize
326         (*vsitr)->finalize( err );
327
328         // when first vs, replication switch to slave
329         if( 0U == vslist.size() ){
330             rep->switch_to_slave();
331         }
332     }
333     else {
334         std::string msg("virtual service not found.");
335         Logger::putLogWarn(LOG_CAT_L7VSD_VIRTUALSERVICE, 24, msg, __FILE__, __LINE__);
336
337         err.setter( true, msg );
338         return;
339     }
340 }
341
342 //! virtual_service edit command
343 //! @param[in]    vs_element
344 //! @param[out]    error_code
345 void    l7vsd::edit_virtual_service( const virtualservice_element* in_vselement, error_code& err ){
346     Logger    logger( LOG_CAT_L7VSD_MAINTHREAD, 11, "l7vsd::edit_virtual_service", __FILE__, __LINE__ );
347
348     boost::mutex::scoped_lock command_lock( command_mutex );
349     boost::mutex::scoped_lock vslist_lock( vslist_mutex );
350
351     if( !in_vselement ){
352         std::string msg("in_vselement pointer is null.");
353         Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 8, msg, __FILE__, __LINE__);
354         err.setter( true, msg );
355         return;
356     }
357
358     /*-------- DEBUG LOG --------*/
359     if( LOG_LV_DEBUG == Logger::getLogLevel( LOG_CAT_L7VSD_MAINTHREAD ) ){
360         std::stringstream    debugstr;
361         debugstr << "l7vsd::edit_virtual_service arguments:";
362         debugstr << boost::format( "*in_vselement=%s" ) % *in_vselement;
363         Logger::putLogDebug( LOG_CAT_L7VSD_MAINTHREAD, 12, debugstr.str(), __FILE__, __LINE__ );
364     }
365     /*------ DEBUG LOG END ------*/
366
367     vslist_type::iterator vsitr = search_vslist( *in_vselement );
368     if( vslist.end() !=  vsitr ){
369         // edit virtualservice
370         (*vsitr)->edit_virtualservice( *in_vselement, err );
371         if( err )    return;
372     }
373     else {
374         std::string msg("virtual service not found.");
375         Logger::putLogWarn(LOG_CAT_L7VSD_VIRTUALSERVICE, 25, msg, __FILE__, __LINE__);
376
377         err.setter( true, msg );
378         return;
379     }
380 }
381
382 //! real_server add command
383 //! @param[in]    vs_element
384 //! @param[out]    error_code
385 void    l7vsd::add_real_server( const virtualservice_element* in_vselement, error_code& err ){
386     Logger    logger( LOG_CAT_L7VSD_MAINTHREAD, 13, "l7vsd::add_real_server", __FILE__, __LINE__ );
387
388     boost::mutex::scoped_lock command_lock( command_mutex );
389     boost::mutex::scoped_lock vslist_lock( vslist_mutex );
390
391     if( !in_vselement ){
392         std::string msg("in_vselement pointer is null.");
393         Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 9, msg, __FILE__, __LINE__);
394         err.setter( true, msg );
395         return;
396     }
397
398     /*-------- DEBUG LOG --------*/
399     if( LOG_LV_DEBUG == Logger::getLogLevel( LOG_CAT_L7VSD_MAINTHREAD ) ){
400         std::stringstream    debugstr;
401         debugstr << "l7vsd::add_real_server arguments:";
402         debugstr << boost::format( "*in_vselement=%s" ) % *in_vselement;
403         Logger::putLogDebug( LOG_CAT_L7VSD_MAINTHREAD, 14, debugstr.str(), __FILE__, __LINE__ );
404     }
405     /*------ DEBUG LOG END ------*/
406
407     vslist_type::iterator vsitr = search_vslist( *in_vselement );
408     if( vslist.end() !=  vsitr ){
409         // add realserver
410         (*vsitr)->add_realserver( *in_vselement, err );
411         if( err )    return;
412     }
413     else {
414         std::string msg("virtual service not found.");
415         Logger::putLogWarn(LOG_CAT_L7VSD_VIRTUALSERVICE, 26, msg, __FILE__, __LINE__);
416
417         err.setter( true, msg );
418         return;
419     }
420 }
421
422 //! real_server del command
423 //! @param[in]    vs_element
424 //! @param[out]    error_code
425 void    l7vsd::del_real_server( const virtualservice_element* in_vselement, error_code& err ){
426     Logger    logger( LOG_CAT_L7VSD_MAINTHREAD, 15, "l7vsd::del_real_server", __FILE__, __LINE__ );
427
428     boost::mutex::scoped_lock command_lock( command_mutex );
429     boost::mutex::scoped_lock vslist_lock( vslist_mutex );
430
431     if( !in_vselement ){
432         std::string msg("in_vselement pointer is null.");
433         Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 10, msg, __FILE__, __LINE__);
434         err.setter( true, msg );
435         return;
436     }
437
438     /*-------- DEBUG LOG --------*/
439     if( LOG_LV_DEBUG == Logger::getLogLevel( LOG_CAT_L7VSD_MAINTHREAD ) ){
440         std::stringstream    debugstr;
441         debugstr << "l7vsd::del_real_server arguments:";
442         debugstr << boost::format( "*in_vselement=%s" ) % *in_vselement;
443         Logger::putLogDebug( LOG_CAT_L7VSD_MAINTHREAD, 16, debugstr.str(), __FILE__, __LINE__ );
444     }
445     /*------ DEBUG LOG END ------*/
446
447     vslist_type::iterator vsitr = search_vslist( *in_vselement );
448     if( vslist.end() !=  vsitr ){
449         // del realserver
450         (*vsitr)->del_realserver( *in_vselement, err );
451         if( err )    return;
452     }
453     else {
454         std::string msg("virtual service not found.");
455         Logger::putLogWarn(LOG_CAT_L7VSD_VIRTUALSERVICE, 27, msg, __FILE__, __LINE__);
456
457         err.setter( true, msg );
458         return;
459     }
460 }
461
462 //! real_server edit command
463 //! @param[in]    vs_element
464 //! @param[out]    error_code
465 void    l7vsd::edit_real_server( const virtualservice_element* in_vselement, error_code& err ){
466     Logger    logger( LOG_CAT_L7VSD_MAINTHREAD, 17, "l7vsd::edit_real_server", __FILE__, __LINE__ );
467
468     boost::mutex::scoped_lock command_lock( command_mutex );
469     boost::mutex::scoped_lock vslist_lock( vslist_mutex );
470
471     if( !in_vselement ){
472         std::string msg("in_vselement pointer is null.");
473         Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 11, msg, __FILE__, __LINE__);
474         err.setter( true, msg );
475         return;
476     }
477
478     /*-------- DEBUG LOG --------*/
479     if( LOG_LV_DEBUG == Logger::getLogLevel( LOG_CAT_L7VSD_MAINTHREAD ) ){
480         std::stringstream    debugstr;
481         debugstr << "l7vsd::edit_real_server arguments:";
482         debugstr << boost::format( "*in_vselement=%s" ) % *in_vselement;
483         Logger::putLogDebug( LOG_CAT_L7VSD_MAINTHREAD, 18, debugstr.str(), __FILE__, __LINE__ );
484     }
485     /*------ DEBUG LOG END ------*/
486
487     vslist_type::iterator vsitr = search_vslist( *in_vselement );
488     if( vslist.end() !=  vsitr ){
489         // del realserver
490         (*vsitr)->edit_realserver( *in_vselement, err );
491         if( err )    return;
492     }
493     else {
494         std::string msg("virtual service not found.");
495         Logger::putLogWarn(LOG_CAT_L7VSD_VIRTUALSERVICE, 28, msg, __FILE__, __LINE__);
496
497         err.setter( true, msg );
498         return;
499     }
500 }
501
502 //! virtual_service flush command
503 //! @param[out]    error_code
504 void    l7vsd::flush_virtual_service( error_code& err ){
505     Logger    logger( LOG_CAT_L7VSD_MAINTHREAD, 19, "l7vsd::flush_virtual_service", __FILE__, __LINE__ );
506
507     boost::mutex::scoped_lock command_lock( command_mutex );
508     boost::mutex::scoped_lock vslist_lock( vslist_mutex );
509
510     // all virtualservice stop and finalize
511     for(;;){
512         vslist_type::iterator itr = vslist.begin();
513         if(vslist.end() == itr){
514             break;
515         }
516         else{
517             // vs stop
518             (*itr)->stop();
519             // vs finalize
520             (*itr)->finalize( err );
521         }
522     }    
523
524     // join virtualservice threads
525     vs_threads.join_all();
526
527     // replication switch to slave
528     rep->switch_to_slave();
529 }
530
531 //! replication command
532 //! @param[in]    replicaiton command
533 //! @param[out]    error_code
534 void    l7vsd::replication_command( const l7vsadm_request::REPLICATION_COMMAND_TAG* cmd, error_code& err ){
535     Logger    logger( LOG_CAT_L7VSD_MAINTHREAD, 20, "l7vsd::replication_command", __FILE__, __LINE__ );
536
537     boost::mutex::scoped_lock command_lock( command_mutex );
538     boost::mutex::scoped_lock vslist_lock( vslist_mutex );
539
540     if( !cmd ){
541         std::string msg("cmd pointer is null.");
542         Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 12, msg, __FILE__, __LINE__);
543         err.setter( true, msg );
544         return;
545     }
546     if( !rep ){
547         std::string msg("rep pointer is null.");
548         Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 13, msg, __FILE__, __LINE__);
549         err.setter( true, msg );
550         return;
551     }
552
553     /*-------- DEBUG LOG --------*/
554     if( LOG_LV_DEBUG == Logger::getLogLevel( LOG_CAT_L7VSD_MAINTHREAD ) ){
555         std::stringstream    debugstr;
556         debugstr << "l7vsd::replication_command arguments:";
557         debugstr << boost::format( "*cmd=%d" ) % *cmd;
558         Logger::putLogDebug( LOG_CAT_L7VSD_MAINTHREAD, 21, debugstr.str(), __FILE__, __LINE__ );
559     }
560     /*------ DEBUG LOG END ------*/
561
562     switch( *cmd ){
563     case    l7vsadm_request::REP_START:
564         rep->start();
565         break;
566     case    l7vsadm_request::REP_STOP:
567         rep->stop();
568         break;
569     case    l7vsadm_request::REP_FORCE:
570         rep->force_replicate();
571         break;
572     case    l7vsadm_request::REP_DUMP:
573         rep->dump_memory();
574         break;
575     default:
576         std::string msg("invalid replication command.");
577         Logger::putLogError(LOG_CAT_L7VSD_REPLICATION, 38, msg, __FILE__, __LINE__);
578         err.setter( true, msg );
579         return;
580     }
581 }
582
583 //! loglevel set command
584 //! @param[in]    log category
585 //! @param[in]    log level
586 //! @param[out]    error_code
587 void    l7vsd::set_loglevel( const LOG_CATEGORY_TAG* cat, const LOG_LEVEL_TAG* level, error_code& err ){
588     Logger    logger( LOG_CAT_L7VSD_MAINTHREAD, 22, "l7vsd::set_loglevel", __FILE__, __LINE__ );
589
590     boost::mutex::scoped_lock command_lock( command_mutex );
591     boost::mutex::scoped_lock vslist_lock( vslist_mutex );
592
593     if( !cat ){
594         std::string msg("cat pointer is null.");
595         Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 14, msg, __FILE__, __LINE__);
596         err.setter( true, msg );
597         return;
598     }
599     if( !level ){
600         std::string msg("level pointer is null.");
601         Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 15, msg, __FILE__, __LINE__);
602         err.setter( true, msg );
603         return;
604     }
605
606     /*-------- DEBUG LOG --------*/
607     if( LOG_LV_DEBUG == Logger::getLogLevel( LOG_CAT_L7VSD_MAINTHREAD ) ){
608         std::stringstream    debugstr;
609         debugstr << "l7vsd::set_loglevel arguments:";
610         debugstr << boost::format( "*cat=%d, level=%d" ) % *cat % *level;
611         Logger::putLogDebug( LOG_CAT_L7VSD_MAINTHREAD, 23, debugstr.str(), __FILE__, __LINE__ );
612     }
613     /*------ DEBUG LOG END ------*/
614
615     if( LOG_CAT_END == *cat ){
616         // set loglevel all
617         if( !Logger::setLogLevelAll( *level ) ){
618             std::string msg("set loglevel all failed.");
619             Logger::putLogError(LOG_CAT_L7VSD_LOGGER, 122, msg, __FILE__, __LINE__);
620             err.setter( true, msg );
621             return;
622         }
623     }
624     else{
625         if( !Logger::setLogLevel( *cat, *level ) ){
626             std::string msg("set loglevel failed.");
627             Logger::putLogError(LOG_CAT_L7VSD_LOGGER, 123, msg, __FILE__, __LINE__);
628             err.setter( true, msg );
629             return;
630         }
631     }
632 }
633
634 //! snmp loglevel set command
635 //! @param[in]    log category
636 //! @param[in]    log level
637 //! @param[out]    error_code
638 void    l7vsd::snmp_set_loglevel( const LOG_CATEGORY_TAG* cat, const LOG_LEVEL_TAG* level, error_code& err ){
639     Logger    logger( LOG_CAT_L7VSD_MAINTHREAD, 24, "l7vsd::snmp_set_loglevel", __FILE__, __LINE__ );
640
641     boost::mutex::scoped_lock command_lock( command_mutex );
642     boost::mutex::scoped_lock vslist_lock( vslist_mutex );
643
644     if( !cat ){
645         std::string msg("cat pointer is null.");
646         Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 16, msg, __FILE__, __LINE__);
647         err.setter( true, msg );
648         return;
649     }
650     if( !level ){
651         std::string msg("level pointer is null.");
652         Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 17, msg, __FILE__, __LINE__);
653         err.setter( true, msg );
654         return;
655     }
656     if( !bridge ){
657         std::string msg("bridge pointer is null.");
658         Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 18, msg, __FILE__, __LINE__);
659         err.setter( true, msg );
660         return;
661     }
662
663     /*-------- DEBUG LOG --------*/
664     if( LOG_LV_DEBUG == Logger::getLogLevel( LOG_CAT_L7VSD_MAINTHREAD ) ){
665         std::stringstream    debugstr;
666         debugstr << "l7vsd::snmp_set_loglevel arguments:";
667         debugstr << boost::format( "*cat=%d, level=%d" ) % *cat % *level;
668         Logger::putLogDebug( LOG_CAT_L7VSD_MAINTHREAD, 25, debugstr.str(), __FILE__, __LINE__ );
669     }
670     /*------ DEBUG LOG END ------*/
671
672     if( LOG_CAT_END == *cat ){
673         // set loglevel all
674         if( 0 != bridge->change_loglevel_allcategory( *level ) ){
675             std::string msg("set snmp loglevel all failed.");
676             Logger::putLogError(LOG_CAT_L7VSD_LOGGER, 124, msg, __FILE__, __LINE__);
677             err.setter( true, msg );
678             return;
679         }
680     }
681     else{
682         if( 0 != bridge->change_loglevel( *cat, *level ) ){
683             std::string msg("set snmp loglevel failed.");
684             Logger::putLogError(LOG_CAT_L7VSD_LOGGER, 125, msg, __FILE__, __LINE__);
685             err.setter( true, msg );
686             return;
687         }
688     }
689 }
690
691 //! reload parameter command
692 //! @param[in]    reload component
693 //! @param[out]    error_code
694 void    l7vsd::reload_parameter( const PARAMETER_COMPONENT_TAG* comp, error_code& err ){
695     Logger    logger( LOG_CAT_L7VSD_MAINTHREAD, 26, "l7vsd::reload_parameter", __FILE__, __LINE__ );
696
697     boost::mutex::scoped_lock command_lock( command_mutex );
698     boost::mutex::scoped_lock vslist_lock( vslist_mutex );
699
700     if( !comp ){
701         std::string msg("comp pointer is null.");
702         Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 19, msg, __FILE__, __LINE__);
703         err.setter( true, msg );
704         return;
705     }
706     if( !rep ){
707         std::string msg("rep pointer is null.");
708         Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 20, msg, __FILE__, __LINE__);
709         err.setter( true, msg );
710         return;
711     }
712     if( !bridge ){
713         std::string msg("bridge pointer is null.");
714         Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 21, msg, __FILE__, __LINE__);
715         err.setter( true, msg );
716         return;
717     }
718
719     /*-------- DEBUG LOG --------*/
720     if( LOG_LV_DEBUG == Logger::getLogLevel( LOG_CAT_L7VSD_MAINTHREAD ) ){
721         std::stringstream    debugstr;
722         debugstr << "l7vsd::reload_parameter arguments:";
723         debugstr << boost::format( "*comp=%d" ) % *comp;
724         Logger::putLogDebug( LOG_CAT_L7VSD_MAINTHREAD, 27, debugstr.str(), __FILE__, __LINE__ );
725     }
726     /*------ DEBUG LOG END ------*/
727
728     Parameter    param;
729     Logger        logger_instance;
730
731     switch( *comp ){
732     case    PARAM_COMP_REPLICATION:
733         if( param.read_file( *comp  )){
734             rep->reset();
735         } else {
736             std::string msg("parameter reload failed.");
737             Logger::putLogError(LOG_CAT_L7VSD_PARAMETER, 7, msg, __FILE__, __LINE__);
738             err.setter( true, msg );
739             return;
740         }
741         
742         break;
743     case    PARAM_COMP_LOGGER:
744         if( param.read_file( *comp  )){
745         
746             try {
747                 logger_instance.loadConf();
748             }catch(...){
749             }
750             
751         } else {
752             std::string msg("parameter reload failed.");
753             Logger::putLogError(LOG_CAT_L7VSD_PARAMETER, 7, msg, __FILE__, __LINE__);
754             err.setter( true, msg );
755             return;
756         }
757
758         break;
759     case    PARAM_COMP_SNMPAGENT:
760         if( param.read_file( *comp  )){
761             bridge->reload_config();
762         } else {
763             std::string msg("parameter reload failed.");
764             Logger::putLogError(LOG_CAT_L7VSD_PARAMETER, 7, msg, __FILE__, __LINE__);
765             err.setter( true, msg );
766             return;
767         }
768
769         break;
770     case    PARAM_COMP_ALL:
771         if( !param.read_file( PARAM_COMP_REPLICATION  )){
772             std::string msg("parameter reload failed.");
773             Logger::putLogError(LOG_CAT_L7VSD_PARAMETER, 7, msg, __FILE__, __LINE__);
774             err.setter( true, msg );
775             return;
776         }
777         
778         if( !param.read_file( PARAM_COMP_LOGGER  )){
779             std::string msg("parameter reload failed.");
780             Logger::putLogError(LOG_CAT_L7VSD_PARAMETER, 7, msg, __FILE__, __LINE__);
781             err.setter( true, msg );
782             return;
783         }
784         
785         if( !param.read_file( PARAM_COMP_SNMPAGENT  )){
786             std::string msg("parameter reload failed.");
787             Logger::putLogError(LOG_CAT_L7VSD_PARAMETER, 7, msg, __FILE__, __LINE__);
788             err.setter( true, msg );
789             return;
790         }
791         
792         rep->reset();
793         try {
794             logger_instance.loadConf();
795         }catch(...){
796         }
797         bridge->reload_config();
798     
799         break;
800     default:
801         std::string msg("parameter reload command not found.");
802         Logger::putLogWarn(LOG_CAT_L7VSD_PARAMETER, 1, msg, __FILE__, __LINE__);
803         err.setter( true, msg );
804         return;
805     }
806
807
808 }
809
810 //! vs_list search function
811 //! @param[in]    vs_element
812 //! @param[out]    error_code
813 l7vsd::vslist_type::iterator    l7vsd::search_vslist( 
814     const virtualservice_element& in_vselement,
815     bool find_module_name ) const {
816     Logger    logger( LOG_CAT_L7VSD_MAINTHREAD, 28, "l7vsd::search_vslist", __FILE__, __LINE__ );
817
818     /*-------- DEBUG LOG --------*/
819     if( LOG_LV_DEBUG == Logger::getLogLevel( LOG_CAT_L7VSD_MAINTHREAD ) ){
820         std::stringstream    debugstr;
821         debugstr << "l7vsd::search_vslist arguments:";
822         debugstr << boost::format( "in_vselement=%s" ) % in_vselement;
823         Logger::putLogDebug( LOG_CAT_L7VSD_MAINTHREAD, 29, debugstr.str(), __FILE__, __LINE__ );
824     }
825     /*------ DEBUG LOG END ------*/
826
827     for( vslist_type::iterator itr = vslist.begin();
828          itr != vslist.end();
829          ++itr ){
830         if( in_vselement.udpmode ){
831             if(    ( (*itr)->get_element().udpmode ) &&
832                 ( (*itr)->get_element().udp_recv_endpoint  == in_vselement.udp_recv_endpoint ) ){
833                 if( find_module_name ){
834                     if( (*itr)->get_element().protocol_module_name ==  in_vselement.protocol_module_name){
835                         return itr;
836                     }
837                 }else{
838                     return itr;
839                 }
840             }
841         }
842         else{
843             if(    ( !((*itr)->get_element().udpmode) ) &&
844                 ( (*itr)->get_element().tcp_accept_endpoint == in_vselement.tcp_accept_endpoint ) ){
845                 if( find_module_name ){
846                     if( (*itr)->get_element().protocol_module_name ==  in_vselement.protocol_module_name){
847                         return itr;
848                     }
849                 }else{
850                     return itr;
851                 }
852             }
853         }
854     }
855     return vslist.end();
856 }
857
858 //! virtualservice release from vslist
859 //! @param[in]    vs_element
860 void    l7vsd::release_virtual_service( const virtualservice_element& in_vselement ) const {
861     Logger    logger( LOG_CAT_L7VSD_MAINTHREAD, 30, "l7vsd::release_virtual_service", __FILE__, __LINE__ );
862
863     /*-------- DEBUG LOG --------*/
864     if( LOG_LV_DEBUG == Logger::getLogLevel( LOG_CAT_L7VSD_MAINTHREAD ) ){
865         std::stringstream    debugstr;
866         debugstr << "l7vsd::release_virtual_service arguments:";
867         debugstr << boost::format( "in_vselement=%s" ) % in_vselement;
868         Logger::putLogDebug( LOG_CAT_L7VSD_MAINTHREAD, 31, debugstr.str(), __FILE__, __LINE__ );
869     }
870     /*------ DEBUG LOG END ------*/
871
872     vslist_type::iterator vsitr = search_vslist( in_vselement );
873     if( vslist.end() !=  vsitr ){
874         // remove from vslist
875         vslist.remove( *vsitr );
876     }
877 }
878 //! virtualservice_list getter
879 //! @return    vslist
880 l7vsd::vslist_type&    l7vsd::get_virtualservice_list(){
881     Logger    logger( LOG_CAT_L7VSD_MAINTHREAD, 32, "l7vsd::get_virtualservice_list", __FILE__, __LINE__ );
882
883     return vslist;
884 }
885
886 //! virtualservice_list mutex getter
887 //! @return    vslist_mutex
888 boost::mutex&    l7vsd::get_virtualservice_list_mutex(){
889     Logger    logger( LOG_CAT_L7VSD_MAINTHREAD, 33, "l7vsd::get_virtualservice_list_mutex", __FILE__, __LINE__ );
890
891     return vslist_mutex;
892 }
893
894 //! l7vsd run method
895 //! @param[in]    argument count
896 //! @param[in]    argument value
897 int    l7vsd::run( int argc, char* argv[] ) {
898     Logger    logger( LOG_CAT_L7VSD_MAINTHREAD, 34, "l7vsd::run", __FILE__, __LINE__ );
899
900     /*-------- DEBUG LOG --------*/
901     if( LOG_LV_DEBUG == Logger::getLogLevel( LOG_CAT_L7VSADM_COMMON ) ){
902         std::stringstream    debugstr;
903         debugstr << boost::format( "l7vsd::run arguments:%s" ) % argument_debug_dump( argc, argv );
904         Logger::putLogDebug( LOG_CAT_L7VSD_MAINTHREAD, 35, debugstr.str(), __FILE__, __LINE__ );
905     }
906     /*------ DEBUG LOG END ------*/
907
908     mlockall(MCL_FUTURE);
909
910     try{
911         // check options
912         if( !check_options( argc, argv ) ){
913             std::cerr << usage();
914             munlockall();
915             return -1;
916         }
917     
918         // help mode ?
919         if( help ){
920             std::cout << usage();
921             munlockall();
922             return 0;
923         }
924     
925         if( 0 > daemon( 0, 0 ) ){
926             std::stringstream buf;
927             buf << "daemon() failed: " << strerror( errno );
928             logger.putLogError( LOG_CAT_L7VSD_MAINTHREAD, 3, buf.str(), __FILE__, __LINE__ );
929             munlockall();
930             return -1;
931         }
932
933         //set max file open num
934         Parameter    param;
935         error_code    err;
936         int    maxfileno = param.get_int(PARAM_COMP_L7VSD, "maxfileno", err);
937         if( err ){
938             logger.putLogWarn( LOG_CAT_L7VSD_MAINTHREAD, 1, 
939                 "maxfileno parameter not found.", __FILE__, __LINE__ );
940             maxfileno = 1024;
941         }
942         if ( maxfileno < 32 ){
943             logger.putLogWarn( LOG_CAT_L7VSD_MAINTHREAD, 10, 
944                 "invalid parameter for maxfileno.", __FILE__, __LINE__ );
945             maxfileno = 1024;
946         }
947
948         //set process scheduler & priority
949         int    scheduler = SCHED_OTHER;
950         bool   change_scheduler = true;
951         int    int_val = param.get_int(PARAM_COMP_L7VSD, PARAM_SCHED_ALGORITHM, err);
952         if( err ){
953             change_scheduler = false;
954         }
955         if( change_scheduler ){
956             if( (SCHED_FIFO == int_val) || (SCHED_RR == int_val) || (SCHED_OTHER == int_val) || (SCHED_BATCH == int_val) ){
957                 scheduler = int_val;
958             }else{
959                 logger.putLogWarn( LOG_CAT_L7VSD_MAINTHREAD, 5, "invalid parameter for task scheduler algorithm.", __FILE__, __LINE__ );
960             }
961             int    proc_pri  = param.get_int(PARAM_COMP_L7VSD, PARAM_SCHED_PRIORITY, err);
962             if( err ){
963                 logger.putLogWarn( LOG_CAT_L7VSD_MAINTHREAD, 6, "task scheduler priority parameter not found.", __FILE__, __LINE__ );
964                 proc_pri  = sched_get_priority_min( scheduler );
965             }else{
966                 if( (SCHED_FIFO == scheduler) || (SCHED_RR == scheduler) ){
967                     if(proc_pri < 1 || 99 < proc_pri){
968                         logger.putLogWarn( LOG_CAT_L7VSD_MAINTHREAD, 7, "invalid parameter for task scheduler priority.", __FILE__, __LINE__ );
969                         proc_pri  = sched_get_priority_min( scheduler );
970                     }
971                 }
972                 if( (SCHED_OTHER == scheduler) || (SCHED_BATCH == scheduler) ){
973                     if(proc_pri != 0){
974                         logger.putLogWarn( LOG_CAT_L7VSD_MAINTHREAD, 8, "invalid parameter for task scheduler priority.", __FILE__, __LINE__ );
975                         proc_pri  = sched_get_priority_min( scheduler );
976                     }
977                 }
978             }
979     
980             sched_param        scheduler_param;
981             int    ret_val        = sched_getparam( 0, &scheduler_param );
982             scheduler_param.__sched_priority    = proc_pri;
983             ret_val            = sched_setscheduler( 0, scheduler, &scheduler_param );
984             if(ret_val != 0){
985                 logger.putLogWarn( LOG_CAT_L7VSD_MAINTHREAD, 9, "task scheduler setting failed.", __FILE__, __LINE__ );
986             }
987         }
988
989         struct rlimit lim;
990         lim.rlim_cur = maxfileno;
991         lim.rlim_max = maxfileno;
992         int ret;
993         ret = setrlimit( RLIMIT_NOFILE, &lim );
994         if( 0 != ret ){
995             std::stringstream buf;
996             buf << "setrlimit failed:" << errno;
997             logger.putLogWarn( LOG_CAT_L7VSD_MAINTHREAD, 2, buf.str(), __FILE__, __LINE__ );
998         }
999
1000         // signal handler thread start
1001         boost::thread    sigthread( boost::bind( &l7vsd::sig_exit_handler, this ) );
1002         sigthread.detach();
1003
1004         // protoclol module control initialize
1005         protocol_module_control::getInstance().initialize( L7VS_MODULE_PATH );
1006     
1007         // schedule module control initialize
1008         schedule_module_control::getInstance().initialize( L7VS_MODULE_PATH );
1009     
1010         // receiver initialize
1011         receiver.reset( new command_receiver( dispatcher, L7VS_CONFIG_SOCKNAME, *this ) );
1012         if( NULL ==  receiver ){
1013             logger.putLogError( LOG_CAT_L7VSD_MAINTHREAD, 4, "command receiver pointer null.", __FILE__, __LINE__ );
1014             munlockall();
1015             return -1;
1016         }
1017     
1018         // replication initialize
1019         rep.reset( new replication() );
1020         if( NULL ==  rep ){
1021             logger.putLogError( LOG_CAT_L7VSD_MAINTHREAD, 5, "replication pointer null.", __FILE__, __LINE__ );
1022             munlockall();
1023             return -1;
1024         }
1025         if( 0 > rep->initialize() ){
1026             logger.putLogWarn( LOG_CAT_L7VSD_MAINTHREAD, 3, "replication initialize failed.", __FILE__, __LINE__ );
1027         }
1028
1029         // snmp bridge initialize
1030         bridge.reset( new snmpbridge( *this, dispatcher ) );
1031         if( NULL ==  bridge ){
1032             logger.putLogFatal( LOG_CAT_L7VSD_MAINTHREAD, 22, "snmpbridge pointer null.", __FILE__, __LINE__ );
1033             munlockall();
1034             return -1;
1035         }
1036         if( 0 > bridge->initialize() ){
1037             logger.putLogError( LOG_CAT_L7VSD_MAINTHREAD, 6, "snmpbridge initialize failed.", __FILE__, __LINE__ );
1038             munlockall();
1039             return -1;
1040         }
1041
1042 //SNMP is unsupported.
1043 //
1044 //        // snmp trap function set
1045 //        Logger::setSnmpSendtrap( boost::bind( &snmpbridge::send_trap, bridge, _1 ) );
1046 //
1047
1048         // main loop
1049         for(;;){
1050             if( unlikely( exit_requested ) ){
1051                 std::stringstream buf;
1052                 buf << boost::format( "l7vsd signal(%d) received. exitting..." ) % received_sig;
1053                 logger.putLogInfo( LOG_CAT_L7VSD_MAINTHREAD, 1, buf.str(), __FILE__, __LINE__ );
1054                 break;
1055             }
1056             dispatcher.poll();
1057             timespec    wait_val;
1058             wait_val.tv_sec        = 0;
1059             wait_val.tv_nsec    = 10;
1060             nanosleep( &wait_val, NULL );
1061             boost::this_thread::yield();
1062         }
1063     
1064         // snmp trap function unset
1065         Logger::setSnmpSendtrap( NULL );
1066     
1067         // snmp bridge finalize
1068         bridge->finalize();
1069     
1070         // replication finalize
1071         rep->finalize();
1072     
1073         // schedule module control finalize
1074         schedule_module_control::getInstance().finalize();
1075     
1076         // protpcol module control finalize
1077         protocol_module_control::getInstance().finalize();
1078     }
1079     catch( std::exception& e ){
1080         std::stringstream    buf;
1081         buf << "l7vsd run error:" << e.what();
1082         logger.putLogError( LOG_CAT_L7VSD_MAINTHREAD, 7, buf.str(), __FILE__, __LINE__ );
1083         munlockall();
1084         return -1;
1085     }
1086
1087     munlockall();
1088     return 0;
1089 }
1090
1091 //! argument dump for debug
1092 //! @param[in]    argument count
1093 //! @param[in]    argument value
1094 std::string    l7vsd::argument_debug_dump( int argc, char* argv[] ){
1095     std::stringstream buf;
1096     if( !argv ){
1097         buf << "argument=(null)";
1098     }
1099     else{
1100         buf << boost::format( "argument={argc=%d: " ) % argc;
1101         for( int i = 0; i < argc; ++i){
1102             buf << boost::format( "argv[%d]=%s: " ) % i % argv[i];
1103         }
1104         buf << "}";
1105     }
1106     return buf.str();
1107 }
1108
1109 //! command option check
1110 //! @param[in]    argument count
1111 //! @param[in]    argument value
1112 bool    l7vsd::check_options( int argc, char* argv[] ){
1113     Logger    logger( LOG_CAT_L7VSD_MAINTHREAD, 36, "l7vsd::check_options", __FILE__, __LINE__ );
1114
1115     for( int pos = 1; pos < argc; ++pos ){    // check options.
1116         parse_opt_map_type::iterator itr = option_dic.find( argv[pos] );
1117         if( itr != option_dic.end() ){    // find option
1118             if( !itr->second( pos, argc, argv ) ){
1119                 return false;    // option function execute.
1120             }
1121         }
1122         else{    // don't find option function.
1123             std::stringstream buf;
1124             buf << "l7vsd: unknown option: " << argv[ pos ] << "\n";
1125             std::cerr << buf.str();
1126             return false;
1127         }
1128     }
1129     return true;
1130 }
1131
1132 //! command help parse
1133 //! @param[in]    argument count
1134 //! @param[in]    argument value
1135 bool    l7vsd::parse_help(int& pos, int argc, char* argv[] ){
1136     Logger    logger( LOG_CAT_L7VSD_MAINTHREAD, 37, "l7vsd::parse_help", __FILE__, __LINE__ );
1137
1138     help = true;        //help_mode flag on
1139     return true;
1140 }
1141
1142 //! create usage string
1143 //! @return        usage string
1144 std::string    l7vsd::usage(){
1145     Logger    logger( LOG_CAT_L7VSD_MAINTHREAD, 39, "l7vsd::usage", __FILE__, __LINE__ );
1146
1147     std::stringstream    stream;
1148     stream <<
1149     "Usage: l7vsd [-h]\n"
1150     "   -h    --help         print this help messages and exit\n";
1151     return stream.str();
1152 }
1153
1154 //! signal handler function
1155 void    l7vsd::sig_exit_handler(){
1156     Logger    logger( LOG_CAT_L7VSD_MAINTHREAD, 40, "l7vsd::sig_exit_handler", __FILE__, __LINE__ );
1157
1158     sigset_t    sigmask;
1159     sigemptyset( &sigmask );
1160     sigaddset( &sigmask, SIGHUP );
1161     sigaddset( &sigmask, SIGINT );
1162     sigaddset( &sigmask, SIGQUIT );
1163     sigaddset( &sigmask, SIGTERM );
1164     
1165     int    sig;
1166     sigwait( &sigmask, &sig );
1167
1168     received_sig = sig;
1169     exit_requested = 1;
1170 }
1171
1172 };// namespace l7vsd
1173
1174 #ifndef    TEST_CASE
1175
1176 extern "C" int pthread_sigmask_non( int how, const sigset_t* newmask, sigset_t* old_mask ){
1177     return 0;
1178 }
1179 int pthread_sigmask( int, const sigset_t*, sigset_t*) __attribute__((weak,alias("pthread_sigmask_non" )));
1180
1181
1182 //! main function
1183 int main( int argc, char* argv[] ){
1184
1185     int ret = 0;
1186
1187     // signal block
1188     sigset_t    newmask;
1189     sigset_t    oldmask;
1190     sigfillset( &newmask );
1191     ret = sigprocmask( SIG_BLOCK, &newmask, &oldmask );
1192     if( 0 != ret )
1193         return ret;
1194
1195     try{
1196         l7vs::Logger    logger_instance;
1197         l7vs::Parameter    parameter_instance;
1198         logger_instance.loadConf();
1199         l7vs::logger_access_manager::getInstance().access_log_rotate_loadConf();
1200
1201         l7vs::l7vsd vsd;
1202
1203         ret =  vsd.run( argc, argv );
1204     }
1205     catch( ... ){
1206         return -1;
1207     }
1208
1209     // restore sigmask
1210     pthread_sigmask( SIG_SETMASK, &oldmask, NULL );
1211
1212     return ret;
1213
1214 }
1215 #endif    //TEST_CASE