1
The following changes since commit 98b2e3c9ab3abfe476a2b02f8f51813edb90e72d:
1
The following changes since commit 346ed3151f1c43e72c40cb55b392a1d4cface62c:
2
2
3
Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging (2019-10-08 16:08:35 +0100)
3
Merge remote-tracking branch 'remotes/awilliam/tags/vfio-update-20200206.0' into staging (2020-02-07 11:52:15 +0000)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://github.com/XanClic/qemu.git tags/pull-block-2019-10-10
7
https://github.com/stefanha/qemu.git tags/block-pull-request
8
8
9
for you to fetch changes up to 35f05b2e2ee59e077bf949057dc0959ddd6e5249:
9
for you to fetch changes up to 11a18c84db4a71497d3d40769688a01b6f64b2ad:
10
10
11
iotests/162: Fix for newer Linux 5.3+ (2019-10-10 12:13:23 +0200)
11
hw/core: Allow setting 'virtio-blk-device.scsi' property on OSX host (2020-02-07 16:49:39 +0000)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block patches:
14
Pull request
15
- Parallelized request handling for qcow2
16
- Backup job refactoring to use a filter node instead of before-write
17
notifiers
18
- Add discard accounting information to file-posix nodes
19
- Allow trivial reopening of nbd nodes
20
- Some iotest fixes
21
15
22
----------------------------------------------------------------
16
----------------------------------------------------------------
23
Anton Nefedov (9):
24
qapi: group BlockDeviceStats fields
25
qapi: add unmap to BlockDeviceStats
26
block: add empty account cookie type
27
ide: account UNMAP (TRIM) operations
28
scsi: store unmap offset and nb_sectors in request struct
29
scsi: move unmap error checking to the complete callback
30
scsi: account unmap operations
31
file-posix: account discard operations
32
qapi: query-blockstat: add driver specific file-posix stats
33
17
34
Daniel P. Berrangé (1):
18
Philippe Mathieu-Daudé (1):
35
tests: fix I/O test for hosts defaulting to LUKSv2
19
hw/core: Allow setting 'virtio-blk-device.scsi' property on OSX host
36
20
37
Max Reitz (4):
21
Vladimir Sementsov-Ogievskiy (1):
38
iotests: Fix 125 for growth_mode = metadata
22
block: fix crash on zero-length unaligned write and read
39
iotests: Disable 125 on broken XFS versions
40
iotests: Use stat -c %b in 125
41
iotests/162: Fix for newer Linux 5.3+
42
23
43
Maxim Levitsky (1):
24
block/io.c | 28 +++++++++++++++++++++++++++-
44
nbd: add empty .bdrv_reopen_prepare
25
hw/core/machine.c | 3 ++-
45
26
2 files changed, 29 insertions(+), 2 deletions(-)
46
Vladimir Sementsov-Ogievskiy (21):
47
qemu-iotests: ignore leaks on failure paths in 026
48
block: introduce aio task pool
49
block/qcow2: refactor qcow2_co_preadv_part
50
block/qcow2: refactor qcow2_co_pwritev_part
51
block/qcow2: introduce parallel subrequest handling in read and write
52
block/backup: fix max_transfer handling for copy_range
53
block/backup: fix backup_cow_with_offload for last cluster
54
block/backup: split shareable copying part from backup_do_cow
55
block/backup: improve comment about image fleecing
56
block/backup: introduce BlockCopyState
57
block/backup: fix block-comment style
58
block: move block_copy from block/backup.c to separate file
59
block: teach bdrv_debug_breakpoint skip filters with backing
60
iotests: prepare 124 and 257 bitmap querying for backup-top filter
61
iotests: 257: drop unused Drive.device field
62
iotests: 257: drop device_add
63
block/backup: move in-flight requests handling from backup to
64
block-copy
65
block/backup: move write_flags calculation inside backup_job_create
66
block/block-copy: split block_copy_set_callbacks function
67
block: introduce backup-top filter driver
68
block/backup: use backup-top instead of write notifiers
69
70
block/Makefile.objs | 4 +
71
qapi/block-core.json | 89 +++-
72
block/backup-top.h | 41 ++
73
block/qcow2.h | 3 +
74
include/block/accounting.h | 2 +
75
include/block/aio_task.h | 54 +++
76
include/block/block-copy.h | 93 ++++
77
include/block/block.h | 1 +
78
include/block/block_int.h | 2 +
79
block.c | 43 +-
80
block/accounting.c | 6 +
81
block/aio_task.c | 124 +++++
82
block/backup-top.c | 276 +++++++++++
83
block/backup.c | 443 ++++--------------
84
block/block-copy.c | 345 ++++++++++++++
85
block/file-posix.c | 54 ++-
86
block/nbd.c | 15 +
87
block/qapi.c | 11 +
88
block/qcow2.c | 466 ++++++++++++-------
89
block/replication.c | 2 +-
90
blockdev.c | 1 +
91
hw/ide/core.c | 12 +
92
hw/scsi/scsi-disk.c | 34 +-
93
block/trace-events | 15 +-
94
tests/qemu-iotests/026 | 6 +-
95
tests/qemu-iotests/026.out | 80 +---
96
tests/qemu-iotests/026.out.nocache | 80 +---
97
tests/qemu-iotests/056 | 8 +-
98
tests/qemu-iotests/124 | 83 ++--
99
tests/qemu-iotests/125 | 45 +-
100
tests/qemu-iotests/141.out | 2 +-
101
tests/qemu-iotests/149 | 2 +-
102
tests/qemu-iotests/149.out | 44 +-
103
tests/qemu-iotests/162 | 2 +-
104
tests/qemu-iotests/162.out | 2 +-
105
tests/qemu-iotests/227.out | 18 +
106
tests/qemu-iotests/257 | 91 ++--
107
tests/qemu-iotests/257.out | 714 ++++++++++++-----------------
108
tests/qemu-iotests/common.rc | 17 +
109
tests/qemu-iotests/iotests.py | 27 ++
110
40 files changed, 2108 insertions(+), 1249 deletions(-)
111
create mode 100644 block/backup-top.h
112
create mode 100644 include/block/aio_task.h
113
create mode 100644 include/block/block-copy.h
114
create mode 100644 block/aio_task.c
115
create mode 100644 block/backup-top.c
116
create mode 100644 block/block-copy.c
117
27
118
--
28
--
119
2.21.0
29
2.24.1
120
30
121
31
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Upcoming asynchronous handling of sub-parts of qcow2 requests will
4
change number of leaked clusters and even make it racy. As a
5
preparation, ignore leaks on failure parts in 026.
6
7
It's not trivial to just grep or substitute qemu-img output for such
8
thing. Instead do better: 3 is a error code of qemu-img check, if only
9
leaks are found. Catch this case and print success output.
10
11
Suggested-by: Anton Nefedov <anton.nefedov@virtuozzo.com>
12
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
13
Message-id: 20190916175324.18478-2-vsementsov@virtuozzo.com
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
15
---
16
tests/qemu-iotests/026 | 6 +--
17
tests/qemu-iotests/026.out | 80 ++++++++----------------------
18
tests/qemu-iotests/026.out.nocache | 80 ++++++++----------------------
19
tests/qemu-iotests/common.rc | 17 +++++++
20
4 files changed, 60 insertions(+), 123 deletions(-)
21
22
diff --git a/tests/qemu-iotests/026 b/tests/qemu-iotests/026
23
index XXXXXXX..XXXXXXX 100755
24
--- a/tests/qemu-iotests/026
25
+++ b/tests/qemu-iotests/026
26
@@ -XXX,XX +XXX,XX @@ if [ "$event" == "l2_load" ]; then
27
$QEMU_IO -c "read $vmstate 0 128k " "$BLKDBG_TEST_IMG" | _filter_qemu_io
28
fi
29
30
-_check_test_img 2>&1 | grep -v "refcount=1 reference=0"
31
+_check_test_img_ignore_leaks 2>&1 | grep -v "refcount=1 reference=0"
32
33
done
34
done
35
@@ -XXX,XX +XXX,XX @@ echo
36
echo "Event: $event; errno: $errno; imm: $imm; once: $once; write $vmstate"
37
$QEMU_IO -c "write $vmstate 0 64M" "$BLKDBG_TEST_IMG" | _filter_qemu_io
38
39
-_check_test_img 2>&1 | grep -v "refcount=1 reference=0"
40
+_check_test_img_ignore_leaks 2>&1 | grep -v "refcount=1 reference=0"
41
42
done
43
done
44
@@ -XXX,XX +XXX,XX @@ echo
45
echo "Event: $event; errno: $errno; imm: $imm; once: $once"
46
$QEMU_IO -c "write -b 0 64k" "$BLKDBG_TEST_IMG" | _filter_qemu_io
47
48
-_check_test_img 2>&1 | grep -v "refcount=1 reference=0"
49
+_check_test_img_ignore_leaks 2>&1 | grep -v "refcount=1 reference=0"
50
51
done
52
done
53
diff --git a/tests/qemu-iotests/026.out b/tests/qemu-iotests/026.out
54
index XXXXXXX..XXXXXXX 100644
55
--- a/tests/qemu-iotests/026.out
56
+++ b/tests/qemu-iotests/026.out
57
@@ -XXX,XX +XXX,XX @@ Event: l1_update; errno: 5; imm: off; once: off; write
58
qemu-io: Failed to flush the L2 table cache: Input/output error
59
qemu-io: Failed to flush the refcount block cache: Input/output error
60
write failed: Input/output error
61
-
62
-1 leaked clusters were found on the image.
63
-This means waste of disk space, but no harm to data.
64
+No errors were found on the image.
65
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
66
67
Event: l1_update; errno: 5; imm: off; once: off; write -b
68
qemu-io: Failed to flush the L2 table cache: Input/output error
69
qemu-io: Failed to flush the refcount block cache: Input/output error
70
write failed: Input/output error
71
-
72
-1 leaked clusters were found on the image.
73
-This means waste of disk space, but no harm to data.
74
+No errors were found on the image.
75
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
76
77
Event: l1_update; errno: 28; imm: off; once: on; write
78
@@ -XXX,XX +XXX,XX @@ Event: l1_update; errno: 28; imm: off; once: off; write
79
qemu-io: Failed to flush the L2 table cache: No space left on device
80
qemu-io: Failed to flush the refcount block cache: No space left on device
81
write failed: No space left on device
82
-
83
-1 leaked clusters were found on the image.
84
-This means waste of disk space, but no harm to data.
85
+No errors were found on the image.
86
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
87
88
Event: l1_update; errno: 28; imm: off; once: off; write -b
89
qemu-io: Failed to flush the L2 table cache: No space left on device
90
qemu-io: Failed to flush the refcount block cache: No space left on device
91
write failed: No space left on device
92
-
93
-1 leaked clusters were found on the image.
94
-This means waste of disk space, but no harm to data.
95
+No errors were found on the image.
96
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
97
98
Event: l2_load; errno: 5; imm: off; once: on; write
99
@@ -XXX,XX +XXX,XX @@ Event: l2_update; errno: 5; imm: off; once: off; write
100
qemu-io: Failed to flush the L2 table cache: Input/output error
101
qemu-io: Failed to flush the refcount block cache: Input/output error
102
write failed: Input/output error
103
-
104
-127 leaked clusters were found on the image.
105
-This means waste of disk space, but no harm to data.
106
+No errors were found on the image.
107
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
108
109
Event: l2_update; errno: 5; imm: off; once: off; write -b
110
qemu-io: Failed to flush the L2 table cache: Input/output error
111
qemu-io: Failed to flush the refcount block cache: Input/output error
112
write failed: Input/output error
113
-
114
-127 leaked clusters were found on the image.
115
-This means waste of disk space, but no harm to data.
116
+No errors were found on the image.
117
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
118
119
Event: l2_update; errno: 28; imm: off; once: on; write
120
@@ -XXX,XX +XXX,XX @@ Event: l2_update; errno: 28; imm: off; once: off; write
121
qemu-io: Failed to flush the L2 table cache: No space left on device
122
qemu-io: Failed to flush the refcount block cache: No space left on device
123
write failed: No space left on device
124
-
125
-127 leaked clusters were found on the image.
126
-This means waste of disk space, but no harm to data.
127
+No errors were found on the image.
128
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
129
130
Event: l2_update; errno: 28; imm: off; once: off; write -b
131
qemu-io: Failed to flush the L2 table cache: No space left on device
132
qemu-io: Failed to flush the refcount block cache: No space left on device
133
write failed: No space left on device
134
-
135
-127 leaked clusters were found on the image.
136
-This means waste of disk space, but no harm to data.
137
+No errors were found on the image.
138
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
139
140
Event: l2_alloc_write; errno: 5; imm: off; once: on; write
141
@@ -XXX,XX +XXX,XX @@ Event: l2_alloc_write; errno: 5; imm: off; once: off; write -b
142
qemu-io: Failed to flush the L2 table cache: Input/output error
143
qemu-io: Failed to flush the refcount block cache: Input/output error
144
write failed: Input/output error
145
-
146
-1 leaked clusters were found on the image.
147
-This means waste of disk space, but no harm to data.
148
+No errors were found on the image.
149
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
150
151
Event: l2_alloc_write; errno: 28; imm: off; once: on; write
152
@@ -XXX,XX +XXX,XX @@ Event: l2_alloc_write; errno: 28; imm: off; once: off; write -b
153
qemu-io: Failed to flush the L2 table cache: No space left on device
154
qemu-io: Failed to flush the refcount block cache: No space left on device
155
write failed: No space left on device
156
-
157
-1 leaked clusters were found on the image.
158
-This means waste of disk space, but no harm to data.
159
+No errors were found on the image.
160
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
161
162
Event: write_aio; errno: 5; imm: off; once: on; write
163
@@ -XXX,XX +XXX,XX @@ Event: refblock_alloc_hookup; errno: 28; imm: off; once: off; write
164
qemu-io: Failed to flush the L2 table cache: No space left on device
165
qemu-io: Failed to flush the refcount block cache: No space left on device
166
write failed: No space left on device
167
-
168
-55 leaked clusters were found on the image.
169
-This means waste of disk space, but no harm to data.
170
+No errors were found on the image.
171
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
172
173
Event: refblock_alloc_hookup; errno: 28; imm: off; once: off; write -b
174
qemu-io: Failed to flush the L2 table cache: No space left on device
175
qemu-io: Failed to flush the refcount block cache: No space left on device
176
write failed: No space left on device
177
-
178
-251 leaked clusters were found on the image.
179
-This means waste of disk space, but no harm to data.
180
+No errors were found on the image.
181
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
182
183
Event: refblock_alloc_write; errno: 28; imm: off; once: on; write
184
@@ -XXX,XX +XXX,XX @@ Event: refblock_alloc_write_blocks; errno: 28; imm: off; once: off; write
185
qemu-io: Failed to flush the L2 table cache: No space left on device
186
qemu-io: Failed to flush the refcount block cache: No space left on device
187
write failed: No space left on device
188
-
189
-10 leaked clusters were found on the image.
190
-This means waste of disk space, but no harm to data.
191
+No errors were found on the image.
192
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
193
194
Event: refblock_alloc_write_blocks; errno: 28; imm: off; once: off; write -b
195
qemu-io: Failed to flush the L2 table cache: No space left on device
196
qemu-io: Failed to flush the refcount block cache: No space left on device
197
write failed: No space left on device
198
-
199
-23 leaked clusters were found on the image.
200
-This means waste of disk space, but no harm to data.
201
+No errors were found on the image.
202
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
203
204
Event: refblock_alloc_write_table; errno: 28; imm: off; once: on; write
205
@@ -XXX,XX +XXX,XX @@ Event: refblock_alloc_write_table; errno: 28; imm: off; once: off; write
206
qemu-io: Failed to flush the L2 table cache: No space left on device
207
qemu-io: Failed to flush the refcount block cache: No space left on device
208
write failed: No space left on device
209
-
210
-10 leaked clusters were found on the image.
211
-This means waste of disk space, but no harm to data.
212
+No errors were found on the image.
213
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
214
215
Event: refblock_alloc_write_table; errno: 28; imm: off; once: off; write -b
216
qemu-io: Failed to flush the L2 table cache: No space left on device
217
qemu-io: Failed to flush the refcount block cache: No space left on device
218
write failed: No space left on device
219
-
220
-23 leaked clusters were found on the image.
221
-This means waste of disk space, but no harm to data.
222
+No errors were found on the image.
223
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
224
225
Event: refblock_alloc_switch_table; errno: 28; imm: off; once: on; write
226
@@ -XXX,XX +XXX,XX @@ Event: refblock_alloc_switch_table; errno: 28; imm: off; once: off; write
227
qemu-io: Failed to flush the L2 table cache: No space left on device
228
qemu-io: Failed to flush the refcount block cache: No space left on device
229
write failed: No space left on device
230
-
231
-10 leaked clusters were found on the image.
232
-This means waste of disk space, but no harm to data.
233
+No errors were found on the image.
234
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
235
236
Event: refblock_alloc_switch_table; errno: 28; imm: off; once: off; write -b
237
qemu-io: Failed to flush the L2 table cache: No space left on device
238
qemu-io: Failed to flush the refcount block cache: No space left on device
239
write failed: No space left on device
240
-
241
-23 leaked clusters were found on the image.
242
-This means waste of disk space, but no harm to data.
243
+No errors were found on the image.
244
245
=== L1 growth tests ===
246
247
@@ -XXX,XX +XXX,XX @@ Event: l1_grow_activate_table; errno: 5; imm: off; once: off
248
qemu-io: Failed to flush the L2 table cache: Input/output error
249
qemu-io: Failed to flush the refcount block cache: Input/output error
250
write failed: Input/output error
251
-
252
-96 leaked clusters were found on the image.
253
-This means waste of disk space, but no harm to data.
254
+No errors were found on the image.
255
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
256
257
Event: l1_grow_activate_table; errno: 28; imm: off; once: on
258
@@ -XXX,XX +XXX,XX @@ Event: l1_grow_activate_table; errno: 28; imm: off; once: off
259
qemu-io: Failed to flush the L2 table cache: No space left on device
260
qemu-io: Failed to flush the refcount block cache: No space left on device
261
write failed: No space left on device
262
-
263
-96 leaked clusters were found on the image.
264
-This means waste of disk space, but no harm to data.
265
+No errors were found on the image.
266
267
=== Avoid cluster leaks after temporary failure ===
268
269
diff --git a/tests/qemu-iotests/026.out.nocache b/tests/qemu-iotests/026.out.nocache
270
index XXXXXXX..XXXXXXX 100644
271
--- a/tests/qemu-iotests/026.out.nocache
272
+++ b/tests/qemu-iotests/026.out.nocache
273
@@ -XXX,XX +XXX,XX @@ Event: l1_update; errno: 5; imm: off; once: off; write
274
qemu-io: Failed to flush the L2 table cache: Input/output error
275
qemu-io: Failed to flush the refcount block cache: Input/output error
276
write failed: Input/output error
277
-
278
-1 leaked clusters were found on the image.
279
-This means waste of disk space, but no harm to data.
280
+No errors were found on the image.
281
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
282
283
Event: l1_update; errno: 5; imm: off; once: off; write -b
284
qemu-io: Failed to flush the L2 table cache: Input/output error
285
qemu-io: Failed to flush the refcount block cache: Input/output error
286
write failed: Input/output error
287
-
288
-1 leaked clusters were found on the image.
289
-This means waste of disk space, but no harm to data.
290
+No errors were found on the image.
291
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
292
293
Event: l1_update; errno: 28; imm: off; once: on; write
294
@@ -XXX,XX +XXX,XX @@ Event: l1_update; errno: 28; imm: off; once: off; write
295
qemu-io: Failed to flush the L2 table cache: No space left on device
296
qemu-io: Failed to flush the refcount block cache: No space left on device
297
write failed: No space left on device
298
-
299
-1 leaked clusters were found on the image.
300
-This means waste of disk space, but no harm to data.
301
+No errors were found on the image.
302
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
303
304
Event: l1_update; errno: 28; imm: off; once: off; write -b
305
qemu-io: Failed to flush the L2 table cache: No space left on device
306
qemu-io: Failed to flush the refcount block cache: No space left on device
307
write failed: No space left on device
308
-
309
-1 leaked clusters were found on the image.
310
-This means waste of disk space, but no harm to data.
311
+No errors were found on the image.
312
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
313
314
Event: l2_load; errno: 5; imm: off; once: on; write
315
@@ -XXX,XX +XXX,XX @@ qemu-io: Failed to flush the L2 table cache: Input/output error
316
qemu-io: Failed to flush the refcount block cache: Input/output error
317
wrote 131072/131072 bytes at offset 0
318
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
319
-
320
-127 leaked clusters were found on the image.
321
-This means waste of disk space, but no harm to data.
322
+No errors were found on the image.
323
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
324
325
Event: l2_update; errno: 5; imm: off; once: off; write -b
326
@@ -XXX,XX +XXX,XX @@ qemu-io: Failed to flush the L2 table cache: Input/output error
327
qemu-io: Failed to flush the refcount block cache: Input/output error
328
wrote 131072/131072 bytes at offset 0
329
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
330
-
331
-127 leaked clusters were found on the image.
332
-This means waste of disk space, but no harm to data.
333
+No errors were found on the image.
334
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
335
336
Event: l2_update; errno: 28; imm: off; once: on; write
337
@@ -XXX,XX +XXX,XX @@ qemu-io: Failed to flush the L2 table cache: No space left on device
338
qemu-io: Failed to flush the refcount block cache: No space left on device
339
wrote 131072/131072 bytes at offset 0
340
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
341
-
342
-127 leaked clusters were found on the image.
343
-This means waste of disk space, but no harm to data.
344
+No errors were found on the image.
345
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
346
347
Event: l2_update; errno: 28; imm: off; once: off; write -b
348
@@ -XXX,XX +XXX,XX @@ qemu-io: Failed to flush the L2 table cache: No space left on device
349
qemu-io: Failed to flush the refcount block cache: No space left on device
350
wrote 131072/131072 bytes at offset 0
351
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
352
-
353
-127 leaked clusters were found on the image.
354
-This means waste of disk space, but no harm to data.
355
+No errors were found on the image.
356
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
357
358
Event: l2_alloc_write; errno: 5; imm: off; once: on; write
359
@@ -XXX,XX +XXX,XX @@ Event: l2_alloc_write; errno: 5; imm: off; once: off; write -b
360
qemu-io: Failed to flush the L2 table cache: Input/output error
361
qemu-io: Failed to flush the refcount block cache: Input/output error
362
write failed: Input/output error
363
-
364
-1 leaked clusters were found on the image.
365
-This means waste of disk space, but no harm to data.
366
+No errors were found on the image.
367
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
368
369
Event: l2_alloc_write; errno: 28; imm: off; once: on; write
370
@@ -XXX,XX +XXX,XX @@ Event: l2_alloc_write; errno: 28; imm: off; once: off; write -b
371
qemu-io: Failed to flush the L2 table cache: No space left on device
372
qemu-io: Failed to flush the refcount block cache: No space left on device
373
write failed: No space left on device
374
-
375
-1 leaked clusters were found on the image.
376
-This means waste of disk space, but no harm to data.
377
+No errors were found on the image.
378
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
379
380
Event: write_aio; errno: 5; imm: off; once: on; write
381
@@ -XXX,XX +XXX,XX @@ Event: refblock_alloc_hookup; errno: 28; imm: off; once: off; write
382
qemu-io: Failed to flush the L2 table cache: No space left on device
383
qemu-io: Failed to flush the refcount block cache: No space left on device
384
write failed: No space left on device
385
-
386
-55 leaked clusters were found on the image.
387
-This means waste of disk space, but no harm to data.
388
+No errors were found on the image.
389
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
390
391
Event: refblock_alloc_hookup; errno: 28; imm: off; once: off; write -b
392
qemu-io: Failed to flush the L2 table cache: No space left on device
393
qemu-io: Failed to flush the refcount block cache: No space left on device
394
write failed: No space left on device
395
-
396
-251 leaked clusters were found on the image.
397
-This means waste of disk space, but no harm to data.
398
+No errors were found on the image.
399
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
400
401
Event: refblock_alloc_write; errno: 28; imm: off; once: on; write
402
@@ -XXX,XX +XXX,XX @@ Event: refblock_alloc_write_blocks; errno: 28; imm: off; once: off; write
403
qemu-io: Failed to flush the L2 table cache: No space left on device
404
qemu-io: Failed to flush the refcount block cache: No space left on device
405
write failed: No space left on device
406
-
407
-10 leaked clusters were found on the image.
408
-This means waste of disk space, but no harm to data.
409
+No errors were found on the image.
410
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
411
412
Event: refblock_alloc_write_blocks; errno: 28; imm: off; once: off; write -b
413
qemu-io: Failed to flush the L2 table cache: No space left on device
414
qemu-io: Failed to flush the refcount block cache: No space left on device
415
write failed: No space left on device
416
-
417
-23 leaked clusters were found on the image.
418
-This means waste of disk space, but no harm to data.
419
+No errors were found on the image.
420
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
421
422
Event: refblock_alloc_write_table; errno: 28; imm: off; once: on; write
423
@@ -XXX,XX +XXX,XX @@ Event: refblock_alloc_write_table; errno: 28; imm: off; once: off; write
424
qemu-io: Failed to flush the L2 table cache: No space left on device
425
qemu-io: Failed to flush the refcount block cache: No space left on device
426
write failed: No space left on device
427
-
428
-10 leaked clusters were found on the image.
429
-This means waste of disk space, but no harm to data.
430
+No errors were found on the image.
431
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
432
433
Event: refblock_alloc_write_table; errno: 28; imm: off; once: off; write -b
434
qemu-io: Failed to flush the L2 table cache: No space left on device
435
qemu-io: Failed to flush the refcount block cache: No space left on device
436
write failed: No space left on device
437
-
438
-23 leaked clusters were found on the image.
439
-This means waste of disk space, but no harm to data.
440
+No errors were found on the image.
441
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
442
443
Event: refblock_alloc_switch_table; errno: 28; imm: off; once: on; write
444
@@ -XXX,XX +XXX,XX @@ Event: refblock_alloc_switch_table; errno: 28; imm: off; once: off; write
445
qemu-io: Failed to flush the L2 table cache: No space left on device
446
qemu-io: Failed to flush the refcount block cache: No space left on device
447
write failed: No space left on device
448
-
449
-10 leaked clusters were found on the image.
450
-This means waste of disk space, but no harm to data.
451
+No errors were found on the image.
452
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
453
454
Event: refblock_alloc_switch_table; errno: 28; imm: off; once: off; write -b
455
qemu-io: Failed to flush the L2 table cache: No space left on device
456
qemu-io: Failed to flush the refcount block cache: No space left on device
457
write failed: No space left on device
458
-
459
-23 leaked clusters were found on the image.
460
-This means waste of disk space, but no harm to data.
461
+No errors were found on the image.
462
463
=== L1 growth tests ===
464
465
@@ -XXX,XX +XXX,XX @@ Event: l1_grow_activate_table; errno: 5; imm: off; once: off
466
qemu-io: Failed to flush the L2 table cache: Input/output error
467
qemu-io: Failed to flush the refcount block cache: Input/output error
468
write failed: Input/output error
469
-
470
-96 leaked clusters were found on the image.
471
-This means waste of disk space, but no harm to data.
472
+No errors were found on the image.
473
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
474
475
Event: l1_grow_activate_table; errno: 28; imm: off; once: on
476
@@ -XXX,XX +XXX,XX @@ Event: l1_grow_activate_table; errno: 28; imm: off; once: off
477
qemu-io: Failed to flush the L2 table cache: No space left on device
478
qemu-io: Failed to flush the refcount block cache: No space left on device
479
write failed: No space left on device
480
-
481
-96 leaked clusters were found on the image.
482
-This means waste of disk space, but no harm to data.
483
+No errors were found on the image.
484
485
=== Avoid cluster leaks after temporary failure ===
486
487
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
488
index XXXXXXX..XXXXXXX 100644
489
--- a/tests/qemu-iotests/common.rc
490
+++ b/tests/qemu-iotests/common.rc
491
@@ -XXX,XX +XXX,XX @@ _check_test_img()
492
$QEMU_IMG check "$@" -f $IMGFMT "$TEST_IMG" 2>&1
493
fi
494
) | _filter_testdir | _filter_qemu_img_check
495
+
496
+ # return real qemu_img check status, to analyze in
497
+ # _check_test_img_ignore_leaks
498
+ return ${PIPESTATUS[0]}
499
+}
500
+
501
+_check_test_img_ignore_leaks()
502
+{
503
+ out=$(_check_test_img "$@")
504
+ status=$?
505
+ if [ $status = 3 ]; then
506
+ # This must correspond to success output in dump_human_image_check()
507
+ echo "No errors were found on the image."
508
+ return 0
509
+ fi
510
+ echo "$out"
511
+ return $status
512
}
513
514
_img_info()
515
--
516
2.21.0
517
518
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Common interface for aio task loops. To be used for improving
4
performance of synchronous io loops in qcow2, block-stream,
5
copy-on-read, and may be other places.
6
7
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
Message-id: 20190916175324.18478-3-vsementsov@virtuozzo.com
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
---
12
block/Makefile.objs | 2 +
13
include/block/aio_task.h | 54 +++++++++++++++++
14
block/aio_task.c | 124 +++++++++++++++++++++++++++++++++++++++
15
3 files changed, 180 insertions(+)
16
create mode 100644 include/block/aio_task.h
17
create mode 100644 block/aio_task.c
18
19
diff --git a/block/Makefile.objs b/block/Makefile.objs
20
index XXXXXXX..XXXXXXX 100644
21
--- a/block/Makefile.objs
22
+++ b/block/Makefile.objs
23
@@ -XXX,XX +XXX,XX @@ block-obj-y += throttle.o copy-on-read.o
24
25
block-obj-y += crypto.o
26
27
+block-obj-y += aio_task.o
28
+
29
common-obj-y += stream.o
30
31
nfs.o-libs := $(LIBNFS_LIBS)
32
diff --git a/include/block/aio_task.h b/include/block/aio_task.h
33
new file mode 100644
34
index XXXXXXX..XXXXXXX
35
--- /dev/null
36
+++ b/include/block/aio_task.h
37
@@ -XXX,XX +XXX,XX @@
38
+/*
39
+ * Aio tasks loops
40
+ *
41
+ * Copyright (c) 2019 Virtuozzo International GmbH.
42
+ *
43
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
44
+ * of this software and associated documentation files (the "Software"), to deal
45
+ * in the Software without restriction, including without limitation the rights
46
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
47
+ * copies of the Software, and to permit persons to whom the Software is
48
+ * furnished to do so, subject to the following conditions:
49
+ *
50
+ * The above copyright notice and this permission notice shall be included in
51
+ * all copies or substantial portions of the Software.
52
+ *
53
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
54
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
55
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
56
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
57
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
58
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
59
+ * THE SOFTWARE.
60
+ */
61
+
62
+#ifndef BLOCK_AIO_TASK_H
63
+#define BLOCK_AIO_TASK_H
64
+
65
+#include "qemu/coroutine.h"
66
+
67
+typedef struct AioTaskPool AioTaskPool;
68
+typedef struct AioTask AioTask;
69
+typedef int coroutine_fn (*AioTaskFunc)(AioTask *task);
70
+struct AioTask {
71
+ AioTaskPool *pool;
72
+ AioTaskFunc func;
73
+ int ret;
74
+};
75
+
76
+AioTaskPool *coroutine_fn aio_task_pool_new(int max_busy_tasks);
77
+void aio_task_pool_free(AioTaskPool *);
78
+
79
+/* error code of failed task or 0 if all is OK */
80
+int aio_task_pool_status(AioTaskPool *pool);
81
+
82
+bool aio_task_pool_empty(AioTaskPool *pool);
83
+
84
+/* User provides filled @task, however task->pool will be set automatically */
85
+void coroutine_fn aio_task_pool_start_task(AioTaskPool *pool, AioTask *task);
86
+
87
+void coroutine_fn aio_task_pool_wait_slot(AioTaskPool *pool);
88
+void coroutine_fn aio_task_pool_wait_one(AioTaskPool *pool);
89
+void coroutine_fn aio_task_pool_wait_all(AioTaskPool *pool);
90
+
91
+#endif /* BLOCK_AIO_TASK_H */
92
diff --git a/block/aio_task.c b/block/aio_task.c
93
new file mode 100644
94
index XXXXXXX..XXXXXXX
95
--- /dev/null
96
+++ b/block/aio_task.c
97
@@ -XXX,XX +XXX,XX @@
98
+/*
99
+ * Aio tasks loops
100
+ *
101
+ * Copyright (c) 2019 Virtuozzo International GmbH.
102
+ *
103
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
104
+ * of this software and associated documentation files (the "Software"), to deal
105
+ * in the Software without restriction, including without limitation the rights
106
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
107
+ * copies of the Software, and to permit persons to whom the Software is
108
+ * furnished to do so, subject to the following conditions:
109
+ *
110
+ * The above copyright notice and this permission notice shall be included in
111
+ * all copies or substantial portions of the Software.
112
+ *
113
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
114
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
115
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
116
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
117
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
118
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
119
+ * THE SOFTWARE.
120
+ */
121
+
122
+#include "qemu/osdep.h"
123
+#include "block/aio.h"
124
+#include "block/aio_task.h"
125
+
126
+struct AioTaskPool {
127
+ Coroutine *main_co;
128
+ int status;
129
+ int max_busy_tasks;
130
+ int busy_tasks;
131
+ bool waiting;
132
+};
133
+
134
+static void coroutine_fn aio_task_co(void *opaque)
135
+{
136
+ AioTask *task = opaque;
137
+ AioTaskPool *pool = task->pool;
138
+
139
+ assert(pool->busy_tasks < pool->max_busy_tasks);
140
+ pool->busy_tasks++;
141
+
142
+ task->ret = task->func(task);
143
+
144
+ pool->busy_tasks--;
145
+
146
+ if (task->ret < 0 && pool->status == 0) {
147
+ pool->status = task->ret;
148
+ }
149
+
150
+ g_free(task);
151
+
152
+ if (pool->waiting) {
153
+ pool->waiting = false;
154
+ aio_co_wake(pool->main_co);
155
+ }
156
+}
157
+
158
+void coroutine_fn aio_task_pool_wait_one(AioTaskPool *pool)
159
+{
160
+ assert(pool->busy_tasks > 0);
161
+ assert(qemu_coroutine_self() == pool->main_co);
162
+
163
+ pool->waiting = true;
164
+ qemu_coroutine_yield();
165
+
166
+ assert(!pool->waiting);
167
+ assert(pool->busy_tasks < pool->max_busy_tasks);
168
+}
169
+
170
+void coroutine_fn aio_task_pool_wait_slot(AioTaskPool *pool)
171
+{
172
+ if (pool->busy_tasks < pool->max_busy_tasks) {
173
+ return;
174
+ }
175
+
176
+ aio_task_pool_wait_one(pool);
177
+}
178
+
179
+void coroutine_fn aio_task_pool_wait_all(AioTaskPool *pool)
180
+{
181
+ while (pool->busy_tasks > 0) {
182
+ aio_task_pool_wait_one(pool);
183
+ }
184
+}
185
+
186
+void coroutine_fn aio_task_pool_start_task(AioTaskPool *pool, AioTask *task)
187
+{
188
+ aio_task_pool_wait_slot(pool);
189
+
190
+ task->pool = pool;
191
+ qemu_coroutine_enter(qemu_coroutine_create(aio_task_co, task));
192
+}
193
+
194
+AioTaskPool *coroutine_fn aio_task_pool_new(int max_busy_tasks)
195
+{
196
+ AioTaskPool *pool = g_new0(AioTaskPool, 1);
197
+
198
+ pool->main_co = qemu_coroutine_self();
199
+ pool->max_busy_tasks = max_busy_tasks;
200
+
201
+ return pool;
202
+}
203
+
204
+void aio_task_pool_free(AioTaskPool *pool)
205
+{
206
+ g_free(pool);
207
+}
208
+
209
+int aio_task_pool_status(AioTaskPool *pool)
210
+{
211
+ if (!pool) {
212
+ return 0; /* Sugar for lazy allocation of aio pool */
213
+ }
214
+
215
+ return pool->status;
216
+}
217
+
218
+bool aio_task_pool_empty(AioTaskPool *pool)
219
+{
220
+ return pool->busy_tasks == 0;
221
+}
222
--
223
2.21.0
224
225
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Further patch will run partial requests of iterations of
4
qcow2_co_preadv in parallel for performance reasons. To prepare for
5
this, separate part which may be parallelized into separate function
6
(qcow2_co_preadv_task).
7
8
While being here, also separate encrypted clusters reading to own
9
function, like it is done for compressed reading.
10
11
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
12
Reviewed-by: Max Reitz <mreitz@redhat.com>
13
Message-id: 20190916175324.18478-4-vsementsov@virtuozzo.com
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
15
---
16
block/qcow2.c | 209 +++++++++++++++++++++++++++-----------------------
17
1 file changed, 113 insertions(+), 96 deletions(-)
18
19
diff --git a/block/qcow2.c b/block/qcow2.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/block/qcow2.c
22
+++ b/block/qcow2.c
23
@@ -XXX,XX +XXX,XX @@ out:
24
return ret;
25
}
26
27
+static coroutine_fn int
28
+qcow2_co_preadv_encrypted(BlockDriverState *bs,
29
+ uint64_t file_cluster_offset,
30
+ uint64_t offset,
31
+ uint64_t bytes,
32
+ QEMUIOVector *qiov,
33
+ uint64_t qiov_offset)
34
+{
35
+ int ret;
36
+ BDRVQcow2State *s = bs->opaque;
37
+ uint8_t *buf;
38
+
39
+ assert(bs->encrypted && s->crypto);
40
+ assert(bytes <= QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
41
+
42
+ /*
43
+ * For encrypted images, read everything into a temporary
44
+ * contiguous buffer on which the AES functions can work.
45
+ * Also, decryption in a separate buffer is better as it
46
+ * prevents the guest from learning information about the
47
+ * encrypted nature of the virtual disk.
48
+ */
49
+
50
+ buf = qemu_try_blockalign(s->data_file->bs, bytes);
51
+ if (buf == NULL) {
52
+ return -ENOMEM;
53
+ }
54
+
55
+ BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
56
+ ret = bdrv_co_pread(s->data_file,
57
+ file_cluster_offset + offset_into_cluster(s, offset),
58
+ bytes, buf, 0);
59
+ if (ret < 0) {
60
+ goto fail;
61
+ }
62
+
63
+ assert(QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE));
64
+ assert(QEMU_IS_ALIGNED(bytes, BDRV_SECTOR_SIZE));
65
+ if (qcow2_co_decrypt(bs,
66
+ file_cluster_offset + offset_into_cluster(s, offset),
67
+ offset, buf, bytes) < 0)
68
+ {
69
+ ret = -EIO;
70
+ goto fail;
71
+ }
72
+ qemu_iovec_from_buf(qiov, qiov_offset, buf, bytes);
73
+
74
+fail:
75
+ qemu_vfree(buf);
76
+
77
+ return ret;
78
+}
79
+
80
+static coroutine_fn int qcow2_co_preadv_task(BlockDriverState *bs,
81
+ QCow2ClusterType cluster_type,
82
+ uint64_t file_cluster_offset,
83
+ uint64_t offset, uint64_t bytes,
84
+ QEMUIOVector *qiov,
85
+ size_t qiov_offset)
86
+{
87
+ BDRVQcow2State *s = bs->opaque;
88
+ int offset_in_cluster = offset_into_cluster(s, offset);
89
+
90
+ switch (cluster_type) {
91
+ case QCOW2_CLUSTER_ZERO_PLAIN:
92
+ case QCOW2_CLUSTER_ZERO_ALLOC:
93
+ /* Both zero types are handled in qcow2_co_preadv_part */
94
+ g_assert_not_reached();
95
+
96
+ case QCOW2_CLUSTER_UNALLOCATED:
97
+ assert(bs->backing); /* otherwise handled in qcow2_co_preadv_part */
98
+
99
+ BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
100
+ return bdrv_co_preadv_part(bs->backing, offset, bytes,
101
+ qiov, qiov_offset, 0);
102
+
103
+ case QCOW2_CLUSTER_COMPRESSED:
104
+ return qcow2_co_preadv_compressed(bs, file_cluster_offset,
105
+ offset, bytes, qiov, qiov_offset);
106
+
107
+ case QCOW2_CLUSTER_NORMAL:
108
+ if ((file_cluster_offset & 511) != 0) {
109
+ return -EIO;
110
+ }
111
+
112
+ if (bs->encrypted) {
113
+ return qcow2_co_preadv_encrypted(bs, file_cluster_offset,
114
+ offset, bytes, qiov, qiov_offset);
115
+ }
116
+
117
+ BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
118
+ return bdrv_co_preadv_part(s->data_file,
119
+ file_cluster_offset + offset_in_cluster,
120
+ bytes, qiov, qiov_offset, 0);
121
+
122
+ default:
123
+ g_assert_not_reached();
124
+ }
125
+
126
+ g_assert_not_reached();
127
+}
128
+
129
static coroutine_fn int qcow2_co_preadv_part(BlockDriverState *bs,
130
uint64_t offset, uint64_t bytes,
131
QEMUIOVector *qiov,
132
size_t qiov_offset, int flags)
133
{
134
BDRVQcow2State *s = bs->opaque;
135
- int offset_in_cluster;
136
int ret;
137
unsigned int cur_bytes; /* number of bytes in current iteration */
138
uint64_t cluster_offset = 0;
139
- uint8_t *cluster_data = NULL;
140
141
while (bytes != 0) {
142
143
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_preadv_part(BlockDriverState *bs,
144
ret = qcow2_get_cluster_offset(bs, offset, &cur_bytes, &cluster_offset);
145
qemu_co_mutex_unlock(&s->lock);
146
if (ret < 0) {
147
- goto fail;
148
+ return ret;
149
}
150
151
- offset_in_cluster = offset_into_cluster(s, offset);
152
-
153
- switch (ret) {
154
- case QCOW2_CLUSTER_UNALLOCATED:
155
-
156
- if (bs->backing) {
157
- BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
158
- ret = bdrv_co_preadv_part(bs->backing, offset, cur_bytes,
159
- qiov, qiov_offset, 0);
160
- if (ret < 0) {
161
- goto fail;
162
- }
163
- } else {
164
- /* Note: in this case, no need to wait */
165
- qemu_iovec_memset(qiov, qiov_offset, 0, cur_bytes);
166
- }
167
- break;
168
-
169
- case QCOW2_CLUSTER_ZERO_PLAIN:
170
- case QCOW2_CLUSTER_ZERO_ALLOC:
171
+ if (ret == QCOW2_CLUSTER_ZERO_PLAIN ||
172
+ ret == QCOW2_CLUSTER_ZERO_ALLOC ||
173
+ (ret == QCOW2_CLUSTER_UNALLOCATED && !bs->backing))
174
+ {
175
qemu_iovec_memset(qiov, qiov_offset, 0, cur_bytes);
176
- break;
177
-
178
- case QCOW2_CLUSTER_COMPRESSED:
179
- ret = qcow2_co_preadv_compressed(bs, cluster_offset,
180
- offset, cur_bytes,
181
- qiov, qiov_offset);
182
+ } else {
183
+ ret = qcow2_co_preadv_task(bs, ret,
184
+ cluster_offset, offset, cur_bytes,
185
+ qiov, qiov_offset);
186
if (ret < 0) {
187
- goto fail;
188
- }
189
-
190
- break;
191
-
192
- case QCOW2_CLUSTER_NORMAL:
193
- if ((cluster_offset & 511) != 0) {
194
- ret = -EIO;
195
- goto fail;
196
- }
197
-
198
- if (bs->encrypted) {
199
- assert(s->crypto);
200
-
201
- /*
202
- * For encrypted images, read everything into a temporary
203
- * contiguous buffer on which the AES functions can work.
204
- */
205
- if (!cluster_data) {
206
- cluster_data =
207
- qemu_try_blockalign(s->data_file->bs,
208
- QCOW_MAX_CRYPT_CLUSTERS
209
- * s->cluster_size);
210
- if (cluster_data == NULL) {
211
- ret = -ENOMEM;
212
- goto fail;
213
- }
214
- }
215
-
216
- assert(cur_bytes <= QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
217
-
218
- BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
219
- ret = bdrv_co_pread(s->data_file,
220
- cluster_offset + offset_in_cluster,
221
- cur_bytes, cluster_data, 0);
222
- if (ret < 0) {
223
- goto fail;
224
- }
225
-
226
- assert(QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE));
227
- assert(QEMU_IS_ALIGNED(cur_bytes, BDRV_SECTOR_SIZE));
228
- if (qcow2_co_decrypt(bs, cluster_offset + offset_in_cluster,
229
- offset,
230
- cluster_data, cur_bytes) < 0) {
231
- ret = -EIO;
232
- goto fail;
233
- }
234
- qemu_iovec_from_buf(qiov, qiov_offset, cluster_data, cur_bytes);
235
- } else {
236
- BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
237
- ret = bdrv_co_preadv_part(s->data_file,
238
- cluster_offset + offset_in_cluster,
239
- cur_bytes, qiov, qiov_offset, 0);
240
- if (ret < 0) {
241
- goto fail;
242
- }
243
+ return ret;
244
}
245
- break;
246
-
247
- default:
248
- g_assert_not_reached();
249
- ret = -EIO;
250
- goto fail;
251
}
252
253
bytes -= cur_bytes;
254
offset += cur_bytes;
255
qiov_offset += cur_bytes;
256
}
257
- ret = 0;
258
-
259
-fail:
260
- qemu_vfree(cluster_data);
261
262
- return ret;
263
+ return 0;
264
}
265
266
/* Check if it's possible to merge a write request with the writing of
267
--
268
2.21.0
269
270
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Similarly to previous commit, prepare for parallelizing write-loop
4
iterations.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Max Reitz <mreitz@redhat.com>
8
Message-id: 20190916175324.18478-5-vsementsov@virtuozzo.com
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
---
11
block/qcow2.c | 154 +++++++++++++++++++++++++++++---------------------
12
1 file changed, 90 insertions(+), 64 deletions(-)
13
14
diff --git a/block/qcow2.c b/block/qcow2.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/block/qcow2.c
17
+++ b/block/qcow2.c
18
@@ -XXX,XX +XXX,XX @@ static int handle_alloc_space(BlockDriverState *bs, QCowL2Meta *l2meta)
19
return 0;
20
}
21
22
+/*
23
+ * qcow2_co_pwritev_task
24
+ * Called with s->lock unlocked
25
+ * l2meta - if not NULL, qcow2_co_pwritev_task() will consume it. Caller must
26
+ * not use it somehow after qcow2_co_pwritev_task() call
27
+ */
28
+static coroutine_fn int qcow2_co_pwritev_task(BlockDriverState *bs,
29
+ uint64_t file_cluster_offset,
30
+ uint64_t offset, uint64_t bytes,
31
+ QEMUIOVector *qiov,
32
+ uint64_t qiov_offset,
33
+ QCowL2Meta *l2meta)
34
+{
35
+ int ret;
36
+ BDRVQcow2State *s = bs->opaque;
37
+ void *crypt_buf = NULL;
38
+ int offset_in_cluster = offset_into_cluster(s, offset);
39
+ QEMUIOVector encrypted_qiov;
40
+
41
+ if (bs->encrypted) {
42
+ assert(s->crypto);
43
+ assert(bytes <= QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
44
+ crypt_buf = qemu_try_blockalign(bs->file->bs, bytes);
45
+ if (crypt_buf == NULL) {
46
+ ret = -ENOMEM;
47
+ goto out_unlocked;
48
+ }
49
+ qemu_iovec_to_buf(qiov, qiov_offset, crypt_buf, bytes);
50
+
51
+ if (qcow2_co_encrypt(bs, file_cluster_offset + offset_in_cluster,
52
+ offset, crypt_buf, bytes) < 0)
53
+ {
54
+ ret = -EIO;
55
+ goto out_unlocked;
56
+ }
57
+
58
+ qemu_iovec_init_buf(&encrypted_qiov, crypt_buf, bytes);
59
+ qiov = &encrypted_qiov;
60
+ qiov_offset = 0;
61
+ }
62
+
63
+ /* Try to efficiently initialize the physical space with zeroes */
64
+ ret = handle_alloc_space(bs, l2meta);
65
+ if (ret < 0) {
66
+ goto out_unlocked;
67
+ }
68
+
69
+ /*
70
+ * If we need to do COW, check if it's possible to merge the
71
+ * writing of the guest data together with that of the COW regions.
72
+ * If it's not possible (or not necessary) then write the
73
+ * guest data now.
74
+ */
75
+ if (!merge_cow(offset, bytes, qiov, qiov_offset, l2meta)) {
76
+ BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
77
+ trace_qcow2_writev_data(qemu_coroutine_self(),
78
+ file_cluster_offset + offset_in_cluster);
79
+ ret = bdrv_co_pwritev_part(s->data_file,
80
+ file_cluster_offset + offset_in_cluster,
81
+ bytes, qiov, qiov_offset, 0);
82
+ if (ret < 0) {
83
+ goto out_unlocked;
84
+ }
85
+ }
86
+
87
+ qemu_co_mutex_lock(&s->lock);
88
+
89
+ ret = qcow2_handle_l2meta(bs, &l2meta, true);
90
+ goto out_locked;
91
+
92
+out_unlocked:
93
+ qemu_co_mutex_lock(&s->lock);
94
+
95
+out_locked:
96
+ qcow2_handle_l2meta(bs, &l2meta, false);
97
+ qemu_co_mutex_unlock(&s->lock);
98
+
99
+ qemu_vfree(crypt_buf);
100
+
101
+ return ret;
102
+}
103
+
104
static coroutine_fn int qcow2_co_pwritev_part(
105
BlockDriverState *bs, uint64_t offset, uint64_t bytes,
106
QEMUIOVector *qiov, size_t qiov_offset, int flags)
107
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_pwritev_part(
108
int ret;
109
unsigned int cur_bytes; /* number of sectors in current iteration */
110
uint64_t cluster_offset;
111
- QEMUIOVector encrypted_qiov;
112
- uint64_t bytes_done = 0;
113
- uint8_t *cluster_data = NULL;
114
QCowL2Meta *l2meta = NULL;
115
116
trace_qcow2_writev_start_req(qemu_coroutine_self(), offset, bytes);
117
118
- qemu_co_mutex_lock(&s->lock);
119
-
120
while (bytes != 0) {
121
122
l2meta = NULL;
123
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_pwritev_part(
124
- offset_in_cluster);
125
}
126
127
+ qemu_co_mutex_lock(&s->lock);
128
+
129
ret = qcow2_alloc_cluster_offset(bs, offset, &cur_bytes,
130
&cluster_offset, &l2meta);
131
if (ret < 0) {
132
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_pwritev_part(
133
134
qemu_co_mutex_unlock(&s->lock);
135
136
- if (bs->encrypted) {
137
- assert(s->crypto);
138
- if (!cluster_data) {
139
- cluster_data = qemu_try_blockalign(bs->file->bs,
140
- QCOW_MAX_CRYPT_CLUSTERS
141
- * s->cluster_size);
142
- if (cluster_data == NULL) {
143
- ret = -ENOMEM;
144
- goto out_unlocked;
145
- }
146
- }
147
-
148
- assert(cur_bytes <= QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
149
- qemu_iovec_to_buf(qiov, qiov_offset + bytes_done,
150
- cluster_data, cur_bytes);
151
-
152
- if (qcow2_co_encrypt(bs, cluster_offset + offset_in_cluster, offset,
153
- cluster_data, cur_bytes) < 0) {
154
- ret = -EIO;
155
- goto out_unlocked;
156
- }
157
-
158
- qemu_iovec_init_buf(&encrypted_qiov, cluster_data, cur_bytes);
159
- }
160
-
161
- /* Try to efficiently initialize the physical space with zeroes */
162
- ret = handle_alloc_space(bs, l2meta);
163
+ ret = qcow2_co_pwritev_task(bs, cluster_offset, offset, cur_bytes,
164
+ qiov, qiov_offset, l2meta);
165
+ l2meta = NULL; /* l2meta is consumed by qcow2_co_pwritev_task() */
166
if (ret < 0) {
167
- goto out_unlocked;
168
- }
169
-
170
- /* If we need to do COW, check if it's possible to merge the
171
- * writing of the guest data together with that of the COW regions.
172
- * If it's not possible (or not necessary) then write the
173
- * guest data now. */
174
- if (!merge_cow(offset, cur_bytes,
175
- bs->encrypted ? &encrypted_qiov : qiov,
176
- bs->encrypted ? 0 : qiov_offset + bytes_done, l2meta))
177
- {
178
- BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
179
- trace_qcow2_writev_data(qemu_coroutine_self(),
180
- cluster_offset + offset_in_cluster);
181
- ret = bdrv_co_pwritev_part(
182
- s->data_file, cluster_offset + offset_in_cluster, cur_bytes,
183
- bs->encrypted ? &encrypted_qiov : qiov,
184
- bs->encrypted ? 0 : qiov_offset + bytes_done, 0);
185
- if (ret < 0) {
186
- goto out_unlocked;
187
- }
188
- }
189
-
190
- qemu_co_mutex_lock(&s->lock);
191
-
192
- ret = qcow2_handle_l2meta(bs, &l2meta, true);
193
- if (ret) {
194
- goto out_locked;
195
+ goto fail_nometa;
196
}
197
198
bytes -= cur_bytes;
199
offset += cur_bytes;
200
- bytes_done += cur_bytes;
201
+ qiov_offset += cur_bytes;
202
trace_qcow2_writev_done_part(qemu_coroutine_self(), cur_bytes);
203
}
204
ret = 0;
205
- goto out_locked;
206
207
-out_unlocked:
208
qemu_co_mutex_lock(&s->lock);
209
210
out_locked:
211
@@ -XXX,XX +XXX,XX @@ out_locked:
212
213
qemu_co_mutex_unlock(&s->lock);
214
215
- qemu_vfree(cluster_data);
216
+fail_nometa:
217
trace_qcow2_writev_done_req(qemu_coroutine_self(), ret);
218
219
return ret;
220
--
221
2.21.0
222
223
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
It improves performance for fragmented qcow2 images.
4
5
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
Message-id: 20190916175324.18478-6-vsementsov@virtuozzo.com
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
---
9
block/qcow2.h | 3 ++
10
block/qcow2.c | 125 ++++++++++++++++++++++++++++++++++++++++-----
11
block/trace-events | 1 +
12
3 files changed, 117 insertions(+), 12 deletions(-)
13
14
diff --git a/block/qcow2.h b/block/qcow2.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/block/qcow2.h
17
+++ b/block/qcow2.h
18
@@ -XXX,XX +XXX,XX @@
19
#define QCOW2_MAX_BITMAPS 65535
20
#define QCOW2_MAX_BITMAP_DIRECTORY_SIZE (1024 * QCOW2_MAX_BITMAPS)
21
22
+/* Maximum of parallel sub-request per guest request */
23
+#define QCOW2_MAX_WORKERS 8
24
+
25
/* indicate that the refcount of the referenced cluster is exactly one. */
26
#define QCOW_OFLAG_COPIED (1ULL << 63)
27
/* indicate that the cluster is compressed (they never have the copied flag) */
28
diff --git a/block/qcow2.c b/block/qcow2.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/block/qcow2.c
31
+++ b/block/qcow2.c
32
@@ -XXX,XX +XXX,XX @@
33
#include "qapi/qobject-input-visitor.h"
34
#include "qapi/qapi-visit-block-core.h"
35
#include "crypto.h"
36
+#include "block/aio_task.h"
37
38
/*
39
Differences with QCOW:
40
@@ -XXX,XX +XXX,XX @@ fail:
41
return ret;
42
}
43
44
+typedef struct Qcow2AioTask {
45
+ AioTask task;
46
+
47
+ BlockDriverState *bs;
48
+ QCow2ClusterType cluster_type; /* only for read */
49
+ uint64_t file_cluster_offset;
50
+ uint64_t offset;
51
+ uint64_t bytes;
52
+ QEMUIOVector *qiov;
53
+ uint64_t qiov_offset;
54
+ QCowL2Meta *l2meta; /* only for write */
55
+} Qcow2AioTask;
56
+
57
+static coroutine_fn int qcow2_co_preadv_task_entry(AioTask *task);
58
+static coroutine_fn int qcow2_add_task(BlockDriverState *bs,
59
+ AioTaskPool *pool,
60
+ AioTaskFunc func,
61
+ QCow2ClusterType cluster_type,
62
+ uint64_t file_cluster_offset,
63
+ uint64_t offset,
64
+ uint64_t bytes,
65
+ QEMUIOVector *qiov,
66
+ size_t qiov_offset,
67
+ QCowL2Meta *l2meta)
68
+{
69
+ Qcow2AioTask local_task;
70
+ Qcow2AioTask *task = pool ? g_new(Qcow2AioTask, 1) : &local_task;
71
+
72
+ *task = (Qcow2AioTask) {
73
+ .task.func = func,
74
+ .bs = bs,
75
+ .cluster_type = cluster_type,
76
+ .qiov = qiov,
77
+ .file_cluster_offset = file_cluster_offset,
78
+ .offset = offset,
79
+ .bytes = bytes,
80
+ .qiov_offset = qiov_offset,
81
+ .l2meta = l2meta,
82
+ };
83
+
84
+ trace_qcow2_add_task(qemu_coroutine_self(), bs, pool,
85
+ func == qcow2_co_preadv_task_entry ? "read" : "write",
86
+ cluster_type, file_cluster_offset, offset, bytes,
87
+ qiov, qiov_offset);
88
+
89
+ if (!pool) {
90
+ return func(&task->task);
91
+ }
92
+
93
+ aio_task_pool_start_task(pool, &task->task);
94
+
95
+ return 0;
96
+}
97
+
98
static coroutine_fn int qcow2_co_preadv_task(BlockDriverState *bs,
99
QCow2ClusterType cluster_type,
100
uint64_t file_cluster_offset,
101
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_preadv_task(BlockDriverState *bs,
102
g_assert_not_reached();
103
}
104
105
+static coroutine_fn int qcow2_co_preadv_task_entry(AioTask *task)
106
+{
107
+ Qcow2AioTask *t = container_of(task, Qcow2AioTask, task);
108
+
109
+ assert(!t->l2meta);
110
+
111
+ return qcow2_co_preadv_task(t->bs, t->cluster_type, t->file_cluster_offset,
112
+ t->offset, t->bytes, t->qiov, t->qiov_offset);
113
+}
114
+
115
static coroutine_fn int qcow2_co_preadv_part(BlockDriverState *bs,
116
uint64_t offset, uint64_t bytes,
117
QEMUIOVector *qiov,
118
size_t qiov_offset, int flags)
119
{
120
BDRVQcow2State *s = bs->opaque;
121
- int ret;
122
+ int ret = 0;
123
unsigned int cur_bytes; /* number of bytes in current iteration */
124
uint64_t cluster_offset = 0;
125
+ AioTaskPool *aio = NULL;
126
127
- while (bytes != 0) {
128
-
129
+ while (bytes != 0 && aio_task_pool_status(aio) == 0) {
130
/* prepare next request */
131
cur_bytes = MIN(bytes, INT_MAX);
132
if (s->crypto) {
133
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_preadv_part(BlockDriverState *bs,
134
ret = qcow2_get_cluster_offset(bs, offset, &cur_bytes, &cluster_offset);
135
qemu_co_mutex_unlock(&s->lock);
136
if (ret < 0) {
137
- return ret;
138
+ goto out;
139
}
140
141
if (ret == QCOW2_CLUSTER_ZERO_PLAIN ||
142
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_preadv_part(BlockDriverState *bs,
143
{
144
qemu_iovec_memset(qiov, qiov_offset, 0, cur_bytes);
145
} else {
146
- ret = qcow2_co_preadv_task(bs, ret,
147
- cluster_offset, offset, cur_bytes,
148
- qiov, qiov_offset);
149
+ if (!aio && cur_bytes != bytes) {
150
+ aio = aio_task_pool_new(QCOW2_MAX_WORKERS);
151
+ }
152
+ ret = qcow2_add_task(bs, aio, qcow2_co_preadv_task_entry, ret,
153
+ cluster_offset, offset, cur_bytes,
154
+ qiov, qiov_offset, NULL);
155
if (ret < 0) {
156
- return ret;
157
+ goto out;
158
}
159
}
160
161
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_preadv_part(BlockDriverState *bs,
162
qiov_offset += cur_bytes;
163
}
164
165
- return 0;
166
+out:
167
+ if (aio) {
168
+ aio_task_pool_wait_all(aio);
169
+ if (ret == 0) {
170
+ ret = aio_task_pool_status(aio);
171
+ }
172
+ g_free(aio);
173
+ }
174
+
175
+ return ret;
176
}
177
178
/* Check if it's possible to merge a write request with the writing of
179
@@ -XXX,XX +XXX,XX @@ out_locked:
180
return ret;
181
}
182
183
+static coroutine_fn int qcow2_co_pwritev_task_entry(AioTask *task)
184
+{
185
+ Qcow2AioTask *t = container_of(task, Qcow2AioTask, task);
186
+
187
+ assert(!t->cluster_type);
188
+
189
+ return qcow2_co_pwritev_task(t->bs, t->file_cluster_offset,
190
+ t->offset, t->bytes, t->qiov, t->qiov_offset,
191
+ t->l2meta);
192
+}
193
+
194
static coroutine_fn int qcow2_co_pwritev_part(
195
BlockDriverState *bs, uint64_t offset, uint64_t bytes,
196
QEMUIOVector *qiov, size_t qiov_offset, int flags)
197
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_pwritev_part(
198
unsigned int cur_bytes; /* number of sectors in current iteration */
199
uint64_t cluster_offset;
200
QCowL2Meta *l2meta = NULL;
201
+ AioTaskPool *aio = NULL;
202
203
trace_qcow2_writev_start_req(qemu_coroutine_self(), offset, bytes);
204
205
- while (bytes != 0) {
206
+ while (bytes != 0 && aio_task_pool_status(aio) == 0) {
207
208
l2meta = NULL;
209
210
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_pwritev_part(
211
212
qemu_co_mutex_unlock(&s->lock);
213
214
- ret = qcow2_co_pwritev_task(bs, cluster_offset, offset, cur_bytes,
215
- qiov, qiov_offset, l2meta);
216
+ if (!aio && cur_bytes != bytes) {
217
+ aio = aio_task_pool_new(QCOW2_MAX_WORKERS);
218
+ }
219
+ ret = qcow2_add_task(bs, aio, qcow2_co_pwritev_task_entry, 0,
220
+ cluster_offset, offset, cur_bytes,
221
+ qiov, qiov_offset, l2meta);
222
l2meta = NULL; /* l2meta is consumed by qcow2_co_pwritev_task() */
223
if (ret < 0) {
224
goto fail_nometa;
225
@@ -XXX,XX +XXX,XX @@ out_locked:
226
qemu_co_mutex_unlock(&s->lock);
227
228
fail_nometa:
229
+ if (aio) {
230
+ aio_task_pool_wait_all(aio);
231
+ if (ret == 0) {
232
+ ret = aio_task_pool_status(aio);
233
+ }
234
+ g_free(aio);
235
+ }
236
+
237
trace_qcow2_writev_done_req(qemu_coroutine_self(), ret);
238
239
return ret;
240
diff --git a/block/trace-events b/block/trace-events
241
index XXXXXXX..XXXXXXX 100644
242
--- a/block/trace-events
243
+++ b/block/trace-events
244
@@ -XXX,XX +XXX,XX @@ file_paio_submit(void *acb, void *opaque, int64_t offset, int count, int type) "
245
file_copy_file_range(void *bs, int src, int64_t src_off, int dst, int64_t dst_off, int64_t bytes, int flags, int64_t ret) "bs %p src_fd %d offset %"PRIu64" dst_fd %d offset %"PRIu64" bytes %"PRIu64" flags %d ret %"PRId64
246
247
# qcow2.c
248
+qcow2_add_task(void *co, void *bs, void *pool, const char *action, int cluster_type, uint64_t file_cluster_offset, uint64_t offset, uint64_t bytes, void *qiov, size_t qiov_offset) "co %p bs %p pool %p: %s: cluster_type %d file_cluster_offset %" PRIu64 " offset %" PRIu64 " bytes %" PRIu64 " qiov %p qiov_offset %zu"
249
qcow2_writev_start_req(void *co, int64_t offset, int bytes) "co %p offset 0x%" PRIx64 " bytes %d"
250
qcow2_writev_done_req(void *co, int ret) "co %p ret %d"
251
qcow2_writev_start_part(void *co) "co %p"
252
--
253
2.21.0
254
255
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Of course, QEMU_ALIGN_UP is a typo, it should be QEMU_ALIGN_DOWN, as we
4
are trying to find aligned size which satisfy both source and target.
5
Also, don't ignore too small max_transfer. In this case seems safer to
6
disable copy_range.
7
8
Fixes: 9ded4a0114968e
9
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Message-id: 20190920142056.12778-2-vsementsov@virtuozzo.com
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
---
13
block/backup.c | 15 +++++++++++----
14
1 file changed, 11 insertions(+), 4 deletions(-)
15
16
diff --git a/block/backup.c b/block/backup.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/backup.c
19
+++ b/block/backup.c
20
@@ -XXX,XX +XXX,XX @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
21
job->cluster_size = cluster_size;
22
job->copy_bitmap = copy_bitmap;
23
copy_bitmap = NULL;
24
- job->use_copy_range = !compress; /* compression isn't supported for it */
25
job->copy_range_size = MIN_NON_ZERO(blk_get_max_transfer(job->common.blk),
26
blk_get_max_transfer(job->target));
27
- job->copy_range_size = MAX(job->cluster_size,
28
- QEMU_ALIGN_UP(job->copy_range_size,
29
- job->cluster_size));
30
+ job->copy_range_size = QEMU_ALIGN_DOWN(job->copy_range_size,
31
+ job->cluster_size);
32
+ /*
33
+ * Set use_copy_range, consider the following:
34
+ * 1. Compression is not supported for copy_range.
35
+ * 2. copy_range does not respect max_transfer (it's a TODO), so we factor
36
+ * that in here. If max_transfer is smaller than the job->cluster_size,
37
+ * we do not use copy_range (in that case it's zero after aligning down
38
+ * above).
39
+ */
40
+ job->use_copy_range = !compress && job->copy_range_size > 0;
41
42
/* Required permissions are already taken with target's blk_new() */
43
block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL,
44
--
45
2.21.0
46
47
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
We shouldn't try to copy bytes beyond EOF. Fix it.
4
5
Fixes: 9ded4a0114968e
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Max Reitz <mreitz@redhat.com>
8
Reviewed-by: John Snow <jsnow@redhat.com>
9
Message-id: 20190920142056.12778-3-vsementsov@virtuozzo.com
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
---
12
block/backup.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/block/backup.c b/block/backup.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/block/backup.c
18
+++ b/block/backup.c
19
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_cow_with_offload(BackupBlockJob *job,
20
21
assert(QEMU_IS_ALIGNED(job->copy_range_size, job->cluster_size));
22
assert(QEMU_IS_ALIGNED(start, job->cluster_size));
23
- nbytes = MIN(job->copy_range_size, end - start);
24
+ nbytes = MIN(job->copy_range_size, MIN(end, job->len) - start);
25
nr_clusters = DIV_ROUND_UP(nbytes, job->cluster_size);
26
bdrv_reset_dirty_bitmap(job->copy_bitmap, start,
27
job->cluster_size * nr_clusters);
28
--
29
2.21.0
30
31
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Split copying logic which will be shared with backup-top filter.
4
5
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
Reviewed-by: Max Reitz <mreitz@redhat.com>
7
Message-id: 20190920142056.12778-4-vsementsov@virtuozzo.com
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
---
10
block/backup.c | 47 ++++++++++++++++++++++++++++++++---------------
11
1 file changed, 32 insertions(+), 15 deletions(-)
12
13
diff --git a/block/backup.c b/block/backup.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/block/backup.c
16
+++ b/block/backup.c
17
@@ -XXX,XX +XXX,XX @@ static int64_t backup_bitmap_reset_unallocated(BackupBlockJob *s,
18
return ret;
19
}
20
21
-static int coroutine_fn backup_do_cow(BackupBlockJob *job,
22
- int64_t offset, uint64_t bytes,
23
- bool *error_is_read,
24
- bool is_write_notifier)
25
+static int coroutine_fn backup_do_copy(BackupBlockJob *job,
26
+ int64_t start, uint64_t bytes,
27
+ bool *error_is_read,
28
+ bool is_write_notifier)
29
{
30
- CowRequest cow_request;
31
int ret = 0;
32
- int64_t start, end; /* bytes */
33
+ int64_t end = bytes + start; /* bytes */
34
void *bounce_buffer = NULL;
35
int64_t status_bytes;
36
37
- qemu_co_rwlock_rdlock(&job->flush_rwlock);
38
-
39
- start = QEMU_ALIGN_DOWN(offset, job->cluster_size);
40
- end = QEMU_ALIGN_UP(bytes + offset, job->cluster_size);
41
-
42
- trace_backup_do_cow_enter(job, start, offset, bytes);
43
-
44
- wait_for_overlapping_requests(job, start, end);
45
- cow_request_begin(&cow_request, job, start, end);
46
+ assert(QEMU_IS_ALIGNED(start, job->cluster_size));
47
+ assert(QEMU_IS_ALIGNED(end, job->cluster_size));
48
49
while (start < end) {
50
int64_t dirty_end;
51
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job,
52
qemu_vfree(bounce_buffer);
53
}
54
55
+ return ret;
56
+}
57
+
58
+static int coroutine_fn backup_do_cow(BackupBlockJob *job,
59
+ int64_t offset, uint64_t bytes,
60
+ bool *error_is_read,
61
+ bool is_write_notifier)
62
+{
63
+ CowRequest cow_request;
64
+ int ret = 0;
65
+ int64_t start, end; /* bytes */
66
+
67
+ qemu_co_rwlock_rdlock(&job->flush_rwlock);
68
+
69
+ start = QEMU_ALIGN_DOWN(offset, job->cluster_size);
70
+ end = QEMU_ALIGN_UP(bytes + offset, job->cluster_size);
71
+
72
+ trace_backup_do_cow_enter(job, start, offset, bytes);
73
+
74
+ wait_for_overlapping_requests(job, start, end);
75
+ cow_request_begin(&cow_request, job, start, end);
76
+
77
+ ret = backup_do_copy(job, start, end - start, error_is_read,
78
+ is_write_notifier);
79
+
80
cow_request_end(&cow_request);
81
82
trace_backup_do_cow_return(job, offset, bytes, ret);
83
--
84
2.21.0
85
86
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
4
Reviewed-by: Max Reitz <mreitz@redhat.com>
5
Message-id: 20190920142056.12778-5-vsementsov@virtuozzo.com
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
---
8
block/backup.c | 15 ++++++++++++---
9
1 file changed, 12 insertions(+), 3 deletions(-)
10
11
diff --git a/block/backup.c b/block/backup.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/block/backup.c
14
+++ b/block/backup.c
15
@@ -XXX,XX +XXX,XX @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
16
job->bitmap_mode = bitmap_mode;
17
18
/*
19
- * Set write flags:
20
- * 1. Detect image-fleecing (and similar) schemes
21
- * 2. Handle compression
22
+ * If source is in backing chain of target assume that target is going to be
23
+ * used for "image fleecing", i.e. it should represent a kind of snapshot of
24
+ * source at backup-start point in time. And target is going to be read by
25
+ * somebody (for example, used as NBD export) during backup job.
26
+ *
27
+ * In this case, we need to add BDRV_REQ_SERIALISING write flag to avoid
28
+ * intersection of backup writes and third party reads from target,
29
+ * otherwise reading from target we may occasionally read already updated by
30
+ * guest data.
31
+ *
32
+ * For more information see commit f8d59dfb40bb and test
33
+ * tests/qemu-iotests/222
34
*/
35
job->write_flags =
36
(bdrv_chain_contains(target, bs) ? BDRV_REQ_SERIALISING : 0) |
37
--
38
2.21.0
39
40
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Split copying code part from backup to "block-copy", including separate
4
state structure and function renaming. This is needed to share it with
5
backup-top filter driver in further commits.
6
7
Notes:
8
9
1. As BlockCopyState keeps own BlockBackend objects, remaining
10
job->common.blk users only use it to get bs by blk_bs() call, so clear
11
job->commen.blk permissions set in block_job_create and add
12
job->source_bs to be used instead of blk_bs(job->common.blk), to keep
13
it more clear which bs we use when introduce backup-top filter in
14
further commit.
15
16
2. Rename s/initializing_bitmap/skip_unallocated/ to sound a bit better
17
as interface to BlockCopyState
18
19
3. Split is not very clean: there left some duplicated fields, backup
20
code uses some BlockCopyState fields directly, let's postpone it for
21
further improvements and keep this comment simpler for review.
22
23
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
24
Message-id: 20190920142056.12778-6-vsementsov@virtuozzo.com
25
Signed-off-by: Max Reitz <mreitz@redhat.com>
26
---
27
block/backup.c | 370 ++++++++++++++++++++++++++++-----------------
28
block/trace-events | 12 +-
29
2 files changed, 239 insertions(+), 143 deletions(-)
30
31
diff --git a/block/backup.c b/block/backup.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/block/backup.c
34
+++ b/block/backup.c
35
@@ -XXX,XX +XXX,XX @@ typedef struct CowRequest {
36
CoQueue wait_queue; /* coroutines blocked on this request */
37
} CowRequest;
38
39
+typedef void (*ProgressBytesCallbackFunc)(int64_t bytes, void *opaque);
40
+typedef void (*ProgressResetCallbackFunc)(void *opaque);
41
+typedef struct BlockCopyState {
42
+ BlockBackend *source;
43
+ BlockBackend *target;
44
+ BdrvDirtyBitmap *copy_bitmap;
45
+ int64_t cluster_size;
46
+ bool use_copy_range;
47
+ int64_t copy_range_size;
48
+ uint64_t len;
49
+
50
+ BdrvRequestFlags write_flags;
51
+
52
+ /*
53
+ * skip_unallocated:
54
+ *
55
+ * Used by sync=top jobs, which first scan the source node for unallocated
56
+ * areas and clear them in the copy_bitmap. During this process, the bitmap
57
+ * is thus not fully initialized: It may still have bits set for areas that
58
+ * are unallocated and should actually not be copied.
59
+ *
60
+ * This is indicated by skip_unallocated.
61
+ *
62
+ * In this case, block_copy() will query the source’s allocation status,
63
+ * skip unallocated regions, clear them in the copy_bitmap, and invoke
64
+ * block_copy_reset_unallocated() every time it does.
65
+ */
66
+ bool skip_unallocated;
67
+
68
+ /* progress_bytes_callback: called when some copying progress is done. */
69
+ ProgressBytesCallbackFunc progress_bytes_callback;
70
+
71
+ /*
72
+ * progress_reset_callback: called when some bytes reset from copy_bitmap
73
+ * (see @skip_unallocated above). The callee is assumed to recalculate how
74
+ * many bytes remain based on the dirty bit count of copy_bitmap.
75
+ */
76
+ ProgressResetCallbackFunc progress_reset_callback;
77
+ void *progress_opaque;
78
+} BlockCopyState;
79
+
80
typedef struct BackupBlockJob {
81
BlockJob common;
82
- BlockBackend *target;
83
+ BlockDriverState *source_bs;
84
85
BdrvDirtyBitmap *sync_bitmap;
86
- BdrvDirtyBitmap *copy_bitmap;
87
88
MirrorSyncMode sync_mode;
89
BitmapSyncMode bitmap_mode;
90
@@ -XXX,XX +XXX,XX @@ typedef struct BackupBlockJob {
91
NotifierWithReturn before_write;
92
QLIST_HEAD(, CowRequest) inflight_reqs;
93
94
- bool use_copy_range;
95
- int64_t copy_range_size;
96
-
97
- BdrvRequestFlags write_flags;
98
- bool initializing_bitmap;
99
+ BlockCopyState *bcs;
100
} BackupBlockJob;
101
102
static const BlockJobDriver backup_job_driver;
103
@@ -XXX,XX +XXX,XX @@ static void cow_request_end(CowRequest *req)
104
qemu_co_queue_restart_all(&req->wait_queue);
105
}
106
107
+static void block_copy_state_free(BlockCopyState *s)
108
+{
109
+ if (!s) {
110
+ return;
111
+ }
112
+
113
+ bdrv_release_dirty_bitmap(blk_bs(s->source), s->copy_bitmap);
114
+ blk_unref(s->source);
115
+ blk_unref(s->target);
116
+ g_free(s);
117
+}
118
+
119
+static BlockCopyState *block_copy_state_new(
120
+ BlockDriverState *source, BlockDriverState *target,
121
+ int64_t cluster_size, BdrvRequestFlags write_flags,
122
+ ProgressBytesCallbackFunc progress_bytes_callback,
123
+ ProgressResetCallbackFunc progress_reset_callback,
124
+ void *progress_opaque, Error **errp)
125
+{
126
+ BlockCopyState *s;
127
+ int ret;
128
+ uint64_t no_resize = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE |
129
+ BLK_PERM_WRITE_UNCHANGED | BLK_PERM_GRAPH_MOD;
130
+ BdrvDirtyBitmap *copy_bitmap;
131
+
132
+ copy_bitmap = bdrv_create_dirty_bitmap(source, cluster_size, NULL, errp);
133
+ if (!copy_bitmap) {
134
+ return NULL;
135
+ }
136
+ bdrv_disable_dirty_bitmap(copy_bitmap);
137
+
138
+ s = g_new(BlockCopyState, 1);
139
+ *s = (BlockCopyState) {
140
+ .source = blk_new(bdrv_get_aio_context(source),
141
+ BLK_PERM_CONSISTENT_READ, no_resize),
142
+ .target = blk_new(bdrv_get_aio_context(target),
143
+ BLK_PERM_WRITE, no_resize),
144
+ .copy_bitmap = copy_bitmap,
145
+ .cluster_size = cluster_size,
146
+ .len = bdrv_dirty_bitmap_size(copy_bitmap),
147
+ .write_flags = write_flags,
148
+ .progress_bytes_callback = progress_bytes_callback,
149
+ .progress_reset_callback = progress_reset_callback,
150
+ .progress_opaque = progress_opaque,
151
+ };
152
+
153
+ s->copy_range_size = QEMU_ALIGN_DOWN(MIN(blk_get_max_transfer(s->source),
154
+ blk_get_max_transfer(s->target)),
155
+ s->cluster_size);
156
+ /*
157
+ * Set use_copy_range, consider the following:
158
+ * 1. Compression is not supported for copy_range.
159
+ * 2. copy_range does not respect max_transfer (it's a TODO), so we factor
160
+ * that in here. If max_transfer is smaller than the job->cluster_size,
161
+ * we do not use copy_range (in that case it's zero after aligning down
162
+ * above).
163
+ */
164
+ s->use_copy_range =
165
+ !(write_flags & BDRV_REQ_WRITE_COMPRESSED) && s->copy_range_size > 0;
166
+
167
+ /*
168
+ * We just allow aio context change on our block backends. block_copy() user
169
+ * (now it's only backup) is responsible for source and target being in same
170
+ * aio context.
171
+ */
172
+ blk_set_disable_request_queuing(s->source, true);
173
+ blk_set_allow_aio_context_change(s->source, true);
174
+ blk_set_disable_request_queuing(s->target, true);
175
+ blk_set_allow_aio_context_change(s->target, true);
176
+
177
+ ret = blk_insert_bs(s->source, source, errp);
178
+ if (ret < 0) {
179
+ goto fail;
180
+ }
181
+
182
+ ret = blk_insert_bs(s->target, target, errp);
183
+ if (ret < 0) {
184
+ goto fail;
185
+ }
186
+
187
+ return s;
188
+
189
+fail:
190
+ block_copy_state_free(s);
191
+
192
+ return NULL;
193
+}
194
+
195
/* Copy range to target with a bounce buffer and return the bytes copied. If
196
* error occurred, return a negative error number */
197
-static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job,
198
+static int coroutine_fn block_copy_with_bounce_buffer(BlockCopyState *s,
199
int64_t start,
200
int64_t end,
201
bool is_write_notifier,
202
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job,
203
void **bounce_buffer)
204
{
205
int ret;
206
- BlockBackend *blk = job->common.blk;
207
int nbytes;
208
int read_flags = is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0;
209
210
- assert(QEMU_IS_ALIGNED(start, job->cluster_size));
211
- bdrv_reset_dirty_bitmap(job->copy_bitmap, start, job->cluster_size);
212
- nbytes = MIN(job->cluster_size, job->len - start);
213
+ assert(QEMU_IS_ALIGNED(start, s->cluster_size));
214
+ bdrv_reset_dirty_bitmap(s->copy_bitmap, start, s->cluster_size);
215
+ nbytes = MIN(s->cluster_size, s->len - start);
216
if (!*bounce_buffer) {
217
- *bounce_buffer = blk_blockalign(blk, job->cluster_size);
218
+ *bounce_buffer = blk_blockalign(s->source, s->cluster_size);
219
}
220
221
- ret = blk_co_pread(blk, start, nbytes, *bounce_buffer, read_flags);
222
+ ret = blk_co_pread(s->source, start, nbytes, *bounce_buffer, read_flags);
223
if (ret < 0) {
224
- trace_backup_do_cow_read_fail(job, start, ret);
225
+ trace_block_copy_with_bounce_buffer_read_fail(s, start, ret);
226
if (error_is_read) {
227
*error_is_read = true;
228
}
229
goto fail;
230
}
231
232
- ret = blk_co_pwrite(job->target, start, nbytes, *bounce_buffer,
233
- job->write_flags);
234
+ ret = blk_co_pwrite(s->target, start, nbytes, *bounce_buffer,
235
+ s->write_flags);
236
if (ret < 0) {
237
- trace_backup_do_cow_write_fail(job, start, ret);
238
+ trace_block_copy_with_bounce_buffer_write_fail(s, start, ret);
239
if (error_is_read) {
240
*error_is_read = false;
241
}
242
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job,
243
244
return nbytes;
245
fail:
246
- bdrv_set_dirty_bitmap(job->copy_bitmap, start, job->cluster_size);
247
+ bdrv_set_dirty_bitmap(s->copy_bitmap, start, s->cluster_size);
248
return ret;
249
250
}
251
252
/* Copy range to target and return the bytes copied. If error occurred, return a
253
* negative error number. */
254
-static int coroutine_fn backup_cow_with_offload(BackupBlockJob *job,
255
+static int coroutine_fn block_copy_with_offload(BlockCopyState *s,
256
int64_t start,
257
int64_t end,
258
bool is_write_notifier)
259
{
260
int ret;
261
int nr_clusters;
262
- BlockBackend *blk = job->common.blk;
263
int nbytes;
264
int read_flags = is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0;
265
266
- assert(QEMU_IS_ALIGNED(job->copy_range_size, job->cluster_size));
267
- assert(QEMU_IS_ALIGNED(start, job->cluster_size));
268
- nbytes = MIN(job->copy_range_size, MIN(end, job->len) - start);
269
- nr_clusters = DIV_ROUND_UP(nbytes, job->cluster_size);
270
- bdrv_reset_dirty_bitmap(job->copy_bitmap, start,
271
- job->cluster_size * nr_clusters);
272
- ret = blk_co_copy_range(blk, start, job->target, start, nbytes,
273
- read_flags, job->write_flags);
274
+ assert(QEMU_IS_ALIGNED(s->copy_range_size, s->cluster_size));
275
+ assert(QEMU_IS_ALIGNED(start, s->cluster_size));
276
+ nbytes = MIN(s->copy_range_size, MIN(end, s->len) - start);
277
+ nr_clusters = DIV_ROUND_UP(nbytes, s->cluster_size);
278
+ bdrv_reset_dirty_bitmap(s->copy_bitmap, start,
279
+ s->cluster_size * nr_clusters);
280
+ ret = blk_co_copy_range(s->source, start, s->target, start, nbytes,
281
+ read_flags, s->write_flags);
282
if (ret < 0) {
283
- trace_backup_do_cow_copy_range_fail(job, start, ret);
284
- bdrv_set_dirty_bitmap(job->copy_bitmap, start,
285
- job->cluster_size * nr_clusters);
286
+ trace_block_copy_with_offload_fail(s, start, ret);
287
+ bdrv_set_dirty_bitmap(s->copy_bitmap, start,
288
+ s->cluster_size * nr_clusters);
289
return ret;
290
}
291
292
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_cow_with_offload(BackupBlockJob *job,
293
* Check if the cluster starting at offset is allocated or not.
294
* return via pnum the number of contiguous clusters sharing this allocation.
295
*/
296
-static int backup_is_cluster_allocated(BackupBlockJob *s, int64_t offset,
297
- int64_t *pnum)
298
+static int block_copy_is_cluster_allocated(BlockCopyState *s, int64_t offset,
299
+ int64_t *pnum)
300
{
301
- BlockDriverState *bs = blk_bs(s->common.blk);
302
+ BlockDriverState *bs = blk_bs(s->source);
303
int64_t count, total_count = 0;
304
int64_t bytes = s->len - offset;
305
int ret;
306
@@ -XXX,XX +XXX,XX @@ static int backup_is_cluster_allocated(BackupBlockJob *s, int64_t offset,
307
* @return 0 when the cluster at @offset was unallocated,
308
* 1 otherwise, and -ret on error.
309
*/
310
-static int64_t backup_bitmap_reset_unallocated(BackupBlockJob *s,
311
- int64_t offset, int64_t *count)
312
+static int64_t block_copy_reset_unallocated(BlockCopyState *s,
313
+ int64_t offset, int64_t *count)
314
{
315
int ret;
316
- int64_t clusters, bytes, estimate;
317
+ int64_t clusters, bytes;
318
319
- ret = backup_is_cluster_allocated(s, offset, &clusters);
320
+ ret = block_copy_is_cluster_allocated(s, offset, &clusters);
321
if (ret < 0) {
322
return ret;
323
}
324
@@ -XXX,XX +XXX,XX @@ static int64_t backup_bitmap_reset_unallocated(BackupBlockJob *s,
325
326
if (!ret) {
327
bdrv_reset_dirty_bitmap(s->copy_bitmap, offset, bytes);
328
- estimate = bdrv_get_dirty_count(s->copy_bitmap);
329
- job_progress_set_remaining(&s->common.job, estimate);
330
+ s->progress_reset_callback(s->progress_opaque);
331
}
332
333
*count = bytes;
334
return ret;
335
}
336
337
-static int coroutine_fn backup_do_copy(BackupBlockJob *job,
338
- int64_t start, uint64_t bytes,
339
- bool *error_is_read,
340
- bool is_write_notifier)
341
+static int coroutine_fn block_copy(BlockCopyState *s,
342
+ int64_t start, uint64_t bytes,
343
+ bool *error_is_read,
344
+ bool is_write_notifier)
345
{
346
int ret = 0;
347
int64_t end = bytes + start; /* bytes */
348
void *bounce_buffer = NULL;
349
int64_t status_bytes;
350
351
- assert(QEMU_IS_ALIGNED(start, job->cluster_size));
352
- assert(QEMU_IS_ALIGNED(end, job->cluster_size));
353
+ /*
354
+ * block_copy() user is responsible for keeping source and target in same
355
+ * aio context
356
+ */
357
+ assert(blk_get_aio_context(s->source) == blk_get_aio_context(s->target));
358
+
359
+ assert(QEMU_IS_ALIGNED(start, s->cluster_size));
360
+ assert(QEMU_IS_ALIGNED(end, s->cluster_size));
361
362
while (start < end) {
363
int64_t dirty_end;
364
365
- if (!bdrv_dirty_bitmap_get(job->copy_bitmap, start)) {
366
- trace_backup_do_cow_skip(job, start);
367
- start += job->cluster_size;
368
+ if (!bdrv_dirty_bitmap_get(s->copy_bitmap, start)) {
369
+ trace_block_copy_skip(s, start);
370
+ start += s->cluster_size;
371
continue; /* already copied */
372
}
373
374
- dirty_end = bdrv_dirty_bitmap_next_zero(job->copy_bitmap, start,
375
+ dirty_end = bdrv_dirty_bitmap_next_zero(s->copy_bitmap, start,
376
(end - start));
377
if (dirty_end < 0) {
378
dirty_end = end;
379
}
380
381
- if (job->initializing_bitmap) {
382
- ret = backup_bitmap_reset_unallocated(job, start, &status_bytes);
383
+ if (s->skip_unallocated) {
384
+ ret = block_copy_reset_unallocated(s, start, &status_bytes);
385
if (ret == 0) {
386
- trace_backup_do_cow_skip_range(job, start, status_bytes);
387
+ trace_block_copy_skip_range(s, start, status_bytes);
388
start += status_bytes;
389
continue;
390
}
391
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_do_copy(BackupBlockJob *job,
392
dirty_end = MIN(dirty_end, start + status_bytes);
393
}
394
395
- trace_backup_do_cow_process(job, start);
396
+ trace_block_copy_process(s, start);
397
398
- if (job->use_copy_range) {
399
- ret = backup_cow_with_offload(job, start, dirty_end,
400
+ if (s->use_copy_range) {
401
+ ret = block_copy_with_offload(s, start, dirty_end,
402
is_write_notifier);
403
if (ret < 0) {
404
- job->use_copy_range = false;
405
+ s->use_copy_range = false;
406
}
407
}
408
- if (!job->use_copy_range) {
409
- ret = backup_cow_with_bounce_buffer(job, start, dirty_end,
410
+ if (!s->use_copy_range) {
411
+ ret = block_copy_with_bounce_buffer(s, start, dirty_end,
412
is_write_notifier,
413
error_is_read, &bounce_buffer);
414
}
415
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_do_copy(BackupBlockJob *job,
416
break;
417
}
418
419
- /* Publish progress, guest I/O counts as progress too. Note that the
420
- * offset field is an opaque progress value, it is not a disk offset.
421
- */
422
start += ret;
423
- job->bytes_read += ret;
424
- job_progress_update(&job->common.job, ret);
425
+ s->progress_bytes_callback(ret, s->progress_opaque);
426
ret = 0;
427
}
428
429
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_do_copy(BackupBlockJob *job,
430
return ret;
431
}
432
433
+static void backup_progress_bytes_callback(int64_t bytes, void *opaque)
434
+{
435
+ BackupBlockJob *s = opaque;
436
+
437
+ s->bytes_read += bytes;
438
+ job_progress_update(&s->common.job, bytes);
439
+}
440
+
441
+static void backup_progress_reset_callback(void *opaque)
442
+{
443
+ BackupBlockJob *s = opaque;
444
+ uint64_t estimate = bdrv_get_dirty_count(s->bcs->copy_bitmap);
445
+
446
+ job_progress_set_remaining(&s->common.job, estimate);
447
+}
448
+
449
static int coroutine_fn backup_do_cow(BackupBlockJob *job,
450
int64_t offset, uint64_t bytes,
451
bool *error_is_read,
452
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job,
453
wait_for_overlapping_requests(job, start, end);
454
cow_request_begin(&cow_request, job, start, end);
455
456
- ret = backup_do_copy(job, start, end - start, error_is_read,
457
- is_write_notifier);
458
+ ret = block_copy(job->bcs, start, end - start, error_is_read,
459
+ is_write_notifier);
460
461
cow_request_end(&cow_request);
462
463
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_before_write_notify(
464
BackupBlockJob *job = container_of(notifier, BackupBlockJob, before_write);
465
BdrvTrackedRequest *req = opaque;
466
467
- assert(req->bs == blk_bs(job->common.blk));
468
+ assert(req->bs == job->source_bs);
469
assert(QEMU_IS_ALIGNED(req->offset, BDRV_SECTOR_SIZE));
470
assert(QEMU_IS_ALIGNED(req->bytes, BDRV_SECTOR_SIZE));
471
472
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_before_write_notify(
473
static void backup_cleanup_sync_bitmap(BackupBlockJob *job, int ret)
474
{
475
BdrvDirtyBitmap *bm;
476
- BlockDriverState *bs = blk_bs(job->common.blk);
477
bool sync = (((ret == 0) || (job->bitmap_mode == BITMAP_SYNC_MODE_ALWAYS)) \
478
&& (job->bitmap_mode != BITMAP_SYNC_MODE_NEVER));
479
480
@@ -XXX,XX +XXX,XX @@ static void backup_cleanup_sync_bitmap(BackupBlockJob *job, int ret)
481
* We succeeded, or we always intended to sync the bitmap.
482
* Delete this bitmap and install the child.
483
*/
484
- bm = bdrv_dirty_bitmap_abdicate(bs, job->sync_bitmap, NULL);
485
+ bm = bdrv_dirty_bitmap_abdicate(job->source_bs, job->sync_bitmap, NULL);
486
} else {
487
/*
488
* We failed, or we never intended to sync the bitmap anyway.
489
* Merge the successor back into the parent, keeping all data.
490
*/
491
- bm = bdrv_reclaim_dirty_bitmap(bs, job->sync_bitmap, NULL);
492
+ bm = bdrv_reclaim_dirty_bitmap(job->source_bs, job->sync_bitmap, NULL);
493
}
494
495
assert(bm);
496
497
if (ret < 0 && job->bitmap_mode == BITMAP_SYNC_MODE_ALWAYS) {
498
/* If we failed and synced, merge in the bits we didn't copy: */
499
- bdrv_dirty_bitmap_merge_internal(bm, job->copy_bitmap,
500
+ bdrv_dirty_bitmap_merge_internal(bm, job->bcs->copy_bitmap,
501
NULL, true);
502
}
503
}
504
@@ -XXX,XX +XXX,XX @@ static void backup_abort(Job *job)
505
static void backup_clean(Job *job)
506
{
507
BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
508
- BlockDriverState *bs = blk_bs(s->common.blk);
509
510
- if (s->copy_bitmap) {
511
- bdrv_release_dirty_bitmap(bs, s->copy_bitmap);
512
- s->copy_bitmap = NULL;
513
- }
514
-
515
- assert(s->target);
516
- blk_unref(s->target);
517
- s->target = NULL;
518
+ block_copy_state_free(s->bcs);
519
}
520
521
void backup_do_checkpoint(BlockJob *job, Error **errp)
522
@@ -XXX,XX +XXX,XX @@ void backup_do_checkpoint(BlockJob *job, Error **errp)
523
return;
524
}
525
526
- bdrv_set_dirty_bitmap(backup_job->copy_bitmap, 0, backup_job->len);
527
+ bdrv_set_dirty_bitmap(backup_job->bcs->copy_bitmap, 0, backup_job->len);
528
}
529
530
static BlockErrorAction backup_error_action(BackupBlockJob *job,
531
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_loop(BackupBlockJob *job)
532
BdrvDirtyBitmapIter *bdbi;
533
int ret = 0;
534
535
- bdbi = bdrv_dirty_iter_new(job->copy_bitmap);
536
+ bdbi = bdrv_dirty_iter_new(job->bcs->copy_bitmap);
537
while ((offset = bdrv_dirty_iter_next(bdbi)) != -1) {
538
do {
539
if (yield_and_check(job)) {
540
@@ -XXX,XX +XXX,XX @@ static void backup_init_copy_bitmap(BackupBlockJob *job)
541
uint64_t estimate;
542
543
if (job->sync_mode == MIRROR_SYNC_MODE_BITMAP) {
544
- ret = bdrv_dirty_bitmap_merge_internal(job->copy_bitmap,
545
+ ret = bdrv_dirty_bitmap_merge_internal(job->bcs->copy_bitmap,
546
job->sync_bitmap,
547
NULL, true);
548
assert(ret);
549
@@ -XXX,XX +XXX,XX @@ static void backup_init_copy_bitmap(BackupBlockJob *job)
550
* We can't hog the coroutine to initialize this thoroughly.
551
* Set a flag and resume work when we are able to yield safely.
552
*/
553
- job->initializing_bitmap = true;
554
+ job->bcs->skip_unallocated = true;
555
}
556
- bdrv_set_dirty_bitmap(job->copy_bitmap, 0, job->len);
557
+ bdrv_set_dirty_bitmap(job->bcs->copy_bitmap, 0, job->len);
558
}
559
560
- estimate = bdrv_get_dirty_count(job->copy_bitmap);
561
+ estimate = bdrv_get_dirty_count(job->bcs->copy_bitmap);
562
job_progress_set_remaining(&job->common.job, estimate);
563
}
564
565
static int coroutine_fn backup_run(Job *job, Error **errp)
566
{
567
BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
568
- BlockDriverState *bs = blk_bs(s->common.blk);
569
int ret = 0;
570
571
QLIST_INIT(&s->inflight_reqs);
572
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_run(Job *job, Error **errp)
573
backup_init_copy_bitmap(s);
574
575
s->before_write.notify = backup_before_write_notify;
576
- bdrv_add_before_write_notifier(bs, &s->before_write);
577
+ bdrv_add_before_write_notifier(s->source_bs, &s->before_write);
578
579
if (s->sync_mode == MIRROR_SYNC_MODE_TOP) {
580
int64_t offset = 0;
581
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_run(Job *job, Error **errp)
582
goto out;
583
}
584
585
- ret = backup_bitmap_reset_unallocated(s, offset, &count);
586
+ ret = block_copy_reset_unallocated(s->bcs, offset, &count);
587
if (ret < 0) {
588
goto out;
589
}
590
591
offset += count;
592
}
593
- s->initializing_bitmap = false;
594
+ s->bcs->skip_unallocated = false;
595
}
596
597
if (s->sync_mode == MIRROR_SYNC_MODE_NONE) {
598
@@ -XXX,XX +XXX,XX @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
599
{
600
int64_t len;
601
BackupBlockJob *job = NULL;
602
- int ret;
603
int64_t cluster_size;
604
- BdrvDirtyBitmap *copy_bitmap = NULL;
605
+ BdrvRequestFlags write_flags;
606
607
assert(bs);
608
assert(target);
609
@@ -XXX,XX +XXX,XX @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
610
goto error;
611
}
612
613
- copy_bitmap = bdrv_create_dirty_bitmap(bs, cluster_size, NULL, errp);
614
- if (!copy_bitmap) {
615
- goto error;
616
- }
617
- bdrv_disable_dirty_bitmap(copy_bitmap);
618
-
619
/* job->len is fixed, so we can't allow resize */
620
- job = block_job_create(job_id, &backup_job_driver, txn, bs,
621
- BLK_PERM_CONSISTENT_READ,
622
- BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE |
623
- BLK_PERM_WRITE_UNCHANGED | BLK_PERM_GRAPH_MOD,
624
+ job = block_job_create(job_id, &backup_job_driver, txn, bs, 0, BLK_PERM_ALL,
625
speed, creation_flags, cb, opaque, errp);
626
if (!job) {
627
goto error;
628
}
629
630
- /* The target must match the source in size, so no resize here either */
631
- job->target = blk_new(job->common.job.aio_context,
632
- BLK_PERM_WRITE,
633
- BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE |
634
- BLK_PERM_WRITE_UNCHANGED | BLK_PERM_GRAPH_MOD);
635
- ret = blk_insert_bs(job->target, target, errp);
636
- if (ret < 0) {
637
- goto error;
638
- }
639
- blk_set_disable_request_queuing(job->target, true);
640
-
641
+ job->source_bs = bs;
642
job->on_source_error = on_source_error;
643
job->on_target_error = on_target_error;
644
job->sync_mode = sync_mode;
645
@@ -XXX,XX +XXX,XX @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
646
* For more information see commit f8d59dfb40bb and test
647
* tests/qemu-iotests/222
648
*/
649
- job->write_flags =
650
- (bdrv_chain_contains(target, bs) ? BDRV_REQ_SERIALISING : 0) |
651
- (compress ? BDRV_REQ_WRITE_COMPRESSED : 0);
652
+ write_flags = (bdrv_chain_contains(target, bs) ? BDRV_REQ_SERIALISING : 0) |
653
+ (compress ? BDRV_REQ_WRITE_COMPRESSED : 0),
654
+
655
+ job->bcs = block_copy_state_new(bs, target, cluster_size, write_flags,
656
+ backup_progress_bytes_callback,
657
+ backup_progress_reset_callback, job, errp);
658
+ if (!job->bcs) {
659
+ goto error;
660
+ }
661
662
job->cluster_size = cluster_size;
663
- job->copy_bitmap = copy_bitmap;
664
- copy_bitmap = NULL;
665
- job->copy_range_size = MIN_NON_ZERO(blk_get_max_transfer(job->common.blk),
666
- blk_get_max_transfer(job->target));
667
- job->copy_range_size = QEMU_ALIGN_DOWN(job->copy_range_size,
668
- job->cluster_size);
669
- /*
670
- * Set use_copy_range, consider the following:
671
- * 1. Compression is not supported for copy_range.
672
- * 2. copy_range does not respect max_transfer (it's a TODO), so we factor
673
- * that in here. If max_transfer is smaller than the job->cluster_size,
674
- * we do not use copy_range (in that case it's zero after aligning down
675
- * above).
676
- */
677
- job->use_copy_range = !compress && job->copy_range_size > 0;
678
679
- /* Required permissions are already taken with target's blk_new() */
680
+ /* Required permissions are already taken by block-copy-state target */
681
block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL,
682
&error_abort);
683
job->len = len;
684
@@ -XXX,XX +XXX,XX @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
685
return &job->common;
686
687
error:
688
- if (copy_bitmap) {
689
- assert(!job || !job->copy_bitmap);
690
- bdrv_release_dirty_bitmap(bs, copy_bitmap);
691
- }
692
if (sync_bitmap) {
693
bdrv_reclaim_dirty_bitmap(bs, sync_bitmap, NULL);
694
}
695
diff --git a/block/trace-events b/block/trace-events
696
index XXXXXXX..XXXXXXX 100644
697
--- a/block/trace-events
698
+++ b/block/trace-events
699
@@ -XXX,XX +XXX,XX @@ mirror_yield_in_flight(void *s, int64_t offset, int in_flight) "s %p offset %" P
700
# backup.c
701
backup_do_cow_enter(void *job, int64_t start, int64_t offset, uint64_t bytes) "job %p start %" PRId64 " offset %" PRId64 " bytes %" PRIu64
702
backup_do_cow_return(void *job, int64_t offset, uint64_t bytes, int ret) "job %p offset %" PRId64 " bytes %" PRIu64 " ret %d"
703
-backup_do_cow_skip(void *job, int64_t start) "job %p start %"PRId64
704
-backup_do_cow_skip_range(void *job, int64_t start, uint64_t bytes) "job %p start %"PRId64" bytes %"PRId64
705
-backup_do_cow_process(void *job, int64_t start) "job %p start %"PRId64
706
-backup_do_cow_read_fail(void *job, int64_t start, int ret) "job %p start %"PRId64" ret %d"
707
-backup_do_cow_write_fail(void *job, int64_t start, int ret) "job %p start %"PRId64" ret %d"
708
-backup_do_cow_copy_range_fail(void *job, int64_t start, int ret) "job %p start %"PRId64" ret %d"
709
+block_copy_skip(void *bcs, int64_t start) "bcs %p start %"PRId64
710
+block_copy_skip_range(void *bcs, int64_t start, uint64_t bytes) "bcs %p start %"PRId64" bytes %"PRId64
711
+block_copy_process(void *bcs, int64_t start) "bcs %p start %"PRId64
712
+block_copy_with_bounce_buffer_read_fail(void *bcs, int64_t start, int ret) "bcs %p start %"PRId64" ret %d"
713
+block_copy_with_bounce_buffer_write_fail(void *bcs, int64_t start, int ret) "bcs %p start %"PRId64" ret %d"
714
+block_copy_with_offload_fail(void *bcs, int64_t start, int ret) "bcs %p start %"PRId64" ret %d"
715
716
# ../blockdev.c
717
qmp_block_job_cancel(void *job) "job %p"
718
--
719
2.21.0
720
721
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
We need to fix comment style around block-copy functions before further
4
moving them to separate file to satisfy checkpatch. But do more: fix
5
all comments style. Also, seems like doubled first asterisk is not
6
forbidden, but drop it too for consistency.
7
8
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
Reviewed-by: Max Reitz <mreitz@redhat.com>
10
Message-id: 20190920142056.12778-7-vsementsov@virtuozzo.com
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
---
13
block/backup.c | 32 +++++++++++++++++++++-----------
14
1 file changed, 21 insertions(+), 11 deletions(-)
15
16
diff --git a/block/backup.c b/block/backup.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/backup.c
19
+++ b/block/backup.c
20
@@ -XXX,XX +XXX,XX @@ fail:
21
return NULL;
22
}
23
24
-/* Copy range to target with a bounce buffer and return the bytes copied. If
25
- * error occurred, return a negative error number */
26
+/*
27
+ * Copy range to target with a bounce buffer and return the bytes copied. If
28
+ * error occurred, return a negative error number
29
+ */
30
static int coroutine_fn block_copy_with_bounce_buffer(BlockCopyState *s,
31
int64_t start,
32
int64_t end,
33
@@ -XXX,XX +XXX,XX @@ fail:
34
35
}
36
37
-/* Copy range to target and return the bytes copied. If error occurred, return a
38
- * negative error number. */
39
+/*
40
+ * Copy range to target and return the bytes copied. If error occurred, return a
41
+ * negative error number.
42
+ */
43
static int coroutine_fn block_copy_with_offload(BlockCopyState *s,
44
int64_t start,
45
int64_t end,
46
@@ -XXX,XX +XXX,XX @@ static int block_copy_is_cluster_allocated(BlockCopyState *s, int64_t offset,
47
}
48
}
49
50
-/**
51
+/*
52
* Reset bits in copy_bitmap starting at offset if they represent unallocated
53
* data in the image. May reset subsequent contiguous bits.
54
* @return 0 when the cluster at @offset was unallocated,
55
@@ -XXX,XX +XXX,XX @@ static bool coroutine_fn yield_and_check(BackupBlockJob *job)
56
return true;
57
}
58
59
- /* We need to yield even for delay_ns = 0 so that bdrv_drain_all() can
60
- * return. Without a yield, the VM would not reboot. */
61
+ /*
62
+ * We need to yield even for delay_ns = 0 so that bdrv_drain_all() can
63
+ * return. Without a yield, the VM would not reboot.
64
+ */
65
delay_ns = block_job_ratelimit_get_delay(&job->common, job->bytes_read);
66
job->bytes_read = 0;
67
job_sleep_ns(&job->common.job, delay_ns);
68
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_run(Job *job, Error **errp)
69
}
70
71
if (s->sync_mode == MIRROR_SYNC_MODE_NONE) {
72
- /* All bits are set in copy_bitmap to allow any cluster to be copied.
73
- * This does not actually require them to be copied. */
74
+ /*
75
+ * All bits are set in copy_bitmap to allow any cluster to be copied.
76
+ * This does not actually require them to be copied.
77
+ */
78
while (!job_is_cancelled(job)) {
79
- /* Yield until the job is cancelled. We just let our before_write
80
- * notify callback service CoW requests. */
81
+ /*
82
+ * Yield until the job is cancelled. We just let our before_write
83
+ * notify callback service CoW requests.
84
+ */
85
job_yield(job);
86
}
87
} else {
88
--
89
2.21.0
90
91
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Split block_copy to separate file, to be cleanly shared with backup-top
4
filter driver in further commits.
5
6
It's a clean movement, the only change is drop "static" from interface
7
functions.
8
9
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Reviewed-by: Max Reitz <mreitz@redhat.com>
11
Message-id: 20190920142056.12778-8-vsementsov@virtuozzo.com
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
13
---
14
block/Makefile.objs | 1 +
15
include/block/block-copy.h | 76 ++++++++
16
block/backup.c | 355 +------------------------------------
17
block/block-copy.c | 333 ++++++++++++++++++++++++++++++++++
18
block/trace-events | 2 +
19
5 files changed, 413 insertions(+), 354 deletions(-)
20
create mode 100644 include/block/block-copy.h
21
create mode 100644 block/block-copy.c
22
23
diff --git a/block/Makefile.objs b/block/Makefile.objs
24
index XXXXXXX..XXXXXXX 100644
25
--- a/block/Makefile.objs
26
+++ b/block/Makefile.objs
27
@@ -XXX,XX +XXX,XX @@ block-obj-y += write-threshold.o
28
block-obj-y += backup.o
29
block-obj-$(CONFIG_REPLICATION) += replication.o
30
block-obj-y += throttle.o copy-on-read.o
31
+block-obj-y += block-copy.o
32
33
block-obj-y += crypto.o
34
35
diff --git a/include/block/block-copy.h b/include/block/block-copy.h
36
new file mode 100644
37
index XXXXXXX..XXXXXXX
38
--- /dev/null
39
+++ b/include/block/block-copy.h
40
@@ -XXX,XX +XXX,XX @@
41
+/*
42
+ * block_copy API
43
+ *
44
+ * Copyright (C) 2013 Proxmox Server Solutions
45
+ * Copyright (c) 2019 Virtuozzo International GmbH.
46
+ *
47
+ * Authors:
48
+ * Dietmar Maurer (dietmar@proxmox.com)
49
+ * Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
50
+ *
51
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
52
+ * See the COPYING file in the top-level directory.
53
+ */
54
+
55
+#ifndef BLOCK_COPY_H
56
+#define BLOCK_COPY_H
57
+
58
+#include "block/block.h"
59
+
60
+typedef void (*ProgressBytesCallbackFunc)(int64_t bytes, void *opaque);
61
+typedef void (*ProgressResetCallbackFunc)(void *opaque);
62
+typedef struct BlockCopyState {
63
+ BlockBackend *source;
64
+ BlockBackend *target;
65
+ BdrvDirtyBitmap *copy_bitmap;
66
+ int64_t cluster_size;
67
+ bool use_copy_range;
68
+ int64_t copy_range_size;
69
+ uint64_t len;
70
+
71
+ BdrvRequestFlags write_flags;
72
+
73
+ /*
74
+ * skip_unallocated:
75
+ *
76
+ * Used by sync=top jobs, which first scan the source node for unallocated
77
+ * areas and clear them in the copy_bitmap. During this process, the bitmap
78
+ * is thus not fully initialized: It may still have bits set for areas that
79
+ * are unallocated and should actually not be copied.
80
+ *
81
+ * This is indicated by skip_unallocated.
82
+ *
83
+ * In this case, block_copy() will query the source’s allocation status,
84
+ * skip unallocated regions, clear them in the copy_bitmap, and invoke
85
+ * block_copy_reset_unallocated() every time it does.
86
+ */
87
+ bool skip_unallocated;
88
+
89
+ /* progress_bytes_callback: called when some copying progress is done. */
90
+ ProgressBytesCallbackFunc progress_bytes_callback;
91
+
92
+ /*
93
+ * progress_reset_callback: called when some bytes reset from copy_bitmap
94
+ * (see @skip_unallocated above). The callee is assumed to recalculate how
95
+ * many bytes remain based on the dirty bit count of copy_bitmap.
96
+ */
97
+ ProgressResetCallbackFunc progress_reset_callback;
98
+ void *progress_opaque;
99
+} BlockCopyState;
100
+
101
+BlockCopyState *block_copy_state_new(
102
+ BlockDriverState *source, BlockDriverState *target,
103
+ int64_t cluster_size, BdrvRequestFlags write_flags,
104
+ ProgressBytesCallbackFunc progress_bytes_callback,
105
+ ProgressResetCallbackFunc progress_reset_callback,
106
+ void *progress_opaque, Error **errp);
107
+
108
+void block_copy_state_free(BlockCopyState *s);
109
+
110
+int64_t block_copy_reset_unallocated(BlockCopyState *s,
111
+ int64_t offset, int64_t *count);
112
+
113
+int coroutine_fn block_copy(BlockCopyState *s, int64_t start, uint64_t bytes,
114
+ bool *error_is_read, bool is_write_notifier);
115
+
116
+#endif /* BLOCK_COPY_H */
117
diff --git a/block/backup.c b/block/backup.c
118
index XXXXXXX..XXXXXXX 100644
119
--- a/block/backup.c
120
+++ b/block/backup.c
121
@@ -XXX,XX +XXX,XX @@
122
#include "block/block_int.h"
123
#include "block/blockjob_int.h"
124
#include "block/block_backup.h"
125
+#include "block/block-copy.h"
126
#include "qapi/error.h"
127
#include "qapi/qmp/qerror.h"
128
#include "qemu/ratelimit.h"
129
@@ -XXX,XX +XXX,XX @@ typedef struct CowRequest {
130
CoQueue wait_queue; /* coroutines blocked on this request */
131
} CowRequest;
132
133
-typedef void (*ProgressBytesCallbackFunc)(int64_t bytes, void *opaque);
134
-typedef void (*ProgressResetCallbackFunc)(void *opaque);
135
-typedef struct BlockCopyState {
136
- BlockBackend *source;
137
- BlockBackend *target;
138
- BdrvDirtyBitmap *copy_bitmap;
139
- int64_t cluster_size;
140
- bool use_copy_range;
141
- int64_t copy_range_size;
142
- uint64_t len;
143
-
144
- BdrvRequestFlags write_flags;
145
-
146
- /*
147
- * skip_unallocated:
148
- *
149
- * Used by sync=top jobs, which first scan the source node for unallocated
150
- * areas and clear them in the copy_bitmap. During this process, the bitmap
151
- * is thus not fully initialized: It may still have bits set for areas that
152
- * are unallocated and should actually not be copied.
153
- *
154
- * This is indicated by skip_unallocated.
155
- *
156
- * In this case, block_copy() will query the source’s allocation status,
157
- * skip unallocated regions, clear them in the copy_bitmap, and invoke
158
- * block_copy_reset_unallocated() every time it does.
159
- */
160
- bool skip_unallocated;
161
-
162
- /* progress_bytes_callback: called when some copying progress is done. */
163
- ProgressBytesCallbackFunc progress_bytes_callback;
164
-
165
- /*
166
- * progress_reset_callback: called when some bytes reset from copy_bitmap
167
- * (see @skip_unallocated above). The callee is assumed to recalculate how
168
- * many bytes remain based on the dirty bit count of copy_bitmap.
169
- */
170
- ProgressResetCallbackFunc progress_reset_callback;
171
- void *progress_opaque;
172
-} BlockCopyState;
173
-
174
typedef struct BackupBlockJob {
175
BlockJob common;
176
BlockDriverState *source_bs;
177
@@ -XXX,XX +XXX,XX @@ static void cow_request_end(CowRequest *req)
178
qemu_co_queue_restart_all(&req->wait_queue);
179
}
180
181
-static void block_copy_state_free(BlockCopyState *s)
182
-{
183
- if (!s) {
184
- return;
185
- }
186
-
187
- bdrv_release_dirty_bitmap(blk_bs(s->source), s->copy_bitmap);
188
- blk_unref(s->source);
189
- blk_unref(s->target);
190
- g_free(s);
191
-}
192
-
193
-static BlockCopyState *block_copy_state_new(
194
- BlockDriverState *source, BlockDriverState *target,
195
- int64_t cluster_size, BdrvRequestFlags write_flags,
196
- ProgressBytesCallbackFunc progress_bytes_callback,
197
- ProgressResetCallbackFunc progress_reset_callback,
198
- void *progress_opaque, Error **errp)
199
-{
200
- BlockCopyState *s;
201
- int ret;
202
- uint64_t no_resize = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE |
203
- BLK_PERM_WRITE_UNCHANGED | BLK_PERM_GRAPH_MOD;
204
- BdrvDirtyBitmap *copy_bitmap;
205
-
206
- copy_bitmap = bdrv_create_dirty_bitmap(source, cluster_size, NULL, errp);
207
- if (!copy_bitmap) {
208
- return NULL;
209
- }
210
- bdrv_disable_dirty_bitmap(copy_bitmap);
211
-
212
- s = g_new(BlockCopyState, 1);
213
- *s = (BlockCopyState) {
214
- .source = blk_new(bdrv_get_aio_context(source),
215
- BLK_PERM_CONSISTENT_READ, no_resize),
216
- .target = blk_new(bdrv_get_aio_context(target),
217
- BLK_PERM_WRITE, no_resize),
218
- .copy_bitmap = copy_bitmap,
219
- .cluster_size = cluster_size,
220
- .len = bdrv_dirty_bitmap_size(copy_bitmap),
221
- .write_flags = write_flags,
222
- .progress_bytes_callback = progress_bytes_callback,
223
- .progress_reset_callback = progress_reset_callback,
224
- .progress_opaque = progress_opaque,
225
- };
226
-
227
- s->copy_range_size = QEMU_ALIGN_DOWN(MIN(blk_get_max_transfer(s->source),
228
- blk_get_max_transfer(s->target)),
229
- s->cluster_size);
230
- /*
231
- * Set use_copy_range, consider the following:
232
- * 1. Compression is not supported for copy_range.
233
- * 2. copy_range does not respect max_transfer (it's a TODO), so we factor
234
- * that in here. If max_transfer is smaller than the job->cluster_size,
235
- * we do not use copy_range (in that case it's zero after aligning down
236
- * above).
237
- */
238
- s->use_copy_range =
239
- !(write_flags & BDRV_REQ_WRITE_COMPRESSED) && s->copy_range_size > 0;
240
-
241
- /*
242
- * We just allow aio context change on our block backends. block_copy() user
243
- * (now it's only backup) is responsible for source and target being in same
244
- * aio context.
245
- */
246
- blk_set_disable_request_queuing(s->source, true);
247
- blk_set_allow_aio_context_change(s->source, true);
248
- blk_set_disable_request_queuing(s->target, true);
249
- blk_set_allow_aio_context_change(s->target, true);
250
-
251
- ret = blk_insert_bs(s->source, source, errp);
252
- if (ret < 0) {
253
- goto fail;
254
- }
255
-
256
- ret = blk_insert_bs(s->target, target, errp);
257
- if (ret < 0) {
258
- goto fail;
259
- }
260
-
261
- return s;
262
-
263
-fail:
264
- block_copy_state_free(s);
265
-
266
- return NULL;
267
-}
268
-
269
-/*
270
- * Copy range to target with a bounce buffer and return the bytes copied. If
271
- * error occurred, return a negative error number
272
- */
273
-static int coroutine_fn block_copy_with_bounce_buffer(BlockCopyState *s,
274
- int64_t start,
275
- int64_t end,
276
- bool is_write_notifier,
277
- bool *error_is_read,
278
- void **bounce_buffer)
279
-{
280
- int ret;
281
- int nbytes;
282
- int read_flags = is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0;
283
-
284
- assert(QEMU_IS_ALIGNED(start, s->cluster_size));
285
- bdrv_reset_dirty_bitmap(s->copy_bitmap, start, s->cluster_size);
286
- nbytes = MIN(s->cluster_size, s->len - start);
287
- if (!*bounce_buffer) {
288
- *bounce_buffer = blk_blockalign(s->source, s->cluster_size);
289
- }
290
-
291
- ret = blk_co_pread(s->source, start, nbytes, *bounce_buffer, read_flags);
292
- if (ret < 0) {
293
- trace_block_copy_with_bounce_buffer_read_fail(s, start, ret);
294
- if (error_is_read) {
295
- *error_is_read = true;
296
- }
297
- goto fail;
298
- }
299
-
300
- ret = blk_co_pwrite(s->target, start, nbytes, *bounce_buffer,
301
- s->write_flags);
302
- if (ret < 0) {
303
- trace_block_copy_with_bounce_buffer_write_fail(s, start, ret);
304
- if (error_is_read) {
305
- *error_is_read = false;
306
- }
307
- goto fail;
308
- }
309
-
310
- return nbytes;
311
-fail:
312
- bdrv_set_dirty_bitmap(s->copy_bitmap, start, s->cluster_size);
313
- return ret;
314
-
315
-}
316
-
317
-/*
318
- * Copy range to target and return the bytes copied. If error occurred, return a
319
- * negative error number.
320
- */
321
-static int coroutine_fn block_copy_with_offload(BlockCopyState *s,
322
- int64_t start,
323
- int64_t end,
324
- bool is_write_notifier)
325
-{
326
- int ret;
327
- int nr_clusters;
328
- int nbytes;
329
- int read_flags = is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0;
330
-
331
- assert(QEMU_IS_ALIGNED(s->copy_range_size, s->cluster_size));
332
- assert(QEMU_IS_ALIGNED(start, s->cluster_size));
333
- nbytes = MIN(s->copy_range_size, MIN(end, s->len) - start);
334
- nr_clusters = DIV_ROUND_UP(nbytes, s->cluster_size);
335
- bdrv_reset_dirty_bitmap(s->copy_bitmap, start,
336
- s->cluster_size * nr_clusters);
337
- ret = blk_co_copy_range(s->source, start, s->target, start, nbytes,
338
- read_flags, s->write_flags);
339
- if (ret < 0) {
340
- trace_block_copy_with_offload_fail(s, start, ret);
341
- bdrv_set_dirty_bitmap(s->copy_bitmap, start,
342
- s->cluster_size * nr_clusters);
343
- return ret;
344
- }
345
-
346
- return nbytes;
347
-}
348
-
349
-/*
350
- * Check if the cluster starting at offset is allocated or not.
351
- * return via pnum the number of contiguous clusters sharing this allocation.
352
- */
353
-static int block_copy_is_cluster_allocated(BlockCopyState *s, int64_t offset,
354
- int64_t *pnum)
355
-{
356
- BlockDriverState *bs = blk_bs(s->source);
357
- int64_t count, total_count = 0;
358
- int64_t bytes = s->len - offset;
359
- int ret;
360
-
361
- assert(QEMU_IS_ALIGNED(offset, s->cluster_size));
362
-
363
- while (true) {
364
- ret = bdrv_is_allocated(bs, offset, bytes, &count);
365
- if (ret < 0) {
366
- return ret;
367
- }
368
-
369
- total_count += count;
370
-
371
- if (ret || count == 0) {
372
- /*
373
- * ret: partial segment(s) are considered allocated.
374
- * otherwise: unallocated tail is treated as an entire segment.
375
- */
376
- *pnum = DIV_ROUND_UP(total_count, s->cluster_size);
377
- return ret;
378
- }
379
-
380
- /* Unallocated segment(s) with uncertain following segment(s) */
381
- if (total_count >= s->cluster_size) {
382
- *pnum = total_count / s->cluster_size;
383
- return 0;
384
- }
385
-
386
- offset += count;
387
- bytes -= count;
388
- }
389
-}
390
-
391
-/*
392
- * Reset bits in copy_bitmap starting at offset if they represent unallocated
393
- * data in the image. May reset subsequent contiguous bits.
394
- * @return 0 when the cluster at @offset was unallocated,
395
- * 1 otherwise, and -ret on error.
396
- */
397
-static int64_t block_copy_reset_unallocated(BlockCopyState *s,
398
- int64_t offset, int64_t *count)
399
-{
400
- int ret;
401
- int64_t clusters, bytes;
402
-
403
- ret = block_copy_is_cluster_allocated(s, offset, &clusters);
404
- if (ret < 0) {
405
- return ret;
406
- }
407
-
408
- bytes = clusters * s->cluster_size;
409
-
410
- if (!ret) {
411
- bdrv_reset_dirty_bitmap(s->copy_bitmap, offset, bytes);
412
- s->progress_reset_callback(s->progress_opaque);
413
- }
414
-
415
- *count = bytes;
416
- return ret;
417
-}
418
-
419
-static int coroutine_fn block_copy(BlockCopyState *s,
420
- int64_t start, uint64_t bytes,
421
- bool *error_is_read,
422
- bool is_write_notifier)
423
-{
424
- int ret = 0;
425
- int64_t end = bytes + start; /* bytes */
426
- void *bounce_buffer = NULL;
427
- int64_t status_bytes;
428
-
429
- /*
430
- * block_copy() user is responsible for keeping source and target in same
431
- * aio context
432
- */
433
- assert(blk_get_aio_context(s->source) == blk_get_aio_context(s->target));
434
-
435
- assert(QEMU_IS_ALIGNED(start, s->cluster_size));
436
- assert(QEMU_IS_ALIGNED(end, s->cluster_size));
437
-
438
- while (start < end) {
439
- int64_t dirty_end;
440
-
441
- if (!bdrv_dirty_bitmap_get(s->copy_bitmap, start)) {
442
- trace_block_copy_skip(s, start);
443
- start += s->cluster_size;
444
- continue; /* already copied */
445
- }
446
-
447
- dirty_end = bdrv_dirty_bitmap_next_zero(s->copy_bitmap, start,
448
- (end - start));
449
- if (dirty_end < 0) {
450
- dirty_end = end;
451
- }
452
-
453
- if (s->skip_unallocated) {
454
- ret = block_copy_reset_unallocated(s, start, &status_bytes);
455
- if (ret == 0) {
456
- trace_block_copy_skip_range(s, start, status_bytes);
457
- start += status_bytes;
458
- continue;
459
- }
460
- /* Clamp to known allocated region */
461
- dirty_end = MIN(dirty_end, start + status_bytes);
462
- }
463
-
464
- trace_block_copy_process(s, start);
465
-
466
- if (s->use_copy_range) {
467
- ret = block_copy_with_offload(s, start, dirty_end,
468
- is_write_notifier);
469
- if (ret < 0) {
470
- s->use_copy_range = false;
471
- }
472
- }
473
- if (!s->use_copy_range) {
474
- ret = block_copy_with_bounce_buffer(s, start, dirty_end,
475
- is_write_notifier,
476
- error_is_read, &bounce_buffer);
477
- }
478
- if (ret < 0) {
479
- break;
480
- }
481
-
482
- start += ret;
483
- s->progress_bytes_callback(ret, s->progress_opaque);
484
- ret = 0;
485
- }
486
-
487
- if (bounce_buffer) {
488
- qemu_vfree(bounce_buffer);
489
- }
490
-
491
- return ret;
492
-}
493
-
494
static void backup_progress_bytes_callback(int64_t bytes, void *opaque)
495
{
496
BackupBlockJob *s = opaque;
497
diff --git a/block/block-copy.c b/block/block-copy.c
498
new file mode 100644
499
index XXXXXXX..XXXXXXX
500
--- /dev/null
501
+++ b/block/block-copy.c
502
@@ -XXX,XX +XXX,XX @@
503
+/*
504
+ * block_copy API
505
+ *
506
+ * Copyright (C) 2013 Proxmox Server Solutions
507
+ * Copyright (c) 2019 Virtuozzo International GmbH.
508
+ *
509
+ * Authors:
510
+ * Dietmar Maurer (dietmar@proxmox.com)
511
+ * Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
512
+ *
513
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
514
+ * See the COPYING file in the top-level directory.
515
+ */
516
+
517
+#include "qemu/osdep.h"
518
+
519
+#include "trace.h"
520
+#include "qapi/error.h"
521
+#include "block/block-copy.h"
522
+#include "sysemu/block-backend.h"
523
+
524
+void block_copy_state_free(BlockCopyState *s)
525
+{
526
+ if (!s) {
527
+ return;
528
+ }
529
+
530
+ bdrv_release_dirty_bitmap(blk_bs(s->source), s->copy_bitmap);
531
+ blk_unref(s->source);
532
+ blk_unref(s->target);
533
+ g_free(s);
534
+}
535
+
536
+BlockCopyState *block_copy_state_new(
537
+ BlockDriverState *source, BlockDriverState *target,
538
+ int64_t cluster_size, BdrvRequestFlags write_flags,
539
+ ProgressBytesCallbackFunc progress_bytes_callback,
540
+ ProgressResetCallbackFunc progress_reset_callback,
541
+ void *progress_opaque, Error **errp)
542
+{
543
+ BlockCopyState *s;
544
+ int ret;
545
+ uint64_t no_resize = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE |
546
+ BLK_PERM_WRITE_UNCHANGED | BLK_PERM_GRAPH_MOD;
547
+ BdrvDirtyBitmap *copy_bitmap;
548
+
549
+ copy_bitmap = bdrv_create_dirty_bitmap(source, cluster_size, NULL, errp);
550
+ if (!copy_bitmap) {
551
+ return NULL;
552
+ }
553
+ bdrv_disable_dirty_bitmap(copy_bitmap);
554
+
555
+ s = g_new(BlockCopyState, 1);
556
+ *s = (BlockCopyState) {
557
+ .source = blk_new(bdrv_get_aio_context(source),
558
+ BLK_PERM_CONSISTENT_READ, no_resize),
559
+ .target = blk_new(bdrv_get_aio_context(target),
560
+ BLK_PERM_WRITE, no_resize),
561
+ .copy_bitmap = copy_bitmap,
562
+ .cluster_size = cluster_size,
563
+ .len = bdrv_dirty_bitmap_size(copy_bitmap),
564
+ .write_flags = write_flags,
565
+ .progress_bytes_callback = progress_bytes_callback,
566
+ .progress_reset_callback = progress_reset_callback,
567
+ .progress_opaque = progress_opaque,
568
+ };
569
+
570
+ s->copy_range_size = QEMU_ALIGN_DOWN(MIN(blk_get_max_transfer(s->source),
571
+ blk_get_max_transfer(s->target)),
572
+ s->cluster_size);
573
+ /*
574
+ * Set use_copy_range, consider the following:
575
+ * 1. Compression is not supported for copy_range.
576
+ * 2. copy_range does not respect max_transfer (it's a TODO), so we factor
577
+ * that in here. If max_transfer is smaller than the job->cluster_size,
578
+ * we do not use copy_range (in that case it's zero after aligning down
579
+ * above).
580
+ */
581
+ s->use_copy_range =
582
+ !(write_flags & BDRV_REQ_WRITE_COMPRESSED) && s->copy_range_size > 0;
583
+
584
+ /*
585
+ * We just allow aio context change on our block backends. block_copy() user
586
+ * (now it's only backup) is responsible for source and target being in same
587
+ * aio context.
588
+ */
589
+ blk_set_disable_request_queuing(s->source, true);
590
+ blk_set_allow_aio_context_change(s->source, true);
591
+ blk_set_disable_request_queuing(s->target, true);
592
+ blk_set_allow_aio_context_change(s->target, true);
593
+
594
+ ret = blk_insert_bs(s->source, source, errp);
595
+ if (ret < 0) {
596
+ goto fail;
597
+ }
598
+
599
+ ret = blk_insert_bs(s->target, target, errp);
600
+ if (ret < 0) {
601
+ goto fail;
602
+ }
603
+
604
+ return s;
605
+
606
+fail:
607
+ block_copy_state_free(s);
608
+
609
+ return NULL;
610
+}
611
+
612
+/*
613
+ * Copy range to target with a bounce buffer and return the bytes copied. If
614
+ * error occurred, return a negative error number
615
+ */
616
+static int coroutine_fn block_copy_with_bounce_buffer(BlockCopyState *s,
617
+ int64_t start,
618
+ int64_t end,
619
+ bool is_write_notifier,
620
+ bool *error_is_read,
621
+ void **bounce_buffer)
622
+{
623
+ int ret;
624
+ int nbytes;
625
+ int read_flags = is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0;
626
+
627
+ assert(QEMU_IS_ALIGNED(start, s->cluster_size));
628
+ bdrv_reset_dirty_bitmap(s->copy_bitmap, start, s->cluster_size);
629
+ nbytes = MIN(s->cluster_size, s->len - start);
630
+ if (!*bounce_buffer) {
631
+ *bounce_buffer = blk_blockalign(s->source, s->cluster_size);
632
+ }
633
+
634
+ ret = blk_co_pread(s->source, start, nbytes, *bounce_buffer, read_flags);
635
+ if (ret < 0) {
636
+ trace_block_copy_with_bounce_buffer_read_fail(s, start, ret);
637
+ if (error_is_read) {
638
+ *error_is_read = true;
639
+ }
640
+ goto fail;
641
+ }
642
+
643
+ ret = blk_co_pwrite(s->target, start, nbytes, *bounce_buffer,
644
+ s->write_flags);
645
+ if (ret < 0) {
646
+ trace_block_copy_with_bounce_buffer_write_fail(s, start, ret);
647
+ if (error_is_read) {
648
+ *error_is_read = false;
649
+ }
650
+ goto fail;
651
+ }
652
+
653
+ return nbytes;
654
+fail:
655
+ bdrv_set_dirty_bitmap(s->copy_bitmap, start, s->cluster_size);
656
+ return ret;
657
+
658
+}
659
+
660
+/*
661
+ * Copy range to target and return the bytes copied. If error occurred, return a
662
+ * negative error number.
663
+ */
664
+static int coroutine_fn block_copy_with_offload(BlockCopyState *s,
665
+ int64_t start,
666
+ int64_t end,
667
+ bool is_write_notifier)
668
+{
669
+ int ret;
670
+ int nr_clusters;
671
+ int nbytes;
672
+ int read_flags = is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0;
673
+
674
+ assert(QEMU_IS_ALIGNED(s->copy_range_size, s->cluster_size));
675
+ assert(QEMU_IS_ALIGNED(start, s->cluster_size));
676
+ nbytes = MIN(s->copy_range_size, MIN(end, s->len) - start);
677
+ nr_clusters = DIV_ROUND_UP(nbytes, s->cluster_size);
678
+ bdrv_reset_dirty_bitmap(s->copy_bitmap, start,
679
+ s->cluster_size * nr_clusters);
680
+ ret = blk_co_copy_range(s->source, start, s->target, start, nbytes,
681
+ read_flags, s->write_flags);
682
+ if (ret < 0) {
683
+ trace_block_copy_with_offload_fail(s, start, ret);
684
+ bdrv_set_dirty_bitmap(s->copy_bitmap, start,
685
+ s->cluster_size * nr_clusters);
686
+ return ret;
687
+ }
688
+
689
+ return nbytes;
690
+}
691
+
692
+/*
693
+ * Check if the cluster starting at offset is allocated or not.
694
+ * return via pnum the number of contiguous clusters sharing this allocation.
695
+ */
696
+static int block_copy_is_cluster_allocated(BlockCopyState *s, int64_t offset,
697
+ int64_t *pnum)
698
+{
699
+ BlockDriverState *bs = blk_bs(s->source);
700
+ int64_t count, total_count = 0;
701
+ int64_t bytes = s->len - offset;
702
+ int ret;
703
+
704
+ assert(QEMU_IS_ALIGNED(offset, s->cluster_size));
705
+
706
+ while (true) {
707
+ ret = bdrv_is_allocated(bs, offset, bytes, &count);
708
+ if (ret < 0) {
709
+ return ret;
710
+ }
711
+
712
+ total_count += count;
713
+
714
+ if (ret || count == 0) {
715
+ /*
716
+ * ret: partial segment(s) are considered allocated.
717
+ * otherwise: unallocated tail is treated as an entire segment.
718
+ */
719
+ *pnum = DIV_ROUND_UP(total_count, s->cluster_size);
720
+ return ret;
721
+ }
722
+
723
+ /* Unallocated segment(s) with uncertain following segment(s) */
724
+ if (total_count >= s->cluster_size) {
725
+ *pnum = total_count / s->cluster_size;
726
+ return 0;
727
+ }
728
+
729
+ offset += count;
730
+ bytes -= count;
731
+ }
732
+}
733
+
734
+/*
735
+ * Reset bits in copy_bitmap starting at offset if they represent unallocated
736
+ * data in the image. May reset subsequent contiguous bits.
737
+ * @return 0 when the cluster at @offset was unallocated,
738
+ * 1 otherwise, and -ret on error.
739
+ */
740
+int64_t block_copy_reset_unallocated(BlockCopyState *s,
741
+ int64_t offset, int64_t *count)
742
+{
743
+ int ret;
744
+ int64_t clusters, bytes;
745
+
746
+ ret = block_copy_is_cluster_allocated(s, offset, &clusters);
747
+ if (ret < 0) {
748
+ return ret;
749
+ }
750
+
751
+ bytes = clusters * s->cluster_size;
752
+
753
+ if (!ret) {
754
+ bdrv_reset_dirty_bitmap(s->copy_bitmap, offset, bytes);
755
+ s->progress_reset_callback(s->progress_opaque);
756
+ }
757
+
758
+ *count = bytes;
759
+ return ret;
760
+}
761
+
762
+int coroutine_fn block_copy(BlockCopyState *s,
763
+ int64_t start, uint64_t bytes,
764
+ bool *error_is_read,
765
+ bool is_write_notifier)
766
+{
767
+ int ret = 0;
768
+ int64_t end = bytes + start; /* bytes */
769
+ void *bounce_buffer = NULL;
770
+ int64_t status_bytes;
771
+
772
+ /*
773
+ * block_copy() user is responsible for keeping source and target in same
774
+ * aio context
775
+ */
776
+ assert(blk_get_aio_context(s->source) == blk_get_aio_context(s->target));
777
+
778
+ assert(QEMU_IS_ALIGNED(start, s->cluster_size));
779
+ assert(QEMU_IS_ALIGNED(end, s->cluster_size));
780
+
781
+ while (start < end) {
782
+ int64_t dirty_end;
783
+
784
+ if (!bdrv_dirty_bitmap_get(s->copy_bitmap, start)) {
785
+ trace_block_copy_skip(s, start);
786
+ start += s->cluster_size;
787
+ continue; /* already copied */
788
+ }
789
+
790
+ dirty_end = bdrv_dirty_bitmap_next_zero(s->copy_bitmap, start,
791
+ (end - start));
792
+ if (dirty_end < 0) {
793
+ dirty_end = end;
794
+ }
795
+
796
+ if (s->skip_unallocated) {
797
+ ret = block_copy_reset_unallocated(s, start, &status_bytes);
798
+ if (ret == 0) {
799
+ trace_block_copy_skip_range(s, start, status_bytes);
800
+ start += status_bytes;
801
+ continue;
802
+ }
803
+ /* Clamp to known allocated region */
804
+ dirty_end = MIN(dirty_end, start + status_bytes);
805
+ }
806
+
807
+ trace_block_copy_process(s, start);
808
+
809
+ if (s->use_copy_range) {
810
+ ret = block_copy_with_offload(s, start, dirty_end,
811
+ is_write_notifier);
812
+ if (ret < 0) {
813
+ s->use_copy_range = false;
814
+ }
815
+ }
816
+ if (!s->use_copy_range) {
817
+ ret = block_copy_with_bounce_buffer(s, start, dirty_end,
818
+ is_write_notifier,
819
+ error_is_read, &bounce_buffer);
820
+ }
821
+ if (ret < 0) {
822
+ break;
823
+ }
824
+
825
+ start += ret;
826
+ s->progress_bytes_callback(ret, s->progress_opaque);
827
+ ret = 0;
828
+ }
829
+
830
+ if (bounce_buffer) {
831
+ qemu_vfree(bounce_buffer);
832
+ }
833
+
834
+ return ret;
835
+}
836
diff --git a/block/trace-events b/block/trace-events
837
index XXXXXXX..XXXXXXX 100644
838
--- a/block/trace-events
839
+++ b/block/trace-events
840
@@ -XXX,XX +XXX,XX @@ mirror_yield_in_flight(void *s, int64_t offset, int in_flight) "s %p offset %" P
841
# backup.c
842
backup_do_cow_enter(void *job, int64_t start, int64_t offset, uint64_t bytes) "job %p start %" PRId64 " offset %" PRId64 " bytes %" PRIu64
843
backup_do_cow_return(void *job, int64_t offset, uint64_t bytes, int ret) "job %p offset %" PRId64 " bytes %" PRIu64 " ret %d"
844
+
845
+# block-copy.c
846
block_copy_skip(void *bcs, int64_t start) "bcs %p start %"PRId64
847
block_copy_skip_range(void *bcs, int64_t start, uint64_t bytes) "bcs %p start %"PRId64" bytes %"PRId64
848
block_copy_process(void *bcs, int64_t start) "bcs %p start %"PRId64
849
--
850
2.21.0
851
852
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Teach bdrv_debug_breakpoint and bdrv_debug_remove_breakpoint skip
4
filters with backing. This is needed to implement and use in backup job
5
it's own backup_top filter driver (like mirror already has one), and
6
without this improvement, breakpoint removal will fail at least in 55
7
iotest.
8
9
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Reviewed-by: Max Reitz <mreitz@redhat.com>
11
Message-id: 20190920142056.12778-9-vsementsov@virtuozzo.com
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
13
---
14
block.c | 34 ++++++++++++++++++++++++++--------
15
1 file changed, 26 insertions(+), 8 deletions(-)
16
17
diff --git a/block.c b/block.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block.c
20
+++ b/block.c
21
@@ -XXX,XX +XXX,XX @@ void bdrv_debug_event(BlockDriverState *bs, BlkdebugEvent event)
22
bs->drv->bdrv_debug_event(bs, event);
23
}
24
25
-int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event,
26
- const char *tag)
27
+static BlockDriverState *bdrv_find_debug_node(BlockDriverState *bs)
28
{
29
while (bs && bs->drv && !bs->drv->bdrv_debug_breakpoint) {
30
- bs = bs->file ? bs->file->bs : NULL;
31
+ if (bs->file) {
32
+ bs = bs->file->bs;
33
+ continue;
34
+ }
35
+
36
+ if (bs->drv->is_filter && bs->backing) {
37
+ bs = bs->backing->bs;
38
+ continue;
39
+ }
40
+
41
+ break;
42
}
43
44
if (bs && bs->drv && bs->drv->bdrv_debug_breakpoint) {
45
+ assert(bs->drv->bdrv_debug_remove_breakpoint);
46
+ return bs;
47
+ }
48
+
49
+ return NULL;
50
+}
51
+
52
+int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event,
53
+ const char *tag)
54
+{
55
+ bs = bdrv_find_debug_node(bs);
56
+ if (bs) {
57
return bs->drv->bdrv_debug_breakpoint(bs, event, tag);
58
}
59
60
@@ -XXX,XX +XXX,XX @@ int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event,
61
62
int bdrv_debug_remove_breakpoint(BlockDriverState *bs, const char *tag)
63
{
64
- while (bs && bs->drv && !bs->drv->bdrv_debug_remove_breakpoint) {
65
- bs = bs->file ? bs->file->bs : NULL;
66
- }
67
-
68
- if (bs && bs->drv && bs->drv->bdrv_debug_remove_breakpoint) {
69
+ bs = bdrv_find_debug_node(bs);
70
+ if (bs) {
71
return bs->drv->bdrv_debug_remove_breakpoint(bs, tag);
72
}
73
74
--
75
2.21.0
76
77
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
After backup-top filter appearing it's not possible to see dirty
4
bitmaps in top node, so use node-name instead.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Max Reitz <mreitz@redhat.com>
8
Message-id: 20190920142056.12778-10-vsementsov@virtuozzo.com
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
---
11
tests/qemu-iotests/124 | 83 ++++----
12
tests/qemu-iotests/257 | 49 ++---
13
tests/qemu-iotests/257.out | 364 +++++++++++++---------------------
14
tests/qemu-iotests/iotests.py | 27 +++
15
4 files changed, 219 insertions(+), 304 deletions(-)
16
17
diff --git a/tests/qemu-iotests/124 b/tests/qemu-iotests/124
18
index XXXXXXX..XXXXXXX 100755
19
--- a/tests/qemu-iotests/124
20
+++ b/tests/qemu-iotests/124
21
@@ -XXX,XX +XXX,XX @@ class TestIncrementalBackupBase(iotests.QMPTestCase):
22
# Create a base image with a distinctive patterning
23
drive0 = self.add_node('drive0')
24
self.img_create(drive0['file'], drive0['fmt'])
25
- self.vm.add_drive(drive0['file'])
26
+ self.vm.add_drive(drive0['file'], opts='node-name=node0')
27
self.write_default_pattern(drive0['file'])
28
self.vm.launch()
29
30
@@ -XXX,XX +XXX,XX @@ class TestIncrementalBackup(TestIncrementalBackupBase):
31
('0xfe', '16M', '256k'),
32
('0x64', '32736k', '64k')))
33
# Check the dirty bitmap stats
34
- result = self.vm.qmp('query-block')
35
- self.assert_qmp(result, 'return[0]/dirty-bitmaps[0]/name', 'bitmap0')
36
- self.assert_qmp(result, 'return[0]/dirty-bitmaps[0]/count', 458752)
37
- self.assert_qmp(result, 'return[0]/dirty-bitmaps[0]/granularity', 65536)
38
- self.assert_qmp(result, 'return[0]/dirty-bitmaps[0]/status', 'active')
39
- self.assert_qmp(result, 'return[0]/dirty-bitmaps[0]/persistent', False)
40
+ self.assertTrue(self.vm.check_bitmap_status(
41
+ 'node0', bitmap0.name, {
42
+ 'name': 'bitmap0',
43
+ 'count': 458752,
44
+ 'granularity': 65536,
45
+ 'status': 'active',
46
+ 'persistent': False
47
+ }))
48
49
# Prepare a cluster_size=128k backup target without a backing file.
50
(target, _) = bitmap0.new_target()
51
@@ -XXX,XX +XXX,XX @@ class TestIncrementalBackupBlkdebug(TestIncrementalBackupBase):
52
"""
53
54
drive0 = self.drives[0]
55
- # NB: The blkdebug script here looks for a "flush, read, read" pattern.
56
- # The flush occurs in hmp_io_writes, the first read in device_add, and
57
- # the last read during the block job.
58
+ # NB: The blkdebug script here looks for a "flush, read" pattern.
59
+ # The flush occurs in hmp_io_writes, and the read during the block job.
60
result = self.vm.qmp('blockdev-add',
61
node_name=drive0['id'],
62
driver=drive0['fmt'],
63
@@ -XXX,XX +XXX,XX @@ class TestIncrementalBackupBlkdebug(TestIncrementalBackupBase):
64
'event': 'flush_to_disk',
65
'state': 1,
66
'new_state': 2
67
- },{
68
- 'event': 'read_aio',
69
- 'state': 2,
70
- 'new_state': 3
71
}],
72
'inject-error': [{
73
'event': 'read_aio',
74
'errno': 5,
75
- 'state': 3,
76
+ 'state': 2,
77
'immediately': False,
78
'once': True
79
}],
80
@@ -XXX,XX +XXX,XX @@ class TestIncrementalBackupBlkdebug(TestIncrementalBackupBase):
81
('0xfe', '16M', '256k'),
82
('0x64', '32736k', '64k')))
83
84
- # For the purposes of query-block visibility of bitmaps, add a drive
85
- # frontend after we've written data; otherwise we can't use hmp-io
86
- result = self.vm.qmp("device_add",
87
- id="device0",
88
- drive=drive0['id'],
89
- driver="virtio-blk")
90
- self.assert_qmp(result, 'return', {})
91
-
92
# Bitmap Status Check
93
- query = self.vm.qmp('query-block')
94
- ret = [bmap for bmap in query['return'][0]['dirty-bitmaps']
95
- if bmap.get('name') == bitmap.name][0]
96
- self.assert_qmp(ret, 'count', 458752)
97
- self.assert_qmp(ret, 'granularity', 65536)
98
- self.assert_qmp(ret, 'status', 'active')
99
- self.assert_qmp(ret, 'busy', False)
100
- self.assert_qmp(ret, 'recording', True)
101
+ self.assertTrue(self.vm.check_bitmap_status(
102
+ drive0['id'], bitmap.name, {
103
+ 'count': 458752,
104
+ 'granularity': 65536,
105
+ 'status': 'active',
106
+ 'busy': False,
107
+ 'recording': True
108
+ }))
109
110
# Start backup
111
parent, _ = bitmap.last_target()
112
@@ -XXX,XX +XXX,XX @@ class TestIncrementalBackupBlkdebug(TestIncrementalBackupBase):
113
'operation': 'read'})
114
115
# Bitmap Status Check
116
- query = self.vm.qmp('query-block')
117
- ret = [bmap for bmap in query['return'][0]['dirty-bitmaps']
118
- if bmap.get('name') == bitmap.name][0]
119
- self.assert_qmp(ret, 'count', 458752)
120
- self.assert_qmp(ret, 'granularity', 65536)
121
- self.assert_qmp(ret, 'status', 'frozen')
122
- self.assert_qmp(ret, 'busy', True)
123
- self.assert_qmp(ret, 'recording', True)
124
+ self.assertTrue(self.vm.check_bitmap_status(
125
+ drive0['id'], bitmap.name, {
126
+ 'count': 458752,
127
+ 'granularity': 65536,
128
+ 'status': 'frozen',
129
+ 'busy': True,
130
+ 'recording': True
131
+ }))
132
133
# Resume and check incremental backup for consistency
134
res = self.vm.qmp('block-job-resume', device=bitmap.drive['id'])
135
@@ -XXX,XX +XXX,XX @@ class TestIncrementalBackupBlkdebug(TestIncrementalBackupBase):
136
self.wait_qmp_backup(bitmap.drive['id'])
137
138
# Bitmap Status Check
139
- query = self.vm.qmp('query-block')
140
- ret = [bmap for bmap in query['return'][0]['dirty-bitmaps']
141
- if bmap.get('name') == bitmap.name][0]
142
- self.assert_qmp(ret, 'count', 0)
143
- self.assert_qmp(ret, 'granularity', 65536)
144
- self.assert_qmp(ret, 'status', 'active')
145
- self.assert_qmp(ret, 'busy', False)
146
- self.assert_qmp(ret, 'recording', True)
147
+ self.assertTrue(self.vm.check_bitmap_status(
148
+ drive0['id'], bitmap.name, {
149
+ 'count': 0,
150
+ 'granularity': 65536,
151
+ 'status': 'active',
152
+ 'busy': False,
153
+ 'recording': True
154
+ }))
155
156
# Finalize / Cleanup
157
self.make_reference_backup(bitmap)
158
diff --git a/tests/qemu-iotests/257 b/tests/qemu-iotests/257
159
index XXXXXXX..XXXXXXX 100755
160
--- a/tests/qemu-iotests/257
161
+++ b/tests/qemu-iotests/257
162
@@ -XXX,XX +XXX,XX @@ class Drive:
163
self.size = size
164
self.node = name
165
166
-def query_bitmaps(vm):
167
- res = vm.qmp("query-block")
168
- return {"bitmaps": {device['device'] or device['qdev']:
169
- device.get('dirty-bitmaps', []) for
170
- device in res['return']}}
171
-
172
-def get_bitmap(bitmaps, drivename, name, recording=None):
173
- """
174
- get a specific bitmap from the object returned by query_bitmaps.
175
- :param recording: If specified, filter results by the specified value.
176
- """
177
- for bitmap in bitmaps['bitmaps'][drivename]:
178
- if bitmap.get('name', '') == name:
179
- if recording is None:
180
- return bitmap
181
- elif bitmap.get('recording') == recording:
182
- return bitmap
183
- return None
184
-
185
def blockdev_backup(vm, device, target, sync, **kwargs):
186
# Strip any arguments explicitly nulled by the caller:
187
kwargs = {key: val for key, val in kwargs.items() if val is not None}
188
@@ -XXX,XX +XXX,XX @@ def perform_writes(drive, n):
189
pattern.size)
190
log(cmd)
191
log(drive.vm.hmp_qemu_io(drive.name, cmd))
192
- bitmaps = query_bitmaps(drive.vm)
193
- log(bitmaps, indent=2)
194
+ bitmaps = drive.vm.query_bitmaps()
195
+ log({'bitmaps': bitmaps}, indent=2)
196
log('')
197
return bitmaps
198
199
@@ -XXX,XX +XXX,XX @@ def test_bitmap_sync(bsync_mode, msync_mode='bitmap', failure=None):
200
# 1 - Writes and Reference Backup
201
bitmaps = perform_writes(drive0, 1)
202
ebitmap.dirty_group(1)
203
- bitmap = get_bitmap(bitmaps, drive0.device, 'bitmap0')
204
+ bitmap = vm.get_bitmap(drive0.node, 'bitmap0', bitmaps=bitmaps)
205
ebitmap.compare(bitmap)
206
reference_backup(drive0, 1, fbackup1)
207
208
@@ -XXX,XX +XXX,XX @@ def test_bitmap_sync(bsync_mode, msync_mode='bitmap', failure=None):
209
log('')
210
bitmaps = perform_writes(drive0, 2)
211
# Named bitmap (static, should be unchanged)
212
- ebitmap.compare(get_bitmap(bitmaps, drive0.device, 'bitmap0'))
213
+ ebitmap.compare(vm.get_bitmap(drive0.node, 'bitmap0',
214
+ bitmaps=bitmaps))
215
# Anonymous bitmap (dynamic, shows new writes)
216
anonymous = EmulatedBitmap()
217
anonymous.dirty_group(2)
218
- anonymous.compare(get_bitmap(bitmaps, drive0.device, '',
219
- recording=True))
220
+ anonymous.compare(vm.get_bitmap(drive0.node, '', recording=True,
221
+ bitmaps=bitmaps))
222
223
# Simulate the order in which this will happen:
224
# group 1 gets cleared first, then group two gets written.
225
@@ -XXX,XX +XXX,XX @@ def test_bitmap_sync(bsync_mode, msync_mode='bitmap', failure=None):
226
vm.run_job(job, auto_dismiss=True, auto_finalize=False,
227
pre_finalize=_callback,
228
cancel=(failure == 'simulated'))
229
- bitmaps = query_bitmaps(vm)
230
- log(bitmaps, indent=2)
231
+ bitmaps = vm.query_bitmaps()
232
+ log({'bitmaps': bitmaps}, indent=2)
233
log('')
234
235
if bsync_mode == 'always' and failure == 'intermediate':
236
@@ -XXX,XX +XXX,XX @@ def test_bitmap_sync(bsync_mode, msync_mode='bitmap', failure=None):
237
ebitmap.clear()
238
ebitmap.dirty_bits(range(fail_bit, SIZE // GRANULARITY))
239
240
- ebitmap.compare(get_bitmap(bitmaps, drive0.device, 'bitmap0'))
241
+ ebitmap.compare(vm.get_bitmap(drive0.node, 'bitmap0', bitmaps=bitmaps))
242
243
# 2 - Writes and Reference Backup
244
bitmaps = perform_writes(drive0, 3)
245
ebitmap.dirty_group(3)
246
- ebitmap.compare(get_bitmap(bitmaps, drive0.device, 'bitmap0'))
247
+ ebitmap.compare(vm.get_bitmap(drive0.node, 'bitmap0', bitmaps=bitmaps))
248
reference_backup(drive0, 2, fbackup2)
249
250
# 2 - Bitmap Backup (In failure modes, this is a recovery.)
251
job = backup(drive0, 2, bsync2, "bitmap",
252
bitmap="bitmap0", bitmap_mode=bsync_mode)
253
vm.run_job(job, auto_dismiss=True, auto_finalize=False)
254
- bitmaps = query_bitmaps(vm)
255
- log(bitmaps, indent=2)
256
+ bitmaps = vm.query_bitmaps()
257
+ log({'bitmaps': bitmaps}, indent=2)
258
log('')
259
if bsync_mode != 'never':
260
ebitmap.clear()
261
- ebitmap.compare(get_bitmap(bitmaps, drive0.device, 'bitmap0'))
262
+ ebitmap.compare(vm.get_bitmap(drive0.node, 'bitmap0', bitmaps=bitmaps))
263
264
log('--- Cleanup ---\n')
265
vm.qmp_log("block-dirty-bitmap-remove",
266
node=drive0.name, name="bitmap0")
267
- log(query_bitmaps(vm), indent=2)
268
+ bitmaps = vm.query_bitmaps()
269
+ log({'bitmaps': bitmaps}, indent=2)
270
vm.shutdown()
271
log('')
272
273
diff --git a/tests/qemu-iotests/257.out b/tests/qemu-iotests/257.out
274
index XXXXXXX..XXXXXXX 100644
275
--- a/tests/qemu-iotests/257.out
276
+++ b/tests/qemu-iotests/257.out
277
@@ -XXX,XX +XXX,XX @@ write -P0x6f 0x2000000 0x10000
278
write -P0x76 0x3ff0000 0x10000
279
{"return": ""}
280
{
281
- "bitmaps": {
282
- "device0": []
283
- }
284
+ "bitmaps": {}
285
}
286
287
--- Reference Backup #0 ---
288
@@ -XXX,XX +XXX,XX @@ write -P0x69 0x3fe0000 0x10000
289
{"return": ""}
290
{
291
"bitmaps": {
292
- "device0": [
293
+ "drive0": [
294
{
295
"busy": false,
296
"count": 393216,
297
@@ -XXX,XX +XXX,XX @@ write -P0x67 0x3fe0000 0x20000
298
{"return": ""}
299
{
300
"bitmaps": {
301
- "device0": [
302
+ "drive0": [
303
{
304
"busy": false,
305
"count": 0,
306
@@ -XXX,XX +XXX,XX @@ expecting 7 dirty sectors; have 7. OK!
307
{"data": {"device": "backup_1", "len": 393216, "offset": 393216, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_CANCELLED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
308
{
309
"bitmaps": {
310
- "device0": [
311
+ "drive0": [
312
{
313
"busy": false,
314
"count": 655360,
315
@@ -XXX,XX +XXX,XX @@ write -P0xdd 0x3fc0000 0x10000
316
{"return": ""}
317
{
318
"bitmaps": {
319
- "device0": [
320
+ "drive0": [
321
{
322
"busy": false,
323
"count": 983040,
324
@@ -XXX,XX +XXX,XX @@ expecting 15 dirty sectors; have 15. OK!
325
{"data": {"device": "backup_2", "len": 983040, "offset": 983040, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
326
{
327
"bitmaps": {
328
- "device0": [
329
+ "drive0": [
330
{
331
"busy": false,
332
"count": 983040,
333
@@ -XXX,XX +XXX,XX @@ expecting 15 dirty sectors; have 15. OK!
334
{"execute": "block-dirty-bitmap-remove", "arguments": {"name": "bitmap0", "node": "drive0"}}
335
{"return": {}}
336
{
337
- "bitmaps": {
338
- "device0": []
339
- }
340
+ "bitmaps": {}
341
}
342
343
--- Verification ---
344
@@ -XXX,XX +XXX,XX @@ write -P0x6f 0x2000000 0x10000
345
write -P0x76 0x3ff0000 0x10000
346
{"return": ""}
347
{
348
- "bitmaps": {
349
- "device0": []
350
- }
351
+ "bitmaps": {}
352
}
353
354
--- Reference Backup #0 ---
355
@@ -XXX,XX +XXX,XX @@ write -P0x69 0x3fe0000 0x10000
356
{"return": ""}
357
{
358
"bitmaps": {
359
- "device0": [
360
+ "drive0": [
361
{
362
"busy": false,
363
"count": 393216,
364
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
365
{"data": {"device": "backup_1", "error": "Input/output error", "len": 393216, "offset": 65536, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
366
{
367
"bitmaps": {
368
- "device0": [
369
+ "drive0": [
370
{
371
"busy": false,
372
"count": 393216,
373
@@ -XXX,XX +XXX,XX @@ write -P0xdd 0x3fc0000 0x10000
374
{"return": ""}
375
{
376
"bitmaps": {
377
- "device0": [
378
+ "drive0": [
379
{
380
"busy": false,
381
"count": 917504,
382
@@ -XXX,XX +XXX,XX @@ expecting 14 dirty sectors; have 14. OK!
383
{"data": {"device": "backup_2", "len": 917504, "offset": 917504, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
384
{
385
"bitmaps": {
386
- "device0": [
387
+ "drive0": [
388
{
389
"busy": false,
390
"count": 917504,
391
@@ -XXX,XX +XXX,XX @@ expecting 14 dirty sectors; have 14. OK!
392
{"execute": "block-dirty-bitmap-remove", "arguments": {"name": "bitmap0", "node": "drive0"}}
393
{"return": {}}
394
{
395
- "bitmaps": {
396
- "device0": []
397
- }
398
+ "bitmaps": {}
399
}
400
401
--- Verification ---
402
@@ -XXX,XX +XXX,XX @@ write -P0x6f 0x2000000 0x10000
403
write -P0x76 0x3ff0000 0x10000
404
{"return": ""}
405
{
406
- "bitmaps": {
407
- "device0": []
408
- }
409
+ "bitmaps": {}
410
}
411
412
--- Reference Backup #0 ---
413
@@ -XXX,XX +XXX,XX @@ write -P0x69 0x3fe0000 0x10000
414
{"return": ""}
415
{
416
"bitmaps": {
417
- "device0": [
418
+ "drive0": [
419
{
420
"busy": false,
421
"count": 393216,
422
@@ -XXX,XX +XXX,XX @@ write -P0x67 0x3fe0000 0x20000
423
{"return": ""}
424
{
425
"bitmaps": {
426
- "device0": [
427
+ "drive0": [
428
{
429
"busy": false,
430
"count": 0,
431
@@ -XXX,XX +XXX,XX @@ expecting 7 dirty sectors; have 7. OK!
432
{"data": {"device": "backup_1", "len": 393216, "offset": 393216, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
433
{
434
"bitmaps": {
435
- "device0": [
436
+ "drive0": [
437
{
438
"busy": false,
439
"count": 655360,
440
@@ -XXX,XX +XXX,XX @@ write -P0xdd 0x3fc0000 0x10000
441
{"return": ""}
442
{
443
"bitmaps": {
444
- "device0": [
445
+ "drive0": [
446
{
447
"busy": false,
448
"count": 983040,
449
@@ -XXX,XX +XXX,XX @@ expecting 15 dirty sectors; have 15. OK!
450
{"data": {"device": "backup_2", "len": 983040, "offset": 983040, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
451
{
452
"bitmaps": {
453
- "device0": [
454
+ "drive0": [
455
{
456
"busy": false,
457
"count": 983040,
458
@@ -XXX,XX +XXX,XX @@ expecting 15 dirty sectors; have 15. OK!
459
{"execute": "block-dirty-bitmap-remove", "arguments": {"name": "bitmap0", "node": "drive0"}}
460
{"return": {}}
461
{
462
- "bitmaps": {
463
- "device0": []
464
- }
465
+ "bitmaps": {}
466
}
467
468
--- Verification ---
469
@@ -XXX,XX +XXX,XX @@ write -P0x6f 0x2000000 0x10000
470
write -P0x76 0x3ff0000 0x10000
471
{"return": ""}
472
{
473
- "bitmaps": {
474
- "device0": []
475
- }
476
+ "bitmaps": {}
477
}
478
479
--- Reference Backup #0 ---
480
@@ -XXX,XX +XXX,XX @@ write -P0x69 0x3fe0000 0x10000
481
{"return": ""}
482
{
483
"bitmaps": {
484
- "device0": [
485
+ "drive0": [
486
{
487
"busy": false,
488
"count": 393216,
489
@@ -XXX,XX +XXX,XX @@ write -P0x67 0x3fe0000 0x20000
490
{"return": ""}
491
{
492
"bitmaps": {
493
- "device0": [
494
+ "drive0": [
495
{
496
"busy": false,
497
"count": 0,
498
@@ -XXX,XX +XXX,XX @@ expecting 7 dirty sectors; have 7. OK!
499
{"data": {"device": "backup_1", "len": 393216, "offset": 393216, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_CANCELLED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
500
{
501
"bitmaps": {
502
- "device0": [
503
+ "drive0": [
504
{
505
"busy": false,
506
"count": 655360,
507
@@ -XXX,XX +XXX,XX @@ write -P0xdd 0x3fc0000 0x10000
508
{"return": ""}
509
{
510
"bitmaps": {
511
- "device0": [
512
+ "drive0": [
513
{
514
"busy": false,
515
"count": 983040,
516
@@ -XXX,XX +XXX,XX @@ expecting 15 dirty sectors; have 15. OK!
517
{"data": {"device": "backup_2", "len": 983040, "offset": 983040, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
518
{
519
"bitmaps": {
520
- "device0": [
521
+ "drive0": [
522
{
523
"busy": false,
524
"count": 0,
525
@@ -XXX,XX +XXX,XX @@ expecting 0 dirty sectors; have 0. OK!
526
{"execute": "block-dirty-bitmap-remove", "arguments": {"name": "bitmap0", "node": "drive0"}}
527
{"return": {}}
528
{
529
- "bitmaps": {
530
- "device0": []
531
- }
532
+ "bitmaps": {}
533
}
534
535
--- Verification ---
536
@@ -XXX,XX +XXX,XX @@ write -P0x6f 0x2000000 0x10000
537
write -P0x76 0x3ff0000 0x10000
538
{"return": ""}
539
{
540
- "bitmaps": {
541
- "device0": []
542
- }
543
+ "bitmaps": {}
544
}
545
546
--- Reference Backup #0 ---
547
@@ -XXX,XX +XXX,XX @@ write -P0x69 0x3fe0000 0x10000
548
{"return": ""}
549
{
550
"bitmaps": {
551
- "device0": [
552
+ "drive0": [
553
{
554
"busy": false,
555
"count": 393216,
556
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
557
{"data": {"device": "backup_1", "error": "Input/output error", "len": 393216, "offset": 65536, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
558
{
559
"bitmaps": {
560
- "device0": [
561
+ "drive0": [
562
{
563
"busy": false,
564
"count": 393216,
565
@@ -XXX,XX +XXX,XX @@ write -P0xdd 0x3fc0000 0x10000
566
{"return": ""}
567
{
568
"bitmaps": {
569
- "device0": [
570
+ "drive0": [
571
{
572
"busy": false,
573
"count": 917504,
574
@@ -XXX,XX +XXX,XX @@ expecting 14 dirty sectors; have 14. OK!
575
{"data": {"device": "backup_2", "len": 917504, "offset": 917504, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
576
{
577
"bitmaps": {
578
- "device0": [
579
+ "drive0": [
580
{
581
"busy": false,
582
"count": 0,
583
@@ -XXX,XX +XXX,XX @@ expecting 0 dirty sectors; have 0. OK!
584
{"execute": "block-dirty-bitmap-remove", "arguments": {"name": "bitmap0", "node": "drive0"}}
585
{"return": {}}
586
{
587
- "bitmaps": {
588
- "device0": []
589
- }
590
+ "bitmaps": {}
591
}
592
593
--- Verification ---
594
@@ -XXX,XX +XXX,XX @@ write -P0x6f 0x2000000 0x10000
595
write -P0x76 0x3ff0000 0x10000
596
{"return": ""}
597
{
598
- "bitmaps": {
599
- "device0": []
600
- }
601
+ "bitmaps": {}
602
}
603
604
--- Reference Backup #0 ---
605
@@ -XXX,XX +XXX,XX @@ write -P0x69 0x3fe0000 0x10000
606
{"return": ""}
607
{
608
"bitmaps": {
609
- "device0": [
610
+ "drive0": [
611
{
612
"busy": false,
613
"count": 393216,
614
@@ -XXX,XX +XXX,XX @@ write -P0x67 0x3fe0000 0x20000
615
{"return": ""}
616
{
617
"bitmaps": {
618
- "device0": [
619
+ "drive0": [
620
{
621
"busy": false,
622
"count": 0,
623
@@ -XXX,XX +XXX,XX @@ expecting 7 dirty sectors; have 7. OK!
624
{"data": {"device": "backup_1", "len": 393216, "offset": 393216, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
625
{
626
"bitmaps": {
627
- "device0": [
628
+ "drive0": [
629
{
630
"busy": false,
631
"count": 458752,
632
@@ -XXX,XX +XXX,XX @@ write -P0xdd 0x3fc0000 0x10000
633
{"return": ""}
634
{
635
"bitmaps": {
636
- "device0": [
637
+ "drive0": [
638
{
639
"busy": false,
640
"count": 786432,
641
@@ -XXX,XX +XXX,XX @@ expecting 12 dirty sectors; have 12. OK!
642
{"data": {"device": "backup_2", "len": 786432, "offset": 786432, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
643
{
644
"bitmaps": {
645
- "device0": [
646
+ "drive0": [
647
{
648
"busy": false,
649
"count": 0,
650
@@ -XXX,XX +XXX,XX @@ expecting 0 dirty sectors; have 0. OK!
651
{"execute": "block-dirty-bitmap-remove", "arguments": {"name": "bitmap0", "node": "drive0"}}
652
{"return": {}}
653
{
654
- "bitmaps": {
655
- "device0": []
656
- }
657
+ "bitmaps": {}
658
}
659
660
--- Verification ---
661
@@ -XXX,XX +XXX,XX @@ write -P0x6f 0x2000000 0x10000
662
write -P0x76 0x3ff0000 0x10000
663
{"return": ""}
664
{
665
- "bitmaps": {
666
- "device0": []
667
- }
668
+ "bitmaps": {}
669
}
670
671
--- Reference Backup #0 ---
672
@@ -XXX,XX +XXX,XX @@ write -P0x69 0x3fe0000 0x10000
673
{"return": ""}
674
{
675
"bitmaps": {
676
- "device0": [
677
+ "drive0": [
678
{
679
"busy": false,
680
"count": 393216,
681
@@ -XXX,XX +XXX,XX @@ write -P0x67 0x3fe0000 0x20000
682
{"return": ""}
683
{
684
"bitmaps": {
685
- "device0": [
686
+ "drive0": [
687
{
688
"busy": false,
689
"count": 0,
690
@@ -XXX,XX +XXX,XX @@ expecting 7 dirty sectors; have 7. OK!
691
{"data": {"device": "backup_1", "len": 393216, "offset": 393216, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_CANCELLED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
692
{
693
"bitmaps": {
694
- "device0": [
695
+ "drive0": [
696
{
697
"busy": false,
698
"count": 458752,
699
@@ -XXX,XX +XXX,XX @@ write -P0xdd 0x3fc0000 0x10000
700
{"return": ""}
701
{
702
"bitmaps": {
703
- "device0": [
704
+ "drive0": [
705
{
706
"busy": false,
707
"count": 786432,
708
@@ -XXX,XX +XXX,XX @@ expecting 12 dirty sectors; have 12. OK!
709
{"data": {"device": "backup_2", "len": 786432, "offset": 786432, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
710
{
711
"bitmaps": {
712
- "device0": [
713
+ "drive0": [
714
{
715
"busy": false,
716
"count": 0,
717
@@ -XXX,XX +XXX,XX @@ expecting 0 dirty sectors; have 0. OK!
718
{"execute": "block-dirty-bitmap-remove", "arguments": {"name": "bitmap0", "node": "drive0"}}
719
{"return": {}}
720
{
721
- "bitmaps": {
722
- "device0": []
723
- }
724
+ "bitmaps": {}
725
}
726
727
--- Verification ---
728
@@ -XXX,XX +XXX,XX @@ write -P0x6f 0x2000000 0x10000
729
write -P0x76 0x3ff0000 0x10000
730
{"return": ""}
731
{
732
- "bitmaps": {
733
- "device0": []
734
- }
735
+ "bitmaps": {}
736
}
737
738
--- Reference Backup #0 ---
739
@@ -XXX,XX +XXX,XX @@ write -P0x69 0x3fe0000 0x10000
740
{"return": ""}
741
{
742
"bitmaps": {
743
- "device0": [
744
+ "drive0": [
745
{
746
"busy": false,
747
"count": 393216,
748
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
749
{"data": {"device": "backup_1", "error": "Input/output error", "len": 393216, "offset": 65536, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
750
{
751
"bitmaps": {
752
- "device0": [
753
+ "drive0": [
754
{
755
"busy": false,
756
"count": 327680,
757
@@ -XXX,XX +XXX,XX @@ write -P0xdd 0x3fc0000 0x10000
758
{"return": ""}
759
{
760
"bitmaps": {
761
- "device0": [
762
+ "drive0": [
763
{
764
"busy": false,
765
"count": 851968,
766
@@ -XXX,XX +XXX,XX @@ expecting 13 dirty sectors; have 13. OK!
767
{"data": {"device": "backup_2", "len": 851968, "offset": 851968, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
768
{
769
"bitmaps": {
770
- "device0": [
771
+ "drive0": [
772
{
773
"busy": false,
774
"count": 0,
775
@@ -XXX,XX +XXX,XX @@ expecting 0 dirty sectors; have 0. OK!
776
{"execute": "block-dirty-bitmap-remove", "arguments": {"name": "bitmap0", "node": "drive0"}}
777
{"return": {}}
778
{
779
- "bitmaps": {
780
- "device0": []
781
- }
782
+ "bitmaps": {}
783
}
784
785
--- Verification ---
786
@@ -XXX,XX +XXX,XX @@ write -P0x6f 0x2000000 0x10000
787
write -P0x76 0x3ff0000 0x10000
788
{"return": ""}
789
{
790
- "bitmaps": {
791
- "device0": []
792
- }
793
+ "bitmaps": {}
794
}
795
796
--- Reference Backup #0 ---
797
@@ -XXX,XX +XXX,XX @@ write -P0x69 0x3fe0000 0x10000
798
{"return": ""}
799
{
800
"bitmaps": {
801
- "device0": [
802
+ "drive0": [
803
{
804
"busy": false,
805
"count": 393216,
806
@@ -XXX,XX +XXX,XX @@ write -P0x67 0x3fe0000 0x20000
807
{"return": ""}
808
{
809
"bitmaps": {
810
- "device0": [
811
+ "drive0": [
812
{
813
"busy": false,
814
"count": 0,
815
@@ -XXX,XX +XXX,XX @@ expecting 7 dirty sectors; have 7. OK!
816
{"data": {"device": "backup_1", "len": 393216, "offset": 393216, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
817
{
818
"bitmaps": {
819
- "device0": [
820
+ "drive0": [
821
{
822
"busy": false,
823
"count": 458752,
824
@@ -XXX,XX +XXX,XX @@ write -P0xdd 0x3fc0000 0x10000
825
{"return": ""}
826
{
827
"bitmaps": {
828
- "device0": [
829
+ "drive0": [
830
{
831
"busy": false,
832
"count": 786432,
833
@@ -XXX,XX +XXX,XX @@ expecting 12 dirty sectors; have 12. OK!
834
{"data": {"device": "backup_2", "len": 786432, "offset": 786432, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
835
{
836
"bitmaps": {
837
- "device0": [
838
+ "drive0": [
839
{
840
"busy": false,
841
"count": 0,
842
@@ -XXX,XX +XXX,XX @@ expecting 0 dirty sectors; have 0. OK!
843
{"execute": "block-dirty-bitmap-remove", "arguments": {"name": "bitmap0", "node": "drive0"}}
844
{"return": {}}
845
{
846
- "bitmaps": {
847
- "device0": []
848
- }
849
+ "bitmaps": {}
850
}
851
852
--- Verification ---
853
@@ -XXX,XX +XXX,XX @@ write -P0x6f 0x2000000 0x10000
854
write -P0x76 0x3ff0000 0x10000
855
{"return": ""}
856
{
857
- "bitmaps": {
858
- "device0": []
859
- }
860
+ "bitmaps": {}
861
}
862
863
--- Reference Backup #0 ---
864
@@ -XXX,XX +XXX,XX @@ write -P0x69 0x3fe0000 0x10000
865
{"return": ""}
866
{
867
"bitmaps": {
868
- "device0": [
869
+ "drive0": [
870
{
871
"busy": false,
872
"count": 393216,
873
@@ -XXX,XX +XXX,XX @@ write -P0x67 0x3fe0000 0x20000
874
{"return": ""}
875
{
876
"bitmaps": {
877
- "device0": [
878
+ "drive0": [
879
{
880
"busy": false,
881
"count": 0,
882
@@ -XXX,XX +XXX,XX @@ expecting 7 dirty sectors; have 7. OK!
883
{"data": {"device": "backup_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_CANCELLED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
884
{
885
"bitmaps": {
886
- "device0": [
887
+ "drive0": [
888
{
889
"busy": false,
890
"count": 655360,
891
@@ -XXX,XX +XXX,XX @@ write -P0xdd 0x3fc0000 0x10000
892
{"return": ""}
893
{
894
"bitmaps": {
895
- "device0": [
896
+ "drive0": [
897
{
898
"busy": false,
899
"count": 983040,
900
@@ -XXX,XX +XXX,XX @@ expecting 15 dirty sectors; have 15. OK!
901
{"data": {"device": "backup_2", "len": 983040, "offset": 983040, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
902
{
903
"bitmaps": {
904
- "device0": [
905
+ "drive0": [
906
{
907
"busy": false,
908
"count": 0,
909
@@ -XXX,XX +XXX,XX @@ expecting 0 dirty sectors; have 0. OK!
910
{"execute": "block-dirty-bitmap-remove", "arguments": {"name": "bitmap0", "node": "drive0"}}
911
{"return": {}}
912
{
913
- "bitmaps": {
914
- "device0": []
915
- }
916
+ "bitmaps": {}
917
}
918
919
--- Verification ---
920
@@ -XXX,XX +XXX,XX @@ write -P0x6f 0x2000000 0x10000
921
write -P0x76 0x3ff0000 0x10000
922
{"return": ""}
923
{
924
- "bitmaps": {
925
- "device0": []
926
- }
927
+ "bitmaps": {}
928
}
929
930
--- Reference Backup #0 ---
931
@@ -XXX,XX +XXX,XX @@ write -P0x69 0x3fe0000 0x10000
932
{"return": ""}
933
{
934
"bitmaps": {
935
- "device0": [
936
+ "drive0": [
937
{
938
"busy": false,
939
"count": 393216,
940
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
941
{"data": {"device": "backup_1", "error": "Input/output error", "len": 67108864, "offset": 983040, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
942
{
943
"bitmaps": {
944
- "device0": [
945
+ "drive0": [
946
{
947
"busy": false,
948
"count": 393216,
949
@@ -XXX,XX +XXX,XX @@ write -P0xdd 0x3fc0000 0x10000
950
{"return": ""}
951
{
952
"bitmaps": {
953
- "device0": [
954
+ "drive0": [
955
{
956
"busy": false,
957
"count": 917504,
958
@@ -XXX,XX +XXX,XX @@ expecting 14 dirty sectors; have 14. OK!
959
{"data": {"device": "backup_2", "len": 917504, "offset": 917504, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
960
{
961
"bitmaps": {
962
- "device0": [
963
+ "drive0": [
964
{
965
"busy": false,
966
"count": 0,
967
@@ -XXX,XX +XXX,XX @@ expecting 0 dirty sectors; have 0. OK!
968
{"execute": "block-dirty-bitmap-remove", "arguments": {"name": "bitmap0", "node": "drive0"}}
969
{"return": {}}
970
{
971
- "bitmaps": {
972
- "device0": []
973
- }
974
+ "bitmaps": {}
975
}
976
977
--- Verification ---
978
@@ -XXX,XX +XXX,XX @@ write -P0x6f 0x2000000 0x10000
979
write -P0x76 0x3ff0000 0x10000
980
{"return": ""}
981
{
982
- "bitmaps": {
983
- "device0": []
984
- }
985
+ "bitmaps": {}
986
}
987
988
--- Reference Backup #0 ---
989
@@ -XXX,XX +XXX,XX @@ write -P0x69 0x3fe0000 0x10000
990
{"return": ""}
991
{
992
"bitmaps": {
993
- "device0": [
994
+ "drive0": [
995
{
996
"busy": false,
997
"count": 393216,
998
@@ -XXX,XX +XXX,XX @@ write -P0x67 0x3fe0000 0x20000
999
{"return": ""}
1000
{
1001
"bitmaps": {
1002
- "device0": [
1003
+ "drive0": [
1004
{
1005
"busy": false,
1006
"count": 0,
1007
@@ -XXX,XX +XXX,XX @@ expecting 7 dirty sectors; have 7. OK!
1008
{"data": {"device": "backup_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1009
{
1010
"bitmaps": {
1011
- "device0": [
1012
+ "drive0": [
1013
{
1014
"busy": false,
1015
"count": 458752,
1016
@@ -XXX,XX +XXX,XX @@ write -P0xdd 0x3fc0000 0x10000
1017
{"return": ""}
1018
{
1019
"bitmaps": {
1020
- "device0": [
1021
+ "drive0": [
1022
{
1023
"busy": false,
1024
"count": 786432,
1025
@@ -XXX,XX +XXX,XX @@ expecting 12 dirty sectors; have 12. OK!
1026
{"data": {"device": "backup_2", "len": 786432, "offset": 786432, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1027
{
1028
"bitmaps": {
1029
- "device0": [
1030
+ "drive0": [
1031
{
1032
"busy": false,
1033
"count": 0,
1034
@@ -XXX,XX +XXX,XX @@ expecting 0 dirty sectors; have 0. OK!
1035
{"execute": "block-dirty-bitmap-remove", "arguments": {"name": "bitmap0", "node": "drive0"}}
1036
{"return": {}}
1037
{
1038
- "bitmaps": {
1039
- "device0": []
1040
- }
1041
+ "bitmaps": {}
1042
}
1043
1044
--- Verification ---
1045
@@ -XXX,XX +XXX,XX @@ write -P0x6f 0x2000000 0x10000
1046
write -P0x76 0x3ff0000 0x10000
1047
{"return": ""}
1048
{
1049
- "bitmaps": {
1050
- "device0": []
1051
- }
1052
+ "bitmaps": {}
1053
}
1054
1055
--- Reference Backup #0 ---
1056
@@ -XXX,XX +XXX,XX @@ write -P0x69 0x3fe0000 0x10000
1057
{"return": ""}
1058
{
1059
"bitmaps": {
1060
- "device0": [
1061
+ "drive0": [
1062
{
1063
"busy": false,
1064
"count": 393216,
1065
@@ -XXX,XX +XXX,XX @@ write -P0x67 0x3fe0000 0x20000
1066
{"return": ""}
1067
{
1068
"bitmaps": {
1069
- "device0": [
1070
+ "drive0": [
1071
{
1072
"busy": false,
1073
"count": 0,
1074
@@ -XXX,XX +XXX,XX @@ expecting 7 dirty sectors; have 7. OK!
1075
{"data": {"device": "backup_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_CANCELLED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1076
{
1077
"bitmaps": {
1078
- "device0": [
1079
+ "drive0": [
1080
{
1081
"busy": false,
1082
"count": 458752,
1083
@@ -XXX,XX +XXX,XX @@ write -P0xdd 0x3fc0000 0x10000
1084
{"return": ""}
1085
{
1086
"bitmaps": {
1087
- "device0": [
1088
+ "drive0": [
1089
{
1090
"busy": false,
1091
"count": 786432,
1092
@@ -XXX,XX +XXX,XX @@ expecting 12 dirty sectors; have 12. OK!
1093
{"data": {"device": "backup_2", "len": 786432, "offset": 786432, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1094
{
1095
"bitmaps": {
1096
- "device0": [
1097
+ "drive0": [
1098
{
1099
"busy": false,
1100
"count": 0,
1101
@@ -XXX,XX +XXX,XX @@ expecting 0 dirty sectors; have 0. OK!
1102
{"execute": "block-dirty-bitmap-remove", "arguments": {"name": "bitmap0", "node": "drive0"}}
1103
{"return": {}}
1104
{
1105
- "bitmaps": {
1106
- "device0": []
1107
- }
1108
+ "bitmaps": {}
1109
}
1110
1111
--- Verification ---
1112
@@ -XXX,XX +XXX,XX @@ write -P0x6f 0x2000000 0x10000
1113
write -P0x76 0x3ff0000 0x10000
1114
{"return": ""}
1115
{
1116
- "bitmaps": {
1117
- "device0": []
1118
- }
1119
+ "bitmaps": {}
1120
}
1121
1122
--- Reference Backup #0 ---
1123
@@ -XXX,XX +XXX,XX @@ write -P0x69 0x3fe0000 0x10000
1124
{"return": ""}
1125
{
1126
"bitmaps": {
1127
- "device0": [
1128
+ "drive0": [
1129
{
1130
"busy": false,
1131
"count": 393216,
1132
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1133
{"data": {"device": "backup_1", "error": "Input/output error", "len": 67108864, "offset": 983040, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1134
{
1135
"bitmaps": {
1136
- "device0": [
1137
+ "drive0": [
1138
{
1139
"busy": false,
1140
"count": 66125824,
1141
@@ -XXX,XX +XXX,XX @@ write -P0xdd 0x3fc0000 0x10000
1142
{"return": ""}
1143
{
1144
"bitmaps": {
1145
- "device0": [
1146
+ "drive0": [
1147
{
1148
"busy": false,
1149
"count": 66453504,
1150
@@ -XXX,XX +XXX,XX @@ expecting 1014 dirty sectors; have 1014. OK!
1151
{"data": {"device": "backup_2", "len": 66453504, "offset": 66453504, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1152
{
1153
"bitmaps": {
1154
- "device0": [
1155
+ "drive0": [
1156
{
1157
"busy": false,
1158
"count": 0,
1159
@@ -XXX,XX +XXX,XX @@ expecting 0 dirty sectors; have 0. OK!
1160
{"execute": "block-dirty-bitmap-remove", "arguments": {"name": "bitmap0", "node": "drive0"}}
1161
{"return": {}}
1162
{
1163
- "bitmaps": {
1164
- "device0": []
1165
- }
1166
+ "bitmaps": {}
1167
}
1168
1169
--- Verification ---
1170
@@ -XXX,XX +XXX,XX @@ write -P0x6f 0x2000000 0x10000
1171
write -P0x76 0x3ff0000 0x10000
1172
{"return": ""}
1173
{
1174
- "bitmaps": {
1175
- "device0": []
1176
- }
1177
+ "bitmaps": {}
1178
}
1179
1180
--- Reference Backup #0 ---
1181
@@ -XXX,XX +XXX,XX @@ write -P0x69 0x3fe0000 0x10000
1182
{"return": ""}
1183
{
1184
"bitmaps": {
1185
- "device0": [
1186
+ "drive0": [
1187
{
1188
"busy": false,
1189
"count": 393216,
1190
@@ -XXX,XX +XXX,XX @@ write -P0x67 0x3fe0000 0x20000
1191
{"return": ""}
1192
{
1193
"bitmaps": {
1194
- "device0": [
1195
+ "drive0": [
1196
{
1197
"busy": false,
1198
"count": 0,
1199
@@ -XXX,XX +XXX,XX @@ expecting 7 dirty sectors; have 7. OK!
1200
{"data": {"device": "backup_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1201
{
1202
"bitmaps": {
1203
- "device0": [
1204
+ "drive0": [
1205
{
1206
"busy": false,
1207
"count": 458752,
1208
@@ -XXX,XX +XXX,XX @@ write -P0xdd 0x3fc0000 0x10000
1209
{"return": ""}
1210
{
1211
"bitmaps": {
1212
- "device0": [
1213
+ "drive0": [
1214
{
1215
"busy": false,
1216
"count": 786432,
1217
@@ -XXX,XX +XXX,XX @@ expecting 12 dirty sectors; have 12. OK!
1218
{"data": {"device": "backup_2", "len": 786432, "offset": 786432, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1219
{
1220
"bitmaps": {
1221
- "device0": [
1222
+ "drive0": [
1223
{
1224
"busy": false,
1225
"count": 0,
1226
@@ -XXX,XX +XXX,XX @@ expecting 0 dirty sectors; have 0. OK!
1227
{"execute": "block-dirty-bitmap-remove", "arguments": {"name": "bitmap0", "node": "drive0"}}
1228
{"return": {}}
1229
{
1230
- "bitmaps": {
1231
- "device0": []
1232
- }
1233
+ "bitmaps": {}
1234
}
1235
1236
--- Verification ---
1237
@@ -XXX,XX +XXX,XX @@ write -P0x6f 0x2000000 0x10000
1238
write -P0x76 0x3ff0000 0x10000
1239
{"return": ""}
1240
{
1241
- "bitmaps": {
1242
- "device0": []
1243
- }
1244
+ "bitmaps": {}
1245
}
1246
1247
--- Reference Backup #0 ---
1248
@@ -XXX,XX +XXX,XX @@ write -P0x69 0x3fe0000 0x10000
1249
{"return": ""}
1250
{
1251
"bitmaps": {
1252
- "device0": [
1253
+ "drive0": [
1254
{
1255
"busy": false,
1256
"count": 393216,
1257
@@ -XXX,XX +XXX,XX @@ write -P0x67 0x3fe0000 0x20000
1258
{"return": ""}
1259
{
1260
"bitmaps": {
1261
- "device0": [
1262
+ "drive0": [
1263
{
1264
"busy": false,
1265
"count": 0,
1266
@@ -XXX,XX +XXX,XX @@ expecting 7 dirty sectors; have 7. OK!
1267
{"data": {"device": "backup_1", "len": 458752, "offset": 458752, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_CANCELLED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1268
{
1269
"bitmaps": {
1270
- "device0": [
1271
+ "drive0": [
1272
{
1273
"busy": false,
1274
"count": 655360,
1275
@@ -XXX,XX +XXX,XX @@ write -P0xdd 0x3fc0000 0x10000
1276
{"return": ""}
1277
{
1278
"bitmaps": {
1279
- "device0": [
1280
+ "drive0": [
1281
{
1282
"busy": false,
1283
"count": 983040,
1284
@@ -XXX,XX +XXX,XX @@ expecting 15 dirty sectors; have 15. OK!
1285
{"data": {"device": "backup_2", "len": 983040, "offset": 983040, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1286
{
1287
"bitmaps": {
1288
- "device0": [
1289
+ "drive0": [
1290
{
1291
"busy": false,
1292
"count": 0,
1293
@@ -XXX,XX +XXX,XX @@ expecting 0 dirty sectors; have 0. OK!
1294
{"execute": "block-dirty-bitmap-remove", "arguments": {"name": "bitmap0", "node": "drive0"}}
1295
{"return": {}}
1296
{
1297
- "bitmaps": {
1298
- "device0": []
1299
- }
1300
+ "bitmaps": {}
1301
}
1302
1303
--- Verification ---
1304
@@ -XXX,XX +XXX,XX @@ write -P0x6f 0x2000000 0x10000
1305
write -P0x76 0x3ff0000 0x10000
1306
{"return": ""}
1307
{
1308
- "bitmaps": {
1309
- "device0": []
1310
- }
1311
+ "bitmaps": {}
1312
}
1313
1314
--- Reference Backup #0 ---
1315
@@ -XXX,XX +XXX,XX @@ write -P0x69 0x3fe0000 0x10000
1316
{"return": ""}
1317
{
1318
"bitmaps": {
1319
- "device0": [
1320
+ "drive0": [
1321
{
1322
"busy": false,
1323
"count": 393216,
1324
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1325
{"data": {"device": "backup_1", "error": "Input/output error", "len": 458752, "offset": 65536, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1326
{
1327
"bitmaps": {
1328
- "device0": [
1329
+ "drive0": [
1330
{
1331
"busy": false,
1332
"count": 393216,
1333
@@ -XXX,XX +XXX,XX @@ write -P0xdd 0x3fc0000 0x10000
1334
{"return": ""}
1335
{
1336
"bitmaps": {
1337
- "device0": [
1338
+ "drive0": [
1339
{
1340
"busy": false,
1341
"count": 917504,
1342
@@ -XXX,XX +XXX,XX @@ expecting 14 dirty sectors; have 14. OK!
1343
{"data": {"device": "backup_2", "len": 917504, "offset": 917504, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1344
{
1345
"bitmaps": {
1346
- "device0": [
1347
+ "drive0": [
1348
{
1349
"busy": false,
1350
"count": 0,
1351
@@ -XXX,XX +XXX,XX @@ expecting 0 dirty sectors; have 0. OK!
1352
{"execute": "block-dirty-bitmap-remove", "arguments": {"name": "bitmap0", "node": "drive0"}}
1353
{"return": {}}
1354
{
1355
- "bitmaps": {
1356
- "device0": []
1357
- }
1358
+ "bitmaps": {}
1359
}
1360
1361
--- Verification ---
1362
@@ -XXX,XX +XXX,XX @@ write -P0x6f 0x2000000 0x10000
1363
write -P0x76 0x3ff0000 0x10000
1364
{"return": ""}
1365
{
1366
- "bitmaps": {
1367
- "device0": []
1368
- }
1369
+ "bitmaps": {}
1370
}
1371
1372
--- Reference Backup #0 ---
1373
@@ -XXX,XX +XXX,XX @@ write -P0x69 0x3fe0000 0x10000
1374
{"return": ""}
1375
{
1376
"bitmaps": {
1377
- "device0": [
1378
+ "drive0": [
1379
{
1380
"busy": false,
1381
"count": 393216,
1382
@@ -XXX,XX +XXX,XX @@ write -P0x67 0x3fe0000 0x20000
1383
{"return": ""}
1384
{
1385
"bitmaps": {
1386
- "device0": [
1387
+ "drive0": [
1388
{
1389
"busy": false,
1390
"count": 0,
1391
@@ -XXX,XX +XXX,XX @@ expecting 7 dirty sectors; have 7. OK!
1392
{"data": {"device": "backup_1", "len": 458752, "offset": 458752, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1393
{
1394
"bitmaps": {
1395
- "device0": [
1396
+ "drive0": [
1397
{
1398
"busy": false,
1399
"count": 458752,
1400
@@ -XXX,XX +XXX,XX @@ write -P0xdd 0x3fc0000 0x10000
1401
{"return": ""}
1402
{
1403
"bitmaps": {
1404
- "device0": [
1405
+ "drive0": [
1406
{
1407
"busy": false,
1408
"count": 786432,
1409
@@ -XXX,XX +XXX,XX @@ expecting 12 dirty sectors; have 12. OK!
1410
{"data": {"device": "backup_2", "len": 786432, "offset": 786432, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1411
{
1412
"bitmaps": {
1413
- "device0": [
1414
+ "drive0": [
1415
{
1416
"busy": false,
1417
"count": 0,
1418
@@ -XXX,XX +XXX,XX @@ expecting 0 dirty sectors; have 0. OK!
1419
{"execute": "block-dirty-bitmap-remove", "arguments": {"name": "bitmap0", "node": "drive0"}}
1420
{"return": {}}
1421
{
1422
- "bitmaps": {
1423
- "device0": []
1424
- }
1425
+ "bitmaps": {}
1426
}
1427
1428
--- Verification ---
1429
@@ -XXX,XX +XXX,XX @@ write -P0x6f 0x2000000 0x10000
1430
write -P0x76 0x3ff0000 0x10000
1431
{"return": ""}
1432
{
1433
- "bitmaps": {
1434
- "device0": []
1435
- }
1436
+ "bitmaps": {}
1437
}
1438
1439
--- Reference Backup #0 ---
1440
@@ -XXX,XX +XXX,XX @@ write -P0x69 0x3fe0000 0x10000
1441
{"return": ""}
1442
{
1443
"bitmaps": {
1444
- "device0": [
1445
+ "drive0": [
1446
{
1447
"busy": false,
1448
"count": 393216,
1449
@@ -XXX,XX +XXX,XX @@ write -P0x67 0x3fe0000 0x20000
1450
{"return": ""}
1451
{
1452
"bitmaps": {
1453
- "device0": [
1454
+ "drive0": [
1455
{
1456
"busy": false,
1457
"count": 0,
1458
@@ -XXX,XX +XXX,XX @@ expecting 7 dirty sectors; have 7. OK!
1459
{"data": {"device": "backup_1", "len": 458752, "offset": 458752, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_CANCELLED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1460
{
1461
"bitmaps": {
1462
- "device0": [
1463
+ "drive0": [
1464
{
1465
"busy": false,
1466
"count": 458752,
1467
@@ -XXX,XX +XXX,XX @@ write -P0xdd 0x3fc0000 0x10000
1468
{"return": ""}
1469
{
1470
"bitmaps": {
1471
- "device0": [
1472
+ "drive0": [
1473
{
1474
"busy": false,
1475
"count": 786432,
1476
@@ -XXX,XX +XXX,XX @@ expecting 12 dirty sectors; have 12. OK!
1477
{"data": {"device": "backup_2", "len": 786432, "offset": 786432, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1478
{
1479
"bitmaps": {
1480
- "device0": [
1481
+ "drive0": [
1482
{
1483
"busy": false,
1484
"count": 0,
1485
@@ -XXX,XX +XXX,XX @@ expecting 0 dirty sectors; have 0. OK!
1486
{"execute": "block-dirty-bitmap-remove", "arguments": {"name": "bitmap0", "node": "drive0"}}
1487
{"return": {}}
1488
{
1489
- "bitmaps": {
1490
- "device0": []
1491
- }
1492
+ "bitmaps": {}
1493
}
1494
1495
--- Verification ---
1496
@@ -XXX,XX +XXX,XX @@ write -P0x6f 0x2000000 0x10000
1497
write -P0x76 0x3ff0000 0x10000
1498
{"return": ""}
1499
{
1500
- "bitmaps": {
1501
- "device0": []
1502
- }
1503
+ "bitmaps": {}
1504
}
1505
1506
--- Reference Backup #0 ---
1507
@@ -XXX,XX +XXX,XX @@ write -P0x69 0x3fe0000 0x10000
1508
{"return": ""}
1509
{
1510
"bitmaps": {
1511
- "device0": [
1512
+ "drive0": [
1513
{
1514
"busy": false,
1515
"count": 393216,
1516
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1517
{"data": {"device": "backup_1", "error": "Input/output error", "len": 458752, "offset": 65536, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1518
{
1519
"bitmaps": {
1520
- "device0": [
1521
+ "drive0": [
1522
{
1523
"busy": false,
1524
"count": 393216,
1525
@@ -XXX,XX +XXX,XX @@ write -P0xdd 0x3fc0000 0x10000
1526
{"return": ""}
1527
{
1528
"bitmaps": {
1529
- "device0": [
1530
+ "drive0": [
1531
{
1532
"busy": false,
1533
"count": 917504,
1534
@@ -XXX,XX +XXX,XX @@ expecting 14 dirty sectors; have 14. OK!
1535
{"data": {"device": "backup_2", "len": 917504, "offset": 917504, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1536
{
1537
"bitmaps": {
1538
- "device0": [
1539
+ "drive0": [
1540
{
1541
"busy": false,
1542
"count": 0,
1543
@@ -XXX,XX +XXX,XX @@ expecting 0 dirty sectors; have 0. OK!
1544
{"execute": "block-dirty-bitmap-remove", "arguments": {"name": "bitmap0", "node": "drive0"}}
1545
{"return": {}}
1546
{
1547
- "bitmaps": {
1548
- "device0": []
1549
- }
1550
+ "bitmaps": {}
1551
}
1552
1553
--- Verification ---
1554
@@ -XXX,XX +XXX,XX @@ write -P0x6f 0x2000000 0x10000
1555
write -P0x76 0x3ff0000 0x10000
1556
{"return": ""}
1557
{
1558
- "bitmaps": {
1559
- "device0": []
1560
- }
1561
+ "bitmaps": {}
1562
}
1563
1564
--- Reference Backup #0 ---
1565
@@ -XXX,XX +XXX,XX @@ write -P0x69 0x3fe0000 0x10000
1566
{"return": ""}
1567
{
1568
"bitmaps": {
1569
- "device0": [
1570
+ "drive0": [
1571
{
1572
"busy": false,
1573
"count": 393216,
1574
@@ -XXX,XX +XXX,XX @@ write -P0x67 0x3fe0000 0x20000
1575
{"return": ""}
1576
{
1577
"bitmaps": {
1578
- "device0": [
1579
+ "drive0": [
1580
{
1581
"busy": false,
1582
"count": 0,
1583
@@ -XXX,XX +XXX,XX @@ expecting 7 dirty sectors; have 7. OK!
1584
{"data": {"device": "backup_1", "len": 458752, "offset": 458752, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1585
{
1586
"bitmaps": {
1587
- "device0": [
1588
+ "drive0": [
1589
{
1590
"busy": false,
1591
"count": 458752,
1592
@@ -XXX,XX +XXX,XX @@ write -P0xdd 0x3fc0000 0x10000
1593
{"return": ""}
1594
{
1595
"bitmaps": {
1596
- "device0": [
1597
+ "drive0": [
1598
{
1599
"busy": false,
1600
"count": 786432,
1601
@@ -XXX,XX +XXX,XX @@ expecting 12 dirty sectors; have 12. OK!
1602
{"data": {"device": "backup_2", "len": 786432, "offset": 786432, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1603
{
1604
"bitmaps": {
1605
- "device0": [
1606
+ "drive0": [
1607
{
1608
"busy": false,
1609
"count": 0,
1610
@@ -XXX,XX +XXX,XX @@ expecting 0 dirty sectors; have 0. OK!
1611
{"execute": "block-dirty-bitmap-remove", "arguments": {"name": "bitmap0", "node": "drive0"}}
1612
{"return": {}}
1613
{
1614
- "bitmaps": {
1615
- "device0": []
1616
- }
1617
+ "bitmaps": {}
1618
}
1619
1620
--- Verification ---
1621
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
1622
index XXXXXXX..XXXXXXX 100644
1623
--- a/tests/qemu-iotests/iotests.py
1624
+++ b/tests/qemu-iotests/iotests.py
1625
@@ -XXX,XX +XXX,XX @@ class VM(qtest.QEMUQtestMachine):
1626
return x
1627
return None
1628
1629
+ def query_bitmaps(self):
1630
+ res = self.qmp("query-named-block-nodes")
1631
+ return {device['node-name']: device['dirty-bitmaps']
1632
+ for device in res['return'] if 'dirty-bitmaps' in device}
1633
+
1634
+ def get_bitmap(self, node_name, bitmap_name, recording=None, bitmaps=None):
1635
+ """
1636
+ get a specific bitmap from the object returned by query_bitmaps.
1637
+ :param recording: If specified, filter results by the specified value.
1638
+ :param bitmaps: If specified, use it instead of call query_bitmaps()
1639
+ """
1640
+ if bitmaps is None:
1641
+ bitmaps = self.query_bitmaps()
1642
+
1643
+ for bitmap in bitmaps[node_name]:
1644
+ if bitmap.get('name', '') == bitmap_name:
1645
+ if recording is None:
1646
+ return bitmap
1647
+ elif bitmap.get('recording') == recording:
1648
+ return bitmap
1649
+ return None
1650
+
1651
+ def check_bitmap_status(self, node_name, bitmap_name, fields):
1652
+ ret = self.get_bitmap(node_name, bitmap_name)
1653
+
1654
+ return fields.items() <= ret.items()
1655
+
1656
1657
index_re = re.compile(r'([^\[]+)\[([^\]]+)\]')
1658
1659
--
1660
2.21.0
1661
1662
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
After previous commit Drive.device is actually unused. Drop it together
4
with .name property. While being here reuse .node in qmp commands
5
instead of writing 'drive0' twice.
6
7
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
Message-id: 20190920142056.12778-11-vsementsov@virtuozzo.com
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
---
12
tests/qemu-iotests/257 | 37 +++++++++++++++----------------------
13
1 file changed, 15 insertions(+), 22 deletions(-)
14
15
diff --git a/tests/qemu-iotests/257 b/tests/qemu-iotests/257
16
index XXXXXXX..XXXXXXX 100755
17
--- a/tests/qemu-iotests/257
18
+++ b/tests/qemu-iotests/257
19
@@ -XXX,XX +XXX,XX @@ class Drive:
20
self.fmt = None
21
self.size = None
22
self.node = None
23
- self.device = None
24
-
25
- @property
26
- def name(self):
27
- return self.node or self.device
28
29
def img_create(self, fmt, size):
30
self.fmt = fmt
31
@@ -XXX,XX +XXX,XX @@ def blockdev_backup(vm, device, target, sync, **kwargs):
32
def blockdev_backup_mktarget(drive, target_id, filepath, sync, **kwargs):
33
target_drive = Drive(filepath, vm=drive.vm)
34
target_drive.create_target(target_id, drive.fmt, drive.size)
35
- blockdev_backup(drive.vm, drive.name, target_id, sync, **kwargs)
36
+ blockdev_backup(drive.vm, drive.node, target_id, sync, **kwargs)
37
38
def reference_backup(drive, n, filepath):
39
log("--- Reference Backup #{:d} ---\n".format(n))
40
@@ -XXX,XX +XXX,XX @@ def perform_writes(drive, n):
41
pattern.offset,
42
pattern.size)
43
log(cmd)
44
- log(drive.vm.hmp_qemu_io(drive.name, cmd))
45
+ log(drive.vm.hmp_qemu_io(drive.node, cmd))
46
bitmaps = drive.vm.query_bitmaps()
47
log({'bitmaps': bitmaps}, indent=2)
48
log('')
49
@@ -XXX,XX +XXX,XX @@ def test_bitmap_sync(bsync_mode, msync_mode='bitmap', failure=None):
50
}]
51
}
52
53
+ drive0.node = 'drive0'
54
vm.qmp_log('blockdev-add',
55
filters=[iotests.filter_qmp_testfiles],
56
- node_name="drive0",
57
+ node_name=drive0.node,
58
driver=drive0.fmt,
59
file=file_config)
60
- drive0.node = 'drive0'
61
- drive0.device = 'device0'
62
# Use share-rw to allow writes directly to the node;
63
# The anonymous block-backend for this configuration prevents us
64
# from using HMP's qemu-io commands to address the device.
65
- vm.qmp_log("device_add", id=drive0.device,
66
- drive=drive0.name, driver="scsi-hd",
67
+ vm.qmp_log("device_add", id='device0',
68
+ drive=drive0.node, driver="scsi-hd",
69
share_rw=True)
70
log('')
71
72
@@ -XXX,XX +XXX,XX @@ def test_bitmap_sync(bsync_mode, msync_mode='bitmap', failure=None):
73
perform_writes(drive0, 0)
74
reference_backup(drive0, 0, fbackup0)
75
log('--- Add Bitmap ---\n')
76
- vm.qmp_log("block-dirty-bitmap-add", node=drive0.name,
77
+ vm.qmp_log("block-dirty-bitmap-add", node=drive0.node,
78
name="bitmap0", granularity=GRANULARITY)
79
log('')
80
ebitmap = EmulatedBitmap()
81
@@ -XXX,XX +XXX,XX @@ def test_bitmap_sync(bsync_mode, msync_mode='bitmap', failure=None):
82
# 1 - Test Backup (w/ Optional induced failure)
83
if failure == 'intermediate':
84
# Activate blkdebug induced failure for second-to-next read
85
- log(vm.hmp_qemu_io(drive0.name, 'flush'))
86
+ log(vm.hmp_qemu_io(drive0.node, 'flush'))
87
log('')
88
job = backup(drive0, 1, bsync1, msync_mode,
89
bitmap="bitmap0", bitmap_mode=bsync_mode)
90
@@ -XXX,XX +XXX,XX @@ def test_bitmap_sync(bsync_mode, msync_mode='bitmap', failure=None):
91
92
log('--- Cleanup ---\n')
93
vm.qmp_log("block-dirty-bitmap-remove",
94
- node=drive0.name, name="bitmap0")
95
+ node=drive0.node, name="bitmap0")
96
bitmaps = vm.query_bitmaps()
97
log({'bitmaps': bitmaps}, indent=2)
98
vm.shutdown()
99
@@ -XXX,XX +XXX,XX @@ def test_backup_api():
100
'filename': drive0.path
101
}
102
103
+ drive0.node = 'drive0'
104
vm.qmp_log('blockdev-add',
105
filters=[iotests.filter_qmp_testfiles],
106
- node_name="drive0",
107
+ node_name=drive0.node,
108
driver=drive0.fmt,
109
file=file_config)
110
- drive0.node = 'drive0'
111
- drive0.device = 'device0'
112
- vm.qmp_log("device_add", id=drive0.device,
113
- drive=drive0.name, driver="scsi-hd")
114
+ vm.qmp_log("device_add", id='device0',
115
+ drive=drive0.node, driver="scsi-hd")
116
log('')
117
118
target0 = Drive(backup_path, vm=vm)
119
target0.create_target("backup_target", drive0.fmt, drive0.size)
120
log('')
121
122
- vm.qmp_log("block-dirty-bitmap-add", node=drive0.name,
123
+ vm.qmp_log("block-dirty-bitmap-add", node=drive0.node,
124
name="bitmap0", granularity=GRANULARITY)
125
log('')
126
127
@@ -XXX,XX +XXX,XX @@ def test_backup_api():
128
log("-- Sync mode {:s} tests --\n".format(sync_mode))
129
for bitmap in (None, 'bitmap404', 'bitmap0'):
130
for policy in error_cases[sync_mode][bitmap]:
131
- blockdev_backup(drive0.vm, drive0.name, "backup_target",
132
+ blockdev_backup(drive0.vm, drive0.node, "backup_target",
133
sync_mode, job_id='api_job',
134
bitmap=bitmap, bitmap_mode=policy)
135
log('')
136
--
137
2.21.0
138
139
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
SCSI devices are unused in test, drop them.
4
5
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
Reviewed-by: Max Reitz <mreitz@redhat.com>
7
Message-id: 20190920142056.12778-12-vsementsov@virtuozzo.com
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
---
10
tests/qemu-iotests/257 | 8 -------
11
tests/qemu-iotests/257.out | 44 --------------------------------------
12
2 files changed, 52 deletions(-)
13
14
diff --git a/tests/qemu-iotests/257 b/tests/qemu-iotests/257
15
index XXXXXXX..XXXXXXX 100755
16
--- a/tests/qemu-iotests/257
17
+++ b/tests/qemu-iotests/257
18
@@ -XXX,XX +XXX,XX @@ def test_bitmap_sync(bsync_mode, msync_mode='bitmap', failure=None):
19
node_name=drive0.node,
20
driver=drive0.fmt,
21
file=file_config)
22
- # Use share-rw to allow writes directly to the node;
23
- # The anonymous block-backend for this configuration prevents us
24
- # from using HMP's qemu-io commands to address the device.
25
- vm.qmp_log("device_add", id='device0',
26
- drive=drive0.node, driver="scsi-hd",
27
- share_rw=True)
28
log('')
29
30
# 0 - Writes and Reference Backup
31
@@ -XXX,XX +XXX,XX @@ def test_backup_api():
32
node_name=drive0.node,
33
driver=drive0.fmt,
34
file=file_config)
35
- vm.qmp_log("device_add", id='device0',
36
- drive=drive0.node, driver="scsi-hd")
37
log('')
38
39
target0 = Drive(backup_path, vm=vm)
40
diff --git a/tests/qemu-iotests/257.out b/tests/qemu-iotests/257.out
41
index XXXXXXX..XXXXXXX 100644
42
--- a/tests/qemu-iotests/257.out
43
+++ b/tests/qemu-iotests/257.out
44
@@ -XXX,XX +XXX,XX @@
45
46
{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/PID-img"}, "node-name": "drive0"}}
47
{"return": {}}
48
-{"execute": "device_add", "arguments": {"drive": "drive0", "driver": "scsi-hd", "id": "device0", "share-rw": true}}
49
-{"return": {}}
50
51
--- Write #0 ---
52
53
@@ -XXX,XX +XXX,XX @@ qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fbackup2" ==> Identical, OK!
54
55
{"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}], "set-state": [{"event": "flush_to_disk", "new-state": 2, "state": 1}, {"event": "read_aio", "new-state": 3, "state": 2}]}, "node-name": "drive0"}}
56
{"return": {}}
57
-{"execute": "device_add", "arguments": {"drive": "drive0", "driver": "scsi-hd", "id": "device0", "share-rw": true}}
58
-{"return": {}}
59
60
--- Write #0 ---
61
62
@@ -XXX,XX +XXX,XX @@ qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fbackup2" ==> Identical, OK!
63
64
{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/PID-img"}, "node-name": "drive0"}}
65
{"return": {}}
66
-{"execute": "device_add", "arguments": {"drive": "drive0", "driver": "scsi-hd", "id": "device0", "share-rw": true}}
67
-{"return": {}}
68
69
--- Write #0 ---
70
71
@@ -XXX,XX +XXX,XX @@ qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fbackup2" ==> Identical, OK!
72
73
{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/PID-img"}, "node-name": "drive0"}}
74
{"return": {}}
75
-{"execute": "device_add", "arguments": {"drive": "drive0", "driver": "scsi-hd", "id": "device0", "share-rw": true}}
76
-{"return": {}}
77
78
--- Write #0 ---
79
80
@@ -XXX,XX +XXX,XX @@ qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fbackup2" ==> Identical, OK!
81
82
{"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}], "set-state": [{"event": "flush_to_disk", "new-state": 2, "state": 1}, {"event": "read_aio", "new-state": 3, "state": 2}]}, "node-name": "drive0"}}
83
{"return": {}}
84
-{"execute": "device_add", "arguments": {"drive": "drive0", "driver": "scsi-hd", "id": "device0", "share-rw": true}}
85
-{"return": {}}
86
87
--- Write #0 ---
88
89
@@ -XXX,XX +XXX,XX @@ qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fbackup2" ==> Identical, OK!
90
91
{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/PID-img"}, "node-name": "drive0"}}
92
{"return": {}}
93
-{"execute": "device_add", "arguments": {"drive": "drive0", "driver": "scsi-hd", "id": "device0", "share-rw": true}}
94
-{"return": {}}
95
96
--- Write #0 ---
97
98
@@ -XXX,XX +XXX,XX @@ qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fbackup2" ==> Identical, OK!
99
100
{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/PID-img"}, "node-name": "drive0"}}
101
{"return": {}}
102
-{"execute": "device_add", "arguments": {"drive": "drive0", "driver": "scsi-hd", "id": "device0", "share-rw": true}}
103
-{"return": {}}
104
105
--- Write #0 ---
106
107
@@ -XXX,XX +XXX,XX @@ qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fbackup2" ==> Identical, OK!
108
109
{"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}], "set-state": [{"event": "flush_to_disk", "new-state": 2, "state": 1}, {"event": "read_aio", "new-state": 3, "state": 2}]}, "node-name": "drive0"}}
110
{"return": {}}
111
-{"execute": "device_add", "arguments": {"drive": "drive0", "driver": "scsi-hd", "id": "device0", "share-rw": true}}
112
-{"return": {}}
113
114
--- Write #0 ---
115
116
@@ -XXX,XX +XXX,XX @@ qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fbackup2" ==> Identical, OK!
117
118
{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/PID-img"}, "node-name": "drive0"}}
119
{"return": {}}
120
-{"execute": "device_add", "arguments": {"drive": "drive0", "driver": "scsi-hd", "id": "device0", "share-rw": true}}
121
-{"return": {}}
122
123
--- Write #0 ---
124
125
@@ -XXX,XX +XXX,XX @@ qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fbackup2" ==> Identical, OK!
126
127
{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/PID-img"}, "node-name": "drive0"}}
128
{"return": {}}
129
-{"execute": "device_add", "arguments": {"drive": "drive0", "driver": "scsi-hd", "id": "device0", "share-rw": true}}
130
-{"return": {}}
131
132
--- Write #0 ---
133
134
@@ -XXX,XX +XXX,XX @@ qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fbackup2" ==> Identical, OK!
135
136
{"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}], "set-state": [{"event": "flush_to_disk", "new-state": 2, "state": 1}, {"event": "read_aio", "new-state": 3, "state": 2}]}, "node-name": "drive0"}}
137
{"return": {}}
138
-{"execute": "device_add", "arguments": {"drive": "drive0", "driver": "scsi-hd", "id": "device0", "share-rw": true}}
139
-{"return": {}}
140
141
--- Write #0 ---
142
143
@@ -XXX,XX +XXX,XX @@ qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fbackup2" ==> Identical, OK!
144
145
{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/PID-img"}, "node-name": "drive0"}}
146
{"return": {}}
147
-{"execute": "device_add", "arguments": {"drive": "drive0", "driver": "scsi-hd", "id": "device0", "share-rw": true}}
148
-{"return": {}}
149
150
--- Write #0 ---
151
152
@@ -XXX,XX +XXX,XX @@ qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fbackup2" ==> Identical, OK!
153
154
{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/PID-img"}, "node-name": "drive0"}}
155
{"return": {}}
156
-{"execute": "device_add", "arguments": {"drive": "drive0", "driver": "scsi-hd", "id": "device0", "share-rw": true}}
157
-{"return": {}}
158
159
--- Write #0 ---
160
161
@@ -XXX,XX +XXX,XX @@ qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fbackup2" ==> Identical, OK!
162
163
{"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}], "set-state": [{"event": "flush_to_disk", "new-state": 2, "state": 1}, {"event": "read_aio", "new-state": 3, "state": 2}]}, "node-name": "drive0"}}
164
{"return": {}}
165
-{"execute": "device_add", "arguments": {"drive": "drive0", "driver": "scsi-hd", "id": "device0", "share-rw": true}}
166
-{"return": {}}
167
168
--- Write #0 ---
169
170
@@ -XXX,XX +XXX,XX @@ qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fbackup2" ==> Identical, OK!
171
172
{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/PID-img"}, "node-name": "drive0"}}
173
{"return": {}}
174
-{"execute": "device_add", "arguments": {"drive": "drive0", "driver": "scsi-hd", "id": "device0", "share-rw": true}}
175
-{"return": {}}
176
177
--- Write #0 ---
178
179
@@ -XXX,XX +XXX,XX @@ qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fbackup2" ==> Identical, OK!
180
181
{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/PID-img"}, "node-name": "drive0"}}
182
{"return": {}}
183
-{"execute": "device_add", "arguments": {"drive": "drive0", "driver": "scsi-hd", "id": "device0", "share-rw": true}}
184
-{"return": {}}
185
186
--- Write #0 ---
187
188
@@ -XXX,XX +XXX,XX @@ qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fbackup2" ==> Identical, OK!
189
190
{"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}], "set-state": [{"event": "flush_to_disk", "new-state": 2, "state": 1}, {"event": "read_aio", "new-state": 3, "state": 2}]}, "node-name": "drive0"}}
191
{"return": {}}
192
-{"execute": "device_add", "arguments": {"drive": "drive0", "driver": "scsi-hd", "id": "device0", "share-rw": true}}
193
-{"return": {}}
194
195
--- Write #0 ---
196
197
@@ -XXX,XX +XXX,XX @@ qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fbackup2" ==> Identical, OK!
198
199
{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/PID-img"}, "node-name": "drive0"}}
200
{"return": {}}
201
-{"execute": "device_add", "arguments": {"drive": "drive0", "driver": "scsi-hd", "id": "device0", "share-rw": true}}
202
-{"return": {}}
203
204
--- Write #0 ---
205
206
@@ -XXX,XX +XXX,XX @@ qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fbackup2" ==> Identical, OK!
207
208
{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/PID-img"}, "node-name": "drive0"}}
209
{"return": {}}
210
-{"execute": "device_add", "arguments": {"drive": "drive0", "driver": "scsi-hd", "id": "device0", "share-rw": true}}
211
-{"return": {}}
212
213
--- Write #0 ---
214
215
@@ -XXX,XX +XXX,XX @@ qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fbackup2" ==> Identical, OK!
216
217
{"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}], "set-state": [{"event": "flush_to_disk", "new-state": 2, "state": 1}, {"event": "read_aio", "new-state": 3, "state": 2}]}, "node-name": "drive0"}}
218
{"return": {}}
219
-{"execute": "device_add", "arguments": {"drive": "drive0", "driver": "scsi-hd", "id": "device0", "share-rw": true}}
220
-{"return": {}}
221
222
--- Write #0 ---
223
224
@@ -XXX,XX +XXX,XX @@ qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fbackup2" ==> Identical, OK!
225
226
{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/PID-img"}, "node-name": "drive0"}}
227
{"return": {}}
228
-{"execute": "device_add", "arguments": {"drive": "drive0", "driver": "scsi-hd", "id": "device0", "share-rw": true}}
229
-{"return": {}}
230
231
--- Write #0 ---
232
233
@@ -XXX,XX +XXX,XX @@ qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fbackup2" ==> Identical, OK!
234
235
{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/PID-img"}, "node-name": "drive0"}}
236
{"return": {}}
237
-{"execute": "device_add", "arguments": {"drive": "drive0", "driver": "scsi-hd", "id": "device0"}}
238
-{"return": {}}
239
240
{}
241
{"execute": "job-dismiss", "arguments": {"id": "bdc-file-job"}}
242
--
243
2.21.0
244
245
diff view generated by jsdifflib
Deleted patch
1
From: Anton Nefedov <anton.nefedov@virtuozzo.com>
2
1
3
Make the stat fields definition slightly more readable.
4
Also reorder total_time_ns stats read-write-flush as done elsewhere.
5
Cosmetic change only.
6
7
Signed-off-by: Anton Nefedov <anton.nefedov@virtuozzo.com>
8
Reviewed-by: Alberto Garcia <berto@igalia.com>
9
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Message-id: 20190923121737.83281-2-anton.nefedov@virtuozzo.com
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
---
13
qapi/block-core.json | 26 +++++++++++++++-----------
14
1 file changed, 15 insertions(+), 11 deletions(-)
15
16
diff --git a/qapi/block-core.json b/qapi/block-core.json
17
index XXXXXXX..XXXXXXX 100644
18
--- a/qapi/block-core.json
19
+++ b/qapi/block-core.json
20
@@ -XXX,XX +XXX,XX @@
21
# @flush_operations: The number of cache flush operations performed by the
22
# device (since 0.15.0)
23
#
24
-# @flush_total_time_ns: Total time spend on cache flushes in nano-seconds
25
-# (since 0.15.0).
26
+# @rd_total_time_ns: Total time spent on reads in nanoseconds (since 0.15.0).
27
#
28
-# @wr_total_time_ns: Total time spend on writes in nano-seconds (since 0.15.0).
29
+# @wr_total_time_ns: Total time spent on writes in nanoseconds (since 0.15.0).
30
#
31
-# @rd_total_time_ns: Total_time_spend on reads in nano-seconds (since 0.15.0).
32
+# @flush_total_time_ns: Total time spent on cache flushes in nanoseconds
33
+# (since 0.15.0).
34
#
35
# @wr_highest_offset: The offset after the greatest byte written to the
36
# device. The intended use of this information is for
37
@@ -XXX,XX +XXX,XX @@
38
# Since: 0.14.0
39
##
40
{ 'struct': 'BlockDeviceStats',
41
- 'data': {'rd_bytes': 'int', 'wr_bytes': 'int', 'rd_operations': 'int',
42
- 'wr_operations': 'int', 'flush_operations': 'int',
43
- 'flush_total_time_ns': 'int', 'wr_total_time_ns': 'int',
44
- 'rd_total_time_ns': 'int', 'wr_highest_offset': 'int',
45
- 'rd_merged': 'int', 'wr_merged': 'int', '*idle_time_ns': 'int',
46
+ 'data': {'rd_bytes': 'int', 'wr_bytes': 'int',
47
+ 'rd_operations': 'int', 'wr_operations': 'int',
48
+ 'flush_operations': 'int',
49
+ 'rd_total_time_ns': 'int', 'wr_total_time_ns': 'int',
50
+ 'flush_total_time_ns': 'int',
51
+ 'wr_highest_offset': 'int',
52
+ 'rd_merged': 'int', 'wr_merged': 'int',
53
+ '*idle_time_ns': 'int',
54
'failed_rd_operations': 'int', 'failed_wr_operations': 'int',
55
- 'failed_flush_operations': 'int', 'invalid_rd_operations': 'int',
56
- 'invalid_wr_operations': 'int', 'invalid_flush_operations': 'int',
57
+ 'failed_flush_operations': 'int',
58
+ 'invalid_rd_operations': 'int', 'invalid_wr_operations': 'int',
59
+ 'invalid_flush_operations': 'int',
60
'account_invalid': 'bool', 'account_failed': 'bool',
61
'timed_stats': ['BlockDeviceTimedStats'],
62
'*rd_latency_histogram': 'BlockLatencyHistogramInfo',
63
--
64
2.21.0
65
66
diff view generated by jsdifflib
Deleted patch
1
From: Anton Nefedov <anton.nefedov@virtuozzo.com>
2
1
3
Signed-off-by: Anton Nefedov <anton.nefedov@virtuozzo.com>
4
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
5
Reviewed-by: Alberto Garcia <berto@igalia.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
7
Message-id: 20190923121737.83281-3-anton.nefedov@virtuozzo.com
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
---
10
qapi/block-core.json | 29 +++++++++++++++++++++++------
11
include/block/accounting.h | 1 +
12
block/qapi.c | 6 ++++++
13
tests/qemu-iotests/227.out | 18 ++++++++++++++++++
14
4 files changed, 48 insertions(+), 6 deletions(-)
15
16
diff --git a/qapi/block-core.json b/qapi/block-core.json
17
index XXXXXXX..XXXXXXX 100644
18
--- a/qapi/block-core.json
19
+++ b/qapi/block-core.json
20
@@ -XXX,XX +XXX,XX @@
21
#
22
# @wr_bytes: The number of bytes written by the device.
23
#
24
+# @unmap_bytes: The number of bytes unmapped by the device (Since 4.2)
25
+#
26
# @rd_operations: The number of read operations performed by the device.
27
#
28
# @wr_operations: The number of write operations performed by the device.
29
@@ -XXX,XX +XXX,XX @@
30
# @flush_operations: The number of cache flush operations performed by the
31
# device (since 0.15.0)
32
#
33
+# @unmap_operations: The number of unmap operations performed by the device
34
+# (Since 4.2)
35
+#
36
# @rd_total_time_ns: Total time spent on reads in nanoseconds (since 0.15.0).
37
#
38
# @wr_total_time_ns: Total time spent on writes in nanoseconds (since 0.15.0).
39
@@ -XXX,XX +XXX,XX @@
40
# @flush_total_time_ns: Total time spent on cache flushes in nanoseconds
41
# (since 0.15.0).
42
#
43
+# @unmap_total_time_ns: Total time spent on unmap operations in nanoseconds
44
+# (Since 4.2)
45
+#
46
# @wr_highest_offset: The offset after the greatest byte written to the
47
# device. The intended use of this information is for
48
# growable sparse files (like qcow2) that are used on top
49
@@ -XXX,XX +XXX,XX @@
50
# @wr_merged: Number of write requests that have been merged into another
51
# request (Since 2.3).
52
#
53
+# @unmap_merged: Number of unmap requests that have been merged into another
54
+# request (Since 4.2)
55
+#
56
# @idle_time_ns: Time since the last I/O operation, in
57
# nanoseconds. If the field is absent it means that
58
# there haven't been any operations yet (Since 2.5).
59
@@ -XXX,XX +XXX,XX @@
60
# @failed_flush_operations: The number of failed flush operations
61
# performed by the device (Since 2.5)
62
#
63
+# @failed_unmap_operations: The number of failed unmap operations performed
64
+# by the device (Since 4.2)
65
+#
66
# @invalid_rd_operations: The number of invalid read operations
67
# performed by the device (Since 2.5)
68
#
69
@@ -XXX,XX +XXX,XX @@
70
# @invalid_flush_operations: The number of invalid flush operations
71
# performed by the device (Since 2.5)
72
#
73
+# @invalid_unmap_operations: The number of invalid unmap operations performed
74
+# by the device (Since 4.2)
75
+#
76
# @account_invalid: Whether invalid operations are included in the
77
# last access statistics (Since 2.5)
78
#
79
@@ -XXX,XX +XXX,XX @@
80
# Since: 0.14.0
81
##
82
{ 'struct': 'BlockDeviceStats',
83
- 'data': {'rd_bytes': 'int', 'wr_bytes': 'int',
84
+ 'data': {'rd_bytes': 'int', 'wr_bytes': 'int', 'unmap_bytes' : 'int',
85
'rd_operations': 'int', 'wr_operations': 'int',
86
- 'flush_operations': 'int',
87
+ 'flush_operations': 'int', 'unmap_operations': 'int',
88
'rd_total_time_ns': 'int', 'wr_total_time_ns': 'int',
89
- 'flush_total_time_ns': 'int',
90
+ 'flush_total_time_ns': 'int', 'unmap_total_time_ns': 'int',
91
'wr_highest_offset': 'int',
92
- 'rd_merged': 'int', 'wr_merged': 'int',
93
+ 'rd_merged': 'int', 'wr_merged': 'int', 'unmap_merged': 'int',
94
'*idle_time_ns': 'int',
95
'failed_rd_operations': 'int', 'failed_wr_operations': 'int',
96
- 'failed_flush_operations': 'int',
97
+ 'failed_flush_operations': 'int', 'failed_unmap_operations': 'int',
98
'invalid_rd_operations': 'int', 'invalid_wr_operations': 'int',
99
- 'invalid_flush_operations': 'int',
100
+ 'invalid_flush_operations': 'int', 'invalid_unmap_operations': 'int',
101
'account_invalid': 'bool', 'account_failed': 'bool',
102
'timed_stats': ['BlockDeviceTimedStats'],
103
'*rd_latency_histogram': 'BlockLatencyHistogramInfo',
104
diff --git a/include/block/accounting.h b/include/block/accounting.h
105
index XXXXXXX..XXXXXXX 100644
106
--- a/include/block/accounting.h
107
+++ b/include/block/accounting.h
108
@@ -XXX,XX +XXX,XX @@ enum BlockAcctType {
109
BLOCK_ACCT_READ,
110
BLOCK_ACCT_WRITE,
111
BLOCK_ACCT_FLUSH,
112
+ BLOCK_ACCT_UNMAP,
113
BLOCK_MAX_IOTYPE,
114
};
115
116
diff --git a/block/qapi.c b/block/qapi.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/block/qapi.c
119
+++ b/block/qapi.c
120
@@ -XXX,XX +XXX,XX @@ static void bdrv_query_blk_stats(BlockDeviceStats *ds, BlockBackend *blk)
121
122
ds->rd_bytes = stats->nr_bytes[BLOCK_ACCT_READ];
123
ds->wr_bytes = stats->nr_bytes[BLOCK_ACCT_WRITE];
124
+ ds->unmap_bytes = stats->nr_bytes[BLOCK_ACCT_UNMAP];
125
ds->rd_operations = stats->nr_ops[BLOCK_ACCT_READ];
126
ds->wr_operations = stats->nr_ops[BLOCK_ACCT_WRITE];
127
+ ds->unmap_operations = stats->nr_ops[BLOCK_ACCT_UNMAP];
128
129
ds->failed_rd_operations = stats->failed_ops[BLOCK_ACCT_READ];
130
ds->failed_wr_operations = stats->failed_ops[BLOCK_ACCT_WRITE];
131
ds->failed_flush_operations = stats->failed_ops[BLOCK_ACCT_FLUSH];
132
+ ds->failed_unmap_operations = stats->failed_ops[BLOCK_ACCT_UNMAP];
133
134
ds->invalid_rd_operations = stats->invalid_ops[BLOCK_ACCT_READ];
135
ds->invalid_wr_operations = stats->invalid_ops[BLOCK_ACCT_WRITE];
136
ds->invalid_flush_operations =
137
stats->invalid_ops[BLOCK_ACCT_FLUSH];
138
+ ds->invalid_unmap_operations = stats->invalid_ops[BLOCK_ACCT_UNMAP];
139
140
ds->rd_merged = stats->merged[BLOCK_ACCT_READ];
141
ds->wr_merged = stats->merged[BLOCK_ACCT_WRITE];
142
+ ds->unmap_merged = stats->merged[BLOCK_ACCT_UNMAP];
143
ds->flush_operations = stats->nr_ops[BLOCK_ACCT_FLUSH];
144
ds->wr_total_time_ns = stats->total_time_ns[BLOCK_ACCT_WRITE];
145
ds->rd_total_time_ns = stats->total_time_ns[BLOCK_ACCT_READ];
146
ds->flush_total_time_ns = stats->total_time_ns[BLOCK_ACCT_FLUSH];
147
+ ds->unmap_total_time_ns = stats->total_time_ns[BLOCK_ACCT_UNMAP];
148
149
ds->has_idle_time_ns = stats->last_access_time_ns > 0;
150
if (ds->has_idle_time_ns) {
151
diff --git a/tests/qemu-iotests/227.out b/tests/qemu-iotests/227.out
152
index XXXXXXX..XXXXXXX 100644
153
--- a/tests/qemu-iotests/227.out
154
+++ b/tests/qemu-iotests/227.out
155
@@ -XXX,XX +XXX,XX @@ Testing: -drive driver=null-co,read-zeroes=on,if=virtio
156
{
157
"device": "virtio0",
158
"stats": {
159
+ "unmap_operations": 0,
160
+ "unmap_merged": 0,
161
"flush_total_time_ns": 0,
162
"wr_highest_offset": 0,
163
"wr_total_time_ns": 0,
164
@@ -XXX,XX +XXX,XX @@ Testing: -drive driver=null-co,read-zeroes=on,if=virtio
165
"wr_bytes": 0,
166
"timed_stats": [
167
],
168
+ "failed_unmap_operations": 0,
169
"failed_flush_operations": 0,
170
"account_invalid": true,
171
"rd_total_time_ns": 0,
172
+ "invalid_unmap_operations": 0,
173
"flush_operations": 0,
174
"wr_operations": 0,
175
+ "unmap_bytes": 0,
176
"rd_merged": 0,
177
"rd_bytes": 0,
178
+ "unmap_total_time_ns": 0,
179
"invalid_flush_operations": 0,
180
"account_failed": true,
181
"rd_operations": 0,
182
@@ -XXX,XX +XXX,XX @@ Testing: -drive driver=null-co,if=none
183
{
184
"device": "none0",
185
"stats": {
186
+ "unmap_operations": 0,
187
+ "unmap_merged": 0,
188
"flush_total_time_ns": 0,
189
"wr_highest_offset": 0,
190
"wr_total_time_ns": 0,
191
@@ -XXX,XX +XXX,XX @@ Testing: -drive driver=null-co,if=none
192
"wr_bytes": 0,
193
"timed_stats": [
194
],
195
+ "failed_unmap_operations": 0,
196
"failed_flush_operations": 0,
197
"account_invalid": true,
198
"rd_total_time_ns": 0,
199
+ "invalid_unmap_operations": 0,
200
"flush_operations": 0,
201
"wr_operations": 0,
202
+ "unmap_bytes": 0,
203
"rd_merged": 0,
204
"rd_bytes": 0,
205
+ "unmap_total_time_ns": 0,
206
"invalid_flush_operations": 0,
207
"account_failed": true,
208
"rd_operations": 0,
209
@@ -XXX,XX +XXX,XX @@ Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device virtio-b
210
{
211
"device": "",
212
"stats": {
213
+ "unmap_operations": 0,
214
+ "unmap_merged": 0,
215
"flush_total_time_ns": 0,
216
"wr_highest_offset": 0,
217
"wr_total_time_ns": 0,
218
@@ -XXX,XX +XXX,XX @@ Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device virtio-b
219
"wr_bytes": 0,
220
"timed_stats": [
221
],
222
+ "failed_unmap_operations": 0,
223
"failed_flush_operations": 0,
224
"account_invalid": false,
225
"rd_total_time_ns": 0,
226
+ "invalid_unmap_operations": 0,
227
"flush_operations": 0,
228
"wr_operations": 0,
229
+ "unmap_bytes": 0,
230
"rd_merged": 0,
231
"rd_bytes": 0,
232
+ "unmap_total_time_ns": 0,
233
"invalid_flush_operations": 0,
234
"account_failed": false,
235
"rd_operations": 0,
236
--
237
2.21.0
238
239
diff view generated by jsdifflib
Deleted patch
1
From: Anton Nefedov <anton.nefedov@virtuozzo.com>
2
1
3
Each block_acct_done/failed call is designed to correspond to a
4
previous block_acct_start call, which initializes the stats cookie.
5
However sometimes it is not the case, e.g. some error paths might
6
report the same cookie twice because it is hard to accurately track if
7
the cookie was reported yet or not.
8
9
This patch cleans the cookie after report.
10
(Note: block_acct_failed/done without a previous block_acct_start at
11
all should be avoided. Uninitialized cookie might hold a garbage value
12
and there is still "< BLOCK_MAX_IOTYPE" assertion for that)
13
14
It will be particularly useful in ide code where it's hard to
15
keep track whether the request done its accounting or not: in the
16
following patch of the series, trim requests will do the accounting
17
separately.
18
19
Signed-off-by: Anton Nefedov <anton.nefedov@virtuozzo.com>
20
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
21
Message-id: 20190923121737.83281-4-anton.nefedov@virtuozzo.com
22
Signed-off-by: Max Reitz <mreitz@redhat.com>
23
---
24
include/block/accounting.h | 1 +
25
block/accounting.c | 6 ++++++
26
2 files changed, 7 insertions(+)
27
28
diff --git a/include/block/accounting.h b/include/block/accounting.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/include/block/accounting.h
31
+++ b/include/block/accounting.h
32
@@ -XXX,XX +XXX,XX @@ typedef struct BlockAcctTimedStats BlockAcctTimedStats;
33
typedef struct BlockAcctStats BlockAcctStats;
34
35
enum BlockAcctType {
36
+ BLOCK_ACCT_NONE = 0,
37
BLOCK_ACCT_READ,
38
BLOCK_ACCT_WRITE,
39
BLOCK_ACCT_FLUSH,
40
diff --git a/block/accounting.c b/block/accounting.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/block/accounting.c
43
+++ b/block/accounting.c
44
@@ -XXX,XX +XXX,XX @@ static void block_account_one_io(BlockAcctStats *stats, BlockAcctCookie *cookie,
45
46
assert(cookie->type < BLOCK_MAX_IOTYPE);
47
48
+ if (cookie->type == BLOCK_ACCT_NONE) {
49
+ return;
50
+ }
51
+
52
qemu_mutex_lock(&stats->lock);
53
54
if (failed) {
55
@@ -XXX,XX +XXX,XX @@ static void block_account_one_io(BlockAcctStats *stats, BlockAcctCookie *cookie,
56
}
57
58
qemu_mutex_unlock(&stats->lock);
59
+
60
+ cookie->type = BLOCK_ACCT_NONE;
61
}
62
63
void block_acct_done(BlockAcctStats *stats, BlockAcctCookie *cookie)
64
--
65
2.21.0
66
67
diff view generated by jsdifflib
Deleted patch
1
From: Anton Nefedov <anton.nefedov@virtuozzo.com>
2
1
3
Signed-off-by: Anton Nefedov <anton.nefedov@virtuozzo.com>
4
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
5
Message-id: 20190923121737.83281-5-anton.nefedov@virtuozzo.com
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
---
8
hw/ide/core.c | 12 ++++++++++++
9
1 file changed, 12 insertions(+)
10
11
diff --git a/hw/ide/core.c b/hw/ide/core.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/ide/core.c
14
+++ b/hw/ide/core.c
15
@@ -XXX,XX +XXX,XX @@ static void ide_issue_trim_cb(void *opaque, int ret)
16
TrimAIOCB *iocb = opaque;
17
IDEState *s = iocb->s;
18
19
+ if (iocb->i >= 0) {
20
+ if (ret >= 0) {
21
+ block_acct_done(blk_get_stats(s->blk), &s->acct);
22
+ } else {
23
+ block_acct_failed(blk_get_stats(s->blk), &s->acct);
24
+ }
25
+ }
26
+
27
if (ret >= 0) {
28
while (iocb->j < iocb->qiov->niov) {
29
int j = iocb->j;
30
@@ -XXX,XX +XXX,XX @@ static void ide_issue_trim_cb(void *opaque, int ret)
31
}
32
33
if (!ide_sect_range_ok(s, sector, count)) {
34
+ block_acct_invalid(blk_get_stats(s->blk), BLOCK_ACCT_UNMAP);
35
iocb->ret = -EINVAL;
36
goto done;
37
}
38
39
+ block_acct_start(blk_get_stats(s->blk), &s->acct,
40
+ count << BDRV_SECTOR_BITS, BLOCK_ACCT_UNMAP);
41
+
42
/* Got an entry! Submit and exit. */
43
iocb->aiocb = blk_aio_pdiscard(s->blk,
44
sector << BDRV_SECTOR_BITS,
45
--
46
2.21.0
47
48
diff view generated by jsdifflib
Deleted patch
1
From: Anton Nefedov <anton.nefedov@virtuozzo.com>
2
1
3
it allows to report it in the error handler
4
5
Signed-off-by: Anton Nefedov <anton.nefedov@virtuozzo.com>
6
Message-id: 20190923121737.83281-6-anton.nefedov@virtuozzo.com
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
---
9
hw/scsi/scsi-disk.c | 14 +++++++-------
10
1 file changed, 7 insertions(+), 7 deletions(-)
11
12
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/scsi/scsi-disk.c
15
+++ b/hw/scsi/scsi-disk.c
16
@@ -XXX,XX +XXX,XX @@ static void scsi_unmap_complete_noio(UnmapCBData *data, int ret)
17
{
18
SCSIDiskReq *r = data->r;
19
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
20
- uint64_t sector_num;
21
- uint32_t nb_sectors;
22
23
assert(r->req.aiocb == NULL);
24
if (scsi_disk_req_check_error(r, ret, false)) {
25
@@ -XXX,XX +XXX,XX @@ static void scsi_unmap_complete_noio(UnmapCBData *data, int ret)
26
}
27
28
if (data->count > 0) {
29
- sector_num = ldq_be_p(&data->inbuf[0]);
30
- nb_sectors = ldl_be_p(&data->inbuf[8]) & 0xffffffffULL;
31
- if (!check_lba_range(s, sector_num, nb_sectors)) {
32
+ r->sector = ldq_be_p(&data->inbuf[0])
33
+ * (s->qdev.blocksize / BDRV_SECTOR_SIZE);
34
+ r->sector_count = (ldl_be_p(&data->inbuf[8]) & 0xffffffffULL)
35
+ * (s->qdev.blocksize / BDRV_SECTOR_SIZE);
36
+ if (!check_lba_range(s, r->sector, r->sector_count)) {
37
scsi_check_condition(r, SENSE_CODE(LBA_OUT_OF_RANGE));
38
goto done;
39
}
40
41
r->req.aiocb = blk_aio_pdiscard(s->qdev.conf.blk,
42
- sector_num * s->qdev.blocksize,
43
- nb_sectors * s->qdev.blocksize,
44
+ r->sector * BDRV_SECTOR_SIZE,
45
+ r->sector_count * BDRV_SECTOR_SIZE,
46
scsi_unmap_complete, data);
47
data->count--;
48
data->inbuf += 16;
49
--
50
2.21.0
51
52
diff view generated by jsdifflib
Deleted patch
1
From: Anton Nefedov <anton.nefedov@virtuozzo.com>
2
1
3
This will help to account the operation in the following commit.
4
5
The difference is that we don't call scsi_disk_req_check_error() before
6
the 1st discard iteration anymore. That function also checks if
7
the request is cancelled, however it shouldn't get canceled until it
8
yields in blk_aio() functions anyway.
9
Same approach is already used for emulate_write_same.
10
11
Signed-off-by: Anton Nefedov <anton.nefedov@virtuozzo.com>
12
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
13
Reviewed-by: Alberto Garcia <berto@igalia.com>
14
Message-id: 20190923121737.83281-7-anton.nefedov@virtuozzo.com
15
Signed-off-by: Max Reitz <mreitz@redhat.com>
16
---
17
hw/scsi/scsi-disk.c | 10 ++++++----
18
1 file changed, 6 insertions(+), 4 deletions(-)
19
20
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/scsi/scsi-disk.c
23
+++ b/hw/scsi/scsi-disk.c
24
@@ -XXX,XX +XXX,XX @@ static void scsi_unmap_complete_noio(UnmapCBData *data, int ret)
25
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
26
27
assert(r->req.aiocb == NULL);
28
- if (scsi_disk_req_check_error(r, ret, false)) {
29
- goto done;
30
- }
31
32
if (data->count > 0) {
33
r->sector = ldq_be_p(&data->inbuf[0])
34
@@ -XXX,XX +XXX,XX @@ static void scsi_unmap_complete(void *opaque, int ret)
35
r->req.aiocb = NULL;
36
37
aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
38
- scsi_unmap_complete_noio(data, ret);
39
+ if (scsi_disk_req_check_error(r, ret, false)) {
40
+ scsi_req_unref(&r->req);
41
+ g_free(data);
42
+ } else {
43
+ scsi_unmap_complete_noio(data, ret);
44
+ }
45
aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
46
}
47
48
--
49
2.21.0
50
51
diff view generated by jsdifflib
Deleted patch
1
From: Anton Nefedov <anton.nefedov@virtuozzo.com>
2
1
3
Signed-off-by: Anton Nefedov <anton.nefedov@virtuozzo.com>
4
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
5
Message-id: 20190923121737.83281-8-anton.nefedov@virtuozzo.com
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
---
8
hw/scsi/scsi-disk.c | 12 +++++++++++-
9
1 file changed, 11 insertions(+), 1 deletion(-)
10
11
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/scsi/scsi-disk.c
14
+++ b/hw/scsi/scsi-disk.c
15
@@ -XXX,XX +XXX,XX @@ static void scsi_unmap_complete_noio(UnmapCBData *data, int ret)
16
r->sector_count = (ldl_be_p(&data->inbuf[8]) & 0xffffffffULL)
17
* (s->qdev.blocksize / BDRV_SECTOR_SIZE);
18
if (!check_lba_range(s, r->sector, r->sector_count)) {
19
+ block_acct_invalid(blk_get_stats(s->qdev.conf.blk),
20
+ BLOCK_ACCT_UNMAP);
21
scsi_check_condition(r, SENSE_CODE(LBA_OUT_OF_RANGE));
22
goto done;
23
}
24
25
+ block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct,
26
+ r->sector_count * BDRV_SECTOR_SIZE,
27
+ BLOCK_ACCT_UNMAP);
28
+
29
r->req.aiocb = blk_aio_pdiscard(s->qdev.conf.blk,
30
r->sector * BDRV_SECTOR_SIZE,
31
r->sector_count * BDRV_SECTOR_SIZE,
32
@@ -XXX,XX +XXX,XX @@ static void scsi_unmap_complete(void *opaque, int ret)
33
r->req.aiocb = NULL;
34
35
aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
36
- if (scsi_disk_req_check_error(r, ret, false)) {
37
+ if (scsi_disk_req_check_error(r, ret, true)) {
38
scsi_req_unref(&r->req);
39
g_free(data);
40
} else {
41
+ block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
42
scsi_unmap_complete_noio(data, ret);
43
}
44
aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
45
@@ -XXX,XX +XXX,XX @@ static void scsi_disk_emulate_unmap(SCSIDiskReq *r, uint8_t *inbuf)
46
}
47
48
if (blk_is_read_only(s->qdev.conf.blk)) {
49
+ block_acct_invalid(blk_get_stats(s->qdev.conf.blk), BLOCK_ACCT_UNMAP);
50
scsi_check_condition(r, SENSE_CODE(WRITE_PROTECTED));
51
return;
52
}
53
@@ -XXX,XX +XXX,XX @@ static void scsi_disk_emulate_unmap(SCSIDiskReq *r, uint8_t *inbuf)
54
return;
55
56
invalid_param_len:
57
+ block_acct_invalid(blk_get_stats(s->qdev.conf.blk), BLOCK_ACCT_UNMAP);
58
scsi_check_condition(r, SENSE_CODE(INVALID_PARAM_LEN));
59
return;
60
61
invalid_field:
62
+ block_acct_invalid(blk_get_stats(s->qdev.conf.blk), BLOCK_ACCT_UNMAP);
63
scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
64
}
65
66
--
67
2.21.0
68
69
diff view generated by jsdifflib
Deleted patch
1
From: Anton Nefedov <anton.nefedov@virtuozzo.com>
2
1
3
This will help to identify how many of the user-issued discard operations
4
(accounted on a device level) have actually suceeded down on the host file
5
(even though the numbers will not be exactly the same if non-raw format
6
driver is used (e.g. qcow2 sending metadata discards)).
7
8
Note that these numbers will not include discards triggered by
9
write-zeroes + MAY_UNMAP calls.
10
11
Signed-off-by: Anton Nefedov <anton.nefedov@virtuozzo.com>
12
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
13
Message-id: 20190923121737.83281-9-anton.nefedov@virtuozzo.com
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
15
---
16
block/file-posix.c | 22 +++++++++++++++++++++-
17
1 file changed, 21 insertions(+), 1 deletion(-)
18
19
diff --git a/block/file-posix.c b/block/file-posix.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/block/file-posix.c
22
+++ b/block/file-posix.c
23
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVRawState {
24
bool needs_alignment;
25
bool drop_cache;
26
bool check_cache_dropped;
27
+ struct {
28
+ uint64_t discard_nb_ok;
29
+ uint64_t discard_nb_failed;
30
+ uint64_t discard_bytes_ok;
31
+ } stats;
32
33
PRManager *pr_mgr;
34
} BDRVRawState;
35
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn raw_co_invalidate_cache(BlockDriverState *bs,
36
#endif /* !__linux__ */
37
}
38
39
+static void raw_account_discard(BDRVRawState *s, uint64_t nbytes, int ret)
40
+{
41
+ if (ret) {
42
+ s->stats.discard_nb_failed++;
43
+ } else {
44
+ s->stats.discard_nb_ok++;
45
+ s->stats.discard_bytes_ok += nbytes;
46
+ }
47
+}
48
+
49
static coroutine_fn int
50
raw_do_pdiscard(BlockDriverState *bs, int64_t offset, int bytes, bool blkdev)
51
{
52
BDRVRawState *s = bs->opaque;
53
RawPosixAIOData acb;
54
+ int ret;
55
56
acb = (RawPosixAIOData) {
57
.bs = bs,
58
@@ -XXX,XX +XXX,XX @@ raw_do_pdiscard(BlockDriverState *bs, int64_t offset, int bytes, bool blkdev)
59
acb.aio_type |= QEMU_AIO_BLKDEV;
60
}
61
62
- return raw_thread_pool_submit(bs, handle_aiocb_discard, &acb);
63
+ ret = raw_thread_pool_submit(bs, handle_aiocb_discard, &acb);
64
+ raw_account_discard(s, bytes, ret);
65
+ return ret;
66
}
67
68
static coroutine_fn int
69
@@ -XXX,XX +XXX,XX @@ static int fd_open(BlockDriverState *bs)
70
static coroutine_fn int
71
hdev_co_pdiscard(BlockDriverState *bs, int64_t offset, int bytes)
72
{
73
+ BDRVRawState *s = bs->opaque;
74
int ret;
75
76
ret = fd_open(bs);
77
if (ret < 0) {
78
+ raw_account_discard(s, bytes, ret);
79
return ret;
80
}
81
return raw_do_pdiscard(bs, offset, bytes, true);
82
--
83
2.21.0
84
85
diff view generated by jsdifflib
Deleted patch
1
From: Anton Nefedov <anton.nefedov@virtuozzo.com>
2
1
3
A block driver can provide a callback to report driver-specific
4
statistics.
5
6
file-posix driver now reports discard statistics
7
8
Signed-off-by: Anton Nefedov <anton.nefedov@virtuozzo.com>
9
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Acked-by: Markus Armbruster <armbru@redhat.com>
11
Message-id: 20190923121737.83281-10-anton.nefedov@virtuozzo.com
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
13
---
14
qapi/block-core.json | 38 ++++++++++++++++++++++++++++++++++++++
15
include/block/block.h | 1 +
16
include/block/block_int.h | 1 +
17
block.c | 9 +++++++++
18
block/file-posix.c | 32 ++++++++++++++++++++++++++++++++
19
block/qapi.c | 5 +++++
20
6 files changed, 86 insertions(+)
21
22
diff --git a/qapi/block-core.json b/qapi/block-core.json
23
index XXXXXXX..XXXXXXX 100644
24
--- a/qapi/block-core.json
25
+++ b/qapi/block-core.json
26
@@ -XXX,XX +XXX,XX @@
27
'*wr_latency_histogram': 'BlockLatencyHistogramInfo',
28
'*flush_latency_histogram': 'BlockLatencyHistogramInfo' } }
29
30
+##
31
+# @BlockStatsSpecificFile:
32
+#
33
+# File driver statistics
34
+#
35
+# @discard-nb-ok: The number of successful discard operations performed by
36
+# the driver.
37
+#
38
+# @discard-nb-failed: The number of failed discard operations performed by
39
+# the driver.
40
+#
41
+# @discard-bytes-ok: The number of bytes discarded by the driver.
42
+#
43
+# Since: 4.2
44
+##
45
+{ 'struct': 'BlockStatsSpecificFile',
46
+ 'data': {
47
+ 'discard-nb-ok': 'uint64',
48
+ 'discard-nb-failed': 'uint64',
49
+ 'discard-bytes-ok': 'uint64' } }
50
+
51
+##
52
+# @BlockStatsSpecific:
53
+#
54
+# Block driver specific statistics
55
+#
56
+# Since: 4.2
57
+##
58
+{ 'union': 'BlockStatsSpecific',
59
+ 'base': { 'driver': 'BlockdevDriver' },
60
+ 'discriminator': 'driver',
61
+ 'data': {
62
+ 'file': 'BlockStatsSpecificFile',
63
+ 'host_device': 'BlockStatsSpecificFile' } }
64
+
65
##
66
# @BlockStats:
67
#
68
@@ -XXX,XX +XXX,XX @@
69
#
70
# @stats: A @BlockDeviceStats for the device.
71
#
72
+# @driver-specific: Optional driver-specific stats. (Since 4.2)
73
+#
74
# @parent: This describes the file block device if it has one.
75
# Contains recursively the statistics of the underlying
76
# protocol (e.g. the host file for a qcow2 image). If there is
77
@@ -XXX,XX +XXX,XX @@
78
{ 'struct': 'BlockStats',
79
'data': {'*device': 'str', '*qdev': 'str', '*node-name': 'str',
80
'stats': 'BlockDeviceStats',
81
+ '*driver-specific': 'BlockStatsSpecific',
82
'*parent': 'BlockStats',
83
'*backing': 'BlockStats'} }
84
85
diff --git a/include/block/block.h b/include/block/block.h
86
index XXXXXXX..XXXXXXX 100644
87
--- a/include/block/block.h
88
+++ b/include/block/block.h
89
@@ -XXX,XX +XXX,XX @@ int bdrv_get_flags(BlockDriverState *bs);
90
int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
91
ImageInfoSpecific *bdrv_get_specific_info(BlockDriverState *bs,
92
Error **errp);
93
+BlockStatsSpecific *bdrv_get_specific_stats(BlockDriverState *bs);
94
void bdrv_round_to_clusters(BlockDriverState *bs,
95
int64_t offset, int64_t bytes,
96
int64_t *cluster_offset,
97
diff --git a/include/block/block_int.h b/include/block/block_int.h
98
index XXXXXXX..XXXXXXX 100644
99
--- a/include/block/block_int.h
100
+++ b/include/block/block_int.h
101
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
102
int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi);
103
ImageInfoSpecific *(*bdrv_get_specific_info)(BlockDriverState *bs,
104
Error **errp);
105
+ BlockStatsSpecific *(*bdrv_get_specific_stats)(BlockDriverState *bs);
106
107
int coroutine_fn (*bdrv_save_vmstate)(BlockDriverState *bs,
108
QEMUIOVector *qiov,
109
diff --git a/block.c b/block.c
110
index XXXXXXX..XXXXXXX 100644
111
--- a/block.c
112
+++ b/block.c
113
@@ -XXX,XX +XXX,XX @@ ImageInfoSpecific *bdrv_get_specific_info(BlockDriverState *bs,
114
return NULL;
115
}
116
117
+BlockStatsSpecific *bdrv_get_specific_stats(BlockDriverState *bs)
118
+{
119
+ BlockDriver *drv = bs->drv;
120
+ if (!drv || !drv->bdrv_get_specific_stats) {
121
+ return NULL;
122
+ }
123
+ return drv->bdrv_get_specific_stats(bs);
124
+}
125
+
126
void bdrv_debug_event(BlockDriverState *bs, BlkdebugEvent event)
127
{
128
if (!bs || !bs->drv || !bs->drv->bdrv_debug_event) {
129
diff --git a/block/file-posix.c b/block/file-posix.c
130
index XXXXXXX..XXXXXXX 100644
131
--- a/block/file-posix.c
132
+++ b/block/file-posix.c
133
@@ -XXX,XX +XXX,XX @@ static int raw_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
134
return 0;
135
}
136
137
+static BlockStatsSpecificFile get_blockstats_specific_file(BlockDriverState *bs)
138
+{
139
+ BDRVRawState *s = bs->opaque;
140
+ return (BlockStatsSpecificFile) {
141
+ .discard_nb_ok = s->stats.discard_nb_ok,
142
+ .discard_nb_failed = s->stats.discard_nb_failed,
143
+ .discard_bytes_ok = s->stats.discard_bytes_ok,
144
+ };
145
+}
146
+
147
+static BlockStatsSpecific *raw_get_specific_stats(BlockDriverState *bs)
148
+{
149
+ BlockStatsSpecific *stats = g_new(BlockStatsSpecific, 1);
150
+
151
+ stats->driver = BLOCKDEV_DRIVER_FILE;
152
+ stats->u.file = get_blockstats_specific_file(bs);
153
+
154
+ return stats;
155
+}
156
+
157
+static BlockStatsSpecific *hdev_get_specific_stats(BlockDriverState *bs)
158
+{
159
+ BlockStatsSpecific *stats = g_new(BlockStatsSpecific, 1);
160
+
161
+ stats->driver = BLOCKDEV_DRIVER_HOST_DEVICE;
162
+ stats->u.host_device = get_blockstats_specific_file(bs);
163
+
164
+ return stats;
165
+}
166
+
167
static QemuOptsList raw_create_opts = {
168
.name = "raw-create-opts",
169
.head = QTAILQ_HEAD_INITIALIZER(raw_create_opts.head),
170
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_file = {
171
.bdrv_get_info = raw_get_info,
172
.bdrv_get_allocated_file_size
173
= raw_get_allocated_file_size,
174
+ .bdrv_get_specific_stats = raw_get_specific_stats,
175
.bdrv_check_perm = raw_check_perm,
176
.bdrv_set_perm = raw_set_perm,
177
.bdrv_abort_perm_update = raw_abort_perm_update,
178
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_device = {
179
.bdrv_get_info = raw_get_info,
180
.bdrv_get_allocated_file_size
181
= raw_get_allocated_file_size,
182
+ .bdrv_get_specific_stats = hdev_get_specific_stats,
183
.bdrv_check_perm = raw_check_perm,
184
.bdrv_set_perm = raw_set_perm,
185
.bdrv_abort_perm_update = raw_abort_perm_update,
186
diff --git a/block/qapi.c b/block/qapi.c
187
index XXXXXXX..XXXXXXX 100644
188
--- a/block/qapi.c
189
+++ b/block/qapi.c
190
@@ -XXX,XX +XXX,XX @@ static BlockStats *bdrv_query_bds_stats(BlockDriverState *bs,
191
192
s->stats->wr_highest_offset = stat64_get(&bs->wr_highest_offset);
193
194
+ s->driver_specific = bdrv_get_specific_stats(bs);
195
+ if (s->driver_specific) {
196
+ s->has_driver_specific = true;
197
+ }
198
+
199
if (bs->file) {
200
s->has_parent = true;
201
s->parent = bdrv_query_bds_stats(bs->file->bs, blk_level);
202
--
203
2.21.0
204
205
diff view generated by jsdifflib
Deleted patch
1
If we use growth_mode = metadata, it is very much possible that the file
2
uses more disk space after we have written something to the added area.
3
We did indeed want to test for this case, but unfortunately we evidently
4
just copied the code from the "Test creation preallocation" section and
5
forgot to replace "$create_mode" by "$growth_mode".
6
1
7
We never noticed because we only read the first number from qemu-img
8
info's "disk size" output -- and that is effectively useless, because
9
qemu-img prints a human-readable value (which generally includes a
10
decimal point). That will be fixed in the patch after the next one.
11
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
13
Message-id: 20190925183231.11196-2-mreitz@redhat.com
14
Reviewed-by: Eric Blake <eblake@redhat.com>
15
Signed-off-by: Max Reitz <mreitz@redhat.com>
16
---
17
tests/qemu-iotests/125 | 2 +-
18
1 file changed, 1 insertion(+), 1 deletion(-)
19
20
diff --git a/tests/qemu-iotests/125 b/tests/qemu-iotests/125
21
index XXXXXXX..XXXXXXX 100755
22
--- a/tests/qemu-iotests/125
23
+++ b/tests/qemu-iotests/125
24
@@ -XXX,XX +XXX,XX @@ for GROWTH_SIZE in 16 48 80; do
25
if [ $file_length_2 -gt $file_length_1 ]; then
26
echo "ERROR (grow): Image length has grown from $file_length_1 to $file_length_2"
27
fi
28
- if [ $create_mode != metadata ]; then
29
+ if [ $growth_mode != metadata ]; then
30
# The host size should not have grown either
31
if [ $host_size_2 -gt $host_size_1 ]; then
32
echo "ERROR (grow): Host size has grown from $host_size_1 to $host_size_2"
33
--
34
2.21.0
35
36
diff view generated by jsdifflib
Deleted patch
1
And by that I mean all XFS versions, as far as I can tell. All details
2
are in the comment below.
3
1
4
We never noticed this problem because we only read the first number from
5
qemu-img info's "disk size" output -- and that is effectively useless,
6
because qemu-img prints a human-readable value (which generally includes
7
a decimal point). That will be fixed in the next patch.
8
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
Message-id: 20190925183231.11196-3-mreitz@redhat.com
11
Reviewed-by: Eric Blake <eblake@redhat.com>
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
13
---
14
tests/qemu-iotests/125 | 40 ++++++++++++++++++++++++++++++++++++++++
15
1 file changed, 40 insertions(+)
16
17
diff --git a/tests/qemu-iotests/125 b/tests/qemu-iotests/125
18
index XXXXXXX..XXXXXXX 100755
19
--- a/tests/qemu-iotests/125
20
+++ b/tests/qemu-iotests/125
21
@@ -XXX,XX +XXX,XX @@ if [ -z "$TEST_IMG_FILE" ]; then
22
TEST_IMG_FILE=$TEST_IMG
23
fi
24
25
+# Test whether we are running on a broken XFS version. There is this
26
+# bug:
27
+
28
+# $ rm -f foo
29
+# $ touch foo
30
+# $ block_size=4096 # Your FS's block size
31
+# $ fallocate -o $((block_size / 2)) -l $block_size foo
32
+# $ LANG=C xfs_bmap foo | grep hole
33
+# 1: [8..15]: hole
34
+#
35
+# The problem is that the XFS driver rounds down the offset and
36
+# rounds up the length to the block size, but independently. As
37
+# such, it only allocates the first block in the example above,
38
+# even though it should allocate the first two blocks (because our
39
+# request is to fallocate something that touches both the first
40
+# two blocks).
41
+#
42
+# This means that when you then write to the beginning of the
43
+# second block, the disk usage of the first two blocks grows.
44
+#
45
+# That is precisely what fallocate() promises, though: That when you
46
+# write to an area that you have fallocated, no new blocks will have
47
+# to be allocated.
48
+
49
+touch "$TEST_IMG_FILE"
50
+# Assuming there is no FS with a block size greater than 64k
51
+fallocate -o 65535 -l 2 "$TEST_IMG_FILE"
52
+len0=$(get_image_size_on_host)
53
+
54
+# Write to something that in theory we have just fallocated
55
+# (Thus, the on-disk size should not increase)
56
+poke_file "$TEST_IMG_FILE" 65536 42
57
+len1=$(get_image_size_on_host)
58
+
59
+if [ $len1 -gt $len0 ]; then
60
+ _notrun "the test filesystem's fallocate() is broken"
61
+fi
62
+
63
+rm -f "$TEST_IMG_FILE"
64
+
65
# Generally, we create some image with or without existing preallocation and
66
# then resize it. Then we write some data into the image and verify that its
67
# size does not change if we have used preallocation.
68
--
69
2.21.0
70
71
diff view generated by jsdifflib
Deleted patch
1
125 should not use qemu-img to get the on-disk image size, because that
2
reports it in a human-readable format that is useless to us. Just use
3
stat instead (like we do to get the image file length).
4
1
5
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
Message-id: 20190925183231.11196-4-mreitz@redhat.com
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
---
10
tests/qemu-iotests/125 | 3 +--
11
1 file changed, 1 insertion(+), 2 deletions(-)
12
13
diff --git a/tests/qemu-iotests/125 b/tests/qemu-iotests/125
14
index XXXXXXX..XXXXXXX 100755
15
--- a/tests/qemu-iotests/125
16
+++ b/tests/qemu-iotests/125
17
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
18
19
get_image_size_on_host()
20
{
21
- $QEMU_IMG info -f "$IMGFMT" "$TEST_IMG" | grep "disk size" \
22
- | sed -e 's/^[^0-9]*\([0-9]\+\).*$/\1/'
23
+ echo $(($(stat -c '%b * %B' "$TEST_IMG_FILE")))
24
}
25
26
# get standard environment and filters
27
--
28
2.21.0
29
30
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Move synchronization mechanism to block-copy, to be able to use one
4
block-copy instance from backup job and backup-top filter in parallel.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Message-id: 20191001131409.14202-2-vsementsov@virtuozzo.com
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
---
11
include/block/block-copy.h | 8 ++++++
12
block/backup.c | 52 --------------------------------------
13
block/block-copy.c | 43 +++++++++++++++++++++++++++++++
14
3 files changed, 51 insertions(+), 52 deletions(-)
15
16
diff --git a/include/block/block-copy.h b/include/block/block-copy.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/block/block-copy.h
19
+++ b/include/block/block-copy.h
20
@@ -XXX,XX +XXX,XX @@
21
22
#include "block/block.h"
23
24
+typedef struct BlockCopyInFlightReq {
25
+ int64_t start_byte;
26
+ int64_t end_byte;
27
+ QLIST_ENTRY(BlockCopyInFlightReq) list;
28
+ CoQueue wait_queue; /* coroutines blocked on this request */
29
+} BlockCopyInFlightReq;
30
+
31
typedef void (*ProgressBytesCallbackFunc)(int64_t bytes, void *opaque);
32
typedef void (*ProgressResetCallbackFunc)(void *opaque);
33
typedef struct BlockCopyState {
34
@@ -XXX,XX +XXX,XX @@ typedef struct BlockCopyState {
35
bool use_copy_range;
36
int64_t copy_range_size;
37
uint64_t len;
38
+ QLIST_HEAD(, BlockCopyInFlightReq) inflight_reqs;
39
40
BdrvRequestFlags write_flags;
41
42
diff --git a/block/backup.c b/block/backup.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/block/backup.c
45
+++ b/block/backup.c
46
@@ -XXX,XX +XXX,XX @@
47
48
#define BACKUP_CLUSTER_SIZE_DEFAULT (1 << 16)
49
50
-typedef struct CowRequest {
51
- int64_t start_byte;
52
- int64_t end_byte;
53
- QLIST_ENTRY(CowRequest) list;
54
- CoQueue wait_queue; /* coroutines blocked on this request */
55
-} CowRequest;
56
-
57
typedef struct BackupBlockJob {
58
BlockJob common;
59
BlockDriverState *source_bs;
60
@@ -XXX,XX +XXX,XX @@ typedef struct BackupBlockJob {
61
uint64_t bytes_read;
62
int64_t cluster_size;
63
NotifierWithReturn before_write;
64
- QLIST_HEAD(, CowRequest) inflight_reqs;
65
66
BlockCopyState *bcs;
67
} BackupBlockJob;
68
69
static const BlockJobDriver backup_job_driver;
70
71
-/* See if in-flight requests overlap and wait for them to complete */
72
-static void coroutine_fn wait_for_overlapping_requests(BackupBlockJob *job,
73
- int64_t start,
74
- int64_t end)
75
-{
76
- CowRequest *req;
77
- bool retry;
78
-
79
- do {
80
- retry = false;
81
- QLIST_FOREACH(req, &job->inflight_reqs, list) {
82
- if (end > req->start_byte && start < req->end_byte) {
83
- qemu_co_queue_wait(&req->wait_queue, NULL);
84
- retry = true;
85
- break;
86
- }
87
- }
88
- } while (retry);
89
-}
90
-
91
-/* Keep track of an in-flight request */
92
-static void cow_request_begin(CowRequest *req, BackupBlockJob *job,
93
- int64_t start, int64_t end)
94
-{
95
- req->start_byte = start;
96
- req->end_byte = end;
97
- qemu_co_queue_init(&req->wait_queue);
98
- QLIST_INSERT_HEAD(&job->inflight_reqs, req, list);
99
-}
100
-
101
-/* Forget about a completed request */
102
-static void cow_request_end(CowRequest *req)
103
-{
104
- QLIST_REMOVE(req, list);
105
- qemu_co_queue_restart_all(&req->wait_queue);
106
-}
107
-
108
static void backup_progress_bytes_callback(int64_t bytes, void *opaque)
109
{
110
BackupBlockJob *s = opaque;
111
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job,
112
bool *error_is_read,
113
bool is_write_notifier)
114
{
115
- CowRequest cow_request;
116
int ret = 0;
117
int64_t start, end; /* bytes */
118
119
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job,
120
121
trace_backup_do_cow_enter(job, start, offset, bytes);
122
123
- wait_for_overlapping_requests(job, start, end);
124
- cow_request_begin(&cow_request, job, start, end);
125
-
126
ret = block_copy(job->bcs, start, end - start, error_is_read,
127
is_write_notifier);
128
129
- cow_request_end(&cow_request);
130
-
131
trace_backup_do_cow_return(job, offset, bytes, ret);
132
133
qemu_co_rwlock_unlock(&job->flush_rwlock);
134
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_run(Job *job, Error **errp)
135
BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
136
int ret = 0;
137
138
- QLIST_INIT(&s->inflight_reqs);
139
qemu_co_rwlock_init(&s->flush_rwlock);
140
141
backup_init_copy_bitmap(s);
142
diff --git a/block/block-copy.c b/block/block-copy.c
143
index XXXXXXX..XXXXXXX 100644
144
--- a/block/block-copy.c
145
+++ b/block/block-copy.c
146
@@ -XXX,XX +XXX,XX @@
147
#include "block/block-copy.h"
148
#include "sysemu/block-backend.h"
149
150
+static void coroutine_fn block_copy_wait_inflight_reqs(BlockCopyState *s,
151
+ int64_t start,
152
+ int64_t end)
153
+{
154
+ BlockCopyInFlightReq *req;
155
+ bool waited;
156
+
157
+ do {
158
+ waited = false;
159
+ QLIST_FOREACH(req, &s->inflight_reqs, list) {
160
+ if (end > req->start_byte && start < req->end_byte) {
161
+ qemu_co_queue_wait(&req->wait_queue, NULL);
162
+ waited = true;
163
+ break;
164
+ }
165
+ }
166
+ } while (waited);
167
+}
168
+
169
+static void block_copy_inflight_req_begin(BlockCopyState *s,
170
+ BlockCopyInFlightReq *req,
171
+ int64_t start, int64_t end)
172
+{
173
+ req->start_byte = start;
174
+ req->end_byte = end;
175
+ qemu_co_queue_init(&req->wait_queue);
176
+ QLIST_INSERT_HEAD(&s->inflight_reqs, req, list);
177
+}
178
+
179
+static void coroutine_fn block_copy_inflight_req_end(BlockCopyInFlightReq *req)
180
+{
181
+ QLIST_REMOVE(req, list);
182
+ qemu_co_queue_restart_all(&req->wait_queue);
183
+}
184
+
185
void block_copy_state_free(BlockCopyState *s)
186
{
187
if (!s) {
188
@@ -XXX,XX +XXX,XX @@ BlockCopyState *block_copy_state_new(
189
s->use_copy_range =
190
!(write_flags & BDRV_REQ_WRITE_COMPRESSED) && s->copy_range_size > 0;
191
192
+ QLIST_INIT(&s->inflight_reqs);
193
+
194
/*
195
* We just allow aio context change on our block backends. block_copy() user
196
* (now it's only backup) is responsible for source and target being in same
197
@@ -XXX,XX +XXX,XX @@ int coroutine_fn block_copy(BlockCopyState *s,
198
int64_t end = bytes + start; /* bytes */
199
void *bounce_buffer = NULL;
200
int64_t status_bytes;
201
+ BlockCopyInFlightReq req;
202
203
/*
204
* block_copy() user is responsible for keeping source and target in same
205
@@ -XXX,XX +XXX,XX @@ int coroutine_fn block_copy(BlockCopyState *s,
206
assert(QEMU_IS_ALIGNED(start, s->cluster_size));
207
assert(QEMU_IS_ALIGNED(end, s->cluster_size));
208
209
+ block_copy_wait_inflight_reqs(s, start, bytes);
210
+ block_copy_inflight_req_begin(s, &req, start, end);
211
+
212
while (start < end) {
213
int64_t dirty_end;
214
215
@@ -XXX,XX +XXX,XX @@ int coroutine_fn block_copy(BlockCopyState *s,
216
qemu_vfree(bounce_buffer);
217
}
218
219
+ block_copy_inflight_req_end(&req);
220
+
221
return ret;
222
}
223
--
224
2.21.0
225
226
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
This is logic-less refactoring, which simplifies further patch, as
4
we'll need write_flags for backup-top filter creation and backup-top
5
should be created before block job creation.
6
7
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Message-id: 20191001131409.14202-3-vsementsov@virtuozzo.com
9
Reviewed-by: Max Reitz <mreitz@redhat.com>
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
---
12
block/backup.c | 30 +++++++++++++++---------------
13
1 file changed, 15 insertions(+), 15 deletions(-)
14
15
diff --git a/block/backup.c b/block/backup.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/block/backup.c
18
+++ b/block/backup.c
19
@@ -XXX,XX +XXX,XX @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
20
goto error;
21
}
22
23
- /* job->len is fixed, so we can't allow resize */
24
- job = block_job_create(job_id, &backup_job_driver, txn, bs, 0, BLK_PERM_ALL,
25
- speed, creation_flags, cb, opaque, errp);
26
- if (!job) {
27
- goto error;
28
- }
29
-
30
- job->source_bs = bs;
31
- job->on_source_error = on_source_error;
32
- job->on_target_error = on_target_error;
33
- job->sync_mode = sync_mode;
34
- job->sync_bitmap = sync_bitmap;
35
- job->bitmap_mode = bitmap_mode;
36
-
37
/*
38
* If source is in backing chain of target assume that target is going to be
39
* used for "image fleecing", i.e. it should represent a kind of snapshot of
40
@@ -XXX,XX +XXX,XX @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
41
write_flags = (bdrv_chain_contains(target, bs) ? BDRV_REQ_SERIALISING : 0) |
42
(compress ? BDRV_REQ_WRITE_COMPRESSED : 0),
43
44
+ /* job->len is fixed, so we can't allow resize */
45
+ job = block_job_create(job_id, &backup_job_driver, txn, bs, 0, BLK_PERM_ALL,
46
+ speed, creation_flags, cb, opaque, errp);
47
+ if (!job) {
48
+ goto error;
49
+ }
50
+
51
+ job->source_bs = bs;
52
+ job->on_source_error = on_source_error;
53
+ job->on_target_error = on_target_error;
54
+ job->sync_mode = sync_mode;
55
+ job->sync_bitmap = sync_bitmap;
56
+ job->bitmap_mode = bitmap_mode;
57
+
58
job->bcs = block_copy_state_new(bs, target, cluster_size, write_flags,
59
backup_progress_bytes_callback,
60
backup_progress_reset_callback, job, errp);
61
@@ -XXX,XX +XXX,XX @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
62
}
63
64
job->cluster_size = cluster_size;
65
+ job->len = len;
66
67
/* Required permissions are already taken by block-copy-state target */
68
block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL,
69
&error_abort);
70
- job->len = len;
71
72
return &job->common;
73
74
--
75
2.21.0
76
77
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Split block_copy_set_callbacks out of block_copy_state_new. It's needed
4
for further commit: block-copy will use BdrvChildren of backup-top
5
filter, so it will be created from backup-top filter creation function.
6
But callbacks will still belong to backup job and will be set in
7
separate.
8
9
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Message-id: 20191001131409.14202-4-vsementsov@virtuozzo.com
11
Reviewed-by: Max Reitz <mreitz@redhat.com>
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
13
---
14
include/block/block-copy.h | 13 +++++++++----
15
block/backup.c | 6 ++++--
16
block/block-copy.c | 24 +++++++++++++++---------
17
3 files changed, 28 insertions(+), 15 deletions(-)
18
19
diff --git a/include/block/block-copy.h b/include/block/block-copy.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/block/block-copy.h
22
+++ b/include/block/block-copy.h
23
@@ -XXX,XX +XXX,XX @@ typedef struct BlockCopyState {
24
void *progress_opaque;
25
} BlockCopyState;
26
27
-BlockCopyState *block_copy_state_new(
28
- BlockDriverState *source, BlockDriverState *target,
29
- int64_t cluster_size, BdrvRequestFlags write_flags,
30
+BlockCopyState *block_copy_state_new(BlockDriverState *source,
31
+ BlockDriverState *target,
32
+ int64_t cluster_size,
33
+ BdrvRequestFlags write_flags,
34
+ Error **errp);
35
+
36
+void block_copy_set_callbacks(
37
+ BlockCopyState *s,
38
ProgressBytesCallbackFunc progress_bytes_callback,
39
ProgressResetCallbackFunc progress_reset_callback,
40
- void *progress_opaque, Error **errp);
41
+ void *progress_opaque);
42
43
void block_copy_state_free(BlockCopyState *s);
44
45
diff --git a/block/backup.c b/block/backup.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/block/backup.c
48
+++ b/block/backup.c
49
@@ -XXX,XX +XXX,XX @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
50
job->bitmap_mode = bitmap_mode;
51
52
job->bcs = block_copy_state_new(bs, target, cluster_size, write_flags,
53
- backup_progress_bytes_callback,
54
- backup_progress_reset_callback, job, errp);
55
+ errp);
56
if (!job->bcs) {
57
goto error;
58
}
59
@@ -XXX,XX +XXX,XX @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
60
job->cluster_size = cluster_size;
61
job->len = len;
62
63
+ block_copy_set_callbacks(job->bcs, backup_progress_bytes_callback,
64
+ backup_progress_reset_callback, job);
65
+
66
/* Required permissions are already taken by block-copy-state target */
67
block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL,
68
&error_abort);
69
diff --git a/block/block-copy.c b/block/block-copy.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/block/block-copy.c
72
+++ b/block/block-copy.c
73
@@ -XXX,XX +XXX,XX @@ void block_copy_state_free(BlockCopyState *s)
74
g_free(s);
75
}
76
77
-BlockCopyState *block_copy_state_new(
78
- BlockDriverState *source, BlockDriverState *target,
79
- int64_t cluster_size, BdrvRequestFlags write_flags,
80
- ProgressBytesCallbackFunc progress_bytes_callback,
81
- ProgressResetCallbackFunc progress_reset_callback,
82
- void *progress_opaque, Error **errp)
83
+BlockCopyState *block_copy_state_new(BlockDriverState *source,
84
+ BlockDriverState *target,
85
+ int64_t cluster_size,
86
+ BdrvRequestFlags write_flags, Error **errp)
87
{
88
BlockCopyState *s;
89
int ret;
90
@@ -XXX,XX +XXX,XX @@ BlockCopyState *block_copy_state_new(
91
.cluster_size = cluster_size,
92
.len = bdrv_dirty_bitmap_size(copy_bitmap),
93
.write_flags = write_flags,
94
- .progress_bytes_callback = progress_bytes_callback,
95
- .progress_reset_callback = progress_reset_callback,
96
- .progress_opaque = progress_opaque,
97
};
98
99
s->copy_range_size = QEMU_ALIGN_DOWN(MIN(blk_get_max_transfer(s->source),
100
@@ -XXX,XX +XXX,XX @@ fail:
101
return NULL;
102
}
103
104
+void block_copy_set_callbacks(
105
+ BlockCopyState *s,
106
+ ProgressBytesCallbackFunc progress_bytes_callback,
107
+ ProgressResetCallbackFunc progress_reset_callback,
108
+ void *progress_opaque)
109
+{
110
+ s->progress_bytes_callback = progress_bytes_callback;
111
+ s->progress_reset_callback = progress_reset_callback;
112
+ s->progress_opaque = progress_opaque;
113
+}
114
+
115
/*
116
* Copy range to target with a bounce buffer and return the bytes copied. If
117
* error occurred, return a negative error number
118
--
119
2.21.0
120
121
diff view generated by jsdifflib
Deleted patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
1
3
Backup-top filter caches write operations and does copy-before-write
4
operations.
5
6
The driver will be used in backup instead of write-notifiers.
7
8
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
Message-id: 20191001131409.14202-5-vsementsov@virtuozzo.com
10
Reviewed-by: Max Reitz <mreitz@redhat.com>
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
---
13
block/Makefile.objs | 1 +
14
block/backup-top.h | 41 +++++++
15
block/backup-top.c | 281 ++++++++++++++++++++++++++++++++++++++++++++
16
3 files changed, 323 insertions(+)
17
create mode 100644 block/backup-top.h
18
create mode 100644 block/backup-top.c
19
20
diff --git a/block/Makefile.objs b/block/Makefile.objs
21
index XXXXXXX..XXXXXXX 100644
22
--- a/block/Makefile.objs
23
+++ b/block/Makefile.objs
24
@@ -XXX,XX +XXX,XX @@ block-obj-y += block-copy.o
25
block-obj-y += crypto.o
26
27
block-obj-y += aio_task.o
28
+block-obj-y += backup-top.o
29
30
common-obj-y += stream.o
31
32
diff --git a/block/backup-top.h b/block/backup-top.h
33
new file mode 100644
34
index XXXXXXX..XXXXXXX
35
--- /dev/null
36
+++ b/block/backup-top.h
37
@@ -XXX,XX +XXX,XX @@
38
+/*
39
+ * backup-top filter driver
40
+ *
41
+ * The driver performs Copy-Before-Write (CBW) operation: it is injected above
42
+ * some node, and before each write it copies _old_ data to the target node.
43
+ *
44
+ * Copyright (c) 2018-2019 Virtuozzo International GmbH.
45
+ *
46
+ * Author:
47
+ * Sementsov-Ogievskiy Vladimir <vsementsov@virtuozzo.com>
48
+ *
49
+ * This program is free software; you can redistribute it and/or modify
50
+ * it under the terms of the GNU General Public License as published by
51
+ * the Free Software Foundation; either version 2 of the License, or
52
+ * (at your option) any later version.
53
+ *
54
+ * This program is distributed in the hope that it will be useful,
55
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
56
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
57
+ * GNU General Public License for more details.
58
+ *
59
+ * You should have received a copy of the GNU General Public License
60
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
61
+ */
62
+
63
+#ifndef BACKUP_TOP_H
64
+#define BACKUP_TOP_H
65
+
66
+#include "block/block_int.h"
67
+#include "block/block-copy.h"
68
+
69
+BlockDriverState *bdrv_backup_top_append(BlockDriverState *source,
70
+ BlockDriverState *target,
71
+ const char *filter_node_name,
72
+ uint64_t cluster_size,
73
+ BdrvRequestFlags write_flags,
74
+ BlockCopyState **bcs,
75
+ Error **errp);
76
+void bdrv_backup_top_drop(BlockDriverState *bs);
77
+
78
+#endif /* BACKUP_TOP_H */
79
diff --git a/block/backup-top.c b/block/backup-top.c
80
new file mode 100644
81
index XXXXXXX..XXXXXXX
82
--- /dev/null
83
+++ b/block/backup-top.c
84
@@ -XXX,XX +XXX,XX @@
85
+/*
86
+ * backup-top filter driver
87
+ *
88
+ * The driver performs Copy-Before-Write (CBW) operation: it is injected above
89
+ * some node, and before each write it copies _old_ data to the target node.
90
+ *
91
+ * Copyright (c) 2018-2019 Virtuozzo International GmbH.
92
+ *
93
+ * Author:
94
+ * Sementsov-Ogievskiy Vladimir <vsementsov@virtuozzo.com>
95
+ *
96
+ * This program is free software; you can redistribute it and/or modify
97
+ * it under the terms of the GNU General Public License as published by
98
+ * the Free Software Foundation; either version 2 of the License, or
99
+ * (at your option) any later version.
100
+ *
101
+ * This program is distributed in the hope that it will be useful,
102
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
103
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
104
+ * GNU General Public License for more details.
105
+ *
106
+ * You should have received a copy of the GNU General Public License
107
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
108
+ */
109
+
110
+#include "qemu/osdep.h"
111
+
112
+#include "sysemu/block-backend.h"
113
+#include "qemu/cutils.h"
114
+#include "qapi/error.h"
115
+#include "block/block_int.h"
116
+#include "block/qdict.h"
117
+#include "block/block-copy.h"
118
+
119
+#include "block/backup-top.h"
120
+
121
+typedef struct BDRVBackupTopState {
122
+ BlockCopyState *bcs;
123
+ BdrvChild *target;
124
+ bool active;
125
+} BDRVBackupTopState;
126
+
127
+static coroutine_fn int backup_top_co_preadv(
128
+ BlockDriverState *bs, uint64_t offset, uint64_t bytes,
129
+ QEMUIOVector *qiov, int flags)
130
+{
131
+ return bdrv_co_preadv(bs->backing, offset, bytes, qiov, flags);
132
+}
133
+
134
+static coroutine_fn int backup_top_cbw(BlockDriverState *bs, uint64_t offset,
135
+ uint64_t bytes)
136
+{
137
+ /*
138
+ * Here we'd like to use block_copy(), but block-copy need to be moved to
139
+ * use BdrvChildren to correctly use it in backup-top filter. It's a TODO.
140
+ */
141
+
142
+ abort();
143
+}
144
+
145
+static int coroutine_fn backup_top_co_pdiscard(BlockDriverState *bs,
146
+ int64_t offset, int bytes)
147
+{
148
+ int ret = backup_top_cbw(bs, offset, bytes);
149
+ if (ret < 0) {
150
+ return ret;
151
+ }
152
+
153
+ return bdrv_co_pdiscard(bs->backing, offset, bytes);
154
+}
155
+
156
+static int coroutine_fn backup_top_co_pwrite_zeroes(BlockDriverState *bs,
157
+ int64_t offset, int bytes, BdrvRequestFlags flags)
158
+{
159
+ int ret = backup_top_cbw(bs, offset, bytes);
160
+ if (ret < 0) {
161
+ return ret;
162
+ }
163
+
164
+ return bdrv_co_pwrite_zeroes(bs->backing, offset, bytes, flags);
165
+}
166
+
167
+static coroutine_fn int backup_top_co_pwritev(BlockDriverState *bs,
168
+ uint64_t offset,
169
+ uint64_t bytes,
170
+ QEMUIOVector *qiov, int flags)
171
+{
172
+ if (!(flags & BDRV_REQ_WRITE_UNCHANGED)) {
173
+ int ret = backup_top_cbw(bs, offset, bytes);
174
+ if (ret < 0) {
175
+ return ret;
176
+ }
177
+ }
178
+
179
+ return bdrv_co_pwritev(bs->backing, offset, bytes, qiov, flags);
180
+}
181
+
182
+static int coroutine_fn backup_top_co_flush(BlockDriverState *bs)
183
+{
184
+ if (!bs->backing) {
185
+ return 0;
186
+ }
187
+
188
+ return bdrv_co_flush(bs->backing->bs);
189
+}
190
+
191
+static void backup_top_refresh_filename(BlockDriverState *bs)
192
+{
193
+ if (bs->backing == NULL) {
194
+ /*
195
+ * we can be here after failed bdrv_attach_child in
196
+ * bdrv_set_backing_hd
197
+ */
198
+ return;
199
+ }
200
+ pstrcpy(bs->exact_filename, sizeof(bs->exact_filename),
201
+ bs->backing->bs->filename);
202
+}
203
+
204
+static void backup_top_child_perm(BlockDriverState *bs, BdrvChild *c,
205
+ const BdrvChildRole *role,
206
+ BlockReopenQueue *reopen_queue,
207
+ uint64_t perm, uint64_t shared,
208
+ uint64_t *nperm, uint64_t *nshared)
209
+{
210
+ BDRVBackupTopState *s = bs->opaque;
211
+
212
+ if (!s->active) {
213
+ /*
214
+ * The filter node may be in process of bdrv_append(), which firstly do
215
+ * bdrv_set_backing_hd() and then bdrv_replace_node(). This means that
216
+ * we can't unshare BLK_PERM_WRITE during bdrv_append() operation. So,
217
+ * let's require nothing during bdrv_append() and refresh permissions
218
+ * after it (see bdrv_backup_top_append()).
219
+ */
220
+ *nperm = 0;
221
+ *nshared = BLK_PERM_ALL;
222
+ return;
223
+ }
224
+
225
+ if (role == &child_file) {
226
+ /*
227
+ * Target child
228
+ *
229
+ * Share write to target (child_file), to not interfere
230
+ * with guest writes to its disk which may be in target backing chain.
231
+ */
232
+ *nshared = BLK_PERM_ALL;
233
+ *nperm = BLK_PERM_WRITE;
234
+ } else {
235
+ /* Source child */
236
+ bdrv_filter_default_perms(bs, c, role, reopen_queue, perm, shared,
237
+ nperm, nshared);
238
+
239
+ if (perm & BLK_PERM_WRITE) {
240
+ *nperm = *nperm | BLK_PERM_CONSISTENT_READ;
241
+ }
242
+ *nshared &= ~BLK_PERM_WRITE;
243
+ }
244
+}
245
+
246
+BlockDriver bdrv_backup_top_filter = {
247
+ .format_name = "backup-top",
248
+ .instance_size = sizeof(BDRVBackupTopState),
249
+
250
+ .bdrv_co_preadv = backup_top_co_preadv,
251
+ .bdrv_co_pwritev = backup_top_co_pwritev,
252
+ .bdrv_co_pwrite_zeroes = backup_top_co_pwrite_zeroes,
253
+ .bdrv_co_pdiscard = backup_top_co_pdiscard,
254
+ .bdrv_co_flush = backup_top_co_flush,
255
+
256
+ .bdrv_co_block_status = bdrv_co_block_status_from_backing,
257
+
258
+ .bdrv_refresh_filename = backup_top_refresh_filename,
259
+
260
+ .bdrv_child_perm = backup_top_child_perm,
261
+
262
+ .is_filter = true,
263
+};
264
+
265
+BlockDriverState *bdrv_backup_top_append(BlockDriverState *source,
266
+ BlockDriverState *target,
267
+ const char *filter_node_name,
268
+ uint64_t cluster_size,
269
+ BdrvRequestFlags write_flags,
270
+ BlockCopyState **bcs,
271
+ Error **errp)
272
+{
273
+ Error *local_err = NULL;
274
+ BDRVBackupTopState *state;
275
+ BlockDriverState *top = bdrv_new_open_driver(&bdrv_backup_top_filter,
276
+ filter_node_name,
277
+ BDRV_O_RDWR, errp);
278
+
279
+ if (!top) {
280
+ return NULL;
281
+ }
282
+
283
+ top->total_sectors = source->total_sectors;
284
+ top->opaque = state = g_new0(BDRVBackupTopState, 1);
285
+
286
+ bdrv_ref(target);
287
+ state->target = bdrv_attach_child(top, target, "target", &child_file, errp);
288
+ if (!state->target) {
289
+ bdrv_unref(target);
290
+ bdrv_unref(top);
291
+ return NULL;
292
+ }
293
+
294
+ bdrv_drained_begin(source);
295
+
296
+ bdrv_ref(top);
297
+ bdrv_append(top, source, &local_err);
298
+ if (local_err) {
299
+ error_prepend(&local_err, "Cannot append backup-top filter: ");
300
+ goto append_failed;
301
+ }
302
+
303
+ /*
304
+ * bdrv_append() finished successfully, now we can require permissions
305
+ * we want.
306
+ */
307
+ state->active = true;
308
+ bdrv_child_refresh_perms(top, top->backing, &local_err);
309
+ if (local_err) {
310
+ error_prepend(&local_err,
311
+ "Cannot set permissions for backup-top filter: ");
312
+ goto failed_after_append;
313
+ }
314
+
315
+ /*
316
+ * TODO: Create block-copy-state here (which will utilize @cluster_size and
317
+ * @write_flags parameters which are unused now). For this, block-copy
318
+ * should be refactored to use BdrvChildren.
319
+ */
320
+ state->bcs = NULL;
321
+ if (!state->bcs) {
322
+ error_setg(&local_err, "Cannot create block-copy-state");
323
+ goto failed_after_append;
324
+ }
325
+ *bcs = state->bcs;
326
+
327
+ bdrv_drained_end(source);
328
+
329
+ return top;
330
+
331
+failed_after_append:
332
+ state->active = false;
333
+ bdrv_backup_top_drop(top);
334
+
335
+append_failed:
336
+ bdrv_drained_end(source);
337
+ bdrv_unref_child(top, state->target);
338
+ bdrv_unref(top);
339
+ error_propagate(errp, local_err);
340
+
341
+ return NULL;
342
+}
343
+
344
+void bdrv_backup_top_drop(BlockDriverState *bs)
345
+{
346
+ BDRVBackupTopState *s = bs->opaque;
347
+ AioContext *aio_context = bdrv_get_aio_context(bs);
348
+
349
+ block_copy_state_free(s->bcs);
350
+
351
+ aio_context_acquire(aio_context);
352
+
353
+ bdrv_drained_begin(bs);
354
+
355
+ s->active = false;
356
+ bdrv_child_refresh_perms(bs, bs->backing, &error_abort);
357
+ bdrv_replace_node(bs, backing_bs(bs), &error_abort);
358
+ bdrv_set_backing_hd(bs, NULL, &error_abort);
359
+
360
+ bdrv_drained_end(bs);
361
+
362
+ bdrv_unref(bs);
363
+
364
+ aio_context_release(aio_context);
365
+}
366
--
367
2.21.0
368
369
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
Drop write notifiers and use filter node instead.
3
Commit 7a3f542fbd "block/io: refactor padding" occasionally dropped
4
aligning for zero-length request: bdrv_init_padding() blindly return
5
false if bytes == 0, like there is nothing to align.
4
6
5
= Changes =
7
This leads the following command to crash:
6
8
7
1. Add filter-node-name argument for backup qmp api. We have to do it
9
./qemu-io --image-opts -c 'write 1 0' \
8
in this commit, as 257 needs to be fixed.
10
driver=blkdebug,align=512,image.driver=null-co,image.size=512
9
11
10
2. There are no more write notifiers here, so is_write_notifier
12
>> qemu-io: block/io.c:1955: bdrv_aligned_pwritev: Assertion
11
parameter is dropped from block-copy paths.
13
`(offset & (align - 1)) == 0' failed.
14
>> Aborted (core dumped)
12
15
13
3. To sync with in-flight requests at job finish we now have drained
16
Prior to 7a3f542fbd we does aligning of such zero requests. Instead of
14
removing of the filter, we don't need rw-lock.
17
recovering this behavior let's just do nothing on such requests as it
18
is useless.
15
19
16
4. Block-copy is now using BdrvChildren instead of BlockBackends
20
Note that driver may have special meaning of zero-length reqeusts, like
21
qcow2_co_pwritev_compressed_part, so we can't skip any zero-length
22
operation. But for unaligned ones, we can't pass it to driver anyway.
17
23
18
5. As backup-top owns these children, we also move block-copy state
24
This commit also fixes crash in iotest 80 running with -nocache:
19
into backup-top's ownership.
20
25
21
= Iotest changes =
26
./check -nocache -qcow2 80
22
27
23
56: op-blocker doesn't shoot now, as we set it on source, but then
28
which crashes on same assertion due to trying to read empty extra data
24
check on filter, when trying to start second backup.
29
in qcow2_do_read_snapshots().
25
To keep the test we instead can catch another collision: both jobs will
26
get 'drive0' job-id, as job-id parameter is unspecified. To prevent
27
interleaving with file-posix locks (as they are dependent on config)
28
let's use another target for second backup.
29
30
30
Also, it's obvious now that we'd like to drop this op-blocker at all
31
Cc: qemu-stable@nongnu.org # v4.2
31
and add a test-case for two backups from one node (to different
32
Fixes: 7a3f542fbd
32
destinations) actually works. But not in these series.
33
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
34
Reviewed-by: Max Reitz <mreitz@redhat.com>
35
Message-id: 20200206164245.17781-1-vsementsov@virtuozzo.com
36
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
37
---
38
block/io.c | 28 +++++++++++++++++++++++++++-
39
1 file changed, 27 insertions(+), 1 deletion(-)
33
40
34
141: Output changed: prepatch, "Node is in use" comes from bdrv_has_blk
41
diff --git a/block/io.c b/block/io.c
35
check inside qmp_blockdev_del. But we've dropped block-copy blk
36
objects, so no more blk objects on source bs (job blk is on backup-top
37
filter bs). New message is from op-blocker, which is the next check in
38
qmp_blockdev_add.
39
40
257: The test wants to emulate guest write during backup. They should
41
go to filter node, not to original source node, of course. Therefore we
42
need to specify filter node name and use it.
43
44
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
45
Message-id: 20191001131409.14202-6-vsementsov@virtuozzo.com
46
Reviewed-by: Max Reitz <mreitz@redhat.com>
47
Signed-off-by: Max Reitz <mreitz@redhat.com>
48
---
49
qapi/block-core.json | 8 +-
50
include/block/block-copy.h | 14 +-
51
include/block/block_int.h | 1 +
52
block/backup-top.c | 21 +--
53
block/backup.c | 73 +++------
54
block/block-copy.c | 81 +++-------
55
block/replication.c | 2 +-
56
blockdev.c | 1 +
57
tests/qemu-iotests/056 | 8 +-
58
tests/qemu-iotests/141.out | 2 +-
59
tests/qemu-iotests/257 | 7 +-
60
tests/qemu-iotests/257.out | 306 ++++++++++++++++++-------------------
61
12 files changed, 237 insertions(+), 287 deletions(-)
62
63
diff --git a/qapi/block-core.json b/qapi/block-core.json
64
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
65
--- a/qapi/block-core.json
43
--- a/block/io.c
66
+++ b/qapi/block-core.json
44
+++ b/block/io.c
67
@@ -XXX,XX +XXX,XX @@
45
@@ -XXX,XX +XXX,XX @@ static bool bdrv_init_padding(BlockDriverState *bs,
68
# list without user intervention.
46
pad->tail = align - pad->tail;
69
# Defaults to true. (Since 2.12)
70
#
71
+# @filter-node-name: the node name that should be assigned to the
72
+# filter driver that the backup job inserts into the graph
73
+# above node specified by @drive. If this option is not given,
74
+# a node name is autogenerated. (Since: 4.2)
75
+#
76
# Note: @on-source-error and @on-target-error only affect background
77
# I/O. If an error occurs during a guest write request, the device's
78
# rerror/werror actions will be used.
79
@@ -XXX,XX +XXX,XX @@
80
'*compress': 'bool',
81
'*on-source-error': 'BlockdevOnError',
82
'*on-target-error': 'BlockdevOnError',
83
- '*auto-finalize': 'bool', '*auto-dismiss': 'bool' } }
84
+ '*auto-finalize': 'bool', '*auto-dismiss': 'bool',
85
+ '*filter-node-name': 'str' } }
86
87
##
88
# @DriveBackup:
89
diff --git a/include/block/block-copy.h b/include/block/block-copy.h
90
index XXXXXXX..XXXXXXX 100644
91
--- a/include/block/block-copy.h
92
+++ b/include/block/block-copy.h
93
@@ -XXX,XX +XXX,XX @@ typedef struct BlockCopyInFlightReq {
94
typedef void (*ProgressBytesCallbackFunc)(int64_t bytes, void *opaque);
95
typedef void (*ProgressResetCallbackFunc)(void *opaque);
96
typedef struct BlockCopyState {
97
- BlockBackend *source;
98
- BlockBackend *target;
99
+ /*
100
+ * BdrvChild objects are not owned or managed by block-copy. They are
101
+ * provided by block-copy user and user is responsible for appropriate
102
+ * permissions on these children.
103
+ */
104
+ BdrvChild *source;
105
+ BdrvChild *target;
106
BdrvDirtyBitmap *copy_bitmap;
107
int64_t cluster_size;
108
bool use_copy_range;
109
@@ -XXX,XX +XXX,XX @@ typedef struct BlockCopyState {
110
void *progress_opaque;
111
} BlockCopyState;
112
113
-BlockCopyState *block_copy_state_new(BlockDriverState *source,
114
- BlockDriverState *target,
115
+BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target,
116
int64_t cluster_size,
117
BdrvRequestFlags write_flags,
118
Error **errp);
119
@@ -XXX,XX +XXX,XX @@ int64_t block_copy_reset_unallocated(BlockCopyState *s,
120
int64_t offset, int64_t *count);
121
122
int coroutine_fn block_copy(BlockCopyState *s, int64_t start, uint64_t bytes,
123
- bool *error_is_read, bool is_write_notifier);
124
+ bool *error_is_read);
125
126
#endif /* BLOCK_COPY_H */
127
diff --git a/include/block/block_int.h b/include/block/block_int.h
128
index XXXXXXX..XXXXXXX 100644
129
--- a/include/block/block_int.h
130
+++ b/include/block/block_int.h
131
@@ -XXX,XX +XXX,XX @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
132
BdrvDirtyBitmap *sync_bitmap,
133
BitmapSyncMode bitmap_mode,
134
bool compress,
135
+ const char *filter_node_name,
136
BlockdevOnError on_source_error,
137
BlockdevOnError on_target_error,
138
int creation_flags,
139
diff --git a/block/backup-top.c b/block/backup-top.c
140
index XXXXXXX..XXXXXXX 100644
141
--- a/block/backup-top.c
142
+++ b/block/backup-top.c
143
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int backup_top_co_preadv(
144
static coroutine_fn int backup_top_cbw(BlockDriverState *bs, uint64_t offset,
145
uint64_t bytes)
146
{
147
- /*
148
- * Here we'd like to use block_copy(), but block-copy need to be moved to
149
- * use BdrvChildren to correctly use it in backup-top filter. It's a TODO.
150
- */
151
+ BDRVBackupTopState *s = bs->opaque;
152
+ uint64_t end = QEMU_ALIGN_UP(offset + bytes, s->bcs->cluster_size);
153
+ uint64_t off = QEMU_ALIGN_DOWN(offset, s->bcs->cluster_size);
154
155
- abort();
156
+ return block_copy(s->bcs, off, end - off, NULL);
157
}
158
159
static int coroutine_fn backup_top_co_pdiscard(BlockDriverState *bs,
160
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_backup_top_append(BlockDriverState *source,
161
goto failed_after_append;
162
}
47
}
163
48
164
- /*
49
- if ((!pad->head && !pad->tail) || !bytes) {
165
- * TODO: Create block-copy-state here (which will utilize @cluster_size and
50
+ if (!pad->head && !pad->tail) {
166
- * @write_flags parameters which are unused now). For this, block-copy
51
return false;
167
- * should be refactored to use BdrvChildren.
168
- */
169
- state->bcs = NULL;
170
- if (!state->bcs) {
171
- error_setg(&local_err, "Cannot create block-copy-state");
172
+ state->bcs = block_copy_state_new(top->backing, state->target,
173
+ cluster_size, write_flags, &local_err);
174
+ if (local_err) {
175
+ error_prepend(&local_err, "Cannot create block-copy-state: ");
176
goto failed_after_append;
177
}
52
}
178
*bcs = state->bcs;
53
179
diff --git a/block/backup.c b/block/backup.c
54
+ assert(bytes); /* Nothing good in aligning zero-length requests */
180
index XXXXXXX..XXXXXXX 100644
181
--- a/block/backup.c
182
+++ b/block/backup.c
183
@@ -XXX,XX +XXX,XX @@
184
* QEMU backup
185
*
186
* Copyright (C) 2013 Proxmox Server Solutions
187
+ * Copyright (c) 2019 Virtuozzo International GmbH.
188
*
189
* Authors:
190
* Dietmar Maurer (dietmar@proxmox.com)
191
@@ -XXX,XX +XXX,XX @@
192
#include "qemu/bitmap.h"
193
#include "qemu/error-report.h"
194
195
+#include "block/backup-top.h"
196
+
55
+
197
#define BACKUP_CLUSTER_SIZE_DEFAULT (1 << 16)
56
sum = pad->head + bytes + pad->tail;
198
57
pad->buf_len = (sum > align && pad->head && pad->tail) ? 2 * align : align;
199
typedef struct BackupBlockJob {
58
pad->buf = qemu_blockalign(bs, pad->buf_len);
200
BlockJob common;
59
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_preadv_part(BdrvChild *child,
201
+ BlockDriverState *backup_top;
60
return ret;
202
BlockDriverState *source_bs;
203
204
BdrvDirtyBitmap *sync_bitmap;
205
@@ -XXX,XX +XXX,XX @@ typedef struct BackupBlockJob {
206
BitmapSyncMode bitmap_mode;
207
BlockdevOnError on_source_error;
208
BlockdevOnError on_target_error;
209
- CoRwlock flush_rwlock;
210
uint64_t len;
211
uint64_t bytes_read;
212
int64_t cluster_size;
213
- NotifierWithReturn before_write;
214
215
BlockCopyState *bcs;
216
} BackupBlockJob;
217
@@ -XXX,XX +XXX,XX @@ static void backup_progress_reset_callback(void *opaque)
218
219
static int coroutine_fn backup_do_cow(BackupBlockJob *job,
220
int64_t offset, uint64_t bytes,
221
- bool *error_is_read,
222
- bool is_write_notifier)
223
+ bool *error_is_read)
224
{
225
int ret = 0;
226
int64_t start, end; /* bytes */
227
228
- qemu_co_rwlock_rdlock(&job->flush_rwlock);
229
-
230
start = QEMU_ALIGN_DOWN(offset, job->cluster_size);
231
end = QEMU_ALIGN_UP(bytes + offset, job->cluster_size);
232
233
trace_backup_do_cow_enter(job, start, offset, bytes);
234
235
- ret = block_copy(job->bcs, start, end - start, error_is_read,
236
- is_write_notifier);
237
+ ret = block_copy(job->bcs, start, end - start, error_is_read);
238
239
trace_backup_do_cow_return(job, offset, bytes, ret);
240
241
- qemu_co_rwlock_unlock(&job->flush_rwlock);
242
-
243
return ret;
244
}
245
246
-static int coroutine_fn backup_before_write_notify(
247
- NotifierWithReturn *notifier,
248
- void *opaque)
249
-{
250
- BackupBlockJob *job = container_of(notifier, BackupBlockJob, before_write);
251
- BdrvTrackedRequest *req = opaque;
252
-
253
- assert(req->bs == job->source_bs);
254
- assert(QEMU_IS_ALIGNED(req->offset, BDRV_SECTOR_SIZE));
255
- assert(QEMU_IS_ALIGNED(req->bytes, BDRV_SECTOR_SIZE));
256
-
257
- return backup_do_cow(job, req->offset, req->bytes, NULL, true);
258
-}
259
-
260
static void backup_cleanup_sync_bitmap(BackupBlockJob *job, int ret)
261
{
262
BdrvDirtyBitmap *bm;
263
@@ -XXX,XX +XXX,XX @@ static void backup_clean(Job *job)
264
{
265
BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
266
267
- block_copy_state_free(s->bcs);
268
+ bdrv_backup_top_drop(s->backup_top);
269
}
270
271
void backup_do_checkpoint(BlockJob *job, Error **errp)
272
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_loop(BackupBlockJob *job)
273
if (yield_and_check(job)) {
274
goto out;
275
}
276
- ret = backup_do_cow(job, offset,
277
- job->cluster_size, &error_is_read, false);
278
+ ret = backup_do_cow(job, offset, job->cluster_size, &error_is_read);
279
if (ret < 0 && backup_error_action(job, error_is_read, -ret) ==
280
BLOCK_ERROR_ACTION_REPORT)
281
{
282
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_run(Job *job, Error **errp)
283
BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
284
int ret = 0;
285
286
- qemu_co_rwlock_init(&s->flush_rwlock);
287
-
288
backup_init_copy_bitmap(s);
289
290
- s->before_write.notify = backup_before_write_notify;
291
- bdrv_add_before_write_notifier(s->source_bs, &s->before_write);
292
-
293
if (s->sync_mode == MIRROR_SYNC_MODE_TOP) {
294
int64_t offset = 0;
295
int64_t count;
296
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_run(Job *job, Error **errp)
297
}
61
}
298
62
299
out:
63
+ if (bytes == 0 && !QEMU_IS_ALIGNED(offset, bs->bl.request_alignment)) {
300
- notifier_with_return_remove(&s->before_write);
64
+ /*
301
-
65
+ * Aligning zero request is nonsense. Even if driver has special meaning
302
- /* wait until pending backup_do_cow() calls have completed */
66
+ * of zero-length (like qcow2_co_pwritev_compressed_part), we can't pass
303
- qemu_co_rwlock_wrlock(&s->flush_rwlock);
67
+ * it to driver due to request_alignment.
304
- qemu_co_rwlock_unlock(&s->flush_rwlock);
68
+ *
305
-
69
+ * Still, no reason to return an error if someone do unaligned
306
return ret;
70
+ * zero-length read occasionally.
307
}
71
+ */
308
72
+ return 0;
309
@@ -XXX,XX +XXX,XX @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
310
MirrorSyncMode sync_mode, BdrvDirtyBitmap *sync_bitmap,
311
BitmapSyncMode bitmap_mode,
312
bool compress,
313
+ const char *filter_node_name,
314
BlockdevOnError on_source_error,
315
BlockdevOnError on_target_error,
316
int creation_flags,
317
@@ -XXX,XX +XXX,XX @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
318
BackupBlockJob *job = NULL;
319
int64_t cluster_size;
320
BdrvRequestFlags write_flags;
321
+ BlockDriverState *backup_top = NULL;
322
+ BlockCopyState *bcs = NULL;
323
324
assert(bs);
325
assert(target);
326
@@ -XXX,XX +XXX,XX @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
327
write_flags = (bdrv_chain_contains(target, bs) ? BDRV_REQ_SERIALISING : 0) |
328
(compress ? BDRV_REQ_WRITE_COMPRESSED : 0),
329
330
+ backup_top = bdrv_backup_top_append(bs, target, filter_node_name,
331
+ cluster_size, write_flags, &bcs, errp);
332
+ if (!backup_top) {
333
+ goto error;
334
+ }
73
+ }
335
+
74
+
336
/* job->len is fixed, so we can't allow resize */
75
bdrv_inc_in_flight(bs);
337
- job = block_job_create(job_id, &backup_job_driver, txn, bs, 0, BLK_PERM_ALL,
76
338
+ job = block_job_create(job_id, &backup_job_driver, txn, backup_top,
77
/* Don't do copy-on-read if we read data before write operation */
339
+ 0, BLK_PERM_ALL,
78
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwritev_part(BdrvChild *child,
340
speed, creation_flags, cb, opaque, errp);
79
return -ENOTSUP;
341
if (!job) {
342
goto error;
343
}
80
}
344
81
345
+ job->backup_top = backup_top;
82
+ if (bytes == 0 && !QEMU_IS_ALIGNED(offset, bs->bl.request_alignment)) {
346
job->source_bs = bs;
83
+ /*
347
job->on_source_error = on_source_error;
84
+ * Aligning zero request is nonsense. Even if driver has special meaning
348
job->on_target_error = on_target_error;
85
+ * of zero-length (like qcow2_co_pwritev_compressed_part), we can't pass
349
job->sync_mode = sync_mode;
86
+ * it to driver due to request_alignment.
350
job->sync_bitmap = sync_bitmap;
87
+ *
351
job->bitmap_mode = bitmap_mode;
88
+ * Still, no reason to return an error if someone do unaligned
352
-
89
+ * zero-length write occasionally.
353
- job->bcs = block_copy_state_new(bs, target, cluster_size, write_flags,
90
+ */
354
- errp);
91
+ return 0;
355
- if (!job->bcs) {
92
+ }
356
- goto error;
93
+
357
- }
94
bdrv_inc_in_flight(bs);
358
-
359
+ job->bcs = bcs;
360
job->cluster_size = cluster_size;
361
job->len = len;
362
363
- block_copy_set_callbacks(job->bcs, backup_progress_bytes_callback,
364
+ block_copy_set_callbacks(bcs, backup_progress_bytes_callback,
365
backup_progress_reset_callback, job);
366
367
- /* Required permissions are already taken by block-copy-state target */
368
+ /* Required permissions are already taken by backup-top target */
369
block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL,
370
&error_abort);
371
372
@@ -XXX,XX +XXX,XX @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
373
if (job) {
374
backup_clean(&job->common.job);
375
job_early_fail(&job->common.job);
376
+ } else if (backup_top) {
377
+ bdrv_backup_top_drop(backup_top);
378
}
379
380
return NULL;
381
diff --git a/block/block-copy.c b/block/block-copy.c
382
index XXXXXXX..XXXXXXX 100644
383
--- a/block/block-copy.c
384
+++ b/block/block-copy.c
385
@@ -XXX,XX +XXX,XX @@ void block_copy_state_free(BlockCopyState *s)
386
return;
387
}
388
389
- bdrv_release_dirty_bitmap(blk_bs(s->source), s->copy_bitmap);
390
- blk_unref(s->source);
391
- blk_unref(s->target);
392
+ bdrv_release_dirty_bitmap(s->source->bs, s->copy_bitmap);
393
g_free(s);
394
}
395
396
-BlockCopyState *block_copy_state_new(BlockDriverState *source,
397
- BlockDriverState *target,
398
+BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target,
399
int64_t cluster_size,
400
BdrvRequestFlags write_flags, Error **errp)
401
{
402
BlockCopyState *s;
403
- int ret;
404
- uint64_t no_resize = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE |
405
- BLK_PERM_WRITE_UNCHANGED | BLK_PERM_GRAPH_MOD;
406
BdrvDirtyBitmap *copy_bitmap;
407
+ uint32_t max_transfer =
408
+ MIN_NON_ZERO(INT_MAX, MIN_NON_ZERO(source->bs->bl.max_transfer,
409
+ target->bs->bl.max_transfer));
410
411
- copy_bitmap = bdrv_create_dirty_bitmap(source, cluster_size, NULL, errp);
412
+ copy_bitmap = bdrv_create_dirty_bitmap(source->bs, cluster_size, NULL,
413
+ errp);
414
if (!copy_bitmap) {
415
return NULL;
416
}
417
@@ -XXX,XX +XXX,XX @@ BlockCopyState *block_copy_state_new(BlockDriverState *source,
418
419
s = g_new(BlockCopyState, 1);
420
*s = (BlockCopyState) {
421
- .source = blk_new(bdrv_get_aio_context(source),
422
- BLK_PERM_CONSISTENT_READ, no_resize),
423
- .target = blk_new(bdrv_get_aio_context(target),
424
- BLK_PERM_WRITE, no_resize),
425
+ .source = source,
426
+ .target = target,
427
.copy_bitmap = copy_bitmap,
428
.cluster_size = cluster_size,
429
.len = bdrv_dirty_bitmap_size(copy_bitmap),
430
.write_flags = write_flags,
431
};
432
433
- s->copy_range_size = QEMU_ALIGN_DOWN(MIN(blk_get_max_transfer(s->source),
434
- blk_get_max_transfer(s->target)),
435
- s->cluster_size);
436
+ s->copy_range_size = QEMU_ALIGN_DOWN(max_transfer, cluster_size),
437
/*
95
/*
438
* Set use_copy_range, consider the following:
96
* Align write if necessary by performing a read-modify-write cycle.
439
* 1. Compression is not supported for copy_range.
440
@@ -XXX,XX +XXX,XX @@ BlockCopyState *block_copy_state_new(BlockDriverState *source,
441
442
QLIST_INIT(&s->inflight_reqs);
443
444
- /*
445
- * We just allow aio context change on our block backends. block_copy() user
446
- * (now it's only backup) is responsible for source and target being in same
447
- * aio context.
448
- */
449
- blk_set_disable_request_queuing(s->source, true);
450
- blk_set_allow_aio_context_change(s->source, true);
451
- blk_set_disable_request_queuing(s->target, true);
452
- blk_set_allow_aio_context_change(s->target, true);
453
-
454
- ret = blk_insert_bs(s->source, source, errp);
455
- if (ret < 0) {
456
- goto fail;
457
- }
458
-
459
- ret = blk_insert_bs(s->target, target, errp);
460
- if (ret < 0) {
461
- goto fail;
462
- }
463
-
464
return s;
465
-
466
-fail:
467
- block_copy_state_free(s);
468
-
469
- return NULL;
470
}
471
472
void block_copy_set_callbacks(
473
@@ -XXX,XX +XXX,XX @@ void block_copy_set_callbacks(
474
static int coroutine_fn block_copy_with_bounce_buffer(BlockCopyState *s,
475
int64_t start,
476
int64_t end,
477
- bool is_write_notifier,
478
bool *error_is_read,
479
void **bounce_buffer)
480
{
481
int ret;
482
int nbytes;
483
- int read_flags = is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0;
484
485
assert(QEMU_IS_ALIGNED(start, s->cluster_size));
486
bdrv_reset_dirty_bitmap(s->copy_bitmap, start, s->cluster_size);
487
nbytes = MIN(s->cluster_size, s->len - start);
488
if (!*bounce_buffer) {
489
- *bounce_buffer = blk_blockalign(s->source, s->cluster_size);
490
+ *bounce_buffer = qemu_blockalign(s->source->bs, s->cluster_size);
491
}
492
493
- ret = blk_co_pread(s->source, start, nbytes, *bounce_buffer, read_flags);
494
+ ret = bdrv_co_pread(s->source, start, nbytes, *bounce_buffer, 0);
495
if (ret < 0) {
496
trace_block_copy_with_bounce_buffer_read_fail(s, start, ret);
497
if (error_is_read) {
498
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn block_copy_with_bounce_buffer(BlockCopyState *s,
499
goto fail;
500
}
501
502
- ret = blk_co_pwrite(s->target, start, nbytes, *bounce_buffer,
503
- s->write_flags);
504
+ ret = bdrv_co_pwrite(s->target, start, nbytes, *bounce_buffer,
505
+ s->write_flags);
506
if (ret < 0) {
507
trace_block_copy_with_bounce_buffer_write_fail(s, start, ret);
508
if (error_is_read) {
509
@@ -XXX,XX +XXX,XX @@ fail:
510
*/
511
static int coroutine_fn block_copy_with_offload(BlockCopyState *s,
512
int64_t start,
513
- int64_t end,
514
- bool is_write_notifier)
515
+ int64_t end)
516
{
517
int ret;
518
int nr_clusters;
519
int nbytes;
520
- int read_flags = is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0;
521
522
assert(QEMU_IS_ALIGNED(s->copy_range_size, s->cluster_size));
523
assert(QEMU_IS_ALIGNED(start, s->cluster_size));
524
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn block_copy_with_offload(BlockCopyState *s,
525
nr_clusters = DIV_ROUND_UP(nbytes, s->cluster_size);
526
bdrv_reset_dirty_bitmap(s->copy_bitmap, start,
527
s->cluster_size * nr_clusters);
528
- ret = blk_co_copy_range(s->source, start, s->target, start, nbytes,
529
- read_flags, s->write_flags);
530
+ ret = bdrv_co_copy_range(s->source, start, s->target, start, nbytes,
531
+ 0, s->write_flags);
532
if (ret < 0) {
533
trace_block_copy_with_offload_fail(s, start, ret);
534
bdrv_set_dirty_bitmap(s->copy_bitmap, start,
535
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn block_copy_with_offload(BlockCopyState *s,
536
static int block_copy_is_cluster_allocated(BlockCopyState *s, int64_t offset,
537
int64_t *pnum)
538
{
539
- BlockDriverState *bs = blk_bs(s->source);
540
+ BlockDriverState *bs = s->source->bs;
541
int64_t count, total_count = 0;
542
int64_t bytes = s->len - offset;
543
int ret;
544
@@ -XXX,XX +XXX,XX @@ int64_t block_copy_reset_unallocated(BlockCopyState *s,
545
546
int coroutine_fn block_copy(BlockCopyState *s,
547
int64_t start, uint64_t bytes,
548
- bool *error_is_read,
549
- bool is_write_notifier)
550
+ bool *error_is_read)
551
{
552
int ret = 0;
553
int64_t end = bytes + start; /* bytes */
554
@@ -XXX,XX +XXX,XX @@ int coroutine_fn block_copy(BlockCopyState *s,
555
* block_copy() user is responsible for keeping source and target in same
556
* aio context
557
*/
558
- assert(blk_get_aio_context(s->source) == blk_get_aio_context(s->target));
559
+ assert(bdrv_get_aio_context(s->source->bs) ==
560
+ bdrv_get_aio_context(s->target->bs));
561
562
assert(QEMU_IS_ALIGNED(start, s->cluster_size));
563
assert(QEMU_IS_ALIGNED(end, s->cluster_size));
564
@@ -XXX,XX +XXX,XX @@ int coroutine_fn block_copy(BlockCopyState *s,
565
trace_block_copy_process(s, start);
566
567
if (s->use_copy_range) {
568
- ret = block_copy_with_offload(s, start, dirty_end,
569
- is_write_notifier);
570
+ ret = block_copy_with_offload(s, start, dirty_end);
571
if (ret < 0) {
572
s->use_copy_range = false;
573
}
574
}
575
if (!s->use_copy_range) {
576
ret = block_copy_with_bounce_buffer(s, start, dirty_end,
577
- is_write_notifier,
578
error_is_read, &bounce_buffer);
579
}
580
if (ret < 0) {
581
diff --git a/block/replication.c b/block/replication.c
582
index XXXXXXX..XXXXXXX 100644
583
--- a/block/replication.c
584
+++ b/block/replication.c
585
@@ -XXX,XX +XXX,XX @@ static void replication_start(ReplicationState *rs, ReplicationMode mode,
586
587
s->backup_job = backup_job_create(
588
NULL, s->secondary_disk->bs, s->hidden_disk->bs,
589
- 0, MIRROR_SYNC_MODE_NONE, NULL, 0, false,
590
+ 0, MIRROR_SYNC_MODE_NONE, NULL, 0, false, NULL,
591
BLOCKDEV_ON_ERROR_REPORT,
592
BLOCKDEV_ON_ERROR_REPORT, JOB_INTERNAL,
593
backup_job_completed, bs, NULL, &local_err);
594
diff --git a/blockdev.c b/blockdev.c
595
index XXXXXXX..XXXXXXX 100644
596
--- a/blockdev.c
597
+++ b/blockdev.c
598
@@ -XXX,XX +XXX,XX @@ static BlockJob *do_backup_common(BackupCommon *backup,
599
job = backup_job_create(backup->job_id, bs, target_bs, backup->speed,
600
backup->sync, bmap, backup->bitmap_mode,
601
backup->compress,
602
+ backup->filter_node_name,
603
backup->on_source_error,
604
backup->on_target_error,
605
job_flags, NULL, NULL, txn, errp);
606
diff --git a/tests/qemu-iotests/056 b/tests/qemu-iotests/056
607
index XXXXXXX..XXXXXXX 100755
608
--- a/tests/qemu-iotests/056
609
+++ b/tests/qemu-iotests/056
610
@@ -XXX,XX +XXX,XX @@ class BackupTest(iotests.QMPTestCase):
611
self.vm = iotests.VM()
612
self.test_img = img_create('test')
613
self.dest_img = img_create('dest')
614
+ self.dest_img2 = img_create('dest2')
615
self.ref_img = img_create('ref')
616
self.vm.add_drive(self.test_img)
617
self.vm.launch()
618
@@ -XXX,XX +XXX,XX @@ class BackupTest(iotests.QMPTestCase):
619
self.vm.shutdown()
620
try_remove(self.test_img)
621
try_remove(self.dest_img)
622
+ try_remove(self.dest_img2)
623
try_remove(self.ref_img)
624
625
def hmp_io_writes(self, drive, patterns):
626
@@ -XXX,XX +XXX,XX @@ class BackupTest(iotests.QMPTestCase):
627
res = self.vm.qmp('query-block-jobs')
628
self.assert_qmp(res, 'return[0]/status', 'concluded')
629
# Leave zombie job un-dismissed, observe a failure:
630
- res = self.qmp_backup_and_wait(serror="Node 'drive0' is busy: block device is in use by block job: backup",
631
+ res = self.qmp_backup_and_wait(serror="Job ID 'drive0' already in use",
632
device='drive0', format=iotests.imgfmt,
633
- sync='full', target=self.dest_img,
634
+ sync='full', target=self.dest_img2,
635
auto_dismiss=False)
636
self.assertEqual(res, False)
637
# OK, dismiss the zombie.
638
@@ -XXX,XX +XXX,XX @@ class BackupTest(iotests.QMPTestCase):
639
self.assert_qmp(res, 'return', [])
640
# Ensure it's really gone.
641
self.qmp_backup_and_wait(device='drive0', format=iotests.imgfmt,
642
- sync='full', target=self.dest_img,
643
+ sync='full', target=self.dest_img2,
644
auto_dismiss=False)
645
646
def dismissal_failure(self, dismissal_opt):
647
diff --git a/tests/qemu-iotests/141.out b/tests/qemu-iotests/141.out
648
index XXXXXXX..XXXXXXX 100644
649
--- a/tests/qemu-iotests/141.out
650
+++ b/tests/qemu-iotests/141.out
651
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/m.
652
Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT backing_fmt=IMGFMT
653
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
654
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
655
-{"error": {"class": "GenericError", "desc": "Node drv0 is in use"}}
656
+{"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: node is used as backing hd of 'NODE_NAME'"}}
657
{"return": {}}
658
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}}
659
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 1048576, "offset": 0, "speed": 0, "type": "backup"}}
660
diff --git a/tests/qemu-iotests/257 b/tests/qemu-iotests/257
661
index XXXXXXX..XXXXXXX 100755
662
--- a/tests/qemu-iotests/257
663
+++ b/tests/qemu-iotests/257
664
@@ -XXX,XX +XXX,XX @@ def blockdev_backup(vm, device, target, sync, **kwargs):
665
device=device,
666
target=target,
667
sync=sync,
668
+ filter_node_name='backup-top',
669
**kwargs)
670
return result
671
672
@@ -XXX,XX +XXX,XX @@ def backup(drive, n, filepath, sync, **kwargs):
673
job_id=job_id, **kwargs)
674
return job_id
675
676
-def perform_writes(drive, n):
677
+def perform_writes(drive, n, filter_node_name=None):
678
log("--- Write #{:d} ---\n".format(n))
679
for pattern in GROUPS[n].patterns:
680
cmd = "write -P{:s} 0x{:07x} 0x{:x}".format(
681
@@ -XXX,XX +XXX,XX @@ def perform_writes(drive, n):
682
pattern.offset,
683
pattern.size)
684
log(cmd)
685
- log(drive.vm.hmp_qemu_io(drive.node, cmd))
686
+ log(drive.vm.hmp_qemu_io(filter_node_name or drive.node, cmd))
687
bitmaps = drive.vm.query_bitmaps()
688
log({'bitmaps': bitmaps}, indent=2)
689
log('')
690
@@ -XXX,XX +XXX,XX @@ def test_bitmap_sync(bsync_mode, msync_mode='bitmap', failure=None):
691
"""Issue writes while the job is open to test bitmap divergence."""
692
# Note: when `failure` is 'intermediate', this isn't called.
693
log('')
694
- bitmaps = perform_writes(drive0, 2)
695
+ bitmaps = perform_writes(drive0, 2, filter_node_name='backup-top')
696
# Named bitmap (static, should be unchanged)
697
ebitmap.compare(vm.get_bitmap(drive0.node, 'bitmap0',
698
bitmaps=bitmaps))
699
diff --git a/tests/qemu-iotests/257.out b/tests/qemu-iotests/257.out
700
index XXXXXXX..XXXXXXX 100644
701
--- a/tests/qemu-iotests/257.out
702
+++ b/tests/qemu-iotests/257.out
703
@@ -XXX,XX +XXX,XX @@ write -P0x76 0x3ff0000 0x10000
704
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
705
{"return": {}}
706
{}
707
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
708
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
709
{"return": {}}
710
{"data": {"device": "ref_backup_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
711
712
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
713
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
714
{"return": {}}
715
{}
716
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
717
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
718
{"return": {}}
719
{"data": {"device": "ref_backup_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
720
721
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
722
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
723
{"return": {}}
724
{}
725
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "job-id": "backup_1", "sync": "bitmap", "target": "backup_target_1"}}
726
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_1", "sync": "bitmap", "target": "backup_target_1"}}
727
{"return": {}}
728
729
--- Write #2 ---
730
@@ -XXX,XX +XXX,XX @@ expecting 15 dirty sectors; have 15. OK!
731
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
732
{"return": {}}
733
{}
734
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
735
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
736
{"return": {}}
737
{"data": {"device": "ref_backup_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
738
739
@@ -XXX,XX +XXX,XX @@ expecting 15 dirty sectors; have 15. OK!
740
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
741
{"return": {}}
742
{}
743
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
744
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
745
{"return": {}}
746
{"execute": "job-finalize", "arguments": {"id": "backup_2"}}
747
{"return": {}}
748
@@ -XXX,XX +XXX,XX @@ write -P0x76 0x3ff0000 0x10000
749
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
750
{"return": {}}
751
{}
752
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
753
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
754
{"return": {}}
755
{"data": {"device": "ref_backup_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
756
757
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
758
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
759
{"return": {}}
760
{}
761
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
762
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
763
{"return": {}}
764
{"data": {"device": "ref_backup_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
765
766
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
767
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
768
{"return": {}}
769
{}
770
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "job-id": "backup_1", "sync": "bitmap", "target": "backup_target_1"}}
771
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_1", "sync": "bitmap", "target": "backup_target_1"}}
772
{"return": {}}
773
{"data": {"action": "report", "device": "backup_1", "operation": "read"}, "event": "BLOCK_JOB_ERROR", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
774
{"data": {"device": "backup_1", "error": "Input/output error", "len": 393216, "offset": 65536, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
775
@@ -XXX,XX +XXX,XX @@ expecting 14 dirty sectors; have 14. OK!
776
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
777
{"return": {}}
778
{}
779
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
780
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
781
{"return": {}}
782
{"data": {"device": "ref_backup_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
783
784
@@ -XXX,XX +XXX,XX @@ expecting 14 dirty sectors; have 14. OK!
785
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
786
{"return": {}}
787
{}
788
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
789
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
790
{"return": {}}
791
{"execute": "job-finalize", "arguments": {"id": "backup_2"}}
792
{"return": {}}
793
@@ -XXX,XX +XXX,XX @@ write -P0x76 0x3ff0000 0x10000
794
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
795
{"return": {}}
796
{}
797
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
798
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
799
{"return": {}}
800
{"data": {"device": "ref_backup_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
801
802
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
803
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
804
{"return": {}}
805
{}
806
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
807
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
808
{"return": {}}
809
{"data": {"device": "ref_backup_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
810
811
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
812
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
813
{"return": {}}
814
{}
815
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "job-id": "backup_1", "sync": "bitmap", "target": "backup_target_1"}}
816
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_1", "sync": "bitmap", "target": "backup_target_1"}}
817
{"return": {}}
818
819
--- Write #2 ---
820
@@ -XXX,XX +XXX,XX @@ expecting 15 dirty sectors; have 15. OK!
821
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
822
{"return": {}}
823
{}
824
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
825
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
826
{"return": {}}
827
{"data": {"device": "ref_backup_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
828
829
@@ -XXX,XX +XXX,XX @@ expecting 15 dirty sectors; have 15. OK!
830
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
831
{"return": {}}
832
{}
833
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
834
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
835
{"return": {}}
836
{"execute": "job-finalize", "arguments": {"id": "backup_2"}}
837
{"return": {}}
838
@@ -XXX,XX +XXX,XX @@ write -P0x76 0x3ff0000 0x10000
839
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
840
{"return": {}}
841
{}
842
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
843
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
844
{"return": {}}
845
{"data": {"device": "ref_backup_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
846
847
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
848
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
849
{"return": {}}
850
{}
851
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
852
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
853
{"return": {}}
854
{"data": {"device": "ref_backup_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
855
856
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
857
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
858
{"return": {}}
859
{}
860
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "job-id": "backup_1", "sync": "bitmap", "target": "backup_target_1"}}
861
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_1", "sync": "bitmap", "target": "backup_target_1"}}
862
{"return": {}}
863
864
--- Write #2 ---
865
@@ -XXX,XX +XXX,XX @@ expecting 15 dirty sectors; have 15. OK!
866
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
867
{"return": {}}
868
{}
869
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
870
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
871
{"return": {}}
872
{"data": {"device": "ref_backup_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
873
874
@@ -XXX,XX +XXX,XX @@ expecting 15 dirty sectors; have 15. OK!
875
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
876
{"return": {}}
877
{}
878
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
879
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
880
{"return": {}}
881
{"execute": "job-finalize", "arguments": {"id": "backup_2"}}
882
{"return": {}}
883
@@ -XXX,XX +XXX,XX @@ write -P0x76 0x3ff0000 0x10000
884
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
885
{"return": {}}
886
{}
887
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
888
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
889
{"return": {}}
890
{"data": {"device": "ref_backup_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
891
892
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
893
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
894
{"return": {}}
895
{}
896
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
897
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
898
{"return": {}}
899
{"data": {"device": "ref_backup_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
900
901
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
902
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
903
{"return": {}}
904
{}
905
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "job-id": "backup_1", "sync": "bitmap", "target": "backup_target_1"}}
906
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_1", "sync": "bitmap", "target": "backup_target_1"}}
907
{"return": {}}
908
{"data": {"action": "report", "device": "backup_1", "operation": "read"}, "event": "BLOCK_JOB_ERROR", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
909
{"data": {"device": "backup_1", "error": "Input/output error", "len": 393216, "offset": 65536, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
910
@@ -XXX,XX +XXX,XX @@ expecting 14 dirty sectors; have 14. OK!
911
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
912
{"return": {}}
913
{}
914
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
915
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
916
{"return": {}}
917
{"data": {"device": "ref_backup_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
918
919
@@ -XXX,XX +XXX,XX @@ expecting 14 dirty sectors; have 14. OK!
920
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
921
{"return": {}}
922
{}
923
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
924
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
925
{"return": {}}
926
{"execute": "job-finalize", "arguments": {"id": "backup_2"}}
927
{"return": {}}
928
@@ -XXX,XX +XXX,XX @@ write -P0x76 0x3ff0000 0x10000
929
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
930
{"return": {}}
931
{}
932
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
933
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
934
{"return": {}}
935
{"data": {"device": "ref_backup_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
936
937
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
938
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
939
{"return": {}}
940
{}
941
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
942
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
943
{"return": {}}
944
{"data": {"device": "ref_backup_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
945
946
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
947
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
948
{"return": {}}
949
{}
950
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "job-id": "backup_1", "sync": "bitmap", "target": "backup_target_1"}}
951
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_1", "sync": "bitmap", "target": "backup_target_1"}}
952
{"return": {}}
953
954
--- Write #2 ---
955
@@ -XXX,XX +XXX,XX @@ expecting 12 dirty sectors; have 12. OK!
956
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
957
{"return": {}}
958
{}
959
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
960
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
961
{"return": {}}
962
{"data": {"device": "ref_backup_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
963
964
@@ -XXX,XX +XXX,XX @@ expecting 12 dirty sectors; have 12. OK!
965
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
966
{"return": {}}
967
{}
968
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
969
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
970
{"return": {}}
971
{"execute": "job-finalize", "arguments": {"id": "backup_2"}}
972
{"return": {}}
973
@@ -XXX,XX +XXX,XX @@ write -P0x76 0x3ff0000 0x10000
974
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
975
{"return": {}}
976
{}
977
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
978
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
979
{"return": {}}
980
{"data": {"device": "ref_backup_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
981
982
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
983
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
984
{"return": {}}
985
{}
986
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
987
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
988
{"return": {}}
989
{"data": {"device": "ref_backup_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
990
991
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
992
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
993
{"return": {}}
994
{}
995
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "job-id": "backup_1", "sync": "bitmap", "target": "backup_target_1"}}
996
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_1", "sync": "bitmap", "target": "backup_target_1"}}
997
{"return": {}}
998
999
--- Write #2 ---
1000
@@ -XXX,XX +XXX,XX @@ expecting 12 dirty sectors; have 12. OK!
1001
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1002
{"return": {}}
1003
{}
1004
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
1005
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
1006
{"return": {}}
1007
{"data": {"device": "ref_backup_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1008
1009
@@ -XXX,XX +XXX,XX @@ expecting 12 dirty sectors; have 12. OK!
1010
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1011
{"return": {}}
1012
{}
1013
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
1014
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
1015
{"return": {}}
1016
{"execute": "job-finalize", "arguments": {"id": "backup_2"}}
1017
{"return": {}}
1018
@@ -XXX,XX +XXX,XX @@ write -P0x76 0x3ff0000 0x10000
1019
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1020
{"return": {}}
1021
{}
1022
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
1023
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
1024
{"return": {}}
1025
{"data": {"device": "ref_backup_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1026
1027
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1028
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1029
{"return": {}}
1030
{}
1031
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
1032
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
1033
{"return": {}}
1034
{"data": {"device": "ref_backup_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1035
1036
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1037
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1038
{"return": {}}
1039
{}
1040
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "job-id": "backup_1", "sync": "bitmap", "target": "backup_target_1"}}
1041
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_1", "sync": "bitmap", "target": "backup_target_1"}}
1042
{"return": {}}
1043
{"data": {"action": "report", "device": "backup_1", "operation": "read"}, "event": "BLOCK_JOB_ERROR", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1044
{"data": {"device": "backup_1", "error": "Input/output error", "len": 393216, "offset": 65536, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1045
@@ -XXX,XX +XXX,XX @@ expecting 13 dirty sectors; have 13. OK!
1046
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1047
{"return": {}}
1048
{}
1049
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
1050
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
1051
{"return": {}}
1052
{"data": {"device": "ref_backup_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1053
1054
@@ -XXX,XX +XXX,XX @@ expecting 13 dirty sectors; have 13. OK!
1055
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1056
{"return": {}}
1057
{}
1058
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
1059
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
1060
{"return": {}}
1061
{"execute": "job-finalize", "arguments": {"id": "backup_2"}}
1062
{"return": {}}
1063
@@ -XXX,XX +XXX,XX @@ write -P0x76 0x3ff0000 0x10000
1064
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1065
{"return": {}}
1066
{}
1067
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
1068
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
1069
{"return": {}}
1070
{"data": {"device": "ref_backup_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1071
1072
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1073
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1074
{"return": {}}
1075
{}
1076
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
1077
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
1078
{"return": {}}
1079
{"data": {"device": "ref_backup_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1080
1081
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1082
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1083
{"return": {}}
1084
{}
1085
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "job-id": "backup_1", "sync": "bitmap", "target": "backup_target_1"}}
1086
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_1", "sync": "bitmap", "target": "backup_target_1"}}
1087
{"return": {}}
1088
1089
--- Write #2 ---
1090
@@ -XXX,XX +XXX,XX @@ expecting 12 dirty sectors; have 12. OK!
1091
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1092
{"return": {}}
1093
{}
1094
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
1095
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
1096
{"return": {}}
1097
{"data": {"device": "ref_backup_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1098
1099
@@ -XXX,XX +XXX,XX @@ expecting 12 dirty sectors; have 12. OK!
1100
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1101
{"return": {}}
1102
{}
1103
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
1104
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
1105
{"return": {}}
1106
{"execute": "job-finalize", "arguments": {"id": "backup_2"}}
1107
{"return": {}}
1108
@@ -XXX,XX +XXX,XX @@ write -P0x76 0x3ff0000 0x10000
1109
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1110
{"return": {}}
1111
{}
1112
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
1113
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
1114
{"return": {}}
1115
{"data": {"device": "ref_backup_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1116
1117
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1118
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1119
{"return": {}}
1120
{}
1121
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
1122
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
1123
{"return": {}}
1124
{"data": {"device": "ref_backup_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1125
1126
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1127
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1128
{"return": {}}
1129
{}
1130
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "job-id": "backup_1", "sync": "full", "target": "backup_target_1"}}
1131
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_1", "sync": "full", "target": "backup_target_1"}}
1132
{"return": {}}
1133
1134
--- Write #2 ---
1135
@@ -XXX,XX +XXX,XX @@ expecting 15 dirty sectors; have 15. OK!
1136
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1137
{"return": {}}
1138
{}
1139
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
1140
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
1141
{"return": {}}
1142
{"data": {"device": "ref_backup_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1143
1144
@@ -XXX,XX +XXX,XX @@ expecting 15 dirty sectors; have 15. OK!
1145
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1146
{"return": {}}
1147
{}
1148
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
1149
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
1150
{"return": {}}
1151
{"execute": "job-finalize", "arguments": {"id": "backup_2"}}
1152
{"return": {}}
1153
@@ -XXX,XX +XXX,XX @@ write -P0x76 0x3ff0000 0x10000
1154
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1155
{"return": {}}
1156
{}
1157
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
1158
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
1159
{"return": {}}
1160
{"data": {"device": "ref_backup_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1161
1162
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1163
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1164
{"return": {}}
1165
{}
1166
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
1167
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
1168
{"return": {}}
1169
{"data": {"device": "ref_backup_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1170
1171
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1172
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1173
{"return": {}}
1174
{}
1175
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "job-id": "backup_1", "sync": "full", "target": "backup_target_1"}}
1176
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_1", "sync": "full", "target": "backup_target_1"}}
1177
{"return": {}}
1178
{"data": {"action": "report", "device": "backup_1", "operation": "read"}, "event": "BLOCK_JOB_ERROR", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1179
{"data": {"device": "backup_1", "error": "Input/output error", "len": 67108864, "offset": 983040, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1180
@@ -XXX,XX +XXX,XX @@ expecting 14 dirty sectors; have 14. OK!
1181
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1182
{"return": {}}
1183
{}
1184
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
1185
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
1186
{"return": {}}
1187
{"data": {"device": "ref_backup_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1188
1189
@@ -XXX,XX +XXX,XX @@ expecting 14 dirty sectors; have 14. OK!
1190
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1191
{"return": {}}
1192
{}
1193
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
1194
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
1195
{"return": {}}
1196
{"execute": "job-finalize", "arguments": {"id": "backup_2"}}
1197
{"return": {}}
1198
@@ -XXX,XX +XXX,XX @@ write -P0x76 0x3ff0000 0x10000
1199
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1200
{"return": {}}
1201
{}
1202
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
1203
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
1204
{"return": {}}
1205
{"data": {"device": "ref_backup_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1206
1207
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1208
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1209
{"return": {}}
1210
{}
1211
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
1212
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
1213
{"return": {}}
1214
{"data": {"device": "ref_backup_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1215
1216
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1217
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1218
{"return": {}}
1219
{}
1220
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "job-id": "backup_1", "sync": "full", "target": "backup_target_1"}}
1221
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_1", "sync": "full", "target": "backup_target_1"}}
1222
{"return": {}}
1223
1224
--- Write #2 ---
1225
@@ -XXX,XX +XXX,XX @@ expecting 12 dirty sectors; have 12. OK!
1226
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1227
{"return": {}}
1228
{}
1229
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
1230
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
1231
{"return": {}}
1232
{"data": {"device": "ref_backup_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1233
1234
@@ -XXX,XX +XXX,XX @@ expecting 12 dirty sectors; have 12. OK!
1235
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1236
{"return": {}}
1237
{}
1238
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
1239
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
1240
{"return": {}}
1241
{"execute": "job-finalize", "arguments": {"id": "backup_2"}}
1242
{"return": {}}
1243
@@ -XXX,XX +XXX,XX @@ write -P0x76 0x3ff0000 0x10000
1244
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1245
{"return": {}}
1246
{}
1247
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
1248
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
1249
{"return": {}}
1250
{"data": {"device": "ref_backup_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1251
1252
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1253
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1254
{"return": {}}
1255
{}
1256
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
1257
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
1258
{"return": {}}
1259
{"data": {"device": "ref_backup_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1260
1261
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1262
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1263
{"return": {}}
1264
{}
1265
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "job-id": "backup_1", "sync": "full", "target": "backup_target_1"}}
1266
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_1", "sync": "full", "target": "backup_target_1"}}
1267
{"return": {}}
1268
1269
--- Write #2 ---
1270
@@ -XXX,XX +XXX,XX @@ expecting 12 dirty sectors; have 12. OK!
1271
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1272
{"return": {}}
1273
{}
1274
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
1275
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
1276
{"return": {}}
1277
{"data": {"device": "ref_backup_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1278
1279
@@ -XXX,XX +XXX,XX @@ expecting 12 dirty sectors; have 12. OK!
1280
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1281
{"return": {}}
1282
{}
1283
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
1284
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
1285
{"return": {}}
1286
{"execute": "job-finalize", "arguments": {"id": "backup_2"}}
1287
{"return": {}}
1288
@@ -XXX,XX +XXX,XX @@ write -P0x76 0x3ff0000 0x10000
1289
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1290
{"return": {}}
1291
{}
1292
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
1293
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
1294
{"return": {}}
1295
{"data": {"device": "ref_backup_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1296
1297
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1298
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1299
{"return": {}}
1300
{}
1301
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
1302
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
1303
{"return": {}}
1304
{"data": {"device": "ref_backup_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1305
1306
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1307
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1308
{"return": {}}
1309
{}
1310
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "job-id": "backup_1", "sync": "full", "target": "backup_target_1"}}
1311
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_1", "sync": "full", "target": "backup_target_1"}}
1312
{"return": {}}
1313
{"data": {"action": "report", "device": "backup_1", "operation": "read"}, "event": "BLOCK_JOB_ERROR", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1314
{"data": {"device": "backup_1", "error": "Input/output error", "len": 67108864, "offset": 983040, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1315
@@ -XXX,XX +XXX,XX @@ expecting 1014 dirty sectors; have 1014. OK!
1316
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1317
{"return": {}}
1318
{}
1319
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
1320
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
1321
{"return": {}}
1322
{"data": {"device": "ref_backup_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1323
1324
@@ -XXX,XX +XXX,XX @@ expecting 1014 dirty sectors; have 1014. OK!
1325
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1326
{"return": {}}
1327
{}
1328
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
1329
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
1330
{"return": {}}
1331
{"execute": "job-finalize", "arguments": {"id": "backup_2"}}
1332
{"return": {}}
1333
@@ -XXX,XX +XXX,XX @@ write -P0x76 0x3ff0000 0x10000
1334
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1335
{"return": {}}
1336
{}
1337
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
1338
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
1339
{"return": {}}
1340
{"data": {"device": "ref_backup_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1341
1342
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1343
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1344
{"return": {}}
1345
{}
1346
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
1347
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
1348
{"return": {}}
1349
{"data": {"device": "ref_backup_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1350
1351
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1352
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1353
{"return": {}}
1354
{}
1355
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "job-id": "backup_1", "sync": "full", "target": "backup_target_1"}}
1356
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_1", "sync": "full", "target": "backup_target_1"}}
1357
{"return": {}}
1358
1359
--- Write #2 ---
1360
@@ -XXX,XX +XXX,XX @@ expecting 12 dirty sectors; have 12. OK!
1361
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1362
{"return": {}}
1363
{}
1364
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
1365
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
1366
{"return": {}}
1367
{"data": {"device": "ref_backup_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1368
1369
@@ -XXX,XX +XXX,XX @@ expecting 12 dirty sectors; have 12. OK!
1370
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1371
{"return": {}}
1372
{}
1373
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
1374
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
1375
{"return": {}}
1376
{"execute": "job-finalize", "arguments": {"id": "backup_2"}}
1377
{"return": {}}
1378
@@ -XXX,XX +XXX,XX @@ write -P0x76 0x3ff0000 0x10000
1379
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1380
{"return": {}}
1381
{}
1382
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
1383
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
1384
{"return": {}}
1385
{"data": {"device": "ref_backup_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1386
1387
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1388
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1389
{"return": {}}
1390
{}
1391
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
1392
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
1393
{"return": {}}
1394
{"data": {"device": "ref_backup_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1395
1396
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1397
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1398
{"return": {}}
1399
{}
1400
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "job-id": "backup_1", "sync": "top", "target": "backup_target_1"}}
1401
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_1", "sync": "top", "target": "backup_target_1"}}
1402
{"return": {}}
1403
1404
--- Write #2 ---
1405
@@ -XXX,XX +XXX,XX @@ expecting 15 dirty sectors; have 15. OK!
1406
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1407
{"return": {}}
1408
{}
1409
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
1410
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
1411
{"return": {}}
1412
{"data": {"device": "ref_backup_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1413
1414
@@ -XXX,XX +XXX,XX @@ expecting 15 dirty sectors; have 15. OK!
1415
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1416
{"return": {}}
1417
{}
1418
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
1419
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
1420
{"return": {}}
1421
{"execute": "job-finalize", "arguments": {"id": "backup_2"}}
1422
{"return": {}}
1423
@@ -XXX,XX +XXX,XX @@ write -P0x76 0x3ff0000 0x10000
1424
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1425
{"return": {}}
1426
{}
1427
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
1428
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
1429
{"return": {}}
1430
{"data": {"device": "ref_backup_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1431
1432
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1433
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1434
{"return": {}}
1435
{}
1436
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
1437
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
1438
{"return": {}}
1439
{"data": {"device": "ref_backup_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1440
1441
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1442
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1443
{"return": {}}
1444
{}
1445
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "job-id": "backup_1", "sync": "top", "target": "backup_target_1"}}
1446
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_1", "sync": "top", "target": "backup_target_1"}}
1447
{"return": {}}
1448
{"data": {"action": "report", "device": "backup_1", "operation": "read"}, "event": "BLOCK_JOB_ERROR", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1449
{"data": {"device": "backup_1", "error": "Input/output error", "len": 458752, "offset": 65536, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1450
@@ -XXX,XX +XXX,XX @@ expecting 14 dirty sectors; have 14. OK!
1451
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1452
{"return": {}}
1453
{}
1454
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
1455
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
1456
{"return": {}}
1457
{"data": {"device": "ref_backup_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1458
1459
@@ -XXX,XX +XXX,XX @@ expecting 14 dirty sectors; have 14. OK!
1460
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1461
{"return": {}}
1462
{}
1463
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
1464
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
1465
{"return": {}}
1466
{"execute": "job-finalize", "arguments": {"id": "backup_2"}}
1467
{"return": {}}
1468
@@ -XXX,XX +XXX,XX @@ write -P0x76 0x3ff0000 0x10000
1469
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1470
{"return": {}}
1471
{}
1472
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
1473
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
1474
{"return": {}}
1475
{"data": {"device": "ref_backup_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1476
1477
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1478
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1479
{"return": {}}
1480
{}
1481
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
1482
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
1483
{"return": {}}
1484
{"data": {"device": "ref_backup_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1485
1486
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1487
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1488
{"return": {}}
1489
{}
1490
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "job-id": "backup_1", "sync": "top", "target": "backup_target_1"}}
1491
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_1", "sync": "top", "target": "backup_target_1"}}
1492
{"return": {}}
1493
1494
--- Write #2 ---
1495
@@ -XXX,XX +XXX,XX @@ expecting 12 dirty sectors; have 12. OK!
1496
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1497
{"return": {}}
1498
{}
1499
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
1500
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
1501
{"return": {}}
1502
{"data": {"device": "ref_backup_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1503
1504
@@ -XXX,XX +XXX,XX @@ expecting 12 dirty sectors; have 12. OK!
1505
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1506
{"return": {}}
1507
{}
1508
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
1509
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
1510
{"return": {}}
1511
{"execute": "job-finalize", "arguments": {"id": "backup_2"}}
1512
{"return": {}}
1513
@@ -XXX,XX +XXX,XX @@ write -P0x76 0x3ff0000 0x10000
1514
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1515
{"return": {}}
1516
{}
1517
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
1518
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
1519
{"return": {}}
1520
{"data": {"device": "ref_backup_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1521
1522
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1523
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1524
{"return": {}}
1525
{}
1526
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
1527
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
1528
{"return": {}}
1529
{"data": {"device": "ref_backup_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1530
1531
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1532
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1533
{"return": {}}
1534
{}
1535
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "job-id": "backup_1", "sync": "top", "target": "backup_target_1"}}
1536
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_1", "sync": "top", "target": "backup_target_1"}}
1537
{"return": {}}
1538
1539
--- Write #2 ---
1540
@@ -XXX,XX +XXX,XX @@ expecting 12 dirty sectors; have 12. OK!
1541
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1542
{"return": {}}
1543
{}
1544
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
1545
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
1546
{"return": {}}
1547
{"data": {"device": "ref_backup_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1548
1549
@@ -XXX,XX +XXX,XX @@ expecting 12 dirty sectors; have 12. OK!
1550
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1551
{"return": {}}
1552
{}
1553
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
1554
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
1555
{"return": {}}
1556
{"execute": "job-finalize", "arguments": {"id": "backup_2"}}
1557
{"return": {}}
1558
@@ -XXX,XX +XXX,XX @@ write -P0x76 0x3ff0000 0x10000
1559
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1560
{"return": {}}
1561
{}
1562
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
1563
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
1564
{"return": {}}
1565
{"data": {"device": "ref_backup_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1566
1567
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1568
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1569
{"return": {}}
1570
{}
1571
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
1572
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
1573
{"return": {}}
1574
{"data": {"device": "ref_backup_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1575
1576
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1577
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1578
{"return": {}}
1579
{}
1580
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "job-id": "backup_1", "sync": "top", "target": "backup_target_1"}}
1581
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_1", "sync": "top", "target": "backup_target_1"}}
1582
{"return": {}}
1583
{"data": {"action": "report", "device": "backup_1", "operation": "read"}, "event": "BLOCK_JOB_ERROR", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1584
{"data": {"device": "backup_1", "error": "Input/output error", "len": 458752, "offset": 65536, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1585
@@ -XXX,XX +XXX,XX @@ expecting 14 dirty sectors; have 14. OK!
1586
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1587
{"return": {}}
1588
{}
1589
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
1590
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
1591
{"return": {}}
1592
{"data": {"device": "ref_backup_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1593
1594
@@ -XXX,XX +XXX,XX @@ expecting 14 dirty sectors; have 14. OK!
1595
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1596
{"return": {}}
1597
{}
1598
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
1599
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
1600
{"return": {}}
1601
{"execute": "job-finalize", "arguments": {"id": "backup_2"}}
1602
{"return": {}}
1603
@@ -XXX,XX +XXX,XX @@ write -P0x76 0x3ff0000 0x10000
1604
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1605
{"return": {}}
1606
{}
1607
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
1608
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_0", "sync": "full", "target": "ref_target_0"}}
1609
{"return": {}}
1610
{"data": {"device": "ref_backup_0", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1611
1612
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1613
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1614
{"return": {}}
1615
{}
1616
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
1617
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_1", "sync": "full", "target": "ref_target_1"}}
1618
{"return": {}}
1619
{"data": {"device": "ref_backup_1", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1620
1621
@@ -XXX,XX +XXX,XX @@ expecting 6 dirty sectors; have 6. OK!
1622
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1623
{"return": {}}
1624
{}
1625
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "job-id": "backup_1", "sync": "top", "target": "backup_target_1"}}
1626
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_1", "sync": "top", "target": "backup_target_1"}}
1627
{"return": {}}
1628
1629
--- Write #2 ---
1630
@@ -XXX,XX +XXX,XX @@ expecting 12 dirty sectors; have 12. OK!
1631
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1632
{"return": {}}
1633
{}
1634
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
1635
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "ref_backup_2", "sync": "full", "target": "ref_target_2"}}
1636
{"return": {}}
1637
{"data": {"device": "ref_backup_2", "len": 67108864, "offset": 67108864, "speed": 0, "type": "backup"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
1638
1639
@@ -XXX,XX +XXX,XX @@ expecting 12 dirty sectors; have 12. OK!
1640
{"execute": "job-dismiss", "arguments": {"id": "bdc-fmt-job"}}
1641
{"return": {}}
1642
{}
1643
-{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
1644
+{"execute": "blockdev-backup", "arguments": {"auto-finalize": false, "bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "backup-top", "job-id": "backup_2", "sync": "bitmap", "target": "backup_target_2"}}
1645
{"return": {}}
1646
{"execute": "job-finalize", "arguments": {"id": "backup_2"}}
1647
{"return": {}}
1648
@@ -XXX,XX +XXX,XX @@ qemu_img compare "TEST_DIR/PID-img" "TEST_DIR/PID-fbackup2" ==> Identical, OK!
1649
1650
-- Sync mode incremental tests --
1651
1652
-{"execute": "blockdev-backup", "arguments": {"bitmap-mode": "on-success", "device": "drive0", "job-id": "api_job", "sync": "incremental", "target": "backup_target"}}
1653
+{"execute": "blockdev-backup", "arguments": {"bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "incremental", "target": "backup_target"}}
1654
{"error": {"class": "GenericError", "desc": "must provide a valid bitmap name for 'incremental' sync mode"}}
1655
1656
-{"execute": "blockdev-backup", "arguments": {"bitmap-mode": "always", "device": "drive0", "job-id": "api_job", "sync": "incremental", "target": "backup_target"}}
1657
+{"execute": "blockdev-backup", "arguments": {"bitmap-mode": "always", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "incremental", "target": "backup_target"}}
1658
{"error": {"class": "GenericError", "desc": "must provide a valid bitmap name for 'incremental' sync mode"}}
1659
1660
-{"execute": "blockdev-backup", "arguments": {"bitmap-mode": "never", "device": "drive0", "job-id": "api_job", "sync": "incremental", "target": "backup_target"}}
1661
+{"execute": "blockdev-backup", "arguments": {"bitmap-mode": "never", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "incremental", "target": "backup_target"}}
1662
{"error": {"class": "GenericError", "desc": "must provide a valid bitmap name for 'incremental' sync mode"}}
1663
1664
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "api_job", "sync": "incremental", "target": "backup_target"}}
1665
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "incremental", "target": "backup_target"}}
1666
{"error": {"class": "GenericError", "desc": "must provide a valid bitmap name for 'incremental' sync mode"}}
1667
1668
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "on-success", "device": "drive0", "job-id": "api_job", "sync": "incremental", "target": "backup_target"}}
1669
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "incremental", "target": "backup_target"}}
1670
{"error": {"class": "GenericError", "desc": "Bitmap 'bitmap404' could not be found"}}
1671
1672
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "always", "device": "drive0", "job-id": "api_job", "sync": "incremental", "target": "backup_target"}}
1673
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "incremental", "target": "backup_target"}}
1674
{"error": {"class": "GenericError", "desc": "Bitmap sync mode must be 'on-success' when using sync mode 'incremental'"}}
1675
1676
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "never", "device": "drive0", "job-id": "api_job", "sync": "incremental", "target": "backup_target"}}
1677
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "incremental", "target": "backup_target"}}
1678
{"error": {"class": "GenericError", "desc": "Bitmap sync mode must be 'on-success' when using sync mode 'incremental'"}}
1679
1680
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "device": "drive0", "job-id": "api_job", "sync": "incremental", "target": "backup_target"}}
1681
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "incremental", "target": "backup_target"}}
1682
{"error": {"class": "GenericError", "desc": "Bitmap 'bitmap404' could not be found"}}
1683
1684
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "job-id": "api_job", "sync": "incremental", "target": "backup_target"}}
1685
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "incremental", "target": "backup_target"}}
1686
{"error": {"class": "GenericError", "desc": "Bitmap sync mode must be 'on-success' when using sync mode 'incremental'"}}
1687
1688
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "job-id": "api_job", "sync": "incremental", "target": "backup_target"}}
1689
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "incremental", "target": "backup_target"}}
1690
{"error": {"class": "GenericError", "desc": "Bitmap sync mode must be 'on-success' when using sync mode 'incremental'"}}
1691
1692
-- Sync mode bitmap tests --
1693
1694
-{"execute": "blockdev-backup", "arguments": {"bitmap-mode": "on-success", "device": "drive0", "job-id": "api_job", "sync": "bitmap", "target": "backup_target"}}
1695
+{"execute": "blockdev-backup", "arguments": {"bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "bitmap", "target": "backup_target"}}
1696
{"error": {"class": "GenericError", "desc": "must provide a valid bitmap name for 'bitmap' sync mode"}}
1697
1698
-{"execute": "blockdev-backup", "arguments": {"bitmap-mode": "always", "device": "drive0", "job-id": "api_job", "sync": "bitmap", "target": "backup_target"}}
1699
+{"execute": "blockdev-backup", "arguments": {"bitmap-mode": "always", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "bitmap", "target": "backup_target"}}
1700
{"error": {"class": "GenericError", "desc": "must provide a valid bitmap name for 'bitmap' sync mode"}}
1701
1702
-{"execute": "blockdev-backup", "arguments": {"bitmap-mode": "never", "device": "drive0", "job-id": "api_job", "sync": "bitmap", "target": "backup_target"}}
1703
+{"execute": "blockdev-backup", "arguments": {"bitmap-mode": "never", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "bitmap", "target": "backup_target"}}
1704
{"error": {"class": "GenericError", "desc": "must provide a valid bitmap name for 'bitmap' sync mode"}}
1705
1706
-{"execute": "blockdev-backup", "arguments": {"device": "drive0", "job-id": "api_job", "sync": "bitmap", "target": "backup_target"}}
1707
+{"execute": "blockdev-backup", "arguments": {"device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "bitmap", "target": "backup_target"}}
1708
{"error": {"class": "GenericError", "desc": "must provide a valid bitmap name for 'bitmap' sync mode"}}
1709
1710
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "on-success", "device": "drive0", "job-id": "api_job", "sync": "bitmap", "target": "backup_target"}}
1711
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "bitmap", "target": "backup_target"}}
1712
{"error": {"class": "GenericError", "desc": "Bitmap 'bitmap404' could not be found"}}
1713
1714
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "always", "device": "drive0", "job-id": "api_job", "sync": "bitmap", "target": "backup_target"}}
1715
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "bitmap", "target": "backup_target"}}
1716
{"error": {"class": "GenericError", "desc": "Bitmap 'bitmap404' could not be found"}}
1717
1718
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "never", "device": "drive0", "job-id": "api_job", "sync": "bitmap", "target": "backup_target"}}
1719
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "bitmap", "target": "backup_target"}}
1720
{"error": {"class": "GenericError", "desc": "Bitmap 'bitmap404' could not be found"}}
1721
1722
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "device": "drive0", "job-id": "api_job", "sync": "bitmap", "target": "backup_target"}}
1723
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "bitmap", "target": "backup_target"}}
1724
{"error": {"class": "GenericError", "desc": "Bitmap 'bitmap404' could not be found"}}
1725
1726
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap0", "device": "drive0", "job-id": "api_job", "sync": "bitmap", "target": "backup_target"}}
1727
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap0", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "bitmap", "target": "backup_target"}}
1728
{"error": {"class": "GenericError", "desc": "Bitmap sync mode must be given when providing a bitmap"}}
1729
1730
-- Sync mode full tests --
1731
1732
-{"execute": "blockdev-backup", "arguments": {"bitmap-mode": "on-success", "device": "drive0", "job-id": "api_job", "sync": "full", "target": "backup_target"}}
1733
+{"execute": "blockdev-backup", "arguments": {"bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "full", "target": "backup_target"}}
1734
{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
1735
1736
-{"execute": "blockdev-backup", "arguments": {"bitmap-mode": "always", "device": "drive0", "job-id": "api_job", "sync": "full", "target": "backup_target"}}
1737
+{"execute": "blockdev-backup", "arguments": {"bitmap-mode": "always", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "full", "target": "backup_target"}}
1738
{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
1739
1740
-{"execute": "blockdev-backup", "arguments": {"bitmap-mode": "never", "device": "drive0", "job-id": "api_job", "sync": "full", "target": "backup_target"}}
1741
+{"execute": "blockdev-backup", "arguments": {"bitmap-mode": "never", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "full", "target": "backup_target"}}
1742
{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
1743
1744
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "on-success", "device": "drive0", "job-id": "api_job", "sync": "full", "target": "backup_target"}}
1745
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "full", "target": "backup_target"}}
1746
{"error": {"class": "GenericError", "desc": "Bitmap 'bitmap404' could not be found"}}
1747
1748
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "always", "device": "drive0", "job-id": "api_job", "sync": "full", "target": "backup_target"}}
1749
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "full", "target": "backup_target"}}
1750
{"error": {"class": "GenericError", "desc": "Bitmap 'bitmap404' could not be found"}}
1751
1752
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "never", "device": "drive0", "job-id": "api_job", "sync": "full", "target": "backup_target"}}
1753
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "full", "target": "backup_target"}}
1754
{"error": {"class": "GenericError", "desc": "Bitmap 'bitmap404' could not be found"}}
1755
1756
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "device": "drive0", "job-id": "api_job", "sync": "full", "target": "backup_target"}}
1757
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "full", "target": "backup_target"}}
1758
{"error": {"class": "GenericError", "desc": "Bitmap 'bitmap404' could not be found"}}
1759
1760
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "job-id": "api_job", "sync": "full", "target": "backup_target"}}
1761
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "full", "target": "backup_target"}}
1762
{"error": {"class": "GenericError", "desc": "Bitmap sync mode 'never' has no meaningful effect when combined with sync mode 'full'"}}
1763
1764
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap0", "device": "drive0", "job-id": "api_job", "sync": "full", "target": "backup_target"}}
1765
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap0", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "full", "target": "backup_target"}}
1766
{"error": {"class": "GenericError", "desc": "Bitmap sync mode must be given when providing a bitmap"}}
1767
1768
-- Sync mode top tests --
1769
1770
-{"execute": "blockdev-backup", "arguments": {"bitmap-mode": "on-success", "device": "drive0", "job-id": "api_job", "sync": "top", "target": "backup_target"}}
1771
+{"execute": "blockdev-backup", "arguments": {"bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "top", "target": "backup_target"}}
1772
{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
1773
1774
-{"execute": "blockdev-backup", "arguments": {"bitmap-mode": "always", "device": "drive0", "job-id": "api_job", "sync": "top", "target": "backup_target"}}
1775
+{"execute": "blockdev-backup", "arguments": {"bitmap-mode": "always", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "top", "target": "backup_target"}}
1776
{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
1777
1778
-{"execute": "blockdev-backup", "arguments": {"bitmap-mode": "never", "device": "drive0", "job-id": "api_job", "sync": "top", "target": "backup_target"}}
1779
+{"execute": "blockdev-backup", "arguments": {"bitmap-mode": "never", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "top", "target": "backup_target"}}
1780
{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
1781
1782
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "on-success", "device": "drive0", "job-id": "api_job", "sync": "top", "target": "backup_target"}}
1783
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "top", "target": "backup_target"}}
1784
{"error": {"class": "GenericError", "desc": "Bitmap 'bitmap404' could not be found"}}
1785
1786
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "always", "device": "drive0", "job-id": "api_job", "sync": "top", "target": "backup_target"}}
1787
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "top", "target": "backup_target"}}
1788
{"error": {"class": "GenericError", "desc": "Bitmap 'bitmap404' could not be found"}}
1789
1790
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "never", "device": "drive0", "job-id": "api_job", "sync": "top", "target": "backup_target"}}
1791
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "top", "target": "backup_target"}}
1792
{"error": {"class": "GenericError", "desc": "Bitmap 'bitmap404' could not be found"}}
1793
1794
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "device": "drive0", "job-id": "api_job", "sync": "top", "target": "backup_target"}}
1795
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "top", "target": "backup_target"}}
1796
{"error": {"class": "GenericError", "desc": "Bitmap 'bitmap404' could not be found"}}
1797
1798
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "job-id": "api_job", "sync": "top", "target": "backup_target"}}
1799
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "top", "target": "backup_target"}}
1800
{"error": {"class": "GenericError", "desc": "Bitmap sync mode 'never' has no meaningful effect when combined with sync mode 'top'"}}
1801
1802
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap0", "device": "drive0", "job-id": "api_job", "sync": "top", "target": "backup_target"}}
1803
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap0", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "top", "target": "backup_target"}}
1804
{"error": {"class": "GenericError", "desc": "Bitmap sync mode must be given when providing a bitmap"}}
1805
1806
-- Sync mode none tests --
1807
1808
-{"execute": "blockdev-backup", "arguments": {"bitmap-mode": "on-success", "device": "drive0", "job-id": "api_job", "sync": "none", "target": "backup_target"}}
1809
+{"execute": "blockdev-backup", "arguments": {"bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "none", "target": "backup_target"}}
1810
{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
1811
1812
-{"execute": "blockdev-backup", "arguments": {"bitmap-mode": "always", "device": "drive0", "job-id": "api_job", "sync": "none", "target": "backup_target"}}
1813
+{"execute": "blockdev-backup", "arguments": {"bitmap-mode": "always", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "none", "target": "backup_target"}}
1814
{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
1815
1816
-{"execute": "blockdev-backup", "arguments": {"bitmap-mode": "never", "device": "drive0", "job-id": "api_job", "sync": "none", "target": "backup_target"}}
1817
+{"execute": "blockdev-backup", "arguments": {"bitmap-mode": "never", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "none", "target": "backup_target"}}
1818
{"error": {"class": "GenericError", "desc": "Cannot specify bitmap sync mode without a bitmap"}}
1819
1820
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "on-success", "device": "drive0", "job-id": "api_job", "sync": "none", "target": "backup_target"}}
1821
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "none", "target": "backup_target"}}
1822
{"error": {"class": "GenericError", "desc": "Bitmap 'bitmap404' could not be found"}}
1823
1824
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "always", "device": "drive0", "job-id": "api_job", "sync": "none", "target": "backup_target"}}
1825
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "none", "target": "backup_target"}}
1826
{"error": {"class": "GenericError", "desc": "Bitmap 'bitmap404' could not be found"}}
1827
1828
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "never", "device": "drive0", "job-id": "api_job", "sync": "none", "target": "backup_target"}}
1829
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "none", "target": "backup_target"}}
1830
{"error": {"class": "GenericError", "desc": "Bitmap 'bitmap404' could not be found"}}
1831
1832
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "device": "drive0", "job-id": "api_job", "sync": "none", "target": "backup_target"}}
1833
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap404", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "none", "target": "backup_target"}}
1834
{"error": {"class": "GenericError", "desc": "Bitmap 'bitmap404' could not be found"}}
1835
1836
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "job-id": "api_job", "sync": "none", "target": "backup_target"}}
1837
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "on-success", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "none", "target": "backup_target"}}
1838
{"error": {"class": "GenericError", "desc": "sync mode 'none' does not produce meaningful bitmap outputs"}}
1839
1840
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "job-id": "api_job", "sync": "none", "target": "backup_target"}}
1841
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "always", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "none", "target": "backup_target"}}
1842
{"error": {"class": "GenericError", "desc": "sync mode 'none' does not produce meaningful bitmap outputs"}}
1843
1844
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "job-id": "api_job", "sync": "none", "target": "backup_target"}}
1845
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap0", "bitmap-mode": "never", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "none", "target": "backup_target"}}
1846
{"error": {"class": "GenericError", "desc": "sync mode 'none' does not produce meaningful bitmap outputs"}}
1847
1848
-{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap0", "device": "drive0", "job-id": "api_job", "sync": "none", "target": "backup_target"}}
1849
+{"execute": "blockdev-backup", "arguments": {"bitmap": "bitmap0", "device": "drive0", "filter-node-name": "backup-top", "job-id": "api_job", "sync": "none", "target": "backup_target"}}
1850
{"error": {"class": "GenericError", "desc": "Bitmap sync mode must be given when providing a bitmap"}}
1851
1852
--
97
--
1853
2.21.0
98
2.24.1
1854
99
1855
100
diff view generated by jsdifflib
Deleted patch
1
From: Maxim Levitsky <mlevitsk@redhat.com>
2
1
3
Fixes commit job / qemu-img commit, when
4
commiting qcow2 file which is based on nbd export.
5
6
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1718727
7
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
8
Message-id: 20190930213820.29777-2-mlevitsk@redhat.com
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
---
11
block/nbd.c | 15 +++++++++++++++
12
1 file changed, 15 insertions(+)
13
14
diff --git a/block/nbd.c b/block/nbd.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/block/nbd.c
17
+++ b/block/nbd.c
18
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn nbd_client_co_block_status(
19
BDRV_BLOCK_OFFSET_VALID;
20
}
21
22
+static int nbd_client_reopen_prepare(BDRVReopenState *state,
23
+ BlockReopenQueue *queue, Error **errp)
24
+{
25
+ BDRVNBDState *s = (BDRVNBDState *)state->bs->opaque;
26
+
27
+ if ((state->flags & BDRV_O_RDWR) && (s->info.flags & NBD_FLAG_READ_ONLY)) {
28
+ error_setg(errp, "Can't reopen read-only NBD mount as read/write");
29
+ return -EACCES;
30
+ }
31
+ return 0;
32
+}
33
+
34
static void nbd_client_close(BlockDriverState *bs)
35
{
36
BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
37
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_nbd = {
38
.instance_size = sizeof(BDRVNBDState),
39
.bdrv_parse_filename = nbd_parse_filename,
40
.bdrv_file_open = nbd_open,
41
+ .bdrv_reopen_prepare = nbd_client_reopen_prepare,
42
.bdrv_co_preadv = nbd_client_co_preadv,
43
.bdrv_co_pwritev = nbd_client_co_pwritev,
44
.bdrv_co_pwrite_zeroes = nbd_client_co_pwrite_zeroes,
45
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_nbd_tcp = {
46
.instance_size = sizeof(BDRVNBDState),
47
.bdrv_parse_filename = nbd_parse_filename,
48
.bdrv_file_open = nbd_open,
49
+ .bdrv_reopen_prepare = nbd_client_reopen_prepare,
50
.bdrv_co_preadv = nbd_client_co_preadv,
51
.bdrv_co_pwritev = nbd_client_co_pwritev,
52
.bdrv_co_pwrite_zeroes = nbd_client_co_pwrite_zeroes,
53
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_nbd_unix = {
54
.instance_size = sizeof(BDRVNBDState),
55
.bdrv_parse_filename = nbd_parse_filename,
56
.bdrv_file_open = nbd_open,
57
+ .bdrv_reopen_prepare = nbd_client_reopen_prepare,
58
.bdrv_co_preadv = nbd_client_co_preadv,
59
.bdrv_co_pwritev = nbd_client_co_pwritev,
60
.bdrv_co_pwrite_zeroes = nbd_client_co_pwrite_zeroes,
61
--
62
2.21.0
63
64
diff view generated by jsdifflib
Deleted patch
1
From: Daniel P. Berrangé <berrange@redhat.com>
2
1
3
Some distros are now defaulting to LUKS version 2 which QEMU cannot
4
process. For our I/O test that validates interoperability between the
5
kernel/cryptsetup and QEMU, we need to explicitly ask for version 1
6
of the LUKS format.
7
8
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
9
Message-id: 20190927101155.25896-1-berrange@redhat.com
10
Tested-by: Maxim Levitsky <mlevitsk@redhat.com>
11
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
13
---
14
tests/qemu-iotests/149 | 2 +-
15
tests/qemu-iotests/149.out | 44 +++++++++++++++++++-------------------
16
2 files changed, 23 insertions(+), 23 deletions(-)
17
18
diff --git a/tests/qemu-iotests/149 b/tests/qemu-iotests/149
19
index XXXXXXX..XXXXXXX 100755
20
--- a/tests/qemu-iotests/149
21
+++ b/tests/qemu-iotests/149
22
@@ -XXX,XX +XXX,XX @@ def cryptsetup_format(config):
23
24
(password, slot) = config.first_password()
25
26
- args = ["luksFormat"]
27
+ args = ["luksFormat", "--type", "luks1"]
28
cipher = config.cipher + "-" + config.mode + "-" + config.ivgen
29
if config.ivgen_hash is not None:
30
cipher = cipher + ":" + config.ivgen_hash
31
diff --git a/tests/qemu-iotests/149.out b/tests/qemu-iotests/149.out
32
index XXXXXXX..XXXXXXX 100644
33
--- a/tests/qemu-iotests/149.out
34
+++ b/tests/qemu-iotests/149.out
35
@@ -XXX,XX +XXX,XX @@
36
# Create image
37
truncate TEST_DIR/luks-aes-256-xts-plain64-sha1.img --size 4194304MB
38
# Format image
39
-sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain64 --key-size 512 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain64-sha1.img
40
+sudo cryptsetup -q -v luksFormat --type luks1 --cipher aes-xts-plain64 --key-size 512 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain64-sha1.img
41
# Open dev
42
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha1.img qiotest-145-aes-256-xts-plain64-sha1
43
# Write test pattern 0xa7
44
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-xts-plain64-sha1.img
45
# Create image
46
truncate TEST_DIR/luks-twofish-256-xts-plain64-sha1.img --size 4194304MB
47
# Format image
48
-sudo cryptsetup -q -v luksFormat --cipher twofish-xts-plain64 --key-size 512 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-twofish-256-xts-plain64-sha1.img
49
+sudo cryptsetup -q -v luksFormat --type luks1 --cipher twofish-xts-plain64 --key-size 512 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-twofish-256-xts-plain64-sha1.img
50
# Open dev
51
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-twofish-256-xts-plain64-sha1.img qiotest-145-twofish-256-xts-plain64-sha1
52
# Write test pattern 0xa7
53
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-twofish-256-xts-plain64-sha1.img
54
# Create image
55
truncate TEST_DIR/luks-serpent-256-xts-plain64-sha1.img --size 4194304MB
56
# Format image
57
-sudo cryptsetup -q -v luksFormat --cipher serpent-xts-plain64 --key-size 512 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-serpent-256-xts-plain64-sha1.img
58
+sudo cryptsetup -q -v luksFormat --type luks1 --cipher serpent-xts-plain64 --key-size 512 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-serpent-256-xts-plain64-sha1.img
59
# Open dev
60
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-serpent-256-xts-plain64-sha1.img qiotest-145-serpent-256-xts-plain64-sha1
61
# Write test pattern 0xa7
62
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-serpent-256-xts-plain64-sha1.img
63
# Create image
64
truncate TEST_DIR/luks-cast5-128-cbc-plain64-sha1.img --size 4194304MB
65
# Format image
66
-sudo cryptsetup -q -v luksFormat --cipher cast5-cbc-plain64 --key-size 128 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-cast5-128-cbc-plain64-sha1.img
67
+sudo cryptsetup -q -v luksFormat --type luks1 --cipher cast5-cbc-plain64 --key-size 128 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-cast5-128-cbc-plain64-sha1.img
68
# Open dev
69
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-cast5-128-cbc-plain64-sha1.img qiotest-145-cast5-128-cbc-plain64-sha1
70
# Write test pattern 0xa7
71
@@ -XXX,XX +XXX,XX @@ Skipping cast6-256-xts-plain64-sha1 in blacklist
72
# Create image
73
truncate TEST_DIR/luks-aes-256-cbc-plain-sha1.img --size 4194304MB
74
# Format image
75
-sudo cryptsetup -q -v luksFormat --cipher aes-cbc-plain --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-cbc-plain-sha1.img
76
+sudo cryptsetup -q -v luksFormat --type luks1 --cipher aes-cbc-plain --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-cbc-plain-sha1.img
77
# Open dev
78
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-plain-sha1.img qiotest-145-aes-256-cbc-plain-sha1
79
# Write test pattern 0xa7
80
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-cbc-plain-sha1.img
81
# Create image
82
truncate TEST_DIR/luks-aes-256-cbc-plain64-sha1.img --size 4194304MB
83
# Format image
84
-sudo cryptsetup -q -v luksFormat --cipher aes-cbc-plain64 --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-cbc-plain64-sha1.img
85
+sudo cryptsetup -q -v luksFormat --type luks1 --cipher aes-cbc-plain64 --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-cbc-plain64-sha1.img
86
# Open dev
87
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-plain64-sha1.img qiotest-145-aes-256-cbc-plain64-sha1
88
# Write test pattern 0xa7
89
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-cbc-plain64-sha1.img
90
# Create image
91
truncate TEST_DIR/luks-aes-256-cbc-essiv-sha256-sha1.img --size 4194304MB
92
# Format image
93
-sudo cryptsetup -q -v luksFormat --cipher aes-cbc-essiv:sha256 --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-cbc-essiv-sha256-sha1.img
94
+sudo cryptsetup -q -v luksFormat --type luks1 --cipher aes-cbc-essiv:sha256 --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-cbc-essiv-sha256-sha1.img
95
# Open dev
96
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-essiv-sha256-sha1.img qiotest-145-aes-256-cbc-essiv-sha256-sha1
97
# Write test pattern 0xa7
98
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-cbc-essiv-sha256-sha1.img
99
# Create image
100
truncate TEST_DIR/luks-aes-256-xts-essiv-sha256-sha1.img --size 4194304MB
101
# Format image
102
-sudo cryptsetup -q -v luksFormat --cipher aes-xts-essiv:sha256 --key-size 512 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-essiv-sha256-sha1.img
103
+sudo cryptsetup -q -v luksFormat --type luks1 --cipher aes-xts-essiv:sha256 --key-size 512 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-essiv-sha256-sha1.img
104
# Open dev
105
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-essiv-sha256-sha1.img qiotest-145-aes-256-xts-essiv-sha256-sha1
106
# Write test pattern 0xa7
107
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-xts-essiv-sha256-sha1.img
108
# Create image
109
truncate TEST_DIR/luks-aes-128-xts-plain64-sha256-sha1.img --size 4194304MB
110
# Format image
111
-sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain64 --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-128-xts-plain64-sha256-sha1.img
112
+sudo cryptsetup -q -v luksFormat --type luks1 --cipher aes-xts-plain64 --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-128-xts-plain64-sha256-sha1.img
113
# Open dev
114
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-128-xts-plain64-sha256-sha1.img qiotest-145-aes-128-xts-plain64-sha256-sha1
115
# Write test pattern 0xa7
116
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-128-xts-plain64-sha256-sha1.img
117
# Create image
118
truncate TEST_DIR/luks-aes-192-xts-plain64-sha256-sha1.img --size 4194304MB
119
# Format image
120
-sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain64 --key-size 384 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-192-xts-plain64-sha256-sha1.img
121
+sudo cryptsetup -q -v luksFormat --type luks1 --cipher aes-xts-plain64 --key-size 384 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-192-xts-plain64-sha256-sha1.img
122
# Open dev
123
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-192-xts-plain64-sha256-sha1.img qiotest-145-aes-192-xts-plain64-sha256-sha1
124
# Write test pattern 0xa7
125
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-192-xts-plain64-sha256-sha1.img
126
# Create image
127
truncate TEST_DIR/luks-twofish-128-xts-plain64-sha1.img --size 4194304MB
128
# Format image
129
-sudo cryptsetup -q -v luksFormat --cipher twofish-xts-plain64 --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-twofish-128-xts-plain64-sha1.img
130
+sudo cryptsetup -q -v luksFormat --type luks1 --cipher twofish-xts-plain64 --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-twofish-128-xts-plain64-sha1.img
131
# Open dev
132
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-twofish-128-xts-plain64-sha1.img qiotest-145-twofish-128-xts-plain64-sha1
133
# Write test pattern 0xa7
134
@@ -XXX,XX +XXX,XX @@ Skipping twofish-192-xts-plain64-sha1 in blacklist
135
# Create image
136
truncate TEST_DIR/luks-serpent-128-xts-plain64-sha1.img --size 4194304MB
137
# Format image
138
-sudo cryptsetup -q -v luksFormat --cipher serpent-xts-plain64 --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-serpent-128-xts-plain64-sha1.img
139
+sudo cryptsetup -q -v luksFormat --type luks1 --cipher serpent-xts-plain64 --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-serpent-128-xts-plain64-sha1.img
140
# Open dev
141
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-serpent-128-xts-plain64-sha1.img qiotest-145-serpent-128-xts-plain64-sha1
142
# Write test pattern 0xa7
143
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-serpent-128-xts-plain64-sha1.img
144
# Create image
145
truncate TEST_DIR/luks-serpent-192-xts-plain64-sha1.img --size 4194304MB
146
# Format image
147
-sudo cryptsetup -q -v luksFormat --cipher serpent-xts-plain64 --key-size 384 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-serpent-192-xts-plain64-sha1.img
148
+sudo cryptsetup -q -v luksFormat --type luks1 --cipher serpent-xts-plain64 --key-size 384 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-serpent-192-xts-plain64-sha1.img
149
# Open dev
150
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-serpent-192-xts-plain64-sha1.img qiotest-145-serpent-192-xts-plain64-sha1
151
# Write test pattern 0xa7
152
@@ -XXX,XX +XXX,XX @@ Skipping cast6-192-xts-plain64-sha1 in blacklist
153
# Create image
154
truncate TEST_DIR/luks-aes-256-xts-plain64-sha224.img --size 4194304MB
155
# Format image
156
-sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain64 --key-size 512 --hash sha224 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain64-sha224.img
157
+sudo cryptsetup -q -v luksFormat --type luks1 --cipher aes-xts-plain64 --key-size 512 --hash sha224 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain64-sha224.img
158
# Open dev
159
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha224.img qiotest-145-aes-256-xts-plain64-sha224
160
# Write test pattern 0xa7
161
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-xts-plain64-sha224.img
162
# Create image
163
truncate TEST_DIR/luks-aes-256-xts-plain64-sha256.img --size 4194304MB
164
# Format image
165
-sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain64 --key-size 512 --hash sha256 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain64-sha256.img
166
+sudo cryptsetup -q -v luksFormat --type luks1 --cipher aes-xts-plain64 --key-size 512 --hash sha256 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain64-sha256.img
167
# Open dev
168
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha256.img qiotest-145-aes-256-xts-plain64-sha256
169
# Write test pattern 0xa7
170
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-xts-plain64-sha256.img
171
# Create image
172
truncate TEST_DIR/luks-aes-256-xts-plain64-sha384.img --size 4194304MB
173
# Format image
174
-sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain64 --key-size 512 --hash sha384 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain64-sha384.img
175
+sudo cryptsetup -q -v luksFormat --type luks1 --cipher aes-xts-plain64 --key-size 512 --hash sha384 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain64-sha384.img
176
# Open dev
177
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha384.img qiotest-145-aes-256-xts-plain64-sha384
178
# Write test pattern 0xa7
179
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-xts-plain64-sha384.img
180
# Create image
181
truncate TEST_DIR/luks-aes-256-xts-plain64-sha512.img --size 4194304MB
182
# Format image
183
-sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain64 --key-size 512 --hash sha512 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain64-sha512.img
184
+sudo cryptsetup -q -v luksFormat --type luks1 --cipher aes-xts-plain64 --key-size 512 --hash sha512 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain64-sha512.img
185
# Open dev
186
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha512.img qiotest-145-aes-256-xts-plain64-sha512
187
# Write test pattern 0xa7
188
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-xts-plain64-sha512.img
189
# Create image
190
truncate TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img --size 4194304MB
191
# Format image
192
-sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain64 --key-size 512 --hash ripemd160 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img
193
+sudo cryptsetup -q -v luksFormat --type luks1 --cipher aes-xts-plain64 --key-size 512 --hash ripemd160 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img
194
# Open dev
195
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img qiotest-145-aes-256-xts-plain64-ripemd160
196
# Write test pattern 0xa7
197
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img
198
# Create image
199
truncate TEST_DIR/luks-aes-256-xts-plain-sha1-pwslot3.img --size 4194304MB
200
# Format image
201
-sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain --key-size 512 --hash sha1 --key-slot 3 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain-sha1-pwslot3.img
202
+sudo cryptsetup -q -v luksFormat --type luks1 --cipher aes-xts-plain --key-size 512 --hash sha1 --key-slot 3 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain-sha1-pwslot3.img
203
# Open dev
204
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain-sha1-pwslot3.img qiotest-145-aes-256-xts-plain-sha1-pwslot3
205
# Write test pattern 0xa7
206
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-xts-plain-sha1-pwslot3.img
207
# Create image
208
truncate TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img --size 4194304MB
209
# Format image
210
-sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain --key-size 512 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img
211
+sudo cryptsetup -q -v luksFormat --type luks1 --cipher aes-xts-plain --key-size 512 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img
212
# Add password slot 1
213
sudo cryptsetup -q -v luksAddKey TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img --key-slot 1 --key-file - --iter-time 10 TEST_DIR/passwd.txt
214
# Add password slot 2
215
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img
216
# Create image
217
truncate TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img --size 4194304MB
218
# Format image
219
-sudo cryptsetup -q -v luksFormat --cipher aes-cbc-essiv:sha256 --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img
220
+sudo cryptsetup -q -v luksFormat --type luks1 --cipher aes-cbc-essiv:sha256 --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img
221
# Open dev
222
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img qiotest-145-aes-256-cbc-essiv-auto-sha1
223
# Write test pattern 0xa7
224
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img
225
# Create image
226
truncate TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img --size 4194304MB
227
# Format image
228
-sudo cryptsetup -q -v luksFormat --cipher aes-cbc-plain64:sha256 --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img
229
+sudo cryptsetup -q -v luksFormat --type luks1 --cipher aes-cbc-plain64:sha256 --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img
230
# Open dev
231
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img qiotest-145-aes-256-cbc-plain64-sha256-sha1
232
# Write test pattern 0xa7
233
--
234
2.21.0
235
236
diff view generated by jsdifflib
1
Linux 5.3 has made 0.0.0.0/8 a working IPv4 subnet. As such, "42" is
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
now a valid host, and the connection to it will (hopefully) time out
3
over a long period rather than quickly return with EINVAL.
4
2
5
So let us use a negative integer for testing that NBD will not crash
3
Commit ed65fd1a2750 ("virtio-blk: switch off scsi-passthrough by
6
when it receives integer hosts. This way, the connection will again
4
default") changed the default value of the 'scsi' property of
7
fail quickly and reliably.
5
virtio-blk, which is only available on Linux hosts. It also added
6
an unconditional compat entry for 2.4 or earlier machines.
8
7
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
Trying to set this property on a pre-2.5 machine on OSX, we get:
10
Message-id: 20191002174052.5773-1-mreitz@redhat.com
9
11
Reviewed-by: Eric Blake <eblake@redhat.com>
10
Unexpected error in object_property_find() at qom/object.c:1201:
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
qemu-system-x86_64: -device virtio-blk-pci,id=scsi0,drive=drive0: can't apply global virtio-blk-device.scsi=true: Property '.scsi' not found
12
13
Fix this error by marking the property optional.
14
15
Fixes: ed65fd1a27 ("virtio-blk: switch off scsi-passthrough by default")
16
Suggested-by: Cornelia Huck <cohuck@redhat.com>
17
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
18
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
19
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
20
Message-id: 20200207001404.1739-1-philmd@redhat.com
21
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
---
22
---
14
tests/qemu-iotests/162 | 2 +-
23
hw/core/machine.c | 3 ++-
15
tests/qemu-iotests/162.out | 2 +-
24
1 file changed, 2 insertions(+), 1 deletion(-)
16
2 files changed, 2 insertions(+), 2 deletions(-)
17
25
18
diff --git a/tests/qemu-iotests/162 b/tests/qemu-iotests/162
26
diff --git a/hw/core/machine.c b/hw/core/machine.c
19
index XXXXXXX..XXXXXXX 100755
20
--- a/tests/qemu-iotests/162
21
+++ b/tests/qemu-iotests/162
22
@@ -XXX,XX +XXX,XX @@ echo '=== NBD ==='
23
# NBD expects all of its arguments to be strings
24
25
# So this should not crash
26
-$QEMU_IMG info 'json:{"driver": "nbd", "host": 42}'
27
+$QEMU_IMG info 'json:{"driver": "nbd", "host": -1}'
28
29
# And this should not treat @port as if it had not been specified
30
# (We need to set up a server here, because the error message for "Connection
31
diff --git a/tests/qemu-iotests/162.out b/tests/qemu-iotests/162.out
32
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
33
--- a/tests/qemu-iotests/162.out
28
--- a/hw/core/machine.c
34
+++ b/tests/qemu-iotests/162.out
29
+++ b/hw/core/machine.c
35
@@ -XXX,XX +XXX,XX @@
30
@@ -XXX,XX +XXX,XX @@ GlobalProperty hw_compat_2_5[] = {
36
QA output created by 162
31
const size_t hw_compat_2_5_len = G_N_ELEMENTS(hw_compat_2_5);
37
32
38
=== NBD ===
33
GlobalProperty hw_compat_2_4[] = {
39
-qemu-img: Could not open 'json:{"driver": "nbd", "host": 42}': Failed to connect socket: Invalid argument
34
- { "virtio-blk-device", "scsi", "true" },
40
+qemu-img: Could not open 'json:{"driver": "nbd", "host": -1}': address resolution failed for -1:10809: Name or service not known
35
+ /* Optional because the 'scsi' property is Linux-only */
41
image: nbd://localhost:PORT
36
+ { "virtio-blk-device", "scsi", "true", .optional = true },
42
image: nbd+unix://?socket=42
37
{ "e1000", "extra_mac_registers", "off" },
43
38
{ "virtio-pci", "x-disable-pcie", "on" },
39
{ "virtio-pci", "migrate-extra", "off" },
44
--
40
--
45
2.21.0
41
2.24.1
46
42
47
43
diff view generated by jsdifflib