1 | The following changes since commit 81b2d5ceb0cfb4cdc2163492e3169ed714b0cda9: | 1 | The following changes since commit b785d25e91718a660546a6550f64b3c543af7754: |
---|---|---|---|
2 | 2 | ||
3 | Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20170426' into staging (2017-04-26 20:50:49 +0100) | 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 | |||
7 | 6 | ||
8 | git://repo.or.cz/qemu/kevin.git tags/for-upstream | 7 | git://repo.or.cz/qemu/kevin.git tags/for-upstream |
9 | 8 | ||
10 | for you to fetch changes up to 5fc0fe383fff318b38291dcdf2cf38e329ec232a: | 9 | for you to fetch changes up to 960d5fb3e8ee09bc5f1a5c84f66dce42a6cef920: |
11 | 10 | ||
12 | Merge remote-tracking branch 'mreitz/tags/pull-block-2017-04-28' into queue-block (2017-04-28 20:52:17 +0200) | 11 | block: Fix deadlock in bdrv_co_yield_to_drain() (2020-12-11 17:52:40 +0100) |
13 | 12 | ||
14 | ---------------------------------------------------------------- | 13 | ---------------------------------------------------------------- |
14 | Block layer patches: | ||
15 | 15 | ||
16 | Block layer patches | 16 | - Support for FUSE exports |
17 | - Fix deadlock in bdrv_co_yield_to_drain() | ||
18 | - Use lock guard macros | ||
19 | - Some preparational patches for 64 bit block layer | ||
20 | - file-posix: Fix request extension to INT64_MAX in raw_do_pwrite_zeroes() | ||
17 | 21 | ||
18 | ---------------------------------------------------------------- | 22 | ---------------------------------------------------------------- |
19 | Denis V. Lunev (2): | 23 | Gan Qixin (4): |
20 | block: fix alignment calculations in bdrv_co_do_zero_pwritev | 24 | block/accounting: Use lock guard macros |
21 | block: assert no image modification under BDRV_O_INACTIVE | 25 | block/curl: Use lock guard macros |
26 | block/throttle-groups: Use lock guard macros | ||
27 | block/iscsi: Use lock guard macros | ||
22 | 28 | ||
23 | Eric Blake (2): | 29 | Kevin Wolf (4): |
24 | iotests: Fix typo in 026 | 30 | can-host: Fix crash when 'canbus' property is not set |
25 | qcow2: Allow discard of final unaligned cluster | 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() | ||
26 | 34 | ||
27 | Fam Zheng (2): | 35 | Li Feng (1): |
28 | block: Remove NULL check in bdrv_co_flush | 36 | file-posix: check the use_lock before setting the file lock |
29 | iotests: 109: Filter out "len" of failed jobs | ||
30 | 37 | ||
31 | John Snow (2): | 38 | Max Reitz (21): |
32 | iotests: clarify help text | 39 | meson: Detect libfuse |
33 | iotests: fix exclusion option | 40 | fuse: Allow exporting BDSs via FUSE |
41 | fuse: Implement standard FUSE operations | ||
42 | fuse: Allow growable exports | ||
43 | fuse: (Partially) implement fallocate() | ||
44 | fuse: Implement hole detection through lseek | ||
45 | iotests: Do not needlessly filter _make_test_img | ||
46 | iotests: Do not pipe _make_test_img | ||
47 | iotests: Use convert -n in some cases | ||
48 | iotests/046: Avoid renaming images | ||
49 | iotests: Derive image names from $TEST_IMG | ||
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 | ||
34 | 60 | ||
35 | Kevin Wolf (8): | 61 | Vladimir Sementsov-Ogievskiy (4): |
36 | file-posix: Remove unnecessary includes | 62 | block/file-posix: fix workaround in raw_do_pwrite_zeroes() |
37 | file-win32: Remove unnecessary include | 63 | block/io: bdrv_refresh_limits(): use ERRP_GUARD |
38 | migration: Call blk_resume_after_migration() for postcopy | 64 | block/io: bdrv_check_byte_request(): drop bdrv_is_inserted() |
39 | qemu-iotests: Filter HMP readline escape characters | 65 | block: introduce BDRV_MAX_LENGTH |
40 | qemu-iotests: Test postcopy migration | ||
41 | qemu-iotests: Remove PERL_PROG and BC_PROG | ||
42 | qemu_iotests: Remove _readlink() | ||
43 | Merge remote-tracking branch 'mreitz/tags/pull-block-2017-04-28' into queue-block | ||
44 | 66 | ||
45 | Klim Kireev (1): | 67 | qapi/block-export.json | 27 +- |
46 | block: fix obvious coding style mistakes in block_int.h | 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 | ||
47 | 185 | ||
48 | Krzysztof Kozlowski (1): | ||
49 | block: Constify data passed by pointer to blk_name | ||
50 | 186 | ||
51 | Lidong Chen (1): | ||
52 | qemu-img: use blk_co_pwrite_zeroes for zero sectors when compressed | ||
53 | |||
54 | Max Reitz (13): | ||
55 | Revert "block/io: Comment out permission assertions" | ||
56 | block: An empty filename counts as no filename | ||
57 | iotests/051: Add test for empty filename | ||
58 | iotests: Launch qemu-nbd with -e 42 | ||
59 | block: Do not unref bs->file on error in BD's open | ||
60 | qemu-img/convert: Use @opts for one thing only | ||
61 | qemu-img/convert: Move bs_n > 1 && -B check down | ||
62 | qemu-img: Document backing options | ||
63 | block/vhdx: Make vhdx_create() always set errp | ||
64 | block: Add errp to b{lk,drv}_truncate() | ||
65 | block: Add errp to BD.bdrv_truncate() | ||
66 | block: Add .bdrv_truncate() error messages | ||
67 | progress: Show current progress on SIGINFO | ||
68 | |||
69 | Peter Lieven (1): | ||
70 | qemu-img: simplify img_convert | ||
71 | |||
72 | Thomas Huth (1): | ||
73 | Issue a deprecation warning if the user specifies the "-hdachs" option. | ||
74 | |||
75 | Vladimir Sementsov-Ogievskiy (1): | ||
76 | qemu-img: improve convert_iteration_sectors() | ||
77 | |||
78 | block.c | 26 +-- | ||
79 | block/blkdebug.c | 8 +- | ||
80 | block/blkreplay.c | 3 - | ||
81 | block/blkverify.c | 3 - | ||
82 | block/block-backend.c | 7 +- | ||
83 | block/commit.c | 5 +- | ||
84 | block/crypto.c | 5 +- | ||
85 | block/file-posix.c | 21 ++- | ||
86 | block/file-win32.c | 7 +- | ||
87 | block/gluster.c | 7 +- | ||
88 | block/io.c | 16 +- | ||
89 | block/iscsi.c | 6 +- | ||
90 | block/mirror.c | 2 +- | ||
91 | block/nfs.c | 12 +- | ||
92 | block/parallels.c | 13 +- | ||
93 | block/qcow.c | 6 +- | ||
94 | block/qcow2-refcount.c | 5 +- | ||
95 | block/qcow2.c | 31 ++-- | ||
96 | block/qed.c | 8 +- | ||
97 | block/raw-format.c | 6 +- | ||
98 | block/rbd.c | 3 +- | ||
99 | block/sheepdog.c | 14 +- | ||
100 | block/vdi.c | 4 +- | ||
101 | block/vhdx-log.c | 2 +- | ||
102 | block/vhdx.c | 25 ++- | ||
103 | block/vmdk.c | 13 +- | ||
104 | block/vpc.c | 13 +- | ||
105 | blockdev.c | 21 +-- | ||
106 | include/block/block.h | 2 +- | ||
107 | include/block/block_int.h | 8 +- | ||
108 | include/sysemu/block-backend.h | 4 +- | ||
109 | migration/savevm.c | 8 + | ||
110 | qemu-img-cmds.hx | 8 +- | ||
111 | qemu-img.c | 313 ++++++++++++++----------------------- | ||
112 | qemu-img.texi | 7 +- | ||
113 | qemu-io-cmds.c | 5 +- | ||
114 | qemu-options.hx | 4 +- | ||
115 | tests/qemu-iotests/026 | 2 +- | ||
116 | tests/qemu-iotests/026.out | 2 +- | ||
117 | tests/qemu-iotests/026.out.nocache | 2 +- | ||
118 | tests/qemu-iotests/028.out | 2 +- | ||
119 | tests/qemu-iotests/051 | 4 +- | ||
120 | tests/qemu-iotests/051.out | 109 ++++++------- | ||
121 | tests/qemu-iotests/051.pc.out | 135 ++++++++-------- | ||
122 | tests/qemu-iotests/066 | 12 +- | ||
123 | tests/qemu-iotests/066.out | 12 +- | ||
124 | tests/qemu-iotests/068 | 4 +- | ||
125 | tests/qemu-iotests/068.out | 6 +- | ||
126 | tests/qemu-iotests/109 | 6 +- | ||
127 | tests/qemu-iotests/109.out | 20 +-- | ||
128 | tests/qemu-iotests/122.out | 4 +- | ||
129 | tests/qemu-iotests/130.out | 4 +- | ||
130 | tests/qemu-iotests/142 | 2 +- | ||
131 | tests/qemu-iotests/142.out | 10 +- | ||
132 | tests/qemu-iotests/145 | 3 +- | ||
133 | tests/qemu-iotests/145.out | 2 +- | ||
134 | tests/qemu-iotests/181 | 119 ++++++++++++++ | ||
135 | tests/qemu-iotests/181.out | 38 +++++ | ||
136 | tests/qemu-iotests/common | 11 +- | ||
137 | tests/qemu-iotests/common.config | 24 --- | ||
138 | tests/qemu-iotests/common.filter | 13 ++ | ||
139 | tests/qemu-iotests/common.qemu | 4 +- | ||
140 | tests/qemu-iotests/common.rc | 4 +- | ||
141 | tests/qemu-iotests/group | 1 + | ||
142 | util/qemu-progress.c | 3 + | ||
143 | vl.c | 2 + | ||
144 | 66 files changed, 669 insertions(+), 542 deletions(-) | ||
145 | create mode 100755 tests/qemu-iotests/181 | ||
146 | create mode 100644 tests/qemu-iotests/181.out | ||
147 | diff view generated by jsdifflib |
1 | From: Peter Lieven <pl@kamp.de> | 1 | From: Gan Qixin <ganqixin@huawei.com> |
---|---|---|---|
2 | 2 | ||
3 | img_convert has been around before there was an ImgConvertState or | 3 | Replace manual lock()/unlock() calls with lock guard macros |
4 | a block backend, but it has never been modified to directly use | 4 | (QEMU_LOCK_GUARD/WITH_QEMU_LOCK_GUARD) in block/accounting. |
5 | these structs. Change this by parsing parameters directly into | ||
6 | the ImgConvertState and directly use BlockBackend where possible. | ||
7 | Furthermore variable initialization has been reworked and sorted. | ||
8 | 5 | ||
9 | Signed-off-by: Peter Lieven <pl@kamp.de> | 6 | Signed-off-by: Gan Qixin <ganqixin@huawei.com> |
10 | Reviewed-by: Eric Blake <eblake@redhat.com> | 7 | Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> |
8 | Message-Id: <20201203075055.127773-2-ganqixin@huawei.com> | ||
11 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 9 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
12 | --- | 10 | --- |
13 | qemu-img.c | 201 +++++++++++++++++++++++++------------------------------------ | 11 | block/accounting.c | 32 +++++++++++++++----------------- |
14 | 1 file changed, 81 insertions(+), 120 deletions(-) | 12 | 1 file changed, 15 insertions(+), 17 deletions(-) |
15 | 13 | ||
16 | diff --git a/qemu-img.c b/qemu-img.c | 14 | diff --git a/block/accounting.c b/block/accounting.c |
17 | index XXXXXXX..XXXXXXX 100644 | 15 | index XXXXXXX..XXXXXXX 100644 |
18 | --- a/qemu-img.c | 16 | --- a/block/accounting.c |
19 | +++ b/qemu-img.c | 17 | +++ b/block/accounting.c |
20 | @@ -XXX,XX +XXX,XX @@ typedef struct ImgConvertState { | 18 | @@ -XXX,XX +XXX,XX @@ static void block_account_one_io(BlockAcctStats *stats, BlockAcctCookie *cookie, |
21 | int min_sparse; | 19 | return; |
22 | size_t cluster_sectors; | ||
23 | size_t buf_sectors; | ||
24 | - int num_coroutines; | ||
25 | + long num_coroutines; | ||
26 | int running_coroutines; | ||
27 | Coroutine *co[MAX_COROUTINES]; | ||
28 | int64_t wait_sector_num[MAX_COROUTINES]; | ||
29 | @@ -XXX,XX +XXX,XX @@ static int convert_do_copy(ImgConvertState *s) | ||
30 | |||
31 | static int img_convert(int argc, char **argv) | ||
32 | { | ||
33 | - int c, bs_n, bs_i, compress, cluster_sectors, skip_create; | ||
34 | - int64_t ret = 0; | ||
35 | - int progress = 0, flags, src_flags; | ||
36 | - bool writethrough, src_writethrough; | ||
37 | - const char *fmt, *out_fmt, *cache, *src_cache, *out_baseimg, *out_filename; | ||
38 | + int c, bs_i, flags, src_flags = 0; | ||
39 | + const char *fmt = NULL, *out_fmt = "raw", *cache = "unsafe", | ||
40 | + *src_cache = BDRV_DEFAULT_CACHE, *out_baseimg = NULL, | ||
41 | + *out_filename, *out_baseimg_param, *snapshot_name = NULL; | ||
42 | BlockDriver *drv, *proto_drv; | ||
43 | - BlockBackend **blk = NULL, *out_blk = NULL; | ||
44 | - BlockDriverState **bs = NULL, *out_bs = NULL; | ||
45 | - int64_t total_sectors; | ||
46 | - int64_t *bs_sectors = NULL; | ||
47 | - size_t bufsectors = IO_BUF_SIZE / BDRV_SECTOR_SIZE; | ||
48 | BlockDriverInfo bdi; | ||
49 | - QemuOpts *opts = NULL; | ||
50 | + BlockDriverState *out_bs; | ||
51 | + QemuOpts *opts = NULL, *sn_opts = NULL; | ||
52 | QemuOptsList *create_opts = NULL; | ||
53 | - const char *out_baseimg_param; | ||
54 | char *options = NULL; | ||
55 | - const char *snapshot_name = NULL; | ||
56 | - int min_sparse = 8; /* Need at least 4k of zeros for sparse detection */ | ||
57 | - bool quiet = false; | ||
58 | Error *local_err = NULL; | ||
59 | - QemuOpts *sn_opts = NULL; | ||
60 | - ImgConvertState state; | ||
61 | - bool image_opts = false; | ||
62 | - bool wr_in_order = true; | ||
63 | - long num_coroutines = 8; | ||
64 | + bool writethrough, src_writethrough, quiet = false, image_opts = false, | ||
65 | + skip_create = false, progress = false; | ||
66 | + int64_t ret = -EINVAL; | ||
67 | + | ||
68 | + ImgConvertState s = (ImgConvertState) { | ||
69 | + /* Need at least 4k of zeros for sparse detection */ | ||
70 | + .min_sparse = 8, | ||
71 | + .buf_sectors = IO_BUF_SIZE / BDRV_SECTOR_SIZE, | ||
72 | + .wr_in_order = true, | ||
73 | + .num_coroutines = 8, | ||
74 | + }; | ||
75 | |||
76 | - fmt = NULL; | ||
77 | - out_fmt = "raw"; | ||
78 | - cache = "unsafe"; | ||
79 | - src_cache = BDRV_DEFAULT_CACHE; | ||
80 | - out_baseimg = NULL; | ||
81 | - compress = 0; | ||
82 | - skip_create = 0; | ||
83 | for(;;) { | ||
84 | static const struct option long_options[] = { | ||
85 | {"help", no_argument, 0, 'h'}, | ||
86 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
87 | out_baseimg = optarg; | ||
88 | break; | ||
89 | case 'c': | ||
90 | - compress = 1; | ||
91 | + s.compressed = true; | ||
92 | break; | ||
93 | case 'e': | ||
94 | error_report("option -e is deprecated, please use \'-o " | ||
95 | "encryption\' instead!"); | ||
96 | - ret = -1; | ||
97 | goto fail_getopt; | ||
98 | case '6': | ||
99 | error_report("option -6 is deprecated, please use \'-o " | ||
100 | "compat6\' instead!"); | ||
101 | - ret = -1; | ||
102 | goto fail_getopt; | ||
103 | case 'o': | ||
104 | if (!is_valid_option_list(optarg)) { | ||
105 | error_report("Invalid option list: %s", optarg); | ||
106 | - ret = -1; | ||
107 | goto fail_getopt; | ||
108 | } | ||
109 | if (!options) { | ||
110 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
111 | if (!sn_opts) { | ||
112 | error_report("Failed in parsing snapshot param '%s'", | ||
113 | optarg); | ||
114 | - ret = -1; | ||
115 | goto fail_getopt; | ||
116 | } | ||
117 | } else { | ||
118 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
119 | sval = cvtnum(optarg); | ||
120 | if (sval < 0) { | ||
121 | error_report("Invalid minimum zero buffer size for sparse output specified"); | ||
122 | - ret = -1; | ||
123 | goto fail_getopt; | ||
124 | } | ||
125 | |||
126 | - min_sparse = sval / BDRV_SECTOR_SIZE; | ||
127 | + s.min_sparse = sval / BDRV_SECTOR_SIZE; | ||
128 | break; | ||
129 | } | ||
130 | case 'p': | ||
131 | - progress = 1; | ||
132 | + progress = true; | ||
133 | break; | ||
134 | case 't': | ||
135 | cache = optarg; | ||
136 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
137 | quiet = true; | ||
138 | break; | ||
139 | case 'n': | ||
140 | - skip_create = 1; | ||
141 | + skip_create = true; | ||
142 | break; | ||
143 | case 'm': | ||
144 | - if (qemu_strtol(optarg, NULL, 0, &num_coroutines) || | ||
145 | - num_coroutines < 1 || num_coroutines > MAX_COROUTINES) { | ||
146 | + if (qemu_strtol(optarg, NULL, 0, &s.num_coroutines) || | ||
147 | + s.num_coroutines < 1 || s.num_coroutines > MAX_COROUTINES) { | ||
148 | error_report("Invalid number of coroutines. Allowed number of" | ||
149 | " coroutines is between 1 and %d", MAX_COROUTINES); | ||
150 | - ret = -1; | ||
151 | goto fail_getopt; | ||
152 | } | ||
153 | break; | ||
154 | case 'W': | ||
155 | - wr_in_order = false; | ||
156 | + s.wr_in_order = false; | ||
157 | break; | ||
158 | case OPTION_OBJECT: | ||
159 | opts = qemu_opts_parse_noisily(&qemu_object_opts, | ||
160 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
161 | goto fail_getopt; | ||
162 | } | 20 | } |
163 | 21 | ||
164 | - if (!wr_in_order && compress) { | 22 | - qemu_mutex_lock(&stats->lock); |
165 | + if (!s.wr_in_order && s.compressed) { | 23 | - |
166 | error_report("Out of order write and compress are mutually exclusive"); | 24 | - if (failed) { |
167 | - ret = -1; | 25 | - stats->failed_ops[cookie->type]++; |
168 | goto fail_getopt; | 26 | - } else { |
169 | } | 27 | - stats->nr_bytes[cookie->type] += cookie->bytes; |
170 | 28 | - stats->nr_ops[cookie->type]++; | |
171 | - /* Initialize before goto out */ | ||
172 | - if (quiet) { | ||
173 | - progress = 0; | ||
174 | - } | 29 | - } |
175 | - qemu_progress_init(progress, 1.0); | 30 | + WITH_QEMU_LOCK_GUARD(&stats->lock) { |
176 | - | 31 | + if (failed) { |
177 | - bs_n = argc - optind - 1; | 32 | + stats->failed_ops[cookie->type]++; |
178 | - out_filename = bs_n >= 1 ? argv[argc - 1] : NULL; | 33 | + } else { |
179 | + s.src_num = argc - optind - 1; | 34 | + stats->nr_bytes[cookie->type] += cookie->bytes; |
180 | + out_filename = s.src_num >= 1 ? argv[argc - 1] : NULL; | 35 | + stats->nr_ops[cookie->type]++; |
181 | 36 | + } | |
182 | if (options && has_help_option(options)) { | 37 | |
183 | ret = print_block_option_help(out_filename, out_fmt); | 38 | - block_latency_histogram_account(&stats->latency_histogram[cookie->type], |
184 | - goto out; | 39 | - latency_ns); |
185 | + goto fail_getopt; | 40 | + block_latency_histogram_account(&stats->latency_histogram[cookie->type], |
186 | } | 41 | + latency_ns); |
187 | 42 | ||
188 | - if (bs_n < 1) { | 43 | - if (!failed || stats->account_failed) { |
189 | - error_exit("Must specify image file name"); | 44 | - stats->total_time_ns[cookie->type] += latency_ns; |
190 | + if (s.src_num < 1) { | 45 | - stats->last_access_time_ns = time_ns; |
191 | + error_report("Must specify image file name"); | 46 | + if (!failed || stats->account_failed) { |
192 | + goto fail_getopt; | 47 | + stats->total_time_ns[cookie->type] += latency_ns; |
193 | } | 48 | + stats->last_access_time_ns = time_ns; |
194 | 49 | ||
195 | 50 | - QSLIST_FOREACH(s, &stats->intervals, entries) { | |
196 | - if (bs_n > 1 && out_baseimg) { | 51 | - timed_average_account(&s->latency[cookie->type], latency_ns); |
197 | + if (s.src_num > 1 && out_baseimg) { | 52 | + QSLIST_FOREACH(s, &stats->intervals, entries) { |
198 | error_report("-B makes no sense when concatenating multiple input " | 53 | + timed_average_account(&s->latency[cookie->type], latency_ns); |
199 | "images"); | 54 | + } |
200 | - ret = -1; | ||
201 | - goto out; | ||
202 | + goto fail_getopt; | ||
203 | } | ||
204 | |||
205 | - src_flags = 0; | ||
206 | + /* ret is still -EINVAL until here */ | ||
207 | ret = bdrv_parse_cache_mode(src_cache, &src_flags, &src_writethrough); | ||
208 | if (ret < 0) { | ||
209 | error_report("Invalid source cache option: %s", src_cache); | ||
210 | - goto out; | ||
211 | + goto fail_getopt; | ||
212 | } | ||
213 | |||
214 | + /* Initialize before goto out */ | ||
215 | + if (quiet) { | ||
216 | + progress = false; | ||
217 | + } | ||
218 | + qemu_progress_init(progress, 1.0); | ||
219 | qemu_progress_print(0, 100); | ||
220 | |||
221 | - blk = g_new0(BlockBackend *, bs_n); | ||
222 | - bs = g_new0(BlockDriverState *, bs_n); | ||
223 | - bs_sectors = g_new(int64_t, bs_n); | ||
224 | + s.src = g_new0(BlockBackend *, s.src_num); | ||
225 | + s.src_sectors = g_new(int64_t, s.src_num); | ||
226 | |||
227 | - total_sectors = 0; | ||
228 | - for (bs_i = 0; bs_i < bs_n; bs_i++) { | ||
229 | - blk[bs_i] = img_open(image_opts, argv[optind + bs_i], | ||
230 | - fmt, src_flags, src_writethrough, quiet); | ||
231 | - if (!blk[bs_i]) { | ||
232 | + for (bs_i = 0; bs_i < s.src_num; bs_i++) { | ||
233 | + s.src[bs_i] = img_open(image_opts, argv[optind + bs_i], | ||
234 | + fmt, src_flags, src_writethrough, quiet); | ||
235 | + if (!s.src[bs_i]) { | ||
236 | ret = -1; | ||
237 | goto out; | ||
238 | } | ||
239 | - bs[bs_i] = blk_bs(blk[bs_i]); | ||
240 | - bs_sectors[bs_i] = blk_nb_sectors(blk[bs_i]); | ||
241 | - if (bs_sectors[bs_i] < 0) { | ||
242 | + s.src_sectors[bs_i] = blk_nb_sectors(s.src[bs_i]); | ||
243 | + if (s.src_sectors[bs_i] < 0) { | ||
244 | error_report("Could not get size of %s: %s", | ||
245 | - argv[optind + bs_i], strerror(-bs_sectors[bs_i])); | ||
246 | + argv[optind + bs_i], strerror(-s.src_sectors[bs_i])); | ||
247 | ret = -1; | ||
248 | goto out; | ||
249 | } | ||
250 | - total_sectors += bs_sectors[bs_i]; | ||
251 | + s.total_sectors += s.src_sectors[bs_i]; | ||
252 | } | ||
253 | |||
254 | if (sn_opts) { | ||
255 | - bdrv_snapshot_load_tmp(bs[0], | ||
256 | + bdrv_snapshot_load_tmp(blk_bs(s.src[0]), | ||
257 | qemu_opt_get(sn_opts, SNAPSHOT_OPT_ID), | ||
258 | qemu_opt_get(sn_opts, SNAPSHOT_OPT_NAME), | ||
259 | &local_err); | ||
260 | } else if (snapshot_name != NULL) { | ||
261 | - if (bs_n > 1) { | ||
262 | + if (s.src_num > 1) { | ||
263 | error_report("No support for concatenating multiple snapshot"); | ||
264 | ret = -1; | ||
265 | goto out; | ||
266 | } | ||
267 | |||
268 | - bdrv_snapshot_load_tmp_by_id_or_name(bs[0], snapshot_name, &local_err); | ||
269 | + bdrv_snapshot_load_tmp_by_id_or_name(blk_bs(s.src[0]), snapshot_name, | ||
270 | + &local_err); | ||
271 | } | ||
272 | if (local_err) { | ||
273 | error_reportf_err(local_err, "Failed to load snapshot: "); | ||
274 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
275 | } | ||
276 | } | ||
277 | |||
278 | - qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_sectors * 512, | ||
279 | + qemu_opt_set_number(opts, BLOCK_OPT_SIZE, s.total_sectors * 512, | ||
280 | &error_abort); | ||
281 | ret = add_old_style_options(out_fmt, opts, out_baseimg, NULL); | ||
282 | if (ret < 0) { | ||
283 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
284 | if (out_baseimg_param) { | ||
285 | out_baseimg = out_baseimg_param; | ||
286 | } | ||
287 | + s.target_has_backing = (bool) out_baseimg; | ||
288 | |||
289 | /* Check if compression is supported */ | ||
290 | - if (compress) { | ||
291 | + if (s.compressed) { | ||
292 | bool encryption = | ||
293 | qemu_opt_get_bool(opts, BLOCK_OPT_ENCRYPT, false); | ||
294 | const char *preallocation = | ||
295 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
296 | } | 55 | } |
297 | } | 56 | } |
298 | 57 | ||
299 | - flags = min_sparse ? (BDRV_O_RDWR | BDRV_O_UNMAP) : BDRV_O_RDWR; | 58 | - qemu_mutex_unlock(&stats->lock); |
300 | + flags = s.min_sparse ? (BDRV_O_RDWR | BDRV_O_UNMAP) : BDRV_O_RDWR; | ||
301 | ret = bdrv_parse_cache_mode(cache, &flags, &writethrough); | ||
302 | if (ret < 0) { | ||
303 | error_report("Invalid cache option: %s", cache); | ||
304 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
305 | * the bdrv_create() call which takes different params. | ||
306 | * Not critical right now, so fix can wait... | ||
307 | */ | ||
308 | - out_blk = img_open_file(out_filename, out_fmt, flags, writethrough, quiet); | ||
309 | - if (!out_blk) { | ||
310 | + s.target = img_open_file(out_filename, out_fmt, flags, writethrough, quiet); | ||
311 | + if (!s.target) { | ||
312 | ret = -1; | ||
313 | goto out; | ||
314 | } | ||
315 | - out_bs = blk_bs(out_blk); | ||
316 | + out_bs = blk_bs(s.target); | ||
317 | |||
318 | /* increase bufsectors from the default 4096 (2M) if opt_transfer | ||
319 | * or discard_alignment of the out_bs is greater. Limit to 32768 (16MB) | ||
320 | * as maximum. */ | ||
321 | - bufsectors = MIN(32768, | ||
322 | - MAX(bufsectors, | ||
323 | - MAX(out_bs->bl.opt_transfer >> BDRV_SECTOR_BITS, | ||
324 | - out_bs->bl.pdiscard_alignment >> | ||
325 | - BDRV_SECTOR_BITS))); | ||
326 | + s.buf_sectors = MIN(32768, | ||
327 | + MAX(s.buf_sectors, | ||
328 | + MAX(out_bs->bl.opt_transfer >> BDRV_SECTOR_BITS, | ||
329 | + out_bs->bl.pdiscard_alignment >> | ||
330 | + BDRV_SECTOR_BITS))); | ||
331 | |||
332 | if (skip_create) { | ||
333 | - int64_t output_sectors = blk_nb_sectors(out_blk); | ||
334 | + int64_t output_sectors = blk_nb_sectors(s.target); | ||
335 | if (output_sectors < 0) { | ||
336 | error_report("unable to get output image length: %s", | ||
337 | strerror(-output_sectors)); | ||
338 | ret = -1; | ||
339 | goto out; | ||
340 | - } else if (output_sectors < total_sectors) { | ||
341 | + } else if (output_sectors < s.total_sectors) { | ||
342 | error_report("output file is smaller than input file"); | ||
343 | ret = -1; | ||
344 | goto out; | ||
345 | } | ||
346 | } | ||
347 | |||
348 | - cluster_sectors = 0; | ||
349 | ret = bdrv_get_info(out_bs, &bdi); | ||
350 | if (ret < 0) { | ||
351 | - if (compress) { | ||
352 | + if (s.compressed) { | ||
353 | error_report("could not get block driver info"); | ||
354 | goto out; | ||
355 | } | ||
356 | } else { | ||
357 | - compress = compress || bdi.needs_compressed_writes; | ||
358 | - cluster_sectors = bdi.cluster_size / BDRV_SECTOR_SIZE; | ||
359 | - } | ||
360 | - | 59 | - |
361 | - state = (ImgConvertState) { | 60 | cookie->type = BLOCK_ACCT_NONE; |
362 | - .src = blk, | ||
363 | - .src_sectors = bs_sectors, | ||
364 | - .src_num = bs_n, | ||
365 | - .total_sectors = total_sectors, | ||
366 | - .target = out_blk, | ||
367 | - .compressed = compress, | ||
368 | - .target_has_backing = (bool) out_baseimg, | ||
369 | - .min_sparse = min_sparse, | ||
370 | - .cluster_sectors = cluster_sectors, | ||
371 | - .buf_sectors = bufsectors, | ||
372 | - .wr_in_order = wr_in_order, | ||
373 | - .num_coroutines = num_coroutines, | ||
374 | - }; | ||
375 | - ret = convert_do_copy(&state); | ||
376 | + s.compressed = s.compressed || bdi.needs_compressed_writes; | ||
377 | + s.cluster_sectors = bdi.cluster_size / BDRV_SECTOR_SIZE; | ||
378 | + } | ||
379 | |||
380 | + ret = convert_do_copy(&s); | ||
381 | out: | ||
382 | if (!ret) { | ||
383 | qemu_progress_print(100, 0); | ||
384 | @@ -XXX,XX +XXX,XX @@ out: | ||
385 | qemu_opts_del(opts); | ||
386 | qemu_opts_free(create_opts); | ||
387 | qemu_opts_del(sn_opts); | ||
388 | - blk_unref(out_blk); | ||
389 | - g_free(bs); | ||
390 | - if (blk) { | ||
391 | - for (bs_i = 0; bs_i < bs_n; bs_i++) { | ||
392 | - blk_unref(blk[bs_i]); | ||
393 | + blk_unref(s.target); | ||
394 | + if (s.src) { | ||
395 | + for (bs_i = 0; bs_i < s.src_num; bs_i++) { | ||
396 | + blk_unref(s.src[bs_i]); | ||
397 | } | ||
398 | - g_free(blk); | ||
399 | + g_free(s.src); | ||
400 | } | ||
401 | - g_free(bs_sectors); | ||
402 | + g_free(s.src_sectors); | ||
403 | fail_getopt: | ||
404 | g_free(options); | ||
405 | |||
406 | - if (ret) { | ||
407 | - return 1; | ||
408 | - } | ||
409 | - return 0; | ||
410 | + return !!ret; | ||
411 | } | 61 | } |
412 | 62 | ||
413 | |||
414 | -- | 63 | -- |
415 | 1.8.3.1 | 64 | 2.29.2 |
416 | 65 | ||
417 | 66 | diff view generated by jsdifflib |
1 | From: Klim Kireev <proffk@virtuozzo.mipt.ru> | 1 | From: Gan Qixin <ganqixin@huawei.com> |
---|---|---|---|
2 | 2 | ||
3 | Signed-off-by: Klim Kireev <proffk@virtuozzo.mipt.ru> | 3 | Replace manual lock()/unlock() calls with lock guard macros |
4 | Signed-off-by: Denis V. Lunev <den@openvz.org> | 4 | (QEMU_LOCK_GUARD/WITH_QEMU_LOCK_GUARD) in block/curl. |
5 | CC: Kevin Wolf <kwolf@redhat.com> | 5 | |
6 | CC: Max Reitz <mreitz@redhat.com> | 6 | Signed-off-by: Gan Qixin <ganqixin@huawei.com> |
7 | Message-id: 1491405505-31620-2-git-send-email-den@openvz.org | 7 | Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> |
8 | Reviewed-by: Eric Blake <eblake@redhat.com> | 8 | Message-Id: <20201203075055.127773-3-ganqixin@huawei.com> |
9 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 9 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
10 | --- | 10 | --- |
11 | include/block/block_int.h | 6 +++--- | 11 | block/curl.c | 28 ++++++++++++++-------------- |
12 | 1 file changed, 3 insertions(+), 3 deletions(-) | 12 | 1 file changed, 14 insertions(+), 14 deletions(-) |
13 | 13 | ||
14 | diff --git a/include/block/block_int.h b/include/block/block_int.h | 14 | diff --git a/block/curl.c b/block/curl.c |
15 | index XXXXXXX..XXXXXXX 100644 | 15 | index XXXXXXX..XXXXXXX 100644 |
16 | --- a/include/block/block_int.h | 16 | --- a/block/curl.c |
17 | +++ b/include/block/block_int.h | 17 | +++ b/block/curl.c |
18 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | 18 | @@ -XXX,XX +XXX,XX @@ static void curl_detach_aio_context(BlockDriverState *bs) |
19 | * Returns 0 for completed check, -errno for internal errors. | 19 | BDRVCURLState *s = bs->opaque; |
20 | * The check results are stored in result. | 20 | int i; |
21 | */ | 21 | |
22 | - int (*bdrv_check)(BlockDriverState* bs, BdrvCheckResult *result, | 22 | - qemu_mutex_lock(&s->mutex); |
23 | + int (*bdrv_check)(BlockDriverState *bs, BdrvCheckResult *result, | 23 | - for (i = 0; i < CURL_NUM_STATES; i++) { |
24 | BdrvCheckMode fix); | 24 | - if (s->states[i].in_use) { |
25 | 25 | - curl_clean_state(&s->states[i]); | |
26 | int (*bdrv_amend_options)(BlockDriverState *bs, QemuOpts *opts, | 26 | + WITH_QEMU_LOCK_GUARD(&s->mutex) { |
27 | @@ -XXX,XX +XXX,XX @@ struct BdrvChildRole { | 27 | + for (i = 0; i < CURL_NUM_STATES; i++) { |
28 | /* Returns a name that is supposedly more useful for human users than the | 28 | + if (s->states[i].in_use) { |
29 | * node name for identifying the node in question (in particular, a BB | 29 | + curl_clean_state(&s->states[i]); |
30 | * name), or NULL if the parent can't provide a better name. */ | 30 | + } |
31 | - const char* (*get_name)(BdrvChild *child); | 31 | + if (s->states[i].curl) { |
32 | + const char *(*get_name)(BdrvChild *child); | 32 | + curl_easy_cleanup(s->states[i].curl); |
33 | 33 | + s->states[i].curl = NULL; | |
34 | /* Returns a malloced string that describes the parent of the child for a | 34 | + } |
35 | * human reader. This could be a node-name, BlockBackend name, qdev ID or | 35 | + g_free(s->states[i].orig_buf); |
36 | * QOM path of the device owning the BlockBackend, job type and ID etc. The | 36 | + s->states[i].orig_buf = NULL; |
37 | * caller is responsible for freeing the memory. */ | 37 | } |
38 | - char* (*get_parent_desc)(BdrvChild *child); | 38 | - if (s->states[i].curl) { |
39 | + char *(*get_parent_desc)(BdrvChild *child); | 39 | - curl_easy_cleanup(s->states[i].curl); |
40 | 40 | - s->states[i].curl = NULL; | |
41 | /* | 41 | + if (s->multi) { |
42 | * If this pair of functions is implemented, the parent doesn't issue new | 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; | ||
51 | } | ||
52 | - qemu_mutex_unlock(&s->mutex); | ||
53 | |||
54 | timer_del(&s->timer); | ||
55 | } | ||
43 | -- | 56 | -- |
44 | 1.8.3.1 | 57 | 2.29.2 |
45 | 58 | ||
46 | 59 | diff view generated by jsdifflib |
1 | From: Lidong Chen <lidongchen@tencent.com> | 1 | From: Gan Qixin <ganqixin@huawei.com> |
---|---|---|---|
2 | 2 | ||
3 | When the buffer is zero, blk_co_pwrite_zeroes is more effective than | 3 | Replace manual lock()/unlock() calls with lock guard macros |
4 | blk_co_pwritev with BDRV_REQ_WRITE_COMPRESSED. This patch can reduce | 4 | (QEMU_LOCK_GUARD/WITH_QEMU_LOCK_GUARD) in block/throttle-groups. |
5 | the time for converting qcow2 images with lots of zero data. | ||
6 | 5 | ||
7 | Signed-off-by: Lidong Chen <lidongchen@tencent.com> | 6 | Signed-off-by: Gan Qixin <ganqixin@huawei.com> |
8 | Message-id: 1493261907-18734-1-git-send-email-lidongchen@tencent.com | 7 | Message-Id: <20201203075055.127773-4-ganqixin@huawei.com> |
9 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 8 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
10 | --- | 9 | --- |
11 | qemu-img.c | 44 ++++++++++++++------------------------------ | 10 | block/throttle-groups.c | 48 ++++++++++++++++++++--------------------- |
12 | 1 file changed, 14 insertions(+), 30 deletions(-) | 11 | 1 file changed, 23 insertions(+), 25 deletions(-) |
13 | 12 | ||
14 | diff --git a/qemu-img.c b/qemu-img.c | 13 | diff --git a/block/throttle-groups.c b/block/throttle-groups.c |
15 | index XXXXXXX..XXXXXXX 100644 | 14 | index XXXXXXX..XXXXXXX 100644 |
16 | --- a/qemu-img.c | 15 | --- a/block/throttle-groups.c |
17 | +++ b/qemu-img.c | 16 | +++ b/block/throttle-groups.c |
18 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn convert_co_write(ImgConvertState *s, int64_t sector_num, | 17 | @@ -XXX,XX +XXX,XX @@ void throttle_group_register_tgm(ThrottleGroupMember *tgm, |
19 | 18 | tgm->aio_context = ctx; | |
20 | while (nb_sectors > 0) { | 19 | qatomic_set(&tgm->restart_pending, 0); |
21 | int n = nb_sectors; | 20 | |
22 | + BdrvRequestFlags flags = s->compressed ? BDRV_REQ_WRITE_COMPRESSED : 0; | 21 | - qemu_mutex_lock(&tg->lock); |
23 | + | 22 | + QEMU_LOCK_GUARD(&tg->lock); |
24 | switch (status) { | 23 | /* If the ThrottleGroup is new set this ThrottleGroupMember as the token */ |
25 | case BLK_BACKING_FILE: | 24 | for (i = 0; i < 2; i++) { |
26 | /* If we have a backing file, leave clusters unallocated that are | 25 | if (!tg->tokens[i]) { |
27 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn convert_co_write(ImgConvertState *s, int64_t sector_num, | 26 | @@ -XXX,XX +XXX,XX @@ void throttle_group_register_tgm(ThrottleGroupMember *tgm, |
28 | break; | 27 | qemu_co_mutex_init(&tgm->throttled_reqs_lock); |
29 | 28 | qemu_co_queue_init(&tgm->throttled_reqs[0]); | |
30 | case BLK_DATA: | 29 | qemu_co_queue_init(&tgm->throttled_reqs[1]); |
31 | - /* We must always write compressed clusters as a whole, so don't | ||
32 | - * try to find zeroed parts in the buffer. We can only save the | ||
33 | - * write if the buffer is completely zeroed and we're allowed to | ||
34 | - * keep the target sparse. */ | ||
35 | - if (s->compressed) { | ||
36 | - if (s->has_zero_init && s->min_sparse && | ||
37 | - buffer_is_zero(buf, n * BDRV_SECTOR_SIZE)) | ||
38 | - { | ||
39 | - assert(!s->target_has_backing); | ||
40 | - break; | ||
41 | - } | ||
42 | - | 30 | - |
43 | - iov.iov_base = buf; | 31 | - qemu_mutex_unlock(&tg->lock); |
44 | - iov.iov_len = n << BDRV_SECTOR_BITS; | 32 | } |
45 | - qemu_iovec_init_external(&qiov, &iov, 1); | 33 | |
46 | - | 34 | /* Unregister a ThrottleGroupMember from its group, removing it from the list, |
47 | - ret = blk_co_pwritev(s->target, sector_num << BDRV_SECTOR_BITS, | 35 | @@ -XXX,XX +XXX,XX @@ void throttle_group_unregister_tgm(ThrottleGroupMember *tgm) |
48 | - n << BDRV_SECTOR_BITS, &qiov, | 36 | /* Wait for throttle_group_restart_queue_entry() coroutines to finish */ |
49 | - BDRV_REQ_WRITE_COMPRESSED); | 37 | AIO_WAIT_WHILE(tgm->aio_context, qatomic_read(&tgm->restart_pending) > 0); |
50 | - if (ret < 0) { | 38 | |
51 | - return ret; | 39 | - qemu_mutex_lock(&tg->lock); |
52 | - } | 40 | - for (i = 0; i < 2; i++) { |
53 | - break; | 41 | - assert(tgm->pending_reqs[i] == 0); |
54 | - } | 42 | - assert(qemu_co_queue_empty(&tgm->throttled_reqs[i])); |
55 | - | 43 | - assert(!timer_pending(tgm->throttle_timers.timers[i])); |
56 | - /* If there is real non-zero data or we're told to keep the target | 44 | - if (tg->tokens[i] == tgm) { |
57 | - * fully allocated (-S 0), we must write it. Otherwise we can treat | 45 | - token = throttle_group_next_tgm(tgm); |
58 | - * it as zero sectors. */ | 46 | - /* Take care of the case where this is the last tgm in the group */ |
59 | + /* If we're told to keep the target fully allocated (-S 0) or there | 47 | - if (token == tgm) { |
60 | + * is real non-zero data, we must write it. Otherwise we can treat | 48 | - token = NULL; |
61 | + * it as zero sectors. | 49 | + WITH_QEMU_LOCK_GUARD(&tg->lock) { |
62 | + * Compressed clusters need to be written as a whole, so in that | 50 | + for (i = 0; i < 2; i++) { |
63 | + * case we can only save the write if the buffer is completely | 51 | + assert(tgm->pending_reqs[i] == 0); |
64 | + * zeroed. */ | 52 | + assert(qemu_co_queue_empty(&tgm->throttled_reqs[i])); |
65 | if (!s->min_sparse || | 53 | + assert(!timer_pending(tgm->throttle_timers.timers[i])); |
66 | - is_allocated_sectors_min(buf, n, &n, s->min_sparse)) | 54 | + if (tg->tokens[i] == tgm) { |
67 | + (!s->compressed && | 55 | + token = throttle_group_next_tgm(tgm); |
68 | + is_allocated_sectors_min(buf, n, &n, s->min_sparse)) || | 56 | + /* Take care of the case where this is the last tgm in the group */ |
69 | + (s->compressed && | 57 | + if (token == tgm) { |
70 | + !buffer_is_zero(buf, n * BDRV_SECTOR_SIZE))) | 58 | + token = NULL; |
71 | { | 59 | + } |
72 | iov.iov_base = buf; | 60 | + tg->tokens[i] = token; |
73 | iov.iov_len = n << BDRV_SECTOR_BITS; | ||
74 | qemu_iovec_init_external(&qiov, &iov, 1); | ||
75 | |||
76 | ret = blk_co_pwritev(s->target, sector_num << BDRV_SECTOR_BITS, | ||
77 | - n << BDRV_SECTOR_BITS, &qiov, 0); | ||
78 | + n << BDRV_SECTOR_BITS, &qiov, flags); | ||
79 | if (ret < 0) { | ||
80 | return ret; | ||
81 | } | ||
82 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn convert_co_write(ImgConvertState *s, int64_t sector_num, | ||
83 | |||
84 | case BLK_ZERO: | ||
85 | if (s->has_zero_init) { | ||
86 | + assert(!s->target_has_backing); | ||
87 | break; | ||
88 | } | 61 | } |
89 | ret = blk_co_pwrite_zeroes(s->target, | 62 | - tg->tokens[i] = token; |
63 | } | ||
64 | - } | ||
65 | |||
66 | - /* remove the current tgm from the list */ | ||
67 | - QLIST_REMOVE(tgm, round_robin); | ||
68 | - throttle_timers_destroy(&tgm->throttle_timers); | ||
69 | - qemu_mutex_unlock(&tg->lock); | ||
70 | + /* remove the current tgm from the list */ | ||
71 | + QLIST_REMOVE(tgm, round_robin); | ||
72 | + throttle_timers_destroy(&tgm->throttle_timers); | ||
73 | + } | ||
74 | |||
75 | throttle_group_unref(&tg->ts); | ||
76 | tgm->throttle_state = NULL; | ||
77 | @@ -XXX,XX +XXX,XX @@ void throttle_group_detach_aio_context(ThrottleGroupMember *tgm) | ||
78 | assert(qemu_co_queue_empty(&tgm->throttled_reqs[1])); | ||
79 | |||
80 | /* Kick off next ThrottleGroupMember, if necessary */ | ||
81 | - qemu_mutex_lock(&tg->lock); | ||
82 | - for (i = 0; i < 2; i++) { | ||
83 | - if (timer_pending(tt->timers[i])) { | ||
84 | - tg->any_timer_armed[i] = false; | ||
85 | - schedule_next_request(tgm, i); | ||
86 | + WITH_QEMU_LOCK_GUARD(&tg->lock) { | ||
87 | + for (i = 0; i < 2; i++) { | ||
88 | + if (timer_pending(tt->timers[i])) { | ||
89 | + tg->any_timer_armed[i] = false; | ||
90 | + schedule_next_request(tgm, i); | ||
91 | + } | ||
92 | } | ||
93 | } | ||
94 | - qemu_mutex_unlock(&tg->lock); | ||
95 | |||
96 | throttle_timers_detach_aio_context(tt); | ||
97 | tgm->aio_context = NULL; | ||
90 | -- | 98 | -- |
91 | 1.8.3.1 | 99 | 2.29.2 |
92 | 100 | ||
93 | 101 | diff view generated by jsdifflib |
1 | We test for the presence of perl and bc and save their path in the | 1 | From: Gan Qixin <ganqixin@huawei.com> |
---|---|---|---|
2 | variables PERL_PROG and BC_PROG, but never actually make use of them. | ||
3 | Remove the checks and assignments so qemu-iotests can run even when | ||
4 | bc isn't installed. | ||
5 | 2 | ||
6 | Reported-by: Yash Mankad <ymankad@redhat.com> | 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> | ||
7 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 8 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
8 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
9 | Reviewed-by: Fam Zheng <famz@redhat.com> | ||
10 | --- | 9 | --- |
11 | tests/qemu-iotests/common.config | 6 ------ | 10 | block/iscsi.c | 50 ++++++++++++++++++++++++-------------------------- |
12 | 1 file changed, 6 deletions(-) | 11 | 1 file changed, 24 insertions(+), 26 deletions(-) |
13 | 12 | ||
14 | diff --git a/tests/qemu-iotests/common.config b/tests/qemu-iotests/common.config | 13 | diff --git a/block/iscsi.c b/block/iscsi.c |
15 | index XXXXXXX..XXXXXXX 100644 | 14 | index XXXXXXX..XXXXXXX 100644 |
16 | --- a/tests/qemu-iotests/common.config | 15 | --- a/block/iscsi.c |
17 | +++ b/tests/qemu-iotests/common.config | 16 | +++ b/block/iscsi.c |
18 | @@ -XXX,XX +XXX,XX @@ _fatal() | 17 | @@ -XXX,XX +XXX,XX @@ iscsi_aio_cancel(BlockAIOCB *blockacb) |
19 | exit 1 | 18 | IscsiAIOCB *acb = (IscsiAIOCB *)blockacb; |
19 | IscsiLun *iscsilun = acb->iscsilun; | ||
20 | |||
21 | - qemu_mutex_lock(&iscsilun->mutex); | ||
22 | + WITH_QEMU_LOCK_GUARD(&iscsilun->mutex) { | ||
23 | |||
24 | - /* If it was cancelled or completed already, our work is done here */ | ||
25 | - if (acb->cancelled || acb->status != -EINPROGRESS) { | ||
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; | ||
32 | + } | ||
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 | + } | ||
49 | } | ||
50 | - | ||
51 | - qemu_mutex_unlock(&iscsilun->mutex); | ||
20 | } | 52 | } |
21 | 53 | ||
22 | -export PERL_PROG="`set_prog_path perl`" | 54 | static const AIOCBInfo iscsi_aiocb_info = { |
23 | -[ "$PERL_PROG" = "" ] && _fatal "perl not found" | 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); | ||
24 | - | 84 | - |
25 | export AWK_PROG="`set_prog_path awk`" | 85 | - qemu_mutex_unlock(&iscsilun->mutex); |
26 | [ "$AWK_PROG" = "" ] && _fatal "awk not found" | ||
27 | |||
28 | export SED_PROG="`set_prog_path sed`" | ||
29 | [ "$SED_PROG" = "" ] && _fatal "sed not found" | ||
30 | |||
31 | -export BC_PROG="`set_prog_path bc`" | ||
32 | -[ "$BC_PROG" = "" ] && _fatal "bc not found" | ||
33 | - | 86 | - |
34 | export PS_ALL_FLAGS="-ef" | 87 | timer_mod(iscsilun->event_timer, |
35 | 88 | qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + EVENT_INTERVAL); | |
36 | if [ -z "$QEMU_PROG" ]; then | 89 | } |
37 | -- | 90 | -- |
38 | 1.8.3.1 | 91 | 2.29.2 |
39 | 92 | ||
40 | 93 | diff view generated by jsdifflib |
1 | From: Max Reitz <mreitz@redhat.com> | 1 | From: Max Reitz <mreitz@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | Currently we only print progress information on retrieval of SIGUSR1. | 3 | Signed-off-by: Max Reitz <mreitz@redhat.com> |
4 | Some systems have a dedicated SIGINFO for this, however, so it should be | 4 | Message-Id: <20201027190600.192171-2-mreitz@redhat.com> |
5 | handled appropriately if it is available. | 5 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
6 | --- | ||
7 | meson_options.txt | 2 ++ | ||
8 | configure | 7 +++++++ | ||
9 | meson.build | 6 ++++++ | ||
10 | 3 files changed, 15 insertions(+) | ||
6 | 11 | ||
7 | Buglink: https://bugs.launchpad.net/qemu/+bug/1662468 | 12 | diff --git a/meson_options.txt b/meson_options.txt |
8 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
9 | Message-id: 20170207235757.2026-1-mreitz@redhat.com | ||
10 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
11 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
12 | --- | ||
13 | qemu-img.texi | 3 ++- | ||
14 | util/qemu-progress.c | 3 +++ | ||
15 | 2 files changed, 5 insertions(+), 1 deletion(-) | ||
16 | |||
17 | diff --git a/qemu-img.texi b/qemu-img.texi | ||
18 | index XXXXXXX..XXXXXXX 100644 | 13 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/qemu-img.texi | 14 | --- a/meson_options.txt |
20 | +++ b/qemu-img.texi | 15 | +++ b/meson_options.txt |
21 | @@ -XXX,XX +XXX,XX @@ with or without a command shows help and lists the supported formats | 16 | @@ -XXX,XX +XXX,XX @@ option('virtiofsd', type: 'feature', value: 'auto', |
22 | @item -p | 17 | description: 'build virtiofs daemon (virtiofsd)') |
23 | display progress bar (compare, convert and rebase commands only). | 18 | option('vhost_user_blk_server', type: 'feature', value: 'auto', |
24 | If the @var{-p} option is not used for a command that supports it, the | 19 | description: 'build vhost-user-blk server') |
25 | -progress is reported when the process receives a @code{SIGUSR1} signal. | 20 | +option('fuse', type: 'feature', value: 'auto', |
26 | +progress is reported when the process receives a @code{SIGUSR1} or | 21 | + description: 'FUSE block device export') |
27 | +@code{SIGINFO} signal. | 22 | |
28 | @item -q | 23 | option('capstone', type: 'combo', value: 'auto', |
29 | Quiet mode - do not print any output (except errors). There's no progress bar | 24 | choices: ['disabled', 'enabled', 'auto', 'system', 'internal'], |
30 | in case both @var{-q} and @var{-p} options are used. | 25 | diff --git a/configure b/configure |
31 | diff --git a/util/qemu-progress.c b/util/qemu-progress.c | 26 | index XXXXXXX..XXXXXXX 100755 |
27 | --- a/configure | ||
28 | +++ b/configure | ||
29 | @@ -XXX,XX +XXX,XX @@ meson="" | ||
30 | ninja="" | ||
31 | skip_meson=no | ||
32 | gettext="" | ||
33 | +fuse="auto" | ||
34 | |||
35 | bogus_os="no" | ||
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 | ||
32 | index XXXXXXX..XXXXXXX 100644 | 65 | index XXXXXXX..XXXXXXX 100644 |
33 | --- a/util/qemu-progress.c | 66 | --- a/meson.build |
34 | +++ b/util/qemu-progress.c | 67 | +++ b/meson.build |
35 | @@ -XXX,XX +XXX,XX @@ static void progress_dummy_init(void) | 68 | @@ -XXX,XX +XXX,XX @@ elif get_option('vhost_user_blk_server').disabled() or not have_system |
36 | action.sa_handler = sigusr_print; | 69 | have_vhost_user_blk_server = false |
37 | action.sa_flags = 0; | 70 | endif |
38 | sigaction(SIGUSR1, &action, NULL); | 71 | |
39 | +#ifdef SIGINFO | 72 | +fuse = dependency('fuse3', required: get_option('fuse'), |
40 | + sigaction(SIGINFO, &action, NULL); | 73 | + version: '>=3.1', method: 'pkg-config', |
41 | +#endif | 74 | + static: enable_static) |
42 | 75 | + | |
43 | /* | 76 | ################# |
44 | * SIGUSR1 is SIG_IPI and gets blocked in qemu_init_main_loop(). In the | 77 | # config-host.h # |
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) | ||
45 | -- | 95 | -- |
46 | 1.8.3.1 | 96 | 2.29.2 |
47 | 97 | ||
48 | 98 | diff view generated by jsdifflib |
1 | From: Max Reitz <mreitz@redhat.com> | 1 | From: Max Reitz <mreitz@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | This reverts commit e3e0003a8f6570aba1421ef99a0b383a43371a74. | 3 | block-export-add type=fuse allows mounting block graph nodes via FUSE on |
4 | 4 | some existing regular file. That file should then appears like a raw | |
5 | This commit was necessary for the 2.9 release because we were unable to | 5 | disk image, and accesses to it result in accesses to the exported BDS. |
6 | fix the underlying issue(s) in time. However, we will be for 2.10. | 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. | ||
7 | 20 | ||
8 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 21 | Signed-off-by: Max Reitz <mreitz@redhat.com> |
9 | Acked-by: Fam Zheng <famz@redhat.com> | 22 | Message-Id: <20201027190600.192171-3-mreitz@redhat.com> |
10 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 23 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
11 | --- | 24 | --- |
12 | block.c | 6 +----- | 25 | qapi/block-export.json | 23 ++- |
13 | block/io.c | 12 ++---------- | 26 | include/block/fuse.h | 30 ++++ |
14 | 2 files changed, 3 insertions(+), 15 deletions(-) | 27 | block.c | 1 + |
15 | 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 | ||
16 | diff --git a/block.c b/block.c | 124 | diff --git a/block.c b/block.c |
17 | index XXXXXXX..XXXXXXX 100644 | 125 | index XXXXXXX..XXXXXXX 100644 |
18 | --- a/block.c | 126 | --- a/block.c |
19 | +++ b/block.c | 127 | +++ b/block.c |
20 | @@ -XXX,XX +XXX,XX @@ int bdrv_truncate(BdrvChild *child, int64_t offset) | 128 | @@ -XXX,XX +XXX,XX @@ |
21 | BlockDriver *drv = bs->drv; | 129 | #include "block/trace.h" |
22 | int ret; | 130 | #include "block/block_int.h" |
23 | 131 | #include "block/blockjob.h" | |
24 | - /* FIXME: Some format block drivers use this function instead of implicitly | 132 | +#include "block/fuse.h" |
25 | - * growing their file by writing beyond its end. | 133 | #include "block/nbd.h" |
26 | - * See bdrv_aligned_pwritev() for an explanation why we currently | 134 | #include "block/qdict.h" |
27 | - * cannot assert this permission in that case. */ | 135 | #include "qemu/error-report.h" |
28 | - // assert(child->perm & BLK_PERM_RESIZE); | 136 | diff --git a/block/export/export.c b/block/export/export.c |
29 | + assert(child->perm & BLK_PERM_RESIZE); | ||
30 | |||
31 | if (!drv) | ||
32 | return -ENOMEDIUM; | ||
33 | diff --git a/block/io.c b/block/io.c | ||
34 | index XXXXXXX..XXXXXXX 100644 | 137 | index XXXXXXX..XXXXXXX 100644 |
35 | --- a/block/io.c | 138 | --- a/block/export/export.c |
36 | +++ b/block/io.c | 139 | +++ b/block/export/export.c |
37 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child, | 140 | @@ -XXX,XX +XXX,XX @@ |
38 | assert(!waited || !req->serialising); | 141 | #include "sysemu/block-backend.h" |
39 | assert(req->overlap_offset <= offset); | 142 | #include "sysemu/iothread.h" |
40 | assert(offset + bytes <= req->overlap_offset + req->overlap_bytes); | 143 | #include "block/export.h" |
41 | - /* FIXME: Block migration uses the BlockBackend of the guest device at a | 144 | +#include "block/fuse.h" |
42 | - * point when it has not yet taken write permissions. This will be | 145 | #include "block/nbd.h" |
43 | - * fixed by a future patch, but for now we have to bypass this | 146 | #include "qapi/error.h" |
44 | - * assertion for block migration to work. */ | 147 | #include "qapi/qapi-commands-block-export.h" |
45 | - // assert(child->perm & BLK_PERM_WRITE); | 148 | @@ -XXX,XX +XXX,XX @@ static const BlockExportDriver *blk_exp_drivers[] = { |
46 | - /* FIXME: Because of the above, we also cannot guarantee that all format | 149 | #ifdef CONFIG_VHOST_USER_BLK_SERVER |
47 | - * BDS take the BLK_PERM_RESIZE permission on their file BDS, since | 150 | &blk_exp_vhost_user_blk, |
48 | - * they are not obligated to do so if they do not have any parent | 151 | #endif |
49 | - * that has taken the permission to write to them. */ | 152 | +#ifdef CONFIG_FUSE |
50 | - // assert(end_sector <= bs->total_sectors || child->perm & BLK_PERM_RESIZE); | 153 | + &blk_exp_fuse, |
51 | + assert(child->perm & BLK_PERM_WRITE); | 154 | +#endif |
52 | + assert(end_sector <= bs->total_sectors || child->perm & BLK_PERM_RESIZE); | 155 | }; |
53 | 156 | ||
54 | ret = notifier_with_return_list_notify(&bs->before_write_notifiers, req); | 157 | /* Only accessed from the main thread */ |
55 | 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')) | ||
56 | -- | 486 | -- |
57 | 1.8.3.1 | 487 | 2.29.2 |
58 | 488 | ||
59 | 489 | diff view generated by jsdifflib |
1 | From: Max Reitz <mreitz@redhat.com> | 1 | From: Max Reitz <mreitz@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | The block layer takes care of removing the bs->file child if the block | 3 | This makes the export actually useful instead of only producing errors |
4 | driver's bdrv_open()/bdrv_file_open() implementation fails. The block | 4 | whenever it is accessed. |
5 | driver therefore does not need to do so, and indeed should not unless it | 5 | |
6 | sets bs->file to NULL afterwards -- because if this is not done, the | ||
7 | bdrv_unref_child() in bdrv_open_inherit() will dereference the freed | ||
8 | memory block at bs->file afterwards, which is not good. | ||
9 | |||
10 | We can now decide whether to add a "bs->file = NULL;" after each of the | ||
11 | offending bdrv_unref_child() invocations, or just drop them altogether. | ||
12 | The latter is simpler, so let's do that. | ||
13 | |||
14 | Cc: qemu-stable <qemu-stable@nongnu.org> | ||
15 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 6 | Signed-off-by: Max Reitz <mreitz@redhat.com> |
16 | Reviewed-by: Eric Blake <eblake@redhat.com> | 7 | Message-Id: <20201027190600.192171-4-mreitz@redhat.com> |
17 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
18 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 8 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
19 | --- | 9 | --- |
20 | block/blkdebug.c | 4 +--- | 10 | block/export/fuse.c | 242 ++++++++++++++++++++++++++++++++++++++++++++ |
21 | block/blkreplay.c | 3 --- | 11 | 1 file changed, 242 insertions(+) |
22 | block/blkverify.c | 3 --- | 12 | |
23 | 3 files changed, 1 insertion(+), 9 deletions(-) | 13 | diff --git a/block/export/fuse.c b/block/export/fuse.c |
24 | |||
25 | diff --git a/block/blkdebug.c b/block/blkdebug.c | ||
26 | index XXXXXXX..XXXXXXX 100644 | 14 | index XXXXXXX..XXXXXXX 100644 |
27 | --- a/block/blkdebug.c | 15 | --- a/block/export/fuse.c |
28 | +++ b/block/blkdebug.c | 16 | +++ b/block/export/fuse.c |
29 | @@ -XXX,XX +XXX,XX @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags, | 17 | @@ -XXX,XX +XXX,XX @@ static void fuse_init(void *userdata, struct fuse_conn_info *conn) |
30 | } else if (align) { | 18 | conn->max_write = MIN_NON_ZERO(BDRV_REQUEST_MAX_BYTES, conn->max_write); |
31 | error_setg(errp, "Invalid alignment"); | ||
32 | ret = -EINVAL; | ||
33 | - goto fail_unref; | ||
34 | + goto out; | ||
35 | } | ||
36 | |||
37 | ret = 0; | ||
38 | goto out; | ||
39 | |||
40 | -fail_unref: | ||
41 | - bdrv_unref_child(bs, bs->file); | ||
42 | out: | ||
43 | if (ret < 0) { | ||
44 | g_free(s->config_file); | ||
45 | diff --git a/block/blkreplay.c b/block/blkreplay.c | ||
46 | index XXXXXXX..XXXXXXX 100755 | ||
47 | --- a/block/blkreplay.c | ||
48 | +++ b/block/blkreplay.c | ||
49 | @@ -XXX,XX +XXX,XX @@ static int blkreplay_open(BlockDriverState *bs, QDict *options, int flags, | ||
50 | |||
51 | ret = 0; | ||
52 | fail: | ||
53 | - if (ret < 0) { | ||
54 | - bdrv_unref_child(bs, bs->file); | ||
55 | - } | ||
56 | return ret; | ||
57 | } | 19 | } |
58 | 20 | ||
59 | diff --git a/block/blkverify.c b/block/blkverify.c | 21 | +/** |
60 | index XXXXXXX..XXXXXXX 100644 | 22 | + * Let clients look up files. Always return ENOENT because we only |
61 | --- a/block/blkverify.c | 23 | + * care about the mountpoint itself. |
62 | +++ b/block/blkverify.c | 24 | + */ |
63 | @@ -XXX,XX +XXX,XX @@ static int blkverify_open(BlockDriverState *bs, QDict *options, int flags, | 25 | +static void fuse_lookup(fuse_req_t req, fuse_ino_t parent, const char *name) |
64 | 26 | +{ | |
65 | ret = 0; | 27 | + fuse_reply_err(req, ENOENT); |
66 | fail: | 28 | +} |
67 | - if (ret < 0) { | 29 | + |
68 | - bdrv_unref_child(bs, bs->file); | 30 | +/** |
69 | - } | 31 | + * Let clients get file attributes (i.e., stat() the file). |
70 | qemu_opts_del(opts); | 32 | + */ |
71 | return ret; | 33 | +static void fuse_getattr(fuse_req_t req, fuse_ino_t inode, |
72 | } | 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 = { | ||
73 | -- | 268 | -- |
74 | 1.8.3.1 | 269 | 2.29.2 |
75 | 270 | ||
76 | 271 | diff view generated by jsdifflib |
1 | From: Max Reitz <mreitz@redhat.com> | 1 | From: Max Reitz <mreitz@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | For one thing, this allows us to drop the error message generation from | 3 | These will behave more like normal files in that writes beyond the EOF |
4 | qemu-img.c and blockdev.c and instead have it unified in | 4 | will automatically grow the export size. |
5 | bdrv_truncate(). | 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.) | ||
6 | 10 | ||
7 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 11 | Signed-off-by: Max Reitz <mreitz@redhat.com> |
8 | Message-id: 20170328205129.15138-3-mreitz@redhat.com | 12 | Message-Id: <20201027190600.192171-5-mreitz@redhat.com> |
9 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | 13 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
10 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
11 | --- | 14 | --- |
12 | block.c | 16 ++++++++++++---- | 15 | qapi/block-export.json | 6 +++++- |
13 | block/blkdebug.c | 2 +- | 16 | block/export/fuse.c | 44 ++++++++++++++++++++++++++++++++++-------- |
14 | block/block-backend.c | 5 +++-- | 17 | 2 files changed, 41 insertions(+), 9 deletions(-) |
15 | block/commit.c | 5 +++-- | ||
16 | block/crypto.c | 2 +- | ||
17 | block/mirror.c | 2 +- | ||
18 | block/parallels.c | 13 ++++++++----- | ||
19 | block/qcow.c | 6 +++--- | ||
20 | block/qcow2-refcount.c | 5 ++++- | ||
21 | block/qcow2.c | 14 +++++++++----- | ||
22 | block/qed.c | 2 +- | ||
23 | block/raw-format.c | 2 +- | ||
24 | block/vdi.c | 4 ++-- | ||
25 | block/vhdx-log.c | 2 +- | ||
26 | block/vhdx.c | 10 +++------- | ||
27 | block/vmdk.c | 13 +++---------- | ||
28 | block/vpc.c | 13 +++++++------ | ||
29 | blockdev.c | 21 +-------------------- | ||
30 | include/block/block.h | 2 +- | ||
31 | include/sysemu/block-backend.h | 2 +- | ||
32 | qemu-img.c | 17 ++++------------- | ||
33 | qemu-io-cmds.c | 5 +++-- | ||
34 | 22 files changed, 73 insertions(+), 90 deletions(-) | ||
35 | 18 | ||
36 | diff --git a/block.c b/block.c | 19 | diff --git a/qapi/block-export.json b/qapi/block-export.json |
37 | index XXXXXXX..XXXXXXX 100644 | 20 | index XXXXXXX..XXXXXXX 100644 |
38 | --- a/block.c | 21 | --- a/qapi/block-export.json |
39 | +++ b/block.c | 22 | +++ b/qapi/block-export.json |
40 | @@ -XXX,XX +XXX,XX @@ exit: | 23 | @@ -XXX,XX +XXX,XX @@ |
41 | /** | 24 | # @mountpoint: Path on which to export the block device via FUSE. |
42 | * Truncate file to 'offset' bytes (needed only for file protocols) | 25 | # This must point to an existing regular file. |
43 | */ | 26 | # |
44 | -int bdrv_truncate(BdrvChild *child, int64_t offset) | 27 | +# @growable: Whether writes beyond the EOF should grow the block node |
45 | +int bdrv_truncate(BdrvChild *child, int64_t offset, Error **errp) | 28 | +# accordingly. (default: false) |
46 | { | 29 | +# |
47 | BlockDriverState *bs = child->bs; | 30 | # Since: 6.0 |
48 | BlockDriver *drv = bs->drv; | 31 | ## |
49 | @@ -XXX,XX +XXX,XX @@ int bdrv_truncate(BdrvChild *child, int64_t offset) | 32 | { 'struct': 'BlockExportOptionsFuse', |
50 | 33 | - 'data': { 'mountpoint': 'str' }, | |
51 | assert(child->perm & BLK_PERM_RESIZE); | 34 | + 'data': { 'mountpoint': 'str', |
52 | 35 | + '*growable': 'bool' }, | |
53 | - if (!drv) | 36 | 'if': 'defined(CONFIG_FUSE)' } |
54 | + if (!drv) { | 37 | |
55 | + error_setg(errp, "No medium inserted"); | 38 | ## |
56 | return -ENOMEDIUM; | 39 | diff --git a/block/export/fuse.c b/block/export/fuse.c |
57 | - if (!drv->bdrv_truncate) | 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 | + } | ||
58 | + } | 66 | + } |
59 | + if (!drv->bdrv_truncate) { | 67 | + |
60 | + error_setg(errp, "Image format driver does not support resize"); | 68 | init_exports_table(); |
61 | return -ENOTSUP; | 69 | |
62 | - if (bs->read_only) | 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; | ||
81 | } | ||
82 | |||
83 | - blk_get_perm(exp->common.blk, &blk_perm, &blk_shared_perm); | ||
84 | + /* Growable exports have a permanent RESIZE permission */ | ||
85 | + if (!exp->growable) { | ||
86 | + blk_get_perm(exp->common.blk, &blk_perm, &blk_shared_perm); | ||
87 | |||
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); | ||
94 | + if (ret < 0) { | ||
95 | + return ret; | ||
96 | + } | ||
97 | } | ||
98 | |||
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); | ||
63 | + } | 107 | + } |
64 | + if (bs->read_only) { | 108 | |
65 | + error_setg(errp, "Image is read-only"); | ||
66 | return -EACCES; | ||
67 | + } | ||
68 | |||
69 | ret = drv->bdrv_truncate(bs, offset); | ||
70 | if (ret == 0) { | ||
71 | @@ -XXX,XX +XXX,XX @@ int bdrv_truncate(BdrvChild *child, int64_t offset) | ||
72 | bdrv_dirty_bitmap_truncate(bs); | ||
73 | bdrv_parent_cb_resize(bs); | ||
74 | ++bs->write_gen; | ||
75 | + } else { | ||
76 | + error_setg_errno(errp, -ret, "Failed to resize image"); | ||
77 | } | ||
78 | return ret; | 109 | return ret; |
79 | } | 110 | } |
80 | diff --git a/block/blkdebug.c b/block/blkdebug.c | 111 | @@ -XXX,XX +XXX,XX @@ static void fuse_write(fuse_req_t req, fuse_ino_t inode, const char *buf, |
81 | index XXXXXXX..XXXXXXX 100644 | ||
82 | --- a/block/blkdebug.c | ||
83 | +++ b/block/blkdebug.c | ||
84 | @@ -XXX,XX +XXX,XX @@ static int64_t blkdebug_getlength(BlockDriverState *bs) | ||
85 | |||
86 | static int blkdebug_truncate(BlockDriverState *bs, int64_t offset) | ||
87 | { | ||
88 | - return bdrv_truncate(bs->file, offset); | ||
89 | + return bdrv_truncate(bs->file, offset, NULL); | ||
90 | } | ||
91 | |||
92 | static void blkdebug_refresh_filename(BlockDriverState *bs, QDict *options) | ||
93 | diff --git a/block/block-backend.c b/block/block-backend.c | ||
94 | index XXXXXXX..XXXXXXX 100644 | ||
95 | --- a/block/block-backend.c | ||
96 | +++ b/block/block-backend.c | ||
97 | @@ -XXX,XX +XXX,XX @@ int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf, | ||
98 | BDRV_REQ_WRITE_COMPRESSED); | ||
99 | } | ||
100 | |||
101 | -int blk_truncate(BlockBackend *blk, int64_t offset) | ||
102 | +int blk_truncate(BlockBackend *blk, int64_t offset, Error **errp) | ||
103 | { | ||
104 | if (!blk_is_available(blk)) { | ||
105 | + error_setg(errp, "No medium inserted"); | ||
106 | return -ENOMEDIUM; | ||
107 | } | 112 | } |
108 | 113 | ||
109 | - return bdrv_truncate(blk->root, offset); | 114 | if (offset + size > length) { |
110 | + return bdrv_truncate(blk->root, offset, errp); | 115 | - size = length - offset; |
111 | } | 116 | + if (exp->growable) { |
112 | 117 | + ret = fuse_do_truncate(exp, offset + size, true, PREALLOC_MODE_OFF); | |
113 | static void blk_pdiscard_entry(void *opaque) | 118 | + if (ret < 0) { |
114 | diff --git a/block/commit.c b/block/commit.c | 119 | + fuse_reply_err(req, -ret); |
115 | index XXXXXXX..XXXXXXX 100644 | 120 | + return; |
116 | --- a/block/commit.c | 121 | + } |
117 | +++ b/block/commit.c | 122 | + } else { |
118 | @@ -XXX,XX +XXX,XX @@ static void coroutine_fn commit_run(void *opaque) | 123 | + size = length - offset; |
124 | + } | ||
119 | } | 125 | } |
120 | 126 | ||
121 | if (base_len < s->common.len) { | 127 | ret = blk_pwrite(exp->common.blk, offset, buf, size, 0); |
122 | - ret = blk_truncate(s->base, s->common.len); | ||
123 | + ret = blk_truncate(s->base, s->common.len, NULL); | ||
124 | if (ret) { | ||
125 | goto out; | ||
126 | } | ||
127 | @@ -XXX,XX +XXX,XX @@ int bdrv_commit(BlockDriverState *bs) | ||
128 | * grow the backing file image if possible. If not possible, | ||
129 | * we must return an error */ | ||
130 | if (length > backing_length) { | ||
131 | - ret = blk_truncate(backing, length); | ||
132 | + ret = blk_truncate(backing, length, &local_err); | ||
133 | if (ret < 0) { | ||
134 | + error_report_err(local_err); | ||
135 | goto ro_cleanup; | ||
136 | } | ||
137 | } | ||
138 | diff --git a/block/crypto.c b/block/crypto.c | ||
139 | index XXXXXXX..XXXXXXX 100644 | ||
140 | --- a/block/crypto.c | ||
141 | +++ b/block/crypto.c | ||
142 | @@ -XXX,XX +XXX,XX @@ static int block_crypto_truncate(BlockDriverState *bs, int64_t offset) | ||
143 | |||
144 | offset += payload_offset; | ||
145 | |||
146 | - return bdrv_truncate(bs->file, offset); | ||
147 | + return bdrv_truncate(bs->file, offset, NULL); | ||
148 | } | ||
149 | |||
150 | static void block_crypto_close(BlockDriverState *bs) | ||
151 | diff --git a/block/mirror.c b/block/mirror.c | ||
152 | index XXXXXXX..XXXXXXX 100644 | ||
153 | --- a/block/mirror.c | ||
154 | +++ b/block/mirror.c | ||
155 | @@ -XXX,XX +XXX,XX @@ static void coroutine_fn mirror_run(void *opaque) | ||
156 | } | ||
157 | |||
158 | if (s->bdev_length > base_length) { | ||
159 | - ret = blk_truncate(s->target, s->bdev_length); | ||
160 | + ret = blk_truncate(s->target, s->bdev_length, NULL); | ||
161 | if (ret < 0) { | ||
162 | goto immediate_exit; | ||
163 | } | ||
164 | diff --git a/block/parallels.c b/block/parallels.c | ||
165 | index XXXXXXX..XXXXXXX 100644 | ||
166 | --- a/block/parallels.c | ||
167 | +++ b/block/parallels.c | ||
168 | @@ -XXX,XX +XXX,XX @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num, | ||
169 | space << BDRV_SECTOR_BITS, 0); | ||
170 | } else { | ||
171 | ret = bdrv_truncate(bs->file, | ||
172 | - (s->data_end + space) << BDRV_SECTOR_BITS); | ||
173 | + (s->data_end + space) << BDRV_SECTOR_BITS, | ||
174 | + NULL); | ||
175 | } | ||
176 | if (ret < 0) { | ||
177 | return ret; | ||
178 | @@ -XXX,XX +XXX,XX @@ static int parallels_check(BlockDriverState *bs, BdrvCheckResult *res, | ||
179 | size - res->image_end_offset); | ||
180 | res->leaks += count; | ||
181 | if (fix & BDRV_FIX_LEAKS) { | ||
182 | - ret = bdrv_truncate(bs->file, res->image_end_offset); | ||
183 | + Error *local_err = NULL; | ||
184 | + ret = bdrv_truncate(bs->file, res->image_end_offset, &local_err); | ||
185 | if (ret < 0) { | ||
186 | + error_report_err(local_err); | ||
187 | res->check_errors++; | ||
188 | return ret; | ||
189 | } | ||
190 | @@ -XXX,XX +XXX,XX @@ static int parallels_create(const char *filename, QemuOpts *opts, Error **errp) | ||
191 | |||
192 | blk_set_allow_write_beyond_eof(file, true); | ||
193 | |||
194 | - ret = blk_truncate(file, 0); | ||
195 | + ret = blk_truncate(file, 0, errp); | ||
196 | if (ret < 0) { | ||
197 | goto exit; | ||
198 | } | ||
199 | @@ -XXX,XX +XXX,XX @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags, | ||
200 | } | ||
201 | |||
202 | if (!(flags & BDRV_O_RESIZE) || !bdrv_has_zero_init(bs->file->bs) || | ||
203 | - bdrv_truncate(bs->file, bdrv_getlength(bs->file->bs)) != 0) { | ||
204 | + bdrv_truncate(bs->file, bdrv_getlength(bs->file->bs), NULL) != 0) { | ||
205 | s->prealloc_mode = PRL_PREALLOC_MODE_FALLOCATE; | ||
206 | } | ||
207 | |||
208 | @@ -XXX,XX +XXX,XX @@ static void parallels_close(BlockDriverState *bs) | ||
209 | } | ||
210 | |||
211 | if (bs->open_flags & BDRV_O_RDWR) { | ||
212 | - bdrv_truncate(bs->file, s->data_end << BDRV_SECTOR_BITS); | ||
213 | + bdrv_truncate(bs->file, s->data_end << BDRV_SECTOR_BITS, NULL); | ||
214 | } | ||
215 | |||
216 | g_free(s->bat_dirty_bmap); | ||
217 | diff --git a/block/qcow.c b/block/qcow.c | ||
218 | index XXXXXXX..XXXXXXX 100644 | ||
219 | --- a/block/qcow.c | ||
220 | +++ b/block/qcow.c | ||
221 | @@ -XXX,XX +XXX,XX @@ static uint64_t get_cluster_offset(BlockDriverState *bs, | ||
222 | /* round to cluster size */ | ||
223 | cluster_offset = (cluster_offset + s->cluster_size - 1) & | ||
224 | ~(s->cluster_size - 1); | ||
225 | - bdrv_truncate(bs->file, cluster_offset + s->cluster_size); | ||
226 | + bdrv_truncate(bs->file, cluster_offset + s->cluster_size, NULL); | ||
227 | /* if encrypted, we must initialize the cluster | ||
228 | content which won't be written */ | ||
229 | if (bs->encrypted && | ||
230 | @@ -XXX,XX +XXX,XX @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp) | ||
231 | |||
232 | blk_set_allow_write_beyond_eof(qcow_blk, true); | ||
233 | |||
234 | - ret = blk_truncate(qcow_blk, 0); | ||
235 | + ret = blk_truncate(qcow_blk, 0, errp); | ||
236 | if (ret < 0) { | ||
237 | goto exit; | ||
238 | } | ||
239 | @@ -XXX,XX +XXX,XX @@ static int qcow_make_empty(BlockDriverState *bs) | ||
240 | if (bdrv_pwrite_sync(bs->file, s->l1_table_offset, s->l1_table, | ||
241 | l1_length) < 0) | ||
242 | return -1; | ||
243 | - ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length); | ||
244 | + ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length, NULL); | ||
245 | if (ret < 0) | ||
246 | return ret; | ||
247 | |||
248 | diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c | ||
249 | index XXXXXXX..XXXXXXX 100644 | ||
250 | --- a/block/qcow2-refcount.c | ||
251 | +++ b/block/qcow2-refcount.c | ||
252 | @@ -XXX,XX +XXX,XX @@ static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res, | ||
253 | |||
254 | if (fix & BDRV_FIX_ERRORS) { | ||
255 | int64_t new_nb_clusters; | ||
256 | + Error *local_err = NULL; | ||
257 | |||
258 | if (offset > INT64_MAX - s->cluster_size) { | ||
259 | ret = -EINVAL; | ||
260 | goto resize_fail; | ||
261 | } | ||
262 | |||
263 | - ret = bdrv_truncate(bs->file, offset + s->cluster_size); | ||
264 | + ret = bdrv_truncate(bs->file, offset + s->cluster_size, | ||
265 | + &local_err); | ||
266 | if (ret < 0) { | ||
267 | + error_report_err(local_err); | ||
268 | goto resize_fail; | ||
269 | } | ||
270 | size = bdrv_getlength(bs->file->bs); | ||
271 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
272 | index XXXXXXX..XXXXXXX 100644 | ||
273 | --- a/block/qcow2.c | ||
274 | +++ b/block/qcow2.c | ||
275 | @@ -XXX,XX +XXX,XX @@ static int qcow2_create2(const char *filename, int64_t total_size, | ||
276 | } | ||
277 | |||
278 | /* Okay, now that we have a valid image, let's give it the right size */ | ||
279 | - ret = blk_truncate(blk, total_size); | ||
280 | + ret = blk_truncate(blk, total_size, errp); | ||
281 | if (ret < 0) { | ||
282 | - error_setg_errno(errp, -ret, "Could not resize image"); | ||
283 | + error_prepend(errp, "Could not resize image: "); | ||
284 | goto out; | ||
285 | } | ||
286 | |||
287 | @@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset, | ||
288 | /* align end of file to a sector boundary to ease reading with | ||
289 | sector based I/Os */ | ||
290 | cluster_offset = bdrv_getlength(bs->file->bs); | ||
291 | - return bdrv_truncate(bs->file, cluster_offset); | ||
292 | + return bdrv_truncate(bs->file, cluster_offset, NULL); | ||
293 | } | ||
294 | |||
295 | buf = qemu_blockalign(bs, s->cluster_size); | ||
296 | @@ -XXX,XX +XXX,XX @@ fail: | ||
297 | static int make_completely_empty(BlockDriverState *bs) | ||
298 | { | ||
299 | BDRVQcow2State *s = bs->opaque; | ||
300 | + Error *local_err = NULL; | ||
301 | int ret, l1_clusters; | ||
302 | int64_t offset; | ||
303 | uint64_t *new_reftable = NULL; | ||
304 | @@ -XXX,XX +XXX,XX @@ static int make_completely_empty(BlockDriverState *bs) | ||
305 | goto fail; | ||
306 | } | ||
307 | |||
308 | - ret = bdrv_truncate(bs->file, (3 + l1_clusters) * s->cluster_size); | ||
309 | + ret = bdrv_truncate(bs->file, (3 + l1_clusters) * s->cluster_size, | ||
310 | + &local_err); | ||
311 | if (ret < 0) { | ||
312 | + error_report_err(local_err); | ||
313 | goto fail; | ||
314 | } | ||
315 | |||
316 | @@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts, | ||
317 | return ret; | ||
318 | } | ||
319 | |||
320 | - ret = blk_truncate(blk, new_size); | ||
321 | + ret = blk_truncate(blk, new_size, &local_err); | ||
322 | blk_unref(blk); | ||
323 | if (ret < 0) { | ||
324 | + error_report_err(local_err); | ||
325 | return ret; | ||
326 | } | ||
327 | } | ||
328 | diff --git a/block/qed.c b/block/qed.c | ||
329 | index XXXXXXX..XXXXXXX 100644 | ||
330 | --- a/block/qed.c | ||
331 | +++ b/block/qed.c | ||
332 | @@ -XXX,XX +XXX,XX @@ static int qed_create(const char *filename, uint32_t cluster_size, | ||
333 | blk_set_allow_write_beyond_eof(blk, true); | ||
334 | |||
335 | /* File must start empty and grow, check truncate is supported */ | ||
336 | - ret = blk_truncate(blk, 0); | ||
337 | + ret = blk_truncate(blk, 0, errp); | ||
338 | if (ret < 0) { | ||
339 | goto out; | ||
340 | } | ||
341 | diff --git a/block/raw-format.c b/block/raw-format.c | ||
342 | index XXXXXXX..XXXXXXX 100644 | ||
343 | --- a/block/raw-format.c | ||
344 | +++ b/block/raw-format.c | ||
345 | @@ -XXX,XX +XXX,XX @@ static int raw_truncate(BlockDriverState *bs, int64_t offset) | ||
346 | |||
347 | s->size = offset; | ||
348 | offset += s->offset; | ||
349 | - return bdrv_truncate(bs->file, offset); | ||
350 | + return bdrv_truncate(bs->file, offset, NULL); | ||
351 | } | ||
352 | |||
353 | static int raw_media_changed(BlockDriverState *bs) | ||
354 | diff --git a/block/vdi.c b/block/vdi.c | ||
355 | index XXXXXXX..XXXXXXX 100644 | ||
356 | --- a/block/vdi.c | ||
357 | +++ b/block/vdi.c | ||
358 | @@ -XXX,XX +XXX,XX @@ static int vdi_create(const char *filename, QemuOpts *opts, Error **errp) | ||
359 | } | ||
360 | |||
361 | if (image_type == VDI_TYPE_STATIC) { | ||
362 | - ret = blk_truncate(blk, offset + blocks * block_size); | ||
363 | + ret = blk_truncate(blk, offset + blocks * block_size, errp); | ||
364 | if (ret < 0) { | ||
365 | - error_setg(errp, "Failed to statically allocate %s", filename); | ||
366 | + error_prepend(errp, "Failed to statically allocate %s", filename); | ||
367 | goto exit; | ||
368 | } | ||
369 | } | ||
370 | diff --git a/block/vhdx-log.c b/block/vhdx-log.c | ||
371 | index XXXXXXX..XXXXXXX 100644 | ||
372 | --- a/block/vhdx-log.c | ||
373 | +++ b/block/vhdx-log.c | ||
374 | @@ -XXX,XX +XXX,XX @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s, | ||
375 | if (new_file_size % (1024*1024)) { | ||
376 | /* round up to nearest 1MB boundary */ | ||
377 | new_file_size = ((new_file_size >> 20) + 1) << 20; | ||
378 | - bdrv_truncate(bs->file, new_file_size); | ||
379 | + bdrv_truncate(bs->file, new_file_size, NULL); | ||
380 | } | ||
381 | } | ||
382 | qemu_vfree(desc_entries); | ||
383 | diff --git a/block/vhdx.c b/block/vhdx.c | ||
384 | index XXXXXXX..XXXXXXX 100644 | ||
385 | --- a/block/vhdx.c | ||
386 | +++ b/block/vhdx.c | ||
387 | @@ -XXX,XX +XXX,XX @@ static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s, | ||
388 | /* per the spec, the address for a block is in units of 1MB */ | ||
389 | *new_offset = ROUND_UP(*new_offset, 1024 * 1024); | ||
390 | |||
391 | - return bdrv_truncate(bs->file, *new_offset + s->block_size); | ||
392 | + return bdrv_truncate(bs->file, *new_offset + s->block_size, NULL); | ||
393 | } | ||
394 | |||
395 | /* | ||
396 | @@ -XXX,XX +XXX,XX @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s, | ||
397 | if (type == VHDX_TYPE_DYNAMIC) { | ||
398 | /* All zeroes, so we can just extend the file - the end of the BAT | ||
399 | * is the furthest thing we have written yet */ | ||
400 | - ret = blk_truncate(blk, data_file_offset); | ||
401 | + ret = blk_truncate(blk, data_file_offset, errp); | ||
402 | if (ret < 0) { | ||
403 | - error_setg_errno(errp, -ret, | ||
404 | - "Failed to resize the underlying file"); | ||
405 | goto exit; | ||
406 | } | ||
407 | } else if (type == VHDX_TYPE_FIXED) { | ||
408 | - ret = blk_truncate(blk, data_file_offset + image_size); | ||
409 | + ret = blk_truncate(blk, data_file_offset + image_size, errp); | ||
410 | if (ret < 0) { | ||
411 | - error_setg_errno(errp, -ret, | ||
412 | - "Failed to resize the underlying file"); | ||
413 | goto exit; | ||
414 | } | ||
415 | } else { | ||
416 | diff --git a/block/vmdk.c b/block/vmdk.c | ||
417 | index XXXXXXX..XXXXXXX 100644 | ||
418 | --- a/block/vmdk.c | ||
419 | +++ b/block/vmdk.c | ||
420 | @@ -XXX,XX +XXX,XX @@ static int vmdk_create_extent(const char *filename, int64_t filesize, | ||
421 | blk_set_allow_write_beyond_eof(blk, true); | ||
422 | |||
423 | if (flat) { | ||
424 | - ret = blk_truncate(blk, filesize); | ||
425 | - if (ret < 0) { | ||
426 | - error_setg_errno(errp, -ret, "Could not truncate file"); | ||
427 | - } | ||
428 | + ret = blk_truncate(blk, filesize, errp); | ||
429 | goto exit; | ||
430 | } | ||
431 | magic = cpu_to_be32(VMDK4_MAGIC); | ||
432 | @@ -XXX,XX +XXX,XX @@ static int vmdk_create_extent(const char *filename, int64_t filesize, | ||
433 | goto exit; | ||
434 | } | ||
435 | |||
436 | - ret = blk_truncate(blk, le64_to_cpu(header.grain_offset) << 9); | ||
437 | + ret = blk_truncate(blk, le64_to_cpu(header.grain_offset) << 9, errp); | ||
438 | if (ret < 0) { | ||
439 | - error_setg_errno(errp, -ret, "Could not truncate file"); | ||
440 | goto exit; | ||
441 | } | ||
442 | |||
443 | @@ -XXX,XX +XXX,XX @@ static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp) | ||
444 | /* bdrv_pwrite write padding zeros to align to sector, we don't need that | ||
445 | * for description file */ | ||
446 | if (desc_offset == 0) { | ||
447 | - ret = blk_truncate(new_blk, desc_len); | ||
448 | - if (ret < 0) { | ||
449 | - error_setg_errno(errp, -ret, "Could not truncate file"); | ||
450 | - } | ||
451 | + ret = blk_truncate(new_blk, desc_len, errp); | ||
452 | } | ||
453 | exit: | ||
454 | if (new_blk) { | ||
455 | diff --git a/block/vpc.c b/block/vpc.c | ||
456 | index XXXXXXX..XXXXXXX 100644 | ||
457 | --- a/block/vpc.c | ||
458 | +++ b/block/vpc.c | ||
459 | @@ -XXX,XX +XXX,XX @@ static int create_dynamic_disk(BlockBackend *blk, uint8_t *buf, | ||
460 | } | ||
461 | |||
462 | static int create_fixed_disk(BlockBackend *blk, uint8_t *buf, | ||
463 | - int64_t total_size) | ||
464 | + int64_t total_size, Error **errp) | ||
465 | { | ||
466 | int ret; | ||
467 | |||
468 | /* Add footer to total size */ | ||
469 | total_size += HEADER_SIZE; | ||
470 | |||
471 | - ret = blk_truncate(blk, total_size); | ||
472 | + ret = blk_truncate(blk, total_size, errp); | ||
473 | if (ret < 0) { | ||
474 | return ret; | ||
475 | } | ||
476 | |||
477 | ret = blk_pwrite(blk, total_size - HEADER_SIZE, buf, HEADER_SIZE, 0); | ||
478 | if (ret < 0) { | ||
479 | + error_setg_errno(errp, -ret, "Unable to write VHD header"); | ||
480 | return ret; | ||
481 | } | ||
482 | |||
483 | @@ -XXX,XX +XXX,XX @@ static int vpc_create(const char *filename, QemuOpts *opts, Error **errp) | ||
484 | |||
485 | if (disk_type == VHD_DYNAMIC) { | ||
486 | ret = create_dynamic_disk(blk, buf, total_sectors); | ||
487 | + if (ret < 0) { | ||
488 | + error_setg(errp, "Unable to create or write VHD header"); | ||
489 | + } | ||
490 | } else { | ||
491 | - ret = create_fixed_disk(blk, buf, total_size); | ||
492 | - } | ||
493 | - if (ret < 0) { | ||
494 | - error_setg(errp, "Unable to create or write VHD header"); | ||
495 | + ret = create_fixed_disk(blk, buf, total_size, errp); | ||
496 | } | ||
497 | |||
498 | out: | ||
499 | diff --git a/blockdev.c b/blockdev.c | ||
500 | index XXXXXXX..XXXXXXX 100644 | ||
501 | --- a/blockdev.c | ||
502 | +++ b/blockdev.c | ||
503 | @@ -XXX,XX +XXX,XX @@ void qmp_block_resize(bool has_device, const char *device, | ||
504 | /* complete all in-flight operations before resizing the device */ | ||
505 | bdrv_drain_all(); | ||
506 | |||
507 | - ret = blk_truncate(blk, size); | ||
508 | - switch (ret) { | ||
509 | - case 0: | ||
510 | - break; | ||
511 | - case -ENOMEDIUM: | ||
512 | - error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, device); | ||
513 | - break; | ||
514 | - case -ENOTSUP: | ||
515 | - error_setg(errp, QERR_UNSUPPORTED); | ||
516 | - break; | ||
517 | - case -EACCES: | ||
518 | - error_setg(errp, "Device '%s' is read only", device); | ||
519 | - break; | ||
520 | - case -EBUSY: | ||
521 | - error_setg(errp, QERR_DEVICE_IN_USE, device); | ||
522 | - break; | ||
523 | - default: | ||
524 | - error_setg_errno(errp, -ret, "Could not resize"); | ||
525 | - break; | ||
526 | - } | ||
527 | + ret = blk_truncate(blk, size, errp); | ||
528 | |||
529 | out: | ||
530 | blk_unref(blk); | ||
531 | diff --git a/include/block/block.h b/include/block/block.h | ||
532 | index XXXXXXX..XXXXXXX 100644 | ||
533 | --- a/include/block/block.h | ||
534 | +++ b/include/block/block.h | ||
535 | @@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs, | ||
536 | const char *backing_file); | ||
537 | int bdrv_get_backing_file_depth(BlockDriverState *bs); | ||
538 | void bdrv_refresh_filename(BlockDriverState *bs); | ||
539 | -int bdrv_truncate(BdrvChild *child, int64_t offset); | ||
540 | +int bdrv_truncate(BdrvChild *child, int64_t offset, Error **errp); | ||
541 | int64_t bdrv_nb_sectors(BlockDriverState *bs); | ||
542 | int64_t bdrv_getlength(BlockDriverState *bs); | ||
543 | int64_t bdrv_get_allocated_file_size(BlockDriverState *bs); | ||
544 | diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h | ||
545 | index XXXXXXX..XXXXXXX 100644 | ||
546 | --- a/include/sysemu/block-backend.h | ||
547 | +++ b/include/sysemu/block-backend.h | ||
548 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset, | ||
549 | int count, BdrvRequestFlags flags); | ||
550 | int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf, | ||
551 | int count); | ||
552 | -int blk_truncate(BlockBackend *blk, int64_t offset); | ||
553 | +int blk_truncate(BlockBackend *blk, int64_t offset, Error **errp); | ||
554 | int blk_pdiscard(BlockBackend *blk, int64_t offset, int count); | ||
555 | int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf, | ||
556 | int64_t pos, int size); | ||
557 | diff --git a/qemu-img.c b/qemu-img.c | ||
558 | index XXXXXXX..XXXXXXX 100644 | ||
559 | --- a/qemu-img.c | ||
560 | +++ b/qemu-img.c | ||
561 | @@ -XXX,XX +XXX,XX @@ static int img_resize(int argc, char **argv) | ||
562 | goto out; | ||
563 | } | ||
564 | |||
565 | - ret = blk_truncate(blk, total_size); | ||
566 | - switch (ret) { | ||
567 | - case 0: | ||
568 | + ret = blk_truncate(blk, total_size, &err); | ||
569 | + if (!ret) { | ||
570 | qprintf(quiet, "Image resized.\n"); | ||
571 | - break; | ||
572 | - case -ENOTSUP: | ||
573 | - error_report("This image does not support resize"); | ||
574 | - break; | ||
575 | - case -EACCES: | ||
576 | - error_report("Image is read-only"); | ||
577 | - break; | ||
578 | - default: | ||
579 | - error_report("Error resizing image: %s", strerror(-ret)); | ||
580 | - break; | ||
581 | + } else { | ||
582 | + error_report_err(err); | ||
583 | } | ||
584 | out: | ||
585 | blk_unref(blk); | ||
586 | diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c | ||
587 | index XXXXXXX..XXXXXXX 100644 | ||
588 | --- a/qemu-io-cmds.c | ||
589 | +++ b/qemu-io-cmds.c | ||
590 | @@ -XXX,XX +XXX,XX @@ static const cmdinfo_t flush_cmd = { | ||
591 | |||
592 | static int truncate_f(BlockBackend *blk, int argc, char **argv) | ||
593 | { | ||
594 | + Error *local_err = NULL; | ||
595 | int64_t offset; | ||
596 | int ret; | ||
597 | |||
598 | @@ -XXX,XX +XXX,XX @@ static int truncate_f(BlockBackend *blk, int argc, char **argv) | ||
599 | return 0; | ||
600 | } | ||
601 | |||
602 | - ret = blk_truncate(blk, offset); | ||
603 | + ret = blk_truncate(blk, offset, &local_err); | ||
604 | if (ret < 0) { | ||
605 | - printf("truncate: %s\n", strerror(-ret)); | ||
606 | + error_report_err(local_err); | ||
607 | return 0; | ||
608 | } | ||
609 | |||
610 | -- | 128 | -- |
611 | 1.8.3.1 | 129 | 2.29.2 |
612 | 130 | ||
613 | 131 | diff view generated by jsdifflib |
1 | From: Max Reitz <mreitz@redhat.com> | 1 | From: Max Reitz <mreitz@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | Add missing error messages for the block driver implementations of | 3 | This allows allocating areas after the (old) EOF as part of a growing |
4 | .bdrv_truncate(); drop the generic one from block.c's bdrv_truncate(). | 4 | resize, writing zeroes, and discarding. |
5 | |||
6 | Since one of these changes touches a mis-indented block in | ||
7 | block/file-posix.c, this patch fixes that coding style issue along the | ||
8 | way. | ||
9 | 5 | ||
10 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 6 | Signed-off-by: Max Reitz <mreitz@redhat.com> |
11 | Message-id: 20170328205129.15138-5-mreitz@redhat.com | 7 | Message-Id: <20201027190600.192171-6-mreitz@redhat.com> |
12 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | 8 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
13 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
14 | --- | 9 | --- |
15 | block.c | 2 -- | 10 | block/export/fuse.c | 84 +++++++++++++++++++++++++++++++++++++++++++++ |
16 | block/file-posix.c | 17 ++++++++++++----- | 11 | 1 file changed, 84 insertions(+) |
17 | block/gluster.c | 4 +++- | ||
18 | block/iscsi.c | 2 ++ | ||
19 | block/nfs.c | 10 +++++++++- | ||
20 | block/qcow2.c | 2 ++ | ||
21 | block/qed.c | 4 +++- | ||
22 | block/raw-format.c | 2 ++ | ||
23 | block/rbd.c | 1 + | ||
24 | 9 files changed, 34 insertions(+), 10 deletions(-) | ||
25 | 12 | ||
26 | diff --git a/block.c b/block.c | 13 | diff --git a/block/export/fuse.c b/block/export/fuse.c |
27 | index XXXXXXX..XXXXXXX 100644 | 14 | index XXXXXXX..XXXXXXX 100644 |
28 | --- a/block.c | 15 | --- a/block/export/fuse.c |
29 | +++ b/block.c | 16 | +++ b/block/export/fuse.c |
30 | @@ -XXX,XX +XXX,XX @@ int bdrv_truncate(BdrvChild *child, int64_t offset, Error **errp) | 17 | @@ -XXX,XX +XXX,XX @@ static void fuse_write(fuse_req_t req, fuse_ino_t inode, const char *buf, |
31 | bdrv_dirty_bitmap_truncate(bs); | ||
32 | bdrv_parent_cb_resize(bs); | ||
33 | ++bs->write_gen; | ||
34 | - } else if (errp && !*errp) { | ||
35 | - error_setg_errno(errp, -ret, "Failed to resize image"); | ||
36 | } | 18 | } |
37 | return ret; | ||
38 | } | 19 | } |
39 | diff --git a/block/file-posix.c b/block/file-posix.c | 20 | |
40 | index XXXXXXX..XXXXXXX 100644 | 21 | +/** |
41 | --- a/block/file-posix.c | 22 | + * Let clients perform various fallocate() operations. |
42 | +++ b/block/file-posix.c | 23 | + */ |
43 | @@ -XXX,XX +XXX,XX @@ static int raw_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | 24 | +static void fuse_fallocate(fuse_req_t req, fuse_ino_t inode, int mode, |
44 | { | 25 | + off_t offset, off_t length, |
45 | BDRVRawState *s = bs->opaque; | 26 | + struct fuse_file_info *fi) |
46 | struct stat st; | 27 | +{ |
47 | + int ret; | 28 | + FuseExport *exp = fuse_req_userdata(req); |
48 | 29 | + int64_t blk_len; | |
49 | if (fstat(s->fd, &st)) { | ||
50 | - return -errno; | ||
51 | + ret = -errno; | ||
52 | + error_setg_errno(errp, -ret, "Failed to fstat() the file"); | ||
53 | + return ret; | ||
54 | } | ||
55 | |||
56 | if (S_ISREG(st.st_mode)) { | ||
57 | if (ftruncate(s->fd, offset) < 0) { | ||
58 | - return -errno; | ||
59 | + ret = -errno; | ||
60 | + error_setg_errno(errp, -ret, "Failed to resize the file"); | ||
61 | + return ret; | ||
62 | } | ||
63 | } else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) { | ||
64 | - if (offset > raw_getlength(bs)) { | ||
65 | - return -EINVAL; | ||
66 | - } | ||
67 | + if (offset > raw_getlength(bs)) { | ||
68 | + error_setg(errp, "Cannot grow device files"); | ||
69 | + return -EINVAL; | ||
70 | + } | ||
71 | } else { | ||
72 | + error_setg(errp, "Resizing this file is not supported"); | ||
73 | return -ENOTSUP; | ||
74 | } | ||
75 | |||
76 | diff --git a/block/gluster.c b/block/gluster.c | ||
77 | index XXXXXXX..XXXXXXX 100644 | ||
78 | --- a/block/gluster.c | ||
79 | +++ b/block/gluster.c | ||
80 | @@ -XXX,XX +XXX,XX @@ static int qemu_gluster_truncate(BlockDriverState *bs, int64_t offset, | ||
81 | |||
82 | ret = glfs_ftruncate(s->fd, offset); | ||
83 | if (ret < 0) { | ||
84 | - return -errno; | ||
85 | + ret = -errno; | ||
86 | + error_setg_errno(errp, -ret, "Failed to truncate file"); | ||
87 | + return ret; | ||
88 | } | ||
89 | |||
90 | return 0; | ||
91 | diff --git a/block/iscsi.c b/block/iscsi.c | ||
92 | index XXXXXXX..XXXXXXX 100644 | ||
93 | --- a/block/iscsi.c | ||
94 | +++ b/block/iscsi.c | ||
95 | @@ -XXX,XX +XXX,XX @@ static int iscsi_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | ||
96 | Error *local_err = NULL; | ||
97 | |||
98 | if (iscsilun->type != TYPE_DISK) { | ||
99 | + error_setg(errp, "Cannot resize non-disk iSCSI devices"); | ||
100 | return -ENOTSUP; | ||
101 | } | ||
102 | |||
103 | @@ -XXX,XX +XXX,XX @@ static int iscsi_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | ||
104 | } | ||
105 | |||
106 | if (offset > iscsi_getlength(bs)) { | ||
107 | + error_setg(errp, "Cannot grow iSCSI devices"); | ||
108 | return -EINVAL; | ||
109 | } | ||
110 | |||
111 | diff --git a/block/nfs.c b/block/nfs.c | ||
112 | index XXXXXXX..XXXXXXX 100644 | ||
113 | --- a/block/nfs.c | ||
114 | +++ b/block/nfs.c | ||
115 | @@ -XXX,XX +XXX,XX @@ static int64_t nfs_get_allocated_file_size(BlockDriverState *bs) | ||
116 | static int nfs_file_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | ||
117 | { | ||
118 | NFSClient *client = bs->opaque; | ||
119 | - return nfs_ftruncate(client->context, client->fh, offset); | ||
120 | + int ret; | 30 | + int ret; |
121 | + | 31 | + |
122 | + ret = nfs_ftruncate(client->context, client->fh, offset); | 32 | + if (!exp->writable) { |
123 | + if (ret < 0) { | 33 | + fuse_reply_err(req, EACCES); |
124 | + error_setg_errno(errp, -ret, "Failed to truncate file"); | 34 | + return; |
125 | + return ret; | ||
126 | + } | 35 | + } |
127 | + | 36 | + |
128 | + return 0; | 37 | + blk_len = blk_getlength(exp->common.blk); |
129 | } | 38 | + if (blk_len < 0) { |
130 | 39 | + fuse_reply_err(req, -blk_len); | |
131 | /* Note that this will not re-establish a connection with the NFS server | 40 | + return; |
132 | diff --git a/block/qcow2.c b/block/qcow2.c | 41 | + } |
133 | index XXXXXXX..XXXXXXX 100644 | 42 | + |
134 | --- a/block/qcow2.c | 43 | + if (mode & FALLOC_FL_KEEP_SIZE) { |
135 | +++ b/block/qcow2.c | 44 | + length = MIN(length, blk_len - offset); |
136 | @@ -XXX,XX +XXX,XX @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | 45 | + } |
137 | new_l1_size = size_to_l1(s, offset); | 46 | + |
138 | ret = qcow2_grow_l1_table(bs, new_l1_size, true); | 47 | + if (mode & FALLOC_FL_PUNCH_HOLE) { |
139 | if (ret < 0) { | 48 | + if (!(mode & FALLOC_FL_KEEP_SIZE)) { |
140 | + error_setg_errno(errp, -ret, "Failed to grow the L1 table"); | 49 | + fuse_reply_err(req, EINVAL); |
141 | return ret; | 50 | + return; |
142 | } | 51 | + } |
143 | 52 | + | |
144 | @@ -XXX,XX +XXX,XX @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | 53 | + do { |
145 | ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, size), | 54 | + int size = MIN(length, BDRV_REQUEST_MAX_BYTES); |
146 | &offset, sizeof(uint64_t)); | 55 | + |
147 | if (ret < 0) { | 56 | + ret = blk_pdiscard(exp->common.blk, offset, size); |
148 | + error_setg_errno(errp, -ret, "Failed to update the image size"); | 57 | + offset += size; |
149 | return ret; | 58 | + length -= size; |
150 | } | 59 | + } while (ret == 0 && length > 0); |
151 | 60 | + } else if (mode & FALLOC_FL_ZERO_RANGE) { | |
152 | diff --git a/block/qed.c b/block/qed.c | 61 | + if (!(mode & FALLOC_FL_KEEP_SIZE) && offset + length > blk_len) { |
153 | index XXXXXXX..XXXXXXX 100644 | 62 | + /* No need for zeroes, we are going to write them ourselves */ |
154 | --- a/block/qed.c | 63 | + ret = fuse_do_truncate(exp, offset + length, false, |
155 | +++ b/block/qed.c | 64 | + PREALLOC_MODE_OFF); |
156 | @@ -XXX,XX +XXX,XX @@ static int bdrv_qed_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | 65 | + if (ret < 0) { |
157 | 66 | + fuse_reply_err(req, -ret); | |
158 | if (!qed_is_image_size_valid(offset, s->header.cluster_size, | 67 | + return; |
159 | s->header.table_size)) { | 68 | + } |
160 | + error_setg(errp, "Invalid image size specified"); | 69 | + } |
161 | return -EINVAL; | 70 | + |
162 | } | 71 | + do { |
163 | 72 | + int size = MIN(length, BDRV_REQUEST_MAX_BYTES); | |
164 | - /* Shrinking is currently not supported */ | 73 | + |
165 | if ((uint64_t)offset < s->header.image_size) { | 74 | + ret = blk_pwrite_zeroes(exp->common.blk, |
166 | + error_setg(errp, "Shrinking images is currently not supported"); | 75 | + offset, size, 0); |
167 | return -ENOTSUP; | 76 | + offset += size; |
168 | } | 77 | + length -= size; |
169 | 78 | + } while (ret == 0 && length > 0); | |
170 | @@ -XXX,XX +XXX,XX @@ static int bdrv_qed_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | 79 | + } else if (!mode) { |
171 | ret = qed_write_header_sync(s); | 80 | + /* We can only fallocate at the EOF with a truncate */ |
172 | if (ret < 0) { | 81 | + if (offset < blk_len) { |
173 | s->header.image_size = old_image_size; | 82 | + fuse_reply_err(req, EOPNOTSUPP); |
174 | + error_setg_errno(errp, -ret, "Failed to update the image size"); | 83 | + return; |
175 | } | 84 | + } |
176 | return ret; | 85 | + |
177 | } | 86 | + if (offset > blk_len) { |
178 | diff --git a/block/raw-format.c b/block/raw-format.c | 87 | + /* No preallocation needed here */ |
179 | index XXXXXXX..XXXXXXX 100644 | 88 | + ret = fuse_do_truncate(exp, offset, true, PREALLOC_MODE_OFF); |
180 | --- a/block/raw-format.c | 89 | + if (ret < 0) { |
181 | +++ b/block/raw-format.c | 90 | + fuse_reply_err(req, -ret); |
182 | @@ -XXX,XX +XXX,XX @@ static int raw_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | 91 | + return; |
183 | BDRVRawState *s = bs->opaque; | 92 | + } |
184 | 93 | + } | |
185 | if (s->has_size) { | 94 | + |
186 | + error_setg(errp, "Cannot resize fixed-size raw disks"); | 95 | + ret = fuse_do_truncate(exp, offset + length, true, |
187 | return -ENOTSUP; | 96 | + PREALLOC_MODE_FALLOC); |
188 | } | 97 | + } else { |
189 | 98 | + ret = -EOPNOTSUPP; | |
190 | if (INT64_MAX - offset < s->offset) { | 99 | + } |
191 | + error_setg(errp, "Disk size too large for the chosen offset"); | 100 | + |
192 | return -EINVAL; | 101 | + fuse_reply_err(req, ret < 0 ? -ret : 0); |
193 | } | 102 | +} |
194 | 103 | + | |
195 | diff --git a/block/rbd.c b/block/rbd.c | 104 | /** |
196 | index XXXXXXX..XXXXXXX 100644 | 105 | * Let clients fsync the exported image. |
197 | --- a/block/rbd.c | 106 | */ |
198 | +++ b/block/rbd.c | 107 | @@ -XXX,XX +XXX,XX @@ static const struct fuse_lowlevel_ops fuse_ops = { |
199 | @@ -XXX,XX +XXX,XX @@ static int qemu_rbd_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | 108 | .open = fuse_open, |
200 | 109 | .read = fuse_read, | |
201 | r = rbd_resize(s->image, offset); | 110 | .write = fuse_write, |
202 | if (r < 0) { | 111 | + .fallocate = fuse_fallocate, |
203 | + error_setg_errno(errp, -r, "Failed to resize file"); | 112 | .flush = fuse_flush, |
204 | return r; | 113 | .fsync = fuse_fsync, |
205 | } | 114 | }; |
206 | |||
207 | -- | 115 | -- |
208 | 1.8.3.1 | 116 | 2.29.2 |
209 | 117 | ||
210 | 118 | diff view generated by jsdifflib |
1 | From: Max Reitz <mreitz@redhat.com> | 1 | From: Max Reitz <mreitz@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | It does not make much sense to use a backing image for the target when | 3 | This is a relatively new feature in libfuse (available since 3.8.0, |
4 | you concatenate multiple images (because then there is no correspondence | 4 | which was released in November 2019), so we have to add a dedicated |
5 | between the source images' backing files and the target's); but it was | 5 | check whether it is available before making use of it. |
6 | still possible to give one by using -o backing_file=X instead of -B X. | ||
7 | |||
8 | Fix this by moving the check. | ||
9 | |||
10 | (Also, change the error message because -B is not the only way to | ||
11 | specify the backing file, evidently.) | ||
12 | 6 | ||
13 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 7 | Signed-off-by: Max Reitz <mreitz@redhat.com> |
14 | Reviewed-by: Eric Blake <eblake@redhat.com> | 8 | Message-Id: <20201027190600.192171-7-mreitz@redhat.com> |
15 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 9 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
16 | --- | 10 | --- |
17 | qemu-img.c | 13 +++++++------ | 11 | meson_options.txt | 2 ++ |
18 | tests/qemu-iotests/122.out | 4 ++-- | 12 | configure | 8 ++++- |
19 | 2 files changed, 9 insertions(+), 8 deletions(-) | 13 | block/export/fuse.c | 77 +++++++++++++++++++++++++++++++++++++++++++++ |
20 | 14 | meson.build | 20 ++++++++++++ | |
21 | diff --git a/qemu-img.c b/qemu-img.c | 15 | 4 files changed, 106 insertions(+), 1 deletion(-) |
16 | |||
17 | diff --git a/meson_options.txt b/meson_options.txt | ||
22 | index XXXXXXX..XXXXXXX 100644 | 18 | index XXXXXXX..XXXXXXX 100644 |
23 | --- a/qemu-img.c | 19 | --- a/meson_options.txt |
24 | +++ b/qemu-img.c | 20 | +++ b/meson_options.txt |
25 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | 21 | @@ -XXX,XX +XXX,XX @@ option('vhost_user_blk_server', type: 'feature', value: 'auto', |
26 | } | 22 | description: 'build vhost-user-blk server') |
27 | 23 | option('fuse', type: 'feature', value: 'auto', | |
28 | 24 | description: 'FUSE block device export') | |
29 | - if (s.src_num > 1 && out_baseimg) { | 25 | +option('fuse_lseek', type : 'feature', value : 'auto', |
30 | - error_report("-B makes no sense when concatenating multiple input " | 26 | + description: 'SEEK_HOLE/SEEK_DATA support for FUSE exports') |
31 | - "images"); | 27 | |
32 | - goto fail_getopt; | 28 | option('capstone', type: 'combo', value: 'auto', |
33 | - } | 29 | choices: ['disabled', 'enabled', 'auto', 'system', 'internal'], |
34 | - | 30 | diff --git a/configure b/configure |
35 | /* ret is still -EINVAL until here */ | 31 | index XXXXXXX..XXXXXXX 100755 |
36 | ret = bdrv_parse_cache_mode(src_cache, &src_flags, &src_writethrough); | 32 | --- a/configure |
37 | if (ret < 0) { | 33 | +++ b/configure |
38 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | 34 | @@ -XXX,XX +XXX,XX @@ ninja="" |
39 | } | 35 | skip_meson=no |
40 | s.target_has_backing = (bool) out_baseimg; | 36 | gettext="" |
41 | 37 | fuse="auto" | |
42 | + if (s.src_num > 1 && out_baseimg) { | 38 | +fuse_lseek="auto" |
43 | + error_report("Having a backing file for the target makes no sense when " | 39 | |
44 | + "concatenating multiple input images"); | 40 | bogus_os="no" |
45 | + ret = -1; | 41 | malloc_trim="auto" |
46 | + goto out; | 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); | ||
89 | + return; | ||
47 | + } | 90 | + } |
48 | + | 91 | + |
49 | /* Check if compression is supported */ | 92 | + while (true) { |
50 | if (s.compressed) { | 93 | + int64_t pnum; |
51 | bool encryption = | 94 | + int ret; |
52 | diff --git a/tests/qemu-iotests/122.out b/tests/qemu-iotests/122.out | 95 | + |
96 | + ret = bdrv_block_status_above(blk_bs(exp->common.blk), NULL, | ||
97 | + offset, INT64_MAX, &pnum, NULL, NULL); | ||
98 | + if (ret < 0) { | ||
99 | + fuse_reply_err(req, -ret); | ||
100 | + return; | ||
101 | + } | ||
102 | + | ||
103 | + if (!pnum && (ret & BDRV_BLOCK_EOF)) { | ||
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 | ||
53 | index XXXXXXX..XXXXXXX 100644 | 166 | index XXXXXXX..XXXXXXX 100644 |
54 | --- a/tests/qemu-iotests/122.out | 167 | --- a/meson.build |
55 | +++ b/tests/qemu-iotests/122.out | 168 | +++ b/meson.build |
56 | @@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 4194304 | 169 | @@ -XXX,XX +XXX,XX @@ elif get_option('vhost_user_blk_server').disabled() or not have_system |
57 | 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | 170 | have_vhost_user_blk_server = false |
58 | read 65536/65536 bytes at offset 8388608 | 171 | endif |
59 | 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | 172 | |
60 | -qemu-img: -B makes no sense when concatenating multiple input images | 173 | +if get_option('fuse').disabled() and get_option('fuse_lseek').enabled() |
61 | -qemu-img: -B makes no sense when concatenating multiple input images | 174 | + error('Cannot enable fuse-lseek while fuse is disabled') |
62 | +qemu-img: Having a backing file for the target makes no sense when concatenating multiple input images | 175 | +endif |
63 | +qemu-img: Having a backing file for the target makes no sense when concatenating multiple input images | 176 | + |
64 | 177 | fuse = dependency('fuse3', required: get_option('fuse'), | |
65 | === Compression with misaligned allocations and image sizes === | 178 | version: '>=3.1', method: 'pkg-config', |
66 | 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) | ||
67 | -- | 214 | -- |
68 | 1.8.3.1 | 215 | 2.29.2 |
69 | 216 | ||
70 | 217 | diff view generated by jsdifflib |
1 | It is unused. | 1 | From: Max Reitz <mreitz@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | Suggested-by: Fam Zheng <famz@redhat.com> | 3 | In most cases, _make_test_img does not need a _filter_imgfmt on top. It |
4 | does that by itself. | ||
5 | |||
6 | (The exception is when IMGFMT has been overwritten but TEST_IMG has not. | ||
7 | In such cases, we do need a _filter_imgfmt on top to filter the test's | ||
8 | original IMGFMT from TEST_IMG.) | ||
9 | |||
10 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
11 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> | ||
12 | Message-Id: <20201027190600.192171-8-mreitz@redhat.com> | ||
4 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 13 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
5 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
6 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
7 | Reviewed-by: Fam Zheng <famz@redhat.com> | ||
8 | --- | 14 | --- |
9 | tests/qemu-iotests/common.config | 18 ------------------ | 15 | tests/qemu-iotests/161 | 12 ++++++------ |
10 | 1 file changed, 18 deletions(-) | 16 | tests/qemu-iotests/175 | 6 +++--- |
17 | tests/qemu-iotests/249 | 6 +++--- | ||
18 | 3 files changed, 12 insertions(+), 12 deletions(-) | ||
11 | 19 | ||
12 | diff --git a/tests/qemu-iotests/common.config b/tests/qemu-iotests/common.config | 20 | diff --git a/tests/qemu-iotests/161 b/tests/qemu-iotests/161 |
13 | index XXXXXXX..XXXXXXX 100644 | 21 | index XXXXXXX..XXXXXXX 100755 |
14 | --- a/tests/qemu-iotests/common.config | 22 | --- a/tests/qemu-iotests/161 |
15 | +++ b/tests/qemu-iotests/common.config | 23 | +++ b/tests/qemu-iotests/161 |
16 | @@ -XXX,XX +XXX,XX @@ fi | 24 | @@ -XXX,XX +XXX,XX @@ _supported_os Linux |
17 | 25 | IMG_SIZE=1M | |
18 | export SAMPLE_IMG_DIR | 26 | |
19 | 27 | # Create the images | |
20 | -_readlink() | 28 | -TEST_IMG="$TEST_IMG.base" _make_test_img $IMG_SIZE | _filter_imgfmt |
21 | -{ | 29 | -TEST_IMG="$TEST_IMG.int" _make_test_img -b "$TEST_IMG.base" -F $IMGFMT | _filter_imgfmt |
22 | - if [ $# -ne 1 ]; then | 30 | -_make_test_img -b "$TEST_IMG.int" -F $IMGFMT -F $IMGFMT | _filter_imgfmt |
23 | - echo "Usage: _readlink filename" 1>&2 | 31 | +TEST_IMG="$TEST_IMG.base" _make_test_img $IMG_SIZE |
24 | - exit 1 | 32 | +TEST_IMG="$TEST_IMG.int" _make_test_img -b "$TEST_IMG.base" -F $IMGFMT |
25 | - fi | 33 | +_make_test_img -b "$TEST_IMG.int" -F $IMGFMT -F $IMGFMT |
26 | - | 34 | |
27 | - perl -e "\$in=\"$1\";" -e ' | 35 | # First test: reopen $TEST.IMG changing the detect-zeroes option on |
28 | - $lnk = readlink($in); | 36 | # its backing file ($TEST_IMG.int). |
29 | - if ($lnk =~ m!^/.*!) { | 37 | @@ -XXX,XX +XXX,XX @@ echo |
30 | - print "$lnk\n"; | 38 | echo "*** Commit and then change an option on the backing file" |
31 | - } | 39 | echo |
32 | - else { | 40 | # Create the images again |
33 | - chomp($dir = `dirname $in`); | 41 | -TEST_IMG="$TEST_IMG.base" _make_test_img $IMG_SIZE | _filter_imgfmt |
34 | - print "$dir/$lnk\n"; | 42 | -TEST_IMG="$TEST_IMG.int" _make_test_img -b "$TEST_IMG.base" -F $IMGFMT| _filter_imgfmt |
35 | - }' | 43 | -_make_test_img -b "$TEST_IMG.int" -F $IMGFMT | _filter_imgfmt |
36 | -} | 44 | +TEST_IMG="$TEST_IMG.base" _make_test_img $IMG_SIZE |
37 | - | 45 | +TEST_IMG="$TEST_IMG.int" _make_test_img -b "$TEST_IMG.base" -F $IMGFMT |
38 | # make sure this script returns success | 46 | +_make_test_img -b "$TEST_IMG.int" -F $IMGFMT |
39 | true | 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) | ||
40 | -- | 95 | -- |
41 | 1.8.3.1 | 96 | 2.29.2 |
42 | 97 | ||
43 | 98 | diff view generated by jsdifflib |
1 | From: Max Reitz <mreitz@redhat.com> | 1 | From: Max Reitz <mreitz@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | Executing _make_test_img as part of a pipe will undo all variable | ||
4 | changes it has done. As such, this could not work with FUSE (because | ||
5 | we want to remember all of our exports and their qemu instances). | ||
6 | |||
7 | Replace the pipe by a temporary file in 071 and 174 (the two tests that | ||
8 | can run on FUSE). | ||
9 | |||
3 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 10 | Signed-off-by: Max Reitz <mreitz@redhat.com> |
4 | Reviewed-by: Eric Blake <eblake@redhat.com> | 11 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> |
5 | Reviewed-by: Fam Zheng <famz@redhat.com> | 12 | Message-Id: <20201027190600.192171-9-mreitz@redhat.com> |
6 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 13 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
7 | --- | 14 | --- |
8 | tests/qemu-iotests/051 | 1 + | 15 | tests/qemu-iotests/071 | 19 +++++++++++++++---- |
9 | tests/qemu-iotests/051.out | 3 +++ | 16 | tests/qemu-iotests/174 | 10 +++++++++- |
10 | tests/qemu-iotests/051.pc.out | 3 +++ | 17 | 2 files changed, 24 insertions(+), 5 deletions(-) |
11 | 3 files changed, 7 insertions(+) | ||
12 | 18 | ||
13 | diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051 | 19 | diff --git a/tests/qemu-iotests/071 b/tests/qemu-iotests/071 |
14 | index XXXXXXX..XXXXXXX 100755 | 20 | index XXXXXXX..XXXXXXX 100755 |
15 | --- a/tests/qemu-iotests/051 | 21 | --- a/tests/qemu-iotests/071 |
16 | +++ b/tests/qemu-iotests/051 | 22 | +++ b/tests/qemu-iotests/071 |
17 | @@ -XXX,XX +XXX,XX @@ echo === Leaving out required options === | 23 | @@ -XXX,XX +XXX,XX @@ echo |
24 | echo "=== Testing blkverify through filename ===" | ||
18 | echo | 25 | echo |
19 | 26 | ||
20 | run_qemu -drive driver=file | 27 | -TEST_IMG="$TEST_IMG.base" IMGFMT="raw" _make_test_img --no-opts $IMG_SIZE |\ |
21 | +run_qemu -drive driver=file,filename= | 28 | - _filter_imgfmt |
22 | run_qemu -drive driver=nbd | 29 | +# _make_test_img may set variables that we need to retain. Everything |
23 | run_qemu -drive driver=raw | 30 | +# in a pipe is executed in a subshell, so doing so would throw away |
24 | run_qemu -drive file.driver=file | 31 | +# all changes. Therefore, we have to store the output in some temp |
25 | diff --git a/tests/qemu-iotests/051.out b/tests/qemu-iotests/051.out | 32 | +# file and filter that. |
26 | index XXXXXXX..XXXXXXX 100644 | 33 | +scratch_out="$TEST_DIR/img-create.out" |
27 | --- a/tests/qemu-iotests/051.out | ||
28 | +++ b/tests/qemu-iotests/051.out | ||
29 | @@ -XXX,XX +XXX,XX @@ QEMU X.Y.Z monitor - type 'help' for more information | ||
30 | Testing: -drive driver=file | ||
31 | QEMU_PROG: -drive driver=file: The 'file' block driver requires a file name | ||
32 | |||
33 | +Testing: -drive driver=file,filename= | ||
34 | +QEMU_PROG: -drive driver=file,filename=: The 'file' block driver requires a file name | ||
35 | + | 34 | + |
36 | Testing: -drive driver=nbd | 35 | +TEST_IMG="$TEST_IMG.base" IMGFMT="raw" _make_test_img --no-opts $IMG_SIZE \ |
37 | QEMU_PROG: -drive driver=nbd: NBD server address missing | 36 | + >"$scratch_out" |
38 | 37 | +_filter_imgfmt <"$scratch_out" | |
39 | diff --git a/tests/qemu-iotests/051.pc.out b/tests/qemu-iotests/051.pc.out | 38 | +rm -f "$scratch_out" |
40 | index XXXXXXX..XXXXXXX 100644 | ||
41 | --- a/tests/qemu-iotests/051.pc.out | ||
42 | +++ b/tests/qemu-iotests/051.pc.out | ||
43 | @@ -XXX,XX +XXX,XX @@ QEMU X.Y.Z monitor - type 'help' for more information | ||
44 | Testing: -drive driver=file | ||
45 | QEMU_PROG: -drive driver=file: The 'file' block driver requires a file name | ||
46 | |||
47 | +Testing: -drive driver=file,filename= | ||
48 | +QEMU_PROG: -drive driver=file,filename=: The 'file' block driver requires a file name | ||
49 | + | 39 | + |
50 | Testing: -drive driver=nbd | 40 | _make_test_img $IMG_SIZE |
51 | QEMU_PROG: -drive driver=nbd: NBD server address missing | 41 | $QEMU_IO -c "open -o driver=raw,file.driver=blkverify,file.raw.filename=$TEST_IMG.base $TEST_IMG" \ |
52 | 42 | -c 'read 0 512' -c 'write -P 42 0x38000 512' -c 'read -P 42 0x38000 512' | _filter_qemu_io | |
43 | @@ -XXX,XX +XXX,XX @@ echo | ||
44 | echo "=== Testing blkverify through file blockref ===" | ||
45 | echo | ||
46 | |||
47 | -TEST_IMG="$TEST_IMG.base" IMGFMT="raw" _make_test_img --no-opts $IMG_SIZE |\ | ||
48 | - _filter_imgfmt | ||
49 | +TEST_IMG="$TEST_IMG.base" IMGFMT="raw" _make_test_img --no-opts $IMG_SIZE \ | ||
50 | + >"$scratch_out" | ||
51 | +_filter_imgfmt <"$scratch_out" | ||
52 | + | ||
53 | _make_test_img $IMG_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" \ | ||
55 | -c 'read 0 512' -c 'write -P 42 0x38000 512' -c 'read -P 42 0x38000 512' | _filter_qemu_io | ||
56 | diff --git a/tests/qemu-iotests/174 b/tests/qemu-iotests/174 | ||
57 | index XXXXXXX..XXXXXXX 100755 | ||
58 | --- a/tests/qemu-iotests/174 | ||
59 | +++ b/tests/qemu-iotests/174 | ||
60 | @@ -XXX,XX +XXX,XX @@ _unsupported_fmt raw | ||
61 | |||
62 | |||
63 | size=256K | ||
64 | -IMGFMT=raw IMGKEYSECRET= _make_test_img --no-opts $size | _filter_imgfmt | ||
65 | + | ||
66 | +# _make_test_img may set variables that we need to retain. Everything | ||
67 | +# in a pipe is executed in a subshell, so doing so would throw away | ||
68 | +# all changes. Therefore, we have to store the output in some temp | ||
69 | +# file and filter that. | ||
70 | +scratch_out="$TEST_DIR/img-create.out" | ||
71 | +IMGFMT=raw IMGKEYSECRET= _make_test_img --no-opts $size >"$scratch_out" | ||
72 | +_filter_imgfmt <"$scratch_out" | ||
73 | +rm -f "$scratch_out" | ||
74 | |||
75 | echo | ||
76 | echo "== reading wrong format should fail ==" | ||
53 | -- | 77 | -- |
54 | 1.8.3.1 | 78 | 2.29.2 |
55 | 79 | ||
56 | 80 | diff view generated by jsdifflib |
1 | The only thing the escape characters achieve is making the reference | 1 | From: Max Reitz <mreitz@redhat.com> |
---|---|---|---|
2 | output unreadable and lines that are potentially so long that git | ||
3 | doesn't want to put them into an email any more. Let's filter them out. | ||
4 | 2 | ||
3 | qemu-img convert (without -n) can often be replaced by a combination of | ||
4 | _make_test_img + qemu-img convert -n. Doing so allows converting to | ||
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. | ||
9 | |||
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. | ||
14 | |||
15 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
16 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> | ||
17 | Message-Id: <20201027190600.192171-10-mreitz@redhat.com> | ||
5 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 18 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
6 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
7 | --- | 19 | --- |
8 | tests/qemu-iotests/028.out | 2 +- | 20 | tests/qemu-iotests/028 | 14 ++++---------- |
9 | tests/qemu-iotests/051 | 3 +- | 21 | tests/qemu-iotests/028.out | 3 +++ |
10 | tests/qemu-iotests/051.out | 106 +++++++++++++++---------------- | 22 | tests/qemu-iotests/089 | 3 ++- |
11 | tests/qemu-iotests/051.pc.out | 132 +++++++++++++++++++-------------------- | 23 | tests/qemu-iotests/089.out | 1 + |
12 | tests/qemu-iotests/068 | 4 +- | 24 | 4 files changed, 10 insertions(+), 11 deletions(-) |
13 | tests/qemu-iotests/068.out | 6 +- | ||
14 | tests/qemu-iotests/130.out | 4 +- | ||
15 | tests/qemu-iotests/142 | 2 +- | ||
16 | tests/qemu-iotests/142.out | 10 +-- | ||
17 | tests/qemu-iotests/145 | 3 +- | ||
18 | tests/qemu-iotests/145.out | 2 +- | ||
19 | tests/qemu-iotests/common.filter | 7 +++ | ||
20 | tests/qemu-iotests/common.qemu | 4 +- | ||
21 | 13 files changed, 147 insertions(+), 138 deletions(-) | ||
22 | 25 | ||
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' "" | ||
23 | diff --git a/tests/qemu-iotests/028.out b/tests/qemu-iotests/028.out | 51 | diff --git a/tests/qemu-iotests/028.out b/tests/qemu-iotests/028.out |
24 | index XXXXXXX..XXXXXXX 100644 | 52 | index XXXXXXX..XXXXXXX 100644 |
25 | --- a/tests/qemu-iotests/028.out | 53 | --- a/tests/qemu-iotests/028.out |
26 | +++ b/tests/qemu-iotests/028.out | 54 | +++ b/tests/qemu-iotests/028.out |
27 | @@ -XXX,XX +XXX,XX @@ No errors were found on the image. | 55 | @@ -XXX,XX +XXX,XX @@ No errors were found on the image. |
56 | |||
28 | block-backup | 57 | block-backup |
29 | 58 | ||
30 | Formatting 'TEST_DIR/t.IMGFMT.copy', fmt=IMGFMT size=4294968832 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=IMGFMT | 59 | +Formatting 'TEST_DIR/t.IMGFMT.copy', fmt=IMGFMT size=4294968832 |
31 | -(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K[D[D[D[D[D[D[D[D[D[Dinfo block-[K[D[D[D[D[D[D[D[D[D[D[Dinfo block-j[K[D[D[D[D[D[D[D[D[D[D[D[Dinfo block-jo[K[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block-job[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block-jobs[K | 60 | +QEMU X.Y.Z monitor - type 'help' for more information |
32 | +(qemu) info block-jobs | 61 | +(qemu) drive_backup -n disk TEST_DIR/t.IMGFMT.copy |
62 | (qemu) info block-jobs | ||
33 | No active jobs | 63 | No active jobs |
34 | === IO: pattern 195 | 64 | === IO: pattern 195 |
35 | read 512/512 bytes at offset 3221194240 | 65 | diff --git a/tests/qemu-iotests/089 b/tests/qemu-iotests/089 |
36 | diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051 | ||
37 | index XXXXXXX..XXXXXXX 100755 | 66 | index XXXXXXX..XXXXXXX 100755 |
38 | --- a/tests/qemu-iotests/051 | 67 | --- a/tests/qemu-iotests/089 |
39 | +++ b/tests/qemu-iotests/051 | 68 | +++ b/tests/qemu-iotests/089 |
40 | @@ -XXX,XX +XXX,XX @@ function do_run_qemu() | 69 | @@ -XXX,XX +XXX,XX @@ TEST_IMG="$TEST_IMG.base" _make_test_img $IMG_SIZE |
41 | 70 | $QEMU_IO -c 'write -P 42 0 512' -c 'write -P 23 512 512' \ | |
42 | function run_qemu() | 71 | -c 'write -P 66 1024 512' "$TEST_IMG.base" | _filter_qemu_io |
43 | { | 72 | |
44 | - do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_generated_node_ids | 73 | -$QEMU_IMG convert -f raw -O $IMGFMT "$TEST_IMG.base" "$TEST_IMG" |
45 | + do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | | 74 | +_make_test_img $IMG_SIZE |
46 | + _filter_generated_node_ids | _filter_hmp | 75 | +$QEMU_IMG convert -f raw -O $IMGFMT -n "$TEST_IMG.base" "$TEST_IMG" |
47 | } | 76 | |
48 | 77 | $QEMU_IO_PROG --cache $CACHEMODE --aio $AIOMODE \ | |
49 | size=128M | 78 | -c 'read -P 42 0 512' -c 'read -P 23 512 512' \ |
50 | diff --git a/tests/qemu-iotests/051.out b/tests/qemu-iotests/051.out | 79 | diff --git a/tests/qemu-iotests/089.out b/tests/qemu-iotests/089.out |
51 | index XXXXXXX..XXXXXXX 100644 | 80 | index XXXXXXX..XXXXXXX 100644 |
52 | --- a/tests/qemu-iotests/051.out | 81 | --- a/tests/qemu-iotests/089.out |
53 | +++ b/tests/qemu-iotests/051.out | 82 | +++ b/tests/qemu-iotests/089.out |
54 | @@ -XXX,XX +XXX,XX @@ QEMU X.Y.Z monitor - type 'help' for more information | 83 | @@ -XXX,XX +XXX,XX @@ wrote 512/512 bytes at offset 512 |
55 | 84 | 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | |
56 | Testing: -drive file=TEST_DIR/t.qcow2,driver=qcow2,backing.file.filename=TEST_DIR/t.qcow2.orig,if=none,id=drive0 -nodefaults | 85 | wrote 512/512 bytes at offset 1024 |
57 | QEMU X.Y.Z monitor - type 'help' for more information | 86 | 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) |
58 | -(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K | 87 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 |
59 | +(qemu) info block | 88 | read 512/512 bytes at offset 0 |
60 | drive0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2) | 89 | 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) |
61 | Removable device: not locked, tray closed | 90 | read 512/512 bytes at offset 512 |
62 | Cache mode: writeback | ||
63 | Backing file: TEST_DIR/t.qcow2.orig (chain depth: 1) | ||
64 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
65 | +(qemu) quit | ||
66 | |||
67 | Testing: -drive file=TEST_DIR/t.qcow2,driver=raw,backing.file.filename=TEST_DIR/t.qcow2.orig | ||
68 | QEMU_PROG: -drive file=TEST_DIR/t.qcow2,driver=raw,backing.file.filename=TEST_DIR/t.qcow2.orig: Driver doesn't support backing files | ||
69 | @@ -XXX,XX +XXX,XX @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,file.backing.driver=qcow2,file.backing.f | ||
70 | |||
71 | Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=on | ||
72 | QEMU X.Y.Z monitor - type 'help' for more information | ||
73 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
74 | +(qemu) quit | ||
75 | |||
76 | Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=off | ||
77 | QEMU X.Y.Z monitor - type 'help' for more information | ||
78 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
79 | +(qemu) quit | ||
80 | |||
81 | Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts= | ||
82 | QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=: Parameter 'lazy-refcounts' expects 'on' or 'off' | ||
83 | @@ -XXX,XX +XXX,XX @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=on: Lazy ref | ||
84 | |||
85 | Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=off | ||
86 | QEMU X.Y.Z monitor - type 'help' for more information | ||
87 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
88 | +(qemu) quit | ||
89 | |||
90 | |||
91 | === No medium === | ||
92 | @@ -XXX,XX +XXX,XX @@ QEMU X.Y.Z monitor - type 'help' for more information | ||
93 | |||
94 | Testing: -drive file=TEST_DIR/t.qcow2,if=virtio,readonly=on | ||
95 | QEMU X.Y.Z monitor - type 'help' for more information | ||
96 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
97 | +(qemu) quit | ||
98 | |||
99 | |||
100 | === Cache modes === | ||
101 | |||
102 | Testing: -drive driver=null-co,cache=none | ||
103 | QEMU X.Y.Z monitor - type 'help' for more information | ||
104 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
105 | +(qemu) quit | ||
106 | |||
107 | Testing: -drive driver=null-co,cache=directsync | ||
108 | QEMU X.Y.Z monitor - type 'help' for more information | ||
109 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
110 | +(qemu) quit | ||
111 | |||
112 | Testing: -drive driver=null-co,cache=writeback | ||
113 | QEMU X.Y.Z monitor - type 'help' for more information | ||
114 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
115 | +(qemu) quit | ||
116 | |||
117 | Testing: -drive driver=null-co,cache=writethrough | ||
118 | QEMU X.Y.Z monitor - type 'help' for more information | ||
119 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
120 | +(qemu) quit | ||
121 | |||
122 | Testing: -drive driver=null-co,cache=unsafe | ||
123 | QEMU X.Y.Z monitor - type 'help' for more information | ||
124 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
125 | +(qemu) quit | ||
126 | |||
127 | Testing: -drive driver=null-co,cache=invalid_value | ||
128 | QEMU_PROG: -drive driver=null-co,cache=invalid_value: invalid cache option | ||
129 | |||
130 | Testing: -drive file=TEST_DIR/t.qcow2,cache=writeback,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0 -nodefaults | ||
131 | QEMU X.Y.Z monitor - type 'help' for more information | ||
132 | -(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K | ||
133 | +(qemu) info block | ||
134 | drive0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2) | ||
135 | Removable device: not locked, tray closed | ||
136 | Cache mode: writeback | ||
137 | Backing file: TEST_DIR/t.qcow2.base (chain depth: 1) | ||
138 | -(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K[D[D[D[D[D[D[D[D[D[Dinfo block [K[D[D[D[D[D[D[D[D[D[D[Dinfo block f[K[D[D[D[D[D[D[D[D[D[D[D[Dinfo block fi[K[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block fil[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block file[K | ||
139 | +(qemu) info block file | ||
140 | |||
141 | file: TEST_DIR/t.qcow2 (file) | ||
142 | Cache mode: writeback | ||
143 | -(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K[D[D[D[D[D[D[D[D[D[Dinfo block [K[D[D[D[D[D[D[D[D[D[D[Dinfo block b[K[D[D[D[D[D[D[D[D[D[D[D[Dinfo block ba[K[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block bac[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block back[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backi[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backin[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing[K | ||
144 | +(qemu) info block backing | ||
145 | backing: TEST_DIR/t.qcow2.base (qcow2, read-only) | ||
146 | Cache mode: writeback, ignore flushes | ||
147 | -(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K[D[D[D[D[D[D[D[D[D[Dinfo block [K[D[D[D[D[D[D[D[D[D[D[Dinfo block b[K[D[D[D[D[D[D[D[D[D[D[D[Dinfo block ba[K[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block bac[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block back[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backi[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backin[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing-[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing-f[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing-fi[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinf | ||
148 | o block backing-fil[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing-file[K | ||
149 | +(qemu) info block backing-file | ||
150 | |||
151 | backing-file: TEST_DIR/t.qcow2.base (file, read-only) | ||
152 | Cache mode: writeback, ignore flushes | ||
153 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
154 | +(qemu) quit | ||
155 | |||
156 | Testing: -drive file=TEST_DIR/t.qcow2,cache=writethrough,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0 -nodefaults | ||
157 | QEMU X.Y.Z monitor - type 'help' for more information | ||
158 | -(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K | ||
159 | +(qemu) info block | ||
160 | drive0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2) | ||
161 | Removable device: not locked, tray closed | ||
162 | Cache mode: writethrough | ||
163 | Backing file: TEST_DIR/t.qcow2.base (chain depth: 1) | ||
164 | -(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K[D[D[D[D[D[D[D[D[D[Dinfo block [K[D[D[D[D[D[D[D[D[D[D[Dinfo block f[K[D[D[D[D[D[D[D[D[D[D[D[Dinfo block fi[K[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block fil[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block file[K | ||
165 | +(qemu) info block file | ||
166 | |||
167 | file: TEST_DIR/t.qcow2 (file) | ||
168 | Cache mode: writeback | ||
169 | -(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K[D[D[D[D[D[D[D[D[D[Dinfo block [K[D[D[D[D[D[D[D[D[D[D[Dinfo block b[K[D[D[D[D[D[D[D[D[D[D[D[Dinfo block ba[K[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block bac[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block back[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backi[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backin[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing[K | ||
170 | +(qemu) info block backing | ||
171 | backing: TEST_DIR/t.qcow2.base (qcow2, read-only) | ||
172 | Cache mode: writeback, ignore flushes | ||
173 | -(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K[D[D[D[D[D[D[D[D[D[Dinfo block [K[D[D[D[D[D[D[D[D[D[D[Dinfo block b[K[D[D[D[D[D[D[D[D[D[D[D[Dinfo block ba[K[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block bac[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block back[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backi[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backin[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing-[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing-f[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing-fi[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinf | ||
174 | o block backing-fil[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing-file[K | ||
175 | +(qemu) info block backing-file | ||
176 | |||
177 | backing-file: TEST_DIR/t.qcow2.base (file, read-only) | ||
178 | Cache mode: writeback, ignore flushes | ||
179 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
180 | +(qemu) quit | ||
181 | |||
182 | Testing: -drive file=TEST_DIR/t.qcow2,cache=unsafe,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0 -nodefaults | ||
183 | QEMU X.Y.Z monitor - type 'help' for more information | ||
184 | -(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K | ||
185 | +(qemu) info block | ||
186 | drive0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2) | ||
187 | Removable device: not locked, tray closed | ||
188 | Cache mode: writeback, ignore flushes | ||
189 | Backing file: TEST_DIR/t.qcow2.base (chain depth: 1) | ||
190 | -(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K[D[D[D[D[D[D[D[D[D[Dinfo block [K[D[D[D[D[D[D[D[D[D[D[Dinfo block f[K[D[D[D[D[D[D[D[D[D[D[D[Dinfo block fi[K[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block fil[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block file[K | ||
191 | +(qemu) info block file | ||
192 | |||
193 | file: TEST_DIR/t.qcow2 (file) | ||
194 | Cache mode: writeback, ignore flushes | ||
195 | -(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K[D[D[D[D[D[D[D[D[D[Dinfo block [K[D[D[D[D[D[D[D[D[D[D[Dinfo block b[K[D[D[D[D[D[D[D[D[D[D[D[Dinfo block ba[K[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block bac[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block back[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backi[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backin[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing[K | ||
196 | +(qemu) info block backing | ||
197 | backing: TEST_DIR/t.qcow2.base (qcow2, read-only) | ||
198 | Cache mode: writeback, ignore flushes | ||
199 | -(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K[D[D[D[D[D[D[D[D[D[Dinfo block [K[D[D[D[D[D[D[D[D[D[D[Dinfo block b[K[D[D[D[D[D[D[D[D[D[D[D[Dinfo block ba[K[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block bac[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block back[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backi[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backin[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing-[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing-f[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing-fi[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinf | ||
200 | o block backing-fil[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing-file[K | ||
201 | +(qemu) info block backing-file | ||
202 | |||
203 | backing-file: TEST_DIR/t.qcow2.base (file, read-only) | ||
204 | Cache mode: writeback, ignore flushes | ||
205 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
206 | +(qemu) quit | ||
207 | |||
208 | Testing: -drive file=TEST_DIR/t.qcow2,cache=invalid_value,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0 -nodefaults | ||
209 | QEMU_PROG: -drive file=TEST_DIR/t.qcow2,cache=invalid_value,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0: invalid cache option | ||
210 | @@ -XXX,XX +XXX,XX @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,cache=invalid_value,backing.file.filenam | ||
211 | |||
212 | Testing: -drive file=TEST_DIR/t.qcow2,file.driver=file | ||
213 | QEMU X.Y.Z monitor - type 'help' for more information | ||
214 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
215 | +(qemu) quit | ||
216 | |||
217 | |||
218 | === Leaving out required options === | ||
219 | @@ -XXX,XX +XXX,XX @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,throttling.bps-total=-5: bps/iops/max va | ||
220 | |||
221 | Testing: -drive file=TEST_DIR/t.qcow2,bps=0 | ||
222 | QEMU X.Y.Z monitor - type 'help' for more information | ||
223 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
224 | +(qemu) quit | ||
225 | |||
226 | Testing: -drive file=TEST_DIR/t.qcow2,bps=1 | ||
227 | QEMU X.Y.Z monitor - type 'help' for more information | ||
228 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
229 | +(qemu) quit | ||
230 | |||
231 | Testing: -drive file=TEST_DIR/t.qcow2,bps=1000000000000000 | ||
232 | QEMU X.Y.Z monitor - type 'help' for more information | ||
233 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
234 | +(qemu) quit | ||
235 | |||
236 | Testing: -drive file=TEST_DIR/t.qcow2,bps=1000000000000001 | ||
237 | QEMU_PROG: -drive file=TEST_DIR/t.qcow2,bps=1000000000000001: bps/iops/max values must be within [0, 1000000000000000] | ||
238 | @@ -XXX,XX +XXX,XX @@ QEMU_PROG: -drive file.filename=foo:bar: Could not open 'foo:bar': No such file | ||
239 | |||
240 | Testing: -hda file:TEST_DIR/t.qcow2 | ||
241 | QEMU X.Y.Z monitor - type 'help' for more information | ||
242 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
243 | +(qemu) quit | ||
244 | |||
245 | Testing: -drive file=file:TEST_DIR/t.qcow2 | ||
246 | QEMU X.Y.Z monitor - type 'help' for more information | ||
247 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
248 | +(qemu) quit | ||
249 | |||
250 | Testing: -drive file.filename=file:TEST_DIR/t.qcow2 | ||
251 | QEMU_PROG: -drive file.filename=file:TEST_DIR/t.qcow2: Could not open 'file:TEST_DIR/t.qcow2': No such file or directory | ||
252 | @@ -XXX,XX +XXX,XX @@ wrote 4096/4096 bytes at offset 0 | ||
253 | 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
254 | Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=drive0 -snapshot | ||
255 | QEMU X.Y.Z monitor - type 'help' for more information | ||
256 | -(qemu) q[K[Dqe[K[D[Dqem[K[D[D[Dqemu[K[D[D[D[Dqemu-[K[D[D[D[D[Dqemu-i[K[D[D[D[D[D[Dqemu-io[K[D[D[D[D[D[D[Dqemu-io [K[D[D[D[D[D[D[D[Dqemu-io d[K[D[D[D[D[D[D[D[D[Dqemu-io dr[K[D[D[D[D[D[D[D[D[D[Dqemu-io dri[K[D[D[D[D[D[D[D[D[D[D[Dqemu-io driv[K[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive[K[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "w[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wr[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wri[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "writ[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqem | ||
257 | u-io drive0 "write [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x2[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0[K[D | ||
258 | [D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k"[K | ||
259 | +(qemu) qemu-io drive0 "write -P 0x22 0 4k" | ||
260 | wrote 4096/4096 bytes at offset 0 | ||
261 | 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
262 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
263 | +(qemu) quit | ||
264 | |||
265 | Testing: -drive file=TEST_DIR/t.qcow2,snapshot=on,if=none,id=drive0 | ||
266 | QEMU X.Y.Z monitor - type 'help' for more information | ||
267 | -(qemu) q[K[Dqe[K[D[Dqem[K[D[D[Dqemu[K[D[D[D[Dqemu-[K[D[D[D[D[Dqemu-i[K[D[D[D[D[D[Dqemu-io[K[D[D[D[D[D[D[Dqemu-io [K[D[D[D[D[D[D[D[Dqemu-io d[K[D[D[D[D[D[D[D[D[Dqemu-io dr[K[D[D[D[D[D[D[D[D[D[Dqemu-io dri[K[D[D[D[D[D[D[D[D[D[D[Dqemu-io driv[K[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive[K[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "w[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wr[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wri[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "writ[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqem | ||
268 | u-io drive0 "write [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x2[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0[K[D | ||
269 | [D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k"[K | ||
270 | +(qemu) qemu-io drive0 "write -P 0x22 0 4k" | ||
271 | wrote 4096/4096 bytes at offset 0 | ||
272 | 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
273 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
274 | +(qemu) quit | ||
275 | |||
276 | Testing: -drive file.filename=TEST_DIR/t.qcow2,driver=qcow2,snapshot=on,if=none,id=drive0 | ||
277 | QEMU X.Y.Z monitor - type 'help' for more information | ||
278 | -(qemu) q[K[Dqe[K[D[Dqem[K[D[D[Dqemu[K[D[D[D[Dqemu-[K[D[D[D[D[Dqemu-i[K[D[D[D[D[D[Dqemu-io[K[D[D[D[D[D[D[Dqemu-io [K[D[D[D[D[D[D[D[Dqemu-io d[K[D[D[D[D[D[D[D[D[Dqemu-io dr[K[D[D[D[D[D[D[D[D[D[Dqemu-io dri[K[D[D[D[D[D[D[D[D[D[D[Dqemu-io driv[K[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive[K[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "w[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wr[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wri[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "writ[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqem | ||
279 | u-io drive0 "write [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x2[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0[K[D | ||
280 | [D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k"[K | ||
281 | +(qemu) qemu-io drive0 "write -P 0x22 0 4k" | ||
282 | wrote 4096/4096 bytes at offset 0 | ||
283 | 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
284 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
285 | +(qemu) quit | ||
286 | |||
287 | Testing: -drive file.filename=TEST_DIR/t.qcow2,driver=qcow2,if=none,id=drive0 -snapshot | ||
288 | QEMU X.Y.Z monitor - type 'help' for more information | ||
289 | -(qemu) q[K[Dqe[K[D[Dqem[K[D[D[Dqemu[K[D[D[D[Dqemu-[K[D[D[D[D[Dqemu-i[K[D[D[D[D[D[Dqemu-io[K[D[D[D[D[D[D[Dqemu-io [K[D[D[D[D[D[D[D[Dqemu-io d[K[D[D[D[D[D[D[D[D[Dqemu-io dr[K[D[D[D[D[D[D[D[D[D[Dqemu-io dri[K[D[D[D[D[D[D[D[D[D[D[Dqemu-io driv[K[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive[K[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "w[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wr[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wri[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "writ[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqem | ||
290 | u-io drive0 "write [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x2[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0[K[D | ||
291 | [D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k"[K | ||
292 | +(qemu) qemu-io drive0 "write -P 0x22 0 4k" | ||
293 | wrote 4096/4096 bytes at offset 0 | ||
294 | 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
295 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
296 | +(qemu) quit | ||
297 | |||
298 | Testing: -drive file=file:TEST_DIR/t.qcow2,if=none,id=drive0 -snapshot | ||
299 | QEMU X.Y.Z monitor - type 'help' for more information | ||
300 | -(qemu) q[K[Dqe[K[D[Dqem[K[D[D[Dqemu[K[D[D[D[Dqemu-[K[D[D[D[D[Dqemu-i[K[D[D[D[D[D[Dqemu-io[K[D[D[D[D[D[D[Dqemu-io [K[D[D[D[D[D[D[D[Dqemu-io d[K[D[D[D[D[D[D[D[D[Dqemu-io dr[K[D[D[D[D[D[D[D[D[D[Dqemu-io dri[K[D[D[D[D[D[D[D[D[D[D[Dqemu-io driv[K[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive[K[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "w[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wr[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wri[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "writ[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqem | ||
301 | u-io drive0 "write [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x2[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0[K[D | ||
302 | [D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k"[K | ||
303 | +(qemu) qemu-io drive0 "write -P 0x22 0 4k" | ||
304 | wrote 4096/4096 bytes at offset 0 | ||
305 | 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
306 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
307 | +(qemu) quit | ||
308 | |||
309 | Testing: -drive file=file:TEST_DIR/t.qcow2,snapshot=on,if=none,id=drive0 | ||
310 | QEMU X.Y.Z monitor - type 'help' for more information | ||
311 | -(qemu) q[K[Dqe[K[D[Dqem[K[D[D[Dqemu[K[D[D[D[Dqemu-[K[D[D[D[D[Dqemu-i[K[D[D[D[D[D[Dqemu-io[K[D[D[D[D[D[D[Dqemu-io [K[D[D[D[D[D[D[D[Dqemu-io d[K[D[D[D[D[D[D[D[D[Dqemu-io dr[K[D[D[D[D[D[D[D[D[D[Dqemu-io dri[K[D[D[D[D[D[D[D[D[D[D[Dqemu-io driv[K[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive[K[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "w[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wr[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wri[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "writ[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqem | ||
312 | u-io drive0 "write [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x2[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0[K[D | ||
313 | [D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k"[K | ||
314 | +(qemu) qemu-io drive0 "write -P 0x22 0 4k" | ||
315 | wrote 4096/4096 bytes at offset 0 | ||
316 | 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
317 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
318 | +(qemu) quit | ||
319 | |||
320 | Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=drive0 -snapshot | ||
321 | QEMU X.Y.Z monitor - type 'help' for more information | ||
322 | -(qemu) q[K[Dqe[K[D[Dqem[K[D[D[Dqemu[K[D[D[D[Dqemu-[K[D[D[D[D[Dqemu-i[K[D[D[D[D[D[Dqemu-io[K[D[D[D[D[D[D[Dqemu-io [K[D[D[D[D[D[D[D[Dqemu-io d[K[D[D[D[D[D[D[D[D[Dqemu-io dr[K[D[D[D[D[D[D[D[D[D[Dqemu-io dri[K[D[D[D[D[D[D[D[D[D[D[Dqemu-io driv[K[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive[K[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "w[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wr[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wri[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "writ[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqem | ||
323 | u-io drive0 "write [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x2[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0[K[D | ||
324 | [D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k"[K | ||
325 | +(qemu) qemu-io drive0 "write -P 0x22 0 4k" | ||
326 | wrote 4096/4096 bytes at offset 0 | ||
327 | 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
328 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
329 | +(qemu) quit | ||
330 | |||
331 | Testing: -drive file=TEST_DIR/t.qcow2,snapshot=on,if=none,id=drive0 | ||
332 | QEMU X.Y.Z monitor - type 'help' for more information | ||
333 | -(qemu) q[K[Dqe[K[D[Dqem[K[D[D[Dqemu[K[D[D[D[Dqemu-[K[D[D[D[D[Dqemu-i[K[D[D[D[D[D[Dqemu-io[K[D[D[D[D[D[D[Dqemu-io [K[D[D[D[D[D[D[D[Dqemu-io d[K[D[D[D[D[D[D[D[D[Dqemu-io dr[K[D[D[D[D[D[D[D[D[D[Dqemu-io dri[K[D[D[D[D[D[D[D[D[D[D[Dqemu-io driv[K[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive[K[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "w[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wr[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wri[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "writ[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqem | ||
334 | u-io drive0 "write [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x2[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0[K[D | ||
335 | [D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k"[K | ||
336 | +(qemu) qemu-io drive0 "write -P 0x22 0 4k" | ||
337 | wrote 4096/4096 bytes at offset 0 | ||
338 | 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
339 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
340 | +(qemu) quit | ||
341 | |||
342 | read 4096/4096 bytes at offset 0 | ||
343 | 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
344 | Testing: -drive file=TEST_DIR/t.qcow2,snapshot=off,if=none,id=drive0 | ||
345 | QEMU X.Y.Z monitor - type 'help' for more information | ||
346 | -(qemu) q[K[Dqe[K[D[Dqem[K[D[D[Dqemu[K[D[D[D[Dqemu-[K[D[D[D[D[Dqemu-i[K[D[D[D[D[D[Dqemu-io[K[D[D[D[D[D[D[Dqemu-io [K[D[D[D[D[D[D[D[Dqemu-io d[K[D[D[D[D[D[D[D[D[Dqemu-io dr[K[D[D[D[D[D[D[D[D[D[Dqemu-io dri[K[D[D[D[D[D[D[D[D[D[D[Dqemu-io driv[K[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive[K[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "w[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wr[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wri[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "writ[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqem | ||
347 | u-io drive0 "write [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x2[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0[K[D | ||
348 | [D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k"[K | ||
349 | +(qemu) qemu-io drive0 "write -P 0x22 0 4k" | ||
350 | wrote 4096/4096 bytes at offset 0 | ||
351 | 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
352 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
353 | +(qemu) quit | ||
354 | |||
355 | read 4096/4096 bytes at offset 0 | ||
356 | 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
357 | Testing: -drive file=TEST_DIR/t.qcow2,snapshot=on,if=none,id=drive0 | ||
358 | QEMU X.Y.Z monitor - type 'help' for more information | ||
359 | -(qemu) q[K[Dqe[K[D[Dqem[K[D[D[Dqemu[K[D[D[D[Dqemu-[K[D[D[D[D[Dqemu-i[K[D[D[D[D[D[Dqemu-io[K[D[D[D[D[D[D[Dqemu-io [K[D[D[D[D[D[D[D[Dqemu-io d[K[D[D[D[D[D[D[D[D[Dqemu-io dr[K[D[D[D[D[D[D[D[D[D[Dqemu-io dri[K[D[D[D[D[D[D[D[D[D[D[Dqemu-io driv[K[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive[K[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "w[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wr[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wri[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "writ[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqem | ||
360 | u-io drive0 "write [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x3[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x33[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x33 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x33 0[K[D | ||
361 | [D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x33 0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x33 0 4[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x33 0 4k[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x33 0 4k"[K | ||
362 | +(qemu) qemu-io drive0 "write -P 0x33 0 4k" | ||
363 | wrote 4096/4096 bytes at offset 0 | ||
364 | 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
365 | -(qemu) c[K[Dco[K[D[Dcom[K[D[D[Dcomm[K[D[D[D[Dcommi[K[D[D[D[D[Dcommit[K[D[D[D[D[D[Dcommit [K[D[D[D[D[D[D[Dcommit d[K[D[D[D[D[D[D[D[Dcommit dr[K[D[D[D[D[D[D[D[D[Dcommit dri[K[D[D[D[D[D[D[D[D[D[Dcommit driv[K[D[D[D[D[D[D[D[D[D[D[Dcommit drive[K[D[D[D[D[D[D[D[D[D[D[D[Dcommit drive0[K | ||
366 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
367 | +(qemu) commit drive0 | ||
368 | +(qemu) quit | ||
369 | |||
370 | read 4096/4096 bytes at offset 0 | ||
371 | 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
372 | diff --git a/tests/qemu-iotests/051.pc.out b/tests/qemu-iotests/051.pc.out | ||
373 | index XXXXXXX..XXXXXXX 100644 | ||
374 | --- a/tests/qemu-iotests/051.pc.out | ||
375 | +++ b/tests/qemu-iotests/051.pc.out | ||
376 | @@ -XXX,XX +XXX,XX @@ QEMU X.Y.Z monitor - type 'help' for more information | ||
377 | |||
378 | Testing: -drive file=TEST_DIR/t.qcow2,driver=qcow2,backing.file.filename=TEST_DIR/t.qcow2.orig,if=none,id=drive0 -nodefaults | ||
379 | QEMU X.Y.Z monitor - type 'help' for more information | ||
380 | -(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K | ||
381 | +(qemu) info block | ||
382 | drive0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2) | ||
383 | Removable device: not locked, tray closed | ||
384 | Cache mode: writeback | ||
385 | Backing file: TEST_DIR/t.qcow2.orig (chain depth: 1) | ||
386 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
387 | +(qemu) quit | ||
388 | |||
389 | Testing: -drive file=TEST_DIR/t.qcow2,driver=raw,backing.file.filename=TEST_DIR/t.qcow2.orig | ||
390 | QEMU_PROG: -drive file=TEST_DIR/t.qcow2,driver=raw,backing.file.filename=TEST_DIR/t.qcow2.orig: Driver doesn't support backing files | ||
391 | @@ -XXX,XX +XXX,XX @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,file.backing.driver=qcow2,file.backing.f | ||
392 | |||
393 | Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=on | ||
394 | QEMU X.Y.Z monitor - type 'help' for more information | ||
395 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
396 | +(qemu) quit | ||
397 | |||
398 | Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=off | ||
399 | QEMU X.Y.Z monitor - type 'help' for more information | ||
400 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
401 | +(qemu) quit | ||
402 | |||
403 | Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts= | ||
404 | QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=: Parameter 'lazy-refcounts' expects 'on' or 'off' | ||
405 | @@ -XXX,XX +XXX,XX @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=on: Lazy ref | ||
406 | |||
407 | Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=off | ||
408 | QEMU X.Y.Z monitor - type 'help' for more information | ||
409 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
410 | +(qemu) quit | ||
411 | |||
412 | |||
413 | === No medium === | ||
414 | |||
415 | Testing: -drive if=floppy | ||
416 | QEMU X.Y.Z monitor - type 'help' for more information | ||
417 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
418 | +(qemu) quit | ||
419 | |||
420 | Testing: -drive if=ide,media=cdrom | ||
421 | QEMU X.Y.Z monitor - type 'help' for more information | ||
422 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
423 | +(qemu) quit | ||
424 | |||
425 | Testing: -drive if=scsi,media=cdrom | ||
426 | QEMU X.Y.Z monitor - type 'help' for more information | ||
427 | (qemu) QEMU_PROG: -drive if=scsi,media=cdrom: warning: bus=0,unit=0 is deprecated with this machine type | ||
428 | -q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
429 | +quit | ||
430 | |||
431 | Testing: -drive if=ide | ||
432 | QEMU X.Y.Z monitor - type 'help' for more information | ||
433 | @@ -XXX,XX +XXX,XX @@ QEMU X.Y.Z monitor - type 'help' for more information | ||
434 | |||
435 | Testing: -drive if=none,id=disk -device ide-cd,drive=disk | ||
436 | QEMU X.Y.Z monitor - type 'help' for more information | ||
437 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
438 | +(qemu) quit | ||
439 | |||
440 | Testing: -drive if=none,id=disk -device lsi53c895a -device scsi-cd,drive=disk | ||
441 | QEMU X.Y.Z monitor - type 'help' for more information | ||
442 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
443 | +(qemu) quit | ||
444 | |||
445 | Testing: -drive if=none,id=disk -device ide-drive,drive=disk | ||
446 | QEMU X.Y.Z monitor - type 'help' for more information | ||
447 | @@ -XXX,XX +XXX,XX @@ QEMU X.Y.Z monitor - type 'help' for more information | ||
448 | |||
449 | Testing: -drive file=TEST_DIR/t.qcow2,if=floppy,readonly=on | ||
450 | QEMU X.Y.Z monitor - type 'help' for more information | ||
451 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
452 | +(qemu) quit | ||
453 | |||
454 | Testing: -drive file=TEST_DIR/t.qcow2,if=ide,media=cdrom,readonly=on | ||
455 | QEMU X.Y.Z monitor - type 'help' for more information | ||
456 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
457 | +(qemu) quit | ||
458 | |||
459 | Testing: -drive file=TEST_DIR/t.qcow2,if=scsi,media=cdrom,readonly=on | ||
460 | QEMU X.Y.Z monitor - type 'help' for more information | ||
461 | (qemu) QEMU_PROG: -drive file=TEST_DIR/t.qcow2,if=scsi,media=cdrom,readonly=on: warning: bus=0,unit=0 is deprecated with this machine type | ||
462 | -q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
463 | +quit | ||
464 | |||
465 | Testing: -drive file=TEST_DIR/t.qcow2,if=ide,readonly=on | ||
466 | QEMU X.Y.Z monitor - type 'help' for more information | ||
467 | @@ -XXX,XX +XXX,XX @@ QEMU_PROG: Initialization of device ide-hd failed: Device initialization failed. | ||
468 | Testing: -drive file=TEST_DIR/t.qcow2,if=scsi,readonly=on | ||
469 | QEMU X.Y.Z monitor - type 'help' for more information | ||
470 | (qemu) QEMU_PROG: -drive file=TEST_DIR/t.qcow2,if=scsi,readonly=on: warning: bus=0,unit=0 is deprecated with this machine type | ||
471 | -q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
472 | +quit | ||
473 | |||
474 | Testing: -drive file=TEST_DIR/t.qcow2,if=virtio,readonly=on | ||
475 | QEMU X.Y.Z monitor - type 'help' for more information | ||
476 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
477 | +(qemu) quit | ||
478 | |||
479 | Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device ide-cd,drive=disk | ||
480 | QEMU X.Y.Z monitor - type 'help' for more information | ||
481 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
482 | +(qemu) quit | ||
483 | |||
484 | Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device lsi53c895a -device scsi-cd,drive=disk | ||
485 | QEMU X.Y.Z monitor - type 'help' for more information | ||
486 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
487 | +(qemu) quit | ||
488 | |||
489 | Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device ide-drive,drive=disk | ||
490 | QEMU X.Y.Z monitor - type 'help' for more information | ||
491 | @@ -XXX,XX +XXX,XX @@ QEMU_PROG: -device ide-hd,drive=disk: Device initialization failed. | ||
492 | |||
493 | Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device lsi53c895a -device scsi-disk,drive=disk | ||
494 | QEMU X.Y.Z monitor - type 'help' for more information | ||
495 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
496 | +(qemu) quit | ||
497 | |||
498 | Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device lsi53c895a -device scsi-hd,drive=disk | ||
499 | QEMU X.Y.Z monitor - type 'help' for more information | ||
500 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
501 | +(qemu) quit | ||
502 | |||
503 | |||
504 | === Cache modes === | ||
505 | |||
506 | Testing: -drive driver=null-co,cache=none | ||
507 | QEMU X.Y.Z monitor - type 'help' for more information | ||
508 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
509 | +(qemu) quit | ||
510 | |||
511 | Testing: -drive driver=null-co,cache=directsync | ||
512 | QEMU X.Y.Z monitor - type 'help' for more information | ||
513 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
514 | +(qemu) quit | ||
515 | |||
516 | Testing: -drive driver=null-co,cache=writeback | ||
517 | QEMU X.Y.Z monitor - type 'help' for more information | ||
518 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
519 | +(qemu) quit | ||
520 | |||
521 | Testing: -drive driver=null-co,cache=writethrough | ||
522 | QEMU X.Y.Z monitor - type 'help' for more information | ||
523 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
524 | +(qemu) quit | ||
525 | |||
526 | Testing: -drive driver=null-co,cache=unsafe | ||
527 | QEMU X.Y.Z monitor - type 'help' for more information | ||
528 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
529 | +(qemu) quit | ||
530 | |||
531 | Testing: -drive driver=null-co,cache=invalid_value | ||
532 | QEMU_PROG: -drive driver=null-co,cache=invalid_value: invalid cache option | ||
533 | |||
534 | Testing: -drive file=TEST_DIR/t.qcow2,cache=writeback,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0 -nodefaults | ||
535 | QEMU X.Y.Z monitor - type 'help' for more information | ||
536 | -(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K | ||
537 | +(qemu) info block | ||
538 | drive0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2) | ||
539 | Removable device: not locked, tray closed | ||
540 | Cache mode: writeback | ||
541 | Backing file: TEST_DIR/t.qcow2.base (chain depth: 1) | ||
542 | -(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K[D[D[D[D[D[D[D[D[D[Dinfo block [K[D[D[D[D[D[D[D[D[D[D[Dinfo block f[K[D[D[D[D[D[D[D[D[D[D[D[Dinfo block fi[K[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block fil[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block file[K | ||
543 | +(qemu) info block file | ||
544 | |||
545 | file: TEST_DIR/t.qcow2 (file) | ||
546 | Cache mode: writeback | ||
547 | -(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K[D[D[D[D[D[D[D[D[D[Dinfo block [K[D[D[D[D[D[D[D[D[D[D[Dinfo block b[K[D[D[D[D[D[D[D[D[D[D[D[Dinfo block ba[K[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block bac[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block back[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backi[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backin[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing[K | ||
548 | +(qemu) info block backing | ||
549 | backing: TEST_DIR/t.qcow2.base (qcow2, read-only) | ||
550 | Cache mode: writeback, ignore flushes | ||
551 | -(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K[D[D[D[D[D[D[D[D[D[Dinfo block [K[D[D[D[D[D[D[D[D[D[D[Dinfo block b[K[D[D[D[D[D[D[D[D[D[D[D[Dinfo block ba[K[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block bac[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block back[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backi[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backin[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing-[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing-f[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing-fi[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinf | ||
552 | o block backing-fil[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing-file[K | ||
553 | +(qemu) info block backing-file | ||
554 | |||
555 | backing-file: TEST_DIR/t.qcow2.base (file, read-only) | ||
556 | Cache mode: writeback, ignore flushes | ||
557 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
558 | +(qemu) quit | ||
559 | |||
560 | Testing: -drive file=TEST_DIR/t.qcow2,cache=writethrough,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0 -nodefaults | ||
561 | QEMU X.Y.Z monitor - type 'help' for more information | ||
562 | -(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K | ||
563 | +(qemu) info block | ||
564 | drive0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2) | ||
565 | Removable device: not locked, tray closed | ||
566 | Cache mode: writethrough | ||
567 | Backing file: TEST_DIR/t.qcow2.base (chain depth: 1) | ||
568 | -(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K[D[D[D[D[D[D[D[D[D[Dinfo block [K[D[D[D[D[D[D[D[D[D[D[Dinfo block f[K[D[D[D[D[D[D[D[D[D[D[D[Dinfo block fi[K[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block fil[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block file[K | ||
569 | +(qemu) info block file | ||
570 | |||
571 | file: TEST_DIR/t.qcow2 (file) | ||
572 | Cache mode: writeback | ||
573 | -(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K[D[D[D[D[D[D[D[D[D[Dinfo block [K[D[D[D[D[D[D[D[D[D[D[Dinfo block b[K[D[D[D[D[D[D[D[D[D[D[D[Dinfo block ba[K[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block bac[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block back[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backi[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backin[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing[K | ||
574 | +(qemu) info block backing | ||
575 | backing: TEST_DIR/t.qcow2.base (qcow2, read-only) | ||
576 | Cache mode: writeback, ignore flushes | ||
577 | -(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K[D[D[D[D[D[D[D[D[D[Dinfo block [K[D[D[D[D[D[D[D[D[D[D[Dinfo block b[K[D[D[D[D[D[D[D[D[D[D[D[Dinfo block ba[K[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block bac[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block back[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backi[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backin[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing-[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing-f[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing-fi[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinf | ||
578 | o block backing-fil[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing-file[K | ||
579 | +(qemu) info block backing-file | ||
580 | |||
581 | backing-file: TEST_DIR/t.qcow2.base (file, read-only) | ||
582 | Cache mode: writeback, ignore flushes | ||
583 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
584 | +(qemu) quit | ||
585 | |||
586 | Testing: -drive file=TEST_DIR/t.qcow2,cache=unsafe,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0 -nodefaults | ||
587 | QEMU X.Y.Z monitor - type 'help' for more information | ||
588 | -(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K | ||
589 | +(qemu) info block | ||
590 | drive0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2) | ||
591 | Removable device: not locked, tray closed | ||
592 | Cache mode: writeback, ignore flushes | ||
593 | Backing file: TEST_DIR/t.qcow2.base (chain depth: 1) | ||
594 | -(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K[D[D[D[D[D[D[D[D[D[Dinfo block [K[D[D[D[D[D[D[D[D[D[D[Dinfo block f[K[D[D[D[D[D[D[D[D[D[D[D[Dinfo block fi[K[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block fil[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block file[K | ||
595 | +(qemu) info block file | ||
596 | |||
597 | file: TEST_DIR/t.qcow2 (file) | ||
598 | Cache mode: writeback, ignore flushes | ||
599 | -(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K[D[D[D[D[D[D[D[D[D[Dinfo block [K[D[D[D[D[D[D[D[D[D[D[Dinfo block b[K[D[D[D[D[D[D[D[D[D[D[D[Dinfo block ba[K[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block bac[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block back[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backi[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backin[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing[K | ||
600 | +(qemu) info block backing | ||
601 | backing: TEST_DIR/t.qcow2.base (qcow2, read-only) | ||
602 | Cache mode: writeback, ignore flushes | ||
603 | -(qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K[D[D[D[D[D[D[D[D[D[Dinfo block [K[D[D[D[D[D[D[D[D[D[D[Dinfo block b[K[D[D[D[D[D[D[D[D[D[D[D[Dinfo block ba[K[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block bac[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block back[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backi[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backin[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing-[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing-f[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing-fi[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinf | ||
604 | o block backing-fil[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block backing-file[K | ||
605 | +(qemu) info block backing-file | ||
606 | |||
607 | backing-file: TEST_DIR/t.qcow2.base (file, read-only) | ||
608 | Cache mode: writeback, ignore flushes | ||
609 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
610 | +(qemu) quit | ||
611 | |||
612 | Testing: -drive file=TEST_DIR/t.qcow2,cache=invalid_value,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0 -nodefaults | ||
613 | QEMU_PROG: -drive file=TEST_DIR/t.qcow2,cache=invalid_value,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0: invalid cache option | ||
614 | @@ -XXX,XX +XXX,XX @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,cache=invalid_value,backing.file.filenam | ||
615 | |||
616 | Testing: -drive file=TEST_DIR/t.qcow2,file.driver=file | ||
617 | QEMU X.Y.Z monitor - type 'help' for more information | ||
618 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
619 | +(qemu) quit | ||
620 | |||
621 | |||
622 | === Leaving out required options === | ||
623 | @@ -XXX,XX +XXX,XX @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,throttling.bps-total=-5: bps/iops/max va | ||
624 | |||
625 | Testing: -drive file=TEST_DIR/t.qcow2,bps=0 | ||
626 | QEMU X.Y.Z monitor - type 'help' for more information | ||
627 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
628 | +(qemu) quit | ||
629 | |||
630 | Testing: -drive file=TEST_DIR/t.qcow2,bps=1 | ||
631 | QEMU X.Y.Z monitor - type 'help' for more information | ||
632 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
633 | +(qemu) quit | ||
634 | |||
635 | Testing: -drive file=TEST_DIR/t.qcow2,bps=1000000000000000 | ||
636 | QEMU X.Y.Z monitor - type 'help' for more information | ||
637 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
638 | +(qemu) quit | ||
639 | |||
640 | Testing: -drive file=TEST_DIR/t.qcow2,bps=1000000000000001 | ||
641 | QEMU_PROG: -drive file=TEST_DIR/t.qcow2,bps=1000000000000001: bps/iops/max values must be within [0, 1000000000000000] | ||
642 | @@ -XXX,XX +XXX,XX @@ QEMU_PROG: -drive file.filename=foo:bar: Could not open 'foo:bar': No such file | ||
643 | |||
644 | Testing: -hda file:TEST_DIR/t.qcow2 | ||
645 | QEMU X.Y.Z monitor - type 'help' for more information | ||
646 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
647 | +(qemu) quit | ||
648 | |||
649 | Testing: -drive file=file:TEST_DIR/t.qcow2 | ||
650 | QEMU X.Y.Z monitor - type 'help' for more information | ||
651 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
652 | +(qemu) quit | ||
653 | |||
654 | Testing: -drive file.filename=file:TEST_DIR/t.qcow2 | ||
655 | QEMU_PROG: -drive file.filename=file:TEST_DIR/t.qcow2: Could not open 'file:TEST_DIR/t.qcow2': No such file or directory | ||
656 | @@ -XXX,XX +XXX,XX @@ wrote 4096/4096 bytes at offset 0 | ||
657 | 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
658 | Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=drive0 -snapshot | ||
659 | QEMU X.Y.Z monitor - type 'help' for more information | ||
660 | -(qemu) q[K[Dqe[K[D[Dqem[K[D[D[Dqemu[K[D[D[D[Dqemu-[K[D[D[D[D[Dqemu-i[K[D[D[D[D[D[Dqemu-io[K[D[D[D[D[D[D[Dqemu-io [K[D[D[D[D[D[D[D[Dqemu-io d[K[D[D[D[D[D[D[D[D[Dqemu-io dr[K[D[D[D[D[D[D[D[D[D[Dqemu-io dri[K[D[D[D[D[D[D[D[D[D[D[Dqemu-io driv[K[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive[K[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "w[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wr[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wri[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "writ[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqem | ||
661 | u-io drive0 "write [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x2[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0[K[D | ||
662 | [D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k"[K | ||
663 | +(qemu) qemu-io drive0 "write -P 0x22 0 4k" | ||
664 | wrote 4096/4096 bytes at offset 0 | ||
665 | 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
666 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
667 | +(qemu) quit | ||
668 | |||
669 | Testing: -drive file=TEST_DIR/t.qcow2,snapshot=on,if=none,id=drive0 | ||
670 | QEMU X.Y.Z monitor - type 'help' for more information | ||
671 | -(qemu) q[K[Dqe[K[D[Dqem[K[D[D[Dqemu[K[D[D[D[Dqemu-[K[D[D[D[D[Dqemu-i[K[D[D[D[D[D[Dqemu-io[K[D[D[D[D[D[D[Dqemu-io [K[D[D[D[D[D[D[D[Dqemu-io d[K[D[D[D[D[D[D[D[D[Dqemu-io dr[K[D[D[D[D[D[D[D[D[D[Dqemu-io dri[K[D[D[D[D[D[D[D[D[D[D[Dqemu-io driv[K[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive[K[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "w[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wr[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wri[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "writ[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqem | ||
672 | u-io drive0 "write [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x2[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0[K[D | ||
673 | [D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k"[K | ||
674 | +(qemu) qemu-io drive0 "write -P 0x22 0 4k" | ||
675 | wrote 4096/4096 bytes at offset 0 | ||
676 | 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
677 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
678 | +(qemu) quit | ||
679 | |||
680 | Testing: -drive file.filename=TEST_DIR/t.qcow2,driver=qcow2,snapshot=on,if=none,id=drive0 | ||
681 | QEMU X.Y.Z monitor - type 'help' for more information | ||
682 | -(qemu) q[K[Dqe[K[D[Dqem[K[D[D[Dqemu[K[D[D[D[Dqemu-[K[D[D[D[D[Dqemu-i[K[D[D[D[D[D[Dqemu-io[K[D[D[D[D[D[D[Dqemu-io [K[D[D[D[D[D[D[D[Dqemu-io d[K[D[D[D[D[D[D[D[D[Dqemu-io dr[K[D[D[D[D[D[D[D[D[D[Dqemu-io dri[K[D[D[D[D[D[D[D[D[D[D[Dqemu-io driv[K[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive[K[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "w[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wr[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wri[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "writ[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqem | ||
683 | u-io drive0 "write [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x2[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0[K[D | ||
684 | [D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k"[K | ||
685 | +(qemu) qemu-io drive0 "write -P 0x22 0 4k" | ||
686 | wrote 4096/4096 bytes at offset 0 | ||
687 | 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
688 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
689 | +(qemu) quit | ||
690 | |||
691 | Testing: -drive file.filename=TEST_DIR/t.qcow2,driver=qcow2,if=none,id=drive0 -snapshot | ||
692 | QEMU X.Y.Z monitor - type 'help' for more information | ||
693 | -(qemu) q[K[Dqe[K[D[Dqem[K[D[D[Dqemu[K[D[D[D[Dqemu-[K[D[D[D[D[Dqemu-i[K[D[D[D[D[D[Dqemu-io[K[D[D[D[D[D[D[Dqemu-io [K[D[D[D[D[D[D[D[Dqemu-io d[K[D[D[D[D[D[D[D[D[Dqemu-io dr[K[D[D[D[D[D[D[D[D[D[Dqemu-io dri[K[D[D[D[D[D[D[D[D[D[D[Dqemu-io driv[K[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive[K[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "w[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wr[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wri[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "writ[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqem | ||
694 | u-io drive0 "write [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x2[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0[K[D | ||
695 | [D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k"[K | ||
696 | +(qemu) qemu-io drive0 "write -P 0x22 0 4k" | ||
697 | wrote 4096/4096 bytes at offset 0 | ||
698 | 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
699 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
700 | +(qemu) quit | ||
701 | |||
702 | Testing: -drive file=file:TEST_DIR/t.qcow2,if=none,id=drive0 -snapshot | ||
703 | QEMU X.Y.Z monitor - type 'help' for more information | ||
704 | -(qemu) q[K[Dqe[K[D[Dqem[K[D[D[Dqemu[K[D[D[D[Dqemu-[K[D[D[D[D[Dqemu-i[K[D[D[D[D[D[Dqemu-io[K[D[D[D[D[D[D[Dqemu-io [K[D[D[D[D[D[D[D[Dqemu-io d[K[D[D[D[D[D[D[D[D[Dqemu-io dr[K[D[D[D[D[D[D[D[D[D[Dqemu-io dri[K[D[D[D[D[D[D[D[D[D[D[Dqemu-io driv[K[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive[K[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "w[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wr[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wri[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "writ[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqem | ||
705 | u-io drive0 "write [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x2[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0[K[D | ||
706 | [D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k"[K | ||
707 | +(qemu) qemu-io drive0 "write -P 0x22 0 4k" | ||
708 | wrote 4096/4096 bytes at offset 0 | ||
709 | 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
710 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
711 | +(qemu) quit | ||
712 | |||
713 | Testing: -drive file=file:TEST_DIR/t.qcow2,snapshot=on,if=none,id=drive0 | ||
714 | QEMU X.Y.Z monitor - type 'help' for more information | ||
715 | -(qemu) q[K[Dqe[K[D[Dqem[K[D[D[Dqemu[K[D[D[D[Dqemu-[K[D[D[D[D[Dqemu-i[K[D[D[D[D[D[Dqemu-io[K[D[D[D[D[D[D[Dqemu-io [K[D[D[D[D[D[D[D[Dqemu-io d[K[D[D[D[D[D[D[D[D[Dqemu-io dr[K[D[D[D[D[D[D[D[D[D[Dqemu-io dri[K[D[D[D[D[D[D[D[D[D[D[Dqemu-io driv[K[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive[K[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "w[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wr[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wri[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "writ[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqem | ||
716 | u-io drive0 "write [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x2[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0[K[D | ||
717 | [D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k"[K | ||
718 | +(qemu) qemu-io drive0 "write -P 0x22 0 4k" | ||
719 | wrote 4096/4096 bytes at offset 0 | ||
720 | 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
721 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
722 | +(qemu) quit | ||
723 | |||
724 | Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=drive0 -snapshot | ||
725 | QEMU X.Y.Z monitor - type 'help' for more information | ||
726 | -(qemu) q[K[Dqe[K[D[Dqem[K[D[D[Dqemu[K[D[D[D[Dqemu-[K[D[D[D[D[Dqemu-i[K[D[D[D[D[D[Dqemu-io[K[D[D[D[D[D[D[Dqemu-io [K[D[D[D[D[D[D[D[Dqemu-io d[K[D[D[D[D[D[D[D[D[Dqemu-io dr[K[D[D[D[D[D[D[D[D[D[Dqemu-io dri[K[D[D[D[D[D[D[D[D[D[D[Dqemu-io driv[K[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive[K[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "w[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wr[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wri[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "writ[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqem | ||
727 | u-io drive0 "write [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x2[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0[K[D | ||
728 | [D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k"[K | ||
729 | +(qemu) qemu-io drive0 "write -P 0x22 0 4k" | ||
730 | wrote 4096/4096 bytes at offset 0 | ||
731 | 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
732 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
733 | +(qemu) quit | ||
734 | |||
735 | Testing: -drive file=TEST_DIR/t.qcow2,snapshot=on,if=none,id=drive0 | ||
736 | QEMU X.Y.Z monitor - type 'help' for more information | ||
737 | -(qemu) q[K[Dqe[K[D[Dqem[K[D[D[Dqemu[K[D[D[D[Dqemu-[K[D[D[D[D[Dqemu-i[K[D[D[D[D[D[Dqemu-io[K[D[D[D[D[D[D[Dqemu-io [K[D[D[D[D[D[D[D[Dqemu-io d[K[D[D[D[D[D[D[D[D[Dqemu-io dr[K[D[D[D[D[D[D[D[D[D[Dqemu-io dri[K[D[D[D[D[D[D[D[D[D[D[Dqemu-io driv[K[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive[K[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "w[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wr[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wri[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "writ[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqem | ||
738 | u-io drive0 "write [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x2[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0[K[D | ||
739 | [D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k"[K | ||
740 | +(qemu) qemu-io drive0 "write -P 0x22 0 4k" | ||
741 | wrote 4096/4096 bytes at offset 0 | ||
742 | 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
743 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
744 | +(qemu) quit | ||
745 | |||
746 | read 4096/4096 bytes at offset 0 | ||
747 | 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
748 | Testing: -drive file=TEST_DIR/t.qcow2,snapshot=off,if=none,id=drive0 | ||
749 | QEMU X.Y.Z monitor - type 'help' for more information | ||
750 | -(qemu) q[K[Dqe[K[D[Dqem[K[D[D[Dqemu[K[D[D[D[Dqemu-[K[D[D[D[D[Dqemu-i[K[D[D[D[D[D[Dqemu-io[K[D[D[D[D[D[D[Dqemu-io [K[D[D[D[D[D[D[D[Dqemu-io d[K[D[D[D[D[D[D[D[D[Dqemu-io dr[K[D[D[D[D[D[D[D[D[D[Dqemu-io dri[K[D[D[D[D[D[D[D[D[D[D[Dqemu-io driv[K[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive[K[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "w[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wr[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wri[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "writ[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqem | ||
751 | u-io drive0 "write [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x2[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0[K[D | ||
752 | [D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x22 0 4k"[K | ||
753 | +(qemu) qemu-io drive0 "write -P 0x22 0 4k" | ||
754 | wrote 4096/4096 bytes at offset 0 | ||
755 | 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
756 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
757 | +(qemu) quit | ||
758 | |||
759 | read 4096/4096 bytes at offset 0 | ||
760 | 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
761 | Testing: -drive file=TEST_DIR/t.qcow2,snapshot=on,if=none,id=drive0 | ||
762 | QEMU X.Y.Z monitor - type 'help' for more information | ||
763 | -(qemu) q[K[Dqe[K[D[Dqem[K[D[D[Dqemu[K[D[D[D[Dqemu-[K[D[D[D[D[Dqemu-i[K[D[D[D[D[D[Dqemu-io[K[D[D[D[D[D[D[Dqemu-io [K[D[D[D[D[D[D[D[Dqemu-io d[K[D[D[D[D[D[D[D[D[Dqemu-io dr[K[D[D[D[D[D[D[D[D[D[Dqemu-io dri[K[D[D[D[D[D[D[D[D[D[D[Dqemu-io driv[K[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive[K[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "w[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wr[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "wri[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "writ[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqem | ||
764 | u-io drive0 "write [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x3[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x33[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x33 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x33 0[K[D | ||
765 | [D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x33 0 [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x33 0 4[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x33 0 4k[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Dqemu-io drive0 "write -P 0x33 0 4k"[K | ||
766 | +(qemu) qemu-io drive0 "write -P 0x33 0 4k" | ||
767 | wrote 4096/4096 bytes at offset 0 | ||
768 | 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
769 | -(qemu) c[K[Dco[K[D[Dcom[K[D[D[Dcomm[K[D[D[D[Dcommi[K[D[D[D[D[Dcommit[K[D[D[D[D[D[Dcommit [K[D[D[D[D[D[D[Dcommit d[K[D[D[D[D[D[D[D[Dcommit dr[K[D[D[D[D[D[D[D[D[Dcommit dri[K[D[D[D[D[D[D[D[D[D[Dcommit driv[K[D[D[D[D[D[D[D[D[D[D[Dcommit drive[K[D[D[D[D[D[D[D[D[D[D[D[Dcommit drive0[K | ||
770 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
771 | +(qemu) commit drive0 | ||
772 | +(qemu) quit | ||
773 | |||
774 | read 4096/4096 bytes at offset 0 | ||
775 | 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
776 | diff --git a/tests/qemu-iotests/068 b/tests/qemu-iotests/068 | ||
777 | index XXXXXXX..XXXXXXX 100755 | ||
778 | --- a/tests/qemu-iotests/068 | ||
779 | +++ b/tests/qemu-iotests/068 | ||
780 | @@ -XXX,XX +XXX,XX @@ esac | ||
781 | # Give qemu some time to boot before saving the VM state | ||
782 | bash -c 'sleep 1; echo -e "savevm 0\nquit"' |\ | ||
783 | $QEMU $platform_parm -nographic -monitor stdio -serial none -hda "$TEST_IMG" |\ | ||
784 | - _filter_qemu | ||
785 | + _filter_qemu | _filter_hmp | ||
786 | # Now try to continue from that VM state (this should just work) | ||
787 | echo quit |\ | ||
788 | $QEMU $platform_parm -nographic -monitor stdio -serial none -hda "$TEST_IMG" -loadvm 0 |\ | ||
789 | - _filter_qemu | ||
790 | + _filter_qemu | _filter_hmp | ||
791 | |||
792 | # success, all done | ||
793 | echo "*** done" | ||
794 | diff --git a/tests/qemu-iotests/068.out b/tests/qemu-iotests/068.out | ||
795 | index XXXXXXX..XXXXXXX 100644 | ||
796 | --- a/tests/qemu-iotests/068.out | ||
797 | +++ b/tests/qemu-iotests/068.out | ||
798 | @@ -XXX,XX +XXX,XX @@ QA output created by 068 | ||
799 | |||
800 | Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072 | ||
801 | QEMU X.Y.Z monitor - type 'help' for more information | ||
802 | -(qemu) s[K[Dsa[K[D[Dsav[K[D[D[Dsave[K[D[D[D[Dsavev[K[D[D[D[D[Dsavevm[K[D[D[D[D[D[Dsavevm [K[D[D[D[D[D[D[Dsavevm 0[K | ||
803 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
804 | +(qemu) savevm 0 | ||
805 | +(qemu) quit | ||
806 | QEMU X.Y.Z monitor - type 'help' for more information | ||
807 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
808 | +(qemu) quit | ||
809 | *** done | ||
810 | diff --git a/tests/qemu-iotests/130.out b/tests/qemu-iotests/130.out | ||
811 | index XXXXXXX..XXXXXXX 100644 | ||
812 | --- a/tests/qemu-iotests/130.out | ||
813 | +++ b/tests/qemu-iotests/130.out | ||
814 | @@ -XXX,XX +XXX,XX @@ virtual size: 64M (67108864 bytes) | ||
815 | === HMP commit === | ||
816 | |||
817 | QEMU X.Y.Z monitor - type 'help' for more information | ||
818 | -(qemu) c[K[Dco[K[D[Dcom[K[D[D[Dcomm[K[D[D[D[Dcommi[K[D[D[D[D[Dcommit[K[D[D[D[D[D[Dcommit [K[D[D[D[D[D[D[Dcommit t[K[D[D[D[D[D[D[D[Dcommit te[K[D[D[D[D[D[D[D[D[Dcommit tes[K[D[D[D[D[D[D[D[D[D[Dcommit test[K[D[D[D[D[D[D[D[D[D[D[Dcommit testd[K[D[D[D[D[D[D[D[D[D[D[D[Dcommit testdi[K[D[D[D[D[D[D[D[D[D[D[D[D[Dcommit testdis[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dcommit testdisk[K | ||
819 | +(qemu) commit testdisk | ||
820 | (qemu) | ||
821 | image: TEST_DIR/t.IMGFMT | ||
822 | file format: IMGFMT | ||
823 | virtual size: 64M (67108864 bytes) | ||
824 | Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.orig backing_fmt=raw | ||
825 | QEMU X.Y.Z monitor - type 'help' for more information | ||
826 | -(qemu) c[K[Dco[K[D[Dcom[K[D[D[Dcomm[K[D[D[D[Dcommi[K[D[D[D[D[Dcommit[K[D[D[D[D[D[Dcommit [K[D[D[D[D[D[D[Dcommit t[K[D[D[D[D[D[D[D[Dcommit te[K[D[D[D[D[D[D[D[D[Dcommit tes[K[D[D[D[D[D[D[D[D[D[Dcommit test[K[D[D[D[D[D[D[D[D[D[D[Dcommit testd[K[D[D[D[D[D[D[D[D[D[D[D[Dcommit testdi[K[D[D[D[D[D[D[D[D[D[D[D[D[Dcommit testdis[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dcommit testdisk[K | ||
827 | +(qemu) commit testdisk | ||
828 | (qemu) | ||
829 | image: TEST_DIR/t.IMGFMT | ||
830 | file format: IMGFMT | ||
831 | diff --git a/tests/qemu-iotests/142 b/tests/qemu-iotests/142 | ||
832 | index XXXXXXX..XXXXXXX 100755 | ||
833 | --- a/tests/qemu-iotests/142 | ||
834 | +++ b/tests/qemu-iotests/142 | ||
835 | @@ -XXX,XX +XXX,XX @@ function do_run_qemu() | ||
836 | |||
837 | function run_qemu() | ||
838 | { | ||
839 | - do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | ||
840 | + do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_hmp | ||
841 | } | ||
842 | |||
843 | size=128M | ||
844 | diff --git a/tests/qemu-iotests/142.out b/tests/qemu-iotests/142.out | ||
845 | index XXXXXXX..XXXXXXX 100644 | ||
846 | --- a/tests/qemu-iotests/142.out | ||
847 | +++ b/tests/qemu-iotests/142.out | ||
848 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/ | ||
849 | |||
850 | Testing: -drive file=TEST_DIR/t.qcow2,cache=none | ||
851 | QEMU X.Y.Z monitor - type 'help' for more information | ||
852 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
853 | +(qemu) quit | ||
854 | |||
855 | Testing: -drive file=TEST_DIR/t.qcow2,cache=directsync | ||
856 | QEMU X.Y.Z monitor - type 'help' for more information | ||
857 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
858 | +(qemu) quit | ||
859 | |||
860 | Testing: -drive file=TEST_DIR/t.qcow2,cache=writeback | ||
861 | QEMU X.Y.Z monitor - type 'help' for more information | ||
862 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
863 | +(qemu) quit | ||
864 | |||
865 | Testing: -drive file=TEST_DIR/t.qcow2,cache=writethrough | ||
866 | QEMU X.Y.Z monitor - type 'help' for more information | ||
867 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
868 | +(qemu) quit | ||
869 | |||
870 | Testing: -drive file=TEST_DIR/t.qcow2,cache=unsafe | ||
871 | QEMU X.Y.Z monitor - type 'help' for more information | ||
872 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
873 | +(qemu) quit | ||
874 | |||
875 | Testing: -drive file=TEST_DIR/t.qcow2,cache=invalid_value | ||
876 | QEMU_PROG: -drive file=TEST_DIR/t.qcow2,cache=invalid_value: invalid cache option | ||
877 | diff --git a/tests/qemu-iotests/145 b/tests/qemu-iotests/145 | ||
878 | index XXXXXXX..XXXXXXX 100755 | ||
879 | --- a/tests/qemu-iotests/145 | ||
880 | +++ b/tests/qemu-iotests/145 | ||
881 | @@ -XXX,XX +XXX,XX @@ _supported_proto generic | ||
882 | _supported_os Linux | ||
883 | |||
884 | _make_test_img 1M | ||
885 | -echo quit | $QEMU -nographic -hda "$TEST_IMG" -incoming 'exec:true' -snapshot -serial none -monitor stdio | _filter_qemu | ||
886 | +echo quit | $QEMU -nographic -hda "$TEST_IMG" -incoming 'exec:true' -snapshot -serial none -monitor stdio | | ||
887 | + _filter_qemu | _filter_hmp | ||
888 | |||
889 | # success, all done | ||
890 | echo "*** done" | ||
891 | diff --git a/tests/qemu-iotests/145.out b/tests/qemu-iotests/145.out | ||
892 | index XXXXXXX..XXXXXXX 100644 | ||
893 | --- a/tests/qemu-iotests/145.out | ||
894 | +++ b/tests/qemu-iotests/145.out | ||
895 | @@ -XXX,XX +XXX,XX @@ | ||
896 | QA output created by 145 | ||
897 | Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 | ||
898 | QEMU X.Y.Z monitor - type 'help' for more information | ||
899 | -(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K | ||
900 | +(qemu) quit | ||
901 | *** done | ||
902 | diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter | ||
903 | index XXXXXXX..XXXXXXX 100644 | ||
904 | --- a/tests/qemu-iotests/common.filter | ||
905 | +++ b/tests/qemu-iotests/common.filter | ||
906 | @@ -XXX,XX +XXX,XX @@ _filter_qmp() | ||
907 | -e ' QMP_VERSION' | ||
908 | } | ||
909 | |||
910 | +# readline makes HMP command strings so long that git complains | ||
911 | +_filter_hmp() | ||
912 | +{ | ||
913 | + sed -e $'s/^\\((qemu) \\)\\?.*\e\\[D/\\1/g' \ | ||
914 | + -e $'s/\e\\[K//g' | ||
915 | +} | ||
916 | + | ||
917 | # replace block job offset | ||
918 | _filter_block_job_offset() | ||
919 | { | ||
920 | diff --git a/tests/qemu-iotests/common.qemu b/tests/qemu-iotests/common.qemu | ||
921 | index XXXXXXX..XXXXXXX 100644 | ||
922 | --- a/tests/qemu-iotests/common.qemu | ||
923 | +++ b/tests/qemu-iotests/common.qemu | ||
924 | @@ -XXX,XX +XXX,XX @@ function _timed_wait_for() | ||
925 | do | ||
926 | if [ -z "${silent}" ]; then | ||
927 | echo "${resp}" | _filter_testdir | _filter_qemu \ | ||
928 | - | _filter_qemu_io | _filter_qmp | ||
929 | + | _filter_qemu_io | _filter_qmp | _filter_hmp | ||
930 | fi | ||
931 | grep -q "${*}" < <(echo ${resp}) | ||
932 | if [ $? -eq 0 ]; then | ||
933 | @@ -XXX,XX +XXX,XX @@ function _cleanup_qemu() | ||
934 | |||
935 | if [ -n "${wait}" ]; then | ||
936 | cat <&${QEMU_OUT[$i]} | _filter_testdir | _filter_qemu \ | ||
937 | - | _filter_qemu_io | _filter_qmp | ||
938 | + | _filter_qemu_io | _filter_qmp | _filter_hmp | ||
939 | fi | ||
940 | rm -f "${QEMU_FIFO_IN}_${i}" "${QEMU_FIFO_OUT}_${i}" | ||
941 | eval "exec ${QEMU_IN[$i]}<&-" # close file descriptors | ||
942 | -- | 91 | -- |
943 | 1.8.3.1 | 92 | 2.29.2 |
944 | 93 | ||
945 | 94 | diff view generated by jsdifflib |
1 | From: Max Reitz <mreitz@redhat.com> | 1 | From: Max Reitz <mreitz@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | The create and convert subcommands have shorthands to set the | 3 | This generally does not work on non-file protocols. It is better to |
4 | backing_file and, in the case of create, the backing_fmt options for the | 4 | create the image with the final name from the start, and most tests do |
5 | new image. However, they have not been documented so far, which is | 5 | this already. Let 046 follow suit. |
6 | remedied by this patch. | ||
7 | 6 | ||
8 | Reported-by: Eric Blake <eblake@redhat.com> | ||
9 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 7 | Signed-off-by: Max Reitz <mreitz@redhat.com> |
10 | Reviewed-by: Eric Blake <eblake@redhat.com> | 8 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> |
9 | Message-Id: <20201027190600.192171-11-mreitz@redhat.com> | ||
11 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 10 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
12 | --- | 11 | --- |
13 | qemu-img-cmds.hx | 8 ++++---- | 12 | tests/qemu-iotests/046 | 5 +++-- |
14 | qemu-img.texi | 4 ++-- | 13 | tests/qemu-iotests/046.out | 2 +- |
15 | 2 files changed, 6 insertions(+), 6 deletions(-) | 14 | 2 files changed, 4 insertions(+), 3 deletions(-) |
16 | 15 | ||
17 | diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx | 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 | ||
18 | index XXXXXXX..XXXXXXX 100644 | 40 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/qemu-img-cmds.hx | 41 | --- a/tests/qemu-iotests/046.out |
20 | +++ b/qemu-img-cmds.hx | 42 | +++ b/tests/qemu-iotests/046.out |
21 | @@ -XXX,XX +XXX,XX @@ STEXI | 43 | @@ -XXX,XX +XXX,XX @@ |
22 | ETEXI | 44 | QA output created by 046 |
23 | 45 | ||
24 | DEF("create", img_create, | 46 | == creating backing file for COW tests == |
25 | - "create [-q] [--object objectdef] [-f fmt] [-o options] filename [size]") | 47 | -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 |
26 | + "create [-q] [--object objectdef] [-f fmt] [-b backing_file] [-F backing_fmt] [-o options] filename [size]") | 48 | +Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728 |
27 | STEXI | 49 | wrote 65536/65536 bytes at offset 0 |
28 | -@item create [--object @var{objectdef}] [-q] [-f @var{fmt}] [-o @var{options}] @var{filename} [@var{size}] | 50 | 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) |
29 | +@item create [--object @var{objectdef}] [-q] [-f @var{fmt}] [-b @var{backing_file}] [-F @var{backing_fmt}] [-o @var{options}] @var{filename} [@var{size}] | 51 | wrote 65536/65536 bytes at offset 65536 |
30 | ETEXI | ||
31 | |||
32 | DEF("commit", img_commit, | ||
33 | @@ -XXX,XX +XXX,XX @@ STEXI | ||
34 | ETEXI | ||
35 | |||
36 | DEF("convert", img_convert, | ||
37 | - "convert [--object objectdef] [--image-opts] [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-T src_cache] [-O output_fmt] [-o options] [-s snapshot_id_or_name] [-l snapshot_param] [-S sparse_size] [-m num_coroutines] [-W] filename [filename2 [...]] output_filename") | ||
38 | + "convert [--object objectdef] [--image-opts] [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-T src_cache] [-O output_fmt] [-B backing_file] [-o options] [-s snapshot_id_or_name] [-l snapshot_param] [-S sparse_size] [-m num_coroutines] [-W] filename [filename2 [...]] output_filename") | ||
39 | STEXI | ||
40 | -@item convert [--object @var{objectdef}] [--image-opts] [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-S @var{sparse_size}] [-m @var{num_coroutines}] [-W] @var{filename} [@var{filename2} [...]] @var{output_filename} | ||
41 | +@item convert [--object @var{objectdef}] [--image-opts] [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-B @var{backing_file}] [-o @var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-S @var{sparse_size}] [-m @var{num_coroutines}] [-W] @var{filename} [@var{filename2} [...]] @var{output_filename} | ||
42 | ETEXI | ||
43 | |||
44 | DEF("dd", img_dd, | ||
45 | diff --git a/qemu-img.texi b/qemu-img.texi | ||
46 | index XXXXXXX..XXXXXXX 100644 | ||
47 | --- a/qemu-img.texi | ||
48 | +++ b/qemu-img.texi | ||
49 | @@ -XXX,XX +XXX,XX @@ If @code{-r} is specified, exit codes representing the image state refer to the | ||
50 | state after (the attempt at) repairing it. That is, a successful @code{-r all} | ||
51 | will yield the exit code 0, independently of the image state before. | ||
52 | |||
53 | -@item create [-f @var{fmt}] [-o @var{options}] @var{filename} [@var{size}] | ||
54 | +@item create [-f @var{fmt}] [-b @var{backing_file}] [-F @var{backing_fmt}] [-o @var{options}] @var{filename} [@var{size}] | ||
55 | |||
56 | Create the new disk image @var{filename} of size @var{size} and format | ||
57 | @var{fmt}. Depending on the file format, you can add one or more @var{options} | ||
58 | @@ -XXX,XX +XXX,XX @@ Error on reading data | ||
59 | |||
60 | @end table | ||
61 | |||
62 | -@item convert [-c] [-p] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-m @var{num_coroutines}] [-W] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename} | ||
63 | +@item convert [-c] [-p] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-B @var{backing_file}] [-o @var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-m @var{num_coroutines}] [-W] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename} | ||
64 | |||
65 | Convert the disk image @var{filename} or a snapshot @var{snapshot_param}(@var{snapshot_id_or_name} is deprecated) | ||
66 | to disk image @var{output_filename} using format @var{output_fmt}. It can be optionally compressed (@code{-c} | ||
67 | -- | 52 | -- |
68 | 1.8.3.1 | 53 | 2.29.2 |
69 | 54 | ||
70 | 55 | diff view generated by jsdifflib |
1 | From: Max Reitz <mreitz@redhat.com> | 1 | From: Max Reitz <mreitz@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | After storing the creation options for the new image into @opts, we | 3 | Avoid creating images with custom filenames in $TEST_DIR, because |
4 | fetch some things for our own information, like the backing file name, | 4 | non-file protocols may want to keep $TEST_IMG (and all other test |
5 | or whether to use encryption or preallocation. | 5 | images) in some other directory. |
6 | |||
7 | With the -n parameter, there will not be any creation options; this is | ||
8 | not too bad because this just means that querying a NULL @opts will | ||
9 | always return the default value. | ||
10 | |||
11 | However, we also use @opts for the --object options. Therefore, @opts is | ||
12 | not necessarily NULL if -n was specified; instead, it may contain those | ||
13 | options. In practice, this probably does not cause any problems because | ||
14 | there most likely is no object that supports any of the parameters we | ||
15 | query here, but this is neither something we should rely on nor does | ||
16 | this variable reuse make the code very nice to read. | ||
17 | |||
18 | Therefore, just use a separate variable for the --object options. | ||
19 | 6 | ||
20 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 7 | Signed-off-by: Max Reitz <mreitz@redhat.com> |
21 | Reviewed-by: Eric Blake <eblake@redhat.com> | 8 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> |
9 | Message-Id: <20201027190600.192171-12-mreitz@redhat.com> | ||
22 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 10 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
23 | --- | 11 | --- |
24 | qemu-img.c | 10 ++++++---- | 12 | tests/qemu-iotests/200 | 3 +-- |
25 | 1 file changed, 6 insertions(+), 4 deletions(-) | 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(-) | ||
26 | 17 | ||
27 | diff --git a/qemu-img.c b/qemu-img.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 | ||
28 | index XXXXXXX..XXXXXXX 100644 | 33 | index XXXXXXX..XXXXXXX 100644 |
29 | --- a/qemu-img.c | 34 | --- a/tests/qemu-iotests/200.out |
30 | +++ b/qemu-img.c | 35 | +++ b/tests/qemu-iotests/200.out |
31 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | 36 | @@ -XXX,XX +XXX,XX @@ |
32 | case 'W': | 37 | QA output created by 200 |
33 | s.wr_in_order = false; | 38 | -Formatting 'TEST_DIR/backing.img', fmt=IMGFMT size=536870912 |
34 | break; | 39 | -Formatting 'TEST_DIR/test.img', fmt=IMGFMT size=536870912 backing_file=TEST_DIR/backing.img backing_fmt=IMGFMT |
35 | - case OPTION_OBJECT: | 40 | +Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=536870912 |
36 | - opts = qemu_opts_parse_noisily(&qemu_object_opts, | 41 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=536870912 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=IMGFMT |
37 | - optarg, true); | 42 | wrote 314572800/314572800 bytes at offset 512 |
38 | - if (!opts) { | 43 | 300 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) |
39 | + case OPTION_OBJECT: { | 44 | |
40 | + QemuOpts *object_opts; | 45 | diff --git a/tests/qemu-iotests/229 b/tests/qemu-iotests/229 |
41 | + object_opts = qemu_opts_parse_noisily(&qemu_object_opts, | 46 | index XXXXXXX..XXXXXXX 100755 |
42 | + optarg, true); | 47 | --- a/tests/qemu-iotests/229 |
43 | + if (!object_opts) { | 48 | +++ b/tests/qemu-iotests/229 |
44 | goto fail_getopt; | 49 | @@ -XXX,XX +XXX,XX @@ _supported_os Linux |
45 | } | 50 | _unsupported_imgopts data_file |
46 | break; | 51 | |
47 | + } | 52 | |
48 | case OPTION_IMAGE_OPTS: | 53 | -DEST_IMG="$TEST_DIR/d.$IMGFMT" |
49 | image_opts = true; | 54 | -TEST_IMG="$TEST_DIR/b.$IMGFMT" |
50 | break; | 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": {}} | ||
51 | -- | 81 | -- |
52 | 1.8.3.1 | 82 | 2.29.2 |
53 | 83 | ||
54 | 84 | diff view generated by jsdifflib |
1 | From: John Snow <jsnow@redhat.com> | 1 | From: Max Reitz <mreitz@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | If you are running out-of-tree, the -x option to exclude | 3 | If the test environment has some other child processes running (like a |
4 | a certain iotest is broken. | 4 | storage daemon that provides a FUSE export), then "wait" will never |
5 | finish. Use wait=yes _cleanup_qemu instead. | ||
5 | 6 | ||
6 | Replace porcelain usage of ls with a sturdier awk command. | 7 | (We need to discard the output so there is no change to the reference |
8 | output.) | ||
7 | 9 | ||
8 | Reviewed-by: Fam Zheng <famz@redhat.com> | ||
9 | Signed-off-by: John Snow <jsnow@redhat.com> | ||
10 | Message-id: 20170427205100.9505-3-jsnow@redhat.com | ||
11 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
12 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 10 | Signed-off-by: Max Reitz <mreitz@redhat.com> |
11 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> | ||
12 | Message-Id: <20201027190600.192171-13-mreitz@redhat.com> | ||
13 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
13 | --- | 14 | --- |
14 | tests/qemu-iotests/common | 3 ++- | 15 | tests/qemu-iotests/091 | 3 ++- |
15 | 1 file changed, 2 insertions(+), 1 deletion(-) | 16 | 1 file changed, 2 insertions(+), 1 deletion(-) |
16 | 17 | ||
17 | diff --git a/tests/qemu-iotests/common b/tests/qemu-iotests/common | 18 | diff --git a/tests/qemu-iotests/091 b/tests/qemu-iotests/091 |
18 | index XXXXXXX..XXXXXXX 100644 | 19 | index XXXXXXX..XXXXXXX 100755 |
19 | --- a/tests/qemu-iotests/common | 20 | --- a/tests/qemu-iotests/091 |
20 | +++ b/tests/qemu-iotests/common | 21 | +++ b/tests/qemu-iotests/091 |
21 | @@ -XXX,XX +XXX,XX @@ s/ .*//p | 22 | @@ -XXX,XX +XXX,XX @@ _send_qemu_cmd $h2 'qemu-io disk flush' "(qemu)" |
22 | elif $xgroup | 23 | _send_qemu_cmd $h2 'quit' "" |
23 | then | 24 | _send_qemu_cmd $h1 'quit' "" |
24 | # arg after -x | 25 | |
25 | - [ ! -s $tmp.list ] && ls [0-9][0-9][0-9] [0-9][0-9][0-9][0-9] >$tmp.list 2>/dev/null | 26 | -wait |
26 | + # Populate $tmp.list with all tests | 27 | +wait=yes _cleanup_qemu >/dev/null |
27 | + awk '/^[0-9]{3,}/ {print $1}' "${source_iotests}/group" > $tmp.list 2>/dev/null | 28 | + |
28 | group_list=`sed -n <"$source_iotests/group" -e 's/$/ /' -e "/^[0-9][0-9][0-9].* $r /"'{ | 29 | echo "Check image pattern" |
29 | s/ .*//p | 30 | ${QEMU_IO} -c "read -P 0x22 0 4M" "${TEST_IMG}" | _filter_testdir | _filter_qemu_io |
30 | }'` | 31 | |
31 | -- | 32 | -- |
32 | 1.8.3.1 | 33 | 2.29.2 |
33 | 34 | ||
34 | 35 | diff view generated by jsdifflib |
1 | From: Thomas Huth <thuth@redhat.com> | 1 | From: Max Reitz <mreitz@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | If the user needs to specify the disk geometry, the corresponding | 3 | Most Python tests are restricted to the file protocol (without |
4 | parameters of the "-device ide-hd" option should be used instead. | 4 | explicitly saying so), but these are the ones that would break |
5 | "-hdachs" is considered as deprecated and might be removed soon. | 5 | ./check -fuse -qcow2. |
6 | 6 | ||
7 | Signed-off-by: Thomas Huth <thuth@redhat.com> | 7 | Signed-off-by: Max Reitz <mreitz@redhat.com> |
8 | Reviewed-by: Eric Blake <eblake@redhat.com> | 8 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> |
9 | Message-Id: <20201027190600.192171-14-mreitz@redhat.com> | ||
9 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 10 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
10 | --- | 11 | --- |
11 | qemu-options.hx | 4 ++-- | 12 | tests/qemu-iotests/206 | 3 ++- |
12 | vl.c | 2 ++ | 13 | tests/qemu-iotests/242 | 3 ++- |
13 | 2 files changed, 4 insertions(+), 2 deletions(-) | 14 | 2 files changed, 4 insertions(+), 2 deletions(-) |
14 | 15 | ||
15 | diff --git a/qemu-options.hx b/qemu-options.hx | 16 | diff --git a/tests/qemu-iotests/206 b/tests/qemu-iotests/206 |
16 | index XXXXXXX..XXXXXXX 100644 | 17 | index XXXXXXX..XXXXXXX 100755 |
17 | --- a/qemu-options.hx | 18 | --- a/tests/qemu-iotests/206 |
18 | +++ b/qemu-options.hx | 19 | +++ b/tests/qemu-iotests/206 |
19 | @@ -XXX,XX +XXX,XX @@ STEXI | 20 | @@ -XXX,XX +XXX,XX @@ |
20 | Force hard disk 0 physical geometry (1 <= @var{c} <= 16383, 1 <= | 21 | import iotests |
21 | @var{h} <= 16, 1 <= @var{s} <= 63) and optionally force the BIOS | 22 | from iotests import imgfmt |
22 | translation mode (@var{t}=none, lba or auto). Usually QEMU can guess | 23 | |
23 | -all those parameters. This option is useful for old MS-DOS disk | 24 | -iotests.script_initialize(supported_fmts=['qcow2']) |
24 | -images. | 25 | +iotests.script_initialize(supported_fmts=['qcow2'], |
25 | +all those parameters. This option is deprecated, please use | 26 | + supported_protocols=['file']) |
26 | +@code{-device ide-hd,cyls=c,heads=h,secs=s,...} instead. | 27 | iotests.verify_working_luks() |
27 | ETEXI | 28 | |
28 | 29 | with iotests.FilePath('t.qcow2') as disk_path, \ | |
29 | DEF("fsdev", HAS_ARG, QEMU_OPTION_fsdev, | 30 | diff --git a/tests/qemu-iotests/242 b/tests/qemu-iotests/242 |
30 | diff --git a/vl.c b/vl.c | 31 | index XXXXXXX..XXXXXXX 100755 |
31 | index XXXXXXX..XXXXXXX 100644 | 32 | --- a/tests/qemu-iotests/242 |
32 | --- a/vl.c | 33 | +++ b/tests/qemu-iotests/242 |
33 | +++ b/vl.c | 34 | @@ -XXX,XX +XXX,XX @@ import struct |
34 | @@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv, char **envp) | 35 | from iotests import qemu_img_create, qemu_io, qemu_img_pipe, \ |
35 | } | 36 | file_path, img_info_log, log, filter_qemu_io |
36 | } | 37 | |
37 | } | 38 | -iotests.script_initialize(supported_fmts=['qcow2']) |
38 | + error_report("'-hdachs' is deprecated, please use '-device" | 39 | +iotests.script_initialize(supported_fmts=['qcow2'], |
39 | + " ide-hd,cyls=c,heads=h,secs=s,...' instead"); | 40 | + supported_protocols=['file']) |
40 | break; | 41 | |
41 | case QEMU_OPTION_numa: | 42 | disk = file_path('disk') |
42 | opts = qemu_opts_parse_noisily(qemu_find_opts("numa"), | 43 | chunk = 256 * 1024 |
43 | -- | 44 | -- |
44 | 1.8.3.1 | 45 | 2.29.2 |
45 | 46 | ||
46 | 47 | 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 reason for the qemu-nbd server used for tests not to accept | 3 | When most iotests want to create a test image that is named differently |
4 | an arbitrary number of clients. In fact, test 181 will require it to | 4 | from the default $TEST_IMG, they do something like this: |
5 | accept two clients at the same time (and thus it fails before this | ||
6 | patch). | ||
7 | 5 | ||
8 | This patch updates common.rc to launch qemu-nbd with -e 42 which should | 6 | TEST_IMG="$TEST_IMG.base" _make_test_img $options |
9 | be enough for all of our current and future tests. | 7 | |
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. | ||
12 | |||
13 | There are two ways we can fix this: First, we could make all tests | ||
14 | adjust not only TEST_IMG, but also TEST_IMG_FILE if that is present | ||
15 | (e.g. with something like _set_test_img_suffix $suffix that would affect | ||
16 | not only TEST_IMG but also TEST_IMG_FILE, if necessary). This is a | ||
17 | pretty clean solution, and this is maybe what we should have done from | ||
18 | the start. | ||
19 | |||
20 | But it would also require changes to most existing bash tests. So the | ||
21 | alternative is this: Let _make_test_img see whether $TEST_IMG_FILE still | ||
22 | points to the original value. If so, it is possible that the caller has | ||
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. | ||
10 | 31 | ||
11 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 32 | Signed-off-by: Max Reitz <mreitz@redhat.com> |
12 | Reviewed-by: Eric Blake <eblake@redhat.com> | 33 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> |
34 | Message-Id: <20201027190600.192171-15-mreitz@redhat.com> | ||
13 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 35 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
14 | --- | 36 | --- |
15 | tests/qemu-iotests/common.rc | 4 +++- | 37 | tests/qemu-iotests/common.rc | 40 +++++++++++++++++++++++++++++++++--- |
16 | 1 file changed, 3 insertions(+), 1 deletion(-) | 38 | 1 file changed, 37 insertions(+), 3 deletions(-) |
17 | 39 | ||
18 | diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc | 40 | diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc |
19 | index XXXXXXX..XXXXXXX 100644 | 41 | index XXXXXXX..XXXXXXX 100644 |
20 | --- a/tests/qemu-iotests/common.rc | 42 | --- a/tests/qemu-iotests/common.rc |
21 | +++ b/tests/qemu-iotests/common.rc | 43 | +++ b/tests/qemu-iotests/common.rc |
44 | @@ -XXX,XX +XXX,XX @@ else | ||
45 | TEST_IMG=$IMGPROTO:$TEST_DIR/t.$IMGFMT | ||
46 | fi | ||
47 | fi | ||
48 | +ORIG_TEST_IMG_FILE=$TEST_IMG_FILE | ||
49 | ORIG_TEST_IMG="$TEST_IMG" | ||
50 | |||
51 | if [ -z "$TEST_DIR" ]; then | ||
52 | @@ -XXX,XX +XXX,XX @@ _get_data_file() | ||
53 | | sed -e "s#\\\$TEST_IMG#$1#" | ||
54 | } | ||
55 | |||
56 | +# Translate a $TEST_IMG to its corresponding $TEST_IMG_FILE for | ||
57 | +# different protocols | ||
58 | +_test_img_to_test_img_file() | ||
59 | +{ | ||
60 | + case "$IMGPROTO" in | ||
61 | + file) | ||
62 | + echo "$1" | ||
63 | + ;; | ||
64 | + | ||
65 | + nfs) | ||
66 | + echo "$1" | sed -e "s#nfs://127.0.0.1##" | ||
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() | ||
81 | { | ||
82 | # extra qemu-img options can be added by tests | ||
22 | @@ -XXX,XX +XXX,XX @@ _make_test_img() | 83 | @@ -XXX,XX +XXX,XX @@ _make_test_img() |
23 | 84 | local opts_param=false | |
24 | # Start an NBD server on the image file, which is what we'll be talking to | 85 | local misc_params=() |
25 | if [ $IMGPROTO = "nbd" ]; then | 86 | |
26 | - eval "$QEMU_NBD -v -t -b 127.0.0.1 -p 10810 -f $IMGFMT $TEST_IMG_FILE >/dev/null &" | 87 | - if [ -n "$TEST_IMG_FILE" ]; then |
27 | + # Pass a sufficiently high number to -e that should be enough for all | 88 | - img_name=$TEST_IMG_FILE |
28 | + # tests | 89 | - else |
29 | + eval "$QEMU_NBD -v -t -b 127.0.0.1 -p 10810 -f $IMGFMT -e 42 $TEST_IMG_FILE >/dev/null &" | 90 | + if [ -z "$TEST_IMG_FILE" ]; then |
30 | sleep 1 # FIXME: qemu-nbd needs to be listening before we continue | 91 | img_name=$TEST_IMG |
92 | + elif [ "$IMGOPTSSYNTAX" != "true" -a \ | ||
93 | + "$TEST_IMG_FILE" = "$ORIG_TEST_IMG_FILE" ]; then | ||
94 | + # Handle cases of tests only updating TEST_IMG, but not TEST_IMG_FILE | ||
95 | + img_name=$(_test_img_to_test_img_file "$TEST_IMG") | ||
96 | + if [ "$?" != 0 ]; then | ||
97 | + img_name=$TEST_IMG_FILE | ||
98 | + fi | ||
99 | + else | ||
100 | + # $TEST_IMG_FILE is not the default value, so it definitely has been | ||
101 | + # modified by the test | ||
102 | + img_name=$TEST_IMG_FILE | ||
31 | fi | 103 | fi |
32 | 104 | ||
105 | if [ -n "$IMGOPTS" ]; then | ||
33 | -- | 106 | -- |
34 | 1.8.3.1 | 107 | 2.29.2 |
35 | 108 | ||
36 | 109 | diff view generated by jsdifflib |
1 | From: Max Reitz <mreitz@redhat.com> | 1 | From: Max Reitz <mreitz@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | This patch makes vhdx_create() always set errp in case of an error. It | 3 | 287 creates an image in a subshell (thanks to the pipe) to see whether |
4 | also adds errp parameters to vhdx_create_bat() and | 4 | that is possible with compression_type=zstd. If _make_test_img were to |
5 | vhdx_create_new_region_table() so we can pass on the error object | 5 | modify any global state, this global state would then be lost before we |
6 | generated by blk_truncate() as of a future commit. | 6 | could cleanup the image. |
7 | |||
8 | When using FUSE as the test protocol, this global state is important, so | ||
9 | clean up the image before the state is lost. | ||
7 | 10 | ||
8 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 11 | Signed-off-by: Max Reitz <mreitz@redhat.com> |
9 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> | 12 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> |
10 | Message-id: 20170328205129.15138-2-mreitz@redhat.com | 13 | Message-Id: <20201027190600.192171-16-mreitz@redhat.com> |
11 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | 14 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
12 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
13 | --- | 15 | --- |
14 | block/vhdx.c | 23 +++++++++++++++++++---- | 16 | tests/qemu-iotests/287 | 4 ++-- |
15 | 1 file changed, 19 insertions(+), 4 deletions(-) | 17 | 1 file changed, 2 insertions(+), 2 deletions(-) |
16 | 18 | ||
17 | diff --git a/block/vhdx.c b/block/vhdx.c | 19 | diff --git a/tests/qemu-iotests/287 b/tests/qemu-iotests/287 |
18 | index XXXXXXX..XXXXXXX 100644 | 20 | index XXXXXXX..XXXXXXX 100755 |
19 | --- a/block/vhdx.c | 21 | --- a/tests/qemu-iotests/287 |
20 | +++ b/block/vhdx.c | 22 | +++ b/tests/qemu-iotests/287 |
21 | @@ -XXX,XX +XXX,XX @@ exit: | 23 | @@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15 |
22 | static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s, | 24 | CLUSTER_SIZE=65536 |
23 | uint64_t image_size, VHDXImageType type, | 25 | |
24 | bool use_zero_blocks, uint64_t file_offset, | 26 | # Check if we can run this test. |
25 | - uint32_t length) | 27 | -if IMGOPTS='compression_type=zstd' _make_test_img 64M | |
26 | + uint32_t length, Error **errp) | 28 | - grep "Invalid parameter 'zstd'"; then |
27 | { | 29 | +output=$(_make_test_img -o 'compression_type=zstd' 64M; _cleanup_test_img) |
28 | int ret = 0; | 30 | +if echo "$output" | grep -q "Invalid parameter 'zstd'"; then |
29 | uint64_t data_file_offset; | 31 | _notrun "ZSTD is disabled" |
30 | @@ -XXX,XX +XXX,XX @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s, | 32 | fi |
31 | * is the furthest thing we have written yet */ | ||
32 | ret = blk_truncate(blk, data_file_offset); | ||
33 | if (ret < 0) { | ||
34 | + error_setg_errno(errp, -ret, | ||
35 | + "Failed to resize the underlying file"); | ||
36 | goto exit; | ||
37 | } | ||
38 | } else if (type == VHDX_TYPE_FIXED) { | ||
39 | ret = blk_truncate(blk, data_file_offset + image_size); | ||
40 | if (ret < 0) { | ||
41 | + error_setg_errno(errp, -ret, | ||
42 | + "Failed to resize the underlying file"); | ||
43 | goto exit; | ||
44 | } | ||
45 | } else { | ||
46 | + error_setg(errp, "Unsupported image type"); | ||
47 | ret = -ENOTSUP; | ||
48 | goto exit; | ||
49 | } | ||
50 | @@ -XXX,XX +XXX,XX @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s, | ||
51 | /* for a fixed file, the default BAT entry is not zero */ | ||
52 | s->bat = g_try_malloc0(length); | ||
53 | if (length && s->bat == NULL) { | ||
54 | + error_setg(errp, "Failed to allocate memory for the BAT"); | ||
55 | ret = -ENOMEM; | ||
56 | goto exit; | ||
57 | } | ||
58 | @@ -XXX,XX +XXX,XX @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s, | ||
59 | } | ||
60 | ret = blk_pwrite(blk, file_offset, s->bat, length, 0); | ||
61 | if (ret < 0) { | ||
62 | + error_setg_errno(errp, -ret, "Failed to write the BAT"); | ||
63 | goto exit; | ||
64 | } | ||
65 | } | ||
66 | @@ -XXX,XX +XXX,XX @@ static int vhdx_create_new_region_table(BlockBackend *blk, | ||
67 | uint32_t log_size, | ||
68 | bool use_zero_blocks, | ||
69 | VHDXImageType type, | ||
70 | - uint64_t *metadata_offset) | ||
71 | + uint64_t *metadata_offset, | ||
72 | + Error **errp) | ||
73 | { | ||
74 | int ret = 0; | ||
75 | uint32_t offset = 0; | ||
76 | @@ -XXX,XX +XXX,XX @@ static int vhdx_create_new_region_table(BlockBackend *blk, | ||
77 | /* The region table gives us the data we need to create the BAT, | ||
78 | * so do that now */ | ||
79 | ret = vhdx_create_bat(blk, s, image_size, type, use_zero_blocks, | ||
80 | - bat_file_offset, bat_length); | ||
81 | + bat_file_offset, bat_length, errp); | ||
82 | if (ret < 0) { | ||
83 | goto exit; | ||
84 | } | ||
85 | @@ -XXX,XX +XXX,XX @@ static int vhdx_create_new_region_table(BlockBackend *blk, | ||
86 | ret = blk_pwrite(blk, VHDX_REGION_TABLE_OFFSET, buffer, | ||
87 | VHDX_HEADER_BLOCK_SIZE, 0); | ||
88 | if (ret < 0) { | ||
89 | + error_setg_errno(errp, -ret, "Failed to write first region table"); | ||
90 | goto exit; | ||
91 | } | ||
92 | |||
93 | ret = blk_pwrite(blk, VHDX_REGION_TABLE2_OFFSET, buffer, | ||
94 | VHDX_HEADER_BLOCK_SIZE, 0); | ||
95 | if (ret < 0) { | ||
96 | + error_setg_errno(errp, -ret, "Failed to write second region table"); | ||
97 | goto exit; | ||
98 | } | ||
99 | |||
100 | @@ -XXX,XX +XXX,XX @@ static int vhdx_create(const char *filename, QemuOpts *opts, Error **errp) | ||
101 | ret = -ENOTSUP; | ||
102 | goto exit; | ||
103 | } else { | ||
104 | + error_setg(errp, "Invalid subformat '%s'", type); | ||
105 | ret = -EINVAL; | ||
106 | goto exit; | ||
107 | } | ||
108 | @@ -XXX,XX +XXX,XX @@ static int vhdx_create(const char *filename, QemuOpts *opts, Error **errp) | ||
109 | ret = blk_pwrite(blk, VHDX_FILE_ID_OFFSET, &signature, sizeof(signature), | ||
110 | 0); | ||
111 | if (ret < 0) { | ||
112 | + error_setg_errno(errp, -ret, "Failed to write file signature"); | ||
113 | goto delete_and_exit; | ||
114 | } | ||
115 | if (creator) { | ||
116 | ret = blk_pwrite(blk, VHDX_FILE_ID_OFFSET + sizeof(signature), | ||
117 | creator, creator_items * sizeof(gunichar2), 0); | ||
118 | if (ret < 0) { | ||
119 | + error_setg_errno(errp, -ret, "Failed to write creator field"); | ||
120 | goto delete_and_exit; | ||
121 | } | ||
122 | } | ||
123 | @@ -XXX,XX +XXX,XX @@ static int vhdx_create(const char *filename, QemuOpts *opts, Error **errp) | ||
124 | /* Creates (B),(C) */ | ||
125 | ret = vhdx_create_new_headers(blk, image_size, log_size); | ||
126 | if (ret < 0) { | ||
127 | + error_setg_errno(errp, -ret, "Failed to write image headers"); | ||
128 | goto delete_and_exit; | ||
129 | } | ||
130 | |||
131 | /* Creates (D),(E),(G) explicitly. (F) created as by-product */ | ||
132 | ret = vhdx_create_new_region_table(blk, image_size, block_size, 512, | ||
133 | log_size, use_zero_blocks, image_type, | ||
134 | - &metadata_offset); | ||
135 | + &metadata_offset, errp); | ||
136 | if (ret < 0) { | ||
137 | goto delete_and_exit; | ||
138 | } | ||
139 | @@ -XXX,XX +XXX,XX @@ static int vhdx_create(const char *filename, QemuOpts *opts, Error **errp) | ||
140 | ret = vhdx_create_new_metadata(blk, image_size, block_size, 512, | ||
141 | metadata_offset, image_type); | ||
142 | if (ret < 0) { | ||
143 | + error_setg_errno(errp, -ret, "Failed to initialize metadata"); | ||
144 | goto delete_and_exit; | ||
145 | } | ||
146 | 33 | ||
147 | -- | 34 | -- |
148 | 1.8.3.1 | 35 | 2.29.2 |
149 | 36 | ||
150 | 37 | diff view generated by jsdifflib |
1 | From: Max Reitz <mreitz@redhat.com> | 1 | From: Max Reitz <mreitz@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | Reproducer: | 3 | Otherwise, exports and block devices are not properly shut down and |
4 | $ ./qemu-img info '' | 4 | closed, unless the users explicitly issues blockdev-del and |
5 | qemu-img: ./block.c:1008: bdrv_open_driver: Assertion | 5 | block-export-del commands for each of them. |
6 | `!drv->bdrv_needs_filename || bs->filename[0]' failed. | ||
7 | [1] 26105 abort (core dumped) ./qemu-img info '' | ||
8 | 6 | ||
9 | This patch fixes this to be: | ||
10 | $ ./qemu-img info '' | ||
11 | qemu-img: Could not open '': The 'file' block driver requires a file | ||
12 | name | ||
13 | |||
14 | Cc: qemu-stable <qemu-stable@nongnu.org> | ||
15 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 7 | Signed-off-by: Max Reitz <mreitz@redhat.com> |
16 | Reviewed-by: Eric Blake <eblake@redhat.com> | 8 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> |
17 | Reviewed-by: Fam Zheng <famz@redhat.com> | 9 | Message-Id: <20201027190600.192171-17-mreitz@redhat.com> |
18 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | ||
19 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 10 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
20 | --- | 11 | --- |
21 | block.c | 2 +- | 12 | storage-daemon/qemu-storage-daemon.c | 3 +++ |
22 | 1 file changed, 1 insertion(+), 1 deletion(-) | 13 | 1 file changed, 3 insertions(+) |
23 | 14 | ||
24 | diff --git a/block.c b/block.c | 15 | diff --git a/storage-daemon/qemu-storage-daemon.c b/storage-daemon/qemu-storage-daemon.c |
25 | index XXXXXXX..XXXXXXX 100644 | 16 | index XXXXXXX..XXXXXXX 100644 |
26 | --- a/block.c | 17 | --- a/storage-daemon/qemu-storage-daemon.c |
27 | +++ b/block.c | 18 | +++ b/storage-daemon/qemu-storage-daemon.c |
28 | @@ -XXX,XX +XXX,XX @@ static int bdrv_open_common(BlockDriverState *bs, BlockBackend *file, | 19 | @@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[]) |
29 | filename = qdict_get_try_str(options, "filename"); | 20 | main_loop_wait(false); |
30 | } | 21 | } |
31 | 22 | ||
32 | - if (drv->bdrv_needs_filename && !filename) { | 23 | + bdrv_drain_all_begin(); |
33 | + if (drv->bdrv_needs_filename && (!filename || !filename[0])) { | 24 | + bdrv_close_all(); |
34 | error_setg(errp, "The '%s' block driver requires a file name", | 25 | + |
35 | drv->format_name); | 26 | monitor_cleanup(); |
36 | ret = -EINVAL; | 27 | qemu_chr_cleanup(); |
28 | user_creatable_cleanup(); | ||
37 | -- | 29 | -- |
38 | 1.8.3.1 | 30 | 2.29.2 |
39 | 31 | ||
40 | 32 | diff view generated by jsdifflib |
1 | From: Fam Zheng <famz@redhat.com> | 1 | From: Max Reitz <mreitz@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | Mirror calculates job len from current I/O progress: | 3 | Signed-off-by: Max Reitz <mreitz@redhat.com> |
4 | 4 | Message-Id: <20201027190600.192171-18-mreitz@redhat.com> | |
5 | s->common.len = s->common.offset + | ||
6 | (cnt + s->sectors_in_flight) * BDRV_SECTOR_SIZE; | ||
7 | |||
8 | The final "len" of a failed mirror job in iotests 109 depends on the | ||
9 | subtle timing of the completion of read and write issued in the first | ||
10 | mirror iteration. The second iteration may or may not have run when the | ||
11 | I/O error happens, resulting in non-deterministic output of the | ||
12 | BLOCK_JOB_COMPLETED event text. | ||
13 | |||
14 | Similar to what was done in a752e4786, filter out the field to make the | ||
15 | test robust. | ||
16 | |||
17 | Signed-off-by: Fam Zheng <famz@redhat.com> | ||
18 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
19 | Tested-by: Eric Blake <eblake@redhat.com> | ||
20 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 5 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
21 | --- | 6 | --- |
22 | tests/qemu-iotests/109 | 6 ++++-- | 7 | tests/qemu-iotests/check | 11 +++++++++++ |
23 | tests/qemu-iotests/109.out | 20 ++++++++++---------- | 8 | tests/qemu-iotests/common.rc | 17 +++++++++++++++++ |
24 | tests/qemu-iotests/common.filter | 6 ++++++ | 9 | 2 files changed, 28 insertions(+) |
25 | 3 files changed, 20 insertions(+), 12 deletions(-) | ||
26 | 10 | ||
27 | diff --git a/tests/qemu-iotests/109 b/tests/qemu-iotests/109 | 11 | diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check |
28 | index XXXXXXX..XXXXXXX 100755 | 12 | index XXXXXXX..XXXXXXX 100755 |
29 | --- a/tests/qemu-iotests/109 | 13 | --- a/tests/qemu-iotests/check |
30 | +++ b/tests/qemu-iotests/109 | 14 | +++ b/tests/qemu-iotests/check |
31 | @@ -XXX,XX +XXX,XX @@ for fmt in qcow qcow2 qed vdi vmdk vpc; do | 15 | @@ -XXX,XX +XXX,XX @@ if [ -z $QEMU_NBD_PROG ]; then |
32 | 16 | fi | |
33 | # This first test should fail: The image format was probed, we may not | 17 | export QEMU_NBD_PROG="$(type -p "$QEMU_NBD_PROG")" |
34 | # write an image header at the start of the image | 18 | |
35 | - run_qemu "$TEST_IMG" "$TEST_IMG.src" "" "BLOCK_JOB_ERROR" | 19 | +if [ -z "$QSD_PROG" ]; then |
36 | + run_qemu "$TEST_IMG" "$TEST_IMG.src" "" "BLOCK_JOB_ERROR" | | 20 | + if [ -x "$build_iotests/qemu-storage-daemon" ]; then |
37 | + _filter_block_job_len | 21 | + export QSD_PROG="$build_iotests/qemu-storage-daemon" |
38 | $QEMU_IO -c 'read -P 0 0 64k' "$TEST_IMG" | _filter_qemu_io | 22 | + elif [ -x "$build_root/storage-daemon/qemu-storage-daemon" ]; then |
39 | 23 | + export QSD_PROG="$build_root/storage-daemon/qemu-storage-daemon" | |
40 | 24 | + else | |
41 | @@ -XXX,XX +XXX,XX @@ for sample_img in empty.bochs iotest-dirtylog-10G-4M.vhdx parallels-v1 \ | 25 | + _init_error "qemu-storage-daemon not found" |
42 | _make_test_img 64M | 26 | + fi |
43 | bzcat "$SAMPLE_IMG_DIR/$sample_img.bz2" > "$TEST_IMG.src" | 27 | +fi |
44 | 28 | +export QSD_PROG="$(type -p "$QSD_PROG")" | |
45 | - run_qemu "$TEST_IMG" "$TEST_IMG.src" "" "BLOCK_JOB_ERROR" | _filter_block_job_offset | 29 | + |
46 | + run_qemu "$TEST_IMG" "$TEST_IMG.src" "" "BLOCK_JOB_ERROR" | | 30 | if [ -x "$build_iotests/socket_scm_helper" ] |
47 | + _filter_block_job_offset | _filter_block_job_len | 31 | then |
48 | $QEMU_IO -c 'read -P 0 0 64k' "$TEST_IMG" | _filter_qemu_io | 32 | export SOCKET_SCM_HELPER="$build_iotests/socket_scm_helper" |
49 | 33 | diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc | |
50 | run_qemu "$TEST_IMG" "$TEST_IMG.src" "'format': 'raw'," "BLOCK_JOB_READY" | ||
51 | diff --git a/tests/qemu-iotests/109.out b/tests/qemu-iotests/109.out | ||
52 | index XXXXXXX..XXXXXXX 100644 | 34 | index XXXXXXX..XXXXXXX 100644 |
53 | --- a/tests/qemu-iotests/109.out | 35 | --- a/tests/qemu-iotests/common.rc |
54 | +++ b/tests/qemu-iotests/109.out | 36 | +++ b/tests/qemu-iotests/common.rc |
55 | @@ -XXX,XX +XXX,XX @@ Automatically detecting the format is dangerous for raw images, write operations | 37 | @@ -XXX,XX +XXX,XX @@ fi |
56 | Specify the 'raw' format explicitly to remove the restrictions. | 38 | : ${VALGRIND_QEMU_IMG=$VALGRIND_QEMU} |
57 | {"return": {}} | 39 | : ${VALGRIND_QEMU_IO=$VALGRIND_QEMU} |
58 | {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}} | 40 | : ${VALGRIND_QEMU_NBD=$VALGRIND_QEMU} |
59 | -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 65536, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} | 41 | +: ${VALGRIND_QSD=$VALGRIND_QEMU} |
60 | +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} | 42 | |
61 | {"return": []} | 43 | # The Valgrind own parameters may be set with |
62 | read 65536/65536 bytes at offset 0 | 44 | # its environment variable VALGRIND_OPTS, e.g. |
63 | 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | 45 | @@ -XXX,XX +XXX,XX @@ _qemu_nbd_wrapper() |
64 | @@ -XXX,XX +XXX,XX @@ Automatically detecting the format is dangerous for raw images, write operations | 46 | return $RETVAL |
65 | Specify the 'raw' format explicitly to remove the restrictions. | ||
66 | {"return": {}} | ||
67 | {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}} | ||
68 | -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 197120, "offset": 512, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} | ||
69 | +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 512, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} | ||
70 | {"return": []} | ||
71 | read 65536/65536 bytes at offset 0 | ||
72 | 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
73 | @@ -XXX,XX +XXX,XX @@ Automatically detecting the format is dangerous for raw images, write operations | ||
74 | Specify the 'raw' format explicitly to remove the restrictions. | ||
75 | {"return": {}} | ||
76 | {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}} | ||
77 | -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 327680, "offset": 262144, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} | ||
78 | +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 262144, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} | ||
79 | {"return": []} | ||
80 | read 65536/65536 bytes at offset 0 | ||
81 | 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
82 | @@ -XXX,XX +XXX,XX @@ Automatically detecting the format is dangerous for raw images, write operations | ||
83 | Specify the 'raw' format explicitly to remove the restrictions. | ||
84 | {"return": {}} | ||
85 | {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}} | ||
86 | -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 65536, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} | ||
87 | +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} | ||
88 | {"return": []} | ||
89 | read 65536/65536 bytes at offset 0 | ||
90 | 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
91 | @@ -XXX,XX +XXX,XX @@ Automatically detecting the format is dangerous for raw images, write operations | ||
92 | Specify the 'raw' format explicitly to remove the restrictions. | ||
93 | {"return": {}} | ||
94 | {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}} | ||
95 | -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 65536, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} | ||
96 | +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} | ||
97 | {"return": []} | ||
98 | read 65536/65536 bytes at offset 0 | ||
99 | 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
100 | @@ -XXX,XX +XXX,XX @@ Automatically detecting the format is dangerous for raw images, write operations | ||
101 | Specify the 'raw' format explicitly to remove the restrictions. | ||
102 | {"return": {}} | ||
103 | {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}} | ||
104 | -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 65536, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} | ||
105 | +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} | ||
106 | {"return": []} | ||
107 | read 65536/65536 bytes at offset 0 | ||
108 | 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
109 | @@ -XXX,XX +XXX,XX @@ Automatically detecting the format is dangerous for raw images, write operations | ||
110 | Specify the 'raw' format explicitly to remove the restrictions. | ||
111 | {"return": {}} | ||
112 | {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}} | ||
113 | -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 65536, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} | ||
114 | +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} | ||
115 | {"return": []} | ||
116 | read 65536/65536 bytes at offset 0 | ||
117 | 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
118 | @@ -XXX,XX +XXX,XX @@ Automatically detecting the format is dangerous for raw images, write operations | ||
119 | Specify the 'raw' format explicitly to remove the restrictions. | ||
120 | {"return": {}} | ||
121 | {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}} | ||
122 | -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 31457280, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} | ||
123 | +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} | ||
124 | {"return": []} | ||
125 | read 65536/65536 bytes at offset 0 | ||
126 | 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
127 | @@ -XXX,XX +XXX,XX @@ Automatically detecting the format is dangerous for raw images, write operations | ||
128 | Specify the 'raw' format explicitly to remove the restrictions. | ||
129 | {"return": {}} | ||
130 | {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}} | ||
131 | -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 327680, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} | ||
132 | +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} | ||
133 | {"return": []} | ||
134 | read 65536/65536 bytes at offset 0 | ||
135 | 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
136 | @@ -XXX,XX +XXX,XX @@ Automatically detecting the format is dangerous for raw images, write operations | ||
137 | Specify the 'raw' format explicitly to remove the restrictions. | ||
138 | {"return": {}} | ||
139 | {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}} | ||
140 | -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 65536, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} | ||
141 | +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} | ||
142 | {"return": []} | ||
143 | read 65536/65536 bytes at offset 0 | ||
144 | 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
145 | diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter | ||
146 | index XXXXXXX..XXXXXXX 100644 | ||
147 | --- a/tests/qemu-iotests/common.filter | ||
148 | +++ b/tests/qemu-iotests/common.filter | ||
149 | @@ -XXX,XX +XXX,XX @@ _filter_block_job_offset() | ||
150 | sed -e 's/, "offset": [0-9]\+,/, "offset": OFFSET,/' | ||
151 | } | 47 | } |
152 | 48 | ||
153 | +# replace block job len | 49 | +_qemu_storage_daemon_wrapper() |
154 | +_filter_block_job_len() | ||
155 | +{ | 50 | +{ |
156 | + sed -e 's/, "len": [0-9]\+,/, "len": LEN,/g' | 51 | + local VALGRIND_LOGFILE="${TEST_DIR}"/$$.valgrind |
52 | + ( | ||
53 | + if [ -n "${QSD_NEED_PID}" ]; then | ||
54 | + echo $BASHPID > "${QEMU_TEST_DIR}/qemu-storage-daemon.pid" | ||
55 | + fi | ||
56 | + VALGRIND_QEMU="${VALGRIND_QSD}" _qemu_proc_exec "${VALGRIND_LOGFILE}" \ | ||
57 | + "$QSD_PROG" $QSD_OPTIONS "$@" | ||
58 | + ) | ||
59 | + RETVAL=$? | ||
60 | + _qemu_proc_valgrind_log "${VALGRIND_LOGFILE}" $RETVAL | ||
61 | + return $RETVAL | ||
157 | +} | 62 | +} |
158 | + | 63 | + |
159 | # replace driver-specific options in the "Formatting..." line | 64 | # Valgrind bug #409141 https://bugs.kde.org/show_bug.cgi?id=409141 |
160 | _filter_img_create() | 65 | # Until valgrind 3.16+ is ubiquitous, we must work around a hang in |
161 | { | 66 | # valgrind when issuing sigkill. Disable valgrind for this invocation. |
67 | @@ -XXX,XX +XXX,XX @@ export QEMU=_qemu_wrapper | ||
68 | export QEMU_IMG=_qemu_img_wrapper | ||
69 | export QEMU_IO=_qemu_io_wrapper | ||
70 | export QEMU_NBD=_qemu_nbd_wrapper | ||
71 | +export QSD=_qemu_storage_daemon_wrapper | ||
72 | |||
73 | if [ "$IMGOPTSSYNTAX" = "true" ]; then | ||
74 | DRIVER="driver=$IMGFMT" | ||
162 | -- | 75 | -- |
163 | 1.8.3.1 | 76 | 2.29.2 |
164 | 77 | ||
165 | 78 | diff view generated by jsdifflib |
1 | From: John Snow <jsnow@redhat.com> | 1 | From: Max Reitz <mreitz@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | Split the help text to highlight the groups of options | 3 | This pretends FUSE exports are a kind of protocol. As such, they are |
4 | a little better, carving out a clear "format" and | 4 | always tested under the format node. This is probably the best way to |
5 | "protocols" section. | 5 | test them, actually, because this will generate more I/O load and more |
6 | 6 | varied patterns. | |
7 | Signed-off-by: John Snow <jsnow@redhat.com> | 7 | |
8 | Message-id: 20170427205100.9505-2-jsnow@redhat.com | ||
9 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
10 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 8 | Signed-off-by: Max Reitz <mreitz@redhat.com> |
9 | Message-Id: <20201027190600.192171-19-mreitz@redhat.com> | ||
10 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
11 | --- | 11 | --- |
12 | tests/qemu-iotests/common | 8 ++++++-- | 12 | tests/qemu-iotests/check | 6 ++ |
13 | 1 file changed, 6 insertions(+), 2 deletions(-) | 13 | tests/qemu-iotests/common.filter | 5 +- |
14 | 14 | tests/qemu-iotests/common.rc | 124 +++++++++++++++++++++++++++++++ | |
15 | diff --git a/tests/qemu-iotests/common b/tests/qemu-iotests/common | 15 | 3 files changed, 134 insertions(+), 1 deletion(-) |
16 | index XXXXXXX..XXXXXXX 100644 | 16 | |
17 | --- a/tests/qemu-iotests/common | 17 | diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check |
18 | +++ b/tests/qemu-iotests/common | 18 | index XXXXXXX..XXXXXXX 100755 |
19 | @@ -XXX,XX +XXX,XX @@ common options | 19 | --- a/tests/qemu-iotests/check |
20 | -v verbose | 20 | +++ b/tests/qemu-iotests/check |
21 | -d debug | 21 | @@ -XXX,XX +XXX,XX @@ image protocol options |
22 | |||
23 | -check options | ||
24 | +image format options | ||
25 | -raw test raw (default) | ||
26 | -bochs test bochs | ||
27 | -cloop test cloop | ||
28 | @@ -XXX,XX +XXX,XX @@ check options | ||
29 | -vpc test vpc | ||
30 | -vhdx test vhdx | ||
31 | -vmdk test vmdk | ||
32 | + -luks test luks | ||
33 | + | ||
34 | +image protocol options | ||
35 | -file test file (default) | ||
36 | -rbd test rbd | 22 | -rbd test rbd |
37 | -sheepdog test sheepdog | 23 | -sheepdog test sheepdog |
38 | -nbd test nbd | 24 | -nbd test nbd |
25 | + -fuse test fuse | ||
39 | -ssh test ssh | 26 | -ssh test ssh |
40 | -nfs test nfs | 27 | -nfs test nfs |
41 | - -luks test luks | 28 | |
42 | -vxhs test vxhs | 29 | @@ -XXX,XX +XXX,XX @@ testlist options |
43 | + | 30 | xpand=false |
44 | +other options | 31 | ;; |
45 | -xdiff graphical mode diff | 32 | |
46 | -nocache use O_DIRECT on backing file | 33 | + -fuse) |
47 | -misalign misalign memory allocations | 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 | ||
42 | index XXXXXXX..XXXXXXX 100644 | ||
43 | --- a/tests/qemu-iotests/common.filter | ||
44 | +++ b/tests/qemu-iotests/common.filter | ||
45 | @@ -XXX,XX +XXX,XX @@ _filter_qom_path() | ||
46 | _filter_testdir() | ||
47 | { | ||
48 | $SED -e "s#$TEST_DIR/#TEST_DIR/#g" \ | ||
49 | - -e "s#$SOCK_DIR/#SOCK_DIR/#g" | ||
50 | + -e "s#$SOCK_DIR/#SOCK_DIR/#g" \ | ||
51 | + -e "s#SOCK_DIR/fuse-#TEST_DIR/#g" | ||
52 | } | ||
53 | |||
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" | \ | ||
48 | -- | 260 | -- |
49 | 1.8.3.1 | 261 | 2.29.2 |
50 | 262 | ||
51 | 263 | diff view generated by jsdifflib |
1 | From: Eric Blake <eblake@redhat.com> | 1 | From: Max Reitz <mreitz@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | s/refcout/refcount/ | 3 | Many tests (that do not support generic protocols) can run just fine |
4 | with FUSE-exported images, so allow them to. Note that this is no | ||
5 | attempt at being definitely complete. There are some tests that might | ||
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. | ||
4 | 8 | ||
5 | CC: qemu-trivial@nongnu.org | 9 | Note that 221 and 250 only pass when .lseek is correctly implemented, |
6 | Signed-off-by: Eric Blake <eblake@redhat.com> | 10 | which is only possible with a libfuse that is 3.8 or newer. |
7 | Reviewed-by: Laurent Vivier <lvivier@redhat.com> | 11 | |
12 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
13 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> | ||
14 | Message-Id: <20201027190600.192171-20-mreitz@redhat.com> | ||
8 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 15 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
9 | --- | 16 | --- |
10 | tests/qemu-iotests/026 | 2 +- | 17 | tests/qemu-iotests/025 | 2 +- |
11 | tests/qemu-iotests/026.out | 2 +- | 18 | tests/qemu-iotests/026 | 2 +- |
12 | tests/qemu-iotests/026.out.nocache | 2 +- | 19 | tests/qemu-iotests/028 | 2 +- |
13 | 3 files changed, 3 insertions(+), 3 deletions(-) | 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(-) | ||
14 | 93 | ||
94 | diff --git a/tests/qemu-iotests/025 b/tests/qemu-iotests/025 | ||
95 | index XXXXXXX..XXXXXXX 100755 | ||
96 | --- a/tests/qemu-iotests/025 | ||
97 | +++ b/tests/qemu-iotests/025 | ||
98 | @@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15 | ||
99 | . ./common.pattern | ||
100 | |||
101 | _supported_fmt raw qcow2 qed luks | ||
102 | -_supported_proto file sheepdog rbd nfs | ||
103 | +_supported_proto file sheepdog rbd nfs fuse | ||
104 | |||
105 | echo "=== Creating image" | ||
106 | echo | ||
15 | diff --git a/tests/qemu-iotests/026 b/tests/qemu-iotests/026 | 107 | diff --git a/tests/qemu-iotests/026 b/tests/qemu-iotests/026 |
16 | index XXXXXXX..XXXXXXX 100755 | 108 | index XXXXXXX..XXXXXXX 100755 |
17 | --- a/tests/qemu-iotests/026 | 109 | --- a/tests/qemu-iotests/026 |
18 | +++ b/tests/qemu-iotests/026 | 110 | +++ b/tests/qemu-iotests/026 |
19 | @@ -XXX,XX +XXX,XX @@ done | 111 | @@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15 |
20 | 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 | ||
21 | 234 | ||
22 | echo | 235 | echo |
23 | -echo === Refcout table growth tests === | 236 | echo "== Creating images ==" |
24 | +echo === Refcount table growth tests === | 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 | |||
25 | echo | 248 | echo |
26 | CLUSTER_SIZE=512 | 249 | echo "creating too large image (1 EB)" |
27 | 250 | diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060 | |
28 | diff --git a/tests/qemu-iotests/026.out b/tests/qemu-iotests/026.out | 251 | index XXXXXXX..XXXXXXX 100755 |
29 | index XXXXXXX..XXXXXXX 100644 | 252 | --- a/tests/qemu-iotests/060 |
30 | --- a/tests/qemu-iotests/026.out | 253 | +++ b/tests/qemu-iotests/060 |
31 | +++ b/tests/qemu-iotests/026.out | 254 | @@ -XXX,XX +XXX,XX @@ _filter_io_error() |
32 | @@ -XXX,XX +XXX,XX @@ Event: cluster_alloc; errno: 28; imm: off; once: off; write -b | 255 | |
33 | write failed: No space left on device | 256 | # This tests qcow2-specific low-level functionality |
34 | No errors were found on the image. | 257 | _supported_fmt qcow2 |
35 | 258 | -_supported_proto file | |
36 | -=== Refcout table growth tests === | 259 | +_supported_proto file fuse |
37 | +=== Refcount table growth tests === | 260 | _supported_os Linux |
38 | 261 | # These tests only work for compat=1.1 images without an external | |
39 | Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 | 262 | # data file with refcount_bits=16 |
40 | 263 | diff --git a/tests/qemu-iotests/071 b/tests/qemu-iotests/071 | |
41 | diff --git a/tests/qemu-iotests/026.out.nocache b/tests/qemu-iotests/026.out.nocache | 264 | index XXXXXXX..XXXXXXX 100755 |
42 | index XXXXXXX..XXXXXXX 100644 | 265 | --- a/tests/qemu-iotests/071 |
43 | --- a/tests/qemu-iotests/026.out.nocache | 266 | +++ b/tests/qemu-iotests/071 |
44 | +++ b/tests/qemu-iotests/026.out.nocache | 267 | @@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15 |
45 | @@ -XXX,XX +XXX,XX @@ Event: cluster_alloc; errno: 28; imm: off; once: off; write -b | 268 | . ./common.filter |
46 | write failed: No space left on device | 269 | |
47 | No errors were found on the image. | 270 | _supported_fmt qcow2 |
48 | 271 | -_supported_proto file | |
49 | -=== Refcout table growth tests === | 272 | +_supported_proto file fuse |
50 | +=== Refcount table growth tests === | 273 | _require_drivers blkdebug blkverify |
51 | 274 | # blkdebug can only inject errors on bs->file, not on the data_file, | |
52 | Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 | 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 | ||
53 | 1068 | ||
54 | -- | 1069 | -- |
55 | 1.8.3.1 | 1070 | 2.29.2 |
56 | 1071 | ||
57 | 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: Dr. David Alan Gilbert <dgilbert@redhat.com> | ||
3 | --- | 12 | --- |
4 | tests/qemu-iotests/181 | 119 +++++++++++++++++++++++++++++++++++++++++++++ | 13 | tests/qemu-iotests/308 | 339 +++++++++++++++++++++++++++++++++++++ |
5 | tests/qemu-iotests/181.out | 38 +++++++++++++++ | 14 | tests/qemu-iotests/308.out | 97 +++++++++++ |
6 | tests/qemu-iotests/group | 1 + | 15 | tests/qemu-iotests/group | 1 + |
7 | 3 files changed, 158 insertions(+) | 16 | 3 files changed, 437 insertions(+) |
8 | create mode 100755 tests/qemu-iotests/181 | 17 | create mode 100755 tests/qemu-iotests/308 |
9 | create mode 100644 tests/qemu-iotests/181.out | 18 | create mode 100644 tests/qemu-iotests/308.out |
10 | 19 | ||
11 | diff --git a/tests/qemu-iotests/181 b/tests/qemu-iotests/181 | 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/181 | 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 postcopy live migration with shared storage | 28 | +# Test FUSE exports (in ways that are not captured by the generic |
20 | +# | 29 | +# tests) |
21 | +# Copyright (C) 2017 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 | + | ||
46 | +MIG_SOCKET="${TEST_DIR}/migrate" | ||
47 | + | 51 | + |
48 | +_cleanup() | 52 | +_cleanup() |
49 | +{ | 53 | +{ |
50 | + rm -f "${MIG_SOCKET}" | ||
51 | + _cleanup_test_img | ||
52 | + _cleanup_qemu | 54 | + _cleanup_qemu |
55 | + _cleanup_test_img | ||
56 | + rmdir "$EXT_MP" 2>/dev/null | ||
57 | + rm -f "$EXT_MP" | ||
58 | + rm -f "$COPIED_IMG" | ||
53 | +} | 59 | +} |
54 | +trap "_cleanup; exit \$status" 0 1 2 3 15 | 60 | +trap "_cleanup; exit \$status" 0 1 2 3 15 |
55 | + | 61 | + |
56 | +# get standard environment, filters and checks | 62 | +# get standard environment, filters and checks |
57 | +. ./common.rc | 63 | +. ./common.rc |
58 | +. ./common.filter | 64 | +. ./common.filter |
59 | +. ./common.qemu | 65 | +. ./common.qemu |
60 | + | 66 | + |
67 | +# Generic format, but needs a plain filename | ||
61 | +_supported_fmt generic | 68 | +_supported_fmt generic |
62 | +_supported_proto generic | 69 | +if [ "$IMGOPTSSYNTAX" = "true" ]; then |
63 | +_supported_os Linux | 70 | + _unsupported_fmt $IMGFMT |
64 | + | 71 | +fi |
65 | +size=64M | 72 | +# We need the image to have exactly the specified size, and VPC does |
66 | +_make_test_img $size | 73 | +# not allow that by default |
67 | + | 74 | +_unsupported_fmt vpc |
68 | +echo | 75 | + |
69 | +echo === Starting VMs === | 76 | +_supported_proto file # We create the FUSE export manually |
70 | +echo | 77 | +_supported_os Linux # We need /dev/urandom |
71 | + | 78 | + |
72 | +qemu_comm_method="monitor" | 79 | +# $1: Export ID |
73 | + | 80 | +# $2: Options (beyond the node-name and ID) |
74 | +_launch_qemu \ | 81 | +# $3: Expected return value (defaults to 'return') |
75 | + -drive file="${TEST_IMG}",cache=${CACHEMODE},driver=$IMGFMT,id=disk | 82 | +# $4: Node to export (defaults to 'node-format') |
76 | +src=$QEMU_HANDLE | 83 | +fuse_export_add() |
77 | + | 84 | +{ |
78 | +_launch_qemu \ | 85 | + _send_qemu_cmd $QEMU_HANDLE \ |
79 | + -drive file="${TEST_IMG}",cache=${CACHEMODE},driver=$IMGFMT,id=disk \ | 86 | + "{'execute': 'block-export-add', |
80 | + -incoming "unix:${MIG_SOCKET}" | 87 | + 'arguments': { |
81 | +dest=$QEMU_HANDLE | 88 | + 'type': 'fuse', |
82 | + | 89 | + 'id': '$1', |
83 | +echo | 90 | + 'node-name': '${4:-node-format}', |
84 | +echo === Write something on the source === | 91 | + $2 |
85 | +echo | 92 | + } }" \ |
86 | + | 93 | + "${3:-return}" \ |
87 | +silent= | 94 | + | _filter_imgfmt |
88 | +_send_qemu_cmd $src 'qemu-io disk "write -P 0x55 0 64k"' "(qemu)" | 95 | +} |
89 | +_send_qemu_cmd $src "" "ops/sec" | 96 | + |
90 | +_send_qemu_cmd $src 'qemu-io disk "read -P 0x55 0 64k"' "(qemu)" | 97 | +# $1: Export ID |
91 | +_send_qemu_cmd $src "" "ops/sec" | 98 | +fuse_export_del() |
92 | + | 99 | +{ |
93 | +echo | 100 | + _send_qemu_cmd $QEMU_HANDLE \ |
94 | +echo === Do postcopy migration to destination === | 101 | + "{'execute': 'block-export-del', |
95 | +echo | 102 | + 'arguments': { |
96 | + | 103 | + 'id': '$1' |
97 | +# Slow down migration so much that it definitely won't finish before we can | 104 | + } }" \ |
98 | +# switch to postcopy | 105 | + 'return' |
99 | +silent=yes | 106 | + |
100 | +_send_qemu_cmd $src 'migrate_set_speed 4k' "(qemu)" | 107 | + _send_qemu_cmd $QEMU_HANDLE \ |
101 | +_send_qemu_cmd $src 'migrate_set_capability postcopy-ram on' "(qemu)" | 108 | + '' \ |
102 | +_send_qemu_cmd $src "migrate -d unix:${MIG_SOCKET}" "(qemu)" | 109 | + 'BLOCK_EXPORT_DELETED' |
103 | +_send_qemu_cmd $src 'migrate_start_postcopy' "(qemu)" | 110 | +} |
104 | + | 111 | + |
105 | +QEMU_COMM_TIMEOUT=1 qemu_cmd_repeat=10 silent=yes \ | 112 | +# Return the length of the protocol file |
106 | + _send_qemu_cmd $src "info migrate" "completed\|failed" | 113 | +# $1: Protocol node export mount point |
107 | +silent=yes _send_qemu_cmd $src "" "(qemu)" | 114 | +# $2: Original file (to compare) |
108 | + | 115 | +get_proto_len() |
109 | +echo | 116 | +{ |
110 | +echo === Do some I/O on the destination === | 117 | + len1=$(stat -c '%s' "$1") |
111 | +echo | 118 | + len2=$(stat -c '%s' "$2") |
112 | + | 119 | + |
113 | +# It is important that we use the BlockBackend of the guest device here instead | 120 | + if [ "$len1" != "$len2" ]; then |
114 | +# of the node name, which would create a new BlockBackend and not test whether | 121 | + echo 'ERROR: Length of export and original differ:' >&2 |
115 | +# the guest has the necessary permissions to access the image now | 122 | + echo "$len1 != $len2" >&2 |
116 | +silent= | 123 | + else |
117 | +_send_qemu_cmd $dest 'qemu-io disk "read -P 0x55 0 64k"' "(qemu)" | 124 | + echo '(OK: Lengths of export and original are the same)' >&2 |
118 | +_send_qemu_cmd $dest "" "ops/sec" | 125 | + fi |
119 | +_send_qemu_cmd $dest 'qemu-io disk "write -P 0x66 1M 64k"' "(qemu)" | 126 | + |
120 | +_send_qemu_cmd $dest "" "ops/sec" | 127 | + echo "$len1" |
121 | + | 128 | +} |
122 | +echo | 129 | + |
123 | +echo === Shut down and check image === | 130 | +COPIED_IMG="$TEST_IMG.copy" |
124 | +echo | 131 | +EXT_MP="$TEST_IMG.fuse" |
125 | + | 132 | + |
126 | +_send_qemu_cmd $src 'quit' "" | 133 | +echo '=== Set up ===' |
127 | +_send_qemu_cmd $dest 'quit' "" | 134 | + |
128 | +wait=1 _cleanup_qemu | 135 | +# Create image with random data |
129 | + | 136 | +_make_test_img 64M |
130 | +_check_test_img | 137 | +$QEMU_IO -c 'write -s /dev/urandom 0 64M' "$TEST_IMG" | _filter_qemu_io |
138 | + | ||
139 | +_launch_qemu | ||
140 | +_send_qemu_cmd $QEMU_HANDLE \ | ||
141 | + "{'execute': 'qmp_capabilities'}" \ | ||
142 | + 'return' | ||
143 | + | ||
144 | +# Separate blockdev-add calls for format and protocol so we can remove | ||
145 | +# the format layer later on | ||
146 | +_send_qemu_cmd $QEMU_HANDLE \ | ||
147 | + "{'execute': 'blockdev-add', | ||
148 | + 'arguments': { | ||
149 | + 'driver': 'file', | ||
150 | + 'node-name': 'node-protocol', | ||
151 | + 'filename': '$TEST_IMG' | ||
152 | + } }" \ | ||
153 | + 'return' | ||
154 | + | ||
155 | +_send_qemu_cmd $QEMU_HANDLE \ | ||
156 | + "{'execute': 'blockdev-add', | ||
157 | + 'arguments': { | ||
158 | + 'driver': '$IMGFMT', | ||
159 | + 'node-name': 'node-format', | ||
160 | + 'file': 'node-protocol' | ||
161 | + } }" \ | ||
162 | + 'return' | ||
163 | + | ||
164 | +echo | ||
165 | +echo '=== Mountpoint not present ===' | ||
166 | + | ||
167 | +rmdir "$EXT_MP" 2>/dev/null | ||
168 | +rm -f "$EXT_MP" | ||
169 | +output=$(fuse_export_add 'export-err' "'mountpoint': '$EXT_MP'" error) | ||
170 | + | ||
171 | +if echo "$output" | grep -q "Invalid parameter 'fuse'"; then | ||
172 | + _notrun 'No FUSE support' | ||
173 | +fi | ||
174 | + | ||
175 | +echo "$output" | ||
176 | + | ||
177 | +echo | ||
178 | +echo '=== Mountpoint is a directory ===' | ||
179 | + | ||
180 | +mkdir "$EXT_MP" | ||
181 | +fuse_export_add 'export-err' "'mountpoint': '$EXT_MP'" error | ||
182 | +rmdir "$EXT_MP" | ||
183 | + | ||
184 | +echo | ||
185 | +echo '=== Mountpoint is a regular file ===' | ||
186 | + | ||
187 | +touch "$EXT_MP" | ||
188 | +fuse_export_add 'export-mp' "'mountpoint': '$EXT_MP'" | ||
189 | + | ||
190 | +# Check that the export presents the same data as the original image | ||
191 | +$QEMU_IMG compare -f raw -F $IMGFMT -U "$EXT_MP" "$TEST_IMG" | ||
192 | + | ||
193 | +echo | ||
194 | +echo '=== Mount over existing file ===' | ||
195 | + | ||
196 | +# This is the coolest feature of FUSE exports: You can transparently | ||
197 | +# make images in any format appear as raw images | ||
198 | +fuse_export_add 'export-img' "'mountpoint': '$TEST_IMG'" | ||
199 | + | ||
200 | +# Accesses both exports at the same time, so we get a concurrency test | ||
201 | +$QEMU_IMG compare -f raw -F raw -U "$EXT_MP" "$TEST_IMG" | ||
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" | ||
131 | + | 360 | + |
132 | +# success, all done | 361 | +# success, all done |
133 | +echo "*** done" | 362 | +echo "*** done" |
134 | +rm -f $seq.full | 363 | +rm -f $seq.full |
135 | +status=0 | 364 | +status=0 |
136 | diff --git a/tests/qemu-iotests/181.out b/tests/qemu-iotests/181.out | 365 | diff --git a/tests/qemu-iotests/308.out b/tests/qemu-iotests/308.out |
137 | new file mode 100644 | 366 | new file mode 100644 |
138 | index XXXXXXX..XXXXXXX | 367 | index XXXXXXX..XXXXXXX |
139 | --- /dev/null | 368 | --- /dev/null |
140 | +++ b/tests/qemu-iotests/181.out | 369 | +++ b/tests/qemu-iotests/308.out |
141 | @@ -XXX,XX +XXX,XX @@ | 370 | @@ -XXX,XX +XXX,XX @@ |
142 | +QA output created by 181 | 371 | +QA output created by 308 |
372 | +=== Set up === | ||
143 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 | 373 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 |
144 | + | 374 | +wrote 67108864/67108864 bytes at offset 0 |
145 | +=== Starting VMs === | 375 | +64 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) |
146 | + | 376 | +{'execute': 'qmp_capabilities'} |
147 | + | 377 | +{"return": {}} |
148 | +=== Write something on the source === | 378 | +{'execute': 'blockdev-add', 'arguments': { 'driver': 'file', 'node-name': 'node-protocol', 'filename': 'TEST_DIR/t.IMGFMT' } } |
149 | + | 379 | +{"return": {}} |
150 | +QEMU X.Y.Z monitor - type 'help' for more information | 380 | +{'execute': 'blockdev-add', 'arguments': { 'driver': 'IMGFMT', 'node-name': 'node-format', 'file': 'node-protocol' } } |
151 | +(qemu) qemu-io disk "write -P 0x55 0 64k" | 381 | +{"return": {}} |
152 | +wrote 65536/65536 bytes at offset 0 | 382 | + |
153 | +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | 383 | +=== Mountpoint not present === |
154 | +(qemu) | 384 | +{'execute': 'block-export-add', 'arguments': { 'type': 'fuse', 'id': 'export-err', 'node-name': 'node-format', 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse' } } |
155 | +(qemu) qemu-io disk "read -P 0x55 0 64k" | 385 | +{"error": {"class": "GenericError", "desc": "Failed to stat 'TEST_DIR/t.IMGFMT.fuse': No such file or directory"}} |
156 | +read 65536/65536 bytes at offset 0 | 386 | + |
157 | +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | 387 | +=== Mountpoint is a directory === |
158 | + | 388 | +{'execute': 'block-export-add', 'arguments': { 'type': 'fuse', 'id': 'export-err', 'node-name': 'node-format', 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse' } } |
159 | +=== Do postcopy migration to destination === | 389 | +{"error": {"class": "GenericError", "desc": "'TEST_DIR/t.IMGFMT.fuse' is not a regular file"}} |
160 | + | 390 | + |
161 | + | 391 | +=== Mountpoint is a regular file === |
162 | +=== Do some I/O on the destination === | 392 | +{'execute': 'block-export-add', 'arguments': { 'type': 'fuse', 'id': 'export-mp', 'node-name': 'node-format', 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse' } } |
163 | + | 393 | +{"return": {}} |
164 | +QEMU X.Y.Z monitor - type 'help' for more information | 394 | +Images are identical. |
165 | +(qemu) qemu-io disk "read -P 0x55 0 64k" | 395 | + |
166 | +read 65536/65536 bytes at offset 0 | 396 | +=== Mount over existing file === |
167 | +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | 397 | +{'execute': 'block-export-add', 'arguments': { 'type': 'fuse', 'id': 'export-img', 'node-name': 'node-format', 'mountpoint': 'TEST_DIR/t.IMGFMT' } } |
168 | +(qemu) | 398 | +{"return": {}} |
169 | +(qemu) qemu-io disk "write -P 0x66 1M 64k" | 399 | +Images are identical. |
400 | + | ||
401 | +=== Double export === | ||
402 | +{'execute': 'block-export-add', 'arguments': { 'type': 'fuse', 'id': 'export-err', 'node-name': 'node-format', 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse' } } | ||
403 | +{"error": {"class": "GenericError", "desc": "There already is a FUSE export on 'TEST_DIR/t.IMGFMT.fuse'"}} | ||
404 | + | ||
405 | +=== Remove export === | ||
406 | +virtual size: 64 MiB (67108864 bytes) | ||
407 | +{'execute': 'block-export-del', 'arguments': { 'id': 'export-mp' } } | ||
408 | +{"return": {}} | ||
409 | +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "export-mp"}} | ||
410 | +virtual size: 0 B (0 bytes) | ||
411 | + | ||
412 | +=== Writable export === | ||
413 | +{'execute': 'block-export-add', 'arguments': { 'type': 'fuse', 'id': 'export-mp', 'node-name': 'node-format', 'mountpoint': 'TEST_DIR/t.IMGFMT.fuse', 'writable': true } } | ||
414 | +{"return": {}} | ||
415 | +write failed: Permission denied | ||
170 | +wrote 65536/65536 bytes at offset 1048576 | 416 | +wrote 65536/65536 bytes at offset 1048576 |
171 | +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | 417 | +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) |
172 | + | 418 | +wrote 65536/65536 bytes at offset 1048576 |
173 | +=== Shut down and check image === | 419 | +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) |
174 | + | 420 | + |
175 | +(qemu) quit | 421 | +=== Resizing exports === |
176 | +(qemu) | 422 | +{'execute': 'block-export-del', 'arguments': { 'id': 'export-mp' } } |
177 | +(qemu) quit | 423 | +{"return": {}} |
178 | +No errors were found on the image. | 424 | +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "export-mp"}} |
425 | +{'execute': 'block-export-del', 'arguments': { 'id': 'export-img' } } | ||
426 | +{"return": {}} | ||
427 | +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "export-img"}} | ||
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. | ||
179 | +*** done | 467 | +*** done |
180 | 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 |
181 | index XXXXXXX..XXXXXXX 100644 | 469 | index XXXXXXX..XXXXXXX 100644 |
182 | --- a/tests/qemu-iotests/group | 470 | --- a/tests/qemu-iotests/group |
183 | +++ b/tests/qemu-iotests/group | 471 | +++ b/tests/qemu-iotests/group |
184 | @@ -XXX,XX +XXX,XX @@ | 472 | @@ -XXX,XX +XXX,XX @@ |
185 | 174 auto | 473 | 304 rw quick |
186 | 175 auto quick | 474 | 305 rw quick |
187 | 176 rw auto backing | 475 | 307 rw quick export |
188 | +181 rw auto migration | 476 | +308 rw |
477 | 309 rw auto quick | ||
189 | -- | 478 | -- |
190 | 1.8.3.1 | 479 | 2.29.2 |
191 | 480 | ||
192 | 481 | diff view generated by jsdifflib |
1 | From: Li Feng <fengli@smartx.com> | ||
---|---|---|---|
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> | ||
1 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 12 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
2 | --- | 13 | --- |
3 | block/file-posix.c | 2 -- | 14 | block/file-posix.c | 2 +- |
4 | 1 file changed, 2 deletions(-) | 15 | 1 file changed, 1 insertion(+), 1 deletion(-) |
5 | 16 | ||
6 | 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 |
7 | index XXXXXXX..XXXXXXX 100644 | 18 | index XXXXXXX..XXXXXXX 100644 |
8 | --- a/block/file-posix.c | 19 | --- a/block/file-posix.c |
9 | +++ b/block/file-posix.c | 20 | +++ b/block/file-posix.c |
10 | @@ -XXX,XX +XXX,XX @@ | 21 | @@ -XXX,XX +XXX,XX @@ static int raw_check_perm(BlockDriverState *bs, uint64_t perm, uint64_t shared, |
11 | #include "qapi/error.h" | 22 | } |
12 | #include "qemu/cutils.h" | 23 | |
13 | #include "qemu/error-report.h" | 24 | /* Copy locks to the new fd */ |
14 | -#include "qemu/timer.h" | 25 | - if (s->perm_change_fd) { |
15 | -#include "qemu/log.h" | 26 | + if (s->perm_change_fd && s->use_lock) { |
16 | #include "block/block_int.h" | 27 | ret = raw_apply_lock_bytes(NULL, s->perm_change_fd, perm, ~shared, |
17 | #include "qemu/module.h" | 28 | false, errp); |
18 | #include "trace.h" | 29 | if (ret < 0) { |
19 | -- | 30 | -- |
20 | 1.8.3.1 | 31 | 2.29.2 |
21 | 32 | ||
22 | 33 | diff view generated by jsdifflib |
1 | From: Eric Blake <eblake@redhat.com> | 1 | From: Max Reitz <mreitz@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | As mentioned in commit 0c1bd46, we ignored requests to | 3 | See the new comment for why this should be done. |
4 | discard the trailing cluster of an unaligned image. While | ||
5 | discard is an advisory operation from the guest standpoint, | ||
6 | (and we are therefore free to ignore any request), our | ||
7 | qcow2 implementation exploits the fact that a discarded | ||
8 | cluster reads back as 0. As long as we discard on cluster | ||
9 | boundaries, we are fine; but that means we could observe | ||
10 | non-zero data leaked at the tail of an unaligned image. | ||
11 | 4 | ||
12 | Enhance iotest 66 to cover this case, and fix the implementation | 5 | I do not have a reproducer on master, but when using FUSE block exports, |
13 | to honor a discard request on the final partial cluster. | 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). | ||
14 | 9 | ||
15 | Signed-off-by: Eric Blake <eblake@redhat.com> | 10 | Suggested-by: Kevin Wolf <kwolf@redhat.com> |
16 | Message-id: 20170407013709.18440-1-eblake@redhat.com | ||
17 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 11 | Signed-off-by: Max Reitz <mreitz@redhat.com> |
12 | Message-Id: <20201207152245.66987-1-mreitz@redhat.com> | ||
13 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
18 | --- | 14 | --- |
19 | block/qcow2.c | 7 ++++++- | 15 | tests/qemu-iotests/221 | 7 +++++++ |
20 | tests/qemu-iotests/066 | 12 +++++++----- | 16 | tests/qemu-iotests/221.out | 14 ++++++-------- |
21 | tests/qemu-iotests/066.out | 12 ++++++++---- | 17 | 2 files changed, 13 insertions(+), 8 deletions(-) |
22 | 3 files changed, 21 insertions(+), 10 deletions(-) | ||
23 | 18 | ||
24 | diff --git a/block/qcow2.c b/block/qcow2.c | 19 | diff --git a/tests/qemu-iotests/221 b/tests/qemu-iotests/221 |
20 | index XXXXXXX..XXXXXXX 100755 | ||
21 | --- a/tests/qemu-iotests/221 | ||
22 | +++ b/tests/qemu-iotests/221 | ||
23 | @@ -XXX,XX +XXX,XX @@ echo "=== Check mapping of unaligned raw image ===" | ||
24 | echo | ||
25 | |||
26 | _make_test_img 65537 # qemu-img create rounds size up | ||
27 | + | ||
28 | +# file-posix allocates the first block of any images when it is created; | ||
29 | +# the size of this block depends on the host page size and the file | ||
30 | +# system block size, none of which are constant. Discard the whole | ||
31 | +# image so we will not see this allocation in qemu-img map's output. | ||
32 | +$QEMU_IO -c 'discard 0 65537' "$TEST_IMG" | _filter_qemu_io | ||
33 | + | ||
34 | $QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map | ||
35 | |||
36 | truncate --size=65537 "$TEST_IMG" # so we resize it and check again | ||
37 | diff --git a/tests/qemu-iotests/221.out b/tests/qemu-iotests/221.out | ||
25 | index XXXXXXX..XXXXXXX 100644 | 38 | index XXXXXXX..XXXXXXX 100644 |
26 | --- a/block/qcow2.c | 39 | --- a/tests/qemu-iotests/221.out |
27 | +++ b/block/qcow2.c | 40 | +++ b/tests/qemu-iotests/221.out |
28 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_pdiscard(BlockDriverState *bs, | 41 | @@ -XXX,XX +XXX,XX @@ QA output created by 221 |
29 | 42 | === Check mapping of unaligned raw image === | |
30 | if (!QEMU_IS_ALIGNED(offset | count, s->cluster_size)) { | 43 | |
31 | assert(count < s->cluster_size); | 44 | Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=65537 |
32 | - return -ENOTSUP; | 45 | -[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET}, |
33 | + /* Ignore partial clusters, except for the special case of the | 46 | -{ "start": 4096, "length": 61952, "depth": 0, "zero": true, "data": false, "offset": OFFSET}] |
34 | + * complete partial cluster at the end of an unaligned file */ | 47 | -[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET}, |
35 | + if (!QEMU_IS_ALIGNED(offset, s->cluster_size) || | 48 | -{ "start": 4096, "length": 61952, "depth": 0, "zero": true, "data": false, "offset": OFFSET}] |
36 | + offset + count != bs->total_sectors * BDRV_SECTOR_SIZE) { | 49 | +discard 65537/65537 bytes at offset 0 |
37 | + return -ENOTSUP; | 50 | +64.001 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) |
38 | + } | 51 | +[{ "start": 0, "length": 66048, "depth": 0, "zero": true, "data": false, "offset": OFFSET}] |
39 | } | 52 | +[{ "start": 0, "length": 66048, "depth": 0, "zero": true, "data": false, "offset": OFFSET}] |
40 | 53 | wrote 1/1 bytes at offset 65536 | |
41 | qemu_co_mutex_lock(&s->lock); | 54 | 1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) |
42 | diff --git a/tests/qemu-iotests/066 b/tests/qemu-iotests/066 | 55 | -[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET}, |
43 | index XXXXXXX..XXXXXXX 100755 | 56 | -{ "start": 4096, "length": 61440, "depth": 0, "zero": true, "data": false, "offset": OFFSET}, |
44 | --- a/tests/qemu-iotests/066 | 57 | +[{ "start": 0, "length": 65536, "depth": 0, "zero": true, "data": false, "offset": OFFSET}, |
45 | +++ b/tests/qemu-iotests/066 | 58 | { "start": 65536, "length": 1, "depth": 0, "zero": false, "data": true, "offset": OFFSET}, |
46 | @@ -XXX,XX +XXX,XX @@ _supported_fmt qcow2 | 59 | { "start": 65537, "length": 511, "depth": 0, "zero": true, "data": false, "offset": OFFSET}] |
47 | _supported_proto generic | 60 | -[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET}, |
48 | _supported_os Linux | 61 | -{ "start": 4096, "length": 61440, "depth": 0, "zero": true, "data": false, "offset": OFFSET}, |
49 | 62 | +[{ "start": 0, "length": 65536, "depth": 0, "zero": true, "data": false, "offset": OFFSET}, | |
50 | +# Intentionally create an unaligned image | 63 | { "start": 65536, "length": 1, "depth": 0, "zero": false, "data": true, "offset": OFFSET}, |
51 | IMGOPTS="compat=1.1" | 64 | { "start": 65537, "length": 511, "depth": 0, "zero": true, "data": false, "offset": OFFSET}] |
52 | -IMG_SIZE=64M | ||
53 | +IMG_SIZE=$((64 * 1024 * 1024 + 512)) | ||
54 | |||
55 | echo | ||
56 | -echo "=== Testing snapshotting an image with zero clusters ===" | ||
57 | +echo "=== Testing cluster discards ===" | ||
58 | echo | ||
59 | _make_test_img $IMG_SIZE | ||
60 | -# Write some normal clusters, zero them (creating preallocated zero clusters) | ||
61 | -# and discard those | ||
62 | -$QEMU_IO -c "write 0 256k" -c "write -z 0 256k" -c "discard 0 256k" "$TEST_IMG" \ | ||
63 | +# Write some normal clusters, zero some of them (creating preallocated | ||
64 | +# zero clusters) and discard everything. Everything should now read as 0. | ||
65 | +$QEMU_IO -c "write 0 256k" -c "write -z 0 256k" -c "write 64M 512" \ | ||
66 | + -c "discard 0 $IMG_SIZE" -c "read -P 0 0 $IMG_SIZE" "$TEST_IMG" \ | ||
67 | | _filter_qemu_io | ||
68 | # Check the image (there shouldn't be any leaks) | ||
69 | _check_test_img | ||
70 | diff --git a/tests/qemu-iotests/066.out b/tests/qemu-iotests/066.out | ||
71 | index XXXXXXX..XXXXXXX 100644 | ||
72 | --- a/tests/qemu-iotests/066.out | ||
73 | +++ b/tests/qemu-iotests/066.out | ||
74 | @@ -XXX,XX +XXX,XX @@ | ||
75 | QA output created by 066 | ||
76 | |||
77 | -=== Testing snapshotting an image with zero clusters === | ||
78 | +=== Testing cluster discards === | ||
79 | |||
80 | -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 | ||
81 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67109376 | ||
82 | wrote 262144/262144 bytes at offset 0 | ||
83 | 256 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
84 | wrote 262144/262144 bytes at offset 0 | ||
85 | 256 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
86 | -discard 262144/262144 bytes at offset 0 | ||
87 | -256 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
88 | +wrote 512/512 bytes at offset 67108864 | ||
89 | +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
90 | +discard 67109376/67109376 bytes at offset 0 | ||
91 | +64 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
92 | +read 67109376/67109376 bytes at offset 0 | ||
93 | +64 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
94 | No errors were found on the image. | ||
95 | *** done | 65 | *** done |
96 | -- | 66 | -- |
97 | 1.8.3.1 | 67 | 2.29.2 |
98 | 68 | ||
99 | 69 | diff view generated by jsdifflib |
1 | Commit d35ff5e6 ('block: Ignore guest dev permissions during incoming | 1 | Providing the 'if' property, but not 'canbus' segfaults like this: |
---|---|---|---|
2 | migration') added blk_resume_after_migration() to the precopy migration | ||
3 | path, but neglected to add it to the duplicated code that is used for | ||
4 | postcopy migration. This means that the guest device doesn't request the | ||
5 | necessary permissions, which ultimately led to failing assertions. | ||
6 | 2 | ||
7 | Add the missing blk_resume_after_migration() to the postcopy path. | 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. | ||
8 | 9 | ||
9 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 10 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
10 | Reviewed-by: Eric Blake <eblake@redhat.com> | 11 | Message-Id: <20201130105615.21799-5-kwolf@redhat.com> |
12 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
11 | --- | 13 | --- |
12 | migration/savevm.c | 8 ++++++++ | 14 | net/can/can_host.c | 5 +++++ |
13 | 1 file changed, 8 insertions(+) | 15 | 1 file changed, 5 insertions(+) |
14 | 16 | ||
15 | diff --git a/migration/savevm.c b/migration/savevm.c | 17 | diff --git a/net/can/can_host.c b/net/can/can_host.c |
16 | index XXXXXXX..XXXXXXX 100644 | 18 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/migration/savevm.c | 19 | --- a/net/can/can_host.c |
18 | +++ b/migration/savevm.c | 20 | +++ b/net/can/can_host.c |
19 | @@ -XXX,XX +XXX,XX @@ static void loadvm_postcopy_handle_run_bh(void *opaque) | 21 | @@ -XXX,XX +XXX,XX @@ static void can_host_connect(CanHostState *ch, Error **errp) |
20 | error_report_err(local_err); | 22 | CanHostClass *chc = CAN_HOST_GET_CLASS(ch); |
21 | } | 23 | Error *local_err = NULL; |
22 | 24 | ||
23 | + /* If we get an error here, just don't restart the VM yet. */ | 25 | + if (ch->bus == NULL) { |
24 | + blk_resume_after_migration(&local_err); | 26 | + error_setg(errp, "'canbus' property not set"); |
25 | + if (local_err) { | 27 | + return; |
26 | + error_free(local_err); | ||
27 | + local_err = NULL; | ||
28 | + autostart = false; | ||
29 | + } | 28 | + } |
30 | + | 29 | + |
31 | trace_loadvm_postcopy_handle_run_cpu_sync(); | 30 | chc->connect(ch, &local_err); |
32 | cpu_synchronize_all_post_init(); | 31 | if (local_err) { |
33 | 32 | error_propagate(errp, local_err); | |
34 | -- | 33 | -- |
35 | 1.8.3.1 | 34 | 2.29.2 |
36 | 35 | ||
37 | 36 | diff view generated by jsdifflib |
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
---|---|---|---|
2 | |||
3 | We should not set overlap_bytes: | ||
4 | |||
5 | 1. Don't worry: it is calculated by bdrv_mark_request_serialising() and | ||
6 | will be equal to or greater than bytes anyway. | ||
7 | |||
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. | ||
12 | |||
13 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
14 | Message-Id: <20201203222713.13507-2-vsementsov@virtuozzo.com> | ||
1 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 15 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
2 | --- | 16 | --- |
3 | block/file-win32.c | 1 - | 17 | block/file-posix.c | 1 - |
4 | 1 file changed, 1 deletion(-) | 18 | 1 file changed, 1 deletion(-) |
5 | 19 | ||
6 | diff --git a/block/file-win32.c b/block/file-win32.c | 20 | diff --git a/block/file-posix.c b/block/file-posix.c |
7 | index XXXXXXX..XXXXXXX 100644 | 21 | index XXXXXXX..XXXXXXX 100644 |
8 | --- a/block/file-win32.c | 22 | --- a/block/file-posix.c |
9 | +++ b/block/file-win32.c | 23 | +++ b/block/file-posix.c |
10 | @@ -XXX,XX +XXX,XX @@ | 24 | @@ -XXX,XX +XXX,XX @@ raw_do_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int bytes, |
11 | #include "qemu/osdep.h" | 25 | |
12 | #include "qapi/error.h" | 26 | end = INT64_MAX & -(uint64_t)bs->bl.request_alignment; |
13 | #include "qemu/cutils.h" | 27 | req->bytes = end - req->offset; |
14 | -#include "qemu/timer.h" | 28 | - req->overlap_bytes = req->bytes; |
15 | #include "block/block_int.h" | 29 | |
16 | #include "qemu/module.h" | 30 | bdrv_mark_request_serialising(req, bs->bl.request_alignment); |
17 | #include "block/raw-aio.h" | 31 | } |
18 | -- | 32 | -- |
19 | 1.8.3.1 | 33 | 2.29.2 |
20 | 34 | ||
21 | 35 | diff view generated by jsdifflib |
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | 1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> |
---|---|---|---|
2 | 2 | ||
3 | Do not do extra call to _get_block_status() | 3 | This simplifies following commit. |
4 | 4 | ||
5 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | 5 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> |
6 | Message-id: 20170407113404.9351-1-vsementsov@virtuozzo.com | 6 | Message-Id: <20201203222713.13507-3-vsementsov@virtuozzo.com> |
7 | Reviewed-by: John Snow <jsnow@redhat.com> | 7 | Reviewed-by: Alberto Garcia <berto@igalia.com> |
8 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 8 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
9 | --- | 9 | --- |
10 | qemu-img.c | 32 ++++++++++---------------------- | 10 | block/io.c | 7 +++---- |
11 | 1 file changed, 10 insertions(+), 22 deletions(-) | 11 | 1 file changed, 3 insertions(+), 4 deletions(-) |
12 | 12 | ||
13 | diff --git a/qemu-img.c b/qemu-img.c | 13 | diff --git a/block/io.c b/block/io.c |
14 | index XXXXXXX..XXXXXXX 100644 | 14 | index XXXXXXX..XXXXXXX 100644 |
15 | --- a/qemu-img.c | 15 | --- a/block/io.c |
16 | +++ b/qemu-img.c | 16 | +++ b/block/io.c |
17 | @@ -XXX,XX +XXX,XX @@ static int convert_iteration_sectors(ImgConvertState *s, int64_t sector_num) | 17 | @@ -XXX,XX +XXX,XX @@ static void bdrv_merge_limits(BlockLimits *dst, const BlockLimits *src) |
18 | 18 | ||
19 | if (s->sector_next_status <= sector_num) { | 19 | void bdrv_refresh_limits(BlockDriverState *bs, Error **errp) |
20 | BlockDriverState *file; | 20 | { |
21 | - ret = bdrv_get_block_status(blk_bs(s->src[src_cur]), | 21 | + ERRP_GUARD(); |
22 | - sector_num - src_cur_offset, | 22 | BlockDriver *drv = bs->drv; |
23 | - n, &n, &file); | 23 | BdrvChild *c; |
24 | + if (s->target_has_backing) { | 24 | bool have_limits; |
25 | + ret = bdrv_get_block_status(blk_bs(s->src[src_cur]), | 25 | - Error *local_err = NULL; |
26 | + sector_num - src_cur_offset, | 26 | |
27 | + n, &n, &file); | 27 | memset(&bs->bl, 0, sizeof(bs->bl)); |
28 | + } else { | 28 | |
29 | + ret = bdrv_get_block_status_above(blk_bs(s->src[src_cur]), NULL, | 29 | @@ -XXX,XX +XXX,XX @@ void bdrv_refresh_limits(BlockDriverState *bs, Error **errp) |
30 | + sector_num - src_cur_offset, | 30 | QLIST_FOREACH(c, &bs->children, next) { |
31 | + n, &n, &file); | 31 | if (c->role & (BDRV_CHILD_DATA | BDRV_CHILD_FILTERED | BDRV_CHILD_COW)) |
32 | + } | 32 | { |
33 | if (ret < 0) { | 33 | - bdrv_refresh_limits(c->bs, &local_err); |
34 | return ret; | 34 | - if (local_err) { |
35 | } | 35 | - error_propagate(errp, local_err); |
36 | @@ -XXX,XX +XXX,XX @@ static int convert_iteration_sectors(ImgConvertState *s, int64_t sector_num) | 36 | + bdrv_refresh_limits(c->bs, errp); |
37 | s->status = BLK_ZERO; | 37 | + if (*errp) { |
38 | } else if (ret & BDRV_BLOCK_DATA) { | 38 | return; |
39 | s->status = BLK_DATA; | 39 | } |
40 | - } else if (!s->target_has_backing) { | 40 | bdrv_merge_limits(&bs->bl, &c->bs->bl); |
41 | - /* Without a target backing file we must copy over the contents of | ||
42 | - * the backing file as well. */ | ||
43 | - /* Check block status of the backing file chain to avoid | ||
44 | - * needlessly reading zeroes and limiting the iteration to the | ||
45 | - * buffer size */ | ||
46 | - ret = bdrv_get_block_status_above(blk_bs(s->src[src_cur]), NULL, | ||
47 | - sector_num - src_cur_offset, | ||
48 | - n, &n, &file); | ||
49 | - if (ret < 0) { | ||
50 | - return ret; | ||
51 | - } | ||
52 | - | ||
53 | - if (ret & BDRV_BLOCK_ZERO) { | ||
54 | - s->status = BLK_ZERO; | ||
55 | - } else { | ||
56 | - s->status = BLK_DATA; | ||
57 | - } | ||
58 | } else { | ||
59 | - s->status = BLK_BACKING_FILE; | ||
60 | + s->status = s->target_has_backing ? BLK_BACKING_FILE : BLK_DATA; | ||
61 | } | ||
62 | |||
63 | s->sector_next_status = sector_num + n; | ||
64 | -- | 41 | -- |
65 | 1.8.3.1 | 42 | 2.29.2 |
66 | 43 | ||
67 | 44 | diff view generated by jsdifflib |
1 | From: Fam Zheng <famz@redhat.com> | 1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> |
---|---|---|---|
2 | 2 | ||
3 | Reported by Coverity. We already use bs in bdrv_inc_in_flight before | 3 | Move bdrv_is_inserted() calls into callers. |
4 | checking for NULL. It is unnecessary as all callers pass non-NULL bs, so | ||
5 | drop it. | ||
6 | 4 | ||
7 | Signed-off-by: Fam Zheng <famz@redhat.com> | 5 | We are going to make bdrv_check_byte_request() a clean thing. |
8 | Reviewed-by: Max Reitz <mreitz@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> | ||
9 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 24 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
10 | --- | 25 | --- |
11 | block/io.c | 2 +- | 26 | block/io.c | 25 ++++++++++++------------- |
12 | 1 file changed, 1 insertion(+), 1 deletion(-) | 27 | 1 file changed, 12 insertions(+), 13 deletions(-) |
13 | 28 | ||
14 | diff --git a/block/io.c b/block/io.c | 29 | diff --git a/block/io.c b/block/io.c |
15 | index XXXXXXX..XXXXXXX 100644 | 30 | index XXXXXXX..XXXXXXX 100644 |
16 | --- a/block/io.c | 31 | --- a/block/io.c |
17 | +++ b/block/io.c | 32 | +++ b/block/io.c |
18 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs) | 33 | @@ -XXX,XX +XXX,XX @@ static bool coroutine_fn bdrv_wait_serialising_requests(BdrvTrackedRequest *self |
19 | 34 | return waited; | |
20 | bdrv_inc_in_flight(bs); | 35 | } |
21 | 36 | ||
22 | - if (!bs || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs) || | 37 | -static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset, |
23 | + if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs) || | 38 | - size_t size) |
24 | bdrv_is_sg(bs)) { | 39 | +static int bdrv_check_byte_request(int64_t offset, size_t size) |
25 | goto early_exit; | 40 | { |
41 | if (size > BDRV_REQUEST_MAX_BYTES) { | ||
42 | return -EIO; | ||
43 | } | ||
44 | |||
45 | - if (!bdrv_is_inserted(bs)) { | ||
46 | - return -ENOMEDIUM; | ||
47 | - } | ||
48 | - | ||
49 | if (offset < 0) { | ||
50 | return -EIO; | ||
51 | } | ||
52 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_preadv_part(BdrvChild *child, | ||
53 | |||
54 | trace_bdrv_co_preadv(bs, offset, bytes, flags); | ||
55 | |||
56 | - ret = bdrv_check_byte_request(bs, offset, bytes); | ||
57 | + if (!bdrv_is_inserted(bs)) { | ||
58 | + return -ENOMEDIUM; | ||
59 | + } | ||
60 | + | ||
61 | + ret = bdrv_check_byte_request(offset, bytes); | ||
62 | if (ret < 0) { | ||
63 | return ret; | ||
64 | } | ||
65 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwritev_part(BdrvChild *child, | ||
66 | |||
67 | trace_bdrv_co_pwritev(child->bs, offset, bytes, flags); | ||
68 | |||
69 | - if (!bs->drv) { | ||
70 | + if (!bdrv_is_inserted(bs)) { | ||
71 | return -ENOMEDIUM; | ||
72 | } | ||
73 | |||
74 | - ret = bdrv_check_byte_request(bs, offset, bytes); | ||
75 | + ret = bdrv_check_byte_request(offset, bytes); | ||
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; | ||
26 | } | 104 | } |
27 | -- | 105 | -- |
28 | 1.8.3.1 | 106 | 2.29.2 |
29 | 107 | ||
30 | 108 | diff view generated by jsdifflib |
1 | From: Max Reitz <mreitz@redhat.com> | 1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> |
---|---|---|---|
2 | 2 | ||
3 | Add an Error parameter to the block drivers' bdrv_truncate() interface. | 3 | We are going to modify block layer to work with 64bit requests. And |
4 | If a block driver does not set this in case of an error, the generic | 4 | first step is moving to int64_t type for both offset and bytes |
5 | bdrv_truncate() implementation will do so. | 5 | arguments in all block request related functions. |
6 | 6 | ||
7 | Where it is obvious, this patch also makes some block drivers set this | 7 | It's mostly safe (when widening signed or unsigned int to int64_t), but |
8 | value. | 8 | switching from uint64_t is questionable. |
9 | 9 | ||
10 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 10 | So, let's first establish the set of requests we want to work with. |
11 | Message-id: 20170328205129.15138-4-mreitz@redhat.com | 11 | First signed int64_t should be enough, as off_t is signed anyway. Then, |
12 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | 12 | obviously offset + bytes should not overflow. |
13 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 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> | ||
85 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
14 | --- | 86 | --- |
15 | block.c | 4 ++-- | 87 | include/block/block.h | 10 +++++++ |
16 | block/blkdebug.c | 4 ++-- | 88 | include/block/block_int.h | 8 ++++++ |
17 | block/crypto.c | 5 +++-- | 89 | block.c | 17 +++++++++++- |
18 | block/file-posix.c | 2 +- | 90 | block/file-posix.c | 6 ++--- |
19 | block/file-win32.c | 6 +++--- | 91 | block/io.c | 51 +++++++++++++++++++++++++++++------- |
20 | block/gluster.c | 3 ++- | 92 | tests/test-write-threshold.c | 4 +++ |
21 | block/iscsi.c | 4 ++-- | 93 | tests/qemu-iotests/206 | 2 +- |
22 | block/nfs.c | 2 +- | 94 | tests/qemu-iotests/206.out | 6 +++++ |
23 | block/qcow2.c | 8 ++++---- | 95 | 8 files changed, 90 insertions(+), 14 deletions(-) |
24 | block/qed.c | 2 +- | 96 | |
25 | block/raw-format.c | 4 ++-- | 97 | diff --git a/include/block/block.h b/include/block/block.h |
26 | block/rbd.c | 2 +- | 98 | index XXXXXXX..XXXXXXX 100644 |
27 | block/sheepdog.c | 14 ++++++-------- | 99 | --- a/include/block/block.h |
28 | include/block/block_int.h | 2 +- | 100 | +++ b/include/block/block.h |
29 | 14 files changed, 31 insertions(+), 31 deletions(-) | 101 | @@ -XXX,XX +XXX,XX @@ typedef struct HDGeometry { |
30 | 102 | INT_MAX >> BDRV_SECTOR_BITS) | |
103 | #define BDRV_REQUEST_MAX_BYTES (BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS) | ||
104 | |||
105 | +/* | ||
106 | + * We want allow aligning requests and disk length up to any 32bit alignment | ||
107 | + * and don't afraid of overflow. | ||
108 | + * To achieve it, and in the same time use some pretty number as maximum disk | ||
109 | + * size, let's define maximum "length" (a limit for any offset/bytes request and | ||
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; | ||
31 | diff --git a/block.c b/block.c | 144 | diff --git a/block.c b/block.c |
32 | index XXXXXXX..XXXXXXX 100644 | 145 | index XXXXXXX..XXXXXXX 100644 |
33 | --- a/block.c | 146 | --- a/block.c |
34 | +++ b/block.c | 147 | +++ b/block.c |
35 | @@ -XXX,XX +XXX,XX @@ int bdrv_truncate(BdrvChild *child, int64_t offset, Error **errp) | 148 | @@ -XXX,XX +XXX,XX @@ int refresh_total_sectors(BlockDriverState *bs, int64_t hint) |
36 | return -EACCES; | 149 | } |
37 | } | 150 | |
38 | 151 | bs->total_sectors = hint; | |
39 | - ret = drv->bdrv_truncate(bs, offset); | 152 | + |
40 | + ret = drv->bdrv_truncate(bs, offset, errp); | 153 | + if (bs->total_sectors * BDRV_SECTOR_SIZE > BDRV_MAX_LENGTH) { |
41 | if (ret == 0) { | 154 | + return -EFBIG; |
42 | ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS); | 155 | + } |
43 | bdrv_dirty_bitmap_truncate(bs); | 156 | + |
44 | bdrv_parent_cb_resize(bs); | 157 | return 0; |
45 | ++bs->write_gen; | ||
46 | - } else { | ||
47 | + } else if (errp && !*errp) { | ||
48 | error_setg_errno(errp, -ret, "Failed to resize image"); | ||
49 | } | ||
50 | return ret; | ||
51 | diff --git a/block/blkdebug.c b/block/blkdebug.c | ||
52 | index XXXXXXX..XXXXXXX 100644 | ||
53 | --- a/block/blkdebug.c | ||
54 | +++ b/block/blkdebug.c | ||
55 | @@ -XXX,XX +XXX,XX @@ static int64_t blkdebug_getlength(BlockDriverState *bs) | ||
56 | return bdrv_getlength(bs->file->bs); | ||
57 | } | 158 | } |
58 | 159 | ||
59 | -static int blkdebug_truncate(BlockDriverState *bs, int64_t offset) | 160 | @@ -XXX,XX +XXX,XX @@ void bdrv_get_backing_filename(BlockDriverState *bs, |
60 | +static int blkdebug_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | 161 | |
162 | int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) | ||
61 | { | 163 | { |
62 | - return bdrv_truncate(bs->file, offset, NULL); | 164 | + int ret; |
63 | + return bdrv_truncate(bs->file, offset, errp); | 165 | BlockDriver *drv = bs->drv; |
166 | /* if bs->drv == NULL, bs is closed, so there's nothing to do here */ | ||
167 | if (!drv) { | ||
168 | @@ -XXX,XX +XXX,XX @@ int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) | ||
169 | return -ENOTSUP; | ||
170 | } | ||
171 | memset(bdi, 0, sizeof(*bdi)); | ||
172 | - return drv->bdrv_get_info(bs, bdi); | ||
173 | + ret = drv->bdrv_get_info(bs, bdi); | ||
174 | + if (ret < 0) { | ||
175 | + return ret; | ||
176 | + } | ||
177 | + | ||
178 | + if (bdi->cluster_size > BDRV_MAX_ALIGNMENT) { | ||
179 | + return -EINVAL; | ||
180 | + } | ||
181 | + | ||
182 | + return 0; | ||
64 | } | 183 | } |
65 | 184 | ||
66 | static void blkdebug_refresh_filename(BlockDriverState *bs, QDict *options) | 185 | ImageInfoSpecific *bdrv_get_specific_info(BlockDriverState *bs, |
67 | diff --git a/block/crypto.c b/block/crypto.c | ||
68 | index XXXXXXX..XXXXXXX 100644 | ||
69 | --- a/block/crypto.c | ||
70 | +++ b/block/crypto.c | ||
71 | @@ -XXX,XX +XXX,XX @@ static int block_crypto_create_generic(QCryptoBlockFormat format, | ||
72 | return ret; | ||
73 | } | ||
74 | |||
75 | -static int block_crypto_truncate(BlockDriverState *bs, int64_t offset) | ||
76 | +static int block_crypto_truncate(BlockDriverState *bs, int64_t offset, | ||
77 | + Error **errp) | ||
78 | { | ||
79 | BlockCrypto *crypto = bs->opaque; | ||
80 | size_t payload_offset = | ||
81 | @@ -XXX,XX +XXX,XX @@ static int block_crypto_truncate(BlockDriverState *bs, int64_t offset) | ||
82 | |||
83 | offset += payload_offset; | ||
84 | |||
85 | - return bdrv_truncate(bs->file, offset, NULL); | ||
86 | + return bdrv_truncate(bs->file, offset, errp); | ||
87 | } | ||
88 | |||
89 | static void block_crypto_close(BlockDriverState *bs) | ||
90 | diff --git a/block/file-posix.c b/block/file-posix.c | 186 | diff --git a/block/file-posix.c b/block/file-posix.c |
91 | index XXXXXXX..XXXXXXX 100644 | 187 | index XXXXXXX..XXXXXXX 100644 |
92 | --- a/block/file-posix.c | 188 | --- a/block/file-posix.c |
93 | +++ b/block/file-posix.c | 189 | +++ b/block/file-posix.c |
94 | @@ -XXX,XX +XXX,XX @@ static void raw_close(BlockDriverState *bs) | 190 | @@ -XXX,XX +XXX,XX @@ raw_do_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int bytes, |
191 | #ifdef CONFIG_FALLOCATE | ||
192 | if (offset + bytes > bs->total_sectors * BDRV_SECTOR_SIZE) { | ||
193 | BdrvTrackedRequest *req; | ||
194 | - uint64_t end; | ||
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"); | ||
95 | } | 225 | } |
96 | } | 226 | } |
97 | 227 | ||
98 | -static int raw_truncate(BlockDriverState *bs, int64_t offset) | 228 | @@ -XXX,XX +XXX,XX @@ static bool coroutine_fn bdrv_wait_serialising_requests(BdrvTrackedRequest *self |
99 | +static int raw_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | 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) | ||
100 | { | 234 | { |
101 | BDRVRawState *s = bs->opaque; | 235 | - if (size > BDRV_REQUEST_MAX_BYTES) { |
102 | struct stat st; | 236 | + if (offset < 0 || bytes < 0) { |
103 | diff --git a/block/file-win32.c b/block/file-win32.c | ||
104 | index XXXXXXX..XXXXXXX 100644 | ||
105 | --- a/block/file-win32.c | ||
106 | +++ b/block/file-win32.c | ||
107 | @@ -XXX,XX +XXX,XX @@ static void raw_close(BlockDriverState *bs) | ||
108 | } | ||
109 | } | ||
110 | |||
111 | -static int raw_truncate(BlockDriverState *bs, int64_t offset) | ||
112 | +static int raw_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | ||
113 | { | ||
114 | BDRVRawState *s = bs->opaque; | ||
115 | LONG low, high; | ||
116 | @@ -XXX,XX +XXX,XX @@ static int raw_truncate(BlockDriverState *bs, int64_t offset) | ||
117 | */ | ||
118 | dwPtrLow = SetFilePointer(s->hfile, low, &high, FILE_BEGIN); | ||
119 | if (dwPtrLow == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) { | ||
120 | - fprintf(stderr, "SetFilePointer error: %lu\n", GetLastError()); | ||
121 | + error_setg_win32(errp, GetLastError(), "SetFilePointer error"); | ||
122 | return -EIO; | 237 | return -EIO; |
123 | } | 238 | } |
124 | if (SetEndOfFile(s->hfile) == 0) { | 239 | |
125 | - fprintf(stderr, "SetEndOfFile error: %lu\n", GetLastError()); | 240 | - if (offset < 0) { |
126 | + error_setg_win32(errp, GetLastError(), "SetEndOfFile error"); | 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) { | ||
127 | return -EIO; | 260 | return -EIO; |
128 | } | 261 | } |
129 | return 0; | 262 | |
130 | diff --git a/block/gluster.c b/block/gluster.c | 263 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_preadv_part(BdrvChild *child, |
131 | index XXXXXXX..XXXXXXX 100644 | 264 | return -ENOMEDIUM; |
132 | --- a/block/gluster.c | 265 | } |
133 | +++ b/block/gluster.c | 266 | |
134 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qemu_gluster_co_rw(BlockDriverState *bs, | 267 | - ret = bdrv_check_byte_request(offset, bytes); |
135 | return acb.ret; | 268 | + ret = bdrv_check_request32(offset, bytes); |
136 | } | 269 | if (ret < 0) { |
137 | 270 | return ret; | |
138 | -static int qemu_gluster_truncate(BlockDriverState *bs, int64_t offset) | 271 | } |
139 | +static int qemu_gluster_truncate(BlockDriverState *bs, int64_t offset, | 272 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwritev_part(BdrvChild *child, |
140 | + Error **errp) | 273 | return -ENOMEDIUM; |
141 | { | 274 | } |
142 | int ret; | 275 | |
143 | BDRVGlusterState *s = bs->opaque; | 276 | - ret = bdrv_check_byte_request(offset, bytes); |
144 | diff --git a/block/iscsi.c b/block/iscsi.c | 277 | + ret = bdrv_check_request32(offset, bytes); |
145 | index XXXXXXX..XXXXXXX 100644 | 278 | if (ret < 0) { |
146 | --- a/block/iscsi.c | 279 | return ret; |
147 | +++ b/block/iscsi.c | 280 | } |
148 | @@ -XXX,XX +XXX,XX @@ static void iscsi_reopen_commit(BDRVReopenState *reopen_state) | 281 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset, |
149 | } | 282 | return -EPERM; |
150 | } | 283 | } |
151 | 284 | ||
152 | -static int iscsi_truncate(BlockDriverState *bs, int64_t offset) | 285 | - if (offset < 0 || bytes < 0 || bytes > INT64_MAX - offset) { |
153 | +static int iscsi_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | 286 | - return -EIO; |
154 | { | 287 | + ret = bdrv_check_request(offset, bytes); |
155 | IscsiLun *iscsilun = bs->opaque; | 288 | + if (ret < 0) { |
156 | Error *local_err = NULL; | 289 | + return ret; |
157 | @@ -XXX,XX +XXX,XX @@ static int iscsi_truncate(BlockDriverState *bs, int64_t offset) | 290 | } |
158 | 291 | ||
159 | iscsi_readcapacity_sync(iscsilun, &local_err); | 292 | /* Do nothing if disabled. */ |
160 | if (local_err != NULL) { | 293 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_copy_range_internal( |
161 | - error_free(local_err); | 294 | if (!dst || !dst->bs || !bdrv_is_inserted(dst->bs)) { |
162 | + error_propagate(errp, local_err); | 295 | return -ENOMEDIUM; |
163 | return -EIO; | 296 | } |
164 | } | 297 | - ret = bdrv_check_byte_request(dst_offset, bytes); |
165 | 298 | + ret = bdrv_check_request32(dst_offset, bytes); | |
166 | diff --git a/block/nfs.c b/block/nfs.c | 299 | if (ret) { |
167 | index XXXXXXX..XXXXXXX 100644 | 300 | return ret; |
168 | --- a/block/nfs.c | 301 | } |
169 | +++ b/block/nfs.c | 302 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_copy_range_internal( |
170 | @@ -XXX,XX +XXX,XX @@ static int64_t nfs_get_allocated_file_size(BlockDriverState *bs) | 303 | if (!src || !src->bs || !bdrv_is_inserted(src->bs)) { |
171 | return (task.ret < 0 ? task.ret : st.st_blocks * 512); | 304 | return -ENOMEDIUM; |
172 | } | 305 | } |
173 | 306 | - ret = bdrv_check_byte_request(src_offset, bytes); | |
174 | -static int nfs_file_truncate(BlockDriverState *bs, int64_t offset) | 307 | + ret = bdrv_check_request32(src_offset, bytes); |
175 | +static int nfs_file_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | 308 | if (ret) { |
176 | { | 309 | return ret; |
177 | NFSClient *client = bs->opaque; | 310 | } |
178 | return nfs_ftruncate(client->context, client->fh, offset); | 311 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact, |
179 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
180 | index XXXXXXX..XXXXXXX 100644 | ||
181 | --- a/block/qcow2.c | ||
182 | +++ b/block/qcow2.c | ||
183 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_pdiscard(BlockDriverState *bs, | ||
184 | return ret; | ||
185 | } | ||
186 | |||
187 | -static int qcow2_truncate(BlockDriverState *bs, int64_t offset) | ||
188 | +static int qcow2_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | ||
189 | { | ||
190 | BDRVQcow2State *s = bs->opaque; | ||
191 | int64_t new_l1_size; | ||
192 | int ret; | ||
193 | |||
194 | if (offset & 511) { | ||
195 | - error_report("The new size must be a multiple of 512"); | ||
196 | + error_setg(errp, "The new size must be a multiple of 512"); | ||
197 | return -EINVAL; | 312 | return -EINVAL; |
198 | } | 313 | } |
199 | 314 | ||
200 | /* cannot proceed if image has snapshots */ | 315 | + ret = bdrv_check_request(offset, 0); |
201 | if (s->nb_snapshots) { | 316 | + if (ret < 0) { |
202 | - error_report("Can't resize an image which has snapshots"); | 317 | + error_setg(errp, "Required too big image size, it must be not greater " |
203 | + error_setg(errp, "Can't resize an image which has snapshots"); | 318 | + "than %" PRId64, BDRV_MAX_LENGTH); |
204 | return -ENOTSUP; | 319 | + return ret; |
205 | } | 320 | + } |
206 | 321 | + | |
207 | /* shrinking is currently not supported */ | 322 | old_size = bdrv_getlength(bs); |
208 | if (offset < bs->total_sectors * 512) { | 323 | if (old_size < 0) { |
209 | - error_report("qcow2 doesn't support shrinking images yet"); | 324 | error_setg_errno(errp, -old_size, "Failed to get old image size"); |
210 | + error_setg(errp, "qcow2 doesn't support shrinking images yet"); | 325 | diff --git a/tests/test-write-threshold.c b/tests/test-write-threshold.c |
211 | return -ENOTSUP; | 326 | index XXXXXXX..XXXXXXX 100644 |
212 | } | 327 | --- a/tests/test-write-threshold.c |
213 | 328 | +++ b/tests/test-write-threshold.c | |
214 | diff --git a/block/qed.c b/block/qed.c | 329 | @@ -XXX,XX +XXX,XX @@ static void test_threshold_not_trigger(void) |
215 | index XXXXXXX..XXXXXXX 100644 | 330 | req.offset = 1024; |
216 | --- a/block/qed.c | 331 | req.bytes = 1024; |
217 | +++ b/block/qed.c | 332 | |
218 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs, | 333 | + assert(bdrv_check_request(req.offset, req.bytes) == 0); |
219 | return cb.ret; | 334 | + |
220 | } | 335 | bdrv_write_threshold_set(&bs, threshold); |
221 | 336 | amount = bdrv_write_threshold_exceeded(&bs, &req); | |
222 | -static int bdrv_qed_truncate(BlockDriverState *bs, int64_t offset) | 337 | g_assert_cmpuint(amount, ==, 0); |
223 | +static int bdrv_qed_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | 338 | @@ -XXX,XX +XXX,XX @@ static void test_threshold_trigger(void) |
224 | { | 339 | req.offset = (4 * 1024 * 1024) - 1024; |
225 | BDRVQEDState *s = bs->opaque; | 340 | req.bytes = 2 * 1024; |
226 | uint64_t old_image_size; | 341 | |
227 | diff --git a/block/raw-format.c b/block/raw-format.c | 342 | + assert(bdrv_check_request(req.offset, req.bytes) == 0); |
228 | index XXXXXXX..XXXXXXX 100644 | 343 | + |
229 | --- a/block/raw-format.c | 344 | bdrv_write_threshold_set(&bs, threshold); |
230 | +++ b/block/raw-format.c | 345 | amount = bdrv_write_threshold_exceeded(&bs, &req); |
231 | @@ -XXX,XX +XXX,XX @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp) | 346 | g_assert_cmpuint(amount, >=, 1024); |
232 | } | 347 | diff --git a/tests/qemu-iotests/206 b/tests/qemu-iotests/206 |
233 | } | 348 | index XXXXXXX..XXXXXXX 100755 |
234 | 349 | --- a/tests/qemu-iotests/206 | |
235 | -static int raw_truncate(BlockDriverState *bs, int64_t offset) | 350 | +++ b/tests/qemu-iotests/206 |
236 | +static int raw_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | 351 | @@ -XXX,XX +XXX,XX @@ with iotests.FilePath('t.qcow2') as disk_path, \ |
237 | { | 352 | |
238 | BDRVRawState *s = bs->opaque; | 353 | vm.launch() |
239 | 354 | for size in [ 1234, 18446744073709551104, 9223372036854775808, | |
240 | @@ -XXX,XX +XXX,XX @@ static int raw_truncate(BlockDriverState *bs, int64_t offset) | 355 | - 9223372036854775296 ]: |
241 | 356 | + 9223372036854775296, 9223372035781033984 ]: | |
242 | s->size = offset; | 357 | vm.blockdev_create({ 'driver': imgfmt, |
243 | offset += s->offset; | 358 | 'file': 'node0', |
244 | - return bdrv_truncate(bs->file, offset, NULL); | 359 | 'size': size }) |
245 | + return bdrv_truncate(bs->file, offset, errp); | 360 | diff --git a/tests/qemu-iotests/206.out b/tests/qemu-iotests/206.out |
246 | } | 361 | index XXXXXXX..XXXXXXX 100644 |
247 | 362 | --- a/tests/qemu-iotests/206.out | |
248 | static int raw_media_changed(BlockDriverState *bs) | 363 | +++ b/tests/qemu-iotests/206.out |
249 | diff --git a/block/rbd.c b/block/rbd.c | 364 | @@ -XXX,XX +XXX,XX @@ Job failed: Could not resize image: Image size cannot be negative |
250 | index XXXXXXX..XXXXXXX 100644 | 365 | |
251 | --- a/block/rbd.c | 366 | {"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "qcow2", "file": "node0", "size": 9223372036854775296}}} |
252 | +++ b/block/rbd.c | 367 | {"return": {}} |
253 | @@ -XXX,XX +XXX,XX @@ static int64_t qemu_rbd_getlength(BlockDriverState *bs) | 368 | +Job failed: Could not resize image: Required too big image size, it must be not greater than 9223372035781033984 |
254 | return info.size; | 369 | +{"execute": "job-dismiss", "arguments": {"id": "job0"}} |
255 | } | 370 | +{"return": {}} |
256 | 371 | + | |
257 | -static int qemu_rbd_truncate(BlockDriverState *bs, int64_t offset) | 372 | +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "qcow2", "file": "node0", "size": 9223372035781033984}}} |
258 | +static int qemu_rbd_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | 373 | +{"return": {}} |
259 | { | 374 | Job failed: Could not resize image: Failed to grow the L1 table: File too large |
260 | BDRVRBDState *s = bs->opaque; | 375 | {"execute": "job-dismiss", "arguments": {"id": "job0"}} |
261 | int r; | 376 | {"return": {}} |
262 | diff --git a/block/sheepdog.c b/block/sheepdog.c | ||
263 | index XXXXXXX..XXXXXXX 100644 | ||
264 | --- a/block/sheepdog.c | ||
265 | +++ b/block/sheepdog.c | ||
266 | @@ -XXX,XX +XXX,XX @@ static int64_t sd_getlength(BlockDriverState *bs) | ||
267 | return s->inode.vdi_size; | ||
268 | } | ||
269 | |||
270 | -static int sd_truncate(BlockDriverState *bs, int64_t offset) | ||
271 | +static int sd_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | ||
272 | { | ||
273 | - Error *local_err = NULL; | ||
274 | BDRVSheepdogState *s = bs->opaque; | ||
275 | int ret, fd; | ||
276 | unsigned int datalen; | ||
277 | @@ -XXX,XX +XXX,XX @@ static int sd_truncate(BlockDriverState *bs, int64_t offset) | ||
278 | |||
279 | max_vdi_size = (UINT64_C(1) << s->inode.block_size_shift) * MAX_DATA_OBJS; | ||
280 | if (offset < s->inode.vdi_size) { | ||
281 | - error_report("shrinking is not supported"); | ||
282 | + error_setg(errp, "shrinking is not supported"); | ||
283 | return -EINVAL; | ||
284 | } else if (offset > max_vdi_size) { | ||
285 | - error_report("too big image size"); | ||
286 | + error_setg(errp, "too big image size"); | ||
287 | return -EINVAL; | ||
288 | } | ||
289 | |||
290 | - fd = connect_to_sdog(s, &local_err); | ||
291 | + fd = connect_to_sdog(s, errp); | ||
292 | if (fd < 0) { | ||
293 | - error_report_err(local_err); | ||
294 | return fd; | ||
295 | } | ||
296 | |||
297 | @@ -XXX,XX +XXX,XX @@ static int sd_truncate(BlockDriverState *bs, int64_t offset) | ||
298 | close(fd); | ||
299 | |||
300 | if (ret < 0) { | ||
301 | - error_report("failed to update an inode."); | ||
302 | + error_setg_errno(errp, -ret, "failed to update an inode"); | ||
303 | } | ||
304 | |||
305 | return ret; | ||
306 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int sd_co_writev(BlockDriverState *bs, int64_t sector_num, | ||
307 | BDRVSheepdogState *s = bs->opaque; | ||
308 | |||
309 | if (offset > s->inode.vdi_size) { | ||
310 | - ret = sd_truncate(bs, offset); | ||
311 | + ret = sd_truncate(bs, offset, NULL); | ||
312 | if (ret < 0) { | ||
313 | return ret; | ||
314 | } | ||
315 | diff --git a/include/block/block_int.h b/include/block/block_int.h | ||
316 | index XXXXXXX..XXXXXXX 100644 | ||
317 | --- a/include/block/block_int.h | ||
318 | +++ b/include/block/block_int.h | ||
319 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
320 | int coroutine_fn (*bdrv_co_flush_to_os)(BlockDriverState *bs); | ||
321 | |||
322 | const char *protocol_name; | ||
323 | - int (*bdrv_truncate)(BlockDriverState *bs, int64_t offset); | ||
324 | + int (*bdrv_truncate)(BlockDriverState *bs, int64_t offset, Error **errp); | ||
325 | |||
326 | int64_t (*bdrv_getlength)(BlockDriverState *bs); | ||
327 | bool has_variable_length; | ||
328 | -- | 377 | -- |
329 | 1.8.3.1 | 378 | 2.29.2 |
330 | 379 | ||
331 | 380 | diff view generated by jsdifflib |
1 | From: "Denis V. Lunev" <den@openvz.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 | As long as BDRV_O_INACTIVE is set, the image file is only opened so we | 5 | Cc: qemu-stable@nongnu.org |
4 | have a file descriptor for it. We're definitely not supposed to modify | 6 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
5 | the image, it's still owned by the migration source. | 7 | Message-Id: <20201203172311.68232-2-kwolf@redhat.com> |
8 | Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
9 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
10 | --- | ||
11 | blockdev.c | 9 ++++----- | ||
12 | 1 file changed, 4 insertions(+), 5 deletions(-) | ||
6 | 13 | ||
7 | This commit is an addition to 09e0c771 but the assert() is added to | 14 | diff --git a/blockdev.c b/blockdev.c |
8 | bdrv_truncate(). | ||
9 | |||
10 | Signed-off-by: Denis V. Lunev <den@openvz.org> | ||
11 | CC: Kevin Wolf <kwolf@redhat.com> | ||
12 | CC: Max Reitz <mreitz@redhat.com> | ||
13 | Message-id: 1491405505-31620-3-git-send-email-den@openvz.org | ||
14 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
15 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
16 | --- | ||
17 | block.c | 2 ++ | ||
18 | 1 file changed, 2 insertions(+) | ||
19 | |||
20 | diff --git a/block.c b/block.c | ||
21 | index XXXXXXX..XXXXXXX 100644 | 15 | index XXXXXXX..XXXXXXX 100644 |
22 | --- a/block.c | 16 | --- a/blockdev.c |
23 | +++ b/block.c | 17 | +++ b/blockdev.c |
24 | @@ -XXX,XX +XXX,XX @@ int bdrv_truncate(BdrvChild *child, int64_t offset, Error **errp) | 18 | @@ -XXX,XX +XXX,XX @@ void coroutine_fn qmp_block_resize(bool has_device, const char *device, |
25 | return -EACCES; | 19 | int64_t size, Error **errp) |
20 | { | ||
21 | Error *local_err = NULL; | ||
22 | - BlockBackend *blk = NULL; | ||
23 | + BlockBackend *blk; | ||
24 | BlockDriverState *bs; | ||
25 | AioContext *old_ctx; | ||
26 | |||
27 | @@ -XXX,XX +XXX,XX @@ void coroutine_fn qmp_block_resize(bool has_device, const char *device, | ||
28 | |||
29 | if (size < 0) { | ||
30 | error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "size", "a >0 size"); | ||
31 | - goto out; | ||
32 | + return; | ||
26 | } | 33 | } |
27 | 34 | ||
28 | + assert(!(bs->open_flags & BDRV_O_INACTIVE)); | 35 | if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_RESIZE, NULL)) { |
29 | + | 36 | error_setg(errp, QERR_DEVICE_IN_USE, device); |
30 | ret = drv->bdrv_truncate(bs, offset, errp); | 37 | - goto out; |
31 | if (ret == 0) { | 38 | + return; |
32 | ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS); | 39 | } |
40 | |||
41 | blk = blk_new_with_bs(bs, BLK_PERM_RESIZE, BLK_PERM_ALL, errp); | ||
42 | if (!blk) { | ||
43 | - goto out; | ||
44 | + return; | ||
45 | } | ||
46 | |||
47 | bdrv_drained_begin(bs); | ||
48 | @@ -XXX,XX +XXX,XX @@ void coroutine_fn qmp_block_resize(bool has_device, const char *device, | ||
49 | bdrv_co_leave(bs, old_ctx); | ||
50 | bdrv_drained_end(bs); | ||
51 | |||
52 | -out: | ||
53 | bdrv_co_lock(bs); | ||
54 | blk_unref(blk); | ||
55 | bdrv_co_unlock(bs); | ||
33 | -- | 56 | -- |
34 | 1.8.3.1 | 57 | 2.29.2 |
35 | 58 | ||
36 | 59 | diff view generated by jsdifflib |
1 | From: Krzysztof Kozlowski <krzk@kernel.org> | 1 | The drain functions assume that we hold the AioContext lock of the |
---|---|---|---|
2 | drained block node. Make sure to actually take the lock. | ||
2 | 3 | ||
3 | blk_name() is not modifying data passed to it through pointer and it | 4 | Cc: qemu-stable@nongnu.org |
4 | returns also a pointer to const so the argument can be made const for | 5 | Fixes: eb94b81a94bce112e6b206df846c1551aaf6cab6 |
5 | code safeness. | 6 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
6 | 7 | Message-Id: <20201203172311.68232-3-kwolf@redhat.com> | |
7 | Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org> | 8 | Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> |
8 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | ||
9 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 9 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
10 | --- | 10 | --- |
11 | block/block-backend.c | 2 +- | 11 | blockdev.c | 5 ++++- |
12 | include/sysemu/block-backend.h | 2 +- | 12 | 1 file changed, 4 insertions(+), 1 deletion(-) |
13 | 2 files changed, 2 insertions(+), 2 deletions(-) | ||
14 | 13 | ||
15 | diff --git a/block/block-backend.c b/block/block-backend.c | 14 | diff --git a/blockdev.c b/blockdev.c |
16 | index XXXXXXX..XXXXXXX 100644 | 15 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/block/block-backend.c | 16 | --- a/blockdev.c |
18 | +++ b/block/block-backend.c | 17 | +++ b/blockdev.c |
19 | @@ -XXX,XX +XXX,XX @@ void monitor_remove_blk(BlockBackend *blk) | 18 | @@ -XXX,XX +XXX,XX @@ void coroutine_fn qmp_block_resize(bool has_device, const char *device, |
20 | * Return @blk's name, a non-null string. | 19 | return; |
21 | * Returns an empty string iff @blk is not referenced by the monitor. | 20 | } |
22 | */ | 21 | |
23 | -const char *blk_name(BlockBackend *blk) | 22 | + bdrv_co_lock(bs); |
24 | +const char *blk_name(const BlockBackend *blk) | 23 | bdrv_drained_begin(bs); |
25 | { | 24 | + bdrv_co_unlock(bs); |
26 | return blk->name ?: ""; | 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); | ||
27 | } | 35 | } |
28 | diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h | ||
29 | index XXXXXXX..XXXXXXX 100644 | ||
30 | --- a/include/sysemu/block-backend.h | ||
31 | +++ b/include/sysemu/block-backend.h | ||
32 | @@ -XXX,XX +XXX,XX @@ int blk_get_refcnt(BlockBackend *blk); | ||
33 | void blk_ref(BlockBackend *blk); | ||
34 | void blk_unref(BlockBackend *blk); | ||
35 | void blk_remove_all_bs(void); | ||
36 | -const char *blk_name(BlockBackend *blk); | ||
37 | +const char *blk_name(const BlockBackend *blk); | ||
38 | BlockBackend *blk_by_name(const char *name); | ||
39 | BlockBackend *blk_next(BlockBackend *blk); | ||
40 | bool monitor_add_blk(BlockBackend *blk, const char *name, Error **errp); | ||
41 | -- | 36 | -- |
42 | 1.8.3.1 | 37 | 2.29.2 |
43 | 38 | ||
44 | 39 | diff view generated by jsdifflib |
1 | From: "Denis V. Lunev" <den@openvz.org> | 1 | If bdrv_co_yield_to_drain() is called for draining a block node that |
---|---|---|---|
2 | runs in a different AioContext, it keeps that AioContext locked while it | ||
3 | yields and schedules a BH in the AioContext to do the actual drain. | ||
2 | 4 | ||
3 | tail_padding_bytes is calculated wrong. F.e. for | 5 | As long as executing the BH is the very next thing that the event loop |
4 | offset = 0 | 6 | of the node's AioContext does, this actually happens to work, but when |
5 | bytes = 2048 | 7 | it tries to execute something else that wants to take the AioContext |
6 | align = 512 | 8 | lock, it will deadlock. (In the bug report, this other thing is a |
7 | we will have tail_padding_bytes = 512 which is definitely wrong. The patch | 9 | virtio-scsi device running virtio_scsi_data_plane_handle_cmd().) |
8 | fixes that arithmetics. | ||
9 | 10 | ||
10 | Fortunately this problem is harmless, we will have 1 extra allocation and | 11 | Instead, always drop the AioContext lock across the yield and reacquire |
11 | free thus there is no need to put this into stable. The problem is here | 12 | it only when the coroutine is reentered. The BH needs to unconditionally |
12 | from the very beginning. | 13 | take the lock for itself now. |
13 | 14 | ||
14 | Signed-off-by: Denis V. Lunev <den@openvz.org> | 15 | This fixes the 'block_resize' QMP command on a block node that runs in |
15 | CC: Stefan Hajnoczi <stefanha@redhat.com> | 16 | an iothread. |
16 | CC: Fam Zheng <famz@redhat.com> | 17 | |
17 | Reviewed-by: Eric Blake <eblake@redhat.com> | 18 | Cc: qemu-stable@nongnu.org |
19 | Fixes: eb94b81a94bce112e6b206df846c1551aaf6cab6 | ||
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> | ||
18 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 24 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
19 | --- | 25 | --- |
20 | block/io.c | 2 +- | 26 | block/io.c | 41 ++++++++++++++++++++++++----------------- |
21 | 1 file changed, 1 insertion(+), 1 deletion(-) | 27 | 1 file changed, 24 insertions(+), 17 deletions(-) |
22 | 28 | ||
23 | diff --git a/block/io.c b/block/io.c | 29 | diff --git a/block/io.c b/block/io.c |
24 | index XXXXXXX..XXXXXXX 100644 | 30 | index XXXXXXX..XXXXXXX 100644 |
25 | --- a/block/io.c | 31 | --- a/block/io.c |
26 | +++ b/block/io.c | 32 | +++ b/block/io.c |
27 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_zero_pwritev(BdrvChild *child, | 33 | @@ -XXX,XX +XXX,XX @@ static void bdrv_co_drain_bh_cb(void *opaque) |
28 | int ret = 0; | 34 | |
29 | 35 | if (bs) { | |
30 | head_padding_bytes = offset & (align - 1); | 36 | AioContext *ctx = bdrv_get_aio_context(bs); |
31 | - tail_padding_bytes = align - ((offset + bytes) & (align - 1)); | 37 | - AioContext *co_ctx = qemu_coroutine_get_aio_context(co); |
32 | + tail_padding_bytes = (align - (offset + bytes)) & (align - 1); | 38 | - |
33 | 39 | - /* | |
34 | 40 | - * When the coroutine yielded, the lock for its home context was | |
35 | assert(flags & BDRV_REQ_ZERO_WRITE); | 41 | - * released, so we need to re-acquire it here. If it explicitly |
42 | - * acquired a different context, the lock is still held and we don't | ||
43 | - * want to lock it a second time (or AIO_WAIT_WHILE() would hang). | ||
44 | - */ | ||
45 | - if (ctx == co_ctx) { | ||
46 | - aio_context_acquire(ctx); | ||
47 | - } | ||
48 | + aio_context_acquire(ctx); | ||
49 | bdrv_dec_in_flight(bs); | ||
50 | if (data->begin) { | ||
51 | assert(!data->drained_end_counter); | ||
52 | @@ -XXX,XX +XXX,XX @@ static void bdrv_co_drain_bh_cb(void *opaque) | ||
53 | data->ignore_bds_parents, | ||
54 | data->drained_end_counter); | ||
55 | } | ||
56 | - if (ctx == co_ctx) { | ||
57 | - aio_context_release(ctx); | ||
58 | - } | ||
59 | + aio_context_release(ctx); | ||
60 | } else { | ||
61 | assert(data->begin); | ||
62 | bdrv_drain_all_begin(); | ||
63 | @@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs, | ||
64 | int *drained_end_counter) | ||
65 | { | ||
66 | BdrvCoDrainData data; | ||
67 | + Coroutine *self = qemu_coroutine_self(); | ||
68 | + AioContext *ctx = bdrv_get_aio_context(bs); | ||
69 | + AioContext *co_ctx = qemu_coroutine_get_aio_context(self); | ||
70 | |||
71 | /* Calling bdrv_drain() from a BH ensures the current coroutine yields and | ||
72 | * other coroutines run if they were queued by aio_co_enter(). */ | ||
73 | |||
74 | assert(qemu_in_coroutine()); | ||
75 | data = (BdrvCoDrainData) { | ||
76 | - .co = qemu_coroutine_self(), | ||
77 | + .co = self, | ||
78 | .bs = bs, | ||
79 | .done = false, | ||
80 | .begin = begin, | ||
81 | @@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs, | ||
82 | if (bs) { | ||
83 | bdrv_inc_in_flight(bs); | ||
84 | } | ||
85 | - replay_bh_schedule_oneshot_event(bdrv_get_aio_context(bs), | ||
86 | - bdrv_co_drain_bh_cb, &data); | ||
87 | + | ||
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); | ||
109 | + } | ||
110 | } | ||
111 | |||
112 | void bdrv_do_drained_begin_quiesce(BlockDriverState *bs, | ||
36 | -- | 113 | -- |
37 | 1.8.3.1 | 114 | 2.29.2 |
38 | 115 | ||
39 | 116 | diff view generated by jsdifflib |