[PATCH i-g-t 03/10] tools/vmtb: Fix VM snapshot query handling

Adam Miszczak
2026-02-24T08:23:16Z

QMP command 'query-named-block-nodes' is used to select a block device
for saving VM snapshot (QMP 'snapshot-save').

Add polling for the command's return message in QMP response queue.
It sporadically happened that unsolicited QMP message like:
[QMP RSP] <- {"timestamp": {...}, "event": "RTC_CHANGE" ...}
was falsely taken as a response to previously submitted
QMP 'query-named-block-nodes' command.
Hence, no 'block device node' argument is passed to
'snapshot-load' command which leads to migration tests fail.
Also, add a condition to check if a given block node
is writable (not read-only).

Signed-off-by: Adam Miszczak <adam.miszczak@linux.intel.com>
---
.../machines/virtual/backends/qmp_monitor.py | 25 ++++++++++---------
1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/tools/vmtb/bench/machines/virtual/backends/qmp_monitor.py b/tools/vmtb/bench/machines/virtual/backends/qmp_monitor.py
index ef3c8aa1c..d364a5711 100644
--- a/tools/vmtb/bench/machines/virtual/backends/qmp_monitor.py
+++ b/tools/vmtb/bench/machines/virtual/backends/qmp_monitor.py
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: MIT
-# Copyright © 2024 Intel Corporation
+# Copyright © 2024-2026 Intel Corporation

import json
import logging
@@ -123,17 +123,18 @@ class QmpMonitor():
ret: typing.Dict = {}

qmp_msg = self.qmp_queue.get()
- # logger.debug('[QMP RSP Queue] -> %s', qmp_msg)
- if 'return' in qmp_msg:
- ret = qmp_msg.get('return')
- for block in ret:
- if block.get('drv') == 'qcow2':
- node_name = block.get('node-name')
- # Get the most recent state snapshot from the snapshots list:
- snapshots = block.get('image').get('snapshots')
- if snapshots:
- snapshot_tag = snapshots[-1].get('name')
- break
+ while 'return' not in qmp_msg:
+ qmp_msg = self.qmp_queue.get()
+
+ ret = qmp_msg.get('return')
+ for block in ret:
+ if block.get('drv') == 'qcow2' and block.get('ro') is False:
+ node_name = block.get('node-name')
+ # Get the most recent state snapshot from the snapshots list:
+ snapshots = block.get('image').get('snapshots')
+ if snapshots:
+ snapshot_tag = snapshots[-1].get('name')
+ break

return (node_name, snapshot_tag)

--
2.39.1