aboutsummaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2019-06-14 14:46:13 +0100
committerPeter Maydell <peter.maydell@linaro.org>2019-06-14 14:46:13 +0100
commitf3d0bec9f80e4ed7796fffa834ba0a53f2094f7f (patch)
tree94b53ffb785bd696cf62e350dd44b0005c801e8a /python
parent5ec2eca83dc478ddf24077e02a8b34dd26cd3ff9 (diff)
parent21c1ce592a144188dfe59b9e156a97da412a59a2 (diff)
downloadqemu-f3d0bec9f80e4ed7796fffa834ba0a53f2094f7f.zip
qemu-f3d0bec9f80e4ed7796fffa834ba0a53f2094f7f.tar.gz
qemu-f3d0bec9f80e4ed7796fffa834ba0a53f2094f7f.tar.bz2
Merge remote-tracking branch 'remotes/maxreitz/tags/pull-block-2019-06-14' into staging
Block patches: - Allow blockdev-backup from nodes that are not in qemu's main AIO context to newly added nodes - Add salvaging mode to qemu-img convert - Minor fixes to tests, documentation, and for less Valgrind annoyance # gpg: Signature made Fri 14 Jun 2019 14:38:11 BST # gpg: using RSA key 91BEB60A30DB3E8857D11829F407DB0061D5CF40 # gpg: issuer "mreitz@redhat.com" # gpg: Good signature from "Max Reitz <mreitz@redhat.com>" [full] # Primary key fingerprint: 91BE B60A 30DB 3E88 57D1 1829 F407 DB00 61D5 CF40 * remotes/maxreitz/tags/pull-block-2019-06-14: iotests: Test qemu-img convert -C --salvage iotests: Test qemu-img convert --salvage blkdebug: Inject errors on .bdrv_co_block_status() blkdebug: Add "none" event blkdebug: Add @iotype error option qemu-img: Add salvaging mode to convert qemu-img: Move quiet into ImgConvertState blockdev: Overlays are not snapshots qapi/block-core: Overlays are not snapshots qemu-img: Fix options leakage in img_rebase() iotests: restrict 254 to support only qcow2 hw/block/fdc: floppy command FIFO memory initialization iotests: Fix intermittent failure in 219 iotests: Filter 175's allocation information event_match: always match on None value iotests: add iotest 256 for testing blockdev-backup across iothread contexts iotests.py: rewrite run_job to be pickier QEMUMachine: add events_wait method iotests.py: do not use infinite waits blockdev-backup: don't check aio_context too early Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'python')
-rw-r--r--python/qemu/__init__.py67
1 files changed, 50 insertions, 17 deletions
diff --git a/python/qemu/__init__.py b/python/qemu/__init__.py
index 81d9657..dbaf8a5 100644
--- a/python/qemu/__init__.py
+++ b/python/qemu/__init__.py
@@ -402,42 +402,75 @@ class QEMUMachine(object):
self._qmp.clear_events()
return events
- def event_wait(self, name, timeout=60.0, match=None):
+ @staticmethod
+ def event_match(event, match=None):
"""
- Wait for specified timeout on named event in QMP; optionally filter
- results by match.
+ Check if an event matches optional match criteria.
+
+ The match criteria takes the form of a matching subdict. The event is
+ checked to be a superset of the subdict, recursively, with matching
+ values whenever the subdict values are not None.
- The 'match' is checked to be a recursive subset of the 'event'; skips
- branch processing on match's value None
- {"foo": {"bar": 1}} matches {"foo": None}
- {"foo": {"bar": 1}} does not matches {"foo": {"baz": None}}
+ This has a limitation that you cannot explicitly check for None values.
+
+ Examples, with the subdict queries on the left:
+ - None matches any object.
+ - {"foo": None} matches {"foo": {"bar": 1}}
+ - {"foo": None} matches {"foo": 5}
+ - {"foo": {"abc": None}} does not match {"foo": {"bar": 1}}
+ - {"foo": {"rab": 2}} matches {"foo": {"bar": 1, "rab": 2}}
"""
- def event_match(event, match=None):
- if match is None:
- return True
+ if match is None:
+ return True
+ try:
for key in match:
if key in event:
- if isinstance(event[key], dict):
- if not event_match(event[key], match[key]):
- return False
- elif event[key] != match[key]:
+ if not QEMUMachine.event_match(event[key], match[key]):
return False
else:
return False
-
return True
+ except TypeError:
+ # either match or event wasn't iterable (not a dict)
+ return match == event
+
+ def event_wait(self, name, timeout=60.0, match=None):
+ """
+ event_wait waits for and returns a named event from QMP with a timeout.
+
+ name: The event to wait for.
+ timeout: QEMUMonitorProtocol.pull_event timeout parameter.
+ match: Optional match criteria. See event_match for details.
+ """
+ return self.events_wait([(name, match)], timeout)
+
+ def events_wait(self, events, timeout=60.0):
+ """
+ events_wait waits for and returns a named event from QMP with a timeout.
+
+ events: a sequence of (name, match_criteria) tuples.
+ The match criteria are optional and may be None.
+ See event_match for details.
+ timeout: QEMUMonitorProtocol.pull_event timeout parameter.
+ """
+ def _match(event):
+ for name, match in events:
+ if (event['event'] == name and
+ self.event_match(event, match)):
+ return True
+ return False
# Search cached events
for event in self._events:
- if (event['event'] == name) and event_match(event, match):
+ if _match(event):
self._events.remove(event)
return event
# Poll for new events
while True:
event = self._qmp.pull_event(wait=timeout)
- if (event['event'] == name) and event_match(event, match):
+ if _match(event):
return event
self._events.append(event)