1
The following changes since commit b2f7a038bb4c4fc5ce6b8486e8513dfd97665e2a:
1
The following changes since commit ad88e4252f09c2956b99c90de39e95bab2e8e7af:
2
2
3
Merge remote-tracking branch 'remotes/rth/tags/pull-softfloat-20181104' into staging (2018-11-05 10:32:49 +0000)
3
Merge remote-tracking branch 'remotes/amarkovic/tags/mips-queue-jun-1-2019' into staging (2019-06-03 10:25:12 +0100)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
git://repo.or.cz/qemu/kevin.git tags/for-upstream
7
git://repo.or.cz/qemu/kevin.git tags/for-upstream
8
8
9
for you to fetch changes up to 1240ac558d348f6c7a5752b1a57c1da58e4efe3e:
9
for you to fetch changes up to 9593db8ccd27800ce4a17f1d5b735b9130c541a2:
10
10
11
include: Add a comment to explain the origin of sizes' lookup table (2018-11-05 15:29:59 +0100)
11
iotests: Fix duplicated diff output on failure (2019-06-03 16:33:20 +0200)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block layer patches:
14
Block layer patches:
15
15
16
- auto-read-only option to fix commit job when used with -blockdev
16
- block: AioContext management, part 2
17
- Fix help text related qemu-iotests failure (by improving the help text
17
- Avoid recursive block_status call (i.e. lseek() calls) if possible
18
and updating the reference output)
18
- linux-aio: Drop unused BlockAIOCB submission method
19
- quorum: Add missing checks when adding/removing child nodes
19
- nvme: add Get/Set Feature Timestamp support
20
- Don't take address of fields in packed structs
20
- Fix crash on commit job start with active I/O on base node
21
- vvfat: Fix crash when reporting error about too many files in directory
21
- Fix crash in bdrv_drained_end
22
- Fix integer overflow in qcow2 discard
22
23
23
----------------------------------------------------------------
24
----------------------------------------------------------------
24
Alberto Garcia (7):
25
John Snow (1):
25
block: replace "discard" literal with BDRV_OPT_DISCARD macro
26
blockdev: fix missed target unref for drive-backup
26
qcow2: Get the request alignment for encrypted images from QCryptoBlock
27
quorum: Remove quorum_err()
28
quorum: Return an error if the blkverify mode has invalid settings
29
iotest: Test the blkverify mode of the Quorum driver
30
quorum: Forbid adding children in blkverify mode
31
iotest: Test x-blockdev-change on a Quorum
32
27
33
Cleber Rosa (1):
28
Julia Suvorova (1):
34
iotests: make 083 specific to raw
29
block/linux-aio: Drop unused BlockAIOCB submission method
35
30
36
Daniel P. Berrangé (1):
31
Kenneth Heitke (1):
37
crypto: initialize sector size even when opening with no IO flag
32
nvme: add Get/Set Feature Timestamp support
38
33
39
Kevin Wolf (12):
34
Kevin Wolf (19):
40
vpc: Don't leak opts in vpc_open()
35
block: Drain source node in bdrv_replace_node()
41
block: Update flags in bdrv_set_read_only()
36
iotests: Test commit job start with concurrent I/O
42
block: Add auto-read-only option
37
test-block-iothread: Check filter node in test_propagate_mirror
43
rbd: Close image in qemu_rbd_open() error path
38
nbd-server: Call blk_set_allow_aio_context_change()
44
block: Require auto-read-only for existing fallbacks
39
block: Add Error to blk_set_aio_context()
45
nbd: Support auto-read-only option
40
block: Add BlockBackend.ctx
46
file-posix: Support auto-read-only option
41
block: Add qdev_prop_drive_iothread property type
47
curl: Support auto-read-only option
42
scsi-disk: Use qdev_prop_drive_iothread
48
gluster: Support auto-read-only option
43
block: Adjust AioContexts when attaching nodes
49
iscsi: Support auto-read-only option
44
test-block-iothread: Test adding parent to iothread node
50
block: Make auto-read-only=on default for -drive
45
test-block-iothread: BlockBackend AioContext across root node change
51
qemu-iotests: Test auto-read-only with -drive and -blockdev
46
block: Move node without parents to main AioContext
47
blockdev: Use bdrv_try_set_aio_context() for monitor commands
48
block: Remove wrong bdrv_set_aio_context() calls
49
virtio-scsi-test: Test attaching new overlay with iothreads
50
iotests: Attach new devices to node in non-default iothread
51
test-bdrv-drain: Use bdrv_try_set_aio_context()
52
block: Remove bdrv_set_aio_context()
53
iotests: Fix duplicated diff output on failure
52
54
53
Leonid Bloch (2):
55
Max Reitz (2):
54
vdi: Use a literal number of bytes for DEFAULT_CLUSTER_SIZE
56
block/io: Delay decrementing the quiesce_counter
55
include: Add a comment to explain the origin of sizes' lookup table
57
iotests: Test cancelling a job and closing the VM
56
58
57
Li Qiang (1):
59
Vladimir Sementsov-Ogievskiy (4):
58
block: change some function return type to bool
60
tests/perf: Test lseek influence on qcow2 block-status
61
block: avoid recursive block_status call if possible
62
block/qcow2-refcount: add trace-point to qcow2_process_discards
63
block/io: bdrv_pdiscard: support int64_t bytes parameter
59
64
60
Max Reitz (5):
65
docs/devel/multiple-iothreads.txt | 4 +-
61
option: Make option help nicer to read
66
block/qcow2.h | 4 +
62
chardev: Indent list of chardevs
67
hw/block/nvme.h | 2 +
63
qdev-monitor: Make device options help nicer
68
include/block/block.h | 21 ++---
64
object: Make option help nicer to read
69
include/block/block_int.h | 1 +
65
fw_cfg: Drop newline in @file description
70
include/block/nvme.h | 2 +
71
include/block/raw-aio.h | 3 -
72
include/hw/block/block.h | 7 +-
73
include/hw/qdev-properties.h | 3 +
74
include/hw/scsi/scsi.h | 1 +
75
include/sysemu/block-backend.h | 5 +-
76
tests/libqtest.h | 11 +++
77
block.c | 79 ++++++++++++-----
78
block/backup.c | 3 +-
79
block/block-backend.c | 47 ++++++----
80
block/commit.c | 13 +--
81
block/crypto.c | 3 +-
82
block/io.c | 28 +++---
83
block/linux-aio.c | 72 +++------------
84
block/mirror.c | 4 +-
85
block/parallels.c | 3 +-
86
block/qcow.c | 3 +-
87
block/qcow2-refcount.c | 39 ++++++++-
88
block/qcow2.c | 17 +++-
89
block/qed.c | 3 +-
90
block/sheepdog.c | 3 +-
91
block/vdi.c | 3 +-
92
block/vhdx.c | 3 +-
93
block/vmdk.c | 3 +-
94
block/vpc.c | 3 +-
95
blockdev.c | 61 +++++++------
96
blockjob.c | 12 ++-
97
hmp.c | 3 +-
98
hw/block/dataplane/virtio-blk.c | 12 ++-
99
hw/block/dataplane/xen-block.c | 6 +-
100
hw/block/fdc.c | 2 +-
101
hw/block/nvme.c | 106 +++++++++++++++++++++-
102
hw/block/xen-block.c | 2 +-
103
hw/core/qdev-properties-system.c | 41 ++++++++-
104
hw/ide/qdev.c | 2 +-
105
hw/scsi/scsi-disk.c | 24 +++--
106
hw/scsi/virtio-scsi.c | 25 +++---
107
migration/block.c | 3 +-
108
nbd/server.c | 6 +-
109
qemu-img.c | 6 +-
110
tests/libqtest.c | 19 ++++
111
tests/test-bdrv-drain.c | 50 ++++++-----
112
tests/test-bdrv-graph-mod.c | 5 +-
113
tests/test-block-backend.c | 6 +-
114
tests/test-block-iothread.c | 104 ++++++++++++++++++----
115
tests/test-blockjob.c | 2 +-
116
tests/test-throttle.c | 6 +-
117
tests/virtio-scsi-test.c | 62 +++++++++++++
118
block/trace-events | 3 +
119
hw/block/trace-events | 2 +
120
tests/perf/block/qcow2/convert-blockstatus | 71 +++++++++++++++
121
tests/qemu-iotests/051 | 24 +++++
122
tests/qemu-iotests/051.out | 3 +
123
tests/qemu-iotests/051.pc.out | 27 ++++++
124
tests/qemu-iotests/102 | 2 +-
125
tests/qemu-iotests/102.out | 3 +-
126
tests/qemu-iotests/141.out | 2 +-
127
tests/qemu-iotests/144.out | 2 +-
128
tests/qemu-iotests/240 | 21 +++++
129
tests/qemu-iotests/240.out | 15 +++-
130
tests/qemu-iotests/255 | 135 +++++++++++++++++++++++++++++
131
tests/qemu-iotests/255.out | 40 +++++++++
132
tests/qemu-iotests/check | 1 -
133
tests/qemu-iotests/group | 1 +
134
tests/qemu-iotests/iotests.py | 10 ++-
135
70 files changed, 1048 insertions(+), 272 deletions(-)
136
create mode 100755 tests/perf/block/qcow2/convert-blockstatus
137
create mode 100755 tests/qemu-iotests/255
138
create mode 100644 tests/qemu-iotests/255.out
66
139
67
Peter Maydell (5):
68
block/qcow2: Don't take address of fields in packed structs
69
block/qcow: Don't take address of fields in packed structs
70
block/qcow2-bitmap: Don't take address of fields in packed structs
71
block/vhdx: Don't take address of fields in packed structs
72
block/vdi: Don't take address of fields in packed structs
73
74
Stefan Weil (1):
75
qemu-io-cmds: Fix two format strings
76
77
Thomas Huth (1):
78
block/vvfat: Fix crash when reporting error about too many files in directory
79
80
qapi/block-core.json | 7 +
81
block/vhdx.h | 12 +-
82
include/block/block.h | 5 +-
83
include/qemu/option.h | 2 +-
84
include/qemu/units.h | 18 +
85
include/sysemu/block-backend.h | 6 +-
86
block.c | 60 ++-
87
block/block-backend.c | 8 +-
88
block/bochs.c | 17 +-
89
block/cloop.c | 16 +-
90
block/curl.c | 8 +-
91
block/dmg.c | 16 +-
92
block/file-posix.c | 19 +-
93
block/gluster.c | 12 +-
94
block/iscsi.c | 8 +-
95
block/nbd-client.c | 10 +-
96
block/qcow.c | 18 +-
97
block/qcow2-bitmap.c | 24 +-
98
block/qcow2.c | 66 +--
99
block/quorum.c | 45 +-
100
block/rbd.c | 14 +-
101
block/vdi.c | 68 +--
102
block/vhdx-endian.c | 118 ++---
103
block/vhdx-log.c | 4 +-
104
block/vhdx.c | 18 +-
105
block/vpc.c | 2 +
106
block/vvfat.c | 15 +-
107
blockdev.c | 3 +-
108
chardev/char.c | 2 +-
109
crypto/block-qcow.c | 2 +
110
qdev-monitor.c | 13 +-
111
qemu-img.c | 4 +-
112
qemu-io-cmds.c | 4 +-
113
util/qemu-option.c | 32 +-
114
vl.c | 15 +-
115
tests/qemu-iotests/081 | 116 +++++
116
tests/qemu-iotests/081.out | 70 +++
117
tests/qemu-iotests/082.out | 956 ++++++++++++++++++++---------------------
118
tests/qemu-iotests/083 | 2 +-
119
tests/qemu-iotests/232 | 147 +++++++
120
tests/qemu-iotests/232.out | 59 +++
121
tests/qemu-iotests/group | 1 +
122
42 files changed, 1266 insertions(+), 776 deletions(-)
123
create mode 100755 tests/qemu-iotests/232
124
create mode 100644 tests/qemu-iotests/232.out
125
diff view generated by jsdifflib
Deleted patch
1
From: Thomas Huth <thuth@redhat.com>
2
1
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>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
---
18
block/vvfat.c | 4 ++--
19
1 file changed, 2 insertions(+), 2 deletions(-)
20
21
diff --git a/block/vvfat.c b/block/vvfat.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/block/vvfat.c
24
+++ b/block/vvfat.c
25
@@ -XXX,XX +XXX,XX @@ static int init_directories(BDRVVVFATState* s,
26
mapping = array_get(&(s->mapping), i);
27
28
if (mapping->mode & MODE_DIRECTORY) {
29
+ char *path = mapping->path;
30
mapping->begin = cluster;
31
if(read_directory(s, i)) {
32
- error_setg(errp, "Could not read directory %s",
33
- mapping->path);
34
+ error_setg(errp, "Could not read directory %s", path);
35
return -1;
36
}
37
mapping = array_get(&(s->mapping), i);
38
--
39
2.19.1
40
41
diff view generated by jsdifflib
1
To fully change the read-only state of a node, we must not only change
1
Instead of just asserting that no requests are in flight in
2
bs->read_only, but also update bs->open_flags.
2
bdrv_replace_node(), which is a requirement that most callers ignore, we
3
can just drain the source node right there. This fixes at least starting
4
a commit job while I/O is active on the backing chain, but probably
5
other callers, too.
3
6
7
Having requests in flight on the target node isn't a problem because the
8
target just gets new parents, but the call path of running requests
9
isn't modified. So we can just drop this assertion without a replacement.
10
11
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1711643
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Eric Blake <eblake@redhat.com>
13
Reviewed-by: Max Reitz <mreitz@redhat.com>
6
Reviewed-by: Alberto Garcia <berto@igalia.com>
7
---
14
---
8
block.c | 7 +++++++
15
block.c | 7 ++++---
9
1 file changed, 7 insertions(+)
16
1 file changed, 4 insertions(+), 3 deletions(-)
10
17
11
diff --git a/block.c b/block.c
18
diff --git a/block.c b/block.c
12
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
13
--- a/block.c
20
--- a/block.c
14
+++ b/block.c
21
+++ b/block.c
15
@@ -XXX,XX +XXX,XX @@ int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
22
@@ -XXX,XX +XXX,XX @@ void bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
16
}
23
uint64_t perm = 0, shared = BLK_PERM_ALL;
17
24
int ret;
18
bs->read_only = read_only;
25
26
- assert(!atomic_read(&from->in_flight));
27
- assert(!atomic_read(&to->in_flight));
28
-
29
/* Make sure that @from doesn't go away until we have successfully attached
30
* all of its parents to @to. */
31
bdrv_ref(from);
32
33
+ assert(qemu_get_current_aio_context() == qemu_get_aio_context());
34
+ bdrv_drained_begin(from);
19
+
35
+
20
+ if (read_only) {
36
/* Put all parents into @list and calculate their cumulative permissions */
21
+ bs->open_flags &= ~BDRV_O_RDWR;
37
QLIST_FOREACH_SAFE(c, &from->parents, next_parent, next) {
22
+ } else {
38
assert(c->bs == from);
23
+ bs->open_flags |= BDRV_O_RDWR;
39
@@ -XXX,XX +XXX,XX @@ void bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
24
+ }
40
25
+
41
out:
26
return 0;
42
g_slist_free(list);
43
+ bdrv_drained_end(from);
44
bdrv_unref(from);
27
}
45
}
28
46
29
--
47
--
30
2.19.1
48
2.20.1
31
49
32
50
diff view generated by jsdifflib
1
This tests that concurrent requests are correctly drained before making
2
graph modifications instead of running into assertions in
3
bdrv_replace_node().
4
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2
Reviewed-by: Eric Blake <eblake@redhat.com>
6
Reviewed-by: Max Reitz <mreitz@redhat.com>
3
---
7
---
4
tests/qemu-iotests/232 | 147 +++++++++++++++++++++++++++++++++++++
8
tests/qemu-iotests/255 | 83 +++++++++++++++++++++++++++++++++++
5
tests/qemu-iotests/232.out | 59 +++++++++++++++
9
tests/qemu-iotests/255.out | 16 +++++++
6
tests/qemu-iotests/group | 1 +
10
tests/qemu-iotests/group | 1 +
7
3 files changed, 207 insertions(+)
11
tests/qemu-iotests/iotests.py | 10 ++++-
8
create mode 100755 tests/qemu-iotests/232
12
4 files changed, 109 insertions(+), 1 deletion(-)
9
create mode 100644 tests/qemu-iotests/232.out
13
create mode 100755 tests/qemu-iotests/255
14
create mode 100644 tests/qemu-iotests/255.out
10
15
11
diff --git a/tests/qemu-iotests/232 b/tests/qemu-iotests/232
16
diff --git a/tests/qemu-iotests/255 b/tests/qemu-iotests/255
12
new file mode 100755
17
new file mode 100755
13
index XXXXXXX..XXXXXXX
18
index XXXXXXX..XXXXXXX
14
--- /dev/null
19
--- /dev/null
15
+++ b/tests/qemu-iotests/232
20
+++ b/tests/qemu-iotests/255
16
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@
17
+#!/bin/bash
22
+#!/usr/bin/env python
18
+#
23
+#
19
+# Test for auto-read-only
24
+# Test commit job graph modifications while requests are active
20
+#
25
+#
21
+# Copyright (C) 2018 Red Hat, Inc.
26
+# Copyright (C) 2019 Red Hat, Inc.
27
+#
28
+# Creator/Owner: Kevin Wolf <kwolf@redhat.com>
22
+#
29
+#
23
+# This program is free software; you can redistribute it and/or modify
30
+# This program is free software; you can redistribute it and/or modify
24
+# it under the terms of the GNU General Public License as published by
31
+# it under the terms of the GNU General Public License as published by
25
+# the Free Software Foundation; either version 2 of the License, or
32
+# the Free Software Foundation; either version 2 of the License, or
26
+# (at your option) any later version.
33
+# (at your option) any later version.
...
...
32
+#
39
+#
33
+# You should have received a copy of the GNU General Public License
40
+# You should have received a copy of the GNU General Public License
34
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
41
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
35
+#
42
+#
36
+
43
+
37
+# creator
44
+import iotests
38
+owner=kwolf@redhat.com
45
+from iotests import imgfmt
39
+
46
+
40
+seq=`basename $0`
47
+iotests.verify_image_format(supported_fmts=['qcow2'])
41
+echo "QA output created by $seq"
42
+
48
+
43
+here=`pwd`
49
+def blockdev_create(vm, options):
44
+status=1    # failure is the default!
50
+ result = vm.qmp_log('blockdev-create',
51
+ filters=[iotests.filter_qmp_testfiles],
52
+ job_id='job0', options=options)
45
+
53
+
46
+_cleanup()
54
+ if 'return' in result:
47
+{
55
+ assert result['return'] == {}
48
+ _cleanup_test_img
56
+ vm.run_job('job0')
49
+ rm -f $TEST_IMG.snap
57
+ iotests.log("")
50
+}
51
+trap "_cleanup; exit \$status" 0 1 2 3 15
52
+
58
+
53
+# get standard environment, filters and checks
59
+with iotests.FilePath('t.qcow2') as disk_path, \
54
+. ./common.rc
60
+ iotests.FilePath('t.qcow2.mid') as mid_path, \
55
+. ./common.filter
61
+ iotests.FilePath('t.qcow2.base') as base_path, \
62
+ iotests.VM() as vm:
56
+
63
+
57
+_supported_fmt generic
64
+ iotests.log("=== Create backing chain and start VM ===")
58
+_supported_proto file
65
+ iotests.log("")
59
+_supported_os Linux
60
+
66
+
61
+function do_run_qemu()
67
+ size = 128 * 1024 * 1024
62
+{
68
+ size_str = str(size)
63
+ echo Testing: "$@"
64
+ (
65
+ if ! test -t 0; then
66
+ while read cmd; do
67
+ echo $cmd
68
+ done
69
+ fi
70
+ echo quit
71
+ ) | $QEMU -nographic -monitor stdio -nodefaults "$@"
72
+ echo
73
+}
74
+
69
+
75
+function run_qemu()
70
+ iotests.create_image(base_path, size)
76
+{
71
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, mid_path, size_str)
77
+ do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_hmp |
72
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, disk_path, size_str)
78
+ _filter_generated_node_ids | _filter_imgfmt
79
+}
80
+
73
+
81
+function run_qemu_info_block()
74
+ # Create a backing chain like this:
82
+{
75
+ # base <- [throttled: bps-read=4096] <- mid <- overlay
83
+ echo "info block -n" | run_qemu "$@" | grep -e "(file" -e "QEMU_PROG"
84
+}
85
+
76
+
86
+size=128M
77
+ vm.add_object('throttle-group,x-bps-read=4096,id=throttle0')
78
+ vm.add_blockdev('file,filename=%s,node-name=base' % (base_path))
79
+ vm.add_blockdev('throttle,throttle-group=throttle0,file=base,node-name=throttled')
80
+ vm.add_blockdev('file,filename=%s,node-name=mid-file' % (mid_path))
81
+ vm.add_blockdev('qcow2,file=mid-file,node-name=mid,backing=throttled')
82
+ vm.add_drive_raw('if=none,id=overlay,driver=qcow2,file=%s,backing=mid' % (disk_path))
87
+
83
+
88
+_make_test_img $size
84
+ vm.launch()
89
+
85
+
90
+echo
86
+ iotests.log("=== Start background read requests ===")
91
+echo "=== -drive with read-write image: read-only/auto-read-only combinations ==="
87
+ iotests.log("")
92
+echo
93
+
88
+
94
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on,auto-read-only=off
89
+ def start_requests():
95
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on,auto-read-only=on
90
+ vm.hmp_qemu_io('overlay', 'aio_read 0 4k')
96
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on
91
+ vm.hmp_qemu_io('overlay', 'aio_read 0 4k')
97
+echo
98
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off,auto-read-only=off
99
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off,auto-read-only=on
100
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off
101
+echo
102
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,auto-read-only=off
103
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,auto-read-only=on
104
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none
105
+
92
+
106
+echo
93
+ start_requests()
107
+echo "=== -drive with read-only image: read-only/auto-read-only combinations ==="
108
+echo
109
+
94
+
110
+chmod a-w $TEST_IMG
95
+ iotests.log("=== Run a commit job ===")
96
+ iotests.log("")
111
+
97
+
112
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on,auto-read-only=off
98
+ result = vm.qmp_log('block-commit', job_id='job0', auto_finalize=False,
113
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on,auto-read-only=on
99
+ device='overlay', top_node='mid')
114
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on
115
+echo
116
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off,auto-read-only=off
117
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off,auto-read-only=on
118
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off
119
+echo
120
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,auto-read-only=off
121
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,auto-read-only=on
122
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none
123
+
100
+
124
+echo
101
+ vm.run_job('job0', auto_finalize=False, pre_finalize=start_requests,
125
+echo "=== -blockdev with read-write image: read-only/auto-read-only combinations ==="
102
+ auto_dismiss=True)
126
+echo
127
+
103
+
128
+chmod a+w $TEST_IMG
104
+ vm.shutdown()
129
+
105
diff --git a/tests/qemu-iotests/255.out b/tests/qemu-iotests/255.out
130
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on,auto-read-only=off
131
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on,auto-read-only=on
132
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on
133
+echo
134
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off,auto-read-only=off
135
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off,auto-read-only=on
136
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off
137
+echo
138
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,auto-read-only=off
139
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,auto-read-only=on
140
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0
141
+
142
+echo
143
+echo "=== -blockdev with read-only image: read-only/auto-read-only combinations ==="
144
+echo
145
+
146
+chmod a-w $TEST_IMG
147
+
148
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on,auto-read-only=off
149
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on,auto-read-only=on
150
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on
151
+echo
152
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off,auto-read-only=off
153
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off,auto-read-only=on
154
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off
155
+echo
156
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,auto-read-only=off
157
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,auto-read-only=on
158
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0
159
+
160
+# success, all done
161
+echo "*** done"
162
+rm -f $seq.full
163
+status=0
164
diff --git a/tests/qemu-iotests/232.out b/tests/qemu-iotests/232.out
165
new file mode 100644
106
new file mode 100644
166
index XXXXXXX..XXXXXXX
107
index XXXXXXX..XXXXXXX
167
--- /dev/null
108
--- /dev/null
168
+++ b/tests/qemu-iotests/232.out
109
+++ b/tests/qemu-iotests/255.out
169
@@ -XXX,XX +XXX,XX @@
110
@@ -XXX,XX +XXX,XX @@
170
+QA output created by 232
111
+=== Create backing chain and start VM ===
171
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
172
+
112
+
173
+=== -drive with read-write image: read-only/auto-read-only combinations ===
113
+Formatting 'TEST_DIR/PID-t.qcow2.mid', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16
174
+
114
+
175
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
115
+Formatting 'TEST_DIR/PID-t.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16
176
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
177
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
178
+
116
+
179
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
117
+=== Start background read requests ===
180
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
181
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
182
+
118
+
183
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
119
+=== Run a commit job ===
184
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
185
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
186
+
120
+
187
+=== -drive with read-only image: read-only/auto-read-only combinations ===
121
+{"execute": "block-commit", "arguments": {"auto-finalize": false, "device": "overlay", "job-id": "job0", "top-node": "mid"}}
188
+
122
+{"return": {}}
189
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
123
+{"execute": "job-finalize", "arguments": {"id": "job0"}}
190
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
124
+{"return": {}}
191
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
125
+{"data": {"id": "job0", "type": "commit"}, "event": "BLOCK_JOB_PENDING", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
192
+
126
+{"data": {"device": "job0", "len": 134217728, "offset": 134217728, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
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
194
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
195
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
196
+
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
198
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
199
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
200
+
201
+=== -blockdev with read-write image: read-only/auto-read-only combinations ===
202
+
203
+node0: TEST_DIR/t.IMGFMT (file, read-only)
204
+node0: TEST_DIR/t.IMGFMT (file, read-only)
205
+node0: TEST_DIR/t.IMGFMT (file, read-only)
206
+
207
+node0: TEST_DIR/t.IMGFMT (file)
208
+node0: TEST_DIR/t.IMGFMT (file)
209
+node0: TEST_DIR/t.IMGFMT (file)
210
+
211
+node0: TEST_DIR/t.IMGFMT (file)
212
+node0: TEST_DIR/t.IMGFMT (file)
213
+node0: TEST_DIR/t.IMGFMT (file)
214
+
215
+=== -blockdev with read-only image: read-only/auto-read-only combinations ===
216
+
217
+node0: TEST_DIR/t.IMGFMT (file, read-only)
218
+node0: TEST_DIR/t.IMGFMT (file, read-only)
219
+node0: TEST_DIR/t.IMGFMT (file, read-only)
220
+
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
222
+node0: TEST_DIR/t.IMGFMT (file, read-only)
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
224
+
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
226
+node0: TEST_DIR/t.IMGFMT (file, read-only)
227
+QEMU_PROG: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
228
+*** done
229
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
127
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
230
index XXXXXXX..XXXXXXX 100644
128
index XXXXXXX..XXXXXXX 100644
231
--- a/tests/qemu-iotests/group
129
--- a/tests/qemu-iotests/group
232
+++ b/tests/qemu-iotests/group
130
+++ b/tests/qemu-iotests/group
233
@@ -XXX,XX +XXX,XX @@
131
@@ -XXX,XX +XXX,XX @@
234
227 auto quick
132
252 rw auto backing quick
235
229 auto quick
133
253 rw auto quick
236
231 auto quick
134
254 rw auto backing quick
237
+232 auto quick
135
+255 rw auto quick
136
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
137
index XXXXXXX..XXXXXXX 100644
138
--- a/tests/qemu-iotests/iotests.py
139
+++ b/tests/qemu-iotests/iotests.py
140
@@ -XXX,XX +XXX,XX @@ def qemu_img_pipe(*args):
141
sys.stderr.write('qemu-img received signal %i: %s\n' % (-exitcode, ' '.join(qemu_img_args + list(args))))
142
return subp.communicate()[0]
143
144
+def qemu_img_log(*args):
145
+ result = qemu_img_pipe(*args)
146
+ log(result, filters=[filter_testfiles])
147
+ return result
148
+
149
def img_info_log(filename, filter_path=None, imgopts=False, extra_args=[]):
150
args = [ 'info' ]
151
if imgopts:
152
@@ -XXX,XX +XXX,XX @@ class VM(qtest.QEMUQtestMachine):
153
return result
154
155
# Returns None on success, and an error string on failure
156
- def run_job(self, job, auto_finalize=True, auto_dismiss=False):
157
+ def run_job(self, job, auto_finalize=True, auto_dismiss=False,
158
+ pre_finalize=None):
159
error = None
160
while True:
161
for ev in self.get_qmp_events_filtered(wait=True):
162
@@ -XXX,XX +XXX,XX @@ class VM(qtest.QEMUQtestMachine):
163
error = j['error']
164
log('Job failed: %s' % (j['error']))
165
elif status == 'pending' and not auto_finalize:
166
+ if pre_finalize:
167
+ pre_finalize()
168
self.qmp_log('job-finalize', id=job)
169
elif status == 'concluded' and not auto_dismiss:
170
self.qmp_log('job-dismiss', id=job)
238
--
171
--
239
2.19.1
172
2.20.1
240
173
241
174
diff view generated by jsdifflib
1
From: Peter Maydell <peter.maydell@linaro.org>
1
From: John Snow <jsnow@redhat.com>
2
2
3
Taking the address of a field in a packed struct is a bad idea, because
3
If the bitmap can't be used for whatever reason, we skip putting down
4
it might not be actually aligned enough for that pointer type (and
4
the reference. Fix that.
5
thus cause a crash on dereference on some host architectures). Newer
6
versions of clang warn about this. Avoid the bug by not using the
7
"modify in place" byte swapping functions.
8
5
9
There are a few places where the in-place swap function is
6
In practice, this means that if you attempt to gracefully exit QEMU
10
used on something other than a packed struct field; we convert
7
after a backup command being rejected, bdrv_close_all will fail and
11
those anyway, for consistency.
8
tell you some unpleasant things via assert().
12
9
13
This patch was produced with the following spatch script
10
Reported-by: aihua liang <aliang@redhat.com>
14
(and hand-editing to fold a few resulting overlength lines):
11
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1703916
15
12
Signed-off-by: John Snow <jsnow@redhat.com>
16
@@
13
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
17
expression E;
18
@@
19
-be16_to_cpus(&E);
20
+E = be16_to_cpu(E);
21
@@
22
expression E;
23
@@
24
-be32_to_cpus(&E);
25
+E = be32_to_cpu(E);
26
@@
27
expression E;
28
@@
29
-be64_to_cpus(&E);
30
+E = be64_to_cpu(E);
31
@@
32
expression E;
33
@@
34
-cpu_to_be16s(&E);
35
+E = cpu_to_be16(E);
36
@@
37
expression E;
38
@@
39
-cpu_to_be32s(&E);
40
+E = cpu_to_be32(E);
41
@@
42
expression E;
43
@@
44
-cpu_to_be64s(&E);
45
+E = cpu_to_be64(E);
46
47
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
48
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
49
Tested-by: John Snow <jsnow@redhat.com>
50
Reviewed-by: John Snow <jsnow@redhat.com>
51
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
52
---
15
---
53
block/qcow2.c | 64 +++++++++++++++++++++++++++------------------------
16
blockdev.c | 13 ++++++-------
54
1 file changed, 34 insertions(+), 30 deletions(-)
17
1 file changed, 6 insertions(+), 7 deletions(-)
55
18
56
diff --git a/block/qcow2.c b/block/qcow2.c
19
diff --git a/blockdev.c b/blockdev.c
57
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
58
--- a/block/qcow2.c
21
--- a/blockdev.c
59
+++ b/block/qcow2.c
22
+++ b/blockdev.c
60
@@ -XXX,XX +XXX,XX @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
23
@@ -XXX,XX +XXX,XX @@ static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn,
61
"pread fail from offset %" PRIu64, offset);
24
if (set_backing_hd) {
62
return 1;
25
bdrv_set_backing_hd(target_bs, source, &local_err);
63
}
26
if (local_err) {
64
- be32_to_cpus(&ext.magic);
27
- bdrv_unref(target_bs);
65
- be32_to_cpus(&ext.len);
28
- goto out;
66
+ ext.magic = be32_to_cpu(ext.magic);
29
+ goto unref;
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;
100
}
101
- be32_to_cpus(&header.magic);
102
- be32_to_cpus(&header.version);
103
- be64_to_cpus(&header.backing_file_offset);
104
- be32_to_cpus(&header.backing_file_size);
105
- be64_to_cpus(&header.size);
106
- be32_to_cpus(&header.cluster_bits);
107
- be32_to_cpus(&header.crypt_method);
108
- be64_to_cpus(&header.l1_table_offset);
109
- be32_to_cpus(&header.l1_size);
110
- be64_to_cpus(&header.refcount_table_offset);
111
- be32_to_cpus(&header.refcount_table_clusters);
112
- be64_to_cpus(&header.snapshots_offset);
113
- be32_to_cpus(&header.nb_snapshots);
114
+ header.magic = be32_to_cpu(header.magic);
115
+ header.version = be32_to_cpu(header.version);
116
+ header.backing_file_offset = be64_to_cpu(header.backing_file_offset);
117
+ header.backing_file_size = be32_to_cpu(header.backing_file_size);
118
+ header.size = be64_to_cpu(header.size);
119
+ header.cluster_bits = be32_to_cpu(header.cluster_bits);
120
+ header.crypt_method = be32_to_cpu(header.crypt_method);
121
+ header.l1_table_offset = be64_to_cpu(header.l1_table_offset);
122
+ header.l1_size = be32_to_cpu(header.l1_size);
123
+ header.refcount_table_offset = be64_to_cpu(header.refcount_table_offset);
124
+ header.refcount_table_clusters =
125
+ be32_to_cpu(header.refcount_table_clusters);
126
+ header.snapshots_offset = be64_to_cpu(header.snapshots_offset);
127
+ header.nb_snapshots = be32_to_cpu(header.nb_snapshots);
128
129
if (header.magic != QCOW_MAGIC) {
130
error_setg(errp, "Image is not in qcow2 format");
131
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
132
header.refcount_order = 4;
133
header.header_length = 72;
134
} else {
135
- be64_to_cpus(&header.incompatible_features);
136
- be64_to_cpus(&header.compatible_features);
137
- be64_to_cpus(&header.autoclear_features);
138
- be32_to_cpus(&header.refcount_order);
139
- be32_to_cpus(&header.header_length);
140
+ header.incompatible_features =
141
+ be64_to_cpu(header.incompatible_features);
142
+ header.compatible_features = be64_to_cpu(header.compatible_features);
143
+ header.autoclear_features = be64_to_cpu(header.autoclear_features);
144
+ header.refcount_order = be32_to_cpu(header.refcount_order);
145
+ header.header_length = be32_to_cpu(header.header_length);
146
147
if (header.header_length < 104) {
148
error_setg(errp, "qcow2 header too short");
149
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
150
goto fail;
151
}
152
for(i = 0;i < s->l1_size; i++) {
153
- be64_to_cpus(&s->l1_table[i]);
154
+ s->l1_table[i] = be64_to_cpu(s->l1_table[i]);
155
}
30
}
156
}
31
}
157
32
158
@@ -XXX,XX +XXX,XX @@ int qcow2_update_header(BlockDriverState *bs)
33
@@ -XXX,XX +XXX,XX @@ static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn,
159
34
bmap = bdrv_find_dirty_bitmap(bs, backup->bitmap);
160
/* Full disk encryption header pointer extension */
35
if (!bmap) {
161
if (s->crypto_header.offset != 0) {
36
error_setg(errp, "Bitmap '%s' could not be found", backup->bitmap);
162
- cpu_to_be64s(&s->crypto_header.offset);
37
- bdrv_unref(target_bs);
163
- cpu_to_be64s(&s->crypto_header.length);
38
- goto out;
164
+ s->crypto_header.offset = cpu_to_be64(s->crypto_header.offset);
39
+ goto unref;
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
}
40
}
41
if (bdrv_dirty_bitmap_check(bmap, BDRV_BITMAP_DEFAULT, errp)) {
42
- goto out;
43
+ goto unref;
44
}
45
}
46
if (!backup->auto_finalize) {
47
@@ -XXX,XX +XXX,XX @@ static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn,
48
backup->sync, bmap, backup->compress,
49
backup->on_source_error, backup->on_target_error,
50
job_flags, NULL, NULL, txn, &local_err);
51
- bdrv_unref(target_bs);
52
if (local_err != NULL) {
53
error_propagate(errp, local_err);
54
- goto out;
55
+ goto unref;
56
}
57
58
+unref:
59
+ bdrv_unref(target_bs);
60
out:
61
aio_context_release(aio_context);
62
return job;
176
--
63
--
177
2.19.1
64
2.20.1
178
65
179
66
diff view generated by jsdifflib
1
From: Leonid Bloch <lbloch@janustech.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
The lookup table for power-of-two sizes was added in commit 540b8492618eb
3
Block layer may recursively check block_status in file child of qcow2,
4
for the purpose of having convenient shortcuts for these sizes in cases
4
if qcow2 driver returned DATA. There are several test cases to check
5
when the literal number has to be present at compile time, and
5
influence of lseek on block_status performance. To see real difference
6
expressions as '(1 * KiB)' can not be used. One such case is the
6
run on tmpfs.
7
stringification of sizes. Beyond that, it is convenient to use these
8
shortcuts for all power-of-two sizes, even if they don't have to be
9
literal numbers.
10
7
11
Despite its convenience, this table introduced 55 lines of "dumb" code,
8
Tests originally created by Kevin, I just refactored and put them
12
the purpose and origin of which are obscure without reading the message
9
together into one executable file with simple output.
13
of the commit which introduced it. This patch fixes that by adding a
14
comment to the code itself with a brief explanation for the reasoning
15
behind this table. This comment includes the short AWK script that
16
generated the table, so that anyone who's interested could make sure
17
that the values in it are correct (otherwise these values look as if
18
they were typed manually).
19
10
20
Signed-off-by: Leonid Bloch <lbloch@janustech.com>
11
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
---
13
---
23
include/qemu/units.h | 18 ++++++++++++++++++
14
tests/perf/block/qcow2/convert-blockstatus | 71 ++++++++++++++++++++++
24
1 file changed, 18 insertions(+)
15
1 file changed, 71 insertions(+)
16
create mode 100755 tests/perf/block/qcow2/convert-blockstatus
25
17
26
diff --git a/include/qemu/units.h b/include/qemu/units.h
18
diff --git a/tests/perf/block/qcow2/convert-blockstatus b/tests/perf/block/qcow2/convert-blockstatus
27
index XXXXXXX..XXXXXXX 100644
19
new file mode 100755
28
--- a/include/qemu/units.h
20
index XXXXXXX..XXXXXXX
29
+++ b/include/qemu/units.h
21
--- /dev/null
22
+++ b/tests/perf/block/qcow2/convert-blockstatus
30
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@
31
#define PiB (INT64_C(1) << 50)
24
+#!/bin/bash
32
#define EiB (INT64_C(1) << 60)
25
+#
33
26
+# Test lseek influence on qcow2 block-status
34
+/*
27
+#
35
+ * The following lookup table is intended to be used when a literal string of
28
+# Block layer may recursively check block_status in file child of qcow2, if
36
+ * the number of bytes is required (for example if it needs to be stringified).
29
+# qcow2 driver returned DATA. There are several test cases to check influence
37
+ * It can also be used for generic shortcuts of power-of-two sizes.
30
+# of lseek on block_status performance. To see real difference run on tmpfs.
38
+ * This table is generated using the AWK script below:
31
+#
39
+ *
32
+# Copyright (c) 2019 Virtuozzo International GmbH. All rights reserved.
40
+ * BEGIN {
33
+#
41
+ * suffix="KMGTPE";
34
+# Tests originally written by Kevin Wolf
42
+ * for(i=10; i<64; i++) {
35
+#
43
+ * val=2**i;
36
+# This program is free software; you can redistribute it and/or modify
44
+ * s=substr(suffix, int(i/10), 1);
37
+# it under the terms of the GNU General Public License as published by
45
+ * n=2**(i%10);
38
+# the Free Software Foundation; either version 2 of the License, or
46
+ * pad=21-int(log(n)/log(10));
39
+# (at your option) any later version.
47
+ * printf("#define S_%d%siB %*d\n", n, s, pad, val);
40
+#
48
+ * }
41
+# This program is distributed in the hope that it will be useful,
49
+ * }
42
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
50
+ */
43
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
44
+# GNU General Public License for more details.
45
+#
46
+# You should have received a copy of the GNU General Public License
47
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
48
+#
51
+
49
+
52
#define S_1KiB 1024
50
+if [ "$#" -lt 1 ]; then
53
#define S_2KiB 2048
51
+ echo "Usage: $0 SOURCE_FILE"
54
#define S_4KiB 4096
52
+ exit 1
53
+fi
54
+
55
+ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../../../.." >/dev/null 2>&1 && pwd )"
56
+QEMU_IMG="$ROOT_DIR/qemu-img"
57
+QEMU_IO="$ROOT_DIR/qemu-io"
58
+
59
+size=1G
60
+src="$1"
61
+
62
+# test-case plain
63
+
64
+(
65
+$QEMU_IMG create -f qcow2 "$src" $size
66
+for i in $(seq 16384 -1 0); do
67
+ echo "write $((i * 65536)) 64k"
68
+done | $QEMU_IO "$src"
69
+) > /dev/null
70
+
71
+echo -n "plain: "
72
+/usr/bin/time -f %e $QEMU_IMG convert -n "$src" null-co://
73
+
74
+# test-case forward
75
+
76
+(
77
+$QEMU_IMG create -f qcow2 "$src" $size
78
+for i in $(seq 0 2 16384); do
79
+ echo "write $((i * 65536)) 64k"
80
+done | $QEMU_IO "$src"
81
+for i in $(seq 1 2 16384); do
82
+ echo "write $((i * 65536)) 64k"
83
+done | $QEMU_IO "$src"
84
+) > /dev/null
85
+
86
+echo -n "forward: "
87
+/usr/bin/time -f %e $QEMU_IMG convert -n "$src" null-co://
88
+
89
+# test-case prealloc
90
+
91
+$QEMU_IMG create -f qcow2 -o preallocation=metadata "$src" $size > /dev/null
92
+
93
+echo -n "prealloc: "
94
+/usr/bin/time -f %e $QEMU_IMG convert -n "$src" null-co://
55
--
95
--
56
2.19.1
96
2.20.1
57
97
58
98
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
This doesn't have any practical effect at the moment because the
3
drv_co_block_status digs bs->file for additional, more accurate search
4
values of BDRV_SECTOR_SIZE, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE and
4
for hole inside region, reported as DATA by bs since 5daa74a6ebc.
5
QCRYPTO_BLOCK_QCOW_SECTOR_SIZE are all the same (512 bytes), but
5
6
future encryption methods could have different requirements.
6
This accuracy is not free: assume we have qcow2 disk. Actually, qcow2
7
7
knows, where are holes and where is data. But every block_status
8
Signed-off-by: Alberto Garcia <berto@igalia.com>
8
request calls lseek additionally. Assume a big disk, full of
9
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
9
data, in any iterative copying block job (or img convert) we'll call
10
lseek(HOLE) on every iteration, and each of these lseeks will have to
11
iterate through all metadata up to the end of file. It's obviously
12
ineffective behavior. And for many scenarios we don't need this lseek
13
at all.
14
15
However, lseek is needed when we have metadata-preallocated image.
16
17
So, let's detect metadata-preallocation case and don't dig qcow2's
18
protocol file in other cases.
19
20
The idea is to compare allocation size in POV of filesystem with
21
allocations size in POV of Qcow2 (by refcounts). If allocation in fs is
22
significantly lower, consider it as metadata-preallocation case.
23
24
102 iotest changed, as our detector can't detect shrinked file as
25
metadata-preallocation, which don't seem to be wrong, as with metadata
26
preallocation we always have valid file length.
27
28
Two other iotests have a slight change in their QMP output sequence:
29
Active 'block-commit' returns earlier because the job coroutine yields
30
earlier on a blocking operation. This operation is loading the refcount
31
blocks in qcow2_detect_metadata_preallocation().
32
33
Suggested-by: Denis V. Lunev <den@openvz.org>
34
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
35
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
36
---
12
block/qcow2.c | 2 +-
37
block/qcow2.h | 4 ++++
13
1 file changed, 1 insertion(+), 1 deletion(-)
38
include/block/block.h | 8 +++++++-
14
39
block/io.c | 9 ++++++++-
40
block/qcow2-refcount.c | 32 ++++++++++++++++++++++++++++++++
41
block/qcow2.c | 11 +++++++++++
42
tests/qemu-iotests/102 | 2 +-
43
tests/qemu-iotests/102.out | 3 ++-
44
tests/qemu-iotests/141.out | 2 +-
45
tests/qemu-iotests/144.out | 2 +-
46
9 files changed, 67 insertions(+), 6 deletions(-)
47
48
diff --git a/block/qcow2.h b/block/qcow2.h
49
index XXXXXXX..XXXXXXX 100644
50
--- a/block/qcow2.h
51
+++ b/block/qcow2.h
52
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVQcow2State {
53
int nb_threads;
54
55
BdrvChild *data_file;
56
+
57
+ bool metadata_preallocation_checked;
58
+ bool metadata_preallocation;
59
} BDRVQcow2State;
60
61
typedef struct Qcow2COWRegion {
62
@@ -XXX,XX +XXX,XX @@ int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order,
63
void *cb_opaque, Error **errp);
64
int qcow2_shrink_reftable(BlockDriverState *bs);
65
int64_t qcow2_get_last_cluster(BlockDriverState *bs, int64_t size);
66
+int qcow2_detect_metadata_preallocation(BlockDriverState *bs);
67
68
/* qcow2-cluster.c functions */
69
int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
70
diff --git a/include/block/block.h b/include/block/block.h
71
index XXXXXXX..XXXXXXX 100644
72
--- a/include/block/block.h
73
+++ b/include/block/block.h
74
@@ -XXX,XX +XXX,XX @@ typedef struct HDGeometry {
75
* BDRV_BLOCK_EOF: the returned pnum covers through end of file for this
76
* layer, set by block layer
77
*
78
- * Internal flag:
79
+ * Internal flags:
80
* BDRV_BLOCK_RAW: for use by passthrough drivers, such as raw, to request
81
* that the block layer recompute the answer from the returned
82
* BDS; must be accompanied by just BDRV_BLOCK_OFFSET_VALID.
83
+ * BDRV_BLOCK_RECURSE: request that the block layer will recursively search for
84
+ * zeroes in file child of current block node inside
85
+ * returned region. Only valid together with both
86
+ * BDRV_BLOCK_DATA and BDRV_BLOCK_OFFSET_VALID. Should not
87
+ * appear with BDRV_BLOCK_ZERO.
88
*
89
* If BDRV_BLOCK_OFFSET_VALID is set, the map parameter represents the
90
* host offset within the returned BDS that is allocated for the
91
@@ -XXX,XX +XXX,XX @@ typedef struct HDGeometry {
92
#define BDRV_BLOCK_RAW 0x08
93
#define BDRV_BLOCK_ALLOCATED 0x10
94
#define BDRV_BLOCK_EOF 0x20
95
+#define BDRV_BLOCK_RECURSE 0x40
96
#define BDRV_BLOCK_OFFSET_MASK BDRV_SECTOR_MASK
97
98
typedef QSIMPLEQ_HEAD(BlockReopenQueue, BlockReopenQueueEntry) BlockReopenQueue;
99
diff --git a/block/io.c b/block/io.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/block/io.c
102
+++ b/block/io.c
103
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_block_status(BlockDriverState *bs,
104
*/
105
assert(*pnum && QEMU_IS_ALIGNED(*pnum, align) &&
106
align > offset - aligned_offset);
107
+ if (ret & BDRV_BLOCK_RECURSE) {
108
+ assert(ret & BDRV_BLOCK_DATA);
109
+ assert(ret & BDRV_BLOCK_OFFSET_VALID);
110
+ assert(!(ret & BDRV_BLOCK_ZERO));
111
+ }
112
+
113
*pnum -= offset - aligned_offset;
114
if (*pnum > bytes) {
115
*pnum = bytes;
116
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_block_status(BlockDriverState *bs,
117
}
118
}
119
120
- if (want_zero && local_file && local_file != bs &&
121
+ if (want_zero && ret & BDRV_BLOCK_RECURSE &&
122
+ local_file && local_file != bs &&
123
(ret & BDRV_BLOCK_DATA) && !(ret & BDRV_BLOCK_ZERO) &&
124
(ret & BDRV_BLOCK_OFFSET_VALID)) {
125
int64_t file_pnum;
126
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
127
index XXXXXXX..XXXXXXX 100644
128
--- a/block/qcow2-refcount.c
129
+++ b/block/qcow2-refcount.c
130
@@ -XXX,XX +XXX,XX @@ int64_t qcow2_get_last_cluster(BlockDriverState *bs, int64_t size)
131
"There are no references in the refcount table.");
132
return -EIO;
133
}
134
+
135
+int qcow2_detect_metadata_preallocation(BlockDriverState *bs)
136
+{
137
+ BDRVQcow2State *s = bs->opaque;
138
+ int64_t i, end_cluster, cluster_count = 0, threshold;
139
+ int64_t file_length, real_allocation, real_clusters;
140
+
141
+ file_length = bdrv_getlength(bs->file->bs);
142
+ if (file_length < 0) {
143
+ return file_length;
144
+ }
145
+
146
+ real_allocation = bdrv_get_allocated_file_size(bs->file->bs);
147
+ if (real_allocation < 0) {
148
+ return real_allocation;
149
+ }
150
+
151
+ real_clusters = real_allocation / s->cluster_size;
152
+ threshold = MAX(real_clusters * 10 / 9, real_clusters + 2);
153
+
154
+ end_cluster = size_to_clusters(s, file_length);
155
+ for (i = 0; i < end_cluster && cluster_count < threshold; i++) {
156
+ uint64_t refcount;
157
+ int ret = qcow2_get_refcount(bs, i, &refcount);
158
+ if (ret < 0) {
159
+ return ret;
160
+ }
161
+ cluster_count += !!refcount;
162
+ }
163
+
164
+ return cluster_count >= threshold;
165
+}
15
diff --git a/block/qcow2.c b/block/qcow2.c
166
diff --git a/block/qcow2.c b/block/qcow2.c
16
index XXXXXXX..XXXXXXX 100644
167
index XXXXXXX..XXXXXXX 100644
17
--- a/block/qcow2.c
168
--- a/block/qcow2.c
18
+++ b/block/qcow2.c
169
+++ b/block/qcow2.c
19
@@ -XXX,XX +XXX,XX @@ static void qcow2_refresh_limits(BlockDriverState *bs, Error **errp)
170
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs,
20
171
unsigned int bytes;
21
if (bs->encrypted) {
172
int status = 0;
22
/* Encryption works on a sector granularity */
173
23
- bs->bl.request_alignment = BDRV_SECTOR_SIZE;
174
+ if (!s->metadata_preallocation_checked) {
24
+ bs->bl.request_alignment = qcrypto_block_get_sector_size(s->crypto);
175
+ ret = qcow2_detect_metadata_preallocation(bs);
176
+ s->metadata_preallocation = (ret == 1);
177
+ s->metadata_preallocation_checked = true;
178
+ }
179
+
180
bytes = MIN(INT_MAX, count);
181
qemu_co_mutex_lock(&s->lock);
182
ret = qcow2_get_cluster_offset(bs, offset, &bytes, &cluster_offset);
183
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs,
184
} else if (ret != QCOW2_CLUSTER_UNALLOCATED) {
185
status |= BDRV_BLOCK_DATA;
25
}
186
}
26
bs->bl.pwrite_zeroes_alignment = s->cluster_size;
187
+ if (s->metadata_preallocation && (status & BDRV_BLOCK_DATA) &&
27
bs->bl.pdiscard_alignment = s->cluster_size;
188
+ (status & BDRV_BLOCK_OFFSET_VALID))
189
+ {
190
+ status |= BDRV_BLOCK_RECURSE;
191
+ }
192
return status;
193
}
194
195
diff --git a/tests/qemu-iotests/102 b/tests/qemu-iotests/102
196
index XXXXXXX..XXXXXXX 100755
197
--- a/tests/qemu-iotests/102
198
+++ b/tests/qemu-iotests/102
199
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c 'write 0 64k' "$TEST_IMG" | _filter_qemu_io
200
$QEMU_IMG resize -f raw --shrink "$TEST_IMG" $((5 * 64 * 1024))
201
202
$QEMU_IO -c map "$TEST_IMG"
203
-$QEMU_IMG map "$TEST_IMG"
204
+$QEMU_IMG map "$TEST_IMG" | _filter_qemu_img_map
205
206
echo
207
echo '=== Testing map on an image file truncated outside of qemu ==='
208
diff --git a/tests/qemu-iotests/102.out b/tests/qemu-iotests/102.out
209
index XXXXXXX..XXXXXXX 100644
210
--- a/tests/qemu-iotests/102.out
211
+++ b/tests/qemu-iotests/102.out
212
@@ -XXX,XX +XXX,XX @@ wrote 65536/65536 bytes at offset 0
213
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
214
Image resized.
215
64 KiB (0x10000) bytes allocated at offset 0 bytes (0x0)
216
-Offset Length Mapped to File
217
+Offset Length File
218
+0 0x10000 TEST_DIR/t.IMGFMT
219
220
=== Testing map on an image file truncated outside of qemu ===
221
222
diff --git a/tests/qemu-iotests/141.out b/tests/qemu-iotests/141.out
223
index XXXXXXX..XXXXXXX 100644
224
--- a/tests/qemu-iotests/141.out
225
+++ b/tests/qemu-iotests/141.out
226
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
227
{"return": {}}
228
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
229
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
230
+{"return": {}}
231
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job0"}}
232
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
233
-{"return": {}}
234
{"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: commit"}}
235
{"return": {}}
236
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job0"}}
237
diff --git a/tests/qemu-iotests/144.out b/tests/qemu-iotests/144.out
238
index XXXXXXX..XXXXXXX 100644
239
--- a/tests/qemu-iotests/144.out
240
+++ b/tests/qemu-iotests/144.out
241
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/tmp.qcow2', fmt=qcow2 size=536870912 backing_file=TEST_DIR/
242
243
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "virtio0"}}
244
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "virtio0"}}
245
+{"return": {}}
246
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "virtio0"}}
247
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "virtio0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
248
{"return": {}}
249
-{"return": {}}
250
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "virtio0"}}
251
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "virtio0"}}
252
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "virtio0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
28
--
253
--
29
2.19.1
254
2.20.1
30
255
31
256
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
There is no good reason why there should be a newline in this
3
When ending a drained section, bdrv_do_drained_end() currently first
4
description, so remove it.
4
decrements the quiesce_counter, and only then actually ends the drain.
5
6
The bdrv_drain_invoke(bs, false) call may cause graph changes. Say the
7
graph change involves replacing an existing BB's ("blk") BDS
8
(blk_bs(blk)) by @bs. Let us introducing the following values:
9
- bs_oqc = old_quiesce_counter
10
(so bs->quiesce_counter == bs_oqc - 1)
11
- obs_qc = blk_bs(blk)->quiesce_counter (before bdrv_drain_invoke())
12
13
Let us assume there is no blk_pread_unthrottled() involved, so
14
blk->quiesce_counter == obs_qc (before bdrv_drain_invoke()).
15
16
Now replacing blk_bs(blk) by @bs will reduce blk->quiesce_counter by
17
obs_qc (making it 0) and increase it by bs_oqc-1 (making it bs_oqc-1).
18
19
bdrv_drain_invoke() returns and we invoke bdrv_parent_drained_end().
20
This will decrement blk->quiesce_counter by one, so it would be -1 --
21
were there not an assertion against that in blk_root_drained_end().
22
23
We therefore have to keep the quiesce_counter up at least until
24
bdrv_drain_invoke() returns, so that bdrv_parent_drained_end() does the
25
right thing for the parents @bs got during bdrv_drain_invoke().
26
27
But let us delay it even further, namely until bdrv_parent_drained_end()
28
returns, because then it mirrors bdrv_do_drained_begin(): There, we
29
first increment the quiesce_counter, then begin draining the parents,
30
and then call bdrv_drain_invoke(). It makes sense to let
31
bdrv_do_drained_end() unravel this exactly in reverse.
5
32
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
33
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
34
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
35
---
11
vl.c | 2 +-
36
block/io.c | 3 ++-
12
1 file changed, 1 insertion(+), 1 deletion(-)
37
1 file changed, 2 insertions(+), 1 deletion(-)
13
38
14
diff --git a/vl.c b/vl.c
39
diff --git a/block/io.c b/block/io.c
15
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
16
--- a/vl.c
41
--- a/block/io.c
17
+++ b/vl.c
42
+++ b/block/io.c
18
@@ -XXX,XX +XXX,XX @@ static QemuOptsList qemu_fw_cfg_opts = {
43
@@ -XXX,XX +XXX,XX @@ static void bdrv_do_drained_end(BlockDriverState *bs, bool recursive,
19
}, {
44
return;
20
.name = "file",
45
}
21
.type = QEMU_OPT_STRING,
46
assert(bs->quiesce_counter > 0);
22
- .help = "Sets the name of the file from which\n"
47
- old_quiesce_counter = atomic_fetch_dec(&bs->quiesce_counter);
23
+ .help = "Sets the name of the file from which "
48
24
"the fw_cfg blob will be loaded",
49
/* Re-enable things in child-to-parent order */
25
}, {
50
bdrv_drain_invoke(bs, false);
26
.name = "string",
51
bdrv_parent_drained_end(bs, parent, ignore_bds_parents);
52
+
53
+ old_quiesce_counter = atomic_fetch_dec(&bs->quiesce_counter);
54
if (old_quiesce_counter == 1) {
55
aio_enable_external(bdrv_get_aio_context(bs));
56
}
27
--
57
--
28
2.19.1
58
2.20.1
29
59
30
60
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
Just like in qemu_opts_print_help(), print the object name as a caption
3
This patch adds a test where we cancel a throttled mirror job and
4
instead of on every single line, indent all options, add angle brackets
4
immediately close the VM before it can be cancelled. Doing so will
5
around types, and align the descriptions after 24 characters.
5
invoke bdrv_drain_all() while the mirror job tries to drain the
6
6
throttled node. When bdrv_drain_all_end() tries to lift its drain on
7
Also, indent every object name in the list of available objects.
7
the throttle node, the job will exit and replace the current root node
8
of the BB drive0 (which is the job's filter node) by the throttle node.
9
Before the previous patch, this replacement did not increase drive0's
10
quiesce_counter by a sufficient amount, so when
11
bdrv_parent_drained_end() (invoked by bdrv_do_drained_end(), invoked by
12
bdrv_drain_all_end()) tried to end the drain on all of the throttle
13
node's parents, it decreased drive0's quiesce_counter below 0 -- which
14
fails an assertion.
8
15
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
16
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
18
---
13
vl.c | 13 ++++++++++---
19
tests/qemu-iotests/255 | 52 ++++++++++++++++++++++++++++++++++++++
14
1 file changed, 10 insertions(+), 3 deletions(-)
20
tests/qemu-iotests/255.out | 24 ++++++++++++++++++
21
2 files changed, 76 insertions(+)
15
22
16
diff --git a/vl.c b/vl.c
23
diff --git a/tests/qemu-iotests/255 b/tests/qemu-iotests/255
24
index XXXXXXX..XXXXXXX 100755
25
--- a/tests/qemu-iotests/255
26
+++ b/tests/qemu-iotests/255
27
@@ -XXX,XX +XXX,XX @@ def blockdev_create(vm, options):
28
vm.run_job('job0')
29
iotests.log("")
30
31
+iotests.log('Finishing a commit job with background reads')
32
+iotests.log('============================================')
33
+iotests.log('')
34
+
35
with iotests.FilePath('t.qcow2') as disk_path, \
36
iotests.FilePath('t.qcow2.mid') as mid_path, \
37
iotests.FilePath('t.qcow2.base') as base_path, \
38
@@ -XXX,XX +XXX,XX @@ with iotests.FilePath('t.qcow2') as disk_path, \
39
auto_dismiss=True)
40
41
vm.shutdown()
42
+
43
+iotests.log('')
44
+iotests.log('Closing the VM while a job is being cancelled')
45
+iotests.log('=============================================')
46
+iotests.log('')
47
+
48
+with iotests.FilePath('src.qcow2') as src_path, \
49
+ iotests.FilePath('dst.qcow2') as dst_path, \
50
+ iotests.VM() as vm:
51
+
52
+ iotests.log('=== Create images and start VM ===')
53
+ iotests.log('')
54
+
55
+ size = 128 * 1024 * 1024
56
+ size_str = str(size)
57
+
58
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, src_path, size_str)
59
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, dst_path, size_str)
60
+
61
+ iotests.log(iotests.qemu_io('-f', iotests.imgfmt, '-c', 'write 0 1M',
62
+ src_path),
63
+ filters=[iotests.filter_test_dir, iotests.filter_qemu_io])
64
+
65
+ vm.add_object('throttle-group,x-bps-read=4096,id=throttle0')
66
+
67
+ vm.add_blockdev('file,node-name=src-file,filename=%s' % (src_path))
68
+ vm.add_blockdev('%s,node-name=src,file=src-file' % (iotests.imgfmt))
69
+
70
+ vm.add_blockdev('file,node-name=dst-file,filename=%s' % (dst_path))
71
+ vm.add_blockdev('%s,node-name=dst,file=dst-file' % (iotests.imgfmt))
72
+
73
+ vm.add_blockdev('throttle,node-name=src-throttled,' +
74
+ 'throttle-group=throttle0,file=src')
75
+
76
+ vm.add_device('virtio-blk,drive=src-throttled')
77
+
78
+ vm.launch()
79
+
80
+ iotests.log('=== Start a mirror job ===')
81
+ iotests.log('')
82
+
83
+ vm.qmp_log('blockdev-mirror', job_id='job0', device='src-throttled',
84
+ target='dst', sync='full')
85
+
86
+ vm.qmp_log('block-job-cancel', device='job0')
87
+ vm.qmp_log('quit')
88
+
89
+ vm.shutdown()
90
diff --git a/tests/qemu-iotests/255.out b/tests/qemu-iotests/255.out
17
index XXXXXXX..XXXXXXX 100644
91
index XXXXXXX..XXXXXXX 100644
18
--- a/vl.c
92
--- a/tests/qemu-iotests/255.out
19
+++ b/vl.c
93
+++ b/tests/qemu-iotests/255.out
20
@@ -XXX,XX +XXX,XX @@ static bool object_create_initial(const char *type, QemuOpts *opts)
94
@@ -XXX,XX +XXX,XX @@
21
list = object_class_get_list_sorted(TYPE_USER_CREATABLE, false);
95
+Finishing a commit job with background reads
22
for (l = list; l != NULL; l = l->next) {
96
+============================================
23
ObjectClass *oc = OBJECT_CLASS(l->data);
97
+
24
- printf("%s\n", object_class_get_name(oc));
98
=== Create backing chain and start VM ===
25
+ printf(" %s\n", object_class_get_name(oc));
99
26
}
100
Formatting 'TEST_DIR/PID-t.qcow2.mid', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16
27
g_slist_free(list);
101
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/PID-t.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 l
28
exit(0);
102
{"return": {}}
29
@@ -XXX,XX +XXX,XX @@ static bool object_create_initial(const char *type, QemuOpts *opts)
103
{"data": {"id": "job0", "type": "commit"}, "event": "BLOCK_JOB_PENDING", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
30
}
104
{"data": {"device": "job0", "len": 134217728, "offset": 134217728, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
31
105
+
32
str = g_string_new(NULL);
106
+Closing the VM while a job is being cancelled
33
- g_string_append_printf(str, "%s.%s=%s", type,
107
+=============================================
34
- prop->name, prop->type);
108
+
35
+ g_string_append_printf(str, " %s=<%s>", prop->name, prop->type);
109
+=== Create images and start VM ===
36
if (prop->description) {
110
+
37
+ if (str->len < 24) {
111
+Formatting 'TEST_DIR/PID-src.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16
38
+ g_string_append_printf(str, "%*s", 24 - (int)str->len, "");
112
+
39
+ }
113
+Formatting 'TEST_DIR/PID-dst.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16
40
g_string_append_printf(str, " - %s", prop->description);
114
+
41
}
115
+wrote 1048576/1048576 bytes at offset 0
42
g_ptr_array_add(array, g_string_free(str, false));
116
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
43
}
117
+
44
g_ptr_array_sort(array, (GCompareFunc)qemu_pstrcmp0);
118
+=== Start a mirror job ===
45
+ if (array->len > 0) {
119
+
46
+ printf("%s options:\n", type);
120
+{"execute": "blockdev-mirror", "arguments": {"device": "src-throttled", "job-id": "job0", "sync": "full", "target": "dst"}}
47
+ } else {
121
+{"return": {}}
48
+ printf("There are no options for %s.\n", type);
122
+{"execute": "block-job-cancel", "arguments": {"device": "job0"}}
49
+ }
123
+{"return": {}}
50
for (i = 0; i < array->len; i++) {
124
+{"execute": "quit", "arguments": {}}
51
printf("%s\n", (char *)array->pdata[i]);
125
+{"return": {}}
52
}
53
--
126
--
54
2.19.1
127
2.20.1
55
128
56
129
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Julia Suvorova <jusual@mail.ru>
2
2
3
This is a static function with only one caller, so there's no need to
3
Callback-based laio_submit() and laio_cancel() were left after
4
keep it. Inlining the code in quorum_compare() makes it much simpler.
4
rewriting Linux AIO backend to coroutines in hope that they would be
5
used in other code that could bypass coroutines. They can be safely
6
removed because they have not been used since that time.
5
7
6
Signed-off-by: Alberto Garcia <berto@igalia.com>
8
Signed-off-by: Julia Suvorova <jusual@mail.ru>
7
Reported-by: Markus Armbruster <armbru@redhat.com>
9
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
11
---
10
block/quorum.c | 24 +++++-------------------
12
include/block/raw-aio.h | 3 --
11
1 file changed, 5 insertions(+), 19 deletions(-)
13
block/linux-aio.c | 72 ++++++-----------------------------------
14
2 files changed, 10 insertions(+), 65 deletions(-)
12
15
13
diff --git a/block/quorum.c b/block/quorum.c
16
diff --git a/include/block/raw-aio.h b/include/block/raw-aio.h
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/block/quorum.c
18
--- a/include/block/raw-aio.h
16
+++ b/block/quorum.c
19
+++ b/include/block/raw-aio.h
17
@@ -XXX,XX +XXX,XX @@ static bool quorum_iovec_compare(QEMUIOVector *a, QEMUIOVector *b)
20
@@ -XXX,XX +XXX,XX @@ LinuxAioState *laio_init(Error **errp);
21
void laio_cleanup(LinuxAioState *s);
22
int coroutine_fn laio_co_submit(BlockDriverState *bs, LinuxAioState *s, int fd,
23
uint64_t offset, QEMUIOVector *qiov, int type);
24
-BlockAIOCB *laio_submit(BlockDriverState *bs, LinuxAioState *s, int fd,
25
- int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
26
- BlockCompletionFunc *cb, void *opaque, int type);
27
void laio_detach_aio_context(LinuxAioState *s, AioContext *old_context);
28
void laio_attach_aio_context(LinuxAioState *s, AioContext *new_context);
29
void laio_io_plug(BlockDriverState *bs, LinuxAioState *s);
30
diff --git a/block/linux-aio.c b/block/linux-aio.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/block/linux-aio.c
33
+++ b/block/linux-aio.c
34
@@ -XXX,XX +XXX,XX @@
35
#define MAX_EVENTS 128
36
37
struct qemu_laiocb {
38
- BlockAIOCB common;
39
Coroutine *co;
40
LinuxAioState *ctx;
41
struct iocb iocb;
42
@@ -XXX,XX +XXX,XX @@ static inline ssize_t io_event_ret(struct io_event *ev)
43
}
44
45
/*
46
- * Completes an AIO request (calls the callback and frees the ACB).
47
+ * Completes an AIO request.
48
*/
49
static void qemu_laio_process_completion(struct qemu_laiocb *laiocb)
50
{
51
@@ -XXX,XX +XXX,XX @@ static void qemu_laio_process_completion(struct qemu_laiocb *laiocb)
52
}
53
54
laiocb->ret = ret;
55
- if (laiocb->co) {
56
- /* If the coroutine is already entered it must be in ioq_submit() and
57
- * will notice laio->ret has been filled in when it eventually runs
58
- * later. Coroutines cannot be entered recursively so avoid doing
59
- * that!
60
- */
61
- if (!qemu_coroutine_entered(laiocb->co)) {
62
- aio_co_wake(laiocb->co);
63
- }
64
- } else {
65
- laiocb->common.cb(laiocb->common.opaque, ret);
66
- qemu_aio_unref(laiocb);
67
+
68
+ /*
69
+ * If the coroutine is already entered it must be in ioq_submit() and
70
+ * will notice laio->ret has been filled in when it eventually runs
71
+ * later. Coroutines cannot be entered recursively so avoid doing
72
+ * that!
73
+ */
74
+ if (!qemu_coroutine_entered(laiocb->co)) {
75
+ aio_co_wake(laiocb->co);
76
}
77
}
78
79
@@ -XXX,XX +XXX,XX @@ static bool qemu_laio_poll_cb(void *opaque)
18
return true;
80
return true;
19
}
81
}
20
82
21
-static void GCC_FMT_ATTR(2, 3) quorum_err(QuorumAIOCB *acb,
83
-static void laio_cancel(BlockAIOCB *blockacb)
22
- const char *fmt, ...)
23
-{
84
-{
24
- va_list ap;
85
- struct qemu_laiocb *laiocb = (struct qemu_laiocb *)blockacb;
86
- struct io_event event;
87
- int ret;
25
-
88
-
26
- va_start(ap, fmt);
89
- if (laiocb->ret != -EINPROGRESS) {
27
- fprintf(stderr, "quorum: offset=%" PRIu64 " bytes=%" PRIu64 " ",
90
- return;
28
- acb->offset, acb->bytes);
91
- }
29
- vfprintf(stderr, fmt, ap);
92
- ret = io_cancel(laiocb->ctx->ctx, &laiocb->iocb, &event);
30
- fprintf(stderr, "\n");
93
- laiocb->ret = -ECANCELED;
31
- va_end(ap);
94
- if (ret != 0) {
32
- exit(1);
95
- /* iocb is not cancelled, cb will be called by the event loop later */
96
- return;
97
- }
98
-
99
- laiocb->common.cb(laiocb->common.opaque, laiocb->ret);
33
-}
100
-}
34
-
101
-
35
-static bool quorum_compare(QuorumAIOCB *acb,
102
-static const AIOCBInfo laio_aiocb_info = {
36
- QEMUIOVector *a,
103
- .aiocb_size = sizeof(struct qemu_laiocb),
37
- QEMUIOVector *b)
104
- .cancel_async = laio_cancel,
38
+static bool quorum_compare(QuorumAIOCB *acb, QEMUIOVector *a, QEMUIOVector *b)
105
-};
106
-
107
static void ioq_init(LaioQueue *io_q)
39
{
108
{
40
BDRVQuorumState *s = acb->bs->opaque;
109
QSIMPLEQ_INIT(&io_q->pending);
41
ssize_t offset;
110
@@ -XXX,XX +XXX,XX @@ int coroutine_fn laio_co_submit(BlockDriverState *bs, LinuxAioState *s, int fd,
42
@@ -XXX,XX +XXX,XX @@ static bool quorum_compare(QuorumAIOCB *acb,
111
return laiocb.ret;
43
if (s->is_blkverify) {
112
}
44
offset = qemu_iovec_compare(a, b);
113
45
if (offset != -1) {
114
-BlockAIOCB *laio_submit(BlockDriverState *bs, LinuxAioState *s, int fd,
46
- quorum_err(acb, "contents mismatch at offset %" PRIu64,
115
- int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
47
- acb->offset + offset);
116
- BlockCompletionFunc *cb, void *opaque, int type)
48
+ fprintf(stderr, "quorum: offset=%" PRIu64 " bytes=%" PRIu64
117
-{
49
+ " contents mismatch at offset %" PRIu64 "\n",
118
- struct qemu_laiocb *laiocb;
50
+ acb->offset, acb->bytes, acb->offset + offset);
119
- off_t offset = sector_num * BDRV_SECTOR_SIZE;
51
+ exit(1);
120
- int ret;
52
}
121
-
53
return true;
122
- laiocb = qemu_aio_get(&laio_aiocb_info, bs, cb, opaque);
54
}
123
- laiocb->nbytes = nb_sectors * BDRV_SECTOR_SIZE;
124
- laiocb->ctx = s;
125
- laiocb->ret = -EINPROGRESS;
126
- laiocb->is_read = (type == QEMU_AIO_READ);
127
- laiocb->qiov = qiov;
128
-
129
- ret = laio_do_submit(fd, laiocb, offset, type);
130
- if (ret < 0) {
131
- qemu_aio_unref(laiocb);
132
- return NULL;
133
- }
134
-
135
- return &laiocb->common;
136
-}
137
-
138
void laio_detach_aio_context(LinuxAioState *s, AioContext *old_context)
139
{
140
aio_set_event_notifier(old_context, &s->e, false, NULL, NULL);
55
--
141
--
56
2.19.1
142
2.20.1
57
143
58
144
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Kenneth Heitke <kenneth.heitke@intel.com>
2
2
3
This adds some whitespace into the option help (including indentation)
3
Signed-off-by: Kenneth Heitke <kenneth.heitke@intel.com>
4
and puts angle brackets around the type names. Furthermore, the list
4
Reviewed-by: Klaus Birkelund Jensen <klaus.jensen@cnexlabs.com>
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.
7
8
This patch also restores the description alignment we had before commit
9
9cbef9d68ee1d8d0, just at 24 instead of 16 characters like we used to.
10
This increase is because now we have the type and two spaces of
11
indentation before the description, and with a usual type name length of
12
three chracters, this sums up to eight additional characters -- which
13
means that we now need 24 characters to get the same amount of padding
14
for most options. Also, 24 is a third of 80, which makes it kind of a
15
round number in terminal terms.
16
17
Finally, this patch amends the reference output of iotest 082 to match
18
the changes (and thus makes it pass again).
19
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>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
23
---
6
---
24
include/qemu/option.h | 2 +-
7
hw/block/nvme.h | 2 +
25
qemu-img.c | 4 +-
8
include/block/nvme.h | 2 +
26
util/qemu-option.c | 32 +-
9
hw/block/nvme.c | 106 +++++++++++++++++++++++++++++++++++++++++-
27
tests/qemu-iotests/082.out | 956 ++++++++++++++++++-------------------
10
hw/block/trace-events | 2 +
28
4 files changed, 507 insertions(+), 487 deletions(-)
11
4 files changed, 110 insertions(+), 2 deletions(-)
29
12
30
diff --git a/include/qemu/option.h b/include/qemu/option.h
13
diff --git a/hw/block/nvme.h b/hw/block/nvme.h
31
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
32
--- a/include/qemu/option.h
15
--- a/hw/block/nvme.h
33
+++ b/include/qemu/option.h
16
+++ b/hw/block/nvme.h
34
@@ -XXX,XX +XXX,XX @@ typedef int (*qemu_opts_loopfunc)(void *opaque, QemuOpts *opts, Error **errp);
17
@@ -XXX,XX +XXX,XX @@ typedef struct NvmeCtrl {
35
int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func,
18
uint32_t cmbloc;
36
void *opaque, Error **errp);
19
uint8_t *cmbuf;
37
void qemu_opts_print(QemuOpts *opts, const char *sep);
20
uint64_t irq_status;
38
-void qemu_opts_print_help(QemuOptsList *list);
21
+ uint64_t host_timestamp; /* Timestamp sent by the host */
39
+void qemu_opts_print_help(QemuOptsList *list, bool print_caption);
22
+ uint64_t timestamp_set_qemu_clock_ms; /* QEMU clock time */
40
void qemu_opts_free(QemuOptsList *list);
23
41
QemuOptsList *qemu_opts_append(QemuOptsList *dst, QemuOptsList *list);
24
char *serial;
42
25
NvmeNamespace *namespaces;
43
diff --git a/qemu-img.c b/qemu-img.c
26
diff --git a/include/block/nvme.h b/include/block/nvme.h
44
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
45
--- a/qemu-img.c
28
--- a/include/block/nvme.h
46
+++ b/qemu-img.c
29
+++ b/include/block/nvme.h
47
@@ -XXX,XX +XXX,XX @@ static int print_block_option_help(const char *filename, const char *fmt)
30
@@ -XXX,XX +XXX,XX @@ enum NvmeIdCtrlOncs {
31
NVME_ONCS_WRITE_ZEROS = 1 << 3,
32
NVME_ONCS_FEATURES = 1 << 4,
33
NVME_ONCS_RESRVATIONS = 1 << 5,
34
+ NVME_ONCS_TIMESTAMP = 1 << 6,
35
};
36
37
#define NVME_CTRL_SQES_MIN(sqes) ((sqes) & 0xf)
38
@@ -XXX,XX +XXX,XX @@ enum NvmeFeatureIds {
39
NVME_INTERRUPT_VECTOR_CONF = 0x9,
40
NVME_WRITE_ATOMICITY = 0xa,
41
NVME_ASYNCHRONOUS_EVENT_CONF = 0xb,
42
+ NVME_TIMESTAMP = 0xe,
43
NVME_SOFTWARE_PROGRESS_MARKER = 0x80
44
};
45
46
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/block/nvme.c
49
+++ b/hw/block/nvme.c
50
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_map_prp(QEMUSGList *qsg, QEMUIOVector *iov, uint64_t prp1,
51
return NVME_INVALID_FIELD | NVME_DNR;
52
}
53
54
+static uint16_t nvme_dma_write_prp(NvmeCtrl *n, uint8_t *ptr, uint32_t len,
55
+ uint64_t prp1, uint64_t prp2)
56
+{
57
+ QEMUSGList qsg;
58
+ QEMUIOVector iov;
59
+ uint16_t status = NVME_SUCCESS;
60
+
61
+ if (nvme_map_prp(&qsg, &iov, prp1, prp2, len, n)) {
62
+ return NVME_INVALID_FIELD | NVME_DNR;
63
+ }
64
+ if (qsg.nsg > 0) {
65
+ if (dma_buf_write(ptr, len, &qsg)) {
66
+ status = NVME_INVALID_FIELD | NVME_DNR;
67
+ }
68
+ qemu_sglist_destroy(&qsg);
69
+ } else {
70
+ if (qemu_iovec_to_buf(&iov, 0, ptr, len) != len) {
71
+ status = NVME_INVALID_FIELD | NVME_DNR;
72
+ }
73
+ qemu_iovec_destroy(&iov);
74
+ }
75
+ return status;
76
+}
77
+
78
static uint16_t nvme_dma_read_prp(NvmeCtrl *n, uint8_t *ptr, uint32_t len,
79
uint64_t prp1, uint64_t prp2)
80
{
81
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_identify_nslist(NvmeCtrl *n, NvmeIdentify *c)
82
return ret;
83
}
84
85
-
86
static uint16_t nvme_identify(NvmeCtrl *n, NvmeCmd *cmd)
87
{
88
NvmeIdentify *c = (NvmeIdentify *)cmd;
89
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_identify(NvmeCtrl *n, NvmeCmd *cmd)
48
}
90
}
49
91
}
50
printf("Supported options:\n");
92
51
- qemu_opts_print_help(create_opts);
93
+static inline void nvme_set_timestamp(NvmeCtrl *n, uint64_t ts)
52
+ qemu_opts_print_help(create_opts, false);
94
+{
53
qemu_opts_free(create_opts);
95
+ trace_nvme_setfeat_timestamp(ts);
96
+
97
+ n->host_timestamp = le64_to_cpu(ts);
98
+ n->timestamp_set_qemu_clock_ms = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
99
+}
100
+
101
+static inline uint64_t nvme_get_timestamp(const NvmeCtrl *n)
102
+{
103
+ uint64_t current_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
104
+ uint64_t elapsed_time = current_time - n->timestamp_set_qemu_clock_ms;
105
+
106
+ union nvme_timestamp {
107
+ struct {
108
+ uint64_t timestamp:48;
109
+ uint64_t sync:1;
110
+ uint64_t origin:3;
111
+ uint64_t rsvd1:12;
112
+ };
113
+ uint64_t all;
114
+ };
115
+
116
+ union nvme_timestamp ts;
117
+ ts.all = 0;
118
+
119
+ /*
120
+ * If the sum of the Timestamp value set by the host and the elapsed
121
+ * time exceeds 2^48, the value returned should be reduced modulo 2^48.
122
+ */
123
+ ts.timestamp = (n->host_timestamp + elapsed_time) & 0xffffffffffff;
124
+
125
+ /* If the host timestamp is non-zero, set the timestamp origin */
126
+ ts.origin = n->host_timestamp ? 0x01 : 0x00;
127
+
128
+ trace_nvme_getfeat_timestamp(ts.all);
129
+
130
+ return cpu_to_le64(ts.all);
131
+}
132
+
133
+static uint16_t nvme_get_feature_timestamp(NvmeCtrl *n, NvmeCmd *cmd)
134
+{
135
+ uint64_t prp1 = le64_to_cpu(cmd->prp1);
136
+ uint64_t prp2 = le64_to_cpu(cmd->prp2);
137
+
138
+ uint64_t timestamp = nvme_get_timestamp(n);
139
+
140
+ return nvme_dma_read_prp(n, (uint8_t *)&timestamp,
141
+ sizeof(timestamp), prp1, prp2);
142
+}
143
+
144
static uint16_t nvme_get_feature(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req)
145
{
146
uint32_t dw10 = le32_to_cpu(cmd->cdw10);
147
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_get_feature(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req)
148
result = cpu_to_le32((n->num_queues - 2) | ((n->num_queues - 2) << 16));
149
trace_nvme_getfeat_numq(result);
150
break;
151
+ case NVME_TIMESTAMP:
152
+ return nvme_get_feature_timestamp(n, cmd);
153
+ break;
154
default:
155
trace_nvme_err_invalid_getfeat(dw10);
156
return NVME_INVALID_FIELD | NVME_DNR;
157
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_get_feature(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req)
158
return NVME_SUCCESS;
159
}
160
161
+static uint16_t nvme_set_feature_timestamp(NvmeCtrl *n, NvmeCmd *cmd)
162
+{
163
+ uint16_t ret;
164
+ uint64_t timestamp;
165
+ uint64_t prp1 = le64_to_cpu(cmd->prp1);
166
+ uint64_t prp2 = le64_to_cpu(cmd->prp2);
167
+
168
+ ret = nvme_dma_write_prp(n, (uint8_t *)&timestamp,
169
+ sizeof(timestamp), prp1, prp2);
170
+ if (ret != NVME_SUCCESS) {
171
+ return ret;
172
+ }
173
+
174
+ nvme_set_timestamp(n, timestamp);
175
+
176
+ return NVME_SUCCESS;
177
+}
178
+
179
static uint16_t nvme_set_feature(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req)
180
{
181
uint32_t dw10 = le32_to_cpu(cmd->cdw10);
182
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_set_feature(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req)
183
req->cqe.result =
184
cpu_to_le32((n->num_queues - 2) | ((n->num_queues - 2) << 16));
185
break;
186
+
187
+ case NVME_TIMESTAMP:
188
+ return nvme_set_feature_timestamp(n, cmd);
189
+ break;
190
+
191
default:
192
trace_nvme_err_invalid_setfeat(dw10);
193
return NVME_INVALID_FIELD | NVME_DNR;
194
@@ -XXX,XX +XXX,XX @@ static int nvme_start_ctrl(NvmeCtrl *n)
195
nvme_init_sq(&n->admin_sq, n, n->bar.asq, 0, 0,
196
NVME_AQA_ASQS(n->bar.aqa) + 1);
197
198
+ nvme_set_timestamp(n, 0ULL);
199
+
54
return 0;
200
return 0;
55
}
201
}
56
@@ -XXX,XX +XXX,XX @@ static int print_amend_option_help(const char *format)
202
57
assert(drv->create_opts);
203
@@ -XXX,XX +XXX,XX @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp)
58
204
id->sqes = (0x6 << 4) | 0x6;
59
printf("Creation options for '%s':\n", format);
205
id->cqes = (0x4 << 4) | 0x4;
60
- qemu_opts_print_help(drv->create_opts);
206
id->nn = cpu_to_le32(n->num_namespaces);
61
+ qemu_opts_print_help(drv->create_opts, false);
207
- id->oncs = cpu_to_le16(NVME_ONCS_WRITE_ZEROS);
62
printf("\nNote that not all of these options may be amendable.\n");
208
+ id->oncs = cpu_to_le16(NVME_ONCS_WRITE_ZEROS | NVME_ONCS_TIMESTAMP);
63
return 0;
209
id->psd[0].mp = cpu_to_le16(0x9c4);
64
}
210
id->psd[0].enlat = cpu_to_le32(0x10);
65
diff --git a/util/qemu-option.c b/util/qemu-option.c
211
id->psd[0].exlat = cpu_to_le32(0x4);
66
index XXXXXXX..XXXXXXX 100644
212
diff --git a/hw/block/trace-events b/hw/block/trace-events
67
--- a/util/qemu-option.c
213
index XXXXXXX..XXXXXXX 100644
68
+++ b/util/qemu-option.c
214
--- a/hw/block/trace-events
69
@@ -XXX,XX +XXX,XX @@ static const char *opt_type_to_string(enum QemuOptType type)
215
+++ b/hw/block/trace-events
70
g_assert_not_reached();
216
@@ -XXX,XX +XXX,XX @@ nvme_identify_nslist(uint16_t ns) "identify namespace list, nsid=%"PRIu16""
71
}
217
nvme_getfeat_vwcache(const char* result) "get feature volatile write cache, result=%s"
72
218
nvme_getfeat_numq(int result) "get feature number of queues, result=%d"
73
-void qemu_opts_print_help(QemuOptsList *list)
219
nvme_setfeat_numq(int reqcq, int reqsq, int gotcq, int gotsq) "requested cq_count=%d sq_count=%d, responding with cq_count=%d sq_count=%d"
74
+/**
220
+nvme_setfeat_timestamp(uint64_t ts) "set feature timestamp = 0x%"PRIx64""
75
+ * Print the list of options available in the given list. If
221
+nvme_getfeat_timestamp(uint64_t ts) "get feature timestamp = 0x%"PRIx64""
76
+ * @print_caption is true, a caption (including the list name, if it
222
nvme_mmio_intm_set(uint64_t data, uint64_t new_mask) "wrote MMIO, interrupt mask set, data=0x%"PRIx64", new_mask=0x%"PRIx64""
77
+ * exists) is printed. The options itself will be indented, so
223
nvme_mmio_intm_clr(uint64_t data, uint64_t new_mask) "wrote MMIO, interrupt mask clr, data=0x%"PRIx64", new_mask=0x%"PRIx64""
78
+ * @print_caption should only be set to false if the caller prints its
224
nvme_mmio_cfg(uint64_t data) "wrote MMIO, config controller config=0x%"PRIx64""
79
+ * own custom caption (so that the indentation makes sense).
80
+ */
81
+void qemu_opts_print_help(QemuOptsList *list, bool print_caption)
82
{
83
QemuOptDesc *desc;
84
int i;
85
@@ -XXX,XX +XXX,XX @@ void qemu_opts_print_help(QemuOptsList *list)
86
desc = list->desc;
87
while (desc && desc->name) {
88
GString *str = g_string_new(NULL);
89
- if (list->name) {
90
- g_string_append_printf(str, "%s.", list->name);
91
- }
92
- g_string_append_printf(str, "%s=%s", desc->name,
93
+ g_string_append_printf(str, " %s=<%s>", desc->name,
94
opt_type_to_string(desc->type));
95
if (desc->help) {
96
+ if (str->len < 24) {
97
+ g_string_append_printf(str, "%*s", 24 - (int)str->len, "");
98
+ }
99
g_string_append_printf(str, " - %s", desc->help);
100
}
101
g_ptr_array_add(array, g_string_free(str, false));
102
@@ -XXX,XX +XXX,XX @@ void qemu_opts_print_help(QemuOptsList *list)
103
}
104
105
g_ptr_array_sort(array, (GCompareFunc)qemu_pstrcmp0);
106
+ if (print_caption && array->len > 0) {
107
+ if (list->name) {
108
+ printf("%s options:\n", list->name);
109
+ } else {
110
+ printf("Options:\n");
111
+ }
112
+ } else if (array->len == 0) {
113
+ if (list->name) {
114
+ printf("There are no options for %s.\n", list->name);
115
+ } else {
116
+ printf("No options available.\n");
117
+ }
118
+ }
119
for (i = 0; i < array->len; i++) {
120
printf("%s\n", (char *)array->pdata[i]);
121
}
122
@@ -XXX,XX +XXX,XX @@ QemuOpts *qemu_opts_parse_noisily(QemuOptsList *list, const char *params,
123
opts = opts_parse(list, params, permit_abbrev, false, &invalidp, &err);
124
if (err) {
125
if (invalidp && has_help_option(params)) {
126
- qemu_opts_print_help(list);
127
+ qemu_opts_print_help(list, true);
128
error_free(err);
129
} else {
130
error_report_err(err);
131
diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out
132
index XXXXXXX..XXXXXXX 100644
133
--- a/tests/qemu-iotests/082.out
134
+++ b/tests/qemu-iotests/082.out
135
@@ -XXX,XX +XXX,XX @@ cluster_size: 8192
136
137
Testing: create -f qcow2 -o help TEST_DIR/t.qcow2 128M
138
Supported options:
139
-size Virtual disk size
140
-compat Compatibility level (0.10 or 1.1)
141
-backing_file File name of a base image
142
-backing_fmt Image format of the base image
143
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
144
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
145
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
146
-encrypt.cipher-alg Name of encryption cipher algorithm
147
-encrypt.cipher-mode Name of encryption cipher mode
148
-encrypt.ivgen-alg Name of IV generator algorithm
149
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
150
-encrypt.hash-alg Name of encryption hash algorithm
151
-encrypt.iter-time Time to spend in PBKDF in milliseconds
152
-cluster_size qcow2 cluster size
153
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
154
-lazy_refcounts Postpone refcount updates
155
-refcount_bits Width of a reference count entry in bits
156
-nocow Turn off copy-on-write (valid only on btrfs)
157
+ backing_file=<str> - File name of a base image
158
+ backing_fmt=<str> - Image format of the base image
159
+ cluster_size=<size> - qcow2 cluster size
160
+ compat=<str> - Compatibility level (0.10 or 1.1)
161
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
162
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
163
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
164
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
165
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
166
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
167
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
168
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
169
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
170
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
171
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
172
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
173
+ refcount_bits=<num> - Width of a reference count entry in bits
174
+ size=<size> - Virtual disk size
175
176
Testing: create -f qcow2 -o ? TEST_DIR/t.qcow2 128M
177
Supported options:
178
-size Virtual disk size
179
-compat Compatibility level (0.10 or 1.1)
180
-backing_file File name of a base image
181
-backing_fmt Image format of the base image
182
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
183
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
184
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
185
-encrypt.cipher-alg Name of encryption cipher algorithm
186
-encrypt.cipher-mode Name of encryption cipher mode
187
-encrypt.ivgen-alg Name of IV generator algorithm
188
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
189
-encrypt.hash-alg Name of encryption hash algorithm
190
-encrypt.iter-time Time to spend in PBKDF in milliseconds
191
-cluster_size qcow2 cluster size
192
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
193
-lazy_refcounts Postpone refcount updates
194
-refcount_bits Width of a reference count entry in bits
195
-nocow Turn off copy-on-write (valid only on btrfs)
196
+ backing_file=<str> - File name of a base image
197
+ backing_fmt=<str> - Image format of the base image
198
+ cluster_size=<size> - qcow2 cluster size
199
+ compat=<str> - Compatibility level (0.10 or 1.1)
200
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
201
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
202
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
203
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
204
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
205
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
206
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
207
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
208
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
209
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
210
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
211
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
212
+ refcount_bits=<num> - Width of a reference count entry in bits
213
+ size=<size> - Virtual disk size
214
215
Testing: create -f qcow2 -o cluster_size=4k,help TEST_DIR/t.qcow2 128M
216
Supported options:
217
-size Virtual disk size
218
-compat Compatibility level (0.10 or 1.1)
219
-backing_file File name of a base image
220
-backing_fmt Image format of the base image
221
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
222
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
223
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
224
-encrypt.cipher-alg Name of encryption cipher algorithm
225
-encrypt.cipher-mode Name of encryption cipher mode
226
-encrypt.ivgen-alg Name of IV generator algorithm
227
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
228
-encrypt.hash-alg Name of encryption hash algorithm
229
-encrypt.iter-time Time to spend in PBKDF in milliseconds
230
-cluster_size qcow2 cluster size
231
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
232
-lazy_refcounts Postpone refcount updates
233
-refcount_bits Width of a reference count entry in bits
234
-nocow Turn off copy-on-write (valid only on btrfs)
235
+ backing_file=<str> - File name of a base image
236
+ backing_fmt=<str> - Image format of the base image
237
+ cluster_size=<size> - qcow2 cluster size
238
+ compat=<str> - Compatibility level (0.10 or 1.1)
239
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
240
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
241
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
242
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
243
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
244
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
245
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
246
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
247
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
248
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
249
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
250
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
251
+ refcount_bits=<num> - Width of a reference count entry in bits
252
+ size=<size> - Virtual disk size
253
254
Testing: create -f qcow2 -o cluster_size=4k,? TEST_DIR/t.qcow2 128M
255
Supported options:
256
-size Virtual disk size
257
-compat Compatibility level (0.10 or 1.1)
258
-backing_file File name of a base image
259
-backing_fmt Image format of the base image
260
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
261
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
262
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
263
-encrypt.cipher-alg Name of encryption cipher algorithm
264
-encrypt.cipher-mode Name of encryption cipher mode
265
-encrypt.ivgen-alg Name of IV generator algorithm
266
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
267
-encrypt.hash-alg Name of encryption hash algorithm
268
-encrypt.iter-time Time to spend in PBKDF in milliseconds
269
-cluster_size qcow2 cluster size
270
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
271
-lazy_refcounts Postpone refcount updates
272
-refcount_bits Width of a reference count entry in bits
273
-nocow Turn off copy-on-write (valid only on btrfs)
274
+ backing_file=<str> - File name of a base image
275
+ backing_fmt=<str> - Image format of the base image
276
+ cluster_size=<size> - qcow2 cluster size
277
+ compat=<str> - Compatibility level (0.10 or 1.1)
278
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
279
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
280
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
281
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
282
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
283
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
284
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
285
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
286
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
287
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
288
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
289
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
290
+ refcount_bits=<num> - Width of a reference count entry in bits
291
+ size=<size> - Virtual disk size
292
293
Testing: create -f qcow2 -o help,cluster_size=4k TEST_DIR/t.qcow2 128M
294
Supported options:
295
-size Virtual disk size
296
-compat Compatibility level (0.10 or 1.1)
297
-backing_file File name of a base image
298
-backing_fmt Image format of the base image
299
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
300
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
301
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
302
-encrypt.cipher-alg Name of encryption cipher algorithm
303
-encrypt.cipher-mode Name of encryption cipher mode
304
-encrypt.ivgen-alg Name of IV generator algorithm
305
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
306
-encrypt.hash-alg Name of encryption hash algorithm
307
-encrypt.iter-time Time to spend in PBKDF in milliseconds
308
-cluster_size qcow2 cluster size
309
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
310
-lazy_refcounts Postpone refcount updates
311
-refcount_bits Width of a reference count entry in bits
312
-nocow Turn off copy-on-write (valid only on btrfs)
313
+ backing_file=<str> - File name of a base image
314
+ backing_fmt=<str> - Image format of the base image
315
+ cluster_size=<size> - qcow2 cluster size
316
+ compat=<str> - Compatibility level (0.10 or 1.1)
317
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
318
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
319
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
320
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
321
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
322
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
323
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
324
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
325
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
326
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
327
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
328
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
329
+ refcount_bits=<num> - Width of a reference count entry in bits
330
+ size=<size> - Virtual disk size
331
332
Testing: create -f qcow2 -o ?,cluster_size=4k TEST_DIR/t.qcow2 128M
333
Supported options:
334
-size Virtual disk size
335
-compat Compatibility level (0.10 or 1.1)
336
-backing_file File name of a base image
337
-backing_fmt Image format of the base image
338
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
339
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
340
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
341
-encrypt.cipher-alg Name of encryption cipher algorithm
342
-encrypt.cipher-mode Name of encryption cipher mode
343
-encrypt.ivgen-alg Name of IV generator algorithm
344
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
345
-encrypt.hash-alg Name of encryption hash algorithm
346
-encrypt.iter-time Time to spend in PBKDF in milliseconds
347
-cluster_size qcow2 cluster size
348
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
349
-lazy_refcounts Postpone refcount updates
350
-refcount_bits Width of a reference count entry in bits
351
-nocow Turn off copy-on-write (valid only on btrfs)
352
+ backing_file=<str> - File name of a base image
353
+ backing_fmt=<str> - Image format of the base image
354
+ cluster_size=<size> - qcow2 cluster size
355
+ compat=<str> - Compatibility level (0.10 or 1.1)
356
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
357
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
358
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
359
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
360
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
361
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
362
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
363
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
364
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
365
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
366
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
367
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
368
+ refcount_bits=<num> - Width of a reference count entry in bits
369
+ size=<size> - Virtual disk size
370
371
Testing: create -f qcow2 -o cluster_size=4k -o help TEST_DIR/t.qcow2 128M
372
Supported options:
373
-size Virtual disk size
374
-compat Compatibility level (0.10 or 1.1)
375
-backing_file File name of a base image
376
-backing_fmt Image format of the base image
377
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
378
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
379
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
380
-encrypt.cipher-alg Name of encryption cipher algorithm
381
-encrypt.cipher-mode Name of encryption cipher mode
382
-encrypt.ivgen-alg Name of IV generator algorithm
383
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
384
-encrypt.hash-alg Name of encryption hash algorithm
385
-encrypt.iter-time Time to spend in PBKDF in milliseconds
386
-cluster_size qcow2 cluster size
387
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
388
-lazy_refcounts Postpone refcount updates
389
-refcount_bits Width of a reference count entry in bits
390
-nocow Turn off copy-on-write (valid only on btrfs)
391
+ backing_file=<str> - File name of a base image
392
+ backing_fmt=<str> - Image format of the base image
393
+ cluster_size=<size> - qcow2 cluster size
394
+ compat=<str> - Compatibility level (0.10 or 1.1)
395
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
396
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
397
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
398
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
399
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
400
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
401
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
402
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
403
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
404
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
405
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
406
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
407
+ refcount_bits=<num> - Width of a reference count entry in bits
408
+ size=<size> - Virtual disk size
409
410
Testing: create -f qcow2 -o cluster_size=4k -o ? TEST_DIR/t.qcow2 128M
411
Supported options:
412
-size Virtual disk size
413
-compat Compatibility level (0.10 or 1.1)
414
-backing_file File name of a base image
415
-backing_fmt Image format of the base image
416
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
417
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
418
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
419
-encrypt.cipher-alg Name of encryption cipher algorithm
420
-encrypt.cipher-mode Name of encryption cipher mode
421
-encrypt.ivgen-alg Name of IV generator algorithm
422
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
423
-encrypt.hash-alg Name of encryption hash algorithm
424
-encrypt.iter-time Time to spend in PBKDF in milliseconds
425
-cluster_size qcow2 cluster size
426
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
427
-lazy_refcounts Postpone refcount updates
428
-refcount_bits Width of a reference count entry in bits
429
-nocow Turn off copy-on-write (valid only on btrfs)
430
+ backing_file=<str> - File name of a base image
431
+ backing_fmt=<str> - Image format of the base image
432
+ cluster_size=<size> - qcow2 cluster size
433
+ compat=<str> - Compatibility level (0.10 or 1.1)
434
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
435
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
436
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
437
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
438
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
439
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
440
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
441
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
442
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
443
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
444
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
445
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
446
+ refcount_bits=<num> - Width of a reference count entry in bits
447
+ size=<size> - Virtual disk size
448
449
Testing: create -f qcow2 -u -o backing_file=TEST_DIR/t.qcow2,,help TEST_DIR/t.qcow2 128M
450
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2,,help cluster_size=65536 lazy_refcounts=off refcount_bits=16
451
@@ -XXX,XX +XXX,XX @@ qemu-img: Invalid option list: ,,
452
453
Testing: create -f qcow2 -o help
454
Supported options:
455
-size Virtual disk size
456
-compat Compatibility level (0.10 or 1.1)
457
-backing_file File name of a base image
458
-backing_fmt Image format of the base image
459
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
460
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
461
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
462
-encrypt.cipher-alg Name of encryption cipher algorithm
463
-encrypt.cipher-mode Name of encryption cipher mode
464
-encrypt.ivgen-alg Name of IV generator algorithm
465
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
466
-encrypt.hash-alg Name of encryption hash algorithm
467
-encrypt.iter-time Time to spend in PBKDF in milliseconds
468
-cluster_size qcow2 cluster size
469
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
470
-lazy_refcounts Postpone refcount updates
471
-refcount_bits Width of a reference count entry in bits
472
+ backing_file=<str> - File name of a base image
473
+ backing_fmt=<str> - Image format of the base image
474
+ cluster_size=<size> - qcow2 cluster size
475
+ compat=<str> - Compatibility level (0.10 or 1.1)
476
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
477
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
478
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
479
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
480
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
481
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
482
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
483
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
484
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
485
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
486
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
487
+ refcount_bits=<num> - Width of a reference count entry in bits
488
+ size=<size> - Virtual disk size
489
490
Testing: create -o help
491
Supported options:
492
-size Virtual disk size
493
+ size=<size> - Virtual disk size
494
495
Testing: create -f bochs -o help
496
qemu-img: Format driver 'bochs' does not support image creation
497
@@ -XXX,XX +XXX,XX @@ cluster_size: 8192
498
499
Testing: convert -O qcow2 -o help TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
500
Supported options:
501
-size Virtual disk size
502
-compat Compatibility level (0.10 or 1.1)
503
-backing_file File name of a base image
504
-backing_fmt Image format of the base image
505
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
506
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
507
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
508
-encrypt.cipher-alg Name of encryption cipher algorithm
509
-encrypt.cipher-mode Name of encryption cipher mode
510
-encrypt.ivgen-alg Name of IV generator algorithm
511
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
512
-encrypt.hash-alg Name of encryption hash algorithm
513
-encrypt.iter-time Time to spend in PBKDF in milliseconds
514
-cluster_size qcow2 cluster size
515
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
516
-lazy_refcounts Postpone refcount updates
517
-refcount_bits Width of a reference count entry in bits
518
-nocow Turn off copy-on-write (valid only on btrfs)
519
+ backing_file=<str> - File name of a base image
520
+ backing_fmt=<str> - Image format of the base image
521
+ cluster_size=<size> - qcow2 cluster size
522
+ compat=<str> - Compatibility level (0.10 or 1.1)
523
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
524
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
525
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
526
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
527
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
528
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
529
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
530
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
531
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
532
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
533
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
534
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
535
+ refcount_bits=<num> - Width of a reference count entry in bits
536
+ size=<size> - Virtual disk size
537
538
Testing: convert -O qcow2 -o ? TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
539
Supported options:
540
-size Virtual disk size
541
-compat Compatibility level (0.10 or 1.1)
542
-backing_file File name of a base image
543
-backing_fmt Image format of the base image
544
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
545
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
546
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
547
-encrypt.cipher-alg Name of encryption cipher algorithm
548
-encrypt.cipher-mode Name of encryption cipher mode
549
-encrypt.ivgen-alg Name of IV generator algorithm
550
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
551
-encrypt.hash-alg Name of encryption hash algorithm
552
-encrypt.iter-time Time to spend in PBKDF in milliseconds
553
-cluster_size qcow2 cluster size
554
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
555
-lazy_refcounts Postpone refcount updates
556
-refcount_bits Width of a reference count entry in bits
557
-nocow Turn off copy-on-write (valid only on btrfs)
558
+ backing_file=<str> - File name of a base image
559
+ backing_fmt=<str> - Image format of the base image
560
+ cluster_size=<size> - qcow2 cluster size
561
+ compat=<str> - Compatibility level (0.10 or 1.1)
562
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
563
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
564
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
565
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
566
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
567
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
568
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
569
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
570
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
571
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
572
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
573
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
574
+ refcount_bits=<num> - Width of a reference count entry in bits
575
+ size=<size> - Virtual disk size
576
577
Testing: convert -O qcow2 -o cluster_size=4k,help TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
578
Supported options:
579
-size Virtual disk size
580
-compat Compatibility level (0.10 or 1.1)
581
-backing_file File name of a base image
582
-backing_fmt Image format of the base image
583
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
584
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
585
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
586
-encrypt.cipher-alg Name of encryption cipher algorithm
587
-encrypt.cipher-mode Name of encryption cipher mode
588
-encrypt.ivgen-alg Name of IV generator algorithm
589
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
590
-encrypt.hash-alg Name of encryption hash algorithm
591
-encrypt.iter-time Time to spend in PBKDF in milliseconds
592
-cluster_size qcow2 cluster size
593
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
594
-lazy_refcounts Postpone refcount updates
595
-refcount_bits Width of a reference count entry in bits
596
-nocow Turn off copy-on-write (valid only on btrfs)
597
+ backing_file=<str> - File name of a base image
598
+ backing_fmt=<str> - Image format of the base image
599
+ cluster_size=<size> - qcow2 cluster size
600
+ compat=<str> - Compatibility level (0.10 or 1.1)
601
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
602
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
603
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
604
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
605
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
606
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
607
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
608
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
609
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
610
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
611
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
612
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
613
+ refcount_bits=<num> - Width of a reference count entry in bits
614
+ size=<size> - Virtual disk size
615
616
Testing: convert -O qcow2 -o cluster_size=4k,? TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
617
Supported options:
618
-size Virtual disk size
619
-compat Compatibility level (0.10 or 1.1)
620
-backing_file File name of a base image
621
-backing_fmt Image format of the base image
622
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
623
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
624
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
625
-encrypt.cipher-alg Name of encryption cipher algorithm
626
-encrypt.cipher-mode Name of encryption cipher mode
627
-encrypt.ivgen-alg Name of IV generator algorithm
628
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
629
-encrypt.hash-alg Name of encryption hash algorithm
630
-encrypt.iter-time Time to spend in PBKDF in milliseconds
631
-cluster_size qcow2 cluster size
632
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
633
-lazy_refcounts Postpone refcount updates
634
-refcount_bits Width of a reference count entry in bits
635
-nocow Turn off copy-on-write (valid only on btrfs)
636
+ backing_file=<str> - File name of a base image
637
+ backing_fmt=<str> - Image format of the base image
638
+ cluster_size=<size> - qcow2 cluster size
639
+ compat=<str> - Compatibility level (0.10 or 1.1)
640
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
641
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
642
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
643
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
644
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
645
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
646
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
647
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
648
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
649
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
650
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
651
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
652
+ refcount_bits=<num> - Width of a reference count entry in bits
653
+ size=<size> - Virtual disk size
654
655
Testing: convert -O qcow2 -o help,cluster_size=4k TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
656
Supported options:
657
-size Virtual disk size
658
-compat Compatibility level (0.10 or 1.1)
659
-backing_file File name of a base image
660
-backing_fmt Image format of the base image
661
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
662
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
663
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
664
-encrypt.cipher-alg Name of encryption cipher algorithm
665
-encrypt.cipher-mode Name of encryption cipher mode
666
-encrypt.ivgen-alg Name of IV generator algorithm
667
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
668
-encrypt.hash-alg Name of encryption hash algorithm
669
-encrypt.iter-time Time to spend in PBKDF in milliseconds
670
-cluster_size qcow2 cluster size
671
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
672
-lazy_refcounts Postpone refcount updates
673
-refcount_bits Width of a reference count entry in bits
674
-nocow Turn off copy-on-write (valid only on btrfs)
675
+ backing_file=<str> - File name of a base image
676
+ backing_fmt=<str> - Image format of the base image
677
+ cluster_size=<size> - qcow2 cluster size
678
+ compat=<str> - Compatibility level (0.10 or 1.1)
679
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
680
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
681
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
682
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
683
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
684
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
685
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
686
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
687
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
688
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
689
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
690
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
691
+ refcount_bits=<num> - Width of a reference count entry in bits
692
+ size=<size> - Virtual disk size
693
694
Testing: convert -O qcow2 -o ?,cluster_size=4k TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
695
Supported options:
696
-size Virtual disk size
697
-compat Compatibility level (0.10 or 1.1)
698
-backing_file File name of a base image
699
-backing_fmt Image format of the base image
700
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
701
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
702
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
703
-encrypt.cipher-alg Name of encryption cipher algorithm
704
-encrypt.cipher-mode Name of encryption cipher mode
705
-encrypt.ivgen-alg Name of IV generator algorithm
706
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
707
-encrypt.hash-alg Name of encryption hash algorithm
708
-encrypt.iter-time Time to spend in PBKDF in milliseconds
709
-cluster_size qcow2 cluster size
710
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
711
-lazy_refcounts Postpone refcount updates
712
-refcount_bits Width of a reference count entry in bits
713
-nocow Turn off copy-on-write (valid only on btrfs)
714
+ backing_file=<str> - File name of a base image
715
+ backing_fmt=<str> - Image format of the base image
716
+ cluster_size=<size> - qcow2 cluster size
717
+ compat=<str> - Compatibility level (0.10 or 1.1)
718
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
719
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
720
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
721
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
722
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
723
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
724
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
725
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
726
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
727
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
728
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
729
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
730
+ refcount_bits=<num> - Width of a reference count entry in bits
731
+ size=<size> - Virtual disk size
732
733
Testing: convert -O qcow2 -o cluster_size=4k -o help TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
734
Supported options:
735
-size Virtual disk size
736
-compat Compatibility level (0.10 or 1.1)
737
-backing_file File name of a base image
738
-backing_fmt Image format of the base image
739
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
740
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
741
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
742
-encrypt.cipher-alg Name of encryption cipher algorithm
743
-encrypt.cipher-mode Name of encryption cipher mode
744
-encrypt.ivgen-alg Name of IV generator algorithm
745
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
746
-encrypt.hash-alg Name of encryption hash algorithm
747
-encrypt.iter-time Time to spend in PBKDF in milliseconds
748
-cluster_size qcow2 cluster size
749
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
750
-lazy_refcounts Postpone refcount updates
751
-refcount_bits Width of a reference count entry in bits
752
-nocow Turn off copy-on-write (valid only on btrfs)
753
+ backing_file=<str> - File name of a base image
754
+ backing_fmt=<str> - Image format of the base image
755
+ cluster_size=<size> - qcow2 cluster size
756
+ compat=<str> - Compatibility level (0.10 or 1.1)
757
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
758
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
759
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
760
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
761
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
762
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
763
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
764
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
765
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
766
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
767
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
768
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
769
+ refcount_bits=<num> - Width of a reference count entry in bits
770
+ size=<size> - Virtual disk size
771
772
Testing: convert -O qcow2 -o cluster_size=4k -o ? TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
773
Supported options:
774
-size Virtual disk size
775
-compat Compatibility level (0.10 or 1.1)
776
-backing_file File name of a base image
777
-backing_fmt Image format of the base image
778
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
779
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
780
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
781
-encrypt.cipher-alg Name of encryption cipher algorithm
782
-encrypt.cipher-mode Name of encryption cipher mode
783
-encrypt.ivgen-alg Name of IV generator algorithm
784
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
785
-encrypt.hash-alg Name of encryption hash algorithm
786
-encrypt.iter-time Time to spend in PBKDF in milliseconds
787
-cluster_size qcow2 cluster size
788
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
789
-lazy_refcounts Postpone refcount updates
790
-refcount_bits Width of a reference count entry in bits
791
-nocow Turn off copy-on-write (valid only on btrfs)
792
+ backing_file=<str> - File name of a base image
793
+ backing_fmt=<str> - Image format of the base image
794
+ cluster_size=<size> - qcow2 cluster size
795
+ compat=<str> - Compatibility level (0.10 or 1.1)
796
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
797
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
798
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
799
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
800
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
801
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
802
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
803
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
804
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
805
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
806
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
807
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
808
+ refcount_bits=<num> - Width of a reference count entry in bits
809
+ size=<size> - Virtual disk size
810
811
Testing: convert -O qcow2 -o backing_file=TEST_DIR/t.qcow2,,help TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
812
qemu-img: Could not open 'TEST_DIR/t.qcow2.base': Could not open backing file: Could not open 'TEST_DIR/t.qcow2,help': No such file or directory
813
@@ -XXX,XX +XXX,XX @@ qemu-img: Invalid option list: ,,
814
815
Testing: convert -O qcow2 -o help
816
Supported options:
817
-size Virtual disk size
818
-compat Compatibility level (0.10 or 1.1)
819
-backing_file File name of a base image
820
-backing_fmt Image format of the base image
821
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
822
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
823
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
824
-encrypt.cipher-alg Name of encryption cipher algorithm
825
-encrypt.cipher-mode Name of encryption cipher mode
826
-encrypt.ivgen-alg Name of IV generator algorithm
827
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
828
-encrypt.hash-alg Name of encryption hash algorithm
829
-encrypt.iter-time Time to spend in PBKDF in milliseconds
830
-cluster_size qcow2 cluster size
831
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
832
-lazy_refcounts Postpone refcount updates
833
-refcount_bits Width of a reference count entry in bits
834
+ backing_file=<str> - File name of a base image
835
+ backing_fmt=<str> - Image format of the base image
836
+ cluster_size=<size> - qcow2 cluster size
837
+ compat=<str> - Compatibility level (0.10 or 1.1)
838
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
839
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
840
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
841
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
842
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
843
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
844
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
845
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
846
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
847
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
848
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
849
+ refcount_bits=<num> - Width of a reference count entry in bits
850
+ size=<size> - Virtual disk size
851
852
Testing: convert -o help
853
Supported options:
854
-size Virtual disk size
855
+ size=<size> - Virtual disk size
856
857
Testing: convert -O bochs -o help
858
qemu-img: Format driver 'bochs' does not support image creation
859
@@ -XXX,XX +XXX,XX @@ cluster_size: 65536
860
861
Testing: amend -f qcow2 -o help TEST_DIR/t.qcow2
862
Creation options for 'qcow2':
863
-size Virtual disk size
864
-compat Compatibility level (0.10 or 1.1)
865
-backing_file File name of a base image
866
-backing_fmt Image format of the base image
867
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
868
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
869
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
870
-encrypt.cipher-alg Name of encryption cipher algorithm
871
-encrypt.cipher-mode Name of encryption cipher mode
872
-encrypt.ivgen-alg Name of IV generator algorithm
873
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
874
-encrypt.hash-alg Name of encryption hash algorithm
875
-encrypt.iter-time Time to spend in PBKDF in milliseconds
876
-cluster_size qcow2 cluster size
877
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
878
-lazy_refcounts Postpone refcount updates
879
-refcount_bits Width of a reference count entry in bits
880
+ backing_file=<str> - File name of a base image
881
+ backing_fmt=<str> - Image format of the base image
882
+ cluster_size=<size> - qcow2 cluster size
883
+ compat=<str> - Compatibility level (0.10 or 1.1)
884
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
885
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
886
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
887
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
888
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
889
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
890
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
891
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
892
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
893
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
894
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
895
+ refcount_bits=<num> - Width of a reference count entry in bits
896
+ size=<size> - Virtual disk size
897
898
Note that not all of these options may be amendable.
899
900
Testing: amend -f qcow2 -o ? TEST_DIR/t.qcow2
901
Creation options for 'qcow2':
902
-size Virtual disk size
903
-compat Compatibility level (0.10 or 1.1)
904
-backing_file File name of a base image
905
-backing_fmt Image format of the base image
906
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
907
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
908
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
909
-encrypt.cipher-alg Name of encryption cipher algorithm
910
-encrypt.cipher-mode Name of encryption cipher mode
911
-encrypt.ivgen-alg Name of IV generator algorithm
912
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
913
-encrypt.hash-alg Name of encryption hash algorithm
914
-encrypt.iter-time Time to spend in PBKDF in milliseconds
915
-cluster_size qcow2 cluster size
916
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
917
-lazy_refcounts Postpone refcount updates
918
-refcount_bits Width of a reference count entry in bits
919
+ backing_file=<str> - File name of a base image
920
+ backing_fmt=<str> - Image format of the base image
921
+ cluster_size=<size> - qcow2 cluster size
922
+ compat=<str> - Compatibility level (0.10 or 1.1)
923
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
924
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
925
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
926
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
927
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
928
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
929
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
930
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
931
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
932
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
933
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
934
+ refcount_bits=<num> - Width of a reference count entry in bits
935
+ size=<size> - Virtual disk size
936
937
Note that not all of these options may be amendable.
938
939
Testing: amend -f qcow2 -o cluster_size=4k,help TEST_DIR/t.qcow2
940
Creation options for 'qcow2':
941
-size Virtual disk size
942
-compat Compatibility level (0.10 or 1.1)
943
-backing_file File name of a base image
944
-backing_fmt Image format of the base image
945
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
946
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
947
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
948
-encrypt.cipher-alg Name of encryption cipher algorithm
949
-encrypt.cipher-mode Name of encryption cipher mode
950
-encrypt.ivgen-alg Name of IV generator algorithm
951
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
952
-encrypt.hash-alg Name of encryption hash algorithm
953
-encrypt.iter-time Time to spend in PBKDF in milliseconds
954
-cluster_size qcow2 cluster size
955
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
956
-lazy_refcounts Postpone refcount updates
957
-refcount_bits Width of a reference count entry in bits
958
+ backing_file=<str> - File name of a base image
959
+ backing_fmt=<str> - Image format of the base image
960
+ cluster_size=<size> - qcow2 cluster size
961
+ compat=<str> - Compatibility level (0.10 or 1.1)
962
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
963
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
964
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
965
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
966
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
967
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
968
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
969
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
970
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
971
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
972
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
973
+ refcount_bits=<num> - Width of a reference count entry in bits
974
+ size=<size> - Virtual disk size
975
976
Note that not all of these options may be amendable.
977
978
Testing: amend -f qcow2 -o cluster_size=4k,? TEST_DIR/t.qcow2
979
Creation options for 'qcow2':
980
-size Virtual disk size
981
-compat Compatibility level (0.10 or 1.1)
982
-backing_file File name of a base image
983
-backing_fmt Image format of the base image
984
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
985
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
986
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
987
-encrypt.cipher-alg Name of encryption cipher algorithm
988
-encrypt.cipher-mode Name of encryption cipher mode
989
-encrypt.ivgen-alg Name of IV generator algorithm
990
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
991
-encrypt.hash-alg Name of encryption hash algorithm
992
-encrypt.iter-time Time to spend in PBKDF in milliseconds
993
-cluster_size qcow2 cluster size
994
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
995
-lazy_refcounts Postpone refcount updates
996
-refcount_bits Width of a reference count entry in bits
997
+ backing_file=<str> - File name of a base image
998
+ backing_fmt=<str> - Image format of the base image
999
+ cluster_size=<size> - qcow2 cluster size
1000
+ compat=<str> - Compatibility level (0.10 or 1.1)
1001
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1002
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1003
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1004
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1005
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1006
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1007
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1008
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1009
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1010
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1011
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1012
+ refcount_bits=<num> - Width of a reference count entry in bits
1013
+ size=<size> - Virtual disk size
1014
1015
Note that not all of these options may be amendable.
1016
1017
Testing: amend -f qcow2 -o help,cluster_size=4k TEST_DIR/t.qcow2
1018
Creation options for 'qcow2':
1019
-size Virtual disk size
1020
-compat Compatibility level (0.10 or 1.1)
1021
-backing_file File name of a base image
1022
-backing_fmt Image format of the base image
1023
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1024
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
1025
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
1026
-encrypt.cipher-alg Name of encryption cipher algorithm
1027
-encrypt.cipher-mode Name of encryption cipher mode
1028
-encrypt.ivgen-alg Name of IV generator algorithm
1029
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
1030
-encrypt.hash-alg Name of encryption hash algorithm
1031
-encrypt.iter-time Time to spend in PBKDF in milliseconds
1032
-cluster_size qcow2 cluster size
1033
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
1034
-lazy_refcounts Postpone refcount updates
1035
-refcount_bits Width of a reference count entry in bits
1036
+ backing_file=<str> - File name of a base image
1037
+ backing_fmt=<str> - Image format of the base image
1038
+ cluster_size=<size> - qcow2 cluster size
1039
+ compat=<str> - Compatibility level (0.10 or 1.1)
1040
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1041
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1042
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1043
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1044
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1045
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1046
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1047
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1048
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1049
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1050
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1051
+ refcount_bits=<num> - Width of a reference count entry in bits
1052
+ size=<size> - Virtual disk size
1053
1054
Note that not all of these options may be amendable.
1055
1056
Testing: amend -f qcow2 -o ?,cluster_size=4k TEST_DIR/t.qcow2
1057
Creation options for 'qcow2':
1058
-size Virtual disk size
1059
-compat Compatibility level (0.10 or 1.1)
1060
-backing_file File name of a base image
1061
-backing_fmt Image format of the base image
1062
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1063
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
1064
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
1065
-encrypt.cipher-alg Name of encryption cipher algorithm
1066
-encrypt.cipher-mode Name of encryption cipher mode
1067
-encrypt.ivgen-alg Name of IV generator algorithm
1068
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
1069
-encrypt.hash-alg Name of encryption hash algorithm
1070
-encrypt.iter-time Time to spend in PBKDF in milliseconds
1071
-cluster_size qcow2 cluster size
1072
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
1073
-lazy_refcounts Postpone refcount updates
1074
-refcount_bits Width of a reference count entry in bits
1075
+ backing_file=<str> - File name of a base image
1076
+ backing_fmt=<str> - Image format of the base image
1077
+ cluster_size=<size> - qcow2 cluster size
1078
+ compat=<str> - Compatibility level (0.10 or 1.1)
1079
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1080
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1081
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1082
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1083
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1084
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1085
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1086
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1087
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1088
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1089
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1090
+ refcount_bits=<num> - Width of a reference count entry in bits
1091
+ size=<size> - Virtual disk size
1092
1093
Note that not all of these options may be amendable.
1094
1095
Testing: amend -f qcow2 -o cluster_size=4k -o help TEST_DIR/t.qcow2
1096
Creation options for 'qcow2':
1097
-size Virtual disk size
1098
-compat Compatibility level (0.10 or 1.1)
1099
-backing_file File name of a base image
1100
-backing_fmt Image format of the base image
1101
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1102
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
1103
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
1104
-encrypt.cipher-alg Name of encryption cipher algorithm
1105
-encrypt.cipher-mode Name of encryption cipher mode
1106
-encrypt.ivgen-alg Name of IV generator algorithm
1107
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
1108
-encrypt.hash-alg Name of encryption hash algorithm
1109
-encrypt.iter-time Time to spend in PBKDF in milliseconds
1110
-cluster_size qcow2 cluster size
1111
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
1112
-lazy_refcounts Postpone refcount updates
1113
-refcount_bits Width of a reference count entry in bits
1114
+ backing_file=<str> - File name of a base image
1115
+ backing_fmt=<str> - Image format of the base image
1116
+ cluster_size=<size> - qcow2 cluster size
1117
+ compat=<str> - Compatibility level (0.10 or 1.1)
1118
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1119
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1120
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1121
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1122
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1123
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1124
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1125
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1126
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1127
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1128
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1129
+ refcount_bits=<num> - Width of a reference count entry in bits
1130
+ size=<size> - Virtual disk size
1131
1132
Note that not all of these options may be amendable.
1133
1134
Testing: amend -f qcow2 -o cluster_size=4k -o ? TEST_DIR/t.qcow2
1135
Creation options for 'qcow2':
1136
-size Virtual disk size
1137
-compat Compatibility level (0.10 or 1.1)
1138
-backing_file File name of a base image
1139
-backing_fmt Image format of the base image
1140
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1141
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
1142
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
1143
-encrypt.cipher-alg Name of encryption cipher algorithm
1144
-encrypt.cipher-mode Name of encryption cipher mode
1145
-encrypt.ivgen-alg Name of IV generator algorithm
1146
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
1147
-encrypt.hash-alg Name of encryption hash algorithm
1148
-encrypt.iter-time Time to spend in PBKDF in milliseconds
1149
-cluster_size qcow2 cluster size
1150
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
1151
-lazy_refcounts Postpone refcount updates
1152
-refcount_bits Width of a reference count entry in bits
1153
+ backing_file=<str> - File name of a base image
1154
+ backing_fmt=<str> - Image format of the base image
1155
+ cluster_size=<size> - qcow2 cluster size
1156
+ compat=<str> - Compatibility level (0.10 or 1.1)
1157
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1158
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1159
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1160
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1161
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1162
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1163
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1164
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1165
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1166
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1167
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1168
+ refcount_bits=<num> - Width of a reference count entry in bits
1169
+ size=<size> - Virtual disk size
1170
1171
Note that not all of these options may be amendable.
1172
1173
@@ -XXX,XX +XXX,XX @@ qemu-img: Invalid option list: ,,
1174
1175
Testing: amend -f qcow2 -o help
1176
Creation options for 'qcow2':
1177
-size Virtual disk size
1178
-compat Compatibility level (0.10 or 1.1)
1179
-backing_file File name of a base image
1180
-backing_fmt Image format of the base image
1181
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1182
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
1183
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
1184
-encrypt.cipher-alg Name of encryption cipher algorithm
1185
-encrypt.cipher-mode Name of encryption cipher mode
1186
-encrypt.ivgen-alg Name of IV generator algorithm
1187
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
1188
-encrypt.hash-alg Name of encryption hash algorithm
1189
-encrypt.iter-time Time to spend in PBKDF in milliseconds
1190
-cluster_size qcow2 cluster size
1191
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
1192
-lazy_refcounts Postpone refcount updates
1193
-refcount_bits Width of a reference count entry in bits
1194
+ backing_file=<str> - File name of a base image
1195
+ backing_fmt=<str> - Image format of the base image
1196
+ cluster_size=<size> - qcow2 cluster size
1197
+ compat=<str> - Compatibility level (0.10 or 1.1)
1198
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1199
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1200
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1201
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1202
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1203
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1204
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1205
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1206
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1207
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1208
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1209
+ refcount_bits=<num> - Width of a reference count entry in bits
1210
+ size=<size> - Virtual disk size
1211
1212
Note that not all of these options may be amendable.
1213
1214
Testing: convert -o help
1215
Supported options:
1216
-size Virtual disk size
1217
+ size=<size> - Virtual disk size
1218
1219
Testing: amend -f bochs -o help
1220
qemu-img: Format driver 'bochs' does not support option amendment
1221
--
225
--
1222
2.19.1
226
2.20.1
1223
227
1224
228
diff view generated by jsdifflib
1
If read-only=off, but auto-read-only=on is given, open the volume
1
Just make the test cover the AioContext of the filter node as well.
2
read-write if we have the permissions, but instead of erroring out for
3
read-only volumes, just degrade to read-only.
4
2
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
3
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
4
Reviewed-by: Eric Blake <eblake@redhat.com>
7
---
5
---
8
block/iscsi.c | 8 +++++---
6
tests/test-block-iothread.c | 7 ++++++-
9
1 file changed, 5 insertions(+), 3 deletions(-)
7
1 file changed, 6 insertions(+), 1 deletion(-)
10
8
11
diff --git a/block/iscsi.c b/block/iscsi.c
9
diff --git a/tests/test-block-iothread.c b/tests/test-block-iothread.c
12
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
13
--- a/block/iscsi.c
11
--- a/tests/test-block-iothread.c
14
+++ b/block/iscsi.c
12
+++ b/tests/test-block-iothread.c
15
@@ -XXX,XX +XXX,XX @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
13
@@ -XXX,XX +XXX,XX @@ static void test_propagate_mirror(void)
16
/* Check the write protect flag of the LUN if we want to write */
14
IOThread *iothread = iothread_new();
17
if (iscsilun->type == TYPE_DISK && (flags & BDRV_O_RDWR) &&
15
AioContext *ctx = iothread_get_aio_context(iothread);
18
iscsilun->write_protected) {
16
AioContext *main_ctx = qemu_get_aio_context();
19
- error_setg(errp, "Cannot open a write protected LUN as read-write");
17
- BlockDriverState *src, *target;
20
- ret = -EACCES;
18
+ BlockDriverState *src, *target, *filter;
21
- goto out;
19
BlockBackend *blk;
22
+ ret = bdrv_apply_auto_read_only(bs, "LUN is write protected", errp);
20
Job *job;
23
+ if (ret < 0) {
21
Error *local_err = NULL;
24
+ goto out;
22
@@ -XXX,XX +XXX,XX @@ static void test_propagate_mirror(void)
25
+ }
23
false, "filter_node", MIRROR_COPY_MODE_BACKGROUND,
26
+ flags &= ~BDRV_O_RDWR;
24
&error_abort);
27
}
25
job = job_get("job0");
28
26
+ filter = bdrv_find_node("filter_node");
29
iscsi_readcapacity_sync(iscsilun, &local_err);
27
28
/* Change the AioContext of src */
29
bdrv_try_set_aio_context(src, ctx, &error_abort);
30
g_assert(bdrv_get_aio_context(src) == ctx);
31
g_assert(bdrv_get_aio_context(target) == ctx);
32
+ g_assert(bdrv_get_aio_context(filter) == ctx);
33
g_assert(job->aio_context == ctx);
34
35
/* Change the AioContext of target */
36
@@ -XXX,XX +XXX,XX @@ static void test_propagate_mirror(void)
37
aio_context_release(ctx);
38
g_assert(bdrv_get_aio_context(src) == main_ctx);
39
g_assert(bdrv_get_aio_context(target) == main_ctx);
40
+ g_assert(bdrv_get_aio_context(filter) == main_ctx);
41
42
/* With a BlockBackend on src, changing target must fail */
43
blk = blk_new(0, BLK_PERM_ALL);
44
@@ -XXX,XX +XXX,XX @@ static void test_propagate_mirror(void)
45
g_assert(blk_get_aio_context(blk) == main_ctx);
46
g_assert(bdrv_get_aio_context(src) == main_ctx);
47
g_assert(bdrv_get_aio_context(target) == main_ctx);
48
+ g_assert(bdrv_get_aio_context(filter) == main_ctx);
49
50
/* ...unless we explicitly allow it */
51
aio_context_acquire(ctx);
52
@@ -XXX,XX +XXX,XX @@ static void test_propagate_mirror(void)
53
g_assert(blk_get_aio_context(blk) == ctx);
54
g_assert(bdrv_get_aio_context(src) == ctx);
55
g_assert(bdrv_get_aio_context(target) == ctx);
56
+ g_assert(bdrv_get_aio_context(filter) == ctx);
57
58
job_cancel_sync_all();
59
30
--
60
--
31
2.19.1
61
2.20.1
32
62
33
63
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
The NBD server uses an AioContext notifier, so it can tolerate that its
2
BlockBackend is switched to a different AioContext. Before we start
3
actually calling bdrv_try_set_aio_context(), which checks for
4
consistency, outside of test cases, we need to make sure that the NBD
5
server actually allows this.
2
6
3
This patch tests that you can add and remove drives from a Quorum
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
using the x-blockdev-change command.
8
Reviewed-by: Eric Blake <eblake@redhat.com>
9
---
10
nbd/server.c | 1 +
11
tests/qemu-iotests/240 | 21 +++++++++++++++++++++
12
tests/qemu-iotests/240.out | 13 +++++++++++++
13
3 files changed, 35 insertions(+)
5
14
6
Signed-off-by: Alberto Garcia <berto@igalia.com>
15
diff --git a/nbd/server.c b/nbd/server.c
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
index XXXXXXX..XXXXXXX 100644
8
---
17
--- a/nbd/server.c
9
tests/qemu-iotests/081 | 86 ++++++++++++++++++++++++++++++++++++++
18
+++ b/nbd/server.c
10
tests/qemu-iotests/081.out | 54 ++++++++++++++++++++++++
19
@@ -XXX,XX +XXX,XX @@ NBDExport *nbd_export_new(BlockDriverState *bs, uint64_t dev_offset,
11
2 files changed, 140 insertions(+)
20
goto fail;
12
21
}
13
diff --git a/tests/qemu-iotests/081 b/tests/qemu-iotests/081
22
blk_set_enable_write_cache(blk, !writethrough);
23
+ blk_set_allow_aio_context_change(blk, true);
24
25
exp->refcount = 1;
26
QTAILQ_INIT(&exp->clients);
27
diff --git a/tests/qemu-iotests/240 b/tests/qemu-iotests/240
14
index XXXXXXX..XXXXXXX 100755
28
index XXXXXXX..XXXXXXX 100755
15
--- a/tests/qemu-iotests/081
29
--- a/tests/qemu-iotests/240
16
+++ b/tests/qemu-iotests/081
30
+++ b/tests/qemu-iotests/240
17
@@ -XXX,XX +XXX,XX @@ quorum="$quorum,file.children.2.driver=raw"
31
@@ -XXX,XX +XXX,XX @@ echo "QA output created by $seq"
18
32
19
$QEMU_IO -c "open -o $quorum" | _filter_qemu_io
33
status=1    # failure is the default!
34
35
+_cleanup()
36
+{
37
+ rm -f "$TEST_DIR/nbd"
38
+}
39
+trap "_cleanup; exit \$status" 0 1 2 3 15
40
+
41
# get standard environment, filters and checks
42
. ./common.rc
43
. ./common.filter
44
@@ -XXX,XX +XXX,XX @@ run_qemu <<EOF
45
{ "execute": "quit"}
46
EOF
20
47
21
+echo
48
+echo
22
+echo "== dynamically adding a child to a quorum =="
49
+echo === Attach a SCSI disks using the same block device as a NBD server ===
50
+echo
23
+
51
+
24
+for verify in false true; do
52
+run_qemu <<EOF
25
+ run_qemu <<EOF
53
+{ "execute": "qmp_capabilities" }
26
+ { "execute": "qmp_capabilities" }
54
+{ "execute": "blockdev-add", "arguments": {"driver": "null-co", "node-name": "hd0", "read-only": true}}
27
+ { "execute": "blockdev-add",
55
+{ "execute": "nbd-server-start", "arguments": {"addr":{"type":"unix","data":{"path":"$TEST_DIR/nbd"}}}}
28
+ "arguments": {
56
+{ "execute": "nbd-server-add", "arguments": {"device":"hd0"}}
29
+ "driver": "quorum",
57
+{ "execute": "object-add", "arguments": {"qom-type": "iothread", "id": "iothread0"}}
30
+ "node-name": "drive0-quorum",
58
+{ "execute": "device_add", "arguments": {"id": "scsi0", "driver": "${virtio_scsi}", "iothread": "iothread0"}}
31
+ "vote-threshold": 2,
59
+{ "execute": "device_add", "arguments": {"id": "scsi-hd0", "driver": "scsi-hd", "drive": "hd0", "bus": "scsi0.0"}}
32
+ "blkverify": ${verify},
60
+{ "execute": "quit"}
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
61
+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
+
62
+
107
# success, all done
63
# success, all done
108
echo "*** done"
64
echo "*** done"
109
rm -f $seq.full
65
rm -f $seq.full
110
diff --git a/tests/qemu-iotests/081.out b/tests/qemu-iotests/081.out
66
diff --git a/tests/qemu-iotests/240.out b/tests/qemu-iotests/240.out
111
index XXXXXXX..XXXXXXX 100644
67
index XXXXXXX..XXXXXXX 100644
112
--- a/tests/qemu-iotests/081.out
68
--- a/tests/qemu-iotests/240.out
113
+++ b/tests/qemu-iotests/081.out
69
+++ b/tests/qemu-iotests/240.out
114
@@ -XXX,XX +XXX,XX @@ read 10485760/10485760 bytes at offset 0
70
@@ -XXX,XX +XXX,XX @@ QMP_VERSION
115
71
{"return": {}}
116
== checking the blkverify mode with invalid settings ==
72
{"return": {}}
117
can't open: blkverify=on can only be set if there are exactly two files and vote-threshold is 2
73
{"return": {}}
118
+
74
+
119
+== dynamically adding a child to a quorum ==
75
+=== Attach a SCSI disks using the same block device as a NBD server ===
76
+
120
+Testing:
77
+Testing:
121
+QMP_VERSION
78
+QMP_VERSION
122
+{"return": {}}
79
+{"return": {}}
123
+{"return": {}}
80
+{"return": {}}
124
+{"return": {}}
81
+{"return": {}}
125
+{"return": {}}
82
+{"return": {}}
126
+{"return": {}}
83
+{"return": {}}
127
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
128
+
129
+Testing:
130
+QMP_VERSION
131
+{"return": {}}
84
+{"return": {}}
132
+{"return": {}}
85
+{"return": {}}
133
+{"return": {}}
86
+{"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
87
*** done
173
--
88
--
174
2.19.1
89
2.20.1
175
90
176
91
diff view generated by jsdifflib
1
From: Li Qiang <liq3ea@163.com>
1
Add an Error parameter to blk_set_aio_context() and use
2
bdrv_child_try_set_aio_context() internally to check whether all
3
involved nodes can actually support the AioContext switch.
2
4
3
Signed-off-by: Li Qiang <liq3ea@163.com>
4
Reviewed-by: Alberto Garcia <berto@igalia.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
---
6
---
7
include/sysemu/block-backend.h | 6 +++---
7
include/sysemu/block-backend.h | 3 ++-
8
block/block-backend.c | 8 ++++----
8
block/block-backend.c | 26 ++++++++++++++++----------
9
2 files changed, 7 insertions(+), 7 deletions(-)
9
hw/block/dataplane/virtio-blk.c | 12 +++++++++---
10
hw/block/dataplane/xen-block.c | 6 ++++--
11
hw/scsi/virtio-scsi.c | 10 +++++++---
12
tests/test-bdrv-drain.c | 8 ++++----
13
tests/test-block-iothread.c | 22 +++++++++++-----------
14
7 files changed, 53 insertions(+), 34 deletions(-)
10
15
11
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
16
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
12
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
13
--- a/include/sysemu/block-backend.h
18
--- a/include/sysemu/block-backend.h
14
+++ b/include/sysemu/block-backend.h
19
+++ b/include/sysemu/block-backend.h
15
@@ -XXX,XX +XXX,XX @@ BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
20
@@ -XXX,XX +XXX,XX @@ void blk_op_unblock(BlockBackend *blk, BlockOpType op, Error *reason);
16
int error);
21
void blk_op_block_all(BlockBackend *blk, Error *reason);
17
void blk_error_action(BlockBackend *blk, BlockErrorAction action,
22
void blk_op_unblock_all(BlockBackend *blk, Error *reason);
18
bool is_read, int error);
23
AioContext *blk_get_aio_context(BlockBackend *blk);
19
-int blk_is_read_only(BlockBackend *blk);
24
-void blk_set_aio_context(BlockBackend *blk, AioContext *new_context);
20
-int blk_is_sg(BlockBackend *blk);
25
+int blk_set_aio_context(BlockBackend *blk, AioContext *new_context,
21
-int blk_enable_write_cache(BlockBackend *blk);
26
+ Error **errp);
22
+bool blk_is_read_only(BlockBackend *blk);
27
void blk_add_aio_context_notifier(BlockBackend *blk,
23
+bool blk_is_sg(BlockBackend *blk);
28
void (*attached_aio_context)(AioContext *new_context, void *opaque),
24
+bool blk_enable_write_cache(BlockBackend *blk);
29
void (*detach_aio_context)(void *opaque), void *opaque);
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
30
diff --git a/block/block-backend.c b/block/block-backend.c
29
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
30
--- a/block/block-backend.c
32
--- a/block/block-backend.c
31
+++ b/block/block-backend.c
33
+++ b/block/block-backend.c
32
@@ -XXX,XX +XXX,XX @@ void blk_error_action(BlockBackend *blk, BlockErrorAction action,
34
@@ -XXX,XX +XXX,XX @@ static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb)
33
}
35
return blk_get_aio_context(blk_acb->blk);
34
}
36
}
35
37
36
-int blk_is_read_only(BlockBackend *blk)
38
-static void blk_do_set_aio_context(BlockBackend *blk, AioContext *new_context,
37
+bool blk_is_read_only(BlockBackend *blk)
39
- bool update_root_node)
40
+static int blk_do_set_aio_context(BlockBackend *blk, AioContext *new_context,
41
+ bool update_root_node, Error **errp)
38
{
42
{
39
BlockDriverState *bs = blk_bs(blk);
43
BlockDriverState *bs = blk_bs(blk);
40
44
ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
41
@@ -XXX,XX +XXX,XX @@ int blk_is_read_only(BlockBackend *blk)
45
+ int ret;
42
}
46
47
if (bs) {
48
+ if (update_root_node) {
49
+ ret = bdrv_child_try_set_aio_context(bs, new_context, blk->root,
50
+ errp);
51
+ if (ret < 0) {
52
+ return ret;
53
+ }
54
+ }
55
if (tgm->throttle_state) {
56
bdrv_drained_begin(bs);
57
throttle_group_detach_aio_context(tgm);
58
throttle_group_attach_aio_context(tgm, new_context);
59
bdrv_drained_end(bs);
60
}
61
- if (update_root_node) {
62
- GSList *ignore = g_slist_prepend(NULL, blk->root);
63
- bdrv_set_aio_context_ignore(bs, new_context, &ignore);
64
- g_slist_free(ignore);
65
- }
66
}
67
+
68
+ return 0;
43
}
69
}
44
70
45
-int blk_is_sg(BlockBackend *blk)
71
-void blk_set_aio_context(BlockBackend *blk, AioContext *new_context)
46
+bool blk_is_sg(BlockBackend *blk)
72
+int blk_set_aio_context(BlockBackend *blk, AioContext *new_context,
73
+ Error **errp)
47
{
74
{
48
BlockDriverState *bs = blk_bs(blk);
75
- blk_do_set_aio_context(blk, new_context, true);
49
76
+ return blk_do_set_aio_context(blk, new_context, true, errp);
50
if (!bs) {
51
- return 0;
52
+ return false;
53
}
54
55
return bdrv_is_sg(bs);
56
}
77
}
57
78
58
-int blk_enable_write_cache(BlockBackend *blk)
79
static bool blk_root_can_set_aio_ctx(BdrvChild *child, AioContext *ctx,
59
+bool blk_enable_write_cache(BlockBackend *blk)
80
@@ -XXX,XX +XXX,XX @@ static void blk_root_set_aio_ctx(BdrvChild *child, AioContext *ctx,
81
GSList **ignore)
60
{
82
{
61
return blk->enable_write_cache;
83
BlockBackend *blk = child->opaque;
84
- blk_do_set_aio_context(blk, ctx, false);
85
+ blk_do_set_aio_context(blk, ctx, false, &error_abort);
62
}
86
}
87
88
void blk_add_aio_context_notifier(BlockBackend *blk,
89
diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
90
index XXXXXXX..XXXXXXX 100644
91
--- a/hw/block/dataplane/virtio-blk.c
92
+++ b/hw/block/dataplane/virtio-blk.c
93
@@ -XXX,XX +XXX,XX @@ int virtio_blk_data_plane_start(VirtIODevice *vdev)
94
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
95
unsigned i;
96
unsigned nvqs = s->conf->num_queues;
97
+ Error *local_err = NULL;
98
int r;
99
100
if (vblk->dataplane_started || s->starting) {
101
@@ -XXX,XX +XXX,XX @@ int virtio_blk_data_plane_start(VirtIODevice *vdev)
102
vblk->dataplane_started = true;
103
trace_virtio_blk_data_plane_start(s);
104
105
- blk_set_aio_context(s->conf->conf.blk, s->ctx);
106
+ r = blk_set_aio_context(s->conf->conf.blk, s->ctx, &local_err);
107
+ if (r < 0) {
108
+ error_report_err(local_err);
109
+ goto fail_guest_notifiers;
110
+ }
111
112
/* Kick right away to begin processing requests already in vring */
113
for (i = 0; i < nvqs; i++) {
114
@@ -XXX,XX +XXX,XX @@ void virtio_blk_data_plane_stop(VirtIODevice *vdev)
115
aio_context_acquire(s->ctx);
116
aio_wait_bh_oneshot(s->ctx, virtio_blk_data_plane_stop_bh, s);
117
118
- /* Drain and switch bs back to the QEMU main loop */
119
- blk_set_aio_context(s->conf->conf.blk, qemu_get_aio_context());
120
+ /* Drain and try to switch bs back to the QEMU main loop. If other users
121
+ * keep the BlockBackend in the iothread, that's ok */
122
+ blk_set_aio_context(s->conf->conf.blk, qemu_get_aio_context(), NULL);
123
124
aio_context_release(s->ctx);
125
126
diff --git a/hw/block/dataplane/xen-block.c b/hw/block/dataplane/xen-block.c
127
index XXXXXXX..XXXXXXX 100644
128
--- a/hw/block/dataplane/xen-block.c
129
+++ b/hw/block/dataplane/xen-block.c
130
@@ -XXX,XX +XXX,XX @@ void xen_block_dataplane_stop(XenBlockDataPlane *dataplane)
131
}
132
133
aio_context_acquire(dataplane->ctx);
134
- blk_set_aio_context(dataplane->blk, qemu_get_aio_context());
135
+ /* Xen doesn't have multiple users for nodes, so this can't fail */
136
+ blk_set_aio_context(dataplane->blk, qemu_get_aio_context(), &error_abort);
137
aio_context_release(dataplane->ctx);
138
139
xendev = dataplane->xendev;
140
@@ -XXX,XX +XXX,XX @@ void xen_block_dataplane_start(XenBlockDataPlane *dataplane,
141
}
142
143
aio_context_acquire(dataplane->ctx);
144
- blk_set_aio_context(dataplane->blk, dataplane->ctx);
145
+ /* If other users keep the BlockBackend in the iothread, that's ok */
146
+ blk_set_aio_context(dataplane->blk, dataplane->ctx, NULL);
147
aio_context_release(dataplane->ctx);
148
return;
149
150
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
151
index XXXXXXX..XXXXXXX 100644
152
--- a/hw/scsi/virtio-scsi.c
153
+++ b/hw/scsi/virtio-scsi.c
154
@@ -XXX,XX +XXX,XX @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev,
155
VirtIODevice *vdev = VIRTIO_DEVICE(hotplug_dev);
156
VirtIOSCSI *s = VIRTIO_SCSI(vdev);
157
SCSIDevice *sd = SCSI_DEVICE(dev);
158
+ int ret;
159
160
if (s->ctx && !s->dataplane_fenced) {
161
AioContext *ctx;
162
@@ -XXX,XX +XXX,XX @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev,
163
return;
164
}
165
virtio_scsi_acquire(s);
166
- blk_set_aio_context(sd->conf.blk, s->ctx);
167
+ ret = blk_set_aio_context(sd->conf.blk, s->ctx, errp);
168
virtio_scsi_release(s);
169
-
170
+ if (ret < 0) {
171
+ return;
172
+ }
173
}
174
175
if (virtio_vdev_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) {
176
@@ -XXX,XX +XXX,XX @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev,
177
178
if (s->ctx) {
179
virtio_scsi_acquire(s);
180
- blk_set_aio_context(sd->conf.blk, qemu_get_aio_context());
181
+ /* If other users keep the BlockBackend in the iothread, that's ok */
182
+ blk_set_aio_context(sd->conf.blk, qemu_get_aio_context(), NULL);
183
virtio_scsi_release(s);
184
}
185
186
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
187
index XXXXXXX..XXXXXXX 100644
188
--- a/tests/test-bdrv-drain.c
189
+++ b/tests/test-bdrv-drain.c
190
@@ -XXX,XX +XXX,XX @@ static void test_iothread_common(enum drain_type drain_type, int drain_thread)
191
s = bs->opaque;
192
blk_insert_bs(blk, bs, &error_abort);
193
194
- blk_set_aio_context(blk, ctx_a);
195
+ blk_set_aio_context(blk, ctx_a, &error_abort);
196
aio_context_acquire(ctx_a);
197
198
s->bh_indirection_ctx = ctx_b;
199
@@ -XXX,XX +XXX,XX @@ static void test_iothread_common(enum drain_type drain_type, int drain_thread)
200
}
201
202
aio_context_acquire(ctx_a);
203
- blk_set_aio_context(blk, qemu_get_aio_context());
204
+ blk_set_aio_context(blk, qemu_get_aio_context(), &error_abort);
205
aio_context_release(ctx_a);
206
207
bdrv_unref(bs);
208
@@ -XXX,XX +XXX,XX @@ static void test_blockjob_common_drain_node(enum drain_type drain_type,
209
if (use_iothread) {
210
iothread = iothread_new();
211
ctx = iothread_get_aio_context(iothread);
212
- blk_set_aio_context(blk_src, ctx);
213
+ blk_set_aio_context(blk_src, ctx, &error_abort);
214
} else {
215
ctx = qemu_get_aio_context();
216
}
217
@@ -XXX,XX +XXX,XX @@ static void test_blockjob_common_drain_node(enum drain_type drain_type,
218
g_assert_cmpint(ret, ==, (result == TEST_JOB_SUCCESS ? 0 : -EIO));
219
220
if (use_iothread) {
221
- blk_set_aio_context(blk_src, qemu_get_aio_context());
222
+ blk_set_aio_context(blk_src, qemu_get_aio_context(), &error_abort);
223
}
224
aio_context_release(ctx);
225
226
diff --git a/tests/test-block-iothread.c b/tests/test-block-iothread.c
227
index XXXXXXX..XXXXXXX 100644
228
--- a/tests/test-block-iothread.c
229
+++ b/tests/test-block-iothread.c
230
@@ -XXX,XX +XXX,XX @@ static void test_sync_op(const void *opaque)
231
blk_insert_bs(blk, bs, &error_abort);
232
c = QLIST_FIRST(&bs->parents);
233
234
- blk_set_aio_context(blk, ctx);
235
+ blk_set_aio_context(blk, ctx, &error_abort);
236
aio_context_acquire(ctx);
237
t->fn(c);
238
if (t->blkfn) {
239
t->blkfn(blk);
240
}
241
aio_context_release(ctx);
242
- blk_set_aio_context(blk, qemu_get_aio_context());
243
+ blk_set_aio_context(blk, qemu_get_aio_context(), &error_abort);
244
245
bdrv_unref(bs);
246
blk_unref(blk);
247
@@ -XXX,XX +XXX,XX @@ static void test_attach_blockjob(void)
248
aio_poll(qemu_get_aio_context(), false);
249
}
250
251
- blk_set_aio_context(blk, ctx);
252
+ blk_set_aio_context(blk, ctx, &error_abort);
253
254
tjob->n = 0;
255
while (tjob->n == 0) {
256
@@ -XXX,XX +XXX,XX @@ static void test_attach_blockjob(void)
257
}
258
259
aio_context_acquire(ctx);
260
- blk_set_aio_context(blk, qemu_get_aio_context());
261
+ blk_set_aio_context(blk, qemu_get_aio_context(), &error_abort);
262
aio_context_release(ctx);
263
264
tjob->n = 0;
265
@@ -XXX,XX +XXX,XX @@ static void test_attach_blockjob(void)
266
aio_poll(qemu_get_aio_context(), false);
267
}
268
269
- blk_set_aio_context(blk, ctx);
270
+ blk_set_aio_context(blk, ctx, &error_abort);
271
272
tjob->n = 0;
273
while (tjob->n == 0) {
274
@@ -XXX,XX +XXX,XX @@ static void test_attach_blockjob(void)
275
276
aio_context_acquire(ctx);
277
job_complete_sync(&tjob->common.job, &error_abort);
278
- blk_set_aio_context(blk, qemu_get_aio_context());
279
+ blk_set_aio_context(blk, qemu_get_aio_context(), &error_abort);
280
aio_context_release(ctx);
281
282
bdrv_unref(bs);
283
@@ -XXX,XX +XXX,XX @@ static void test_propagate_basic(void)
284
bs_verify = bdrv_open(NULL, NULL, options, BDRV_O_RDWR, &error_abort);
285
286
/* Switch the AioContext */
287
- blk_set_aio_context(blk, ctx);
288
+ blk_set_aio_context(blk, ctx, &error_abort);
289
g_assert(blk_get_aio_context(blk) == ctx);
290
g_assert(bdrv_get_aio_context(bs_a) == ctx);
291
g_assert(bdrv_get_aio_context(bs_verify) == ctx);
292
@@ -XXX,XX +XXX,XX @@ static void test_propagate_basic(void)
293
294
/* Switch the AioContext back */
295
ctx = qemu_get_aio_context();
296
- blk_set_aio_context(blk, ctx);
297
+ blk_set_aio_context(blk, ctx, &error_abort);
298
g_assert(blk_get_aio_context(blk) == ctx);
299
g_assert(bdrv_get_aio_context(bs_a) == ctx);
300
g_assert(bdrv_get_aio_context(bs_verify) == ctx);
301
@@ -XXX,XX +XXX,XX @@ static void test_propagate_diamond(void)
302
blk_insert_bs(blk, bs_verify, &error_abort);
303
304
/* Switch the AioContext */
305
- blk_set_aio_context(blk, ctx);
306
+ blk_set_aio_context(blk, ctx, &error_abort);
307
g_assert(blk_get_aio_context(blk) == ctx);
308
g_assert(bdrv_get_aio_context(bs_verify) == ctx);
309
g_assert(bdrv_get_aio_context(bs_a) == ctx);
310
@@ -XXX,XX +XXX,XX @@ static void test_propagate_diamond(void)
311
312
/* Switch the AioContext back */
313
ctx = qemu_get_aio_context();
314
- blk_set_aio_context(blk, ctx);
315
+ blk_set_aio_context(blk, ctx, &error_abort);
316
g_assert(blk_get_aio_context(blk) == ctx);
317
g_assert(bdrv_get_aio_context(bs_verify) == ctx);
318
g_assert(bdrv_get_aio_context(bs_a) == ctx);
319
@@ -XXX,XX +XXX,XX @@ static void test_propagate_mirror(void)
320
job_cancel_sync_all();
321
322
aio_context_acquire(ctx);
323
- blk_set_aio_context(blk, main_ctx);
324
+ blk_set_aio_context(blk, main_ctx, &error_abort);
325
bdrv_try_set_aio_context(target, main_ctx, &error_abort);
326
aio_context_release(ctx);
327
63
--
328
--
64
2.19.1
329
2.20.1
65
330
66
331
diff view generated by jsdifflib
1
From: Peter Maydell <peter.maydell@linaro.org>
1
This adds a new parameter to blk_new() which requires its callers to
2
declare from which AioContext this BlockBackend is going to be used (or
3
the locks of which AioContext need to be taken anyway).
2
4
3
Taking the address of a field in a packed struct is a bad idea, because
5
The given context is only stored and kept up to date when changing
4
it might not be actually aligned enough for that pointer type (and
6
AioContexts. Actually applying the stored AioContext to the root node
5
thus cause a crash on dereference on some host architectures). Newer
7
is saved for another commit.
6
versions of clang warn about this. Avoid the bug by not using the
7
"modify in place" byte swapping functions.
8
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>
50
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
51
---
10
---
52
block/qcow.c | 18 +++++++++---------
11
include/sysemu/block-backend.h | 2 +-
53
1 file changed, 9 insertions(+), 9 deletions(-)
12
block.c | 2 +-
13
block/backup.c | 3 ++-
14
block/block-backend.c | 18 +++++++++++++++---
15
block/commit.c | 11 +++++++----
16
block/crypto.c | 3 ++-
17
block/mirror.c | 3 ++-
18
block/parallels.c | 3 ++-
19
block/qcow.c | 3 ++-
20
block/qcow2.c | 6 ++++--
21
block/qed.c | 3 ++-
22
block/sheepdog.c | 3 ++-
23
block/vdi.c | 3 ++-
24
block/vhdx.c | 3 ++-
25
block/vmdk.c | 3 ++-
26
block/vpc.c | 3 ++-
27
blockdev.c | 4 ++--
28
blockjob.c | 2 +-
29
hmp.c | 3 ++-
30
hw/block/fdc.c | 2 +-
31
hw/block/xen-block.c | 2 +-
32
hw/core/qdev-properties-system.c | 4 +++-
33
hw/ide/qdev.c | 2 +-
34
hw/scsi/scsi-disk.c | 2 +-
35
migration/block.c | 3 ++-
36
nbd/server.c | 5 +++--
37
qemu-img.c | 6 ++++--
38
tests/test-bdrv-drain.c | 30 +++++++++++++++---------------
39
tests/test-bdrv-graph-mod.c | 5 +++--
40
tests/test-block-backend.c | 6 ++++--
41
tests/test-block-iothread.c | 10 +++++-----
42
tests/test-blockjob.c | 2 +-
43
tests/test-throttle.c | 6 +++---
44
33 files changed, 102 insertions(+), 64 deletions(-)
54
45
46
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
47
index XXXXXXX..XXXXXXX 100644
48
--- a/include/sysemu/block-backend.h
49
+++ b/include/sysemu/block-backend.h
50
@@ -XXX,XX +XXX,XX @@ typedef struct BlockBackendPublic {
51
ThrottleGroupMember throttle_group_member;
52
} BlockBackendPublic;
53
54
-BlockBackend *blk_new(uint64_t perm, uint64_t shared_perm);
55
+BlockBackend *blk_new(AioContext *ctx, uint64_t perm, uint64_t shared_perm);
56
BlockBackend *blk_new_open(const char *filename, const char *reference,
57
QDict *options, int flags, Error **errp);
58
int blk_get_refcnt(BlockBackend *blk);
59
diff --git a/block.c b/block.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/block.c
62
+++ b/block.c
63
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
64
/* Not requesting BLK_PERM_CONSISTENT_READ because we're only
65
* looking at the header to guess the image format. This works even
66
* in cases where a guest would not see a consistent state. */
67
- file = blk_new(0, BLK_PERM_ALL);
68
+ file = blk_new(bdrv_get_aio_context(file_bs), 0, BLK_PERM_ALL);
69
blk_insert_bs(file, file_bs, &local_err);
70
bdrv_unref(file_bs);
71
if (local_err) {
72
diff --git a/block/backup.c b/block/backup.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/block/backup.c
75
+++ b/block/backup.c
76
@@ -XXX,XX +XXX,XX @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
77
}
78
79
/* The target must match the source in size, so no resize here either */
80
- job->target = blk_new(BLK_PERM_WRITE,
81
+ job->target = blk_new(job->common.job.aio_context,
82
+ BLK_PERM_WRITE,
83
BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE |
84
BLK_PERM_WRITE_UNCHANGED | BLK_PERM_GRAPH_MOD);
85
ret = blk_insert_bs(job->target, target, errp);
86
diff --git a/block/block-backend.c b/block/block-backend.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/block/block-backend.c
89
+++ b/block/block-backend.c
90
@@ -XXX,XX +XXX,XX @@ struct BlockBackend {
91
char *name;
92
int refcnt;
93
BdrvChild *root;
94
+ AioContext *ctx;
95
DriveInfo *legacy_dinfo; /* null unless created by drive_new() */
96
QTAILQ_ENTRY(BlockBackend) link; /* for block_backends */
97
QTAILQ_ENTRY(BlockBackend) monitor_link; /* for monitor_block_backends */
98
@@ -XXX,XX +XXX,XX @@ static const BdrvChildRole child_root = {
99
*
100
* Return the new BlockBackend on success, null on failure.
101
*/
102
-BlockBackend *blk_new(uint64_t perm, uint64_t shared_perm)
103
+BlockBackend *blk_new(AioContext *ctx, uint64_t perm, uint64_t shared_perm)
104
{
105
BlockBackend *blk;
106
107
blk = g_new0(BlockBackend, 1);
108
blk->refcnt = 1;
109
+ blk->ctx = ctx;
110
blk->perm = perm;
111
blk->shared_perm = shared_perm;
112
blk_set_enable_write_cache(blk, true);
113
@@ -XXX,XX +XXX,XX @@ BlockBackend *blk_new(uint64_t perm, uint64_t shared_perm)
114
115
/*
116
* Creates a new BlockBackend, opens a new BlockDriverState, and connects both.
117
+ * The new BlockBackend is in the main AioContext.
118
*
119
* Just as with bdrv_open(), after having called this function the reference to
120
* @options belongs to the block layer (even on failure).
121
@@ -XXX,XX +XXX,XX @@ BlockBackend *blk_new_open(const char *filename, const char *reference,
122
perm |= BLK_PERM_RESIZE;
123
}
124
125
- blk = blk_new(perm, BLK_PERM_ALL);
126
+ blk = blk_new(qemu_get_aio_context(), perm, BLK_PERM_ALL);
127
bs = bdrv_open(filename, reference, options, flags, errp);
128
if (!bs) {
129
blk_unref(blk);
130
@@ -XXX,XX +XXX,XX @@ void blk_op_unblock_all(BlockBackend *blk, Error *reason)
131
132
AioContext *blk_get_aio_context(BlockBackend *blk)
133
{
134
- return bdrv_get_aio_context(blk_bs(blk));
135
+ BlockDriverState *bs = blk_bs(blk);
136
+
137
+ /* FIXME The AioContext of bs and blk can be inconsistent. For the moment,
138
+ * we prefer the one of bs for compatibility. */
139
+ if (bs) {
140
+ return bdrv_get_aio_context(blk_bs(blk));
141
+ }
142
+
143
+ return blk->ctx;
144
}
145
146
static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb)
147
@@ -XXX,XX +XXX,XX @@ static int blk_do_set_aio_context(BlockBackend *blk, AioContext *new_context,
148
}
149
}
150
151
+ blk->ctx = new_context;
152
return 0;
153
}
154
155
diff --git a/block/commit.c b/block/commit.c
156
index XXXXXXX..XXXXXXX 100644
157
--- a/block/commit.c
158
+++ b/block/commit.c
159
@@ -XXX,XX +XXX,XX @@ void commit_start(const char *job_id, BlockDriverState *bs,
160
goto fail;
161
}
162
163
- s->base = blk_new(BLK_PERM_CONSISTENT_READ
164
+ s->base = blk_new(s->common.job.aio_context,
165
+ BLK_PERM_CONSISTENT_READ
166
| BLK_PERM_WRITE
167
| BLK_PERM_RESIZE,
168
BLK_PERM_CONSISTENT_READ
169
@@ -XXX,XX +XXX,XX @@ void commit_start(const char *job_id, BlockDriverState *bs,
170
s->base_bs = base;
171
172
/* Required permissions are already taken with block_job_add_bdrv() */
173
- s->top = blk_new(0, BLK_PERM_ALL);
174
+ s->top = blk_new(s->common.job.aio_context, 0, BLK_PERM_ALL);
175
ret = blk_insert_bs(s->top, top, errp);
176
if (ret < 0) {
177
goto fail;
178
@@ -XXX,XX +XXX,XX @@ int bdrv_commit(BlockDriverState *bs)
179
BlockDriverState *backing_file_bs = NULL;
180
BlockDriverState *commit_top_bs = NULL;
181
BlockDriver *drv = bs->drv;
182
+ AioContext *ctx;
183
int64_t offset, length, backing_length;
184
int ro;
185
int64_t n;
186
@@ -XXX,XX +XXX,XX @@ int bdrv_commit(BlockDriverState *bs)
187
}
188
}
189
190
- src = blk_new(BLK_PERM_CONSISTENT_READ, BLK_PERM_ALL);
191
- backing = blk_new(BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);
192
+ ctx = bdrv_get_aio_context(bs);
193
+ src = blk_new(ctx, BLK_PERM_CONSISTENT_READ, BLK_PERM_ALL);
194
+ backing = blk_new(ctx, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);
195
196
ret = blk_insert_bs(src, bs, &local_err);
197
if (ret < 0) {
198
diff --git a/block/crypto.c b/block/crypto.c
199
index XXXXXXX..XXXXXXX 100644
200
--- a/block/crypto.c
201
+++ b/block/crypto.c
202
@@ -XXX,XX +XXX,XX @@ static int block_crypto_co_create_generic(BlockDriverState *bs,
203
QCryptoBlock *crypto = NULL;
204
struct BlockCryptoCreateData data;
205
206
- blk = blk_new(BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);
207
+ blk = blk_new(bdrv_get_aio_context(bs),
208
+ BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);
209
210
ret = blk_insert_bs(blk, bs, errp);
211
if (ret < 0) {
212
diff --git a/block/mirror.c b/block/mirror.c
213
index XXXXXXX..XXXXXXX 100644
214
--- a/block/mirror.c
215
+++ b/block/mirror.c
216
@@ -XXX,XX +XXX,XX @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
217
* We can allow anything except resize there.*/
218
target_is_backing = bdrv_chain_contains(bs, target);
219
target_graph_mod = (backing_mode != MIRROR_LEAVE_BACKING_CHAIN);
220
- s->target = blk_new(BLK_PERM_WRITE | BLK_PERM_RESIZE |
221
+ s->target = blk_new(s->common.job.aio_context,
222
+ BLK_PERM_WRITE | BLK_PERM_RESIZE |
223
(target_graph_mod ? BLK_PERM_GRAPH_MOD : 0),
224
BLK_PERM_WRITE_UNCHANGED |
225
(target_is_backing ? BLK_PERM_CONSISTENT_READ |
226
diff --git a/block/parallels.c b/block/parallels.c
227
index XXXXXXX..XXXXXXX 100644
228
--- a/block/parallels.c
229
+++ b/block/parallels.c
230
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn parallels_co_create(BlockdevCreateOptions* opts,
231
return -EIO;
232
}
233
234
- blk = blk_new(BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);
235
+ blk = blk_new(bdrv_get_aio_context(bs),
236
+ BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);
237
ret = blk_insert_bs(blk, bs, errp);
238
if (ret < 0) {
239
goto out;
55
diff --git a/block/qcow.c b/block/qcow.c
240
diff --git a/block/qcow.c b/block/qcow.c
56
index XXXXXXX..XXXXXXX 100644
241
index XXXXXXX..XXXXXXX 100644
57
--- a/block/qcow.c
242
--- a/block/qcow.c
58
+++ b/block/qcow.c
243
+++ b/block/qcow.c
59
@@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
244
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow_co_create(BlockdevCreateOptions *opts,
245
return -EIO;
246
}
247
248
- qcow_blk = blk_new(BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);
249
+ qcow_blk = blk_new(bdrv_get_aio_context(bs),
250
+ BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);
251
ret = blk_insert_bs(qcow_blk, bs, errp);
252
if (ret < 0) {
253
goto exit;
254
diff --git a/block/qcow2.c b/block/qcow2.c
255
index XXXXXXX..XXXXXXX 100644
256
--- a/block/qcow2.c
257
+++ b/block/qcow2.c
258
@@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
259
}
260
261
/* Create BlockBackend to write to the image */
262
- blk = blk_new(BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);
263
+ blk = blk_new(bdrv_get_aio_context(bs),
264
+ BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);
265
ret = blk_insert_bs(blk, bs, errp);
266
if (ret < 0) {
267
goto out;
268
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
269
}
270
271
if (new_size) {
272
- BlockBackend *blk = blk_new(BLK_PERM_RESIZE, BLK_PERM_ALL);
273
+ BlockBackend *blk = blk_new(bdrv_get_aio_context(bs),
274
+ BLK_PERM_RESIZE, BLK_PERM_ALL);
275
ret = blk_insert_bs(blk, bs, errp);
276
if (ret < 0) {
277
blk_unref(blk);
278
diff --git a/block/qed.c b/block/qed.c
279
index XXXXXXX..XXXXXXX 100644
280
--- a/block/qed.c
281
+++ b/block/qed.c
282
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_create(BlockdevCreateOptions *opts,
283
return -EIO;
284
}
285
286
- blk = blk_new(BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);
287
+ blk = blk_new(bdrv_get_aio_context(bs),
288
+ BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);
289
ret = blk_insert_bs(blk, bs, errp);
290
if (ret < 0) {
291
goto out;
292
diff --git a/block/sheepdog.c b/block/sheepdog.c
293
index XXXXXXX..XXXXXXX 100644
294
--- a/block/sheepdog.c
295
+++ b/block/sheepdog.c
296
@@ -XXX,XX +XXX,XX @@ static int sd_prealloc(BlockDriverState *bs, int64_t old_size, int64_t new_size,
297
void *buf = NULL;
298
int ret;
299
300
- blk = blk_new(BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE | BLK_PERM_RESIZE,
301
+ blk = blk_new(bdrv_get_aio_context(bs),
302
+ BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE | BLK_PERM_RESIZE,
303
BLK_PERM_ALL);
304
305
ret = blk_insert_bs(blk, bs, errp);
306
diff --git a/block/vdi.c b/block/vdi.c
307
index XXXXXXX..XXXXXXX 100644
308
--- a/block/vdi.c
309
+++ b/block/vdi.c
310
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
311
goto exit;
312
}
313
314
- blk = blk_new(BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);
315
+ blk = blk_new(bdrv_get_aio_context(bs_file),
316
+ BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);
317
ret = blk_insert_bs(blk, bs_file, errp);
318
if (ret < 0) {
319
goto exit;
320
diff --git a/block/vhdx.c b/block/vhdx.c
321
index XXXXXXX..XXXXXXX 100644
322
--- a/block/vhdx.c
323
+++ b/block/vhdx.c
324
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vhdx_co_create(BlockdevCreateOptions *opts,
325
return -EIO;
326
}
327
328
- blk = blk_new(BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);
329
+ blk = blk_new(bdrv_get_aio_context(bs),
330
+ BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);
331
ret = blk_insert_bs(blk, bs, errp);
332
if (ret < 0) {
333
goto delete_and_exit;
334
diff --git a/block/vmdk.c b/block/vmdk.c
335
index XXXXXXX..XXXXXXX 100644
336
--- a/block/vmdk.c
337
+++ b/block/vmdk.c
338
@@ -XXX,XX +XXX,XX @@ static BlockBackend *vmdk_co_create_cb(int64_t size, int idx,
339
if (!bs) {
340
return NULL;
341
}
342
- blk = blk_new(BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE | BLK_PERM_RESIZE,
343
+ blk = blk_new(bdrv_get_aio_context(bs),
344
+ BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE | BLK_PERM_RESIZE,
345
BLK_PERM_ALL);
346
if (blk_insert_bs(blk, bs, errp)) {
347
bdrv_unref(bs);
348
diff --git a/block/vpc.c b/block/vpc.c
349
index XXXXXXX..XXXXXXX 100644
350
--- a/block/vpc.c
351
+++ b/block/vpc.c
352
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vpc_co_create(BlockdevCreateOptions *opts,
353
return -EIO;
354
}
355
356
- blk = blk_new(BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);
357
+ blk = blk_new(bdrv_get_aio_context(bs),
358
+ BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);
359
ret = blk_insert_bs(blk, bs, errp);
360
if (ret < 0) {
361
goto out;
362
diff --git a/blockdev.c b/blockdev.c
363
index XXXXXXX..XXXXXXX 100644
364
--- a/blockdev.c
365
+++ b/blockdev.c
366
@@ -XXX,XX +XXX,XX @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
367
if ((!file || !*file) && !qdict_size(bs_opts)) {
368
BlockBackendRootState *blk_rs;
369
370
- blk = blk_new(0, BLK_PERM_ALL);
371
+ blk = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL);
372
blk_rs = blk_get_root_state(blk);
373
blk_rs->open_flags = bdrv_flags;
374
blk_rs->read_only = read_only;
375
@@ -XXX,XX +XXX,XX @@ void qmp_block_resize(bool has_device, const char *device,
376
goto out;
377
}
378
379
- blk = blk_new(BLK_PERM_RESIZE, BLK_PERM_ALL);
380
+ blk = blk_new(qemu_get_aio_context(), BLK_PERM_RESIZE, BLK_PERM_ALL);
381
ret = blk_insert_bs(blk, bs, errp);
382
if (ret < 0) {
383
goto out;
384
diff --git a/blockjob.c b/blockjob.c
385
index XXXXXXX..XXXXXXX 100644
386
--- a/blockjob.c
387
+++ b/blockjob.c
388
@@ -XXX,XX +XXX,XX @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
389
job_id = bdrv_get_device_name(bs);
390
}
391
392
- blk = blk_new(perm, shared_perm);
393
+ blk = blk_new(bdrv_get_aio_context(bs), perm, shared_perm);
394
ret = blk_insert_bs(blk, bs, errp);
395
if (ret < 0) {
396
blk_unref(blk);
397
diff --git a/hmp.c b/hmp.c
398
index XXXXXXX..XXXXXXX 100644
399
--- a/hmp.c
400
+++ b/hmp.c
401
@@ -XXX,XX +XXX,XX @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict)
402
if (!blk) {
403
BlockDriverState *bs = bdrv_lookup_bs(NULL, device, &err);
404
if (bs) {
405
- blk = local_blk = blk_new(0, BLK_PERM_ALL);
406
+ blk = local_blk = blk_new(bdrv_get_aio_context(bs),
407
+ 0, BLK_PERM_ALL);
408
ret = blk_insert_bs(blk, bs, &err);
409
if (ret < 0) {
410
goto fail;
411
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
412
index XXXXXXX..XXXXXXX 100644
413
--- a/hw/block/fdc.c
414
+++ b/hw/block/fdc.c
415
@@ -XXX,XX +XXX,XX @@ static void floppy_drive_realize(DeviceState *qdev, Error **errp)
416
417
if (!dev->conf.blk) {
418
/* Anonymous BlockBackend for an empty drive */
419
- dev->conf.blk = blk_new(0, BLK_PERM_ALL);
420
+ dev->conf.blk = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL);
421
ret = blk_attach_dev(dev->conf.blk, qdev);
422
assert(ret == 0);
423
}
424
diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
425
index XXXXXXX..XXXXXXX 100644
426
--- a/hw/block/xen-block.c
427
+++ b/hw/block/xen-block.c
428
@@ -XXX,XX +XXX,XX @@ static void xen_cdrom_realize(XenBlockDevice *blockdev, Error **errp)
429
int rc;
430
431
/* Set up an empty drive */
432
- conf->blk = blk_new(0, BLK_PERM_ALL);
433
+ conf->blk = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL);
434
435
rc = blk_attach_dev(conf->blk, DEVICE(blockdev));
436
if (!rc) {
437
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
438
index XXXXXXX..XXXXXXX 100644
439
--- a/hw/core/qdev-properties-system.c
440
+++ b/hw/core/qdev-properties-system.c
441
@@ -XXX,XX +XXX,XX @@ static void parse_drive(DeviceState *dev, const char *str, void **ptr,
442
if (!blk) {
443
BlockDriverState *bs = bdrv_lookup_bs(NULL, str, NULL);
444
if (bs) {
445
- blk = blk_new(0, BLK_PERM_ALL);
446
+ /* BlockBackends of devices start in the main context and are only
447
+ * later moved into another context if the device supports that. */
448
+ blk = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL);
449
blk_created = true;
450
451
ret = blk_insert_bs(blk, bs, errp);
452
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
453
index XXXXXXX..XXXXXXX 100644
454
--- a/hw/ide/qdev.c
455
+++ b/hw/ide/qdev.c
456
@@ -XXX,XX +XXX,XX @@ static void ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind, Error **errp)
457
return;
458
} else {
459
/* Anonymous BlockBackend for an empty drive */
460
- dev->conf.blk = blk_new(0, BLK_PERM_ALL);
461
+ dev->conf.blk = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL);
462
ret = blk_attach_dev(dev->conf.blk, &dev->qdev);
463
assert(ret == 0);
464
}
465
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
466
index XXXXXXX..XXXXXXX 100644
467
--- a/hw/scsi/scsi-disk.c
468
+++ b/hw/scsi/scsi-disk.c
469
@@ -XXX,XX +XXX,XX @@ static void scsi_cd_realize(SCSIDevice *dev, Error **errp)
470
if (!dev->conf.blk) {
471
/* Anonymous BlockBackend for an empty drive. As we put it into
472
* dev->conf, qdev takes care of detaching on unplug. */
473
- dev->conf.blk = blk_new(0, BLK_PERM_ALL);
474
+ dev->conf.blk = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL);
475
ret = blk_attach_dev(dev->conf.blk, &dev->qdev);
476
assert(ret == 0);
477
}
478
diff --git a/migration/block.c b/migration/block.c
479
index XXXXXXX..XXXXXXX 100644
480
--- a/migration/block.c
481
+++ b/migration/block.c
482
@@ -XXX,XX +XXX,XX @@ static int init_blk_migration(QEMUFile *f)
483
}
484
485
bmds = g_new0(BlkMigDevState, 1);
486
- bmds->blk = blk_new(BLK_PERM_CONSISTENT_READ, BLK_PERM_ALL);
487
+ bmds->blk = blk_new(qemu_get_aio_context(),
488
+ BLK_PERM_CONSISTENT_READ, BLK_PERM_ALL);
489
bmds->blk_name = g_strdup(bdrv_get_device_name(bs));
490
bmds->bulk_completed = 0;
491
bmds->total_sectors = sectors;
492
diff --git a/nbd/server.c b/nbd/server.c
493
index XXXXXXX..XXXXXXX 100644
494
--- a/nbd/server.c
495
+++ b/nbd/server.c
496
@@ -XXX,XX +XXX,XX @@ NBDExport *nbd_export_new(BlockDriverState *bs, uint64_t dev_offset,
497
if ((nbdflags & NBD_FLAG_READ_ONLY) == 0) {
498
perm |= BLK_PERM_WRITE;
499
}
500
- blk = blk_new(perm, BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED |
501
- BLK_PERM_WRITE | BLK_PERM_GRAPH_MOD);
502
+ blk = blk_new(bdrv_get_aio_context(bs), perm,
503
+ BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED |
504
+ BLK_PERM_WRITE | BLK_PERM_GRAPH_MOD);
505
ret = blk_insert_bs(blk, bs, errp);
60
if (ret < 0) {
506
if (ret < 0) {
61
goto fail;
507
goto fail;
62
}
508
diff --git a/qemu-img.c b/qemu-img.c
63
- be32_to_cpus(&header.magic);
509
index XXXXXXX..XXXXXXX 100644
64
- be32_to_cpus(&header.version);
510
--- a/qemu-img.c
65
- be64_to_cpus(&header.backing_file_offset);
511
+++ b/qemu-img.c
66
- be32_to_cpus(&header.backing_file_size);
512
@@ -XXX,XX +XXX,XX @@ static int img_rebase(int argc, char **argv)
67
- be32_to_cpus(&header.mtime);
513
BlockDriverState *base_bs = backing_bs(bs);
68
- be64_to_cpus(&header.size);
514
69
- be32_to_cpus(&header.crypt_method);
515
if (base_bs) {
70
- be64_to_cpus(&header.l1_table_offset);
516
- blk_old_backing = blk_new(BLK_PERM_CONSISTENT_READ,
71
+ header.magic = be32_to_cpu(header.magic);
517
+ blk_old_backing = blk_new(qemu_get_aio_context(),
72
+ header.version = be32_to_cpu(header.version);
518
+ BLK_PERM_CONSISTENT_READ,
73
+ header.backing_file_offset = be64_to_cpu(header.backing_file_offset);
519
BLK_PERM_ALL);
74
+ header.backing_file_size = be32_to_cpu(header.backing_file_size);
520
ret = blk_insert_bs(blk_old_backing, base_bs,
75
+ header.mtime = be32_to_cpu(header.mtime);
521
&local_err);
76
+ header.size = be64_to_cpu(header.size);
522
@@ -XXX,XX +XXX,XX @@ static int img_rebase(int argc, char **argv)
77
+ header.crypt_method = be32_to_cpu(header.crypt_method);
523
prefix_chain_bs = bdrv_find_backing_image(bs, out_real_path);
78
+ header.l1_table_offset = be64_to_cpu(header.l1_table_offset);
524
if (prefix_chain_bs) {
79
525
g_free(out_real_path);
80
if (header.magic != QCOW_MAGIC) {
526
- blk_new_backing = blk_new(BLK_PERM_CONSISTENT_READ,
81
error_setg(errp, "Image not in qcow format");
527
+ blk_new_backing = blk_new(qemu_get_aio_context(),
82
@@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
528
+ BLK_PERM_CONSISTENT_READ,
83
}
529
BLK_PERM_ALL);
84
530
ret = blk_insert_bs(blk_new_backing, prefix_chain_bs,
85
for(i = 0;i < s->l1_size; i++) {
531
&local_err);
86
- be64_to_cpus(&s->l1_table[i]);
532
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
87
+ s->l1_table[i] = be64_to_cpu(s->l1_table[i]);
533
index XXXXXXX..XXXXXXX 100644
88
}
534
--- a/tests/test-bdrv-drain.c
89
535
+++ b/tests/test-bdrv-drain.c
90
/* alloc L2 cache (max. 64k * 16 * 8 = 8 MB) */
536
@@ -XXX,XX +XXX,XX @@ static void test_drv_cb_common(enum drain_type drain_type, bool recursive)
537
538
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, NULL, 0);
539
540
- blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
541
+ blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
542
bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR,
543
&error_abort);
544
s = bs->opaque;
545
@@ -XXX,XX +XXX,XX @@ static void test_quiesce_common(enum drain_type drain_type, bool recursive)
546
BlockBackend *blk;
547
BlockDriverState *bs, *backing;
548
549
- blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
550
+ blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
551
bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR,
552
&error_abort);
553
blk_insert_bs(blk, bs, &error_abort);
554
@@ -XXX,XX +XXX,XX @@ static void test_nested(void)
555
BDRVTestState *s, *backing_s;
556
enum drain_type outer, inner;
557
558
- blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
559
+ blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
560
bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR,
561
&error_abort);
562
s = bs->opaque;
563
@@ -XXX,XX +XXX,XX @@ static void test_multiparent(void)
564
BlockDriverState *bs_a, *bs_b, *backing;
565
BDRVTestState *a_s, *b_s, *backing_s;
566
567
- blk_a = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
568
+ blk_a = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
569
bs_a = bdrv_new_open_driver(&bdrv_test, "test-node-a", BDRV_O_RDWR,
570
&error_abort);
571
a_s = bs_a->opaque;
572
blk_insert_bs(blk_a, bs_a, &error_abort);
573
574
- blk_b = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
575
+ blk_b = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
576
bs_b = bdrv_new_open_driver(&bdrv_test, "test-node-b", BDRV_O_RDWR,
577
&error_abort);
578
b_s = bs_b->opaque;
579
@@ -XXX,XX +XXX,XX @@ static void test_graph_change_drain_subtree(void)
580
BlockDriverState *bs_a, *bs_b, *backing;
581
BDRVTestState *a_s, *b_s, *backing_s;
582
583
- blk_a = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
584
+ blk_a = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
585
bs_a = bdrv_new_open_driver(&bdrv_test, "test-node-a", BDRV_O_RDWR,
586
&error_abort);
587
a_s = bs_a->opaque;
588
blk_insert_bs(blk_a, bs_a, &error_abort);
589
590
- blk_b = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
591
+ blk_b = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
592
bs_b = bdrv_new_open_driver(&bdrv_test, "test-node-b", BDRV_O_RDWR,
593
&error_abort);
594
b_s = bs_b->opaque;
595
@@ -XXX,XX +XXX,XX @@ static void test_graph_change_drain_all(void)
596
BDRVTestState *a_s, *b_s;
597
598
/* Create node A with a BlockBackend */
599
- blk_a = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
600
+ blk_a = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
601
bs_a = bdrv_new_open_driver(&bdrv_test, "test-node-a", BDRV_O_RDWR,
602
&error_abort);
603
a_s = bs_a->opaque;
604
@@ -XXX,XX +XXX,XX @@ static void test_graph_change_drain_all(void)
605
g_assert_cmpint(a_s->drain_count, ==, 1);
606
607
/* Create node B with a BlockBackend */
608
- blk_b = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
609
+ blk_b = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
610
bs_b = bdrv_new_open_driver(&bdrv_test, "test-node-b", BDRV_O_RDWR,
611
&error_abort);
612
b_s = bs_b->opaque;
613
@@ -XXX,XX +XXX,XX @@ static void test_iothread_common(enum drain_type drain_type, int drain_thread)
614
goto out;
615
}
616
617
- blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
618
+ blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
619
bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR,
620
&error_abort);
621
s = bs->opaque;
622
@@ -XXX,XX +XXX,XX @@ static void test_blockjob_common_drain_node(enum drain_type drain_type,
623
bdrv_set_backing_hd(src, src_backing, &error_abort);
624
bdrv_unref(src_backing);
625
626
- blk_src = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
627
+ blk_src = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
628
blk_insert_bs(blk_src, src_overlay, &error_abort);
629
630
switch (drain_node) {
631
@@ -XXX,XX +XXX,XX @@ static void test_blockjob_common_drain_node(enum drain_type drain_type,
632
633
target = bdrv_new_open_driver(&bdrv_test, "target", BDRV_O_RDWR,
634
&error_abort);
635
- blk_target = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
636
+ blk_target = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
637
blk_insert_bs(blk_target, target, &error_abort);
638
639
aio_context_acquire(ctx);
640
@@ -XXX,XX +XXX,XX @@ static void do_test_delete_by_drain(bool detach_instead_of_delete,
641
&error_abort);
642
bdrv_attach_child(bs, null_bs, "null-child", &child_file, &error_abort);
643
644
- blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
645
+ blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
646
blk_insert_bs(blk, bs, &error_abort);
647
648
/* Referenced by blk now */
649
@@ -XXX,XX +XXX,XX @@ static void test_detach_indirect(bool by_parent_cb)
650
c = bdrv_new_open_driver(&bdrv_test, "c", BDRV_O_RDWR, &error_abort);
651
652
/* blk is a BB for parent-a */
653
- blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
654
+ blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
655
blk_insert_bs(blk, parent_a, &error_abort);
656
bdrv_unref(parent_a);
657
658
@@ -XXX,XX +XXX,XX @@ static void test_append_to_drained(void)
659
BlockDriverState *base, *overlay;
660
BDRVTestState *base_s, *overlay_s;
661
662
- blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
663
+ blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
664
base = bdrv_new_open_driver(&bdrv_test, "base", BDRV_O_RDWR, &error_abort);
665
base_s = base->opaque;
666
blk_insert_bs(blk, base, &error_abort);
667
diff --git a/tests/test-bdrv-graph-mod.c b/tests/test-bdrv-graph-mod.c
668
index XXXXXXX..XXXXXXX 100644
669
--- a/tests/test-bdrv-graph-mod.c
670
+++ b/tests/test-bdrv-graph-mod.c
671
@@ -XXX,XX +XXX,XX @@ static void test_update_perm_tree(void)
672
{
673
Error *local_err = NULL;
674
675
- BlockBackend *root = blk_new(BLK_PERM_WRITE | BLK_PERM_CONSISTENT_READ,
676
+ BlockBackend *root = blk_new(qemu_get_aio_context(),
677
+ BLK_PERM_WRITE | BLK_PERM_CONSISTENT_READ,
678
BLK_PERM_ALL & ~BLK_PERM_WRITE);
679
BlockDriverState *bs = no_perm_node("node");
680
BlockDriverState *filter = pass_through_node("filter");
681
@@ -XXX,XX +XXX,XX @@ static void test_update_perm_tree(void)
682
*/
683
static void test_should_update_child(void)
684
{
685
- BlockBackend *root = blk_new(0, BLK_PERM_ALL);
686
+ BlockBackend *root = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL);
687
BlockDriverState *bs = no_perm_node("node");
688
BlockDriverState *filter = no_perm_node("filter");
689
BlockDriverState *target = no_perm_node("target");
690
diff --git a/tests/test-block-backend.c b/tests/test-block-backend.c
691
index XXXXXXX..XXXXXXX 100644
692
--- a/tests/test-block-backend.c
693
+++ b/tests/test-block-backend.c
694
@@ -XXX,XX +XXX,XX @@ static void test_drain_aio_error_flush_cb(void *opaque, int ret)
695
696
static void test_drain_aio_error(void)
697
{
698
- BlockBackend *blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
699
+ BlockBackend *blk = blk_new(qemu_get_aio_context(),
700
+ BLK_PERM_ALL, BLK_PERM_ALL);
701
BlockAIOCB *acb;
702
bool completed = false;
703
704
@@ -XXX,XX +XXX,XX @@ static void test_drain_aio_error(void)
705
706
static void test_drain_all_aio_error(void)
707
{
708
- BlockBackend *blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
709
+ BlockBackend *blk = blk_new(qemu_get_aio_context(),
710
+ BLK_PERM_ALL, BLK_PERM_ALL);
711
BlockAIOCB *acb;
712
bool completed = false;
713
714
diff --git a/tests/test-block-iothread.c b/tests/test-block-iothread.c
715
index XXXXXXX..XXXXXXX 100644
716
--- a/tests/test-block-iothread.c
717
+++ b/tests/test-block-iothread.c
718
@@ -XXX,XX +XXX,XX @@ static void test_sync_op(const void *opaque)
719
BlockDriverState *bs;
720
BdrvChild *c;
721
722
- blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
723
+ blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
724
bs = bdrv_new_open_driver(&bdrv_test, "base", BDRV_O_RDWR, &error_abort);
725
bs->total_sectors = 65536 / BDRV_SECTOR_SIZE;
726
blk_insert_bs(blk, bs, &error_abort);
727
@@ -XXX,XX +XXX,XX @@ static void test_attach_blockjob(void)
728
BlockDriverState *bs;
729
TestBlockJob *tjob;
730
731
- blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
732
+ blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
733
bs = bdrv_new_open_driver(&bdrv_test, "base", BDRV_O_RDWR, &error_abort);
734
blk_insert_bs(blk, bs, &error_abort);
735
736
@@ -XXX,XX +XXX,XX @@ static void test_propagate_basic(void)
737
QDict *options;
738
739
/* Create bs_a and its BlockBackend */
740
- blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
741
+ blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
742
bs_a = bdrv_new_open_driver(&bdrv_test, "bs_a", BDRV_O_RDWR, &error_abort);
743
blk_insert_bs(blk, bs_a, &error_abort);
744
745
@@ -XXX,XX +XXX,XX @@ static void test_propagate_diamond(void)
746
qdict_put_str(options, "raw", "bs_c");
747
748
bs_verify = bdrv_open(NULL, NULL, options, BDRV_O_RDWR, &error_abort);
749
- blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
750
+ blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
751
blk_insert_bs(blk, bs_verify, &error_abort);
752
753
/* Switch the AioContext */
754
@@ -XXX,XX +XXX,XX @@ static void test_propagate_mirror(void)
755
g_assert(bdrv_get_aio_context(filter) == main_ctx);
756
757
/* With a BlockBackend on src, changing target must fail */
758
- blk = blk_new(0, BLK_PERM_ALL);
759
+ blk = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL);
760
blk_insert_bs(blk, src, &error_abort);
761
762
bdrv_try_set_aio_context(target, ctx, &local_err);
763
diff --git a/tests/test-blockjob.c b/tests/test-blockjob.c
764
index XXXXXXX..XXXXXXX 100644
765
--- a/tests/test-blockjob.c
766
+++ b/tests/test-blockjob.c
767
@@ -XXX,XX +XXX,XX @@ static BlockJob *do_test_id(BlockBackend *blk, const char *id,
768
static BlockBackend *create_blk(const char *name)
769
{
770
/* No I/O is performed on this device */
771
- BlockBackend *blk = blk_new(0, BLK_PERM_ALL);
772
+ BlockBackend *blk = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL);
773
BlockDriverState *bs;
774
775
bs = bdrv_open("null-co://", NULL, NULL, 0, &error_abort);
776
diff --git a/tests/test-throttle.c b/tests/test-throttle.c
777
index XXXXXXX..XXXXXXX 100644
778
--- a/tests/test-throttle.c
779
+++ b/tests/test-throttle.c
780
@@ -XXX,XX +XXX,XX @@ static void test_groups(void)
781
ThrottleGroupMember *tgm1, *tgm2, *tgm3;
782
783
/* No actual I/O is performed on these devices */
784
- blk1 = blk_new(0, BLK_PERM_ALL);
785
- blk2 = blk_new(0, BLK_PERM_ALL);
786
- blk3 = blk_new(0, BLK_PERM_ALL);
787
+ blk1 = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL);
788
+ blk2 = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL);
789
+ blk3 = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL);
790
791
blkp1 = blk_get_public(blk1);
792
blkp2 = blk_get_public(blk2);
91
--
793
--
92
2.19.1
794
2.20.1
93
795
94
796
diff view generated by jsdifflib
1
From: Peter Maydell <peter.maydell@linaro.org>
1
Some qdev block devices have support for iothreads and take care of the
2
AioContext they are running in, but most devices don't know about any of
3
this. For the latter category, the qdev drive property must make sure
4
that their BlockBackend is in the main AioContext.
2
5
3
Taking the address of a field in a packed struct is a bad idea, because
6
Unfortunately, while the current code just does the same thing for
4
it might not be actually aligned enough for that pointer type (and
7
devices that do support iothreads, this is not correct and it would show
5
thus cause a crash on dereference on some host architectures). Newer
8
as soon as we actually try to keep a consistent AioContext assignment
6
versions of clang warn about this. Avoid the bug by not using the
9
across all nodes and users of a block graph subtree: If a node is
7
"modify in place" byte swapping functions.
10
already in a non-default AioContext because of one of its users,
11
attaching a new device should still be possible if that device can work
12
in the same AioContext. Switching the node back to the main context
13
first and only then into the device AioContext causes failure (because
14
the existing user wouldn't allow the switch to the main context).
8
15
9
There are a few places where the in-place swap function is
16
So devices that support iothreads need a different kind of drive
10
used on something other than a packed struct field; we convert
17
property that leaves the node in its current AioContext, but by using
11
those anyway, for consistency.
18
this type, the device promises to check later that it can work with this
19
context.
12
20
13
This patch was produced with the following spatch script:
21
This patch adds the qdev infrastructure that allows devices to signal
22
that they handle iothreads and qdev should leave the AioContext alone.
14
23
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>
50
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
24
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
51
---
25
---
52
block/qcow2-bitmap.c | 24 ++++++++++++------------
26
include/hw/block/block.h | 7 ++++--
53
1 file changed, 12 insertions(+), 12 deletions(-)
27
include/hw/qdev-properties.h | 3 +++
28
hw/core/qdev-properties-system.c | 43 ++++++++++++++++++++++++++++----
29
3 files changed, 46 insertions(+), 7 deletions(-)
54
30
55
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
31
diff --git a/include/hw/block/block.h b/include/hw/block/block.h
56
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
57
--- a/block/qcow2-bitmap.c
33
--- a/include/hw/block/block.h
58
+++ b/block/qcow2-bitmap.c
34
+++ b/include/hw/block/block.h
59
@@ -XXX,XX +XXX,XX @@ static inline void bitmap_table_to_be(uint64_t *bitmap_table, size_t size)
35
@@ -XXX,XX +XXX,XX @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
60
size_t i;
36
return exp;
61
37
}
62
for (i = 0; i < size; ++i) {
38
63
- cpu_to_be64s(&bitmap_table[i]);
39
-#define DEFINE_BLOCK_PROPERTIES(_state, _conf) \
64
+ bitmap_table[i] = cpu_to_be64(bitmap_table[i]);
40
- DEFINE_PROP_DRIVE("drive", _state, _conf.blk), \
41
+#define DEFINE_BLOCK_PROPERTIES_BASE(_state, _conf) \
42
DEFINE_PROP_BLOCKSIZE("logical_block_size", _state, \
43
_conf.logical_block_size), \
44
DEFINE_PROP_BLOCKSIZE("physical_block_size", _state, \
45
@@ -XXX,XX +XXX,XX @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
46
ON_OFF_AUTO_AUTO), \
47
DEFINE_PROP_BOOL("share-rw", _state, _conf.share_rw, false)
48
49
+#define DEFINE_BLOCK_PROPERTIES(_state, _conf) \
50
+ DEFINE_PROP_DRIVE("drive", _state, _conf.blk), \
51
+ DEFINE_BLOCK_PROPERTIES_BASE(_state, _conf)
52
+
53
#define DEFINE_BLOCK_CHS_PROPERTIES(_state, _conf) \
54
DEFINE_PROP_UINT32("cyls", _state, _conf.cyls, 0), \
55
DEFINE_PROP_UINT32("heads", _state, _conf.heads, 0), \
56
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
57
index XXXXXXX..XXXXXXX 100644
58
--- a/include/hw/qdev-properties.h
59
+++ b/include/hw/qdev-properties.h
60
@@ -XXX,XX +XXX,XX @@ extern const PropertyInfo qdev_prop_blockdev_on_error;
61
extern const PropertyInfo qdev_prop_bios_chs_trans;
62
extern const PropertyInfo qdev_prop_fdc_drive_type;
63
extern const PropertyInfo qdev_prop_drive;
64
+extern const PropertyInfo qdev_prop_drive_iothread;
65
extern const PropertyInfo qdev_prop_netdev;
66
extern const PropertyInfo qdev_prop_pci_devfn;
67
extern const PropertyInfo qdev_prop_blocksize;
68
@@ -XXX,XX +XXX,XX @@ extern const PropertyInfo qdev_prop_pcie_link_width;
69
DEFINE_PROP(_n, _s, _f, qdev_prop_netdev, NICPeers)
70
#define DEFINE_PROP_DRIVE(_n, _s, _f) \
71
DEFINE_PROP(_n, _s, _f, qdev_prop_drive, BlockBackend *)
72
+#define DEFINE_PROP_DRIVE_IOTHREAD(_n, _s, _f) \
73
+ DEFINE_PROP(_n, _s, _f, qdev_prop_drive_iothread, BlockBackend *)
74
#define DEFINE_PROP_MACADDR(_n, _s, _f) \
75
DEFINE_PROP(_n, _s, _f, qdev_prop_macaddr, MACAddr)
76
#define DEFINE_PROP_ON_OFF_AUTO(_n, _s, _f, _d) \
77
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/core/qdev-properties-system.c
80
+++ b/hw/core/qdev-properties-system.c
81
@@ -XXX,XX +XXX,XX @@ static void set_pointer(Object *obj, Visitor *v, Property *prop,
82
83
/* --- drive --- */
84
85
-static void parse_drive(DeviceState *dev, const char *str, void **ptr,
86
- const char *propname, Error **errp)
87
+static void do_parse_drive(DeviceState *dev, const char *str, void **ptr,
88
+ const char *propname, bool iothread, Error **errp)
89
{
90
BlockBackend *blk;
91
bool blk_created = false;
92
@@ -XXX,XX +XXX,XX @@ static void parse_drive(DeviceState *dev, const char *str, void **ptr,
93
if (!blk) {
94
BlockDriverState *bs = bdrv_lookup_bs(NULL, str, NULL);
95
if (bs) {
96
- /* BlockBackends of devices start in the main context and are only
97
- * later moved into another context if the device supports that. */
98
- blk = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL);
99
+ /*
100
+ * If the device supports iothreads, it will make sure to move the
101
+ * block node to the right AioContext if necessary (or fail if this
102
+ * isn't possible because of other users). Devices that are not
103
+ * aware of iothreads require their BlockBackends to be in the main
104
+ * AioContext.
105
+ */
106
+ AioContext *ctx = iothread ? bdrv_get_aio_context(bs) :
107
+ qemu_get_aio_context();
108
+ blk = blk_new(ctx, 0, BLK_PERM_ALL);
109
blk_created = true;
110
111
ret = blk_insert_bs(blk, bs, errp);
112
@@ -XXX,XX +XXX,XX @@ fail:
65
}
113
}
66
}
114
}
67
115
68
@@ -XXX,XX +XXX,XX @@ static int bitmap_table_load(BlockDriverState *bs, Qcow2BitmapTable *tb,
116
+static void parse_drive(DeviceState *dev, const char *str, void **ptr,
69
}
117
+ const char *propname, Error **errp)
70
118
+{
71
for (i = 0; i < tb->size; ++i) {
119
+ do_parse_drive(dev, str, ptr, propname, false, errp);
72
- be64_to_cpus(&table[i]);
120
+}
73
+ table[i] = be64_to_cpu(table[i]);
121
+
74
ret = check_table_entry(table[i], s->cluster_size);
122
+static void parse_drive_iothread(DeviceState *dev, const char *str, void **ptr,
75
if (ret < 0) {
123
+ const char *propname, Error **errp)
76
goto fail;
124
+{
77
@@ -XXX,XX +XXX,XX @@ fail:
125
+ do_parse_drive(dev, str, ptr, propname, true, errp);
78
126
+}
79
static inline void bitmap_dir_entry_to_cpu(Qcow2BitmapDirEntry *entry)
127
+
128
static void release_drive(Object *obj, const char *name, void *opaque)
80
{
129
{
81
- be64_to_cpus(&entry->bitmap_table_offset);
130
DeviceState *dev = DEVICE(obj);
82
- be32_to_cpus(&entry->bitmap_table_size);
131
@@ -XXX,XX +XXX,XX @@ static void set_drive(Object *obj, Visitor *v, const char *name, void *opaque,
83
- be32_to_cpus(&entry->flags);
132
set_pointer(obj, v, opaque, parse_drive, name, errp);
84
- be16_to_cpus(&entry->name_size);
85
- be32_to_cpus(&entry->extra_data_size);
86
+ entry->bitmap_table_offset = be64_to_cpu(entry->bitmap_table_offset);
87
+ entry->bitmap_table_size = be32_to_cpu(entry->bitmap_table_size);
88
+ entry->flags = be32_to_cpu(entry->flags);
89
+ entry->name_size = be16_to_cpu(entry->name_size);
90
+ entry->extra_data_size = be32_to_cpu(entry->extra_data_size);
91
}
133
}
92
134
93
static inline void bitmap_dir_entry_to_be(Qcow2BitmapDirEntry *entry)
135
+static void set_drive_iothread(Object *obj, Visitor *v, const char *name,
94
{
136
+ void *opaque, Error **errp)
95
- cpu_to_be64s(&entry->bitmap_table_offset);
137
+{
96
- cpu_to_be32s(&entry->bitmap_table_size);
138
+ set_pointer(obj, v, opaque, parse_drive_iothread, name, errp);
97
- cpu_to_be32s(&entry->flags);
139
+}
98
- cpu_to_be16s(&entry->name_size);
140
+
99
- cpu_to_be32s(&entry->extra_data_size);
141
const PropertyInfo qdev_prop_drive = {
100
+ entry->bitmap_table_offset = cpu_to_be64(entry->bitmap_table_offset);
142
.name = "str",
101
+ entry->bitmap_table_size = cpu_to_be32(entry->bitmap_table_size);
143
.description = "Node name or ID of a block device to use as a backend",
102
+ entry->flags = cpu_to_be32(entry->flags);
144
@@ -XXX,XX +XXX,XX @@ const PropertyInfo qdev_prop_drive = {
103
+ entry->name_size = cpu_to_be16(entry->name_size);
145
.release = release_drive,
104
+ entry->extra_data_size = cpu_to_be32(entry->extra_data_size);
146
};
105
}
147
106
148
+const PropertyInfo qdev_prop_drive_iothread = {
107
static inline int calc_dir_entry_size(size_t name_size, size_t extra_data_size)
149
+ .name = "str",
150
+ .description = "Node name or ID of a block device to use as a backend",
151
+ .get = get_drive,
152
+ .set = set_drive_iothread,
153
+ .release = release_drive,
154
+};
155
+
156
/* --- character device --- */
157
158
static void get_chr(Object *obj, Visitor *v, const char *name, void *opaque,
108
--
159
--
109
2.19.1
160
2.20.1
110
161
111
162
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
This makes use of qdev_prop_drive_iothread for scsi-disk so that the
2
disk can be attached to a node that is already in the target AioContext.
3
We need to check that the HBA actually supports iothreads, otherwise
4
scsi-disk must make sure that the node is already in the main
5
AioContext.
2
6
3
The blkverify mode of Quorum only works when the number of children is
7
This changes the error message for conflicting iothread settings.
4
exactly two, so any attempt to add a new one must return an error.
8
Previously, virtio-scsi produced the error message, now it comes from
9
blk_set_aio_context(). Update a test case accordingly.
5
10
6
quorum_del_child() on the other hand doesn't need any additional check
7
because decreasing the number of children would make it go under the
8
vote threshold.
9
10
Signed-off-by: Alberto Garcia <berto@igalia.com>
11
Reported-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
12
---
14
block/quorum.c | 8 ++++++++
13
include/hw/scsi/scsi.h | 1 +
15
1 file changed, 8 insertions(+)
14
hw/scsi/scsi-disk.c | 22 +++++++++++++++-------
15
hw/scsi/virtio-scsi.c | 15 ++++++++-------
16
tests/qemu-iotests/240.out | 2 +-
17
4 files changed, 25 insertions(+), 15 deletions(-)
16
18
17
diff --git a/block/quorum.c b/block/quorum.c
19
diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
18
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
19
--- a/block/quorum.c
21
--- a/include/hw/scsi/scsi.h
20
+++ b/block/quorum.c
22
+++ b/include/hw/scsi/scsi.h
21
@@ -XXX,XX +XXX,XX @@ static void quorum_add_child(BlockDriverState *bs, BlockDriverState *child_bs,
23
@@ -XXX,XX +XXX,XX @@ struct SCSIDevice
22
char indexstr[32];
24
int scsi_version;
23
int ret;
25
int default_scsi_version;
24
26
bool needs_vpd_bl_emulation;
25
+ if (s->is_blkverify) {
27
+ bool hba_supports_iothread;
26
+ error_setg(errp, "Cannot add a child to a quorum in blkverify mode");
28
};
29
30
extern const VMStateDescription vmstate_scsi_device;
31
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/scsi/scsi-disk.c
34
+++ b/hw/scsi/scsi-disk.c
35
@@ -XXX,XX +XXX,XX @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
36
return;
37
}
38
39
+ if (blk_get_aio_context(s->qdev.conf.blk) != qemu_get_aio_context() &&
40
+ !s->qdev.hba_supports_iothread)
41
+ {
42
+ error_setg(errp, "HBA does not support iothreads");
27
+ return;
43
+ return;
28
+ }
44
+ }
29
+
45
+
30
assert(s->num_children <= INT_MAX / sizeof(BdrvChild *));
46
if (dev->type == TYPE_DISK) {
31
if (s->num_children == INT_MAX / sizeof(BdrvChild *) ||
47
if (!blkconf_geometry(&dev->conf, NULL, 65535, 255, 255, errp)) {
32
s->next_child_index == UINT_MAX) {
48
return;
33
@@ -XXX,XX +XXX,XX @@ static void quorum_del_child(BlockDriverState *bs, BdrvChild *child,
49
@@ -XXX,XX +XXX,XX @@ static const TypeInfo scsi_disk_base_info = {
34
return;
50
.abstract = true,
51
};
52
53
-#define DEFINE_SCSI_DISK_PROPERTIES() \
54
- DEFINE_BLOCK_PROPERTIES(SCSIDiskState, qdev.conf), \
55
- DEFINE_BLOCK_ERROR_PROPERTIES(SCSIDiskState, qdev.conf), \
56
- DEFINE_PROP_STRING("ver", SCSIDiskState, version), \
57
- DEFINE_PROP_STRING("serial", SCSIDiskState, serial), \
58
- DEFINE_PROP_STRING("vendor", SCSIDiskState, vendor), \
59
- DEFINE_PROP_STRING("product", SCSIDiskState, product), \
60
+#define DEFINE_SCSI_DISK_PROPERTIES() \
61
+ DEFINE_PROP_DRIVE_IOTHREAD("drive", SCSIDiskState, qdev.conf.blk), \
62
+ DEFINE_BLOCK_PROPERTIES_BASE(SCSIDiskState, qdev.conf), \
63
+ DEFINE_BLOCK_ERROR_PROPERTIES(SCSIDiskState, qdev.conf), \
64
+ DEFINE_PROP_STRING("ver", SCSIDiskState, version), \
65
+ DEFINE_PROP_STRING("serial", SCSIDiskState, serial), \
66
+ DEFINE_PROP_STRING("vendor", SCSIDiskState, vendor), \
67
+ DEFINE_PROP_STRING("product", SCSIDiskState, product), \
68
DEFINE_PROP_STRING("device_id", SCSIDiskState, device_id)
69
70
71
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/hw/scsi/virtio-scsi.c
74
+++ b/hw/scsi/virtio-scsi.c
75
@@ -XXX,XX +XXX,XX @@ static void virtio_scsi_change(SCSIBus *bus, SCSIDevice *dev, SCSISense sense)
35
}
76
}
36
77
}
37
+ /* We know now that num_children > threshold, so blkverify must be false */
78
38
+ assert(!s->is_blkverify);
79
+static void virtio_scsi_pre_hotplug(HotplugHandler *hotplug_dev,
80
+ DeviceState *dev, Error **errp)
81
+{
82
+ SCSIDevice *sd = SCSI_DEVICE(dev);
83
+ sd->hba_supports_iothread = true;
84
+}
39
+
85
+
40
bdrv_drained_begin(bs);
86
static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev,
41
87
Error **errp)
42
/* We can safely remove this child now */
88
{
89
@@ -XXX,XX +XXX,XX @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev,
90
int ret;
91
92
if (s->ctx && !s->dataplane_fenced) {
93
- AioContext *ctx;
94
if (blk_op_is_blocked(sd->conf.blk, BLOCK_OP_TYPE_DATAPLANE, errp)) {
95
return;
96
}
97
- ctx = blk_get_aio_context(sd->conf.blk);
98
- if (ctx != s->ctx && ctx != qemu_get_aio_context()) {
99
- error_setg(errp, "Cannot attach a blockdev that is using "
100
- "a different iothread");
101
- return;
102
- }
103
virtio_scsi_acquire(s);
104
ret = blk_set_aio_context(sd->conf.blk, s->ctx, errp);
105
virtio_scsi_release(s);
106
@@ -XXX,XX +XXX,XX @@ static void virtio_scsi_class_init(ObjectClass *klass, void *data)
107
vdc->reset = virtio_scsi_reset;
108
vdc->start_ioeventfd = virtio_scsi_dataplane_start;
109
vdc->stop_ioeventfd = virtio_scsi_dataplane_stop;
110
+ hc->pre_plug = virtio_scsi_pre_hotplug;
111
hc->plug = virtio_scsi_hotplug;
112
hc->unplug = virtio_scsi_hotunplug;
113
}
114
diff --git a/tests/qemu-iotests/240.out b/tests/qemu-iotests/240.out
115
index XXXXXXX..XXXXXXX 100644
116
--- a/tests/qemu-iotests/240.out
117
+++ b/tests/qemu-iotests/240.out
118
@@ -XXX,XX +XXX,XX @@ QMP_VERSION
119
{"return": {}}
120
{"return": {}}
121
{"return": {}}
122
-{"error": {"class": "GenericError", "desc": "Cannot attach a blockdev that is using a different iothread"}}
123
+{"error": {"class": "GenericError", "desc": "Cannot change iothread of active block backend"}}
124
{"return": {}}
125
{"return": {}}
126
{"return": {}}
43
--
127
--
44
2.19.1
128
2.20.1
45
129
46
130
diff view generated by jsdifflib
1
If read-only=off, but auto-read-only=on is given, open the file
1
So far, we only made sure that updating the AioContext of a node
2
read-write if we have the permissions, but instead of erroring out for
2
affected the whole subtree. However, if a node is newly attached to a
3
read-only files, just degrade to read-only.
3
new parent, we also need to make sure that both the subtree of the node
4
and the parent are in the same AioContext. This tries to move the new
5
child node to the parent AioContext and returns an error if this isn't
6
possible.
7
8
BlockBackends now actually apply their AioContext to their root node.
4
9
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
7
---
11
---
8
block/file-posix.c | 19 ++++++++++++++++---
12
include/block/block_int.h | 1 +
9
1 file changed, 16 insertions(+), 3 deletions(-)
13
block.c | 35 ++++++++++++++++++++++++++++++++++-
10
14
block/block-backend.c | 9 ++++-----
11
diff --git a/block/file-posix.c b/block/file-posix.c
15
blockjob.c | 10 ++++++++--
12
index XXXXXXX..XXXXXXX 100644
16
tests/test-bdrv-drain.c | 6 ++++--
13
--- a/block/file-posix.c
17
5 files changed, 51 insertions(+), 10 deletions(-)
14
+++ b/block/file-posix.c
18
15
@@ -XXX,XX +XXX,XX @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
19
diff --git a/include/block/block_int.h b/include/block/block_int.h
16
20
index XXXXXXX..XXXXXXX 100644
17
s->fd = -1;
21
--- a/include/block/block_int.h
18
fd = qemu_open(filename, s->open_flags, 0644);
22
+++ b/include/block/block_int.h
19
- if (fd < 0) {
23
@@ -XXX,XX +XXX,XX @@ void hmp_drive_add_node(Monitor *mon, const char *optstr);
20
- ret = -errno;
24
BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
21
- error_setg_errno(errp, errno, "Could not open '%s'", filename);
25
const char *child_name,
22
+ ret = fd < 0 ? -errno : 0;
26
const BdrvChildRole *child_role,
23
+
27
+ AioContext *ctx,
24
+ if (ret == -EACCES || ret == -EROFS) {
28
uint64_t perm, uint64_t shared_perm,
25
+ /* Try to degrade to read-only, but if it doesn't work, still use the
29
void *opaque, Error **errp);
26
+ * normal error message. */
30
void bdrv_root_unref_child(BdrvChild *child);
27
+ if (bdrv_apply_auto_read_only(bs, NULL, NULL) == 0) {
31
diff --git a/block.c b/block.c
28
+ bdrv_flags &= ~BDRV_O_RDWR;
32
index XXXXXXX..XXXXXXX 100644
29
+ raw_parse_flags(bdrv_flags, &s->open_flags);
33
--- a/block.c
30
+ assert(!(s->open_flags & O_CREAT));
34
+++ b/block.c
31
+ fd = qemu_open(filename, s->open_flags);
35
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs)
32
+ ret = fd < 0 ? -errno : 0;
36
*
37
* On failure NULL is returned, errp is set and the reference to
38
* child_bs is also dropped.
39
+ *
40
+ * The caller must hold the AioContext lock @child_bs, but not that of @ctx
41
+ * (unless @child_bs is already in @ctx).
42
*/
43
BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
44
const char *child_name,
45
const BdrvChildRole *child_role,
46
+ AioContext *ctx,
47
uint64_t perm, uint64_t shared_perm,
48
void *opaque, Error **errp)
49
{
50
BdrvChild *child;
51
+ Error *local_err = NULL;
52
int ret;
53
54
ret = bdrv_check_update_perm(child_bs, NULL, perm, shared_perm, NULL, errp);
55
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
56
.opaque = opaque,
57
};
58
59
+ /* If the AioContexts don't match, first try to move the subtree of
60
+ * child_bs into the AioContext of the new parent. If this doesn't work,
61
+ * try moving the parent into the AioContext of child_bs instead. */
62
+ if (bdrv_get_aio_context(child_bs) != ctx) {
63
+ ret = bdrv_try_set_aio_context(child_bs, ctx, &local_err);
64
+ if (ret < 0 && child_role->can_set_aio_ctx) {
65
+ GSList *ignore = g_slist_prepend(NULL, child);;
66
+ ctx = bdrv_get_aio_context(child_bs);
67
+ if (child_role->can_set_aio_ctx(child, ctx, &ignore, NULL)) {
68
+ error_free(local_err);
69
+ ret = 0;
70
+ g_slist_free(ignore);
71
+ ignore = g_slist_prepend(NULL, child);;
72
+ child_role->set_aio_ctx(child, ctx, &ignore);
73
+ }
74
+ g_slist_free(ignore);
75
+ }
76
+ if (ret < 0) {
77
+ error_propagate(errp, local_err);
78
+ g_free(child);
79
+ bdrv_abort_perm_update(child_bs);
80
+ return NULL;
33
+ }
81
+ }
34
+ }
82
+ }
35
+
83
+
36
+ if (ret < 0) {
84
/* This performs the matching bdrv_set_perm() for the above check. */
37
+ error_setg_errno(errp, -ret, "Could not open '%s'", filename);
85
bdrv_replace_child(child, child_bs);
38
if (ret == -EROFS) {
86
39
ret = -EACCES;
87
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
40
}
88
*
89
* On failure NULL is returned, errp is set and the reference to
90
* child_bs is also dropped.
91
+ *
92
+ * If @parent_bs and @child_bs are in different AioContexts, the caller must
93
+ * hold the AioContext lock for @child_bs, but not for @parent_bs.
94
*/
95
BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
96
BlockDriverState *child_bs,
97
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
98
bdrv_get_cumulative_perm(parent_bs, &perm, &shared_perm);
99
100
assert(parent_bs->drv);
101
- assert(bdrv_get_aio_context(parent_bs) == bdrv_get_aio_context(child_bs));
102
bdrv_child_perm(parent_bs, child_bs, NULL, child_role, NULL,
103
perm, shared_perm, &perm, &shared_perm);
104
105
child = bdrv_root_attach_child(child_bs, child_name, child_role,
106
+ bdrv_get_aio_context(parent_bs),
107
perm, shared_perm, parent_bs, errp);
108
if (child == NULL) {
109
return NULL;
110
diff --git a/block/block-backend.c b/block/block-backend.c
111
index XXXXXXX..XXXXXXX 100644
112
--- a/block/block-backend.c
113
+++ b/block/block-backend.c
114
@@ -XXX,XX +XXX,XX @@ BlockBackend *blk_new_open(const char *filename, const char *reference,
115
return NULL;
116
}
117
118
- blk->root = bdrv_root_attach_child(bs, "root", &child_root,
119
+ blk->root = bdrv_root_attach_child(bs, "root", &child_root, blk->ctx,
120
perm, BLK_PERM_ALL, blk, errp);
121
if (!blk->root) {
122
blk_unref(blk);
123
@@ -XXX,XX +XXX,XX @@ int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp)
124
{
125
ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
126
bdrv_ref(bs);
127
- blk->root = bdrv_root_attach_child(bs, "root", &child_root,
128
+ blk->root = bdrv_root_attach_child(bs, "root", &child_root, blk->ctx,
129
blk->perm, blk->shared_perm, blk, errp);
130
if (blk->root == NULL) {
131
return -EPERM;
132
@@ -XXX,XX +XXX,XX @@ AioContext *blk_get_aio_context(BlockBackend *blk)
133
{
134
BlockDriverState *bs = blk_bs(blk);
135
136
- /* FIXME The AioContext of bs and blk can be inconsistent. For the moment,
137
- * we prefer the one of bs for compatibility. */
138
if (bs) {
139
- return bdrv_get_aio_context(blk_bs(blk));
140
+ AioContext *ctx = bdrv_get_aio_context(blk_bs(blk));
141
+ assert(ctx == blk->ctx);
142
}
143
144
return blk->ctx;
145
diff --git a/blockjob.c b/blockjob.c
146
index XXXXXXX..XXXXXXX 100644
147
--- a/blockjob.c
148
+++ b/blockjob.c
149
@@ -XXX,XX +XXX,XX @@ int block_job_add_bdrv(BlockJob *job, const char *name, BlockDriverState *bs,
150
BdrvChild *c;
151
152
bdrv_ref(bs);
153
- c = bdrv_root_attach_child(bs, name, &child_job, perm, shared_perm,
154
- job, errp);
155
+ if (job->job.aio_context != qemu_get_aio_context()) {
156
+ aio_context_release(job->job.aio_context);
157
+ }
158
+ c = bdrv_root_attach_child(bs, name, &child_job, job->job.aio_context,
159
+ perm, shared_perm, job, errp);
160
+ if (job->job.aio_context != qemu_get_aio_context()) {
161
+ aio_context_acquire(job->job.aio_context);
162
+ }
163
if (c == NULL) {
164
return -EPERM;
165
}
166
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
167
index XXXXXXX..XXXXXXX 100644
168
--- a/tests/test-bdrv-drain.c
169
+++ b/tests/test-bdrv-drain.c
170
@@ -XXX,XX +XXX,XX @@ static void test_blockjob_common_drain_node(enum drain_type drain_type,
171
&error_abort);
172
blk_target = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
173
blk_insert_bs(blk_target, target, &error_abort);
174
+ blk_set_allow_aio_context_change(blk_target, true);
175
176
aio_context_acquire(ctx);
177
tjob = block_job_create("job0", &test_job_driver, NULL, src,
178
@@ -XXX,XX +XXX,XX @@ static void test_blockjob_common_drain_node(enum drain_type drain_type,
179
g_assert_false(job->job.paused);
180
g_assert_true(job->job.busy); /* We're in qemu_co_sleep_ns() */
181
182
- do_drain_begin(drain_type, target);
183
+ do_drain_begin_unlocked(drain_type, target);
184
185
if (drain_type == BDRV_DRAIN_ALL) {
186
/* bdrv_drain_all() drains both src and target */
187
@@ -XXX,XX +XXX,XX @@ static void test_blockjob_common_drain_node(enum drain_type drain_type,
188
g_assert_true(job->job.paused);
189
g_assert_false(job->job.busy); /* The job is paused */
190
191
- do_drain_end(drain_type, target);
192
+ do_drain_end_unlocked(drain_type, target);
193
194
if (use_iothread) {
195
/* paused is reset in the I/O thread, wait for it */
196
@@ -XXX,XX +XXX,XX @@ static void test_blockjob_common_drain_node(enum drain_type drain_type,
197
198
if (use_iothread) {
199
blk_set_aio_context(blk_src, qemu_get_aio_context(), &error_abort);
200
+ blk_set_aio_context(blk_target, qemu_get_aio_context(), &error_abort);
201
}
202
aio_context_release(ctx);
203
41
--
204
--
42
2.19.1
205
2.20.1
43
206
44
207
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
Opening a new parent node for a node that has already been moved into a
2
different AioContext must cause the new parent to move into the same
3
context.
2
4
3
Just like in qemu_opts_print_help(), print the device name as a caption
4
instead of on every single line, indent all options, add angle brackets
5
around types, and align the descriptions after 24 characters. Also,
6
separate the descriptions with " - " instead of putting them in
7
parentheses, because that is what we do everywhere else. This does look
8
a bit funny here because basically all bits have the description
9
"on/off", but funny does not mean it is less readable.
10
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>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
6
---
15
qdev-monitor.c | 13 +++++++++++--
7
tests/test-block-iothread.c | 33 +++++++++++++++++++++++++++++++++
16
1 file changed, 11 insertions(+), 2 deletions(-)
8
1 file changed, 33 insertions(+)
17
9
18
diff --git a/qdev-monitor.c b/qdev-monitor.c
10
diff --git a/tests/test-block-iothread.c b/tests/test-block-iothread.c
19
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
20
--- a/qdev-monitor.c
12
--- a/tests/test-block-iothread.c
21
+++ b/qdev-monitor.c
13
+++ b/tests/test-block-iothread.c
22
@@ -XXX,XX +XXX,XX @@ int qdev_device_help(QemuOpts *opts)
14
@@ -XXX,XX +XXX,XX @@ static void test_propagate_mirror(void)
23
goto error;
15
bdrv_unref(target);
16
}
17
18
+static void test_attach_second_node(void)
19
+{
20
+ IOThread *iothread = iothread_new();
21
+ AioContext *ctx = iothread_get_aio_context(iothread);
22
+ AioContext *main_ctx = qemu_get_aio_context();
23
+ BlockBackend *blk;
24
+ BlockDriverState *bs, *filter;
25
+ QDict *options;
26
+
27
+ blk = blk_new(ctx, BLK_PERM_ALL, BLK_PERM_ALL);
28
+ bs = bdrv_new_open_driver(&bdrv_test, "base", BDRV_O_RDWR, &error_abort);
29
+ blk_insert_bs(blk, bs, &error_abort);
30
+
31
+ options = qdict_new();
32
+ qdict_put_str(options, "driver", "raw");
33
+ qdict_put_str(options, "file", "base");
34
+
35
+ filter = bdrv_open(NULL, NULL, options, BDRV_O_RDWR, &error_abort);
36
+ g_assert(blk_get_aio_context(blk) == ctx);
37
+ g_assert(bdrv_get_aio_context(bs) == ctx);
38
+ g_assert(bdrv_get_aio_context(filter) == ctx);
39
+
40
+ blk_set_aio_context(blk, main_ctx, &error_abort);
41
+ g_assert(blk_get_aio_context(blk) == main_ctx);
42
+ g_assert(bdrv_get_aio_context(bs) == main_ctx);
43
+ g_assert(bdrv_get_aio_context(filter) == main_ctx);
44
+
45
+ bdrv_unref(filter);
46
+ bdrv_unref(bs);
47
+ blk_unref(blk);
48
+}
49
+
50
int main(int argc, char **argv)
51
{
52
int i;
53
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
24
}
54
}
25
55
26
+ if (prop_list) {
56
g_test_add_func("/attach/blockjob", test_attach_blockjob);
27
+ out_printf("%s options:\n", driver);
57
+ g_test_add_func("/attach/second_node", test_attach_second_node);
28
+ } else {
58
g_test_add_func("/propagate/basic", test_propagate_basic);
29
+ out_printf("There are no options for %s.\n", driver);
59
g_test_add_func("/propagate/diamond", test_propagate_diamond);
30
+ }
60
g_test_add_func("/propagate/mirror", test_propagate_mirror);
31
for (prop = prop_list; prop; prop = prop->next) {
32
- out_printf("%s.%s=%s", driver, prop->value->name, prop->value->type);
33
+ int len;
34
+ out_printf(" %s=<%s>%n", prop->value->name, prop->value->type, &len);
35
if (prop->value->has_description) {
36
- out_printf(" (%s)\n", prop->value->description);
37
+ if (len < 24) {
38
+ out_printf("%*s", 24 - len, "");
39
+ }
40
+ out_printf(" - %s\n", prop->value->description);
41
} else {
42
out_printf("\n");
43
}
44
--
61
--
45
2.19.1
62
2.20.1
46
63
47
64
diff view generated by jsdifflib
1
From: Leonid Bloch <lbloch@janustech.com>
1
Test that BlockBackends preserve their assigned AioContext even when the
2
root node goes away. Inserting a new root node will move it to the right
3
AioContext.
2
4
3
If an expression is used to define DEFAULT_CLUSTER_SIZE, when compiled,
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.
7
8
Signed-off-by: Leonid Bloch <lbloch@janustech.com>
9
Reviewed-by: Stefan Weil <sw@weilnetz.de>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
6
---
12
block/vdi.c | 4 ++--
7
tests/test-block-iothread.c | 33 +++++++++++++++++++++++++++++++++
13
1 file changed, 2 insertions(+), 2 deletions(-)
8
1 file changed, 33 insertions(+)
14
9
15
diff --git a/block/vdi.c b/block/vdi.c
10
diff --git a/tests/test-block-iothread.c b/tests/test-block-iothread.c
16
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
17
--- a/block/vdi.c
12
--- a/tests/test-block-iothread.c
18
+++ b/block/vdi.c
13
+++ b/tests/test-block-iothread.c
19
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ static void test_attach_second_node(void)
20
#define BLOCK_OPT_STATIC "static"
15
blk_unref(blk);
21
16
}
22
#define SECTOR_SIZE 512
17
23
-#define DEFAULT_CLUSTER_SIZE (1 * MiB)
18
+static void test_attach_preserve_blk_ctx(void)
24
+#define DEFAULT_CLUSTER_SIZE S_1MiB
19
+{
25
20
+ IOThread *iothread = iothread_new();
26
#if defined(CONFIG_VDI_DEBUG)
21
+ AioContext *ctx = iothread_get_aio_context(iothread);
27
#define VDI_DEBUG 1
22
+ BlockBackend *blk;
28
@@ -XXX,XX +XXX,XX @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
23
+ BlockDriverState *bs;
29
goto fail;
24
+
30
} else if (header.block_size != DEFAULT_CLUSTER_SIZE) {
25
+ blk = blk_new(ctx, BLK_PERM_ALL, BLK_PERM_ALL);
31
error_setg(errp, "unsupported VDI image (block size %" PRIu32
26
+ bs = bdrv_new_open_driver(&bdrv_test, "base", BDRV_O_RDWR, &error_abort);
32
- " is not %" PRIu64 ")",
27
+ bs->total_sectors = 65536 / BDRV_SECTOR_SIZE;
33
+ " is not %" PRIu32 ")",
28
+
34
header.block_size, DEFAULT_CLUSTER_SIZE);
29
+ /* Add node to BlockBackend that has an iothread context assigned */
35
ret = -ENOTSUP;
30
+ blk_insert_bs(blk, bs, &error_abort);
36
goto fail;
31
+ g_assert(blk_get_aio_context(blk) == ctx);
32
+ g_assert(bdrv_get_aio_context(bs) == ctx);
33
+
34
+ /* Remove the node again */
35
+ blk_remove_bs(blk);
36
+ /* TODO bs should move back to main context here */
37
+ g_assert(blk_get_aio_context(blk) == ctx);
38
+ g_assert(bdrv_get_aio_context(bs) == ctx);
39
+
40
+ /* Re-attach the node */
41
+ blk_insert_bs(blk, bs, &error_abort);
42
+ g_assert(blk_get_aio_context(blk) == ctx);
43
+ g_assert(bdrv_get_aio_context(bs) == ctx);
44
+
45
+ blk_set_aio_context(blk, qemu_get_aio_context(), &error_abort);
46
+ bdrv_unref(bs);
47
+ blk_unref(blk);
48
+}
49
+
50
int main(int argc, char **argv)
51
{
52
int i;
53
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
54
55
g_test_add_func("/attach/blockjob", test_attach_blockjob);
56
g_test_add_func("/attach/second_node", test_attach_second_node);
57
+ g_test_add_func("/attach/preserve_blk_ctx", test_attach_preserve_blk_ctx);
58
g_test_add_func("/propagate/basic", test_propagate_basic);
59
g_test_add_func("/propagate/diamond", test_propagate_diamond);
60
g_test_add_func("/propagate/mirror", test_propagate_mirror);
37
--
61
--
38
2.19.1
62
2.20.1
39
63
40
64
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
A node should only be in a non-default AioContext if a user is attached
2
to it that requires this. When the last parent of a node is gone, it can
3
move back to the main AioContext.
2
4
3
Signed-off-by: Alberto Garcia <berto@igalia.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
---
6
---
6
block.c | 6 +++---
7
block.c | 4 ++++
7
1 file changed, 3 insertions(+), 3 deletions(-)
8
tests/test-bdrv-drain.c | 2 +-
9
tests/test-block-iothread.c | 3 +--
10
3 files changed, 6 insertions(+), 3 deletions(-)
8
11
9
diff --git a/block.c b/block.c
12
diff --git a/block.c b/block.c
10
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
11
--- a/block.c
14
--- a/block.c
12
+++ b/block.c
15
+++ b/block.c
13
@@ -XXX,XX +XXX,XX @@ QemuOptsList bdrv_runtime_opts = {
16
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs)
14
.help = "try to optimize zero writes (off, on, unmap)",
17
bdrv_get_cumulative_perm(old_bs, &perm, &shared_perm);
15
},
18
bdrv_check_perm(old_bs, NULL, perm, shared_perm, NULL, &error_abort);
16
{
19
bdrv_set_perm(old_bs, perm, shared_perm);
17
- .name = "discard",
20
+
18
+ .name = BDRV_OPT_DISCARD,
21
+ /* When the parent requiring a non-default AioContext is removed, the
19
.type = QEMU_OPT_STRING,
22
+ * node moves back to the main AioContext */
20
.help = "discard operation (ignore/off, unmap/on)",
23
+ bdrv_try_set_aio_context(old_bs, qemu_get_aio_context(), NULL);
21
},
22
@@ -XXX,XX +XXX,XX @@ static int bdrv_open_common(BlockDriverState *bs, BlockBackend *file,
23
}
24
}
24
}
25
25
26
- discard = qemu_opt_get(opts, "discard");
26
if (new_bs) {
27
+ discard = qemu_opt_get(opts, BDRV_OPT_DISCARD);
27
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
28
if (discard != NULL) {
28
index XXXXXXX..XXXXXXX 100644
29
if (bdrv_parse_discard_flags(discard, &bs->open_flags) != 0) {
29
--- a/tests/test-bdrv-drain.c
30
error_setg(errp, "Invalid discard option");
30
+++ b/tests/test-bdrv-drain.c
31
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
31
@@ -XXX,XX +XXX,XX @@ static void test_blockjob_common_drain_node(enum drain_type drain_type,
32
32
33
update_flags_from_options(&reopen_state->flags, opts);
33
if (use_iothread) {
34
34
blk_set_aio_context(blk_src, qemu_get_aio_context(), &error_abort);
35
- discard = qemu_opt_get_del(opts, "discard");
35
- blk_set_aio_context(blk_target, qemu_get_aio_context(), &error_abort);
36
+ discard = qemu_opt_get_del(opts, BDRV_OPT_DISCARD);
36
+ assert(blk_get_aio_context(blk_target) == qemu_get_aio_context());
37
if (discard != NULL) {
37
}
38
if (bdrv_parse_discard_flags(discard, &reopen_state->flags) != 0) {
38
aio_context_release(ctx);
39
error_setg(errp, "Invalid discard option");
39
40
diff --git a/tests/test-block-iothread.c b/tests/test-block-iothread.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/tests/test-block-iothread.c
43
+++ b/tests/test-block-iothread.c
44
@@ -XXX,XX +XXX,XX @@ static void test_attach_preserve_blk_ctx(void)
45
46
/* Remove the node again */
47
blk_remove_bs(blk);
48
- /* TODO bs should move back to main context here */
49
g_assert(blk_get_aio_context(blk) == ctx);
50
- g_assert(bdrv_get_aio_context(bs) == ctx);
51
+ g_assert(bdrv_get_aio_context(bs) == qemu_get_aio_context());
52
53
/* Re-attach the node */
54
blk_insert_bs(blk, bs, &error_abort);
40
--
55
--
41
2.19.1
56
2.20.1
42
57
43
58
diff view generated by jsdifflib
Deleted patch
1
From: Stefan Weil <sw@weilnetz.de>
2
1
3
Use %zu instead of %zd for unsigned numbers.
4
5
This fixes two error messages from the LSTM static code analyzer:
6
7
This argument should be of type 'ssize_t' but is of type 'unsigned long'
8
9
Signed-off-by: Stefan Weil <sw@weilnetz.de>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
13
qemu-io-cmds.c | 4 ++--
14
1 file changed, 2 insertions(+), 2 deletions(-)
15
16
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/qemu-io-cmds.c
19
+++ b/qemu-io-cmds.c
20
@@ -XXX,XX +XXX,XX @@ static int readv_f(BlockBackend *blk, int argc, char **argv)
21
memset(cmp_buf, pattern, qiov.size);
22
if (memcmp(buf, cmp_buf, qiov.size)) {
23
printf("Pattern verification failed at offset %"
24
- PRId64 ", %zd bytes\n", offset, qiov.size);
25
+ PRId64 ", %zu bytes\n", offset, qiov.size);
26
ret = -EINVAL;
27
}
28
g_free(cmp_buf);
29
@@ -XXX,XX +XXX,XX @@ static void aio_read_done(void *opaque, int ret)
30
memset(cmp_buf, ctx->pattern, ctx->qiov.size);
31
if (memcmp(ctx->buf, cmp_buf, ctx->qiov.size)) {
32
printf("Pattern verification failed at offset %"
33
- PRId64 ", %zd bytes\n", ctx->offset, ctx->qiov.size);
34
+ PRId64 ", %zu bytes\n", ctx->offset, ctx->qiov.size);
35
}
36
g_free(cmp_buf);
37
}
38
--
39
2.19.1
40
41
diff view generated by jsdifflib
Deleted patch
1
From: Daniel P. Berrangé <berrange@redhat.com>
2
1
3
The qcow2 block driver expects to see a valid sector size even when it
4
has opened the crypto layer with QCRYPTO_BLOCK_OPEN_NO_IO.
5
6
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
7
Reviewed-by: Alberto Garcia <berto@igalia.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
10
crypto/block-qcow.c | 2 ++
11
1 file changed, 2 insertions(+)
12
13
diff --git a/crypto/block-qcow.c b/crypto/block-qcow.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/crypto/block-qcow.c
16
+++ b/crypto/block-qcow.c
17
@@ -XXX,XX +XXX,XX @@ qcrypto_block_qcow_open(QCryptoBlock *block,
18
Error **errp)
19
{
20
if (flags & QCRYPTO_BLOCK_OPEN_NO_IO) {
21
+ block->sector_size = QCRYPTO_BLOCK_QCOW_SECTOR_SIZE;
22
+ block->payload_offset = 0;
23
return 0;
24
} else {
25
if (!options->u.qcow.key_secret) {
26
--
27
2.19.1
28
29
diff view generated by jsdifflib
1
While we want machine interfaces like -blockdev and QMP blockdev-add to
1
Monitor commands can handle errors, so they can easily be converted to
2
add as little auto-detection as possible so that management tools are
2
using the safer bdrv_try_set_aio_context() function.
3
explicit about their needs, -drive is a convenience option for human
4
users. Enabling auto-read-only=on by default there enables users to use
5
read-only images for read-only guest devices without having to specify
6
read-only=on explicitly. If they try to attach the image to a read-write
7
device, they will still get an error message.
8
3
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Reviewed-by: Eric Blake <eblake@redhat.com>
11
---
5
---
12
blockdev.c | 1 +
6
blockdev.c | 44 ++++++++++++++++++++++++++++----------------
13
1 file changed, 1 insertion(+)
7
1 file changed, 28 insertions(+), 16 deletions(-)
14
8
15
diff --git a/blockdev.c b/blockdev.c
9
diff --git a/blockdev.c b/blockdev.c
16
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
17
--- a/blockdev.c
11
--- a/blockdev.c
18
+++ b/blockdev.c
12
+++ b/blockdev.c
19
@@ -XXX,XX +XXX,XX @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
13
@@ -XXX,XX +XXX,XX @@ static void external_snapshot_prepare(BlkActionState *common,
20
qdict_set_default_str(bs_opts, BDRV_OPT_CACHE_NO_FLUSH, "off");
14
DO_UPCAST(ExternalSnapshotState, common, common);
21
qdict_set_default_str(bs_opts, BDRV_OPT_READ_ONLY,
15
TransactionAction *action = common->action;
22
read_only ? "on" : "off");
16
AioContext *aio_context;
23
+ qdict_set_default_str(bs_opts, BDRV_OPT_AUTO_READ_ONLY, "on");
17
+ int ret;
24
assert((bdrv_flags & BDRV_O_CACHE_MASK) == 0);
18
25
19
/* 'blockdev-snapshot' and 'blockdev-snapshot-sync' have similar
26
if (runstate_check(RUN_STATE_INMIGRATE)) {
20
* purpose but a different set of parameters */
21
@@ -XXX,XX +XXX,XX @@ static void external_snapshot_prepare(BlkActionState *common,
22
goto out;
23
}
24
25
- bdrv_set_aio_context(state->new_bs, aio_context);
26
+ ret = bdrv_try_set_aio_context(state->new_bs, aio_context, errp);
27
+ if (ret < 0) {
28
+ goto out;
29
+ }
30
31
/* This removes our old bs and adds the new bs. This is an operation that
32
* can fail, so we need to do it in .prepare; undoing it for abort is
33
@@ -XXX,XX +XXX,XX @@ static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn,
34
int flags, job_flags = JOB_DEFAULT;
35
int64_t size;
36
bool set_backing_hd = false;
37
+ int ret;
38
39
if (!backup->has_speed) {
40
backup->speed = 0;
41
@@ -XXX,XX +XXX,XX @@ static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn,
42
goto out;
43
}
44
45
- bdrv_set_aio_context(target_bs, aio_context);
46
+ ret = bdrv_try_set_aio_context(target_bs, aio_context, errp);
47
+ if (ret < 0) {
48
+ bdrv_unref(target_bs);
49
+ goto out;
50
+ }
51
52
if (set_backing_hd) {
53
bdrv_set_backing_hd(target_bs, source, &local_err);
54
@@ -XXX,XX +XXX,XX @@ BlockJob *do_blockdev_backup(BlockdevBackup *backup, JobTxn *txn,
55
AioContext *aio_context;
56
BlockJob *job = NULL;
57
int job_flags = JOB_DEFAULT;
58
+ int ret;
59
60
if (!backup->has_speed) {
61
backup->speed = 0;
62
@@ -XXX,XX +XXX,XX @@ BlockJob *do_blockdev_backup(BlockdevBackup *backup, JobTxn *txn,
63
goto out;
64
}
65
66
- if (bdrv_get_aio_context(target_bs) != aio_context) {
67
- if (!bdrv_has_blk(target_bs)) {
68
- /* The target BDS is not attached, we can safely move it to another
69
- * AioContext. */
70
- bdrv_set_aio_context(target_bs, aio_context);
71
- } else {
72
- error_setg(errp, "Target is attached to a different thread from "
73
- "source.");
74
- goto out;
75
- }
76
+ ret = bdrv_try_set_aio_context(target_bs, aio_context, errp);
77
+ if (ret < 0) {
78
+ goto out;
79
}
80
81
if (backup->has_bitmap) {
82
@@ -XXX,XX +XXX,XX @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
83
int flags;
84
int64_t size;
85
const char *format = arg->format;
86
+ int ret;
87
88
bs = qmp_get_root_bs(arg->device, errp);
89
if (!bs) {
90
@@ -XXX,XX +XXX,XX @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
91
goto out;
92
}
93
94
- bdrv_set_aio_context(target_bs, aio_context);
95
+ ret = bdrv_try_set_aio_context(target_bs, aio_context, errp);
96
+ if (ret < 0) {
97
+ bdrv_unref(target_bs);
98
+ goto out;
99
+ }
100
101
blockdev_mirror_common(arg->has_job_id ? arg->job_id : NULL, bs, target_bs,
102
arg->has_replaces, arg->replaces, arg->sync,
103
@@ -XXX,XX +XXX,XX @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id,
104
AioContext *aio_context;
105
BlockMirrorBackingMode backing_mode = MIRROR_LEAVE_BACKING_CHAIN;
106
Error *local_err = NULL;
107
+ int ret;
108
109
bs = qmp_get_root_bs(device, errp);
110
if (!bs) {
111
@@ -XXX,XX +XXX,XX @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id,
112
aio_context = bdrv_get_aio_context(bs);
113
aio_context_acquire(aio_context);
114
115
- bdrv_set_aio_context(target_bs, aio_context);
116
+ ret = bdrv_try_set_aio_context(target_bs, aio_context, errp);
117
+ if (ret < 0) {
118
+ goto out;
119
+ }
120
121
blockdev_mirror_common(has_job_id ? job_id : NULL, bs, target_bs,
122
has_replaces, replaces, sync, backing_mode,
123
@@ -XXX,XX +XXX,XX @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id,
124
has_auto_dismiss, auto_dismiss,
125
&local_err);
126
error_propagate(errp, local_err);
127
-
128
+out:
129
aio_context_release(aio_context);
130
}
131
132
@@ -XXX,XX +XXX,XX @@ void qmp_x_blockdev_set_iothread(const char *node_name, StrOrNull *iothread,
133
old_context = bdrv_get_aio_context(bs);
134
aio_context_acquire(old_context);
135
136
- bdrv_set_aio_context(bs, new_context);
137
+ bdrv_try_set_aio_context(bs, new_context, errp);
138
139
aio_context_release(old_context);
140
}
27
--
141
--
28
2.19.1
142
2.20.1
29
143
30
144
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
The mirror and commit block jobs use bdrv_set_aio_context() to move
2
their filter node into the right AioContext before hooking it up in the
3
graph. Similarly, bdrv_open_backing_file() explicitly moves the backing
4
file node into the right AioContext first.
2
5
3
Following the example of qemu_opts_print_help(), indent all entries in
6
This isn't necessary any more, they get automatically moved into the
4
the list of character devices.
7
right context now when attaching them.
5
8
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
However, in the case of bdrv_open_backing_file() with a node reference,
7
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
10
it's actually not only unnecessary, but even wrong: The unchecked
11
bdrv_set_aio_context() changes the AioContext of the child node even if
12
other parents require it to retain the old context. So this is not only
13
a simplification, but a bug fix, too.
14
15
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1684342
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
17
---
10
chardev/char.c | 2 +-
18
block.c | 1 -
11
1 file changed, 1 insertion(+), 1 deletion(-)
19
block/commit.c | 2 --
20
block/mirror.c | 1 -
21
3 files changed, 4 deletions(-)
12
22
13
diff --git a/chardev/char.c b/chardev/char.c
23
diff --git a/block.c b/block.c
14
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
15
--- a/chardev/char.c
25
--- a/block.c
16
+++ b/chardev/char.c
26
+++ b/block.c
17
@@ -XXX,XX +XXX,XX @@ help_string_append(const char *name, void *opaque)
27
@@ -XXX,XX +XXX,XX @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
18
{
28
ret = -EINVAL;
19
GString *str = opaque;
29
goto free_exit;
20
30
}
21
- g_string_append_printf(str, "\n%s", name);
31
- bdrv_set_aio_context(backing_hd, bdrv_get_aio_context(bs));
22
+ g_string_append_printf(str, "\n %s", name);
32
23
}
33
if (implicit_backing) {
24
34
bdrv_refresh_filename(backing_hd);
25
static const char *chardev_alias_translate(const char *name)
35
diff --git a/block/commit.c b/block/commit.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/block/commit.c
38
+++ b/block/commit.c
39
@@ -XXX,XX +XXX,XX @@ void commit_start(const char *job_id, BlockDriverState *bs,
40
commit_top_bs->implicit = true;
41
}
42
commit_top_bs->total_sectors = top->total_sectors;
43
- bdrv_set_aio_context(commit_top_bs, bdrv_get_aio_context(top));
44
45
bdrv_append(commit_top_bs, top, &local_err);
46
if (local_err) {
47
@@ -XXX,XX +XXX,XX @@ int bdrv_commit(BlockDriverState *bs)
48
error_report_err(local_err);
49
goto ro_cleanup;
50
}
51
- bdrv_set_aio_context(commit_top_bs, bdrv_get_aio_context(backing_file_bs));
52
53
bdrv_set_backing_hd(commit_top_bs, backing_file_bs, &error_abort);
54
bdrv_set_backing_hd(bs, commit_top_bs, &error_abort);
55
diff --git a/block/mirror.c b/block/mirror.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/block/mirror.c
58
+++ b/block/mirror.c
59
@@ -XXX,XX +XXX,XX @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
60
BDRV_REQ_NO_FALLBACK;
61
bs_opaque = g_new0(MirrorBDSOpaque, 1);
62
mirror_top_bs->opaque = bs_opaque;
63
- bdrv_set_aio_context(mirror_top_bs, bdrv_get_aio_context(bs));
64
65
/* bdrv_append takes ownership of the mirror_top_bs reference, need to keep
66
* it alive until block_job_create() succeeds even if bs has no parent. */
26
--
67
--
27
2.19.1
68
2.20.1
28
69
29
70
diff view generated by jsdifflib
1
From: Peter Maydell <peter.maydell@linaro.org>
1
This tests that blockdev-add can correctly add a qcow2 overlay to an
2
image used by a virtio-scsi disk in an iothread. The interesting point
3
here is whether the newly added node gets correctly moved into the
4
iothread AioContext.
2
5
3
Taking the address of a field in a packed struct is a bad idea, because
6
If it isn't, we get an assertion failure in virtio-scsi while processing
4
it might not be actually aligned enough for that pointer type (and
7
the next request:
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
8
9
There are a few places where the in-place swap function is
9
virtio_scsi_ctx_check: Assertion `blk_get_aio_context(d->conf.blk) == s->ctx' failed.
10
used on something other than a packed struct field; we convert
11
those anyway, for consistency.
12
10
13
Patch produced with scripts/coccinelle/inplace-byteswaps.cocci.
14
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
---
12
---
19
block/vhdx.h | 12 ++---
13
tests/libqtest.h | 11 +++++++
20
block/vhdx-endian.c | 118 ++++++++++++++++++++++----------------------
14
tests/libqtest.c | 19 ++++++++++++
21
block/vhdx-log.c | 4 +-
15
tests/virtio-scsi-test.c | 62 ++++++++++++++++++++++++++++++++++++++++
22
block/vhdx.c | 18 +++----
16
3 files changed, 92 insertions(+)
23
4 files changed, 76 insertions(+), 76 deletions(-)
24
17
25
diff --git a/block/vhdx.h b/block/vhdx.h
18
diff --git a/tests/libqtest.h b/tests/libqtest.h
26
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
27
--- a/block/vhdx.h
20
--- a/tests/libqtest.h
28
+++ b/block/vhdx.h
21
+++ b/tests/libqtest.h
29
@@ -XXX,XX +XXX,XX @@ int vhdx_log_write_and_flush(BlockDriverState *bs, BDRVVHDXState *s,
22
@@ -XXX,XX +XXX,XX @@ static inline void qtest_end(void)
30
23
QDict *qmp(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
31
static inline void leguid_to_cpus(MSGUID *guid)
24
25
/**
26
+ * qmp_assert_success:
27
+ * @fmt...: QMP message to send to qemu, formatted like
28
+ * qobject_from_jsonf_nofail(). See parse_escape() for what's
29
+ * supported after '%'.
30
+ *
31
+ * Sends a QMP message to QEMU and asserts that a 'return' key is present in
32
+ * the response.
33
+ */
34
+void qmp_assert_success(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
35
+
36
+/*
37
* qmp_eventwait:
38
* @s: #event event to wait for.
39
*
40
diff --git a/tests/libqtest.c b/tests/libqtest.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/tests/libqtest.c
43
+++ b/tests/libqtest.c
44
@@ -XXX,XX +XXX,XX @@ QDict *qmp(const char *fmt, ...)
45
return response;
46
}
47
48
+void qmp_assert_success(const char *fmt, ...)
49
+{
50
+ va_list ap;
51
+ QDict *response;
52
+
53
+ va_start(ap, fmt);
54
+ response = qtest_vqmp(global_qtest, fmt, ap);
55
+ va_end(ap);
56
+
57
+ g_assert(response);
58
+ if (!qdict_haskey(response, "return")) {
59
+ QString *s = qobject_to_json_pretty(QOBJECT(response));
60
+ g_test_message("%s", qstring_get_str(s));
61
+ qobject_unref(s);
62
+ }
63
+ g_assert(qdict_haskey(response, "return"));
64
+ qobject_unref(response);
65
+}
66
+
67
char *hmp(const char *fmt, ...)
32
{
68
{
33
- le32_to_cpus(&guid->data1);
69
va_list ap;
34
- le16_to_cpus(&guid->data2);
70
diff --git a/tests/virtio-scsi-test.c b/tests/virtio-scsi-test.c
35
- le16_to_cpus(&guid->data3);
71
index XXXXXXX..XXXXXXX 100644
36
+ guid->data1 = le32_to_cpu(guid->data1);
72
--- a/tests/virtio-scsi-test.c
37
+ guid->data2 = le16_to_cpu(guid->data2);
73
+++ b/tests/virtio-scsi-test.c
38
+ guid->data3 = le16_to_cpu(guid->data3);
74
@@ -XXX,XX +XXX,XX @@ static void test_unaligned_write_same(void *obj, void *data,
75
qvirtio_scsi_pci_free(vs);
39
}
76
}
40
77
41
static inline void cpu_to_leguids(MSGUID *guid)
78
+static void test_iothread_attach_node(void *obj, void *data,
79
+ QGuestAllocator *t_alloc)
80
+{
81
+ QVirtioSCSI *scsi = obj;
82
+ QVirtioSCSIQueues *vs;
83
+ char tmp_path[] = "/tmp/qtest.XXXXXX";
84
+ int fd;
85
+ int ret;
86
+
87
+ uint8_t buf[512] = { 0 };
88
+ const uint8_t write_cdb[VIRTIO_SCSI_CDB_SIZE] = {
89
+ /* WRITE(10) to LBA 0, transfer length 1 */
90
+ 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00
91
+ };
92
+
93
+ alloc = t_alloc;
94
+ vs = qvirtio_scsi_init(scsi->vdev);
95
+
96
+ /* Create a temporary qcow2 overlay*/
97
+ fd = mkstemp(tmp_path);
98
+ g_assert(fd >= 0);
99
+ close(fd);
100
+
101
+ if (!have_qemu_img()) {
102
+ g_test_message("QTEST_QEMU_IMG not set or qemu-img missing; "
103
+ "skipping snapshot test");
104
+ goto fail;
105
+ }
106
+
107
+ mkqcow2(tmp_path, 64);
108
+
109
+ /* Attach the overlay to the null0 node */
110
+ qmp_assert_success("{'execute': 'blockdev-add', 'arguments': {"
111
+ " 'driver': 'qcow2', 'node-name': 'overlay',"
112
+ " 'backing': 'null0', 'file': {"
113
+ " 'driver': 'file', 'filename': %s}}}", tmp_path);
114
+
115
+ /* Send a request to see if the AioContext is still right */
116
+ ret = virtio_scsi_do_command(vs, write_cdb, NULL, 0, buf, 512, NULL);
117
+ g_assert_cmphex(ret, ==, 0);
118
+
119
+fail:
120
+ qvirtio_scsi_pci_free(vs);
121
+ unlink(tmp_path);
122
+}
123
+
124
static void *virtio_scsi_hotplug_setup(GString *cmd_line, void *arg)
42
{
125
{
43
- cpu_to_le32s(&guid->data1);
126
g_string_append(cmd_line,
44
- cpu_to_le16s(&guid->data2);
127
@@ -XXX,XX +XXX,XX @@ static void *virtio_scsi_setup(GString *cmd_line, void *arg)
45
- cpu_to_le16s(&guid->data3);
128
return arg;
46
+ guid->data1 = cpu_to_le32(guid->data1);
47
+ guid->data2 = cpu_to_le16(guid->data2);
48
+ guid->data3 = cpu_to_le16(guid->data3);
49
}
129
}
50
130
51
void vhdx_header_le_import(VHDXHeader *h);
131
+static void *virtio_scsi_setup_iothread(GString *cmd_line, void *arg)
52
diff --git a/block/vhdx-endian.c b/block/vhdx-endian.c
132
+{
53
index XXXXXXX..XXXXXXX 100644
133
+ g_string_append(cmd_line,
54
--- a/block/vhdx-endian.c
134
+ " -object iothread,id=thread0"
55
+++ b/block/vhdx-endian.c
135
+ " -blockdev driver=null-co,node-name=null0"
56
@@ -XXX,XX +XXX,XX @@ void vhdx_header_le_import(VHDXHeader *h)
136
+ " -device scsi-hd,drive=null0");
137
+ return arg;
138
+}
139
+
140
static void register_virtio_scsi_test(void)
57
{
141
{
58
assert(h != NULL);
142
QOSGraphTestOptions opts = { };
59
143
@@ -XXX,XX +XXX,XX @@ static void register_virtio_scsi_test(void)
60
- le32_to_cpus(&h->signature);
144
opts.before = virtio_scsi_setup;
61
- le32_to_cpus(&h->checksum);
145
qos_add_test("unaligned-write-same", "virtio-scsi",
62
- le64_to_cpus(&h->sequence_number);
146
test_unaligned_write_same, &opts);
63
+ h->signature = le32_to_cpu(h->signature);
147
+
64
+ h->checksum = le32_to_cpu(h->checksum);
148
+ opts.before = virtio_scsi_setup_iothread;
65
+ h->sequence_number = le64_to_cpu(h->sequence_number);
149
+ opts.edge = (QOSGraphEdgeOptions) {
66
150
+ .extra_device_opts = "iothread=thread0",
67
leguid_to_cpus(&h->file_write_guid);
151
+ };
68
leguid_to_cpus(&h->data_write_guid);
152
+ qos_add_test("iothread-attach-node", "virtio-scsi",
69
leguid_to_cpus(&h->log_guid);
153
+ test_iothread_attach_node, &opts);
70
71
- le16_to_cpus(&h->log_version);
72
- le16_to_cpus(&h->version);
73
- le32_to_cpus(&h->log_length);
74
- le64_to_cpus(&h->log_offset);
75
+ h->log_version = le16_to_cpu(h->log_version);
76
+ h->version = le16_to_cpu(h->version);
77
+ h->log_length = le32_to_cpu(h->log_length);
78
+ h->log_offset = le64_to_cpu(h->log_offset);
79
}
154
}
80
155
81
void vhdx_header_le_export(VHDXHeader *orig_h, VHDXHeader *new_h)
156
libqos_init(register_virtio_scsi_test);
82
@@ -XXX,XX +XXX,XX @@ void vhdx_log_desc_le_import(VHDXLogDescriptor *d)
83
{
84
assert(d != NULL);
85
86
- le32_to_cpus(&d->signature);
87
- le64_to_cpus(&d->file_offset);
88
- le64_to_cpus(&d->sequence_number);
89
+ d->signature = le32_to_cpu(d->signature);
90
+ d->file_offset = le64_to_cpu(d->file_offset);
91
+ d->sequence_number = le64_to_cpu(d->sequence_number);
92
}
93
94
void vhdx_log_desc_le_export(VHDXLogDescriptor *d)
95
{
96
assert(d != NULL);
97
98
- cpu_to_le32s(&d->signature);
99
- cpu_to_le32s(&d->trailing_bytes);
100
- cpu_to_le64s(&d->leading_bytes);
101
- cpu_to_le64s(&d->file_offset);
102
- cpu_to_le64s(&d->sequence_number);
103
+ d->signature = cpu_to_le32(d->signature);
104
+ d->trailing_bytes = cpu_to_le32(d->trailing_bytes);
105
+ d->leading_bytes = cpu_to_le64(d->leading_bytes);
106
+ d->file_offset = cpu_to_le64(d->file_offset);
107
+ d->sequence_number = cpu_to_le64(d->sequence_number);
108
}
109
110
void vhdx_log_data_le_import(VHDXLogDataSector *d)
111
{
112
assert(d != NULL);
113
114
- le32_to_cpus(&d->data_signature);
115
- le32_to_cpus(&d->sequence_high);
116
- le32_to_cpus(&d->sequence_low);
117
+ d->data_signature = le32_to_cpu(d->data_signature);
118
+ d->sequence_high = le32_to_cpu(d->sequence_high);
119
+ d->sequence_low = le32_to_cpu(d->sequence_low);
120
}
121
122
void vhdx_log_data_le_export(VHDXLogDataSector *d)
123
{
124
assert(d != NULL);
125
126
- cpu_to_le32s(&d->data_signature);
127
- cpu_to_le32s(&d->sequence_high);
128
- cpu_to_le32s(&d->sequence_low);
129
+ d->data_signature = cpu_to_le32(d->data_signature);
130
+ d->sequence_high = cpu_to_le32(d->sequence_high);
131
+ d->sequence_low = cpu_to_le32(d->sequence_low);
132
}
133
134
void vhdx_log_entry_hdr_le_import(VHDXLogEntryHeader *hdr)
135
{
136
assert(hdr != NULL);
137
138
- le32_to_cpus(&hdr->signature);
139
- le32_to_cpus(&hdr->checksum);
140
- le32_to_cpus(&hdr->entry_length);
141
- le32_to_cpus(&hdr->tail);
142
- le64_to_cpus(&hdr->sequence_number);
143
- le32_to_cpus(&hdr->descriptor_count);
144
+ hdr->signature = le32_to_cpu(hdr->signature);
145
+ hdr->checksum = le32_to_cpu(hdr->checksum);
146
+ hdr->entry_length = le32_to_cpu(hdr->entry_length);
147
+ hdr->tail = le32_to_cpu(hdr->tail);
148
+ hdr->sequence_number = le64_to_cpu(hdr->sequence_number);
149
+ hdr->descriptor_count = le32_to_cpu(hdr->descriptor_count);
150
leguid_to_cpus(&hdr->log_guid);
151
- le64_to_cpus(&hdr->flushed_file_offset);
152
- le64_to_cpus(&hdr->last_file_offset);
153
+ hdr->flushed_file_offset = le64_to_cpu(hdr->flushed_file_offset);
154
+ hdr->last_file_offset = le64_to_cpu(hdr->last_file_offset);
155
}
156
157
void vhdx_log_entry_hdr_le_export(VHDXLogEntryHeader *hdr)
158
{
159
assert(hdr != NULL);
160
161
- cpu_to_le32s(&hdr->signature);
162
- cpu_to_le32s(&hdr->checksum);
163
- cpu_to_le32s(&hdr->entry_length);
164
- cpu_to_le32s(&hdr->tail);
165
- cpu_to_le64s(&hdr->sequence_number);
166
- cpu_to_le32s(&hdr->descriptor_count);
167
+ hdr->signature = cpu_to_le32(hdr->signature);
168
+ hdr->checksum = cpu_to_le32(hdr->checksum);
169
+ hdr->entry_length = cpu_to_le32(hdr->entry_length);
170
+ hdr->tail = cpu_to_le32(hdr->tail);
171
+ hdr->sequence_number = cpu_to_le64(hdr->sequence_number);
172
+ hdr->descriptor_count = cpu_to_le32(hdr->descriptor_count);
173
cpu_to_leguids(&hdr->log_guid);
174
- cpu_to_le64s(&hdr->flushed_file_offset);
175
- cpu_to_le64s(&hdr->last_file_offset);
176
+ hdr->flushed_file_offset = cpu_to_le64(hdr->flushed_file_offset);
177
+ hdr->last_file_offset = cpu_to_le64(hdr->last_file_offset);
178
}
179
180
181
@@ -XXX,XX +XXX,XX @@ void vhdx_region_header_le_import(VHDXRegionTableHeader *hdr)
182
{
183
assert(hdr != NULL);
184
185
- le32_to_cpus(&hdr->signature);
186
- le32_to_cpus(&hdr->checksum);
187
- le32_to_cpus(&hdr->entry_count);
188
+ hdr->signature = le32_to_cpu(hdr->signature);
189
+ hdr->checksum = le32_to_cpu(hdr->checksum);
190
+ hdr->entry_count = le32_to_cpu(hdr->entry_count);
191
}
192
193
void vhdx_region_header_le_export(VHDXRegionTableHeader *hdr)
194
{
195
assert(hdr != NULL);
196
197
- cpu_to_le32s(&hdr->signature);
198
- cpu_to_le32s(&hdr->checksum);
199
- cpu_to_le32s(&hdr->entry_count);
200
+ hdr->signature = cpu_to_le32(hdr->signature);
201
+ hdr->checksum = cpu_to_le32(hdr->checksum);
202
+ hdr->entry_count = cpu_to_le32(hdr->entry_count);
203
}
204
205
void vhdx_region_entry_le_import(VHDXRegionTableEntry *e)
206
@@ -XXX,XX +XXX,XX @@ void vhdx_region_entry_le_import(VHDXRegionTableEntry *e)
207
assert(e != NULL);
208
209
leguid_to_cpus(&e->guid);
210
- le64_to_cpus(&e->file_offset);
211
- le32_to_cpus(&e->length);
212
- le32_to_cpus(&e->data_bits);
213
+ e->file_offset = le64_to_cpu(e->file_offset);
214
+ e->length = le32_to_cpu(e->length);
215
+ e->data_bits = le32_to_cpu(e->data_bits);
216
}
217
218
void vhdx_region_entry_le_export(VHDXRegionTableEntry *e)
219
@@ -XXX,XX +XXX,XX @@ void vhdx_region_entry_le_export(VHDXRegionTableEntry *e)
220
assert(e != NULL);
221
222
cpu_to_leguids(&e->guid);
223
- cpu_to_le64s(&e->file_offset);
224
- cpu_to_le32s(&e->length);
225
- cpu_to_le32s(&e->data_bits);
226
+ e->file_offset = cpu_to_le64(e->file_offset);
227
+ e->length = cpu_to_le32(e->length);
228
+ e->data_bits = cpu_to_le32(e->data_bits);
229
}
230
231
232
@@ -XXX,XX +XXX,XX @@ void vhdx_metadata_header_le_import(VHDXMetadataTableHeader *hdr)
233
{
234
assert(hdr != NULL);
235
236
- le64_to_cpus(&hdr->signature);
237
- le16_to_cpus(&hdr->entry_count);
238
+ hdr->signature = le64_to_cpu(hdr->signature);
239
+ hdr->entry_count = le16_to_cpu(hdr->entry_count);
240
}
241
242
void vhdx_metadata_header_le_export(VHDXMetadataTableHeader *hdr)
243
{
244
assert(hdr != NULL);
245
246
- cpu_to_le64s(&hdr->signature);
247
- cpu_to_le16s(&hdr->entry_count);
248
+ hdr->signature = cpu_to_le64(hdr->signature);
249
+ hdr->entry_count = cpu_to_le16(hdr->entry_count);
250
}
251
252
void vhdx_metadata_entry_le_import(VHDXMetadataTableEntry *e)
253
@@ -XXX,XX +XXX,XX @@ void vhdx_metadata_entry_le_import(VHDXMetadataTableEntry *e)
254
assert(e != NULL);
255
256
leguid_to_cpus(&e->item_id);
257
- le32_to_cpus(&e->offset);
258
- le32_to_cpus(&e->length);
259
- le32_to_cpus(&e->data_bits);
260
+ e->offset = le32_to_cpu(e->offset);
261
+ e->length = le32_to_cpu(e->length);
262
+ e->data_bits = le32_to_cpu(e->data_bits);
263
}
264
void vhdx_metadata_entry_le_export(VHDXMetadataTableEntry *e)
265
{
266
assert(e != NULL);
267
268
cpu_to_leguids(&e->item_id);
269
- cpu_to_le32s(&e->offset);
270
- cpu_to_le32s(&e->length);
271
- cpu_to_le32s(&e->data_bits);
272
+ e->offset = cpu_to_le32(e->offset);
273
+ e->length = cpu_to_le32(e->length);
274
+ e->data_bits = cpu_to_le32(e->data_bits);
275
}
276
diff --git a/block/vhdx-log.c b/block/vhdx-log.c
277
index XXXXXXX..XXXXXXX 100644
278
--- a/block/vhdx-log.c
279
+++ b/block/vhdx-log.c
280
@@ -XXX,XX +XXX,XX @@ static void vhdx_log_raw_to_le_sector(VHDXLogDescriptor *desc,
281
/* 8 + 4084 + 4 = 4096, 1 log sector */
282
memcpy(&desc->leading_bytes, data, 8);
283
data += 8;
284
- cpu_to_le64s(&desc->leading_bytes);
285
+ desc->leading_bytes = cpu_to_le64(desc->leading_bytes);
286
memcpy(sector->data, data, 4084);
287
data += 4084;
288
memcpy(&desc->trailing_bytes, data, 4);
289
- cpu_to_le32s(&desc->trailing_bytes);
290
+ desc->trailing_bytes = cpu_to_le32(desc->trailing_bytes);
291
data += 4;
292
293
sector->sequence_high = (uint32_t) (seq >> 32);
294
diff --git a/block/vhdx.c b/block/vhdx.c
295
index XXXXXXX..XXXXXXX 100644
296
--- a/block/vhdx.c
297
+++ b/block/vhdx.c
298
@@ -XXX,XX +XXX,XX @@ uint32_t vhdx_update_checksum(uint8_t *buf, size_t size, int crc_offset)
299
300
memset(buf + crc_offset, 0, sizeof(crc));
301
crc = crc32c(0xffffffff, buf, size);
302
- cpu_to_le32s(&crc);
303
+ crc = cpu_to_le32(crc);
304
memcpy(buf + crc_offset, &crc, sizeof(crc));
305
306
return crc;
307
@@ -XXX,XX +XXX,XX @@ static int vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s)
308
goto exit;
309
}
310
311
- le32_to_cpus(&s->params.block_size);
312
- le32_to_cpus(&s->params.data_bits);
313
+ s->params.block_size = le32_to_cpu(s->params.block_size);
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;
320
}
321
322
- le64_to_cpus(&s->virtual_disk_size);
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);
346
}
347
348
vhdx_guid_generate(&mt_page83->page_83_data);
349
@@ -XXX,XX +XXX,XX @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
350
sinfo.file_offset = ROUND_UP(sinfo.file_offset, MiB);
351
vhdx_update_bat_table_entry(blk_bs(blk), s, &sinfo, &unused, &unused,
352
block_state);
353
- cpu_to_le64s(&s->bat[sinfo.bat_idx]);
354
+ s->bat[sinfo.bat_idx] = cpu_to_le64(s->bat[sinfo.bat_idx]);
355
sector_num += s->sectors_per_block;
356
}
357
ret = blk_pwrite(blk, file_offset, s->bat, length, 0);
358
--
157
--
359
2.19.1
158
2.20.1
360
159
361
160
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
This tests that devices refuse to be attached to a node that has already
2
been moved to a different iothread if they can't be or aren't configured
3
to work in the same iothread.
2
4
3
Signed-off-by: Alberto Garcia <berto@igalia.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
---
6
---
6
tests/qemu-iotests/081 | 30 ++++++++++++++++++++++++++++++
7
tests/qemu-iotests/051 | 24 ++++++++++++++++++++++++
7
tests/qemu-iotests/081.out | 16 ++++++++++++++++
8
tests/qemu-iotests/051.out | 3 +++
8
2 files changed, 46 insertions(+)
9
tests/qemu-iotests/051.pc.out | 27 +++++++++++++++++++++++++++
10
3 files changed, 54 insertions(+)
9
11
10
diff --git a/tests/qemu-iotests/081 b/tests/qemu-iotests/081
12
diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051
11
index XXXXXXX..XXXXXXX 100755
13
index XXXXXXX..XXXXXXX 100755
12
--- a/tests/qemu-iotests/081
14
--- a/tests/qemu-iotests/051
13
+++ b/tests/qemu-iotests/081
15
+++ b/tests/qemu-iotests/051
14
@@ -XXX,XX +XXX,XX @@ echo "== checking that quorum is broken =="
16
@@ -XXX,XX +XXX,XX @@ case "$QEMU_DEFAULT_MACHINE" in
15
17
;;
16
$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
18
esac
17
19
18
+echo
20
+echo
19
+echo "== checking the blkverify mode with broken content =="
21
+echo === Attach to node in non-default iothread ===
22
+echo
20
+
23
+
21
+quorum="driver=raw,file.driver=quorum,file.vote-threshold=2,file.blkverify=on"
24
+case "$QEMU_DEFAULT_MACHINE" in
22
+quorum="$quorum,file.children.0.file.filename=$TEST_DIR/1.raw"
25
+ pc)
23
+quorum="$quorum,file.children.1.file.filename=$TEST_DIR/2.raw"
26
+ iothread="-drive file=$TEST_IMG,if=none,node-name=disk -object iothread,id=thread0 -device virtio-scsi,iothread=thread0,id=virtio-scsi0 -device scsi-hd,bus=virtio-scsi0.0,drive=disk,share-rw=on"
24
+quorum="$quorum,file.children.0.driver=raw"
25
+quorum="$quorum,file.children.1.driver=raw"
26
+
27
+
27
+$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
28
+ # Can't add a device in the main thread while virtio-scsi0 uses the node
29
+ run_qemu $iothread -device ide-hd,drive=disk,share-rw=on
30
+ run_qemu $iothread -device virtio-blk-pci,drive=disk,share-rw=on
31
+ run_qemu $iothread -device lsi53c895a,id=lsi0 -device scsi-hd,bus=lsi0.0,drive=disk,share-rw=on
32
+ run_qemu $iothread -device virtio-scsi,id=virtio-scsi1 -device scsi-hd,bus=virtio-scsi1.0,drive=disk,share-rw=on
28
+
33
+
29
+echo
34
+ # virtio-blk enables the iothread only when the driver initialises the
30
+echo "== writing the same data to both files =="
35
+ # device, so a second virtio-blk device can't be added even with the
36
+ # same iothread. virtio-scsi allows this.
37
+ run_qemu $iothread -device virtio-blk-pci,drive=disk,iohtread=iothread0,share-rw=on
38
+ run_qemu $iothread -device virtio-scsi,id=virtio-scsi1,iothread=thread0 -device scsi-hd,bus=virtio-scsi1.0,drive=disk,share-rw=on
39
+ ;;
40
+ *)
41
+ ;;
42
+esac
31
+
43
+
32
+$QEMU_IO -c "write -P 0x32 0 $size" "$TEST_DIR/1.raw" | _filter_qemu_io
44
echo
33
+$QEMU_IO -c "write -P 0x32 0 $size" "$TEST_DIR/2.raw" | _filter_qemu_io
45
echo === Read-only ===
46
echo
47
diff --git a/tests/qemu-iotests/051.out b/tests/qemu-iotests/051.out
48
index XXXXXXX..XXXXXXX 100644
49
--- a/tests/qemu-iotests/051.out
50
+++ b/tests/qemu-iotests/051.out
51
@@ -XXX,XX +XXX,XX @@ QEMU X.Y.Z monitor - type 'help' for more information
52
(qemu) QEMU_PROG: -drive if=virtio: Device needs media, but drive is empty
53
54
55
+=== Attach to node in non-default iothread ===
34
+
56
+
35
+echo
36
+echo "== checking the blkverify mode with valid content =="
37
+
57
+
38
+$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
58
=== Read-only ===
59
60
Testing: -drive file=TEST_DIR/t.qcow2,if=virtio,readonly=on
61
diff --git a/tests/qemu-iotests/051.pc.out b/tests/qemu-iotests/051.pc.out
62
index XXXXXXX..XXXXXXX 100644
63
--- a/tests/qemu-iotests/051.pc.out
64
+++ b/tests/qemu-iotests/051.pc.out
65
@@ -XXX,XX +XXX,XX @@ QEMU X.Y.Z monitor - type 'help' for more information
66
(qemu) QEMU_PROG: -device scsi-hd,drive=disk: Device needs media, but drive is empty
67
68
69
+=== Attach to node in non-default iothread ===
39
+
70
+
40
+echo
71
+Testing: -drive file=TEST_DIR/t.qcow2,if=none,node-name=disk -object iothread,id=thread0 -device virtio-scsi,iothread=thread0,id=virtio-scsi0 -device scsi-hd,bus=virtio-scsi0.0,drive=disk,share-rw=on -device ide-hd,drive=disk,share-rw=on
41
+echo "== checking the blkverify mode with invalid settings =="
72
+QEMU X.Y.Z monitor - type 'help' for more information
73
+(qemu) QEMU_PROG: -device ide-hd,drive=disk,share-rw=on: Cannot change iothread of active block backend
42
+
74
+
43
+quorum="$quorum,file.children.2.file.filename=$TEST_DIR/3.raw"
75
+Testing: -drive file=TEST_DIR/t.qcow2,if=none,node-name=disk -object iothread,id=thread0 -device virtio-scsi,iothread=thread0,id=virtio-scsi0 -device scsi-hd,bus=virtio-scsi0.0,drive=disk,share-rw=on -device virtio-blk-pci,drive=disk,share-rw=on
44
+quorum="$quorum,file.children.2.driver=raw"
76
+QEMU X.Y.Z monitor - type 'help' for more information
77
+(qemu) QEMU_PROG: -device virtio-blk-pci,drive=disk,share-rw=on: Cannot change iothread of active block backend
45
+
78
+
46
+$QEMU_IO -c "open -o $quorum" | _filter_qemu_io
79
+Testing: -drive file=TEST_DIR/t.qcow2,if=none,node-name=disk -object iothread,id=thread0 -device virtio-scsi,iothread=thread0,id=virtio-scsi0 -device scsi-hd,bus=virtio-scsi0.0,drive=disk,share-rw=on -device lsi53c895a,id=lsi0 -device scsi-hd,bus=lsi0.0,drive=disk,share-rw=on
80
+QEMU X.Y.Z monitor - type 'help' for more information
81
+(qemu) QEMU_PROG: -device scsi-hd,bus=lsi0.0,drive=disk,share-rw=on: HBA does not support iothreads
47
+
82
+
48
# success, all done
83
+Testing: -drive file=TEST_DIR/t.qcow2,if=none,node-name=disk -object iothread,id=thread0 -device virtio-scsi,iothread=thread0,id=virtio-scsi0 -device scsi-hd,bus=virtio-scsi0.0,drive=disk,share-rw=on -device virtio-scsi,id=virtio-scsi1 -device scsi-hd,bus=virtio-scsi1.0,drive=disk,share-rw=on
49
echo "*** done"
84
+QEMU X.Y.Z monitor - type 'help' for more information
50
rm -f $seq.full
85
+(qemu) QEMU_PROG: -device scsi-hd,bus=virtio-scsi1.0,drive=disk,share-rw=on: Cannot change iothread of active block backend
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
+
86
+
60
+== checking the blkverify mode with broken content ==
87
+Testing: -drive file=TEST_DIR/t.qcow2,if=none,node-name=disk -object iothread,id=thread0 -device virtio-scsi,iothread=thread0,id=virtio-scsi0 -device scsi-hd,bus=virtio-scsi0.0,drive=disk,share-rw=on -device virtio-blk-pci,drive=disk,iohtread=iothread0,share-rw=on
61
+quorum: offset=0 bytes=10485760 contents mismatch at offset 0
88
+QEMU X.Y.Z monitor - type 'help' for more information
89
+(qemu) QEMU_PROG: -device virtio-blk-pci,drive=disk,iohtread=iothread0,share-rw=on: Cannot change iothread of active block backend
62
+
90
+
63
+== writing the same data to both files ==
91
+Testing: -drive file=TEST_DIR/t.qcow2,if=none,node-name=disk -object iothread,id=thread0 -device virtio-scsi,iothread=thread0,id=virtio-scsi0 -device scsi-hd,bus=virtio-scsi0.0,drive=disk,share-rw=on -device virtio-scsi,id=virtio-scsi1,iothread=thread0 -device scsi-hd,bus=virtio-scsi1.0,drive=disk,share-rw=on
64
+wrote 10485760/10485760 bytes at offset 0
92
+QEMU X.Y.Z monitor - type 'help' for more information
65
+10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
93
+(qemu) quit
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
+
94
+
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
+
95
+
73
+== checking the blkverify mode with invalid settings ==
96
=== Read-only ===
74
+can't open: blkverify=on can only be set if there are exactly two files and vote-threshold is 2
97
75
*** done
98
Testing: -drive file=TEST_DIR/t.qcow2,if=floppy,readonly=on
76
--
99
--
77
2.19.1
100
2.20.1
78
101
79
102
diff view generated by jsdifflib
1
From: Cleber Rosa <crosa@redhat.com>
1
No reason to use the unchecked version in tests, even more so when these
2
are the last callers of bdrv_set_aio_context() outside of block.c.
2
3
3
While testing the Python 3 changes which touch the 083 test, I noticed
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:
7
8
raw: pass
9
bochs: not generic
10
cloop: not generic
11
parallels: fail
12
qcow: fail
13
qcow2: fail
14
qed: fail
15
vdi: fail
16
vhdx: fail
17
vmdk: fail
18
vpc: fail
19
luks: fail
20
21
The errors are a mixture I/O and "image not in xxx format", such as:
22
23
=== Check disconnect before data ===
24
25
Unexpected end-of-file before all bytes were read
26
-read failed: Input/output error
27
+can't open device nbd+tcp://127.0.0.1:PORT/foo: Could not open 'nbd://127.0.0.1:PORT/foo': Input/output error
28
29
=== Check disconnect after data ===
30
31
-read 512/512 bytes at offset 0
32
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
33
+can't open device nbd+tcp://127.0.0.1:PORT/foo: Image not in qcow format
34
35
I'm not aware if there's a quick fix, so, for the time being, it looks
36
like the honest approach is to make the test known to work on raw
37
only.
38
39
Signed-off-by: Cleber Rosa <crosa@redhat.com>
40
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
41
---
5
---
42
tests/qemu-iotests/083 | 2 +-
6
tests/test-bdrv-drain.c | 6 +++---
43
1 file changed, 1 insertion(+), 1 deletion(-)
7
1 file changed, 3 insertions(+), 3 deletions(-)
44
8
45
diff --git a/tests/qemu-iotests/083 b/tests/qemu-iotests/083
9
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
46
index XXXXXXX..XXXXXXX 100755
10
index XXXXXXX..XXXXXXX 100644
47
--- a/tests/qemu-iotests/083
11
--- a/tests/test-bdrv-drain.c
48
+++ b/tests/qemu-iotests/083
12
+++ b/tests/test-bdrv-drain.c
49
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
13
@@ -XXX,XX +XXX,XX @@ static void test_set_aio_context(void)
50
. ./common.rc
14
&error_abort);
51
. ./common.filter
15
52
16
bdrv_drained_begin(bs);
53
-_supported_fmt generic
17
- bdrv_set_aio_context(bs, ctx_a);
54
+_supported_fmt raw
18
+ bdrv_try_set_aio_context(bs, ctx_a, &error_abort);
55
_supported_proto nbd
19
56
_supported_os Linux
20
aio_context_acquire(ctx_a);
21
bdrv_drained_end(bs);
22
23
bdrv_drained_begin(bs);
24
- bdrv_set_aio_context(bs, ctx_b);
25
+ bdrv_try_set_aio_context(bs, ctx_b, &error_abort);
26
aio_context_release(ctx_a);
27
aio_context_acquire(ctx_b);
28
- bdrv_set_aio_context(bs, qemu_get_aio_context());
29
+ bdrv_try_set_aio_context(bs, qemu_get_aio_context(), &error_abort);
30
aio_context_release(ctx_b);
31
bdrv_drained_end(bs);
57
32
58
--
33
--
59
2.19.1
34
2.20.1
60
35
61
36
diff view generated by jsdifflib
Deleted patch
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2
Reviewed-by: Alberto Garcia <berto@igalia.com>
3
---
4
block/vpc.c | 2 ++
5
1 file changed, 2 insertions(+)
6
1
7
diff --git a/block/vpc.c b/block/vpc.c
8
index XXXXXXX..XXXXXXX 100644
9
--- a/block/vpc.c
10
+++ b/block/vpc.c
11
@@ -XXX,XX +XXX,XX @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
12
}
13
14
qemu_co_mutex_init(&s->lock);
15
+ qemu_opts_del(opts);
16
17
return 0;
18
19
fail:
20
+ qemu_opts_del(opts);
21
qemu_vfree(s->pagetable);
22
#ifdef CACHE
23
g_free(s->pageentry_u8);
24
--
25
2.19.1
26
27
diff view generated by jsdifflib
1
If a management application builds the block graph node by node, the
1
All callers of bdrv_set_aio_context() are eliminated now, they have
2
protocol layer doesn't inherit its read-only option from the format
2
moved to bdrv_try_set_aio_context() and related safe functions. Remove
3
layer any more, so it must be set explicitly.
3
bdrv_set_aio_context().
4
4
5
Backing files should work on read-only storage, but at the same time, a
5
With this, we can now know that the .set_aio_ctx callback must be
6
block job like commit should be able to reopen them read-write if they
6
present in bdrv_set_aio_context_ignore() because
7
are on read-write storage. However, without option inheritance, reopen
7
bdrv_can_set_aio_context() would have returned false previously, so
8
only changes the read-only option for the root node (typically the
8
instead of checking the condition, we can assert it.
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.
37
9
38
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
39
Reviewed-by: Eric Blake <eblake@redhat.com>
40
---
11
---
41
qapi/block-core.json | 7 +++++++
12
docs/devel/multiple-iothreads.txt | 4 ++--
42
include/block/block.h | 2 ++
13
include/block/block.h | 9 ---------
43
block.c | 17 +++++++++++++++++
14
block.c | 30 ++++++++++++++----------------
44
block/vvfat.c | 1 +
15
3 files changed, 16 insertions(+), 27 deletions(-)
45
blockdev.c | 2 +-
46
5 files changed, 28 insertions(+), 1 deletion(-)
47
16
48
diff --git a/qapi/block-core.json b/qapi/block-core.json
17
diff --git a/docs/devel/multiple-iothreads.txt b/docs/devel/multiple-iothreads.txt
49
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
50
--- a/qapi/block-core.json
19
--- a/docs/devel/multiple-iothreads.txt
51
+++ b/qapi/block-core.json
20
+++ b/docs/devel/multiple-iothreads.txt
52
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ The AioContext originates from the QEMU block layer, even though nowadays
53
# either generally or in certain configurations. In this case,
22
AioContext is a generic event loop that can be used by any QEMU subsystem.
54
# the default value does not work and the option must be
23
55
# specified explicitly.
24
The block layer has support for AioContext integrated. Each BlockDriverState
56
+# @auto-read-only: if true and @read-only is false, QEMU may automatically
25
-is associated with an AioContext using bdrv_set_aio_context() and
57
+# decide not to open the image read-write as requested, but
26
+is associated with an AioContext using bdrv_try_set_aio_context() and
58
+# fall back to read-only instead (and switch between the modes
27
bdrv_get_aio_context(). This allows block layer code to process I/O inside the
59
+# later), e.g. depending on whether the image file is writable
28
right AioContext. Other subsystems may wish to follow a similar approach.
60
+# or whether a writing user is attached to the node
29
61
+# (default: false, since 3.1)
30
@@ -XXX,XX +XXX,XX @@ Long-running jobs (usually in the form of coroutines) are best scheduled in
62
# @detect-zeroes: detect and optimize zero writes (Since 2.1)
31
the BlockDriverState's AioContext to avoid the need to acquire/release around
63
# (default: off)
32
each bdrv_*() call. The functions bdrv_add/remove_aio_context_notifier,
64
# @force-share: force share all permission on added nodes.
33
or alternatively blk_add/remove_aio_context_notifier if you use BlockBackends,
65
@@ -XXX,XX +XXX,XX @@
34
-can be used to get a notification whenever bdrv_set_aio_context() moves a
66
'*discard': 'BlockdevDiscardOptions',
35
+can be used to get a notification whenever bdrv_try_set_aio_context() moves a
67
'*cache': 'BlockdevCacheOptions',
36
BlockDriverState to a different AioContext.
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
37
diff --git a/include/block/block.h b/include/block/block.h
74
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
75
--- a/include/block/block.h
39
--- a/include/block/block.h
76
+++ b/include/block/block.h
40
+++ b/include/block/block.h
77
@@ -XXX,XX +XXX,XX @@ typedef struct HDGeometry {
41
@@ -XXX,XX +XXX,XX @@ AioContext *bdrv_get_aio_context(BlockDriverState *bs);
78
select an appropriate protocol driver,
42
*/
79
ignoring the format layer */
43
void bdrv_coroutine_enter(BlockDriverState *bs, Coroutine *co);
80
#define BDRV_O_NO_IO 0x10000 /* don't initialize for I/O */
44
81
+#define BDRV_O_AUTO_RDONLY 0x20000 /* degrade to read-only if opening read-write fails */
45
-/**
82
46
- * bdrv_set_aio_context:
83
#define BDRV_O_CACHE_MASK (BDRV_O_NOCACHE | BDRV_O_NO_FLUSH)
47
- *
84
48
- * Changes the #AioContext used for fd handlers, timers, and BHs by this
85
@@ -XXX,XX +XXX,XX @@ typedef struct HDGeometry {
49
- * BlockDriverState and all its children.
86
#define BDRV_OPT_CACHE_DIRECT "cache.direct"
50
- *
87
#define BDRV_OPT_CACHE_NO_FLUSH "cache.no-flush"
51
- * This function must be called with iothread lock held.
88
#define BDRV_OPT_READ_ONLY "read-only"
52
- */
89
+#define BDRV_OPT_AUTO_READ_ONLY "auto-read-only"
53
-void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context);
90
#define BDRV_OPT_DISCARD "discard"
54
void bdrv_set_aio_context_ignore(BlockDriverState *bs,
91
#define BDRV_OPT_FORCE_SHARE "force-share"
55
AioContext *new_context, GSList **ignore);
92
56
int bdrv_try_set_aio_context(BlockDriverState *bs, AioContext *ctx,
93
diff --git a/block.c b/block.c
57
diff --git a/block.c b/block.c
94
index XXXXXXX..XXXXXXX 100644
58
index XXXXXXX..XXXXXXX 100644
95
--- a/block.c
59
--- a/block.c
96
+++ b/block.c
60
+++ b/block.c
97
@@ -XXX,XX +XXX,XX @@ static void bdrv_inherited_options(int *child_flags, QDict *child_options,
61
@@ -XXX,XX +XXX,XX @@ static void bdrv_attach_aio_context(BlockDriverState *bs,
98
62
bs->walking_aio_notifiers = false;
99
/* Inherit the read-only option from the parent if it's not set */
63
}
100
qdict_copy_default(child_options, parent_options, BDRV_OPT_READ_ONLY);
64
101
+ qdict_copy_default(child_options, parent_options, BDRV_OPT_AUTO_READ_ONLY);
65
-/* @ignore will accumulate all visited BdrvChild object. The caller is
102
66
- * responsible for freeing the list afterwards. */
103
/* Our block drivers take care to send flushes and respect unmap policy,
67
+/*
104
* so we can default to enable both on lower layers regardless of the
68
+ * Changes the AioContext used for fd handlers, timers, and BHs by this
105
@@ -XXX,XX +XXX,XX @@ static void bdrv_backing_options(int *child_flags, QDict *child_options,
69
+ * BlockDriverState and all its children and parents.
106
70
+ *
107
/* backing files always opened read-only */
71
+ * The caller must own the AioContext lock for the old AioContext of bs, but it
108
qdict_set_default_str(child_options, BDRV_OPT_READ_ONLY, "on");
72
+ * must not own the AioContext lock for new_context (unless new_context is the
109
+ qdict_set_default_str(child_options, BDRV_OPT_AUTO_READ_ONLY, "off");
73
+ * same as the current context of bs).
110
flags &= ~BDRV_O_COPY_ON_READ;
74
+ *
111
75
+ * @ignore will accumulate all visited BdrvChild object. The caller is
112
/* snapshot=on is handled on the top layer */
76
+ * responsible for freeing the list afterwards.
113
@@ -XXX,XX +XXX,XX @@ static void update_flags_from_options(int *flags, QemuOpts *opts)
77
+ */
114
*flags |= BDRV_O_RDWR;
78
void bdrv_set_aio_context_ignore(BlockDriverState *bs,
79
AioContext *new_context, GSList **ignore)
80
{
81
@@ -XXX,XX +XXX,XX @@ void bdrv_set_aio_context_ignore(BlockDriverState *bs,
82
if (g_slist_find(*ignore, child)) {
83
continue;
84
}
85
- if (child->role->set_aio_ctx) {
86
- *ignore = g_slist_prepend(*ignore, child);
87
- child->role->set_aio_ctx(child, new_context, ignore);
88
- }
89
+ assert(child->role->set_aio_ctx);
90
+ *ignore = g_slist_prepend(*ignore, child);
91
+ child->role->set_aio_ctx(child, new_context, ignore);
115
}
92
}
116
93
117
+ assert(qemu_opt_find(opts, BDRV_OPT_AUTO_READ_ONLY));
94
bdrv_detach_aio_context(bs);
118
+ if (qemu_opt_get_bool_del(opts, BDRV_OPT_AUTO_READ_ONLY, false)) {
95
@@ -XXX,XX +XXX,XX @@ void bdrv_set_aio_context_ignore(BlockDriverState *bs,
119
+ *flags |= BDRV_O_AUTO_RDONLY;
96
aio_context_release(new_context);
120
+ }
121
}
97
}
122
98
123
static void update_options_from_flags(QDict *options, int flags)
99
-/* The caller must own the AioContext lock for the old AioContext of bs, but it
124
@@ -XXX,XX +XXX,XX @@ static void update_options_from_flags(QDict *options, int flags)
100
- * must not own the AioContext lock for new_context (unless new_context is
125
if (!qdict_haskey(options, BDRV_OPT_READ_ONLY)) {
101
- * the same as the current context of bs). */
126
qdict_put_bool(options, BDRV_OPT_READ_ONLY, !(flags & BDRV_O_RDWR));
102
-void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
127
}
103
-{
128
+ if (!qdict_haskey(options, BDRV_OPT_AUTO_READ_ONLY)) {
104
- GSList *ignore_list = NULL;
129
+ qdict_put_bool(options, BDRV_OPT_AUTO_READ_ONLY,
105
- bdrv_set_aio_context_ignore(bs, new_context, &ignore_list);
130
+ flags & BDRV_O_AUTO_RDONLY);
106
- g_slist_free(ignore_list);
131
+ }
107
-}
132
}
108
-
133
109
static bool bdrv_parent_can_set_aio_context(BdrvChild *c, AioContext *ctx,
134
static void bdrv_assign_node_name(BlockDriverState *bs,
110
GSList **ignore, Error **errp)
135
@@ -XXX,XX +XXX,XX @@ QemuOptsList bdrv_runtime_opts = {
136
.type = QEMU_OPT_BOOL,
137
.help = "Node is opened in read-only mode",
138
},
139
+ {
140
+ .name = BDRV_OPT_AUTO_READ_ONLY,
141
+ .type = QEMU_OPT_BOOL,
142
+ .help = "Node can become read-only if opening read-write fails",
143
+ },
144
{
145
.name = "detect-zeroes",
146
.type = QEMU_OPT_STRING,
147
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp)
148
qdict_set_default_str(qdict, BDRV_OPT_CACHE_DIRECT, "off");
149
qdict_set_default_str(qdict, BDRV_OPT_CACHE_NO_FLUSH, "off");
150
qdict_set_default_str(qdict, BDRV_OPT_READ_ONLY, "off");
151
+ qdict_set_default_str(qdict, BDRV_OPT_AUTO_READ_ONLY, "off");
152
+
153
}
154
155
bs = bdrv_open_inherit(NULL, reference, qdict, 0, NULL, NULL, errp);
156
diff --git a/block/vvfat.c b/block/vvfat.c
157
index XXXXXXX..XXXXXXX 100644
158
--- a/block/vvfat.c
159
+++ b/block/vvfat.c
160
@@ -XXX,XX +XXX,XX @@ static void vvfat_qcow_options(int *child_flags, QDict *child_options,
161
int parent_flags, QDict *parent_options)
162
{
111
{
163
qdict_set_default_str(child_options, BDRV_OPT_READ_ONLY, "off");
164
+ qdict_set_default_str(child_options, BDRV_OPT_AUTO_READ_ONLY, "off");
165
qdict_set_default_str(child_options, BDRV_OPT_CACHE_NO_FLUSH, "on");
166
}
167
168
diff --git a/blockdev.c b/blockdev.c
169
index XXXXXXX..XXXXXXX 100644
170
--- a/blockdev.c
171
+++ b/blockdev.c
172
@@ -XXX,XX +XXX,XX @@ void qmp_blockdev_change_medium(bool has_device, const char *device,
173
174
bdrv_flags = blk_get_open_flags_from_root_state(blk);
175
bdrv_flags &= ~(BDRV_O_TEMPORARY | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING |
176
- BDRV_O_PROTOCOL);
177
+ BDRV_O_PROTOCOL | BDRV_O_AUTO_RDONLY);
178
179
if (!has_read_only) {
180
read_only = BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN;
181
--
112
--
182
2.19.1
113
2.20.1
183
114
184
115
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
The blkverify mode of Quorum can only be enabled if the number of
3
Let's at least trace ignored failure.
4
children is exactly two and the value of vote-threshold is also two.
5
4
6
If the user tries to enable it but the other settings are incorrect
5
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
then QEMU simply prints an error message to stderr and carries on
6
Reviewed-by: Eric Blake <eblake@redhat.com>
8
disabling the blkverify setting.
9
10
This patch makes quorum_open() fail and return an error in this case.
11
12
Signed-off-by: Alberto Garcia <berto@igalia.com>
13
Reported-by: Markus Armbruster <armbru@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
8
---
16
block/quorum.c | 13 ++++++-------
9
block/qcow2-refcount.c | 7 ++++++-
17
1 file changed, 6 insertions(+), 7 deletions(-)
10
block/trace-events | 3 +++
11
2 files changed, 9 insertions(+), 1 deletion(-)
18
12
19
diff --git a/block/quorum.c b/block/quorum.c
13
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
20
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
21
--- a/block/quorum.c
15
--- a/block/qcow2-refcount.c
22
+++ b/block/quorum.c
16
+++ b/block/qcow2-refcount.c
23
@@ -XXX,XX +XXX,XX @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags,
17
@@ -XXX,XX +XXX,XX @@
24
s->read_pattern = ret;
18
#include "qemu/range.h"
25
19
#include "qemu/bswap.h"
26
if (s->read_pattern == QUORUM_READ_PATTERN_QUORUM) {
20
#include "qemu/cutils.h"
27
- /* is the driver in blkverify mode */
21
+#include "trace.h"
28
- if (qemu_opt_get_bool(opts, QUORUM_OPT_BLKVERIFY, false) &&
22
29
- s->num_children == 2 && s->threshold == 2) {
23
static int64_t alloc_clusters_noref(BlockDriverState *bs, uint64_t size,
30
- s->is_blkverify = true;
24
uint64_t max);
31
- } else if (qemu_opt_get_bool(opts, QUORUM_OPT_BLKVERIFY, false)) {
25
@@ -XXX,XX +XXX,XX @@ void qcow2_process_discards(BlockDriverState *bs, int ret)
32
- fprintf(stderr, "blkverify mode is set by setting blkverify=on "
26
33
- "and using two files with vote_threshold=2\n");
27
/* Discard is optional, ignore the return value */
34
+ s->is_blkverify = qemu_opt_get_bool(opts, QUORUM_OPT_BLKVERIFY, false);
28
if (ret >= 0) {
35
+ if (s->is_blkverify && (s->num_children != 2 || s->threshold != 2)) {
29
- bdrv_pdiscard(bs->file, d->offset, d->bytes);
36
+ error_setg(&local_err, "blkverify=on can only be set if there are "
30
+ int r2 = bdrv_pdiscard(bs->file, d->offset, d->bytes);
37
+ "exactly two files and vote-threshold is 2");
31
+ if (r2 < 0) {
38
+ ret = -EINVAL;
32
+ trace_qcow2_process_discards_failed_region(d->offset, d->bytes,
39
+ goto exit;
33
+ r2);
34
+ }
40
}
35
}
41
36
42
s->rewrite_corrupted = qemu_opt_get_bool(opts, QUORUM_OPT_REWRITE,
37
g_free(d);
38
diff --git a/block/trace-events b/block/trace-events
39
index XXXXXXX..XXXXXXX 100644
40
--- a/block/trace-events
41
+++ b/block/trace-events
42
@@ -XXX,XX +XXX,XX @@ qcow2_cache_get_done(void *co, int c, int i) "co %p is_l2_cache %d index %d"
43
qcow2_cache_flush(void *co, int c) "co %p is_l2_cache %d"
44
qcow2_cache_entry_flush(void *co, int c, int i) "co %p is_l2_cache %d index %d"
45
46
+# qcow2-refcount.c
47
+qcow2_process_discards_failed_region(uint64_t offset, uint64_t bytes, int ret) "offset 0x%" PRIx64 " bytes 0x%" PRIx64 " ret %d"
48
+
49
# qed-l2-cache.c
50
qed_alloc_l2_cache_entry(void *l2_cache, void *entry) "l2_cache %p entry %p"
51
qed_unref_l2_cache_entry(void *entry, int ref) "entry %p ref %d"
43
--
52
--
44
2.19.1
53
2.20.1
45
54
46
55
diff view generated by jsdifflib
1
Some block drivers have traditionally changed their node to read-only
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
mode without asking the user. This behaviour has been marked deprecated
3
since 2.11, expecting users to provide an explicit read-only=on option.
4
2
5
Now that we have auto-read-only=on, enable these drivers to make use of
3
This fixes at least one overflow in qcow2_process_discards, which
6
the option.
4
passes 64bit region length to bdrv_pdiscard where bytes (or sectors in
5
the past) parameter is int since its introduction in 0b919fae.
7
6
8
This is the only use of bdrv_set_read_only(), so we can make it a bit
7
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
more specific and turn it into a bdrv_apply_auto_read_only() that is
10
more convenient for drivers to use.
11
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Reviewed-by: Eric Blake <eblake@redhat.com>
14
---
9
---
15
include/block/block.h | 3 ++-
10
include/block/block.h | 4 ++--
16
block.c | 42 +++++++++++++++++++++++++++---------------
11
block/io.c | 16 ++++++++--------
17
block/bochs.c | 17 ++++++-----------
12
2 files changed, 10 insertions(+), 10 deletions(-)
18
block/cloop.c | 16 +++++-----------
19
block/dmg.c | 16 +++++-----------
20
block/rbd.c | 15 ++++-----------
21
block/vvfat.c | 10 ++--------
22
7 files changed, 51 insertions(+), 68 deletions(-)
23
13
24
diff --git a/include/block/block.h b/include/block/block.h
14
diff --git a/include/block/block.h b/include/block/block.h
25
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
26
--- a/include/block/block.h
16
--- a/include/block/block.h
27
+++ b/include/block/block.h
17
+++ b/include/block/block.h
28
@@ -XXX,XX +XXX,XX @@ int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
18
@@ -XXX,XX +XXX,XX @@ void bdrv_drain_all(void);
29
bool bdrv_is_read_only(BlockDriverState *bs);
19
AIO_WAIT_WHILE(bdrv_get_aio_context(bs_), \
30
int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
20
cond); })
31
bool ignore_allow_rdw, Error **errp);
21
32
-int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp);
22
-int bdrv_pdiscard(BdrvChild *child, int64_t offset, int bytes);
33
+int bdrv_apply_auto_read_only(BlockDriverState *bs, const char *errmsg,
23
-int bdrv_co_pdiscard(BdrvChild *child, int64_t offset, int bytes);
34
+ Error **errp);
24
+int bdrv_pdiscard(BdrvChild *child, int64_t offset, int64_t bytes);
35
bool bdrv_is_writable(BlockDriverState *bs);
25
+int bdrv_co_pdiscard(BdrvChild *child, int64_t offset, int64_t bytes);
36
bool bdrv_is_sg(BlockDriverState *bs);
26
int bdrv_has_zero_init_1(BlockDriverState *bs);
37
bool bdrv_is_inserted(BlockDriverState *bs);
27
int bdrv_has_zero_init(BlockDriverState *bs);
38
diff --git a/block.c b/block.c
28
bool bdrv_unallocated_blocks_are_zero(BlockDriverState *bs);
29
diff --git a/block/io.c b/block/io.c
39
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
40
--- a/block.c
31
--- a/block/io.c
41
+++ b/block.c
32
+++ b/block/io.c
42
@@ -XXX,XX +XXX,XX @@ int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
33
@@ -XXX,XX +XXX,XX @@ int bdrv_flush(BlockDriverState *bs)
43
return 0;
34
typedef struct DiscardCo {
35
BdrvChild *child;
36
int64_t offset;
37
- int bytes;
38
+ int64_t bytes;
39
int ret;
40
} DiscardCo;
41
static void coroutine_fn bdrv_pdiscard_co_entry(void *opaque)
42
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_pdiscard_co_entry(void *opaque)
43
aio_wait_kick();
44
}
44
}
45
45
46
-/* TODO Remove (deprecated since 2.11)
46
-int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset, int bytes)
47
- * Block drivers are not supposed to automatically change bs->read_only.
47
+int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset,
48
- * Instead, they should just check whether they can provide what the user
48
+ int64_t bytes)
49
- * explicitly requested and error out if read-write is requested, but they can
50
- * only provide read-only access. */
51
-int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
52
+/*
53
+ * Called by a driver that can only provide a read-only image.
54
+ *
55
+ * Returns 0 if the node is already read-only or it could switch the node to
56
+ * read-only because BDRV_O_AUTO_RDONLY is set.
57
+ *
58
+ * Returns -EACCES if the node is read-write and BDRV_O_AUTO_RDONLY is not set
59
+ * or bdrv_can_set_read_only() forbids making the node read-only. If @errmsg
60
+ * is not NULL, it is used as the error message for the Error object.
61
+ */
62
+int bdrv_apply_auto_read_only(BlockDriverState *bs, const char *errmsg,
63
+ Error **errp)
64
{
49
{
65
int ret = 0;
50
BdrvTrackedRequest req;
66
51
int max_pdiscard, ret;
67
- ret = bdrv_can_set_read_only(bs, read_only, false, errp);
52
int head, tail, align;
53
BlockDriverState *bs = child->bs;
54
55
- if (!bs || !bs->drv) {
56
+ if (!bs || !bs->drv || !bdrv_is_inserted(bs)) {
57
return -ENOMEDIUM;
58
}
59
60
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset, int bytes)
61
return -EPERM;
62
}
63
64
- ret = bdrv_check_byte_request(bs, offset, bytes);
68
- if (ret < 0) {
65
- if (ret < 0) {
69
- return ret;
66
- return ret;
70
+ if (!(bs->open_flags & BDRV_O_RDWR)) {
67
+ if (offset < 0 || bytes < 0 || bytes > INT64_MAX - offset) {
71
+ return 0;
68
+ return -EIO;
72
+ }
73
+ if (!(bs->open_flags & BDRV_O_AUTO_RDONLY)) {
74
+ goto fail;
75
}
69
}
76
70
77
- bs->read_only = read_only;
71
/* Do nothing if disabled. */
78
-
72
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset, int bytes)
79
- if (read_only) {
73
assert(max_pdiscard >= bs->bl.request_alignment);
80
- bs->open_flags &= ~BDRV_O_RDWR;
74
81
- } else {
75
while (bytes > 0) {
82
- bs->open_flags |= BDRV_O_RDWR;
76
- int num = bytes;
83
+ ret = bdrv_can_set_read_only(bs, true, false, NULL);
77
+ int64_t num = bytes;
84
+ if (ret < 0) {
78
85
+ goto fail;
79
if (head) {
86
}
80
/* Make small requests to get to alignment boundaries. */
87
81
@@ -XXX,XX +XXX,XX @@ out:
88
+ bs->read_only = true;
82
return ret;
89
+ bs->open_flags &= ~BDRV_O_RDWR;
90
+
91
return 0;
92
+
93
+fail:
94
+ error_setg(errp, "%s", errmsg ?: "Image is read-only");
95
+ return -EACCES;
96
}
83
}
97
84
98
void bdrv_get_full_backing_filename_from_filename(const char *backed,
85
-int bdrv_pdiscard(BdrvChild *child, int64_t offset, int bytes)
99
diff --git a/block/bochs.c b/block/bochs.c
86
+int bdrv_pdiscard(BdrvChild *child, int64_t offset, int64_t bytes)
100
index XXXXXXX..XXXXXXX 100644
87
{
101
--- a/block/bochs.c
88
Coroutine *co;
102
+++ b/block/bochs.c
89
DiscardCo rwco = {
103
@@ -XXX,XX +XXX,XX @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
104
struct bochs_header bochs;
105
int ret;
106
107
+ /* No write support yet */
108
+ ret = bdrv_apply_auto_read_only(bs, NULL, errp);
109
+ if (ret < 0) {
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
- }
128
- }
129
-
130
ret = bdrv_pread(bs->file, 0, &bochs, sizeof(bochs));
131
if (ret < 0) {
132
return ret;
133
diff --git a/block/cloop.c b/block/cloop.c
134
index XXXXXXX..XXXXXXX 100644
135
--- a/block/cloop.c
136
+++ b/block/cloop.c
137
@@ -XXX,XX +XXX,XX @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags,
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
}
247
--
90
--
248
2.19.1
91
2.20.1
249
92
250
93
diff view generated by jsdifflib
1
From: Peter Maydell <peter.maydell@linaro.org>
1
Commit 70ff5b07 wanted to move the diff between actual and reference
2
output to the end after printing the test result line. It really only
3
copied it, though, so the diff is now displayed twice. Remove the old
4
one.
2
5
3
Taking the address of a field in a packed struct is a bad idea, because
6
Fixes: 70ff5b07fcdd378180ad2d5cc0b0d5e67e7ef325
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
There are other places where we take the address of a packed member
16
in this file for other purposes than passing it to a byteswap
17
function (all the calls to qemu_uuid_*()); we leave those for now.
18
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
---
8
---
23
block/vdi.c | 64 ++++++++++++++++++++++++++---------------------------
9
tests/qemu-iotests/check | 1 -
24
1 file changed, 32 insertions(+), 32 deletions(-)
10
1 file changed, 1 deletion(-)
25
11
26
diff --git a/block/vdi.c b/block/vdi.c
12
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
27
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100755
28
--- a/block/vdi.c
14
--- a/tests/qemu-iotests/check
29
+++ b/block/vdi.c
15
+++ b/tests/qemu-iotests/check
30
@@ -XXX,XX +XXX,XX @@ typedef struct {
16
@@ -XXX,XX +XXX,XX @@ do
31
17
fi
32
static void vdi_header_to_cpu(VdiHeader *header)
18
else
33
{
19
mv $tmp.out $seq.out.bad
34
- le32_to_cpus(&header->signature);
20
- $diff -w "$reference" "$PWD"/$seq.out.bad
35
- le32_to_cpus(&header->version);
21
status="fail"
36
- le32_to_cpus(&header->header_size);
22
results="output mismatch (see $seq.out.bad)"
37
- le32_to_cpus(&header->image_type);
23
printdiff=true
38
- le32_to_cpus(&header->image_flags);
39
- le32_to_cpus(&header->offset_bmap);
40
- le32_to_cpus(&header->offset_data);
41
- le32_to_cpus(&header->cylinders);
42
- le32_to_cpus(&header->heads);
43
- le32_to_cpus(&header->sectors);
44
- le32_to_cpus(&header->sector_size);
45
- le64_to_cpus(&header->disk_size);
46
- le32_to_cpus(&header->block_size);
47
- le32_to_cpus(&header->block_extra);
48
- le32_to_cpus(&header->blocks_in_image);
49
- le32_to_cpus(&header->blocks_allocated);
50
+ header->signature = le32_to_cpu(header->signature);
51
+ header->version = le32_to_cpu(header->version);
52
+ header->header_size = le32_to_cpu(header->header_size);
53
+ header->image_type = le32_to_cpu(header->image_type);
54
+ header->image_flags = le32_to_cpu(header->image_flags);
55
+ header->offset_bmap = le32_to_cpu(header->offset_bmap);
56
+ header->offset_data = le32_to_cpu(header->offset_data);
57
+ header->cylinders = le32_to_cpu(header->cylinders);
58
+ header->heads = le32_to_cpu(header->heads);
59
+ header->sectors = le32_to_cpu(header->sectors);
60
+ header->sector_size = le32_to_cpu(header->sector_size);
61
+ header->disk_size = le64_to_cpu(header->disk_size);
62
+ header->block_size = le32_to_cpu(header->block_size);
63
+ header->block_extra = le32_to_cpu(header->block_extra);
64
+ header->blocks_in_image = le32_to_cpu(header->blocks_in_image);
65
+ header->blocks_allocated = le32_to_cpu(header->blocks_allocated);
66
qemu_uuid_bswap(&header->uuid_image);
67
qemu_uuid_bswap(&header->uuid_last_snap);
68
qemu_uuid_bswap(&header->uuid_link);
69
@@ -XXX,XX +XXX,XX @@ static void vdi_header_to_cpu(VdiHeader *header)
70
71
static void vdi_header_to_le(VdiHeader *header)
72
{
73
- cpu_to_le32s(&header->signature);
74
- cpu_to_le32s(&header->version);
75
- cpu_to_le32s(&header->header_size);
76
- cpu_to_le32s(&header->image_type);
77
- cpu_to_le32s(&header->image_flags);
78
- cpu_to_le32s(&header->offset_bmap);
79
- cpu_to_le32s(&header->offset_data);
80
- cpu_to_le32s(&header->cylinders);
81
- cpu_to_le32s(&header->heads);
82
- cpu_to_le32s(&header->sectors);
83
- cpu_to_le32s(&header->sector_size);
84
- cpu_to_le64s(&header->disk_size);
85
- cpu_to_le32s(&header->block_size);
86
- cpu_to_le32s(&header->block_extra);
87
- cpu_to_le32s(&header->blocks_in_image);
88
- cpu_to_le32s(&header->blocks_allocated);
89
+ header->signature = cpu_to_le32(header->signature);
90
+ header->version = cpu_to_le32(header->version);
91
+ header->header_size = cpu_to_le32(header->header_size);
92
+ header->image_type = cpu_to_le32(header->image_type);
93
+ header->image_flags = cpu_to_le32(header->image_flags);
94
+ header->offset_bmap = cpu_to_le32(header->offset_bmap);
95
+ header->offset_data = cpu_to_le32(header->offset_data);
96
+ header->cylinders = cpu_to_le32(header->cylinders);
97
+ header->heads = cpu_to_le32(header->heads);
98
+ header->sectors = cpu_to_le32(header->sectors);
99
+ header->sector_size = cpu_to_le32(header->sector_size);
100
+ header->disk_size = cpu_to_le64(header->disk_size);
101
+ header->block_size = cpu_to_le32(header->block_size);
102
+ header->block_extra = cpu_to_le32(header->block_extra);
103
+ header->blocks_in_image = cpu_to_le32(header->blocks_in_image);
104
+ header->blocks_allocated = cpu_to_le32(header->blocks_allocated);
105
qemu_uuid_bswap(&header->uuid_image);
106
qemu_uuid_bswap(&header->uuid_last_snap);
107
qemu_uuid_bswap(&header->uuid_link);
108
--
24
--
109
2.19.1
25
2.20.1
110
26
111
27
diff view generated by jsdifflib
Deleted patch
1
Commit e2b8247a322 introduced an error path in qemu_rbd_open() after
2
calling rbd_open(), but neglected to close the image again in this error
3
path. The error path should contain everything that the regular close
4
function qemu_rbd_close() contains.
5
1
6
This adds the missing rbd_close() call.
7
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Reviewed-by: Eric Blake <eblake@redhat.com>
10
---
11
block/rbd.c | 1 +
12
1 file changed, 1 insertion(+)
13
14
diff --git a/block/rbd.c b/block/rbd.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/block/rbd.c
17
+++ b/block/rbd.c
18
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
19
"automatically marking the image read-only.");
20
r = bdrv_set_read_only(bs, true, &local_err);
21
if (r < 0) {
22
+ rbd_close(s->image);
23
error_propagate(errp, local_err);
24
goto failed_open;
25
}
26
--
27
2.19.1
28
29
diff view generated by jsdifflib
Deleted patch
1
If read-only=off, but auto-read-only=on is given, open a read-write NBD
2
connection if the server provides a read-write export, but instead of
3
erroring out for read-only exports, just degrade to read-only.
4
1
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
7
---
8
block/nbd-client.c | 10 +++++-----
9
1 file changed, 5 insertions(+), 5 deletions(-)
10
11
diff --git a/block/nbd-client.c b/block/nbd-client.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/block/nbd-client.c
14
+++ b/block/nbd-client.c
15
@@ -XXX,XX +XXX,XX @@ int nbd_client_init(BlockDriverState *bs,
16
logout("Failed to negotiate with the NBD server\n");
17
return ret;
18
}
19
- if (client->info.flags & NBD_FLAG_READ_ONLY &&
20
- !bdrv_is_read_only(bs)) {
21
- error_setg(errp,
22
- "request for write access conflicts with read-only export");
23
- return -EACCES;
24
+ if (client->info.flags & NBD_FLAG_READ_ONLY) {
25
+ ret = bdrv_apply_auto_read_only(bs, "NBD export is read-only", errp);
26
+ if (ret < 0) {
27
+ return ret;
28
+ }
29
}
30
if (client->info.flags & NBD_FLAG_SEND_FUA) {
31
bs->supported_write_flags = BDRV_REQ_FUA;
32
--
33
2.19.1
34
35
diff view generated by jsdifflib
Deleted patch
1
If read-only=off, but auto-read-only=on is given, just degrade to
2
read-only.
3
1
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Eric Blake <eblake@redhat.com>
6
---
7
block/curl.c | 8 ++++----
8
1 file changed, 4 insertions(+), 4 deletions(-)
9
10
diff --git a/block/curl.c b/block/curl.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/block/curl.c
13
+++ b/block/curl.c
14
@@ -XXX,XX +XXX,XX @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
15
const char *protocol_delimiter;
16
int ret;
17
18
-
19
- if (flags & BDRV_O_RDWR) {
20
- error_setg(errp, "curl block device does not support writes");
21
- return -EROFS;
22
+ ret = bdrv_apply_auto_read_only(bs, "curl driver does not support writes",
23
+ errp);
24
+ if (ret < 0) {
25
+ return ret;
26
}
27
28
if (!libcurl_initialized) {
29
--
30
2.19.1
31
32
diff view generated by jsdifflib
Deleted patch
1
If read-only=off, but auto-read-only=on is given, open the file
2
read-write if we have the permissions, but instead of erroring out for
3
read-only files, just degrade to read-only.
4
1
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Niels de Vos <ndevos@redhat.com>
7
---
8
block/gluster.c | 12 ++++++++++--
9
1 file changed, 10 insertions(+), 2 deletions(-)
10
11
diff --git a/block/gluster.c b/block/gluster.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/block/gluster.c
14
+++ b/block/gluster.c
15
@@ -XXX,XX +XXX,XX @@ static int qemu_gluster_open(BlockDriverState *bs, QDict *options,
16
qemu_gluster_parse_flags(bdrv_flags, &open_flags);
17
18
s->fd = glfs_open(s->glfs, gconf->path, open_flags);
19
- if (!s->fd) {
20
- ret = -errno;
21
+ ret = s->fd ? 0 : -errno;
22
+
23
+ if (ret == -EACCES || ret == -EROFS) {
24
+ /* Try to degrade to read-only, but if it doesn't work, still use the
25
+ * normal error message. */
26
+ if (bdrv_apply_auto_read_only(bs, NULL, NULL) == 0) {
27
+ open_flags = (open_flags & ~O_RDWR) | O_RDONLY;
28
+ s->fd = glfs_open(s->glfs, gconf->path, open_flags);
29
+ ret = s->fd ? 0 : -errno;
30
+ }
31
}
32
33
s->supports_seek_data = qemu_gluster_test_seek(s->fd);
34
--
35
2.19.1
36
37
diff view generated by jsdifflib