Extend the virDomainSetMemeoryFlags() to accept a 'VIR_DOMAIN_MEM_PERIOD'
which will be used to dynamically set the collection period for the balloon
driver via a 'virsh dommemstat <domain> --period <value>' command.
Add
the --current, --live, & --config options to dommemstat.
---
docs/formatdomain.html.in | 14 +++++++++
include/libvirt/libvirt.h.in | 1 +
src/libvirt.c | 8 ++++-
src/qemu/qemu_driver.c | 44 +++++++++++++++++++++++++++-
tools/virsh-domain-monitor.c | 70 ++++++++++++++++++++++++++++++++++++++++++--
5 files changed, 132 insertions(+), 5 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index cc4c5ea..0ec256d 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -4612,6 +4612,7 @@ qemu-kvm -net nic,model=? /dev/null
<devices>
<memballoon model='virtio'>
<address type='pci' domain='0x0000' bus='0x00'
slot='0x02' function='0x0'/>
+ <stats period='10'/>
</memballoon>
</devices>
</domain></pre>
@@ -4629,6 +4630,19 @@ qemu-kvm -net nic,model=? /dev/null
<li>'xen' — default with Xen</li>
</ul>
</dd>
+ <dt><code>period</code></dt>
+ <dd>
+ <p>
+ The optional <code>period</code> allows the QEMU virtio memory
+ balloon driver to provide statistics through the <code>virsh
+ dommemstat [domain]</code> command. By default, collection is
+ not enabled. In order to enable, use the <code>virsh dommemstat
+ [domain] --period [number]</code> command or <code>virsh
edit</code>
+ command to add the option. If the QEMU driver is not at the right
+ revision, the attempt to set the period will fail.
+ <span class='since'>Since 1.1.1, requires QEMU 1.5</span>
+ </p>
+ </dd>
</dl>
<h4><a name="elementsRng">Random number generator
device</a></h4>
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index b791125..1fc6e82 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -1844,6 +1844,7 @@ typedef enum {
/* Additionally, these flags may be bitwise-OR'd in. */
VIR_DOMAIN_MEM_MAXIMUM = (1 << 2), /* affect Max rather than current */
+ VIR_DOMAIN_MEM_PERIOD = (1 << 3), /* set dommemstats period */
} virDomainMemoryModFlags;
diff --git a/src/libvirt.c b/src/libvirt.c
index bc1694a..81745bb 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -3738,6 +3738,9 @@ error:
* on whether just live or both live and persistent state is changed.
* If VIR_DOMAIN_MEM_MAXIMUM is set, the change affects domain's maximum memory
* size rather than current memory size.
+ * If VIR_DOMAIN_MEM_PERIOD is set, the domain memory statistics collection
+ * period for the balloon driver will be adjusted. Use 0 to disable and
+ * a positive value to enable.
* Not all hypervisors can support all flag combinations.
*
* Returns 0 in case of success, -1 in case of failure.
@@ -3763,7 +3766,10 @@ virDomainSetMemoryFlags(virDomainPtr domain, unsigned long memory,
virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
goto error;
}
- virCheckNonZeroArgGoto(memory, error);
+
+ /* This can be non zero only for setting the balloon collection period */
+ if (!(flags & VIR_DOMAIN_MEM_PERIOD))
+ virCheckNonZeroArgGoto(memory, error);
conn = domain->conn;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index c9a66ff..b76e634 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -2166,7 +2166,8 @@ static int qemuDomainSetMemoryFlags(virDomainPtr dom, unsigned long
newmem,
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
VIR_DOMAIN_AFFECT_CONFIG |
- VIR_DOMAIN_MEM_MAXIMUM, -1);
+ VIR_DOMAIN_MEM_MAXIMUM |
+ VIR_DOMAIN_MEM_PERIOD, -1);
if (!(vm = qemuDomObjFromDomain(dom)))
goto cleanup;
@@ -2205,6 +2206,47 @@ static int qemuDomainSetMemoryFlags(virDomainPtr dom, unsigned long
newmem,
goto endjob;
}
+ } else if (flags & VIR_DOMAIN_MEM_PERIOD) {
+ /* Set the balloon driver collection interval */
+ priv = vm->privateData;
+ if (!priv->balloonpath) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("memory balloon driver not defined or "
+ "not virtio model"));
+ goto endjob;
+ }
+
+ if (newmem != (int)newmem) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ _("period value=%lu does not match set value=%d"),
+ newmem, (int)newmem);
+ goto endjob;
+ }
+
+ if (flags & VIR_DOMAIN_AFFECT_LIVE) {
+ qemuMonitorObjectProperty prop;
+
+ memset(&prop, 0, sizeof(qemuMonitorObjectProperty));
+ prop.type = QEMU_MONITOR_OBJECT_PROPERTY_INT;
+ prop.val.i = newmem;
+
+ qemuDomainObjEnterMonitor(driver, vm);
+ r = qemuMonitorSetObjectProperty(priv->mon, priv->balloonpath,
+ "guest-stats-polling-interval",
+ &prop);
+ qemuDomainObjExitMonitor(driver, vm);
+ if (r < 0)
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("unable to set balloon driver collection "
+ "period"));
+ }
+
+ if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
+ sa_assert(persistentDef);
+ persistentDef->memballoon->period = newmem;
+ ret = virDomainSaveConfig(cfg->configDir, persistentDef);
+ goto endjob;
+ }
} else {
/* resize the current memory */
diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
index 3ba829c..f123247 100644
--- a/tools/virsh-domain-monitor.c
+++ b/tools/virsh-domain-monitor.c
@@ -306,6 +306,23 @@ static const vshCmdOptDef opts_dommemstat[] = {
.flags = VSH_OFLAG_REQ,
.help = N_("domain name, id or uuid")
},
+ {.name = "period",
+ .type = VSH_OT_DATA,
+ .flags = VSH_OFLAG_EMPTY_OK,
+ .help = N_("period in seconds to set collection")
+ },
+ {.name = "config",
+ .type = VSH_OT_BOOL,
+ .help = N_("affect next boot")
+ },
+ {.name = "live",
+ .type = VSH_OT_BOOL,
+ .help = N_("affect running domain")
+ },
+ {.name = "current",
+ .type = VSH_OT_BOOL,
+ .help = N_("affect current domain")
+ },
{.name = NULL}
};
@@ -316,15 +333,60 @@ cmdDomMemStat(vshControl *ctl, const vshCmd *cmd)
const char *name;
struct _virDomainMemoryStat stats[VIR_DOMAIN_MEMORY_STAT_NR];
unsigned int nr_stats, i;
+ int ret = false;
+ int rv = 0;
+ int period = -1;
+ bool config = vshCommandOptBool(cmd, "config");
+ bool live = vshCommandOptBool(cmd, "live");
+ bool current = vshCommandOptBool(cmd, "current");
+ unsigned int flags = VIR_DOMAIN_AFFECT_CURRENT;
+
+ VSH_EXCLUSIVE_OPTIONS_VAR(current, live);
+ VSH_EXCLUSIVE_OPTIONS_VAR(current, config);
+ if (config)
+ flags |= VIR_DOMAIN_AFFECT_CONFIG;
+ if (live)
+ flags |= VIR_DOMAIN_AFFECT_LIVE;
if (!(dom = vshCommandOptDomain(ctl, cmd, &name)))
return false;
+ /* none of the options were specified - choose defaults based on state */
+ if (!current && !live && !config) {
+ if (virDomainIsActive(dom) == 1)
+ flags |= VIR_DOMAIN_AFFECT_LIVE;
+ else
+ flags |= VIR_DOMAIN_AFFECT_CONFIG;
+ }
+
+ /* Providing a period will adjust the balloon driver collection period.
+ * This is not really an unsigned long, but it
+ */
+ if ((rv = vshCommandOptInt(cmd, "period", &period)) < 0) {
+ vshError(ctl, "%s",
+ _("Unable to parse integer parameter."));
+ goto cleanup;
+ }
+ if (rv > 0) {
+ if (period < 0) {
+ vshError(ctl, _("Invalid collection period value '%d'"),
period);
+ goto cleanup;
+ }
+
+ flags |= VIR_DOMAIN_MEM_PERIOD;
+ if (virDomainSetMemoryFlags(dom, period, flags) < 0) {
+ vshError(ctl, "%s",
+ _("Unable to change balloon collection period."));
+ } else {
+ ret = true;
+ }
+ goto cleanup;
+ }
+
nr_stats = virDomainMemoryStats(dom, stats, VIR_DOMAIN_MEMORY_STAT_NR, 0);
if (nr_stats == -1) {
vshError(ctl, _("Failed to get memory statistics for domain %s"),
name);
- virDomainFree(dom);
- return false;
+ goto cleanup;
}
for (i = 0; i < nr_stats; i++) {
@@ -346,8 +408,10 @@ cmdDomMemStat(vshControl *ctl, const vshCmd *cmd)
vshPrint(ctl, "rss %llu\n", stats[i].val);
}
+ ret = true;
+cleanup:
virDomainFree(dom);
- return true;
+ return ret;
}
/*
--
1.8.1.4