3 * @brief l7vsd main class
5 * L7VSD: Linux Virtual Server for Layer7 Load Balancing
6 * Copyright (C) 2009 NTT COMWARE Corporation.
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.
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.
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
23 **********************************************************************/
30 #include <sys/resource.h>
31 #include <boost/shared_ptr.hpp>
35 #include "error_code.h"
37 #define PARAM_SCHED_ALGORITHM "task_scheduler_algorithm"
38 #define PARAM_SCHED_PRIORITY "task_scheduler_priority"
47 Logger logger( LOG_CAT_L7VSD_MAINTHREAD, 1, "l7vsd::l7vsd", __FILE__, __LINE__ );
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 );
52 starttime = boost::posix_time::second_clock::local_time();
57 Logger logger( LOG_CAT_L7VSD_MAINTHREAD, 2, "l7vsd::~l7vsd", __FILE__, __LINE__ );
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__ );
66 boost::mutex::scoped_lock command_lock( command_mutex );
67 boost::mutex::scoped_lock vslist_lock( vslist_mutex );
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 );
76 // make vselement list
77 for( vslist_type::iterator itr = vslist.begin();
80 out_vslist->push_back( (*itr)->get_element() );
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:";
88 BOOST_FOREACH( virtualservice_element vs_elem, *out_vslist ){
89 debugstr << boost::format( "*out_vslist[%d]=" ) % i;
94 Logger::putLogDebug( LOG_CAT_L7VSD_MAINTHREAD, 4, debugstr.str(), __FILE__, __LINE__ );
96 /*------ DEBUG LOG END ------*/
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__ );
106 boost::mutex::scoped_lock command_lock( command_mutex );
107 boost::mutex::scoped_lock vslist_lock( vslist_mutex );
110 std::string msg("response pointer is null.");
111 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 2, msg, __FILE__, __LINE__);
112 err.setter( true, msg );
116 std::string msg("bridge pointer is null.");
117 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 3, msg, __FILE__, __LINE__);
118 err.setter( true, msg );
122 std::string msg("rep pointer is null.");
123 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 4, msg, __FILE__, __LINE__);
124 err.setter( true, msg );
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;
133 // make vselement list
134 for( vslist_type::iterator itr = vslist.begin();
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();
145 // get_replication_mode
146 response->replication_mode_status = rep->get_status();
148 // get all category log level
149 Logger::getLogLevelAll( response->log_status_list );
151 // get snmp connect status
152 response->snmp_connection_status = bridge->get_connectionstate();
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();
161 response->snmp_log_status_list.push_back( *itr );
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;
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() );
177 response->total_bps = 0ULL;
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;
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__ );
190 /*------ DEBUG LOG END ------*/
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__ );
200 boost::mutex::scoped_lock command_lock( command_mutex );
201 boost::mutex::scoped_lock vslist_lock( vslist_mutex );
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 );
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__ );
217 /*------ DEBUG LOG END ------*/
219 if( vslist.end() == search_vslist( *in_vselement ) ){
220 // replication null check
222 std::string msg("replication pointer is null.");
223 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 6, msg, __FILE__, __LINE__);
225 err.setter( true, msg );
228 // create virtualservice
229 virtualservice_ptr vsptr;
231 vsptr.reset( new virtual_service( *this, *rep, *in_vselement ) );
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 );
240 std::string msg("virtualservice pointer is null.");
241 Logger::putLogError(LOG_CAT_L7VSD_MAINTHREAD, 2, msg, __FILE__, __LINE__);
242 err.setter( true, msg );
247 vsptr->initialize( err );
250 // set virtualservice
251 vsptr->set_virtualservice( *in_vselement, err );
256 // create thread and run
257 vs_threads.create_thread( boost::bind( &virtual_service::run, vsptr ) );
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() );
267 l7vs::error_code finalize_err;
268 vsptr->finalize( finalize_err );
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__ );
274 /*------ DEBUG LOG END ------*/
280 vslist.push_back( vsptr );
282 // when first vs, replication switch to master
283 if( 1U == vslist.size() ){
284 rep->switch_to_master();
288 std::string msg("virtual service already exist.");
289 Logger::putLogWarn(LOG_CAT_L7VSD_VIRTUALSERVICE, 23, msg, __FILE__, __LINE__);
291 err.setter( true, msg );
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__ );
302 boost::mutex::scoped_lock command_lock( command_mutex );
303 boost::mutex::scoped_lock vslist_lock( vslist_mutex );
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 );
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__ );
319 /*------ DEBUG LOG END ------*/
321 vslist_type::iterator vsitr = search_vslist( *in_vselement ,true);
322 if( vslist.end() != vsitr ){
326 (*vsitr)->finalize( err );
328 // when first vs, replication switch to slave
329 if( 0U == vslist.size() ){
330 rep->switch_to_slave();
334 std::string msg("virtual service not found.");
335 Logger::putLogWarn(LOG_CAT_L7VSD_VIRTUALSERVICE, 24, msg, __FILE__, __LINE__);
337 err.setter( true, msg );
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__ );
348 boost::mutex::scoped_lock command_lock( command_mutex );
349 boost::mutex::scoped_lock vslist_lock( vslist_mutex );
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 );
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__ );
365 /*------ DEBUG LOG END ------*/
367 vslist_type::iterator vsitr = search_vslist( *in_vselement );
368 if( vslist.end() != vsitr ){
369 // edit virtualservice
370 (*vsitr)->edit_virtualservice( *in_vselement, err );
374 std::string msg("virtual service not found.");
375 Logger::putLogWarn(LOG_CAT_L7VSD_VIRTUALSERVICE, 25, msg, __FILE__, __LINE__);
377 err.setter( true, msg );
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__ );
388 boost::mutex::scoped_lock command_lock( command_mutex );
389 boost::mutex::scoped_lock vslist_lock( vslist_mutex );
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 );
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__ );
405 /*------ DEBUG LOG END ------*/
407 vslist_type::iterator vsitr = search_vslist( *in_vselement );
408 if( vslist.end() != vsitr ){
410 (*vsitr)->add_realserver( *in_vselement, err );
414 std::string msg("virtual service not found.");
415 Logger::putLogWarn(LOG_CAT_L7VSD_VIRTUALSERVICE, 26, msg, __FILE__, __LINE__);
417 err.setter( true, msg );
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__ );
428 boost::mutex::scoped_lock command_lock( command_mutex );
429 boost::mutex::scoped_lock vslist_lock( vslist_mutex );
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 );
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__ );
445 /*------ DEBUG LOG END ------*/
447 vslist_type::iterator vsitr = search_vslist( *in_vselement );
448 if( vslist.end() != vsitr ){
450 (*vsitr)->del_realserver( *in_vselement, err );
454 std::string msg("virtual service not found.");
455 Logger::putLogWarn(LOG_CAT_L7VSD_VIRTUALSERVICE, 27, msg, __FILE__, __LINE__);
457 err.setter( true, msg );
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__ );
468 boost::mutex::scoped_lock command_lock( command_mutex );
469 boost::mutex::scoped_lock vslist_lock( vslist_mutex );
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 );
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__ );
485 /*------ DEBUG LOG END ------*/
487 vslist_type::iterator vsitr = search_vslist( *in_vselement );
488 if( vslist.end() != vsitr ){
490 (*vsitr)->edit_realserver( *in_vselement, err );
494 std::string msg("virtual service not found.");
495 Logger::putLogWarn(LOG_CAT_L7VSD_VIRTUALSERVICE, 28, msg, __FILE__, __LINE__);
497 err.setter( true, msg );
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__ );
507 boost::mutex::scoped_lock command_lock( command_mutex );
508 boost::mutex::scoped_lock vslist_lock( vslist_mutex );
510 // all virtualservice stop and finalize
512 vslist_type::iterator itr = vslist.begin();
513 if(vslist.end() == itr){
520 (*itr)->finalize( err );
524 // join virtualservice threads
525 vs_threads.join_all();
527 // replication switch to slave
528 rep->switch_to_slave();
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__ );
537 boost::mutex::scoped_lock command_lock( command_mutex );
538 boost::mutex::scoped_lock vslist_lock( vslist_mutex );
541 std::string msg("cmd pointer is null.");
542 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 12, msg, __FILE__, __LINE__);
543 err.setter( true, msg );
547 std::string msg("rep pointer is null.");
548 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 13, msg, __FILE__, __LINE__);
549 err.setter( true, msg );
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__ );
560 /*------ DEBUG LOG END ------*/
563 case l7vsadm_request::REP_START:
566 case l7vsadm_request::REP_STOP:
569 case l7vsadm_request::REP_FORCE:
570 rep->force_replicate();
572 case l7vsadm_request::REP_DUMP:
576 std::string msg("invalid replication command.");
577 Logger::putLogError(LOG_CAT_L7VSD_REPLICATION, 38, msg, __FILE__, __LINE__);
578 err.setter( true, msg );
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__ );
590 boost::mutex::scoped_lock command_lock( command_mutex );
591 boost::mutex::scoped_lock vslist_lock( vslist_mutex );
594 std::string msg("cat pointer is null.");
595 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 14, msg, __FILE__, __LINE__);
596 err.setter( true, msg );
600 std::string msg("level pointer is null.");
601 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 15, msg, __FILE__, __LINE__);
602 err.setter( true, msg );
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__ );
613 /*------ DEBUG LOG END ------*/
615 if( LOG_CAT_END == *cat ){
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 );
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 );
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__ );
641 boost::mutex::scoped_lock command_lock( command_mutex );
642 boost::mutex::scoped_lock vslist_lock( vslist_mutex );
645 std::string msg("cat pointer is null.");
646 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 16, msg, __FILE__, __LINE__);
647 err.setter( true, msg );
651 std::string msg("level pointer is null.");
652 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 17, msg, __FILE__, __LINE__);
653 err.setter( true, msg );
657 std::string msg("bridge pointer is null.");
658 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 18, msg, __FILE__, __LINE__);
659 err.setter( true, msg );
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__ );
670 /*------ DEBUG LOG END ------*/
672 if( LOG_CAT_END == *cat ){
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 );
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 );
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__ );
697 boost::mutex::scoped_lock command_lock( command_mutex );
698 boost::mutex::scoped_lock vslist_lock( vslist_mutex );
701 std::string msg("comp pointer is null.");
702 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 19, msg, __FILE__, __LINE__);
703 err.setter( true, msg );
707 std::string msg("rep pointer is null.");
708 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 20, msg, __FILE__, __LINE__);
709 err.setter( true, msg );
713 std::string msg("bridge pointer is null.");
714 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 21, msg, __FILE__, __LINE__);
715 err.setter( true, msg );
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__ );
726 /*------ DEBUG LOG END ------*/
729 Logger logger_instance;
732 case PARAM_COMP_REPLICATION:
733 if( param.read_file( *comp )){
736 std::string msg("parameter reload failed.");
737 Logger::putLogError(LOG_CAT_L7VSD_PARAMETER, 7, msg, __FILE__, __LINE__);
738 err.setter( true, msg );
743 case PARAM_COMP_LOGGER:
744 if( param.read_file( *comp )){
747 logger_instance.loadConf();
752 std::string msg("parameter reload failed.");
753 Logger::putLogError(LOG_CAT_L7VSD_PARAMETER, 7, msg, __FILE__, __LINE__);
754 err.setter( true, msg );
759 case PARAM_COMP_SNMPAGENT:
760 if( param.read_file( *comp )){
761 bridge->reload_config();
763 std::string msg("parameter reload failed.");
764 Logger::putLogError(LOG_CAT_L7VSD_PARAMETER, 7, msg, __FILE__, __LINE__);
765 err.setter( true, msg );
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 );
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 );
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 );
794 logger_instance.loadConf();
797 bridge->reload_config();
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 );
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__ );
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__ );
825 /*------ DEBUG LOG END ------*/
827 for( vslist_type::iterator itr = vslist.begin();
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){
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){
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__ );
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__ );
870 /*------ DEBUG LOG END ------*/
872 vslist_type::iterator vsitr = search_vslist( in_vselement );
873 if( vslist.end() != vsitr ){
874 // remove from vslist
875 vslist.remove( *vsitr );
878 //! virtualservice_list getter
880 l7vsd::vslist_type& l7vsd::get_virtualservice_list(){
881 Logger logger( LOG_CAT_L7VSD_MAINTHREAD, 32, "l7vsd::get_virtualservice_list", __FILE__, __LINE__ );
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__ );
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__ );
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__ );
906 /*------ DEBUG LOG END ------*/
908 mlockall(MCL_FUTURE);
912 if( !check_options( argc, argv ) ){
913 std::cerr << usage();
920 std::cout << usage();
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__ );
933 //set max file open num
936 int maxfileno = param.get_int(PARAM_COMP_L7VSD, "maxfileno", err);
938 logger.putLogWarn( LOG_CAT_L7VSD_MAINTHREAD, 1,
939 "maxfileno parameter not found.", __FILE__, __LINE__ );
942 if ( maxfileno < 32 ){
943 logger.putLogWarn( LOG_CAT_L7VSD_MAINTHREAD, 10,
944 "invalid parameter for maxfileno.", __FILE__, __LINE__ );
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);
953 change_scheduler = false;
955 if( change_scheduler ){
956 if( (SCHED_FIFO == int_val) || (SCHED_RR == int_val) || (SCHED_OTHER == int_val) || (SCHED_BATCH == int_val) ){
959 logger.putLogWarn( LOG_CAT_L7VSD_MAINTHREAD, 5, "invalid parameter for task scheduler algorithm.", __FILE__, __LINE__ );
961 int proc_pri = param.get_int(PARAM_COMP_L7VSD, PARAM_SCHED_PRIORITY, 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 );
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 );
972 if( (SCHED_OTHER == scheduler) || (SCHED_BATCH == scheduler) ){
974 logger.putLogWarn( LOG_CAT_L7VSD_MAINTHREAD, 8, "invalid parameter for task scheduler priority.", __FILE__, __LINE__ );
975 proc_pri = sched_get_priority_min( scheduler );
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 );
985 logger.putLogWarn( LOG_CAT_L7VSD_MAINTHREAD, 9, "task scheduler setting failed.", __FILE__, __LINE__ );
990 lim.rlim_cur = maxfileno;
991 lim.rlim_max = maxfileno;
993 ret = setrlimit( RLIMIT_NOFILE, &lim );
995 std::stringstream buf;
996 buf << "setrlimit failed:" << errno;
997 logger.putLogWarn( LOG_CAT_L7VSD_MAINTHREAD, 2, buf.str(), __FILE__, __LINE__ );
1000 // signal handler thread start
1001 boost::thread sigthread( boost::bind( &l7vsd::sig_exit_handler, this ) );
1004 // protoclol module control initialize
1005 protocol_module_control::getInstance().initialize( L7VS_MODULE_PATH );
1007 // schedule module control initialize
1008 schedule_module_control::getInstance().initialize( L7VS_MODULE_PATH );
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__ );
1018 // replication initialize
1019 rep.reset( new replication() );
1021 logger.putLogError( LOG_CAT_L7VSD_MAINTHREAD, 5, "replication pointer null.", __FILE__, __LINE__ );
1025 if( 0 > rep->initialize() ){
1026 logger.putLogWarn( LOG_CAT_L7VSD_MAINTHREAD, 3, "replication initialize failed.", __FILE__, __LINE__ );
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__ );
1036 if( 0 > bridge->initialize() ){
1037 logger.putLogError( LOG_CAT_L7VSD_MAINTHREAD, 6, "snmpbridge initialize failed.", __FILE__, __LINE__ );
1042 //SNMP is unsupported.
1044 // // snmp trap function set
1045 // Logger::setSnmpSendtrap( boost::bind( &snmpbridge::send_trap, bridge, _1 ) );
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__ );
1058 wait_val.tv_sec = 0;
1059 wait_val.tv_nsec = 10;
1060 nanosleep( &wait_val, NULL );
1061 boost::this_thread::yield();
1064 // snmp trap function unset
1065 Logger::setSnmpSendtrap( NULL );
1067 // snmp bridge finalize
1070 // replication finalize
1073 // schedule module control finalize
1074 schedule_module_control::getInstance().finalize();
1076 // protpcol module control finalize
1077 protocol_module_control::getInstance().finalize();
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__ );
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;
1097 buf << "argument=(null)";
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];
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__ );
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.
1122 else{ // don't find option function.
1123 std::stringstream buf;
1124 buf << "l7vsd: unknown option: " << argv[ pos ] << "\n";
1125 std::cerr << buf.str();
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__ );
1138 help = true; //help_mode flag on
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__ );
1147 std::stringstream stream;
1149 "Usage: l7vsd [-h]\n"
1150 " -h --help print this help messages and exit\n";
1151 return stream.str();
1154 //! signal handler function
1155 void l7vsd::sig_exit_handler(){
1156 Logger logger( LOG_CAT_L7VSD_MAINTHREAD, 40, "l7vsd::sig_exit_handler", __FILE__, __LINE__ );
1159 sigemptyset( &sigmask );
1160 sigaddset( &sigmask, SIGHUP );
1161 sigaddset( &sigmask, SIGINT );
1162 sigaddset( &sigmask, SIGQUIT );
1163 sigaddset( &sigmask, SIGTERM );
1166 sigwait( &sigmask, &sig );
1172 };// namespace l7vsd
1176 extern "C" int pthread_sigmask_non( int how, const sigset_t* newmask, sigset_t* old_mask ){
1179 int pthread_sigmask( int, const sigset_t*, sigset_t*) __attribute__((weak,alias("pthread_sigmask_non" )));
1183 int main( int argc, char* argv[] ){
1190 sigfillset( &newmask );
1191 ret = sigprocmask( SIG_BLOCK, &newmask, &oldmask );
1196 l7vs::Logger logger_instance;
1197 l7vs::Parameter parameter_instance;
1198 logger_instance.loadConf();
1199 l7vs::logger_access_manager::getInstance().access_log_rotate_loadConf();
1203 ret = vsd.run( argc, argv );
1210 pthread_sigmask( SIG_SETMASK, &oldmask, NULL );