hyperv: implement connectGetCapabilities

Co-authored-by: Sri Ramanujam <sramanujam@datto.com>
Signed-off-by: Matt Coleman <matt@datto.com>
Reviewed-by: Neal Gompa <ngompa13@gmail.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Matt Coleman 2020-10-05 12:20:10 -04:00 committed by Michal Privoznik
parent 110e649f8a
commit ab75d6b17c
2 changed files with 92 additions and 0 deletions

View File

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

View File

@ -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;
};