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) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block-info block-jinfo block-joinfo block-jobinfo block-jobs
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) iininfinfoinfo info binfo blinfo bloinfo blocinfo block
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) qququiquit
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) qququiquit
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) qququiquit
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) qququiquit
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) qququiquit
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) qququiquit
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) qququiquit
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) qququiquit
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) qququiquit
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) qququiquit
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) iininfinfoinfo info binfo blinfo bloinfo blocinfo block
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) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block finfo block fiinfo block filinfo block file
139
+(qemu) info block file
140
141
file: TEST_DIR/t.qcow2 (file)
142
Cache mode: writeback
143
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block binfo block bainfo block bacinfo block backinfo block backiinfo block backininfo block backing
144
+(qemu) info block backing
145
backing: TEST_DIR/t.qcow2.base (qcow2, read-only)
146
Cache mode: writeback, ignore flushes
147
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block binfo block bainfo block bacinfo block backinfo block backiinfo block backininfo block backinginfo block backing-info block backing-finfo block backing-fiinf
148
o block backing-filinfo block backing-file
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) qququiquit
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) iininfinfoinfo info binfo blinfo bloinfo blocinfo block
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) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block finfo block fiinfo block filinfo block file
165
+(qemu) info block file
166
167
file: TEST_DIR/t.qcow2 (file)
168
Cache mode: writeback
169
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block binfo block bainfo block bacinfo block backinfo block backiinfo block backininfo block backing
170
+(qemu) info block backing
171
backing: TEST_DIR/t.qcow2.base (qcow2, read-only)
172
Cache mode: writeback, ignore flushes
173
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block binfo block bainfo block bacinfo block backinfo block backiinfo block backininfo block backinginfo block backing-info block backing-finfo block backing-fiinf
174
o block backing-filinfo block backing-file
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) qququiquit
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) iininfinfoinfo info binfo blinfo bloinfo blocinfo block
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) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block finfo block fiinfo block filinfo block file
191
+(qemu) info block file
192
193
file: TEST_DIR/t.qcow2 (file)
194
Cache mode: writeback, ignore flushes
195
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block binfo block bainfo block bacinfo block backinfo block backiinfo block backininfo block backing
196
+(qemu) info block backing
197
backing: TEST_DIR/t.qcow2.base (qcow2, read-only)
198
Cache mode: writeback, ignore flushes
199
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block binfo block bainfo block bacinfo block backinfo block backiinfo block backininfo block backinginfo block backing-info block backing-finfo block backing-fiinf
200
o block backing-filinfo block backing-file
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) qququiquit
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) qququiquit
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) qququiquit
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) qququiquit
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) qququiquit
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) qququiquit
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) qququiquit
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) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqem
257
u-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0
258
qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
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) qququiquit
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) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqem
268
u-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0
269
qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
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) qququiquit
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) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqem
279
u-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0
280
qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
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) qququiquit
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) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqem
290
u-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0
291
qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
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) qququiquit
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) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqem
301
u-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0
302
qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
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) qququiquit
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) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqem
312
u-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0
313
qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
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) qququiquit
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) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqem
323
u-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0
324
qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
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) qququiquit
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) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqem
334
u-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0
335
qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
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) qququiquit
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) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqem
347
u-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0
348
qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
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) qququiquit
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) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqem
360
u-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x3qemu-io drive0 "write -P 0x33qemu-io drive0 "write -P 0x33 qemu-io drive0 "write -P 0x33 0
361
qemu-io drive0 "write -P 0x33 0 qemu-io drive0 "write -P 0x33 0 4qemu-io drive0 "write -P 0x33 0 4kqemu-io drive0 "write -P 0x33 0 4k"
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) ccocomcommcommicommitcommit commit dcommit drcommit dricommit drivcommit drivecommit drive0
366
-(qemu) qququiquit
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) iininfinfoinfo info binfo blinfo bloinfo blocinfo block
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) qququiquit
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) qququiquit
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) qququiquit
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) qququiquit
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) qququiquit
418
+(qemu) quit
419
420
Testing: -drive if=ide,media=cdrom
421
QEMU X.Y.Z monitor - type 'help' for more information
422
-(qemu) qququiquit
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
-qququiquit
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) qququiquit
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) qququiquit
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) qququiquit
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) qququiquit
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
-qququiquit
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
-qququiquit
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) qququiquit
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) qququiquit
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) qququiquit
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) qququiquit
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) qququiquit
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) qququiquit
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) qququiquit
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) qququiquit
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) qququiquit
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) qququiquit
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) iininfinfoinfo info binfo blinfo bloinfo blocinfo block
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) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block finfo block fiinfo block filinfo block file
543
+(qemu) info block file
544
545
file: TEST_DIR/t.qcow2 (file)
546
Cache mode: writeback
547
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block binfo block bainfo block bacinfo block backinfo block backiinfo block backininfo block backing
548
+(qemu) info block backing
549
backing: TEST_DIR/t.qcow2.base (qcow2, read-only)
550
Cache mode: writeback, ignore flushes
551
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block binfo block bainfo block bacinfo block backinfo block backiinfo block backininfo block backinginfo block backing-info block backing-finfo block backing-fiinf
552
o block backing-filinfo block backing-file
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) qququiquit
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) iininfinfoinfo info binfo blinfo bloinfo blocinfo block
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) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block finfo block fiinfo block filinfo block file
569
+(qemu) info block file
570
571
file: TEST_DIR/t.qcow2 (file)
572
Cache mode: writeback
573
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block binfo block bainfo block bacinfo block backinfo block backiinfo block backininfo block backing
574
+(qemu) info block backing
575
backing: TEST_DIR/t.qcow2.base (qcow2, read-only)
576
Cache mode: writeback, ignore flushes
577
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block binfo block bainfo block bacinfo block backinfo block backiinfo block backininfo block backinginfo block backing-info block backing-finfo block backing-fiinf
578
o block backing-filinfo block backing-file
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) qququiquit
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) iininfinfoinfo info binfo blinfo bloinfo blocinfo block
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) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block finfo block fiinfo block filinfo block file
595
+(qemu) info block file
596
597
file: TEST_DIR/t.qcow2 (file)
598
Cache mode: writeback, ignore flushes
599
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block binfo block bainfo block bacinfo block backinfo block backiinfo block backininfo block backing
600
+(qemu) info block backing
601
backing: TEST_DIR/t.qcow2.base (qcow2, read-only)
602
Cache mode: writeback, ignore flushes
603
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block binfo block bainfo block bacinfo block backinfo block backiinfo block backininfo block backinginfo block backing-info block backing-finfo block backing-fiinf
604
o block backing-filinfo block backing-file
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) qququiquit
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) qququiquit
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) qququiquit
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) qququiquit
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) qququiquit
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) qququiquit
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) qququiquit
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) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqem
661
u-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0
662
qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
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) qququiquit
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) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqem
672
u-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0
673
qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
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) qququiquit
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) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqem
683
u-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0
684
qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
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) qququiquit
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) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqem
694
u-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0
695
qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
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) qququiquit
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) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqem
705
u-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0
706
qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
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) qququiquit
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) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqem
716
u-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0
717
qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
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) qququiquit
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) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqem
727
u-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0
728
qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
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) qququiquit
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) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqem
738
u-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0
739
qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
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) qququiquit
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) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqem
751
u-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0
752
qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
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) qququiquit
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) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqem
764
u-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x3qemu-io drive0 "write -P 0x33qemu-io drive0 "write -P 0x33 qemu-io drive0 "write -P 0x33 0
765
qemu-io drive0 "write -P 0x33 0 qemu-io drive0 "write -P 0x33 0 4qemu-io drive0 "write -P 0x33 0 4kqemu-io drive0 "write -P 0x33 0 4k"
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) ccocomcommcommicommitcommit commit dcommit drcommit dricommit drivcommit drivecommit drive0
770
-(qemu) qququiquit
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) ssasavsavesavevsavevmsavevm savevm 0
803
-(qemu) qququiquit
804
+(qemu) savevm 0
805
+(qemu) quit
806
QEMU X.Y.Z monitor - type 'help' for more information
807
-(qemu) qququiquit
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) ccocomcommcommicommitcommit commit tcommit tecommit tescommit testcommit testdcommit testdicommit testdiscommit testdisk
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) ccocomcommcommicommitcommit commit tcommit tecommit tescommit testcommit testdcommit testdicommit testdiscommit testdisk
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) qququiquit
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) qququiquit
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) qququiquit
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) qququiquit
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) qququiquit
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) qququiquit
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