Excessive memory balloon inflation can cause invocation of OOM-killer,
when Linux is under severe memory pressure. QEMU memballoon device
has a feature to release some memory at the last moment before some
process will be get killed by OOM-killer.
Introduce a new optional balloon device attribute 'autodeflate' to
enable or disable this feature.
---
docs/formatdomain.html.in | 10 ++++++++++
docs/schemas/domaincommon.rng | 5 +++++
src/conf/domain_conf.c | 23 +++++++++++++++++++++++
src/conf/domain_conf.h | 1 +
4 files changed, 39 insertions(+)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 889e721..b3187bb 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -5962,6 +5962,16 @@ qemu-kvm -net nic,model=? /dev/null
<li>'xen' — default with Xen</li>
</ul>
</dd>
+ <dt><code>autodeflate</code></dt>
+ <dd>
+ <p>
+ The optional <code>autodeflate</code> attribute allows to
+ enable/disable (values "on"/"off", respectively) the
ability of the
+ QEMU virtio memory balloon to release some memory at the last moment
+ before a guest's process get killed by Out of Memory killer.
+ <span class="since">Since 1.3.1, QEMU and KVM
only</span>
+ </p>
+ </dd>
<dt><code>period</code></dt>
<dd>
<p>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 7c47f60..5deb17b 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -3420,6 +3420,11 @@
<value>none</value>
</choice>
</attribute>
+ <optional>
+ <attribute name="autodeflate">
+ <ref name="virOnOff"/>
+ </attribute>
+ </optional>
<interleave>
<optional>
<ref name="alias"/>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 9d47846..34a896d 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -11327,6 +11327,7 @@ virDomainMemballoonDefParseXML(xmlNodePtr node,
unsigned int flags)
{
char *model;
+ char *deflate;
virDomainMemballoonDefPtr def;
xmlNodePtr save = ctxt->node;
unsigned int period = 0;
@@ -11347,6 +11348,13 @@ virDomainMemballoonDefParseXML(xmlNodePtr node,
goto error;
}
+ if ((deflate = virXMLPropString(node, "autodeflate")) &&
+ (def->autodeflate = virTristateSwitchTypeFromString(deflate)) <= 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("invalid autodeflate attribute value '%s'"),
deflate);
+ goto error;
+ }
+
ctxt->node = node;
if (virXPathUInt("string(./stats/@period)", ctxt, &period) < -1) {
virReportError(VIR_ERR_XML_ERROR, "%s",
@@ -11365,6 +11373,7 @@ virDomainMemballoonDefParseXML(xmlNodePtr node,
cleanup:
VIR_FREE(model);
+ VIR_FREE(deflate);
ctxt->node = save;
return def;
@@ -17238,6 +17247,15 @@ virDomainMemballoonDefCheckABIStability(virDomainMemballoonDefPtr
src,
return false;
}
+ if (src->autodeflate != dst->autodeflate) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Target balloon autodeflate attribute value "
+ "'%s' does not match source '%s'"),
+ virTristateSwitchTypeToString(dst->autodeflate),
+ virTristateSwitchTypeToString(src->autodeflate));
+ return false;
+ }
+
if (!virDomainDeviceInfoCheckABIStability(&src->info, &dst->info))
return false;
@@ -20419,6 +20437,11 @@ virDomainMemballoonDefFormat(virBufferPtr buf,
}
virBufferAsprintf(buf, "<memballoon model='%s'", model);
+
+ if (def->autodeflate != VIR_TRISTATE_SWITCH_ABSENT)
+ virBufferAsprintf(buf, " autodeflate='%s'",
+ virTristateSwitchTypeToString(def->autodeflate));
+
virBufferAdjustIndent(&childrenBuf, indent + 2);
if (def->period)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index ae6d546..5d2682d 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1635,6 +1635,7 @@ struct _virDomainMemballoonDef {
int model;
virDomainDeviceInfo info;
int period; /* seconds between collections */
+ int autodeflate; /* enum virTristateSwitch */
};
struct _virDomainNVRAMDef {
--
1.8.3.1