qemu: agent: sync once if qemu has serial port event

Sync was introduced in [1] to check for ga presence. This
check is racy but in the era before serial events are available
there was not better solution I guess.

In case we have the events the sync function is different. It allows us
to flush stateless ga channel from remnants of previous communications.
But we need to do it only once. Until we get timeout on issued command
channel state is ok.

[1] qemu_agent: Issue guest-sync prior to every command

Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy@virtuozzo.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Nikolay Shirokovskiy 2020-03-05 17:47:01 +03:00 committed by Michal Privoznik
parent a30078cb83
commit b47e3b9b5c
4 changed files with 18 additions and 4 deletions

View File

@ -108,6 +108,8 @@ struct _qemuAgent {
GSource *watch;
bool running;
bool singleSync;
bool inSync;
virDomainObjPtr vm;
@ -673,7 +675,8 @@ qemuAgentPtr
qemuAgentOpen(virDomainObjPtr vm,
const virDomainChrSourceDef *config,
GMainContext *context,
qemuAgentCallbacksPtr cb)
qemuAgentCallbacksPtr cb,
bool singleSync)
{
qemuAgentPtr agent;
g_autoptr(GError) gerr = NULL;
@ -700,6 +703,7 @@ qemuAgentOpen(virDomainObjPtr vm,
}
agent->vm = vm;
agent->cb = cb;
agent->singleSync = singleSync;
if (config->type != VIR_DOMAIN_CHR_TYPE_UNIX) {
virReportError(VIR_ERR_INTERNAL_ERROR,
@ -853,6 +857,7 @@ static int qemuAgentSend(qemuAgentPtr agent,
_("Unable to wait on agent socket "
"condition"));
}
agent->inSync = false;
goto cleanup;
}
}
@ -894,6 +899,9 @@ qemuAgentGuestSync(qemuAgentPtr agent)
qemuAgentMessage sync_msg;
int timeout = VIR_DOMAIN_QEMU_AGENT_COMMAND_DEFAULT;
if (agent->singleSync && agent->inSync)
return 0;
/* if user specified a custom agent timeout that is lower than the
* default timeout, use the shorter timeout instead */
if ((agent->timeout >= 0) && (agent->timeout < timeout))
@ -939,6 +947,9 @@ qemuAgentGuestSync(qemuAgentPtr agent)
}
}
if (agent->singleSync)
agent->inSync = true;
ret = 0;
cleanup:

View File

@ -42,7 +42,8 @@ struct _qemuAgentCallbacks {
qemuAgentPtr qemuAgentOpen(virDomainObjPtr vm,
const virDomainChrSourceDef *config,
GMainContext *context,
qemuAgentCallbacksPtr cb);
qemuAgentCallbacksPtr cb,
bool singleSync);
void qemuAgentClose(qemuAgentPtr mon);

View File

@ -238,7 +238,8 @@ qemuConnectAgent(virQEMUDriverPtr driver, virDomainObjPtr vm)
agent = qemuAgentOpen(vm,
config->source,
virEventThreadGetContext(priv->eventThread),
&agentCallbacks);
&agentCallbacks,
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VSERPORT_CHANGE));
virObjectLock(vm);

View File

@ -1407,7 +1407,8 @@ qemuMonitorTestNewAgent(virDomainXMLOptionPtr xmlopt)
if (!(test->agent = qemuAgentOpen(test->vm,
&src,
virEventThreadGetContext(test->eventThread),
&qemuMonitorTestAgentCallbacks)))
&qemuMonitorTestAgentCallbacks,
false)))
goto error;
virObjectLock(test->agent);