1
The following changes since commit b2f7a038bb4c4fc5ce6b8486e8513dfd97665e2a:
1
The following changes since commit b785d25e91718a660546a6550f64b3c543af7754:
2
2
3
Merge remote-tracking branch 'remotes/rth/tags/pull-softfloat-20181104' into staging (2018-11-05 10:32:49 +0000)
3
Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into staging (2020-12-11 13:50:35 +0000)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
git://repo.or.cz/qemu/kevin.git tags/for-upstream
7
git://repo.or.cz/qemu/kevin.git tags/for-upstream
8
8
9
for you to fetch changes up to 1240ac558d348f6c7a5752b1a57c1da58e4efe3e:
9
for you to fetch changes up to 960d5fb3e8ee09bc5f1a5c84f66dce42a6cef920:
10
10
11
include: Add a comment to explain the origin of sizes' lookup table (2018-11-05 15:29:59 +0100)
11
block: Fix deadlock in bdrv_co_yield_to_drain() (2020-12-11 17:52:40 +0100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block layer patches:
14
Block layer patches:
15
15
16
- auto-read-only option to fix commit job when used with -blockdev
16
- Support for FUSE exports
17
- Fix help text related qemu-iotests failure (by improving the help text
17
- Fix deadlock in bdrv_co_yield_to_drain()
18
and updating the reference output)
18
- Use lock guard macros
19
- quorum: Add missing checks when adding/removing child nodes
19
- Some preparational patches for 64 bit block layer
20
- Don't take address of fields in packed structs
20
- file-posix: Fix request extension to INT64_MAX in raw_do_pwrite_zeroes()
21
- vvfat: Fix crash when reporting error about too many files in directory
22
21
23
----------------------------------------------------------------
22
----------------------------------------------------------------
24
Alberto Garcia (7):
23
Gan Qixin (4):
25
block: replace "discard" literal with BDRV_OPT_DISCARD macro
24
block/accounting: Use lock guard macros
26
qcow2: Get the request alignment for encrypted images from QCryptoBlock
25
block/curl: Use lock guard macros
27
quorum: Remove quorum_err()
26
block/throttle-groups: Use lock guard macros
28
quorum: Return an error if the blkverify mode has invalid settings
27
block/iscsi: Use lock guard macros
29
iotest: Test the blkverify mode of the Quorum driver
30
quorum: Forbid adding children in blkverify mode
31
iotest: Test x-blockdev-change on a Quorum
32
28
33
Cleber Rosa (1):
29
Kevin Wolf (4):
34
iotests: make 083 specific to raw
30
can-host: Fix crash when 'canbus' property is not set
31
block: Simplify qmp_block_resize() error paths
32
block: Fix locking in qmp_block_resize()
33
block: Fix deadlock in bdrv_co_yield_to_drain()
35
34
36
Daniel P. Berrangé (1):
35
Li Feng (1):
37
crypto: initialize sector size even when opening with no IO flag
36
file-posix: check the use_lock before setting the file lock
38
37
39
Kevin Wolf (12):
38
Max Reitz (21):
40
vpc: Don't leak opts in vpc_open()
39
meson: Detect libfuse
41
block: Update flags in bdrv_set_read_only()
40
fuse: Allow exporting BDSs via FUSE
42
block: Add auto-read-only option
41
fuse: Implement standard FUSE operations
43
rbd: Close image in qemu_rbd_open() error path
42
fuse: Allow growable exports
44
block: Require auto-read-only for existing fallbacks
43
fuse: (Partially) implement fallocate()
45
nbd: Support auto-read-only option
44
fuse: Implement hole detection through lseek
46
file-posix: Support auto-read-only option
45
iotests: Do not needlessly filter _make_test_img
47
curl: Support auto-read-only option
46
iotests: Do not pipe _make_test_img
48
gluster: Support auto-read-only option
47
iotests: Use convert -n in some cases
49
iscsi: Support auto-read-only option
48
iotests/046: Avoid renaming images
50
block: Make auto-read-only=on default for -drive
49
iotests: Derive image names from $TEST_IMG
51
qemu-iotests: Test auto-read-only with -drive and -blockdev
50
iotests/091: Use _cleanup_qemu instad of "wait"
51
iotests: Restrict some Python tests to file
52
iotests: Let _make_test_img guess $TEST_IMG_FILE
53
iotests/287: Clean up subshell test image
54
storage-daemon: Call bdrv_close_all() on exit
55
iotests: Give access to the qemu-storage-daemon
56
iotests: Allow testing FUSE exports
57
iotests: Enable fuse for many tests
58
iotests/308: Add test for FUSE exports
59
iotests/221: Discard image before qemu-img map
52
60
53
Leonid Bloch (2):
61
Vladimir Sementsov-Ogievskiy (4):
54
vdi: Use a literal number of bytes for DEFAULT_CLUSTER_SIZE
62
block/file-posix: fix workaround in raw_do_pwrite_zeroes()
55
include: Add a comment to explain the origin of sizes' lookup table
63
block/io: bdrv_refresh_limits(): use ERRP_GUARD
64
block/io: bdrv_check_byte_request(): drop bdrv_is_inserted()
65
block: introduce BDRV_MAX_LENGTH
56
66
57
Li Qiang (1):
67
qapi/block-export.json | 27 +-
58
block: change some function return type to bool
68
meson_options.txt | 4 +
69
configure | 13 +
70
include/block/block.h | 10 +
71
include/block/block_int.h | 8 +
72
include/block/fuse.h | 30 ++
73
block.c | 18 +-
74
block/accounting.c | 32 +-
75
block/curl.c | 28 +-
76
block/export/export.c | 4 +
77
block/export/fuse.c | 726 +++++++++++++++++++++++++++++++++++
78
block/file-posix.c | 9 +-
79
block/io.c | 110 ++++--
80
block/iscsi.c | 50 ++-
81
block/throttle-groups.c | 48 ++-
82
blockdev.c | 14 +-
83
net/can/can_host.c | 5 +
84
storage-daemon/qemu-storage-daemon.c | 3 +
85
tests/test-write-threshold.c | 4 +
86
MAINTAINERS | 6 +
87
block/export/meson.build | 2 +
88
meson.build | 26 ++
89
tests/qemu-iotests/025 | 2 +-
90
tests/qemu-iotests/026 | 2 +-
91
tests/qemu-iotests/028 | 16 +-
92
tests/qemu-iotests/028.out | 3 +
93
tests/qemu-iotests/031 | 2 +-
94
tests/qemu-iotests/034 | 2 +-
95
tests/qemu-iotests/036 | 2 +-
96
tests/qemu-iotests/037 | 2 +-
97
tests/qemu-iotests/038 | 2 +-
98
tests/qemu-iotests/039 | 2 +-
99
tests/qemu-iotests/046 | 7 +-
100
tests/qemu-iotests/046.out | 2 +-
101
tests/qemu-iotests/050 | 2 +-
102
tests/qemu-iotests/054 | 2 +-
103
tests/qemu-iotests/060 | 2 +-
104
tests/qemu-iotests/071 | 21 +-
105
tests/qemu-iotests/079 | 2 +-
106
tests/qemu-iotests/080 | 2 +-
107
tests/qemu-iotests/089 | 5 +-
108
tests/qemu-iotests/089.out | 1 +
109
tests/qemu-iotests/090 | 2 +-
110
tests/qemu-iotests/091 | 5 +-
111
tests/qemu-iotests/095 | 2 +-
112
tests/qemu-iotests/097 | 2 +-
113
tests/qemu-iotests/098 | 2 +-
114
tests/qemu-iotests/102 | 2 +-
115
tests/qemu-iotests/103 | 2 +-
116
tests/qemu-iotests/106 | 2 +-
117
tests/qemu-iotests/107 | 2 +-
118
tests/qemu-iotests/108 | 2 +-
119
tests/qemu-iotests/111 | 2 +-
120
tests/qemu-iotests/112 | 2 +-
121
tests/qemu-iotests/115 | 2 +-
122
tests/qemu-iotests/117 | 2 +-
123
tests/qemu-iotests/120 | 2 +-
124
tests/qemu-iotests/121 | 2 +-
125
tests/qemu-iotests/127 | 2 +-
126
tests/qemu-iotests/133 | 2 +-
127
tests/qemu-iotests/137 | 2 +-
128
tests/qemu-iotests/138 | 2 +-
129
tests/qemu-iotests/140 | 2 +-
130
tests/qemu-iotests/154 | 2 +-
131
tests/qemu-iotests/161 | 14 +-
132
tests/qemu-iotests/171 | 2 +-
133
tests/qemu-iotests/174 | 10 +-
134
tests/qemu-iotests/175 | 8 +-
135
tests/qemu-iotests/176 | 2 +-
136
tests/qemu-iotests/177 | 2 +-
137
tests/qemu-iotests/179 | 2 +-
138
tests/qemu-iotests/183 | 2 +-
139
tests/qemu-iotests/186 | 2 +-
140
tests/qemu-iotests/187 | 2 +-
141
tests/qemu-iotests/191 | 2 +-
142
tests/qemu-iotests/195 | 2 +-
143
tests/qemu-iotests/200 | 5 +-
144
tests/qemu-iotests/200.out | 4 +-
145
tests/qemu-iotests/204 | 2 +-
146
tests/qemu-iotests/206 | 5 +-
147
tests/qemu-iotests/206.out | 6 +
148
tests/qemu-iotests/214 | 2 +-
149
tests/qemu-iotests/217 | 2 +-
150
tests/qemu-iotests/220 | 2 +-
151
tests/qemu-iotests/221 | 9 +-
152
tests/qemu-iotests/221.out | 14 +-
153
tests/qemu-iotests/229 | 5 +-
154
tests/qemu-iotests/229.out | 6 +-
155
tests/qemu-iotests/242 | 3 +-
156
tests/qemu-iotests/247 | 2 +-
157
tests/qemu-iotests/249 | 8 +-
158
tests/qemu-iotests/250 | 2 +-
159
tests/qemu-iotests/252 | 2 +-
160
tests/qemu-iotests/265 | 2 +-
161
tests/qemu-iotests/268 | 2 +-
162
tests/qemu-iotests/272 | 2 +-
163
tests/qemu-iotests/273 | 2 +-
164
tests/qemu-iotests/279 | 2 +-
165
tests/qemu-iotests/286 | 2 +-
166
tests/qemu-iotests/287 | 6 +-
167
tests/qemu-iotests/289 | 2 +-
168
tests/qemu-iotests/290 | 2 +-
169
tests/qemu-iotests/291 | 2 +-
170
tests/qemu-iotests/292 | 2 +-
171
tests/qemu-iotests/293 | 2 +-
172
tests/qemu-iotests/294 | 2 +-
173
tests/qemu-iotests/305 | 2 +-
174
tests/qemu-iotests/308 | 339 ++++++++++++++++
175
tests/qemu-iotests/308.out | 97 +++++
176
tests/qemu-iotests/check | 17 +
177
tests/qemu-iotests/common.filter | 5 +-
178
tests/qemu-iotests/common.rc | 181 ++++++++-
179
tests/qemu-iotests/group | 1 +
180
113 files changed, 1841 insertions(+), 265 deletions(-)
181
create mode 100644 include/block/fuse.h
182
create mode 100644 block/export/fuse.c
183
create mode 100755 tests/qemu-iotests/308
184
create mode 100644 tests/qemu-iotests/308.out
59
185
60
Max Reitz (5):
61
option: Make option help nicer to read
62
chardev: Indent list of chardevs
63
qdev-monitor: Make device options help nicer
64
object: Make option help nicer to read
65
fw_cfg: Drop newline in @file description
66
186
67
Peter Maydell (5):
68
block/qcow2: Don't take address of fields in packed structs
69
block/qcow: Don't take address of fields in packed structs
70
block/qcow2-bitmap: Don't take address of fields in packed structs
71
block/vhdx: Don't take address of fields in packed structs
72
block/vdi: Don't take address of fields in packed structs
73
74
Stefan Weil (1):
75
qemu-io-cmds: Fix two format strings
76
77
Thomas Huth (1):
78
block/vvfat: Fix crash when reporting error about too many files in directory
79
80
qapi/block-core.json | 7 +
81
block/vhdx.h | 12 +-
82
include/block/block.h | 5 +-
83
include/qemu/option.h | 2 +-
84
include/qemu/units.h | 18 +
85
include/sysemu/block-backend.h | 6 +-
86
block.c | 60 ++-
87
block/block-backend.c | 8 +-
88
block/bochs.c | 17 +-
89
block/cloop.c | 16 +-
90
block/curl.c | 8 +-
91
block/dmg.c | 16 +-
92
block/file-posix.c | 19 +-
93
block/gluster.c | 12 +-
94
block/iscsi.c | 8 +-
95
block/nbd-client.c | 10 +-
96
block/qcow.c | 18 +-
97
block/qcow2-bitmap.c | 24 +-
98
block/qcow2.c | 66 +--
99
block/quorum.c | 45 +-
100
block/rbd.c | 14 +-
101
block/vdi.c | 68 +--
102
block/vhdx-endian.c | 118 ++---
103
block/vhdx-log.c | 4 +-
104
block/vhdx.c | 18 +-
105
block/vpc.c | 2 +
106
block/vvfat.c | 15 +-
107
blockdev.c | 3 +-
108
chardev/char.c | 2 +-
109
crypto/block-qcow.c | 2 +
110
qdev-monitor.c | 13 +-
111
qemu-img.c | 4 +-
112
qemu-io-cmds.c | 4 +-
113
util/qemu-option.c | 32 +-
114
vl.c | 15 +-
115
tests/qemu-iotests/081 | 116 +++++
116
tests/qemu-iotests/081.out | 70 +++
117
tests/qemu-iotests/082.out | 956 ++++++++++++++++++++---------------------
118
tests/qemu-iotests/083 | 2 +-
119
tests/qemu-iotests/232 | 147 +++++++
120
tests/qemu-iotests/232.out | 59 +++
121
tests/qemu-iotests/group | 1 +
122
42 files changed, 1266 insertions(+), 776 deletions(-)
123
create mode 100755 tests/qemu-iotests/232
124
create mode 100644 tests/qemu-iotests/232.out
125
diff view generated by jsdifflib
1
To fully change the read-only state of a node, we must not only change
1
From: Gan Qixin <ganqixin@huawei.com>
2
bs->read_only, but also update bs->open_flags.
3
2
3
Replace manual lock()/unlock() calls with lock guard macros
4
(QEMU_LOCK_GUARD/WITH_QEMU_LOCK_GUARD) in block/accounting.
5
6
Signed-off-by: Gan Qixin <ganqixin@huawei.com>
7
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
8
Message-Id: <20201203075055.127773-2-ganqixin@huawei.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Eric Blake <eblake@redhat.com>
6
Reviewed-by: Alberto Garcia <berto@igalia.com>
7
---
10
---
8
block.c | 7 +++++++
11
block/accounting.c | 32 +++++++++++++++-----------------
9
1 file changed, 7 insertions(+)
12
1 file changed, 15 insertions(+), 17 deletions(-)
10
13
11
diff --git a/block.c b/block.c
14
diff --git a/block/accounting.c b/block/accounting.c
12
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
13
--- a/block.c
16
--- a/block/accounting.c
14
+++ b/block.c
17
+++ b/block/accounting.c
15
@@ -XXX,XX +XXX,XX @@ int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
18
@@ -XXX,XX +XXX,XX @@ static void block_account_one_io(BlockAcctStats *stats, BlockAcctCookie *cookie,
19
return;
16
}
20
}
17
21
18
bs->read_only = read_only;
22
- qemu_mutex_lock(&stats->lock);
19
+
23
-
20
+ if (read_only) {
24
- if (failed) {
21
+ bs->open_flags &= ~BDRV_O_RDWR;
25
- stats->failed_ops[cookie->type]++;
22
+ } else {
26
- } else {
23
+ bs->open_flags |= BDRV_O_RDWR;
27
- stats->nr_bytes[cookie->type] += cookie->bytes;
24
+ }
28
- stats->nr_ops[cookie->type]++;
25
+
29
- }
26
return 0;
30
+ WITH_QEMU_LOCK_GUARD(&stats->lock) {
31
+ if (failed) {
32
+ stats->failed_ops[cookie->type]++;
33
+ } else {
34
+ stats->nr_bytes[cookie->type] += cookie->bytes;
35
+ stats->nr_ops[cookie->type]++;
36
+ }
37
38
- block_latency_histogram_account(&stats->latency_histogram[cookie->type],
39
- latency_ns);
40
+ block_latency_histogram_account(&stats->latency_histogram[cookie->type],
41
+ latency_ns);
42
43
- if (!failed || stats->account_failed) {
44
- stats->total_time_ns[cookie->type] += latency_ns;
45
- stats->last_access_time_ns = time_ns;
46
+ if (!failed || stats->account_failed) {
47
+ stats->total_time_ns[cookie->type] += latency_ns;
48
+ stats->last_access_time_ns = time_ns;
49
50
- QSLIST_FOREACH(s, &stats->intervals, entries) {
51
- timed_average_account(&s->latency[cookie->type], latency_ns);
52
+ QSLIST_FOREACH(s, &stats->intervals, entries) {
53
+ timed_average_account(&s->latency[cookie->type], latency_ns);
54
+ }
55
}
56
}
57
58
- qemu_mutex_unlock(&stats->lock);
59
-
60
cookie->type = BLOCK_ACCT_NONE;
27
}
61
}
28
62
29
--
63
--
30
2.19.1
64
2.29.2
31
65
32
66
diff view generated by jsdifflib
1
If read-only=off, but auto-read-only=on is given, just degrade to
1
From: Gan Qixin <ganqixin@huawei.com>
2
read-only.
3
2
3
Replace manual lock()/unlock() calls with lock guard macros
4
(QEMU_LOCK_GUARD/WITH_QEMU_LOCK_GUARD) in block/curl.
5
6
Signed-off-by: Gan Qixin <ganqixin@huawei.com>
7
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
8
Message-Id: <20201203075055.127773-3-ganqixin@huawei.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Eric Blake <eblake@redhat.com>
6
---
10
---
7
block/curl.c | 8 ++++----
11
block/curl.c | 28 ++++++++++++++--------------
8
1 file changed, 4 insertions(+), 4 deletions(-)
12
1 file changed, 14 insertions(+), 14 deletions(-)
9
13
10
diff --git a/block/curl.c b/block/curl.c
14
diff --git a/block/curl.c b/block/curl.c
11
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
12
--- a/block/curl.c
16
--- a/block/curl.c
13
+++ b/block/curl.c
17
+++ b/block/curl.c
14
@@ -XXX,XX +XXX,XX @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
18
@@ -XXX,XX +XXX,XX @@ static void curl_detach_aio_context(BlockDriverState *bs)
15
const char *protocol_delimiter;
19
BDRVCURLState *s = bs->opaque;
16
int ret;
20
int i;
17
21
18
-
22
- qemu_mutex_lock(&s->mutex);
19
- if (flags & BDRV_O_RDWR) {
23
- for (i = 0; i < CURL_NUM_STATES; i++) {
20
- error_setg(errp, "curl block device does not support writes");
24
- if (s->states[i].in_use) {
21
- return -EROFS;
25
- curl_clean_state(&s->states[i]);
22
+ ret = bdrv_apply_auto_read_only(bs, "curl driver does not support writes",
26
+ WITH_QEMU_LOCK_GUARD(&s->mutex) {
23
+ errp);
27
+ for (i = 0; i < CURL_NUM_STATES; i++) {
24
+ if (ret < 0) {
28
+ if (s->states[i].in_use) {
25
+ return ret;
29
+ curl_clean_state(&s->states[i]);
30
+ }
31
+ if (s->states[i].curl) {
32
+ curl_easy_cleanup(s->states[i].curl);
33
+ s->states[i].curl = NULL;
34
+ }
35
+ g_free(s->states[i].orig_buf);
36
+ s->states[i].orig_buf = NULL;
37
}
38
- if (s->states[i].curl) {
39
- curl_easy_cleanup(s->states[i].curl);
40
- s->states[i].curl = NULL;
41
+ if (s->multi) {
42
+ curl_multi_cleanup(s->multi);
43
+ s->multi = NULL;
44
}
45
- g_free(s->states[i].orig_buf);
46
- s->states[i].orig_buf = NULL;
47
- }
48
- if (s->multi) {
49
- curl_multi_cleanup(s->multi);
50
- s->multi = NULL;
26
}
51
}
27
52
- qemu_mutex_unlock(&s->mutex);
28
if (!libcurl_initialized) {
53
54
timer_del(&s->timer);
55
}
29
--
56
--
30
2.19.1
57
2.29.2
31
58
32
59
diff view generated by jsdifflib
1
From: Peter Maydell <peter.maydell@linaro.org>
1
From: Gan Qixin <ganqixin@huawei.com>
2
2
3
Taking the address of a field in a packed struct is a bad idea, because
3
Replace manual lock()/unlock() calls with lock guard macros
4
it might not be actually aligned enough for that pointer type (and
4
(QEMU_LOCK_GUARD/WITH_QEMU_LOCK_GUARD) in block/throttle-groups.
5
thus cause a crash on dereference on some host architectures). Newer
6
versions of clang warn about this. Avoid the bug by not using the
7
"modify in place" byte swapping functions.
8
5
9
There are a few places where the in-place swap function is
6
Signed-off-by: Gan Qixin <ganqixin@huawei.com>
10
used on something other than a packed struct field; we convert
7
Message-Id: <20201203075055.127773-4-ganqixin@huawei.com>
11
those anyway, for consistency.
12
13
This patch was produced with the following spatch script
14
(and hand-editing to fold a few resulting overlength lines):
15
16
@@
17
expression E;
18
@@
19
-be16_to_cpus(&E);
20
+E = be16_to_cpu(E);
21
@@
22
expression E;
23
@@
24
-be32_to_cpus(&E);
25
+E = be32_to_cpu(E);
26
@@
27
expression E;
28
@@
29
-be64_to_cpus(&E);
30
+E = be64_to_cpu(E);
31
@@
32
expression E;
33
@@
34
-cpu_to_be16s(&E);
35
+E = cpu_to_be16(E);
36
@@
37
expression E;
38
@@
39
-cpu_to_be32s(&E);
40
+E = cpu_to_be32(E);
41
@@
42
expression E;
43
@@
44
-cpu_to_be64s(&E);
45
+E = cpu_to_be64(E);
46
47
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
48
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
49
Tested-by: John Snow <jsnow@redhat.com>
50
Reviewed-by: John Snow <jsnow@redhat.com>
51
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
52
---
9
---
53
block/qcow2.c | 64 +++++++++++++++++++++++++++------------------------
10
block/throttle-groups.c | 48 ++++++++++++++++++++---------------------
54
1 file changed, 34 insertions(+), 30 deletions(-)
11
1 file changed, 23 insertions(+), 25 deletions(-)
55
12
56
diff --git a/block/qcow2.c b/block/qcow2.c
13
diff --git a/block/throttle-groups.c b/block/throttle-groups.c
57
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
58
--- a/block/qcow2.c
15
--- a/block/throttle-groups.c
59
+++ b/block/qcow2.c
16
+++ b/block/throttle-groups.c
60
@@ -XXX,XX +XXX,XX @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
17
@@ -XXX,XX +XXX,XX @@ void throttle_group_register_tgm(ThrottleGroupMember *tgm,
61
"pread fail from offset %" PRIu64, offset);
18
tgm->aio_context = ctx;
62
return 1;
19
qatomic_set(&tgm->restart_pending, 0);
20
21
- qemu_mutex_lock(&tg->lock);
22
+ QEMU_LOCK_GUARD(&tg->lock);
23
/* If the ThrottleGroup is new set this ThrottleGroupMember as the token */
24
for (i = 0; i < 2; i++) {
25
if (!tg->tokens[i]) {
26
@@ -XXX,XX +XXX,XX @@ void throttle_group_register_tgm(ThrottleGroupMember *tgm,
27
qemu_co_mutex_init(&tgm->throttled_reqs_lock);
28
qemu_co_queue_init(&tgm->throttled_reqs[0]);
29
qemu_co_queue_init(&tgm->throttled_reqs[1]);
30
-
31
- qemu_mutex_unlock(&tg->lock);
32
}
33
34
/* Unregister a ThrottleGroupMember from its group, removing it from the list,
35
@@ -XXX,XX +XXX,XX @@ void throttle_group_unregister_tgm(ThrottleGroupMember *tgm)
36
/* Wait for throttle_group_restart_queue_entry() coroutines to finish */
37
AIO_WAIT_WHILE(tgm->aio_context, qatomic_read(&tgm->restart_pending) > 0);
38
39
- qemu_mutex_lock(&tg->lock);
40
- for (i = 0; i < 2; i++) {
41
- assert(tgm->pending_reqs[i] == 0);
42
- assert(qemu_co_queue_empty(&tgm->throttled_reqs[i]));
43
- assert(!timer_pending(tgm->throttle_timers.timers[i]));
44
- if (tg->tokens[i] == tgm) {
45
- token = throttle_group_next_tgm(tgm);
46
- /* Take care of the case where this is the last tgm in the group */
47
- if (token == tgm) {
48
- token = NULL;
49
+ WITH_QEMU_LOCK_GUARD(&tg->lock) {
50
+ for (i = 0; i < 2; i++) {
51
+ assert(tgm->pending_reqs[i] == 0);
52
+ assert(qemu_co_queue_empty(&tgm->throttled_reqs[i]));
53
+ assert(!timer_pending(tgm->throttle_timers.timers[i]));
54
+ if (tg->tokens[i] == tgm) {
55
+ token = throttle_group_next_tgm(tgm);
56
+ /* Take care of the case where this is the last tgm in the group */
57
+ if (token == tgm) {
58
+ token = NULL;
59
+ }
60
+ tg->tokens[i] = token;
61
}
62
- tg->tokens[i] = token;
63
}
63
}
64
- be32_to_cpus(&ext.magic);
64
- }
65
- be32_to_cpus(&ext.len);
65
66
+ ext.magic = be32_to_cpu(ext.magic);
66
- /* remove the current tgm from the list */
67
+ ext.len = be32_to_cpu(ext.len);
67
- QLIST_REMOVE(tgm, round_robin);
68
offset += sizeof(ext);
68
- throttle_timers_destroy(&tgm->throttle_timers);
69
#ifdef DEBUG_EXT
69
- qemu_mutex_unlock(&tg->lock);
70
printf("ext.magic = 0x%x\n", ext.magic);
70
+ /* remove the current tgm from the list */
71
@@ -XXX,XX +XXX,XX @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
71
+ QLIST_REMOVE(tgm, round_robin);
72
"Unable to read CRYPTO header extension");
72
+ throttle_timers_destroy(&tgm->throttle_timers);
73
return ret;
73
+ }
74
}
74
75
- be64_to_cpus(&s->crypto_header.offset);
75
throttle_group_unref(&tg->ts);
76
- be64_to_cpus(&s->crypto_header.length);
76
tgm->throttle_state = NULL;
77
+ s->crypto_header.offset = be64_to_cpu(s->crypto_header.offset);
77
@@ -XXX,XX +XXX,XX @@ void throttle_group_detach_aio_context(ThrottleGroupMember *tgm)
78
+ s->crypto_header.length = be64_to_cpu(s->crypto_header.length);
78
assert(qemu_co_queue_empty(&tgm->throttled_reqs[1]));
79
79
80
if ((s->crypto_header.offset % s->cluster_size) != 0) {
80
/* Kick off next ThrottleGroupMember, if necessary */
81
error_setg(errp, "Encryption header offset '%" PRIu64 "' is "
81
- qemu_mutex_lock(&tg->lock);
82
@@ -XXX,XX +XXX,XX @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
82
- for (i = 0; i < 2; i++) {
83
return -EINVAL;
83
- if (timer_pending(tt->timers[i])) {
84
}
84
- tg->any_timer_armed[i] = false;
85
85
- schedule_next_request(tgm, i);
86
- be32_to_cpus(&bitmaps_ext.nb_bitmaps);
86
+ WITH_QEMU_LOCK_GUARD(&tg->lock) {
87
- be64_to_cpus(&bitmaps_ext.bitmap_directory_size);
87
+ for (i = 0; i < 2; i++) {
88
- be64_to_cpus(&bitmaps_ext.bitmap_directory_offset);
88
+ if (timer_pending(tt->timers[i])) {
89
+ bitmaps_ext.nb_bitmaps = be32_to_cpu(bitmaps_ext.nb_bitmaps);
89
+ tg->any_timer_armed[i] = false;
90
+ bitmaps_ext.bitmap_directory_size =
90
+ schedule_next_request(tgm, i);
91
+ be64_to_cpu(bitmaps_ext.bitmap_directory_size);
91
+ }
92
+ bitmaps_ext.bitmap_directory_offset =
93
+ be64_to_cpu(bitmaps_ext.bitmap_directory_offset);
94
95
if (bitmaps_ext.nb_bitmaps > QCOW2_MAX_BITMAPS) {
96
error_setg(errp,
97
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
98
error_setg_errno(errp, -ret, "Could not read qcow2 header");
99
goto fail;
100
}
101
- be32_to_cpus(&header.magic);
102
- be32_to_cpus(&header.version);
103
- be64_to_cpus(&header.backing_file_offset);
104
- be32_to_cpus(&header.backing_file_size);
105
- be64_to_cpus(&header.size);
106
- be32_to_cpus(&header.cluster_bits);
107
- be32_to_cpus(&header.crypt_method);
108
- be64_to_cpus(&header.l1_table_offset);
109
- be32_to_cpus(&header.l1_size);
110
- be64_to_cpus(&header.refcount_table_offset);
111
- be32_to_cpus(&header.refcount_table_clusters);
112
- be64_to_cpus(&header.snapshots_offset);
113
- be32_to_cpus(&header.nb_snapshots);
114
+ header.magic = be32_to_cpu(header.magic);
115
+ header.version = be32_to_cpu(header.version);
116
+ header.backing_file_offset = be64_to_cpu(header.backing_file_offset);
117
+ header.backing_file_size = be32_to_cpu(header.backing_file_size);
118
+ header.size = be64_to_cpu(header.size);
119
+ header.cluster_bits = be32_to_cpu(header.cluster_bits);
120
+ header.crypt_method = be32_to_cpu(header.crypt_method);
121
+ header.l1_table_offset = be64_to_cpu(header.l1_table_offset);
122
+ header.l1_size = be32_to_cpu(header.l1_size);
123
+ header.refcount_table_offset = be64_to_cpu(header.refcount_table_offset);
124
+ header.refcount_table_clusters =
125
+ be32_to_cpu(header.refcount_table_clusters);
126
+ header.snapshots_offset = be64_to_cpu(header.snapshots_offset);
127
+ header.nb_snapshots = be32_to_cpu(header.nb_snapshots);
128
129
if (header.magic != QCOW_MAGIC) {
130
error_setg(errp, "Image is not in qcow2 format");
131
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
132
header.refcount_order = 4;
133
header.header_length = 72;
134
} else {
135
- be64_to_cpus(&header.incompatible_features);
136
- be64_to_cpus(&header.compatible_features);
137
- be64_to_cpus(&header.autoclear_features);
138
- be32_to_cpus(&header.refcount_order);
139
- be32_to_cpus(&header.header_length);
140
+ header.incompatible_features =
141
+ be64_to_cpu(header.incompatible_features);
142
+ header.compatible_features = be64_to_cpu(header.compatible_features);
143
+ header.autoclear_features = be64_to_cpu(header.autoclear_features);
144
+ header.refcount_order = be32_to_cpu(header.refcount_order);
145
+ header.header_length = be32_to_cpu(header.header_length);
146
147
if (header.header_length < 104) {
148
error_setg(errp, "qcow2 header too short");
149
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
150
goto fail;
151
}
152
for(i = 0;i < s->l1_size; i++) {
153
- be64_to_cpus(&s->l1_table[i]);
154
+ s->l1_table[i] = be64_to_cpu(s->l1_table[i]);
155
}
92
}
156
}
93
}
157
94
- qemu_mutex_unlock(&tg->lock);
158
@@ -XXX,XX +XXX,XX @@ int qcow2_update_header(BlockDriverState *bs)
95
159
96
throttle_timers_detach_aio_context(tt);
160
/* Full disk encryption header pointer extension */
97
tgm->aio_context = NULL;
161
if (s->crypto_header.offset != 0) {
162
- cpu_to_be64s(&s->crypto_header.offset);
163
- cpu_to_be64s(&s->crypto_header.length);
164
+ s->crypto_header.offset = cpu_to_be64(s->crypto_header.offset);
165
+ s->crypto_header.length = cpu_to_be64(s->crypto_header.length);
166
ret = header_ext_add(buf, QCOW2_EXT_MAGIC_CRYPTO_HEADER,
167
&s->crypto_header, sizeof(s->crypto_header),
168
buflen);
169
- be64_to_cpus(&s->crypto_header.offset);
170
- be64_to_cpus(&s->crypto_header.length);
171
+ s->crypto_header.offset = be64_to_cpu(s->crypto_header.offset);
172
+ s->crypto_header.length = be64_to_cpu(s->crypto_header.length);
173
if (ret < 0) {
174
goto fail;
175
}
176
--
98
--
177
2.19.1
99
2.29.2
178
100
179
101
diff view generated by jsdifflib
1
If read-only=off, but auto-read-only=on is given, open the volume
1
From: Gan Qixin <ganqixin@huawei.com>
2
read-write if we have the permissions, but instead of erroring out for
3
read-only volumes, just degrade to read-only.
4
2
3
Replace manual lock()/unlock() calls with lock guard macros
4
(QEMU_LOCK_GUARD/WITH_QEMU_LOCK_GUARD) in block/iscsi.
5
6
Signed-off-by: Gan Qixin <ganqixin@huawei.com>
7
Message-Id: <20201203075055.127773-5-ganqixin@huawei.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
7
---
9
---
8
block/iscsi.c | 8 +++++---
10
block/iscsi.c | 50 ++++++++++++++++++++++++--------------------------
9
1 file changed, 5 insertions(+), 3 deletions(-)
11
1 file changed, 24 insertions(+), 26 deletions(-)
10
12
11
diff --git a/block/iscsi.c b/block/iscsi.c
13
diff --git a/block/iscsi.c b/block/iscsi.c
12
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
13
--- a/block/iscsi.c
15
--- a/block/iscsi.c
14
+++ b/block/iscsi.c
16
+++ b/block/iscsi.c
15
@@ -XXX,XX +XXX,XX @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
17
@@ -XXX,XX +XXX,XX @@ iscsi_aio_cancel(BlockAIOCB *blockacb)
16
/* Check the write protect flag of the LUN if we want to write */
18
IscsiAIOCB *acb = (IscsiAIOCB *)blockacb;
17
if (iscsilun->type == TYPE_DISK && (flags & BDRV_O_RDWR) &&
19
IscsiLun *iscsilun = acb->iscsilun;
18
iscsilun->write_protected) {
20
19
- error_setg(errp, "Cannot open a write protected LUN as read-write");
21
- qemu_mutex_lock(&iscsilun->mutex);
20
- ret = -EACCES;
22
+ WITH_QEMU_LOCK_GUARD(&iscsilun->mutex) {
21
- goto out;
23
22
+ ret = bdrv_apply_auto_read_only(bs, "LUN is write protected", errp);
24
- /* If it was cancelled or completed already, our work is done here */
23
+ if (ret < 0) {
25
- if (acb->cancelled || acb->status != -EINPROGRESS) {
24
+ goto out;
26
- qemu_mutex_unlock(&iscsilun->mutex);
27
- return;
28
- }
29
+ /* If it was cancelled or completed already, our work is done here */
30
+ if (acb->cancelled || acb->status != -EINPROGRESS) {
31
+ return;
25
+ }
32
+ }
26
+ flags &= ~BDRV_O_RDWR;
33
34
- acb->cancelled = true;
35
+ acb->cancelled = true;
36
37
- qemu_aio_ref(acb); /* released in iscsi_abort_task_cb() */
38
+ qemu_aio_ref(acb); /* released in iscsi_abort_task_cb() */
39
40
- /* send a task mgmt call to the target to cancel the task on the target */
41
- if (iscsi_task_mgmt_abort_task_async(iscsilun->iscsi, acb->task,
42
- iscsi_abort_task_cb, acb) < 0) {
43
- qemu_aio_unref(acb); /* since iscsi_abort_task_cb() won't be called */
44
+ /* send a task mgmt call to the target to cancel the task on the target */
45
+ if (iscsi_task_mgmt_abort_task_async(iscsilun->iscsi, acb->task,
46
+ iscsi_abort_task_cb, acb) < 0) {
47
+ qemu_aio_unref(acb); /* since iscsi_abort_task_cb() won't be called */
48
+ }
27
}
49
}
28
50
-
29
iscsi_readcapacity_sync(iscsilun, &local_err);
51
- qemu_mutex_unlock(&iscsilun->mutex);
52
}
53
54
static const AIOCBInfo iscsi_aiocb_info = {
55
@@ -XXX,XX +XXX,XX @@ static void iscsi_timed_check_events(void *opaque)
56
{
57
IscsiLun *iscsilun = opaque;
58
59
- qemu_mutex_lock(&iscsilun->mutex);
60
+ WITH_QEMU_LOCK_GUARD(&iscsilun->mutex) {
61
+ /* check for timed out requests */
62
+ iscsi_service(iscsilun->iscsi, 0);
63
64
- /* check for timed out requests */
65
- iscsi_service(iscsilun->iscsi, 0);
66
+ if (iscsilun->request_timed_out) {
67
+ iscsilun->request_timed_out = false;
68
+ iscsi_reconnect(iscsilun->iscsi);
69
+ }
70
71
- if (iscsilun->request_timed_out) {
72
- iscsilun->request_timed_out = false;
73
- iscsi_reconnect(iscsilun->iscsi);
74
+ /*
75
+ * newer versions of libiscsi may return zero events. Ensure we are
76
+ * able to return to service once this situation changes.
77
+ */
78
+ iscsi_set_events(iscsilun);
79
}
80
81
- /* newer versions of libiscsi may return zero events. Ensure we are able
82
- * to return to service once this situation changes. */
83
- iscsi_set_events(iscsilun);
84
-
85
- qemu_mutex_unlock(&iscsilun->mutex);
86
-
87
timer_mod(iscsilun->event_timer,
88
qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + EVENT_INTERVAL);
89
}
30
--
90
--
31
2.19.1
91
2.29.2
32
92
33
93
diff view generated by jsdifflib
1
From: Leonid Bloch <lbloch@janustech.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
The lookup table for power-of-two sizes was added in commit 540b8492618eb
3
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
for the purpose of having convenient shortcuts for these sizes in cases
4
Message-Id: <20201027190600.192171-2-mreitz@redhat.com>
5
when the literal number has to be present at compile time, and
6
expressions as '(1 * KiB)' can not be used. One such case is the
7
stringification of sizes. Beyond that, it is convenient to use these
8
shortcuts for all power-of-two sizes, even if they don't have to be
9
literal numbers.
10
11
Despite its convenience, this table introduced 55 lines of "dumb" code,
12
the purpose and origin of which are obscure without reading the message
13
of the commit which introduced it. This patch fixes that by adding a
14
comment to the code itself with a brief explanation for the reasoning
15
behind this table. This comment includes the short AWK script that
16
generated the table, so that anyone who's interested could make sure
17
that the values in it are correct (otherwise these values look as if
18
they were typed manually).
19
20
Signed-off-by: Leonid Bloch <lbloch@janustech.com>
21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
---
6
---
23
include/qemu/units.h | 18 ++++++++++++++++++
7
meson_options.txt | 2 ++
24
1 file changed, 18 insertions(+)
8
configure | 7 +++++++
9
meson.build | 6 ++++++
10
3 files changed, 15 insertions(+)
25
11
26
diff --git a/include/qemu/units.h b/include/qemu/units.h
12
diff --git a/meson_options.txt b/meson_options.txt
27
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
28
--- a/include/qemu/units.h
14
--- a/meson_options.txt
29
+++ b/include/qemu/units.h
15
+++ b/meson_options.txt
30
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ option('virtiofsd', type: 'feature', value: 'auto',
31
#define PiB (INT64_C(1) << 50)
17
description: 'build virtiofs daemon (virtiofsd)')
32
#define EiB (INT64_C(1) << 60)
18
option('vhost_user_blk_server', type: 'feature', value: 'auto',
33
19
description: 'build vhost-user-blk server')
34
+/*
20
+option('fuse', type: 'feature', value: 'auto',
35
+ * The following lookup table is intended to be used when a literal string of
21
+ description: 'FUSE block device export')
36
+ * the number of bytes is required (for example if it needs to be stringified).
22
37
+ * It can also be used for generic shortcuts of power-of-two sizes.
23
option('capstone', type: 'combo', value: 'auto',
38
+ * This table is generated using the AWK script below:
24
choices: ['disabled', 'enabled', 'auto', 'system', 'internal'],
39
+ *
25
diff --git a/configure b/configure
40
+ * BEGIN {
26
index XXXXXXX..XXXXXXX 100755
41
+ * suffix="KMGTPE";
27
--- a/configure
42
+ * for(i=10; i<64; i++) {
28
+++ b/configure
43
+ * val=2**i;
29
@@ -XXX,XX +XXX,XX @@ meson=""
44
+ * s=substr(suffix, int(i/10), 1);
30
ninja=""
45
+ * n=2**(i%10);
31
skip_meson=no
46
+ * pad=21-int(log(n)/log(10));
32
gettext=""
47
+ * printf("#define S_%d%siB %*d\n", n, s, pad, val);
33
+fuse="auto"
48
+ * }
34
49
+ * }
35
bogus_os="no"
50
+ */
36
malloc_trim="auto"
37
@@ -XXX,XX +XXX,XX @@ for opt do
38
;;
39
--disable-libdaxctl) libdaxctl=no
40
;;
41
+ --enable-fuse) fuse="enabled"
42
+ ;;
43
+ --disable-fuse) fuse="disabled"
44
+ ;;
45
*)
46
echo "ERROR: unknown option $opt"
47
echo "Try '$0 --help' for more information"
48
@@ -XXX,XX +XXX,XX @@ disabled with --disable-FEATURE, default is enabled if available:
49
xkbcommon xkbcommon support
50
rng-none dummy RNG, avoid using /dev/(u)random and getrandom()
51
libdaxctl libdaxctl support
52
+ fuse FUSE block device export
53
54
NOTE: The object files are built at the place where configure is launched
55
EOF
56
@@ -XXX,XX +XXX,XX @@ NINJA=$ninja $meson setup \
57
-Diconv=$iconv -Dcurses=$curses -Dlibudev=$libudev\
58
-Ddocs=$docs -Dsphinx_build=$sphinx_build -Dinstall_blobs=$blobs \
59
-Dvhost_user_blk_server=$vhost_user_blk_server \
60
+ -Dfuse=$fuse \
61
$cross_arg \
62
"$PWD" "$source_path"
63
64
diff --git a/meson.build b/meson.build
65
index XXXXXXX..XXXXXXX 100644
66
--- a/meson.build
67
+++ b/meson.build
68
@@ -XXX,XX +XXX,XX @@ elif get_option('vhost_user_blk_server').disabled() or not have_system
69
have_vhost_user_blk_server = false
70
endif
71
72
+fuse = dependency('fuse3', required: get_option('fuse'),
73
+ version: '>=3.1', method: 'pkg-config',
74
+ static: enable_static)
51
+
75
+
52
#define S_1KiB 1024
76
#################
53
#define S_2KiB 2048
77
# config-host.h #
54
#define S_4KiB 4096
78
#################
79
@@ -XXX,XX +XXX,XX @@ config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
80
config_host_data.set('CONFIG_GETTID', has_gettid)
81
config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
82
config_host_data.set('CONFIG_STATX', has_statx)
83
+config_host_data.set('CONFIG_FUSE', fuse.found())
84
config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
85
config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
86
config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
87
@@ -XXX,XX +XXX,XX @@ endif
88
summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
89
summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')}
90
summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
91
+summary_info += {'FUSE exports': fuse.found()}
92
summary(summary_info, bool_yn: true)
93
94
if not supported_cpus.contains(cpu)
55
--
95
--
56
2.19.1
96
2.29.2
57
97
58
98
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
Signed-off-by: Alberto Garcia <berto@igalia.com>
3
block-export-add type=fuse allows mounting block graph nodes via FUSE on
4
some existing regular file. That file should then appears like a raw
5
disk image, and accesses to it result in accesses to the exported BDS.
6
7
Right now, we only implement the necessary block export functions to set
8
it up and shut it down. We do not implement any access functions, so
9
accessing the mount point only results in errors. This will be
10
addressed by a followup patch.
11
12
We keep a hash table of exported mount points, because we want to be
13
able to detect when users try to use a mount point twice. This is
14
because we invoke stat() to check whether the given mount point is a
15
regular file, but if that file is served by ourselves (because it is
16
already used as a mount point), then this stat() would have to be served
17
by ourselves, too, which is impossible to do while we (as the caller)
18
are waiting for it to settle. Therefore, keep track of mount point
19
paths to at least catch the most obvious instances of that problem.
20
21
Signed-off-by: Max Reitz <mreitz@redhat.com>
22
Message-Id: <20201027190600.192171-3-mreitz@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
23
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
---
24
---
6
block.c | 6 +++---
25
qapi/block-export.json | 23 ++-
7
1 file changed, 3 insertions(+), 3 deletions(-)
26
include/block/fuse.h | 30 ++++
8
27
block.c | 1 +
28
block/export/export.c | 4 +
29
block/export/fuse.c | 295 +++++++++++++++++++++++++++++++++++++++
30
MAINTAINERS | 6 +
31
block/export/meson.build | 2 +
32
7 files changed, 359 insertions(+), 2 deletions(-)
33
create mode 100644 include/block/fuse.h
34
create mode 100644 block/export/fuse.c
35
36
diff --git a/qapi/block-export.json b/qapi/block-export.json
37
index XXXXXXX..XXXXXXX 100644
38
--- a/qapi/block-export.json
39
+++ b/qapi/block-export.json
40
@@ -XXX,XX +XXX,XX @@
41
     '*logical-block-size': 'size',
42
'*num-queues': 'uint16'} }
43
44
+##
45
+# @BlockExportOptionsFuse:
46
+#
47
+# Options for exporting a block graph node on some (file) mountpoint
48
+# as a raw image.
49
+#
50
+# @mountpoint: Path on which to export the block device via FUSE.
51
+# This must point to an existing regular file.
52
+#
53
+# Since: 6.0
54
+##
55
+{ 'struct': 'BlockExportOptionsFuse',
56
+ 'data': { 'mountpoint': 'str' },
57
+ 'if': 'defined(CONFIG_FUSE)' }
58
+
59
##
60
# @NbdServerAddOptions:
61
#
62
@@ -XXX,XX +XXX,XX @@
63
#
64
# @nbd: NBD export
65
# @vhost-user-blk: vhost-user-blk export (since 5.2)
66
+# @fuse: FUSE export (since: 6.0)
67
#
68
# Since: 4.2
69
##
70
{ 'enum': 'BlockExportType',
71
- 'data': [ 'nbd', 'vhost-user-blk' ] }
72
+ 'data': [ 'nbd', 'vhost-user-blk',
73
+ { 'name': 'fuse', 'if': 'defined(CONFIG_FUSE)' } ] }
74
75
##
76
# @BlockExportOptions:
77
@@ -XXX,XX +XXX,XX @@
78
'discriminator': 'type',
79
'data': {
80
'nbd': 'BlockExportOptionsNbd',
81
- 'vhost-user-blk': 'BlockExportOptionsVhostUserBlk'
82
+ 'vhost-user-blk': 'BlockExportOptionsVhostUserBlk',
83
+ 'fuse': { 'type': 'BlockExportOptionsFuse',
84
+ 'if': 'defined(CONFIG_FUSE)' }
85
} }
86
87
##
88
diff --git a/include/block/fuse.h b/include/block/fuse.h
89
new file mode 100644
90
index XXXXXXX..XXXXXXX
91
--- /dev/null
92
+++ b/include/block/fuse.h
93
@@ -XXX,XX +XXX,XX @@
94
+/*
95
+ * Present a block device as a raw image through FUSE
96
+ *
97
+ * Copyright (c) 2020 Max Reitz <mreitz@redhat.com>
98
+ *
99
+ * This program is free software; you can redistribute it and/or modify
100
+ * it under the terms of the GNU General Public License as published by
101
+ * the Free Software Foundation; under version 2 or later of the License.
102
+ *
103
+ * This program is distributed in the hope that it will be useful,
104
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
105
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
106
+ * GNU General Public License for more details.
107
+ *
108
+ * You should have received a copy of the GNU General Public License
109
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
110
+ */
111
+
112
+#ifndef BLOCK_FUSE_H
113
+#define BLOCK_FUSE_H
114
+
115
+#ifdef CONFIG_FUSE
116
+
117
+#include "block/export.h"
118
+
119
+extern const BlockExportDriver blk_exp_fuse;
120
+
121
+#endif /* CONFIG_FUSE */
122
+
123
+#endif
9
diff --git a/block.c b/block.c
124
diff --git a/block.c b/block.c
10
index XXXXXXX..XXXXXXX 100644
125
index XXXXXXX..XXXXXXX 100644
11
--- a/block.c
126
--- a/block.c
12
+++ b/block.c
127
+++ b/block.c
13
@@ -XXX,XX +XXX,XX @@ QemuOptsList bdrv_runtime_opts = {
128
@@ -XXX,XX +XXX,XX @@
14
.help = "try to optimize zero writes (off, on, unmap)",
129
#include "block/trace.h"
15
},
130
#include "block/block_int.h"
16
{
131
#include "block/blockjob.h"
17
- .name = "discard",
132
+#include "block/fuse.h"
18
+ .name = BDRV_OPT_DISCARD,
133
#include "block/nbd.h"
19
.type = QEMU_OPT_STRING,
134
#include "block/qdict.h"
20
.help = "discard operation (ignore/off, unmap/on)",
135
#include "qemu/error-report.h"
21
},
136
diff --git a/block/export/export.c b/block/export/export.c
22
@@ -XXX,XX +XXX,XX @@ static int bdrv_open_common(BlockDriverState *bs, BlockBackend *file,
137
index XXXXXXX..XXXXXXX 100644
23
}
138
--- a/block/export/export.c
24
}
139
+++ b/block/export/export.c
25
140
@@ -XXX,XX +XXX,XX @@
26
- discard = qemu_opt_get(opts, "discard");
141
#include "sysemu/block-backend.h"
27
+ discard = qemu_opt_get(opts, BDRV_OPT_DISCARD);
142
#include "sysemu/iothread.h"
28
if (discard != NULL) {
143
#include "block/export.h"
29
if (bdrv_parse_discard_flags(discard, &bs->open_flags) != 0) {
144
+#include "block/fuse.h"
30
error_setg(errp, "Invalid discard option");
145
#include "block/nbd.h"
31
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
146
#include "qapi/error.h"
32
147
#include "qapi/qapi-commands-block-export.h"
33
update_flags_from_options(&reopen_state->flags, opts);
148
@@ -XXX,XX +XXX,XX @@ static const BlockExportDriver *blk_exp_drivers[] = {
34
149
#ifdef CONFIG_VHOST_USER_BLK_SERVER
35
- discard = qemu_opt_get_del(opts, "discard");
150
&blk_exp_vhost_user_blk,
36
+ discard = qemu_opt_get_del(opts, BDRV_OPT_DISCARD);
151
#endif
37
if (discard != NULL) {
152
+#ifdef CONFIG_FUSE
38
if (bdrv_parse_discard_flags(discard, &reopen_state->flags) != 0) {
153
+ &blk_exp_fuse,
39
error_setg(errp, "Invalid discard option");
154
+#endif
155
};
156
157
/* Only accessed from the main thread */
158
diff --git a/block/export/fuse.c b/block/export/fuse.c
159
new file mode 100644
160
index XXXXXXX..XXXXXXX
161
--- /dev/null
162
+++ b/block/export/fuse.c
163
@@ -XXX,XX +XXX,XX @@
164
+/*
165
+ * Present a block device as a raw image through FUSE
166
+ *
167
+ * Copyright (c) 2020 Max Reitz <mreitz@redhat.com>
168
+ *
169
+ * This program is free software; you can redistribute it and/or modify
170
+ * it under the terms of the GNU General Public License as published by
171
+ * the Free Software Foundation; under version 2 or later of the License.
172
+ *
173
+ * This program is distributed in the hope that it will be useful,
174
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
175
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
176
+ * GNU General Public License for more details.
177
+ *
178
+ * You should have received a copy of the GNU General Public License
179
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
180
+ */
181
+
182
+#define FUSE_USE_VERSION 31
183
+
184
+#include "qemu/osdep.h"
185
+#include "block/aio.h"
186
+#include "block/block.h"
187
+#include "block/export.h"
188
+#include "block/fuse.h"
189
+#include "block/qapi.h"
190
+#include "qapi/error.h"
191
+#include "qapi/qapi-commands-block.h"
192
+#include "sysemu/block-backend.h"
193
+
194
+#include <fuse.h>
195
+#include <fuse_lowlevel.h>
196
+
197
+
198
+/* Prevent overly long bounce buffer allocations */
199
+#define FUSE_MAX_BOUNCE_BYTES (MIN(BDRV_REQUEST_MAX_BYTES, 64 * 1024 * 1024))
200
+
201
+
202
+typedef struct FuseExport {
203
+ BlockExport common;
204
+
205
+ struct fuse_session *fuse_session;
206
+ struct fuse_buf fuse_buf;
207
+ bool mounted, fd_handler_set_up;
208
+
209
+ char *mountpoint;
210
+ bool writable;
211
+} FuseExport;
212
+
213
+static GHashTable *exports;
214
+static const struct fuse_lowlevel_ops fuse_ops;
215
+
216
+static void fuse_export_shutdown(BlockExport *exp);
217
+static void fuse_export_delete(BlockExport *exp);
218
+
219
+static void init_exports_table(void);
220
+
221
+static int setup_fuse_export(FuseExport *exp, const char *mountpoint,
222
+ Error **errp);
223
+static void read_from_fuse_export(void *opaque);
224
+
225
+static bool is_regular_file(const char *path, Error **errp);
226
+
227
+
228
+static int fuse_export_create(BlockExport *blk_exp,
229
+ BlockExportOptions *blk_exp_args,
230
+ Error **errp)
231
+{
232
+ FuseExport *exp = container_of(blk_exp, FuseExport, common);
233
+ BlockExportOptionsFuse *args = &blk_exp_args->u.fuse;
234
+ int ret;
235
+
236
+ assert(blk_exp_args->type == BLOCK_EXPORT_TYPE_FUSE);
237
+
238
+ init_exports_table();
239
+
240
+ /*
241
+ * It is important to do this check before calling is_regular_file() --
242
+ * that function will do a stat(), which we would have to handle if we
243
+ * already exported something on @mountpoint. But we cannot, because
244
+ * we are currently caught up here.
245
+ * (Note that ideally we would want to resolve relative paths here,
246
+ * but bdrv_make_absolute_filename() might do the wrong thing for
247
+ * paths that contain colons, and realpath() would resolve symlinks,
248
+ * which we do not want: The mount point is not going to be the
249
+ * symlink's destination, but the link itself.)
250
+ * So this will not catch all potential clashes, but hopefully at
251
+ * least the most common one of specifying exactly the same path
252
+ * string twice.
253
+ */
254
+ if (g_hash_table_contains(exports, args->mountpoint)) {
255
+ error_setg(errp, "There already is a FUSE export on '%s'",
256
+ args->mountpoint);
257
+ ret = -EEXIST;
258
+ goto fail;
259
+ }
260
+
261
+ if (!is_regular_file(args->mountpoint, errp)) {
262
+ ret = -EINVAL;
263
+ goto fail;
264
+ }
265
+
266
+ exp->mountpoint = g_strdup(args->mountpoint);
267
+ exp->writable = blk_exp_args->writable;
268
+
269
+ ret = setup_fuse_export(exp, args->mountpoint, errp);
270
+ if (ret < 0) {
271
+ goto fail;
272
+ }
273
+
274
+ return 0;
275
+
276
+fail:
277
+ fuse_export_delete(blk_exp);
278
+ return ret;
279
+}
280
+
281
+/**
282
+ * Allocates the global @exports hash table.
283
+ */
284
+static void init_exports_table(void)
285
+{
286
+ if (exports) {
287
+ return;
288
+ }
289
+
290
+ exports = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
291
+}
292
+
293
+/**
294
+ * Create exp->fuse_session and mount it.
295
+ */
296
+static int setup_fuse_export(FuseExport *exp, const char *mountpoint,
297
+ Error **errp)
298
+{
299
+ const char *fuse_argv[4];
300
+ char *mount_opts;
301
+ struct fuse_args fuse_args;
302
+ int ret;
303
+
304
+ /* Needs to match what fuse_init() sets. Only max_read must be supplied. */
305
+ mount_opts = g_strdup_printf("max_read=%zu", FUSE_MAX_BOUNCE_BYTES);
306
+
307
+ fuse_argv[0] = ""; /* Dummy program name */
308
+ fuse_argv[1] = "-o";
309
+ fuse_argv[2] = mount_opts;
310
+ fuse_argv[3] = NULL;
311
+ fuse_args = (struct fuse_args)FUSE_ARGS_INIT(3, (char **)fuse_argv);
312
+
313
+ exp->fuse_session = fuse_session_new(&fuse_args, &fuse_ops,
314
+ sizeof(fuse_ops), exp);
315
+ g_free(mount_opts);
316
+ if (!exp->fuse_session) {
317
+ error_setg(errp, "Failed to set up FUSE session");
318
+ ret = -EIO;
319
+ goto fail;
320
+ }
321
+
322
+ ret = fuse_session_mount(exp->fuse_session, mountpoint);
323
+ if (ret < 0) {
324
+ error_setg(errp, "Failed to mount FUSE session to export");
325
+ ret = -EIO;
326
+ goto fail;
327
+ }
328
+ exp->mounted = true;
329
+
330
+ g_hash_table_insert(exports, g_strdup(mountpoint), NULL);
331
+
332
+ aio_set_fd_handler(exp->common.ctx,
333
+ fuse_session_fd(exp->fuse_session), true,
334
+ read_from_fuse_export, NULL, NULL, exp);
335
+ exp->fd_handler_set_up = true;
336
+
337
+ return 0;
338
+
339
+fail:
340
+ fuse_export_shutdown(&exp->common);
341
+ return ret;
342
+}
343
+
344
+/**
345
+ * Callback to be invoked when the FUSE session FD can be read from.
346
+ * (This is basically the FUSE event loop.)
347
+ */
348
+static void read_from_fuse_export(void *opaque)
349
+{
350
+ FuseExport *exp = opaque;
351
+ int ret;
352
+
353
+ blk_exp_ref(&exp->common);
354
+
355
+ do {
356
+ ret = fuse_session_receive_buf(exp->fuse_session, &exp->fuse_buf);
357
+ } while (ret == -EINTR);
358
+ if (ret < 0) {
359
+ goto out;
360
+ }
361
+
362
+ fuse_session_process_buf(exp->fuse_session, &exp->fuse_buf);
363
+
364
+out:
365
+ blk_exp_unref(&exp->common);
366
+}
367
+
368
+static void fuse_export_shutdown(BlockExport *blk_exp)
369
+{
370
+ FuseExport *exp = container_of(blk_exp, FuseExport, common);
371
+
372
+ if (exp->fuse_session) {
373
+ fuse_session_exit(exp->fuse_session);
374
+
375
+ if (exp->fd_handler_set_up) {
376
+ aio_set_fd_handler(exp->common.ctx,
377
+ fuse_session_fd(exp->fuse_session), true,
378
+ NULL, NULL, NULL, NULL);
379
+ exp->fd_handler_set_up = false;
380
+ }
381
+ }
382
+
383
+ if (exp->mountpoint) {
384
+ /*
385
+ * Safe to drop now, because we will not handle any requests
386
+ * for this export anymore anyway.
387
+ */
388
+ g_hash_table_remove(exports, exp->mountpoint);
389
+ }
390
+}
391
+
392
+static void fuse_export_delete(BlockExport *blk_exp)
393
+{
394
+ FuseExport *exp = container_of(blk_exp, FuseExport, common);
395
+
396
+ if (exp->fuse_session) {
397
+ if (exp->mounted) {
398
+ fuse_session_unmount(exp->fuse_session);
399
+ }
400
+
401
+ fuse_session_destroy(exp->fuse_session);
402
+ }
403
+
404
+ free(exp->fuse_buf.mem);
405
+ g_free(exp->mountpoint);
406
+}
407
+
408
+/**
409
+ * Check whether @path points to a regular file. If not, put an
410
+ * appropriate message into *errp.
411
+ */
412
+static bool is_regular_file(const char *path, Error **errp)
413
+{
414
+ struct stat statbuf;
415
+ int ret;
416
+
417
+ ret = stat(path, &statbuf);
418
+ if (ret < 0) {
419
+ error_setg_errno(errp, errno, "Failed to stat '%s'", path);
420
+ return false;
421
+ }
422
+
423
+ if (!S_ISREG(statbuf.st_mode)) {
424
+ error_setg(errp, "'%s' is not a regular file", path);
425
+ return false;
426
+ }
427
+
428
+ return true;
429
+}
430
+
431
+/**
432
+ * A chance to set change some parameters supplied to FUSE_INIT.
433
+ */
434
+static void fuse_init(void *userdata, struct fuse_conn_info *conn)
435
+{
436
+ /*
437
+ * MIN_NON_ZERO() would not be wrong here, but what we set here
438
+ * must equal what has been passed to fuse_session_new().
439
+ * Therefore, as long as max_read must be passed as a mount option
440
+ * (which libfuse claims will be changed at some point), we have
441
+ * to set max_read to a fixed value here.
442
+ */
443
+ conn->max_read = FUSE_MAX_BOUNCE_BYTES;
444
+
445
+ conn->max_write = MIN_NON_ZERO(BDRV_REQUEST_MAX_BYTES, conn->max_write);
446
+}
447
+
448
+static const struct fuse_lowlevel_ops fuse_ops = {
449
+ .init = fuse_init,
450
+};
451
+
452
+const BlockExportDriver blk_exp_fuse = {
453
+ .type = BLOCK_EXPORT_TYPE_FUSE,
454
+ .instance_size = sizeof(FuseExport),
455
+ .create = fuse_export_create,
456
+ .delete = fuse_export_delete,
457
+ .request_shutdown = fuse_export_shutdown,
458
+};
459
diff --git a/MAINTAINERS b/MAINTAINERS
460
index XXXXXXX..XXXXXXX 100644
461
--- a/MAINTAINERS
462
+++ b/MAINTAINERS
463
@@ -XXX,XX +XXX,XX @@ F: include/qemu/vhost-user-server.h
464
F: tests/qtest/libqos/vhost-user-blk.c
465
F: util/vhost-user-server.c
466
467
+FUSE block device exports
468
+M: Max Reitz <mreitz@redhat.com>
469
+L: qemu-block@nongnu.org
470
+S: Supported
471
+F: block/export/fuse.c
472
+
473
Replication
474
M: Wen Congyang <wencongyang2@huawei.com>
475
M: Xie Changlong <xiechanglong.d@gmail.com>
476
diff --git a/block/export/meson.build b/block/export/meson.build
477
index XXXXXXX..XXXXXXX 100644
478
--- a/block/export/meson.build
479
+++ b/block/export/meson.build
480
@@ -XXX,XX +XXX,XX @@ blockdev_ss.add(files('export.c'))
481
if have_vhost_user_blk_server
482
blockdev_ss.add(files('vhost-user-blk-server.c'))
483
endif
484
+
485
+blockdev_ss.add(when: fuse, if_true: files('fuse.c'))
40
--
486
--
41
2.19.1
487
2.29.2
42
488
43
489
diff view generated by jsdifflib
1
From: Leonid Bloch <lbloch@janustech.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
If an expression is used to define DEFAULT_CLUSTER_SIZE, when compiled,
3
This makes the export actually useful instead of only producing errors
4
it will be embedded as a literal expression in the binary (as the
4
whenever it is accessed.
5
default value) because it is stringified to mark the size of the default
5
6
value. Now this is fixed by using a defined number to define this value.
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
7
Message-Id: <20201027190600.192171-4-mreitz@redhat.com>
8
Signed-off-by: Leonid Bloch <lbloch@janustech.com>
9
Reviewed-by: Stefan Weil <sw@weilnetz.de>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
9
---
12
block/vdi.c | 4 ++--
10
block/export/fuse.c | 242 ++++++++++++++++++++++++++++++++++++++++++++
13
1 file changed, 2 insertions(+), 2 deletions(-)
11
1 file changed, 242 insertions(+)
14
12
15
diff --git a/block/vdi.c b/block/vdi.c
13
diff --git a/block/export/fuse.c b/block/export/fuse.c
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/block/vdi.c
15
--- a/block/export/fuse.c
18
+++ b/block/vdi.c
16
+++ b/block/export/fuse.c
19
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static void fuse_init(void *userdata, struct fuse_conn_info *conn)
20
#define BLOCK_OPT_STATIC "static"
18
conn->max_write = MIN_NON_ZERO(BDRV_REQUEST_MAX_BYTES, conn->max_write);
21
19
}
22
#define SECTOR_SIZE 512
20
23
-#define DEFAULT_CLUSTER_SIZE (1 * MiB)
21
+/**
24
+#define DEFAULT_CLUSTER_SIZE S_1MiB
22
+ * Let clients look up files. Always return ENOENT because we only
25
23
+ * care about the mountpoint itself.
26
#if defined(CONFIG_VDI_DEBUG)
24
+ */
27
#define VDI_DEBUG 1
25
+static void fuse_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
28
@@ -XXX,XX +XXX,XX @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
26
+{
29
goto fail;
27
+ fuse_reply_err(req, ENOENT);
30
} else if (header.block_size != DEFAULT_CLUSTER_SIZE) {
28
+}
31
error_setg(errp, "unsupported VDI image (block size %" PRIu32
29
+
32
- " is not %" PRIu64 ")",
30
+/**
33
+ " is not %" PRIu32 ")",
31
+ * Let clients get file attributes (i.e., stat() the file).
34
header.block_size, DEFAULT_CLUSTER_SIZE);
32
+ */
35
ret = -ENOTSUP;
33
+static void fuse_getattr(fuse_req_t req, fuse_ino_t inode,
36
goto fail;
34
+ struct fuse_file_info *fi)
35
+{
36
+ struct stat statbuf;
37
+ int64_t length, allocated_blocks;
38
+ time_t now = time(NULL);
39
+ FuseExport *exp = fuse_req_userdata(req);
40
+ mode_t mode;
41
+
42
+ length = blk_getlength(exp->common.blk);
43
+ if (length < 0) {
44
+ fuse_reply_err(req, -length);
45
+ return;
46
+ }
47
+
48
+ allocated_blocks = bdrv_get_allocated_file_size(blk_bs(exp->common.blk));
49
+ if (allocated_blocks <= 0) {
50
+ allocated_blocks = DIV_ROUND_UP(length, 512);
51
+ } else {
52
+ allocated_blocks = DIV_ROUND_UP(allocated_blocks, 512);
53
+ }
54
+
55
+ mode = S_IFREG | S_IRUSR;
56
+ if (exp->writable) {
57
+ mode |= S_IWUSR;
58
+ }
59
+
60
+ statbuf = (struct stat) {
61
+ .st_ino = inode,
62
+ .st_mode = mode,
63
+ .st_nlink = 1,
64
+ .st_uid = getuid(),
65
+ .st_gid = getgid(),
66
+ .st_size = length,
67
+ .st_blksize = blk_bs(exp->common.blk)->bl.request_alignment,
68
+ .st_blocks = allocated_blocks,
69
+ .st_atime = now,
70
+ .st_mtime = now,
71
+ .st_ctime = now,
72
+ };
73
+
74
+ fuse_reply_attr(req, &statbuf, 1.);
75
+}
76
+
77
+static int fuse_do_truncate(const FuseExport *exp, int64_t size,
78
+ bool req_zero_write, PreallocMode prealloc)
79
+{
80
+ uint64_t blk_perm, blk_shared_perm;
81
+ BdrvRequestFlags truncate_flags = 0;
82
+ int ret;
83
+
84
+ if (req_zero_write) {
85
+ truncate_flags |= BDRV_REQ_ZERO_WRITE;
86
+ }
87
+
88
+ blk_get_perm(exp->common.blk, &blk_perm, &blk_shared_perm);
89
+
90
+ ret = blk_set_perm(exp->common.blk, blk_perm | BLK_PERM_RESIZE,
91
+ blk_shared_perm, NULL);
92
+ if (ret < 0) {
93
+ return ret;
94
+ }
95
+
96
+ ret = blk_truncate(exp->common.blk, size, true, prealloc,
97
+ truncate_flags, NULL);
98
+
99
+ /* Must succeed, because we are only giving up the RESIZE permission */
100
+ blk_set_perm(exp->common.blk, blk_perm, blk_shared_perm, &error_abort);
101
+
102
+ return ret;
103
+}
104
+
105
+/**
106
+ * Let clients set file attributes. Only resizing is supported.
107
+ */
108
+static void fuse_setattr(fuse_req_t req, fuse_ino_t inode, struct stat *statbuf,
109
+ int to_set, struct fuse_file_info *fi)
110
+{
111
+ FuseExport *exp = fuse_req_userdata(req);
112
+ int ret;
113
+
114
+ if (!exp->writable) {
115
+ fuse_reply_err(req, EACCES);
116
+ return;
117
+ }
118
+
119
+ if (to_set & ~FUSE_SET_ATTR_SIZE) {
120
+ fuse_reply_err(req, ENOTSUP);
121
+ return;
122
+ }
123
+
124
+ ret = fuse_do_truncate(exp, statbuf->st_size, true, PREALLOC_MODE_OFF);
125
+ if (ret < 0) {
126
+ fuse_reply_err(req, -ret);
127
+ return;
128
+ }
129
+
130
+ fuse_getattr(req, inode, fi);
131
+}
132
+
133
+/**
134
+ * Let clients open a file (i.e., the exported image).
135
+ */
136
+static void fuse_open(fuse_req_t req, fuse_ino_t inode,
137
+ struct fuse_file_info *fi)
138
+{
139
+ fuse_reply_open(req, fi);
140
+}
141
+
142
+/**
143
+ * Handle client reads from the exported image.
144
+ */
145
+static void fuse_read(fuse_req_t req, fuse_ino_t inode,
146
+ size_t size, off_t offset, struct fuse_file_info *fi)
147
+{
148
+ FuseExport *exp = fuse_req_userdata(req);
149
+ int64_t length;
150
+ void *buf;
151
+ int ret;
152
+
153
+ /* Limited by max_read, should not happen */
154
+ if (size > FUSE_MAX_BOUNCE_BYTES) {
155
+ fuse_reply_err(req, EINVAL);
156
+ return;
157
+ }
158
+
159
+ /**
160
+ * Clients will expect short reads at EOF, so we have to limit
161
+ * offset+size to the image length.
162
+ */
163
+ length = blk_getlength(exp->common.blk);
164
+ if (length < 0) {
165
+ fuse_reply_err(req, -length);
166
+ return;
167
+ }
168
+
169
+ if (offset + size > length) {
170
+ size = length - offset;
171
+ }
172
+
173
+ buf = qemu_try_blockalign(blk_bs(exp->common.blk), size);
174
+ if (!buf) {
175
+ fuse_reply_err(req, ENOMEM);
176
+ return;
177
+ }
178
+
179
+ ret = blk_pread(exp->common.blk, offset, buf, size);
180
+ if (ret >= 0) {
181
+ fuse_reply_buf(req, buf, size);
182
+ } else {
183
+ fuse_reply_err(req, -ret);
184
+ }
185
+
186
+ qemu_vfree(buf);
187
+}
188
+
189
+/**
190
+ * Handle client writes to the exported image.
191
+ */
192
+static void fuse_write(fuse_req_t req, fuse_ino_t inode, const char *buf,
193
+ size_t size, off_t offset, struct fuse_file_info *fi)
194
+{
195
+ FuseExport *exp = fuse_req_userdata(req);
196
+ int64_t length;
197
+ int ret;
198
+
199
+ /* Limited by max_write, should not happen */
200
+ if (size > BDRV_REQUEST_MAX_BYTES) {
201
+ fuse_reply_err(req, EINVAL);
202
+ return;
203
+ }
204
+
205
+ if (!exp->writable) {
206
+ fuse_reply_err(req, EACCES);
207
+ return;
208
+ }
209
+
210
+ /**
211
+ * Clients will expect short writes at EOF, so we have to limit
212
+ * offset+size to the image length.
213
+ */
214
+ length = blk_getlength(exp->common.blk);
215
+ if (length < 0) {
216
+ fuse_reply_err(req, -length);
217
+ return;
218
+ }
219
+
220
+ if (offset + size > length) {
221
+ size = length - offset;
222
+ }
223
+
224
+ ret = blk_pwrite(exp->common.blk, offset, buf, size, 0);
225
+ if (ret >= 0) {
226
+ fuse_reply_write(req, size);
227
+ } else {
228
+ fuse_reply_err(req, -ret);
229
+ }
230
+}
231
+
232
+/**
233
+ * Let clients fsync the exported image.
234
+ */
235
+static void fuse_fsync(fuse_req_t req, fuse_ino_t inode, int datasync,
236
+ struct fuse_file_info *fi)
237
+{
238
+ FuseExport *exp = fuse_req_userdata(req);
239
+ int ret;
240
+
241
+ ret = blk_flush(exp->common.blk);
242
+ fuse_reply_err(req, ret < 0 ? -ret : 0);
243
+}
244
+
245
+/**
246
+ * Called before an FD to the exported image is closed. (libfuse
247
+ * notes this to be a way to return last-minute errors.)
248
+ */
249
+static void fuse_flush(fuse_req_t req, fuse_ino_t inode,
250
+ struct fuse_file_info *fi)
251
+{
252
+ fuse_fsync(req, inode, 1, fi);
253
+}
254
+
255
static const struct fuse_lowlevel_ops fuse_ops = {
256
.init = fuse_init,
257
+ .lookup = fuse_lookup,
258
+ .getattr = fuse_getattr,
259
+ .setattr = fuse_setattr,
260
+ .open = fuse_open,
261
+ .read = fuse_read,
262
+ .write = fuse_write,
263
+ .flush = fuse_flush,
264
+ .fsync = fuse_fsync,
265
};
266
267
const BlockExportDriver blk_exp_fuse = {
37
--
268
--
38
2.19.1
269
2.29.2
39
270
40
271
diff view generated by jsdifflib
1
If read-only=off, but auto-read-only=on is given, open a read-write NBD
1
From: Max Reitz <mreitz@redhat.com>
2
connection if the server provides a read-write export, but instead of
3
erroring out for read-only exports, just degrade to read-only.
4
2
3
These will behave more like normal files in that writes beyond the EOF
4
will automatically grow the export size.
5
6
As an optimization, keep the RESIZE permission for growable exports so
7
we do not have to take it for every post-EOF write. (This permission is
8
not released when the export is destroyed, because at that point the
9
BlockBackend is destroyed altogether anyway.)
10
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
Message-Id: <20201027190600.192171-5-mreitz@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
7
---
14
---
8
block/nbd-client.c | 10 +++++-----
15
qapi/block-export.json | 6 +++++-
9
1 file changed, 5 insertions(+), 5 deletions(-)
16
block/export/fuse.c | 44 ++++++++++++++++++++++++++++++++++--------
17
2 files changed, 41 insertions(+), 9 deletions(-)
10
18
11
diff --git a/block/nbd-client.c b/block/nbd-client.c
19
diff --git a/qapi/block-export.json b/qapi/block-export.json
12
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
13
--- a/block/nbd-client.c
21
--- a/qapi/block-export.json
14
+++ b/block/nbd-client.c
22
+++ b/qapi/block-export.json
15
@@ -XXX,XX +XXX,XX @@ int nbd_client_init(BlockDriverState *bs,
23
@@ -XXX,XX +XXX,XX @@
16
logout("Failed to negotiate with the NBD server\n");
24
# @mountpoint: Path on which to export the block device via FUSE.
17
return ret;
25
# This must point to an existing regular file.
26
#
27
+# @growable: Whether writes beyond the EOF should grow the block node
28
+# accordingly. (default: false)
29
+#
30
# Since: 6.0
31
##
32
{ 'struct': 'BlockExportOptionsFuse',
33
- 'data': { 'mountpoint': 'str' },
34
+ 'data': { 'mountpoint': 'str',
35
+ '*growable': 'bool' },
36
'if': 'defined(CONFIG_FUSE)' }
37
38
##
39
diff --git a/block/export/fuse.c b/block/export/fuse.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/block/export/fuse.c
42
+++ b/block/export/fuse.c
43
@@ -XXX,XX +XXX,XX @@ typedef struct FuseExport {
44
45
char *mountpoint;
46
bool writable;
47
+ bool growable;
48
} FuseExport;
49
50
static GHashTable *exports;
51
@@ -XXX,XX +XXX,XX @@ static int fuse_export_create(BlockExport *blk_exp,
52
53
assert(blk_exp_args->type == BLOCK_EXPORT_TYPE_FUSE);
54
55
+ /* For growable exports, take the RESIZE permission */
56
+ if (args->growable) {
57
+ uint64_t blk_perm, blk_shared_perm;
58
+
59
+ blk_get_perm(exp->common.blk, &blk_perm, &blk_shared_perm);
60
+
61
+ ret = blk_set_perm(exp->common.blk, blk_perm | BLK_PERM_RESIZE,
62
+ blk_shared_perm, errp);
63
+ if (ret < 0) {
64
+ return ret;
65
+ }
66
+ }
67
+
68
init_exports_table();
69
70
/*
71
@@ -XXX,XX +XXX,XX @@ static int fuse_export_create(BlockExport *blk_exp,
72
73
exp->mountpoint = g_strdup(args->mountpoint);
74
exp->writable = blk_exp_args->writable;
75
+ exp->growable = args->growable;
76
77
ret = setup_fuse_export(exp, args->mountpoint, errp);
78
if (ret < 0) {
79
@@ -XXX,XX +XXX,XX @@ static int fuse_do_truncate(const FuseExport *exp, int64_t size,
80
truncate_flags |= BDRV_REQ_ZERO_WRITE;
18
}
81
}
19
- if (client->info.flags & NBD_FLAG_READ_ONLY &&
82
20
- !bdrv_is_read_only(bs)) {
83
- blk_get_perm(exp->common.blk, &blk_perm, &blk_shared_perm);
21
- error_setg(errp,
84
+ /* Growable exports have a permanent RESIZE permission */
22
- "request for write access conflicts with read-only export");
85
+ if (!exp->growable) {
23
- return -EACCES;
86
+ blk_get_perm(exp->common.blk, &blk_perm, &blk_shared_perm);
24
+ if (client->info.flags & NBD_FLAG_READ_ONLY) {
87
25
+ ret = bdrv_apply_auto_read_only(bs, "NBD export is read-only", errp);
88
- ret = blk_set_perm(exp->common.blk, blk_perm | BLK_PERM_RESIZE,
89
- blk_shared_perm, NULL);
90
- if (ret < 0) {
91
- return ret;
92
+ ret = blk_set_perm(exp->common.blk, blk_perm | BLK_PERM_RESIZE,
93
+ blk_shared_perm, NULL);
26
+ if (ret < 0) {
94
+ if (ret < 0) {
27
+ return ret;
95
+ return ret;
28
+ }
96
+ }
29
}
97
}
30
if (client->info.flags & NBD_FLAG_SEND_FUA) {
98
31
bs->supported_write_flags = BDRV_REQ_FUA;
99
ret = blk_truncate(exp->common.blk, size, true, prealloc,
100
truncate_flags, NULL);
101
102
- /* Must succeed, because we are only giving up the RESIZE permission */
103
- blk_set_perm(exp->common.blk, blk_perm, blk_shared_perm, &error_abort);
104
+ if (!exp->growable) {
105
+ /* Must succeed, because we are only giving up the RESIZE permission */
106
+ blk_set_perm(exp->common.blk, blk_perm, blk_shared_perm, &error_abort);
107
+ }
108
109
return ret;
110
}
111
@@ -XXX,XX +XXX,XX @@ static void fuse_write(fuse_req_t req, fuse_ino_t inode, const char *buf,
112
}
113
114
if (offset + size > length) {
115
- size = length - offset;
116
+ if (exp->growable) {
117
+ ret = fuse_do_truncate(exp, offset + size, true, PREALLOC_MODE_OFF);
118
+ if (ret < 0) {
119
+ fuse_reply_err(req, -ret);
120
+ return;
121
+ }
122
+ } else {
123
+ size = length - offset;
124
+ }
125
}
126
127
ret = blk_pwrite(exp->common.blk, offset, buf, size, 0);
32
--
128
--
33
2.19.1
129
2.29.2
34
130
35
131
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
This patch tests that you can add and remove drives from a Quorum
3
This allows allocating areas after the (old) EOF as part of a growing
4
using the x-blockdev-change command.
4
resize, writing zeroes, and discarding.
5
5
6
Signed-off-by: Alberto Garcia <berto@igalia.com>
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Message-Id: <20201027190600.192171-6-mreitz@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
---
9
tests/qemu-iotests/081 | 86 ++++++++++++++++++++++++++++++++++++++
10
block/export/fuse.c | 84 +++++++++++++++++++++++++++++++++++++++++++++
10
tests/qemu-iotests/081.out | 54 ++++++++++++++++++++++++
11
1 file changed, 84 insertions(+)
11
2 files changed, 140 insertions(+)
12
12
13
diff --git a/tests/qemu-iotests/081 b/tests/qemu-iotests/081
13
diff --git a/block/export/fuse.c b/block/export/fuse.c
14
index XXXXXXX..XXXXXXX 100755
14
index XXXXXXX..XXXXXXX 100644
15
--- a/tests/qemu-iotests/081
15
--- a/block/export/fuse.c
16
+++ b/tests/qemu-iotests/081
16
+++ b/block/export/fuse.c
17
@@ -XXX,XX +XXX,XX @@ quorum="$quorum,file.children.2.driver=raw"
17
@@ -XXX,XX +XXX,XX @@ static void fuse_write(fuse_req_t req, fuse_ino_t inode, const char *buf,
18
18
}
19
$QEMU_IO -c "open -o $quorum" | _filter_qemu_io
19
}
20
20
21
+echo
21
+/**
22
+echo "== dynamically adding a child to a quorum =="
22
+ * Let clients perform various fallocate() operations.
23
+ */
24
+static void fuse_fallocate(fuse_req_t req, fuse_ino_t inode, int mode,
25
+ off_t offset, off_t length,
26
+ struct fuse_file_info *fi)
27
+{
28
+ FuseExport *exp = fuse_req_userdata(req);
29
+ int64_t blk_len;
30
+ int ret;
23
+
31
+
24
+for verify in false true; do
32
+ if (!exp->writable) {
25
+ run_qemu <<EOF
33
+ fuse_reply_err(req, EACCES);
26
+ { "execute": "qmp_capabilities" }
34
+ return;
27
+ { "execute": "blockdev-add",
35
+ }
28
+ "arguments": {
36
+
29
+ "driver": "quorum",
37
+ blk_len = blk_getlength(exp->common.blk);
30
+ "node-name": "drive0-quorum",
38
+ if (blk_len < 0) {
31
+ "vote-threshold": 2,
39
+ fuse_reply_err(req, -blk_len);
32
+ "blkverify": ${verify},
40
+ return;
33
+ "children": [
41
+ }
34
+ {
42
+
35
+ "driver": "$IMGFMT",
43
+ if (mode & FALLOC_FL_KEEP_SIZE) {
36
+ "file": {
44
+ length = MIN(length, blk_len - offset);
37
+ "driver": "file",
45
+ }
38
+ "filename": "$TEST_DIR/1.raw"
46
+
39
+ }
47
+ if (mode & FALLOC_FL_PUNCH_HOLE) {
40
+ },
48
+ if (!(mode & FALLOC_FL_KEEP_SIZE)) {
41
+ {
49
+ fuse_reply_err(req, EINVAL);
42
+ "driver": "$IMGFMT",
50
+ return;
43
+ "file": {
44
+ "driver": "file",
45
+ "filename": "$TEST_DIR/2.raw"
46
+ }
47
+ }
48
+ ]
49
+ }
51
+ }
50
+ }
52
+
51
+ { "execute": "blockdev-add",
53
+ do {
52
+ "arguments": {
54
+ int size = MIN(length, BDRV_REQUEST_MAX_BYTES);
53
+ "node-name": "drive3",
55
+
54
+ "driver": "$IMGFMT",
56
+ ret = blk_pdiscard(exp->common.blk, offset, size);
55
+ "file": {
57
+ offset += size;
56
+ "driver": "file",
58
+ length -= size;
57
+ "filename": "$TEST_DIR/2.raw"
59
+ } while (ret == 0 && length > 0);
60
+ } else if (mode & FALLOC_FL_ZERO_RANGE) {
61
+ if (!(mode & FALLOC_FL_KEEP_SIZE) && offset + length > blk_len) {
62
+ /* No need for zeroes, we are going to write them ourselves */
63
+ ret = fuse_do_truncate(exp, offset + length, false,
64
+ PREALLOC_MODE_OFF);
65
+ if (ret < 0) {
66
+ fuse_reply_err(req, -ret);
67
+ return;
58
+ }
68
+ }
59
+ }
69
+ }
60
+ }
61
+ { "execute": "x-blockdev-change",
62
+ "arguments": { "parent": "drive0-quorum",
63
+ "node": "drive3" } }
64
+ { "execute": "quit" }
65
+EOF
66
+done
67
+
70
+
68
+echo
71
+ do {
69
+echo "== dynamically removing a child from a quorum =="
72
+ int size = MIN(length, BDRV_REQUEST_MAX_BYTES);
70
+
73
+
71
+for verify in false true; do
74
+ ret = blk_pwrite_zeroes(exp->common.blk,
72
+ for vote_threshold in 1 2; do
75
+ offset, size, 0);
73
+ run_qemu <<EOF
76
+ offset += size;
74
+ { "execute": "qmp_capabilities" }
77
+ length -= size;
75
+ { "execute": "blockdev-add",
78
+ } while (ret == 0 && length > 0);
76
+ "arguments": {
79
+ } else if (!mode) {
77
+ "driver": "quorum",
80
+ /* We can only fallocate at the EOF with a truncate */
78
+ "node-name": "drive0-quorum",
81
+ if (offset < blk_len) {
79
+ "vote-threshold": ${vote_threshold},
82
+ fuse_reply_err(req, EOPNOTSUPP);
80
+ "blkverify": ${verify},
83
+ return;
81
+ "children": [
84
+ }
82
+ {
85
+
83
+ "driver": "$IMGFMT",
86
+ if (offset > blk_len) {
84
+ "file": {
87
+ /* No preallocation needed here */
85
+ "driver": "file",
88
+ ret = fuse_do_truncate(exp, offset, true, PREALLOC_MODE_OFF);
86
+ "filename": "$TEST_DIR/1.raw"
89
+ if (ret < 0) {
87
+ }
90
+ fuse_reply_err(req, -ret);
88
+ },
91
+ return;
89
+ {
90
+ "driver": "$IMGFMT",
91
+ "file": {
92
+ "driver": "file",
93
+ "filename": "$TEST_DIR/2.raw"
94
+ }
95
+ }
96
+ ]
97
+ }
92
+ }
98
+ }
93
+ }
99
+ { "execute": "x-blockdev-change",
100
+ "arguments": { "parent": "drive0-quorum",
101
+ "child": "children.1" } }
102
+ { "execute": "quit" }
103
+EOF
104
+ done
105
+done
106
+
94
+
107
# success, all done
95
+ ret = fuse_do_truncate(exp, offset + length, true,
108
echo "*** done"
96
+ PREALLOC_MODE_FALLOC);
109
rm -f $seq.full
97
+ } else {
110
diff --git a/tests/qemu-iotests/081.out b/tests/qemu-iotests/081.out
98
+ ret = -EOPNOTSUPP;
111
index XXXXXXX..XXXXXXX 100644
99
+ }
112
--- a/tests/qemu-iotests/081.out
113
+++ b/tests/qemu-iotests/081.out
114
@@ -XXX,XX +XXX,XX @@ read 10485760/10485760 bytes at offset 0
115
116
== checking the blkverify mode with invalid settings ==
117
can't open: blkverify=on can only be set if there are exactly two files and vote-threshold is 2
118
+
100
+
119
+== dynamically adding a child to a quorum ==
101
+ fuse_reply_err(req, ret < 0 ? -ret : 0);
120
+Testing:
102
+}
121
+QMP_VERSION
122
+{"return": {}}
123
+{"return": {}}
124
+{"return": {}}
125
+{"return": {}}
126
+{"return": {}}
127
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
128
+
103
+
129
+Testing:
104
/**
130
+QMP_VERSION
105
* Let clients fsync the exported image.
131
+{"return": {}}
106
*/
132
+{"return": {}}
107
@@ -XXX,XX +XXX,XX @@ static const struct fuse_lowlevel_ops fuse_ops = {
133
+{"return": {}}
108
.open = fuse_open,
134
+{"error": {"class": "GenericError", "desc": "Cannot add a child to a quorum in blkverify mode"}}
109
.read = fuse_read,
135
+{"return": {}}
110
.write = fuse_write,
136
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
111
+ .fallocate = fuse_fallocate,
137
+
112
.flush = fuse_flush,
138
+
113
.fsync = fuse_fsync,
139
+== dynamically removing a child from a quorum ==
114
};
140
+Testing:
141
+QMP_VERSION
142
+{"return": {}}
143
+{"return": {}}
144
+{"return": {}}
145
+{"return": {}}
146
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
147
+
148
+Testing:
149
+QMP_VERSION
150
+{"return": {}}
151
+{"return": {}}
152
+{"error": {"class": "GenericError", "desc": "The number of children cannot be lower than the vote threshold 2"}}
153
+{"return": {}}
154
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
155
+
156
+Testing:
157
+QMP_VERSION
158
+{"return": {}}
159
+{"error": {"class": "GenericError", "desc": "blkverify=on can only be set if there are exactly two files and vote-threshold is 2"}}
160
+{"error": {"class": "GenericError", "desc": "Cannot find device=drive0-quorum nor node_name=drive0-quorum"}}
161
+{"return": {}}
162
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
163
+
164
+Testing:
165
+QMP_VERSION
166
+{"return": {}}
167
+{"return": {}}
168
+{"error": {"class": "GenericError", "desc": "The number of children cannot be lower than the vote threshold 2"}}
169
+{"return": {}}
170
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
171
+
172
*** done
173
--
115
--
174
2.19.1
116
2.29.2
175
117
176
118
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
The blkverify mode of Quorum only works when the number of children is
3
This is a relatively new feature in libfuse (available since 3.8.0,
4
exactly two, so any attempt to add a new one must return an error.
4
which was released in November 2019), so we have to add a dedicated
5
5
check whether it is available before making use of it.
6
quorum_del_child() on the other hand doesn't need any additional check
6
7
because decreasing the number of children would make it go under the
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
vote threshold.
8
Message-Id: <20201027190600.192171-7-mreitz@redhat.com>
9
10
Signed-off-by: Alberto Garcia <berto@igalia.com>
11
Reported-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
10
---
14
block/quorum.c | 8 ++++++++
11
meson_options.txt | 2 ++
15
1 file changed, 8 insertions(+)
12
configure | 8 ++++-
16
13
block/export/fuse.c | 77 +++++++++++++++++++++++++++++++++++++++++++++
17
diff --git a/block/quorum.c b/block/quorum.c
14
meson.build | 20 ++++++++++++
15
4 files changed, 106 insertions(+), 1 deletion(-)
16
17
diff --git a/meson_options.txt b/meson_options.txt
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block/quorum.c
19
--- a/meson_options.txt
20
+++ b/block/quorum.c
20
+++ b/meson_options.txt
21
@@ -XXX,XX +XXX,XX @@ static void quorum_add_child(BlockDriverState *bs, BlockDriverState *child_bs,
21
@@ -XXX,XX +XXX,XX @@ option('vhost_user_blk_server', type: 'feature', value: 'auto',
22
char indexstr[32];
22
description: 'build vhost-user-blk server')
23
int ret;
23
option('fuse', type: 'feature', value: 'auto',
24
24
description: 'FUSE block device export')
25
+ if (s->is_blkverify) {
25
+option('fuse_lseek', type : 'feature', value : 'auto',
26
+ error_setg(errp, "Cannot add a child to a quorum in blkverify mode");
26
+ description: 'SEEK_HOLE/SEEK_DATA support for FUSE exports')
27
28
option('capstone', type: 'combo', value: 'auto',
29
choices: ['disabled', 'enabled', 'auto', 'system', 'internal'],
30
diff --git a/configure b/configure
31
index XXXXXXX..XXXXXXX 100755
32
--- a/configure
33
+++ b/configure
34
@@ -XXX,XX +XXX,XX @@ ninja=""
35
skip_meson=no
36
gettext=""
37
fuse="auto"
38
+fuse_lseek="auto"
39
40
bogus_os="no"
41
malloc_trim="auto"
42
@@ -XXX,XX +XXX,XX @@ for opt do
43
;;
44
--disable-fuse) fuse="disabled"
45
;;
46
+ --enable-fuse-lseek) fuse_lseek="enabled"
47
+ ;;
48
+ --disable-fuse-lseek) fuse_lseek="disabled"
49
+ ;;
50
*)
51
echo "ERROR: unknown option $opt"
52
echo "Try '$0 --help' for more information"
53
@@ -XXX,XX +XXX,XX @@ disabled with --disable-FEATURE, default is enabled if available:
54
rng-none dummy RNG, avoid using /dev/(u)random and getrandom()
55
libdaxctl libdaxctl support
56
fuse FUSE block device export
57
+ fuse-lseek SEEK_HOLE/SEEK_DATA support for FUSE exports
58
59
NOTE: The object files are built at the place where configure is launched
60
EOF
61
@@ -XXX,XX +XXX,XX @@ NINJA=$ninja $meson setup \
62
-Diconv=$iconv -Dcurses=$curses -Dlibudev=$libudev\
63
-Ddocs=$docs -Dsphinx_build=$sphinx_build -Dinstall_blobs=$blobs \
64
-Dvhost_user_blk_server=$vhost_user_blk_server \
65
- -Dfuse=$fuse \
66
+ -Dfuse=$fuse -Dfuse_lseek=$fuse_lseek \
67
$cross_arg \
68
"$PWD" "$source_path"
69
70
diff --git a/block/export/fuse.c b/block/export/fuse.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/block/export/fuse.c
73
+++ b/block/export/fuse.c
74
@@ -XXX,XX +XXX,XX @@ static void fuse_flush(fuse_req_t req, fuse_ino_t inode,
75
fuse_fsync(req, inode, 1, fi);
76
}
77
78
+#ifdef CONFIG_FUSE_LSEEK
79
+/**
80
+ * Let clients inquire allocation status.
81
+ */
82
+static void fuse_lseek(fuse_req_t req, fuse_ino_t inode, off_t offset,
83
+ int whence, struct fuse_file_info *fi)
84
+{
85
+ FuseExport *exp = fuse_req_userdata(req);
86
+
87
+ if (whence != SEEK_HOLE && whence != SEEK_DATA) {
88
+ fuse_reply_err(req, EINVAL);
27
+ return;
89
+ return;
28
+ }
90
+ }
29
+
91
+
30
assert(s->num_children <= INT_MAX / sizeof(BdrvChild *));
92
+ while (true) {
31
if (s->num_children == INT_MAX / sizeof(BdrvChild *) ||
93
+ int64_t pnum;
32
s->next_child_index == UINT_MAX) {
94
+ int ret;
33
@@ -XXX,XX +XXX,XX @@ static void quorum_del_child(BlockDriverState *bs, BdrvChild *child,
95
+
34
return;
96
+ ret = bdrv_block_status_above(blk_bs(exp->common.blk), NULL,
35
}
97
+ offset, INT64_MAX, &pnum, NULL, NULL);
36
98
+ if (ret < 0) {
37
+ /* We know now that num_children > threshold, so blkverify must be false */
99
+ fuse_reply_err(req, -ret);
38
+ assert(!s->is_blkverify);
100
+ return;
39
+
101
+ }
40
bdrv_drained_begin(bs);
102
+
41
103
+ if (!pnum && (ret & BDRV_BLOCK_EOF)) {
42
/* We can safely remove this child now */
104
+ int64_t blk_len;
105
+
106
+ /*
107
+ * If blk_getlength() rounds (e.g. by sectors), then the
108
+ * export length will be rounded, too. However,
109
+ * bdrv_block_status_above() may return EOF at unaligned
110
+ * offsets. We must not let this become visible and thus
111
+ * always simulate a hole between @offset (the real EOF)
112
+ * and @blk_len (the client-visible EOF).
113
+ */
114
+
115
+ blk_len = blk_getlength(exp->common.blk);
116
+ if (blk_len < 0) {
117
+ fuse_reply_err(req, -blk_len);
118
+ return;
119
+ }
120
+
121
+ if (offset > blk_len || whence == SEEK_DATA) {
122
+ fuse_reply_err(req, ENXIO);
123
+ } else {
124
+ fuse_reply_lseek(req, offset);
125
+ }
126
+ return;
127
+ }
128
+
129
+ if (ret & BDRV_BLOCK_DATA) {
130
+ if (whence == SEEK_DATA) {
131
+ fuse_reply_lseek(req, offset);
132
+ return;
133
+ }
134
+ } else {
135
+ if (whence == SEEK_HOLE) {
136
+ fuse_reply_lseek(req, offset);
137
+ return;
138
+ }
139
+ }
140
+
141
+ /* Safety check against infinite loops */
142
+ if (!pnum) {
143
+ fuse_reply_err(req, ENXIO);
144
+ return;
145
+ }
146
+
147
+ offset += pnum;
148
+ }
149
+}
150
+#endif
151
+
152
static const struct fuse_lowlevel_ops fuse_ops = {
153
.init = fuse_init,
154
.lookup = fuse_lookup,
155
@@ -XXX,XX +XXX,XX @@ static const struct fuse_lowlevel_ops fuse_ops = {
156
.fallocate = fuse_fallocate,
157
.flush = fuse_flush,
158
.fsync = fuse_fsync,
159
+#ifdef CONFIG_FUSE_LSEEK
160
+ .lseek = fuse_lseek,
161
+#endif
162
};
163
164
const BlockExportDriver blk_exp_fuse = {
165
diff --git a/meson.build b/meson.build
166
index XXXXXXX..XXXXXXX 100644
167
--- a/meson.build
168
+++ b/meson.build
169
@@ -XXX,XX +XXX,XX @@ elif get_option('vhost_user_blk_server').disabled() or not have_system
170
have_vhost_user_blk_server = false
171
endif
172
173
+if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
174
+ error('Cannot enable fuse-lseek while fuse is disabled')
175
+endif
176
+
177
fuse = dependency('fuse3', required: get_option('fuse'),
178
version: '>=3.1', method: 'pkg-config',
179
static: enable_static)
180
181
+fuse_lseek = not_found
182
+if not get_option('fuse_lseek').disabled()
183
+ if fuse.version().version_compare('>=3.8')
184
+ # Dummy dependency
185
+ fuse_lseek = declare_dependency()
186
+ elif get_option('fuse_lseek').enabled()
187
+ if fuse.found()
188
+ error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
189
+ else
190
+ error('fuse-lseek requires libfuse, which was not found')
191
+ endif
192
+ endif
193
+endif
194
+
195
#################
196
# config-host.h #
197
#################
198
@@ -XXX,XX +XXX,XX @@ config_host_data.set('CONFIG_GETTID', has_gettid)
199
config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
200
config_host_data.set('CONFIG_STATX', has_statx)
201
config_host_data.set('CONFIG_FUSE', fuse.found())
202
+config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
203
config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
204
config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
205
config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
206
@@ -XXX,XX +XXX,XX @@ summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
207
summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')}
208
summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
209
summary_info += {'FUSE exports': fuse.found()}
210
+summary_info += {'FUSE lseek': fuse_lseek.found()}
211
summary(summary_info, bool_yn: true)
212
213
if not supported_cpus.contains(cpu)
43
--
214
--
44
2.19.1
215
2.29.2
45
216
46
217
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
The blkverify mode of Quorum can only be enabled if the number of
3
In most cases, _make_test_img does not need a _filter_imgfmt on top. It
4
children is exactly two and the value of vote-threshold is also two.
4
does that by itself.
5
5
6
If the user tries to enable it but the other settings are incorrect
6
(The exception is when IMGFMT has been overwritten but TEST_IMG has not.
7
then QEMU simply prints an error message to stderr and carries on
7
In such cases, we do need a _filter_imgfmt on top to filter the test's
8
disabling the blkverify setting.
8
original IMGFMT from TEST_IMG.)
9
9
10
This patch makes quorum_open() fail and return an error in this case.
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
11
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Alberto Garcia <berto@igalia.com>
12
Message-Id: <20201027190600.192171-8-mreitz@redhat.com>
13
Reported-by: Markus Armbruster <armbru@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
14
---
16
block/quorum.c | 13 ++++++-------
15
tests/qemu-iotests/161 | 12 ++++++------
17
1 file changed, 6 insertions(+), 7 deletions(-)
16
tests/qemu-iotests/175 | 6 +++---
17
tests/qemu-iotests/249 | 6 +++---
18
3 files changed, 12 insertions(+), 12 deletions(-)
18
19
19
diff --git a/block/quorum.c b/block/quorum.c
20
diff --git a/tests/qemu-iotests/161 b/tests/qemu-iotests/161
20
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100755
21
--- a/block/quorum.c
22
--- a/tests/qemu-iotests/161
22
+++ b/block/quorum.c
23
+++ b/tests/qemu-iotests/161
23
@@ -XXX,XX +XXX,XX @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags,
24
@@ -XXX,XX +XXX,XX @@ _supported_os Linux
24
s->read_pattern = ret;
25
IMG_SIZE=1M
25
26
26
if (s->read_pattern == QUORUM_READ_PATTERN_QUORUM) {
27
# Create the images
27
- /* is the driver in blkverify mode */
28
-TEST_IMG="$TEST_IMG.base" _make_test_img $IMG_SIZE | _filter_imgfmt
28
- if (qemu_opt_get_bool(opts, QUORUM_OPT_BLKVERIFY, false) &&
29
-TEST_IMG="$TEST_IMG.int" _make_test_img -b "$TEST_IMG.base" -F $IMGFMT | _filter_imgfmt
29
- s->num_children == 2 && s->threshold == 2) {
30
-_make_test_img -b "$TEST_IMG.int" -F $IMGFMT -F $IMGFMT | _filter_imgfmt
30
- s->is_blkverify = true;
31
+TEST_IMG="$TEST_IMG.base" _make_test_img $IMG_SIZE
31
- } else if (qemu_opt_get_bool(opts, QUORUM_OPT_BLKVERIFY, false)) {
32
+TEST_IMG="$TEST_IMG.int" _make_test_img -b "$TEST_IMG.base" -F $IMGFMT
32
- fprintf(stderr, "blkverify mode is set by setting blkverify=on "
33
+_make_test_img -b "$TEST_IMG.int" -F $IMGFMT -F $IMGFMT
33
- "and using two files with vote_threshold=2\n");
34
34
+ s->is_blkverify = qemu_opt_get_bool(opts, QUORUM_OPT_BLKVERIFY, false);
35
# First test: reopen $TEST.IMG changing the detect-zeroes option on
35
+ if (s->is_blkverify && (s->num_children != 2 || s->threshold != 2)) {
36
# its backing file ($TEST_IMG.int).
36
+ error_setg(&local_err, "blkverify=on can only be set if there are "
37
@@ -XXX,XX +XXX,XX @@ echo
37
+ "exactly two files and vote-threshold is 2");
38
echo "*** Commit and then change an option on the backing file"
38
+ ret = -EINVAL;
39
echo
39
+ goto exit;
40
# Create the images again
40
}
41
-TEST_IMG="$TEST_IMG.base" _make_test_img $IMG_SIZE | _filter_imgfmt
41
42
-TEST_IMG="$TEST_IMG.int" _make_test_img -b "$TEST_IMG.base" -F $IMGFMT| _filter_imgfmt
42
s->rewrite_corrupted = qemu_opt_get_bool(opts, QUORUM_OPT_REWRITE,
43
-_make_test_img -b "$TEST_IMG.int" -F $IMGFMT | _filter_imgfmt
44
+TEST_IMG="$TEST_IMG.base" _make_test_img $IMG_SIZE
45
+TEST_IMG="$TEST_IMG.int" _make_test_img -b "$TEST_IMG.base" -F $IMGFMT
46
+_make_test_img -b "$TEST_IMG.int" -F $IMGFMT
47
48
_launch_qemu -drive if=none,file="${TEST_IMG}"
49
_send_qemu_cmd $QEMU_HANDLE \
50
diff --git a/tests/qemu-iotests/175 b/tests/qemu-iotests/175
51
index XXXXXXX..XXXXXXX 100755
52
--- a/tests/qemu-iotests/175
53
+++ b/tests/qemu-iotests/175
54
@@ -XXX,XX +XXX,XX @@ min_blocks=$(stat -c '%b' "$TEST_DIR/empty")
55
56
echo
57
echo "== creating image with default preallocation =="
58
-_make_test_img -o extent_size_hint=0 $size | _filter_imgfmt
59
+_make_test_img -o extent_size_hint=0 $size
60
stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $min_blocks $size
61
62
for mode in off full falloc; do
63
echo
64
echo "== creating image with preallocation $mode =="
65
- _make_test_img -o preallocation=$mode,extent_size_hint=0 $size | _filter_imgfmt
66
+ _make_test_img -o preallocation=$mode,extent_size_hint=0 $size
67
stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $min_blocks $size
68
done
69
70
for new_size in 4096 1048576; do
71
echo
72
echo "== resize empty image with block_resize =="
73
- _make_test_img -o extent_size_hint=0 0 | _filter_imgfmt
74
+ _make_test_img -o extent_size_hint=0 0
75
_block_resize $TEST_IMG $new_size >/dev/null
76
stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $min_blocks $new_size
77
done
78
diff --git a/tests/qemu-iotests/249 b/tests/qemu-iotests/249
79
index XXXXXXX..XXXXXXX 100755
80
--- a/tests/qemu-iotests/249
81
+++ b/tests/qemu-iotests/249
82
@@ -XXX,XX +XXX,XX @@ _supported_os Linux
83
IMG_SIZE=1M
84
85
# Create the images: base <- int <- active
86
-TEST_IMG="$TEST_IMG.base" _make_test_img $IMG_SIZE | _filter_imgfmt
87
-TEST_IMG="$TEST_IMG.int" _make_test_img -b "$TEST_IMG.base" -F $IMGFMT | _filter_imgfmt
88
-_make_test_img -b "$TEST_IMG.int" -F $IMGFMT | _filter_imgfmt
89
+TEST_IMG="$TEST_IMG.base" _make_test_img $IMG_SIZE
90
+TEST_IMG="$TEST_IMG.int" _make_test_img -b "$TEST_IMG.base" -F $IMGFMT
91
+_make_test_img -b "$TEST_IMG.int" -F $IMGFMT
92
93
# Launch QEMU with these two drives:
94
# none0: base (read-only)
43
--
95
--
44
2.19.1
96
2.29.2
45
97
46
98
diff view generated by jsdifflib
1
From: Peter Maydell <peter.maydell@linaro.org>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
Taking the address of a field in a packed struct is a bad idea, because
3
Executing _make_test_img as part of a pipe will undo all variable
4
it might not be actually aligned enough for that pointer type (and
4
changes it has done. As such, this could not work with FUSE (because
5
thus cause a crash on dereference on some host architectures). Newer
5
we want to remember all of our exports and their qemu instances).
6
versions of clang warn about this. Avoid the bug by not using the
7
"modify in place" byte swapping functions.
8
6
9
There are a few places where the in-place swap function is
7
Replace the pipe by a temporary file in 071 and 174 (the two tests that
10
used on something other than a packed struct field; we convert
8
can run on FUSE).
11
those anyway, for consistency.
12
9
13
Patch produced with scripts/coccinelle/inplace-byteswaps.cocci.
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
11
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
15
There are other places where we take the address of a packed member
12
Message-Id: <20201027190600.192171-9-mreitz@redhat.com>
16
in this file for other purposes than passing it to a byteswap
17
function (all the calls to qemu_uuid_*()); we leave those for now.
18
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
---
14
---
23
block/vdi.c | 64 ++++++++++++++++++++++++++---------------------------
15
tests/qemu-iotests/071 | 19 +++++++++++++++----
24
1 file changed, 32 insertions(+), 32 deletions(-)
16
tests/qemu-iotests/174 | 10 +++++++++-
17
2 files changed, 24 insertions(+), 5 deletions(-)
25
18
26
diff --git a/block/vdi.c b/block/vdi.c
19
diff --git a/tests/qemu-iotests/071 b/tests/qemu-iotests/071
27
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100755
28
--- a/block/vdi.c
21
--- a/tests/qemu-iotests/071
29
+++ b/block/vdi.c
22
+++ b/tests/qemu-iotests/071
30
@@ -XXX,XX +XXX,XX @@ typedef struct {
23
@@ -XXX,XX +XXX,XX @@ echo
31
24
echo "=== Testing blkverify through filename ==="
32
static void vdi_header_to_cpu(VdiHeader *header)
25
echo
33
{
26
34
- le32_to_cpus(&header->signature);
27
-TEST_IMG="$TEST_IMG.base" IMGFMT="raw" _make_test_img --no-opts $IMG_SIZE |\
35
- le32_to_cpus(&header->version);
28
- _filter_imgfmt
36
- le32_to_cpus(&header->header_size);
29
+# _make_test_img may set variables that we need to retain. Everything
37
- le32_to_cpus(&header->image_type);
30
+# in a pipe is executed in a subshell, so doing so would throw away
38
- le32_to_cpus(&header->image_flags);
31
+# all changes. Therefore, we have to store the output in some temp
39
- le32_to_cpus(&header->offset_bmap);
32
+# file and filter that.
40
- le32_to_cpus(&header->offset_data);
33
+scratch_out="$TEST_DIR/img-create.out"
41
- le32_to_cpus(&header->cylinders);
34
+
42
- le32_to_cpus(&header->heads);
35
+TEST_IMG="$TEST_IMG.base" IMGFMT="raw" _make_test_img --no-opts $IMG_SIZE \
43
- le32_to_cpus(&header->sectors);
36
+ >"$scratch_out"
44
- le32_to_cpus(&header->sector_size);
37
+_filter_imgfmt <"$scratch_out"
45
- le64_to_cpus(&header->disk_size);
38
+rm -f "$scratch_out"
46
- le32_to_cpus(&header->block_size);
39
+
47
- le32_to_cpus(&header->block_extra);
40
_make_test_img $IMG_SIZE
48
- le32_to_cpus(&header->blocks_in_image);
41
$QEMU_IO -c "open -o driver=raw,file.driver=blkverify,file.raw.filename=$TEST_IMG.base $TEST_IMG" \
49
- le32_to_cpus(&header->blocks_allocated);
42
-c 'read 0 512' -c 'write -P 42 0x38000 512' -c 'read -P 42 0x38000 512' | _filter_qemu_io
50
+ header->signature = le32_to_cpu(header->signature);
43
@@ -XXX,XX +XXX,XX @@ echo
51
+ header->version = le32_to_cpu(header->version);
44
echo "=== Testing blkverify through file blockref ==="
52
+ header->header_size = le32_to_cpu(header->header_size);
45
echo
53
+ header->image_type = le32_to_cpu(header->image_type);
46
54
+ header->image_flags = le32_to_cpu(header->image_flags);
47
-TEST_IMG="$TEST_IMG.base" IMGFMT="raw" _make_test_img --no-opts $IMG_SIZE |\
55
+ header->offset_bmap = le32_to_cpu(header->offset_bmap);
48
- _filter_imgfmt
56
+ header->offset_data = le32_to_cpu(header->offset_data);
49
+TEST_IMG="$TEST_IMG.base" IMGFMT="raw" _make_test_img --no-opts $IMG_SIZE \
57
+ header->cylinders = le32_to_cpu(header->cylinders);
50
+ >"$scratch_out"
58
+ header->heads = le32_to_cpu(header->heads);
51
+_filter_imgfmt <"$scratch_out"
59
+ header->sectors = le32_to_cpu(header->sectors);
52
+
60
+ header->sector_size = le32_to_cpu(header->sector_size);
53
_make_test_img $IMG_SIZE
61
+ header->disk_size = le64_to_cpu(header->disk_size);
54
$QEMU_IO -c "open -o driver=raw,file.driver=blkverify,file.raw.filename=$TEST_IMG.base,file.test.driver=$IMGFMT,file.test.file.filename=$TEST_IMG" \
62
+ header->block_size = le32_to_cpu(header->block_size);
55
-c 'read 0 512' -c 'write -P 42 0x38000 512' -c 'read -P 42 0x38000 512' | _filter_qemu_io
63
+ header->block_extra = le32_to_cpu(header->block_extra);
56
diff --git a/tests/qemu-iotests/174 b/tests/qemu-iotests/174
64
+ header->blocks_in_image = le32_to_cpu(header->blocks_in_image);
57
index XXXXXXX..XXXXXXX 100755
65
+ header->blocks_allocated = le32_to_cpu(header->blocks_allocated);
58
--- a/tests/qemu-iotests/174
66
qemu_uuid_bswap(&header->uuid_image);
59
+++ b/tests/qemu-iotests/174
67
qemu_uuid_bswap(&header->uuid_last_snap);
60
@@ -XXX,XX +XXX,XX @@ _unsupported_fmt raw
68
qemu_uuid_bswap(&header->uuid_link);
61
69
@@ -XXX,XX +XXX,XX @@ static void vdi_header_to_cpu(VdiHeader *header)
62
70
63
size=256K
71
static void vdi_header_to_le(VdiHeader *header)
64
-IMGFMT=raw IMGKEYSECRET= _make_test_img --no-opts $size | _filter_imgfmt
72
{
65
+
73
- cpu_to_le32s(&header->signature);
66
+# _make_test_img may set variables that we need to retain. Everything
74
- cpu_to_le32s(&header->version);
67
+# in a pipe is executed in a subshell, so doing so would throw away
75
- cpu_to_le32s(&header->header_size);
68
+# all changes. Therefore, we have to store the output in some temp
76
- cpu_to_le32s(&header->image_type);
69
+# file and filter that.
77
- cpu_to_le32s(&header->image_flags);
70
+scratch_out="$TEST_DIR/img-create.out"
78
- cpu_to_le32s(&header->offset_bmap);
71
+IMGFMT=raw IMGKEYSECRET= _make_test_img --no-opts $size >"$scratch_out"
79
- cpu_to_le32s(&header->offset_data);
72
+_filter_imgfmt <"$scratch_out"
80
- cpu_to_le32s(&header->cylinders);
73
+rm -f "$scratch_out"
81
- cpu_to_le32s(&header->heads);
74
82
- cpu_to_le32s(&header->sectors);
75
echo
83
- cpu_to_le32s(&header->sector_size);
76
echo "== reading wrong format should fail =="
84
- cpu_to_le64s(&header->disk_size);
85
- cpu_to_le32s(&header->block_size);
86
- cpu_to_le32s(&header->block_extra);
87
- cpu_to_le32s(&header->blocks_in_image);
88
- cpu_to_le32s(&header->blocks_allocated);
89
+ header->signature = cpu_to_le32(header->signature);
90
+ header->version = cpu_to_le32(header->version);
91
+ header->header_size = cpu_to_le32(header->header_size);
92
+ header->image_type = cpu_to_le32(header->image_type);
93
+ header->image_flags = cpu_to_le32(header->image_flags);
94
+ header->offset_bmap = cpu_to_le32(header->offset_bmap);
95
+ header->offset_data = cpu_to_le32(header->offset_data);
96
+ header->cylinders = cpu_to_le32(header->cylinders);
97
+ header->heads = cpu_to_le32(header->heads);
98
+ header->sectors = cpu_to_le32(header->sectors);
99
+ header->sector_size = cpu_to_le32(header->sector_size);
100
+ header->disk_size = cpu_to_le64(header->disk_size);
101
+ header->block_size = cpu_to_le32(header->block_size);
102
+ header->block_extra = cpu_to_le32(header->block_extra);
103
+ header->blocks_in_image = cpu_to_le32(header->blocks_in_image);
104
+ header->blocks_allocated = cpu_to_le32(header->blocks_allocated);
105
qemu_uuid_bswap(&header->uuid_image);
106
qemu_uuid_bswap(&header->uuid_last_snap);
107
qemu_uuid_bswap(&header->uuid_link);
108
--
77
--
109
2.19.1
78
2.29.2
110
79
111
80
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
Just like in qemu_opts_print_help(), print the object name as a caption
3
qemu-img convert (without -n) can often be replaced by a combination of
4
instead of on every single line, indent all options, add angle brackets
4
_make_test_img + qemu-img convert -n. Doing so allows converting to
5
around types, and align the descriptions after 24 characters.
5
protocols that do not allow direct file creation, such as FUSE exports.
6
The only problem is that for formats other than qcow2 and qed (qcow1 at
7
least), this may lead to high disk usage for some reason, so we cannot
8
do it everywhere.
6
9
7
Also, indent every object name in the list of available objects.
10
But we can do it in 028 and 089, so let us do that so they can run on
11
FUSE exports. Also, in 028 this allows us to remove a 9-line comment
12
that used to explain why we cannot safely filter drive-backup's image
13
creation output.
8
14
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
15
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
16
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
17
Message-Id: <20201027190600.192171-10-mreitz@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
19
---
13
vl.c | 13 ++++++++++---
20
tests/qemu-iotests/028 | 14 ++++----------
14
1 file changed, 10 insertions(+), 3 deletions(-)
21
tests/qemu-iotests/028.out | 3 +++
22
tests/qemu-iotests/089 | 3 ++-
23
tests/qemu-iotests/089.out | 1 +
24
4 files changed, 10 insertions(+), 11 deletions(-)
15
25
16
diff --git a/vl.c b/vl.c
26
diff --git a/tests/qemu-iotests/028 b/tests/qemu-iotests/028
27
index XXXXXXX..XXXXXXX 100755
28
--- a/tests/qemu-iotests/028
29
+++ b/tests/qemu-iotests/028
30
@@ -XXX,XX +XXX,XX @@ else
31
QEMU_COMM_TIMEOUT=1
32
fi
33
34
-# Silence output since it contains the disk image path and QEMU's readline
35
-# character echoing makes it very hard to filter the output. Plus, there
36
-# is no telling how many times the command will repeat before succeeding.
37
-# (Note that creating the image results in a "Formatting..." message over
38
-# stdout, which is the same channel the monitor uses. We cannot reliably
39
-# wait for it because the monitor output may interact with it in such a
40
-# way that _timed_wait_for cannot read it. However, once the block job is
41
-# done, we know that the "Formatting..." message must have appeared
42
-# already, so the output is still deterministic.)
43
-silent=y _send_qemu_cmd $h "drive_backup disk ${TEST_IMG}.copy" "(qemu)"
44
+TEST_IMG="$TEST_IMG.copy" _make_test_img $image_size
45
+_send_qemu_cmd $h "drive_backup -n disk ${TEST_IMG}.copy" "(qemu)" \
46
+ | _filter_imgfmt
47
+
48
silent=y qemu_cmd_repeat=20 _send_qemu_cmd $h "info block-jobs" "No active jobs"
49
_send_qemu_cmd $h "info block-jobs" "No active jobs"
50
_send_qemu_cmd $h 'quit' ""
51
diff --git a/tests/qemu-iotests/028.out b/tests/qemu-iotests/028.out
17
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
18
--- a/vl.c
53
--- a/tests/qemu-iotests/028.out
19
+++ b/vl.c
54
+++ b/tests/qemu-iotests/028.out
20
@@ -XXX,XX +XXX,XX @@ static bool object_create_initial(const char *type, QemuOpts *opts)
55
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
21
list = object_class_get_list_sorted(TYPE_USER_CREATABLE, false);
56
22
for (l = list; l != NULL; l = l->next) {
57
block-backup
23
ObjectClass *oc = OBJECT_CLASS(l->data);
58
24
- printf("%s\n", object_class_get_name(oc));
59
+Formatting 'TEST_DIR/t.IMGFMT.copy', fmt=IMGFMT size=4294968832
25
+ printf(" %s\n", object_class_get_name(oc));
60
+QEMU X.Y.Z monitor - type 'help' for more information
26
}
61
+(qemu) drive_backup -n disk TEST_DIR/t.IMGFMT.copy
27
g_slist_free(list);
62
(qemu) info block-jobs
28
exit(0);
63
No active jobs
29
@@ -XXX,XX +XXX,XX @@ static bool object_create_initial(const char *type, QemuOpts *opts)
64
=== IO: pattern 195
30
}
65
diff --git a/tests/qemu-iotests/089 b/tests/qemu-iotests/089
31
66
index XXXXXXX..XXXXXXX 100755
32
str = g_string_new(NULL);
67
--- a/tests/qemu-iotests/089
33
- g_string_append_printf(str, "%s.%s=%s", type,
68
+++ b/tests/qemu-iotests/089
34
- prop->name, prop->type);
69
@@ -XXX,XX +XXX,XX @@ TEST_IMG="$TEST_IMG.base" _make_test_img $IMG_SIZE
35
+ g_string_append_printf(str, " %s=<%s>", prop->name, prop->type);
70
$QEMU_IO -c 'write -P 42 0 512' -c 'write -P 23 512 512' \
36
if (prop->description) {
71
-c 'write -P 66 1024 512' "$TEST_IMG.base" | _filter_qemu_io
37
+ if (str->len < 24) {
72
38
+ g_string_append_printf(str, "%*s", 24 - (int)str->len, "");
73
-$QEMU_IMG convert -f raw -O $IMGFMT "$TEST_IMG.base" "$TEST_IMG"
39
+ }
74
+_make_test_img $IMG_SIZE
40
g_string_append_printf(str, " - %s", prop->description);
75
+$QEMU_IMG convert -f raw -O $IMGFMT -n "$TEST_IMG.base" "$TEST_IMG"
41
}
76
42
g_ptr_array_add(array, g_string_free(str, false));
77
$QEMU_IO_PROG --cache $CACHEMODE --aio $AIOMODE \
43
}
78
-c 'read -P 42 0 512' -c 'read -P 23 512 512' \
44
g_ptr_array_sort(array, (GCompareFunc)qemu_pstrcmp0);
79
diff --git a/tests/qemu-iotests/089.out b/tests/qemu-iotests/089.out
45
+ if (array->len > 0) {
80
index XXXXXXX..XXXXXXX 100644
46
+ printf("%s options:\n", type);
81
--- a/tests/qemu-iotests/089.out
47
+ } else {
82
+++ b/tests/qemu-iotests/089.out
48
+ printf("There are no options for %s.\n", type);
83
@@ -XXX,XX +XXX,XX @@ wrote 512/512 bytes at offset 512
49
+ }
84
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
50
for (i = 0; i < array->len; i++) {
85
wrote 512/512 bytes at offset 1024
51
printf("%s\n", (char *)array->pdata[i]);
86
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
52
}
87
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
88
read 512/512 bytes at offset 0
89
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
90
read 512/512 bytes at offset 512
53
--
91
--
54
2.19.1
92
2.29.2
55
93
56
94
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
There is no good reason why there should be a newline in this
3
This generally does not work on non-file protocols. It is better to
4
description, so remove it.
4
create the image with the final name from the start, and most tests do
5
this already. Let 046 follow suit.
5
6
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
8
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
9
Message-Id: <20201027190600.192171-11-mreitz@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
---
11
vl.c | 2 +-
12
tests/qemu-iotests/046 | 5 +++--
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
tests/qemu-iotests/046.out | 2 +-
14
2 files changed, 4 insertions(+), 3 deletions(-)
13
15
14
diff --git a/vl.c b/vl.c
16
diff --git a/tests/qemu-iotests/046 b/tests/qemu-iotests/046
17
index XXXXXXX..XXXXXXX 100755
18
--- a/tests/qemu-iotests/046
19
+++ b/tests/qemu-iotests/046
20
@@ -XXX,XX +XXX,XX @@ size=128M
21
echo
22
echo "== creating backing file for COW tests =="
23
24
+TEST_IMG_SAVE=$TEST_IMG
25
+TEST_IMG="$TEST_IMG.base"
26
_make_test_img $size
27
28
backing_io()
29
@@ -XXX,XX +XXX,XX @@ backing_io()
30
31
backing_io 0 32 write | $QEMU_IO "$TEST_IMG" | _filter_qemu_io
32
33
-mv "$TEST_IMG" "$TEST_IMG.base"
34
-
35
+TEST_IMG=$TEST_IMG_SAVE
36
_make_test_img -b "$TEST_IMG.base" -F $IMGFMT 6G
37
38
echo
39
diff --git a/tests/qemu-iotests/046.out b/tests/qemu-iotests/046.out
15
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
16
--- a/vl.c
41
--- a/tests/qemu-iotests/046.out
17
+++ b/vl.c
42
+++ b/tests/qemu-iotests/046.out
18
@@ -XXX,XX +XXX,XX @@ static QemuOptsList qemu_fw_cfg_opts = {
43
@@ -XXX,XX +XXX,XX @@
19
}, {
44
QA output created by 046
20
.name = "file",
45
21
.type = QEMU_OPT_STRING,
46
== creating backing file for COW tests ==
22
- .help = "Sets the name of the file from which\n"
47
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
23
+ .help = "Sets the name of the file from which "
48
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728
24
"the fw_cfg blob will be loaded",
49
wrote 65536/65536 bytes at offset 0
25
}, {
50
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
26
.name = "string",
51
wrote 65536/65536 bytes at offset 65536
27
--
52
--
28
2.19.1
53
2.29.2
29
54
30
55
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
This doesn't have any practical effect at the moment because the
3
Avoid creating images with custom filenames in $TEST_DIR, because
4
values of BDRV_SECTOR_SIZE, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE and
4
non-file protocols may want to keep $TEST_IMG (and all other test
5
QCRYPTO_BLOCK_QCOW_SECTOR_SIZE are all the same (512 bytes), but
5
images) in some other directory.
6
future encryption methods could have different requirements.
7
6
8
Signed-off-by: Alberto Garcia <berto@igalia.com>
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
8
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Message-Id: <20201027190600.192171-12-mreitz@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
11
---
12
block/qcow2.c | 2 +-
12
tests/qemu-iotests/200 | 3 +--
13
1 file changed, 1 insertion(+), 1 deletion(-)
13
tests/qemu-iotests/200.out | 4 ++--
14
tests/qemu-iotests/229 | 3 +--
15
tests/qemu-iotests/229.out | 6 +++---
16
4 files changed, 7 insertions(+), 9 deletions(-)
14
17
15
diff --git a/block/qcow2.c b/block/qcow2.c
18
diff --git a/tests/qemu-iotests/200 b/tests/qemu-iotests/200
19
index XXXXXXX..XXXXXXX 100755
20
--- a/tests/qemu-iotests/200
21
+++ b/tests/qemu-iotests/200
22
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
23
_supported_fmt qcow2 qed
24
_supported_proto file
25
26
-BACKING_IMG="${TEST_DIR}/backing.img"
27
-TEST_IMG="${TEST_DIR}/test.img"
28
+BACKING_IMG="$TEST_IMG.base"
29
30
TEST_IMG="$BACKING_IMG" _make_test_img 512M
31
_make_test_img -F $IMGFMT -b "$BACKING_IMG" 512M
32
diff --git a/tests/qemu-iotests/200.out b/tests/qemu-iotests/200.out
16
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
17
--- a/block/qcow2.c
34
--- a/tests/qemu-iotests/200.out
18
+++ b/block/qcow2.c
35
+++ b/tests/qemu-iotests/200.out
19
@@ -XXX,XX +XXX,XX @@ static void qcow2_refresh_limits(BlockDriverState *bs, Error **errp)
36
@@ -XXX,XX +XXX,XX @@
20
37
QA output created by 200
21
if (bs->encrypted) {
38
-Formatting 'TEST_DIR/backing.img', fmt=IMGFMT size=536870912
22
/* Encryption works on a sector granularity */
39
-Formatting 'TEST_DIR/test.img', fmt=IMGFMT size=536870912 backing_file=TEST_DIR/backing.img backing_fmt=IMGFMT
23
- bs->bl.request_alignment = BDRV_SECTOR_SIZE;
40
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=536870912
24
+ bs->bl.request_alignment = qcrypto_block_get_sector_size(s->crypto);
41
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=536870912 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=IMGFMT
25
}
42
wrote 314572800/314572800 bytes at offset 512
26
bs->bl.pwrite_zeroes_alignment = s->cluster_size;
43
300 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
27
bs->bl.pdiscard_alignment = s->cluster_size;
44
45
diff --git a/tests/qemu-iotests/229 b/tests/qemu-iotests/229
46
index XXXXXXX..XXXXXXX 100755
47
--- a/tests/qemu-iotests/229
48
+++ b/tests/qemu-iotests/229
49
@@ -XXX,XX +XXX,XX @@ _supported_os Linux
50
_unsupported_imgopts data_file
51
52
53
-DEST_IMG="$TEST_DIR/d.$IMGFMT"
54
-TEST_IMG="$TEST_DIR/b.$IMGFMT"
55
+DEST_IMG="$TEST_IMG.dest"
56
BLKDEBUG_CONF="$TEST_DIR/blkdebug.conf"
57
58
_make_test_img 2M
59
diff --git a/tests/qemu-iotests/229.out b/tests/qemu-iotests/229.out
60
index XXXXXXX..XXXXXXX 100644
61
--- a/tests/qemu-iotests/229.out
62
+++ b/tests/qemu-iotests/229.out
63
@@ -XXX,XX +XXX,XX @@
64
QA output created by 229
65
-Formatting 'TEST_DIR/b.IMGFMT', fmt=IMGFMT size=2097152
66
-Formatting 'TEST_DIR/d.IMGFMT', fmt=IMGFMT size=2097152
67
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2097152
68
+Formatting 'TEST_DIR/t.IMGFMT.dest', fmt=IMGFMT size=2097152
69
wrote 2097152/2097152 bytes at offset 0
70
2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
71
{'execute': 'qmp_capabilities'}
72
@@ -XXX,XX +XXX,XX @@ wrote 2097152/2097152 bytes at offset 0
73
74
=== Starting drive-mirror, causing error & stop ===
75
76
-{'execute': 'drive-mirror', 'arguments': {'device': 'testdisk', 'format': 'IMGFMT', 'target': 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/d.IMGFMT', 'sync': 'full', 'mode': 'existing', 'on-source-error': 'stop', 'on-target-error': 'stop' }}
77
+{'execute': 'drive-mirror', 'arguments': {'device': 'testdisk', 'format': 'IMGFMT', 'target': 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT.dest', 'sync': 'full', 'mode': 'existing', 'on-source-error': 'stop', 'on-target-error': 'stop' }}
78
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "testdisk"}}
79
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "testdisk"}}
80
{"return": {}}
28
--
81
--
29
2.19.1
82
2.29.2
30
83
31
84
diff view generated by jsdifflib
1
From: Peter Maydell <peter.maydell@linaro.org>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
Taking the address of a field in a packed struct is a bad idea, because
3
If the test environment has some other child processes running (like a
4
it might not be actually aligned enough for that pointer type (and
4
storage daemon that provides a FUSE export), then "wait" will never
5
thus cause a crash on dereference on some host architectures). Newer
5
finish. Use wait=yes _cleanup_qemu instead.
6
versions of clang warn about this. Avoid the bug by not using the
7
"modify in place" byte swapping functions.
8
6
9
There are a few places where the in-place swap function is
7
(We need to discard the output so there is no change to the reference
10
used on something other than a packed struct field; we convert
8
output.)
11
those anyway, for consistency.
12
9
13
This patch was produced with the following spatch script:
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
11
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
15
@@
12
Message-Id: <20201027190600.192171-13-mreitz@redhat.com>
16
expression E;
17
@@
18
-be16_to_cpus(&E);
19
+E = be16_to_cpu(E);
20
@@
21
expression E;
22
@@
23
-be32_to_cpus(&E);
24
+E = be32_to_cpu(E);
25
@@
26
expression E;
27
@@
28
-be64_to_cpus(&E);
29
+E = be64_to_cpu(E);
30
@@
31
expression E;
32
@@
33
-cpu_to_be16s(&E);
34
+E = cpu_to_be16(E);
35
@@
36
expression E;
37
@@
38
-cpu_to_be32s(&E);
39
+E = cpu_to_be32(E);
40
@@
41
expression E;
42
@@
43
-cpu_to_be64s(&E);
44
+E = cpu_to_be64(E);
45
46
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
47
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
48
Tested-by: John Snow <jsnow@redhat.com>
49
Reviewed-by: John Snow <jsnow@redhat.com>
50
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
51
---
14
---
52
block/qcow.c | 18 +++++++++---------
15
tests/qemu-iotests/091 | 3 ++-
53
1 file changed, 9 insertions(+), 9 deletions(-)
16
1 file changed, 2 insertions(+), 1 deletion(-)
54
17
55
diff --git a/block/qcow.c b/block/qcow.c
18
diff --git a/tests/qemu-iotests/091 b/tests/qemu-iotests/091
56
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100755
57
--- a/block/qcow.c
20
--- a/tests/qemu-iotests/091
58
+++ b/block/qcow.c
21
+++ b/tests/qemu-iotests/091
59
@@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
22
@@ -XXX,XX +XXX,XX @@ _send_qemu_cmd $h2 'qemu-io disk flush' "(qemu)"
60
if (ret < 0) {
23
_send_qemu_cmd $h2 'quit' ""
61
goto fail;
24
_send_qemu_cmd $h1 'quit' ""
62
}
25
63
- be32_to_cpus(&header.magic);
26
-wait
64
- be32_to_cpus(&header.version);
27
+wait=yes _cleanup_qemu >/dev/null
65
- be64_to_cpus(&header.backing_file_offset);
28
+
66
- be32_to_cpus(&header.backing_file_size);
29
echo "Check image pattern"
67
- be32_to_cpus(&header.mtime);
30
${QEMU_IO} -c "read -P 0x22 0 4M" "${TEST_IMG}" | _filter_testdir | _filter_qemu_io
68
- be64_to_cpus(&header.size);
31
69
- be32_to_cpus(&header.crypt_method);
70
- be64_to_cpus(&header.l1_table_offset);
71
+ header.magic = be32_to_cpu(header.magic);
72
+ header.version = be32_to_cpu(header.version);
73
+ header.backing_file_offset = be64_to_cpu(header.backing_file_offset);
74
+ header.backing_file_size = be32_to_cpu(header.backing_file_size);
75
+ header.mtime = be32_to_cpu(header.mtime);
76
+ header.size = be64_to_cpu(header.size);
77
+ header.crypt_method = be32_to_cpu(header.crypt_method);
78
+ header.l1_table_offset = be64_to_cpu(header.l1_table_offset);
79
80
if (header.magic != QCOW_MAGIC) {
81
error_setg(errp, "Image not in qcow format");
82
@@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
83
}
84
85
for(i = 0;i < s->l1_size; i++) {
86
- be64_to_cpus(&s->l1_table[i]);
87
+ s->l1_table[i] = be64_to_cpu(s->l1_table[i]);
88
}
89
90
/* alloc L2 cache (max. 64k * 16 * 8 = 8 MB) */
91
--
32
--
92
2.19.1
33
2.29.2
93
34
94
35
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
Just like in qemu_opts_print_help(), print the device name as a caption
3
Most Python tests are restricted to the file protocol (without
4
instead of on every single line, indent all options, add angle brackets
4
explicitly saying so), but these are the ones that would break
5
around types, and align the descriptions after 24 characters. Also,
5
./check -fuse -qcow2.
6
separate the descriptions with " - " instead of putting them in
7
parentheses, because that is what we do everywhere else. This does look
8
a bit funny here because basically all bits have the description
9
"on/off", but funny does not mean it is less readable.
10
6
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
8
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Message-Id: <20201027190600.192171-14-mreitz@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
11
---
15
qdev-monitor.c | 13 +++++++++++--
12
tests/qemu-iotests/206 | 3 ++-
16
1 file changed, 11 insertions(+), 2 deletions(-)
13
tests/qemu-iotests/242 | 3 ++-
14
2 files changed, 4 insertions(+), 2 deletions(-)
17
15
18
diff --git a/qdev-monitor.c b/qdev-monitor.c
16
diff --git a/tests/qemu-iotests/206 b/tests/qemu-iotests/206
19
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100755
20
--- a/qdev-monitor.c
18
--- a/tests/qemu-iotests/206
21
+++ b/qdev-monitor.c
19
+++ b/tests/qemu-iotests/206
22
@@ -XXX,XX +XXX,XX @@ int qdev_device_help(QemuOpts *opts)
20
@@ -XXX,XX +XXX,XX @@
23
goto error;
21
import iotests
24
}
22
from iotests import imgfmt
25
23
26
+ if (prop_list) {
24
-iotests.script_initialize(supported_fmts=['qcow2'])
27
+ out_printf("%s options:\n", driver);
25
+iotests.script_initialize(supported_fmts=['qcow2'],
28
+ } else {
26
+ supported_protocols=['file'])
29
+ out_printf("There are no options for %s.\n", driver);
27
iotests.verify_working_luks()
30
+ }
28
31
for (prop = prop_list; prop; prop = prop->next) {
29
with iotests.FilePath('t.qcow2') as disk_path, \
32
- out_printf("%s.%s=%s", driver, prop->value->name, prop->value->type);
30
diff --git a/tests/qemu-iotests/242 b/tests/qemu-iotests/242
33
+ int len;
31
index XXXXXXX..XXXXXXX 100755
34
+ out_printf(" %s=<%s>%n", prop->value->name, prop->value->type, &len);
32
--- a/tests/qemu-iotests/242
35
if (prop->value->has_description) {
33
+++ b/tests/qemu-iotests/242
36
- out_printf(" (%s)\n", prop->value->description);
34
@@ -XXX,XX +XXX,XX @@ import struct
37
+ if (len < 24) {
35
from iotests import qemu_img_create, qemu_io, qemu_img_pipe, \
38
+ out_printf("%*s", 24 - len, "");
36
file_path, img_info_log, log, filter_qemu_io
39
+ }
37
40
+ out_printf(" - %s\n", prop->value->description);
38
-iotests.script_initialize(supported_fmts=['qcow2'])
41
} else {
39
+iotests.script_initialize(supported_fmts=['qcow2'],
42
out_printf("\n");
40
+ supported_protocols=['file'])
43
}
41
42
disk = file_path('disk')
43
chunk = 256 * 1024
44
--
44
--
45
2.19.1
45
2.29.2
46
46
47
47
diff view generated by jsdifflib
1
From: Peter Maydell <peter.maydell@linaro.org>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
Taking the address of a field in a packed struct is a bad idea, because
3
When most iotests want to create a test image that is named differently
4
it might not be actually aligned enough for that pointer type (and
4
from the default $TEST_IMG, they do something like this:
5
thus cause a crash on dereference on some host architectures). Newer
6
versions of clang warn about this. Avoid the bug by not using the
7
"modify in place" byte swapping functions.
8
5
9
There are a few places where the in-place swap function is
6
TEST_IMG="$TEST_IMG.base" _make_test_img $options
10
used on something other than a packed struct field; we convert
11
those anyway, for consistency.
12
7
13
This patch was produced with the following spatch script:
8
This works fine with the "file" protocol, but not so much for anything
9
else: _make_test_img tries to create an image under $TEST_IMG_FILE
10
first, and only under $TEST_IMG if the former is not set; and on
11
everything but "file", $TEST_IMG_FILE is set.
14
12
15
@@
13
There are two ways we can fix this: First, we could make all tests
16
expression E;
14
adjust not only TEST_IMG, but also TEST_IMG_FILE if that is present
17
@@
15
(e.g. with something like _set_test_img_suffix $suffix that would affect
18
-be16_to_cpus(&E);
16
not only TEST_IMG but also TEST_IMG_FILE, if necessary). This is a
19
+E = be16_to_cpu(E);
17
pretty clean solution, and this is maybe what we should have done from
20
@@
18
the start.
21
expression E;
22
@@
23
-be32_to_cpus(&E);
24
+E = be32_to_cpu(E);
25
@@
26
expression E;
27
@@
28
-be64_to_cpus(&E);
29
+E = be64_to_cpu(E);
30
@@
31
expression E;
32
@@
33
-cpu_to_be16s(&E);
34
+E = cpu_to_be16(E);
35
@@
36
expression E;
37
@@
38
-cpu_to_be32s(&E);
39
+E = cpu_to_be32(E);
40
@@
41
expression E;
42
@@
43
-cpu_to_be64s(&E);
44
+E = cpu_to_be64(E);
45
19
46
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
But it would also require changes to most existing bash tests. So the
47
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
alternative is this: Let _make_test_img see whether $TEST_IMG_FILE still
48
Tested-by: John Snow <jsnow@redhat.com>
22
points to the original value. If so, it is possible that the caller has
49
Reviewed-by: John Snow <jsnow@redhat.com>
23
adjusted $TEST_IMG but not $TEST_IMG_FILE. In such a case, we can (for
24
most protocols) derive the corresponding $TEST_IMG_FILE value from
25
$TEST_IMG value and thus work around what technically is the caller
26
misbehaving.
27
28
This second solution is less clean, but it is robust against people
29
keeping their old habit of adjusting TEST_IMG only, and requires much
30
less changes. So this patch implements it.
31
32
Signed-off-by: Max Reitz <mreitz@redhat.com>
33
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
34
Message-Id: <20201027190600.192171-15-mreitz@redhat.com>
50
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
35
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
51
---
36
---
52
block/qcow2-bitmap.c | 24 ++++++++++++------------
37
tests/qemu-iotests/common.rc | 40 +++++++++++++++++++++++++++++++++---
53
1 file changed, 12 insertions(+), 12 deletions(-)
38
1 file changed, 37 insertions(+), 3 deletions(-)
54
39
55
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
40
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
56
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
57
--- a/block/qcow2-bitmap.c
42
--- a/tests/qemu-iotests/common.rc
58
+++ b/block/qcow2-bitmap.c
43
+++ b/tests/qemu-iotests/common.rc
59
@@ -XXX,XX +XXX,XX @@ static inline void bitmap_table_to_be(uint64_t *bitmap_table, size_t size)
44
@@ -XXX,XX +XXX,XX @@ else
60
size_t i;
45
TEST_IMG=$IMGPROTO:$TEST_DIR/t.$IMGFMT
61
46
fi
62
for (i = 0; i < size; ++i) {
47
fi
63
- cpu_to_be64s(&bitmap_table[i]);
48
+ORIG_TEST_IMG_FILE=$TEST_IMG_FILE
64
+ bitmap_table[i] = cpu_to_be64(bitmap_table[i]);
49
ORIG_TEST_IMG="$TEST_IMG"
65
}
50
51
if [ -z "$TEST_DIR" ]; then
52
@@ -XXX,XX +XXX,XX @@ _get_data_file()
53
| sed -e "s#\\\$TEST_IMG#$1#"
66
}
54
}
67
55
68
@@ -XXX,XX +XXX,XX @@ static int bitmap_table_load(BlockDriverState *bs, Qcow2BitmapTable *tb,
56
+# Translate a $TEST_IMG to its corresponding $TEST_IMG_FILE for
69
}
57
+# different protocols
70
58
+_test_img_to_test_img_file()
71
for (i = 0; i < tb->size; ++i) {
59
+{
72
- be64_to_cpus(&table[i]);
60
+ case "$IMGPROTO" in
73
+ table[i] = be64_to_cpu(table[i]);
61
+ file)
74
ret = check_table_entry(table[i], s->cluster_size);
62
+ echo "$1"
75
if (ret < 0) {
63
+ ;;
76
goto fail;
64
+
77
@@ -XXX,XX +XXX,XX @@ fail:
65
+ nfs)
78
66
+ echo "$1" | sed -e "s#nfs://127.0.0.1##"
79
static inline void bitmap_dir_entry_to_cpu(Qcow2BitmapDirEntry *entry)
67
+ ;;
68
+
69
+ ssh)
70
+ echo "$1" | \
71
+ sed -e "s#ssh://\\($USER@\\)\\?127.0.0.1\\(:[0-9]\\+\\)\\?##"
72
+ ;;
73
+
74
+ *)
75
+ return 1
76
+ ;;
77
+ esac
78
+}
79
+
80
_make_test_img()
80
{
81
{
81
- be64_to_cpus(&entry->bitmap_table_offset);
82
# extra qemu-img options can be added by tests
82
- be32_to_cpus(&entry->bitmap_table_size);
83
@@ -XXX,XX +XXX,XX @@ _make_test_img()
83
- be32_to_cpus(&entry->flags);
84
local opts_param=false
84
- be16_to_cpus(&entry->name_size);
85
local misc_params=()
85
- be32_to_cpus(&entry->extra_data_size);
86
86
+ entry->bitmap_table_offset = be64_to_cpu(entry->bitmap_table_offset);
87
- if [ -n "$TEST_IMG_FILE" ]; then
87
+ entry->bitmap_table_size = be32_to_cpu(entry->bitmap_table_size);
88
- img_name=$TEST_IMG_FILE
88
+ entry->flags = be32_to_cpu(entry->flags);
89
- else
89
+ entry->name_size = be16_to_cpu(entry->name_size);
90
+ if [ -z "$TEST_IMG_FILE" ]; then
90
+ entry->extra_data_size = be32_to_cpu(entry->extra_data_size);
91
img_name=$TEST_IMG
91
}
92
+ elif [ "$IMGOPTSSYNTAX" != "true" -a \
92
93
+ "$TEST_IMG_FILE" = "$ORIG_TEST_IMG_FILE" ]; then
93
static inline void bitmap_dir_entry_to_be(Qcow2BitmapDirEntry *entry)
94
+ # Handle cases of tests only updating TEST_IMG, but not TEST_IMG_FILE
94
{
95
+ img_name=$(_test_img_to_test_img_file "$TEST_IMG")
95
- cpu_to_be64s(&entry->bitmap_table_offset);
96
+ if [ "$?" != 0 ]; then
96
- cpu_to_be32s(&entry->bitmap_table_size);
97
+ img_name=$TEST_IMG_FILE
97
- cpu_to_be32s(&entry->flags);
98
+ fi
98
- cpu_to_be16s(&entry->name_size);
99
+ else
99
- cpu_to_be32s(&entry->extra_data_size);
100
+ # $TEST_IMG_FILE is not the default value, so it definitely has been
100
+ entry->bitmap_table_offset = cpu_to_be64(entry->bitmap_table_offset);
101
+ # modified by the test
101
+ entry->bitmap_table_size = cpu_to_be32(entry->bitmap_table_size);
102
+ img_name=$TEST_IMG_FILE
102
+ entry->flags = cpu_to_be32(entry->flags);
103
fi
103
+ entry->name_size = cpu_to_be16(entry->name_size);
104
104
+ entry->extra_data_size = cpu_to_be32(entry->extra_data_size);
105
if [ -n "$IMGOPTS" ]; then
105
}
106
107
static inline int calc_dir_entry_size(size_t name_size, size_t extra_data_size)
108
--
106
--
109
2.19.1
107
2.29.2
110
108
111
109
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
When using the vvfat driver with a directory that contains too many files,
3
287 creates an image in a subshell (thanks to the pipe) to see whether
4
QEMU currently crashes. This can be triggered like this for example:
4
that is possible with compression_type=zstd. If _make_test_img were to
5
modify any global state, this global state would then be lost before we
6
could cleanup the image.
5
7
6
mkdir /tmp/vvfattest
8
When using FUSE as the test protocol, this global state is important, so
7
cd /tmp/vvfattest
9
clean up the image before the state is lost.
8
for ((x=0;x<=513;x++)); do mkdir $x; done
9
qemu-system-x86_64 -drive \
10
file.driver=vvfat,file.dir=.,read-only=on,media=cdrom
11
10
12
Seems like read_directory() is changing the mapping->path variable. Make
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
13
sure we use the right pointer instead.
12
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
14
13
Message-Id: <20201027190600.192171-16-mreitz@redhat.com>
15
Signed-off-by: Thomas Huth <thuth@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
---
15
---
18
block/vvfat.c | 4 ++--
16
tests/qemu-iotests/287 | 4 ++--
19
1 file changed, 2 insertions(+), 2 deletions(-)
17
1 file changed, 2 insertions(+), 2 deletions(-)
20
18
21
diff --git a/block/vvfat.c b/block/vvfat.c
19
diff --git a/tests/qemu-iotests/287 b/tests/qemu-iotests/287
22
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100755
23
--- a/block/vvfat.c
21
--- a/tests/qemu-iotests/287
24
+++ b/block/vvfat.c
22
+++ b/tests/qemu-iotests/287
25
@@ -XXX,XX +XXX,XX @@ static int init_directories(BDRVVVFATState* s,
23
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
26
mapping = array_get(&(s->mapping), i);
24
CLUSTER_SIZE=65536
27
25
28
if (mapping->mode & MODE_DIRECTORY) {
26
# Check if we can run this test.
29
+ char *path = mapping->path;
27
-if IMGOPTS='compression_type=zstd' _make_test_img 64M |
30
mapping->begin = cluster;
28
- grep "Invalid parameter 'zstd'"; then
31
if(read_directory(s, i)) {
29
+output=$(_make_test_img -o 'compression_type=zstd' 64M; _cleanup_test_img)
32
- error_setg(errp, "Could not read directory %s",
30
+if echo "$output" | grep -q "Invalid parameter 'zstd'"; then
33
- mapping->path);
31
_notrun "ZSTD is disabled"
34
+ error_setg(errp, "Could not read directory %s", path);
32
fi
35
return -1;
33
36
}
37
mapping = array_get(&(s->mapping), i);
38
--
34
--
39
2.19.1
35
2.29.2
40
36
41
37
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
This adds some whitespace into the option help (including indentation)
3
Otherwise, exports and block devices are not properly shut down and
4
and puts angle brackets around the type names. Furthermore, the list
4
closed, unless the users explicitly issues blockdev-del and
5
name is no longer printed as part of every line, but only once in
5
block-export-del commands for each of them.
6
advance, and only if the caller did not print a caption already.
7
8
This patch also restores the description alignment we had before commit
9
9cbef9d68ee1d8d0, just at 24 instead of 16 characters like we used to.
10
This increase is because now we have the type and two spaces of
11
indentation before the description, and with a usual type name length of
12
three chracters, this sums up to eight additional characters -- which
13
means that we now need 24 characters to get the same amount of padding
14
for most options. Also, 24 is a third of 80, which makes it kind of a
15
round number in terminal terms.
16
17
Finally, this patch amends the reference output of iotest 082 to match
18
the changes (and thus makes it pass again).
19
6
20
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
21
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
8
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Message-Id: <20201027190600.192171-17-mreitz@redhat.com>
22
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
23
---
11
---
24
include/qemu/option.h | 2 +-
12
storage-daemon/qemu-storage-daemon.c | 3 +++
25
qemu-img.c | 4 +-
13
1 file changed, 3 insertions(+)
26
util/qemu-option.c | 32 +-
27
tests/qemu-iotests/082.out | 956 ++++++++++++++++++-------------------
28
4 files changed, 507 insertions(+), 487 deletions(-)
29
14
30
diff --git a/include/qemu/option.h b/include/qemu/option.h
15
diff --git a/storage-daemon/qemu-storage-daemon.c b/storage-daemon/qemu-storage-daemon.c
31
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
32
--- a/include/qemu/option.h
17
--- a/storage-daemon/qemu-storage-daemon.c
33
+++ b/include/qemu/option.h
18
+++ b/storage-daemon/qemu-storage-daemon.c
34
@@ -XXX,XX +XXX,XX @@ typedef int (*qemu_opts_loopfunc)(void *opaque, QemuOpts *opts, Error **errp);
19
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
35
int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func,
20
main_loop_wait(false);
36
void *opaque, Error **errp);
37
void qemu_opts_print(QemuOpts *opts, const char *sep);
38
-void qemu_opts_print_help(QemuOptsList *list);
39
+void qemu_opts_print_help(QemuOptsList *list, bool print_caption);
40
void qemu_opts_free(QemuOptsList *list);
41
QemuOptsList *qemu_opts_append(QemuOptsList *dst, QemuOptsList *list);
42
43
diff --git a/qemu-img.c b/qemu-img.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/qemu-img.c
46
+++ b/qemu-img.c
47
@@ -XXX,XX +XXX,XX @@ static int print_block_option_help(const char *filename, const char *fmt)
48
}
21
}
49
22
50
printf("Supported options:\n");
23
+ bdrv_drain_all_begin();
51
- qemu_opts_print_help(create_opts);
24
+ bdrv_close_all();
52
+ qemu_opts_print_help(create_opts, false);
25
+
53
qemu_opts_free(create_opts);
26
monitor_cleanup();
54
return 0;
27
qemu_chr_cleanup();
55
}
28
user_creatable_cleanup();
56
@@ -XXX,XX +XXX,XX @@ static int print_amend_option_help(const char *format)
57
assert(drv->create_opts);
58
59
printf("Creation options for '%s':\n", format);
60
- qemu_opts_print_help(drv->create_opts);
61
+ qemu_opts_print_help(drv->create_opts, false);
62
printf("\nNote that not all of these options may be amendable.\n");
63
return 0;
64
}
65
diff --git a/util/qemu-option.c b/util/qemu-option.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/util/qemu-option.c
68
+++ b/util/qemu-option.c
69
@@ -XXX,XX +XXX,XX @@ static const char *opt_type_to_string(enum QemuOptType type)
70
g_assert_not_reached();
71
}
72
73
-void qemu_opts_print_help(QemuOptsList *list)
74
+/**
75
+ * Print the list of options available in the given list. If
76
+ * @print_caption is true, a caption (including the list name, if it
77
+ * exists) is printed. The options itself will be indented, so
78
+ * @print_caption should only be set to false if the caller prints its
79
+ * own custom caption (so that the indentation makes sense).
80
+ */
81
+void qemu_opts_print_help(QemuOptsList *list, bool print_caption)
82
{
83
QemuOptDesc *desc;
84
int i;
85
@@ -XXX,XX +XXX,XX @@ void qemu_opts_print_help(QemuOptsList *list)
86
desc = list->desc;
87
while (desc && desc->name) {
88
GString *str = g_string_new(NULL);
89
- if (list->name) {
90
- g_string_append_printf(str, "%s.", list->name);
91
- }
92
- g_string_append_printf(str, "%s=%s", desc->name,
93
+ g_string_append_printf(str, " %s=<%s>", desc->name,
94
opt_type_to_string(desc->type));
95
if (desc->help) {
96
+ if (str->len < 24) {
97
+ g_string_append_printf(str, "%*s", 24 - (int)str->len, "");
98
+ }
99
g_string_append_printf(str, " - %s", desc->help);
100
}
101
g_ptr_array_add(array, g_string_free(str, false));
102
@@ -XXX,XX +XXX,XX @@ void qemu_opts_print_help(QemuOptsList *list)
103
}
104
105
g_ptr_array_sort(array, (GCompareFunc)qemu_pstrcmp0);
106
+ if (print_caption && array->len > 0) {
107
+ if (list->name) {
108
+ printf("%s options:\n", list->name);
109
+ } else {
110
+ printf("Options:\n");
111
+ }
112
+ } else if (array->len == 0) {
113
+ if (list->name) {
114
+ printf("There are no options for %s.\n", list->name);
115
+ } else {
116
+ printf("No options available.\n");
117
+ }
118
+ }
119
for (i = 0; i < array->len; i++) {
120
printf("%s\n", (char *)array->pdata[i]);
121
}
122
@@ -XXX,XX +XXX,XX @@ QemuOpts *qemu_opts_parse_noisily(QemuOptsList *list, const char *params,
123
opts = opts_parse(list, params, permit_abbrev, false, &invalidp, &err);
124
if (err) {
125
if (invalidp && has_help_option(params)) {
126
- qemu_opts_print_help(list);
127
+ qemu_opts_print_help(list, true);
128
error_free(err);
129
} else {
130
error_report_err(err);
131
diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out
132
index XXXXXXX..XXXXXXX 100644
133
--- a/tests/qemu-iotests/082.out
134
+++ b/tests/qemu-iotests/082.out
135
@@ -XXX,XX +XXX,XX @@ cluster_size: 8192
136
137
Testing: create -f qcow2 -o help TEST_DIR/t.qcow2 128M
138
Supported options:
139
-size Virtual disk size
140
-compat Compatibility level (0.10 or 1.1)
141
-backing_file File name of a base image
142
-backing_fmt Image format of the base image
143
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
144
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
145
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
146
-encrypt.cipher-alg Name of encryption cipher algorithm
147
-encrypt.cipher-mode Name of encryption cipher mode
148
-encrypt.ivgen-alg Name of IV generator algorithm
149
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
150
-encrypt.hash-alg Name of encryption hash algorithm
151
-encrypt.iter-time Time to spend in PBKDF in milliseconds
152
-cluster_size qcow2 cluster size
153
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
154
-lazy_refcounts Postpone refcount updates
155
-refcount_bits Width of a reference count entry in bits
156
-nocow Turn off copy-on-write (valid only on btrfs)
157
+ backing_file=<str> - File name of a base image
158
+ backing_fmt=<str> - Image format of the base image
159
+ cluster_size=<size> - qcow2 cluster size
160
+ compat=<str> - Compatibility level (0.10 or 1.1)
161
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
162
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
163
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
164
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
165
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
166
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
167
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
168
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
169
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
170
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
171
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
172
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
173
+ refcount_bits=<num> - Width of a reference count entry in bits
174
+ size=<size> - Virtual disk size
175
176
Testing: create -f qcow2 -o ? TEST_DIR/t.qcow2 128M
177
Supported options:
178
-size Virtual disk size
179
-compat Compatibility level (0.10 or 1.1)
180
-backing_file File name of a base image
181
-backing_fmt Image format of the base image
182
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
183
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
184
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
185
-encrypt.cipher-alg Name of encryption cipher algorithm
186
-encrypt.cipher-mode Name of encryption cipher mode
187
-encrypt.ivgen-alg Name of IV generator algorithm
188
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
189
-encrypt.hash-alg Name of encryption hash algorithm
190
-encrypt.iter-time Time to spend in PBKDF in milliseconds
191
-cluster_size qcow2 cluster size
192
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
193
-lazy_refcounts Postpone refcount updates
194
-refcount_bits Width of a reference count entry in bits
195
-nocow Turn off copy-on-write (valid only on btrfs)
196
+ backing_file=<str> - File name of a base image
197
+ backing_fmt=<str> - Image format of the base image
198
+ cluster_size=<size> - qcow2 cluster size
199
+ compat=<str> - Compatibility level (0.10 or 1.1)
200
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
201
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
202
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
203
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
204
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
205
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
206
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
207
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
208
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
209
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
210
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
211
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
212
+ refcount_bits=<num> - Width of a reference count entry in bits
213
+ size=<size> - Virtual disk size
214
215
Testing: create -f qcow2 -o cluster_size=4k,help TEST_DIR/t.qcow2 128M
216
Supported options:
217
-size Virtual disk size
218
-compat Compatibility level (0.10 or 1.1)
219
-backing_file File name of a base image
220
-backing_fmt Image format of the base image
221
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
222
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
223
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
224
-encrypt.cipher-alg Name of encryption cipher algorithm
225
-encrypt.cipher-mode Name of encryption cipher mode
226
-encrypt.ivgen-alg Name of IV generator algorithm
227
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
228
-encrypt.hash-alg Name of encryption hash algorithm
229
-encrypt.iter-time Time to spend in PBKDF in milliseconds
230
-cluster_size qcow2 cluster size
231
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
232
-lazy_refcounts Postpone refcount updates
233
-refcount_bits Width of a reference count entry in bits
234
-nocow Turn off copy-on-write (valid only on btrfs)
235
+ backing_file=<str> - File name of a base image
236
+ backing_fmt=<str> - Image format of the base image
237
+ cluster_size=<size> - qcow2 cluster size
238
+ compat=<str> - Compatibility level (0.10 or 1.1)
239
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
240
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
241
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
242
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
243
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
244
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
245
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
246
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
247
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
248
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
249
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
250
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
251
+ refcount_bits=<num> - Width of a reference count entry in bits
252
+ size=<size> - Virtual disk size
253
254
Testing: create -f qcow2 -o cluster_size=4k,? TEST_DIR/t.qcow2 128M
255
Supported options:
256
-size Virtual disk size
257
-compat Compatibility level (0.10 or 1.1)
258
-backing_file File name of a base image
259
-backing_fmt Image format of the base image
260
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
261
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
262
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
263
-encrypt.cipher-alg Name of encryption cipher algorithm
264
-encrypt.cipher-mode Name of encryption cipher mode
265
-encrypt.ivgen-alg Name of IV generator algorithm
266
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
267
-encrypt.hash-alg Name of encryption hash algorithm
268
-encrypt.iter-time Time to spend in PBKDF in milliseconds
269
-cluster_size qcow2 cluster size
270
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
271
-lazy_refcounts Postpone refcount updates
272
-refcount_bits Width of a reference count entry in bits
273
-nocow Turn off copy-on-write (valid only on btrfs)
274
+ backing_file=<str> - File name of a base image
275
+ backing_fmt=<str> - Image format of the base image
276
+ cluster_size=<size> - qcow2 cluster size
277
+ compat=<str> - Compatibility level (0.10 or 1.1)
278
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
279
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
280
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
281
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
282
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
283
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
284
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
285
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
286
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
287
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
288
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
289
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
290
+ refcount_bits=<num> - Width of a reference count entry in bits
291
+ size=<size> - Virtual disk size
292
293
Testing: create -f qcow2 -o help,cluster_size=4k TEST_DIR/t.qcow2 128M
294
Supported options:
295
-size Virtual disk size
296
-compat Compatibility level (0.10 or 1.1)
297
-backing_file File name of a base image
298
-backing_fmt Image format of the base image
299
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
300
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
301
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
302
-encrypt.cipher-alg Name of encryption cipher algorithm
303
-encrypt.cipher-mode Name of encryption cipher mode
304
-encrypt.ivgen-alg Name of IV generator algorithm
305
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
306
-encrypt.hash-alg Name of encryption hash algorithm
307
-encrypt.iter-time Time to spend in PBKDF in milliseconds
308
-cluster_size qcow2 cluster size
309
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
310
-lazy_refcounts Postpone refcount updates
311
-refcount_bits Width of a reference count entry in bits
312
-nocow Turn off copy-on-write (valid only on btrfs)
313
+ backing_file=<str> - File name of a base image
314
+ backing_fmt=<str> - Image format of the base image
315
+ cluster_size=<size> - qcow2 cluster size
316
+ compat=<str> - Compatibility level (0.10 or 1.1)
317
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
318
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
319
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
320
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
321
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
322
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
323
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
324
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
325
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
326
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
327
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
328
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
329
+ refcount_bits=<num> - Width of a reference count entry in bits
330
+ size=<size> - Virtual disk size
331
332
Testing: create -f qcow2 -o ?,cluster_size=4k TEST_DIR/t.qcow2 128M
333
Supported options:
334
-size Virtual disk size
335
-compat Compatibility level (0.10 or 1.1)
336
-backing_file File name of a base image
337
-backing_fmt Image format of the base image
338
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
339
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
340
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
341
-encrypt.cipher-alg Name of encryption cipher algorithm
342
-encrypt.cipher-mode Name of encryption cipher mode
343
-encrypt.ivgen-alg Name of IV generator algorithm
344
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
345
-encrypt.hash-alg Name of encryption hash algorithm
346
-encrypt.iter-time Time to spend in PBKDF in milliseconds
347
-cluster_size qcow2 cluster size
348
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
349
-lazy_refcounts Postpone refcount updates
350
-refcount_bits Width of a reference count entry in bits
351
-nocow Turn off copy-on-write (valid only on btrfs)
352
+ backing_file=<str> - File name of a base image
353
+ backing_fmt=<str> - Image format of the base image
354
+ cluster_size=<size> - qcow2 cluster size
355
+ compat=<str> - Compatibility level (0.10 or 1.1)
356
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
357
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
358
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
359
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
360
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
361
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
362
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
363
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
364
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
365
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
366
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
367
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
368
+ refcount_bits=<num> - Width of a reference count entry in bits
369
+ size=<size> - Virtual disk size
370
371
Testing: create -f qcow2 -o cluster_size=4k -o help TEST_DIR/t.qcow2 128M
372
Supported options:
373
-size Virtual disk size
374
-compat Compatibility level (0.10 or 1.1)
375
-backing_file File name of a base image
376
-backing_fmt Image format of the base image
377
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
378
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
379
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
380
-encrypt.cipher-alg Name of encryption cipher algorithm
381
-encrypt.cipher-mode Name of encryption cipher mode
382
-encrypt.ivgen-alg Name of IV generator algorithm
383
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
384
-encrypt.hash-alg Name of encryption hash algorithm
385
-encrypt.iter-time Time to spend in PBKDF in milliseconds
386
-cluster_size qcow2 cluster size
387
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
388
-lazy_refcounts Postpone refcount updates
389
-refcount_bits Width of a reference count entry in bits
390
-nocow Turn off copy-on-write (valid only on btrfs)
391
+ backing_file=<str> - File name of a base image
392
+ backing_fmt=<str> - Image format of the base image
393
+ cluster_size=<size> - qcow2 cluster size
394
+ compat=<str> - Compatibility level (0.10 or 1.1)
395
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
396
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
397
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
398
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
399
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
400
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
401
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
402
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
403
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
404
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
405
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
406
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
407
+ refcount_bits=<num> - Width of a reference count entry in bits
408
+ size=<size> - Virtual disk size
409
410
Testing: create -f qcow2 -o cluster_size=4k -o ? TEST_DIR/t.qcow2 128M
411
Supported options:
412
-size Virtual disk size
413
-compat Compatibility level (0.10 or 1.1)
414
-backing_file File name of a base image
415
-backing_fmt Image format of the base image
416
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
417
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
418
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
419
-encrypt.cipher-alg Name of encryption cipher algorithm
420
-encrypt.cipher-mode Name of encryption cipher mode
421
-encrypt.ivgen-alg Name of IV generator algorithm
422
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
423
-encrypt.hash-alg Name of encryption hash algorithm
424
-encrypt.iter-time Time to spend in PBKDF in milliseconds
425
-cluster_size qcow2 cluster size
426
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
427
-lazy_refcounts Postpone refcount updates
428
-refcount_bits Width of a reference count entry in bits
429
-nocow Turn off copy-on-write (valid only on btrfs)
430
+ backing_file=<str> - File name of a base image
431
+ backing_fmt=<str> - Image format of the base image
432
+ cluster_size=<size> - qcow2 cluster size
433
+ compat=<str> - Compatibility level (0.10 or 1.1)
434
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
435
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
436
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
437
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
438
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
439
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
440
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
441
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
442
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
443
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
444
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
445
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
446
+ refcount_bits=<num> - Width of a reference count entry in bits
447
+ size=<size> - Virtual disk size
448
449
Testing: create -f qcow2 -u -o backing_file=TEST_DIR/t.qcow2,,help TEST_DIR/t.qcow2 128M
450
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2,,help cluster_size=65536 lazy_refcounts=off refcount_bits=16
451
@@ -XXX,XX +XXX,XX @@ qemu-img: Invalid option list: ,,
452
453
Testing: create -f qcow2 -o help
454
Supported options:
455
-size Virtual disk size
456
-compat Compatibility level (0.10 or 1.1)
457
-backing_file File name of a base image
458
-backing_fmt Image format of the base image
459
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
460
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
461
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
462
-encrypt.cipher-alg Name of encryption cipher algorithm
463
-encrypt.cipher-mode Name of encryption cipher mode
464
-encrypt.ivgen-alg Name of IV generator algorithm
465
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
466
-encrypt.hash-alg Name of encryption hash algorithm
467
-encrypt.iter-time Time to spend in PBKDF in milliseconds
468
-cluster_size qcow2 cluster size
469
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
470
-lazy_refcounts Postpone refcount updates
471
-refcount_bits Width of a reference count entry in bits
472
+ backing_file=<str> - File name of a base image
473
+ backing_fmt=<str> - Image format of the base image
474
+ cluster_size=<size> - qcow2 cluster size
475
+ compat=<str> - Compatibility level (0.10 or 1.1)
476
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
477
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
478
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
479
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
480
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
481
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
482
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
483
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
484
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
485
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
486
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
487
+ refcount_bits=<num> - Width of a reference count entry in bits
488
+ size=<size> - Virtual disk size
489
490
Testing: create -o help
491
Supported options:
492
-size Virtual disk size
493
+ size=<size> - Virtual disk size
494
495
Testing: create -f bochs -o help
496
qemu-img: Format driver 'bochs' does not support image creation
497
@@ -XXX,XX +XXX,XX @@ cluster_size: 8192
498
499
Testing: convert -O qcow2 -o help TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
500
Supported options:
501
-size Virtual disk size
502
-compat Compatibility level (0.10 or 1.1)
503
-backing_file File name of a base image
504
-backing_fmt Image format of the base image
505
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
506
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
507
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
508
-encrypt.cipher-alg Name of encryption cipher algorithm
509
-encrypt.cipher-mode Name of encryption cipher mode
510
-encrypt.ivgen-alg Name of IV generator algorithm
511
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
512
-encrypt.hash-alg Name of encryption hash algorithm
513
-encrypt.iter-time Time to spend in PBKDF in milliseconds
514
-cluster_size qcow2 cluster size
515
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
516
-lazy_refcounts Postpone refcount updates
517
-refcount_bits Width of a reference count entry in bits
518
-nocow Turn off copy-on-write (valid only on btrfs)
519
+ backing_file=<str> - File name of a base image
520
+ backing_fmt=<str> - Image format of the base image
521
+ cluster_size=<size> - qcow2 cluster size
522
+ compat=<str> - Compatibility level (0.10 or 1.1)
523
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
524
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
525
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
526
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
527
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
528
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
529
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
530
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
531
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
532
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
533
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
534
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
535
+ refcount_bits=<num> - Width of a reference count entry in bits
536
+ size=<size> - Virtual disk size
537
538
Testing: convert -O qcow2 -o ? TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
539
Supported options:
540
-size Virtual disk size
541
-compat Compatibility level (0.10 or 1.1)
542
-backing_file File name of a base image
543
-backing_fmt Image format of the base image
544
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
545
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
546
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
547
-encrypt.cipher-alg Name of encryption cipher algorithm
548
-encrypt.cipher-mode Name of encryption cipher mode
549
-encrypt.ivgen-alg Name of IV generator algorithm
550
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
551
-encrypt.hash-alg Name of encryption hash algorithm
552
-encrypt.iter-time Time to spend in PBKDF in milliseconds
553
-cluster_size qcow2 cluster size
554
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
555
-lazy_refcounts Postpone refcount updates
556
-refcount_bits Width of a reference count entry in bits
557
-nocow Turn off copy-on-write (valid only on btrfs)
558
+ backing_file=<str> - File name of a base image
559
+ backing_fmt=<str> - Image format of the base image
560
+ cluster_size=<size> - qcow2 cluster size
561
+ compat=<str> - Compatibility level (0.10 or 1.1)
562
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
563
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
564
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
565
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
566
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
567
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
568
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
569
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
570
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
571
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
572
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
573
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
574
+ refcount_bits=<num> - Width of a reference count entry in bits
575
+ size=<size> - Virtual disk size
576
577
Testing: convert -O qcow2 -o cluster_size=4k,help TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
578
Supported options:
579
-size Virtual disk size
580
-compat Compatibility level (0.10 or 1.1)
581
-backing_file File name of a base image
582
-backing_fmt Image format of the base image
583
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
584
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
585
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
586
-encrypt.cipher-alg Name of encryption cipher algorithm
587
-encrypt.cipher-mode Name of encryption cipher mode
588
-encrypt.ivgen-alg Name of IV generator algorithm
589
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
590
-encrypt.hash-alg Name of encryption hash algorithm
591
-encrypt.iter-time Time to spend in PBKDF in milliseconds
592
-cluster_size qcow2 cluster size
593
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
594
-lazy_refcounts Postpone refcount updates
595
-refcount_bits Width of a reference count entry in bits
596
-nocow Turn off copy-on-write (valid only on btrfs)
597
+ backing_file=<str> - File name of a base image
598
+ backing_fmt=<str> - Image format of the base image
599
+ cluster_size=<size> - qcow2 cluster size
600
+ compat=<str> - Compatibility level (0.10 or 1.1)
601
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
602
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
603
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
604
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
605
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
606
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
607
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
608
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
609
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
610
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
611
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
612
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
613
+ refcount_bits=<num> - Width of a reference count entry in bits
614
+ size=<size> - Virtual disk size
615
616
Testing: convert -O qcow2 -o cluster_size=4k,? TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
617
Supported options:
618
-size Virtual disk size
619
-compat Compatibility level (0.10 or 1.1)
620
-backing_file File name of a base image
621
-backing_fmt Image format of the base image
622
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
623
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
624
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
625
-encrypt.cipher-alg Name of encryption cipher algorithm
626
-encrypt.cipher-mode Name of encryption cipher mode
627
-encrypt.ivgen-alg Name of IV generator algorithm
628
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
629
-encrypt.hash-alg Name of encryption hash algorithm
630
-encrypt.iter-time Time to spend in PBKDF in milliseconds
631
-cluster_size qcow2 cluster size
632
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
633
-lazy_refcounts Postpone refcount updates
634
-refcount_bits Width of a reference count entry in bits
635
-nocow Turn off copy-on-write (valid only on btrfs)
636
+ backing_file=<str> - File name of a base image
637
+ backing_fmt=<str> - Image format of the base image
638
+ cluster_size=<size> - qcow2 cluster size
639
+ compat=<str> - Compatibility level (0.10 or 1.1)
640
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
641
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
642
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
643
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
644
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
645
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
646
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
647
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
648
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
649
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
650
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
651
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
652
+ refcount_bits=<num> - Width of a reference count entry in bits
653
+ size=<size> - Virtual disk size
654
655
Testing: convert -O qcow2 -o help,cluster_size=4k TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
656
Supported options:
657
-size Virtual disk size
658
-compat Compatibility level (0.10 or 1.1)
659
-backing_file File name of a base image
660
-backing_fmt Image format of the base image
661
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
662
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
663
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
664
-encrypt.cipher-alg Name of encryption cipher algorithm
665
-encrypt.cipher-mode Name of encryption cipher mode
666
-encrypt.ivgen-alg Name of IV generator algorithm
667
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
668
-encrypt.hash-alg Name of encryption hash algorithm
669
-encrypt.iter-time Time to spend in PBKDF in milliseconds
670
-cluster_size qcow2 cluster size
671
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
672
-lazy_refcounts Postpone refcount updates
673
-refcount_bits Width of a reference count entry in bits
674
-nocow Turn off copy-on-write (valid only on btrfs)
675
+ backing_file=<str> - File name of a base image
676
+ backing_fmt=<str> - Image format of the base image
677
+ cluster_size=<size> - qcow2 cluster size
678
+ compat=<str> - Compatibility level (0.10 or 1.1)
679
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
680
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
681
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
682
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
683
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
684
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
685
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
686
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
687
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
688
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
689
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
690
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
691
+ refcount_bits=<num> - Width of a reference count entry in bits
692
+ size=<size> - Virtual disk size
693
694
Testing: convert -O qcow2 -o ?,cluster_size=4k TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
695
Supported options:
696
-size Virtual disk size
697
-compat Compatibility level (0.10 or 1.1)
698
-backing_file File name of a base image
699
-backing_fmt Image format of the base image
700
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
701
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
702
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
703
-encrypt.cipher-alg Name of encryption cipher algorithm
704
-encrypt.cipher-mode Name of encryption cipher mode
705
-encrypt.ivgen-alg Name of IV generator algorithm
706
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
707
-encrypt.hash-alg Name of encryption hash algorithm
708
-encrypt.iter-time Time to spend in PBKDF in milliseconds
709
-cluster_size qcow2 cluster size
710
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
711
-lazy_refcounts Postpone refcount updates
712
-refcount_bits Width of a reference count entry in bits
713
-nocow Turn off copy-on-write (valid only on btrfs)
714
+ backing_file=<str> - File name of a base image
715
+ backing_fmt=<str> - Image format of the base image
716
+ cluster_size=<size> - qcow2 cluster size
717
+ compat=<str> - Compatibility level (0.10 or 1.1)
718
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
719
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
720
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
721
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
722
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
723
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
724
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
725
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
726
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
727
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
728
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
729
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
730
+ refcount_bits=<num> - Width of a reference count entry in bits
731
+ size=<size> - Virtual disk size
732
733
Testing: convert -O qcow2 -o cluster_size=4k -o help TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
734
Supported options:
735
-size Virtual disk size
736
-compat Compatibility level (0.10 or 1.1)
737
-backing_file File name of a base image
738
-backing_fmt Image format of the base image
739
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
740
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
741
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
742
-encrypt.cipher-alg Name of encryption cipher algorithm
743
-encrypt.cipher-mode Name of encryption cipher mode
744
-encrypt.ivgen-alg Name of IV generator algorithm
745
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
746
-encrypt.hash-alg Name of encryption hash algorithm
747
-encrypt.iter-time Time to spend in PBKDF in milliseconds
748
-cluster_size qcow2 cluster size
749
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
750
-lazy_refcounts Postpone refcount updates
751
-refcount_bits Width of a reference count entry in bits
752
-nocow Turn off copy-on-write (valid only on btrfs)
753
+ backing_file=<str> - File name of a base image
754
+ backing_fmt=<str> - Image format of the base image
755
+ cluster_size=<size> - qcow2 cluster size
756
+ compat=<str> - Compatibility level (0.10 or 1.1)
757
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
758
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
759
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
760
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
761
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
762
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
763
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
764
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
765
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
766
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
767
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
768
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
769
+ refcount_bits=<num> - Width of a reference count entry in bits
770
+ size=<size> - Virtual disk size
771
772
Testing: convert -O qcow2 -o cluster_size=4k -o ? TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
773
Supported options:
774
-size Virtual disk size
775
-compat Compatibility level (0.10 or 1.1)
776
-backing_file File name of a base image
777
-backing_fmt Image format of the base image
778
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
779
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
780
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
781
-encrypt.cipher-alg Name of encryption cipher algorithm
782
-encrypt.cipher-mode Name of encryption cipher mode
783
-encrypt.ivgen-alg Name of IV generator algorithm
784
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
785
-encrypt.hash-alg Name of encryption hash algorithm
786
-encrypt.iter-time Time to spend in PBKDF in milliseconds
787
-cluster_size qcow2 cluster size
788
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
789
-lazy_refcounts Postpone refcount updates
790
-refcount_bits Width of a reference count entry in bits
791
-nocow Turn off copy-on-write (valid only on btrfs)
792
+ backing_file=<str> - File name of a base image
793
+ backing_fmt=<str> - Image format of the base image
794
+ cluster_size=<size> - qcow2 cluster size
795
+ compat=<str> - Compatibility level (0.10 or 1.1)
796
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
797
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
798
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
799
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
800
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
801
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
802
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
803
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
804
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
805
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
806
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
807
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
808
+ refcount_bits=<num> - Width of a reference count entry in bits
809
+ size=<size> - Virtual disk size
810
811
Testing: convert -O qcow2 -o backing_file=TEST_DIR/t.qcow2,,help TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
812
qemu-img: Could not open 'TEST_DIR/t.qcow2.base': Could not open backing file: Could not open 'TEST_DIR/t.qcow2,help': No such file or directory
813
@@ -XXX,XX +XXX,XX @@ qemu-img: Invalid option list: ,,
814
815
Testing: convert -O qcow2 -o help
816
Supported options:
817
-size Virtual disk size
818
-compat Compatibility level (0.10 or 1.1)
819
-backing_file File name of a base image
820
-backing_fmt Image format of the base image
821
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
822
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
823
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
824
-encrypt.cipher-alg Name of encryption cipher algorithm
825
-encrypt.cipher-mode Name of encryption cipher mode
826
-encrypt.ivgen-alg Name of IV generator algorithm
827
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
828
-encrypt.hash-alg Name of encryption hash algorithm
829
-encrypt.iter-time Time to spend in PBKDF in milliseconds
830
-cluster_size qcow2 cluster size
831
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
832
-lazy_refcounts Postpone refcount updates
833
-refcount_bits Width of a reference count entry in bits
834
+ backing_file=<str> - File name of a base image
835
+ backing_fmt=<str> - Image format of the base image
836
+ cluster_size=<size> - qcow2 cluster size
837
+ compat=<str> - Compatibility level (0.10 or 1.1)
838
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
839
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
840
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
841
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
842
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
843
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
844
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
845
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
846
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
847
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
848
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
849
+ refcount_bits=<num> - Width of a reference count entry in bits
850
+ size=<size> - Virtual disk size
851
852
Testing: convert -o help
853
Supported options:
854
-size Virtual disk size
855
+ size=<size> - Virtual disk size
856
857
Testing: convert -O bochs -o help
858
qemu-img: Format driver 'bochs' does not support image creation
859
@@ -XXX,XX +XXX,XX @@ cluster_size: 65536
860
861
Testing: amend -f qcow2 -o help TEST_DIR/t.qcow2
862
Creation options for 'qcow2':
863
-size Virtual disk size
864
-compat Compatibility level (0.10 or 1.1)
865
-backing_file File name of a base image
866
-backing_fmt Image format of the base image
867
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
868
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
869
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
870
-encrypt.cipher-alg Name of encryption cipher algorithm
871
-encrypt.cipher-mode Name of encryption cipher mode
872
-encrypt.ivgen-alg Name of IV generator algorithm
873
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
874
-encrypt.hash-alg Name of encryption hash algorithm
875
-encrypt.iter-time Time to spend in PBKDF in milliseconds
876
-cluster_size qcow2 cluster size
877
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
878
-lazy_refcounts Postpone refcount updates
879
-refcount_bits Width of a reference count entry in bits
880
+ backing_file=<str> - File name of a base image
881
+ backing_fmt=<str> - Image format of the base image
882
+ cluster_size=<size> - qcow2 cluster size
883
+ compat=<str> - Compatibility level (0.10 or 1.1)
884
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
885
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
886
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
887
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
888
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
889
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
890
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
891
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
892
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
893
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
894
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
895
+ refcount_bits=<num> - Width of a reference count entry in bits
896
+ size=<size> - Virtual disk size
897
898
Note that not all of these options may be amendable.
899
900
Testing: amend -f qcow2 -o ? TEST_DIR/t.qcow2
901
Creation options for 'qcow2':
902
-size Virtual disk size
903
-compat Compatibility level (0.10 or 1.1)
904
-backing_file File name of a base image
905
-backing_fmt Image format of the base image
906
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
907
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
908
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
909
-encrypt.cipher-alg Name of encryption cipher algorithm
910
-encrypt.cipher-mode Name of encryption cipher mode
911
-encrypt.ivgen-alg Name of IV generator algorithm
912
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
913
-encrypt.hash-alg Name of encryption hash algorithm
914
-encrypt.iter-time Time to spend in PBKDF in milliseconds
915
-cluster_size qcow2 cluster size
916
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
917
-lazy_refcounts Postpone refcount updates
918
-refcount_bits Width of a reference count entry in bits
919
+ backing_file=<str> - File name of a base image
920
+ backing_fmt=<str> - Image format of the base image
921
+ cluster_size=<size> - qcow2 cluster size
922
+ compat=<str> - Compatibility level (0.10 or 1.1)
923
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
924
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
925
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
926
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
927
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
928
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
929
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
930
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
931
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
932
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
933
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
934
+ refcount_bits=<num> - Width of a reference count entry in bits
935
+ size=<size> - Virtual disk size
936
937
Note that not all of these options may be amendable.
938
939
Testing: amend -f qcow2 -o cluster_size=4k,help TEST_DIR/t.qcow2
940
Creation options for 'qcow2':
941
-size Virtual disk size
942
-compat Compatibility level (0.10 or 1.1)
943
-backing_file File name of a base image
944
-backing_fmt Image format of the base image
945
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
946
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
947
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
948
-encrypt.cipher-alg Name of encryption cipher algorithm
949
-encrypt.cipher-mode Name of encryption cipher mode
950
-encrypt.ivgen-alg Name of IV generator algorithm
951
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
952
-encrypt.hash-alg Name of encryption hash algorithm
953
-encrypt.iter-time Time to spend in PBKDF in milliseconds
954
-cluster_size qcow2 cluster size
955
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
956
-lazy_refcounts Postpone refcount updates
957
-refcount_bits Width of a reference count entry in bits
958
+ backing_file=<str> - File name of a base image
959
+ backing_fmt=<str> - Image format of the base image
960
+ cluster_size=<size> - qcow2 cluster size
961
+ compat=<str> - Compatibility level (0.10 or 1.1)
962
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
963
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
964
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
965
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
966
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
967
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
968
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
969
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
970
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
971
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
972
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
973
+ refcount_bits=<num> - Width of a reference count entry in bits
974
+ size=<size> - Virtual disk size
975
976
Note that not all of these options may be amendable.
977
978
Testing: amend -f qcow2 -o cluster_size=4k,? TEST_DIR/t.qcow2
979
Creation options for 'qcow2':
980
-size Virtual disk size
981
-compat Compatibility level (0.10 or 1.1)
982
-backing_file File name of a base image
983
-backing_fmt Image format of the base image
984
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
985
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
986
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
987
-encrypt.cipher-alg Name of encryption cipher algorithm
988
-encrypt.cipher-mode Name of encryption cipher mode
989
-encrypt.ivgen-alg Name of IV generator algorithm
990
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
991
-encrypt.hash-alg Name of encryption hash algorithm
992
-encrypt.iter-time Time to spend in PBKDF in milliseconds
993
-cluster_size qcow2 cluster size
994
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
995
-lazy_refcounts Postpone refcount updates
996
-refcount_bits Width of a reference count entry in bits
997
+ backing_file=<str> - File name of a base image
998
+ backing_fmt=<str> - Image format of the base image
999
+ cluster_size=<size> - qcow2 cluster size
1000
+ compat=<str> - Compatibility level (0.10 or 1.1)
1001
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1002
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1003
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1004
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1005
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1006
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1007
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1008
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1009
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1010
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1011
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1012
+ refcount_bits=<num> - Width of a reference count entry in bits
1013
+ size=<size> - Virtual disk size
1014
1015
Note that not all of these options may be amendable.
1016
1017
Testing: amend -f qcow2 -o help,cluster_size=4k TEST_DIR/t.qcow2
1018
Creation options for 'qcow2':
1019
-size Virtual disk size
1020
-compat Compatibility level (0.10 or 1.1)
1021
-backing_file File name of a base image
1022
-backing_fmt Image format of the base image
1023
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1024
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
1025
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
1026
-encrypt.cipher-alg Name of encryption cipher algorithm
1027
-encrypt.cipher-mode Name of encryption cipher mode
1028
-encrypt.ivgen-alg Name of IV generator algorithm
1029
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
1030
-encrypt.hash-alg Name of encryption hash algorithm
1031
-encrypt.iter-time Time to spend in PBKDF in milliseconds
1032
-cluster_size qcow2 cluster size
1033
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
1034
-lazy_refcounts Postpone refcount updates
1035
-refcount_bits Width of a reference count entry in bits
1036
+ backing_file=<str> - File name of a base image
1037
+ backing_fmt=<str> - Image format of the base image
1038
+ cluster_size=<size> - qcow2 cluster size
1039
+ compat=<str> - Compatibility level (0.10 or 1.1)
1040
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1041
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1042
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1043
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1044
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1045
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1046
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1047
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1048
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1049
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1050
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1051
+ refcount_bits=<num> - Width of a reference count entry in bits
1052
+ size=<size> - Virtual disk size
1053
1054
Note that not all of these options may be amendable.
1055
1056
Testing: amend -f qcow2 -o ?,cluster_size=4k TEST_DIR/t.qcow2
1057
Creation options for 'qcow2':
1058
-size Virtual disk size
1059
-compat Compatibility level (0.10 or 1.1)
1060
-backing_file File name of a base image
1061
-backing_fmt Image format of the base image
1062
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1063
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
1064
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
1065
-encrypt.cipher-alg Name of encryption cipher algorithm
1066
-encrypt.cipher-mode Name of encryption cipher mode
1067
-encrypt.ivgen-alg Name of IV generator algorithm
1068
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
1069
-encrypt.hash-alg Name of encryption hash algorithm
1070
-encrypt.iter-time Time to spend in PBKDF in milliseconds
1071
-cluster_size qcow2 cluster size
1072
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
1073
-lazy_refcounts Postpone refcount updates
1074
-refcount_bits Width of a reference count entry in bits
1075
+ backing_file=<str> - File name of a base image
1076
+ backing_fmt=<str> - Image format of the base image
1077
+ cluster_size=<size> - qcow2 cluster size
1078
+ compat=<str> - Compatibility level (0.10 or 1.1)
1079
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1080
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1081
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1082
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1083
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1084
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1085
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1086
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1087
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1088
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1089
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1090
+ refcount_bits=<num> - Width of a reference count entry in bits
1091
+ size=<size> - Virtual disk size
1092
1093
Note that not all of these options may be amendable.
1094
1095
Testing: amend -f qcow2 -o cluster_size=4k -o help TEST_DIR/t.qcow2
1096
Creation options for 'qcow2':
1097
-size Virtual disk size
1098
-compat Compatibility level (0.10 or 1.1)
1099
-backing_file File name of a base image
1100
-backing_fmt Image format of the base image
1101
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1102
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
1103
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
1104
-encrypt.cipher-alg Name of encryption cipher algorithm
1105
-encrypt.cipher-mode Name of encryption cipher mode
1106
-encrypt.ivgen-alg Name of IV generator algorithm
1107
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
1108
-encrypt.hash-alg Name of encryption hash algorithm
1109
-encrypt.iter-time Time to spend in PBKDF in milliseconds
1110
-cluster_size qcow2 cluster size
1111
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
1112
-lazy_refcounts Postpone refcount updates
1113
-refcount_bits Width of a reference count entry in bits
1114
+ backing_file=<str> - File name of a base image
1115
+ backing_fmt=<str> - Image format of the base image
1116
+ cluster_size=<size> - qcow2 cluster size
1117
+ compat=<str> - Compatibility level (0.10 or 1.1)
1118
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1119
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1120
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1121
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1122
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1123
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1124
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1125
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1126
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1127
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1128
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1129
+ refcount_bits=<num> - Width of a reference count entry in bits
1130
+ size=<size> - Virtual disk size
1131
1132
Note that not all of these options may be amendable.
1133
1134
Testing: amend -f qcow2 -o cluster_size=4k -o ? TEST_DIR/t.qcow2
1135
Creation options for 'qcow2':
1136
-size Virtual disk size
1137
-compat Compatibility level (0.10 or 1.1)
1138
-backing_file File name of a base image
1139
-backing_fmt Image format of the base image
1140
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1141
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
1142
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
1143
-encrypt.cipher-alg Name of encryption cipher algorithm
1144
-encrypt.cipher-mode Name of encryption cipher mode
1145
-encrypt.ivgen-alg Name of IV generator algorithm
1146
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
1147
-encrypt.hash-alg Name of encryption hash algorithm
1148
-encrypt.iter-time Time to spend in PBKDF in milliseconds
1149
-cluster_size qcow2 cluster size
1150
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
1151
-lazy_refcounts Postpone refcount updates
1152
-refcount_bits Width of a reference count entry in bits
1153
+ backing_file=<str> - File name of a base image
1154
+ backing_fmt=<str> - Image format of the base image
1155
+ cluster_size=<size> - qcow2 cluster size
1156
+ compat=<str> - Compatibility level (0.10 or 1.1)
1157
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1158
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1159
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1160
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1161
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1162
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1163
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1164
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1165
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1166
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1167
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1168
+ refcount_bits=<num> - Width of a reference count entry in bits
1169
+ size=<size> - Virtual disk size
1170
1171
Note that not all of these options may be amendable.
1172
1173
@@ -XXX,XX +XXX,XX @@ qemu-img: Invalid option list: ,,
1174
1175
Testing: amend -f qcow2 -o help
1176
Creation options for 'qcow2':
1177
-size Virtual disk size
1178
-compat Compatibility level (0.10 or 1.1)
1179
-backing_file File name of a base image
1180
-backing_fmt Image format of the base image
1181
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1182
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
1183
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
1184
-encrypt.cipher-alg Name of encryption cipher algorithm
1185
-encrypt.cipher-mode Name of encryption cipher mode
1186
-encrypt.ivgen-alg Name of IV generator algorithm
1187
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
1188
-encrypt.hash-alg Name of encryption hash algorithm
1189
-encrypt.iter-time Time to spend in PBKDF in milliseconds
1190
-cluster_size qcow2 cluster size
1191
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
1192
-lazy_refcounts Postpone refcount updates
1193
-refcount_bits Width of a reference count entry in bits
1194
+ backing_file=<str> - File name of a base image
1195
+ backing_fmt=<str> - Image format of the base image
1196
+ cluster_size=<size> - qcow2 cluster size
1197
+ compat=<str> - Compatibility level (0.10 or 1.1)
1198
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1199
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1200
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1201
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1202
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1203
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1204
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1205
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1206
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1207
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1208
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1209
+ refcount_bits=<num> - Width of a reference count entry in bits
1210
+ size=<size> - Virtual disk size
1211
1212
Note that not all of these options may be amendable.
1213
1214
Testing: convert -o help
1215
Supported options:
1216
-size Virtual disk size
1217
+ size=<size> - Virtual disk size
1218
1219
Testing: amend -f bochs -o help
1220
qemu-img: Format driver 'bochs' does not support option amendment
1221
--
29
--
1222
2.19.1
30
2.29.2
1223
31
1224
32
diff view generated by jsdifflib
1
From: Li Qiang <liq3ea@163.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
Signed-off-by: Li Qiang <liq3ea@163.com>
3
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
Reviewed-by: Alberto Garcia <berto@igalia.com>
4
Message-Id: <20201027190600.192171-18-mreitz@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
---
6
---
7
include/sysemu/block-backend.h | 6 +++---
7
tests/qemu-iotests/check | 11 +++++++++++
8
block/block-backend.c | 8 ++++----
8
tests/qemu-iotests/common.rc | 17 +++++++++++++++++
9
2 files changed, 7 insertions(+), 7 deletions(-)
9
2 files changed, 28 insertions(+)
10
10
11
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
11
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
12
index XXXXXXX..XXXXXXX 100755
13
--- a/tests/qemu-iotests/check
14
+++ b/tests/qemu-iotests/check
15
@@ -XXX,XX +XXX,XX @@ if [ -z $QEMU_NBD_PROG ]; then
16
fi
17
export QEMU_NBD_PROG="$(type -p "$QEMU_NBD_PROG")"
18
19
+if [ -z "$QSD_PROG" ]; then
20
+ if [ -x "$build_iotests/qemu-storage-daemon" ]; then
21
+ export QSD_PROG="$build_iotests/qemu-storage-daemon"
22
+ elif [ -x "$build_root/storage-daemon/qemu-storage-daemon" ]; then
23
+ export QSD_PROG="$build_root/storage-daemon/qemu-storage-daemon"
24
+ else
25
+ _init_error "qemu-storage-daemon not found"
26
+ fi
27
+fi
28
+export QSD_PROG="$(type -p "$QSD_PROG")"
29
+
30
if [ -x "$build_iotests/socket_scm_helper" ]
31
then
32
export SOCKET_SCM_HELPER="$build_iotests/socket_scm_helper"
33
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
12
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
13
--- a/include/sysemu/block-backend.h
35
--- a/tests/qemu-iotests/common.rc
14
+++ b/include/sysemu/block-backend.h
36
+++ b/tests/qemu-iotests/common.rc
15
@@ -XXX,XX +XXX,XX @@ BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
37
@@ -XXX,XX +XXX,XX @@ fi
16
int error);
38
: ${VALGRIND_QEMU_IMG=$VALGRIND_QEMU}
17
void blk_error_action(BlockBackend *blk, BlockErrorAction action,
39
: ${VALGRIND_QEMU_IO=$VALGRIND_QEMU}
18
bool is_read, int error);
40
: ${VALGRIND_QEMU_NBD=$VALGRIND_QEMU}
19
-int blk_is_read_only(BlockBackend *blk);
41
+: ${VALGRIND_QSD=$VALGRIND_QEMU}
20
-int blk_is_sg(BlockBackend *blk);
42
21
-int blk_enable_write_cache(BlockBackend *blk);
43
# The Valgrind own parameters may be set with
22
+bool blk_is_read_only(BlockBackend *blk);
44
# its environment variable VALGRIND_OPTS, e.g.
23
+bool blk_is_sg(BlockBackend *blk);
45
@@ -XXX,XX +XXX,XX @@ _qemu_nbd_wrapper()
24
+bool blk_enable_write_cache(BlockBackend *blk);
46
return $RETVAL
25
void blk_set_enable_write_cache(BlockBackend *blk, bool wce);
26
void blk_invalidate_cache(BlockBackend *blk, Error **errp);
27
bool blk_is_inserted(BlockBackend *blk);
28
diff --git a/block/block-backend.c b/block/block-backend.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/block/block-backend.c
31
+++ b/block/block-backend.c
32
@@ -XXX,XX +XXX,XX @@ void blk_error_action(BlockBackend *blk, BlockErrorAction action,
33
}
34
}
47
}
35
48
36
-int blk_is_read_only(BlockBackend *blk)
49
+_qemu_storage_daemon_wrapper()
37
+bool blk_is_read_only(BlockBackend *blk)
50
+{
38
{
51
+ local VALGRIND_LOGFILE="${TEST_DIR}"/$$.valgrind
39
BlockDriverState *bs = blk_bs(blk);
52
+ (
40
53
+ if [ -n "${QSD_NEED_PID}" ]; then
41
@@ -XXX,XX +XXX,XX @@ int blk_is_read_only(BlockBackend *blk)
54
+ echo $BASHPID > "${QEMU_TEST_DIR}/qemu-storage-daemon.pid"
42
}
55
+ fi
43
}
56
+ VALGRIND_QEMU="${VALGRIND_QSD}" _qemu_proc_exec "${VALGRIND_LOGFILE}" \
44
57
+ "$QSD_PROG" $QSD_OPTIONS "$@"
45
-int blk_is_sg(BlockBackend *blk)
58
+ )
46
+bool blk_is_sg(BlockBackend *blk)
59
+ RETVAL=$?
47
{
60
+ _qemu_proc_valgrind_log "${VALGRIND_LOGFILE}" $RETVAL
48
BlockDriverState *bs = blk_bs(blk);
61
+ return $RETVAL
49
62
+}
50
if (!bs) {
63
+
51
- return 0;
64
# Valgrind bug #409141 https://bugs.kde.org/show_bug.cgi?id=409141
52
+ return false;
65
# Until valgrind 3.16+ is ubiquitous, we must work around a hang in
53
}
66
# valgrind when issuing sigkill. Disable valgrind for this invocation.
54
67
@@ -XXX,XX +XXX,XX @@ export QEMU=_qemu_wrapper
55
return bdrv_is_sg(bs);
68
export QEMU_IMG=_qemu_img_wrapper
56
}
69
export QEMU_IO=_qemu_io_wrapper
57
70
export QEMU_NBD=_qemu_nbd_wrapper
58
-int blk_enable_write_cache(BlockBackend *blk)
71
+export QSD=_qemu_storage_daemon_wrapper
59
+bool blk_enable_write_cache(BlockBackend *blk)
72
60
{
73
if [ "$IMGOPTSSYNTAX" = "true" ]; then
61
return blk->enable_write_cache;
74
DRIVER="driver=$IMGFMT"
62
}
63
--
75
--
64
2.19.1
76
2.29.2
65
77
66
78
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
Following the example of qemu_opts_print_help(), indent all entries in
3
This pretends FUSE exports are a kind of protocol. As such, they are
4
the list of character devices.
4
always tested under the format node. This is probably the best way to
5
test them, actually, because this will generate more I/O load and more
6
varied patterns.
5
7
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
9
Message-Id: <20201027190600.192171-19-mreitz@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
11
---
10
chardev/char.c | 2 +-
12
tests/qemu-iotests/check | 6 ++
11
1 file changed, 1 insertion(+), 1 deletion(-)
13
tests/qemu-iotests/common.filter | 5 +-
12
14
tests/qemu-iotests/common.rc | 124 +++++++++++++++++++++++++++++++
13
diff --git a/chardev/char.c b/chardev/char.c
15
3 files changed, 134 insertions(+), 1 deletion(-)
16
17
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
18
index XXXXXXX..XXXXXXX 100755
19
--- a/tests/qemu-iotests/check
20
+++ b/tests/qemu-iotests/check
21
@@ -XXX,XX +XXX,XX @@ image protocol options
22
-rbd test rbd
23
-sheepdog test sheepdog
24
-nbd test nbd
25
+ -fuse test fuse
26
-ssh test ssh
27
-nfs test nfs
28
29
@@ -XXX,XX +XXX,XX @@ testlist options
30
xpand=false
31
;;
32
33
+ -fuse)
34
+ IMGPROTO=fuse
35
+ xpand=false
36
+ ;;
37
+
38
-ssh)
39
IMGPROTO=ssh
40
xpand=false
41
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
14
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
15
--- a/chardev/char.c
43
--- a/tests/qemu-iotests/common.filter
16
+++ b/chardev/char.c
44
+++ b/tests/qemu-iotests/common.filter
17
@@ -XXX,XX +XXX,XX @@ help_string_append(const char *name, void *opaque)
45
@@ -XXX,XX +XXX,XX @@ _filter_qom_path()
46
_filter_testdir()
18
{
47
{
19
GString *str = opaque;
48
$SED -e "s#$TEST_DIR/#TEST_DIR/#g" \
20
49
- -e "s#$SOCK_DIR/#SOCK_DIR/#g"
21
- g_string_append_printf(str, "\n%s", name);
50
+ -e "s#$SOCK_DIR/#SOCK_DIR/#g" \
22
+ g_string_append_printf(str, "\n %s", name);
51
+ -e "s#SOCK_DIR/fuse-#TEST_DIR/#g"
23
}
52
}
24
53
25
static const char *chardev_alias_translate(const char *name)
54
# replace occurrences of the actual IMGFMT value with IMGFMT
55
@@ -XXX,XX +XXX,XX @@ _filter_img_create_filenames()
56
-e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \
57
-e "s#$TEST_DIR#TEST_DIR#g" \
58
-e "s#$SOCK_DIR#SOCK_DIR#g" \
59
+ -e 's#SOCK_DIR/fuse-#TEST_DIR/#g' \
60
-e "s#$IMGFMT#IMGFMT#g" \
61
-e 's#nbd:127.0.0.1:[0-9]\\+#TEST_DIR/t.IMGFMT#g' \
62
-e 's#nbd+unix:///\??socket=SOCK_DIR/nbd#TEST_DIR/t.IMGFMT#g'
63
@@ -XXX,XX +XXX,XX @@ _filter_img_info()
64
-e "s#$IMGFMT#IMGFMT#g" \
65
-e 's#nbd://127.0.0.1:[0-9]\\+$#TEST_DIR/t.IMGFMT#g' \
66
-e 's#nbd+unix:///\??socket=SOCK_DIR/nbd#TEST_DIR/t.IMGFMT#g' \
67
+ -e 's#SOCK_DIR/fuse-#TEST_DIR/#g' \
68
-e "/encrypted: yes/d" \
69
-e "/cluster_size: [0-9]\\+/d" \
70
-e "/table_size: [0-9]\\+/d" \
71
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
72
index XXXXXXX..XXXXXXX 100644
73
--- a/tests/qemu-iotests/common.rc
74
+++ b/tests/qemu-iotests/common.rc
75
@@ -XXX,XX +XXX,XX @@ if [ "$IMGOPTSSYNTAX" = "true" ]; then
76
TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
77
TEST_IMG="$DRIVER,file.driver=nbd,file.type=unix"
78
TEST_IMG="$TEST_IMG,file.path=$SOCK_DIR/nbd"
79
+ elif [ "$IMGPROTO" = "fuse" ]; then
80
+ TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
81
+ TEST_IMG="$DRIVER,file.filename=$SOCK_DIR/fuse-t.$IMGFMT"
82
elif [ "$IMGPROTO" = "ssh" ]; then
83
TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
84
TEST_IMG="$DRIVER,file.driver=ssh,file.host=127.0.0.1,file.path=$TEST_IMG_FILE"
85
@@ -XXX,XX +XXX,XX @@ else
86
elif [ "$IMGPROTO" = "nbd" ]; then
87
TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
88
TEST_IMG="nbd+unix:///?socket=$SOCK_DIR/nbd"
89
+ elif [ "$IMGPROTO" = "fuse" ]; then
90
+ TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
91
+ TEST_IMG="$SOCK_DIR/fuse-t.$IMGFMT"
92
elif [ "$IMGPROTO" = "ssh" ]; then
93
TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
94
REMOTE_TEST_DIR="ssh://\\($USER@\\)\\?127.0.0.1\\(:[0-9]\\+\\)\\?$TEST_DIR"
95
@@ -XXX,XX +XXX,XX @@ fi
96
ORIG_TEST_IMG_FILE=$TEST_IMG_FILE
97
ORIG_TEST_IMG="$TEST_IMG"
98
99
+FUSE_PIDS=()
100
+FUSE_EXPORTS=()
101
+
102
if [ -z "$TEST_DIR" ]; then
103
TEST_DIR=$PWD/scratch
104
fi
105
@@ -XXX,XX +XXX,XX @@ _test_img_to_test_img_file()
106
echo "$1"
107
;;
108
109
+ fuse)
110
+ echo "$1" | sed -e "s#$SOCK_DIR/fuse-#$TEST_DIR/#"
111
+ ;;
112
+
113
nfs)
114
echo "$1" | sed -e "s#nfs://127.0.0.1##"
115
;;
116
@@ -XXX,XX +XXX,XX @@ _make_test_img()
117
local opts_param=false
118
local misc_params=()
119
120
+ if [[ $IMGPROTO == fuse && $TEST_IMG == $SOCK_DIR/fuse-* ]]; then
121
+ # The caller may be trying to overwrite an existing image
122
+ _rm_test_img "$TEST_IMG"
123
+ fi
124
+
125
if [ -z "$TEST_IMG_FILE" ]; then
126
img_name=$TEST_IMG
127
elif [ "$IMGOPTSSYNTAX" != "true" -a \
128
@@ -XXX,XX +XXX,XX @@ _make_test_img()
129
eval "$QEMU_NBD -v -t -k '$SOCK_DIR/nbd' -f $IMGFMT -e 42 -x '' $TEST_IMG_FILE >/dev/null &"
130
sleep 1 # FIXME: qemu-nbd needs to be listening before we continue
131
fi
132
+
133
+ if [ $IMGPROTO = "fuse" -a -f "$img_name" ]; then
134
+ local export_mp
135
+ local pid
136
+ local pidfile
137
+ local timeout
138
+
139
+ export_mp=$(echo "$img_name" | sed -e "s#$TEST_DIR/#$SOCK_DIR/fuse-#")
140
+ if ! echo "$export_mp" | grep -q "^$SOCK_DIR"; then
141
+ echo 'Cannot use FUSE exports with images outside of TEST_DIR' >&2
142
+ return 1
143
+ fi
144
+
145
+ touch "$export_mp"
146
+ rm -f "$SOCK_DIR/fuse-output"
147
+
148
+ # Usually, users would export formatted nodes. But we present fuse as a
149
+ # protocol-level driver here, so we have to leave the format to the
150
+ # client.
151
+ QSD_NEED_PID=y $QSD \
152
+ --blockdev file,node-name=export-node,filename=$img_name,discard=unmap \
153
+ --export fuse,id=fuse-export,node-name=export-node,mountpoint="$export_mp",writable=on,growable=on \
154
+ &
155
+
156
+ pidfile="$QEMU_TEST_DIR/qemu-storage-daemon.pid"
157
+
158
+ # Wait for the PID file
159
+ while [ ! -f "$pidfile" ]; do
160
+ sleep 0.5
161
+ done
162
+
163
+ pid=$(cat "$pidfile")
164
+ rm -f "$pidfile"
165
+
166
+ FUSE_PIDS+=($pid)
167
+ FUSE_EXPORTS+=("$export_mp")
168
+ fi
169
}
170
171
_rm_test_img()
172
{
173
local img=$1
174
+
175
+ if [[ $IMGPROTO == fuse && $img == $SOCK_DIR/fuse-* ]]; then
176
+ # Drop a FUSE export
177
+ local df_output
178
+ local i
179
+ local image_file
180
+ local index=''
181
+ local timeout
182
+
183
+ for i in "${!FUSE_EXPORTS[@]}"; do
184
+ if [ "${FUSE_EXPORTS[i]}" = "$img" ]; then
185
+ index=$i
186
+ break
187
+ fi
188
+ done
189
+
190
+ if [ -z "$index" ]; then
191
+ # Probably gone already
192
+ return 0
193
+ fi
194
+
195
+ kill "${FUSE_PIDS[index]}"
196
+
197
+ # Wait until the mount is gone
198
+ timeout=10 # *0.5 s
199
+ while true; do
200
+ # Will show the mount point; if the mount is still there,
201
+ # it will be $img.
202
+ df_output=$(df "$img" 2>/dev/null)
203
+
204
+ # But df may also show an error ("Transpoint endpoint not
205
+ # connected"), so retry in such cases
206
+ if [ -n "$df_output" ]; then
207
+ if ! echo "$df_output" | grep -q "$img"; then
208
+ break
209
+ fi
210
+ fi
211
+
212
+ sleep 0.5
213
+
214
+ timeout=$((timeout - 1))
215
+ if [ "$timeout" = 0 ]; then
216
+ echo 'Failed to take down FUSE export' >&2
217
+ return 1
218
+ fi
219
+ done
220
+
221
+ rm -f "$img"
222
+
223
+ unset "FUSE_PIDS[$index]"
224
+ unset "FUSE_EXPORTS[$index]"
225
+
226
+ image_file=$(echo "$img" | sed -e "s#$SOCK_DIR/fuse-#$TEST_DIR/#")
227
+ _rm_test_img "$image_file"
228
+ return
229
+ fi
230
+
231
if [ "$IMGFMT" = "vmdk" ]; then
232
# Remove all the extents for vmdk
233
"$QEMU_IMG" info "$img" 2>/dev/null | grep 'filename:' | cut -f 2 -d: \
234
@@ -XXX,XX +XXX,XX @@ _cleanup_test_img()
235
rm -f "$TEST_IMG_FILE"
236
;;
237
238
+ fuse)
239
+ local mp
240
+
241
+ for mp in "${FUSE_EXPORTS[@]}"; do
242
+ _rm_test_img "$mp"
243
+ done
244
+
245
+ FUSE_PIDS=()
246
+ FUSE_EXPORTS=()
247
+ ;;
248
+
249
file)
250
_rm_test_img "$TEST_DIR/t.$IMGFMT"
251
_rm_test_img "$TEST_DIR/t.$IMGFMT.orig"
252
@@ -XXX,XX +XXX,XX @@ _img_info()
253
sed -e "s#$REMOTE_TEST_DIR#TEST_DIR#g" \
254
-e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \
255
-e "s#$TEST_DIR#TEST_DIR#g" \
256
+ -e "s#$SOCK_DIR/fuse-#TEST_DIR/#g" \
257
-e "s#$IMGFMT#IMGFMT#g" \
258
-e "/^disk size:/ D" \
259
-e "/actual-size/ D" | \
26
--
260
--
27
2.19.1
261
2.29.2
28
262
29
263
diff view generated by jsdifflib
1
From: Cleber Rosa <crosa@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
While testing the Python 3 changes which touch the 083 test, I noticed
3
Many tests (that do not support generic protocols) can run just fine
4
that it would fail with qcow2. Expanding the testing, I noticed it
4
with FUSE-exported images, so allow them to. Note that this is no
5
had nothing to do with the Python 3 changes, and in fact, it would not
5
attempt at being definitely complete. There are some tests that might
6
pass on anything but raw:
6
be modified to run on FUSE, but this patch still skips them. This patch
7
only tries to pick the rather low-hanging fruits.
7
8
8
raw: pass
9
Note that 221 and 250 only pass when .lseek is correctly implemented,
9
bochs: not generic
10
which is only possible with a libfuse that is 3.8 or newer.
10
cloop: not generic
11
parallels: fail
12
qcow: fail
13
qcow2: fail
14
qed: fail
15
vdi: fail
16
vhdx: fail
17
vmdk: fail
18
vpc: fail
19
luks: fail
20
11
21
The errors are a mixture I/O and "image not in xxx format", such as:
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
22
13
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
23
=== Check disconnect before data ===
14
Message-Id: <20201027190600.192171-20-mreitz@redhat.com>
24
25
Unexpected end-of-file before all bytes were read
26
-read failed: Input/output error
27
+can't open device nbd+tcp://127.0.0.1:PORT/foo: Could not open 'nbd://127.0.0.1:PORT/foo': Input/output error
28
29
=== Check disconnect after data ===
30
31
-read 512/512 bytes at offset 0
32
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
33
+can't open device nbd+tcp://127.0.0.1:PORT/foo: Image not in qcow format
34
35
I'm not aware if there's a quick fix, so, for the time being, it looks
36
like the honest approach is to make the test known to work on raw
37
only.
38
39
Signed-off-by: Cleber Rosa <crosa@redhat.com>
40
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
41
---
16
---
42
tests/qemu-iotests/083 | 2 +-
17
tests/qemu-iotests/025 | 2 +-
43
1 file changed, 1 insertion(+), 1 deletion(-)
18
tests/qemu-iotests/026 | 2 +-
19
tests/qemu-iotests/028 | 2 +-
20
tests/qemu-iotests/031 | 2 +-
21
tests/qemu-iotests/034 | 2 +-
22
tests/qemu-iotests/036 | 2 +-
23
tests/qemu-iotests/037 | 2 +-
24
tests/qemu-iotests/038 | 2 +-
25
tests/qemu-iotests/039 | 2 +-
26
tests/qemu-iotests/046 | 2 +-
27
tests/qemu-iotests/050 | 2 +-
28
tests/qemu-iotests/054 | 2 +-
29
tests/qemu-iotests/060 | 2 +-
30
tests/qemu-iotests/071 | 2 +-
31
tests/qemu-iotests/079 | 2 +-
32
tests/qemu-iotests/080 | 2 +-
33
tests/qemu-iotests/089 | 2 +-
34
tests/qemu-iotests/090 | 2 +-
35
tests/qemu-iotests/091 | 2 +-
36
tests/qemu-iotests/095 | 2 +-
37
tests/qemu-iotests/097 | 2 +-
38
tests/qemu-iotests/098 | 2 +-
39
tests/qemu-iotests/102 | 2 +-
40
tests/qemu-iotests/103 | 2 +-
41
tests/qemu-iotests/106 | 2 +-
42
tests/qemu-iotests/107 | 2 +-
43
tests/qemu-iotests/108 | 2 +-
44
tests/qemu-iotests/111 | 2 +-
45
tests/qemu-iotests/112 | 2 +-
46
tests/qemu-iotests/115 | 2 +-
47
tests/qemu-iotests/117 | 2 +-
48
tests/qemu-iotests/120 | 2 +-
49
tests/qemu-iotests/121 | 2 +-
50
tests/qemu-iotests/127 | 2 +-
51
tests/qemu-iotests/133 | 2 +-
52
tests/qemu-iotests/137 | 2 +-
53
tests/qemu-iotests/138 | 2 +-
54
tests/qemu-iotests/140 | 2 +-
55
tests/qemu-iotests/154 | 2 +-
56
tests/qemu-iotests/161 | 2 +-
57
tests/qemu-iotests/171 | 2 +-
58
tests/qemu-iotests/175 | 2 +-
59
tests/qemu-iotests/176 | 2 +-
60
tests/qemu-iotests/177 | 2 +-
61
tests/qemu-iotests/179 | 2 +-
62
tests/qemu-iotests/183 | 2 +-
63
tests/qemu-iotests/186 | 2 +-
64
tests/qemu-iotests/187 | 2 +-
65
tests/qemu-iotests/191 | 2 +-
66
tests/qemu-iotests/195 | 2 +-
67
tests/qemu-iotests/200 | 2 +-
68
tests/qemu-iotests/204 | 2 +-
69
tests/qemu-iotests/214 | 2 +-
70
tests/qemu-iotests/217 | 2 +-
71
tests/qemu-iotests/220 | 2 +-
72
tests/qemu-iotests/221 | 2 +-
73
tests/qemu-iotests/229 | 2 +-
74
tests/qemu-iotests/247 | 2 +-
75
tests/qemu-iotests/249 | 2 +-
76
tests/qemu-iotests/250 | 2 +-
77
tests/qemu-iotests/252 | 2 +-
78
tests/qemu-iotests/265 | 2 +-
79
tests/qemu-iotests/268 | 2 +-
80
tests/qemu-iotests/272 | 2 +-
81
tests/qemu-iotests/273 | 2 +-
82
tests/qemu-iotests/279 | 2 +-
83
tests/qemu-iotests/286 | 2 +-
84
tests/qemu-iotests/287 | 2 +-
85
tests/qemu-iotests/289 | 2 +-
86
tests/qemu-iotests/290 | 2 +-
87
tests/qemu-iotests/291 | 2 +-
88
tests/qemu-iotests/292 | 2 +-
89
tests/qemu-iotests/293 | 2 +-
90
tests/qemu-iotests/294 | 2 +-
91
tests/qemu-iotests/305 | 2 +-
92
75 files changed, 75 insertions(+), 75 deletions(-)
44
93
45
diff --git a/tests/qemu-iotests/083 b/tests/qemu-iotests/083
94
diff --git a/tests/qemu-iotests/025 b/tests/qemu-iotests/025
46
index XXXXXXX..XXXXXXX 100755
95
index XXXXXXX..XXXXXXX 100755
47
--- a/tests/qemu-iotests/083
96
--- a/tests/qemu-iotests/025
48
+++ b/tests/qemu-iotests/083
97
+++ b/tests/qemu-iotests/025
49
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
98
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
50
. ./common.rc
99
. ./common.pattern
51
. ./common.filter
100
52
101
_supported_fmt raw qcow2 qed luks
53
-_supported_fmt generic
102
-_supported_proto file sheepdog rbd nfs
54
+_supported_fmt raw
103
+_supported_proto file sheepdog rbd nfs fuse
55
_supported_proto nbd
104
56
_supported_os Linux
105
echo "=== Creating image"
106
echo
107
diff --git a/tests/qemu-iotests/026 b/tests/qemu-iotests/026
108
index XXXXXXX..XXXXXXX 100755
109
--- a/tests/qemu-iotests/026
110
+++ b/tests/qemu-iotests/026
111
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
112
113
# Currently only qcow2 supports rebasing
114
_supported_fmt qcow2
115
-_supported_proto file
116
+_supported_proto file fuse
117
_default_cache_mode writethrough
118
_supported_cache_modes writethrough none
119
# The refcount table tests expect a certain minimum width for refcount entries
120
diff --git a/tests/qemu-iotests/028 b/tests/qemu-iotests/028
121
index XXXXXXX..XXXXXXX 100755
122
--- a/tests/qemu-iotests/028
123
+++ b/tests/qemu-iotests/028
124
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
125
# Any format supporting backing files except vmdk and qcow which do not support
126
# smaller backing files.
127
_supported_fmt qcow2 qed
128
-_supported_proto file
129
+_supported_proto file fuse
130
_supported_os Linux
131
132
# Choose a size that is not necessarily a cluster size multiple for image
133
diff --git a/tests/qemu-iotests/031 b/tests/qemu-iotests/031
134
index XXXXXXX..XXXXXXX 100755
135
--- a/tests/qemu-iotests/031
136
+++ b/tests/qemu-iotests/031
137
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
138
139
# This tests qcow2-specific low-level functionality
140
_supported_fmt qcow2
141
-_supported_proto file
142
+_supported_proto file fuse
143
# We want to test compat=0.10, which does not support external data
144
# files or refcount widths other than 16
145
_unsupported_imgopts data_file 'refcount_bits=\([^1]\|.\([^6]\|$\)\)'
146
diff --git a/tests/qemu-iotests/034 b/tests/qemu-iotests/034
147
index XXXXXXX..XXXXXXX 100755
148
--- a/tests/qemu-iotests/034
149
+++ b/tests/qemu-iotests/034
150
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
151
. ./common.filter
152
153
_supported_fmt qcow qcow2 vmdk qed
154
-_supported_proto file
155
+_supported_proto file fuse
156
_supported_os Linux
157
_unsupported_imgopts "subformat=monolithicFlat" \
158
"subformat=twoGbMaxExtentFlat" \
159
diff --git a/tests/qemu-iotests/036 b/tests/qemu-iotests/036
160
index XXXXXXX..XXXXXXX 100755
161
--- a/tests/qemu-iotests/036
162
+++ b/tests/qemu-iotests/036
163
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
164
165
# This tests qcow2-specific low-level functionality
166
_supported_fmt qcow2
167
-_supported_proto file
168
+_supported_proto file fuse
169
# Only qcow2v3 and later supports feature bits;
170
# qcow2.py does not support external data files;
171
# this test requires a cluster size large enough for the feature table
172
diff --git a/tests/qemu-iotests/037 b/tests/qemu-iotests/037
173
index XXXXXXX..XXXXXXX 100755
174
--- a/tests/qemu-iotests/037
175
+++ b/tests/qemu-iotests/037
176
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
177
. ./common.filter
178
179
_supported_fmt qcow qcow2 vmdk qed
180
-_supported_proto file
181
+_supported_proto file fuse
182
_unsupported_imgopts "subformat=monolithicFlat" \
183
"subformat=twoGbMaxExtentFlat" \
184
"subformat=twoGbMaxExtentSparse" \
185
diff --git a/tests/qemu-iotests/038 b/tests/qemu-iotests/038
186
index XXXXXXX..XXXXXXX 100755
187
--- a/tests/qemu-iotests/038
188
+++ b/tests/qemu-iotests/038
189
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
190
. ./common.filter
191
192
_supported_fmt qcow2 qed
193
-_supported_proto file
194
+_supported_proto file fuse
195
_supported_os Linux
196
197
CLUSTER_SIZE=2M
198
diff --git a/tests/qemu-iotests/039 b/tests/qemu-iotests/039
199
index XXXXXXX..XXXXXXX 100755
200
--- a/tests/qemu-iotests/039
201
+++ b/tests/qemu-iotests/039
202
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
203
. ./common.filter
204
205
_supported_fmt qcow2
206
-_supported_proto file
207
+_supported_proto file fuse
208
_supported_os Linux
209
_default_cache_mode writethrough
210
_supported_cache_modes writethrough
211
diff --git a/tests/qemu-iotests/046 b/tests/qemu-iotests/046
212
index XXXXXXX..XXXXXXX 100755
213
--- a/tests/qemu-iotests/046
214
+++ b/tests/qemu-iotests/046
215
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
216
. ./common.filter
217
218
_supported_fmt qcow2
219
-_supported_proto file
220
+_supported_proto file fuse
221
# data_file does not support compressed clusters
222
_unsupported_imgopts data_file
223
224
diff --git a/tests/qemu-iotests/050 b/tests/qemu-iotests/050
225
index XXXXXXX..XXXXXXX 100755
226
--- a/tests/qemu-iotests/050
227
+++ b/tests/qemu-iotests/050
228
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
229
. ./common.filter
230
231
_supported_fmt qcow2 qed
232
-_supported_proto file
233
+_supported_proto file fuse
234
235
echo
236
echo "== Creating images =="
237
diff --git a/tests/qemu-iotests/054 b/tests/qemu-iotests/054
238
index XXXXXXX..XXXXXXX 100755
239
--- a/tests/qemu-iotests/054
240
+++ b/tests/qemu-iotests/054
241
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
242
. ./common.filter
243
244
_supported_fmt qcow2
245
-_supported_proto file
246
+_supported_proto file fuse
247
248
echo
249
echo "creating too large image (1 EB)"
250
diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060
251
index XXXXXXX..XXXXXXX 100755
252
--- a/tests/qemu-iotests/060
253
+++ b/tests/qemu-iotests/060
254
@@ -XXX,XX +XXX,XX @@ _filter_io_error()
255
256
# This tests qcow2-specific low-level functionality
257
_supported_fmt qcow2
258
-_supported_proto file
259
+_supported_proto file fuse
260
_supported_os Linux
261
# These tests only work for compat=1.1 images without an external
262
# data file with refcount_bits=16
263
diff --git a/tests/qemu-iotests/071 b/tests/qemu-iotests/071
264
index XXXXXXX..XXXXXXX 100755
265
--- a/tests/qemu-iotests/071
266
+++ b/tests/qemu-iotests/071
267
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
268
. ./common.filter
269
270
_supported_fmt qcow2
271
-_supported_proto file
272
+_supported_proto file fuse
273
_require_drivers blkdebug blkverify
274
# blkdebug can only inject errors on bs->file, not on the data_file,
275
# so thie test does not work with external data files
276
diff --git a/tests/qemu-iotests/079 b/tests/qemu-iotests/079
277
index XXXXXXX..XXXXXXX 100755
278
--- a/tests/qemu-iotests/079
279
+++ b/tests/qemu-iotests/079
280
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
281
. ./common.filter
282
283
_supported_fmt qcow2
284
-_supported_proto file nfs
285
+_supported_proto file nfs fuse
286
287
# Some containers (e.g. non-x86 on Travis) do not allow large files
288
_require_large_file 4G
289
diff --git a/tests/qemu-iotests/080 b/tests/qemu-iotests/080
290
index XXXXXXX..XXXXXXX 100755
291
--- a/tests/qemu-iotests/080
292
+++ b/tests/qemu-iotests/080
293
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
294
. ./common.filter
295
296
_supported_fmt qcow2
297
-_supported_proto file
298
+_supported_proto file fuse
299
_supported_os Linux
300
# - Internal snapshots are (currently) impossible with refcount_bits=1,
301
# and generally impossible with external data files
302
diff --git a/tests/qemu-iotests/089 b/tests/qemu-iotests/089
303
index XXXXXXX..XXXXXXX 100755
304
--- a/tests/qemu-iotests/089
305
+++ b/tests/qemu-iotests/089
306
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
307
. ./common.filter
308
309
_supported_fmt qcow2
310
-_supported_proto file
311
+_supported_proto file fuse
312
# Because anything other than 16 would change the output of qemu_io -c info
313
_unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)'
314
315
diff --git a/tests/qemu-iotests/090 b/tests/qemu-iotests/090
316
index XXXXXXX..XXXXXXX 100755
317
--- a/tests/qemu-iotests/090
318
+++ b/tests/qemu-iotests/090
319
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
320
. ./common.filter
321
322
_supported_fmt qcow2
323
-_supported_proto file nfs
324
+_supported_proto file nfs fuse
325
# External data files do not support compressed clusters
326
_unsupported_imgopts data_file
327
328
diff --git a/tests/qemu-iotests/091 b/tests/qemu-iotests/091
329
index XXXXXXX..XXXXXXX 100755
330
--- a/tests/qemu-iotests/091
331
+++ b/tests/qemu-iotests/091
332
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
333
. ./common.qemu
334
335
_supported_fmt qcow2
336
-_supported_proto file
337
+_supported_proto file fuse
338
_supported_os Linux
339
_supported_cache_modes writethrough none writeback
340
_default_cache_mode none writeback
341
diff --git a/tests/qemu-iotests/095 b/tests/qemu-iotests/095
342
index XXXXXXX..XXXXXXX 100755
343
--- a/tests/qemu-iotests/095
344
+++ b/tests/qemu-iotests/095
345
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
346
. ./common.qemu
347
348
_supported_fmt qcow2
349
-_supported_proto file
350
+_supported_proto file fuse
351
352
size_smaller=5M
353
size_larger=100M
354
diff --git a/tests/qemu-iotests/097 b/tests/qemu-iotests/097
355
index XXXXXXX..XXXXXXX 100755
356
--- a/tests/qemu-iotests/097
357
+++ b/tests/qemu-iotests/097
358
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
359
360
# Any format supporting backing files and bdrv_make_empty
361
_supported_fmt qcow qcow2
362
-_supported_proto file
363
+_supported_proto file fuse
364
_supported_os Linux
365
366
367
diff --git a/tests/qemu-iotests/098 b/tests/qemu-iotests/098
368
index XXXXXXX..XXXXXXX 100755
369
--- a/tests/qemu-iotests/098
370
+++ b/tests/qemu-iotests/098
371
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
372
. ./common.pattern
373
374
_supported_fmt qcow2
375
-_supported_proto file
376
+_supported_proto file fuse
377
# The code path we want to test here only works for compat=1.1 images;
378
# blkdebug can only inject errors on bs->file, so external data files
379
# do not work with this test
380
diff --git a/tests/qemu-iotests/102 b/tests/qemu-iotests/102
381
index XXXXXXX..XXXXXXX 100755
382
--- a/tests/qemu-iotests/102
383
+++ b/tests/qemu-iotests/102
384
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
385
. ./common.qemu
386
387
_supported_fmt qcow2
388
-_supported_proto file
389
+_supported_proto file fuse
390
391
IMG_SIZE=64K
392
393
diff --git a/tests/qemu-iotests/103 b/tests/qemu-iotests/103
394
index XXXXXXX..XXXXXXX 100755
395
--- a/tests/qemu-iotests/103
396
+++ b/tests/qemu-iotests/103
397
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
398
. ./common.filter
399
400
_supported_fmt qcow2
401
-_supported_proto file nfs
402
+_supported_proto file nfs fuse
403
# Internal snapshots are (currently) impossible with refcount_bits=1,
404
# and generally impossible with external data files
405
_unsupported_imgopts 'refcount_bits=1[^0-9]' data_file
406
diff --git a/tests/qemu-iotests/106 b/tests/qemu-iotests/106
407
index XXXXXXX..XXXXXXX 100755
408
--- a/tests/qemu-iotests/106
409
+++ b/tests/qemu-iotests/106
410
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
411
. ./common.filter
412
413
_supported_fmt raw
414
-_supported_proto file
415
+_supported_proto file fuse
416
_supported_os Linux
417
418
# in kB
419
diff --git a/tests/qemu-iotests/107 b/tests/qemu-iotests/107
420
index XXXXXXX..XXXXXXX 100755
421
--- a/tests/qemu-iotests/107
422
+++ b/tests/qemu-iotests/107
423
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
424
. ./common.filter
425
426
_supported_fmt qcow2
427
-_supported_proto file nfs
428
+_supported_proto file nfs fuse
429
430
431
IMG_SIZE=64K
432
diff --git a/tests/qemu-iotests/108 b/tests/qemu-iotests/108
433
index XXXXXXX..XXXXXXX 100755
434
--- a/tests/qemu-iotests/108
435
+++ b/tests/qemu-iotests/108
436
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
437
438
# This tests qcow2-specific low-level functionality
439
_supported_fmt qcow2
440
-_supported_proto file
441
+_supported_proto file fuse
442
_supported_os Linux
443
# This test directly modifies a refblock so it relies on refcount_bits being 16;
444
# and the low-level modification it performs are not tuned for external data
445
diff --git a/tests/qemu-iotests/111 b/tests/qemu-iotests/111
446
index XXXXXXX..XXXXXXX 100755
447
--- a/tests/qemu-iotests/111
448
+++ b/tests/qemu-iotests/111
449
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
450
. ./common.filter
451
452
_supported_fmt qed qcow qcow2 vmdk
453
-_supported_proto file
454
+_supported_proto file fuse
455
_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat"
456
457
_make_test_img -b "$TEST_IMG.inexistent"
458
diff --git a/tests/qemu-iotests/112 b/tests/qemu-iotests/112
459
index XXXXXXX..XXXXXXX 100755
460
--- a/tests/qemu-iotests/112
461
+++ b/tests/qemu-iotests/112
462
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
463
464
# This tests qcow2-specific low-level functionality
465
_supported_fmt qcow2
466
-_supported_proto file
467
+_supported_proto file fuse
468
# This test will set refcount_bits on its own which would conflict with the
469
# manual setting; compat will be overridden as well;
470
# and external data files do not work well with our refcount testing
471
diff --git a/tests/qemu-iotests/115 b/tests/qemu-iotests/115
472
index XXXXXXX..XXXXXXX 100755
473
--- a/tests/qemu-iotests/115
474
+++ b/tests/qemu-iotests/115
475
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
476
. ./common.filter
477
478
_supported_fmt qcow2
479
-_supported_proto file
480
+_supported_proto file fuse
481
# This test relies on refcounts being 64 bits wide (which does not work with
482
# compat=0.10)
483
_unsupported_imgopts 'refcount_bits=\([^6]\|.\([^4]\|$\)\)' 'compat=0.10'
484
diff --git a/tests/qemu-iotests/117 b/tests/qemu-iotests/117
485
index XXXXXXX..XXXXXXX 100755
486
--- a/tests/qemu-iotests/117
487
+++ b/tests/qemu-iotests/117
488
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
489
. ./common.qemu
490
491
_supported_fmt qcow2
492
-_supported_proto file
493
+_supported_proto file fuse
494
495
_make_test_img 64k
496
497
diff --git a/tests/qemu-iotests/120 b/tests/qemu-iotests/120
498
index XXXXXXX..XXXXXXX 100755
499
--- a/tests/qemu-iotests/120
500
+++ b/tests/qemu-iotests/120
501
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
502
. ./common.filter
503
504
_supported_fmt generic
505
-_supported_proto file
506
+_supported_proto file fuse
507
_unsupported_fmt luks
508
_require_drivers raw
509
510
diff --git a/tests/qemu-iotests/121 b/tests/qemu-iotests/121
511
index XXXXXXX..XXXXXXX 100755
512
--- a/tests/qemu-iotests/121
513
+++ b/tests/qemu-iotests/121
514
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
515
. ./common.filter
516
517
_supported_fmt qcow2
518
-_supported_proto file
519
+_supported_proto file fuse
520
_supported_os Linux
521
# Refcount structures are used much differently with external data
522
# files
523
diff --git a/tests/qemu-iotests/127 b/tests/qemu-iotests/127
524
index XXXXXXX..XXXXXXX 100755
525
--- a/tests/qemu-iotests/127
526
+++ b/tests/qemu-iotests/127
527
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
528
. ./common.qemu
529
530
_supported_fmt qcow2
531
-_supported_proto file
532
+_supported_proto file fuse
533
534
_require_devices virtio-scsi scsi-hd
535
536
diff --git a/tests/qemu-iotests/133 b/tests/qemu-iotests/133
537
index XXXXXXX..XXXXXXX 100755
538
--- a/tests/qemu-iotests/133
539
+++ b/tests/qemu-iotests/133
540
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
541
. ./common.filter
542
543
_supported_fmt qcow2
544
-_supported_proto file
545
+_supported_proto file fuse
546
547
TEST_IMG="$TEST_IMG.base" _make_test_img 64M
548
_make_test_img -b "$TEST_IMG.base" -F $IMGFMT
549
diff --git a/tests/qemu-iotests/137 b/tests/qemu-iotests/137
550
index XXXXXXX..XXXXXXX 100755
551
--- a/tests/qemu-iotests/137
552
+++ b/tests/qemu-iotests/137
553
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
554
. ./common.qemu
555
556
_supported_fmt qcow2
557
-_supported_proto file
558
+_supported_proto file fuse
559
_supported_os Linux
560
# We are going to use lazy-refcounts
561
_unsupported_imgopts 'compat=0.10'
562
diff --git a/tests/qemu-iotests/138 b/tests/qemu-iotests/138
563
index XXXXXXX..XXXXXXX 100755
564
--- a/tests/qemu-iotests/138
565
+++ b/tests/qemu-iotests/138
566
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
567
568
# This tests qcow2-specific low-level functionality
569
_supported_fmt qcow2
570
-_supported_proto file
571
+_supported_proto file fuse
572
_supported_os Linux
573
# With an external data file, data clusters are not refcounted
574
# (so qemu-img check would not do much);
575
diff --git a/tests/qemu-iotests/140 b/tests/qemu-iotests/140
576
index XXXXXXX..XXXXXXX 100755
577
--- a/tests/qemu-iotests/140
578
+++ b/tests/qemu-iotests/140
579
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
580
. ./common.qemu
581
582
_supported_fmt generic
583
-_supported_proto file
584
+_supported_proto file fuse
585
_supported_os Linux
586
587
_make_test_img 64k
588
diff --git a/tests/qemu-iotests/154 b/tests/qemu-iotests/154
589
index XXXXXXX..XXXXXXX 100755
590
--- a/tests/qemu-iotests/154
591
+++ b/tests/qemu-iotests/154
592
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
593
. ./common.filter
594
595
_supported_fmt qcow2
596
-_supported_proto file
597
+_supported_proto file fuse
598
_supported_os Linux
599
600
CLUSTER_SIZE=4k
601
diff --git a/tests/qemu-iotests/161 b/tests/qemu-iotests/161
602
index XXXXXXX..XXXXXXX 100755
603
--- a/tests/qemu-iotests/161
604
+++ b/tests/qemu-iotests/161
605
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
606
607
# Any format implementing BlockDriver.bdrv_change_backing_file
608
_supported_fmt qcow2 qed
609
-_supported_proto file
610
+_supported_proto file fuse
611
_supported_os Linux
612
613
IMG_SIZE=1M
614
diff --git a/tests/qemu-iotests/171 b/tests/qemu-iotests/171
615
index XXXXXXX..XXXXXXX 100755
616
--- a/tests/qemu-iotests/171
617
+++ b/tests/qemu-iotests/171
618
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
619
. ./common.filter
620
621
_supported_fmt raw
622
-_supported_proto file
623
+_supported_proto file fuse
624
_supported_os Linux
625
626
627
diff --git a/tests/qemu-iotests/175 b/tests/qemu-iotests/175
628
index XXXXXXX..XXXXXXX 100755
629
--- a/tests/qemu-iotests/175
630
+++ b/tests/qemu-iotests/175
631
@@ -XXX,XX +XXX,XX @@ EOF
632
. ./common.filter
633
634
_supported_fmt raw
635
-_supported_proto file
636
+_supported_proto file fuse
637
_supported_os Linux
638
639
_default_cache_mode none
640
diff --git a/tests/qemu-iotests/176 b/tests/qemu-iotests/176
641
index XXXXXXX..XXXXXXX 100755
642
--- a/tests/qemu-iotests/176
643
+++ b/tests/qemu-iotests/176
644
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
645
646
# This test is specific to qcow2
647
_supported_fmt qcow2
648
-_supported_proto file
649
+_supported_proto file fuse
650
_supported_os Linux
651
# Persistent dirty bitmaps require compat=1.1;
652
# Internal snapshots forbid using an external data file
653
diff --git a/tests/qemu-iotests/177 b/tests/qemu-iotests/177
654
index XXXXXXX..XXXXXXX 100755
655
--- a/tests/qemu-iotests/177
656
+++ b/tests/qemu-iotests/177
657
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
658
# tests specific to compat=1.1.
659
660
_supported_fmt qcow2
661
-_supported_proto file
662
+_supported_proto file fuse
663
664
CLUSTER_SIZE=1M
665
size=128M
666
diff --git a/tests/qemu-iotests/179 b/tests/qemu-iotests/179
667
index XXXXXXX..XXXXXXX 100755
668
--- a/tests/qemu-iotests/179
669
+++ b/tests/qemu-iotests/179
670
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
671
. ./common.filter
672
673
_supported_fmt qcow2
674
-_supported_proto file
675
+_supported_proto file fuse
676
_supported_os Linux
677
678
# v2 images can't mark clusters as zero
679
diff --git a/tests/qemu-iotests/183 b/tests/qemu-iotests/183
680
index XXXXXXX..XXXXXXX 100755
681
--- a/tests/qemu-iotests/183
682
+++ b/tests/qemu-iotests/183
683
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
684
685
_supported_os Linux FreeBSD NetBSD
686
_supported_fmt qcow2 raw qed quorum
687
-_supported_proto file
688
+_supported_proto file fuse
689
690
size=64M
691
_make_test_img $size
692
diff --git a/tests/qemu-iotests/186 b/tests/qemu-iotests/186
693
index XXXXXXX..XXXXXXX 100755
694
--- a/tests/qemu-iotests/186
695
+++ b/tests/qemu-iotests/186
696
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
697
. ./common.filter
698
699
_supported_fmt qcow2
700
-_supported_proto file
701
+_supported_proto file fuse
702
_require_drivers null-co
703
704
if [ "$QEMU_DEFAULT_MACHINE" != "pc" ]; then
705
diff --git a/tests/qemu-iotests/187 b/tests/qemu-iotests/187
706
index XXXXXXX..XXXXXXX 100755
707
--- a/tests/qemu-iotests/187
708
+++ b/tests/qemu-iotests/187
709
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
710
. ./common.filter
711
712
_supported_fmt qcow2
713
-_supported_proto file
714
+_supported_proto file fuse
715
716
size=64M
717
_make_test_img $size
718
diff --git a/tests/qemu-iotests/191 b/tests/qemu-iotests/191
719
index XXXXXXX..XXXXXXX 100755
720
--- a/tests/qemu-iotests/191
721
+++ b/tests/qemu-iotests/191
722
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
723
. ./common.qemu
724
725
_supported_fmt qcow2
726
-_supported_proto file
727
+_supported_proto file fuse
728
# An external data file would change the query-named-block-nodes output
729
_unsupported_imgopts data_file
730
731
diff --git a/tests/qemu-iotests/195 b/tests/qemu-iotests/195
732
index XXXXXXX..XXXXXXX 100755
733
--- a/tests/qemu-iotests/195
734
+++ b/tests/qemu-iotests/195
735
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
736
. ./common.filter
737
738
_supported_fmt qcow2
739
-_supported_proto file
740
+_supported_proto file fuse
741
742
do_run_qemu()
743
{
744
diff --git a/tests/qemu-iotests/200 b/tests/qemu-iotests/200
745
index XXXXXXX..XXXXXXX 100755
746
--- a/tests/qemu-iotests/200
747
+++ b/tests/qemu-iotests/200
748
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
749
. ./common.qemu
750
751
_supported_fmt qcow2 qed
752
-_supported_proto file
753
+_supported_proto file fuse
754
755
BACKING_IMG="$TEST_IMG.base"
756
757
diff --git a/tests/qemu-iotests/204 b/tests/qemu-iotests/204
758
index XXXXXXX..XXXXXXX 100755
759
--- a/tests/qemu-iotests/204
760
+++ b/tests/qemu-iotests/204
761
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
762
. ./common.filter
763
764
_supported_fmt qcow2
765
-_supported_proto file
766
+_supported_proto file fuse
767
# This test assumes that discard leaves zero clusters; see test 177 for
768
# other tests that also work in older images
769
_unsupported_imgopts 'compat=0.10'
770
diff --git a/tests/qemu-iotests/214 b/tests/qemu-iotests/214
771
index XXXXXXX..XXXXXXX 100755
772
--- a/tests/qemu-iotests/214
773
+++ b/tests/qemu-iotests/214
774
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
775
. ./common.filter
776
777
_supported_fmt qcow2
778
-_supported_proto file
779
+_supported_proto file fuse
780
781
# Repairing the corrupted image requires qemu-img check to store a
782
# refcount up to 3, which requires at least two refcount bits.
783
diff --git a/tests/qemu-iotests/217 b/tests/qemu-iotests/217
784
index XXXXXXX..XXXXXXX 100755
785
--- a/tests/qemu-iotests/217
786
+++ b/tests/qemu-iotests/217
787
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
788
789
# This test is specific to qcow2
790
_supported_fmt qcow2
791
-_supported_proto file
792
+_supported_proto file fuse
793
794
# This test needs clusters with at least a refcount of 2 so that
795
# OFLAG_COPIED is not set. refcount_bits=1 is therefore unsupported.
796
diff --git a/tests/qemu-iotests/220 b/tests/qemu-iotests/220
797
index XXXXXXX..XXXXXXX 100755
798
--- a/tests/qemu-iotests/220
799
+++ b/tests/qemu-iotests/220
800
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
801
. ./common.pattern
802
803
_supported_fmt qcow2
804
-_supported_proto file
805
+_supported_proto file fuse
806
_supported_os Linux
807
# To use a different refcount width but 16 bits we need compat=1.1,
808
# and external data files do not support compressed clusters.
809
diff --git a/tests/qemu-iotests/221 b/tests/qemu-iotests/221
810
index XXXXXXX..XXXXXXX 100755
811
--- a/tests/qemu-iotests/221
812
+++ b/tests/qemu-iotests/221
813
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
814
. ./common.filter
815
816
_supported_fmt raw
817
-_supported_proto file
818
+_supported_proto file fuse
819
_supported_os Linux
820
821
_default_cache_mode writeback
822
diff --git a/tests/qemu-iotests/229 b/tests/qemu-iotests/229
823
index XXXXXXX..XXXXXXX 100755
824
--- a/tests/qemu-iotests/229
825
+++ b/tests/qemu-iotests/229
826
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
827
828
# Needs backing file and backing format support
829
_supported_fmt qcow2 qed
830
-_supported_proto file
831
+_supported_proto file fuse
832
_supported_os Linux
833
# blkdebug can only inject errors on bs->file, so external data files
834
# do not work with this test
835
diff --git a/tests/qemu-iotests/247 b/tests/qemu-iotests/247
836
index XXXXXXX..XXXXXXX 100755
837
--- a/tests/qemu-iotests/247
838
+++ b/tests/qemu-iotests/247
839
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
840
841
# Requires backing files and .bdrv_change_backing_file support
842
_supported_fmt qcow2 qed
843
-_supported_proto file
844
+_supported_proto file fuse
845
846
size=128M
847
848
diff --git a/tests/qemu-iotests/249 b/tests/qemu-iotests/249
849
index XXXXXXX..XXXXXXX 100755
850
--- a/tests/qemu-iotests/249
851
+++ b/tests/qemu-iotests/249
852
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
853
854
# Any format implementing BlockDriver.bdrv_change_backing_file
855
_supported_fmt qcow2 qed
856
-_supported_proto file
857
+_supported_proto file fuse
858
_supported_os Linux
859
860
IMG_SIZE=1M
861
diff --git a/tests/qemu-iotests/250 b/tests/qemu-iotests/250
862
index XXXXXXX..XXXXXXX 100755
863
--- a/tests/qemu-iotests/250
864
+++ b/tests/qemu-iotests/250
865
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
866
. ./common.filter
867
868
_supported_fmt qcow2
869
-_supported_proto file
870
+_supported_proto file fuse
871
_supported_os Linux
872
# This test does not make much sense with external data files
873
_unsupported_imgopts data_file
874
diff --git a/tests/qemu-iotests/252 b/tests/qemu-iotests/252
875
index XXXXXXX..XXXXXXX 100755
876
--- a/tests/qemu-iotests/252
877
+++ b/tests/qemu-iotests/252
878
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
879
# zero cluster support
880
_supported_fmt qcow2
881
_unsupported_imgopts 'compat=0.10'
882
-_supported_proto file
883
+_supported_proto file fuse
884
_supported_os Linux
885
886
CLUSTER_SIZE=65536
887
diff --git a/tests/qemu-iotests/265 b/tests/qemu-iotests/265
888
index XXXXXXX..XXXXXXX 100755
889
--- a/tests/qemu-iotests/265
890
+++ b/tests/qemu-iotests/265
891
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
892
893
# qcow2-specific test
894
_supported_fmt qcow2
895
-_supported_proto file
896
+_supported_proto file fuse
897
_supported_os Linux
898
899
echo '--- Writing to the image ---'
900
diff --git a/tests/qemu-iotests/268 b/tests/qemu-iotests/268
901
index XXXXXXX..XXXXXXX 100755
902
--- a/tests/qemu-iotests/268
903
+++ b/tests/qemu-iotests/268
904
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
905
. ./common.filter
906
907
_supported_fmt qcow2
908
-_supported_proto file
909
+_supported_proto file fuse
910
911
echo
912
echo "== Required alignment larger than cluster size =="
913
diff --git a/tests/qemu-iotests/272 b/tests/qemu-iotests/272
914
index XXXXXXX..XXXXXXX 100755
915
--- a/tests/qemu-iotests/272
916
+++ b/tests/qemu-iotests/272
917
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
918
919
# This is a qcow2 regression test
920
_supported_fmt qcow2
921
-_supported_proto file
922
+_supported_proto file fuse
923
924
# External data files do not support compression;
925
# We need an exact cluster size (2M) and refcount width (2) so we can
926
diff --git a/tests/qemu-iotests/273 b/tests/qemu-iotests/273
927
index XXXXXXX..XXXXXXX 100755
928
--- a/tests/qemu-iotests/273
929
+++ b/tests/qemu-iotests/273
930
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
931
932
# This is a qcow2 regression test
933
_supported_fmt qcow2
934
-_supported_proto file
935
+_supported_proto file fuse
936
_supported_os Linux
937
# External data files would add nodes to the block graph, so it would
938
# not match the reference output
939
diff --git a/tests/qemu-iotests/279 b/tests/qemu-iotests/279
940
index XXXXXXX..XXXXXXX 100755
941
--- a/tests/qemu-iotests/279
942
+++ b/tests/qemu-iotests/279
943
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
944
945
# Backing files are required...
946
_supported_fmt qcow qcow2 vmdk qed
947
-_supported_proto file
948
+_supported_proto file fuse
949
_supported_os Linux
950
_unsupported_imgopts "subformat=monolithicFlat" \
951
"subformat=twoGbMaxExtentFlat" \
952
diff --git a/tests/qemu-iotests/286 b/tests/qemu-iotests/286
953
index XXXXXXX..XXXXXXX 100755
954
--- a/tests/qemu-iotests/286
955
+++ b/tests/qemu-iotests/286
956
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
957
. ./common.qemu
958
959
_supported_fmt qcow2
960
-_supported_proto file
961
+_supported_proto file fuse
962
# Internal snapshots are (currently) impossible with refcount_bits=1,
963
# and generally impossible with external data files
964
_unsupported_imgopts 'refcount_bits=1[^0-9]' data_file
965
diff --git a/tests/qemu-iotests/287 b/tests/qemu-iotests/287
966
index XXXXXXX..XXXXXXX 100755
967
--- a/tests/qemu-iotests/287
968
+++ b/tests/qemu-iotests/287
969
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
970
971
# This tests qocw2-specific low-level functionality
972
_supported_fmt qcow2
973
-_supported_proto file
974
+_supported_proto file fuse
975
_supported_os Linux
976
_unsupported_imgopts 'compat=0.10' data_file
977
978
diff --git a/tests/qemu-iotests/289 b/tests/qemu-iotests/289
979
index XXXXXXX..XXXXXXX 100755
980
--- a/tests/qemu-iotests/289
981
+++ b/tests/qemu-iotests/289
982
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
983
. ./common.pattern
984
985
_supported_fmt qcow2
986
-_supported_proto file
987
+_supported_proto file fuse
988
# This is a v3-exclusive test;
989
# As for data_file, error paths often very much depend on whether
990
# there is an external data file or not; so we create one exactly when
991
diff --git a/tests/qemu-iotests/290 b/tests/qemu-iotests/290
992
index XXXXXXX..XXXXXXX 100755
993
--- a/tests/qemu-iotests/290
994
+++ b/tests/qemu-iotests/290
995
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
996
. ./common.filter
997
998
_supported_fmt qcow2
999
-_supported_proto file
1000
+_supported_proto file fuse
1001
_supported_os Linux
1002
_unsupported_imgopts 'compat=0.10' refcount_bits data_file
1003
1004
diff --git a/tests/qemu-iotests/291 b/tests/qemu-iotests/291
1005
index XXXXXXX..XXXXXXX 100755
1006
--- a/tests/qemu-iotests/291
1007
+++ b/tests/qemu-iotests/291
1008
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
1009
. ./common.nbd
1010
1011
_supported_fmt qcow2
1012
-_supported_proto file
1013
+_supported_proto file fuse
1014
_supported_os Linux
1015
_require_command QEMU_NBD
1016
# compat=0.10 does not support bitmaps
1017
diff --git a/tests/qemu-iotests/292 b/tests/qemu-iotests/292
1018
index XXXXXXX..XXXXXXX 100755
1019
--- a/tests/qemu-iotests/292
1020
+++ b/tests/qemu-iotests/292
1021
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
1022
. ./common.filter
1023
1024
_supported_fmt qcow2
1025
-_supported_proto file
1026
+_supported_proto file fuse
1027
_supported_os Linux
1028
# We need qemu-img map to show the file where the data is allocated,
1029
# but with an external data file, it will show that instead of the
1030
diff --git a/tests/qemu-iotests/293 b/tests/qemu-iotests/293
1031
index XXXXXXX..XXXXXXX 100755
1032
--- a/tests/qemu-iotests/293
1033
+++ b/tests/qemu-iotests/293
1034
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
1035
. ./common.filter
1036
1037
_supported_fmt qcow2 luks
1038
-_supported_proto file #TODO
1039
+_supported_proto file fuse #TODO
1040
_require_working_luks
1041
1042
QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT
1043
diff --git a/tests/qemu-iotests/294 b/tests/qemu-iotests/294
1044
index XXXXXXX..XXXXXXX 100755
1045
--- a/tests/qemu-iotests/294
1046
+++ b/tests/qemu-iotests/294
1047
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
1048
. ./common.filter
1049
1050
_supported_fmt luks
1051
-_supported_proto file #TODO
1052
+_supported_proto file fuse #TODO
1053
1054
QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT
1055
1056
diff --git a/tests/qemu-iotests/305 b/tests/qemu-iotests/305
1057
index XXXXXXX..XXXXXXX 100755
1058
--- a/tests/qemu-iotests/305
1059
+++ b/tests/qemu-iotests/305
1060
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
1061
. ./common.filter
1062
1063
_supported_fmt qcow2
1064
-_supported_proto file
1065
+_supported_proto file fuse
1066
_supported_os Linux
1067
_unsupported_imgopts cluster_size refcount_bits extended_l2 compat=0.10 data_file
57
1068
58
--
1069
--
59
2.19.1
1070
2.29.2
60
1071
61
1072
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
2
3
We have good coverage of the normal I/O paths now, but what remains is a
4
test that tests some more special cases: Exporting an image on itself
5
(thus turning a formatted image into a raw one), some error cases, and
6
non-writable and non-growable exports.
7
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
10
Message-Id: <20201027190600.192171-21-mreitz@redhat.com>
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2
Reviewed-by: Eric Blake <eblake@redhat.com>
3
---
12
---
4
tests/qemu-iotests/232 | 147 +++++++++++++++++++++++++++++++++++++
13
tests/qemu-iotests/308 | 339 +++++++++++++++++++++++++++++++++++++
5
tests/qemu-iotests/232.out | 59 +++++++++++++++
14
tests/qemu-iotests/308.out | 97 +++++++++++
6
tests/qemu-iotests/group | 1 +
15
tests/qemu-iotests/group | 1 +
7
3 files changed, 207 insertions(+)
16
3 files changed, 437 insertions(+)
8
create mode 100755 tests/qemu-iotests/232
17
create mode 100755 tests/qemu-iotests/308
9
create mode 100644 tests/qemu-iotests/232.out
18
create mode 100644 tests/qemu-iotests/308.out
10
19
11
diff --git a/tests/qemu-iotests/232 b/tests/qemu-iotests/232
20
diff --git a/tests/qemu-iotests/308 b/tests/qemu-iotests/308
12
new file mode 100755
21
new file mode 100755
13
index XXXXXXX..XXXXXXX
22
index XXXXXXX..XXXXXXX
14
--- /dev/null
23
--- /dev/null
15
+++ b/tests/qemu-iotests/232
24
+++ b/tests/qemu-iotests/308
16
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@
17
+#!/bin/bash
26
+#!/usr/bin/env bash
18
+#
27
+#
19
+# Test for auto-read-only
28
+# Test FUSE exports (in ways that are not captured by the generic
20
+#
29
+# tests)
21
+# Copyright (C) 2018 Red Hat, Inc.
30
+#
31
+# Copyright (C) 2020 Red Hat, Inc.
22
+#
32
+#
23
+# This program is free software; you can redistribute it and/or modify
33
+# This program is free software; you can redistribute it and/or modify
24
+# it under the terms of the GNU General Public License as published by
34
+# it under the terms of the GNU General Public License as published by
25
+# the Free Software Foundation; either version 2 of the License, or
35
+# the Free Software Foundation; either version 2 of the License, or
26
+# (at your option) any later version.
36
+# (at your option) any later version.
...
...
32
+#
42
+#
33
+# You should have received a copy of the GNU General Public License
43
+# You should have received a copy of the GNU General Public License
34
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
44
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
35
+#
45
+#
36
+
46
+
37
+# creator
47
+seq=$(basename "$0")
38
+owner=kwolf@redhat.com
39
+
40
+seq=`basename $0`
41
+echo "QA output created by $seq"
48
+echo "QA output created by $seq"
42
+
49
+
43
+here=`pwd`
44
+status=1    # failure is the default!
50
+status=1    # failure is the default!
45
+
51
+
46
+_cleanup()
52
+_cleanup()
47
+{
53
+{
54
+ _cleanup_qemu
48
+ _cleanup_test_img
55
+ _cleanup_test_img
49
+ rm -f $TEST_IMG.snap
56
+ rmdir "$EXT_MP" 2>/dev/null
57
+ rm -f "$EXT_MP"
58
+ rm -f "$COPIED_IMG"
50
+}
59
+}
51
+trap "_cleanup; exit \$status" 0 1 2 3 15
60
+trap "_cleanup; exit \$status" 0 1 2 3 15
52
+
61
+
53
+# get standard environment, filters and checks
62
+# get standard environment, filters and checks
54
+. ./common.rc
63
+. ./common.rc
55
+. ./common.filter
64
+. ./common.filter
56
+
65
+. ./common.qemu
66
+
67
+# Generic format, but needs a plain filename
57
+_supported_fmt generic
68
+_supported_fmt generic
58
+_supported_proto file
69
+if [ "$IMGOPTSSYNTAX" = "true" ]; then
59
+_supported_os Linux
70
+ _unsupported_fmt $IMGFMT
60
+
71
+fi
61
+function do_run_qemu()
72
+# We need the image to have exactly the specified size, and VPC does
73
+# not allow that by default
74
+_unsupported_fmt vpc
75
+
76
+_supported_proto file # We create the FUSE export manually
77
+_supported_os Linux # We need /dev/urandom
78
+
79
+# $1: Export ID
80
+# $2: Options (beyond the node-name and ID)
81
+# $3: Expected return value (defaults to 'return')
82
+# $4: Node to export (defaults to 'node-format')
83
+fuse_export_add()
62
+{
84
+{
63
+ echo Testing: "$@"
85
+ _send_qemu_cmd $QEMU_HANDLE \
64
+ (
86
+ "{'execute': 'block-export-add',
65
+ if ! test -t 0; then
87
+ 'arguments': {
66
+ while read cmd; do
88
+ 'type': 'fuse',
67
+ echo $cmd
89
+ 'id': '$1',
68
+ done
90
+ 'node-name': '${4:-node-format}',
69
+ fi
91
+ $2
70
+ echo quit
92
+ } }" \
71
+ ) | $QEMU -nographic -monitor stdio -nodefaults "$@"
93
+ "${3:-return}" \
72
+ echo
94
+ | _filter_imgfmt
73
+}
95
+}
74
+
96
+
75
+function run_qemu()
97
+# $1: Export ID
98
+fuse_export_del()
76
+{
99
+{
77
+ do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_hmp |
100
+ _send_qemu_cmd $QEMU_HANDLE \
78
+ _filter_generated_node_ids | _filter_imgfmt
101
+ "{'execute': 'block-export-del',
102
+ 'arguments': {
103
+ 'id': '$1'
104
+ } }" \
105
+ 'return'
106
+
107
+ _send_qemu_cmd $QEMU_HANDLE \
108
+ '' \
109
+ 'BLOCK_EXPORT_DELETED'
79
+}
110
+}
80
+
111
+
81
+function run_qemu_info_block()
112
+# Return the length of the protocol file
113
+# $1: Protocol node export mount point
114
+# $2: Original file (to compare)
115
+get_proto_len()
82
+{
116
+{
83
+ echo "info block -n" | run_qemu "$@" | grep -e "(file" -e "QEMU_PROG"
117
+ len1=$(stat -c '%s' "$1")
118
+ len2=$(stat -c '%s' "$2")
119
+
120
+ if [ "$len1" != "$len2" ]; then
121
+ echo 'ERROR: Length of export and original differ:' >&2
122
+ echo "$len1 != $len2" >&2
123
+ else
124
+ echo '(OK: Lengths of export and original are the same)' >&2
125
+ fi
126
+
127
+ echo "$len1"
84
+}
128
+}
85
+
129
+
86
+size=128M
130
+COPIED_IMG="$TEST_IMG.copy"
87
+
131
+EXT_MP="$TEST_IMG.fuse"
88
+_make_test_img $size
132
+
89
+
133
+echo '=== Set up ==='
90
+echo
134
+
91
+echo "=== -drive with read-write image: read-only/auto-read-only combinations ==="
135
+# Create image with random data
92
+echo
136
+_make_test_img 64M
93
+
137
+$QEMU_IO -c 'write -s /dev/urandom 0 64M' "$TEST_IMG" | _filter_qemu_io
94
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on,auto-read-only=off
138
+
95
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on,auto-read-only=on
139
+_launch_qemu
96
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on
140
+_send_qemu_cmd $QEMU_HANDLE \
97
+echo
141
+ "{'execute': 'qmp_capabilities'}" \
98
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off,auto-read-only=off
142
+ 'return'
99
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off,auto-read-only=on
143
+
100
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off
144
+# Separate blockdev-add calls for format and protocol so we can remove
101
+echo
145
+# the format layer later on
102
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,auto-read-only=off
146
+_send_qemu_cmd $QEMU_HANDLE \
103
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,auto-read-only=on
147
+ "{'execute': 'blockdev-add',
104
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none
148
+ 'arguments': {
105
+
149
+ 'driver': 'file',
106
+echo
150
+ 'node-name': 'node-protocol',
107
+echo "=== -drive with read-only image: read-only/auto-read-only combinations ==="
151
+ 'filename': '$TEST_IMG'
108
+echo
152
+ } }" \
109
+
153
+ 'return'
110
+chmod a-w $TEST_IMG
154
+
111
+
155
+_send_qemu_cmd $QEMU_HANDLE \
112
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on,auto-read-only=off
156
+ "{'execute': 'blockdev-add',
113
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on,auto-read-only=on
157
+ 'arguments': {
114
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on
158
+ 'driver': '$IMGFMT',
115
+echo
159
+ 'node-name': 'node-format',
116
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off,auto-read-only=off
160
+ 'file': 'node-protocol'
117
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off,auto-read-only=on
161
+ } }" \
118
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off
162
+ 'return'
119
+echo
163
+
120
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,auto-read-only=off
164
+echo
121
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,auto-read-only=on
165
+echo '=== Mountpoint not present ==='
122
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none
166
+
123
+
167
+rmdir "$EXT_MP" 2>/dev/null
124
+echo
168
+rm -f "$EXT_MP"
125
+echo "=== -blockdev with read-write image: read-only/auto-read-only combinations ==="
169
+output=$(fuse_export_add 'export-err' "'mountpoint': '$EXT_MP'" error)
126
+echo
170
+
127
+
171
+if echo "$output" | grep -q "Invalid parameter 'fuse'"; then
128
+chmod a+w $TEST_IMG
172
+ _notrun 'No FUSE support'
129
+
173
+fi
130
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on,auto-read-only=off
174
+
131
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on,auto-read-only=on
175
+echo "$output"
132
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on
176
+
133
+echo
177
+echo
134
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off,auto-read-only=off
178
+echo '=== Mountpoint is a directory ==='
135
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off,auto-read-only=on
179
+
136
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off
180
+mkdir "$EXT_MP"
137
+echo
181
+fuse_export_add 'export-err' "'mountpoint': '$EXT_MP'" error
138
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,auto-read-only=off
182
+rmdir "$EXT_MP"
139
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,auto-read-only=on
183
+
140
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0
184
+echo
141
+
185
+echo '=== Mountpoint is a regular file ==='
142
+echo
186
+
143
+echo "=== -blockdev with read-only image: read-only/auto-read-only combinations ==="
187
+touch "$EXT_MP"
144
+echo
188
+fuse_export_add 'export-mp' "'mountpoint': '$EXT_MP'"
145
+
189
+
146
+chmod a-w $TEST_IMG
190
+# Check that the export presents the same data as the original image
147
+
191
+$QEMU_IMG compare -f raw -F $IMGFMT -U "$EXT_MP" "$TEST_IMG"
148
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on,auto-read-only=off
192
+
149
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on,auto-read-only=on
193
+echo
150
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on
194
+echo '=== Mount over existing file ==='
151
+echo
195
+
152
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off,auto-read-only=off
196
+# This is the coolest feature of FUSE exports: You can transparently
153
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off,auto-read-only=on
197
+# make images in any format appear as raw images
154
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off
198
+fuse_export_add 'export-img' "'mountpoint': '$TEST_IMG'"
155
+echo
199
+
156
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,auto-read-only=off
200
+# Accesses both exports at the same time, so we get a concurrency test
157
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,auto-read-only=on
201
+$QEMU_IMG compare -f raw -F raw -U "$EXT_MP" "$TEST_IMG"
158
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0
202
+
203
+# Just to be sure, we later want to compare the data offline. Also,
204
+# this allows us to see that cp works without complaining.
205
+# (This is not a given, because cp will expect a short read at EOF.
206
+# Internally, qemu does not allow short reads, so we have to check
207
+# whether the FUSE export driver lets them work.)
208
+cp "$TEST_IMG" "$COPIED_IMG"
209
+
210
+# $TEST_IMG will be in mode 0400 because it is read-only; we are going
211
+# to write to the copy, so make it writable
212
+chmod 0600 "$COPIED_IMG"
213
+
214
+echo
215
+echo '=== Double export ==='
216
+
217
+# We have already seen that exporting a node twice works fine, but you
218
+# cannot export anything twice on the same mount point. The reason is
219
+# that qemu has to stat the given mount point, and this would have to
220
+# be answered by the same qemu instance if it already has an export
221
+# there. However, it cannot answer the stat because it is itself
222
+# caught up in that same stat.
223
+fuse_export_add 'export-err' "'mountpoint': '$EXT_MP'" error
224
+
225
+echo
226
+echo '=== Remove export ==='
227
+
228
+# Double-check that $EXT_MP appears as a non-empty file (the raw image)
229
+$QEMU_IMG info -f raw "$EXT_MP" | grep 'virtual size'
230
+
231
+fuse_export_del 'export-mp'
232
+
233
+# See that the file appears empty again
234
+$QEMU_IMG info -f raw "$EXT_MP" | grep 'virtual size'
235
+
236
+echo
237
+echo '=== Writable export ==='
238
+
239
+fuse_export_add 'export-mp' "'mountpoint': '$EXT_MP', 'writable': true"
240
+
241
+# Check that writing to the read-only export fails
242
+$QEMU_IO -f raw -c 'write -P 42 1M 64k' "$TEST_IMG" | _filter_qemu_io
243
+
244
+# But here it should work
245
+$QEMU_IO -f raw -c 'write -P 42 1M 64k' "$EXT_MP" | _filter_qemu_io
246
+
247
+# (Adjust the copy, too)
248
+$QEMU_IO -f raw -c 'write -P 42 1M 64k' "$COPIED_IMG" | _filter_qemu_io
249
+
250
+echo
251
+echo '=== Resizing exports ==='
252
+
253
+# Here, we need to export the protocol node -- the format layer may
254
+# not be growable, simply because the format does not support it.
255
+
256
+# Remove all exports and the format node first so permissions will not
257
+# get in the way
258
+fuse_export_del 'export-mp'
259
+fuse_export_del 'export-img'
260
+
261
+_send_qemu_cmd $QEMU_HANDLE \
262
+ "{'execute': 'blockdev-del',
263
+ 'arguments': {
264
+ 'node-name': 'node-format'
265
+ } }" \
266
+ 'return'
267
+
268
+# Now export the protocol node
269
+fuse_export_add \
270
+ 'export-mp' \
271
+ "'mountpoint': '$EXT_MP', 'writable': true" \
272
+ 'return' \
273
+ 'node-protocol'
274
+
275
+echo
276
+echo '--- Try growing non-growable export ---'
277
+
278
+# Get the current size so we can write beyond the EOF
279
+orig_len=$(get_proto_len "$EXT_MP" "$TEST_IMG")
280
+orig_disk_usage=$(stat -c '%b' "$TEST_IMG")
281
+
282
+# Should fail (exports are non-growable by default)
283
+# (Note that qemu-io can never write beyond the EOF, so we have to use
284
+# dd here)
285
+dd if=/dev/zero of="$EXT_MP" bs=1 count=64k seek=$orig_len 2>&1 \
286
+ | _filter_testdir | _filter_imgfmt
287
+
288
+echo
289
+echo '--- Resize export ---'
290
+
291
+# But we can truncate it explicitly; even with fallocate
292
+fallocate -o "$orig_len" -l 64k "$EXT_MP"
293
+
294
+new_len=$(get_proto_len "$EXT_MP" "$TEST_IMG")
295
+if [ "$new_len" != "$((orig_len + 65536))" ]; then
296
+ echo 'ERROR: Unexpected post-truncate image size:'
297
+ echo "$new_len != $((orig_len + 65536))"
298
+else
299
+ echo 'OK: Post-truncate image size is as expected'
300
+fi
301
+
302
+new_disk_usage=$(stat -c '%b' "$TEST_IMG")
303
+if [ "$new_disk_usage" -gt "$orig_disk_usage" ]; then
304
+ echo 'OK: Disk usage grew with fallocate'
305
+else
306
+ echo 'ERROR: Disk usage did not grow despite fallocate:'
307
+ echo "$orig_disk_usage => $new_disk_usage"
308
+fi
309
+
310
+echo
311
+echo '--- Try growing growable export ---'
312
+
313
+# Now export as growable
314
+fuse_export_del 'export-mp'
315
+fuse_export_add \
316
+ 'export-mp' \
317
+ "'mountpoint': '$EXT_MP', 'writable': true, 'growable': true" \
318
+ 'return' \
319
+ 'node-protocol'
320
+
321
+# Now we should be able to write beyond the EOF
322
+dd if=/dev/zero of="$EXT_MP" bs=1 count=64k seek=$new_len 2>&1 \
323
+ | _filter_testdir | _filter_imgfmt
324
+
325
+new_len=$(get_proto_len "$EXT_MP" "$TEST_IMG")
326
+if [ "$new_len" != "$((orig_len + 131072))" ]; then
327
+ echo 'ERROR: Unexpected post-grow image size:'
328
+ echo "$new_len != $((orig_len + 131072))"
329
+else
330
+ echo 'OK: Post-grow image size is as expected'
331
+fi
332
+
333
+echo
334
+echo '--- Shrink export ---'
335
+
336
+# Now go back to the original size
337
+truncate -s "$orig_len" "$EXT_MP"
338
+
339
+new_len=$(get_proto_len "$EXT_MP" "$TEST_IMG")
340
+if [ "$new_len" != "$orig_len" ]; then
341
+ echo 'ERROR: Unexpected post-truncate image size:'
342
+ echo "$new_len != $orig_len"
343
+else
344
+ echo 'OK: Post-truncate image size is as expected'
345
+fi
346
+
347
+echo
348
+echo '=== Tear down ==='
349
+
350
+_send_qemu_cmd $QEMU_HANDLE \
351
+ "{'execute': 'quit'}" \
352
+ 'return'
353
+
354
+wait=yes _cleanup_qemu
355
+
356
+echo
357
+echo '=== Compare copy with original ==='
358
+
359
+$QEMU_IMG compare -f raw -F $IMGFMT "$COPIED_IMG" "$TEST_IMG"
159
+
360
+
160
+# success, all done
361
+# success, all done
161
+echo "*** done"
362
+echo "*** done"
162
+rm -f $seq.full
363
+rm -f $seq.full
163
+status=0
364
+status=0
164
diff --git a/tests/qemu-iotests/232.out b/tests/qemu-iotests/232.out
365
diff --git a/tests/qemu-iotests/308.out b/tests/qemu-iotests/308.out
165
new file mode 100644
366
new file mode 100644
166
index XXXXXXX..XXXXXXX
367
index XXXXXXX..XXXXXXX
167
--- /dev/null
368
--- /dev/null
168
+++ b/tests/qemu-iotests/232.out
369
+++ b/tests/qemu-iotests/308.out
169
@@ -XXX,XX +XXX,XX @@
370
@@ -XXX,XX +XXX,XX @@
170
+QA output created by 232
371
+QA output created by 308
171
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
372
+=== Set up ===
172
+
373
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
173
+=== -drive with read-write image: read-only/auto-read-only combinations ===
374
+wrote 67108864/67108864 bytes at offset 0
174
+
375
+64 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
175
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
376
+{'execute': 'qmp_capabilities'}
176
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
377
+{"return": {}}
177
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
378
+{'execute': 'blockdev-add', 'arguments': { 'driver': 'file', 'node-name': 'node-protocol', 'filename': 'TEST_DIR/t.IMGFMT' } }
178
+
379
+{"return": {}}
179
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
380
+{'execute': 'blockdev-add', 'arguments': { 'driver': 'IMGFMT', 'node-name': 'node-format', 'file': 'node-protocol' } }
180
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
381
+{"return": {}}
181
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
382
+
182
+
383
+=== Mountpoint not present ===
183
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
384
+{'execute': 'block-export-add', 'arguments': { 'type': 'fuse', 'id': 'export-err', 'node-name': 'node-format', 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse' } }
184
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
385
+{"error": {"class": "GenericError", "desc": "Failed to stat 'TEST_DIR/t.IMGFMT.fuse': No such file or directory"}}
185
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
386
+
186
+
387
+=== Mountpoint is a directory ===
187
+=== -drive with read-only image: read-only/auto-read-only combinations ===
388
+{'execute': 'block-export-add', 'arguments': { 'type': 'fuse', 'id': 'export-err', 'node-name': 'node-format', 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse' } }
188
+
389
+{"error": {"class": "GenericError", "desc": "'TEST_DIR/t.IMGFMT.fuse' is not a regular file"}}
189
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
390
+
190
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
391
+=== Mountpoint is a regular file ===
191
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
392
+{'execute': 'block-export-add', 'arguments': { 'type': 'fuse', 'id': 'export-mp', 'node-name': 'node-format', 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse' } }
192
+
393
+{"return": {}}
193
+QEMU_PROG: -drive driver=file,file=TEST_DIR/t.IMGFMT,if=none,read-only=off,auto-read-only=off: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
394
+Images are identical.
194
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
395
+
195
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
396
+=== Mount over existing file ===
196
+
397
+{'execute': 'block-export-add', 'arguments': { 'type': 'fuse', 'id': 'export-img', 'node-name': 'node-format', 'mountpoint': 'TEST_DIR/t.IMGFMT' } }
197
+QEMU_PROG: -drive driver=file,file=TEST_DIR/t.IMGFMT,if=none,auto-read-only=off: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
398
+{"return": {}}
198
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
399
+Images are identical.
199
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
400
+
200
+
401
+=== Double export ===
201
+=== -blockdev with read-write image: read-only/auto-read-only combinations ===
402
+{'execute': 'block-export-add', 'arguments': { 'type': 'fuse', 'id': 'export-err', 'node-name': 'node-format', 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse' } }
202
+
403
+{"error": {"class": "GenericError", "desc": "There already is a FUSE export on 'TEST_DIR/t.IMGFMT.fuse'"}}
203
+node0: TEST_DIR/t.IMGFMT (file, read-only)
404
+
204
+node0: TEST_DIR/t.IMGFMT (file, read-only)
405
+=== Remove export ===
205
+node0: TEST_DIR/t.IMGFMT (file, read-only)
406
+virtual size: 64 MiB (67108864 bytes)
206
+
407
+{'execute': 'block-export-del', 'arguments': { 'id': 'export-mp' } }
207
+node0: TEST_DIR/t.IMGFMT (file)
408
+{"return": {}}
208
+node0: TEST_DIR/t.IMGFMT (file)
409
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "export-mp"}}
209
+node0: TEST_DIR/t.IMGFMT (file)
410
+virtual size: 0 B (0 bytes)
210
+
411
+
211
+node0: TEST_DIR/t.IMGFMT (file)
412
+=== Writable export ===
212
+node0: TEST_DIR/t.IMGFMT (file)
413
+{'execute': 'block-export-add', 'arguments': { 'type': 'fuse', 'id': 'export-mp', 'node-name': 'node-format', 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse', 'writable': true } }
213
+node0: TEST_DIR/t.IMGFMT (file)
414
+{"return": {}}
214
+
415
+write failed: Permission denied
215
+=== -blockdev with read-only image: read-only/auto-read-only combinations ===
416
+wrote 65536/65536 bytes at offset 1048576
216
+
417
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
217
+node0: TEST_DIR/t.IMGFMT (file, read-only)
418
+wrote 65536/65536 bytes at offset 1048576
218
+node0: TEST_DIR/t.IMGFMT (file, read-only)
419
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
219
+node0: TEST_DIR/t.IMGFMT (file, read-only)
420
+
220
+
421
+=== Resizing exports ===
221
+QEMU_PROG: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0,read-only=off,auto-read-only=off: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
422
+{'execute': 'block-export-del', 'arguments': { 'id': 'export-mp' } }
222
+node0: TEST_DIR/t.IMGFMT (file, read-only)
423
+{"return": {}}
223
+QEMU_PROG: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0,read-only=off: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
424
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "export-mp"}}
224
+
425
+{'execute': 'block-export-del', 'arguments': { 'id': 'export-img' } }
225
+QEMU_PROG: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0,auto-read-only=off: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
426
+{"return": {}}
226
+node0: TEST_DIR/t.IMGFMT (file, read-only)
427
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "export-img"}}
227
+QEMU_PROG: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
428
+{'execute': 'blockdev-del', 'arguments': { 'node-name': 'node-format' } }
429
+{"return": {}}
430
+{'execute': 'block-export-add', 'arguments': { 'type': 'fuse', 'id': 'export-mp', 'node-name': 'node-protocol', 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse', 'writable': true } }
431
+{"return": {}}
432
+
433
+--- Try growing non-growable export ---
434
+(OK: Lengths of export and original are the same)
435
+dd: error writing 'TEST_DIR/t.IMGFMT.fuse': Input/output error
436
+1+0 records in
437
+0+0 records out
438
+
439
+--- Resize export ---
440
+(OK: Lengths of export and original are the same)
441
+OK: Post-truncate image size is as expected
442
+OK: Disk usage grew with fallocate
443
+
444
+--- Try growing growable export ---
445
+{'execute': 'block-export-del', 'arguments': { 'id': 'export-mp' } }
446
+{"return": {}}
447
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "export-mp"}}
448
+{'execute': 'block-export-add', 'arguments': { 'type': 'fuse', 'id': 'export-mp', 'node-name': 'node-protocol', 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse', 'writable': true, 'growable': true } }
449
+{"return": {}}
450
+65536+0 records in
451
+65536+0 records out
452
+(OK: Lengths of export and original are the same)
453
+OK: Post-grow image size is as expected
454
+
455
+--- Shrink export ---
456
+(OK: Lengths of export and original are the same)
457
+OK: Post-truncate image size is as expected
458
+
459
+=== Tear down ===
460
+{'execute': 'quit'}
461
+{"return": {}}
462
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
463
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "export-mp"}}
464
+
465
+=== Compare copy with original ===
466
+Images are identical.
228
+*** done
467
+*** done
229
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
468
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
230
index XXXXXXX..XXXXXXX 100644
469
index XXXXXXX..XXXXXXX 100644
231
--- a/tests/qemu-iotests/group
470
--- a/tests/qemu-iotests/group
232
+++ b/tests/qemu-iotests/group
471
+++ b/tests/qemu-iotests/group
233
@@ -XXX,XX +XXX,XX @@
472
@@ -XXX,XX +XXX,XX @@
234
227 auto quick
473
304 rw quick
235
229 auto quick
474
305 rw quick
236
231 auto quick
475
307 rw quick export
237
+232 auto quick
476
+308 rw
477
309 rw auto quick
238
--
478
--
239
2.19.1
479
2.29.2
240
480
241
481
diff view generated by jsdifflib
1
If read-only=off, but auto-read-only=on is given, open the file
1
From: Li Feng <fengli@smartx.com>
2
read-write if we have the permissions, but instead of erroring out for
3
read-only files, just degrade to read-only.
4
2
3
The scenario is that when accessing a volume on an NFS filesystem
4
without supporting the file lock, Qemu will complain "Failed to lock
5
byte 100", even when setting the file.locking = off.
6
7
We should do file lock related operations only when the file.locking is
8
enabled, otherwise, the syscall of 'fcntl' will return non-zero.
9
10
Signed-off-by: Li Feng <fengli@smartx.com>
11
Message-Id: <1607341446-85506-1-git-send-email-fengli@smartx.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
7
---
13
---
8
block/file-posix.c | 19 ++++++++++++++++---
14
block/file-posix.c | 2 +-
9
1 file changed, 16 insertions(+), 3 deletions(-)
15
1 file changed, 1 insertion(+), 1 deletion(-)
10
16
11
diff --git a/block/file-posix.c b/block/file-posix.c
17
diff --git a/block/file-posix.c b/block/file-posix.c
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/block/file-posix.c
19
--- a/block/file-posix.c
14
+++ b/block/file-posix.c
20
+++ b/block/file-posix.c
15
@@ -XXX,XX +XXX,XX @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
21
@@ -XXX,XX +XXX,XX @@ static int raw_check_perm(BlockDriverState *bs, uint64_t perm, uint64_t shared,
16
22
}
17
s->fd = -1;
23
18
fd = qemu_open(filename, s->open_flags, 0644);
24
/* Copy locks to the new fd */
19
- if (fd < 0) {
25
- if (s->perm_change_fd) {
20
- ret = -errno;
26
+ if (s->perm_change_fd && s->use_lock) {
21
- error_setg_errno(errp, errno, "Could not open '%s'", filename);
27
ret = raw_apply_lock_bytes(NULL, s->perm_change_fd, perm, ~shared,
22
+ ret = fd < 0 ? -errno : 0;
28
false, errp);
23
+
29
if (ret < 0) {
24
+ if (ret == -EACCES || ret == -EROFS) {
25
+ /* Try to degrade to read-only, but if it doesn't work, still use the
26
+ * normal error message. */
27
+ if (bdrv_apply_auto_read_only(bs, NULL, NULL) == 0) {
28
+ bdrv_flags &= ~BDRV_O_RDWR;
29
+ raw_parse_flags(bdrv_flags, &s->open_flags);
30
+ assert(!(s->open_flags & O_CREAT));
31
+ fd = qemu_open(filename, s->open_flags);
32
+ ret = fd < 0 ? -errno : 0;
33
+ }
34
+ }
35
+
36
+ if (ret < 0) {
37
+ error_setg_errno(errp, -ret, "Could not open '%s'", filename);
38
if (ret == -EROFS) {
39
ret = -EACCES;
40
}
41
--
30
--
42
2.19.1
31
2.29.2
43
32
44
33
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
Signed-off-by: Alberto Garcia <berto@igalia.com>
3
See the new comment for why this should be done.
4
5
I do not have a reproducer on master, but when using FUSE block exports,
6
this test breaks depending on the underlying filesystem (for me, it
7
works on tmpfs, but fails on xfs, because the block allocated by
8
file-posix has 16 kB there instead of 4 kB).
9
10
Suggested-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
Message-Id: <20201207152245.66987-1-mreitz@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
---
14
---
6
tests/qemu-iotests/081 | 30 ++++++++++++++++++++++++++++++
15
tests/qemu-iotests/221 | 7 +++++++
7
tests/qemu-iotests/081.out | 16 ++++++++++++++++
16
tests/qemu-iotests/221.out | 14 ++++++--------
8
2 files changed, 46 insertions(+)
17
2 files changed, 13 insertions(+), 8 deletions(-)
9
18
10
diff --git a/tests/qemu-iotests/081 b/tests/qemu-iotests/081
19
diff --git a/tests/qemu-iotests/221 b/tests/qemu-iotests/221
11
index XXXXXXX..XXXXXXX 100755
20
index XXXXXXX..XXXXXXX 100755
12
--- a/tests/qemu-iotests/081
21
--- a/tests/qemu-iotests/221
13
+++ b/tests/qemu-iotests/081
22
+++ b/tests/qemu-iotests/221
14
@@ -XXX,XX +XXX,XX @@ echo "== checking that quorum is broken =="
23
@@ -XXX,XX +XXX,XX @@ echo "=== Check mapping of unaligned raw image ==="
15
24
echo
16
$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
25
17
26
_make_test_img 65537 # qemu-img create rounds size up
18
+echo
19
+echo "== checking the blkverify mode with broken content =="
20
+
27
+
21
+quorum="driver=raw,file.driver=quorum,file.vote-threshold=2,file.blkverify=on"
28
+# file-posix allocates the first block of any images when it is created;
22
+quorum="$quorum,file.children.0.file.filename=$TEST_DIR/1.raw"
29
+# the size of this block depends on the host page size and the file
23
+quorum="$quorum,file.children.1.file.filename=$TEST_DIR/2.raw"
30
+# system block size, none of which are constant. Discard the whole
24
+quorum="$quorum,file.children.0.driver=raw"
31
+# image so we will not see this allocation in qemu-img map's output.
25
+quorum="$quorum,file.children.1.driver=raw"
32
+$QEMU_IO -c 'discard 0 65537' "$TEST_IMG" | _filter_qemu_io
26
+
33
+
27
+$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
34
$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
28
+
35
29
+echo
36
truncate --size=65537 "$TEST_IMG" # so we resize it and check again
30
+echo "== writing the same data to both files =="
37
diff --git a/tests/qemu-iotests/221.out b/tests/qemu-iotests/221.out
31
+
32
+$QEMU_IO -c "write -P 0x32 0 $size" "$TEST_DIR/1.raw" | _filter_qemu_io
33
+$QEMU_IO -c "write -P 0x32 0 $size" "$TEST_DIR/2.raw" | _filter_qemu_io
34
+
35
+echo
36
+echo "== checking the blkverify mode with valid content =="
37
+
38
+$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
39
+
40
+echo
41
+echo "== checking the blkverify mode with invalid settings =="
42
+
43
+quorum="$quorum,file.children.2.file.filename=$TEST_DIR/3.raw"
44
+quorum="$quorum,file.children.2.driver=raw"
45
+
46
+$QEMU_IO -c "open -o $quorum" | _filter_qemu_io
47
+
48
# success, all done
49
echo "*** done"
50
rm -f $seq.full
51
diff --git a/tests/qemu-iotests/081.out b/tests/qemu-iotests/081.out
52
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
53
--- a/tests/qemu-iotests/081.out
39
--- a/tests/qemu-iotests/221.out
54
+++ b/tests/qemu-iotests/081.out
40
+++ b/tests/qemu-iotests/221.out
55
@@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 0
41
@@ -XXX,XX +XXX,XX @@ QA output created by 221
56
42
=== Check mapping of unaligned raw image ===
57
== checking that quorum is broken ==
43
58
read failed: Input/output error
44
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=65537
59
+
45
-[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
60
+== checking the blkverify mode with broken content ==
46
-{ "start": 4096, "length": 61952, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
61
+quorum: offset=0 bytes=10485760 contents mismatch at offset 0
47
-[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
62
+
48
-{ "start": 4096, "length": 61952, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
63
+== writing the same data to both files ==
49
+discard 65537/65537 bytes at offset 0
64
+wrote 10485760/10485760 bytes at offset 0
50
+64.001 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
65
+10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
51
+[{ "start": 0, "length": 66048, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
66
+wrote 10485760/10485760 bytes at offset 0
52
+[{ "start": 0, "length": 66048, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
67
+10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
53
wrote 1/1 bytes at offset 65536
68
+
54
1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
69
+== checking the blkverify mode with valid content ==
55
-[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
70
+read 10485760/10485760 bytes at offset 0
56
-{ "start": 4096, "length": 61440, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
71
+10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
57
+[{ "start": 0, "length": 65536, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
72
+
58
{ "start": 65536, "length": 1, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
73
+== checking the blkverify mode with invalid settings ==
59
{ "start": 65537, "length": 511, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
74
+can't open: blkverify=on can only be set if there are exactly two files and vote-threshold is 2
60
-[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
61
-{ "start": 4096, "length": 61440, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
62
+[{ "start": 0, "length": 65536, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
63
{ "start": 65536, "length": 1, "depth": 0, "zero": false, "data": true, "offset": OFFSET},
64
{ "start": 65537, "length": 511, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
75
*** done
65
*** done
76
--
66
--
77
2.19.1
67
2.29.2
78
68
79
69
diff view generated by jsdifflib
1
If read-only=off, but auto-read-only=on is given, open the file
1
Providing the 'if' property, but not 'canbus' segfaults like this:
2
read-write if we have the permissions, but instead of erroring out for
2
3
read-only files, just degrade to read-only.
3
#0 0x0000555555b0f14d in can_bus_insert_client (bus=0x0, client=0x555556aa9af0) at ../net/can/can_core.c:88
4
#1 0x00005555559c3803 in can_host_connect (ch=0x555556aa9ac0, errp=0x7fffffffd568) at ../net/can/can_host.c:62
5
#2 0x00005555559c386a in can_host_complete (uc=0x555556aa9ac0, errp=0x7fffffffd568) at ../net/can/can_host.c:72
6
#3 0x0000555555d52de9 in user_creatable_complete (uc=0x555556aa9ac0, errp=0x7fffffffd5c8) at ../qom/object_interfaces.c:23
7
8
Add the missing NULL check.
4
9
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Niels de Vos <ndevos@redhat.com>
11
Message-Id: <20201130105615.21799-5-kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
13
---
8
block/gluster.c | 12 ++++++++++--
14
net/can/can_host.c | 5 +++++
9
1 file changed, 10 insertions(+), 2 deletions(-)
15
1 file changed, 5 insertions(+)
10
16
11
diff --git a/block/gluster.c b/block/gluster.c
17
diff --git a/net/can/can_host.c b/net/can/can_host.c
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/block/gluster.c
19
--- a/net/can/can_host.c
14
+++ b/block/gluster.c
20
+++ b/net/can/can_host.c
15
@@ -XXX,XX +XXX,XX @@ static int qemu_gluster_open(BlockDriverState *bs, QDict *options,
21
@@ -XXX,XX +XXX,XX @@ static void can_host_connect(CanHostState *ch, Error **errp)
16
qemu_gluster_parse_flags(bdrv_flags, &open_flags);
22
CanHostClass *chc = CAN_HOST_GET_CLASS(ch);
17
23
Error *local_err = NULL;
18
s->fd = glfs_open(s->glfs, gconf->path, open_flags);
24
19
- if (!s->fd) {
25
+ if (ch->bus == NULL) {
20
- ret = -errno;
26
+ error_setg(errp, "'canbus' property not set");
21
+ ret = s->fd ? 0 : -errno;
27
+ return;
28
+ }
22
+
29
+
23
+ if (ret == -EACCES || ret == -EROFS) {
30
chc->connect(ch, &local_err);
24
+ /* Try to degrade to read-only, but if it doesn't work, still use the
31
if (local_err) {
25
+ * normal error message. */
32
error_propagate(errp, local_err);
26
+ if (bdrv_apply_auto_read_only(bs, NULL, NULL) == 0) {
27
+ open_flags = (open_flags & ~O_RDWR) | O_RDONLY;
28
+ s->fd = glfs_open(s->glfs, gconf->path, open_flags);
29
+ ret = s->fd ? 0 : -errno;
30
+ }
31
}
32
33
s->supports_seek_data = qemu_gluster_test_seek(s->fd);
34
--
33
--
35
2.19.1
34
2.29.2
36
35
37
36
diff view generated by jsdifflib
1
From: Stefan Weil <sw@weilnetz.de>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
Use %zu instead of %zd for unsigned numbers.
3
We should not set overlap_bytes:
4
4
5
This fixes two error messages from the LSTM static code analyzer:
5
1. Don't worry: it is calculated by bdrv_mark_request_serialising() and
6
will be equal to or greater than bytes anyway.
6
7
7
This argument should be of type 'ssize_t' but is of type 'unsigned long'
8
2. If the request was already aligned up to some greater alignment,
9
than we may break things: we reduce overlap_bytes, and further
10
bdrv_mark_request_serialising() may not help, as it will not restore
11
old bigger alignment.
8
12
9
Signed-off-by: Stefan Weil <sw@weilnetz.de>
13
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-Id: <20201203222713.13507-2-vsementsov@virtuozzo.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
16
---
13
qemu-io-cmds.c | 4 ++--
17
block/file-posix.c | 1 -
14
1 file changed, 2 insertions(+), 2 deletions(-)
18
1 file changed, 1 deletion(-)
15
19
16
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
20
diff --git a/block/file-posix.c b/block/file-posix.c
17
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
18
--- a/qemu-io-cmds.c
22
--- a/block/file-posix.c
19
+++ b/qemu-io-cmds.c
23
+++ b/block/file-posix.c
20
@@ -XXX,XX +XXX,XX @@ static int readv_f(BlockBackend *blk, int argc, char **argv)
24
@@ -XXX,XX +XXX,XX @@ raw_do_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int bytes,
21
memset(cmp_buf, pattern, qiov.size);
25
22
if (memcmp(buf, cmp_buf, qiov.size)) {
26
end = INT64_MAX & -(uint64_t)bs->bl.request_alignment;
23
printf("Pattern verification failed at offset %"
27
req->bytes = end - req->offset;
24
- PRId64 ", %zd bytes\n", offset, qiov.size);
28
- req->overlap_bytes = req->bytes;
25
+ PRId64 ", %zu bytes\n", offset, qiov.size);
29
26
ret = -EINVAL;
30
bdrv_mark_request_serialising(req, bs->bl.request_alignment);
27
}
28
g_free(cmp_buf);
29
@@ -XXX,XX +XXX,XX @@ static void aio_read_done(void *opaque, int ret)
30
memset(cmp_buf, ctx->pattern, ctx->qiov.size);
31
if (memcmp(ctx->buf, cmp_buf, ctx->qiov.size)) {
32
printf("Pattern verification failed at offset %"
33
- PRId64 ", %zd bytes\n", ctx->offset, ctx->qiov.size);
34
+ PRId64 ", %zu bytes\n", ctx->offset, ctx->qiov.size);
35
}
36
g_free(cmp_buf);
37
}
31
}
38
--
32
--
39
2.19.1
33
2.29.2
40
34
41
35
diff view generated by jsdifflib
1
From: Daniel P. Berrangé <berrange@redhat.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
The qcow2 block driver expects to see a valid sector size even when it
3
This simplifies following commit.
4
has opened the crypto layer with QCRYPTO_BLOCK_OPEN_NO_IO.
5
4
6
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
5
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
Message-Id: <20201203222713.13507-3-vsementsov@virtuozzo.com>
7
Reviewed-by: Alberto Garcia <berto@igalia.com>
7
Reviewed-by: Alberto Garcia <berto@igalia.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
9
---
10
crypto/block-qcow.c | 2 ++
10
block/io.c | 7 +++----
11
1 file changed, 2 insertions(+)
11
1 file changed, 3 insertions(+), 4 deletions(-)
12
12
13
diff --git a/crypto/block-qcow.c b/crypto/block-qcow.c
13
diff --git a/block/io.c b/block/io.c
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/crypto/block-qcow.c
15
--- a/block/io.c
16
+++ b/crypto/block-qcow.c
16
+++ b/block/io.c
17
@@ -XXX,XX +XXX,XX @@ qcrypto_block_qcow_open(QCryptoBlock *block,
17
@@ -XXX,XX +XXX,XX @@ static void bdrv_merge_limits(BlockLimits *dst, const BlockLimits *src)
18
Error **errp)
18
19
void bdrv_refresh_limits(BlockDriverState *bs, Error **errp)
19
{
20
{
20
if (flags & QCRYPTO_BLOCK_OPEN_NO_IO) {
21
+ ERRP_GUARD();
21
+ block->sector_size = QCRYPTO_BLOCK_QCOW_SECTOR_SIZE;
22
BlockDriver *drv = bs->drv;
22
+ block->payload_offset = 0;
23
BdrvChild *c;
23
return 0;
24
bool have_limits;
24
} else {
25
- Error *local_err = NULL;
25
if (!options->u.qcow.key_secret) {
26
27
memset(&bs->bl, 0, sizeof(bs->bl));
28
29
@@ -XXX,XX +XXX,XX @@ void bdrv_refresh_limits(BlockDriverState *bs, Error **errp)
30
QLIST_FOREACH(c, &bs->children, next) {
31
if (c->role & (BDRV_CHILD_DATA | BDRV_CHILD_FILTERED | BDRV_CHILD_COW))
32
{
33
- bdrv_refresh_limits(c->bs, &local_err);
34
- if (local_err) {
35
- error_propagate(errp, local_err);
36
+ bdrv_refresh_limits(c->bs, errp);
37
+ if (*errp) {
38
return;
39
}
40
bdrv_merge_limits(&bs->bl, &c->bs->bl);
26
--
41
--
27
2.19.1
42
2.29.2
28
43
29
44
diff view generated by jsdifflib
Deleted patch
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2
Reviewed-by: Alberto Garcia <berto@igalia.com>
3
---
4
block/vpc.c | 2 ++
5
1 file changed, 2 insertions(+)
6
1
7
diff --git a/block/vpc.c b/block/vpc.c
8
index XXXXXXX..XXXXXXX 100644
9
--- a/block/vpc.c
10
+++ b/block/vpc.c
11
@@ -XXX,XX +XXX,XX @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
12
}
13
14
qemu_co_mutex_init(&s->lock);
15
+ qemu_opts_del(opts);
16
17
return 0;
18
19
fail:
20
+ qemu_opts_del(opts);
21
qemu_vfree(s->pagetable);
22
#ifdef CACHE
23
g_free(s->pageentry_u8);
24
--
25
2.19.1
26
27
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
This is a static function with only one caller, so there's no need to
3
Move bdrv_is_inserted() calls into callers.
4
keep it. Inlining the code in quorum_compare() makes it much simpler.
5
4
6
Signed-off-by: Alberto Garcia <berto@igalia.com>
5
We are going to make bdrv_check_byte_request() a clean thing.
7
Reported-by: Markus Armbruster <armbru@redhat.com>
6
bdrv_is_inserted() is not about checking the request, it's about
7
checking the bs. So, it should be separate.
8
9
With this patch we probably change error path for some failure
10
scenarios. But depending on the fact that querying too big request on
11
empty cdrom (or corrupted qcow2 node with no drv) will result in EIO
12
and not ENOMEDIUM would be very strange. More over, we are going to
13
move to 64bit requests, so larger requests will be allowed anyway.
14
15
More over, keeping in mind that cdrom is the only driver that has
16
.bdrv_is_inserted() handler it's strange that we should care so much
17
about it in generic block layer, intuitively we should just do read and
18
write, and cdrom driver should return correct errors if it is not
19
inserted. But it's a work for another series.
20
21
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
22
Message-Id: <20201203222713.13507-4-vsementsov@virtuozzo.com>
23
Reviewed-by: Alberto Garcia <berto@igalia.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
24
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
25
---
10
block/quorum.c | 24 +++++-------------------
26
block/io.c | 25 ++++++++++++-------------
11
1 file changed, 5 insertions(+), 19 deletions(-)
27
1 file changed, 12 insertions(+), 13 deletions(-)
12
28
13
diff --git a/block/quorum.c b/block/quorum.c
29
diff --git a/block/io.c b/block/io.c
14
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
15
--- a/block/quorum.c
31
--- a/block/io.c
16
+++ b/block/quorum.c
32
+++ b/block/io.c
17
@@ -XXX,XX +XXX,XX @@ static bool quorum_iovec_compare(QEMUIOVector *a, QEMUIOVector *b)
33
@@ -XXX,XX +XXX,XX @@ static bool coroutine_fn bdrv_wait_serialising_requests(BdrvTrackedRequest *self
18
return true;
34
return waited;
19
}
35
}
20
36
21
-static void GCC_FMT_ATTR(2, 3) quorum_err(QuorumAIOCB *acb,
37
-static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset,
22
- const char *fmt, ...)
38
- size_t size)
23
-{
39
+static int bdrv_check_byte_request(int64_t offset, size_t size)
24
- va_list ap;
40
{
41
if (size > BDRV_REQUEST_MAX_BYTES) {
42
return -EIO;
43
}
44
45
- if (!bdrv_is_inserted(bs)) {
46
- return -ENOMEDIUM;
47
- }
25
-
48
-
26
- va_start(ap, fmt);
49
if (offset < 0) {
27
- fprintf(stderr, "quorum: offset=%" PRIu64 " bytes=%" PRIu64 " ",
50
return -EIO;
28
- acb->offset, acb->bytes);
51
}
29
- vfprintf(stderr, fmt, ap);
52
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_preadv_part(BdrvChild *child,
30
- fprintf(stderr, "\n");
53
31
- va_end(ap);
54
trace_bdrv_co_preadv(bs, offset, bytes, flags);
32
- exit(1);
55
33
-}
56
- ret = bdrv_check_byte_request(bs, offset, bytes);
34
-
57
+ if (!bdrv_is_inserted(bs)) {
35
-static bool quorum_compare(QuorumAIOCB *acb,
58
+ return -ENOMEDIUM;
36
- QEMUIOVector *a,
59
+ }
37
- QEMUIOVector *b)
60
+
38
+static bool quorum_compare(QuorumAIOCB *acb, QEMUIOVector *a, QEMUIOVector *b)
61
+ ret = bdrv_check_byte_request(offset, bytes);
39
{
62
if (ret < 0) {
40
BDRVQuorumState *s = acb->bs->opaque;
63
return ret;
41
ssize_t offset;
64
}
42
@@ -XXX,XX +XXX,XX @@ static bool quorum_compare(QuorumAIOCB *acb,
65
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwritev_part(BdrvChild *child,
43
if (s->is_blkverify) {
66
44
offset = qemu_iovec_compare(a, b);
67
trace_bdrv_co_pwritev(child->bs, offset, bytes, flags);
45
if (offset != -1) {
68
46
- quorum_err(acb, "contents mismatch at offset %" PRIu64,
69
- if (!bs->drv) {
47
- acb->offset + offset);
70
+ if (!bdrv_is_inserted(bs)) {
48
+ fprintf(stderr, "quorum: offset=%" PRIu64 " bytes=%" PRIu64
71
return -ENOMEDIUM;
49
+ " contents mismatch at offset %" PRIu64 "\n",
72
}
50
+ acb->offset, acb->bytes, acb->offset + offset);
73
51
+ exit(1);
74
- ret = bdrv_check_byte_request(bs, offset, bytes);
52
}
75
+ ret = bdrv_check_byte_request(offset, bytes);
53
return true;
76
if (ret < 0) {
77
return ret;
78
}
79
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_copy_range_internal(
80
assert(!(read_flags & BDRV_REQ_NO_FALLBACK));
81
assert(!(write_flags & BDRV_REQ_NO_FALLBACK));
82
83
- if (!dst || !dst->bs) {
84
+ if (!dst || !dst->bs || !bdrv_is_inserted(dst->bs)) {
85
return -ENOMEDIUM;
86
}
87
- ret = bdrv_check_byte_request(dst->bs, dst_offset, bytes);
88
+ ret = bdrv_check_byte_request(dst_offset, bytes);
89
if (ret) {
90
return ret;
91
}
92
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_copy_range_internal(
93
return bdrv_co_pwrite_zeroes(dst, dst_offset, bytes, write_flags);
94
}
95
96
- if (!src || !src->bs) {
97
+ if (!src || !src->bs || !bdrv_is_inserted(src->bs)) {
98
return -ENOMEDIUM;
99
}
100
- ret = bdrv_check_byte_request(src->bs, src_offset, bytes);
101
+ ret = bdrv_check_byte_request(src_offset, bytes);
102
if (ret) {
103
return ret;
54
}
104
}
55
--
105
--
56
2.19.1
106
2.29.2
57
107
58
108
diff view generated by jsdifflib
1
Some block drivers have traditionally changed their node to read-only
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
mode without asking the user. This behaviour has been marked deprecated
2
3
since 2.11, expecting users to provide an explicit read-only=on option.
3
We are going to modify block layer to work with 64bit requests. And
4
4
first step is moving to int64_t type for both offset and bytes
5
Now that we have auto-read-only=on, enable these drivers to make use of
5
arguments in all block request related functions.
6
the option.
6
7
7
It's mostly safe (when widening signed or unsigned int to int64_t), but
8
This is the only use of bdrv_set_read_only(), so we can make it a bit
8
switching from uint64_t is questionable.
9
more specific and turn it into a bdrv_apply_auto_read_only() that is
9
10
more convenient for drivers to use.
10
So, let's first establish the set of requests we want to work with.
11
11
First signed int64_t should be enough, as off_t is signed anyway. Then,
12
obviously offset + bytes should not overflow.
13
14
And most interesting: (offset + bytes) being aligned up should not
15
overflow as well. Aligned to what alignment? First thing that comes in
16
mind is bs->bl.request_alignment, as we align up request to this
17
alignment. But there is another thing: look at
18
bdrv_mark_request_serialising(). It aligns request up to some given
19
alignment. And this parameter may be bdrv_get_cluster_size(), which is
20
often a lot greater than bs->bl.request_alignment.
21
Note also, that bdrv_mark_request_serialising() uses signed int64_t for
22
calculations. So, actually, we already depend on some restrictions.
23
24
Happily, bdrv_get_cluster_size() returns int and
25
bs->bl.request_alignment has 32bit unsigned type, but defined to be a
26
power of 2 less than INT_MAX. So, we may establish, that INT_MAX is
27
absolute maximum for any kind of alignment that may occur with the
28
request.
29
30
Note, that bdrv_get_cluster_size() is not documented to return power
31
of 2, still bdrv_mark_request_serialising() behaves like it is.
32
Also, backup uses bdi.cluster_size and is not prepared to it not being
33
power of 2.
34
So, let's establish that Qemu supports only power-of-2 clusters and
35
alignments.
36
37
So, alignment can't be greater than 2^30.
38
39
Finally to be safe with calculations, to not calculate different
40
maximums for different nodes (depending on cluster size and
41
request_alignment), let's simply set QEMU_ALIGN_DOWN(INT64_MAX, 2^30)
42
as absolute maximum bytes length for Qemu. Actually, it's not much less
43
than INT64_MAX.
44
45
OK, then, let's apply it to block/io.
46
47
Let's consider all block/io entry points of offset/bytes:
48
49
4 bytes/offset interface functions: bdrv_co_preadv_part(),
50
bdrv_co_pwritev_part(), bdrv_co_copy_range_internal() and
51
bdrv_co_pdiscard() and we check them all with bdrv_check_request().
52
53
We also have one entry point with only offset: bdrv_co_truncate().
54
Check the offset.
55
56
And one public structure: BdrvTrackedRequest. Happily, it has only
57
three external users:
58
59
file-posix.c: adopted by this patch
60
write-threshold.c: only read fields
61
test-write-threshold.c: sets obviously small constant values
62
63
Better is to make the structure private and add corresponding
64
interfaces.. Still it's not obvious what kind of interface is needed
65
for file-posix.c. Let's keep it public but add corresponding
66
assertions.
67
68
After this patch we'll convert functions in block/io.c to int64_t bytes
69
and offset parameters. We can assume that offset/bytes pair always
70
satisfy new restrictions, and make
71
corresponding assertions where needed. If we reach some offset/bytes
72
point in block/io.c missing bdrv_check_request() it is considered a
73
bug. As well, if block/io.c modifies a offset/bytes request, expanding
74
it more then aligning up to request_alignment, it's a bug too.
75
76
For all io requests except for discard we keep for now old restriction
77
of 32bit request length.
78
79
iotest 206 output error message changed, as now test disk size is
80
larger than new limit. Add one more test case with new maximum disk
81
size to cover too-big-L1 case.
82
83
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
84
Message-Id: <20201203222713.13507-5-vsementsov@virtuozzo.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
85
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Reviewed-by: Eric Blake <eblake@redhat.com>
14
---
86
---
15
include/block/block.h | 3 ++-
87
include/block/block.h | 10 +++++++
16
block.c | 42 +++++++++++++++++++++++++++---------------
88
include/block/block_int.h | 8 ++++++
17
block/bochs.c | 17 ++++++-----------
89
block.c | 17 +++++++++++-
18
block/cloop.c | 16 +++++-----------
90
block/file-posix.c | 6 ++---
19
block/dmg.c | 16 +++++-----------
91
block/io.c | 51 +++++++++++++++++++++++++++++-------
20
block/rbd.c | 15 ++++-----------
92
tests/test-write-threshold.c | 4 +++
21
block/vvfat.c | 10 ++--------
93
tests/qemu-iotests/206 | 2 +-
22
7 files changed, 51 insertions(+), 68 deletions(-)
94
tests/qemu-iotests/206.out | 6 +++++
95
8 files changed, 90 insertions(+), 14 deletions(-)
23
96
24
diff --git a/include/block/block.h b/include/block/block.h
97
diff --git a/include/block/block.h b/include/block/block.h
25
index XXXXXXX..XXXXXXX 100644
98
index XXXXXXX..XXXXXXX 100644
26
--- a/include/block/block.h
99
--- a/include/block/block.h
27
+++ b/include/block/block.h
100
+++ b/include/block/block.h
28
@@ -XXX,XX +XXX,XX @@ int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
101
@@ -XXX,XX +XXX,XX @@ typedef struct HDGeometry {
29
bool bdrv_is_read_only(BlockDriverState *bs);
102
INT_MAX >> BDRV_SECTOR_BITS)
30
int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
103
#define BDRV_REQUEST_MAX_BYTES (BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS)
31
bool ignore_allow_rdw, Error **errp);
104
32
-int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp);
105
+/*
33
+int bdrv_apply_auto_read_only(BlockDriverState *bs, const char *errmsg,
106
+ * We want allow aligning requests and disk length up to any 32bit alignment
34
+ Error **errp);
107
+ * and don't afraid of overflow.
35
bool bdrv_is_writable(BlockDriverState *bs);
108
+ * To achieve it, and in the same time use some pretty number as maximum disk
36
bool bdrv_is_sg(BlockDriverState *bs);
109
+ * size, let's define maximum "length" (a limit for any offset/bytes request and
37
bool bdrv_is_inserted(BlockDriverState *bs);
110
+ * for disk size) to be the greatest power of 2 less than INT64_MAX.
111
+ */
112
+#define BDRV_MAX_ALIGNMENT (1L << 30)
113
+#define BDRV_MAX_LENGTH (QEMU_ALIGN_DOWN(INT64_MAX, BDRV_MAX_ALIGNMENT))
114
+
115
/*
116
* Allocation status flags for bdrv_block_status() and friends.
117
*
118
diff --git a/include/block/block_int.h b/include/block/block_int.h
119
index XXXXXXX..XXXXXXX 100644
120
--- a/include/block/block_int.h
121
+++ b/include/block/block_int.h
122
@@ -XXX,XX +XXX,XX @@ enum BdrvTrackedRequestType {
123
BDRV_TRACKED_TRUNCATE,
124
};
125
126
+/*
127
+ * That is not quite good that BdrvTrackedRequest structure is public,
128
+ * as block/io.c is very careful about incoming offset/bytes being
129
+ * correct. Be sure to assert bdrv_check_request() succeeded after any
130
+ * modification of BdrvTrackedRequest object out of block/io.c
131
+ */
132
typedef struct BdrvTrackedRequest {
133
BlockDriverState *bs;
134
int64_t offset;
135
@@ -XXX,XX +XXX,XX @@ typedef struct BdrvTrackedRequest {
136
struct BdrvTrackedRequest *waiting_for;
137
} BdrvTrackedRequest;
138
139
+int bdrv_check_request(int64_t offset, int64_t bytes);
140
+
141
struct BlockDriver {
142
const char *format_name;
143
int instance_size;
38
diff --git a/block.c b/block.c
144
diff --git a/block.c b/block.c
39
index XXXXXXX..XXXXXXX 100644
145
index XXXXXXX..XXXXXXX 100644
40
--- a/block.c
146
--- a/block.c
41
+++ b/block.c
147
+++ b/block.c
42
@@ -XXX,XX +XXX,XX @@ int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
148
@@ -XXX,XX +XXX,XX @@ int refresh_total_sectors(BlockDriverState *bs, int64_t hint)
149
}
150
151
bs->total_sectors = hint;
152
+
153
+ if (bs->total_sectors * BDRV_SECTOR_SIZE > BDRV_MAX_LENGTH) {
154
+ return -EFBIG;
155
+ }
156
+
43
return 0;
157
return 0;
44
}
158
}
45
159
46
-/* TODO Remove (deprecated since 2.11)
160
@@ -XXX,XX +XXX,XX @@ void bdrv_get_backing_filename(BlockDriverState *bs,
47
- * Block drivers are not supposed to automatically change bs->read_only.
161
48
- * Instead, they should just check whether they can provide what the user
162
int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
49
- * explicitly requested and error out if read-write is requested, but they can
50
- * only provide read-only access. */
51
-int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
52
+/*
53
+ * Called by a driver that can only provide a read-only image.
54
+ *
55
+ * Returns 0 if the node is already read-only or it could switch the node to
56
+ * read-only because BDRV_O_AUTO_RDONLY is set.
57
+ *
58
+ * Returns -EACCES if the node is read-write and BDRV_O_AUTO_RDONLY is not set
59
+ * or bdrv_can_set_read_only() forbids making the node read-only. If @errmsg
60
+ * is not NULL, it is used as the error message for the Error object.
61
+ */
62
+int bdrv_apply_auto_read_only(BlockDriverState *bs, const char *errmsg,
63
+ Error **errp)
64
{
163
{
65
int ret = 0;
164
+ int ret;
66
165
BlockDriver *drv = bs->drv;
67
- ret = bdrv_can_set_read_only(bs, read_only, false, errp);
166
/* if bs->drv == NULL, bs is closed, so there's nothing to do here */
68
- if (ret < 0) {
167
if (!drv) {
69
- return ret;
168
@@ -XXX,XX +XXX,XX @@ int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
70
+ if (!(bs->open_flags & BDRV_O_RDWR)) {
169
return -ENOTSUP;
71
+ return 0;
170
}
72
+ }
171
memset(bdi, 0, sizeof(*bdi));
73
+ if (!(bs->open_flags & BDRV_O_AUTO_RDONLY)) {
172
- return drv->bdrv_get_info(bs, bdi);
74
+ goto fail;
173
+ ret = drv->bdrv_get_info(bs, bdi);
75
}
76
77
- bs->read_only = read_only;
78
-
79
- if (read_only) {
80
- bs->open_flags &= ~BDRV_O_RDWR;
81
- } else {
82
- bs->open_flags |= BDRV_O_RDWR;
83
+ ret = bdrv_can_set_read_only(bs, true, false, NULL);
84
+ if (ret < 0) {
85
+ goto fail;
86
}
87
88
+ bs->read_only = true;
89
+ bs->open_flags &= ~BDRV_O_RDWR;
90
+
91
return 0;
92
+
93
+fail:
94
+ error_setg(errp, "%s", errmsg ?: "Image is read-only");
95
+ return -EACCES;
96
}
97
98
void bdrv_get_full_backing_filename_from_filename(const char *backed,
99
diff --git a/block/bochs.c b/block/bochs.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/block/bochs.c
102
+++ b/block/bochs.c
103
@@ -XXX,XX +XXX,XX @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
104
struct bochs_header bochs;
105
int ret;
106
107
+ /* No write support yet */
108
+ ret = bdrv_apply_auto_read_only(bs, NULL, errp);
109
+ if (ret < 0) {
174
+ if (ret < 0) {
110
+ return ret;
175
+ return ret;
111
+ }
176
+ }
112
+
177
+
113
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
178
+ if (bdi->cluster_size > BDRV_MAX_ALIGNMENT) {
114
false, errp);
179
+ return -EINVAL;
115
if (!bs->file) {
180
+ }
116
return -EINVAL;
181
+
117
}
182
+ return 0;
118
183
}
119
- if (!bdrv_is_read_only(bs)) {
184
120
- error_report("Opening bochs images without an explicit read-only=on "
185
ImageInfoSpecific *bdrv_get_specific_info(BlockDriverState *bs,
121
- "option is deprecated. Future versions will refuse to "
186
diff --git a/block/file-posix.c b/block/file-posix.c
122
- "open the image instead of automatically marking the "
187
index XXXXXXX..XXXXXXX 100644
123
- "image read-only.");
188
--- a/block/file-posix.c
124
- ret = bdrv_set_read_only(bs, true, errp); /* no write support yet */
189
+++ b/block/file-posix.c
125
- if (ret < 0) {
190
@@ -XXX,XX +XXX,XX @@ raw_do_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int bytes,
126
- return ret;
191
#ifdef CONFIG_FALLOCATE
127
- }
192
if (offset + bytes > bs->total_sectors * BDRV_SECTOR_SIZE) {
128
- }
193
BdrvTrackedRequest *req;
129
-
194
- uint64_t end;
130
ret = bdrv_pread(bs->file, 0, &bochs, sizeof(bochs));
195
196
/*
197
* This is a workaround for a bug in the Linux XFS driver,
198
@@ -XXX,XX +XXX,XX @@ raw_do_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int bytes,
199
assert(req->offset <= offset);
200
assert(req->offset + req->bytes >= offset + bytes);
201
202
- end = INT64_MAX & -(uint64_t)bs->bl.request_alignment;
203
- req->bytes = end - req->offset;
204
+ req->bytes = BDRV_MAX_LENGTH - req->offset;
205
+
206
+ assert(bdrv_check_request(req->offset, req->bytes) == 0);
207
208
bdrv_mark_request_serialising(req, bs->bl.request_alignment);
209
}
210
diff --git a/block/io.c b/block/io.c
211
index XXXXXXX..XXXXXXX 100644
212
--- a/block/io.c
213
+++ b/block/io.c
214
@@ -XXX,XX +XXX,XX @@ void bdrv_refresh_limits(BlockDriverState *bs, Error **errp)
215
/* Then let the driver override it */
216
if (drv->bdrv_refresh_limits) {
217
drv->bdrv_refresh_limits(bs, errp);
218
+ if (*errp) {
219
+ return;
220
+ }
221
+ }
222
+
223
+ if (bs->bl.request_alignment > BDRV_MAX_ALIGNMENT) {
224
+ error_setg(errp, "Driver requires too large request alignment");
225
}
226
}
227
228
@@ -XXX,XX +XXX,XX @@ static bool coroutine_fn bdrv_wait_serialising_requests(BdrvTrackedRequest *self
229
return waited;
230
}
231
232
-static int bdrv_check_byte_request(int64_t offset, size_t size)
233
+int bdrv_check_request(int64_t offset, int64_t bytes)
234
{
235
- if (size > BDRV_REQUEST_MAX_BYTES) {
236
+ if (offset < 0 || bytes < 0) {
237
return -EIO;
238
}
239
240
- if (offset < 0) {
241
+ if (bytes > BDRV_MAX_LENGTH) {
242
+ return -EIO;
243
+ }
244
+
245
+ if (offset > BDRV_MAX_LENGTH - bytes) {
246
+ return -EIO;
247
+ }
248
+
249
+ return 0;
250
+}
251
+
252
+static int bdrv_check_request32(int64_t offset, int64_t bytes)
253
+{
254
+ int ret = bdrv_check_request(offset, bytes);
255
+ if (ret < 0) {
256
+ return ret;
257
+ }
258
+
259
+ if (bytes > BDRV_REQUEST_MAX_BYTES) {
260
return -EIO;
261
}
262
263
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_preadv_part(BdrvChild *child,
264
return -ENOMEDIUM;
265
}
266
267
- ret = bdrv_check_byte_request(offset, bytes);
268
+ ret = bdrv_check_request32(offset, bytes);
131
if (ret < 0) {
269
if (ret < 0) {
132
return ret;
270
return ret;
133
diff --git a/block/cloop.c b/block/cloop.c
271
}
134
index XXXXXXX..XXXXXXX 100644
272
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwritev_part(BdrvChild *child,
135
--- a/block/cloop.c
273
return -ENOMEDIUM;
136
+++ b/block/cloop.c
274
}
137
@@ -XXX,XX +XXX,XX @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags,
275
138
uint32_t offsets_size, max_compressed_block_size = 1, i;
276
- ret = bdrv_check_byte_request(offset, bytes);
139
int ret;
277
+ ret = bdrv_check_request32(offset, bytes);
140
278
if (ret < 0) {
141
+ ret = bdrv_apply_auto_read_only(bs, NULL, errp);
279
return ret;
280
}
281
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset,
282
return -EPERM;
283
}
284
285
- if (offset < 0 || bytes < 0 || bytes > INT64_MAX - offset) {
286
- return -EIO;
287
+ ret = bdrv_check_request(offset, bytes);
142
+ if (ret < 0) {
288
+ if (ret < 0) {
143
+ return ret;
289
+ return ret;
144
+ }
290
}
145
+
291
146
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
292
/* Do nothing if disabled. */
147
false, errp);
293
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_copy_range_internal(
148
if (!bs->file) {
294
if (!dst || !dst->bs || !bdrv_is_inserted(dst->bs)) {
295
return -ENOMEDIUM;
296
}
297
- ret = bdrv_check_byte_request(dst_offset, bytes);
298
+ ret = bdrv_check_request32(dst_offset, bytes);
299
if (ret) {
300
return ret;
301
}
302
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_copy_range_internal(
303
if (!src || !src->bs || !bdrv_is_inserted(src->bs)) {
304
return -ENOMEDIUM;
305
}
306
- ret = bdrv_check_byte_request(src_offset, bytes);
307
+ ret = bdrv_check_request32(src_offset, bytes);
308
if (ret) {
309
return ret;
310
}
311
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
149
return -EINVAL;
312
return -EINVAL;
150
}
313
}
151
314
152
- if (!bdrv_is_read_only(bs)) {
315
+ ret = bdrv_check_request(offset, 0);
153
- error_report("Opening cloop images without an explicit read-only=on "
154
- "option is deprecated. Future versions will refuse to "
155
- "open the image instead of automatically marking the "
156
- "image read-only.");
157
- ret = bdrv_set_read_only(bs, true, errp);
158
- if (ret < 0) {
159
- return ret;
160
- }
161
- }
162
-
163
/* read header */
164
ret = bdrv_pread(bs->file, 128, &s->block_size, 4);
165
if (ret < 0) {
166
diff --git a/block/dmg.c b/block/dmg.c
167
index XXXXXXX..XXXXXXX 100644
168
--- a/block/dmg.c
169
+++ b/block/dmg.c
170
@@ -XXX,XX +XXX,XX @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
171
int64_t offset;
172
int ret;
173
174
+ ret = bdrv_apply_auto_read_only(bs, NULL, errp);
175
+ if (ret < 0) {
316
+ if (ret < 0) {
317
+ error_setg(errp, "Required too big image size, it must be not greater "
318
+ "than %" PRId64, BDRV_MAX_LENGTH);
176
+ return ret;
319
+ return ret;
177
+ }
320
+ }
178
+
321
+
179
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
322
old_size = bdrv_getlength(bs);
180
false, errp);
323
if (old_size < 0) {
181
if (!bs->file) {
324
error_setg_errno(errp, -old_size, "Failed to get old image size");
182
return -EINVAL;
325
diff --git a/tests/test-write-threshold.c b/tests/test-write-threshold.c
183
}
326
index XXXXXXX..XXXXXXX 100644
184
327
--- a/tests/test-write-threshold.c
185
- if (!bdrv_is_read_only(bs)) {
328
+++ b/tests/test-write-threshold.c
186
- error_report("Opening dmg images without an explicit read-only=on "
329
@@ -XXX,XX +XXX,XX @@ static void test_threshold_not_trigger(void)
187
- "option is deprecated. Future versions will refuse to "
330
req.offset = 1024;
188
- "open the image instead of automatically marking the "
331
req.bytes = 1024;
189
- "image read-only.");
332
190
- ret = bdrv_set_read_only(bs, true, errp);
333
+ assert(bdrv_check_request(req.offset, req.bytes) == 0);
191
- if (ret < 0) {
334
+
192
- return ret;
335
bdrv_write_threshold_set(&bs, threshold);
193
- }
336
amount = bdrv_write_threshold_exceeded(&bs, &req);
194
- }
337
g_assert_cmpuint(amount, ==, 0);
195
-
338
@@ -XXX,XX +XXX,XX @@ static void test_threshold_trigger(void)
196
block_module_load_one("dmg-bz2");
339
req.offset = (4 * 1024 * 1024) - 1024;
197
340
req.bytes = 2 * 1024;
198
s->n_chunks = 0;
341
199
diff --git a/block/rbd.c b/block/rbd.c
342
+ assert(bdrv_check_request(req.offset, req.bytes) == 0);
200
index XXXXXXX..XXXXXXX 100644
343
+
201
--- a/block/rbd.c
344
bdrv_write_threshold_set(&bs, threshold);
202
+++ b/block/rbd.c
345
amount = bdrv_write_threshold_exceeded(&bs, &req);
203
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
346
g_assert_cmpuint(amount, >=, 1024);
204
/* If we are using an rbd snapshot, we must be r/o, otherwise
347
diff --git a/tests/qemu-iotests/206 b/tests/qemu-iotests/206
205
* leave as-is */
348
index XXXXXXX..XXXXXXX 100755
206
if (s->snap != NULL) {
349
--- a/tests/qemu-iotests/206
207
- if (!bdrv_is_read_only(bs)) {
350
+++ b/tests/qemu-iotests/206
208
- error_report("Opening rbd snapshots without an explicit "
351
@@ -XXX,XX +XXX,XX @@ with iotests.FilePath('t.qcow2') as disk_path, \
209
- "read-only=on option is deprecated. Future versions "
352
210
- "will refuse to open the image instead of "
353
vm.launch()
211
- "automatically marking the image read-only.");
354
for size in [ 1234, 18446744073709551104, 9223372036854775808,
212
- r = bdrv_set_read_only(bs, true, &local_err);
355
- 9223372036854775296 ]:
213
- if (r < 0) {
356
+ 9223372036854775296, 9223372035781033984 ]:
214
- rbd_close(s->image);
357
vm.blockdev_create({ 'driver': imgfmt,
215
- error_propagate(errp, local_err);
358
'file': 'node0',
216
- goto failed_open;
359
'size': size })
217
- }
360
diff --git a/tests/qemu-iotests/206.out b/tests/qemu-iotests/206.out
218
+ r = bdrv_apply_auto_read_only(bs, "rbd snapshots are read-only", errp);
361
index XXXXXXX..XXXXXXX 100644
219
+ if (r < 0) {
362
--- a/tests/qemu-iotests/206.out
220
+ rbd_close(s->image);
363
+++ b/tests/qemu-iotests/206.out
221
+ goto failed_open;
364
@@ -XXX,XX +XXX,XX @@ Job failed: Could not resize image: Image size cannot be negative
222
}
365
223
}
366
{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "qcow2", "file": "node0", "size": 9223372036854775296}}}
224
367
{"return": {}}
225
diff --git a/block/vvfat.c b/block/vvfat.c
368
+Job failed: Could not resize image: Required too big image size, it must be not greater than 9223372035781033984
226
index XXXXXXX..XXXXXXX 100644
369
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
227
--- a/block/vvfat.c
370
+{"return": {}}
228
+++ b/block/vvfat.c
371
+
229
@@ -XXX,XX +XXX,XX @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
372
+{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "qcow2", "file": "node0", "size": 9223372035781033984}}}
230
"Unable to set VVFAT to 'rw' when drive is read-only");
373
+{"return": {}}
231
goto fail;
374
Job failed: Could not resize image: Failed to grow the L1 table: File too large
232
}
375
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
233
- } else if (!bdrv_is_read_only(bs)) {
376
{"return": {}}
234
- error_report("Opening non-rw vvfat images without an explicit "
235
- "read-only=on option is deprecated. Future versions "
236
- "will refuse to open the image instead of "
237
- "automatically marking the image read-only.");
238
- /* read only is the default for safety */
239
- ret = bdrv_set_read_only(bs, true, &local_err);
240
+ } else {
241
+ ret = bdrv_apply_auto_read_only(bs, NULL, errp);
242
if (ret < 0) {
243
- error_propagate(errp, local_err);
244
goto fail;
245
}
246
}
247
--
377
--
248
2.19.1
378
2.29.2
249
379
250
380
diff view generated by jsdifflib
1
From: Peter Maydell <peter.maydell@linaro.org>
1
The only thing that happens after the 'out:' label is blk_unref(blk).
2
However, blk = NULL in all of the error cases, so instead of jumping to
3
'out:', we can just return directly.
2
4
3
Taking the address of a field in a packed struct is a bad idea, because
5
Cc: qemu-stable@nongnu.org
4
it might not be actually aligned enough for that pointer type (and
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
thus cause a crash on dereference on some host architectures). Newer
7
Message-Id: <20201203172311.68232-2-kwolf@redhat.com>
6
versions of clang warn about this. Avoid the bug by not using the
8
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
"modify in place" byte swapping functions.
8
9
There are a few places where the in-place swap function is
10
used on something other than a packed struct field; we convert
11
those anyway, for consistency.
12
13
Patch produced with scripts/coccinelle/inplace-byteswaps.cocci.
14
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
---
10
---
19
block/vhdx.h | 12 ++---
11
blockdev.c | 9 ++++-----
20
block/vhdx-endian.c | 118 ++++++++++++++++++++++----------------------
12
1 file changed, 4 insertions(+), 5 deletions(-)
21
block/vhdx-log.c | 4 +-
22
block/vhdx.c | 18 +++----
23
4 files changed, 76 insertions(+), 76 deletions(-)
24
13
25
diff --git a/block/vhdx.h b/block/vhdx.h
14
diff --git a/blockdev.c b/blockdev.c
26
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
27
--- a/block/vhdx.h
16
--- a/blockdev.c
28
+++ b/block/vhdx.h
17
+++ b/blockdev.c
29
@@ -XXX,XX +XXX,XX @@ int vhdx_log_write_and_flush(BlockDriverState *bs, BDRVVHDXState *s,
18
@@ -XXX,XX +XXX,XX @@ void coroutine_fn qmp_block_resize(bool has_device, const char *device,
30
19
int64_t size, Error **errp)
31
static inline void leguid_to_cpus(MSGUID *guid)
32
{
20
{
33
- le32_to_cpus(&guid->data1);
21
Error *local_err = NULL;
34
- le16_to_cpus(&guid->data2);
22
- BlockBackend *blk = NULL;
35
- le16_to_cpus(&guid->data3);
23
+ BlockBackend *blk;
36
+ guid->data1 = le32_to_cpu(guid->data1);
24
BlockDriverState *bs;
37
+ guid->data2 = le16_to_cpu(guid->data2);
25
AioContext *old_ctx;
38
+ guid->data3 = le16_to_cpu(guid->data3);
26
39
}
27
@@ -XXX,XX +XXX,XX @@ void coroutine_fn qmp_block_resize(bool has_device, const char *device,
40
28
41
static inline void cpu_to_leguids(MSGUID *guid)
29
if (size < 0) {
42
{
30
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "size", "a >0 size");
43
- cpu_to_le32s(&guid->data1);
31
- goto out;
44
- cpu_to_le16s(&guid->data2);
32
+ return;
45
- cpu_to_le16s(&guid->data3);
46
+ guid->data1 = cpu_to_le32(guid->data1);
47
+ guid->data2 = cpu_to_le16(guid->data2);
48
+ guid->data3 = cpu_to_le16(guid->data3);
49
}
50
51
void vhdx_header_le_import(VHDXHeader *h);
52
diff --git a/block/vhdx-endian.c b/block/vhdx-endian.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/block/vhdx-endian.c
55
+++ b/block/vhdx-endian.c
56
@@ -XXX,XX +XXX,XX @@ void vhdx_header_le_import(VHDXHeader *h)
57
{
58
assert(h != NULL);
59
60
- le32_to_cpus(&h->signature);
61
- le32_to_cpus(&h->checksum);
62
- le64_to_cpus(&h->sequence_number);
63
+ h->signature = le32_to_cpu(h->signature);
64
+ h->checksum = le32_to_cpu(h->checksum);
65
+ h->sequence_number = le64_to_cpu(h->sequence_number);
66
67
leguid_to_cpus(&h->file_write_guid);
68
leguid_to_cpus(&h->data_write_guid);
69
leguid_to_cpus(&h->log_guid);
70
71
- le16_to_cpus(&h->log_version);
72
- le16_to_cpus(&h->version);
73
- le32_to_cpus(&h->log_length);
74
- le64_to_cpus(&h->log_offset);
75
+ h->log_version = le16_to_cpu(h->log_version);
76
+ h->version = le16_to_cpu(h->version);
77
+ h->log_length = le32_to_cpu(h->log_length);
78
+ h->log_offset = le64_to_cpu(h->log_offset);
79
}
80
81
void vhdx_header_le_export(VHDXHeader *orig_h, VHDXHeader *new_h)
82
@@ -XXX,XX +XXX,XX @@ void vhdx_log_desc_le_import(VHDXLogDescriptor *d)
83
{
84
assert(d != NULL);
85
86
- le32_to_cpus(&d->signature);
87
- le64_to_cpus(&d->file_offset);
88
- le64_to_cpus(&d->sequence_number);
89
+ d->signature = le32_to_cpu(d->signature);
90
+ d->file_offset = le64_to_cpu(d->file_offset);
91
+ d->sequence_number = le64_to_cpu(d->sequence_number);
92
}
93
94
void vhdx_log_desc_le_export(VHDXLogDescriptor *d)
95
{
96
assert(d != NULL);
97
98
- cpu_to_le32s(&d->signature);
99
- cpu_to_le32s(&d->trailing_bytes);
100
- cpu_to_le64s(&d->leading_bytes);
101
- cpu_to_le64s(&d->file_offset);
102
- cpu_to_le64s(&d->sequence_number);
103
+ d->signature = cpu_to_le32(d->signature);
104
+ d->trailing_bytes = cpu_to_le32(d->trailing_bytes);
105
+ d->leading_bytes = cpu_to_le64(d->leading_bytes);
106
+ d->file_offset = cpu_to_le64(d->file_offset);
107
+ d->sequence_number = cpu_to_le64(d->sequence_number);
108
}
109
110
void vhdx_log_data_le_import(VHDXLogDataSector *d)
111
{
112
assert(d != NULL);
113
114
- le32_to_cpus(&d->data_signature);
115
- le32_to_cpus(&d->sequence_high);
116
- le32_to_cpus(&d->sequence_low);
117
+ d->data_signature = le32_to_cpu(d->data_signature);
118
+ d->sequence_high = le32_to_cpu(d->sequence_high);
119
+ d->sequence_low = le32_to_cpu(d->sequence_low);
120
}
121
122
void vhdx_log_data_le_export(VHDXLogDataSector *d)
123
{
124
assert(d != NULL);
125
126
- cpu_to_le32s(&d->data_signature);
127
- cpu_to_le32s(&d->sequence_high);
128
- cpu_to_le32s(&d->sequence_low);
129
+ d->data_signature = cpu_to_le32(d->data_signature);
130
+ d->sequence_high = cpu_to_le32(d->sequence_high);
131
+ d->sequence_low = cpu_to_le32(d->sequence_low);
132
}
133
134
void vhdx_log_entry_hdr_le_import(VHDXLogEntryHeader *hdr)
135
{
136
assert(hdr != NULL);
137
138
- le32_to_cpus(&hdr->signature);
139
- le32_to_cpus(&hdr->checksum);
140
- le32_to_cpus(&hdr->entry_length);
141
- le32_to_cpus(&hdr->tail);
142
- le64_to_cpus(&hdr->sequence_number);
143
- le32_to_cpus(&hdr->descriptor_count);
144
+ hdr->signature = le32_to_cpu(hdr->signature);
145
+ hdr->checksum = le32_to_cpu(hdr->checksum);
146
+ hdr->entry_length = le32_to_cpu(hdr->entry_length);
147
+ hdr->tail = le32_to_cpu(hdr->tail);
148
+ hdr->sequence_number = le64_to_cpu(hdr->sequence_number);
149
+ hdr->descriptor_count = le32_to_cpu(hdr->descriptor_count);
150
leguid_to_cpus(&hdr->log_guid);
151
- le64_to_cpus(&hdr->flushed_file_offset);
152
- le64_to_cpus(&hdr->last_file_offset);
153
+ hdr->flushed_file_offset = le64_to_cpu(hdr->flushed_file_offset);
154
+ hdr->last_file_offset = le64_to_cpu(hdr->last_file_offset);
155
}
156
157
void vhdx_log_entry_hdr_le_export(VHDXLogEntryHeader *hdr)
158
{
159
assert(hdr != NULL);
160
161
- cpu_to_le32s(&hdr->signature);
162
- cpu_to_le32s(&hdr->checksum);
163
- cpu_to_le32s(&hdr->entry_length);
164
- cpu_to_le32s(&hdr->tail);
165
- cpu_to_le64s(&hdr->sequence_number);
166
- cpu_to_le32s(&hdr->descriptor_count);
167
+ hdr->signature = cpu_to_le32(hdr->signature);
168
+ hdr->checksum = cpu_to_le32(hdr->checksum);
169
+ hdr->entry_length = cpu_to_le32(hdr->entry_length);
170
+ hdr->tail = cpu_to_le32(hdr->tail);
171
+ hdr->sequence_number = cpu_to_le64(hdr->sequence_number);
172
+ hdr->descriptor_count = cpu_to_le32(hdr->descriptor_count);
173
cpu_to_leguids(&hdr->log_guid);
174
- cpu_to_le64s(&hdr->flushed_file_offset);
175
- cpu_to_le64s(&hdr->last_file_offset);
176
+ hdr->flushed_file_offset = cpu_to_le64(hdr->flushed_file_offset);
177
+ hdr->last_file_offset = cpu_to_le64(hdr->last_file_offset);
178
}
179
180
181
@@ -XXX,XX +XXX,XX @@ void vhdx_region_header_le_import(VHDXRegionTableHeader *hdr)
182
{
183
assert(hdr != NULL);
184
185
- le32_to_cpus(&hdr->signature);
186
- le32_to_cpus(&hdr->checksum);
187
- le32_to_cpus(&hdr->entry_count);
188
+ hdr->signature = le32_to_cpu(hdr->signature);
189
+ hdr->checksum = le32_to_cpu(hdr->checksum);
190
+ hdr->entry_count = le32_to_cpu(hdr->entry_count);
191
}
192
193
void vhdx_region_header_le_export(VHDXRegionTableHeader *hdr)
194
{
195
assert(hdr != NULL);
196
197
- cpu_to_le32s(&hdr->signature);
198
- cpu_to_le32s(&hdr->checksum);
199
- cpu_to_le32s(&hdr->entry_count);
200
+ hdr->signature = cpu_to_le32(hdr->signature);
201
+ hdr->checksum = cpu_to_le32(hdr->checksum);
202
+ hdr->entry_count = cpu_to_le32(hdr->entry_count);
203
}
204
205
void vhdx_region_entry_le_import(VHDXRegionTableEntry *e)
206
@@ -XXX,XX +XXX,XX @@ void vhdx_region_entry_le_import(VHDXRegionTableEntry *e)
207
assert(e != NULL);
208
209
leguid_to_cpus(&e->guid);
210
- le64_to_cpus(&e->file_offset);
211
- le32_to_cpus(&e->length);
212
- le32_to_cpus(&e->data_bits);
213
+ e->file_offset = le64_to_cpu(e->file_offset);
214
+ e->length = le32_to_cpu(e->length);
215
+ e->data_bits = le32_to_cpu(e->data_bits);
216
}
217
218
void vhdx_region_entry_le_export(VHDXRegionTableEntry *e)
219
@@ -XXX,XX +XXX,XX @@ void vhdx_region_entry_le_export(VHDXRegionTableEntry *e)
220
assert(e != NULL);
221
222
cpu_to_leguids(&e->guid);
223
- cpu_to_le64s(&e->file_offset);
224
- cpu_to_le32s(&e->length);
225
- cpu_to_le32s(&e->data_bits);
226
+ e->file_offset = cpu_to_le64(e->file_offset);
227
+ e->length = cpu_to_le32(e->length);
228
+ e->data_bits = cpu_to_le32(e->data_bits);
229
}
230
231
232
@@ -XXX,XX +XXX,XX @@ void vhdx_metadata_header_le_import(VHDXMetadataTableHeader *hdr)
233
{
234
assert(hdr != NULL);
235
236
- le64_to_cpus(&hdr->signature);
237
- le16_to_cpus(&hdr->entry_count);
238
+ hdr->signature = le64_to_cpu(hdr->signature);
239
+ hdr->entry_count = le16_to_cpu(hdr->entry_count);
240
}
241
242
void vhdx_metadata_header_le_export(VHDXMetadataTableHeader *hdr)
243
{
244
assert(hdr != NULL);
245
246
- cpu_to_le64s(&hdr->signature);
247
- cpu_to_le16s(&hdr->entry_count);
248
+ hdr->signature = cpu_to_le64(hdr->signature);
249
+ hdr->entry_count = cpu_to_le16(hdr->entry_count);
250
}
251
252
void vhdx_metadata_entry_le_import(VHDXMetadataTableEntry *e)
253
@@ -XXX,XX +XXX,XX @@ void vhdx_metadata_entry_le_import(VHDXMetadataTableEntry *e)
254
assert(e != NULL);
255
256
leguid_to_cpus(&e->item_id);
257
- le32_to_cpus(&e->offset);
258
- le32_to_cpus(&e->length);
259
- le32_to_cpus(&e->data_bits);
260
+ e->offset = le32_to_cpu(e->offset);
261
+ e->length = le32_to_cpu(e->length);
262
+ e->data_bits = le32_to_cpu(e->data_bits);
263
}
264
void vhdx_metadata_entry_le_export(VHDXMetadataTableEntry *e)
265
{
266
assert(e != NULL);
267
268
cpu_to_leguids(&e->item_id);
269
- cpu_to_le32s(&e->offset);
270
- cpu_to_le32s(&e->length);
271
- cpu_to_le32s(&e->data_bits);
272
+ e->offset = cpu_to_le32(e->offset);
273
+ e->length = cpu_to_le32(e->length);
274
+ e->data_bits = cpu_to_le32(e->data_bits);
275
}
276
diff --git a/block/vhdx-log.c b/block/vhdx-log.c
277
index XXXXXXX..XXXXXXX 100644
278
--- a/block/vhdx-log.c
279
+++ b/block/vhdx-log.c
280
@@ -XXX,XX +XXX,XX @@ static void vhdx_log_raw_to_le_sector(VHDXLogDescriptor *desc,
281
/* 8 + 4084 + 4 = 4096, 1 log sector */
282
memcpy(&desc->leading_bytes, data, 8);
283
data += 8;
284
- cpu_to_le64s(&desc->leading_bytes);
285
+ desc->leading_bytes = cpu_to_le64(desc->leading_bytes);
286
memcpy(sector->data, data, 4084);
287
data += 4084;
288
memcpy(&desc->trailing_bytes, data, 4);
289
- cpu_to_le32s(&desc->trailing_bytes);
290
+ desc->trailing_bytes = cpu_to_le32(desc->trailing_bytes);
291
data += 4;
292
293
sector->sequence_high = (uint32_t) (seq >> 32);
294
diff --git a/block/vhdx.c b/block/vhdx.c
295
index XXXXXXX..XXXXXXX 100644
296
--- a/block/vhdx.c
297
+++ b/block/vhdx.c
298
@@ -XXX,XX +XXX,XX @@ uint32_t vhdx_update_checksum(uint8_t *buf, size_t size, int crc_offset)
299
300
memset(buf + crc_offset, 0, sizeof(crc));
301
crc = crc32c(0xffffffff, buf, size);
302
- cpu_to_le32s(&crc);
303
+ crc = cpu_to_le32(crc);
304
memcpy(buf + crc_offset, &crc, sizeof(crc));
305
306
return crc;
307
@@ -XXX,XX +XXX,XX @@ static int vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s)
308
goto exit;
309
}
33
}
310
34
311
- le32_to_cpus(&s->params.block_size);
35
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_RESIZE, NULL)) {
312
- le32_to_cpus(&s->params.data_bits);
36
error_setg(errp, QERR_DEVICE_IN_USE, device);
313
+ s->params.block_size = le32_to_cpu(s->params.block_size);
37
- goto out;
314
+ s->params.data_bits = le32_to_cpu(s->params.data_bits);
38
+ return;
315
316
317
/* We now have the file parameters, so we can tell if this is a
318
@@ -XXX,XX +XXX,XX @@ static int vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s)
319
goto exit;
320
}
39
}
321
40
322
- le64_to_cpus(&s->virtual_disk_size);
41
blk = blk_new_with_bs(bs, BLK_PERM_RESIZE, BLK_PERM_ALL, errp);
323
- le32_to_cpus(&s->logical_sector_size);
42
if (!blk) {
324
- le32_to_cpus(&s->physical_sector_size);
43
- goto out;
325
+ s->virtual_disk_size = le64_to_cpu(s->virtual_disk_size);
44
+ return;
326
+ s->logical_sector_size = le32_to_cpu(s->logical_sector_size);
327
+ s->physical_sector_size = le32_to_cpu(s->physical_sector_size);
328
329
if (s->params.block_size < VHDX_BLOCK_SIZE_MIN ||
330
s->params.block_size > VHDX_BLOCK_SIZE_MAX) {
331
@@ -XXX,XX +XXX,XX @@ static int vhdx_open(BlockDriverState *bs, QDict *options, int flags,
332
/* endian convert, and verify populated BAT field file offsets against
333
* region table and log entries */
334
for (i = 0; i < s->bat_entries; i++) {
335
- le64_to_cpus(&s->bat[i]);
336
+ s->bat[i] = le64_to_cpu(s->bat[i]);
337
if (payblocks--) {
338
/* payload bat entries */
339
if ((s->bat[i] & VHDX_BAT_STATE_BIT_MASK) ==
340
@@ -XXX,XX +XXX,XX @@ static int vhdx_create_new_metadata(BlockBackend *blk,
341
mt_file_params->block_size = cpu_to_le32(block_size);
342
if (type == VHDX_TYPE_FIXED) {
343
mt_file_params->data_bits |= VHDX_PARAMS_LEAVE_BLOCKS_ALLOCED;
344
- cpu_to_le32s(&mt_file_params->data_bits);
345
+ mt_file_params->data_bits = cpu_to_le32(mt_file_params->data_bits);
346
}
45
}
347
46
348
vhdx_guid_generate(&mt_page83->page_83_data);
47
bdrv_drained_begin(bs);
349
@@ -XXX,XX +XXX,XX @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
48
@@ -XXX,XX +XXX,XX @@ void coroutine_fn qmp_block_resize(bool has_device, const char *device,
350
sinfo.file_offset = ROUND_UP(sinfo.file_offset, MiB);
49
bdrv_co_leave(bs, old_ctx);
351
vhdx_update_bat_table_entry(blk_bs(blk), s, &sinfo, &unused, &unused,
50
bdrv_drained_end(bs);
352
block_state);
51
353
- cpu_to_le64s(&s->bat[sinfo.bat_idx]);
52
-out:
354
+ s->bat[sinfo.bat_idx] = cpu_to_le64(s->bat[sinfo.bat_idx]);
53
bdrv_co_lock(bs);
355
sector_num += s->sectors_per_block;
54
blk_unref(blk);
356
}
55
bdrv_co_unlock(bs);
357
ret = blk_pwrite(blk, file_offset, s->bat, length, 0);
358
--
56
--
359
2.19.1
57
2.29.2
360
58
361
59
diff view generated by jsdifflib
1
While we want machine interfaces like -blockdev and QMP blockdev-add to
1
The drain functions assume that we hold the AioContext lock of the
2
add as little auto-detection as possible so that management tools are
2
drained block node. Make sure to actually take the lock.
3
explicit about their needs, -drive is a convenience option for human
4
users. Enabling auto-read-only=on by default there enables users to use
5
read-only images for read-only guest devices without having to specify
6
read-only=on explicitly. If they try to attach the image to a read-write
7
device, they will still get an error message.
8
3
4
Cc: qemu-stable@nongnu.org
5
Fixes: eb94b81a94bce112e6b206df846c1551aaf6cab6
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Reviewed-by: Eric Blake <eblake@redhat.com>
7
Message-Id: <20201203172311.68232-3-kwolf@redhat.com>
8
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
10
---
12
blockdev.c | 1 +
11
blockdev.c | 5 ++++-
13
1 file changed, 1 insertion(+)
12
1 file changed, 4 insertions(+), 1 deletion(-)
14
13
15
diff --git a/blockdev.c b/blockdev.c
14
diff --git a/blockdev.c b/blockdev.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/blockdev.c
16
--- a/blockdev.c
18
+++ b/blockdev.c
17
+++ b/blockdev.c
19
@@ -XXX,XX +XXX,XX @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
18
@@ -XXX,XX +XXX,XX @@ void coroutine_fn qmp_block_resize(bool has_device, const char *device,
20
qdict_set_default_str(bs_opts, BDRV_OPT_CACHE_NO_FLUSH, "off");
19
return;
21
qdict_set_default_str(bs_opts, BDRV_OPT_READ_ONLY,
20
}
22
read_only ? "on" : "off");
21
23
+ qdict_set_default_str(bs_opts, BDRV_OPT_AUTO_READ_ONLY, "on");
22
+ bdrv_co_lock(bs);
24
assert((bdrv_flags & BDRV_O_CACHE_MASK) == 0);
23
bdrv_drained_begin(bs);
25
24
+ bdrv_co_unlock(bs);
26
if (runstate_check(RUN_STATE_INMIGRATE)) {
25
+
26
old_ctx = bdrv_co_enter(bs);
27
blk_truncate(blk, size, false, PREALLOC_MODE_OFF, 0, errp);
28
bdrv_co_leave(bs, old_ctx);
29
- bdrv_drained_end(bs);
30
31
bdrv_co_lock(bs);
32
+ bdrv_drained_end(bs);
33
blk_unref(blk);
34
bdrv_co_unlock(bs);
35
}
27
--
36
--
28
2.19.1
37
2.29.2
29
38
30
39
diff view generated by jsdifflib
1
If a management application builds the block graph node by node, the
1
If bdrv_co_yield_to_drain() is called for draining a block node that
2
protocol layer doesn't inherit its read-only option from the format
2
runs in a different AioContext, it keeps that AioContext locked while it
3
layer any more, so it must be set explicitly.
3
yields and schedules a BH in the AioContext to do the actual drain.
4
4
5
Backing files should work on read-only storage, but at the same time, a
5
As long as executing the BH is the very next thing that the event loop
6
block job like commit should be able to reopen them read-write if they
6
of the node's AioContext does, this actually happens to work, but when
7
are on read-write storage. However, without option inheritance, reopen
7
it tries to execute something else that wants to take the AioContext
8
only changes the read-only option for the root node (typically the
8
lock, it will deadlock. (In the bug report, this other thing is a
9
format layer), but not the protocol layer, so reopening fails (the
9
virtio-scsi device running virtio_scsi_data_plane_handle_cmd().)
10
format layer wants to get write permissions, but the protocol layer is
11
still read-only).
12
10
13
A simple workaround for the problem in the management tool would be to
11
Instead, always drop the AioContext lock across the yield and reacquire
14
open the protocol layer always read-write and to make only the format
12
it only when the coroutine is reentered. The BH needs to unconditionally
15
layer read-only for backing files. However, sometimes the file is
13
take the lock for itself now.
16
actually stored on read-only storage and we don't know whether the image
17
can be opened read-write (for example, for NBD it depends on the server
18
we're trying to connect to). This adds an option that makes QEMU try to
19
open the image read-write, but allows it to degrade to a read-only mode
20
without returning an error.
21
14
22
The documentation for this option is consciously phrased in a way that
15
This fixes the 'block_resize' QMP command on a block node that runs in
23
allows QEMU to switch to a better model eventually: Instead of trying
16
an iothread.
24
when the image is first opened, making the read-only flag dynamic and
25
changing it automatically whenever the first BLK_PERM_WRITE user is
26
attached or the last one is detached would be much more useful
27
behaviour.
28
17
29
Unfortunately, this more useful behaviour is also a lot harder to
18
Cc: qemu-stable@nongnu.org
30
implement, and libvirt needs a solution now before it can switch to
19
Fixes: eb94b81a94bce112e6b206df846c1551aaf6cab6
31
-blockdev, so let's start with this easier approach for now.
20
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1903511
21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
Message-Id: <20201203172311.68232-4-kwolf@redhat.com>
23
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
24
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
25
---
26
block/io.c | 41 ++++++++++++++++++++++++-----------------
27
1 file changed, 24 insertions(+), 17 deletions(-)
32
28
33
Instead of adding a new auto-read-only option, turning the existing
29
diff --git a/block/io.c b/block/io.c
34
read-only into an enum (with a bool alternate for compatibility) was
35
considered, but it complicated the implementation to the point that it
36
didn't seem to be worth it.
37
38
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
39
Reviewed-by: Eric Blake <eblake@redhat.com>
40
---
41
qapi/block-core.json | 7 +++++++
42
include/block/block.h | 2 ++
43
block.c | 17 +++++++++++++++++
44
block/vvfat.c | 1 +
45
blockdev.c | 2 +-
46
5 files changed, 28 insertions(+), 1 deletion(-)
47
48
diff --git a/qapi/block-core.json b/qapi/block-core.json
49
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
50
--- a/qapi/block-core.json
31
--- a/block/io.c
51
+++ b/qapi/block-core.json
32
+++ b/block/io.c
52
@@ -XXX,XX +XXX,XX @@
33
@@ -XXX,XX +XXX,XX @@ static void bdrv_co_drain_bh_cb(void *opaque)
53
# either generally or in certain configurations. In this case,
34
54
# the default value does not work and the option must be
35
if (bs) {
55
# specified explicitly.
36
AioContext *ctx = bdrv_get_aio_context(bs);
56
+# @auto-read-only: if true and @read-only is false, QEMU may automatically
37
- AioContext *co_ctx = qemu_coroutine_get_aio_context(co);
57
+# decide not to open the image read-write as requested, but
38
-
58
+# fall back to read-only instead (and switch between the modes
39
- /*
59
+# later), e.g. depending on whether the image file is writable
40
- * When the coroutine yielded, the lock for its home context was
60
+# or whether a writing user is attached to the node
41
- * released, so we need to re-acquire it here. If it explicitly
61
+# (default: false, since 3.1)
42
- * acquired a different context, the lock is still held and we don't
62
# @detect-zeroes: detect and optimize zero writes (Since 2.1)
43
- * want to lock it a second time (or AIO_WAIT_WHILE() would hang).
63
# (default: off)
44
- */
64
# @force-share: force share all permission on added nodes.
45
- if (ctx == co_ctx) {
65
@@ -XXX,XX +XXX,XX @@
46
- aio_context_acquire(ctx);
66
'*discard': 'BlockdevDiscardOptions',
47
- }
67
'*cache': 'BlockdevCacheOptions',
48
+ aio_context_acquire(ctx);
68
'*read-only': 'bool',
49
bdrv_dec_in_flight(bs);
69
+ '*auto-read-only': 'bool',
50
if (data->begin) {
70
'*force-share': 'bool',
51
assert(!data->drained_end_counter);
71
'*detect-zeroes': 'BlockdevDetectZeroesOptions' },
52
@@ -XXX,XX +XXX,XX @@ static void bdrv_co_drain_bh_cb(void *opaque)
72
'discriminator': 'driver',
53
data->ignore_bds_parents,
73
diff --git a/include/block/block.h b/include/block/block.h
54
data->drained_end_counter);
74
index XXXXXXX..XXXXXXX 100644
55
}
75
--- a/include/block/block.h
56
- if (ctx == co_ctx) {
76
+++ b/include/block/block.h
57
- aio_context_release(ctx);
77
@@ -XXX,XX +XXX,XX @@ typedef struct HDGeometry {
58
- }
78
select an appropriate protocol driver,
59
+ aio_context_release(ctx);
79
ignoring the format layer */
60
} else {
80
#define BDRV_O_NO_IO 0x10000 /* don't initialize for I/O */
61
assert(data->begin);
81
+#define BDRV_O_AUTO_RDONLY 0x20000 /* degrade to read-only if opening read-write fails */
62
bdrv_drain_all_begin();
82
63
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs,
83
#define BDRV_O_CACHE_MASK (BDRV_O_NOCACHE | BDRV_O_NO_FLUSH)
64
int *drained_end_counter)
84
65
{
85
@@ -XXX,XX +XXX,XX @@ typedef struct HDGeometry {
66
BdrvCoDrainData data;
86
#define BDRV_OPT_CACHE_DIRECT "cache.direct"
67
+ Coroutine *self = qemu_coroutine_self();
87
#define BDRV_OPT_CACHE_NO_FLUSH "cache.no-flush"
68
+ AioContext *ctx = bdrv_get_aio_context(bs);
88
#define BDRV_OPT_READ_ONLY "read-only"
69
+ AioContext *co_ctx = qemu_coroutine_get_aio_context(self);
89
+#define BDRV_OPT_AUTO_READ_ONLY "auto-read-only"
70
90
#define BDRV_OPT_DISCARD "discard"
71
/* Calling bdrv_drain() from a BH ensures the current coroutine yields and
91
#define BDRV_OPT_FORCE_SHARE "force-share"
72
* other coroutines run if they were queued by aio_co_enter(). */
92
73
93
diff --git a/block.c b/block.c
74
assert(qemu_in_coroutine());
94
index XXXXXXX..XXXXXXX 100644
75
data = (BdrvCoDrainData) {
95
--- a/block.c
76
- .co = qemu_coroutine_self(),
96
+++ b/block.c
77
+ .co = self,
97
@@ -XXX,XX +XXX,XX @@ static void bdrv_inherited_options(int *child_flags, QDict *child_options,
78
.bs = bs,
98
79
.done = false,
99
/* Inherit the read-only option from the parent if it's not set */
80
.begin = begin,
100
qdict_copy_default(child_options, parent_options, BDRV_OPT_READ_ONLY);
81
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs,
101
+ qdict_copy_default(child_options, parent_options, BDRV_OPT_AUTO_READ_ONLY);
82
if (bs) {
102
83
bdrv_inc_in_flight(bs);
103
/* Our block drivers take care to send flushes and respect unmap policy,
104
* so we can default to enable both on lower layers regardless of the
105
@@ -XXX,XX +XXX,XX @@ static void bdrv_backing_options(int *child_flags, QDict *child_options,
106
107
/* backing files always opened read-only */
108
qdict_set_default_str(child_options, BDRV_OPT_READ_ONLY, "on");
109
+ qdict_set_default_str(child_options, BDRV_OPT_AUTO_READ_ONLY, "off");
110
flags &= ~BDRV_O_COPY_ON_READ;
111
112
/* snapshot=on is handled on the top layer */
113
@@ -XXX,XX +XXX,XX @@ static void update_flags_from_options(int *flags, QemuOpts *opts)
114
*flags |= BDRV_O_RDWR;
115
}
84
}
116
85
- replay_bh_schedule_oneshot_event(bdrv_get_aio_context(bs),
117
+ assert(qemu_opt_find(opts, BDRV_OPT_AUTO_READ_ONLY));
86
- bdrv_co_drain_bh_cb, &data);
118
+ if (qemu_opt_get_bool_del(opts, BDRV_OPT_AUTO_READ_ONLY, false)) {
87
+
119
+ *flags |= BDRV_O_AUTO_RDONLY;
88
+ /*
89
+ * Temporarily drop the lock across yield or we would get deadlocks.
90
+ * bdrv_co_drain_bh_cb() reaquires the lock as needed.
91
+ *
92
+ * When we yield below, the lock for the current context will be
93
+ * released, so if this is actually the lock that protects bs, don't drop
94
+ * it a second time.
95
+ */
96
+ if (ctx != co_ctx) {
97
+ aio_context_release(ctx);
98
+ }
99
+ replay_bh_schedule_oneshot_event(ctx, bdrv_co_drain_bh_cb, &data);
100
101
qemu_coroutine_yield();
102
/* If we are resumed from some other event (such as an aio completion or a
103
* timer callback), it is a bug in the caller that should be fixed. */
104
assert(data.done);
105
+
106
+ /* Reaquire the AioContext of bs if we dropped it */
107
+ if (ctx != co_ctx) {
108
+ aio_context_acquire(ctx);
120
+ }
109
+ }
121
}
110
}
122
111
123
static void update_options_from_flags(QDict *options, int flags)
112
void bdrv_do_drained_begin_quiesce(BlockDriverState *bs,
124
@@ -XXX,XX +XXX,XX @@ static void update_options_from_flags(QDict *options, int flags)
125
if (!qdict_haskey(options, BDRV_OPT_READ_ONLY)) {
126
qdict_put_bool(options, BDRV_OPT_READ_ONLY, !(flags & BDRV_O_RDWR));
127
}
128
+ if (!qdict_haskey(options, BDRV_OPT_AUTO_READ_ONLY)) {
129
+ qdict_put_bool(options, BDRV_OPT_AUTO_READ_ONLY,
130
+ flags & BDRV_O_AUTO_RDONLY);
131
+ }
132
}
133
134
static void bdrv_assign_node_name(BlockDriverState *bs,
135
@@ -XXX,XX +XXX,XX @@ QemuOptsList bdrv_runtime_opts = {
136
.type = QEMU_OPT_BOOL,
137
.help = "Node is opened in read-only mode",
138
},
139
+ {
140
+ .name = BDRV_OPT_AUTO_READ_ONLY,
141
+ .type = QEMU_OPT_BOOL,
142
+ .help = "Node can become read-only if opening read-write fails",
143
+ },
144
{
145
.name = "detect-zeroes",
146
.type = QEMU_OPT_STRING,
147
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp)
148
qdict_set_default_str(qdict, BDRV_OPT_CACHE_DIRECT, "off");
149
qdict_set_default_str(qdict, BDRV_OPT_CACHE_NO_FLUSH, "off");
150
qdict_set_default_str(qdict, BDRV_OPT_READ_ONLY, "off");
151
+ qdict_set_default_str(qdict, BDRV_OPT_AUTO_READ_ONLY, "off");
152
+
153
}
154
155
bs = bdrv_open_inherit(NULL, reference, qdict, 0, NULL, NULL, errp);
156
diff --git a/block/vvfat.c b/block/vvfat.c
157
index XXXXXXX..XXXXXXX 100644
158
--- a/block/vvfat.c
159
+++ b/block/vvfat.c
160
@@ -XXX,XX +XXX,XX @@ static void vvfat_qcow_options(int *child_flags, QDict *child_options,
161
int parent_flags, QDict *parent_options)
162
{
163
qdict_set_default_str(child_options, BDRV_OPT_READ_ONLY, "off");
164
+ qdict_set_default_str(child_options, BDRV_OPT_AUTO_READ_ONLY, "off");
165
qdict_set_default_str(child_options, BDRV_OPT_CACHE_NO_FLUSH, "on");
166
}
167
168
diff --git a/blockdev.c b/blockdev.c
169
index XXXXXXX..XXXXXXX 100644
170
--- a/blockdev.c
171
+++ b/blockdev.c
172
@@ -XXX,XX +XXX,XX @@ void qmp_blockdev_change_medium(bool has_device, const char *device,
173
174
bdrv_flags = blk_get_open_flags_from_root_state(blk);
175
bdrv_flags &= ~(BDRV_O_TEMPORARY | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING |
176
- BDRV_O_PROTOCOL);
177
+ BDRV_O_PROTOCOL | BDRV_O_AUTO_RDONLY);
178
179
if (!has_read_only) {
180
read_only = BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN;
181
--
113
--
182
2.19.1
114
2.29.2
183
115
184
116
diff view generated by jsdifflib
Deleted patch
1
Commit e2b8247a322 introduced an error path in qemu_rbd_open() after
2
calling rbd_open(), but neglected to close the image again in this error
3
path. The error path should contain everything that the regular close
4
function qemu_rbd_close() contains.
5
1
6
This adds the missing rbd_close() call.
7
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Reviewed-by: Eric Blake <eblake@redhat.com>
10
---
11
block/rbd.c | 1 +
12
1 file changed, 1 insertion(+)
13
14
diff --git a/block/rbd.c b/block/rbd.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/block/rbd.c
17
+++ b/block/rbd.c
18
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
19
"automatically marking the image read-only.");
20
r = bdrv_set_read_only(bs, true, &local_err);
21
if (r < 0) {
22
+ rbd_close(s->image);
23
error_propagate(errp, local_err);
24
goto failed_open;
25
}
26
--
27
2.19.1
28
29
diff view generated by jsdifflib