1
The following changes since commit 3fbd3405d2b0604ea530fc7a1828f19da1e95ff9:
1
The following changes since commit 23919ddfd56135cad3cb468a8f54d5a595f024f4:
2
2
3
Merge remote-tracking branch 'remotes/huth-gitlab/tags/pull-request-2019-08-17' into staging (2019-08-19 14:14:09 +0100)
3
Merge remote-tracking branch 'remotes/aperard/tags/pull-xen-20190827' into staging (2019-08-27 15:52:36 +0100)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://github.com/XanClic/qemu.git tags/pull-block-2019-08-19
7
https://github.com/XanClic/qemu.git tags/pull-block-2019-08-27
8
8
9
for you to fetch changes up to fa27c478102a6b5d1c6b02c005607ad9404b915f:
9
for you to fetch changes up to bb043c056cffcc2f3ce88bfdaf2e76e455c09e2c:
10
10
11
doc: Preallocation does not require writing zeroes (2019-08-19 17:13:26 +0200)
11
iotests: Unify cache mode quoting (2019-08-27 19:48:44 +0200)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block patches:
14
Block patches:
15
- preallocation=falloc/full support for LUKS
15
- qemu-io now accepts a file to read a write pattern from
16
- Various minor fixes
16
- Ensure that raw files have their first block allocated so we can probe
17
the O_DIRECT alignment if necessary
18
- Various fixes
17
19
18
----------------------------------------------------------------
20
----------------------------------------------------------------
19
Max Reitz (16):
21
Denis Plotnikov (1):
20
qemu-img: Fix bdrv_has_zero_init() use in convert
22
qemu-io: add pattern file for write command
21
mirror: Fix bdrv_has_zero_init() use
22
block: Add bdrv_has_zero_init_truncate()
23
block: Implement .bdrv_has_zero_init_truncate()
24
block: Use bdrv_has_zero_init_truncate()
25
qcow2: Fix .bdrv_has_zero_init()
26
vdi: Fix .bdrv_has_zero_init()
27
vhdx: Fix .bdrv_has_zero_init()
28
iotests: Convert to preallocated encrypted qcow2
29
iotests: Test convert -n to pre-filled image
30
iotests: Full mirror to existing non-zero image
31
vdi: Make block_status recurse for fixed images
32
vmdk: Make block_status recurse for flat extents
33
vpc: Do not return RAW from block_status
34
iotests: Fix 141 when run with qed
35
doc: Preallocation does not require writing zeroes
36
23
37
Maxim Levitsky (1):
24
Max Reitz (7):
38
LUKS: support preallocation
25
iotests: Fix _filter_img_create()
26
vmdk: Use bdrv_dirname() for relative extent paths
27
iotests: Keep testing broken relative extent paths
28
vmdk: Reject invalid compressed writes
29
iotests: Disable broken streamOptimized tests
30
iotests: Disable 110 for vmdk.twoGbMaxExtentSparse
31
iotests: Disable 126 for flat vmdk subformats
39
32
40
qapi/block-core.json | 15 +++++---
33
Nir Soffer (3):
41
include/block/block.h | 1 +
34
block: posix: Always allocate the first block
42
include/block/block_int.h | 9 +++++
35
iotests: Test allocate_first_block() with O_DIRECT
43
block.c | 21 +++++++++++
36
iotests: Unify cache mode quoting
44
block/crypto.c | 30 ++++++++++++++--
37
45
block/file-posix.c | 1 +
38
Stefan Hajnoczi (1):
46
block/file-win32.c | 1 +
39
file-posix: fix request_alignment typo
47
block/gluster.c | 4 +++
40
48
block/mirror.c | 11 ++++--
41
Thomas Huth (2):
49
block/nfs.c | 1 +
42
iotests: Check for enabled drivers before testing them
50
block/parallels.c | 2 +-
43
tests/check-block: Skip iotests when sanitizers are enabled
51
block/qcow2.c | 30 +++++++++++++++-
44
52
block/qed.c | 1 +
45
Vladimir Sementsov-Ogievskiy (1):
53
block/raw-format.c | 6 ++++
46
block: fix permission update in bdrv_replace_node
54
block/rbd.c | 1 +
47
55
block/sheepdog.c | 1 +
48
block.c | 5 +-
56
block/ssh.c | 1 +
49
block/file-posix.c | 53 +++++++++-
57
block/vdi.c | 16 +++++++--
50
block/vmdk.c | 64 ++++++++----
58
block/vhdx.c | 28 +++++++++++++--
51
qemu-io-cmds.c | 99 +++++++++++++++++--
59
block/vmdk.c | 3 ++
52
tests/check-block.sh | 5 +
60
block/vpc.c | 2 +-
53
tests/qemu-iotests/002 | 1 +
61
blockdev.c | 16 +++++++--
54
tests/qemu-iotests/003 | 1 +
62
qemu-img.c | 11 ++++--
55
tests/qemu-iotests/005 | 3 +-
63
tests/test-block-iothread.c | 2 +-
56
tests/qemu-iotests/009 | 1 +
64
docs/qemu-block-drivers.texi | 4 +--
57
tests/qemu-iotests/010 | 1 +
65
qemu-img.texi | 4 +--
58
tests/qemu-iotests/011 | 1 +
66
tests/qemu-iotests/041 | 62 +++++++++++++++++++++++++++++---
59
tests/qemu-iotests/017 | 3 +-
67
tests/qemu-iotests/041.out | 4 +--
60
tests/qemu-iotests/018 | 3 +-
68
tests/qemu-iotests/122 | 17 +++++++++
61
tests/qemu-iotests/019 | 3 +-
69
tests/qemu-iotests/122.out | 8 +++++
62
tests/qemu-iotests/020 | 3 +-
70
tests/qemu-iotests/141 | 9 +++--
63
tests/qemu-iotests/026 | 4 +-
71
tests/qemu-iotests/141.out | 5 ---
64
tests/qemu-iotests/027 | 1 +
72
tests/qemu-iotests/188 | 20 ++++++++++-
65
tests/qemu-iotests/032 | 1 +
73
tests/qemu-iotests/188.out | 4 +++
66
tests/qemu-iotests/033 | 1 +
74
tests/qemu-iotests/common.filter | 5 +++
67
tests/qemu-iotests/034 | 3 +-
75
35 files changed, 313 insertions(+), 43 deletions(-)
68
tests/qemu-iotests/037 | 3 +-
69
tests/qemu-iotests/039 | 4 +-
70
tests/qemu-iotests/052 | 2 +-
71
tests/qemu-iotests/059 | 34 ++++++-
72
tests/qemu-iotests/059.out | 26 +++--
73
tests/qemu-iotests/063 | 3 +-
74
tests/qemu-iotests/071 | 1 +
75
tests/qemu-iotests/072 | 1 +
76
tests/qemu-iotests/081 | 4 +-
77
tests/qemu-iotests/091 | 4 +-
78
tests/qemu-iotests/099 | 1 +
79
tests/qemu-iotests/105 | 3 +-
80
tests/qemu-iotests/110 | 3 +-
81
tests/qemu-iotests/120 | 1 +
82
tests/qemu-iotests/126 | 2 +
83
tests/qemu-iotests/{150.out => 150.out.qcow2} | 0
84
tests/qemu-iotests/150.out.raw | 12 +++
85
tests/qemu-iotests/162 | 4 +-
86
tests/qemu-iotests/175 | 47 +++++++--
87
tests/qemu-iotests/175.out | 16 ++-
88
tests/qemu-iotests/178.out.qcow2 | 4 +-
89
tests/qemu-iotests/184 | 1 +
90
tests/qemu-iotests/186 | 1 +
91
tests/qemu-iotests/197 | 1 +
92
tests/qemu-iotests/215 | 1 +
93
tests/qemu-iotests/221.out | 12 ++-
94
tests/qemu-iotests/251 | 1 +
95
tests/qemu-iotests/253.out | 12 ++-
96
tests/qemu-iotests/common.filter | 4 +-
97
tests/qemu-iotests/common.rc | 14 +++
98
50 files changed, 391 insertions(+), 87 deletions(-)
99
rename tests/qemu-iotests/{150.out => 150.out.qcow2} (100%)
100
create mode 100644 tests/qemu-iotests/150.out.raw
76
101
77
--
102
--
78
2.21.0
103
2.21.0
79
104
80
105
diff view generated by jsdifflib
1
From: Maxim Levitsky <mlevitsk@redhat.com>
1
From: Denis Plotnikov <dplotnikov@virtuozzo.com>
2
2
3
preallocation=off and preallocation=metadata
3
The patch allows to provide a pattern file for write
4
both allocate luks header only, and preallocation=falloc/full
4
command. There was no similar ability before.
5
is passed to underlying file.
6
5
7
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1534951
6
Signed-off-by: Denis Plotnikov <dplotnikov@virtuozzo.com>
8
7
Message-id: 20190820164616.4072-1-dplotnikov@virtuozzo.com
9
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
8
Reviewed-by: Eric Blake <eblake@redhat.com>
10
Message-id: 20190716161901.1430-1-mlevitsk@redhat.com
9
[mreitz: Keep optstring in alphabetical order]
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
---
11
---
13
qapi/block-core.json | 6 +++++-
12
qemu-io-cmds.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++---
14
block/crypto.c | 30 +++++++++++++++++++++++++++---
13
1 file changed, 93 insertions(+), 6 deletions(-)
15
2 files changed, 32 insertions(+), 4 deletions(-)
16
14
17
diff --git a/qapi/block-core.json b/qapi/block-core.json
15
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/qapi/block-core.json
17
--- a/qemu-io-cmds.c
20
+++ b/qapi/block-core.json
18
+++ b/qemu-io-cmds.c
21
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static void qemu_io_free(void *p)
22
#
20
qemu_vfree(p);
23
# @file Node to create the image format on
24
# @size Size of the virtual disk in bytes
25
+# @preallocation Preallocation mode for the new image
26
+# (since: 4.2)
27
+# (default: off; allowed values: off, metadata, falloc, full)
28
#
29
# Since: 2.12
30
##
31
{ 'struct': 'BlockdevCreateOptionsLUKS',
32
'base': 'QCryptoBlockCreateOptionsLUKS',
33
'data': { 'file': 'BlockdevRef',
34
- 'size': 'size' } }
35
+ 'size': 'size',
36
+ '*preallocation': 'PreallocMode' } }
37
38
##
39
# @BlockdevCreateOptionsNfs:
40
diff --git a/block/crypto.c b/block/crypto.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/block/crypto.c
43
+++ b/block/crypto.c
44
@@ -XXX,XX +XXX,XX @@ static ssize_t block_crypto_read_func(QCryptoBlock *block,
45
struct BlockCryptoCreateData {
46
BlockBackend *blk;
47
uint64_t size;
48
+ PreallocMode prealloc;
49
};
50
51
52
@@ -XXX,XX +XXX,XX @@ static ssize_t block_crypto_init_func(QCryptoBlock *block,
53
* available to the guest, so we must take account of that
54
* which will be used by the crypto header
55
*/
56
- return blk_truncate(data->blk, data->size + headerlen, PREALLOC_MODE_OFF,
57
+ return blk_truncate(data->blk, data->size + headerlen, data->prealloc,
58
errp);
59
}
21
}
60
22
61
@@ -XXX,XX +XXX,XX @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
23
+/*
62
static int block_crypto_co_create_generic(BlockDriverState *bs,
24
+ * qemu_io_alloc_from_file()
63
int64_t size,
25
+ *
64
QCryptoBlockCreateOptions *opts,
26
+ * Allocates the buffer and populates it with the content of the given file
65
+ PreallocMode prealloc,
27
+ * up to @len bytes. If the file length is less than @len, then the buffer
66
Error **errp)
28
+ * is populated with the file content cyclically.
67
{
29
+ *
68
int ret;
30
+ * @blk - the block backend where the buffer content is going to be written to
69
@@ -XXX,XX +XXX,XX @@ static int block_crypto_co_create_generic(BlockDriverState *bs,
31
+ * @len - the buffer length
70
goto cleanup;
32
+ * @file_name - the file to read the content from
71
}
33
+ *
72
34
+ * Returns: the buffer pointer on success
73
+ if (prealloc == PREALLOC_MODE_METADATA) {
35
+ * NULL on error
74
+ prealloc = PREALLOC_MODE_OFF;
36
+ */
37
+static void *qemu_io_alloc_from_file(BlockBackend *blk, size_t len,
38
+ const char *file_name)
39
+{
40
+ char *buf, *buf_origin;
41
+ FILE *f = fopen(file_name, "r");
42
+ int pattern_len;
43
+
44
+ if (!f) {
45
+ perror(file_name);
46
+ return NULL;
75
+ }
47
+ }
76
+
48
+
77
data = (struct BlockCryptoCreateData) {
49
+ if (qemuio_misalign) {
78
.blk = blk,
50
+ len += MISALIGN_OFFSET;
79
.size = size,
80
+ .prealloc = prealloc,
81
};
82
83
crypto = qcrypto_block_create(opts, NULL,
84
@@ -XXX,XX +XXX,XX @@ block_crypto_co_create_luks(BlockdevCreateOptions *create_options, Error **errp)
85
BlockdevCreateOptionsLUKS *luks_opts;
86
BlockDriverState *bs = NULL;
87
QCryptoBlockCreateOptions create_opts;
88
+ PreallocMode preallocation = PREALLOC_MODE_OFF;
89
int ret;
90
91
assert(create_options->driver == BLOCKDEV_DRIVER_LUKS);
92
@@ -XXX,XX +XXX,XX @@ block_crypto_co_create_luks(BlockdevCreateOptions *create_options, Error **errp)
93
.u.luks = *qapi_BlockdevCreateOptionsLUKS_base(luks_opts),
94
};
95
96
+ if (luks_opts->has_preallocation) {
97
+ preallocation = luks_opts->preallocation;
98
+ }
51
+ }
99
+
52
+
100
ret = block_crypto_co_create_generic(bs, luks_opts->size, &create_opts,
53
+ buf_origin = buf = blk_blockalign(blk, len);
101
- errp);
54
+
102
+ preallocation, errp);
55
+ if (qemuio_misalign) {
103
if (ret < 0) {
56
+ buf_origin += MISALIGN_OFFSET;
104
goto fail;
57
+ buf += MISALIGN_OFFSET;
105
}
58
+ len -= MISALIGN_OFFSET;
106
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn block_crypto_co_create_opts_luks(const char *filename,
107
QCryptoBlockCreateOptions *create_opts = NULL;
108
BlockDriverState *bs = NULL;
109
QDict *cryptoopts;
110
+ PreallocMode prealloc;
111
+ char *buf = NULL;
112
int64_t size;
113
int ret;
114
+ Error *local_err = NULL;
115
116
/* Parse options */
117
size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
118
119
+ buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
120
+ prealloc = qapi_enum_parse(&PreallocMode_lookup, buf,
121
+ PREALLOC_MODE_OFF, &local_err);
122
+ g_free(buf);
123
+ if (local_err) {
124
+ error_propagate(errp, local_err);
125
+ return -EINVAL;
126
+ }
59
+ }
127
+
60
+
128
cryptoopts = qemu_opts_to_qdict_filtered(opts, NULL,
61
+ pattern_len = fread(buf_origin, 1, len, f);
129
&block_crypto_create_opts_luks,
62
+
130
true);
63
+ if (ferror(f)) {
131
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn block_crypto_co_create_opts_luks(const char *filename,
64
+ perror(file_name);
65
+ goto error;
66
+ }
67
+
68
+ if (pattern_len == 0) {
69
+ fprintf(stderr, "%s: file is empty\n", file_name);
70
+ goto error;
71
+ }
72
+
73
+ fclose(f);
74
+
75
+ if (len > pattern_len) {
76
+ len -= pattern_len;
77
+ buf += pattern_len;
78
+
79
+ while (len > 0) {
80
+ size_t len_to_copy = MIN(pattern_len, len);
81
+
82
+ memcpy(buf, buf_origin, len_to_copy);
83
+
84
+ len -= len_to_copy;
85
+ buf += len_to_copy;
86
+ }
87
+ }
88
+
89
+ return buf_origin;
90
+
91
+error:
92
+ qemu_io_free(buf_origin);
93
+ return NULL;
94
+}
95
+
96
static void dump_buffer(const void *buffer, int64_t offset, int64_t len)
97
{
98
uint64_t i;
99
@@ -XXX,XX +XXX,XX @@ static void write_help(void)
100
" -n, -- with -z, don't allow slow fallback\n"
101
" -p, -- ignored for backwards compatibility\n"
102
" -P, -- use different pattern to fill file\n"
103
+" -s, -- use a pattern file to fill the write buffer\n"
104
" -C, -- report statistics in a machine parsable format\n"
105
" -q, -- quiet mode, do not show I/O statistics\n"
106
" -u, -- with -z, allow unmapping\n"
107
@@ -XXX,XX +XXX,XX @@ static const cmdinfo_t write_cmd = {
108
.perm = BLK_PERM_WRITE,
109
.argmin = 2,
110
.argmax = -1,
111
- .args = "[-bcCfnquz] [-P pattern] off len",
112
+ .args = "[-bcCfnquz] [-P pattern | -s source_file] off len",
113
.oneline = "writes a number of bytes at a specified offset",
114
.help = write_help,
115
};
116
@@ -XXX,XX +XXX,XX @@ static int write_f(BlockBackend *blk, int argc, char **argv)
117
{
118
struct timespec t1, t2;
119
bool Cflag = false, qflag = false, bflag = false;
120
- bool Pflag = false, zflag = false, cflag = false;
121
+ bool Pflag = false, zflag = false, cflag = false, sflag = false;
122
int flags = 0;
123
int c, cnt, ret;
124
char *buf = NULL;
125
@@ -XXX,XX +XXX,XX @@ static int write_f(BlockBackend *blk, int argc, char **argv)
126
/* Some compilers get confused and warn if this is not initialized. */
127
int64_t total = 0;
128
int pattern = 0xcd;
129
+ const char *file_name = NULL;
130
131
- while ((c = getopt(argc, argv, "bcCfnpP:quz")) != -1) {
132
+ while ((c = getopt(argc, argv, "bcCfnpP:qs:uz")) != -1) {
133
switch (c) {
134
case 'b':
135
bflag = true;
136
@@ -XXX,XX +XXX,XX @@ static int write_f(BlockBackend *blk, int argc, char **argv)
137
case 'q':
138
qflag = true;
139
break;
140
+ case 's':
141
+ sflag = true;
142
+ file_name = optarg;
143
+ break;
144
case 'u':
145
flags |= BDRV_REQ_MAY_UNMAP;
146
break;
147
@@ -XXX,XX +XXX,XX @@ static int write_f(BlockBackend *blk, int argc, char **argv)
148
return -EINVAL;
132
}
149
}
133
150
134
/* Create format layer */
151
- if (zflag && Pflag) {
135
- ret = block_crypto_co_create_generic(bs, size, create_opts, errp);
152
- printf("-z and -P cannot be specified at the same time\n");
136
+ ret = block_crypto_co_create_generic(bs, size, create_opts, prealloc, errp);
153
+ if (zflag + Pflag + sflag > 1) {
137
if (ret < 0) {
154
+ printf("Only one of -z, -P, and -s "
138
goto fail;
155
+ "can be specified at the same time\n");
156
return -EINVAL;
139
}
157
}
158
159
@@ -XXX,XX +XXX,XX @@ static int write_f(BlockBackend *blk, int argc, char **argv)
160
}
161
162
if (!zflag) {
163
- buf = qemu_io_alloc(blk, count, pattern);
164
+ if (sflag) {
165
+ buf = qemu_io_alloc_from_file(blk, count, file_name);
166
+ if (!buf) {
167
+ return -EINVAL;
168
+ }
169
+ } else {
170
+ buf = qemu_io_alloc(blk, count, pattern);
171
+ }
172
}
173
174
clock_gettime(CLOCK_MONOTONIC, &t1);
140
--
175
--
141
2.21.0
176
2.21.0
142
177
143
178
diff view generated by jsdifflib
Deleted patch
1
bdrv_has_zero_init() only has meaning for newly created images or image
2
areas. If qemu-img convert did not create the image itself, it cannot
3
rely on bdrv_has_zero_init()'s result to carry any meaning.
4
1
5
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
Message-id: 20190724171239.8764-2-mreitz@redhat.com
7
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
8
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
---
11
qemu-img.c | 11 ++++++++---
12
1 file changed, 8 insertions(+), 3 deletions(-)
13
14
diff --git a/qemu-img.c b/qemu-img.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/qemu-img.c
17
+++ b/qemu-img.c
18
@@ -XXX,XX +XXX,XX @@ typedef struct ImgConvertState {
19
bool has_zero_init;
20
bool compressed;
21
bool unallocated_blocks_are_zero;
22
+ bool target_is_new;
23
bool target_has_backing;
24
int64_t target_backing_sectors; /* negative if unknown */
25
bool wr_in_order;
26
@@ -XXX,XX +XXX,XX @@ static int convert_do_copy(ImgConvertState *s)
27
int64_t sector_num = 0;
28
29
/* Check whether we have zero initialisation or can get it efficiently */
30
- s->has_zero_init = s->min_sparse && !s->target_has_backing
31
- ? bdrv_has_zero_init(blk_bs(s->target))
32
- : false;
33
+ if (s->target_is_new && s->min_sparse && !s->target_has_backing) {
34
+ s->has_zero_init = bdrv_has_zero_init(blk_bs(s->target));
35
+ } else {
36
+ s->has_zero_init = false;
37
+ }
38
39
if (!s->has_zero_init && !s->target_has_backing &&
40
bdrv_can_write_zeroes_with_unmap(blk_bs(s->target)))
41
@@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv)
42
}
43
}
44
45
+ s.target_is_new = !skip_create;
46
+
47
flags = s.min_sparse ? (BDRV_O_RDWR | BDRV_O_UNMAP) : BDRV_O_RDWR;
48
ret = bdrv_parse_cache_mode(cache, &flags, &writethrough);
49
if (ret < 0) {
50
--
51
2.21.0
52
53
diff view generated by jsdifflib
1
No .bdrv_has_zero_init() implementation returns 1 if growing the file
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
would add non-zero areas (at least with PREALLOC_MODE_OFF), so using it
3
in lieu of this new function was always safe.
4
2
5
But on the other hand, it is possible that growing an image that is not
3
It's wrong to OR shared permissions. It may lead to crash on further
6
zero-initialized would still add a zero-initialized area, like when
4
permission updates.
7
using nonpreallocating truncation on a preallocated image. For callers
5
Also, no needs to consider previously calculated permissions, as at
8
that care only about truncation, not about creation with potential
6
this point we already bind all new parents and bdrv_get_cumulative_perm
9
preallocation, this new function is useful.
7
result is enough. So fix the bug by just set permissions by
8
bdrv_get_cumulative_perm result.
10
9
11
Alternatively, we could have added a PreallocMode parameter to
10
Bug was introduced in long ago 234ac1a9025, in 2.9.
12
bdrv_has_zero_init(). But the only user would have been qemu-img
13
convert, which does not have a plain PreallocMode value right now -- it
14
would have to parse the creation option to obtain it. Therefore, the
15
simpler solution is to let bdrv_has_zero_init() inquire the
16
preallocation status and add the new bdrv_has_zero_init_truncate() that
17
presupposes PREALLOC_MODE_OFF.
18
11
19
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
20
Message-id: 20190724171239.8764-4-mreitz@redhat.com
13
Message-id: 20190824100740.61635-1-vsementsov@virtuozzo.com
21
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
22
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
23
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
24
---
15
---
25
include/block/block.h | 1 +
16
block.c | 5 ++---
26
include/block/block_int.h | 7 +++++++
17
1 file changed, 2 insertions(+), 3 deletions(-)
27
block.c | 21 +++++++++++++++++++++
28
3 files changed, 29 insertions(+)
29
18
30
diff --git a/include/block/block.h b/include/block/block.h
31
index XXXXXXX..XXXXXXX 100644
32
--- a/include/block/block.h
33
+++ b/include/block/block.h
34
@@ -XXX,XX +XXX,XX @@ int bdrv_pdiscard(BdrvChild *child, int64_t offset, int64_t bytes);
35
int bdrv_co_pdiscard(BdrvChild *child, int64_t offset, int64_t bytes);
36
int bdrv_has_zero_init_1(BlockDriverState *bs);
37
int bdrv_has_zero_init(BlockDriverState *bs);
38
+int bdrv_has_zero_init_truncate(BlockDriverState *bs);
39
bool bdrv_unallocated_blocks_are_zero(BlockDriverState *bs);
40
bool bdrv_can_write_zeroes_with_unmap(BlockDriverState *bs);
41
int bdrv_block_status(BlockDriverState *bs, int64_t offset,
42
diff --git a/include/block/block_int.h b/include/block/block_int.h
43
index XXXXXXX..XXXXXXX 100644
44
--- a/include/block/block_int.h
45
+++ b/include/block/block_int.h
46
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
47
/*
48
* Returns 1 if newly created images are guaranteed to contain only
49
* zeros, 0 otherwise.
50
+ * Must return 0 if .bdrv_has_zero_init_truncate() returns 0.
51
*/
52
int (*bdrv_has_zero_init)(BlockDriverState *bs);
53
54
+ /*
55
+ * Returns 1 if new areas added by growing the image with
56
+ * PREALLOC_MODE_OFF contain only zeros, 0 otherwise.
57
+ */
58
+ int (*bdrv_has_zero_init_truncate)(BlockDriverState *bs);
59
+
60
/* Remove fd handlers, timers, and other event loop callbacks so the event
61
* loop is no longer in use. Called with no in-flight requests and in
62
* depth-first traversal order with parents before child nodes.
63
diff --git a/block.c b/block.c
19
diff --git a/block.c b/block.c
64
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
65
--- a/block.c
21
--- a/block.c
66
+++ b/block.c
22
+++ b/block.c
67
@@ -XXX,XX +XXX,XX @@ int bdrv_has_zero_init(BlockDriverState *bs)
23
@@ -XXX,XX +XXX,XX @@ void bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
68
return 0;
69
}
70
71
+int bdrv_has_zero_init_truncate(BlockDriverState *bs)
72
+{
73
+ if (!bs->drv) {
74
+ return 0;
75
+ }
76
+
77
+ if (bs->backing) {
78
+ /* Depends on the backing image length, but better safe than sorry */
79
+ return 0;
80
+ }
81
+ if (bs->drv->bdrv_has_zero_init_truncate) {
82
+ return bs->drv->bdrv_has_zero_init_truncate(bs);
83
+ }
84
+ if (bs->file && bs->drv->is_filter) {
85
+ return bdrv_has_zero_init_truncate(bs->file->bs);
86
+ }
87
+
88
+ /* safe default */
89
+ return 0;
90
+}
91
+
92
bool bdrv_unallocated_blocks_are_zero(BlockDriverState *bs)
93
{
24
{
94
BlockDriverInfo bdi;
25
BdrvChild *c, *next;
26
GSList *list = NULL, *p;
27
- uint64_t old_perm, old_shared;
28
uint64_t perm = 0, shared = BLK_PERM_ALL;
29
int ret;
30
31
@@ -XXX,XX +XXX,XX @@ void bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
32
bdrv_unref(from);
33
}
34
35
- bdrv_get_cumulative_perm(to, &old_perm, &old_shared);
36
- bdrv_set_perm(to, old_perm | perm, old_shared | shared);
37
+ bdrv_get_cumulative_perm(to, &perm, &shared);
38
+ bdrv_set_perm(to, perm, shared);
39
40
out:
41
g_slist_free(list);
95
--
42
--
96
2.21.0
43
2.21.0
97
44
98
45
diff view generated by jsdifflib
1
We need to implement .bdrv_has_zero_init_truncate() for every block
1
From: Nir Soffer <nirsof@gmail.com>
2
driver that supports truncation and has a .bdrv_has_zero_init()
2
3
implementation.
3
When creating an image with preallocation "off" or "falloc", the first
4
4
block of the image is typically not allocated. When using Gluster
5
Implement it the same way each driver implements .bdrv_has_zero_init().
5
storage backed by XFS filesystem, reading this block using direct I/O
6
This is at least not any more unsafe than what we had before.
6
succeeds regardless of request length, fooling alignment detection.
7
7
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
In this case we fallback to a safe value (4096) instead of the optimal
9
Message-id: 20190724171239.8764-5-mreitz@redhat.com
9
value (512), which may lead to unneeded data copying when aligning
10
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
10
requests. Allocating the first block avoids the fallback.
11
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
11
12
Since we allocate the first block even with preallocation=off, we no
13
longer create images with zero disk size:
14
15
$ ./qemu-img create -f raw test.raw 1g
16
Formatting 'test.raw', fmt=raw size=1073741824
17
18
$ ls -lhs test.raw
19
4.0K -rw-r--r--. 1 nsoffer nsoffer 1.0G Aug 16 23:48 test.raw
20
21
And converting the image requires additional cluster:
22
23
$ ./qemu-img measure -f raw -O qcow2 test.raw
24
required size: 458752
25
fully allocated size: 1074135040
26
27
When using format like vmdk with multiple files per image, we allocate
28
one block per file:
29
30
$ ./qemu-img create -f vmdk -o subformat=twoGbMaxExtentFlat test.vmdk 4g
31
Formatting 'test.vmdk', fmt=vmdk size=4294967296 compat6=off hwversion=undefined subformat=twoGbMaxExtentFlat
32
33
$ ls -lhs test*.vmdk
34
4.0K -rw-r--r--. 1 nsoffer nsoffer 2.0G Aug 27 03:23 test-f001.vmdk
35
4.0K -rw-r--r--. 1 nsoffer nsoffer 2.0G Aug 27 03:23 test-f002.vmdk
36
4.0K -rw-r--r--. 1 nsoffer nsoffer 353 Aug 27 03:23 test.vmdk
37
38
I did quick performance test for copying disks with qemu-img convert to
39
new raw target image to Gluster storage with sector size of 512 bytes:
40
41
for i in $(seq 10); do
42
rm -f dst.raw
43
sleep 10
44
time ./qemu-img convert -f raw -O raw -t none -T none src.raw dst.raw
45
done
46
47
Here is a table comparing the total time spent:
48
49
Type Before(s) After(s) Diff(%)
50
---------------------------------------
51
real 530.028 469.123 -11.4
52
user 17.204 10.768 -37.4
53
sys 17.881 7.011 -60.7
54
55
We can see very clear improvement in CPU usage.
56
57
Signed-off-by: Nir Soffer <nsoffer@redhat.com>
58
Message-id: 20190827010528.8818-2-nsoffer@redhat.com
59
Reviewed-by: Max Reitz <mreitz@redhat.com>
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
60
Signed-off-by: Max Reitz <mreitz@redhat.com>
13
---
61
---
14
block/file-posix.c | 1 +
62
block/file-posix.c | 51 +++++++++++++++++++
15
block/file-win32.c | 1 +
63
tests/qemu-iotests/059.out | 2 +-
16
block/gluster.c | 4 ++++
64
tests/qemu-iotests/{150.out => 150.out.qcow2} | 0
17
block/nfs.c | 1 +
65
tests/qemu-iotests/150.out.raw | 12 +++++
18
block/qcow2.c | 1 +
66
tests/qemu-iotests/175 | 19 ++++---
19
block/qed.c | 1 +
67
tests/qemu-iotests/175.out | 8 +--
20
block/raw-format.c | 6 ++++++
68
tests/qemu-iotests/178.out.qcow2 | 4 +-
21
block/rbd.c | 1 +
69
tests/qemu-iotests/221.out | 12 +++--
22
block/sheepdog.c | 1 +
70
tests/qemu-iotests/253.out | 12 +++--
23
block/ssh.c | 1 +
71
9 files changed, 99 insertions(+), 21 deletions(-)
24
10 files changed, 18 insertions(+)
72
rename tests/qemu-iotests/{150.out => 150.out.qcow2} (100%)
73
create mode 100644 tests/qemu-iotests/150.out.raw
25
74
26
diff --git a/block/file-posix.c b/block/file-posix.c
75
diff --git a/block/file-posix.c b/block/file-posix.c
27
index XXXXXXX..XXXXXXX 100644
76
index XXXXXXX..XXXXXXX 100644
28
--- a/block/file-posix.c
77
--- a/block/file-posix.c
29
+++ b/block/file-posix.c
78
+++ b/block/file-posix.c
30
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_file = {
79
@@ -XXX,XX +XXX,XX @@ static int handle_aiocb_discard(void *opaque)
31
.bdrv_co_create = raw_co_create,
80
return ret;
32
.bdrv_co_create_opts = raw_co_create_opts,
33
.bdrv_has_zero_init = bdrv_has_zero_init_1,
34
+ .bdrv_has_zero_init_truncate = bdrv_has_zero_init_1,
35
.bdrv_co_block_status = raw_co_block_status,
36
.bdrv_co_invalidate_cache = raw_co_invalidate_cache,
37
.bdrv_co_pwrite_zeroes = raw_co_pwrite_zeroes,
38
diff --git a/block/file-win32.c b/block/file-win32.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/block/file-win32.c
41
+++ b/block/file-win32.c
42
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_file = {
43
.bdrv_close = raw_close,
44
.bdrv_co_create_opts = raw_co_create_opts,
45
.bdrv_has_zero_init = bdrv_has_zero_init_1,
46
+ .bdrv_has_zero_init_truncate = bdrv_has_zero_init_1,
47
48
.bdrv_aio_preadv = raw_aio_preadv,
49
.bdrv_aio_pwritev = raw_aio_pwritev,
50
diff --git a/block/gluster.c b/block/gluster.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/block/gluster.c
53
+++ b/block/gluster.c
54
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_gluster = {
55
.bdrv_co_writev = qemu_gluster_co_writev,
56
.bdrv_co_flush_to_disk = qemu_gluster_co_flush_to_disk,
57
.bdrv_has_zero_init = qemu_gluster_has_zero_init,
58
+ .bdrv_has_zero_init_truncate = qemu_gluster_has_zero_init,
59
#ifdef CONFIG_GLUSTERFS_DISCARD
60
.bdrv_co_pdiscard = qemu_gluster_co_pdiscard,
61
#endif
62
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_gluster_tcp = {
63
.bdrv_co_writev = qemu_gluster_co_writev,
64
.bdrv_co_flush_to_disk = qemu_gluster_co_flush_to_disk,
65
.bdrv_has_zero_init = qemu_gluster_has_zero_init,
66
+ .bdrv_has_zero_init_truncate = qemu_gluster_has_zero_init,
67
#ifdef CONFIG_GLUSTERFS_DISCARD
68
.bdrv_co_pdiscard = qemu_gluster_co_pdiscard,
69
#endif
70
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_gluster_unix = {
71
.bdrv_co_writev = qemu_gluster_co_writev,
72
.bdrv_co_flush_to_disk = qemu_gluster_co_flush_to_disk,
73
.bdrv_has_zero_init = qemu_gluster_has_zero_init,
74
+ .bdrv_has_zero_init_truncate = qemu_gluster_has_zero_init,
75
#ifdef CONFIG_GLUSTERFS_DISCARD
76
.bdrv_co_pdiscard = qemu_gluster_co_pdiscard,
77
#endif
78
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_gluster_rdma = {
79
.bdrv_co_writev = qemu_gluster_co_writev,
80
.bdrv_co_flush_to_disk = qemu_gluster_co_flush_to_disk,
81
.bdrv_has_zero_init = qemu_gluster_has_zero_init,
82
+ .bdrv_has_zero_init_truncate = qemu_gluster_has_zero_init,
83
#ifdef CONFIG_GLUSTERFS_DISCARD
84
.bdrv_co_pdiscard = qemu_gluster_co_pdiscard,
85
#endif
86
diff --git a/block/nfs.c b/block/nfs.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/block/nfs.c
89
+++ b/block/nfs.c
90
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_nfs = {
91
.create_opts = &nfs_create_opts,
92
93
.bdrv_has_zero_init = nfs_has_zero_init,
94
+ .bdrv_has_zero_init_truncate = nfs_has_zero_init,
95
.bdrv_get_allocated_file_size = nfs_get_allocated_file_size,
96
.bdrv_co_truncate = nfs_file_co_truncate,
97
98
diff --git a/block/qcow2.c b/block/qcow2.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/block/qcow2.c
101
+++ b/block/qcow2.c
102
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_qcow2 = {
103
.bdrv_co_create_opts = qcow2_co_create_opts,
104
.bdrv_co_create = qcow2_co_create,
105
.bdrv_has_zero_init = bdrv_has_zero_init_1,
106
+ .bdrv_has_zero_init_truncate = bdrv_has_zero_init_1,
107
.bdrv_co_block_status = qcow2_co_block_status,
108
109
.bdrv_co_preadv = qcow2_co_preadv,
110
diff --git a/block/qed.c b/block/qed.c
111
index XXXXXXX..XXXXXXX 100644
112
--- a/block/qed.c
113
+++ b/block/qed.c
114
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_qed = {
115
.bdrv_co_create = bdrv_qed_co_create,
116
.bdrv_co_create_opts = bdrv_qed_co_create_opts,
117
.bdrv_has_zero_init = bdrv_has_zero_init_1,
118
+ .bdrv_has_zero_init_truncate = bdrv_has_zero_init_1,
119
.bdrv_co_block_status = bdrv_qed_co_block_status,
120
.bdrv_co_readv = bdrv_qed_co_readv,
121
.bdrv_co_writev = bdrv_qed_co_writev,
122
diff --git a/block/raw-format.c b/block/raw-format.c
123
index XXXXXXX..XXXXXXX 100644
124
--- a/block/raw-format.c
125
+++ b/block/raw-format.c
126
@@ -XXX,XX +XXX,XX @@ static int raw_has_zero_init(BlockDriverState *bs)
127
return bdrv_has_zero_init(bs->file->bs);
128
}
81
}
129
82
130
+static int raw_has_zero_init_truncate(BlockDriverState *bs)
83
+/*
84
+ * Help alignment probing by allocating the first block.
85
+ *
86
+ * When reading with direct I/O from unallocated area on Gluster backed by XFS,
87
+ * reading succeeds regardless of request length. In this case we fallback to
88
+ * safe alignment which is not optimal. Allocating the first block avoids this
89
+ * fallback.
90
+ *
91
+ * fd may be opened with O_DIRECT, but we don't know the buffer alignment or
92
+ * request alignment, so we use safe values.
93
+ *
94
+ * Returns: 0 on success, -errno on failure. Since this is an optimization,
95
+ * caller may ignore failures.
96
+ */
97
+static int allocate_first_block(int fd, size_t max_size)
131
+{
98
+{
132
+ return bdrv_has_zero_init_truncate(bs->file->bs);
99
+ size_t write_size = (max_size < MAX_BLOCKSIZE)
100
+ ? BDRV_SECTOR_SIZE
101
+ : MAX_BLOCKSIZE;
102
+ size_t max_align = MAX(MAX_BLOCKSIZE, getpagesize());
103
+ void *buf;
104
+ ssize_t n;
105
+ int ret;
106
+
107
+ buf = qemu_memalign(max_align, write_size);
108
+ memset(buf, 0, write_size);
109
+
110
+ do {
111
+ n = pwrite(fd, buf, write_size, 0);
112
+ } while (n == -1 && errno == EINTR);
113
+
114
+ ret = (n == -1) ? -errno : 0;
115
+
116
+ qemu_vfree(buf);
117
+ return ret;
133
+}
118
+}
134
+
119
+
135
static int coroutine_fn raw_co_create_opts(const char *filename, QemuOpts *opts,
120
static int handle_aiocb_truncate(void *opaque)
136
Error **errp)
137
{
121
{
138
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_raw = {
122
RawPosixAIOData *aiocb = opaque;
139
.bdrv_co_ioctl = &raw_co_ioctl,
123
@@ -XXX,XX +XXX,XX @@ static int handle_aiocb_truncate(void *opaque)
140
.create_opts = &raw_create_opts,
124
/* posix_fallocate() doesn't set errno. */
141
.bdrv_has_zero_init = &raw_has_zero_init,
125
error_setg_errno(errp, -result,
142
+ .bdrv_has_zero_init_truncate = &raw_has_zero_init_truncate,
126
"Could not preallocate new data");
143
.strong_runtime_opts = raw_strong_runtime_opts,
127
+ } else if (current_length == 0) {
144
.mutable_opts = mutable_opts,
128
+ /*
145
};
129
+ * posix_fallocate() uses fallocate() if the filesystem
146
diff --git a/block/rbd.c b/block/rbd.c
130
+ * supports it, or fallback to manually writing zeroes. If
147
index XXXXXXX..XXXXXXX 100644
131
+ * fallocate() was used, unaligned reads from the fallocated
148
--- a/block/rbd.c
132
+ * area in raw_probe_alignment() will succeed, hence we need to
149
+++ b/block/rbd.c
133
+ * allocate the first block.
150
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_rbd = {
134
+ *
151
.bdrv_co_create = qemu_rbd_co_create,
135
+ * Optimize future alignment probing; ignore failures.
152
.bdrv_co_create_opts = qemu_rbd_co_create_opts,
136
+ */
153
.bdrv_has_zero_init = bdrv_has_zero_init_1,
137
+ allocate_first_block(fd, offset);
154
+ .bdrv_has_zero_init_truncate = bdrv_has_zero_init_1,
138
}
155
.bdrv_get_info = qemu_rbd_getinfo,
139
} else {
156
.create_opts = &qemu_rbd_create_opts,
140
result = 0;
157
.bdrv_getlength = qemu_rbd_getlength,
141
@@ -XXX,XX +XXX,XX @@ static int handle_aiocb_truncate(void *opaque)
158
diff --git a/block/sheepdog.c b/block/sheepdog.c
142
if (ftruncate(fd, offset) != 0) {
159
index XXXXXXX..XXXXXXX 100644
143
result = -errno;
160
--- a/block/sheepdog.c
144
error_setg_errno(errp, -result, "Could not resize file");
161
+++ b/block/sheepdog.c
145
+ } else if (current_length == 0 && offset > current_length) {
162
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_sheepdog = {
146
+ /* Optimize future alignment probing; ignore failures. */
163
.bdrv_co_create = sd_co_create,
147
+ allocate_first_block(fd, offset);
164
.bdrv_co_create_opts = sd_co_create_opts,
148
}
165
.bdrv_has_zero_init = bdrv_has_zero_init_1,
149
return result;
166
+ .bdrv_has_zero_init_truncate = bdrv_has_zero_init_1,
150
default:
167
.bdrv_getlength = sd_getlength,
151
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
168
.bdrv_get_allocated_file_size = sd_get_allocated_file_size,
152
index XXXXXXX..XXXXXXX 100644
169
.bdrv_co_truncate = sd_co_truncate,
153
--- a/tests/qemu-iotests/059.out
170
diff --git a/block/ssh.c b/block/ssh.c
154
+++ b/tests/qemu-iotests/059.out
171
index XXXXXXX..XXXXXXX 100644
155
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824000 subformat=twoGbMax
172
--- a/block/ssh.c
156
image: TEST_DIR/t.vmdk
173
+++ b/block/ssh.c
157
file format: vmdk
174
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_ssh = {
158
virtual size: 0.977 TiB (1073741824000 bytes)
175
.bdrv_co_create_opts = ssh_co_create_opts,
159
-disk size: 16 KiB
176
.bdrv_close = ssh_close,
160
+disk size: 1.97 MiB
177
.bdrv_has_zero_init = ssh_has_zero_init,
161
Format specific information:
178
+ .bdrv_has_zero_init_truncate = ssh_has_zero_init,
162
cid: XXXXXXXX
179
.bdrv_co_readv = ssh_co_readv,
163
parent cid: XXXXXXXX
180
.bdrv_co_writev = ssh_co_writev,
164
diff --git a/tests/qemu-iotests/150.out b/tests/qemu-iotests/150.out.qcow2
181
.bdrv_getlength = ssh_getlength,
165
similarity index 100%
166
rename from tests/qemu-iotests/150.out
167
rename to tests/qemu-iotests/150.out.qcow2
168
diff --git a/tests/qemu-iotests/150.out.raw b/tests/qemu-iotests/150.out.raw
169
new file mode 100644
170
index XXXXXXX..XXXXXXX
171
--- /dev/null
172
+++ b/tests/qemu-iotests/150.out.raw
173
@@ -XXX,XX +XXX,XX @@
174
+QA output created by 150
175
+
176
+=== Mapping sparse conversion ===
177
+
178
+Offset Length File
179
+0 0x1000 TEST_DIR/t.IMGFMT
180
+
181
+=== Mapping non-sparse conversion ===
182
+
183
+Offset Length File
184
+0 0x100000 TEST_DIR/t.IMGFMT
185
+*** done
186
diff --git a/tests/qemu-iotests/175 b/tests/qemu-iotests/175
187
index XXXXXXX..XXXXXXX 100755
188
--- a/tests/qemu-iotests/175
189
+++ b/tests/qemu-iotests/175
190
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
191
# the file size. This function hides the resulting difference in the
192
# stat -c '%b' output.
193
# Parameter 1: Number of blocks an empty file occupies
194
-# Parameter 2: Image size in bytes
195
+# Parameter 2: Minimal number of blocks in an image
196
+# Parameter 3: Image size in bytes
197
_filter_blocks()
198
{
199
extra_blocks=$1
200
- img_size=$2
201
+ min_blocks=$2
202
+ img_size=$3
203
204
- sed -e "s/blocks=$extra_blocks\\(\$\\|[^0-9]\\)/nothing allocated/" \
205
- -e "s/blocks=$((extra_blocks + img_size / 512))\\(\$\\|[^0-9]\\)/everything allocated/"
206
+ sed -e "s/blocks=$min_blocks\\(\$\\|[^0-9]\\)/min allocation/" \
207
+ -e "s/blocks=$((extra_blocks + img_size / 512))\\(\$\\|[^0-9]\\)/max allocation/"
208
}
209
210
# get standard environment, filters and checks
211
@@ -XXX,XX +XXX,XX @@ size=$((1 * 1024 * 1024))
212
touch "$TEST_DIR/empty"
213
extra_blocks=$(stat -c '%b' "$TEST_DIR/empty")
214
215
+# We always write the first byte; check how many blocks this filesystem
216
+# allocates to match empty image alloation.
217
+printf "\0" > "$TEST_DIR/empty"
218
+min_blocks=$(stat -c '%b' "$TEST_DIR/empty")
219
+
220
echo
221
echo "== creating image with default preallocation =="
222
_make_test_img $size | _filter_imgfmt
223
-stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $size
224
+stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $min_blocks $size
225
226
for mode in off full falloc; do
227
echo
228
echo "== creating image with preallocation $mode =="
229
IMGOPTS=preallocation=$mode _make_test_img $size | _filter_imgfmt
230
- stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $size
231
+ stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $min_blocks $size
232
done
233
234
# success, all done
235
diff --git a/tests/qemu-iotests/175.out b/tests/qemu-iotests/175.out
236
index XXXXXXX..XXXXXXX 100644
237
--- a/tests/qemu-iotests/175.out
238
+++ b/tests/qemu-iotests/175.out
239
@@ -XXX,XX +XXX,XX @@ QA output created by 175
240
241
== creating image with default preallocation ==
242
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
243
-size=1048576, nothing allocated
244
+size=1048576, min allocation
245
246
== creating image with preallocation off ==
247
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 preallocation=off
248
-size=1048576, nothing allocated
249
+size=1048576, min allocation
250
251
== creating image with preallocation full ==
252
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 preallocation=full
253
-size=1048576, everything allocated
254
+size=1048576, max allocation
255
256
== creating image with preallocation falloc ==
257
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 preallocation=falloc
258
-size=1048576, everything allocated
259
+size=1048576, max allocation
260
*** done
261
diff --git a/tests/qemu-iotests/178.out.qcow2 b/tests/qemu-iotests/178.out.qcow2
262
index XXXXXXX..XXXXXXX 100644
263
--- a/tests/qemu-iotests/178.out.qcow2
264
+++ b/tests/qemu-iotests/178.out.qcow2
265
@@ -XXX,XX +XXX,XX @@ converted image file size in bytes: 196608
266
== raw input image with data (human) ==
267
268
Formatting 'TEST_DIR/t.qcow2', fmt=IMGFMT size=1073741824
269
-required size: 393216
270
+required size: 458752
271
fully allocated size: 1074135040
272
wrote 512/512 bytes at offset 512
273
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
274
@@ -XXX,XX +XXX,XX @@ converted image file size in bytes: 196608
275
276
Formatting 'TEST_DIR/t.qcow2', fmt=IMGFMT size=1073741824
277
{
278
- "required": 393216,
279
+ "required": 458752,
280
"fully-allocated": 1074135040
281
}
282
wrote 512/512 bytes at offset 512
283
diff --git a/tests/qemu-iotests/221.out b/tests/qemu-iotests/221.out
284
index XXXXXXX..XXXXXXX 100644
285
--- a/tests/qemu-iotests/221.out
286
+++ b/tests/qemu-iotests/221.out
287
@@ -XXX,XX +XXX,XX @@ QA output created by 221
288
=== Check mapping of unaligned raw image ===
289
290
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=65537
291
-[{ "start": 0, "length": 66048, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
292
-[{ "start": 0, "length": 66048, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
293
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
294
+{ "start": 4096, "length": 61952, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
295
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
296
+{ "start": 4096, "length": 61952, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
297
wrote 1/1 bytes at offset 65536
298
1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
299
-[{ "start": 0, "length": 65536, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
300
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
301
+{ "start": 4096, "length": 61440, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
302
{ "start": 65536, "length": 1, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
303
{ "start": 65537, "length": 511, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
304
-[{ "start": 0, "length": 65536, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
305
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
306
+{ "start": 4096, "length": 61440, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
307
{ "start": 65536, "length": 1, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
308
{ "start": 65537, "length": 511, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
309
*** done
310
diff --git a/tests/qemu-iotests/253.out b/tests/qemu-iotests/253.out
311
index XXXXXXX..XXXXXXX 100644
312
--- a/tests/qemu-iotests/253.out
313
+++ b/tests/qemu-iotests/253.out
314
@@ -XXX,XX +XXX,XX @@ QA output created by 253
315
=== Check mapping of unaligned raw image ===
316
317
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048575
318
-[{ "start": 0, "length": 1048576, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
319
-[{ "start": 0, "length": 1048576, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
320
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
321
+{ "start": 4096, "length": 1044480, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
322
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
323
+{ "start": 4096, "length": 1044480, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
324
wrote 65535/65535 bytes at offset 983040
325
63.999 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
326
-[{ "start": 0, "length": 983040, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
327
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
328
+{ "start": 4096, "length": 978944, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
329
{ "start": 983040, "length": 65536, "depth": 0, "zero": false, "data": true, "offset": OFFSET}]
330
-[{ "start": 0, "length": 983040, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
331
+[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
332
+{ "start": 4096, "length": 978944, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
333
{ "start": 983040, "length": 65536, "depth": 0, "zero": false, "data": true, "offset": OFFSET}]
334
*** done
182
--
335
--
183
2.21.0
336
2.21.0
184
337
185
338
diff view generated by jsdifflib
1
Signed-off-by: Max Reitz <mreitz@redhat.com>
1
From: Nir Soffer <nirsof@gmail.com>
2
Message-id: 20190724171239.8764-11-mreitz@redhat.com
2
3
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
3
Using block_resize we can test allocate_first_block() with file
4
descriptor opened with O_DIRECT, ensuring that it works for any size
5
larger than 4096 bytes.
6
7
Testing smaller sizes is tricky as the result depends on the filesystem
8
used for testing. For example on NFS any size will work since O_DIRECT
9
does not require any alignment.
10
11
Signed-off-by: Nir Soffer <nsoffer@redhat.com>
12
Reviewed-by: Max Reitz <mreitz@redhat.com>
13
Message-id: 20190827010528.8818-3-nsoffer@redhat.com
4
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
5
---
15
---
6
tests/qemu-iotests/122 | 17 +++++++++++++++++
16
tests/qemu-iotests/175 | 28 ++++++++++++++++++++++++++++
7
tests/qemu-iotests/122.out | 8 ++++++++
17
tests/qemu-iotests/175.out | 8 ++++++++
8
2 files changed, 25 insertions(+)
18
2 files changed, 36 insertions(+)
9
19
10
diff --git a/tests/qemu-iotests/122 b/tests/qemu-iotests/122
20
diff --git a/tests/qemu-iotests/175 b/tests/qemu-iotests/175
11
index XXXXXXX..XXXXXXX 100755
21
index XXXXXXX..XXXXXXX 100755
12
--- a/tests/qemu-iotests/122
22
--- a/tests/qemu-iotests/175
13
+++ b/tests/qemu-iotests/122
23
+++ b/tests/qemu-iotests/175
14
@@ -XXX,XX +XXX,XX @@ for min_sparse in 4k 8k; do
24
@@ -XXX,XX +XXX,XX @@ _filter_blocks()
15
$QEMU_IMG map --output=json "$TEST_IMG".orig | _filter_qemu_img_map
25
-e "s/blocks=$((extra_blocks + img_size / 512))\\(\$\\|[^0-9]\\)/max allocation/"
26
}
27
28
+# Resize image using block_resize.
29
+# Parameter 1: image path
30
+# Parameter 2: new size
31
+_block_resize()
32
+{
33
+ local path=$1
34
+ local size=$2
35
+
36
+ $QEMU -qmp stdio -nographic -nodefaults \
37
+ -blockdev file,node-name=file,filename=$path,cache.direct=on \
38
+ <<EOF
39
+{'execute': 'qmp_capabilities'}
40
+{'execute': 'block_resize', 'arguments': {'node-name': 'file', 'size': $size}}
41
+{'execute': 'quit'}
42
+EOF
43
+}
44
+
45
# get standard environment, filters and checks
46
. ./common.rc
47
. ./common.filter
48
@@ -XXX,XX +XXX,XX @@ _supported_fmt raw
49
_supported_proto file
50
_supported_os Linux
51
52
+_default_cache_mode none
53
+_supported_cache_modes none directsync
54
+
55
size=$((1 * 1024 * 1024))
56
57
touch "$TEST_DIR/empty"
58
@@ -XXX,XX +XXX,XX @@ for mode in off full falloc; do
59
stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $min_blocks $size
16
done
60
done
17
61
18
+
62
+for new_size in 4096 1048576; do
19
+echo
63
+ echo
20
+echo '=== -n to a non-zero image ==='
64
+ echo "== resize empty image with block_resize =="
21
+echo
65
+ _make_test_img 0 | _filter_imgfmt
22
+
66
+ _block_resize $TEST_IMG $new_size >/dev/null
23
+# Keep source zero
67
+ stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $min_blocks $new_size
24
+_make_test_img 64M
68
+done
25
+
26
+# Output is not zero, but has bdrv_has_zero_init() == 1
27
+TEST_IMG="$TEST_IMG".orig _make_test_img 64M
28
+$QEMU_IO -c "write -P 42 0 64k" "$TEST_IMG".orig | _filter_qemu_io
29
+
30
+# Convert with -n, which should not assume that the target is zeroed
31
+$QEMU_IMG convert -O $IMGFMT -n "$TEST_IMG" "$TEST_IMG".orig
32
+
33
+$QEMU_IMG compare "$TEST_IMG" "$TEST_IMG".orig
34
+
69
+
35
# success, all done
70
# success, all done
36
echo '*** done'
71
echo "*** done"
37
rm -f $seq.full
72
rm -f $seq.full
38
diff --git a/tests/qemu-iotests/122.out b/tests/qemu-iotests/122.out
73
diff --git a/tests/qemu-iotests/175.out b/tests/qemu-iotests/175.out
39
index XXXXXXX..XXXXXXX 100644
74
index XXXXXXX..XXXXXXX 100644
40
--- a/tests/qemu-iotests/122.out
75
--- a/tests/qemu-iotests/175.out
41
+++ b/tests/qemu-iotests/122.out
76
+++ b/tests/qemu-iotests/175.out
42
@@ -XXX,XX +XXX,XX @@ convert -c -S 8k
77
@@ -XXX,XX +XXX,XX @@ size=1048576, max allocation
43
{ "start": 9216, "length": 8192, "depth": 0, "zero": true, "data": false},
78
== creating image with preallocation falloc ==
44
{ "start": 17408, "length": 1024, "depth": 0, "zero": false, "data": true},
79
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 preallocation=falloc
45
{ "start": 18432, "length": 67090432, "depth": 0, "zero": true, "data": false}]
80
size=1048576, max allocation
46
+
81
+
47
+=== -n to a non-zero image ===
82
+== resize empty image with block_resize ==
83
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=0
84
+size=4096, min allocation
48
+
85
+
49
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
86
+== resize empty image with block_resize ==
50
+Formatting 'TEST_DIR/t.IMGFMT.orig', fmt=IMGFMT size=67108864
87
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=0
51
+wrote 65536/65536 bytes at offset 0
88
+size=1048576, min allocation
52
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
89
*** done
53
+Images are identical.
54
*** done
55
--
90
--
56
2.21.0
91
2.21.0
57
92
58
93
diff view generated by jsdifflib
1
69f47505ee has changed qcow2 in such a way that the commit job run in
1
fe646693acc changed qemu-img create's output so that it no longer prints
2
test 141 (and 144[1]) returns before it emits the READY event. However,
2
single quotes around parameter values. The subformat and adapter_type
3
141 also runs with qed, where the order is still the other way around.
3
filters in _filter_img_create() have never been adapted to that change.
4
Just filter out the {"return": {}} so the test passes for qed again.
5
4
6
[1] 144 only runs with qcow2, so it is fine as it is.
5
Fixes: fe646693acc13ac48b98435d14149ab04dc597bc
7
8
Suggested-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
Fixes: 69f47505ee66afaa513305de0c1895a224e52c45
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
Message-id: 20190809185253.17535-1-mreitz@redhat.com
7
Reviewed-by: John Snow <jsnow@redhat.com>
12
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Message-id: 20190815153638.4600-2-mreitz@redhat.com
13
Reviewed-by: John Snow <jsnow@redhat.com>
9
Reviewed-by: John Snow <jsnow@redhat.com>
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
15
---
11
---
16
tests/qemu-iotests/141 | 9 +++++++--
12
tests/qemu-iotests/059.out | 16 ++++++++--------
17
tests/qemu-iotests/141.out | 5 -----
13
tests/qemu-iotests/common.filter | 4 ++--
18
tests/qemu-iotests/common.filter | 5 +++++
14
2 files changed, 10 insertions(+), 10 deletions(-)
19
3 files changed, 12 insertions(+), 7 deletions(-)
20
15
21
diff --git a/tests/qemu-iotests/141 b/tests/qemu-iotests/141
16
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
22
index XXXXXXX..XXXXXXX 100755
23
--- a/tests/qemu-iotests/141
24
+++ b/tests/qemu-iotests/141
25
@@ -XXX,XX +XXX,XX @@ test_blockjob()
26
}}}" \
27
'return'
28
29
+ # If "$2" is an event, we may or may not see it before the
30
+ # {"return": {}}. Therefore, filter the {"return": {}} out both
31
+ # here and in the next command. (Naturally, if we do not see it
32
+ # here, we will see it before the next command can be executed,
33
+ # so it will appear in the next _send_qemu_cmd's output.)
34
_send_qemu_cmd $QEMU_HANDLE \
35
"$1" \
36
"$2" \
37
- | _filter_img_create
38
+ | _filter_img_create | _filter_qmp_empty_return
39
40
# We want this to return an error because the block job is still running
41
_send_qemu_cmd $QEMU_HANDLE \
42
"{'execute': 'blockdev-del',
43
'arguments': {'node-name': 'drv0'}}" \
44
- 'error' | _filter_generated_node_ids
45
+ 'error' | _filter_generated_node_ids | _filter_qmp_empty_return
46
47
_send_qemu_cmd $QEMU_HANDLE \
48
"{'execute': 'block-job-cancel',
49
diff --git a/tests/qemu-iotests/141.out b/tests/qemu-iotests/141.out
50
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
51
--- a/tests/qemu-iotests/141.out
18
--- a/tests/qemu-iotests/059.out
52
+++ b/tests/qemu-iotests/141.out
19
+++ b/tests/qemu-iotests/059.out
53
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/m.
20
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
54
Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT backing_fmt=IMGFMT
21
qemu-io: can't open device TEST_DIR/t.vmdk: L1 size too big
55
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
22
56
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
23
=== Testing monolithicFlat creation and opening ===
57
-{"return": {}}
24
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648 subformat=monolithicFlat
58
{"error": {"class": "GenericError", "desc": "Node drv0 is in use"}}
25
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648
59
{"return": {}}
26
image: TEST_DIR/t.IMGFMT
60
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}}
27
file format: IMGFMT
61
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
28
virtual size: 2 GiB (2147483648 bytes)
62
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
29
63
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job0"}}
30
=== Testing monolithicFlat with zeroed_grain ===
64
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "mirror"}}
31
qemu-img: TEST_DIR/t.IMGFMT: Flat image can't enable zeroed grain
65
-{"return": {}}
32
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648 subformat=monolithicFlat
66
{"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: mirror"}}
33
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648
67
{"return": {}}
34
68
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job0"}}
35
=== Testing big twoGbMaxExtentFlat ===
69
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
36
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824000 subformat=twoGbMaxExtentFlat
70
{"return": {}}
37
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824000
71
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
38
image: TEST_DIR/t.vmdk
72
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
39
file format: vmdk
73
-{"return": {}}
40
virtual size: 0.977 TiB (1073741824000 bytes)
74
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job0"}}
41
@@ -XXX,XX +XXX,XX @@ Format specific information:
75
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
42
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Invalid extent line: RW 12582912 VMFS "dummy.IMGFMT" 1
76
{"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: commit"}}
43
77
@@ -XXX,XX +XXX,XX @@ wrote 1048576/1048576 bytes at offset 0
44
=== Testing truncated sparse ===
78
{"return": {}}
45
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=107374182400 subformat=monolithicSparse
79
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
46
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=107374182400
80
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
47
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': File truncated, expecting at least 13172736 bytes
81
-{"return": {}}
48
82
{"error": {"class": "GenericError", "desc": "Node drv0 is in use"}}
49
=== Converting to streamOptimized from image with small cluster size===
83
{"return": {}}
50
@@ -XXX,XX +XXX,XX @@ wrote 512/512 bytes at offset 10240
84
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}}
51
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
85
@@ -XXX,XX +XXX,XX @@ wrote 1048576/1048576 bytes at offset 0
52
86
{"return": {}}
53
=== Testing monolithicFlat with internally generated JSON file name ===
87
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
54
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 subformat=monolithicFlat
88
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
55
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
89
-{"return": {}}
56
qemu-io: can't open: Cannot use relative extent paths with VMDK descriptor file 'json:{"image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug", "inject-error.0.event": "read_aio"}'
90
{"error": {"class": "GenericError", "desc": "Node drv0 is in use"}}
57
91
{"return": {}}
58
=== Testing version 3 ===
92
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}}
59
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 64931328
60
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
61
62
=== Testing 4TB monolithicFlat creation and IO ===
63
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4398046511104 subformat=monolithicFlat
64
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4398046511104
65
image: TEST_DIR/t.IMGFMT
66
file format: IMGFMT
67
virtual size: 4 TiB (4398046511104 bytes)
68
@@ -XXX,XX +XXX,XX @@ read 1024/1024 bytes at offset 966367641600
69
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
70
71
=== Testing qemu-img map on extents ===
72
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33285996544 subformat=monolithicSparse
73
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33285996544
74
wrote 1024/1024 bytes at offset 65024
75
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
76
wrote 1024/1024 bytes at offset 2147483136
77
@@ -XXX,XX +XXX,XX @@ Offset Length Mapped to File
78
0 0x20000 0x3f0000 TEST_DIR/t.vmdk
79
0x7fff0000 0x20000 0x410000 TEST_DIR/t.vmdk
80
0x140000000 0x10000 0x430000 TEST_DIR/t.vmdk
81
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33285996544 subformat=twoGbMaxExtentSparse
82
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33285996544
83
wrote 1024/1024 bytes at offset 65024
84
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
85
wrote 1024/1024 bytes at offset 2147483136
93
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
86
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
94
index XXXXXXX..XXXXXXX 100644
87
index XXXXXXX..XXXXXXX 100644
95
--- a/tests/qemu-iotests/common.filter
88
--- a/tests/qemu-iotests/common.filter
96
+++ b/tests/qemu-iotests/common.filter
89
+++ b/tests/qemu-iotests/common.filter
97
@@ -XXX,XX +XXX,XX @@ _filter_nbd()
90
@@ -XXX,XX +XXX,XX @@ _filter_img_create()
98
-e 's#\(foo\|PORT/\?\|.sock\): Failed to .*$#\1#'
91
-e "s# compat6=\\(on\\|off\\)##g" \
99
}
92
-e "s# static=\\(on\\|off\\)##g" \
100
93
-e "s# zeroed_grain=\\(on\\|off\\)##g" \
101
+_filter_qmp_empty_return()
94
- -e "s# subformat='[^']*'##g" \
102
+{
95
- -e "s# adapter_type='[^']*'##g" \
103
+ grep -v '{"return": {}}'
96
+ -e "s# subformat=[^ ]*##g" \
104
+}
97
+ -e "s# adapter_type=[^ ]*##g" \
105
+
98
-e "s# hwversion=[^ ]*##g" \
106
# make sure this script returns success
99
-e "s# lazy_refcounts=\\(on\\|off\\)##g" \
107
true
100
-e "s# block_size=[0-9]\\+##g" \
108
--
101
--
109
2.21.0
102
2.21.0
110
103
111
104
diff view generated by jsdifflib
1
When preallocating an encrypted qcow2 image, it just lets the protocol
1
This makes iotest 033 pass with e.g. subformat=monolithicFlat. It also
2
driver write data and then does not mark the clusters as zero.
2
turns a former error in 059 into success.
3
Therefore, reading this image will yield effectively random data.
4
5
As such, we have not fulfilled the promise of always writing zeroes when
6
preallocating an image in a while. It seems that nobody has really
7
cared, so change the documentation to conform to qemu's actual behavior.
8
3
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
Message-id: 20190711132935.13070-1-mreitz@redhat.com
5
Message-id: 20190815153638.4600-3-mreitz@redhat.com
11
Reviewed-by: Eric Blake <eblake@redhat.com>
6
Reviewed-by: John Snow <jsnow@redhat.com>
12
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
13
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
15
---
8
---
16
qapi/block-core.json | 9 +++++----
9
block/vmdk.c | 54 ++++++++++++++++++++++++--------------
17
docs/qemu-block-drivers.texi | 4 ++--
10
tests/qemu-iotests/059 | 7 +++--
18
qemu-img.texi | 4 ++--
11
tests/qemu-iotests/059.out | 4 ++-
19
3 files changed, 9 insertions(+), 8 deletions(-)
12
3 files changed, 42 insertions(+), 23 deletions(-)
20
13
21
diff --git a/qapi/block-core.json b/qapi/block-core.json
14
diff --git a/block/vmdk.c b/block/vmdk.c
22
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
23
--- a/qapi/block-core.json
16
--- a/block/vmdk.c
24
+++ b/qapi/block-core.json
17
+++ b/block/vmdk.c
25
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static const char *next_line(const char *s)
26
# @off: no preallocation
19
}
27
# @metadata: preallocate only for metadata
20
28
# @falloc: like @full preallocation but allocate disk space by
21
static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
29
-# posix_fallocate() rather than writing zeros.
22
- const char *desc_file_path, QDict *options,
30
-# @full: preallocate all data by writing zeros to device to ensure disk
23
- Error **errp)
31
-# space is really available. @full preallocation also sets up
24
+ QDict *options, Error **errp)
32
-# metadata correctly.
25
{
33
+# posix_fallocate() rather than writing data.
26
int ret;
34
+# @full: preallocate all data by writing it to the device to ensure
27
int matches;
35
+# disk space is really available. This data may or may not be
28
@@ -XXX,XX +XXX,XX @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
36
+# zero, depending on the image format and storage.
29
const char *p, *np;
37
+# @full preallocation also sets up metadata correctly.
30
int64_t sectors = 0;
38
#
31
int64_t flat_offset;
39
# Since: 2.2
32
+ char *desc_file_dir = NULL;
40
##
33
char *extent_path;
41
diff --git a/docs/qemu-block-drivers.texi b/docs/qemu-block-drivers.texi
34
BdrvChild *extent_file;
35
BDRVVmdkState *s = bs->opaque;
36
@@ -XXX,XX +XXX,XX @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
37
continue;
38
}
39
40
- if (!path_is_absolute(fname) && !path_has_protocol(fname) &&
41
- !desc_file_path[0])
42
- {
43
- bdrv_refresh_filename(bs->file->bs);
44
- error_setg(errp, "Cannot use relative extent paths with VMDK "
45
- "descriptor file '%s'", bs->file->bs->filename);
46
- return -EINVAL;
47
- }
48
+ if (path_is_absolute(fname)) {
49
+ extent_path = g_strdup(fname);
50
+ } else {
51
+ if (!desc_file_dir) {
52
+ desc_file_dir = bdrv_dirname(bs->file->bs, errp);
53
+ if (!desc_file_dir) {
54
+ bdrv_refresh_filename(bs->file->bs);
55
+ error_prepend(errp, "Cannot use relative paths with VMDK "
56
+ "descriptor file '%s': ",
57
+ bs->file->bs->filename);
58
+ ret = -EINVAL;
59
+ goto out;
60
+ }
61
+ }
62
63
- extent_path = path_combine(desc_file_path, fname);
64
+ extent_path = g_strconcat(desc_file_dir, fname, NULL);
65
+ }
66
67
ret = snprintf(extent_opt_prefix, 32, "extents.%d", s->num_extents);
68
assert(ret < 32);
69
@@ -XXX,XX +XXX,XX @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
70
g_free(extent_path);
71
if (local_err) {
72
error_propagate(errp, local_err);
73
- return -EINVAL;
74
+ ret = -EINVAL;
75
+ goto out;
76
}
77
78
/* save to extents array */
79
@@ -XXX,XX +XXX,XX @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
80
0, 0, 0, 0, 0, &extent, errp);
81
if (ret < 0) {
82
bdrv_unref_child(bs, extent_file);
83
- return ret;
84
+ goto out;
85
}
86
extent->flat_start_offset = flat_offset << 9;
87
} else if (!strcmp(type, "SPARSE") || !strcmp(type, "VMFSSPARSE")) {
88
@@ -XXX,XX +XXX,XX @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
89
g_free(buf);
90
if (ret) {
91
bdrv_unref_child(bs, extent_file);
92
- return ret;
93
+ goto out;
94
}
95
extent = &s->extents[s->num_extents - 1];
96
} else if (!strcmp(type, "SESPARSE")) {
97
ret = vmdk_open_se_sparse(bs, extent_file, bs->open_flags, errp);
98
if (ret) {
99
bdrv_unref_child(bs, extent_file);
100
- return ret;
101
+ goto out;
102
}
103
extent = &s->extents[s->num_extents - 1];
104
} else {
105
error_setg(errp, "Unsupported extent type '%s'", type);
106
bdrv_unref_child(bs, extent_file);
107
- return -ENOTSUP;
108
+ ret = -ENOTSUP;
109
+ goto out;
110
}
111
extent->type = g_strdup(type);
112
}
113
- return 0;
114
+
115
+ ret = 0;
116
+ goto out;
117
118
invalid:
119
np = next_line(p);
120
@@ -XXX,XX +XXX,XX @@ invalid:
121
np--;
122
}
123
error_setg(errp, "Invalid extent line: %.*s", (int)(np - p), p);
124
- return -EINVAL;
125
+ ret = -EINVAL;
126
+
127
+out:
128
+ g_free(desc_file_dir);
129
+ return ret;
130
}
131
132
static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf,
133
@@ -XXX,XX +XXX,XX @@ static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf,
134
}
135
s->create_type = g_strdup(ct);
136
s->desc_offset = 0;
137
- ret = vmdk_parse_extents(buf, bs, bs->file->bs->exact_filename, options,
138
- errp);
139
+ ret = vmdk_parse_extents(buf, bs, options, errp);
140
exit:
141
return ret;
142
}
143
diff --git a/tests/qemu-iotests/059 b/tests/qemu-iotests/059
144
index XXXXXXX..XXXXXXX 100755
145
--- a/tests/qemu-iotests/059
146
+++ b/tests/qemu-iotests/059
147
@@ -XXX,XX +XXX,XX @@ $QEMU_IMG convert -f qcow2 -O vmdk -o subformat=streamOptimized "$TEST_IMG.qcow2
148
149
echo
150
echo "=== Testing monolithicFlat with internally generated JSON file name ==="
151
+# Should work, because bdrv_dirname() works fine with blkdebug
152
IMGOPTS="subformat=monolithicFlat" _make_test_img 64M
153
-$QEMU_IO -c "open -o driver=$IMGFMT,file.driver=blkdebug,file.image.filename=$TEST_IMG,file.inject-error.0.event=read_aio" 2>&1 \
154
- | _filter_testdir | _filter_imgfmt
155
+$QEMU_IO -c "open -o driver=$IMGFMT,file.driver=blkdebug,file.image.filename=$TEST_IMG,file.inject-error.0.event=read_aio" \
156
+ -c info \
157
+ 2>&1 \
158
+ | _filter_testdir | _filter_imgfmt | _filter_img_info
159
_cleanup_test_img
160
161
echo
162
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
42
index XXXXXXX..XXXXXXX 100644
163
index XXXXXXX..XXXXXXX 100644
43
--- a/docs/qemu-block-drivers.texi
164
--- a/tests/qemu-iotests/059.out
44
+++ b/docs/qemu-block-drivers.texi
165
+++ b/tests/qemu-iotests/059.out
45
@@ -XXX,XX +XXX,XX @@ Supported options:
166
@@ -XXX,XX +XXX,XX @@ wrote 512/512 bytes at offset 10240
46
@item preallocation
167
47
Preallocation mode (allowed values: @code{off}, @code{falloc}, @code{full}).
168
=== Testing monolithicFlat with internally generated JSON file name ===
48
@code{falloc} mode preallocates space for image by calling posix_fallocate().
169
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
49
-@code{full} mode preallocates space for image by writing zeros to underlying
170
-qemu-io: can't open: Cannot use relative extent paths with VMDK descriptor file 'json:{"image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug", "inject-error.0.event": "read_aio"}'
50
-storage.
171
+format name: IMGFMT
51
+@code{full} mode preallocates space for image by writing data to underlying
172
+cluster size: 0 bytes
52
+storage. This data may or may not be zero, depending on the storage location.
173
+vm state offset: 0 bytes
53
@end table
174
54
175
=== Testing version 3 ===
55
@item qcow2
176
image: TEST_DIR/iotest-version3.IMGFMT
56
diff --git a/qemu-img.texi b/qemu-img.texi
57
index XXXXXXX..XXXXXXX 100644
58
--- a/qemu-img.texi
59
+++ b/qemu-img.texi
60
@@ -XXX,XX +XXX,XX @@ Supported options:
61
@item preallocation
62
Preallocation mode (allowed values: @code{off}, @code{falloc}, @code{full}).
63
@code{falloc} mode preallocates space for image by calling posix_fallocate().
64
-@code{full} mode preallocates space for image by writing zeros to underlying
65
-storage.
66
+@code{full} mode preallocates space for image by writing data to underlying
67
+storage. This data may or may not be zero, depending on the storage location.
68
@end table
69
70
@item qcow2
71
--
177
--
72
2.21.0
178
2.21.0
73
179
74
180
diff view generated by jsdifflib
1
The result of a sync=full mirror should always be the equal to the
1
We had a test for a case where relative extent paths did not work, but
2
input. Therefore, existing images should be treated as potentially
2
unfortunately we just fixed the underlying problem, so it works now.
3
non-zero and thus should be explicitly initialized to be zero
3
This patch adds a new test case that still fails.
4
beforehand.
5
4
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
5
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Message-id: 20190724171239.8764-12-mreitz@redhat.com
6
Reviewed-by: John Snow <jsnow@redhat.com>
7
Message-id: 20190815153638.4600-4-mreitz@redhat.com
8
Reviewed-by: John Snow <jsnow@redhat.com>
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
---
10
---
10
tests/qemu-iotests/041 | 62 +++++++++++++++++++++++++++++++++++---
11
tests/qemu-iotests/059 | 27 +++++++++++++++++++++++++++
11
tests/qemu-iotests/041.out | 4 +--
12
tests/qemu-iotests/059.out | 4 ++++
12
2 files changed, 60 insertions(+), 6 deletions(-)
13
2 files changed, 31 insertions(+)
13
14
14
diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
15
diff --git a/tests/qemu-iotests/059 b/tests/qemu-iotests/059
15
index XXXXXXX..XXXXXXX 100755
16
index XXXXXXX..XXXXXXX 100755
16
--- a/tests/qemu-iotests/041
17
--- a/tests/qemu-iotests/059
17
+++ b/tests/qemu-iotests/041
18
+++ b/tests/qemu-iotests/059
18
@@ -XXX,XX +XXX,XX @@ class TestUnbackedSource(iotests.QMPTestCase):
19
@@ -XXX,XX +XXX,XX @@ $QEMU_IMG convert -f qcow2 -O vmdk -o subformat=streamOptimized "$TEST_IMG.qcow2
19
def setUp(self):
20
20
qemu_img('create', '-f', iotests.imgfmt, test_img,
21
echo
21
str(TestUnbackedSource.image_len))
22
echo "=== Testing monolithicFlat with internally generated JSON file name ==="
22
- self.vm = iotests.VM().add_drive(test_img)
23
+ self.vm = iotests.VM()
24
self.vm.launch()
25
+ result = self.vm.qmp('blockdev-add', node_name='drive0',
26
+ driver=iotests.imgfmt,
27
+ file={
28
+ 'driver': 'file',
29
+ 'filename': test_img,
30
+ })
31
+ self.assert_qmp(result, 'return', {})
32
33
def tearDown(self):
34
self.vm.shutdown()
35
@@ -XXX,XX +XXX,XX @@ class TestUnbackedSource(iotests.QMPTestCase):
36
37
def test_absolute_paths_full(self):
38
self.assert_no_active_block_jobs()
39
- result = self.vm.qmp('drive-mirror', device='drive0',
40
+ result = self.vm.qmp('drive-mirror', job_id='drive0', device='drive0',
41
sync='full', target=target_img,
42
mode='absolute-paths')
43
self.assert_qmp(result, 'return', {})
44
@@ -XXX,XX +XXX,XX @@ class TestUnbackedSource(iotests.QMPTestCase):
45
46
def test_absolute_paths_top(self):
47
self.assert_no_active_block_jobs()
48
- result = self.vm.qmp('drive-mirror', device='drive0',
49
+ result = self.vm.qmp('drive-mirror', job_id='drive0', device='drive0',
50
sync='top', target=target_img,
51
mode='absolute-paths')
52
self.assert_qmp(result, 'return', {})
53
@@ -XXX,XX +XXX,XX @@ class TestUnbackedSource(iotests.QMPTestCase):
54
55
def test_absolute_paths_none(self):
56
self.assert_no_active_block_jobs()
57
- result = self.vm.qmp('drive-mirror', device='drive0',
58
+ result = self.vm.qmp('drive-mirror', job_id='drive0', device='drive0',
59
sync='none', target=target_img,
60
mode='absolute-paths')
61
self.assert_qmp(result, 'return', {})
62
self.complete_and_wait()
63
self.assert_no_active_block_jobs()
64
65
+ def test_existing_full(self):
66
+ qemu_img('create', '-f', iotests.imgfmt, target_img,
67
+ str(self.image_len))
68
+ qemu_io('-c', 'write -P 42 0 64k', target_img)
69
+
23
+
70
+ self.assert_no_active_block_jobs()
24
+echo '--- blkdebug ---'
71
+ result = self.vm.qmp('drive-mirror', job_id='drive0', device='drive0',
25
# Should work, because bdrv_dirname() works fine with blkdebug
72
+ sync='full', target=target_img, mode='existing')
26
IMGOPTS="subformat=monolithicFlat" _make_test_img 64M
73
+ self.assert_qmp(result, 'return', {})
27
$QEMU_IO -c "open -o driver=$IMGFMT,file.driver=blkdebug,file.image.filename=$TEST_IMG,file.inject-error.0.event=read_aio" \
74
+ self.complete_and_wait()
28
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c "open -o driver=$IMGFMT,file.driver=blkdebug,file.image.filename=$TE
75
+ self.assert_no_active_block_jobs()
29
| _filter_testdir | _filter_imgfmt | _filter_img_info
30
_cleanup_test_img
31
32
+echo '--- quorum ---'
33
+# Should not work, because bdrv_dirname() does not work with quorum
34
+IMGOPTS="subformat=monolithicFlat" _make_test_img 64M
35
+cp "$TEST_IMG" "$TEST_IMG.orig"
76
+
36
+
77
+ result = self.vm.qmp('blockdev-del', node_name='drive0')
37
+filename="json:{
78
+ self.assert_qmp(result, 'return', {})
38
+ \"driver\": \"$IMGFMT\",
39
+ \"file\": {
40
+ \"driver\": \"quorum\",
41
+ \"children\": [ {
42
+ \"driver\": \"file\",
43
+ \"filename\": \"$TEST_IMG\"
44
+ }, {
45
+ \"driver\": \"file\",
46
+ \"filename\": \"$TEST_IMG.orig\"
47
+ } ],
48
+ \"vote-threshold\": 1
49
+ } }"
79
+
50
+
80
+ self.assertTrue(iotests.compare_images(test_img, target_img),
51
+filename=$(echo "$filename" | tr '\n' ' ' | sed -e 's/\s\+/ /g')
81
+ 'target image does not match source after mirroring')
52
+$QEMU_IMG info "$filename" 2>&1 \
53
+ | sed -e "s/'json:[^']*'/\$QUORUM_FILE/g" \
54
+ | _filter_testdir | _filter_imgfmt | _filter_img_info
82
+
55
+
83
+ def test_blockdev_full(self):
84
+ qemu_img('create', '-f', iotests.imgfmt, target_img,
85
+ str(self.image_len))
86
+ qemu_io('-c', 'write -P 42 0 64k', target_img)
87
+
56
+
88
+ result = self.vm.qmp('blockdev-add', node_name='target',
57
echo
89
+ driver=iotests.imgfmt,
58
echo "=== Testing version 3 ==="
90
+ file={
59
_use_sample_img iotest-version3.vmdk.bz2
91
+ 'driver': 'file',
60
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
92
+ 'filename': target_img,
93
+ })
94
+ self.assert_qmp(result, 'return', {})
95
+
96
+ self.assert_no_active_block_jobs()
97
+ result = self.vm.qmp('blockdev-mirror', job_id='drive0', device='drive0',
98
+ sync='full', target='target')
99
+ self.assert_qmp(result, 'return', {})
100
+ self.complete_and_wait()
101
+ self.assert_no_active_block_jobs()
102
+
103
+ result = self.vm.qmp('blockdev-del', node_name='drive0')
104
+ self.assert_qmp(result, 'return', {})
105
+
106
+ result = self.vm.qmp('blockdev-del', node_name='target')
107
+ self.assert_qmp(result, 'return', {})
108
+
109
+ self.assertTrue(iotests.compare_images(test_img, target_img),
110
+ 'target image does not match source after mirroring')
111
+
112
class TestGranularity(iotests.QMPTestCase):
113
image_len = 10 * 1024 * 1024 # MB
114
115
diff --git a/tests/qemu-iotests/041.out b/tests/qemu-iotests/041.out
116
index XXXXXXX..XXXXXXX 100644
61
index XXXXXXX..XXXXXXX 100644
117
--- a/tests/qemu-iotests/041.out
62
--- a/tests/qemu-iotests/059.out
118
+++ b/tests/qemu-iotests/041.out
63
+++ b/tests/qemu-iotests/059.out
119
@@ -XXX,XX +XXX,XX @@
64
@@ -XXX,XX +XXX,XX @@ wrote 512/512 bytes at offset 10240
120
-........................................................................................
65
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
121
+..........................................................................................
66
122
----------------------------------------------------------------------
67
=== Testing monolithicFlat with internally generated JSON file name ===
123
-Ran 88 tests
68
+--- blkdebug ---
124
+Ran 90 tests
69
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
125
70
format name: IMGFMT
126
OK
71
cluster size: 0 bytes
72
vm state offset: 0 bytes
73
+--- quorum ---
74
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
75
+qemu-img: Could not open $QUORUM_FILE: Cannot use relative paths with VMDK descriptor file $QUORUM_FILE: Cannot generate a base directory for quorum nodes
76
77
=== Testing version 3 ===
78
image: TEST_DIR/iotest-version3.IMGFMT
127
--
79
--
128
2.21.0
80
2.21.0
129
81
130
82
diff view generated by jsdifflib
1
Fixes: 69f47505ee66afaa513305de0c1895a224e52c45
1
Compressed writes generally have to write full clusters, not just in
2
theory but also in practice when it comes to vmdk's streamOptimized
3
subformat. It currently is just silently broken for writes with
4
non-zero in-cluster offsets:
5
6
$ qemu-img create -f vmdk -o subformat=streamOptimized foo.vmdk 1M
7
$ qemu-io -c 'write 4k 4k' -c 'read 4k 4k' foo.vmdk
8
wrote 4096/4096 bytes at offset 4096
9
4 KiB, 1 ops; 00.01 sec (443.724 KiB/sec and 110.9309 ops/sec)
10
read failed: Invalid argument
11
12
(The technical reason is that vmdk_write_extent() just writes the
13
incomplete compressed data actually to offset 4k. When reading the
14
data, vmdk_read_extent() looks at offset 0 and finds the compressed data
15
size to be 0, because that is what it reads from there. This yields an
16
error.)
17
18
For incomplete writes with zero in-cluster offsets, the error path when
19
reading the rest of the cluster is a bit different, but the result is
20
the same:
21
22
$ qemu-img create -f vmdk -o subformat=streamOptimized foo.vmdk 1M
23
$ qemu-io -c 'write 0k 4k' -c 'read 4k 4k' foo.vmdk
24
wrote 4096/4096 bytes at offset 0
25
4 KiB, 1 ops; 00.01 sec (362.641 KiB/sec and 90.6603 ops/sec)
26
read failed: Invalid argument
27
28
(Here, vmdk_read_extent() finds the data and then sees that the
29
uncompressed data is short.)
30
31
It is better to reject invalid writes than to make the user believe they
32
might have succeeded and then fail when trying to read it back.
33
2
Signed-off-by: Max Reitz <mreitz@redhat.com>
34
Signed-off-by: Max Reitz <mreitz@redhat.com>
3
Message-id: 20190725155512.9827-3-mreitz@redhat.com
35
Reviewed-by: John Snow <jsnow@redhat.com>
4
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
36
Message-id: 20190815153638.4600-5-mreitz@redhat.com
5
Reviewed-by: John Snow <jsnow@redhat.com>
37
Reviewed-by: John Snow <jsnow@redhat.com>
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
38
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
---
39
---
8
block/vmdk.c | 3 +++
40
block/vmdk.c | 10 ++++++++++
9
1 file changed, 3 insertions(+)
41
1 file changed, 10 insertions(+)
10
42
11
diff --git a/block/vmdk.c b/block/vmdk.c
43
diff --git a/block/vmdk.c b/block/vmdk.c
12
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
13
--- a/block/vmdk.c
45
--- a/block/vmdk.c
14
+++ b/block/vmdk.c
46
+++ b/block/vmdk.c
15
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vmdk_co_block_status(BlockDriverState *bs,
47
@@ -XXX,XX +XXX,XX @@ static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
16
if (!extent->compressed) {
48
if (extent->compressed) {
17
ret |= BDRV_BLOCK_OFFSET_VALID;
49
void *compressed_data;
18
*map = cluster_offset + index_in_cluster;
50
19
+ if (extent->flat) {
51
+ /* Only whole clusters */
20
+ ret |= BDRV_BLOCK_RECURSE;
52
+ if (offset_in_cluster ||
21
+ }
53
+ n_bytes > (extent->cluster_sectors * SECTOR_SIZE) ||
22
}
54
+ (n_bytes < (extent->cluster_sectors * SECTOR_SIZE) &&
23
*file = extent->file->bs;
55
+ offset + n_bytes != extent->end_sector * SECTOR_SIZE))
24
break;
56
+ {
57
+ ret = -EINVAL;
58
+ goto out;
59
+ }
60
+
61
if (!extent->has_marker) {
62
ret = -EINVAL;
63
goto out;
25
--
64
--
26
2.21.0
65
2.21.0
27
66
28
67
diff view generated by jsdifflib
1
vhdx and parallels call bdrv_has_zero_init() when they do not really
1
streamOptimized does not support writes that do not span exactly one
2
care about an image's post-create state but only about what happens when
2
cluster. Furthermore, it cannot rewrite already allocated clusters.
3
you grow an image. That is a bit ugly, and also overly safe when
3
As such, many iotests do not work with it. Disable them.
4
growing preallocated images without preallocating the new areas.
5
6
Let them use bdrv_has_zero_init_truncate() instead.
7
4
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
5
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
Message-id: 20190724171239.8764-6-mreitz@redhat.com
6
Message-id: 20190815153638.4600-6-mreitz@redhat.com
10
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
7
Reviewed-by: John Snow <jsnow@redhat.com>
11
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
12
[mreitz: Added commit message]
13
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
---
9
---
15
block/parallels.c | 2 +-
10
tests/qemu-iotests/002 | 1 +
16
block/vhdx.c | 2 +-
11
tests/qemu-iotests/003 | 1 +
17
2 files changed, 2 insertions(+), 2 deletions(-)
12
tests/qemu-iotests/005 | 3 ++-
13
tests/qemu-iotests/009 | 1 +
14
tests/qemu-iotests/010 | 1 +
15
tests/qemu-iotests/011 | 1 +
16
tests/qemu-iotests/017 | 3 ++-
17
tests/qemu-iotests/018 | 3 ++-
18
tests/qemu-iotests/019 | 3 ++-
19
tests/qemu-iotests/020 | 3 ++-
20
tests/qemu-iotests/027 | 1 +
21
tests/qemu-iotests/032 | 1 +
22
tests/qemu-iotests/033 | 1 +
23
tests/qemu-iotests/034 | 3 ++-
24
tests/qemu-iotests/037 | 3 ++-
25
tests/qemu-iotests/063 | 3 ++-
26
tests/qemu-iotests/072 | 1 +
27
tests/qemu-iotests/105 | 3 ++-
28
tests/qemu-iotests/197 | 1 +
29
tests/qemu-iotests/215 | 1 +
30
tests/qemu-iotests/251 | 1 +
31
21 files changed, 30 insertions(+), 9 deletions(-)
18
32
19
diff --git a/block/parallels.c b/block/parallels.c
33
diff --git a/tests/qemu-iotests/002 b/tests/qemu-iotests/002
20
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100755
21
--- a/block/parallels.c
35
--- a/tests/qemu-iotests/002
22
+++ b/block/parallels.c
36
+++ b/tests/qemu-iotests/002
23
@@ -XXX,XX +XXX,XX @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
37
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
24
goto fail_options;
38
25
}
39
_supported_fmt generic
26
40
_supported_proto generic
27
- if (!bdrv_has_zero_init(bs->file->bs)) {
41
+_unsupported_imgopts "subformat=streamOptimized"
28
+ if (!bdrv_has_zero_init_truncate(bs->file->bs)) {
42
29
s->prealloc_mode = PRL_PREALLOC_MODE_FALLOCATE;
43
30
}
44
size=128M
31
45
diff --git a/tests/qemu-iotests/003 b/tests/qemu-iotests/003
32
diff --git a/block/vhdx.c b/block/vhdx.c
46
index XXXXXXX..XXXXXXX 100755
33
index XXXXXXX..XXXXXXX 100644
47
--- a/tests/qemu-iotests/003
34
--- a/block/vhdx.c
48
+++ b/tests/qemu-iotests/003
35
+++ b/block/vhdx.c
49
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
36
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int vhdx_co_writev(BlockDriverState *bs, int64_t sector_num,
50
37
/* Queue another write of zero buffers if the underlying file
51
_supported_fmt generic
38
* does not zero-fill on file extension */
52
_supported_proto generic
39
53
+_unsupported_imgopts "subformat=streamOptimized"
40
- if (bdrv_has_zero_init(bs->file->bs) == 0) {
54
41
+ if (bdrv_has_zero_init_truncate(bs->file->bs) == 0) {
55
size=128M
42
use_zero_buffers = true;
56
offset=67M
43
57
diff --git a/tests/qemu-iotests/005 b/tests/qemu-iotests/005
44
/* zero fill the front, if any */
58
index XXXXXXX..XXXXXXX 100755
59
--- a/tests/qemu-iotests/005
60
+++ b/tests/qemu-iotests/005
61
@@ -XXX,XX +XXX,XX @@ _supported_fmt generic
62
_supported_proto generic
63
_supported_os Linux
64
_unsupported_imgopts "subformat=twoGbMaxExtentFlat" \
65
- "subformat=twoGbMaxExtentSparse"
66
+ "subformat=twoGbMaxExtentSparse" \
67
+ "subformat=streamOptimized"
68
69
# vpc is limited to 127GB, so we can't test it here
70
if [ "$IMGFMT" = "vpc" ]; then
71
diff --git a/tests/qemu-iotests/009 b/tests/qemu-iotests/009
72
index XXXXXXX..XXXXXXX 100755
73
--- a/tests/qemu-iotests/009
74
+++ b/tests/qemu-iotests/009
75
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
76
77
_supported_fmt generic
78
_supported_proto generic
79
+_unsupported_imgopts "subformat=streamOptimized"
80
81
82
size=6G
83
diff --git a/tests/qemu-iotests/010 b/tests/qemu-iotests/010
84
index XXXXXXX..XXXXXXX 100755
85
--- a/tests/qemu-iotests/010
86
+++ b/tests/qemu-iotests/010
87
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
88
89
_supported_fmt generic
90
_supported_proto generic
91
+_unsupported_imgopts "subformat=streamOptimized"
92
93
94
size=6G
95
diff --git a/tests/qemu-iotests/011 b/tests/qemu-iotests/011
96
index XXXXXXX..XXXXXXX 100755
97
--- a/tests/qemu-iotests/011
98
+++ b/tests/qemu-iotests/011
99
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
100
101
_supported_fmt generic
102
_supported_proto generic
103
+_unsupported_imgopts "subformat=streamOptimized"
104
105
106
size=6G
107
diff --git a/tests/qemu-iotests/017 b/tests/qemu-iotests/017
108
index XXXXXXX..XXXXXXX 100755
109
--- a/tests/qemu-iotests/017
110
+++ b/tests/qemu-iotests/017
111
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
112
_supported_fmt qcow qcow2 vmdk qed
113
_supported_proto generic
114
_unsupported_proto vxhs
115
-_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat"
116
+_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat" \
117
+ "subformat=streamOptimized"
118
119
TEST_OFFSETS="0 4294967296"
120
121
diff --git a/tests/qemu-iotests/018 b/tests/qemu-iotests/018
122
index XXXXXXX..XXXXXXX 100755
123
--- a/tests/qemu-iotests/018
124
+++ b/tests/qemu-iotests/018
125
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
126
_supported_fmt qcow qcow2 vmdk qed
127
_supported_proto file
128
_supported_os Linux
129
-_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat"
130
+_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat" \
131
+ "streamOptimized"
132
133
TEST_OFFSETS="0 4294967296"
134
135
diff --git a/tests/qemu-iotests/019 b/tests/qemu-iotests/019
136
index XXXXXXX..XXXXXXX 100755
137
--- a/tests/qemu-iotests/019
138
+++ b/tests/qemu-iotests/019
139
@@ -XXX,XX +XXX,XX @@ _supported_proto file
140
_supported_os Linux
141
_unsupported_imgopts "subformat=monolithicFlat" \
142
"subformat=twoGbMaxExtentFlat" \
143
- "subformat=twoGbMaxExtentSparse"
144
+ "subformat=twoGbMaxExtentSparse" \
145
+ "subformat=streamOptimized"
146
147
TEST_OFFSETS="0 4294967296"
148
CLUSTER_SIZE=65536
149
diff --git a/tests/qemu-iotests/020 b/tests/qemu-iotests/020
150
index XXXXXXX..XXXXXXX 100755
151
--- a/tests/qemu-iotests/020
152
+++ b/tests/qemu-iotests/020
153
@@ -XXX,XX +XXX,XX @@ _supported_fmt qcow qcow2 vmdk qed
154
_supported_proto file
155
_unsupported_imgopts "subformat=monolithicFlat" \
156
"subformat=twoGbMaxExtentFlat" \
157
- "subformat=twoGbMaxExtentSparse"
158
+ "subformat=twoGbMaxExtentSparse" \
159
+ "subformat=streamOptimized"
160
161
TEST_OFFSETS="0 4294967296"
162
163
diff --git a/tests/qemu-iotests/027 b/tests/qemu-iotests/027
164
index XXXXXXX..XXXXXXX 100755
165
--- a/tests/qemu-iotests/027
166
+++ b/tests/qemu-iotests/027
167
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
168
169
_supported_fmt vmdk qcow qcow2 qed
170
_supported_proto generic
171
+_unsupported_imgopts "subformat=streamOptimized"
172
173
174
size=128M
175
diff --git a/tests/qemu-iotests/032 b/tests/qemu-iotests/032
176
index XXXXXXX..XXXXXXX 100755
177
--- a/tests/qemu-iotests/032
178
+++ b/tests/qemu-iotests/032
179
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
180
# This works for any image format (though unlikely to segfault for raw)
181
_supported_fmt generic
182
_supported_proto generic
183
+_unsupported_imgopts "subformat=streamOptimized"
184
185
echo
186
echo === Prepare image ===
187
diff --git a/tests/qemu-iotests/033 b/tests/qemu-iotests/033
188
index XXXXXXX..XXXXXXX 100755
189
--- a/tests/qemu-iotests/033
190
+++ b/tests/qemu-iotests/033
191
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
192
193
_supported_fmt generic
194
_supported_proto generic
195
+_unsupported_imgopts "subformat=streamOptimized"
196
197
198
size=128M
199
diff --git a/tests/qemu-iotests/034 b/tests/qemu-iotests/034
200
index XXXXXXX..XXXXXXX 100755
201
--- a/tests/qemu-iotests/034
202
+++ b/tests/qemu-iotests/034
203
@@ -XXX,XX +XXX,XX @@ _supported_proto file
204
_supported_os Linux
205
_unsupported_imgopts "subformat=monolithicFlat" \
206
"subformat=twoGbMaxExtentFlat" \
207
- "subformat=twoGbMaxExtentSparse"
208
+ "subformat=twoGbMaxExtentSparse" \
209
+ "subformat=streamOptimized"
210
211
CLUSTER_SIZE=4k
212
size=128M
213
diff --git a/tests/qemu-iotests/037 b/tests/qemu-iotests/037
214
index XXXXXXX..XXXXXXX 100755
215
--- a/tests/qemu-iotests/037
216
+++ b/tests/qemu-iotests/037
217
@@ -XXX,XX +XXX,XX @@ _supported_fmt qcow qcow2 vmdk qed
218
_supported_proto file
219
_unsupported_imgopts "subformat=monolithicFlat" \
220
"subformat=twoGbMaxExtentFlat" \
221
- "subformat=twoGbMaxExtentSparse"
222
+ "subformat=twoGbMaxExtentSparse" \
223
+ "subformat=streamOptimized"
224
225
CLUSTER_SIZE=4k
226
size=128M
227
diff --git a/tests/qemu-iotests/063 b/tests/qemu-iotests/063
228
index XXXXXXX..XXXXXXX 100755
229
--- a/tests/qemu-iotests/063
230
+++ b/tests/qemu-iotests/063
231
@@ -XXX,XX +XXX,XX @@ _supported_fmt qcow qcow2 vmdk qed raw
232
_supported_proto file
233
_unsupported_imgopts "subformat=monolithicFlat" \
234
"subformat=twoGbMaxExtentFlat" \
235
- "subformat=twoGbMaxExtentSparse"
236
+ "subformat=twoGbMaxExtentSparse" \
237
+ "subformat=streamOptimized"
238
239
_make_test_img 4M
240
241
diff --git a/tests/qemu-iotests/072 b/tests/qemu-iotests/072
242
index XXXXXXX..XXXXXXX 100755
243
--- a/tests/qemu-iotests/072
244
+++ b/tests/qemu-iotests/072
245
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
246
247
_supported_fmt vpc vmdk vhdx vdi qed qcow2 qcow
248
_supported_proto file
249
+_unsupported_imgopts "subformat=streamOptimized"
250
251
IMG_SIZE=64M
252
253
diff --git a/tests/qemu-iotests/105 b/tests/qemu-iotests/105
254
index XXXXXXX..XXXXXXX 100755
255
--- a/tests/qemu-iotests/105
256
+++ b/tests/qemu-iotests/105
257
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
258
_supported_fmt qcow2 vmdk vhdx qed
259
_supported_proto generic
260
_unsupported_imgopts "subformat=twoGbMaxExtentFlat" \
261
- "subformat=twoGbMaxExtentSparse"
262
+ "subformat=twoGbMaxExtentSparse" \
263
+ "subformat=streamOptimized"
264
265
echo
266
echo "creating large image"
267
diff --git a/tests/qemu-iotests/197 b/tests/qemu-iotests/197
268
index XXXXXXX..XXXXXXX 100755
269
--- a/tests/qemu-iotests/197
270
+++ b/tests/qemu-iotests/197
271
@@ -XXX,XX +XXX,XX @@ _supported_fmt generic
272
_supported_proto generic
273
# LUKS support may be possible, but it complicates things.
274
_unsupported_fmt luks
275
+_unsupported_imgopts "subformat=streamOptimized"
276
277
echo
278
echo '=== Copy-on-read ==='
279
diff --git a/tests/qemu-iotests/215 b/tests/qemu-iotests/215
280
index XXXXXXX..XXXXXXX 100755
281
--- a/tests/qemu-iotests/215
282
+++ b/tests/qemu-iotests/215
283
@@ -XXX,XX +XXX,XX @@ _supported_fmt generic
284
_supported_proto generic
285
# LUKS support may be possible, but it complicates things.
286
_unsupported_fmt luks
287
+_unsupported_imgopts "subformat=streamOptimized"
288
289
echo
290
echo '=== Copy-on-read ==='
291
diff --git a/tests/qemu-iotests/251 b/tests/qemu-iotests/251
292
index XXXXXXX..XXXXXXX 100755
293
--- a/tests/qemu-iotests/251
294
+++ b/tests/qemu-iotests/251
295
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
296
_supported_fmt generic
297
_supported_proto file
298
_supported_os Linux
299
+_unsupported_imgopts "subformat=streamOptimized"
300
301
if [ "$IMGOPTSSYNTAX" = "true" ]; then
302
# We use json:{} filenames here, so we cannot work with additional options.
45
--
303
--
46
2.21.0
304
2.21.0
47
305
48
306
diff view generated by jsdifflib
1
Suggested-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
The error message for the test case where we have a quorum node for
2
Fixes: 69f47505ee66afaa513305de0c1895a224e52c45
2
which no directory name can be generated is different: For
3
twoGbMaxExtentSparse, it complains that it cannot open the extent file.
4
For other (sub)formats, it just notes that it cannot determine the
5
backing file path. Both are fine, but just disable twoGbMaxExtentSparse
6
for simplicity's sake.
7
3
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
Message-id: 20190725155512.9827-2-mreitz@redhat.com
9
Reviewed-by: John Snow <jsnow@redhat.com>
5
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Message-id: 20190815153638.4600-7-mreitz@redhat.com
6
Reviewed-by: John Snow <jsnow@redhat.com>
11
Reviewed-by: John Snow <jsnow@redhat.com>
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
---
13
---
9
block/vdi.c | 3 ++-
14
tests/qemu-iotests/110 | 3 ++-
10
1 file changed, 2 insertions(+), 1 deletion(-)
15
1 file changed, 2 insertions(+), 1 deletion(-)
11
16
12
diff --git a/block/vdi.c b/block/vdi.c
17
diff --git a/tests/qemu-iotests/110 b/tests/qemu-iotests/110
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100755
14
--- a/block/vdi.c
19
--- a/tests/qemu-iotests/110
15
+++ b/block/vdi.c
20
+++ b/tests/qemu-iotests/110
16
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vdi_co_block_status(BlockDriverState *bs,
21
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
17
*map = s->header.offset_data + (uint64_t)bmap_entry * s->block_size +
22
# Any format supporting backing files
18
index_in_block;
23
_supported_fmt qed qcow qcow2 vmdk
19
*file = bs->file->bs;
24
_supported_proto file
20
- return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
25
-_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat"
21
+ return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID |
26
+_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat" \
22
+ (s->header.image_type == VDI_TYPE_STATIC ? BDRV_BLOCK_RECURSE : 0);
27
+ "subformat=twoGbMaxExtentSparse"
23
}
28
24
29
TEST_IMG_REL=$(basename "$TEST_IMG")
25
static int coroutine_fn
30
26
--
31
--
27
2.21.0
32
2.21.0
28
33
29
34
diff view generated by jsdifflib
1
vpc is not really a passthrough driver, even when using the fixed
1
iotest 126 requires backing file support, which flat vmdks cannot offer.
2
subformat (where host and guest offsets are equal). It should handle
2
Skip this test for such subformats.
3
preallocation like all other drivers do, namely by returning
4
DATA | RECURSE instead of RAW.
5
6
There is no tangible difference but the fact that bdrv_is_allocated() no
7
longer falls through to the protocol layer.
8
3
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
Message-id: 20190725155512.9827-4-mreitz@redhat.com
5
Message-id: 20190815153638.4600-8-mreitz@redhat.com
11
Reviewed-by: John Snow <jsnow@redhat.com>
6
Reviewed-by: John Snow <jsnow@redhat.com>
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
13
---
8
---
14
block/vpc.c | 2 +-
9
tests/qemu-iotests/126 | 2 ++
15
1 file changed, 1 insertion(+), 1 deletion(-)
10
1 file changed, 2 insertions(+)
16
11
17
diff --git a/block/vpc.c b/block/vpc.c
12
diff --git a/tests/qemu-iotests/126 b/tests/qemu-iotests/126
18
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100755
19
--- a/block/vpc.c
14
--- a/tests/qemu-iotests/126
20
+++ b/block/vpc.c
15
+++ b/tests/qemu-iotests/126
21
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vpc_co_block_status(BlockDriverState *bs,
16
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
22
*pnum = bytes;
17
23
*map = offset;
18
# Needs backing file support
24
*file = bs->file->bs;
19
_supported_fmt qcow qcow2 qed vmdk
25
- return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID;
20
+_unsupported_imgopts "subformat=monolithicFlat" \
26
+ return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | BDRV_BLOCK_RECURSE;
21
+ "subformat=twoGbMaxExtentFlat"
27
}
22
# This is the default protocol (and we want to test the difference between
28
23
# colons which separate a protocol prefix from the rest and colons which are
29
qemu_co_mutex_lock(&s->lock);
24
# just part of the filename, so we cannot test protocols which require a prefix)
30
--
25
--
31
2.21.0
26
2.21.0
32
27
33
28
diff view generated by jsdifflib
1
bdrv_has_zero_init() only has meaning for newly created images or image
1
From: Stefan Hajnoczi <stefanha@redhat.com>
2
areas. If the mirror job itself did not create the image, it cannot
3
rely on bdrv_has_zero_init()'s result to carry any meaning.
4
2
5
This is the case for drive-mirror with mode=existing and always for
3
Fixes: a6b257a08e3d72219f03e461a52152672fec0612
6
blockdev-mirror.
4
("file-posix: Handle undetectable alignment")
7
5
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Note that we only have to zero-initialize the target with sync=full,
6
Message-id: 20190827101328.4062-1-stefanha@redhat.com
9
because other modes actually do not promise that the target will contain
7
Reviewed-by: Thomas Huth <thuth@redhat.com>
10
the same data as the source after the job -- sync=top only promises to
11
copy anything allocated in the top layer, and sync=none will only copy
12
new I/O. (Which is how mirror has always handled it.)
13
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
15
Message-id: 20190724171239.8764-3-mreitz@redhat.com
16
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
17
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
18
---
9
---
19
include/block/block_int.h | 2 ++
10
block/file-posix.c | 2 +-
20
block/mirror.c | 11 ++++++++---
11
1 file changed, 1 insertion(+), 1 deletion(-)
21
blockdev.c | 16 +++++++++++++---
22
tests/test-block-iothread.c | 2 +-
23
4 files changed, 24 insertions(+), 7 deletions(-)
24
12
25
diff --git a/include/block/block_int.h b/include/block/block_int.h
13
diff --git a/block/file-posix.c b/block/file-posix.c
26
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
27
--- a/include/block/block_int.h
15
--- a/block/file-posix.c
28
+++ b/include/block/block_int.h
16
+++ b/block/file-posix.c
29
@@ -XXX,XX +XXX,XX @@ BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs,
17
@@ -XXX,XX +XXX,XX @@ static void raw_probe_alignment(BlockDriverState *bs, int fd, Error **errp)
30
* @buf_size: The amount of data that can be in flight at one time.
18
for (i = 0; i < ARRAY_SIZE(alignments); i++) {
31
* @mode: Whether to collapse all images in the chain to the target.
19
align = alignments[i];
32
* @backing_mode: How to establish the target's backing chain after completion.
20
if (raw_is_io_aligned(fd, buf + align, max_align)) {
33
+ * @zero_target: Whether the target should be explicitly zero-initialized
21
- /* Fallback to request_aligment. */
34
* @on_source_error: The action to take upon error reading from the source.
22
+ /* Fallback to request_alignment. */
35
* @on_target_error: The action to take upon error writing to the target.
23
s->buf_align = (align != 1) ? align : bs->bl.request_alignment;
36
* @unmap: Whether to unmap target where source sectors only contain zeroes.
24
break;
37
@@ -XXX,XX +XXX,XX @@ void mirror_start(const char *job_id, BlockDriverState *bs,
25
}
38
int creation_flags, int64_t speed,
39
uint32_t granularity, int64_t buf_size,
40
MirrorSyncMode mode, BlockMirrorBackingMode backing_mode,
41
+ bool zero_target,
42
BlockdevOnError on_source_error,
43
BlockdevOnError on_target_error,
44
bool unmap, const char *filter_node_name,
45
diff --git a/block/mirror.c b/block/mirror.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/block/mirror.c
48
+++ b/block/mirror.c
49
@@ -XXX,XX +XXX,XX @@ typedef struct MirrorBlockJob {
50
Error *replace_blocker;
51
bool is_none_mode;
52
BlockMirrorBackingMode backing_mode;
53
+ /* Whether the target image requires explicit zero-initialization */
54
+ bool zero_target;
55
MirrorCopyMode copy_mode;
56
BlockdevOnError on_source_error, on_target_error;
57
bool synced;
58
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
59
int ret;
60
int64_t count;
61
62
- if (base == NULL && !bdrv_has_zero_init(target_bs)) {
63
+ if (s->zero_target) {
64
if (!bdrv_can_write_zeroes_with_unmap(target_bs)) {
65
bdrv_set_dirty_bitmap(s->dirty_bitmap, 0, s->bdev_length);
66
return 0;
67
@@ -XXX,XX +XXX,XX @@ static BlockJob *mirror_start_job(
68
const char *replaces, int64_t speed,
69
uint32_t granularity, int64_t buf_size,
70
BlockMirrorBackingMode backing_mode,
71
+ bool zero_target,
72
BlockdevOnError on_source_error,
73
BlockdevOnError on_target_error,
74
bool unmap,
75
@@ -XXX,XX +XXX,XX @@ static BlockJob *mirror_start_job(
76
s->on_target_error = on_target_error;
77
s->is_none_mode = is_none_mode;
78
s->backing_mode = backing_mode;
79
+ s->zero_target = zero_target;
80
s->copy_mode = copy_mode;
81
s->base = base;
82
s->granularity = granularity;
83
@@ -XXX,XX +XXX,XX @@ void mirror_start(const char *job_id, BlockDriverState *bs,
84
int creation_flags, int64_t speed,
85
uint32_t granularity, int64_t buf_size,
86
MirrorSyncMode mode, BlockMirrorBackingMode backing_mode,
87
+ bool zero_target,
88
BlockdevOnError on_source_error,
89
BlockdevOnError on_target_error,
90
bool unmap, const char *filter_node_name,
91
@@ -XXX,XX +XXX,XX @@ void mirror_start(const char *job_id, BlockDriverState *bs,
92
is_none_mode = mode == MIRROR_SYNC_MODE_NONE;
93
base = mode == MIRROR_SYNC_MODE_TOP ? backing_bs(bs) : NULL;
94
mirror_start_job(job_id, bs, creation_flags, target, replaces,
95
- speed, granularity, buf_size, backing_mode,
96
+ speed, granularity, buf_size, backing_mode, zero_target,
97
on_source_error, on_target_error, unmap, NULL, NULL,
98
&mirror_job_driver, is_none_mode, base, false,
99
filter_node_name, true, copy_mode, errp);
100
@@ -XXX,XX +XXX,XX @@ BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs,
101
102
ret = mirror_start_job(
103
job_id, bs, creation_flags, base, NULL, speed, 0, 0,
104
- MIRROR_LEAVE_BACKING_CHAIN,
105
+ MIRROR_LEAVE_BACKING_CHAIN, false,
106
on_error, on_error, true, cb, opaque,
107
&commit_active_job_driver, false, base, auto_complete,
108
filter_node_name, false, MIRROR_COPY_MODE_BACKGROUND,
109
diff --git a/blockdev.c b/blockdev.c
110
index XXXXXXX..XXXXXXX 100644
111
--- a/blockdev.c
112
+++ b/blockdev.c
113
@@ -XXX,XX +XXX,XX @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
114
bool has_replaces, const char *replaces,
115
enum MirrorSyncMode sync,
116
BlockMirrorBackingMode backing_mode,
117
+ bool zero_target,
118
bool has_speed, int64_t speed,
119
bool has_granularity, uint32_t granularity,
120
bool has_buf_size, int64_t buf_size,
121
@@ -XXX,XX +XXX,XX @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
122
*/
123
mirror_start(job_id, bs, target,
124
has_replaces ? replaces : NULL, job_flags,
125
- speed, granularity, buf_size, sync, backing_mode,
126
+ speed, granularity, buf_size, sync, backing_mode, zero_target,
127
on_source_error, on_target_error, unmap, filter_node_name,
128
copy_mode, errp);
129
}
130
@@ -XXX,XX +XXX,XX @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
131
int flags;
132
int64_t size;
133
const char *format = arg->format;
134
+ bool zero_target;
135
int ret;
136
137
bs = qmp_get_root_bs(arg->device, errp);
138
@@ -XXX,XX +XXX,XX @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
139
goto out;
140
}
141
142
+ zero_target = (arg->sync == MIRROR_SYNC_MODE_FULL &&
143
+ (arg->mode == NEW_IMAGE_MODE_EXISTING ||
144
+ !bdrv_has_zero_init(target_bs)));
145
+
146
ret = bdrv_try_set_aio_context(target_bs, aio_context, errp);
147
if (ret < 0) {
148
bdrv_unref(target_bs);
149
@@ -XXX,XX +XXX,XX @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
150
151
blockdev_mirror_common(arg->has_job_id ? arg->job_id : NULL, bs, target_bs,
152
arg->has_replaces, arg->replaces, arg->sync,
153
- backing_mode, arg->has_speed, arg->speed,
154
+ backing_mode, zero_target,
155
+ arg->has_speed, arg->speed,
156
arg->has_granularity, arg->granularity,
157
arg->has_buf_size, arg->buf_size,
158
arg->has_on_source_error, arg->on_source_error,
159
@@ -XXX,XX +XXX,XX @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id,
160
AioContext *aio_context;
161
BlockMirrorBackingMode backing_mode = MIRROR_LEAVE_BACKING_CHAIN;
162
Error *local_err = NULL;
163
+ bool zero_target;
164
int ret;
165
166
bs = qmp_get_root_bs(device, errp);
167
@@ -XXX,XX +XXX,XX @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id,
168
return;
169
}
170
171
+ zero_target = (sync == MIRROR_SYNC_MODE_FULL);
172
+
173
aio_context = bdrv_get_aio_context(bs);
174
aio_context_acquire(aio_context);
175
176
@@ -XXX,XX +XXX,XX @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id,
177
178
blockdev_mirror_common(has_job_id ? job_id : NULL, bs, target_bs,
179
has_replaces, replaces, sync, backing_mode,
180
- has_speed, speed,
181
+ zero_target, has_speed, speed,
182
has_granularity, granularity,
183
has_buf_size, buf_size,
184
has_on_source_error, on_source_error,
185
diff --git a/tests/test-block-iothread.c b/tests/test-block-iothread.c
186
index XXXXXXX..XXXXXXX 100644
187
--- a/tests/test-block-iothread.c
188
+++ b/tests/test-block-iothread.c
189
@@ -XXX,XX +XXX,XX @@ static void test_propagate_mirror(void)
190
191
/* Start a mirror job */
192
mirror_start("job0", src, target, NULL, JOB_DEFAULT, 0, 0, 0,
193
- MIRROR_SYNC_MODE_NONE, MIRROR_OPEN_BACKING_CHAIN,
194
+ MIRROR_SYNC_MODE_NONE, MIRROR_OPEN_BACKING_CHAIN, false,
195
BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
196
false, "filter_node", MIRROR_COPY_MODE_BACKGROUND,
197
&error_abort);
198
--
26
--
199
2.21.0
27
2.21.0
200
28
201
29
diff view generated by jsdifflib
Deleted patch
1
If a qcow2 file is preallocated, it can no longer guarantee that it
2
initially appears as filled with zeroes.
3
1
4
So implement .bdrv_has_zero_init() by checking whether the file is
5
preallocated; if so, forward the call to the underlying storage node,
6
except for when it is encrypted: Encrypted preallocated images always
7
return effectively random data, so .bdrv_has_zero_init() must always
8
return 0 for them.
9
10
.bdrv_has_zero_init_truncate() can remain bdrv_has_zero_init_1(),
11
because it presupposes PREALLOC_MODE_OFF.
12
13
Reported-by: Stefano Garzarella <sgarzare@redhat.com>
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
15
Message-id: 20190724171239.8764-7-mreitz@redhat.com
16
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
17
Signed-off-by: Max Reitz <mreitz@redhat.com>
18
---
19
block/qcow2.c | 29 ++++++++++++++++++++++++++++-
20
1 file changed, 28 insertions(+), 1 deletion(-)
21
22
diff --git a/block/qcow2.c b/block/qcow2.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/block/qcow2.c
25
+++ b/block/qcow2.c
26
@@ -XXX,XX +XXX,XX @@ static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs,
27
return spec_info;
28
}
29
30
+static int qcow2_has_zero_init(BlockDriverState *bs)
31
+{
32
+ BDRVQcow2State *s = bs->opaque;
33
+ bool preallocated;
34
+
35
+ if (qemu_in_coroutine()) {
36
+ qemu_co_mutex_lock(&s->lock);
37
+ }
38
+ /*
39
+ * Check preallocation status: Preallocated images have all L2
40
+ * tables allocated, nonpreallocated images have none. It is
41
+ * therefore enough to check the first one.
42
+ */
43
+ preallocated = s->l1_size > 0 && s->l1_table[0] != 0;
44
+ if (qemu_in_coroutine()) {
45
+ qemu_co_mutex_unlock(&s->lock);
46
+ }
47
+
48
+ if (!preallocated) {
49
+ return 1;
50
+ } else if (bs->encrypted) {
51
+ return 0;
52
+ } else {
53
+ return bdrv_has_zero_init(s->data_file->bs);
54
+ }
55
+}
56
+
57
static int qcow2_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov,
58
int64_t pos)
59
{
60
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_qcow2 = {
61
.bdrv_child_perm = bdrv_format_default_perms,
62
.bdrv_co_create_opts = qcow2_co_create_opts,
63
.bdrv_co_create = qcow2_co_create,
64
- .bdrv_has_zero_init = bdrv_has_zero_init_1,
65
+ .bdrv_has_zero_init = qcow2_has_zero_init,
66
.bdrv_has_zero_init_truncate = bdrv_has_zero_init_1,
67
.bdrv_co_block_status = qcow2_co_block_status,
68
69
--
70
2.21.0
71
72
diff view generated by jsdifflib
1
Fixed VHDX images cannot guarantee to be zero-initialized. If the image
1
From: Thomas Huth <thuth@redhat.com>
2
has the "fixed" subformat, forward the call to the underlying storage
3
node.
4
2
5
Reported-by: Stefano Garzarella <sgarzare@redhat.com>
3
It is possible to enable only a subset of the block drivers with the
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
"--block-drv-rw-whitelist" option of the "configure" script. All other
7
Message-id: 20190724171239.8764-9-mreitz@redhat.com
5
drivers are marked as unusable (or only included as read-only with the
8
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
6
"--block-drv-ro-whitelist" option). If an iotest is now using such a
7
disabled block driver, it is failing - which is bad, since at least the
8
tests in the "auto" group should be able to deal with this situation.
9
Thus let's introduce a "_require_drivers" function that can be used by
10
the shell tests to check for the availability of certain drivers first,
11
and marks the test as "not run" if one of the drivers is missing.
12
13
This patch mainly targets the test in the "auto" group which should
14
never fail in such a case, but also improves some of the other tests
15
along the way. Note that we also assume that the "qcow2" and "file"
16
drivers are always available - otherwise it does not make sense to
17
run "make check-block" at all (which only tests with qcow2 by default).
18
19
Signed-off-by: Thomas Huth <thuth@redhat.com>
20
Message-id: 20190823133552.11680-1-thuth@redhat.com
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
21
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
---
22
---
11
block/vhdx.c | 26 +++++++++++++++++++++++++-
23
tests/qemu-iotests/071 | 1 +
12
1 file changed, 25 insertions(+), 1 deletion(-)
24
tests/qemu-iotests/081 | 4 +---
25
tests/qemu-iotests/099 | 1 +
26
tests/qemu-iotests/120 | 1 +
27
tests/qemu-iotests/162 | 4 +---
28
tests/qemu-iotests/184 | 1 +
29
tests/qemu-iotests/186 | 1 +
30
tests/qemu-iotests/common.rc | 14 ++++++++++++++
31
8 files changed, 21 insertions(+), 6 deletions(-)
13
32
14
diff --git a/block/vhdx.c b/block/vhdx.c
33
diff --git a/tests/qemu-iotests/071 b/tests/qemu-iotests/071
34
index XXXXXXX..XXXXXXX 100755
35
--- a/tests/qemu-iotests/071
36
+++ b/tests/qemu-iotests/071
37
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
38
39
_supported_fmt qcow2
40
_supported_proto file
41
+_require_drivers blkdebug blkverify
42
43
do_run_qemu()
44
{
45
diff --git a/tests/qemu-iotests/081 b/tests/qemu-iotests/081
46
index XXXXXXX..XXXXXXX 100755
47
--- a/tests/qemu-iotests/081
48
+++ b/tests/qemu-iotests/081
49
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
50
_supported_fmt raw
51
_supported_proto file
52
_supported_os Linux
53
+_require_drivers quorum
54
55
do_run_qemu()
56
{
57
@@ -XXX,XX +XXX,XX @@ run_qemu()
58
| _filter_qemu_io | _filter_generated_node_ids
59
}
60
61
-test_quorum=$($QEMU_IMG --help|grep quorum)
62
-[ "$test_quorum" = "" ] && _supported_fmt quorum
63
-
64
quorum="driver=raw,file.driver=quorum,file.vote-threshold=2"
65
quorum="$quorum,file.children.0.file.filename=$TEST_DIR/1.raw"
66
quorum="$quorum,file.children.1.file.filename=$TEST_DIR/2.raw"
67
diff --git a/tests/qemu-iotests/099 b/tests/qemu-iotests/099
68
index XXXXXXX..XXXXXXX 100755
69
--- a/tests/qemu-iotests/099
70
+++ b/tests/qemu-iotests/099
71
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
72
_supported_fmt qcow qcow2 qed vdi vhdx vmdk vpc
73
_supported_proto file
74
_supported_os Linux
75
+_require_drivers blkdebug blkverify
76
_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat" \
77
"subformat=twoGbMaxExtentSparse"
78
79
diff --git a/tests/qemu-iotests/120 b/tests/qemu-iotests/120
80
index XXXXXXX..XXXXXXX 100755
81
--- a/tests/qemu-iotests/120
82
+++ b/tests/qemu-iotests/120
83
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
84
_supported_fmt generic
85
_supported_proto file
86
_unsupported_fmt luks
87
+_require_drivers raw
88
89
_make_test_img 64M
90
91
diff --git a/tests/qemu-iotests/162 b/tests/qemu-iotests/162
92
index XXXXXXX..XXXXXXX 100755
93
--- a/tests/qemu-iotests/162
94
+++ b/tests/qemu-iotests/162
95
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
96
. ./common.filter
97
98
_supported_fmt generic
99
-
100
-test_ssh=$($QEMU_IMG --help | grep '^Supported formats:.* ssh\( \|$\)')
101
-[ "$test_ssh" = "" ] && _notrun "ssh support required"
102
+_require_drivers ssh
103
104
echo
105
echo '=== NBD ==='
106
diff --git a/tests/qemu-iotests/184 b/tests/qemu-iotests/184
107
index XXXXXXX..XXXXXXX 100755
108
--- a/tests/qemu-iotests/184
109
+++ b/tests/qemu-iotests/184
110
@@ -XXX,XX +XXX,XX @@ trap "exit \$status" 0 1 2 3 15
111
. ./common.filter
112
113
_supported_os Linux
114
+_require_drivers throttle
115
116
do_run_qemu()
117
{
118
diff --git a/tests/qemu-iotests/186 b/tests/qemu-iotests/186
119
index XXXXXXX..XXXXXXX 100755
120
--- a/tests/qemu-iotests/186
121
+++ b/tests/qemu-iotests/186
122
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
123
124
_supported_fmt qcow2
125
_supported_proto file
126
+_require_drivers null-co
127
128
if [ "$QEMU_DEFAULT_MACHINE" != "pc" ]; then
129
_notrun "Requires a PC machine"
130
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
15
index XXXXXXX..XXXXXXX 100644
131
index XXXXXXX..XXXXXXX 100644
16
--- a/block/vhdx.c
132
--- a/tests/qemu-iotests/common.rc
17
+++ b/block/vhdx.c
133
+++ b/tests/qemu-iotests/common.rc
18
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vhdx_co_check(BlockDriverState *bs,
134
@@ -XXX,XX +XXX,XX @@ _require_command()
19
return 0;
135
[ -x "$c" ] || _notrun "$1 utility required, skipped this test"
20
}
136
}
21
137
22
+static int vhdx_has_zero_init(BlockDriverState *bs)
138
+# Check that a set of drivers has been whitelisted in the QEMU binary
139
+#
140
+_require_drivers()
23
+{
141
+{
24
+ BDRVVHDXState *s = bs->opaque;
142
+ available=$($QEMU -drive format=help | \
25
+ int state;
143
+ sed -e '/Supported formats:/!d' -e 's/Supported formats://')
26
+
144
+ for driver
27
+ /*
145
+ do
28
+ * Check the subformat: Fixed images have all BAT entries present,
146
+ if ! echo "$available" | grep -q " $driver\( \|$\)"; then
29
+ * dynamic images have none (right after creation). It is
147
+ _notrun "$driver not available"
30
+ * therefore enough to check the first BAT entry.
148
+ fi
31
+ */
149
+ done
32
+ if (!s->bat_entries) {
33
+ return 1;
34
+ }
35
+
36
+ state = s->bat[0] & VHDX_BAT_STATE_BIT_MASK;
37
+ if (state == PAYLOAD_BLOCK_FULLY_PRESENT) {
38
+ /* Fixed subformat */
39
+ return bdrv_has_zero_init(bs->file->bs);
40
+ }
41
+
42
+ /* Dynamic subformat */
43
+ return 1;
44
+}
150
+}
45
+
151
+
46
static QemuOptsList vhdx_create_opts = {
152
# make sure this script returns success
47
.name = "vhdx-create-opts",
153
true
48
.head = QTAILQ_HEAD_INITIALIZER(vhdx_create_opts.head),
49
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_vhdx = {
50
.bdrv_co_create_opts = vhdx_co_create_opts,
51
.bdrv_get_info = vhdx_get_info,
52
.bdrv_co_check = vhdx_co_check,
53
- .bdrv_has_zero_init = bdrv_has_zero_init_1,
54
+ .bdrv_has_zero_init = vhdx_has_zero_init,
55
56
.create_opts = &vhdx_create_opts,
57
};
58
--
154
--
59
2.21.0
155
2.21.0
60
156
61
157
diff view generated by jsdifflib
1
Add a test case for converting an empty image (which only returns zeroes
1
From: Thomas Huth <thuth@redhat.com>
2
when read) to a preallocated encrypted qcow2 image.
3
qcow2_has_zero_init() should return 0 then, thus forcing qemu-img
4
convert to create zero clusters.
5
2
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
3
The sanitizers (especially the address sanitizer from Clang) are
7
Acked-by: Stefano Garzarella <sgarzare@redhat.com>
4
sometimes printing out warnings or false positives - this spoils
8
Tested-by: Stefano Garzarella <sgarzare@redhat.com>
5
the output of the iotests, causing some of the tests to fail.
9
Message-id: 20190724171239.8764-10-mreitz@redhat.com
6
Thus let's skip the automatic iotests during "make check" when the
10
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
7
user configured QEMU with --enable-sanitizers.
8
9
Signed-off-by: Thomas Huth <thuth@redhat.com>
10
Message-id: 20190823084203.29734-1-thuth@redhat.com
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
---
12
---
13
tests/qemu-iotests/188 | 20 +++++++++++++++++++-
13
tests/check-block.sh | 5 +++++
14
tests/qemu-iotests/188.out | 4 ++++
14
1 file changed, 5 insertions(+)
15
2 files changed, 23 insertions(+), 1 deletion(-)
16
15
17
diff --git a/tests/qemu-iotests/188 b/tests/qemu-iotests/188
16
diff --git a/tests/check-block.sh b/tests/check-block.sh
18
index XXXXXXX..XXXXXXX 100755
17
index XXXXXXX..XXXXXXX 100755
19
--- a/tests/qemu-iotests/188
18
--- a/tests/check-block.sh
20
+++ b/tests/qemu-iotests/188
19
+++ b/tests/check-block.sh
21
@@ -XXX,XX +XXX,XX @@ SECRETALT="secret,id=sec0,data=platypus"
20
@@ -XXX,XX +XXX,XX @@ if grep -q "TARGET_GPROF=y" *-softmmu/config-target.mak 2>/dev/null ; then
22
21
exit 0
23
_make_test_img --object $SECRET -o "encrypt.format=luks,encrypt.key-secret=sec0,encrypt.iter-time=10" $size
22
fi
24
23
25
-IMGSPEC="driver=$IMGFMT,file.filename=$TEST_IMG,encrypt.key-secret=sec0"
24
+if grep -q "CFLAGS.*-fsanitize" config-host.mak 2>/dev/null ; then
26
+IMGSPEC="driver=$IMGFMT,encrypt.key-secret=sec0,file.filename=$TEST_IMG"
25
+ echo "Sanitizers are enabled ==> Not running the qemu-iotests."
27
26
+ exit 0
28
QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT
29
30
@@ -XXX,XX +XXX,XX @@ echo
31
echo "== verify open failure with wrong password =="
32
$QEMU_IO --object $SECRETALT -c "read -P 0xa 0 $size" --image-opts $IMGSPEC | _filter_qemu_io | _filter_testdir
33
34
+_cleanup_test_img
35
+
36
+echo
37
+echo "== verify that has_zero_init returns false when preallocating =="
38
+
39
+# Empty source file
40
+if [ -n "$TEST_IMG_FILE" ]; then
41
+ TEST_IMG_FILE="${TEST_IMG_FILE}.orig" _make_test_img $size
42
+else
43
+ TEST_IMG="${TEST_IMG}.orig" _make_test_img $size
44
+fi
27
+fi
45
+
28
+
46
+$QEMU_IMG convert -O "$IMGFMT" --object $SECRET \
29
if [ -z "$(find . -name 'qemu-system-*' -print)" ]; then
47
+ -o "encrypt.format=luks,encrypt.key-secret=sec0,encrypt.iter-time=10,preallocation=metadata" \
30
echo "No qemu-system binary available ==> Not running the qemu-iotests."
48
+ "${TEST_IMG}.orig" "$TEST_IMG"
31
exit 0
49
+
50
+$QEMU_IMG compare --object $SECRET --image-opts "${IMGSPEC}.orig" "$IMGSPEC"
51
+
52
53
# success, all done
54
echo "*** done"
55
diff --git a/tests/qemu-iotests/188.out b/tests/qemu-iotests/188.out
56
index XXXXXXX..XXXXXXX 100644
57
--- a/tests/qemu-iotests/188.out
58
+++ b/tests/qemu-iotests/188.out
59
@@ -XXX,XX +XXX,XX @@ read 16777216/16777216 bytes at offset 0
60
61
== verify open failure with wrong password ==
62
qemu-io: can't open: Invalid password, cannot unlock any keyslot
63
+
64
+== verify that has_zero_init returns false when preallocating ==
65
+Formatting 'TEST_DIR/t.IMGFMT.orig', fmt=IMGFMT size=16777216
66
+Images are identical.
67
*** done
68
--
32
--
69
2.21.0
33
2.21.0
70
34
71
35
diff view generated by jsdifflib
1
Static VDI images cannot guarantee to be zero-initialized. If the image
1
From: Nir Soffer <nirsof@gmail.com>
2
has been statically allocated, forward the call to the underlying
3
storage node.
4
2
5
Reported-by: Stefano Garzarella <sgarzare@redhat.com>
3
Quoting cache mode is not needed, and most tests use unquoted values.
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
Unify all test to use the same style.
7
Reviewed-by: Stefan Weil <sw@weilnetz.de>
5
8
Acked-by: Stefano Garzarella <sgarzare@redhat.com>
6
Message-id: 20190827173432.7656-1-nsoffer@redhat.com
9
Tested-by: Stefano Garzarella <sgarzare@redhat.com>
7
Signed-off-by: Nir Soffer <nsoffer@redhat.com>
10
Message-id: 20190724171239.8764-8-mreitz@redhat.com
11
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
13
---
9
---
14
block/vdi.c | 13 ++++++++++++-
10
tests/qemu-iotests/026 | 4 ++--
15
1 file changed, 12 insertions(+), 1 deletion(-)
11
tests/qemu-iotests/039 | 4 ++--
12
tests/qemu-iotests/052 | 2 +-
13
tests/qemu-iotests/091 | 4 ++--
14
4 files changed, 7 insertions(+), 7 deletions(-)
16
15
17
diff --git a/block/vdi.c b/block/vdi.c
16
diff --git a/tests/qemu-iotests/026 b/tests/qemu-iotests/026
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100755
19
--- a/block/vdi.c
18
--- a/tests/qemu-iotests/026
20
+++ b/block/vdi.c
19
+++ b/tests/qemu-iotests/026
21
@@ -XXX,XX +XXX,XX @@ static void vdi_close(BlockDriverState *bs)
20
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
22
error_free(s->migration_blocker);
21
# Currently only qcow2 supports rebasing
23
}
22
_supported_fmt qcow2
24
23
_supported_proto file
25
+static int vdi_has_zero_init(BlockDriverState *bs)
24
-_default_cache_mode "writethrough"
26
+{
25
-_supported_cache_modes "writethrough" "none"
27
+ BDRVVdiState *s = bs->opaque;
26
+_default_cache_mode writethrough
28
+
27
+_supported_cache_modes writethrough none
29
+ if (s->header.image_type == VDI_TYPE_STATIC) {
28
# The refcount table tests expect a certain minimum width for refcount entries
30
+ return bdrv_has_zero_init(bs->file->bs);
29
# (so that the refcount table actually needs to grow); that minimum is 16 bits,
31
+ } else {
30
# being the default refcount entry width.
32
+ return 1;
31
diff --git a/tests/qemu-iotests/039 b/tests/qemu-iotests/039
33
+ }
32
index XXXXXXX..XXXXXXX 100755
34
+}
33
--- a/tests/qemu-iotests/039
35
+
34
+++ b/tests/qemu-iotests/039
36
static QemuOptsList vdi_create_opts = {
35
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
37
.name = "vdi-create-opts",
36
_supported_fmt qcow2
38
.head = QTAILQ_HEAD_INITIALIZER(vdi_create_opts.head),
37
_supported_proto file
39
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_vdi = {
38
_supported_os Linux
40
.bdrv_child_perm = bdrv_format_default_perms,
39
-_default_cache_mode "writethrough"
41
.bdrv_co_create = vdi_co_create,
40
-_supported_cache_modes "writethrough"
42
.bdrv_co_create_opts = vdi_co_create_opts,
41
+_default_cache_mode writethrough
43
- .bdrv_has_zero_init = bdrv_has_zero_init_1,
42
+_supported_cache_modes writethrough
44
+ .bdrv_has_zero_init = vdi_has_zero_init,
43
45
.bdrv_co_block_status = vdi_co_block_status,
44
size=128M
46
.bdrv_make_empty = vdi_make_empty,
45
46
diff --git a/tests/qemu-iotests/052 b/tests/qemu-iotests/052
47
index XXXXXXX..XXXXXXX 100755
48
--- a/tests/qemu-iotests/052
49
+++ b/tests/qemu-iotests/052
50
@@ -XXX,XX +XXX,XX @@ _supported_fmt generic
51
_supported_proto file
52
53
# Don't do O_DIRECT on tmpfs
54
-_supported_cache_modes "writeback" "writethrough" "unsafe"
55
+_supported_cache_modes writeback writethrough unsafe
56
57
size=128M
58
_make_test_img $size
59
diff --git a/tests/qemu-iotests/091 b/tests/qemu-iotests/091
60
index XXXXXXX..XXXXXXX 100755
61
--- a/tests/qemu-iotests/091
62
+++ b/tests/qemu-iotests/091
63
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
64
_supported_fmt qcow2
65
_supported_proto file
66
_supported_os Linux
67
-_default_cache_mode "none"
68
-_supported_cache_modes "writethrough" "none" "writeback"
69
+_default_cache_mode none
70
+_supported_cache_modes writethrough none writeback
71
72
size=1G
47
73
48
--
74
--
49
2.21.0
75
2.21.0
50
76
51
77
diff view generated by jsdifflib