mirror of
https://github.com/ipmitool/ipmitool.git
synced 2025-05-11 19:17:22 +00:00
add new "dump" command to dump the entire sdr to a binary file
relax version check to try and support IPMIv1.0 SDRs
This commit is contained in:
parent
4f9cbb3f38
commit
4d8ec39062
@ -37,6 +37,13 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include <ipmitool/ipmi.h>
|
#include <ipmitool/ipmi.h>
|
||||||
#include <ipmitool/ipmi_sdr.h>
|
#include <ipmitool/ipmi_sdr.h>
|
||||||
#include <ipmitool/ipmi_intf.h>
|
#include <ipmitool/ipmi_intf.h>
|
||||||
@ -321,14 +328,13 @@ void ipmi_sdr_print_sensor_full(struct ipmi_intf * intf,
|
|||||||
*/
|
*/
|
||||||
printf("%s,", sensor->id_code ? desc : NULL);
|
printf("%s,", sensor->id_code ? desc : NULL);
|
||||||
|
|
||||||
if (validread)
|
if (validread) {
|
||||||
printf("%.*f,", (val==(int)val) ? 0 : 3, val);
|
printf("%.*f,", (val==(int)val) ? 0 : 3, val);
|
||||||
else
|
printf("%s,%s", do_unit ? unitstr : "",
|
||||||
printf(",");
|
ipmi_sdr_get_status(rsp->data[2]));
|
||||||
|
} else
|
||||||
|
printf(",,%s", ipmi_sdr_get_status(rsp->data[2]));
|
||||||
|
|
||||||
printf("%s,%s",
|
|
||||||
do_unit ? unitstr : "",
|
|
||||||
ipmi_sdr_get_status(rsp->data[2]));
|
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
{
|
{
|
||||||
@ -538,8 +544,16 @@ void ipmi_sdr_print_sensor_compact(struct ipmi_intf * intf,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rsp->ccode && (!(rsp->data[1] & 0x80)))
|
if (rsp->ccode) {
|
||||||
|
if (verbose > 1)
|
||||||
|
printf("Invalid ccode: %x\n", rsp->ccode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!(rsp->data[1] & 0x80)) {
|
||||||
|
if (verbose > 1)
|
||||||
|
printf("Sensor %x scanning disabled\n", sensor->keys.sensor_num);
|
||||||
return; /* sensor scanning disabled */
|
return; /* sensor scanning disabled */
|
||||||
|
}
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
printf("Sensor ID : %s (0x%x)\n",
|
printf("Sensor ID : %s (0x%x)\n",
|
||||||
@ -576,7 +590,7 @@ void ipmi_sdr_print_sensor_compact(struct ipmi_intf * intf,
|
|||||||
char temp[18];
|
char temp[18];
|
||||||
|
|
||||||
if ((rsp->ccode == 0xcd) || (rsp->data[1] & READING_UNAVAILABLE)) {
|
if ((rsp->ccode == 0xcd) || (rsp->data[1] & READING_UNAVAILABLE)) {
|
||||||
state = "Not Readable ";
|
state = csv_output ? "Not Readable" : "Not Readable ";
|
||||||
} else {
|
} else {
|
||||||
switch (sensor->sensor.type) {
|
switch (sensor->sensor.type) {
|
||||||
case 0x07: /* processor */
|
case 0x07: /* processor */
|
||||||
@ -659,7 +673,7 @@ void ipmi_sdr_print_sensor_eventonly(struct ipmi_intf * intf,
|
|||||||
else {
|
else {
|
||||||
char * state = "Event-Only ";
|
char * state = "Event-Only ";
|
||||||
if (csv_output)
|
if (csv_output)
|
||||||
printf("%s,%s,ns", sensor->id_code ? desc : NULL, state);
|
printf("%s,Event-Only,ns\n", sensor->id_code ? desc : NULL);
|
||||||
else
|
else
|
||||||
printf("%-16s | %-17s | ns\n", sensor->id_code ? desc : NULL, state);
|
printf("%-16s | %-17s | ns\n", sensor->id_code ? desc : NULL, state);
|
||||||
}
|
}
|
||||||
@ -784,6 +798,74 @@ void ipmi_sdr_print_fru_locator(struct ipmi_intf * intf,
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void ipmi_sdr_print_oem(struct ipmi_intf * intf, unsigned char * data, int len)
|
||||||
|
{
|
||||||
|
if (verbose > 2)
|
||||||
|
printbuf(data, len, "OEM Record");
|
||||||
|
|
||||||
|
/* intel manufacturer id */
|
||||||
|
if (data[0] == 0x57 && data[1] == 0x01 && data[2] == 0x00) {
|
||||||
|
switch (data[3]) { /* record sub-type */
|
||||||
|
case 0x02: /* Power Unit Map */
|
||||||
|
if (verbose) {
|
||||||
|
printf("Sensor ID : Power Unit Redundancy (0x%x)\n",
|
||||||
|
data[4]);
|
||||||
|
printf("Sensor Type : Intel OEM - Power Unit Map\n");
|
||||||
|
printf("Redundant Supplies : %d", data[6]);
|
||||||
|
if (data[5])
|
||||||
|
printf(" (flags %xh)", data[5]);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (len) {
|
||||||
|
case 7: /* SR1300, non-redundant */
|
||||||
|
if (verbose)
|
||||||
|
printf("Power Redundancy : No\n");
|
||||||
|
else if (csv_output)
|
||||||
|
printf("Power Redundancy,Not Available,nr\n");
|
||||||
|
else
|
||||||
|
printf("Power Redundancy | Not Available | nr\n");
|
||||||
|
break;
|
||||||
|
case 8: /* SR2300, redundant, PS1 & PS2 present */
|
||||||
|
if (verbose) {
|
||||||
|
printf("Power Redundancy : No\n");
|
||||||
|
printf("Power Supply 2 Sensor : %x\n", data[8]);
|
||||||
|
} else if (csv_output) {
|
||||||
|
printf("Power Redundancy,PS@%02xh,nr\n", data[8]);
|
||||||
|
} else {
|
||||||
|
printf("Power Redundancy | PS@%02xh | nr\n",
|
||||||
|
data[8]);
|
||||||
|
}
|
||||||
|
case 9: /* SR2300, non-redundant, PSx present */
|
||||||
|
if (verbose) {
|
||||||
|
printf("Power Redundancy : Yes\n");
|
||||||
|
printf("Power Supply Sensor : %x\n", data[7]);
|
||||||
|
printf("Power Supply Sensor : %x\n", data[8]);
|
||||||
|
} else if (csv_output) {
|
||||||
|
printf("Power Redundancy,PS@%02xh + PS@%02xh,ok\n");
|
||||||
|
} else {
|
||||||
|
printf("Power Redundancy | PS@%02xh + PS@%02xh | ok\n",
|
||||||
|
data[7], data[8]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (verbose)
|
||||||
|
printf("\n");
|
||||||
|
break;
|
||||||
|
case 0x03: /* Fan Speed Control */
|
||||||
|
break;
|
||||||
|
case 0x06: /* System Information */
|
||||||
|
break;
|
||||||
|
case 0x07: /* Ambient Temperature Fan Speed Control */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (verbose > 1)
|
||||||
|
printf("Unknown Intel OEM SDR Record type %02x\n", data[3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ipmi_sdr_print_sdr(struct ipmi_intf * intf, unsigned char type)
|
void ipmi_sdr_print_sdr(struct ipmi_intf * intf, unsigned char type)
|
||||||
{
|
{
|
||||||
struct sdr_get_rs * header;
|
struct sdr_get_rs * header;
|
||||||
@ -840,6 +922,7 @@ void ipmi_sdr_print_sdr(struct ipmi_intf * intf, unsigned char type)
|
|||||||
case SDR_RECORD_TYPE_BMC_MSG_CHANNEL_INFO:
|
case SDR_RECORD_TYPE_BMC_MSG_CHANNEL_INFO:
|
||||||
break;
|
break;
|
||||||
case SDR_RECORD_TYPE_OEM:
|
case SDR_RECORD_TYPE_OEM:
|
||||||
|
ipmi_sdr_print_oem(intf, rec, header->length);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
free(rec);
|
free(rec);
|
||||||
@ -897,7 +980,7 @@ ipmi_sdr_start(struct ipmi_intf * intf)
|
|||||||
memcpy(&sdr_info, rsp->data, sizeof(sdr_info));
|
memcpy(&sdr_info, rsp->data, sizeof(sdr_info));
|
||||||
|
|
||||||
/* byte 1 is SDR version, should be 51h */
|
/* byte 1 is SDR version, should be 51h */
|
||||||
if (sdr_info.version != 0x51) {
|
if ((sdr_info.version != 0x51) && (sdr_info.version != 0x01)) {
|
||||||
printf("SDR repository version mismatch!\n");
|
printf("SDR repository version mismatch!\n");
|
||||||
free (itr);
|
free (itr);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1300,6 +1383,100 @@ ipmi_sdr_print_info(struct ipmi_intf * intf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int ipmi_sdr_dump_bin(struct ipmi_intf * intf, const char * ofile)
|
||||||
|
{
|
||||||
|
struct stat st1, st2;
|
||||||
|
struct sdr_get_rs * header;
|
||||||
|
struct ipmi_sdr_iterator * itr;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
/* open file for writing */
|
||||||
|
if (lstat(ofile, &st1) < 0) {
|
||||||
|
/* does not exist, ok to create */
|
||||||
|
fd = open(ofile, O_WRONLY|O_TRUNC|O_EXCL|O_CREAT, 0600);
|
||||||
|
if (fd < 1) {
|
||||||
|
printf("ERROR: Unable to open file '%s' for write: %s\n",
|
||||||
|
ofile, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* it exists - allow only regular file, not links */
|
||||||
|
if (!S_ISREG(st1.st_mode)) {
|
||||||
|
printf("ERROR: file '%s' has invalid mode: %d\n",
|
||||||
|
ofile, st1.st_mode);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allow only files with 1 link (itself) */
|
||||||
|
if (st1.st_nlink != 1) {
|
||||||
|
printf("ERROR: file '%s' has invalid link count: %d != 1\n",
|
||||||
|
ofile, st1.st_nlink);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* open it for write, overwrite existing file */
|
||||||
|
fd = open(ofile, O_WRONLY | O_TRUNC, 0600);
|
||||||
|
if (fd < 1) {
|
||||||
|
printf("ERROR: unable to overwrite file '%s': %s\n",
|
||||||
|
ofile, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* stat again and verify inode/owner/link count */
|
||||||
|
fstat(fd, &st2);
|
||||||
|
if (st2.st_ino != st1.st_ino || st2.st_uid != st1.st_uid ||
|
||||||
|
st2.st_nlink != 1) {
|
||||||
|
printf("ERROR: unable to verify file '%s'\n", ofile);
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* open connection to SDR */
|
||||||
|
itr = ipmi_sdr_start(intf);
|
||||||
|
if (!itr) {
|
||||||
|
printf("Unable to open SDR for reading\n");
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Dumping Sensor Data Repository to '%s'\n", ofile);
|
||||||
|
|
||||||
|
/* go through sdr records */
|
||||||
|
while (header = ipmi_sdr_get_next_header(intf, itr)) {
|
||||||
|
int r;
|
||||||
|
unsigned char h[5];
|
||||||
|
unsigned char * rec;
|
||||||
|
|
||||||
|
if (verbose)
|
||||||
|
printf("Record ID %04x (%d bytes)\n", header->id, header->length);
|
||||||
|
|
||||||
|
rec = ipmi_sdr_get_record(intf, header, itr);
|
||||||
|
if (!rec) continue;
|
||||||
|
|
||||||
|
/* build and write sdr header */
|
||||||
|
h[0] = header->id & 0xff;
|
||||||
|
h[1] = (header->id >> 8) & 0xff;
|
||||||
|
h[2] = header->version;
|
||||||
|
h[3] = header->type;
|
||||||
|
h[4] = header->length;
|
||||||
|
|
||||||
|
r = write(fd, h, 5);
|
||||||
|
if (r != 5) {
|
||||||
|
printf("Error writing %d byte to output file\n", 5);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* write sdr entry */
|
||||||
|
r = write(fd, rec, header->length);
|
||||||
|
if (r != header->length) {
|
||||||
|
printf("Error writing %d bytes to output file\n", header->length);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
int ipmi_sdr_main(struct ipmi_intf * intf, int argc, char ** argv)
|
int ipmi_sdr_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||||
{
|
{
|
||||||
@ -1340,7 +1517,13 @@ int ipmi_sdr_main(struct ipmi_intf * intf, int argc, char ** argv)
|
|||||||
else if (!strncmp(argv[0], "info", 4)) {
|
else if (!strncmp(argv[0], "info", 4)) {
|
||||||
ipmi_sdr_print_info(intf);
|
ipmi_sdr_print_info(intf);
|
||||||
}
|
}
|
||||||
else
|
else if (!strncmp(argv[0], "dump", 4)) {
|
||||||
|
if (argc < 2)
|
||||||
|
printf("usage: sdr dump <filename>\n");
|
||||||
|
else
|
||||||
|
ipmi_sdr_dump_bin(intf, argv[1]);
|
||||||
|
} else {
|
||||||
printf("Invalid SDR command: %s\n", argv[0]);
|
printf("Invalid SDR command: %s\n", argv[0]);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user