Commit 429e5336 authored by Michael Ott's avatar Michael Ott
Browse files

Retrieve record from SDR cache only once on first read() for each sensor and...

Retrieve record from SDR cache only once on first read() for each sensor and close the cache file afterwards to reduce the number of open file handles
parent 100f868a
......@@ -105,15 +105,30 @@ void IPMIHost::checkConnection() {
}
}
void IPMIHost::createSdrCache() {
_sdrCtx = ipmi_sdr_ctx_create();
bool IPMIHost::openSdrCache() {
if (_sdrCtx) {
return true;
}
if (!(_sdrCtx = ipmi_sdr_ctx_create())) {
return false;
}
try {
checkConnection();
} catch (const std::runtime_error& e) {
increaseErrorCount();
throw e;
return false;
}
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) << "Deleting SDR cache " << _cache;
ipmi_sdr_cache_delete (_sdrCtx, _cache.c_str());
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) << "Created new SDR cache " << _cache;
......@@ -125,14 +140,14 @@ void IPMIHost::createSdrCache() {
if (ipmi_sdr_ctx_errnum (_sdrCtx) != IPMI_SDR_ERR_SUCCESS) {
errorMsg = ipmi_sdr_ctx_errormsg(_sdrCtx);
} else {
return;
return true;
}
destroySdrCache();
closeSdrCache();
throw std::runtime_error("ipmi_sdr_cache_open Error:" + errorMsg);
return;
return false;
}
void IPMIHost::destroySdrCache() {
void IPMIHost::closeSdrCache() {
if (_sdrCtx) {
ipmi_sdr_cache_close(_sdrCtx);
ipmi_sdr_ctx_destroy(_sdrCtx);
......@@ -142,6 +157,35 @@ void IPMIHost::destroySdrCache() {
return;
}
bool IPMIHost::getSdrRecord(uint16_t recordId, std::vector<uint8_t>& record) {
if (openSdrCache()) {
int recordLength = 0;
uint8_t recordBuf[IPMI_SDR_MAX_RECORD_LENGTH];
if (ipmi_sdr_cache_search_record_id(_sdrCtx, recordId) < 0) {
increaseErrorCount();
throw std::runtime_error("ipmi_sdr_cache_search_record_id() Error: " + std::string(ipmi_sdr_ctx_errormsg(_sdrCtx)));
closeSdrCache();
return false;
}
if ((recordLength = ipmi_sdr_cache_record_read(_sdrCtx, recordBuf, IPMI_SDR_MAX_RECORD_LENGTH)) < 0) {
increaseErrorCount();
throw std::runtime_error("ipmi_sdr_cache_record_read Error: " + std::string(ipmi_sdr_ctx_errormsg(_sdrCtx)));
closeSdrCache();
return false;
}
_lastRead = getTimestamp();
record.insert(record.end(), &recordBuf[0], &recordBuf[recordLength]);
closeSdrCache();
return true;
} else {
closeSdrCache();
return false;
}
}
uint64_t IPMIHost::sendRawCmd(const std::vector<uint8_t>& rawCmd,
uint16_t start, uint16_t stop) {
uint8_t buf[256];
......@@ -194,41 +238,24 @@ uint64_t IPMIHost::sendRawCmd(const std::vector<uint8_t>& rawCmd,
return val;
}
double IPMIHost::readSensor_recordId(uint16_t recordId) {
double IPMIHost::readSensorRecord(std::vector<uint8_t>& record) {
uint8_t rawReading = 0;
double *reading = NULL;
uint16_t eventBitmask = 0;
try {
checkConnection();
if (!_sensorReadCtx || !_sdrCtx) {
createSdrCache();
}
} catch (const std::runtime_error& e) {
increaseErrorCount();
throw e;
return 0;
}
if (!_sensorReadCtx) {
_sensorReadCtx = ipmi_sensor_read_ctx_create(_ipmiCtx);
}
int recordLength = 0;
uint8_t record[IPMI_SDR_MAX_RECORD_LENGTH];
uint8_t rawReading = 0;
double *reading = NULL;
uint16_t eventBitmask = 0;
if (ipmi_sdr_cache_search_record_id(_sdrCtx, recordId) < 0) {
increaseErrorCount();
throw std::runtime_error("ipmi_sdr_cache_search_record_id() Error: " + std::string(ipmi_sdr_ctx_errormsg(_sdrCtx)));
return 0;
}
if ((recordLength = ipmi_sdr_cache_record_read(_sdrCtx, record, IPMI_SDR_MAX_RECORD_LENGTH)) < 0) {
increaseErrorCount();
throw std::runtime_error("ipmi_sdr_cache_record_read Error: " + std::string(ipmi_sdr_ctx_errormsg(_sdrCtx)));
return 0;
}
if (ipmi_sensor_read(_sensorReadCtx, record, recordLength, 0, &rawReading, &reading, &eventBitmask) < 0) {
if (ipmi_sensor_read(_sensorReadCtx, &record[0], record.size(), 0, &rawReading, &reading, &eventBitmask) < 0) {
increaseErrorCount();
throw std::runtime_error("ipmi_sensor_read Error: " + std::string(ipmi_sensor_read_ctx_errormsg(_sensorReadCtx)));
return 0;
......
......@@ -25,7 +25,9 @@ namespace DCDB {
/* Send raw command to BMC. Returns sensor reading as responded by BMC. */
uint64_t sendRawCmd(const std::vector<uint8_t>& rawCmd, uint16_t start, uint16_t stop);
/* Read the sensor specified by its record id. Returns sensor reading. */
double readSensor_recordId(uint16_t recordId);
double readSensorRecord(std::vector<uint8_t>& record);
bool getSdrRecord(uint16_t recordId, std::vector<uint8_t>& record);
void increaseErrorCount();
const uint64_t getDelayFactor() const;
......@@ -112,9 +114,9 @@ namespace DCDB {
int disconnect();
void checkConnection() ;
/* Open and create/destroy SDR cache (sets/destroys _sdrCtx and _sensorReadCtx) */
void createSdrCache();
void destroySdrCache();
/* Open and create/destroy SDR cache (sets/destroys _sdrCtx) */
bool openSdrCache();
void closeSdrCache();
/* Various context structs, required to make use of FreeIPMI */
ipmi_ctx_t _ipmiCtx;
......
......@@ -41,7 +41,10 @@ namespace DCDB {
#endif
try {
if (_recordId != 0) { /* recordId was set */
reading.value = _host->readSensor_recordId(_recordId) * _factor;
if (_sdrRecord.size() == 0) {
_host->getSdrRecord(_recordId, _sdrRecord);
}
reading.value = _host->readSensorRecord(_sdrRecord) * _factor;
} else { /* use raw command */
reading.value = _host->sendRawCmd(_rawCmd, _start, _stop) * _factor;
}
......
......@@ -78,6 +78,7 @@ namespace DCDB {
private:
uint16_t _recordId;
std::vector<uint8_t> _sdrRecord;
double _factor;
std::vector<uint8_t> _rawCmd;
......
Supports Markdown
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