From c6f4acc4cbbc41e9097d5266cc5310ca891bb234 Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Thu, 23 Feb 2017 13:50:24 +0100 Subject: [PATCH] qemu: implement qemuDomainSetBlockThreshold Add code to call the appropriate monitor command and code to lookup the given disk backing chain member. --- src/qemu/qemu_driver.c | 70 ++++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor.c | 13 +++++++ src/qemu/qemu_monitor.h | 5 +++ src/qemu/qemu_monitor_json.c | 31 ++++++++++++++++ src/qemu/qemu_monitor_json.h | 6 ++++ 5 files changed, 125 insertions(+) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 972c06c34e..f6403e43c1 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -20312,6 +20312,75 @@ qemuDomainSetVcpu(virDomainPtr dom, } +static int +qemuDomainSetBlockThreshold(virDomainPtr dom, + const char *dev, + unsigned long long threshold, + unsigned int flags) +{ + virQEMUDriverPtr driver = dom->conn->privateData; + qemuDomainObjPrivatePtr priv; + virDomainObjPtr vm = NULL; + virStorageSourcePtr src; + char *nodename = NULL; + int rc; + int ret = -1; + + virCheckFlags(0, -1); + + if (!(vm = qemuDomObjFromDomain(dom))) + goto cleanup; + + priv = vm->privateData; + + if (virDomainSetBlockThresholdEnsureACL(dom->conn, vm->def) < 0) + 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 (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCK_WRITE_THRESHOLD)) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("this qemu does not support setting device threshold")); + goto endjob; + } + + if (!(src = qemuDomainGetStorageSourceByDevstr(dev, vm->def))) + goto endjob; + + if (!src->nodebacking) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, + _("threshold currently can't be set for block device '%s'"), + dev); + goto endjob; + } + + if (VIR_STRDUP(nodename, src->nodebacking) < 0) + goto endjob; + + qemuDomainObjEnterMonitor(driver, vm); + rc = qemuMonitorSetBlockThreshold(priv->mon, nodename, threshold); + if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0) + goto endjob; + + ret = 0; + + endjob: + qemuDomainObjEndJob(driver, vm); + + cleanup: + VIR_FREE(nodename); + virDomainObjEndAPI(&vm); + return ret; +} + + static virHypervisorDriver qemuHypervisorDriver = { .name = QEMU_DRIVER_NAME, .connectOpen = qemuConnectOpen, /* 0.2.0 */ @@ -20526,6 +20595,7 @@ static virHypervisorDriver qemuHypervisorDriver = { .domainGetGuestVcpus = qemuDomainGetGuestVcpus, /* 2.0.0 */ .domainSetGuestVcpus = qemuDomainSetGuestVcpus, /* 2.0.0 */ .domainSetVcpu = qemuDomainSetVcpu, /* 3.1.0 */ + .domainSetBlockThreshold = qemuDomainSetBlockThreshold /* 3.2.0 */ }; diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index a85eacfee4..ab476da7f0 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -4206,3 +4206,16 @@ qemuMonitorQueryQMPSchema(qemuMonitorPtr mon) return qemuMonitorJSONQueryQMPSchema(mon); } + + +int +qemuMonitorSetBlockThreshold(qemuMonitorPtr mon, + const char *nodename, + unsigned long long threshold) +{ + VIR_DEBUG("mon=%p, node='%s', threshold=%llu", mon, nodename, threshold); + + QEMU_CHECK_MONITOR_JSON(mon); + + return qemuMonitorJSONSetBlockThreshold(mon, nodename, threshold); +} diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 3270baba04..7fd83b620d 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -1079,4 +1079,9 @@ int qemuMonitorGetRTCTime(qemuMonitorPtr mon, virHashTablePtr qemuMonitorQueryQMPSchema(qemuMonitorPtr mon); +int qemuMonitorSetBlockThreshold(qemuMonitorPtr mon, + const char *nodename, + unsigned long long threshold); + + #endif /* QEMU_MONITOR_H */ diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index f95afd1ed6..06bf84dd96 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -7526,3 +7526,34 @@ qemuMonitorJSONQueryQMPSchema(qemuMonitorPtr mon) return ret; } + + +int +qemuMonitorJSONSetBlockThreshold(qemuMonitorPtr mon, + const char *nodename, + unsigned long long threshold) +{ + virJSONValuePtr cmd; + virJSONValuePtr reply = NULL; + int ret = -1; + + if (!(cmd = qemuMonitorJSONMakeCommand("block-set-write-threshold", + "s:node-name", nodename, + "U:write-threshold", threshold, + NULL))) + return -1; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) + goto cleanup; + + if (qemuMonitorJSONCheckError(cmd, reply) < 0) + goto cleanup; + + ret = 0; + + cleanup: + virJSONValueFree(cmd); + virJSONValueFree(reply); + + return ret; +} diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 2bc2d6ea8f..8bcd443333 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -512,4 +512,10 @@ int qemuMonitorJSONGetHotpluggableCPUs(qemuMonitorPtr mon, virHashTablePtr qemuMonitorJSONQueryQMPSchema(qemuMonitorPtr mon) ATTRIBUTE_NONNULL(1); + +int qemuMonitorJSONSetBlockThreshold(qemuMonitorPtr mon, + const char *nodename, + unsigned long long threshold) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + #endif /* QEMU_MONITOR_JSON_H */ -- GitLab