1
The following changes since commit 16aaacb307ed607b9780c12702c44f0fe52edc7e:
1
The following changes since commit bf159f0bdc7b8e7aa8342dedb3829ca744c1b612:
2
2
3
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20200430' into staging (2020-04-30 14:00:36 +0100)
3
Merge remote-tracking branch 'remotes/edgar/tags/edgar/xilinx-next-2021-01-27.for-upstream' into staging (2021-01-27 17:40:25 +0000)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
git://repo.or.cz/qemu/kevin.git tags/for-upstream
7
git://repo.or.cz/qemu/kevin.git tags/for-upstream
8
8
9
for you to fetch changes up to eaae29ef89d498d0eac553c77b554f310a47f809:
9
for you to fetch changes up to a44be0334beae3a9affb4a3a92cc6852993d7a84:
10
10
11
qemu-storage-daemon: Fix non-string --object properties (2020-04-30 17:51:07 +0200)
11
iotests: rename and move 169 and 199 tests (2021-01-27 20:53:14 +0100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block layer patches:
14
Block layer patches:
15
15
16
- Fix resize (extending) of short overlays
16
- Fix crash on write to read-only devices
17
- nvme: introduce PMR support from NVMe 1.4 spec
17
- iotests: Rewrite 'check' in Python, get rid of 'groups' and allow
18
- qemu-storage-daemon: Fix non-string --object properties
18
non-numeric test case names
19
19
20
----------------------------------------------------------------
20
----------------------------------------------------------------
21
Alberto Garcia (1):
21
Kevin Wolf (2):
22
qcow2: Add incompatibility note between backing files and raw external data files
22
block: Separate blk_is_writable() and blk_supports_write_perm()
23
virtio-scsi-test: Test writing to scsi-cd device
23
24
24
Andrzej Jakowski (1):
25
Vladimir Sementsov-Ogievskiy (6):
25
nvme: introduce PMR support from NVMe 1.4 spec
26
iotests: 146: drop extra whitespaces from .out file
27
iotests: add findtests.py
28
iotests: add testenv.py
29
iotests: add testrunner.py
30
iotests: rewrite check into python
31
iotests: rename and move 169 and 199 tests
26
32
27
Kevin Wolf (12):
33
docs/devel/testing.rst | 50 +-
28
block: Add flags to BlockDriver.bdrv_co_truncate()
34
include/sysemu/block-backend.h | 3 +-
29
block: Add flags to bdrv(_co)_truncate()
35
block/block-backend.c | 19 +-
30
block-backend: Add flags to blk_truncate()
36
hw/block/dataplane/xen-block.c | 2 +-
31
qcow2: Support BDRV_REQ_ZERO_WRITE for truncate
37
hw/block/fdc.c | 9 +-
32
raw-format: Support BDRV_REQ_ZERO_WRITE for truncate
38
hw/block/m25p80.c | 6 +-
33
file-posix: Support BDRV_REQ_ZERO_WRITE for truncate
39
hw/block/nand.c | 2 +-
34
block: truncate: Don't make backing file data visible
40
hw/block/nvme-ns.c | 7 +-
35
iotests: Filter testfiles out in filter_img_info()
41
hw/block/onenand.c | 2 +-
36
iotests: Test committing to short backing file
42
hw/block/pflash_cfi01.c | 2 +-
37
qcow2: Forward ZERO_WRITE flag for full preallocation
43
hw/block/pflash_cfi02.c | 2 +-
38
qom: Factor out user_creatable_add_dict()
44
hw/block/swim.c | 6 +-
39
qemu-storage-daemon: Fix non-string --object properties
45
hw/block/virtio-blk.c | 6 +-
40
46
hw/block/xen-block.c | 2 +-
41
Paolo Bonzini (1):
47
hw/ide/core.c | 2 +-
42
qemu-iotests: allow qcow2 external discarded clusters to contain stale data
48
hw/misc/sifive_u_otp.c | 2 +-
43
49
hw/ppc/pnv_pnor.c | 2 +-
44
docs/interop/qcow2.txt | 3 +
50
hw/scsi/scsi-disk.c | 10 +-
45
hw/block/nvme.h | 2 +
51
hw/scsi/scsi-generic.c | 4 +-
46
include/block/block.h | 5 +-
52
hw/sd/sd.c | 6 +-
47
include/block/block_int.h | 10 +-
53
hw/usb/dev-storage.c | 4 +-
48
include/block/nvme.h | 172 ++++++++++++++++++++++++++
54
tests/qtest/virtio-scsi-test.c | 39 +
49
include/qom/object_interfaces.h | 16 +++
55
tests/qemu-iotests/findtests.py | 159 +++
50
include/sysemu/block-backend.h | 2 +-
56
tests/qemu-iotests/iotests.py | 8 +
51
block.c | 3 +-
57
tests/qemu-iotests/testenv.py | 281 +++++
52
block/block-backend.c | 4 +-
58
tests/qemu-iotests/testrunner.py | 367 +++++++
53
block/commit.c | 4 +-
59
Makefile | 1 -
54
block/crypto.c | 7 +-
60
tests/check-block.sh | 3 +-
55
block/file-posix.c | 6 +-
61
tests/qemu-iotests/146.out | 780 +++++++-------
56
block/file-win32.c | 2 +-
62
tests/qemu-iotests/check | 1095 +++-----------------
57
block/gluster.c | 1 +
63
tests/qemu-iotests/common.env.in | 3 -
58
block/io.c | 43 ++++++-
64
tests/qemu-iotests/group | 323 ------
59
block/iscsi.c | 2 +-
65
tests/qemu-iotests/meson.build | 3 -
60
block/mirror.c | 2 +-
66
.../{199 => tests/migrate-bitmaps-postcopy-test} | 0
61
block/nfs.c | 3 +-
67
.../migrate-bitmaps-postcopy-test.out} | 0
62
block/parallels.c | 6 +-
68
.../{169 => tests/migrate-bitmaps-test} | 0
63
block/qcow.c | 4 +-
69
.../{169.out => tests/migrate-bitmaps-test.out} | 0
64
block/qcow2-cluster.c | 2 +-
70
37 files changed, 1481 insertions(+), 1729 deletions(-)
65
block/qcow2-refcount.c | 2 +-
71
create mode 100644 tests/qemu-iotests/findtests.py
66
block/qcow2.c | 73 +++++++++--
72
create mode 100644 tests/qemu-iotests/testenv.py
67
block/qed.c | 3 +-
73
create mode 100644 tests/qemu-iotests/testrunner.py
68
block/raw-format.c | 6 +-
74
delete mode 100644 tests/qemu-iotests/common.env.in
69
block/rbd.c | 1 +
75
delete mode 100644 tests/qemu-iotests/group
70
block/sheepdog.c | 4 +-
76
rename tests/qemu-iotests/{199 => tests/migrate-bitmaps-postcopy-test} (100%)
71
block/ssh.c | 2 +-
77
rename tests/qemu-iotests/{199.out => tests/migrate-bitmaps-postcopy-test.out} (100%)
72
block/vdi.c | 2 +-
78
rename tests/qemu-iotests/{169 => tests/migrate-bitmaps-test} (100%)
73
block/vhdx-log.c | 2 +-
79
rename tests/qemu-iotests/{169.out => tests/migrate-bitmaps-test.out} (100%)
74
block/vhdx.c | 6 +-
75
block/vmdk.c | 8 +-
76
block/vpc.c | 2 +-
77
blockdev.c | 2 +-
78
hw/block/nvme.c | 109 ++++++++++++++++
79
qemu-img.c | 2 +-
80
qemu-io-cmds.c | 2 +-
81
qemu-storage-daemon.c | 4 +-
82
qom/object_interfaces.c | 31 +++++
83
qom/qom-qmp-cmds.c | 24 +---
84
tests/test-block-iothread.c | 9 +-
85
tests/qemu-iotests/iotests.py | 5 +-
86
hw/block/Makefile.objs | 2 +-
87
hw/block/trace-events | 4 +
88
tests/qemu-iotests/244 | 10 +-
89
tests/qemu-iotests/244.out | 9 +-
90
tests/qemu-iotests/274 | 155 +++++++++++++++++++++++
91
tests/qemu-iotests/274.out | 268 ++++++++++++++++++++++++++++++++++++++++
92
tests/qemu-iotests/group | 1 +
93
49 files changed, 951 insertions(+), 96 deletions(-)
94
create mode 100755 tests/qemu-iotests/274
95
create mode 100644 tests/qemu-iotests/274.out
96
80
97
81
diff view generated by jsdifflib
1
Now that node level interface bdrv_truncate() supports passing request
1
Currently, blk_is_read_only() tells whether a given BlockBackend can
2
flags to the block driver, expose this on the BlockBackend level, too.
2
only be used in read-only mode because its root node is read-only. Some
3
3
callers actually try to answer a slightly different question: Is the
4
BlockBackend configured to be writable, by taking write permissions on
5
the root node?
6
7
This can differ, for example, for CD-ROM devices which don't take write
8
permissions, but may be backed by a writable image file. scsi-cd allows
9
write requests to the drive if blk_is_read_only() returns false.
10
However, the write request will immediately run into an assertion
11
failure because the write permission is missing.
12
13
This patch introduces separate functions for both questions.
14
blk_supports_write_perm() answers the question whether the block
15
node/image file can support writable devices, whereas blk_is_writable()
16
tells whether the BlockBackend is currently configured to be writable.
17
18
All calls of blk_is_read_only() are converted to one of the two new
19
functions.
20
21
Fixes: https://bugs.launchpad.net/bugs/1906693
22
Cc: qemu-stable@nongnu.org
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
23
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
24
Message-Id: <20210118123448.307825-2-kwolf@redhat.com>
6
Reviewed-by: Alberto Garcia <berto@igalia.com>
25
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Max Reitz <mreitz@redhat.com>
26
Reviewed-by: Max Reitz <mreitz@redhat.com>
8
Message-Id: <20200424125448.63318-4-kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
27
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
28
---
11
include/sysemu/block-backend.h | 2 +-
29
include/sysemu/block-backend.h | 3 ++-
12
block.c | 3 ++-
30
block/block-backend.c | 19 ++++++++++++++++---
13
block/block-backend.c | 4 ++--
31
hw/block/dataplane/xen-block.c | 2 +-
14
block/commit.c | 4 ++--
32
hw/block/fdc.c | 9 +++++----
15
block/crypto.c | 2 +-
33
hw/block/m25p80.c | 6 +++---
16
block/mirror.c | 2 +-
34
hw/block/nand.c | 2 +-
17
block/qcow2.c | 4 ++--
35
hw/block/nvme-ns.c | 7 ++++---
18
block/qed.c | 2 +-
36
hw/block/onenand.c | 2 +-
19
block/vdi.c | 2 +-
37
hw/block/pflash_cfi01.c | 2 +-
20
block/vhdx.c | 4 ++--
38
hw/block/pflash_cfi02.c | 2 +-
21
block/vmdk.c | 6 +++---
39
hw/block/swim.c | 6 +++---
22
block/vpc.c | 2 +-
40
hw/block/virtio-blk.c | 6 +++---
23
blockdev.c | 2 +-
41
hw/block/xen-block.c | 2 +-
24
qemu-img.c | 2 +-
42
hw/ide/core.c | 2 +-
25
qemu-io-cmds.c | 2 +-
43
hw/misc/sifive_u_otp.c | 2 +-
26
15 files changed, 22 insertions(+), 21 deletions(-)
44
hw/ppc/pnv_pnor.c | 2 +-
45
hw/scsi/scsi-disk.c | 10 +++++-----
46
hw/scsi/scsi-generic.c | 4 ++--
47
hw/sd/sd.c | 6 +++---
48
hw/usb/dev-storage.c | 4 ++--
49
20 files changed, 57 insertions(+), 41 deletions(-)
27
50
28
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
51
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
29
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
30
--- a/include/sysemu/block-backend.h
53
--- a/include/sysemu/block-backend.h
31
+++ b/include/sysemu/block-backend.h
54
+++ b/include/sysemu/block-backend.h
32
@@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
55
@@ -XXX,XX +XXX,XX @@ BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
33
int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
56
int error);
34
int bytes);
57
void blk_error_action(BlockBackend *blk, BlockErrorAction action,
35
int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
58
bool is_read, int error);
36
- PreallocMode prealloc, Error **errp);
59
-bool blk_is_read_only(BlockBackend *blk);
37
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp);
60
+bool blk_supports_write_perm(BlockBackend *blk);
38
int blk_pdiscard(BlockBackend *blk, int64_t offset, int bytes);
61
+bool blk_is_writable(BlockBackend *blk);
39
int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
62
bool blk_is_sg(BlockBackend *blk);
40
int64_t pos, int size);
63
bool blk_enable_write_cache(BlockBackend *blk);
41
diff --git a/block.c b/block.c
64
void blk_set_enable_write_cache(BlockBackend *blk, bool wce);
42
index XXXXXXX..XXXXXXX 100644
43
--- a/block.c
44
+++ b/block.c
45
@@ -XXX,XX +XXX,XX @@ static int64_t create_file_fallback_truncate(BlockBackend *blk,
46
int64_t size;
47
int ret;
48
49
- ret = blk_truncate(blk, minimum_size, false, PREALLOC_MODE_OFF, &local_err);
50
+ ret = blk_truncate(blk, minimum_size, false, PREALLOC_MODE_OFF, 0,
51
+ &local_err);
52
if (ret < 0 && ret != -ENOTSUP) {
53
error_propagate(errp, local_err);
54
return ret;
55
diff --git a/block/block-backend.c b/block/block-backend.c
65
diff --git a/block/block-backend.c b/block/block-backend.c
56
index XXXXXXX..XXXXXXX 100644
66
index XXXXXXX..XXXXXXX 100644
57
--- a/block/block-backend.c
67
--- a/block/block-backend.c
58
+++ b/block/block-backend.c
68
+++ b/block/block-backend.c
59
@@ -XXX,XX +XXX,XX @@ int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
69
@@ -XXX,XX +XXX,XX @@ void blk_error_action(BlockBackend *blk, BlockErrorAction action,
70
}
60
}
71
}
61
72
62
int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
73
-bool blk_is_read_only(BlockBackend *blk)
63
- PreallocMode prealloc, Error **errp)
74
+/*
64
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp)
75
+ * Returns true if the BlockBackend can support taking write permissions
65
{
76
+ * (because its root node is not read-only).
66
if (!blk_is_available(blk)) {
77
+ */
67
error_setg(errp, "No medium inserted");
78
+bool blk_supports_write_perm(BlockBackend *blk)
68
return -ENOMEDIUM;
79
{
69
}
80
BlockDriverState *bs = blk_bs(blk);
70
81
71
- return bdrv_truncate(blk->root, offset, exact, prealloc, 0, errp);
82
if (bs) {
72
+ return bdrv_truncate(blk->root, offset, exact, prealloc, flags, errp);
83
- return bdrv_is_read_only(bs);
84
+ return !bdrv_is_read_only(bs);
85
} else {
86
- return blk->root_state.read_only;
87
+ return !blk->root_state.read_only;
88
}
73
}
89
}
74
90
75
int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
91
+/*
76
diff --git a/block/commit.c b/block/commit.c
92
+ * Returns true if the BlockBackend can be written to in its current
77
index XXXXXXX..XXXXXXX 100644
93
+ * configuration (i.e. if write permission have been requested)
78
--- a/block/commit.c
94
+ */
79
+++ b/block/commit.c
95
+bool blk_is_writable(BlockBackend *blk)
80
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn commit_run(Job *job, Error **errp)
96
+{
81
}
97
+ return blk->perm & BLK_PERM_WRITE;
82
98
+}
83
if (base_len < len) {
99
+
84
- ret = blk_truncate(s->base, len, false, PREALLOC_MODE_OFF, NULL);
100
bool blk_is_sg(BlockBackend *blk)
85
+ ret = blk_truncate(s->base, len, false, PREALLOC_MODE_OFF, 0, NULL);
101
{
86
if (ret) {
102
BlockDriverState *bs = blk_bs(blk);
87
goto out;
103
diff --git a/hw/block/dataplane/xen-block.c b/hw/block/dataplane/xen-block.c
88
}
104
index XXXXXXX..XXXXXXX 100644
89
@@ -XXX,XX +XXX,XX @@ int bdrv_commit(BlockDriverState *bs)
105
--- a/hw/block/dataplane/xen-block.c
90
* grow the backing file image if possible. If not possible,
106
+++ b/hw/block/dataplane/xen-block.c
91
* we must return an error */
107
@@ -XXX,XX +XXX,XX @@ static int xen_block_parse_request(XenBlockRequest *request)
92
if (length > backing_length) {
108
};
93
- ret = blk_truncate(backing, length, false, PREALLOC_MODE_OFF,
109
94
+ ret = blk_truncate(backing, length, false, PREALLOC_MODE_OFF, 0,
110
if (request->req.operation != BLKIF_OP_READ &&
95
&local_err);
111
- blk_is_read_only(dataplane->blk)) {
112
+ !blk_is_writable(dataplane->blk)) {
113
error_report("error: write req for ro device");
114
goto err;
115
}
116
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/hw/block/fdc.c
119
+++ b/hw/block/fdc.c
120
@@ -XXX,XX +XXX,XX @@ static void fd_revalidate(FDrive *drv)
121
122
FLOPPY_DPRINTF("revalidate\n");
123
if (drv->blk != NULL) {
124
- drv->ro = blk_is_read_only(drv->blk);
125
+ drv->ro = !blk_is_writable(drv->blk);
126
if (!blk_is_inserted(drv->blk)) {
127
FLOPPY_DPRINTF("No disk in drive\n");
128
drv->disk = FLOPPY_DRIVE_TYPE_NONE;
129
@@ -XXX,XX +XXX,XX @@ static void fd_change_cb(void *opaque, bool load, Error **errp)
130
blk_set_perm(drive->blk, 0, BLK_PERM_ALL, &error_abort);
131
} else {
132
if (!blkconf_apply_backend_options(drive->conf,
133
- blk_is_read_only(drive->blk), false,
134
- errp)) {
135
+ !blk_supports_write_perm(drive->blk),
136
+ false, errp)) {
137
return;
138
}
139
}
140
@@ -XXX,XX +XXX,XX @@ static void floppy_drive_realize(DeviceState *qdev, Error **errp)
141
* read-only node later */
142
read_only = true;
143
} else {
144
- read_only = !blk_bs(dev->conf.blk) || blk_is_read_only(dev->conf.blk);
145
+ read_only = !blk_bs(dev->conf.blk) ||
146
+ !blk_supports_write_perm(dev->conf.blk);
147
}
148
149
if (!blkconf_blocksizes(&dev->conf, errp)) {
150
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
151
index XXXXXXX..XXXXXXX 100644
152
--- a/hw/block/m25p80.c
153
+++ b/hw/block/m25p80.c
154
@@ -XXX,XX +XXX,XX @@ static void flash_sync_page(Flash *s, int page)
155
{
156
QEMUIOVector *iov;
157
158
- if (!s->blk || blk_is_read_only(s->blk)) {
159
+ if (!s->blk || !blk_is_writable(s->blk)) {
160
return;
161
}
162
163
@@ -XXX,XX +XXX,XX @@ static inline void flash_sync_area(Flash *s, int64_t off, int64_t len)
164
{
165
QEMUIOVector *iov;
166
167
- if (!s->blk || blk_is_read_only(s->blk)) {
168
+ if (!s->blk || !blk_is_writable(s->blk)) {
169
return;
170
}
171
172
@@ -XXX,XX +XXX,XX @@ static void m25p80_realize(SSIPeripheral *ss, Error **errp)
173
174
if (s->blk) {
175
uint64_t perm = BLK_PERM_CONSISTENT_READ |
176
- (blk_is_read_only(s->blk) ? 0 : BLK_PERM_WRITE);
177
+ (blk_supports_write_perm(s->blk) ? BLK_PERM_WRITE : 0);
178
ret = blk_set_perm(s->blk, perm, BLK_PERM_ALL, errp);
96
if (ret < 0) {
179
if (ret < 0) {
97
error_report_err(local_err);
180
return;
98
diff --git a/block/crypto.c b/block/crypto.c
181
diff --git a/hw/block/nand.c b/hw/block/nand.c
99
index XXXXXXX..XXXXXXX 100644
182
index XXXXXXX..XXXXXXX 100644
100
--- a/block/crypto.c
183
--- a/hw/block/nand.c
101
+++ b/block/crypto.c
184
+++ b/hw/block/nand.c
102
@@ -XXX,XX +XXX,XX @@ static ssize_t block_crypto_init_func(QCryptoBlock *block,
185
@@ -XXX,XX +XXX,XX @@ static void nand_realize(DeviceState *dev, Error **errp)
103
* which will be used by the crypto header
186
pagesize = 1 << s->oob_shift;
187
s->mem_oob = 1;
188
if (s->blk) {
189
- if (blk_is_read_only(s->blk)) {
190
+ if (!blk_supports_write_perm(s->blk)) {
191
error_setg(errp, "Can't use a read-only drive");
192
return;
193
}
194
diff --git a/hw/block/nvme-ns.c b/hw/block/nvme-ns.c
195
index XXXXXXX..XXXXXXX 100644
196
--- a/hw/block/nvme-ns.c
197
+++ b/hw/block/nvme-ns.c
198
@@ -XXX,XX +XXX,XX @@ static void nvme_ns_init(NvmeNamespace *ns)
199
200
static int nvme_ns_init_blk(NvmeCtrl *n, NvmeNamespace *ns, Error **errp)
201
{
202
+ bool read_only;
203
+
204
if (!blkconf_blocksizes(&ns->blkconf, errp)) {
205
return -1;
206
}
207
208
- if (!blkconf_apply_backend_options(&ns->blkconf,
209
- blk_is_read_only(ns->blkconf.blk),
210
- false, errp)) {
211
+ read_only = !blk_supports_write_perm(ns->blkconf.blk);
212
+ if (!blkconf_apply_backend_options(&ns->blkconf, read_only, false, errp)) {
213
return -1;
214
}
215
216
diff --git a/hw/block/onenand.c b/hw/block/onenand.c
217
index XXXXXXX..XXXXXXX 100644
218
--- a/hw/block/onenand.c
219
+++ b/hw/block/onenand.c
220
@@ -XXX,XX +XXX,XX @@ static void onenand_realize(DeviceState *dev, Error **errp)
221
s->image = memset(g_malloc(size + (size >> 5)),
222
0xff, size + (size >> 5));
223
} else {
224
- if (blk_is_read_only(s->blk)) {
225
+ if (!blk_supports_write_perm(s->blk)) {
226
error_setg(errp, "Can't use a read-only drive");
227
return;
228
}
229
diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
230
index XXXXXXX..XXXXXXX 100644
231
--- a/hw/block/pflash_cfi01.c
232
+++ b/hw/block/pflash_cfi01.c
233
@@ -XXX,XX +XXX,XX @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
234
235
if (pfl->blk) {
236
uint64_t perm;
237
- pfl->ro = blk_is_read_only(pfl->blk);
238
+ pfl->ro = !blk_supports_write_perm(pfl->blk);
239
perm = BLK_PERM_CONSISTENT_READ | (pfl->ro ? 0 : BLK_PERM_WRITE);
240
ret = blk_set_perm(pfl->blk, perm, BLK_PERM_ALL, errp);
241
if (ret < 0) {
242
diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
243
index XXXXXXX..XXXXXXX 100644
244
--- a/hw/block/pflash_cfi02.c
245
+++ b/hw/block/pflash_cfi02.c
246
@@ -XXX,XX +XXX,XX @@ static void pflash_cfi02_realize(DeviceState *dev, Error **errp)
247
248
if (pfl->blk) {
249
uint64_t perm;
250
- pfl->ro = blk_is_read_only(pfl->blk);
251
+ pfl->ro = !blk_supports_write_perm(pfl->blk);
252
perm = BLK_PERM_CONSISTENT_READ | (pfl->ro ? 0 : BLK_PERM_WRITE);
253
ret = blk_set_perm(pfl->blk, perm, BLK_PERM_ALL, errp);
254
if (ret < 0) {
255
diff --git a/hw/block/swim.c b/hw/block/swim.c
256
index XXXXXXX..XXXXXXX 100644
257
--- a/hw/block/swim.c
258
+++ b/hw/block/swim.c
259
@@ -XXX,XX +XXX,XX @@ static void swim_change_cb(void *opaque, bool load, Error **errp)
260
blk_set_perm(drive->blk, 0, BLK_PERM_ALL, &error_abort);
261
} else {
262
if (!blkconf_apply_backend_options(drive->conf,
263
- blk_is_read_only(drive->blk), false,
264
- errp)) {
265
+ !blk_supports_write_perm(drive->blk),
266
+ false, errp)) {
267
return;
268
}
269
}
270
@@ -XXX,XX +XXX,XX @@ static void swim_drive_realize(DeviceState *qdev, Error **errp)
271
dev->conf.werror = BLOCKDEV_ON_ERROR_AUTO;
272
273
if (!blkconf_apply_backend_options(&dev->conf,
274
- blk_is_read_only(dev->conf.blk),
275
+ !blk_supports_write_perm(dev->conf.blk),
276
false, errp)) {
277
return;
278
}
279
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
280
index XXXXXXX..XXXXXXX 100644
281
--- a/hw/block/virtio-blk.c
282
+++ b/hw/block/virtio-blk.c
283
@@ -XXX,XX +XXX,XX @@ static uint64_t virtio_blk_get_features(VirtIODevice *vdev, uint64_t features,
284
virtio_has_feature(features, VIRTIO_BLK_F_CONFIG_WCE))) {
285
virtio_add_feature(&features, VIRTIO_BLK_F_WCE);
286
}
287
- if (blk_is_read_only(s->blk)) {
288
+ if (!blk_is_writable(s->blk)) {
289
virtio_add_feature(&features, VIRTIO_BLK_F_RO);
290
}
291
if (s->conf.num_queues > 1) {
292
@@ -XXX,XX +XXX,XX @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
293
}
294
295
if (!blkconf_apply_backend_options(&conf->conf,
296
- blk_is_read_only(conf->conf.blk), true,
297
- errp)) {
298
+ !blk_supports_write_perm(conf->conf.blk),
299
+ true, errp)) {
300
return;
301
}
302
s->original_wce = blk_enable_write_cache(conf->conf.blk);
303
diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
304
index XXXXXXX..XXXXXXX 100644
305
--- a/hw/block/xen-block.c
306
+++ b/hw/block/xen-block.c
307
@@ -XXX,XX +XXX,XX @@ static void xen_disk_realize(XenBlockDevice *blockdev, Error **errp)
308
return;
309
}
310
311
- blockdev->info = blk_is_read_only(conf->blk) ? VDISK_READONLY : 0;
312
+ blockdev->info = blk_supports_write_perm(conf->blk) ? 0 : VDISK_READONLY;
313
}
314
315
static void xen_disk_class_init(ObjectClass *class, void *data)
316
diff --git a/hw/ide/core.c b/hw/ide/core.c
317
index XXXXXXX..XXXXXXX 100644
318
--- a/hw/ide/core.c
319
+++ b/hw/ide/core.c
320
@@ -XXX,XX +XXX,XX @@ int ide_init_drive(IDEState *s, BlockBackend *blk, IDEDriveKind kind,
321
error_setg(errp, "Device needs media, but drive is empty");
322
return -1;
323
}
324
- if (blk_is_read_only(blk)) {
325
+ if (!blk_is_writable(blk)) {
326
error_setg(errp, "Can't use a read-only drive");
327
return -1;
328
}
329
diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c
330
index XXXXXXX..XXXXXXX 100644
331
--- a/hw/misc/sifive_u_otp.c
332
+++ b/hw/misc/sifive_u_otp.c
333
@@ -XXX,XX +XXX,XX @@ static void sifive_u_otp_realize(DeviceState *dev, Error **errp)
334
335
if (s->blk) {
336
perm = BLK_PERM_CONSISTENT_READ |
337
- (blk_is_read_only(s->blk) ? 0 : BLK_PERM_WRITE);
338
+ (blk_supports_write_perm(s->blk) ? BLK_PERM_WRITE : 0);
339
ret = blk_set_perm(s->blk, perm, BLK_PERM_ALL, errp);
340
if (ret < 0) {
341
return;
342
diff --git a/hw/ppc/pnv_pnor.c b/hw/ppc/pnv_pnor.c
343
index XXXXXXX..XXXXXXX 100644
344
--- a/hw/ppc/pnv_pnor.c
345
+++ b/hw/ppc/pnv_pnor.c
346
@@ -XXX,XX +XXX,XX @@ static void pnv_pnor_realize(DeviceState *dev, Error **errp)
347
348
if (s->blk) {
349
uint64_t perm = BLK_PERM_CONSISTENT_READ |
350
- (blk_is_read_only(s->blk) ? 0 : BLK_PERM_WRITE);
351
+ (blk_supports_write_perm(s->blk) ? BLK_PERM_WRITE : 0);
352
ret = blk_set_perm(s->blk, perm, BLK_PERM_ALL, errp);
353
if (ret < 0) {
354
return;
355
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
356
index XXXXXXX..XXXXXXX 100644
357
--- a/hw/scsi/scsi-disk.c
358
+++ b/hw/scsi/scsi-disk.c
359
@@ -XXX,XX +XXX,XX @@ static int scsi_disk_emulate_mode_sense(SCSIDiskReq *r, uint8_t *outbuf)
360
361
if (s->qdev.type == TYPE_DISK) {
362
dev_specific_param = s->features & (1 << SCSI_DISK_F_DPOFUA) ? 0x10 : 0;
363
- if (blk_is_read_only(s->qdev.conf.blk)) {
364
+ if (!blk_is_writable(s->qdev.conf.blk)) {
365
dev_specific_param |= 0x80; /* Readonly. */
366
}
367
} else {
368
@@ -XXX,XX +XXX,XX @@ static void scsi_disk_emulate_unmap(SCSIDiskReq *r, uint8_t *inbuf)
369
goto invalid_param_len;
370
}
371
372
- if (blk_is_read_only(s->qdev.conf.blk)) {
373
+ if (!blk_is_writable(s->qdev.conf.blk)) {
374
block_acct_invalid(blk_get_stats(s->qdev.conf.blk), BLOCK_ACCT_UNMAP);
375
scsi_check_condition(r, SENSE_CODE(WRITE_PROTECTED));
376
return;
377
@@ -XXX,XX +XXX,XX @@ static void scsi_disk_emulate_write_same(SCSIDiskReq *r, uint8_t *inbuf)
378
return;
379
}
380
381
- if (blk_is_read_only(s->qdev.conf.blk)) {
382
+ if (!blk_is_writable(s->qdev.conf.blk)) {
383
scsi_check_condition(r, SENSE_CODE(WRITE_PROTECTED));
384
return;
385
}
386
@@ -XXX,XX +XXX,XX @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
387
case WRITE_VERIFY_10:
388
case WRITE_VERIFY_12:
389
case WRITE_VERIFY_16:
390
- if (blk_is_read_only(s->qdev.conf.blk)) {
391
+ if (!blk_is_writable(s->qdev.conf.blk)) {
392
scsi_check_condition(r, SENSE_CODE(WRITE_PROTECTED));
393
return 0;
394
}
395
@@ -XXX,XX +XXX,XX @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
396
}
397
}
398
399
- read_only = blk_is_read_only(s->qdev.conf.blk);
400
+ read_only = !blk_supports_write_perm(s->qdev.conf.blk);
401
if (dev->type == TYPE_ROM) {
402
read_only = true;
403
}
404
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
405
index XXXXXXX..XXXXXXX 100644
406
--- a/hw/scsi/scsi-generic.c
407
+++ b/hw/scsi/scsi-generic.c
408
@@ -XXX,XX +XXX,XX @@ static void scsi_read_complete(void * opaque, int ret)
409
* readonly.
104
*/
410
*/
105
return blk_truncate(data->blk, data->size + headerlen, false,
411
if ((s->type == TYPE_DISK || s->type == TYPE_TAPE || s->type == TYPE_ZBC) &&
106
- data->prealloc, errp);
412
- blk_is_read_only(s->conf.blk) &&
107
+ data->prealloc, 0, errp);
413
+ !blk_is_writable(s->conf.blk) &&
414
(r->req.cmd.buf[0] == MODE_SENSE ||
415
r->req.cmd.buf[0] == MODE_SENSE_10) &&
416
(r->req.cmd.buf[1] & 0x8) == 0) {
417
@@ -XXX,XX +XXX,XX @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp)
418
return;
419
}
420
if (!blkconf_apply_backend_options(&s->conf,
421
- blk_is_read_only(s->conf.blk),
422
+ !blk_supports_write_perm(s->conf.blk),
423
true, errp)) {
424
return;
425
}
426
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
427
index XXXXXXX..XXXXXXX 100644
428
--- a/hw/sd/sd.c
429
+++ b/hw/sd/sd.c
430
@@ -XXX,XX +XXX,XX @@ static void sd_reset(DeviceState *dev)
431
sd_set_sdstatus(sd);
432
433
g_free(sd->wp_groups);
434
- sd->wp_switch = sd->blk ? blk_is_read_only(sd->blk) : false;
435
+ sd->wp_switch = sd->blk ? !blk_is_writable(sd->blk) : false;
436
sd->wpgrps_size = sect;
437
sd->wp_groups = bitmap_new(sd->wpgrps_size);
438
memset(sd->function_group, 0, sizeof(sd->function_group));
439
@@ -XXX,XX +XXX,XX @@ void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert)
440
{
441
sd->readonly_cb = readonly;
442
sd->inserted_cb = insert;
443
- qemu_set_irq(readonly, sd->blk ? blk_is_read_only(sd->blk) : 0);
444
+ qemu_set_irq(readonly, sd->blk ? !blk_is_writable(sd->blk) : 0);
445
qemu_set_irq(insert, sd->blk ? blk_is_inserted(sd->blk) : 0);
108
}
446
}
109
447
110
448
@@ -XXX,XX +XXX,XX @@ static void sd_realize(DeviceState *dev, Error **errp)
111
diff --git a/block/mirror.c b/block/mirror.c
449
if (sd->blk) {
112
index XXXXXXX..XXXXXXX 100644
450
int64_t blk_size;
113
--- a/block/mirror.c
451
114
+++ b/block/mirror.c
452
- if (blk_is_read_only(sd->blk)) {
115
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
453
+ if (!blk_supports_write_perm(sd->blk)) {
116
454
error_setg(errp, "Cannot use read-only drive as SD card");
117
if (s->bdev_length > base_length) {
455
return;
118
ret = blk_truncate(s->target, s->bdev_length, false,
456
}
119
- PREALLOC_MODE_OFF, NULL);
457
diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
120
+ PREALLOC_MODE_OFF, 0, NULL);
458
index XXXXXXX..XXXXXXX 100644
121
if (ret < 0) {
459
--- a/hw/usb/dev-storage.c
122
goto immediate_exit;
460
+++ b/hw/usb/dev-storage.c
123
}
461
@@ -XXX,XX +XXX,XX @@ static void usb_msd_storage_realize(USBDevice *dev, Error **errp)
124
diff --git a/block/qcow2.c b/block/qcow2.c
462
return;
125
index XXXXXXX..XXXXXXX 100644
463
}
126
--- a/block/qcow2.c
464
127
+++ b/block/qcow2.c
465
- if (!blkconf_apply_backend_options(&s->conf, blk_is_read_only(blk), true,
128
@@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
466
- errp)) {
129
467
+ if (!blkconf_apply_backend_options(&s->conf, !blk_supports_write_perm(blk),
130
/* Okay, now that we have a valid image, let's give it the right size */
468
+ true, errp)) {
131
ret = blk_truncate(blk, qcow2_opts->size, false, qcow2_opts->preallocation,
469
return;
132
- errp);
470
}
133
+ 0, errp);
471
134
if (ret < 0) {
135
error_prepend(errp, "Could not resize image: ");
136
goto out;
137
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
138
* Amending image options should ensure that the image has
139
* exactly the given new values, so pass exact=true here.
140
*/
141
- ret = blk_truncate(blk, new_size, true, PREALLOC_MODE_OFF, errp);
142
+ ret = blk_truncate(blk, new_size, true, PREALLOC_MODE_OFF, 0, errp);
143
blk_unref(blk);
144
if (ret < 0) {
145
return ret;
146
diff --git a/block/qed.c b/block/qed.c
147
index XXXXXXX..XXXXXXX 100644
148
--- a/block/qed.c
149
+++ b/block/qed.c
150
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_create(BlockdevCreateOptions *opts,
151
* The QED format associates file length with allocation status,
152
* so a new file (which is empty) must have a length of 0.
153
*/
154
- ret = blk_truncate(blk, 0, true, PREALLOC_MODE_OFF, errp);
155
+ ret = blk_truncate(blk, 0, true, PREALLOC_MODE_OFF, 0, errp);
156
if (ret < 0) {
157
goto out;
158
}
159
diff --git a/block/vdi.c b/block/vdi.c
160
index XXXXXXX..XXXXXXX 100644
161
--- a/block/vdi.c
162
+++ b/block/vdi.c
163
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
164
165
if (image_type == VDI_TYPE_STATIC) {
166
ret = blk_truncate(blk, offset + blocks * block_size, false,
167
- PREALLOC_MODE_OFF, errp);
168
+ PREALLOC_MODE_OFF, 0, errp);
169
if (ret < 0) {
170
error_prepend(errp, "Failed to statically allocate file");
171
goto exit;
172
diff --git a/block/vhdx.c b/block/vhdx.c
173
index XXXXXXX..XXXXXXX 100644
174
--- a/block/vhdx.c
175
+++ b/block/vhdx.c
176
@@ -XXX,XX +XXX,XX @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
177
/* All zeroes, so we can just extend the file - the end of the BAT
178
* is the furthest thing we have written yet */
179
ret = blk_truncate(blk, data_file_offset, false, PREALLOC_MODE_OFF,
180
- errp);
181
+ 0, errp);
182
if (ret < 0) {
183
goto exit;
184
}
185
} else if (type == VHDX_TYPE_FIXED) {
186
ret = blk_truncate(blk, data_file_offset + image_size, false,
187
- PREALLOC_MODE_OFF, errp);
188
+ PREALLOC_MODE_OFF, 0, errp);
189
if (ret < 0) {
190
goto exit;
191
}
192
diff --git a/block/vmdk.c b/block/vmdk.c
193
index XXXXXXX..XXXXXXX 100644
194
--- a/block/vmdk.c
195
+++ b/block/vmdk.c
196
@@ -XXX,XX +XXX,XX @@ static int vmdk_init_extent(BlockBackend *blk,
197
int gd_buf_size;
198
199
if (flat) {
200
- ret = blk_truncate(blk, filesize, false, PREALLOC_MODE_OFF, errp);
201
+ ret = blk_truncate(blk, filesize, false, PREALLOC_MODE_OFF, 0, errp);
202
goto exit;
203
}
204
magic = cpu_to_be32(VMDK4_MAGIC);
205
@@ -XXX,XX +XXX,XX @@ static int vmdk_init_extent(BlockBackend *blk,
206
}
207
208
ret = blk_truncate(blk, le64_to_cpu(header.grain_offset) << 9, false,
209
- PREALLOC_MODE_OFF, errp);
210
+ PREALLOC_MODE_OFF, 0, errp);
211
if (ret < 0) {
212
goto exit;
213
}
214
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vmdk_co_do_create(int64_t size,
215
/* bdrv_pwrite write padding zeros to align to sector, we don't need that
216
* for description file */
217
if (desc_offset == 0) {
218
- ret = blk_truncate(blk, desc_len, false, PREALLOC_MODE_OFF, errp);
219
+ ret = blk_truncate(blk, desc_len, false, PREALLOC_MODE_OFF, 0, errp);
220
if (ret < 0) {
221
goto exit;
222
}
223
diff --git a/block/vpc.c b/block/vpc.c
224
index XXXXXXX..XXXXXXX 100644
225
--- a/block/vpc.c
226
+++ b/block/vpc.c
227
@@ -XXX,XX +XXX,XX @@ static int create_fixed_disk(BlockBackend *blk, uint8_t *buf,
228
/* Add footer to total size */
229
total_size += HEADER_SIZE;
230
231
- ret = blk_truncate(blk, total_size, false, PREALLOC_MODE_OFF, errp);
232
+ ret = blk_truncate(blk, total_size, false, PREALLOC_MODE_OFF, 0, errp);
233
if (ret < 0) {
234
return ret;
235
}
236
diff --git a/blockdev.c b/blockdev.c
237
index XXXXXXX..XXXXXXX 100644
238
--- a/blockdev.c
239
+++ b/blockdev.c
240
@@ -XXX,XX +XXX,XX @@ void qmp_block_resize(bool has_device, const char *device,
241
}
242
243
bdrv_drained_begin(bs);
244
- ret = blk_truncate(blk, size, false, PREALLOC_MODE_OFF, errp);
245
+ ret = blk_truncate(blk, size, false, PREALLOC_MODE_OFF, 0, errp);
246
bdrv_drained_end(bs);
247
248
out:
249
diff --git a/qemu-img.c b/qemu-img.c
250
index XXXXXXX..XXXXXXX 100644
251
--- a/qemu-img.c
252
+++ b/qemu-img.c
253
@@ -XXX,XX +XXX,XX @@ static int img_resize(int argc, char **argv)
254
* resizing, so pass @exact=true. It is of no use to report
255
* success when the image has not actually been resized.
256
*/
257
- ret = blk_truncate(blk, total_size, true, prealloc, &err);
258
+ ret = blk_truncate(blk, total_size, true, prealloc, 0, &err);
259
if (!ret) {
260
qprintf(quiet, "Image resized.\n");
261
} else {
262
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
263
index XXXXXXX..XXXXXXX 100644
264
--- a/qemu-io-cmds.c
265
+++ b/qemu-io-cmds.c
266
@@ -XXX,XX +XXX,XX @@ static int truncate_f(BlockBackend *blk, int argc, char **argv)
267
* exact=true. It is better to err on the "emit more errors" side
268
* than to be overly permissive.
269
*/
270
- ret = blk_truncate(blk, offset, true, PREALLOC_MODE_OFF, &local_err);
271
+ ret = blk_truncate(blk, offset, true, PREALLOC_MODE_OFF, 0, &local_err);
272
if (ret < 0) {
273
error_report_err(local_err);
274
return ret;
275
--
472
--
276
2.25.3
473
2.29.2
277
474
278
475
diff view generated by jsdifflib
1
Now that block drivers can support flags for .bdrv_co_truncate, expose
1
This tests that trying to write to a (read-only) scsi-cd device backed
2
the parameter in the node level interfaces bdrv_co_truncate() and
2
by a read-write image file doesn't crash and results in the correct
3
bdrv_truncate().
3
error.
4
5
This is a regression test for https://bugs.launchpad.net/bugs/1906693.
4
6
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Message-Id: <20210118123448.307825-3-kwolf@redhat.com>
7
Reviewed-by: Alberto Garcia <berto@igalia.com>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
10
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
Message-Id: <20200424125448.63318-3-kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
---
12
include/block/block.h | 5 +++--
13
tests/qtest/virtio-scsi-test.c | 39 ++++++++++++++++++++++++++++++++++
13
block/block-backend.c | 2 +-
14
1 file changed, 39 insertions(+)
14
block/crypto.c | 2 +-
15
block/io.c | 12 +++++++-----
16
block/parallels.c | 6 +++---
17
block/qcow.c | 4 ++--
18
block/qcow2-refcount.c | 2 +-
19
block/qcow2.c | 15 +++++++++------
20
block/raw-format.c | 2 +-
21
block/vhdx-log.c | 2 +-
22
block/vhdx.c | 2 +-
23
block/vmdk.c | 2 +-
24
tests/test-block-iothread.c | 6 +++---
25
13 files changed, 34 insertions(+), 28 deletions(-)
26
15
27
diff --git a/include/block/block.h b/include/block/block.h
16
diff --git a/tests/qtest/virtio-scsi-test.c b/tests/qtest/virtio-scsi-test.c
28
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
29
--- a/include/block/block.h
18
--- a/tests/qtest/virtio-scsi-test.c
30
+++ b/include/block/block.h
19
+++ b/tests/qtest/virtio-scsi-test.c
31
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
20
@@ -XXX,XX +XXX,XX @@ static void test_unaligned_write_same(void *obj, void *data,
32
void bdrv_refresh_filename(BlockDriverState *bs);
21
qvirtio_scsi_pci_free(vs);
33
34
int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
35
- PreallocMode prealloc, Error **errp);
36
+ PreallocMode prealloc, BdrvRequestFlags flags,
37
+ Error **errp);
38
int bdrv_truncate(BdrvChild *child, int64_t offset, bool exact,
39
- PreallocMode prealloc, Error **errp);
40
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp);
41
42
int64_t bdrv_nb_sectors(BlockDriverState *bs);
43
int64_t bdrv_getlength(BlockDriverState *bs);
44
diff --git a/block/block-backend.c b/block/block-backend.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/block/block-backend.c
47
+++ b/block/block-backend.c
48
@@ -XXX,XX +XXX,XX @@ int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
49
return -ENOMEDIUM;
50
}
51
52
- return bdrv_truncate(blk->root, offset, exact, prealloc, errp);
53
+ return bdrv_truncate(blk->root, offset, exact, prealloc, 0, errp);
54
}
22
}
55
23
56
int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
24
+static void test_write_to_cdrom(void *obj, void *data,
57
diff --git a/block/crypto.c b/block/crypto.c
25
+ QGuestAllocator *t_alloc)
58
index XXXXXXX..XXXXXXX 100644
26
+{
59
--- a/block/crypto.c
27
+ QVirtioSCSI *scsi = obj;
60
+++ b/block/crypto.c
28
+ QVirtioSCSIQueues *vs;
61
@@ -XXX,XX +XXX,XX @@ block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
29
+ uint8_t buf[2048] = { 0 };
62
30
+ const uint8_t write_cdb[VIRTIO_SCSI_CDB_SIZE] = {
63
offset += payload_offset;
31
+ /* WRITE(10) to LBA 0, transfer length 1 */
64
32
+ 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00
65
- return bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
33
+ };
66
+ return bdrv_co_truncate(bs->file, offset, exact, prealloc, 0, errp);
34
+ struct virtio_scsi_cmd_resp resp;
35
+
36
+ alloc = t_alloc;
37
+ vs = qvirtio_scsi_init(scsi->vdev);
38
+
39
+ virtio_scsi_do_command(vs, write_cdb, NULL, 0, buf, 2048, &resp);
40
+ g_assert_cmphex(resp.response, ==, 0);
41
+ g_assert_cmphex(resp.status, ==, CHECK_CONDITION);
42
+ g_assert_cmphex(resp.sense[0], ==, 0x70);
43
+ g_assert_cmphex(resp.sense[2], ==, DATA_PROTECT);
44
+ g_assert_cmphex(resp.sense[12], ==, 0x27); /* WRITE PROTECTED */
45
+ g_assert_cmphex(resp.sense[13], ==, 0x00); /* WRITE PROTECTED */
46
+
47
+ qvirtio_scsi_pci_free(vs);
48
+}
49
+
50
static void test_iothread_attach_node(void *obj, void *data,
51
QGuestAllocator *t_alloc)
52
{
53
@@ -XXX,XX +XXX,XX @@ static void *virtio_scsi_setup(GString *cmd_line, void *arg)
54
return arg;
67
}
55
}
68
56
69
static void block_crypto_close(BlockDriverState *bs)
57
+static void *virtio_scsi_setup_cd(GString *cmd_line, void *arg)
70
diff --git a/block/io.c b/block/io.c
58
+{
71
index XXXXXXX..XXXXXXX 100644
59
+ g_string_append(cmd_line,
72
--- a/block/io.c
60
+ " -drive file=null-co://,"
73
+++ b/block/io.c
61
+ "file.read-zeroes=on,"
74
@@ -XXX,XX +XXX,XX @@ static void bdrv_parent_cb_resize(BlockDriverState *bs)
62
+ "if=none,id=dr1,format=raw "
75
* 'offset' bytes in length.
63
+ "-device scsi-cd,drive=dr1,lun=0,scsi-id=1");
76
*/
64
+ return arg;
77
int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
65
+}
78
- PreallocMode prealloc, Error **errp)
66
+
79
+ PreallocMode prealloc, BdrvRequestFlags flags,
67
static void *virtio_scsi_setup_iothread(GString *cmd_line, void *arg)
80
+ Error **errp)
81
{
68
{
82
BlockDriverState *bs = child->bs;
69
g_string_append(cmd_line,
83
BlockDriver *drv = bs->drv;
70
@@ -XXX,XX +XXX,XX @@ static void register_virtio_scsi_test(void)
84
BdrvTrackedRequest req;
71
qos_add_test("unaligned-write-same", "virtio-scsi",
85
- BdrvRequestFlags flags = 0;
72
test_unaligned_write_same, &opts);
86
int64_t old_size, new_bytes;
73
87
int ret;
74
+ opts.before = virtio_scsi_setup_cd;
88
75
+ qos_add_test("write-to-cdrom", "virtio-scsi", test_write_to_cdrom, &opts);
89
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
76
+
90
}
77
opts.before = virtio_scsi_setup_iothread;
91
ret = drv->bdrv_co_truncate(bs, offset, exact, prealloc, flags, errp);
78
opts.edge = (QOSGraphEdgeOptions) {
92
} else if (bs->file && drv->is_filter) {
79
.extra_device_opts = "iothread=thread0",
93
- ret = bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
94
+ ret = bdrv_co_truncate(bs->file, offset, exact, prealloc, flags, errp);
95
} else {
96
error_setg(errp, "Image format driver does not support resize");
97
ret = -ENOTSUP;
98
@@ -XXX,XX +XXX,XX @@ typedef struct TruncateCo {
99
int64_t offset;
100
bool exact;
101
PreallocMode prealloc;
102
+ BdrvRequestFlags flags;
103
Error **errp;
104
int ret;
105
} TruncateCo;
106
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_truncate_co_entry(void *opaque)
107
{
108
TruncateCo *tco = opaque;
109
tco->ret = bdrv_co_truncate(tco->child, tco->offset, tco->exact,
110
- tco->prealloc, tco->errp);
111
+ tco->prealloc, tco->flags, tco->errp);
112
aio_wait_kick();
113
}
114
115
int bdrv_truncate(BdrvChild *child, int64_t offset, bool exact,
116
- PreallocMode prealloc, Error **errp)
117
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp)
118
{
119
Coroutine *co;
120
TruncateCo tco = {
121
@@ -XXX,XX +XXX,XX @@ int bdrv_truncate(BdrvChild *child, int64_t offset, bool exact,
122
.offset = offset,
123
.exact = exact,
124
.prealloc = prealloc,
125
+ .flags = flags,
126
.errp = errp,
127
.ret = NOT_DONE,
128
};
129
diff --git a/block/parallels.c b/block/parallels.c
130
index XXXXXXX..XXXXXXX 100644
131
--- a/block/parallels.c
132
+++ b/block/parallels.c
133
@@ -XXX,XX +XXX,XX @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num,
134
} else {
135
ret = bdrv_truncate(bs->file,
136
(s->data_end + space) << BDRV_SECTOR_BITS,
137
- false, PREALLOC_MODE_OFF, NULL);
138
+ false, PREALLOC_MODE_OFF, 0, NULL);
139
}
140
if (ret < 0) {
141
return ret;
142
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn parallels_co_check(BlockDriverState *bs,
143
* That means we have to pass exact=true.
144
*/
145
ret = bdrv_truncate(bs->file, res->image_end_offset, true,
146
- PREALLOC_MODE_OFF, &local_err);
147
+ PREALLOC_MODE_OFF, 0, &local_err);
148
if (ret < 0) {
149
error_report_err(local_err);
150
res->check_errors++;
151
@@ -XXX,XX +XXX,XX @@ static void parallels_close(BlockDriverState *bs)
152
153
/* errors are ignored, so we might as well pass exact=true */
154
bdrv_truncate(bs->file, s->data_end << BDRV_SECTOR_BITS, true,
155
- PREALLOC_MODE_OFF, NULL);
156
+ PREALLOC_MODE_OFF, 0, NULL);
157
}
158
159
g_free(s->bat_dirty_bmap);
160
diff --git a/block/qcow.c b/block/qcow.c
161
index XXXXXXX..XXXXXXX 100644
162
--- a/block/qcow.c
163
+++ b/block/qcow.c
164
@@ -XXX,XX +XXX,XX @@ static int get_cluster_offset(BlockDriverState *bs,
165
return -E2BIG;
166
}
167
ret = bdrv_truncate(bs->file, cluster_offset + s->cluster_size,
168
- false, PREALLOC_MODE_OFF, NULL);
169
+ false, PREALLOC_MODE_OFF, 0, NULL);
170
if (ret < 0) {
171
return ret;
172
}
173
@@ -XXX,XX +XXX,XX @@ static int qcow_make_empty(BlockDriverState *bs)
174
l1_length) < 0)
175
return -1;
176
ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length, false,
177
- PREALLOC_MODE_OFF, NULL);
178
+ PREALLOC_MODE_OFF, 0, NULL);
179
if (ret < 0)
180
return ret;
181
182
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
183
index XXXXXXX..XXXXXXX 100644
184
--- a/block/qcow2-refcount.c
185
+++ b/block/qcow2-refcount.c
186
@@ -XXX,XX +XXX,XX @@ static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res,
187
}
188
189
ret = bdrv_truncate(bs->file, offset + s->cluster_size, false,
190
- PREALLOC_MODE_OFF, &local_err);
191
+ PREALLOC_MODE_OFF, 0, &local_err);
192
if (ret < 0) {
193
error_report_err(local_err);
194
goto resize_fail;
195
diff --git a/block/qcow2.c b/block/qcow2.c
196
index XXXXXXX..XXXXXXX 100644
197
--- a/block/qcow2.c
198
+++ b/block/qcow2.c
199
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
200
mode = PREALLOC_MODE_OFF;
201
}
202
ret = bdrv_co_truncate(s->data_file, host_offset + cur_bytes, false,
203
- mode, errp);
204
+ mode, 0, errp);
205
if (ret < 0) {
206
return ret;
207
}
208
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
209
* always fulfilled, so there is no need to pass it on.)
210
*/
211
bdrv_co_truncate(bs->file, (last_cluster + 1) * s->cluster_size,
212
- false, PREALLOC_MODE_OFF, &local_err);
213
+ false, PREALLOC_MODE_OFF, 0, &local_err);
214
if (local_err) {
215
warn_reportf_err(local_err,
216
"Failed to truncate the tail of the image: ");
217
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
218
* file should be resized to the exact target size, too,
219
* so we pass @exact here.
220
*/
221
- ret = bdrv_co_truncate(s->data_file, offset, exact, prealloc, errp);
222
+ ret = bdrv_co_truncate(s->data_file, offset, exact, prealloc, 0,
223
+ errp);
224
if (ret < 0) {
225
goto fail;
226
}
227
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
228
new_file_size = allocation_start +
229
nb_new_data_clusters * s->cluster_size;
230
/* Image file grows, so @exact does not matter */
231
- ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, errp);
232
+ ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, 0,
233
+ errp);
234
if (ret < 0) {
235
error_prepend(errp, "Failed to resize underlying file: ");
236
qcow2_free_clusters(bs, allocation_start,
237
@@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed_part(BlockDriverState *bs,
238
if (len < 0) {
239
return len;
240
}
241
- return bdrv_co_truncate(bs->file, len, false, PREALLOC_MODE_OFF, NULL);
242
+ return bdrv_co_truncate(bs->file, len, false, PREALLOC_MODE_OFF, 0,
243
+ NULL);
244
}
245
246
if (offset_into_cluster(s, offset)) {
247
@@ -XXX,XX +XXX,XX @@ static int make_completely_empty(BlockDriverState *bs)
248
}
249
250
ret = bdrv_truncate(bs->file, (3 + l1_clusters) * s->cluster_size, false,
251
- PREALLOC_MODE_OFF, &local_err);
252
+ PREALLOC_MODE_OFF, 0, &local_err);
253
if (ret < 0) {
254
error_report_err(local_err);
255
goto fail;
256
diff --git a/block/raw-format.c b/block/raw-format.c
257
index XXXXXXX..XXXXXXX 100644
258
--- a/block/raw-format.c
259
+++ b/block/raw-format.c
260
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
261
262
s->size = offset;
263
offset += s->offset;
264
- return bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
265
+ return bdrv_co_truncate(bs->file, offset, exact, prealloc, 0, errp);
266
}
267
268
static void raw_eject(BlockDriverState *bs, bool eject_flag)
269
diff --git a/block/vhdx-log.c b/block/vhdx-log.c
270
index XXXXXXX..XXXXXXX 100644
271
--- a/block/vhdx-log.c
272
+++ b/block/vhdx-log.c
273
@@ -XXX,XX +XXX,XX @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s,
274
goto exit;
275
}
276
ret = bdrv_truncate(bs->file, new_file_size, false,
277
- PREALLOC_MODE_OFF, NULL);
278
+ PREALLOC_MODE_OFF, 0, NULL);
279
if (ret < 0) {
280
goto exit;
281
}
282
diff --git a/block/vhdx.c b/block/vhdx.c
283
index XXXXXXX..XXXXXXX 100644
284
--- a/block/vhdx.c
285
+++ b/block/vhdx.c
286
@@ -XXX,XX +XXX,XX @@ static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s,
287
}
288
289
return bdrv_truncate(bs->file, *new_offset + s->block_size, false,
290
- PREALLOC_MODE_OFF, NULL);
291
+ PREALLOC_MODE_OFF, 0, NULL);
292
}
293
294
/*
295
diff --git a/block/vmdk.c b/block/vmdk.c
296
index XXXXXXX..XXXXXXX 100644
297
--- a/block/vmdk.c
298
+++ b/block/vmdk.c
299
@@ -XXX,XX +XXX,XX @@ vmdk_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
300
}
301
length = QEMU_ALIGN_UP(length, BDRV_SECTOR_SIZE);
302
ret = bdrv_truncate(s->extents[i].file, length, false,
303
- PREALLOC_MODE_OFF, NULL);
304
+ PREALLOC_MODE_OFF, 0, NULL);
305
if (ret < 0) {
306
return ret;
307
}
308
diff --git a/tests/test-block-iothread.c b/tests/test-block-iothread.c
309
index XXXXXXX..XXXXXXX 100644
310
--- a/tests/test-block-iothread.c
311
+++ b/tests/test-block-iothread.c
312
@@ -XXX,XX +XXX,XX @@ static void test_sync_op_truncate(BdrvChild *c)
313
int ret;
314
315
/* Normal success path */
316
- ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, NULL);
317
+ ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, 0, NULL);
318
g_assert_cmpint(ret, ==, 0);
319
320
/* Early error: Negative offset */
321
- ret = bdrv_truncate(c, -2, false, PREALLOC_MODE_OFF, NULL);
322
+ ret = bdrv_truncate(c, -2, false, PREALLOC_MODE_OFF, 0, NULL);
323
g_assert_cmpint(ret, ==, -EINVAL);
324
325
/* Error: Read-only image */
326
c->bs->read_only = true;
327
c->bs->open_flags &= ~BDRV_O_RDWR;
328
329
- ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, NULL);
330
+ ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, 0, NULL);
331
g_assert_cmpint(ret, ==, -EACCES);
332
333
c->bs->read_only = false;
334
--
80
--
335
2.25.3
81
2.29.2
336
82
337
83
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
Backing files and raw external data files are mutually exclusive.
3
check script will be stricter soon about whitespaces, so fix 146.out
4
The documentation of the raw external data bit (in autoclear_features)
4
now.
5
already indicates that, but we should also mention it on the other
6
side.
7
5
8
Suggested-by: Eric Blake <eblake@redhat.com>
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
Signed-off-by: Alberto Garcia <berto@igalia.com>
7
Message-Id: <20210125185056.129513-2-vsementsov@virtuozzo.com>
10
Message-Id: <20200410121816.8334-1-berto@igalia.com>
11
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Reviewed-by: Eric Blake <eblake@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
10
---
14
docs/interop/qcow2.txt | 3 +++
11
tests/qemu-iotests/146.out | 780 ++++++++++++++++++-------------------
15
1 file changed, 3 insertions(+)
12
1 file changed, 390 insertions(+), 390 deletions(-)
16
13
17
diff --git a/docs/interop/qcow2.txt b/docs/interop/qcow2.txt
14
diff --git a/tests/qemu-iotests/146.out b/tests/qemu-iotests/146.out
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/docs/interop/qcow2.txt
16
--- a/tests/qemu-iotests/146.out
20
+++ b/docs/interop/qcow2.txt
17
+++ b/tests/qemu-iotests/146.out
21
@@ -XXX,XX +XXX,XX @@ The first cluster of a qcow2 image contains the file header:
18
@@ -XXX,XX +XXX,XX @@ QA output created by 146
22
is stored (NB: The string is not null terminated). 0 if the
19
23
image doesn't have a backing file.
20
=== Testing VPC Autodetect ===
24
21
25
+ Note: backing files are incompatible with raw external data
22
-[{ "start": 0, "length": 136363130880, "depth": 0, "zero": true, "data": false }]
26
+ files (auto-clear feature bit 1).
23
+[{ "start": 0, "length": 136363130880, "depth": 0, "zero": true, "data": false}]
27
+
24
28
16 - 19: backing_file_size
25
=== Testing VPC with current_size force ===
29
Length of the backing file name in bytes. Must not be
26
30
longer than 1023 bytes. Undefined if the image doesn't have
27
-[{ "start": 0, "length": 136365211648, "depth": 0, "zero": true, "data": false }]
28
+[{ "start": 0, "length": 136365211648, "depth": 0, "zero": true, "data": false}]
29
30
=== Testing VPC with chs force ===
31
32
-[{ "start": 0, "length": 136363130880, "depth": 0, "zero": true, "data": false }]
33
+[{ "start": 0, "length": 136363130880, "depth": 0, "zero": true, "data": false}]
34
35
=== Testing Hyper-V Autodetect ===
36
37
-[{ "start": 0, "length": 136365211648, "depth": 0, "zero": true, "data": false }]
38
+[{ "start": 0, "length": 136365211648, "depth": 0, "zero": true, "data": false}]
39
40
=== Testing Hyper-V with current_size force ===
41
42
-[{ "start": 0, "length": 136365211648, "depth": 0, "zero": true, "data": false }]
43
+[{ "start": 0, "length": 136365211648, "depth": 0, "zero": true, "data": false}]
44
45
=== Testing Hyper-V with chs force ===
46
47
-[{ "start": 0, "length": 136363130880, "depth": 0, "zero": true, "data": false }]
48
+[{ "start": 0, "length": 136363130880, "depth": 0, "zero": true, "data": false}]
49
50
=== Testing d2v Autodetect ===
51
52
-[{ "start": 0, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
53
-{ "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
54
-{ "start": 4194304, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
55
-{ "start": 6291456, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
56
-{ "start": 8388608, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
57
-{ "start": 10485760, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
58
-{ "start": 12582912, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
59
-{ "start": 14680064, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
60
-{ "start": 16777216, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
61
-{ "start": 18874368, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
62
-{ "start": 20971520, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
63
-{ "start": 23068672, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
64
-{ "start": 25165824, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
65
-{ "start": 27262976, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
66
-{ "start": 29360128, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
67
-{ "start": 31457280, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
68
-{ "start": 33554432, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
69
-{ "start": 35651584, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
70
-{ "start": 37748736, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
71
-{ "start": 39845888, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
72
-{ "start": 41943040, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
73
-{ "start": 44040192, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
74
-{ "start": 46137344, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
75
-{ "start": 48234496, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
76
-{ "start": 50331648, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
77
-{ "start": 52428800, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
78
-{ "start": 54525952, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
79
-{ "start": 56623104, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
80
-{ "start": 58720256, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
81
-{ "start": 60817408, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
82
-{ "start": 62914560, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
83
-{ "start": 65011712, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
84
-{ "start": 67108864, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
85
-{ "start": 69206016, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
86
-{ "start": 71303168, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
87
-{ "start": 73400320, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
88
-{ "start": 75497472, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
89
-{ "start": 77594624, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
90
-{ "start": 79691776, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
91
-{ "start": 81788928, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
92
-{ "start": 83886080, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
93
-{ "start": 85983232, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
94
-{ "start": 88080384, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
95
-{ "start": 90177536, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
96
-{ "start": 92274688, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
97
-{ "start": 94371840, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
98
-{ "start": 96468992, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
99
-{ "start": 98566144, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
100
-{ "start": 100663296, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
101
-{ "start": 102760448, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
102
-{ "start": 104857600, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
103
-{ "start": 106954752, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
104
-{ "start": 109051904, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
105
-{ "start": 111149056, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
106
-{ "start": 113246208, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
107
-{ "start": 115343360, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
108
-{ "start": 117440512, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
109
-{ "start": 119537664, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
110
-{ "start": 121634816, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
111
-{ "start": 123731968, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
112
-{ "start": 125829120, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
113
-{ "start": 127926272, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
114
-{ "start": 130023424, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
115
-{ "start": 132120576, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
116
-{ "start": 134217728, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
117
-{ "start": 136314880, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
118
-{ "start": 138412032, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
119
-{ "start": 140509184, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
120
-{ "start": 142606336, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
121
-{ "start": 144703488, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
122
-{ "start": 146800640, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
123
-{ "start": 148897792, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
124
-{ "start": 150994944, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
125
-{ "start": 153092096, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
126
-{ "start": 155189248, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
127
-{ "start": 157286400, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
128
-{ "start": 159383552, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
129
-{ "start": 161480704, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
130
-{ "start": 163577856, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
131
-{ "start": 165675008, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
132
-{ "start": 167772160, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
133
-{ "start": 169869312, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
134
-{ "start": 171966464, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
135
-{ "start": 174063616, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
136
-{ "start": 176160768, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
137
-{ "start": 178257920, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
138
-{ "start": 180355072, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
139
-{ "start": 182452224, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
140
-{ "start": 184549376, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
141
-{ "start": 186646528, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
142
-{ "start": 188743680, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
143
-{ "start": 190840832, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
144
-{ "start": 192937984, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
145
-{ "start": 195035136, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
146
-{ "start": 197132288, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
147
-{ "start": 199229440, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
148
-{ "start": 201326592, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
149
-{ "start": 203423744, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
150
-{ "start": 205520896, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
151
-{ "start": 207618048, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
152
-{ "start": 209715200, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
153
-{ "start": 211812352, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
154
-{ "start": 213909504, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
155
-{ "start": 216006656, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
156
-{ "start": 218103808, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
157
-{ "start": 220200960, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
158
-{ "start": 222298112, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
159
-{ "start": 224395264, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
160
-{ "start": 226492416, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
161
-{ "start": 228589568, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
162
-{ "start": 230686720, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
163
-{ "start": 232783872, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
164
-{ "start": 234881024, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
165
-{ "start": 236978176, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
166
-{ "start": 239075328, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
167
-{ "start": 241172480, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
168
-{ "start": 243269632, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
169
-{ "start": 245366784, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
170
-{ "start": 247463936, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
171
-{ "start": 249561088, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
172
-{ "start": 251658240, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
173
-{ "start": 253755392, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
174
-{ "start": 255852544, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
175
-{ "start": 257949696, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
176
-{ "start": 260046848, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
177
-{ "start": 262144000, "length": 1310720, "depth": 0, "zero": false, "data": true, "offset": OFFSET }]
178
+[{ "start": 0, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
179
+{ "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
180
+{ "start": 4194304, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
181
+{ "start": 6291456, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
182
+{ "start": 8388608, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
183
+{ "start": 10485760, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
184
+{ "start": 12582912, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
185
+{ "start": 14680064, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
186
+{ "start": 16777216, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
187
+{ "start": 18874368, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
188
+{ "start": 20971520, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
189
+{ "start": 23068672, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
190
+{ "start": 25165824, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
191
+{ "start": 27262976, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
192
+{ "start": 29360128, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
193
+{ "start": 31457280, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
194
+{ "start": 33554432, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
195
+{ "start": 35651584, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
196
+{ "start": 37748736, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
197
+{ "start": 39845888, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
198
+{ "start": 41943040, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
199
+{ "start": 44040192, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
200
+{ "start": 46137344, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
201
+{ "start": 48234496, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
202
+{ "start": 50331648, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
203
+{ "start": 52428800, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
204
+{ "start": 54525952, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
205
+{ "start": 56623104, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
206
+{ "start": 58720256, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
207
+{ "start": 60817408, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
208
+{ "start": 62914560, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
209
+{ "start": 65011712, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
210
+{ "start": 67108864, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
211
+{ "start": 69206016, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
212
+{ "start": 71303168, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
213
+{ "start": 73400320, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
214
+{ "start": 75497472, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
215
+{ "start": 77594624, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
216
+{ "start": 79691776, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
217
+{ "start": 81788928, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
218
+{ "start": 83886080, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
219
+{ "start": 85983232, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
220
+{ "start": 88080384, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
221
+{ "start": 90177536, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
222
+{ "start": 92274688, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
223
+{ "start": 94371840, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
224
+{ "start": 96468992, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
225
+{ "start": 98566144, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
226
+{ "start": 100663296, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
227
+{ "start": 102760448, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
228
+{ "start": 104857600, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
229
+{ "start": 106954752, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
230
+{ "start": 109051904, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
231
+{ "start": 111149056, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
232
+{ "start": 113246208, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
233
+{ "start": 115343360, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
234
+{ "start": 117440512, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
235
+{ "start": 119537664, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
236
+{ "start": 121634816, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
237
+{ "start": 123731968, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
238
+{ "start": 125829120, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
239
+{ "start": 127926272, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
240
+{ "start": 130023424, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
241
+{ "start": 132120576, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
242
+{ "start": 134217728, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
243
+{ "start": 136314880, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
244
+{ "start": 138412032, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
245
+{ "start": 140509184, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
246
+{ "start": 142606336, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
247
+{ "start": 144703488, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
248
+{ "start": 146800640, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
249
+{ "start": 148897792, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
250
+{ "start": 150994944, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
251
+{ "start": 153092096, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
252
+{ "start": 155189248, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
253
+{ "start": 157286400, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
254
+{ "start": 159383552, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
255
+{ "start": 161480704, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
256
+{ "start": 163577856, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
257
+{ "start": 165675008, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
258
+{ "start": 167772160, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
259
+{ "start": 169869312, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
260
+{ "start": 171966464, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
261
+{ "start": 174063616, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
262
+{ "start": 176160768, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
263
+{ "start": 178257920, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
264
+{ "start": 180355072, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
265
+{ "start": 182452224, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
266
+{ "start": 184549376, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
267
+{ "start": 186646528, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
268
+{ "start": 188743680, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
269
+{ "start": 190840832, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
270
+{ "start": 192937984, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
271
+{ "start": 195035136, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
272
+{ "start": 197132288, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
273
+{ "start": 199229440, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
274
+{ "start": 201326592, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
275
+{ "start": 203423744, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
276
+{ "start": 205520896, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
277
+{ "start": 207618048, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
278
+{ "start": 209715200, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
279
+{ "start": 211812352, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
280
+{ "start": 213909504, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
281
+{ "start": 216006656, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
282
+{ "start": 218103808, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
283
+{ "start": 220200960, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
284
+{ "start": 222298112, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
285
+{ "start": 224395264, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
286
+{ "start": 226492416, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
287
+{ "start": 228589568, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
288
+{ "start": 230686720, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
289
+{ "start": 232783872, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
290
+{ "start": 234881024, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
291
+{ "start": 236978176, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
292
+{ "start": 239075328, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
293
+{ "start": 241172480, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
294
+{ "start": 243269632, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
295
+{ "start": 245366784, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
296
+{ "start": 247463936, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
297
+{ "start": 249561088, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
298
+{ "start": 251658240, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
299
+{ "start": 253755392, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
300
+{ "start": 255852544, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
301
+{ "start": 257949696, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
302
+{ "start": 260046848, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
303
+{ "start": 262144000, "length": 1310720, "depth": 0, "zero": false, "data": true, "offset": OFFSET}]
304
305
=== Testing d2v with current_size force ===
306
307
-[{ "start": 0, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
308
-{ "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
309
-{ "start": 4194304, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
310
-{ "start": 6291456, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
311
-{ "start": 8388608, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
312
-{ "start": 10485760, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
313
-{ "start": 12582912, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
314
-{ "start": 14680064, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
315
-{ "start": 16777216, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
316
-{ "start": 18874368, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
317
-{ "start": 20971520, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
318
-{ "start": 23068672, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
319
-{ "start": 25165824, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
320
-{ "start": 27262976, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
321
-{ "start": 29360128, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
322
-{ "start": 31457280, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
323
-{ "start": 33554432, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
324
-{ "start": 35651584, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
325
-{ "start": 37748736, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
326
-{ "start": 39845888, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
327
-{ "start": 41943040, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
328
-{ "start": 44040192, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
329
-{ "start": 46137344, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
330
-{ "start": 48234496, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
331
-{ "start": 50331648, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
332
-{ "start": 52428800, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
333
-{ "start": 54525952, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
334
-{ "start": 56623104, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
335
-{ "start": 58720256, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
336
-{ "start": 60817408, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
337
-{ "start": 62914560, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
338
-{ "start": 65011712, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
339
-{ "start": 67108864, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
340
-{ "start": 69206016, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
341
-{ "start": 71303168, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
342
-{ "start": 73400320, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
343
-{ "start": 75497472, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
344
-{ "start": 77594624, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
345
-{ "start": 79691776, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
346
-{ "start": 81788928, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
347
-{ "start": 83886080, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
348
-{ "start": 85983232, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
349
-{ "start": 88080384, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
350
-{ "start": 90177536, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
351
-{ "start": 92274688, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
352
-{ "start": 94371840, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
353
-{ "start": 96468992, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
354
-{ "start": 98566144, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
355
-{ "start": 100663296, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
356
-{ "start": 102760448, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
357
-{ "start": 104857600, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
358
-{ "start": 106954752, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
359
-{ "start": 109051904, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
360
-{ "start": 111149056, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
361
-{ "start": 113246208, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
362
-{ "start": 115343360, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
363
-{ "start": 117440512, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
364
-{ "start": 119537664, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
365
-{ "start": 121634816, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
366
-{ "start": 123731968, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
367
-{ "start": 125829120, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
368
-{ "start": 127926272, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
369
-{ "start": 130023424, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
370
-{ "start": 132120576, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
371
-{ "start": 134217728, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
372
-{ "start": 136314880, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
373
-{ "start": 138412032, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
374
-{ "start": 140509184, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
375
-{ "start": 142606336, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
376
-{ "start": 144703488, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
377
-{ "start": 146800640, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
378
-{ "start": 148897792, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
379
-{ "start": 150994944, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
380
-{ "start": 153092096, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
381
-{ "start": 155189248, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
382
-{ "start": 157286400, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
383
-{ "start": 159383552, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
384
-{ "start": 161480704, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
385
-{ "start": 163577856, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
386
-{ "start": 165675008, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
387
-{ "start": 167772160, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
388
-{ "start": 169869312, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
389
-{ "start": 171966464, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
390
-{ "start": 174063616, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
391
-{ "start": 176160768, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
392
-{ "start": 178257920, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
393
-{ "start": 180355072, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
394
-{ "start": 182452224, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
395
-{ "start": 184549376, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
396
-{ "start": 186646528, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
397
-{ "start": 188743680, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
398
-{ "start": 190840832, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
399
-{ "start": 192937984, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
400
-{ "start": 195035136, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
401
-{ "start": 197132288, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
402
-{ "start": 199229440, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
403
-{ "start": 201326592, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
404
-{ "start": 203423744, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
405
-{ "start": 205520896, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
406
-{ "start": 207618048, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
407
-{ "start": 209715200, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
408
-{ "start": 211812352, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
409
-{ "start": 213909504, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
410
-{ "start": 216006656, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
411
-{ "start": 218103808, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
412
-{ "start": 220200960, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
413
-{ "start": 222298112, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
414
-{ "start": 224395264, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
415
-{ "start": 226492416, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
416
-{ "start": 228589568, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
417
-{ "start": 230686720, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
418
-{ "start": 232783872, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
419
-{ "start": 234881024, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
420
-{ "start": 236978176, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
421
-{ "start": 239075328, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
422
-{ "start": 241172480, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
423
-{ "start": 243269632, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
424
-{ "start": 245366784, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
425
-{ "start": 247463936, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
426
-{ "start": 249561088, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
427
-{ "start": 251658240, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
428
-{ "start": 253755392, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
429
-{ "start": 255852544, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
430
-{ "start": 257949696, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
431
-{ "start": 260046848, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
432
-{ "start": 262144000, "length": 1310720, "depth": 0, "zero": false, "data": true, "offset": OFFSET }]
433
+[{ "start": 0, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
434
+{ "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
435
+{ "start": 4194304, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
436
+{ "start": 6291456, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
437
+{ "start": 8388608, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
438
+{ "start": 10485760, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
439
+{ "start": 12582912, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
440
+{ "start": 14680064, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
441
+{ "start": 16777216, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
442
+{ "start": 18874368, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
443
+{ "start": 20971520, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
444
+{ "start": 23068672, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
445
+{ "start": 25165824, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
446
+{ "start": 27262976, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
447
+{ "start": 29360128, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
448
+{ "start": 31457280, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
449
+{ "start": 33554432, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
450
+{ "start": 35651584, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
451
+{ "start": 37748736, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
452
+{ "start": 39845888, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
453
+{ "start": 41943040, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
454
+{ "start": 44040192, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
455
+{ "start": 46137344, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
456
+{ "start": 48234496, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
457
+{ "start": 50331648, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
458
+{ "start": 52428800, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
459
+{ "start": 54525952, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
460
+{ "start": 56623104, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
461
+{ "start": 58720256, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
462
+{ "start": 60817408, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
463
+{ "start": 62914560, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
464
+{ "start": 65011712, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
465
+{ "start": 67108864, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
466
+{ "start": 69206016, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
467
+{ "start": 71303168, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
468
+{ "start": 73400320, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
469
+{ "start": 75497472, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
470
+{ "start": 77594624, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
471
+{ "start": 79691776, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
472
+{ "start": 81788928, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
473
+{ "start": 83886080, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
474
+{ "start": 85983232, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
475
+{ "start": 88080384, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
476
+{ "start": 90177536, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
477
+{ "start": 92274688, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
478
+{ "start": 94371840, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
479
+{ "start": 96468992, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
480
+{ "start": 98566144, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
481
+{ "start": 100663296, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
482
+{ "start": 102760448, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
483
+{ "start": 104857600, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
484
+{ "start": 106954752, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
485
+{ "start": 109051904, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
486
+{ "start": 111149056, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
487
+{ "start": 113246208, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
488
+{ "start": 115343360, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
489
+{ "start": 117440512, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
490
+{ "start": 119537664, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
491
+{ "start": 121634816, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
492
+{ "start": 123731968, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
493
+{ "start": 125829120, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
494
+{ "start": 127926272, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
495
+{ "start": 130023424, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
496
+{ "start": 132120576, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
497
+{ "start": 134217728, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
498
+{ "start": 136314880, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
499
+{ "start": 138412032, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
500
+{ "start": 140509184, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
501
+{ "start": 142606336, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
502
+{ "start": 144703488, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
503
+{ "start": 146800640, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
504
+{ "start": 148897792, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
505
+{ "start": 150994944, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
506
+{ "start": 153092096, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
507
+{ "start": 155189248, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
508
+{ "start": 157286400, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
509
+{ "start": 159383552, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
510
+{ "start": 161480704, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
511
+{ "start": 163577856, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
512
+{ "start": 165675008, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
513
+{ "start": 167772160, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
514
+{ "start": 169869312, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
515
+{ "start": 171966464, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
516
+{ "start": 174063616, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
517
+{ "start": 176160768, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
518
+{ "start": 178257920, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
519
+{ "start": 180355072, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
520
+{ "start": 182452224, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
521
+{ "start": 184549376, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
522
+{ "start": 186646528, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
523
+{ "start": 188743680, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
524
+{ "start": 190840832, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
525
+{ "start": 192937984, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
526
+{ "start": 195035136, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
527
+{ "start": 197132288, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
528
+{ "start": 199229440, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
529
+{ "start": 201326592, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
530
+{ "start": 203423744, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
531
+{ "start": 205520896, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
532
+{ "start": 207618048, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
533
+{ "start": 209715200, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
534
+{ "start": 211812352, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
535
+{ "start": 213909504, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
536
+{ "start": 216006656, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
537
+{ "start": 218103808, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
538
+{ "start": 220200960, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
539
+{ "start": 222298112, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
540
+{ "start": 224395264, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
541
+{ "start": 226492416, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
542
+{ "start": 228589568, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
543
+{ "start": 230686720, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
544
+{ "start": 232783872, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
545
+{ "start": 234881024, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
546
+{ "start": 236978176, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
547
+{ "start": 239075328, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
548
+{ "start": 241172480, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
549
+{ "start": 243269632, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
550
+{ "start": 245366784, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
551
+{ "start": 247463936, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
552
+{ "start": 249561088, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
553
+{ "start": 251658240, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
554
+{ "start": 253755392, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
555
+{ "start": 255852544, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
556
+{ "start": 257949696, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
557
+{ "start": 260046848, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
558
+{ "start": 262144000, "length": 1310720, "depth": 0, "zero": false, "data": true, "offset": OFFSET}]
559
560
=== Testing d2v with chs force ===
561
562
-[{ "start": 0, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
563
-{ "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
564
-{ "start": 4194304, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
565
-{ "start": 6291456, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
566
-{ "start": 8388608, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
567
-{ "start": 10485760, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
568
-{ "start": 12582912, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
569
-{ "start": 14680064, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
570
-{ "start": 16777216, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
571
-{ "start": 18874368, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
572
-{ "start": 20971520, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
573
-{ "start": 23068672, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
574
-{ "start": 25165824, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
575
-{ "start": 27262976, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
576
-{ "start": 29360128, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
577
-{ "start": 31457280, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
578
-{ "start": 33554432, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
579
-{ "start": 35651584, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
580
-{ "start": 37748736, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
581
-{ "start": 39845888, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
582
-{ "start": 41943040, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
583
-{ "start": 44040192, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
584
-{ "start": 46137344, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
585
-{ "start": 48234496, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
586
-{ "start": 50331648, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
587
-{ "start": 52428800, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
588
-{ "start": 54525952, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
589
-{ "start": 56623104, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
590
-{ "start": 58720256, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
591
-{ "start": 60817408, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
592
-{ "start": 62914560, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
593
-{ "start": 65011712, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
594
-{ "start": 67108864, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
595
-{ "start": 69206016, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
596
-{ "start": 71303168, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
597
-{ "start": 73400320, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
598
-{ "start": 75497472, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
599
-{ "start": 77594624, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
600
-{ "start": 79691776, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
601
-{ "start": 81788928, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
602
-{ "start": 83886080, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
603
-{ "start": 85983232, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
604
-{ "start": 88080384, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
605
-{ "start": 90177536, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
606
-{ "start": 92274688, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
607
-{ "start": 94371840, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
608
-{ "start": 96468992, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
609
-{ "start": 98566144, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
610
-{ "start": 100663296, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
611
-{ "start": 102760448, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
612
-{ "start": 104857600, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
613
-{ "start": 106954752, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
614
-{ "start": 109051904, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
615
-{ "start": 111149056, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
616
-{ "start": 113246208, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
617
-{ "start": 115343360, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
618
-{ "start": 117440512, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
619
-{ "start": 119537664, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
620
-{ "start": 121634816, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
621
-{ "start": 123731968, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
622
-{ "start": 125829120, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
623
-{ "start": 127926272, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
624
-{ "start": 130023424, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
625
-{ "start": 132120576, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
626
-{ "start": 134217728, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
627
-{ "start": 136314880, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
628
-{ "start": 138412032, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
629
-{ "start": 140509184, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
630
-{ "start": 142606336, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
631
-{ "start": 144703488, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
632
-{ "start": 146800640, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
633
-{ "start": 148897792, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
634
-{ "start": 150994944, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
635
-{ "start": 153092096, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
636
-{ "start": 155189248, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
637
-{ "start": 157286400, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
638
-{ "start": 159383552, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
639
-{ "start": 161480704, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
640
-{ "start": 163577856, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
641
-{ "start": 165675008, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
642
-{ "start": 167772160, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
643
-{ "start": 169869312, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
644
-{ "start": 171966464, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
645
-{ "start": 174063616, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
646
-{ "start": 176160768, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
647
-{ "start": 178257920, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
648
-{ "start": 180355072, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
649
-{ "start": 182452224, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
650
-{ "start": 184549376, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
651
-{ "start": 186646528, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
652
-{ "start": 188743680, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
653
-{ "start": 190840832, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
654
-{ "start": 192937984, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
655
-{ "start": 195035136, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
656
-{ "start": 197132288, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
657
-{ "start": 199229440, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
658
-{ "start": 201326592, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
659
-{ "start": 203423744, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
660
-{ "start": 205520896, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
661
-{ "start": 207618048, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
662
-{ "start": 209715200, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
663
-{ "start": 211812352, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
664
-{ "start": 213909504, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
665
-{ "start": 216006656, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
666
-{ "start": 218103808, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
667
-{ "start": 220200960, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
668
-{ "start": 222298112, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
669
-{ "start": 224395264, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
670
-{ "start": 226492416, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
671
-{ "start": 228589568, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
672
-{ "start": 230686720, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
673
-{ "start": 232783872, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
674
-{ "start": 234881024, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
675
-{ "start": 236978176, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
676
-{ "start": 239075328, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
677
-{ "start": 241172480, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
678
-{ "start": 243269632, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
679
-{ "start": 245366784, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
680
-{ "start": 247463936, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
681
-{ "start": 249561088, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
682
-{ "start": 251658240, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
683
-{ "start": 253755392, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
684
-{ "start": 255852544, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
685
-{ "start": 257949696, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
686
-{ "start": 260046848, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET },
687
-{ "start": 262144000, "length": 1310720, "depth": 0, "zero": false, "data": true, "offset": OFFSET }]
688
+[{ "start": 0, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
689
+{ "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
690
+{ "start": 4194304, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
691
+{ "start": 6291456, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
692
+{ "start": 8388608, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
693
+{ "start": 10485760, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
694
+{ "start": 12582912, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
695
+{ "start": 14680064, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
696
+{ "start": 16777216, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
697
+{ "start": 18874368, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
698
+{ "start": 20971520, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
699
+{ "start": 23068672, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
700
+{ "start": 25165824, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
701
+{ "start": 27262976, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
702
+{ "start": 29360128, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
703
+{ "start": 31457280, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
704
+{ "start": 33554432, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
705
+{ "start": 35651584, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
706
+{ "start": 37748736, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
707
+{ "start": 39845888, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
708
+{ "start": 41943040, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
709
+{ "start": 44040192, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
710
+{ "start": 46137344, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
711
+{ "start": 48234496, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
712
+{ "start": 50331648, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
713
+{ "start": 52428800, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
714
+{ "start": 54525952, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
715
+{ "start": 56623104, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
716
+{ "start": 58720256, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
717
+{ "start": 60817408, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
718
+{ "start": 62914560, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
719
+{ "start": 65011712, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
720
+{ "start": 67108864, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
721
+{ "start": 69206016, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
722
+{ "start": 71303168, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
723
+{ "start": 73400320, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
724
+{ "start": 75497472, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
725
+{ "start": 77594624, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
726
+{ "start": 79691776, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
727
+{ "start": 81788928, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
728
+{ "start": 83886080, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
729
+{ "start": 85983232, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
730
+{ "start": 88080384, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
731
+{ "start": 90177536, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
732
+{ "start": 92274688, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
733
+{ "start": 94371840, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
734
+{ "start": 96468992, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
735
+{ "start": 98566144, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
736
+{ "start": 100663296, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
737
+{ "start": 102760448, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
738
+{ "start": 104857600, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
739
+{ "start": 106954752, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
740
+{ "start": 109051904, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
741
+{ "start": 111149056, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
742
+{ "start": 113246208, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
743
+{ "start": 115343360, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
744
+{ "start": 117440512, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
745
+{ "start": 119537664, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
746
+{ "start": 121634816, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
747
+{ "start": 123731968, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
748
+{ "start": 125829120, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
749
+{ "start": 127926272, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
750
+{ "start": 130023424, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
751
+{ "start": 132120576, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
752
+{ "start": 134217728, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
753
+{ "start": 136314880, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
754
+{ "start": 138412032, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
755
+{ "start": 140509184, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
756
+{ "start": 142606336, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
757
+{ "start": 144703488, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
758
+{ "start": 146800640, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
759
+{ "start": 148897792, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
760
+{ "start": 150994944, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
761
+{ "start": 153092096, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
762
+{ "start": 155189248, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
763
+{ "start": 157286400, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
764
+{ "start": 159383552, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
765
+{ "start": 161480704, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
766
+{ "start": 163577856, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
767
+{ "start": 165675008, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
768
+{ "start": 167772160, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
769
+{ "start": 169869312, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
770
+{ "start": 171966464, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
771
+{ "start": 174063616, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
772
+{ "start": 176160768, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
773
+{ "start": 178257920, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
774
+{ "start": 180355072, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
775
+{ "start": 182452224, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
776
+{ "start": 184549376, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
777
+{ "start": 186646528, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
778
+{ "start": 188743680, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
779
+{ "start": 190840832, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
780
+{ "start": 192937984, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
781
+{ "start": 195035136, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
782
+{ "start": 197132288, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
783
+{ "start": 199229440, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
784
+{ "start": 201326592, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
785
+{ "start": 203423744, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
786
+{ "start": 205520896, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
787
+{ "start": 207618048, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
788
+{ "start": 209715200, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
789
+{ "start": 211812352, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
790
+{ "start": 213909504, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
791
+{ "start": 216006656, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
792
+{ "start": 218103808, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
793
+{ "start": 220200960, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
794
+{ "start": 222298112, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
795
+{ "start": 224395264, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
796
+{ "start": 226492416, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
797
+{ "start": 228589568, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
798
+{ "start": 230686720, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
799
+{ "start": 232783872, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
800
+{ "start": 234881024, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
801
+{ "start": 236978176, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
802
+{ "start": 239075328, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
803
+{ "start": 241172480, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
804
+{ "start": 243269632, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
805
+{ "start": 245366784, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
806
+{ "start": 247463936, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
807
+{ "start": 249561088, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
808
+{ "start": 251658240, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
809
+{ "start": 253755392, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
810
+{ "start": 255852544, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
811
+{ "start": 257949696, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
812
+{ "start": 260046848, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
813
+{ "start": 262144000, "length": 1310720, "depth": 0, "zero": false, "data": true, "offset": OFFSET}]
814
815
=== Testing Image create, default ===
816
817
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/IMGFMT-create-test.IMGFMT', fmt=IMGFMT size=4294967296
818
819
=== Read created image, default opts ====
820
821
-[{ "start": 0, "length": 4295467008, "depth": 0, "zero": true, "data": false }]
822
+[{ "start": 0, "length": 4295467008, "depth": 0, "zero": true, "data": false}]
823
824
=== Read created image, force_size_calc=chs ====
825
826
-[{ "start": 0, "length": 4295467008, "depth": 0, "zero": true, "data": false }]
827
+[{ "start": 0, "length": 4295467008, "depth": 0, "zero": true, "data": false}]
828
829
=== Read created image, force_size_calc=current_size ====
830
831
-[{ "start": 0, "length": 4295467008, "depth": 0, "zero": true, "data": false }]
832
+[{ "start": 0, "length": 4295467008, "depth": 0, "zero": true, "data": false}]
833
834
=== Testing Image create, force_size ===
835
836
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/IMGFMT-create-test.IMGFMT', fmt=IMGFMT size=4294967296
837
838
=== Read created image, default opts ====
839
840
-[{ "start": 0, "length": 4294967296, "depth": 0, "zero": true, "data": false }]
841
+[{ "start": 0, "length": 4294967296, "depth": 0, "zero": true, "data": false}]
842
843
=== Read created image, force_size_calc=chs ====
844
845
-[{ "start": 0, "length": 4294967296, "depth": 0, "zero": true, "data": false }]
846
+[{ "start": 0, "length": 4294967296, "depth": 0, "zero": true, "data": false}]
847
848
=== Read created image, force_size_calc=current_size ====
849
850
-[{ "start": 0, "length": 4294967296, "depth": 0, "zero": true, "data": false }]
851
+[{ "start": 0, "length": 4294967296, "depth": 0, "zero": true, "data": false}]
852
*** done
31
--
853
--
32
2.25.3
854
2.29.2
33
855
34
856
diff view generated by jsdifflib
Deleted patch
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
1
3
Test 244 checks the expected behavior of qcow2 external data files
4
with respect to zero and discarded clusters. Filesystems however
5
are free to ignore discard requests, and this seems to be the
6
case for overlayfs. Relax the tests to skip checks on the
7
external data file for discarded areas, which implies not using
8
qemu-img compare in the data_file_raw=on case.
9
10
This fixes docker tests on RHEL8.
11
12
Cc: Kevin Wolf <kwolf@redhat.com>
13
Cc: qemu-block@nongnu.org
14
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
15
Message-Id: <20200409191006.24429-1-pbonzini@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
---
18
tests/qemu-iotests/244 | 10 ++++++++--
19
tests/qemu-iotests/244.out | 9 ++++++---
20
2 files changed, 14 insertions(+), 5 deletions(-)
21
22
diff --git a/tests/qemu-iotests/244 b/tests/qemu-iotests/244
23
index XXXXXXX..XXXXXXX 100755
24
--- a/tests/qemu-iotests/244
25
+++ b/tests/qemu-iotests/244
26
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c 'read -P 0 0 1M' \
27
echo
28
$QEMU_IO -c 'read -P 0 0 1M' \
29
-c 'read -P 0x11 1M 1M' \
30
- -c 'read -P 0 2M 2M' \
31
-c 'read -P 0x11 4M 1M' \
32
-c 'read -P 0 5M 1M' \
33
-f raw "$TEST_IMG.data" |
34
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c 'read -P 0 0 1M' \
35
-f $IMGFMT "$TEST_IMG" |
36
_filter_qemu_io
37
38
+# Discarded clusters are only marked as such in the qcow2 metadata, but
39
+# they can contain stale data in the external data file. Instead, zero
40
+# clusters must be zeroed in the external data file too.
41
echo
42
-$QEMU_IMG compare "$TEST_IMG" "$TEST_IMG.data"
43
+$QEMU_IO -c 'read -P 0 0 1M' \
44
+ -c 'read -P 0x11 1M 1M' \
45
+ -c 'read -P 0 3M 3M' \
46
+ -f raw "$TEST_IMG".data |
47
+ _filter_qemu_io
48
49
echo -n "qcow2 file size after I/O: "
50
du -b $TEST_IMG | cut -f1
51
diff --git a/tests/qemu-iotests/244.out b/tests/qemu-iotests/244.out
52
index XXXXXXX..XXXXXXX 100644
53
--- a/tests/qemu-iotests/244.out
54
+++ b/tests/qemu-iotests/244.out
55
@@ -XXX,XX +XXX,XX @@ read 1048576/1048576 bytes at offset 0
56
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
57
read 1048576/1048576 bytes at offset 1048576
58
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
59
-read 2097152/2097152 bytes at offset 2097152
60
-2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
61
read 1048576/1048576 bytes at offset 4194304
62
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
63
read 1048576/1048576 bytes at offset 5242880
64
@@ -XXX,XX +XXX,XX @@ read 1048576/1048576 bytes at offset 1048576
65
read 4194304/4194304 bytes at offset 2097152
66
4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
67
68
-Images are identical.
69
+read 1048576/1048576 bytes at offset 0
70
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
71
+read 1048576/1048576 bytes at offset 1048576
72
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
73
+read 3145728/3145728 bytes at offset 3145728
74
+3 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
75
qcow2 file size after I/O: 327680
76
77
=== bdrv_co_block_status test for file and offset=0 ===
78
--
79
2.25.3
80
81
diff view generated by jsdifflib
Deleted patch
1
This adds a new BdrvRequestFlags parameter to the .bdrv_co_truncate()
2
driver callbacks, and a supported_truncate_flags field in
3
BlockDriverState that allows drivers to advertise support for request
4
flags in the context of truncate.
5
1
6
For now, we always pass 0 and no drivers declare support for any flag.
7
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Reviewed-by: Alberto Garcia <berto@igalia.com>
11
Reviewed-by: Max Reitz <mreitz@redhat.com>
12
Message-Id: <20200424125448.63318-2-kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
15
include/block/block_int.h | 10 +++++++++-
16
block/crypto.c | 3 ++-
17
block/file-posix.c | 2 +-
18
block/file-win32.c | 2 +-
19
block/gluster.c | 1 +
20
block/io.c | 8 +++++++-
21
block/iscsi.c | 2 +-
22
block/nfs.c | 3 ++-
23
block/qcow2.c | 2 +-
24
block/qed.c | 1 +
25
block/raw-format.c | 2 +-
26
block/rbd.c | 1 +
27
block/sheepdog.c | 4 ++--
28
block/ssh.c | 2 +-
29
tests/test-block-iothread.c | 3 ++-
30
15 files changed, 33 insertions(+), 13 deletions(-)
31
32
diff --git a/include/block/block_int.h b/include/block/block_int.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/include/block/block_int.h
35
+++ b/include/block/block_int.h
36
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
37
*/
38
int coroutine_fn (*bdrv_co_truncate)(BlockDriverState *bs, int64_t offset,
39
bool exact, PreallocMode prealloc,
40
- Error **errp);
41
+ BdrvRequestFlags flags, Error **errp);
42
43
int64_t (*bdrv_getlength)(BlockDriverState *bs);
44
bool has_variable_length;
45
@@ -XXX,XX +XXX,XX @@ struct BlockDriverState {
46
/* Flags honored during pwrite_zeroes (so far: BDRV_REQ_FUA,
47
* BDRV_REQ_MAY_UNMAP, BDRV_REQ_WRITE_UNCHANGED) */
48
unsigned int supported_zero_flags;
49
+ /*
50
+ * Flags honoured during truncate (so far: BDRV_REQ_ZERO_WRITE).
51
+ *
52
+ * If BDRV_REQ_ZERO_WRITE is given, the truncate operation must make sure
53
+ * that any added space reads as all zeros. If this can't be guaranteed,
54
+ * the operation must fail.
55
+ */
56
+ unsigned int supported_truncate_flags;
57
58
/* the following member gives a name to every node on the bs graph. */
59
char node_name[32];
60
diff --git a/block/crypto.c b/block/crypto.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/block/crypto.c
63
+++ b/block/crypto.c
64
@@ -XXX,XX +XXX,XX @@ static int block_crypto_co_create_generic(BlockDriverState *bs,
65
66
static int coroutine_fn
67
block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
68
- PreallocMode prealloc, Error **errp)
69
+ PreallocMode prealloc, BdrvRequestFlags flags,
70
+ Error **errp)
71
{
72
BlockCrypto *crypto = bs->opaque;
73
uint64_t payload_offset =
74
diff --git a/block/file-posix.c b/block/file-posix.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/block/file-posix.c
77
+++ b/block/file-posix.c
78
@@ -XXX,XX +XXX,XX @@ raw_regular_truncate(BlockDriverState *bs, int fd, int64_t offset,
79
80
static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
81
bool exact, PreallocMode prealloc,
82
- Error **errp)
83
+ BdrvRequestFlags flags, Error **errp)
84
{
85
BDRVRawState *s = bs->opaque;
86
struct stat st;
87
diff --git a/block/file-win32.c b/block/file-win32.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/block/file-win32.c
90
+++ b/block/file-win32.c
91
@@ -XXX,XX +XXX,XX @@ static void raw_close(BlockDriverState *bs)
92
93
static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
94
bool exact, PreallocMode prealloc,
95
- Error **errp)
96
+ BdrvRequestFlags flags, Error **errp)
97
{
98
BDRVRawState *s = bs->opaque;
99
LONG low, high;
100
diff --git a/block/gluster.c b/block/gluster.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/block/gluster.c
103
+++ b/block/gluster.c
104
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qemu_gluster_co_truncate(BlockDriverState *bs,
105
int64_t offset,
106
bool exact,
107
PreallocMode prealloc,
108
+ BdrvRequestFlags flags,
109
Error **errp)
110
{
111
BDRVGlusterState *s = bs->opaque;
112
diff --git a/block/io.c b/block/io.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/block/io.c
115
+++ b/block/io.c
116
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
117
BlockDriverState *bs = child->bs;
118
BlockDriver *drv = bs->drv;
119
BdrvTrackedRequest req;
120
+ BdrvRequestFlags flags = 0;
121
int64_t old_size, new_bytes;
122
int ret;
123
124
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
125
}
126
127
if (drv->bdrv_co_truncate) {
128
- ret = drv->bdrv_co_truncate(bs, offset, exact, prealloc, errp);
129
+ if (flags & ~bs->supported_truncate_flags) {
130
+ error_setg(errp, "Block driver does not support requested flags");
131
+ ret = -ENOTSUP;
132
+ goto out;
133
+ }
134
+ ret = drv->bdrv_co_truncate(bs, offset, exact, prealloc, flags, errp);
135
} else if (bs->file && drv->is_filter) {
136
ret = bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
137
} else {
138
diff --git a/block/iscsi.c b/block/iscsi.c
139
index XXXXXXX..XXXXXXX 100644
140
--- a/block/iscsi.c
141
+++ b/block/iscsi.c
142
@@ -XXX,XX +XXX,XX @@ static void iscsi_reopen_commit(BDRVReopenState *reopen_state)
143
144
static int coroutine_fn iscsi_co_truncate(BlockDriverState *bs, int64_t offset,
145
bool exact, PreallocMode prealloc,
146
- Error **errp)
147
+ BdrvRequestFlags flags, Error **errp)
148
{
149
IscsiLun *iscsilun = bs->opaque;
150
int64_t cur_length;
151
diff --git a/block/nfs.c b/block/nfs.c
152
index XXXXXXX..XXXXXXX 100644
153
--- a/block/nfs.c
154
+++ b/block/nfs.c
155
@@ -XXX,XX +XXX,XX @@ static int64_t nfs_get_allocated_file_size(BlockDriverState *bs)
156
157
static int coroutine_fn
158
nfs_file_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
159
- PreallocMode prealloc, Error **errp)
160
+ PreallocMode prealloc, BdrvRequestFlags flags,
161
+ Error **errp)
162
{
163
NFSClient *client = bs->opaque;
164
int ret;
165
diff --git a/block/qcow2.c b/block/qcow2.c
166
index XXXXXXX..XXXXXXX 100644
167
--- a/block/qcow2.c
168
+++ b/block/qcow2.c
169
@@ -XXX,XX +XXX,XX @@ fail:
170
171
static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
172
bool exact, PreallocMode prealloc,
173
- Error **errp)
174
+ BdrvRequestFlags flags, Error **errp)
175
{
176
BDRVQcow2State *s = bs->opaque;
177
uint64_t old_length;
178
diff --git a/block/qed.c b/block/qed.c
179
index XXXXXXX..XXXXXXX 100644
180
--- a/block/qed.c
181
+++ b/block/qed.c
182
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_truncate(BlockDriverState *bs,
183
int64_t offset,
184
bool exact,
185
PreallocMode prealloc,
186
+ BdrvRequestFlags flags,
187
Error **errp)
188
{
189
BDRVQEDState *s = bs->opaque;
190
diff --git a/block/raw-format.c b/block/raw-format.c
191
index XXXXXXX..XXXXXXX 100644
192
--- a/block/raw-format.c
193
+++ b/block/raw-format.c
194
@@ -XXX,XX +XXX,XX @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
195
196
static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
197
bool exact, PreallocMode prealloc,
198
- Error **errp)
199
+ BdrvRequestFlags flags, Error **errp)
200
{
201
BDRVRawState *s = bs->opaque;
202
203
diff --git a/block/rbd.c b/block/rbd.c
204
index XXXXXXX..XXXXXXX 100644
205
--- a/block/rbd.c
206
+++ b/block/rbd.c
207
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qemu_rbd_co_truncate(BlockDriverState *bs,
208
int64_t offset,
209
bool exact,
210
PreallocMode prealloc,
211
+ BdrvRequestFlags flags,
212
Error **errp)
213
{
214
int r;
215
diff --git a/block/sheepdog.c b/block/sheepdog.c
216
index XXXXXXX..XXXXXXX 100644
217
--- a/block/sheepdog.c
218
+++ b/block/sheepdog.c
219
@@ -XXX,XX +XXX,XX @@ static int64_t sd_getlength(BlockDriverState *bs)
220
221
static int coroutine_fn sd_co_truncate(BlockDriverState *bs, int64_t offset,
222
bool exact, PreallocMode prealloc,
223
- Error **errp)
224
+ BdrvRequestFlags flags, Error **errp)
225
{
226
BDRVSheepdogState *s = bs->opaque;
227
int ret, fd;
228
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int sd_co_writev(BlockDriverState *bs, int64_t sector_num,
229
230
assert(!flags);
231
if (offset > s->inode.vdi_size) {
232
- ret = sd_co_truncate(bs, offset, false, PREALLOC_MODE_OFF, NULL);
233
+ ret = sd_co_truncate(bs, offset, false, PREALLOC_MODE_OFF, 0, NULL);
234
if (ret < 0) {
235
return ret;
236
}
237
diff --git a/block/ssh.c b/block/ssh.c
238
index XXXXXXX..XXXXXXX 100644
239
--- a/block/ssh.c
240
+++ b/block/ssh.c
241
@@ -XXX,XX +XXX,XX @@ static int64_t ssh_getlength(BlockDriverState *bs)
242
243
static int coroutine_fn ssh_co_truncate(BlockDriverState *bs, int64_t offset,
244
bool exact, PreallocMode prealloc,
245
- Error **errp)
246
+ BdrvRequestFlags flags, Error **errp)
247
{
248
BDRVSSHState *s = bs->opaque;
249
250
diff --git a/tests/test-block-iothread.c b/tests/test-block-iothread.c
251
index XXXXXXX..XXXXXXX 100644
252
--- a/tests/test-block-iothread.c
253
+++ b/tests/test-block-iothread.c
254
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_test_co_pdiscard(BlockDriverState *bs,
255
256
static int coroutine_fn
257
bdrv_test_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
258
- PreallocMode prealloc, Error **errp)
259
+ PreallocMode prealloc, BdrvRequestFlags flags,
260
+ Error **errp)
261
{
262
return 0;
263
}
264
--
265
2.25.3
266
267
diff view generated by jsdifflib
Deleted patch
1
If BDRV_REQ_ZERO_WRITE is set and we're extending the image, calling
2
qcow2_cluster_zeroize() with flags=0 does the right thing: It doesn't
3
undo any previous preallocation, but just adds the zero flag to all
4
relevant L2 entries. If an external data file is in use, a write_zeroes
5
request to the data file is made instead.
6
1
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Message-Id: <20200424125448.63318-5-kwolf@redhat.com>
9
Reviewed-by: Eric Blake <eblake@redhat.com>
10
Reviewed-by: Max Reitz <mreitz@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
13
block/qcow2-cluster.c | 2 +-
14
block/qcow2.c | 34 ++++++++++++++++++++++++++++++++++
15
2 files changed, 35 insertions(+), 1 deletion(-)
16
17
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block/qcow2-cluster.c
20
+++ b/block/qcow2-cluster.c
21
@@ -XXX,XX +XXX,XX @@ int qcow2_cluster_zeroize(BlockDriverState *bs, uint64_t offset,
22
/* Caller must pass aligned values, except at image end */
23
assert(QEMU_IS_ALIGNED(offset, s->cluster_size));
24
assert(QEMU_IS_ALIGNED(end_offset, s->cluster_size) ||
25
- end_offset == bs->total_sectors << BDRV_SECTOR_BITS);
26
+ end_offset >= bs->total_sectors << BDRV_SECTOR_BITS);
27
28
/* The zero flag is only supported by version 3 and newer */
29
if (s->qcow_version < 3) {
30
diff --git a/block/qcow2.c b/block/qcow2.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/block/qcow2.c
33
+++ b/block/qcow2.c
34
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
35
36
bs->supported_zero_flags = header.version >= 3 ?
37
BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK : 0;
38
+ bs->supported_truncate_flags = BDRV_REQ_ZERO_WRITE;
39
40
/* Repair image if dirty */
41
if (!(flags & (BDRV_O_CHECK | BDRV_O_INACTIVE)) && !bs->read_only &&
42
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
43
g_assert_not_reached();
44
}
45
46
+ if ((flags & BDRV_REQ_ZERO_WRITE) && offset > old_length) {
47
+ uint64_t zero_start = QEMU_ALIGN_UP(old_length, s->cluster_size);
48
+
49
+ /*
50
+ * Use zero clusters as much as we can. qcow2_cluster_zeroize()
51
+ * requires a cluster-aligned start. The end may be unaligned if it is
52
+ * at the end of the image (which it is here).
53
+ */
54
+ ret = qcow2_cluster_zeroize(bs, zero_start, offset - zero_start, 0);
55
+ if (ret < 0) {
56
+ error_setg_errno(errp, -ret, "Failed to zero out new clusters");
57
+ goto fail;
58
+ }
59
+
60
+ /* Write explicit zeros for the unaligned head */
61
+ if (zero_start > old_length) {
62
+ uint64_t len = zero_start - old_length;
63
+ uint8_t *buf = qemu_blockalign0(bs, len);
64
+ QEMUIOVector qiov;
65
+ qemu_iovec_init_buf(&qiov, buf, len);
66
+
67
+ qemu_co_mutex_unlock(&s->lock);
68
+ ret = qcow2_co_pwritev_part(bs, old_length, len, &qiov, 0, 0);
69
+ qemu_co_mutex_lock(&s->lock);
70
+
71
+ qemu_vfree(buf);
72
+ if (ret < 0) {
73
+ error_setg_errno(errp, -ret, "Failed to zero out the new area");
74
+ goto fail;
75
+ }
76
+ }
77
+ }
78
+
79
if (prealloc != PREALLOC_MODE_OFF) {
80
/* Flush metadata before actually changing the image size */
81
ret = qcow2_write_caches(bs);
82
--
83
2.25.3
84
85
diff view generated by jsdifflib
Deleted patch
1
The raw format driver can simply forward the flag and let its bs->file
2
child take care of actually providing the zeros.
3
1
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Max Reitz <mreitz@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
7
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Message-Id: <20200424125448.63318-6-kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
block/raw-format.c | 4 +++-
12
1 file changed, 3 insertions(+), 1 deletion(-)
13
14
diff --git a/block/raw-format.c b/block/raw-format.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/block/raw-format.c
17
+++ b/block/raw-format.c
18
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
19
20
s->size = offset;
21
offset += s->offset;
22
- return bdrv_co_truncate(bs->file, offset, exact, prealloc, 0, errp);
23
+ return bdrv_co_truncate(bs->file, offset, exact, prealloc, flags, errp);
24
}
25
26
static void raw_eject(BlockDriverState *bs, bool eject_flag)
27
@@ -XXX,XX +XXX,XX @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
28
bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
29
((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) &
30
bs->file->bs->supported_zero_flags);
31
+ bs->supported_truncate_flags = bs->file->bs->supported_truncate_flags &
32
+ BDRV_REQ_ZERO_WRITE;
33
34
if (bs->probed && !bdrv_is_read_only(bs)) {
35
bdrv_refresh_filename(bs->file->bs);
36
--
37
2.25.3
38
39
diff view generated by jsdifflib
Deleted patch
1
For regular files, we always get BDRV_REQ_ZERO_WRITE behaviour from the
2
OS, so we can advertise the flag and just ignore it.
3
1
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
Reviewed-by: Alberto Garcia <berto@igalia.com>
7
Reviewed-by: Max Reitz <mreitz@redhat.com>
8
Message-Id: <20200424125448.63318-7-kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
block/file-posix.c | 4 ++++
12
1 file changed, 4 insertions(+)
13
14
diff --git a/block/file-posix.c b/block/file-posix.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/block/file-posix.c
17
+++ b/block/file-posix.c
18
@@ -XXX,XX +XXX,XX @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
19
#endif
20
21
bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK;
22
+ if (S_ISREG(st.st_mode)) {
23
+ /* When extending regular files, we get zeros from the OS */
24
+ bs->supported_truncate_flags = BDRV_REQ_ZERO_WRITE;
25
+ }
26
ret = 0;
27
fail:
28
if (filename && (bdrv_flags & BDRV_O_TEMPORARY)) {
29
--
30
2.25.3
31
32
diff view generated by jsdifflib
Deleted patch
1
When extending the size of an image that has a backing file larger than
2
its old size, make sure that the backing file data doesn't become
3
visible in the guest, but the added area is properly zeroed out.
4
1
5
Consider the following scenario where the overlay is shorter than its
6
backing file:
7
8
base.qcow2: AAAAAAAA
9
overlay.qcow2: BBBB
10
11
When resizing (extending) overlay.qcow2, the new blocks should not stay
12
unallocated and make the additional As from base.qcow2 visible like
13
before this patch, but zeros should be read.
14
15
A similar case happens with the various variants of a commit job when an
16
intermediate file is short (- for unallocated):
17
18
base.qcow2: A-A-AAAA
19
mid.qcow2: BB-B
20
top.qcow2: C--C--C-
21
22
After commit top.qcow2 to mid.qcow2, the following happens:
23
24
mid.qcow2: CB-C00C0 (correct result)
25
mid.qcow2: CB-C--C- (before this fix)
26
27
Without the fix, blocks that previously read as zeros on top.qcow2
28
suddenly turn into A.
29
30
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
31
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
32
Message-Id: <20200424125448.63318-8-kwolf@redhat.com>
33
Reviewed-by: Max Reitz <mreitz@redhat.com>
34
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
35
---
36
block/io.c | 25 +++++++++++++++++++++++++
37
1 file changed, 25 insertions(+)
38
39
diff --git a/block/io.c b/block/io.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/block/io.c
42
+++ b/block/io.c
43
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
44
goto out;
45
}
46
47
+ /*
48
+ * If the image has a backing file that is large enough that it would
49
+ * provide data for the new area, we cannot leave it unallocated because
50
+ * then the backing file content would become visible. Instead, zero-fill
51
+ * the new area.
52
+ *
53
+ * Note that if the image has a backing file, but was opened without the
54
+ * backing file, taking care of keeping things consistent with that backing
55
+ * file is the user's responsibility.
56
+ */
57
+ if (new_bytes && bs->backing) {
58
+ int64_t backing_len;
59
+
60
+ backing_len = bdrv_getlength(backing_bs(bs));
61
+ if (backing_len < 0) {
62
+ ret = backing_len;
63
+ error_setg_errno(errp, -ret, "Could not get backing file size");
64
+ goto out;
65
+ }
66
+
67
+ if (backing_len > old_size) {
68
+ flags |= BDRV_REQ_ZERO_WRITE;
69
+ }
70
+ }
71
+
72
if (drv->bdrv_co_truncate) {
73
if (flags & ~bs->supported_truncate_flags) {
74
error_setg(errp, "Block driver does not support requested flags");
75
--
76
2.25.3
77
78
diff view generated by jsdifflib
1
After processing the option string with the keyval parser, we get a
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
QDict that contains only strings. This QDict must be fed to a keyval
2
3
visitor which converts the strings into the right data types.
3
Add python script with new logic of searching for tests:
4
4
5
qmp_object_add(), however, uses the normal QObject input visitor, which
5
Current ./check behavior:
6
expects a QDict where all properties already have the QType that matches
6
- tests are named [0-9][0-9][0-9]
7
the data type required by the QOM object type.
7
- tests must be registered in group file (even if test doesn't belong
8
8
to any group, like 142)
9
Change the --object implementation in qemu-storage-daemon so that it
9
10
doesn't call qmp_object_add(), but calls user_creatable_add_dict()
10
Behavior of findtests.py:
11
directly instead and pass it a new keyval boolean that decides which
11
- group file is dropped
12
visitor must be used.
12
- tests are all files in tests/ subdirectory (except for .out files),
13
13
so it's not needed more to "register the test", just create it with
14
Reported-by: Coiby Xu <coiby.xu@gmail.com>
14
appropriate name in tests/ subdirectory. Old names like
15
[0-9][0-9][0-9] (in root iotests directory) are supported too, but
16
not recommended for new tests
17
- groups are parsed from '# group: ' line inside test files
18
- optional file group.local may be used to define some additional
19
groups for downstreams
20
- 'disabled' group is used to temporary disable tests. So instead of
21
commenting tests in old 'group' file you now can add them to
22
disabled group with help of 'group.local' file
23
- selecting test ranges like 5-15 are not supported more
24
(to support restarting failed ./check command from the middle of the
25
process, new argument is added: --start-from)
26
27
Benefits:
28
- no rebase conflicts in group file on patch porting from branch to
29
branch
30
- no conflicts in upstream, when different series want to occupy same
31
test number
32
- meaningful names for test files
33
For example, with digital number, when some person wants to add some
34
test about block-stream, he most probably will just create a new
35
test. But if there would be test-block-stream test already, he will
36
at first look at it and may be just add a test-case into it.
37
And anyway meaningful names are better.
38
39
This commit doesn't update check behavior (which will be done in
40
further commit), still, the documentation changed like new behavior is
41
already here. Let's live with this small inconsistency for the
42
following few commits, until final change.
43
44
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
45
Reviewed-by: Eric Blake <eblake@redhat.com>
46
Message-Id: <20210125185056.129513-3-vsementsov@virtuozzo.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
47
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
---
48
---
17
include/qom/object_interfaces.h | 6 +++++-
49
docs/devel/testing.rst | 50 +++++++++-
18
qemu-storage-daemon.c | 4 +---
50
tests/qemu-iotests/findtests.py | 159 ++++++++++++++++++++++++++++++++
19
qom/object_interfaces.c | 8 ++++++--
51
2 files changed, 208 insertions(+), 1 deletion(-)
20
qom/qom-qmp-cmds.c | 2 +-
52
create mode 100644 tests/qemu-iotests/findtests.py
21
4 files changed, 13 insertions(+), 7 deletions(-)
53
22
54
diff --git a/docs/devel/testing.rst b/docs/devel/testing.rst
23
diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
24
index XXXXXXX..XXXXXXX 100644
55
index XXXXXXX..XXXXXXX 100644
25
--- a/include/qom/object_interfaces.h
56
--- a/docs/devel/testing.rst
26
+++ b/include/qom/object_interfaces.h
57
+++ b/docs/devel/testing.rst
27
@@ -XXX,XX +XXX,XX @@ Object *user_creatable_add_type(const char *type, const char *id,
58
@@ -XXX,XX +XXX,XX @@ check-block
28
/**
59
-----------
29
* user_creatable_add_dict:
60
30
* @qdict: the object definition
61
``make check-block`` runs a subset of the block layer iotests (the tests that
31
+ * @keyval: if true, use a keyval visitor for processing @qdict (i.e.
62
-are in the "auto" group in ``tests/qemu-iotests/group``).
32
+ * assume that all @qdict values are strings); otherwise, use
63
+are in the "auto" group).
33
+ * the normal QObject visitor (i.e. assume all @qdict values
64
See the "QEMU iotests" section below for more information.
34
+ * have the QType expected by the QOM object type)
65
35
* @errp: if an error occurs, a pointer to an area to store the error
66
GCC gcov support
36
*
67
@@ -XXX,XX +XXX,XX @@ another application on the host may have locked the file, possibly leading to a
37
* Create an instance of the user creatable object that is defined by
68
test failure. If using such devices are explicitly desired, consider adding
38
@@ -XXX,XX +XXX,XX @@ Object *user_creatable_add_type(const char *type, const char *id,
69
``locking=off`` option to disable image locking.
39
* ID from the key 'id'. The remaining entries in @qdict are used to
70
40
* initialize the object properties.
71
+Test case groups
41
*/
72
+----------------
42
-void user_creatable_add_dict(QDict *qdict, Error **errp);
73
+
43
+void user_creatable_add_dict(QDict *qdict, bool keyval, Error **errp);
74
+"Tests may belong to one or more test groups, which are defined in the form
44
75
+of a comment in the test source file. By convention, test groups are listed
45
/**
76
+in the second line of the test file, after the "#!/..." line, like this:
46
* user_creatable_add_opts:
77
+
47
diff --git a/qemu-storage-daemon.c b/qemu-storage-daemon.c
78
+.. code::
48
index XXXXXXX..XXXXXXX 100644
79
+
49
--- a/qemu-storage-daemon.c
80
+ #!/usr/bin/env python3
50
+++ b/qemu-storage-daemon.c
81
+ # group: auto quick
51
@@ -XXX,XX +XXX,XX @@ static void process_options(int argc, char *argv[])
82
+ #
52
QemuOpts *opts;
83
+ ...
53
const char *type;
84
+
54
QDict *args;
85
+Another way of defining groups is creating the tests/qemu-iotests/group.local
55
- QObject *ret_data = NULL;
86
+file. This should be used only for downstream (this file should never appear
56
87
+in upstream). This file may be used for defining some downstream test groups
57
/* FIXME The keyval parser rejects 'help' arguments, so we must
88
+or for temporarily disabling tests, like this:
58
* unconditionall try QemuOpts first. */
89
+
59
@@ -XXX,XX +XXX,XX @@ static void process_options(int argc, char *argv[])
90
+.. code::
60
qemu_opts_del(opts);
91
+
61
92
+ # groups for some company downstream process
62
args = keyval_parse(optarg, "qom-type", &error_fatal);
93
+ #
63
- qmp_object_add(args, &ret_data, &error_fatal);
94
+ # ci - tests to run on build
64
+ user_creatable_add_dict(args, true, &error_fatal);
95
+ # down - our downstream tests, not for upstream
65
qobject_unref(args);
96
+ #
66
- qobject_unref(ret_data);
97
+ # Format of each line is:
67
break;
98
+ # TEST_NAME TEST_GROUP [TEST_GROUP ]...
68
}
99
+
69
default:
100
+ 013 ci
70
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
101
+ 210 disabled
71
index XXXXXXX..XXXXXXX 100644
102
+ 215 disabled
72
--- a/qom/object_interfaces.c
103
+ our-ugly-workaround-test down ci
73
+++ b/qom/object_interfaces.c
104
+
74
@@ -XXX,XX +XXX,XX @@ out:
105
+Note that the following group names have a special meaning:
75
return obj;
106
+
76
}
107
+- quick: Tests in this group should finish within a few seconds.
77
108
+
78
-void user_creatable_add_dict(QDict *qdict, Error **errp)
109
+- auto: Tests in this group are used during "make check" and should be
79
+void user_creatable_add_dict(QDict *qdict, bool keyval, Error **errp)
110
+ runnable in any case. That means they should run with every QEMU binary
80
{
111
+ (also non-x86), with every QEMU configuration (i.e. must not fail if
81
Visitor *v;
112
+ an optional feature is not compiled in - but reporting a "skip" is ok),
82
Object *obj;
113
+ work at least with the qcow2 file format, work with all kind of host
83
@@ -XXX,XX +XXX,XX @@ void user_creatable_add_dict(QDict *qdict, Error **errp)
114
+ filesystems and users (e.g. "nobody" or "root") and must not take too
84
}
115
+ much memory and disk space (since CI pipelines tend to fail otherwise).
85
qdict_del(qdict, "id");
116
+
86
117
+- disabled: Tests in this group are disabled and ignored by check.
87
- v = qobject_input_visitor_new(QOBJECT(qdict));
118
+
88
+ if (keyval) {
119
.. _docker-ref:
89
+ v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
120
90
+ } else {
121
Docker based tests
91
+ v = qobject_input_visitor_new(QOBJECT(qdict));
122
diff --git a/tests/qemu-iotests/findtests.py b/tests/qemu-iotests/findtests.py
92
+ }
123
new file mode 100644
93
obj = user_creatable_add_type(type, id, qdict, v, errp);
124
index XXXXXXX..XXXXXXX
94
visit_free(v);
125
--- /dev/null
95
object_unref(obj);
126
+++ b/tests/qemu-iotests/findtests.py
96
diff --git a/qom/qom-qmp-cmds.c b/qom/qom-qmp-cmds.c
127
@@ -XXX,XX +XXX,XX @@
97
index XXXXXXX..XXXXXXX 100644
128
+# TestFinder class, define set of tests to run.
98
--- a/qom/qom-qmp-cmds.c
129
+#
99
+++ b/qom/qom-qmp-cmds.c
130
+# Copyright (c) 2020-2021 Virtuozzo International GmbH
100
@@ -XXX,XX +XXX,XX @@ void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp)
131
+#
101
qobject_unref(pdict);
132
+# This program is free software; you can redistribute it and/or modify
102
}
133
+# it under the terms of the GNU General Public License as published by
103
134
+# the Free Software Foundation; either version 2 of the License, or
104
- user_creatable_add_dict(qdict, errp);
135
+# (at your option) any later version.
105
+ user_creatable_add_dict(qdict, false, errp);
136
+#
106
}
137
+# This program is distributed in the hope that it will be useful,
107
138
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
108
void qmp_object_del(const char *id, Error **errp)
139
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
140
+# GNU General Public License for more details.
141
+#
142
+# You should have received a copy of the GNU General Public License
143
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
144
+#
145
+
146
+import os
147
+import glob
148
+import re
149
+from collections import defaultdict
150
+from contextlib import contextmanager
151
+from typing import Optional, List, Iterator, Set
152
+
153
+
154
+@contextmanager
155
+def chdir(path: Optional[str] = None) -> Iterator[None]:
156
+ if path is None:
157
+ yield
158
+ return
159
+
160
+ saved_dir = os.getcwd()
161
+ os.chdir(path)
162
+ try:
163
+ yield
164
+ finally:
165
+ os.chdir(saved_dir)
166
+
167
+
168
+class TestFinder:
169
+ def __init__(self, test_dir: Optional[str] = None) -> None:
170
+ self.groups = defaultdict(set)
171
+
172
+ with chdir(test_dir):
173
+ self.all_tests = glob.glob('[0-9][0-9][0-9]')
174
+ self.all_tests += [f for f in glob.iglob('tests/*')
175
+ if not f.endswith('.out') and
176
+ os.path.isfile(f + '.out')]
177
+
178
+ for t in self.all_tests:
179
+ with open(t, encoding="utf-8") as f:
180
+ for line in f:
181
+ if line.startswith('# group: '):
182
+ for g in line.split()[2:]:
183
+ self.groups[g].add(t)
184
+ break
185
+
186
+ def add_group_file(self, fname: str) -> None:
187
+ with open(fname, encoding="utf-8") as f:
188
+ for line in f:
189
+ line = line.strip()
190
+
191
+ if (not line) or line[0] == '#':
192
+ continue
193
+
194
+ words = line.split()
195
+ test_file = self.parse_test_name(words[0])
196
+ groups = words[1:]
197
+
198
+ for g in groups:
199
+ self.groups[g].add(test_file)
200
+
201
+ def parse_test_name(self, name: str) -> str:
202
+ if '/' in name:
203
+ raise ValueError('Paths are unsupported for test selection, '
204
+ f'requiring "{name}" is wrong')
205
+
206
+ if re.fullmatch(r'\d+', name):
207
+ # Numbered tests are old naming convention. We should convert them
208
+ # to three-digit-length, like 1 --> 001.
209
+ name = f'{int(name):03}'
210
+ else:
211
+ # Named tests all should be in tests/ subdirectory
212
+ name = os.path.join('tests', name)
213
+
214
+ if name not in self.all_tests:
215
+ raise ValueError(f'Test "{name}" is not found')
216
+
217
+ return name
218
+
219
+ def find_tests(self, groups: Optional[List[str]] = None,
220
+ exclude_groups: Optional[List[str]] = None,
221
+ tests: Optional[List[str]] = None,
222
+ start_from: Optional[str] = None) -> List[str]:
223
+ """Find tests
224
+
225
+ Algorithm:
226
+
227
+ 1. a. if some @groups specified
228
+ a.1 Take all tests from @groups
229
+ a.2 Drop tests, which are in at least one of @exclude_groups or in
230
+ 'disabled' group (if 'disabled' is not listed in @groups)
231
+ a.3 Add tests from @tests (don't exclude anything from them)
232
+
233
+ b. else, if some @tests specified:
234
+ b.1 exclude_groups must be not specified, so just take @tests
235
+
236
+ c. else (only @exclude_groups list is non-empty):
237
+ c.1 Take all tests
238
+ c.2 Drop tests, which are in at least one of @exclude_groups or in
239
+ 'disabled' group
240
+
241
+ 2. sort
242
+
243
+ 3. If start_from specified, drop tests from first one to @start_from
244
+ (not inclusive)
245
+ """
246
+ if groups is None:
247
+ groups = []
248
+ if exclude_groups is None:
249
+ exclude_groups = []
250
+ if tests is None:
251
+ tests = []
252
+
253
+ res: Set[str] = set()
254
+ if groups:
255
+ # Some groups specified. exclude_groups supported, additionally
256
+ # selecting some individual tests supported as well.
257
+ res.update(*(self.groups[g] for g in groups))
258
+ elif tests:
259
+ # Some individual tests specified, but no groups. In this case
260
+ # we don't support exclude_groups.
261
+ if exclude_groups:
262
+ raise ValueError("Can't exclude from individually specified "
263
+ "tests.")
264
+ else:
265
+ # No tests no groups: start from all tests, exclude_groups
266
+ # supported.
267
+ res.update(self.all_tests)
268
+
269
+ if 'disabled' not in groups and 'disabled' not in exclude_groups:
270
+ # Don't want to modify function argument, so create new list.
271
+ exclude_groups = exclude_groups + ['disabled']
272
+
273
+ res = res.difference(*(self.groups[g] for g in exclude_groups))
274
+
275
+ # We want to add @tests. But for compatibility with old test names,
276
+ # we should convert any number < 100 to number padded by
277
+ # leading zeroes, like 1 -> 001 and 23 -> 023.
278
+ for t in tests:
279
+ res.add(self.parse_test_name(t))
280
+
281
+ sequence = sorted(res)
282
+
283
+ if start_from is not None:
284
+ del sequence[:sequence.index(self.parse_test_name(start_from))]
285
+
286
+ return sequence
109
--
287
--
110
2.25.3
288
2.29.2
111
289
112
290
diff view generated by jsdifflib
1
The QMP handler qmp_object_add() and the implementation of --object in
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
qemu-storage-daemon can share most of the code. Currently,
2
3
qemu-storage-daemon calls qmp_object_add(), but this is not correct
3
Add TestEnv class, which will handle test environment in a new python
4
because different visitors need to be used.
4
iotests running framework.
5
5
6
As a first step towards a fix, make qmp_object_add() a wrapper around a
6
Don't add compat=1.1 for qcow2 IMGOPTS, as v3 is default anyway.
7
new function user_creatable_add_dict() that can get an additional
7
8
parameter. The handling of "props" is only required for compatibility
8
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
and not required for the qemu-storage-daemon command line, so it stays
9
Message-Id: <20210125185056.129513-4-vsementsov@virtuozzo.com>
10
in qmp_object_add().
11
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
11
---
14
include/qom/object_interfaces.h | 12 ++++++++++++
12
tests/qemu-iotests/testenv.py | 281 ++++++++++++++++++++++++++++++++++
15
qom/object_interfaces.c | 27 +++++++++++++++++++++++++++
13
1 file changed, 281 insertions(+)
16
qom/qom-qmp-cmds.c | 24 +-----------------------
14
create mode 100644 tests/qemu-iotests/testenv.py
17
3 files changed, 40 insertions(+), 23 deletions(-)
15
18
16
diff --git a/tests/qemu-iotests/testenv.py b/tests/qemu-iotests/testenv.py
19
diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
17
new file mode 100644
20
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX
21
--- a/include/qom/object_interfaces.h
19
--- /dev/null
22
+++ b/include/qom/object_interfaces.h
20
+++ b/tests/qemu-iotests/testenv.py
23
@@ -XXX,XX +XXX,XX @@ Object *user_creatable_add_type(const char *type, const char *id,
24
const QDict *qdict,
25
Visitor *v, Error **errp);
26
27
+/**
28
+ * user_creatable_add_dict:
29
+ * @qdict: the object definition
30
+ * @errp: if an error occurs, a pointer to an area to store the error
31
+ *
32
+ * Create an instance of the user creatable object that is defined by
33
+ * @qdict. The object type is taken from the QDict key 'qom-type', its
34
+ * ID from the key 'id'. The remaining entries in @qdict are used to
35
+ * initialize the object properties.
36
+ */
37
+void user_creatable_add_dict(QDict *qdict, Error **errp);
38
+
39
/**
40
* user_creatable_add_opts:
41
* @opts: the object definition
42
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/qom/object_interfaces.c
45
+++ b/qom/object_interfaces.c
46
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@
47
#include "qapi/qmp/qerror.h"
22
+# TestEnv class to manage test environment variables.
48
#include "qapi/qmp/qjson.h"
23
+#
49
#include "qapi/qmp/qstring.h"
24
+# Copyright (c) 2020-2021 Virtuozzo International GmbH
50
+#include "qapi/qobject-input-visitor.h"
25
+#
51
#include "qom/object_interfaces.h"
26
+# This program is free software; you can redistribute it and/or modify
52
#include "qemu/help_option.h"
27
+# it under the terms of the GNU General Public License as published by
53
#include "qemu/module.h"
28
+# the Free Software Foundation; either version 2 of the License, or
54
@@ -XXX,XX +XXX,XX @@ out:
29
+# (at your option) any later version.
55
return obj;
30
+#
56
}
31
+# This program is distributed in the hope that it will be useful,
57
32
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
58
+void user_creatable_add_dict(QDict *qdict, Error **errp)
33
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
59
+{
34
+# GNU General Public License for more details.
60
+ Visitor *v;
35
+#
61
+ Object *obj;
36
+# You should have received a copy of the GNU General Public License
62
+ g_autofree char *type = NULL;
37
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
63
+ g_autofree char *id = NULL;
38
+#
64
+
39
+
65
+ type = g_strdup(qdict_get_try_str(qdict, "qom-type"));
40
+import os
66
+ if (!type) {
41
+import sys
67
+ error_setg(errp, QERR_MISSING_PARAMETER, "qom-type");
42
+import tempfile
68
+ return;
43
+from pathlib import Path
69
+ }
44
+import shutil
70
+ qdict_del(qdict, "qom-type");
45
+import collections
71
+
46
+import random
72
+ id = g_strdup(qdict_get_try_str(qdict, "id"));
47
+import subprocess
73
+ if (!id) {
48
+import glob
74
+ error_setg(errp, QERR_MISSING_PARAMETER, "id");
49
+from typing import Dict, Any, Optional, ContextManager
75
+ return;
50
+
76
+ }
51
+
77
+ qdict_del(qdict, "id");
52
+def isxfile(path: str) -> bool:
78
+
53
+ return os.path.isfile(path) and os.access(path, os.X_OK)
79
+ v = qobject_input_visitor_new(QOBJECT(qdict));
54
+
80
+ obj = user_creatable_add_type(type, id, qdict, v, errp);
55
+
81
+ visit_free(v);
56
+def get_default_machine(qemu_prog: str) -> str:
82
+ object_unref(obj);
57
+ outp = subprocess.run([qemu_prog, '-machine', 'help'], check=True,
83
+}
58
+ universal_newlines=True,
84
59
+ stdout=subprocess.PIPE).stdout
85
Object *user_creatable_add_opts(QemuOpts *opts, Error **errp)
60
+
86
{
61
+ machines = outp.split('\n')
87
diff --git a/qom/qom-qmp-cmds.c b/qom/qom-qmp-cmds.c
62
+ try:
88
index XXXXXXX..XXXXXXX 100644
63
+ default_machine = next(m for m in machines if m.endswith(' (default)'))
89
--- a/qom/qom-qmp-cmds.c
64
+ except StopIteration:
90
+++ b/qom/qom-qmp-cmds.c
65
+ return ''
91
@@ -XXX,XX +XXX,XX @@
66
+ default_machine = default_machine.split(' ', 1)[0]
92
#include "qapi/qapi-commands-qom.h"
67
+
93
#include "qapi/qmp/qdict.h"
68
+ alias_suf = ' (alias of {})'.format(default_machine)
94
#include "qapi/qmp/qerror.h"
69
+ alias = next((m for m in machines if m.endswith(alias_suf)), None)
95
-#include "qapi/qobject-input-visitor.h"
70
+ if alias is not None:
96
#include "qemu/cutils.h"
71
+ default_machine = alias.split(' ', 1)[0]
97
#include "qom/object_interfaces.h"
72
+
98
#include "qom/qom-qobject.h"
73
+ return default_machine
99
@@ -XXX,XX +XXX,XX @@ void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp)
74
+
100
{
75
+
101
QObject *props;
76
+class TestEnv(ContextManager['TestEnv']):
102
QDict *pdict;
77
+ """
103
- Visitor *v;
78
+ Manage system environment for running tests
104
- Object *obj;
79
+
105
- g_autofree char *type = NULL;
80
+ The following variables are supported/provided. They are represented by
106
- g_autofree char *id = NULL;
81
+ lower-cased TestEnv attributes.
107
-
82
+ """
108
- type = g_strdup(qdict_get_try_str(qdict, "qom-type"));
83
+
109
- if (!type) {
84
+ # We store environment variables as instance attributes, and there are a
110
- error_setg(errp, QERR_MISSING_PARAMETER, "qom-type");
85
+ # lot of them. Silence pylint:
111
- return;
86
+ # pylint: disable=too-many-instance-attributes
112
- }
87
+
113
- qdict_del(qdict, "qom-type");
88
+ env_variables = ['PYTHONPATH', 'TEST_DIR', 'SOCK_DIR', 'SAMPLE_IMG_DIR',
114
-
89
+ 'OUTPUT_DIR', 'PYTHON', 'QEMU_PROG', 'QEMU_IMG_PROG',
115
- id = g_strdup(qdict_get_try_str(qdict, "id"));
90
+ 'QEMU_IO_PROG', 'QEMU_NBD_PROG', 'QSD_PROG',
116
- if (!id) {
91
+ 'SOCKET_SCM_HELPER', 'QEMU_OPTIONS', 'QEMU_IMG_OPTIONS',
117
- error_setg(errp, QERR_MISSING_PARAMETER, "id");
92
+ 'QEMU_IO_OPTIONS', 'QEMU_IO_OPTIONS_NO_FMT',
118
- return;
93
+ 'QEMU_NBD_OPTIONS', 'IMGOPTS', 'IMGFMT', 'IMGPROTO',
119
- }
94
+ 'AIOMODE', 'CACHEMODE', 'VALGRIND_QEMU',
120
- qdict_del(qdict, "id");
95
+ 'CACHEMODE_IS_DEFAULT', 'IMGFMT_GENERIC', 'IMGOPTSSYNTAX',
121
96
+ 'IMGKEYSECRET', 'QEMU_DEFAULT_MACHINE', 'MALLOC_PERTURB_']
122
props = qdict_get(qdict, "props");
97
+
123
if (props) {
98
+ def get_env(self) -> Dict[str, str]:
124
@@ -XXX,XX +XXX,XX @@ void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp)
99
+ env = {}
125
qobject_unref(pdict);
100
+ for v in self.env_variables:
126
}
101
+ val = getattr(self, v.lower(), None)
127
102
+ if val is not None:
128
- v = qobject_input_visitor_new(QOBJECT(qdict));
103
+ env[v] = val
129
- obj = user_creatable_add_type(type, id, qdict, v, errp);
104
+
130
- visit_free(v);
105
+ return env
131
- object_unref(obj);
106
+
132
+ user_creatable_add_dict(qdict, errp);
107
+ def init_directories(self) -> None:
133
}
108
+ """Init directory variables:
134
109
+ PYTHONPATH
135
void qmp_object_del(const char *id, Error **errp)
110
+ TEST_DIR
111
+ SOCK_DIR
112
+ SAMPLE_IMG_DIR
113
+ OUTPUT_DIR
114
+ """
115
+ self.pythonpath = os.getenv('PYTHONPATH')
116
+ if self.pythonpath:
117
+ self.pythonpath = self.source_iotests + os.pathsep + \
118
+ self.pythonpath
119
+ else:
120
+ self.pythonpath = self.source_iotests
121
+
122
+ self.test_dir = os.getenv('TEST_DIR',
123
+ os.path.join(os.getcwd(), 'scratch'))
124
+ Path(self.test_dir).mkdir(parents=True, exist_ok=True)
125
+
126
+ try:
127
+ self.sock_dir = os.environ['SOCK_DIR']
128
+ self.tmp_sock_dir = False
129
+ Path(self.test_dir).mkdir(parents=True, exist_ok=True)
130
+ except KeyError:
131
+ self.sock_dir = tempfile.mkdtemp()
132
+ self.tmp_sock_dir = True
133
+
134
+ self.sample_img_dir = os.getenv('SAMPLE_IMG_DIR',
135
+ os.path.join(self.source_iotests,
136
+ 'sample_images'))
137
+
138
+ self.output_dir = os.getcwd() # OUTPUT_DIR
139
+
140
+ def init_binaries(self) -> None:
141
+ """Init binary path variables:
142
+ PYTHON (for bash tests)
143
+ QEMU_PROG, QEMU_IMG_PROG, QEMU_IO_PROG, QEMU_NBD_PROG, QSD_PROG
144
+ SOCKET_SCM_HELPER
145
+ """
146
+ self.python = sys.executable
147
+
148
+ def root(*names: str) -> str:
149
+ return os.path.join(self.build_root, *names)
150
+
151
+ arch = os.uname().machine
152
+ if 'ppc64' in arch:
153
+ arch = 'ppc64'
154
+
155
+ self.qemu_prog = os.getenv('QEMU_PROG', root(f'qemu-system-{arch}'))
156
+ if not os.path.exists(self.qemu_prog):
157
+ pattern = root('qemu-system-*')
158
+ try:
159
+ progs = glob.iglob(pattern)
160
+ self.qemu_prog = next(p for p in progs if isxfile(p))
161
+ except StopIteration:
162
+ sys.exit("Not found any Qemu executable binary by pattern "
163
+ f"'{pattern}'")
164
+
165
+ self.qemu_img_prog = os.getenv('QEMU_IMG_PROG', root('qemu-img'))
166
+ self.qemu_io_prog = os.getenv('QEMU_IO_PROG', root('qemu-io'))
167
+ self.qemu_nbd_prog = os.getenv('QEMU_NBD_PROG', root('qemu-nbd'))
168
+ self.qsd_prog = os.getenv('QSD_PROG', root('storage-daemon',
169
+ 'qemu-storage-daemon'))
170
+
171
+ for b in [self.qemu_img_prog, self.qemu_io_prog, self.qemu_nbd_prog,
172
+ self.qemu_prog, self.qsd_prog]:
173
+ if not os.path.exists(b):
174
+ sys.exit('No such file: ' + b)
175
+ if not isxfile(b):
176
+ sys.exit('Not executable: ' + b)
177
+
178
+ helper_path = os.path.join(self.build_iotests, 'socket_scm_helper')
179
+ if isxfile(helper_path):
180
+ self.socket_scm_helper = helper_path # SOCKET_SCM_HELPER
181
+
182
+ def __init__(self, imgfmt: str, imgproto: str, aiomode: str,
183
+ cachemode: Optional[str] = None,
184
+ imgopts: Optional[str] = None,
185
+ misalign: bool = False,
186
+ debug: bool = False,
187
+ valgrind: bool = False) -> None:
188
+ self.imgfmt = imgfmt
189
+ self.imgproto = imgproto
190
+ self.aiomode = aiomode
191
+ self.imgopts = imgopts
192
+ self.misalign = misalign
193
+ self.debug = debug
194
+
195
+ if valgrind:
196
+ self.valgrind_qemu = 'y'
197
+
198
+ if cachemode is None:
199
+ self.cachemode_is_default = 'true'
200
+ self.cachemode = 'writeback'
201
+ else:
202
+ self.cachemode_is_default = 'false'
203
+ self.cachemode = cachemode
204
+
205
+ # Initialize generic paths: build_root, build_iotests, source_iotests,
206
+ # which are needed to initialize some environment variables. They are
207
+ # used by init_*() functions as well.
208
+
209
+ if os.path.islink(sys.argv[0]):
210
+ # called from the build tree
211
+ self.source_iotests = os.path.dirname(os.readlink(sys.argv[0]))
212
+ self.build_iotests = os.path.dirname(os.path.abspath(sys.argv[0]))
213
+ else:
214
+ # called from the source tree
215
+ self.source_iotests = os.getcwd()
216
+ self.build_iotests = self.source_iotests
217
+
218
+ self.build_root = os.path.join(self.build_iotests, '..', '..')
219
+
220
+ self.init_directories()
221
+ self.init_binaries()
222
+
223
+ self.malloc_perturb_ = os.getenv('MALLOC_PERTURB_',
224
+ str(random.randrange(1, 255)))
225
+
226
+ # QEMU_OPTIONS
227
+ self.qemu_options = '-nodefaults -display none -accel qtest'
228
+ machine_map = (
229
+ ('arm', 'virt'),
230
+ ('aarch64', 'virt'),
231
+ ('avr', 'mega2560'),
232
+ ('rx', 'gdbsim-r5f562n8'),
233
+ ('tricore', 'tricore_testboard')
234
+ )
235
+ for suffix, machine in machine_map:
236
+ if self.qemu_prog.endswith(f'qemu-system-{suffix}'):
237
+ self.qemu_options += f' -machine {machine}'
238
+
239
+ # QEMU_DEFAULT_MACHINE
240
+ self.qemu_default_machine = get_default_machine(self.qemu_prog)
241
+
242
+ self.qemu_img_options = os.getenv('QEMU_IMG_OPTIONS')
243
+ self.qemu_nbd_options = os.getenv('QEMU_NBD_OPTIONS')
244
+
245
+ is_generic = self.imgfmt not in ['bochs', 'cloop', 'dmg']
246
+ self.imgfmt_generic = 'true' if is_generic else 'false'
247
+
248
+ self.qemu_io_options = f'--cache {self.cachemode} --aio {self.aiomode}'
249
+ if self.misalign:
250
+ self.qemu_io_options += ' --misalign'
251
+
252
+ self.qemu_io_options_no_fmt = self.qemu_io_options
253
+
254
+ if self.imgfmt == 'luks':
255
+ self.imgoptssyntax = 'true'
256
+ self.imgkeysecret = '123456'
257
+ if not self.imgopts:
258
+ self.imgopts = 'iter-time=10'
259
+ elif 'iter-time=' not in self.imgopts:
260
+ self.imgopts += ',iter-time=10'
261
+ else:
262
+ self.imgoptssyntax = 'false'
263
+ self.qemu_io_options += ' -f ' + self.imgfmt
264
+
265
+ if self.imgfmt == 'vmdk':
266
+ if not self.imgopts:
267
+ self.imgopts = 'zeroed_grain=on'
268
+ elif 'zeroed_grain=' not in self.imgopts:
269
+ self.imgopts += ',zeroed_grain=on'
270
+
271
+ def close(self) -> None:
272
+ if self.tmp_sock_dir:
273
+ shutil.rmtree(self.sock_dir)
274
+
275
+ def __enter__(self) -> 'TestEnv':
276
+ return self
277
+
278
+ def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None:
279
+ self.close()
280
+
281
+ def print_env(self) -> None:
282
+ template = """\
283
+QEMU -- "{QEMU_PROG}" {QEMU_OPTIONS}
284
+QEMU_IMG -- "{QEMU_IMG_PROG}" {QEMU_IMG_OPTIONS}
285
+QEMU_IO -- "{QEMU_IO_PROG}" {QEMU_IO_OPTIONS}
286
+QEMU_NBD -- "{QEMU_NBD_PROG}" {QEMU_NBD_OPTIONS}
287
+IMGFMT -- {IMGFMT}{imgopts}
288
+IMGPROTO -- {IMGPROTO}
289
+PLATFORM -- {platform}
290
+TEST_DIR -- {TEST_DIR}
291
+SOCK_DIR -- {SOCK_DIR}
292
+SOCKET_SCM_HELPER -- {SOCKET_SCM_HELPER}"""
293
+
294
+ args = collections.defaultdict(str, self.get_env())
295
+
296
+ if 'IMGOPTS' in args:
297
+ args['imgopts'] = f" ({args['IMGOPTS']})"
298
+
299
+ u = os.uname()
300
+ args['platform'] = f'{u.sysname}/{u.machine} {u.nodename} {u.release}'
301
+
302
+ print(template.format_map(args))
136
--
303
--
137
2.25.3
304
2.29.2
138
305
139
306
diff view generated by jsdifflib
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
Message-Id: <20200424125448.63318-10-kwolf@redhat.com>
2
3
Reviewed-by: Max Reitz <mreitz@redhat.com>
3
Add TestRunner class, which will run tests in a new python iotests
4
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
4
running framework.
5
6
There are some differences with current ./check behavior, most
7
significant are:
8
- Consider all tests self-executable, just run them, don't run python
9
by hand.
10
- Elapsed time is cached in json file
11
- Elapsed time precision increased a bit
12
- Instead of using "diff -w" which ignores all whitespace differences,
13
manually strip whitespace at line end then use python difflib, which
14
no longer ignores spacing mid-line
15
16
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
17
Message-Id: <20210125185056.129513-5-vsementsov@virtuozzo.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
---
19
---
7
tests/qemu-iotests/274 | 155 +++++++++++++++++++++
20
tests/qemu-iotests/testrunner.py | 367 +++++++++++++++++++++++++++++++
8
tests/qemu-iotests/274.out | 268 +++++++++++++++++++++++++++++++++++++
21
1 file changed, 367 insertions(+)
9
tests/qemu-iotests/group | 1 +
22
create mode 100644 tests/qemu-iotests/testrunner.py
10
3 files changed, 424 insertions(+)
23
11
create mode 100755 tests/qemu-iotests/274
24
diff --git a/tests/qemu-iotests/testrunner.py b/tests/qemu-iotests/testrunner.py
12
create mode 100644 tests/qemu-iotests/274.out
25
new file mode 100644
13
14
diff --git a/tests/qemu-iotests/274 b/tests/qemu-iotests/274
15
new file mode 100755
16
index XXXXXXX..XXXXXXX
26
index XXXXXXX..XXXXXXX
17
--- /dev/null
27
--- /dev/null
18
+++ b/tests/qemu-iotests/274
28
+++ b/tests/qemu-iotests/testrunner.py
19
@@ -XXX,XX +XXX,XX @@
29
@@ -XXX,XX +XXX,XX @@
20
+#!/usr/bin/env python3
30
+# Class for actually running tests.
21
+#
31
+#
22
+# Copyright (C) 2019 Red Hat, Inc.
32
+# Copyright (c) 2020-2021 Virtuozzo International GmbH
23
+#
33
+#
24
+# This program is free software; you can redistribute it and/or modify
34
+# This program is free software; you can redistribute it and/or modify
25
+# it under the terms of the GNU General Public License as published by
35
+# it under the terms of the GNU General Public License as published by
26
+# the Free Software Foundation; either version 2 of the License, or
36
+# the Free Software Foundation; either version 2 of the License, or
27
+# (at your option) any later version.
37
+# (at your option) any later version.
...
...
32
+# GNU General Public License for more details.
42
+# GNU General Public License for more details.
33
+#
43
+#
34
+# You should have received a copy of the GNU General Public License
44
+# You should have received a copy of the GNU General Public License
35
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
45
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
36
+#
46
+#
37
+# Creator/Owner: Kevin Wolf <kwolf@redhat.com>
47
+
38
+#
48
+import os
39
+# Some tests for short backing files and short overlays
49
+from pathlib import Path
40
+
50
+import datetime
41
+import iotests
51
+import time
42
+
52
+import difflib
43
+iotests.verify_image_format(supported_fmts=['qcow2'])
53
+import subprocess
44
+iotests.verify_platform(['linux'])
54
+import contextlib
45
+
55
+import json
46
+size_short = 1 * 1024 * 1024
56
+import termios
47
+size_long = 2 * 1024 * 1024
57
+import sys
48
+size_diff = size_long - size_short
58
+from contextlib import contextmanager
49
+
59
+from typing import List, Optional, Iterator, Any, Sequence, Dict, \
50
+def create_chain() -> None:
60
+ ContextManager
51
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, base,
61
+
52
+ str(size_long))
62
+from testenv import TestEnv
53
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', base, mid,
63
+
54
+ str(size_short))
64
+
55
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', mid, top,
65
+def silent_unlink(path: Path) -> None:
56
+ str(size_long))
66
+ try:
57
+
67
+ path.unlink()
58
+ iotests.qemu_io_log('-c', 'write -P 1 0 %d' % size_long, base)
68
+ except OSError:
59
+
69
+ pass
60
+def create_vm() -> iotests.VM:
70
+
61
+ vm = iotests.VM()
71
+
62
+ vm.add_blockdev('file,filename=%s,node-name=base-file' % base)
72
+def file_diff(file1: str, file2: str) -> List[str]:
63
+ vm.add_blockdev('%s,file=base-file,node-name=base' % iotests.imgfmt)
73
+ with open(file1, encoding="utf-8") as f1, \
64
+ vm.add_blockdev('file,filename=%s,node-name=mid-file' % mid)
74
+ open(file2, encoding="utf-8") as f2:
65
+ vm.add_blockdev('%s,file=mid-file,node-name=mid,backing=base'
75
+ # We want to ignore spaces at line ends. There are a lot of mess about
66
+ % iotests.imgfmt)
76
+ # it in iotests.
67
+ vm.add_drive(top, 'backing=mid,node-name=top')
77
+ # TODO: fix all tests to not produce extra spaces, fix all .out files
68
+ return vm
78
+ # and use strict diff here!
69
+
79
+ seq1 = [line.rstrip() for line in f1]
70
+with iotests.FilePath('base') as base, \
80
+ seq2 = [line.rstrip() for line in f2]
71
+ iotests.FilePath('mid') as mid, \
81
+ res = [line.rstrip()
72
+ iotests.FilePath('top') as top:
82
+ for line in difflib.unified_diff(seq1, seq2, file1, file2)]
73
+
83
+ return res
74
+ iotests.log('== Commit tests ==')
84
+
75
+
85
+
76
+ create_chain()
86
+# We want to save current tty settings during test run,
77
+
87
+# since an aborting qemu call may leave things screwed up.
78
+ iotests.log('=== Check visible data ===')
88
+@contextmanager
79
+
89
+def savetty() -> Iterator[None]:
80
+ iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, top)
90
+ isterm = sys.stdin.isatty()
81
+ iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), top)
91
+ if isterm:
82
+
92
+ fd = sys.stdin.fileno()
83
+ iotests.log('=== Checking allocation status ===')
93
+ attr = termios.tcgetattr(fd)
84
+
94
+
85
+ iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short,
95
+ try:
86
+ '-c', 'alloc %d %d' % (size_short, size_diff),
96
+ yield
87
+ base)
97
+ finally:
88
+
98
+ if isterm:
89
+ iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short,
99
+ termios.tcsetattr(fd, termios.TCSADRAIN, attr)
90
+ '-c', 'alloc %d %d' % (size_short, size_diff),
100
+
91
+ mid)
101
+
92
+
102
+class LastElapsedTime(ContextManager['LastElapsedTime']):
93
+ iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short,
103
+ """ Cache for elapsed time for tests, to show it during new test run
94
+ '-c', 'alloc %d %d' % (size_short, size_diff),
104
+
95
+ top)
105
+ It is safe to use get() at any time. To use update(), you must either
96
+
106
+ use it inside with-block or use save() after update().
97
+ iotests.log('=== Checking map ===')
107
+ """
98
+
108
+ def __init__(self, cache_file: str, env: TestEnv) -> None:
99
+ iotests.qemu_img_log('map', '--output=json', base)
109
+ self.env = env
100
+ iotests.qemu_img_log('map', '--output=human', base)
110
+ self.cache_file = cache_file
101
+ iotests.qemu_img_log('map', '--output=json', mid)
111
+ self.cache: Dict[str, Dict[str, Dict[str, float]]]
102
+ iotests.qemu_img_log('map', '--output=human', mid)
112
+
103
+ iotests.qemu_img_log('map', '--output=json', top)
113
+ try:
104
+ iotests.qemu_img_log('map', '--output=human', top)
114
+ with open(cache_file, encoding="utf-8") as f:
105
+
115
+ self.cache = json.load(f)
106
+ iotests.log('=== Testing qemu-img commit (top -> mid) ===')
116
+ except (OSError, ValueError):
107
+
117
+ self.cache = {}
108
+ iotests.qemu_img_log('commit', top)
118
+
109
+ iotests.img_info_log(mid)
119
+ def get(self, test: str,
110
+ iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid)
120
+ default: Optional[float] = None) -> Optional[float]:
111
+ iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid)
121
+ if test not in self.cache:
112
+
122
+ return default
113
+ iotests.log('=== Testing HMP commit (top -> mid) ===')
123
+
114
+
124
+ if self.env.imgproto not in self.cache[test]:
115
+ create_chain()
125
+ return default
116
+ with create_vm() as vm:
126
+
117
+ vm.launch()
127
+ return self.cache[test][self.env.imgproto].get(self.env.imgfmt,
118
+ vm.qmp_log('human-monitor-command', command_line='commit drive0')
128
+ default)
119
+
129
+
120
+ iotests.img_info_log(mid)
130
+ def update(self, test: str, elapsed: float) -> None:
121
+ iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid)
131
+ d = self.cache.setdefault(test, {})
122
+ iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid)
132
+ d.setdefault(self.env.imgproto, {})[self.env.imgfmt] = elapsed
123
+
133
+
124
+ iotests.log('=== Testing QMP active commit (top -> mid) ===')
134
+ def save(self) -> None:
125
+
135
+ with open(self.cache_file, 'w', encoding="utf-8") as f:
126
+ create_chain()
136
+ json.dump(self.cache, f)
127
+ with create_vm() as vm:
137
+
128
+ vm.launch()
138
+ def __enter__(self) -> 'LastElapsedTime':
129
+ vm.qmp_log('block-commit', device='top', base_node='mid',
139
+ return self
130
+ job_id='job0', auto_dismiss=False)
140
+
131
+ vm.run_job('job0', wait=5)
141
+ def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None:
132
+
142
+ self.save()
133
+ iotests.img_info_log(mid)
143
+
134
+ iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid)
144
+
135
+ iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid)
145
+class TestResult:
136
+
146
+ def __init__(self, status: str, description: str = '',
137
+
147
+ elapsed: Optional[float] = None, diff: Sequence[str] = (),
138
+ iotests.log('== Resize tests ==')
148
+ casenotrun: str = '', interrupted: bool = False) -> None:
139
+
149
+ self.status = status
140
+ # Use different sizes for different allocation modes:
150
+ self.description = description
141
+ #
151
+ self.elapsed = elapsed
142
+ # We want to have at least one test where 32 bit truncation in the size of
152
+ self.diff = diff
143
+ # the overlapping area becomes visible. This is covered by the
153
+ self.casenotrun = casenotrun
144
+ # prealloc='off' case (1G to 6G is an overlap of 5G).
154
+ self.interrupted = interrupted
145
+ #
155
+
146
+ # However, we can only do this for modes that don't preallocate data
156
+
147
+ # because otherwise we might run out of space on the test host.
157
+class TestRunner(ContextManager['TestRunner']):
148
+ #
158
+ def __init__(self, env: TestEnv, makecheck: bool = False,
149
+ # We also want to test some unaligned combinations.
159
+ color: str = 'auto') -> None:
150
+ for (prealloc, base_size, top_size_old, top_size_new, off) in [
160
+ self.env = env
151
+ ('off', '6G', '1G', '8G', '5G'),
161
+ self.test_run_env = self.env.get_env()
152
+ ('metadata', '32G', '30G', '33G', '31G'),
162
+ self.makecheck = makecheck
153
+ ('falloc', '10M', '5M', '15M', '9M'),
163
+ self.last_elapsed = LastElapsedTime('.last-elapsed-cache', env)
154
+ ('full', '16M', '8M', '12M', '11M'),
164
+
155
+ ('off', '384k', '253k', '512k', '253k'),
165
+ assert color in ('auto', 'on', 'off')
156
+ ('off', '400k', '256k', '512k', '336k'),
166
+ self.color = (color == 'on') or (color == 'auto' and
157
+ ('off', '512k', '256k', '500k', '436k')]:
167
+ sys.stdout.isatty())
158
+
168
+
159
+ iotests.log('=== preallocation=%s ===' % prealloc)
169
+ self._stack: contextlib.ExitStack
160
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, base, base_size)
170
+
161
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', base, top,
171
+ def __enter__(self) -> 'TestRunner':
162
+ top_size_old)
172
+ self._stack = contextlib.ExitStack()
163
+ iotests.qemu_io_log('-c', 'write -P 1 %s 64k' % off, base)
173
+ self._stack.enter_context(self.env)
164
+
174
+ self._stack.enter_context(self.last_elapsed)
165
+ # After this, top_size_old to base_size should be allocated/zeroed.
175
+ self._stack.enter_context(savetty())
166
+ #
176
+ return self
167
+ # In theory, leaving base_size to top_size_new unallocated would be
177
+
168
+ # correct, but in practice, if we zero out anything, we zero out
178
+ def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None:
169
+ # everything up to top_size_new.
179
+ self._stack.close()
170
+ iotests.qemu_img_log('resize', '-f', iotests.imgfmt,
180
+
171
+ '--preallocation', prealloc, top, top_size_new)
181
+ def test_print_one_line(self, test: str, starttime: str,
172
+ iotests.qemu_io_log('-c', 'read -P 0 %s 64k' % off, top)
182
+ endtime: Optional[str] = None, status: str = '...',
173
+ iotests.qemu_io_log('-c', 'map', top)
183
+ lasttime: Optional[float] = None,
174
+ iotests.qemu_img_log('map', '--output=json', top)
184
+ thistime: Optional[float] = None,
175
diff --git a/tests/qemu-iotests/274.out b/tests/qemu-iotests/274.out
185
+ description: str = '',
176
new file mode 100644
186
+ test_field_width: Optional[int] = None,
177
index XXXXXXX..XXXXXXX
187
+ end: str = '\n') -> None:
178
--- /dev/null
188
+ """ Print short test info before/after test run """
179
+++ b/tests/qemu-iotests/274.out
189
+ test = os.path.basename(test)
180
@@ -XXX,XX +XXX,XX @@
190
+
181
+== Commit tests ==
191
+ if test_field_width is None:
182
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16
192
+ test_field_width = 8
183
+
193
+
184
+Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
194
+ if self.makecheck and status != '...':
185
+
195
+ if status and status != 'pass':
186
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16
196
+ status = f' [{status}]'
187
+
197
+ else:
188
+wrote 2097152/2097152 bytes at offset 0
198
+ status = ''
189
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
199
+
190
+
200
+ print(f' TEST iotest-{self.env.imgfmt}: {test}{status}')
191
+=== Check visible data ===
201
+ return
192
+read 1048576/1048576 bytes at offset 0
202
+
193
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
203
+ if lasttime:
194
+
204
+ lasttime_s = f' (last: {lasttime:.1f}s)'
195
+read 1048576/1048576 bytes at offset 1048576
205
+ else:
196
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
206
+ lasttime_s = ''
197
+
207
+ if thistime:
198
+=== Checking allocation status ===
208
+ thistime_s = f'{thistime:.1f}s'
199
+1048576/1048576 bytes allocated at offset 0 bytes
209
+ else:
200
+1048576/1048576 bytes allocated at offset 1 MiB
210
+ thistime_s = '...'
201
+
211
+
202
+0/1048576 bytes allocated at offset 0 bytes
212
+ if endtime:
203
+0/0 bytes allocated at offset 1 MiB
213
+ endtime = f'[{endtime}]'
204
+
214
+ else:
205
+0/1048576 bytes allocated at offset 0 bytes
215
+ endtime = ''
206
+0/1048576 bytes allocated at offset 1 MiB
216
+
207
+
217
+ if self.color:
208
+=== Checking map ===
218
+ if status == 'pass':
209
+[{ "start": 0, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": 327680}]
219
+ col = '\033[32m'
210
+
220
+ elif status == 'fail':
211
+Offset Length Mapped to File
221
+ col = '\033[1m\033[31m'
212
+0 0x200000 0x50000 TEST_DIR/PID-base
222
+ elif status == 'not run':
213
+
223
+ col = '\033[33m'
214
+[{ "start": 0, "length": 1048576, "depth": 1, "zero": false, "data": true, "offset": 327680}]
224
+ else:
215
+
225
+ col = ''
216
+Offset Length Mapped to File
226
+
217
+0 0x100000 0x50000 TEST_DIR/PID-base
227
+ col_end = '\033[0m'
218
+
228
+ else:
219
+[{ "start": 0, "length": 1048576, "depth": 2, "zero": false, "data": true, "offset": 327680},
229
+ col = ''
220
+{ "start": 1048576, "length": 1048576, "depth": 0, "zero": true, "data": false}]
230
+ col_end = ''
221
+
231
+
222
+Offset Length Mapped to File
232
+ print(f'{test:{test_field_width}} {col}{status:10}{col_end} '
223
+0 0x100000 0x50000 TEST_DIR/PID-base
233
+ f'[{starttime}] {endtime:13}{thistime_s:5} {lasttime_s:14} '
224
+
234
+ f'{description}', end=end)
225
+=== Testing qemu-img commit (top -> mid) ===
235
+
226
+Image committed.
236
+ def find_reference(self, test: str) -> str:
227
+
237
+ if self.env.cachemode == 'none':
228
+image: TEST_IMG
238
+ ref = f'{test}.out.nocache'
229
+file format: IMGFMT
239
+ if os.path.isfile(ref):
230
+virtual size: 2 MiB (2097152 bytes)
240
+ return ref
231
+cluster_size: 65536
241
+
232
+backing file: TEST_DIR/PID-base
242
+ ref = f'{test}.out.{self.env.imgfmt}'
233
+Format specific information:
243
+ if os.path.isfile(ref):
234
+ compat: 1.1
244
+ return ref
235
+ lazy refcounts: false
245
+
236
+ refcount bits: 16
246
+ ref = f'{test}.{self.env.qemu_default_machine}.out'
237
+ corrupt: false
247
+ if os.path.isfile(ref):
238
+
248
+ return ref
239
+read 1048576/1048576 bytes at offset 0
249
+
240
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
250
+ return f'{test}.out'
241
+
251
+
242
+read 1048576/1048576 bytes at offset 1048576
252
+ def do_run_test(self, test: str) -> TestResult:
243
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
253
+ f_test = Path(test)
244
+
254
+ f_bad = Path(f_test.name + '.out.bad')
245
+=== Testing HMP commit (top -> mid) ===
255
+ f_notrun = Path(f_test.name + '.notrun')
246
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16
256
+ f_casenotrun = Path(f_test.name + '.casenotrun')
247
+
257
+ f_reference = Path(self.find_reference(test))
248
+Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
258
+
249
+
259
+ if not f_test.exists():
250
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16
260
+ return TestResult(status='fail',
251
+
261
+ description=f'No such test file: {f_test}')
252
+wrote 2097152/2097152 bytes at offset 0
262
+
253
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
263
+ if not os.access(str(f_test), os.X_OK):
254
+
264
+ sys.exit(f'Not executable: {f_test}')
255
+{"execute": "human-monitor-command", "arguments": {"command-line": "commit drive0"}}
265
+
256
+{"return": ""}
266
+ if not f_reference.exists():
257
+image: TEST_IMG
267
+ return TestResult(status='not run',
258
+file format: IMGFMT
268
+ description='No qualified output '
259
+virtual size: 2 MiB (2097152 bytes)
269
+ f'(expected {f_reference})')
260
+cluster_size: 65536
270
+
261
+backing file: TEST_DIR/PID-base
271
+ for p in (f_bad, f_notrun, f_casenotrun):
262
+Format specific information:
272
+ silent_unlink(p)
263
+ compat: 1.1
273
+
264
+ lazy refcounts: false
274
+ args = [str(f_test.resolve())]
265
+ refcount bits: 16
275
+ if self.env.debug:
266
+ corrupt: false
276
+ args.append('-d')
267
+
277
+
268
+read 1048576/1048576 bytes at offset 0
278
+ with f_test.open(encoding="utf-8") as f:
269
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
279
+ try:
270
+
280
+ if f.readline() == '#!/usr/bin/env python3':
271
+read 1048576/1048576 bytes at offset 1048576
281
+ args.insert(0, self.env.python)
272
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
282
+ except UnicodeDecodeError: # binary test? for future.
273
+
283
+ pass
274
+=== Testing QMP active commit (top -> mid) ===
284
+
275
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16
285
+ env = os.environ.copy()
276
+
286
+ env.update(self.test_run_env)
277
+Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
287
+
278
+
288
+ t0 = time.time()
279
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16
289
+ with f_bad.open('w', encoding="utf-8") as f:
280
+
290
+ proc = subprocess.Popen(args, cwd=str(f_test.parent), env=env,
281
+wrote 2097152/2097152 bytes at offset 0
291
+ stdout=f, stderr=subprocess.STDOUT)
282
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
292
+ try:
283
+
293
+ proc.wait()
284
+{"execute": "block-commit", "arguments": {"auto-dismiss": false, "base-node": "mid", "device": "top", "job-id": "job0"}}
294
+ except KeyboardInterrupt:
285
+{"return": {}}
295
+ proc.terminate()
286
+{"execute": "job-complete", "arguments": {"id": "job0"}}
296
+ proc.wait()
287
+{"return": {}}
297
+ return TestResult(status='not run',
288
+{"data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
298
+ description='Interrupted by user',
289
+{"data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
299
+ interrupted=True)
290
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
300
+ ret = proc.returncode
291
+{"return": {}}
301
+
292
+image: TEST_IMG
302
+ elapsed = round(time.time() - t0, 1)
293
+file format: IMGFMT
303
+
294
+virtual size: 2 MiB (2097152 bytes)
304
+ if ret != 0:
295
+cluster_size: 65536
305
+ return TestResult(status='fail', elapsed=elapsed,
296
+backing file: TEST_DIR/PID-base
306
+ description=f'failed, exit status {ret}',
297
+Format specific information:
307
+ diff=file_diff(str(f_reference), str(f_bad)))
298
+ compat: 1.1
308
+
299
+ lazy refcounts: false
309
+ if f_notrun.exists():
300
+ refcount bits: 16
310
+ return TestResult(status='not run',
301
+ corrupt: false
311
+ description=f_notrun.read_text().strip())
302
+
312
+
303
+read 1048576/1048576 bytes at offset 0
313
+ casenotrun = ''
304
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
314
+ if f_casenotrun.exists():
305
+
315
+ casenotrun = f_casenotrun.read_text()
306
+read 1048576/1048576 bytes at offset 1048576
316
+
307
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
317
+ diff = file_diff(str(f_reference), str(f_bad))
308
+
318
+ if diff:
309
+== Resize tests ==
319
+ return TestResult(status='fail', elapsed=elapsed,
310
+=== preallocation=off ===
320
+ description=f'output mismatch (see {f_bad})',
311
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=6442450944 cluster_size=65536 lazy_refcounts=off refcount_bits=16
321
+ diff=diff, casenotrun=casenotrun)
312
+
322
+ else:
313
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=1073741824 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
323
+ f_bad.unlink()
314
+
324
+ self.last_elapsed.update(test, elapsed)
315
+wrote 65536/65536 bytes at offset 5368709120
325
+ return TestResult(status='pass', elapsed=elapsed,
316
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
326
+ casenotrun=casenotrun)
317
+
327
+
318
+Image resized.
328
+ def run_test(self, test: str,
319
+
329
+ test_field_width: Optional[int] = None) -> TestResult:
320
+read 65536/65536 bytes at offset 5368709120
330
+ last_el = self.last_elapsed.get(test)
321
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
331
+ start = datetime.datetime.now().strftime('%H:%M:%S')
322
+
332
+
323
+1 GiB (0x40000000) bytes not allocated at offset 0 bytes (0x0)
333
+ self.test_print_one_line(test=test, starttime=start, lasttime=last_el,
324
+7 GiB (0x1c0000000) bytes allocated at offset 1 GiB (0x40000000)
334
+ end='\r', test_field_width=test_field_width)
325
+
335
+
326
+[{ "start": 0, "length": 1073741824, "depth": 1, "zero": true, "data": false},
336
+ res = self.do_run_test(test)
327
+{ "start": 1073741824, "length": 7516192768, "depth": 0, "zero": true, "data": false}]
337
+
328
+
338
+ end = datetime.datetime.now().strftime('%H:%M:%S')
329
+=== preallocation=metadata ===
339
+ self.test_print_one_line(test=test, status=res.status,
330
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=34359738368 cluster_size=65536 lazy_refcounts=off refcount_bits=16
340
+ starttime=start, endtime=end,
331
+
341
+ lasttime=last_el, thistime=res.elapsed,
332
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=32212254720 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
342
+ description=res.description,
333
+
343
+ test_field_width=test_field_width)
334
+wrote 65536/65536 bytes at offset 33285996544
344
+
335
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
345
+ if res.casenotrun:
336
+
346
+ print(res.casenotrun)
337
+Image resized.
347
+
338
+
348
+ return res
339
+read 65536/65536 bytes at offset 33285996544
349
+
340
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
350
+ def run_tests(self, tests: List[str]) -> None:
341
+
351
+ n_run = 0
342
+30 GiB (0x780000000) bytes not allocated at offset 0 bytes (0x0)
352
+ failed = []
343
+3 GiB (0xc0000000) bytes allocated at offset 30 GiB (0x780000000)
353
+ notrun = []
344
+
354
+ casenotrun = []
345
+[{ "start": 0, "length": 32212254720, "depth": 1, "zero": true, "data": false},
355
+
346
+{ "start": 32212254720, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 327680},
356
+ if not self.makecheck:
347
+{ "start": 32749125632, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 537264128},
357
+ self.env.print_env()
348
+{ "start": 33285996544, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 1074200576},
358
+ print()
349
+{ "start": 33822867456, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 1611137024},
359
+
350
+{ "start": 34359738368, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 2148139008},
360
+ test_field_width = max(len(os.path.basename(t)) for t in tests) + 2
351
+{ "start": 34896609280, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 2685075456}]
361
+
352
+
362
+ for t in tests:
353
+=== preallocation=falloc ===
363
+ name = os.path.basename(t)
354
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=10485760 cluster_size=65536 lazy_refcounts=off refcount_bits=16
364
+ res = self.run_test(t, test_field_width=test_field_width)
355
+
365
+
356
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=5242880 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
366
+ assert res.status in ('pass', 'fail', 'not run')
357
+
367
+
358
+wrote 65536/65536 bytes at offset 9437184
368
+ if res.casenotrun:
359
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
369
+ casenotrun.append(t)
360
+
370
+
361
+Image resized.
371
+ if res.status != 'not run':
362
+
372
+ n_run += 1
363
+read 65536/65536 bytes at offset 9437184
373
+
364
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
374
+ if res.status == 'fail':
365
+
375
+ failed.append(name)
366
+5 MiB (0x500000) bytes not allocated at offset 0 bytes (0x0)
376
+ if self.makecheck:
367
+10 MiB (0xa00000) bytes allocated at offset 5 MiB (0x500000)
377
+ self.env.print_env()
368
+
378
+ if res.diff:
369
+[{ "start": 0, "length": 5242880, "depth": 1, "zero": true, "data": false},
379
+ print('\n'.join(res.diff))
370
+{ "start": 5242880, "length": 10485760, "depth": 0, "zero": true, "data": false, "offset": 327680}]
380
+ elif res.status == 'not run':
371
+
381
+ notrun.append(name)
372
+=== preallocation=full ===
382
+
373
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=16777216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
383
+ if res.interrupted:
374
+
384
+ break
375
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=8388608 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
385
+
376
+
386
+ if notrun:
377
+wrote 65536/65536 bytes at offset 11534336
387
+ print('Not run:', ' '.join(notrun))
378
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
388
+
379
+
389
+ if casenotrun:
380
+Image resized.
390
+ print('Some cases not run in:', ' '.join(casenotrun))
381
+
391
+
382
+read 65536/65536 bytes at offset 11534336
392
+ if failed:
383
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
393
+ print('Failures:', ' '.join(failed))
384
+
394
+ print(f'Failed {len(failed)} of {n_run} iotests')
385
+8 MiB (0x800000) bytes not allocated at offset 0 bytes (0x0)
395
+ else:
386
+4 MiB (0x400000) bytes allocated at offset 8 MiB (0x800000)
396
+ print(f'Passed all {n_run} iotests')
387
+
388
+[{ "start": 0, "length": 8388608, "depth": 1, "zero": true, "data": false},
389
+{ "start": 8388608, "length": 4194304, "depth": 0, "zero": true, "data": false, "offset": 327680}]
390
+
391
+=== preallocation=off ===
392
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=393216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
393
+
394
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=259072 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
395
+
396
+wrote 65536/65536 bytes at offset 259072
397
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
398
+
399
+Image resized.
400
+
401
+read 65536/65536 bytes at offset 259072
402
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
403
+
404
+192 KiB (0x30000) bytes not allocated at offset 0 bytes (0x0)
405
+320 KiB (0x50000) bytes allocated at offset 192 KiB (0x30000)
406
+
407
+[{ "start": 0, "length": 196608, "depth": 1, "zero": true, "data": false},
408
+{ "start": 196608, "length": 65536, "depth": 0, "zero": false, "data": true, "offset": 327680},
409
+{ "start": 262144, "length": 262144, "depth": 0, "zero": true, "data": false}]
410
+
411
+=== preallocation=off ===
412
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=409600 cluster_size=65536 lazy_refcounts=off refcount_bits=16
413
+
414
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=262144 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
415
+
416
+wrote 65536/65536 bytes at offset 344064
417
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
418
+
419
+Image resized.
420
+
421
+read 65536/65536 bytes at offset 344064
422
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
423
+
424
+256 KiB (0x40000) bytes not allocated at offset 0 bytes (0x0)
425
+256 KiB (0x40000) bytes allocated at offset 256 KiB (0x40000)
426
+
427
+[{ "start": 0, "length": 262144, "depth": 1, "zero": true, "data": false},
428
+{ "start": 262144, "length": 262144, "depth": 0, "zero": true, "data": false}]
429
+
430
+=== preallocation=off ===
431
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=524288 cluster_size=65536 lazy_refcounts=off refcount_bits=16
432
+
433
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=262144 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
434
+
435
+wrote 65536/65536 bytes at offset 446464
436
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
437
+
438
+Image resized.
439
+
440
+read 65536/65536 bytes at offset 446464
441
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
442
+
443
+256 KiB (0x40000) bytes not allocated at offset 0 bytes (0x0)
444
+244 KiB (0x3d000) bytes allocated at offset 256 KiB (0x40000)
445
+
446
+[{ "start": 0, "length": 262144, "depth": 1, "zero": true, "data": false},
447
+{ "start": 262144, "length": 249856, "depth": 0, "zero": true, "data": false}]
448
+
449
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
450
index XXXXXXX..XXXXXXX 100644
451
--- a/tests/qemu-iotests/group
452
+++ b/tests/qemu-iotests/group
453
@@ -XXX,XX +XXX,XX @@
454
270 rw backing quick
455
272 rw
456
273 backing quick
457
+274 rw backing
458
277 rw quick
459
279 rw backing quick
460
280 rw migration quick
461
--
397
--
462
2.25.3
398
2.29.2
463
399
464
400
diff view generated by jsdifflib
1
We want to keep TEST_IMG for the full path of the main test image, but
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
filter_testfiles() must be called for other test images before replacing
3
other things like the image format because the test directory path could
4
contain the format as a substring.
5
2
6
Insert a filter_testfiles() call between both.
3
Just use classes introduced in previous three commits. Behavior
4
difference is described in these three commits.
7
5
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Drop group file, as it becomes unused.
9
Reviewed-by: Max Reitz <mreitz@redhat.com>
7
10
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Drop common.env: now check is in python, and for tests we use same
11
Message-Id: <20200424125448.63318-9-kwolf@redhat.com>
9
python interpreter that runs the check itself. Use build environment
10
PYTHON in check-block instead, to keep "make check" use the same
11
python.
12
13
Checking for virtio-blk moved to iotests.py, as it actually iotests.py
14
dependency. Actually not all python iotests depend on it, so in future
15
it may be refactored to checked only when really needed.
16
17
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
18
Message-Id: <20210125185056.129513-6-vsementsov@virtuozzo.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
19
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
20
---
14
tests/qemu-iotests/iotests.py | 5 +++--
21
tests/qemu-iotests/iotests.py | 8 +
15
1 file changed, 3 insertions(+), 2 deletions(-)
22
Makefile | 1 -
23
tests/check-block.sh | 3 +-
24
tests/qemu-iotests/check | 1095 ++++--------------------------
25
tests/qemu-iotests/common.env.in | 3 -
26
tests/qemu-iotests/group | 323 ---------
27
tests/qemu-iotests/meson.build | 3 -
28
7 files changed, 139 insertions(+), 1297 deletions(-)
29
delete mode 100644 tests/qemu-iotests/common.env.in
30
delete mode 100644 tests/qemu-iotests/group
16
31
17
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
32
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
18
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
19
--- a/tests/qemu-iotests/iotests.py
34
--- a/tests/qemu-iotests/iotests.py
20
+++ b/tests/qemu-iotests/iotests.py
35
+++ b/tests/qemu-iotests/iotests.py
21
@@ -XXX,XX +XXX,XX @@ def filter_img_info(output, filename):
36
@@ -XXX,XX +XXX,XX @@ def _verify_formats(required_formats: Sequence[str] = ()) -> None:
22
for line in output.split('\n'):
37
if usf_list:
23
if 'disk size' in line or 'actual-size' in line:
38
notrun(f'formats {usf_list} are not whitelisted')
24
continue
39
25
- line = line.replace(filename, 'TEST_IMG') \
40
+
26
- .replace(imgfmt, 'IMGFMT')
41
+def _verify_virtio_blk() -> None:
27
+ line = line.replace(filename, 'TEST_IMG')
42
+ out = qemu_pipe('-M', 'none', '-device', 'help')
28
+ line = filter_testfiles(line)
43
+ if 'virtio-blk' not in out:
29
+ line = line.replace(imgfmt, 'IMGFMT')
44
+ notrun('Missing virtio-blk in QEMU binary')
30
line = re.sub('iters: [0-9]+', 'iters: XXX', line)
45
+
31
line = re.sub('uuid: [-a-f0-9]+', 'uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX', line)
46
+
32
line = re.sub('cid: [0-9]+', 'cid: XXXXXXXXXX', line)
47
def supports_quorum():
48
return 'quorum' in qemu_img_pipe('--help')
49
50
@@ -XXX,XX +XXX,XX @@ def execute_setup_common(supported_fmts: Sequence[str] = (),
51
_verify_cache_mode(supported_cache_modes)
52
_verify_aio_mode(supported_aio_modes)
53
_verify_formats(required_fmts)
54
+ _verify_virtio_blk()
55
56
return debug
57
58
diff --git a/Makefile b/Makefile
59
index XXXXXXX..XXXXXXX 100644
60
--- a/Makefile
61
+++ b/Makefile
62
@@ -XXX,XX +XXX,XX @@ distclean: clean
63
    rm -f config-host.mak config-host.h*
64
    rm -f tests/tcg/config-*.mak
65
    rm -f config-all-disas.mak config.status
66
-    rm -f tests/qemu-iotests/common.env
67
    rm -f roms/seabios/config.mak roms/vgabios/config.mak
68
    rm -f qemu-plugins-ld.symbols qemu-plugins-ld64.symbols
69
    rm -f *-config-target.h *-config-devices.mak *-config-devices.h
70
diff --git a/tests/check-block.sh b/tests/check-block.sh
71
index XXXXXXX..XXXXXXX 100755
72
--- a/tests/check-block.sh
73
+++ b/tests/check-block.sh
74
@@ -XXX,XX +XXX,XX @@ cd tests/qemu-iotests
75
76
# QEMU_CHECK_BLOCK_AUTO is used to disable some unstable sub-tests
77
export QEMU_CHECK_BLOCK_AUTO=1
78
+export PYTHONUTF8=1
79
80
ret=0
81
for fmt in $format_list ; do
82
- ./check -makecheck -$fmt $group || ret=1
83
+ ${PYTHON} ./check -makecheck -$fmt $group || ret=1
84
done
85
86
exit $ret
87
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
88
index XXXXXXX..XXXXXXX 100755
89
--- a/tests/qemu-iotests/check
90
+++ b/tests/qemu-iotests/check
91
@@ -XXX,XX +XXX,XX @@
92
-#!/usr/bin/env bash
93
+#!/usr/bin/env python3
94
#
95
-# Copyright (C) 2009 Red Hat, Inc.
96
-# Copyright (c) 2000-2002,2006 Silicon Graphics, Inc. All Rights Reserved.
97
+# Configure environment and run group of tests in it.
98
+#
99
+# Copyright (c) 2020-2021 Virtuozzo International GmbH
100
#
101
# This program is free software; you can redistribute it and/or
102
# modify it under the terms of the GNU General Public License as
103
@@ -XXX,XX +XXX,XX @@
104
#
105
# You should have received a copy of the GNU General Public License
106
# along with this program. If not, see <http://www.gnu.org/licenses/>.
107
-#
108
-#
109
-# Control script for QA
110
-#
111
-
112
-status=0
113
-needwrap=true
114
-try=0
115
-n_bad=0
116
-bad=""
117
-notrun=""
118
-casenotrun=""
119
-interrupt=true
120
-makecheck=false
121
-
122
-_init_error()
123
-{
124
- echo "check: $1" >&2
125
- exit 1
126
-}
127
-
128
-if [ -L "$0" ]
129
-then
130
- # called from the build tree
131
- source_iotests=$(dirname "$(readlink "$0")")
132
- if [ -z "$source_iotests" ]
133
- then
134
- _init_error "failed to obtain source tree name from check symlink"
135
- fi
136
- source_iotests=$(cd "$source_iotests"; pwd) || _init_error "failed to enter source tree"
137
- build_iotests=$(cd "$(dirname "$0")"; pwd)
138
-else
139
- # called from the source tree
140
- source_iotests=$PWD
141
- # this may be an in-tree build (note that in the following code we may not
142
- # assume that it truly is and have to test whether the build results
143
- # actually exist)
144
- build_iotests=$PWD
145
-fi
146
-
147
-build_root="$build_iotests/../.."
148
-
149
-# we need common.env
150
-if ! . "$build_iotests/common.env"
151
-then
152
- _init_error "failed to source common.env (make sure the qemu-iotests are run from tests/qemu-iotests in the build tree)"
153
-fi
154
-
155
-# we need common.config
156
-if ! . "$source_iotests/common.config"
157
-then
158
- _init_error "failed to source common.config"
159
-fi
160
-
161
-_full_imgfmt_details()
162
-{
163
- if [ -n "$IMGOPTS" ]; then
164
- echo "$IMGFMT ($IMGOPTS)"
165
- else
166
- echo "$IMGFMT"
167
- fi
168
-}
169
-
170
-_full_platform_details()
171
-{
172
- os=$(uname -s)
173
- host=$(hostname -s)
174
- kernel=$(uname -r)
175
- platform=$(uname -m)
176
- echo "$os/$platform $host $kernel"
177
-}
178
-
179
-_full_env_details()
180
-{
181
- cat <<EOF
182
-QEMU -- "$QEMU_PROG" $QEMU_OPTIONS
183
-QEMU_IMG -- "$QEMU_IMG_PROG" $QEMU_IMG_OPTIONS
184
-QEMU_IO -- "$QEMU_IO_PROG" $QEMU_IO_OPTIONS
185
-QEMU_NBD -- "$QEMU_NBD_PROG" $QEMU_NBD_OPTIONS
186
-IMGFMT -- $FULL_IMGFMT_DETAILS
187
-IMGPROTO -- $IMGPROTO
188
-PLATFORM -- $FULL_HOST_DETAILS
189
-TEST_DIR -- $TEST_DIR
190
-SOCK_DIR -- $SOCK_DIR
191
-SOCKET_SCM_HELPER -- $SOCKET_SCM_HELPER
192
-
193
-EOF
194
-}
195
-
196
-# $1 = prog to look for
197
-set_prog_path()
198
-{
199
- p=$(command -v $1 2> /dev/null)
200
- if [ -n "$p" -a -x "$p" ]; then
201
- type -p "$p"
202
- else
203
- return 1
204
- fi
205
-}
206
-
207
-if [ -z "$TEST_DIR" ]; then
208
- TEST_DIR=$PWD/scratch
209
-fi
210
-mkdir -p "$TEST_DIR" || _init_error 'Failed to create TEST_DIR'
211
-
212
-tmp_sock_dir=false
213
-if [ -z "$SOCK_DIR" ]; then
214
- SOCK_DIR=$(mktemp -d)
215
- tmp_sock_dir=true
216
-fi
217
-mkdir -p "$SOCK_DIR" || _init_error 'Failed to create SOCK_DIR'
218
-
219
-diff="diff -u"
220
-verbose=false
221
-debug=false
222
-group=false
223
-xgroup=false
224
-imgopts=false
225
-showme=false
226
-sortme=false
227
-expunge=true
228
-have_test_arg=false
229
-cachemode=false
230
-aiomode=false
231
-
232
-tmp="${TEST_DIR}"/$$
233
-rm -f $tmp.list $tmp.tmp $tmp.sed
234
-
235
-export IMGFMT=raw
236
-export IMGFMT_GENERIC=true
237
-export IMGPROTO=file
238
-export IMGOPTS=""
239
-export CACHEMODE="writeback"
240
-export AIOMODE="threads"
241
-export QEMU_IO_OPTIONS=""
242
-export QEMU_IO_OPTIONS_NO_FMT=""
243
-export CACHEMODE_IS_DEFAULT=true
244
-export VALGRIND_QEMU=
245
-export IMGKEYSECRET=
246
-export IMGOPTSSYNTAX=false
247
-
248
-# Save current tty settings, since an aborting qemu call may leave things
249
-# screwed up
250
-STTY_RESTORE=
251
-if test -t 0; then
252
- STTY_RESTORE=$(stty -g)
253
-fi
254
-
255
-for r
256
-do
257
-
258
- if $group
259
- then
260
- # arg after -g
261
- group_list=$(sed -n <"$source_iotests/group" -e 's/$/ /' -e "/^[0-9][0-9][0-9].* $r /"'{
262
-s/ .*//p
263
-}')
264
- if [ -z "$group_list" ]
265
- then
266
- echo "Group \"$r\" is empty or not defined?"
267
- exit 1
268
- fi
269
- [ ! -s $tmp.list ] && touch $tmp.list
270
- for t in $group_list
271
- do
272
- if grep -s "^$t\$" $tmp.list >/dev/null
273
- then
274
- :
275
- else
276
- echo "$t" >>$tmp.list
277
- fi
278
- done
279
- group=false
280
- continue
281
-
282
- elif $xgroup
283
- then
284
- # arg after -x
285
- # Populate $tmp.list with all tests
286
- awk '/^[0-9]{3,}/ {print $1}' "${source_iotests}/group" > $tmp.list 2>/dev/null
287
- group_list=$(sed -n <"$source_iotests/group" -e 's/$/ /' -e "/^[0-9][0-9][0-9].* $r /"'{
288
-s/ .*//p
289
-}')
290
- if [ -z "$group_list" ]
291
- then
292
- echo "Group \"$r\" is empty or not defined?"
293
- exit 1
294
- fi
295
- numsed=0
296
- rm -f $tmp.sed
297
- for t in $group_list
298
- do
299
- if [ $numsed -gt 100 ]
300
- then
301
- sed -f $tmp.sed <$tmp.list >$tmp.tmp
302
- mv $tmp.tmp $tmp.list
303
- numsed=0
304
- rm -f $tmp.sed
305
- fi
306
- echo "/^$t\$/d" >>$tmp.sed
307
- numsed=$(expr $numsed + 1)
308
- done
309
- sed -f $tmp.sed <$tmp.list >$tmp.tmp
310
- mv $tmp.tmp $tmp.list
311
- xgroup=false
312
- continue
313
-
314
- elif $imgopts
315
- then
316
- IMGOPTS="$r"
317
- imgopts=false
318
- continue
319
- elif $cachemode
320
- then
321
- CACHEMODE="$r"
322
- CACHEMODE_IS_DEFAULT=false
323
- cachemode=false
324
- continue
325
- elif $aiomode
326
- then
327
- AIOMODE="$r"
328
- aiomode=false
329
- continue
330
- fi
331
-
332
- xpand=true
333
- case "$r"
334
- in
335
-
336
- -\? | -h | --help) # usage
337
- echo "Usage: $0 [options] [testlist]"'
338
-
339
-common options
340
- -v verbose
341
- -d debug
342
-
343
-image format options
344
- -raw test raw (default)
345
- -bochs test bochs
346
- -cloop test cloop
347
- -parallels test parallels
348
- -qcow test qcow
349
- -qcow2 test qcow2
350
- -qed test qed
351
- -vdi test vdi
352
- -vpc test vpc
353
- -vhdx test vhdx
354
- -vmdk test vmdk
355
- -luks test luks
356
- -dmg test dmg
357
-
358
-image protocol options
359
- -file test file (default)
360
- -rbd test rbd
361
- -sheepdog test sheepdog
362
- -nbd test nbd
363
- -fuse test fuse
364
- -ssh test ssh
365
- -nfs test nfs
366
-
367
-other options
368
- -xdiff graphical mode diff
369
- -nocache use O_DIRECT on backing file
370
- -misalign misalign memory allocations
371
- -n show me, do not run tests
372
- -o options -o options to pass to qemu-img create/convert
373
- -c mode cache mode
374
- -i mode AIO mode
375
- -makecheck pretty print output for make check
376
-
377
-testlist options
378
- -g group[,group...] include tests from these groups
379
- -x group[,group...] exclude tests from these groups
380
- NNN include test NNN
381
- NNN-NNN include test range (eg. 012-021)
382
-'
383
- exit 0
384
- ;;
385
-
386
- -raw)
387
- IMGFMT=raw
388
- xpand=false
389
- ;;
390
-
391
- -bochs)
392
- IMGFMT=bochs
393
- IMGFMT_GENERIC=false
394
- xpand=false
395
- ;;
396
-
397
- -cloop)
398
- IMGFMT=cloop
399
- IMGFMT_GENERIC=false
400
- xpand=false
401
- ;;
402
-
403
- -parallels)
404
- IMGFMT=parallels
405
- xpand=false
406
- ;;
407
-
408
- -qcow)
409
- IMGFMT=qcow
410
- xpand=false
411
- ;;
412
-
413
- -qcow2)
414
- IMGFMT=qcow2
415
- xpand=false
416
- ;;
417
-
418
- -luks)
419
- IMGOPTSSYNTAX=true
420
- IMGFMT=luks
421
- IMGKEYSECRET=123456
422
- xpand=false
423
- ;;
424
-
425
- -dmg)
426
- IMGFMT=dmg
427
- IMGFMT_GENERIC=false
428
- xpand=false
429
- ;;
430
-
431
- -qed)
432
- IMGFMT=qed
433
- xpand=false
434
- ;;
435
-
436
- -vdi)
437
- IMGFMT=vdi
438
- xpand=false
439
- ;;
440
-
441
- -vmdk)
442
- IMGFMT=vmdk
443
- xpand=false
444
- ;;
445
-
446
- -vpc)
447
- IMGFMT=vpc
448
- xpand=false
449
- ;;
450
-
451
- -vhdx)
452
- IMGFMT=vhdx
453
- xpand=false
454
- ;;
455
-
456
- -file)
457
- IMGPROTO=file
458
- xpand=false
459
- ;;
460
-
461
- -rbd)
462
- IMGPROTO=rbd
463
- xpand=false
464
- ;;
465
-
466
- -sheepdog)
467
- IMGPROTO=sheepdog
468
- xpand=false
469
- ;;
470
-
471
- -nbd)
472
- IMGPROTO=nbd
473
- xpand=false
474
- ;;
475
-
476
- -fuse)
477
- IMGPROTO=fuse
478
- xpand=false
479
- ;;
480
-
481
- -ssh)
482
- IMGPROTO=ssh
483
- xpand=false
484
- ;;
485
-
486
- -nfs)
487
- IMGPROTO=nfs
488
- xpand=false
489
- ;;
490
-
491
- -nocache)
492
- CACHEMODE="none"
493
- CACHEMODE_IS_DEFAULT=false
494
- xpand=false
495
- ;;
496
-
497
- -misalign)
498
- QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS --misalign"
499
- xpand=false
500
- ;;
501
-
502
- -valgrind)
503
- VALGRIND_QEMU='y'
504
- xpand=false
505
- ;;
506
-
507
- -g) # -g group ... pick from group file
508
- group=true
509
- xpand=false
510
- ;;
511
-
512
- -xdiff) # graphical diff mode
513
- xpand=false
514
-
515
- if [ ! -z "$DISPLAY" ]
516
- then
517
- command -v xdiff >/dev/null 2>&1 && diff=xdiff
518
- command -v gdiff >/dev/null 2>&1 && diff=gdiff
519
- command -v tkdiff >/dev/null 2>&1 && diff=tkdiff
520
- command -v xxdiff >/dev/null 2>&1 && diff=xxdiff
521
- fi
522
- ;;
523
- -makecheck) # makecheck friendly output
524
- makecheck=true
525
- xpand=false
526
- ;;
527
- -n) # show me, don't do it
528
- showme=true
529
- xpand=false
530
- ;;
531
- -o)
532
- imgopts=true
533
- xpand=false
534
- ;;
535
- -c)
536
- cachemode=true
537
- xpand=false
538
- ;;
539
- -i)
540
- aiomode=true
541
- xpand=false
542
- ;;
543
- -T) # deprecated timestamp option
544
- xpand=false
545
- ;;
546
- -v)
547
- verbose=true
548
- xpand=false
549
- ;;
550
- -d)
551
- debug=true
552
- xpand=false
553
- ;;
554
- -x) # -x group ... exclude from group file
555
- xgroup=true
556
- xpand=false
557
- ;;
558
- '[0-9][0-9][0-9] [0-9][0-9][0-9][0-9]')
559
- echo "No tests?"
560
- status=1
561
- exit $status
562
- ;;
563
-
564
- [0-9]*-[0-9]*)
565
- eval $(echo $r | sed -e 's/^/start=/' -e 's/-/ end=/')
566
- ;;
567
-
568
- [0-9]*-)
569
- eval $(echo $r | sed -e 's/^/start=/' -e 's/-//')
570
- end=$(echo [0-9][0-9][0-9] [0-9][0-9][0-9][0-9] | sed -e 's/\[0-9]//g' -e 's/ *$//' -e 's/.* //')
571
- if [ -z "$end" ]
572
- then
573
- echo "No tests in range \"$r\"?"
574
- status=1
575
- exit $status
576
- fi
577
- ;;
578
-
579
- *)
580
- start=$r
581
- end=$r
582
- ;;
583
-
584
- esac
585
-
586
- # get rid of leading 0s as can be interpreted as octal
587
- start=$(echo $start | sed 's/^0*//')
588
- end=$(echo $end | sed 's/^0*//')
589
-
590
- if $xpand
591
- then
592
- have_test_arg=true
593
- awk </dev/null '
594
-BEGIN { for (t='$start'; t<='$end'; t++) printf "%03d\n",t }' \
595
- | while read id
596
- do
597
- if grep -s "^$id\( \|\$\)" "$source_iotests/group" >/dev/null
598
- then
599
- # in group file ... OK
600
- echo $id >>$tmp.list
601
- else
602
- if [ -f expunged ] && $expunge && egrep "^$id([ ]|\$)" expunged >/dev/null
603
- then
604
- # expunged ... will be reported, but not run, later
605
- echo $id >>$tmp.list
606
- else
607
- # oops
608
- if [ "$start" == "$end" -a "$id" == "$end" ]
609
- then
610
- echo "$id - unknown test"
611
- exit 1
612
- else
613
- echo "$id - unknown test, ignored"
614
- fi
615
- fi
616
- fi
617
- done || exit 1
618
- fi
619
-
620
-done
621
-
622
-# Set qemu-io cache mode with $CACHEMODE we have
623
-QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS --cache $CACHEMODE"
624
-# Set qemu-io aio mode with $AIOMODE we have
625
-QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS --aio $AIOMODE"
626
-
627
-QEMU_IO_OPTIONS_NO_FMT="$QEMU_IO_OPTIONS"
628
-if [ "$IMGOPTSSYNTAX" != "true" ]; then
629
- QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS -f $IMGFMT"
630
-fi
631
-
632
-# Set default options for qemu-img create -o if they were not specified
633
-if [ "$IMGFMT" == "qcow2" ] && ! (echo "$IMGOPTS" | grep "compat=" > /dev/null); then
634
- IMGOPTS=$(_optstr_add "$IMGOPTS" "compat=1.1")
635
-fi
636
-if [ "$IMGFMT" == "luks" ] && ! (echo "$IMGOPTS" | grep "iter-time=" > /dev/null); then
637
- IMGOPTS=$(_optstr_add "$IMGOPTS" "iter-time=10")
638
-fi
639
-if [ "$IMGFMT" == "vmdk" ] && ! (echo "$IMGOPTS" | grep "zeroed_grain=" > /dev/null); then
640
- IMGOPTS=$(_optstr_add "$IMGOPTS" "zeroed_grain=on")
641
-fi
642
-
643
-if [ -z "$SAMPLE_IMG_DIR" ]; then
644
- SAMPLE_IMG_DIR="$source_iotests/sample_images"
645
-fi
646
-
647
-export TEST_DIR
648
-export SOCK_DIR
649
-export SAMPLE_IMG_DIR
650
-
651
-if [ -s $tmp.list ]
652
-then
653
- # found some valid test numbers ... this is good
654
- :
655
-else
656
- if $have_test_arg
657
- then
658
- # had test numbers, but none in group file ... do nothing
659
- touch $tmp.list
660
- else
661
- # no test numbers, do everything from group file
662
- sed -n -e '/^[0-9][0-9][0-9]*/s/^\([0-9]*\).*/\1/p' <"$source_iotests/group" >$tmp.list
663
- fi
664
-fi
665
-
666
-# should be sort -n, but this did not work for Linux when this
667
-# was ported from IRIX
668
-#
669
-list=$(sort $tmp.list)
670
-rm -f $tmp.list $tmp.tmp $tmp.sed
671
-
672
-if [ -z "$QEMU_PROG" ]
673
-then
674
- if [ -x "$build_iotests/qemu" ]; then
675
- export QEMU_PROG="$build_iotests/qemu"
676
- elif [ -x "$build_root/qemu-system-${qemu_arch}" ]; then
677
- export QEMU_PROG="$build_root/qemu-system-${qemu_arch}"
678
- else
679
- pushd "$build_root" > /dev/null
680
- for binary in qemu-system-*
681
- do
682
- if [ -x "$binary" ]
683
- then
684
- export QEMU_PROG="$build_root/$binary"
685
- break
686
- fi
687
- done
688
- popd > /dev/null
689
- [ "$QEMU_PROG" = "" ] && _init_error "qemu not found"
690
- fi
691
-fi
692
-export QEMU_PROG="$(type -p "$QEMU_PROG")"
693
-
694
-export QEMU_OPTIONS="-nodefaults -display none -accel qtest"
695
-case "$QEMU_PROG" in
696
- *qemu-system-arm|*qemu-system-aarch64)
697
- export QEMU_OPTIONS="$QEMU_OPTIONS -machine virt"
698
- ;;
699
- *qemu-system-avr)
700
- export QEMU_OPTIONS="$QEMU_OPTIONS -machine mega2560"
701
- ;;
702
- *qemu-system-rx)
703
- export QEMU_OPTIONS="$QEMU_OPTIONS -machine gdbsim-r5f562n8"
704
- ;;
705
- *qemu-system-tricore)
706
- export QEMU_OPTIONS="-$QEMU_OPTIONS -machine tricore_testboard"
707
- ;;
708
-esac
709
-
710
-if [ -z "$QEMU_IMG_PROG" ]; then
711
- if [ -x "$build_iotests/qemu-img" ]; then
712
- export QEMU_IMG_PROG="$build_iotests/qemu-img"
713
- elif [ -x "$build_root/qemu-img" ]; then
714
- export QEMU_IMG_PROG="$build_root/qemu-img"
715
- else
716
- _init_error "qemu-img not found"
717
- fi
718
-fi
719
-export QEMU_IMG_PROG="$(type -p "$QEMU_IMG_PROG")"
720
-
721
-if [ -z "$QEMU_IO_PROG" ]; then
722
- if [ -x "$build_iotests/qemu-io" ]; then
723
- export QEMU_IO_PROG="$build_iotests/qemu-io"
724
- elif [ -x "$build_root/qemu-io" ]; then
725
- export QEMU_IO_PROG="$build_root/qemu-io"
726
- else
727
- _init_error "qemu-io not found"
728
- fi
729
-fi
730
-export QEMU_IO_PROG="$(type -p "$QEMU_IO_PROG")"
731
-
732
-if [ -z $QEMU_NBD_PROG ]; then
733
- if [ -x "$build_iotests/qemu-nbd" ]; then
734
- export QEMU_NBD_PROG="$build_iotests/qemu-nbd"
735
- elif [ -x "$build_root/qemu-nbd" ]; then
736
- export QEMU_NBD_PROG="$build_root/qemu-nbd"
737
- else
738
- _init_error "qemu-nbd not found"
739
- fi
740
-fi
741
-export QEMU_NBD_PROG="$(type -p "$QEMU_NBD_PROG")"
742
-
743
-if [ -z "$QSD_PROG" ]; then
744
- if [ -x "$build_iotests/qemu-storage-daemon" ]; then
745
- export QSD_PROG="$build_iotests/qemu-storage-daemon"
746
- elif [ -x "$build_root/storage-daemon/qemu-storage-daemon" ]; then
747
- export QSD_PROG="$build_root/storage-daemon/qemu-storage-daemon"
748
- else
749
- _init_error "qemu-storage-daemon not found"
750
- fi
751
-fi
752
-export QSD_PROG="$(type -p "$QSD_PROG")"
753
-
754
-if [ -x "$build_iotests/socket_scm_helper" ]
755
-then
756
- export SOCKET_SCM_HELPER="$build_iotests/socket_scm_helper"
757
-fi
758
-
759
-python_usable=false
760
-if $PYTHON -c 'import sys; sys.exit(0 if sys.version_info >= (3,6) else 1)'
761
-then
762
- # Our python framework also requires virtio-blk
763
- if "$QEMU_PROG" -M none -device help | grep -q virtio-blk >/dev/null 2>&1
764
- then
765
- python_usable=true
766
- else
767
- python_unusable_because="Missing virtio-blk in QEMU binary"
768
- fi
769
-else
770
- python_unusable_because="Unsupported Python version"
771
-fi
772
-
773
-default_machine=$($QEMU_PROG -machine help | sed -n '/(default)/ s/ .*//p')
774
-default_alias_machine=$($QEMU_PROG -machine help | \
775
- sed -n "/(alias of $default_machine)/ { s/ .*//p; q; }")
776
-if [[ "$default_alias_machine" ]]; then
777
- default_machine="$default_alias_machine"
778
-fi
779
-
780
-export QEMU_DEFAULT_MACHINE="$default_machine"
781
-
782
-TIMESTAMP_FILE=check.time-$IMGPROTO-$IMGFMT
783
-
784
-_wallclock()
785
-{
786
- date "+%H %M %S" | awk '{ print $1*3600 + $2*60 + $3 }'
787
-}
788
-
789
-_wrapup()
790
-{
791
- if $showme
792
- then
793
- :
794
- elif $needwrap
795
- then
796
- if [ -f $TIMESTAMP_FILE -a -f $tmp.time ]
797
- then
798
- cat $TIMESTAMP_FILE $tmp.time \
799
- | awk '
800
- { t[$1] = $2 }
801
-END { if (NR > 0) {
802
- for (i in t) print i " " t[i]
803
- }
804
- }' \
805
- | sort -n >$tmp.out
806
- mv $tmp.out $TIMESTAMP_FILE
807
- fi
808
-
809
- if [ -f $tmp.expunged ]
810
- then
811
- notrun=$(wc -l <$tmp.expunged | sed -e 's/ *//g')
812
- try=$(expr $try - $notrun)
813
- list=$(echo "$list" | sed -f $tmp.expunged)
814
- fi
815
-
816
- echo "" >>check.log
817
- date >>check.log
818
- echo $list | fmt | sed -e 's/^/ /' >>check.log
819
- $interrupt && echo "Interrupted!" >>check.log
820
-
821
- if [ ! -z "$notrun" ]
822
- then
823
- echo "Not run:$notrun"
824
- echo "Not run:$notrun" >>check.log
825
- fi
826
- if [ ! -z "$casenotrun" ]
827
- then
828
- echo "Some cases not run in:$casenotrun"
829
- echo "Some cases not run in:$casenotrun" >>check.log
830
- fi
831
- if [ ! -z "$n_bad" -a $n_bad != 0 ]
832
- then
833
- echo "Failures:$bad"
834
- echo "Failed $n_bad of $try iotests"
835
- echo "Failures:$bad" | fmt >>check.log
836
- echo "Failed $n_bad of $try iotests" >>check.log
837
- else
838
- echo "Passed all $try iotests"
839
- echo "Passed all $try iotests" >>check.log
840
- fi
841
- needwrap=false
842
- fi
843
-
844
- if test -n "$STTY_RESTORE"; then
845
- stty $STTY_RESTORE
846
- fi
847
- rm -f "${TEST_DIR}"/*.out "${TEST_DIR}"/*.err "${TEST_DIR}"/*.time
848
- rm -f "${TEST_DIR}"/check.pid "${TEST_DIR}"/check.sts
849
- rm -f $tmp.*
850
-
851
- if $tmp_sock_dir
852
- then
853
- rm -rf "$SOCK_DIR"
854
- fi
855
-}
856
-
857
-trap "_wrapup; exit \$status" 0 1 2 3 15
858
-
859
-# Report the test start and results. For makecheck we want to pretty
860
-# print the whole report at the end of the execution.
861
-# args: $seq, $starttime, $lasttime
862
-_report_test_start()
863
-{
864
- if ! $makecheck; then
865
- if [ -n "$3" ]; then
866
- local lasttime=" (last: $3s)"
867
- fi
868
- printf "%-8s %-10s [%s] %4s%-14s\r" "$1" "..." "$2" "..." "$lasttime"
869
- fi
870
-}
871
-# args:$seq $status $starttime $lasttime $thistime $details
872
-_report_test_result()
873
-{
874
- local status lasttime thistime
875
- if $makecheck; then
876
- if [ -n "$2" ] && [ "$2" != "pass" ]; then
877
- status=" [$2]"
878
- fi
879
- printf " TEST iotest-$IMGFMT: %s%s\n" "$1" "$status"
880
- return
881
- fi
882
-
883
- if [ -n "$4" ]; then
884
- lasttime=" (last: $4s)"
885
- fi
886
- if [ -n "$5" ]; then
887
- thistime=" $5s"
888
- fi
889
- case "$2" in
890
- "pass") status=$(printf "\e[32m%-10s\e[0m" "$2") ;;
891
- "fail") status=$(printf "\e[1m\e[31m%-10s\e[0m" "$2") ;;
892
- "not run") status=$(printf "\e[33m%-10s\e[0m" "$2") ;;
893
- *) status=$(printf "%-10s" "$2") ;;
894
- esac
895
-
896
- printf "%-8s %s [%s] [%s] %4s%-14s %s\n" "$1" "$status" "$3" "$(date '+%T')" "$thistime" "$lasttime" "$6"
897
-}
898
-
899
-[ -f $TIMESTAMP_FILE ] || touch $TIMESTAMP_FILE
900
-
901
-FULL_IMGFMT_DETAILS=$(_full_imgfmt_details)
902
-FULL_HOST_DETAILS=$(_full_platform_details)
903
-
904
-if ! $makecheck; then
905
- _full_env_details
906
-fi
907
-
908
-seq="check"
909
-
910
-[ -n "$TESTS_REMAINING_LOG" ] && echo $list > $TESTS_REMAINING_LOG
911
-
912
-for seq in $list
913
-do
914
- err=false # error flag
915
- printdiff=false # show diff to reference output?
916
- status="" # test result summary
917
- results="" # test result details
918
- thistime="" # time the test took
919
-
920
- if [ -n "$TESTS_REMAINING_LOG" ] ; then
921
- sed -e "s/$seq//" -e 's/ / /' -e 's/^ *//' $TESTS_REMAINING_LOG > $TESTS_REMAINING_LOG.tmp
922
- mv $TESTS_REMAINING_LOG.tmp $TESTS_REMAINING_LOG
923
- sync
924
- fi
925
-
926
- lasttime=$(sed -n -e "/^$seq /s/.* //p" <$TIMESTAMP_FILE)
927
- starttime=$(date "+%T")
928
- _report_test_start $seq $starttime $lasttime
929
-
930
- if $showme
931
- then
932
- status="not run"
933
- elif [ -f expunged ] && $expunge && egrep "^$seq([ ]|\$)" expunged >/dev/null
934
- then
935
- status="not run"
936
- results="expunged"
937
- rm -f $seq.out.bad
938
- echo "/^$seq\$/d" >>$tmp.expunged
939
- elif [ ! -f "$source_iotests/$seq" ]
940
- then
941
- status="not run"
942
- results="no such test?"
943
- echo "/^$seq\$/d" >>$tmp.expunged
944
- else
945
- # really going to try and run this one
946
- #
947
- rm -f $seq.out.bad
948
- rm -f core $seq.notrun
949
- rm -f $seq.casenotrun
950
-
951
- start=$(_wallclock)
952
-
953
- if [ "$(head -n 1 "$source_iotests/$seq")" == "#!/usr/bin/env python3" ]; then
954
- if $python_usable; then
955
- run_command="$PYTHON $seq"
956
- else
957
- run_command="false"
958
- echo "$python_unusable_because" > $seq.notrun
959
- fi
960
- else
961
- run_command="./$seq"
962
- fi
963
- export OUTPUT_DIR=$PWD
964
- if $debug; then
965
- (cd "$source_iotests";
966
- MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(($RANDOM % 255 + 1))} \
967
- $run_command -d 2>&1 | tee $tmp.out)
968
- else
969
- (cd "$source_iotests";
970
- MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(($RANDOM % 255 + 1))} \
971
- $run_command >$tmp.out 2>&1)
972
- fi
973
- sts=$?
974
- stop=$(_wallclock)
975
-
976
- if [ -f core ]
977
- then
978
- mv core $seq.core
979
- status="fail"
980
- results="[dumped core] $seq.core"
981
- err=true
982
- fi
983
-
984
- if [ -f $seq.notrun ]
985
- then
986
- # overwrites timestamp output
987
- status="not run"
988
- results="$(cat $seq.notrun)"
989
- else
990
- if [ $sts -ne 0 ]
991
- then
992
- status="fail"
993
- results=$(printf %s "[failed, exit status $sts]")
994
- err=true
995
- fi
996
-
997
- reference="$source_iotests/$seq.out"
998
- reference_machine="$source_iotests/$seq.$QEMU_DEFAULT_MACHINE.out"
999
- if [ -f "$reference_machine" ]; then
1000
- reference="$reference_machine"
1001
- fi
1002
-
1003
- reference_format="$source_iotests/$seq.out.$IMGFMT"
1004
- if [ -f "$reference_format" ]; then
1005
- reference="$reference_format"
1006
- fi
1007
-
1008
- if [ "$CACHEMODE" = "none" ]; then
1009
- [ -f "$source_iotests/$seq.out.nocache" ] && reference="$source_iotests/$seq.out.nocache"
1010
- fi
1011
-
1012
- if [ ! -f "$reference" ]
1013
- then
1014
- status="fail"
1015
- results="no qualified output"
1016
- err=true
1017
- else
1018
- if diff -w "$reference" $tmp.out >/dev/null 2>&1
1019
- then
1020
- if ! $err; then
1021
- status="pass"
1022
- thistime=$(expr $stop - $start)
1023
- echo "$seq $thistime" >>$tmp.time
1024
- fi
1025
- else
1026
- mv $tmp.out $seq.out.bad
1027
- status="fail"
1028
- results="output mismatch (see $seq.out.bad)"
1029
- printdiff=true
1030
- err=true
1031
- fi
1032
- fi
1033
- fi
1034
- if [ -f $seq.casenotrun ]
1035
- then
1036
- cat $seq.casenotrun
1037
- casenotrun="$casenotrun $seq"
1038
- fi
1039
- fi
1040
-
1041
- # come here for each test, except when $showme is true
1042
- #
1043
- _report_test_result $seq "$status" "$starttime" "$lasttime" "$thistime" "$results"
1044
- case "$status" in
1045
- "pass")
1046
- try=$(expr $try + 1)
1047
- ;;
1048
- "fail")
1049
- try=$(expr $try + 1)
1050
- if $makecheck; then
1051
- _full_env_details
1052
- fi
1053
- if $printdiff; then
1054
- $diff -w "$reference" "$PWD"/$seq.out.bad
1055
- fi
1056
- bad="$bad $seq"
1057
- n_bad=$(expr $n_bad + 1)
1058
- quick=false
1059
- ;;
1060
- "not run")
1061
- notrun="$notrun $seq"
1062
- ;;
1063
- esac
1064
-
1065
- seq="after_$seq"
1066
-done
1067
1068
-interrupt=false
1069
-status=$(expr $n_bad)
1070
-exit
1071
+import os
1072
+import sys
1073
+import argparse
1074
+from findtests import TestFinder
1075
+from testenv import TestEnv
1076
+from testrunner import TestRunner
1077
+
1078
+
1079
+def make_argparser() -> argparse.ArgumentParser:
1080
+ p = argparse.ArgumentParser(description="Test run options")
1081
+
1082
+ p.add_argument('-n', '--dry-run', action='store_true',
1083
+ help='show me, do not run tests')
1084
+ p.add_argument('-makecheck', action='store_true',
1085
+ help='pretty print output for make check')
1086
+
1087
+ p.add_argument('-d', dest='debug', action='store_true', help='debug')
1088
+ p.add_argument('-misalign', action='store_true',
1089
+ help='misalign memory allocations')
1090
+ p.add_argument('--color', choices=['on', 'off', 'auto'],
1091
+ default='auto', help="use terminal colors. The default "
1092
+ "'auto' value means use colors if terminal stdout detected")
1093
+
1094
+ g_env = p.add_argument_group('test environment options')
1095
+ mg = g_env.add_mutually_exclusive_group()
1096
+ # We don't set default for cachemode, as we need to distinguish default
1097
+ # from user input later.
1098
+ mg.add_argument('-nocache', dest='cachemode', action='store_const',
1099
+ const='none', help='set cache mode "none" (O_DIRECT), '
1100
+ 'sets CACHEMODE environment variable')
1101
+ mg.add_argument('-c', dest='cachemode',
1102
+ help='sets CACHEMODE environment variable')
1103
+
1104
+ g_env.add_argument('-i', dest='aiomode', default='threads',
1105
+ help='sets AIOMODE environment variable')
1106
+
1107
+ p.set_defaults(imgfmt='raw', imgproto='file')
1108
+
1109
+ format_list = ['raw', 'bochs', 'cloop', 'parallels', 'qcow', 'qcow2',
1110
+ 'qed', 'vdi', 'vpc', 'vhdx', 'vmdk', 'luks', 'dmg']
1111
+ g_fmt = p.add_argument_group(
1112
+ ' image format options',
1113
+ 'The following options set the IMGFMT environment variable. '
1114
+ 'At most one choice is allowed, default is "raw"')
1115
+ mg = g_fmt.add_mutually_exclusive_group()
1116
+ for fmt in format_list:
1117
+ mg.add_argument('-' + fmt, dest='imgfmt', action='store_const',
1118
+ const=fmt, help=f'test {fmt}')
1119
+
1120
+ protocol_list = ['file', 'rbd', 'sheepdog', 'nbd', 'ssh', 'nfs',
1121
+ 'fuse']
1122
+ g_prt = p.add_argument_group(
1123
+ ' image protocol options',
1124
+ 'The following options set the IMGPROTO environment variable. '
1125
+ 'At most one choice is allowed, default is "file"')
1126
+ mg = g_prt.add_mutually_exclusive_group()
1127
+ for prt in protocol_list:
1128
+ mg.add_argument('-' + prt, dest='imgproto', action='store_const',
1129
+ const=prt, help=f'test {prt}')
1130
+
1131
+ g_bash = p.add_argument_group('bash tests options',
1132
+ 'The following options are ignored by '
1133
+ 'python tests.')
1134
+ # TODO: make support for the following options in iotests.py
1135
+ g_bash.add_argument('-o', dest='imgopts',
1136
+ help='options to pass to qemu-img create/convert, '
1137
+ 'sets IMGOPTS environment variable')
1138
+ g_bash.add_argument('-valgrind', action='store_true',
1139
+ help='use valgrind, sets VALGRIND_QEMU environment '
1140
+ 'variable')
1141
+
1142
+ g_sel = p.add_argument_group('test selecting options',
1143
+ 'The following options specify test set '
1144
+ 'to run.')
1145
+ g_sel.add_argument('-g', '--groups', metavar='group1,...',
1146
+ help='include tests from these groups')
1147
+ g_sel.add_argument('-x', '--exclude-groups', metavar='group1,...',
1148
+ help='exclude tests from these groups')
1149
+ g_sel.add_argument('--start-from', metavar='TEST',
1150
+ help='Start from specified test: make sorted sequence '
1151
+ 'of tests as usual and then drop tests from the first '
1152
+ 'one to TEST (not inclusive). This may be used to '
1153
+ 'rerun failed ./check command, starting from the '
1154
+ 'middle of the process.')
1155
+ g_sel.add_argument('tests', metavar='TEST_FILES', nargs='*',
1156
+ help='tests to run')
1157
+
1158
+ return p
1159
+
1160
+
1161
+if __name__ == '__main__':
1162
+ args = make_argparser().parse_args()
1163
+
1164
+ env = TestEnv(imgfmt=args.imgfmt, imgproto=args.imgproto,
1165
+ aiomode=args.aiomode, cachemode=args.cachemode,
1166
+ imgopts=args.imgopts, misalign=args.misalign,
1167
+ debug=args.debug, valgrind=args.valgrind)
1168
+
1169
+ testfinder = TestFinder(test_dir=env.source_iotests)
1170
+
1171
+ groups = args.groups.split(',') if args.groups else None
1172
+ x_groups = args.exclude_groups.split(',') if args.exclude_groups else None
1173
+
1174
+ group_local = os.path.join(env.source_iotests, 'group.local')
1175
+ if os.path.isfile(group_local):
1176
+ try:
1177
+ testfinder.add_group_file(group_local)
1178
+ except ValueError as e:
1179
+ sys.exit(f"Failed to parse group file '{group_local}': {e}")
1180
+
1181
+ try:
1182
+ tests = testfinder.find_tests(groups=groups, exclude_groups=x_groups,
1183
+ tests=args.tests,
1184
+ start_from=args.start_from)
1185
+ if not tests:
1186
+ raise ValueError('No tests selected')
1187
+ except ValueError as e:
1188
+ sys.exit(e)
1189
+
1190
+ if args.dry_run:
1191
+ print('\n'.join(tests))
1192
+ else:
1193
+ with TestRunner(env, makecheck=args.makecheck,
1194
+ color=args.color) as tr:
1195
+ tr.run_tests([os.path.join(env.source_iotests, t) for t in tests])
1196
diff --git a/tests/qemu-iotests/common.env.in b/tests/qemu-iotests/common.env.in
1197
deleted file mode 100644
1198
index XXXXXXX..XXXXXXX
1199
--- a/tests/qemu-iotests/common.env.in
1200
+++ /dev/null
1201
@@ -XXX,XX +XXX,XX @@
1202
-# Automatically generated by configure - do not modify
1203
-
1204
-export PYTHON='@PYTHON@'
1205
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
1206
deleted file mode 100644
1207
index XXXXXXX..XXXXXXX
1208
--- a/tests/qemu-iotests/group
1209
+++ /dev/null
1210
@@ -XXX,XX +XXX,XX @@
1211
-#
1212
-# QA groups control file
1213
-# Defines test groups
1214
-#
1215
-# Some notes about the groups:
1216
-#
1217
-# - do not start group names with a digit
1218
-#
1219
-# - quick : Tests in this group should finish within some few seconds.
1220
-#
1221
-# - img : Tests in this group can be used to excercise the qemu-img tool.
1222
-#
1223
-# - auto : Tests in this group are used during "make check" and should be
1224
-# runnable in any case. That means they should run with every QEMU binary
1225
-# (also non-x86), with every QEMU configuration (i.e. must not fail if
1226
-# an optional feature is not compiled in - but reporting a "skip" is ok),
1227
-# work at least with the qcow2 file format, work with all kind of host
1228
-# filesystems and users (e.g. "nobody" or "root") and must not take too
1229
-# much memory and disk space (since CI pipelines tend to fail otherwise).
1230
-#
1231
-
1232
-#
1233
-# test-group association ... one line per test
1234
-#
1235
-001 rw auto quick
1236
-002 rw auto quick
1237
-003 rw auto
1238
-004 rw auto quick
1239
-005 img auto quick
1240
-# 006 was removed, do not reuse
1241
-007 snapshot auto
1242
-008 rw auto quick
1243
-009 rw auto quick
1244
-010 rw auto quick
1245
-011 rw auto quick
1246
-012 auto quick
1247
-013 rw auto
1248
-014 rw
1249
-015 rw snapshot
1250
-# 016 was removed, do not reuse
1251
-017 rw backing auto quick
1252
-018 rw backing auto quick
1253
-019 rw backing auto quick
1254
-020 rw backing auto quick
1255
-021 io auto quick
1256
-022 rw snapshot auto
1257
-023 rw
1258
-024 rw backing auto quick
1259
-025 rw auto quick
1260
-026 rw blkdbg
1261
-027 rw auto quick
1262
-028 rw backing quick
1263
-029 rw auto quick
1264
-030 rw auto backing
1265
-031 rw auto quick
1266
-032 rw auto quick
1267
-033 rw auto quick
1268
-034 rw auto backing quick
1269
-035 rw auto quick
1270
-036 rw auto quick
1271
-037 rw auto backing quick
1272
-038 rw auto backing quick
1273
-039 rw auto quick
1274
-040 rw auto
1275
-041 rw auto backing
1276
-042 rw auto quick
1277
-043 rw auto backing
1278
-044 rw
1279
-045 rw quick
1280
-046 rw auto aio quick
1281
-047 rw auto quick
1282
-048 img auto quick
1283
-049 rw auto
1284
-050 rw auto backing quick
1285
-051 rw
1286
-052 rw auto backing quick
1287
-053 rw auto quick
1288
-054 rw auto quick
1289
-055 rw
1290
-056 rw backing
1291
-057 rw
1292
-058 rw quick
1293
-059 rw quick
1294
-060 rw auto quick
1295
-061 rw auto
1296
-062 rw auto quick
1297
-063 rw auto quick
1298
-064 rw quick
1299
-065 rw quick
1300
-066 rw auto quick
1301
-# 067 was removed, do not reuse
1302
-068 rw quick
1303
-069 rw auto quick
1304
-070 rw quick
1305
-071 rw auto quick
1306
-072 rw auto quick
1307
-073 rw auto quick
1308
-074 rw auto quick
1309
-075 rw quick
1310
-076 io
1311
-077 rw quick
1312
-078 rw quick
1313
-079 rw auto
1314
-080 rw auto
1315
-081 rw quick
1316
-082 rw quick
1317
-083 rw
1318
-084 img quick
1319
-085 rw
1320
-086 rw auto quick
1321
-087 rw quick
1322
-088 rw quick
1323
-089 rw auto quick
1324
-090 rw auto quick
1325
-091 rw migration quick
1326
-092 rw quick
1327
-093 throttle
1328
-094 rw quick
1329
-095 rw quick
1330
-096 rw quick
1331
-097 rw auto backing
1332
-098 rw auto backing quick
1333
-099 rw auto quick
1334
-# 100 was removed, do not reuse
1335
-101 rw quick
1336
-102 rw quick
1337
-103 rw auto quick
1338
-104 rw auto
1339
-105 rw auto quick
1340
-106 rw quick
1341
-107 rw auto quick
1342
-108 rw auto quick
1343
-109 rw
1344
-110 rw auto backing quick
1345
-111 rw auto quick
1346
-112 rw
1347
-113 rw quick
1348
-114 rw auto quick
1349
-115 rw
1350
-116 rw quick
1351
-117 rw auto
1352
-118 rw
1353
-119 rw quick
1354
-120 rw auto quick
1355
-121 rw
1356
-122 rw
1357
-123 rw quick
1358
-124 rw backing
1359
-125 rw
1360
-126 rw auto backing
1361
-127 rw auto backing quick
1362
-128 rw quick
1363
-129 rw quick
1364
-130 rw quick
1365
-131 rw quick
1366
-132 rw quick
1367
-133 auto quick
1368
-134 rw auto quick
1369
-135 rw
1370
-136 rw
1371
-137 rw auto
1372
-138 rw auto quick
1373
-139 rw quick
1374
-140 rw auto quick
1375
-141 rw auto quick
1376
-142
1377
-143 auto quick
1378
-144 rw quick
1379
-145 quick
1380
-146 quick
1381
-147 img
1382
-148 rw quick
1383
-149 rw sudo
1384
-150 rw auto quick
1385
-151 rw
1386
-152 rw quick
1387
-153 rw quick
1388
-154 rw auto backing quick
1389
-155 rw
1390
-156 rw auto quick
1391
-157 quick
1392
-158 rw auto quick
1393
-159 rw auto quick
1394
-160 rw quick
1395
-161 rw auto quick
1396
-162 quick
1397
-163 rw
1398
-165 rw quick
1399
-169 rw migration
1400
-170 rw auto quick
1401
-171 rw quick
1402
-172 auto
1403
-173 rw
1404
-174 auto
1405
-175 quick
1406
-176 rw auto backing
1407
-177 rw auto quick
1408
-178 img
1409
-179 rw auto quick
1410
-181 rw auto migration quick
1411
-182 rw quick
1412
-183 rw migration quick
1413
-184 rw auto quick
1414
-185 rw
1415
-186 rw auto
1416
-187 rw auto
1417
-188 rw quick
1418
-189 rw
1419
-190 rw auto quick
1420
-191 rw auto
1421
-192 rw auto quick
1422
-194 rw migration quick
1423
-195 rw auto quick
1424
-196 rw quick migration
1425
-197 rw quick
1426
-198 rw
1427
-199 rw migration
1428
-200 rw
1429
-201 rw migration quick
1430
-202 rw quick
1431
-203 rw auto migration quick
1432
-204 rw quick
1433
-205 rw quick
1434
-206 rw
1435
-207 rw
1436
-208 rw quick
1437
-209 rw quick
1438
-210 rw
1439
-211 rw quick
1440
-212 rw quick
1441
-213 rw quick
1442
-214 rw auto
1443
-215 rw quick
1444
-216 rw quick
1445
-217 rw auto quick
1446
-218 rw quick
1447
-219 rw
1448
-220 rw auto
1449
-221 rw quick
1450
-222 rw quick
1451
-223 rw quick
1452
-224 rw quick
1453
-225 rw quick
1454
-226 auto quick
1455
-227 quick
1456
-228 rw quick
1457
-229 auto quick
1458
-231 quick
1459
-232 quick
1460
-233 quick
1461
-234 quick migration
1462
-235 quick
1463
-236 quick
1464
-237 rw quick
1465
-238 quick
1466
-239 rw quick
1467
-240 quick
1468
-241 rw quick
1469
-242 rw quick
1470
-243 rw quick
1471
-244 rw auto quick
1472
-245 rw
1473
-246 rw quick
1474
-247 rw quick
1475
-248 rw quick
1476
-249 rw auto quick
1477
-250 rw quick
1478
-251 rw auto quick
1479
-252 rw auto backing quick
1480
-253 rw quick
1481
-254 rw backing quick
1482
-255 rw quick
1483
-256 rw auto quick
1484
-257 rw
1485
-258 rw quick
1486
-259 rw auto quick
1487
-260 rw quick
1488
-261 rw
1489
-262 rw quick migration
1490
-263 rw quick
1491
-264 rw
1492
-265 rw auto quick
1493
-266 rw quick
1494
-267 rw auto quick snapshot
1495
-268 rw auto quick
1496
-270 rw backing quick
1497
-271 rw auto
1498
-272 rw
1499
-273 backing quick
1500
-274 rw backing
1501
-277 rw quick
1502
-279 rw backing quick
1503
-280 rw migration quick
1504
-281 rw quick
1505
-282 rw img quick
1506
-283 auto quick
1507
-284 rw
1508
-286 rw quick
1509
-287 auto quick
1510
-288 quick
1511
-289 rw quick
1512
-290 rw auto quick
1513
-291 rw quick
1514
-292 rw auto quick
1515
-293 rw
1516
-294 rw quick
1517
-295 rw
1518
-296 rw
1519
-297 meta
1520
-298
1521
-299 auto quick
1522
-300 migration
1523
-301 backing quick
1524
-302 quick
1525
-303 rw quick
1526
-304 rw quick
1527
-305 rw quick
1528
-307 rw quick export
1529
-308 rw
1530
-309 rw auto quick
1531
-310 rw quick
1532
-312 rw quick
1533
-313 rw auto quick
1534
diff --git a/tests/qemu-iotests/meson.build b/tests/qemu-iotests/meson.build
1535
index XXXXXXX..XXXXXXX 100644
1536
--- a/tests/qemu-iotests/meson.build
1537
+++ b/tests/qemu-iotests/meson.build
1538
@@ -XXX,XX +XXX,XX @@ if 'CONFIG_LINUX' in config_host
1539
else
1540
socket_scm_helper = []
1541
endif
1542
-configure_file(output: 'common.env',
1543
- input: files('common.env.in'),
1544
- configuration: {'PYTHON': python.full_path()})
33
--
1545
--
34
2.25.3
1546
2.29.2
35
1547
36
1548
diff view generated by jsdifflib
Deleted patch
1
The BDRV_REQ_ZERO_WRITE is currently implemented in a way that first the
2
image is possibly preallocated and then the zero flag is added to all
3
clusters. This means that a copy-on-write operation may be needed when
4
writing to these clusters, despite having used preallocation, negating
5
one of the major benefits of preallocation.
6
1
7
Instead, try to forward the BDRV_REQ_ZERO_WRITE to the protocol driver,
8
and if the protocol driver can ensure that the new area reads as zeros,
9
we can skip setting the zero flag in the qcow2 layer.
10
11
Unfortunately, the same approach doesn't work for metadata
12
preallocation, so we'll still set the zero flag there.
13
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
Reviewed-by: Max Reitz <mreitz@redhat.com>
16
Message-Id: <20200424142701.67053-1-kwolf@redhat.com>
17
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
19
---
20
block/qcow2.c | 22 +++++++++++++++++++---
21
tests/qemu-iotests/274.out | 4 ++--
22
2 files changed, 21 insertions(+), 5 deletions(-)
23
24
diff --git a/block/qcow2.c b/block/qcow2.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/block/qcow2.c
27
+++ b/block/qcow2.c
28
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
29
/* Allocate the data area */
30
new_file_size = allocation_start +
31
nb_new_data_clusters * s->cluster_size;
32
- /* Image file grows, so @exact does not matter */
33
- ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, 0,
34
- errp);
35
+ /*
36
+ * Image file grows, so @exact does not matter.
37
+ *
38
+ * If we need to zero out the new area, try first whether the protocol
39
+ * driver can already take care of this.
40
+ */
41
+ if (flags & BDRV_REQ_ZERO_WRITE) {
42
+ ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc,
43
+ BDRV_REQ_ZERO_WRITE, NULL);
44
+ if (ret >= 0) {
45
+ flags &= ~BDRV_REQ_ZERO_WRITE;
46
+ }
47
+ } else {
48
+ ret = -1;
49
+ }
50
+ if (ret < 0) {
51
+ ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, 0,
52
+ errp);
53
+ }
54
if (ret < 0) {
55
error_prepend(errp, "Failed to resize underlying file: ");
56
qcow2_free_clusters(bs, allocation_start,
57
diff --git a/tests/qemu-iotests/274.out b/tests/qemu-iotests/274.out
58
index XXXXXXX..XXXXXXX 100644
59
--- a/tests/qemu-iotests/274.out
60
+++ b/tests/qemu-iotests/274.out
61
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 9437184
62
10 MiB (0xa00000) bytes allocated at offset 5 MiB (0x500000)
63
64
[{ "start": 0, "length": 5242880, "depth": 1, "zero": true, "data": false},
65
-{ "start": 5242880, "length": 10485760, "depth": 0, "zero": true, "data": false, "offset": 327680}]
66
+{ "start": 5242880, "length": 10485760, "depth": 0, "zero": false, "data": true, "offset": 327680}]
67
68
=== preallocation=full ===
69
Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=16777216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
70
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 11534336
71
4 MiB (0x400000) bytes allocated at offset 8 MiB (0x800000)
72
73
[{ "start": 0, "length": 8388608, "depth": 1, "zero": true, "data": false},
74
-{ "start": 8388608, "length": 4194304, "depth": 0, "zero": true, "data": false, "offset": 327680}]
75
+{ "start": 8388608, "length": 4194304, "depth": 0, "zero": false, "data": true, "offset": 327680}]
76
77
=== preallocation=off ===
78
Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=393216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
79
--
80
2.25.3
81
82
diff view generated by jsdifflib
1
From: Andrzej Jakowski <andrzej.jakowski@linux.intel.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
This patch introduces support for PMR that has been defined as part of NVMe 1.4
3
Rename bitmaps migration tests and move them to tests subdirectory to
4
spec. User can now specify a pmrdev option that should point to HostMemoryBackend.
4
demonstrate new human-friendly test naming.
5
pmrdev memory region will subsequently be exposed as PCI BAR 2 in emulated NVMe
6
device. Guest OS can perform mmio read and writes to the PMR region that will stay
7
persistent across system reboot.
8
5
9
Signed-off-by: Andrzej Jakowski <andrzej.jakowski@linux.intel.com>
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
7
Message-Id: <20210125185056.129513-7-vsementsov@virtuozzo.com>
11
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
12
Message-Id: <20200330164656.9348-1-andrzej.jakowski@linux.intel.com>
13
Reviewed-by: Keith Busch <kbusch@kernel.org>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
9
---
16
hw/block/nvme.h | 2 +
10
tests/qemu-iotests/{199 => tests/migrate-bitmaps-postcopy-test} | 0
17
include/block/nvme.h | 172 +++++++++++++++++++++++++++++++++++++++++
11
.../{199.out => tests/migrate-bitmaps-postcopy-test.out} | 0
18
hw/block/nvme.c | 109 ++++++++++++++++++++++++++
12
tests/qemu-iotests/{169 => tests/migrate-bitmaps-test} | 0
19
hw/block/Makefile.objs | 2 +-
13
tests/qemu-iotests/{169.out => tests/migrate-bitmaps-test.out} | 0
20
hw/block/trace-events | 4 +
14
4 files changed, 0 insertions(+), 0 deletions(-)
21
5 files changed, 288 insertions(+), 1 deletion(-)
15
rename tests/qemu-iotests/{199 => tests/migrate-bitmaps-postcopy-test} (100%)
16
rename tests/qemu-iotests/{199.out => tests/migrate-bitmaps-postcopy-test.out} (100%)
17
rename tests/qemu-iotests/{169 => tests/migrate-bitmaps-test} (100%)
18
rename tests/qemu-iotests/{169.out => tests/migrate-bitmaps-test.out} (100%)
22
19
23
diff --git a/hw/block/nvme.h b/hw/block/nvme.h
20
diff --git a/tests/qemu-iotests/199 b/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test
24
index XXXXXXX..XXXXXXX 100644
21
similarity index 100%
25
--- a/hw/block/nvme.h
22
rename from tests/qemu-iotests/199
26
+++ b/hw/block/nvme.h
23
rename to tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test
27
@@ -XXX,XX +XXX,XX @@ typedef struct NvmeCtrl {
24
diff --git a/tests/qemu-iotests/199.out b/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test.out
28
uint64_t timestamp_set_qemu_clock_ms; /* QEMU clock time */
25
similarity index 100%
29
26
rename from tests/qemu-iotests/199.out
30
char *serial;
27
rename to tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test.out
31
+ HostMemoryBackend *pmrdev;
28
diff --git a/tests/qemu-iotests/169 b/tests/qemu-iotests/tests/migrate-bitmaps-test
32
+
29
similarity index 100%
33
NvmeNamespace *namespaces;
30
rename from tests/qemu-iotests/169
34
NvmeSQueue **sq;
31
rename to tests/qemu-iotests/tests/migrate-bitmaps-test
35
NvmeCQueue **cq;
32
diff --git a/tests/qemu-iotests/169.out b/tests/qemu-iotests/tests/migrate-bitmaps-test.out
36
diff --git a/include/block/nvme.h b/include/block/nvme.h
33
similarity index 100%
37
index XXXXXXX..XXXXXXX 100644
34
rename from tests/qemu-iotests/169.out
38
--- a/include/block/nvme.h
35
rename to tests/qemu-iotests/tests/migrate-bitmaps-test.out
39
+++ b/include/block/nvme.h
40
@@ -XXX,XX +XXX,XX @@ typedef struct NvmeBar {
41
uint64_t acq;
42
uint32_t cmbloc;
43
uint32_t cmbsz;
44
+ uint8_t padding[3520]; /* not used by QEMU */
45
+ uint32_t pmrcap;
46
+ uint32_t pmrctl;
47
+ uint32_t pmrsts;
48
+ uint32_t pmrebs;
49
+ uint32_t pmrswtp;
50
+ uint32_t pmrmsc;
51
} NvmeBar;
52
53
enum NvmeCapShift {
54
@@ -XXX,XX +XXX,XX @@ enum NvmeCapShift {
55
CAP_CSS_SHIFT = 37,
56
CAP_MPSMIN_SHIFT = 48,
57
CAP_MPSMAX_SHIFT = 52,
58
+ CAP_PMR_SHIFT = 56,
59
};
60
61
enum NvmeCapMask {
62
@@ -XXX,XX +XXX,XX @@ enum NvmeCapMask {
63
CAP_CSS_MASK = 0xff,
64
CAP_MPSMIN_MASK = 0xf,
65
CAP_MPSMAX_MASK = 0xf,
66
+ CAP_PMR_MASK = 0x1,
67
};
68
69
#define NVME_CAP_MQES(cap) (((cap) >> CAP_MQES_SHIFT) & CAP_MQES_MASK)
70
@@ -XXX,XX +XXX,XX @@ enum NvmeCapMask {
71
<< CAP_MPSMIN_SHIFT)
72
#define NVME_CAP_SET_MPSMAX(cap, val) (cap |= (uint64_t)(val & CAP_MPSMAX_MASK)\
73
<< CAP_MPSMAX_SHIFT)
74
+#define NVME_CAP_SET_PMRS(cap, val) (cap |= (uint64_t)(val & CAP_PMR_MASK)\
75
+ << CAP_PMR_SHIFT)
76
77
enum NvmeCcShift {
78
CC_EN_SHIFT = 0,
79
@@ -XXX,XX +XXX,XX @@ enum NvmeCmbszMask {
80
#define NVME_CMBSZ_GETSIZE(cmbsz) \
81
(NVME_CMBSZ_SZ(cmbsz) * (1 << (12 + 4 * NVME_CMBSZ_SZU(cmbsz))))
82
83
+enum NvmePmrcapShift {
84
+ PMRCAP_RDS_SHIFT = 3,
85
+ PMRCAP_WDS_SHIFT = 4,
86
+ PMRCAP_BIR_SHIFT = 5,
87
+ PMRCAP_PMRTU_SHIFT = 8,
88
+ PMRCAP_PMRWBM_SHIFT = 10,
89
+ PMRCAP_PMRTO_SHIFT = 16,
90
+ PMRCAP_CMSS_SHIFT = 24,
91
+};
92
+
93
+enum NvmePmrcapMask {
94
+ PMRCAP_RDS_MASK = 0x1,
95
+ PMRCAP_WDS_MASK = 0x1,
96
+ PMRCAP_BIR_MASK = 0x7,
97
+ PMRCAP_PMRTU_MASK = 0x3,
98
+ PMRCAP_PMRWBM_MASK = 0xf,
99
+ PMRCAP_PMRTO_MASK = 0xff,
100
+ PMRCAP_CMSS_MASK = 0x1,
101
+};
102
+
103
+#define NVME_PMRCAP_RDS(pmrcap) \
104
+ ((pmrcap >> PMRCAP_RDS_SHIFT) & PMRCAP_RDS_MASK)
105
+#define NVME_PMRCAP_WDS(pmrcap) \
106
+ ((pmrcap >> PMRCAP_WDS_SHIFT) & PMRCAP_WDS_MASK)
107
+#define NVME_PMRCAP_BIR(pmrcap) \
108
+ ((pmrcap >> PMRCAP_BIR_SHIFT) & PMRCAP_BIR_MASK)
109
+#define NVME_PMRCAP_PMRTU(pmrcap) \
110
+ ((pmrcap >> PMRCAP_PMRTU_SHIFT) & PMRCAP_PMRTU_MASK)
111
+#define NVME_PMRCAP_PMRWBM(pmrcap) \
112
+ ((pmrcap >> PMRCAP_PMRWBM_SHIFT) & PMRCAP_PMRWBM_MASK)
113
+#define NVME_PMRCAP_PMRTO(pmrcap) \
114
+ ((pmrcap >> PMRCAP_PMRTO_SHIFT) & PMRCAP_PMRTO_MASK)
115
+#define NVME_PMRCAP_CMSS(pmrcap) \
116
+ ((pmrcap >> PMRCAP_CMSS_SHIFT) & PMRCAP_CMSS_MASK)
117
+
118
+#define NVME_PMRCAP_SET_RDS(pmrcap, val) \
119
+ (pmrcap |= (uint64_t)(val & PMRCAP_RDS_MASK) << PMRCAP_RDS_SHIFT)
120
+#define NVME_PMRCAP_SET_WDS(pmrcap, val) \
121
+ (pmrcap |= (uint64_t)(val & PMRCAP_WDS_MASK) << PMRCAP_WDS_SHIFT)
122
+#define NVME_PMRCAP_SET_BIR(pmrcap, val) \
123
+ (pmrcap |= (uint64_t)(val & PMRCAP_BIR_MASK) << PMRCAP_BIR_SHIFT)
124
+#define NVME_PMRCAP_SET_PMRTU(pmrcap, val) \
125
+ (pmrcap |= (uint64_t)(val & PMRCAP_PMRTU_MASK) << PMRCAP_PMRTU_SHIFT)
126
+#define NVME_PMRCAP_SET_PMRWBM(pmrcap, val) \
127
+ (pmrcap |= (uint64_t)(val & PMRCAP_PMRWBM_MASK) << PMRCAP_PMRWBM_SHIFT)
128
+#define NVME_PMRCAP_SET_PMRTO(pmrcap, val) \
129
+ (pmrcap |= (uint64_t)(val & PMRCAP_PMRTO_MASK) << PMRCAP_PMRTO_SHIFT)
130
+#define NVME_PMRCAP_SET_CMSS(pmrcap, val) \
131
+ (pmrcap |= (uint64_t)(val & PMRCAP_CMSS_MASK) << PMRCAP_CMSS_SHIFT)
132
+
133
+enum NvmePmrctlShift {
134
+ PMRCTL_EN_SHIFT = 0,
135
+};
136
+
137
+enum NvmePmrctlMask {
138
+ PMRCTL_EN_MASK = 0x1,
139
+};
140
+
141
+#define NVME_PMRCTL_EN(pmrctl) ((pmrctl >> PMRCTL_EN_SHIFT) & PMRCTL_EN_MASK)
142
+
143
+#define NVME_PMRCTL_SET_EN(pmrctl, val) \
144
+ (pmrctl |= (uint64_t)(val & PMRCTL_EN_MASK) << PMRCTL_EN_SHIFT)
145
+
146
+enum NvmePmrstsShift {
147
+ PMRSTS_ERR_SHIFT = 0,
148
+ PMRSTS_NRDY_SHIFT = 8,
149
+ PMRSTS_HSTS_SHIFT = 9,
150
+ PMRSTS_CBAI_SHIFT = 12,
151
+};
152
+
153
+enum NvmePmrstsMask {
154
+ PMRSTS_ERR_MASK = 0xff,
155
+ PMRSTS_NRDY_MASK = 0x1,
156
+ PMRSTS_HSTS_MASK = 0x7,
157
+ PMRSTS_CBAI_MASK = 0x1,
158
+};
159
+
160
+#define NVME_PMRSTS_ERR(pmrsts) \
161
+ ((pmrsts >> PMRSTS_ERR_SHIFT) & PMRSTS_ERR_MASK)
162
+#define NVME_PMRSTS_NRDY(pmrsts) \
163
+ ((pmrsts >> PMRSTS_NRDY_SHIFT) & PMRSTS_NRDY_MASK)
164
+#define NVME_PMRSTS_HSTS(pmrsts) \
165
+ ((pmrsts >> PMRSTS_HSTS_SHIFT) & PMRSTS_HSTS_MASK)
166
+#define NVME_PMRSTS_CBAI(pmrsts) \
167
+ ((pmrsts >> PMRSTS_CBAI_SHIFT) & PMRSTS_CBAI_MASK)
168
+
169
+#define NVME_PMRSTS_SET_ERR(pmrsts, val) \
170
+ (pmrsts |= (uint64_t)(val & PMRSTS_ERR_MASK) << PMRSTS_ERR_SHIFT)
171
+#define NVME_PMRSTS_SET_NRDY(pmrsts, val) \
172
+ (pmrsts |= (uint64_t)(val & PMRSTS_NRDY_MASK) << PMRSTS_NRDY_SHIFT)
173
+#define NVME_PMRSTS_SET_HSTS(pmrsts, val) \
174
+ (pmrsts |= (uint64_t)(val & PMRSTS_HSTS_MASK) << PMRSTS_HSTS_SHIFT)
175
+#define NVME_PMRSTS_SET_CBAI(pmrsts, val) \
176
+ (pmrsts |= (uint64_t)(val & PMRSTS_CBAI_MASK) << PMRSTS_CBAI_SHIFT)
177
+
178
+enum NvmePmrebsShift {
179
+ PMREBS_PMRSZU_SHIFT = 0,
180
+ PMREBS_RBB_SHIFT = 4,
181
+ PMREBS_PMRWBZ_SHIFT = 8,
182
+};
183
+
184
+enum NvmePmrebsMask {
185
+ PMREBS_PMRSZU_MASK = 0xf,
186
+ PMREBS_RBB_MASK = 0x1,
187
+ PMREBS_PMRWBZ_MASK = 0xffffff,
188
+};
189
+
190
+#define NVME_PMREBS_PMRSZU(pmrebs) \
191
+ ((pmrebs >> PMREBS_PMRSZU_SHIFT) & PMREBS_PMRSZU_MASK)
192
+#define NVME_PMREBS_RBB(pmrebs) \
193
+ ((pmrebs >> PMREBS_RBB_SHIFT) & PMREBS_RBB_MASK)
194
+#define NVME_PMREBS_PMRWBZ(pmrebs) \
195
+ ((pmrebs >> PMREBS_PMRWBZ_SHIFT) & PMREBS_PMRWBZ_MASK)
196
+
197
+#define NVME_PMREBS_SET_PMRSZU(pmrebs, val) \
198
+ (pmrebs |= (uint64_t)(val & PMREBS_PMRSZU_MASK) << PMREBS_PMRSZU_SHIFT)
199
+#define NVME_PMREBS_SET_RBB(pmrebs, val) \
200
+ (pmrebs |= (uint64_t)(val & PMREBS_RBB_MASK) << PMREBS_RBB_SHIFT)
201
+#define NVME_PMREBS_SET_PMRWBZ(pmrebs, val) \
202
+ (pmrebs |= (uint64_t)(val & PMREBS_PMRWBZ_MASK) << PMREBS_PMRWBZ_SHIFT)
203
+
204
+enum NvmePmrswtpShift {
205
+ PMRSWTP_PMRSWTU_SHIFT = 0,
206
+ PMRSWTP_PMRSWTV_SHIFT = 8,
207
+};
208
+
209
+enum NvmePmrswtpMask {
210
+ PMRSWTP_PMRSWTU_MASK = 0xf,
211
+ PMRSWTP_PMRSWTV_MASK = 0xffffff,
212
+};
213
+
214
+#define NVME_PMRSWTP_PMRSWTU(pmrswtp) \
215
+ ((pmrswtp >> PMRSWTP_PMRSWTU_SHIFT) & PMRSWTP_PMRSWTU_MASK)
216
+#define NVME_PMRSWTP_PMRSWTV(pmrswtp) \
217
+ ((pmrswtp >> PMRSWTP_PMRSWTV_SHIFT) & PMRSWTP_PMRSWTV_MASK)
218
+
219
+#define NVME_PMRSWTP_SET_PMRSWTU(pmrswtp, val) \
220
+ (pmrswtp |= (uint64_t)(val & PMRSWTP_PMRSWTU_MASK) << PMRSWTP_PMRSWTU_SHIFT)
221
+#define NVME_PMRSWTP_SET_PMRSWTV(pmrswtp, val) \
222
+ (pmrswtp |= (uint64_t)(val & PMRSWTP_PMRSWTV_MASK) << PMRSWTP_PMRSWTV_SHIFT)
223
+
224
+enum NvmePmrmscShift {
225
+ PMRMSC_CMSE_SHIFT = 1,
226
+ PMRMSC_CBA_SHIFT = 12,
227
+};
228
+
229
+enum NvmePmrmscMask {
230
+ PMRMSC_CMSE_MASK = 0x1,
231
+ PMRMSC_CBA_MASK = 0xfffffffffffff,
232
+};
233
+
234
+#define NVME_PMRMSC_CMSE(pmrmsc) \
235
+ ((pmrmsc >> PMRMSC_CMSE_SHIFT) & PMRMSC_CMSE_MASK)
236
+#define NVME_PMRMSC_CBA(pmrmsc) \
237
+ ((pmrmsc >> PMRMSC_CBA_SHIFT) & PMRMSC_CBA_MASK)
238
+
239
+#define NVME_PMRMSC_SET_CMSE(pmrmsc, val) \
240
+ (pmrmsc |= (uint64_t)(val & PMRMSC_CMSE_MASK) << PMRMSC_CMSE_SHIFT)
241
+#define NVME_PMRMSC_SET_CBA(pmrmsc, val) \
242
+ (pmrmsc |= (uint64_t)(val & PMRMSC_CBA_MASK) << PMRMSC_CBA_SHIFT)
243
+
244
typedef struct NvmeCmd {
245
uint8_t opcode;
246
uint8_t fuse;
247
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
248
index XXXXXXX..XXXXXXX 100644
249
--- a/hw/block/nvme.c
250
+++ b/hw/block/nvme.c
251
@@ -XXX,XX +XXX,XX @@
252
* -drive file=<file>,if=none,id=<drive_id>
253
* -device nvme,drive=<drive_id>,serial=<serial>,id=<id[optional]>, \
254
* cmb_size_mb=<cmb_size_mb[optional]>, \
255
+ * [pmrdev=<mem_backend_file_id>,] \
256
* num_queues=<N[optional]>
257
*
258
* Note cmb_size_mb denotes size of CMB in MB. CMB is assumed to be at
259
* offset 0 in BAR2 and supports only WDS, RDS and SQS for now.
260
+ *
261
+ * cmb_size_mb= and pmrdev= options are mutually exclusive due to limitation
262
+ * in available BAR's. cmb_size_mb= will take precedence over pmrdev= when
263
+ * both provided.
264
+ * Enabling pmr emulation can be achieved by pointing to memory-backend-file.
265
+ * For example:
266
+ * -object memory-backend-file,id=<mem_id>,share=on,mem-path=<file_path>, \
267
+ * size=<size> .... -device nvme,...,pmrdev=<mem_id>
268
*/
269
270
#include "qemu/osdep.h"
271
@@ -XXX,XX +XXX,XX @@
272
#include "sysemu/sysemu.h"
273
#include "qapi/error.h"
274
#include "qapi/visitor.h"
275
+#include "sysemu/hostmem.h"
276
#include "sysemu/block-backend.h"
277
+#include "exec/ram_addr.h"
278
279
#include "qemu/log.h"
280
#include "qemu/module.h"
281
@@ -XXX,XX +XXX,XX @@ static void nvme_write_bar(NvmeCtrl *n, hwaddr offset, uint64_t data,
282
NVME_GUEST_ERR(nvme_ub_mmiowr_cmbsz_readonly,
283
"invalid write to read only CMBSZ, ignored");
284
return;
285
+ case 0xE00: /* PMRCAP */
286
+ NVME_GUEST_ERR(nvme_ub_mmiowr_pmrcap_readonly,
287
+ "invalid write to PMRCAP register, ignored");
288
+ return;
289
+ case 0xE04: /* TODO PMRCTL */
290
+ break;
291
+ case 0xE08: /* PMRSTS */
292
+ NVME_GUEST_ERR(nvme_ub_mmiowr_pmrsts_readonly,
293
+ "invalid write to PMRSTS register, ignored");
294
+ return;
295
+ case 0xE0C: /* PMREBS */
296
+ NVME_GUEST_ERR(nvme_ub_mmiowr_pmrebs_readonly,
297
+ "invalid write to PMREBS register, ignored");
298
+ return;
299
+ case 0xE10: /* PMRSWTP */
300
+ NVME_GUEST_ERR(nvme_ub_mmiowr_pmrswtp_readonly,
301
+ "invalid write to PMRSWTP register, ignored");
302
+ return;
303
+ case 0xE14: /* TODO PMRMSC */
304
+ break;
305
default:
306
NVME_GUEST_ERR(nvme_ub_mmiowr_invalid,
307
"invalid MMIO write,"
308
@@ -XXX,XX +XXX,XX @@ static uint64_t nvme_mmio_read(void *opaque, hwaddr addr, unsigned size)
309
}
310
311
if (addr < sizeof(n->bar)) {
312
+ /*
313
+ * When PMRWBM bit 1 is set then read from
314
+ * from PMRSTS should ensure prior writes
315
+ * made it to persistent media
316
+ */
317
+ if (addr == 0xE08 &&
318
+ (NVME_PMRCAP_PMRWBM(n->bar.pmrcap) & 0x02)) {
319
+ qemu_ram_writeback(n->pmrdev->mr.ram_block,
320
+ 0, n->pmrdev->size);
321
+ }
322
memcpy(&val, ptr + addr, size);
323
} else {
324
NVME_GUEST_ERR(nvme_ub_mmiord_invalid_ofs,
325
@@ -XXX,XX +XXX,XX @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp)
326
error_setg(errp, "serial property not set");
327
return;
328
}
329
+
330
+ if (!n->cmb_size_mb && n->pmrdev) {
331
+ if (host_memory_backend_is_mapped(n->pmrdev)) {
332
+ char *path = object_get_canonical_path_component(OBJECT(n->pmrdev));
333
+ error_setg(errp, "can't use already busy memdev: %s", path);
334
+ g_free(path);
335
+ return;
336
+ }
337
+
338
+ if (!is_power_of_2(n->pmrdev->size)) {
339
+ error_setg(errp, "pmr backend size needs to be power of 2 in size");
340
+ return;
341
+ }
342
+
343
+ host_memory_backend_set_mapped(n->pmrdev, true);
344
+ }
345
+
346
blkconf_blocksizes(&n->conf);
347
if (!blkconf_apply_backend_options(&n->conf, blk_is_read_only(n->conf.blk),
348
false, errp)) {
349
@@ -XXX,XX +XXX,XX @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp)
350
PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64 |
351
PCI_BASE_ADDRESS_MEM_PREFETCH, &n->ctrl_mem);
352
353
+ } else if (n->pmrdev) {
354
+ /* Controller Capabilities register */
355
+ NVME_CAP_SET_PMRS(n->bar.cap, 1);
356
+
357
+ /* PMR Capabities register */
358
+ n->bar.pmrcap = 0;
359
+ NVME_PMRCAP_SET_RDS(n->bar.pmrcap, 0);
360
+ NVME_PMRCAP_SET_WDS(n->bar.pmrcap, 0);
361
+ NVME_PMRCAP_SET_BIR(n->bar.pmrcap, 2);
362
+ NVME_PMRCAP_SET_PMRTU(n->bar.pmrcap, 0);
363
+ /* Turn on bit 1 support */
364
+ NVME_PMRCAP_SET_PMRWBM(n->bar.pmrcap, 0x02);
365
+ NVME_PMRCAP_SET_PMRTO(n->bar.pmrcap, 0);
366
+ NVME_PMRCAP_SET_CMSS(n->bar.pmrcap, 0);
367
+
368
+ /* PMR Control register */
369
+ n->bar.pmrctl = 0;
370
+ NVME_PMRCTL_SET_EN(n->bar.pmrctl, 0);
371
+
372
+ /* PMR Status register */
373
+ n->bar.pmrsts = 0;
374
+ NVME_PMRSTS_SET_ERR(n->bar.pmrsts, 0);
375
+ NVME_PMRSTS_SET_NRDY(n->bar.pmrsts, 0);
376
+ NVME_PMRSTS_SET_HSTS(n->bar.pmrsts, 0);
377
+ NVME_PMRSTS_SET_CBAI(n->bar.pmrsts, 0);
378
+
379
+ /* PMR Elasticity Buffer Size register */
380
+ n->bar.pmrebs = 0;
381
+ NVME_PMREBS_SET_PMRSZU(n->bar.pmrebs, 0);
382
+ NVME_PMREBS_SET_RBB(n->bar.pmrebs, 0);
383
+ NVME_PMREBS_SET_PMRWBZ(n->bar.pmrebs, 0);
384
+
385
+ /* PMR Sustained Write Throughput register */
386
+ n->bar.pmrswtp = 0;
387
+ NVME_PMRSWTP_SET_PMRSWTU(n->bar.pmrswtp, 0);
388
+ NVME_PMRSWTP_SET_PMRSWTV(n->bar.pmrswtp, 0);
389
+
390
+ /* PMR Memory Space Control register */
391
+ n->bar.pmrmsc = 0;
392
+ NVME_PMRMSC_SET_CMSE(n->bar.pmrmsc, 0);
393
+ NVME_PMRMSC_SET_CBA(n->bar.pmrmsc, 0);
394
+
395
+ pci_register_bar(pci_dev, NVME_PMRCAP_BIR(n->bar.pmrcap),
396
+ PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64 |
397
+ PCI_BASE_ADDRESS_MEM_PREFETCH, &n->pmrdev->mr);
398
}
399
400
for (i = 0; i < n->num_namespaces; i++) {
401
@@ -XXX,XX +XXX,XX @@ static void nvme_exit(PCIDevice *pci_dev)
402
if (n->cmb_size_mb) {
403
g_free(n->cmbuf);
404
}
405
+
406
+ if (n->pmrdev) {
407
+ host_memory_backend_set_mapped(n->pmrdev, false);
408
+ }
409
msix_uninit_exclusive_bar(pci_dev);
410
}
411
412
static Property nvme_props[] = {
413
DEFINE_BLOCK_PROPERTIES(NvmeCtrl, conf),
414
+ DEFINE_PROP_LINK("pmrdev", NvmeCtrl, pmrdev, TYPE_MEMORY_BACKEND,
415
+ HostMemoryBackend *),
416
DEFINE_PROP_STRING("serial", NvmeCtrl, serial),
417
DEFINE_PROP_UINT32("cmb_size_mb", NvmeCtrl, cmb_size_mb, 0),
418
DEFINE_PROP_UINT32("num_queues", NvmeCtrl, num_queues, 64),
419
diff --git a/hw/block/Makefile.objs b/hw/block/Makefile.objs
420
index XXXXXXX..XXXXXXX 100644
421
--- a/hw/block/Makefile.objs
422
+++ b/hw/block/Makefile.objs
423
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_PFLASH_CFI02) += pflash_cfi02.o
424
common-obj-$(CONFIG_XEN) += xen-block.o
425
common-obj-$(CONFIG_ECC) += ecc.o
426
common-obj-$(CONFIG_ONENAND) += onenand.o
427
-common-obj-$(CONFIG_NVME_PCI) += nvme.o
428
common-obj-$(CONFIG_SWIM) += swim.o
429
430
common-obj-$(CONFIG_SH4) += tc58128.o
431
432
obj-$(CONFIG_VIRTIO_BLK) += virtio-blk.o
433
obj-$(CONFIG_VHOST_USER_BLK) += vhost-user-blk.o
434
+obj-$(CONFIG_NVME_PCI) += nvme.o
435
436
obj-y += dataplane/
437
diff --git a/hw/block/trace-events b/hw/block/trace-events
438
index XXXXXXX..XXXXXXX 100644
439
--- a/hw/block/trace-events
440
+++ b/hw/block/trace-events
441
@@ -XXX,XX +XXX,XX @@ nvme_ub_mmiowr_ssreset_w1c_unsupported(void) "attempted to W1C CSTS.NSSRO but CA
442
nvme_ub_mmiowr_ssreset_unsupported(void) "attempted NVM subsystem reset but CAP.NSSRS is zero (not supported)"
443
nvme_ub_mmiowr_cmbloc_reserved(void) "invalid write to reserved CMBLOC when CMBSZ is zero, ignored"
444
nvme_ub_mmiowr_cmbsz_readonly(void) "invalid write to read only CMBSZ, ignored"
445
+nvme_ub_mmiowr_pmrcap_readonly(void) "invalid write to read only PMRCAP, ignored"
446
+nvme_ub_mmiowr_pmrsts_readonly(void) "invalid write to read only PMRSTS, ignored"
447
+nvme_ub_mmiowr_pmrebs_readonly(void) "invalid write to read only PMREBS, ignored"
448
+nvme_ub_mmiowr_pmrswtp_readonly(void) "invalid write to read only PMRSWTP, ignored"
449
nvme_ub_mmiowr_invalid(uint64_t offset, uint64_t data) "invalid MMIO write, offset=0x%"PRIx64", data=0x%"PRIx64""
450
nvme_ub_mmiord_misaligned32(uint64_t offset) "MMIO read not 32-bit aligned, offset=0x%"PRIx64""
451
nvme_ub_mmiord_toosmall(uint64_t offset) "MMIO read smaller than 32-bits, offset=0x%"PRIx64""
452
--
36
--
453
2.25.3
37
2.29.2
454
38
455
39
diff view generated by jsdifflib