[libvirt] [PATCHv3 2/2] conf: allow fuzz in XML with cur balloon > max

Eric Blake eblake at redhat.com
Sat Mar 31 15:33:39 UTC 2012


Commit 1b1402b introduced a regression.  Since older libvirt versions
would silently round memory up (until the previous patch), but populated
current memory based on querying the guest, it was possible to have
dumpxml show cur > max by the amount of the rounding.  For example, if
a user requested 1048570 KiB memory (just shy of 1GiB), the qemu
driver would actually run with 1048576 KiB, and libvirt 0.9.10 would
output a current that was 6KiB larger than the maximum.  Situations
where this could have an impact include, but are not limited to,
migration from old to new libvirt, managedsave in old libvirt and
start in new libvirt, snapshot creation in old libvirt and revert in
new libvirt - without this patch, the new libvirt would reject the
VM because of the rounding discrepancy.

Fix things by adding a fuzz factor, and silently clamp current down to
maximum in that case, rather than failing to reparse XML for an existing
VM.  From a practical standpoint, this has no user impact: 'virsh
dumpxml' will continue to query the running guest rather than rely on
the incoming xml, which will see the currect current value, and even if
clamping down occurs during parsing, it will be by at most the fuzz
factor of a megabyte alignment, and rounded back up when passed back to
the hypervisor.

Meanwhile, we continue to reject cur > max if the difference is beyond
the fuzz factor of nearest megabyte.  But this is not a real change in
behavior, since with 0.9.10, even though the parser allowed it, later
in the processing stream we would reject it at the qemu layer; so
rejecting it in the parser just moves error detection to a nicer place.

* src/conf/domain_conf.c (virDomainDefParseXML): Don't reject
existing XML.
Based on a report by Zhou Peng.
---

v3: improve the commit message (no change to the code)

 src/conf/domain_conf.c |   19 +++++++++++++++----
 1 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 7ea57b9..c800160 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -7769,10 +7769,21 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
         goto error;

     if (def->mem.cur_balloon > def->mem.max_balloon) {
-        virDomainReportError(VIR_ERR_XML_ERROR,
-                             _("current memory '%lluk' exceeds maximum '%lluk'"),
-                             def->mem.cur_balloon, def->mem.max_balloon);
-        goto error;
+        /* Older libvirt could get into this situation due to
+         * rounding; if the discrepancy is less than 1MiB, we silently
+         * round down, otherwise we flag the issue.  */
+        if (VIR_DIV_UP(def->mem.cur_balloon, 1024) >
+            VIR_DIV_UP(def->mem.max_balloon, 1024)) {
+            virDomainReportError(VIR_ERR_XML_ERROR,
+                                 _("current memory '%lluk' exceeds "
+                                   "maximum '%lluk'"),
+                                 def->mem.cur_balloon, def->mem.max_balloon);
+            goto error;
+        } else {
+            VIR_DEBUG("Truncating current %lluk to maximum %lluk",
+                      def->mem.cur_balloon, def->mem.max_balloon);
+            def->mem.cur_balloon = def->mem.max_balloon;
+        }
     } else if (def->mem.cur_balloon == 0) {
         def->mem.cur_balloon = def->mem.max_balloon;
     }
-- 
1.7.7.6




More information about the libvir-list mailing list