[libvirt] [PATCHv2 08/15] xml: use long long internally, to centralize overflow checks

Eric Blake eblake at redhat.com
Tue Mar 6 00:34:23 UTC 2012


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.

* 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.
---

v2: new

 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    |   12 ++++++------
 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, 56 insertions(+), 46 deletions(-)

diff --git a/src/driver.h b/src/driver.h
index 212d2f5..03d249b 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 b6b22f8..6943534 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 <matthias.bolte at googlemail.com>
  * Copyright (C) 2009 Maximilian Wilhelm <max at rfc2324.org>
  *
@@ -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 de23db8..73fb8de 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -3602,10 +3602,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 d5fa64a..a7bb751 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 d9cbd9e..1a0e458 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 1bdd2f0..aee95e4 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);
@@ -12264,7 +12266,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 3f37d58..ef369b9 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 39fd63d..f03b2fd 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 378dffc..16818cd 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 19ce7da..0238ed7 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 b5b2328..4401b68 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 83bfac0..691ce17 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 <aliguori at us.ibm.com>
  *
  *  This file is subject to the terms and conditions of the GNU Lesser General
@@ -1638,29 +1638,29 @@ 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);

-    ret = (unsigned long) sexpr_u64(root, "domain/memory") << 10;
+    ret = sexpr_u64(root, "domain/memory") << 10;
     sexpr_free(root);

     return(ret);
diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h
index 3f0b63d..5942788 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 <aliguori at us.ibm.com>
@@ -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 5acac8b..e966e63 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 89af23e..3e1f886 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 86e5519..10811dd 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 f7e487b..1ada0f3 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 94644ae..298db12 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);
-- 
1.7.7.6




More information about the libvir-list mailing list