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
- (qemuDomainObjBeginJob) or both at the same time
- (qemuDomainObjBeginJobWithAgent). Which type of job to grab depends
- whether caller wishes to communicate only with agent socket, or only
- with qemu monitor socket or both, respectively.
+ (qemuDomainObjBeginAgentJob), or only normal job (qemuDomainObjBeginJob)
+ 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
+ depends whether caller wishes to communicate only with agent socket, or
+ only with qemu monitor socket.
Immediately after acquiring the virDomainObjPtr lock, any method
which intends to update state must acquire asynchronous, normal or
-To acquire both normal and agent job condition
-
- qemuDomainObjBeginJobWithAgent()
- - Waits until there is no normal and no agent job set
- - Sets both job.active and job.agentActive with required job types
-
- qemuDomainObjEndJobWithAgent()
- - Sets both job.active and job.agentActive to 0
- - Signals on job.cond condition
-
-
-
To acquire the asynchronous job condition
qemuDomainObjBeginAsyncJob()
virDomainObjEndAPI(&obj);
- * Invoking both monitor and agent commands on a virDomainObjPtr
-
- virDomainObjPtr obj;
- qemuAgentPtr agent;
-
- obj = qemuDomObjFromDomain(dom);
-
- qemuDomainObjBeginJobWithAgent(obj, QEMU_JOB_TYPE, QEMU_AGENT_JOB_TYPE);
-
- if (!virDomainObjIsActive(dom))
- goto cleanup;
-
- ...do prep work...
-
- if (!qemuDomainAgentAvailable(obj, true))
- goto cleanup;
-
- agent = qemuDomainObjEnterAgent(obj);
- qemuAgentXXXX(agent, ..);
- qemuDomainObjExitAgent(obj, agent);
-
- ...
-
- qemuDomainObjEnterMonitor(obj);
- qemuMonitorXXXX(priv->mon);
- qemuDomainObjExitMonitor(obj);
-
- /* Alternatively, talk to the monitor first and then talk to the agent. */
-
- ...do final work...
-
- qemuDomainObjEndJobWithAgent(obj);
- virDomainObjEndAPI(&obj);
-
-
* Running asynchronous job
virDomainObjPtr obj;
QEMU_ASYNC_JOB_NONE, false);
}
-/**
- * qemuDomainObjBeginJobWithAgent:
- *
- * Grabs both monitor and agent types of job. Use if caller talks to
- * both monitor and guest agent. However, if @job (or @agentJob) is
- * QEMU_JOB_NONE (or QEMU_AGENT_JOB_NONE) only agent job is acquired (or
- * monitor job).
- *
- * To end job call qemuDomainObjEndJobWithAgent.
- */
-int
-qemuDomainObjBeginJobWithAgent(virQEMUDriverPtr driver,
- virDomainObjPtr obj,
- qemuDomainJob job,
- qemuDomainAgentJob agentJob)
-{
- return qemuDomainObjBeginJobInternal(driver, obj, job, agentJob,
- QEMU_ASYNC_JOB_NONE, false);
-}
-
int qemuDomainObjBeginAsyncJob(virQEMUDriverPtr driver,
virDomainObjPtr obj,
qemuDomainAsyncJob asyncJob,
virCondBroadcast(&priv->job.cond);
}
-void
-qemuDomainObjEndJobWithAgent(virQEMUDriverPtr driver,
- virDomainObjPtr obj)
-{
- qemuDomainObjPrivatePtr priv = obj->privateData;
- qemuDomainJob job = priv->job.active;
- qemuDomainAgentJob agentJob = priv->job.agentActive;
-
- priv->jobs_queued--;
-
- VIR_DEBUG("Stopping both jobs: %s %s (async=%s vm=%p name=%s)",
- qemuDomainJobTypeToString(job),
- qemuDomainAgentJobTypeToString(agentJob),
- qemuDomainAsyncJobTypeToString(priv->job.asyncJob),
- obj, obj->def->name);
-
- qemuDomainObjResetJob(priv);
- qemuDomainObjResetAgentJob(priv);
- if (qemuDomainTrackJob(job))
- qemuDomainObjSaveStatus(driver, obj);
- /* We indeed need to wake up ALL threads waiting because
- * grabbing a job requires checking more variables. */
- virCondBroadcast(&priv->job.cond);
-}
-
void
qemuDomainObjEndAsyncJob(virQEMUDriverPtr driver, virDomainObjPtr obj)
{
* obj must be locked before calling
*
* To be called immediately before any QEMU monitor API call
- * Must have already either called qemuDomainObjBeginJob() or
- * qemuDomainObjBeginJobWithAgent() and checked that the VM is
- * still active; may not be used for nested async jobs.
+ * Must have already called qemuDomainObjBeginJob() and checked
+ * that the VM is still active; may not be used for nested async
+ * jobs.
*
* To be followed with qemuDomainObjExitMonitor() once complete
*/
* obj must be locked before calling
*
* To be called immediately before any QEMU agent API call.
- * Must have already called qemuDomainObjBeginAgentJob() or
- * qemuDomainObjBeginJobWithAgent() and checked that the VM is
- * still active.
+ * Must have already called qemuDomainObjBeginAgentJob() and
+ * checked that the VM is still active.
*
* To be followed with qemuDomainObjExitAgent() once complete
*/
virDomainObjPtr obj,
qemuDomainAgentJob agentJob)
G_GNUC_WARN_UNUSED_RESULT;
-int qemuDomainObjBeginJobWithAgent(virQEMUDriverPtr driver,
- virDomainObjPtr obj,
- qemuDomainJob job,
- qemuDomainAgentJob agentJob)
- G_GNUC_WARN_UNUSED_RESULT;
int qemuDomainObjBeginAsyncJob(virQEMUDriverPtr driver,
virDomainObjPtr obj,
qemuDomainAsyncJob asyncJob,
void qemuDomainObjEndJob(virQEMUDriverPtr driver,
virDomainObjPtr obj);
void qemuDomainObjEndAgentJob(virDomainObjPtr obj);
-void qemuDomainObjEndJobWithAgent(virQEMUDriverPtr driver,
- virDomainObjPtr obj);
void qemuDomainObjEndAsyncJob(virQEMUDriverPtr driver,
virDomainObjPtr obj);
void qemuDomainObjAbortAsyncJob(virDomainObjPtr obj);