Commit e5c84bf2 authored by Michael Ott's avatar Michael Ott
Browse files

Handle connection errors in IPMIHost, delay re-connects

parent 92ce325f
......@@ -58,8 +58,9 @@ IPMIHost::IPMIHost(const std::string &name)
_ipmiVersion(1),
_sessionTimeout(0),
_retransmissionTimeout(0),
_xcc(nullptr) {
}
_xcc(nullptr),
_errorCount(0),
_nextConnectAfter(0) {}
IPMIHost::IPMIHost(const IPMIHost &other)
: EntityInterface(other),
......@@ -74,8 +75,9 @@ IPMIHost::IPMIHost(const IPMIHost &other)
_ipmiVersion(other._ipmiVersion),
_sessionTimeout(other._sessionTimeout),
_retransmissionTimeout(other._retransmissionTimeout),
_xcc(other._xcc) {
}
_xcc(other._xcc),
_errorCount(other._errorCount),
_nextConnectAfter(other._nextConnectAfter) {}
IPMIHost::~IPMIHost() {
if (_xcc != nullptr) {
......@@ -97,37 +99,57 @@ IPMIHost &IPMIHost::operator=(const IPMIHost &other) {
_sessionTimeout = other._sessionTimeout;
_retransmissionTimeout = other._retransmissionTimeout;
_xcc = other._xcc;
_errorCount = other._errorCount;
_nextConnectAfter = other._nextConnectAfter;
return *this;
}
int IPMIHost::connect() {
if (_ipmiCtx) {
return 0;
if (getTimestamp() < _nextConnectAfter) {
return 1;
}
if (!(_ipmiCtx = ipmi_ctx_create())) {
_errorCount++;
LOG(error) << _name << " Error creating IPMI context (" + std::string(strerror(errno)) + ")";
return 1;
}
int workaround_flags = 0;
int flags = IPMI_FLAGS_DEFAULT;
int rc;
if (_ipmiVersion == 1) {
rc = ipmi_ctx_open_outofband(_ipmiCtx, _name.c_str(), _userName.c_str(), _password.c_str(), _auth, _priv, _sessionTimeout, _retransmissionTimeout, workaround_flags, flags);
} else {
rc = ipmi_ctx_open_outofband_2_0(_ipmiCtx, _name.c_str(), _userName.c_str(), _password.c_str(), NULL, 0, _priv, _cipher, _sessionTimeout, _retransmissionTimeout, workaround_flags, flags);
int workaround_flags = 0;
int flags = IPMI_FLAGS_DEFAULT;
int rc;
if (_ipmiVersion == 1) {
rc = ipmi_ctx_open_outofband(_ipmiCtx, _name.c_str(), _userName.c_str(), _password.c_str(), _auth, _priv, _sessionTimeout, _retransmissionTimeout, workaround_flags, flags);
} else {
rc = ipmi_ctx_open_outofband_2_0(_ipmiCtx, _name.c_str(), _userName.c_str(), _password.c_str(), NULL, 0, _priv, _cipher, _sessionTimeout, _retransmissionTimeout, workaround_flags, flags);
}
if (rc < 0) {
_errorCount++;
LOG(error) << _name << " Error opening IPMI connection (" + std::string(ipmi_ctx_errormsg(_ipmiCtx)) + ")";
ipmi_ctx_close(_ipmiCtx);
ipmi_ctx_destroy(_ipmiCtx);
_ipmiCtx = NULL;
} else {
_errorCount = 0;
return 0;
}
}
if (rc < 0) {
LOG(error) << _name << " Error opening IPMI connection (" + std::string(ipmi_ctx_errormsg(_ipmiCtx)) + ")";
ipmi_ctx_close(_ipmiCtx);
ipmi_ctx_destroy(_ipmiCtx);
_ipmiCtx = NULL;
return 2;
/* There was an error, check whether we should delay the next connect */
uint64_t delay = 0;
if (_errorCount >= 50) {
delay = 600;
} else if (_errorCount >= 10) {
delay = 300;
} else if (_errorCount >= 5) {
delay = 60;
}
return 0;
if (delay > 0) {
LOG(debug) << _name << " Delaying next re-connect for " << delay << "s (errors=" << _errorCount << ")";
_nextConnectAfter = getTimestamp() + S_TO_NS(delay);
}
return 2;
}
int IPMIHost::disconnect() {
......
......@@ -102,6 +102,8 @@ class IPMIHost : public EntityInterface {
uint32_t _sessionTimeout;
uint32_t _retransmissionTimeout;
LenovoXCC* _xcc;
uint32_t _errorCount;
uint64_t _nextConnectAfter;
};
#endif /* IPMIHOST_H_ */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment