[Libguestfs] [PATCH] p2v: Use lscpu instead of libvirt to get CPU information.

Pino Toscano ptoscano at redhat.com
Fri Mar 24 10:39:52 UTC 2017


On Thursday, 23 March 2017 15:31:36 CET Richard W.M. Jones wrote:
> Don't get the CPU information from libvirt, because including libvirt
> and all dependencies in the virt-p2v ISO bloats everything.
> 
> Instead get most of the information we need from the util-linux
> program 'lscpu'.
> 
> Unfortunately the CPU model cannot be retrieved.

Theoretically, at least for Intel CPUs it could be mapped from the
"Model" field; there's a table on the intel website:
https://software.intel.com/en-us/articles/intel-architecture-and-processor-identification-with-cpuid-model-and-family-numbers
although it is not up-to-date...

> @@ -65,235 +57,166 @@ free_cpu_config (struct cpu_config *cpu)
>  }
>  
>  /**
> - * Read flags from F</proc/cpuinfo>.
> + * Get the output of lscpu as a list of (key, value) pairs (as a
> + * flattened list of strings).
>   */
> -static void
> -cpuinfo_flags (struct cpu_config *cpu)
> +static char **
> +get_lscpu (void)
>  {
>    const char *cmd;
>    CLEANUP_PCLOSE FILE *fp = NULL;
> -  CLEANUP_FREE char *flag = NULL;
> +  CLEANUP_FREE char *line = NULL;
>    ssize_t len;
>    size_t buflen = 0;
> +  char **ret = NULL;
> +  size_t ret_size = 0;
>  
> -  /* Get the flags, one per line. */
> -  cmd = "< /proc/cpuinfo "
> -#if defined(__arm__)
> -    "grep ^Features"
> -#else
> -    "grep ^flags"
> -#endif
> -    " | awk '{ for (i = 3; i <= NF; ++i) { print $i }; exit }'";
> +  cmd = "lscpu";
>  
>    fp = popen (cmd, "re");
>    if (fp == NULL) {
> -    perror ("/proc/cpuinfo");
> -    return;
> +    perror (cmd);
> +    return NULL;
>    }
>  
> -  while (errno = 0, (len = getline (&flag, &buflen, fp)) != -1) {
> -    if (len > 0 && flag[len-1] == '\n')
> -      flag[len-1] = '\0';
> -
> -    if (STREQ (flag, "acpi"))
> -      cpu->acpi = 1;
> -    else if (STREQ (flag, "apic"))
> -      cpu->apic = 1;
> -    else if (STREQ (flag, "pae"))
> -      cpu->pae = 1;
> +  ret = malloc (sizeof (char *));
> +  if (ret == NULL) error (EXIT_FAILURE, errno, "malloc");
> +  ret[0] = NULL;
> +
> +  while (errno = 0, (len = getline (&line, &buflen, fp)) != -1) {

I know it was already in the previous version, but why the need to
reset errno for each iteration?  IIRC the return code of getline can
be trusted to know when an error happened.

> +  if (vendor) {
> +    /* Note this mapping comes from /usr/share/libvirt/cpu_map.xml */
> +    if (STREQ (vendor, "GenuineIntel"))
> +      cpu->vendor = strdup ("Intel");
> +    else if (STREQ (vendor, "AuthenticAMD"))
> +      cpu->vendor = strdup ("AMD");
> +    /* Currently aarch64 lscpu has no Vendor ID XXX. */
> +  }

How do tools such as dmidecode (use `dmidecode --type 4` to get only
the processor information) or lshw (`lshw -class processor`) behave on
aarch64?
- dmidecode does not have a machine parseable output, but does provide
  the CPU model ID
- lshw has both XML and JSON output, but it does not seem to provide the
  CPU model ID

The rest of the changes would look fine otherwise.

-- 
Pino Toscano
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: This is a digitally signed message part.
URL: <http://listman.redhat.com/archives/libguestfs/attachments/20170324/25a5de3c/attachment.sig>


More information about the Libguestfs mailing list