[libvirt] [PATCH v2] sysinfo: Fix reports on ARM

Due to a kernel commit (b4b8f770e), cpuinfo format has changed on ARMs. Firstly, 'Processor: ...' may not be reported, it's replaced by 'model name: ...'. Secondly, the "Processor" string may occur in CPU name, e.g. 'ARMv7 Processor rev 5 (v7l)'. Therefore, we must firstly look for 'model name' and then for 'Processor' if not found. Moreover, lines in the cpuinfo file are shuffled, so we better not manipulate the pointer to start of internal buffer as we may lost some info. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- diff to v1: - Jan's comments worked in - added new test case (yes, there really is a space at EOL in cpuinfo on my ARM) src/util/virsysinfo.c | 9 +++---- tests/sysinfodata/arm-rpi2cpuinfo.data | 43 ++++++++++++++++++++++++++++++++ tests/sysinfodata/arm-rpi2sysinfo.expect | 18 +++++++++++++ tests/sysinfotest.c | 22 ++++++++++++---- 4 files changed, 82 insertions(+), 10 deletions(-) create mode 100644 tests/sysinfodata/arm-rpi2cpuinfo.data create mode 100644 tests/sysinfodata/arm-rpi2sysinfo.expect diff --git a/src/util/virsysinfo.c b/src/util/virsysinfo.c index 8bb17f0..40390ab 100644 --- a/src/util/virsysinfo.c +++ b/src/util/virsysinfo.c @@ -289,16 +289,15 @@ virSysinfoParseProcessor(const char *base, virSysinfoDefPtr ret) virSysinfoProcessorDefPtr processor; char *processor_type = NULL; - if (!(tmp_base = strstr(base, "Processor"))) + if (!(tmp_base = strstr(base, "model name")) && + !(tmp_base = strstr(base, "Processor"))) return 0; - base = tmp_base; - eol = strchr(base, '\n'); - cur = strchr(base, ':') + 1; + eol = strchr(tmp_base, '\n'); + cur = strchr(tmp_base, ':') + 1; virSkipSpaces(&cur); if (eol && VIR_STRNDUP(processor_type, cur, eol - cur) < 0) goto error; - base = cur; while ((tmp_base = strstr(base, "processor")) != NULL) { base = tmp_base; diff --git a/tests/sysinfodata/arm-rpi2cpuinfo.data b/tests/sysinfodata/arm-rpi2cpuinfo.data new file mode 100644 index 0000000..41fde00 --- /dev/null +++ b/tests/sysinfodata/arm-rpi2cpuinfo.data @@ -0,0 +1,43 @@ +processor : 0 +model name : ARMv7 Processor rev 5 (v7l) +BogoMIPS : 38.40 +Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm +CPU implementer : 0x41 +CPU architecture: 7 +CPU variant : 0x0 +CPU part : 0xc07 +CPU revision : 5 + +processor : 1 +model name : ARMv7 Processor rev 5 (v7l) +BogoMIPS : 38.40 +Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm +CPU implementer : 0x41 +CPU architecture: 7 +CPU variant : 0x0 +CPU part : 0xc07 +CPU revision : 5 + +processor : 2 +model name : ARMv7 Processor rev 5 (v7l) +BogoMIPS : 38.40 +Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm +CPU implementer : 0x41 +CPU architecture: 7 +CPU variant : 0x0 +CPU part : 0xc07 +CPU revision : 5 + +processor : 3 +model name : ARMv7 Processor rev 5 (v7l) +BogoMIPS : 38.40 +Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm +CPU implementer : 0x41 +CPU architecture: 7 +CPU variant : 0x0 +CPU part : 0xc07 +CPU revision : 5 + +Hardware : BCM2709 +Revision : a01041 +Serial : 00000000c9e9323d diff --git a/tests/sysinfodata/arm-rpi2sysinfo.expect b/tests/sysinfodata/arm-rpi2sysinfo.expect new file mode 100644 index 0000000..acb3ad9 --- /dev/null +++ b/tests/sysinfodata/arm-rpi2sysinfo.expect @@ -0,0 +1,18 @@ +<sysinfo type='smbios'> + <processor> + <entry name='socket_destination'>0</entry> + <entry name='type'>ARMv7 Processor rev 5 (v7l)</entry> + </processor> + <processor> + <entry name='socket_destination'>1</entry> + <entry name='type'>ARMv7 Processor rev 5 (v7l)</entry> + </processor> + <processor> + <entry name='socket_destination'>2</entry> + <entry name='type'>ARMv7 Processor rev 5 (v7l)</entry> + </processor> + <processor> + <entry name='socket_destination'>3</entry> + <entry name='type'>ARMv7 Processor rev 5 (v7l)</entry> + </processor> +</sysinfo> diff --git a/tests/sysinfotest.c b/tests/sysinfotest.c index d8266a7..74e5f71 100644 --- a/tests/sysinfotest.c +++ b/tests/sysinfotest.c @@ -166,11 +166,23 @@ VIRT_TEST_MAIN(test_x86) static int test_arm(void) { - return sysinfotest_run("arm sysinfo", - NULL, - NULL, - "/sysinfodata/armcpuinfo.data", - "/sysinfodata/armsysinfo.expect"); + int ret = EXIT_SUCCESS; + + if (sysinfotest_run("arm sysinfo", + NULL, + NULL, + "/sysinfodata/armcpuinfo.data", + "/sysinfodata/armsysinfo.expect") != EXIT_SUCCESS) + ret = EXIT_FAILURE; + + if (sysinfotest_run("Raspberry Pi 2 sysinfo", + NULL, + NULL, + "/sysinfodata/arm-rpi2cpuinfo.data", + "/sysinfodata/arm-rpi2sysinfo.expect") != EXIT_SUCCESS) + ret = EXIT_FAILURE; + + return ret; } VIRT_TEST_MAIN(test_arm) -- 2.3.6

On Wed, May 13, 2015 at 01:55:43PM +0200, Michal Privoznik wrote:
Due to a kernel commit (b4b8f770e), cpuinfo format has changed on ARMs. Firstly, 'Processor: ...' may not be reported, it's replaced by 'model name: ...'. Secondly, the "Processor" string may occur in CPU name, e.g. 'ARMv7 Processor rev 5 (v7l)'. Therefore, we must firstly look for 'model name' and then for 'Processor' if not found. Moreover, lines in the cpuinfo file are shuffled, so we better not manipulate the pointer to start of internal buffer as we may lost some info.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
[snip]
diff --git a/tests/sysinfodata/arm-rpi2cpuinfo.data b/tests/sysinfodata/arm-rpi2cpuinfo.data new file mode 100644 index 0000000..41fde00 --- /dev/null +++ b/tests/sysinfodata/arm-rpi2cpuinfo.data @@ -0,0 +1,43 @@ +processor : 0 +model name : ARMv7 Processor rev 5 (v7l) +BogoMIPS : 38.40 +Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm +CPU implementer : 0x41 +CPU architecture: 7 +CPU variant : 0x0 +CPU part : 0xc07 +CPU revision : 5
It occurs to me that our code would clearer and more robust if we changed the way we dealt with the cpu info files from proc. Instead of doing all the insane strchr/strstr searches and pointer manipulation we could usefully have a generic parsing method that does: - Read file contents - Split file into lines - For each line - Split on ':' - Strip whitespace from each part - Store left hand side as key, right hand side as value in a virTypedParameter - Returns an array of arrays of virTypedParameter Then, the code for extract information from the file merely has to iterate over the outer array to get each processor. For each processor it can then do exact matches on the key name. This avoids the kind of issue where we're matching on 'processor' but that can occurr in the value too. I've no objection to your proposed patch though. This is just a thought for someone motivated enough to cleanup this area of code. Regards, 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 Wed, May 13, 2015 at 01:55:43PM +0200, Michal Privoznik wrote:
Due to a kernel commit (b4b8f770e), cpuinfo format has changed on ARMs. Firstly, 'Processor: ...' may not be reported, it's replaced by 'model name: ...'. Secondly, the "Processor" string may occur in CPU name, e.g. 'ARMv7 Processor rev 5 (v7l)'. Therefore, we must firstly look for 'model name' and then for 'Processor' if not found. Moreover, lines in the cpuinfo file are shuffled, so we better not manipulate the pointer to start of internal buffer as we may lost some info.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> ---
diff to v1: - Jan's comments worked in - added new test case (yes, there really is a space at EOL in cpuinfo on my ARM)
src/util/virsysinfo.c | 9 +++---- tests/sysinfodata/arm-rpi2cpuinfo.data | 43 ++++++++++++++++++++++++++++++++ tests/sysinfodata/arm-rpi2sysinfo.expect | 18 +++++++++++++ tests/sysinfotest.c | 22 ++++++++++++---- 4 files changed, 82 insertions(+), 10 deletions(-) create mode 100644 tests/sysinfodata/arm-rpi2cpuinfo.data create mode 100644 tests/sysinfodata/arm-rpi2sysinfo.expect
ACK Jan
participants (3)
-
Daniel P. Berrange
-
Ján Tomko
-
Michal Privoznik