[libvirt] [PATCH 0/2] Implement sysinfo for PowerPC, improve its behaviour on x86.

This series of patches implements the following: Patch 1/2 : Implement sysinfo for PowerPC. OnPowerPC, sysinfo is obtained by reading /proc/cpuinfo since dmidecode is not available. Patch 2/2 : Based on Eric's suggestion (http://www.redhat.com/archives/libvir-list/2012-February/msg00509.html), Allow x86 to read host system's processor information from /proc/cpuinfo in the event dmidecode is not available. Changelog: * Patch 1: Rebased and cleanups done. * Patch 2: New. -- Prerna Saxena Linux Technology Centre, IBM Systems and Technology Lab, Bangalore, India

From: Prerna Saxena <prerna@linux.vnet.ibm.com> Date: Tue, 17 Feb 2012 16:55:26 +0530 Subject: [PATCH 1/2] Implement sysinfo on PowerPC. Libvirt on x86 parses 'dmidecode' to gather characteristics of host system, which are then reflected to libvirt users by virSysinfoRead(), invoked by 'virsh sysinfo'. This patch implements it on PowerPC by reading /proc/cpuinfo. The presently available fields in 'sysinfo' are strongly tied to dmidecode output fields. This patch attempts to retrofit the information available in PowerPC to appropriate sysinfo fields. I will be happy to change the organization of this information to if there are expected outputs for individual fields. (I couldnt find any documentation which explained what each sysinfo field was expected to convey.) TODOS: 1. Adding Memory DIMM information 2) Firmware (<bios>) details. 3) Expand <processor> tag to have more fields available. Example output on PowerPC : virsh # sysinfo <sysinfo type='smbios'> <system> <entry name='version'>PowerNV 8246-L2C</entry> <entry name='serial'>8246-L2C</entry> <entry name='family'>PowerNV</entry> </system> <processor> <entry name='socket_destination'>0</entry> <entry name='type'>POWER7 (raw), altivec supported</entry> <entry name='version'>2.3 (pvr 003f 0203)</entry> </processor> <processor> <entry name='socket_destination'>4</entry> <entry name='type'>POWER7 (raw), altivec supported</entry> <entry name='version'>2.3 (pvr 003f 0203)</entry> </processor> ...... --- src/util/sysinfo.c | 131 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 129 insertions(+), 2 deletions(-) diff --git a/src/util/sysinfo.c b/src/util/sysinfo.c index 39c7581..0161b22 100644 --- a/src/util/sysinfo.c +++ b/src/util/sysinfo.c @@ -44,6 +44,7 @@ __FUNCTION__, __LINE__, __VA_ARGS__) #define SYSINFO_SMBIOS_DECODER "dmidecode" +#define CPUINFO "/proc/cpuinfo" VIR_ENUM_IMPL(virSysinfo, VIR_SYSINFO_LAST, "smbios"); @@ -113,10 +114,136 @@ void virSysinfoDefFree(virSysinfoDefPtr def) * * Returns: a filled up sysinfo structure or NULL in case of error */ -#if defined(WIN32) || \ + +#if defined(__powerpc__) +static int +virSysinfoParseSystem(const char *base, virSysinfoDefPtr ret) +{ + char *cur, *eol = NULL; + + if ((cur = strstr(base, "platform")) == NULL) + return 0; + + base = cur; + /* Account for format 'platform : XXXX'*/ + cur = strchr(cur, ':') + 1; + eol = strchr(cur, '\n'); + if ((eol) && + ((ret->system_family = strndup(cur, eol - cur)) == NULL)) + goto no_memory; + virSkipSpaces(&(ret->system_family)); + + if ((cur = strstr(base, "model")) != NULL) { + cur = strchr(cur, ':') + 1; + eol = strchr(cur, '\n'); + if ((eol) && ((ret->system_serial = strndup(cur, eol - cur)) + == NULL)) + goto no_memory; + virSkipSpaces(&(ret->system_serial)); + } + + if ((cur = strstr(base, "machine")) != NULL) { + cur = strchr(cur, ':') + 1; + eol = strchr(cur, '\n'); + if ((eol) && ((ret->system_version = strndup(cur, eol - cur)) + == NULL)) + goto no_memory; + virSkipSpaces(&(ret->system_version)); + } + + return 0; + +no_memory: + return -1; +} + +static int +virSysinfoParseProcessor(const char *base, virSysinfoDefPtr ret) +{ + char *cur, *eol, *tmp_base; + virSysinfoProcessorDefPtr processor; + + while((tmp_base = strstr(base, "processor")) != NULL) { + base = tmp_base; + eol = strchr(base, '\n'); + cur = strchr(base, ':') + 1; + + if (VIR_EXPAND_N(ret->processor, ret->nprocessor, 1) < 0) { + goto no_memory; + } + + processor = &ret->processor[ret->nprocessor - 1]; + if ((eol) && + ((processor->processor_socket_destination = strndup + (cur, eol - cur)) == NULL)) + goto no_memory; + virSkipSpaces(&(processor->processor_socket_destination)); + + if ((cur = strstr(base, "cpu")) != NULL) { + cur = strchr(cur, ':') + 1; + eol = strchr(cur, '\n'); + if ((eol) && + ((processor->processor_type = strndup(cur, eol - cur)) + == NULL)) + goto no_memory; + virSkipSpaces(&(processor->processor_type)); + } + + if ((cur = strstr(base, "revision")) != NULL) { + cur = strchr(cur, ':') + 1; + eol = strchr(cur, '\n'); + if ((eol) && + ((processor->processor_version = strndup(cur, eol - cur)) + == NULL)) + goto no_memory; + virSkipSpaces(&(processor->processor_version)); + } + + base = cur; + } + + return 0; + +no_memory: + return -1; +} + +/* virSysinfoRead for PowerPC + * Gathers sysinfo data from /proc/cpuinfo */ +virSysinfoDefPtr +virSysinfoRead(void) { + virSysinfoDefPtr ret = NULL; + char *outbuf = NULL; + + if (VIR_ALLOC(ret) < 0) + goto no_memory; + + if(virFileReadAll(CPUINFO, 2048, &outbuf) < 0) { + virSmbiosReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to open %s"), CPUINFO); + return NULL; + } + + ret->nprocessor = 0; + ret->processor = NULL; + if (virSysinfoParseProcessor(outbuf, ret) < 0) + goto no_memory; + + if (virSysinfoParseSystem(outbuf, ret) < 0) + goto no_memory; + + return ret; + +no_memory: + VIR_FREE(outbuf); + return NULL; +} + +#elif defined(WIN32) || \ !(defined(__x86_64__) || \ defined(__i386__) || \ - defined(__amd64__)) + defined(__amd64__) || \ + defined(__powerpc__)) virSysinfoDefPtr virSysinfoRead(void) { /* -- 1.7.7 -- Prerna Saxena Linux Technology Centre, IBM Systems and Technology Lab, Bangalore, India

On Thu, Feb 16, 2012 at 05:56:22PM +0530, Prerna wrote:
From: Prerna Saxena <prerna@linux.vnet.ibm.com> Date: Tue, 17 Feb 2012 16:55:26 +0530 Subject: [PATCH 1/2] Implement sysinfo on PowerPC.
Libvirt on x86 parses 'dmidecode' to gather characteristics of host system, which are then reflected to libvirt users by virSysinfoRead(), invoked by 'virsh sysinfo'. This patch implements it on PowerPC by reading /proc/cpuinfo.
The presently available fields in 'sysinfo' are strongly tied to dmidecode output fields. This patch attempts to retrofit the information available in PowerPC to appropriate sysinfo fields. I will be happy to change the organization of this information to if there are expected outputs for individual fields. (I couldnt find any documentation which explained what each sysinfo field was expected to convey.)
TODOS: 1. Adding Memory DIMM information 2) Firmware (<bios>) details. 3) Expand <processor> tag to have more fields available.
Example output on PowerPC : virsh # sysinfo <sysinfo type='smbios'> <system> <entry name='version'>PowerNV 8246-L2C</entry> <entry name='serial'>8246-L2C</entry> <entry name='family'>PowerNV</entry> </system> <processor> <entry name='socket_destination'>0</entry> <entry name='type'>POWER7 (raw), altivec supported</entry> <entry name='version'>2.3 (pvr 003f 0203)</entry> </processor> <processor> <entry name='socket_destination'>4</entry> <entry name='type'>POWER7 (raw), altivec supported</entry> <entry name='version'>2.3 (pvr 003f 0203)</entry> </processor> ......
ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

From: Prerna Saxena <prerna@linux.vnet.ibm.com> Date: Thu, 16 Feb 2012 15:33:43 +0530 Subject: [PATCH 2/2] Sysinfo : Allow x86 to fetch sysinfo from /proc/cpuinfo in the event 'dmidecode' is absent in the system. Based on Eric's suggestion (http://www.redhat.com/archives/libvir-list/2012-February/msg00509.html) --- src/util/sysinfo.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 91 insertions(+), 4 deletions(-) diff --git a/src/util/sysinfo.c b/src/util/sysinfo.c index 0161b22..5ca725e 100644 --- a/src/util/sysinfo.c +++ b/src/util/sysinfo.c @@ -596,6 +596,96 @@ no_memory: return -1; } +/* If a call to 'dmidecode' fails, + * extract basic sysinfo from /proc/cpuinfo */ + +static int +virSysinfoParseCPUInfoProcessor(const char *base, virSysinfoDefPtr ret) +{ + char *cur, *eol, *tmp_base; + virSysinfoProcessorDefPtr processor; + + while((tmp_base = strstr(base, "processor")) != NULL) { + base = tmp_base; + eol = strchr(base, '\n'); + cur = strchr(base, ':') + 1; + + if (VIR_EXPAND_N(ret->processor, ret->nprocessor, 1) < 0) { + goto no_memory; + } + + processor = &ret->processor[ret->nprocessor - 1]; + if ((eol) && + ((processor->processor_socket_destination = + strndup(cur, eol - cur)) == NULL)) + goto no_memory; + virSkipSpaces(&(processor->processor_socket_destination)); + + if ((cur = strstr(base, "vendor_id")) != NULL) { + cur = strchr(cur, ':') + 1; + eol = strchr(cur, '\n'); + if ((eol) && + ((processor->processor_manufacturer = + strndup(cur, eol - cur)) == NULL)) + goto no_memory; + virSkipSpaces(&(processor->processor_manufacturer)); + } + + if ((cur = strstr(base, "cpu family")) != NULL) { + cur = strchr(cur, ':') + 1; + eol = strchr(cur, '\n'); + if ((eol) && + ((processor->processor_family = strndup(cur, eol - cur)) == + NULL)) + goto no_memory; + virSkipSpaces(&(processor->processor_family)); + } + + if ((cur = strstr(base, "model name")) != NULL) { + cur = strchr(cur, ':') + 1; + eol = strchr(cur, '\n'); + if ((eol) && + ((processor->processor_type = strndup(cur, eol - cur)) == + NULL)) + goto no_memory; + virSkipSpaces(&(processor->processor_type)); + } + + base = cur; + } + + return 0; + +no_memory: + return -1; +} + +static virSysinfoDefPtr +virCPUInfoSysinfoRead(void) { + virSysinfoDefPtr ret = NULL; + char *outbuf = NULL; + + if (VIR_ALLOC(ret) < 0) + goto no_memory; + + if(virFileReadAll(CPUINFO, 20000, &outbuf) < 0) { + virSmbiosReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to open %s"), CPUINFO); + return NULL; + } + + ret->nprocessor = 0; + ret->processor = NULL; + if (virSysinfoParseCPUInfoProcessor(outbuf, ret) < 0) + goto no_memory; + + return ret; + +no_memory: + VIR_FREE(outbuf); + return NULL; +} + virSysinfoDefPtr virSysinfoRead(void) { char *path; @@ -605,10 +695,7 @@ virSysinfoRead(void) { path = virFindFileInPath(SYSINFO_SMBIOS_DECODER); if (path == NULL) { - virSmbiosReportError(VIR_ERR_INTERNAL_ERROR, - _("Failed to find path for %s binary"), - SYSINFO_SMBIOS_DECODER); - return NULL; + return virCPUInfoSysinfoRead(); } cmd = virCommandNewArgList(path, "-q", "-t", "0,1,4,17", NULL); -- 1.7.7 -- Prerna Saxena Linux Technology Centre, IBM Systems and Technology Lab, Bangalore, India

The last patch was mangled by my mailer, resending. From: Prerna Saxena <prerna@linux.vnet.ibm.com> Date: Thu, 16 Feb 2012 15:33:43 +0530 Subject: [PATCH 2/2] Sysinfo : Allow x86 to fetch sysinfo from /proc/cpuinfo in the event 'dmidecode' is absent in the system. Until now, libvirt on x86 flags an error message if dmidecode is not found. With this patch, the following is a sample output on x86 when dmidecode is absent: virsh # sysinfo <sysinfo type='smbios'> <processor> <entry name='socket_destination'>0</entry> <entry name='type'>Intel(R) Xeon(R) CPU X5570 @ 2.93GHz</entry> <entry name='family'>6</entry> <entry name='manufacturer'>GenuineIntel</entry> </processor> <processor> <entry name='socket_destination'>1</entry> <entry name='type'>Intel(R) Xeon(R) CPU X5570 @ 2.93GHz</entry> <entry name='family'>6</entry> <entry name='manufacturer'>GenuineIntel</entry> </processor> ... (listing for all online CPUs) </sysinfo> --- src/util/sysinfo.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 91 insertions(+), 4 deletions(-) diff --git a/src/util/sysinfo.c b/src/util/sysinfo.c index 0161b22..de78d23 100644 --- a/src/util/sysinfo.c +++ b/src/util/sysinfo.c @@ -596,6 +596,96 @@ no_memory: return -1; } +/* If a call to 'dmidecode' fails, + * extract basic sysinfo from /proc/cpuinfo */ + +static int +virSysinfoParseCPUInfoProcessor(const char *base, virSysinfoDefPtr ret) +{ + char *cur, *eol, *tmp_base; + virSysinfoProcessorDefPtr processor; + + while((tmp_base = strstr(base, "processor")) != NULL) { + base = tmp_base; + eol = strchr(base, '\n'); + cur = strchr(base, ':') + 1; + + if (VIR_EXPAND_N(ret->processor, ret->nprocessor, 1) < 0) { + goto no_memory; + } + + processor = &ret->processor[ret->nprocessor - 1]; + if ((eol) && + ((processor->processor_socket_destination = + strndup(cur, eol - cur)) == NULL)) + goto no_memory; + virSkipSpaces(&(processor->processor_socket_destination)); + + if ((cur = strstr(base, "vendor_id")) != NULL) { + cur = strchr(cur, ':') + 1; + eol = strchr(cur, '\n'); + if ((eol) && + ((processor->processor_manufacturer = + strndup(cur, eol - cur)) == NULL)) + goto no_memory; + virSkipSpaces(&(processor->processor_manufacturer)); + } + + if ((cur = strstr(base, "cpu family")) != NULL) { + cur = strchr(cur, ':') + 1; + eol = strchr(cur, '\n'); + if ((eol) && + ((processor->processor_family = strndup(cur, eol - cur)) + == NULL)) + goto no_memory; + virSkipSpaces(&(processor->processor_family)); + } + + if ((cur = strstr(base, "model name")) != NULL) { + cur = strchr(cur, ':') + 1; + eol = strchr(cur, '\n'); + if ((eol) && + ((processor->processor_type = strndup(cur, eol - cur)) + == NULL)) + goto no_memory; + virSkipSpaces(&(processor->processor_type)); + } + + base = cur; + } + + return 0; + +no_memory: + return -1; +} + +static virSysinfoDefPtr +virCPUInfoSysinfoRead(void) { + virSysinfoDefPtr ret = NULL; + char *outbuf = NULL; + + if (VIR_ALLOC(ret) < 0) + goto no_memory; + + if(virFileReadAll(CPUINFO, 20000, &outbuf) < 0) { + virSmbiosReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to open %s"), CPUINFO); + return NULL; + } + + ret->nprocessor = 0; + ret->processor = NULL; + if (virSysinfoParseCPUInfoProcessor(outbuf, ret) < 0) + goto no_memory; + + return ret; + +no_memory: + VIR_FREE(outbuf); + return NULL; +} + virSysinfoDefPtr virSysinfoRead(void) { char *path; @@ -605,10 +695,7 @@ virSysinfoRead(void) { path = virFindFileInPath(SYSINFO_SMBIOS_DECODER); if (path == NULL) { - virSmbiosReportError(VIR_ERR_INTERNAL_ERROR, - _("Failed to find path for %s binary"), - SYSINFO_SMBIOS_DECODER); - return NULL; + return virCPUInfoSysinfoRead(); } cmd = virCommandNewArgList(path, "-q", "-t", "0,1,4,17", NULL); -- 1.7.7 -- Prerna Saxena Linux Technology Centre, IBM Systems and Technology Lab, Bangalore, India

On Fri, Feb 17, 2012 at 01:00:22PM +0530, Prerna wrote:
The last patch was mangled by my mailer, resending.
From: Prerna Saxena <prerna@linux.vnet.ibm.com> Date: Thu, 16 Feb 2012 15:33:43 +0530 Subject: [PATCH 2/2] Sysinfo : Allow x86 to fetch sysinfo from /proc/cpuinfo in the event 'dmidecode' is absent in the system.
Until now, libvirt on x86 flags an error message if dmidecode is not found. With this patch, the following is a sample output on x86 when dmidecode is absent:
virsh # sysinfo <sysinfo type='smbios'> <processor> <entry name='socket_destination'>0</entry> <entry name='type'>Intel(R) Xeon(R) CPU X5570 @ 2.93GHz</entry> <entry name='family'>6</entry> <entry name='manufacturer'>GenuineIntel</entry> </processor> <processor> <entry name='socket_destination'>1</entry> <entry name='type'>Intel(R) Xeon(R) CPU X5570 @ 2.93GHz</entry> <entry name='family'>6</entry> <entry name='manufacturer'>GenuineIntel</entry> </processor> ... (listing for all online CPUs) </sysinfo>
--- src/util/sysinfo.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 91 insertions(+), 4 deletions(-)
ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On 02/28/2012 12:58 PM, Daniel P. Berrange wrote:
On Fri, Feb 17, 2012 at 01:00:22PM +0530, Prerna wrote:
The last patch was mangled by my mailer, resending.
From: Prerna Saxena <prerna@linux.vnet.ibm.com> Date: Thu, 16 Feb 2012 15:33:43 +0530 Subject: [PATCH 2/2] Sysinfo : Allow x86 to fetch sysinfo from /proc/cpuinfo in the event 'dmidecode' is absent in the system.
Until now, libvirt on x86 flags an error message if dmidecode is not found. With this patch, the following is a sample output on x86 when dmidecode is absent:
--- src/util/sysinfo.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 91 insertions(+), 4 deletions(-)
ACK
NACK; we need a v2 for both patches. You had TABs (run 'make syntax-check'), and this compiler warning is evidence of a real bug: util/sysinfo.c: In function 'virSysinfoParseCPUInfoProcessor': util/sysinfo.c:622:9: error: passing argument 1 of 'virSkipSpaces' from incompatible pointer type [-Werror] util/util.h:162:6: note: expected 'const char **' but argument is of type 'char **' Looking at that code: if ((eol) && ((processor->processor_socket_destination = strndup(cur, eol - cur)) == NULL)) goto no_memory; virSkipSpaces(&(processor->processor_socket_destination)); but virSkipSpaces is _designed_ to advance the pointer. Which means that when you later call VIR_FREE on the altered pointer, you aren't freeing the pointer returned by the malloc inside strndup, but are instead freeing some random address occurring later in the allocated chunk of memory - a surefire way to corrupt your heap. I didn't compile-test the PowerPC code, but see the same bug there by inspection. If you want to skip spaces, you need to skip them in 'cur', prior to calling strndup; something like: diff --git i/src/util/sysinfo.c w/src/util/sysinfo.c index de78d23..f8095e5 100644 --- i/src/util/sysinfo.c +++ w/src/util/sysinfo.c @@ -602,13 +602,15 @@ no_memory: static int virSysinfoParseCPUInfoProcessor(const char *base, virSysinfoDefPtr ret) { - char *cur, *eol, *tmp_base; + const char *cur; + char *eol, *tmp_base; virSysinfoProcessorDefPtr processor; while((tmp_base = strstr(base, "processor")) != NULL) { base = tmp_base; eol = strchr(base, '\n'); cur = strchr(base, ':') + 1; + virSkipSpaces(&cur); if (VIR_EXPAND_N(ret->processor, ret->nprocessor, 1) < 0) { goto no_memory; @@ -619,7 +621,6 @@ virSysinfoParseCPUInfoProcessor(const char *base, virSysinfoDefPtr ret) ((processor->processor_socket_destination = strndup(cur, eol - cur)) == NULL)) goto no_memory; - virSkipSpaces(&(processor->processor_socket_destination)); if ((cur = strstr(base, "vendor_id")) != NULL) { cur = strchr(cur, ':') + 1; -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

From: Prerna Saxena <prerna@linux.vnet.ibm.com> Date: Tue, 7 Feb 2012 16:55:26 +0530 Subject: [PATCH 1/2] Implement sysinfo on PowerPC. Libvirt on x86 parses 'dmidecode' to gather characteristics of host system, which are then reflected to libvirt users by virSysinfoRead(), invoked by 'virsh sysinfo'. This patch implements it on PowerPC by reading /proc/cpuinfo. The presently available fields in 'sysinfo' are strongly tied to dmidecode output fields. This patch attempts to retrofit the information available in PowerPC to appropriate sysinfo fields. I will be happy to change the organization of this information to if there are expected outputs for individual fields. (I couldnt find any documentation which explained what each sysinfo field was expected to convey.) TODOS: 1. Adding Memory DIMM information 2) Firmware (<bios>) details. 3) Expand <processor> tag to have more fields available. Example output on PowerPC : virsh # sysinfo <sysinfo type='smbios'> <system> <entry name='version'>PowerNV 8246-L2C</entry> <entry name='serial'>8246-L2C</entry> <entry name='family'>PowerNV</entry> </system> <processor> <entry name='socket_destination'>0</entry> <entry name='type'>POWER7 (raw), altivec supported</entry> <entry name='version'>2.3 (pvr 003f 0203)</entry> </processor> <processor> <entry name='socket_destination'>4</entry> <entry name='type'>POWER7 (raw), altivec supported</entry> <entry name='version'>2.3 (pvr 003f 0203)</entry> </processor> ...... Changelog: --------- Cleanups. --- src/util/sysinfo.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 131 insertions(+), 2 deletions(-) diff --git a/src/util/sysinfo.c b/src/util/sysinfo.c index 39c7581..78efc32 100644 --- a/src/util/sysinfo.c +++ b/src/util/sysinfo.c @@ -44,6 +44,7 @@ __FUNCTION__, __LINE__, __VA_ARGS__) #define SYSINFO_SMBIOS_DECODER "dmidecode" +#define CPUINFO "/proc/cpuinfo" VIR_ENUM_IMPL(virSysinfo, VIR_SYSINFO_LAST, "smbios"); @@ -113,10 +114,138 @@ void virSysinfoDefFree(virSysinfoDefPtr def) * * Returns: a filled up sysinfo structure or NULL in case of error */ -#if defined(WIN32) || \ + +#if defined(__powerpc__) +static int +virSysinfoParseSystem(const char *base, virSysinfoDefPtr ret) +{ + char *eol = NULL; + const char *cur; + + if ((cur = strstr(base, "platform")) == NULL) + return 0; + + base = cur; + /* Account for format 'platform : XXXX'*/ + cur = strchr(cur, ':') + 1; + eol = strchr(cur, '\n'); + virSkipSpaces(&cur); + if (eol && + ((ret->system_family = strndup(cur, eol - cur)) == NULL)) + goto no_memory; + + if ((cur = strstr(base, "model")) != NULL) { + cur = strchr(cur, ':') + 1; + eol = strchr(cur, '\n'); + virSkipSpaces(&cur); + if (eol && ((ret->system_serial = strndup(cur, eol - cur)) + == NULL)) + goto no_memory; + } + + if ((cur = strstr(base, "machine")) != NULL) { + cur = strchr(cur, ':') + 1; + eol = strchr(cur, '\n'); + virSkipSpaces(&cur); + if (eol && ((ret->system_version = strndup(cur, eol - cur)) + == NULL)) + goto no_memory; + } + + return 0; + +no_memory: + return -1; +} + +static int +virSysinfoParseProcessor(const char *base, virSysinfoDefPtr ret) +{ + const char *cur; + char *eol, *tmp_base; + virSysinfoProcessorDefPtr processor; + + while((tmp_base = strstr(base, "processor")) != NULL) { + base = tmp_base; + eol = strchr(base, '\n'); + cur = strchr(base, ':') + 1; + + if (VIR_EXPAND_N(ret->processor, ret->nprocessor, 1) < 0) { + goto no_memory; + } + processor = &ret->processor[ret->nprocessor - 1]; + + virSkipSpaces(&cur); + if (eol && + ((processor->processor_socket_destination = strndup + (cur, eol - cur)) == NULL)) + goto no_memory; + + if ((cur = strstr(base, "cpu")) != NULL) { + cur = strchr(cur, ':') + 1; + eol = strchr(cur, '\n'); + virSkipSpaces(&cur); + if (eol && + ((processor->processor_type = strndup(cur, eol - cur)) + == NULL)) + goto no_memory; + } + + if ((cur = strstr(base, "revision")) != NULL) { + cur = strchr(cur, ':') + 1; + eol = strchr(cur, '\n'); + virSkipSpaces(&cur); + if (eol && + ((processor->processor_version = strndup(cur, eol - cur)) + == NULL)) + goto no_memory; + } + + base = cur; + } + + return 0; + +no_memory: + return -1; +} + +/* virSysinfoRead for PowerPC + * Gathers sysinfo data from /proc/cpuinfo */ +virSysinfoDefPtr +virSysinfoRead(void) { + virSysinfoDefPtr ret = NULL; + char *outbuf = NULL; + + if (VIR_ALLOC(ret) < 0) + goto no_memory; + + if(virFileReadAll(CPUINFO, 2048, &outbuf) < 0) { + virSmbiosReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to open %s"), CPUINFO); + return NULL; + } + + ret->nprocessor = 0; + ret->processor = NULL; + if (virSysinfoParseProcessor(outbuf, ret) < 0) + goto no_memory; + + if (virSysinfoParseSystem(outbuf, ret) < 0) + goto no_memory; + + return ret; + +no_memory: + VIR_FREE(outbuf); + return NULL; +} + +#elif defined(WIN32) || \ !(defined(__x86_64__) || \ defined(__i386__) || \ - defined(__amd64__)) + defined(__amd64__) || \ + defined(__powerpc__)) virSysinfoDefPtr virSysinfoRead(void) { /* -- 1.7.7 -- Prerna Saxena Linux Technology Centre, IBM Systems and Technology Lab, Bangalore, India

On 02/17/2012 12:30 AM, Prerna wrote:
The last patch was mangled by my mailer, resending.
From: Prerna Saxena <prerna@linux.vnet.ibm.com> Date: Thu, 16 Feb 2012 15:33:43 +0530 Subject: [PATCH 2/2] Sysinfo : Allow x86 to fetch sysinfo from /proc/cpuinfo in the event 'dmidecode' is absent in the system.
+ processor = &ret->processor[ret->nprocessor - 1]; + if ((eol) && + ((processor->processor_socket_destination = + strndup(cur, eol - cur)) == NULL))
This is over-parenthesized; I would write it: if (eol && (processor->processor_socket_destination = strndup(cur, eol - cur)) == NULL) -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

From 98c4f68702bc21060347011144603ee10be4847e Mon Sep 17 00:00:00 2001 From: Prerna Saxena <prerna@linux.vnet.ibm.com> Date: Thu, 16 Feb 2012 15:33:43 +0530 Subject: [PATCH 2/2] Sysinfo : Allow x86 to fetch sysinfo from /proc/cpuinfo in the event 'dmidecode' is absent in the system.
Based on Eric's suggestion (http://www.redhat.com/archives/libvir-list/2012-February/msg00509.html) Changelog: --------- Cleanups --- src/util/sysinfo.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 93 insertions(+), 4 deletions(-) diff --git a/src/util/sysinfo.c b/src/util/sysinfo.c index 78efc32..290b69f 100644 --- a/src/util/sysinfo.c +++ b/src/util/sysinfo.c @@ -598,6 +598,98 @@ no_memory: return -1; } +/* If a call to 'dmidecode' fails, + * extract basic sysinfo from /proc/cpuinfo */ + +static int +virSysinfoParseCPUInfoProcessor(const char *base, virSysinfoDefPtr ret) +{ + const char *cur; + char *eol, *tmp_base; + virSysinfoProcessorDefPtr processor; + + while((tmp_base = strstr(base, "processor")) != NULL) { + base = tmp_base; + eol = strchr(base, '\n'); + cur = strchr(base, ':') + 1; + + if (VIR_EXPAND_N(ret->processor, ret->nprocessor, 1) < 0) { + goto no_memory; + } + + processor = &ret->processor[ret->nprocessor - 1]; + virSkipSpaces(&cur); + if (eol && + (processor->processor_socket_destination = + strndup(cur, eol - cur)) == NULL) + goto no_memory; + + + if ((cur = strstr(base, "vendor_id")) != NULL) { + cur = strchr(cur, ':') + 1; + eol = strchr(cur, '\n'); + virSkipSpaces(&cur); + if (eol && + ((processor->processor_manufacturer = + strndup(cur, eol - cur)) == NULL)) + goto no_memory; + } + + if ((cur = strstr(base, "cpu family")) != NULL) { + cur = strchr(cur, ':') + 1; + eol = strchr(cur, '\n'); + virSkipSpaces(&cur); + if (eol && + ((processor->processor_family = strndup(cur, eol - cur)) + == NULL)) + goto no_memory; + } + + if ((cur = strstr(base, "model name")) != NULL) { + cur = strchr(cur, ':') + 1; + eol = strchr(cur, '\n'); + virSkipSpaces(&cur); + if (eol && + ((processor->processor_type = strndup(cur, eol - cur)) + == NULL)) + goto no_memory; + } + + base = cur; + } + + return 0; + +no_memory: + return -1; +} + +static virSysinfoDefPtr +virCPUInfoSysinfoRead(void) { + virSysinfoDefPtr ret = NULL; + char *outbuf = NULL; + + if (VIR_ALLOC(ret) < 0) + goto no_memory; + + if(virFileReadAll(CPUINFO, 20000, &outbuf) < 0) { + virSmbiosReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to open %s"), CPUINFO); + return NULL; + } + + ret->nprocessor = 0; + ret->processor = NULL; + if (virSysinfoParseCPUInfoProcessor(outbuf, ret) < 0) + goto no_memory; + + return ret; + +no_memory: + VIR_FREE(outbuf); + return NULL; +} + virSysinfoDefPtr virSysinfoRead(void) { char *path; @@ -607,10 +699,7 @@ virSysinfoRead(void) { path = virFindFileInPath(SYSINFO_SMBIOS_DECODER); if (path == NULL) { - virSmbiosReportError(VIR_ERR_INTERNAL_ERROR, - _("Failed to find path for %s binary"), - SYSINFO_SMBIOS_DECODER); - return NULL; + return virCPUInfoSysinfoRead(); } cmd = virCommandNewArgList(path, "-q", "-t", "0,1,4,17", NULL); -- 1.7.7 -- Prerna Saxena Linux Technology Centre, IBM Systems and Technology Lab, Bangalore, India

On 02/16/2012 05:03 PM, Prerna wrote:
This series of patches implements the following:
Patch 1/2 : Implement sysinfo for PowerPC. OnPowerPC, sysinfo is obtained by reading /proc/cpuinfo since dmidecode is not available.
Patch 2/2 : Based on Eric's suggestion (http://www.redhat.com/archives/libvir-list/2012-February/msg00509.html), Allow x86 to read host system's processor information from /proc/cpuinfo in the event dmidecode is not available.
Changelog: * Patch 1: Rebased and cleanups done. * Patch 2: New.
Hi, Any thoughts on this patch series ? I will be happy to modify the output information based on feedback. Thanks, -- Prerna Saxena Linux Technology Centre, IBM Systems and Technology Lab, Bangalore, India
participants (4)
-
Daniel P. Berrange
-
Eric Blake
-
Prerna
-
Prerna Saxena