mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-22 03:12:22 +00:00
qemuAgentOpen: Rework domain object refcounting
Currently, when opening an agent socket the qemuConnectAgent() increments domain object refcounter and calls qemuAgentOpen() where the domain object pointer is simply stored inside _qemuAgent struct. If qemuAgentOpen() fails, then it clears @cb member only to avoid qemuProcessHandleAgentDestroy() being called (which decrements the domain object refcounter) and the domain object refcounter is then decreased explicitly in qemuConnectAgent(). The same result can be achieved with much cleaner code: increment the refcounter inside qemuAgentOpen() and drop the dance around @cb. Also, the comment in qemuConnectAgent() about holding an extra reference is not correct. The thread that called qemuConnectAgent() already holds a reference to the domain object. No matter how many time the object is locked and unlocked the reference counter can't be decreased. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
108e131a3d
commit
0a9cb29ba2
@ -160,9 +160,11 @@ qemuAgentEscapeNonPrintable(const char *text)
|
||||
static void qemuAgentDispose(void *obj)
|
||||
{
|
||||
qemuAgent *agent = obj;
|
||||
|
||||
VIR_DEBUG("agent=%p", agent);
|
||||
if (agent->cb && agent->cb->destroy)
|
||||
(agent->cb->destroy)(agent, agent->vm);
|
||||
|
||||
if (agent->vm)
|
||||
virObjectUnref(agent->vm);
|
||||
virCondDestroy(&agent->notify);
|
||||
g_free(agent->buffer);
|
||||
g_main_context_unref(agent->context);
|
||||
@ -671,7 +673,7 @@ qemuAgentOpen(virDomainObj *vm,
|
||||
virObjectUnref(agent);
|
||||
return NULL;
|
||||
}
|
||||
agent->vm = vm;
|
||||
agent->vm = virObjectRef(vm);
|
||||
agent->cb = cb;
|
||||
agent->singleSync = singleSync;
|
||||
|
||||
@ -707,12 +709,6 @@ qemuAgentOpen(virDomainObj *vm,
|
||||
return agent;
|
||||
|
||||
cleanup:
|
||||
/* We don't want the 'destroy' callback invoked during
|
||||
* cleanup from construction failure, because that can
|
||||
* give a double-unref on virDomainObj *in the caller,
|
||||
* so kill the callbacks now.
|
||||
*/
|
||||
agent->cb = NULL;
|
||||
qemuAgentClose(agent);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -234,19 +234,12 @@ qemuConnectAgent(virQEMUDriver *driver, virDomainObj *vm)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Hold an extra reference because we can't allow 'vm' to be
|
||||
* deleted while the agent is active */
|
||||
virObjectRef(vm);
|
||||
|
||||
agent = qemuAgentOpen(vm,
|
||||
config->source,
|
||||
virEventThreadGetContext(priv->eventThread),
|
||||
&agentCallbacks,
|
||||
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VSERPORT_CHANGE));
|
||||
|
||||
if (agent == NULL)
|
||||
virObjectUnref(vm);
|
||||
|
||||
if (!virDomainObjIsActive(vm)) {
|
||||
qemuAgentClose(agent);
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
|
Loading…
x
Reference in New Issue
Block a user