[libvirt] [PATCH 3/4] qemu: Implement virDomainFSTrim
Peter Krempa
pkrempa at redhat.com
Wed Nov 28 10:51:25 UTC 2012
On 11/20/12 19:47, Michal Privoznik wrote:
> using qemu guest agent. As said in previous patch,
> @mountPoint must be NULL and @flags zero because
> qemu guest agent doesn't support these arguments
> yet. If qemu learns them, we can start supporting
> them as well.
> ---
> src/qemu/qemu_agent.c | 25 ++++++++++++++
> src/qemu/qemu_agent.h | 2 +
> src/qemu/qemu_driver.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 110 insertions(+), 0 deletions(-)
>
> diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c
> index ab6dc22..6f517c9 100644
> --- a/src/qemu/qemu_agent.c
> +++ b/src/qemu/qemu_agent.c
> @@ -1448,3 +1448,28 @@ qemuAgentArbitraryCommand(qemuAgentPtr mon,
> virJSONValueFree(reply);
> return ret;
> }
> +
> +int
> +qemuAgentFSTrim(qemuAgentPtr mon,
> + unsigned long long minimum)
> +{
> + int ret = -1;
> + virJSONValuePtr cmd;
> + virJSONValuePtr reply = NULL;
> +
> + cmd = qemuAgentMakeCommand("guest-fstrim",
> + "U:minimum", minimum,
> + NULL);
> + if (!cmd)
> + return ret;
> +
> + ret = qemuAgentCommand(mon, cmd, &reply,
> + VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK);
I didn't check the full call graph of qemuAgentCommand, but most of the
paths already contain error reporting ... (relevance of this command
will be revealed later :))
> +
> + if (reply && ret == 0)
> + ret = qemuAgentCheckError(cmd, reply);
> +
> + virJSONValueFree(cmd);
> + virJSONValueFree(reply);
> + return ret;
> +}
> diff --git a/src/qemu/qemu_agent.h b/src/qemu/qemu_agent.h
> index c62c438..dad068b 100644
> --- a/src/qemu/qemu_agent.h
> +++ b/src/qemu/qemu_agent.h
> @@ -83,4 +83,6 @@ int qemuAgentArbitraryCommand(qemuAgentPtr mon,
> const char *cmd,
> char **result,
> int timeout);
> +int qemuAgentFSTrim(qemuAgentPtr mon,
> + unsigned long long minimum);
> #endif /* __QEMU_AGENT_H__ */
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 595c452..3dc5bdd 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -14733,6 +14733,88 @@ cleanup:
> return result;
> }
>
> +static int
> +qemuDomainFSTrim(virDomainPtr dom,
> + const char *mountPoint,
> + unsigned long long minimum,
> + unsigned int flags)
> +{
> + struct qemud_driver *driver = dom->conn->privateData;
> + virDomainObjPtr vm;
> + int ret = -1;
> + qemuDomainObjPrivatePtr priv;
> +
> + virCheckFlags(0, -1);
> +
> + if (mountPoint) {
> + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
> + _("Specifying mount point "
> + "is not supported for now"));
> + return -1;
> + }
> +
> + qemuDriverLock(driver);
> + vm = virDomainFindByUUID(&driver->domains, dom->uuid);
> + qemuDriverUnlock(driver);
> +
> + if (!vm) {
> + char uuidstr[VIR_UUID_STRING_BUFLEN];
> + virUUIDFormat(dom->uuid, uuidstr);
> + virReportError(VIR_ERR_NO_DOMAIN,
> + _("no domain with matching uuid '%s'"), uuidstr);
> + goto cleanup;
> + }
You can avoid the two blocks of code above using the
qemuDomObjFromDomain() helper that does that for you.
> +
> + priv = vm->privateData;
> +
> + if (!virDomainObjIsActive(vm)) {
> + virReportError(VIR_ERR_OPERATION_INVALID,
> + "%s", _("domain is not running"));
> + goto cleanup;
> + }
> +
> + if (priv->agentError) {
> + virReportError(VIR_ERR_AGENT_UNRESPONSIVE, "%s",
> + _("QEMU guest agent is not "
> + "available due to an error"));
> + goto cleanup;
> + }
> +
> + if (!priv->agent) {
> + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
> + _("QEMU guest agent is not configured"));
> + goto cleanup;
> + }
I'd swap the two blocks above, it makes more sense to check if there's
an agent error after you check for the agent.
> +
> + 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;
> + }
> +
> + qemuDomainObjEnterAgent(driver, vm);
> + ret = qemuAgentFSTrim(priv->agent, minimum);
> + qemuDomainObjExitAgent(driver, vm);
> + if (ret < 0) {
> + virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> + _("Failed to execute agent command"));
> + goto endjob;
(the relevant part from the comment up)
... this masks the error from the underlying helper function. The goto
statement is redundant here.
> + }
> +
> +endjob:
> + if (qemuDomainObjEndJob(driver, vm) == 0) {
block quotes are not needed here
> + vm = NULL;
> + }
> +
> +cleanup:
> + if (vm)
> + virDomainObjUnlock(vm);
> + return ret;
> +}
> +
> static virDriver qemuDriver = {
> .no = VIR_DRV_QEMU,
> .name = QEMU_DRIVER_NAME,
> @@ -14906,6 +14988,7 @@ static virDriver qemuDriver = {
> .nodeGetMemoryParameters = nodeGetMemoryParameters, /* 0.10.2 */
> .nodeSetMemoryParameters = nodeSetMemoryParameters, /* 0.10.2 */
> .nodeGetCPUMap = nodeGetCPUMap, /* 1.0.0 */
> + .domainFSTrim = qemuDomainFSTrim, /* 1.0.1 */
> };
>
I don't like masking errors from underlying layers. I'd rather have it
changed so that more specific errors are shown but it's not a hard
requirement if you think it's not needed.
More information about the libvir-list
mailing list