On Mon, Jun 22, 2015 at 17:06:46 -0600, Eric Blake wrote: > Time to wire up the new API to call into the QMP command for setting > a write threshold. > > For now, the API only allows setting the threshold on the active > layer. But I left TODOs in the series for places that need > touching to find and support node names of backing files, so that > we can use "vda[1]" notation to register for a threshold on the > backing image during an active commit operation. > > * src/qemu/qemu_driver.c (qemuDomainBlockSetWriteThreshold): New > function. > * src/qemu/qemu_monitor.c (qemuMonitorBlockSetWriteThreshold): > Likewise. > * src/qemu/qemu_monitor.h (qemuMonitorBlockSetWriteThreshold): > Likewise. > * src/qemu/qemu_monitor_json.c > (qemuMonitorJSONBlockSetWriteThreshold): Likewise. > * src/qemu/qemu_monitor_json.h > (qemuMonitorJSONBlockSetWriteThreshold): Likewise. > > Signed-off-by: Eric Blake <eblake@xxxxxxxxxx> > --- > src/qemu/qemu_driver.c | 95 ++++++++++++++++++++++++++++++++++++++++++++ > src/qemu/qemu_monitor.c | 13 ++++++ > src/qemu/qemu_monitor.h | 5 +++ > src/qemu/qemu_monitor_json.c | 30 ++++++++++++++ > src/qemu/qemu_monitor_json.h | 3 ++ > 5 files changed, 146 insertions(+) > > diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c > index 72e256b..732f102 100644 > --- a/src/qemu/qemu_driver.c > +++ b/src/qemu/qemu_driver.c > @@ -17906,6 +17906,100 @@ qemuDomainGetBlockIoTune(virDomainPtr dom, > return ret; > } > > + > +static int > +qemuDomainBlockSetWriteThreshold(virDomainPtr dom, > + const char *path, > + unsigned long long threshold, > + unsigned int flags) > +{ > + virQEMUDriverPtr driver = dom->conn->privateData; > + virDomainObjPtr vm = NULL; > + qemuDomainObjPrivatePtr priv; > + virDomainDiskDefPtr disk = NULL; > + virCapsPtr caps = NULL; > + virQEMUDriverConfigPtr cfg = NULL; > + const char *node = NULL; > + int ret = -1; > + > + virCheckFlags(VIR_DOMAIN_BLOCK_SET_WRITE_THRESHOLD_PROPORTION, -1); > + > + if (!(vm = qemuDomObjFromDomain(dom))) > + return -1; > + priv = vm->privateData; > + > + if (virDomainBlockSetWriteThresholdEnsureACL(dom->conn, vm->def) < 0) > + goto cleanup; > + > + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) > + goto cleanup; > + if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCK_WRITE_THRESHOLD) || > + !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_AUTO_NODE_NAMES)) { > + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", > + _("block write threshold not supported by this " > + "qemu binary")); > + goto cleanup; > + } > + > + if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) > + goto cleanup; > + > + if (!virDomainObjIsActive(vm)) { > + virReportError(VIR_ERR_OPERATION_INVALID, > + "%s", _("domain is not running")); > + goto endjob; > + } > + > + if (!(disk = virDomainDiskByName(vm->def, path, false))) { > + virReportError(VIR_ERR_INVALID_ARG, > + _("invalid path %s not assigned to domain"), path); > + goto endjob; > + } > + > + if (!(node = qemuDomainDiskGetAllocationNode(driver, vm, disk))) { > + virReportError(VIR_ERR_INVALID_ARG, > + _("cannot track threshold events on disk '%s'"), > + path); > + goto endjob; > + } > + > + cfg = virQEMUDriverGetConfig(driver); > + if (qemuStorageLimitsRefresh(driver, cfg, vm, disk->src) < 0) This function begins with a rather long comment explaining that it's not entirely a good idea to use it on online VMs and especially on write-enabled disk sources. Shouldn't we query the monitor rather than use that? > + goto endjob; > + > + if (flags & VIR_DOMAIN_BLOCK_SET_WRITE_THRESHOLD_PROPORTION) { > + /* Caller already sanitized max value to 1000000. Use of > + * floating point intermediary reduces (but does not > + * eliminate) rounding error, but since we already document a > + * granularity of parts per million, it shouldn't matter too > + * much if the answer is a few bytes off. */ > + threshold *= disk->src->physical / 1e6; > + } else { > + if (threshold > disk->src->physical) { > + virReportError(VIR_ERR_INVALID_ARG, > + _("threshold %llu exceeds disk size %llu"), > + threshold, disk->src->physical); > + goto endjob; > + } > + } > + > + qemuDomainObjEnterMonitor(driver, vm); > + ret = qemuMonitorBlockSetWriteThreshold(priv->mon, node, threshold); > + if (qemuDomainObjExitMonitor(driver, vm) < 0) > + ret = -1; > + > + > + endjob: > + qemuDomainObjEndJob(driver, vm); > + > + cleanup: > + virDomainObjEndAPI(&vm); > + virObjectUnref(caps); > + virObjectUnref(cfg); > + return ret; > +} > + > + > static int > qemuDomainGetDiskErrors(virDomainPtr dom, > virDomainDiskErrorPtr errors, > @@ -20037,6 +20131,7 @@ static virHypervisorDriver qemuHypervisorDriver = { > .nodeSuspendForDuration = qemuNodeSuspendForDuration, /* 0.9.8 */ > .domainSetBlockIoTune = qemuDomainSetBlockIoTune, /* 0.9.8 */ > .domainGetBlockIoTune = qemuDomainGetBlockIoTune, /* 0.9.8 */ > + .domainBlockSetWriteThreshold = qemuDomainBlockSetWriteThreshold, /* 1.3.0 */ > .domainSetNumaParameters = qemuDomainSetNumaParameters, /* 0.9.9 */ > .domainGetNumaParameters = qemuDomainGetNumaParameters, /* 0.9.9 */ > .domainGetInterfaceParameters = qemuDomainGetInterfaceParameters, /* 0.9.9 */ > diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c > index c4b6073..2ff34e2 100644 > --- a/src/qemu/qemu_monitor.c > +++ b/src/qemu/qemu_monitor.c > @@ -1866,6 +1866,19 @@ qemuMonitorBlockStatsUpdateThreshold(qemuMonitorPtr mon, > > > int > +qemuMonitorBlockSetWriteThreshold(qemuMonitorPtr mon, > + const char *dev_name, This function needs a node name passed so it should also be called that way to avoid confusion since the function lacks docs. > + unsigned long long threshold) > +{ > + VIR_DEBUG("dev_name=%s, threshold=%llu", dev_name, threshold); > + > + QEMU_CHECK_MONITOR_JSON(mon); > + > + return qemuMonitorJSONBlockSetWriteThreshold(mon, dev_name, threshold); > +} > + > + > +int > qemuMonitorGetBlockExtent(qemuMonitorPtr mon, > const char *dev_name, > unsigned long long *extent) Peter
Attachment:
signature.asc
Description: Digital signature
-- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list