diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index c674ff2232..f79b4b4bb4 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -647,11 +647,30 @@ xenUnifiedConnectNumOfDomains(virConnectPtr conn) static virDomainPtr xenUnifiedDomainCreateXML(virConnectPtr conn, - const char *xmlDesc, unsigned int flags) + const char *xml, + unsigned int flags) { + xenUnifiedPrivatePtr priv = conn->privateData; + virDomainDefPtr def = NULL; + virDomainPtr ret = NULL; + virCheckFlags(0, NULL); - return xenDaemonCreateXML(conn, xmlDesc); + if (!(def = virDomainDefParseString(xml, priv->caps, priv->xmlopt, + 1 << VIR_DOMAIN_VIRT_XEN, + VIR_DOMAIN_XML_INACTIVE))) + goto cleanup; + + if (xenDaemonCreateXML(conn, def) < 0) + goto cleanup; + + ret = virGetDomain(conn, def->name, def->uuid); + if (ret) + ret->id = def->id; + +cleanup: + virDomainDefFree(def); + return ret; } static virDomainPtr @@ -1292,18 +1311,31 @@ static char * xenUnifiedDomainGetXMLDesc(virDomainPtr dom, unsigned int flags) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + virDomainDefPtr minidef = NULL; + virDomainDefPtr def = NULL; + char *ret = NULL; + + if (!(minidef = xenGetDomainDefForDom(dom))) + goto cleanup; if (dom->id < 0 && priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) { - return xenXMDomainGetXMLDesc(dom, flags); + def = xenXMDomainGetXMLDesc(dom->conn, minidef); } else { - char *cpus, *res; + char *cpus; xenUnifiedLock(priv); cpus = xenDomainUsedCpus(dom); xenUnifiedUnlock(priv); - res = xenDaemonDomainGetXMLDesc(dom, flags, cpus); + def = xenDaemonDomainGetXMLDesc(dom->conn, minidef, cpus); VIR_FREE(cpus); - return res; } + + if (def) + ret = virDomainDefFormat(def, flags); + +cleanup: + virDomainDefFree(def); + virDomainDefFree(minidef); + return ret; } @@ -1436,10 +1468,21 @@ xenUnifiedDomainMigratePerform(virDomainPtr dom, const char *dname, unsigned long resource) { + virDomainDefPtr def = NULL; + int ret = -1; + virCheckFlags(XEN_MIGRATION_FLAGS, -1); - return xenDaemonDomainMigratePerform(dom, cookie, cookielen, uri, - flags, dname, resource); + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + ret = xenDaemonDomainMigratePerform(dom->conn, def, + cookie, cookielen, uri, + flags, dname, resource); + +cleanup: + virDomainDefFree(def); + return ret; } static virDomainPtr @@ -1450,45 +1493,37 @@ xenUnifiedDomainMigrateFinish(virConnectPtr dconn, const char *uri ATTRIBUTE_UNUSED, unsigned long flags) { - virDomainPtr dom = NULL; - char *domain_xml = NULL; - virDomainPtr dom_new = NULL; + xenUnifiedPrivatePtr priv = dconn->privateData; + virDomainPtr ret = NULL; + virDomainDefPtr minidef = NULL; + virDomainDefPtr def = NULL; virCheckFlags(XEN_MIGRATION_FLAGS, NULL); - if (!(dom = xenUnifiedDomainLookupByName(dconn, dname))) - return NULL; + if (!(minidef = xenGetDomainDefForName(dconn, dname))) + goto cleanup; if (flags & VIR_MIGRATE_PERSIST_DEST) { - domain_xml = xenDaemonDomainGetXMLDesc(dom, 0, NULL); - if (! domain_xml) { - virReportError(VIR_ERR_MIGRATE_PERSIST_FAILED, - "%s", _("failed to get XML representation of migrated domain")); - goto error; - } + if (!(def = xenDaemonDomainGetXMLDesc(dconn, minidef, NULL))) + goto cleanup; - dom_new = xenDaemonDomainDefineXML(dconn, domain_xml); - if (! dom_new) { - virReportError(VIR_ERR_MIGRATE_PERSIST_FAILED, - "%s", _("failed to define domain on destination host")); - goto error; + if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) { + if (xenXMDomainDefineXML(dconn, def) < 0) + goto cleanup; + } else { + if (xenDaemonDomainDefineXML(dconn, def) < 0) + goto cleanup; } - - /* Free additional reference added by Define */ - virDomainFree(dom_new); } - VIR_FREE(domain_xml); + ret = virGetDomain(dconn, minidef->name, minidef->uuid); + if (ret) + ret->id = minidef->id; - return dom; - - -error: - virDomainFree(dom); - - VIR_FREE(domain_xml); - - return NULL; +cleanup: + virDomainDefFree(def); + virDomainDefFree(minidef); + return ret; } static int @@ -1563,23 +1598,52 @@ static virDomainPtr xenUnifiedDomainDefineXML(virConnectPtr conn, const char *xml) { xenUnifiedPrivatePtr priv = conn->privateData; + virDomainDefPtr def = NULL; + virDomainPtr ret = NULL; - if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainDefineXML(conn, xml); - else - return xenDaemonDomainDefineXML(conn, xml); + if (!(def = virDomainDefParseString(xml, priv->caps, priv->xmlopt, + 1 << VIR_DOMAIN_VIRT_XEN, + VIR_DOMAIN_XML_INACTIVE))) + goto cleanup; + + if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) { + if (xenXMDomainDefineXML(conn, def) < 0) + goto cleanup; + def = NULL; /* XM driver owns it now */ + } else { + if (xenDaemonDomainDefineXML(conn, def) < 0) + goto cleanup; + } + + ret = virGetDomain(conn, def->name, def->uuid); + if (ret) + ret->id = -1; + +cleanup: + virDomainDefFree(def); + return ret; } static int xenUnifiedDomainUndefineFlags(virDomainPtr dom, unsigned int flags) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + virDomainDefPtr def = NULL; + int ret = -1; virCheckFlags(0, -1); + + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainUndefine(dom); + ret = xenXMDomainUndefine(dom->conn, def); else - return xenDaemonDomainUndefine(dom); + ret = xenDaemonDomainUndefine(dom->conn, def); + +cleanup: + virDomainDefFree(def); + return ret; } static int diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index 005afdb852..de0af5d343 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -1614,35 +1614,21 @@ cleanup: /** * xenDaemonDomainGetXMLDesc: * @domain: a domain object - * @flags: potential dump flags * @cpus: list of cpu the domain is pinned to. * - * Provide an XML description of the domain. + * Get the XML description of the domain as a structure. * - * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of error. - * the caller must free() the returned value. + * Returns a virDomainDefPtr instance, or NULL in case of error. */ -char * -xenDaemonDomainGetXMLDesc(virDomainPtr domain, - unsigned int flags, +virDomainDefPtr +xenDaemonDomainGetXMLDesc(virConnectPtr conn, + virDomainDefPtr minidef, const char *cpus) { - virDomainDefPtr def; - char *xml; - - /* Flags checked by virDomainDefFormat */ - - if (!(def = xenDaemonDomainFetch(domain->conn, - domain->id, - domain->name, - cpus))) - return NULL; - - xml = virDomainDefFormat(def, flags); - - virDomainDefFree(def); - - return xml; + return xenDaemonDomainFetch(conn, + minidef->id, + minidef->name, + cpus); } @@ -2142,7 +2128,7 @@ xenDaemonLookupByUUID(virConnectPtr conn, const unsigned char *uuid) /** * xenDaemonCreateXML: * @conn: pointer to the hypervisor connection - * @xmlDesc: an XML description of the domain + * @def: domain configuration * @flags: an optional set of virDomainFlags * * Launch a new Linux guest domain, based on an XML description similar @@ -2151,25 +2137,25 @@ xenDaemonLookupByUUID(virConnectPtr conn, const unsigned char *uuid) * * Returns a new domain object or NULL in case of failure */ -virDomainPtr -xenDaemonCreateXML(virConnectPtr conn, const char *xmlDesc) +int +xenDaemonCreateXML(virConnectPtr conn, virDomainDefPtr def) { int ret; char *sexpr; - virDomainPtr dom = NULL; + const char *tmp; + struct sexpr *root; xenUnifiedPrivatePtr priv = conn->privateData; - virDomainDefPtr def; - if (!(def = virDomainDefParseString(xmlDesc, priv->caps, priv->xmlopt, - 1 << VIR_DOMAIN_VIRT_XEN, - VIR_DOMAIN_XML_INACTIVE))) - return NULL; - - if (!(sexpr = xenFormatSxpr(conn, def, priv->xendConfigVersion))) { - virDomainDefFree(def); - return NULL; + if (def->id != -1) { + virReportError(VIR_ERR_OPERATION_INVALID, + _("Domain %s is already running"), + def->name); + return -1; } + if (!(sexpr = xenFormatSxpr(conn, def, priv->xendConfigVersion))) + return -1; + ret = xenDaemonDomainCreateXML(conn, sexpr); VIR_FREE(sexpr); if (ret != 0) { @@ -2178,9 +2164,20 @@ xenDaemonCreateXML(virConnectPtr conn, const char *xmlDesc) /* This comes before wait_for_devices, to ensure that latter cleanup will destroy the domain upon failure */ - if (!(dom = virDomainLookupByName(conn, def->name))) + root = sexpr_get(conn, "/xend/domain/%s?detail=1", def->name); + if (root == NULL) goto error; + tmp = sexpr_node(root, "domain/domid"); + if (!tmp) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Domain %s did not start"), + def->name); + goto error; + } + if (tmp) + def->id = sexpr_int(root, "domain/domid"); + if (xend_wait_for_devices(conn, def->name) < 0) goto error; @@ -2188,16 +2185,13 @@ xenDaemonCreateXML(virConnectPtr conn, const char *xmlDesc) goto error; virDomainDefFree(def); - return dom; + return 0; error: /* Make sure we don't leave a still-born domain around */ - if (dom != NULL) { + if (def->id != -1) xenDaemonDomainDestroy(conn, def); - virObjectUnref(dom); - } - virDomainDefFree(def); - return NULL; + return -1; } /** @@ -2667,7 +2661,8 @@ xenDaemonDomainMigratePrepare(virConnectPtr dconn ATTRIBUTE_UNUSED, } int -xenDaemonDomainMigratePerform(virDomainPtr domain, +xenDaemonDomainMigratePerform(virConnectPtr conn, + virDomainDefPtr def, const char *cookie ATTRIBUTE_UNUSED, int cookielen ATTRIBUTE_UNUSED, const char *uri, @@ -2811,7 +2806,7 @@ xenDaemonDomainMigratePerform(virDomainPtr domain, * to our advantage since all parameters supported and required * by current xend can be included without breaking older xend. */ - ret = xend_op(domain->conn, domain->name, + ret = xend_op(conn, def->name, "op", "migrate", "destination", hostname, "live", live, @@ -2824,34 +2819,24 @@ xenDaemonDomainMigratePerform(virDomainPtr domain, VIR_FREE(hostname); if (ret == 0 && undefined_source) - xenDaemonDomainUndefine(domain); + xenDaemonDomainUndefine(conn, def); VIR_DEBUG("migration done"); return ret; } -virDomainPtr -xenDaemonDomainDefineXML(virConnectPtr conn, const char *xmlDesc) +int +xenDaemonDomainDefineXML(virConnectPtr conn, virDomainDefPtr def) { - int ret; + int ret = -1; char *sexpr; - virDomainPtr dom; xenUnifiedPrivatePtr priv = conn->privateData; - virDomainDefPtr def; - - if (!(def = virDomainDefParseString(xmlDesc, priv->caps, priv->xmlopt, - 1 << VIR_DOMAIN_VIRT_XEN, - VIR_DOMAIN_XML_INACTIVE))) { - virReportError(VIR_ERR_XML_ERROR, - "%s", _("failed to parse domain description")); - return NULL; - } if (!(sexpr = xenFormatSxpr(conn, def, priv->xendConfigVersion))) { virReportError(VIR_ERR_XML_ERROR, "%s", _("failed to build sexpr")); - goto error; + goto cleanup; } ret = xend_op(conn, "", "op", "new", "config", sexpr, NULL); @@ -2859,20 +2844,15 @@ xenDaemonDomainDefineXML(virConnectPtr conn, const char *xmlDesc) if (ret != 0) { virReportError(VIR_ERR_XEN_CALL, _("Failed to create inactive domain %s"), def->name); - goto error; + goto cleanup; } - dom = virDomainLookupByName(conn, def->name); - if (dom == NULL) { - goto error; - } - virDomainDefFree(def); - return dom; + ret = 0; - error: - virDomainDefFree(def); - return NULL; +cleanup: + return ret; } + int xenDaemonDomainCreate(virConnectPtr conn, virDomainDefPtr def) @@ -2892,9 +2872,9 @@ xenDaemonDomainCreate(virConnectPtr conn, } int -xenDaemonDomainUndefine(virDomainPtr domain) +xenDaemonDomainUndefine(virConnectPtr conn, virDomainDefPtr def) { - return xend_op(domain->conn, domain->name, "op", "delete", NULL); + return xend_op(conn, def->name, "op", "delete", NULL); } /** diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h index 35dfab920e..880566c0e6 100644 --- a/src/xen/xend_internal.h +++ b/src/xen/xend_internal.h @@ -118,8 +118,9 @@ int xenDaemonDomainGetState(virConnectPtr conn, virDomainDefPtr def, int *state, int *reason); -char *xenDaemonDomainGetXMLDesc(virDomainPtr domain, unsigned int flags, - const char *cpus); +virDomainDefPtr xenDaemonDomainGetXMLDesc(virConnectPtr conn, + virDomainDefPtr def, + const char *cpus); unsigned long long xenDaemonDomainGetMaxMemory(virConnectPtr conn, virDomainDefPtr def); char **xenDaemonListDomainsOld(virConnectPtr xend); @@ -139,10 +140,12 @@ int xenDaemonDetachDeviceFlags(virDomainPtr domain, const char *xml, unsigned int flags); -virDomainPtr xenDaemonDomainDefineXML(virConnectPtr xend, const char *sexpr); +int xenDaemonDomainDefineXML(virConnectPtr conn, + virDomainDefPtr def); int xenDaemonDomainCreate(virConnectPtr conn, virDomainDefPtr def); -int xenDaemonDomainUndefine(virDomainPtr domain); +int xenDaemonDomainUndefine(virConnectPtr conn, + virDomainDefPtr def); int xenDaemonDomainSetVcpus (virDomainPtr domain, unsigned int vcpus); @@ -167,11 +170,18 @@ int xenDaemonDomainGetAutostart (virDomainPtr dom, int xenDaemonDomainSetAutostart (virDomainPtr domain, int autostart); -virDomainPtr xenDaemonCreateXML(virConnectPtr conn, const char *xmlDesc); +int xenDaemonCreateXML(virConnectPtr conn, virDomainDefPtr def); virDomainDefPtr xenDaemonLookupByUUID(virConnectPtr conn, const unsigned char *uuid); virDomainDefPtr xenDaemonLookupByName(virConnectPtr conn, const char *domname); -int xenDaemonDomainMigratePrepare (virConnectPtr dconn, char **cookie, int *cookielen, const char *uri_in, char **uri_out, unsigned long flags, const char *dname, unsigned long resource); -int xenDaemonDomainMigratePerform (virDomainPtr domain, const char *cookie, int cookielen, const char *uri, unsigned long flags, const char *dname, unsigned long resource); +int xenDaemonDomainMigratePrepare (virConnectPtr dconn, + char **cookie, int *cookielen, + const char *uri_in, char **uri_out, + unsigned long flags, const char *dname, unsigned long resource); +int xenDaemonDomainMigratePerform (virConnectPtr conn, + virDomainDefPtr def, + const char *cookie, int cookielen, + const char *uri, unsigned long flags, + const char *dname, unsigned long resource); int xenDaemonDomainBlockPeek (virDomainPtr domain, const char *path, unsigned long long offset, size_t size, void *buffer); diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c index 88de7d5337..77b351f541 100644 --- a/src/xen/xm_internal.c +++ b/src/xen/xm_internal.c @@ -501,28 +501,29 @@ error: * Turn a config record into a lump of XML describing the * domain, suitable for later feeding for virDomainCreateXML */ -char * -xenXMDomainGetXMLDesc(virDomainPtr domain, unsigned int flags) +virDomainDefPtr +xenXMDomainGetXMLDesc(virConnectPtr conn, + virDomainDefPtr def) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; const char *filename; xenXMConfCachePtr entry; - char *ret = NULL; + virDomainDefPtr ret = NULL; /* Flags checked by virDomainDefFormat */ - if (domain->id != -1) - return NULL; - xenUnifiedLock(priv); - if (!(filename = virHashLookup(priv->nameConfigMap, domain->name))) + if (!(filename = virHashLookup(priv->nameConfigMap, def->name))) goto cleanup; if (!(entry = virHashLookup(priv->configCache, filename))) goto cleanup; - ret = virDomainDefFormat(entry->def, flags); + ret = virDomainDefCopy(entry->def, + priv->caps, + priv->xmlopt, + false); cleanup: xenUnifiedUnlock(priv); @@ -946,13 +947,11 @@ xenXMDomainCreate(virConnectPtr conn, * Create a config file for a domain, based on an XML * document describing its config */ -virDomainPtr -xenXMDomainDefineXML(virConnectPtr conn, const char *xml) +int +xenXMDomainDefineXML(virConnectPtr conn, virDomainDefPtr def) { - virDomainPtr ret; char *filename = NULL; const char *oldfilename; - virDomainDefPtr def = NULL; virConfPtr conf = NULL; xenXMConfCachePtr entry = NULL; xenUnifiedPrivatePtr priv = conn->privateData; @@ -961,14 +960,7 @@ xenXMDomainDefineXML(virConnectPtr conn, const char *xml) if (!xenInotifyActive(conn) && xenXMConfigCacheRefresh(conn) < 0) { xenUnifiedUnlock(priv); - return NULL; - } - - if (!(def = virDomainDefParseString(xml, priv->caps, priv->xmlopt, - 1 << VIR_DOMAIN_VIRT_XEN, - VIR_DOMAIN_XML_INACTIVE))) { - xenUnifiedUnlock(priv); - return NULL; + return -1; } if (!(conf = xenFormatXM(conn, def, priv->xendConfigVersion))) @@ -1062,10 +1054,9 @@ xenXMDomainDefineXML(virConnectPtr conn, const char *xml) goto error; } - ret = virGetDomain(conn, def->name, def->uuid); xenUnifiedUnlock(priv); VIR_FREE(filename); - return ret; + return 0; error: VIR_FREE(filename); @@ -1073,25 +1064,25 @@ xenXMDomainDefineXML(virConnectPtr conn, const char *xml) VIR_FREE(entry->filename); VIR_FREE(entry); virConfFree(conf); - virDomainDefFree(def); xenUnifiedUnlock(priv); - return NULL; + return -1; } /* * Delete a domain from disk */ int -xenXMDomainUndefine(virDomainPtr domain) +xenXMDomainUndefine(virConnectPtr conn, + virDomainDefPtr def) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; const char *filename; xenXMConfCachePtr entry; int ret = -1; xenUnifiedLock(priv); - if (!(filename = virHashLookup(priv->nameConfigMap, domain->name))) + if (!(filename = virHashLookup(priv->nameConfigMap, def->name))) goto cleanup; if (!(entry = virHashLookup(priv->configCache, filename))) @@ -1101,7 +1092,7 @@ xenXMDomainUndefine(virDomainPtr domain) goto cleanup; /* Remove the name -> filename mapping */ - if (virHashRemoveEntry(priv->nameConfigMap, domain->name) < 0) + if (virHashRemoveEntry(priv->nameConfigMap, def->name) < 0) goto cleanup; /* Remove the config record itself */ diff --git a/src/xen/xm_internal.h b/src/xen/xm_internal.h index 0521625e4a..5a434b9700 100644 --- a/src/xen/xm_internal.h +++ b/src/xen/xm_internal.h @@ -44,7 +44,8 @@ int xenXMDomainGetState(virConnectPtr conn, virDomainDefPtr def, int *state, int *reason); -char *xenXMDomainGetXMLDesc(virDomainPtr domain, unsigned int flags); +virDomainDefPtr xenXMDomainGetXMLDesc(virConnectPtr conn, + virDomainDefPtr def); int xenXMDomainSetMemory(virConnectPtr conn, virDomainDefPtr def, unsigned long memory); @@ -67,8 +68,8 @@ int xenXMNumOfDefinedDomains(virConnectPtr conn); int xenXMDomainCreate(virConnectPtr conn, virDomainDefPtr def); -virDomainPtr xenXMDomainDefineXML(virConnectPtr con, const char *xml); -int xenXMDomainUndefine(virDomainPtr domain); +int xenXMDomainDefineXML(virConnectPtr con, virDomainDefPtr def); +int xenXMDomainUndefine(virConnectPtr conn, virDomainDefPtr def); int xenXMDomainBlockPeek (virDomainPtr dom, const char *path, unsigned long long offset, size_t size, void *buffer);