[libvirt] [PATCH] Add support for detecting capablities using QMP commands

2012-09-28 Thread Daniel P. Berrange
From: Daniel P. Berrange berra...@redhat.com

Start a QEMU process using

   $QEMU -S -no-user-config -nodefaults \
 -nographic -M none -qmp unix:/some/path,server,nowait

and talk QMP over stdio to discover what capabilities the
binary supports. This works for QEMU 1.2.0 or later and
for older QEMU automatically fallback to the old approach
of parsing -help and related command line args.

Signed-off-by: Daniel P. Berrange berra...@redhat.com
---
 src/qemu/qemu_capabilities.c | 419 +++
 src/qemu/qemu_capabilities.h |   5 +-
 src/qemu/qemu_driver.c   |   2 +-
 3 files changed, 385 insertions(+), 41 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index f0442ee..c977e25 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -35,6 +35,7 @@
 #include command.h
 #include bitmap.h
 #include virnodesuspend.h
+#include qemu_monitor.h
 
 #include sys/stat.h
 #include unistd.h
@@ -189,6 +190,8 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST,
 struct _qemuCaps {
 virObject object;
 
+bool usedQMP;
+
 char *binary;
 time_t mtime;
 
@@ -210,6 +213,7 @@ struct _qemuCaps {
 struct _qemuCapsCache {
 virMutex lock;
 virHashTablePtr binaries;
+char *libDir;
 };
 
 
@@ -1286,6 +1290,7 @@ static struct qemuCapsStringFlags 
qemuCapsObjectPropsVirtioNet[] = {
 };
 
 static struct qemuCapsStringFlags qemuCapsObjectPropsPciAssign[] = {
+{ rombar, QEMU_CAPS_PCI_ROMBAR },
 { configfd, QEMU_CAPS_PCI_CONFIGFD },
 { bootindex, QEMU_CAPS_PCI_BOOTINDEX },
 };
@@ -1866,6 +1871,10 @@ qemuCapsProbeQMPCommands(qemuCapsPtr caps,
 qemuCapsSet(caps, QEMU_CAPS_BLOCKJOB_ASYNC);
 else if (STREQ(name, dump-guest-memory))
 qemuCapsSet(caps, QEMU_CAPS_DUMP_GUEST_MEMORY);
+else if (STREQ(name, query-spice))
+qemuCapsSet(caps, QEMU_CAPS_SPICE);
+else if (STREQ(name, query-kvm))
+qemuCapsSet(caps, QEMU_CAPS_KVM);
 VIR_FREE(name);
 }
 VIR_FREE(commands);
@@ -1898,11 +1907,117 @@ qemuCapsProbeQMPEvents(qemuCapsPtr caps,
 }
 
 
+static int
+qemuCapsProbeQMPObjects(qemuCapsPtr caps,
+qemuMonitorPtr mon)
+{
+int nvalues;
+char **values;
+size_t i;
+
+if ((nvalues = qemuMonitorGetObjectTypes(mon, values))  0)
+return -1;
+qemuCapsProcessStringFlags(caps,
+   ARRAY_CARDINALITY(qemuCapsObjectTypes),
+   qemuCapsObjectTypes,
+   nvalues, values);
+qemuCapsFreeStringList(nvalues, values);
+
+for (i = 0 ; i  ARRAY_CARDINALITY(qemuCapsObjectProps); i++) {
+const char *type = qemuCapsObjectProps[i].type;
+if ((nvalues = qemuMonitorGetObjectProps(mon,
+ type,
+ values))  0)
+return -1;
+qemuCapsProcessStringFlags(caps,
+   qemuCapsObjectProps[i].nprops,
+   qemuCapsObjectProps[i].props,
+   nvalues, values);
+qemuCapsFreeStringList(nvalues, values);
+}
+
+/* Prefer -chardev spicevmc (detected earlier) over -device spicevmc */
+if (qemuCapsGet(caps, QEMU_CAPS_CHARDEV_SPICEVMC))
+qemuCapsClear(caps, QEMU_CAPS_DEVICE_SPICEVMC);
+
+return 0;
+}
+
+
+static int
+qemuCapsProbeQMPMachineTypes(qemuCapsPtr caps,
+ qemuMonitorPtr mon)
+{
+qemuMonitorMachineInfoPtr *machines = NULL;
+int nmachines = 0;
+int ret = -1;
+size_t i;
+
+if ((nmachines = qemuMonitorGetMachines(mon, machines))  0)
+goto cleanup;
+
+if (VIR_ALLOC_N(caps-machineTypes, nmachines)  0) {
+virReportOOMError();
+goto cleanup;
+}
+if (VIR_ALLOC_N(caps-machineAliases, nmachines)  0) {
+virReportOOMError();
+goto cleanup;
+}
+
+for (i = 0 ; i  nmachines ; i++) {
+if (machines[i]-alias) {
+if (!(caps-machineAliases[i] = strdup(machines[i]-name))) {
+virReportOOMError();
+goto cleanup;
+}
+if (!(caps-machineTypes[i] = strdup(machines[i]-alias))) {
+virReportOOMError();
+goto cleanup;
+}
+} else {
+if (!(caps-machineTypes[i] = strdup(machines[i]-name))) {
+virReportOOMError();
+goto cleanup;
+}
+}
+}
+
+ret = 0;
+
+cleanup:
+for (i = 0 ; i  nmachines ; i++)
+qemuMonitorMachineInfoFree(machines[i]);
+VIR_FREE(machines);
+return ret;
+}
+
+
+static int
+qemuCapsProbeQMPCPUDefinitions(qemuCapsPtr caps,
+   qemuMonitorPtr mon)
+{
+int ncpuDefinitions;
+char **cpuDefinitions;
+
+if ((ncpuDefinitions = 

Re: [libvirt] [PATCH] Add support for detecting capablities using QMP commands

2012-09-28 Thread Eric Blake
On 09/28/2012 09:43 AM, Daniel P. Berrange wrote:
 From: Daniel P. Berrange berra...@redhat.com
 
 Start a QEMU process using
 
$QEMU -S -no-user-config -nodefaults \
  -nographic -M none -qmp unix:/some/path,server,nowait
 
 and talk QMP over stdio to discover what capabilities the
 binary supports. This works for QEMU 1.2.0 or later and
 for older QEMU automatically fallback to the old approach
 of parsing -help and related command line args.
 
 Signed-off-by: Daniel P. Berrange berra...@redhat.com
 ---
  src/qemu/qemu_capabilities.c | 419 
 +++
  src/qemu/qemu_capabilities.h |   5 +-
  src/qemu/qemu_driver.c   |   2 +-
  3 files changed, 385 insertions(+), 41 deletions(-)

 +char *monarg = NULL;
 +char *monpath = NULL;
 +
 +if (virAsprintf(monpath, %s/%s, libDir, capabilities.monitor.sock) 
  0) {
 +virReportOOMError();
 +goto cleanup;
 +}
 +if (virAsprintf(monarg, unix:%s,server,nowait, monpath)  0) {
 +virReportOOMError();
 +goto cleanup;
 +}

I would have used virCommandAddArgFormat() instead of creating my own
temporary string here, but that's minor.

ACK; you fixed my concerns from the previous version.

Also, be sure you run 'make check'; somewhere between commit de29867 and
7022b09, you broke qemuhelptest (I'm assuming it will get fixed soon,
perhaps by this commit, so I'm not chasing which commit did the actual
breakage):

16) QEMU Help String Parsing qemu-1.2.0
... qemu-1.2.0: computed flags do not match: got
0xb0f2f1bffefff4cffd62fffddc6e, expected
0xb0f2f1bffefff4effd72fffddc6e
Missing flag 36
Missing flag 53
FAILED

-- 
Eric Blake   ebl...@redhat.com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list