From b47e3b9b5c556b7bc3c7d0d1a6452e0df8630653 Mon Sep 17 00:00:00 2001 From: Nikolay Shirokovskiy Date: Thu, 5 Mar 2020 17:47:01 +0300 Subject: [PATCH] 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 Signed-off-by: Michal Privoznik Reviewed-by: Michal Privoznik --- src/qemu/qemu_agent.c | 13 ++++++++++++- src/qemu/qemu_agent.h | 3 ++- src/qemu/qemu_process.c | 3 ++- tests/qemumonitortestutils.c | 3 ++- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c index d183b310cb..f8f197bfc2 100644 --- a/src/qemu/qemu_agent.c +++ b/src/qemu/qemu_agent.c @@ -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: diff --git a/src/qemu/qemu_agent.h b/src/qemu/qemu_agent.h index d4d8615323..67fe9fcde9 100644 --- a/src/qemu/qemu_agent.h +++ b/src/qemu/qemu_agent.h @@ -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); diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 67dad9841a..31cd553afd 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -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); diff --git a/tests/qemumonitortestutils.c b/tests/qemumonitortestutils.c index 328bfb8525..159b1b909e 100644 --- a/tests/qemumonitortestutils.c +++ b/tests/qemumonitortestutils.c @@ -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); -- GitLab