diff --git a/ipmitool/lib/ipmi_sdr.c b/ipmitool/lib/ipmi_sdr.c index 7d18397..eb105f7 100644 --- a/ipmitool/lib/ipmi_sdr.c +++ b/ipmitool/lib/ipmi_sdr.c @@ -154,368 +154,229 @@ ipmi_sdr_get_header(struct ipmi_intf * intf, unsigned short reserve_id, unsigned return &sdr_rs; } -static struct sdr_record_compact_sensor * -ipmi_sdr_get_entry_02(struct ipmi_intf * intf, unsigned short reserve_id, unsigned short record_id, int len) +struct sdr_get_rs * +ipmi_sdr_get_next_header(struct ipmi_intf * intf, struct ipmi_sdr_iterator * itr) { - struct ipmi_rq req; - struct ipmi_rs * rsp; - struct sdr_get_rq sdr_rq; - struct sdr_record_compact_sensor * sensor; - unsigned char data[256]; - int i; + struct sdr_get_rs *header; - memset(&sdr_rq, 0, sizeof(sdr_rq)); - sdr_rq.reserve_id = reserve_id; - sdr_rq.id = record_id; - sdr_rq.offset = 0; + if (itr->next >= itr->total) + return NULL; - memset(&req, 0, sizeof(req)); - req.msg.netfn = IPMI_NETFN_STORAGE; - req.msg.cmd = GET_SDR; - req.msg.data = (unsigned char *)&sdr_rq; - req.msg.data_len = sizeof(sdr_rq); + if (!(header = ipmi_sdr_get_header(intf, itr->reservation, itr->next))) + return NULL; - /* read SDR record with partial (30 byte) reads - * because a full read (0xff) exceeds the maximum - * transport buffer size. (completion code 0xca) - */ - memset(data, 0, sizeof(data)); - for (i=0; i 1) - printf("getting %d bytes from SDR at offset %d\n", - sdr_rq.length, sdr_rq.offset); - rsp = intf->sendrecv(intf, &req); - if (rsp && rsp->data) - memcpy(data+i, rsp->data+2, sdr_rq.length); - } + itr->next = header->next; - sensor = malloc(sizeof(*sensor)); - memcpy(sensor, data, sizeof(*sensor)); - - if (verbose > 1) { - printbuf(data, len, "SDR Entry"); - - printf("keys.owner_id: 0x%x\n", sensor->keys.owner_id); - printf("keys.lun: 0x%x\n", sensor->keys.lun); - printf("keys.channel: 0x%x\n", sensor->keys.channel); - printf("keys.sensor_num: 0x%x\n", sensor->keys.sensor_num); - - printf("entity: %d.%d\n", sensor->entity.id, sensor->entity.instance); - - printf("entity.id: %s\n", val2str(sensor->entity.id, entity_id_vals)); - printf("entity.instance: %d\n", sensor->entity.instance); - printf("entity.logical: %d\n", sensor->entity.logical); - - printf("sensor unit.pct: 0x%x\n", sensor->unit.pct); - printf("sensor unit.rate: 0x%x\n", sensor->unit.rate); - printf("sensor unit.analog: 0x%x\n", sensor->unit.analog); - printf("sensor unit.modifier: 0x%x\n", sensor->unit.modifier); - printf("sensor unit.type.base: 0x%x\n", sensor->unit.type.base); - printf("sensor unit.type.modifier: 0x%x\n", sensor->unit.type.modifier); - - printf("sensor.type: 0x%02x\n", sensor->sensor.type); - printf("event_type: 0x%02x\n", sensor->event_type); - - printf("sensor id code: 0x%x\n", sensor->id_code); - - if (sensor->id_code) - printf("sensor id: %s\n", sensor->id_string); - } - - return sensor; -} - -static struct sdr_record_full_sensor * -ipmi_sdr_get_entry_01(struct ipmi_intf * intf, unsigned short reserve_id, unsigned short record_id, int len) -{ - struct ipmi_rq req; - struct ipmi_rs * rsp; - struct sdr_get_rq sdr_rq; - struct sdr_record_full_sensor * sensor; - unsigned char data[256]; - int i; - - memset(&sdr_rq, 0, sizeof(sdr_rq)); - sdr_rq.reserve_id = reserve_id; - sdr_rq.id = record_id; - sdr_rq.offset = 0; - - memset(&req, 0, sizeof(req)); - req.msg.netfn = IPMI_NETFN_STORAGE; - req.msg.cmd = GET_SDR; - req.msg.data = (unsigned char *)&sdr_rq; - req.msg.data_len = sizeof(sdr_rq); - - /* read SDR record with partial (30 byte) reads - * because a full read (0xff) exceeds the maximum - * transport buffer size. (completion code 0xca) - */ - memset(data, 0, sizeof(data)); - for (i=0; i 1) - printf("getting %d bytes from SDR at offset %d\n", - sdr_rq.length, sdr_rq.offset); - rsp = intf->sendrecv(intf, &req); - if (rsp && rsp->data) - memcpy(data+i, rsp->data+2, sdr_rq.length); - } - - sensor = malloc(sizeof(*sensor)); - memcpy(sensor, data, sizeof(*sensor)); - - if (verbose > 1) { - printbuf(data, len, "SDR Entry"); - - printf("keys.owner_id: 0x%x\n", sensor->keys.owner_id); - printf("keys.lun: 0x%x\n", sensor->keys.lun); - printf("keys.channel: 0x%x\n", sensor->keys.channel); - printf("keys.sensor_num: 0x%x\n", sensor->keys.sensor_num); - - printf("entity: %d.%d\n", sensor->entity.id, sensor->entity.instance); - - printf("entity.id: %s\n", val2str(sensor->entity.id, entity_id_vals)); - printf("entity.instance: %d\n", sensor->entity.instance); - printf("entity.logical: %d\n", sensor->entity.logical); - - printf("sensor unit.pct: 0x%x\n", sensor->unit.pct); - printf("sensor unit.rate: 0x%x\n", sensor->unit.rate); - printf("sensor unit.analog: 0x%x\n", sensor->unit.analog); - printf("sensor unit.modifier: 0x%x\n", sensor->unit.modifier); - printf("sensor unit.type.base: 0x%x\n", sensor->unit.type.base); - printf("sensor unit.type.modifier: 0x%x\n", sensor->unit.type.modifier); - - printf("sensor linearization: 0x%x\n", sensor->linearization); - - printf("sensor tolerance: 0x%x\n", __TO_TOL(sensor->mtol)); - printf("sensor M: 0x%x\n", __TO_M(sensor->mtol)); - printf("sensor B: 0x%x\n", __TO_B(sensor->bacc)); - printf("sensor B exp: %d\n", __TO_B_EXP(sensor->bacc)); - printf("sensor R exp: %d\n", __TO_R_EXP(sensor->bacc)); - printf("sensor accuracy: 0x%x\n", __TO_ACC(sensor->bacc)); - printf("sensor accuracy exp: 0x%x\n", __TO_ACC_EXP(sensor->bacc)); - - printf("sensor.type: 0x%02x\n", sensor->sensor.type); - printf("event_type: 0x%02x\n", sensor->event_type); - - printf("sensor min=0x%x max=0x%x\n", sensor->sensor_min, sensor->sensor_max); - printf("sensor id code: 0x%x\n", sensor->id_code); - - printf("Nominal Reading : %.3f\n", - sdr_convert_sensor_reading(sensor, sensor->nominal_read)); - printf("Normal Minimum Reading : %.3f\n", - sdr_convert_sensor_reading(sensor, sensor->normal_min)); - printf("Normal Maximum Reading : %.3f\n", - sdr_convert_sensor_reading(sensor, sensor->normal_max)); - printf("Upper non-recoverable Threshold : %.3f\n", - sdr_convert_sensor_reading(sensor, sensor->threshold.upper.non_recover)); - printf("Upper critical Threshold : %.3f\n", - sdr_convert_sensor_reading(sensor, sensor->threshold.upper.critical)); - printf("Upper non-critical Threshold : %.3f\n", - sdr_convert_sensor_reading(sensor, sensor->threshold.upper.non_critical)); - printf("Lower non-recoverable Threshold : %.3f\n", - sdr_convert_sensor_reading(sensor, sensor->threshold.lower.non_recover)); - printf("Lower critical Threshold : %.3f\n", - sdr_convert_sensor_reading(sensor, sensor->threshold.lower.critical)); - printf("Lower non-critical Threshold : %.3f\n", - sdr_convert_sensor_reading(sensor, sensor->threshold.lower.non_critical)); - - if (sensor->id_code) - printf("sensor id: %s\n", sensor->id_string); - } - - return sensor; + return header; } static void -ipmi_sdr_print_sensors(struct ipmi_intf * intf, int do_unit) +ipmi_sdr_print_sensor_compact(struct ipmi_intf * intf, + struct sdr_record_compact_sensor * sensor) { - struct ipmi_rs * rsp; - struct ipmi_rq req; - struct sdr_repo_info_rs sdr_info; - struct sdr_reserve_repo_rs sdr_reserve; - struct sdr_get_rs * header; - struct sdr_record_full_sensor * sensor; - - int next = 0, i = 0, total, validread; - unsigned short reservation; - float val; - char sval[16], unitstr[16]; char desc[17]; - if (verbose) + if (!sensor) + return; + + memset(desc, 0, sizeof(desc)); + memcpy(desc, sensor->id_string, 16); + + if (verbose) { + printf("Sensor ID : %s (0x%x)\n", + sensor->id_code ? desc : NULL, sensor->keys.sensor_num); + printf("Entity ID : %d.%d (%s)\n", + sensor->entity.id, sensor->entity.instance, + val2str(sensor->entity.id, entity_id_vals)); + + if (verbose > 1) { + printf("sensor unit.pct: 0x%x\n", sensor->unit.pct); + printf("sensor unit.rate: 0x%x\n", sensor->unit.rate); + printf("sensor unit.analog: 0x%x\n", sensor->unit.analog); + printf("sensor unit.modifier: 0x%x\n", sensor->unit.modifier); + printf("sensor unit.type.base: 0x%x\n", sensor->unit.type.base); + printf("sensor unit.type.modifier: 0x%x\n", sensor->unit.type.modifier); + printf("sensor.type: 0x%02x\n", sensor->sensor.type); + printf("event_type: 0x%02x\n", sensor->event_type); + } + + printf("\n"); + } +} + +static void +ipmi_sdr_print_sensor_full(struct ipmi_intf * intf, + struct sdr_record_full_sensor * sensor) +{ + char sval[16], unitstr[16], desc[17]; + int i=0, validread=1, do_unit=1; + float val; + struct ipmi_rs * rsp; + + if (!sensor) + return; + + /* only handle linear sensors (for now) */ + if (sensor->linearization) { + printf("non-linear!\n"); + return; + } + + memset(desc, 0, sizeof(desc)); + memcpy(desc, sensor->id_string, 16); + + rsp = ipmi_sdr_get_sensor_reading(intf, sensor->keys.sensor_num); + if (!rsp || rsp->ccode) { + if (rsp && rsp->ccode == 0xcb) { + /* sensor not found */ + val = 0.0; + validread = 0; + } else { + printf("Error reading sensor: %s\n", + val2str(rsp->ccode, completion_code_vals)); + return; + } + } else { + /* convert RAW reading into units */ + val = rsp->data[0] ? sdr_convert_sensor_reading(sensor, rsp->data[0]) : 0; + } + + if (do_unit && validread) { + memset(unitstr, 0, sizeof(unitstr)); + /* determine units with possible modifiers */ + switch (sensor->unit.modifier) { + case 2: + i += snprintf(unitstr, sizeof(unitstr), "%s * %s", + unit_desc[sensor->unit.type.base], + unit_desc[sensor->unit.type.modifier]); + break; + case 1: + i += snprintf(unitstr, sizeof(unitstr), "%s/%s", + unit_desc[sensor->unit.type.base], + unit_desc[sensor->unit.type.modifier]); + break; + case 0: + default: + i += snprintf(unitstr, sizeof(unitstr), "%s", + unit_desc[sensor->unit.type.base]); + break; + } + } + + if (!verbose) { + /* + * print sensor name, reading, state + */ + if (csv_output) + printf("%s,", + sensor->id_code ? desc : NULL); + else + printf("%-16s | ", + sensor->id_code ? desc : NULL); + + memset(sval, 0, sizeof(sval)); + if (validread) { + i += snprintf(sval, sizeof(sval), "%.*f", + (val==(int)val) ? 0 : 3, val); + } else { + i += snprintf(sval, sizeof(sval), "no reading"); + i--; + } + printf("%s", sval); + + if (csv_output) + printf(","); + + if (validread) { + if (!csv_output) + printf(" "); + if (do_unit) + printf("%s", unitstr); + } + + if (csv_output) + printf(","); + else { + for (; idata[2])); + printf("\n"); + } + else { + printf("Sensor ID : %s (0x%x)\n", + sensor->id_code ? desc : NULL, sensor->keys.sensor_num); + printf("Entity ID : %d.%d (%s)\n", + sensor->entity.id, sensor->entity.instance, + val2str(sensor->entity.id, entity_id_vals)); + + printf("Sensor Reading : "); + if (validread) + printf("%.*f %s\n", (val==(int)val) ? 0 : 3, val, unitstr); + else + printf("not present\n"); + + printf("Status : %s\n", + ipmi_sdr_get_status(rsp->data[2])); + + printf("Nominal Reading : %.3f\n", + sdr_convert_sensor_reading(sensor, sensor->nominal_read)); + printf("Normal Minimum : %.3f\n", + sdr_convert_sensor_reading(sensor, sensor->normal_min)); + printf("Normal Maximum : %.3f\n", + sdr_convert_sensor_reading(sensor, sensor->normal_max)); + + printf("Upper non-recoverable : %.3f\n", + sdr_convert_sensor_reading(sensor, sensor->threshold.upper.non_recover)); + printf("Upper critical : %.3f\n", + sdr_convert_sensor_reading(sensor, sensor->threshold.upper.critical)); + printf("Upper non-critical : %.3f\n", + sdr_convert_sensor_reading(sensor, sensor->threshold.upper.non_critical)); + printf("Lower non-recoverable : %.3f\n", + sdr_convert_sensor_reading(sensor, sensor->threshold.lower.non_recover)); + printf("Lower critical : %.3f\n", + sdr_convert_sensor_reading(sensor, sensor->threshold.lower.critical)); + printf("Lower non-critical : %.3f\n", + sdr_convert_sensor_reading(sensor, sensor->threshold.lower.non_critical)); + printf("\n"); + } +} + +static void +ipmi_sdr_print_sensors(struct ipmi_intf * intf) +{ + struct sdr_get_rs * header; + struct ipmi_sdr_iterator * itr; + + if (verbose > 1) printf("Querying SDR for sensor list\n"); - /* get sdr repository info */ - memset(&req, 0, sizeof(req)); - req.msg.netfn = IPMI_NETFN_STORAGE; - req.msg.cmd = GET_SDR_REPO_INFO; - - rsp = intf->sendrecv(intf, &req); - if (!rsp || !rsp->data_len) - return; - memcpy(&sdr_info, rsp->data, sizeof(sdr_info)); - - /* byte 1 is SDR version, should be 51h */ - if (sdr_info.version != 0x51) { - printf("SDR repository version mismatch!\n"); + itr = ipmi_sdr_start(intf); + if (!itr) { + printf("Unable to open SDR for reading\n"); return; } - total = sdr_info.count; - if (verbose > 1) { - printf("SDR free space: %d\n", sdr_info.free); - printf("SDR records: %d\n", total); - } - /* obtain reservation ID */ - memset(&req, 0, sizeof(req)); - req.msg.netfn = IPMI_NETFN_STORAGE; - req.msg.cmd = GET_SDR_RESERVE_REPO; - rsp = intf->sendrecv(intf, &req); - if (!rsp || !rsp->data_len) - return; - memcpy(&sdr_reserve, rsp->data, sizeof(sdr_reserve)); - reservation = sdr_reserve.reserve_id; - if (verbose > 1) - printf("SDR reserveration ID %04x\n", reservation); - - while (next < total) { - validread = 1; - i = 0; - - header = ipmi_sdr_get_header(intf, reservation, next); - if (!header) + while (header = ipmi_sdr_get_next_header(intf, itr)) { + unsigned char * rec = ipmi_sdr_get_record(intf, header, itr); + if (!rec) + continue; + switch (header->type) { + case SDR_RECORD_TYPE_FULL_SENSOR: + ipmi_sdr_print_sensor_full(intf, + (struct sdr_record_full_sensor *) rec); + break; + case SDR_RECORD_TYPE_COMPACT_SENSOR: + ipmi_sdr_print_sensor_compact(intf, + (struct sdr_record_compact_sensor *) rec); break; - - if (header->type == SDR_RECORD_TYPE_COMPACT_SENSOR) { - struct sdr_record_compact_sensor * s; - s = ipmi_sdr_get_entry_02(intf, reservation, next, header->length); - next = header->next; - free(s); - continue; } - - if (header->type != SDR_RECORD_TYPE_FULL_SENSOR) { - if (verbose > 1) - printf("Invalid SDR type 0x%02x\n", header->type); - next = header->next; - continue; - } - - sensor = ipmi_sdr_get_entry_01(intf, reservation, next, header->length); - next = header->next; - - /* only handle linear sensors (for now) */ - if (sensor->linearization) { - printf("non-linear!\n"); - continue; - } - - memset(desc, 0, sizeof(desc)); - memcpy(desc, sensor->id_string, 16); - - rsp = ipmi_sdr_get_sensor_reading(intf, sensor->keys.sensor_num); - if (!rsp || rsp->ccode) { - if (rsp && rsp->ccode == 0xcb) { - /* sensor not found */ - val = 0.0; - validread = 0; - } else { - printf("Error reading sensor: %s\n", - val2str(rsp->ccode, completion_code_vals)); - continue; - } - } else { - /* convert RAW reading into units */ - val = rsp->data[0] ? sdr_convert_sensor_reading(sensor, rsp->data[0]) : 0; - } - - if (do_unit && validread) { - memset(unitstr, 0, sizeof(unitstr)); - /* determine units with possible modifiers */ - switch (sensor->unit.modifier) { - case 2: - i += snprintf(unitstr, sizeof(unitstr), "%s * %s", - unit_desc[sensor->unit.type.base], - unit_desc[sensor->unit.type.modifier]); - break; - case 1: - i += snprintf(unitstr, sizeof(unitstr), "%s/%s", - unit_desc[sensor->unit.type.base], - unit_desc[sensor->unit.type.modifier]); - break; - case 0: - default: - i += snprintf(unitstr, sizeof(unitstr), "%s", - unit_desc[sensor->unit.type.base]); - break; - } - } - - if (!verbose) { - /* - * print sensor name, reading, state - */ - if (csv_output) - printf("%s,", - sensor->id_code ? desc : NULL); - else - printf("%-16s | ", - sensor->id_code ? desc : NULL); - - memset(sval, 0, sizeof(sval)); - if (validread) { - i += snprintf(sval, sizeof(sval), "%.*f", - (val==(int)val) ? 0 : 3, val); - } else { - i += snprintf(sval, sizeof(sval), "no reading"); - i--; - } - printf("%s", sval); - - if (csv_output) - printf(","); - - if (validread) { - if (!csv_output) - printf(" "); - if (do_unit) - printf("%s", unitstr); - } - - if (csv_output) - printf(","); - else { - for (; idata[2])); - printf("\n"); - } - else { - printf("Sensor | %s (0x%x)\n", - sensor->id_code ? desc : NULL, - sensor->keys.sensor_num); - printf("Entity | %d.%d (%s)\n", - sensor->entity.id, sensor->entity.instance, - val2str(sensor->entity.id, entity_id_vals)); - if (validread) - printf("Reading | %.*f %s\n", - (val==(int)val) ? 0 : 3, val, unitstr); - else - printf("Reading | not present\n"); - printf("Status | %s\n", - ipmi_sdr_get_status(rsp->data[2])); - printf("\n"); - } - - free(sensor); + free(rec); } + + ipmi_sdr_end(intf, itr); } struct ipmi_sdr_iterator * @@ -576,35 +437,19 @@ ipmi_sdr_start(struct ipmi_intf * intf) return itr; } -struct sdr_get_rs * -ipmi_sdr_get_next_header(struct ipmi_intf * intf, struct ipmi_sdr_iterator * itr) -{ - struct sdr_get_rs *header; - - if (itr->next >= itr->total) - return NULL; - - if (!(header = ipmi_sdr_get_header(intf, itr->reservation, itr->next))) - return NULL; - - itr->next = header->next; - - return (header); -} - unsigned char * -ipmi_sdr_get_record(struct ipmi_intf * intf, struct sdr_get_rs * header, struct ipmi_sdr_iterator * itr) +ipmi_sdr_get_record(struct ipmi_intf * intf, struct sdr_get_rs * header, + struct ipmi_sdr_iterator * itr) { struct ipmi_rq req; struct ipmi_rs * rsp; struct sdr_get_rq sdr_rq; - struct sdr_record_compact_sensor * sensor; unsigned char * data; - int i, len; + int i, len = header->length; - - if (!(data = malloc (header->length))) + if (!(data = malloc(len+1))) return NULL; + memset(data, 0, len+1); memset(&sdr_rq, 0, sizeof(sdr_rq)); sdr_rq.reserve_id = itr->reservation; @@ -617,13 +462,10 @@ ipmi_sdr_get_record(struct ipmi_intf * intf, struct sdr_get_rs * header, struct req.msg.data = (unsigned char *)&sdr_rq; req.msg.data_len = sizeof(sdr_rq); - len = header->length; - /* read SDR record with partial (30 byte) reads * because a full read (0xff) exceeds the maximum * transport buffer size. (completion code 0xca) */ - memset(data, 0, sizeof(data)); for (i=0; i