Re: [PATCH v2 05/10] hyperv: implement connectGetCapabilities

2020-10-05 Thread Neal Gompa
On Mon, Oct 5, 2020 at 12:21 PM Matt Coleman  wrote:
>
> Co-authored-by: Sri Ramanujam 
> Signed-off-by: Matt Coleman 
> ---
>  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(, WIN32_COMPUTERSYSTEMPRODUCT_WQL_SELECT);
> +if (hypervGetWmiClass(Win32_ComputerSystemProduct, ) < 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 


-- 
真実はいつも一つ!/ Always, there's only one truth!




[PATCH v2 05/10] hyperv: implement connectGetCapabilities

2020-10-05 Thread Matt Coleman
Co-authored-by: Sri Ramanujam 
Signed-off-by: Matt Coleman 
---
 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(, WIN32_COMPUTERSYSTEMPRODUCT_WQL_SELECT);
+if (hypervGetWmiClass(Win32_ComputerSystemProduct, ) < 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