Co-authored-by: Sri Ramanujam <sramanujam@xxxxxxxxx> Signed-off-by: Matt Coleman <matt@xxxxxxxxx> --- src/hyperv/hyperv_driver.c | 90 +++++++++++++++++++++++++++++++++++++ src/hyperv/hyperv_private.h | 2 + 2 files changed, 92 insertions(+) diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c index 3e4563252e..93e08c54c0 100644 --- a/src/hyperv/hyperv_driver.c +++ b/src/hyperv/hyperv_driver.c @@ -36,6 +36,7 @@ #include "openwsman.h" #include "virstring.h" #include "virkeycode.h" +#include "domain_conf.h" #define VIR_FROM_THIS VIR_FROM_HYPERV @@ -283,6 +284,76 @@ hypervGetMemSDByVSSDInstanceId(hypervPrivate *priv, const char *id, +/* + * API-specific utility functions + */ + +static int +hypervLookupHostSystemBiosUuid(hypervPrivate *priv, unsigned char *uuid) +{ + Win32_ComputerSystemProduct *computerSystem = NULL; + g_auto(virBuffer) query = VIR_BUFFER_INITIALIZER; + int result = -1; + + virBufferAddLit(&query, WIN32_COMPUTERSYSTEMPRODUCT_WQL_SELECT); + if (hypervGetWmiClass(Win32_ComputerSystemProduct, &computerSystem) < 0) + goto cleanup; + + if (virUUIDParse(computerSystem->data.common->UUID, uuid) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not parse UUID from string '%s'"), + computerSystem->data.common->UUID); + goto cleanup; + } + result = 0; + + cleanup: + hypervFreeObject(priv, (hypervObject *) computerSystem); + + return result; +} + +static virCapsPtr +hypervCapsInit(hypervPrivate *priv) +{ + virCapsPtr caps = NULL; + virCapsGuestPtr guest = NULL; + + caps = virCapabilitiesNew(VIR_ARCH_X86_64, 1, 1); + + if (!caps) + return NULL; + + if (hypervLookupHostSystemBiosUuid(priv, caps->host.host_uuid) < 0) + goto error; + + /* i686 caps */ + guest = virCapabilitiesAddGuest(caps, VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_I686, + NULL, NULL, 0, NULL); + if (!guest) + goto error; + + if (!virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_HYPERV, NULL, NULL, 0, NULL)) + goto error; + + /* x86_64 caps */ + guest = virCapabilitiesAddGuest(caps, VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_X86_64, + NULL, NULL, 0, NULL); + if (!guest) + goto error; + + if (!virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_HYPERV, NULL, NULL, 0, NULL)) + goto error; + + return caps; + + error: + virObjectUnref(caps); + return NULL; +} + + + /* * Driver functions */ @@ -298,6 +369,9 @@ hypervFreePrivate(hypervPrivate **priv) wsmc_release((*priv)->client); } + if ((*priv)->caps) + virObjectUnref((*priv)->caps); + hypervFreeParsedUri(&(*priv)->parsedUri); VIR_FREE(*priv); } @@ -408,6 +482,11 @@ hypervConnectOpen(virConnectPtr conn, virConnectAuthPtr auth, if (hypervInitConnection(conn, priv, username, password) < 0) goto cleanup; + /* set up capabilities */ + priv->caps = hypervCapsInit(priv); + if (!priv->caps) + goto cleanup; + conn->privateData = priv; priv = NULL; result = VIR_DRV_OPEN_SUCCESS; @@ -464,6 +543,16 @@ hypervConnectGetHostname(virConnectPtr conn) +static char* +hypervConnectGetCapabilities(virConnectPtr conn) +{ + hypervPrivate *priv = conn->privateData; + + return virCapabilitiesFormatXML(priv->caps); +} + + + static int hypervNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info) { @@ -1601,6 +1690,7 @@ static virHypervisorDriver hypervHypervisorDriver = { .connectGetType = hypervConnectGetType, /* 0.9.5 */ .connectGetHostname = hypervConnectGetHostname, /* 0.9.5 */ .nodeGetInfo = hypervNodeGetInfo, /* 0.9.5 */ + .connectGetCapabilities = hypervConnectGetCapabilities, /* 6.9.0 */ .connectListDomains = hypervConnectListDomains, /* 0.9.5 */ .connectNumOfDomains = hypervConnectNumOfDomains, /* 0.9.5 */ .connectListAllDomains = hypervConnectListAllDomains, /* 0.10.2 */ diff --git a/src/hyperv/hyperv_private.h b/src/hyperv/hyperv_private.h index b502e71d83..cf08bf542b 100644 --- a/src/hyperv/hyperv_private.h +++ b/src/hyperv/hyperv_private.h @@ -26,6 +26,7 @@ #include "virerror.h" #include "hyperv_util.h" #include "openwsman.h" +#include "capabilities.h" typedef enum _hypervWmiVersion hypervWmiVersion; enum _hypervWmiVersion { @@ -38,4 +39,5 @@ struct _hypervPrivate { hypervParsedUri *parsedUri; WsManClient *client; hypervWmiVersion wmiVersion; + virCapsPtr caps; }; -- 2.27.0