On 3/11/20 12:12 PM, Nikolay Shirokovskiy wrote:
On 11.03.2020 12:38, Michal Privoznik wrote:
On 3/5/20 3:47 PM, Nikolay Shirokovskiy wrote:
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.
Can you elaborate more on the raciness? There should never be more than one thread talking on the agent monitor.
The race is in another dimension) So sync checks for GA presence, it only waits for 5s so if
there is no GA the actual command with no timeout won't block. But GA can go down right
after successful sync so command can block. This is true if there are no serial events
in the latter case agent monitor will be closed when GA go down and command will unblock.
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@xxxxxxxxxxxxx>
---
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 cd25ef6cd3..2de53efb7a 100644
--- a/src/qemu/qemu_agent.c
+++ b/src/qemu/qemu_agent.c
@@ -104,6 +104,8 @@ struct _qemuAgent {
int watch;
bool running;
+ bool singleSync;
+ bool inSync;
I wonder if we can do this with just inSync and not have singleSync. I mean, it looks like at all places where singleSync is used we have access to qemuCaps so it should be as easy as:
qemuAgentOpen();
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VSERPORT_CHANGE)) {
if *qemuAgentGuestSync(mon) < 0)
goto error;
mon->inSync = true;
and then qemuagentGuestSync() would be a NOP if inSync is set. But it would also not set it. But maybe I'm pushing it too far, it's just that I'm confused by the name 'singleSync'. Probably 'hasSingleSync' would be better? The boolean reflect whether qemu has the VSERPORT_CHANGE capability and thus libvirt knows when GA connects/disconnects. 'singleSync' just doesn't ring that bell at first.
If we try to sync only on monitor opening then we can't sync if for example command timeouts and
GA stays connect (thus no serial event and monitor won't be closed). With current patch we just
try to sync when we need to send next command to GA.
I guess singleSync is better. It just reflects that we don't need to sync before every
command (in order to avoid hangs) in case there is serial events. Strictly speaking
it is not correct to use sync to check for GA presence because of the race and as to
using it as a means to flush channel it works well without sereal events as well.
Nikolay
Alright, you've persuaded me on both.
Reviewed-by: Michal Privoznik <mprivozn@xxxxxxxxxx>
and resolved the merge commit on both patches that appeared meanwhile
and pushed.
Michal