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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list