From: Prerna Saxena <prerna(a)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>
Based on suggestion from Eric Blake:
(
http://www.redhat.com/archives/libvir-list/2012-February/msg00509.html)
Also updated to display only socket-level information under '<processor>'
XML tags, to bring it analogous to 'dmidecode' output.
(Observed by Daniel Veillard :
http://www.spinics.net/linux/fedora/libvir/msg53922.html)
Acked-by: Daniel P Berrange <berrange(a)redhat.com>
Signed-off-by: Prerna Saxena <prerna(a)linux.vnet.ibm.com>
---
src/util/sysinfo.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 106 insertions(+), 4 deletions(-)
diff --git a/src/util/sysinfo.c b/src/util/sysinfo.c
index 78efc32..220338f 100644
--- a/src/util/sysinfo.c
+++ b/src/util/sysinfo.c
@@ -598,6 +598,111 @@ 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, *physical_id=NULL, *tmp_physical_id;
+ int physical_id_len;
+ virSysinfoProcessorDefPtr processor;
+
+ while((tmp_base = strstr(base, "processor")) != NULL) {
+ base = tmp_base;
+ eol = strchr(base, '\n');
+ cur = strchr(base, ':') + 1;
+
+ tmp_physical_id = strchr(strstr(base, "physical id"), ':') +
1;
+ physical_id_len = strchr(tmp_physical_id, '\n') - tmp_physical_id;
+
+ if(!physical_id) {
+ physical_id = tmp_physical_id;
+ }
+ else if (!strncmp(physical_id, tmp_physical_id, physical_id_len)) {
+ base = cur;
+ continue;
+ }
+
+ 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;
+ physical_id = tmp_physical_id;
+ }
+
+ 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 +712,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.6
--
Prerna Saxena
Linux Technology Centre,
IBM Systems and Technology Lab,
Bangalore, India