On Mon, Oct 5, 2020 at 12:21 PM Matt Coleman <mcoleman@xxxxxxxxx> wrote: > > 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 > > Reviewed-by: Neal Gompa <ngompa13@xxxxxxxxx> -- 真実はいつも一つ!/ Always, there's only one truth!