Commit 92ce325f authored by Michael Ott's avatar Michael Ott
Browse files

Remove error handling from IPMIHost and trigger connect and disconnect from IPMISensorGroup

parent 42dd81fc
......@@ -58,7 +58,6 @@ IPMIHost::IPMIHost(const std::string &name)
_ipmiVersion(1),
_sessionTimeout(0),
_retransmissionTimeout(0),
_errorCount(0),
_xcc(nullptr) {
}
......@@ -75,7 +74,6 @@ IPMIHost::IPMIHost(const IPMIHost &other)
_ipmiVersion(other._ipmiVersion),
_sessionTimeout(other._sessionTimeout),
_retransmissionTimeout(other._retransmissionTimeout),
_errorCount(0),
_xcc(other._xcc) {
}
......@@ -98,7 +96,6 @@ IPMIHost &IPMIHost::operator=(const IPMIHost &other) {
_ipmiVersion = other._ipmiVersion;
_sessionTimeout = other._sessionTimeout;
_retransmissionTimeout = other._retransmissionTimeout;
_errorCount = 0;
_xcc = other._xcc;
return *this;
......@@ -110,7 +107,7 @@ int IPMIHost::connect() {
}
if (!(_ipmiCtx = ipmi_ctx_create())) {
_errorMsg = "Error creating IPMI context" + std::string(strerror(errno));
LOG(error) << _name << " Error creating IPMI context (" + std::string(strerror(errno)) + ")";
return 1;
}
......@@ -123,7 +120,7 @@ int IPMIHost::connect() {
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) {
_errorMsg = "Error opening IPMI connection: " + std::string(ipmi_ctx_errormsg(_ipmiCtx));
LOG(error) << _name << " Error opening IPMI connection (" + std::string(ipmi_ctx_errormsg(_ipmiCtx)) + ")";
ipmi_ctx_close(_ipmiCtx);
ipmi_ctx_destroy(_ipmiCtx);
_ipmiCtx = NULL;
......@@ -148,100 +145,70 @@ int IPMIHost::disconnect() {
return 1;
}
bool IPMIHost::getSdrRecord(uint16_t recordId, std::vector<uint8_t> &record) {
void IPMIHost::getSdrRecord(uint16_t recordId, std::vector<uint8_t> &record) {
ipmi_sdr_ctx_t sdrCtx = ipmi_sdr_ctx_create();
if (!sdrCtx) {
throw std::runtime_error("Error creating SDR context: " + std::string(strerror(errno)));
return false;
throw std::runtime_error("Error creating SDR context (" + std::string(strerror(errno)) + ")");
}
bool success = false;
int retries = RETRIES;
while (retries-- && !success) {
if (connect() == 0) {
if (ipmi_sdr_cache_open(sdrCtx, _ipmiCtx, _cache.c_str()) < 0) {
if ((ipmi_sdr_ctx_errnum(sdrCtx) == IPMI_SDR_ERR_CACHE_READ_CACHE_DOES_NOT_EXIST) || (ipmi_sdr_ctx_errnum(sdrCtx) == IPMI_SDR_ERR_CACHE_INVALID) || (ipmi_sdr_ctx_errnum(sdrCtx) == IPMI_SDR_ERR_CACHE_OUT_OF_DATE)) {
if ((ipmi_sdr_ctx_errnum(sdrCtx) == IPMI_SDR_ERR_CACHE_INVALID) || (ipmi_sdr_ctx_errnum(sdrCtx) == IPMI_SDR_ERR_CACHE_OUT_OF_DATE)) {
LOG(debug) << _name << "Deleting SDR cache " << _cache;
ipmi_sdr_cache_close(sdrCtx);
ipmi_sdr_cache_delete(sdrCtx, _cache.c_str());
}
if (ipmi_sdr_cache_create(sdrCtx, _ipmiCtx, _cache.c_str(), IPMI_SDR_CACHE_CREATE_FLAGS_DEFAULT, NULL, NULL) == 0) {
LOG(debug) << _name << ": Created new SDR cache " << _cache;
} else {
LOG(debug) << _name << ": Error creating new SDR cache " << _cache;
}
} else {
_errorMsg = "Error opening SDR cache: " + std::string(ipmi_sdr_ctx_errormsg(sdrCtx));
disconnect();
}
} else {
int recordLength = 0;
uint8_t recordBuf[IPMI_SDR_MAX_RECORD_LENGTH];
if (ipmi_sdr_cache_search_record_id(sdrCtx, recordId) < 0) {
_errorMsg = "Error searching SDR record: " + std::string(ipmi_sdr_ctx_errormsg(sdrCtx));
} else {
if ((recordLength = ipmi_sdr_cache_record_read(sdrCtx, recordBuf, IPMI_SDR_MAX_RECORD_LENGTH)) < 0) {
_errorMsg = "Error reading SDR record: " + std::string(ipmi_sdr_ctx_errormsg(sdrCtx));
} else {
record.insert(record.end(), &recordBuf[0], &recordBuf[recordLength]);
success = true;
}
}
std::string errorMsg;
if (ipmi_sdr_cache_open(sdrCtx, _ipmiCtx, _cache.c_str()) < 0) {
if ((ipmi_sdr_ctx_errnum(sdrCtx) == IPMI_SDR_ERR_CACHE_READ_CACHE_DOES_NOT_EXIST) || (ipmi_sdr_ctx_errnum(sdrCtx) == IPMI_SDR_ERR_CACHE_INVALID) || (ipmi_sdr_ctx_errnum(sdrCtx) == IPMI_SDR_ERR_CACHE_OUT_OF_DATE)) {
if ((ipmi_sdr_ctx_errnum(sdrCtx) == IPMI_SDR_ERR_CACHE_INVALID) || (ipmi_sdr_ctx_errnum(sdrCtx) == IPMI_SDR_ERR_CACHE_OUT_OF_DATE)) {
LOG(debug) << _name << " Deleting SDR cache " << _cache;
ipmi_sdr_cache_close(sdrCtx);
ipmi_sdr_cache_delete(sdrCtx, _cache.c_str());
}
if (ipmi_sdr_cache_create(sdrCtx, _ipmiCtx, _cache.c_str(), IPMI_SDR_CACHE_CREATE_FLAGS_DEFAULT, NULL, NULL) == 0) {
LOG(debug) << _name << " Created new SDR cache " << _cache;
} else {
errorMsg = "Error creating new SDR cache " + _cache;
}
} else {
errorMsg = "Error opening SDR cache (" + std::string(ipmi_sdr_ctx_errormsg(sdrCtx)) + ")";
}
} else {
int recordLength = 0;
uint8_t recordBuf[IPMI_SDR_MAX_RECORD_LENGTH];
if (ipmi_sdr_cache_search_record_id(sdrCtx, recordId) < 0) {
errorMsg = "Error searching SDR record (" + std::string(ipmi_sdr_ctx_errormsg(sdrCtx)) + ")";
} else {
disconnect();
if ((recordLength = ipmi_sdr_cache_record_read(sdrCtx, recordBuf, IPMI_SDR_MAX_RECORD_LENGTH)) < 0) {
errorMsg = "Error reading SDR record (" + std::string(ipmi_sdr_ctx_errormsg(sdrCtx)) + ")";
} else {
record.insert(record.end(), &recordBuf[0], &recordBuf[recordLength]);
success = true;
}
}
ipmi_sdr_cache_close(sdrCtx);
}
ipmi_sdr_ctx_destroy(sdrCtx);
if (!success) {
throw std::runtime_error(_errorMsg);
throw std::runtime_error(errorMsg);
}
return success;
}
int IPMIHost::sendRawCmd(const uint8_t *rawCmd, unsigned int rawCmdLen, void *buf, unsigned int bufLen) {
int len = -1;
int i;
if (!IPMI_NET_FN_RQ_VALID(rawCmd[1])) {
throw std::runtime_error("Error sending raw IPMI command: Invalid netfn value");
return 0;
}
bool success = false;
int retries = RETRIES;
while (retries-- && !success) {
if (connect() == 0) {
if ((len = ipmi_cmd_raw(_ipmiCtx, rawCmd[0], rawCmd[1], &rawCmd[2], rawCmdLen - 2, buf, bufLen)) < 0) {
_errorMsg = "Error sending IPMI raw command: " + std::string(ipmi_ctx_errormsg(_ipmiCtx));
disconnect();
} else {
success = true;
}
} else {
disconnect();
}
throw std::runtime_error("Error sending IPMI raw command (Invalid netfn value)");
}
int len = -1;
if ((len = ipmi_cmd_raw(_ipmiCtx, rawCmd[0], rawCmd[1], &rawCmd[2], rawCmdLen - 2, buf, bufLen)) < 0) {
throw std::runtime_error("Error sending IPMI raw command (" + std::string(ipmi_ctx_errormsg(_ipmiCtx)) + ")");
} else {
#if 0
std::cout << "IPMIHost::sendRawCmd() received " << len << " bytes: " << std::setw(2) << std::setfill('0') << std::hex;
for (i = 0; i < len; i++) {
std::cout << (unsigned) buf[i] << " ";
}
std::cout << std::dec << std::endl;
std::cout << "IPMIHost::sendRawCmd() received " << len << " bytes: " << std::setw(2) << std::setfill('0') << std::hex;
for (i = 0; i < len; i++) {
std::cout << (unsigned) buf[i] << " ";
}
std::cout << std::dec << std::endl;
#endif
if (!success) {
throw std::runtime_error(_errorMsg);
return -1;
return len;
}
return len;
}
double IPMIHost::readSensorRecord(std::vector<uint8_t> &record) {
......@@ -249,38 +216,24 @@ double IPMIHost::readSensorRecord(std::vector<uint8_t> &record) {
double * reading = NULL;
uint16_t eventBitmask = 0;
bool success = false;
int retries = RETRIES;
while (retries-- && !success) {
if (connect() == 0) {
if (!_sensorReadCtx) {
_sensorReadCtx = ipmi_sensor_read_ctx_create(_ipmiCtx);
}
if (_sensorReadCtx) {
if (ipmi_sensor_read(_sensorReadCtx, &record[0], record.size(), 0, &rawReading, &reading, &eventBitmask) < 0) {
_errorMsg = "Error reading IPMI record: " + std::string(ipmi_sensor_read_ctx_errormsg(_sensorReadCtx));
disconnect();
} else {
success = true;
}
} else {
_errorMsg = "Error creating sensor context: " + std::string(ipmi_ctx_errormsg(_ipmiCtx));
}
if (!_sensorReadCtx) {
_sensorReadCtx = ipmi_sensor_read_ctx_create(_ipmiCtx);
}
if (_sensorReadCtx) {
if (ipmi_sensor_read(_sensorReadCtx, &record[0], record.size(), 0, &rawReading, &reading, &eventBitmask) < 0) {
throw std::runtime_error("Error reading IPMI record (" + std::string(ipmi_sensor_read_ctx_errormsg(_sensorReadCtx)) + ")");
} else {
disconnect();
double ret = .0;
if (reading) {
ret = *reading;
free(reading);
}
return ret;
}
}
double ret = .0;
if (success && reading) {
ret = *reading;
free(reading);
} else {
throw std::runtime_error(_errorMsg);
throw std::runtime_error("Error creating sensor context (" + std::string(ipmi_ctx_errormsg(_ipmiCtx)) + ")");
}
return ret;
}
void IPMIHost::printEntityConfig(LOG_LEVEL ll, unsigned int leadingSpaces) {
......
......@@ -48,8 +48,12 @@ class IPMIHost : public EntityInterface {
virtual ~IPMIHost();
IPMIHost &operator=(const IPMIHost &other);
/* Open/close connection to BMC (sets/destroys _ipmiCtx) */
int connect();
int disconnect();
/* Translate recordId to SDR record */
bool getSdrRecord(uint16_t recordId, std::vector<uint8_t> &record);
void getSdrRecord(uint16_t recordId, std::vector<uint8_t> &record);
/* Send raw command to BMC. Returns sensor reading as responded by BMC. */
int sendRawCmd(const uint8_t *rawCmd, unsigned int rawCmdLen, void *buf, unsigned int bufLen);
/* Read the sensor specified by its record id. Returns sensor reading. */
......@@ -80,10 +84,6 @@ class IPMIHost : public EntityInterface {
void printEntityConfig(LOG_LEVEL ll, unsigned int leadingSpaces) final override;
private:
/* Open/close connection to BMC (sets/destroys _ipmiCtx) */
int connect();
int disconnect();
/* Open and create/destroy SDR cache (sets/destroys _sdrCtx and _sensorReadCtx) */
void createSdrCache();
void destroySdrCache();
......@@ -101,8 +101,6 @@ class IPMIHost : public EntityInterface {
uint8_t _ipmiVersion;
uint32_t _sessionTimeout;
uint32_t _retransmissionTimeout;
uint32_t _errorCount;
std::string _errorMsg;
LenovoXCC* _xcc;
};
......
......@@ -111,72 +111,75 @@ void IPMISensorGroup::read() {
reading.value = 0;
reading.timestamp = getTimestamp();
for (const auto &s : _sensors) {
try {
switch (s->getType()) {
case IPMISensorBase::sensorType::xccDatastorePower: {
std::vector<reading_t> readings;
LenovoXCC xcc(_entity);
if (_entity->getXCC()->getDatastorePower(readings) == 0) {
for (unsigned int i=0; i<readings.size(); i++) {
s->storeReading(readings[i], s->getFactor());
if (_entity->connect() == 0) {
for (const auto &s : _sensors) {
try {
switch (s->getType()) {
case IPMISensorBase::sensorType::xccDatastorePower: {
std::vector<reading_t> readings;
LenovoXCC xcc(_entity);
if (_entity->getXCC()->getDatastorePower(readings) == 0) {
for (unsigned int i=0; i<readings.size(); i++) {
s->storeReading(readings[i], s->getFactor());
}
reading = readings.back();
}
reading = readings.back();
break;
}
break;
}
case IPMISensorBase::sensorType::xccSingleEnergy: {
if (_entity->getXCC()->getSingleEnergy(reading) == 0) {
s->storeReading(reading, s->getFactor());
case IPMISensorBase::sensorType::xccSingleEnergy: {
if (_entity->getXCC()->getSingleEnergy(reading) == 0) {
s->storeReading(reading, s->getFactor());
}
break;
}
break;
}
case IPMISensorBase::sensorType::xccBulkPower: {
std::vector<reading_t> readings;
if (_entity->getXCC()->getBulkPower(readings) == 0) {
for (unsigned int i=0; i<readings.size(); i++) {
s->storeReading(readings[i], s->getFactor());
case IPMISensorBase::sensorType::xccBulkPower: {
std::vector<reading_t> readings;
if (_entity->getXCC()->getBulkPower(readings) == 0) {
for (unsigned int i=0; i<readings.size(); i++) {
s->storeReading(readings[i], s->getFactor());
}
reading = readings.back();
}
reading = readings.back();
break;
}
break;
}
case IPMISensorBase::sensorType::xccBulkEnergy: {
std::vector<reading_t> readings;
if (_entity->getXCC()->getBulkEnergy(readings) == 0) {
for (unsigned int i=0; i<readings.size(); i++) {
s->storeReading(readings[i], s->getFactor());
case IPMISensorBase::sensorType::xccBulkEnergy: {
std::vector<reading_t> readings;
if (_entity->getXCC()->getBulkEnergy(readings) == 0) {
for (unsigned int i=0; i<readings.size(); i++) {
s->storeReading(readings[i], s->getFactor());
}
reading = readings.back();
}
reading = readings.back();
break;
}
break;
}
case IPMISensorBase::sensorType::sdr: {
std::vector<uint8_t> sdrRecord = s->getSdrRecord();
if (sdrRecord.size() == 0) {
_entity->getSdrRecord(s->getRecordId(), sdrRecord);
s->setSdrRecord(sdrRecord);
case IPMISensorBase::sensorType::sdr: {
std::vector<uint8_t> sdrRecord = s->getSdrRecord();
if (sdrRecord.size() == 0) {
_entity->getSdrRecord(s->getRecordId(), sdrRecord);
s->setSdrRecord(sdrRecord);
}
reading.value = _entity->readSensorRecord(sdrRecord);
s->storeReading(reading, s->getFactor());
break;
}
reading.value = _entity->readSensorRecord(sdrRecord);
s->storeReading(reading, s->getFactor());
break;
}
case IPMISensorBase::sensorType::raw: {
reading.value = readRaw(s->getRawCmd(), s->getLsb(), s->getMsb());
s->storeReading(reading, s->getFactor());
break;
case IPMISensorBase::sensorType::raw: {
reading.value = readRaw(s->getRawCmd(), s->getLsb(), s->getMsb());
s->storeReading(reading, s->getFactor());
break;
}
default:
LOG(error) << _groupName << "::" << s->getName() << " undefined sensor type";
break;
}
default:
LOG(error) << _groupName << "::" << s->getName() << " undefined sensor type";
break;
}
#ifdef DEBUG
LOG(debug) << s->getName() << " reading: ts=" << prettyPrintTimestamp(reading.timestamp) << " val=" << reading.value;
LOG(debug) << s->getName() << " reading: ts=" << prettyPrintTimestamp(reading.timestamp) << " val=" << reading.value;
#endif
} catch (const std::exception &e) {
LOG(error) << _groupName << "::" << s->getName() << " could not read value: " << e.what();
continue;
} catch (const std::exception &e) {
LOG(error) << _entity->getName() << " " << e.what() << ": " << s->getName();
continue;
}
}
_entity->disconnect();
}
}
......
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