diff options
| author | Michael Larson <slioch@eng-140.vyatta.com> | 2008-01-31 14:50:57 -0800 |
|---|---|---|
| committer | Michael Larson <slioch@eng-140.vyatta.com> | 2008-01-31 14:50:57 -0800 |
| commit | 1b4349fce41b93bc5965c39d1a9a33279a3ddfbb (patch) | |
| tree | 39b88d1fa5443e2ba1feb0c26e6ba8c0b65aba8e /src | |
| parent | 07e2dbf1d5a98860333aefa989370305467c2254 (diff) | |
| download | vyatta-wanloadbalance-1b4349fce41b93bc5965c39d1a9a33279a3ddfbb.tar.gz vyatta-wanloadbalance-1b4349fce41b93bc5965c39d1a9a33279a3ddfbb.zip | |
moved most stdout messages to new debug output command. reworked (simplified) init script so that rules table is properly cleaned
up on exit of wlb. fixed a couple cli structural related issues.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lbdatafactory.cc | 73 | ||||
| -rw-r--r-- | src/lbdatafactory.hh | 3 | ||||
| -rw-r--r-- | src/lbdecision.cc | 40 | ||||
| -rw-r--r-- | src/lbdecision.hh | 3 | ||||
| -rw-r--r-- | src/lboutput.cc | 4 | ||||
| -rw-r--r-- | src/lboutput.hh | 5 | ||||
| -rw-r--r-- | src/lbpathtest.cc | 116 | ||||
| -rw-r--r-- | src/lbpathtest.hh | 3 | ||||
| -rw-r--r-- | src/loadbalance.cc | 7 | ||||
| -rw-r--r-- | src/loadbalance.hh | 3 | ||||
| -rw-r--r-- | src/main.cc | 30 |
11 files changed, 179 insertions, 108 deletions
diff --git a/src/lbdatafactory.cc b/src/lbdatafactory.cc index 0220416..ed96d72 100644 --- a/src/lbdatafactory.cc +++ b/src/lbdatafactory.cc @@ -40,7 +40,8 @@ using namespace std; -LBDataFactory::LBDataFactory() +LBDataFactory::LBDataFactory(bool debug) : + _debug(debug) { } @@ -55,7 +56,9 @@ LBDataFactory::load(const string &conf_file) //open file FILE *fp = fopen(conf_file.c_str(), "r"); if (fp == NULL) { - cerr << "Error opening configuration file: " << conf_file << endl; + if (_debug) { + cerr << "Error opening configuration file: " << conf_file << endl; + } syslog(LOG_ERR, "wan_lb: configuration file not found: %s", conf_file.c_str()); return false; } @@ -96,7 +99,9 @@ LBDataFactory::load(const string &conf_file) process(path,depth,key,value); } if (depth > 9 || depth < 0) { - cerr << "configuration error: malformed configuration file: brackets" << endl; + if (_debug) { + cerr << "configuration error: malformed configuration file: brackets" << endl; + } syslog(LOG_ERR, "wan_lb: malformed configuration file: brackets"); return false; } @@ -104,14 +109,16 @@ LBDataFactory::load(const string &conf_file) fclose(fp); if (depth != 0) { - cerr << "configuration error: mismatched brackets in configuration file" << endl; + if (_debug) { + cerr << "configuration error: mismatched brackets in configuration file" << endl; + } syslog(LOG_ERR, "wan_lb: configuration error due to mismatched brackets"); return false; } -#ifdef DEBUG - _lb_data.dump(); -#endif + if (_debug) { + _lb_data.dump(); + } return true; } @@ -177,7 +184,9 @@ LBDataFactory::process_health_interface(const string &key, const string &value) _health_iter->second._success_ct = num; } else { - cerr << "illegal success-ct specified: " << value << endl; + if (_debug) { + cerr << "illegal success-ct specified: " << value << endl; + } syslog(LOG_ERR, "wan_lb: illegal success-ct specified in configuration file: %s", value.c_str()); } } @@ -187,7 +196,9 @@ LBDataFactory::process_health_interface(const string &key, const string &value) _health_iter->second._failure_ct = num; } else { - cerr << "illegal failure-ct specified: " << value << endl; + if (_debug) { + cerr << "illegal failure-ct specified: " << value << endl; + } syslog(LOG_ERR, "wan_lb: illegal failure-ct specified in configuration file: %s", value.c_str()); } } @@ -197,7 +208,9 @@ LBDataFactory::process_health_interface(const string &key, const string &value) _health_iter->second._ping_resp_time = num; } else { - cerr << "illegal ping-resp specified: " << value << endl; + if (_debug) { + cerr << "illegal ping-resp specified: " << value << endl; + } syslog(LOG_ERR, "wan_lb: illegal ping-resp specified in configuration file: %s", value.c_str()); } } @@ -205,7 +218,9 @@ LBDataFactory::process_health_interface(const string &key, const string &value) //nothing } else { - cout << "LBDataFactory::process_health(): " << "don't understand this symbol: " << key << endl; + if (_debug) { + cout << "LBDataFactory::process_health(): " << "don't understand this symbol: " << key << endl; + } //nothing } @@ -217,15 +232,17 @@ LBDataFactory::process_rule(const string &key, const string &value) if (key.empty()) { return; } -#ifdef DEBUG - cout << "LBDataFactor::process_rule(): " << key << ", " << value << endl; -#endif + if (_debug) { + cout << "LBDataFactor::process_rule(): " << key << ", " << value << endl; + } int num = strtoul(value.c_str(), NULL, 10); if (num > 0) { _lb_data._lb_rule_coll.insert(pair<int,LBRule>(num,LBRule())); } else { - cerr << "Rule number: illegal value" << endl; + if (_debug) { + cerr << "Rule number: illegal value" << endl; + } syslog(LOG_ERR, "wan_lb: illegal rule number: %s", value.c_str()); return; } @@ -249,7 +266,9 @@ LBDataFactory::process_rule_protocol(const string &key, const string &value) _rule_iter->second._proto = "tcp"; } else { - cerr << "protocol not recognized: " << key << ", " << value << endl; + if (_debug) { + cerr << "protocol not recognized: " << key << ", " << value << endl; + } syslog(LOG_ERR, "wan_lb: illegal protocol specified: %s", value.c_str()); } } @@ -260,7 +279,9 @@ LBDataFactory::process_rule_source(const string &key, const string &value) { if (key == "address") { if (inet_addr(value.c_str()) == (unsigned)-1) { - cerr << "malformed ip address: " << key << ", " << value << endl; + if (_debug) { + cerr << "malformed ip address: " << key << ", " << value << endl; + } syslog(LOG_ERR, "wan_lb, malformed ip address in configuration: %s,%s", key.c_str(),value.c_str()); return; } @@ -282,7 +303,9 @@ LBDataFactory::process_rule_destination(const string &key, const string &value) { if (key == "address") { if (inet_addr(value.c_str()) == (unsigned)-1) { - cerr << "malformed ip address: " << key << ", " << value << endl; + if (_debug) { + cerr << "malformed ip address: " << key << ", " << value << endl; + } syslog(LOG_ERR, "wan_lb, malformed ip address in configuration: %s,%s", key.c_str(),value.c_str()); return; } @@ -302,9 +325,9 @@ LBDataFactory::process_rule_destination(const string &key, const string &value) void LBDataFactory::process_rule_interface(const string &key, const string &value) { -#ifdef DEBUG - cout << "LBDataFactory::process_rule_interface(): " << key << ", " << value << endl; -#endif + if (_debug) { + cout << "LBDataFactory::process_rule_interface(): " << key << ", " << value << endl; + } if (key == "interface") { _rule_iter->second._iface_dist_coll.insert(pair<string,int>(value,0)); _rule_iface_iter = _rule_iter->second._iface_dist_coll.find(value); @@ -315,12 +338,16 @@ LBDataFactory::process_rule_interface(const string &key, const string &value) _rule_iface_iter->second = num; } else { - cerr << "illegal interface weight specified: " << value << endl; + if (_debug) { + cerr << "illegal interface weight specified: " << value << endl; + } syslog(LOG_ERR, "wan_lb: illegal interface weight specified in configuration file: %s", value.c_str()); } } else { - cerr << "LBDataFactory::process_rule(): " << "don't understand this symbol: " << key << endl; + if (_debug) { + cerr << "LBDataFactory::process_rule(): " << "don't understand this symbol: " << key << endl; + } } } diff --git a/src/lbdatafactory.hh b/src/lbdatafactory.hh index 29fe609..49f5f06 100644 --- a/src/lbdatafactory.hh +++ b/src/lbdatafactory.hh @@ -41,7 +41,7 @@ public: typedef vector<string>::iterator ConfIter; public: - LBDataFactory(); + LBDataFactory(bool debug); ~LBDataFactory(); bool @@ -82,6 +82,7 @@ private: process_rule_interface(const string &key, const string &value); private: + bool _debug; LBHealth _lb_health; LBRule _lb_rule; LBData _lb_data; diff --git a/src/lbdecision.cc b/src/lbdecision.cc index 79e86cb..7f9fb55 100644 --- a/src/lbdecision.cc +++ b/src/lbdecision.cc @@ -69,7 +69,8 @@ ip ro fl ca * * **/ -LBDecision::LBDecision() +LBDecision::LBDecision(bool debug) : + _debug(debug) { } @@ -151,18 +152,18 @@ iptables -t mangle -A PREROUTING -i eth0 -j MARK --set-mark 2 void LBDecision::run(LBData &lb_data) { -#ifdef DEBUG - cout << "LBDecision::run(), starting decision" << endl; -#endif + if (_debug) { + cout << "LBDecision::run(), starting decision" << endl; + } //first determine if we need to alter the rule set if (!lb_data.state_changed()) { return; } -#ifdef DEBUG - cout << "LBDecision::run(), state changed, applying new rule set" << endl; -#endif + if (_debug) { + cout << "LBDecision::run(), state changed, applying new rule set" << endl; + } //then if we do, flush all execute("iptables -t mangle -F PREROUTING"); @@ -206,6 +207,8 @@ LBDecision::run(LBData &lb_data) void LBDecision::shutdown() { + cout << "LBDecision::shutdown(): " << _iface_mark_coll.size() << endl; + char buf[20]; //then if we do, flush all @@ -215,6 +218,9 @@ LBDecision::shutdown() InterfaceMarkIter iter = _iface_mark_coll.begin(); while (iter != _iface_mark_coll.end()) { sprintf(buf,"%d",iter->second); + + cout << "LBDecision::shutdown(): removing " << buf << endl; + execute(string("ip rule del fwmark ") + buf); ++iter; } @@ -227,19 +233,23 @@ LBDecision::shutdown() void LBDecision::execute(string cmd) { -#ifdef DEBUG - cout << "LBDecision::execute(): applying command to system: " << cmd << endl; -#endif + if (_debug) { + cout << "LBDecision::execute(): applying command to system: " << cmd << endl; + } FILE *f = popen(cmd.c_str(), "w"); if (f) { if (pclose(f) != 0) { - cerr << "LBDecision::execute(): error executing command: " << cmd << endl; + if (_debug) { + cerr << "LBDecision::execute(): error executing command: " << cmd << endl; + } syslog(LOG_ERR, "Error executing system command: %s", cmd.c_str()); } } else { - cerr << "LBDecision::execute(): error executing command: " << cmd << endl; + if (_debug) { + cerr << "LBDecision::execute(): error executing command: " << cmd << endl; + } syslog(LOG_ERR, "Error executing system command: %s", cmd.c_str()); } } @@ -252,9 +262,9 @@ LBDecision::get_new_weights(LBData &data, LBRule &rule) int ct = 1; LBRule::InterfaceDistIter iter = rule._iface_dist_coll.begin(); while (iter != rule._iface_dist_coll.end()) { -#ifdef DEBUG - cout << "LBDecision::get_new_weights(): " << iter->first << " is active: " << (data.is_active(iter->first) ? "true" : "false") << endl; -#endif + if (_debug) { + cout << "LBDecision::get_new_weights(): " << iter->first << " is active: " << (data.is_active(iter->first) ? "true" : "false") << endl; + } if (data.is_active(iter->first)) { weights.insert(pair<int,float>(ct,iter->second)); group += iter->second; diff --git a/src/lbdecision.hh b/src/lbdecision.hh index 299544a..a03279f 100644 --- a/src/lbdecision.hh +++ b/src/lbdecision.hh @@ -41,7 +41,7 @@ public: typedef map<string,int>::iterator InterfaceMarkIter; public: - LBDecision(); + LBDecision(bool debug); ~LBDecision(); void @@ -64,6 +64,7 @@ private: get_application_cmd(LBRule &rule); private: + bool _debug; InterfaceMarkColl _iface_mark_coll; }; diff --git a/src/lboutput.cc b/src/lboutput.cc index e0ed18b..7434446 100644 --- a/src/lboutput.cc +++ b/src/lboutput.cc @@ -52,7 +52,9 @@ LBOutput::write(const LBData &lbdata) //dump out the application data LBData::LBRuleConstIter r_iter = lbdata._lb_rule_coll.begin(); while (r_iter != lbdata._lb_rule_coll.end()) { - cout << "squirt out results here." << endl; + if (_debug) { + cout << "squirt out results here." << endl; + } ++r_iter; } } diff --git a/src/lboutput.hh b/src/lboutput.hh index b68c9f2..33f58bf 100644 --- a/src/lboutput.hh +++ b/src/lboutput.hh @@ -35,11 +35,14 @@ using namespace std; class LBOutput { public: - LBOutput() {} + LBOutput(bool debug) : _debug(debug) {} ~LBOutput() {} void write(const LBData &lbdata); +private: + bool _debug; + }; #endif //__LBOUTPUT_HH__ diff --git a/src/lbpathtest.cc b/src/lbpathtest.cc index 7e052c7..0e66199 100644 --- a/src/lbpathtest.cc +++ b/src/lbpathtest.cc @@ -50,7 +50,8 @@ using namespace std; -LBPathTest::LBPathTest() : +LBPathTest::LBPathTest(bool debug) : + _debug(debug), _send_sock(0), _recv_sock(0), _packet_id(0) @@ -58,7 +59,9 @@ LBPathTest::LBPathTest() : struct protoent *ppe = getprotobyname("icmp"); _send_sock = socket(PF_INET, SOCK_RAW, ppe->p_proto); if (_send_sock < 0){ - cerr << "LBPathTest::LBPathTest(): no send sock: " << _send_sock << endl; + if (_debug) { + cerr << "LBPathTest::LBPathTest(): no send sock: " << _send_sock << endl; + } syslog(LOG_ERR, "wan_lb: failed to acquired socket"); _send_sock = 0; return; @@ -77,13 +80,17 @@ LBPathTest::LBPathTest() : _recv_sock = socket(PF_INET, SOCK_RAW, ppe->p_proto); if (_recv_sock < 0) { - cerr << "LBPathTest::LBPathTest(): no recv sock: " << _recv_sock << endl; + if (_debug) { + cerr << "LBPathTest::LBPathTest(): no recv sock: " << _recv_sock << endl; + } syslog(LOG_ERR, "wan_lb: failed to acquired socket"); _recv_sock = 0; return; } if (bind(_recv_sock, (struct sockaddr*)&addr, sizeof(addr))==-1) { - cerr << "failed on bind" << endl; + if (_debug) { + cerr << "failed on bind" << endl; + } syslog(LOG_ERR, "wan_lb: failed to bind recv sock"); } } @@ -100,9 +107,9 @@ LBPathTest::~LBPathTest() void LBPathTest::start(LBData &lb_data) { -#ifdef DEBUG - cout << "LBPathTest::start(): starting health test. client ct: " << lb_data._iface_health_coll.size() << endl; -#endif + if (_debug) { + cout << "LBPathTest::start(): starting health test. client ct: " << lb_data._iface_health_coll.size() << endl; + } map<int,PktData> results; @@ -113,9 +120,9 @@ LBPathTest::start(LBData &lb_data) //iterate over packets and send LBData::InterfaceHealthIter iter = lb_data._iface_health_coll.begin(); while (iter != lb_data._iface_health_coll.end()) { -#ifdef DEBUG - cout << "LBPathTest::start(): sending ping test for: " << iter->first << " for " << iter->second._ping_target << endl; -#endif + if (_debug) { + cout << "LBPathTest::start(): sending ping test for: " << iter->first << " for " << iter->second._ping_target << endl; + } _packet_id = ++_packet_id % 32767; send(iter->first, iter->second._ping_target, _packet_id); results.insert(pair<int,PktData>(_packet_id,PktData(iter->first,-1))); @@ -136,9 +143,9 @@ LBPathTest::start(LBData &lb_data) //then iterate over recv socket and receive and record while (ct > 0 && cur_time < timeout) { int id = receive(); -#ifdef DEBUG - cout << "LBPathTest::start(): " << id << endl; -#endif + if (_debug) { + cout << "LBPathTest::start(): " << id << endl; + } //update current time for comparison sysinfo(&si); timeval recv_time; @@ -162,9 +169,9 @@ LBPathTest::start(LBData &lb_data) LBData::InterfaceHealthIter iter = lb_data._iface_health_coll.find(r_iter->second._iface); if (iter != lb_data._iface_health_coll.end()) { //check to see if this returned in the configured time, otherwise apply timeout -#ifdef DEBUG - cout << "LBPathTest::start(): received pkt: " << iter->first << ", rtt: " << rtt << endl; -#endif + if (_debug) { + cout << "LBPathTest::start(): received pkt: " << iter->first << ", rtt: " << rtt << endl; + } if (rtt < iter->second._ping_resp_time) { iter->second.put(rtt); } @@ -187,9 +194,9 @@ LBPathTest::start(LBData &lb_data) ++r_iter; } -#ifdef DEBUG - cout << "LBPathTest::start(): finished heath test" << endl; -#endif + if (_debug) { + cout << "LBPathTest::start(): finished heath test" << endl; + } } void @@ -208,7 +215,9 @@ LBPathTest::send(const string &iface, const string &target_addr, int packet_id) //convert target_addr to ip addr struct hostent *h = gethostbyname(target_addr.c_str()); if (h == NULL) { - cerr << "LBPathTest::send() Error in resolving hostname" << endl; + if (_debug) { + cerr << "LBPathTest::send() Error in resolving hostname" << endl; + } syslog(LOG_ERR, "wan_lb: error in resolving configured hostname: %s", target_addr.c_str()); return; } @@ -248,38 +257,39 @@ LBPathTest::send(const string &iface, const string &target_addr, int packet_id) //need to direct this packet out a specific interface!!!!!!!!!!!!! err = sendto(_send_sock, buffer, icmp_pktsize, 0, (struct sockaddr*)&taddr, sizeof(taddr)); -#ifdef DEBUG - cout << "lbpathtest: sendto: " << err << ", packet id: " << packet_id << endl; -#endif + if (_debug) { + cout << "lbpathtest: sendto: " << err << ", packet id: " << packet_id << endl; + } if(err < 0) { - if (errno == EBADF) - cout << "EBADF" << endl; - else if (errno == ENOTSOCK) - cout << "ENOTSOCK" << endl; - else if (errno == EFAULT) - cout << "EFAULT" << endl; - else if (errno == EMSGSIZE) - cout << "EMSGSIZE" << endl; - else if (errno == EWOULDBLOCK) - cout << "EWOULDBLOCK" << endl; - else if (errno == EAGAIN) - cout << "EAGAIN" << endl; - else if (errno == ENOBUFS) - cout << "ENOBUFS" << endl; - else if (errno == EINTR) - cout << "EINTR" << endl; - else if (errno == ENOMEM) - cout << "ENOMEM" << endl; - else if (errno == EACCES) - cout << "EACCES" << endl; - else if (errno == EINVAL) - cout << "EINVAL" << endl; - else if (errno == EPIPE) - cout << "EPIPE" << endl; - else - cout << "unknown error: " << errno << endl; - + if (_debug) { + if (errno == EBADF) + cout << "EBADF" << endl; + else if (errno == ENOTSOCK) + cout << "ENOTSOCK" << endl; + else if (errno == EFAULT) + cout << "EFAULT" << endl; + else if (errno == EMSGSIZE) + cout << "EMSGSIZE" << endl; + else if (errno == EWOULDBLOCK) + cout << "EWOULDBLOCK" << endl; + else if (errno == EAGAIN) + cout << "EAGAIN" << endl; + else if (errno == ENOBUFS) + cout << "ENOBUFS" << endl; + else if (errno == EINTR) + cout << "EINTR" << endl; + else if (errno == ENOMEM) + cout << "ENOMEM" << endl; + else if (errno == EACCES) + cout << "EACCES" << endl; + else if (errno == EINVAL) + cout << "EINVAL" << endl; + else if (errno == EPIPE) + cout << "EPIPE" << endl; + else + cout << "unknown error: " << errno << endl; + } syslog(LOG_ERR, "wan_lb: error on sending icmp packet: %d", errno); } } @@ -308,9 +318,9 @@ LBPathTest::receive() icmp_hdr = (struct icmphdr *)(resp_buf + sizeof(iphdr)); if (icmp_hdr->type == ICMP_ECHOREPLY) { -#ifdef DEBUG - cout << "LBPathTest::receive(): " << endl; -#endif + if (_debug) { + cout << "LBPathTest::receive(): " << endl; + } //process packet data char* data; int id = 0; diff --git a/src/lbpathtest.hh b/src/lbpathtest.hh index 176bf18..aba3a54 100644 --- a/src/lbpathtest.hh +++ b/src/lbpathtest.hh @@ -47,7 +47,7 @@ public: class LBPathTest { public: - LBPathTest(); + LBPathTest(bool debug); ~LBPathTest(); void @@ -64,6 +64,7 @@ private: in_checksum(const unsigned short *buf, int lenght) const; private: + bool _debug; int _send_sock; int _recv_sock; int _packet_id; diff --git a/src/loadbalance.cc b/src/loadbalance.cc index a48ace0..60a793f 100644 --- a/src/loadbalance.cc +++ b/src/loadbalance.cc @@ -34,7 +34,12 @@ using namespace std; /** * **/ -LoadBalance::LoadBalance() : +LoadBalance::LoadBalance(bool debug) : + _debug(debug), + _lbdata_factory(debug), + _ph(debug), + _decision(debug), + _output(debug), _cycle_interval(5000) { } diff --git a/src/loadbalance.hh b/src/loadbalance.hh index 624a3e4..47fa7b5 100644 --- a/src/loadbalance.hh +++ b/src/loadbalance.hh @@ -45,7 +45,7 @@ using namespace std; class LoadBalance { public: - LoadBalance(); + LoadBalance(bool debug); ~LoadBalance(); bool set_conf(const string &filename); @@ -64,6 +64,7 @@ class LoadBalance void sleep() {::sleep(5);} private: + bool _debug; LBDataFactory _lbdata_factory; LBData _lbdata; LBPathTest _ph; diff --git a/src/main.cc b/src/main.cc index 098b664..e62c6c5 100644 --- a/src/main.cc +++ b/src/main.cc @@ -42,6 +42,7 @@ static void usage() cout << "lb -ftidh" << endl; cout << "-f [file] configuration file" << endl; cout << "-t load configuration file only and exit" << endl; + cout << "-v print debug output" << endl; cout << "-i specify location of pid directory" << endl; cout << "-d run as daemon" << endl; cout << "-h help" << endl; @@ -70,12 +71,13 @@ static void sig_user(int signo) int main(int argc, char* argv[]) { int ch; + bool debug = false; bool config_debug_mode = false, daemon = false; string pid_path; string c_file; //grab inputs - while ((ch = getopt(argc, argv, "f:hti:d")) != -1) { + while ((ch = getopt(argc, argv, "f:hti:dv")) != -1) { switch (ch) { case 'f': c_file = optarg; @@ -86,11 +88,14 @@ int main(int argc, char* argv[]) case 't': config_debug_mode = true; break; + case 'i': + pid_path = optarg; + break; case 'd': daemon = true; break; - case 'i': - pid_path = optarg; + case 'v': + debug = true; break; default: usage(); @@ -115,7 +120,7 @@ int main(int argc, char* argv[]) pid_output(pid_path.c_str()); } - g_lb = new LoadBalance(); + g_lb = new LoadBalance(debug); bool success = g_lb->set_conf(c_file); if (success == false) { @@ -127,9 +132,9 @@ int main(int argc, char* argv[]) exit(0); } -#ifdef DEBUG - cout << "STARTING CYCLE" << endl; -#endif + if (debug) { + cout << "STARTING CYCLE" << endl; + } g_lb->init(); @@ -142,9 +147,9 @@ int main(int argc, char* argv[]) //drop into event loop do { -#ifdef DEBUG - cout << "main.cc: starting new cycle" << endl; -#endif + if (debug) { + cout << "main.cc: starting new cycle" << endl; + } //health test g_lb->health_test(); @@ -157,6 +162,11 @@ int main(int argc, char* argv[]) g_lb->sleep(); } while (g_lb->start_cycle()); + + if (g_lb) { + delete g_lb; + } + exit(0); } |
