From: yvinter <yves.vinter@xxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list