1
The following changes since commit 4c8c1cc544dbd5e2564868e61c5037258e393832:
1
The following changes since commit b2f7a038bb4c4fc5ce6b8486e8513dfd97665e2a:
2
2
3
Merge remote-tracking branch 'remotes/vivier/tags/m68k-for-2.10-pull-request' into staging (2017-06-22 19:01:58 +0100)
3
Merge remote-tracking branch 'remotes/rth/tags/pull-softfloat-20181104' into staging (2018-11-05 10:32:49 +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 1512008812410ca4054506a7c44343088abdd977:
9
for you to fetch changes up to 1240ac558d348f6c7a5752b1a57c1da58e4efe3e:
11
10
12
Merge remote-tracking branch 'mreitz/tags/pull-block-2017-06-23' into queue-block (2017-06-23 14:09:12 +0200)
11
include: Add a comment to explain the origin of sizes' lookup table (2018-11-05 15:29:59 +0100)
13
12
14
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block layer patches:
15
15
16
Block layer patches
16
- auto-read-only option to fix commit job when used with -blockdev
17
- Fix help text related qemu-iotests failure (by improving the help text
18
and updating the reference output)
19
- quorum: Add missing checks when adding/removing child nodes
20
- Don't take address of fields in packed structs
21
- vvfat: Fix crash when reporting error about too many files in directory
17
22
18
----------------------------------------------------------------
23
----------------------------------------------------------------
19
Alberto Garcia (9):
24
Alberto Garcia (7):
20
throttle: Update throttle-groups.c documentation
25
block: replace "discard" literal with BDRV_OPT_DISCARD macro
21
qcow2: Remove unused Error variable in do_perform_cow()
26
qcow2: Get the request alignment for encrypted images from QCryptoBlock
22
qcow2: Use unsigned int for both members of Qcow2COWRegion
27
quorum: Remove quorum_err()
23
qcow2: Make perform_cow() call do_perform_cow() twice
28
quorum: Return an error if the blkverify mode has invalid settings
24
qcow2: Split do_perform_cow() into _read(), _encrypt() and _write()
29
iotest: Test the blkverify mode of the Quorum driver
25
qcow2: Allow reading both COW regions with only one request
30
quorum: Forbid adding children in blkverify mode
26
qcow2: Pass a QEMUIOVector to do_perform_cow_{read,write}()
31
iotest: Test x-blockdev-change on a Quorum
27
qcow2: Merge the writing of the COW regions with the guest data
28
qcow2: Use offset_into_cluster() and offset_to_l2_index()
29
32
30
Kevin Wolf (37):
33
Cleber Rosa (1):
31
commit: Fix completion with extra reference
34
iotests: make 083 specific to raw
32
qemu-iotests: Allow starting new qemu after cleanup
33
qemu-iotests: Test exiting qemu with running job
34
doc: Document generic -blockdev options
35
doc: Document driver-specific -blockdev options
36
qed: Use bottom half to resume waiting requests
37
qed: Make qed_read_table() synchronous
38
qed: Remove callback from qed_read_table()
39
qed: Remove callback from qed_read_l2_table()
40
qed: Remove callback from qed_find_cluster()
41
qed: Make qed_read_backing_file() synchronous
42
qed: Make qed_copy_from_backing_file() synchronous
43
qed: Remove callback from qed_copy_from_backing_file()
44
qed: Make qed_write_header() synchronous
45
qed: Remove callback from qed_write_header()
46
qed: Make qed_write_table() synchronous
47
qed: Remove GenericCB
48
qed: Remove callback from qed_write_table()
49
qed: Make qed_aio_read_data() synchronous
50
qed: Make qed_aio_write_main() synchronous
51
qed: Inline qed_commit_l2_update()
52
qed: Add return value to qed_aio_write_l1_update()
53
qed: Add return value to qed_aio_write_l2_update()
54
qed: Add return value to qed_aio_write_main()
55
qed: Add return value to qed_aio_write_cow()
56
qed: Add return value to qed_aio_write_inplace/alloc()
57
qed: Add return value to qed_aio_read/write_data()
58
qed: Remove ret argument from qed_aio_next_io()
59
qed: Remove recursion in qed_aio_next_io()
60
qed: Implement .bdrv_co_readv/writev
61
qed: Use CoQueue for serialising allocations
62
qed: Simplify request handling
63
qed: Use a coroutine for need_check_timer
64
qed: Add coroutine_fn to I/O path functions
65
qed: Use bdrv_co_* for coroutine_fns
66
block: Remove bdrv_aio_readv/writev/flush()
67
Merge remote-tracking branch 'mreitz/tags/pull-block-2017-06-23' into queue-block
68
35
69
Manos Pitsidianakis (1):
36
Daniel P. Berrangé (1):
70
block: change variable names in BlockDriverState
37
crypto: initialize sector size even when opening with no IO flag
71
38
72
Max Reitz (3):
39
Kevin Wolf (12):
73
blkdebug: Catch bs->exact_filename overflow
40
vpc: Don't leak opts in vpc_open()
74
blkverify: Catch bs->exact_filename overflow
41
block: Update flags in bdrv_set_read_only()
75
block: Do not strcmp() with NULL uri->scheme
42
block: Add auto-read-only option
43
rbd: Close image in qemu_rbd_open() error path
44
block: Require auto-read-only for existing fallbacks
45
nbd: Support auto-read-only option
46
file-posix: Support auto-read-only option
47
curl: Support auto-read-only option
48
gluster: Support auto-read-only option
49
iscsi: Support auto-read-only option
50
block: Make auto-read-only=on default for -drive
51
qemu-iotests: Test auto-read-only with -drive and -blockdev
76
52
77
Stefan Hajnoczi (10):
53
Leonid Bloch (2):
78
block: count bdrv_co_rw_vmstate() requests
54
vdi: Use a literal number of bytes for DEFAULT_CLUSTER_SIZE
79
block: use BDRV_POLL_WHILE() in bdrv_rw_vmstate()
55
include: Add a comment to explain the origin of sizes' lookup table
80
migration: avoid recursive AioContext locking in save_vmstate()
81
migration: use bdrv_drain_all_begin/end() instead bdrv_drain_all()
82
virtio-pci: use ioeventfd even when KVM is disabled
83
migration: hold AioContext lock for loadvm qemu_fclose()
84
qemu-iotests: 068: extract _qemu() function
85
qemu-iotests: 068: use -drive/-device instead of -hda
86
qemu-iotests: 068: test iothread mode
87
qemu-img: don't shadow opts variable in img_dd()
88
56
89
Stephen Bates (1):
57
Li Qiang (1):
90
nvme: Add support for Read Data and Write Data in CMBs.
58
block: change some function return type to bool
91
59
92
sochin.jiang (1):
60
Max Reitz (5):
93
fix: avoid an infinite loop or a dangling pointer problem in img_commit
61
option: Make option help nicer to read
62
chardev: Indent list of chardevs
63
qdev-monitor: Make device options help nicer
64
object: Make option help nicer to read
65
fw_cfg: Drop newline in @file description
94
66
95
block/Makefile.objs | 2 +-
67
Peter Maydell (5):
96
block/blkdebug.c | 46 +--
68
block/qcow2: Don't take address of fields in packed structs
97
block/blkreplay.c | 8 +-
69
block/qcow: Don't take address of fields in packed structs
98
block/blkverify.c | 12 +-
70
block/qcow2-bitmap: Don't take address of fields in packed structs
99
block/block-backend.c | 22 +-
71
block/vhdx: Don't take address of fields in packed structs
100
block/commit.c | 7 +
72
block/vdi: Don't take address of fields in packed structs
101
block/file-posix.c | 34 +-
73
102
block/io.c | 240 ++-----------
74
Stefan Weil (1):
103
block/iscsi.c | 20 +-
75
qemu-io-cmds: Fix two format strings
104
block/mirror.c | 8 +-
76
105
block/nbd-client.c | 8 +-
77
Thomas Huth (1):
106
block/nbd-client.h | 4 +-
78
block/vvfat: Fix crash when reporting error about too many files in directory
107
block/nbd.c | 6 +-
79
108
block/nfs.c | 2 +-
80
qapi/block-core.json | 7 +
109
block/qcow2-cluster.c | 201 ++++++++---
81
block/vhdx.h | 12 +-
110
block/qcow2.c | 94 +++--
82
include/block/block.h | 5 +-
111
block/qcow2.h | 11 +-
83
include/qemu/option.h | 2 +-
112
block/qed-cluster.c | 124 +++----
84
include/qemu/units.h | 18 +
113
block/qed-gencb.c | 33 --
85
include/sysemu/block-backend.h | 6 +-
114
block/qed-table.c | 261 +++++---------
86
block.c | 60 ++-
115
block/qed.c | 779 ++++++++++++++++-------------------------
87
block/block-backend.c | 8 +-
116
block/qed.h | 54 +--
88
block/bochs.c | 17 +-
117
block/raw-format.c | 8 +-
89
block/cloop.c | 16 +-
118
block/rbd.c | 4 +-
90
block/curl.c | 8 +-
119
block/sheepdog.c | 12 +-
91
block/dmg.c | 16 +-
120
block/ssh.c | 2 +-
92
block/file-posix.c | 19 +-
121
block/throttle-groups.c | 2 +-
93
block/gluster.c | 12 +-
122
block/trace-events | 3 -
94
block/iscsi.c | 8 +-
123
blockjob.c | 4 +-
95
block/nbd-client.c | 10 +-
124
hw/block/nvme.c | 83 +++--
96
block/qcow.c | 18 +-
125
hw/block/nvme.h | 1 +
97
block/qcow2-bitmap.c | 24 +-
126
hw/virtio/virtio-pci.c | 2 +-
98
block/qcow2.c | 66 +--
127
include/block/block.h | 16 +-
99
block/quorum.c | 45 +-
128
include/block/block_int.h | 6 +-
100
block/rbd.c | 14 +-
129
include/block/blockjob.h | 18 +
101
block/vdi.c | 68 +--
130
include/sysemu/block-backend.h | 20 +-
102
block/vhdx-endian.c | 118 ++---
131
migration/savevm.c | 32 +-
103
block/vhdx-log.c | 4 +-
132
qemu-img.c | 29 +-
104
block/vhdx.c | 18 +-
133
qemu-io-cmds.c | 46 +--
105
block/vpc.c | 2 +
134
qemu-options.hx | 221 ++++++++++--
106
block/vvfat.c | 15 +-
135
tests/qemu-iotests/068 | 37 +-
107
blockdev.c | 3 +-
136
tests/qemu-iotests/068.out | 11 +-
108
chardev/char.c | 2 +-
137
tests/qemu-iotests/185 | 206 +++++++++++
109
crypto/block-qcow.c | 2 +
138
tests/qemu-iotests/185.out | 59 ++++
110
qdev-monitor.c | 13 +-
139
tests/qemu-iotests/common.qemu | 3 +
111
qemu-img.c | 4 +-
112
qemu-io-cmds.c | 4 +-
113
util/qemu-option.c | 32 +-
114
vl.c | 15 +-
115
tests/qemu-iotests/081 | 116 +++++
116
tests/qemu-iotests/081.out | 70 +++
117
tests/qemu-iotests/082.out | 956 ++++++++++++++++++++---------------------
118
tests/qemu-iotests/083 | 2 +-
119
tests/qemu-iotests/232 | 147 +++++++
120
tests/qemu-iotests/232.out | 59 +++
140
tests/qemu-iotests/group | 1 +
121
tests/qemu-iotests/group | 1 +
141
46 files changed, 1477 insertions(+), 1325 deletions(-)
122
42 files changed, 1266 insertions(+), 776 deletions(-)
142
delete mode 100644 block/qed-gencb.c
123
create mode 100755 tests/qemu-iotests/232
143
create mode 100755 tests/qemu-iotests/185
124
create mode 100644 tests/qemu-iotests/232.out
144
create mode 100644 tests/qemu-iotests/185.out
145
125
diff view generated by jsdifflib
Deleted patch
1
commit_complete() can't assume that after its block_job_completed() the
2
job is actually immediately freed; someone else may still be holding
3
references. In this case, the op blockers on the intermediate nodes make
4
the graph reconfiguration in the completion code fail.
5
1
6
Call block_job_remove_all_bdrv() manually so that we know for sure that
7
any blockers on intermediate nodes are given up.
8
9
Cc: qemu-stable@nongnu.org
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Reviewed-by: Eric Blake <eblake@redhat.com>
12
Reviewed-by: Max Reitz <mreitz@redhat.com>
13
---
14
block/commit.c | 7 +++++++
15
1 file changed, 7 insertions(+)
16
17
diff --git a/block/commit.c b/block/commit.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block/commit.c
20
+++ b/block/commit.c
21
@@ -XXX,XX +XXX,XX @@ static void commit_complete(BlockJob *job, void *opaque)
22
}
23
g_free(s->backing_file_str);
24
blk_unref(s->top);
25
+
26
+ /* If there is more than one reference to the job (e.g. if called from
27
+ * block_job_finish_sync()), block_job_completed() won't free it and
28
+ * therefore the blockers on the intermediate nodes remain. This would
29
+ * cause bdrv_set_backing_hd() to fail. */
30
+ block_job_remove_all_bdrv(job);
31
+
32
block_job_completed(&s->common, ret);
33
g_free(data);
34
35
--
36
1.8.3.1
37
38
diff view generated by jsdifflib
1
All functions that are marked coroutine_fn can directly call the
1
From: Thomas Huth <thuth@redhat.com>
2
bdrv_co_* version of functions instead of going through the wrapper.
3
2
3
When using the vvfat driver with a directory that contains too many files,
4
QEMU currently crashes. This can be triggered like this for example:
5
6
mkdir /tmp/vvfattest
7
cd /tmp/vvfattest
8
for ((x=0;x<=513;x++)); do mkdir $x; done
9
qemu-system-x86_64 -drive \
10
file.driver=vvfat,file.dir=.,read-only=on,media=cdrom
11
12
Seems like read_directory() is changing the mapping->path variable. Make
13
sure we use the right pointer instead.
14
15
Signed-off-by: Thomas Huth <thuth@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Manos Pitsidianakis <el13635@mail.ntua.gr>
6
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
7
---
17
---
8
block/qed.c | 16 +++++++++-------
18
block/vvfat.c | 4 ++--
9
1 file changed, 9 insertions(+), 7 deletions(-)
19
1 file changed, 2 insertions(+), 2 deletions(-)
10
20
11
diff --git a/block/qed.c b/block/qed.c
21
diff --git a/block/vvfat.c b/block/vvfat.c
12
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
13
--- a/block/qed.c
23
--- a/block/vvfat.c
14
+++ b/block/qed.c
24
+++ b/block/vvfat.c
15
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qed_write_header(BDRVQEDState *s)
25
@@ -XXX,XX +XXX,XX @@ static int init_directories(BDRVVVFATState* s,
16
};
26
mapping = array_get(&(s->mapping), i);
17
qemu_iovec_init_external(&qiov, &iov, 1);
27
18
28
if (mapping->mode & MODE_DIRECTORY) {
19
- ret = bdrv_preadv(s->bs->file, 0, &qiov);
29
+ char *path = mapping->path;
20
+ ret = bdrv_co_preadv(s->bs->file, 0, qiov.size, &qiov, 0);
30
mapping->begin = cluster;
21
if (ret < 0) {
31
if(read_directory(s, i)) {
22
goto out;
32
- error_setg(errp, "Could not read directory %s",
23
}
33
- mapping->path);
24
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qed_write_header(BDRVQEDState *s)
34
+ error_setg(errp, "Could not read directory %s", path);
25
/* Update header */
35
return -1;
26
qed_header_cpu_to_le(&s->header, (QEDHeader *) buf);
27
28
- ret = bdrv_pwritev(s->bs->file, 0, &qiov);
29
+ ret = bdrv_co_pwritev(s->bs->file, 0, qiov.size, &qiov, 0);
30
if (ret < 0) {
31
goto out;
32
}
33
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qed_read_backing_file(BDRVQEDState *s, uint64_t pos,
34
qemu_iovec_concat(*backing_qiov, qiov, 0, size);
35
36
BLKDBG_EVENT(s->bs->file, BLKDBG_READ_BACKING_AIO);
37
- ret = bdrv_preadv(s->bs->backing, pos, *backing_qiov);
38
+ ret = bdrv_co_preadv(s->bs->backing, pos, size, *backing_qiov, 0);
39
if (ret < 0) {
40
return ret;
41
}
42
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qed_copy_from_backing_file(BDRVQEDState *s,
43
}
44
45
BLKDBG_EVENT(s->bs->file, BLKDBG_COW_WRITE);
46
- ret = bdrv_pwritev(s->bs->file, offset, &qiov);
47
+ ret = bdrv_co_pwritev(s->bs->file, offset, qiov.size, &qiov, 0);
48
if (ret < 0) {
49
goto out;
50
}
51
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qed_aio_write_main(QEDAIOCB *acb)
52
trace_qed_aio_write_main(s, acb, 0, offset, acb->cur_qiov.size);
53
54
BLKDBG_EVENT(s->bs->file, BLKDBG_WRITE_AIO);
55
- ret = bdrv_pwritev(s->bs->file, offset, &acb->cur_qiov);
56
+ ret = bdrv_co_pwritev(s->bs->file, offset, acb->cur_qiov.size,
57
+ &acb->cur_qiov, 0);
58
if (ret < 0) {
59
return ret;
60
}
61
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qed_aio_write_main(QEDAIOCB *acb)
62
* region. The solution is to flush after writing a new data
63
* cluster and before updating the L2 table.
64
*/
65
- ret = bdrv_flush(s->bs->file->bs);
66
+ ret = bdrv_co_flush(s->bs->file->bs);
67
if (ret < 0) {
68
return ret;
69
}
36
}
70
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qed_aio_read_data(void *opaque, int ret,
37
mapping = array_get(&(s->mapping), i);
71
}
72
73
BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
74
- ret = bdrv_preadv(bs->file, offset, &acb->cur_qiov);
75
+ ret = bdrv_co_preadv(bs->file, offset, acb->cur_qiov.size,
76
+ &acb->cur_qiov, 0);
77
if (ret < 0) {
78
return ret;
79
}
80
--
38
--
81
1.8.3.1
39
2.19.1
82
40
83
41
diff view generated by jsdifflib
1
Don't recurse into qed_aio_next_io() and qed_aio_complete() here, but
1
From: Alberto Garcia <berto@igalia.com>
2
just return an error code and let the caller handle it.
3
2
3
Signed-off-by: Alberto Garcia <berto@igalia.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
6
---
5
---
7
block/qed.c | 43 ++++++++++++++++++++-----------------------
6
block.c | 6 +++---
8
1 file changed, 20 insertions(+), 23 deletions(-)
7
1 file changed, 3 insertions(+), 3 deletions(-)
9
8
10
diff --git a/block/qed.c b/block/qed.c
9
diff --git a/block.c b/block.c
11
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
12
--- a/block/qed.c
11
--- a/block.c
13
+++ b/block/qed.c
12
+++ b/block.c
14
@@ -XXX,XX +XXX,XX @@ static bool qed_should_set_need_check(BDRVQEDState *s)
13
@@ -XXX,XX +XXX,XX @@ QemuOptsList bdrv_runtime_opts = {
15
*
14
.help = "try to optimize zero writes (off, on, unmap)",
16
* This path is taken when writing to previously unallocated clusters.
15
},
17
*/
16
{
18
-static void qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
17
- .name = "discard",
19
+static int qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
18
+ .name = BDRV_OPT_DISCARD,
20
{
19
.type = QEMU_OPT_STRING,
21
BDRVQEDState *s = acb_to_s(acb);
20
.help = "discard operation (ignore/off, unmap/on)",
22
int ret;
21
},
23
@@ -XXX,XX +XXX,XX @@ static void qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
22
@@ -XXX,XX +XXX,XX @@ static int bdrv_open_common(BlockDriverState *bs, BlockBackend *file,
24
}
25
if (acb != QSIMPLEQ_FIRST(&s->allocating_write_reqs) ||
26
s->allocating_write_reqs_plugged) {
27
- return; /* wait for existing request to finish */
28
+ return -EINPROGRESS; /* wait for existing request to finish */
29
}
30
31
acb->cur_nclusters = qed_bytes_to_clusters(s,
32
@@ -XXX,XX +XXX,XX @@ static void qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
33
if (acb->flags & QED_AIOCB_ZERO) {
34
/* Skip ahead if the clusters are already zero */
35
if (acb->find_cluster_ret == QED_CLUSTER_ZERO) {
36
- qed_aio_start_io(acb);
37
- return;
38
+ return 0;
39
}
40
} else {
41
acb->cur_cluster = qed_alloc_clusters(s, acb->cur_nclusters);
42
@@ -XXX,XX +XXX,XX @@ static void qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
43
s->header.features |= QED_F_NEED_CHECK;
44
ret = qed_write_header(s);
45
if (ret < 0) {
46
- qed_aio_complete(acb, ret);
47
- return;
48
+ return ret;
49
}
23
}
50
}
24
}
51
25
52
@@ -XXX,XX +XXX,XX @@ static void qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
26
- discard = qemu_opt_get(opts, "discard");
53
ret = qed_aio_write_cow(acb);
27
+ discard = qemu_opt_get(opts, BDRV_OPT_DISCARD);
54
}
28
if (discard != NULL) {
55
if (ret < 0) {
29
if (bdrv_parse_discard_flags(discard, &bs->open_flags) != 0) {
56
- qed_aio_complete(acb, ret);
30
error_setg(errp, "Invalid discard option");
57
- return;
31
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
58
+ return ret;
32
59
}
33
update_flags_from_options(&reopen_state->flags, opts);
60
- qed_aio_next_io(acb, 0);
34
61
+ return 0;
35
- discard = qemu_opt_get_del(opts, "discard");
62
}
36
+ discard = qemu_opt_get_del(opts, BDRV_OPT_DISCARD);
63
37
if (discard != NULL) {
64
/**
38
if (bdrv_parse_discard_flags(discard, &reopen_state->flags) != 0) {
65
@@ -XXX,XX +XXX,XX @@ static void qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
39
error_setg(errp, "Invalid discard option");
66
*
67
* This path is taken when writing to already allocated clusters.
68
*/
69
-static void qed_aio_write_inplace(QEDAIOCB *acb, uint64_t offset, size_t len)
70
+static int qed_aio_write_inplace(QEDAIOCB *acb, uint64_t offset, size_t len)
71
{
72
- int ret;
73
-
74
/* Allocate buffer for zero writes */
75
if (acb->flags & QED_AIOCB_ZERO) {
76
struct iovec *iov = acb->qiov->iov;
77
@@ -XXX,XX +XXX,XX @@ static void qed_aio_write_inplace(QEDAIOCB *acb, uint64_t offset, size_t len)
78
if (!iov->iov_base) {
79
iov->iov_base = qemu_try_blockalign(acb->common.bs, iov->iov_len);
80
if (iov->iov_base == NULL) {
81
- qed_aio_complete(acb, -ENOMEM);
82
- return;
83
+ return -ENOMEM;
84
}
85
memset(iov->iov_base, 0, iov->iov_len);
86
}
87
@@ -XXX,XX +XXX,XX @@ static void qed_aio_write_inplace(QEDAIOCB *acb, uint64_t offset, size_t len)
88
qemu_iovec_concat(&acb->cur_qiov, acb->qiov, acb->qiov_offset, len);
89
90
/* Do the actual write */
91
- ret = qed_aio_write_main(acb);
92
- if (ret < 0) {
93
- qed_aio_complete(acb, ret);
94
- return;
95
- }
96
- qed_aio_next_io(acb, 0);
97
+ return qed_aio_write_main(acb);
98
}
99
100
/**
101
@@ -XXX,XX +XXX,XX @@ static void qed_aio_write_data(void *opaque, int ret,
102
103
switch (ret) {
104
case QED_CLUSTER_FOUND:
105
- qed_aio_write_inplace(acb, offset, len);
106
+ ret = qed_aio_write_inplace(acb, offset, len);
107
break;
108
109
case QED_CLUSTER_L2:
110
case QED_CLUSTER_L1:
111
case QED_CLUSTER_ZERO:
112
- qed_aio_write_alloc(acb, len);
113
+ ret = qed_aio_write_alloc(acb, len);
114
break;
115
116
default:
117
- qed_aio_complete(acb, ret);
118
+ assert(ret < 0);
119
break;
120
}
121
+
122
+ if (ret < 0) {
123
+ if (ret != -EINPROGRESS) {
124
+ qed_aio_complete(acb, ret);
125
+ }
126
+ return;
127
+ }
128
+ qed_aio_next_io(acb, 0);
129
}
130
131
/**
132
--
40
--
133
1.8.3.1
41
2.19.1
134
42
135
43
diff view generated by jsdifflib
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
From: Stefan Weil <sw@weilnetz.de>
2
2
3
AioContext was designed to allow nested acquire/release calls. It uses
3
Use %zu instead of %zd for unsigned numbers.
4
a recursive mutex so callers don't need to worry about nesting...or so
5
we thought.
6
4
7
BDRV_POLL_WHILE() is used to wait for block I/O requests. It releases
5
This fixes two error messages from the LSTM static code analyzer:
8
the AioContext temporarily around aio_poll(). This gives IOThreads a
9
chance to acquire the AioContext to process I/O completions.
10
6
11
It turns out that recursive locking and BDRV_POLL_WHILE() don't mix.
7
This argument should be of type 'ssize_t' but is of type 'unsigned long'
12
BDRV_POLL_WHILE() only releases the AioContext once, so the IOThread
13
will not be able to acquire the AioContext if it was acquired
14
multiple times.
15
8
16
Instead of trying to release AioContext n times in BDRV_POLL_WHILE(),
9
Signed-off-by: Stefan Weil <sw@weilnetz.de>
17
this patch simply avoids nested locking in save_vmstate(). It's the
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
18
simplest fix and we should step back to consider the big picture with
19
all the recent changes to block layer threading.
20
21
This patch is the final fix to solve 'savevm' hanging with -object
22
iothread.
23
24
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
25
Reviewed-by: Eric Blake <eblake@redhat.com>
26
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
27
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
28
---
12
---
29
migration/savevm.c | 12 +++++++++++-
13
qemu-io-cmds.c | 4 ++--
30
1 file changed, 11 insertions(+), 1 deletion(-)
14
1 file changed, 2 insertions(+), 2 deletions(-)
31
15
32
diff --git a/migration/savevm.c b/migration/savevm.c
16
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
33
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
34
--- a/migration/savevm.c
18
--- a/qemu-io-cmds.c
35
+++ b/migration/savevm.c
19
+++ b/qemu-io-cmds.c
36
@@ -XXX,XX +XXX,XX @@ int save_snapshot(const char *name, Error **errp)
20
@@ -XXX,XX +XXX,XX @@ static int readv_f(BlockBackend *blk, int argc, char **argv)
37
goto the_end;
21
memset(cmp_buf, pattern, qiov.size);
38
}
22
if (memcmp(buf, cmp_buf, qiov.size)) {
39
23
printf("Pattern verification failed at offset %"
40
+ /* The bdrv_all_create_snapshot() call that follows acquires the AioContext
24
- PRId64 ", %zd bytes\n", offset, qiov.size);
41
+ * for itself. BDRV_POLL_WHILE() does not support nested locking because
25
+ PRId64 ", %zu bytes\n", offset, qiov.size);
42
+ * it only releases the lock once. Therefore synchronous I/O will deadlock
26
ret = -EINVAL;
43
+ * unless we release the AioContext before bdrv_all_create_snapshot().
27
}
44
+ */
28
g_free(cmp_buf);
45
+ aio_context_release(aio_context);
29
@@ -XXX,XX +XXX,XX @@ static void aio_read_done(void *opaque, int ret)
46
+ aio_context = NULL;
30
memset(cmp_buf, ctx->pattern, ctx->qiov.size);
47
+
31
if (memcmp(ctx->buf, cmp_buf, ctx->qiov.size)) {
48
ret = bdrv_all_create_snapshot(sn, bs, vm_state_size, &bs);
32
printf("Pattern verification failed at offset %"
49
if (ret < 0) {
33
- PRId64 ", %zd bytes\n", ctx->offset, ctx->qiov.size);
50
error_setg(errp, "Error while creating snapshot on '%s'",
34
+ PRId64 ", %zu bytes\n", ctx->offset, ctx->qiov.size);
51
@@ -XXX,XX +XXX,XX @@ int save_snapshot(const char *name, Error **errp)
35
}
52
ret = 0;
36
g_free(cmp_buf);
53
54
the_end:
55
- aio_context_release(aio_context);
56
+ if (aio_context) {
57
+ aio_context_release(aio_context);
58
+ }
59
if (saved_vm_running) {
60
vm_start();
61
}
37
}
62
--
38
--
63
1.8.3.1
39
2.19.1
64
40
65
41
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Peter Maydell <peter.maydell@linaro.org>
2
2
3
We already have functions for doing these calculations, so let's use
3
Taking the address of a field in a packed struct is a bad idea, because
4
them instead of doing everything by hand. This makes the code a bit
4
it might not be actually aligned enough for that pointer type (and
5
more readable.
5
thus cause a crash on dereference on some host architectures). Newer
6
versions of clang warn about this. Avoid the bug by not using the
7
"modify in place" byte swapping functions.
6
8
7
Signed-off-by: Alberto Garcia <berto@igalia.com>
9
There are a few places where the in-place swap function is
10
used on something other than a packed struct field; we convert
11
those anyway, for consistency.
12
13
This patch was produced with the following spatch script
14
(and hand-editing to fold a few resulting overlength lines):
15
16
@@
17
expression E;
18
@@
19
-be16_to_cpus(&E);
20
+E = be16_to_cpu(E);
21
@@
22
expression E;
23
@@
24
-be32_to_cpus(&E);
25
+E = be32_to_cpu(E);
26
@@
27
expression E;
28
@@
29
-be64_to_cpus(&E);
30
+E = be64_to_cpu(E);
31
@@
32
expression E;
33
@@
34
-cpu_to_be16s(&E);
35
+E = cpu_to_be16(E);
36
@@
37
expression E;
38
@@
39
-cpu_to_be32s(&E);
40
+E = cpu_to_be32(E);
41
@@
42
expression E;
43
@@
44
-cpu_to_be64s(&E);
45
+E = cpu_to_be64(E);
46
47
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
48
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
49
Tested-by: John Snow <jsnow@redhat.com>
50
Reviewed-by: John Snow <jsnow@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
51
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
52
---
10
block/qcow2-cluster.c | 4 ++--
53
block/qcow2.c | 64 +++++++++++++++++++++++++++------------------------
11
block/qcow2.c | 2 +-
54
1 file changed, 34 insertions(+), 30 deletions(-)
12
2 files changed, 3 insertions(+), 3 deletions(-)
13
55
14
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/block/qcow2-cluster.c
17
+++ b/block/qcow2-cluster.c
18
@@ -XXX,XX +XXX,XX @@ int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
19
20
/* find the cluster offset for the given disk offset */
21
22
- l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);
23
+ l2_index = offset_to_l2_index(s, offset);
24
*cluster_offset = be64_to_cpu(l2_table[l2_index]);
25
26
nb_clusters = size_to_clusters(s, bytes_needed);
27
@@ -XXX,XX +XXX,XX @@ static int get_cluster_table(BlockDriverState *bs, uint64_t offset,
28
29
/* find the cluster offset for the given disk offset */
30
31
- l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);
32
+ l2_index = offset_to_l2_index(s, offset);
33
34
*new_l2_table = l2_table;
35
*new_l2_index = l2_index;
36
diff --git a/block/qcow2.c b/block/qcow2.c
56
diff --git a/block/qcow2.c b/block/qcow2.c
37
index XXXXXXX..XXXXXXX 100644
57
index XXXXXXX..XXXXXXX 100644
38
--- a/block/qcow2.c
58
--- a/block/qcow2.c
39
+++ b/block/qcow2.c
59
+++ b/block/qcow2.c
40
@@ -XXX,XX +XXX,XX @@ static int validate_table_offset(BlockDriverState *bs, uint64_t offset,
60
@@ -XXX,XX +XXX,XX @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
61
"pread fail from offset %" PRIu64, offset);
62
return 1;
63
}
64
- be32_to_cpus(&ext.magic);
65
- be32_to_cpus(&ext.len);
66
+ ext.magic = be32_to_cpu(ext.magic);
67
+ ext.len = be32_to_cpu(ext.len);
68
offset += sizeof(ext);
69
#ifdef DEBUG_EXT
70
printf("ext.magic = 0x%x\n", ext.magic);
71
@@ -XXX,XX +XXX,XX @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
72
"Unable to read CRYPTO header extension");
73
return ret;
74
}
75
- be64_to_cpus(&s->crypto_header.offset);
76
- be64_to_cpus(&s->crypto_header.length);
77
+ s->crypto_header.offset = be64_to_cpu(s->crypto_header.offset);
78
+ s->crypto_header.length = be64_to_cpu(s->crypto_header.length);
79
80
if ((s->crypto_header.offset % s->cluster_size) != 0) {
81
error_setg(errp, "Encryption header offset '%" PRIu64 "' is "
82
@@ -XXX,XX +XXX,XX @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
83
return -EINVAL;
84
}
85
86
- be32_to_cpus(&bitmaps_ext.nb_bitmaps);
87
- be64_to_cpus(&bitmaps_ext.bitmap_directory_size);
88
- be64_to_cpus(&bitmaps_ext.bitmap_directory_offset);
89
+ bitmaps_ext.nb_bitmaps = be32_to_cpu(bitmaps_ext.nb_bitmaps);
90
+ bitmaps_ext.bitmap_directory_size =
91
+ be64_to_cpu(bitmaps_ext.bitmap_directory_size);
92
+ bitmaps_ext.bitmap_directory_offset =
93
+ be64_to_cpu(bitmaps_ext.bitmap_directory_offset);
94
95
if (bitmaps_ext.nb_bitmaps > QCOW2_MAX_BITMAPS) {
96
error_setg(errp,
97
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
98
error_setg_errno(errp, -ret, "Could not read qcow2 header");
99
goto fail;
41
}
100
}
42
101
- be32_to_cpus(&header.magic);
43
/* Tables must be cluster aligned */
102
- be32_to_cpus(&header.version);
44
- if (offset & (s->cluster_size - 1)) {
103
- be64_to_cpus(&header.backing_file_offset);
45
+ if (offset_into_cluster(s, offset) != 0) {
104
- be32_to_cpus(&header.backing_file_size);
46
return -EINVAL;
105
- be64_to_cpus(&header.size);
106
- be32_to_cpus(&header.cluster_bits);
107
- be32_to_cpus(&header.crypt_method);
108
- be64_to_cpus(&header.l1_table_offset);
109
- be32_to_cpus(&header.l1_size);
110
- be64_to_cpus(&header.refcount_table_offset);
111
- be32_to_cpus(&header.refcount_table_clusters);
112
- be64_to_cpus(&header.snapshots_offset);
113
- be32_to_cpus(&header.nb_snapshots);
114
+ header.magic = be32_to_cpu(header.magic);
115
+ header.version = be32_to_cpu(header.version);
116
+ header.backing_file_offset = be64_to_cpu(header.backing_file_offset);
117
+ header.backing_file_size = be32_to_cpu(header.backing_file_size);
118
+ header.size = be64_to_cpu(header.size);
119
+ header.cluster_bits = be32_to_cpu(header.cluster_bits);
120
+ header.crypt_method = be32_to_cpu(header.crypt_method);
121
+ header.l1_table_offset = be64_to_cpu(header.l1_table_offset);
122
+ header.l1_size = be32_to_cpu(header.l1_size);
123
+ header.refcount_table_offset = be64_to_cpu(header.refcount_table_offset);
124
+ header.refcount_table_clusters =
125
+ be32_to_cpu(header.refcount_table_clusters);
126
+ header.snapshots_offset = be64_to_cpu(header.snapshots_offset);
127
+ header.nb_snapshots = be32_to_cpu(header.nb_snapshots);
128
129
if (header.magic != QCOW_MAGIC) {
130
error_setg(errp, "Image is not in qcow2 format");
131
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
132
header.refcount_order = 4;
133
header.header_length = 72;
134
} else {
135
- be64_to_cpus(&header.incompatible_features);
136
- be64_to_cpus(&header.compatible_features);
137
- be64_to_cpus(&header.autoclear_features);
138
- be32_to_cpus(&header.refcount_order);
139
- be32_to_cpus(&header.header_length);
140
+ header.incompatible_features =
141
+ be64_to_cpu(header.incompatible_features);
142
+ header.compatible_features = be64_to_cpu(header.compatible_features);
143
+ header.autoclear_features = be64_to_cpu(header.autoclear_features);
144
+ header.refcount_order = be32_to_cpu(header.refcount_order);
145
+ header.header_length = be32_to_cpu(header.header_length);
146
147
if (header.header_length < 104) {
148
error_setg(errp, "qcow2 header too short");
149
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
150
goto fail;
151
}
152
for(i = 0;i < s->l1_size; i++) {
153
- be64_to_cpus(&s->l1_table[i]);
154
+ s->l1_table[i] = be64_to_cpu(s->l1_table[i]);
155
}
47
}
156
}
48
157
158
@@ -XXX,XX +XXX,XX @@ int qcow2_update_header(BlockDriverState *bs)
159
160
/* Full disk encryption header pointer extension */
161
if (s->crypto_header.offset != 0) {
162
- cpu_to_be64s(&s->crypto_header.offset);
163
- cpu_to_be64s(&s->crypto_header.length);
164
+ s->crypto_header.offset = cpu_to_be64(s->crypto_header.offset);
165
+ s->crypto_header.length = cpu_to_be64(s->crypto_header.length);
166
ret = header_ext_add(buf, QCOW2_EXT_MAGIC_CRYPTO_HEADER,
167
&s->crypto_header, sizeof(s->crypto_header),
168
buflen);
169
- be64_to_cpus(&s->crypto_header.offset);
170
- be64_to_cpus(&s->crypto_header.length);
171
+ s->crypto_header.offset = be64_to_cpu(s->crypto_header.offset);
172
+ s->crypto_header.length = be64_to_cpu(s->crypto_header.length);
173
if (ret < 0) {
174
goto fail;
175
}
49
--
176
--
50
1.8.3.1
177
2.19.1
51
178
52
179
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Peter Maydell <peter.maydell@linaro.org>
2
2
3
Instead of passing a single buffer pointer to do_perform_cow_write(),
3
Taking the address of a field in a packed struct is a bad idea, because
4
pass a QEMUIOVector. This will allow us to merge the write requests
4
it might not be actually aligned enough for that pointer type (and
5
for the COW regions and the actual data into a single one.
5
thus cause a crash on dereference on some host architectures). Newer
6
versions of clang warn about this. Avoid the bug by not using the
7
"modify in place" byte swapping functions.
6
8
7
Although do_perform_cow_read() does not strictly need to change its
9
There are a few places where the in-place swap function is
8
API, we're doing it here as well for consistency.
10
used on something other than a packed struct field; we convert
11
those anyway, for consistency.
9
12
10
Signed-off-by: Alberto Garcia <berto@igalia.com>
13
This patch was produced with the following spatch script:
11
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
14
15
@@
16
expression E;
17
@@
18
-be16_to_cpus(&E);
19
+E = be16_to_cpu(E);
20
@@
21
expression E;
22
@@
23
-be32_to_cpus(&E);
24
+E = be32_to_cpu(E);
25
@@
26
expression E;
27
@@
28
-be64_to_cpus(&E);
29
+E = be64_to_cpu(E);
30
@@
31
expression E;
32
@@
33
-cpu_to_be16s(&E);
34
+E = cpu_to_be16(E);
35
@@
36
expression E;
37
@@
38
-cpu_to_be32s(&E);
39
+E = cpu_to_be32(E);
40
@@
41
expression E;
42
@@
43
-cpu_to_be64s(&E);
44
+E = cpu_to_be64(E);
45
46
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
47
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
48
Tested-by: John Snow <jsnow@redhat.com>
49
Reviewed-by: John Snow <jsnow@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
50
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
51
---
14
block/qcow2-cluster.c | 51 ++++++++++++++++++++++++---------------------------
52
block/qcow.c | 18 +++++++++---------
15
1 file changed, 24 insertions(+), 27 deletions(-)
53
1 file changed, 9 insertions(+), 9 deletions(-)
16
54
17
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
55
diff --git a/block/qcow.c b/block/qcow.c
18
index XXXXXXX..XXXXXXX 100644
56
index XXXXXXX..XXXXXXX 100644
19
--- a/block/qcow2-cluster.c
57
--- a/block/qcow.c
20
+++ b/block/qcow2-cluster.c
58
+++ b/block/qcow.c
21
@@ -XXX,XX +XXX,XX @@ int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num,
59
@@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
22
static int coroutine_fn do_perform_cow_read(BlockDriverState *bs,
23
uint64_t src_cluster_offset,
24
unsigned offset_in_cluster,
25
- uint8_t *buffer,
26
- unsigned bytes)
27
+ QEMUIOVector *qiov)
28
{
29
- QEMUIOVector qiov;
30
- struct iovec iov = { .iov_base = buffer, .iov_len = bytes };
31
int ret;
32
33
- if (bytes == 0) {
34
+ if (qiov->size == 0) {
35
return 0;
36
}
37
38
- qemu_iovec_init_external(&qiov, &iov, 1);
39
-
40
BLKDBG_EVENT(bs->file, BLKDBG_COW_READ);
41
42
if (!bs->drv) {
43
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn do_perform_cow_read(BlockDriverState *bs,
44
* which can lead to deadlock when block layer copy-on-read is enabled.
45
*/
46
ret = bs->drv->bdrv_co_preadv(bs, src_cluster_offset + offset_in_cluster,
47
- bytes, &qiov, 0);
48
+ qiov->size, qiov, 0);
49
if (ret < 0) {
50
return ret;
51
}
52
@@ -XXX,XX +XXX,XX @@ static bool coroutine_fn do_perform_cow_encrypt(BlockDriverState *bs,
53
static int coroutine_fn do_perform_cow_write(BlockDriverState *bs,
54
uint64_t cluster_offset,
55
unsigned offset_in_cluster,
56
- uint8_t *buffer,
57
- unsigned bytes)
58
+ QEMUIOVector *qiov)
59
{
60
- QEMUIOVector qiov;
61
- struct iovec iov = { .iov_base = buffer, .iov_len = bytes };
62
int ret;
63
64
- if (bytes == 0) {
65
+ if (qiov->size == 0) {
66
return 0;
67
}
68
69
- qemu_iovec_init_external(&qiov, &iov, 1);
70
-
71
ret = qcow2_pre_write_overlap_check(bs, 0,
72
- cluster_offset + offset_in_cluster, bytes);
73
+ cluster_offset + offset_in_cluster, qiov->size);
74
if (ret < 0) {
75
return ret;
76
}
77
78
BLKDBG_EVENT(bs->file, BLKDBG_COW_WRITE);
79
ret = bdrv_co_pwritev(bs->file, cluster_offset + offset_in_cluster,
80
- bytes, &qiov, 0);
81
+ qiov->size, qiov, 0);
82
if (ret < 0) {
83
return ret;
84
}
85
@@ -XXX,XX +XXX,XX @@ static int perform_cow(BlockDriverState *bs, QCowL2Meta *m)
86
unsigned data_bytes = end->offset - (start->offset + start->nb_bytes);
87
bool merge_reads;
88
uint8_t *start_buffer, *end_buffer;
89
+ QEMUIOVector qiov;
90
int ret;
91
92
assert(start->nb_bytes <= UINT_MAX - end->nb_bytes);
93
@@ -XXX,XX +XXX,XX @@ static int perform_cow(BlockDriverState *bs, QCowL2Meta *m)
94
/* The part of the buffer where the end region is located */
95
end_buffer = start_buffer + buffer_size - end->nb_bytes;
96
97
+ qemu_iovec_init(&qiov, 1);
98
+
99
qemu_co_mutex_unlock(&s->lock);
100
/* First we read the existing data from both COW regions. We
101
* either read the whole region in one go, or the start and end
102
* regions separately. */
103
if (merge_reads) {
104
- ret = do_perform_cow_read(bs, m->offset, start->offset,
105
- start_buffer, buffer_size);
106
+ qemu_iovec_add(&qiov, start_buffer, buffer_size);
107
+ ret = do_perform_cow_read(bs, m->offset, start->offset, &qiov);
108
} else {
109
- ret = do_perform_cow_read(bs, m->offset, start->offset,
110
- start_buffer, start->nb_bytes);
111
+ qemu_iovec_add(&qiov, start_buffer, start->nb_bytes);
112
+ ret = do_perform_cow_read(bs, m->offset, start->offset, &qiov);
113
if (ret < 0) {
114
goto fail;
115
}
116
117
- ret = do_perform_cow_read(bs, m->offset, end->offset,
118
- end_buffer, end->nb_bytes);
119
+ qemu_iovec_reset(&qiov);
120
+ qemu_iovec_add(&qiov, end_buffer, end->nb_bytes);
121
+ ret = do_perform_cow_read(bs, m->offset, end->offset, &qiov);
122
}
123
if (ret < 0) {
124
goto fail;
125
@@ -XXX,XX +XXX,XX @@ static int perform_cow(BlockDriverState *bs, QCowL2Meta *m)
126
}
127
128
/* And now we can write everything */
129
- ret = do_perform_cow_write(bs, m->alloc_offset, start->offset,
130
- start_buffer, start->nb_bytes);
131
+ qemu_iovec_reset(&qiov);
132
+ qemu_iovec_add(&qiov, start_buffer, start->nb_bytes);
133
+ ret = do_perform_cow_write(bs, m->alloc_offset, start->offset, &qiov);
134
if (ret < 0) {
60
if (ret < 0) {
135
goto fail;
61
goto fail;
136
}
62
}
137
63
- be32_to_cpus(&header.magic);
138
- ret = do_perform_cow_write(bs, m->alloc_offset, end->offset,
64
- be32_to_cpus(&header.version);
139
- end_buffer, end->nb_bytes);
65
- be64_to_cpus(&header.backing_file_offset);
140
+ qemu_iovec_reset(&qiov);
66
- be32_to_cpus(&header.backing_file_size);
141
+ qemu_iovec_add(&qiov, end_buffer, end->nb_bytes);
67
- be32_to_cpus(&header.mtime);
142
+ ret = do_perform_cow_write(bs, m->alloc_offset, end->offset, &qiov);
68
- be64_to_cpus(&header.size);
143
fail:
69
- be32_to_cpus(&header.crypt_method);
144
qemu_co_mutex_lock(&s->lock);
70
- be64_to_cpus(&header.l1_table_offset);
145
71
+ header.magic = be32_to_cpu(header.magic);
146
@@ -XXX,XX +XXX,XX @@ fail:
72
+ header.version = be32_to_cpu(header.version);
73
+ header.backing_file_offset = be64_to_cpu(header.backing_file_offset);
74
+ header.backing_file_size = be32_to_cpu(header.backing_file_size);
75
+ header.mtime = be32_to_cpu(header.mtime);
76
+ header.size = be64_to_cpu(header.size);
77
+ header.crypt_method = be32_to_cpu(header.crypt_method);
78
+ header.l1_table_offset = be64_to_cpu(header.l1_table_offset);
79
80
if (header.magic != QCOW_MAGIC) {
81
error_setg(errp, "Image not in qcow format");
82
@@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
147
}
83
}
148
84
149
qemu_vfree(start_buffer);
85
for(i = 0;i < s->l1_size; i++) {
150
+ qemu_iovec_destroy(&qiov);
86
- be64_to_cpus(&s->l1_table[i]);
151
return ret;
87
+ s->l1_table[i] = be64_to_cpu(s->l1_table[i]);
152
}
88
}
153
89
90
/* alloc L2 cache (max. 64k * 16 * 8 = 8 MB) */
154
--
91
--
155
1.8.3.1
92
2.19.1
156
93
157
94
diff view generated by jsdifflib
1
Most of the qed code is now synchronous and matches the coroutine model.
1
From: Peter Maydell <peter.maydell@linaro.org>
2
One notable exception is the serialisation between requests which can
3
still schedule a callback. Before we can replace this with coroutine
4
locks, let's convert the driver's external interfaces to the coroutine
5
versions.
6
2
7
We need to be careful to handle both requests that call the completion
3
Taking the address of a field in a packed struct is a bad idea, because
8
callback directly from the calling coroutine (i.e. fully synchronous
4
it might not be actually aligned enough for that pointer type (and
9
code) and requests that involve some callback, so that we need to yield
5
thus cause a crash on dereference on some host architectures). Newer
10
and wait for the completion callback coming from outside the coroutine.
6
versions of clang warn about this. Avoid the bug by not using the
7
"modify in place" byte swapping functions.
11
8
9
There are a few places where the in-place swap function is
10
used on something other than a packed struct field; we convert
11
those anyway, for consistency.
12
13
This patch was produced with the following spatch script:
14
15
@@
16
expression E;
17
@@
18
-be16_to_cpus(&E);
19
+E = be16_to_cpu(E);
20
@@
21
expression E;
22
@@
23
-be32_to_cpus(&E);
24
+E = be32_to_cpu(E);
25
@@
26
expression E;
27
@@
28
-be64_to_cpus(&E);
29
+E = be64_to_cpu(E);
30
@@
31
expression E;
32
@@
33
-cpu_to_be16s(&E);
34
+E = cpu_to_be16(E);
35
@@
36
expression E;
37
@@
38
-cpu_to_be32s(&E);
39
+E = cpu_to_be32(E);
40
@@
41
expression E;
42
@@
43
-cpu_to_be64s(&E);
44
+E = cpu_to_be64(E);
45
46
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
47
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
48
Tested-by: John Snow <jsnow@redhat.com>
49
Reviewed-by: John Snow <jsnow@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
50
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Reviewed-by: Manos Pitsidianakis <el13635@mail.ntua.gr>
14
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
15
---
51
---
16
block/qed.c | 97 ++++++++++++++++++++++++++-----------------------------------
52
block/qcow2-bitmap.c | 24 ++++++++++++------------
17
1 file changed, 42 insertions(+), 55 deletions(-)
53
1 file changed, 12 insertions(+), 12 deletions(-)
18
54
19
diff --git a/block/qed.c b/block/qed.c
55
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
20
index XXXXXXX..XXXXXXX 100644
56
index XXXXXXX..XXXXXXX 100644
21
--- a/block/qed.c
57
--- a/block/qcow2-bitmap.c
22
+++ b/block/qed.c
58
+++ b/block/qcow2-bitmap.c
23
@@ -XXX,XX +XXX,XX @@ static void qed_aio_next_io(QEDAIOCB *acb)
59
@@ -XXX,XX +XXX,XX @@ static inline void bitmap_table_to_be(uint64_t *bitmap_table, size_t size)
60
size_t i;
61
62
for (i = 0; i < size; ++i) {
63
- cpu_to_be64s(&bitmap_table[i]);
64
+ bitmap_table[i] = cpu_to_be64(bitmap_table[i]);
24
}
65
}
25
}
66
}
26
67
27
-static BlockAIOCB *qed_aio_setup(BlockDriverState *bs,
68
@@ -XXX,XX +XXX,XX @@ static int bitmap_table_load(BlockDriverState *bs, Qcow2BitmapTable *tb,
28
- int64_t sector_num,
69
}
29
- QEMUIOVector *qiov, int nb_sectors,
70
30
- BlockCompletionFunc *cb,
71
for (i = 0; i < tb->size; ++i) {
31
- void *opaque, int flags)
72
- be64_to_cpus(&table[i]);
32
+typedef struct QEDRequestCo {
73
+ table[i] = be64_to_cpu(table[i]);
33
+ Coroutine *co;
74
ret = check_table_entry(table[i], s->cluster_size);
34
+ bool done;
75
if (ret < 0) {
35
+ int ret;
76
goto fail;
36
+} QEDRequestCo;
77
@@ -XXX,XX +XXX,XX @@ fail:
37
+
78
38
+static void qed_co_request_cb(void *opaque, int ret)
79
static inline void bitmap_dir_entry_to_cpu(Qcow2BitmapDirEntry *entry)
39
{
80
{
40
- QEDAIOCB *acb = qemu_aio_get(&qed_aiocb_info, bs, cb, opaque);
81
- be64_to_cpus(&entry->bitmap_table_offset);
41
+ QEDRequestCo *co = opaque;
82
- be32_to_cpus(&entry->bitmap_table_size);
42
83
- be32_to_cpus(&entry->flags);
43
- trace_qed_aio_setup(bs->opaque, acb, sector_num, nb_sectors,
84
- be16_to_cpus(&entry->name_size);
44
- opaque, flags);
85
- be32_to_cpus(&entry->extra_data_size);
45
+ co->done = true;
86
+ entry->bitmap_table_offset = be64_to_cpu(entry->bitmap_table_offset);
46
+ co->ret = ret;
87
+ entry->bitmap_table_size = be32_to_cpu(entry->bitmap_table_size);
47
+ qemu_coroutine_enter_if_inactive(co->co);
88
+ entry->flags = be32_to_cpu(entry->flags);
48
+}
89
+ entry->name_size = be16_to_cpu(entry->name_size);
49
+
90
+ entry->extra_data_size = be32_to_cpu(entry->extra_data_size);
50
+static int coroutine_fn qed_co_request(BlockDriverState *bs, int64_t sector_num,
51
+ QEMUIOVector *qiov, int nb_sectors,
52
+ int flags)
53
+{
54
+ QEDRequestCo co = {
55
+ .co = qemu_coroutine_self(),
56
+ .done = false,
57
+ };
58
+ QEDAIOCB *acb = qemu_aio_get(&qed_aiocb_info, bs, qed_co_request_cb, &co);
59
+
60
+ trace_qed_aio_setup(bs->opaque, acb, sector_num, nb_sectors, &co, flags);
61
62
acb->flags = flags;
63
acb->qiov = qiov;
64
@@ -XXX,XX +XXX,XX @@ static BlockAIOCB *qed_aio_setup(BlockDriverState *bs,
65
66
/* Start request */
67
qed_aio_start_io(acb);
68
- return &acb->common;
69
-}
70
71
-static BlockAIOCB *bdrv_qed_aio_readv(BlockDriverState *bs,
72
- int64_t sector_num,
73
- QEMUIOVector *qiov, int nb_sectors,
74
- BlockCompletionFunc *cb,
75
- void *opaque)
76
-{
77
- return qed_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, 0);
78
+ if (!co.done) {
79
+ qemu_coroutine_yield();
80
+ }
81
+
82
+ return co.ret;
83
}
91
}
84
92
85
-static BlockAIOCB *bdrv_qed_aio_writev(BlockDriverState *bs,
93
static inline void bitmap_dir_entry_to_be(Qcow2BitmapDirEntry *entry)
86
- int64_t sector_num,
87
- QEMUIOVector *qiov, int nb_sectors,
88
- BlockCompletionFunc *cb,
89
- void *opaque)
90
+static int coroutine_fn bdrv_qed_co_readv(BlockDriverState *bs,
91
+ int64_t sector_num, int nb_sectors,
92
+ QEMUIOVector *qiov)
93
{
94
{
94
- return qed_aio_setup(bs, sector_num, qiov, nb_sectors, cb,
95
- cpu_to_be64s(&entry->bitmap_table_offset);
95
- opaque, QED_AIOCB_WRITE);
96
- cpu_to_be32s(&entry->bitmap_table_size);
96
+ return qed_co_request(bs, sector_num, qiov, nb_sectors, 0);
97
- cpu_to_be32s(&entry->flags);
98
- cpu_to_be16s(&entry->name_size);
99
- cpu_to_be32s(&entry->extra_data_size);
100
+ entry->bitmap_table_offset = cpu_to_be64(entry->bitmap_table_offset);
101
+ entry->bitmap_table_size = cpu_to_be32(entry->bitmap_table_size);
102
+ entry->flags = cpu_to_be32(entry->flags);
103
+ entry->name_size = cpu_to_be16(entry->name_size);
104
+ entry->extra_data_size = cpu_to_be32(entry->extra_data_size);
97
}
105
}
98
106
99
-typedef struct {
107
static inline int calc_dir_entry_size(size_t name_size, size_t extra_data_size)
100
- Coroutine *co;
101
- int ret;
102
- bool done;
103
-} QEDWriteZeroesCB;
104
-
105
-static void coroutine_fn qed_co_pwrite_zeroes_cb(void *opaque, int ret)
106
+static int coroutine_fn bdrv_qed_co_writev(BlockDriverState *bs,
107
+ int64_t sector_num, int nb_sectors,
108
+ QEMUIOVector *qiov)
109
{
110
- QEDWriteZeroesCB *cb = opaque;
111
-
112
- cb->done = true;
113
- cb->ret = ret;
114
- if (cb->co) {
115
- aio_co_wake(cb->co);
116
- }
117
+ return qed_co_request(bs, sector_num, qiov, nb_sectors, QED_AIOCB_WRITE);
118
}
119
120
static int coroutine_fn bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs,
121
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs,
122
int count,
123
BdrvRequestFlags flags)
124
{
125
- BlockAIOCB *blockacb;
126
BDRVQEDState *s = bs->opaque;
127
- QEDWriteZeroesCB cb = { .done = false };
128
QEMUIOVector qiov;
129
struct iovec iov;
130
131
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs,
132
iov.iov_len = count;
133
134
qemu_iovec_init_external(&qiov, &iov, 1);
135
- blockacb = qed_aio_setup(bs, offset >> BDRV_SECTOR_BITS, &qiov,
136
- count >> BDRV_SECTOR_BITS,
137
- qed_co_pwrite_zeroes_cb, &cb,
138
- QED_AIOCB_WRITE | QED_AIOCB_ZERO);
139
- if (!blockacb) {
140
- return -EIO;
141
- }
142
- if (!cb.done) {
143
- cb.co = qemu_coroutine_self();
144
- qemu_coroutine_yield();
145
- }
146
- assert(cb.done);
147
- return cb.ret;
148
+ return qed_co_request(bs, offset >> BDRV_SECTOR_BITS, &qiov,
149
+ count >> BDRV_SECTOR_BITS,
150
+ QED_AIOCB_WRITE | QED_AIOCB_ZERO);
151
}
152
153
static int bdrv_qed_truncate(BlockDriverState *bs, int64_t offset, Error **errp)
154
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_qed = {
155
.bdrv_create = bdrv_qed_create,
156
.bdrv_has_zero_init = bdrv_has_zero_init_1,
157
.bdrv_co_get_block_status = bdrv_qed_co_get_block_status,
158
- .bdrv_aio_readv = bdrv_qed_aio_readv,
159
- .bdrv_aio_writev = bdrv_qed_aio_writev,
160
+ .bdrv_co_readv = bdrv_qed_co_readv,
161
+ .bdrv_co_writev = bdrv_qed_co_writev,
162
.bdrv_co_pwrite_zeroes = bdrv_qed_co_pwrite_zeroes,
163
.bdrv_truncate = bdrv_qed_truncate,
164
.bdrv_getlength = bdrv_qed_getlength,
165
--
108
--
166
1.8.3.1
109
2.19.1
167
110
168
111
diff view generated by jsdifflib
1
From: Stephen Bates <sbates@raithlin.com>
1
From: Daniel P. Berrangé <berrange@redhat.com>
2
2
3
Add the ability for the NVMe model to support both the RDS and WDS
3
The qcow2 block driver expects to see a valid sector size even when it
4
modes in the Controller Memory Buffer.
4
has opened the crypto layer with QCRYPTO_BLOCK_OPEN_NO_IO.
5
5
6
Although not currently supported in the upstreamed Linux kernel a fork
6
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
7
with support exists [1] and user-space test programs that build on
7
Reviewed-by: Alberto Garcia <berto@igalia.com>
8
this also exist [2].
9
10
Useful for testing CMB functionality in preperation for real CMB
11
enabled NVMe devices (coming soon).
12
13
[1] https://github.com/sbates130272/linux-p2pmem
14
[2] https://github.com/sbates130272/p2pmem-test
15
16
Signed-off-by: Stephen Bates <sbates@raithlin.com>
17
Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
18
Reviewed-by: Keith Busch <keith.busch@intel.com>
19
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
20
---
9
---
21
hw/block/nvme.c | 83 +++++++++++++++++++++++++++++++++++++++------------------
10
crypto/block-qcow.c | 2 ++
22
hw/block/nvme.h | 1 +
11
1 file changed, 2 insertions(+)
23
2 files changed, 58 insertions(+), 26 deletions(-)
24
12
25
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
13
diff --git a/crypto/block-qcow.c b/crypto/block-qcow.c
26
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/block/nvme.c
15
--- a/crypto/block-qcow.c
28
+++ b/hw/block/nvme.c
16
+++ b/crypto/block-qcow.c
29
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ qcrypto_block_qcow_open(QCryptoBlock *block,
30
* cmb_size_mb=<cmb_size_mb[optional]>
18
Error **errp)
31
*
32
* Note cmb_size_mb denotes size of CMB in MB. CMB is assumed to be at
33
- * offset 0 in BAR2 and supports SQS only for now.
34
+ * offset 0 in BAR2 and supports only WDS, RDS and SQS for now.
35
*/
36
37
#include "qemu/osdep.h"
38
@@ -XXX,XX +XXX,XX @@ static void nvme_isr_notify(NvmeCtrl *n, NvmeCQueue *cq)
39
}
40
}
41
42
-static uint16_t nvme_map_prp(QEMUSGList *qsg, uint64_t prp1, uint64_t prp2,
43
- uint32_t len, NvmeCtrl *n)
44
+static uint16_t nvme_map_prp(QEMUSGList *qsg, QEMUIOVector *iov, uint64_t prp1,
45
+ uint64_t prp2, uint32_t len, NvmeCtrl *n)
46
{
19
{
47
hwaddr trans_len = n->page_size - (prp1 % n->page_size);
20
if (flags & QCRYPTO_BLOCK_OPEN_NO_IO) {
48
trans_len = MIN(len, trans_len);
21
+ block->sector_size = QCRYPTO_BLOCK_QCOW_SECTOR_SIZE;
49
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_map_prp(QEMUSGList *qsg, uint64_t prp1, uint64_t prp2,
22
+ block->payload_offset = 0;
50
23
return 0;
51
if (!prp1) {
24
} else {
52
return NVME_INVALID_FIELD | NVME_DNR;
25
if (!options->u.qcow.key_secret) {
53
+ } else if (n->cmbsz && prp1 >= n->ctrl_mem.addr &&
54
+ prp1 < n->ctrl_mem.addr + int128_get64(n->ctrl_mem.size)) {
55
+ qsg->nsg = 0;
56
+ qemu_iovec_init(iov, num_prps);
57
+ qemu_iovec_add(iov, (void *)&n->cmbuf[prp1 - n->ctrl_mem.addr], trans_len);
58
+ } else {
59
+ pci_dma_sglist_init(qsg, &n->parent_obj, num_prps);
60
+ qemu_sglist_add(qsg, prp1, trans_len);
61
}
62
-
63
- pci_dma_sglist_init(qsg, &n->parent_obj, num_prps);
64
- qemu_sglist_add(qsg, prp1, trans_len);
65
len -= trans_len;
66
if (len) {
67
if (!prp2) {
68
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_map_prp(QEMUSGList *qsg, uint64_t prp1, uint64_t prp2,
69
70
nents = (len + n->page_size - 1) >> n->page_bits;
71
prp_trans = MIN(n->max_prp_ents, nents) * sizeof(uint64_t);
72
- pci_dma_read(&n->parent_obj, prp2, (void *)prp_list, prp_trans);
73
+ nvme_addr_read(n, prp2, (void *)prp_list, prp_trans);
74
while (len != 0) {
75
uint64_t prp_ent = le64_to_cpu(prp_list[i]);
76
77
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_map_prp(QEMUSGList *qsg, uint64_t prp1, uint64_t prp2,
78
i = 0;
79
nents = (len + n->page_size - 1) >> n->page_bits;
80
prp_trans = MIN(n->max_prp_ents, nents) * sizeof(uint64_t);
81
- pci_dma_read(&n->parent_obj, prp_ent, (void *)prp_list,
82
+ nvme_addr_read(n, prp_ent, (void *)prp_list,
83
prp_trans);
84
prp_ent = le64_to_cpu(prp_list[i]);
85
}
86
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_map_prp(QEMUSGList *qsg, uint64_t prp1, uint64_t prp2,
87
}
88
89
trans_len = MIN(len, n->page_size);
90
- qemu_sglist_add(qsg, prp_ent, trans_len);
91
+ if (qsg->nsg){
92
+ qemu_sglist_add(qsg, prp_ent, trans_len);
93
+ } else {
94
+ qemu_iovec_add(iov, (void *)&n->cmbuf[prp_ent - n->ctrl_mem.addr], trans_len);
95
+ }
96
len -= trans_len;
97
i++;
98
}
99
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_map_prp(QEMUSGList *qsg, uint64_t prp1, uint64_t prp2,
100
if (prp2 & (n->page_size - 1)) {
101
goto unmap;
102
}
103
- qemu_sglist_add(qsg, prp2, len);
104
+ if (qsg->nsg) {
105
+ qemu_sglist_add(qsg, prp2, len);
106
+ } else {
107
+ qemu_iovec_add(iov, (void *)&n->cmbuf[prp2 - n->ctrl_mem.addr], trans_len);
108
+ }
109
}
110
}
111
return NVME_SUCCESS;
112
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_dma_read_prp(NvmeCtrl *n, uint8_t *ptr, uint32_t len,
113
uint64_t prp1, uint64_t prp2)
114
{
115
QEMUSGList qsg;
116
+ QEMUIOVector iov;
117
+ uint16_t status = NVME_SUCCESS;
118
119
- if (nvme_map_prp(&qsg, prp1, prp2, len, n)) {
120
+ if (nvme_map_prp(&qsg, &iov, prp1, prp2, len, n)) {
121
return NVME_INVALID_FIELD | NVME_DNR;
122
}
123
- if (dma_buf_read(ptr, len, &qsg)) {
124
+ if (qsg.nsg > 0) {
125
+ if (dma_buf_read(ptr, len, &qsg)) {
126
+ status = NVME_INVALID_FIELD | NVME_DNR;
127
+ }
128
qemu_sglist_destroy(&qsg);
129
- return NVME_INVALID_FIELD | NVME_DNR;
130
+ } else {
131
+ if (qemu_iovec_to_buf(&iov, 0, ptr, len) != len) {
132
+ status = NVME_INVALID_FIELD | NVME_DNR;
133
+ }
134
+ qemu_iovec_destroy(&iov);
135
}
136
- qemu_sglist_destroy(&qsg);
137
- return NVME_SUCCESS;
138
+ return status;
139
}
140
141
static void nvme_post_cqes(void *opaque)
142
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_rw(NvmeCtrl *n, NvmeNamespace *ns, NvmeCmd *cmd,
143
return NVME_LBA_RANGE | NVME_DNR;
144
}
145
146
- if (nvme_map_prp(&req->qsg, prp1, prp2, data_size, n)) {
147
+ if (nvme_map_prp(&req->qsg, &req->iov, prp1, prp2, data_size, n)) {
148
block_acct_invalid(blk_get_stats(n->conf.blk), acct);
149
return NVME_INVALID_FIELD | NVME_DNR;
150
}
151
152
- assert((nlb << data_shift) == req->qsg.size);
153
-
154
- req->has_sg = true;
155
dma_acct_start(n->conf.blk, &req->acct, &req->qsg, acct);
156
- req->aiocb = is_write ?
157
- dma_blk_write(n->conf.blk, &req->qsg, data_offset, BDRV_SECTOR_SIZE,
158
- nvme_rw_cb, req) :
159
- dma_blk_read(n->conf.blk, &req->qsg, data_offset, BDRV_SECTOR_SIZE,
160
- nvme_rw_cb, req);
161
+ if (req->qsg.nsg > 0) {
162
+ req->has_sg = true;
163
+ req->aiocb = is_write ?
164
+ dma_blk_write(n->conf.blk, &req->qsg, data_offset, BDRV_SECTOR_SIZE,
165
+ nvme_rw_cb, req) :
166
+ dma_blk_read(n->conf.blk, &req->qsg, data_offset, BDRV_SECTOR_SIZE,
167
+ nvme_rw_cb, req);
168
+ } else {
169
+ req->has_sg = false;
170
+ req->aiocb = is_write ?
171
+ blk_aio_pwritev(n->conf.blk, data_offset, &req->iov, 0, nvme_rw_cb,
172
+ req) :
173
+ blk_aio_preadv(n->conf.blk, data_offset, &req->iov, 0, nvme_rw_cb,
174
+ req);
175
+ }
176
177
return NVME_NO_COMPLETE;
178
}
179
@@ -XXX,XX +XXX,XX @@ static int nvme_init(PCIDevice *pci_dev)
180
NVME_CMBSZ_SET_SQS(n->bar.cmbsz, 1);
181
NVME_CMBSZ_SET_CQS(n->bar.cmbsz, 0);
182
NVME_CMBSZ_SET_LISTS(n->bar.cmbsz, 0);
183
- NVME_CMBSZ_SET_RDS(n->bar.cmbsz, 0);
184
- NVME_CMBSZ_SET_WDS(n->bar.cmbsz, 0);
185
+ NVME_CMBSZ_SET_RDS(n->bar.cmbsz, 1);
186
+ NVME_CMBSZ_SET_WDS(n->bar.cmbsz, 1);
187
NVME_CMBSZ_SET_SZU(n->bar.cmbsz, 2); /* MBs */
188
NVME_CMBSZ_SET_SZ(n->bar.cmbsz, n->cmb_size_mb);
189
190
+ n->cmbloc = n->bar.cmbloc;
191
+ n->cmbsz = n->bar.cmbsz;
192
+
193
n->cmbuf = g_malloc0(NVME_CMBSZ_GETSIZE(n->bar.cmbsz));
194
memory_region_init_io(&n->ctrl_mem, OBJECT(n), &nvme_cmb_ops, n,
195
"nvme-cmb", NVME_CMBSZ_GETSIZE(n->bar.cmbsz));
196
diff --git a/hw/block/nvme.h b/hw/block/nvme.h
197
index XXXXXXX..XXXXXXX 100644
198
--- a/hw/block/nvme.h
199
+++ b/hw/block/nvme.h
200
@@ -XXX,XX +XXX,XX @@ typedef struct NvmeRequest {
201
NvmeCqe cqe;
202
BlockAcctCookie acct;
203
QEMUSGList qsg;
204
+ QEMUIOVector iov;
205
QTAILQ_ENTRY(NvmeRequest)entry;
206
} NvmeRequest;
207
208
--
26
--
209
1.8.3.1
27
2.19.1
210
28
211
29
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Alberto Garcia <berto@igalia.com>
2
2
3
If the guest tries to write data that results on the allocation of a
3
This doesn't have any practical effect at the moment because the
4
new cluster, instead of writing the guest data first and then the data
4
values of BDRV_SECTOR_SIZE, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE and
5
from the COW regions, write everything together using one single I/O
5
QCRYPTO_BLOCK_QCOW_SECTOR_SIZE are all the same (512 bytes), but
6
operation.
6
future encryption methods could have different requirements.
7
8
This can improve the write performance by 25% or more, depending on
9
several factors such as the media type, the cluster size and the I/O
10
request size.
11
7
12
Signed-off-by: Alberto Garcia <berto@igalia.com>
8
Signed-off-by: Alberto Garcia <berto@igalia.com>
13
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
11
---
16
block/qcow2-cluster.c | 40 ++++++++++++++++++++++++--------
12
block/qcow2.c | 2 +-
17
block/qcow2.c | 64 +++++++++++++++++++++++++++++++++++++++++++--------
13
1 file changed, 1 insertion(+), 1 deletion(-)
18
block/qcow2.h | 7 ++++++
19
3 files changed, 91 insertions(+), 20 deletions(-)
20
14
21
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/block/qcow2-cluster.c
24
+++ b/block/qcow2-cluster.c
25
@@ -XXX,XX +XXX,XX @@ static int perform_cow(BlockDriverState *bs, QCowL2Meta *m)
26
assert(start->nb_bytes <= UINT_MAX - end->nb_bytes);
27
assert(start->nb_bytes + end->nb_bytes <= UINT_MAX - data_bytes);
28
assert(start->offset + start->nb_bytes <= end->offset);
29
+ assert(!m->data_qiov || m->data_qiov->size == data_bytes);
30
31
if (start->nb_bytes == 0 && end->nb_bytes == 0) {
32
return 0;
33
@@ -XXX,XX +XXX,XX @@ static int perform_cow(BlockDriverState *bs, QCowL2Meta *m)
34
/* The part of the buffer where the end region is located */
35
end_buffer = start_buffer + buffer_size - end->nb_bytes;
36
37
- qemu_iovec_init(&qiov, 1);
38
+ qemu_iovec_init(&qiov, 2 + (m->data_qiov ? m->data_qiov->niov : 0));
39
40
qemu_co_mutex_unlock(&s->lock);
41
/* First we read the existing data from both COW regions. We
42
@@ -XXX,XX +XXX,XX @@ static int perform_cow(BlockDriverState *bs, QCowL2Meta *m)
43
}
44
}
45
46
- /* And now we can write everything */
47
- qemu_iovec_reset(&qiov);
48
- qemu_iovec_add(&qiov, start_buffer, start->nb_bytes);
49
- ret = do_perform_cow_write(bs, m->alloc_offset, start->offset, &qiov);
50
- if (ret < 0) {
51
- goto fail;
52
+ /* And now we can write everything. If we have the guest data we
53
+ * can write everything in one single operation */
54
+ if (m->data_qiov) {
55
+ qemu_iovec_reset(&qiov);
56
+ if (start->nb_bytes) {
57
+ qemu_iovec_add(&qiov, start_buffer, start->nb_bytes);
58
+ }
59
+ qemu_iovec_concat(&qiov, m->data_qiov, 0, data_bytes);
60
+ if (end->nb_bytes) {
61
+ qemu_iovec_add(&qiov, end_buffer, end->nb_bytes);
62
+ }
63
+ /* NOTE: we have a write_aio blkdebug event here followed by
64
+ * a cow_write one in do_perform_cow_write(), but there's only
65
+ * one single I/O operation */
66
+ BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
67
+ ret = do_perform_cow_write(bs, m->alloc_offset, start->offset, &qiov);
68
+ } else {
69
+ /* If there's no guest data then write both COW regions separately */
70
+ qemu_iovec_reset(&qiov);
71
+ qemu_iovec_add(&qiov, start_buffer, start->nb_bytes);
72
+ ret = do_perform_cow_write(bs, m->alloc_offset, start->offset, &qiov);
73
+ if (ret < 0) {
74
+ goto fail;
75
+ }
76
+
77
+ qemu_iovec_reset(&qiov);
78
+ qemu_iovec_add(&qiov, end_buffer, end->nb_bytes);
79
+ ret = do_perform_cow_write(bs, m->alloc_offset, end->offset, &qiov);
80
}
81
82
- qemu_iovec_reset(&qiov);
83
- qemu_iovec_add(&qiov, end_buffer, end->nb_bytes);
84
- ret = do_perform_cow_write(bs, m->alloc_offset, end->offset, &qiov);
85
fail:
86
qemu_co_mutex_lock(&s->lock);
87
88
diff --git a/block/qcow2.c b/block/qcow2.c
15
diff --git a/block/qcow2.c b/block/qcow2.c
89
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
90
--- a/block/qcow2.c
17
--- a/block/qcow2.c
91
+++ b/block/qcow2.c
18
+++ b/block/qcow2.c
92
@@ -XXX,XX +XXX,XX @@ fail:
19
@@ -XXX,XX +XXX,XX @@ static void qcow2_refresh_limits(BlockDriverState *bs, Error **errp)
93
return ret;
20
94
}
21
if (bs->encrypted) {
95
22
/* Encryption works on a sector granularity */
96
+/* Check if it's possible to merge a write request with the writing of
23
- bs->bl.request_alignment = BDRV_SECTOR_SIZE;
97
+ * the data from the COW regions */
24
+ bs->bl.request_alignment = qcrypto_block_get_sector_size(s->crypto);
98
+static bool merge_cow(uint64_t offset, unsigned bytes,
25
}
99
+ QEMUIOVector *hd_qiov, QCowL2Meta *l2meta)
26
bs->bl.pwrite_zeroes_alignment = s->cluster_size;
100
+{
27
bs->bl.pdiscard_alignment = s->cluster_size;
101
+ QCowL2Meta *m;
102
+
103
+ for (m = l2meta; m != NULL; m = m->next) {
104
+ /* If both COW regions are empty then there's nothing to merge */
105
+ if (m->cow_start.nb_bytes == 0 && m->cow_end.nb_bytes == 0) {
106
+ continue;
107
+ }
108
+
109
+ /* The data (middle) region must be immediately after the
110
+ * start region */
111
+ if (l2meta_cow_start(m) + m->cow_start.nb_bytes != offset) {
112
+ continue;
113
+ }
114
+
115
+ /* The end region must be immediately after the data (middle)
116
+ * region */
117
+ if (m->offset + m->cow_end.offset != offset + bytes) {
118
+ continue;
119
+ }
120
+
121
+ /* Make sure that adding both COW regions to the QEMUIOVector
122
+ * does not exceed IOV_MAX */
123
+ if (hd_qiov->niov > IOV_MAX - 2) {
124
+ continue;
125
+ }
126
+
127
+ m->data_qiov = hd_qiov;
128
+ return true;
129
+ }
130
+
131
+ return false;
132
+}
133
+
134
static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset,
135
uint64_t bytes, QEMUIOVector *qiov,
136
int flags)
137
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset,
138
goto fail;
139
}
140
141
- qemu_co_mutex_unlock(&s->lock);
142
- BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
143
- trace_qcow2_writev_data(qemu_coroutine_self(),
144
- cluster_offset + offset_in_cluster);
145
- ret = bdrv_co_pwritev(bs->file,
146
- cluster_offset + offset_in_cluster,
147
- cur_bytes, &hd_qiov, 0);
148
- qemu_co_mutex_lock(&s->lock);
149
- if (ret < 0) {
150
- goto fail;
151
+ /* If we need to do COW, check if it's possible to merge the
152
+ * writing of the guest data together with that of the COW regions.
153
+ * If it's not possible (or not necessary) then write the
154
+ * guest data now. */
155
+ if (!merge_cow(offset, cur_bytes, &hd_qiov, l2meta)) {
156
+ qemu_co_mutex_unlock(&s->lock);
157
+ BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
158
+ trace_qcow2_writev_data(qemu_coroutine_self(),
159
+ cluster_offset + offset_in_cluster);
160
+ ret = bdrv_co_pwritev(bs->file,
161
+ cluster_offset + offset_in_cluster,
162
+ cur_bytes, &hd_qiov, 0);
163
+ qemu_co_mutex_lock(&s->lock);
164
+ if (ret < 0) {
165
+ goto fail;
166
+ }
167
}
168
169
while (l2meta != NULL) {
170
diff --git a/block/qcow2.h b/block/qcow2.h
171
index XXXXXXX..XXXXXXX 100644
172
--- a/block/qcow2.h
173
+++ b/block/qcow2.h
174
@@ -XXX,XX +XXX,XX @@ typedef struct QCowL2Meta
175
*/
176
Qcow2COWRegion cow_end;
177
178
+ /**
179
+ * The I/O vector with the data from the actual guest write request.
180
+ * If non-NULL, this is meant to be merged together with the data
181
+ * from @cow_start and @cow_end into one single write operation.
182
+ */
183
+ QEMUIOVector *data_qiov;
184
+
185
/** Pointer to next L2Meta of the same write request */
186
struct QCowL2Meta *next;
187
188
--
28
--
189
1.8.3.1
29
2.19.1
190
30
191
31
diff view generated by jsdifflib
1
All callers pass ret = 0, so we can just remove it.
1
From: Li Qiang <liq3ea@163.com>
2
2
3
Signed-off-by: Li Qiang <liq3ea@163.com>
4
Reviewed-by: Alberto Garcia <berto@igalia.com>
3
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
5
---
6
---
6
block/qed.c | 17 ++++++-----------
7
include/sysemu/block-backend.h | 6 +++---
7
1 file changed, 6 insertions(+), 11 deletions(-)
8
block/block-backend.c | 8 ++++----
9
2 files changed, 7 insertions(+), 7 deletions(-)
8
10
9
diff --git a/block/qed.c b/block/qed.c
11
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
10
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
11
--- a/block/qed.c
13
--- a/include/sysemu/block-backend.h
12
+++ b/block/qed.c
14
+++ b/include/sysemu/block-backend.h
13
@@ -XXX,XX +XXX,XX @@ static CachedL2Table *qed_new_l2_table(BDRVQEDState *s)
15
@@ -XXX,XX +XXX,XX @@ BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
14
return l2_table;
16
int error);
17
void blk_error_action(BlockBackend *blk, BlockErrorAction action,
18
bool is_read, int error);
19
-int blk_is_read_only(BlockBackend *blk);
20
-int blk_is_sg(BlockBackend *blk);
21
-int blk_enable_write_cache(BlockBackend *blk);
22
+bool blk_is_read_only(BlockBackend *blk);
23
+bool blk_is_sg(BlockBackend *blk);
24
+bool blk_enable_write_cache(BlockBackend *blk);
25
void blk_set_enable_write_cache(BlockBackend *blk, bool wce);
26
void blk_invalidate_cache(BlockBackend *blk, Error **errp);
27
bool blk_is_inserted(BlockBackend *blk);
28
diff --git a/block/block-backend.c b/block/block-backend.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/block/block-backend.c
31
+++ b/block/block-backend.c
32
@@ -XXX,XX +XXX,XX @@ void blk_error_action(BlockBackend *blk, BlockErrorAction action,
33
}
15
}
34
}
16
35
17
-static void qed_aio_next_io(QEDAIOCB *acb, int ret);
36
-int blk_is_read_only(BlockBackend *blk)
18
+static void qed_aio_next_io(QEDAIOCB *acb);
37
+bool blk_is_read_only(BlockBackend *blk)
19
20
static void qed_aio_start_io(QEDAIOCB *acb)
21
{
38
{
22
- qed_aio_next_io(acb, 0);
39
BlockDriverState *bs = blk_bs(blk);
23
+ qed_aio_next_io(acb);
40
41
@@ -XXX,XX +XXX,XX @@ int blk_is_read_only(BlockBackend *blk)
42
}
24
}
43
}
25
44
26
static void qed_plug_allocating_write_reqs(BDRVQEDState *s)
45
-int blk_is_sg(BlockBackend *blk)
27
@@ -XXX,XX +XXX,XX @@ static int qed_aio_read_data(void *opaque, int ret, uint64_t offset, size_t len)
46
+bool blk_is_sg(BlockBackend *blk)
28
/**
29
* Begin next I/O or complete the request
30
*/
31
-static void qed_aio_next_io(QEDAIOCB *acb, int ret)
32
+static void qed_aio_next_io(QEDAIOCB *acb)
33
{
47
{
34
BDRVQEDState *s = acb_to_s(acb);
48
BlockDriverState *bs = blk_bs(blk);
35
uint64_t offset;
49
36
size_t len;
50
if (!bs) {
37
+ int ret;
51
- return 0;
38
52
+ return false;
39
- trace_qed_aio_next_io(s, acb, ret, acb->cur_pos + acb->cur_qiov.size);
40
+ trace_qed_aio_next_io(s, acb, 0, acb->cur_pos + acb->cur_qiov.size);
41
42
if (acb->backing_qiov) {
43
qemu_iovec_destroy(acb->backing_qiov);
44
@@ -XXX,XX +XXX,XX @@ static void qed_aio_next_io(QEDAIOCB *acb, int ret)
45
acb->backing_qiov = NULL;
46
}
53
}
47
54
48
- /* Handle I/O error */
55
return bdrv_is_sg(bs);
49
- if (ret) {
50
- qed_aio_complete(acb, ret);
51
- return;
52
- }
53
-
54
acb->qiov_offset += acb->cur_qiov.size;
55
acb->cur_pos += acb->cur_qiov.size;
56
qemu_iovec_reset(&acb->cur_qiov);
57
@@ -XXX,XX +XXX,XX @@ static void qed_aio_next_io(QEDAIOCB *acb, int ret)
58
}
59
return;
60
}
61
- qed_aio_next_io(acb, 0);
62
+ qed_aio_next_io(acb);
63
}
56
}
64
57
65
static BlockAIOCB *qed_aio_setup(BlockDriverState *bs,
58
-int blk_enable_write_cache(BlockBackend *blk)
59
+bool blk_enable_write_cache(BlockBackend *blk)
60
{
61
return blk->enable_write_cache;
62
}
66
--
63
--
67
1.8.3.1
64
2.19.1
68
65
69
66
diff view generated by jsdifflib
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
From: Cleber Rosa <crosa@redhat.com>
2
2
3
Old kvm.ko versions only supported a tiny number of ioeventfds so
3
While testing the Python 3 changes which touch the 083 test, I noticed
4
virtio-pci avoids ioeventfds when kvm_has_many_ioeventfds() returns 0.
4
that it would fail with qcow2. Expanding the testing, I noticed it
5
had nothing to do with the Python 3 changes, and in fact, it would not
6
pass on anything but raw:
5
7
6
Do not check kvm_has_many_ioeventfds() when KVM is disabled since it
8
raw: pass
7
always returns 0. Since commit 8c56c1a592b5092d91da8d8943c17777d6462a6f
9
bochs: not generic
8
("memory: emulate ioeventfd") it has been possible to use ioeventfds in
10
cloop: not generic
9
qtest or TCG mode.
11
parallels: fail
12
qcow: fail
13
qcow2: fail
14
qed: fail
15
vdi: fail
16
vhdx: fail
17
vmdk: fail
18
vpc: fail
19
luks: fail
10
20
11
This patch makes -device virtio-blk-pci,iothread=iothread0 work even
21
The errors are a mixture I/O and "image not in xxx format", such as:
12
when KVM is disabled.
13
22
14
I have tested that virtio-blk-pci works under TCG both with and without
23
=== Check disconnect before data ===
15
iothread.
16
24
17
Cc: Michael S. Tsirkin <mst@redhat.com>
25
Unexpected end-of-file before all bytes were read
18
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
26
-read failed: Input/output error
19
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
27
+can't open device nbd+tcp://127.0.0.1:PORT/foo: Could not open 'nbd://127.0.0.1:PORT/foo': Input/output error
28
29
=== Check disconnect after data ===
30
31
-read 512/512 bytes at offset 0
32
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
33
+can't open device nbd+tcp://127.0.0.1:PORT/foo: Image not in qcow format
34
35
I'm not aware if there's a quick fix, so, for the time being, it looks
36
like the honest approach is to make the test known to work on raw
37
only.
38
39
Signed-off-by: Cleber Rosa <crosa@redhat.com>
20
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
40
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
21
---
41
---
22
hw/virtio/virtio-pci.c | 2 +-
42
tests/qemu-iotests/083 | 2 +-
23
1 file changed, 1 insertion(+), 1 deletion(-)
43
1 file changed, 1 insertion(+), 1 deletion(-)
24
44
25
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
45
diff --git a/tests/qemu-iotests/083 b/tests/qemu-iotests/083
26
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100755
27
--- a/hw/virtio/virtio-pci.c
47
--- a/tests/qemu-iotests/083
28
+++ b/hw/virtio/virtio-pci.c
48
+++ b/tests/qemu-iotests/083
29
@@ -XXX,XX +XXX,XX @@ static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp)
49
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
30
bool pcie_port = pci_bus_is_express(pci_dev->bus) &&
50
. ./common.rc
31
!pci_bus_is_root(pci_dev->bus);
51
. ./common.filter
32
52
33
- if (!kvm_has_many_ioeventfds()) {
53
-_supported_fmt generic
34
+ if (kvm_enabled() && !kvm_has_many_ioeventfds()) {
54
+_supported_fmt raw
35
proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD;
55
_supported_proto nbd
36
}
56
_supported_os Linux
37
57
38
--
58
--
39
1.8.3.1
59
2.19.1
40
60
41
61
diff view generated by jsdifflib
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2
Reviewed-by: Eric Blake <eblake@redhat.com>
2
Reviewed-by: Alberto Garcia <berto@igalia.com>
3
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
4
---
3
---
5
block/qed-cluster.c | 94 ++++++++++++++++++-----------------------------------
4
block/vpc.c | 2 ++
6
block/qed-table.c | 15 +++------
5
1 file changed, 2 insertions(+)
7
block/qed.h | 3 +-
8
3 files changed, 36 insertions(+), 76 deletions(-)
9
6
10
diff --git a/block/qed-cluster.c b/block/qed-cluster.c
7
diff --git a/block/vpc.c b/block/vpc.c
11
index XXXXXXX..XXXXXXX 100644
8
index XXXXXXX..XXXXXXX 100644
12
--- a/block/qed-cluster.c
9
--- a/block/vpc.c
13
+++ b/block/qed-cluster.c
10
+++ b/block/vpc.c
14
@@ -XXX,XX +XXX,XX @@ static unsigned int qed_count_contiguous_clusters(BDRVQEDState *s,
11
@@ -XXX,XX +XXX,XX @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
15
return i - index;
16
}
17
18
-typedef struct {
19
- BDRVQEDState *s;
20
- uint64_t pos;
21
- size_t len;
22
-
23
- QEDRequest *request;
24
-
25
- /* User callback */
26
- QEDFindClusterFunc *cb;
27
- void *opaque;
28
-} QEDFindClusterCB;
29
-
30
-static void qed_find_cluster_cb(void *opaque, int ret)
31
-{
32
- QEDFindClusterCB *find_cluster_cb = opaque;
33
- BDRVQEDState *s = find_cluster_cb->s;
34
- QEDRequest *request = find_cluster_cb->request;
35
- uint64_t offset = 0;
36
- size_t len = 0;
37
- unsigned int index;
38
- unsigned int n;
39
-
40
- qed_acquire(s);
41
- if (ret) {
42
- goto out;
43
- }
44
-
45
- index = qed_l2_index(s, find_cluster_cb->pos);
46
- n = qed_bytes_to_clusters(s,
47
- qed_offset_into_cluster(s, find_cluster_cb->pos) +
48
- find_cluster_cb->len);
49
- n = qed_count_contiguous_clusters(s, request->l2_table->table,
50
- index, n, &offset);
51
-
52
- if (qed_offset_is_unalloc_cluster(offset)) {
53
- ret = QED_CLUSTER_L2;
54
- } else if (qed_offset_is_zero_cluster(offset)) {
55
- ret = QED_CLUSTER_ZERO;
56
- } else if (qed_check_cluster_offset(s, offset)) {
57
- ret = QED_CLUSTER_FOUND;
58
- } else {
59
- ret = -EINVAL;
60
- }
61
-
62
- len = MIN(find_cluster_cb->len, n * s->header.cluster_size -
63
- qed_offset_into_cluster(s, find_cluster_cb->pos));
64
-
65
-out:
66
- find_cluster_cb->cb(find_cluster_cb->opaque, ret, offset, len);
67
- qed_release(s);
68
- g_free(find_cluster_cb);
69
-}
70
-
71
/**
72
* Find the offset of a data cluster
73
*
74
@@ -XXX,XX +XXX,XX @@ out:
75
void qed_find_cluster(BDRVQEDState *s, QEDRequest *request, uint64_t pos,
76
size_t len, QEDFindClusterFunc *cb, void *opaque)
77
{
78
- QEDFindClusterCB *find_cluster_cb;
79
uint64_t l2_offset;
80
+ uint64_t offset = 0;
81
+ unsigned int index;
82
+ unsigned int n;
83
+ int ret;
84
85
/* Limit length to L2 boundary. Requests are broken up at the L2 boundary
86
* so that a request acts on one L2 table at a time.
87
@@ -XXX,XX +XXX,XX @@ void qed_find_cluster(BDRVQEDState *s, QEDRequest *request, uint64_t pos,
88
return;
89
}
12
}
90
13
91
- find_cluster_cb = g_malloc(sizeof(*find_cluster_cb));
14
qemu_co_mutex_init(&s->lock);
92
- find_cluster_cb->s = s;
15
+ qemu_opts_del(opts);
93
- find_cluster_cb->pos = pos;
16
94
- find_cluster_cb->len = len;
17
return 0;
95
- find_cluster_cb->cb = cb;
18
96
- find_cluster_cb->opaque = opaque;
19
fail:
97
- find_cluster_cb->request = request;
20
+ qemu_opts_del(opts);
98
+ ret = qed_read_l2_table(s, request, l2_offset);
21
qemu_vfree(s->pagetable);
99
+ qed_acquire(s);
22
#ifdef CACHE
100
+ if (ret) {
23
g_free(s->pageentry_u8);
101
+ goto out;
102
+ }
103
+
104
+ index = qed_l2_index(s, pos);
105
+ n = qed_bytes_to_clusters(s,
106
+ qed_offset_into_cluster(s, pos) + len);
107
+ n = qed_count_contiguous_clusters(s, request->l2_table->table,
108
+ index, n, &offset);
109
+
110
+ if (qed_offset_is_unalloc_cluster(offset)) {
111
+ ret = QED_CLUSTER_L2;
112
+ } else if (qed_offset_is_zero_cluster(offset)) {
113
+ ret = QED_CLUSTER_ZERO;
114
+ } else if (qed_check_cluster_offset(s, offset)) {
115
+ ret = QED_CLUSTER_FOUND;
116
+ } else {
117
+ ret = -EINVAL;
118
+ }
119
+
120
+ len = MIN(len,
121
+ n * s->header.cluster_size - qed_offset_into_cluster(s, pos));
122
123
- qed_read_l2_table(s, request, l2_offset,
124
- qed_find_cluster_cb, find_cluster_cb);
125
+out:
126
+ cb(opaque, ret, offset, len);
127
+ qed_release(s);
128
}
129
diff --git a/block/qed-table.c b/block/qed-table.c
130
index XXXXXXX..XXXXXXX 100644
131
--- a/block/qed-table.c
132
+++ b/block/qed-table.c
133
@@ -XXX,XX +XXX,XX @@ int qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index,
134
return ret;
135
}
136
137
-void qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset,
138
- BlockCompletionFunc *cb, void *opaque)
139
+int qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset)
140
{
141
int ret;
142
143
@@ -XXX,XX +XXX,XX @@ void qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset,
144
/* Check for cached L2 entry */
145
request->l2_table = qed_find_l2_cache_entry(&s->l2_cache, offset);
146
if (request->l2_table) {
147
- cb(opaque, 0);
148
- return;
149
+ return 0;
150
}
151
152
request->l2_table = qed_alloc_l2_cache_entry(&s->l2_cache);
153
@@ -XXX,XX +XXX,XX @@ void qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset,
154
}
155
qed_release(s);
156
157
- cb(opaque, ret);
158
+ return ret;
159
}
160
161
int qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request, uint64_t offset)
162
{
163
- int ret = -EINPROGRESS;
164
-
165
- qed_read_l2_table(s, request, offset, qed_sync_cb, &ret);
166
- BDRV_POLL_WHILE(s->bs, ret == -EINPROGRESS);
167
-
168
- return ret;
169
+ return qed_read_l2_table(s, request, offset);
170
}
171
172
void qed_write_l2_table(BDRVQEDState *s, QEDRequest *request,
173
diff --git a/block/qed.h b/block/qed.h
174
index XXXXXXX..XXXXXXX 100644
175
--- a/block/qed.h
176
+++ b/block/qed.h
177
@@ -XXX,XX +XXX,XX @@ int qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index,
178
unsigned int n);
179
int qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
180
uint64_t offset);
181
-void qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset,
182
- BlockCompletionFunc *cb, void *opaque);
183
+int qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset);
184
void qed_write_l2_table(BDRVQEDState *s, QEDRequest *request,
185
unsigned int index, unsigned int n, bool flush,
186
BlockCompletionFunc *cb, void *opaque);
187
--
24
--
188
1.8.3.1
25
2.19.1
189
26
190
27
diff view generated by jsdifflib
1
From: Peter Maydell <peter.maydell@linaro.org>
2
3
Taking the address of a field in a packed struct is a bad idea, because
4
it might not be actually aligned enough for that pointer type (and
5
thus cause a crash on dereference on some host architectures). Newer
6
versions of clang warn about this. Avoid the bug by not using the
7
"modify in place" byte swapping functions.
8
9
There are a few places where the in-place swap function is
10
used on something other than a packed struct field; we convert
11
those anyway, for consistency.
12
13
Patch produced with scripts/coccinelle/inplace-byteswaps.cocci.
14
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
3
---
18
---
4
block/qed-cluster.c | 39 ++++++++++++++++++++++-----------------
19
block/vhdx.h | 12 ++---
5
block/qed.c | 24 +++++++++++-------------
20
block/vhdx-endian.c | 118 ++++++++++++++++++++++----------------------
6
block/qed.h | 4 ++--
21
block/vhdx-log.c | 4 +-
7
3 files changed, 35 insertions(+), 32 deletions(-)
22
block/vhdx.c | 18 +++----
8
23
4 files changed, 76 insertions(+), 76 deletions(-)
9
diff --git a/block/qed-cluster.c b/block/qed-cluster.c
24
25
diff --git a/block/vhdx.h b/block/vhdx.h
10
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
11
--- a/block/qed-cluster.c
27
--- a/block/vhdx.h
12
+++ b/block/qed-cluster.c
28
+++ b/block/vhdx.h
13
@@ -XXX,XX +XXX,XX @@ static unsigned int qed_count_contiguous_clusters(BDRVQEDState *s,
29
@@ -XXX,XX +XXX,XX @@ int vhdx_log_write_and_flush(BlockDriverState *bs, BDRVVHDXState *s,
14
* @s: QED state
30
15
* @request: L2 cache entry
31
static inline void leguid_to_cpus(MSGUID *guid)
16
* @pos: Byte position in device
32
{
17
- * @len: Number of bytes
33
- le32_to_cpus(&guid->data1);
18
- * @cb: Completion function
34
- le16_to_cpus(&guid->data2);
19
- * @opaque: User data for completion function
35
- le16_to_cpus(&guid->data3);
20
+ * @len: Number of bytes (may be shortened on return)
36
+ guid->data1 = le32_to_cpu(guid->data1);
21
+ * @img_offset: Contains offset in the image file on success
37
+ guid->data2 = le16_to_cpu(guid->data2);
22
*
38
+ guid->data3 = le16_to_cpu(guid->data3);
23
* This function translates a position in the block device to an offset in the
39
}
24
- * image file. It invokes the cb completion callback to report back the
40
25
- * translated offset or unallocated range in the image file.
41
static inline void cpu_to_leguids(MSGUID *guid)
26
+ * image file. The translated offset or unallocated range in the image file is
42
{
27
+ * reported back in *img_offset and *len.
43
- cpu_to_le32s(&guid->data1);
28
*
44
- cpu_to_le16s(&guid->data2);
29
* If the L2 table exists, request->l2_table points to the L2 table cache entry
45
- cpu_to_le16s(&guid->data3);
30
* and the caller must free the reference when they are finished. The cache
46
+ guid->data1 = cpu_to_le32(guid->data1);
31
* entry is exposed in this way to avoid callers having to read the L2 table
47
+ guid->data2 = cpu_to_le16(guid->data2);
32
* again later during request processing. If request->l2_table is non-NULL it
48
+ guid->data3 = cpu_to_le16(guid->data3);
33
* will be unreferenced before taking on the new cache entry.
49
}
34
+ *
50
35
+ * On success QED_CLUSTER_FOUND is returned and img_offset/len are a contiguous
51
void vhdx_header_le_import(VHDXHeader *h);
36
+ * range in the image file.
52
diff --git a/block/vhdx-endian.c b/block/vhdx-endian.c
37
+ *
53
index XXXXXXX..XXXXXXX 100644
38
+ * On failure QED_CLUSTER_L2 or QED_CLUSTER_L1 is returned for missing L2 or L1
54
--- a/block/vhdx-endian.c
39
+ * table offset, respectively. len is number of contiguous unallocated bytes.
55
+++ b/block/vhdx-endian.c
40
*/
56
@@ -XXX,XX +XXX,XX @@ void vhdx_header_le_import(VHDXHeader *h)
41
-void qed_find_cluster(BDRVQEDState *s, QEDRequest *request, uint64_t pos,
57
{
42
- size_t len, QEDFindClusterFunc *cb, void *opaque)
58
assert(h != NULL);
43
+int qed_find_cluster(BDRVQEDState *s, QEDRequest *request, uint64_t pos,
59
44
+ size_t *len, uint64_t *img_offset)
60
- le32_to_cpus(&h->signature);
45
{
61
- le32_to_cpus(&h->checksum);
46
uint64_t l2_offset;
62
- le64_to_cpus(&h->sequence_number);
47
uint64_t offset = 0;
63
+ h->signature = le32_to_cpu(h->signature);
48
@@ -XXX,XX +XXX,XX @@ void qed_find_cluster(BDRVQEDState *s, QEDRequest *request, uint64_t pos,
64
+ h->checksum = le32_to_cpu(h->checksum);
49
/* Limit length to L2 boundary. Requests are broken up at the L2 boundary
65
+ h->sequence_number = le64_to_cpu(h->sequence_number);
50
* so that a request acts on one L2 table at a time.
66
51
*/
67
leguid_to_cpus(&h->file_write_guid);
52
- len = MIN(len, (((pos >> s->l1_shift) + 1) << s->l1_shift) - pos);
68
leguid_to_cpus(&h->data_write_guid);
53
+ *len = MIN(*len, (((pos >> s->l1_shift) + 1) << s->l1_shift) - pos);
69
leguid_to_cpus(&h->log_guid);
54
70
55
l2_offset = s->l1_table->offsets[qed_l1_index(s, pos)];
71
- le16_to_cpus(&h->log_version);
56
if (qed_offset_is_unalloc_cluster(l2_offset)) {
72
- le16_to_cpus(&h->version);
57
- cb(opaque, QED_CLUSTER_L1, 0, len);
73
- le32_to_cpus(&h->log_length);
58
- return;
74
- le64_to_cpus(&h->log_offset);
59
+ *img_offset = 0;
75
+ h->log_version = le16_to_cpu(h->log_version);
60
+ return QED_CLUSTER_L1;
76
+ h->version = le16_to_cpu(h->version);
77
+ h->log_length = le32_to_cpu(h->log_length);
78
+ h->log_offset = le64_to_cpu(h->log_offset);
79
}
80
81
void vhdx_header_le_export(VHDXHeader *orig_h, VHDXHeader *new_h)
82
@@ -XXX,XX +XXX,XX @@ void vhdx_log_desc_le_import(VHDXLogDescriptor *d)
83
{
84
assert(d != NULL);
85
86
- le32_to_cpus(&d->signature);
87
- le64_to_cpus(&d->file_offset);
88
- le64_to_cpus(&d->sequence_number);
89
+ d->signature = le32_to_cpu(d->signature);
90
+ d->file_offset = le64_to_cpu(d->file_offset);
91
+ d->sequence_number = le64_to_cpu(d->sequence_number);
92
}
93
94
void vhdx_log_desc_le_export(VHDXLogDescriptor *d)
95
{
96
assert(d != NULL);
97
98
- cpu_to_le32s(&d->signature);
99
- cpu_to_le32s(&d->trailing_bytes);
100
- cpu_to_le64s(&d->leading_bytes);
101
- cpu_to_le64s(&d->file_offset);
102
- cpu_to_le64s(&d->sequence_number);
103
+ d->signature = cpu_to_le32(d->signature);
104
+ d->trailing_bytes = cpu_to_le32(d->trailing_bytes);
105
+ d->leading_bytes = cpu_to_le64(d->leading_bytes);
106
+ d->file_offset = cpu_to_le64(d->file_offset);
107
+ d->sequence_number = cpu_to_le64(d->sequence_number);
108
}
109
110
void vhdx_log_data_le_import(VHDXLogDataSector *d)
111
{
112
assert(d != NULL);
113
114
- le32_to_cpus(&d->data_signature);
115
- le32_to_cpus(&d->sequence_high);
116
- le32_to_cpus(&d->sequence_low);
117
+ d->data_signature = le32_to_cpu(d->data_signature);
118
+ d->sequence_high = le32_to_cpu(d->sequence_high);
119
+ d->sequence_low = le32_to_cpu(d->sequence_low);
120
}
121
122
void vhdx_log_data_le_export(VHDXLogDataSector *d)
123
{
124
assert(d != NULL);
125
126
- cpu_to_le32s(&d->data_signature);
127
- cpu_to_le32s(&d->sequence_high);
128
- cpu_to_le32s(&d->sequence_low);
129
+ d->data_signature = cpu_to_le32(d->data_signature);
130
+ d->sequence_high = cpu_to_le32(d->sequence_high);
131
+ d->sequence_low = cpu_to_le32(d->sequence_low);
132
}
133
134
void vhdx_log_entry_hdr_le_import(VHDXLogEntryHeader *hdr)
135
{
136
assert(hdr != NULL);
137
138
- le32_to_cpus(&hdr->signature);
139
- le32_to_cpus(&hdr->checksum);
140
- le32_to_cpus(&hdr->entry_length);
141
- le32_to_cpus(&hdr->tail);
142
- le64_to_cpus(&hdr->sequence_number);
143
- le32_to_cpus(&hdr->descriptor_count);
144
+ hdr->signature = le32_to_cpu(hdr->signature);
145
+ hdr->checksum = le32_to_cpu(hdr->checksum);
146
+ hdr->entry_length = le32_to_cpu(hdr->entry_length);
147
+ hdr->tail = le32_to_cpu(hdr->tail);
148
+ hdr->sequence_number = le64_to_cpu(hdr->sequence_number);
149
+ hdr->descriptor_count = le32_to_cpu(hdr->descriptor_count);
150
leguid_to_cpus(&hdr->log_guid);
151
- le64_to_cpus(&hdr->flushed_file_offset);
152
- le64_to_cpus(&hdr->last_file_offset);
153
+ hdr->flushed_file_offset = le64_to_cpu(hdr->flushed_file_offset);
154
+ hdr->last_file_offset = le64_to_cpu(hdr->last_file_offset);
155
}
156
157
void vhdx_log_entry_hdr_le_export(VHDXLogEntryHeader *hdr)
158
{
159
assert(hdr != NULL);
160
161
- cpu_to_le32s(&hdr->signature);
162
- cpu_to_le32s(&hdr->checksum);
163
- cpu_to_le32s(&hdr->entry_length);
164
- cpu_to_le32s(&hdr->tail);
165
- cpu_to_le64s(&hdr->sequence_number);
166
- cpu_to_le32s(&hdr->descriptor_count);
167
+ hdr->signature = cpu_to_le32(hdr->signature);
168
+ hdr->checksum = cpu_to_le32(hdr->checksum);
169
+ hdr->entry_length = cpu_to_le32(hdr->entry_length);
170
+ hdr->tail = cpu_to_le32(hdr->tail);
171
+ hdr->sequence_number = cpu_to_le64(hdr->sequence_number);
172
+ hdr->descriptor_count = cpu_to_le32(hdr->descriptor_count);
173
cpu_to_leguids(&hdr->log_guid);
174
- cpu_to_le64s(&hdr->flushed_file_offset);
175
- cpu_to_le64s(&hdr->last_file_offset);
176
+ hdr->flushed_file_offset = cpu_to_le64(hdr->flushed_file_offset);
177
+ hdr->last_file_offset = cpu_to_le64(hdr->last_file_offset);
178
}
179
180
181
@@ -XXX,XX +XXX,XX @@ void vhdx_region_header_le_import(VHDXRegionTableHeader *hdr)
182
{
183
assert(hdr != NULL);
184
185
- le32_to_cpus(&hdr->signature);
186
- le32_to_cpus(&hdr->checksum);
187
- le32_to_cpus(&hdr->entry_count);
188
+ hdr->signature = le32_to_cpu(hdr->signature);
189
+ hdr->checksum = le32_to_cpu(hdr->checksum);
190
+ hdr->entry_count = le32_to_cpu(hdr->entry_count);
191
}
192
193
void vhdx_region_header_le_export(VHDXRegionTableHeader *hdr)
194
{
195
assert(hdr != NULL);
196
197
- cpu_to_le32s(&hdr->signature);
198
- cpu_to_le32s(&hdr->checksum);
199
- cpu_to_le32s(&hdr->entry_count);
200
+ hdr->signature = cpu_to_le32(hdr->signature);
201
+ hdr->checksum = cpu_to_le32(hdr->checksum);
202
+ hdr->entry_count = cpu_to_le32(hdr->entry_count);
203
}
204
205
void vhdx_region_entry_le_import(VHDXRegionTableEntry *e)
206
@@ -XXX,XX +XXX,XX @@ void vhdx_region_entry_le_import(VHDXRegionTableEntry *e)
207
assert(e != NULL);
208
209
leguid_to_cpus(&e->guid);
210
- le64_to_cpus(&e->file_offset);
211
- le32_to_cpus(&e->length);
212
- le32_to_cpus(&e->data_bits);
213
+ e->file_offset = le64_to_cpu(e->file_offset);
214
+ e->length = le32_to_cpu(e->length);
215
+ e->data_bits = le32_to_cpu(e->data_bits);
216
}
217
218
void vhdx_region_entry_le_export(VHDXRegionTableEntry *e)
219
@@ -XXX,XX +XXX,XX @@ void vhdx_region_entry_le_export(VHDXRegionTableEntry *e)
220
assert(e != NULL);
221
222
cpu_to_leguids(&e->guid);
223
- cpu_to_le64s(&e->file_offset);
224
- cpu_to_le32s(&e->length);
225
- cpu_to_le32s(&e->data_bits);
226
+ e->file_offset = cpu_to_le64(e->file_offset);
227
+ e->length = cpu_to_le32(e->length);
228
+ e->data_bits = cpu_to_le32(e->data_bits);
229
}
230
231
232
@@ -XXX,XX +XXX,XX @@ void vhdx_metadata_header_le_import(VHDXMetadataTableHeader *hdr)
233
{
234
assert(hdr != NULL);
235
236
- le64_to_cpus(&hdr->signature);
237
- le16_to_cpus(&hdr->entry_count);
238
+ hdr->signature = le64_to_cpu(hdr->signature);
239
+ hdr->entry_count = le16_to_cpu(hdr->entry_count);
240
}
241
242
void vhdx_metadata_header_le_export(VHDXMetadataTableHeader *hdr)
243
{
244
assert(hdr != NULL);
245
246
- cpu_to_le64s(&hdr->signature);
247
- cpu_to_le16s(&hdr->entry_count);
248
+ hdr->signature = cpu_to_le64(hdr->signature);
249
+ hdr->entry_count = cpu_to_le16(hdr->entry_count);
250
}
251
252
void vhdx_metadata_entry_le_import(VHDXMetadataTableEntry *e)
253
@@ -XXX,XX +XXX,XX @@ void vhdx_metadata_entry_le_import(VHDXMetadataTableEntry *e)
254
assert(e != NULL);
255
256
leguid_to_cpus(&e->item_id);
257
- le32_to_cpus(&e->offset);
258
- le32_to_cpus(&e->length);
259
- le32_to_cpus(&e->data_bits);
260
+ e->offset = le32_to_cpu(e->offset);
261
+ e->length = le32_to_cpu(e->length);
262
+ e->data_bits = le32_to_cpu(e->data_bits);
263
}
264
void vhdx_metadata_entry_le_export(VHDXMetadataTableEntry *e)
265
{
266
assert(e != NULL);
267
268
cpu_to_leguids(&e->item_id);
269
- cpu_to_le32s(&e->offset);
270
- cpu_to_le32s(&e->length);
271
- cpu_to_le32s(&e->data_bits);
272
+ e->offset = cpu_to_le32(e->offset);
273
+ e->length = cpu_to_le32(e->length);
274
+ e->data_bits = cpu_to_le32(e->data_bits);
275
}
276
diff --git a/block/vhdx-log.c b/block/vhdx-log.c
277
index XXXXXXX..XXXXXXX 100644
278
--- a/block/vhdx-log.c
279
+++ b/block/vhdx-log.c
280
@@ -XXX,XX +XXX,XX @@ static void vhdx_log_raw_to_le_sector(VHDXLogDescriptor *desc,
281
/* 8 + 4084 + 4 = 4096, 1 log sector */
282
memcpy(&desc->leading_bytes, data, 8);
283
data += 8;
284
- cpu_to_le64s(&desc->leading_bytes);
285
+ desc->leading_bytes = cpu_to_le64(desc->leading_bytes);
286
memcpy(sector->data, data, 4084);
287
data += 4084;
288
memcpy(&desc->trailing_bytes, data, 4);
289
- cpu_to_le32s(&desc->trailing_bytes);
290
+ desc->trailing_bytes = cpu_to_le32(desc->trailing_bytes);
291
data += 4;
292
293
sector->sequence_high = (uint32_t) (seq >> 32);
294
diff --git a/block/vhdx.c b/block/vhdx.c
295
index XXXXXXX..XXXXXXX 100644
296
--- a/block/vhdx.c
297
+++ b/block/vhdx.c
298
@@ -XXX,XX +XXX,XX @@ uint32_t vhdx_update_checksum(uint8_t *buf, size_t size, int crc_offset)
299
300
memset(buf + crc_offset, 0, sizeof(crc));
301
crc = crc32c(0xffffffff, buf, size);
302
- cpu_to_le32s(&crc);
303
+ crc = cpu_to_le32(crc);
304
memcpy(buf + crc_offset, &crc, sizeof(crc));
305
306
return crc;
307
@@ -XXX,XX +XXX,XX @@ static int vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s)
308
goto exit;
61
}
309
}
62
if (!qed_check_table_offset(s, l2_offset)) {
310
63
- cb(opaque, -EINVAL, 0, 0);
311
- le32_to_cpus(&s->params.block_size);
64
- return;
312
- le32_to_cpus(&s->params.data_bits);
65
+ *img_offset = *len = 0;
313
+ s->params.block_size = le32_to_cpu(s->params.block_size);
66
+ return -EINVAL;
314
+ s->params.data_bits = le32_to_cpu(s->params.data_bits);
315
316
317
/* We now have the file parameters, so we can tell if this is a
318
@@ -XXX,XX +XXX,XX @@ static int vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s)
319
goto exit;
67
}
320
}
68
321
69
ret = qed_read_l2_table(s, request, l2_offset);
322
- le64_to_cpus(&s->virtual_disk_size);
70
@@ -XXX,XX +XXX,XX @@ void qed_find_cluster(BDRVQEDState *s, QEDRequest *request, uint64_t pos,
323
- le32_to_cpus(&s->logical_sector_size);
324
- le32_to_cpus(&s->physical_sector_size);
325
+ s->virtual_disk_size = le64_to_cpu(s->virtual_disk_size);
326
+ s->logical_sector_size = le32_to_cpu(s->logical_sector_size);
327
+ s->physical_sector_size = le32_to_cpu(s->physical_sector_size);
328
329
if (s->params.block_size < VHDX_BLOCK_SIZE_MIN ||
330
s->params.block_size > VHDX_BLOCK_SIZE_MAX) {
331
@@ -XXX,XX +XXX,XX @@ static int vhdx_open(BlockDriverState *bs, QDict *options, int flags,
332
/* endian convert, and verify populated BAT field file offsets against
333
* region table and log entries */
334
for (i = 0; i < s->bat_entries; i++) {
335
- le64_to_cpus(&s->bat[i]);
336
+ s->bat[i] = le64_to_cpu(s->bat[i]);
337
if (payblocks--) {
338
/* payload bat entries */
339
if ((s->bat[i] & VHDX_BAT_STATE_BIT_MASK) ==
340
@@ -XXX,XX +XXX,XX @@ static int vhdx_create_new_metadata(BlockBackend *blk,
341
mt_file_params->block_size = cpu_to_le32(block_size);
342
if (type == VHDX_TYPE_FIXED) {
343
mt_file_params->data_bits |= VHDX_PARAMS_LEAVE_BLOCKS_ALLOCED;
344
- cpu_to_le32s(&mt_file_params->data_bits);
345
+ mt_file_params->data_bits = cpu_to_le32(mt_file_params->data_bits);
71
}
346
}
72
347
73
index = qed_l2_index(s, pos);
348
vhdx_guid_generate(&mt_page83->page_83_data);
74
- n = qed_bytes_to_clusters(s,
349
@@ -XXX,XX +XXX,XX @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
75
- qed_offset_into_cluster(s, pos) + len);
350
sinfo.file_offset = ROUND_UP(sinfo.file_offset, MiB);
76
+ n = qed_bytes_to_clusters(s, qed_offset_into_cluster(s, pos) + *len);
351
vhdx_update_bat_table_entry(blk_bs(blk), s, &sinfo, &unused, &unused,
77
n = qed_count_contiguous_clusters(s, request->l2_table->table,
352
block_state);
78
index, n, &offset);
353
- cpu_to_le64s(&s->bat[sinfo.bat_idx]);
79
354
+ s->bat[sinfo.bat_idx] = cpu_to_le64(s->bat[sinfo.bat_idx]);
80
@@ -XXX,XX +XXX,XX @@ void qed_find_cluster(BDRVQEDState *s, QEDRequest *request, uint64_t pos,
355
sector_num += s->sectors_per_block;
81
ret = -EINVAL;
356
}
82
}
357
ret = blk_pwrite(blk, file_offset, s->bat, length, 0);
83
84
- len = MIN(len,
85
- n * s->header.cluster_size - qed_offset_into_cluster(s, pos));
86
+ *len = MIN(*len,
87
+ n * s->header.cluster_size - qed_offset_into_cluster(s, pos));
88
89
out:
90
- cb(opaque, ret, offset, len);
91
+ *img_offset = offset;
92
qed_release(s);
93
+ return ret;
94
}
95
diff --git a/block/qed.c b/block/qed.c
96
index XXXXXXX..XXXXXXX 100644
97
--- a/block/qed.c
98
+++ b/block/qed.c
99
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn bdrv_qed_co_get_block_status(BlockDriverState *bs,
100
.file = file,
101
};
102
QEDRequest request = { .l2_table = NULL };
103
+ uint64_t offset;
104
+ int ret;
105
106
- qed_find_cluster(s, &request, cb.pos, len, qed_is_allocated_cb, &cb);
107
+ ret = qed_find_cluster(s, &request, cb.pos, &len, &offset);
108
+ qed_is_allocated_cb(&cb, ret, offset, len);
109
110
- /* Now sleep if the callback wasn't invoked immediately */
111
- while (cb.status == BDRV_BLOCK_OFFSET_MASK) {
112
- cb.co = qemu_coroutine_self();
113
- qemu_coroutine_yield();
114
- }
115
+ /* The callback was invoked immediately */
116
+ assert(cb.status != BDRV_BLOCK_OFFSET_MASK);
117
118
qed_unref_l2_cache_entry(request.l2_table);
119
120
@@ -XXX,XX +XXX,XX @@ static void qed_aio_write_inplace(QEDAIOCB *acb, uint64_t offset, size_t len)
121
* or -errno
122
* @offset: Cluster offset in bytes
123
* @len: Length in bytes
124
- *
125
- * Callback from qed_find_cluster().
126
*/
127
static void qed_aio_write_data(void *opaque, int ret,
128
uint64_t offset, size_t len)
129
@@ -XXX,XX +XXX,XX @@ static void qed_aio_write_data(void *opaque, int ret,
130
* or -errno
131
* @offset: Cluster offset in bytes
132
* @len: Length in bytes
133
- *
134
- * Callback from qed_find_cluster().
135
*/
136
static void qed_aio_read_data(void *opaque, int ret,
137
uint64_t offset, size_t len)
138
@@ -XXX,XX +XXX,XX @@ static void qed_aio_next_io(QEDAIOCB *acb, int ret)
139
BDRVQEDState *s = acb_to_s(acb);
140
QEDFindClusterFunc *io_fn = (acb->flags & QED_AIOCB_WRITE) ?
141
qed_aio_write_data : qed_aio_read_data;
142
+ uint64_t offset;
143
+ size_t len;
144
145
trace_qed_aio_next_io(s, acb, ret, acb->cur_pos + acb->cur_qiov.size);
146
147
@@ -XXX,XX +XXX,XX @@ static void qed_aio_next_io(QEDAIOCB *acb, int ret)
148
}
149
150
/* Find next cluster and start I/O */
151
- qed_find_cluster(s, &acb->request,
152
- acb->cur_pos, acb->end_pos - acb->cur_pos,
153
- io_fn, acb);
154
+ len = acb->end_pos - acb->cur_pos;
155
+ ret = qed_find_cluster(s, &acb->request, acb->cur_pos, &len, &offset);
156
+ io_fn(acb, ret, offset, len);
157
}
158
159
static BlockAIOCB *qed_aio_setup(BlockDriverState *bs,
160
diff --git a/block/qed.h b/block/qed.h
161
index XXXXXXX..XXXXXXX 100644
162
--- a/block/qed.h
163
+++ b/block/qed.h
164
@@ -XXX,XX +XXX,XX @@ int qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
165
/**
166
* Cluster functions
167
*/
168
-void qed_find_cluster(BDRVQEDState *s, QEDRequest *request, uint64_t pos,
169
- size_t len, QEDFindClusterFunc *cb, void *opaque);
170
+int qed_find_cluster(BDRVQEDState *s, QEDRequest *request, uint64_t pos,
171
+ size_t *len, uint64_t *img_offset);
172
173
/**
174
* Consistency check
175
--
358
--
176
1.8.3.1
359
2.19.1
177
360
178
361
diff view generated by jsdifflib
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
From: Peter Maydell <peter.maydell@linaro.org>
2
2
3
blk/bdrv_drain_all() only takes effect for a single instant and then
3
Taking the address of a field in a packed struct is a bad idea, because
4
resumes block jobs, guest devices, and other external clients like the
4
it might not be actually aligned enough for that pointer type (and
5
NBD server. This can be handy when performing a synchronous drain
5
thus cause a crash on dereference on some host architectures). Newer
6
before terminating the program, for example.
6
versions of clang warn about this. Avoid the bug by not using the
7
"modify in place" byte swapping functions.
7
8
8
Monitor commands usually need to quiesce I/O across an entire code
9
There are a few places where the in-place swap function is
9
region so blk/bdrv_drain_all() is not suitable. They must use
10
used on something other than a packed struct field; we convert
10
bdrv_drain_all_begin/end() to mark the region. This prevents new I/O
11
those anyway, for consistency.
11
requests from slipping in or worse - block jobs completing and modifying
12
the graph.
13
12
14
I audited other blk/bdrv_drain_all() callers but did not find anything
13
Patch produced with scripts/coccinelle/inplace-byteswaps.cocci.
15
that needs a similar fix. This patch fixes the savevm/loadvm commands.
16
Although I haven't encountered a read world issue this makes the code
17
safer.
18
14
19
Suggested-by: Kevin Wolf <kwolf@redhat.com>
15
There are other places where we take the address of a packed member
20
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
16
in this file for other purposes than passing it to a byteswap
21
Reviewed-by: Eric Blake <eblake@redhat.com>
17
function (all the calls to qemu_uuid_*()); we leave those for now.
18
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
22
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
23
---
22
---
24
migration/savevm.c | 18 +++++++++++++++---
23
block/vdi.c | 64 ++++++++++++++++++++++++++---------------------------
25
1 file changed, 15 insertions(+), 3 deletions(-)
24
1 file changed, 32 insertions(+), 32 deletions(-)
26
25
27
diff --git a/migration/savevm.c b/migration/savevm.c
26
diff --git a/block/vdi.c b/block/vdi.c
28
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
29
--- a/migration/savevm.c
28
--- a/block/vdi.c
30
+++ b/migration/savevm.c
29
+++ b/block/vdi.c
31
@@ -XXX,XX +XXX,XX @@ int save_snapshot(const char *name, Error **errp)
30
@@ -XXX,XX +XXX,XX @@ typedef struct {
32
}
31
33
vm_stop(RUN_STATE_SAVE_VM);
32
static void vdi_header_to_cpu(VdiHeader *header)
34
33
{
35
+ bdrv_drain_all_begin();
34
- le32_to_cpus(&header->signature);
36
+
35
- le32_to_cpus(&header->version);
37
aio_context_acquire(aio_context);
36
- le32_to_cpus(&header->header_size);
38
37
- le32_to_cpus(&header->image_type);
39
memset(sn, 0, sizeof(*sn));
38
- le32_to_cpus(&header->image_flags);
40
@@ -XXX,XX +XXX,XX @@ int save_snapshot(const char *name, Error **errp)
39
- le32_to_cpus(&header->offset_bmap);
41
if (aio_context) {
40
- le32_to_cpus(&header->offset_data);
42
aio_context_release(aio_context);
41
- le32_to_cpus(&header->cylinders);
43
}
42
- le32_to_cpus(&header->heads);
44
+
43
- le32_to_cpus(&header->sectors);
45
+ bdrv_drain_all_end();
44
- le32_to_cpus(&header->sector_size);
46
+
45
- le64_to_cpus(&header->disk_size);
47
if (saved_vm_running) {
46
- le32_to_cpus(&header->block_size);
48
vm_start();
47
- le32_to_cpus(&header->block_extra);
49
}
48
- le32_to_cpus(&header->blocks_in_image);
50
@@ -XXX,XX +XXX,XX @@ int load_snapshot(const char *name, Error **errp)
49
- le32_to_cpus(&header->blocks_allocated);
51
}
50
+ header->signature = le32_to_cpu(header->signature);
52
51
+ header->version = le32_to_cpu(header->version);
53
/* Flush all IO requests so they don't interfere with the new state. */
52
+ header->header_size = le32_to_cpu(header->header_size);
54
- bdrv_drain_all();
53
+ header->image_type = le32_to_cpu(header->image_type);
55
+ bdrv_drain_all_begin();
54
+ header->image_flags = le32_to_cpu(header->image_flags);
56
55
+ header->offset_bmap = le32_to_cpu(header->offset_bmap);
57
ret = bdrv_all_goto_snapshot(name, &bs);
56
+ header->offset_data = le32_to_cpu(header->offset_data);
58
if (ret < 0) {
57
+ header->cylinders = le32_to_cpu(header->cylinders);
59
error_setg(errp, "Error %d while activating snapshot '%s' on '%s'",
58
+ header->heads = le32_to_cpu(header->heads);
60
ret, name, bdrv_get_device_name(bs));
59
+ header->sectors = le32_to_cpu(header->sectors);
61
- return ret;
60
+ header->sector_size = le32_to_cpu(header->sector_size);
62
+ goto err_drain;
61
+ header->disk_size = le64_to_cpu(header->disk_size);
63
}
62
+ header->block_size = le32_to_cpu(header->block_size);
64
63
+ header->block_extra = le32_to_cpu(header->block_extra);
65
/* restore the VM state */
64
+ header->blocks_in_image = le32_to_cpu(header->blocks_in_image);
66
f = qemu_fopen_bdrv(bs_vm_state, 0);
65
+ header->blocks_allocated = le32_to_cpu(header->blocks_allocated);
67
if (!f) {
66
qemu_uuid_bswap(&header->uuid_image);
68
error_setg(errp, "Could not open VM state file");
67
qemu_uuid_bswap(&header->uuid_last_snap);
69
- return -EINVAL;
68
qemu_uuid_bswap(&header->uuid_link);
70
+ ret = -EINVAL;
69
@@ -XXX,XX +XXX,XX @@ static void vdi_header_to_cpu(VdiHeader *header)
71
+ goto err_drain;
70
72
}
71
static void vdi_header_to_le(VdiHeader *header)
73
72
{
74
qemu_system_reset(SHUTDOWN_CAUSE_NONE);
73
- cpu_to_le32s(&header->signature);
75
@@ -XXX,XX +XXX,XX @@ int load_snapshot(const char *name, Error **errp)
74
- cpu_to_le32s(&header->version);
76
ret = qemu_loadvm_state(f);
75
- cpu_to_le32s(&header->header_size);
77
aio_context_release(aio_context);
76
- cpu_to_le32s(&header->image_type);
78
77
- cpu_to_le32s(&header->image_flags);
79
+ bdrv_drain_all_end();
78
- cpu_to_le32s(&header->offset_bmap);
80
+
79
- cpu_to_le32s(&header->offset_data);
81
migration_incoming_state_destroy();
80
- cpu_to_le32s(&header->cylinders);
82
if (ret < 0) {
81
- cpu_to_le32s(&header->heads);
83
error_setg(errp, "Error %d while loading VM state", ret);
82
- cpu_to_le32s(&header->sectors);
84
@@ -XXX,XX +XXX,XX @@ int load_snapshot(const char *name, Error **errp)
83
- cpu_to_le32s(&header->sector_size);
85
}
84
- cpu_to_le64s(&header->disk_size);
86
85
- cpu_to_le32s(&header->block_size);
87
return 0;
86
- cpu_to_le32s(&header->block_extra);
88
+
87
- cpu_to_le32s(&header->blocks_in_image);
89
+err_drain:
88
- cpu_to_le32s(&header->blocks_allocated);
90
+ bdrv_drain_all_end();
89
+ header->signature = cpu_to_le32(header->signature);
91
+ return ret;
90
+ header->version = cpu_to_le32(header->version);
92
}
91
+ header->header_size = cpu_to_le32(header->header_size);
93
92
+ header->image_type = cpu_to_le32(header->image_type);
94
void vmstate_register_ram(MemoryRegion *mr, DeviceState *dev)
93
+ header->image_flags = cpu_to_le32(header->image_flags);
94
+ header->offset_bmap = cpu_to_le32(header->offset_bmap);
95
+ header->offset_data = cpu_to_le32(header->offset_data);
96
+ header->cylinders = cpu_to_le32(header->cylinders);
97
+ header->heads = cpu_to_le32(header->heads);
98
+ header->sectors = cpu_to_le32(header->sectors);
99
+ header->sector_size = cpu_to_le32(header->sector_size);
100
+ header->disk_size = cpu_to_le64(header->disk_size);
101
+ header->block_size = cpu_to_le32(header->block_size);
102
+ header->block_extra = cpu_to_le32(header->block_extra);
103
+ header->blocks_in_image = cpu_to_le32(header->blocks_in_image);
104
+ header->blocks_allocated = cpu_to_le32(header->blocks_allocated);
105
qemu_uuid_bswap(&header->uuid_image);
106
qemu_uuid_bswap(&header->uuid_last_snap);
107
qemu_uuid_bswap(&header->uuid_link);
95
--
108
--
96
1.8.3.1
109
2.19.1
97
110
98
111
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Alberto Garcia <berto@igalia.com>
2
2
3
Instead of calling perform_cow() twice with a different COW region
3
This is a static function with only one caller, so there's no need to
4
each time, call it just once and make perform_cow() handle both
4
keep it. Inlining the code in quorum_compare() makes it much simpler.
5
regions.
6
7
This patch simply moves code around. The next one will do the actual
8
reordering of the COW operations.
9
5
10
Signed-off-by: Alberto Garcia <berto@igalia.com>
6
Signed-off-by: Alberto Garcia <berto@igalia.com>
11
Reviewed-by: Eric Blake <eblake@redhat.com>
7
Reported-by: Markus Armbruster <armbru@redhat.com>
12
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
9
---
15
block/qcow2-cluster.c | 36 ++++++++++++++++++++++--------------
10
block/quorum.c | 24 +++++-------------------
16
1 file changed, 22 insertions(+), 14 deletions(-)
11
1 file changed, 5 insertions(+), 19 deletions(-)
17
12
18
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
13
diff --git a/block/quorum.c b/block/quorum.c
19
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
20
--- a/block/qcow2-cluster.c
15
--- a/block/quorum.c
21
+++ b/block/qcow2-cluster.c
16
+++ b/block/quorum.c
22
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn do_perform_cow(BlockDriverState *bs,
17
@@ -XXX,XX +XXX,XX @@ static bool quorum_iovec_compare(QEMUIOVector *a, QEMUIOVector *b)
23
struct iovec iov;
18
return true;
24
int ret;
25
26
+ if (bytes == 0) {
27
+ return 0;
28
+ }
29
+
30
iov.iov_len = bytes;
31
iov.iov_base = qemu_try_blockalign(bs, iov.iov_len);
32
if (iov.iov_base == NULL) {
33
@@ -XXX,XX +XXX,XX @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
34
return cluster_offset;
35
}
19
}
36
20
37
-static int perform_cow(BlockDriverState *bs, QCowL2Meta *m, Qcow2COWRegion *r)
21
-static void GCC_FMT_ATTR(2, 3) quorum_err(QuorumAIOCB *acb,
38
+static int perform_cow(BlockDriverState *bs, QCowL2Meta *m)
22
- const char *fmt, ...)
23
-{
24
- va_list ap;
25
-
26
- va_start(ap, fmt);
27
- fprintf(stderr, "quorum: offset=%" PRIu64 " bytes=%" PRIu64 " ",
28
- acb->offset, acb->bytes);
29
- vfprintf(stderr, fmt, ap);
30
- fprintf(stderr, "\n");
31
- va_end(ap);
32
- exit(1);
33
-}
34
-
35
-static bool quorum_compare(QuorumAIOCB *acb,
36
- QEMUIOVector *a,
37
- QEMUIOVector *b)
38
+static bool quorum_compare(QuorumAIOCB *acb, QEMUIOVector *a, QEMUIOVector *b)
39
{
39
{
40
BDRVQcow2State *s = bs->opaque;
40
BDRVQuorumState *s = acb->bs->opaque;
41
+ Qcow2COWRegion *start = &m->cow_start;
41
ssize_t offset;
42
+ Qcow2COWRegion *end = &m->cow_end;
42
@@ -XXX,XX +XXX,XX @@ static bool quorum_compare(QuorumAIOCB *acb,
43
int ret;
43
if (s->is_blkverify) {
44
44
offset = qemu_iovec_compare(a, b);
45
- if (r->nb_bytes == 0) {
45
if (offset != -1) {
46
+ if (start->nb_bytes == 0 && end->nb_bytes == 0) {
46
- quorum_err(acb, "contents mismatch at offset %" PRIu64,
47
return 0;
47
- acb->offset + offset);
48
}
48
+ fprintf(stderr, "quorum: offset=%" PRIu64 " bytes=%" PRIu64
49
49
+ " contents mismatch at offset %" PRIu64 "\n",
50
qemu_co_mutex_unlock(&s->lock);
50
+ acb->offset, acb->bytes, acb->offset + offset);
51
- ret = do_perform_cow(bs, m->offset, m->alloc_offset, r->offset, r->nb_bytes);
51
+ exit(1);
52
- qemu_co_mutex_lock(&s->lock);
52
}
53
-
53
return true;
54
+ ret = do_perform_cow(bs, m->offset, m->alloc_offset,
55
+ start->offset, start->nb_bytes);
56
if (ret < 0) {
57
- return ret;
58
+ goto fail;
59
}
60
61
+ ret = do_perform_cow(bs, m->offset, m->alloc_offset,
62
+ end->offset, end->nb_bytes);
63
+
64
+fail:
65
+ qemu_co_mutex_lock(&s->lock);
66
+
67
/*
68
* Before we update the L2 table to actually point to the new cluster, we
69
* need to be sure that the refcounts have been increased and COW was
70
* handled.
71
*/
72
- qcow2_cache_depends_on_flush(s->l2_table_cache);
73
+ if (ret == 0) {
74
+ qcow2_cache_depends_on_flush(s->l2_table_cache);
75
+ }
76
77
- return 0;
78
+ return ret;
79
}
80
81
int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m)
82
@@ -XXX,XX +XXX,XX @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m)
83
}
84
85
/* copy content of unmodified sectors */
86
- ret = perform_cow(bs, m, &m->cow_start);
87
- if (ret < 0) {
88
- goto err;
89
- }
90
-
91
- ret = perform_cow(bs, m, &m->cow_end);
92
+ ret = perform_cow(bs, m);
93
if (ret < 0) {
94
goto err;
95
}
54
}
96
--
55
--
97
1.8.3.1
56
2.19.1
98
57
99
58
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Alberto Garcia <berto@igalia.com>
2
2
3
Qcow2COWRegion has two attributes:
3
The blkverify mode of Quorum can only be enabled if the number of
4
children is exactly two and the value of vote-threshold is also two.
4
5
5
- The offset of the COW region from the start of the first cluster
6
If the user tries to enable it but the other settings are incorrect
6
touched by the I/O request. Since it's always going to be positive
7
then QEMU simply prints an error message to stderr and carries on
7
and the maximum request size is at most INT_MAX, we can use a
8
disabling the blkverify setting.
8
regular unsigned int to store this offset.
9
9
10
- The size of the COW region in bytes. This is guaranteed to be >= 0,
10
This patch makes quorum_open() fail and return an error in this case.
11
so we should use an unsigned type instead.
12
13
In x86_64 this reduces the size of Qcow2COWRegion from 16 to 8 bytes.
14
It will also help keep some assertions simpler now that we know that
15
there are no negative numbers.
16
17
The prototype of do_perform_cow() is also updated to reflect these
18
changes.
19
11
20
Signed-off-by: Alberto Garcia <berto@igalia.com>
12
Signed-off-by: Alberto Garcia <berto@igalia.com>
21
Reviewed-by: Eric Blake <eblake@redhat.com>
13
Reported-by: Markus Armbruster <armbru@redhat.com>
22
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
23
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
24
---
15
---
25
block/qcow2-cluster.c | 4 ++--
16
block/quorum.c | 13 ++++++-------
26
block/qcow2.h | 4 ++--
17
1 file changed, 6 insertions(+), 7 deletions(-)
27
2 files changed, 4 insertions(+), 4 deletions(-)
28
18
29
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
19
diff --git a/block/quorum.c b/block/quorum.c
30
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
31
--- a/block/qcow2-cluster.c
21
--- a/block/quorum.c
32
+++ b/block/qcow2-cluster.c
22
+++ b/block/quorum.c
33
@@ -XXX,XX +XXX,XX @@ int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num,
23
@@ -XXX,XX +XXX,XX @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags,
34
static int coroutine_fn do_perform_cow(BlockDriverState *bs,
24
s->read_pattern = ret;
35
uint64_t src_cluster_offset,
25
36
uint64_t cluster_offset,
26
if (s->read_pattern == QUORUM_READ_PATTERN_QUORUM) {
37
- int offset_in_cluster,
27
- /* is the driver in blkverify mode */
38
- int bytes)
28
- if (qemu_opt_get_bool(opts, QUORUM_OPT_BLKVERIFY, false) &&
39
+ unsigned offset_in_cluster,
29
- s->num_children == 2 && s->threshold == 2) {
40
+ unsigned bytes)
30
- s->is_blkverify = true;
41
{
31
- } else if (qemu_opt_get_bool(opts, QUORUM_OPT_BLKVERIFY, false)) {
42
BDRVQcow2State *s = bs->opaque;
32
- fprintf(stderr, "blkverify mode is set by setting blkverify=on "
43
QEMUIOVector qiov;
33
- "and using two files with vote_threshold=2\n");
44
diff --git a/block/qcow2.h b/block/qcow2.h
34
+ s->is_blkverify = qemu_opt_get_bool(opts, QUORUM_OPT_BLKVERIFY, false);
45
index XXXXXXX..XXXXXXX 100644
35
+ if (s->is_blkverify && (s->num_children != 2 || s->threshold != 2)) {
46
--- a/block/qcow2.h
36
+ error_setg(&local_err, "blkverify=on can only be set if there are "
47
+++ b/block/qcow2.h
37
+ "exactly two files and vote-threshold is 2");
48
@@ -XXX,XX +XXX,XX @@ typedef struct Qcow2COWRegion {
38
+ ret = -EINVAL;
49
* Offset of the COW region in bytes from the start of the first cluster
39
+ goto exit;
50
* touched by the request.
40
}
51
*/
41
52
- uint64_t offset;
42
s->rewrite_corrupted = qemu_opt_get_bool(opts, QUORUM_OPT_REWRITE,
53
+ unsigned offset;
54
55
/** Number of bytes to copy */
56
- int nb_bytes;
57
+ unsigned nb_bytes;
58
} Qcow2COWRegion;
59
60
/**
61
--
43
--
62
1.8.3.1
44
2.19.1
63
45
64
46
diff view generated by jsdifflib
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
From: Alberto Garcia <berto@igalia.com>
2
2
3
Avoid duplicating the QEMU command-line.
3
Signed-off-by: Alberto Garcia <berto@igalia.com>
4
5
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
5
---
8
tests/qemu-iotests/068 | 15 +++++++++------
6
tests/qemu-iotests/081 | 30 ++++++++++++++++++++++++++++++
9
1 file changed, 9 insertions(+), 6 deletions(-)
7
tests/qemu-iotests/081.out | 16 ++++++++++++++++
8
2 files changed, 46 insertions(+)
10
9
11
diff --git a/tests/qemu-iotests/068 b/tests/qemu-iotests/068
10
diff --git a/tests/qemu-iotests/081 b/tests/qemu-iotests/081
12
index XXXXXXX..XXXXXXX 100755
11
index XXXXXXX..XXXXXXX 100755
13
--- a/tests/qemu-iotests/068
12
--- a/tests/qemu-iotests/081
14
+++ b/tests/qemu-iotests/068
13
+++ b/tests/qemu-iotests/081
15
@@ -XXX,XX +XXX,XX @@ case "$QEMU_DEFAULT_MACHINE" in
14
@@ -XXX,XX +XXX,XX @@ echo "== checking that quorum is broken =="
16
;;
15
17
esac
16
$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
18
17
19
-# Give qemu some time to boot before saving the VM state
18
+echo
20
-bash -c 'sleep 1; echo -e "savevm 0\nquit"' |\
19
+echo "== checking the blkverify mode with broken content =="
21
- $QEMU $platform_parm -nographic -monitor stdio -serial none -hda "$TEST_IMG" |\
22
+_qemu()
23
+{
24
+ $QEMU $platform_parm -nographic -monitor stdio -serial none -hda "$TEST_IMG" \
25
+ "$@" |\
26
_filter_qemu | _filter_hmp
27
+}
28
+
20
+
29
+# Give qemu some time to boot before saving the VM state
21
+quorum="driver=raw,file.driver=quorum,file.vote-threshold=2,file.blkverify=on"
30
+bash -c 'sleep 1; echo -e "savevm 0\nquit"' | _qemu
22
+quorum="$quorum,file.children.0.file.filename=$TEST_DIR/1.raw"
31
# Now try to continue from that VM state (this should just work)
23
+quorum="$quorum,file.children.1.file.filename=$TEST_DIR/2.raw"
32
-echo quit |\
24
+quorum="$quorum,file.children.0.driver=raw"
33
- $QEMU $platform_parm -nographic -monitor stdio -serial none -hda "$TEST_IMG" -loadvm 0 |\
25
+quorum="$quorum,file.children.1.driver=raw"
34
- _filter_qemu | _filter_hmp
26
+
35
+echo quit | _qemu -loadvm 0
27
+$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
36
28
+
29
+echo
30
+echo "== writing the same data to both files =="
31
+
32
+$QEMU_IO -c "write -P 0x32 0 $size" "$TEST_DIR/1.raw" | _filter_qemu_io
33
+$QEMU_IO -c "write -P 0x32 0 $size" "$TEST_DIR/2.raw" | _filter_qemu_io
34
+
35
+echo
36
+echo "== checking the blkverify mode with valid content =="
37
+
38
+$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
39
+
40
+echo
41
+echo "== checking the blkverify mode with invalid settings =="
42
+
43
+quorum="$quorum,file.children.2.file.filename=$TEST_DIR/3.raw"
44
+quorum="$quorum,file.children.2.driver=raw"
45
+
46
+$QEMU_IO -c "open -o $quorum" | _filter_qemu_io
47
+
37
# success, all done
48
# success, all done
38
echo "*** done"
49
echo "*** done"
50
rm -f $seq.full
51
diff --git a/tests/qemu-iotests/081.out b/tests/qemu-iotests/081.out
52
index XXXXXXX..XXXXXXX 100644
53
--- a/tests/qemu-iotests/081.out
54
+++ b/tests/qemu-iotests/081.out
55
@@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 0
56
57
== checking that quorum is broken ==
58
read failed: Input/output error
59
+
60
+== checking the blkverify mode with broken content ==
61
+quorum: offset=0 bytes=10485760 contents mismatch at offset 0
62
+
63
+== writing the same data to both files ==
64
+wrote 10485760/10485760 bytes at offset 0
65
+10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
66
+wrote 10485760/10485760 bytes at offset 0
67
+10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
68
+
69
+== checking the blkverify mode with valid content ==
70
+read 10485760/10485760 bytes at offset 0
71
+10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
72
+
73
+== checking the blkverify mode with invalid settings ==
74
+can't open: blkverify=on can only be set if there are exactly two files and vote-threshold is 2
75
*** done
39
--
76
--
40
1.8.3.1
77
2.19.1
41
78
42
79
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Alberto Garcia <berto@igalia.com>
2
2
3
This patch splits do_perform_cow() into three separate functions to
3
The blkverify mode of Quorum only works when the number of children is
4
read, encrypt and write the COW regions.
4
exactly two, so any attempt to add a new one must return an error.
5
5
6
perform_cow() can now read both regions first, then encrypt them and
6
quorum_del_child() on the other hand doesn't need any additional check
7
finally write them to disk. The memory allocation is also done in
7
because decreasing the number of children would make it go under the
8
this function now, using one single buffer large enough to hold both
8
vote threshold.
9
regions.
10
9
11
Signed-off-by: Alberto Garcia <berto@igalia.com>
10
Signed-off-by: Alberto Garcia <berto@igalia.com>
12
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
11
Reported-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
13
---
15
block/qcow2-cluster.c | 117 +++++++++++++++++++++++++++++++++++++-------------
14
block/quorum.c | 8 ++++++++
16
1 file changed, 87 insertions(+), 30 deletions(-)
15
1 file changed, 8 insertions(+)
17
16
18
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
17
diff --git a/block/quorum.c b/block/quorum.c
19
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
20
--- a/block/qcow2-cluster.c
19
--- a/block/quorum.c
21
+++ b/block/qcow2-cluster.c
20
+++ b/block/quorum.c
22
@@ -XXX,XX +XXX,XX @@ int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num,
21
@@ -XXX,XX +XXX,XX @@ static void quorum_add_child(BlockDriverState *bs, BlockDriverState *child_bs,
23
return 0;
22
char indexstr[32];
24
}
25
26
-static int coroutine_fn do_perform_cow(BlockDriverState *bs,
27
- uint64_t src_cluster_offset,
28
- uint64_t cluster_offset,
29
- unsigned offset_in_cluster,
30
- unsigned bytes)
31
+static int coroutine_fn do_perform_cow_read(BlockDriverState *bs,
32
+ uint64_t src_cluster_offset,
33
+ unsigned offset_in_cluster,
34
+ uint8_t *buffer,
35
+ unsigned bytes)
36
{
37
- BDRVQcow2State *s = bs->opaque;
38
QEMUIOVector qiov;
39
- struct iovec iov;
40
+ struct iovec iov = { .iov_base = buffer, .iov_len = bytes };
41
int ret;
23
int ret;
42
24
43
if (bytes == 0) {
25
+ if (s->is_blkverify) {
44
return 0;
26
+ error_setg(errp, "Cannot add a child to a quorum in blkverify mode");
45
}
27
+ return;
46
47
- iov.iov_len = bytes;
48
- iov.iov_base = qemu_try_blockalign(bs, iov.iov_len);
49
- if (iov.iov_base == NULL) {
50
- return -ENOMEM;
51
- }
52
-
53
qemu_iovec_init_external(&qiov, &iov, 1);
54
55
BLKDBG_EVENT(bs->file, BLKDBG_COW_READ);
56
57
if (!bs->drv) {
58
- ret = -ENOMEDIUM;
59
- goto out;
60
+ return -ENOMEDIUM;
61
}
62
63
/* Call .bdrv_co_readv() directly instead of using the public block-layer
64
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn do_perform_cow(BlockDriverState *bs,
65
ret = bs->drv->bdrv_co_preadv(bs, src_cluster_offset + offset_in_cluster,
66
bytes, &qiov, 0);
67
if (ret < 0) {
68
- goto out;
69
+ return ret;
70
}
71
72
- if (bs->encrypted) {
73
+ return 0;
74
+}
75
+
76
+static bool coroutine_fn do_perform_cow_encrypt(BlockDriverState *bs,
77
+ uint64_t src_cluster_offset,
78
+ unsigned offset_in_cluster,
79
+ uint8_t *buffer,
80
+ unsigned bytes)
81
+{
82
+ if (bytes && bs->encrypted) {
83
+ BDRVQcow2State *s = bs->opaque;
84
int64_t sector = (src_cluster_offset + offset_in_cluster)
85
>> BDRV_SECTOR_BITS;
86
assert(s->cipher);
87
assert((offset_in_cluster & ~BDRV_SECTOR_MASK) == 0);
88
assert((bytes & ~BDRV_SECTOR_MASK) == 0);
89
- if (qcow2_encrypt_sectors(s, sector, iov.iov_base, iov.iov_base,
90
+ if (qcow2_encrypt_sectors(s, sector, buffer, buffer,
91
bytes >> BDRV_SECTOR_BITS, true, NULL) < 0) {
92
- ret = -EIO;
93
- goto out;
94
+ return false;
95
}
96
}
97
+ return true;
98
+}
99
+
100
+static int coroutine_fn do_perform_cow_write(BlockDriverState *bs,
101
+ uint64_t cluster_offset,
102
+ unsigned offset_in_cluster,
103
+ uint8_t *buffer,
104
+ unsigned bytes)
105
+{
106
+ QEMUIOVector qiov;
107
+ struct iovec iov = { .iov_base = buffer, .iov_len = bytes };
108
+ int ret;
109
+
110
+ if (bytes == 0) {
111
+ return 0;
112
+ }
28
+ }
113
+
29
+
114
+ qemu_iovec_init_external(&qiov, &iov, 1);
30
assert(s->num_children <= INT_MAX / sizeof(BdrvChild *));
115
31
if (s->num_children == INT_MAX / sizeof(BdrvChild *) ||
116
ret = qcow2_pre_write_overlap_check(bs, 0,
32
s->next_child_index == UINT_MAX) {
117
cluster_offset + offset_in_cluster, bytes);
33
@@ -XXX,XX +XXX,XX @@ static void quorum_del_child(BlockDriverState *bs, BdrvChild *child,
118
if (ret < 0) {
34
return;
119
- goto out;
120
+ return ret;
121
}
35
}
122
36
123
BLKDBG_EVENT(bs->file, BLKDBG_COW_WRITE);
37
+ /* We know now that num_children > threshold, so blkverify must be false */
124
ret = bdrv_co_pwritev(bs->file, cluster_offset + offset_in_cluster,
38
+ assert(!s->is_blkverify);
125
bytes, &qiov, 0);
126
if (ret < 0) {
127
- goto out;
128
+ return ret;
129
}
130
131
- ret = 0;
132
-out:
133
- qemu_vfree(iov.iov_base);
134
- return ret;
135
+ return 0;
136
}
137
138
139
@@ -XXX,XX +XXX,XX @@ static int perform_cow(BlockDriverState *bs, QCowL2Meta *m)
140
BDRVQcow2State *s = bs->opaque;
141
Qcow2COWRegion *start = &m->cow_start;
142
Qcow2COWRegion *end = &m->cow_end;
143
+ unsigned buffer_size;
144
+ uint8_t *start_buffer, *end_buffer;
145
int ret;
146
147
+ assert(start->nb_bytes <= UINT_MAX - end->nb_bytes);
148
+
39
+
149
if (start->nb_bytes == 0 && end->nb_bytes == 0) {
40
bdrv_drained_begin(bs);
150
return 0;
41
151
}
42
/* We can safely remove this child now */
152
153
+ /* Reserve a buffer large enough to store the data from both the
154
+ * start and end COW regions. Add some padding in the middle if
155
+ * necessary to make sure that the end region is optimally aligned */
156
+ buffer_size = QEMU_ALIGN_UP(start->nb_bytes, bdrv_opt_mem_align(bs)) +
157
+ end->nb_bytes;
158
+ start_buffer = qemu_try_blockalign(bs, buffer_size);
159
+ if (start_buffer == NULL) {
160
+ return -ENOMEM;
161
+ }
162
+ /* The part of the buffer where the end region is located */
163
+ end_buffer = start_buffer + buffer_size - end->nb_bytes;
164
+
165
qemu_co_mutex_unlock(&s->lock);
166
- ret = do_perform_cow(bs, m->offset, m->alloc_offset,
167
- start->offset, start->nb_bytes);
168
+ /* First we read the existing data from both COW regions */
169
+ ret = do_perform_cow_read(bs, m->offset, start->offset,
170
+ start_buffer, start->nb_bytes);
171
if (ret < 0) {
172
goto fail;
173
}
174
175
- ret = do_perform_cow(bs, m->offset, m->alloc_offset,
176
- end->offset, end->nb_bytes);
177
+ ret = do_perform_cow_read(bs, m->offset, end->offset,
178
+ end_buffer, end->nb_bytes);
179
+ if (ret < 0) {
180
+ goto fail;
181
+ }
182
+
183
+ /* Encrypt the data if necessary before writing it */
184
+ if (bs->encrypted) {
185
+ if (!do_perform_cow_encrypt(bs, m->offset, start->offset,
186
+ start_buffer, start->nb_bytes) ||
187
+ !do_perform_cow_encrypt(bs, m->offset, end->offset,
188
+ end_buffer, end->nb_bytes)) {
189
+ ret = -EIO;
190
+ goto fail;
191
+ }
192
+ }
193
+
194
+ /* And now we can write everything */
195
+ ret = do_perform_cow_write(bs, m->alloc_offset, start->offset,
196
+ start_buffer, start->nb_bytes);
197
+ if (ret < 0) {
198
+ goto fail;
199
+ }
200
201
+ ret = do_perform_cow_write(bs, m->alloc_offset, end->offset,
202
+ end_buffer, end->nb_bytes);
203
fail:
204
qemu_co_mutex_lock(&s->lock);
205
206
@@ -XXX,XX +XXX,XX @@ fail:
207
qcow2_cache_depends_on_flush(s->l2_table_cache);
208
}
209
210
+ qemu_vfree(start_buffer);
211
return ret;
212
}
213
214
--
43
--
215
1.8.3.1
44
2.19.1
216
45
217
46
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Alberto Garcia <berto@igalia.com>
2
2
3
There used to be throttle_timers_{detach,attach}_aio_context() calls
3
This patch tests that you can add and remove drives from a Quorum
4
in bdrv_set_aio_context(), but since 7ca7f0f6db1fedd28d490795d778cf239
4
using the x-blockdev-change command.
5
they are now in blk_set_aio_context().
6
5
7
Signed-off-by: Alberto Garcia <berto@igalia.com>
6
Signed-off-by: Alberto Garcia <berto@igalia.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
8
---
11
block/throttle-groups.c | 2 +-
9
tests/qemu-iotests/081 | 86 ++++++++++++++++++++++++++++++++++++++
12
1 file changed, 1 insertion(+), 1 deletion(-)
10
tests/qemu-iotests/081.out | 54 ++++++++++++++++++++++++
11
2 files changed, 140 insertions(+)
13
12
14
diff --git a/block/throttle-groups.c b/block/throttle-groups.c
13
diff --git a/tests/qemu-iotests/081 b/tests/qemu-iotests/081
14
index XXXXXXX..XXXXXXX 100755
15
--- a/tests/qemu-iotests/081
16
+++ b/tests/qemu-iotests/081
17
@@ -XXX,XX +XXX,XX @@ quorum="$quorum,file.children.2.driver=raw"
18
19
$QEMU_IO -c "open -o $quorum" | _filter_qemu_io
20
21
+echo
22
+echo "== dynamically adding a child to a quorum =="
23
+
24
+for verify in false true; do
25
+ run_qemu <<EOF
26
+ { "execute": "qmp_capabilities" }
27
+ { "execute": "blockdev-add",
28
+ "arguments": {
29
+ "driver": "quorum",
30
+ "node-name": "drive0-quorum",
31
+ "vote-threshold": 2,
32
+ "blkverify": ${verify},
33
+ "children": [
34
+ {
35
+ "driver": "$IMGFMT",
36
+ "file": {
37
+ "driver": "file",
38
+ "filename": "$TEST_DIR/1.raw"
39
+ }
40
+ },
41
+ {
42
+ "driver": "$IMGFMT",
43
+ "file": {
44
+ "driver": "file",
45
+ "filename": "$TEST_DIR/2.raw"
46
+ }
47
+ }
48
+ ]
49
+ }
50
+ }
51
+ { "execute": "blockdev-add",
52
+ "arguments": {
53
+ "node-name": "drive3",
54
+ "driver": "$IMGFMT",
55
+ "file": {
56
+ "driver": "file",
57
+ "filename": "$TEST_DIR/2.raw"
58
+ }
59
+ }
60
+ }
61
+ { "execute": "x-blockdev-change",
62
+ "arguments": { "parent": "drive0-quorum",
63
+ "node": "drive3" } }
64
+ { "execute": "quit" }
65
+EOF
66
+done
67
+
68
+echo
69
+echo "== dynamically removing a child from a quorum =="
70
+
71
+for verify in false true; do
72
+ for vote_threshold in 1 2; do
73
+ run_qemu <<EOF
74
+ { "execute": "qmp_capabilities" }
75
+ { "execute": "blockdev-add",
76
+ "arguments": {
77
+ "driver": "quorum",
78
+ "node-name": "drive0-quorum",
79
+ "vote-threshold": ${vote_threshold},
80
+ "blkverify": ${verify},
81
+ "children": [
82
+ {
83
+ "driver": "$IMGFMT",
84
+ "file": {
85
+ "driver": "file",
86
+ "filename": "$TEST_DIR/1.raw"
87
+ }
88
+ },
89
+ {
90
+ "driver": "$IMGFMT",
91
+ "file": {
92
+ "driver": "file",
93
+ "filename": "$TEST_DIR/2.raw"
94
+ }
95
+ }
96
+ ]
97
+ }
98
+ }
99
+ { "execute": "x-blockdev-change",
100
+ "arguments": { "parent": "drive0-quorum",
101
+ "child": "children.1" } }
102
+ { "execute": "quit" }
103
+EOF
104
+ done
105
+done
106
+
107
# success, all done
108
echo "*** done"
109
rm -f $seq.full
110
diff --git a/tests/qemu-iotests/081.out b/tests/qemu-iotests/081.out
15
index XXXXXXX..XXXXXXX 100644
111
index XXXXXXX..XXXXXXX 100644
16
--- a/block/throttle-groups.c
112
--- a/tests/qemu-iotests/081.out
17
+++ b/block/throttle-groups.c
113
+++ b/tests/qemu-iotests/081.out
18
@@ -XXX,XX +XXX,XX @@
114
@@ -XXX,XX +XXX,XX @@ read 10485760/10485760 bytes at offset 0
19
* Again, all this is handled internally and is mostly transparent to
115
20
* the outside. The 'throttle_timers' field however has an additional
116
== checking the blkverify mode with invalid settings ==
21
* constraint because it may be temporarily invalid (see for example
117
can't open: blkverify=on can only be set if there are exactly two files and vote-threshold is 2
22
- * bdrv_set_aio_context()). Therefore in this file a thread will
118
+
23
+ * blk_set_aio_context()). Therefore in this file a thread will
119
+== dynamically adding a child to a quorum ==
24
* access some other BlockBackend's timers only after verifying that
120
+Testing:
25
* that BlockBackend has throttled requests in the queue.
121
+QMP_VERSION
26
*/
122
+{"return": {}}
123
+{"return": {}}
124
+{"return": {}}
125
+{"return": {}}
126
+{"return": {}}
127
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
128
+
129
+Testing:
130
+QMP_VERSION
131
+{"return": {}}
132
+{"return": {}}
133
+{"return": {}}
134
+{"error": {"class": "GenericError", "desc": "Cannot add a child to a quorum in blkverify mode"}}
135
+{"return": {}}
136
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
137
+
138
+
139
+== dynamically removing a child from a quorum ==
140
+Testing:
141
+QMP_VERSION
142
+{"return": {}}
143
+{"return": {}}
144
+{"return": {}}
145
+{"return": {}}
146
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
147
+
148
+Testing:
149
+QMP_VERSION
150
+{"return": {}}
151
+{"return": {}}
152
+{"error": {"class": "GenericError", "desc": "The number of children cannot be lower than the vote threshold 2"}}
153
+{"return": {}}
154
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
155
+
156
+Testing:
157
+QMP_VERSION
158
+{"return": {}}
159
+{"error": {"class": "GenericError", "desc": "blkverify=on can only be set if there are exactly two files and vote-threshold is 2"}}
160
+{"error": {"class": "GenericError", "desc": "Cannot find device=drive0-quorum nor node_name=drive0-quorum"}}
161
+{"return": {}}
162
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
163
+
164
+Testing:
165
+QMP_VERSION
166
+{"return": {}}
167
+{"return": {}}
168
+{"error": {"class": "GenericError", "desc": "The number of children cannot be lower than the vote threshold 2"}}
169
+{"return": {}}
170
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
171
+
172
*** done
27
--
173
--
28
1.8.3.1
174
2.19.1
29
175
30
176
diff view generated by jsdifflib
1
Note that this code is generally not running in coroutine context, so
1
To fully change the read-only state of a node, we must not only change
2
this is an actual blocking synchronous operation. We'll fix this in a
2
bs->read_only, but also update bs->open_flags.
3
moment.
4
3
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
5
Reviewed-by: Eric Blake <eblake@redhat.com>
6
Reviewed-by: Alberto Garcia <berto@igalia.com>
7
---
7
---
8
block/qed.c | 61 +++++++++++++++++++------------------------------------------
8
block.c | 7 +++++++
9
1 file changed, 19 insertions(+), 42 deletions(-)
9
1 file changed, 7 insertions(+)
10
10
11
diff --git a/block/qed.c b/block/qed.c
11
diff --git a/block.c b/block.c
12
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
13
--- a/block/qed.c
13
--- a/block.c
14
+++ b/block/qed.c
14
+++ b/block.c
15
@@ -XXX,XX +XXX,XX @@ static void qed_aio_start_io(QEDAIOCB *acb)
15
@@ -XXX,XX +XXX,XX @@ int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
16
qed_aio_next_io(acb, 0);
17
}
18
19
-static void qed_aio_next_io_cb(void *opaque, int ret)
20
-{
21
- QEDAIOCB *acb = opaque;
22
-
23
- qed_aio_next_io(acb, ret);
24
-}
25
-
26
static void qed_plug_allocating_write_reqs(BDRVQEDState *s)
27
{
28
assert(!s->allocating_write_reqs_plugged);
29
@@ -XXX,XX +XXX,XX @@ err:
30
qed_aio_complete(acb, ret);
31
}
32
33
-static void qed_aio_write_l2_update_cb(void *opaque, int ret)
34
-{
35
- QEDAIOCB *acb = opaque;
36
- qed_aio_write_l2_update(acb, ret, acb->cur_cluster);
37
-}
38
-
39
-/**
40
- * Flush new data clusters before updating the L2 table
41
- *
42
- * This flush is necessary when a backing file is in use. A crash during an
43
- * allocating write could result in empty clusters in the image. If the write
44
- * only touched a subregion of the cluster, then backing image sectors have
45
- * been lost in the untouched region. The solution is to flush after writing a
46
- * new data cluster and before updating the L2 table.
47
- */
48
-static void qed_aio_write_flush_before_l2_update(void *opaque, int ret)
49
-{
50
- QEDAIOCB *acb = opaque;
51
- BDRVQEDState *s = acb_to_s(acb);
52
-
53
- if (!bdrv_aio_flush(s->bs->file->bs, qed_aio_write_l2_update_cb, opaque)) {
54
- qed_aio_complete(acb, -EIO);
55
- }
56
-}
57
-
58
/**
59
* Write data to the image file
60
*/
61
@@ -XXX,XX +XXX,XX @@ static void qed_aio_write_main(void *opaque, int ret)
62
BDRVQEDState *s = acb_to_s(acb);
63
uint64_t offset = acb->cur_cluster +
64
qed_offset_into_cluster(s, acb->cur_pos);
65
- BlockCompletionFunc *next_fn;
66
67
trace_qed_aio_write_main(s, acb, ret, offset, acb->cur_qiov.size);
68
69
@@ -XXX,XX +XXX,XX @@ static void qed_aio_write_main(void *opaque, int ret)
70
return;
71
}
16
}
72
17
73
+ BLKDBG_EVENT(s->bs->file, BLKDBG_WRITE_AIO);
18
bs->read_only = read_only;
74
+ ret = bdrv_pwritev(s->bs->file, offset, &acb->cur_qiov);
19
+
75
+ if (ret >= 0) {
20
+ if (read_only) {
76
+ ret = 0;
21
+ bs->open_flags &= ~BDRV_O_RDWR;
22
+ } else {
23
+ bs->open_flags |= BDRV_O_RDWR;
77
+ }
24
+ }
78
+
25
+
79
if (acb->find_cluster_ret == QED_CLUSTER_FOUND) {
26
return 0;
80
- next_fn = qed_aio_next_io_cb;
81
+ qed_aio_next_io(acb, ret);
82
} else {
83
if (s->bs->backing) {
84
- next_fn = qed_aio_write_flush_before_l2_update;
85
- } else {
86
- next_fn = qed_aio_write_l2_update_cb;
87
+ /*
88
+ * Flush new data clusters before updating the L2 table
89
+ *
90
+ * This flush is necessary when a backing file is in use. A crash
91
+ * during an allocating write could result in empty clusters in the
92
+ * image. If the write only touched a subregion of the cluster,
93
+ * then backing image sectors have been lost in the untouched
94
+ * region. The solution is to flush after writing a new data
95
+ * cluster and before updating the L2 table.
96
+ */
97
+ ret = bdrv_flush(s->bs->file->bs);
98
}
99
+ qed_aio_write_l2_update(acb, ret, acb->cur_cluster);
100
}
101
-
102
- BLKDBG_EVENT(s->bs->file, BLKDBG_WRITE_AIO);
103
- bdrv_aio_writev(s->bs->file, offset / BDRV_SECTOR_SIZE,
104
- &acb->cur_qiov, acb->cur_qiov.size / BDRV_SECTOR_SIZE,
105
- next_fn, acb);
106
}
27
}
107
28
108
/**
109
--
29
--
110
1.8.3.1
30
2.19.1
111
31
112
32
diff view generated by jsdifflib
1
This fixes the last place where we degraded from AIO to actual blocking
1
If a management application builds the block graph node by node, the
2
synchronous I/O requests. Putting it into a coroutine means that instead
2
protocol layer doesn't inherit its read-only option from the format
3
of blocking, the coroutine simply yields while doing I/O.
3
layer any more, so it must be set explicitly.
4
5
Backing files should work on read-only storage, but at the same time, a
6
block job like commit should be able to reopen them read-write if they
7
are on read-write storage. However, without option inheritance, reopen
8
only changes the read-only option for the root node (typically the
9
format layer), but not the protocol layer, so reopening fails (the
10
format layer wants to get write permissions, but the protocol layer is
11
still read-only).
12
13
A simple workaround for the problem in the management tool would be to
14
open the protocol layer always read-write and to make only the format
15
layer read-only for backing files. However, sometimes the file is
16
actually stored on read-only storage and we don't know whether the image
17
can be opened read-write (for example, for NBD it depends on the server
18
we're trying to connect to). This adds an option that makes QEMU try to
19
open the image read-write, but allows it to degrade to a read-only mode
20
without returning an error.
21
22
The documentation for this option is consciously phrased in a way that
23
allows QEMU to switch to a better model eventually: Instead of trying
24
when the image is first opened, making the read-only flag dynamic and
25
changing it automatically whenever the first BLK_PERM_WRITE user is
26
attached or the last one is detached would be much more useful
27
behaviour.
28
29
Unfortunately, this more useful behaviour is also a lot harder to
30
implement, and libvirt needs a solution now before it can switch to
31
-blockdev, so let's start with this easier approach for now.
32
33
Instead of adding a new auto-read-only option, turning the existing
34
read-only into an enum (with a bool alternate for compatibility) was
35
considered, but it complicated the implementation to the point that it
36
didn't seem to be worth it.
4
37
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
38
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
39
Reviewed-by: Eric Blake <eblake@redhat.com>
7
---
40
---
8
block/qed.c | 33 +++++++++++++++++----------------
41
qapi/block-core.json | 7 +++++++
9
1 file changed, 17 insertions(+), 16 deletions(-)
42
include/block/block.h | 2 ++
43
block.c | 17 +++++++++++++++++
44
block/vvfat.c | 1 +
45
blockdev.c | 2 +-
46
5 files changed, 28 insertions(+), 1 deletion(-)
10
47
11
diff --git a/block/qed.c b/block/qed.c
48
diff --git a/qapi/block-core.json b/qapi/block-core.json
12
index XXXXXXX..XXXXXXX 100644
49
index XXXXXXX..XXXXXXX 100644
13
--- a/block/qed.c
50
--- a/qapi/block-core.json
14
+++ b/block/qed.c
51
+++ b/qapi/block-core.json
15
@@ -XXX,XX +XXX,XX @@ static void qed_unplug_allocating_write_reqs(BDRVQEDState *s)
52
@@ -XXX,XX +XXX,XX @@
16
qemu_co_enter_next(&s->allocating_write_reqs);
53
# either generally or in certain configurations. In this case,
54
# the default value does not work and the option must be
55
# specified explicitly.
56
+# @auto-read-only: if true and @read-only is false, QEMU may automatically
57
+# decide not to open the image read-write as requested, but
58
+# fall back to read-only instead (and switch between the modes
59
+# later), e.g. depending on whether the image file is writable
60
+# or whether a writing user is attached to the node
61
+# (default: false, since 3.1)
62
# @detect-zeroes: detect and optimize zero writes (Since 2.1)
63
# (default: off)
64
# @force-share: force share all permission on added nodes.
65
@@ -XXX,XX +XXX,XX @@
66
'*discard': 'BlockdevDiscardOptions',
67
'*cache': 'BlockdevCacheOptions',
68
'*read-only': 'bool',
69
+ '*auto-read-only': 'bool',
70
'*force-share': 'bool',
71
'*detect-zeroes': 'BlockdevDetectZeroesOptions' },
72
'discriminator': 'driver',
73
diff --git a/include/block/block.h b/include/block/block.h
74
index XXXXXXX..XXXXXXX 100644
75
--- a/include/block/block.h
76
+++ b/include/block/block.h
77
@@ -XXX,XX +XXX,XX @@ typedef struct HDGeometry {
78
select an appropriate protocol driver,
79
ignoring the format layer */
80
#define BDRV_O_NO_IO 0x10000 /* don't initialize for I/O */
81
+#define BDRV_O_AUTO_RDONLY 0x20000 /* degrade to read-only if opening read-write fails */
82
83
#define BDRV_O_CACHE_MASK (BDRV_O_NOCACHE | BDRV_O_NO_FLUSH)
84
85
@@ -XXX,XX +XXX,XX @@ typedef struct HDGeometry {
86
#define BDRV_OPT_CACHE_DIRECT "cache.direct"
87
#define BDRV_OPT_CACHE_NO_FLUSH "cache.no-flush"
88
#define BDRV_OPT_READ_ONLY "read-only"
89
+#define BDRV_OPT_AUTO_READ_ONLY "auto-read-only"
90
#define BDRV_OPT_DISCARD "discard"
91
#define BDRV_OPT_FORCE_SHARE "force-share"
92
93
diff --git a/block.c b/block.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/block.c
96
+++ b/block.c
97
@@ -XXX,XX +XXX,XX @@ static void bdrv_inherited_options(int *child_flags, QDict *child_options,
98
99
/* Inherit the read-only option from the parent if it's not set */
100
qdict_copy_default(child_options, parent_options, BDRV_OPT_READ_ONLY);
101
+ qdict_copy_default(child_options, parent_options, BDRV_OPT_AUTO_READ_ONLY);
102
103
/* Our block drivers take care to send flushes and respect unmap policy,
104
* so we can default to enable both on lower layers regardless of the
105
@@ -XXX,XX +XXX,XX @@ static void bdrv_backing_options(int *child_flags, QDict *child_options,
106
107
/* backing files always opened read-only */
108
qdict_set_default_str(child_options, BDRV_OPT_READ_ONLY, "on");
109
+ qdict_set_default_str(child_options, BDRV_OPT_AUTO_READ_ONLY, "off");
110
flags &= ~BDRV_O_COPY_ON_READ;
111
112
/* snapshot=on is handled on the top layer */
113
@@ -XXX,XX +XXX,XX @@ static void update_flags_from_options(int *flags, QemuOpts *opts)
114
*flags |= BDRV_O_RDWR;
115
}
116
117
+ assert(qemu_opt_find(opts, BDRV_OPT_AUTO_READ_ONLY));
118
+ if (qemu_opt_get_bool_del(opts, BDRV_OPT_AUTO_READ_ONLY, false)) {
119
+ *flags |= BDRV_O_AUTO_RDONLY;
120
+ }
17
}
121
}
18
122
19
-static void qed_clear_need_check(void *opaque, int ret)
123
static void update_options_from_flags(QDict *options, int flags)
20
+static void qed_need_check_timer_entry(void *opaque)
124
@@ -XXX,XX +XXX,XX @@ static void update_options_from_flags(QDict *options, int flags)
125
if (!qdict_haskey(options, BDRV_OPT_READ_ONLY)) {
126
qdict_put_bool(options, BDRV_OPT_READ_ONLY, !(flags & BDRV_O_RDWR));
127
}
128
+ if (!qdict_haskey(options, BDRV_OPT_AUTO_READ_ONLY)) {
129
+ qdict_put_bool(options, BDRV_OPT_AUTO_READ_ONLY,
130
+ flags & BDRV_O_AUTO_RDONLY);
131
+ }
132
}
133
134
static void bdrv_assign_node_name(BlockDriverState *bs,
135
@@ -XXX,XX +XXX,XX @@ QemuOptsList bdrv_runtime_opts = {
136
.type = QEMU_OPT_BOOL,
137
.help = "Node is opened in read-only mode",
138
},
139
+ {
140
+ .name = BDRV_OPT_AUTO_READ_ONLY,
141
+ .type = QEMU_OPT_BOOL,
142
+ .help = "Node can become read-only if opening read-write fails",
143
+ },
144
{
145
.name = "detect-zeroes",
146
.type = QEMU_OPT_STRING,
147
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp)
148
qdict_set_default_str(qdict, BDRV_OPT_CACHE_DIRECT, "off");
149
qdict_set_default_str(qdict, BDRV_OPT_CACHE_NO_FLUSH, "off");
150
qdict_set_default_str(qdict, BDRV_OPT_READ_ONLY, "off");
151
+ qdict_set_default_str(qdict, BDRV_OPT_AUTO_READ_ONLY, "off");
152
+
153
}
154
155
bs = bdrv_open_inherit(NULL, reference, qdict, 0, NULL, NULL, errp);
156
diff --git a/block/vvfat.c b/block/vvfat.c
157
index XXXXXXX..XXXXXXX 100644
158
--- a/block/vvfat.c
159
+++ b/block/vvfat.c
160
@@ -XXX,XX +XXX,XX @@ static void vvfat_qcow_options(int *child_flags, QDict *child_options,
161
int parent_flags, QDict *parent_options)
21
{
162
{
22
BDRVQEDState *s = opaque;
163
qdict_set_default_str(child_options, BDRV_OPT_READ_ONLY, "off");
23
+ int ret;
164
+ qdict_set_default_str(child_options, BDRV_OPT_AUTO_READ_ONLY, "off");
24
165
qdict_set_default_str(child_options, BDRV_OPT_CACHE_NO_FLUSH, "on");
25
- if (ret) {
26
+ /* The timer should only fire when allocating writes have drained */
27
+ assert(!s->allocating_acb);
28
+
29
+ trace_qed_need_check_timer_cb(s);
30
+
31
+ qed_acquire(s);
32
+ qed_plug_allocating_write_reqs(s);
33
+
34
+ /* Ensure writes are on disk before clearing flag */
35
+ ret = bdrv_co_flush(s->bs->file->bs);
36
+ qed_release(s);
37
+ if (ret < 0) {
38
qed_unplug_allocating_write_reqs(s);
39
return;
40
}
41
@@ -XXX,XX +XXX,XX @@ static void qed_clear_need_check(void *opaque, int ret)
42
43
qed_unplug_allocating_write_reqs(s);
44
45
- ret = bdrv_flush(s->bs);
46
+ ret = bdrv_co_flush(s->bs);
47
(void) ret;
48
}
166
}
49
167
50
static void qed_need_check_timer_cb(void *opaque)
168
diff --git a/blockdev.c b/blockdev.c
51
{
169
index XXXXXXX..XXXXXXX 100644
52
- BDRVQEDState *s = opaque;
170
--- a/blockdev.c
53
-
171
+++ b/blockdev.c
54
- /* The timer should only fire when allocating writes have drained */
172
@@ -XXX,XX +XXX,XX @@ void qmp_blockdev_change_medium(bool has_device, const char *device,
55
- assert(!s->allocating_acb);
173
56
-
174
bdrv_flags = blk_get_open_flags_from_root_state(blk);
57
- trace_qed_need_check_timer_cb(s);
175
bdrv_flags &= ~(BDRV_O_TEMPORARY | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING |
58
-
176
- BDRV_O_PROTOCOL);
59
- qed_acquire(s);
177
+ BDRV_O_PROTOCOL | BDRV_O_AUTO_RDONLY);
60
- qed_plug_allocating_write_reqs(s);
178
61
-
179
if (!has_read_only) {
62
- /* Ensure writes are on disk before clearing flag */
180
read_only = BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN;
63
- bdrv_aio_flush(s->bs->file->bs, qed_clear_need_check, s);
64
- qed_release(s);
65
+ Coroutine *co = qemu_coroutine_create(qed_need_check_timer_entry, opaque);
66
+ qemu_coroutine_enter(co);
67
}
68
69
void qed_acquire(BDRVQEDState *s)
70
--
181
--
71
1.8.3.1
182
2.19.1
72
183
73
184
diff view generated by jsdifflib
1
This documents the driver-specific options for the raw, qcow2 and file
1
Commit e2b8247a322 introduced an error path in qemu_rbd_open() after
2
block drivers for the man page. For everything else, we refer to the
2
calling rbd_open(), but neglected to close the image again in this error
3
QAPI documentation.
3
path. The error path should contain everything that the regular close
4
function qemu_rbd_close() contains.
5
6
This adds the missing rbd_close() call.
4
7
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
9
Reviewed-by: Eric Blake <eblake@redhat.com>
7
Reviewed-by: Max Reitz <mreitz@redhat.com>
8
---
10
---
9
qemu-options.hx | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
11
block/rbd.c | 1 +
10
1 file changed, 114 insertions(+), 1 deletion(-)
12
1 file changed, 1 insertion(+)
11
13
12
diff --git a/qemu-options.hx b/qemu-options.hx
14
diff --git a/block/rbd.c b/block/rbd.c
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/qemu-options.hx
16
--- a/block/rbd.c
15
+++ b/qemu-options.hx
17
+++ b/block/rbd.c
16
@@ -XXX,XX +XXX,XX @@ STEXI
18
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
17
@item -blockdev @var{option}[,@var{option}[,@var{option}[,...]]]
19
"automatically marking the image read-only.");
18
@findex -blockdev
20
r = bdrv_set_read_only(bs, true, &local_err);
19
21
if (r < 0) {
20
-Define a new block driver node.
22
+ rbd_close(s->image);
21
+Define a new block driver node. Some of the options apply to all block drivers,
23
error_propagate(errp, local_err);
22
+other options are only accepted for a specific block driver. See below for a
24
goto failed_open;
23
+list of generic options and options for the most common block drivers.
25
}
24
+
25
+Options that expect a reference to another node (e.g. @code{file}) can be
26
+given in two ways. Either you specify the node name of an already existing node
27
+(file=@var{node-name}), or you define a new node inline, adding options
28
+for the referenced node after a dot (file.filename=@var{path},file.aio=native).
29
+
30
+A block driver node created with @option{-blockdev} can be used for a guest
31
+device by specifying its node name for the @code{drive} property in a
32
+@option{-device} argument that defines a block device.
33
34
@table @option
35
@item Valid options for any block driver node:
36
@@ -XXX,XX +XXX,XX @@ zero write commands. You may even choose "unmap" if @var{discard} is set
37
to "unmap" to allow a zero write to be converted to an @code{unmap} operation.
38
@end table
39
40
+@item Driver-specific options for @code{file}
41
+
42
+This is the protocol-level block driver for accessing regular files.
43
+
44
+@table @code
45
+@item filename
46
+The path to the image file in the local filesystem
47
+@item aio
48
+Specifies the AIO backend (threads/native, default: threads)
49
+@end table
50
+Example:
51
+@example
52
+-blockdev driver=file,node-name=disk,filename=disk.img
53
+@end example
54
+
55
+@item Driver-specific options for @code{raw}
56
+
57
+This is the image format block driver for raw images. It is usually
58
+stacked on top of a protocol level block driver such as @code{file}.
59
+
60
+@table @code
61
+@item file
62
+Reference to or definition of the data source block driver node
63
+(e.g. a @code{file} driver node)
64
+@end table
65
+Example 1:
66
+@example
67
+-blockdev driver=file,node-name=disk_file,filename=disk.img
68
+-blockdev driver=raw,node-name=disk,file=disk_file
69
+@end example
70
+Example 2:
71
+@example
72
+-blockdev driver=raw,node-name=disk,file.driver=file,file.filename=disk.img
73
+@end example
74
+
75
+@item Driver-specific options for @code{qcow2}
76
+
77
+This is the image format block driver for qcow2 images. It is usually
78
+stacked on top of a protocol level block driver such as @code{file}.
79
+
80
+@table @code
81
+@item file
82
+Reference to or definition of the data source block driver node
83
+(e.g. a @code{file} driver node)
84
+
85
+@item backing
86
+Reference to or definition of the backing file block device (default is taken
87
+from the image file). It is allowed to pass an empty string here in order to
88
+disable the default backing file.
89
+
90
+@item lazy-refcounts
91
+Whether to enable the lazy refcounts feature (on/off; default is taken from the
92
+image file)
93
+
94
+@item cache-size
95
+The maximum total size of the L2 table and refcount block caches in bytes
96
+(default: 1048576 bytes or 8 clusters, whichever is larger)
97
+
98
+@item l2-cache-size
99
+The maximum size of the L2 table cache in bytes
100
+(default: 4/5 of the total cache size)
101
+
102
+@item refcount-cache-size
103
+The maximum size of the refcount block cache in bytes
104
+(default: 1/5 of the total cache size)
105
+
106
+@item cache-clean-interval
107
+Clean unused entries in the L2 and refcount caches. The interval is in seconds.
108
+The default value is 0 and it disables this feature.
109
+
110
+@item pass-discard-request
111
+Whether discard requests to the qcow2 device should be forwarded to the data
112
+source (on/off; default: on if discard=unmap is specified, off otherwise)
113
+
114
+@item pass-discard-snapshot
115
+Whether discard requests for the data source should be issued when a snapshot
116
+operation (e.g. deleting a snapshot) frees clusters in the qcow2 file (on/off;
117
+default: on)
118
+
119
+@item pass-discard-other
120
+Whether discard requests for the data source should be issued on other
121
+occasions where a cluster gets freed (on/off; default: off)
122
+
123
+@item overlap-check
124
+Which overlap checks to perform for writes to the image
125
+(none/constant/cached/all; default: cached). For details or finer
126
+granularity control refer to the QAPI documentation of @code{blockdev-add}.
127
+@end table
128
+
129
+Example 1:
130
+@example
131
+-blockdev driver=file,node-name=my_file,filename=/tmp/disk.qcow2
132
+-blockdev driver=qcow2,node-name=hda,file=my_file,overlap-check=none,cache-size=16777216
133
+@end example
134
+Example 2:
135
+@example
136
+-blockdev driver=qcow2,node-name=disk,file.driver=http,file.filename=http://example.com/image.qcow2
137
+@end example
138
+
139
+@item Driver-specific options for other drivers
140
+Please refer to the QAPI documentation of the @code{blockdev-add} QMP command.
141
+
142
@end table
143
144
ETEXI
145
--
26
--
146
1.8.3.1
27
2.19.1
147
28
148
29
diff view generated by jsdifflib
1
qed_commit_l2_update() is unconditionally called at the end of
1
Some block drivers have traditionally changed their node to read-only
2
qed_aio_write_l1_update(). Inline it.
2
mode without asking the user. This behaviour has been marked deprecated
3
since 2.11, expecting users to provide an explicit read-only=on option.
4
5
Now that we have auto-read-only=on, enable these drivers to make use of
6
the option.
7
8
This is the only use of bdrv_set_read_only(), so we can make it a bit
9
more specific and turn it into a bdrv_apply_auto_read_only() that is
10
more convenient for drivers to use.
3
11
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
13
Reviewed-by: Eric Blake <eblake@redhat.com>
6
---
14
---
7
block/qed.c | 36 ++++++++++++++----------------------
15
include/block/block.h | 3 ++-
8
1 file changed, 14 insertions(+), 22 deletions(-)
16
block.c | 42 +++++++++++++++++++++++++++---------------
9
17
block/bochs.c | 17 ++++++-----------
10
diff --git a/block/qed.c b/block/qed.c
18
block/cloop.c | 16 +++++-----------
11
index XXXXXXX..XXXXXXX 100644
19
block/dmg.c | 16 +++++-----------
12
--- a/block/qed.c
20
block/rbd.c | 15 ++++-----------
13
+++ b/block/qed.c
21
block/vvfat.c | 10 ++--------
14
@@ -XXX,XX +XXX,XX @@ static void qed_aio_complete(QEDAIOCB *acb, int ret)
22
7 files changed, 51 insertions(+), 68 deletions(-)
23
24
diff --git a/include/block/block.h b/include/block/block.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/include/block/block.h
27
+++ b/include/block/block.h
28
@@ -XXX,XX +XXX,XX @@ int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
29
bool bdrv_is_read_only(BlockDriverState *bs);
30
int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
31
bool ignore_allow_rdw, Error **errp);
32
-int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp);
33
+int bdrv_apply_auto_read_only(BlockDriverState *bs, const char *errmsg,
34
+ Error **errp);
35
bool bdrv_is_writable(BlockDriverState *bs);
36
bool bdrv_is_sg(BlockDriverState *bs);
37
bool bdrv_is_inserted(BlockDriverState *bs);
38
diff --git a/block.c b/block.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/block.c
41
+++ b/block.c
42
@@ -XXX,XX +XXX,XX @@ int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
43
return 0;
15
}
44
}
16
45
17
/**
46
-/* TODO Remove (deprecated since 2.11)
18
- * Commit the current L2 table to the cache
47
- * Block drivers are not supposed to automatically change bs->read_only.
19
+ * Update L1 table with new L2 table offset and write it out
48
- * Instead, they should just check whether they can provide what the user
20
*/
49
- * explicitly requested and error out if read-write is requested, but they can
21
-static void qed_commit_l2_update(void *opaque, int ret)
50
- * only provide read-only access. */
22
+static void qed_aio_write_l1_update(void *opaque, int ret)
51
-int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
52
+/*
53
+ * Called by a driver that can only provide a read-only image.
54
+ *
55
+ * Returns 0 if the node is already read-only or it could switch the node to
56
+ * read-only because BDRV_O_AUTO_RDONLY is set.
57
+ *
58
+ * Returns -EACCES if the node is read-write and BDRV_O_AUTO_RDONLY is not set
59
+ * or bdrv_can_set_read_only() forbids making the node read-only. If @errmsg
60
+ * is not NULL, it is used as the error message for the Error object.
61
+ */
62
+int bdrv_apply_auto_read_only(BlockDriverState *bs, const char *errmsg,
63
+ Error **errp)
23
{
64
{
24
QEDAIOCB *acb = opaque;
65
int ret = 0;
25
BDRVQEDState *s = acb_to_s(acb);
66
26
CachedL2Table *l2_table = acb->request.l2_table;
67
- ret = bdrv_can_set_read_only(bs, read_only, false, errp);
27
uint64_t l2_offset = l2_table->offset;
68
- if (ret < 0) {
28
+ int index;
69
- return ret;
29
+
70
+ if (!(bs->open_flags & BDRV_O_RDWR)) {
30
+ if (ret) {
71
+ return 0;
31
+ qed_aio_complete(acb, ret);
72
+ }
32
+ return;
73
+ if (!(bs->open_flags & BDRV_O_AUTO_RDONLY)) {
33
+ }
74
+ goto fail;
34
75
}
35
+ index = qed_l1_index(s, acb->cur_pos);
76
36
+ s->l1_table->offsets[index] = l2_table->offset;
77
- bs->read_only = read_only;
37
+
78
-
38
+ ret = qed_write_l1_table(s, index, 1);
79
- if (read_only) {
39
+
80
- bs->open_flags &= ~BDRV_O_RDWR;
40
+ /* Commit the current L2 table to the cache */
81
- } else {
41
qed_commit_l2_cache_entry(&s->l2_cache, l2_table);
82
- bs->open_flags |= BDRV_O_RDWR;
42
83
+ ret = bdrv_can_set_read_only(bs, true, false, NULL);
43
/* This is guaranteed to succeed because we just committed the entry to the
84
+ if (ret < 0) {
44
@@ -XXX,XX +XXX,XX @@ static void qed_commit_l2_update(void *opaque, int ret)
85
+ goto fail;
45
qed_aio_next_io(acb, ret);
86
}
87
88
+ bs->read_only = true;
89
+ bs->open_flags &= ~BDRV_O_RDWR;
90
+
91
return 0;
92
+
93
+fail:
94
+ error_setg(errp, "%s", errmsg ?: "Image is read-only");
95
+ return -EACCES;
46
}
96
}
47
97
48
-/**
98
void bdrv_get_full_backing_filename_from_filename(const char *backed,
49
- * Update L1 table with new L2 table offset and write it out
99
diff --git a/block/bochs.c b/block/bochs.c
50
- */
100
index XXXXXXX..XXXXXXX 100644
51
-static void qed_aio_write_l1_update(void *opaque, int ret)
101
--- a/block/bochs.c
52
-{
102
+++ b/block/bochs.c
53
- QEDAIOCB *acb = opaque;
103
@@ -XXX,XX +XXX,XX @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
54
- BDRVQEDState *s = acb_to_s(acb);
104
struct bochs_header bochs;
55
- int index;
105
int ret;
56
-
106
57
- if (ret) {
107
+ /* No write support yet */
58
- qed_aio_complete(acb, ret);
108
+ ret = bdrv_apply_auto_read_only(bs, NULL, errp);
59
- return;
109
+ if (ret < 0) {
110
+ return ret;
111
+ }
112
+
113
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
114
false, errp);
115
if (!bs->file) {
116
return -EINVAL;
117
}
118
119
- if (!bdrv_is_read_only(bs)) {
120
- error_report("Opening bochs images without an explicit read-only=on "
121
- "option is deprecated. Future versions will refuse to "
122
- "open the image instead of automatically marking the "
123
- "image read-only.");
124
- ret = bdrv_set_read_only(bs, true, errp); /* no write support yet */
125
- if (ret < 0) {
126
- return ret;
127
- }
60
- }
128
- }
61
-
129
-
62
- index = qed_l1_index(s, acb->cur_pos);
130
ret = bdrv_pread(bs->file, 0, &bochs, sizeof(bochs));
63
- s->l1_table->offsets[index] = acb->request.l2_table->offset;
131
if (ret < 0) {
64
-
132
return ret;
65
- ret = qed_write_l1_table(s, index, 1);
133
diff --git a/block/cloop.c b/block/cloop.c
66
- qed_commit_l2_update(acb, ret);
134
index XXXXXXX..XXXXXXX 100644
67
-}
135
--- a/block/cloop.c
68
136
+++ b/block/cloop.c
69
/**
137
@@ -XXX,XX +XXX,XX @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags,
70
* Update L2 table with new cluster offsets and write them out
138
uint32_t offsets_size, max_compressed_block_size = 1, i;
139
int ret;
140
141
+ ret = bdrv_apply_auto_read_only(bs, NULL, errp);
142
+ if (ret < 0) {
143
+ return ret;
144
+ }
145
+
146
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
147
false, errp);
148
if (!bs->file) {
149
return -EINVAL;
150
}
151
152
- if (!bdrv_is_read_only(bs)) {
153
- error_report("Opening cloop images without an explicit read-only=on "
154
- "option is deprecated. Future versions will refuse to "
155
- "open the image instead of automatically marking the "
156
- "image read-only.");
157
- ret = bdrv_set_read_only(bs, true, errp);
158
- if (ret < 0) {
159
- return ret;
160
- }
161
- }
162
-
163
/* read header */
164
ret = bdrv_pread(bs->file, 128, &s->block_size, 4);
165
if (ret < 0) {
166
diff --git a/block/dmg.c b/block/dmg.c
167
index XXXXXXX..XXXXXXX 100644
168
--- a/block/dmg.c
169
+++ b/block/dmg.c
170
@@ -XXX,XX +XXX,XX @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
171
int64_t offset;
172
int ret;
173
174
+ ret = bdrv_apply_auto_read_only(bs, NULL, errp);
175
+ if (ret < 0) {
176
+ return ret;
177
+ }
178
+
179
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
180
false, errp);
181
if (!bs->file) {
182
return -EINVAL;
183
}
184
185
- if (!bdrv_is_read_only(bs)) {
186
- error_report("Opening dmg images without an explicit read-only=on "
187
- "option is deprecated. Future versions will refuse to "
188
- "open the image instead of automatically marking the "
189
- "image read-only.");
190
- ret = bdrv_set_read_only(bs, true, errp);
191
- if (ret < 0) {
192
- return ret;
193
- }
194
- }
195
-
196
block_module_load_one("dmg-bz2");
197
198
s->n_chunks = 0;
199
diff --git a/block/rbd.c b/block/rbd.c
200
index XXXXXXX..XXXXXXX 100644
201
--- a/block/rbd.c
202
+++ b/block/rbd.c
203
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
204
/* If we are using an rbd snapshot, we must be r/o, otherwise
205
* leave as-is */
206
if (s->snap != NULL) {
207
- if (!bdrv_is_read_only(bs)) {
208
- error_report("Opening rbd snapshots without an explicit "
209
- "read-only=on option is deprecated. Future versions "
210
- "will refuse to open the image instead of "
211
- "automatically marking the image read-only.");
212
- r = bdrv_set_read_only(bs, true, &local_err);
213
- if (r < 0) {
214
- rbd_close(s->image);
215
- error_propagate(errp, local_err);
216
- goto failed_open;
217
- }
218
+ r = bdrv_apply_auto_read_only(bs, "rbd snapshots are read-only", errp);
219
+ if (r < 0) {
220
+ rbd_close(s->image);
221
+ goto failed_open;
222
}
223
}
224
225
diff --git a/block/vvfat.c b/block/vvfat.c
226
index XXXXXXX..XXXXXXX 100644
227
--- a/block/vvfat.c
228
+++ b/block/vvfat.c
229
@@ -XXX,XX +XXX,XX @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
230
"Unable to set VVFAT to 'rw' when drive is read-only");
231
goto fail;
232
}
233
- } else if (!bdrv_is_read_only(bs)) {
234
- error_report("Opening non-rw vvfat images without an explicit "
235
- "read-only=on option is deprecated. Future versions "
236
- "will refuse to open the image instead of "
237
- "automatically marking the image read-only.");
238
- /* read only is the default for safety */
239
- ret = bdrv_set_read_only(bs, true, &local_err);
240
+ } else {
241
+ ret = bdrv_apply_auto_read_only(bs, NULL, errp);
242
if (ret < 0) {
243
- error_propagate(errp, local_err);
244
goto fail;
245
}
246
}
71
--
247
--
72
1.8.3.1
248
2.19.1
73
249
74
250
diff view generated by jsdifflib
1
Don't recurse into qed_aio_next_io() and qed_aio_complete() here, but
1
If read-only=off, but auto-read-only=on is given, open a read-write NBD
2
just return an error code and let the caller handle it.
2
connection if the server provides a read-write export, but instead of
3
erroring out for read-only exports, just degrade to read-only.
3
4
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
6
---
7
---
7
block/qed.c | 43 ++++++++++++++++++++++++++-----------------
8
block/nbd-client.c | 10 +++++-----
8
1 file changed, 26 insertions(+), 17 deletions(-)
9
1 file changed, 5 insertions(+), 5 deletions(-)
9
10
10
diff --git a/block/qed.c b/block/qed.c
11
diff --git a/block/nbd-client.c b/block/nbd-client.c
11
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
12
--- a/block/qed.c
13
--- a/block/nbd-client.c
13
+++ b/block/qed.c
14
+++ b/block/nbd-client.c
14
@@ -XXX,XX +XXX,XX @@ static int qed_aio_write_l1_update(QEDAIOCB *acb)
15
@@ -XXX,XX +XXX,XX @@ int nbd_client_init(BlockDriverState *bs,
15
/**
16
logout("Failed to negotiate with the NBD server\n");
16
* Update L2 table with new cluster offsets and write them out
17
return ret;
17
*/
18
}
18
-static void qed_aio_write_l2_update(QEDAIOCB *acb, int ret, uint64_t offset)
19
- if (client->info.flags & NBD_FLAG_READ_ONLY &&
19
+static int qed_aio_write_l2_update(QEDAIOCB *acb, uint64_t offset)
20
- !bdrv_is_read_only(bs)) {
20
{
21
- error_setg(errp,
21
BDRVQEDState *s = acb_to_s(acb);
22
- "request for write access conflicts with read-only export");
22
bool need_alloc = acb->find_cluster_ret == QED_CLUSTER_L1;
23
- return -EACCES;
23
- int index;
24
+ if (client->info.flags & NBD_FLAG_READ_ONLY) {
24
-
25
+ ret = bdrv_apply_auto_read_only(bs, "NBD export is read-only", errp);
25
- if (ret) {
26
+ if (ret < 0) {
26
- goto err;
27
- }
28
+ int index, ret;
29
30
if (need_alloc) {
31
qed_unref_l2_cache_entry(acb->request.l2_table);
32
@@ -XXX,XX +XXX,XX @@ static void qed_aio_write_l2_update(QEDAIOCB *acb, int ret, uint64_t offset)
33
/* Write out the whole new L2 table */
34
ret = qed_write_l2_table(s, &acb->request, 0, s->table_nelems, true);
35
if (ret) {
36
- goto err;
37
+ return ret;
38
}
39
- ret = qed_aio_write_l1_update(acb);
40
- qed_aio_next_io(acb, ret);
41
-
42
+ return qed_aio_write_l1_update(acb);
43
} else {
44
/* Write out only the updated part of the L2 table */
45
ret = qed_write_l2_table(s, &acb->request, index, acb->cur_nclusters,
46
false);
47
- qed_aio_next_io(acb, ret);
48
+ if (ret) {
49
+ return ret;
27
+ return ret;
50
+ }
28
+ }
51
}
29
}
52
- return;
30
if (client->info.flags & NBD_FLAG_SEND_FUA) {
53
-
31
bs->supported_write_flags = BDRV_REQ_FUA;
54
-err:
55
- qed_aio_complete(acb, ret);
56
+ return 0;
57
}
58
59
/**
60
@@ -XXX,XX +XXX,XX @@ static void qed_aio_write_main(void *opaque, int ret)
61
*/
62
ret = bdrv_flush(s->bs->file->bs);
63
}
64
- qed_aio_write_l2_update(acb, ret, acb->cur_cluster);
65
+ if (ret) {
66
+ goto err;
67
+ }
68
+ ret = qed_aio_write_l2_update(acb, acb->cur_cluster);
69
+ if (ret) {
70
+ goto err;
71
+ }
72
+ qed_aio_next_io(acb, 0);
73
}
74
+ return;
75
+
76
+err:
77
+ qed_aio_complete(acb, ret);
78
}
79
80
/**
81
@@ -XXX,XX +XXX,XX @@ static void qed_aio_write_zero_cluster(void *opaque, int ret)
82
return;
83
}
84
85
- qed_aio_write_l2_update(acb, 0, 1);
86
+ ret = qed_aio_write_l2_update(acb, 1);
87
+ if (ret < 0) {
88
+ qed_aio_complete(acb, ret);
89
+ return;
90
+ }
91
+ qed_aio_next_io(acb, 0);
92
}
93
94
/**
95
--
32
--
96
1.8.3.1
33
2.19.1
97
34
98
35
diff view generated by jsdifflib
1
This adds documentation for the -blockdev options that apply to all
1
If read-only=off, but auto-read-only=on is given, open the file
2
nodes independent of the block driver used.
2
read-write if we have the permissions, but instead of erroring out for
3
3
read-only files, just degrade to read-only.
4
All options that are shared by -blockdev and -drive are now explained in
5
the section for -blockdev. The documentation of -drive mentions that all
6
-blockdev options are accepted as well.
7
4
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Reviewed-by: Eric Blake <eblake@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
10
Reviewed-by: Max Reitz <mreitz@redhat.com>
11
---
7
---
12
qemu-options.hx | 108 +++++++++++++++++++++++++++++++++++++++++---------------
8
block/file-posix.c | 19 ++++++++++++++++---
13
1 file changed, 79 insertions(+), 29 deletions(-)
9
1 file changed, 16 insertions(+), 3 deletions(-)
14
10
15
diff --git a/qemu-options.hx b/qemu-options.hx
11
diff --git a/block/file-posix.c b/block/file-posix.c
16
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
17
--- a/qemu-options.hx
13
--- a/block/file-posix.c
18
+++ b/qemu-options.hx
14
+++ b/block/file-posix.c
19
@@ -XXX,XX +XXX,XX @@ DEF("blockdev", HAS_ARG, QEMU_OPTION_blockdev,
15
@@ -XXX,XX +XXX,XX @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
20
" [,read-only=on|off][,detect-zeroes=on|off|unmap]\n"
16
21
" [,driver specific parameters...]\n"
17
s->fd = -1;
22
" configure a block backend\n", QEMU_ARCH_ALL)
18
fd = qemu_open(filename, s->open_flags, 0644);
23
+STEXI
19
- if (fd < 0) {
24
+@item -blockdev @var{option}[,@var{option}[,@var{option}[,...]]]
20
- ret = -errno;
25
+@findex -blockdev
21
- error_setg_errno(errp, errno, "Could not open '%s'", filename);
22
+ ret = fd < 0 ? -errno : 0;
26
+
23
+
27
+Define a new block driver node.
24
+ if (ret == -EACCES || ret == -EROFS) {
25
+ /* Try to degrade to read-only, but if it doesn't work, still use the
26
+ * normal error message. */
27
+ if (bdrv_apply_auto_read_only(bs, NULL, NULL) == 0) {
28
+ bdrv_flags &= ~BDRV_O_RDWR;
29
+ raw_parse_flags(bdrv_flags, &s->open_flags);
30
+ assert(!(s->open_flags & O_CREAT));
31
+ fd = qemu_open(filename, s->open_flags);
32
+ ret = fd < 0 ? -errno : 0;
33
+ }
34
+ }
28
+
35
+
29
+@table @option
36
+ if (ret < 0) {
30
+@item Valid options for any block driver node:
37
+ error_setg_errno(errp, -ret, "Could not open '%s'", filename);
31
+
38
if (ret == -EROFS) {
32
+@table @code
39
ret = -EACCES;
33
+@item driver
40
}
34
+Specifies the block driver to use for the given node.
35
+@item node-name
36
+This defines the name of the block driver node by which it will be referenced
37
+later. The name must be unique, i.e. it must not match the name of a different
38
+block driver node, or (if you use @option{-drive} as well) the ID of a drive.
39
+
40
+If no node name is specified, it is automatically generated. The generated node
41
+name is not intended to be predictable and changes between QEMU invocations.
42
+For the top level, an explicit node name must be specified.
43
+@item read-only
44
+Open the node read-only. Guest write attempts will fail.
45
+@item cache.direct
46
+The host page cache can be avoided with @option{cache.direct=on}. This will
47
+attempt to do disk IO directly to the guest's memory. QEMU may still perform an
48
+internal copy of the data.
49
+@item cache.no-flush
50
+In case you don't care about data integrity over host failures, you can use
51
+@option{cache.no-flush=on}. This option tells QEMU that it never needs to write
52
+any data to the disk but can instead keep things in cache. If anything goes
53
+wrong, like your host losing power, the disk storage getting disconnected
54
+accidentally, etc. your image will most probably be rendered unusable.
55
+@item discard=@var{discard}
56
+@var{discard} is one of "ignore" (or "off") or "unmap" (or "on") and controls
57
+whether @code{discard} (also known as @code{trim} or @code{unmap}) requests are
58
+ignored or passed to the filesystem. Some machine types may not support
59
+discard requests.
60
+@item detect-zeroes=@var{detect-zeroes}
61
+@var{detect-zeroes} is "off", "on" or "unmap" and enables the automatic
62
+conversion of plain zero writes by the OS to driver specific optimized
63
+zero write commands. You may even choose "unmap" if @var{discard} is set
64
+to "unmap" to allow a zero write to be converted to an @code{unmap} operation.
65
+@end table
66
+
67
+@end table
68
+
69
+ETEXI
70
71
DEF("drive", HAS_ARG, QEMU_OPTION_drive,
72
"-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i]\n"
73
@@ -XXX,XX +XXX,XX @@ STEXI
74
@item -drive @var{option}[,@var{option}[,@var{option}[,...]]]
75
@findex -drive
76
77
-Define a new drive. Valid options are:
78
+Define a new drive. This includes creating a block driver node (the backend) as
79
+well as a guest device, and is mostly a shortcut for defining the corresponding
80
+@option{-blockdev} and @option{-device} options.
81
+
82
+@option{-drive} accepts all options that are accepted by @option{-blockdev}. In
83
+addition, it knows the following options:
84
85
@table @option
86
@item file=@var{file}
87
@@ -XXX,XX +XXX,XX @@ These options have the same definition as they have in @option{-hdachs}.
88
@var{snapshot} is "on" or "off" and controls snapshot mode for the given drive
89
(see @option{-snapshot}).
90
@item cache=@var{cache}
91
-@var{cache} is "none", "writeback", "unsafe", "directsync" or "writethrough" and controls how the host cache is used to access block data.
92
+@var{cache} is "none", "writeback", "unsafe", "directsync" or "writethrough"
93
+and controls how the host cache is used to access block data. This is a
94
+shortcut that sets the @option{cache.direct} and @option{cache.no-flush}
95
+options (as in @option{-blockdev}), and additionally @option{cache.writeback},
96
+which provides a default for the @option{write-cache} option of block guest
97
+devices (as in @option{-device}). The modes correspond to the following
98
+settings:
99
+
100
+@c Our texi2pod.pl script doesn't support @multitable, so fall back to using
101
+@c plain ASCII art (well, UTF-8 art really). This looks okay both in the manpage
102
+@c and the HTML output.
103
+@example
104
+@ │ cache.writeback cache.direct cache.no-flush
105
+─────────────┼─────────────────────────────────────────────────
106
+writeback │ on off off
107
+none │ on on off
108
+writethrough │ off off off
109
+directsync │ off on off
110
+unsafe │ on off on
111
+@end example
112
+
113
+The default mode is @option{cache=writeback}.
114
+
115
@item aio=@var{aio}
116
@var{aio} is "threads", or "native" and selects between pthread based disk I/O and native Linux AIO.
117
-@item discard=@var{discard}
118
-@var{discard} is one of "ignore" (or "off") or "unmap" (or "on") and controls whether @dfn{discard} (also known as @dfn{trim} or @dfn{unmap}) requests are ignored or passed to the filesystem. Some machine types may not support discard requests.
119
@item format=@var{format}
120
Specify which disk @var{format} will be used rather than detecting
121
the format. Can be used to specify format=raw to avoid interpreting
122
@@ -XXX,XX +XXX,XX @@ Specify which @var{action} to take on write and read errors. Valid actions are:
123
"report" (report the error to the guest), "enospc" (pause QEMU only if the
124
host disk is full; report the error to the guest otherwise).
125
The default setting is @option{werror=enospc} and @option{rerror=report}.
126
-@item readonly
127
-Open drive @option{file} as read-only. Guest write attempts will fail.
128
@item copy-on-read=@var{copy-on-read}
129
@var{copy-on-read} is "on" or "off" and enables whether to copy read backing
130
file sectors into the image file.
131
-@item detect-zeroes=@var{detect-zeroes}
132
-@var{detect-zeroes} is "off", "on" or "unmap" and enables the automatic
133
-conversion of plain zero writes by the OS to driver specific optimized
134
-zero write commands. You may even choose "unmap" if @var{discard} is set
135
-to "unmap" to allow a zero write to be converted to an UNMAP operation.
136
@item bps=@var{b},bps_rd=@var{r},bps_wr=@var{w}
137
Specify bandwidth throttling limits in bytes per second, either for all request
138
types or for reads or writes only. Small values can lead to timeouts or hangs
139
@@ -XXX,XX +XXX,XX @@ prevent guests from circumventing throttling limits by using many small disks
140
instead of a single larger disk.
141
@end table
142
143
-By default, the @option{cache=writeback} mode is used. It will report data
144
+By default, the @option{cache.writeback=on} mode is used. It will report data
145
writes as completed as soon as the data is present in the host page cache.
146
This is safe as long as your guest OS makes sure to correctly flush disk caches
147
where needed. If your guest OS does not handle volatile disk write caches
148
correctly and your host crashes or loses power, then the guest may experience
149
data corruption.
150
151
-For such guests, you should consider using @option{cache=writethrough}. This
152
+For such guests, you should consider using @option{cache.writeback=off}. This
153
means that the host page cache will be used to read and write data, but write
154
notification will be sent to the guest only after QEMU has made sure to flush
155
each write to the disk. Be aware that this has a major impact on performance.
156
157
-The host page cache can be avoided entirely with @option{cache=none}. This will
158
-attempt to do disk IO directly to the guest's memory. QEMU may still perform
159
-an internal copy of the data. Note that this is considered a writeback mode and
160
-the guest OS must handle the disk write cache correctly in order to avoid data
161
-corruption on host crashes.
162
-
163
-The host page cache can be avoided while only sending write notifications to
164
-the guest when the data has been flushed to the disk using
165
-@option{cache=directsync}.
166
-
167
-In case you don't care about data integrity over host failures, use
168
-@option{cache=unsafe}. This option tells QEMU that it never needs to write any
169
-data to the disk but can instead keep things in cache. If anything goes wrong,
170
-like your host losing power, the disk storage getting disconnected accidentally,
171
-etc. your image will most probably be rendered unusable. When using
172
-the @option{-snapshot} option, unsafe caching is always used.
173
+When using the @option{-snapshot} option, unsafe caching is always used.
174
175
Copy-on-read avoids accessing the same backing file sectors repeatedly and is
176
useful when the backing file is over a slow network. By default copy-on-read
177
--
41
--
178
1.8.3.1
42
2.19.1
179
43
180
44
diff view generated by jsdifflib
1
Don't recurse into qed_aio_next_io() and qed_aio_complete() here, but
1
If read-only=off, but auto-read-only=on is given, just degrade to
2
just return an error code and let the caller handle it.
2
read-only.
3
4
While refactoring qed_aio_write_alloc() to accomodate the change,
5
qed_aio_write_zero_cluster() ended up with a single line, so I chose to
6
inline that line and remove the function completely.
7
3
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
5
Reviewed-by: Eric Blake <eblake@redhat.com>
10
---
6
---
11
block/qed.c | 58 +++++++++++++++++++++-------------------------------------
7
block/curl.c | 8 ++++----
12
1 file changed, 21 insertions(+), 37 deletions(-)
8
1 file changed, 4 insertions(+), 4 deletions(-)
13
9
14
diff --git a/block/qed.c b/block/qed.c
10
diff --git a/block/curl.c b/block/curl.c
15
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
16
--- a/block/qed.c
12
--- a/block/curl.c
17
+++ b/block/qed.c
13
+++ b/block/curl.c
18
@@ -XXX,XX +XXX,XX @@ static int qed_aio_write_main(QEDAIOCB *acb)
14
@@ -XXX,XX +XXX,XX @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
19
/**
15
const char *protocol_delimiter;
20
* Populate untouched regions of new data cluster
16
int ret;
21
*/
17
22
-static void qed_aio_write_cow(void *opaque, int ret)
18
-
23
+static int qed_aio_write_cow(QEDAIOCB *acb)
19
- if (flags & BDRV_O_RDWR) {
24
{
20
- error_setg(errp, "curl block device does not support writes");
25
- QEDAIOCB *acb = opaque;
21
- return -EROFS;
26
BDRVQEDState *s = acb_to_s(acb);
22
+ ret = bdrv_apply_auto_read_only(bs, "curl driver does not support writes",
27
uint64_t start, len, offset;
23
+ errp);
28
+ int ret;
29
30
/* Populate front untouched region of new data cluster */
31
start = qed_start_of_cluster(s, acb->cur_pos);
32
@@ -XXX,XX +XXX,XX @@ static void qed_aio_write_cow(void *opaque, int ret)
33
34
trace_qed_aio_write_prefill(s, acb, start, len, acb->cur_cluster);
35
ret = qed_copy_from_backing_file(s, start, len, acb->cur_cluster);
36
- if (ret) {
37
- qed_aio_complete(acb, ret);
38
- return;
39
+ if (ret < 0) {
24
+ if (ret < 0) {
40
+ return ret;
25
+ return ret;
41
}
26
}
42
27
43
/* Populate back untouched region of new data cluster */
28
if (!libcurl_initialized) {
44
@@ -XXX,XX +XXX,XX @@ static void qed_aio_write_cow(void *opaque, int ret)
45
46
trace_qed_aio_write_postfill(s, acb, start, len, offset);
47
ret = qed_copy_from_backing_file(s, start, len, offset);
48
- if (ret) {
49
- qed_aio_complete(acb, ret);
50
- return;
51
- }
52
-
53
- ret = qed_aio_write_main(acb);
54
if (ret < 0) {
55
- qed_aio_complete(acb, ret);
56
- return;
57
+ return ret;
58
}
59
- qed_aio_next_io(acb, 0);
60
+
61
+ return qed_aio_write_main(acb);
62
}
63
64
/**
65
@@ -XXX,XX +XXX,XX @@ static bool qed_should_set_need_check(BDRVQEDState *s)
66
return !(s->header.features & QED_F_NEED_CHECK);
67
}
68
69
-static void qed_aio_write_zero_cluster(void *opaque, int ret)
70
-{
71
- QEDAIOCB *acb = opaque;
72
-
73
- if (ret) {
74
- qed_aio_complete(acb, ret);
75
- return;
76
- }
77
-
78
- ret = qed_aio_write_l2_update(acb, 1);
79
- if (ret < 0) {
80
- qed_aio_complete(acb, ret);
81
- return;
82
- }
83
- qed_aio_next_io(acb, 0);
84
-}
85
-
86
/**
87
* Write new data cluster
88
*
89
@@ -XXX,XX +XXX,XX @@ static void qed_aio_write_zero_cluster(void *opaque, int ret)
90
static void qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
91
{
92
BDRVQEDState *s = acb_to_s(acb);
93
- BlockCompletionFunc *cb;
94
int ret;
95
96
/* Cancel timer when the first allocating request comes in */
97
@@ -XXX,XX +XXX,XX @@ static void qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
98
qed_aio_start_io(acb);
99
return;
100
}
101
-
102
- cb = qed_aio_write_zero_cluster;
103
} else {
104
- cb = qed_aio_write_cow;
105
acb->cur_cluster = qed_alloc_clusters(s, acb->cur_nclusters);
106
}
107
108
if (qed_should_set_need_check(s)) {
109
s->header.features |= QED_F_NEED_CHECK;
110
ret = qed_write_header(s);
111
- cb(acb, ret);
112
+ if (ret < 0) {
113
+ qed_aio_complete(acb, ret);
114
+ return;
115
+ }
116
+ }
117
+
118
+ if (acb->flags & QED_AIOCB_ZERO) {
119
+ ret = qed_aio_write_l2_update(acb, 1);
120
} else {
121
- cb(acb, 0);
122
+ ret = qed_aio_write_cow(acb);
123
}
124
+ if (ret < 0) {
125
+ qed_aio_complete(acb, ret);
126
+ return;
127
+ }
128
+ qed_aio_next_io(acb, 0);
129
}
130
131
/**
132
--
29
--
133
1.8.3.1
30
2.19.1
134
31
135
32
diff view generated by jsdifflib
1
Now that we're running in coroutine context, the ad-hoc serialisation
1
If read-only=off, but auto-read-only=on is given, open the file
2
code (which drops a request that has to wait out of coroutine context)
2
read-write if we have the permissions, but instead of erroring out for
3
can be replaced by a CoQueue.
3
read-only files, just degrade to read-only.
4
5
This means that when we resume a serialised request, it is running in
6
coroutine context again and its I/O isn't blocking any more.
7
4
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
6
Reviewed-by: Niels de Vos <ndevos@redhat.com>
10
---
7
---
11
block/qed.c | 49 +++++++++++++++++--------------------------------
8
block/gluster.c | 12 ++++++++++--
12
block/qed.h | 3 ++-
9
1 file changed, 10 insertions(+), 2 deletions(-)
13
2 files changed, 19 insertions(+), 33 deletions(-)
14
10
15
diff --git a/block/qed.c b/block/qed.c
11
diff --git a/block/gluster.c b/block/gluster.c
16
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
17
--- a/block/qed.c
13
--- a/block/gluster.c
18
+++ b/block/qed.c
14
+++ b/block/gluster.c
19
@@ -XXX,XX +XXX,XX @@ static void qed_plug_allocating_write_reqs(BDRVQEDState *s)
15
@@ -XXX,XX +XXX,XX @@ static int qemu_gluster_open(BlockDriverState *bs, QDict *options,
20
16
qemu_gluster_parse_flags(bdrv_flags, &open_flags);
21
static void qed_unplug_allocating_write_reqs(BDRVQEDState *s)
17
22
{
18
s->fd = glfs_open(s->glfs, gconf->path, open_flags);
23
- QEDAIOCB *acb;
19
- if (!s->fd) {
24
-
20
- ret = -errno;
25
assert(s->allocating_write_reqs_plugged);
21
+ ret = s->fd ? 0 : -errno;
26
22
+
27
s->allocating_write_reqs_plugged = false;
23
+ if (ret == -EACCES || ret == -EROFS) {
28
-
24
+ /* Try to degrade to read-only, but if it doesn't work, still use the
29
- acb = QSIMPLEQ_FIRST(&s->allocating_write_reqs);
25
+ * normal error message. */
30
- if (acb) {
26
+ if (bdrv_apply_auto_read_only(bs, NULL, NULL) == 0) {
31
- qed_aio_start_io(acb);
27
+ open_flags = (open_flags & ~O_RDWR) | O_RDONLY;
32
- }
28
+ s->fd = glfs_open(s->glfs, gconf->path, open_flags);
33
+ qemu_co_enter_next(&s->allocating_write_reqs);
29
+ ret = s->fd ? 0 : -errno;
34
}
30
+ }
35
36
static void qed_clear_need_check(void *opaque, int ret)
37
@@ -XXX,XX +XXX,XX @@ static void qed_need_check_timer_cb(void *opaque)
38
BDRVQEDState *s = opaque;
39
40
/* The timer should only fire when allocating writes have drained */
41
- assert(!QSIMPLEQ_FIRST(&s->allocating_write_reqs));
42
+ assert(!s->allocating_acb);
43
44
trace_qed_need_check_timer_cb(s);
45
46
@@ -XXX,XX +XXX,XX @@ static int bdrv_qed_do_open(BlockDriverState *bs, QDict *options, int flags,
47
int ret;
48
49
s->bs = bs;
50
- QSIMPLEQ_INIT(&s->allocating_write_reqs);
51
+ qemu_co_queue_init(&s->allocating_write_reqs);
52
53
ret = bdrv_pread(bs->file, 0, &le_header, sizeof(le_header));
54
if (ret < 0) {
55
@@ -XXX,XX +XXX,XX @@ static void qed_aio_complete_bh(void *opaque)
56
qed_release(s);
57
}
58
59
-static void qed_resume_alloc_bh(void *opaque)
60
-{
61
- qed_aio_start_io(opaque);
62
-}
63
-
64
static void qed_aio_complete(QEDAIOCB *acb, int ret)
65
{
66
BDRVQEDState *s = acb_to_s(acb);
67
@@ -XXX,XX +XXX,XX @@ static void qed_aio_complete(QEDAIOCB *acb, int ret)
68
* next request in the queue. This ensures that we don't cycle through
69
* requests multiple times but rather finish one at a time completely.
70
*/
71
- if (acb == QSIMPLEQ_FIRST(&s->allocating_write_reqs)) {
72
- QEDAIOCB *next_acb;
73
- QSIMPLEQ_REMOVE_HEAD(&s->allocating_write_reqs, next);
74
- next_acb = QSIMPLEQ_FIRST(&s->allocating_write_reqs);
75
- if (next_acb) {
76
- aio_bh_schedule_oneshot(bdrv_get_aio_context(acb->common.bs),
77
- qed_resume_alloc_bh, next_acb);
78
+ if (acb == s->allocating_acb) {
79
+ s->allocating_acb = NULL;
80
+ if (!qemu_co_queue_empty(&s->allocating_write_reqs)) {
81
+ qemu_co_enter_next(&s->allocating_write_reqs);
82
} else if (s->header.features & QED_F_NEED_CHECK) {
83
qed_start_need_check_timer(s);
84
}
85
@@ -XXX,XX +XXX,XX @@ static int qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
86
int ret;
87
88
/* Cancel timer when the first allocating request comes in */
89
- if (QSIMPLEQ_EMPTY(&s->allocating_write_reqs)) {
90
+ if (s->allocating_acb == NULL) {
91
qed_cancel_need_check_timer(s);
92
}
31
}
93
32
94
/* Freeze this request if another allocating write is in progress */
33
s->supports_seek_data = qemu_gluster_test_seek(s->fd);
95
- if (acb != QSIMPLEQ_FIRST(&s->allocating_write_reqs)) {
96
- QSIMPLEQ_INSERT_TAIL(&s->allocating_write_reqs, acb, next);
97
- }
98
- if (acb != QSIMPLEQ_FIRST(&s->allocating_write_reqs) ||
99
- s->allocating_write_reqs_plugged) {
100
- return -EINPROGRESS; /* wait for existing request to finish */
101
+ if (s->allocating_acb != acb || s->allocating_write_reqs_plugged) {
102
+ if (s->allocating_acb != NULL) {
103
+ qemu_co_queue_wait(&s->allocating_write_reqs, NULL);
104
+ assert(s->allocating_acb == NULL);
105
+ }
106
+ s->allocating_acb = acb;
107
+ return -EAGAIN; /* start over with looking up table entries */
108
}
109
110
acb->cur_nclusters = qed_bytes_to_clusters(s,
111
@@ -XXX,XX +XXX,XX @@ static void qed_aio_next_io(QEDAIOCB *acb)
112
ret = qed_aio_read_data(acb, ret, offset, len);
113
}
114
115
- if (ret < 0) {
116
- if (ret != -EINPROGRESS) {
117
- qed_aio_complete(acb, ret);
118
- }
119
+ if (ret < 0 && ret != -EAGAIN) {
120
+ qed_aio_complete(acb, ret);
121
return;
122
}
123
}
124
diff --git a/block/qed.h b/block/qed.h
125
index XXXXXXX..XXXXXXX 100644
126
--- a/block/qed.h
127
+++ b/block/qed.h
128
@@ -XXX,XX +XXX,XX @@ typedef struct {
129
uint32_t l2_mask;
130
131
/* Allocating write request queue */
132
- QSIMPLEQ_HEAD(, QEDAIOCB) allocating_write_reqs;
133
+ QEDAIOCB *allocating_acb;
134
+ CoQueue allocating_write_reqs;
135
bool allocating_write_reqs_plugged;
136
137
/* Periodic flush and clear need check flag */
138
--
34
--
139
1.8.3.1
35
2.19.1
140
36
141
37
diff view generated by jsdifflib
1
With this change, qed_aio_write_prefill() and qed_aio_write_postfill()
1
If read-only=off, but auto-read-only=on is given, open the volume
2
collapse into a single function. This is reflected by a rename of the
2
read-write if we have the permissions, but instead of erroring out for
3
combined function to qed_aio_write_cow().
3
read-only volumes, just degrade to read-only.
4
4
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
---
7
---
9
block/qed.c | 57 +++++++++++++++++++++++----------------------------------
8
block/iscsi.c | 8 +++++---
10
1 file changed, 23 insertions(+), 34 deletions(-)
9
1 file changed, 5 insertions(+), 3 deletions(-)
11
10
12
diff --git a/block/qed.c b/block/qed.c
11
diff --git a/block/iscsi.c b/block/iscsi.c
13
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
14
--- a/block/qed.c
13
--- a/block/iscsi.c
15
+++ b/block/qed.c
14
+++ b/block/iscsi.c
16
@@ -XXX,XX +XXX,XX @@ static int qed_read_backing_file(BDRVQEDState *s, uint64_t pos,
15
@@ -XXX,XX +XXX,XX @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
17
* @pos: Byte position in device
16
/* Check the write protect flag of the LUN if we want to write */
18
* @len: Number of bytes
17
if (iscsilun->type == TYPE_DISK && (flags & BDRV_O_RDWR) &&
19
* @offset: Byte offset in image file
18
iscsilun->write_protected) {
20
- * @cb: Completion function
19
- error_setg(errp, "Cannot open a write protected LUN as read-write");
21
- * @opaque: User data for completion function
20
- ret = -EACCES;
22
*/
21
- goto out;
23
-static void qed_copy_from_backing_file(BDRVQEDState *s, uint64_t pos,
22
+ ret = bdrv_apply_auto_read_only(bs, "LUN is write protected", errp);
24
- uint64_t len, uint64_t offset,
23
+ if (ret < 0) {
25
- BlockCompletionFunc *cb,
24
+ goto out;
26
- void *opaque)
25
+ }
27
+static int qed_copy_from_backing_file(BDRVQEDState *s, uint64_t pos,
26
+ flags &= ~BDRV_O_RDWR;
28
+ uint64_t len, uint64_t offset)
29
{
30
QEMUIOVector qiov;
31
QEMUIOVector *backing_qiov = NULL;
32
@@ -XXX,XX +XXX,XX @@ static void qed_copy_from_backing_file(BDRVQEDState *s, uint64_t pos,
33
34
/* Skip copy entirely if there is no work to do */
35
if (len == 0) {
36
- cb(opaque, 0);
37
- return;
38
+ return 0;
39
}
27
}
40
28
41
iov = (struct iovec) {
29
iscsi_readcapacity_sync(iscsilun, &local_err);
42
@@ -XXX,XX +XXX,XX @@ static void qed_copy_from_backing_file(BDRVQEDState *s, uint64_t pos,
43
ret = 0;
44
out:
45
qemu_vfree(iov.iov_base);
46
- cb(opaque, ret);
47
+ return ret;
48
}
49
50
/**
51
@@ -XXX,XX +XXX,XX @@ static void qed_aio_write_main(void *opaque, int ret)
52
}
53
54
/**
55
- * Populate back untouched region of new data cluster
56
+ * Populate untouched regions of new data cluster
57
*/
58
-static void qed_aio_write_postfill(void *opaque, int ret)
59
+static void qed_aio_write_cow(void *opaque, int ret)
60
{
61
QEDAIOCB *acb = opaque;
62
BDRVQEDState *s = acb_to_s(acb);
63
- uint64_t start = acb->cur_pos + acb->cur_qiov.size;
64
- uint64_t len =
65
- qed_start_of_cluster(s, start + s->header.cluster_size - 1) - start;
66
- uint64_t offset = acb->cur_cluster +
67
- qed_offset_into_cluster(s, acb->cur_pos) +
68
- acb->cur_qiov.size;
69
+ uint64_t start, len, offset;
70
+
71
+ /* Populate front untouched region of new data cluster */
72
+ start = qed_start_of_cluster(s, acb->cur_pos);
73
+ len = qed_offset_into_cluster(s, acb->cur_pos);
74
75
+ trace_qed_aio_write_prefill(s, acb, start, len, acb->cur_cluster);
76
+ ret = qed_copy_from_backing_file(s, start, len, acb->cur_cluster);
77
if (ret) {
78
qed_aio_complete(acb, ret);
79
return;
80
}
81
82
- trace_qed_aio_write_postfill(s, acb, start, len, offset);
83
- qed_copy_from_backing_file(s, start, len, offset,
84
- qed_aio_write_main, acb);
85
-}
86
+ /* Populate back untouched region of new data cluster */
87
+ start = acb->cur_pos + acb->cur_qiov.size;
88
+ len = qed_start_of_cluster(s, start + s->header.cluster_size - 1) - start;
89
+ offset = acb->cur_cluster +
90
+ qed_offset_into_cluster(s, acb->cur_pos) +
91
+ acb->cur_qiov.size;
92
93
-/**
94
- * Populate front untouched region of new data cluster
95
- */
96
-static void qed_aio_write_prefill(void *opaque, int ret)
97
-{
98
- QEDAIOCB *acb = opaque;
99
- BDRVQEDState *s = acb_to_s(acb);
100
- uint64_t start = qed_start_of_cluster(s, acb->cur_pos);
101
- uint64_t len = qed_offset_into_cluster(s, acb->cur_pos);
102
+ trace_qed_aio_write_postfill(s, acb, start, len, offset);
103
+ ret = qed_copy_from_backing_file(s, start, len, offset);
104
105
- trace_qed_aio_write_prefill(s, acb, start, len, acb->cur_cluster);
106
- qed_copy_from_backing_file(s, start, len, acb->cur_cluster,
107
- qed_aio_write_postfill, acb);
108
+ qed_aio_write_main(acb, ret);
109
}
110
111
/**
112
@@ -XXX,XX +XXX,XX @@ static void qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
113
114
cb = qed_aio_write_zero_cluster;
115
} else {
116
- cb = qed_aio_write_prefill;
117
+ cb = qed_aio_write_cow;
118
acb->cur_cluster = qed_alloc_clusters(s, acb->cur_nclusters);
119
}
120
121
--
30
--
122
1.8.3.1
31
2.19.1
123
32
124
33
diff view generated by jsdifflib
1
After _cleanup_qemu(), test cases should be able to start the next qemu
1
While we want machine interfaces like -blockdev and QMP blockdev-add to
2
process and call _cleanup_qemu() for that one as well. For this to work
2
add as little auto-detection as possible so that management tools are
3
cleanly, we need to improve the cleanup so that the second invocation
3
explicit about their needs, -drive is a convenience option for human
4
doesn't try to kill the qemu instances from the first invocation a
4
users. Enabling auto-read-only=on by default there enables users to use
5
second time (which would result in error messages).
5
read-only images for read-only guest devices without having to specify
6
read-only=on explicitly. If they try to attach the image to a read-write
7
device, they will still get an error message.
6
8
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Reviewed-by: Eric Blake <eblake@redhat.com>
10
Reviewed-by: Eric Blake <eblake@redhat.com>
9
Reviewed-by: Max Reitz <mreitz@redhat.com>
10
---
11
---
11
tests/qemu-iotests/common.qemu | 3 +++
12
blockdev.c | 1 +
12
1 file changed, 3 insertions(+)
13
1 file changed, 1 insertion(+)
13
14
14
diff --git a/tests/qemu-iotests/common.qemu b/tests/qemu-iotests/common.qemu
15
diff --git a/blockdev.c b/blockdev.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/tests/qemu-iotests/common.qemu
17
--- a/blockdev.c
17
+++ b/tests/qemu-iotests/common.qemu
18
+++ b/blockdev.c
18
@@ -XXX,XX +XXX,XX @@ function _cleanup_qemu()
19
@@ -XXX,XX +XXX,XX @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
19
rm -f "${QEMU_FIFO_IN}_${i}" "${QEMU_FIFO_OUT}_${i}"
20
qdict_set_default_str(bs_opts, BDRV_OPT_CACHE_NO_FLUSH, "off");
20
eval "exec ${QEMU_IN[$i]}<&-" # close file descriptors
21
qdict_set_default_str(bs_opts, BDRV_OPT_READ_ONLY,
21
eval "exec ${QEMU_OUT[$i]}<&-"
22
read_only ? "on" : "off");
22
+
23
+ qdict_set_default_str(bs_opts, BDRV_OPT_AUTO_READ_ONLY, "on");
23
+ unset QEMU_IN[$i]
24
assert((bdrv_flags & BDRV_O_CACHE_MASK) == 0);
24
+ unset QEMU_OUT[$i]
25
25
done
26
if (runstate_check(RUN_STATE_INMIGRATE)) {
26
}
27
--
27
--
28
1.8.3.1
28
2.19.1
29
29
30
30
diff view generated by jsdifflib
1
When qemu is exited, all running jobs should be cancelled successfully.
2
This adds a test for this for all types of block jobs that currently
3
exist in qemu.
4
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
2
Reviewed-by: Eric Blake <eblake@redhat.com>
7
---
3
---
8
tests/qemu-iotests/185 | 206 +++++++++++++++++++++++++++++++++++++++++++++
4
tests/qemu-iotests/232 | 147 +++++++++++++++++++++++++++++++++++++
9
tests/qemu-iotests/185.out | 59 +++++++++++++
5
tests/qemu-iotests/232.out | 59 +++++++++++++++
10
tests/qemu-iotests/group | 1 +
6
tests/qemu-iotests/group | 1 +
11
3 files changed, 266 insertions(+)
7
3 files changed, 207 insertions(+)
12
create mode 100755 tests/qemu-iotests/185
8
create mode 100755 tests/qemu-iotests/232
13
create mode 100644 tests/qemu-iotests/185.out
9
create mode 100644 tests/qemu-iotests/232.out
14
10
15
diff --git a/tests/qemu-iotests/185 b/tests/qemu-iotests/185
11
diff --git a/tests/qemu-iotests/232 b/tests/qemu-iotests/232
16
new file mode 100755
12
new file mode 100755
17
index XXXXXXX..XXXXXXX
13
index XXXXXXX..XXXXXXX
18
--- /dev/null
14
--- /dev/null
19
+++ b/tests/qemu-iotests/185
15
+++ b/tests/qemu-iotests/232
20
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@
21
+#!/bin/bash
17
+#!/bin/bash
22
+#
18
+#
23
+# Test exiting qemu while jobs are still running
19
+# Test for auto-read-only
24
+#
20
+#
25
+# Copyright (C) 2017 Red Hat, Inc.
21
+# Copyright (C) 2018 Red Hat, Inc.
26
+#
22
+#
27
+# This program is free software; you can redistribute it and/or modify
23
+# This program is free software; you can redistribute it and/or modify
28
+# it under the terms of the GNU General Public License as published by
24
+# it under the terms of the GNU General Public License as published by
29
+# the Free Software Foundation; either version 2 of the License, or
25
+# the Free Software Foundation; either version 2 of the License, or
30
+# (at your option) any later version.
26
+# (at your option) any later version.
...
...
43
+
39
+
44
+seq=`basename $0`
40
+seq=`basename $0`
45
+echo "QA output created by $seq"
41
+echo "QA output created by $seq"
46
+
42
+
47
+here=`pwd`
43
+here=`pwd`
48
+status=1 # failure is the default!
44
+status=1    # failure is the default!
49
+
50
+MIG_SOCKET="${TEST_DIR}/migrate"
51
+
45
+
52
+_cleanup()
46
+_cleanup()
53
+{
47
+{
54
+ rm -f "${TEST_IMG}.mid"
55
+ rm -f "${TEST_IMG}.copy"
56
+ _cleanup_test_img
48
+ _cleanup_test_img
57
+ _cleanup_qemu
49
+ rm -f $TEST_IMG.snap
58
+}
50
+}
59
+trap "_cleanup; exit \$status" 0 1 2 3 15
51
+trap "_cleanup; exit \$status" 0 1 2 3 15
60
+
52
+
61
+# get standard environment, filters and checks
53
+# get standard environment, filters and checks
62
+. ./common.rc
54
+. ./common.rc
63
+. ./common.filter
55
+. ./common.filter
64
+. ./common.qemu
56
+
65
+
57
+_supported_fmt generic
66
+_supported_fmt qcow2
67
+_supported_proto file
58
+_supported_proto file
68
+_supported_os Linux
59
+_supported_os Linux
69
+
60
+
70
+size=64M
61
+function do_run_qemu()
71
+TEST_IMG="${TEST_IMG}.base" _make_test_img $size
62
+{
72
+
63
+ echo Testing: "$@"
73
+echo
64
+ (
74
+echo === Starting VM ===
65
+ if ! test -t 0; then
75
+echo
66
+ while read cmd; do
76
+
67
+ echo $cmd
77
+qemu_comm_method="qmp"
68
+ done
78
+
69
+ fi
79
+_launch_qemu \
70
+ echo quit
80
+ -drive file="${TEST_IMG}.base",cache=$CACHEMODE,driver=$IMGFMT,id=disk
71
+ ) | $QEMU -nographic -monitor stdio -nodefaults "$@"
81
+h=$QEMU_HANDLE
72
+ echo
82
+_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" 'return'
73
+}
83
+
74
+
84
+echo
75
+function run_qemu()
85
+echo === Creating backing chain ===
76
+{
86
+echo
77
+ do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_hmp |
87
+
78
+ _filter_generated_node_ids | _filter_imgfmt
88
+_send_qemu_cmd $h \
79
+}
89
+ "{ 'execute': 'blockdev-snapshot-sync',
80
+
90
+ 'arguments': { 'device': 'disk',
81
+function run_qemu_info_block()
91
+ 'snapshot-file': '$TEST_IMG.mid',
82
+{
92
+ 'format': '$IMGFMT',
83
+ echo "info block -n" | run_qemu "$@" | grep -e "(file" -e "QEMU_PROG"
93
+ 'mode': 'absolute-paths' } }" \
84
+}
94
+ "return"
85
+
95
+
86
+size=128M
96
+_send_qemu_cmd $h \
87
+
97
+ "{ 'execute': 'human-monitor-command',
88
+_make_test_img $size
98
+ 'arguments': { 'command-line':
89
+
99
+ 'qemu-io disk \"write 0 4M\"' } }" \
90
+echo
100
+ "return"
91
+echo "=== -drive with read-write image: read-only/auto-read-only combinations ==="
101
+
92
+echo
102
+_send_qemu_cmd $h \
93
+
103
+ "{ 'execute': 'blockdev-snapshot-sync',
94
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on,auto-read-only=off
104
+ 'arguments': { 'device': 'disk',
95
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on,auto-read-only=on
105
+ 'snapshot-file': '$TEST_IMG',
96
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on
106
+ 'format': '$IMGFMT',
97
+echo
107
+ 'mode': 'absolute-paths' } }" \
98
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off,auto-read-only=off
108
+ "return"
99
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off,auto-read-only=on
109
+
100
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off
110
+echo
101
+echo
111
+echo === Start commit job and exit qemu ===
102
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,auto-read-only=off
112
+echo
103
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,auto-read-only=on
113
+
104
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none
114
+# Note that the reference output intentionally includes the 'offset' field in
105
+
115
+# BLOCK_JOB_CANCELLED events for all of the following block jobs. They are
106
+echo
116
+# predictable and any change in the offsets would hint at a bug in the job
107
+echo "=== -drive with read-only image: read-only/auto-read-only combinations ==="
117
+# throttling code.
108
+echo
118
+#
109
+
119
+# In order to achieve these predictable offsets, all of the following tests
110
+chmod a-w $TEST_IMG
120
+# use speed=65536. Each job will perform exactly one iteration before it has
111
+
121
+# to sleep at least for a second, which is plenty of time for the 'quit' QMP
112
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on,auto-read-only=off
122
+# command to be received (after receiving the command, the rest runs
113
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on,auto-read-only=on
123
+# synchronously, so jobs can arbitrarily continue or complete).
114
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on
124
+#
115
+echo
125
+# The buffer size for commit and streaming is 512k (waiting for 8 seconds after
116
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off,auto-read-only=off
126
+# the first request), for active commit and mirror it's large enough to cover
117
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off,auto-read-only=on
127
+# the full 4M, and for backup it's the qcow2 cluster size, which we know is
118
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off
128
+# 64k. As all of these are at least as large as the speed, we are sure that the
119
+echo
129
+# offset doesn't advance after the first iteration before qemu exits.
120
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,auto-read-only=off
130
+
121
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,auto-read-only=on
131
+_send_qemu_cmd $h \
122
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none
132
+ "{ 'execute': 'block-commit',
123
+
133
+ 'arguments': { 'device': 'disk',
124
+echo
134
+ 'base':'$TEST_IMG.base',
125
+echo "=== -blockdev with read-write image: read-only/auto-read-only combinations ==="
135
+ 'top': '$TEST_IMG.mid',
126
+echo
136
+ 'speed': 65536 } }" \
127
+
137
+ "return"
128
+chmod a+w $TEST_IMG
138
+
129
+
139
+_send_qemu_cmd $h "{ 'execute': 'quit' }" "return"
130
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on,auto-read-only=off
140
+wait=1 _cleanup_qemu
131
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on,auto-read-only=on
141
+
132
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on
142
+echo
133
+echo
143
+echo === Start active commit job and exit qemu ===
134
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off,auto-read-only=off
144
+echo
135
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off,auto-read-only=on
145
+
136
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off
146
+_launch_qemu \
137
+echo
147
+ -drive file="${TEST_IMG}",cache=$CACHEMODE,driver=$IMGFMT,id=disk
138
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,auto-read-only=off
148
+h=$QEMU_HANDLE
139
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,auto-read-only=on
149
+_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" 'return'
140
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0
150
+
141
+
151
+_send_qemu_cmd $h \
142
+echo
152
+ "{ 'execute': 'block-commit',
143
+echo "=== -blockdev with read-only image: read-only/auto-read-only combinations ==="
153
+ 'arguments': { 'device': 'disk',
144
+echo
154
+ 'base':'$TEST_IMG.base',
145
+
155
+ 'speed': 65536 } }" \
146
+chmod a-w $TEST_IMG
156
+ "return"
147
+
157
+
148
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on,auto-read-only=off
158
+_send_qemu_cmd $h "{ 'execute': 'quit' }" "return"
149
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on,auto-read-only=on
159
+wait=1 _cleanup_qemu
150
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on
160
+
151
+echo
161
+echo
152
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off,auto-read-only=off
162
+echo === Start mirror job and exit qemu ===
153
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off,auto-read-only=on
163
+echo
154
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off
164
+
155
+echo
165
+_launch_qemu \
156
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,auto-read-only=off
166
+ -drive file="${TEST_IMG}",cache=$CACHEMODE,driver=$IMGFMT,id=disk
157
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,auto-read-only=on
167
+h=$QEMU_HANDLE
158
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0
168
+_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" 'return'
169
+
170
+_send_qemu_cmd $h \
171
+ "{ 'execute': 'drive-mirror',
172
+ 'arguments': { 'device': 'disk',
173
+ 'target': '$TEST_IMG.copy',
174
+ 'format': '$IMGFMT',
175
+ 'sync': 'full',
176
+ 'speed': 65536 } }" \
177
+ "return"
178
+
179
+_send_qemu_cmd $h "{ 'execute': 'quit' }" "return"
180
+wait=1 _cleanup_qemu
181
+
182
+echo
183
+echo === Start backup job and exit qemu ===
184
+echo
185
+
186
+_launch_qemu \
187
+ -drive file="${TEST_IMG}",cache=$CACHEMODE,driver=$IMGFMT,id=disk
188
+h=$QEMU_HANDLE
189
+_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" 'return'
190
+
191
+_send_qemu_cmd $h \
192
+ "{ 'execute': 'drive-backup',
193
+ 'arguments': { 'device': 'disk',
194
+ 'target': '$TEST_IMG.copy',
195
+ 'format': '$IMGFMT',
196
+ 'sync': 'full',
197
+ 'speed': 65536 } }" \
198
+ "return"
199
+
200
+_send_qemu_cmd $h "{ 'execute': 'quit' }" "return"
201
+wait=1 _cleanup_qemu
202
+
203
+echo
204
+echo === Start streaming job and exit qemu ===
205
+echo
206
+
207
+_launch_qemu \
208
+ -drive file="${TEST_IMG}",cache=$CACHEMODE,driver=$IMGFMT,id=disk
209
+h=$QEMU_HANDLE
210
+_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" 'return'
211
+
212
+_send_qemu_cmd $h \
213
+ "{ 'execute': 'block-stream',
214
+ 'arguments': { 'device': 'disk',
215
+ 'speed': 65536 } }" \
216
+ "return"
217
+
218
+_send_qemu_cmd $h "{ 'execute': 'quit' }" "return"
219
+wait=1 _cleanup_qemu
220
+
221
+_check_test_img
222
+
159
+
223
+# success, all done
160
+# success, all done
224
+echo "*** done"
161
+echo "*** done"
225
+rm -f $seq.full
162
+rm -f $seq.full
226
+status=0
163
+status=0
227
diff --git a/tests/qemu-iotests/185.out b/tests/qemu-iotests/185.out
164
diff --git a/tests/qemu-iotests/232.out b/tests/qemu-iotests/232.out
228
new file mode 100644
165
new file mode 100644
229
index XXXXXXX..XXXXXXX
166
index XXXXXXX..XXXXXXX
230
--- /dev/null
167
--- /dev/null
231
+++ b/tests/qemu-iotests/185.out
168
+++ b/tests/qemu-iotests/232.out
232
@@ -XXX,XX +XXX,XX @@
169
@@ -XXX,XX +XXX,XX @@
233
+QA output created by 185
170
+QA output created by 232
234
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
171
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
235
+
172
+
236
+=== Starting VM ===
173
+=== -drive with read-write image: read-only/auto-read-only combinations ===
237
+
174
+
238
+{"return": {}}
175
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
239
+
176
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
240
+=== Creating backing chain ===
177
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
241
+
178
+
242
+Formatting 'TEST_DIR/t.qcow2.mid', fmt=qcow2 size=67108864 backing_file=TEST_DIR/t.qcow2.base backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16
179
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
243
+{"return": {}}
180
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
244
+wrote 4194304/4194304 bytes at offset 0
181
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
245
+4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
182
+
246
+{"return": ""}
183
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
247
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 backing_file=TEST_DIR/t.qcow2.mid backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16
184
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
248
+{"return": {}}
185
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
249
+
186
+
250
+=== Start commit job and exit qemu ===
187
+=== -drive with read-only image: read-only/auto-read-only combinations ===
251
+
188
+
252
+{"return": {}}
189
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
253
+{"return": {}}
190
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
254
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
191
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
255
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "disk", "len": 67108864, "offset": 524288, "speed": 65536, "type": "commit"}}
192
+
256
+
193
+QEMU_PROG: -drive driver=file,file=TEST_DIR/t.IMGFMT,if=none,read-only=off,auto-read-only=off: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
257
+=== Start active commit job and exit qemu ===
194
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
258
+
195
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
259
+{"return": {}}
196
+
260
+{"return": {}}
197
+QEMU_PROG: -drive driver=file,file=TEST_DIR/t.IMGFMT,if=none,auto-read-only=off: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
261
+{"return": {}}
198
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
262
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
199
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
263
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "disk", "len": 4194304, "offset": 4194304, "speed": 65536, "type": "commit"}}
200
+
264
+
201
+=== -blockdev with read-write image: read-only/auto-read-only combinations ===
265
+=== Start mirror job and exit qemu ===
202
+
266
+
203
+node0: TEST_DIR/t.IMGFMT (file, read-only)
267
+{"return": {}}
204
+node0: TEST_DIR/t.IMGFMT (file, read-only)
268
+Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16
205
+node0: TEST_DIR/t.IMGFMT (file, read-only)
269
+{"return": {}}
206
+
270
+{"return": {}}
207
+node0: TEST_DIR/t.IMGFMT (file)
271
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
208
+node0: TEST_DIR/t.IMGFMT (file)
272
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "disk", "len": 4194304, "offset": 4194304, "speed": 65536, "type": "mirror"}}
209
+node0: TEST_DIR/t.IMGFMT (file)
273
+
210
+
274
+=== Start backup job and exit qemu ===
211
+node0: TEST_DIR/t.IMGFMT (file)
275
+
212
+node0: TEST_DIR/t.IMGFMT (file)
276
+{"return": {}}
213
+node0: TEST_DIR/t.IMGFMT (file)
277
+Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16
214
+
278
+{"return": {}}
215
+=== -blockdev with read-only image: read-only/auto-read-only combinations ===
279
+{"return": {}}
216
+
280
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
217
+node0: TEST_DIR/t.IMGFMT (file, read-only)
281
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "disk", "len": 67108864, "offset": 65536, "speed": 65536, "type": "backup"}}
218
+node0: TEST_DIR/t.IMGFMT (file, read-only)
282
+
219
+node0: TEST_DIR/t.IMGFMT (file, read-only)
283
+=== Start streaming job and exit qemu ===
220
+
284
+
221
+QEMU_PROG: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0,read-only=off,auto-read-only=off: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
285
+{"return": {}}
222
+node0: TEST_DIR/t.IMGFMT (file, read-only)
286
+{"return": {}}
223
+QEMU_PROG: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0,read-only=off: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
287
+{"return": {}}
224
+
288
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
225
+QEMU_PROG: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0,auto-read-only=off: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
289
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "disk", "len": 67108864, "offset": 524288, "speed": 65536, "type": "stream"}}
226
+node0: TEST_DIR/t.IMGFMT (file, read-only)
290
+No errors were found on the image.
227
+QEMU_PROG: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
291
+*** done
228
+*** done
292
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
229
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
293
index XXXXXXX..XXXXXXX 100644
230
index XXXXXXX..XXXXXXX 100644
294
--- a/tests/qemu-iotests/group
231
--- a/tests/qemu-iotests/group
295
+++ b/tests/qemu-iotests/group
232
+++ b/tests/qemu-iotests/group
296
@@ -XXX,XX +XXX,XX @@
233
@@ -XXX,XX +XXX,XX @@
297
181 rw auto migration
234
227 auto quick
298
182 rw auto quick
235
229 auto quick
299
183 rw auto migration
236
231 auto quick
300
+185 rw auto
237
+232 auto quick
301
--
238
--
302
1.8.3.1
239
2.19.1
303
240
304
241
diff view generated by jsdifflib
1
From: "sochin.jiang" <sochin.jiang@huawei.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
img_commit could fall into an infinite loop calling run_block_job() if
3
This adds some whitespace into the option help (including indentation)
4
its blockjob fails on any I/O error, fix this already known problem.
4
and puts angle brackets around the type names. Furthermore, the list
5
name is no longer printed as part of every line, but only once in
6
advance, and only if the caller did not print a caption already.
5
7
6
Signed-off-by: sochin.jiang <sochin.jiang@huawei.com>
8
This patch also restores the description alignment we had before commit
7
Message-id: 1497509253-28941-1-git-send-email-sochin.jiang@huawei.com
9
9cbef9d68ee1d8d0, just at 24 instead of 16 characters like we used to.
10
This increase is because now we have the type and two spaces of
11
indentation before the description, and with a usual type name length of
12
three chracters, this sums up to eight additional characters -- which
13
means that we now need 24 characters to get the same amount of padding
14
for most options. Also, 24 is a third of 80, which makes it kind of a
15
round number in terminal terms.
16
17
Finally, this patch amends the reference output of iotest 082 to match
18
the changes (and thus makes it pass again).
19
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
20
Signed-off-by: Max Reitz <mreitz@redhat.com>
21
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
22
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
23
---
10
blockjob.c | 4 ++--
24
include/qemu/option.h | 2 +-
11
include/block/blockjob.h | 18 ++++++++++++++++++
25
qemu-img.c | 4 +-
12
qemu-img.c | 20 +++++++++++++-------
26
util/qemu-option.c | 32 +-
13
3 files changed, 33 insertions(+), 9 deletions(-)
27
tests/qemu-iotests/082.out | 956 ++++++++++++++++++-------------------
28
4 files changed, 507 insertions(+), 487 deletions(-)
14
29
15
diff --git a/blockjob.c b/blockjob.c
30
diff --git a/include/qemu/option.h b/include/qemu/option.h
16
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
17
--- a/blockjob.c
32
--- a/include/qemu/option.h
18
+++ b/blockjob.c
33
+++ b/include/qemu/option.h
19
@@ -XXX,XX +XXX,XX @@ static void block_job_resume(BlockJob *job)
34
@@ -XXX,XX +XXX,XX @@ typedef int (*qemu_opts_loopfunc)(void *opaque, QemuOpts *opts, Error **errp);
20
block_job_enter(job);
35
int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func,
21
}
36
void *opaque, Error **errp);
22
37
void qemu_opts_print(QemuOpts *opts, const char *sep);
23
-static void block_job_ref(BlockJob *job)
38
-void qemu_opts_print_help(QemuOptsList *list);
24
+void block_job_ref(BlockJob *job)
39
+void qemu_opts_print_help(QemuOptsList *list, bool print_caption);
25
{
40
void qemu_opts_free(QemuOptsList *list);
26
++job->refcnt;
41
QemuOptsList *qemu_opts_append(QemuOptsList *dst, QemuOptsList *list);
27
}
42
28
@@ -XXX,XX +XXX,XX @@ static void block_job_attached_aio_context(AioContext *new_context,
29
void *opaque);
30
static void block_job_detach_aio_context(void *opaque);
31
32
-static void block_job_unref(BlockJob *job)
33
+void block_job_unref(BlockJob *job)
34
{
35
if (--job->refcnt == 0) {
36
BlockDriverState *bs = blk_bs(job->blk);
37
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
38
index XXXXXXX..XXXXXXX 100644
39
--- a/include/block/blockjob.h
40
+++ b/include/block/blockjob.h
41
@@ -XXX,XX +XXX,XX @@ void block_job_iostatus_reset(BlockJob *job);
42
BlockJobTxn *block_job_txn_new(void);
43
44
/**
45
+ * block_job_ref:
46
+ *
47
+ * Add a reference to BlockJob refcnt, it will be decreased with
48
+ * block_job_unref, and then be freed if it comes to be the last
49
+ * reference.
50
+ */
51
+void block_job_ref(BlockJob *job);
52
+
53
+/**
54
+ * block_job_unref:
55
+ *
56
+ * Release a reference that was previously acquired with block_job_ref
57
+ * or block_job_create. If it's the last reference to the object, it will be
58
+ * freed.
59
+ */
60
+void block_job_unref(BlockJob *job);
61
+
62
+/**
63
* block_job_txn_unref:
64
*
65
* Release a reference that was previously acquired with block_job_txn_add_job
66
diff --git a/qemu-img.c b/qemu-img.c
43
diff --git a/qemu-img.c b/qemu-img.c
67
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
68
--- a/qemu-img.c
45
--- a/qemu-img.c
69
+++ b/qemu-img.c
46
+++ b/qemu-img.c
70
@@ -XXX,XX +XXX,XX @@ static void common_block_job_cb(void *opaque, int ret)
47
@@ -XXX,XX +XXX,XX @@ static int print_block_option_help(const char *filename, const char *fmt)
71
static void run_block_job(BlockJob *job, Error **errp)
48
}
49
50
printf("Supported options:\n");
51
- qemu_opts_print_help(create_opts);
52
+ qemu_opts_print_help(create_opts, false);
53
qemu_opts_free(create_opts);
54
return 0;
55
}
56
@@ -XXX,XX +XXX,XX @@ static int print_amend_option_help(const char *format)
57
assert(drv->create_opts);
58
59
printf("Creation options for '%s':\n", format);
60
- qemu_opts_print_help(drv->create_opts);
61
+ qemu_opts_print_help(drv->create_opts, false);
62
printf("\nNote that not all of these options may be amendable.\n");
63
return 0;
64
}
65
diff --git a/util/qemu-option.c b/util/qemu-option.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/util/qemu-option.c
68
+++ b/util/qemu-option.c
69
@@ -XXX,XX +XXX,XX @@ static const char *opt_type_to_string(enum QemuOptType type)
70
g_assert_not_reached();
71
}
72
73
-void qemu_opts_print_help(QemuOptsList *list)
74
+/**
75
+ * Print the list of options available in the given list. If
76
+ * @print_caption is true, a caption (including the list name, if it
77
+ * exists) is printed. The options itself will be indented, so
78
+ * @print_caption should only be set to false if the caller prints its
79
+ * own custom caption (so that the indentation makes sense).
80
+ */
81
+void qemu_opts_print_help(QemuOptsList *list, bool print_caption)
72
{
82
{
73
AioContext *aio_context = blk_get_aio_context(job->blk);
83
QemuOptDesc *desc;
74
+ int ret = 0;
84
int i;
75
85
@@ -XXX,XX +XXX,XX @@ void qemu_opts_print_help(QemuOptsList *list)
76
- /* FIXME In error cases, the job simply goes away and we access a dangling
86
desc = list->desc;
77
- * pointer below. */
87
while (desc && desc->name) {
78
aio_context_acquire(aio_context);
88
GString *str = g_string_new(NULL);
79
+ block_job_ref(job);
89
- if (list->name) {
80
do {
90
- g_string_append_printf(str, "%s.", list->name);
81
aio_poll(aio_context, true);
91
- }
82
qemu_progress_print(job->len ?
92
- g_string_append_printf(str, "%s=%s", desc->name,
83
((float)job->offset / job->len * 100.f) : 0.0f, 0);
93
+ g_string_append_printf(str, " %s=<%s>", desc->name,
84
- } while (!job->ready);
94
opt_type_to_string(desc->type));
85
+ } while (!job->ready && !job->completed);
95
if (desc->help) {
86
96
+ if (str->len < 24) {
87
- block_job_complete_sync(job, errp);
97
+ g_string_append_printf(str, "%*s", 24 - (int)str->len, "");
88
+ if (!job->completed) {
98
+ }
89
+ ret = block_job_complete_sync(job, errp);
99
g_string_append_printf(str, " - %s", desc->help);
90
+ } else {
100
}
91
+ ret = job->ret;
101
g_ptr_array_add(array, g_string_free(str, false));
102
@@ -XXX,XX +XXX,XX @@ void qemu_opts_print_help(QemuOptsList *list)
103
}
104
105
g_ptr_array_sort(array, (GCompareFunc)qemu_pstrcmp0);
106
+ if (print_caption && array->len > 0) {
107
+ if (list->name) {
108
+ printf("%s options:\n", list->name);
109
+ } else {
110
+ printf("Options:\n");
111
+ }
112
+ } else if (array->len == 0) {
113
+ if (list->name) {
114
+ printf("There are no options for %s.\n", list->name);
115
+ } else {
116
+ printf("No options available.\n");
117
+ }
92
+ }
118
+ }
93
+ block_job_unref(job);
119
for (i = 0; i < array->len; i++) {
94
aio_context_release(aio_context);
120
printf("%s\n", (char *)array->pdata[i]);
95
121
}
96
- /* A block job may finish instantaneously without publishing any progress,
122
@@ -XXX,XX +XXX,XX @@ QemuOpts *qemu_opts_parse_noisily(QemuOptsList *list, const char *params,
97
- * so just signal completion here */
123
opts = opts_parse(list, params, permit_abbrev, false, &invalidp, &err);
98
- qemu_progress_print(100.f, 0);
124
if (err) {
99
+ /* publish completion progress only when success */
125
if (invalidp && has_help_option(params)) {
100
+ if (!ret) {
126
- qemu_opts_print_help(list);
101
+ qemu_progress_print(100.f, 0);
127
+ qemu_opts_print_help(list, true);
102
+ }
128
error_free(err);
103
}
129
} else {
104
130
error_report_err(err);
105
static int img_commit(int argc, char **argv)
131
diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out
132
index XXXXXXX..XXXXXXX 100644
133
--- a/tests/qemu-iotests/082.out
134
+++ b/tests/qemu-iotests/082.out
135
@@ -XXX,XX +XXX,XX @@ cluster_size: 8192
136
137
Testing: create -f qcow2 -o help TEST_DIR/t.qcow2 128M
138
Supported options:
139
-size Virtual disk size
140
-compat Compatibility level (0.10 or 1.1)
141
-backing_file File name of a base image
142
-backing_fmt Image format of the base image
143
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
144
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
145
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
146
-encrypt.cipher-alg Name of encryption cipher algorithm
147
-encrypt.cipher-mode Name of encryption cipher mode
148
-encrypt.ivgen-alg Name of IV generator algorithm
149
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
150
-encrypt.hash-alg Name of encryption hash algorithm
151
-encrypt.iter-time Time to spend in PBKDF in milliseconds
152
-cluster_size qcow2 cluster size
153
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
154
-lazy_refcounts Postpone refcount updates
155
-refcount_bits Width of a reference count entry in bits
156
-nocow Turn off copy-on-write (valid only on btrfs)
157
+ backing_file=<str> - File name of a base image
158
+ backing_fmt=<str> - Image format of the base image
159
+ cluster_size=<size> - qcow2 cluster size
160
+ compat=<str> - Compatibility level (0.10 or 1.1)
161
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
162
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
163
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
164
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
165
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
166
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
167
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
168
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
169
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
170
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
171
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
172
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
173
+ refcount_bits=<num> - Width of a reference count entry in bits
174
+ size=<size> - Virtual disk size
175
176
Testing: create -f qcow2 -o ? TEST_DIR/t.qcow2 128M
177
Supported options:
178
-size Virtual disk size
179
-compat Compatibility level (0.10 or 1.1)
180
-backing_file File name of a base image
181
-backing_fmt Image format of the base image
182
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
183
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
184
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
185
-encrypt.cipher-alg Name of encryption cipher algorithm
186
-encrypt.cipher-mode Name of encryption cipher mode
187
-encrypt.ivgen-alg Name of IV generator algorithm
188
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
189
-encrypt.hash-alg Name of encryption hash algorithm
190
-encrypt.iter-time Time to spend in PBKDF in milliseconds
191
-cluster_size qcow2 cluster size
192
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
193
-lazy_refcounts Postpone refcount updates
194
-refcount_bits Width of a reference count entry in bits
195
-nocow Turn off copy-on-write (valid only on btrfs)
196
+ backing_file=<str> - File name of a base image
197
+ backing_fmt=<str> - Image format of the base image
198
+ cluster_size=<size> - qcow2 cluster size
199
+ compat=<str> - Compatibility level (0.10 or 1.1)
200
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
201
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
202
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
203
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
204
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
205
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
206
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
207
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
208
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
209
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
210
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
211
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
212
+ refcount_bits=<num> - Width of a reference count entry in bits
213
+ size=<size> - Virtual disk size
214
215
Testing: create -f qcow2 -o cluster_size=4k,help TEST_DIR/t.qcow2 128M
216
Supported options:
217
-size Virtual disk size
218
-compat Compatibility level (0.10 or 1.1)
219
-backing_file File name of a base image
220
-backing_fmt Image format of the base image
221
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
222
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
223
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
224
-encrypt.cipher-alg Name of encryption cipher algorithm
225
-encrypt.cipher-mode Name of encryption cipher mode
226
-encrypt.ivgen-alg Name of IV generator algorithm
227
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
228
-encrypt.hash-alg Name of encryption hash algorithm
229
-encrypt.iter-time Time to spend in PBKDF in milliseconds
230
-cluster_size qcow2 cluster size
231
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
232
-lazy_refcounts Postpone refcount updates
233
-refcount_bits Width of a reference count entry in bits
234
-nocow Turn off copy-on-write (valid only on btrfs)
235
+ backing_file=<str> - File name of a base image
236
+ backing_fmt=<str> - Image format of the base image
237
+ cluster_size=<size> - qcow2 cluster size
238
+ compat=<str> - Compatibility level (0.10 or 1.1)
239
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
240
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
241
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
242
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
243
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
244
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
245
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
246
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
247
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
248
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
249
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
250
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
251
+ refcount_bits=<num> - Width of a reference count entry in bits
252
+ size=<size> - Virtual disk size
253
254
Testing: create -f qcow2 -o cluster_size=4k,? TEST_DIR/t.qcow2 128M
255
Supported options:
256
-size Virtual disk size
257
-compat Compatibility level (0.10 or 1.1)
258
-backing_file File name of a base image
259
-backing_fmt Image format of the base image
260
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
261
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
262
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
263
-encrypt.cipher-alg Name of encryption cipher algorithm
264
-encrypt.cipher-mode Name of encryption cipher mode
265
-encrypt.ivgen-alg Name of IV generator algorithm
266
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
267
-encrypt.hash-alg Name of encryption hash algorithm
268
-encrypt.iter-time Time to spend in PBKDF in milliseconds
269
-cluster_size qcow2 cluster size
270
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
271
-lazy_refcounts Postpone refcount updates
272
-refcount_bits Width of a reference count entry in bits
273
-nocow Turn off copy-on-write (valid only on btrfs)
274
+ backing_file=<str> - File name of a base image
275
+ backing_fmt=<str> - Image format of the base image
276
+ cluster_size=<size> - qcow2 cluster size
277
+ compat=<str> - Compatibility level (0.10 or 1.1)
278
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
279
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
280
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
281
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
282
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
283
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
284
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
285
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
286
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
287
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
288
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
289
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
290
+ refcount_bits=<num> - Width of a reference count entry in bits
291
+ size=<size> - Virtual disk size
292
293
Testing: create -f qcow2 -o help,cluster_size=4k TEST_DIR/t.qcow2 128M
294
Supported options:
295
-size Virtual disk size
296
-compat Compatibility level (0.10 or 1.1)
297
-backing_file File name of a base image
298
-backing_fmt Image format of the base image
299
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
300
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
301
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
302
-encrypt.cipher-alg Name of encryption cipher algorithm
303
-encrypt.cipher-mode Name of encryption cipher mode
304
-encrypt.ivgen-alg Name of IV generator algorithm
305
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
306
-encrypt.hash-alg Name of encryption hash algorithm
307
-encrypt.iter-time Time to spend in PBKDF in milliseconds
308
-cluster_size qcow2 cluster size
309
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
310
-lazy_refcounts Postpone refcount updates
311
-refcount_bits Width of a reference count entry in bits
312
-nocow Turn off copy-on-write (valid only on btrfs)
313
+ backing_file=<str> - File name of a base image
314
+ backing_fmt=<str> - Image format of the base image
315
+ cluster_size=<size> - qcow2 cluster size
316
+ compat=<str> - Compatibility level (0.10 or 1.1)
317
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
318
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
319
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
320
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
321
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
322
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
323
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
324
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
325
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
326
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
327
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
328
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
329
+ refcount_bits=<num> - Width of a reference count entry in bits
330
+ size=<size> - Virtual disk size
331
332
Testing: create -f qcow2 -o ?,cluster_size=4k TEST_DIR/t.qcow2 128M
333
Supported options:
334
-size Virtual disk size
335
-compat Compatibility level (0.10 or 1.1)
336
-backing_file File name of a base image
337
-backing_fmt Image format of the base image
338
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
339
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
340
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
341
-encrypt.cipher-alg Name of encryption cipher algorithm
342
-encrypt.cipher-mode Name of encryption cipher mode
343
-encrypt.ivgen-alg Name of IV generator algorithm
344
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
345
-encrypt.hash-alg Name of encryption hash algorithm
346
-encrypt.iter-time Time to spend in PBKDF in milliseconds
347
-cluster_size qcow2 cluster size
348
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
349
-lazy_refcounts Postpone refcount updates
350
-refcount_bits Width of a reference count entry in bits
351
-nocow Turn off copy-on-write (valid only on btrfs)
352
+ backing_file=<str> - File name of a base image
353
+ backing_fmt=<str> - Image format of the base image
354
+ cluster_size=<size> - qcow2 cluster size
355
+ compat=<str> - Compatibility level (0.10 or 1.1)
356
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
357
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
358
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
359
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
360
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
361
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
362
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
363
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
364
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
365
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
366
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
367
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
368
+ refcount_bits=<num> - Width of a reference count entry in bits
369
+ size=<size> - Virtual disk size
370
371
Testing: create -f qcow2 -o cluster_size=4k -o help TEST_DIR/t.qcow2 128M
372
Supported options:
373
-size Virtual disk size
374
-compat Compatibility level (0.10 or 1.1)
375
-backing_file File name of a base image
376
-backing_fmt Image format of the base image
377
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
378
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
379
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
380
-encrypt.cipher-alg Name of encryption cipher algorithm
381
-encrypt.cipher-mode Name of encryption cipher mode
382
-encrypt.ivgen-alg Name of IV generator algorithm
383
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
384
-encrypt.hash-alg Name of encryption hash algorithm
385
-encrypt.iter-time Time to spend in PBKDF in milliseconds
386
-cluster_size qcow2 cluster size
387
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
388
-lazy_refcounts Postpone refcount updates
389
-refcount_bits Width of a reference count entry in bits
390
-nocow Turn off copy-on-write (valid only on btrfs)
391
+ backing_file=<str> - File name of a base image
392
+ backing_fmt=<str> - Image format of the base image
393
+ cluster_size=<size> - qcow2 cluster size
394
+ compat=<str> - Compatibility level (0.10 or 1.1)
395
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
396
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
397
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
398
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
399
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
400
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
401
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
402
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
403
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
404
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
405
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
406
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
407
+ refcount_bits=<num> - Width of a reference count entry in bits
408
+ size=<size> - Virtual disk size
409
410
Testing: create -f qcow2 -o cluster_size=4k -o ? TEST_DIR/t.qcow2 128M
411
Supported options:
412
-size Virtual disk size
413
-compat Compatibility level (0.10 or 1.1)
414
-backing_file File name of a base image
415
-backing_fmt Image format of the base image
416
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
417
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
418
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
419
-encrypt.cipher-alg Name of encryption cipher algorithm
420
-encrypt.cipher-mode Name of encryption cipher mode
421
-encrypt.ivgen-alg Name of IV generator algorithm
422
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
423
-encrypt.hash-alg Name of encryption hash algorithm
424
-encrypt.iter-time Time to spend in PBKDF in milliseconds
425
-cluster_size qcow2 cluster size
426
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
427
-lazy_refcounts Postpone refcount updates
428
-refcount_bits Width of a reference count entry in bits
429
-nocow Turn off copy-on-write (valid only on btrfs)
430
+ backing_file=<str> - File name of a base image
431
+ backing_fmt=<str> - Image format of the base image
432
+ cluster_size=<size> - qcow2 cluster size
433
+ compat=<str> - Compatibility level (0.10 or 1.1)
434
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
435
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
436
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
437
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
438
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
439
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
440
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
441
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
442
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
443
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
444
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
445
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
446
+ refcount_bits=<num> - Width of a reference count entry in bits
447
+ size=<size> - Virtual disk size
448
449
Testing: create -f qcow2 -u -o backing_file=TEST_DIR/t.qcow2,,help TEST_DIR/t.qcow2 128M
450
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2,,help cluster_size=65536 lazy_refcounts=off refcount_bits=16
451
@@ -XXX,XX +XXX,XX @@ qemu-img: Invalid option list: ,,
452
453
Testing: create -f qcow2 -o help
454
Supported options:
455
-size Virtual disk size
456
-compat Compatibility level (0.10 or 1.1)
457
-backing_file File name of a base image
458
-backing_fmt Image format of the base image
459
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
460
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
461
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
462
-encrypt.cipher-alg Name of encryption cipher algorithm
463
-encrypt.cipher-mode Name of encryption cipher mode
464
-encrypt.ivgen-alg Name of IV generator algorithm
465
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
466
-encrypt.hash-alg Name of encryption hash algorithm
467
-encrypt.iter-time Time to spend in PBKDF in milliseconds
468
-cluster_size qcow2 cluster size
469
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
470
-lazy_refcounts Postpone refcount updates
471
-refcount_bits Width of a reference count entry in bits
472
+ backing_file=<str> - File name of a base image
473
+ backing_fmt=<str> - Image format of the base image
474
+ cluster_size=<size> - qcow2 cluster size
475
+ compat=<str> - Compatibility level (0.10 or 1.1)
476
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
477
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
478
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
479
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
480
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
481
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
482
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
483
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
484
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
485
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
486
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
487
+ refcount_bits=<num> - Width of a reference count entry in bits
488
+ size=<size> - Virtual disk size
489
490
Testing: create -o help
491
Supported options:
492
-size Virtual disk size
493
+ size=<size> - Virtual disk size
494
495
Testing: create -f bochs -o help
496
qemu-img: Format driver 'bochs' does not support image creation
497
@@ -XXX,XX +XXX,XX @@ cluster_size: 8192
498
499
Testing: convert -O qcow2 -o help TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
500
Supported options:
501
-size Virtual disk size
502
-compat Compatibility level (0.10 or 1.1)
503
-backing_file File name of a base image
504
-backing_fmt Image format of the base image
505
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
506
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
507
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
508
-encrypt.cipher-alg Name of encryption cipher algorithm
509
-encrypt.cipher-mode Name of encryption cipher mode
510
-encrypt.ivgen-alg Name of IV generator algorithm
511
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
512
-encrypt.hash-alg Name of encryption hash algorithm
513
-encrypt.iter-time Time to spend in PBKDF in milliseconds
514
-cluster_size qcow2 cluster size
515
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
516
-lazy_refcounts Postpone refcount updates
517
-refcount_bits Width of a reference count entry in bits
518
-nocow Turn off copy-on-write (valid only on btrfs)
519
+ backing_file=<str> - File name of a base image
520
+ backing_fmt=<str> - Image format of the base image
521
+ cluster_size=<size> - qcow2 cluster size
522
+ compat=<str> - Compatibility level (0.10 or 1.1)
523
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
524
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
525
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
526
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
527
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
528
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
529
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
530
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
531
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
532
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
533
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
534
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
535
+ refcount_bits=<num> - Width of a reference count entry in bits
536
+ size=<size> - Virtual disk size
537
538
Testing: convert -O qcow2 -o ? TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
539
Supported options:
540
-size Virtual disk size
541
-compat Compatibility level (0.10 or 1.1)
542
-backing_file File name of a base image
543
-backing_fmt Image format of the base image
544
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
545
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
546
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
547
-encrypt.cipher-alg Name of encryption cipher algorithm
548
-encrypt.cipher-mode Name of encryption cipher mode
549
-encrypt.ivgen-alg Name of IV generator algorithm
550
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
551
-encrypt.hash-alg Name of encryption hash algorithm
552
-encrypt.iter-time Time to spend in PBKDF in milliseconds
553
-cluster_size qcow2 cluster size
554
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
555
-lazy_refcounts Postpone refcount updates
556
-refcount_bits Width of a reference count entry in bits
557
-nocow Turn off copy-on-write (valid only on btrfs)
558
+ backing_file=<str> - File name of a base image
559
+ backing_fmt=<str> - Image format of the base image
560
+ cluster_size=<size> - qcow2 cluster size
561
+ compat=<str> - Compatibility level (0.10 or 1.1)
562
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
563
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
564
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
565
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
566
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
567
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
568
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
569
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
570
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
571
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
572
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
573
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
574
+ refcount_bits=<num> - Width of a reference count entry in bits
575
+ size=<size> - Virtual disk size
576
577
Testing: convert -O qcow2 -o cluster_size=4k,help TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
578
Supported options:
579
-size Virtual disk size
580
-compat Compatibility level (0.10 or 1.1)
581
-backing_file File name of a base image
582
-backing_fmt Image format of the base image
583
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
584
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
585
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
586
-encrypt.cipher-alg Name of encryption cipher algorithm
587
-encrypt.cipher-mode Name of encryption cipher mode
588
-encrypt.ivgen-alg Name of IV generator algorithm
589
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
590
-encrypt.hash-alg Name of encryption hash algorithm
591
-encrypt.iter-time Time to spend in PBKDF in milliseconds
592
-cluster_size qcow2 cluster size
593
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
594
-lazy_refcounts Postpone refcount updates
595
-refcount_bits Width of a reference count entry in bits
596
-nocow Turn off copy-on-write (valid only on btrfs)
597
+ backing_file=<str> - File name of a base image
598
+ backing_fmt=<str> - Image format of the base image
599
+ cluster_size=<size> - qcow2 cluster size
600
+ compat=<str> - Compatibility level (0.10 or 1.1)
601
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
602
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
603
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
604
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
605
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
606
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
607
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
608
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
609
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
610
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
611
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
612
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
613
+ refcount_bits=<num> - Width of a reference count entry in bits
614
+ size=<size> - Virtual disk size
615
616
Testing: convert -O qcow2 -o cluster_size=4k,? TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
617
Supported options:
618
-size Virtual disk size
619
-compat Compatibility level (0.10 or 1.1)
620
-backing_file File name of a base image
621
-backing_fmt Image format of the base image
622
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
623
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
624
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
625
-encrypt.cipher-alg Name of encryption cipher algorithm
626
-encrypt.cipher-mode Name of encryption cipher mode
627
-encrypt.ivgen-alg Name of IV generator algorithm
628
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
629
-encrypt.hash-alg Name of encryption hash algorithm
630
-encrypt.iter-time Time to spend in PBKDF in milliseconds
631
-cluster_size qcow2 cluster size
632
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
633
-lazy_refcounts Postpone refcount updates
634
-refcount_bits Width of a reference count entry in bits
635
-nocow Turn off copy-on-write (valid only on btrfs)
636
+ backing_file=<str> - File name of a base image
637
+ backing_fmt=<str> - Image format of the base image
638
+ cluster_size=<size> - qcow2 cluster size
639
+ compat=<str> - Compatibility level (0.10 or 1.1)
640
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
641
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
642
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
643
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
644
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
645
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
646
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
647
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
648
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
649
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
650
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
651
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
652
+ refcount_bits=<num> - Width of a reference count entry in bits
653
+ size=<size> - Virtual disk size
654
655
Testing: convert -O qcow2 -o help,cluster_size=4k TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
656
Supported options:
657
-size Virtual disk size
658
-compat Compatibility level (0.10 or 1.1)
659
-backing_file File name of a base image
660
-backing_fmt Image format of the base image
661
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
662
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
663
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
664
-encrypt.cipher-alg Name of encryption cipher algorithm
665
-encrypt.cipher-mode Name of encryption cipher mode
666
-encrypt.ivgen-alg Name of IV generator algorithm
667
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
668
-encrypt.hash-alg Name of encryption hash algorithm
669
-encrypt.iter-time Time to spend in PBKDF in milliseconds
670
-cluster_size qcow2 cluster size
671
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
672
-lazy_refcounts Postpone refcount updates
673
-refcount_bits Width of a reference count entry in bits
674
-nocow Turn off copy-on-write (valid only on btrfs)
675
+ backing_file=<str> - File name of a base image
676
+ backing_fmt=<str> - Image format of the base image
677
+ cluster_size=<size> - qcow2 cluster size
678
+ compat=<str> - Compatibility level (0.10 or 1.1)
679
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
680
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
681
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
682
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
683
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
684
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
685
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
686
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
687
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
688
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
689
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
690
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
691
+ refcount_bits=<num> - Width of a reference count entry in bits
692
+ size=<size> - Virtual disk size
693
694
Testing: convert -O qcow2 -o ?,cluster_size=4k TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
695
Supported options:
696
-size Virtual disk size
697
-compat Compatibility level (0.10 or 1.1)
698
-backing_file File name of a base image
699
-backing_fmt Image format of the base image
700
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
701
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
702
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
703
-encrypt.cipher-alg Name of encryption cipher algorithm
704
-encrypt.cipher-mode Name of encryption cipher mode
705
-encrypt.ivgen-alg Name of IV generator algorithm
706
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
707
-encrypt.hash-alg Name of encryption hash algorithm
708
-encrypt.iter-time Time to spend in PBKDF in milliseconds
709
-cluster_size qcow2 cluster size
710
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
711
-lazy_refcounts Postpone refcount updates
712
-refcount_bits Width of a reference count entry in bits
713
-nocow Turn off copy-on-write (valid only on btrfs)
714
+ backing_file=<str> - File name of a base image
715
+ backing_fmt=<str> - Image format of the base image
716
+ cluster_size=<size> - qcow2 cluster size
717
+ compat=<str> - Compatibility level (0.10 or 1.1)
718
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
719
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
720
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
721
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
722
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
723
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
724
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
725
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
726
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
727
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
728
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
729
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
730
+ refcount_bits=<num> - Width of a reference count entry in bits
731
+ size=<size> - Virtual disk size
732
733
Testing: convert -O qcow2 -o cluster_size=4k -o help TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
734
Supported options:
735
-size Virtual disk size
736
-compat Compatibility level (0.10 or 1.1)
737
-backing_file File name of a base image
738
-backing_fmt Image format of the base image
739
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
740
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
741
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
742
-encrypt.cipher-alg Name of encryption cipher algorithm
743
-encrypt.cipher-mode Name of encryption cipher mode
744
-encrypt.ivgen-alg Name of IV generator algorithm
745
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
746
-encrypt.hash-alg Name of encryption hash algorithm
747
-encrypt.iter-time Time to spend in PBKDF in milliseconds
748
-cluster_size qcow2 cluster size
749
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
750
-lazy_refcounts Postpone refcount updates
751
-refcount_bits Width of a reference count entry in bits
752
-nocow Turn off copy-on-write (valid only on btrfs)
753
+ backing_file=<str> - File name of a base image
754
+ backing_fmt=<str> - Image format of the base image
755
+ cluster_size=<size> - qcow2 cluster size
756
+ compat=<str> - Compatibility level (0.10 or 1.1)
757
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
758
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
759
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
760
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
761
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
762
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
763
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
764
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
765
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
766
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
767
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
768
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
769
+ refcount_bits=<num> - Width of a reference count entry in bits
770
+ size=<size> - Virtual disk size
771
772
Testing: convert -O qcow2 -o cluster_size=4k -o ? TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
773
Supported options:
774
-size Virtual disk size
775
-compat Compatibility level (0.10 or 1.1)
776
-backing_file File name of a base image
777
-backing_fmt Image format of the base image
778
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
779
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
780
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
781
-encrypt.cipher-alg Name of encryption cipher algorithm
782
-encrypt.cipher-mode Name of encryption cipher mode
783
-encrypt.ivgen-alg Name of IV generator algorithm
784
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
785
-encrypt.hash-alg Name of encryption hash algorithm
786
-encrypt.iter-time Time to spend in PBKDF in milliseconds
787
-cluster_size qcow2 cluster size
788
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
789
-lazy_refcounts Postpone refcount updates
790
-refcount_bits Width of a reference count entry in bits
791
-nocow Turn off copy-on-write (valid only on btrfs)
792
+ backing_file=<str> - File name of a base image
793
+ backing_fmt=<str> - Image format of the base image
794
+ cluster_size=<size> - qcow2 cluster size
795
+ compat=<str> - Compatibility level (0.10 or 1.1)
796
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
797
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
798
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
799
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
800
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
801
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
802
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
803
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
804
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
805
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
806
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
807
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
808
+ refcount_bits=<num> - Width of a reference count entry in bits
809
+ size=<size> - Virtual disk size
810
811
Testing: convert -O qcow2 -o backing_file=TEST_DIR/t.qcow2,,help TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
812
qemu-img: Could not open 'TEST_DIR/t.qcow2.base': Could not open backing file: Could not open 'TEST_DIR/t.qcow2,help': No such file or directory
813
@@ -XXX,XX +XXX,XX @@ qemu-img: Invalid option list: ,,
814
815
Testing: convert -O qcow2 -o help
816
Supported options:
817
-size Virtual disk size
818
-compat Compatibility level (0.10 or 1.1)
819
-backing_file File name of a base image
820
-backing_fmt Image format of the base image
821
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
822
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
823
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
824
-encrypt.cipher-alg Name of encryption cipher algorithm
825
-encrypt.cipher-mode Name of encryption cipher mode
826
-encrypt.ivgen-alg Name of IV generator algorithm
827
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
828
-encrypt.hash-alg Name of encryption hash algorithm
829
-encrypt.iter-time Time to spend in PBKDF in milliseconds
830
-cluster_size qcow2 cluster size
831
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
832
-lazy_refcounts Postpone refcount updates
833
-refcount_bits Width of a reference count entry in bits
834
+ backing_file=<str> - File name of a base image
835
+ backing_fmt=<str> - Image format of the base image
836
+ cluster_size=<size> - qcow2 cluster size
837
+ compat=<str> - Compatibility level (0.10 or 1.1)
838
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
839
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
840
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
841
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
842
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
843
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
844
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
845
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
846
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
847
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
848
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
849
+ refcount_bits=<num> - Width of a reference count entry in bits
850
+ size=<size> - Virtual disk size
851
852
Testing: convert -o help
853
Supported options:
854
-size Virtual disk size
855
+ size=<size> - Virtual disk size
856
857
Testing: convert -O bochs -o help
858
qemu-img: Format driver 'bochs' does not support image creation
859
@@ -XXX,XX +XXX,XX @@ cluster_size: 65536
860
861
Testing: amend -f qcow2 -o help TEST_DIR/t.qcow2
862
Creation options for 'qcow2':
863
-size Virtual disk size
864
-compat Compatibility level (0.10 or 1.1)
865
-backing_file File name of a base image
866
-backing_fmt Image format of the base image
867
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
868
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
869
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
870
-encrypt.cipher-alg Name of encryption cipher algorithm
871
-encrypt.cipher-mode Name of encryption cipher mode
872
-encrypt.ivgen-alg Name of IV generator algorithm
873
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
874
-encrypt.hash-alg Name of encryption hash algorithm
875
-encrypt.iter-time Time to spend in PBKDF in milliseconds
876
-cluster_size qcow2 cluster size
877
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
878
-lazy_refcounts Postpone refcount updates
879
-refcount_bits Width of a reference count entry in bits
880
+ backing_file=<str> - File name of a base image
881
+ backing_fmt=<str> - Image format of the base image
882
+ cluster_size=<size> - qcow2 cluster size
883
+ compat=<str> - Compatibility level (0.10 or 1.1)
884
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
885
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
886
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
887
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
888
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
889
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
890
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
891
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
892
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
893
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
894
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
895
+ refcount_bits=<num> - Width of a reference count entry in bits
896
+ size=<size> - Virtual disk size
897
898
Note that not all of these options may be amendable.
899
900
Testing: amend -f qcow2 -o ? TEST_DIR/t.qcow2
901
Creation options for 'qcow2':
902
-size Virtual disk size
903
-compat Compatibility level (0.10 or 1.1)
904
-backing_file File name of a base image
905
-backing_fmt Image format of the base image
906
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
907
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
908
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
909
-encrypt.cipher-alg Name of encryption cipher algorithm
910
-encrypt.cipher-mode Name of encryption cipher mode
911
-encrypt.ivgen-alg Name of IV generator algorithm
912
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
913
-encrypt.hash-alg Name of encryption hash algorithm
914
-encrypt.iter-time Time to spend in PBKDF in milliseconds
915
-cluster_size qcow2 cluster size
916
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
917
-lazy_refcounts Postpone refcount updates
918
-refcount_bits Width of a reference count entry in bits
919
+ backing_file=<str> - File name of a base image
920
+ backing_fmt=<str> - Image format of the base image
921
+ cluster_size=<size> - qcow2 cluster size
922
+ compat=<str> - Compatibility level (0.10 or 1.1)
923
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
924
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
925
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
926
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
927
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
928
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
929
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
930
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
931
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
932
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
933
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
934
+ refcount_bits=<num> - Width of a reference count entry in bits
935
+ size=<size> - Virtual disk size
936
937
Note that not all of these options may be amendable.
938
939
Testing: amend -f qcow2 -o cluster_size=4k,help TEST_DIR/t.qcow2
940
Creation options for 'qcow2':
941
-size Virtual disk size
942
-compat Compatibility level (0.10 or 1.1)
943
-backing_file File name of a base image
944
-backing_fmt Image format of the base image
945
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
946
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
947
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
948
-encrypt.cipher-alg Name of encryption cipher algorithm
949
-encrypt.cipher-mode Name of encryption cipher mode
950
-encrypt.ivgen-alg Name of IV generator algorithm
951
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
952
-encrypt.hash-alg Name of encryption hash algorithm
953
-encrypt.iter-time Time to spend in PBKDF in milliseconds
954
-cluster_size qcow2 cluster size
955
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
956
-lazy_refcounts Postpone refcount updates
957
-refcount_bits Width of a reference count entry in bits
958
+ backing_file=<str> - File name of a base image
959
+ backing_fmt=<str> - Image format of the base image
960
+ cluster_size=<size> - qcow2 cluster size
961
+ compat=<str> - Compatibility level (0.10 or 1.1)
962
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
963
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
964
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
965
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
966
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
967
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
968
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
969
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
970
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
971
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
972
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
973
+ refcount_bits=<num> - Width of a reference count entry in bits
974
+ size=<size> - Virtual disk size
975
976
Note that not all of these options may be amendable.
977
978
Testing: amend -f qcow2 -o cluster_size=4k,? TEST_DIR/t.qcow2
979
Creation options for 'qcow2':
980
-size Virtual disk size
981
-compat Compatibility level (0.10 or 1.1)
982
-backing_file File name of a base image
983
-backing_fmt Image format of the base image
984
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
985
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
986
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
987
-encrypt.cipher-alg Name of encryption cipher algorithm
988
-encrypt.cipher-mode Name of encryption cipher mode
989
-encrypt.ivgen-alg Name of IV generator algorithm
990
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
991
-encrypt.hash-alg Name of encryption hash algorithm
992
-encrypt.iter-time Time to spend in PBKDF in milliseconds
993
-cluster_size qcow2 cluster size
994
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
995
-lazy_refcounts Postpone refcount updates
996
-refcount_bits Width of a reference count entry in bits
997
+ backing_file=<str> - File name of a base image
998
+ backing_fmt=<str> - Image format of the base image
999
+ cluster_size=<size> - qcow2 cluster size
1000
+ compat=<str> - Compatibility level (0.10 or 1.1)
1001
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1002
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1003
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1004
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1005
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1006
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1007
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1008
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1009
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1010
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1011
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1012
+ refcount_bits=<num> - Width of a reference count entry in bits
1013
+ size=<size> - Virtual disk size
1014
1015
Note that not all of these options may be amendable.
1016
1017
Testing: amend -f qcow2 -o help,cluster_size=4k TEST_DIR/t.qcow2
1018
Creation options for 'qcow2':
1019
-size Virtual disk size
1020
-compat Compatibility level (0.10 or 1.1)
1021
-backing_file File name of a base image
1022
-backing_fmt Image format of the base image
1023
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1024
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
1025
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
1026
-encrypt.cipher-alg Name of encryption cipher algorithm
1027
-encrypt.cipher-mode Name of encryption cipher mode
1028
-encrypt.ivgen-alg Name of IV generator algorithm
1029
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
1030
-encrypt.hash-alg Name of encryption hash algorithm
1031
-encrypt.iter-time Time to spend in PBKDF in milliseconds
1032
-cluster_size qcow2 cluster size
1033
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
1034
-lazy_refcounts Postpone refcount updates
1035
-refcount_bits Width of a reference count entry in bits
1036
+ backing_file=<str> - File name of a base image
1037
+ backing_fmt=<str> - Image format of the base image
1038
+ cluster_size=<size> - qcow2 cluster size
1039
+ compat=<str> - Compatibility level (0.10 or 1.1)
1040
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1041
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1042
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1043
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1044
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1045
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1046
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1047
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1048
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1049
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1050
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1051
+ refcount_bits=<num> - Width of a reference count entry in bits
1052
+ size=<size> - Virtual disk size
1053
1054
Note that not all of these options may be amendable.
1055
1056
Testing: amend -f qcow2 -o ?,cluster_size=4k TEST_DIR/t.qcow2
1057
Creation options for 'qcow2':
1058
-size Virtual disk size
1059
-compat Compatibility level (0.10 or 1.1)
1060
-backing_file File name of a base image
1061
-backing_fmt Image format of the base image
1062
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1063
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
1064
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
1065
-encrypt.cipher-alg Name of encryption cipher algorithm
1066
-encrypt.cipher-mode Name of encryption cipher mode
1067
-encrypt.ivgen-alg Name of IV generator algorithm
1068
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
1069
-encrypt.hash-alg Name of encryption hash algorithm
1070
-encrypt.iter-time Time to spend in PBKDF in milliseconds
1071
-cluster_size qcow2 cluster size
1072
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
1073
-lazy_refcounts Postpone refcount updates
1074
-refcount_bits Width of a reference count entry in bits
1075
+ backing_file=<str> - File name of a base image
1076
+ backing_fmt=<str> - Image format of the base image
1077
+ cluster_size=<size> - qcow2 cluster size
1078
+ compat=<str> - Compatibility level (0.10 or 1.1)
1079
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1080
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1081
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1082
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1083
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1084
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1085
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1086
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1087
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1088
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1089
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1090
+ refcount_bits=<num> - Width of a reference count entry in bits
1091
+ size=<size> - Virtual disk size
1092
1093
Note that not all of these options may be amendable.
1094
1095
Testing: amend -f qcow2 -o cluster_size=4k -o help TEST_DIR/t.qcow2
1096
Creation options for 'qcow2':
1097
-size Virtual disk size
1098
-compat Compatibility level (0.10 or 1.1)
1099
-backing_file File name of a base image
1100
-backing_fmt Image format of the base image
1101
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1102
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
1103
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
1104
-encrypt.cipher-alg Name of encryption cipher algorithm
1105
-encrypt.cipher-mode Name of encryption cipher mode
1106
-encrypt.ivgen-alg Name of IV generator algorithm
1107
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
1108
-encrypt.hash-alg Name of encryption hash algorithm
1109
-encrypt.iter-time Time to spend in PBKDF in milliseconds
1110
-cluster_size qcow2 cluster size
1111
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
1112
-lazy_refcounts Postpone refcount updates
1113
-refcount_bits Width of a reference count entry in bits
1114
+ backing_file=<str> - File name of a base image
1115
+ backing_fmt=<str> - Image format of the base image
1116
+ cluster_size=<size> - qcow2 cluster size
1117
+ compat=<str> - Compatibility level (0.10 or 1.1)
1118
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1119
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1120
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1121
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1122
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1123
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1124
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1125
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1126
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1127
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1128
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1129
+ refcount_bits=<num> - Width of a reference count entry in bits
1130
+ size=<size> - Virtual disk size
1131
1132
Note that not all of these options may be amendable.
1133
1134
Testing: amend -f qcow2 -o cluster_size=4k -o ? TEST_DIR/t.qcow2
1135
Creation options for 'qcow2':
1136
-size Virtual disk size
1137
-compat Compatibility level (0.10 or 1.1)
1138
-backing_file File name of a base image
1139
-backing_fmt Image format of the base image
1140
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1141
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
1142
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
1143
-encrypt.cipher-alg Name of encryption cipher algorithm
1144
-encrypt.cipher-mode Name of encryption cipher mode
1145
-encrypt.ivgen-alg Name of IV generator algorithm
1146
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
1147
-encrypt.hash-alg Name of encryption hash algorithm
1148
-encrypt.iter-time Time to spend in PBKDF in milliseconds
1149
-cluster_size qcow2 cluster size
1150
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
1151
-lazy_refcounts Postpone refcount updates
1152
-refcount_bits Width of a reference count entry in bits
1153
+ backing_file=<str> - File name of a base image
1154
+ backing_fmt=<str> - Image format of the base image
1155
+ cluster_size=<size> - qcow2 cluster size
1156
+ compat=<str> - Compatibility level (0.10 or 1.1)
1157
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1158
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1159
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1160
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1161
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1162
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1163
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1164
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1165
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1166
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1167
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1168
+ refcount_bits=<num> - Width of a reference count entry in bits
1169
+ size=<size> - Virtual disk size
1170
1171
Note that not all of these options may be amendable.
1172
1173
@@ -XXX,XX +XXX,XX @@ qemu-img: Invalid option list: ,,
1174
1175
Testing: amend -f qcow2 -o help
1176
Creation options for 'qcow2':
1177
-size Virtual disk size
1178
-compat Compatibility level (0.10 or 1.1)
1179
-backing_file File name of a base image
1180
-backing_fmt Image format of the base image
1181
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1182
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
1183
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
1184
-encrypt.cipher-alg Name of encryption cipher algorithm
1185
-encrypt.cipher-mode Name of encryption cipher mode
1186
-encrypt.ivgen-alg Name of IV generator algorithm
1187
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
1188
-encrypt.hash-alg Name of encryption hash algorithm
1189
-encrypt.iter-time Time to spend in PBKDF in milliseconds
1190
-cluster_size qcow2 cluster size
1191
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
1192
-lazy_refcounts Postpone refcount updates
1193
-refcount_bits Width of a reference count entry in bits
1194
+ backing_file=<str> - File name of a base image
1195
+ backing_fmt=<str> - Image format of the base image
1196
+ cluster_size=<size> - qcow2 cluster size
1197
+ compat=<str> - Compatibility level (0.10 or 1.1)
1198
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1199
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1200
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1201
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1202
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1203
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1204
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1205
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1206
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1207
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1208
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1209
+ refcount_bits=<num> - Width of a reference count entry in bits
1210
+ size=<size> - Virtual disk size
1211
1212
Note that not all of these options may be amendable.
1213
1214
Testing: convert -o help
1215
Supported options:
1216
-size Virtual disk size
1217
+ size=<size> - Virtual disk size
1218
1219
Testing: amend -f bochs -o help
1220
qemu-img: Format driver 'bochs' does not support option amendment
106
--
1221
--
107
1.8.3.1
1222
2.19.1
108
1223
109
1224
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
The bs->exact_filename field may not be sufficient to store the full
3
Following the example of qemu_opts_print_help(), indent all entries in
4
blkverify node filename. In this case, we should not generate a filename
4
the list of character devices.
5
at all instead of an unusable one.
6
5
7
Cc: qemu-stable@nongnu.org
8
Reported-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
Message-id: 20170613172006.19685-3-mreitz@redhat.com
7
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
11
Reviewed-by: Alberto Garcia <berto@igalia.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
13
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
---
9
---
15
block/blkverify.c | 12 ++++++++----
10
chardev/char.c | 2 +-
16
1 file changed, 8 insertions(+), 4 deletions(-)
11
1 file changed, 1 insertion(+), 1 deletion(-)
17
12
18
diff --git a/block/blkverify.c b/block/blkverify.c
13
diff --git a/chardev/char.c b/chardev/char.c
19
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
20
--- a/block/blkverify.c
15
--- a/chardev/char.c
21
+++ b/block/blkverify.c
16
+++ b/chardev/char.c
22
@@ -XXX,XX +XXX,XX @@ static void blkverify_refresh_filename(BlockDriverState *bs, QDict *options)
17
@@ -XXX,XX +XXX,XX @@ help_string_append(const char *name, void *opaque)
23
if (bs->file->bs->exact_filename[0]
18
{
24
&& s->test_file->bs->exact_filename[0])
19
GString *str = opaque;
25
{
20
26
- snprintf(bs->exact_filename, sizeof(bs->exact_filename),
21
- g_string_append_printf(str, "\n%s", name);
27
- "blkverify:%s:%s",
22
+ g_string_append_printf(str, "\n %s", name);
28
- bs->file->bs->exact_filename,
29
- s->test_file->bs->exact_filename);
30
+ int ret = snprintf(bs->exact_filename, sizeof(bs->exact_filename),
31
+ "blkverify:%s:%s",
32
+ bs->file->bs->exact_filename,
33
+ s->test_file->bs->exact_filename);
34
+ if (ret >= sizeof(bs->exact_filename)) {
35
+ /* An overflow makes the filename unusable, so do not report any */
36
+ bs->exact_filename[0] = 0;
37
+ }
38
}
39
}
23
}
40
24
25
static const char *chardev_alias_translate(const char *name)
41
--
26
--
42
1.8.3.1
27
2.19.1
43
28
44
29
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
uri_parse(...)->scheme may be NULL. In fact, probably every field may be
3
Just like in qemu_opts_print_help(), print the device name as a caption
4
NULL, and the callers do test this for all of the other fields but not
4
instead of on every single line, indent all options, add angle brackets
5
for scheme (except for block/gluster.c; block/vxhs.c does not access
5
around types, and align the descriptions after 24 characters. Also,
6
that field at all).
6
separate the descriptions with " - " instead of putting them in
7
parentheses, because that is what we do everywhere else. This does look
8
a bit funny here because basically all bits have the description
9
"on/off", but funny does not mean it is less readable.
7
10
8
We can easily fix this by using g_strcmp0() instead of strcmp().
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
15
qdev-monitor.c | 13 +++++++++++--
16
1 file changed, 11 insertions(+), 2 deletions(-)
9
17
10
Cc: qemu-stable@nongnu.org
18
diff --git a/qdev-monitor.c b/qdev-monitor.c
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
Message-id: 20170613205726.13544-1-mreitz@redhat.com
13
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
15
---
16
block/nbd.c | 6 +++---
17
block/nfs.c | 2 +-
18
block/sheepdog.c | 6 +++---
19
block/ssh.c | 2 +-
20
4 files changed, 8 insertions(+), 8 deletions(-)
21
22
diff --git a/block/nbd.c b/block/nbd.c
23
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
24
--- a/block/nbd.c
20
--- a/qdev-monitor.c
25
+++ b/block/nbd.c
21
+++ b/qdev-monitor.c
26
@@ -XXX,XX +XXX,XX @@ static int nbd_parse_uri(const char *filename, QDict *options)
22
@@ -XXX,XX +XXX,XX @@ int qdev_device_help(QemuOpts *opts)
23
goto error;
27
}
24
}
28
25
29
/* transport */
26
+ if (prop_list) {
30
- if (!strcmp(uri->scheme, "nbd")) {
27
+ out_printf("%s options:\n", driver);
31
+ if (!g_strcmp0(uri->scheme, "nbd")) {
28
+ } else {
32
is_unix = false;
29
+ out_printf("There are no options for %s.\n", driver);
33
- } else if (!strcmp(uri->scheme, "nbd+tcp")) {
30
+ }
34
+ } else if (!g_strcmp0(uri->scheme, "nbd+tcp")) {
31
for (prop = prop_list; prop; prop = prop->next) {
35
is_unix = false;
32
- out_printf("%s.%s=%s", driver, prop->value->name, prop->value->type);
36
- } else if (!strcmp(uri->scheme, "nbd+unix")) {
33
+ int len;
37
+ } else if (!g_strcmp0(uri->scheme, "nbd+unix")) {
34
+ out_printf(" %s=<%s>%n", prop->value->name, prop->value->type, &len);
38
is_unix = true;
35
if (prop->value->has_description) {
39
} else {
36
- out_printf(" (%s)\n", prop->value->description);
40
ret = -EINVAL;
37
+ if (len < 24) {
41
diff --git a/block/nfs.c b/block/nfs.c
38
+ out_printf("%*s", 24 - len, "");
42
index XXXXXXX..XXXXXXX 100644
39
+ }
43
--- a/block/nfs.c
40
+ out_printf(" - %s\n", prop->value->description);
44
+++ b/block/nfs.c
41
} else {
45
@@ -XXX,XX +XXX,XX @@ static int nfs_parse_uri(const char *filename, QDict *options, Error **errp)
42
out_printf("\n");
46
error_setg(errp, "Invalid URI specified");
43
}
47
goto out;
48
}
49
- if (strcmp(uri->scheme, "nfs") != 0) {
50
+ if (g_strcmp0(uri->scheme, "nfs") != 0) {
51
error_setg(errp, "URI scheme must be 'nfs'");
52
goto out;
53
}
54
diff --git a/block/sheepdog.c b/block/sheepdog.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/block/sheepdog.c
57
+++ b/block/sheepdog.c
58
@@ -XXX,XX +XXX,XX @@ static void sd_parse_uri(SheepdogConfig *cfg, const char *filename,
59
}
60
61
/* transport */
62
- if (!strcmp(uri->scheme, "sheepdog")) {
63
+ if (!g_strcmp0(uri->scheme, "sheepdog")) {
64
is_unix = false;
65
- } else if (!strcmp(uri->scheme, "sheepdog+tcp")) {
66
+ } else if (!g_strcmp0(uri->scheme, "sheepdog+tcp")) {
67
is_unix = false;
68
- } else if (!strcmp(uri->scheme, "sheepdog+unix")) {
69
+ } else if (!g_strcmp0(uri->scheme, "sheepdog+unix")) {
70
is_unix = true;
71
} else {
72
error_setg(&err, "URI scheme must be 'sheepdog', 'sheepdog+tcp',"
73
diff --git a/block/ssh.c b/block/ssh.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/block/ssh.c
76
+++ b/block/ssh.c
77
@@ -XXX,XX +XXX,XX @@ static int parse_uri(const char *filename, QDict *options, Error **errp)
78
return -EINVAL;
79
}
80
81
- if (strcmp(uri->scheme, "ssh") != 0) {
82
+ if (g_strcmp0(uri->scheme, "ssh") != 0) {
83
error_setg(errp, "URI scheme must be 'ssh'");
84
goto err;
85
}
86
--
44
--
87
1.8.3.1
45
2.19.1
88
46
89
47
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
The bs->exact_filename field may not be sufficient to store the full
3
Just like in qemu_opts_print_help(), print the object name as a caption
4
blkdebug node filename. In this case, we should not generate a filename
4
instead of on every single line, indent all options, add angle brackets
5
at all instead of an unusable one.
5
around types, and align the descriptions after 24 characters.
6
6
7
Cc: qemu-stable@nongnu.org
7
Also, indent every object name in the list of available objects.
8
Reported-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
8
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
Message-id: 20170613172006.19685-2-mreitz@redhat.com
10
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
11
Reviewed-by: Alberto Garcia <berto@igalia.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
13
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
---
12
---
15
block/blkdebug.c | 10 +++++++---
13
vl.c | 13 ++++++++++---
16
1 file changed, 7 insertions(+), 3 deletions(-)
14
1 file changed, 10 insertions(+), 3 deletions(-)
17
15
18
diff --git a/block/blkdebug.c b/block/blkdebug.c
16
diff --git a/vl.c b/vl.c
19
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
20
--- a/block/blkdebug.c
18
--- a/vl.c
21
+++ b/block/blkdebug.c
19
+++ b/vl.c
22
@@ -XXX,XX +XXX,XX @@ static void blkdebug_refresh_filename(BlockDriverState *bs, QDict *options)
20
@@ -XXX,XX +XXX,XX @@ static bool object_create_initial(const char *type, QemuOpts *opts)
23
}
21
list = object_class_get_list_sorted(TYPE_USER_CREATABLE, false);
24
22
for (l = list; l != NULL; l = l->next) {
25
if (!force_json && bs->file->bs->exact_filename[0]) {
23
ObjectClass *oc = OBJECT_CLASS(l->data);
26
- snprintf(bs->exact_filename, sizeof(bs->exact_filename),
24
- printf("%s\n", object_class_get_name(oc));
27
- "blkdebug:%s:%s", s->config_file ?: "",
25
+ printf(" %s\n", object_class_get_name(oc));
28
- bs->file->bs->exact_filename);
26
}
29
+ int ret = snprintf(bs->exact_filename, sizeof(bs->exact_filename),
27
g_slist_free(list);
30
+ "blkdebug:%s:%s", s->config_file ?: "",
28
exit(0);
31
+ bs->file->bs->exact_filename);
29
@@ -XXX,XX +XXX,XX @@ static bool object_create_initial(const char *type, QemuOpts *opts)
32
+ if (ret >= sizeof(bs->exact_filename)) {
30
}
33
+ /* An overflow makes the filename unusable, so do not report any */
31
34
+ bs->exact_filename[0] = 0;
32
str = g_string_new(NULL);
33
- g_string_append_printf(str, "%s.%s=%s", type,
34
- prop->name, prop->type);
35
+ g_string_append_printf(str, " %s=<%s>", prop->name, prop->type);
36
if (prop->description) {
37
+ if (str->len < 24) {
38
+ g_string_append_printf(str, "%*s", 24 - (int)str->len, "");
39
+ }
40
g_string_append_printf(str, " - %s", prop->description);
41
}
42
g_ptr_array_add(array, g_string_free(str, false));
43
}
44
g_ptr_array_sort(array, (GCompareFunc)qemu_pstrcmp0);
45
+ if (array->len > 0) {
46
+ printf("%s options:\n", type);
47
+ } else {
48
+ printf("There are no options for %s.\n", type);
35
+ }
49
+ }
36
}
50
for (i = 0; i < array->len; i++) {
37
51
printf("%s\n", (char *)array->pdata[i]);
38
opts = qdict_new();
52
}
39
--
53
--
40
1.8.3.1
54
2.19.1
41
55
42
56
diff view generated by jsdifflib
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
migration_incoming_state_destroy() uses qemu_fclose() on the vmstate
3
There is no good reason why there should be a newline in this
4
file. Make sure to call it inside an AioContext acquire/release region.
4
description, so remove it.
5
5
6
This fixes an 'qemu: qemu_mutex_unlock: Operation not permitted' abort
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
in loadvm.
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
8
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
9
This patch closes the vmstate file before ending the drained region.
10
Previously we closed the vmstate file after ending the drained region.
11
The order does not matter.
12
13
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
10
---
16
migration/savevm.c | 2 +-
11
vl.c | 2 +-
17
1 file changed, 1 insertion(+), 1 deletion(-)
12
1 file changed, 1 insertion(+), 1 deletion(-)
18
13
19
diff --git a/migration/savevm.c b/migration/savevm.c
14
diff --git a/vl.c b/vl.c
20
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
21
--- a/migration/savevm.c
16
--- a/vl.c
22
+++ b/migration/savevm.c
17
+++ b/vl.c
23
@@ -XXX,XX +XXX,XX @@ int load_snapshot(const char *name, Error **errp)
18
@@ -XXX,XX +XXX,XX @@ static QemuOptsList qemu_fw_cfg_opts = {
24
19
}, {
25
aio_context_acquire(aio_context);
20
.name = "file",
26
ret = qemu_loadvm_state(f);
21
.type = QEMU_OPT_STRING,
27
+ migration_incoming_state_destroy();
22
- .help = "Sets the name of the file from which\n"
28
aio_context_release(aio_context);
23
+ .help = "Sets the name of the file from which "
29
24
"the fw_cfg blob will be loaded",
30
bdrv_drain_all_end();
25
}, {
31
26
.name = "string",
32
- migration_incoming_state_destroy();
33
if (ret < 0) {
34
error_setg(errp, "Error %d while loading VM state", ret);
35
return ret;
36
--
27
--
37
1.8.3.1
28
2.19.1
38
29
39
30
diff view generated by jsdifflib
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
From: Leonid Bloch <lbloch@janustech.com>
2
2
3
Perform the savevm/loadvm test with both iothread on and off. This
3
If an expression is used to define DEFAULT_CLUSTER_SIZE, when compiled,
4
covers the recently found savevm/loadvm hang when iothread is enabled.
4
it will be embedded as a literal expression in the binary (as the
5
default value) because it is stringified to mark the size of the default
6
value. Now this is fixed by using a defined number to define this value.
5
7
6
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Signed-off-by: Leonid Bloch <lbloch@janustech.com>
9
Reviewed-by: Stefan Weil <sw@weilnetz.de>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
11
---
9
tests/qemu-iotests/068 | 23 ++++++++++++++---------
12
block/vdi.c | 4 ++--
10
tests/qemu-iotests/068.out | 11 ++++++++++-
13
1 file changed, 2 insertions(+), 2 deletions(-)
11
2 files changed, 24 insertions(+), 10 deletions(-)
12
14
13
diff --git a/tests/qemu-iotests/068 b/tests/qemu-iotests/068
15
diff --git a/block/vdi.c b/block/vdi.c
14
index XXXXXXX..XXXXXXX 100755
15
--- a/tests/qemu-iotests/068
16
+++ b/tests/qemu-iotests/068
17
@@ -XXX,XX +XXX,XX @@ _supported_os Linux
18
IMGOPTS="compat=1.1"
19
IMG_SIZE=128K
20
21
-echo
22
-echo "=== Saving and reloading a VM state to/from a qcow2 image ==="
23
-echo
24
-_make_test_img $IMG_SIZE
25
-
26
case "$QEMU_DEFAULT_MACHINE" in
27
s390-ccw-virtio)
28
platform_parm="-no-shutdown"
29
@@ -XXX,XX +XXX,XX @@ _qemu()
30
_filter_qemu | _filter_hmp
31
}
32
33
-# Give qemu some time to boot before saving the VM state
34
-bash -c 'sleep 1; echo -e "savevm 0\nquit"' | _qemu
35
-# Now try to continue from that VM state (this should just work)
36
-echo quit | _qemu -loadvm 0
37
+for extra_args in \
38
+ "" \
39
+ "-object iothread,id=iothread0 -set device.hba0.iothread=iothread0"; do
40
+ echo
41
+ echo "=== Saving and reloading a VM state to/from a qcow2 image ($extra_args) ==="
42
+ echo
43
+
44
+ _make_test_img $IMG_SIZE
45
+
46
+ # Give qemu some time to boot before saving the VM state
47
+ bash -c 'sleep 1; echo -e "savevm 0\nquit"' | _qemu $extra_args
48
+ # Now try to continue from that VM state (this should just work)
49
+ echo quit | _qemu $extra_args -loadvm 0
50
+done
51
52
# success, all done
53
echo "*** done"
54
diff --git a/tests/qemu-iotests/068.out b/tests/qemu-iotests/068.out
55
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
56
--- a/tests/qemu-iotests/068.out
17
--- a/block/vdi.c
57
+++ b/tests/qemu-iotests/068.out
18
+++ b/block/vdi.c
58
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
59
QA output created by 068
20
#define BLOCK_OPT_STATIC "static"
60
21
61
-=== Saving and reloading a VM state to/from a qcow2 image ===
22
#define SECTOR_SIZE 512
62
+=== Saving and reloading a VM state to/from a qcow2 image () ===
23
-#define DEFAULT_CLUSTER_SIZE (1 * MiB)
63
+
24
+#define DEFAULT_CLUSTER_SIZE S_1MiB
64
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072
25
65
+QEMU X.Y.Z monitor - type 'help' for more information
26
#if defined(CONFIG_VDI_DEBUG)
66
+(qemu) savevm 0
27
#define VDI_DEBUG 1
67
+(qemu) quit
28
@@ -XXX,XX +XXX,XX @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
68
+QEMU X.Y.Z monitor - type 'help' for more information
29
goto fail;
69
+(qemu) quit
30
} else if (header.block_size != DEFAULT_CLUSTER_SIZE) {
70
+
31
error_setg(errp, "unsupported VDI image (block size %" PRIu32
71
+=== Saving and reloading a VM state to/from a qcow2 image (-object iothread,id=iothread0 -set device.hba0.iothread=iothread0) ===
32
- " is not %" PRIu64 ")",
72
33
+ " is not %" PRIu32 ")",
73
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072
34
header.block_size, DEFAULT_CLUSTER_SIZE);
74
QEMU X.Y.Z monitor - type 'help' for more information
35
ret = -ENOTSUP;
36
goto fail;
75
--
37
--
76
1.8.3.1
38
2.19.1
77
39
78
40
diff view generated by jsdifflib
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
From: Leonid Bloch <lbloch@janustech.com>
2
2
3
Calling aio_poll() directly may have been fine previously, but this is
3
The lookup table for power-of-two sizes was added in commit 540b8492618eb
4
the future, man! The difference between an aio_poll() loop and
4
for the purpose of having convenient shortcuts for these sizes in cases
5
BDRV_POLL_WHILE() is that BDRV_POLL_WHILE() releases the AioContext
5
when the literal number has to be present at compile time, and
6
around aio_poll().
6
expressions as '(1 * KiB)' can not be used. One such case is the
7
stringification of sizes. Beyond that, it is convenient to use these
8
shortcuts for all power-of-two sizes, even if they don't have to be
9
literal numbers.
7
10
8
This allows the IOThread to run fd handlers or BHs to complete the
11
Despite its convenience, this table introduced 55 lines of "dumb" code,
9
request. Failure to release the AioContext causes deadlocks.
12
the purpose and origin of which are obscure without reading the message
13
of the commit which introduced it. This patch fixes that by adding a
14
comment to the code itself with a brief explanation for the reasoning
15
behind this table. This comment includes the short AWK script that
16
generated the table, so that anyone who's interested could make sure
17
that the values in it are correct (otherwise these values look as if
18
they were typed manually).
10
19
11
Using BDRV_POLL_WHILE() partially fixes a 'savevm' hang with -object
20
Signed-off-by: Leonid Bloch <lbloch@janustech.com>
12
iothread.
13
14
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
15
Reviewed-by: Eric Blake <eblake@redhat.com>
16
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
---
22
---
19
block/io.c | 4 +---
23
include/qemu/units.h | 18 ++++++++++++++++++
20
1 file changed, 1 insertion(+), 3 deletions(-)
24
1 file changed, 18 insertions(+)
21
25
22
diff --git a/block/io.c b/block/io.c
26
diff --git a/include/qemu/units.h b/include/qemu/units.h
23
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
24
--- a/block/io.c
28
--- a/include/qemu/units.h
25
+++ b/block/io.c
29
+++ b/include/qemu/units.h
26
@@ -XXX,XX +XXX,XX @@ bdrv_rw_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos,
30
@@ -XXX,XX +XXX,XX @@
27
Coroutine *co = qemu_coroutine_create(bdrv_co_rw_vmstate_entry, &data);
31
#define PiB (INT64_C(1) << 50)
28
32
#define EiB (INT64_C(1) << 60)
29
bdrv_coroutine_enter(bs, co);
33
30
- while (data.ret == -EINPROGRESS) {
34
+/*
31
- aio_poll(bdrv_get_aio_context(bs), true);
35
+ * The following lookup table is intended to be used when a literal string of
32
- }
36
+ * the number of bytes is required (for example if it needs to be stringified).
33
+ BDRV_POLL_WHILE(bs, data.ret == -EINPROGRESS);
37
+ * It can also be used for generic shortcuts of power-of-two sizes.
34
return data.ret;
38
+ * This table is generated using the AWK script below:
35
}
39
+ *
36
}
40
+ * BEGIN {
41
+ * suffix="KMGTPE";
42
+ * for(i=10; i<64; i++) {
43
+ * val=2**i;
44
+ * s=substr(suffix, int(i/10), 1);
45
+ * n=2**(i%10);
46
+ * pad=21-int(log(n)/log(10));
47
+ * printf("#define S_%d%siB %*d\n", n, s, pad, val);
48
+ * }
49
+ * }
50
+ */
51
+
52
#define S_1KiB 1024
53
#define S_2KiB 2048
54
#define S_4KiB 4096
37
--
55
--
38
1.8.3.1
56
2.19.1
39
57
40
58
diff view generated by jsdifflib
Deleted patch
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
3
---
4
block/qed.c | 32 ++++++++++++--------------------
5
1 file changed, 12 insertions(+), 20 deletions(-)
6
1
7
diff --git a/block/qed.c b/block/qed.c
8
index XXXXXXX..XXXXXXX 100644
9
--- a/block/qed.c
10
+++ b/block/qed.c
11
@@ -XXX,XX +XXX,XX @@ int qed_write_header_sync(BDRVQEDState *s)
12
* This function only updates known header fields in-place and does not affect
13
* extra data after the QED header.
14
*/
15
-static void qed_write_header(BDRVQEDState *s, BlockCompletionFunc cb,
16
- void *opaque)
17
+static int qed_write_header(BDRVQEDState *s)
18
{
19
/* We must write full sectors for O_DIRECT but cannot necessarily generate
20
* the data following the header if an unrecognized compat feature is
21
@@ -XXX,XX +XXX,XX @@ static void qed_write_header(BDRVQEDState *s, BlockCompletionFunc cb,
22
ret = 0;
23
out:
24
qemu_vfree(buf);
25
- cb(opaque, ret);
26
+ return ret;
27
}
28
29
static uint64_t qed_max_image_size(uint32_t cluster_size, uint32_t table_size)
30
@@ -XXX,XX +XXX,XX @@ static void qed_unplug_allocating_write_reqs(BDRVQEDState *s)
31
}
32
}
33
34
-static void qed_finish_clear_need_check(void *opaque, int ret)
35
-{
36
- /* Do nothing */
37
-}
38
-
39
-static void qed_flush_after_clear_need_check(void *opaque, int ret)
40
-{
41
- BDRVQEDState *s = opaque;
42
-
43
- bdrv_aio_flush(s->bs, qed_finish_clear_need_check, s);
44
-
45
- /* No need to wait until flush completes */
46
- qed_unplug_allocating_write_reqs(s);
47
-}
48
-
49
static void qed_clear_need_check(void *opaque, int ret)
50
{
51
BDRVQEDState *s = opaque;
52
@@ -XXX,XX +XXX,XX @@ static void qed_clear_need_check(void *opaque, int ret)
53
}
54
55
s->header.features &= ~QED_F_NEED_CHECK;
56
- qed_write_header(s, qed_flush_after_clear_need_check, s);
57
+ ret = qed_write_header(s);
58
+ (void) ret;
59
+
60
+ qed_unplug_allocating_write_reqs(s);
61
+
62
+ ret = bdrv_flush(s->bs);
63
+ (void) ret;
64
}
65
66
static void qed_need_check_timer_cb(void *opaque)
67
@@ -XXX,XX +XXX,XX @@ static void qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
68
{
69
BDRVQEDState *s = acb_to_s(acb);
70
BlockCompletionFunc *cb;
71
+ int ret;
72
73
/* Cancel timer when the first allocating request comes in */
74
if (QSIMPLEQ_EMPTY(&s->allocating_write_reqs)) {
75
@@ -XXX,XX +XXX,XX @@ static void qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
76
77
if (qed_should_set_need_check(s)) {
78
s->header.features |= QED_F_NEED_CHECK;
79
- qed_write_header(s, cb, acb);
80
+ ret = qed_write_header(s);
81
+ cb(acb, ret);
82
} else {
83
cb(acb, 0);
84
}
85
--
86
1.8.3.1
87
88
diff view generated by jsdifflib
Deleted patch
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
3
---
4
block/qed-table.c | 47 ++++++++++++-----------------------------------
5
block/qed.c | 12 +++++++-----
6
block/qed.h | 8 +++-----
7
3 files changed, 22 insertions(+), 45 deletions(-)
8
1
9
diff --git a/block/qed-table.c b/block/qed-table.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/block/qed-table.c
12
+++ b/block/qed-table.c
13
@@ -XXX,XX +XXX,XX @@ out:
14
* @index: Index of first element
15
* @n: Number of elements
16
* @flush: Whether or not to sync to disk
17
- * @cb: Completion function
18
- * @opaque: Argument for completion function
19
*/
20
-static void qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
21
- unsigned int index, unsigned int n, bool flush,
22
- BlockCompletionFunc *cb, void *opaque)
23
+static int qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
24
+ unsigned int index, unsigned int n, bool flush)
25
{
26
unsigned int sector_mask = BDRV_SECTOR_SIZE / sizeof(uint64_t) - 1;
27
unsigned int start, end, i;
28
@@ -XXX,XX +XXX,XX @@ static void qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
29
ret = 0;
30
out:
31
qemu_vfree(new_table);
32
- cb(opaque, ret);
33
-}
34
-
35
-/**
36
- * Propagate return value from async callback
37
- */
38
-static void qed_sync_cb(void *opaque, int ret)
39
-{
40
- *(int *)opaque = ret;
41
+ return ret;
42
}
43
44
int qed_read_l1_table_sync(BDRVQEDState *s)
45
@@ -XXX,XX +XXX,XX @@ int qed_read_l1_table_sync(BDRVQEDState *s)
46
return qed_read_table(s, s->header.l1_table_offset, s->l1_table);
47
}
48
49
-void qed_write_l1_table(BDRVQEDState *s, unsigned int index, unsigned int n,
50
- BlockCompletionFunc *cb, void *opaque)
51
+int qed_write_l1_table(BDRVQEDState *s, unsigned int index, unsigned int n)
52
{
53
BLKDBG_EVENT(s->bs->file, BLKDBG_L1_UPDATE);
54
- qed_write_table(s, s->header.l1_table_offset,
55
- s->l1_table, index, n, false, cb, opaque);
56
+ return qed_write_table(s, s->header.l1_table_offset,
57
+ s->l1_table, index, n, false);
58
}
59
60
int qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index,
61
unsigned int n)
62
{
63
- int ret = -EINPROGRESS;
64
-
65
- qed_write_l1_table(s, index, n, qed_sync_cb, &ret);
66
- BDRV_POLL_WHILE(s->bs, ret == -EINPROGRESS);
67
-
68
- return ret;
69
+ return qed_write_l1_table(s, index, n);
70
}
71
72
int qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset)
73
@@ -XXX,XX +XXX,XX @@ int qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request, uint64_t offset
74
return qed_read_l2_table(s, request, offset);
75
}
76
77
-void qed_write_l2_table(BDRVQEDState *s, QEDRequest *request,
78
- unsigned int index, unsigned int n, bool flush,
79
- BlockCompletionFunc *cb, void *opaque)
80
+int qed_write_l2_table(BDRVQEDState *s, QEDRequest *request,
81
+ unsigned int index, unsigned int n, bool flush)
82
{
83
BLKDBG_EVENT(s->bs->file, BLKDBG_L2_UPDATE);
84
- qed_write_table(s, request->l2_table->offset,
85
- request->l2_table->table, index, n, flush, cb, opaque);
86
+ return qed_write_table(s, request->l2_table->offset,
87
+ request->l2_table->table, index, n, flush);
88
}
89
90
int qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
91
unsigned int index, unsigned int n, bool flush)
92
{
93
- int ret = -EINPROGRESS;
94
-
95
- qed_write_l2_table(s, request, index, n, flush, qed_sync_cb, &ret);
96
- BDRV_POLL_WHILE(s->bs, ret == -EINPROGRESS);
97
-
98
- return ret;
99
+ return qed_write_l2_table(s, request, index, n, flush);
100
}
101
diff --git a/block/qed.c b/block/qed.c
102
index XXXXXXX..XXXXXXX 100644
103
--- a/block/qed.c
104
+++ b/block/qed.c
105
@@ -XXX,XX +XXX,XX @@ static void qed_aio_write_l1_update(void *opaque, int ret)
106
index = qed_l1_index(s, acb->cur_pos);
107
s->l1_table->offsets[index] = acb->request.l2_table->offset;
108
109
- qed_write_l1_table(s, index, 1, qed_commit_l2_update, acb);
110
+ ret = qed_write_l1_table(s, index, 1);
111
+ qed_commit_l2_update(acb, ret);
112
}
113
114
/**
115
@@ -XXX,XX +XXX,XX @@ static void qed_aio_write_l2_update(QEDAIOCB *acb, int ret, uint64_t offset)
116
117
if (need_alloc) {
118
/* Write out the whole new L2 table */
119
- qed_write_l2_table(s, &acb->request, 0, s->table_nelems, true,
120
- qed_aio_write_l1_update, acb);
121
+ ret = qed_write_l2_table(s, &acb->request, 0, s->table_nelems, true);
122
+ qed_aio_write_l1_update(acb, ret);
123
} else {
124
/* Write out only the updated part of the L2 table */
125
- qed_write_l2_table(s, &acb->request, index, acb->cur_nclusters, false,
126
- qed_aio_next_io_cb, acb);
127
+ ret = qed_write_l2_table(s, &acb->request, index, acb->cur_nclusters,
128
+ false);
129
+ qed_aio_next_io(acb, ret);
130
}
131
return;
132
133
diff --git a/block/qed.h b/block/qed.h
134
index XXXXXXX..XXXXXXX 100644
135
--- a/block/qed.h
136
+++ b/block/qed.h
137
@@ -XXX,XX +XXX,XX @@ void qed_commit_l2_cache_entry(L2TableCache *l2_cache, CachedL2Table *l2_table);
138
* Table I/O functions
139
*/
140
int qed_read_l1_table_sync(BDRVQEDState *s);
141
-void qed_write_l1_table(BDRVQEDState *s, unsigned int index, unsigned int n,
142
- BlockCompletionFunc *cb, void *opaque);
143
+int qed_write_l1_table(BDRVQEDState *s, unsigned int index, unsigned int n);
144
int qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index,
145
unsigned int n);
146
int qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
147
uint64_t offset);
148
int qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset);
149
-void qed_write_l2_table(BDRVQEDState *s, QEDRequest *request,
150
- unsigned int index, unsigned int n, bool flush,
151
- BlockCompletionFunc *cb, void *opaque);
152
+int qed_write_l2_table(BDRVQEDState *s, QEDRequest *request,
153
+ unsigned int index, unsigned int n, bool flush);
154
int qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
155
unsigned int index, unsigned int n, bool flush);
156
157
--
158
1.8.3.1
159
160
diff view generated by jsdifflib
Deleted patch
1
Don't recurse into qed_aio_next_io() and qed_aio_complete() here, but
2
just return an error code and let the caller handle it.
3
1
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
6
---
7
block/qed.c | 19 +++++++++----------
8
1 file changed, 9 insertions(+), 10 deletions(-)
9
10
diff --git a/block/qed.c b/block/qed.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/block/qed.c
13
+++ b/block/qed.c
14
@@ -XXX,XX +XXX,XX @@ static void qed_aio_complete(QEDAIOCB *acb, int ret)
15
/**
16
* Update L1 table with new L2 table offset and write it out
17
*/
18
-static void qed_aio_write_l1_update(void *opaque, int ret)
19
+static int qed_aio_write_l1_update(QEDAIOCB *acb)
20
{
21
- QEDAIOCB *acb = opaque;
22
BDRVQEDState *s = acb_to_s(acb);
23
CachedL2Table *l2_table = acb->request.l2_table;
24
uint64_t l2_offset = l2_table->offset;
25
- int index;
26
-
27
- if (ret) {
28
- qed_aio_complete(acb, ret);
29
- return;
30
- }
31
+ int index, ret;
32
33
index = qed_l1_index(s, acb->cur_pos);
34
s->l1_table->offsets[index] = l2_table->offset;
35
@@ -XXX,XX +XXX,XX @@ static void qed_aio_write_l1_update(void *opaque, int ret)
36
acb->request.l2_table = qed_find_l2_cache_entry(&s->l2_cache, l2_offset);
37
assert(acb->request.l2_table != NULL);
38
39
- qed_aio_next_io(acb, ret);
40
+ return ret;
41
}
42
43
44
@@ -XXX,XX +XXX,XX @@ static void qed_aio_write_l2_update(QEDAIOCB *acb, int ret, uint64_t offset)
45
if (need_alloc) {
46
/* Write out the whole new L2 table */
47
ret = qed_write_l2_table(s, &acb->request, 0, s->table_nelems, true);
48
- qed_aio_write_l1_update(acb, ret);
49
+ if (ret) {
50
+ goto err;
51
+ }
52
+ ret = qed_aio_write_l1_update(acb);
53
+ qed_aio_next_io(acb, ret);
54
+
55
} else {
56
/* Write out only the updated part of the L2 table */
57
ret = qed_write_l2_table(s, &acb->request, index, acb->cur_nclusters,
58
--
59
1.8.3.1
60
61
diff view generated by jsdifflib
Deleted patch
1
Now that we process a request in the same coroutine from beginning to
2
end and don't drop out of it any more, we can look like a proper
3
coroutine-based driver and simply call qed_aio_next_io() and get a
4
return value from it instead of spawning an additional coroutine that
5
reenters the parent when it's done.
6
1
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
---
10
block/qed.c | 101 +++++++++++++-----------------------------------------------
11
block/qed.h | 3 +-
12
2 files changed, 22 insertions(+), 82 deletions(-)
13
14
diff --git a/block/qed.c b/block/qed.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/block/qed.c
17
+++ b/block/qed.c
18
@@ -XXX,XX +XXX,XX @@
19
#include "qapi/qmp/qerror.h"
20
#include "sysemu/block-backend.h"
21
22
-static const AIOCBInfo qed_aiocb_info = {
23
- .aiocb_size = sizeof(QEDAIOCB),
24
-};
25
-
26
static int bdrv_qed_probe(const uint8_t *buf, int buf_size,
27
const char *filename)
28
{
29
@@ -XXX,XX +XXX,XX @@ static CachedL2Table *qed_new_l2_table(BDRVQEDState *s)
30
return l2_table;
31
}
32
33
-static void qed_aio_next_io(QEDAIOCB *acb);
34
-
35
-static void qed_aio_start_io(QEDAIOCB *acb)
36
-{
37
- qed_aio_next_io(acb);
38
-}
39
-
40
static void qed_plug_allocating_write_reqs(BDRVQEDState *s)
41
{
42
assert(!s->allocating_write_reqs_plugged);
43
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn bdrv_qed_co_get_block_status(BlockDriverState *bs,
44
45
static BDRVQEDState *acb_to_s(QEDAIOCB *acb)
46
{
47
- return acb->common.bs->opaque;
48
+ return acb->bs->opaque;
49
}
50
51
/**
52
@@ -XXX,XX +XXX,XX @@ static void qed_update_l2_table(BDRVQEDState *s, QEDTable *table, int index,
53
}
54
}
55
56
-static void qed_aio_complete_bh(void *opaque)
57
-{
58
- QEDAIOCB *acb = opaque;
59
- BDRVQEDState *s = acb_to_s(acb);
60
- BlockCompletionFunc *cb = acb->common.cb;
61
- void *user_opaque = acb->common.opaque;
62
- int ret = acb->bh_ret;
63
-
64
- qemu_aio_unref(acb);
65
-
66
- /* Invoke callback */
67
- qed_acquire(s);
68
- cb(user_opaque, ret);
69
- qed_release(s);
70
-}
71
-
72
-static void qed_aio_complete(QEDAIOCB *acb, int ret)
73
+static void qed_aio_complete(QEDAIOCB *acb)
74
{
75
BDRVQEDState *s = acb_to_s(acb);
76
77
- trace_qed_aio_complete(s, acb, ret);
78
-
79
/* Free resources */
80
qemu_iovec_destroy(&acb->cur_qiov);
81
qed_unref_l2_cache_entry(acb->request.l2_table);
82
@@ -XXX,XX +XXX,XX @@ static void qed_aio_complete(QEDAIOCB *acb, int ret)
83
acb->qiov->iov[0].iov_base = NULL;
84
}
85
86
- /* Arrange for a bh to invoke the completion function */
87
- acb->bh_ret = ret;
88
- aio_bh_schedule_oneshot(bdrv_get_aio_context(acb->common.bs),
89
- qed_aio_complete_bh, acb);
90
-
91
/* Start next allocating write request waiting behind this one. Note that
92
* requests enqueue themselves when they first hit an unallocated cluster
93
* but they wait until the entire request is finished before waking up the
94
@@ -XXX,XX +XXX,XX @@ static int qed_aio_write_inplace(QEDAIOCB *acb, uint64_t offset, size_t len)
95
struct iovec *iov = acb->qiov->iov;
96
97
if (!iov->iov_base) {
98
- iov->iov_base = qemu_try_blockalign(acb->common.bs, iov->iov_len);
99
+ iov->iov_base = qemu_try_blockalign(acb->bs, iov->iov_len);
100
if (iov->iov_base == NULL) {
101
return -ENOMEM;
102
}
103
@@ -XXX,XX +XXX,XX @@ static int qed_aio_read_data(void *opaque, int ret, uint64_t offset, size_t len)
104
{
105
QEDAIOCB *acb = opaque;
106
BDRVQEDState *s = acb_to_s(acb);
107
- BlockDriverState *bs = acb->common.bs;
108
+ BlockDriverState *bs = acb->bs;
109
110
/* Adjust offset into cluster */
111
offset += qed_offset_into_cluster(s, acb->cur_pos);
112
@@ -XXX,XX +XXX,XX @@ static int qed_aio_read_data(void *opaque, int ret, uint64_t offset, size_t len)
113
/**
114
* Begin next I/O or complete the request
115
*/
116
-static void qed_aio_next_io(QEDAIOCB *acb)
117
+static int qed_aio_next_io(QEDAIOCB *acb)
118
{
119
BDRVQEDState *s = acb_to_s(acb);
120
uint64_t offset;
121
@@ -XXX,XX +XXX,XX @@ static void qed_aio_next_io(QEDAIOCB *acb)
122
123
/* Complete request */
124
if (acb->cur_pos >= acb->end_pos) {
125
- qed_aio_complete(acb, 0);
126
- return;
127
+ ret = 0;
128
+ break;
129
}
130
131
/* Find next cluster and start I/O */
132
len = acb->end_pos - acb->cur_pos;
133
ret = qed_find_cluster(s, &acb->request, acb->cur_pos, &len, &offset);
134
if (ret < 0) {
135
- qed_aio_complete(acb, ret);
136
- return;
137
+ break;
138
}
139
140
if (acb->flags & QED_AIOCB_WRITE) {
141
@@ -XXX,XX +XXX,XX @@ static void qed_aio_next_io(QEDAIOCB *acb)
142
}
143
144
if (ret < 0 && ret != -EAGAIN) {
145
- qed_aio_complete(acb, ret);
146
- return;
147
+ break;
148
}
149
}
150
-}
151
152
-typedef struct QEDRequestCo {
153
- Coroutine *co;
154
- bool done;
155
- int ret;
156
-} QEDRequestCo;
157
-
158
-static void qed_co_request_cb(void *opaque, int ret)
159
-{
160
- QEDRequestCo *co = opaque;
161
-
162
- co->done = true;
163
- co->ret = ret;
164
- qemu_coroutine_enter_if_inactive(co->co);
165
+ trace_qed_aio_complete(s, acb, ret);
166
+ qed_aio_complete(acb);
167
+ return ret;
168
}
169
170
static int coroutine_fn qed_co_request(BlockDriverState *bs, int64_t sector_num,
171
QEMUIOVector *qiov, int nb_sectors,
172
int flags)
173
{
174
- QEDRequestCo co = {
175
- .co = qemu_coroutine_self(),
176
- .done = false,
177
+ QEDAIOCB acb = {
178
+ .bs = bs,
179
+ .cur_pos = (uint64_t) sector_num * BDRV_SECTOR_SIZE,
180
+ .end_pos = (sector_num + nb_sectors) * BDRV_SECTOR_SIZE,
181
+ .qiov = qiov,
182
+ .flags = flags,
183
};
184
- QEDAIOCB *acb = qemu_aio_get(&qed_aiocb_info, bs, qed_co_request_cb, &co);
185
-
186
- trace_qed_aio_setup(bs->opaque, acb, sector_num, nb_sectors, &co, flags);
187
+ qemu_iovec_init(&acb.cur_qiov, qiov->niov);
188
189
- acb->flags = flags;
190
- acb->qiov = qiov;
191
- acb->qiov_offset = 0;
192
- acb->cur_pos = (uint64_t)sector_num * BDRV_SECTOR_SIZE;
193
- acb->end_pos = acb->cur_pos + nb_sectors * BDRV_SECTOR_SIZE;
194
- acb->backing_qiov = NULL;
195
- acb->request.l2_table = NULL;
196
- qemu_iovec_init(&acb->cur_qiov, qiov->niov);
197
+ trace_qed_aio_setup(bs->opaque, &acb, sector_num, nb_sectors, NULL, flags);
198
199
/* Start request */
200
- qed_aio_start_io(acb);
201
-
202
- if (!co.done) {
203
- qemu_coroutine_yield();
204
- }
205
-
206
- return co.ret;
207
+ return qed_aio_next_io(&acb);
208
}
209
210
static int coroutine_fn bdrv_qed_co_readv(BlockDriverState *bs,
211
diff --git a/block/qed.h b/block/qed.h
212
index XXXXXXX..XXXXXXX 100644
213
--- a/block/qed.h
214
+++ b/block/qed.h
215
@@ -XXX,XX +XXX,XX @@ enum {
216
};
217
218
typedef struct QEDAIOCB {
219
- BlockAIOCB common;
220
- int bh_ret; /* final return status for completion bh */
221
+ BlockDriverState *bs;
222
QSIMPLEQ_ENTRY(QEDAIOCB) next; /* next request */
223
int flags; /* QED_AIOCB_* bits ORed together */
224
uint64_t end_pos; /* request end on block device, in bytes */
225
--
226
1.8.3.1
227
228
diff view generated by jsdifflib
Deleted patch
1
Now that we stay in coroutine context for the whole request when doing
2
reads or writes, we can add coroutine_fn annotations to many functions
3
that can do I/O or yield directly.
4
1
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
7
---
8
block/qed-cluster.c | 5 +++--
9
block/qed.c | 44 ++++++++++++++++++++++++--------------------
10
block/qed.h | 5 +++--
11
3 files changed, 30 insertions(+), 24 deletions(-)
12
13
diff --git a/block/qed-cluster.c b/block/qed-cluster.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/block/qed-cluster.c
16
+++ b/block/qed-cluster.c
17
@@ -XXX,XX +XXX,XX @@ static unsigned int qed_count_contiguous_clusters(BDRVQEDState *s,
18
* On failure QED_CLUSTER_L2 or QED_CLUSTER_L1 is returned for missing L2 or L1
19
* table offset, respectively. len is number of contiguous unallocated bytes.
20
*/
21
-int qed_find_cluster(BDRVQEDState *s, QEDRequest *request, uint64_t pos,
22
- size_t *len, uint64_t *img_offset)
23
+int coroutine_fn qed_find_cluster(BDRVQEDState *s, QEDRequest *request,
24
+ uint64_t pos, size_t *len,
25
+ uint64_t *img_offset)
26
{
27
uint64_t l2_offset;
28
uint64_t offset = 0;
29
diff --git a/block/qed.c b/block/qed.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/block/qed.c
32
+++ b/block/qed.c
33
@@ -XXX,XX +XXX,XX @@ int qed_write_header_sync(BDRVQEDState *s)
34
* This function only updates known header fields in-place and does not affect
35
* extra data after the QED header.
36
*/
37
-static int qed_write_header(BDRVQEDState *s)
38
+static int coroutine_fn qed_write_header(BDRVQEDState *s)
39
{
40
/* We must write full sectors for O_DIRECT but cannot necessarily generate
41
* the data following the header if an unrecognized compat feature is
42
@@ -XXX,XX +XXX,XX @@ static void qed_unplug_allocating_write_reqs(BDRVQEDState *s)
43
qemu_co_enter_next(&s->allocating_write_reqs);
44
}
45
46
-static void qed_need_check_timer_entry(void *opaque)
47
+static void coroutine_fn qed_need_check_timer_entry(void *opaque)
48
{
49
BDRVQEDState *s = opaque;
50
int ret;
51
@@ -XXX,XX +XXX,XX @@ static BDRVQEDState *acb_to_s(QEDAIOCB *acb)
52
* This function reads qiov->size bytes starting at pos from the backing file.
53
* If there is no backing file then zeroes are read.
54
*/
55
-static int qed_read_backing_file(BDRVQEDState *s, uint64_t pos,
56
- QEMUIOVector *qiov,
57
- QEMUIOVector **backing_qiov)
58
+static int coroutine_fn qed_read_backing_file(BDRVQEDState *s, uint64_t pos,
59
+ QEMUIOVector *qiov,
60
+ QEMUIOVector **backing_qiov)
61
{
62
uint64_t backing_length = 0;
63
size_t size;
64
@@ -XXX,XX +XXX,XX @@ static int qed_read_backing_file(BDRVQEDState *s, uint64_t pos,
65
* @len: Number of bytes
66
* @offset: Byte offset in image file
67
*/
68
-static int qed_copy_from_backing_file(BDRVQEDState *s, uint64_t pos,
69
- uint64_t len, uint64_t offset)
70
+static int coroutine_fn qed_copy_from_backing_file(BDRVQEDState *s,
71
+ uint64_t pos, uint64_t len,
72
+ uint64_t offset)
73
{
74
QEMUIOVector qiov;
75
QEMUIOVector *backing_qiov = NULL;
76
@@ -XXX,XX +XXX,XX @@ out:
77
* The cluster offset may be an allocated byte offset in the image file, the
78
* zero cluster marker, or the unallocated cluster marker.
79
*/
80
-static void qed_update_l2_table(BDRVQEDState *s, QEDTable *table, int index,
81
- unsigned int n, uint64_t cluster)
82
+static void coroutine_fn qed_update_l2_table(BDRVQEDState *s, QEDTable *table,
83
+ int index, unsigned int n,
84
+ uint64_t cluster)
85
{
86
int i;
87
for (i = index; i < index + n; i++) {
88
@@ -XXX,XX +XXX,XX @@ static void qed_update_l2_table(BDRVQEDState *s, QEDTable *table, int index,
89
}
90
}
91
92
-static void qed_aio_complete(QEDAIOCB *acb)
93
+static void coroutine_fn qed_aio_complete(QEDAIOCB *acb)
94
{
95
BDRVQEDState *s = acb_to_s(acb);
96
97
@@ -XXX,XX +XXX,XX @@ static void qed_aio_complete(QEDAIOCB *acb)
98
/**
99
* Update L1 table with new L2 table offset and write it out
100
*/
101
-static int qed_aio_write_l1_update(QEDAIOCB *acb)
102
+static int coroutine_fn qed_aio_write_l1_update(QEDAIOCB *acb)
103
{
104
BDRVQEDState *s = acb_to_s(acb);
105
CachedL2Table *l2_table = acb->request.l2_table;
106
@@ -XXX,XX +XXX,XX @@ static int qed_aio_write_l1_update(QEDAIOCB *acb)
107
/**
108
* Update L2 table with new cluster offsets and write them out
109
*/
110
-static int qed_aio_write_l2_update(QEDAIOCB *acb, uint64_t offset)
111
+static int coroutine_fn qed_aio_write_l2_update(QEDAIOCB *acb, uint64_t offset)
112
{
113
BDRVQEDState *s = acb_to_s(acb);
114
bool need_alloc = acb->find_cluster_ret == QED_CLUSTER_L1;
115
@@ -XXX,XX +XXX,XX @@ static int qed_aio_write_l2_update(QEDAIOCB *acb, uint64_t offset)
116
/**
117
* Write data to the image file
118
*/
119
-static int qed_aio_write_main(QEDAIOCB *acb)
120
+static int coroutine_fn qed_aio_write_main(QEDAIOCB *acb)
121
{
122
BDRVQEDState *s = acb_to_s(acb);
123
uint64_t offset = acb->cur_cluster +
124
@@ -XXX,XX +XXX,XX @@ static int qed_aio_write_main(QEDAIOCB *acb)
125
/**
126
* Populate untouched regions of new data cluster
127
*/
128
-static int qed_aio_write_cow(QEDAIOCB *acb)
129
+static int coroutine_fn qed_aio_write_cow(QEDAIOCB *acb)
130
{
131
BDRVQEDState *s = acb_to_s(acb);
132
uint64_t start, len, offset;
133
@@ -XXX,XX +XXX,XX @@ static bool qed_should_set_need_check(BDRVQEDState *s)
134
*
135
* This path is taken when writing to previously unallocated clusters.
136
*/
137
-static int qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
138
+static int coroutine_fn qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
139
{
140
BDRVQEDState *s = acb_to_s(acb);
141
int ret;
142
@@ -XXX,XX +XXX,XX @@ static int qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
143
*
144
* This path is taken when writing to already allocated clusters.
145
*/
146
-static int qed_aio_write_inplace(QEDAIOCB *acb, uint64_t offset, size_t len)
147
+static int coroutine_fn qed_aio_write_inplace(QEDAIOCB *acb, uint64_t offset,
148
+ size_t len)
149
{
150
/* Allocate buffer for zero writes */
151
if (acb->flags & QED_AIOCB_ZERO) {
152
@@ -XXX,XX +XXX,XX @@ static int qed_aio_write_inplace(QEDAIOCB *acb, uint64_t offset, size_t len)
153
* @offset: Cluster offset in bytes
154
* @len: Length in bytes
155
*/
156
-static int qed_aio_write_data(void *opaque, int ret,
157
- uint64_t offset, size_t len)
158
+static int coroutine_fn qed_aio_write_data(void *opaque, int ret,
159
+ uint64_t offset, size_t len)
160
{
161
QEDAIOCB *acb = opaque;
162
163
@@ -XXX,XX +XXX,XX @@ static int qed_aio_write_data(void *opaque, int ret,
164
* @offset: Cluster offset in bytes
165
* @len: Length in bytes
166
*/
167
-static int qed_aio_read_data(void *opaque, int ret, uint64_t offset, size_t len)
168
+static int coroutine_fn qed_aio_read_data(void *opaque, int ret,
169
+ uint64_t offset, size_t len)
170
{
171
QEDAIOCB *acb = opaque;
172
BDRVQEDState *s = acb_to_s(acb);
173
@@ -XXX,XX +XXX,XX @@ static int qed_aio_read_data(void *opaque, int ret, uint64_t offset, size_t len)
174
/**
175
* Begin next I/O or complete the request
176
*/
177
-static int qed_aio_next_io(QEDAIOCB *acb)
178
+static int coroutine_fn qed_aio_next_io(QEDAIOCB *acb)
179
{
180
BDRVQEDState *s = acb_to_s(acb);
181
uint64_t offset;
182
diff --git a/block/qed.h b/block/qed.h
183
index XXXXXXX..XXXXXXX 100644
184
--- a/block/qed.h
185
+++ b/block/qed.h
186
@@ -XXX,XX +XXX,XX @@ int qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
187
/**
188
* Cluster functions
189
*/
190
-int qed_find_cluster(BDRVQEDState *s, QEDRequest *request, uint64_t pos,
191
- size_t *len, uint64_t *img_offset);
192
+int coroutine_fn qed_find_cluster(BDRVQEDState *s, QEDRequest *request,
193
+ uint64_t pos, size_t *len,
194
+ uint64_t *img_offset);
195
196
/**
197
* Consistency check
198
--
199
1.8.3.1
200
201
diff view generated by jsdifflib