[libvirt] [PATCH] Implement minimal sysinfo for ARM platforms

Daniel P. Berrange berrange at redhat.com
Wed Apr 3 17:59:57 UTC 2013


From: "Daniel P. Berrange" <berrange at redhat.com>

Implement the bare minimal sysinfo for ARM platforms by
reading the CPU models from /proc/cpuinfo

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 src/util/virsysinfo.c               | 129 +++++++++++++++++++++++++++++++++++-
 tests/sysinfodata/armcpuinfo.data   |  17 +++++
 tests/sysinfodata/armsysinfo.expect |  10 +++
 tests/sysinfotest.c                 |  15 ++++-
 4 files changed, 169 insertions(+), 2 deletions(-)
 create mode 100644 tests/sysinfodata/armcpuinfo.data
 create mode 100644 tests/sysinfodata/armsysinfo.expect

diff --git a/src/util/virsysinfo.c b/src/util/virsysinfo.c
index 83c445d..ba0c245 100644
--- a/src/util/virsysinfo.c
+++ b/src/util/virsysinfo.c
@@ -255,8 +255,134 @@ no_memory:
     return NULL;
 }
 
-#elif defined(__s390__) || defined(__s390x__)
+#elif defined(__arm__)
+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;
+    char *processor_type = NULL;
+
+    if (!(tmp_base = strstr(base, "Processor")))
+        return 0;
+
+    base = tmp_base;
+    eol = strchr(base, '\n');
+    cur = strchr(base, ':') + 1;
+    virSkipSpaces(&cur);
+    if (eol &&
+        ((processor_type = strndup(cur, eol - cur))
+         == NULL))
+        goto no_memory;
+    base = cur;
+
+    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 (processor_type &&
+            !(processor->processor_type = strdup(processor_type)))
+            goto no_memory;
+
+        base = cur;
+    }
+
+    VIR_FREE(processor_type);
+    return 0;
+
+no_memory:
+    VIR_FREE(processor_type);
+    return -1;
+}
+
+/* virSysinfoRead for ARMv7
+ * 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) {
+        virReportError(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(__s390__) || defined(__s390x__)
 /*
   we need to ignore warnings about strchr caused by -Wlogical-op
   for some GCC versions.
@@ -403,6 +529,7 @@ no_memory:
     !(defined(__x86_64__) || \
       defined(__i386__) ||   \
       defined(__amd64__) || \
+      defined(__arm__) || \
       defined(__powerpc__))
 virSysinfoDefPtr
 virSysinfoRead(void) {
diff --git a/tests/sysinfodata/armcpuinfo.data b/tests/sysinfodata/armcpuinfo.data
new file mode 100644
index 0000000..6ef23ca
--- /dev/null
+++ b/tests/sysinfodata/armcpuinfo.data
@@ -0,0 +1,17 @@
+Processor	: ARMv7 Processor rev 4 (v7l)
+processor	: 0
+BogoMIPS	: 1694.10
+
+processor	: 1
+BogoMIPS	: 1694.10
+
+Features	: swp half thumb fastmult vfp edsp thumbee neon vfpv3 tls vfpv4 idiva idivt 
+CPU implementer	: 0x41
+CPU architecture: 7
+CPU variant	: 0x0
+CPU part	: 0xc0f
+CPU revision	: 4
+
+Hardware	: SAMSUNG EXYNOS5 (Flattened Device Tree)
+Revision	: 0000
+Serial		: 0000000000000000
diff --git a/tests/sysinfodata/armsysinfo.expect b/tests/sysinfodata/armsysinfo.expect
new file mode 100644
index 0000000..1af9e6d
--- /dev/null
+++ b/tests/sysinfodata/armsysinfo.expect
@@ -0,0 +1,10 @@
+<sysinfo type='smbios'>
+  <processor>
+    <entry name='socket_destination'>0</entry>
+    <entry name='type'>ARMv7 Processor rev 4 (v7l)</entry>
+  </processor>
+  <processor>
+    <entry name='socket_destination'>1</entry>
+    <entry name='type'>ARMv7 Processor rev 4 (v7l)</entry>
+  </processor>
+</sysinfo>
diff --git a/tests/sysinfotest.c b/tests/sysinfotest.c
index 94493a3..8955208 100644
--- a/tests/sysinfotest.c
+++ b/tests/sysinfotest.c
@@ -40,7 +40,8 @@
 
 # if defined(__s390__) || defined(__s390x__) || \
      defined(__powerpc__) || defined(__powerpc64__) || \
-     defined(__i386__) || defined(__x86_64__) || defined(__amd64__)
+     defined(__i386__) || defined(__x86_64__) || defined(__amd64__) || \
+     defined(__arm__)
 
 /* from sysinfo.c */
 void virSysinfoSetup(const char *decoder,
@@ -164,6 +165,18 @@ test_x86(void)
 }
 
 VIRT_TEST_MAIN(test_x86)
+# elif defined(__arm__)
+static int
+test_arm(void)
+{
+    return sysinfotest_run("arm sysinfo",
+                           NULL,
+                           NULL,
+                           "/sysinfodata/armcpuinfo.data",
+                           "/sysinfodata/armsysinfo.expect");
+}
+
+VIRT_TEST_MAIN(test_arm)
 # else
 int
 main(void)
-- 
1.8.1.4




More information about the libvir-list mailing list