]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
Add QMP probing for TPM
authorStefan Berger <stefanb@linux.vnet.ibm.com>
Fri, 12 Apr 2013 20:55:45 +0000 (16:55 -0400)
committerStefan Berger <stefanb@us.ibm.com>
Fri, 12 Apr 2013 20:55:45 +0000 (16:55 -0400)
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@linux.vnet.ibm.com>
Reviewed-by: Corey Bryant <coreyb@linux.vnet.ibm.com>
Tested-by: Corey Bryant <coreyb@linux.vnet.ibm.com>
src/qemu/qemu_capabilities.c
src/qemu/qemu_capabilities.h
src/qemu/qemu_monitor.c
src/qemu/qemu_monitor.h
src/qemu/qemu_monitor_json.c
src/qemu/qemu_monitor_json.h

index 07cda1f205c811eefdd4ad9f23dfe660b807e0e4..22628ded6c24e34fa4d80fa9b34406a2dc3defc0 100644 (file)
@@ -217,6 +217,8 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
               "ipv6-migration", /* 135 */
               "machine-opt",
               "machine-usb-opt",
+              "tpm-passthrough",
+              "tpm-tis",
     );
 
 struct _virQEMUCaps {
index 9f24d6aada02a8d64b885840b3b6ccf2d138b551..728add5620571454487a9c00228a3bd0c0df3bd2 100644 (file)
@@ -177,6 +177,8 @@ enum virQEMUCapsFlags {
     QEMU_CAPS_IPV6_MIGRATION     = 135, /* -incoming [::] */
     QEMU_CAPS_MACHINE_OPT        = 136, /* -machine xxxx*/
     QEMU_CAPS_MACHINE_USB_OPT    = 137, /* -machine xxx,usb=on/off */
+    QEMU_CAPS_DEVICE_TPM_PASSTHROUGH = 138, /* -tpmdev passthrough */
+    QEMU_CAPS_DEVICE_TPM_TIS     = 139, /* -device tpm_tis */
 
     QEMU_CAPS_LAST,                   /* this must always be the last item */
 };
index d1c6690c382b84c7ff3ac31ee648e5b12a3359e9..1b1d4a18d84dcaa2cfda3c7673977af42b670f1d 100644 (file)
@@ -3525,3 +3525,47 @@ int qemuMonitorNBDServerStop(qemuMonitorPtr mon)
 
     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 b3808a84ab4d51b38ad280797c8cc102ca1c6e65..f39f00904b94c7bb805437d2f0ec7ff3ca31edb8 100644 (file)
@@ -683,6 +683,12 @@ int qemuMonitorNBDServerAdd(qemuMonitorPtr mon,
                             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 0f548774dddd2a08d55665f23ddb4e29ba7b901c..75008749b185d99fe2d8a1f839a8dad187d864c3 100644 (file)
@@ -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"
@@ -4752,3 +4753,92 @@ qemuMonitorJSONNBDServerStop(qemuMonitorPtr mon)
     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);
+}
index 7f65392b7326557031121a82aa60345b6fb01612..5ee0d84fc307b9233c0c34684a1bba331c2645cb 100644 (file)
@@ -341,4 +341,12 @@ int qemuMonitorJSONNBDServerAdd(qemuMonitorPtr mon,
                                 const char *deviceID,
                                 bool writable);
 int qemuMonitorJSONNBDServerStop(qemuMonitorPtr mon);
+int qemuMonitorJSONGetTPMModels(qemuMonitorPtr mon,
+                                char ***tpmmodels)
+    ATTRIBUTE_NONNULL(2);
+
+int qemuMonitorJSONGetTPMTypes(qemuMonitorPtr mon,
+                               char ***tpmtypes)
+    ATTRIBUTE_NONNULL(2);
+
 #endif /* QEMU_MONITOR_JSON_H */