[libvirt] [PATCH v2 00/11] Refactor Xen driver to support ACL work

From: "Daniel P. Berrange" <berrange@redhat.com> The Xen driver currently is a really horrible mess, in particular with the way iterates over sub-drivers calling each one in turn, until one magically works. For each operation there is always a clear rule for which sub-driver must be used. Thus instead of blindly iterating over all drivers, we can directly invoke the correct sub-driver. This highlights that quite alot of code is in fact completely unreachable / used & can be deleted. The second big issue is that the Xen sub-drivers will randomly use either the 'id', 'name' or 'uuid' from the virDomainPtr object. If the user provides a malicious virDomainPtr instance, it is possible to have a 'id' referring to domain A, a 'name' referring to domain B and a 'uuid' referring to domain C. This makes doing reliable access control checks difficult. To ensure we have a consistent triple, use the 'uuid' from virDomainPtr to lookup the guest with the hypervisor and return a virDomainDefPtr where only the name/id/uuid are filled out. Use this in the all the subdrivers isolating them from the public virDomainPtr object. The top level Xen driver will then be able to do access control checks on the virDomainDefPtr instances. In v2: - Merged all patches removing the sub-driver iteration concept - Rebased to latest git Daniel P. Berrange (11): Convert Xen domain lookup driver methods to use virDomainDefPtr Convert Xen domain lifecycle driver methods to use virDomainDefPtr Convert Xen domain property driver methods to use virDomainDefPtr Convert Xen domain managed save driver methods to use virDomainDefPtr Convert Xen domain start/migration APIs to use virDomainDefPtr Convert Xen domain VCPU driver methods to use virDomainDefPtr Convert Xen domain device hotplug driver methods to use virDomainDefPtr Convert Xen domain autostart driver methods to use virDomainDefPtr Convert Xen domain scheduler driver methods to use virDomainDefPtr Convert Xen domain stats/peek driver methods to use virDomainDefPtr Convert Xen domain core dump driver methods to use virDomainDefPtr src/conf/domain_conf.c | 24 ++ src/conf/domain_conf.h | 4 + src/libvirt_private.syms | 1 + src/xen/block_stats.c | 6 +- src/xen/block_stats.h | 2 +- src/xen/xen_driver.c | 781 ++++++++++++++++++++++++++++++++++++----------- src/xen/xen_hypervisor.c | 131 ++++---- src/xen/xen_hypervisor.h | 60 ++-- src/xen/xen_inotify.c | 14 +- src/xen/xend_internal.c | 469 ++++++++++++++-------------- src/xen/xend_internal.h | 127 +++++--- src/xen/xm_internal.c | 224 +++++++------- src/xen/xm_internal.h | 71 +++-- 13 files changed, 1230 insertions(+), 684 deletions(-) -- 1.8.1.4

From: "Daniel P. Berrange" <berrange@redhat.com> Introduce use of a virDomainDefPtr in the domain lookup APIs to simplify introduction of ACL security checks. The virDomainPtr cannot be safely used, since the app may have supplied mis-matching name/uuid/id fields. eg the name points to domain X, while the uuid points to domain Y. Resolving the virDomainPtr to a virDomainDefPtr ensures a consistent name/uuid/id set. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/conf/domain_conf.c | 24 ++++++++ src/conf/domain_conf.h | 4 ++ src/libvirt_private.syms | 1 + src/xen/xen_driver.c | 147 +++++++++++++++++++++++++++++++---------------- src/xen/xen_hypervisor.c | 17 +++--- src/xen/xen_hypervisor.h | 8 +-- src/xen/xen_inotify.c | 14 ++--- src/xen/xend_internal.c | 34 +++++------ src/xen/xend_internal.h | 4 +- src/xen/xm_internal.c | 30 ++++------ src/xen/xm_internal.h | 5 +- 11 files changed, 173 insertions(+), 115 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index d55ce6b..61995cd 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2048,6 +2048,30 @@ error: return NULL; } + +virDomainDefPtr virDomainDefNew(const char *name, + const unsigned char *uuid, + int id) +{ + virDomainDefPtr def; + + if (VIR_ALLOC(def) < 0) { + virReportOOMError(); + return NULL; + } + + if (!(def->name = strdup(name))) { + VIR_FREE(def); + return NULL; + } + + memcpy(def->uuid, uuid, VIR_UUID_BUFLEN); + def->id = id; + + return def; +} + + void virDomainObjAssignDef(virDomainObjPtr domain, const virDomainDefPtr def, bool live, diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 21f7ce2..f7644a6 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2147,6 +2147,10 @@ void virDomainDefFree(virDomainDefPtr vm); virDomainChrDefPtr virDomainChrDefNew(void); +virDomainDefPtr virDomainDefNew(const char *name, + const unsigned char *uuid, + int id); + enum { VIR_DOMAIN_OBJ_LIST_ADD_LIVE = (1 << 0), VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE = (1 << 1), diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index bb70595..d2f5827 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -117,6 +117,7 @@ virDomainDefGenSecurityLabelDef; virDomainDefGetDefaultEmulator; virDomainDefGetSecurityLabelDef; virDomainDefMaybeAddController; +virDomainDefNew; virDomainDefParseFile; virDomainDefParseNode; virDomainDefParseString; diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index cc54f7a..d9420d8 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -82,6 +82,60 @@ xenUnifiedDomainGetVcpus(virDomainPtr dom, static bool is_privileged = false; +static virDomainDefPtr xenGetDomainDefForID(virConnectPtr conn, int id) +{ + virDomainDefPtr ret; + + ret = xenHypervisorLookupDomainByID(conn, id); + + if (!ret && virGetLastError() == NULL) + virReportError(VIR_ERR_NO_DOMAIN, __FUNCTION__); + + return ret; +} + + +static virDomainDefPtr xenGetDomainDefForName(virConnectPtr conn, const char *name) +{ + xenUnifiedPrivatePtr priv = conn->privateData; + virDomainDefPtr ret; + + ret = xenDaemonLookupByName(conn, name); + + /* Try XM for inactive domains. */ + if (!ret && + priv->xendConfigVersion <= XEND_CONFIG_VERSION_3_0_3) + ret = xenXMDomainLookupByName(conn, name); + + if (!ret && virGetLastError() == NULL) + virReportError(VIR_ERR_NO_DOMAIN, __FUNCTION__); + + return ret; +} + + +static virDomainDefPtr xenGetDomainDefForUUID(virConnectPtr conn, const unsigned char *uuid) +{ + xenUnifiedPrivatePtr priv = conn->privateData; + virDomainDefPtr ret; + + ret = xenHypervisorLookupDomainByUUID(conn, uuid); + + /* Try XM for inactive domains. */ + if (!ret) { + if (priv->xendConfigVersion <= XEND_CONFIG_VERSION_3_0_3) + ret = xenXMDomainLookupByUUID(conn, uuid); + else + ret = xenDaemonLookupByUUID(conn, uuid); + } + + if (!ret && virGetLastError() == NULL) + virReportError(VIR_ERR_NO_DOMAIN, __FUNCTION__); + + return ret; +} + + /** * xenNumaInit: * @conn: pointer to the hypervisor connection @@ -597,12 +651,18 @@ static virDomainPtr xenUnifiedDomainLookupByID(virConnectPtr conn, int id) { virDomainPtr ret = NULL; + virDomainDefPtr def = NULL; - ret = xenHypervisorLookupDomainByID(conn, id); + if (!(def = xenGetDomainDefForID(conn, id))) + goto cleanup; - if (!ret && virGetLastError() == NULL) - virReportError(VIR_ERR_NO_DOMAIN, __FUNCTION__); + if (!(ret = virGetDomain(conn, def->name, def->uuid))) + goto cleanup; + ret->id = def->id; + +cleanup: + virDomainDefFree(def); return ret; } @@ -610,22 +670,19 @@ static virDomainPtr xenUnifiedDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid) { - xenUnifiedPrivatePtr priv = conn->privateData; - virDomainPtr ret; + virDomainPtr ret = NULL; + virDomainDefPtr def = NULL; - ret = xenHypervisorLookupDomainByUUID(conn, uuid); + if (!(def = xenGetDomainDefForUUID(conn, uuid))) + goto cleanup; - /* Try XM for inactive domains. */ - if (!ret) { - if (priv->xendConfigVersion <= XEND_CONFIG_VERSION_3_0_3) - ret = xenXMDomainLookupByUUID(conn, uuid); - else - ret = xenDaemonLookupByUUID(conn, uuid); - } + if (!(ret = virGetDomain(conn, def->name, def->uuid))) + goto cleanup; - if (!ret && virGetLastError() == NULL) - virReportError(VIR_ERR_NO_DOMAIN, __FUNCTION__); + ret->id = def->id; +cleanup: + virDomainDefFree(def); return ret; } @@ -633,18 +690,19 @@ static virDomainPtr xenUnifiedDomainLookupByName(virConnectPtr conn, const char *name) { - xenUnifiedPrivatePtr priv = conn->privateData; - virDomainPtr ret; + virDomainPtr ret = NULL; + virDomainDefPtr def = NULL; - ret = xenDaemonLookupByName(conn, name); + if (!(def = xenGetDomainDefForName(conn, name))) + goto cleanup; - /* Try XM for inactive domains. */ - if (priv->xendConfigVersion <= XEND_CONFIG_VERSION_3_0_3) - ret = xenXMDomainLookupByName(conn, name); + if (!(ret = virGetDomain(conn, def->name, def->uuid))) + goto cleanup; - if (!ret && virGetLastError() == NULL) - virReportError(VIR_ERR_NO_DOMAIN, __FUNCTION__); + ret->id = def->id; +cleanup: + virDomainDefFree(def); return ret; } @@ -652,28 +710,18 @@ xenUnifiedDomainLookupByName(virConnectPtr conn, static int xenUnifiedDomainIsActive(virDomainPtr dom) { - xenUnifiedPrivatePtr priv = dom->conn->privateData; - virDomainPtr currdom; + virDomainDefPtr def; int ret = -1; - /* ID field in dom may be outdated, so re-lookup */ - currdom = xenHypervisorLookupDomainByUUID(dom->conn, dom->uuid); - - /* Try XM for inactive domains. */ - if (!currdom) { - if (priv->xendConfigVersion <= XEND_CONFIG_VERSION_3_0_3) - currdom = xenXMDomainLookupByUUID(dom->conn, dom->uuid); - else - currdom = xenDaemonLookupByUUID(dom->conn, dom->uuid); - } + if (!(def = xenGetDomainDefForUUID(dom->conn, dom->uuid))) + goto cleanup; - if (currdom) { - ret = currdom->id == -1 ? 0 : 1; - virDomainFree(currdom); - } else if (virGetLastError() == NULL) { - virReportError(VIR_ERR_NO_DOMAIN, __FUNCTION__); + if (def) { + ret = def->id == -1 ? 0 : 1; + virDomainDefFree(def); } +cleanup: return ret; } @@ -681,22 +729,22 @@ static int xenUnifiedDomainIsPersistent(virDomainPtr dom) { xenUnifiedPrivatePtr priv = dom->conn->privateData; - virDomainPtr currdom = NULL; + virDomainDefPtr def = NULL; int ret = -1; if (priv->opened[XEN_UNIFIED_XM_OFFSET]) { /* Old Xen, pre-inactive domain management. * If the XM driver can see the guest, it is definitely persistent */ - currdom = xenXMDomainLookupByUUID(dom->conn, dom->uuid); - if (currdom) + def = xenXMDomainLookupByUUID(dom->conn, dom->uuid); + if (def) ret = 1; else ret = 0; } else { /* New Xen with inactive domain management */ - currdom = xenDaemonLookupByUUID(dom->conn, dom->uuid); - if (currdom) { - if (currdom->id == -1) { + def = xenDaemonLookupByUUID(dom->conn, dom->uuid); + if (def) { + if (def->id == -1) { /* If its inactive, then trivially, it must be persistent */ ret = 1; } else { @@ -708,7 +756,7 @@ xenUnifiedDomainIsPersistent(virDomainPtr dom) virUUIDFormat(dom->uuid, uuidstr); if (virAsprintf(&path, "%s/%s", XEND_DOMAINS_DIR, uuidstr) < 0) { virReportOOMError(); - goto done; + goto cleanup; } if (access(path, R_OK) == 0) ret = 1; @@ -718,9 +766,8 @@ xenUnifiedDomainIsPersistent(virDomainPtr dom) } } -done: - if (currdom) - virDomainFree(currdom); +cleanup: + virDomainDefFree(def); return ret; } diff --git a/src/xen/xen_hypervisor.c b/src/xen/xen_hypervisor.c index 68a3ef4..55b0930 100644 --- a/src/xen/xen_hypervisor.c +++ b/src/xen/xen_hypervisor.c @@ -2562,12 +2562,13 @@ xenHypervisorHasDomain(virConnectPtr conn, int id) return 1; } -virDomainPtr + +virDomainDefPtr xenHypervisorLookupDomainByID(virConnectPtr conn, int id) { xenUnifiedPrivatePtr priv = conn->privateData; xen_getdomaininfo dominfo; - virDomainPtr ret; + virDomainDefPtr ret; char *name; XEN_GETDOMAININFO_CLEAR(dominfo); @@ -2584,20 +2585,20 @@ xenHypervisorLookupDomainByID(virConnectPtr conn, int id) if (!name) return NULL; - ret = virGetDomain(conn, name, XEN_GETDOMAININFO_UUID(dominfo)); - if (ret) - ret->id = id; + ret = virDomainDefNew(name, + XEN_GETDOMAININFO_UUID(dominfo), + id); VIR_FREE(name); return ret; } -virDomainPtr +virDomainDefPtr xenHypervisorLookupDomainByUUID(virConnectPtr conn, const unsigned char *uuid) { xen_getdomaininfolist dominfos; xenUnifiedPrivatePtr priv = conn->privateData; - virDomainPtr ret; + virDomainDefPtr ret; char *name; int maxids = 100, nids, i, id; @@ -2648,7 +2649,7 @@ xenHypervisorLookupDomainByUUID(virConnectPtr conn, const unsigned char *uuid) if (!name) return NULL; - ret = virGetDomain(conn, name, uuid); + ret = virDomainDefNew(name, uuid, id); if (ret) ret->id = id; VIR_FREE(name); diff --git a/src/xen/xen_hypervisor.h b/src/xen/xen_hypervisor.h index 8507bd0..1d44a92 100644 --- a/src/xen/xen_hypervisor.h +++ b/src/xen/xen_hypervisor.h @@ -27,6 +27,7 @@ # include "capabilities.h" # include "driver.h" # include "viruri.h" +# include "domain_conf.h" /* See xenHypervisorInit() for details. */ struct xenHypervisorVersions { @@ -43,10 +44,9 @@ virCapsPtr xenHypervisorMakeCapabilities (virConnectPtr conn); int xenHypervisorHasDomain(virConnectPtr conn, int id); -virDomainPtr - xenHypervisorLookupDomainByID (virConnectPtr conn, - int id); -virDomainPtr +virDomainDefPtr + xenHypervisorLookupDomainByID (virConnectPtr conn, int id); +virDomainDefPtr xenHypervisorLookupDomainByUUID (virConnectPtr conn, const unsigned char *uuid); char * diff --git a/src/xen/xen_inotify.c b/src/xen/xen_inotify.c index b032bba..576eb10 100644 --- a/src/xen/xen_inotify.c +++ b/src/xen/xen_inotify.c @@ -76,7 +76,7 @@ xenInotifyXendDomainsDirLookup(virConnectPtr conn, unsigned char *uuid) { int i; - virDomainPtr dom; + virDomainDefPtr def; const char *uuid_str; unsigned char rawuuid[VIR_UUID_BUFLEN]; xenUnifiedPrivatePtr priv = conn->privateData; @@ -96,8 +96,8 @@ xenInotifyXendDomainsDirLookup(virConnectPtr conn, be set during open while we are building our initial list of domains */ VIR_DEBUG("Looking for dom with uuid: %s", uuid_str); - /* XXX Should not have to go via a virDomainPtr obj instance */ - if (!(dom = xenDaemonLookupByUUID(conn, rawuuid))) { + + if (!(def = xenDaemonLookupByUUID(conn, rawuuid))) { /* If we are here, the domain has gone away. search for, and create a domain from the stored list info */ @@ -118,13 +118,13 @@ xenInotifyXendDomainsDirLookup(virConnectPtr conn, return -1; } - if (!(*name = strdup(dom->name))) { + if (!(*name = strdup(def->name))) { virReportOOMError(); - virDomainFree(dom); + virDomainDefFree(def); return -1; } - memcpy(uuid, dom->uuid, VIR_UUID_BUFLEN); - virDomainFree(dom); + memcpy(uuid, def->uuid, VIR_UUID_BUFLEN); + virDomainDefFree(def); /* succeeded too find domain by uuid */ return 0; } diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index aec57f5..5ea1627 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -1111,15 +1111,16 @@ sexpr_to_xend_topology(const struct sexpr *root, virCapsPtr caps) * * Internal routine returning the associated virDomainPtr for this domain * - * Returns the domain pointer or NULL in case of error. + * Returns the domain def pointer or NULL in case of error. */ -static virDomainPtr +static virDomainDefPtr sexpr_to_domain(virConnectPtr conn, const struct sexpr *root) { - virDomainPtr ret = NULL; + virDomainDefPtr ret = NULL; unsigned char uuid[VIR_UUID_BUFLEN]; const char *name; const char *tmp; + int id = -1; xenUnifiedPrivatePtr priv = conn->privateData; if (sexpr_uuid(uuid, root, "domain/uuid") < 0) @@ -1128,9 +1129,6 @@ sexpr_to_domain(virConnectPtr conn, const struct sexpr *root) if (name == NULL) goto error; - ret = virGetDomain(conn, name, uuid); - if (ret == NULL) return NULL; - tmp = sexpr_node(root, "domain/domid"); /* New 3.0.4 XenD will not report a domid for inactive domains, * so only error out for old XenD @@ -1139,11 +1137,9 @@ sexpr_to_domain(virConnectPtr conn, const struct sexpr *root) goto error; if (tmp) - ret->id = sexpr_int(root, "domain/domid"); - else - ret->id = -1; /* An inactive domain */ + id = sexpr_int(root, "domain/domid"); - return ret; + return virDomainDefNew(name, uuid, id); error: virReportError(VIR_ERR_INTERNAL_ERROR, @@ -1694,13 +1690,13 @@ xenDaemonDomainGetState(virDomainPtr domain, * it in the form of a struct xend_domain. This should be * free()'d when no longer needed. * - * Returns domain info on success; NULL (with errno) on error + * Returns domain def pointer on success; NULL on error */ -virDomainPtr +virDomainDefPtr xenDaemonLookupByName(virConnectPtr conn, const char *domname) { struct sexpr *root; - virDomainPtr ret = NULL; + virDomainDefPtr ret = NULL; root = sexpr_get(conn, "/xend/domain/%s?detail=1", domname); if (root == NULL) @@ -2048,12 +2044,12 @@ xenDaemonDomainGetVcpus(virDomainPtr domain, * * Try to lookup a domain on xend based on its UUID. * - * Returns a new domain object or NULL in case of failure + * Returns domain def pointer on success; NULL on error */ -virDomainPtr +virDomainDefPtr xenDaemonLookupByUUID(virConnectPtr conn, const unsigned char *uuid) { - virDomainPtr ret; + virDomainDefPtr ret; char *name = NULL; int id = -1; xenUnifiedPrivatePtr priv = conn->privateData; @@ -2113,12 +2109,8 @@ xenDaemonLookupByUUID(virConnectPtr conn, const unsigned char *uuid) if (name == NULL) return NULL; - ret = virGetDomain(conn, name, uuid); - if (ret == NULL) goto cleanup; - - ret->id = id; + ret = virDomainDefNew(name, uuid, id); - cleanup: VIR_FREE(name); return ret; } diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h index 7332303..a2d05f3 100644 --- a/src/xen/xend_internal.h +++ b/src/xen/xend_internal.h @@ -149,8 +149,8 @@ int xenDaemonDomainSetAutostart (virDomainPtr domain, int autostart); virDomainPtr xenDaemonCreateXML(virConnectPtr conn, const char *xmlDesc); -virDomainPtr xenDaemonLookupByUUID(virConnectPtr conn, const unsigned char *uuid); -virDomainPtr xenDaemonLookupByName(virConnectPtr conn, const char *domname); +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); diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c index 66bd289..9b8d742 100644 --- a/src/xen/xm_internal.c +++ b/src/xen/xm_internal.c @@ -814,13 +814,13 @@ xenXMDomainPinVcpu(virDomainPtr domain, /* * Find an inactive domain based on its name */ -virDomainPtr +virDomainDefPtr xenXMDomainLookupByName(virConnectPtr conn, const char *domname) { xenUnifiedPrivatePtr priv = conn->privateData; const char *filename; xenXMConfCachePtr entry; - virDomainPtr ret = NULL; + virDomainDefPtr ret = NULL; xenUnifiedLock(priv); @@ -833,12 +833,7 @@ xenXMDomainLookupByName(virConnectPtr conn, const char *domname) if (!(entry = virHashLookup(priv->configCache, filename))) goto cleanup; - if (!(ret = virGetDomain(conn, domname, entry->def->uuid))) - goto cleanup; - - /* Ensure its marked inactive, because may be cached - handle to a previously active domain */ - ret->id = -1; + ret = virDomainDefNew(domname, entry->def->uuid, -1); cleanup: xenUnifiedUnlock(priv); @@ -866,12 +861,12 @@ xenXMDomainSearchForUUID(const void *payload, /* * Find an inactive domain based on its UUID */ -virDomainPtr +virDomainDefPtr xenXMDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid) { xenUnifiedPrivatePtr priv = conn->privateData; xenXMConfCachePtr entry; - virDomainPtr ret = NULL; + virDomainDefPtr ret = NULL; xenUnifiedLock(priv); @@ -881,12 +876,7 @@ xenXMDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid) if (!(entry = virHashSearch(priv->configCache, xenXMDomainSearchForUUID, (const void *)uuid))) goto cleanup; - if (!(ret = virGetDomain(conn, entry->def->name, uuid))) - goto cleanup; - - /* Ensure its marked inactive, because may be cached - handle to a previously active domain */ - ret->id = -1; + ret = virDomainDefNew(entry->def->name, uuid, -1); cleanup: xenUnifiedUnlock(priv); @@ -1129,7 +1119,7 @@ struct xenXMListIteratorContext { static void xenXMListIterator(void *payload ATTRIBUTE_UNUSED, const void *name, void *data) { struct xenXMListIteratorContext *ctx = data; - virDomainPtr dom = NULL; + virDomainDefPtr def = NULL; if (ctx->oom) return; @@ -1137,14 +1127,14 @@ xenXMListIterator(void *payload ATTRIBUTE_UNUSED, const void *name, void *data) if (ctx->count == ctx->max) return; - dom = xenDaemonLookupByName(ctx->conn, name); - if (!dom) { + def = xenDaemonLookupByName(ctx->conn, name); + if (!def) { if (!(ctx->names[ctx->count] = strdup(name))) ctx->oom = 1; else ctx->count++; } else { - virDomainFree(dom); + virDomainDefFree(def); } } diff --git a/src/xen/xm_internal.h b/src/xen/xm_internal.h index eda7394..0e55897 100644 --- a/src/xen/xm_internal.h +++ b/src/xen/xm_internal.h @@ -51,9 +51,8 @@ int xenXMDomainSetVcpusFlags(virDomainPtr domain, unsigned int vcpus, int xenXMDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags); int xenXMDomainPinVcpu(virDomainPtr domain, unsigned int vcpu, unsigned char *cpumap, int maplen); -virDomainPtr xenXMDomainLookupByName(virConnectPtr conn, const char *domname); -virDomainPtr xenXMDomainLookupByUUID(virConnectPtr conn, - const unsigned char *uuid); +virDomainDefPtr xenXMDomainLookupByName(virConnectPtr conn, const char *domname); +virDomainDefPtr xenXMDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid); int xenXMListDefinedDomains(virConnectPtr conn, char ** const names, int maxnames); int xenXMNumOfDefinedDomains(virConnectPtr conn); -- 1.8.1.4

On 09.05.2013 14:59, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Introduce use of a virDomainDefPtr in the domain lookup APIs to simplify introduction of ACL security checks. The virDomainPtr cannot be safely used, since the app may have supplied mis-matching name/uuid/id fields. eg the name points to domain X, while the uuid points to domain Y. Resolving the virDomainPtr to a virDomainDefPtr ensures a consistent name/uuid/id set.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/conf/domain_conf.c | 24 ++++++++ src/conf/domain_conf.h | 4 ++ src/libvirt_private.syms | 1 + src/xen/xen_driver.c | 147 +++++++++++++++++++++++++++++++---------------- src/xen/xen_hypervisor.c | 17 +++--- src/xen/xen_hypervisor.h | 8 +-- src/xen/xen_inotify.c | 14 ++--- src/xen/xend_internal.c | 34 +++++------ src/xen/xend_internal.h | 4 +- src/xen/xm_internal.c | 30 ++++------ src/xen/xm_internal.h | 5 +- 11 files changed, 173 insertions(+), 115 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index d55ce6b..61995cd 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2048,6 +2048,30 @@ error: return NULL; }
+ +virDomainDefPtr virDomainDefNew(const char *name, + const unsigned char *uuid, + int id) +{ + virDomainDefPtr def; + + if (VIR_ALLOC(def) < 0) { + virReportOOMError(); + return NULL; + } + + if (!(def->name = strdup(name))) { + VIR_FREE(def); + return NULL; + }
Can you switch to VIR_STRDUP instead? Michal

On Thu, May 09, 2013 at 03:01:42PM +0200, Michal Privoznik wrote:
On 09.05.2013 14:59, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Introduce use of a virDomainDefPtr in the domain lookup APIs to simplify introduction of ACL security checks. The virDomainPtr cannot be safely used, since the app may have supplied mis-matching name/uuid/id fields. eg the name points to domain X, while the uuid points to domain Y. Resolving the virDomainPtr to a virDomainDefPtr ensures a consistent name/uuid/id set.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/conf/domain_conf.c | 24 ++++++++ src/conf/domain_conf.h | 4 ++ src/libvirt_private.syms | 1 + src/xen/xen_driver.c | 147 +++++++++++++++++++++++++++++++---------------- src/xen/xen_hypervisor.c | 17 +++--- src/xen/xen_hypervisor.h | 8 +-- src/xen/xen_inotify.c | 14 ++--- src/xen/xend_internal.c | 34 +++++------ src/xen/xend_internal.h | 4 +- src/xen/xm_internal.c | 30 ++++------ src/xen/xm_internal.h | 5 +- 11 files changed, 173 insertions(+), 115 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index d55ce6b..61995cd 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2048,6 +2048,30 @@ error: return NULL; }
+ +virDomainDefPtr virDomainDefNew(const char *name, + const unsigned char *uuid, + int id) +{ + virDomainDefPtr def; + + if (VIR_ALLOC(def) < 0) { + virReportOOMError(); + return NULL; + } + + if (!(def->name = strdup(name))) { + VIR_FREE(def); + return NULL; + }
Can you switch to VIR_STRDUP instead?
Ok, consider this to be squashed in once acked @@ -2060,7 +2060,7 @@ virDomainDefPtr virDomainDefNew(const char *name, return NULL; } - if (!(def->name = strdup(name))) { + if (VIR_STRDUP(def->name, name) < 0) { VIR_FREE(def); return NULL; } Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Introduce use of a virDomainDefPtr in the domain lookup APIs to simplify introduction of ACL security checks. The virDomainPtr cannot be safely used, since the app may have supplied mis-matching name/uuid/id fields. eg the name points to domain X, while the uuid points to domain Y. Resolving the virDomainPtr to a virDomainDefPtr ensures a consistent name/uuid/id set.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/conf/domain_conf.c | 24 ++++++++ src/conf/domain_conf.h | 4 ++ src/libvirt_private.syms | 1 + src/xen/xen_driver.c | 147 +++++++++++++++++++++++++++++++---------------- src/xen/xen_hypervisor.c | 17 +++--- src/xen/xen_hypervisor.h | 8 +-- src/xen/xen_inotify.c | 14 ++--- src/xen/xend_internal.c | 34 +++++------ src/xen/xend_internal.h | 4 +- src/xen/xm_internal.c | 30 ++++------ src/xen/xm_internal.h | 5 +- 11 files changed, 173 insertions(+), 115 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index d55ce6b..61995cd 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2048,6 +2048,30 @@ error: return NULL; }
+
Extra newline? I've noticed inconsistencies throughout most of the files wrt 1 or 2 newlines between function definitions, so difficult to say which is preferred.
+virDomainDefPtr virDomainDefNew(const char *name, + const unsigned char *uuid, + int id) +{ + virDomainDefPtr def; + + if (VIR_ALLOC(def) < 0) { + virReportOOMError(); + return NULL; + } + + if (!(def->name = strdup(name))) { + VIR_FREE(def); + return NULL; + } + + memcpy(def->uuid, uuid, VIR_UUID_BUFLEN); + def->id = id; + + return def; +} + + void virDomainObjAssignDef(virDomainObjPtr domain, const virDomainDefPtr def, bool live, diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 21f7ce2..f7644a6 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2147,6 +2147,10 @@ void virDomainDefFree(virDomainDefPtr vm);
virDomainChrDefPtr virDomainChrDefNew(void);
+virDomainDefPtr virDomainDefNew(const char *name, + const unsigned char *uuid, + int id); + enum { VIR_DOMAIN_OBJ_LIST_ADD_LIVE = (1 << 0), VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE = (1 << 1), diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index bb70595..d2f5827 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -117,6 +117,7 @@ virDomainDefGenSecurityLabelDef; virDomainDefGetDefaultEmulator; virDomainDefGetSecurityLabelDef; virDomainDefMaybeAddController; +virDomainDefNew; virDomainDefParseFile; virDomainDefParseNode; virDomainDefParseString; diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index cc54f7a..d9420d8 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -82,6 +82,60 @@ xenUnifiedDomainGetVcpus(virDomainPtr dom,
static bool is_privileged = false;
+static virDomainDefPtr xenGetDomainDefForID(virConnectPtr conn, int id) +{ + virDomainDefPtr ret; + + ret = xenHypervisorLookupDomainByID(conn, id); + + if (!ret && virGetLastError() == NULL) + virReportError(VIR_ERR_NO_DOMAIN, __FUNCTION__); + + return ret; +} + + +static virDomainDefPtr xenGetDomainDefForName(virConnectPtr conn, const char *name) +{ + xenUnifiedPrivatePtr priv = conn->privateData; + virDomainDefPtr ret; + + ret = xenDaemonLookupByName(conn, name); + + /* Try XM for inactive domains. */ + if (!ret && + priv->xendConfigVersion <= XEND_CONFIG_VERSION_3_0_3) + ret = xenXMDomainLookupByName(conn, name); + + if (!ret && virGetLastError() == NULL) + virReportError(VIR_ERR_NO_DOMAIN, __FUNCTION__); + + return ret; +} + + +static virDomainDefPtr xenGetDomainDefForUUID(virConnectPtr conn, const unsigned char *uuid) +{ + xenUnifiedPrivatePtr priv = conn->privateData; + virDomainDefPtr ret; + + ret = xenHypervisorLookupDomainByUUID(conn, uuid); + + /* Try XM for inactive domains. */ + if (!ret) { + if (priv->xendConfigVersion <= XEND_CONFIG_VERSION_3_0_3) + ret = xenXMDomainLookupByUUID(conn, uuid); + else + ret = xenDaemonLookupByUUID(conn, uuid); + } + + if (!ret && virGetLastError() == NULL) + virReportError(VIR_ERR_NO_DOMAIN, __FUNCTION__); + + return ret; +} + + /** * xenNumaInit: * @conn: pointer to the hypervisor connection @@ -597,12 +651,18 @@ static virDomainPtr xenUnifiedDomainLookupByID(virConnectPtr conn, int id) { virDomainPtr ret = NULL; + virDomainDefPtr def = NULL;
- ret = xenHypervisorLookupDomainByID(conn, id); + if (!(def = xenGetDomainDefForID(conn, id))) + goto cleanup;
- if (!ret && virGetLastError() == NULL) - virReportError(VIR_ERR_NO_DOMAIN, __FUNCTION__); + if (!(ret = virGetDomain(conn, def->name, def->uuid))) + goto cleanup;
+ ret->id = def->id; + +cleanup: + virDomainDefFree(def); return ret; }
@@ -610,22 +670,19 @@ static virDomainPtr xenUnifiedDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid) { - xenUnifiedPrivatePtr priv = conn->privateData; - virDomainPtr ret; + virDomainPtr ret = NULL; + virDomainDefPtr def = NULL;
- ret = xenHypervisorLookupDomainByUUID(conn, uuid); + if (!(def = xenGetDomainDefForUUID(conn, uuid))) + goto cleanup;
- /* Try XM for inactive domains. */ - if (!ret) { - if (priv->xendConfigVersion <= XEND_CONFIG_VERSION_3_0_3) - ret = xenXMDomainLookupByUUID(conn, uuid); - else - ret = xenDaemonLookupByUUID(conn, uuid); - } + if (!(ret = virGetDomain(conn, def->name, def->uuid))) + goto cleanup;
- if (!ret && virGetLastError() == NULL) - virReportError(VIR_ERR_NO_DOMAIN, __FUNCTION__); + ret->id = def->id;
+cleanup: + virDomainDefFree(def); return ret; }
@@ -633,18 +690,19 @@ static virDomainPtr xenUnifiedDomainLookupByName(virConnectPtr conn, const char *name) { - xenUnifiedPrivatePtr priv = conn->privateData; - virDomainPtr ret; + virDomainPtr ret = NULL; + virDomainDefPtr def = NULL;
- ret = xenDaemonLookupByName(conn, name); + if (!(def = xenGetDomainDefForName(conn, name))) + goto cleanup;
- /* Try XM for inactive domains. */ - if (priv->xendConfigVersion <= XEND_CONFIG_VERSION_3_0_3) - ret = xenXMDomainLookupByName(conn, name); + if (!(ret = virGetDomain(conn, def->name, def->uuid))) + goto cleanup;
- if (!ret && virGetLastError() == NULL) - virReportError(VIR_ERR_NO_DOMAIN, __FUNCTION__); + ret->id = def->id;
+cleanup: + virDomainDefFree(def); return ret; }
@@ -652,28 +710,18 @@ xenUnifiedDomainLookupByName(virConnectPtr conn, static int xenUnifiedDomainIsActive(virDomainPtr dom) { - xenUnifiedPrivatePtr priv = dom->conn->privateData; - virDomainPtr currdom; + virDomainDefPtr def; int ret = -1;
- /* ID field in dom may be outdated, so re-lookup */ - currdom = xenHypervisorLookupDomainByUUID(dom->conn, dom->uuid); - - /* Try XM for inactive domains. */ - if (!currdom) { - if (priv->xendConfigVersion <= XEND_CONFIG_VERSION_3_0_3) - currdom = xenXMDomainLookupByUUID(dom->conn, dom->uuid); - else - currdom = xenDaemonLookupByUUID(dom->conn, dom->uuid); - } + if (!(def = xenGetDomainDefForUUID(dom->conn, dom->uuid))) + goto cleanup;
- if (currdom) { - ret = currdom->id == -1 ? 0 : 1; - virDomainFree(currdom); - } else if (virGetLastError() == NULL) { - virReportError(VIR_ERR_NO_DOMAIN, __FUNCTION__); + if (def) {
Already checked for !(def), so this check can be removed.
+ ret = def->id == -1 ? 0 : 1; + virDomainDefFree(def); }
+cleanup: return ret; }
@@ -681,22 +729,22 @@ static int xenUnifiedDomainIsPersistent(virDomainPtr dom) { xenUnifiedPrivatePtr priv = dom->conn->privateData; - virDomainPtr currdom = NULL; + virDomainDefPtr def = NULL; int ret = -1;
if (priv->opened[XEN_UNIFIED_XM_OFFSET]) { /* Old Xen, pre-inactive domain management. * If the XM driver can see the guest, it is definitely persistent */ - currdom = xenXMDomainLookupByUUID(dom->conn, dom->uuid); - if (currdom) + def = xenXMDomainLookupByUUID(dom->conn, dom->uuid); + if (def) ret = 1; else ret = 0; } else { /* New Xen with inactive domain management */ - currdom = xenDaemonLookupByUUID(dom->conn, dom->uuid); - if (currdom) { - if (currdom->id == -1) { + def = xenDaemonLookupByUUID(dom->conn, dom->uuid); + if (def) { + if (def->id == -1) { /* If its inactive, then trivially, it must be persistent */ ret = 1; } else { @@ -708,7 +756,7 @@ xenUnifiedDomainIsPersistent(virDomainPtr dom) virUUIDFormat(dom->uuid, uuidstr); if (virAsprintf(&path, "%s/%s", XEND_DOMAINS_DIR, uuidstr) < 0) { virReportOOMError(); - goto done; + goto cleanup; } if (access(path, R_OK) == 0) ret = 1; @@ -718,9 +766,8 @@ xenUnifiedDomainIsPersistent(virDomainPtr dom) } }
-done: - if (currdom) - virDomainFree(currdom); +cleanup: + virDomainDefFree(def);
return ret; } diff --git a/src/xen/xen_hypervisor.c b/src/xen/xen_hypervisor.c index 68a3ef4..55b0930 100644 --- a/src/xen/xen_hypervisor.c +++ b/src/xen/xen_hypervisor.c @@ -2562,12 +2562,13 @@ xenHypervisorHasDomain(virConnectPtr conn, int id) return 1; }
-virDomainPtr + +virDomainDefPtr xenHypervisorLookupDomainByID(virConnectPtr conn, int id) { xenUnifiedPrivatePtr priv = conn->privateData; xen_getdomaininfo dominfo; - virDomainPtr ret; + virDomainDefPtr ret; char *name;
XEN_GETDOMAININFO_CLEAR(dominfo); @@ -2584,20 +2585,20 @@ xenHypervisorLookupDomainByID(virConnectPtr conn, int id) if (!name) return NULL;
- ret = virGetDomain(conn, name, XEN_GETDOMAININFO_UUID(dominfo)); - if (ret) - ret->id = id; + ret = virDomainDefNew(name, + XEN_GETDOMAININFO_UUID(dominfo), + id); VIR_FREE(name); return ret; }
-virDomainPtr +virDomainDefPtr xenHypervisorLookupDomainByUUID(virConnectPtr conn, const unsigned char *uuid) { xen_getdomaininfolist dominfos; xenUnifiedPrivatePtr priv = conn->privateData; - virDomainPtr ret; + virDomainDefPtr ret; char *name; int maxids = 100, nids, i, id;
@@ -2648,7 +2649,7 @@ xenHypervisorLookupDomainByUUID(virConnectPtr conn, const unsigned char *uuid) if (!name) return NULL;
- ret = virGetDomain(conn, name, uuid); + ret = virDomainDefNew(name, uuid, id); if (ret) ret->id = id; VIR_FREE(name); diff --git a/src/xen/xen_hypervisor.h b/src/xen/xen_hypervisor.h index 8507bd0..1d44a92 100644 --- a/src/xen/xen_hypervisor.h +++ b/src/xen/xen_hypervisor.h @@ -27,6 +27,7 @@ # include "capabilities.h" # include "driver.h" # include "viruri.h" +# include "domain_conf.h"
/* See xenHypervisorInit() for details. */ struct xenHypervisorVersions { @@ -43,10 +44,9 @@ virCapsPtr xenHypervisorMakeCapabilities (virConnectPtr conn); int xenHypervisorHasDomain(virConnectPtr conn, int id); -virDomainPtr - xenHypervisorLookupDomainByID (virConnectPtr conn, - int id); -virDomainPtr +virDomainDefPtr + xenHypervisorLookupDomainByID (virConnectPtr conn, int id); +virDomainDefPtr xenHypervisorLookupDomainByUUID (virConnectPtr conn, const unsigned char *uuid); char * diff --git a/src/xen/xen_inotify.c b/src/xen/xen_inotify.c index b032bba..576eb10 100644 --- a/src/xen/xen_inotify.c +++ b/src/xen/xen_inotify.c @@ -76,7 +76,7 @@ xenInotifyXendDomainsDirLookup(virConnectPtr conn, unsigned char *uuid) { int i; - virDomainPtr dom; + virDomainDefPtr def; const char *uuid_str; unsigned char rawuuid[VIR_UUID_BUFLEN]; xenUnifiedPrivatePtr priv = conn->privateData; @@ -96,8 +96,8 @@ xenInotifyXendDomainsDirLookup(virConnectPtr conn, be set during open while we are building our initial list of domains */ VIR_DEBUG("Looking for dom with uuid: %s", uuid_str); - /* XXX Should not have to go via a virDomainPtr obj instance */ - if (!(dom = xenDaemonLookupByUUID(conn, rawuuid))) { + + if (!(def = xenDaemonLookupByUUID(conn, rawuuid))) { /* If we are here, the domain has gone away. search for, and create a domain from the stored list info */ @@ -118,13 +118,13 @@ xenInotifyXendDomainsDirLookup(virConnectPtr conn, return -1; }
- if (!(*name = strdup(dom->name))) { + if (!(*name = strdup(def->name))) { virReportOOMError(); - virDomainFree(dom); + virDomainDefFree(def); return -1; } - memcpy(uuid, dom->uuid, VIR_UUID_BUFLEN); - virDomainFree(dom); + memcpy(uuid, def->uuid, VIR_UUID_BUFLEN); + virDomainDefFree(def); /* succeeded too find domain by uuid */ return 0; } diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index aec57f5..5ea1627 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -1111,15 +1111,16 @@ sexpr_to_xend_topology(const struct sexpr *root, virCapsPtr caps) * * Internal routine returning the associated virDomainPtr for this domain * - * Returns the domain pointer or NULL in case of error. + * Returns the domain def pointer or NULL in case of error. */ -static virDomainPtr +static virDomainDefPtr sexpr_to_domain(virConnectPtr conn, const struct sexpr *root) { - virDomainPtr ret = NULL; + virDomainDefPtr ret = NULL; unsigned char uuid[VIR_UUID_BUFLEN]; const char *name; const char *tmp; + int id = -1; xenUnifiedPrivatePtr priv = conn->privateData;
if (sexpr_uuid(uuid, root, "domain/uuid") < 0) @@ -1128,9 +1129,6 @@ sexpr_to_domain(virConnectPtr conn, const struct sexpr *root) if (name == NULL) goto error;
- ret = virGetDomain(conn, name, uuid); - if (ret == NULL) return NULL; - tmp = sexpr_node(root, "domain/domid"); /* New 3.0.4 XenD will not report a domid for inactive domains, * so only error out for old XenD @@ -1139,11 +1137,9 @@ sexpr_to_domain(virConnectPtr conn, const struct sexpr *root) goto error;
if (tmp) - ret->id = sexpr_int(root, "domain/domid"); - else - ret->id = -1; /* An inactive domain */ + id = sexpr_int(root, "domain/domid");
- return ret; + return virDomainDefNew(name, uuid, id);
error: virReportError(VIR_ERR_INTERNAL_ERROR, @@ -1694,13 +1690,13 @@ xenDaemonDomainGetState(virDomainPtr domain, * it in the form of a struct xend_domain. This should be * free()'d when no longer needed. * - * Returns domain info on success; NULL (with errno) on error + * Returns domain def pointer on success; NULL on error */ -virDomainPtr +virDomainDefPtr xenDaemonLookupByName(virConnectPtr conn, const char *domname) { struct sexpr *root; - virDomainPtr ret = NULL; + virDomainDefPtr ret = NULL;
root = sexpr_get(conn, "/xend/domain/%s?detail=1", domname); if (root == NULL) @@ -2048,12 +2044,12 @@ xenDaemonDomainGetVcpus(virDomainPtr domain, * * Try to lookup a domain on xend based on its UUID. * - * Returns a new domain object or NULL in case of failure + * Returns domain def pointer on success; NULL on error */ -virDomainPtr +virDomainDefPtr xenDaemonLookupByUUID(virConnectPtr conn, const unsigned char *uuid) { - virDomainPtr ret; + virDomainDefPtr ret; char *name = NULL; int id = -1; xenUnifiedPrivatePtr priv = conn->privateData; @@ -2113,12 +2109,8 @@ xenDaemonLookupByUUID(virConnectPtr conn, const unsigned char *uuid) if (name == NULL) return NULL;
- ret = virGetDomain(conn, name, uuid); - if (ret == NULL) goto cleanup; - - ret->id = id; + ret = virDomainDefNew(name, uuid, id);
- cleanup: VIR_FREE(name); return ret; } diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h index 7332303..a2d05f3 100644 --- a/src/xen/xend_internal.h +++ b/src/xen/xend_internal.h @@ -149,8 +149,8 @@ int xenDaemonDomainSetAutostart (virDomainPtr domain, int autostart);
virDomainPtr xenDaemonCreateXML(virConnectPtr conn, const char *xmlDesc); -virDomainPtr xenDaemonLookupByUUID(virConnectPtr conn, const unsigned char *uuid); -virDomainPtr xenDaemonLookupByName(virConnectPtr conn, const char *domname); +virDomainDefPtr xenDaemonLookupByUUID(virConnectPtr conn, const unsigned char *uuid);
Now over 80 columns, but not the only infraction in this file.
+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);
diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c index 66bd289..9b8d742 100644 --- a/src/xen/xm_internal.c +++ b/src/xen/xm_internal.c @@ -814,13 +814,13 @@ xenXMDomainPinVcpu(virDomainPtr domain, /* * Find an inactive domain based on its name */ -virDomainPtr +virDomainDefPtr xenXMDomainLookupByName(virConnectPtr conn, const char *domname) { xenUnifiedPrivatePtr priv = conn->privateData; const char *filename; xenXMConfCachePtr entry; - virDomainPtr ret = NULL; + virDomainDefPtr ret = NULL;
xenUnifiedLock(priv);
@@ -833,12 +833,7 @@ xenXMDomainLookupByName(virConnectPtr conn, const char *domname) if (!(entry = virHashLookup(priv->configCache, filename))) goto cleanup;
- if (!(ret = virGetDomain(conn, domname, entry->def->uuid))) - goto cleanup; - - /* Ensure its marked inactive, because may be cached - handle to a previously active domain */ - ret->id = -1; + ret = virDomainDefNew(domname, entry->def->uuid, -1);
cleanup: xenUnifiedUnlock(priv); @@ -866,12 +861,12 @@ xenXMDomainSearchForUUID(const void *payload, /* * Find an inactive domain based on its UUID */ -virDomainPtr +virDomainDefPtr xenXMDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid) { xenUnifiedPrivatePtr priv = conn->privateData; xenXMConfCachePtr entry; - virDomainPtr ret = NULL; + virDomainDefPtr ret = NULL;
xenUnifiedLock(priv);
@@ -881,12 +876,7 @@ xenXMDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid) if (!(entry = virHashSearch(priv->configCache, xenXMDomainSearchForUUID, (const void *)uuid))) goto cleanup;
- if (!(ret = virGetDomain(conn, entry->def->name, uuid))) - goto cleanup; - - /* Ensure its marked inactive, because may be cached - handle to a previously active domain */ - ret->id = -1; + ret = virDomainDefNew(entry->def->name, uuid, -1);
cleanup: xenUnifiedUnlock(priv); @@ -1129,7 +1119,7 @@ struct xenXMListIteratorContext { static void xenXMListIterator(void *payload ATTRIBUTE_UNUSED, const void *name, void *data) { struct xenXMListIteratorContext *ctx = data; - virDomainPtr dom = NULL; + virDomainDefPtr def = NULL;
if (ctx->oom) return; @@ -1137,14 +1127,14 @@ xenXMListIterator(void *payload ATTRIBUTE_UNUSED, const void *name, void *data) if (ctx->count == ctx->max) return;
- dom = xenDaemonLookupByName(ctx->conn, name); - if (!dom) { + def = xenDaemonLookupByName(ctx->conn, name); + if (!def) { if (!(ctx->names[ctx->count] = strdup(name))) ctx->oom = 1; else ctx->count++; } else { - virDomainFree(dom); + virDomainDefFree(def); } }
diff --git a/src/xen/xm_internal.h b/src/xen/xm_internal.h index eda7394..0e55897 100644 --- a/src/xen/xm_internal.h +++ b/src/xen/xm_internal.h @@ -51,9 +51,8 @@ int xenXMDomainSetVcpusFlags(virDomainPtr domain, unsigned int vcpus, int xenXMDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags); int xenXMDomainPinVcpu(virDomainPtr domain, unsigned int vcpu, unsigned char *cpumap, int maplen); -virDomainPtr xenXMDomainLookupByName(virConnectPtr conn, const char *domname); -virDomainPtr xenXMDomainLookupByUUID(virConnectPtr conn, - const unsigned char *uuid); +virDomainDefPtr xenXMDomainLookupByName(virConnectPtr conn, const char *domname); +virDomainDefPtr xenXMDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid);
Same here, but again not the only culprit. ACK. Regards, Jim
int xenXMListDefinedDomains(virConnectPtr conn, char ** const names, int maxnames); int xenXMNumOfDefinedDomains(virConnectPtr conn);

On Thu, May 09, 2013 at 11:52:39AM -0600, Jim Fehlig wrote:
Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Introduce use of a virDomainDefPtr in the domain lookup APIs to simplify introduction of ACL security checks. The virDomainPtr cannot be safely used, since the app may have supplied mis-matching name/uuid/id fields. eg the name points to domain X, while the uuid points to domain Y. Resolving the virDomainPtr to a virDomainDefPtr ensures a consistent name/uuid/id set.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/conf/domain_conf.c | 24 ++++++++ src/conf/domain_conf.h | 4 ++ src/libvirt_private.syms | 1 + src/xen/xen_driver.c | 147 +++++++++++++++++++++++++++++++---------------- src/xen/xen_hypervisor.c | 17 +++--- src/xen/xen_hypervisor.h | 8 +-- src/xen/xen_inotify.c | 14 ++--- src/xen/xend_internal.c | 34 +++++------ src/xen/xend_internal.h | 4 +- src/xen/xm_internal.c | 30 ++++------ src/xen/xm_internal.h | 5 +- 11 files changed, 173 insertions(+), 115 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index d55ce6b..61995cd 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2048,6 +2048,30 @@ error: return NULL; }
+
Extra newline? I've noticed inconsistencies throughout most of the files wrt 1 or 2 newlines between function definitions, so difficult to say which is preferred.
Yep, my preference is to use 2 newlines of whitespace between functions, so you'll see that throughout these patches, though as you say we don't enforce that strongly. Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

From: "Daniel P. Berrange" <berrange@redhat.com> Introduce use of a virDomainDefPtr in the domain lifecycle APIs to simplify introduction of ACL security checks. The virDomainPtr cannot be safely used, since the app may have supplied mis-matching name/uuid/id fields. eg the name points to domain X, while the uuid points to domain Y. Resolving the virDomainPtr to a virDomainDefPtr ensures a consistent name/uuid/id set. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/xen/xen_driver.c | 67 +++++++++++++++++++++++++++++++++++++++++++++---- src/xen/xend_internal.c | 60 ++++++++++++++++++++++--------------------- src/xen/xend_internal.h | 10 ++++---- src/xen/xm_internal.c | 8 +++--- 4 files changed, 103 insertions(+), 42 deletions(-) diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index d9420d8..37107ff 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -136,6 +136,13 @@ static virDomainDefPtr xenGetDomainDefForUUID(virConnectPtr conn, const unsigned } +static virDomainDefPtr xenGetDomainDefForDom(virDomainPtr dom) +{ + /* UUID lookup is more efficient than name lookup */ + return xenGetDomainDefForUUID(dom->conn, dom->uuid); +} + + /** * xenNumaInit: * @conn: pointer to the hypervisor connection @@ -781,22 +788,52 @@ xenUnifiedDomainIsUpdated(virDomainPtr dom ATTRIBUTE_UNUSED) static int xenUnifiedDomainSuspend(virDomainPtr dom) { - return xenDaemonDomainSuspend(dom); + int ret = -1; + virDomainDefPtr def; + + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + ret = xenDaemonDomainSuspend(dom->conn, def); + +cleanup: + virDomainDefFree(def); + return ret; } static int xenUnifiedDomainResume(virDomainPtr dom) { - return xenDaemonDomainResume(dom); + int ret = -1; + virDomainDefPtr def; + + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + ret = xenDaemonDomainResume(dom->conn, def); + +cleanup: + virDomainDefFree(def); + return ret; } static int xenUnifiedDomainShutdownFlags(virDomainPtr dom, unsigned int flags) { + int ret = -1; + virDomainDefPtr def; + virCheckFlags(0, -1); - return xenDaemonDomainShutdown(dom); + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + ret = xenDaemonDomainShutdown(dom->conn, def); + +cleanup: + virDomainDefFree(def); + return ret; } static int @@ -808,18 +845,38 @@ xenUnifiedDomainShutdown(virDomainPtr dom) static int xenUnifiedDomainReboot(virDomainPtr dom, unsigned int flags) { + int ret = -1; + virDomainDefPtr def; + virCheckFlags(0, -1); - return xenDaemonDomainReboot(dom); + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + ret = xenDaemonDomainReboot(dom->conn, def); + +cleanup: + virDomainDefFree(def); + return ret; } static int xenUnifiedDomainDestroyFlags(virDomainPtr dom, unsigned int flags) { + int ret = -1; + virDomainDefPtr def; + virCheckFlags(0, -1); - return xenDaemonDomainDestroy(dom); + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + ret = xenDaemonDomainDestroy(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 5ea1627..f8bd72b 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -1251,7 +1251,8 @@ xenDaemonClose(virConnectPtr conn ATTRIBUTE_UNUSED) /** * xenDaemonDomainSuspend: - * @domain: pointer to the Domain block + * @conn: the connection object + * @def: the domain to suspend * * Pause the domain, the domain is not scheduled anymore though its resources * are preserved. Use xenDaemonDomainResume() to resume execution. @@ -1259,41 +1260,42 @@ xenDaemonClose(virConnectPtr conn ATTRIBUTE_UNUSED) * Returns 0 in case of success, -1 (with errno) in case of error. */ int -xenDaemonDomainSuspend(virDomainPtr domain) +xenDaemonDomainSuspend(virConnectPtr conn, virDomainDefPtr def) { - if (domain->id < 0) { + if (def->id < 0) { virReportError(VIR_ERR_OPERATION_INVALID, - _("Domain %s isn't running."), domain->name); + _("Domain %s isn't running."), def->name); return -1; } - return xend_op(domain->conn, domain->name, "op", "pause", NULL); + return xend_op(conn, def->name, "op", "pause", NULL); } /** * xenDaemonDomainResume: - * @xend: pointer to the Xen Daemon block - * @name: name for the domain + * @conn: the connection object + * @def: the domain to resume * * Resume the domain after xenDaemonDomainSuspend() has been called * * Returns 0 in case of success, -1 (with errno) in case of error. */ int -xenDaemonDomainResume(virDomainPtr domain) +xenDaemonDomainResume(virConnectPtr conn, virDomainDefPtr def) { - if (domain->id < 0) { + if (def->id < 0) { virReportError(VIR_ERR_OPERATION_INVALID, - _("Domain %s isn't running."), domain->name); + _("Domain %s isn't running."), def->name); return -1; } - return xend_op(domain->conn, domain->name, "op", "unpause", NULL); + return xend_op(conn, def->name, "op", "unpause", NULL); } /** * xenDaemonDomainShutdown: - * @domain: pointer to the Domain block + * @conn: the connection object + * @def: the domain to shutdown * * Shutdown the domain, the OS is requested to properly shutdown * and the domain may ignore it. It will return immediately @@ -1302,20 +1304,21 @@ xenDaemonDomainResume(virDomainPtr domain) * Returns 0 in case of success, -1 (with errno) in case of error. */ int -xenDaemonDomainShutdown(virDomainPtr domain) +xenDaemonDomainShutdown(virConnectPtr conn, virDomainDefPtr def) { - if (domain->id < 0) { + if (def->id < 0) { virReportError(VIR_ERR_OPERATION_INVALID, - _("Domain %s isn't running."), domain->name); + _("Domain %s isn't running."), def->name); return -1; } - return xend_op(domain->conn, domain->name, "op", "shutdown", "reason", "poweroff", NULL); + return xend_op(conn, def->name, "op", "shutdown", "reason", "poweroff", NULL); } /** * xenDaemonDomainReboot: - * @domain: pointer to the Domain block + * @conn: the connection object + * @def: the domain to reboot * * Reboot the domain, the OS is requested to properly shutdown * and restart but the domain may ignore it. It will return immediately @@ -1324,20 +1327,21 @@ xenDaemonDomainShutdown(virDomainPtr domain) * Returns 0 in case of success, -1 (with errno) in case of error. */ int -xenDaemonDomainReboot(virDomainPtr domain) +xenDaemonDomainReboot(virConnectPtr conn, virDomainDefPtr def) { - if (domain->id < 0) { + if (def->id < 0) { virReportError(VIR_ERR_OPERATION_INVALID, - _("Domain %s isn't running."), domain->name); + _("Domain %s isn't running."), def->name); return -1; } - return xend_op(domain->conn, domain->name, "op", "shutdown", "reason", "reboot", NULL); + return xend_op(conn, def->name, "op", "shutdown", "reason", "reboot", NULL); } /** * xenDaemonDomainDestroy: - * @domain: pointer to the Domain block + * @conn: the connection object + * @def: the domain to destroy * * Abruptly halt the domain, the OS is not properly shutdown and the * resources allocated for the domain are immediately freed, mounted @@ -1349,15 +1353,15 @@ xenDaemonDomainReboot(virDomainPtr domain) * Returns 0 in case of success, -1 (with errno) in case of error. */ int -xenDaemonDomainDestroy(virDomainPtr domain) +xenDaemonDomainDestroy(virConnectPtr conn, virDomainDefPtr def) { - if (domain->id < 0) { + if (def->id < 0) { virReportError(VIR_ERR_OPERATION_INVALID, - _("Domain %s isn't running."), domain->name); + _("Domain %s isn't running."), def->name); return -1; } - return xend_op(domain->conn, domain->name, "op", "destroy", NULL); + return xend_op(conn, def->name, "op", "destroy", NULL); } /** @@ -2160,7 +2164,7 @@ xenDaemonCreateXML(virConnectPtr conn, const char *xmlDesc) if (xend_wait_for_devices(conn, def->name) < 0) goto error; - if (xenDaemonDomainResume(dom) < 0) + if (xenDaemonDomainResume(conn, def) < 0) goto error; virDomainDefFree(def); @@ -2169,7 +2173,7 @@ xenDaemonCreateXML(virConnectPtr conn, const char *xmlDesc) error: /* Make sure we don't leave a still-born domain around */ if (dom != NULL) { - xenDaemonDomainDestroy(dom); + xenDaemonDomainDestroy(conn, def); virObjectUnref(dom); } virDomainDefFree(def); diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h index a2d05f3..4a6b406 100644 --- a/src/xen/xend_internal.h +++ b/src/xen/xend_internal.h @@ -87,11 +87,11 @@ int xenDaemonOpen(virConnectPtr conn, virConnectAuthPtr auth, int xenDaemonClose(virConnectPtr conn); int xenDaemonNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info); int xenDaemonNodeGetTopology(virConnectPtr conn, virCapsPtr caps); -int xenDaemonDomainSuspend(virDomainPtr domain); -int xenDaemonDomainResume(virDomainPtr domain); -int xenDaemonDomainShutdown(virDomainPtr domain); -int xenDaemonDomainReboot(virDomainPtr domain); -int xenDaemonDomainDestroy(virDomainPtr domain); +int xenDaemonDomainSuspend(virConnectPtr conn, virDomainDefPtr def); +int xenDaemonDomainResume(virConnectPtr conn, virDomainDefPtr def); +int xenDaemonDomainShutdown(virConnectPtr conn, virDomainDefPtr def); +int xenDaemonDomainReboot(virConnectPtr conn, virDomainDefPtr def); +int xenDaemonDomainDestroy(virConnectPtr conn, virDomainDefPtr def); int xenDaemonDomainSave(virDomainPtr domain, const char *filename); int xenDaemonDomainCoreDump(virDomainPtr domain, const char *filename, unsigned int flags); diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c index 9b8d742..f4e8ea0 100644 --- a/src/xen/xm_internal.c +++ b/src/xen/xm_internal.c @@ -894,7 +894,7 @@ xenXMDomainCreate(virDomainPtr domain) int ret = -1; xenUnifiedPrivatePtr priv= domain->conn->privateData; const char *filename; - xenXMConfCachePtr entry; + xenXMConfCachePtr entry = NULL; xenUnifiedLock(priv); @@ -920,15 +920,15 @@ xenXMDomainCreate(virDomainPtr domain) if (xend_wait_for_devices(domain->conn, domain->name) < 0) goto error; - if (xenDaemonDomainResume(domain) < 0) + if (xenDaemonDomainResume(domain->conn, entry->def) < 0) goto error; xenUnifiedUnlock(priv); return 0; error: - if (domain->id != -1) { - xenDaemonDomainDestroy(domain); + if (domain->id != -1 && entry) { + xenDaemonDomainDestroy(domain->conn, entry->def); domain->id = -1; } xenUnifiedUnlock(priv); -- 1.8.1.4

Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Introduce use of a virDomainDefPtr in the domain lifecycle APIs to simplify introduction of ACL security checks. The virDomainPtr cannot be safely used, since the app may have supplied mis-matching name/uuid/id fields. eg the name points to domain X, while the uuid points to domain Y. Resolving the virDomainPtr to a virDomainDefPtr ensures a consistent name/uuid/id set.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/xen/xen_driver.c | 67 +++++++++++++++++++++++++++++++++++++++++++++---- src/xen/xend_internal.c | 60 ++++++++++++++++++++++--------------------- src/xen/xend_internal.h | 10 ++++---- src/xen/xm_internal.c | 8 +++--- 4 files changed, 103 insertions(+), 42 deletions(-)
Looks good. ACK. Regards, Jim
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index d9420d8..37107ff 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -136,6 +136,13 @@ static virDomainDefPtr xenGetDomainDefForUUID(virConnectPtr conn, const unsigned }
+static virDomainDefPtr xenGetDomainDefForDom(virDomainPtr dom) +{ + /* UUID lookup is more efficient than name lookup */ + return xenGetDomainDefForUUID(dom->conn, dom->uuid); +} + + /** * xenNumaInit: * @conn: pointer to the hypervisor connection @@ -781,22 +788,52 @@ xenUnifiedDomainIsUpdated(virDomainPtr dom ATTRIBUTE_UNUSED) static int xenUnifiedDomainSuspend(virDomainPtr dom) { - return xenDaemonDomainSuspend(dom); + int ret = -1; + virDomainDefPtr def; + + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + ret = xenDaemonDomainSuspend(dom->conn, def); + +cleanup: + virDomainDefFree(def); + return ret; }
static int xenUnifiedDomainResume(virDomainPtr dom) { - return xenDaemonDomainResume(dom); + int ret = -1; + virDomainDefPtr def; + + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + ret = xenDaemonDomainResume(dom->conn, def); + +cleanup: + virDomainDefFree(def); + return ret; }
static int xenUnifiedDomainShutdownFlags(virDomainPtr dom, unsigned int flags) { + int ret = -1; + virDomainDefPtr def; + virCheckFlags(0, -1);
- return xenDaemonDomainShutdown(dom); + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + ret = xenDaemonDomainShutdown(dom->conn, def); + +cleanup: + virDomainDefFree(def); + return ret; }
static int @@ -808,18 +845,38 @@ xenUnifiedDomainShutdown(virDomainPtr dom) static int xenUnifiedDomainReboot(virDomainPtr dom, unsigned int flags) { + int ret = -1; + virDomainDefPtr def; + virCheckFlags(0, -1);
- return xenDaemonDomainReboot(dom); + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + ret = xenDaemonDomainReboot(dom->conn, def); + +cleanup: + virDomainDefFree(def); + return ret; }
static int xenUnifiedDomainDestroyFlags(virDomainPtr dom, unsigned int flags) { + int ret = -1; + virDomainDefPtr def; + virCheckFlags(0, -1);
- return xenDaemonDomainDestroy(dom); + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + ret = xenDaemonDomainDestroy(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 5ea1627..f8bd72b 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -1251,7 +1251,8 @@ xenDaemonClose(virConnectPtr conn ATTRIBUTE_UNUSED)
/** * xenDaemonDomainSuspend: - * @domain: pointer to the Domain block + * @conn: the connection object + * @def: the domain to suspend * * Pause the domain, the domain is not scheduled anymore though its resources * are preserved. Use xenDaemonDomainResume() to resume execution. @@ -1259,41 +1260,42 @@ xenDaemonClose(virConnectPtr conn ATTRIBUTE_UNUSED) * Returns 0 in case of success, -1 (with errno) in case of error. */ int -xenDaemonDomainSuspend(virDomainPtr domain) +xenDaemonDomainSuspend(virConnectPtr conn, virDomainDefPtr def) { - if (domain->id < 0) { + if (def->id < 0) { virReportError(VIR_ERR_OPERATION_INVALID, - _("Domain %s isn't running."), domain->name); + _("Domain %s isn't running."), def->name); return -1; }
- return xend_op(domain->conn, domain->name, "op", "pause", NULL); + return xend_op(conn, def->name, "op", "pause", NULL); }
/** * xenDaemonDomainResume: - * @xend: pointer to the Xen Daemon block - * @name: name for the domain + * @conn: the connection object + * @def: the domain to resume * * Resume the domain after xenDaemonDomainSuspend() has been called * * Returns 0 in case of success, -1 (with errno) in case of error. */ int -xenDaemonDomainResume(virDomainPtr domain) +xenDaemonDomainResume(virConnectPtr conn, virDomainDefPtr def) { - if (domain->id < 0) { + if (def->id < 0) { virReportError(VIR_ERR_OPERATION_INVALID, - _("Domain %s isn't running."), domain->name); + _("Domain %s isn't running."), def->name); return -1; }
- return xend_op(domain->conn, domain->name, "op", "unpause", NULL); + return xend_op(conn, def->name, "op", "unpause", NULL); }
/** * xenDaemonDomainShutdown: - * @domain: pointer to the Domain block + * @conn: the connection object + * @def: the domain to shutdown * * Shutdown the domain, the OS is requested to properly shutdown * and the domain may ignore it. It will return immediately @@ -1302,20 +1304,21 @@ xenDaemonDomainResume(virDomainPtr domain) * Returns 0 in case of success, -1 (with errno) in case of error. */ int -xenDaemonDomainShutdown(virDomainPtr domain) +xenDaemonDomainShutdown(virConnectPtr conn, virDomainDefPtr def) { - if (domain->id < 0) { + if (def->id < 0) { virReportError(VIR_ERR_OPERATION_INVALID, - _("Domain %s isn't running."), domain->name); + _("Domain %s isn't running."), def->name); return -1; }
- return xend_op(domain->conn, domain->name, "op", "shutdown", "reason", "poweroff", NULL); + return xend_op(conn, def->name, "op", "shutdown", "reason", "poweroff", NULL); }
/** * xenDaemonDomainReboot: - * @domain: pointer to the Domain block + * @conn: the connection object + * @def: the domain to reboot * * Reboot the domain, the OS is requested to properly shutdown * and restart but the domain may ignore it. It will return immediately @@ -1324,20 +1327,21 @@ xenDaemonDomainShutdown(virDomainPtr domain) * Returns 0 in case of success, -1 (with errno) in case of error. */ int -xenDaemonDomainReboot(virDomainPtr domain) +xenDaemonDomainReboot(virConnectPtr conn, virDomainDefPtr def) { - if (domain->id < 0) { + if (def->id < 0) { virReportError(VIR_ERR_OPERATION_INVALID, - _("Domain %s isn't running."), domain->name); + _("Domain %s isn't running."), def->name); return -1; }
- return xend_op(domain->conn, domain->name, "op", "shutdown", "reason", "reboot", NULL); + return xend_op(conn, def->name, "op", "shutdown", "reason", "reboot", NULL); }
/** * xenDaemonDomainDestroy: - * @domain: pointer to the Domain block + * @conn: the connection object + * @def: the domain to destroy * * Abruptly halt the domain, the OS is not properly shutdown and the * resources allocated for the domain are immediately freed, mounted @@ -1349,15 +1353,15 @@ xenDaemonDomainReboot(virDomainPtr domain) * Returns 0 in case of success, -1 (with errno) in case of error. */ int -xenDaemonDomainDestroy(virDomainPtr domain) +xenDaemonDomainDestroy(virConnectPtr conn, virDomainDefPtr def) { - if (domain->id < 0) { + if (def->id < 0) { virReportError(VIR_ERR_OPERATION_INVALID, - _("Domain %s isn't running."), domain->name); + _("Domain %s isn't running."), def->name); return -1; }
- return xend_op(domain->conn, domain->name, "op", "destroy", NULL); + return xend_op(conn, def->name, "op", "destroy", NULL); }
/** @@ -2160,7 +2164,7 @@ xenDaemonCreateXML(virConnectPtr conn, const char *xmlDesc) if (xend_wait_for_devices(conn, def->name) < 0) goto error;
- if (xenDaemonDomainResume(dom) < 0) + if (xenDaemonDomainResume(conn, def) < 0) goto error;
virDomainDefFree(def); @@ -2169,7 +2173,7 @@ xenDaemonCreateXML(virConnectPtr conn, const char *xmlDesc) error: /* Make sure we don't leave a still-born domain around */ if (dom != NULL) { - xenDaemonDomainDestroy(dom); + xenDaemonDomainDestroy(conn, def); virObjectUnref(dom); } virDomainDefFree(def); diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h index a2d05f3..4a6b406 100644 --- a/src/xen/xend_internal.h +++ b/src/xen/xend_internal.h @@ -87,11 +87,11 @@ int xenDaemonOpen(virConnectPtr conn, virConnectAuthPtr auth, int xenDaemonClose(virConnectPtr conn); int xenDaemonNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info); int xenDaemonNodeGetTopology(virConnectPtr conn, virCapsPtr caps); -int xenDaemonDomainSuspend(virDomainPtr domain); -int xenDaemonDomainResume(virDomainPtr domain); -int xenDaemonDomainShutdown(virDomainPtr domain); -int xenDaemonDomainReboot(virDomainPtr domain); -int xenDaemonDomainDestroy(virDomainPtr domain); +int xenDaemonDomainSuspend(virConnectPtr conn, virDomainDefPtr def); +int xenDaemonDomainResume(virConnectPtr conn, virDomainDefPtr def); +int xenDaemonDomainShutdown(virConnectPtr conn, virDomainDefPtr def); +int xenDaemonDomainReboot(virConnectPtr conn, virDomainDefPtr def); +int xenDaemonDomainDestroy(virConnectPtr conn, virDomainDefPtr def); int xenDaemonDomainSave(virDomainPtr domain, const char *filename); int xenDaemonDomainCoreDump(virDomainPtr domain, const char *filename, unsigned int flags); diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c index 9b8d742..f4e8ea0 100644 --- a/src/xen/xm_internal.c +++ b/src/xen/xm_internal.c @@ -894,7 +894,7 @@ xenXMDomainCreate(virDomainPtr domain) int ret = -1; xenUnifiedPrivatePtr priv= domain->conn->privateData; const char *filename; - xenXMConfCachePtr entry; + xenXMConfCachePtr entry = NULL;
xenUnifiedLock(priv);
@@ -920,15 +920,15 @@ xenXMDomainCreate(virDomainPtr domain) if (xend_wait_for_devices(domain->conn, domain->name) < 0) goto error;
- if (xenDaemonDomainResume(domain) < 0) + if (xenDaemonDomainResume(domain->conn, entry->def) < 0) goto error;
xenUnifiedUnlock(priv); return 0;
error: - if (domain->id != -1) { - xenDaemonDomainDestroy(domain); + if (domain->id != -1 && entry) { + xenDaemonDomainDestroy(domain->conn, entry->def); domain->id = -1; } xenUnifiedUnlock(priv);

From: "Daniel P. Berrange" <berrange@redhat.com> Introduce use of a virDomainDefPtr in the domain property APIs to simplify introduction of ACL security checks. The virDomainPtr cannot be safely used, since the app may have supplied mis-matching name/uuid/id fields. eg the name points to domain X, while the uuid points to domain Y. Resolving the virDomainPtr to a virDomainDefPtr ensures a consistent name/uuid/id set. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/xen/xen_driver.c | 98 +++++++++++++++++++++++++++++++++++++----------- src/xen/xen_hypervisor.c | 42 +++++++++++---------- src/xen/xen_hypervisor.h | 18 +++++---- src/xen/xend_internal.c | 44 +++++++++++++--------- src/xen/xend_internal.h | 21 ++++++++--- src/xen/xm_internal.c | 41 +++++++++++--------- src/xen/xm_internal.h | 18 ++++++--- 7 files changed, 187 insertions(+), 95 deletions(-) diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 37107ff..68a86b7 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -889,18 +889,27 @@ static char * xenUnifiedDomainGetOSType(virDomainPtr dom) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + char *ret = NULL; + virDomainDefPtr def; - if (dom->id < 0) { + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + if (def->id < 0) { if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Unable to query OS type for inactive domain")); return NULL; } else { - return xenDaemonDomainGetOSType(dom); + ret = xenHypervisorDomainGetOSType(dom->conn, def); } } else { - return xenHypervisorDomainGetOSType(dom); + ret = xenDaemonDomainGetOSType(dom->conn, def); } + +cleanup: + virDomainDefFree(def); + return ret; } @@ -908,56 +917,92 @@ static unsigned long long xenUnifiedDomainGetMaxMemory(virDomainPtr dom) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + unsigned long long ret = 0; + virDomainDefPtr def; - if (dom->id < 0) { + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + if (def->id < 0) { if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainGetMaxMemory(dom); + ret = xenXMDomainGetMaxMemory(dom->conn, def); else - return xenDaemonDomainGetMaxMemory(dom); + ret = xenDaemonDomainGetMaxMemory(dom->conn, def); } else { - return xenHypervisorGetMaxMemory(dom); + ret = xenHypervisorGetMaxMemory(dom->conn, def); } + +cleanup: + virDomainDefFree(def); + return ret; } static int xenUnifiedDomainSetMaxMemory(virDomainPtr dom, unsigned long memory) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + int ret = -1; + virDomainDefPtr def; - if (dom->id < 0) { + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + if (def->id < 0) { if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainSetMaxMemory(dom, memory); + ret = xenXMDomainSetMaxMemory(dom->conn, def, memory); else - return xenDaemonDomainSetMaxMemory(dom, memory); + ret = xenDaemonDomainSetMaxMemory(dom->conn, def, memory); } else { - return xenHypervisorSetMaxMemory(dom, memory); + ret = xenHypervisorSetMaxMemory(dom->conn, def, memory); } + +cleanup: + virDomainDefFree(def); + return ret; } static int xenUnifiedDomainSetMemory(virDomainPtr dom, unsigned long memory) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + int ret = -1; + virDomainDefPtr def; - if (dom->id < 0 && priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainSetMemory(dom, memory); + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + if (def->id < 0 && priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) + ret = xenXMDomainSetMemory(dom->conn, def, memory); else - return xenDaemonDomainSetMemory(dom, memory); + ret = xenDaemonDomainSetMemory(dom->conn, def, memory); + +cleanup: + virDomainDefFree(def); + return ret; } static int xenUnifiedDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + int ret = -1; + virDomainDefPtr def; - if (dom->id < 0) { + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + if (def->id < 0) { if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainGetInfo(dom, info); + ret = xenXMDomainGetInfo(dom->conn, def, info); else - return xenDaemonDomainGetInfo(dom, info); + ret = xenDaemonDomainGetInfo(dom->conn, def, info); } else { - return xenHypervisorGetDomainInfo(dom, info); + ret = xenHypervisorGetDomainInfo(dom->conn, def, info); } + +cleanup: + virDomainDefFree(def); + return ret; } static int @@ -967,17 +1012,26 @@ xenUnifiedDomainGetState(virDomainPtr dom, unsigned int flags) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + int ret = -1; + virDomainDefPtr def; virCheckFlags(0, -1); - if (dom->id < 0) { + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + if (def->id < 0) { if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainGetState(dom, state, reason); + ret = xenXMDomainGetState(dom->conn, def, state, reason); else - return xenDaemonDomainGetState(dom, state, reason); + ret = xenDaemonDomainGetState(dom->conn, def, state, reason); } else { - return xenHypervisorGetDomainState(dom, state, reason); + ret = xenHypervisorGetDomainState(dom->conn, def, state, reason); } + +cleanup: + virDomainDefFree(def); + return ret; } static int diff --git a/src/xen/xen_hypervisor.c b/src/xen/xen_hypervisor.c index 55b0930..423ce85 100644 --- a/src/xen/xen_hypervisor.c +++ b/src/xen/xen_hypervisor.c @@ -2508,27 +2508,28 @@ xenHypervisorGetCapabilities(virConnectPtr conn) char * -xenHypervisorDomainGetOSType(virDomainPtr dom) +xenHypervisorDomainGetOSType(virConnectPtr conn, + virDomainDefPtr def) { - xenUnifiedPrivatePtr priv = dom->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; xen_getdomaininfo dominfo; char *ostype = NULL; /* HV's earlier than 3.1.0 don't include the HVM flags in guests status*/ if (hv_versions.hypervisor < 2 || hv_versions.dom_interface < 4) { - return xenDaemonDomainGetOSType(dom); + return xenDaemonDomainGetOSType(conn, def); } XEN_GETDOMAININFO_CLEAR(dominfo); - if (virXen_getdomaininfo(priv->handle, dom->id, &dominfo) < 0) { + if (virXen_getdomaininfo(priv->handle, def->id, &dominfo) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot get domain details")); return NULL; } - if (XEN_GETDOMAININFO_DOMAIN(dominfo) != dom->id) { + if (XEN_GETDOMAININFO_DOMAIN(dominfo) != def->id) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot get domain details")); return NULL; @@ -2678,9 +2679,10 @@ xenHypervisorGetMaxVcpus(virConnectPtr conn ATTRIBUTE_UNUSED, * Returns the memory size in kilobytes or 0 in case of error. */ unsigned long -xenHypervisorGetMaxMemory(virDomainPtr dom) +xenHypervisorGetMaxMemory(virConnectPtr conn, + virDomainDefPtr def) { - xenUnifiedPrivatePtr priv = dom->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; xen_getdomaininfo dominfo; int ret; @@ -2692,9 +2694,9 @@ xenHypervisorGetMaxMemory(virDomainPtr dom) XEN_GETDOMAININFO_CLEAR(dominfo); - ret = virXen_getdomaininfo(priv->handle, dom->id, &dominfo); + ret = virXen_getdomaininfo(priv->handle, def->id, &dominfo); - if ((ret < 0) || (XEN_GETDOMAININFO_DOMAIN(dominfo) != dom->id)) + if ((ret < 0) || (XEN_GETDOMAININFO_DOMAIN(dominfo) != def->id)) return 0; return (unsigned long) XEN_GETDOMAININFO_MAX_PAGES(dominfo) * kb_per_pages; @@ -2788,9 +2790,11 @@ xenHypervisorGetDomInfo(virConnectPtr conn, int id, virDomainInfoPtr info) * Returns 0 in case of success, -1 in case of error. */ int -xenHypervisorGetDomainInfo(virDomainPtr domain, virDomainInfoPtr info) +xenHypervisorGetDomainInfo(virConnectPtr conn, + virDomainDefPtr def, + virDomainInfoPtr info) { - return xenHypervisorGetDomInfo(domain->conn, domain->id, info); + return xenHypervisorGetDomInfo(conn, def->id, info); } /** @@ -2804,13 +2808,14 @@ xenHypervisorGetDomainInfo(virDomainPtr domain, virDomainInfoPtr info) * Returns 0 in case of success, -1 in case of error. */ int -xenHypervisorGetDomainState(virDomainPtr domain, +xenHypervisorGetDomainState(virConnectPtr conn, + virDomainDefPtr def, int *state, int *reason) { virDomainInfo info; - if (xenHypervisorGetDomInfo(domain->conn, domain->id, &info) < 0) + if (xenHypervisorGetDomInfo(conn, def->id, &info) < 0) return -1; *state = info.state; @@ -2899,15 +2904,14 @@ xenHypervisorNodeGetCellsFreeMemory(virConnectPtr conn, * Returns 0 in case of success, -1 in case of error. */ int -xenHypervisorSetMaxMemory(virDomainPtr domain, unsigned long memory) +xenHypervisorSetMaxMemory(virConnectPtr conn, + virDomainDefPtr def, + unsigned long memory) { int ret; - xenUnifiedPrivatePtr priv = domain->conn->privateData; - - if (domain->id < 0) - return -1; + xenUnifiedPrivatePtr priv = conn->privateData; - ret = virXen_setmaxmem(priv->handle, domain->id, memory); + ret = virXen_setmaxmem(priv->handle, def->id, memory); if (ret < 0) return -1; return 0; diff --git a/src/xen/xen_hypervisor.h b/src/xen/xen_hypervisor.h index 1d44a92..9ee1f13 100644 --- a/src/xen/xen_hypervisor.h +++ b/src/xen/xen_hypervisor.h @@ -50,7 +50,8 @@ virDomainDefPtr xenHypervisorLookupDomainByUUID (virConnectPtr conn, const unsigned char *uuid); char * - xenHypervisorDomainGetOSType (virDomainPtr dom); + xenHypervisorDomainGetOSType (virConnectPtr conn, + virDomainDefPtr def); int xenHypervisorOpen (virConnectPtr conn, @@ -64,23 +65,26 @@ virCapsPtr virArch hostarch, FILE *cpuinfo, FILE *capabilities); -char * - xenHypervisorGetCapabilities (virConnectPtr conn); +char * xenHypervisorGetCapabilities (virConnectPtr conn); unsigned long - xenHypervisorGetMaxMemory(virDomainPtr dom); + xenHypervisorGetMaxMemory(virConnectPtr conn, + virDomainDefPtr def); int xenHypervisorGetMaxVcpus (virConnectPtr conn, const char *type); -int xenHypervisorGetDomainInfo (virDomainPtr domain, +int xenHypervisorGetDomainInfo (virConnectPtr conn, + virDomainDefPtr def, virDomainInfoPtr info) ATTRIBUTE_NONNULL (1); -int xenHypervisorGetDomainState (virDomainPtr domain, +int xenHypervisorGetDomainState (virConnectPtr conn, + virDomainDefPtr def, int *state, int *reason) ATTRIBUTE_NONNULL (1); int xenHypervisorGetDomInfo (virConnectPtr conn, int id, virDomainInfoPtr info); -int xenHypervisorSetMaxMemory (virDomainPtr domain, +int xenHypervisorSetMaxMemory (virConnectPtr conn, + virDomainDefPtr def, unsigned long memory) ATTRIBUTE_NONNULL (1); int xenHypervisorCheckID (virConnectPtr conn, diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index f8bd72b..c10567c 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -890,7 +890,7 @@ xend_detect_config_version(virConnectPtr conn) */ static int ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) -sexpr_to_xend_domain_state(virDomainPtr domain, const struct sexpr *root) +sexpr_to_xend_domain_state(virDomainDefPtr def, const struct sexpr *root) { const char *flags; int state = VIR_DOMAIN_NOSTATE; @@ -908,7 +908,7 @@ sexpr_to_xend_domain_state(virDomainPtr domain, const struct sexpr *root) state = VIR_DOMAIN_BLOCKED; else if (strchr(flags, 'r')) state = VIR_DOMAIN_RUNNING; - } else if (domain->id < 0 || sexpr_int(root, "domain/status") == 0) { + } else if (def->id < 0 || sexpr_int(root, "domain/status") == 0) { /* As far as I can see the domain->id is a bad sign for checking * inactive domains as this is inaccurate after the domain has * been running once. However domain/status from xend seems to @@ -933,13 +933,13 @@ sexpr_to_xend_domain_state(virDomainPtr domain, const struct sexpr *root) * Returns 0 in case of success, -1 in case of error */ static int -sexpr_to_xend_domain_info(virDomainPtr domain, +sexpr_to_xend_domain_info(virDomainDefPtr def, const struct sexpr *root, virDomainInfoPtr info) { int vcpus; - info->state = sexpr_to_xend_domain_state(domain, root); + info->state = sexpr_to_xend_domain_state(def, root); info->memory = sexpr_u64(root, "domain/memory") << 10; info->maxMem = sexpr_u64(root, "domain/maxmem") << 10; info->cpuTime = sexpr_float(root, "domain/cpu_time") * 1000000000; @@ -1374,13 +1374,14 @@ xenDaemonDomainDestroy(virConnectPtr conn, virDomainDefPtr def) * freed by the caller. */ char * -xenDaemonDomainGetOSType(virDomainPtr domain) +xenDaemonDomainGetOSType(virConnectPtr conn, + virDomainDefPtr def) { char *type; struct sexpr *root; /* can we ask for a subset ? worth it ? */ - root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name); + root = sexpr_get(conn, "/xend/domain/%s?detail=1", def->name); if (root == NULL) return NULL; @@ -1489,13 +1490,13 @@ xenDaemonDomainRestore(virConnectPtr conn, const char *filename) * Returns the memory size in kilobytes or 0 in case of error. */ unsigned long long -xenDaemonDomainGetMaxMemory(virDomainPtr domain) +xenDaemonDomainGetMaxMemory(virConnectPtr conn, virDomainDefPtr def) { unsigned long long ret = 0; struct sexpr *root; /* can we ask for a subset ? worth it ? */ - root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name); + root = sexpr_get(conn, "/xend/domain/%s?detail=1", def->name); if (root == NULL) return 0; @@ -1518,12 +1519,14 @@ xenDaemonDomainGetMaxMemory(virDomainPtr domain) * Returns 0 for success; -1 (with errno) on error */ int -xenDaemonDomainSetMaxMemory(virDomainPtr domain, unsigned long memory) +xenDaemonDomainSetMaxMemory(virConnectPtr conn, + virDomainDefPtr def, + unsigned long memory) { char buf[1024]; snprintf(buf, sizeof(buf), "%lu", VIR_DIV_UP(memory, 1024)); - return xend_op(domain->conn, domain->name, "op", "maxmem_set", "memory", + return xend_op(conn, def->name, "op", "maxmem_set", "memory", buf, NULL); } @@ -1544,12 +1547,14 @@ xenDaemonDomainSetMaxMemory(virDomainPtr domain, unsigned long memory) * Returns 0 for success; -1 (with errno) on error */ int -xenDaemonDomainSetMemory(virDomainPtr domain, unsigned long memory) +xenDaemonDomainSetMemory(virConnectPtr conn, + virDomainDefPtr def, + unsigned long memory) { char buf[1024]; snprintf(buf, sizeof(buf), "%lu", VIR_DIV_UP(memory, 1024)); - return xend_op(domain->conn, domain->name, "op", "mem_target_set", + return xend_op(conn, def->name, "op", "mem_target_set", "target", buf, NULL); } @@ -1640,16 +1645,18 @@ xenDaemonDomainGetXMLDesc(virDomainPtr domain, * Returns 0 in case of success, -1 in case of error */ int -xenDaemonDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info) +xenDaemonDomainGetInfo(virConnectPtr conn, + virDomainDefPtr def, + virDomainInfoPtr info) { struct sexpr *root; int ret; - root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name); + root = sexpr_get(conn, "/xend/domain/%s?detail=1", def->name); if (root == NULL) return -1; - ret = sexpr_to_xend_domain_info(domain, root, info); + ret = sexpr_to_xend_domain_info(def, root, info); sexpr_free(root); return ret; } @@ -1666,17 +1673,18 @@ xenDaemonDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info) * Returns 0 in case of success, -1 in case of error */ int -xenDaemonDomainGetState(virDomainPtr domain, +xenDaemonDomainGetState(virConnectPtr conn, + virDomainDefPtr def, int *state, int *reason) { struct sexpr *root; - root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name); + root = sexpr_get(conn, "/xend/domain/%s?detail=1", def->name); if (!root) return -1; - *state = sexpr_to_xend_domain_state(domain, root); + *state = sexpr_to_xend_domain_state(def, root); if (reason) *reason = 0; diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h index 4a6b406..87e0a0f 100644 --- a/src/xen/xend_internal.h +++ b/src/xen/xend_internal.h @@ -96,18 +96,27 @@ int xenDaemonDomainSave(virDomainPtr domain, const char *filename); int xenDaemonDomainCoreDump(virDomainPtr domain, const char *filename, unsigned int flags); int xenDaemonDomainRestore(virConnectPtr conn, const char *filename); -int xenDaemonDomainSetMemory(virDomainPtr domain, unsigned long memory); -int xenDaemonDomainSetMaxMemory(virDomainPtr domain, unsigned long memory); -int xenDaemonDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info); -int xenDaemonDomainGetState(virDomainPtr domain, +int xenDaemonDomainSetMemory(virConnectPtr conn, + virDomainDefPtr def, + unsigned long memory); +int xenDaemonDomainSetMaxMemory(virConnectPtr conn, + virDomainDefPtr def, + unsigned long memory); +int xenDaemonDomainGetInfo(virConnectPtr conn, + virDomainDefPtr def, + virDomainInfoPtr info); +int xenDaemonDomainGetState(virConnectPtr conn, + virDomainDefPtr def, int *state, int *reason); char *xenDaemonDomainGetXMLDesc(virDomainPtr domain, unsigned int flags, const char *cpus); -unsigned long long xenDaemonDomainGetMaxMemory(virDomainPtr domain); +unsigned long long xenDaemonDomainGetMaxMemory(virConnectPtr conn, + virDomainDefPtr def); char **xenDaemonListDomainsOld(virConnectPtr xend); -char *xenDaemonDomainGetOSType(virDomainPtr domain); +char *xenDaemonDomainGetOSType(virConnectPtr conn, + virDomainDefPtr def); int xenDaemonNumOfDefinedDomains(virConnectPtr conn); int xenDaemonListDefinedDomains(virConnectPtr conn, diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c index f4e8ea0..ce44e39 100644 --- a/src/xen/xm_internal.c +++ b/src/xen/xm_internal.c @@ -446,7 +446,8 @@ xenXMClose(virConnectPtr conn) * Since these are all offline domains, the state is always SHUTOFF. */ int -xenXMDomainGetState(virDomainPtr domain ATTRIBUTE_UNUSED, +xenXMDomainGetState(virConnectPtr conn ATTRIBUTE_UNUSED, + virDomainDefPtr def ATTRIBUTE_UNUSED, int *state, int *reason) { @@ -463,15 +464,17 @@ xenXMDomainGetState(virDomainPtr domain ATTRIBUTE_UNUSED, * VCPUs and memory. */ int -xenXMDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info) +xenXMDomainGetInfo(virConnectPtr conn, + virDomainDefPtr def, + virDomainInfoPtr info) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; const char *filename; xenXMConfCachePtr entry; xenUnifiedLock(priv); - if (!(filename = virHashLookup(priv->nameConfigMap, domain->name))) + if (!(filename = virHashLookup(priv->nameConfigMap, def->name))) goto error; if (!(entry = virHashLookup(priv->configCache, filename))) @@ -530,9 +533,11 @@ cleanup: * Update amount of memory in the config file */ int -xenXMDomainSetMemory(virDomainPtr domain, unsigned long memory) +xenXMDomainSetMemory(virConnectPtr conn, + virDomainDefPtr def, + unsigned long memory) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; const char *filename; xenXMConfCachePtr entry; int ret = -1; @@ -546,7 +551,7 @@ xenXMDomainSetMemory(virDomainPtr domain, unsigned long memory) xenUnifiedLock(priv); - if (!(filename = virHashLookup(priv->nameConfigMap, domain->name))) + if (!(filename = virHashLookup(priv->nameConfigMap, def->name))) goto cleanup; if (!(entry = virHashLookup(priv->configCache, filename))) @@ -559,7 +564,7 @@ xenXMDomainSetMemory(virDomainPtr domain, unsigned long memory) /* If this fails, should we try to undo our changes to the * in-memory representation of the config file. I say not! */ - if (xenXMConfigSaveFile(domain->conn, entry->filename, entry->def) < 0) + if (xenXMConfigSaveFile(conn, entry->filename, entry->def) < 0) goto cleanup; ret = 0; @@ -572,9 +577,11 @@ cleanup: * Update maximum memory limit in config */ int -xenXMDomainSetMaxMemory(virDomainPtr domain, unsigned long memory) +xenXMDomainSetMaxMemory(virConnectPtr conn, + virDomainDefPtr def, + unsigned long memory) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; const char *filename; xenXMConfCachePtr entry; int ret = -1; @@ -588,7 +595,7 @@ xenXMDomainSetMaxMemory(virDomainPtr domain, unsigned long memory) xenUnifiedLock(priv); - if (!(filename = virHashLookup(priv->nameConfigMap, domain->name))) + if (!(filename = virHashLookup(priv->nameConfigMap, def->name))) goto cleanup; if (!(entry = virHashLookup(priv->configCache, filename))) @@ -601,7 +608,7 @@ xenXMDomainSetMaxMemory(virDomainPtr domain, unsigned long memory) /* If this fails, should we try to undo our changes to the * in-memory representation of the config file. I say not! */ - if (xenXMConfigSaveFile(domain->conn, entry->filename, entry->def) < 0) + if (xenXMConfigSaveFile(conn, entry->filename, entry->def) < 0) goto cleanup; ret = 0; @@ -614,19 +621,17 @@ cleanup: * Get max memory limit from config */ unsigned long long -xenXMDomainGetMaxMemory(virDomainPtr domain) +xenXMDomainGetMaxMemory(virConnectPtr conn, + virDomainDefPtr def) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; const char *filename; xenXMConfCachePtr entry; unsigned long long ret = 0; - if (domain->id != -1) - return 0; - xenUnifiedLock(priv); - if (!(filename = virHashLookup(priv->nameConfigMap, domain->name))) + if (!(filename = virHashLookup(priv->nameConfigMap, def->name))) goto cleanup; if (!(entry = virHashLookup(priv->configCache, filename))) diff --git a/src/xen/xm_internal.h b/src/xen/xm_internal.h index 0e55897..0ae32bc 100644 --- a/src/xen/xm_internal.h +++ b/src/xen/xm_internal.h @@ -37,14 +37,22 @@ int xenXMConfigCacheRemoveFile(virConnectPtr conn, const char *filename); int xenXMOpen(virConnectPtr conn, virConnectAuthPtr auth, unsigned int flags); int xenXMClose(virConnectPtr conn); const char *xenXMGetType(virConnectPtr conn); -int xenXMDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info); -int xenXMDomainGetState(virDomainPtr domain, +int xenXMDomainGetInfo(virConnectPtr conn, + virDomainDefPtr def, + virDomainInfoPtr info); +int xenXMDomainGetState(virConnectPtr conn, + virDomainDefPtr def, int *state, int *reason); char *xenXMDomainGetXMLDesc(virDomainPtr domain, unsigned int flags); -int xenXMDomainSetMemory(virDomainPtr domain, unsigned long memory); -int xenXMDomainSetMaxMemory(virDomainPtr domain, unsigned long memory); -unsigned long long xenXMDomainGetMaxMemory(virDomainPtr domain); +int xenXMDomainSetMemory(virConnectPtr conn, + virDomainDefPtr def, + unsigned long memory); +int xenXMDomainSetMaxMemory(virConnectPtr conn, + virDomainDefPtr def, + unsigned long memory); +unsigned long long xenXMDomainGetMaxMemory(virConnectPtr conn, + virDomainDefPtr def); int xenXMDomainSetVcpus(virDomainPtr domain, unsigned int vcpus); int xenXMDomainSetVcpusFlags(virDomainPtr domain, unsigned int vcpus, unsigned int flags); -- 1.8.1.4

Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Introduce use of a virDomainDefPtr in the domain property APIs to simplify introduction of ACL security checks. The virDomainPtr cannot be safely used, since the app may have supplied mis-matching name/uuid/id fields. eg the name points to domain X, while the uuid points to domain Y. Resolving the virDomainPtr to a virDomainDefPtr ensures a consistent name/uuid/id set.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/xen/xen_driver.c | 98 +++++++++++++++++++++++++++++++++++++----------- src/xen/xen_hypervisor.c | 42 +++++++++++---------- src/xen/xen_hypervisor.h | 18 +++++---- src/xen/xend_internal.c | 44 +++++++++++++--------- src/xen/xend_internal.h | 21 ++++++++--- src/xen/xm_internal.c | 41 +++++++++++--------- src/xen/xm_internal.h | 18 ++++++--- 7 files changed, 187 insertions(+), 95 deletions(-)
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 37107ff..68a86b7 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -889,18 +889,27 @@ static char * xenUnifiedDomainGetOSType(virDomainPtr dom) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + char *ret = NULL; + virDomainDefPtr def;
- if (dom->id < 0) { + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + if (def->id < 0) { if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Unable to query OS type for inactive domain")); return NULL; } else { - return xenDaemonDomainGetOSType(dom); + ret = xenHypervisorDomainGetOSType(dom->conn, def);
Should still call xenDaemonDomainGetOSType here since id < 0 right?
} } else { - return xenHypervisorDomainGetOSType(dom); + ret = xenDaemonDomainGetOSType(dom->conn, def);
And call the hypervisor one here when the domain is active.
} + +cleanup: + virDomainDefFree(def); + return ret; }
@@ -908,56 +917,92 @@ static unsigned long long xenUnifiedDomainGetMaxMemory(virDomainPtr dom) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + unsigned long long ret = 0; + virDomainDefPtr def;
- if (dom->id < 0) { + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + if (def->id < 0) { if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainGetMaxMemory(dom); + ret = xenXMDomainGetMaxMemory(dom->conn, def); else - return xenDaemonDomainGetMaxMemory(dom); + ret = xenDaemonDomainGetMaxMemory(dom->conn, def); } else { - return xenHypervisorGetMaxMemory(dom); + ret = xenHypervisorGetMaxMemory(dom->conn, def); } + +cleanup: + virDomainDefFree(def); + return ret; }
static int xenUnifiedDomainSetMaxMemory(virDomainPtr dom, unsigned long memory) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + int ret = -1; + virDomainDefPtr def;
- if (dom->id < 0) { + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + if (def->id < 0) { if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainSetMaxMemory(dom, memory); + ret = xenXMDomainSetMaxMemory(dom->conn, def, memory); else - return xenDaemonDomainSetMaxMemory(dom, memory); + ret = xenDaemonDomainSetMaxMemory(dom->conn, def, memory); } else { - return xenHypervisorSetMaxMemory(dom, memory); + ret = xenHypervisorSetMaxMemory(dom->conn, def, memory); } + +cleanup: + virDomainDefFree(def); + return ret; }
static int xenUnifiedDomainSetMemory(virDomainPtr dom, unsigned long memory) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + int ret = -1; + virDomainDefPtr def;
- if (dom->id < 0 && priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainSetMemory(dom, memory); + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + if (def->id < 0 && priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) + ret = xenXMDomainSetMemory(dom->conn, def, memory); else - return xenDaemonDomainSetMemory(dom, memory); + ret = xenDaemonDomainSetMemory(dom->conn, def, memory); + +cleanup: + virDomainDefFree(def); + return ret; }
static int xenUnifiedDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + int ret = -1; + virDomainDefPtr def;
- if (dom->id < 0) { + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + if (def->id < 0) { if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainGetInfo(dom, info); + ret = xenXMDomainGetInfo(dom->conn, def, info); else - return xenDaemonDomainGetInfo(dom, info); + ret = xenDaemonDomainGetInfo(dom->conn, def, info); } else { - return xenHypervisorGetDomainInfo(dom, info); + ret = xenHypervisorGetDomainInfo(dom->conn, def, info); } + +cleanup: + virDomainDefFree(def); + return ret; }
static int @@ -967,17 +1012,26 @@ xenUnifiedDomainGetState(virDomainPtr dom, unsigned int flags) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + int ret = -1; + virDomainDefPtr def;
virCheckFlags(0, -1);
- if (dom->id < 0) { + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + if (def->id < 0) { if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainGetState(dom, state, reason); + ret = xenXMDomainGetState(dom->conn, def, state, reason); else - return xenDaemonDomainGetState(dom, state, reason); + ret = xenDaemonDomainGetState(dom->conn, def, state, reason); } else { - return xenHypervisorGetDomainState(dom, state, reason); + ret = xenHypervisorGetDomainState(dom->conn, def, state, reason); } + +cleanup: + virDomainDefFree(def); + return ret; }
static int diff --git a/src/xen/xen_hypervisor.c b/src/xen/xen_hypervisor.c index 55b0930..423ce85 100644 --- a/src/xen/xen_hypervisor.c +++ b/src/xen/xen_hypervisor.c @@ -2508,27 +2508,28 @@ xenHypervisorGetCapabilities(virConnectPtr conn)
char * -xenHypervisorDomainGetOSType(virDomainPtr dom) +xenHypervisorDomainGetOSType(virConnectPtr conn, + virDomainDefPtr def)
Fits on one line.
{ - xenUnifiedPrivatePtr priv = dom->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; xen_getdomaininfo dominfo; char *ostype = NULL;
/* HV's earlier than 3.1.0 don't include the HVM flags in guests status*/ if (hv_versions.hypervisor < 2 || hv_versions.dom_interface < 4) { - return xenDaemonDomainGetOSType(dom); + return xenDaemonDomainGetOSType(conn, def); }
XEN_GETDOMAININFO_CLEAR(dominfo);
- if (virXen_getdomaininfo(priv->handle, dom->id, &dominfo) < 0) { + if (virXen_getdomaininfo(priv->handle, def->id, &dominfo) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot get domain details")); return NULL; }
- if (XEN_GETDOMAININFO_DOMAIN(dominfo) != dom->id) { + if (XEN_GETDOMAININFO_DOMAIN(dominfo) != def->id) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot get domain details")); return NULL; @@ -2678,9 +2679,10 @@ xenHypervisorGetMaxVcpus(virConnectPtr conn ATTRIBUTE_UNUSED, * Returns the memory size in kilobytes or 0 in case of error. */ unsigned long -xenHypervisorGetMaxMemory(virDomainPtr dom) +xenHypervisorGetMaxMemory(virConnectPtr conn, + virDomainDefPtr def)
Same here.
{ - xenUnifiedPrivatePtr priv = dom->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; xen_getdomaininfo dominfo; int ret;
@@ -2692,9 +2694,9 @@ xenHypervisorGetMaxMemory(virDomainPtr dom)
XEN_GETDOMAININFO_CLEAR(dominfo);
- ret = virXen_getdomaininfo(priv->handle, dom->id, &dominfo); + ret = virXen_getdomaininfo(priv->handle, def->id, &dominfo);
- if ((ret < 0) || (XEN_GETDOMAININFO_DOMAIN(dominfo) != dom->id)) + if ((ret < 0) || (XEN_GETDOMAININFO_DOMAIN(dominfo) != def->id)) return 0;
return (unsigned long) XEN_GETDOMAININFO_MAX_PAGES(dominfo) * kb_per_pages; @@ -2788,9 +2790,11 @@ xenHypervisorGetDomInfo(virConnectPtr conn, int id, virDomainInfoPtr info) * Returns 0 in case of success, -1 in case of error. */ int -xenHypervisorGetDomainInfo(virDomainPtr domain, virDomainInfoPtr info) +xenHypervisorGetDomainInfo(virConnectPtr conn, + virDomainDefPtr def, + virDomainInfoPtr info) { - return xenHypervisorGetDomInfo(domain->conn, domain->id, info); + return xenHypervisorGetDomInfo(conn, def->id, info); }
/** @@ -2804,13 +2808,14 @@ xenHypervisorGetDomainInfo(virDomainPtr domain, virDomainInfoPtr info) * Returns 0 in case of success, -1 in case of error. */ int -xenHypervisorGetDomainState(virDomainPtr domain, +xenHypervisorGetDomainState(virConnectPtr conn, + virDomainDefPtr def, int *state, int *reason) { virDomainInfo info;
- if (xenHypervisorGetDomInfo(domain->conn, domain->id, &info) < 0) + if (xenHypervisorGetDomInfo(conn, def->id, &info) < 0) return -1;
*state = info.state; @@ -2899,15 +2904,14 @@ xenHypervisorNodeGetCellsFreeMemory(virConnectPtr conn, * Returns 0 in case of success, -1 in case of error. */ int -xenHypervisorSetMaxMemory(virDomainPtr domain, unsigned long memory) +xenHypervisorSetMaxMemory(virConnectPtr conn, + virDomainDefPtr def, + unsigned long memory) { int ret; - xenUnifiedPrivatePtr priv = domain->conn->privateData; - - if (domain->id < 0) - return -1; + xenUnifiedPrivatePtr priv = conn->privateData;
- ret = virXen_setmaxmem(priv->handle, domain->id, memory); + ret = virXen_setmaxmem(priv->handle, def->id, memory); if (ret < 0) return -1; return 0; diff --git a/src/xen/xen_hypervisor.h b/src/xen/xen_hypervisor.h index 1d44a92..9ee1f13 100644 --- a/src/xen/xen_hypervisor.h +++ b/src/xen/xen_hypervisor.h @@ -50,7 +50,8 @@ virDomainDefPtr xenHypervisorLookupDomainByUUID (virConnectPtr conn, const unsigned char *uuid); char * - xenHypervisorDomainGetOSType (virDomainPtr dom); + xenHypervisorDomainGetOSType (virConnectPtr conn, + virDomainDefPtr def);
int xenHypervisorOpen (virConnectPtr conn, @@ -64,23 +65,26 @@ virCapsPtr virArch hostarch, FILE *cpuinfo, FILE *capabilities); -char * - xenHypervisorGetCapabilities (virConnectPtr conn); +char * xenHypervisorGetCapabilities (virConnectPtr conn); unsigned long - xenHypervisorGetMaxMemory(virDomainPtr dom); + xenHypervisorGetMaxMemory(virConnectPtr conn, + virDomainDefPtr def); int xenHypervisorGetMaxVcpus (virConnectPtr conn, const char *type); -int xenHypervisorGetDomainInfo (virDomainPtr domain, +int xenHypervisorGetDomainInfo (virConnectPtr conn, + virDomainDefPtr def, virDomainInfoPtr info) ATTRIBUTE_NONNULL (1); -int xenHypervisorGetDomainState (virDomainPtr domain, +int xenHypervisorGetDomainState (virConnectPtr conn, + virDomainDefPtr def, int *state, int *reason) ATTRIBUTE_NONNULL (1); int xenHypervisorGetDomInfo (virConnectPtr conn, int id, virDomainInfoPtr info); -int xenHypervisorSetMaxMemory (virDomainPtr domain, +int xenHypervisorSetMaxMemory (virConnectPtr conn, + virDomainDefPtr def, unsigned long memory) ATTRIBUTE_NONNULL (1); int xenHypervisorCheckID (virConnectPtr conn, diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index f8bd72b..c10567c 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -890,7 +890,7 @@ xend_detect_config_version(virConnectPtr conn) */ static int ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) -sexpr_to_xend_domain_state(virDomainPtr domain, const struct sexpr *root) +sexpr_to_xend_domain_state(virDomainDefPtr def, const struct sexpr *root) { const char *flags; int state = VIR_DOMAIN_NOSTATE; @@ -908,7 +908,7 @@ sexpr_to_xend_domain_state(virDomainPtr domain, const struct sexpr *root) state = VIR_DOMAIN_BLOCKED; else if (strchr(flags, 'r')) state = VIR_DOMAIN_RUNNING; - } else if (domain->id < 0 || sexpr_int(root, "domain/status") == 0) { + } else if (def->id < 0 || sexpr_int(root, "domain/status") == 0) { /* As far as I can see the domain->id is a bad sign for checking * inactive domains as this is inaccurate after the domain has * been running once. However domain/status from xend seems to @@ -933,13 +933,13 @@ sexpr_to_xend_domain_state(virDomainPtr domain, const struct sexpr *root) * Returns 0 in case of success, -1 in case of error */ static int -sexpr_to_xend_domain_info(virDomainPtr domain, +sexpr_to_xend_domain_info(virDomainDefPtr def, const struct sexpr *root, virDomainInfoPtr info) { int vcpus;
- info->state = sexpr_to_xend_domain_state(domain, root); + info->state = sexpr_to_xend_domain_state(def, root); info->memory = sexpr_u64(root, "domain/memory") << 10; info->maxMem = sexpr_u64(root, "domain/maxmem") << 10; info->cpuTime = sexpr_float(root, "domain/cpu_time") * 1000000000; @@ -1374,13 +1374,14 @@ xenDaemonDomainDestroy(virConnectPtr conn, virDomainDefPtr def) * freed by the caller. */ char * -xenDaemonDomainGetOSType(virDomainPtr domain) +xenDaemonDomainGetOSType(virConnectPtr conn, + virDomainDefPtr def)
Fits on one line.
{ char *type; struct sexpr *root;
/* can we ask for a subset ? worth it ? */ - root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name); + root = sexpr_get(conn, "/xend/domain/%s?detail=1", def->name); if (root == NULL) return NULL;
@@ -1489,13 +1490,13 @@ xenDaemonDomainRestore(virConnectPtr conn, const char *filename) * Returns the memory size in kilobytes or 0 in case of error. */ unsigned long long -xenDaemonDomainGetMaxMemory(virDomainPtr domain) +xenDaemonDomainGetMaxMemory(virConnectPtr conn, virDomainDefPtr def) { unsigned long long ret = 0; struct sexpr *root;
/* can we ask for a subset ? worth it ? */ - root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name); + root = sexpr_get(conn, "/xend/domain/%s?detail=1", def->name); if (root == NULL) return 0;
@@ -1518,12 +1519,14 @@ xenDaemonDomainGetMaxMemory(virDomainPtr domain) * Returns 0 for success; -1 (with errno) on error */ int -xenDaemonDomainSetMaxMemory(virDomainPtr domain, unsigned long memory) +xenDaemonDomainSetMaxMemory(virConnectPtr conn, + virDomainDefPtr def, + unsigned long memory) { char buf[1024];
snprintf(buf, sizeof(buf), "%lu", VIR_DIV_UP(memory, 1024)); - return xend_op(domain->conn, domain->name, "op", "maxmem_set", "memory", + return xend_op(conn, def->name, "op", "maxmem_set", "memory", buf, NULL);
Can be condensed to one line here.
}
@@ -1544,12 +1547,14 @@ xenDaemonDomainSetMaxMemory(virDomainPtr domain, unsigned long memory) * Returns 0 for success; -1 (with errno) on error */ int -xenDaemonDomainSetMemory(virDomainPtr domain, unsigned long memory) +xenDaemonDomainSetMemory(virConnectPtr conn, + virDomainDefPtr def, + unsigned long memory) { char buf[1024];
snprintf(buf, sizeof(buf), "%lu", VIR_DIV_UP(memory, 1024)); - return xend_op(domain->conn, domain->name, "op", "mem_target_set", + return xend_op(conn, def->name, "op", "mem_target_set", "target", buf, NULL);
And here at exactly 80 columns :).
}
@@ -1640,16 +1645,18 @@ xenDaemonDomainGetXMLDesc(virDomainPtr domain, * Returns 0 in case of success, -1 in case of error */ int -xenDaemonDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info) +xenDaemonDomainGetInfo(virConnectPtr conn, + virDomainDefPtr def, + virDomainInfoPtr info) { struct sexpr *root; int ret;
- root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name); + root = sexpr_get(conn, "/xend/domain/%s?detail=1", def->name); if (root == NULL) return -1;
- ret = sexpr_to_xend_domain_info(domain, root, info); + ret = sexpr_to_xend_domain_info(def, root, info); sexpr_free(root); return ret; } @@ -1666,17 +1673,18 @@ xenDaemonDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info) * Returns 0 in case of success, -1 in case of error */ int -xenDaemonDomainGetState(virDomainPtr domain, +xenDaemonDomainGetState(virConnectPtr conn, + virDomainDefPtr def, int *state, int *reason) { struct sexpr *root;
- root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name); + root = sexpr_get(conn, "/xend/domain/%s?detail=1", def->name); if (!root) return -1;
- *state = sexpr_to_xend_domain_state(domain, root); + *state = sexpr_to_xend_domain_state(def, root); if (reason) *reason = 0;
diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h index 4a6b406..87e0a0f 100644 --- a/src/xen/xend_internal.h +++ b/src/xen/xend_internal.h @@ -96,18 +96,27 @@ int xenDaemonDomainSave(virDomainPtr domain, const char *filename); int xenDaemonDomainCoreDump(virDomainPtr domain, const char *filename, unsigned int flags); int xenDaemonDomainRestore(virConnectPtr conn, const char *filename); -int xenDaemonDomainSetMemory(virDomainPtr domain, unsigned long memory); -int xenDaemonDomainSetMaxMemory(virDomainPtr domain, unsigned long memory); -int xenDaemonDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info); -int xenDaemonDomainGetState(virDomainPtr domain, +int xenDaemonDomainSetMemory(virConnectPtr conn, + virDomainDefPtr def, + unsigned long memory); +int xenDaemonDomainSetMaxMemory(virConnectPtr conn, + virDomainDefPtr def, + unsigned long memory); +int xenDaemonDomainGetInfo(virConnectPtr conn, + virDomainDefPtr def, + virDomainInfoPtr info); +int xenDaemonDomainGetState(virConnectPtr conn, + virDomainDefPtr def, int *state, int *reason); char *xenDaemonDomainGetXMLDesc(virDomainPtr domain, unsigned int flags, const char *cpus); -unsigned long long xenDaemonDomainGetMaxMemory(virDomainPtr domain); +unsigned long long xenDaemonDomainGetMaxMemory(virConnectPtr conn, + virDomainDefPtr def); char **xenDaemonListDomainsOld(virConnectPtr xend);
-char *xenDaemonDomainGetOSType(virDomainPtr domain); +char *xenDaemonDomainGetOSType(virConnectPtr conn, + virDomainDefPtr def);
Still fits on one line.
int xenDaemonNumOfDefinedDomains(virConnectPtr conn); int xenDaemonListDefinedDomains(virConnectPtr conn, diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c index f4e8ea0..ce44e39 100644 --- a/src/xen/xm_internal.c +++ b/src/xen/xm_internal.c @@ -446,7 +446,8 @@ xenXMClose(virConnectPtr conn) * Since these are all offline domains, the state is always SHUTOFF. */ int -xenXMDomainGetState(virDomainPtr domain ATTRIBUTE_UNUSED, +xenXMDomainGetState(virConnectPtr conn ATTRIBUTE_UNUSED, + virDomainDefPtr def ATTRIBUTE_UNUSED, int *state, int *reason) { @@ -463,15 +464,17 @@ xenXMDomainGetState(virDomainPtr domain ATTRIBUTE_UNUSED, * VCPUs and memory. */ int -xenXMDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info) +xenXMDomainGetInfo(virConnectPtr conn, + virDomainDefPtr def, + virDomainInfoPtr info) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; const char *filename; xenXMConfCachePtr entry;
xenUnifiedLock(priv);
- if (!(filename = virHashLookup(priv->nameConfigMap, domain->name))) + if (!(filename = virHashLookup(priv->nameConfigMap, def->name))) goto error;
if (!(entry = virHashLookup(priv->configCache, filename))) @@ -530,9 +533,11 @@ cleanup: * Update amount of memory in the config file */ int -xenXMDomainSetMemory(virDomainPtr domain, unsigned long memory) +xenXMDomainSetMemory(virConnectPtr conn, + virDomainDefPtr def, + unsigned long memory) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; const char *filename; xenXMConfCachePtr entry; int ret = -1; @@ -546,7 +551,7 @@ xenXMDomainSetMemory(virDomainPtr domain, unsigned long memory)
xenUnifiedLock(priv);
- if (!(filename = virHashLookup(priv->nameConfigMap, domain->name))) + if (!(filename = virHashLookup(priv->nameConfigMap, def->name))) goto cleanup;
if (!(entry = virHashLookup(priv->configCache, filename))) @@ -559,7 +564,7 @@ xenXMDomainSetMemory(virDomainPtr domain, unsigned long memory) /* If this fails, should we try to undo our changes to the * in-memory representation of the config file. I say not! */ - if (xenXMConfigSaveFile(domain->conn, entry->filename, entry->def) < 0) + if (xenXMConfigSaveFile(conn, entry->filename, entry->def) < 0) goto cleanup; ret = 0;
@@ -572,9 +577,11 @@ cleanup: * Update maximum memory limit in config */ int -xenXMDomainSetMaxMemory(virDomainPtr domain, unsigned long memory) +xenXMDomainSetMaxMemory(virConnectPtr conn, + virDomainDefPtr def, + unsigned long memory) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; const char *filename; xenXMConfCachePtr entry; int ret = -1; @@ -588,7 +595,7 @@ xenXMDomainSetMaxMemory(virDomainPtr domain, unsigned long memory)
xenUnifiedLock(priv);
- if (!(filename = virHashLookup(priv->nameConfigMap, domain->name))) + if (!(filename = virHashLookup(priv->nameConfigMap, def->name))) goto cleanup;
if (!(entry = virHashLookup(priv->configCache, filename))) @@ -601,7 +608,7 @@ xenXMDomainSetMaxMemory(virDomainPtr domain, unsigned long memory) /* If this fails, should we try to undo our changes to the * in-memory representation of the config file. I say not! */ - if (xenXMConfigSaveFile(domain->conn, entry->filename, entry->def) < 0) + if (xenXMConfigSaveFile(conn, entry->filename, entry->def) < 0) goto cleanup; ret = 0;
@@ -614,19 +621,17 @@ cleanup: * Get max memory limit from config */ unsigned long long -xenXMDomainGetMaxMemory(virDomainPtr domain) +xenXMDomainGetMaxMemory(virConnectPtr conn, + virDomainDefPtr def)
Still fits on one line. ACK, pending answer to question above about xenDaemonDomainGetOSType vs xenHypervisorDomainGetOSType. Regards, Jim
{ - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; const char *filename; xenXMConfCachePtr entry; unsigned long long ret = 0;
- if (domain->id != -1) - return 0; - xenUnifiedLock(priv);
- if (!(filename = virHashLookup(priv->nameConfigMap, domain->name))) + if (!(filename = virHashLookup(priv->nameConfigMap, def->name))) goto cleanup;
if (!(entry = virHashLookup(priv->configCache, filename))) diff --git a/src/xen/xm_internal.h b/src/xen/xm_internal.h index 0e55897..0ae32bc 100644 --- a/src/xen/xm_internal.h +++ b/src/xen/xm_internal.h @@ -37,14 +37,22 @@ int xenXMConfigCacheRemoveFile(virConnectPtr conn, const char *filename); int xenXMOpen(virConnectPtr conn, virConnectAuthPtr auth, unsigned int flags); int xenXMClose(virConnectPtr conn); const char *xenXMGetType(virConnectPtr conn); -int xenXMDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info); -int xenXMDomainGetState(virDomainPtr domain, +int xenXMDomainGetInfo(virConnectPtr conn, + virDomainDefPtr def, + virDomainInfoPtr info); +int xenXMDomainGetState(virConnectPtr conn, + virDomainDefPtr def, int *state, int *reason); char *xenXMDomainGetXMLDesc(virDomainPtr domain, unsigned int flags); -int xenXMDomainSetMemory(virDomainPtr domain, unsigned long memory); -int xenXMDomainSetMaxMemory(virDomainPtr domain, unsigned long memory); -unsigned long long xenXMDomainGetMaxMemory(virDomainPtr domain); +int xenXMDomainSetMemory(virConnectPtr conn, + virDomainDefPtr def, + unsigned long memory); +int xenXMDomainSetMaxMemory(virConnectPtr conn, + virDomainDefPtr def, + unsigned long memory); +unsigned long long xenXMDomainGetMaxMemory(virConnectPtr conn, + virDomainDefPtr def); int xenXMDomainSetVcpus(virDomainPtr domain, unsigned int vcpus); int xenXMDomainSetVcpusFlags(virDomainPtr domain, unsigned int vcpus, unsigned int flags);

On Thu, May 09, 2013 at 01:07:59PM -0600, Jim Fehlig wrote:
Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Introduce use of a virDomainDefPtr in the domain property APIs to simplify introduction of ACL security checks. The virDomainPtr cannot be safely used, since the app may have supplied mis-matching name/uuid/id fields. eg the name points to domain X, while the uuid points to domain Y. Resolving the virDomainPtr to a virDomainDefPtr ensures a consistent name/uuid/id set.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
xenUnifiedDomainGetOSType(virDomainPtr dom) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + char *ret = NULL; + virDomainDefPtr def;
- if (dom->id < 0) { + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + if (def->id < 0) { if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Unable to query OS type for inactive domain")); return NULL; } else { - return xenDaemonDomainGetOSType(dom); + ret = xenHypervisorDomainGetOSType(dom->conn, def);
Should still call xenDaemonDomainGetOSType here since id < 0 right?
} } else { - return xenHypervisorDomainGetOSType(dom); + ret = xenDaemonDomainGetOSType(dom->conn, def);
And call the hypervisor one here when the domain is active.
Yes, dunno how i managed to screw that up :-( Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

From: "Daniel P. Berrange" <berrange@redhat.com> Introduce use of a virDomainDefPtr in the domain save APIs to simplify introduction of ACL security checks. The virDomainPtr cannot be safely used, since the app may have supplied mis-matching name/uuid/id fields. eg the name points to domain X, while the uuid points to domain Y. Resolving the virDomainPtr to a virDomainDefPtr ensures a consistent name/uuid/id set. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/xen/xen_driver.c | 72 ++++++++++++++++++++++++++++++++++++------------- src/xen/xend_internal.c | 23 +++++++++------- src/xen/xend_internal.h | 7 +++-- src/xen/xm_internal.c | 25 ++++++++--------- src/xen/xm_internal.h | 3 ++- 5 files changed, 86 insertions(+), 44 deletions(-) diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 68a86b7..89b038c 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -1038,14 +1038,25 @@ static int xenUnifiedDomainSaveFlags(virDomainPtr dom, const char *to, const char *dxml, unsigned int flags) { + int ret = -1; + virDomainDefPtr def; + virCheckFlags(0, -1); + if (dxml) { virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", _("xml modification unsupported")); return -1; } - return xenDaemonDomainSave(dom, to); + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + ret = xenDaemonDomainSave(dom->conn, def, to); + +cleanup: + virDomainDefFree(def); + return ret; } static int @@ -1055,11 +1066,12 @@ xenUnifiedDomainSave(virDomainPtr dom, const char *to) } static char * -xenUnifiedDomainManagedSavePath(xenUnifiedPrivatePtr priv, virDomainPtr dom) +xenUnifiedDomainManagedSavePath(xenUnifiedPrivatePtr priv, + virDomainDefPtr def) { char *ret; - if (virAsprintf(&ret, "%s/%s.save", priv->saveDir, dom->name) < 0) { + if (virAsprintf(&ret, "%s/%s.save", priv->saveDir, def->name) < 0) { virReportOOMError(); return NULL; } @@ -1072,19 +1084,23 @@ static int xenUnifiedDomainManagedSave(virDomainPtr dom, unsigned int flags) { xenUnifiedPrivatePtr priv = dom->conn->privateData; - char *name; + char *name = NULL; + virDomainDefPtr def = NULL; int ret = -1; virCheckFlags(0, -1); - name = xenUnifiedDomainManagedSavePath(priv, dom); - if (!name) + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + if (!(name = xenUnifiedDomainManagedSavePath(priv, def))) goto cleanup; - ret = xenDaemonDomainSave(dom, name); + ret = xenDaemonDomainSave(dom->conn, def, name); cleanup: VIR_FREE(name); + virDomainDefFree(def); return ret; } @@ -1092,17 +1108,23 @@ static int xenUnifiedDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags) { xenUnifiedPrivatePtr priv = dom->conn->privateData; - char *name; + char *name = NULL; + virDomainDefPtr def = NULL; int ret = -1; virCheckFlags(0, -1); - name = xenUnifiedDomainManagedSavePath(priv, dom); - if (!name) - return ret; + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + if (!(name = xenUnifiedDomainManagedSavePath(priv, def))) + goto cleanup; ret = virFileExists(name); + +cleanup: VIR_FREE(name); + virDomainDefFree(def); return ret; } @@ -1110,16 +1132,21 @@ static int xenUnifiedDomainManagedSaveRemove(virDomainPtr dom, unsigned int flags) { xenUnifiedPrivatePtr priv = dom->conn->privateData; - char *name; + char *name = NULL; + virDomainDefPtr def = NULL; int ret = -1; virCheckFlags(0, -1); - name = xenUnifiedDomainManagedSavePath(priv, dom); - if (!name) - return ret; + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + if (!(name = xenUnifiedDomainManagedSavePath(priv, def))) + goto cleanup; ret = unlink(name); + +cleanup: VIR_FREE(name); return ret; } @@ -1496,12 +1523,15 @@ xenUnifiedDomainCreateWithFlags(virDomainPtr dom, unsigned int flags) { xenUnifiedPrivatePtr priv = dom->conn->privateData; int ret = -1; + virDomainDefPtr def = NULL; char *name = NULL; virCheckFlags(0, -1); - name = xenUnifiedDomainManagedSavePath(priv, dom); - if (!name) + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + if (!(name = xenUnifiedDomainManagedSavePath(priv, def))) goto cleanup; if (virFileExists(name)) { @@ -1512,11 +1542,15 @@ xenUnifiedDomainCreateWithFlags(virDomainPtr dom, unsigned int flags) } if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - ret = xenXMDomainCreate(dom); + ret = xenXMDomainCreate(dom->conn, def); else - ret = xenDaemonDomainCreate(dom); + ret = xenDaemonDomainCreate(dom->conn, def); + + if (ret >= 0) + dom->id = def->id; cleanup: + virDomainDefFree(def); VIR_FREE(name); return ret; } diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index c10567c..9555b33 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -1413,22 +1413,24 @@ xenDaemonDomainGetOSType(virConnectPtr conn, * Returns 0 in case of success, -1 (with errno) in case of error. */ int -xenDaemonDomainSave(virDomainPtr domain, const char *filename) +xenDaemonDomainSave(virConnectPtr conn, + virDomainDefPtr def, + const char *filename) { - if (domain->id < 0) { + if (def->id < 0) { virReportError(VIR_ERR_OPERATION_INVALID, - _("Domain %s isn't running."), domain->name); + _("Domain %s isn't running."), def->name); return -1; } /* We can't save the state of Domain-0, that would mean stopping it too */ - if (domain->id == 0) { + if (def->id == 0) { virReportError(VIR_ERR_INVALID_ARG, "%s", _("Cannot save host domain")); return -1; } - return xend_op(domain->conn, domain->name, "op", "save", "file", filename, NULL); + return xend_op(conn, def->name, "op", "save", "file", filename, NULL); } /** @@ -2862,17 +2864,18 @@ xenDaemonDomainDefineXML(virConnectPtr conn, const char *xmlDesc) return NULL; } int -xenDaemonDomainCreate(virDomainPtr domain) +xenDaemonDomainCreate(virConnectPtr conn, + virDomainDefPtr def) { int ret; - ret = xend_op(domain->conn, domain->name, "op", "start", NULL); + ret = xend_op(conn, def->name, "op", "start", NULL); if (ret == 0) { - int id = xenDaemonDomainLookupByName_ids(domain->conn, domain->name, - domain->uuid); + int id = xenDaemonDomainLookupByName_ids(conn, def->name, + def->uuid); if (id > 0) - domain->id = id; + def->id = id; } return ret; diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h index 87e0a0f..01d321f 100644 --- a/src/xen/xend_internal.h +++ b/src/xen/xend_internal.h @@ -92,7 +92,9 @@ int xenDaemonDomainResume(virConnectPtr conn, virDomainDefPtr def); int xenDaemonDomainShutdown(virConnectPtr conn, virDomainDefPtr def); int xenDaemonDomainReboot(virConnectPtr conn, virDomainDefPtr def); int xenDaemonDomainDestroy(virConnectPtr conn, virDomainDefPtr def); -int xenDaemonDomainSave(virDomainPtr domain, const char *filename); +int xenDaemonDomainSave(virConnectPtr conn, + virDomainDefPtr def, + const char *filename); int xenDaemonDomainCoreDump(virDomainPtr domain, const char *filename, unsigned int flags); int xenDaemonDomainRestore(virConnectPtr conn, const char *filename); @@ -131,7 +133,8 @@ int xenDaemonDetachDeviceFlags(virDomainPtr domain, unsigned int flags); virDomainPtr xenDaemonDomainDefineXML(virConnectPtr xend, const char *sexpr); -int xenDaemonDomainCreate(virDomainPtr domain); +int xenDaemonDomainCreate(virConnectPtr conn, + virDomainDefPtr def); int xenDaemonDomainUndefine(virDomainPtr domain); int xenDaemonDomainSetVcpus (virDomainPtr domain, diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c index ce44e39..6c884d9 100644 --- a/src/xen/xm_internal.c +++ b/src/xen/xm_internal.c @@ -893,48 +893,49 @@ cleanup: * Start a domain from an existing defined config file */ int -xenXMDomainCreate(virDomainPtr domain) +xenXMDomainCreate(virConnectPtr conn, + virDomainDefPtr def) { char *sexpr; int ret = -1; - xenUnifiedPrivatePtr priv= domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; const char *filename; xenXMConfCachePtr entry = NULL; xenUnifiedLock(priv); - if (!(filename = virHashLookup(priv->nameConfigMap, domain->name))) + if (!(filename = virHashLookup(priv->nameConfigMap, def->name))) goto error; if (!(entry = virHashLookup(priv->configCache, filename))) goto error; - if (!(sexpr = xenFormatSxpr(domain->conn, entry->def, priv->xendConfigVersion))) + if (!(sexpr = xenFormatSxpr(conn, entry->def, priv->xendConfigVersion))) goto error; - ret = xenDaemonDomainCreateXML(domain->conn, sexpr); + ret = xenDaemonDomainCreateXML(conn, sexpr); VIR_FREE(sexpr); if (ret != 0) goto error; - if ((ret = xenDaemonDomainLookupByName_ids(domain->conn, domain->name, + if ((ret = xenDaemonDomainLookupByName_ids(conn, def->name, entry->def->uuid)) < 0) goto error; - domain->id = ret; + def->id = ret; - if (xend_wait_for_devices(domain->conn, domain->name) < 0) + if (xend_wait_for_devices(conn, def->name) < 0) goto error; - if (xenDaemonDomainResume(domain->conn, entry->def) < 0) + if (xenDaemonDomainResume(conn, entry->def) < 0) goto error; xenUnifiedUnlock(priv); return 0; error: - if (domain->id != -1 && entry) { - xenDaemonDomainDestroy(domain->conn, entry->def); - domain->id = -1; + if (def->id != -1 && entry) { + xenDaemonDomainDestroy(conn, entry->def); + def->id = -1; } xenUnifiedUnlock(priv); return -1; diff --git a/src/xen/xm_internal.h b/src/xen/xm_internal.h index 0ae32bc..0521625 100644 --- a/src/xen/xm_internal.h +++ b/src/xen/xm_internal.h @@ -65,7 +65,8 @@ virDomainDefPtr xenXMDomainLookupByUUID(virConnectPtr conn, const unsigned char int xenXMListDefinedDomains(virConnectPtr conn, char ** const names, int maxnames); int xenXMNumOfDefinedDomains(virConnectPtr conn); -int xenXMDomainCreate(virDomainPtr domain); +int xenXMDomainCreate(virConnectPtr conn, + virDomainDefPtr def); virDomainPtr xenXMDomainDefineXML(virConnectPtr con, const char *xml); int xenXMDomainUndefine(virDomainPtr domain); -- 1.8.1.4

Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Introduce use of a virDomainDefPtr in the domain save APIs to simplify introduction of ACL security checks. The virDomainPtr cannot be safely used, since the app may have supplied mis-matching name/uuid/id fields. eg the name points to domain X, while the uuid points to domain Y. Resolving the virDomainPtr to a virDomainDefPtr ensures a consistent name/uuid/id set.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/xen/xen_driver.c | 72 ++++++++++++++++++++++++++++++++++++------------- src/xen/xend_internal.c | 23 +++++++++------- src/xen/xend_internal.h | 7 +++-- src/xen/xm_internal.c | 25 ++++++++--------- src/xen/xm_internal.h | 3 ++- 5 files changed, 86 insertions(+), 44 deletions(-)
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 68a86b7..89b038c 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -1038,14 +1038,25 @@ static int xenUnifiedDomainSaveFlags(virDomainPtr dom, const char *to, const char *dxml, unsigned int flags) { + int ret = -1; + virDomainDefPtr def; + virCheckFlags(0, -1); + if (dxml) { virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", _("xml modification unsupported")); return -1; }
- return xenDaemonDomainSave(dom, to); + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + ret = xenDaemonDomainSave(dom->conn, def, to); + +cleanup: + virDomainDefFree(def); + return ret; }
static int @@ -1055,11 +1066,12 @@ xenUnifiedDomainSave(virDomainPtr dom, const char *to) }
static char * -xenUnifiedDomainManagedSavePath(xenUnifiedPrivatePtr priv, virDomainPtr dom) +xenUnifiedDomainManagedSavePath(xenUnifiedPrivatePtr priv, + virDomainDefPtr def)
This still fits on one line.
{ char *ret;
- if (virAsprintf(&ret, "%s/%s.save", priv->saveDir, dom->name) < 0) { + if (virAsprintf(&ret, "%s/%s.save", priv->saveDir, def->name) < 0) { virReportOOMError(); return NULL; } @@ -1072,19 +1084,23 @@ static int xenUnifiedDomainManagedSave(virDomainPtr dom, unsigned int flags) { xenUnifiedPrivatePtr priv = dom->conn->privateData; - char *name; + char *name = NULL; + virDomainDefPtr def = NULL; int ret = -1;
virCheckFlags(0, -1);
- name = xenUnifiedDomainManagedSavePath(priv, dom); - if (!name) + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + if (!(name = xenUnifiedDomainManagedSavePath(priv, def))) goto cleanup;
- ret = xenDaemonDomainSave(dom, name); + ret = xenDaemonDomainSave(dom->conn, def, name);
cleanup: VIR_FREE(name); + virDomainDefFree(def); return ret; }
@@ -1092,17 +1108,23 @@ static int xenUnifiedDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags) { xenUnifiedPrivatePtr priv = dom->conn->privateData; - char *name; + char *name = NULL; + virDomainDefPtr def = NULL; int ret = -1;
virCheckFlags(0, -1);
- name = xenUnifiedDomainManagedSavePath(priv, dom); - if (!name) - return ret; + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + if (!(name = xenUnifiedDomainManagedSavePath(priv, def))) + goto cleanup;
ret = virFileExists(name); + +cleanup: VIR_FREE(name); + virDomainDefFree(def); return ret; }
@@ -1110,16 +1132,21 @@ static int xenUnifiedDomainManagedSaveRemove(virDomainPtr dom, unsigned int flags) { xenUnifiedPrivatePtr priv = dom->conn->privateData; - char *name; + char *name = NULL; + virDomainDefPtr def = NULL; int ret = -1;
virCheckFlags(0, -1);
- name = xenUnifiedDomainManagedSavePath(priv, dom); - if (!name) - return ret; + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + if (!(name = xenUnifiedDomainManagedSavePath(priv, def))) + goto cleanup;
ret = unlink(name); + +cleanup: VIR_FREE(name); return ret; } @@ -1496,12 +1523,15 @@ xenUnifiedDomainCreateWithFlags(virDomainPtr dom, unsigned int flags) { xenUnifiedPrivatePtr priv = dom->conn->privateData; int ret = -1; + virDomainDefPtr def = NULL; char *name = NULL;
virCheckFlags(0, -1);
- name = xenUnifiedDomainManagedSavePath(priv, dom); - if (!name) + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + if (!(name = xenUnifiedDomainManagedSavePath(priv, def))) goto cleanup;
if (virFileExists(name)) { @@ -1512,11 +1542,15 @@ xenUnifiedDomainCreateWithFlags(virDomainPtr dom, unsigned int flags) }
if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - ret = xenXMDomainCreate(dom); + ret = xenXMDomainCreate(dom->conn, def); else - ret = xenDaemonDomainCreate(dom); + ret = xenDaemonDomainCreate(dom->conn, def); + + if (ret >= 0) + dom->id = def->id;
cleanup: + virDomainDefFree(def); VIR_FREE(name); return ret; } diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index c10567c..9555b33 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -1413,22 +1413,24 @@ xenDaemonDomainGetOSType(virConnectPtr conn, * Returns 0 in case of success, -1 (with errno) in case of error. */ int -xenDaemonDomainSave(virDomainPtr domain, const char *filename) +xenDaemonDomainSave(virConnectPtr conn, + virDomainDefPtr def, + const char *filename) { - if (domain->id < 0) { + if (def->id < 0) { virReportError(VIR_ERR_OPERATION_INVALID, - _("Domain %s isn't running."), domain->name); + _("Domain %s isn't running."), def->name); return -1; }
/* We can't save the state of Domain-0, that would mean stopping it too */ - if (domain->id == 0) { + if (def->id == 0) { virReportError(VIR_ERR_INVALID_ARG, "%s", _("Cannot save host domain")); return -1; }
- return xend_op(domain->conn, domain->name, "op", "save", "file", filename, NULL); + return xend_op(conn, def->name, "op", "save", "file", filename, NULL); }
/** @@ -2862,17 +2864,18 @@ xenDaemonDomainDefineXML(virConnectPtr conn, const char *xmlDesc) return NULL; } int -xenDaemonDomainCreate(virDomainPtr domain) +xenDaemonDomainCreate(virConnectPtr conn, + virDomainDefPtr def)
Fits on one line.
{ int ret;
- ret = xend_op(domain->conn, domain->name, "op", "start", NULL); + ret = xend_op(conn, def->name, "op", "start", NULL);
if (ret == 0) { - int id = xenDaemonDomainLookupByName_ids(domain->conn, domain->name, - domain->uuid); + int id = xenDaemonDomainLookupByName_ids(conn, def->name, + def->uuid);
Fits on one line now.
if (id > 0) - domain->id = id; + def->id = id; }
return ret; diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h index 87e0a0f..01d321f 100644 --- a/src/xen/xend_internal.h +++ b/src/xen/xend_internal.h @@ -92,7 +92,9 @@ int xenDaemonDomainResume(virConnectPtr conn, virDomainDefPtr def); int xenDaemonDomainShutdown(virConnectPtr conn, virDomainDefPtr def); int xenDaemonDomainReboot(virConnectPtr conn, virDomainDefPtr def); int xenDaemonDomainDestroy(virConnectPtr conn, virDomainDefPtr def); -int xenDaemonDomainSave(virDomainPtr domain, const char *filename); +int xenDaemonDomainSave(virConnectPtr conn, + virDomainDefPtr def, + const char *filename); int xenDaemonDomainCoreDump(virDomainPtr domain, const char *filename, unsigned int flags); int xenDaemonDomainRestore(virConnectPtr conn, const char *filename); @@ -131,7 +133,8 @@ int xenDaemonDetachDeviceFlags(virDomainPtr domain, unsigned int flags);
virDomainPtr xenDaemonDomainDefineXML(virConnectPtr xend, const char *sexpr); -int xenDaemonDomainCreate(virDomainPtr domain); +int xenDaemonDomainCreate(virConnectPtr conn, + virDomainDefPtr def);
Still fits on one line.
int xenDaemonDomainUndefine(virDomainPtr domain);
int xenDaemonDomainSetVcpus (virDomainPtr domain, diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c index ce44e39..6c884d9 100644 --- a/src/xen/xm_internal.c +++ b/src/xen/xm_internal.c @@ -893,48 +893,49 @@ cleanup: * Start a domain from an existing defined config file */ int -xenXMDomainCreate(virDomainPtr domain) +xenXMDomainCreate(virConnectPtr conn, + virDomainDefPtr def)
And again.
{ char *sexpr; int ret = -1; - xenUnifiedPrivatePtr priv= domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; const char *filename; xenXMConfCachePtr entry = NULL;
xenUnifiedLock(priv);
- if (!(filename = virHashLookup(priv->nameConfigMap, domain->name))) + if (!(filename = virHashLookup(priv->nameConfigMap, def->name))) goto error;
if (!(entry = virHashLookup(priv->configCache, filename))) goto error;
- if (!(sexpr = xenFormatSxpr(domain->conn, entry->def, priv->xendConfigVersion))) + if (!(sexpr = xenFormatSxpr(conn, entry->def, priv->xendConfigVersion))) goto error;
- ret = xenDaemonDomainCreateXML(domain->conn, sexpr); + ret = xenDaemonDomainCreateXML(conn, sexpr); VIR_FREE(sexpr); if (ret != 0) goto error;
- if ((ret = xenDaemonDomainLookupByName_ids(domain->conn, domain->name, + if ((ret = xenDaemonDomainLookupByName_ids(conn, def->name, entry->def->uuid)) < 0) goto error; - domain->id = ret; + def->id = ret;
- if (xend_wait_for_devices(domain->conn, domain->name) < 0) + if (xend_wait_for_devices(conn, def->name) < 0) goto error;
- if (xenDaemonDomainResume(domain->conn, entry->def) < 0) + if (xenDaemonDomainResume(conn, entry->def) < 0) goto error;
xenUnifiedUnlock(priv); return 0;
error: - if (domain->id != -1 && entry) { - xenDaemonDomainDestroy(domain->conn, entry->def); - domain->id = -1; + if (def->id != -1 && entry) { + xenDaemonDomainDestroy(conn, entry->def); + def->id = -1; } xenUnifiedUnlock(priv); return -1; diff --git a/src/xen/xm_internal.h b/src/xen/xm_internal.h index 0ae32bc..0521625 100644 --- a/src/xen/xm_internal.h +++ b/src/xen/xm_internal.h @@ -65,7 +65,8 @@ virDomainDefPtr xenXMDomainLookupByUUID(virConnectPtr conn, const unsigned char int xenXMListDefinedDomains(virConnectPtr conn, char ** const names, int maxnames); int xenXMNumOfDefinedDomains(virConnectPtr conn);
-int xenXMDomainCreate(virDomainPtr domain); +int xenXMDomainCreate(virConnectPtr conn, + virDomainDefPtr def);
Fits on one line. No issues found testing this patch. ACK. Regards, Jim
virDomainPtr xenXMDomainDefineXML(virConnectPtr con, const char *xml); int xenXMDomainUndefine(virDomainPtr domain);

From: "Daniel P. Berrange" <berrange@redhat.com> Introduce use of a virDomainDefPtr in the domain migrate & start APIs to simplify introduction of ACL security checks. The virDomainPtr cannot be safely used, since the app may have supplied mis-matching name/uuid/id fields. eg the name points to domain X, while the uuid points to domain Y. Resolving the virDomainPtr to a virDomainDefPtr ensures a consistent name/uuid/id set. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/xen/xen_driver.c | 127 ++++++++++++++++++++++++++++++++---------------- src/xen/xend_internal.c | 71 +++++++++------------------ src/xen/xend_internal.h | 22 ++++++--- src/xen/xm_internal.c | 49 ++++++++----------- src/xen/xm_internal.h | 7 +-- 5 files changed, 148 insertions(+), 128 deletions(-) diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 89b038c..8b7dec9 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -1294,18 +1294,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; } @@ -1438,10 +1451,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 @@ -1452,45 +1476,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); - - return dom; - + ret = virGetDomain(dconn, minidef->name, minidef->uuid); + if (ret) + ret->id = minidef->id; -error: - virDomainFree(dom); - - VIR_FREE(domain_xml); - - return NULL; +cleanup: + virDomainDefFree(def); + virDomainDefFree(minidef); + return ret; } static int @@ -1565,23 +1581,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 9555b33..77c4dec 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -1604,7 +1604,6 @@ 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. @@ -1612,27 +1611,15 @@ cleanup: * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of error. * the caller must free() the returned value. */ -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); } @@ -2657,7 +2644,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, @@ -2801,7 +2789,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, @@ -2814,34 +2802,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); @@ -2849,20 +2827,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) @@ -2882,9 +2855,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 01d321f..1284db3 100644 --- a/src/xen/xend_internal.h +++ b/src/xen/xend_internal.h @@ -111,8 +111,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); @@ -132,10 +133,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); @@ -163,8 +166,15 @@ int xenDaemonDomainSetAutostart (virDomainPtr domain, virDomainPtr xenDaemonCreateXML(virConnectPtr conn, const char *xmlDesc); 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 6c884d9..79f773d 100644 --- a/src/xen/xm_internal.c +++ b/src/xen/xm_internal.c @@ -500,28 +500,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); @@ -945,13 +946,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; @@ -960,14 +959,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))) @@ -1061,10 +1053,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); @@ -1072,25 +1063,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))) @@ -1100,7 +1091,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 0521625..5a434b9 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); -- 1.8.1.4

I finally have some time to continue reviewing this series... Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Introduce use of a virDomainDefPtr in the domain migrate & start APIs to simplify introduction of ACL security checks.
Not really the 'start' API, but GetXMLDesc, Define, and Undefine. Should those be part of the lifecycle changes made in patch 2?
The virDomainPtr cannot be safely used, since the app may have supplied mis-matching name/uuid/id fields. eg the name points to domain X, while the uuid points to domain Y. Resolving the virDomainPtr to a virDomainDefPtr ensures a consistent name/uuid/id set.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/xen/xen_driver.c | 127 ++++++++++++++++++++++++++++++++---------------- src/xen/xend_internal.c | 71 +++++++++------------------ src/xen/xend_internal.h | 22 ++++++--- src/xen/xm_internal.c | 49 ++++++++----------- src/xen/xm_internal.h | 7 +-- 5 files changed, 148 insertions(+), 128 deletions(-)
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 89b038c..8b7dec9 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -1294,18 +1294,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; }
@@ -1438,10 +1451,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 @@ -1452,45 +1476,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); - - return dom; - + ret = virGetDomain(dconn, minidef->name, minidef->uuid); + if (ret) + ret->id = minidef->id;
-error: - virDomainFree(dom); - - VIR_FREE(domain_xml); - - return NULL; +cleanup: + virDomainDefFree(def); + virDomainDefFree(minidef); + return ret; }
static int @@ -1565,23 +1581,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 9555b33..77c4dec 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -1604,7 +1604,6 @@ 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. @@ -1612,27 +1611,15 @@ cleanup: * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of error. * the caller must free() the returned value. */
Comments for this function need updated, e.g. the domain parameter no longer exists and it now returns a virtDomainDefPtr.
-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); }
@@ -2657,7 +2644,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, @@ -2801,7 +2789,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, @@ -2814,34 +2802,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)
xenDaemonDomainGetXMLDesc and xenDaemonDomainDefineXML are poorly named now that they don't return or accept XML, but that's a super nit :).
{ - 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); @@ -2849,20 +2827,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) @@ -2882,9 +2855,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 01d321f..1284db3 100644 --- a/src/xen/xend_internal.h +++ b/src/xen/xend_internal.h @@ -111,8 +111,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); @@ -132,10 +133,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);
These still fit on one line, but this whole files has inconsistent use of whitespace.
int xenDaemonDomainSetVcpus (virDomainPtr domain, unsigned int vcpus); @@ -163,8 +166,15 @@ int xenDaemonDomainSetAutostart (virDomainPtr domain, virDomainPtr xenDaemonCreateXML(virConnectPtr conn, const char *xmlDesc); 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 6c884d9..79f773d 100644 --- a/src/xen/xm_internal.c +++ b/src/xen/xm_internal.c @@ -500,28 +500,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)
Still fits on one line.
{ - 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); @@ -945,13 +946,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; @@ -960,14 +959,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))) @@ -1061,10 +1053,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); @@ -1072,25 +1063,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)
Still fits on one line.
{ - 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))) @@ -1100,7 +1091,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 0521625..5a434b9 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);
This still squeezes into one line too. Regards, Jim
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);

On Mon, May 20, 2013 at 11:40:34AM -0600, Jim Fehlig wrote:
I finally have some time to continue reviewing this series...
Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Introduce use of a virDomainDefPtr in the domain migrate & start APIs to simplify introduction of ACL security checks.
Not really the 'start' API, but GetXMLDesc, Define, and Undefine. Should those be part of the lifecycle changes made in patch 2?
Opps bad description. I tried to make each patch as small as possible. So where I grouped several methods together, I only did it because they were mutually dependent wrt the refactoring. Will fix the description of this commit.
@@ -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);
This still squeezes into one line too.
As you've probably seen by now, I've preferred to split the lines when there are > 1 parameter in the method, even if it would technically fit on one line. Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On 05/09/2013 08:59 AM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
[...snip...]
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 89b038c..8b7dec9 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -1294,18 +1294,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; }
@@ -1438,10 +1451,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 @@ -1452,45 +1476,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); - - return dom; - + ret = virGetDomain(dconn, minidef->name, minidef->uuid); + if (ret) + ret->id = minidef->id;
-error: - virDomainFree(dom); - - VIR_FREE(domain_xml); - - return NULL; +cleanup: + virDomainDefFree(def); + virDomainDefFree(minidef); + return ret; }
static int @@ -1565,23 +1581,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; +
Coverity complains 1666 (7) Event var_deref_op: Dereferencing null pointer "def". Also see events: [assign_zero] Because of : 1660 goto cleanup; (4) Event assign_zero: Assigning: "def" = "NULL". Also see events: [var_deref_op] 1661 def = NULL; /* XM driver owns it now */ (5) Event if_fallthrough: Falling through to end of if statement 1662 } else {
+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 [...snip...]

From: "Daniel P. Berrange" <berrange@redhat.com> Introduce use of a virDomainDefPtr in the domain VCPU APIs to simplify introduction of ACL security checks. The virDomainPtr cannot be safely used, since the app may have supplied mis-matching name/uuid/id fields. eg the name points to domain X, while the uuid points to domain Y. Resolving the virDomainPtr to a virDomainDefPtr ensures a consistent name/uuid/id set. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/xen/xen_driver.c | 84 ++++++++++++++++++++++++++++++++++++++++-------- src/xen/xen_hypervisor.c | 42 ++++++++++++------------ src/xen/xen_hypervisor.h | 9 ++++-- src/xen/xend_internal.c | 81 ++++++++++++++++++++++++++-------------------- src/xen/xend_internal.h | 17 ++++++---- src/xen/xm_internal.c | 30 +++++++++-------- src/xen/xm_internal.h | 19 ++++++++--- 7 files changed, 187 insertions(+), 95 deletions(-) diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 8b7dec9..04cb69d 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 @@ -1182,6 +1201,8 @@ xenUnifiedDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus, unsigned int flags) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + virDomainDefPtr def = NULL; + int ret = -1; virCheckFlags(VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG | @@ -1202,13 +1223,20 @@ xenUnifiedDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus, return -1; } + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + /* Try non-hypervisor methods first, then hypervisor direct method * as a last resort. */ if (dom->id < 0 && priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainSetVcpusFlags(dom, nvcpus, flags); + ret = xenXMDomainSetVcpusFlags(dom->conn, def, nvcpus, flags); else - return xenDaemonDomainSetVcpusFlags(dom, nvcpus, flags); + ret = xenDaemonDomainSetVcpusFlags(dom->conn, def, nvcpus, flags); + +cleanup: + virDomainDefFree(def); + return ret; } static int @@ -1231,15 +1259,24 @@ xenUnifiedDomainPinVcpu(virDomainPtr dom, unsigned int vcpu, unsigned char *cpumap, int maplen) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + virDomainDefPtr def = NULL; + int ret = -1; + + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; if (dom->id < 0) { if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainPinVcpu(dom, vcpu, cpumap, maplen); + ret = xenXMDomainPinVcpu(dom->conn, def, vcpu, cpumap, maplen); else - return xenDaemonDomainPinVcpu(dom, vcpu, cpumap, maplen); + ret = xenDaemonDomainPinVcpu(dom->conn, def, vcpu, cpumap, maplen); } else { - return xenHypervisorPinVcpu(dom, vcpu, cpumap, maplen); + ret = xenHypervisorPinVcpu(dom->conn, def, vcpu, cpumap, maplen); } + +cleanup: + virDomainDefFree(def); + return ret; } static int @@ -1248,39 +1285,58 @@ xenUnifiedDomainGetVcpus(virDomainPtr dom, unsigned char *cpumaps, int maplen) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + virDomainDefPtr def = NULL; + int ret = -1; + + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + if (dom->id < 0) { if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Cannot get VCPUs of inactive domain")); - return -1; + goto cleanup; } else { - return xenDaemonDomainGetVcpus(dom, info, maxinfo, cpumaps, maplen); + ret = xenDaemonDomainGetVcpus(dom->conn, def, info, maxinfo, cpumaps, maplen); } } else { - return xenHypervisorGetVcpus(dom, info, maxinfo, cpumaps, maplen); + ret = xenHypervisorGetVcpus(dom->conn, def, info, maxinfo, cpumaps, maplen); } + +cleanup: + virDomainDefFree(def); + return ret; } static int xenUnifiedDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + virDomainDefPtr def = NULL; + int ret = -1; virCheckFlags(VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG | VIR_DOMAIN_VCPU_MAXIMUM, -1); + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + if (dom->id < 0) { if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainGetVcpusFlags(dom, flags); + ret = xenXMDomainGetVcpusFlags(dom->conn, def, flags); else - return xenDaemonDomainGetVcpusFlags(dom, flags); + ret = xenDaemonDomainGetVcpusFlags(dom->conn, def, flags); } else { if (flags == (VIR_DOMAIN_VCPU_CONFIG | VIR_DOMAIN_VCPU_MAXIMUM)) - return xenHypervisorGetVcpuMax(dom); + ret = xenHypervisorGetVcpuMax(dom->conn, def); else - return xenDaemonDomainGetVcpusFlags(dom, flags); + ret = xenDaemonDomainGetVcpusFlags(dom->conn, def, flags); } + +cleanup: + virDomainDefFree(def); + return ret; } static int diff --git a/src/xen/xen_hypervisor.c b/src/xen/xen_hypervisor.c index 423ce85..b97b329 100644 --- a/src/xen/xen_hypervisor.c +++ b/src/xen/xen_hypervisor.c @@ -2931,16 +2931,16 @@ xenHypervisorSetMaxMemory(virConnectPtr conn, */ int -xenHypervisorPinVcpu(virDomainPtr domain, unsigned int vcpu, - unsigned char *cpumap, int maplen) +xenHypervisorPinVcpu(virConnectPtr conn, + virDomainDefPtr def, + unsigned int vcpu, + unsigned char *cpumap, + int maplen) { int ret; - xenUnifiedPrivatePtr priv = domain->conn->privateData; - - if (domain->id < 0) - return -1; + xenUnifiedPrivatePtr priv = conn->privateData; - ret = virXen_setvcpumap(priv->handle, domain->id, vcpu, + ret = virXen_setvcpumap(priv->handle, def->id, vcpu, cpumap, maplen); if (ret < 0) return -1; @@ -2967,7 +2967,8 @@ xenHypervisorPinVcpu(virDomainPtr domain, unsigned int vcpu, * Returns the number of info filled in case of success, -1 in case of failure. */ int -xenHypervisorGetVcpus(virDomainPtr domain, +xenHypervisorGetVcpus(virConnectPtr conn, + virDomainDefPtr def, virVcpuInfoPtr info, int maxinfo, unsigned char *cpumaps, @@ -2975,22 +2976,22 @@ xenHypervisorGetVcpus(virDomainPtr domain, { xen_getdomaininfo dominfo; int ret; - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; virVcpuInfoPtr ipt; int nbinfo, i; - if (domain->id < 0 || sizeof(cpumap_t) & 7) { + if (sizeof(cpumap_t) & 7) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("domain shut off or invalid")); + _("invalid cpumap_t size")); return -1; } /* first get the number of virtual CPUs in this domain */ XEN_GETDOMAININFO_CLEAR(dominfo); - ret = virXen_getdomaininfo(priv->handle, domain->id, + ret = virXen_getdomaininfo(priv->handle, def->id, &dominfo); - if ((ret < 0) || (XEN_GETDOMAININFO_DOMAIN(dominfo) != domain->id)) { + if ((ret < 0) || (XEN_GETDOMAININFO_DOMAIN(dominfo) != def->id)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot get domain details")); return -1; @@ -3003,7 +3004,7 @@ xenHypervisorGetVcpus(virDomainPtr domain, for (i = 0, ipt = info; i < nbinfo; i++, ipt++) { if ((cpumaps != NULL) && (i < maxinfo)) { - ret = virXen_getvcpusinfo(priv->handle, domain->id, i, + ret = virXen_getvcpusinfo(priv->handle, def->id, i, ipt, (unsigned char *)VIR_GET_CPUMAP(cpumaps, maplen, i), maplen); @@ -3013,7 +3014,7 @@ xenHypervisorGetVcpus(virDomainPtr domain, return -1; } } else { - ret = virXen_getvcpusinfo(priv->handle, domain->id, i, + ret = virXen_getvcpusinfo(priv->handle, def->id, i, ipt, NULL, 0); if (ret < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -3034,22 +3035,23 @@ xenHypervisorGetVcpus(virDomainPtr domain, * the maximum number of virtual CPUs the guest was booted with. */ int -xenHypervisorGetVcpuMax(virDomainPtr domain) +xenHypervisorGetVcpuMax(virConnectPtr conn, + virDomainDefPtr def) { xen_getdomaininfo dominfo; int ret; int maxcpu; - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; /* inactive domain */ - if (domain->id < 0) { + if (def->id < 0) { maxcpu = MAX_VIRT_CPUS; } else { XEN_GETDOMAININFO_CLEAR(dominfo); - ret = virXen_getdomaininfo(priv->handle, domain->id, + ret = virXen_getdomaininfo(priv->handle, def->id, &dominfo); - if ((ret < 0) || (XEN_GETDOMAININFO_DOMAIN(dominfo) != domain->id)) + if ((ret < 0) || (XEN_GETDOMAININFO_DOMAIN(dominfo) != def->id)) return -1; maxcpu = XEN_GETDOMAININFO_MAXCPUID(dominfo) + 1; } diff --git a/src/xen/xen_hypervisor.h b/src/xen/xen_hypervisor.h index 9ee1f13..1cf1e14 100644 --- a/src/xen/xen_hypervisor.h +++ b/src/xen/xen_hypervisor.h @@ -89,18 +89,21 @@ int xenHypervisorSetMaxMemory (virConnectPtr conn, ATTRIBUTE_NONNULL (1); int xenHypervisorCheckID (virConnectPtr conn, int id); -int xenHypervisorPinVcpu (virDomainPtr domain, +int xenHypervisorPinVcpu (virConnectPtr conn, + virDomainDefPtr def, unsigned int vcpu, unsigned char *cpumap, int maplen) ATTRIBUTE_NONNULL (1); -int xenHypervisorGetVcpus (virDomainPtr domain, +int xenHypervisorGetVcpus (virConnectPtr conn, + virDomainDefPtr def, virVcpuInfoPtr info, int maxinfo, unsigned char *cpumaps, int maplen) ATTRIBUTE_NONNULL (1); -int xenHypervisorGetVcpuMax (virDomainPtr domain) +int xenHypervisorGetVcpuMax (virConnectPtr conn, + virDomainDefPtr def) ATTRIBUTE_NONNULL (1); char * xenHypervisorGetSchedulerType (virDomainPtr domain, diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index 77c4dec..75c980c 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -1772,7 +1772,8 @@ xenDaemonNodeGetTopology(virConnectPtr conn, virCapsPtr caps) * Returns 0 on success, -1 if an error message was issued */ int -xenDaemonDomainSetVcpusFlags(virDomainPtr domain, +xenDaemonDomainSetVcpusFlags(virConnectPtr conn, + virDomainDefPtr def, unsigned int vcpus, unsigned int flags) { @@ -1788,7 +1789,7 @@ xenDaemonDomainSetVcpusFlags(virDomainPtr domain, return -1; } - if (domain->id < 0) { + if (def->id < 0) { if (flags & VIR_DOMAIN_VCPU_LIVE) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("domain not running")); @@ -1806,7 +1807,7 @@ xenDaemonDomainSetVcpusFlags(virDomainPtr domain, /* Unfortunately, xend_op does not validate whether this exceeds * the maximum. */ flags |= VIR_DOMAIN_VCPU_MAXIMUM; - if ((max = xenDaemonDomainGetVcpusFlags(domain, flags)) < 0) { + if ((max = xenDaemonDomainGetVcpusFlags(conn, def, flags)) < 0) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("could not determine max vcpus for the domain")); return -1; @@ -1819,7 +1820,7 @@ xenDaemonDomainSetVcpusFlags(virDomainPtr domain, } snprintf(buf, sizeof(buf), "%d", vcpus); - return xend_op(domain->conn, domain->name, "op", "set_vcpus", "vcpus", + return xend_op(conn, def->name, "op", "set_vcpus", "vcpus", buf, NULL); } @@ -1840,14 +1841,15 @@ xenDaemonDomainSetVcpusFlags(virDomainPtr domain, * Returns 0 for success; -1 (with errno) on error */ int -xenDaemonDomainPinVcpu(virDomainPtr domain, +xenDaemonDomainPinVcpu(virConnectPtr conn, + virDomainDefPtr minidef, unsigned int vcpu, unsigned char *cpumap, int maplen) { char buf[VIR_UUID_BUFLEN], mapstr[sizeof(cpumap_t) * 64]; int i, j, ret; - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; virDomainDefPtr def = NULL; if (maplen > (int)sizeof(cpumap_t)) { @@ -1875,12 +1877,12 @@ xenDaemonDomainPinVcpu(virDomainPtr domain, snprintf(buf, sizeof(buf), "%d", vcpu); - ret = xend_op(domain->conn, domain->name, "op", "pincpu", "vcpu", buf, + ret = xend_op(conn, minidef->name, "op", "pincpu", "vcpu", buf, "cpumap", mapstr, NULL); - if (!(def = xenDaemonDomainFetch(domain->conn, - domain->id, - domain->name, + if (!(def = xenDaemonDomainFetch(conn, + minidef->id, + minidef->name, NULL))) goto cleanup; @@ -1922,7 +1924,9 @@ cleanup: */ int -xenDaemonDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags) +xenDaemonDomainGetVcpusFlags(virConnectPtr conn, + virDomainDefPtr def, + unsigned int flags) { struct sexpr *root; int ret; @@ -1931,13 +1935,13 @@ xenDaemonDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags) VIR_DOMAIN_VCPU_CONFIG | VIR_DOMAIN_VCPU_MAXIMUM, -1); - if (domain->id < 0 && (flags & VIR_DOMAIN_VCPU_LIVE)) { + if (def->id < 0 && (flags & VIR_DOMAIN_VCPU_LIVE)) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("domain not active")); return -1; } - root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name); + root = sexpr_get(conn, "/xend/domain/%s?detail=1", def->name); if (root == NULL) return -1; @@ -1973,7 +1977,8 @@ xenDaemonDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags) * Returns the number of info filled in case of success, -1 in case of failure. */ int -xenDaemonDomainGetVcpus(virDomainPtr domain, +xenDaemonDomainGetVcpus(virConnectPtr conn, + virDomainDefPtr def, virVcpuInfoPtr info, int maxinfo, unsigned char *cpumaps, @@ -1985,7 +1990,7 @@ xenDaemonDomainGetVcpus(virDomainPtr domain, unsigned char *cpumap; int vcpu, cpu; - root = sexpr_get(domain->conn, "/xend/domain/%s?op=vcpuinfo", domain->name); + root = sexpr_get(conn, "/xend/domain/%s?op=vcpuinfo", def->name); if (root == NULL) return -1; @@ -2128,25 +2133,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) { @@ -2155,8 +2160,19 @@ 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; @@ -2165,16 +2181,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; } /** diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h index 1284db3..b78145c 100644 --- a/src/xen/xend_internal.h +++ b/src/xen/xend_internal.h @@ -140,18 +140,23 @@ int xenDaemonDomainCreate(virConnectPtr conn, int xenDaemonDomainUndefine(virConnectPtr conn, virDomainDefPtr def); -int xenDaemonDomainSetVcpus (virDomainPtr domain, +int xenDaemonDomainSetVcpus (virConnectPtr conn, + virDomainDefPtr def, unsigned int vcpus); -int xenDaemonDomainSetVcpusFlags (virDomainPtr domain, +int xenDaemonDomainSetVcpusFlags (virConnectPtr conn, + virDomainDefPtr def, unsigned int vcpus, unsigned int flags); -int xenDaemonDomainPinVcpu (virDomainPtr domain, +int xenDaemonDomainPinVcpu (virConnectPtr conn, + virDomainDefPtr def, unsigned int vcpu, unsigned char *cpumap, int maplen); -int xenDaemonDomainGetVcpusFlags (virDomainPtr domain, +int xenDaemonDomainGetVcpusFlags (virConnectPtr conn, + virDomainDefPtr def, unsigned int flags); -int xenDaemonDomainGetVcpus (virDomainPtr domain, +int xenDaemonDomainGetVcpus (virConnectPtr conn, + virDomainDefPtr def, virVcpuInfoPtr info, int maxinfo, unsigned char *cpumaps, @@ -163,7 +168,7 @@ 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, diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c index 79f773d..76425dd 100644 --- a/src/xen/xm_internal.c +++ b/src/xen/xm_internal.c @@ -656,11 +656,12 @@ cleanup: * Returns 0 on success, -1 if an error message was issued */ int -xenXMDomainSetVcpusFlags(virDomainPtr domain, +xenXMDomainSetVcpusFlags(virConnectPtr conn, + virDomainDefPtr def, unsigned int vcpus, unsigned int flags) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; const char *filename; xenXMConfCachePtr entry; int ret = -1; @@ -678,14 +679,14 @@ xenXMDomainSetVcpusFlags(virDomainPtr domain, 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; /* Hypervisor maximum. */ - if ((max = xenUnifiedConnectGetMaxVcpus(domain->conn, NULL)) < 0) { + if ((max = xenUnifiedConnectGetMaxVcpus(conn, NULL)) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("could not determine max vcpus for the domain")); goto cleanup; @@ -712,7 +713,7 @@ xenXMDomainSetVcpusFlags(virDomainPtr domain, /* If this fails, should we try to undo our changes to the * in-memory representation of the config file. I say not! */ - if (xenXMConfigSaveFile(domain->conn, entry->filename, entry->def) < 0) + if (xenXMConfigSaveFile(conn, entry->filename, entry->def) < 0) goto cleanup; ret = 0; @@ -732,12 +733,14 @@ cleanup: * issued */ int -xenXMDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags) +xenXMDomainGetVcpusFlags(virConnectPtr conn, + virDomainDefPtr def, + unsigned int flags) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; const char *filename; xenXMConfCachePtr entry; - int ret = -2; + int ret = -1; virCheckFlags(VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG | @@ -750,7 +753,7 @@ xenXMDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags) xenUnifiedLock(priv); - if (!(filename = virHashLookup(priv->nameConfigMap, domain->name))) + if (!(filename = virHashLookup(priv->nameConfigMap, def->name))) goto cleanup; if (!(entry = virHashLookup(priv->configCache, filename))) @@ -776,12 +779,13 @@ cleanup: * Returns 0 for success; -1 (with errno) on error */ int -xenXMDomainPinVcpu(virDomainPtr domain, +xenXMDomainPinVcpu(virConnectPtr conn, + virDomainDefPtr def, unsigned int vcpu ATTRIBUTE_UNUSED, unsigned char *cpumap, int maplen) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; const char *filename; xenXMConfCachePtr entry; int ret = -1; @@ -793,7 +797,7 @@ xenXMDomainPinVcpu(virDomainPtr domain, xenUnifiedLock(priv); - if (!(filename = virHashLookup(priv->nameConfigMap, domain->name))) { + if (!(filename = virHashLookup(priv->nameConfigMap, def->name))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("virHashLookup")); goto cleanup; } @@ -807,7 +811,7 @@ xenXMDomainPinVcpu(virDomainPtr domain, entry->def->cpumask = virBitmapNewData(cpumap, maplen); if (!entry->def->cpumask) goto cleanup; - if (xenXMConfigSaveFile(domain->conn, entry->filename, entry->def) < 0) + if (xenXMConfigSaveFile(conn, entry->filename, entry->def) < 0) goto cleanup; ret = 0; diff --git a/src/xen/xm_internal.h b/src/xen/xm_internal.h index 5a434b9..28087d3 100644 --- a/src/xen/xm_internal.h +++ b/src/xen/xm_internal.h @@ -54,12 +54,21 @@ int xenXMDomainSetMaxMemory(virConnectPtr conn, unsigned long memory); unsigned long long xenXMDomainGetMaxMemory(virConnectPtr conn, virDomainDefPtr def); -int xenXMDomainSetVcpus(virDomainPtr domain, unsigned int vcpus); -int xenXMDomainSetVcpusFlags(virDomainPtr domain, unsigned int vcpus, +int xenXMDomainSetVcpus(virConnectPtr conn, + virDomainDefPtr def, + unsigned int vcpus); +int xenXMDomainSetVcpusFlags(virConnectPtr conn, + virDomainDefPtr def, + unsigned int vcpus, + unsigned int flags); +int xenXMDomainGetVcpusFlags(virConnectPtr conn, + virDomainDefPtr def, unsigned int flags); -int xenXMDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags); -int xenXMDomainPinVcpu(virDomainPtr domain, unsigned int vcpu, - unsigned char *cpumap, int maplen); +int xenXMDomainPinVcpu(virConnectPtr conn, + virDomainDefPtr def, + unsigned int vcpu, + unsigned char *cpumap, + int maplen); virDomainDefPtr xenXMDomainLookupByName(virConnectPtr conn, const char *domname); virDomainDefPtr xenXMDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid); -- 1.8.1.4

Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Introduce use of a virDomainDefPtr in the domain VCPU APIs to simplify introduction of ACL security checks. The virDomainPtr cannot be safely used, since the app may have supplied mis-matching name/uuid/id fields. eg the name points to domain X, while the uuid points to domain Y. Resolving the virDomainPtr to a virDomainDefPtr ensures a consistent name/uuid/id set.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/xen/xen_driver.c | 84 ++++++++++++++++++++++++++++++++++++++++-------- src/xen/xen_hypervisor.c | 42 ++++++++++++------------ src/xen/xen_hypervisor.h | 9 ++++-- src/xen/xend_internal.c | 81 ++++++++++++++++++++++++++-------------------- src/xen/xend_internal.h | 17 ++++++---- src/xen/xm_internal.c | 30 +++++++++-------- src/xen/xm_internal.h | 19 ++++++++--- 7 files changed, 187 insertions(+), 95 deletions(-)
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 8b7dec9..04cb69d 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; }
Should this hunk be in patch 2? Or perhaps it was meant for patch 5?
static virDomainPtr @@ -1182,6 +1201,8 @@ xenUnifiedDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus, unsigned int flags) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + virDomainDefPtr def = NULL; + int ret = -1;
virCheckFlags(VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG | @@ -1202,13 +1223,20 @@ xenUnifiedDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus, return -1; }
+ if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + /* Try non-hypervisor methods first, then hypervisor direct method * as a last resort. */ if (dom->id < 0 && priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainSetVcpusFlags(dom, nvcpus, flags); + ret = xenXMDomainSetVcpusFlags(dom->conn, def, nvcpus, flags); else - return xenDaemonDomainSetVcpusFlags(dom, nvcpus, flags); + ret = xenDaemonDomainSetVcpusFlags(dom->conn, def, nvcpus, flags); + +cleanup: + virDomainDefFree(def); + return ret; }
static int @@ -1231,15 +1259,24 @@ xenUnifiedDomainPinVcpu(virDomainPtr dom, unsigned int vcpu, unsigned char *cpumap, int maplen) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + virDomainDefPtr def = NULL; + int ret = -1; + + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup;
if (dom->id < 0) { if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainPinVcpu(dom, vcpu, cpumap, maplen); + ret = xenXMDomainPinVcpu(dom->conn, def, vcpu, cpumap, maplen); else - return xenDaemonDomainPinVcpu(dom, vcpu, cpumap, maplen); + ret = xenDaemonDomainPinVcpu(dom->conn, def, vcpu, cpumap, maplen); } else { - return xenHypervisorPinVcpu(dom, vcpu, cpumap, maplen); + ret = xenHypervisorPinVcpu(dom->conn, def, vcpu, cpumap, maplen); } + +cleanup: + virDomainDefFree(def); + return ret; }
static int @@ -1248,39 +1285,58 @@ xenUnifiedDomainGetVcpus(virDomainPtr dom, unsigned char *cpumaps, int maplen) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + virDomainDefPtr def = NULL; + int ret = -1; + + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + if (dom->id < 0) { if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Cannot get VCPUs of inactive domain")); - return -1; + goto cleanup; } else { - return xenDaemonDomainGetVcpus(dom, info, maxinfo, cpumaps, maplen); + ret = xenDaemonDomainGetVcpus(dom->conn, def, info, maxinfo, cpumaps, maplen); } } else { - return xenHypervisorGetVcpus(dom, info, maxinfo, cpumaps, maplen); + ret = xenHypervisorGetVcpus(dom->conn, def, info, maxinfo, cpumaps, maplen); } + +cleanup: + virDomainDefFree(def); + return ret; }
static int xenUnifiedDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + virDomainDefPtr def = NULL; + int ret = -1;
virCheckFlags(VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG | VIR_DOMAIN_VCPU_MAXIMUM, -1);
+ if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + if (dom->id < 0) { if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainGetVcpusFlags(dom, flags); + ret = xenXMDomainGetVcpusFlags(dom->conn, def, flags); else - return xenDaemonDomainGetVcpusFlags(dom, flags); + ret = xenDaemonDomainGetVcpusFlags(dom->conn, def, flags); } else { if (flags == (VIR_DOMAIN_VCPU_CONFIG | VIR_DOMAIN_VCPU_MAXIMUM)) - return xenHypervisorGetVcpuMax(dom); + ret = xenHypervisorGetVcpuMax(dom->conn, def); else - return xenDaemonDomainGetVcpusFlags(dom, flags); + ret = xenDaemonDomainGetVcpusFlags(dom->conn, def, flags); } + +cleanup: + virDomainDefFree(def); + return ret; }
static int diff --git a/src/xen/xen_hypervisor.c b/src/xen/xen_hypervisor.c index 423ce85..b97b329 100644 --- a/src/xen/xen_hypervisor.c +++ b/src/xen/xen_hypervisor.c @@ -2931,16 +2931,16 @@ xenHypervisorSetMaxMemory(virConnectPtr conn, */
int -xenHypervisorPinVcpu(virDomainPtr domain, unsigned int vcpu, - unsigned char *cpumap, int maplen) +xenHypervisorPinVcpu(virConnectPtr conn, + virDomainDefPtr def, + unsigned int vcpu, + unsigned char *cpumap, + int maplen) { int ret; - xenUnifiedPrivatePtr priv = domain->conn->privateData; - - if (domain->id < 0) - return -1; + xenUnifiedPrivatePtr priv = conn->privateData;
- ret = virXen_setvcpumap(priv->handle, domain->id, vcpu, + ret = virXen_setvcpumap(priv->handle, def->id, vcpu, cpumap, maplen); if (ret < 0) return -1; @@ -2967,7 +2967,8 @@ xenHypervisorPinVcpu(virDomainPtr domain, unsigned int vcpu, * Returns the number of info filled in case of success, -1 in case of failure. */ int -xenHypervisorGetVcpus(virDomainPtr domain, +xenHypervisorGetVcpus(virConnectPtr conn, + virDomainDefPtr def, virVcpuInfoPtr info, int maxinfo, unsigned char *cpumaps, @@ -2975,22 +2976,22 @@ xenHypervisorGetVcpus(virDomainPtr domain, { xen_getdomaininfo dominfo; int ret; - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; virVcpuInfoPtr ipt; int nbinfo, i;
- if (domain->id < 0 || sizeof(cpumap_t) & 7) { + if (sizeof(cpumap_t) & 7) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("domain shut off or invalid")); + _("invalid cpumap_t size")); return -1; }
/* first get the number of virtual CPUs in this domain */ XEN_GETDOMAININFO_CLEAR(dominfo); - ret = virXen_getdomaininfo(priv->handle, domain->id, + ret = virXen_getdomaininfo(priv->handle, def->id, &dominfo);
- if ((ret < 0) || (XEN_GETDOMAININFO_DOMAIN(dominfo) != domain->id)) { + if ((ret < 0) || (XEN_GETDOMAININFO_DOMAIN(dominfo) != def->id)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot get domain details")); return -1; @@ -3003,7 +3004,7 @@ xenHypervisorGetVcpus(virDomainPtr domain,
for (i = 0, ipt = info; i < nbinfo; i++, ipt++) { if ((cpumaps != NULL) && (i < maxinfo)) { - ret = virXen_getvcpusinfo(priv->handle, domain->id, i, + ret = virXen_getvcpusinfo(priv->handle, def->id, i, ipt, (unsigned char *)VIR_GET_CPUMAP(cpumaps, maplen, i), maplen); @@ -3013,7 +3014,7 @@ xenHypervisorGetVcpus(virDomainPtr domain, return -1; } } else { - ret = virXen_getvcpusinfo(priv->handle, domain->id, i, + ret = virXen_getvcpusinfo(priv->handle, def->id, i, ipt, NULL, 0); if (ret < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -3034,22 +3035,23 @@ xenHypervisorGetVcpus(virDomainPtr domain, * the maximum number of virtual CPUs the guest was booted with. */ int -xenHypervisorGetVcpuMax(virDomainPtr domain) +xenHypervisorGetVcpuMax(virConnectPtr conn, + virDomainDefPtr def)
Fits on one line.
{ xen_getdomaininfo dominfo; int ret; int maxcpu; - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData;
/* inactive domain */ - if (domain->id < 0) { + if (def->id < 0) { maxcpu = MAX_VIRT_CPUS; } else { XEN_GETDOMAININFO_CLEAR(dominfo); - ret = virXen_getdomaininfo(priv->handle, domain->id, + ret = virXen_getdomaininfo(priv->handle, def->id, &dominfo);
- if ((ret < 0) || (XEN_GETDOMAININFO_DOMAIN(dominfo) != domain->id)) + if ((ret < 0) || (XEN_GETDOMAININFO_DOMAIN(dominfo) != def->id)) return -1; maxcpu = XEN_GETDOMAININFO_MAXCPUID(dominfo) + 1; } diff --git a/src/xen/xen_hypervisor.h b/src/xen/xen_hypervisor.h index 9ee1f13..1cf1e14 100644 --- a/src/xen/xen_hypervisor.h +++ b/src/xen/xen_hypervisor.h @@ -89,18 +89,21 @@ int xenHypervisorSetMaxMemory (virConnectPtr conn, ATTRIBUTE_NONNULL (1); int xenHypervisorCheckID (virConnectPtr conn, int id); -int xenHypervisorPinVcpu (virDomainPtr domain, +int xenHypervisorPinVcpu (virConnectPtr conn, + virDomainDefPtr def, unsigned int vcpu, unsigned char *cpumap, int maplen) ATTRIBUTE_NONNULL (1); -int xenHypervisorGetVcpus (virDomainPtr domain, +int xenHypervisorGetVcpus (virConnectPtr conn, + virDomainDefPtr def, virVcpuInfoPtr info, int maxinfo, unsigned char *cpumaps, int maplen) ATTRIBUTE_NONNULL (1); -int xenHypervisorGetVcpuMax (virDomainPtr domain) +int xenHypervisorGetVcpuMax (virConnectPtr conn, + virDomainDefPtr def) ATTRIBUTE_NONNULL (1);
char * xenHypervisorGetSchedulerType (virDomainPtr domain, diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index 77c4dec..75c980c 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -1772,7 +1772,8 @@ xenDaemonNodeGetTopology(virConnectPtr conn, virCapsPtr caps) * Returns 0 on success, -1 if an error message was issued */ int -xenDaemonDomainSetVcpusFlags(virDomainPtr domain, +xenDaemonDomainSetVcpusFlags(virConnectPtr conn, + virDomainDefPtr def,
Comments need updated.
unsigned int vcpus, unsigned int flags) { @@ -1788,7 +1789,7 @@ xenDaemonDomainSetVcpusFlags(virDomainPtr domain, return -1; }
- if (domain->id < 0) { + if (def->id < 0) { if (flags & VIR_DOMAIN_VCPU_LIVE) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("domain not running")); @@ -1806,7 +1807,7 @@ xenDaemonDomainSetVcpusFlags(virDomainPtr domain, /* Unfortunately, xend_op does not validate whether this exceeds * the maximum. */ flags |= VIR_DOMAIN_VCPU_MAXIMUM; - if ((max = xenDaemonDomainGetVcpusFlags(domain, flags)) < 0) { + if ((max = xenDaemonDomainGetVcpusFlags(conn, def, flags)) < 0) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("could not determine max vcpus for the domain")); return -1; @@ -1819,7 +1820,7 @@ xenDaemonDomainSetVcpusFlags(virDomainPtr domain, }
snprintf(buf, sizeof(buf), "%d", vcpus); - return xend_op(domain->conn, domain->name, "op", "set_vcpus", "vcpus", + return xend_op(conn, def->name, "op", "set_vcpus", "vcpus", buf, NULL); }
@@ -1840,14 +1841,15 @@ xenDaemonDomainSetVcpusFlags(virDomainPtr domain, * Returns 0 for success; -1 (with errno) on error */ int -xenDaemonDomainPinVcpu(virDomainPtr domain, +xenDaemonDomainPinVcpu(virConnectPtr conn, + virDomainDefPtr minidef,
Same here, comments for the function need updated.
unsigned int vcpu, unsigned char *cpumap, int maplen) { char buf[VIR_UUID_BUFLEN], mapstr[sizeof(cpumap_t) * 64]; int i, j, ret; - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; virDomainDefPtr def = NULL;
if (maplen > (int)sizeof(cpumap_t)) { @@ -1875,12 +1877,12 @@ xenDaemonDomainPinVcpu(virDomainPtr domain,
snprintf(buf, sizeof(buf), "%d", vcpu);
- ret = xend_op(domain->conn, domain->name, "op", "pincpu", "vcpu", buf, + ret = xend_op(conn, minidef->name, "op", "pincpu", "vcpu", buf, "cpumap", mapstr, NULL);
- if (!(def = xenDaemonDomainFetch(domain->conn, - domain->id, - domain->name, + if (!(def = xenDaemonDomainFetch(conn, + minidef->id, + minidef->name, NULL))) goto cleanup;
@@ -1922,7 +1924,9 @@ cleanup:
*/ int -xenDaemonDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags) +xenDaemonDomainGetVcpusFlags(virConnectPtr conn, + virDomainDefPtr def, + unsigned int flags)
Comments need updated here too.
{ struct sexpr *root; int ret; @@ -1931,13 +1935,13 @@ xenDaemonDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags) VIR_DOMAIN_VCPU_CONFIG | VIR_DOMAIN_VCPU_MAXIMUM, -1);
- if (domain->id < 0 && (flags & VIR_DOMAIN_VCPU_LIVE)) { + if (def->id < 0 && (flags & VIR_DOMAIN_VCPU_LIVE)) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("domain not active")); return -1; }
- root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name); + root = sexpr_get(conn, "/xend/domain/%s?detail=1", def->name); if (root == NULL) return -1;
@@ -1973,7 +1977,8 @@ xenDaemonDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags) * Returns the number of info filled in case of success, -1 in case of failure. */ int -xenDaemonDomainGetVcpus(virDomainPtr domain, +xenDaemonDomainGetVcpus(virConnectPtr conn, + virDomainDefPtr def,
Same here.
virVcpuInfoPtr info, int maxinfo, unsigned char *cpumaps, @@ -1985,7 +1990,7 @@ xenDaemonDomainGetVcpus(virDomainPtr domain, unsigned char *cpumap; int vcpu, cpu;
- root = sexpr_get(domain->conn, "/xend/domain/%s?op=vcpuinfo", domain->name); + root = sexpr_get(conn, "/xend/domain/%s?op=vcpuinfo", def->name); if (root == NULL) return -1;
@@ -2128,25 +2133,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) {
Comments need updated here to, but again not sure if these last hunks were intended for a previous patch.
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) { @@ -2155,8 +2160,19 @@ 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; @@ -2165,16 +2181,13 @@ xenDaemonCreateXML(virConnectPtr conn, const char *xmlDesc) goto error;
virDomainDefFree(def);
Freeing def here needs to be killed too, right?
- 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; }
/** diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h index 1284db3..b78145c 100644 --- a/src/xen/xend_internal.h +++ b/src/xen/xend_internal.h @@ -140,18 +140,23 @@ int xenDaemonDomainCreate(virConnectPtr conn, int xenDaemonDomainUndefine(virConnectPtr conn, virDomainDefPtr def);
-int xenDaemonDomainSetVcpus (virDomainPtr domain, +int xenDaemonDomainSetVcpus (virConnectPtr conn, + virDomainDefPtr def, unsigned int vcpus); -int xenDaemonDomainSetVcpusFlags (virDomainPtr domain, +int xenDaemonDomainSetVcpusFlags (virConnectPtr conn, + virDomainDefPtr def, unsigned int vcpus, unsigned int flags); -int xenDaemonDomainPinVcpu (virDomainPtr domain, +int xenDaemonDomainPinVcpu (virConnectPtr conn, + virDomainDefPtr def, unsigned int vcpu, unsigned char *cpumap, int maplen); -int xenDaemonDomainGetVcpusFlags (virDomainPtr domain, +int xenDaemonDomainGetVcpusFlags (virConnectPtr conn, + virDomainDefPtr def, unsigned int flags); -int xenDaemonDomainGetVcpus (virDomainPtr domain, +int xenDaemonDomainGetVcpus (virConnectPtr conn, + virDomainDefPtr def, virVcpuInfoPtr info, int maxinfo, unsigned char *cpumaps, @@ -163,7 +168,7 @@ 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,
Another hunk for a previous patch?
diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c index 79f773d..76425dd 100644 --- a/src/xen/xm_internal.c +++ b/src/xen/xm_internal.c @@ -656,11 +656,12 @@ cleanup: * Returns 0 on success, -1 if an error message was issued */ int -xenXMDomainSetVcpusFlags(virDomainPtr domain, +xenXMDomainSetVcpusFlags(virConnectPtr conn, + virDomainDefPtr def,
Function comments need updated.
unsigned int vcpus, unsigned int flags) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; const char *filename; xenXMConfCachePtr entry; int ret = -1; @@ -678,14 +679,14 @@ xenXMDomainSetVcpusFlags(virDomainPtr domain,
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;
/* Hypervisor maximum. */ - if ((max = xenUnifiedConnectGetMaxVcpus(domain->conn, NULL)) < 0) { + if ((max = xenUnifiedConnectGetMaxVcpus(conn, NULL)) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("could not determine max vcpus for the domain")); goto cleanup; @@ -712,7 +713,7 @@ xenXMDomainSetVcpusFlags(virDomainPtr domain, /* If this fails, should we try to undo our changes to the * in-memory representation of the config file. I say not! */ - if (xenXMConfigSaveFile(domain->conn, entry->filename, entry->def) < 0) + if (xenXMConfigSaveFile(conn, entry->filename, entry->def) < 0) goto cleanup; ret = 0;
@@ -732,12 +733,14 @@ cleanup: * issued */ int -xenXMDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags) +xenXMDomainGetVcpusFlags(virConnectPtr conn, + virDomainDefPtr def, + unsigned int flags)
Same here.
{ - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; const char *filename; xenXMConfCachePtr entry; - int ret = -2; + int ret = -1;
virCheckFlags(VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG | @@ -750,7 +753,7 @@ xenXMDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
xenUnifiedLock(priv);
- if (!(filename = virHashLookup(priv->nameConfigMap, domain->name))) + if (!(filename = virHashLookup(priv->nameConfigMap, def->name))) goto cleanup;
if (!(entry = virHashLookup(priv->configCache, filename))) @@ -776,12 +779,13 @@ cleanup: * Returns 0 for success; -1 (with errno) on error */ int -xenXMDomainPinVcpu(virDomainPtr domain, +xenXMDomainPinVcpu(virConnectPtr conn, + virDomainDefPtr def,
Same here, function comments need updated. Regards, Jim
unsigned int vcpu ATTRIBUTE_UNUSED, unsigned char *cpumap, int maplen) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; const char *filename; xenXMConfCachePtr entry; int ret = -1; @@ -793,7 +797,7 @@ xenXMDomainPinVcpu(virDomainPtr domain,
xenUnifiedLock(priv);
- if (!(filename = virHashLookup(priv->nameConfigMap, domain->name))) { + if (!(filename = virHashLookup(priv->nameConfigMap, def->name))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("virHashLookup")); goto cleanup; } @@ -807,7 +811,7 @@ xenXMDomainPinVcpu(virDomainPtr domain, entry->def->cpumask = virBitmapNewData(cpumap, maplen); if (!entry->def->cpumask) goto cleanup; - if (xenXMConfigSaveFile(domain->conn, entry->filename, entry->def) < 0) + if (xenXMConfigSaveFile(conn, entry->filename, entry->def) < 0) goto cleanup;
ret = 0; diff --git a/src/xen/xm_internal.h b/src/xen/xm_internal.h index 5a434b9..28087d3 100644 --- a/src/xen/xm_internal.h +++ b/src/xen/xm_internal.h @@ -54,12 +54,21 @@ int xenXMDomainSetMaxMemory(virConnectPtr conn, unsigned long memory); unsigned long long xenXMDomainGetMaxMemory(virConnectPtr conn, virDomainDefPtr def); -int xenXMDomainSetVcpus(virDomainPtr domain, unsigned int vcpus); -int xenXMDomainSetVcpusFlags(virDomainPtr domain, unsigned int vcpus, +int xenXMDomainSetVcpus(virConnectPtr conn, + virDomainDefPtr def, + unsigned int vcpus); +int xenXMDomainSetVcpusFlags(virConnectPtr conn, + virDomainDefPtr def, + unsigned int vcpus, + unsigned int flags); +int xenXMDomainGetVcpusFlags(virConnectPtr conn, + virDomainDefPtr def, unsigned int flags); -int xenXMDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags); -int xenXMDomainPinVcpu(virDomainPtr domain, unsigned int vcpu, - unsigned char *cpumap, int maplen); +int xenXMDomainPinVcpu(virConnectPtr conn, + virDomainDefPtr def, + unsigned int vcpu, + unsigned char *cpumap, + int maplen); virDomainDefPtr xenXMDomainLookupByName(virConnectPtr conn, const char *domname); virDomainDefPtr xenXMDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid);

On Mon, May 20, 2013 at 12:14:04PM -0600, Jim Fehlig wrote:
Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Introduce use of a virDomainDefPtr in the domain VCPU APIs to simplify introduction of ACL security checks. The virDomainPtr cannot be safely used, since the app may have supplied mis-matching name/uuid/id fields. eg the name points to domain X, while the uuid points to domain Y. Resolving the virDomainPtr to a virDomainDefPtr ensures a consistent name/uuid/id set.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/xen/xen_driver.c | 84 ++++++++++++++++++++++++++++++++++++++++-------- src/xen/xen_hypervisor.c | 42 ++++++++++++------------ src/xen/xen_hypervisor.h | 9 ++++-- src/xen/xend_internal.c | 81 ++++++++++++++++++++++++++-------------------- src/xen/xend_internal.h | 17 ++++++---- src/xen/xm_internal.c | 30 +++++++++-------- src/xen/xm_internal.h | 19 ++++++++--- 7 files changed, 187 insertions(+), 95 deletions(-)
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 8b7dec9..04cb69d 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; }
Should this hunk be in patch 2? Or perhaps it was meant for patch 5?
Hmm, actually, yes, it should be in the previous patch. Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

From: "Daniel P. Berrange" <berrange@redhat.com> Introduce use of a virDomainDefPtr in the domain hotplug APIs to simplify introduction of ACL security checks. The virDomainPtr cannot be safely used, since the app may have supplied mis-matching name/uuid/id fields. eg the name points to domain X, while the uuid points to domain Y. Resolving the virDomainPtr to a virDomainDefPtr ensures a consistent name/uuid/id set. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/xen/xen_driver.c | 64 +++++++++++++++++++++++++++++++------ src/xen/xend_internal.c | 85 ++++++++++++++++++++++++++----------------------- src/xen/xend_internal.h | 10 ++++-- src/xen/xm_internal.c | 22 +++++++------ src/xen/xm_internal.h | 6 ++-- 5 files changed, 122 insertions(+), 65 deletions(-) diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 04cb69d..f5f6407 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -1695,6 +1695,8 @@ xenUnifiedDomainAttachDevice(virDomainPtr dom, const char *xml) { xenUnifiedPrivatePtr priv = dom->conn->privateData; unsigned int flags = VIR_DOMAIN_DEVICE_MODIFY_LIVE; + virDomainDefPtr def = NULL; + int ret = -1; /* * HACK: xend with xendConfigVersion >= 3 does not support changing live @@ -1704,12 +1706,17 @@ xenUnifiedDomainAttachDevice(virDomainPtr dom, const char *xml) if (priv->xendConfigVersion >= XEND_CONFIG_VERSION_3_0_4) flags |= VIR_DOMAIN_DEVICE_MODIFY_CONFIG; + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + if (dom->id < 0 && priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainAttachDeviceFlags(dom, xml, flags); + ret = xenXMDomainAttachDeviceFlags(dom->conn, def, xml, flags); else - return xenDaemonAttachDeviceFlags(dom, xml, flags); + ret = xenDaemonAttachDeviceFlags(dom->conn, def, xml, flags); - return -1; +cleanup: + virDomainDefFree(def); + return ret; } static int @@ -1717,11 +1724,20 @@ xenUnifiedDomainAttachDeviceFlags(virDomainPtr dom, const char *xml, unsigned int flags) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + virDomainDefPtr def = NULL; + int ret = -1; + + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; if (dom->id < 0 && priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainAttachDeviceFlags(dom, xml, flags); + ret = xenXMDomainAttachDeviceFlags(dom->conn, def, xml, flags); else - return xenDaemonAttachDeviceFlags(dom, xml, flags); + ret = xenDaemonAttachDeviceFlags(dom->conn, def, xml, flags); + +cleanup: + virDomainDefFree(def); + return ret; } static int @@ -1729,6 +1745,8 @@ xenUnifiedDomainDetachDevice(virDomainPtr dom, const char *xml) { xenUnifiedPrivatePtr priv = dom->conn->privateData; unsigned int flags = VIR_DOMAIN_DEVICE_MODIFY_LIVE; + virDomainDefPtr def = NULL; + int ret = -1; /* * HACK: xend with xendConfigVersion >= 3 does not support changing live @@ -1738,10 +1756,17 @@ xenUnifiedDomainDetachDevice(virDomainPtr dom, const char *xml) if (priv->xendConfigVersion >= XEND_CONFIG_VERSION_3_0_4) flags |= VIR_DOMAIN_DEVICE_MODIFY_CONFIG; + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + if (dom->id < 0 && priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainDetachDeviceFlags(dom, xml, flags); + ret = xenXMDomainDetachDeviceFlags(dom->conn, def, xml, flags); else - return xenDaemonDetachDeviceFlags(dom, xml, flags); + ret = xenDaemonDetachDeviceFlags(dom->conn, def, xml, flags); + +cleanup: + virDomainDefFree(def); + return ret; } static int @@ -1749,18 +1774,37 @@ xenUnifiedDomainDetachDeviceFlags(virDomainPtr dom, const char *xml, unsigned int flags) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + virDomainDefPtr def = NULL; + int ret = -1; + + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; if (dom->id < 0 && priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainDetachDeviceFlags(dom, xml, flags); + ret = xenXMDomainDetachDeviceFlags(dom->conn, def, xml, flags); else - return xenDaemonDetachDeviceFlags(dom, xml, flags); + ret = xenDaemonDetachDeviceFlags(dom->conn, def, xml, flags); + +cleanup: + virDomainDefFree(def); + return ret; } static int xenUnifiedDomainUpdateDeviceFlags(virDomainPtr dom, const char *xml, unsigned int flags) { - return xenDaemonUpdateDeviceFlags(dom, xml, flags); + virDomainDefPtr def = NULL; + int ret = -1; + + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + ret = xenDaemonUpdateDeviceFlags(dom->conn, def, xml, flags); + +cleanup: + virDomainDefFree(def); + return ret; } static int diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index 75c980c..2715a3e 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -60,7 +60,8 @@ #define XEND_RCV_BUF_MAX_LEN (256 * 1024) static int -virDomainXMLDevID(virDomainPtr domain, virDomainDeviceDefPtr dev, char *class, +virDomainXMLDevID(virConnectPtr conn, virDomainDefPtr domain, + virDomainDeviceDefPtr dev, char *class, char *ref, int ref_len); /** @@ -2202,11 +2203,12 @@ xenDaemonCreateXML(virConnectPtr conn, virDomainDefPtr def) * Returns 0 in case of success, -1 in case of failure. */ int -xenDaemonAttachDeviceFlags(virDomainPtr domain, +xenDaemonAttachDeviceFlags(virConnectPtr conn, + virDomainDefPtr minidef, const char *xml, unsigned int flags) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; char *sexpr = NULL; int ret = -1; virDomainDeviceDefPtr dev = NULL; @@ -2217,7 +2219,7 @@ xenDaemonAttachDeviceFlags(virDomainPtr domain, virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1); - if (domain->id < 0) { + if (minidef->id < 0) { /* Cannot modify live config if domain is inactive */ if (flags & VIR_DOMAIN_DEVICE_MODIFY_LIVE) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", @@ -2247,9 +2249,9 @@ xenDaemonAttachDeviceFlags(virDomainPtr domain, } } - if (!(def = xenDaemonDomainFetch(domain->conn, - domain->id, - domain->name, + if (!(def = xenDaemonDomainFetch(conn, + minidef->id, + minidef->name, NULL))) goto cleanup; @@ -2275,7 +2277,7 @@ xenDaemonAttachDeviceFlags(virDomainPtr domain, break; case VIR_DOMAIN_DEVICE_NET: - if (xenFormatSxprNet(domain->conn, + if (xenFormatSxprNet(conn, dev->data.net, &buf, STREQ(def->os.type, "hvm") ? 1 : 0, @@ -2320,9 +2322,9 @@ xenDaemonAttachDeviceFlags(virDomainPtr domain, sexpr = virBufferContentAndReset(&buf); - if (virDomainXMLDevID(domain, dev, class, ref, sizeof(ref))) { + if (virDomainXMLDevID(conn, minidef, dev, class, ref, sizeof(ref))) { /* device doesn't exist, define it */ - ret = xend_op(domain->conn, domain->name, "op", "device_create", + ret = xend_op(conn, def->name, "op", "device_create", "config", sexpr, NULL); } else { if (dev->data.disk->device != VIR_DOMAIN_DISK_DEVICE_CDROM) { @@ -2330,7 +2332,7 @@ xenDaemonAttachDeviceFlags(virDomainPtr domain, _("target '%s' already exists"), target); } else { /* device exists, attempt to modify it */ - ret = xend_op(domain->conn, domain->name, "op", "device_configure", + ret = xend_op(conn, minidef->name, "op", "device_configure", "config", sexpr, "dev", ref, NULL); } } @@ -2355,11 +2357,12 @@ cleanup: * Returns 0 in case of success, -1 in case of failure. */ int -xenDaemonUpdateDeviceFlags(virDomainPtr domain, +xenDaemonUpdateDeviceFlags(virConnectPtr conn, + virDomainDefPtr minidef, const char *xml, unsigned int flags) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; char *sexpr = NULL; int ret = -1; virDomainDeviceDefPtr dev = NULL; @@ -2370,7 +2373,7 @@ xenDaemonUpdateDeviceFlags(virDomainPtr domain, virCheckFlags(VIR_DOMAIN_DEVICE_MODIFY_LIVE | VIR_DOMAIN_DEVICE_MODIFY_CONFIG, -1); - if (domain->id < 0) { + if (minidef->id < 0) { /* Cannot modify live config if domain is inactive */ if (flags & VIR_DOMAIN_DEVICE_MODIFY_LIVE) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", @@ -2400,9 +2403,9 @@ xenDaemonUpdateDeviceFlags(virDomainPtr domain, } } - if (!(def = xenDaemonDomainFetch(domain->conn, - domain->id, - domain->name, + if (!(def = xenDaemonDomainFetch(conn, + minidef->id, + minidef->name, NULL))) goto cleanup; @@ -2428,13 +2431,13 @@ xenDaemonUpdateDeviceFlags(virDomainPtr domain, sexpr = virBufferContentAndReset(&buf); - if (virDomainXMLDevID(domain, dev, class, ref, sizeof(ref))) { + if (virDomainXMLDevID(conn, minidef, dev, class, ref, sizeof(ref))) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("requested device does not exist")); goto cleanup; } else { /* device exists, attempt to modify it */ - ret = xend_op(domain->conn, domain->name, "op", "device_configure", + ret = xend_op(conn, minidef->name, "op", "device_configure", "config", sexpr, "dev", ref, NULL); } @@ -2456,11 +2459,12 @@ cleanup: * Returns 0 in case of success, -1 in case of failure. */ int -xenDaemonDetachDeviceFlags(virDomainPtr domain, +xenDaemonDetachDeviceFlags(virConnectPtr conn, + virDomainDefPtr minidef, const char *xml, unsigned int flags) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; char class[8], ref[80]; virDomainDeviceDefPtr dev = NULL; virDomainDefPtr def = NULL; @@ -2470,7 +2474,7 @@ xenDaemonDetachDeviceFlags(virDomainPtr domain, virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1); - if (domain->id < 0) { + if (minidef->id < 0) { /* Cannot modify live config if domain is inactive */ if (flags & VIR_DOMAIN_DEVICE_MODIFY_LIVE) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", @@ -2500,9 +2504,9 @@ xenDaemonDetachDeviceFlags(virDomainPtr domain, } } - if (!(def = xenDaemonDomainFetch(domain->conn, - domain->id, - domain->name, + if (!(def = xenDaemonDomainFetch(conn, + minidef->id, + minidef->name, NULL))) goto cleanup; @@ -2510,7 +2514,7 @@ xenDaemonDetachDeviceFlags(virDomainPtr domain, VIR_DOMAIN_XML_INACTIVE))) goto cleanup; - if (virDomainXMLDevID(domain, dev, class, ref, sizeof(ref))) + if (virDomainXMLDevID(conn, minidef, dev, class, ref, sizeof(ref))) goto cleanup; if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) { @@ -2524,12 +2528,12 @@ xenDaemonDetachDeviceFlags(virDomainPtr domain, goto cleanup; } xendev = virBufferContentAndReset(&buf); - ret = xend_op(domain->conn, domain->name, "op", "device_configure", + ret = xend_op(conn, minidef->name, "op", "device_configure", "config", xendev, "dev", ref, NULL); VIR_FREE(xendev); } else { - ret = xend_op(domain->conn, domain->name, "op", "device_destroy", + ret = xend_op(conn, minidef->name, "op", "device_destroy", "type", class, "dev", ref, "force", "0", "rm_cfg", "1", NULL); } @@ -3334,13 +3338,14 @@ xenDaemonDomainBlockPeek(virDomainPtr domain, * Returns 0 in case of success, -1 in case of failure. */ static int -virDomainXMLDevID(virDomainPtr domain, +virDomainXMLDevID(virConnectPtr conn, + virDomainDefPtr def, virDomainDeviceDefPtr dev, char *class, char *ref, int ref_len) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; char *xref; char *tmp; @@ -3357,7 +3362,7 @@ virDomainXMLDevID(virDomainPtr domain, if (dev->data.disk->dst == NULL) return -1; xenUnifiedLock(priv); - xref = xenStoreDomainGetDiskID(domain->conn, domain->id, + xref = xenStoreDomainGetDiskID(conn, def->id, dev->data.disk->dst); xenUnifiedUnlock(priv); if (xref == NULL) @@ -3369,13 +3374,13 @@ virDomainXMLDevID(virDomainPtr domain, return -1; } else if (dev->type == VIR_DOMAIN_DEVICE_NET) { char mac[VIR_MAC_STRING_BUFLEN]; - virDomainNetDefPtr def = dev->data.net; - virMacAddrFormat(&def->mac, mac); + virDomainNetDefPtr netdef = dev->data.net; + virMacAddrFormat(&netdef->mac, mac); strcpy(class, "vif"); xenUnifiedLock(priv); - xref = xenStoreDomainGetNetworkID(domain->conn, domain->id, mac); + xref = xenStoreDomainGetNetworkID(conn, def->id, mac); xenUnifiedUnlock(priv); if (xref == NULL) return -1; @@ -3388,13 +3393,13 @@ virDomainXMLDevID(virDomainPtr domain, dev->data.hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && dev->data.hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) { char *bdf; - virDomainHostdevDefPtr def = dev->data.hostdev; + virDomainHostdevDefPtr hostdef = dev->data.hostdev; if (virAsprintf(&bdf, "%04x:%02x:%02x.%0x", - def->source.subsys.u.pci.addr.domain, - def->source.subsys.u.pci.addr.bus, - def->source.subsys.u.pci.addr.slot, - def->source.subsys.u.pci.addr.function) < 0) { + hostdef->source.subsys.u.pci.addr.domain, + hostdef->source.subsys.u.pci.addr.bus, + hostdef->source.subsys.u.pci.addr.slot, + hostdef->source.subsys.u.pci.addr.function) < 0) { virReportOOMError(); return -1; } @@ -3402,7 +3407,7 @@ virDomainXMLDevID(virDomainPtr domain, strcpy(class, "pci"); xenUnifiedLock(priv); - xref = xenStoreDomainGetPCIID(domain->conn, domain->id, bdf); + xref = xenStoreDomainGetPCIID(conn, def->id, bdf); xenUnifiedUnlock(priv); VIR_FREE(bdf); if (xref == NULL) diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h index b78145c..62b85ef 100644 --- a/src/xen/xend_internal.h +++ b/src/xen/xend_internal.h @@ -126,10 +126,12 @@ int xenDaemonListDefinedDomains(virConnectPtr conn, char **const names, int maxnames); -int xenDaemonAttachDeviceFlags(virDomainPtr domain, +int xenDaemonAttachDeviceFlags(virConnectPtr conn, + virDomainDefPtr def, const char *xml, unsigned int flags); -int xenDaemonDetachDeviceFlags(virDomainPtr domain, +int xenDaemonDetachDeviceFlags(virConnectPtr conn, + virDomainDefPtr def, const char *xml, unsigned int flags); @@ -161,7 +163,9 @@ int xenDaemonDomainGetVcpus (virConnectPtr conn, int maxinfo, unsigned char *cpumaps, int maplen); -int xenDaemonUpdateDeviceFlags(virDomainPtr domain, const char *xml, +int xenDaemonUpdateDeviceFlags(virConnectPtr conn, + virDomainDefPtr def, + const char *xml, unsigned int flags); int xenDaemonDomainGetAutostart (virDomainPtr dom, int *autostart); diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c index 76425dd..c2d9915 100644 --- a/src/xen/xm_internal.c +++ b/src/xen/xm_internal.c @@ -1219,7 +1219,8 @@ cleanup: * Returns 0 in case of success, -1 in case of failure. */ int -xenXMDomainAttachDeviceFlags(virDomainPtr domain, +xenXMDomainAttachDeviceFlags(virConnectPtr conn, + virDomainDefPtr minidef, const char *xml, unsigned int flags) { @@ -1228,12 +1229,12 @@ xenXMDomainAttachDeviceFlags(virDomainPtr domain, int ret = -1; virDomainDeviceDefPtr dev = NULL; virDomainDefPtr def; - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1); if ((flags & VIR_DOMAIN_DEVICE_MODIFY_LIVE) || - (domain->id != -1 && flags == VIR_DOMAIN_DEVICE_MODIFY_CURRENT)) { + (minidef->id != -1 && flags == VIR_DOMAIN_DEVICE_MODIFY_CURRENT)) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("Xm driver only supports modifying persistent config")); return -1; @@ -1241,7 +1242,7 @@ xenXMDomainAttachDeviceFlags(virDomainPtr domain, xenUnifiedLock(priv); - if (!(filename = virHashLookup(priv->nameConfigMap, domain->name))) + if (!(filename = virHashLookup(priv->nameConfigMap, minidef->name))) goto cleanup; if (!(entry = virHashLookup(priv->configCache, filename))) goto cleanup; @@ -1284,7 +1285,7 @@ xenXMDomainAttachDeviceFlags(virDomainPtr domain, /* If this fails, should we try to undo our changes to the * in-memory representation of the config file. I say not! */ - if (xenXMConfigSaveFile(domain->conn, entry->filename, entry->def) < 0) + if (xenXMConfigSaveFile(conn, entry->filename, entry->def) < 0) goto cleanup; ret = 0; @@ -1309,7 +1310,8 @@ xenXMDomainAttachDeviceFlags(virDomainPtr domain, * Returns 0 in case of success, -1 in case of failure. */ int -xenXMDomainDetachDeviceFlags(virDomainPtr domain, +xenXMDomainDetachDeviceFlags(virConnectPtr conn, + virDomainDefPtr minidef, const char *xml, unsigned int flags) { @@ -1319,12 +1321,12 @@ xenXMDomainDetachDeviceFlags(virDomainPtr domain, virDomainDefPtr def; int ret = -1; int i; - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1); if ((flags & VIR_DOMAIN_DEVICE_MODIFY_LIVE) || - (domain->id != -1 && flags == VIR_DOMAIN_DEVICE_MODIFY_CURRENT)) { + (minidef->id != -1 && flags == VIR_DOMAIN_DEVICE_MODIFY_CURRENT)) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("Xm driver only supports modifying persistent config")); return -1; @@ -1332,7 +1334,7 @@ xenXMDomainDetachDeviceFlags(virDomainPtr domain, xenUnifiedLock(priv); - if (!(filename = virHashLookup(priv->nameConfigMap, domain->name))) + if (!(filename = virHashLookup(priv->nameConfigMap, minidef->name))) goto cleanup; if (!(entry = virHashLookup(priv->configCache, filename))) goto cleanup; @@ -1390,7 +1392,7 @@ xenXMDomainDetachDeviceFlags(virDomainPtr domain, /* If this fails, should we try to undo our changes to the * in-memory representation of the config file. I say not! */ - if (xenXMConfigSaveFile(domain->conn, entry->filename, entry->def) < 0) + if (xenXMConfigSaveFile(conn, entry->filename, entry->def) < 0) goto cleanup; ret = 0; diff --git a/src/xen/xm_internal.h b/src/xen/xm_internal.h index 28087d3..7d64dc6 100644 --- a/src/xen/xm_internal.h +++ b/src/xen/xm_internal.h @@ -85,11 +85,13 @@ int xenXMDomainBlockPeek (virDomainPtr dom, const char *path, unsigned long long int xenXMDomainGetAutostart(virDomainPtr dom, int *autostart); int xenXMDomainSetAutostart(virDomainPtr dom, int autostart); -int xenXMDomainAttachDeviceFlags(virDomainPtr domain, +int xenXMDomainAttachDeviceFlags(virConnectPtr conn, + virDomainDefPtr def, const char *xml, unsigned int flags); -int xenXMDomainDetachDeviceFlags(virDomainPtr domain, +int xenXMDomainDetachDeviceFlags(virConnectPtr conn, + virDomainDefPtr def, const char *xml, unsigned int flags); -- 1.8.1.4

Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Introduce use of a virDomainDefPtr in the domain hotplug APIs to simplify introduction of ACL security checks. The virDomainPtr cannot be safely used, since the app may have supplied mis-matching name/uuid/id fields. eg the name points to domain X, while the uuid points to domain Y. Resolving the virDomainPtr to a virDomainDefPtr ensures a consistent name/uuid/id set.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/xen/xen_driver.c | 64 +++++++++++++++++++++++++++++++------ src/xen/xend_internal.c | 85 ++++++++++++++++++++++++++----------------------- src/xen/xend_internal.h | 10 ++++-- src/xen/xm_internal.c | 22 +++++++------ src/xen/xm_internal.h | 6 ++-- 5 files changed, 122 insertions(+), 65 deletions(-)
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 04cb69d..f5f6407 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -1695,6 +1695,8 @@ xenUnifiedDomainAttachDevice(virDomainPtr dom, const char *xml) { xenUnifiedPrivatePtr priv = dom->conn->privateData; unsigned int flags = VIR_DOMAIN_DEVICE_MODIFY_LIVE; + virDomainDefPtr def = NULL; + int ret = -1;
/* * HACK: xend with xendConfigVersion >= 3 does not support changing live @@ -1704,12 +1706,17 @@ xenUnifiedDomainAttachDevice(virDomainPtr dom, const char *xml) if (priv->xendConfigVersion >= XEND_CONFIG_VERSION_3_0_4) flags |= VIR_DOMAIN_DEVICE_MODIFY_CONFIG;
+ if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + if (dom->id < 0 && priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainAttachDeviceFlags(dom, xml, flags); + ret = xenXMDomainAttachDeviceFlags(dom->conn, def, xml, flags); else - return xenDaemonAttachDeviceFlags(dom, xml, flags); + ret = xenDaemonAttachDeviceFlags(dom->conn, def, xml, flags);
- return -1; +cleanup: + virDomainDefFree(def); + return ret; }
static int @@ -1717,11 +1724,20 @@ xenUnifiedDomainAttachDeviceFlags(virDomainPtr dom, const char *xml, unsigned int flags) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + virDomainDefPtr def = NULL; + int ret = -1; + + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup;
if (dom->id < 0 && priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainAttachDeviceFlags(dom, xml, flags); + ret = xenXMDomainAttachDeviceFlags(dom->conn, def, xml, flags); else - return xenDaemonAttachDeviceFlags(dom, xml, flags); + ret = xenDaemonAttachDeviceFlags(dom->conn, def, xml, flags); + +cleanup: + virDomainDefFree(def); + return ret; }
static int @@ -1729,6 +1745,8 @@ xenUnifiedDomainDetachDevice(virDomainPtr dom, const char *xml) { xenUnifiedPrivatePtr priv = dom->conn->privateData; unsigned int flags = VIR_DOMAIN_DEVICE_MODIFY_LIVE; + virDomainDefPtr def = NULL; + int ret = -1;
/* * HACK: xend with xendConfigVersion >= 3 does not support changing live @@ -1738,10 +1756,17 @@ xenUnifiedDomainDetachDevice(virDomainPtr dom, const char *xml) if (priv->xendConfigVersion >= XEND_CONFIG_VERSION_3_0_4) flags |= VIR_DOMAIN_DEVICE_MODIFY_CONFIG;
+ if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + if (dom->id < 0 && priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainDetachDeviceFlags(dom, xml, flags); + ret = xenXMDomainDetachDeviceFlags(dom->conn, def, xml, flags); else - return xenDaemonDetachDeviceFlags(dom, xml, flags); + ret = xenDaemonDetachDeviceFlags(dom->conn, def, xml, flags); + +cleanup: + virDomainDefFree(def); + return ret; }
static int @@ -1749,18 +1774,37 @@ xenUnifiedDomainDetachDeviceFlags(virDomainPtr dom, const char *xml, unsigned int flags) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + virDomainDefPtr def = NULL; + int ret = -1; + + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup;
if (dom->id < 0 && priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainDetachDeviceFlags(dom, xml, flags); + ret = xenXMDomainDetachDeviceFlags(dom->conn, def, xml, flags); else - return xenDaemonDetachDeviceFlags(dom, xml, flags); + ret = xenDaemonDetachDeviceFlags(dom->conn, def, xml, flags); + +cleanup: + virDomainDefFree(def); + return ret; }
static int xenUnifiedDomainUpdateDeviceFlags(virDomainPtr dom, const char *xml, unsigned int flags) { - return xenDaemonUpdateDeviceFlags(dom, xml, flags); + virDomainDefPtr def = NULL; + int ret = -1; + + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + ret = xenDaemonUpdateDeviceFlags(dom->conn, def, xml, flags); + +cleanup: + virDomainDefFree(def); + return ret; }
static int diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index 75c980c..2715a3e 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -60,7 +60,8 @@ #define XEND_RCV_BUF_MAX_LEN (256 * 1024)
static int -virDomainXMLDevID(virDomainPtr domain, virDomainDeviceDefPtr dev, char *class, +virDomainXMLDevID(virConnectPtr conn, virDomainDefPtr domain, + virDomainDeviceDefPtr dev, char *class, char *ref, int ref_len);
/** @@ -2202,11 +2203,12 @@ xenDaemonCreateXML(virConnectPtr conn, virDomainDefPtr def) * Returns 0 in case of success, -1 in case of failure. */ int -xenDaemonAttachDeviceFlags(virDomainPtr domain, +xenDaemonAttachDeviceFlags(virConnectPtr conn, + virDomainDefPtr minidef,
My usual comment about the function comments needing updated :). Here and below where the signatures change. ACK. Regards, Jim
const char *xml, unsigned int flags) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; char *sexpr = NULL; int ret = -1; virDomainDeviceDefPtr dev = NULL; @@ -2217,7 +2219,7 @@ xenDaemonAttachDeviceFlags(virDomainPtr domain,
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1);
- if (domain->id < 0) { + if (minidef->id < 0) { /* Cannot modify live config if domain is inactive */ if (flags & VIR_DOMAIN_DEVICE_MODIFY_LIVE) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", @@ -2247,9 +2249,9 @@ xenDaemonAttachDeviceFlags(virDomainPtr domain, } }
- if (!(def = xenDaemonDomainFetch(domain->conn, - domain->id, - domain->name, + if (!(def = xenDaemonDomainFetch(conn, + minidef->id, + minidef->name, NULL))) goto cleanup;
@@ -2275,7 +2277,7 @@ xenDaemonAttachDeviceFlags(virDomainPtr domain, break;
case VIR_DOMAIN_DEVICE_NET: - if (xenFormatSxprNet(domain->conn, + if (xenFormatSxprNet(conn, dev->data.net, &buf, STREQ(def->os.type, "hvm") ? 1 : 0, @@ -2320,9 +2322,9 @@ xenDaemonAttachDeviceFlags(virDomainPtr domain,
sexpr = virBufferContentAndReset(&buf);
- if (virDomainXMLDevID(domain, dev, class, ref, sizeof(ref))) { + if (virDomainXMLDevID(conn, minidef, dev, class, ref, sizeof(ref))) { /* device doesn't exist, define it */ - ret = xend_op(domain->conn, domain->name, "op", "device_create", + ret = xend_op(conn, def->name, "op", "device_create", "config", sexpr, NULL); } else { if (dev->data.disk->device != VIR_DOMAIN_DISK_DEVICE_CDROM) { @@ -2330,7 +2332,7 @@ xenDaemonAttachDeviceFlags(virDomainPtr domain, _("target '%s' already exists"), target); } else { /* device exists, attempt to modify it */ - ret = xend_op(domain->conn, domain->name, "op", "device_configure", + ret = xend_op(conn, minidef->name, "op", "device_configure", "config", sexpr, "dev", ref, NULL); } } @@ -2355,11 +2357,12 @@ cleanup: * Returns 0 in case of success, -1 in case of failure. */ int -xenDaemonUpdateDeviceFlags(virDomainPtr domain, +xenDaemonUpdateDeviceFlags(virConnectPtr conn, + virDomainDefPtr minidef, const char *xml, unsigned int flags) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; char *sexpr = NULL; int ret = -1; virDomainDeviceDefPtr dev = NULL; @@ -2370,7 +2373,7 @@ xenDaemonUpdateDeviceFlags(virDomainPtr domain, virCheckFlags(VIR_DOMAIN_DEVICE_MODIFY_LIVE | VIR_DOMAIN_DEVICE_MODIFY_CONFIG, -1);
- if (domain->id < 0) { + if (minidef->id < 0) { /* Cannot modify live config if domain is inactive */ if (flags & VIR_DOMAIN_DEVICE_MODIFY_LIVE) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", @@ -2400,9 +2403,9 @@ xenDaemonUpdateDeviceFlags(virDomainPtr domain, } }
- if (!(def = xenDaemonDomainFetch(domain->conn, - domain->id, - domain->name, + if (!(def = xenDaemonDomainFetch(conn, + minidef->id, + minidef->name, NULL))) goto cleanup;
@@ -2428,13 +2431,13 @@ xenDaemonUpdateDeviceFlags(virDomainPtr domain,
sexpr = virBufferContentAndReset(&buf);
- if (virDomainXMLDevID(domain, dev, class, ref, sizeof(ref))) { + if (virDomainXMLDevID(conn, minidef, dev, class, ref, sizeof(ref))) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("requested device does not exist")); goto cleanup; } else { /* device exists, attempt to modify it */ - ret = xend_op(domain->conn, domain->name, "op", "device_configure", + ret = xend_op(conn, minidef->name, "op", "device_configure", "config", sexpr, "dev", ref, NULL); }
@@ -2456,11 +2459,12 @@ cleanup: * Returns 0 in case of success, -1 in case of failure. */ int -xenDaemonDetachDeviceFlags(virDomainPtr domain, +xenDaemonDetachDeviceFlags(virConnectPtr conn, + virDomainDefPtr minidef, const char *xml, unsigned int flags) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; char class[8], ref[80]; virDomainDeviceDefPtr dev = NULL; virDomainDefPtr def = NULL; @@ -2470,7 +2474,7 @@ xenDaemonDetachDeviceFlags(virDomainPtr domain,
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1);
- if (domain->id < 0) { + if (minidef->id < 0) { /* Cannot modify live config if domain is inactive */ if (flags & VIR_DOMAIN_DEVICE_MODIFY_LIVE) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", @@ -2500,9 +2504,9 @@ xenDaemonDetachDeviceFlags(virDomainPtr domain, } }
- if (!(def = xenDaemonDomainFetch(domain->conn, - domain->id, - domain->name, + if (!(def = xenDaemonDomainFetch(conn, + minidef->id, + minidef->name, NULL))) goto cleanup;
@@ -2510,7 +2514,7 @@ xenDaemonDetachDeviceFlags(virDomainPtr domain, VIR_DOMAIN_XML_INACTIVE))) goto cleanup;
- if (virDomainXMLDevID(domain, dev, class, ref, sizeof(ref))) + if (virDomainXMLDevID(conn, minidef, dev, class, ref, sizeof(ref))) goto cleanup;
if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) { @@ -2524,12 +2528,12 @@ xenDaemonDetachDeviceFlags(virDomainPtr domain, goto cleanup; } xendev = virBufferContentAndReset(&buf); - ret = xend_op(domain->conn, domain->name, "op", "device_configure", + ret = xend_op(conn, minidef->name, "op", "device_configure", "config", xendev, "dev", ref, NULL); VIR_FREE(xendev); } else { - ret = xend_op(domain->conn, domain->name, "op", "device_destroy", + ret = xend_op(conn, minidef->name, "op", "device_destroy", "type", class, "dev", ref, "force", "0", "rm_cfg", "1", NULL); } @@ -3334,13 +3338,14 @@ xenDaemonDomainBlockPeek(virDomainPtr domain, * Returns 0 in case of success, -1 in case of failure. */ static int -virDomainXMLDevID(virDomainPtr domain, +virDomainXMLDevID(virConnectPtr conn, + virDomainDefPtr def, virDomainDeviceDefPtr dev, char *class, char *ref, int ref_len) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; char *xref; char *tmp;
@@ -3357,7 +3362,7 @@ virDomainXMLDevID(virDomainPtr domain, if (dev->data.disk->dst == NULL) return -1; xenUnifiedLock(priv); - xref = xenStoreDomainGetDiskID(domain->conn, domain->id, + xref = xenStoreDomainGetDiskID(conn, def->id, dev->data.disk->dst); xenUnifiedUnlock(priv); if (xref == NULL) @@ -3369,13 +3374,13 @@ virDomainXMLDevID(virDomainPtr domain, return -1; } else if (dev->type == VIR_DOMAIN_DEVICE_NET) { char mac[VIR_MAC_STRING_BUFLEN]; - virDomainNetDefPtr def = dev->data.net; - virMacAddrFormat(&def->mac, mac); + virDomainNetDefPtr netdef = dev->data.net; + virMacAddrFormat(&netdef->mac, mac);
strcpy(class, "vif");
xenUnifiedLock(priv); - xref = xenStoreDomainGetNetworkID(domain->conn, domain->id, mac); + xref = xenStoreDomainGetNetworkID(conn, def->id, mac); xenUnifiedUnlock(priv); if (xref == NULL) return -1; @@ -3388,13 +3393,13 @@ virDomainXMLDevID(virDomainPtr domain, dev->data.hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && dev->data.hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) { char *bdf; - virDomainHostdevDefPtr def = dev->data.hostdev; + virDomainHostdevDefPtr hostdef = dev->data.hostdev;
if (virAsprintf(&bdf, "%04x:%02x:%02x.%0x", - def->source.subsys.u.pci.addr.domain, - def->source.subsys.u.pci.addr.bus, - def->source.subsys.u.pci.addr.slot, - def->source.subsys.u.pci.addr.function) < 0) { + hostdef->source.subsys.u.pci.addr.domain, + hostdef->source.subsys.u.pci.addr.bus, + hostdef->source.subsys.u.pci.addr.slot, + hostdef->source.subsys.u.pci.addr.function) < 0) { virReportOOMError(); return -1; } @@ -3402,7 +3407,7 @@ virDomainXMLDevID(virDomainPtr domain, strcpy(class, "pci");
xenUnifiedLock(priv); - xref = xenStoreDomainGetPCIID(domain->conn, domain->id, bdf); + xref = xenStoreDomainGetPCIID(conn, def->id, bdf); xenUnifiedUnlock(priv); VIR_FREE(bdf); if (xref == NULL) diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h index b78145c..62b85ef 100644 --- a/src/xen/xend_internal.h +++ b/src/xen/xend_internal.h @@ -126,10 +126,12 @@ int xenDaemonListDefinedDomains(virConnectPtr conn, char **const names, int maxnames);
-int xenDaemonAttachDeviceFlags(virDomainPtr domain, +int xenDaemonAttachDeviceFlags(virConnectPtr conn, + virDomainDefPtr def, const char *xml, unsigned int flags); -int xenDaemonDetachDeviceFlags(virDomainPtr domain, +int xenDaemonDetachDeviceFlags(virConnectPtr conn, + virDomainDefPtr def, const char *xml, unsigned int flags);
@@ -161,7 +163,9 @@ int xenDaemonDomainGetVcpus (virConnectPtr conn, int maxinfo, unsigned char *cpumaps, int maplen); -int xenDaemonUpdateDeviceFlags(virDomainPtr domain, const char *xml, +int xenDaemonUpdateDeviceFlags(virConnectPtr conn, + virDomainDefPtr def, + const char *xml, unsigned int flags); int xenDaemonDomainGetAutostart (virDomainPtr dom, int *autostart); diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c index 76425dd..c2d9915 100644 --- a/src/xen/xm_internal.c +++ b/src/xen/xm_internal.c @@ -1219,7 +1219,8 @@ cleanup: * Returns 0 in case of success, -1 in case of failure. */ int -xenXMDomainAttachDeviceFlags(virDomainPtr domain, +xenXMDomainAttachDeviceFlags(virConnectPtr conn, + virDomainDefPtr minidef, const char *xml, unsigned int flags) { @@ -1228,12 +1229,12 @@ xenXMDomainAttachDeviceFlags(virDomainPtr domain, int ret = -1; virDomainDeviceDefPtr dev = NULL; virDomainDefPtr def; - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData;
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1);
if ((flags & VIR_DOMAIN_DEVICE_MODIFY_LIVE) || - (domain->id != -1 && flags == VIR_DOMAIN_DEVICE_MODIFY_CURRENT)) { + (minidef->id != -1 && flags == VIR_DOMAIN_DEVICE_MODIFY_CURRENT)) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("Xm driver only supports modifying persistent config")); return -1; @@ -1241,7 +1242,7 @@ xenXMDomainAttachDeviceFlags(virDomainPtr domain,
xenUnifiedLock(priv);
- if (!(filename = virHashLookup(priv->nameConfigMap, domain->name))) + if (!(filename = virHashLookup(priv->nameConfigMap, minidef->name))) goto cleanup; if (!(entry = virHashLookup(priv->configCache, filename))) goto cleanup; @@ -1284,7 +1285,7 @@ xenXMDomainAttachDeviceFlags(virDomainPtr domain, /* If this fails, should we try to undo our changes to the * in-memory representation of the config file. I say not! */ - if (xenXMConfigSaveFile(domain->conn, entry->filename, entry->def) < 0) + if (xenXMConfigSaveFile(conn, entry->filename, entry->def) < 0) goto cleanup;
ret = 0; @@ -1309,7 +1310,8 @@ xenXMDomainAttachDeviceFlags(virDomainPtr domain, * Returns 0 in case of success, -1 in case of failure. */ int -xenXMDomainDetachDeviceFlags(virDomainPtr domain, +xenXMDomainDetachDeviceFlags(virConnectPtr conn, + virDomainDefPtr minidef, const char *xml, unsigned int flags) { @@ -1319,12 +1321,12 @@ xenXMDomainDetachDeviceFlags(virDomainPtr domain, virDomainDefPtr def; int ret = -1; int i; - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData;
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1);
if ((flags & VIR_DOMAIN_DEVICE_MODIFY_LIVE) || - (domain->id != -1 && flags == VIR_DOMAIN_DEVICE_MODIFY_CURRENT)) { + (minidef->id != -1 && flags == VIR_DOMAIN_DEVICE_MODIFY_CURRENT)) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("Xm driver only supports modifying persistent config")); return -1; @@ -1332,7 +1334,7 @@ xenXMDomainDetachDeviceFlags(virDomainPtr domain,
xenUnifiedLock(priv);
- if (!(filename = virHashLookup(priv->nameConfigMap, domain->name))) + if (!(filename = virHashLookup(priv->nameConfigMap, minidef->name))) goto cleanup; if (!(entry = virHashLookup(priv->configCache, filename))) goto cleanup; @@ -1390,7 +1392,7 @@ xenXMDomainDetachDeviceFlags(virDomainPtr domain, /* If this fails, should we try to undo our changes to the * in-memory representation of the config file. I say not! */ - if (xenXMConfigSaveFile(domain->conn, entry->filename, entry->def) < 0) + if (xenXMConfigSaveFile(conn, entry->filename, entry->def) < 0) goto cleanup;
ret = 0; diff --git a/src/xen/xm_internal.h b/src/xen/xm_internal.h index 28087d3..7d64dc6 100644 --- a/src/xen/xm_internal.h +++ b/src/xen/xm_internal.h @@ -85,11 +85,13 @@ int xenXMDomainBlockPeek (virDomainPtr dom, const char *path, unsigned long long int xenXMDomainGetAutostart(virDomainPtr dom, int *autostart); int xenXMDomainSetAutostart(virDomainPtr dom, int autostart);
-int xenXMDomainAttachDeviceFlags(virDomainPtr domain, +int xenXMDomainAttachDeviceFlags(virConnectPtr conn, + virDomainDefPtr def, const char *xml, unsigned int flags);
-int xenXMDomainDetachDeviceFlags(virDomainPtr domain, +int xenXMDomainDetachDeviceFlags(virConnectPtr conn, + virDomainDefPtr def, const char *xml, unsigned int flags);

From: "Daniel P. Berrange" <berrange@redhat.com> Introduce use of a virDomainDefPtr in the domain autostart APIs to simplify introduction of ACL security checks. The virDomainPtr cannot be safely used, since the app may have supplied mis-matching name/uuid/id fields. eg the name points to domain X, while the uuid points to domain Y. Resolving the virDomainPtr to a virDomainDefPtr ensures a consistent name/uuid/id set. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/xen/xen_driver.c | 26 ++++++++++++++++++++++---- src/xen/xend_internal.c | 14 +++++++++----- src/xen/xend_internal.h | 10 ++++++---- src/xen/xm_internal.c | 22 ++++++++++++---------- src/xen/xm_internal.h | 6 ++++-- 5 files changed, 53 insertions(+), 25 deletions(-) diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index f5f6407..43b3020 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -1811,22 +1811,40 @@ static int xenUnifiedDomainGetAutostart(virDomainPtr dom, int *autostart) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + virDomainDefPtr def = NULL; + int ret = -1; + + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainGetAutostart(dom, autostart); + ret = xenXMDomainGetAutostart(def, autostart); else - return xenDaemonDomainGetAutostart(dom, autostart); + ret = xenDaemonDomainGetAutostart(dom->conn, def, autostart); + +cleanup: + virDomainDefFree(def); + return ret; } static int xenUnifiedDomainSetAutostart(virDomainPtr dom, int autostart) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + virDomainDefPtr def = NULL; + int ret = -1; + + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainSetAutostart(dom, autostart); + ret = xenXMDomainSetAutostart(def, autostart); else - return xenDaemonDomainSetAutostart(dom, autostart); + ret = xenDaemonDomainSetAutostart(dom->conn, def, autostart); + +cleanup: + virDomainDefFree(def); + return ret; } static char * diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index 2715a3e..3d852d2 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -2546,12 +2546,14 @@ cleanup: } int -xenDaemonDomainGetAutostart(virDomainPtr domain, int *autostart) +xenDaemonDomainGetAutostart(virConnectPtr conn, + virDomainDefPtr def, + int *autostart) { struct sexpr *root; const char *tmp; - root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name); + root = sexpr_get(conn, "/xend/domain/%s?detail=1", def->name); if (root == NULL) { virReportError(VIR_ERR_XEN_CALL, "%s", _("xenDaemonGetAutostart failed to find this domain")); @@ -2570,14 +2572,16 @@ xenDaemonDomainGetAutostart(virDomainPtr domain, int *autostart) } int -xenDaemonDomainSetAutostart(virDomainPtr domain, int autostart) +xenDaemonDomainSetAutostart(virConnectPtr conn, + virDomainDefPtr def, + int autostart) { struct sexpr *root, *autonode; virBuffer buffer = VIR_BUFFER_INITIALIZER; char *content = NULL; int ret = -1; - root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name); + root = sexpr_get(conn, "/xend/domain/%s?detail=1", def->name); if (root == NULL) { virReportError(VIR_ERR_XEN_CALL, "%s", _("xenDaemonSetAutostart failed to find this domain")); @@ -2616,7 +2620,7 @@ xenDaemonDomainSetAutostart(virDomainPtr domain, int autostart) content = virBufferContentAndReset(&buffer); - if (xend_op(domain->conn, "", "op", "new", "config", content, NULL) != 0) { + if (xend_op(conn, "", "op", "new", "config", content, NULL) != 0) { virReportError(VIR_ERR_XEN_CALL, "%s", _("Failed to redefine sexpr")); goto error; diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h index 62b85ef..3a7c0ac 100644 --- a/src/xen/xend_internal.h +++ b/src/xen/xend_internal.h @@ -167,10 +167,12 @@ int xenDaemonUpdateDeviceFlags(virConnectPtr conn, virDomainDefPtr def, const char *xml, unsigned int flags); -int xenDaemonDomainGetAutostart (virDomainPtr dom, - int *autostart); -int xenDaemonDomainSetAutostart (virDomainPtr domain, - int autostart); +int xenDaemonDomainGetAutostart(virConnectPtr conn, + virDomainDefPtr def, + int *autostart); +int xenDaemonDomainSetAutostart(virConnectPtr conn, + virDomainDefPtr def, + int autostart); int xenDaemonCreateXML(virConnectPtr conn, virDomainDefPtr def); virDomainDefPtr xenDaemonLookupByUUID(virConnectPtr conn, const unsigned char *uuid); diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c index c2d9915..bc98cf1 100644 --- a/src/xen/xm_internal.c +++ b/src/xen/xm_internal.c @@ -1417,28 +1417,29 @@ xenXMDomainBlockPeek(virDomainPtr dom ATTRIBUTE_UNUSED, static char * -xenXMAutostartLinkName(virDomainPtr dom) +xenXMAutostartLinkName(virDomainDefPtr def) { char *ret; - if (virAsprintf(&ret, "/etc/xen/auto/%s", dom->name) < 0) + if (virAsprintf(&ret, "/etc/xen/auto/%s", def->name) < 0) return NULL; return ret; } static char * -xenXMDomainConfigName(virDomainPtr dom) +xenXMDomainConfigName(virDomainDefPtr def) { char *ret; - if (virAsprintf(&ret, "/etc/xen/%s", dom->name) < 0) + if (virAsprintf(&ret, "/etc/xen/%s", def->name) < 0) return NULL; return ret; } int -xenXMDomainGetAutostart(virDomainPtr dom, int *autostart) +xenXMDomainGetAutostart(virDomainDefPtr def, + int *autostart) { - char *linkname = xenXMAutostartLinkName(dom); - char *config = xenXMDomainConfigName(dom); + char *linkname = xenXMAutostartLinkName(def); + char *config = xenXMDomainConfigName(def); int ret = -1; if (!linkname || !config) { @@ -1464,10 +1465,11 @@ cleanup: int -xenXMDomainSetAutostart(virDomainPtr dom, int autostart) +xenXMDomainSetAutostart(virDomainDefPtr def, + int autostart) { - char *linkname = xenXMAutostartLinkName(dom); - char *config = xenXMDomainConfigName(dom); + char *linkname = xenXMAutostartLinkName(def); + char *config = xenXMDomainConfigName(def); int ret = -1; if (!linkname || !config) { diff --git a/src/xen/xm_internal.h b/src/xen/xm_internal.h index 7d64dc6..78cd15c 100644 --- a/src/xen/xm_internal.h +++ b/src/xen/xm_internal.h @@ -82,8 +82,10 @@ int xenXMDomainUndefine(virConnectPtr conn, virDomainDefPtr def); int xenXMDomainBlockPeek (virDomainPtr dom, const char *path, unsigned long long offset, size_t size, void *buffer); -int xenXMDomainGetAutostart(virDomainPtr dom, int *autostart); -int xenXMDomainSetAutostart(virDomainPtr dom, int autostart); +int xenXMDomainGetAutostart(virDomainDefPtr def, + int *autostart); +int xenXMDomainSetAutostart(virDomainDefPtr def, + int autostart); int xenXMDomainAttachDeviceFlags(virConnectPtr conn, virDomainDefPtr def, -- 1.8.1.4

Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Introduce use of a virDomainDefPtr in the domain autostart APIs to simplify introduction of ACL security checks. The virDomainPtr cannot be safely used, since the app may have supplied mis-matching name/uuid/id fields. eg the name points to domain X, while the uuid points to domain Y. Resolving the virDomainPtr to a virDomainDefPtr ensures a consistent name/uuid/id set.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/xen/xen_driver.c | 26 ++++++++++++++++++++++---- src/xen/xend_internal.c | 14 +++++++++----- src/xen/xend_internal.h | 10 ++++++---- src/xen/xm_internal.c | 22 ++++++++++++---------- src/xen/xm_internal.h | 6 ++++-- 5 files changed, 53 insertions(+), 25 deletions(-)
ACK. Regards, Jim
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index f5f6407..43b3020 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -1811,22 +1811,40 @@ static int xenUnifiedDomainGetAutostart(virDomainPtr dom, int *autostart) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + virDomainDefPtr def = NULL; + int ret = -1; + + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup;
if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainGetAutostart(dom, autostart); + ret = xenXMDomainGetAutostart(def, autostart); else - return xenDaemonDomainGetAutostart(dom, autostart); + ret = xenDaemonDomainGetAutostart(dom->conn, def, autostart); + +cleanup: + virDomainDefFree(def); + return ret; }
static int xenUnifiedDomainSetAutostart(virDomainPtr dom, int autostart) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + virDomainDefPtr def = NULL; + int ret = -1; + + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup;
if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainSetAutostart(dom, autostart); + ret = xenXMDomainSetAutostart(def, autostart); else - return xenDaemonDomainSetAutostart(dom, autostart); + ret = xenDaemonDomainSetAutostart(dom->conn, def, autostart); + +cleanup: + virDomainDefFree(def); + return ret; }
static char * diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index 2715a3e..3d852d2 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -2546,12 +2546,14 @@ cleanup: }
int -xenDaemonDomainGetAutostart(virDomainPtr domain, int *autostart) +xenDaemonDomainGetAutostart(virConnectPtr conn, + virDomainDefPtr def, + int *autostart) { struct sexpr *root; const char *tmp;
- root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name); + root = sexpr_get(conn, "/xend/domain/%s?detail=1", def->name); if (root == NULL) { virReportError(VIR_ERR_XEN_CALL, "%s", _("xenDaemonGetAutostart failed to find this domain")); @@ -2570,14 +2572,16 @@ xenDaemonDomainGetAutostart(virDomainPtr domain, int *autostart) }
int -xenDaemonDomainSetAutostart(virDomainPtr domain, int autostart) +xenDaemonDomainSetAutostart(virConnectPtr conn, + virDomainDefPtr def, + int autostart) { struct sexpr *root, *autonode; virBuffer buffer = VIR_BUFFER_INITIALIZER; char *content = NULL; int ret = -1;
- root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name); + root = sexpr_get(conn, "/xend/domain/%s?detail=1", def->name); if (root == NULL) { virReportError(VIR_ERR_XEN_CALL, "%s", _("xenDaemonSetAutostart failed to find this domain")); @@ -2616,7 +2620,7 @@ xenDaemonDomainSetAutostart(virDomainPtr domain, int autostart)
content = virBufferContentAndReset(&buffer);
- if (xend_op(domain->conn, "", "op", "new", "config", content, NULL) != 0) { + if (xend_op(conn, "", "op", "new", "config", content, NULL) != 0) { virReportError(VIR_ERR_XEN_CALL, "%s", _("Failed to redefine sexpr")); goto error; diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h index 62b85ef..3a7c0ac 100644 --- a/src/xen/xend_internal.h +++ b/src/xen/xend_internal.h @@ -167,10 +167,12 @@ int xenDaemonUpdateDeviceFlags(virConnectPtr conn, virDomainDefPtr def, const char *xml, unsigned int flags); -int xenDaemonDomainGetAutostart (virDomainPtr dom, - int *autostart); -int xenDaemonDomainSetAutostart (virDomainPtr domain, - int autostart); +int xenDaemonDomainGetAutostart(virConnectPtr conn, + virDomainDefPtr def, + int *autostart); +int xenDaemonDomainSetAutostart(virConnectPtr conn, + virDomainDefPtr def, + int autostart);
int xenDaemonCreateXML(virConnectPtr conn, virDomainDefPtr def); virDomainDefPtr xenDaemonLookupByUUID(virConnectPtr conn, const unsigned char *uuid); diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c index c2d9915..bc98cf1 100644 --- a/src/xen/xm_internal.c +++ b/src/xen/xm_internal.c @@ -1417,28 +1417,29 @@ xenXMDomainBlockPeek(virDomainPtr dom ATTRIBUTE_UNUSED,
static char * -xenXMAutostartLinkName(virDomainPtr dom) +xenXMAutostartLinkName(virDomainDefPtr def) { char *ret; - if (virAsprintf(&ret, "/etc/xen/auto/%s", dom->name) < 0) + if (virAsprintf(&ret, "/etc/xen/auto/%s", def->name) < 0) return NULL; return ret; }
static char * -xenXMDomainConfigName(virDomainPtr dom) +xenXMDomainConfigName(virDomainDefPtr def) { char *ret; - if (virAsprintf(&ret, "/etc/xen/%s", dom->name) < 0) + if (virAsprintf(&ret, "/etc/xen/%s", def->name) < 0) return NULL; return ret; }
int -xenXMDomainGetAutostart(virDomainPtr dom, int *autostart) +xenXMDomainGetAutostart(virDomainDefPtr def, + int *autostart) { - char *linkname = xenXMAutostartLinkName(dom); - char *config = xenXMDomainConfigName(dom); + char *linkname = xenXMAutostartLinkName(def); + char *config = xenXMDomainConfigName(def); int ret = -1;
if (!linkname || !config) { @@ -1464,10 +1465,11 @@ cleanup:
int -xenXMDomainSetAutostart(virDomainPtr dom, int autostart) +xenXMDomainSetAutostart(virDomainDefPtr def, + int autostart) { - char *linkname = xenXMAutostartLinkName(dom); - char *config = xenXMDomainConfigName(dom); + char *linkname = xenXMAutostartLinkName(def); + char *config = xenXMDomainConfigName(def); int ret = -1;
if (!linkname || !config) { diff --git a/src/xen/xm_internal.h b/src/xen/xm_internal.h index 7d64dc6..78cd15c 100644 --- a/src/xen/xm_internal.h +++ b/src/xen/xm_internal.h @@ -82,8 +82,10 @@ int xenXMDomainUndefine(virConnectPtr conn, virDomainDefPtr def);
int xenXMDomainBlockPeek (virDomainPtr dom, const char *path, unsigned long long offset, size_t size, void *buffer);
-int xenXMDomainGetAutostart(virDomainPtr dom, int *autostart); -int xenXMDomainSetAutostart(virDomainPtr dom, int autostart); +int xenXMDomainGetAutostart(virDomainDefPtr def, + int *autostart); +int xenXMDomainSetAutostart(virDomainDefPtr def, + int autostart);
int xenXMDomainAttachDeviceFlags(virConnectPtr conn, virDomainDefPtr def,

From: "Daniel P. Berrange" <berrange@redhat.com> Introduce use of a virDomainDefPtr in the domain scheduler APIs to simplify introduction of ACL security checks. The virDomainPtr cannot be safely used, since the app may have supplied mis-matching name/uuid/id fields. eg the name points to domain X, while the uuid points to domain Y. Resolving the virDomainPtr to a virDomainDefPtr ensures a consistent name/uuid/id set. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/xen/xen_driver.c | 45 ++++++++++++++++++++++++++++++++++++--------- src/xen/xen_hypervisor.c | 19 +++++++++++-------- src/xen/xen_hypervisor.h | 16 +++++++++------- src/xen/xend_internal.c | 27 +++++++++++++++------------ src/xen/xend_internal.h | 9 ++++++--- 5 files changed, 77 insertions(+), 39 deletions(-) diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 43b3020..5ab1a52 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -1851,17 +1851,26 @@ static char * xenUnifiedDomainGetSchedulerType(virDomainPtr dom, int *nparams) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + virDomainDefPtr def = NULL; + char *ret = NULL; + + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; if (dom->id < 0) { if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Cannot change scheduler parameters")); - return NULL; + goto cleanup; } - return xenDaemonGetSchedulerType(dom, nparams); + ret = xenDaemonGetSchedulerType(dom->conn, nparams); } else { - return xenHypervisorGetSchedulerType(dom, nparams); + ret = xenHypervisorGetSchedulerType(dom->conn, nparams); } + +cleanup: + virDomainDefFree(def); + return ret; } static int @@ -1871,19 +1880,28 @@ xenUnifiedDomainGetSchedulerParametersFlags(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 (dom->id < 0) { if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Cannot change scheduler parameters")); - return -1; + goto cleanup; } - return xenDaemonGetSchedulerParameters(dom, params, nparams); + ret = xenDaemonGetSchedulerParameters(dom->conn, def, params, nparams); } else { - return xenHypervisorGetSchedulerParameters(dom, params, nparams); + ret = xenHypervisorGetSchedulerParameters(dom->conn, def, params, nparams); } + +cleanup: + virDomainDefFree(def); + return ret; } static int @@ -1902,19 +1920,28 @@ xenUnifiedDomainSetSchedulerParametersFlags(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 (dom->id < 0) { if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Cannot change scheduler parameters")); - return -1; + goto cleanup; } - return xenDaemonSetSchedulerParameters(dom, params, nparams); + ret = xenDaemonSetSchedulerParameters(dom->conn, def, params, nparams); } else { - return xenHypervisorSetSchedulerParameters(dom, params, nparams); + ret = xenHypervisorSetSchedulerParameters(dom->conn, def, params, nparams); } + +cleanup: + virDomainDefFree(def); + return ret; } static int diff --git a/src/xen/xen_hypervisor.c b/src/xen/xen_hypervisor.c index b97b329..2525566 100644 --- a/src/xen/xen_hypervisor.c +++ b/src/xen/xen_hypervisor.c @@ -1113,10 +1113,11 @@ virXen_getdomaininfo(int handle, int first_domain, xen_getdomaininfo *dominfo) * Returns scheduler name or NULL in case of failure */ char * -xenHypervisorGetSchedulerType(virDomainPtr domain, int *nparams) +xenHypervisorGetSchedulerType(virConnectPtr conn, + int *nparams) { char *schedulertype = NULL; - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; /* * Support only hv_versions.dom_interface >=5 @@ -1176,11 +1177,12 @@ xenHypervisorGetSchedulerType(virDomainPtr domain, int *nparams) * Returns 0 or -1 in case of failure */ int -xenHypervisorGetSchedulerParameters(virDomainPtr domain, +xenHypervisorGetSchedulerParameters(virConnectPtr conn, + virDomainDefPtr def, virTypedParameterPtr params, int *nparams) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; /* * Support only hv_versions.dom_interface >=5 @@ -1218,7 +1220,7 @@ xenHypervisorGetSchedulerParameters(virDomainPtr domain, case XEN_SCHEDULER_CREDIT: memset(&op_dom, 0, sizeof(op_dom)); op_dom.cmd = XEN_V2_OP_SCHEDULER; - op_dom.domain = (domid_t) domain->id; + op_dom.domain = (domid_t) def->id; op_dom.u.getschedinfo.sched_id = XEN_SCHEDULER_CREDIT; op_dom.u.getschedinfo.cmd = XEN_DOMCTL_SCHEDOP_getinfo; ret = xenHypervisorDoV2Dom(priv->handle, &op_dom); @@ -1262,13 +1264,14 @@ xenHypervisorGetSchedulerParameters(virDomainPtr domain, * Returns 0 or -1 in case of failure */ int -xenHypervisorSetSchedulerParameters(virDomainPtr domain, +xenHypervisorSetSchedulerParameters(virConnectPtr conn, + virDomainDefPtr def, virTypedParameterPtr params, int nparams) { int i; unsigned int val; - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; char buf[256]; if (nparams == 0) { @@ -1313,7 +1316,7 @@ xenHypervisorSetSchedulerParameters(virDomainPtr domain, case XEN_SCHEDULER_CREDIT: { memset(&op_dom, 0, sizeof(op_dom)); op_dom.cmd = XEN_V2_OP_SCHEDULER; - op_dom.domain = (domid_t) domain->id; + op_dom.domain = (domid_t) def->id; op_dom.u.getschedinfo.sched_id = XEN_SCHEDULER_CREDIT; op_dom.u.getschedinfo.cmd = XEN_DOMCTL_SCHEDOP_putinfo; diff --git a/src/xen/xen_hypervisor.h b/src/xen/xen_hypervisor.h index 1cf1e14..1e5bb67 100644 --- a/src/xen/xen_hypervisor.h +++ b/src/xen/xen_hypervisor.h @@ -106,18 +106,20 @@ int xenHypervisorGetVcpuMax (virConnectPtr conn, virDomainDefPtr def) ATTRIBUTE_NONNULL (1); -char * xenHypervisorGetSchedulerType (virDomainPtr domain, +char * xenHypervisorGetSchedulerType (virConnectPtr conn, int *nparams) ATTRIBUTE_NONNULL (1); -int xenHypervisorGetSchedulerParameters(virDomainPtr domain, - virTypedParameterPtr params, - int *nparams) +int xenHypervisorGetSchedulerParameters(virConnectPtr conn, + virDomainDefPtr def, + virTypedParameterPtr params, + int *nparams) ATTRIBUTE_NONNULL (1); -int xenHypervisorSetSchedulerParameters(virDomainPtr domain, - virTypedParameterPtr params, - int nparams) +int xenHypervisorSetSchedulerParameters(virConnectPtr conn, + virDomainDefPtr def, + virTypedParameterPtr params, + int nparams) ATTRIBUTE_NONNULL (1); int xenHypervisorDomainBlockStats (virDomainPtr domain, diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index 3d852d2..3bcd19b 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -2972,9 +2972,10 @@ error: * caller or NULL in case of failure */ char * -xenDaemonGetSchedulerType(virDomainPtr domain, int *nparams) +xenDaemonGetSchedulerType(virConnectPtr conn, + int *nparams) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; struct sexpr *root; const char *ret = NULL; char *schedulertype = NULL; @@ -2986,7 +2987,7 @@ xenDaemonGetSchedulerType(virDomainPtr domain, int *nparams) return NULL; } - root = sexpr_get(domain->conn, "/xend/node/"); + root = sexpr_get(conn, "/xend/node/"); if (root == NULL) return NULL; @@ -3037,11 +3038,12 @@ error: * Returns 0 or -1 in case of failure */ int -xenDaemonGetSchedulerParameters(virDomainPtr domain, +xenDaemonGetSchedulerParameters(virConnectPtr conn, + virDomainDefPtr def, virTypedParameterPtr params, int *nparams) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; struct sexpr *root; char *sched_type = NULL; int sched_nparam = 0; @@ -3055,12 +3057,12 @@ xenDaemonGetSchedulerParameters(virDomainPtr domain, } /* look up the information by domain name */ - root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name); + root = sexpr_get(conn, "/xend/domain/%s?detail=1", def->name); if (root == NULL) return -1; /* get the scheduler type */ - sched_type = xenDaemonGetSchedulerType(domain, &sched_nparam); + sched_type = xenDaemonGetSchedulerType(conn, &sched_nparam); if (sched_type == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Failed to get a scheduler name")); @@ -3139,11 +3141,12 @@ error: * Returns 0 or -1 in case of failure */ int -xenDaemonSetSchedulerParameters(virDomainPtr domain, +xenDaemonSetSchedulerParameters(virConnectPtr conn, + virDomainDefPtr def, virTypedParameterPtr params, int nparams) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; struct sexpr *root; char *sched_type = NULL; int i; @@ -3158,12 +3161,12 @@ xenDaemonSetSchedulerParameters(virDomainPtr domain, } /* look up the information by domain name */ - root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name); + root = sexpr_get(conn, "/xend/domain/%s?detail=1", def->name); if (root == NULL) return -1; /* get the scheduler type */ - sched_type = xenDaemonGetSchedulerType(domain, &sched_nparam); + sched_type = xenDaemonGetSchedulerType(conn, &sched_nparam); if (sched_type == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Failed to get a scheduler name")); @@ -3217,7 +3220,7 @@ xenDaemonSetSchedulerParameters(virDomainPtr domain, snprintf(buf_cap, sizeof(buf_cap), "%s", cap); } - ret = xend_op(domain->conn, domain->name, "op", + ret = xend_op(conn, def->name, "op", "domain_sched_credit_set", "weight", buf_weight, "cap", buf_cap, NULL); break; diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h index 3a7c0ac..cef7da4 100644 --- a/src/xen/xend_internal.h +++ b/src/xen/xend_internal.h @@ -189,11 +189,14 @@ int xenDaemonDomainMigratePerform (virConnectPtr conn, int xenDaemonDomainBlockPeek (virDomainPtr domain, const char *path, unsigned long long offset, size_t size, void *buffer); -char * xenDaemonGetSchedulerType(virDomainPtr domain, int *nparams); -int xenDaemonGetSchedulerParameters(virDomainPtr domain, +char * xenDaemonGetSchedulerType(virConnectPtr conn, + int *nparams); +int xenDaemonGetSchedulerParameters(virConnectPtr conn, + virDomainDefPtr def, virTypedParameterPtr params, int *nparams); -int xenDaemonSetSchedulerParameters(virDomainPtr domain, +int xenDaemonSetSchedulerParameters(virConnectPtr conn, + virDomainDefPtr def, virTypedParameterPtr params, int nparams); -- 1.8.1.4

Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Introduce use of a virDomainDefPtr in the domain scheduler APIs to simplify introduction of ACL security checks. The virDomainPtr cannot be safely used, since the app may have supplied mis-matching name/uuid/id fields. eg the name points to domain X, while the uuid points to domain Y. Resolving the virDomainPtr to a virDomainDefPtr ensures a consistent name/uuid/id set.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/xen/xen_driver.c | 45 ++++++++++++++++++++++++++++++++++++--------- src/xen/xen_hypervisor.c | 19 +++++++++++-------- src/xen/xen_hypervisor.h | 16 +++++++++------- src/xen/xend_internal.c | 27 +++++++++++++++------------ src/xen/xend_internal.h | 9 ++++++--- 5 files changed, 77 insertions(+), 39 deletions(-)
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 43b3020..5ab1a52 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -1851,17 +1851,26 @@ static char * xenUnifiedDomainGetSchedulerType(virDomainPtr dom, int *nparams) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + virDomainDefPtr def = NULL; + char *ret = NULL; + + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup;
if (dom->id < 0) { if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Cannot change scheduler parameters")); - return NULL; + goto cleanup; } - return xenDaemonGetSchedulerType(dom, nparams); + ret = xenDaemonGetSchedulerType(dom->conn, nparams); } else { - return xenHypervisorGetSchedulerType(dom, nparams); + ret = xenHypervisorGetSchedulerType(dom->conn, nparams); } + +cleanup: + virDomainDefFree(def); + return ret; }
static int @@ -1871,19 +1880,28 @@ xenUnifiedDomainGetSchedulerParametersFlags(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 (dom->id < 0) { if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Cannot change scheduler parameters")); - return -1; + goto cleanup; } - return xenDaemonGetSchedulerParameters(dom, params, nparams); + ret = xenDaemonGetSchedulerParameters(dom->conn, def, params, nparams); } else { - return xenHypervisorGetSchedulerParameters(dom, params, nparams); + ret = xenHypervisorGetSchedulerParameters(dom->conn, def, params, nparams); } + +cleanup: + virDomainDefFree(def); + return ret; }
static int @@ -1902,19 +1920,28 @@ xenUnifiedDomainSetSchedulerParametersFlags(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 (dom->id < 0) { if (priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Cannot change scheduler parameters")); - return -1; + goto cleanup; } - return xenDaemonSetSchedulerParameters(dom, params, nparams); + ret = xenDaemonSetSchedulerParameters(dom->conn, def, params, nparams); } else { - return xenHypervisorSetSchedulerParameters(dom, params, nparams); + ret = xenHypervisorSetSchedulerParameters(dom->conn, def, params, nparams); } + +cleanup: + virDomainDefFree(def); + return ret; }
static int diff --git a/src/xen/xen_hypervisor.c b/src/xen/xen_hypervisor.c index b97b329..2525566 100644 --- a/src/xen/xen_hypervisor.c +++ b/src/xen/xen_hypervisor.c @@ -1113,10 +1113,11 @@ virXen_getdomaininfo(int handle, int first_domain, xen_getdomaininfo *dominfo) * Returns scheduler name or NULL in case of failure */ char * -xenHypervisorGetSchedulerType(virDomainPtr domain, int *nparams) +xenHypervisorGetSchedulerType(virConnectPtr conn, + int *nparams)
Still fits on one line. And function comments need updated here and where similar changes are made below.
{ char *schedulertype = NULL; - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData;
/* * Support only hv_versions.dom_interface >=5 @@ -1176,11 +1177,12 @@ xenHypervisorGetSchedulerType(virDomainPtr domain, int *nparams) * Returns 0 or -1 in case of failure */ int -xenHypervisorGetSchedulerParameters(virDomainPtr domain, +xenHypervisorGetSchedulerParameters(virConnectPtr conn, + virDomainDefPtr def, virTypedParameterPtr params, int *nparams) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData;
/* * Support only hv_versions.dom_interface >=5 @@ -1218,7 +1220,7 @@ xenHypervisorGetSchedulerParameters(virDomainPtr domain, case XEN_SCHEDULER_CREDIT: memset(&op_dom, 0, sizeof(op_dom)); op_dom.cmd = XEN_V2_OP_SCHEDULER; - op_dom.domain = (domid_t) domain->id; + op_dom.domain = (domid_t) def->id; op_dom.u.getschedinfo.sched_id = XEN_SCHEDULER_CREDIT; op_dom.u.getschedinfo.cmd = XEN_DOMCTL_SCHEDOP_getinfo; ret = xenHypervisorDoV2Dom(priv->handle, &op_dom); @@ -1262,13 +1264,14 @@ xenHypervisorGetSchedulerParameters(virDomainPtr domain, * Returns 0 or -1 in case of failure */ int -xenHypervisorSetSchedulerParameters(virDomainPtr domain, +xenHypervisorSetSchedulerParameters(virConnectPtr conn, + virDomainDefPtr def, virTypedParameterPtr params, int nparams) { int i; unsigned int val; - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; char buf[256];
if (nparams == 0) { @@ -1313,7 +1316,7 @@ xenHypervisorSetSchedulerParameters(virDomainPtr domain, case XEN_SCHEDULER_CREDIT: { memset(&op_dom, 0, sizeof(op_dom)); op_dom.cmd = XEN_V2_OP_SCHEDULER; - op_dom.domain = (domid_t) domain->id; + op_dom.domain = (domid_t) def->id; op_dom.u.getschedinfo.sched_id = XEN_SCHEDULER_CREDIT; op_dom.u.getschedinfo.cmd = XEN_DOMCTL_SCHEDOP_putinfo;
diff --git a/src/xen/xen_hypervisor.h b/src/xen/xen_hypervisor.h index 1cf1e14..1e5bb67 100644 --- a/src/xen/xen_hypervisor.h +++ b/src/xen/xen_hypervisor.h @@ -106,18 +106,20 @@ int xenHypervisorGetVcpuMax (virConnectPtr conn, virDomainDefPtr def) ATTRIBUTE_NONNULL (1);
-char * xenHypervisorGetSchedulerType (virDomainPtr domain, +char * xenHypervisorGetSchedulerType (virConnectPtr conn, int *nparams)
Is it better to fix this non-standard whitespace as the code is touched, or with one cleanup patch? This code rarely gets touched, so maybe the latter.
ATTRIBUTE_NONNULL (1);
-int xenHypervisorGetSchedulerParameters(virDomainPtr domain, - virTypedParameterPtr params, - int *nparams) +int xenHypervisorGetSchedulerParameters(virConnectPtr conn, + virDomainDefPtr def, + virTypedParameterPtr params, + int *nparams) ATTRIBUTE_NONNULL (1);
-int xenHypervisorSetSchedulerParameters(virDomainPtr domain, - virTypedParameterPtr params, - int nparams) +int xenHypervisorSetSchedulerParameters(virConnectPtr conn, + virDomainDefPtr def, + virTypedParameterPtr params, + int nparams) ATTRIBUTE_NONNULL (1);
int xenHypervisorDomainBlockStats (virDomainPtr domain, diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index 3d852d2..3bcd19b 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -2972,9 +2972,10 @@ error: * caller or NULL in case of failure */ char * -xenDaemonGetSchedulerType(virDomainPtr domain, int *nparams) +xenDaemonGetSchedulerType(virConnectPtr conn, + int *nparams)
Fits on one line, and comment update here and below. ACK. Regards, Jim
{ - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; struct sexpr *root; const char *ret = NULL; char *schedulertype = NULL; @@ -2986,7 +2987,7 @@ xenDaemonGetSchedulerType(virDomainPtr domain, int *nparams) return NULL; }
- root = sexpr_get(domain->conn, "/xend/node/"); + root = sexpr_get(conn, "/xend/node/"); if (root == NULL) return NULL;
@@ -3037,11 +3038,12 @@ error: * Returns 0 or -1 in case of failure */ int -xenDaemonGetSchedulerParameters(virDomainPtr domain, +xenDaemonGetSchedulerParameters(virConnectPtr conn, + virDomainDefPtr def, virTypedParameterPtr params, int *nparams) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; struct sexpr *root; char *sched_type = NULL; int sched_nparam = 0; @@ -3055,12 +3057,12 @@ xenDaemonGetSchedulerParameters(virDomainPtr domain, }
/* look up the information by domain name */ - root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name); + root = sexpr_get(conn, "/xend/domain/%s?detail=1", def->name); if (root == NULL) return -1;
/* get the scheduler type */ - sched_type = xenDaemonGetSchedulerType(domain, &sched_nparam); + sched_type = xenDaemonGetSchedulerType(conn, &sched_nparam); if (sched_type == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Failed to get a scheduler name")); @@ -3139,11 +3141,12 @@ error: * Returns 0 or -1 in case of failure */ int -xenDaemonSetSchedulerParameters(virDomainPtr domain, +xenDaemonSetSchedulerParameters(virConnectPtr conn, + virDomainDefPtr def, virTypedParameterPtr params, int nparams) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; struct sexpr *root; char *sched_type = NULL; int i; @@ -3158,12 +3161,12 @@ xenDaemonSetSchedulerParameters(virDomainPtr domain, }
/* look up the information by domain name */ - root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name); + root = sexpr_get(conn, "/xend/domain/%s?detail=1", def->name); if (root == NULL) return -1;
/* get the scheduler type */ - sched_type = xenDaemonGetSchedulerType(domain, &sched_nparam); + sched_type = xenDaemonGetSchedulerType(conn, &sched_nparam); if (sched_type == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Failed to get a scheduler name")); @@ -3217,7 +3220,7 @@ xenDaemonSetSchedulerParameters(virDomainPtr domain, snprintf(buf_cap, sizeof(buf_cap), "%s", cap); }
- ret = xend_op(domain->conn, domain->name, "op", + ret = xend_op(conn, def->name, "op", "domain_sched_credit_set", "weight", buf_weight, "cap", buf_cap, NULL); break; diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h index 3a7c0ac..cef7da4 100644 --- a/src/xen/xend_internal.h +++ b/src/xen/xend_internal.h @@ -189,11 +189,14 @@ int xenDaemonDomainMigratePerform (virConnectPtr conn,
int xenDaemonDomainBlockPeek (virDomainPtr domain, const char *path, unsigned long long offset, size_t size, void *buffer);
-char * xenDaemonGetSchedulerType(virDomainPtr domain, int *nparams); -int xenDaemonGetSchedulerParameters(virDomainPtr domain, +char * xenDaemonGetSchedulerType(virConnectPtr conn, + int *nparams); +int xenDaemonGetSchedulerParameters(virConnectPtr conn, + virDomainDefPtr def, virTypedParameterPtr params, int *nparams); -int xenDaemonSetSchedulerParameters(virDomainPtr domain, +int xenDaemonSetSchedulerParameters(virConnectPtr conn, + virDomainDefPtr def, virTypedParameterPtr params, int nparams);

From: "Daniel P. Berrange" <berrange@redhat.com> Introduce use of a virDomainDefPtr in the domain stats & peek APIs to simplify introduction of ACL security checks. The virDomainPtr cannot be safely used, since the app may have supplied mis-matching name/uuid/id fields. eg the name points to domain X, while the uuid points to domain Y. Resolving the virDomainPtr to a virDomainDefPtr ensures a consistent name/uuid/id set. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/xen/block_stats.c | 6 +++--- src/xen/block_stats.h | 2 +- src/xen/xen_driver.c | 37 +++++++++++++++++++++++++++++++++---- src/xen/xen_hypervisor.c | 11 ++++++----- src/xen/xen_hypervisor.h | 9 +++++---- src/xen/xend_internal.c | 21 +++++++++++---------- src/xen/xend_internal.h | 7 ++++++- src/xen/xm_internal.c | 3 ++- src/xen/xm_internal.h | 7 ++++++- 9 files changed, 73 insertions(+), 30 deletions(-) diff --git a/src/xen/block_stats.c b/src/xen/block_stats.c index ded8d7f..56a3901 100644 --- a/src/xen/block_stats.c +++ b/src/xen/block_stats.c @@ -359,16 +359,16 @@ xenLinuxDomainDeviceID(int domid, const char *path) int xenLinuxDomainBlockStats(xenUnifiedPrivatePtr priv, - virDomainPtr dom, + virDomainDefPtr def, const char *path, struct _virDomainBlockStats *stats) { - int device = xenLinuxDomainDeviceID(dom->id, path); + int device = xenLinuxDomainDeviceID(def->id, path); if (device < 0) return -1; - return read_bd_stats(priv, device, dom->id, stats); + return read_bd_stats(priv, device, def->id, stats); } #endif /* __linux__ */ diff --git a/src/xen/block_stats.h b/src/xen/block_stats.h index 0a3c40a..6633d97 100644 --- a/src/xen/block_stats.h +++ b/src/xen/block_stats.h @@ -28,7 +28,7 @@ # include "xen_driver.h" extern int xenLinuxDomainBlockStats (xenUnifiedPrivatePtr priv, - virDomainPtr dom, const char *path, + virDomainDefPtr def, const char *path, struct _virDomainBlockStats *stats); extern int xenLinuxDomainDeviceID(int domid, const char *dev); diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 5ab1a52..7c00b70 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -1957,14 +1957,34 @@ static int xenUnifiedDomainBlockStats(virDomainPtr dom, const char *path, struct _virDomainBlockStats *stats) { - return xenHypervisorDomainBlockStats(dom, path, stats); + virDomainDefPtr def = NULL; + int ret = -1; + + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + ret = xenHypervisorDomainBlockStats(dom->conn, def, path, stats); + +cleanup: + virDomainDefFree(def); + return ret; } static int xenUnifiedDomainInterfaceStats(virDomainPtr dom, const char *path, struct _virDomainInterfaceStats *stats) { - return xenHypervisorDomainInterfaceStats(dom, path, stats); + virDomainDefPtr def = NULL; + int ret = -1; + + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + ret = xenHypervisorDomainInterfaceStats(def, path, stats); + +cleanup: + virDomainDefFree(def); + return ret; } static int @@ -1973,13 +1993,22 @@ xenUnifiedDomainBlockPeek(virDomainPtr dom, const char *path, void *buffer, unsigned int flags) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + virDomainDefPtr def = NULL; + int ret = -1; virCheckFlags(0, -1); + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + if (dom->id < 0 && priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainBlockPeek(dom, path, offset, size, buffer); + ret = xenXMDomainBlockPeek(dom->conn, def, path, offset, size, buffer); else - return xenDaemonDomainBlockPeek(dom, path, offset, size, buffer); + ret = xenDaemonDomainBlockPeek(dom->conn, def, path, offset, size, buffer); + +cleanup: + virDomainDefFree(def); + return ret; } static int diff --git a/src/xen/xen_hypervisor.c b/src/xen/xen_hypervisor.c index 2525566..612ac77 100644 --- a/src/xen/xen_hypervisor.c +++ b/src/xen/xen_hypervisor.c @@ -1368,17 +1368,18 @@ xenHypervisorSetSchedulerParameters(virConnectPtr conn, int -xenHypervisorDomainBlockStats(virDomainPtr dom, +xenHypervisorDomainBlockStats(virConnectPtr conn, + virDomainDefPtr def, const char *path, struct _virDomainBlockStats *stats) { #ifdef __linux__ - xenUnifiedPrivatePtr priv = dom->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; int ret; xenUnifiedLock(priv); /* Need to lock because it hits the xenstore handle :-( */ - ret = xenLinuxDomainBlockStats(priv, dom, path, stats); + ret = xenLinuxDomainBlockStats(priv, def, path, stats); xenUnifiedUnlock(priv); return ret; #else @@ -1396,7 +1397,7 @@ xenHypervisorDomainBlockStats(virDomainPtr dom, * virNetwork interface, as yet not decided. */ int -xenHypervisorDomainInterfaceStats(virDomainPtr dom, +xenHypervisorDomainInterfaceStats(virDomainDefPtr def, const char *path, struct _virDomainInterfaceStats *stats) { @@ -1411,7 +1412,7 @@ xenHypervisorDomainInterfaceStats(virDomainPtr dom, _("invalid path, should be vif<domid>.<n>.")); return -1; } - if (rqdomid != dom->id) { + if (rqdomid != def->id) { virReportError(VIR_ERR_INVALID_ARG, "%s", _("invalid path, vif<domid> should match this domain ID")); return -1; diff --git a/src/xen/xen_hypervisor.h b/src/xen/xen_hypervisor.h index 1e5bb67..6aeab79 100644 --- a/src/xen/xen_hypervisor.h +++ b/src/xen/xen_hypervisor.h @@ -122,13 +122,14 @@ int xenHypervisorSetSchedulerParameters(virConnectPtr conn, int nparams) ATTRIBUTE_NONNULL (1); -int xenHypervisorDomainBlockStats (virDomainPtr domain, +int xenHypervisorDomainBlockStats (virConnectPtr conn, + virDomainDefPtr def, const char *path, struct _virDomainBlockStats *stats) ATTRIBUTE_NONNULL (1); -int xenHypervisorDomainInterfaceStats (virDomainPtr domain, - const char *path, - struct _virDomainInterfaceStats *stats) +int xenHypervisorDomainInterfaceStats (virDomainDefPtr def, + const char *path, + struct _virDomainInterfaceStats *stats) ATTRIBUTE_NONNULL (1); int xenHypervisorNodeGetCellsFreeMemory(virConnectPtr conn, diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index 3bcd19b..273408d 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -3247,13 +3247,14 @@ error: * Returns 0 if successful, -1 if error */ int -xenDaemonDomainBlockPeek(virDomainPtr domain, +xenDaemonDomainBlockPeek(virConnectPtr conn, + virDomainDefPtr minidef, const char *path, unsigned long long offset, size_t size, void *buffer) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; struct sexpr *root = NULL; int fd = -1, ret = -1; virDomainDefPtr def; @@ -3263,12 +3264,12 @@ xenDaemonDomainBlockPeek(virDomainPtr domain, const char *actual; /* Security check: The path must correspond to a block device. */ - if (domain->id > 0) - root = sexpr_get(domain->conn, "/xend/domain/%d?detail=1", - domain->id); - else if (domain->id < 0) - root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", - domain->name); + if (minidef->id > 0) + root = sexpr_get(conn, "/xend/domain/%d?detail=1", + minidef->id); + else if (minidef->id < 0) + root = sexpr_get(conn, "/xend/domain/%s?detail=1", + minidef->name); else { /* This call always fails for dom0. */ virReportError(VIR_ERR_OPERATION_INVALID, @@ -3283,8 +3284,8 @@ xenDaemonDomainBlockPeek(virDomainPtr domain, id = xenGetDomIdFromSxpr(root, priv->xendConfigVersion); xenUnifiedLock(priv); - tty = xenStoreDomainGetConsolePath(domain->conn, id); - vncport = xenStoreDomainGetVNCPort(domain->conn, id); + tty = xenStoreDomainGetConsolePath(conn, id); + vncport = xenStoreDomainGetVNCPort(conn, id); xenUnifiedUnlock(priv); if (!(def = xenParseSxpr(root, priv->xendConfigVersion, NULL, tty, diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h index cef7da4..aa05130 100644 --- a/src/xen/xend_internal.h +++ b/src/xen/xend_internal.h @@ -187,7 +187,12 @@ int xenDaemonDomainMigratePerform (virConnectPtr conn, 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); +int xenDaemonDomainBlockPeek(virConnectPtr conn, + virDomainDefPtr def, + const char *path, + unsigned long long offset, + size_t size, + void *buffer); char * xenDaemonGetSchedulerType(virConnectPtr conn, int *nparams); diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c index bc98cf1..740c4df 100644 --- a/src/xen/xm_internal.c +++ b/src/xen/xm_internal.c @@ -1404,7 +1404,8 @@ xenXMDomainDetachDeviceFlags(virConnectPtr conn, } int -xenXMDomainBlockPeek(virDomainPtr dom ATTRIBUTE_UNUSED, +xenXMDomainBlockPeek(virConnectPtr conn ATTRIBUTE_UNUSED, + virDomainDefPtr def ATTRIBUTE_UNUSED, const char *path ATTRIBUTE_UNUSED, unsigned long long offset ATTRIBUTE_UNUSED, size_t size ATTRIBUTE_UNUSED, diff --git a/src/xen/xm_internal.h b/src/xen/xm_internal.h index 78cd15c..25b4fd5 100644 --- a/src/xen/xm_internal.h +++ b/src/xen/xm_internal.h @@ -80,7 +80,12 @@ int xenXMDomainCreate(virConnectPtr conn, 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); +int xenXMDomainBlockPeek(virConnectPtr conn, + virDomainDefPtr def, + const char *path, + unsigned long long offset, + size_t size, + void *buffer); int xenXMDomainGetAutostart(virDomainDefPtr def, int *autostart); -- 1.8.1.4

Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Introduce use of a virDomainDefPtr in the domain stats & peek APIs to simplify introduction of ACL security checks. The virDomainPtr cannot be safely used, since the app may have supplied mis-matching name/uuid/id fields. eg the name points to domain X, while the uuid points to domain Y. Resolving the virDomainPtr to a virDomainDefPtr ensures a consistent name/uuid/id set.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/xen/block_stats.c | 6 +++--- src/xen/block_stats.h | 2 +- src/xen/xen_driver.c | 37 +++++++++++++++++++++++++++++++++---- src/xen/xen_hypervisor.c | 11 ++++++----- src/xen/xen_hypervisor.h | 9 +++++---- src/xen/xend_internal.c | 21 +++++++++++---------- src/xen/xend_internal.h | 7 ++++++- src/xen/xm_internal.c | 3 ++- src/xen/xm_internal.h | 7 ++++++- 9 files changed, 73 insertions(+), 30 deletions(-)
diff --git a/src/xen/block_stats.c b/src/xen/block_stats.c index ded8d7f..56a3901 100644 --- a/src/xen/block_stats.c +++ b/src/xen/block_stats.c @@ -359,16 +359,16 @@ xenLinuxDomainDeviceID(int domid, const char *path)
int xenLinuxDomainBlockStats(xenUnifiedPrivatePtr priv, - virDomainPtr dom, + virDomainDefPtr def, const char *path, struct _virDomainBlockStats *stats) { - int device = xenLinuxDomainDeviceID(dom->id, path); + int device = xenLinuxDomainDeviceID(def->id, path);
if (device < 0) return -1;
- return read_bd_stats(priv, device, dom->id, stats); + return read_bd_stats(priv, device, def->id, stats); }
#endif /* __linux__ */ diff --git a/src/xen/block_stats.h b/src/xen/block_stats.h index 0a3c40a..6633d97 100644 --- a/src/xen/block_stats.h +++ b/src/xen/block_stats.h @@ -28,7 +28,7 @@ # include "xen_driver.h"
extern int xenLinuxDomainBlockStats (xenUnifiedPrivatePtr priv, - virDomainPtr dom, const char *path, + virDomainDefPtr def, const char *path, struct _virDomainBlockStats *stats);
extern int xenLinuxDomainDeviceID(int domid, const char *dev); diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 5ab1a52..7c00b70 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -1957,14 +1957,34 @@ static int xenUnifiedDomainBlockStats(virDomainPtr dom, const char *path, struct _virDomainBlockStats *stats) { - return xenHypervisorDomainBlockStats(dom, path, stats); + virDomainDefPtr def = NULL; + int ret = -1; + + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + ret = xenHypervisorDomainBlockStats(dom->conn, def, path, stats); + +cleanup: + virDomainDefFree(def); + return ret; }
static int xenUnifiedDomainInterfaceStats(virDomainPtr dom, const char *path, struct _virDomainInterfaceStats *stats) { - return xenHypervisorDomainInterfaceStats(dom, path, stats); + virDomainDefPtr def = NULL; + int ret = -1; + + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + ret = xenHypervisorDomainInterfaceStats(def, path, stats); + +cleanup: + virDomainDefFree(def); + return ret; }
static int @@ -1973,13 +1993,22 @@ xenUnifiedDomainBlockPeek(virDomainPtr dom, const char *path, void *buffer, unsigned int flags) { xenUnifiedPrivatePtr priv = dom->conn->privateData; + virDomainDefPtr def = NULL; + int ret = -1;
virCheckFlags(0, -1);
+ if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + if (dom->id < 0 && priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return xenXMDomainBlockPeek(dom, path, offset, size, buffer); + ret = xenXMDomainBlockPeek(dom->conn, def, path, offset, size, buffer); else - return xenDaemonDomainBlockPeek(dom, path, offset, size, buffer); + ret = xenDaemonDomainBlockPeek(dom->conn, def, path, offset, size, buffer); + +cleanup: + virDomainDefFree(def); + return ret; }
static int diff --git a/src/xen/xen_hypervisor.c b/src/xen/xen_hypervisor.c index 2525566..612ac77 100644 --- a/src/xen/xen_hypervisor.c +++ b/src/xen/xen_hypervisor.c @@ -1368,17 +1368,18 @@ xenHypervisorSetSchedulerParameters(virConnectPtr conn,
int -xenHypervisorDomainBlockStats(virDomainPtr dom, +xenHypervisorDomainBlockStats(virConnectPtr conn, + virDomainDefPtr def, const char *path, struct _virDomainBlockStats *stats) { #ifdef __linux__ - xenUnifiedPrivatePtr priv = dom->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; int ret;
xenUnifiedLock(priv); /* Need to lock because it hits the xenstore handle :-( */ - ret = xenLinuxDomainBlockStats(priv, dom, path, stats); + ret = xenLinuxDomainBlockStats(priv, def, path, stats); xenUnifiedUnlock(priv); return ret; #else @@ -1396,7 +1397,7 @@ xenHypervisorDomainBlockStats(virDomainPtr dom, * virNetwork interface, as yet not decided. */ int -xenHypervisorDomainInterfaceStats(virDomainPtr dom, +xenHypervisorDomainInterfaceStats(virDomainDefPtr def, const char *path, struct _virDomainInterfaceStats *stats) { @@ -1411,7 +1412,7 @@ xenHypervisorDomainInterfaceStats(virDomainPtr dom, _("invalid path, should be vif<domid>.<n>.")); return -1; } - if (rqdomid != dom->id) { + if (rqdomid != def->id) { virReportError(VIR_ERR_INVALID_ARG, "%s", _("invalid path, vif<domid> should match this domain ID")); return -1; diff --git a/src/xen/xen_hypervisor.h b/src/xen/xen_hypervisor.h index 1e5bb67..6aeab79 100644 --- a/src/xen/xen_hypervisor.h +++ b/src/xen/xen_hypervisor.h @@ -122,13 +122,14 @@ int xenHypervisorSetSchedulerParameters(virConnectPtr conn, int nparams) ATTRIBUTE_NONNULL (1);
-int xenHypervisorDomainBlockStats (virDomainPtr domain, +int xenHypervisorDomainBlockStats (virConnectPtr conn, + virDomainDefPtr def, const char *path, struct _virDomainBlockStats *stats) ATTRIBUTE_NONNULL (1); -int xenHypervisorDomainInterfaceStats (virDomainPtr domain, - const char *path, - struct _virDomainInterfaceStats *stats) +int xenHypervisorDomainInterfaceStats (virDomainDefPtr def, + const char *path, + struct _virDomainInterfaceStats *stats) ATTRIBUTE_NONNULL (1);
int xenHypervisorNodeGetCellsFreeMemory(virConnectPtr conn, diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index 3bcd19b..273408d 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -3247,13 +3247,14 @@ error: * Returns 0 if successful, -1 if error */ int -xenDaemonDomainBlockPeek(virDomainPtr domain, +xenDaemonDomainBlockPeek(virConnectPtr conn, + virDomainDefPtr minidef,
Function comments need updated. ACK. Regards, Jim
const char *path, unsigned long long offset, size_t size, void *buffer) { - xenUnifiedPrivatePtr priv = domain->conn->privateData; + xenUnifiedPrivatePtr priv = conn->privateData; struct sexpr *root = NULL; int fd = -1, ret = -1; virDomainDefPtr def; @@ -3263,12 +3264,12 @@ xenDaemonDomainBlockPeek(virDomainPtr domain, const char *actual;
/* Security check: The path must correspond to a block device. */ - if (domain->id > 0) - root = sexpr_get(domain->conn, "/xend/domain/%d?detail=1", - domain->id); - else if (domain->id < 0) - root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", - domain->name); + if (minidef->id > 0) + root = sexpr_get(conn, "/xend/domain/%d?detail=1", + minidef->id); + else if (minidef->id < 0) + root = sexpr_get(conn, "/xend/domain/%s?detail=1", + minidef->name); else { /* This call always fails for dom0. */ virReportError(VIR_ERR_OPERATION_INVALID, @@ -3283,8 +3284,8 @@ xenDaemonDomainBlockPeek(virDomainPtr domain,
id = xenGetDomIdFromSxpr(root, priv->xendConfigVersion); xenUnifiedLock(priv); - tty = xenStoreDomainGetConsolePath(domain->conn, id); - vncport = xenStoreDomainGetVNCPort(domain->conn, id); + tty = xenStoreDomainGetConsolePath(conn, id); + vncport = xenStoreDomainGetVNCPort(conn, id); xenUnifiedUnlock(priv);
if (!(def = xenParseSxpr(root, priv->xendConfigVersion, NULL, tty, diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h index cef7da4..aa05130 100644 --- a/src/xen/xend_internal.h +++ b/src/xen/xend_internal.h @@ -187,7 +187,12 @@ int xenDaemonDomainMigratePerform (virConnectPtr conn, 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); +int xenDaemonDomainBlockPeek(virConnectPtr conn, + virDomainDefPtr def, + const char *path, + unsigned long long offset, + size_t size, + void *buffer);
char * xenDaemonGetSchedulerType(virConnectPtr conn, int *nparams); diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c index bc98cf1..740c4df 100644 --- a/src/xen/xm_internal.c +++ b/src/xen/xm_internal.c @@ -1404,7 +1404,8 @@ xenXMDomainDetachDeviceFlags(virConnectPtr conn, }
int -xenXMDomainBlockPeek(virDomainPtr dom ATTRIBUTE_UNUSED, +xenXMDomainBlockPeek(virConnectPtr conn ATTRIBUTE_UNUSED, + virDomainDefPtr def ATTRIBUTE_UNUSED, const char *path ATTRIBUTE_UNUSED, unsigned long long offset ATTRIBUTE_UNUSED, size_t size ATTRIBUTE_UNUSED, diff --git a/src/xen/xm_internal.h b/src/xen/xm_internal.h index 78cd15c..25b4fd5 100644 --- a/src/xen/xm_internal.h +++ b/src/xen/xm_internal.h @@ -80,7 +80,12 @@ int xenXMDomainCreate(virConnectPtr conn, 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); +int xenXMDomainBlockPeek(virConnectPtr conn, + virDomainDefPtr def, + const char *path, + unsigned long long offset, + size_t size, + void *buffer);
int xenXMDomainGetAutostart(virDomainDefPtr def, int *autostart);

From: "Daniel P. Berrange" <berrange@redhat.com> Introduce use of a virDomainDefPtr in the domain coredump APIs to simplify introduction of ACL security checks. The virDomainPtr cannot be safely used, since the app may have supplied mis-matching name/uuid/id fields. eg the name points to domain X, while the uuid points to domain Y. Resolving the virDomainPtr to a virDomainDefPtr ensures a consistent name/uuid/id set. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/xen/xen_driver.c | 14 +++++++++++++- src/xen/xend_internal.c | 9 +++++---- src/xen/xend_internal.h | 4 +++- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 7c00b70..a6c87ce 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -1193,7 +1193,19 @@ xenUnifiedDomainRestore(virConnectPtr conn, const char *from) static int xenUnifiedDomainCoreDump(virDomainPtr dom, const char *to, unsigned int flags) { - return xenDaemonDomainCoreDump(dom, to, flags); + virDomainDefPtr def = NULL; + int ret = -1; + + virCheckFlags(0, -1); + + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + ret = xenDaemonDomainCoreDump(dom->conn, def, to, flags); + +cleanup: + virDomainDefFree(def); + return ret; } static int diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index 273408d..8dc1a2d 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -1447,19 +1447,20 @@ xenDaemonDomainSave(virConnectPtr conn, * Returns 0 in case of success, -1 in case of error. */ int -xenDaemonDomainCoreDump(virDomainPtr domain, +xenDaemonDomainCoreDump(virConnectPtr conn, + virDomainDefPtr def, const char *filename, unsigned int flags) { virCheckFlags(VIR_DUMP_LIVE | VIR_DUMP_CRASH, -1); - if (domain->id < 0) { + if (def->id < 0) { virReportError(VIR_ERR_OPERATION_INVALID, - _("Domain %s isn't running."), domain->name); + _("Domain %s isn't running."), def->name); return -1; } - return xend_op(domain->conn, domain->name, + return xend_op(conn, def->name, "op", "dump", "file", filename, "live", (flags & VIR_DUMP_LIVE ? "1" : "0"), "crash", (flags & VIR_DUMP_CRASH ? "1" : "0"), diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h index aa05130..b2d4368 100644 --- a/src/xen/xend_internal.h +++ b/src/xen/xend_internal.h @@ -95,7 +95,9 @@ int xenDaemonDomainDestroy(virConnectPtr conn, virDomainDefPtr def); int xenDaemonDomainSave(virConnectPtr conn, virDomainDefPtr def, const char *filename); -int xenDaemonDomainCoreDump(virDomainPtr domain, const char *filename, +int xenDaemonDomainCoreDump(virConnectPtr conn, + virDomainDefPtr def, + const char *filename, unsigned int flags); int xenDaemonDomainRestore(virConnectPtr conn, const char *filename); int xenDaemonDomainSetMemory(virConnectPtr conn, -- 1.8.1.4

Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Introduce use of a virDomainDefPtr in the domain coredump APIs to simplify introduction of ACL security checks. The virDomainPtr cannot be safely used, since the app may have supplied mis-matching name/uuid/id fields. eg the name points to domain X, while the uuid points to domain Y. Resolving the virDomainPtr to a virDomainDefPtr ensures a consistent name/uuid/id set.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/xen/xen_driver.c | 14 +++++++++++++- src/xen/xend_internal.c | 9 +++++---- src/xen/xend_internal.h | 4 +++- 3 files changed, 21 insertions(+), 6 deletions(-)
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 7c00b70..a6c87ce 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -1193,7 +1193,19 @@ xenUnifiedDomainRestore(virConnectPtr conn, const char *from) static int xenUnifiedDomainCoreDump(virDomainPtr dom, const char *to, unsigned int flags) { - return xenDaemonDomainCoreDump(dom, to, flags); + virDomainDefPtr def = NULL; + int ret = -1; + + virCheckFlags(0, -1); + + if (!(def = xenGetDomainDefForDom(dom))) + goto cleanup; + + ret = xenDaemonDomainCoreDump(dom->conn, def, to, flags); + +cleanup: + virDomainDefFree(def); + return ret; }
static int diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index 273408d..8dc1a2d 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -1447,19 +1447,20 @@ xenDaemonDomainSave(virConnectPtr conn, * Returns 0 in case of success, -1 in case of error. */ int -xenDaemonDomainCoreDump(virDomainPtr domain, +xenDaemonDomainCoreDump(virConnectPtr conn, + virDomainDefPtr def,
Comments need updated. ACK. Regards, Jim
const char *filename, unsigned int flags) { virCheckFlags(VIR_DUMP_LIVE | VIR_DUMP_CRASH, -1);
- if (domain->id < 0) { + if (def->id < 0) { virReportError(VIR_ERR_OPERATION_INVALID, - _("Domain %s isn't running."), domain->name); + _("Domain %s isn't running."), def->name); return -1; }
- return xend_op(domain->conn, domain->name, + return xend_op(conn, def->name, "op", "dump", "file", filename, "live", (flags & VIR_DUMP_LIVE ? "1" : "0"), "crash", (flags & VIR_DUMP_CRASH ? "1" : "0"), diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h index aa05130..b2d4368 100644 --- a/src/xen/xend_internal.h +++ b/src/xen/xend_internal.h @@ -95,7 +95,9 @@ int xenDaemonDomainDestroy(virConnectPtr conn, virDomainDefPtr def); int xenDaemonDomainSave(virConnectPtr conn, virDomainDefPtr def, const char *filename); -int xenDaemonDomainCoreDump(virDomainPtr domain, const char *filename, +int xenDaemonDomainCoreDump(virConnectPtr conn, + virDomainDefPtr def, + const char *filename, unsigned int flags); int xenDaemonDomainRestore(virConnectPtr conn, const char *filename); int xenDaemonDomainSetMemory(virConnectPtr conn,
participants (4)
-
Daniel P. Berrange
-
Jim Fehlig
-
John Ferlan
-
Michal Privoznik