diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index b2783b0..f18881a 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -283,6 +283,14 @@ + + + + yes + no + + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index bfe01f0..2a21998 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -4208,10 +4208,24 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, "%s", _("missing memory element")); goto error; } - if (virXPathULong("string(./currentMemory[1])", ctxt, &def->memory) < 0) def->memory = def->maxmem; + tmp = virXPathString("string(./memory[1]/@balloonable)", ctxt); + if (tmp) { + if (STREQ(tmp, "yes")) + def->balloonable = 1; + else if (STREQ(tmp, "no")) + def->balloonable = -1; + else { + virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _("memory balloonable attribute: expected yes or no got %s"), + tmp); + goto error; + } + VIR_FREE(tmp); + } + node = virXPathNode("./memoryBacking/hugepages", ctxt); if (node) def->hugepage_backed = 1; @@ -4829,18 +4843,22 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, goto error; } if (n > 0) { - virDomainMemballoonDefPtr memballoon = - virDomainMemballoonDefParseXML(nodes[0], flags); - if (!memballoon) - goto error; + if (def->balloonable >= 0) { + virDomainMemballoonDefPtr memballoon = + virDomainMemballoonDefParseXML(nodes[0], flags); + if (!memballoon) + goto error; - def->memballoon = memballoon; + def->memballoon = memballoon; + def->balloonable = 1; + } VIR_FREE(nodes); } else { - if (def->virtType == VIR_DOMAIN_VIRT_XEN || - def->virtType == VIR_DOMAIN_VIRT_QEMU || - def->virtType == VIR_DOMAIN_VIRT_KQEMU || - def->virtType == VIR_DOMAIN_VIRT_KVM) { + if ((def->balloonable >= 0) && + (def->virtType == VIR_DOMAIN_VIRT_XEN || + def->virtType == VIR_DOMAIN_VIRT_QEMU || + def->virtType == VIR_DOMAIN_VIRT_KQEMU || + def->virtType == VIR_DOMAIN_VIRT_KVM)) { virDomainMemballoonDefPtr memballoon; if (VIR_ALLOC(memballoon) < 0) goto no_memory; @@ -6349,7 +6367,13 @@ char *virDomainDefFormat(virDomainDefPtr def, virBufferEscapeString(&buf, " %s\n", def->description); - virBufferVSprintf(&buf, " %lu\n", def->maxmem); + if (def->balloonable == 1) + virBufferAddLit(&buf, " "); + else if (def->balloonable == -1) + virBufferAddLit(&buf, " "); + else + virBufferAddLit(&buf, " "); + virBufferVSprintf(&buf, "%lu\n", def->maxmem); virBufferVSprintf(&buf, " %lu\n", def->memory); if (def->hugepage_backed) { @@ -6577,7 +6601,7 @@ char *virDomainDefFormat(virDomainDefPtr def, if (def->watchdog) virDomainWatchdogDefFormat (&buf, def->watchdog, flags); - if (def->memballoon) + if ((def->balloonable >= 0) && (def->memballoon)) virDomainMemballoonDefFormat (&buf, def->memballoon, flags); virBufferAddLit(&buf, " \n"); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index e32188f..8bf5c11 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -854,6 +854,7 @@ struct _virDomainDef { unsigned long memory; unsigned long maxmem; + int balloonable; unsigned char hugepage_backed; unsigned long vcpus; int cpumasklen; diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 376cd10..9e21f5d 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -2434,7 +2434,7 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs) } /* VirtIO balloon */ - if (def->memballoon && + if (def->balloonable >= 0 && def->memballoon && def->memballoon->model == VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO && def->memballoon->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { if (qemuDomainPCIAddressSetNextAddr(addrs, &def->memballoon->info) < 0) @@ -4958,7 +4958,7 @@ int qemudBuildCommandLine(virConnectPtr conn, * NB: Earlier we declared that VirtIO balloon will always be in * slot 0x3 on bus 0x0 */ - if (def->memballoon) { + if ((def->balloonable >= 0) && (def->memballoon)) { if (def->memballoon->model != VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO) { qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Memory balloon device type '%s' is not supported by this version of qemu"), @@ -6575,13 +6575,18 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps, def->videos[def->nvideos++] = vid; } - if (!def->memballoon) { + /* + * if we were not told explicitely that memory was not baloonable + * activate the baloon driver + */ + if ((def->balloonable >= 0) && (!def->memballoon)) { virDomainMemballoonDefPtr memballoon; if (VIR_ALLOC(memballoon) < 0) goto no_memory; memballoon->model = VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO; def->memballoon = memballoon; + def->balloonable = 1; } VIR_FREE(nics);