From: yvinter <yves.vinter(a)bull.net>
---
src/hyperv/hyperv_driver.c | 142 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 142 insertions(+)
diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index 8e0d6b3..83fb605 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -3098,6 +3098,146 @@ hypervDomainAttachDevice(virDomainPtr domain, const char *xml)
+static virDomainPtr
+hypervDomainDefineXML(virConnectPtr conn, const char *xml)
+{
+ hypervPrivate *priv = conn->privateData;
+ virDomainDefPtr def = NULL;
+ virDomainPtr domain = NULL;
+ invokeXmlParam *params = NULL;
+ properties_t *tab_props = NULL;
+ embeddedParam embeddedparam;
+ int nb_params, i;
+ const char *selector =
"CreationClassName=Msvm_VirtualSystemManagementService";
+ char uuid_string[VIR_UUID_STRING_BUFLEN];
+
+ /* Parse XML domain description */
+ if ((def = virDomainDefParseString(xml, priv->caps, priv->xmlopt,
+ 1 << VIR_DOMAIN_VIRT_HYPERV,
VIR_DOMAIN_XML_INACTIVE)) == NULL) {
+ goto cleanup;
+ }
+
+ /* Create the domain if does not exist */
+ if (def->uuid == NULL || (domain = hypervDomainLookupByUUID(conn, def->uuid))
== NULL) {
+ /* Prepare EMBEDDED param */
+ /* Edit only VM name */
+ /* FIXME: cannot edit VM UUID */
+ embeddedparam.nbProps = 1;
+ if (VIR_ALLOC_N(tab_props, embeddedparam.nbProps) < 0)
+ goto cleanup;
+ (*tab_props).name = "ElementName";
+ (*tab_props).val = def->name;
+ embeddedparam.instanceName = "Msvm_VirtualSystemGlobalSettingData";
+ embeddedparam.prop_t = tab_props;
+
+ /* Create invokeXmlParam */
+ nb_params = 1;
+ if (VIR_ALLOC_N(params, nb_params) < 0)
+ goto cleanup;
+ (*params).name = "SystemSettingData";
+ (*params).type = EMBEDDED_PARAM;
+ (*params).param = &embeddedparam;
+
+ /* Create VM */
+ if (hypervInvokeMethod(priv, params, nb_params, "DefineVirtualSystem",
+ MSVM_VIRTUALSYSTEMMANAGEMENTSERVICE_RESOURCE_URI,
selector) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Could not create new domain %s"), def->name);
+ goto cleanup;
+ }
+
+ /* Get domain pointer */
+ domain = hypervDomainLookupByName(conn, def->name);
+
+ VIR_DEBUG("Domain created: name=%s, uuid=%s",
+ domain->name, virUUIDFormat(domain->uuid, uuid_string));
+ }
+
+ /* Set VM maximum memory */
+ if (def->mem.max_balloon > 0) {
+ if (hypervDomainSetMaxMemory(domain, def->mem.max_balloon) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Could not set VM maximum memory"));
+ }
+ }
+
+ /* Set VM memory */
+ if (def->mem.cur_balloon > 0) {
+ if (hypervDomainSetMemory(domain, def->mem.cur_balloon) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Could not set VM memory"));
+ }
+ }
+
+ /* Set VM vcpus */
+ if (def->vcpus > 0) {
+ if (hypervDomainSetVcpus(domain, def->vcpus) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Could not set VM vCPUs"));
+ }
+ }
+
+ /* Attach networks */
+ for (i = 0; i < def->nnets; i++) {
+ if (hypervDomainAttachNetwork(domain, def->nets[i]) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Could not attach network"));
+ }
+ }
+
+ /* Attach disks */
+ for (i = 0; i < def->ndisks; i++) {
+ if (hypervDomainAttachDisk(domain, def->disks[i]) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Could not attach disk"));
+ }
+ }
+
+ cleanup:
+ virDomainDefFree(def);
+ VIR_FREE(tab_props);
+ VIR_FREE(params);
+
+ return domain;
+}
+
+
+
+static virDomainPtr
+hypervDomainCreateXML(virConnectPtr conn, const char *xmlDesc, unsigned int flags)
+{
+ virDomainPtr domain;
+
+ virCheckFlags(VIR_DOMAIN_START_PAUSED | VIR_DOMAIN_START_AUTODESTROY, NULL);
+
+ /* Create the new domain */
+ domain = hypervDomainDefineXML(conn, xmlDesc);
+ if (domain == NULL)
+ return NULL;
+
+ /* Start the domain */
+ if (hypervInvokeMsvmComputerSystemRequestStateChange(domain,
MSVM_COMPUTERSYSTEM_REQUESTEDSTATE_ENABLED) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Could not start the domain %s"), domain->name);
+ return domain;
+ }
+
+ /* If the VIR_DOMAIN_START_PAUSED flag is set,
+ the guest domain will be started, but its CPUs will remain paused */
+ if (flags & VIR_DOMAIN_START_PAUSED) {
+ if (hypervDomainSuspend(domain) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Could not pause the domain %s"),
domain->name);
+ }
+ }
+
+ /* FIXME: process autodestroy flag */
+
+ return domain;
+}
+
+
+
static virDriver hypervDriver = {
.no = VIR_DRV_HYPERV,
.name = "Hyper-V",
@@ -3156,6 +3296,8 @@ static virDriver hypervDriver = {
.domainUndefineFlags = hypervDomainUndefineFlags, /* 1.2.10 */
.domainAttachDevice = hypervDomainAttachDevice, /* 1.2.10 */
.domainAttachDeviceFlags = hypervDomainAttachDeviceFlags, /* 1.2.10 */
+ .domainDefineXML = hypervDomainDefineXML, /* 1.2.10 */
+ .domainCreateXML = hypervDomainCreateXML, /* 1.2.10 */
};
--
1.9.1