]> git.proxmox.com Git - pve-qemu.git/blame - debian/patches/pve/0035-iotests-add-test-for-bitmap-mirror.patch
Update to QEMU 5.2
[pve-qemu.git] / debian / patches / pve / 0035-iotests-add-test-for-bitmap-mirror.patch
CommitLineData
83faa3fe 1From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
059a9447 2From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= <f.gruenbichler@proxmox.com>
83faa3fe
TL
3Date: Mon, 6 Apr 2020 12:17:07 +0200
4Subject: [PATCH] iotests: add test for bitmap mirror
059a9447
FG
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9heavily based on/practically forked off iotest 257 for bitmap backups,
10but:
11
12- no writes to filter node 'mirror-top' between completion and
13finalization, as those seem to deadlock?
14- no inclusion of not-yet-available full/top sync modes in combination
15with bitmaps
16- extra set of reference/test mirrors to verify that writes in parallel
17with active mirror work
18
19intentionally keeping copyright and ownership of original test case to
20honor provenance.
21
22Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
23---
83faa3fe
TL
24 tests/qemu-iotests/384 | 547 +++++++
25 tests/qemu-iotests/384.out | 2846 ++++++++++++++++++++++++++++++++++++
059a9447
FG
26 tests/qemu-iotests/group | 1 +
27 3 files changed, 3394 insertions(+)
83faa3fe
TL
28 create mode 100755 tests/qemu-iotests/384
29 create mode 100644 tests/qemu-iotests/384.out
059a9447 30
83faa3fe 31diff --git a/tests/qemu-iotests/384 b/tests/qemu-iotests/384
059a9447
FG
32new file mode 100755
33index 0000000000..b04a8e651a
34--- /dev/null
83faa3fe 35+++ b/tests/qemu-iotests/384
059a9447
FG
36@@ -0,0 +1,547 @@
37+#!/usr/bin/env python3
38+#
39+# Test bitmap-sync mirrors (incremental, differential, and partials)
40+#
41+# Copyright (c) 2019 John Snow for Red Hat, Inc.
42+#
43+# This program is free software; you can redistribute it and/or modify
44+# it under the terms of the GNU General Public License as published by
45+# the Free Software Foundation; either version 2 of the License, or
46+# (at your option) any later version.
47+#
48+# This program is distributed in the hope that it will be useful,
49+# but WITHOUT ANY WARRANTY; without even the implied warranty of
50+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
51+# GNU General Public License for more details.
52+#
53+# You should have received a copy of the GNU General Public License
54+# along with this program. If not, see <http://www.gnu.org/licenses/>.
55+#
56+# owner=jsnow@redhat.com
57+
58+import math
59+import os
60+
61+import iotests
62+from iotests import log, qemu_img
63+
64+SIZE = 64 * 1024 * 1024
65+GRANULARITY = 64 * 1024
66+
67+
68+class Pattern:
69+ def __init__(self, byte, offset, size=GRANULARITY):
70+ self.byte = byte
71+ self.offset = offset
72+ self.size = size
73+
74+ def bits(self, granularity):
75+ lower = self.offset // granularity
76+ upper = (self.offset + self.size - 1) // granularity
77+ return set(range(lower, upper + 1))
78+
79+
80+class PatternGroup:
81+ """Grouping of Pattern objects. Initialize with an iterable of Patterns."""
82+ def __init__(self, patterns):
83+ self.patterns = patterns
84+
85+ def bits(self, granularity):
86+ """Calculate the unique bits dirtied by this pattern grouping"""
87+ res = set()
88+ for pattern in self.patterns:
89+ res |= pattern.bits(granularity)
90+ return res
91+
92+
93+GROUPS = [
94+ PatternGroup([
95+ # Batch 0: 4 clusters
96+ Pattern('0x49', 0x0000000),
97+ Pattern('0x6c', 0x0100000), # 1M
98+ Pattern('0x6f', 0x2000000), # 32M
99+ Pattern('0x76', 0x3ff0000)]), # 64M - 64K
100+ PatternGroup([
101+ # Batch 1: 6 clusters (3 new)
102+ Pattern('0x65', 0x0000000), # Full overwrite
103+ Pattern('0x77', 0x00f8000), # Partial-left (1M-32K)
104+ Pattern('0x72', 0x2008000), # Partial-right (32M+32K)
105+ Pattern('0x69', 0x3fe0000)]), # Adjacent-left (64M - 128K)
106+ PatternGroup([
107+ # Batch 2: 7 clusters (3 new)
108+ Pattern('0x74', 0x0010000), # Adjacent-right
109+ Pattern('0x69', 0x00e8000), # Partial-left (1M-96K)
110+ Pattern('0x6e', 0x2018000), # Partial-right (32M+96K)
111+ Pattern('0x67', 0x3fe0000,
112+ 2*GRANULARITY)]), # Overwrite [(64M-128K)-64M)
113+ PatternGroup([
114+ # Batch 3: 8 clusters (5 new)
115+ # Carefully chosen such that nothing re-dirties the one cluster
116+ # that copies out successfully before failure in Group #1.
117+ Pattern('0xaa', 0x0010000,
118+ 3*GRANULARITY), # Overwrite and 2x Adjacent-right
119+ Pattern('0xbb', 0x00d8000), # Partial-left (1M-160K)
120+ Pattern('0xcc', 0x2028000), # Partial-right (32M+160K)
121+ Pattern('0xdd', 0x3fc0000)]), # New; leaving a gap to the right
122+]
123+
124+
125+class EmulatedBitmap:
126+ def __init__(self, granularity=GRANULARITY):
127+ self._bits = set()
128+ self.granularity = granularity
129+
130+ def dirty_bits(self, bits):
131+ self._bits |= set(bits)
132+
133+ def dirty_group(self, n):
134+ self.dirty_bits(GROUPS[n].bits(self.granularity))
135+
136+ def clear(self):
137+ self._bits = set()
138+
139+ def clear_bits(self, bits):
140+ self._bits -= set(bits)
141+
142+ def clear_bit(self, bit):
143+ self.clear_bits({bit})
144+
145+ def clear_group(self, n):
146+ self.clear_bits(GROUPS[n].bits(self.granularity))
147+
148+ @property
149+ def first_bit(self):
150+ return sorted(self.bits)[0]
151+
152+ @property
153+ def bits(self):
154+ return self._bits
155+
156+ @property
157+ def count(self):
158+ return len(self.bits)
159+
160+ def compare(self, qmp_bitmap):
161+ """
162+ Print a nice human-readable message checking that a bitmap as reported
163+ by the QMP interface has as many bits set as we expect it to.
164+ """
165+
166+ name = qmp_bitmap.get('name', '(anonymous)')
167+ log("= Checking Bitmap {:s} =".format(name))
168+
169+ want = self.count
170+ have = qmp_bitmap['count'] // qmp_bitmap['granularity']
171+
172+ log("expecting {:d} dirty sectors; have {:d}. {:s}".format(
173+ want, have, "OK!" if want == have else "ERROR!"))
174+ log('')
175+
176+
177+class Drive:
178+ """Represents, vaguely, a drive attached to a VM.
179+ Includes format, graph, and device information."""
180+
181+ def __init__(self, path, vm=None):
182+ self.path = path
183+ self.vm = vm
184+ self.fmt = None
185+ self.size = None
186+ self.node = None
187+
188+ def img_create(self, fmt, size):
189+ self.fmt = fmt
190+ self.size = size
191+ iotests.qemu_img_create('-f', self.fmt, self.path, str(self.size))
192+
193+ def create_target(self, name, fmt, size):
194+ basename = os.path.basename(self.path)
195+ file_node_name = "file_{}".format(basename)
196+ vm = self.vm
197+
198+ log(vm.command('blockdev-create', job_id='bdc-file-job',
199+ options={
200+ 'driver': 'file',
201+ 'filename': self.path,
202+ 'size': 0,
203+ }))
204+ vm.run_job('bdc-file-job')
205+ log(vm.command('blockdev-add', driver='file',
206+ node_name=file_node_name, filename=self.path))
207+
208+ log(vm.command('blockdev-create', job_id='bdc-fmt-job',
209+ options={
210+ 'driver': fmt,
211+ 'file': file_node_name,
212+ 'size': size,
213+ }))
214+ vm.run_job('bdc-fmt-job')
215+ log(vm.command('blockdev-add', driver=fmt,
216+ node_name=name,
217+ file=file_node_name))
218+ self.fmt = fmt
219+ self.size = size
220+ self.node = name
221+
222+def blockdev_mirror(vm, device, target, sync, **kwargs):
223+ # Strip any arguments explicitly nulled by the caller:
224+ kwargs = {key: val for key, val in kwargs.items() if val is not None}
225+ result = vm.qmp_log('blockdev-mirror',
226+ device=device,
227+ target=target,
228+ sync=sync,
229+ filter_node_name='mirror-top',
230+ **kwargs)
231+ return result
232+
233+def blockdev_mirror_mktarget(drive, target_id, filepath, sync, **kwargs):
234+ target_drive = Drive(filepath, vm=drive.vm)
235+ target_drive.create_target(target_id, drive.fmt, drive.size)
236+ blockdev_mirror(drive.vm, drive.node, target_id, sync, **kwargs)
237+
238+def reference_mirror(drive, n, filepath):
239+ log("--- Reference mirror #{:d} ---\n".format(n))
240+ target_id = "ref_target_{:d}".format(n)
241+ job_id = "ref_mirror_{:d}".format(n)
242+ blockdev_mirror_mktarget(drive, target_id, filepath, "full",
243+ job_id=job_id)
244+ drive.vm.run_job(job_id, auto_dismiss=True)
245+ log('')
246+
247+def mirror(drive, n, filepath, sync, **kwargs):
248+ log("--- Test mirror #{:d} ---\n".format(n))
249+ target_id = "mirror_target_{:d}".format(n)
250+ job_id = "mirror_{:d}".format(n)
251+ kwargs.setdefault('auto-finalize', False)
252+ blockdev_mirror_mktarget(drive, target_id, filepath, sync,
253+ job_id=job_id, **kwargs)
254+ return job_id
255+
256+def perform_writes(drive, n, filter_node_name=None):
257+ log("--- Write #{:d} ---\n".format(n))
258+ for pattern in GROUPS[n].patterns:
259+ cmd = "write -P{:s} 0x{:07x} 0x{:x}".format(
260+ pattern.byte,
261+ pattern.offset,
262+ pattern.size)
263+ log(cmd)
264+ log(drive.vm.hmp_qemu_io(filter_node_name or drive.node, cmd))
265+ bitmaps = drive.vm.query_bitmaps()
266+ log({'bitmaps': bitmaps}, indent=2)
267+ log('')
268+ return bitmaps
269+
270+
271+def compare_images(image, reference, baseimg=None, expected_match=True):
272+ """
273+ Print a nice human-readable message comparing these images.
274+ """
275+ expected_ret = 0 if expected_match else 1
276+ if baseimg:
277+ assert qemu_img("rebase", "-u", "-b", baseimg, image) == 0
278+ ret = qemu_img("compare", image, reference)
279+ log('qemu_img compare "{:s}" "{:s}" ==> {:s}, {:s}'.format(
280+ image, reference,
281+ "Identical" if ret == 0 else "Mismatch",
282+ "OK!" if ret == expected_ret else "ERROR!"),
283+ filters=[iotests.filter_testfiles])
284+
285+def test_bitmap_sync(bsync_mode, msync_mode='bitmap', failure=None):
286+ """
287+ Test bitmap mirror routines.
288+
289+ :param bsync_mode: Is the Bitmap Sync mode, and can be any of:
290+ - on-success: This is the "incremental" style mode. Bitmaps are
291+ synchronized to what was copied out only on success.
292+ (Partial images must be discarded.)
293+ - never: This is the "differential" style mode.
294+ Bitmaps are never synchronized.
295+ - always: This is a "best effort" style mode.
296+ Bitmaps are always synchronized, regardless of failure.
297+ (Partial images must be kept.)
298+
299+ :param msync_mode: The mirror sync mode to use for the first mirror.
300+ Can be any one of:
301+ - bitmap: mirrors based on bitmap manifest.
302+ - full: Full mirrors.
303+ - top: Full mirrors of the top layer only.
304+
305+ :param failure: Is the (optional) failure mode, and can be any of:
306+ - None: No failure. Test the normative path. Default.
307+ - simulated: Cancel the job right before it completes.
308+ This also tests writes "during" the job.
309+ - intermediate: This tests a job that fails mid-process and produces
310+ an incomplete mirror. Testing limitations prevent
311+ testing competing writes.
312+ """
313+ with iotests.FilePaths(['img', 'bsync1', 'bsync2', 'bsync3',
314+ 'fmirror0', 'fmirror1', 'fmirror2', 'fmirror3']) as \
315+ (img_path, bsync1, bsync2, bsync3,
316+ fmirror0, fmirror1, fmirror2, fmirror3), \
317+ iotests.VM() as vm:
318+
319+ mode = "Mode {:s}; Bitmap Sync {:s}".format(msync_mode, bsync_mode)
320+ preposition = "with" if failure else "without"
321+ cond = "{:s} {:s}".format(preposition,
322+ "{:s} failure".format(failure) if failure
323+ else "failure")
324+ log("\n=== {:s} {:s} ===\n".format(mode, cond))
325+
326+ log('--- Preparing image & VM ---\n')
327+ drive0 = Drive(img_path, vm=vm)
328+ drive0.img_create(iotests.imgfmt, SIZE)
329+ vm.add_device("{},id=scsi0".format(iotests.get_virtio_scsi_device()))
330+ vm.launch()
331+
332+ file_config = {
333+ 'driver': 'file',
334+ 'filename': drive0.path
335+ }
336+
337+ if failure == 'intermediate':
338+ file_config = {
339+ 'driver': 'blkdebug',
340+ 'image': file_config,
341+ 'set-state': [{
342+ 'event': 'flush_to_disk',
343+ 'state': 1,
344+ 'new_state': 2
345+ }, {
346+ 'event': 'read_aio',
347+ 'state': 2,
348+ 'new_state': 3
349+ }, {
350+ 'event': 'read_aio',
351+ 'state': 3,
352+ 'new_state': 4
353+ }],
354+ 'inject-error': [{
355+ 'event': 'read_aio',
356+ 'errno': 5,
357+ 'state': 3,
358+ 'immediately': False,
359+ 'once': True
360+ }, {
361+ 'event': 'read_aio',
362+ 'errno': 5,
363+ 'state': 4,
364+ 'immediately': False,
365+ 'once': True
366+ }]
367+ }
368+
369+ drive0.node = 'drive0'
370+ vm.qmp_log('blockdev-add',
371+ filters=[iotests.filter_qmp_testfiles],
372+ node_name=drive0.node,
373+ driver=drive0.fmt,
374+ file=file_config)
375+ log('')
376+
377+ # 0 - Writes and Reference mirror
378+ perform_writes(drive0, 0)
379+ reference_mirror(drive0, 0, fmirror0)
380+ log('--- Add Bitmap ---\n')
381+ vm.qmp_log("block-dirty-bitmap-add", node=drive0.node,
382+ name="bitmap0", granularity=GRANULARITY)
383+ log('')
384+ ebitmap = EmulatedBitmap()
385+
386+ # 1 - Writes and Reference mirror
387+ bitmaps = perform_writes(drive0, 1)
388+ ebitmap.dirty_group(1)
389+ bitmap = vm.get_bitmap(drive0.node, 'bitmap0', bitmaps=bitmaps)
390+ ebitmap.compare(bitmap)
391+ reference_mirror(drive0, 1, fmirror1)
392+
393+ # 1 - Test mirror (w/ Optional induced failure)
394+ if failure == 'intermediate':
395+ # Activate blkdebug induced failure for second-to-next read
396+ log(vm.hmp_qemu_io(drive0.node, 'flush'))
397+ log('')
398+ job = mirror(drive0, 1, bsync1, msync_mode,
399+ bitmap="bitmap0", bitmap_mode=bsync_mode)
400+
401+ vm.run_job(job, auto_dismiss=True, auto_finalize=False,
402+ cancel=(failure == 'simulated'))
403+ bitmaps = vm.query_bitmaps()
404+ log({'bitmaps': bitmaps}, indent=2)
405+ log('')
406+
407+ if bsync_mode == 'always':
408+ if failure == 'intermediate':
409+ # We manage to copy one sector (one bit) before the error.
410+ ebitmap.clear_bit(ebitmap.first_bit)
411+ else:
412+ # successful mirror / cancelled complete mirror
413+ ebitmap.clear()
414+
415+ if bsync_mode == 'on-success' and not failure:
416+ ebitmap.clear()
417+
418+ ebitmap.compare(vm.get_bitmap(drive0.node, 'bitmap0', bitmaps=bitmaps))
419+
420+ # 2 - Reference mirror
421+ reference_mirror(drive0, 2, fmirror2)
422+
423+ # 2 - Bitmap mirror with writes before completion
424+ job = mirror(drive0, 2, bsync2, "bitmap",
425+ bitmap="bitmap0", bitmap_mode=bsync_mode)
426+
427+ bitmaps = perform_writes(drive0, 2)
428+ ebitmap.dirty_group(2)
429+ ebitmap.compare(vm.get_bitmap(drive0.node, 'bitmap0', bitmaps=bitmaps))
430+
431+ # don't use run_job as that logs too much even with use_log=False
432+ events = [('JOB_STATUS_CHANGE', {'data': {'id': job}})]
433+ while True:
434+ ev = iotests.filter_qmp_event(vm.events_wait(events, timeout=10))
435+ status = ev['data']['status']
436+ if status == 'ready':
437+ vm.qmp('job-complete', id=job)
438+ elif status == 'standby':
439+ vm.qmp('job-resume', id=job)
440+ elif status == 'pending':
441+ vm.qmp('job-finalize', id=job)
442+ elif status == 'null':
443+ break
444+
445+ if bsync_mode != 'never':
446+ ebitmap.clear()
447+
448+ bitmaps = vm.query_bitmaps()
449+ ebitmap.compare(vm.get_bitmap(drive0.node, 'bitmap0', bitmaps=bitmaps))
450+
451+ # 3 - Writes and Reference mirror
452+ bitmaps = perform_writes(drive0, 3)
453+ ebitmap.dirty_group(3)
454+ ebitmap.compare(vm.get_bitmap(drive0.node, 'bitmap0', bitmaps=bitmaps))
455+ reference_mirror(drive0, 3, fmirror3)
456+
457+ # 3 - Bitmap mirror (In failure modes, this is a recovery.)
458+ job = mirror(drive0, 3, bsync3, "bitmap",
459+ bitmap="bitmap0", bitmap_mode=bsync_mode)
460+
461+ vm.run_job(job, auto_dismiss=True, auto_finalize=False)
462+ bitmaps = vm.query_bitmaps()
463+
464+ log({'bitmaps': bitmaps}, indent=2)
465+ log('')
466+ if bsync_mode != 'never':
467+ ebitmap.clear()
468+ ebitmap.compare(vm.get_bitmap(drive0.node, 'bitmap0', bitmaps=bitmaps))
469+
470+ log('--- Cleanup ---\n')
471+ vm.qmp_log("block-dirty-bitmap-remove",
472+ node=drive0.node, name="bitmap0")
473+ bitmaps = vm.query_bitmaps()
474+ log({'bitmaps': bitmaps}, indent=2)
475+ vm.shutdown()
476+ log('')
477+
478+ log('--- Verification ---\n')
479+ compare_images(bsync1, fmirror1, baseimg=fmirror0,
480+ expected_match=failure != 'intermediate')
481+ if not failure or bsync_mode == 'always':
482+ # Always keep the last mirror on success or when using 'always'
483+ base = bsync1
484+ else:
485+ base = fmirror1
486+
487+ compare_images(bsync2, fmirror2, baseimg=base, expected_match=0)
488+ compare_images(bsync3, fmirror3, baseimg=bsync2)
489+ compare_images(img_path, fmirror3)
490+ log('')
491+
492+def test_mirror_api():
493+ """
494+ Test malformed and prohibited invocations of the mirror API.
495+ """
496+ with iotests.FilePaths(['img', 'bsync1']) as \
497+ (img_path, mirror_path), \
498+ iotests.VM() as vm:
499+
500+ log("\n=== API failure tests ===\n")
501+ log('--- Preparing image & VM ---\n')
502+ drive0 = Drive(img_path, vm=vm)
503+ drive0.img_create(iotests.imgfmt, SIZE)
504+ vm.add_device("{},id=scsi0".format(iotests.get_virtio_scsi_device()))
505+ vm.launch()
506+
507+ file_config = {
508+ 'driver': 'file',
509+ 'filename': drive0.path
510+ }
511+
512+ drive0.node = 'drive0'
513+ vm.qmp_log('blockdev-add',
514+ filters=[iotests.filter_qmp_testfiles],
515+ node_name=drive0.node,
516+ driver=drive0.fmt,
517+ file=file_config)
518+ log('')
519+
520+ target0 = Drive(mirror_path, vm=vm)
521+ target0.create_target("mirror_target", drive0.fmt, drive0.size)
522+ log('')
523+
524+ vm.qmp_log("block-dirty-bitmap-add", node=drive0.node,
525+ name="bitmap0", granularity=GRANULARITY)
526+ log('')
527+
528+ log('-- Testing invalid QMP commands --\n')
529+
530+ error_cases = {
531+ 'incremental': {
532+ None: ['on-success', 'always', 'never', None],
533+ 'bitmap404': ['on-success', 'always', 'never', None],
534+ 'bitmap0': ['always', 'never']
535+ },
536+ 'bitmap': {
537+ None: ['on-success', 'always', 'never', None],
538+ 'bitmap404': ['on-success', 'always', 'never', None],
539+ 'bitmap0': [None],
540+ },
541+ 'full': {
542+ None: ['on-success', 'always', 'never'],
543+ 'bitmap404': ['on-success', 'always', 'never', None],
544+ 'bitmap0': ['on-success', 'always', 'never', None],
545+ },
546+ 'top': {
547+ None: ['on-success', 'always', 'never'],
548+ 'bitmap404': ['on-success', 'always', 'never', None],
549+ 'bitmap0': ['on-success', 'always', 'never', None],
550+ },
551+ 'none': {
552+ None: ['on-success', 'always', 'never'],
553+ 'bitmap404': ['on-success', 'always', 'never', None],
554+ 'bitmap0': ['on-success', 'always', 'never', None],
555+ }
556+ }
557+
558+ # Dicts, as always, are not stably-ordered prior to 3.7, so use tuples:
559+ for sync_mode in ('incremental', 'bitmap', 'full', 'top', 'none'):
560+ log("-- Sync mode {:s} tests --\n".format(sync_mode))
561+ for bitmap in (None, 'bitmap404', 'bitmap0'):
562+ for policy in error_cases[sync_mode][bitmap]:
563+ blockdev_mirror(drive0.vm, drive0.node, "mirror_target",
564+ sync_mode, job_id='api_job',
565+ bitmap=bitmap, bitmap_mode=policy)
566+ log('')
567+
568+
569+def main():
570+ for bsync_mode in ("never", "on-success", "always"):
571+ for failure in ("simulated", "intermediate", None):
572+ test_bitmap_sync(bsync_mode, "bitmap", failure)
573+
574+# for sync_mode in ('full', 'top'):
575+# for bsync_mode in ('on-success', 'always'):
576+# for failure in ('simulated', 'intermediate', None):
577+# test_bitmap_sync(bsync_mode, sync_mode, failure)
578+
579+ test_mirror_api()
580+
581+if __name__ == '__main__':
582+ iotests.script_main(main, supported_fmts=['qcow2'],
583+ supported_protocols=['file'])
83faa3fe 584diff --git a/tests/qemu-iotests/384.out b/tests/qemu-iotests/384.out
059a9447
FG
585new file mode 100644
586index 0000000000..9b7408b6d6
587--- /dev/null
83faa3fe 588+++ b/tests/qemu-iotests/384.out
059a9447
FG
589@@ -0,0 +1,2846 @@
590+
591+=== Mode bitmap; Bitmap Sync never with simulated failure ===
592+
593+--- Preparing image & VM ---
594+
595+{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/PID-img"}, "node-name": "drive0"}}
596+{"return": {}}
597+
598+--- Write #0 ---
599+
600+write -P0x49 0x0000000 0x10000
601+{"return": ""}
602+write -P0x6c 0x0100000 0x10000
603+{"return": ""}
604+write -P0x6f 0x2000000 0x10000
605+{"return": ""}
606+write -P0x76 0x3ff0000 0x10000
607+{"return": ""}
608+{
609+ "bitmaps": {}
610+}
611+
612+--- Reference mirror #0 ---
613+
614+{}
615+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
616+{"return": {}}
617+{}
618+{}
619+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
620+{"return": {}}
621+{}
622+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_0", "sync": "full", "target": "ref_target_0"}}
623+{"return": {}}
624+{"execute": "job-complete", "arguments": {"id": "ref_mirror_0"}}
625+{"return": {}}
626+{"data": {"device": "ref_mirror_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
627+{"data": {"device": "ref_mirror_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
628+
629+--- Add Bitmap ---
630+
631+{"execute": "block-dirty-bitmap-add", "arguments": {"granularity": 65536, "name": "bitmap0", "node": "drive0"}}
632+{"return": {}}
633+
634+--- Write #1 ---
635+
636+write -P0x65 0x0000000 0x10000
637+{"return": ""}
638+write -P0x77 0x00f8000 0x10000
639+{"return": ""}
640+write -P0x72 0x2008000 0x10000
641+{"return": ""}
642+write -P0x69 0x3fe0000 0x10000
643+{"return": ""}
644+{
645+ "bitmaps": {
646+ "drive0": [
647+ {
648+ "busy": false,
649+ "count": 393216,
650+ "granularity": 65536,
651+ "name": "bitmap0",
652+ "persistent": false,
653+ "recording": true,
654+ "status": "active"
655+ }
656+ ]
657+ }
658+}
659+
660+= Checking Bitmap bitmap0 =
661+expecting 6 dirty sectors; have 6. OK!
662+
663+--- Reference mirror #1 ---
664+
665+{}
666+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
667+{"return": {}}
668+{}
669+{}
670+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
671+{"return": {}}
672+{}
673+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_1", "sync": "full", "target": "ref_target_1"}}
674+{"return": {}}
675+{"execute": "job-complete", "arguments": {"id": "ref_mirror_1"}}
676+{"return": {}}
677+{"data": {"device": "ref_mirror_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
678+{"data": {"device": "ref_mirror_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
679+
680+--- Test mirror #1 ---
681+
682+{}
683+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
684+{"return": {}}
685+{}
686+{}
687+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
688+{"return": {}}
689+{}
690+{"execute": "blockdev-mirror", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "mirror_1", "sync": "bitmap", "target": "mirror_target_1"}}
691+{"return": {}}
692+{"execute": "job-complete", "arguments": {"id": "mirror_1"}}
693+{"return": {}}
694+{"data": {"device": "mirror_1", "len": 393216, "offset": 393216, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
695+{"execute": "job-cancel", "arguments": {"id": "mirror_1"}}
696+{"return": {}}
697+{"data": {"id": "mirror_1", "type": "mirror"}, "event": "BLOCK_JOB_PENDING", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
698+{"data": {"device": "mirror_1", "len": 393216, "offset": 393216, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_CANCELLED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
699+{
700+ "bitmaps": {
701+ "drive0": [
702+ {
703+ "busy": false,
704+ "count": 393216,
705+ "granularity": 65536,
706+ "name": "bitmap0",
707+ "persistent": false,
708+ "recording": true,
709+ "status": "active"
710+ }
711+ ]
712+ }
713+}
714+
715+= Checking Bitmap bitmap0 =
716+expecting 6 dirty sectors; have 6. OK!
717+
718+--- Reference mirror #2 ---
719+
720+{}
721+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
722+{"return": {}}
723+{}
724+{}
725+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
726+{"return": {}}
727+{}
728+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_2", "sync": "full", "target": "ref_target_2"}}
729+{"return": {}}
730+{"execute": "job-complete", "arguments": {"id": "ref_mirror_2"}}
731+{"return": {}}
732+{"data": {"device": "ref_mirror_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
733+{"data": {"device": "ref_mirror_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
734+
735+--- Test mirror #2 ---
736+
737+{}
738+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
739+{"return": {}}
740+{}
741+{}
742+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
743+{"return": {}}
744+{}
745+{"execute": "blockdev-mirror", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "mirror_2", "sync": "bitmap", "target": "mirror_target_2"}}
746+{"return": {}}
747+--- Write #2 ---
748+
749+write -P0x74 0x0010000 0x10000
750+{"return": ""}
751+write -P0x69 0x00e8000 0x10000
752+{"return": ""}
753+write -P0x6e 0x2018000 0x10000
754+{"return": ""}
755+write -P0x67 0x3fe0000 0x20000
756+{"return": ""}
757+{
758+ "bitmaps": {
759+ "drive0": [
760+ {
761+ "busy": false,
762+ "count": 262144,
763+ "granularity": 65536,
764+ "persistent": false,
765+ "recording": true,
766+ "status": "active"
767+ },
768+ {
769+ "busy": true,
770+ "count": 655360,
771+ "granularity": 65536,
772+ "name": "bitmap0",
773+ "persistent": false,
774+ "recording": true,
775+ "status": "locked"
776+ }
777+ ]
778+ }
779+}
780+
781+= Checking Bitmap bitmap0 =
782+expecting 10 dirty sectors; have 10. OK!
783+
784+= Checking Bitmap bitmap0 =
785+expecting 10 dirty sectors; have 10. OK!
786+
787+--- Write #3 ---
788+
789+write -P0xaa 0x0010000 0x30000
790+{"return": ""}
791+write -P0xbb 0x00d8000 0x10000
792+{"return": ""}
793+write -P0xcc 0x2028000 0x10000
794+{"return": ""}
795+write -P0xdd 0x3fc0000 0x10000
796+{"return": ""}
797+{
798+ "bitmaps": {
799+ "drive0": [
800+ {
801+ "busy": false,
802+ "count": 983040,
803+ "granularity": 65536,
804+ "name": "bitmap0",
805+ "persistent": false,
806+ "recording": true,
807+ "status": "active"
808+ }
809+ ]
810+ }
811+}
812+
813+= Checking Bitmap bitmap0 =
814+expecting 15 dirty sectors; have 15. OK!
815+
816+--- Reference mirror #3 ---
817+
818+{}
819+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
820+{"return": {}}
821+{}
822+{}
823+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
824+{"return": {}}
825+{}
826+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_3", "sync": "full", "target": "ref_target_3"}}
827+{"return": {}}
828+{"execute": "job-complete", "arguments": {"id": "ref_mirror_3"}}
829+{"return": {}}
830+{"data": {"device": "ref_mirror_3", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
831+{"data": {"device": "ref_mirror_3", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
832+
833+--- Test mirror #3 ---
834+
835+{}
836+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
837+{"return": {}}
838+{}
839+{}
840+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
841+{"return": {}}
842+{}
843+{"execute": "blockdev-mirror", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "mirror_3", "sync": "bitmap", "target": "mirror_target_3"}}
844+{"return": {}}
845+{"execute": "job-complete", "arguments": {"id": "mirror_3"}}
846+{"return": {}}
847+{"data": {"device": "mirror_3", "len": 983040, "offset": 983040, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
848+{"execute": "job-finalize", "arguments": {"id": "mirror_3"}}
849+{"return": {}}
850+{"data": {"id": "mirror_3", "type": "mirror"}, "event": "BLOCK_JOB_PENDING", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
851+{"data": {"device": "mirror_3", "len": 983040, "offset": 983040, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
852+{
853+ "bitmaps": {
854+ "drive0": [
855+ {
856+ "busy": false,
857+ "count": 983040,
858+ "granularity": 65536,
859+ "name": "bitmap0",
860+ "persistent": false,
861+ "recording": true,
862+ "status": "active"
863+ }
864+ ]
865+ }
866+}
867+
868+= Checking Bitmap bitmap0 =
869+expecting 15 dirty sectors; have 15. OK!
870+
871+--- Cleanup ---
872+
873+{"execute": "block-dirty-bitmap-remove", "arguments": {"name": "bitmap0", "node": "drive0"}}
874+{"return": {}}
875+{
876+ "bitmaps": {}
877+}
878+
879+--- Verification ---
880+
881+qemu_img compare "TEST_DIR/PID-bsync1" "TEST_DIR/PID-fmirror1" ==> Identical, OK!
882+qemu_img compare "TEST_DIR/PID-bsync2" "TEST_DIR/PID-fmirror2" ==> Mismatch, OK!
883+qemu_img compare "TEST_DIR/PID-bsync3" "TEST_DIR/PID-fmirror3" ==> Identical, OK!
884+qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fmirror3" ==> Identical, OK!
885+
886+
887+=== Mode bitmap; Bitmap Sync never with intermediate failure ===
888+
889+--- Preparing image & VM ---
890+
891+{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": {"driver": "blkdebug", "image": {"driver": "file", "filename": "TEST_DIR/PID-img"}, "inject-error": [{"errno": 5, "event": "read_aio", "immediately": false, "once": true, "state": 3}, {"errno": 5, "event": "read_aio", "immediately": false, "once": true, "state": 4}], "set-state": [{"event": "flush_to_disk", "new-state": 2, "state": 1}, {"event": "read_aio", "new-state": 3, "state": 2}, {"event": "read_aio", "new-state": 4, "state": 3}]}, "node-name": "drive0"}}
892+{"return": {}}
893+
894+--- Write #0 ---
895+
896+write -P0x49 0x0000000 0x10000
897+{"return": ""}
898+write -P0x6c 0x0100000 0x10000
899+{"return": ""}
900+write -P0x6f 0x2000000 0x10000
901+{"return": ""}
902+write -P0x76 0x3ff0000 0x10000
903+{"return": ""}
904+{
905+ "bitmaps": {}
906+}
907+
908+--- Reference mirror #0 ---
909+
910+{}
911+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
912+{"return": {}}
913+{}
914+{}
915+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
916+{"return": {}}
917+{}
918+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_0", "sync": "full", "target": "ref_target_0"}}
919+{"return": {}}
920+{"execute": "job-complete", "arguments": {"id": "ref_mirror_0"}}
921+{"return": {}}
922+{"data": {"device": "ref_mirror_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
923+{"data": {"device": "ref_mirror_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
924+
925+--- Add Bitmap ---
926+
927+{"execute": "block-dirty-bitmap-add", "arguments": {"granularity": 65536, "name": "bitmap0", "node": "drive0"}}
928+{"return": {}}
929+
930+--- Write #1 ---
931+
932+write -P0x65 0x0000000 0x10000
933+{"return": ""}
934+write -P0x77 0x00f8000 0x10000
935+{"return": ""}
936+write -P0x72 0x2008000 0x10000
937+{"return": ""}
938+write -P0x69 0x3fe0000 0x10000
939+{"return": ""}
940+{
941+ "bitmaps": {
942+ "drive0": [
943+ {
944+ "busy": false,
945+ "count": 393216,
946+ "granularity": 65536,
947+ "name": "bitmap0",
948+ "persistent": false,
949+ "recording": true,
950+ "status": "active"
951+ }
952+ ]
953+ }
954+}
955+
956+= Checking Bitmap bitmap0 =
957+expecting 6 dirty sectors; have 6. OK!
958+
959+--- Reference mirror #1 ---
960+
961+{}
962+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
963+{"return": {}}
964+{}
965+{}
966+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
967+{"return": {}}
968+{}
969+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_1", "sync": "full", "target": "ref_target_1"}}
970+{"return": {}}
971+{"execute": "job-complete", "arguments": {"id": "ref_mirror_1"}}
972+{"return": {}}
973+{"data": {"device": "ref_mirror_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
974+{"data": {"device": "ref_mirror_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
975+
976+{"return": ""}
977+
978+--- Test mirror #1 ---
979+
980+{}
981+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
982+{"return": {}}
983+{}
984+{}
985+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
986+{"return": {}}
987+{}
988+{"execute": "blockdev-mirror", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "mirror_1", "sync": "bitmap", "target": "mirror_target_1"}}
989+{"return": {}}
990+{"data": {"action": "report", "device": "mirror_1", "operation": "read"}, "event": "BLOCK_JOB_ERROR", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
991+{"data": {"action": "report", "device": "mirror_1", "operation": "read"}, "event": "BLOCK_JOB_ERROR", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
992+{"data": {"device": "mirror_1", "error": "Input/output error", "len": 393216, "offset": 65536, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
993+{
994+ "bitmaps": {
995+ "drive0": [
996+ {
997+ "busy": false,
998+ "count": 393216,
999+ "granularity": 65536,
1000+ "name": "bitmap0",
1001+ "persistent": false,
1002+ "recording": true,
1003+ "status": "active"
1004+ }
1005+ ]
1006+ }
1007+}
1008+
1009+= Checking Bitmap bitmap0 =
1010+expecting 6 dirty sectors; have 6. OK!
1011+
1012+--- Reference mirror #2 ---
1013+
1014+{}
1015+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
1016+{"return": {}}
1017+{}
1018+{}
1019+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1020+{"return": {}}
1021+{}
1022+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_2", "sync": "full", "target": "ref_target_2"}}
1023+{"return": {}}
1024+{"execute": "job-complete", "arguments": {"id": "ref_mirror_2"}}
1025+{"return": {}}
1026+{"data": {"device": "ref_mirror_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1027+{"data": {"device": "ref_mirror_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1028+
1029+--- Test mirror #2 ---
1030+
1031+{}
1032+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
1033+{"return": {}}
1034+{}
1035+{}
1036+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1037+{"return": {}}
1038+{}
1039+{"execute": "blockdev-mirror", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "mirror_2", "sync": "bitmap", "target": "mirror_target_2"}}
1040+{"return": {}}
1041+--- Write #2 ---
1042+
1043+write -P0x74 0x0010000 0x10000
1044+{"return": ""}
1045+write -P0x69 0x00e8000 0x10000
1046+{"return": ""}
1047+write -P0x6e 0x2018000 0x10000
1048+{"return": ""}
1049+write -P0x67 0x3fe0000 0x20000
1050+{"return": ""}
1051+{
1052+ "bitmaps": {
1053+ "drive0": [
1054+ {
1055+ "busy": false,
1056+ "count": 262144,
1057+ "granularity": 65536,
1058+ "persistent": false,
1059+ "recording": true,
1060+ "status": "active"
1061+ },
1062+ {
1063+ "busy": true,
1064+ "count": 655360,
1065+ "granularity": 65536,
1066+ "name": "bitmap0",
1067+ "persistent": false,
1068+ "recording": true,
1069+ "status": "locked"
1070+ }
1071+ ]
1072+ }
1073+}
1074+
1075+= Checking Bitmap bitmap0 =
1076+expecting 10 dirty sectors; have 10. OK!
1077+
1078+= Checking Bitmap bitmap0 =
1079+expecting 10 dirty sectors; have 10. OK!
1080+
1081+--- Write #3 ---
1082+
1083+write -P0xaa 0x0010000 0x30000
1084+{"return": ""}
1085+write -P0xbb 0x00d8000 0x10000
1086+{"return": ""}
1087+write -P0xcc 0x2028000 0x10000
1088+{"return": ""}
1089+write -P0xdd 0x3fc0000 0x10000
1090+{"return": ""}
1091+{
1092+ "bitmaps": {
1093+ "drive0": [
1094+ {
1095+ "busy": false,
1096+ "count": 983040,
1097+ "granularity": 65536,
1098+ "name": "bitmap0",
1099+ "persistent": false,
1100+ "recording": true,
1101+ "status": "active"
1102+ }
1103+ ]
1104+ }
1105+}
1106+
1107+= Checking Bitmap bitmap0 =
1108+expecting 15 dirty sectors; have 15. OK!
1109+
1110+--- Reference mirror #3 ---
1111+
1112+{}
1113+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
1114+{"return": {}}
1115+{}
1116+{}
1117+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1118+{"return": {}}
1119+{}
1120+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_3", "sync": "full", "target": "ref_target_3"}}
1121+{"return": {}}
1122+{"execute": "job-complete", "arguments": {"id": "ref_mirror_3"}}
1123+{"return": {}}
1124+{"data": {"device": "ref_mirror_3", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1125+{"data": {"device": "ref_mirror_3", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1126+
1127+--- Test mirror #3 ---
1128+
1129+{}
1130+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
1131+{"return": {}}
1132+{}
1133+{}
1134+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1135+{"return": {}}
1136+{}
1137+{"execute": "blockdev-mirror", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "mirror_3", "sync": "bitmap", "target": "mirror_target_3"}}
1138+{"return": {}}
1139+{"execute": "job-complete", "arguments": {"id": "mirror_3"}}
1140+{"return": {}}
1141+{"data": {"device": "mirror_3", "len": 983040, "offset": 983040, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1142+{"execute": "job-finalize", "arguments": {"id": "mirror_3"}}
1143+{"return": {}}
1144+{"data": {"id": "mirror_3", "type": "mirror"}, "event": "BLOCK_JOB_PENDING", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1145+{"data": {"device": "mirror_3", "len": 983040, "offset": 983040, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1146+{
1147+ "bitmaps": {
1148+ "drive0": [
1149+ {
1150+ "busy": false,
1151+ "count": 983040,
1152+ "granularity": 65536,
1153+ "name": "bitmap0",
1154+ "persistent": false,
1155+ "recording": true,
1156+ "status": "active"
1157+ }
1158+ ]
1159+ }
1160+}
1161+
1162+= Checking Bitmap bitmap0 =
1163+expecting 15 dirty sectors; have 15. OK!
1164+
1165+--- Cleanup ---
1166+
1167+{"execute": "block-dirty-bitmap-remove", "arguments": {"name": "bitmap0", "node": "drive0"}}
1168+{"return": {}}
1169+{
1170+ "bitmaps": {}
1171+}
1172+
1173+--- Verification ---
1174+
1175+qemu_img compare "TEST_DIR/PID-bsync1" "TEST_DIR/PID-fmirror1" ==> Mismatch, OK!
1176+qemu_img compare "TEST_DIR/PID-bsync2" "TEST_DIR/PID-fmirror2" ==> Mismatch, OK!
1177+qemu_img compare "TEST_DIR/PID-bsync3" "TEST_DIR/PID-fmirror3" ==> Identical, OK!
1178+qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fmirror3" ==> Identical, OK!
1179+
1180+
1181+=== Mode bitmap; Bitmap Sync never without failure ===
1182+
1183+--- Preparing image & VM ---
1184+
1185+{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/PID-img"}, "node-name": "drive0"}}
1186+{"return": {}}
1187+
1188+--- Write #0 ---
1189+
1190+write -P0x49 0x0000000 0x10000
1191+{"return": ""}
1192+write -P0x6c 0x0100000 0x10000
1193+{"return": ""}
1194+write -P0x6f 0x2000000 0x10000
1195+{"return": ""}
1196+write -P0x76 0x3ff0000 0x10000
1197+{"return": ""}
1198+{
1199+ "bitmaps": {}
1200+}
1201+
1202+--- Reference mirror #0 ---
1203+
1204+{}
1205+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
1206+{"return": {}}
1207+{}
1208+{}
1209+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1210+{"return": {}}
1211+{}
1212+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_0", "sync": "full", "target": "ref_target_0"}}
1213+{"return": {}}
1214+{"execute": "job-complete", "arguments": {"id": "ref_mirror_0"}}
1215+{"return": {}}
1216+{"data": {"device": "ref_mirror_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1217+{"data": {"device": "ref_mirror_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1218+
1219+--- Add Bitmap ---
1220+
1221+{"execute": "block-dirty-bitmap-add", "arguments": {"granularity": 65536, "name": "bitmap0", "node": "drive0"}}
1222+{"return": {}}
1223+
1224+--- Write #1 ---
1225+
1226+write -P0x65 0x0000000 0x10000
1227+{"return": ""}
1228+write -P0x77 0x00f8000 0x10000
1229+{"return": ""}
1230+write -P0x72 0x2008000 0x10000
1231+{"return": ""}
1232+write -P0x69 0x3fe0000 0x10000
1233+{"return": ""}
1234+{
1235+ "bitmaps": {
1236+ "drive0": [
1237+ {
1238+ "busy": false,
1239+ "count": 393216,
1240+ "granularity": 65536,
1241+ "name": "bitmap0",
1242+ "persistent": false,
1243+ "recording": true,
1244+ "status": "active"
1245+ }
1246+ ]
1247+ }
1248+}
1249+
1250+= Checking Bitmap bitmap0 =
1251+expecting 6 dirty sectors; have 6. OK!
1252+
1253+--- Reference mirror #1 ---
1254+
1255+{}
1256+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
1257+{"return": {}}
1258+{}
1259+{}
1260+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1261+{"return": {}}
1262+{}
1263+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_1", "sync": "full", "target": "ref_target_1"}}
1264+{"return": {}}
1265+{"execute": "job-complete", "arguments": {"id": "ref_mirror_1"}}
1266+{"return": {}}
1267+{"data": {"device": "ref_mirror_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1268+{"data": {"device": "ref_mirror_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1269+
1270+--- Test mirror #1 ---
1271+
1272+{}
1273+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
1274+{"return": {}}
1275+{}
1276+{}
1277+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1278+{"return": {}}
1279+{}
1280+{"execute": "blockdev-mirror", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "mirror_1", "sync": "bitmap", "target": "mirror_target_1"}}
1281+{"return": {}}
1282+{"execute": "job-complete", "arguments": {"id": "mirror_1"}}
1283+{"return": {}}
1284+{"data": {"device": "mirror_1", "len": 393216, "offset": 393216, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1285+{"execute": "job-finalize", "arguments": {"id": "mirror_1"}}
1286+{"return": {}}
1287+{"data": {"id": "mirror_1", "type": "mirror"}, "event": "BLOCK_JOB_PENDING", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1288+{"data": {"device": "mirror_1", "len": 393216, "offset": 393216, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1289+{
1290+ "bitmaps": {
1291+ "drive0": [
1292+ {
1293+ "busy": false,
1294+ "count": 393216,
1295+ "granularity": 65536,
1296+ "name": "bitmap0",
1297+ "persistent": false,
1298+ "recording": true,
1299+ "status": "active"
1300+ }
1301+ ]
1302+ }
1303+}
1304+
1305+= Checking Bitmap bitmap0 =
1306+expecting 6 dirty sectors; have 6. OK!
1307+
1308+--- Reference mirror #2 ---
1309+
1310+{}
1311+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
1312+{"return": {}}
1313+{}
1314+{}
1315+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1316+{"return": {}}
1317+{}
1318+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_2", "sync": "full", "target": "ref_target_2"}}
1319+{"return": {}}
1320+{"execute": "job-complete", "arguments": {"id": "ref_mirror_2"}}
1321+{"return": {}}
1322+{"data": {"device": "ref_mirror_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1323+{"data": {"device": "ref_mirror_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1324+
1325+--- Test mirror #2 ---
1326+
1327+{}
1328+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
1329+{"return": {}}
1330+{}
1331+{}
1332+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1333+{"return": {}}
1334+{}
1335+{"execute": "blockdev-mirror", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "mirror_2", "sync": "bitmap", "target": "mirror_target_2"}}
1336+{"return": {}}
1337+--- Write #2 ---
1338+
1339+write -P0x74 0x0010000 0x10000
1340+{"return": ""}
1341+write -P0x69 0x00e8000 0x10000
1342+{"return": ""}
1343+write -P0x6e 0x2018000 0x10000
1344+{"return": ""}
1345+write -P0x67 0x3fe0000 0x20000
1346+{"return": ""}
1347+{
1348+ "bitmaps": {
1349+ "drive0": [
1350+ {
1351+ "busy": false,
1352+ "count": 262144,
1353+ "granularity": 65536,
1354+ "persistent": false,
1355+ "recording": true,
1356+ "status": "active"
1357+ },
1358+ {
1359+ "busy": true,
1360+ "count": 655360,
1361+ "granularity": 65536,
1362+ "name": "bitmap0",
1363+ "persistent": false,
1364+ "recording": true,
1365+ "status": "locked"
1366+ }
1367+ ]
1368+ }
1369+}
1370+
1371+= Checking Bitmap bitmap0 =
1372+expecting 10 dirty sectors; have 10. OK!
1373+
1374+= Checking Bitmap bitmap0 =
1375+expecting 10 dirty sectors; have 10. OK!
1376+
1377+--- Write #3 ---
1378+
1379+write -P0xaa 0x0010000 0x30000
1380+{"return": ""}
1381+write -P0xbb 0x00d8000 0x10000
1382+{"return": ""}
1383+write -P0xcc 0x2028000 0x10000
1384+{"return": ""}
1385+write -P0xdd 0x3fc0000 0x10000
1386+{"return": ""}
1387+{
1388+ "bitmaps": {
1389+ "drive0": [
1390+ {
1391+ "busy": false,
1392+ "count": 983040,
1393+ "granularity": 65536,
1394+ "name": "bitmap0",
1395+ "persistent": false,
1396+ "recording": true,
1397+ "status": "active"
1398+ }
1399+ ]
1400+ }
1401+}
1402+
1403+= Checking Bitmap bitmap0 =
1404+expecting 15 dirty sectors; have 15. OK!
1405+
1406+--- Reference mirror #3 ---
1407+
1408+{}
1409+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
1410+{"return": {}}
1411+{}
1412+{}
1413+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1414+{"return": {}}
1415+{}
1416+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_3", "sync": "full", "target": "ref_target_3"}}
1417+{"return": {}}
1418+{"execute": "job-complete", "arguments": {"id": "ref_mirror_3"}}
1419+{"return": {}}
1420+{"data": {"device": "ref_mirror_3", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1421+{"data": {"device": "ref_mirror_3", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1422+
1423+--- Test mirror #3 ---
1424+
1425+{}
1426+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
1427+{"return": {}}
1428+{}
1429+{}
1430+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1431+{"return": {}}
1432+{}
1433+{"execute": "blockdev-mirror", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "mirror_3", "sync": "bitmap", "target": "mirror_target_3"}}
1434+{"return": {}}
1435+{"execute": "job-complete", "arguments": {"id": "mirror_3"}}
1436+{"return": {}}
1437+{"data": {"device": "mirror_3", "len": 983040, "offset": 983040, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1438+{"execute": "job-finalize", "arguments": {"id": "mirror_3"}}
1439+{"return": {}}
1440+{"data": {"id": "mirror_3", "type": "mirror"}, "event": "BLOCK_JOB_PENDING", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1441+{"data": {"device": "mirror_3", "len": 983040, "offset": 983040, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1442+{
1443+ "bitmaps": {
1444+ "drive0": [
1445+ {
1446+ "busy": false,
1447+ "count": 983040,
1448+ "granularity": 65536,
1449+ "name": "bitmap0",
1450+ "persistent": false,
1451+ "recording": true,
1452+ "status": "active"
1453+ }
1454+ ]
1455+ }
1456+}
1457+
1458+= Checking Bitmap bitmap0 =
1459+expecting 15 dirty sectors; have 15. OK!
1460+
1461+--- Cleanup ---
1462+
1463+{"execute": "block-dirty-bitmap-remove", "arguments": {"name": "bitmap0", "node": "drive0"}}
1464+{"return": {}}
1465+{
1466+ "bitmaps": {}
1467+}
1468+
1469+--- Verification ---
1470+
1471+qemu_img compare "TEST_DIR/PID-bsync1" "TEST_DIR/PID-fmirror1" ==> Identical, OK!
1472+qemu_img compare "TEST_DIR/PID-bsync2" "TEST_DIR/PID-fmirror2" ==> Mismatch, OK!
1473+qemu_img compare "TEST_DIR/PID-bsync3" "TEST_DIR/PID-fmirror3" ==> Identical, OK!
1474+qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fmirror3" ==> Identical, OK!
1475+
1476+
1477+=== Mode bitmap; Bitmap Sync on-success with simulated failure ===
1478+
1479+--- Preparing image & VM ---
1480+
1481+{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/PID-img"}, "node-name": "drive0"}}
1482+{"return": {}}
1483+
1484+--- Write #0 ---
1485+
1486+write -P0x49 0x0000000 0x10000
1487+{"return": ""}
1488+write -P0x6c 0x0100000 0x10000
1489+{"return": ""}
1490+write -P0x6f 0x2000000 0x10000
1491+{"return": ""}
1492+write -P0x76 0x3ff0000 0x10000
1493+{"return": ""}
1494+{
1495+ "bitmaps": {}
1496+}
1497+
1498+--- Reference mirror #0 ---
1499+
1500+{}
1501+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
1502+{"return": {}}
1503+{}
1504+{}
1505+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1506+{"return": {}}
1507+{}
1508+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_0", "sync": "full", "target": "ref_target_0"}}
1509+{"return": {}}
1510+{"execute": "job-complete", "arguments": {"id": "ref_mirror_0"}}
1511+{"return": {}}
1512+{"data": {"device": "ref_mirror_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1513+{"data": {"device": "ref_mirror_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1514+
1515+--- Add Bitmap ---
1516+
1517+{"execute": "block-dirty-bitmap-add", "arguments": {"granularity": 65536, "name": "bitmap0", "node": "drive0"}}
1518+{"return": {}}
1519+
1520+--- Write #1 ---
1521+
1522+write -P0x65 0x0000000 0x10000
1523+{"return": ""}
1524+write -P0x77 0x00f8000 0x10000
1525+{"return": ""}
1526+write -P0x72 0x2008000 0x10000
1527+{"return": ""}
1528+write -P0x69 0x3fe0000 0x10000
1529+{"return": ""}
1530+{
1531+ "bitmaps": {
1532+ "drive0": [
1533+ {
1534+ "busy": false,
1535+ "count": 393216,
1536+ "granularity": 65536,
1537+ "name": "bitmap0",
1538+ "persistent": false,
1539+ "recording": true,
1540+ "status": "active"
1541+ }
1542+ ]
1543+ }
1544+}
1545+
1546+= Checking Bitmap bitmap0 =
1547+expecting 6 dirty sectors; have 6. OK!
1548+
1549+--- Reference mirror #1 ---
1550+
1551+{}
1552+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
1553+{"return": {}}
1554+{}
1555+{}
1556+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1557+{"return": {}}
1558+{}
1559+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_1", "sync": "full", "target": "ref_target_1"}}
1560+{"return": {}}
1561+{"execute": "job-complete", "arguments": {"id": "ref_mirror_1"}}
1562+{"return": {}}
1563+{"data": {"device": "ref_mirror_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1564+{"data": {"device": "ref_mirror_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1565+
1566+--- Test mirror #1 ---
1567+
1568+{}
1569+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
1570+{"return": {}}
1571+{}
1572+{}
1573+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1574+{"return": {}}
1575+{}
1576+{"execute": "blockdev-mirror", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "mirror_1", "sync": "bitmap", "target": "mirror_target_1"}}
1577+{"return": {}}
1578+{"execute": "job-complete", "arguments": {"id": "mirror_1"}}
1579+{"return": {}}
1580+{"data": {"device": "mirror_1", "len": 393216, "offset": 393216, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1581+{"execute": "job-cancel", "arguments": {"id": "mirror_1"}}
1582+{"return": {}}
1583+{"data": {"id": "mirror_1", "type": "mirror"}, "event": "BLOCK_JOB_PENDING", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1584+{"data": {"device": "mirror_1", "len": 393216, "offset": 393216, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_CANCELLED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1585+{
1586+ "bitmaps": {
1587+ "drive0": [
1588+ {
1589+ "busy": false,
1590+ "count": 393216,
1591+ "granularity": 65536,
1592+ "name": "bitmap0",
1593+ "persistent": false,
1594+ "recording": true,
1595+ "status": "active"
1596+ }
1597+ ]
1598+ }
1599+}
1600+
1601+= Checking Bitmap bitmap0 =
1602+expecting 6 dirty sectors; have 6. OK!
1603+
1604+--- Reference mirror #2 ---
1605+
1606+{}
1607+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
1608+{"return": {}}
1609+{}
1610+{}
1611+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1612+{"return": {}}
1613+{}
1614+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_2", "sync": "full", "target": "ref_target_2"}}
1615+{"return": {}}
1616+{"execute": "job-complete", "arguments": {"id": "ref_mirror_2"}}
1617+{"return": {}}
1618+{"data": {"device": "ref_mirror_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1619+{"data": {"device": "ref_mirror_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1620+
1621+--- Test mirror #2 ---
1622+
1623+{}
1624+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
1625+{"return": {}}
1626+{}
1627+{}
1628+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1629+{"return": {}}
1630+{}
1631+{"execute": "blockdev-mirror", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "mirror_2", "sync": "bitmap", "target": "mirror_target_2"}}
1632+{"return": {}}
1633+--- Write #2 ---
1634+
1635+write -P0x74 0x0010000 0x10000
1636+{"return": ""}
1637+write -P0x69 0x00e8000 0x10000
1638+{"return": ""}
1639+write -P0x6e 0x2018000 0x10000
1640+{"return": ""}
1641+write -P0x67 0x3fe0000 0x20000
1642+{"return": ""}
1643+{
1644+ "bitmaps": {
1645+ "drive0": [
1646+ {
1647+ "busy": false,
1648+ "count": 262144,
1649+ "granularity": 65536,
1650+ "persistent": false,
1651+ "recording": true,
1652+ "status": "active"
1653+ },
1654+ {
1655+ "busy": true,
1656+ "count": 655360,
1657+ "granularity": 65536,
1658+ "name": "bitmap0",
1659+ "persistent": false,
1660+ "recording": true,
1661+ "status": "locked"
1662+ }
1663+ ]
1664+ }
1665+}
1666+
1667+= Checking Bitmap bitmap0 =
1668+expecting 10 dirty sectors; have 10. OK!
1669+
1670+= Checking Bitmap bitmap0 =
1671+expecting 0 dirty sectors; have 0. OK!
1672+
1673+--- Write #3 ---
1674+
1675+write -P0xaa 0x0010000 0x30000
1676+{"return": ""}
1677+write -P0xbb 0x00d8000 0x10000
1678+{"return": ""}
1679+write -P0xcc 0x2028000 0x10000
1680+{"return": ""}
1681+write -P0xdd 0x3fc0000 0x10000
1682+{"return": ""}
1683+{
1684+ "bitmaps": {
1685+ "drive0": [
1686+ {
1687+ "busy": false,
1688+ "count": 524288,
1689+ "granularity": 65536,
1690+ "name": "bitmap0",
1691+ "persistent": false,
1692+ "recording": true,
1693+ "status": "active"
1694+ }
1695+ ]
1696+ }
1697+}
1698+
1699+= Checking Bitmap bitmap0 =
1700+expecting 8 dirty sectors; have 8. OK!
1701+
1702+--- Reference mirror #3 ---
1703+
1704+{}
1705+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
1706+{"return": {}}
1707+{}
1708+{}
1709+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1710+{"return": {}}
1711+{}
1712+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_3", "sync": "full", "target": "ref_target_3"}}
1713+{"return": {}}
1714+{"execute": "job-complete", "arguments": {"id": "ref_mirror_3"}}
1715+{"return": {}}
1716+{"data": {"device": "ref_mirror_3", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1717+{"data": {"device": "ref_mirror_3", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1718+
1719+--- Test mirror #3 ---
1720+
1721+{}
1722+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
1723+{"return": {}}
1724+{}
1725+{}
1726+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1727+{"return": {}}
1728+{}
1729+{"execute": "blockdev-mirror", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "mirror_3", "sync": "bitmap", "target": "mirror_target_3"}}
1730+{"return": {}}
1731+{"execute": "job-complete", "arguments": {"id": "mirror_3"}}
1732+{"return": {}}
1733+{"data": {"device": "mirror_3", "len": 524288, "offset": 524288, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1734+{"execute": "job-finalize", "arguments": {"id": "mirror_3"}}
1735+{"return": {}}
1736+{"data": {"id": "mirror_3", "type": "mirror"}, "event": "BLOCK_JOB_PENDING", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1737+{"data": {"device": "mirror_3", "len": 524288, "offset": 524288, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1738+{
1739+ "bitmaps": {
1740+ "drive0": [
1741+ {
1742+ "busy": false,
1743+ "count": 0,
1744+ "granularity": 65536,
1745+ "name": "bitmap0",
1746+ "persistent": false,
1747+ "recording": true,
1748+ "status": "active"
1749+ }
1750+ ]
1751+ }
1752+}
1753+
1754+= Checking Bitmap bitmap0 =
1755+expecting 0 dirty sectors; have 0. OK!
1756+
1757+--- Cleanup ---
1758+
1759+{"execute": "block-dirty-bitmap-remove", "arguments": {"name": "bitmap0", "node": "drive0"}}
1760+{"return": {}}
1761+{
1762+ "bitmaps": {}
1763+}
1764+
1765+--- Verification ---
1766+
1767+qemu_img compare "TEST_DIR/PID-bsync1" "TEST_DIR/PID-fmirror1" ==> Identical, OK!
1768+qemu_img compare "TEST_DIR/PID-bsync2" "TEST_DIR/PID-fmirror2" ==> Mismatch, OK!
1769+qemu_img compare "TEST_DIR/PID-bsync3" "TEST_DIR/PID-fmirror3" ==> Identical, OK!
1770+qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fmirror3" ==> Identical, OK!
1771+
1772+
1773+=== Mode bitmap; Bitmap Sync on-success with intermediate failure ===
1774+
1775+--- Preparing image & VM ---
1776+
1777+{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": {"driver": "blkdebug", "image": {"driver": "file", "filename": "TEST_DIR/PID-img"}, "inject-error": [{"errno": 5, "event": "read_aio", "immediately": false, "once": true, "state": 3}, {"errno": 5, "event": "read_aio", "immediately": false, "once": true, "state": 4}], "set-state": [{"event": "flush_to_disk", "new-state": 2, "state": 1}, {"event": "read_aio", "new-state": 3, "state": 2}, {"event": "read_aio", "new-state": 4, "state": 3}]}, "node-name": "drive0"}}
1778+{"return": {}}
1779+
1780+--- Write #0 ---
1781+
1782+write -P0x49 0x0000000 0x10000
1783+{"return": ""}
1784+write -P0x6c 0x0100000 0x10000
1785+{"return": ""}
1786+write -P0x6f 0x2000000 0x10000
1787+{"return": ""}
1788+write -P0x76 0x3ff0000 0x10000
1789+{"return": ""}
1790+{
1791+ "bitmaps": {}
1792+}
1793+
1794+--- Reference mirror #0 ---
1795+
1796+{}
1797+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
1798+{"return": {}}
1799+{}
1800+{}
1801+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1802+{"return": {}}
1803+{}
1804+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_0", "sync": "full", "target": "ref_target_0"}}
1805+{"return": {}}
1806+{"execute": "job-complete", "arguments": {"id": "ref_mirror_0"}}
1807+{"return": {}}
1808+{"data": {"device": "ref_mirror_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1809+{"data": {"device": "ref_mirror_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1810+
1811+--- Add Bitmap ---
1812+
1813+{"execute": "block-dirty-bitmap-add", "arguments": {"granularity": 65536, "name": "bitmap0", "node": "drive0"}}
1814+{"return": {}}
1815+
1816+--- Write #1 ---
1817+
1818+write -P0x65 0x0000000 0x10000
1819+{"return": ""}
1820+write -P0x77 0x00f8000 0x10000
1821+{"return": ""}
1822+write -P0x72 0x2008000 0x10000
1823+{"return": ""}
1824+write -P0x69 0x3fe0000 0x10000
1825+{"return": ""}
1826+{
1827+ "bitmaps": {
1828+ "drive0": [
1829+ {
1830+ "busy": false,
1831+ "count": 393216,
1832+ "granularity": 65536,
1833+ "name": "bitmap0",
1834+ "persistent": false,
1835+ "recording": true,
1836+ "status": "active"
1837+ }
1838+ ]
1839+ }
1840+}
1841+
1842+= Checking Bitmap bitmap0 =
1843+expecting 6 dirty sectors; have 6. OK!
1844+
1845+--- Reference mirror #1 ---
1846+
1847+{}
1848+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
1849+{"return": {}}
1850+{}
1851+{}
1852+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1853+{"return": {}}
1854+{}
1855+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_1", "sync": "full", "target": "ref_target_1"}}
1856+{"return": {}}
1857+{"execute": "job-complete", "arguments": {"id": "ref_mirror_1"}}
1858+{"return": {}}
1859+{"data": {"device": "ref_mirror_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1860+{"data": {"device": "ref_mirror_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1861+
1862+{"return": ""}
1863+
1864+--- Test mirror #1 ---
1865+
1866+{}
1867+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
1868+{"return": {}}
1869+{}
1870+{}
1871+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1872+{"return": {}}
1873+{}
1874+{"execute": "blockdev-mirror", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "mirror_1", "sync": "bitmap", "target": "mirror_target_1"}}
1875+{"return": {}}
1876+{"data": {"action": "report", "device": "mirror_1", "operation": "read"}, "event": "BLOCK_JOB_ERROR", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1877+{"data": {"action": "report", "device": "mirror_1", "operation": "read"}, "event": "BLOCK_JOB_ERROR", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1878+{"data": {"device": "mirror_1", "error": "Input/output error", "len": 393216, "offset": 65536, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1879+{
1880+ "bitmaps": {
1881+ "drive0": [
1882+ {
1883+ "busy": false,
1884+ "count": 393216,
1885+ "granularity": 65536,
1886+ "name": "bitmap0",
1887+ "persistent": false,
1888+ "recording": true,
1889+ "status": "active"
1890+ }
1891+ ]
1892+ }
1893+}
1894+
1895+= Checking Bitmap bitmap0 =
1896+expecting 6 dirty sectors; have 6. OK!
1897+
1898+--- Reference mirror #2 ---
1899+
1900+{}
1901+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
1902+{"return": {}}
1903+{}
1904+{}
1905+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1906+{"return": {}}
1907+{}
1908+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_2", "sync": "full", "target": "ref_target_2"}}
1909+{"return": {}}
1910+{"execute": "job-complete", "arguments": {"id": "ref_mirror_2"}}
1911+{"return": {}}
1912+{"data": {"device": "ref_mirror_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1913+{"data": {"device": "ref_mirror_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1914+
1915+--- Test mirror #2 ---
1916+
1917+{}
1918+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
1919+{"return": {}}
1920+{}
1921+{}
1922+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1923+{"return": {}}
1924+{}
1925+{"execute": "blockdev-mirror", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "mirror_2", "sync": "bitmap", "target": "mirror_target_2"}}
1926+{"return": {}}
1927+--- Write #2 ---
1928+
1929+write -P0x74 0x0010000 0x10000
1930+{"return": ""}
1931+write -P0x69 0x00e8000 0x10000
1932+{"return": ""}
1933+write -P0x6e 0x2018000 0x10000
1934+{"return": ""}
1935+write -P0x67 0x3fe0000 0x20000
1936+{"return": ""}
1937+{
1938+ "bitmaps": {
1939+ "drive0": [
1940+ {
1941+ "busy": false,
1942+ "count": 262144,
1943+ "granularity": 65536,
1944+ "persistent": false,
1945+ "recording": true,
1946+ "status": "active"
1947+ },
1948+ {
1949+ "busy": true,
1950+ "count": 655360,
1951+ "granularity": 65536,
1952+ "name": "bitmap0",
1953+ "persistent": false,
1954+ "recording": true,
1955+ "status": "locked"
1956+ }
1957+ ]
1958+ }
1959+}
1960+
1961+= Checking Bitmap bitmap0 =
1962+expecting 10 dirty sectors; have 10. OK!
1963+
1964+= Checking Bitmap bitmap0 =
1965+expecting 0 dirty sectors; have 0. OK!
1966+
1967+--- Write #3 ---
1968+
1969+write -P0xaa 0x0010000 0x30000
1970+{"return": ""}
1971+write -P0xbb 0x00d8000 0x10000
1972+{"return": ""}
1973+write -P0xcc 0x2028000 0x10000
1974+{"return": ""}
1975+write -P0xdd 0x3fc0000 0x10000
1976+{"return": ""}
1977+{
1978+ "bitmaps": {
1979+ "drive0": [
1980+ {
1981+ "busy": false,
1982+ "count": 524288,
1983+ "granularity": 65536,
1984+ "name": "bitmap0",
1985+ "persistent": false,
1986+ "recording": true,
1987+ "status": "active"
1988+ }
1989+ ]
1990+ }
1991+}
1992+
1993+= Checking Bitmap bitmap0 =
1994+expecting 8 dirty sectors; have 8. OK!
1995+
1996+--- Reference mirror #3 ---
1997+
1998+{}
1999+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
2000+{"return": {}}
2001+{}
2002+{}
2003+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
2004+{"return": {}}
2005+{}
2006+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_3", "sync": "full", "target": "ref_target_3"}}
2007+{"return": {}}
2008+{"execute": "job-complete", "arguments": {"id": "ref_mirror_3"}}
2009+{"return": {}}
2010+{"data": {"device": "ref_mirror_3", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2011+{"data": {"device": "ref_mirror_3", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2012+
2013+--- Test mirror #3 ---
2014+
2015+{}
2016+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
2017+{"return": {}}
2018+{}
2019+{}
2020+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
2021+{"return": {}}
2022+{}
2023+{"execute": "blockdev-mirror", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "mirror_3", "sync": "bitmap", "target": "mirror_target_3"}}
2024+{"return": {}}
2025+{"execute": "job-complete", "arguments": {"id": "mirror_3"}}
2026+{"return": {}}
2027+{"data": {"device": "mirror_3", "len": 524288, "offset": 524288, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2028+{"execute": "job-finalize", "arguments": {"id": "mirror_3"}}
2029+{"return": {}}
2030+{"data": {"id": "mirror_3", "type": "mirror"}, "event": "BLOCK_JOB_PENDING", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2031+{"data": {"device": "mirror_3", "len": 524288, "offset": 524288, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2032+{
2033+ "bitmaps": {
2034+ "drive0": [
2035+ {
2036+ "busy": false,
2037+ "count": 0,
2038+ "granularity": 65536,
2039+ "name": "bitmap0",
2040+ "persistent": false,
2041+ "recording": true,
2042+ "status": "active"
2043+ }
2044+ ]
2045+ }
2046+}
2047+
2048+= Checking Bitmap bitmap0 =
2049+expecting 0 dirty sectors; have 0. OK!
2050+
2051+--- Cleanup ---
2052+
2053+{"execute": "block-dirty-bitmap-remove", "arguments": {"name": "bitmap0", "node": "drive0"}}
2054+{"return": {}}
2055+{
2056+ "bitmaps": {}
2057+}
2058+
2059+--- Verification ---
2060+
2061+qemu_img compare "TEST_DIR/PID-bsync1" "TEST_DIR/PID-fmirror1" ==> Mismatch, OK!
2062+qemu_img compare "TEST_DIR/PID-bsync2" "TEST_DIR/PID-fmirror2" ==> Mismatch, OK!
2063+qemu_img compare "TEST_DIR/PID-bsync3" "TEST_DIR/PID-fmirror3" ==> Identical, OK!
2064+qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fmirror3" ==> Identical, OK!
2065+
2066+
2067+=== Mode bitmap; Bitmap Sync on-success without failure ===
2068+
2069+--- Preparing image & VM ---
2070+
2071+{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/PID-img"}, "node-name": "drive0"}}
2072+{"return": {}}
2073+
2074+--- Write #0 ---
2075+
2076+write -P0x49 0x0000000 0x10000
2077+{"return": ""}
2078+write -P0x6c 0x0100000 0x10000
2079+{"return": ""}
2080+write -P0x6f 0x2000000 0x10000
2081+{"return": ""}
2082+write -P0x76 0x3ff0000 0x10000
2083+{"return": ""}
2084+{
2085+ "bitmaps": {}
2086+}
2087+
2088+--- Reference mirror #0 ---
2089+
2090+{}
2091+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
2092+{"return": {}}
2093+{}
2094+{}
2095+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
2096+{"return": {}}
2097+{}
2098+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_0", "sync": "full", "target": "ref_target_0"}}
2099+{"return": {}}
2100+{"execute": "job-complete", "arguments": {"id": "ref_mirror_0"}}
2101+{"return": {}}
2102+{"data": {"device": "ref_mirror_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2103+{"data": {"device": "ref_mirror_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2104+
2105+--- Add Bitmap ---
2106+
2107+{"execute": "block-dirty-bitmap-add", "arguments": {"granularity": 65536, "name": "bitmap0", "node": "drive0"}}
2108+{"return": {}}
2109+
2110+--- Write #1 ---
2111+
2112+write -P0x65 0x0000000 0x10000
2113+{"return": ""}
2114+write -P0x77 0x00f8000 0x10000
2115+{"return": ""}
2116+write -P0x72 0x2008000 0x10000
2117+{"return": ""}
2118+write -P0x69 0x3fe0000 0x10000
2119+{"return": ""}
2120+{
2121+ "bitmaps": {
2122+ "drive0": [
2123+ {
2124+ "busy": false,
2125+ "count": 393216,
2126+ "granularity": 65536,
2127+ "name": "bitmap0",
2128+ "persistent": false,
2129+ "recording": true,
2130+ "status": "active"
2131+ }
2132+ ]
2133+ }
2134+}
2135+
2136+= Checking Bitmap bitmap0 =
2137+expecting 6 dirty sectors; have 6. OK!
2138+
2139+--- Reference mirror #1 ---
2140+
2141+{}
2142+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
2143+{"return": {}}
2144+{}
2145+{}
2146+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
2147+{"return": {}}
2148+{}
2149+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_1", "sync": "full", "target": "ref_target_1"}}
2150+{"return": {}}
2151+{"execute": "job-complete", "arguments": {"id": "ref_mirror_1"}}
2152+{"return": {}}
2153+{"data": {"device": "ref_mirror_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2154+{"data": {"device": "ref_mirror_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2155+
2156+--- Test mirror #1 ---
2157+
2158+{}
2159+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
2160+{"return": {}}
2161+{}
2162+{}
2163+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
2164+{"return": {}}
2165+{}
2166+{"execute": "blockdev-mirror", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "mirror_1", "sync": "bitmap", "target": "mirror_target_1"}}
2167+{"return": {}}
2168+{"execute": "job-complete", "arguments": {"id": "mirror_1"}}
2169+{"return": {}}
2170+{"data": {"device": "mirror_1", "len": 393216, "offset": 393216, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2171+{"execute": "job-finalize", "arguments": {"id": "mirror_1"}}
2172+{"return": {}}
2173+{"data": {"id": "mirror_1", "type": "mirror"}, "event": "BLOCK_JOB_PENDING", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2174+{"data": {"device": "mirror_1", "len": 393216, "offset": 393216, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2175+{
2176+ "bitmaps": {
2177+ "drive0": [
2178+ {
2179+ "busy": false,
2180+ "count": 0,
2181+ "granularity": 65536,
2182+ "name": "bitmap0",
2183+ "persistent": false,
2184+ "recording": true,
2185+ "status": "active"
2186+ }
2187+ ]
2188+ }
2189+}
2190+
2191+= Checking Bitmap bitmap0 =
2192+expecting 0 dirty sectors; have 0. OK!
2193+
2194+--- Reference mirror #2 ---
2195+
2196+{}
2197+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
2198+{"return": {}}
2199+{}
2200+{}
2201+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
2202+{"return": {}}
2203+{}
2204+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_2", "sync": "full", "target": "ref_target_2"}}
2205+{"return": {}}
2206+{"execute": "job-complete", "arguments": {"id": "ref_mirror_2"}}
2207+{"return": {}}
2208+{"data": {"device": "ref_mirror_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2209+{"data": {"device": "ref_mirror_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2210+
2211+--- Test mirror #2 ---
2212+
2213+{}
2214+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
2215+{"return": {}}
2216+{}
2217+{}
2218+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
2219+{"return": {}}
2220+{}
2221+{"execute": "blockdev-mirror", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "mirror_2", "sync": "bitmap", "target": "mirror_target_2"}}
2222+{"return": {}}
2223+--- Write #2 ---
2224+
2225+write -P0x74 0x0010000 0x10000
2226+{"return": ""}
2227+write -P0x69 0x00e8000 0x10000
2228+{"return": ""}
2229+write -P0x6e 0x2018000 0x10000
2230+{"return": ""}
2231+write -P0x67 0x3fe0000 0x20000
2232+{"return": ""}
2233+{
2234+ "bitmaps": {
2235+ "drive0": [
2236+ {
2237+ "busy": false,
2238+ "count": 458752,
2239+ "granularity": 65536,
2240+ "persistent": false,
2241+ "recording": true,
2242+ "status": "active"
2243+ },
2244+ {
2245+ "busy": true,
2246+ "count": 458752,
2247+ "granularity": 65536,
2248+ "name": "bitmap0",
2249+ "persistent": false,
2250+ "recording": true,
2251+ "status": "locked"
2252+ }
2253+ ]
2254+ }
2255+}
2256+
2257+= Checking Bitmap bitmap0 =
2258+expecting 7 dirty sectors; have 7. OK!
2259+
2260+= Checking Bitmap bitmap0 =
2261+expecting 0 dirty sectors; have 0. OK!
2262+
2263+--- Write #3 ---
2264+
2265+write -P0xaa 0x0010000 0x30000
2266+{"return": ""}
2267+write -P0xbb 0x00d8000 0x10000
2268+{"return": ""}
2269+write -P0xcc 0x2028000 0x10000
2270+{"return": ""}
2271+write -P0xdd 0x3fc0000 0x10000
2272+{"return": ""}
2273+{
2274+ "bitmaps": {
2275+ "drive0": [
2276+ {
2277+ "busy": false,
2278+ "count": 524288,
2279+ "granularity": 65536,
2280+ "name": "bitmap0",
2281+ "persistent": false,
2282+ "recording": true,
2283+ "status": "active"
2284+ }
2285+ ]
2286+ }
2287+}
2288+
2289+= Checking Bitmap bitmap0 =
2290+expecting 8 dirty sectors; have 8. OK!
2291+
2292+--- Reference mirror #3 ---
2293+
2294+{}
2295+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
2296+{"return": {}}
2297+{}
2298+{}
2299+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
2300+{"return": {}}
2301+{}
2302+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_3", "sync": "full", "target": "ref_target_3"}}
2303+{"return": {}}
2304+{"execute": "job-complete", "arguments": {"id": "ref_mirror_3"}}
2305+{"return": {}}
2306+{"data": {"device": "ref_mirror_3", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2307+{"data": {"device": "ref_mirror_3", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2308+
2309+--- Test mirror #3 ---
2310+
2311+{}
2312+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
2313+{"return": {}}
2314+{}
2315+{}
2316+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
2317+{"return": {}}
2318+{}
2319+{"execute": "blockdev-mirror", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "mirror_3", "sync": "bitmap", "target": "mirror_target_3"}}
2320+{"return": {}}
2321+{"execute": "job-complete", "arguments": {"id": "mirror_3"}}
2322+{"return": {}}
2323+{"data": {"device": "mirror_3", "len": 524288, "offset": 524288, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2324+{"execute": "job-finalize", "arguments": {"id": "mirror_3"}}
2325+{"return": {}}
2326+{"data": {"id": "mirror_3", "type": "mirror"}, "event": "BLOCK_JOB_PENDING", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2327+{"data": {"device": "mirror_3", "len": 524288, "offset": 524288, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2328+{
2329+ "bitmaps": {
2330+ "drive0": [
2331+ {
2332+ "busy": false,
2333+ "count": 0,
2334+ "granularity": 65536,
2335+ "name": "bitmap0",
2336+ "persistent": false,
2337+ "recording": true,
2338+ "status": "active"
2339+ }
2340+ ]
2341+ }
2342+}
2343+
2344+= Checking Bitmap bitmap0 =
2345+expecting 0 dirty sectors; have 0. OK!
2346+
2347+--- Cleanup ---
2348+
2349+{"execute": "block-dirty-bitmap-remove", "arguments": {"name": "bitmap0", "node": "drive0"}}
2350+{"return": {}}
2351+{
2352+ "bitmaps": {}
2353+}
2354+
2355+--- Verification ---
2356+
2357+qemu_img compare "TEST_DIR/PID-bsync1" "TEST_DIR/PID-fmirror1" ==> Identical, OK!
2358+qemu_img compare "TEST_DIR/PID-bsync2" "TEST_DIR/PID-fmirror2" ==> Mismatch, OK!
2359+qemu_img compare "TEST_DIR/PID-bsync3" "TEST_DIR/PID-fmirror3" ==> Identical, OK!
2360+qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fmirror3" ==> Identical, OK!
2361+
2362+
2363+=== Mode bitmap; Bitmap Sync always with simulated failure ===
2364+
2365+--- Preparing image & VM ---
2366+
2367+{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/PID-img"}, "node-name": "drive0"}}
2368+{"return": {}}
2369+
2370+--- Write #0 ---
2371+
2372+write -P0x49 0x0000000 0x10000
2373+{"return": ""}
2374+write -P0x6c 0x0100000 0x10000
2375+{"return": ""}
2376+write -P0x6f 0x2000000 0x10000
2377+{"return": ""}
2378+write -P0x76 0x3ff0000 0x10000
2379+{"return": ""}
2380+{
2381+ "bitmaps": {}
2382+}
2383+
2384+--- Reference mirror #0 ---
2385+
2386+{}
2387+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
2388+{"return": {}}
2389+{}
2390+{}
2391+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
2392+{"return": {}}
2393+{}
2394+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_0", "sync": "full", "target": "ref_target_0"}}
2395+{"return": {}}
2396+{"execute": "job-complete", "arguments": {"id": "ref_mirror_0"}}
2397+{"return": {}}
2398+{"data": {"device": "ref_mirror_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2399+{"data": {"device": "ref_mirror_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2400+
2401+--- Add Bitmap ---
2402+
2403+{"execute": "block-dirty-bitmap-add", "arguments": {"granularity": 65536, "name": "bitmap0", "node": "drive0"}}
2404+{"return": {}}
2405+
2406+--- Write #1 ---
2407+
2408+write -P0x65 0x0000000 0x10000
2409+{"return": ""}
2410+write -P0x77 0x00f8000 0x10000
2411+{"return": ""}
2412+write -P0x72 0x2008000 0x10000
2413+{"return": ""}
2414+write -P0x69 0x3fe0000 0x10000
2415+{"return": ""}
2416+{
2417+ "bitmaps": {
2418+ "drive0": [
2419+ {
2420+ "busy": false,
2421+ "count": 393216,
2422+ "granularity": 65536,
2423+ "name": "bitmap0",
2424+ "persistent": false,
2425+ "recording": true,
2426+ "status": "active"
2427+ }
2428+ ]
2429+ }
2430+}
2431+
2432+= Checking Bitmap bitmap0 =
2433+expecting 6 dirty sectors; have 6. OK!
2434+
2435+--- Reference mirror #1 ---
2436+
2437+{}
2438+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
2439+{"return": {}}
2440+{}
2441+{}
2442+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
2443+{"return": {}}
2444+{}
2445+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_1", "sync": "full", "target": "ref_target_1"}}
2446+{"return": {}}
2447+{"execute": "job-complete", "arguments": {"id": "ref_mirror_1"}}
2448+{"return": {}}
2449+{"data": {"device": "ref_mirror_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2450+{"data": {"device": "ref_mirror_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2451+
2452+--- Test mirror #1 ---
2453+
2454+{}
2455+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
2456+{"return": {}}
2457+{}
2458+{}
2459+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
2460+{"return": {}}
2461+{}
2462+{"execute": "blockdev-mirror", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "mirror_1", "sync": "bitmap", "target": "mirror_target_1"}}
2463+{"return": {}}
2464+{"execute": "job-complete", "arguments": {"id": "mirror_1"}}
2465+{"return": {}}
2466+{"data": {"device": "mirror_1", "len": 393216, "offset": 393216, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2467+{"execute": "job-cancel", "arguments": {"id": "mirror_1"}}
2468+{"return": {}}
2469+{"data": {"id": "mirror_1", "type": "mirror"}, "event": "BLOCK_JOB_PENDING", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2470+{"data": {"device": "mirror_1", "len": 393216, "offset": 393216, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_CANCELLED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2471+{
2472+ "bitmaps": {
2473+ "drive0": [
2474+ {
2475+ "busy": false,
2476+ "count": 0,
2477+ "granularity": 65536,
2478+ "name": "bitmap0",
2479+ "persistent": false,
2480+ "recording": true,
2481+ "status": "active"
2482+ }
2483+ ]
2484+ }
2485+}
2486+
2487+= Checking Bitmap bitmap0 =
2488+expecting 0 dirty sectors; have 0. OK!
2489+
2490+--- Reference mirror #2 ---
2491+
2492+{}
2493+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
2494+{"return": {}}
2495+{}
2496+{}
2497+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
2498+{"return": {}}
2499+{}
2500+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_2", "sync": "full", "target": "ref_target_2"}}
2501+{"return": {}}
2502+{"execute": "job-complete", "arguments": {"id": "ref_mirror_2"}}
2503+{"return": {}}
2504+{"data": {"device": "ref_mirror_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2505+{"data": {"device": "ref_mirror_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2506+
2507+--- Test mirror #2 ---
2508+
2509+{}
2510+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
2511+{"return": {}}
2512+{}
2513+{}
2514+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
2515+{"return": {}}
2516+{}
2517+{"execute": "blockdev-mirror", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "mirror_2", "sync": "bitmap", "target": "mirror_target_2"}}
2518+{"return": {}}
2519+--- Write #2 ---
2520+
2521+write -P0x74 0x0010000 0x10000
2522+{"return": ""}
2523+write -P0x69 0x00e8000 0x10000
2524+{"return": ""}
2525+write -P0x6e 0x2018000 0x10000
2526+{"return": ""}
2527+write -P0x67 0x3fe0000 0x20000
2528+{"return": ""}
2529+{
2530+ "bitmaps": {
2531+ "drive0": [
2532+ {
2533+ "busy": false,
2534+ "count": 458752,
2535+ "granularity": 65536,
2536+ "persistent": false,
2537+ "recording": true,
2538+ "status": "active"
2539+ },
2540+ {
2541+ "busy": true,
2542+ "count": 458752,
2543+ "granularity": 65536,
2544+ "name": "bitmap0",
2545+ "persistent": false,
2546+ "recording": true,
2547+ "status": "locked"
2548+ }
2549+ ]
2550+ }
2551+}
2552+
2553+= Checking Bitmap bitmap0 =
2554+expecting 7 dirty sectors; have 7. OK!
2555+
2556+= Checking Bitmap bitmap0 =
2557+expecting 0 dirty sectors; have 0. OK!
2558+
2559+--- Write #3 ---
2560+
2561+write -P0xaa 0x0010000 0x30000
2562+{"return": ""}
2563+write -P0xbb 0x00d8000 0x10000
2564+{"return": ""}
2565+write -P0xcc 0x2028000 0x10000
2566+{"return": ""}
2567+write -P0xdd 0x3fc0000 0x10000
2568+{"return": ""}
2569+{
2570+ "bitmaps": {
2571+ "drive0": [
2572+ {
2573+ "busy": false,
2574+ "count": 524288,
2575+ "granularity": 65536,
2576+ "name": "bitmap0",
2577+ "persistent": false,
2578+ "recording": true,
2579+ "status": "active"
2580+ }
2581+ ]
2582+ }
2583+}
2584+
2585+= Checking Bitmap bitmap0 =
2586+expecting 8 dirty sectors; have 8. OK!
2587+
2588+--- Reference mirror #3 ---
2589+
2590+{}
2591+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
2592+{"return": {}}
2593+{}
2594+{}
2595+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
2596+{"return": {}}
2597+{}
2598+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_3", "sync": "full", "target": "ref_target_3"}}
2599+{"return": {}}
2600+{"execute": "job-complete", "arguments": {"id": "ref_mirror_3"}}
2601+{"return": {}}
2602+{"data": {"device": "ref_mirror_3", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2603+{"data": {"device": "ref_mirror_3", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2604+
2605+--- Test mirror #3 ---
2606+
2607+{}
2608+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
2609+{"return": {}}
2610+{}
2611+{}
2612+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
2613+{"return": {}}
2614+{}
2615+{"execute": "blockdev-mirror", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "mirror_3", "sync": "bitmap", "target": "mirror_target_3"}}
2616+{"return": {}}
2617+{"execute": "job-complete", "arguments": {"id": "mirror_3"}}
2618+{"return": {}}
2619+{"data": {"device": "mirror_3", "len": 524288, "offset": 524288, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2620+{"execute": "job-finalize", "arguments": {"id": "mirror_3"}}
2621+{"return": {}}
2622+{"data": {"id": "mirror_3", "type": "mirror"}, "event": "BLOCK_JOB_PENDING", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2623+{"data": {"device": "mirror_3", "len": 524288, "offset": 524288, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2624+{
2625+ "bitmaps": {
2626+ "drive0": [
2627+ {
2628+ "busy": false,
2629+ "count": 0,
2630+ "granularity": 65536,
2631+ "name": "bitmap0",
2632+ "persistent": false,
2633+ "recording": true,
2634+ "status": "active"
2635+ }
2636+ ]
2637+ }
2638+}
2639+
2640+= Checking Bitmap bitmap0 =
2641+expecting 0 dirty sectors; have 0. OK!
2642+
2643+--- Cleanup ---
2644+
2645+{"execute": "block-dirty-bitmap-remove", "arguments": {"name": "bitmap0", "node": "drive0"}}
2646+{"return": {}}
2647+{
2648+ "bitmaps": {}
2649+}
2650+
2651+--- Verification ---
2652+
2653+qemu_img compare "TEST_DIR/PID-bsync1" "TEST_DIR/PID-fmirror1" ==> Identical, OK!
2654+qemu_img compare "TEST_DIR/PID-bsync2" "TEST_DIR/PID-fmirror2" ==> Mismatch, OK!
2655+qemu_img compare "TEST_DIR/PID-bsync3" "TEST_DIR/PID-fmirror3" ==> Identical, OK!
2656+qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fmirror3" ==> Identical, OK!
2657+
2658+
2659+=== Mode bitmap; Bitmap Sync always with intermediate failure ===
2660+
2661+--- Preparing image & VM ---
2662+
2663+{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": {"driver": "blkdebug", "image": {"driver": "file", "filename": "TEST_DIR/PID-img"}, "inject-error": [{"errno": 5, "event": "read_aio", "immediately": false, "once": true, "state": 3}, {"errno": 5, "event": "read_aio", "immediately": false, "once": true, "state": 4}], "set-state": [{"event": "flush_to_disk", "new-state": 2, "state": 1}, {"event": "read_aio", "new-state": 3, "state": 2}, {"event": "read_aio", "new-state": 4, "state": 3}]}, "node-name": "drive0"}}
2664+{"return": {}}
2665+
2666+--- Write #0 ---
2667+
2668+write -P0x49 0x0000000 0x10000
2669+{"return": ""}
2670+write -P0x6c 0x0100000 0x10000
2671+{"return": ""}
2672+write -P0x6f 0x2000000 0x10000
2673+{"return": ""}
2674+write -P0x76 0x3ff0000 0x10000
2675+{"return": ""}
2676+{
2677+ "bitmaps": {}
2678+}
2679+
2680+--- Reference mirror #0 ---
2681+
2682+{}
2683+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
2684+{"return": {}}
2685+{}
2686+{}
2687+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
2688+{"return": {}}
2689+{}
2690+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_0", "sync": "full", "target": "ref_target_0"}}
2691+{"return": {}}
2692+{"execute": "job-complete", "arguments": {"id": "ref_mirror_0"}}
2693+{"return": {}}
2694+{"data": {"device": "ref_mirror_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2695+{"data": {"device": "ref_mirror_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2696+
2697+--- Add Bitmap ---
2698+
2699+{"execute": "block-dirty-bitmap-add", "arguments": {"granularity": 65536, "name": "bitmap0", "node": "drive0"}}
2700+{"return": {}}
2701+
2702+--- Write #1 ---
2703+
2704+write -P0x65 0x0000000 0x10000
2705+{"return": ""}
2706+write -P0x77 0x00f8000 0x10000
2707+{"return": ""}
2708+write -P0x72 0x2008000 0x10000
2709+{"return": ""}
2710+write -P0x69 0x3fe0000 0x10000
2711+{"return": ""}
2712+{
2713+ "bitmaps": {
2714+ "drive0": [
2715+ {
2716+ "busy": false,
2717+ "count": 393216,
2718+ "granularity": 65536,
2719+ "name": "bitmap0",
2720+ "persistent": false,
2721+ "recording": true,
2722+ "status": "active"
2723+ }
2724+ ]
2725+ }
2726+}
2727+
2728+= Checking Bitmap bitmap0 =
2729+expecting 6 dirty sectors; have 6. OK!
2730+
2731+--- Reference mirror #1 ---
2732+
2733+{}
2734+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
2735+{"return": {}}
2736+{}
2737+{}
2738+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
2739+{"return": {}}
2740+{}
2741+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_1", "sync": "full", "target": "ref_target_1"}}
2742+{"return": {}}
2743+{"execute": "job-complete", "arguments": {"id": "ref_mirror_1"}}
2744+{"return": {}}
2745+{"data": {"device": "ref_mirror_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2746+{"data": {"device": "ref_mirror_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2747+
2748+{"return": ""}
2749+
2750+--- Test mirror #1 ---
2751+
2752+{}
2753+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
2754+{"return": {}}
2755+{}
2756+{}
2757+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
2758+{"return": {}}
2759+{}
2760+{"execute": "blockdev-mirror", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "mirror_1", "sync": "bitmap", "target": "mirror_target_1"}}
2761+{"return": {}}
2762+{"data": {"action": "report", "device": "mirror_1", "operation": "read"}, "event": "BLOCK_JOB_ERROR", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2763+{"data": {"action": "report", "device": "mirror_1", "operation": "read"}, "event": "BLOCK_JOB_ERROR", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2764+{"data": {"device": "mirror_1", "error": "Input/output error", "len": 393216, "offset": 65536, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2765+{
2766+ "bitmaps": {
2767+ "drive0": [
2768+ {
2769+ "busy": false,
2770+ "count": 327680,
2771+ "granularity": 65536,
2772+ "name": "bitmap0",
2773+ "persistent": false,
2774+ "recording": true,
2775+ "status": "active"
2776+ }
2777+ ]
2778+ }
2779+}
2780+
2781+= Checking Bitmap bitmap0 =
2782+expecting 5 dirty sectors; have 5. OK!
2783+
2784+--- Reference mirror #2 ---
2785+
2786+{}
2787+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
2788+{"return": {}}
2789+{}
2790+{}
2791+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
2792+{"return": {}}
2793+{}
2794+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_2", "sync": "full", "target": "ref_target_2"}}
2795+{"return": {}}
2796+{"execute": "job-complete", "arguments": {"id": "ref_mirror_2"}}
2797+{"return": {}}
2798+{"data": {"device": "ref_mirror_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2799+{"data": {"device": "ref_mirror_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2800+
2801+--- Test mirror #2 ---
2802+
2803+{}
2804+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
2805+{"return": {}}
2806+{}
2807+{}
2808+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
2809+{"return": {}}
2810+{}
2811+{"execute": "blockdev-mirror", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "mirror_2", "sync": "bitmap", "target": "mirror_target_2"}}
2812+{"return": {}}
2813+--- Write #2 ---
2814+
2815+write -P0x74 0x0010000 0x10000
2816+{"return": ""}
2817+write -P0x69 0x00e8000 0x10000
2818+{"return": ""}
2819+write -P0x6e 0x2018000 0x10000
2820+{"return": ""}
2821+write -P0x67 0x3fe0000 0x20000
2822+{"return": ""}
2823+{
2824+ "bitmaps": {
2825+ "drive0": [
2826+ {
2827+ "busy": false,
2828+ "count": 262144,
2829+ "granularity": 65536,
2830+ "persistent": false,
2831+ "recording": true,
2832+ "status": "active"
2833+ },
2834+ {
2835+ "busy": true,
2836+ "count": 589824,
2837+ "granularity": 65536,
2838+ "name": "bitmap0",
2839+ "persistent": false,
2840+ "recording": true,
2841+ "status": "locked"
2842+ }
2843+ ]
2844+ }
2845+}
2846+
2847+= Checking Bitmap bitmap0 =
2848+expecting 9 dirty sectors; have 9. OK!
2849+
2850+= Checking Bitmap bitmap0 =
2851+expecting 0 dirty sectors; have 0. OK!
2852+
2853+--- Write #3 ---
2854+
2855+write -P0xaa 0x0010000 0x30000
2856+{"return": ""}
2857+write -P0xbb 0x00d8000 0x10000
2858+{"return": ""}
2859+write -P0xcc 0x2028000 0x10000
2860+{"return": ""}
2861+write -P0xdd 0x3fc0000 0x10000
2862+{"return": ""}
2863+{
2864+ "bitmaps": {
2865+ "drive0": [
2866+ {
2867+ "busy": false,
2868+ "count": 524288,
2869+ "granularity": 65536,
2870+ "name": "bitmap0",
2871+ "persistent": false,
2872+ "recording": true,
2873+ "status": "active"
2874+ }
2875+ ]
2876+ }
2877+}
2878+
2879+= Checking Bitmap bitmap0 =
2880+expecting 8 dirty sectors; have 8. OK!
2881+
2882+--- Reference mirror #3 ---
2883+
2884+{}
2885+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
2886+{"return": {}}
2887+{}
2888+{}
2889+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
2890+{"return": {}}
2891+{}
2892+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_3", "sync": "full", "target": "ref_target_3"}}
2893+{"return": {}}
2894+{"execute": "job-complete", "arguments": {"id": "ref_mirror_3"}}
2895+{"return": {}}
2896+{"data": {"device": "ref_mirror_3", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2897+{"data": {"device": "ref_mirror_3", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2898+
2899+--- Test mirror #3 ---
2900+
2901+{}
2902+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
2903+{"return": {}}
2904+{}
2905+{}
2906+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
2907+{"return": {}}
2908+{}
2909+{"execute": "blockdev-mirror", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "mirror_3", "sync": "bitmap", "target": "mirror_target_3"}}
2910+{"return": {}}
2911+{"execute": "job-complete", "arguments": {"id": "mirror_3"}}
2912+{"return": {}}
2913+{"data": {"device": "mirror_3", "len": 524288, "offset": 524288, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2914+{"execute": "job-finalize", "arguments": {"id": "mirror_3"}}
2915+{"return": {}}
2916+{"data": {"id": "mirror_3", "type": "mirror"}, "event": "BLOCK_JOB_PENDING", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2917+{"data": {"device": "mirror_3", "len": 524288, "offset": 524288, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2918+{
2919+ "bitmaps": {
2920+ "drive0": [
2921+ {
2922+ "busy": false,
2923+ "count": 0,
2924+ "granularity": 65536,
2925+ "name": "bitmap0",
2926+ "persistent": false,
2927+ "recording": true,
2928+ "status": "active"
2929+ }
2930+ ]
2931+ }
2932+}
2933+
2934+= Checking Bitmap bitmap0 =
2935+expecting 0 dirty sectors; have 0. OK!
2936+
2937+--- Cleanup ---
2938+
2939+{"execute": "block-dirty-bitmap-remove", "arguments": {"name": "bitmap0", "node": "drive0"}}
2940+{"return": {}}
2941+{
2942+ "bitmaps": {}
2943+}
2944+
2945+--- Verification ---
2946+
2947+qemu_img compare "TEST_DIR/PID-bsync1" "TEST_DIR/PID-fmirror1" ==> Mismatch, OK!
2948+qemu_img compare "TEST_DIR/PID-bsync2" "TEST_DIR/PID-fmirror2" ==> Mismatch, OK!
2949+qemu_img compare "TEST_DIR/PID-bsync3" "TEST_DIR/PID-fmirror3" ==> Identical, OK!
2950+qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fmirror3" ==> Identical, OK!
2951+
2952+
2953+=== Mode bitmap; Bitmap Sync always without failure ===
2954+
2955+--- Preparing image & VM ---
2956+
2957+{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/PID-img"}, "node-name": "drive0"}}
2958+{"return": {}}
2959+
2960+--- Write #0 ---
2961+
2962+write -P0x49 0x0000000 0x10000
2963+{"return": ""}
2964+write -P0x6c 0x0100000 0x10000
2965+{"return": ""}
2966+write -P0x6f 0x2000000 0x10000
2967+{"return": ""}
2968+write -P0x76 0x3ff0000 0x10000
2969+{"return": ""}
2970+{
2971+ "bitmaps": {}
2972+}
2973+
2974+--- Reference mirror #0 ---
2975+
2976+{}
2977+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
2978+{"return": {}}
2979+{}
2980+{}
2981+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
2982+{"return": {}}
2983+{}
2984+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_0", "sync": "full", "target": "ref_target_0"}}
2985+{"return": {}}
2986+{"execute": "job-complete", "arguments": {"id": "ref_mirror_0"}}
2987+{"return": {}}
2988+{"data": {"device": "ref_mirror_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2989+{"data": {"device": "ref_mirror_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
2990+
2991+--- Add Bitmap ---
2992+
2993+{"execute": "block-dirty-bitmap-add", "arguments": {"granularity": 65536, "name": "bitmap0", "node": "drive0"}}
2994+{"return": {}}
2995+
2996+--- Write #1 ---
2997+
2998+write -P0x65 0x0000000 0x10000
2999+{"return": ""}
3000+write -P0x77 0x00f8000 0x10000
3001+{"return": ""}
3002+write -P0x72 0x2008000 0x10000
3003+{"return": ""}
3004+write -P0x69 0x3fe0000 0x10000
3005+{"return": ""}
3006+{
3007+ "bitmaps": {
3008+ "drive0": [
3009+ {
3010+ "busy": false,
3011+ "count": 393216,
3012+ "granularity": 65536,
3013+ "name": "bitmap0",
3014+ "persistent": false,
3015+ "recording": true,
3016+ "status": "active"
3017+ }
3018+ ]
3019+ }
3020+}
3021+
3022+= Checking Bitmap bitmap0 =
3023+expecting 6 dirty sectors; have 6. OK!
3024+
3025+--- Reference mirror #1 ---
3026+
3027+{}
3028+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
3029+{"return": {}}
3030+{}
3031+{}
3032+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
3033+{"return": {}}
3034+{}
3035+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_1", "sync": "full", "target": "ref_target_1"}}
3036+{"return": {}}
3037+{"execute": "job-complete", "arguments": {"id": "ref_mirror_1"}}
3038+{"return": {}}
3039+{"data": {"device": "ref_mirror_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
3040+{"data": {"device": "ref_mirror_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
3041+
3042+--- Test mirror #1 ---
3043+
3044+{}
3045+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
3046+{"return": {}}
3047+{}
3048+{}
3049+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
3050+{"return": {}}
3051+{}
3052+{"execute": "blockdev-mirror", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "mirror_1", "sync": "bitmap", "target": "mirror_target_1"}}
3053+{"return": {}}
3054+{"execute": "job-complete", "arguments": {"id": "mirror_1"}}
3055+{"return": {}}
3056+{"data": {"device": "mirror_1", "len": 393216, "offset": 393216, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
3057+{"execute": "job-finalize", "arguments": {"id": "mirror_1"}}
3058+{"return": {}}
3059+{"data": {"id": "mirror_1", "type": "mirror"}, "event": "BLOCK_JOB_PENDING", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
3060+{"data": {"device": "mirror_1", "len": 393216, "offset": 393216, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
3061+{
3062+ "bitmaps": {
3063+ "drive0": [
3064+ {
3065+ "busy": false,
3066+ "count": 0,
3067+ "granularity": 65536,
3068+ "name": "bitmap0",
3069+ "persistent": false,
3070+ "recording": true,
3071+ "status": "active"
3072+ }
3073+ ]
3074+ }
3075+}
3076+
3077+= Checking Bitmap bitmap0 =
3078+expecting 0 dirty sectors; have 0. OK!
3079+
3080+--- Reference mirror #2 ---
3081+
3082+{}
3083+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
3084+{"return": {}}
3085+{}
3086+{}
3087+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
3088+{"return": {}}
3089+{}
3090+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_2", "sync": "full", "target": "ref_target_2"}}
3091+{"return": {}}
3092+{"execute": "job-complete", "arguments": {"id": "ref_mirror_2"}}
3093+{"return": {}}
3094+{"data": {"device": "ref_mirror_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
3095+{"data": {"device": "ref_mirror_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
3096+
3097+--- Test mirror #2 ---
3098+
3099+{}
3100+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
3101+{"return": {}}
3102+{}
3103+{}
3104+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
3105+{"return": {}}
3106+{}
3107+{"execute": "blockdev-mirror", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "mirror_2", "sync": "bitmap", "target": "mirror_target_2"}}
3108+{"return": {}}
3109+--- Write #2 ---
3110+
3111+write -P0x74 0x0010000 0x10000
3112+{"return": ""}
3113+write -P0x69 0x00e8000 0x10000
3114+{"return": ""}
3115+write -P0x6e 0x2018000 0x10000
3116+{"return": ""}
3117+write -P0x67 0x3fe0000 0x20000
3118+{"return": ""}
3119+{
3120+ "bitmaps": {
3121+ "drive0": [
3122+ {
3123+ "busy": false,
3124+ "count": 458752,
3125+ "granularity": 65536,
3126+ "persistent": false,
3127+ "recording": true,
3128+ "status": "active"
3129+ },
3130+ {
3131+ "busy": true,
3132+ "count": 458752,
3133+ "granularity": 65536,
3134+ "name": "bitmap0",
3135+ "persistent": false,
3136+ "recording": true,
3137+ "status": "locked"
3138+ }
3139+ ]
3140+ }
3141+}
3142+
3143+= Checking Bitmap bitmap0 =
3144+expecting 7 dirty sectors; have 7. OK!
3145+
3146+= Checking Bitmap bitmap0 =
3147+expecting 0 dirty sectors; have 0. OK!
3148+
3149+--- Write #3 ---
3150+
3151+write -P0xaa 0x0010000 0x30000
3152+{"return": ""}
3153+write -P0xbb 0x00d8000 0x10000
3154+{"return": ""}
3155+write -P0xcc 0x2028000 0x10000
3156+{"return": ""}
3157+write -P0xdd 0x3fc0000 0x10000
3158+{"return": ""}
3159+{
3160+ "bitmaps": {
3161+ "drive0": [
3162+ {
3163+ "busy": false,
3164+ "count": 524288,
3165+ "granularity": 65536,
3166+ "name": "bitmap0",
3167+ "persistent": false,
3168+ "recording": true,
3169+ "status": "active"
3170+ }
3171+ ]
3172+ }
3173+}
3174+
3175+= Checking Bitmap bitmap0 =
3176+expecting 8 dirty sectors; have 8. OK!
3177+
3178+--- Reference mirror #3 ---
3179+
3180+{}
3181+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
3182+{"return": {}}
3183+{}
3184+{}
3185+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
3186+{"return": {}}
3187+{}
3188+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "ref_mirror_3", "sync": "full", "target": "ref_target_3"}}
3189+{"return": {}}
3190+{"execute": "job-complete", "arguments": {"id": "ref_mirror_3"}}
3191+{"return": {}}
3192+{"data": {"device": "ref_mirror_3", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
3193+{"data": {"device": "ref_mirror_3", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
3194+
3195+--- Test mirror #3 ---
3196+
3197+{}
3198+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
3199+{"return": {}}
3200+{}
3201+{}
3202+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
3203+{"return": {}}
3204+{}
3205+{"execute": "blockdev-mirror", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "mirror_3", "sync": "bitmap", "target": "mirror_target_3"}}
3206+{"return": {}}
3207+{"execute": "job-complete", "arguments": {"id": "mirror_3"}}
3208+{"return": {}}
3209+{"data": {"device": "mirror_3", "len": 524288, "offset": 524288, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
3210+{"execute": "job-finalize", "arguments": {"id": "mirror_3"}}
3211+{"return": {}}
3212+{"data": {"id": "mirror_3", "type": "mirror"}, "event": "BLOCK_JOB_PENDING", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
3213+{"data": {"device": "mirror_3", "len": 524288, "offset": 524288, "speed": 0, "type": "mirror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
3214+{
3215+ "bitmaps": {
3216+ "drive0": [
3217+ {
3218+ "busy": false,
3219+ "count": 0,
3220+ "granularity": 65536,
3221+ "name": "bitmap0",
3222+ "persistent": false,
3223+ "recording": true,
3224+ "status": "active"
3225+ }
3226+ ]
3227+ }
3228+}
3229+
3230+= Checking Bitmap bitmap0 =
3231+expecting 0 dirty sectors; have 0. OK!
3232+
3233+--- Cleanup ---
3234+
3235+{"execute": "block-dirty-bitmap-remove", "arguments": {"name": "bitmap0", "node": "drive0"}}
3236+{"return": {}}
3237+{
3238+ "bitmaps": {}
3239+}
3240+
3241+--- Verification ---
3242+
3243+qemu_img compare "TEST_DIR/PID-bsync1" "TEST_DIR/PID-fmirror1" ==> Identical, OK!
3244+qemu_img compare "TEST_DIR/PID-bsync2" "TEST_DIR/PID-fmirror2" ==> Mismatch, OK!
3245+qemu_img compare "TEST_DIR/PID-bsync3" "TEST_DIR/PID-fmirror3" ==> Identical, OK!
3246+qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fmirror3" ==> Identical, OK!
3247+
3248+
3249+=== API failure tests ===
3250+
3251+--- Preparing image & VM ---
3252+
3253+{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/PID-img"}, "node-name": "drive0"}}
3254+{"return": {}}
3255+
3256+{}
3257+{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
3258+{"return": {}}
3259+{}
3260+{}
3261+{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
3262+{"return": {}}
3263+{}
3264+
3265+{"execute": "block-dirty-bitmap-add", "arguments": {"granularity": 65536, "name": "bitmap0", "node": "drive0"}}
3266+{"return": {}}
3267+
3268+-- Testing invalid QMP commands --
3269+
3270+-- Sync mode incremental tests --
3271+
3272+{"execute": "blockdev-mirror", "arguments": {"bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "incremental", "target": "mirror_target"}}
3273+{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
3274+
3275+{"execute": "blockdev-mirror", "arguments": {"bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "incremental", "target": "mirror_target"}}
3276+{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
3277+
3278+{"execute": "blockdev-mirror", "arguments": {"bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "incremental", "target": "mirror_target"}}
3279+{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
3280+
3281+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "incremental", "target": "mirror_target"}}
3282+{"error": {"class": "GenericError", "desc": "Sync mode 'incremental' not supported"}}
3283+
3284+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "incremental", "target": "mirror_target"}}
3285+{"error": {"class": "GenericError", "desc": "Dirty bitmap 'bitmap404' not found"}}
3286+
3287+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "incremental", "target": "mirror_target"}}
3288+{"error": {"class": "GenericError", "desc": "Dirty bitmap 'bitmap404' not found"}}
3289+
3290+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "incremental", "target": "mirror_target"}}
3291+{"error": {"class": "GenericError", "desc": "Dirty bitmap 'bitmap404' not found"}}
3292+
3293+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "incremental", "target": "mirror_target"}}
3294+{"error": {"class": "GenericError", "desc": "bitmap-mode must be specified if a bitmap is provided"}}
3295+
3296+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "incremental", "target": "mirror_target"}}
3297+{"error": {"class": "GenericError", "desc": "Sync mode 'incremental' not supported"}}
3298+
3299+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "incremental", "target": "mirror_target"}}
3300+{"error": {"class": "GenericError", "desc": "Sync mode 'incremental' not supported"}}
3301+
3302+-- Sync mode bitmap tests --
3303+
3304+{"execute": "blockdev-mirror", "arguments": {"bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "bitmap", "target": "mirror_target"}}
3305+{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
3306+
3307+{"execute": "blockdev-mirror", "arguments": {"bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "bitmap", "target": "mirror_target"}}
3308+{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
3309+
3310+{"execute": "blockdev-mirror", "arguments": {"bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "bitmap", "target": "mirror_target"}}
3311+{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
3312+
3313+{"execute": "blockdev-mirror", "arguments": {"device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "bitmap", "target": "mirror_target"}}
3314+{"error": {"class": "GenericError", "desc": "Must provide a valid bitmap name for 'bitmap' sync mode"}}
3315+
3316+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "bitmap", "target": "mirror_target"}}
3317+{"error": {"class": "GenericError", "desc": "Dirty bitmap 'bitmap404' not found"}}
3318+
3319+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "bitmap", "target": "mirror_target"}}
3320+{"error": {"class": "GenericError", "desc": "Dirty bitmap 'bitmap404' not found"}}
3321+
3322+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "bitmap", "target": "mirror_target"}}
3323+{"error": {"class": "GenericError", "desc": "Dirty bitmap 'bitmap404' not found"}}
3324+
3325+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "bitmap", "target": "mirror_target"}}
3326+{"error": {"class": "GenericError", "desc": "bitmap-mode must be specified if a bitmap is provided"}}
3327+
3328+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap0", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "bitmap", "target": "mirror_target"}}
3329+{"error": {"class": "GenericError", "desc": "bitmap-mode must be specified if a bitmap is provided"}}
3330+
3331+-- Sync mode full tests --
3332+
3333+{"execute": "blockdev-mirror", "arguments": {"bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "full", "target": "mirror_target"}}
3334+{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
3335+
3336+{"execute": "blockdev-mirror", "arguments": {"bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "full", "target": "mirror_target"}}
3337+{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
3338+
3339+{"execute": "blockdev-mirror", "arguments": {"bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "full", "target": "mirror_target"}}
3340+{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
3341+
3342+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "full", "target": "mirror_target"}}
3343+{"error": {"class": "GenericError", "desc": "Dirty bitmap 'bitmap404' not found"}}
3344+
3345+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "full", "target": "mirror_target"}}
3346+{"error": {"class": "GenericError", "desc": "Dirty bitmap 'bitmap404' not found"}}
3347+
3348+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "full", "target": "mirror_target"}}
3349+{"error": {"class": "GenericError", "desc": "Dirty bitmap 'bitmap404' not found"}}
3350+
3351+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "full", "target": "mirror_target"}}
3352+{"error": {"class": "GenericError", "desc": "bitmap-mode must be specified if a bitmap is provided"}}
3353+
3354+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "full", "target": "mirror_target"}}
3355+{"error": {"class": "GenericError", "desc": "sync mode 'full' is not compatible with bitmaps"}}
3356+
3357+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "full", "target": "mirror_target"}}
3358+{"error": {"class": "GenericError", "desc": "sync mode 'full' is not compatible with bitmaps"}}
3359+
3360+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "full", "target": "mirror_target"}}
3361+{"error": {"class": "GenericError", "desc": "sync mode 'full' is not compatible with bitmaps"}}
3362+
3363+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap0", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "full", "target": "mirror_target"}}
3364+{"error": {"class": "GenericError", "desc": "bitmap-mode must be specified if a bitmap is provided"}}
3365+
3366+-- Sync mode top tests --
3367+
3368+{"execute": "blockdev-mirror", "arguments": {"bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "top", "target": "mirror_target"}}
3369+{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
3370+
3371+{"execute": "blockdev-mirror", "arguments": {"bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "top", "target": "mirror_target"}}
3372+{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
3373+
3374+{"execute": "blockdev-mirror", "arguments": {"bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "top", "target": "mirror_target"}}
3375+{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
3376+
3377+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "top", "target": "mirror_target"}}
3378+{"error": {"class": "GenericError", "desc": "Dirty bitmap 'bitmap404' not found"}}
3379+
3380+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "top", "target": "mirror_target"}}
3381+{"error": {"class": "GenericError", "desc": "Dirty bitmap 'bitmap404' not found"}}
3382+
3383+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "top", "target": "mirror_target"}}
3384+{"error": {"class": "GenericError", "desc": "Dirty bitmap 'bitmap404' not found"}}
3385+
3386+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "top", "target": "mirror_target"}}
3387+{"error": {"class": "GenericError", "desc": "bitmap-mode must be specified if a bitmap is provided"}}
3388+
3389+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "top", "target": "mirror_target"}}
3390+{"error": {"class": "GenericError", "desc": "sync mode 'full' is not compatible with bitmaps"}}
3391+
3392+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "top", "target": "mirror_target"}}
3393+{"error": {"class": "GenericError", "desc": "sync mode 'full' is not compatible with bitmaps"}}
3394+
3395+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "top", "target": "mirror_target"}}
3396+{"error": {"class": "GenericError", "desc": "sync mode 'full' is not compatible with bitmaps"}}
3397+
3398+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap0", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "top", "target": "mirror_target"}}
3399+{"error": {"class": "GenericError", "desc": "bitmap-mode must be specified if a bitmap is provided"}}
3400+
3401+-- Sync mode none tests --
3402+
3403+{"execute": "blockdev-mirror", "arguments": {"bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "none", "target": "mirror_target"}}
3404+{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
3405+
3406+{"execute": "blockdev-mirror", "arguments": {"bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "none", "target": "mirror_target"}}
3407+{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
3408+
3409+{"execute": "blockdev-mirror", "arguments": {"bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "none", "target": "mirror_target"}}
3410+{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
3411+
3412+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "none", "target": "mirror_target"}}
3413+{"error": {"class": "GenericError", "desc": "Dirty bitmap 'bitmap404' not found"}}
3414+
3415+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "none", "target": "mirror_target"}}
3416+{"error": {"class": "GenericError", "desc": "Dirty bitmap 'bitmap404' not found"}}
3417+
3418+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "none", "target": "mirror_target"}}
3419+{"error": {"class": "GenericError", "desc": "Dirty bitmap 'bitmap404' not found"}}
3420+
3421+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap404", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "none", "target": "mirror_target"}}
3422+{"error": {"class": "GenericError", "desc": "bitmap-mode must be specified if a bitmap is provided"}}
3423+
3424+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "none", "target": "mirror_target"}}
3425+{"error": {"class": "GenericError", "desc": "sync mode 'none' is not compatible with bitmaps"}}
3426+
3427+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "none", "target": "mirror_target"}}
3428+{"error": {"class": "GenericError", "desc": "sync mode 'none' is not compatible with bitmaps"}}
3429+
3430+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "none", "target": "mirror_target"}}
3431+{"error": {"class": "GenericError", "desc": "sync mode 'none' is not compatible with bitmaps"}}
3432+
3433+{"execute": "blockdev-mirror", "arguments": {"bitmap": "bitmap0", "device": "drive0", "filter-node-name": "mirror-top", "job-id": "api_job", "sync": "none", "target": "mirror_target"}}
3434+{"error": {"class": "GenericError", "desc": "bitmap-mode must be specified if a bitmap is provided"}}
3435+
3436diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
817b7667 3437index 2960dff728..952dceba1f 100644
059a9447
FG
3438--- a/tests/qemu-iotests/group
3439+++ b/tests/qemu-iotests/group
83faa3fe
TL
3440@@ -270,6 +270,7 @@
3441 253 rw quick
3442 254 rw backing quick
3443 255 rw quick
3444+384 rw
3445 256 rw auto quick
3446 257 rw
3447 258 rw quick