mirror of
https://github.com/ipmitool/ipmitool.git
synced 2025-05-10 18:47:22 +00:00
add sdr_cache function, fix Get SDR Header to handle cancelled reservation
This commit is contained in:
parent
392454c646
commit
6052a2b57a
@ -79,6 +79,15 @@ int32_t utos(uint32_t val, int bits);
|
|||||||
#define SDR_SENSOR_STAT_HI_CR (1<<4)
|
#define SDR_SENSOR_STAT_HI_CR (1<<4)
|
||||||
#define SDR_SENSOR_STAT_HI_NR (1<<5)
|
#define SDR_SENSOR_STAT_HI_NR (1<<5)
|
||||||
|
|
||||||
|
#define READING_UNAVAILABLE 0x20
|
||||||
|
#define SCANNING_DISABLED 0x40
|
||||||
|
#define EVENTS_DISABLED 0x80
|
||||||
|
|
||||||
|
#define GET_SENSOR_READING 0x2d
|
||||||
|
#define GET_SENSOR_FACTORS 0x23
|
||||||
|
#define GET_SENSOR_THRES 0x27
|
||||||
|
#define GET_SENSOR_TYPE 0x2f
|
||||||
|
|
||||||
struct sdr_repo_info_rs {
|
struct sdr_repo_info_rs {
|
||||||
uint8_t version; /* SDR version (51h) */
|
uint8_t version; /* SDR version (51h) */
|
||||||
uint16_t count; /* number of records */
|
uint16_t count; /* number of records */
|
||||||
@ -624,5 +633,7 @@ struct sdr_record_list * ipmi_sdr_find_sdr_byid(struct ipmi_intf * intf, char *
|
|||||||
void ipmi_sdr_list_empty(struct ipmi_intf * intf);
|
void ipmi_sdr_list_empty(struct ipmi_intf * intf);
|
||||||
int ipmi_sdr_print_info(struct ipmi_intf * intf);
|
int ipmi_sdr_print_info(struct ipmi_intf * intf);
|
||||||
void ipmi_sdr_print_discrete_state(uint8_t sensor_type, uint8_t event_type, uint8_t state);
|
void ipmi_sdr_print_discrete_state(uint8_t sensor_type, uint8_t event_type, uint8_t state);
|
||||||
|
char * ipmi_sdr_get_unit_string(uint8_t type, uint8_t base, uint8_t modifier);
|
||||||
|
int ipmi_sdr_list_cache(struct ipmi_intf * intf);
|
||||||
|
|
||||||
#endif /* IPMI_SDR_H */
|
#endif /* IPMI_SDR_H */
|
||||||
|
@ -55,15 +55,6 @@
|
|||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define READING_UNAVAILABLE 0x20
|
|
||||||
#define SCANNING_DISABLED 0x40
|
|
||||||
#define EVENTS_DISABLED 0x80
|
|
||||||
|
|
||||||
#define GET_SENSOR_READING 0x2d
|
|
||||||
#define GET_SENSOR_FACTORS 0x23
|
|
||||||
#define GET_SENSOR_THRES 0x27
|
|
||||||
#define GET_SENSOR_TYPE 0x2f
|
|
||||||
|
|
||||||
extern int verbose;
|
extern int verbose;
|
||||||
static int sdr_max_read_len = GET_SDR_ENTIRE_RECORD;
|
static int sdr_max_read_len = GET_SDR_ENTIRE_RECORD;
|
||||||
|
|
||||||
@ -89,6 +80,33 @@ utos(uint32_t val, int bits)
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
ipmi_sdr_get_unit_string(uint8_t type, uint8_t base, uint8_t modifier)
|
||||||
|
{
|
||||||
|
static char unitstr[16];
|
||||||
|
|
||||||
|
memset(unitstr, 0, sizeof(unitstr));
|
||||||
|
switch (type) {
|
||||||
|
case 2:
|
||||||
|
snprintf(unitstr, sizeof(unitstr), "%s * %s",
|
||||||
|
unit_desc[base],
|
||||||
|
unit_desc[modifier]);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
snprintf(unitstr, sizeof(unitstr), "%s/%s",
|
||||||
|
unit_desc[base],
|
||||||
|
unit_desc[modifier]);
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
default:
|
||||||
|
snprintf(unitstr, sizeof(unitstr), "%s",
|
||||||
|
unit_desc[base]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return unitstr;
|
||||||
|
}
|
||||||
|
|
||||||
/* sdr_convert_sensor_reading - convert raw sensor reading
|
/* sdr_convert_sensor_reading - convert raw sensor reading
|
||||||
*
|
*
|
||||||
* @sensor: sensor record
|
* @sensor: sensor record
|
||||||
@ -270,24 +288,23 @@ ipmi_sdr_get_status(uint8_t stat)
|
|||||||
/* ipmi_sdr_get_header - retreive SDR record header
|
/* ipmi_sdr_get_header - retreive SDR record header
|
||||||
*
|
*
|
||||||
* @intf: ipmi interface
|
* @intf: ipmi interface
|
||||||
* @reserve_id: repository reservation id
|
* @itr: sdr iterator
|
||||||
* @record_id: sensor record id to retrieve
|
|
||||||
*
|
*
|
||||||
* returns pointer to static sensor retrieval struct
|
* returns pointer to static sensor retrieval struct
|
||||||
* returns NULL on error
|
* returns NULL on error
|
||||||
*/
|
*/
|
||||||
static struct sdr_get_rs *
|
static struct sdr_get_rs *
|
||||||
ipmi_sdr_get_header(struct ipmi_intf * intf, uint16_t reserve_id,
|
ipmi_sdr_get_header(struct ipmi_intf * intf, struct ipmi_sdr_iterator * itr)
|
||||||
uint16_t record_id)
|
|
||||||
{
|
{
|
||||||
struct ipmi_rq req;
|
struct ipmi_rq req;
|
||||||
struct ipmi_rs * rsp;
|
struct ipmi_rs * rsp;
|
||||||
struct sdr_get_rq sdr_rq;
|
struct sdr_get_rq sdr_rq;
|
||||||
static struct sdr_get_rs sdr_rs;
|
static struct sdr_get_rs sdr_rs;
|
||||||
|
int try = 0;
|
||||||
|
|
||||||
memset(&sdr_rq, 0, sizeof(sdr_rq));
|
memset(&sdr_rq, 0, sizeof(sdr_rq));
|
||||||
sdr_rq.reserve_id = reserve_id;
|
sdr_rq.reserve_id = itr->reservation;
|
||||||
sdr_rq.id = record_id;
|
sdr_rq.id = itr->next;
|
||||||
sdr_rq.offset = 0;
|
sdr_rq.offset = 0;
|
||||||
sdr_rq.length = 5; /* only get the header */
|
sdr_rq.length = 5; /* only get the header */
|
||||||
|
|
||||||
@ -297,24 +314,42 @@ ipmi_sdr_get_header(struct ipmi_intf * intf, uint16_t reserve_id,
|
|||||||
req.msg.data = (uint8_t *)&sdr_rq;
|
req.msg.data = (uint8_t *)&sdr_rq;
|
||||||
req.msg.data_len = sizeof(sdr_rq);
|
req.msg.data_len = sizeof(sdr_rq);
|
||||||
|
|
||||||
|
for (try=0; try<5; try++) {
|
||||||
|
sdr_rq.reserve_id = itr->reservation;
|
||||||
rsp = intf->sendrecv(intf, &req);
|
rsp = intf->sendrecv(intf, &req);
|
||||||
if (rsp == NULL) {
|
if (rsp == NULL) {
|
||||||
lprintf(LOG_ERR, "Get SDR %04x command failed", record_id);
|
lprintf(LOG_ERR, "Get SDR %04x command failed", itr->next);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (rsp->ccode > 0) {
|
else if (rsp->ccode == 0xc5) {
|
||||||
lprintf(LOG_ERR, "Get SDR %04x command failed: %s",
|
/* lost reservation */
|
||||||
record_id, val2str(rsp->ccode, completion_code_vals));
|
lprintf(LOG_DEBUG, "SDR reserveration %04x cancelled. "
|
||||||
|
"Sleeping a bit and retrying...", itr->reservation);
|
||||||
|
|
||||||
|
sleep(rand() & 3);
|
||||||
|
|
||||||
|
if (ipmi_sdr_get_reservation(intf, &(itr->reservation)) < 0) {
|
||||||
|
lprintf(LOG_ERR, "Unable to renew SDR reservation");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (rsp->ccode > 0) {
|
||||||
|
lprintf(LOG_ERR, "Get SDR %04x command failed: %s",
|
||||||
|
itr->next, val2str(rsp->ccode, completion_code_vals));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lprintf(LOG_DEBUG, "SDR record ID : 0x%04x", record_id);
|
lprintf(LOG_DEBUG, "SDR record ID : 0x%04x", itr->next);
|
||||||
|
|
||||||
memcpy(&sdr_rs, rsp->data, sizeof(sdr_rs));
|
memcpy(&sdr_rs, rsp->data, sizeof(sdr_rs));
|
||||||
|
|
||||||
if (sdr_rs.length == 0) {
|
if (sdr_rs.length == 0) {
|
||||||
lprintf(LOG_ERR, "SDR record id 0x%04x: invalid length %d",
|
lprintf(LOG_ERR, "SDR record id 0x%04x: invalid length %d",
|
||||||
record_id, sdr_rs.length);
|
itr->next, sdr_rs.length);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,10 +361,10 @@ ipmi_sdr_get_header(struct ipmi_intf * intf, uint16_t reserve_id,
|
|||||||
* completion code CBh = "Requested Sensor, data, or record
|
* completion code CBh = "Requested Sensor, data, or record
|
||||||
* not present"
|
* not present"
|
||||||
*/
|
*/
|
||||||
if (sdr_rs.id != record_id) {
|
if (sdr_rs.id != itr->next) {
|
||||||
lprintf(LOG_DEBUG, "SDR record id mismatch: 0x%04x",
|
lprintf(LOG_DEBUG, "SDR record id mismatch: 0x%04x",
|
||||||
sdr_rs.id);
|
sdr_rs.id);
|
||||||
sdr_rs.id = record_id;
|
sdr_rs.id = itr->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
lprintf(LOG_DEBUG, "SDR record type : 0x%02x", sdr_rs.type);
|
lprintf(LOG_DEBUG, "SDR record type : 0x%02x", sdr_rs.type);
|
||||||
@ -356,7 +391,7 @@ ipmi_sdr_get_next_header(struct ipmi_intf * intf,
|
|||||||
if (itr->next == 0xffff)
|
if (itr->next == 0xffff)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
header = ipmi_sdr_get_header(intf, itr->reservation, itr->next);
|
header = ipmi_sdr_get_header(intf, itr);
|
||||||
if (header == NULL)
|
if (header == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -1480,7 +1515,7 @@ ipmi_sdr_get_record(struct ipmi_intf * intf, struct sdr_get_rs * header,
|
|||||||
continue;
|
continue;
|
||||||
case 0xc5:
|
case 0xc5:
|
||||||
/* lost reservation */
|
/* lost reservation */
|
||||||
lprintf(LOG_DEBUG, "SDR reserveration canceled. "
|
lprintf(LOG_DEBUG, "SDR reserveration cancelled. "
|
||||||
"Sleeping a bit and retrying...");
|
"Sleeping a bit and retrying...");
|
||||||
|
|
||||||
sleep(rand() & 3);
|
sleep(rand() & 3);
|
||||||
@ -1977,6 +2012,76 @@ ipmi_sdr_find_sdr_byid(struct ipmi_intf * intf, char * id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ipmi_sdr_list_cache - generate SDR cache for fast lookup
|
||||||
|
*
|
||||||
|
* @intf: ipmi interface
|
||||||
|
*
|
||||||
|
* returns pointer to SDR list
|
||||||
|
* returns NULL on error
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
ipmi_sdr_list_cache(struct ipmi_intf * intf)
|
||||||
|
{
|
||||||
|
struct sdr_get_rs * header;
|
||||||
|
|
||||||
|
if (sdr_list_itr == NULL) {
|
||||||
|
sdr_list_itr = ipmi_sdr_start(intf);
|
||||||
|
if (sdr_list_itr == NULL) {
|
||||||
|
lprintf(LOG_ERR, "Unable to open SDR for reading");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((header = ipmi_sdr_get_next_header(intf, sdr_list_itr)) != NULL) {
|
||||||
|
uint8_t * rec;
|
||||||
|
struct sdr_record_list * sdrr;
|
||||||
|
|
||||||
|
sdrr = malloc(sizeof(struct sdr_record_list));
|
||||||
|
if (sdrr == NULL) {
|
||||||
|
lprintf(LOG_ERR, "ipmitool: malloc failure");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
memset(sdrr, 0, sizeof(struct sdr_record_list));
|
||||||
|
sdrr->id = header->id;
|
||||||
|
sdrr->type = header->type;
|
||||||
|
|
||||||
|
rec = ipmi_sdr_get_record(intf, header, sdr_list_itr);
|
||||||
|
if (rec == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (header->type) {
|
||||||
|
case SDR_RECORD_TYPE_FULL_SENSOR:
|
||||||
|
sdrr->record.full = (struct sdr_record_full_sensor *)rec;
|
||||||
|
break;
|
||||||
|
case SDR_RECORD_TYPE_COMPACT_SENSOR:
|
||||||
|
sdrr->record.compact = (struct sdr_record_compact_sensor *)rec;
|
||||||
|
break;
|
||||||
|
case SDR_RECORD_TYPE_EVENTONLY_SENSOR:
|
||||||
|
sdrr->record.eventonly = (struct sdr_record_eventonly_sensor *)rec;
|
||||||
|
break;
|
||||||
|
case SDR_RECORD_TYPE_FRU_DEVICE_LOCATOR:
|
||||||
|
sdrr->record.fruloc = (struct sdr_record_fru_locator *)rec;
|
||||||
|
break;
|
||||||
|
case SDR_RECORD_TYPE_MC_DEVICE_LOCATOR:
|
||||||
|
sdrr->record.mcloc = (struct sdr_record_mc_locator *)rec;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
free(rec);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add to global record liset */
|
||||||
|
if (sdr_list_head == NULL)
|
||||||
|
sdr_list_head = sdrr;
|
||||||
|
else
|
||||||
|
sdr_list_tail->next = sdrr;
|
||||||
|
|
||||||
|
sdr_list_tail = sdrr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ipmi_sdr_get_info
|
* ipmi_sdr_get_info
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user