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>
Reviewed-by: Corey Bryant <coreyb@linux.vnet.ibm.com>
Tested-by: Corey Bryant <coreyb@linux.vnet.ibm.com>
This commit is contained in:
Stefan Berger 2013-04-12 16:55:45 -04:00 committed by Stefan Berger
parent 039a3283fc
commit ed1f031850
6 changed files with 152 additions and 0 deletions

View 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 {

View 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 */
};

View 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);
}

View 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

View 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);
}

View 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 */