qemu & conf: move BeginAgentJob & EndAgentJob into src/conf/virdomainjob

Although these and functions in the following two patches are for
now just being used by the qemu driver, it makes sense to have all
begin job functions in the same file.

Signed-off-by: Kristina Hanicova <khanicov@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Kristina Hanicova 2022-09-05 15:57:13 +02:00 committed by Ján Tomko
parent ac57f744fc
commit 421f1e749f
9 changed files with 92 additions and 90 deletions

View File

@ -62,7 +62,7 @@ There are a number of locks on various objects
Agent job condition is then used when thread wishes to talk to qemu
agent monitor. It is possible to acquire just agent job
(``qemuDomainObjBeginAgentJob``), or only normal job (``virDomainObjBeginJob``)
(``virDomainObjBeginAgentJob``), or only normal job (``virDomainObjBeginJob``)
but not both at the same time. Holding an agent job and a normal job would
allow an unresponsive or malicious agent to block normal libvirt API and
potentially result in a denial of service. Which type of job to grab
@ -130,11 +130,11 @@ To acquire the normal job condition
To acquire the agent job condition
``qemuDomainObjBeginAgentJob()``
``virDomainObjBeginAgentJob()``
- Waits until there is no other agent job set
- Sets ``job.agentActive`` to the job type
``qemuDomainObjEndAgentJob()``
``virDomainObjEndAgentJob()``
- Sets ``job.agentActive`` to 0
- Signals on ``job.cond`` condition
@ -253,7 +253,7 @@ Design patterns
obj = qemuDomObjFromDomain(dom);
qemuDomainObjBeginAgentJob(obj, VIR_AGENT_JOB_TYPE);
virDomainObjBeginAgentJob(obj, VIR_AGENT_JOB_TYPE);
...do prep work...
@ -266,7 +266,7 @@ Design patterns
...do final work...
qemuDomainObjEndAgentJob(obj);
virDomainObjEndAgentJob(obj);
virDomainObjEndAPI(&obj);

View File

@ -528,6 +528,22 @@ int virDomainObjBeginJob(virDomainObj *obj,
return 0;
}
/**
* virDomainObjBeginAgentJob:
*
* Grabs agent type of job. Use if caller talks to guest agent only.
*
* To end job call virDomainObjEndAgentJob.
*/
int
virDomainObjBeginAgentJob(virDomainObj *obj,
virDomainAgentJob agentJob)
{
return virDomainObjBeginJobInternal(obj, obj->job, VIR_JOB_NONE,
agentJob,
VIR_ASYNC_JOB_NONE, false);
}
/*
* obj must be locked and have a reference before calling
*
@ -555,3 +571,21 @@ virDomainObjEndJob(virDomainObj *obj)
* grabbing a job requires checking more variables. */
virCondBroadcast(&obj->job->cond);
}
void
virDomainObjEndAgentJob(virDomainObj *obj)
{
virDomainAgentJob agentJob = obj->job->agentActive;
obj->job->jobsQueued--;
VIR_DEBUG("Stopping agent job: %s (async=%s vm=%p name=%s)",
virDomainAgentJobTypeToString(agentJob),
virDomainAsyncJobTypeToString(obj->job->asyncJob),
obj, obj->def->name);
virDomainObjResetAgentJob(obj->job);
/* We indeed need to wake up ALL threads waiting because
* grabbing a job requires checking more variables. */
virCondBroadcast(&obj->job->cond);
}

View File

@ -249,5 +249,9 @@ int virDomainObjBeginJobInternal(virDomainObj *obj,
int virDomainObjBeginJob(virDomainObj *obj,
virDomainJob job)
G_GNUC_WARN_UNUSED_RESULT;
int virDomainObjBeginAgentJob(virDomainObj *obj,
virDomainAgentJob agentJob)
G_GNUC_WARN_UNUSED_RESULT;
void virDomainObjEndJob(virDomainObj *obj);
void virDomainObjEndAgentJob(virDomainObj *obj);

View File

@ -1187,10 +1187,12 @@ virDomainJobStatusToType;
virDomainJobTypeFromString;
virDomainJobTypeToString;
virDomainNestedJobAllowed;
virDomainObjBeginAgentJob;
virDomainObjBeginJob;
virDomainObjBeginJobInternal;
virDomainObjCanSetJob;
virDomainObjClearJob;
virDomainObjEndAgentJob;
virDomainObjEndJob;
virDomainObjInitJob;
virDomainObjPreserveJob;

View File

@ -6057,7 +6057,7 @@ qemuDomainObjEnterMonitorAsync(virDomainObj *obj,
* obj must be locked before calling
*
* To be called immediately before any QEMU agent API call.
* Must have already called qemuDomainObjBeginAgentJob() and
* Must have already called virDomainObjBeginAgentJob() and
* checked that the VM is still active.
*
* To be followed with qemuDomainObjExitAgent() once complete

View File

@ -655,22 +655,6 @@ qemuDomainObjReleaseAsyncJob(virDomainObj *obj)
obj->job->asyncOwner = 0;
}
/**
* qemuDomainObjBeginAgentJob:
*
* Grabs agent type of job. Use if caller talks to guest agent only.
*
* To end job call qemuDomainObjEndAgentJob.
*/
int
qemuDomainObjBeginAgentJob(virDomainObj *obj,
virDomainAgentJob agentJob)
{
return virDomainObjBeginJobInternal(obj, obj->job, VIR_JOB_NONE,
agentJob,
VIR_ASYNC_JOB_NONE, false);
}
int qemuDomainObjBeginAsyncJob(virDomainObj *obj,
virDomainAsyncJob asyncJob,
virDomainJobOperation operation,
@ -730,24 +714,6 @@ qemuDomainObjBeginJobNowait(virDomainObj *obj,
VIR_ASYNC_JOB_NONE, true);
}
void
qemuDomainObjEndAgentJob(virDomainObj *obj)
{
virDomainAgentJob agentJob = obj->job->agentActive;
obj->job->jobsQueued--;
VIR_DEBUG("Stopping agent job: %s (async=%s vm=%p name=%s)",
virDomainAgentJobTypeToString(agentJob),
virDomainAsyncJobTypeToString(obj->job->asyncJob),
obj, obj->def->name);
virDomainObjResetAgentJob(obj->job);
/* We indeed need to wake up ALL threads waiting because
* grabbing a job requires checking more variables. */
virCondBroadcast(&obj->job->cond);
}
void
qemuDomainObjEndAsyncJob(virDomainObj *obj)
{

View File

@ -69,9 +69,6 @@ int qemuDomainAsyncJobPhaseFromString(virDomainAsyncJob job,
void qemuDomainEventEmitJobCompleted(virQEMUDriver *driver,
virDomainObj *vm);
int qemuDomainObjBeginAgentJob(virDomainObj *obj,
virDomainAgentJob agentJob)
G_GNUC_WARN_UNUSED_RESULT;
int qemuDomainObjBeginAsyncJob(virDomainObj *obj,
virDomainAsyncJob asyncJob,
virDomainJobOperation operation,
@ -84,7 +81,6 @@ int qemuDomainObjBeginJobNowait(virDomainObj *obj,
virDomainJob job)
G_GNUC_WARN_UNUSED_RESULT;
void qemuDomainObjEndAgentJob(virDomainObj *obj);
void qemuDomainObjEndAsyncJob(virDomainObj *obj);
void qemuDomainObjAbortAsyncJob(virDomainObj *obj);
void qemuDomainObjSetJobPhase(virDomainObj *obj,

View File

@ -1781,7 +1781,7 @@ qemuDomainShutdownFlagsAgent(virDomainObj *vm,
int agentFlag = isReboot ? QEMU_AGENT_SHUTDOWN_REBOOT :
QEMU_AGENT_SHUTDOWN_POWERDOWN;
if (qemuDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_MODIFY) < 0)
if (virDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_MODIFY) < 0)
return -1;
if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_RUNNING) {
@ -1799,7 +1799,7 @@ qemuDomainShutdownFlagsAgent(virDomainObj *vm,
qemuDomainObjExitAgent(vm, agent);
endjob:
qemuDomainObjEndAgentJob(vm);
virDomainObjEndAgentJob(vm);
return ret;
}
@ -1909,7 +1909,7 @@ qemuDomainRebootAgent(virDomainObj *vm,
if (!isReboot)
agentFlag = QEMU_AGENT_SHUTDOWN_POWERDOWN;
if (qemuDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_MODIFY) < 0)
if (virDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_MODIFY) < 0)
return -1;
if (!qemuDomainAgentAvailable(vm, agentForced))
@ -1924,7 +1924,7 @@ qemuDomainRebootAgent(virDomainObj *vm,
qemuDomainObjExitAgent(vm, agent);
endjob:
qemuDomainObjEndAgentJob(vm);
virDomainObjEndAgentJob(vm);
return ret;
}
@ -4368,7 +4368,7 @@ qemuDomainSetVcpusFlags(virDomainPtr dom,
if (useAgent) {
if (qemuDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_MODIFY) < 0)
if (virDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_MODIFY) < 0)
goto cleanup;
} else {
if (virDomainObjBeginJob(vm, VIR_JOB_MODIFY) < 0)
@ -4388,7 +4388,7 @@ qemuDomainSetVcpusFlags(virDomainPtr dom,
endjob:
if (useAgent)
qemuDomainObjEndAgentJob(vm);
virDomainObjEndAgentJob(vm);
else
virDomainObjEndJob(vm);
@ -4809,7 +4809,7 @@ qemuDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
goto cleanup;
if (flags & VIR_DOMAIN_VCPU_GUEST) {
if (qemuDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_QUERY) < 0)
if (virDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_QUERY) < 0)
goto cleanup;
if (!virDomainObjIsActive(vm)) {
@ -4827,7 +4827,7 @@ qemuDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
qemuDomainObjExitAgent(vm, agent);
endjob:
qemuDomainObjEndAgentJob(vm);
virDomainObjEndAgentJob(vm);
if (ncpuinfo < 0)
goto cleanup;
@ -16596,7 +16596,7 @@ qemuDomainPMSuspendAgent(virDomainObj *vm,
qemuAgent *agent;
int ret = -1;
if (qemuDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_MODIFY) < 0)
if (virDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_MODIFY) < 0)
return -1;
if (virDomainObjCheckActive(vm) < 0)
@ -16610,7 +16610,7 @@ qemuDomainPMSuspendAgent(virDomainObj *vm,
qemuDomainObjExitAgent(vm, agent);
endjob:
qemuDomainObjEndAgentJob(vm);
virDomainObjEndAgentJob(vm);
return ret;
}
@ -16762,7 +16762,7 @@ qemuDomainQemuAgentCommand(virDomainPtr domain,
if (virDomainQemuAgentCommandEnsureACL(domain->conn, vm->def) < 0)
goto cleanup;
if (qemuDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_MODIFY) < 0)
if (virDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_MODIFY) < 0)
goto cleanup;
if (virDomainObjCheckActive(vm) < 0)
@ -16780,7 +16780,7 @@ qemuDomainQemuAgentCommand(virDomainPtr domain,
VIR_FREE(result);
endjob:
qemuDomainObjEndAgentJob(vm);
virDomainObjEndAgentJob(vm);
cleanup:
virDomainObjEndAPI(&vm);
@ -16856,7 +16856,7 @@ qemuDomainFSTrim(virDomainPtr dom,
if (virDomainFSTrimEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;
if (qemuDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_MODIFY) < 0)
if (virDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_MODIFY) < 0)
goto cleanup;
if (!qemuDomainAgentAvailable(vm, true))
@ -16870,7 +16870,7 @@ qemuDomainFSTrim(virDomainPtr dom,
qemuDomainObjExitAgent(vm, agent);
endjob:
qemuDomainObjEndAgentJob(vm);
virDomainObjEndAgentJob(vm);
cleanup:
virDomainObjEndAPI(&vm);
@ -17026,7 +17026,7 @@ qemuDomainGetHostnameAgent(virDomainObj *vm,
qemuAgent *agent;
int ret = -1;
if (qemuDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_QUERY) < 0)
if (virDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_QUERY) < 0)
return -1;
if (virDomainObjCheckActive(vm) < 0)
@ -17041,7 +17041,7 @@ qemuDomainGetHostnameAgent(virDomainObj *vm,
ret = 0;
endjob:
qemuDomainObjEndAgentJob(vm);
virDomainObjEndAgentJob(vm);
return ret;
}
@ -17167,7 +17167,7 @@ qemuDomainGetTime(virDomainPtr dom,
if (virDomainGetTimeEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;
if (qemuDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_QUERY) < 0)
if (virDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_QUERY) < 0)
goto cleanup;
if (virDomainObjCheckActive(vm) < 0)
@ -17186,7 +17186,7 @@ qemuDomainGetTime(virDomainPtr dom,
ret = 0;
endjob:
qemuDomainObjEndAgentJob(vm);
virDomainObjEndAgentJob(vm);
cleanup:
virDomainObjEndAPI(&vm);
@ -17203,7 +17203,7 @@ qemuDomainSetTimeAgent(virDomainObj *vm,
qemuAgent *agent;
int ret = -1;
if (qemuDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_MODIFY) < 0)
if (virDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_MODIFY) < 0)
return -1;
if (virDomainObjCheckActive(vm) < 0)
@ -17217,7 +17217,7 @@ qemuDomainSetTimeAgent(virDomainObj *vm,
qemuDomainObjExitAgent(vm, agent);
endjob:
qemuDomainObjEndAgentJob(vm);
virDomainObjEndAgentJob(vm);
return ret;
}
@ -17303,7 +17303,7 @@ qemuDomainFSFreeze(virDomainPtr dom,
if (virDomainFSFreezeEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;
if (qemuDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_MODIFY) < 0)
if (virDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_MODIFY) < 0)
goto cleanup;
if (virDomainObjCheckActive(vm) < 0)
@ -17312,7 +17312,7 @@ qemuDomainFSFreeze(virDomainPtr dom,
ret = qemuSnapshotFSFreeze(vm, mountpoints, nmountpoints);
endjob:
qemuDomainObjEndAgentJob(vm);
virDomainObjEndAgentJob(vm);
cleanup:
virDomainObjEndAPI(&vm);
@ -17343,7 +17343,7 @@ qemuDomainFSThaw(virDomainPtr dom,
if (virDomainFSThawEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;
if (qemuDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_MODIFY) < 0)
if (virDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_MODIFY) < 0)
goto cleanup;
if (virDomainObjCheckActive(vm) < 0)
@ -17352,7 +17352,7 @@ qemuDomainFSThaw(virDomainPtr dom,
ret = qemuSnapshotFSThaw(vm, true);
endjob:
qemuDomainObjEndAgentJob(vm);
virDomainObjEndAgentJob(vm);
cleanup:
virDomainObjEndAPI(&vm);
@ -18906,7 +18906,7 @@ qemuDomainGetFSInfoAgent(virDomainObj *vm,
int ret = -1;
qemuAgent *agent;
if (qemuDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_QUERY) < 0)
if (virDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_QUERY) < 0)
return ret;
if (virDomainObjCheckActive(vm) < 0)
@ -18920,7 +18920,7 @@ qemuDomainGetFSInfoAgent(virDomainObj *vm,
qemuDomainObjExitAgent(vm, agent);
endjob:
qemuDomainObjEndAgentJob(vm);
virDomainObjEndAgentJob(vm);
return ret;
}
@ -19065,7 +19065,7 @@ qemuDomainInterfaceAddresses(virDomainPtr dom,
break;
case VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT:
if (qemuDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_QUERY) < 0)
if (virDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_QUERY) < 0)
goto cleanup;
if (!qemuDomainAgentAvailable(vm, true))
@ -19076,7 +19076,7 @@ qemuDomainInterfaceAddresses(virDomainPtr dom,
qemuDomainObjExitAgent(vm, agent);
endjob:
qemuDomainObjEndAgentJob(vm);
virDomainObjEndAgentJob(vm);
break;
@ -19116,7 +19116,7 @@ qemuDomainSetUserPassword(virDomainPtr dom,
if (virDomainSetUserPasswordEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;
if (qemuDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_MODIFY) < 0)
if (virDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_MODIFY) < 0)
goto cleanup;
if (virDomainObjCheckActive(vm) < 0)
@ -19136,7 +19136,7 @@ qemuDomainSetUserPassword(virDomainPtr dom,
ret = 0;
endjob:
qemuDomainObjEndAgentJob(vm);
virDomainObjEndAgentJob(vm);
cleanup:
virDomainObjEndAPI(&vm);
@ -19419,7 +19419,7 @@ qemuDomainGetGuestVcpus(virDomainPtr dom,
if (virDomainGetGuestVcpusEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;
if (qemuDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_QUERY) < 0)
if (virDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_QUERY) < 0)
goto cleanup;
if (!qemuDomainAgentAvailable(vm, true))
@ -19438,7 +19438,7 @@ qemuDomainGetGuestVcpus(virDomainPtr dom,
ret = 0;
endjob:
qemuDomainObjEndAgentJob(vm);
virDomainObjEndAgentJob(vm);
cleanup:
VIR_FREE(info);
@ -19477,7 +19477,7 @@ qemuDomainSetGuestVcpus(virDomainPtr dom,
if (virDomainSetGuestVcpusEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;
if (qemuDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_MODIFY) < 0)
if (virDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_MODIFY) < 0)
goto cleanup;
if (!qemuDomainAgentAvailable(vm, true))
@ -19523,7 +19523,7 @@ qemuDomainSetGuestVcpus(virDomainPtr dom,
qemuDomainObjExitAgent(vm, agent);
endjob:
qemuDomainObjEndAgentJob(vm);
virDomainObjEndAgentJob(vm);
cleanup:
VIR_FREE(info);
@ -20438,7 +20438,7 @@ qemuDomainGetGuestInfo(virDomainPtr dom,
if (virDomainGetGuestInfoEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;
if (qemuDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_QUERY) < 0)
if (virDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_QUERY) < 0)
goto cleanup;
if (!qemuDomainAgentAvailable(vm, true))
@ -20496,7 +20496,7 @@ qemuDomainGetGuestInfo(virDomainPtr dom,
}
qemuDomainObjExitAgent(vm, agent);
qemuDomainObjEndAgentJob(vm);
virDomainObjEndAgentJob(vm);
if (nfs > 0 || ndisks > 0) {
if (virDomainObjBeginJob(vm, VIR_JOB_QUERY) < 0)
@ -20543,7 +20543,7 @@ qemuDomainGetGuestInfo(virDomainPtr dom,
qemuDomainObjExitAgent(vm, agent);
endagentjob:
qemuDomainObjEndAgentJob(vm);
virDomainObjEndAgentJob(vm);
goto cleanup;
}
@ -20614,7 +20614,7 @@ qemuDomainAuthorizedSSHKeysGet(virDomainPtr dom,
if (virDomainAuthorizedSshKeysGetEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;
if (qemuDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_QUERY) < 0)
if (virDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_QUERY) < 0)
goto cleanup;
if (!qemuDomainAgentAvailable(vm, true))
@ -20625,7 +20625,7 @@ qemuDomainAuthorizedSSHKeysGet(virDomainPtr dom,
qemuDomainObjExitAgent(vm, agent);
endagentjob:
qemuDomainObjEndAgentJob(vm);
virDomainObjEndAgentJob(vm);
cleanup:
virDomainObjEndAPI(&vm);
return rv;
@ -20654,7 +20654,7 @@ qemuDomainAuthorizedSSHKeysSet(virDomainPtr dom,
if (virDomainAuthorizedSshKeysSetEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;
if (qemuDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_QUERY) < 0)
if (virDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_QUERY) < 0)
goto cleanup;
if (!qemuDomainAgentAvailable(vm, true))
@ -20668,7 +20668,7 @@ qemuDomainAuthorizedSSHKeysSet(virDomainPtr dom,
qemuDomainObjExitAgent(vm, agent);
endagentjob:
qemuDomainObjEndAgentJob(vm);
virDomainObjEndAgentJob(vm);
cleanup:
virDomainObjEndAPI(&vm);
return rv;

View File

@ -1277,16 +1277,16 @@ qemuSnapshotCreateActiveExternal(virQEMUDriver *driver,
if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE) {
int frozen;
if (qemuDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_MODIFY) < 0)
if (virDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_MODIFY) < 0)
goto cleanup;
if (virDomainObjCheckActive(vm) < 0) {
qemuDomainObjEndAgentJob(vm);
virDomainObjEndAgentJob(vm);
goto cleanup;
}
frozen = qemuSnapshotFSFreeze(vm, NULL, 0);
qemuDomainObjEndAgentJob(vm);
virDomainObjEndAgentJob(vm);
if (frozen < 0)
goto cleanup;
@ -1422,13 +1422,13 @@ qemuSnapshotCreateActiveExternal(virQEMUDriver *driver,
}
if (thaw &&
qemuDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_MODIFY) >= 0 &&
virDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_MODIFY) >= 0 &&
virDomainObjIsActive(vm)) {
/* report error only on an otherwise successful snapshot */
if (qemuSnapshotFSThaw(vm, ret == 0) < 0)
ret = -1;
qemuDomainObjEndAgentJob(vm);
virDomainObjEndAgentJob(vm);
}
virQEMUSaveDataFree(data);