[libvirt] [PATCHv3 2/6] qemu: Add monitor APIs to fetch CPUID data from QEMU

Jiri Denemark jdenemar at redhat.com
Thu Nov 7 21:57:52 UTC 2013


On Mon, Nov 04, 2013 at 14:55:03 +0100, Peter Krempa wrote:
> From: Jiri Denemark <jdenemar at redhat.com>
> 
> The qemu monitor supports retrieval of actual CPUID bits presented to
> the guest using QMP monitor. Add APIs to extract these information and
> tests for them.
> 
> Signed-off-by: Peter Krempa <pkrempa at redhat.com>
> ---
> 
> Notes:
>     Version 3:
>     - removed unneeded error state
>     - fixed typo in error message
>     
>     Version 2:
>     - unified global and JSON monitor func signatures
>     - changed return values so that errors can be differenitated from lack of support
>     - code is conditionally run only when architecture matches
> 
>  src/qemu/qemu_monitor.c                            |  31 +++++
>  src/qemu/qemu_monitor.h                            |   4 +
>  src/qemu/qemu_monitor_json.c                       | 133 +++++++++++++++++++++
>  src/qemu/qemu_monitor_json.h                       |   2 +
>  tests/Makefile.am                                  |   1 +
>  .../qemumonitorjson-getcpu-full.data               |   5 +
>  .../qemumonitorjson-getcpu-full.json               |  46 +++++++
>  .../qemumonitorjson-getcpu-host.data               |   6 +
>  .../qemumonitorjson-getcpu-host.json               |  45 +++++++
>  tests/qemumonitorjsontest.c                        |  75 ++++++++++++
>  10 files changed, 348 insertions(+)
>  create mode 100644 tests/qemumonitorjsondata/qemumonitorjson-getcpu-full.data
>  create mode 100644 tests/qemumonitorjsondata/qemumonitorjson-getcpu-full.json
>  create mode 100644 tests/qemumonitorjsondata/qemumonitorjson-getcpu-host.data
>  create mode 100644 tests/qemumonitorjsondata/qemumonitorjson-getcpu-host.json
> 
> diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
> index 2bafe28..e865808 100644
> --- a/src/qemu/qemu_monitor.c
> +++ b/src/qemu/qemu_monitor.c
> @@ -3926,3 +3926,34 @@ qemuMonitorSetDomainLog(qemuMonitorPtr mon, int logfd)
> 
>      return 0;
>  }
> +
> +
> +/**
> + * qemuMonitorJSONGetGuestCPU:
> + * @mon: Pointer to the monitor
> + * @arch: arch of the guest
> + *
> + * Retrieve the definition of the guest CPU from a running qemu instance.
> + *
> + * Returns the cpu definition object. On error returns NULL.
> + */
> +virCPUDataPtr
> +qemuMonitorGetGuestCPU(qemuMonitorPtr mon,
> +                       virArch arch)
> +{
> +    VIR_DEBUG("mon=%p, arch='%s'", mon, virArchToString(arch));
> +
> +    if (!mon) {
> +        virReportError(VIR_ERR_INVALID_ARG, "%s",
> +                       _("monitor must not be NULL"));
> +        return NULL;
> +    }
> +
> +    if (!mon->json) {
> +        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
> +                       _("JSON monitor is required"));
> +        return NULL;
> +    }
> +
> +    return qemuMonitorJSONGetGuestCPU(mon, arch);
> +}
> diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
> index 06ba7e8..ecc6d7b 100644
> --- a/src/qemu/qemu_monitor.h
> +++ b/src/qemu/qemu_monitor.h
> @@ -32,6 +32,7 @@
>  # include "virhash.h"
>  # include "virjson.h"
>  # include "device_conf.h"
> +# include "cpu/cpu.h"
> 
>  typedef struct _qemuMonitor qemuMonitor;
>  typedef qemuMonitor *qemuMonitorPtr;
> @@ -763,6 +764,9 @@ int qemuMonitorGetDeviceAliases(qemuMonitorPtr mon,
> 
>  int qemuMonitorSetDomainLog(qemuMonitorPtr mon, int logfd);
> 
> +virCPUDataPtr qemuMonitorGetGuestCPU(qemuMonitorPtr mon,
> +                                     virArch arch);
> +
>  /**
>   * When running two dd process and using <> redirection, we need a
>   * shell that will not truncate files.  These two strings serve that
> diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
> index 05f8aa6..e738fe3 100644
> --- a/src/qemu/qemu_monitor_json.c
> +++ b/src/qemu/qemu_monitor_json.c
> @@ -42,6 +42,7 @@
>  #include "virerror.h"
>  #include "virjson.h"
>  #include "virstring.h"
> +#include "cpu/cpu_x86.h"
> 
>  #ifdef WITH_DTRACE_PROBES
>  # include "libvirt_qemu_probes.h"
> @@ -49,6 +50,7 @@
> 
>  #define VIR_FROM_THIS VIR_FROM_QEMU
> 
> +#define QOM_CPU_PATH  "/machine/unattached/device[0]"
> 
>  #define LINE_ENDING "\r\n"
> 
> @@ -5454,3 +5456,134 @@ cleanup:
>      VIR_FREE(paths);
>      return ret;
>  }
> +
> +
> +static int
> +qemuMonitorJSONParseCPUx86FeatureWord(virJSONValuePtr data,
> +                                      virCPUx86CPUID *cpuid)
> +{
> +    const char *reg;
> +    unsigned long long fun;
> +    unsigned long long features;
> +
> +    memset(cpuid, 0, sizeof(*cpuid));
> +
> +    if (!(reg = virJSONValueObjectGetString(data, "cpuid-register"))) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                       _("missing cpuid-register in CPU data"));
> +        return -1;
> +    }
> +    if (virJSONValueObjectGetNumberUlong(data, "cpuid-input-eax", &fun)) {

I guess this should have been "if (... < 0)", right?

> +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                       _("missing or invalid cpuid-input-eax in CPU data"));
> +        return -1;
> +    }
> +    if (virJSONValueObjectGetNumberUlong(data, "features", &features) < 0) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                       _("missing or invalid features in CPU data"));
> +        return -1;
> +    }
...

ACK

Jirka




More information about the libvir-list mailing list