From 73b9977140272cbfd1d5386bb3880419be87a346 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Fri, 2 Mar 2012 17:47:16 -0700 Subject: [PATCH] xml: use long long internally, to centralize overflow checks On 64-bit platforms, unsigned long and unsigned long long are identical, so we don't have to worry about overflow checks. On 32-bit platforms, anywhere we narrow unsigned long long back to unsigned long, we have to worry about overflow; it's easier to do this in one place by having most of the code use the same or wider types, and only doing the narrowing at the last minute. Therefore, the memory set commands remain unsigned long, and the memory get command now centralizes the overflow check into libvirt.c, so that drivers don't have to repeat the work. This also fixes a bug where xen returned the wrong value on failure (most APIs return -1 on failure, but getMaxMemory must return 0 on failure). * src/driver.h (virDrvDomainGetMaxMemory): Use long long. * src/libvirt.c (virDomainGetMaxMemory): Raise overflow. * src/test/test_driver.c (testGetMaxMemory): Fix driver. * src/rpc/gendispatch.pl (name_to_ProcName): Likewise. * src/xen/xen_hypervisor.c (xenHypervisorGetMaxMemory): Likewise. * src/xen/xen_driver.c (xenUnifiedDomainGetMaxMemory): Likewise. * src/xen/xend_internal.c (xenDaemonDomainGetMaxMemory): Likewise. * src/xen/xend_internal.h (xenDaemonDomainGetMaxMemory): Likewise. * src/xen/xm_internal.c (xenXMDomainGetMaxMemory): Likewise. * src/xen/xm_internal.h (xenXMDomainGetMaxMemory): Likewise. * src/xen/xs_internal.c (xenStoreDomainGetMaxMemory): Likewise. * src/xen/xs_internal.h (xenStoreDomainGetMaxMemory): Likewise. * src/xenapi/xenapi_driver.c (xenapiDomainGetMaxMemory): Likewise. * src/esx/esx_driver.c (esxDomainGetMaxMemory): Likewise. * src/libxl/libxl_driver.c (libxlDomainGetMaxMemory): Likewise. * src/qemu/qemu_driver.c (qemudDomainGetMaxMemory): Likewise. * src/lxc/lxc_driver.c (lxcDomainGetMaxMemory): Likewise. * src/uml/uml_driver.c (umlDomainGetMaxMemory): Likewise. --- src/driver.h | 2 +- src/esx/esx_driver.c | 4 ++-- src/libvirt.c | 7 ++++++- src/libxl/libxl_driver.c | 8 ++++---- src/lxc/lxc_driver.c | 6 ++++-- src/qemu/qemu_driver.c | 8 +++++--- src/rpc/gendispatch.pl | 1 - src/test/test_driver.c | 4 ++-- src/uml/uml_driver.c | 6 ++++-- src/xen/xen_driver.c | 6 +++--- src/xen/xen_hypervisor.c | 4 ++-- src/xen/xend_internal.c | 16 ++++++++-------- src/xen/xend_internal.h | 4 ++-- src/xen/xm_internal.c | 6 +++--- src/xen/xm_internal.h | 4 ++-- src/xen/xs_internal.c | 10 +++++----- src/xen/xs_internal.h | 4 ++-- src/xenapi/xenapi_driver.c | 6 +++--- 18 files changed, 58 insertions(+), 48 deletions(-) diff --git a/src/driver.h b/src/driver.h index 212d2f5e76..03d249b7ae 100644 --- a/src/driver.h +++ b/src/driver.h @@ -142,7 +142,7 @@ typedef int unsigned int flags); typedef char * (*virDrvDomainGetOSType) (virDomainPtr domain); -typedef unsigned long +typedef unsigned long long (*virDrvDomainGetMaxMemory) (virDomainPtr domain); typedef int (*virDrvDomainSetMaxMemory) (virDomainPtr domain, diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index b6b22f8d42..69435344be 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -2,7 +2,7 @@ /* * esx_driver.c: core driver functions for managing VMware ESX hosts * - * Copyright (C) 2010-2011 Red Hat, Inc. + * Copyright (C) 2010-2012 Red Hat, Inc. * Copyright (C) 2009-2011 Matthias Bolte * Copyright (C) 2009 Maximilian Wilhelm * @@ -2073,7 +2073,7 @@ esxDomainGetOSType(virDomainPtr domain ATTRIBUTE_UNUSED) -static unsigned long +static unsigned long long esxDomainGetMaxMemory(virDomainPtr domain) { esxPrivate *priv = domain->conn->privateData; diff --git a/src/libvirt.c b/src/libvirt.c index 21b4766088..e916aa04bd 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -3603,10 +3603,15 @@ virDomainGetMaxMemory(virDomainPtr domain) conn = domain->conn; if (conn->driver->domainGetMaxMemory) { - unsigned long ret; + unsigned long long ret; ret = conn->driver->domainGetMaxMemory (domain); if (ret == 0) goto error; + if ((unsigned long) ret != ret) { + virLibDomainError(VIR_ERR_OVERFLOW, _("result too large: %llu"), + ret); + goto error; + } return ret; } diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index d5fa64a87d..a7bb75100a 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -1,7 +1,7 @@ /*---------------------------------------------------------------------------*/ -/* Copyright (c) 2011 SUSE LINUX Products GmbH, Nuernberg, Germany. +/* Copyright (C) 2006-2012 Red Hat, Inc. + * Copyright (c) 2011 SUSE LINUX Products GmbH, Nuernberg, Germany. * Copyright (C) 2011 Univention GmbH. - * Copyright (C) 2006-2011 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -1592,12 +1592,12 @@ cleanup: return type; } -static unsigned long +static unsigned long long libxlDomainGetMaxMemory(virDomainPtr dom) { libxlDriverPrivatePtr driver = dom->conn->privateData; virDomainObjPtr vm; - unsigned long ret = 0; + unsigned long long ret = 0; libxlDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, dom->uuid); diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index d9cbd9e90f..1a0e4586fe 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -670,10 +670,12 @@ cleanup: } /* Returns max memory in kb, 0 if error */ -static unsigned long lxcDomainGetMaxMemory(virDomainPtr dom) { +static unsigned long long +lxcDomainGetMaxMemory(virDomainPtr dom) +{ lxc_driver_t *driver = dom->conn->privateData; virDomainObjPtr vm; - unsigned long ret = 0; + unsigned long long ret = 0; lxcDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, dom->uuid); diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index b364b2c3c1..6546d0b17d 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1877,10 +1877,12 @@ cleanup: } /* Returns max memory in kb, 0 if error */ -static unsigned long qemudDomainGetMaxMemory(virDomainPtr dom) { +static unsigned long long +qemuDomainGetMaxMemory(virDomainPtr dom) +{ struct qemud_driver *driver = dom->conn->privateData; virDomainObjPtr vm; - unsigned long ret = 0; + unsigned long long ret = 0; qemuDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, dom->uuid); @@ -12417,7 +12419,7 @@ static virDriver qemuDriver = { .domainDestroy = qemuDomainDestroy, /* 0.2.0 */ .domainDestroyFlags = qemuDomainDestroyFlags, /* 0.9.4 */ .domainGetOSType = qemudDomainGetOSType, /* 0.2.2 */ - .domainGetMaxMemory = qemudDomainGetMaxMemory, /* 0.4.2 */ + .domainGetMaxMemory = qemuDomainGetMaxMemory, /* 0.4.2 */ .domainSetMaxMemory = qemudDomainSetMaxMemory, /* 0.4.2 */ .domainSetMemory = qemudDomainSetMemory, /* 0.4.2 */ .domainSetMemoryFlags = qemudDomainSetMemoryFlags, /* 0.9.0 */ diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl index 3f37d58420..ef369b980b 100755 --- a/src/rpc/gendispatch.pl +++ b/src/rpc/gendispatch.pl @@ -201,7 +201,6 @@ close(PROTOCOL); # this list is fixed. new procedures and public APIs have to map [unsigned] # hyper to [unsigned] long long my $long_legacy = { - DomainGetMaxMemory => { ret => { memory => 1 } }, DomainGetInfo => { ret => { maxMem => 1, memory => 1 } }, DomainMigrate => { arg => { flags => 1, resource => 1 } }, DomainMigrate2 => { arg => { flags => 1, resource => 1 } }, diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 39fd63dea7..f03b2fdcc5 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -2021,10 +2021,10 @@ static char *testGetOSType(virDomainPtr dom ATTRIBUTE_UNUSED) { return ret; } -static unsigned long testGetMaxMemory(virDomainPtr domain) { +static unsigned long long testGetMaxMemory(virDomainPtr domain) { testConnPtr privconn = domain->conn->privateData; virDomainObjPtr privdom; - unsigned long ret = 0; + unsigned long long ret = 0; testDriverLock(privconn); privdom = virDomainFindByName(&privconn->domains, diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index 378dffcc3e..16818cdc18 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -1625,10 +1625,12 @@ cleanup: } /* Returns max memory in kb, 0 if error */ -static unsigned long umlDomainGetMaxMemory(virDomainPtr dom) { +static unsigned long long +umlDomainGetMaxMemory(virDomainPtr dom) +{ struct uml_driver *driver = dom->conn->privateData; virDomainObjPtr vm; - unsigned long ret = 0; + unsigned long long ret = 0; umlDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, dom->uuid); diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 19ce7dae65..0238ed740d 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -1,7 +1,7 @@ /* * xen_driver.c: Unified Xen driver. * - * Copyright (C) 2007-2011 Red Hat, Inc. + * Copyright (C) 2007-2012 Red Hat, Inc. * * See COPYING.LIB for the License of this software * @@ -937,12 +937,12 @@ xenUnifiedDomainGetOSType (virDomainPtr dom) return NULL; } -static unsigned long +static unsigned long long xenUnifiedDomainGetMaxMemory (virDomainPtr dom) { GET_PRIVATE(dom->conn); int i; - unsigned long ret; + unsigned long long ret; for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i) if (priv->opened[i] && drivers[i]->xenDomainGetMaxMemory) { diff --git a/src/xen/xen_hypervisor.c b/src/xen/xen_hypervisor.c index b5b2328c22..4401b68747 100644 --- a/src/xen/xen_hypervisor.c +++ b/src/xen/xen_hypervisor.c @@ -855,7 +855,7 @@ typedef struct xen_op_v2_dom xen_op_v2_dom; # error "unsupported platform" #endif -static unsigned long xenHypervisorGetMaxMemory(virDomainPtr domain); +static unsigned long long xenHypervisorGetMaxMemory(virDomainPtr domain); struct xenUnifiedDriver xenHypervisorDriver = { .xenClose = xenHypervisorClose, @@ -3157,7 +3157,7 @@ xenHypervisorGetDomMaxMemory(virConnectPtr conn, int id) * * Returns the memory size in kilobytes or 0 in case of error. */ -static unsigned long ATTRIBUTE_NONNULL (1) +static unsigned long long ATTRIBUTE_NONNULL (1) xenHypervisorGetMaxMemory(virDomainPtr domain) { xenUnifiedPrivatePtr priv; diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index 83bfac0f27..a19d055125 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -1,7 +1,7 @@ /* * xend_internal.c: access to Xen though the Xen Daemon interface * - * Copyright (C) 2010-2011 Red Hat, Inc. + * Copyright (C) 2010-2012 Red Hat, Inc. * Copyright (C) 2005 Anthony Liguori * * This file is subject to the terms and conditions of the GNU Lesser General @@ -1638,32 +1638,32 @@ xenDaemonDomainRestore(virConnectPtr conn, const char *filename) * * Returns the memory size in kilobytes or 0 in case of error. */ -unsigned long +unsigned long long xenDaemonDomainGetMaxMemory(virDomainPtr domain) { - unsigned long ret = 0; + unsigned long long ret = 0; struct sexpr *root; xenUnifiedPrivatePtr priv; if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) { virXendError(VIR_ERR_INVALID_ARG, __FUNCTION__); - return(-1); + return 0; } priv = (xenUnifiedPrivatePtr) domain->conn->privateData; if (domain->id < 0 && priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) - return(-1); + return 0; /* can we ask for a subset ? worth it ? */ root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name); if (root == NULL) - return(0); + return 0; - ret = (unsigned long) sexpr_u64(root, "domain/memory") << 10; + ret = sexpr_u64(root, "domain/memory") << 10; sexpr_free(root); - return(ret); + return ret; } diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h index 3f0b63d6ab..5942788103 100644 --- a/src/xen/xend_internal.h +++ b/src/xen/xend_internal.h @@ -1,7 +1,7 @@ /* * xend_internal.h * - * Copyright (C) 2006-2008, 2010-2011 Red Hat, Inc. + * Copyright (C) 2006-2008, 2010-2012 Red Hat, Inc. * Copyright (C) 2005,2006 * * Anthony Liguori @@ -119,7 +119,7 @@ int xenDaemonDomainGetState(virDomainPtr domain, unsigned int flags); char *xenDaemonDomainGetXMLDesc(virDomainPtr domain, unsigned int flags, const char *cpus); -unsigned long xenDaemonDomainGetMaxMemory(virDomainPtr domain); +unsigned long long xenDaemonDomainGetMaxMemory(virDomainPtr domain); char **xenDaemonListDomainsOld(virConnectPtr xend); virDomainPtr xenDaemonDomainDefineXML(virConnectPtr xend, const char *sexpr); diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c index 5acac8b703..e966e637d5 100644 --- a/src/xen/xm_internal.c +++ b/src/xen/xm_internal.c @@ -1,7 +1,7 @@ /* * xm_internal.h: helper routines for dealing with inactive domains * - * Copyright (C) 2006-2007, 2009-2011 Red Hat, Inc. + * Copyright (C) 2006-2007, 2009-2012 Red Hat, Inc. * Copyright (C) 2006 Daniel P. Berrange * * This library is free software; you can redistribute it and/or @@ -646,11 +646,11 @@ cleanup: /* * Get max memory limit from config */ -unsigned long xenXMDomainGetMaxMemory(virDomainPtr domain) { +unsigned long long xenXMDomainGetMaxMemory(virDomainPtr domain) { xenUnifiedPrivatePtr priv; const char *filename; xenXMConfCachePtr entry; - unsigned long ret = 0; + unsigned long long ret = 0; if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) { xenXMError(VIR_ERR_INVALID_ARG, __FUNCTION__); diff --git a/src/xen/xm_internal.h b/src/xen/xm_internal.h index 89af23ee45..3e1f886e0c 100644 --- a/src/xen/xm_internal.h +++ b/src/xen/xm_internal.h @@ -1,7 +1,7 @@ /* * xm_internal.h: helper routines for dealing with inactive domains * - * Copyright (C) 2006-2007, 2010-2011 Red Hat, Inc. + * Copyright (C) 2006-2007, 2010-2012 Red Hat, Inc. * Copyright (C) 2006 Daniel P. Berrange * * This library is free software; you can redistribute it and/or @@ -48,7 +48,7 @@ int xenXMDomainGetState(virDomainPtr domain, char *xenXMDomainGetXMLDesc(virDomainPtr domain, unsigned int flags); int xenXMDomainSetMemory(virDomainPtr domain, unsigned long memory); int xenXMDomainSetMaxMemory(virDomainPtr domain, unsigned long memory); -unsigned long xenXMDomainGetMaxMemory(virDomainPtr domain); +unsigned long long xenXMDomainGetMaxMemory(virDomainPtr domain); int xenXMDomainSetVcpus(virDomainPtr domain, unsigned int vcpus); int xenXMDomainSetVcpusFlags(virDomainPtr domain, unsigned int vcpus, unsigned int flags); diff --git a/src/xen/xs_internal.c b/src/xen/xs_internal.c index 86e5519b45..729873fcd5 100644 --- a/src/xen/xs_internal.c +++ b/src/xen/xs_internal.c @@ -1,7 +1,7 @@ /* * xs_internal.c: access to Xen Store * - * Copyright (C) 2006, 2009-2011 Red Hat, Inc. + * Copyright (C) 2006, 2009-2012 Red Hat, Inc. * * See COPYING.LIB for the License of this software * @@ -495,23 +495,23 @@ xenStoreDomainSetMemory(virDomainPtr domain, unsigned long memory) * * Returns the memory size in kilobytes or 0 in case of error. */ -unsigned long +unsigned long long xenStoreDomainGetMaxMemory(virDomainPtr domain) { char *tmp; - unsigned long ret = 0; + unsigned long long ret = 0; xenUnifiedPrivatePtr priv; if (!VIR_IS_CONNECTED_DOMAIN(domain)) return (ret); if (domain->id == -1) - return(-1); + return 0; priv = domain->conn->privateData; xenUnifiedLock(priv); tmp = virDomainDoStoreQuery(domain->conn, domain->id, "memory/target"); if (tmp != NULL) { - ret = (unsigned long) atol(tmp); + ret = atol(tmp); VIR_FREE(tmp); } xenUnifiedUnlock(priv); diff --git a/src/xen/xs_internal.h b/src/xen/xs_internal.h index f7e487b3be..1ada0f3a15 100644 --- a/src/xen/xs_internal.h +++ b/src/xen/xs_internal.h @@ -1,7 +1,7 @@ /* * xs_internal.h: internal API for access to XenStore * - * Copyright (C) 2006, 2010-2011 Red Hat, Inc. + * Copyright (C) 2006, 2010-2012 Red Hat, Inc. * * See COPYING.LIB for the License of this software * @@ -36,7 +36,7 @@ virDomainPtr xenStoreLookupByName(virConnectPtr conn, unsigned long xenStoreGetMaxMemory (virDomainPtr domain); int xenStoreDomainSetMemory (virDomainPtr domain, unsigned long memory); -unsigned long xenStoreDomainGetMaxMemory(virDomainPtr domain); +unsigned long long xenStoreDomainGetMaxMemory(virDomainPtr domain); int xenStoreDomainShutdown (virDomainPtr domain); int xenStoreDomainReboot (virDomainPtr domain, unsigned int flags); diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c index 94644ae025..298db1220f 100644 --- a/src/xenapi/xenapi_driver.c +++ b/src/xenapi/xenapi_driver.c @@ -1,6 +1,6 @@ /* * xenapi_driver.c: Xen API driver. - * Copyright (C) 2011 Red Hat, Inc. + * Copyright (C) 2011-2012 Red Hat, Inc. * Copyright (C) 2009, 2010 Citrix Ltd. * * This library is free software; you can redistribute it and/or @@ -955,7 +955,7 @@ xenapiDomainGetOSType (virDomainPtr dom) * Returns maximum static memory for VM on success * or 0 in case of error */ -static unsigned long +static unsigned long long xenapiDomainGetMaxMemory (virDomainPtr dom) { int64_t mem_static_max = 0; @@ -972,7 +972,7 @@ xenapiDomainGetMaxMemory (virDomainPtr dom) vm = vms->contents[0]; xen_vm_get_memory_static_max(session, &mem_static_max, vm); xen_vm_set_free(vms); - return (unsigned long)(mem_static_max / 1024); + return (mem_static_max / 1024); } else { if (vms) xen_vm_set_free(vms); xenapiSessionErrorHandler(dom->conn, VIR_ERR_NO_DOMAIN, NULL);