[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH V1 1/6] Add QMP probing for TPM



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>

---
 src/libvirt_private.syms     |    1 
 src/qemu/qemu_capabilities.c |   61 ++++++++++++++++++++++++++++
 src/qemu/qemu_capabilities.h |    3 +
 src/qemu/qemu_monitor.c      |   44 ++++++++++++++++++++
 src/qemu/qemu_monitor.h      |    6 ++
 src/qemu/qemu_monitor_json.c |   91 +++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_monitor_json.h |    8 +++
 src/util/virutil.c           |   14 ++++++
 src/util/virutil.h           |    3 +
 9 files changed, 231 insertions(+)

Index: libvirt/src/qemu/qemu_capabilities.c
===================================================================
--- libvirt.orig/src/qemu/qemu_capabilities.c
+++ libvirt/src/qemu/qemu_capabilities.c
@@ -210,6 +210,8 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAS
 
               "rng-random", /* 130 */
               "rng-egd",
+              "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
@@ -171,6 +171,8 @@ enum virQEMUCapsFlags {
     QEMU_CAPS_OBJECT_RNG_RANDOM  = 130, /* the rng-random backend for
                                            virtio rng */
     QEMU_CAPS_OBJECT_RNG_EGD     = 131, /* EGD protocol daemon for rng */
+    QEMU_CAPS_DEVICE_TPM_PASSTHROUGH = 132, /* -tpmdev passthrough */
+    QEMU_CAPS_DEVICE_TPM_TIS     = 133, /* -device tpm_tis */
 
     QEMU_CAPS_LAST,                   /* this must always be the last item */
 };
@@ -252,4 +254,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
@@ -3522,3 +3522,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
@@ -4707,3 +4707,94 @@ 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;
+    }
+
+    if (VIR_ALLOC_N(list, n) < 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 && list) {
+        for (i = 0 ; i < n ; i++)
+            VIR_FREE(list[i]);
+        VIR_FREE(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: libvirt/src/qemu/qemu_monitor_json.h
===================================================================
--- libvirt.orig/src/qemu/qemu_monitor_json.h
+++ libvirt/src/qemu/qemu_monitor_json.h
@@ -341,4 +341,12 @@ int qemuMonitorJSONNBDServerAdd(qemuMoni
                                 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 */
Index: libvirt/src/libvirt_private.syms
===================================================================
--- libvirt.orig/src/libvirt_private.syms
+++ libvirt/src/libvirt_private.syms
@@ -1886,6 +1886,7 @@ virSetUIDGIDWithCaps;
 virSkipSpaces;
 virSkipSpacesAndBackslash;
 virSkipSpacesBackwards;
+virStrArrayHasString;
 virStrcpy;
 virStrIsPrint;
 virStrncpy;
Index: libvirt/src/util/virutil.c
===================================================================
--- libvirt.orig/src/util/virutil.c
+++ libvirt/src/util/virutil.c
@@ -3379,3 +3379,17 @@ cleanup:
     VIR_FREE(buf);
     return ret;
 }
+
+
+bool
+virStrArrayHasString(char **strings, size_t n_strings, const char *needle)
+{
+    size_t i;
+
+    for (i = 0; i < n_strings; i++) {
+        if (STREQ(strings[i], needle))
+            return true;
+    }
+
+    return false;
+}
Index: libvirt/src/util/virutil.h
===================================================================
--- libvirt.orig/src/util/virutil.h
+++ libvirt/src/util/virutil.h
@@ -297,4 +297,7 @@ int virGetDeviceUnprivSGIO(const char *p
 char * virGetUnprivSGIOSysfsPath(const char *path,
                                  const char *sysfs_dir);
 
+bool virStrArrayHasString(char **strings, size_t n_strings,
+                          const char *needle);
+
 #endif /* __VIR_UTIL_H__ */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]