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"
36 #include "snmpagent.h"
38 #define PARAM_SCHED_ALGORITHM "task_scheduler_algorithm"
39 #define PARAM_SCHED_PRIORITY "task_scheduler_priority"
40 #define TRAP_TIME_STRING_MAX_SIZE (20)
52 Logger logger(LOG_CAT_L7VSD_MAINTHREAD, 1, "l7vsd::l7vsd", __FILE__, __LINE__);
54 option_dic["-h"] = boost::bind(&l7vsd::parse_help, this, _1, _2, _3);
55 option_dic["--help"] = boost::bind(&l7vsd::parse_help, this, _1, _2, _3);
56 option_dic["-d"] = boost::bind(&l7vsd::parse_debug, this, _1, _2, _3);
57 option_dic["--debug"] = boost::bind(&l7vsd::parse_debug, this, _1, _2, _3);
59 starttime = boost::posix_time::second_clock::local_time();
65 Logger logger(LOG_CAT_L7VSD_MAINTHREAD, 2, "l7vsd::~l7vsd", __FILE__, __LINE__);
68 //! virtual_service list command
69 //! @param[out] array of vs_element
70 //! @param[out] error_code
71 void l7vsd::list_virtual_service(vselist_type *out_vslist, error_code &err)
73 Logger logger(LOG_CAT_L7VSD_MAINTHREAD, 3, "l7vsd::list_virtual_service", __FILE__, __LINE__);
75 boost::mutex::scoped_lock command_lock(command_mutex);
76 boost::mutex::scoped_lock vslist_lock(vslist_mutex);
79 std::string msg("out_vslist pointer is null.");
80 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 1, msg, __FILE__, __LINE__);
81 err.setter(true, msg);
85 // make vselement list
86 for (vslist_type::iterator itr = vslist.begin();
89 out_vslist->push_back((*itr)->get_element());
92 /*-------- DEBUG LOG --------*/
93 if (LOG_LV_DEBUG == Logger::getLogLevel(LOG_CAT_L7VSD_MAINTHREAD)) {
94 std::stringstream debugstr;
95 debugstr << "l7vsd::list_virtual_service return value:";
97 BOOST_FOREACH(virtualservice_element vs_elem, *out_vslist) {
98 debugstr << boost::format("*out_vslist[%d]=") % i;
103 Logger::putLogDebug(LOG_CAT_L7VSD_MAINTHREAD, 4, debugstr.str(), __FILE__, __LINE__);
105 /*------ DEBUG LOG END ------*/
109 //! virtual_service list verbose command
110 //! @param[out] array of vs_element
111 //! @param[out] error_code
112 void l7vsd::list_virtual_service_verbose(l7vsd_response *response, error_code &err)
114 Logger logger(LOG_CAT_L7VSD_MAINTHREAD, 5, "l7vsd::list_virtual_service_verbose", __FILE__, __LINE__);
116 boost::mutex::scoped_lock command_lock(command_mutex);
117 boost::mutex::scoped_lock vslist_lock(vslist_mutex);
120 std::string msg("response pointer is null.");
121 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 2, msg, __FILE__, __LINE__);
122 err.setter(true, msg);
127 std::string msg("rep pointer is null.");
128 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 4, msg, __FILE__, __LINE__);
129 err.setter(true, msg);
133 unsigned long long total_client_recv_byte = 0ULL;
134 unsigned long long total_client_send_byte = 0ULL;
135 unsigned long long total_realserver_recv_byte = 0ULL;
136 unsigned long long total_realserver_send_byte = 0ULL;
138 // make vselement list
139 for (vslist_type::iterator itr = vslist.begin();
142 response->virtualservice_status_list.push_back((*itr)->get_element());
143 // calc send recv bytes
144 total_client_recv_byte += (*itr)->get_up_recv_size();
145 total_client_send_byte += (*itr)->get_down_send_size();
146 total_realserver_recv_byte += (*itr)->get_down_recv_size();
147 total_realserver_send_byte += (*itr)->get_up_send_size();
150 // get_replication_mode
151 response->replication_mode_status = rep->get_status();
153 // get all category log level
154 Logger::getLogLevelAll(response->log_status_list);
157 response->snmpinfo = snmpagent::get_snmp_info();
160 unsigned long long total_bytes =
161 total_client_recv_byte +
162 total_client_send_byte +
163 total_realserver_recv_byte +
164 total_realserver_send_byte;
166 boost::posix_time::ptime now =
167 boost::posix_time::second_clock::local_time();
168 boost::posix_time::time_duration dur = (now - starttime);
169 if (0ULL != dur.total_seconds())
170 response->total_bps = (total_bytes / dur.total_seconds());
172 response->total_bps = 0ULL;
174 response->total_client_recv_byte = total_client_recv_byte;
175 response->total_client_send_byte = total_client_send_byte;
176 response->total_realserver_recv_byte = total_realserver_recv_byte;
177 response->total_realserver_send_byte = total_realserver_send_byte;
179 /*-------- DEBUG LOG --------*/
180 if (LOG_LV_DEBUG == Logger::getLogLevel(LOG_CAT_L7VSD_MAINTHREAD)) {
181 std::stringstream debugstr;
182 debugstr << boost::format("l7vsd::list_virtual_service_verbose return value:%s") % *response;
183 Logger::putLogDebug(LOG_CAT_L7VSD_MAINTHREAD, 6, debugstr.str(), __FILE__, __LINE__);
185 /*------ DEBUG LOG END ------*/
189 //! virtual_service add command
190 //! @param[in] vs_element
191 //! @param[out] error_code
192 void l7vsd::add_virtual_service(const virtualservice_element *in_vselement, error_code &err)
194 Logger logger(LOG_CAT_L7VSD_MAINTHREAD, 7, "l7vsd::add_virtual_service", __FILE__, __LINE__);
196 boost::mutex::scoped_lock command_lock(command_mutex);
197 boost::mutex::scoped_lock vslist_lock(vslist_mutex);
200 std::string msg("in_vselement pointer is null.");
201 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 5, msg, __FILE__, __LINE__);
202 err.setter(true, msg);
206 /*-------- DEBUG LOG --------*/
207 if (LOG_LV_DEBUG == Logger::getLogLevel(LOG_CAT_L7VSD_MAINTHREAD)) {
208 std::stringstream debugstr;
209 debugstr << "l7vsd::add_virtual_service arguments:";
210 debugstr << boost::format("*in_vselement=%s") % *in_vselement;
211 Logger::putLogDebug(LOG_CAT_L7VSD_MAINTHREAD, 8, debugstr.str(), __FILE__, __LINE__);
213 /*------ DEBUG LOG END ------*/
215 if (vslist.end() == search_vslist(*in_vselement)) {
216 // replication null check
218 std::string msg("replication pointer is null.");
219 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 6, msg, __FILE__, __LINE__);
221 err.setter(true, msg);
224 // create virtualservice
225 virtualservice_ptr vsptr;
227 vsptr.reset(new virtual_service(*this, *rep, *in_vselement));
228 } catch (std::bad_alloc &) {
229 std::string msg("virtualservice create failed.");
230 Logger::putLogError(LOG_CAT_L7VSD_MAINTHREAD, 1, msg, __FILE__, __LINE__);
231 err.setter(true, msg);
235 std::string msg("virtualservice pointer is null.");
236 Logger::putLogError(LOG_CAT_L7VSD_MAINTHREAD, 2, msg, __FILE__, __LINE__);
237 err.setter(true, msg);
242 vsptr->initialize(err);
245 // set virtualservice
246 vsptr->set_virtualservice(*in_vselement, err);
251 // create thread and run
252 vs_threads.create_thread(boost::bind(&virtual_service::run, vsptr));
255 std::stringstream buf;
256 buf << "virtualservice thread initialize failed.";
257 Logger::putLogError(LOG_CAT_L7VSD_MAINTHREAD, 8, buf.str(), __FILE__, __LINE__);
258 err.setter(true, buf.str());
261 l7vs::error_code finalize_err;
262 vsptr->finalize(finalize_err);
264 /*-------- DEBUG LOG --------*/
265 if (LOG_LV_DEBUG == Logger::getLogLevel(LOG_CAT_L7VSD_MAINTHREAD)) {
266 Logger::putLogDebug(LOG_CAT_L7VSD_MAINTHREAD, 41, "out l7vsd::add_virtual_service", __FILE__, __LINE__);
268 /*------ DEBUG LOG END ------*/
274 vslist.push_back(vsptr);
276 //create trap message
277 trapmessage trap_msg;
278 trap_msg.type = trapmessage::VIRTUALSERVICE_ADD;
280 std::ostringstream oss;
281 oss << "TRAP00020001,A virtual service was added.vs:";
282 if (in_vselement->udpmode) {
283 if (in_vselement->udp_recv_endpoint.address().is_v6()) {
284 oss << "[" << in_vselement->udp_recv_endpoint.address().to_string() << "]:" << in_vselement->udp_recv_endpoint.port();
286 oss << in_vselement->udp_recv_endpoint.address().to_string() << ":" << in_vselement->udp_recv_endpoint.port();
290 if (in_vselement->tcp_accept_endpoint.address().is_v6()) {
291 oss << "[" << in_vselement->tcp_accept_endpoint.address().to_string() << "]:" << in_vselement->tcp_accept_endpoint.port();
293 oss << in_vselement->tcp_accept_endpoint.address().to_string() << ":" << in_vselement->tcp_accept_endpoint.port();
297 trap_msg.message = oss.str();
301 //push the trap message
302 snmpagent::push_trapmessage(trap_msg, err_code);
305 std::string msg("Push trap message failed.");
306 Logger::putLogError(LOG_CAT_L7VSD_VIRTUALSERVICE, 124, msg, __FILE__, __LINE__);
309 // when first vs, replication switch to master
310 if (1U == vslist.size()) {
311 rep->switch_to_master();
314 std::string msg("virtual service already exist.");
315 Logger::putLogWarn(LOG_CAT_L7VSD_VIRTUALSERVICE, 23, msg, __FILE__, __LINE__);
317 err.setter(true, msg);
322 //! virtual_service del command
323 //! @param[in] vs_element
324 //! @param[out] error_code
325 void l7vsd::del_virtual_service(const virtualservice_element *in_vselement, error_code &err)
327 Logger logger(LOG_CAT_L7VSD_MAINTHREAD, 9, "l7vsd::del_virtual_service", __FILE__, __LINE__);
329 boost::mutex::scoped_lock command_lock(command_mutex);
330 boost::mutex::scoped_lock vslist_lock(vslist_mutex);
333 std::string msg("in_vselement pointer is null.");
334 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 7, msg, __FILE__, __LINE__);
335 err.setter(true, msg);
339 /*-------- DEBUG LOG --------*/
340 if (LOG_LV_DEBUG == Logger::getLogLevel(LOG_CAT_L7VSD_MAINTHREAD)) {
341 std::stringstream debugstr;
342 debugstr << "l7vsd::del_virtual_service arguments:";
343 debugstr << boost::format("*in_vselement=%s") % *in_vselement;
344 Logger::putLogDebug(LOG_CAT_L7VSD_MAINTHREAD, 10, debugstr.str(), __FILE__, __LINE__);
346 /*------ DEBUG LOG END ------*/
348 vslist_type::iterator vsitr = search_vslist(*in_vselement , true);
349 if (vslist.end() != vsitr) {
353 (*vsitr)->finalize(err);
355 //create trap message
356 trapmessage trap_msg;
357 trap_msg.type = trapmessage::VIRTUALSERVICE_REMOVE;
359 std::ostringstream oss;
360 oss << "TRAP00020003,A virtual service was eliminated.vs:";
361 if (in_vselement->udpmode) {
362 if (in_vselement->udp_recv_endpoint.address().is_v6()) {
363 oss << "[" << in_vselement->udp_recv_endpoint.address().to_string() << "]:" << in_vselement->udp_recv_endpoint.port();
365 oss << in_vselement->udp_recv_endpoint.address().to_string() << ":" << in_vselement->udp_recv_endpoint.port();
369 if (in_vselement->tcp_accept_endpoint.address().is_v6()) {
370 oss << "[" << in_vselement->tcp_accept_endpoint.address().to_string() << "]:" << in_vselement->tcp_accept_endpoint.port();
372 oss << in_vselement->tcp_accept_endpoint.address().to_string() << ":" << in_vselement->tcp_accept_endpoint.port();
376 trap_msg.message = oss.str();
380 //push the trap message
381 snmpagent::push_trapmessage(trap_msg, err_code);
384 std::string msg("Push trap message failed.");
385 Logger::putLogError(LOG_CAT_L7VSD_VIRTUALSERVICE, 125, msg, __FILE__, __LINE__);
388 // when first vs, replication switch to slave
389 if (0U == vslist.size()) {
390 rep->switch_to_slave();
393 std::string msg("virtual service not found.");
394 Logger::putLogWarn(LOG_CAT_L7VSD_VIRTUALSERVICE, 24, msg, __FILE__, __LINE__);
395 err.setter(true, msg);
400 //! virtual_service edit command
401 //! @param[in] vs_element
402 //! @param[out] error_code
403 void l7vsd::edit_virtual_service(const virtualservice_element *in_vselement, error_code &err)
405 Logger logger(LOG_CAT_L7VSD_MAINTHREAD, 11, "l7vsd::edit_virtual_service", __FILE__, __LINE__);
407 boost::mutex::scoped_lock command_lock(command_mutex);
408 boost::mutex::scoped_lock vslist_lock(vslist_mutex);
411 std::string msg("in_vselement pointer is null.");
412 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 8, msg, __FILE__, __LINE__);
413 err.setter(true, msg);
417 /*-------- DEBUG LOG --------*/
418 if (LOG_LV_DEBUG == Logger::getLogLevel(LOG_CAT_L7VSD_MAINTHREAD)) {
419 std::stringstream debugstr;
420 debugstr << "l7vsd::edit_virtual_service arguments:";
421 debugstr << boost::format("*in_vselement=%s") % *in_vselement;
422 Logger::putLogDebug(LOG_CAT_L7VSD_MAINTHREAD, 12, debugstr.str(), __FILE__, __LINE__);
424 /*------ DEBUG LOG END ------*/
426 vslist_type::iterator vsitr = search_vslist(*in_vselement);
427 if (vslist.end() != vsitr) {
428 // edit virtualservice
429 (*vsitr)->edit_virtualservice(*in_vselement, err);
432 //create trap message
433 trapmessage trap_msg;
434 trap_msg.type = trapmessage::VIRTUALSERVICE_CHANGE;
436 std::ostringstream oss;
437 oss << "TRAP00020002,The virtual service was changed.vs:";
438 if (in_vselement->udpmode) {
439 if (in_vselement->udp_recv_endpoint.address().is_v6()) {
440 oss << "[" << in_vselement->udp_recv_endpoint.address().to_string() << "]:" << in_vselement->udp_recv_endpoint.port();
442 oss << in_vselement->udp_recv_endpoint.address().to_string() << ":" << in_vselement->udp_recv_endpoint.port();
446 if (in_vselement->tcp_accept_endpoint.address().is_v6()) {
447 oss << "[" << in_vselement->tcp_accept_endpoint.address().to_string() << "]:" << in_vselement->tcp_accept_endpoint.port();
449 oss << in_vselement->tcp_accept_endpoint.address().to_string() << ":" << in_vselement->tcp_accept_endpoint.port();
453 trap_msg.message = oss.str();
457 //push the trap message
458 snmpagent::push_trapmessage(trap_msg, err_code);
461 std::string msg("Push trap message failed.");
462 Logger::putLogError(LOG_CAT_L7VSD_VIRTUALSERVICE, 126, msg, __FILE__, __LINE__);
466 std::string msg("virtual service not found.");
467 Logger::putLogWarn(LOG_CAT_L7VSD_VIRTUALSERVICE, 25, msg, __FILE__, __LINE__);
469 err.setter(true, msg);
474 //! real_server add command
475 //! @param[in] vs_element
476 //! @param[out] error_code
477 void l7vsd::add_real_server(const virtualservice_element *in_vselement, error_code &err)
479 Logger logger(LOG_CAT_L7VSD_MAINTHREAD, 13, "l7vsd::add_real_server", __FILE__, __LINE__);
481 boost::mutex::scoped_lock command_lock(command_mutex);
482 boost::mutex::scoped_lock vslist_lock(vslist_mutex);
485 std::string msg("in_vselement pointer is null.");
486 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 9, msg, __FILE__, __LINE__);
487 err.setter(true, msg);
491 /*-------- DEBUG LOG --------*/
492 if (LOG_LV_DEBUG == Logger::getLogLevel(LOG_CAT_L7VSD_MAINTHREAD)) {
493 std::stringstream debugstr;
494 debugstr << "l7vsd::add_real_server arguments:";
495 debugstr << boost::format("*in_vselement=%s") % *in_vselement;
496 Logger::putLogDebug(LOG_CAT_L7VSD_MAINTHREAD, 14, debugstr.str(), __FILE__, __LINE__);
498 /*------ DEBUG LOG END ------*/
500 vslist_type::iterator vsitr = search_vslist(*in_vselement);
501 if (vslist.end() != vsitr) {
503 (*vsitr)->add_realserver(*in_vselement, err);
506 //create trap message
507 trapmessage trap_msg;
508 trap_msg.type = trapmessage::REALSERVER_ADD;
510 std::ostringstream oss;
511 oss << "TRAP00020004,A real server was added.vs:";
512 //virtualservice information
513 if (in_vselement->udpmode) {
514 if (in_vselement->udp_recv_endpoint.address().is_v6()) {
515 oss << "[" << in_vselement->udp_recv_endpoint.address().to_string() << "]:" << in_vselement->udp_recv_endpoint.port();
517 oss << in_vselement->udp_recv_endpoint.address().to_string() << ":" << in_vselement->udp_recv_endpoint.port();
521 if (in_vselement->tcp_accept_endpoint.address().is_v6()) {
522 oss << "[" << in_vselement->tcp_accept_endpoint.address().to_string() << "]:" << in_vselement->tcp_accept_endpoint.port();
524 oss << in_vselement->tcp_accept_endpoint.address().to_string() << ":" << in_vselement->tcp_accept_endpoint.port();
528 //realserver information
529 BOOST_FOREACH(realserver_element elem, in_vselement->realserver_vector) {
530 if (in_vselement->udpmode) {
531 if (elem.udp_endpoint.address().is_v6()) {
532 oss << ",rs:[" << elem.udp_endpoint.address().to_string() << "]:" << elem.udp_endpoint.port();
534 oss << ",rs:" << elem.udp_endpoint.address().to_string() << ":" << elem.udp_endpoint.port();
538 if (elem.tcp_endpoint.address().is_v6()) {
539 oss << ",rs:[" << elem.tcp_endpoint.address().to_string() << "]:" << elem.tcp_endpoint.port();
541 oss << ",rs:" << elem.tcp_endpoint.address().to_string() << ":" << elem.tcp_endpoint.port();
546 trap_msg.message = oss.str();
550 //push the trap message
551 snmpagent::push_trapmessage(trap_msg, err_code);
554 std::string msg("Push trap message failed.");
555 Logger::putLogError(LOG_CAT_L7VSD_VIRTUALSERVICE, 127, msg, __FILE__, __LINE__);
560 std::string msg("virtual service not found.");
561 Logger::putLogWarn(LOG_CAT_L7VSD_VIRTUALSERVICE, 26, msg, __FILE__, __LINE__);
563 err.setter(true, msg);
568 //! real_server del command
569 //! @param[in] vs_element
570 //! @param[out] error_code
571 void l7vsd::del_real_server(const virtualservice_element *in_vselement, error_code &err)
573 Logger logger(LOG_CAT_L7VSD_MAINTHREAD, 15, "l7vsd::del_real_server", __FILE__, __LINE__);
575 boost::mutex::scoped_lock command_lock(command_mutex);
576 boost::mutex::scoped_lock vslist_lock(vslist_mutex);
579 std::string msg("in_vselement pointer is null.");
580 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 10, msg, __FILE__, __LINE__);
581 err.setter(true, msg);
585 /*-------- DEBUG LOG --------*/
586 if (LOG_LV_DEBUG == Logger::getLogLevel(LOG_CAT_L7VSD_MAINTHREAD)) {
587 std::stringstream debugstr;
588 debugstr << "l7vsd::del_real_server arguments:";
589 debugstr << boost::format("*in_vselement=%s") % *in_vselement;
590 Logger::putLogDebug(LOG_CAT_L7VSD_MAINTHREAD, 16, debugstr.str(), __FILE__, __LINE__);
592 /*------ DEBUG LOG END ------*/
594 vslist_type::iterator vsitr = search_vslist(*in_vselement);
595 if (vslist.end() != vsitr) {
597 (*vsitr)->del_realserver(*in_vselement, err);
600 //create trap message
601 trapmessage trap_msg;
602 trap_msg.type = trapmessage::REALSERVER_REMOVE;
604 std::ostringstream oss;
605 oss << "TRAP00020006,A real server was eliminated.vs:";
606 //virtualservice information
607 if (in_vselement->udpmode) {
608 if (in_vselement->udp_recv_endpoint.address().is_v6()) {
609 oss << "[" << in_vselement->udp_recv_endpoint.address().to_string() << "]:" << in_vselement->udp_recv_endpoint.port();
611 oss << in_vselement->udp_recv_endpoint.address().to_string() << ":" << in_vselement->udp_recv_endpoint.port();
615 if (in_vselement->tcp_accept_endpoint.address().is_v6()) {
616 oss << "[" << in_vselement->tcp_accept_endpoint.address().to_string() << "]:" << in_vselement->tcp_accept_endpoint.port();
618 oss << in_vselement->tcp_accept_endpoint.address().to_string() << ":" << in_vselement->tcp_accept_endpoint.port();
622 //realserver information
623 BOOST_FOREACH(realserver_element elem, in_vselement->realserver_vector) {
624 if (in_vselement->udpmode) {
625 if (elem.udp_endpoint.address().is_v6()) {
626 oss << ",rs:[" << elem.udp_endpoint.address().to_string() << "]:" << elem.udp_endpoint.port();
628 oss << ",rs:" << elem.udp_endpoint.address().to_string() << ":" << elem.udp_endpoint.port();
632 if (elem.tcp_endpoint.address().is_v6()) {
633 oss << ",rs:[" << elem.tcp_endpoint.address().to_string() << "]:" << elem.tcp_endpoint.port();
635 oss << ",rs:" << elem.tcp_endpoint.address().to_string() << ":" << elem.tcp_endpoint.port();
640 trap_msg.message = oss.str();
644 //push the trap message
645 snmpagent::push_trapmessage(trap_msg, err_code);
648 std::string msg("Push trap message failed.");
649 Logger::putLogError(LOG_CAT_L7VSD_VIRTUALSERVICE, 128, msg, __FILE__, __LINE__);
652 std::string msg("virtual service not found.");
653 Logger::putLogWarn(LOG_CAT_L7VSD_VIRTUALSERVICE, 27, msg, __FILE__, __LINE__);
655 err.setter(true, msg);
660 //! real_server edit command
661 //! @param[in] vs_element
662 //! @param[out] error_code
663 void l7vsd::edit_real_server(const virtualservice_element *in_vselement, error_code &err)
665 Logger logger(LOG_CAT_L7VSD_MAINTHREAD, 17, "l7vsd::edit_real_server", __FILE__, __LINE__);
667 boost::mutex::scoped_lock command_lock(command_mutex);
668 boost::mutex::scoped_lock vslist_lock(vslist_mutex);
671 std::string msg("in_vselement pointer is null.");
672 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 11, msg, __FILE__, __LINE__);
673 err.setter(true, msg);
677 /*-------- DEBUG LOG --------*/
678 if (LOG_LV_DEBUG == Logger::getLogLevel(LOG_CAT_L7VSD_MAINTHREAD)) {
679 std::stringstream debugstr;
680 debugstr << "l7vsd::edit_real_server arguments:";
681 debugstr << boost::format("*in_vselement=%s") % *in_vselement;
682 Logger::putLogDebug(LOG_CAT_L7VSD_MAINTHREAD, 18, debugstr.str(), __FILE__, __LINE__);
684 /*------ DEBUG LOG END ------*/
686 vslist_type::iterator vsitr = search_vslist(*in_vselement);
687 if (vslist.end() != vsitr) {
689 (*vsitr)->edit_realserver(*in_vselement, err);
692 //create trap message
693 trapmessage trap_msg;
694 trap_msg.type = trapmessage::REALSERVER_CHANGE;
696 std::ostringstream oss;
697 oss << "TRAP00020005,The real server was changed.vs:";
698 //virtualservice information
699 if (in_vselement->udpmode) {
700 if (in_vselement->udp_recv_endpoint.address().is_v6()) {
701 oss << "[" << in_vselement->udp_recv_endpoint.address().to_string() << "]:" << in_vselement->udp_recv_endpoint.port();
703 oss << in_vselement->udp_recv_endpoint.address().to_string() << ":" << in_vselement->udp_recv_endpoint.port();
707 if (in_vselement->tcp_accept_endpoint.address().is_v6()) {
708 oss << "[" << in_vselement->tcp_accept_endpoint.address().to_string() << "]:" << in_vselement->tcp_accept_endpoint.port();
710 oss << in_vselement->tcp_accept_endpoint.address().to_string() << ":" << in_vselement->tcp_accept_endpoint.port();
714 //realserver information
715 BOOST_FOREACH(realserver_element elem, in_vselement->realserver_vector) {
716 if (in_vselement->udpmode) {
717 if (elem.udp_endpoint.address().is_v6()) {
718 oss << ",rs:[" << elem.udp_endpoint.address().to_string() << "]:" << elem.udp_endpoint.port();
720 oss << ",rs:" << elem.udp_endpoint.address().to_string() << ":" << elem.udp_endpoint.port();
724 if (elem.tcp_endpoint.address().is_v6()) {
725 oss << ",rs:[" << elem.tcp_endpoint.address().to_string() << "]:" << elem.tcp_endpoint.port();
727 oss << ",rs:" << elem.tcp_endpoint.address().to_string() << ":" << elem.tcp_endpoint.port();
732 trap_msg.message = oss.str();
736 //push the trap message
737 snmpagent::push_trapmessage(trap_msg, err_code);
740 std::string msg("Push trap message failed.");
741 Logger::putLogError(LOG_CAT_L7VSD_VIRTUALSERVICE, 129, msg, __FILE__, __LINE__);
746 std::string msg("virtual service not found.");
747 Logger::putLogWarn(LOG_CAT_L7VSD_VIRTUALSERVICE, 28, msg, __FILE__, __LINE__);
749 err.setter(true, msg);
754 //! virtual_service flush command
755 //! @param[out] error_code
756 void l7vsd::flush_virtual_service(error_code &err)
758 Logger logger(LOG_CAT_L7VSD_MAINTHREAD, 19, "l7vsd::flush_virtual_service", __FILE__, __LINE__);
760 boost::mutex::scoped_lock command_lock(command_mutex);
761 boost::mutex::scoped_lock vslist_lock(vslist_mutex);
763 // all virtualservice stop and finalize
765 vslist_type::iterator itr = vslist.begin();
766 if (vslist.end() == itr) {
769 //create trap message
770 trapmessage trap_msg;
771 trap_msg.type = trapmessage::VIRTUALSERVICE_REMOVE;
773 std::ostringstream oss;
774 oss << "TRAP00020003,A virtual service was eliminated.vs:";
775 if ((*itr)->get_element().udpmode) {
776 if ((*itr)->get_element().udp_recv_endpoint.address().is_v6()) {
777 oss << "[" << (*itr)->get_element().udp_recv_endpoint.address().to_string() << "]:" << (*itr)->get_element().udp_recv_endpoint.port();
779 oss << (*itr)->get_element().udp_recv_endpoint.address().to_string() << ":" << (*itr)->get_element().udp_recv_endpoint.port();
783 if ((*itr)->get_element().tcp_accept_endpoint.address().is_v6()) {
784 oss << "[" << (*itr)->get_element().tcp_accept_endpoint.address().to_string() << "]:" << (*itr)->get_element().tcp_accept_endpoint.port();
786 oss << (*itr)->get_element().tcp_accept_endpoint.address().to_string() << ":" << (*itr)->get_element().tcp_accept_endpoint.port();
790 trap_msg.message = oss.str();
794 //push the trap message
795 snmpagent::push_trapmessage(trap_msg, err_code);
798 std::string msg("Push trap message failed.");
799 Logger::putLogError(LOG_CAT_L7VSD_VIRTUALSERVICE, 130, msg, __FILE__, __LINE__);
805 (*itr)->finalize(err);
809 // join virtualservice threads
810 vs_threads.join_all();
812 // replication switch to slave
813 rep->switch_to_slave();
816 //! replication command
817 //! @param[in] replication command
818 //! @param[out] error_code
819 void l7vsd::replication_command(const l7vsadm_request::REPLICATION_COMMAND_TAG *cmd, error_code &err)
821 Logger logger(LOG_CAT_L7VSD_MAINTHREAD, 20, "l7vsd::replication_command", __FILE__, __LINE__);
823 boost::mutex::scoped_lock command_lock(command_mutex);
824 boost::mutex::scoped_lock vslist_lock(vslist_mutex);
827 std::string msg("cmd pointer is null.");
828 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 12, msg, __FILE__, __LINE__);
829 err.setter(true, msg);
833 std::string msg("rep pointer is null.");
834 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 13, msg, __FILE__, __LINE__);
835 err.setter(true, msg);
839 /*-------- DEBUG LOG --------*/
840 if (LOG_LV_DEBUG == Logger::getLogLevel(LOG_CAT_L7VSD_MAINTHREAD)) {
841 std::stringstream debugstr;
842 debugstr << "l7vsd::replication_command arguments:";
843 debugstr << boost::format("*cmd=%d") % *cmd;
844 Logger::putLogDebug(LOG_CAT_L7VSD_MAINTHREAD, 21, debugstr.str(), __FILE__, __LINE__);
846 /*------ DEBUG LOG END ------*/
849 case l7vsadm_request::REP_START:
852 case l7vsadm_request::REP_STOP:
855 case l7vsadm_request::REP_FORCE:
856 rep->force_replicate();
858 case l7vsadm_request::REP_DUMP:
862 std::string msg("invalid replication command.");
863 Logger::putLogError(LOG_CAT_L7VSD_REPLICATION, 38, msg, __FILE__, __LINE__);
864 err.setter(true, msg);
869 //! loglevel set command
870 //! @param[in] log category
871 //! @param[in] log level
872 //! @param[out] error_code
873 void l7vsd::set_loglevel(const LOG_CATEGORY_TAG *cat, const LOG_LEVEL_TAG *level, error_code &err)
875 Logger logger(LOG_CAT_L7VSD_MAINTHREAD, 22, "l7vsd::set_loglevel", __FILE__, __LINE__);
877 boost::mutex::scoped_lock command_lock(command_mutex);
878 boost::mutex::scoped_lock vslist_lock(vslist_mutex);
881 std::string msg("cat pointer is null.");
882 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 14, msg, __FILE__, __LINE__);
883 err.setter(true, msg);
887 std::string msg("level pointer is null.");
888 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 15, msg, __FILE__, __LINE__);
889 err.setter(true, msg);
893 /*-------- DEBUG LOG --------*/
894 if (LOG_LV_DEBUG == Logger::getLogLevel(LOG_CAT_L7VSD_MAINTHREAD)) {
895 std::stringstream debugstr;
896 debugstr << "l7vsd::set_loglevel arguments:";
897 debugstr << boost::format("*cat=%d, level=%d") % *cat % *level;
898 Logger::putLogDebug(LOG_CAT_L7VSD_MAINTHREAD, 23, debugstr.str(), __FILE__, __LINE__);
900 /*------ DEBUG LOG END ------*/
902 if (LOG_CAT_END == *cat) {
904 if (!Logger::setLogLevelAll(*level)) {
905 std::string msg("set loglevel all failed.");
906 Logger::putLogError(LOG_CAT_L7VSD_LOGGER, 122, msg, __FILE__, __LINE__);
907 err.setter(true, msg);
911 if (!Logger::setLogLevel(*cat, *level)) {
912 std::string msg("set loglevel failed.");
913 Logger::putLogError(LOG_CAT_L7VSD_LOGGER, 123, msg, __FILE__, __LINE__);
914 err.setter(true, msg);
920 //! reload parameter command
921 //! @param[in] reload component
922 //! @param[out] error_code
923 void l7vsd::reload_parameter(const PARAMETER_COMPONENT_TAG *comp, error_code &err)
925 Logger logger(LOG_CAT_L7VSD_MAINTHREAD, 26, "l7vsd::reload_parameter", __FILE__, __LINE__);
927 boost::mutex::scoped_lock command_lock(command_mutex);
928 boost::mutex::scoped_lock vslist_lock(vslist_mutex);
931 std::string msg("comp pointer is null.");
932 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 19, msg, __FILE__, __LINE__);
933 err.setter(true, msg);
937 std::string msg("rep pointer is null.");
938 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 20, msg, __FILE__, __LINE__);
939 err.setter(true, msg);
943 /*-------- DEBUG LOG --------*/
944 if (LOG_LV_DEBUG == Logger::getLogLevel(LOG_CAT_L7VSD_MAINTHREAD)) {
945 std::stringstream debugstr;
946 debugstr << "l7vsd::reload_parameter arguments:";
947 debugstr << boost::format("*comp=%d") % *comp;
948 Logger::putLogDebug(LOG_CAT_L7VSD_MAINTHREAD, 27, debugstr.str(), __FILE__, __LINE__);
950 /*------ DEBUG LOG END ------*/
953 Logger logger_instance;
956 case PARAM_COMP_REPLICATION:
957 if (param.read_file(*comp)) {
960 std::string msg("parameter reload failed.");
961 Logger::putLogError(LOG_CAT_L7VSD_PARAMETER, 7, msg, __FILE__, __LINE__);
962 err.setter(true, msg);
967 case PARAM_COMP_LOGGER:
968 if (param.read_file(*comp)) {
971 logger_instance.loadConf();
976 std::string msg("parameter reload failed.");
977 Logger::putLogError(LOG_CAT_L7VSD_PARAMETER, 7, msg, __FILE__, __LINE__);
978 err.setter(true, msg);
984 if (!param.read_file(PARAM_COMP_REPLICATION)) {
985 std::string msg("parameter reload failed.");
986 Logger::putLogError(LOG_CAT_L7VSD_PARAMETER, 7, msg, __FILE__, __LINE__);
987 err.setter(true, msg);
991 if (!param.read_file(PARAM_COMP_LOGGER)) {
992 std::string msg("parameter reload failed.");
993 Logger::putLogError(LOG_CAT_L7VSD_PARAMETER, 7, msg, __FILE__, __LINE__);
994 err.setter(true, msg);
1000 logger_instance.loadConf();
1006 std::string msg("parameter reload command not found.");
1007 Logger::putLogWarn(LOG_CAT_L7VSD_PARAMETER, 1, msg, __FILE__, __LINE__);
1008 err.setter(true, msg);
1014 void l7vsd::set_snmp_info(const snmp_info* info, error_code &err)
1016 Logger logger(LOG_CAT_L7VSD_MAINTHREAD, 42, "l7vsd::set_snmp_info", __FILE__, __LINE__);
1018 boost::mutex::scoped_lock command_lock(command_mutex);
1021 std::string msg("info pointer is null.");
1022 Logger::putLogFatal(LOG_CAT_L7VSD_MAINTHREAD, 21, msg, __FILE__, __LINE__);
1023 err.setter(true, msg);
1027 /*-------- DEBUG LOG --------*/
1028 if (LOG_LV_DEBUG == Logger::getLogLevel(LOG_CAT_L7VSD_MAINTHREAD)) {
1029 std::stringstream debugstr;
1030 debugstr << boost::format("info=%s") % *info;
1031 Logger::putLogDebug(LOG_CAT_L7VSD_MAINTHREAD, 43, debugstr.str(), __FILE__, __LINE__);
1033 /*------ DEBUG LOG END ------*/
1035 if (info->option_set_flag & snmp_info::SNMP_ENABLE_OPTION_FLAG)
1038 snmpagent::enable();
1041 snmpagent::disable();
1045 if (info->option_set_flag & snmp_info::SNMP_LOGTRAP_OPTION_FLAG)
1047 if(info->logtrap_enabled) {
1048 snmpagent::logtrap_enable();
1051 snmpagent::logtrap_disable();
1055 if (info->option_set_flag & snmp_info::SNMP_LOGTRAP_LEVEL_OPTION_FLAG)
1057 snmpagent::set_logtrap_level(info->logtrap_level);
1060 if (info->option_set_flag & snmp_info::SNMP_INTERVAL_OPTION_FLAG)
1062 snmpagent::set_interval(info->interval);
1065 if (info->option_set_flag & snmp_info::SNMP_REFRESH_OPTION_FLAG)
1068 boost::mutex::scoped_lock vslist_lock(vslist_mutex);
1069 virtualservice_element element;
1070 element.udpmode = false;
1071 element.tcp_accept_endpoint = info->vs_endpoint;
1072 element.protocol_module_name = info->protocol;
1073 vslist_type::iterator it = search_vslist(element, true);
1074 if (it == vslist.end())
1076 std::string msg("virtual service not found.");
1077 Logger::putLogWarn(LOG_CAT_L7VSD_VIRTUALSERVICE, 29, msg, __FILE__, __LINE__);
1079 err.setter(true, msg);
1084 snmpagent::refresh_statistics(info->vs_endpoint, info->protocol);
1087 if (info->option_set_flag & snmp_info::SNMP_REFRESH_ALL_OPTION_FLAG)
1089 snmpagent::refresh_all_statistics();
1094 //! vs_list search function
1095 //! @param[in] vs_element
1096 //! @param[out] error_code
1097 l7vsd::vslist_type::iterator l7vsd::search_vslist(
1098 const virtualservice_element &in_vselement,
1099 bool find_module_name) const
1101 Logger logger(LOG_CAT_L7VSD_MAINTHREAD, 28, "l7vsd::search_vslist", __FILE__, __LINE__);
1103 /*-------- DEBUG LOG --------*/
1104 if (LOG_LV_DEBUG == Logger::getLogLevel(LOG_CAT_L7VSD_MAINTHREAD)) {
1105 std::stringstream debugstr;
1106 debugstr << "l7vsd::search_vslist arguments:";
1107 debugstr << boost::format("in_vselement=%s") % in_vselement;
1108 Logger::putLogDebug(LOG_CAT_L7VSD_MAINTHREAD, 29, debugstr.str(), __FILE__, __LINE__);
1110 /*------ DEBUG LOG END ------*/
1112 for (vslist_type::iterator itr = vslist.begin();
1113 itr != vslist.end();
1115 if (in_vselement.udpmode) {
1116 if (((*itr)->get_element().udpmode) &&
1117 ((*itr)->get_element().udp_recv_endpoint == in_vselement.udp_recv_endpoint)) {
1118 if (find_module_name) {
1119 if ((*itr)->get_element().protocol_module_name == in_vselement.protocol_module_name) {
1127 if ((!((*itr)->get_element().udpmode)) &&
1128 ((*itr)->get_element().tcp_accept_endpoint == in_vselement.tcp_accept_endpoint)) {
1129 if (find_module_name) {
1130 if ((*itr)->get_element().protocol_module_name == in_vselement.protocol_module_name) {
1139 return vslist.end();
1142 //! virtualservice release from vslist
1143 //! @param[in] vs_element
1144 void l7vsd::release_virtual_service(const virtualservice_element &in_vselement) const
1146 Logger logger(LOG_CAT_L7VSD_MAINTHREAD, 30, "l7vsd::release_virtual_service", __FILE__, __LINE__);
1148 /*-------- DEBUG LOG --------*/
1149 if (LOG_LV_DEBUG == Logger::getLogLevel(LOG_CAT_L7VSD_MAINTHREAD)) {
1150 std::stringstream debugstr;
1151 debugstr << "l7vsd::release_virtual_service arguments:";
1152 debugstr << boost::format("in_vselement=%s") % in_vselement;
1153 Logger::putLogDebug(LOG_CAT_L7VSD_MAINTHREAD, 31, debugstr.str(), __FILE__, __LINE__);
1155 /*------ DEBUG LOG END ------*/
1157 vslist_type::iterator vsitr = search_vslist(in_vselement);
1158 if (vslist.end() != vsitr) {
1159 // remove from vslist
1160 vslist.remove(*vsitr);
1163 //! virtualservice_list getter
1165 l7vsd::vslist_type &l7vsd::get_virtualservice_list()
1167 Logger logger(LOG_CAT_L7VSD_MAINTHREAD, 32, "l7vsd::get_virtualservice_list", __FILE__, __LINE__);
1172 //! virtualservice_list mutex getter
1173 //! @return vslist_mutex
1174 boost::mutex &l7vsd::get_virtualservice_list_mutex()
1176 Logger logger(LOG_CAT_L7VSD_MAINTHREAD, 33, "l7vsd::get_virtualservice_list_mutex", __FILE__, __LINE__);
1178 return vslist_mutex;
1181 //! replication_ptr getter
1182 //! @return replication_ptr
1183 replication::REPLICATION_MODE_TAG l7vsd::get_replication_state() const
1185 return rep->get_status();
1189 //! l7vsd run method
1190 //! @param[in] argument count
1191 //! @param[in] argument value
1192 int l7vsd::run(int argc, char *argv[])
1194 Logger logger(LOG_CAT_L7VSD_MAINTHREAD, 34, "l7vsd::run", __FILE__, __LINE__);
1196 /*-------- DEBUG LOG --------*/
1197 if (LOG_LV_DEBUG == Logger::getLogLevel(LOG_CAT_L7VSADM_COMMON)) {
1198 std::stringstream debugstr;
1199 debugstr << boost::format("l7vsd::run arguments:%s") % argument_debug_dump(argc, argv);
1200 Logger::putLogDebug(LOG_CAT_L7VSD_MAINTHREAD, 35, debugstr.str(), __FILE__, __LINE__);
1202 /*------ DEBUG LOG END ------*/
1204 mlockall(MCL_FUTURE);
1208 if (!check_options(argc, argv)) {
1209 std::cerr << usage();
1216 std::cout << usage();
1222 if (0 > daemon(0, 0)) {
1223 std::stringstream buf;
1224 buf << "daemon() failed: " << strerror(errno);
1225 logger.putLogError(LOG_CAT_L7VSD_MAINTHREAD, 3, buf.str(), __FILE__, __LINE__);
1231 //set max file open num
1234 int maxfileno = param.get_int(PARAM_COMP_L7VSD, "maxfileno", err);
1236 logger.putLogWarn(LOG_CAT_L7VSD_MAINTHREAD, 1,
1237 "maxfileno parameter not found.", __FILE__, __LINE__);
1240 if (maxfileno < 32) {
1241 logger.putLogWarn(LOG_CAT_L7VSD_MAINTHREAD, 10,
1242 "invalid parameter for maxfileno.", __FILE__, __LINE__);
1246 //set process scheduler & priority
1247 int scheduler = SCHED_OTHER;
1248 bool change_scheduler = true;
1249 int int_val = param.get_int(PARAM_COMP_L7VSD, PARAM_SCHED_ALGORITHM, err);
1251 change_scheduler = false;
1253 if (change_scheduler) {
1254 if ((SCHED_FIFO == int_val) || (SCHED_RR == int_val) || (SCHED_OTHER == int_val) || (SCHED_BATCH == int_val)) {
1255 scheduler = int_val;
1257 logger.putLogWarn(LOG_CAT_L7VSD_MAINTHREAD, 5, "invalid parameter for task scheduler algorithm.", __FILE__, __LINE__);
1259 int proc_pri = param.get_int(PARAM_COMP_L7VSD, PARAM_SCHED_PRIORITY, err);
1261 logger.putLogWarn(LOG_CAT_L7VSD_MAINTHREAD, 6, "task scheduler priority parameter not found.", __FILE__, __LINE__);
1262 proc_pri = sched_get_priority_min(scheduler);
1264 if ((SCHED_FIFO == scheduler) || (SCHED_RR == scheduler)) {
1265 if (proc_pri < 1 || 99 < proc_pri) {
1266 logger.putLogWarn(LOG_CAT_L7VSD_MAINTHREAD, 7, "invalid parameter for task scheduler priority.", __FILE__, __LINE__);
1267 proc_pri = sched_get_priority_min(scheduler);
1270 if ((SCHED_OTHER == scheduler) || (SCHED_BATCH == scheduler)) {
1271 if (proc_pri != 0) {
1272 logger.putLogWarn(LOG_CAT_L7VSD_MAINTHREAD, 8, "invalid parameter for task scheduler priority.", __FILE__, __LINE__);
1273 proc_pri = sched_get_priority_min(scheduler);
1278 sched_param scheduler_param;
1279 int ret_val = sched_getparam(0, &scheduler_param);
1280 scheduler_param.__sched_priority = proc_pri;
1281 ret_val = sched_setscheduler(0, scheduler, &scheduler_param);
1283 logger.putLogWarn(LOG_CAT_L7VSD_MAINTHREAD, 9, "task scheduler setting failed.", __FILE__, __LINE__);
1288 lim.rlim_cur = maxfileno;
1289 lim.rlim_max = maxfileno;
1291 ret = setrlimit(RLIMIT_NOFILE, &lim);
1293 std::stringstream buf;
1294 buf << "setrlimit failed:" << errno;
1295 logger.putLogWarn(LOG_CAT_L7VSD_MAINTHREAD, 2, buf.str(), __FILE__, __LINE__);
1298 // signal handler thread start
1299 boost::thread sigthread(boost::bind(&l7vsd::sig_exit_handler, this));
1302 // protocol module control initialize
1303 protocol_module_control::getInstance().initialize(L7VS_MODULE_PATH);
1305 // schedule module control initialize
1306 schedule_module_control::getInstance().initialize(L7VS_MODULE_PATH);
1308 // receiver initialize
1309 receiver.reset(new command_receiver(dispatcher, L7VS_CONFIG_SOCKNAME, *this));
1310 if (NULL == receiver) {
1311 logger.putLogError(LOG_CAT_L7VSD_MAINTHREAD, 4, "command receiver pointer null.", __FILE__, __LINE__);
1316 // replication initialize
1317 rep.reset(new replication());
1319 logger.putLogError(LOG_CAT_L7VSD_MAINTHREAD, 5, "replication pointer null.", __FILE__, __LINE__);
1323 if (0 > rep->initialize()) {
1324 logger.putLogWarn(LOG_CAT_L7VSD_MAINTHREAD, 3, "replication initialize failed.", __FILE__, __LINE__);
1327 // snmpagent initialize
1328 snmpagent agent(this);
1330 // snmp trap function set
1331 Logger::set_snmp_send_trap_func( boost::bind( &snmpagent::push_trapmessage, _1, _2 ) );
1333 error_code err_code;
1336 agent.start(err_code);
1339 logger.putLogError(LOG_CAT_L7VSD_MAINTHREAD, 8, "snmp function start failed.", __FILE__, __LINE__);
1342 err_code.setter(false, "");
1344 //create trap message
1345 trapmessage trap_msg;
1346 trap_msg.type = trapmessage::SERVICE_START;
1347 trap_msg.message = "TRAP00010001,l7vsd start.";
1349 //push the trap message
1350 snmpagent::push_trapmessage(trap_msg, err_code);
1353 std::string msg("Push trap message failed.");
1354 Logger::putLogError(LOG_CAT_L7VSD_MAINTHREAD, 9, msg, __FILE__, __LINE__);
1359 if (unlikely(exit_requested)) {
1360 std::stringstream buf;
1361 buf << boost::format("l7vsd signal(%d) received. exiting...") % received_sig;
1362 logger.putLogInfo(LOG_CAT_L7VSD_MAINTHREAD, 1, buf.str(), __FILE__, __LINE__);
1367 wait_val.tv_sec = 0;
1368 wait_val.tv_nsec = 1000000;
1369 nanosleep(&wait_val, NULL);
1370 boost::this_thread::yield();
1373 // snmp trap function unset
1374 Logger::set_snmp_send_trap_func(NULL);
1376 // check snmp function enabled
1377 if (snmpagent::get_snmp_info().enabled) {
1378 // get local time string
1379 char time_buf[TRAP_TIME_STRING_MAX_SIZE] = {0};
1380 time_t now = time(NULL);
1381 struct tm *t = localtime(&now);
1382 if (t) strftime(time_buf, sizeof(time_buf), "%Y/%m/%d %H:%M:%S", t);
1384 // make trap message
1385 std::stringstream trap_buf;
1386 trap_buf << time_buf << "," << "TRAP00010002,l7vsd stop.";
1387 char buff[HOST_NAME_MAX] = {0};
1388 gethostname(buff, HOST_NAME_MAX);
1389 trap_buf << "," << buff;
1390 // send trap message
1391 trap_service_stop(trap_buf.str());
1394 // snmp agent finalize
1397 // replication finalize
1400 // schedule module control finalize
1401 schedule_module_control::getInstance().finalize();
1403 // protocol module control finalize
1404 protocol_module_control::getInstance().finalize();
1405 } catch (std::exception &e) {
1406 std::stringstream buf;
1407 buf << "l7vsd run error:" << e.what();
1408 logger.putLogError(LOG_CAT_L7VSD_MAINTHREAD, 7, buf.str(), __FILE__, __LINE__);
1417 //! argument dump for debug
1418 //! @param[in] argument count
1419 //! @param[in] argument value
1420 std::string l7vsd::argument_debug_dump(int argc, char *argv[])
1422 std::stringstream buf;
1424 buf << "argument=(null)";
1426 buf << boost::format("argument={argc=%d: ") % argc;
1427 for (int i = 0; i < argc; ++i) {
1428 buf << boost::format("argv[%d]=%s: ") % i % argv[i];
1435 //! command option check
1436 //! @param[in] argument count
1437 //! @param[in] argument value
1438 bool l7vsd::check_options(int argc, char *argv[])
1440 Logger logger(LOG_CAT_L7VSD_MAINTHREAD, 36, "l7vsd::check_options", __FILE__, __LINE__);
1442 for (int pos = 1; pos < argc; ++pos) { // check options.
1443 parse_opt_map_type::iterator itr = option_dic.find(argv[pos]);
1444 if (itr != option_dic.end()) { // find option
1445 if (!itr->second(pos, argc, argv)) {
1446 return false; // option function execute.
1448 } else { // don't find option function.
1449 std::stringstream buf;
1450 buf << "l7vsd: unknown option: " << argv[ pos ] << "\n";
1451 std::cerr << buf.str();
1458 //! command help parse
1459 //! @param[in] argument count
1460 //! @param[in] argument value
1461 bool l7vsd::parse_help(int &pos, int argc, char *argv[])
1463 Logger logger(LOG_CAT_L7VSD_MAINTHREAD, 37, "l7vsd::parse_help", __FILE__, __LINE__);
1465 help = true; //help_mode flag on
1469 //! command debug parse
1470 bool l7vsd::parse_debug( int& pos, int argc, char* argv[] ){
1471 Logger logger(LOG_CAT_L7VSD_MAINTHREAD, 38, "l7vsd::parse_help", __FILE__, __LINE__);
1476 //! create usage string
1477 //! @return usage string
1478 std::string l7vsd::usage()
1480 Logger logger(LOG_CAT_L7VSD_MAINTHREAD, 39, "l7vsd::usage", __FILE__, __LINE__);
1482 std::stringstream stream;
1484 "Usage: l7vsd [-h]\n"
1485 " -h --help print this help messages and exit\n";
1486 return stream.str();
1489 //! signal handler function
1490 void l7vsd::sig_exit_handler()
1492 Logger logger(LOG_CAT_L7VSD_MAINTHREAD, 40, "l7vsd::sig_exit_handler", __FILE__, __LINE__);
1495 sigemptyset(&sigmask);
1496 sigaddset(&sigmask, SIGHUP);
1497 sigaddset(&sigmask, SIGINT);
1498 sigaddset(&sigmask, SIGQUIT);
1499 sigaddset(&sigmask, SIGTERM);
1500 sigaddset(&sigmask, SIGPIPE);
1503 sigwait(&sigmask, &sig);
1509 };// namespace l7vsd
1513 extern "C" int pthread_sigmask_non(int how, const sigset_t *newmask, sigset_t *old_mask)
1517 int pthread_sigmask(int, const sigset_t *, sigset_t *) __attribute__((weak, alias("pthread_sigmask_non")));
1521 int main(int argc, char *argv[])
1529 sigfillset(&newmask);
1530 ret = sigprocmask(SIG_BLOCK, &newmask, &oldmask);
1535 l7vs::Logger logger_instance;
1536 l7vs::Parameter parameter_instance;
1537 logger_instance.loadConf();
1538 l7vs::logger_access_manager::getInstance().access_log_rotate_loadConf();
1542 ret = vsd.run(argc, argv);
1548 pthread_sigmask(SIG_SETMASK, &oldmask, NULL);