On Fri, Apr 05, 2013 at 10:05:52AM -0400, Stefan Berger wrote: > Probe for QEMU's QMP TPM support by querying the lists of > supported TPM models (query-tpm-models) and backend types > (query-tpm-types). > > The setting of the capability flags following the strings > returned from the commands above is only provided in the > patch where domain_conf.c gets TPM support due to dependencies > on functions only introduced there. > > Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxxxxxxxxxx> > Reviewed-by: Corey Bryant <coreyb@xxxxxxxxxxxxxxxxxx> > Tested-by: Corey Bryant <coreyb@xxxxxxxxxxxxxxxxxx> > > --- > src/qemu/qemu_capabilities.c | 2 > src/qemu/qemu_capabilities.h | 3 + > src/qemu/qemu_monitor.c | 44 +++++++++++++++++++++ > src/qemu/qemu_monitor.h | 6 ++ > src/qemu/qemu_monitor_json.c | 90 +++++++++++++++++++++++++++++++++++++++++++ > src/qemu/qemu_monitor_json.h | 8 +++ > 6 files changed, 153 insertions(+) > > Index: libvirt/src/qemu/qemu_capabilities.c > =================================================================== > --- libvirt.orig/src/qemu/qemu_capabilities.c > +++ libvirt/src/qemu/qemu_capabilities.c > @@ -216,6 +216,8 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAS > > "ipv6-migration", /* 135 */ > "machine-opt", > + "tpm-passthrough", > + "tpm-tis", > ); > > struct _virQEMUCaps { > Index: libvirt/src/qemu/qemu_capabilities.h > =================================================================== > --- libvirt.orig/src/qemu/qemu_capabilities.h > +++ libvirt/src/qemu/qemu_capabilities.h > @@ -176,6 +176,8 @@ enum virQEMUCapsFlags { > QEMU_CAPS_SCSI_MEGASAS = 134, /* -device megasas */ > QEMU_CAPS_IPV6_MIGRATION = 135, /* -incoming [::] */ > QEMU_CAPS_MACHINE_OPT = 136, /* -machine xxxx*/ > + QEMU_CAPS_DEVICE_TPM_PASSTHROUGH = 137, /* -tpmdev passthrough */ > + QEMU_CAPS_DEVICE_TPM_TIS = 138, /* -device tpm_tis */ > > QEMU_CAPS_LAST, /* this must always be the last item */ > }; > @@ -257,4 +259,5 @@ int virQEMUCapsParseDeviceStr(virQEMUCap > VIR_ENUM_DECL(virQEMUCaps); > > bool virQEMUCapsUsedQMP(virQEMUCapsPtr qemuCaps); > + > #endif /* __QEMU_CAPABILITIES_H__*/ > Index: libvirt/src/qemu/qemu_monitor.c > =================================================================== > --- libvirt.orig/src/qemu/qemu_monitor.c > +++ libvirt/src/qemu/qemu_monitor.c > @@ -3525,3 +3525,47 @@ int qemuMonitorNBDServerStop(qemuMonitor > > return qemuMonitorJSONNBDServerStop(mon); > } > + > + > +int qemuMonitorGetTPMModels(qemuMonitorPtr mon, > + char ***tpmmodels) > +{ > + VIR_DEBUG("mon=%p tpmmodels=%p", > + mon, tpmmodels); > + > + if (!mon) { > + virReportError(VIR_ERR_INVALID_ARG, "%s", > + _("monitor must not be NULL")); > + return -1; > + } > + > + if (!mon->json) { > + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", > + _("JSON monitor is required")); > + return -1; > + } > + > + return qemuMonitorJSONGetTPMModels(mon, tpmmodels); > +} > + > + > +int qemuMonitorGetTPMTypes(qemuMonitorPtr mon, > + char ***tpmtypes) > +{ > + VIR_DEBUG("mon=%p tpmtypes=%p", > + mon, tpmtypes); > + > + if (!mon) { > + virReportError(VIR_ERR_INVALID_ARG, "%s", > + _("monitor must not be NULL")); > + return -1; > + } > + > + if (!mon->json) { > + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", > + _("JSON monitor is required")); > + return -1; > + } > + > + return qemuMonitorJSONGetTPMTypes(mon, tpmtypes); > +} > Index: libvirt/src/qemu/qemu_monitor.h > =================================================================== > --- libvirt.orig/src/qemu/qemu_monitor.h > +++ libvirt/src/qemu/qemu_monitor.h > @@ -683,6 +683,12 @@ int qemuMonitorNBDServerAdd(qemuMonitorP > const char *deviceID, > bool writable); > int qemuMonitorNBDServerStop(qemuMonitorPtr); > +int qemuMonitorGetTPMModels(qemuMonitorPtr mon, > + char ***tpmmodels); > + > +int qemuMonitorGetTPMTypes(qemuMonitorPtr mon, > + char ***tpmtypes); > + > /** > * When running two dd process and using <> redirection, we need a > * shell that will not truncate files. These two strings serve that > Index: libvirt/src/qemu/qemu_monitor_json.c > =================================================================== > --- libvirt.orig/src/qemu/qemu_monitor_json.c > +++ libvirt/src/qemu/qemu_monitor_json.c > @@ -41,6 +41,7 @@ > #include "datatypes.h" > #include "virerror.h" > #include "virjson.h" > +#include "virstring.h" > > #ifdef WITH_DTRACE_PROBES > # include "libvirt_qemu_probes.h" > @@ -4693,3 +4694,92 @@ qemuMonitorJSONNBDServerStop(qemuMonitor > virJSONValueFree(reply); > return ret; > } > + > + > +static int > +qemuMonitorJSONGetStringArray(qemuMonitorPtr mon, const char *qmpCmd, > + char ***array) > +{ > + int ret; > + virJSONValuePtr cmd; > + virJSONValuePtr reply = NULL; > + virJSONValuePtr data; > + char **list = NULL; > + int n = 0; > + size_t i; > + > + *array = NULL; > + > + if (!(cmd = qemuMonitorJSONMakeCommand(qmpCmd, NULL))) > + return -1; > + > + ret = qemuMonitorJSONCommand(mon, cmd, &reply); > + > + if (ret == 0) > + ret = qemuMonitorJSONCheckError(cmd, reply); > + > + if (ret < 0) > + goto cleanup; > + > + ret = -1; > + > + if (!(data = virJSONValueObjectGet(reply, "return"))) { > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("%s reply was missing return data"), > + qmpCmd); > + goto cleanup; > + } > + > + if ((n = virJSONValueArraySize(data)) < 0) { > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("%s reply data was not an array"), > + qmpCmd); > + goto cleanup; > + } > + > + /* null-terminated list */ > + if (VIR_ALLOC_N(list, n + 1) < 0) { > + virReportOOMError(); > + goto cleanup; > + } > + > + for (i = 0 ; i < n ; i++) { > + virJSONValuePtr child = virJSONValueArrayGet(data, i); > + const char *tmp; > + > + if (!(tmp = virJSONValueGetString(child))) { > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("%s array element does not contain data"), > + qmpCmd); > + goto cleanup; > + } > + > + if (!(list[i] = strdup(tmp))) { > + virReportOOMError(); > + goto cleanup; > + } > + } > + > + ret = n; > + *array = list; > + > +cleanup: > + if (ret < 0) > + virStringFreeList(list); > + virJSONValueFree(cmd); > + virJSONValueFree(reply); > + return ret; > +} > + > +int qemuMonitorJSONGetTPMModels(qemuMonitorPtr mon, > + char ***tpmmodels) > +{ > + return qemuMonitorJSONGetStringArray(mon, "query-tpm-models", tpmmodels); > +} > + > + > +int qemuMonitorJSONGetTPMTypes(qemuMonitorPtr mon, > + char ***tpmtypes) > +{ > + return qemuMonitorJSONGetStringArray(mon, "query-tpm-types", tpmtypes); > +} Guess you never tested this on a QEMU which lacked those commands. Probing capabilities now fails for any QEMU using QMP which lacks these commands # ./daemon/libvirtd 2013-04-15 16:55:57.035+0000: 18459: info : libvirt version: 1.0.4 2013-04-15 16:55:57.035+0000: 18459: error : qemuMonitorJSONCheckError:352 : internal error unable to execute QEMU command 'query-tpm-models': The command query-tpm-models has not been found 2013-04-15 16:55:57.136+0000: 18459: error : qemuMonitorJSONCheckError:352 : internal error unable to execute QEMU command 'query-tpm-models': The command query-tpm-models has not been found 2013-04-15 16:55:57.220+0000: 18459: error : qemuMonitorJSONCheckError:352 : internal error unable to execute QEMU command 'query-tpm-models': The command query-tpm-models has not been found 2013-04-15 16:55:57.313+0000: 18459: error : qemuMonitorJSONCheckError:352 : internal error unable to execute QEMU command 'query-tpm-models': The command query-tpm-models has not been found 2013-04-15 16:55:57.415+0000: 18459: error : qemuMonitorJSONCheckError:352 : internal error unable to execute QEMU command 'query-tpm-models': The command query-tpm-models has not been found 2013-04-15 16:55:57.504+0000: 18459: error : qemuMonitorJSONCheckError:352 : internal error unable to execute QEMU command 'query-tpm-models': The command query-tpm-models has not been found 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 :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list