1
The following changes since commit b2f7a038bb4c4fc5ce6b8486e8513dfd97665e2a:
1
The following changes since commit f4c4357fbfca0fb14e477bf661ae7384b4b9b283:
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/pmaydell/tags/pull-docs-20200306' into staging (2020-03-06 11:11:54 +0000)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
git://repo.or.cz/qemu/kevin.git tags/for-upstream
7
git://repo.or.cz/qemu/kevin.git tags/for-upstream
8
8
9
for you to fetch changes up to 1240ac558d348f6c7a5752b1a57c1da58e4efe3e:
9
for you to fetch changes up to 1de6b45fb5c1489b450df7d1a4c692bba9678ce6:
10
10
11
include: Add a comment to explain the origin of sizes' lookup table (2018-11-05 15:29:59 +0100)
11
block: bdrv_reopen() with backing file in different AioContext (2020-03-06 17:34:09 +0100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block layer patches:
14
Block layer patches:
15
15
16
- auto-read-only option to fix commit job when used with -blockdev
16
- Add qemu-storage-daemon (still experimental)
17
- Fix help text related qemu-iotests failure (by improving the help text
17
- rbd: Add support for ceph namespaces
18
and updating the reference output)
18
- Fix bdrv_reopen() with backing file in different AioContext
19
- quorum: Add missing checks when adding/removing child nodes
19
- qcow2: Fix read-write reopen with persistent dirty bitmaps
20
- Don't take address of fields in packed structs
20
- qcow2: Fix alloc_cluster_abort() for pre-existing clusters
21
- vvfat: Fix crash when reporting error about too many files in directory
22
21
23
----------------------------------------------------------------
22
----------------------------------------------------------------
24
Alberto Garcia (7):
23
Florian Florensa (1):
25
block: replace "discard" literal with BDRV_OPT_DISCARD macro
24
block/rbd: Add support for ceph namespaces
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
25
33
Cleber Rosa (1):
26
Kevin Wolf (22):
34
iotests: make 083 specific to raw
27
qemu-storage-daemon: Add barebone tool
28
stubs: Add arch_type
29
block: Move system emulator QMP commands to block/qapi-sysemu.c
30
block: Move common QMP commands to block-core QAPI module
31
block: Move sysemu QMP commands to QAPI block module
32
qemu-storage-daemon: Add --blockdev option
33
qapi: Flatten object-add
34
qemu-storage-daemon: Add --object option
35
qemu-storage-daemon: Add --nbd-server option
36
blockdev-nbd: Boxed argument type for nbd-server-add
37
qemu-storage-daemon: Add --export option
38
qemu-storage-daemon: Add main loop
39
qemu-storage-daemon: Add --chardev option
40
stubs: Update monitor stubs for qemu-storage-daemon
41
qapi: Create 'pragma' module
42
monitor: Create QAPIfied monitor_init()
43
qmp: Fail gracefully if chardev is already in use
44
hmp: Fail gracefully if chardev is already in use
45
monitor: Add allow_hmp parameter to monitor_init()
46
qemu-storage-daemon: Add --monitor option
47
iotests: Refactor blockdev-reopen test for iothreads
48
block: bdrv_reopen() with backing file in different AioContext
35
49
36
Daniel P. Berrangé (1):
50
Max Reitz (4):
37
crypto: initialize sector size even when opening with no IO flag
51
qcow2: Fix alloc_cluster_abort() for pre-existing clusters
52
iotests/026: Test EIO on preallocated zero cluster
53
iotests/026: Test EIO on allocation in a data-file
54
block: Fix leak in bdrv_create_file_fallback()
38
55
39
Kevin Wolf (12):
56
Peter Krempa (2):
40
vpc: Don't leak opts in vpc_open()
57
block: Introduce 'bdrv_reopen_commit_post' step
41
block: Update flags in bdrv_set_read_only()
58
block/qcow2: Move bitmap reopen into bdrv_reopen_commit_post
42
block: Add auto-read-only option
43
rbd: Close image in qemu_rbd_open() error path
44
block: Require auto-read-only for existing fallbacks
45
nbd: Support auto-read-only option
46
file-posix: Support auto-read-only option
47
curl: Support auto-read-only option
48
gluster: Support auto-read-only option
49
iscsi: Support auto-read-only option
50
block: Make auto-read-only=on default for -drive
51
qemu-iotests: Test auto-read-only with -drive and -blockdev
52
59
53
Leonid Bloch (2):
60
qapi/block-core.json | 733 +++++++++++++++++------------------
54
vdi: Use a literal number of bytes for DEFAULT_CLUSTER_SIZE
61
qapi/block.json | 512 ++++++++++++++----------
55
include: Add a comment to explain the origin of sizes' lookup table
62
qapi/control.json | 37 ++
63
qapi/pragma.json | 24 ++
64
qapi/qapi-schema.json | 25 +-
65
qapi/qom.json | 12 +-
66
qapi/transaction.json | 2 +-
67
docs/system/deprecated.rst | 5 +
68
configure | 2 +-
69
include/block/block_int.h | 1 +
70
include/block/nbd.h | 1 +
71
include/monitor/monitor.h | 6 +-
72
include/qom/object_interfaces.h | 7 +
73
include/sysemu/arch_init.h | 2 +
74
block.c | 44 ++-
75
block/qapi-sysemu.c | 590 ++++++++++++++++++++++++++++
76
block/qcow2-cluster.c | 2 +-
77
block/qcow2.c | 7 +-
78
block/rbd.c | 44 ++-
79
blockdev-nbd.c | 40 +-
80
blockdev.c | 559 --------------------------
81
chardev/char.c | 8 +-
82
gdbstub.c | 2 +-
83
hw/block/xen-block.c | 11 +-
84
monitor/hmp-cmds.c | 21 +-
85
monitor/hmp.c | 8 +-
86
monitor/misc.c | 2 +
87
monitor/monitor.c | 86 ++--
88
monitor/qmp-cmds.c | 2 +-
89
monitor/qmp.c | 11 +-
90
qemu-storage-daemon.c | 340 ++++++++++++++++
91
qom/qom-qmp-cmds.c | 42 +-
92
stubs/arch_type.c | 4 +
93
stubs/monitor-core.c | 21 +
94
stubs/monitor.c | 17 +-
95
tests/test-util-sockets.c | 4 +-
96
scripts/qapi/gen.py | 5 +
97
Makefile | 37 ++
98
Makefile.objs | 9 +
99
block/Makefile.objs | 4 +-
100
monitor/Makefile.objs | 2 +
101
qapi/Makefile.objs | 7 +-
102
qom/Makefile.objs | 1 +
103
storage-daemon/Makefile.objs | 1 +
104
storage-daemon/qapi/Makefile.objs | 1 +
105
storage-daemon/qapi/qapi-schema.json | 26 ++
106
stubs/Makefile.objs | 2 +
107
tests/qemu-iotests/026 | 53 +++
108
tests/qemu-iotests/026.out | 16 +
109
tests/qemu-iotests/026.out.nocache | 16 +
110
tests/qemu-iotests/245 | 45 ++-
111
tests/qemu-iotests/245.out | 4 +-
112
52 files changed, 2157 insertions(+), 1306 deletions(-)
113
create mode 100644 qapi/pragma.json
114
create mode 100644 block/qapi-sysemu.c
115
create mode 100644 qemu-storage-daemon.c
116
create mode 100644 stubs/arch_type.c
117
create mode 100644 stubs/monitor-core.c
118
create mode 100644 storage-daemon/Makefile.objs
119
create mode 100644 storage-daemon/qapi/Makefile.objs
120
create mode 100644 storage-daemon/qapi/qapi-schema.json
56
121
57
Li Qiang (1):
58
block: change some function return type to bool
59
122
60
Max Reitz (5):
61
option: Make option help nicer to read
62
chardev: Indent list of chardevs
63
qdev-monitor: Make device options help nicer
64
object: Make option help nicer to read
65
fw_cfg: Drop newline in @file description
66
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
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
handle_alloc() reuses preallocated zero clusters. If anything goes
4
description, so remove it.
4
wrong during the data write, we do not change their L2 entry, so we
5
must not let qcow2_alloc_cluster_abort() free them.
5
6
7
Fixes: 8b24cd141549b5b264baeddd4e72902cfb5de23b
8
Cc: qemu-stable@nongnu.org
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Message-Id: <20200225143130.111267-2-mreitz@redhat.com>
8
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
12
---
11
vl.c | 2 +-
13
block/qcow2-cluster.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
13
15
14
diff --git a/vl.c b/vl.c
16
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/vl.c
18
--- a/block/qcow2-cluster.c
17
+++ b/vl.c
19
+++ b/block/qcow2-cluster.c
18
@@ -XXX,XX +XXX,XX @@ static QemuOptsList qemu_fw_cfg_opts = {
20
@@ -XXX,XX +XXX,XX @@ err:
19
}, {
21
void qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m)
20
.name = "file",
22
{
21
.type = QEMU_OPT_STRING,
23
BDRVQcow2State *s = bs->opaque;
22
- .help = "Sets the name of the file from which\n"
24
- if (!has_data_file(bs)) {
23
+ .help = "Sets the name of the file from which "
25
+ if (!has_data_file(bs) && !m->keep_old_clusters) {
24
"the fw_cfg blob will be loaded",
26
qcow2_free_clusters(bs, m->alloc_offset,
25
}, {
27
m->nb_clusters << s->cluster_bits,
26
.name = "string",
28
QCOW2_DISCARD_NEVER);
27
--
29
--
28
2.19.1
30
2.20.1
29
31
30
32
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
This patch tests that you can add and remove drives from a Quorum
3
Test what happens when writing data to a preallocated zero cluster, but
4
using the x-blockdev-change command.
4
the data write fails.
5
5
6
Signed-off-by: Alberto Garcia <berto@igalia.com>
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Message-Id: <20200225143130.111267-3-mreitz@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
---
9
tests/qemu-iotests/081 | 86 ++++++++++++++++++++++++++++++++++++++
10
tests/qemu-iotests/026 | 21 +++++++++++++++++++++
10
tests/qemu-iotests/081.out | 54 ++++++++++++++++++++++++
11
tests/qemu-iotests/026.out | 10 ++++++++++
11
2 files changed, 140 insertions(+)
12
tests/qemu-iotests/026.out.nocache | 10 ++++++++++
13
3 files changed, 41 insertions(+)
12
14
13
diff --git a/tests/qemu-iotests/081 b/tests/qemu-iotests/081
15
diff --git a/tests/qemu-iotests/026 b/tests/qemu-iotests/026
14
index XXXXXXX..XXXXXXX 100755
16
index XXXXXXX..XXXXXXX 100755
15
--- a/tests/qemu-iotests/081
17
--- a/tests/qemu-iotests/026
16
+++ b/tests/qemu-iotests/081
18
+++ b/tests/qemu-iotests/026
17
@@ -XXX,XX +XXX,XX @@ quorum="$quorum,file.children.2.driver=raw"
19
@@ -XXX,XX +XXX,XX @@ _make_test_img 64M
18
20
$QEMU_IO -c "write 0 1M" -c "write 0 1M" "$BLKDBG_TEST_IMG" | _filter_qemu_io
19
$QEMU_IO -c "open -o $quorum" | _filter_qemu_io
21
_check_test_img
20
22
21
+echo
23
+echo
22
+echo "== dynamically adding a child to a quorum =="
24
+echo === Avoid freeing preallocated zero clusters on failure ===
25
+echo
23
+
26
+
24
+for verify in false true; do
27
+cat > "$TEST_DIR/blkdebug.conf" <<EOF
25
+ run_qemu <<EOF
28
+[inject-error]
26
+ { "execute": "qmp_capabilities" }
29
+event = "write_aio"
27
+ { "execute": "blockdev-add",
30
+errno = "5"
28
+ "arguments": {
31
+once = "on"
29
+ "driver": "quorum",
30
+ "node-name": "drive0-quorum",
31
+ "vote-threshold": 2,
32
+ "blkverify": ${verify},
33
+ "children": [
34
+ {
35
+ "driver": "$IMGFMT",
36
+ "file": {
37
+ "driver": "file",
38
+ "filename": "$TEST_DIR/1.raw"
39
+ }
40
+ },
41
+ {
42
+ "driver": "$IMGFMT",
43
+ "file": {
44
+ "driver": "file",
45
+ "filename": "$TEST_DIR/2.raw"
46
+ }
47
+ }
48
+ ]
49
+ }
50
+ }
51
+ { "execute": "blockdev-add",
52
+ "arguments": {
53
+ "node-name": "drive3",
54
+ "driver": "$IMGFMT",
55
+ "file": {
56
+ "driver": "file",
57
+ "filename": "$TEST_DIR/2.raw"
58
+ }
59
+ }
60
+ }
61
+ { "execute": "x-blockdev-change",
62
+ "arguments": { "parent": "drive0-quorum",
63
+ "node": "drive3" } }
64
+ { "execute": "quit" }
65
+EOF
32
+EOF
66
+done
67
+
33
+
68
+echo
34
+_make_test_img $CLUSTER_SIZE
69
+echo "== dynamically removing a child from a quorum =="
35
+# Create a preallocated zero cluster
36
+$QEMU_IO -c "write 0 $CLUSTER_SIZE" -c "write -z 0 $CLUSTER_SIZE" "$TEST_IMG" \
37
+ | _filter_qemu_io
38
+# Try to overwrite it (prompting an I/O error from blkdebug), thus
39
+# triggering the alloc abort code
40
+$QEMU_IO -c "write 0 $CLUSTER_SIZE" "$BLKDBG_TEST_IMG" | _filter_qemu_io
70
+
41
+
71
+for verify in false true; do
42
+_check_test_img
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
+
43
+
107
# success, all done
44
# success, all done
108
echo "*** done"
45
echo "*** done"
109
rm -f $seq.full
46
rm -f $seq.full
110
diff --git a/tests/qemu-iotests/081.out b/tests/qemu-iotests/081.out
47
diff --git a/tests/qemu-iotests/026.out b/tests/qemu-iotests/026.out
111
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
112
--- a/tests/qemu-iotests/081.out
49
--- a/tests/qemu-iotests/026.out
113
+++ b/tests/qemu-iotests/081.out
50
+++ b/tests/qemu-iotests/026.out
114
@@ -XXX,XX +XXX,XX @@ read 10485760/10485760 bytes at offset 0
51
@@ -XXX,XX +XXX,XX @@ write failed: Input/output error
115
52
wrote 1048576/1048576 bytes at offset 0
116
== checking the blkverify mode with invalid settings ==
53
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
117
can't open: blkverify=on can only be set if there are exactly two files and vote-threshold is 2
54
No errors were found on the image.
118
+
55
+
119
+== dynamically adding a child to a quorum ==
56
+=== Avoid freeing preallocated zero clusters on failure ===
120
+Testing:
121
+QMP_VERSION
122
+{"return": {}}
123
+{"return": {}}
124
+{"return": {}}
125
+{"return": {}}
126
+{"return": {}}
127
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
128
+
57
+
129
+Testing:
58
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1024
130
+QMP_VERSION
59
+wrote 1024/1024 bytes at offset 0
131
+{"return": {}}
60
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
132
+{"return": {}}
61
+wrote 1024/1024 bytes at offset 0
133
+{"return": {}}
62
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
134
+{"error": {"class": "GenericError", "desc": "Cannot add a child to a quorum in blkverify mode"}}
63
+write failed: Input/output error
135
+{"return": {}}
64
+No errors were found on the image.
136
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
65
*** done
66
diff --git a/tests/qemu-iotests/026.out.nocache b/tests/qemu-iotests/026.out.nocache
67
index XXXXXXX..XXXXXXX 100644
68
--- a/tests/qemu-iotests/026.out.nocache
69
+++ b/tests/qemu-iotests/026.out.nocache
70
@@ -XXX,XX +XXX,XX @@ write failed: Input/output error
71
wrote 1048576/1048576 bytes at offset 0
72
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
73
No errors were found on the image.
137
+
74
+
75
+=== Avoid freeing preallocated zero clusters on failure ===
138
+
76
+
139
+== dynamically removing a child from a quorum ==
77
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1024
140
+Testing:
78
+wrote 1024/1024 bytes at offset 0
141
+QMP_VERSION
79
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
142
+{"return": {}}
80
+wrote 1024/1024 bytes at offset 0
143
+{"return": {}}
81
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
144
+{"return": {}}
82
+write failed: Input/output error
145
+{"return": {}}
83
+No errors were found on the image.
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
84
*** done
173
--
85
--
174
2.19.1
86
2.20.1
175
87
176
88
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
Signed-off-by: Alberto Garcia <berto@igalia.com>
3
Test what happens when writing data to an external data file, where the
4
write requires an L2 entry to be allocated, but the data write fails.
5
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Message-Id: <20200225143130.111267-4-mreitz@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
---
9
---
6
tests/qemu-iotests/081 | 30 ++++++++++++++++++++++++++++++
10
tests/qemu-iotests/026 | 32 ++++++++++++++++++++++++++++++
7
tests/qemu-iotests/081.out | 16 ++++++++++++++++
11
tests/qemu-iotests/026.out | 6 ++++++
8
2 files changed, 46 insertions(+)
12
tests/qemu-iotests/026.out.nocache | 6 ++++++
13
3 files changed, 44 insertions(+)
9
14
10
diff --git a/tests/qemu-iotests/081 b/tests/qemu-iotests/081
15
diff --git a/tests/qemu-iotests/026 b/tests/qemu-iotests/026
11
index XXXXXXX..XXXXXXX 100755
16
index XXXXXXX..XXXXXXX 100755
12
--- a/tests/qemu-iotests/081
17
--- a/tests/qemu-iotests/026
13
+++ b/tests/qemu-iotests/081
18
+++ b/tests/qemu-iotests/026
14
@@ -XXX,XX +XXX,XX @@ echo "== checking that quorum is broken =="
19
@@ -XXX,XX +XXX,XX @@ _cleanup()
15
20
{
16
$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
21
    _cleanup_test_img
22
rm "$TEST_DIR/blkdebug.conf"
23
+ rm -f "$TEST_IMG.data_file"
24
}
25
trap "_cleanup; exit \$status" 0 1 2 3 15
26
27
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c "write 0 $CLUSTER_SIZE" "$BLKDBG_TEST_IMG" | _filter_qemu_io
28
29
_check_test_img
17
30
18
+echo
31
+echo
19
+echo "== checking the blkverify mode with broken content =="
32
+echo === Avoid freeing external data clusters on failure ===
33
+echo
20
+
34
+
21
+quorum="driver=raw,file.driver=quorum,file.vote-threshold=2,file.blkverify=on"
35
+# Similar test as the last one, except we test what happens when there
22
+quorum="$quorum,file.children.0.file.filename=$TEST_DIR/1.raw"
36
+# is an error when writing to an external data file instead of when
23
+quorum="$quorum,file.children.1.file.filename=$TEST_DIR/2.raw"
37
+# writing to a preallocated zero cluster
24
+quorum="$quorum,file.children.0.driver=raw"
38
+_make_test_img -o "data_file=$TEST_IMG.data_file" $CLUSTER_SIZE
25
+quorum="$quorum,file.children.1.driver=raw"
26
+
39
+
27
+$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
40
+# Put blkdebug above the data-file, and a raw node on top of that so
41
+# that blkdebug will see a write_aio event and emit an error
42
+$QEMU_IO -c "write 0 $CLUSTER_SIZE" \
43
+ "json:{
44
+ 'driver': 'qcow2',
45
+ 'file': { 'driver': 'file', 'filename': '$TEST_IMG' },
46
+ 'data-file': {
47
+ 'driver': 'raw',
48
+ 'file': {
49
+ 'driver': 'blkdebug',
50
+ 'config': '$TEST_DIR/blkdebug.conf',
51
+ 'image': {
52
+ 'driver': 'file',
53
+ 'filename': '$TEST_IMG.data_file'
54
+ }
55
+ }
56
+ }
57
+ }" \
58
+ | _filter_qemu_io
28
+
59
+
29
+echo
60
+_check_test_img
30
+echo "== writing the same data to both files =="
31
+
32
+$QEMU_IO -c "write -P 0x32 0 $size" "$TEST_DIR/1.raw" | _filter_qemu_io
33
+$QEMU_IO -c "write -P 0x32 0 $size" "$TEST_DIR/2.raw" | _filter_qemu_io
34
+
35
+echo
36
+echo "== checking the blkverify mode with valid content =="
37
+
38
+$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
39
+
40
+echo
41
+echo "== checking the blkverify mode with invalid settings =="
42
+
43
+quorum="$quorum,file.children.2.file.filename=$TEST_DIR/3.raw"
44
+quorum="$quorum,file.children.2.driver=raw"
45
+
46
+$QEMU_IO -c "open -o $quorum" | _filter_qemu_io
47
+
61
+
48
# success, all done
62
# success, all done
49
echo "*** done"
63
echo "*** done"
50
rm -f $seq.full
64
rm -f $seq.full
51
diff --git a/tests/qemu-iotests/081.out b/tests/qemu-iotests/081.out
65
diff --git a/tests/qemu-iotests/026.out b/tests/qemu-iotests/026.out
52
index XXXXXXX..XXXXXXX 100644
66
index XXXXXXX..XXXXXXX 100644
53
--- a/tests/qemu-iotests/081.out
67
--- a/tests/qemu-iotests/026.out
54
+++ b/tests/qemu-iotests/081.out
68
+++ b/tests/qemu-iotests/026.out
55
@@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 0
69
@@ -XXX,XX +XXX,XX @@ wrote 1024/1024 bytes at offset 0
56
70
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
57
== checking that quorum is broken ==
71
write failed: Input/output error
58
read failed: Input/output error
72
No errors were found on the image.
59
+
73
+
60
+== checking the blkverify mode with broken content ==
74
+=== Avoid freeing external data clusters on failure ===
61
+quorum: offset=0 bytes=10485760 contents mismatch at offset 0
62
+
75
+
63
+== writing the same data to both files ==
76
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1024 data_file=TEST_DIR/t.IMGFMT.data_file
64
+wrote 10485760/10485760 bytes at offset 0
77
+write failed: Input/output error
65
+10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
78
+No errors were found on the image.
66
+wrote 10485760/10485760 bytes at offset 0
79
*** done
67
+10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
80
diff --git a/tests/qemu-iotests/026.out.nocache b/tests/qemu-iotests/026.out.nocache
81
index XXXXXXX..XXXXXXX 100644
82
--- a/tests/qemu-iotests/026.out.nocache
83
+++ b/tests/qemu-iotests/026.out.nocache
84
@@ -XXX,XX +XXX,XX @@ wrote 1024/1024 bytes at offset 0
85
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
86
write failed: Input/output error
87
No errors were found on the image.
68
+
88
+
69
+== checking the blkverify mode with valid content ==
89
+=== Avoid freeing external data clusters on failure ===
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
+
90
+
73
+== checking the blkverify mode with invalid settings ==
91
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1024 data_file=TEST_DIR/t.IMGFMT.data_file
74
+can't open: blkverify=on can only be set if there are exactly two files and vote-threshold is 2
92
+write failed: Input/output error
93
+No errors were found on the image.
75
*** done
94
*** done
76
--
95
--
77
2.19.1
96
2.20.1
78
97
79
98
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
Just like in qemu_opts_print_help(), print the device name as a caption
3
@options is leaked by the first two return statements in this function.
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
4
5
Note that blk_new_open() takes the reference to @options even on
6
failure, so all we need to do to fix the leak is to move the QDict
7
allocation down to where we actually need it.
8
9
Reported-by: Coverity (CID 1419884)
10
Fixes: fd17146cd93d1704cd96d7c2757b325fc7aac6fd
11
("block: Generic file creation fallback")
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
13
Message-Id: <20200225155618.133412-1-mreitz@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
15
---
15
qdev-monitor.c | 13 +++++++++++--
16
block.c | 3 ++-
16
1 file changed, 11 insertions(+), 2 deletions(-)
17
1 file changed, 2 insertions(+), 1 deletion(-)
17
18
18
diff --git a/qdev-monitor.c b/qdev-monitor.c
19
diff --git a/block.c b/block.c
19
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
20
--- a/qdev-monitor.c
21
--- a/block.c
21
+++ b/qdev-monitor.c
22
+++ b/block.c
22
@@ -XXX,XX +XXX,XX @@ int qdev_device_help(QemuOpts *opts)
23
@@ -XXX,XX +XXX,XX @@ static int bdrv_create_file_fallback(const char *filename, BlockDriver *drv,
23
goto error;
24
QemuOpts *opts, Error **errp)
25
{
26
BlockBackend *blk;
27
- QDict *options = qdict_new();
28
+ QDict *options;
29
int64_t size = 0;
30
char *buf = NULL;
31
PreallocMode prealloc;
32
@@ -XXX,XX +XXX,XX @@ static int bdrv_create_file_fallback(const char *filename, BlockDriver *drv,
33
return -ENOTSUP;
24
}
34
}
25
35
26
+ if (prop_list) {
36
+ options = qdict_new();
27
+ out_printf("%s options:\n", driver);
37
qdict_put_str(options, "driver", drv->format_name);
28
+ } else {
38
29
+ out_printf("There are no options for %s.\n", driver);
39
blk = blk_new_open(filename, NULL, options,
30
+ }
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
--
40
--
45
2.19.1
41
2.20.1
46
42
47
43
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Peter Krempa <pkrempa@redhat.com>
2
2
3
Signed-off-by: Alberto Garcia <berto@igalia.com>
3
Add another step in the reopen process where driver can execute code
4
after permission changes are comitted.
5
6
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
7
Message-Id: <adc02cf591c3cb34e98e33518eb1c540a0f27db1.1582893284.git.pkrempa@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
---
9
---
6
block.c | 6 +++---
10
include/block/block_int.h | 1 +
7
1 file changed, 3 insertions(+), 3 deletions(-)
11
block.c | 9 +++++++++
12
2 files changed, 10 insertions(+)
8
13
14
diff --git a/include/block/block_int.h b/include/block/block_int.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/block/block_int.h
17
+++ b/include/block/block_int.h
18
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
19
int (*bdrv_reopen_prepare)(BDRVReopenState *reopen_state,
20
BlockReopenQueue *queue, Error **errp);
21
void (*bdrv_reopen_commit)(BDRVReopenState *reopen_state);
22
+ void (*bdrv_reopen_commit_post)(BDRVReopenState *reopen_state);
23
void (*bdrv_reopen_abort)(BDRVReopenState *reopen_state);
24
void (*bdrv_join_options)(QDict *options, QDict *old_options);
25
9
diff --git a/block.c b/block.c
26
diff --git a/block.c b/block.c
10
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
11
--- a/block.c
28
--- a/block.c
12
+++ b/block.c
29
+++ b/block.c
13
@@ -XXX,XX +XXX,XX @@ QemuOptsList bdrv_runtime_opts = {
30
@@ -XXX,XX +XXX,XX @@ cleanup_perm:
14
.help = "try to optimize zero writes (off, on, unmap)",
31
}
15
},
16
{
17
- .name = "discard",
18
+ .name = BDRV_OPT_DISCARD,
19
.type = QEMU_OPT_STRING,
20
.help = "discard operation (ignore/off, unmap/on)",
21
},
22
@@ -XXX,XX +XXX,XX @@ static int bdrv_open_common(BlockDriverState *bs, BlockBackend *file,
23
}
32
}
24
}
33
}
25
34
+
26
- discard = qemu_opt_get(opts, "discard");
35
+ if (ret == 0) {
27
+ discard = qemu_opt_get(opts, BDRV_OPT_DISCARD);
36
+ QTAILQ_FOREACH_REVERSE(bs_entry, bs_queue, entry) {
28
if (discard != NULL) {
37
+ BlockDriverState *bs = bs_entry->state.bs;
29
if (bdrv_parse_discard_flags(discard, &bs->open_flags) != 0) {
38
+
30
error_setg(errp, "Invalid discard option");
39
+ if (bs->drv->bdrv_reopen_commit_post)
31
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
40
+ bs->drv->bdrv_reopen_commit_post(&bs_entry->state);
32
41
+ }
33
update_flags_from_options(&reopen_state->flags, opts);
42
+ }
34
43
cleanup:
35
- discard = qemu_opt_get_del(opts, "discard");
44
QTAILQ_FOREACH_SAFE(bs_entry, bs_queue, entry, next) {
36
+ discard = qemu_opt_get_del(opts, BDRV_OPT_DISCARD);
45
if (ret) {
37
if (discard != NULL) {
38
if (bdrv_parse_discard_flags(discard, &reopen_state->flags) != 0) {
39
error_setg(errp, "Invalid discard option");
40
--
46
--
41
2.19.1
47
2.20.1
42
48
43
49
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
1
From: Peter Maydell <peter.maydell@linaro.org>
1
From: Peter Krempa <pkrempa@redhat.com>
2
2
3
Taking the address of a field in a packed struct is a bad idea, because
3
The bitmap code requires writing the 'file' child when the qcow2 driver
4
it might not be actually aligned enough for that pointer type (and
4
is reopened in read-write mode.
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
If the 'file' child is being reopened due to a permissions change, the
10
used on something other than a packed struct field; we convert
7
modification is commited yet when qcow2_reopen_commit is called. This
11
those anyway, for consistency.
8
means that any attempt to write the 'file' child will end with EBADFD
9
as the original fd was already closed.
12
10
13
This patch was produced with the following spatch script
11
Moving bitmap reopening to the new callback which is called after
14
(and hand-editing to fold a few resulting overlength lines):
12
permission modifications are commited fixes this as the file descriptor
13
will be replaced with the correct one.
15
14
16
@@
15
The above problem manifests itself when reopening 'qcow2' format layer
17
expression E;
16
which uses a 'file-posix' file child which was opened with the
18
@@
17
'auto-read-only' property set.
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
18
47
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
48
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Message-Id: <db118dbafe1955afbc0a18d3dd220931074ce349.1582893284.git.pkrempa@redhat.com>
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>
21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
52
---
22
---
53
block/qcow2.c | 64 +++++++++++++++++++++++++++------------------------
23
block/qcow2.c | 7 ++++++-
54
1 file changed, 34 insertions(+), 30 deletions(-)
24
1 file changed, 6 insertions(+), 1 deletion(-)
55
25
56
diff --git a/block/qcow2.c b/block/qcow2.c
26
diff --git a/block/qcow2.c b/block/qcow2.c
57
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
58
--- a/block/qcow2.c
28
--- a/block/qcow2.c
59
+++ b/block/qcow2.c
29
+++ b/block/qcow2.c
60
@@ -XXX,XX +XXX,XX @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
30
@@ -XXX,XX +XXX,XX @@ fail:
61
"pread fail from offset %" PRIu64, offset);
31
static void qcow2_reopen_commit(BDRVReopenState *state)
62
return 1;
32
{
63
}
33
qcow2_update_options_commit(state->bs, state->opaque);
64
- be32_to_cpus(&ext.magic);
34
+ g_free(state->opaque);
65
- be32_to_cpus(&ext.len);
35
+}
66
+ ext.magic = be32_to_cpu(ext.magic);
36
+
67
+ ext.len = be32_to_cpu(ext.len);
37
+static void qcow2_reopen_commit_post(BDRVReopenState *state)
68
offset += sizeof(ext);
38
+{
69
#ifdef DEBUG_EXT
39
if (state->flags & BDRV_O_RDWR) {
70
printf("ext.magic = 0x%x\n", ext.magic);
40
Error *local_err = NULL;
71
@@ -XXX,XX +XXX,XX @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
41
72
"Unable to read CRYPTO header extension");
42
@@ -XXX,XX +XXX,XX @@ static void qcow2_reopen_commit(BDRVReopenState *state)
73
return ret;
43
bdrv_get_node_name(state->bs));
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
}
44
}
156
}
45
}
157
46
- g_free(state->opaque);
158
@@ -XXX,XX +XXX,XX @@ int qcow2_update_header(BlockDriverState *bs)
47
}
159
48
160
/* Full disk encryption header pointer extension */
49
static void qcow2_reopen_abort(BDRVReopenState *state)
161
if (s->crypto_header.offset != 0) {
50
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_qcow2 = {
162
- cpu_to_be64s(&s->crypto_header.offset);
51
.bdrv_close = qcow2_close,
163
- cpu_to_be64s(&s->crypto_header.length);
52
.bdrv_reopen_prepare = qcow2_reopen_prepare,
164
+ s->crypto_header.offset = cpu_to_be64(s->crypto_header.offset);
53
.bdrv_reopen_commit = qcow2_reopen_commit,
165
+ s->crypto_header.length = cpu_to_be64(s->crypto_header.length);
54
+ .bdrv_reopen_commit_post = qcow2_reopen_commit_post,
166
ret = header_ext_add(buf, QCOW2_EXT_MAGIC_CRYPTO_HEADER,
55
.bdrv_reopen_abort = qcow2_reopen_abort,
167
&s->crypto_header, sizeof(s->crypto_header),
56
.bdrv_join_options = qcow2_join_options,
168
buflen);
57
.bdrv_child_perm = bdrv_format_default_perms,
169
- be64_to_cpus(&s->crypto_header.offset);
170
- be64_to_cpus(&s->crypto_header.length);
171
+ s->crypto_header.offset = be64_to_cpu(s->crypto_header.offset);
172
+ s->crypto_header.length = be64_to_cpu(s->crypto_header.length);
173
if (ret < 0) {
174
goto fail;
175
}
176
--
58
--
177
2.19.1
59
2.20.1
178
60
179
61
diff view generated by jsdifflib
1
From: Leonid Bloch <lbloch@janustech.com>
1
This adds a new binary qemu-storage-daemon that doesn't yet do more than
2
some typical initialisation for tools and parsing the basic command
3
options --version, --help and --trace.
2
4
3
The lookup table for power-of-two sizes was added in commit 540b8492618eb
5
Even though this doesn't add any options yet that create things (like
4
for the purpose of having convenient shortcuts for these sizes in cases
6
--object or --blockdev), already document that we're planning to process
5
when the literal number has to be present at compile time, and
7
them in the order they are given on the command line rather than trying
6
expressions as '(1 * KiB)' can not be used. One such case is the
8
(and failing, like vl.c) to resolve dependencies between options
7
stringification of sizes. Beyond that, it is convenient to use these
9
automatically.
8
shortcuts for all power-of-two sizes, even if they don't have to be
9
literal numbers.
10
10
11
Despite its convenience, this table introduced 55 lines of "dumb" code,
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
the purpose and origin of which are obscure without reading the message
12
Message-Id: <20200224143008.13362-2-kwolf@redhat.com>
13
of the commit which introduced it. This patch fixes that by adding a
13
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
14
comment to the code itself with a brief explanation for the reasoning
15
behind this table. This comment includes the short AWK script that
16
generated the table, so that anyone who's interested could make sure
17
that the values in it are correct (otherwise these values look as if
18
they were typed manually).
19
20
Signed-off-by: Leonid Bloch <lbloch@janustech.com>
21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
---
15
---
23
include/qemu/units.h | 18 ++++++++++++++++++
16
configure | 2 +-
24
1 file changed, 18 insertions(+)
17
qemu-storage-daemon.c | 127 ++++++++++++++++++++++++++++++++++++++++++
18
Makefile | 1 +
19
3 files changed, 129 insertions(+), 1 deletion(-)
20
create mode 100644 qemu-storage-daemon.c
25
21
26
diff --git a/include/qemu/units.h b/include/qemu/units.h
22
diff --git a/configure b/configure
27
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100755
28
--- a/include/qemu/units.h
24
--- a/configure
29
+++ b/include/qemu/units.h
25
+++ b/configure
26
@@ -XXX,XX +XXX,XX @@ tools=""
27
if test "$want_tools" = "yes" ; then
28
tools="qemu-img\$(EXESUF) qemu-io\$(EXESUF) qemu-edid\$(EXESUF) $tools"
29
if [ "$linux" = "yes" -o "$bsd" = "yes" -o "$solaris" = "yes" ] ; then
30
- tools="qemu-nbd\$(EXESUF) $tools"
31
+ tools="qemu-nbd\$(EXESUF) qemu-storage-daemon\$(EXESUF) $tools"
32
fi
33
if [ "$ivshmem" = "yes" ]; then
34
tools="ivshmem-client\$(EXESUF) ivshmem-server\$(EXESUF) $tools"
35
diff --git a/qemu-storage-daemon.c b/qemu-storage-daemon.c
36
new file mode 100644
37
index XXXXXXX..XXXXXXX
38
--- /dev/null
39
+++ b/qemu-storage-daemon.c
30
@@ -XXX,XX +XXX,XX @@
40
@@ -XXX,XX +XXX,XX @@
31
#define PiB (INT64_C(1) << 50)
32
#define EiB (INT64_C(1) << 60)
33
34
+/*
41
+/*
35
+ * The following lookup table is intended to be used when a literal string of
42
+ * QEMU storage daemon
36
+ * the number of bytes is required (for example if it needs to be stringified).
37
+ * It can also be used for generic shortcuts of power-of-two sizes.
38
+ * This table is generated using the AWK script below:
39
+ *
43
+ *
40
+ * BEGIN {
44
+ * Copyright (c) 2003-2008 Fabrice Bellard
41
+ * suffix="KMGTPE";
45
+ * Copyright (c) 2019 Kevin Wolf <kwolf@redhat.com>
42
+ * for(i=10; i<64; i++) {
46
+ *
43
+ * val=2**i;
47
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
44
+ * s=substr(suffix, int(i/10), 1);
48
+ * of this software and associated documentation files (the "Software"), to deal
45
+ * n=2**(i%10);
49
+ * in the Software without restriction, including without limitation the rights
46
+ * pad=21-int(log(n)/log(10));
50
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
47
+ * printf("#define S_%d%siB %*d\n", n, s, pad, val);
51
+ * copies of the Software, and to permit persons to whom the Software is
48
+ * }
52
+ * furnished to do so, subject to the following conditions:
49
+ * }
53
+ *
54
+ * The above copyright notice and this permission notice shall be included in
55
+ * all copies or substantial portions of the Software.
56
+ *
57
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
58
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
59
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
60
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
61
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
62
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
63
+ * THE SOFTWARE.
50
+ */
64
+ */
51
+
65
+
52
#define S_1KiB 1024
66
+#include "qemu/osdep.h"
53
#define S_2KiB 2048
67
+
54
#define S_4KiB 4096
68
+#include <getopt.h>
69
+
70
+#include "block/block.h"
71
+#include "crypto/init.h"
72
+
73
+#include "qapi/error.h"
74
+#include "qemu-common.h"
75
+#include "qemu-version.h"
76
+#include "qemu/config-file.h"
77
+#include "qemu/error-report.h"
78
+#include "qemu/log.h"
79
+#include "qemu/main-loop.h"
80
+#include "qemu/module.h"
81
+
82
+#include "trace/control.h"
83
+
84
+static void help(void)
85
+{
86
+ printf(
87
+"Usage: %s [options]\n"
88
+"QEMU storage daemon\n"
89
+"\n"
90
+" -h, --help display this help and exit\n"
91
+" -T, --trace [[enable=]<pattern>][,events=<file>][,file=<file>]\n"
92
+" specify tracing options\n"
93
+" -V, --version output version information and exit\n"
94
+"\n"
95
+QEMU_HELP_BOTTOM "\n",
96
+ error_get_progname());
97
+}
98
+
99
+static void process_options(int argc, char *argv[])
100
+{
101
+ int c;
102
+
103
+ static const struct option long_options[] = {
104
+ {"help", no_argument, NULL, 'h'},
105
+ {"trace", required_argument, NULL, 'T'},
106
+ {"version", no_argument, NULL, 'V'},
107
+ {0, 0, 0, 0}
108
+ };
109
+
110
+ /*
111
+ * In contrast to the system emulator, options are processed in the order
112
+ * they are given on the command lines. This means that things must be
113
+ * defined first before they can be referenced in another option.
114
+ */
115
+ while ((c = getopt_long(argc, argv, "hT:V", long_options, NULL)) != -1) {
116
+ switch (c) {
117
+ case '?':
118
+ exit(EXIT_FAILURE);
119
+ case 'h':
120
+ help();
121
+ exit(EXIT_SUCCESS);
122
+ case 'T':
123
+ {
124
+ char *trace_file = trace_opt_parse(optarg);
125
+ trace_init_file(trace_file);
126
+ g_free(trace_file);
127
+ break;
128
+ }
129
+ case 'V':
130
+ printf("qemu-storage-daemon version "
131
+ QEMU_FULL_VERSION "\n" QEMU_COPYRIGHT "\n");
132
+ exit(EXIT_SUCCESS);
133
+ default:
134
+ g_assert_not_reached();
135
+ }
136
+ }
137
+ if (optind != argc) {
138
+ error_report("Unexpected argument: %s", argv[optind]);
139
+ exit(EXIT_FAILURE);
140
+ }
141
+}
142
+
143
+int main(int argc, char *argv[])
144
+{
145
+#ifdef CONFIG_POSIX
146
+ signal(SIGPIPE, SIG_IGN);
147
+#endif
148
+
149
+ error_init(argv[0]);
150
+ qemu_init_exec_dir(argv[0]);
151
+
152
+ module_call_init(MODULE_INIT_QOM);
153
+ module_call_init(MODULE_INIT_TRACE);
154
+ qemu_add_opts(&qemu_trace_opts);
155
+ qcrypto_init(&error_fatal);
156
+ bdrv_init();
157
+
158
+ if (!trace_init_backends()) {
159
+ return EXIT_FAILURE;
160
+ }
161
+ qemu_set_log(LOG_TRACE);
162
+
163
+ qemu_init_main_loop(&error_fatal);
164
+ process_options(argc, argv);
165
+
166
+ return EXIT_SUCCESS;
167
+}
168
diff --git a/Makefile b/Makefile
169
index XXXXXXX..XXXXXXX 100644
170
--- a/Makefile
171
+++ b/Makefile
172
@@ -XXX,XX +XXX,XX @@ qemu-img.o: qemu-img-cmds.h
173
qemu-img$(EXESUF): qemu-img.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
174
qemu-nbd$(EXESUF): qemu-nbd.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
175
qemu-io$(EXESUF): qemu-io.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
176
+qemu-storage-daemon$(EXESUF): qemu-storage-daemon.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
177
178
qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o $(COMMON_LDADDS)
179
55
--
180
--
56
2.19.1
181
2.20.1
57
182
58
183
diff view generated by jsdifflib
1
From: Leonid Bloch <lbloch@janustech.com>
1
blockdev.c uses the arch_type constant, so before we can use the file in
2
tools (i.e. outside of the system emulator), we need to add a stub for
3
it. A new QEMU_ARCH_NONE is introduced for this case.
2
4
3
If an expression is used to define DEFAULT_CLUSTER_SIZE, when compiled,
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
it will be embedded as a literal expression in the binary (as the
6
Message-Id: <20200224143008.13362-3-kwolf@redhat.com>
5
default value) because it is stringified to mark the size of the default
7
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
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>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
9
---
12
block/vdi.c | 4 ++--
10
include/sysemu/arch_init.h | 2 ++
13
1 file changed, 2 insertions(+), 2 deletions(-)
11
stubs/arch_type.c | 4 ++++
12
stubs/Makefile.objs | 1 +
13
3 files changed, 7 insertions(+)
14
create mode 100644 stubs/arch_type.c
14
15
15
diff --git a/block/vdi.c b/block/vdi.c
16
diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/block/vdi.c
18
--- a/include/sysemu/arch_init.h
18
+++ b/block/vdi.c
19
+++ b/include/sysemu/arch_init.h
20
@@ -XXX,XX +XXX,XX @@ enum {
21
QEMU_ARCH_NIOS2 = (1 << 17),
22
QEMU_ARCH_HPPA = (1 << 18),
23
QEMU_ARCH_RISCV = (1 << 19),
24
+
25
+ QEMU_ARCH_NONE = (1 << 31),
26
};
27
28
extern const uint32_t arch_type;
29
diff --git a/stubs/arch_type.c b/stubs/arch_type.c
30
new file mode 100644
31
index XXXXXXX..XXXXXXX
32
--- /dev/null
33
+++ b/stubs/arch_type.c
19
@@ -XXX,XX +XXX,XX @@
34
@@ -XXX,XX +XXX,XX @@
20
#define BLOCK_OPT_STATIC "static"
35
+#include "qemu/osdep.h"
21
36
+#include "sysemu/arch_init.h"
22
#define SECTOR_SIZE 512
37
+
23
-#define DEFAULT_CLUSTER_SIZE (1 * MiB)
38
+const uint32_t arch_type = QEMU_ARCH_NONE;
24
+#define DEFAULT_CLUSTER_SIZE S_1MiB
39
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
25
40
index XXXXXXX..XXXXXXX 100644
26
#if defined(CONFIG_VDI_DEBUG)
41
--- a/stubs/Makefile.objs
27
#define VDI_DEBUG 1
42
+++ b/stubs/Makefile.objs
28
@@ -XXX,XX +XXX,XX @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
43
@@ -XXX,XX +XXX,XX @@
29
goto fail;
44
+stub-obj-y += arch_type.o
30
} else if (header.block_size != DEFAULT_CLUSTER_SIZE) {
45
stub-obj-y += bdrv-next-monitor-owned.o
31
error_setg(errp, "unsupported VDI image (block size %" PRIu32
46
stub-obj-y += blk-commit-all.o
32
- " is not %" PRIu64 ")",
47
stub-obj-y += blockdev-close-all-bdrv-states.o
33
+ " is not %" PRIu32 ")",
34
header.block_size, DEFAULT_CLUSTER_SIZE);
35
ret = -ENOTSUP;
36
goto fail;
37
--
48
--
38
2.19.1
49
2.20.1
39
50
40
51
diff view generated by jsdifflib
1
While we want machine interfaces like -blockdev and QMP blockdev-add to
1
These commands make only sense for system emulators and their
2
add as little auto-detection as possible so that management tools are
2
implementations call functions that don't exist in tools (e.g. to
3
explicit about their needs, -drive is a convenience option for human
3
resolve qdev IDs). Move them out so that blockdev.c can be linked to
4
users. Enabling auto-read-only=on by default there enables users to use
4
qemu-storage-daemon.
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
5
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Reviewed-by: Eric Blake <eblake@redhat.com>
7
Message-Id: <20200224143008.13362-4-kwolf@redhat.com>
8
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
10
---
12
blockdev.c | 1 +
11
block/qapi-sysemu.c | 590 ++++++++++++++++++++++++++++++++++++++++++++
13
1 file changed, 1 insertion(+)
12
blockdev.c | 559 -----------------------------------------
13
block/Makefile.objs | 2 +
14
3 files changed, 592 insertions(+), 559 deletions(-)
15
create mode 100644 block/qapi-sysemu.c
14
16
17
diff --git a/block/qapi-sysemu.c b/block/qapi-sysemu.c
18
new file mode 100644
19
index XXXXXXX..XXXXXXX
20
--- /dev/null
21
+++ b/block/qapi-sysemu.c
22
@@ -XXX,XX +XXX,XX @@
23
+/*
24
+ * QMP command handlers specific to the system emulators
25
+ *
26
+ * Copyright (c) 2003-2008 Fabrice Bellard
27
+ *
28
+ * This work is licensed under the terms of the GNU GPL, version 2 or
29
+ * later. See the COPYING file in the top-level directory.
30
+ *
31
+ * This file incorporates work covered by the following copyright and
32
+ * permission notice:
33
+ *
34
+ * Copyright (c) 2003-2008 Fabrice Bellard
35
+ *
36
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
37
+ * of this software and associated documentation files (the "Software"), to deal
38
+ * in the Software without restriction, including without limitation the rights
39
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
40
+ * copies of the Software, and to permit persons to whom the Software is
41
+ * furnished to do so, subject to the following conditions:
42
+ *
43
+ * The above copyright notice and this permission notice shall be included in
44
+ * all copies or substantial portions of the Software.
45
+ *
46
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
47
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
48
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
49
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
50
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
51
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
52
+ * THE SOFTWARE.
53
+ */
54
+
55
+#include "qemu/osdep.h"
56
+
57
+#include "qapi/error.h"
58
+#include "qapi/qapi-commands-block.h"
59
+#include "qapi/qmp/qdict.h"
60
+#include "sysemu/block-backend.h"
61
+#include "sysemu/blockdev.h"
62
+
63
+static BlockBackend *qmp_get_blk(const char *blk_name, const char *qdev_id,
64
+ Error **errp)
65
+{
66
+ BlockBackend *blk;
67
+
68
+ if (!blk_name == !qdev_id) {
69
+ error_setg(errp, "Need exactly one of 'device' and 'id'");
70
+ return NULL;
71
+ }
72
+
73
+ if (qdev_id) {
74
+ blk = blk_by_qdev_id(qdev_id, errp);
75
+ } else {
76
+ blk = blk_by_name(blk_name);
77
+ if (blk == NULL) {
78
+ error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
79
+ "Device '%s' not found", blk_name);
80
+ }
81
+ }
82
+
83
+ return blk;
84
+}
85
+
86
+/*
87
+ * Attempt to open the tray of @device.
88
+ * If @force, ignore its tray lock.
89
+ * Else, if the tray is locked, don't open it, but ask the guest to open it.
90
+ * On error, store an error through @errp and return -errno.
91
+ * If @device does not exist, return -ENODEV.
92
+ * If it has no removable media, return -ENOTSUP.
93
+ * If it has no tray, return -ENOSYS.
94
+ * If the guest was asked to open the tray, return -EINPROGRESS.
95
+ * Else, return 0.
96
+ */
97
+static int do_open_tray(const char *blk_name, const char *qdev_id,
98
+ bool force, Error **errp)
99
+{
100
+ BlockBackend *blk;
101
+ const char *device = qdev_id ?: blk_name;
102
+ bool locked;
103
+
104
+ blk = qmp_get_blk(blk_name, qdev_id, errp);
105
+ if (!blk) {
106
+ return -ENODEV;
107
+ }
108
+
109
+ if (!blk_dev_has_removable_media(blk)) {
110
+ error_setg(errp, "Device '%s' is not removable", device);
111
+ return -ENOTSUP;
112
+ }
113
+
114
+ if (!blk_dev_has_tray(blk)) {
115
+ error_setg(errp, "Device '%s' does not have a tray", device);
116
+ return -ENOSYS;
117
+ }
118
+
119
+ if (blk_dev_is_tray_open(blk)) {
120
+ return 0;
121
+ }
122
+
123
+ locked = blk_dev_is_medium_locked(blk);
124
+ if (locked) {
125
+ blk_dev_eject_request(blk, force);
126
+ }
127
+
128
+ if (!locked || force) {
129
+ blk_dev_change_media_cb(blk, false, &error_abort);
130
+ }
131
+
132
+ if (locked && !force) {
133
+ error_setg(errp, "Device '%s' is locked and force was not specified, "
134
+ "wait for tray to open and try again", device);
135
+ return -EINPROGRESS;
136
+ }
137
+
138
+ return 0;
139
+}
140
+
141
+void qmp_blockdev_open_tray(bool has_device, const char *device,
142
+ bool has_id, const char *id,
143
+ bool has_force, bool force,
144
+ Error **errp)
145
+{
146
+ Error *local_err = NULL;
147
+ int rc;
148
+
149
+ if (!has_force) {
150
+ force = false;
151
+ }
152
+ rc = do_open_tray(has_device ? device : NULL,
153
+ has_id ? id : NULL,
154
+ force, &local_err);
155
+ if (rc && rc != -ENOSYS && rc != -EINPROGRESS) {
156
+ error_propagate(errp, local_err);
157
+ return;
158
+ }
159
+ error_free(local_err);
160
+}
161
+
162
+void qmp_blockdev_close_tray(bool has_device, const char *device,
163
+ bool has_id, const char *id,
164
+ Error **errp)
165
+{
166
+ BlockBackend *blk;
167
+ Error *local_err = NULL;
168
+
169
+ device = has_device ? device : NULL;
170
+ id = has_id ? id : NULL;
171
+
172
+ blk = qmp_get_blk(device, id, errp);
173
+ if (!blk) {
174
+ return;
175
+ }
176
+
177
+ if (!blk_dev_has_removable_media(blk)) {
178
+ error_setg(errp, "Device '%s' is not removable", device ?: id);
179
+ return;
180
+ }
181
+
182
+ if (!blk_dev_has_tray(blk)) {
183
+ /* Ignore this command on tray-less devices */
184
+ return;
185
+ }
186
+
187
+ if (!blk_dev_is_tray_open(blk)) {
188
+ return;
189
+ }
190
+
191
+ blk_dev_change_media_cb(blk, true, &local_err);
192
+ if (local_err) {
193
+ error_propagate(errp, local_err);
194
+ return;
195
+ }
196
+}
197
+
198
+static void blockdev_remove_medium(bool has_device, const char *device,
199
+ bool has_id, const char *id, Error **errp)
200
+{
201
+ BlockBackend *blk;
202
+ BlockDriverState *bs;
203
+ AioContext *aio_context;
204
+ bool has_attached_device;
205
+
206
+ device = has_device ? device : NULL;
207
+ id = has_id ? id : NULL;
208
+
209
+ blk = qmp_get_blk(device, id, errp);
210
+ if (!blk) {
211
+ return;
212
+ }
213
+
214
+ /* For BBs without a device, we can exchange the BDS tree at will */
215
+ has_attached_device = blk_get_attached_dev(blk);
216
+
217
+ if (has_attached_device && !blk_dev_has_removable_media(blk)) {
218
+ error_setg(errp, "Device '%s' is not removable", device ?: id);
219
+ return;
220
+ }
221
+
222
+ if (has_attached_device && blk_dev_has_tray(blk) &&
223
+ !blk_dev_is_tray_open(blk))
224
+ {
225
+ error_setg(errp, "Tray of device '%s' is not open", device ?: id);
226
+ return;
227
+ }
228
+
229
+ bs = blk_bs(blk);
230
+ if (!bs) {
231
+ return;
232
+ }
233
+
234
+ aio_context = bdrv_get_aio_context(bs);
235
+ aio_context_acquire(aio_context);
236
+
237
+ if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_EJECT, errp)) {
238
+ goto out;
239
+ }
240
+
241
+ blk_remove_bs(blk);
242
+
243
+ if (!blk_dev_has_tray(blk)) {
244
+ /* For tray-less devices, blockdev-open-tray is a no-op (or may not be
245
+ * called at all); therefore, the medium needs to be ejected here.
246
+ * Do it after blk_remove_bs() so blk_is_inserted(blk) returns the @load
247
+ * value passed here (i.e. false). */
248
+ blk_dev_change_media_cb(blk, false, &error_abort);
249
+ }
250
+
251
+out:
252
+ aio_context_release(aio_context);
253
+}
254
+
255
+void qmp_blockdev_remove_medium(const char *id, Error **errp)
256
+{
257
+ blockdev_remove_medium(false, NULL, true, id, errp);
258
+}
259
+
260
+static void qmp_blockdev_insert_anon_medium(BlockBackend *blk,
261
+ BlockDriverState *bs, Error **errp)
262
+{
263
+ Error *local_err = NULL;
264
+ bool has_device;
265
+ int ret;
266
+
267
+ /* For BBs without a device, we can exchange the BDS tree at will */
268
+ has_device = blk_get_attached_dev(blk);
269
+
270
+ if (has_device && !blk_dev_has_removable_media(blk)) {
271
+ error_setg(errp, "Device is not removable");
272
+ return;
273
+ }
274
+
275
+ if (has_device && blk_dev_has_tray(blk) && !blk_dev_is_tray_open(blk)) {
276
+ error_setg(errp, "Tray of the device is not open");
277
+ return;
278
+ }
279
+
280
+ if (blk_bs(blk)) {
281
+ error_setg(errp, "There already is a medium in the device");
282
+ return;
283
+ }
284
+
285
+ ret = blk_insert_bs(blk, bs, errp);
286
+ if (ret < 0) {
287
+ return;
288
+ }
289
+
290
+ if (!blk_dev_has_tray(blk)) {
291
+ /* For tray-less devices, blockdev-close-tray is a no-op (or may not be
292
+ * called at all); therefore, the medium needs to be pushed into the
293
+ * slot here.
294
+ * Do it after blk_insert_bs() so blk_is_inserted(blk) returns the @load
295
+ * value passed here (i.e. true). */
296
+ blk_dev_change_media_cb(blk, true, &local_err);
297
+ if (local_err) {
298
+ error_propagate(errp, local_err);
299
+ blk_remove_bs(blk);
300
+ return;
301
+ }
302
+ }
303
+}
304
+
305
+static void blockdev_insert_medium(bool has_device, const char *device,
306
+ bool has_id, const char *id,
307
+ const char *node_name, Error **errp)
308
+{
309
+ BlockBackend *blk;
310
+ BlockDriverState *bs;
311
+
312
+ blk = qmp_get_blk(has_device ? device : NULL,
313
+ has_id ? id : NULL,
314
+ errp);
315
+ if (!blk) {
316
+ return;
317
+ }
318
+
319
+ bs = bdrv_find_node(node_name);
320
+ if (!bs) {
321
+ error_setg(errp, "Node '%s' not found", node_name);
322
+ return;
323
+ }
324
+
325
+ if (bdrv_has_blk(bs)) {
326
+ error_setg(errp, "Node '%s' is already in use", node_name);
327
+ return;
328
+ }
329
+
330
+ qmp_blockdev_insert_anon_medium(blk, bs, errp);
331
+}
332
+
333
+void qmp_blockdev_insert_medium(const char *id, const char *node_name,
334
+ Error **errp)
335
+{
336
+ blockdev_insert_medium(false, NULL, true, id, node_name, errp);
337
+}
338
+
339
+void qmp_blockdev_change_medium(bool has_device, const char *device,
340
+ bool has_id, const char *id,
341
+ const char *filename,
342
+ bool has_format, const char *format,
343
+ bool has_read_only,
344
+ BlockdevChangeReadOnlyMode read_only,
345
+ Error **errp)
346
+{
347
+ BlockBackend *blk;
348
+ BlockDriverState *medium_bs = NULL;
349
+ int bdrv_flags;
350
+ bool detect_zeroes;
351
+ int rc;
352
+ QDict *options = NULL;
353
+ Error *err = NULL;
354
+
355
+ blk = qmp_get_blk(has_device ? device : NULL,
356
+ has_id ? id : NULL,
357
+ errp);
358
+ if (!blk) {
359
+ goto fail;
360
+ }
361
+
362
+ if (blk_bs(blk)) {
363
+ blk_update_root_state(blk);
364
+ }
365
+
366
+ bdrv_flags = blk_get_open_flags_from_root_state(blk);
367
+ bdrv_flags &= ~(BDRV_O_TEMPORARY | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING |
368
+ BDRV_O_PROTOCOL | BDRV_O_AUTO_RDONLY);
369
+
370
+ if (!has_read_only) {
371
+ read_only = BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN;
372
+ }
373
+
374
+ switch (read_only) {
375
+ case BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN:
376
+ break;
377
+
378
+ case BLOCKDEV_CHANGE_READ_ONLY_MODE_READ_ONLY:
379
+ bdrv_flags &= ~BDRV_O_RDWR;
380
+ break;
381
+
382
+ case BLOCKDEV_CHANGE_READ_ONLY_MODE_READ_WRITE:
383
+ bdrv_flags |= BDRV_O_RDWR;
384
+ break;
385
+
386
+ default:
387
+ abort();
388
+ }
389
+
390
+ options = qdict_new();
391
+ detect_zeroes = blk_get_detect_zeroes_from_root_state(blk);
392
+ qdict_put_str(options, "detect-zeroes", detect_zeroes ? "on" : "off");
393
+
394
+ if (has_format) {
395
+ qdict_put_str(options, "driver", format);
396
+ }
397
+
398
+ medium_bs = bdrv_open(filename, NULL, options, bdrv_flags, errp);
399
+ if (!medium_bs) {
400
+ goto fail;
401
+ }
402
+
403
+ rc = do_open_tray(has_device ? device : NULL,
404
+ has_id ? id : NULL,
405
+ false, &err);
406
+ if (rc && rc != -ENOSYS) {
407
+ error_propagate(errp, err);
408
+ goto fail;
409
+ }
410
+ error_free(err);
411
+ err = NULL;
412
+
413
+ blockdev_remove_medium(has_device, device, has_id, id, &err);
414
+ if (err) {
415
+ error_propagate(errp, err);
416
+ goto fail;
417
+ }
418
+
419
+ qmp_blockdev_insert_anon_medium(blk, medium_bs, &err);
420
+ if (err) {
421
+ error_propagate(errp, err);
422
+ goto fail;
423
+ }
424
+
425
+ qmp_blockdev_close_tray(has_device, device, has_id, id, errp);
426
+
427
+fail:
428
+ /* If the medium has been inserted, the device has its own reference, so
429
+ * ours must be relinquished; and if it has not been inserted successfully,
430
+ * the reference must be relinquished anyway */
431
+ bdrv_unref(medium_bs);
432
+}
433
+
434
+void qmp_eject(bool has_device, const char *device,
435
+ bool has_id, const char *id,
436
+ bool has_force, bool force, Error **errp)
437
+{
438
+ Error *local_err = NULL;
439
+ int rc;
440
+
441
+ if (!has_force) {
442
+ force = false;
443
+ }
444
+
445
+ rc = do_open_tray(has_device ? device : NULL,
446
+ has_id ? id : NULL,
447
+ force, &local_err);
448
+ if (rc && rc != -ENOSYS) {
449
+ error_propagate(errp, local_err);
450
+ return;
451
+ }
452
+ error_free(local_err);
453
+
454
+ blockdev_remove_medium(has_device, device, has_id, id, errp);
455
+}
456
+
457
+/* throttling disk I/O limits */
458
+void qmp_block_set_io_throttle(BlockIOThrottle *arg, Error **errp)
459
+{
460
+ ThrottleConfig cfg;
461
+ BlockDriverState *bs;
462
+ BlockBackend *blk;
463
+ AioContext *aio_context;
464
+
465
+ blk = qmp_get_blk(arg->has_device ? arg->device : NULL,
466
+ arg->has_id ? arg->id : NULL,
467
+ errp);
468
+ if (!blk) {
469
+ return;
470
+ }
471
+
472
+ aio_context = blk_get_aio_context(blk);
473
+ aio_context_acquire(aio_context);
474
+
475
+ bs = blk_bs(blk);
476
+ if (!bs) {
477
+ error_setg(errp, "Device has no medium");
478
+ goto out;
479
+ }
480
+
481
+ throttle_config_init(&cfg);
482
+ cfg.buckets[THROTTLE_BPS_TOTAL].avg = arg->bps;
483
+ cfg.buckets[THROTTLE_BPS_READ].avg = arg->bps_rd;
484
+ cfg.buckets[THROTTLE_BPS_WRITE].avg = arg->bps_wr;
485
+
486
+ cfg.buckets[THROTTLE_OPS_TOTAL].avg = arg->iops;
487
+ cfg.buckets[THROTTLE_OPS_READ].avg = arg->iops_rd;
488
+ cfg.buckets[THROTTLE_OPS_WRITE].avg = arg->iops_wr;
489
+
490
+ if (arg->has_bps_max) {
491
+ cfg.buckets[THROTTLE_BPS_TOTAL].max = arg->bps_max;
492
+ }
493
+ if (arg->has_bps_rd_max) {
494
+ cfg.buckets[THROTTLE_BPS_READ].max = arg->bps_rd_max;
495
+ }
496
+ if (arg->has_bps_wr_max) {
497
+ cfg.buckets[THROTTLE_BPS_WRITE].max = arg->bps_wr_max;
498
+ }
499
+ if (arg->has_iops_max) {
500
+ cfg.buckets[THROTTLE_OPS_TOTAL].max = arg->iops_max;
501
+ }
502
+ if (arg->has_iops_rd_max) {
503
+ cfg.buckets[THROTTLE_OPS_READ].max = arg->iops_rd_max;
504
+ }
505
+ if (arg->has_iops_wr_max) {
506
+ cfg.buckets[THROTTLE_OPS_WRITE].max = arg->iops_wr_max;
507
+ }
508
+
509
+ if (arg->has_bps_max_length) {
510
+ cfg.buckets[THROTTLE_BPS_TOTAL].burst_length = arg->bps_max_length;
511
+ }
512
+ if (arg->has_bps_rd_max_length) {
513
+ cfg.buckets[THROTTLE_BPS_READ].burst_length = arg->bps_rd_max_length;
514
+ }
515
+ if (arg->has_bps_wr_max_length) {
516
+ cfg.buckets[THROTTLE_BPS_WRITE].burst_length = arg->bps_wr_max_length;
517
+ }
518
+ if (arg->has_iops_max_length) {
519
+ cfg.buckets[THROTTLE_OPS_TOTAL].burst_length = arg->iops_max_length;
520
+ }
521
+ if (arg->has_iops_rd_max_length) {
522
+ cfg.buckets[THROTTLE_OPS_READ].burst_length = arg->iops_rd_max_length;
523
+ }
524
+ if (arg->has_iops_wr_max_length) {
525
+ cfg.buckets[THROTTLE_OPS_WRITE].burst_length = arg->iops_wr_max_length;
526
+ }
527
+
528
+ if (arg->has_iops_size) {
529
+ cfg.op_size = arg->iops_size;
530
+ }
531
+
532
+ if (!throttle_is_valid(&cfg, errp)) {
533
+ goto out;
534
+ }
535
+
536
+ if (throttle_enabled(&cfg)) {
537
+ /* Enable I/O limits if they're not enabled yet, otherwise
538
+ * just update the throttling group. */
539
+ if (!blk_get_public(blk)->throttle_group_member.throttle_state) {
540
+ blk_io_limits_enable(blk,
541
+ arg->has_group ? arg->group :
542
+ arg->has_device ? arg->device :
543
+ arg->id);
544
+ } else if (arg->has_group) {
545
+ blk_io_limits_update_group(blk, arg->group);
546
+ }
547
+ /* Set the new throttling configuration */
548
+ blk_set_io_limits(blk, &cfg);
549
+ } else if (blk_get_public(blk)->throttle_group_member.throttle_state) {
550
+ /* If all throttling settings are set to 0, disable I/O limits */
551
+ blk_io_limits_disable(blk);
552
+ }
553
+
554
+out:
555
+ aio_context_release(aio_context);
556
+}
557
+
558
+void qmp_block_latency_histogram_set(
559
+ const char *id,
560
+ bool has_boundaries, uint64List *boundaries,
561
+ bool has_boundaries_read, uint64List *boundaries_read,
562
+ bool has_boundaries_write, uint64List *boundaries_write,
563
+ bool has_boundaries_flush, uint64List *boundaries_flush,
564
+ Error **errp)
565
+{
566
+ BlockBackend *blk = qmp_get_blk(NULL, id, errp);
567
+ BlockAcctStats *stats;
568
+ int ret;
569
+
570
+ if (!blk) {
571
+ return;
572
+ }
573
+
574
+ stats = blk_get_stats(blk);
575
+
576
+ if (!has_boundaries && !has_boundaries_read && !has_boundaries_write &&
577
+ !has_boundaries_flush)
578
+ {
579
+ block_latency_histograms_clear(stats);
580
+ return;
581
+ }
582
+
583
+ if (has_boundaries || has_boundaries_read) {
584
+ ret = block_latency_histogram_set(
585
+ stats, BLOCK_ACCT_READ,
586
+ has_boundaries_read ? boundaries_read : boundaries);
587
+ if (ret) {
588
+ error_setg(errp, "Device '%s' set read boundaries fail", id);
589
+ return;
590
+ }
591
+ }
592
+
593
+ if (has_boundaries || has_boundaries_write) {
594
+ ret = block_latency_histogram_set(
595
+ stats, BLOCK_ACCT_WRITE,
596
+ has_boundaries_write ? boundaries_write : boundaries);
597
+ if (ret) {
598
+ error_setg(errp, "Device '%s' set write boundaries fail", id);
599
+ return;
600
+ }
601
+ }
602
+
603
+ if (has_boundaries || has_boundaries_flush) {
604
+ ret = block_latency_histogram_set(
605
+ stats, BLOCK_ACCT_FLUSH,
606
+ has_boundaries_flush ? boundaries_flush : boundaries);
607
+ if (ret) {
608
+ error_setg(errp, "Device '%s' set flush boundaries fail", id);
609
+ return;
610
+ }
611
+ }
612
+}
15
diff --git a/blockdev.c b/blockdev.c
613
diff --git a/blockdev.c b/blockdev.c
16
index XXXXXXX..XXXXXXX 100644
614
index XXXXXXX..XXXXXXX 100644
17
--- a/blockdev.c
615
--- a/blockdev.c
18
+++ b/blockdev.c
616
+++ b/blockdev.c
19
@@ -XXX,XX +XXX,XX @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
617
@@ -XXX,XX +XXX,XX @@
20
qdict_set_default_str(bs_opts, BDRV_OPT_CACHE_NO_FLUSH, "off");
618
static QTAILQ_HEAD(, BlockDriverState) monitor_bdrv_states =
21
qdict_set_default_str(bs_opts, BDRV_OPT_READ_ONLY,
619
QTAILQ_HEAD_INITIALIZER(monitor_bdrv_states);
22
read_only ? "on" : "off");
620
23
+ qdict_set_default_str(bs_opts, BDRV_OPT_AUTO_READ_ONLY, "on");
621
-static int do_open_tray(const char *blk_name, const char *qdev_id,
24
assert((bdrv_flags & BDRV_O_CACHE_MASK) == 0);
622
- bool force, Error **errp);
25
623
-static void blockdev_remove_medium(bool has_device, const char *device,
26
if (runstate_check(RUN_STATE_INMIGRATE)) {
624
- bool has_id, const char *id, Error **errp);
625
-static void blockdev_insert_medium(bool has_device, const char *device,
626
- bool has_id, const char *id,
627
- const char *node_name, Error **errp);
628
-
629
static const char *const if_name[IF_COUNT] = {
630
[IF_NONE] = "none",
631
[IF_IDE] = "ide",
632
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *qmp_get_root_bs(const char *name, Error **errp)
633
return bs;
634
}
635
636
-static BlockBackend *qmp_get_blk(const char *blk_name, const char *qdev_id,
637
- Error **errp)
638
-{
639
- BlockBackend *blk;
640
-
641
- if (!blk_name == !qdev_id) {
642
- error_setg(errp, "Need exactly one of 'device' and 'id'");
643
- return NULL;
644
- }
645
-
646
- if (qdev_id) {
647
- blk = blk_by_qdev_id(qdev_id, errp);
648
- } else {
649
- blk = blk_by_name(blk_name);
650
- if (blk == NULL) {
651
- error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
652
- "Device '%s' not found", blk_name);
653
- }
654
- }
655
-
656
- return blk;
657
-}
658
-
659
void hmp_commit(Monitor *mon, const QDict *qdict)
660
{
661
const char *device = qdict_get_str(qdict, "device");
662
@@ -XXX,XX +XXX,XX @@ exit:
663
job_txn_unref(block_job_txn);
664
}
665
666
-void qmp_eject(bool has_device, const char *device,
667
- bool has_id, const char *id,
668
- bool has_force, bool force, Error **errp)
669
-{
670
- Error *local_err = NULL;
671
- int rc;
672
-
673
- if (!has_force) {
674
- force = false;
675
- }
676
-
677
- rc = do_open_tray(has_device ? device : NULL,
678
- has_id ? id : NULL,
679
- force, &local_err);
680
- if (rc && rc != -ENOSYS) {
681
- error_propagate(errp, local_err);
682
- return;
683
- }
684
- error_free(local_err);
685
-
686
- blockdev_remove_medium(has_device, device, has_id, id, errp);
687
-}
688
-
689
void qmp_block_passwd(bool has_device, const char *device,
690
bool has_node_name, const char *node_name,
691
const char *password, Error **errp)
692
@@ -XXX,XX +XXX,XX @@ void qmp_block_passwd(bool has_device, const char *device,
693
"Setting block passwords directly is no longer supported");
694
}
695
696
-/*
697
- * Attempt to open the tray of @device.
698
- * If @force, ignore its tray lock.
699
- * Else, if the tray is locked, don't open it, but ask the guest to open it.
700
- * On error, store an error through @errp and return -errno.
701
- * If @device does not exist, return -ENODEV.
702
- * If it has no removable media, return -ENOTSUP.
703
- * If it has no tray, return -ENOSYS.
704
- * If the guest was asked to open the tray, return -EINPROGRESS.
705
- * Else, return 0.
706
- */
707
-static int do_open_tray(const char *blk_name, const char *qdev_id,
708
- bool force, Error **errp)
709
-{
710
- BlockBackend *blk;
711
- const char *device = qdev_id ?: blk_name;
712
- bool locked;
713
-
714
- blk = qmp_get_blk(blk_name, qdev_id, errp);
715
- if (!blk) {
716
- return -ENODEV;
717
- }
718
-
719
- if (!blk_dev_has_removable_media(blk)) {
720
- error_setg(errp, "Device '%s' is not removable", device);
721
- return -ENOTSUP;
722
- }
723
-
724
- if (!blk_dev_has_tray(blk)) {
725
- error_setg(errp, "Device '%s' does not have a tray", device);
726
- return -ENOSYS;
727
- }
728
-
729
- if (blk_dev_is_tray_open(blk)) {
730
- return 0;
731
- }
732
-
733
- locked = blk_dev_is_medium_locked(blk);
734
- if (locked) {
735
- blk_dev_eject_request(blk, force);
736
- }
737
-
738
- if (!locked || force) {
739
- blk_dev_change_media_cb(blk, false, &error_abort);
740
- }
741
-
742
- if (locked && !force) {
743
- error_setg(errp, "Device '%s' is locked and force was not specified, "
744
- "wait for tray to open and try again", device);
745
- return -EINPROGRESS;
746
- }
747
-
748
- return 0;
749
-}
750
-
751
-void qmp_blockdev_open_tray(bool has_device, const char *device,
752
- bool has_id, const char *id,
753
- bool has_force, bool force,
754
- Error **errp)
755
-{
756
- Error *local_err = NULL;
757
- int rc;
758
-
759
- if (!has_force) {
760
- force = false;
761
- }
762
- rc = do_open_tray(has_device ? device : NULL,
763
- has_id ? id : NULL,
764
- force, &local_err);
765
- if (rc && rc != -ENOSYS && rc != -EINPROGRESS) {
766
- error_propagate(errp, local_err);
767
- return;
768
- }
769
- error_free(local_err);
770
-}
771
-
772
-void qmp_blockdev_close_tray(bool has_device, const char *device,
773
- bool has_id, const char *id,
774
- Error **errp)
775
-{
776
- BlockBackend *blk;
777
- Error *local_err = NULL;
778
-
779
- device = has_device ? device : NULL;
780
- id = has_id ? id : NULL;
781
-
782
- blk = qmp_get_blk(device, id, errp);
783
- if (!blk) {
784
- return;
785
- }
786
-
787
- if (!blk_dev_has_removable_media(blk)) {
788
- error_setg(errp, "Device '%s' is not removable", device ?: id);
789
- return;
790
- }
791
-
792
- if (!blk_dev_has_tray(blk)) {
793
- /* Ignore this command on tray-less devices */
794
- return;
795
- }
796
-
797
- if (!blk_dev_is_tray_open(blk)) {
798
- return;
799
- }
800
-
801
- blk_dev_change_media_cb(blk, true, &local_err);
802
- if (local_err) {
803
- error_propagate(errp, local_err);
804
- return;
805
- }
806
-}
807
-
808
-static void blockdev_remove_medium(bool has_device, const char *device,
809
- bool has_id, const char *id, Error **errp)
810
-{
811
- BlockBackend *blk;
812
- BlockDriverState *bs;
813
- AioContext *aio_context;
814
- bool has_attached_device;
815
-
816
- device = has_device ? device : NULL;
817
- id = has_id ? id : NULL;
818
-
819
- blk = qmp_get_blk(device, id, errp);
820
- if (!blk) {
821
- return;
822
- }
823
-
824
- /* For BBs without a device, we can exchange the BDS tree at will */
825
- has_attached_device = blk_get_attached_dev(blk);
826
-
827
- if (has_attached_device && !blk_dev_has_removable_media(blk)) {
828
- error_setg(errp, "Device '%s' is not removable", device ?: id);
829
- return;
830
- }
831
-
832
- if (has_attached_device && blk_dev_has_tray(blk) &&
833
- !blk_dev_is_tray_open(blk))
834
- {
835
- error_setg(errp, "Tray of device '%s' is not open", device ?: id);
836
- return;
837
- }
838
-
839
- bs = blk_bs(blk);
840
- if (!bs) {
841
- return;
842
- }
843
-
844
- aio_context = bdrv_get_aio_context(bs);
845
- aio_context_acquire(aio_context);
846
-
847
- if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_EJECT, errp)) {
848
- goto out;
849
- }
850
-
851
- blk_remove_bs(blk);
852
-
853
- if (!blk_dev_has_tray(blk)) {
854
- /* For tray-less devices, blockdev-open-tray is a no-op (or may not be
855
- * called at all); therefore, the medium needs to be ejected here.
856
- * Do it after blk_remove_bs() so blk_is_inserted(blk) returns the @load
857
- * value passed here (i.e. false). */
858
- blk_dev_change_media_cb(blk, false, &error_abort);
859
- }
860
-
861
-out:
862
- aio_context_release(aio_context);
863
-}
864
-
865
-void qmp_blockdev_remove_medium(const char *id, Error **errp)
866
-{
867
- blockdev_remove_medium(false, NULL, true, id, errp);
868
-}
869
-
870
-static void qmp_blockdev_insert_anon_medium(BlockBackend *blk,
871
- BlockDriverState *bs, Error **errp)
872
-{
873
- Error *local_err = NULL;
874
- bool has_device;
875
- int ret;
876
-
877
- /* For BBs without a device, we can exchange the BDS tree at will */
878
- has_device = blk_get_attached_dev(blk);
879
-
880
- if (has_device && !blk_dev_has_removable_media(blk)) {
881
- error_setg(errp, "Device is not removable");
882
- return;
883
- }
884
-
885
- if (has_device && blk_dev_has_tray(blk) && !blk_dev_is_tray_open(blk)) {
886
- error_setg(errp, "Tray of the device is not open");
887
- return;
888
- }
889
-
890
- if (blk_bs(blk)) {
891
- error_setg(errp, "There already is a medium in the device");
892
- return;
893
- }
894
-
895
- ret = blk_insert_bs(blk, bs, errp);
896
- if (ret < 0) {
897
- return;
898
- }
899
-
900
- if (!blk_dev_has_tray(blk)) {
901
- /* For tray-less devices, blockdev-close-tray is a no-op (or may not be
902
- * called at all); therefore, the medium needs to be pushed into the
903
- * slot here.
904
- * Do it after blk_insert_bs() so blk_is_inserted(blk) returns the @load
905
- * value passed here (i.e. true). */
906
- blk_dev_change_media_cb(blk, true, &local_err);
907
- if (local_err) {
908
- error_propagate(errp, local_err);
909
- blk_remove_bs(blk);
910
- return;
911
- }
912
- }
913
-}
914
-
915
-static void blockdev_insert_medium(bool has_device, const char *device,
916
- bool has_id, const char *id,
917
- const char *node_name, Error **errp)
918
-{
919
- BlockBackend *blk;
920
- BlockDriverState *bs;
921
-
922
- blk = qmp_get_blk(has_device ? device : NULL,
923
- has_id ? id : NULL,
924
- errp);
925
- if (!blk) {
926
- return;
927
- }
928
-
929
- bs = bdrv_find_node(node_name);
930
- if (!bs) {
931
- error_setg(errp, "Node '%s' not found", node_name);
932
- return;
933
- }
934
-
935
- if (bdrv_has_blk(bs)) {
936
- error_setg(errp, "Node '%s' is already in use", node_name);
937
- return;
938
- }
939
-
940
- qmp_blockdev_insert_anon_medium(blk, bs, errp);
941
-}
942
-
943
-void qmp_blockdev_insert_medium(const char *id, const char *node_name,
944
- Error **errp)
945
-{
946
- blockdev_insert_medium(false, NULL, true, id, node_name, errp);
947
-}
948
-
949
-void qmp_blockdev_change_medium(bool has_device, const char *device,
950
- bool has_id, const char *id,
951
- const char *filename,
952
- bool has_format, const char *format,
953
- bool has_read_only,
954
- BlockdevChangeReadOnlyMode read_only,
955
- Error **errp)
956
-{
957
- BlockBackend *blk;
958
- BlockDriverState *medium_bs = NULL;
959
- int bdrv_flags;
960
- bool detect_zeroes;
961
- int rc;
962
- QDict *options = NULL;
963
- Error *err = NULL;
964
-
965
- blk = qmp_get_blk(has_device ? device : NULL,
966
- has_id ? id : NULL,
967
- errp);
968
- if (!blk) {
969
- goto fail;
970
- }
971
-
972
- if (blk_bs(blk)) {
973
- blk_update_root_state(blk);
974
- }
975
-
976
- bdrv_flags = blk_get_open_flags_from_root_state(blk);
977
- bdrv_flags &= ~(BDRV_O_TEMPORARY | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING |
978
- BDRV_O_PROTOCOL | BDRV_O_AUTO_RDONLY);
979
-
980
- if (!has_read_only) {
981
- read_only = BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN;
982
- }
983
-
984
- switch (read_only) {
985
- case BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN:
986
- break;
987
-
988
- case BLOCKDEV_CHANGE_READ_ONLY_MODE_READ_ONLY:
989
- bdrv_flags &= ~BDRV_O_RDWR;
990
- break;
991
-
992
- case BLOCKDEV_CHANGE_READ_ONLY_MODE_READ_WRITE:
993
- bdrv_flags |= BDRV_O_RDWR;
994
- break;
995
-
996
- default:
997
- abort();
998
- }
999
-
1000
- options = qdict_new();
1001
- detect_zeroes = blk_get_detect_zeroes_from_root_state(blk);
1002
- qdict_put_str(options, "detect-zeroes", detect_zeroes ? "on" : "off");
1003
-
1004
- if (has_format) {
1005
- qdict_put_str(options, "driver", format);
1006
- }
1007
-
1008
- medium_bs = bdrv_open(filename, NULL, options, bdrv_flags, errp);
1009
- if (!medium_bs) {
1010
- goto fail;
1011
- }
1012
-
1013
- rc = do_open_tray(has_device ? device : NULL,
1014
- has_id ? id : NULL,
1015
- false, &err);
1016
- if (rc && rc != -ENOSYS) {
1017
- error_propagate(errp, err);
1018
- goto fail;
1019
- }
1020
- error_free(err);
1021
- err = NULL;
1022
-
1023
- blockdev_remove_medium(has_device, device, has_id, id, &err);
1024
- if (err) {
1025
- error_propagate(errp, err);
1026
- goto fail;
1027
- }
1028
-
1029
- qmp_blockdev_insert_anon_medium(blk, medium_bs, &err);
1030
- if (err) {
1031
- error_propagate(errp, err);
1032
- goto fail;
1033
- }
1034
-
1035
- qmp_blockdev_close_tray(has_device, device, has_id, id, errp);
1036
-
1037
-fail:
1038
- /* If the medium has been inserted, the device has its own reference, so
1039
- * ours must be relinquished; and if it has not been inserted successfully,
1040
- * the reference must be relinquished anyway */
1041
- bdrv_unref(medium_bs);
1042
-}
1043
-
1044
-/* throttling disk I/O limits */
1045
-void qmp_block_set_io_throttle(BlockIOThrottle *arg, Error **errp)
1046
-{
1047
- ThrottleConfig cfg;
1048
- BlockDriverState *bs;
1049
- BlockBackend *blk;
1050
- AioContext *aio_context;
1051
-
1052
- blk = qmp_get_blk(arg->has_device ? arg->device : NULL,
1053
- arg->has_id ? arg->id : NULL,
1054
- errp);
1055
- if (!blk) {
1056
- return;
1057
- }
1058
-
1059
- aio_context = blk_get_aio_context(blk);
1060
- aio_context_acquire(aio_context);
1061
-
1062
- bs = blk_bs(blk);
1063
- if (!bs) {
1064
- error_setg(errp, "Device has no medium");
1065
- goto out;
1066
- }
1067
-
1068
- throttle_config_init(&cfg);
1069
- cfg.buckets[THROTTLE_BPS_TOTAL].avg = arg->bps;
1070
- cfg.buckets[THROTTLE_BPS_READ].avg = arg->bps_rd;
1071
- cfg.buckets[THROTTLE_BPS_WRITE].avg = arg->bps_wr;
1072
-
1073
- cfg.buckets[THROTTLE_OPS_TOTAL].avg = arg->iops;
1074
- cfg.buckets[THROTTLE_OPS_READ].avg = arg->iops_rd;
1075
- cfg.buckets[THROTTLE_OPS_WRITE].avg = arg->iops_wr;
1076
-
1077
- if (arg->has_bps_max) {
1078
- cfg.buckets[THROTTLE_BPS_TOTAL].max = arg->bps_max;
1079
- }
1080
- if (arg->has_bps_rd_max) {
1081
- cfg.buckets[THROTTLE_BPS_READ].max = arg->bps_rd_max;
1082
- }
1083
- if (arg->has_bps_wr_max) {
1084
- cfg.buckets[THROTTLE_BPS_WRITE].max = arg->bps_wr_max;
1085
- }
1086
- if (arg->has_iops_max) {
1087
- cfg.buckets[THROTTLE_OPS_TOTAL].max = arg->iops_max;
1088
- }
1089
- if (arg->has_iops_rd_max) {
1090
- cfg.buckets[THROTTLE_OPS_READ].max = arg->iops_rd_max;
1091
- }
1092
- if (arg->has_iops_wr_max) {
1093
- cfg.buckets[THROTTLE_OPS_WRITE].max = arg->iops_wr_max;
1094
- }
1095
-
1096
- if (arg->has_bps_max_length) {
1097
- cfg.buckets[THROTTLE_BPS_TOTAL].burst_length = arg->bps_max_length;
1098
- }
1099
- if (arg->has_bps_rd_max_length) {
1100
- cfg.buckets[THROTTLE_BPS_READ].burst_length = arg->bps_rd_max_length;
1101
- }
1102
- if (arg->has_bps_wr_max_length) {
1103
- cfg.buckets[THROTTLE_BPS_WRITE].burst_length = arg->bps_wr_max_length;
1104
- }
1105
- if (arg->has_iops_max_length) {
1106
- cfg.buckets[THROTTLE_OPS_TOTAL].burst_length = arg->iops_max_length;
1107
- }
1108
- if (arg->has_iops_rd_max_length) {
1109
- cfg.buckets[THROTTLE_OPS_READ].burst_length = arg->iops_rd_max_length;
1110
- }
1111
- if (arg->has_iops_wr_max_length) {
1112
- cfg.buckets[THROTTLE_OPS_WRITE].burst_length = arg->iops_wr_max_length;
1113
- }
1114
-
1115
- if (arg->has_iops_size) {
1116
- cfg.op_size = arg->iops_size;
1117
- }
1118
-
1119
- if (!throttle_is_valid(&cfg, errp)) {
1120
- goto out;
1121
- }
1122
-
1123
- if (throttle_enabled(&cfg)) {
1124
- /* Enable I/O limits if they're not enabled yet, otherwise
1125
- * just update the throttling group. */
1126
- if (!blk_get_public(blk)->throttle_group_member.throttle_state) {
1127
- blk_io_limits_enable(blk,
1128
- arg->has_group ? arg->group :
1129
- arg->has_device ? arg->device :
1130
- arg->id);
1131
- } else if (arg->has_group) {
1132
- blk_io_limits_update_group(blk, arg->group);
1133
- }
1134
- /* Set the new throttling configuration */
1135
- blk_set_io_limits(blk, &cfg);
1136
- } else if (blk_get_public(blk)->throttle_group_member.throttle_state) {
1137
- /* If all throttling settings are set to 0, disable I/O limits */
1138
- blk_io_limits_disable(blk);
1139
- }
1140
-
1141
-out:
1142
- aio_context_release(aio_context);
1143
-}
1144
-
1145
void qmp_block_dirty_bitmap_add(const char *node, const char *name,
1146
bool has_granularity, uint32_t granularity,
1147
bool has_persistent, bool persistent,
1148
@@ -XXX,XX +XXX,XX @@ void qmp_x_blockdev_set_iothread(const char *node_name, StrOrNull *iothread,
1149
aio_context_release(old_context);
1150
}
1151
1152
-void qmp_block_latency_histogram_set(
1153
- const char *id,
1154
- bool has_boundaries, uint64List *boundaries,
1155
- bool has_boundaries_read, uint64List *boundaries_read,
1156
- bool has_boundaries_write, uint64List *boundaries_write,
1157
- bool has_boundaries_flush, uint64List *boundaries_flush,
1158
- Error **errp)
1159
-{
1160
- BlockBackend *blk = qmp_get_blk(NULL, id, errp);
1161
- BlockAcctStats *stats;
1162
- int ret;
1163
-
1164
- if (!blk) {
1165
- return;
1166
- }
1167
-
1168
- stats = blk_get_stats(blk);
1169
-
1170
- if (!has_boundaries && !has_boundaries_read && !has_boundaries_write &&
1171
- !has_boundaries_flush)
1172
- {
1173
- block_latency_histograms_clear(stats);
1174
- return;
1175
- }
1176
-
1177
- if (has_boundaries || has_boundaries_read) {
1178
- ret = block_latency_histogram_set(
1179
- stats, BLOCK_ACCT_READ,
1180
- has_boundaries_read ? boundaries_read : boundaries);
1181
- if (ret) {
1182
- error_setg(errp, "Device '%s' set read boundaries fail", id);
1183
- return;
1184
- }
1185
- }
1186
-
1187
- if (has_boundaries || has_boundaries_write) {
1188
- ret = block_latency_histogram_set(
1189
- stats, BLOCK_ACCT_WRITE,
1190
- has_boundaries_write ? boundaries_write : boundaries);
1191
- if (ret) {
1192
- error_setg(errp, "Device '%s' set write boundaries fail", id);
1193
- return;
1194
- }
1195
- }
1196
-
1197
- if (has_boundaries || has_boundaries_flush) {
1198
- ret = block_latency_histogram_set(
1199
- stats, BLOCK_ACCT_FLUSH,
1200
- has_boundaries_flush ? boundaries_flush : boundaries);
1201
- if (ret) {
1202
- error_setg(errp, "Device '%s' set flush boundaries fail", id);
1203
- return;
1204
- }
1205
- }
1206
-}
1207
-
1208
QemuOptsList qemu_common_drive_opts = {
1209
.name = "drive",
1210
.head = QTAILQ_HEAD_INITIALIZER(qemu_common_drive_opts.head),
1211
diff --git a/block/Makefile.objs b/block/Makefile.objs
1212
index XXXXXXX..XXXXXXX 100644
1213
--- a/block/Makefile.objs
1214
+++ b/block/Makefile.objs
1215
@@ -XXX,XX +XXX,XX @@ block-obj-y += filter-compress.o
1216
1217
common-obj-y += stream.o
1218
1219
+common-obj-y += qapi-sysemu.o
1220
+
1221
nfs.o-libs := $(LIBNFS_LIBS)
1222
iscsi.o-cflags := $(LIBISCSI_CFLAGS)
1223
iscsi.o-libs := $(LIBISCSI_LIBS)
27
--
1224
--
28
2.19.1
1225
2.20.1
29
1226
30
1227
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
block-core is for everything that isn't related to the system emulator.
2
Internal snapshots, the NBD server and quorum events make sense in the
3
tools, too, so move them to block-core.
2
4
3
Just like in qemu_opts_print_help(), print the object name as a caption
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
instead of on every single line, indent all options, add angle brackets
6
Message-Id: <20200224143008.13362-5-kwolf@redhat.com>
5
around types, and align the descriptions after 24 characters.
7
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
6
7
Also, indent every object name in the list of available objects.
8
9
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>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
9
---
13
vl.c | 13 ++++++++++---
10
qapi/block-core.json | 283 ++++++++++++++++++++++++++++++++++++++++++
14
1 file changed, 10 insertions(+), 3 deletions(-)
11
qapi/block.json | 284 -------------------------------------------
12
2 files changed, 283 insertions(+), 284 deletions(-)
15
13
16
diff --git a/vl.c b/vl.c
14
diff --git a/qapi/block-core.json b/qapi/block-core.json
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/vl.c
16
--- a/qapi/block-core.json
19
+++ b/vl.c
17
+++ b/qapi/block-core.json
20
@@ -XXX,XX +XXX,XX @@ static bool object_create_initial(const char *type, QemuOpts *opts)
18
@@ -XXX,XX +XXX,XX @@
21
list = object_class_get_list_sorted(TYPE_USER_CREATABLE, false);
19
'data' : { 'node-name': 'str',
22
for (l = list; l != NULL; l = l->next) {
20
'iothread': 'StrOrNull',
23
ObjectClass *oc = OBJECT_CLASS(l->data);
21
'*force': 'bool' } }
24
- printf("%s\n", object_class_get_name(oc));
22
+
25
+ printf(" %s\n", object_class_get_name(oc));
23
+##
26
}
24
+# @nbd-server-start:
27
g_slist_free(list);
25
+#
28
exit(0);
26
+# Start an NBD server listening on the given host and port. Block
29
@@ -XXX,XX +XXX,XX @@ static bool object_create_initial(const char *type, QemuOpts *opts)
27
+# devices can then be exported using @nbd-server-add. The NBD
30
}
28
+# server will present them as named exports; for example, another
31
29
+# QEMU instance could refer to them as "nbd:HOST:PORT:exportname=NAME".
32
str = g_string_new(NULL);
30
+#
33
- g_string_append_printf(str, "%s.%s=%s", type,
31
+# @addr: Address on which to listen.
34
- prop->name, prop->type);
32
+# @tls-creds: ID of the TLS credentials object (since 2.6).
35
+ g_string_append_printf(str, " %s=<%s>", prop->name, prop->type);
33
+# @tls-authz: ID of the QAuthZ authorization object used to validate
36
if (prop->description) {
34
+# the client's x509 distinguished name. This object is
37
+ if (str->len < 24) {
35
+# is only resolved at time of use, so can be deleted and
38
+ g_string_append_printf(str, "%*s", 24 - (int)str->len, "");
36
+# recreated on the fly while the NBD server is active.
39
+ }
37
+# If missing, it will default to denying access (since 4.0).
40
g_string_append_printf(str, " - %s", prop->description);
38
+#
41
}
39
+# Returns: error if the server is already running.
42
g_ptr_array_add(array, g_string_free(str, false));
40
+#
43
}
41
+# Since: 1.3.0
44
g_ptr_array_sort(array, (GCompareFunc)qemu_pstrcmp0);
42
+##
45
+ if (array->len > 0) {
43
+{ 'command': 'nbd-server-start',
46
+ printf("%s options:\n", type);
44
+ 'data': { 'addr': 'SocketAddressLegacy',
47
+ } else {
45
+ '*tls-creds': 'str',
48
+ printf("There are no options for %s.\n", type);
46
+ '*tls-authz': 'str'} }
49
+ }
47
+
50
for (i = 0; i < array->len; i++) {
48
+##
51
printf("%s\n", (char *)array->pdata[i]);
49
+# @nbd-server-add:
52
}
50
+#
51
+# Export a block node to QEMU's embedded NBD server.
52
+#
53
+# @device: The device name or node name of the node to be exported
54
+#
55
+# @name: Export name. If unspecified, the @device parameter is used as the
56
+# export name. (Since 2.12)
57
+#
58
+# @description: Free-form description of the export, up to 4096 bytes.
59
+# (Since 5.0)
60
+#
61
+# @writable: Whether clients should be able to write to the device via the
62
+# NBD connection (default false).
63
+#
64
+# @bitmap: Also export the dirty bitmap reachable from @device, so the
65
+# NBD client can use NBD_OPT_SET_META_CONTEXT with
66
+# "qemu:dirty-bitmap:NAME" to inspect the bitmap. (since 4.0)
67
+#
68
+# Returns: error if the server is not running, or export with the same name
69
+# already exists.
70
+#
71
+# Since: 1.3.0
72
+##
73
+{ 'command': 'nbd-server-add',
74
+ 'data': {'device': 'str', '*name': 'str', '*description': 'str',
75
+ '*writable': 'bool', '*bitmap': 'str' } }
76
+
77
+##
78
+# @NbdServerRemoveMode:
79
+#
80
+# Mode for removing an NBD export.
81
+#
82
+# @safe: Remove export if there are no existing connections, fail otherwise.
83
+#
84
+# @hard: Drop all connections immediately and remove export.
85
+#
86
+# Potential additional modes to be added in the future:
87
+#
88
+# hide: Just hide export from new clients, leave existing connections as is.
89
+# Remove export after all clients are disconnected.
90
+#
91
+# soft: Hide export from new clients, answer with ESHUTDOWN for all further
92
+# requests from existing clients.
93
+#
94
+# Since: 2.12
95
+##
96
+{'enum': 'NbdServerRemoveMode', 'data': ['safe', 'hard']}
97
+
98
+##
99
+# @nbd-server-remove:
100
+#
101
+# Remove NBD export by name.
102
+#
103
+# @name: Export name.
104
+#
105
+# @mode: Mode of command operation. See @NbdServerRemoveMode description.
106
+# Default is 'safe'.
107
+#
108
+# Returns: error if
109
+# - the server is not running
110
+# - export is not found
111
+# - mode is 'safe' and there are existing connections
112
+#
113
+# Since: 2.12
114
+##
115
+{ 'command': 'nbd-server-remove',
116
+ 'data': {'name': 'str', '*mode': 'NbdServerRemoveMode'} }
117
+
118
+##
119
+# @nbd-server-stop:
120
+#
121
+# Stop QEMU's embedded NBD server, and unregister all devices previously
122
+# added via @nbd-server-add.
123
+#
124
+# Since: 1.3.0
125
+##
126
+{ 'command': 'nbd-server-stop' }
127
+
128
+##
129
+# @QuorumOpType:
130
+#
131
+# An enumeration of the quorum operation types
132
+#
133
+# @read: read operation
134
+#
135
+# @write: write operation
136
+#
137
+# @flush: flush operation
138
+#
139
+# Since: 2.6
140
+##
141
+{ 'enum': 'QuorumOpType',
142
+ 'data': [ 'read', 'write', 'flush' ] }
143
+
144
+##
145
+# @QUORUM_FAILURE:
146
+#
147
+# Emitted by the Quorum block driver if it fails to establish a quorum
148
+#
149
+# @reference: device name if defined else node name
150
+#
151
+# @sector-num: number of the first sector of the failed read operation
152
+#
153
+# @sectors-count: failed read operation sector count
154
+#
155
+# Note: This event is rate-limited.
156
+#
157
+# Since: 2.0
158
+#
159
+# Example:
160
+#
161
+# <- { "event": "QUORUM_FAILURE",
162
+# "data": { "reference": "usr1", "sector-num": 345435, "sectors-count": 5 },
163
+# "timestamp": { "seconds": 1344522075, "microseconds": 745528 } }
164
+#
165
+##
166
+{ 'event': 'QUORUM_FAILURE',
167
+ 'data': { 'reference': 'str', 'sector-num': 'int', 'sectors-count': 'int' } }
168
+
169
+##
170
+# @QUORUM_REPORT_BAD:
171
+#
172
+# Emitted to report a corruption of a Quorum file
173
+#
174
+# @type: quorum operation type (Since 2.6)
175
+#
176
+# @error: error message. Only present on failure. This field
177
+# contains a human-readable error message. There are no semantics other
178
+# than that the block layer reported an error and clients should not
179
+# try to interpret the error string.
180
+#
181
+# @node-name: the graph node name of the block driver state
182
+#
183
+# @sector-num: number of the first sector of the failed read operation
184
+#
185
+# @sectors-count: failed read operation sector count
186
+#
187
+# Note: This event is rate-limited.
188
+#
189
+# Since: 2.0
190
+#
191
+# Example:
192
+#
193
+# 1. Read operation
194
+#
195
+# { "event": "QUORUM_REPORT_BAD",
196
+# "data": { "node-name": "node0", "sector-num": 345435, "sectors-count": 5,
197
+# "type": "read" },
198
+# "timestamp": { "seconds": 1344522075, "microseconds": 745528 } }
199
+#
200
+# 2. Flush operation
201
+#
202
+# { "event": "QUORUM_REPORT_BAD",
203
+# "data": { "node-name": "node0", "sector-num": 0, "sectors-count": 2097120,
204
+# "type": "flush", "error": "Broken pipe" },
205
+# "timestamp": { "seconds": 1456406829, "microseconds": 291763 } }
206
+#
207
+##
208
+{ 'event': 'QUORUM_REPORT_BAD',
209
+ 'data': { 'type': 'QuorumOpType', '*error': 'str', 'node-name': 'str',
210
+ 'sector-num': 'int', 'sectors-count': 'int' } }
211
+
212
+##
213
+# @BlockdevSnapshotInternal:
214
+#
215
+# @device: the device name or node-name of a root node to generate the snapshot
216
+# from
217
+#
218
+# @name: the name of the internal snapshot to be created
219
+#
220
+# Notes: In transaction, if @name is empty, or any snapshot matching @name
221
+# exists, the operation will fail. Only some image formats support it,
222
+# for example, qcow2, rbd, and sheepdog.
223
+#
224
+# Since: 1.7
225
+##
226
+{ 'struct': 'BlockdevSnapshotInternal',
227
+ 'data': { 'device': 'str', 'name': 'str' } }
228
+
229
+##
230
+# @blockdev-snapshot-internal-sync:
231
+#
232
+# Synchronously take an internal snapshot of a block device, when the
233
+# format of the image used supports it. If the name is an empty
234
+# string, or a snapshot with name already exists, the operation will
235
+# fail.
236
+#
237
+# For the arguments, see the documentation of BlockdevSnapshotInternal.
238
+#
239
+# Returns: - nothing on success
240
+# - If @device is not a valid block device, GenericError
241
+# - If any snapshot matching @name exists, or @name is empty,
242
+# GenericError
243
+# - If the format of the image used does not support it,
244
+# BlockFormatFeatureNotSupported
245
+#
246
+# Since: 1.7
247
+#
248
+# Example:
249
+#
250
+# -> { "execute": "blockdev-snapshot-internal-sync",
251
+# "arguments": { "device": "ide-hd0",
252
+# "name": "snapshot0" }
253
+# }
254
+# <- { "return": {} }
255
+#
256
+##
257
+{ 'command': 'blockdev-snapshot-internal-sync',
258
+ 'data': 'BlockdevSnapshotInternal' }
259
+
260
+##
261
+# @blockdev-snapshot-delete-internal-sync:
262
+#
263
+# Synchronously delete an internal snapshot of a block device, when the format
264
+# of the image used support it. The snapshot is identified by name or id or
265
+# both. One of the name or id is required. Return SnapshotInfo for the
266
+# successfully deleted snapshot.
267
+#
268
+# @device: the device name or node-name of a root node to delete the snapshot
269
+# from
270
+#
271
+# @id: optional the snapshot's ID to be deleted
272
+#
273
+# @name: optional the snapshot's name to be deleted
274
+#
275
+# Returns: - SnapshotInfo on success
276
+# - If @device is not a valid block device, GenericError
277
+# - If snapshot not found, GenericError
278
+# - If the format of the image used does not support it,
279
+# BlockFormatFeatureNotSupported
280
+# - If @id and @name are both not specified, GenericError
281
+#
282
+# Since: 1.7
283
+#
284
+# Example:
285
+#
286
+# -> { "execute": "blockdev-snapshot-delete-internal-sync",
287
+# "arguments": { "device": "ide-hd0",
288
+# "name": "snapshot0" }
289
+# }
290
+# <- { "return": {
291
+# "id": "1",
292
+# "name": "snapshot0",
293
+# "vm-state-size": 0,
294
+# "date-sec": 1000012,
295
+# "date-nsec": 10,
296
+# "vm-clock-sec": 100,
297
+# "vm-clock-nsec": 20
298
+# }
299
+# }
300
+#
301
+##
302
+{ 'command': 'blockdev-snapshot-delete-internal-sync',
303
+ 'data': { 'device': 'str', '*id': 'str', '*name': 'str'},
304
+ 'returns': 'SnapshotInfo' }
305
diff --git a/qapi/block.json b/qapi/block.json
306
index XXXXXXX..XXXXXXX 100644
307
--- a/qapi/block.json
308
+++ b/qapi/block.json
309
@@ -XXX,XX +XXX,XX @@
310
{ 'enum': 'FloppyDriveType',
311
'data': ['144', '288', '120', 'none', 'auto']}
312
313
-##
314
-# @BlockdevSnapshotInternal:
315
-#
316
-# @device: the device name or node-name of a root node to generate the snapshot
317
-# from
318
-#
319
-# @name: the name of the internal snapshot to be created
320
-#
321
-# Notes: In transaction, if @name is empty, or any snapshot matching @name
322
-# exists, the operation will fail. Only some image formats support it,
323
-# for example, qcow2, rbd, and sheepdog.
324
-#
325
-# Since: 1.7
326
-##
327
-{ 'struct': 'BlockdevSnapshotInternal',
328
- 'data': { 'device': 'str', 'name': 'str' } }
329
-
330
##
331
# @PRManagerInfo:
332
#
333
@@ -XXX,XX +XXX,XX @@
334
{ 'command': 'query-pr-managers', 'returns': ['PRManagerInfo'],
335
'allow-preconfig': true }
336
337
-
338
-##
339
-# @blockdev-snapshot-internal-sync:
340
-#
341
-# Synchronously take an internal snapshot of a block device, when the
342
-# format of the image used supports it. If the name is an empty
343
-# string, or a snapshot with name already exists, the operation will
344
-# fail.
345
-#
346
-# For the arguments, see the documentation of BlockdevSnapshotInternal.
347
-#
348
-# Returns: - nothing on success
349
-# - If @device is not a valid block device, GenericError
350
-# - If any snapshot matching @name exists, or @name is empty,
351
-# GenericError
352
-# - If the format of the image used does not support it,
353
-# BlockFormatFeatureNotSupported
354
-#
355
-# Since: 1.7
356
-#
357
-# Example:
358
-#
359
-# -> { "execute": "blockdev-snapshot-internal-sync",
360
-# "arguments": { "device": "ide-hd0",
361
-# "name": "snapshot0" }
362
-# }
363
-# <- { "return": {} }
364
-#
365
-##
366
-{ 'command': 'blockdev-snapshot-internal-sync',
367
- 'data': 'BlockdevSnapshotInternal' }
368
-
369
-##
370
-# @blockdev-snapshot-delete-internal-sync:
371
-#
372
-# Synchronously delete an internal snapshot of a block device, when the format
373
-# of the image used support it. The snapshot is identified by name or id or
374
-# both. One of the name or id is required. Return SnapshotInfo for the
375
-# successfully deleted snapshot.
376
-#
377
-# @device: the device name or node-name of a root node to delete the snapshot
378
-# from
379
-#
380
-# @id: optional the snapshot's ID to be deleted
381
-#
382
-# @name: optional the snapshot's name to be deleted
383
-#
384
-# Returns: - SnapshotInfo on success
385
-# - If @device is not a valid block device, GenericError
386
-# - If snapshot not found, GenericError
387
-# - If the format of the image used does not support it,
388
-# BlockFormatFeatureNotSupported
389
-# - If @id and @name are both not specified, GenericError
390
-#
391
-# Since: 1.7
392
-#
393
-# Example:
394
-#
395
-# -> { "execute": "blockdev-snapshot-delete-internal-sync",
396
-# "arguments": { "device": "ide-hd0",
397
-# "name": "snapshot0" }
398
-# }
399
-# <- { "return": {
400
-# "id": "1",
401
-# "name": "snapshot0",
402
-# "vm-state-size": 0,
403
-# "date-sec": 1000012,
404
-# "date-nsec": 10,
405
-# "vm-clock-sec": 100,
406
-# "vm-clock-nsec": 20
407
-# }
408
-# }
409
-#
410
-##
411
-{ 'command': 'blockdev-snapshot-delete-internal-sync',
412
- 'data': { 'device': 'str', '*id': 'str', '*name': 'str'},
413
- 'returns': 'SnapshotInfo' }
414
-
415
##
416
# @eject:
417
#
418
@@ -XXX,XX +XXX,XX @@
419
'*id': 'str',
420
'*force': 'bool' } }
421
422
-##
423
-# @nbd-server-start:
424
-#
425
-# Start an NBD server listening on the given host and port. Block
426
-# devices can then be exported using @nbd-server-add. The NBD
427
-# server will present them as named exports; for example, another
428
-# QEMU instance could refer to them as "nbd:HOST:PORT:exportname=NAME".
429
-#
430
-# @addr: Address on which to listen.
431
-# @tls-creds: ID of the TLS credentials object (since 2.6).
432
-# @tls-authz: ID of the QAuthZ authorization object used to validate
433
-# the client's x509 distinguished name. This object is
434
-# is only resolved at time of use, so can be deleted and
435
-# recreated on the fly while the NBD server is active.
436
-# If missing, it will default to denying access (since 4.0).
437
-#
438
-# Returns: error if the server is already running.
439
-#
440
-# Since: 1.3.0
441
-##
442
-{ 'command': 'nbd-server-start',
443
- 'data': { 'addr': 'SocketAddressLegacy',
444
- '*tls-creds': 'str',
445
- '*tls-authz': 'str'} }
446
-
447
-##
448
-# @nbd-server-add:
449
-#
450
-# Export a block node to QEMU's embedded NBD server.
451
-#
452
-# @device: The device name or node name of the node to be exported
453
-#
454
-# @name: Export name. If unspecified, the @device parameter is used as the
455
-# export name. (Since 2.12)
456
-#
457
-# @description: Free-form description of the export, up to 4096 bytes.
458
-# (Since 5.0)
459
-#
460
-# @writable: Whether clients should be able to write to the device via the
461
-# NBD connection (default false).
462
-#
463
-# @bitmap: Also export the dirty bitmap reachable from @device, so the
464
-# NBD client can use NBD_OPT_SET_META_CONTEXT with
465
-# "qemu:dirty-bitmap:NAME" to inspect the bitmap. (since 4.0)
466
-#
467
-# Returns: error if the server is not running, or export with the same name
468
-# already exists.
469
-#
470
-# Since: 1.3.0
471
-##
472
-{ 'command': 'nbd-server-add',
473
- 'data': {'device': 'str', '*name': 'str', '*description': 'str',
474
- '*writable': 'bool', '*bitmap': 'str' } }
475
-
476
-##
477
-# @NbdServerRemoveMode:
478
-#
479
-# Mode for removing an NBD export.
480
-#
481
-# @safe: Remove export if there are no existing connections, fail otherwise.
482
-#
483
-# @hard: Drop all connections immediately and remove export.
484
-#
485
-# Potential additional modes to be added in the future:
486
-#
487
-# hide: Just hide export from new clients, leave existing connections as is.
488
-# Remove export after all clients are disconnected.
489
-#
490
-# soft: Hide export from new clients, answer with ESHUTDOWN for all further
491
-# requests from existing clients.
492
-#
493
-# Since: 2.12
494
-##
495
-{'enum': 'NbdServerRemoveMode', 'data': ['safe', 'hard']}
496
-
497
-##
498
-# @nbd-server-remove:
499
-#
500
-# Remove NBD export by name.
501
-#
502
-# @name: Export name.
503
-#
504
-# @mode: Mode of command operation. See @NbdServerRemoveMode description.
505
-# Default is 'safe'.
506
-#
507
-# Returns: error if
508
-# - the server is not running
509
-# - export is not found
510
-# - mode is 'safe' and there are existing connections
511
-#
512
-# Since: 2.12
513
-##
514
-{ 'command': 'nbd-server-remove',
515
- 'data': {'name': 'str', '*mode': 'NbdServerRemoveMode'} }
516
-
517
-##
518
-# @nbd-server-stop:
519
-#
520
-# Stop QEMU's embedded NBD server, and unregister all devices previously
521
-# added via @nbd-server-add.
522
-#
523
-# Since: 1.3.0
524
-##
525
-{ 'command': 'nbd-server-stop' }
526
-
527
##
528
# @DEVICE_TRAY_MOVED:
529
#
530
@@ -XXX,XX +XXX,XX @@
531
##
532
{ 'event': 'PR_MANAGER_STATUS_CHANGED',
533
'data': { 'id': 'str', 'connected': 'bool' } }
534
-
535
-##
536
-# @QuorumOpType:
537
-#
538
-# An enumeration of the quorum operation types
539
-#
540
-# @read: read operation
541
-#
542
-# @write: write operation
543
-#
544
-# @flush: flush operation
545
-#
546
-# Since: 2.6
547
-##
548
-{ 'enum': 'QuorumOpType',
549
- 'data': [ 'read', 'write', 'flush' ] }
550
-
551
-##
552
-# @QUORUM_FAILURE:
553
-#
554
-# Emitted by the Quorum block driver if it fails to establish a quorum
555
-#
556
-# @reference: device name if defined else node name
557
-#
558
-# @sector-num: number of the first sector of the failed read operation
559
-#
560
-# @sectors-count: failed read operation sector count
561
-#
562
-# Note: This event is rate-limited.
563
-#
564
-# Since: 2.0
565
-#
566
-# Example:
567
-#
568
-# <- { "event": "QUORUM_FAILURE",
569
-# "data": { "reference": "usr1", "sector-num": 345435, "sectors-count": 5 },
570
-# "timestamp": { "seconds": 1344522075, "microseconds": 745528 } }
571
-#
572
-##
573
-{ 'event': 'QUORUM_FAILURE',
574
- 'data': { 'reference': 'str', 'sector-num': 'int', 'sectors-count': 'int' } }
575
-
576
-##
577
-# @QUORUM_REPORT_BAD:
578
-#
579
-# Emitted to report a corruption of a Quorum file
580
-#
581
-# @type: quorum operation type (Since 2.6)
582
-#
583
-# @error: error message. Only present on failure. This field
584
-# contains a human-readable error message. There are no semantics other
585
-# than that the block layer reported an error and clients should not
586
-# try to interpret the error string.
587
-#
588
-# @node-name: the graph node name of the block driver state
589
-#
590
-# @sector-num: number of the first sector of the failed read operation
591
-#
592
-# @sectors-count: failed read operation sector count
593
-#
594
-# Note: This event is rate-limited.
595
-#
596
-# Since: 2.0
597
-#
598
-# Example:
599
-#
600
-# 1. Read operation
601
-#
602
-# { "event": "QUORUM_REPORT_BAD",
603
-# "data": { "node-name": "node0", "sector-num": 345435, "sectors-count": 5,
604
-# "type": "read" },
605
-# "timestamp": { "seconds": 1344522075, "microseconds": 745528 } }
606
-#
607
-# 2. Flush operation
608
-#
609
-# { "event": "QUORUM_REPORT_BAD",
610
-# "data": { "node-name": "node0", "sector-num": 0, "sectors-count": 2097120,
611
-# "type": "flush", "error": "Broken pipe" },
612
-# "timestamp": { "seconds": 1456406829, "microseconds": 291763 } }
613
-#
614
-##
615
-{ 'event': 'QUORUM_REPORT_BAD',
616
- 'data': { 'type': 'QuorumOpType', '*error': 'str', 'node-name': 'str',
617
- 'sector-num': 'int', 'sectors-count': 'int' } }
53
--
618
--
54
2.19.1
619
2.20.1
55
620
56
621
diff view generated by jsdifflib
1
From: Peter Maydell <peter.maydell@linaro.org>
1
QMP commands that are related to the system emulator and don't make
2
sense in the context of tools such as qemu-storage-daemon should live in
3
qapi/block.json rather than qapi/block-core.json. Move them there.
2
4
3
Taking the address of a field in a packed struct is a bad idea, because
5
The associated data types are actually also used in code shared with the
4
it might not be actually aligned enough for that pointer type (and
6
tools, so they stay in block-core.json.
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
7
9
There are a few places where the in-place swap function is
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
used on something other than a packed struct field; we convert
9
Message-Id: <20200224143008.13362-6-kwolf@redhat.com>
11
those anyway, for consistency.
10
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
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>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
51
---
12
---
52
block/qcow.c | 18 +++++++++---------
13
qapi/block-core.json | 386 -------------------------------------------
53
1 file changed, 9 insertions(+), 9 deletions(-)
14
qapi/block.json | 386 +++++++++++++++++++++++++++++++++++++++++++
15
monitor/qmp-cmds.c | 2 +-
16
3 files changed, 387 insertions(+), 387 deletions(-)
54
17
55
diff --git a/block/qcow.c b/block/qcow.c
18
diff --git a/qapi/block-core.json b/qapi/block-core.json
56
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
57
--- a/block/qcow.c
20
--- a/qapi/block-core.json
58
+++ b/block/qcow.c
21
+++ b/qapi/block-core.json
59
@@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
22
@@ -XXX,XX +XXX,XX @@
60
if (ret < 0) {
23
{ 'struct': 'BlockLatencyHistogramInfo',
61
goto fail;
24
'data': {'boundaries': ['uint64'], 'bins': ['uint64'] } }
62
}
25
63
- be32_to_cpus(&header.magic);
26
-##
64
- be32_to_cpus(&header.version);
27
-# @block-latency-histogram-set:
65
- be64_to_cpus(&header.backing_file_offset);
28
-#
66
- be32_to_cpus(&header.backing_file_size);
29
-# Manage read, write and flush latency histograms for the device.
67
- be32_to_cpus(&header.mtime);
30
-#
68
- be64_to_cpus(&header.size);
31
-# If only @id parameter is specified, remove all present latency histograms
69
- be32_to_cpus(&header.crypt_method);
32
-# for the device. Otherwise, add/reset some of (or all) latency histograms.
70
- be64_to_cpus(&header.l1_table_offset);
33
-#
71
+ header.magic = be32_to_cpu(header.magic);
34
-# @id: The name or QOM path of the guest device.
72
+ header.version = be32_to_cpu(header.version);
35
-#
73
+ header.backing_file_offset = be64_to_cpu(header.backing_file_offset);
36
-# @boundaries: list of interval boundary values (see description in
74
+ header.backing_file_size = be32_to_cpu(header.backing_file_size);
37
-# BlockLatencyHistogramInfo definition). If specified, all
75
+ header.mtime = be32_to_cpu(header.mtime);
38
-# latency histograms are removed, and empty ones created for all
76
+ header.size = be64_to_cpu(header.size);
39
-# io types with intervals corresponding to @boundaries (except for
77
+ header.crypt_method = be32_to_cpu(header.crypt_method);
40
-# io types, for which specific boundaries are set through the
78
+ header.l1_table_offset = be64_to_cpu(header.l1_table_offset);
41
-# following parameters).
79
42
-#
80
if (header.magic != QCOW_MAGIC) {
43
-# @boundaries-read: list of interval boundary values for read latency
81
error_setg(errp, "Image not in qcow format");
44
-# histogram. If specified, old read latency histogram is
82
@@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
45
-# removed, and empty one created with intervals
83
}
46
-# corresponding to @boundaries-read. The parameter has higher
84
47
-# priority then @boundaries.
85
for(i = 0;i < s->l1_size; i++) {
48
-#
86
- be64_to_cpus(&s->l1_table[i]);
49
-# @boundaries-write: list of interval boundary values for write latency
87
+ s->l1_table[i] = be64_to_cpu(s->l1_table[i]);
50
-# histogram.
88
}
51
-#
89
52
-# @boundaries-flush: list of interval boundary values for flush latency
90
/* alloc L2 cache (max. 64k * 16 * 8 = 8 MB) */
53
-# histogram.
54
-#
55
-# Returns: error if device is not found or any boundary arrays are invalid.
56
-#
57
-# Since: 4.0
58
-#
59
-# Example: set new histograms for all io types with intervals
60
-# [0, 10), [10, 50), [50, 100), [100, +inf):
61
-#
62
-# -> { "execute": "block-latency-histogram-set",
63
-# "arguments": { "id": "drive0",
64
-# "boundaries": [10, 50, 100] } }
65
-# <- { "return": {} }
66
-#
67
-# Example: set new histogram only for write, other histograms will remain
68
-# not changed (or not created):
69
-#
70
-# -> { "execute": "block-latency-histogram-set",
71
-# "arguments": { "id": "drive0",
72
-# "boundaries-write": [10, 50, 100] } }
73
-# <- { "return": {} }
74
-#
75
-# Example: set new histograms with the following intervals:
76
-# read, flush: [0, 10), [10, 50), [50, 100), [100, +inf)
77
-# write: [0, 1000), [1000, 5000), [5000, +inf)
78
-#
79
-# -> { "execute": "block-latency-histogram-set",
80
-# "arguments": { "id": "drive0",
81
-# "boundaries": [10, 50, 100],
82
-# "boundaries-write": [1000, 5000] } }
83
-# <- { "return": {} }
84
-#
85
-# Example: remove all latency histograms:
86
-#
87
-# -> { "execute": "block-latency-histogram-set",
88
-# "arguments": { "id": "drive0" } }
89
-# <- { "return": {} }
90
-##
91
-{ 'command': 'block-latency-histogram-set',
92
- 'data': {'id': 'str',
93
- '*boundaries': ['uint64'],
94
- '*boundaries-read': ['uint64'],
95
- '*boundaries-write': ['uint64'],
96
- '*boundaries-flush': ['uint64'] } }
97
-
98
##
99
# @BlockInfo:
100
#
101
@@ -XXX,XX +XXX,XX @@
102
'*copy-mode': 'MirrorCopyMode',
103
'*auto-finalize': 'bool', '*auto-dismiss': 'bool' } }
104
105
-##
106
-# @block_set_io_throttle:
107
-#
108
-# Change I/O throttle limits for a block drive.
109
-#
110
-# Since QEMU 2.4, each device with I/O limits is member of a throttle
111
-# group.
112
-#
113
-# If two or more devices are members of the same group, the limits
114
-# will apply to the combined I/O of the whole group in a round-robin
115
-# fashion. Therefore, setting new I/O limits to a device will affect
116
-# the whole group.
117
-#
118
-# The name of the group can be specified using the 'group' parameter.
119
-# If the parameter is unset, it is assumed to be the current group of
120
-# that device. If it's not in any group yet, the name of the device
121
-# will be used as the name for its group.
122
-#
123
-# The 'group' parameter can also be used to move a device to a
124
-# different group. In this case the limits specified in the parameters
125
-# will be applied to the new group only.
126
-#
127
-# I/O limits can be disabled by setting all of them to 0. In this case
128
-# the device will be removed from its group and the rest of its
129
-# members will not be affected. The 'group' parameter is ignored.
130
-#
131
-# Returns: - Nothing on success
132
-# - If @device is not a valid block device, DeviceNotFound
133
-#
134
-# Since: 1.1
135
-#
136
-# Example:
137
-#
138
-# -> { "execute": "block_set_io_throttle",
139
-# "arguments": { "id": "virtio-blk-pci0/virtio-backend",
140
-# "bps": 0,
141
-# "bps_rd": 0,
142
-# "bps_wr": 0,
143
-# "iops": 512,
144
-# "iops_rd": 0,
145
-# "iops_wr": 0,
146
-# "bps_max": 0,
147
-# "bps_rd_max": 0,
148
-# "bps_wr_max": 0,
149
-# "iops_max": 0,
150
-# "iops_rd_max": 0,
151
-# "iops_wr_max": 0,
152
-# "bps_max_length": 0,
153
-# "iops_size": 0 } }
154
-# <- { "return": {} }
155
-#
156
-# -> { "execute": "block_set_io_throttle",
157
-# "arguments": { "id": "ide0-1-0",
158
-# "bps": 1000000,
159
-# "bps_rd": 0,
160
-# "bps_wr": 0,
161
-# "iops": 0,
162
-# "iops_rd": 0,
163
-# "iops_wr": 0,
164
-# "bps_max": 8000000,
165
-# "bps_rd_max": 0,
166
-# "bps_wr_max": 0,
167
-# "iops_max": 0,
168
-# "iops_rd_max": 0,
169
-# "iops_wr_max": 0,
170
-# "bps_max_length": 60,
171
-# "iops_size": 0 } }
172
-# <- { "return": {} }
173
-##
174
-{ 'command': 'block_set_io_throttle', 'boxed': true,
175
- 'data': 'BlockIOThrottle' }
176
-
177
##
178
# @BlockIOThrottle:
179
#
180
@@ -XXX,XX +XXX,XX @@
181
'data': { 'job-id': 'str',
182
'options': 'BlockdevCreateOptions' } }
183
184
-##
185
-# @blockdev-open-tray:
186
-#
187
-# Opens a block device's tray. If there is a block driver state tree inserted as
188
-# a medium, it will become inaccessible to the guest (but it will remain
189
-# associated to the block device, so closing the tray will make it accessible
190
-# again).
191
-#
192
-# If the tray was already open before, this will be a no-op.
193
-#
194
-# Once the tray opens, a DEVICE_TRAY_MOVED event is emitted. There are cases in
195
-# which no such event will be generated, these include:
196
-#
197
-# - if the guest has locked the tray, @force is false and the guest does not
198
-# respond to the eject request
199
-# - if the BlockBackend denoted by @device does not have a guest device attached
200
-# to it
201
-# - if the guest device does not have an actual tray
202
-#
203
-# @device: Block device name (deprecated, use @id instead)
204
-#
205
-# @id: The name or QOM path of the guest device (since: 2.8)
206
-#
207
-# @force: if false (the default), an eject request will be sent to
208
-# the guest if it has locked the tray (and the tray will not be opened
209
-# immediately); if true, the tray will be opened regardless of whether
210
-# it is locked
211
-#
212
-# Since: 2.5
213
-#
214
-# Example:
215
-#
216
-# -> { "execute": "blockdev-open-tray",
217
-# "arguments": { "id": "ide0-1-0" } }
218
-#
219
-# <- { "timestamp": { "seconds": 1418751016,
220
-# "microseconds": 716996 },
221
-# "event": "DEVICE_TRAY_MOVED",
222
-# "data": { "device": "ide1-cd0",
223
-# "id": "ide0-1-0",
224
-# "tray-open": true } }
225
-#
226
-# <- { "return": {} }
227
-#
228
-##
229
-{ 'command': 'blockdev-open-tray',
230
- 'data': { '*device': 'str',
231
- '*id': 'str',
232
- '*force': 'bool' } }
233
-
234
-##
235
-# @blockdev-close-tray:
236
-#
237
-# Closes a block device's tray. If there is a block driver state tree associated
238
-# with the block device (which is currently ejected), that tree will be loaded
239
-# as the medium.
240
-#
241
-# If the tray was already closed before, this will be a no-op.
242
-#
243
-# @device: Block device name (deprecated, use @id instead)
244
-#
245
-# @id: The name or QOM path of the guest device (since: 2.8)
246
-#
247
-# Since: 2.5
248
-#
249
-# Example:
250
-#
251
-# -> { "execute": "blockdev-close-tray",
252
-# "arguments": { "id": "ide0-1-0" } }
253
-#
254
-# <- { "timestamp": { "seconds": 1418751345,
255
-# "microseconds": 272147 },
256
-# "event": "DEVICE_TRAY_MOVED",
257
-# "data": { "device": "ide1-cd0",
258
-# "id": "ide0-1-0",
259
-# "tray-open": false } }
260
-#
261
-# <- { "return": {} }
262
-#
263
-##
264
-{ 'command': 'blockdev-close-tray',
265
- 'data': { '*device': 'str',
266
- '*id': 'str' } }
267
-
268
-##
269
-# @blockdev-remove-medium:
270
-#
271
-# Removes a medium (a block driver state tree) from a block device. That block
272
-# device's tray must currently be open (unless there is no attached guest
273
-# device).
274
-#
275
-# If the tray is open and there is no medium inserted, this will be a no-op.
276
-#
277
-# @id: The name or QOM path of the guest device
278
-#
279
-# Since: 2.12
280
-#
281
-# Example:
282
-#
283
-# -> { "execute": "blockdev-remove-medium",
284
-# "arguments": { "id": "ide0-1-0" } }
285
-#
286
-# <- { "error": { "class": "GenericError",
287
-# "desc": "Tray of device 'ide0-1-0' is not open" } }
288
-#
289
-# -> { "execute": "blockdev-open-tray",
290
-# "arguments": { "id": "ide0-1-0" } }
291
-#
292
-# <- { "timestamp": { "seconds": 1418751627,
293
-# "microseconds": 549958 },
294
-# "event": "DEVICE_TRAY_MOVED",
295
-# "data": { "device": "ide1-cd0",
296
-# "id": "ide0-1-0",
297
-# "tray-open": true } }
298
-#
299
-# <- { "return": {} }
300
-#
301
-# -> { "execute": "blockdev-remove-medium",
302
-# "arguments": { "id": "ide0-1-0" } }
303
-#
304
-# <- { "return": {} }
305
-#
306
-##
307
-{ 'command': 'blockdev-remove-medium',
308
- 'data': { 'id': 'str' } }
309
-
310
-##
311
-# @blockdev-insert-medium:
312
-#
313
-# Inserts a medium (a block driver state tree) into a block device. That block
314
-# device's tray must currently be open (unless there is no attached guest
315
-# device) and there must be no medium inserted already.
316
-#
317
-# @id: The name or QOM path of the guest device
318
-#
319
-# @node-name: name of a node in the block driver state graph
320
-#
321
-# Since: 2.12
322
-#
323
-# Example:
324
-#
325
-# -> { "execute": "blockdev-add",
326
-# "arguments": {
327
-# "node-name": "node0",
328
-# "driver": "raw",
329
-# "file": { "driver": "file",
330
-# "filename": "fedora.iso" } } }
331
-# <- { "return": {} }
332
-#
333
-# -> { "execute": "blockdev-insert-medium",
334
-# "arguments": { "id": "ide0-1-0",
335
-# "node-name": "node0" } }
336
-#
337
-# <- { "return": {} }
338
-#
339
-##
340
-{ 'command': 'blockdev-insert-medium',
341
- 'data': { 'id': 'str',
342
- 'node-name': 'str'} }
343
-
344
-
345
-##
346
-# @BlockdevChangeReadOnlyMode:
347
-#
348
-# Specifies the new read-only mode of a block device subject to the
349
-# @blockdev-change-medium command.
350
-#
351
-# @retain: Retains the current read-only mode
352
-#
353
-# @read-only: Makes the device read-only
354
-#
355
-# @read-write: Makes the device writable
356
-#
357
-# Since: 2.3
358
-#
359
-##
360
-{ 'enum': 'BlockdevChangeReadOnlyMode',
361
- 'data': ['retain', 'read-only', 'read-write'] }
362
-
363
-
364
-##
365
-# @blockdev-change-medium:
366
-#
367
-# Changes the medium inserted into a block device by ejecting the current medium
368
-# and loading a new image file which is inserted as the new medium (this command
369
-# combines blockdev-open-tray, blockdev-remove-medium, blockdev-insert-medium
370
-# and blockdev-close-tray).
371
-#
372
-# @device: Block device name (deprecated, use @id instead)
373
-#
374
-# @id: The name or QOM path of the guest device
375
-# (since: 2.8)
376
-#
377
-# @filename: filename of the new image to be loaded
378
-#
379
-# @format: format to open the new image with (defaults to
380
-# the probed format)
381
-#
382
-# @read-only-mode: change the read-only mode of the device; defaults
383
-# to 'retain'
384
-#
385
-# Since: 2.5
386
-#
387
-# Examples:
388
-#
389
-# 1. Change a removable medium
390
-#
391
-# -> { "execute": "blockdev-change-medium",
392
-# "arguments": { "id": "ide0-1-0",
393
-# "filename": "/srv/images/Fedora-12-x86_64-DVD.iso",
394
-# "format": "raw" } }
395
-# <- { "return": {} }
396
-#
397
-# 2. Load a read-only medium into a writable drive
398
-#
399
-# -> { "execute": "blockdev-change-medium",
400
-# "arguments": { "id": "floppyA",
401
-# "filename": "/srv/images/ro.img",
402
-# "format": "raw",
403
-# "read-only-mode": "retain" } }
404
-#
405
-# <- { "error":
406
-# { "class": "GenericError",
407
-# "desc": "Could not open '/srv/images/ro.img': Permission denied" } }
408
-#
409
-# -> { "execute": "blockdev-change-medium",
410
-# "arguments": { "id": "floppyA",
411
-# "filename": "/srv/images/ro.img",
412
-# "format": "raw",
413
-# "read-only-mode": "read-only" } }
414
-#
415
-# <- { "return": {} }
416
-#
417
-##
418
-{ 'command': 'blockdev-change-medium',
419
- 'data': { '*device': 'str',
420
- '*id': 'str',
421
- 'filename': 'str',
422
- '*format': 'str',
423
- '*read-only-mode': 'BlockdevChangeReadOnlyMode' } }
424
-
425
-
426
##
427
# @BlockErrorAction:
428
#
429
diff --git a/qapi/block.json b/qapi/block.json
430
index XXXXXXX..XXXXXXX 100644
431
--- a/qapi/block.json
432
+++ b/qapi/block.json
433
@@ -XXX,XX +XXX,XX @@
434
'*id': 'str',
435
'*force': 'bool' } }
436
437
+##
438
+# @blockdev-open-tray:
439
+#
440
+# Opens a block device's tray. If there is a block driver state tree inserted as
441
+# a medium, it will become inaccessible to the guest (but it will remain
442
+# associated to the block device, so closing the tray will make it accessible
443
+# again).
444
+#
445
+# If the tray was already open before, this will be a no-op.
446
+#
447
+# Once the tray opens, a DEVICE_TRAY_MOVED event is emitted. There are cases in
448
+# which no such event will be generated, these include:
449
+#
450
+# - if the guest has locked the tray, @force is false and the guest does not
451
+# respond to the eject request
452
+# - if the BlockBackend denoted by @device does not have a guest device attached
453
+# to it
454
+# - if the guest device does not have an actual tray
455
+#
456
+# @device: Block device name (deprecated, use @id instead)
457
+#
458
+# @id: The name or QOM path of the guest device (since: 2.8)
459
+#
460
+# @force: if false (the default), an eject request will be sent to
461
+# the guest if it has locked the tray (and the tray will not be opened
462
+# immediately); if true, the tray will be opened regardless of whether
463
+# it is locked
464
+#
465
+# Since: 2.5
466
+#
467
+# Example:
468
+#
469
+# -> { "execute": "blockdev-open-tray",
470
+# "arguments": { "id": "ide0-1-0" } }
471
+#
472
+# <- { "timestamp": { "seconds": 1418751016,
473
+# "microseconds": 716996 },
474
+# "event": "DEVICE_TRAY_MOVED",
475
+# "data": { "device": "ide1-cd0",
476
+# "id": "ide0-1-0",
477
+# "tray-open": true } }
478
+#
479
+# <- { "return": {} }
480
+#
481
+##
482
+{ 'command': 'blockdev-open-tray',
483
+ 'data': { '*device': 'str',
484
+ '*id': 'str',
485
+ '*force': 'bool' } }
486
+
487
+##
488
+# @blockdev-close-tray:
489
+#
490
+# Closes a block device's tray. If there is a block driver state tree associated
491
+# with the block device (which is currently ejected), that tree will be loaded
492
+# as the medium.
493
+#
494
+# If the tray was already closed before, this will be a no-op.
495
+#
496
+# @device: Block device name (deprecated, use @id instead)
497
+#
498
+# @id: The name or QOM path of the guest device (since: 2.8)
499
+#
500
+# Since: 2.5
501
+#
502
+# Example:
503
+#
504
+# -> { "execute": "blockdev-close-tray",
505
+# "arguments": { "id": "ide0-1-0" } }
506
+#
507
+# <- { "timestamp": { "seconds": 1418751345,
508
+# "microseconds": 272147 },
509
+# "event": "DEVICE_TRAY_MOVED",
510
+# "data": { "device": "ide1-cd0",
511
+# "id": "ide0-1-0",
512
+# "tray-open": false } }
513
+#
514
+# <- { "return": {} }
515
+#
516
+##
517
+{ 'command': 'blockdev-close-tray',
518
+ 'data': { '*device': 'str',
519
+ '*id': 'str' } }
520
+
521
+##
522
+# @blockdev-remove-medium:
523
+#
524
+# Removes a medium (a block driver state tree) from a block device. That block
525
+# device's tray must currently be open (unless there is no attached guest
526
+# device).
527
+#
528
+# If the tray is open and there is no medium inserted, this will be a no-op.
529
+#
530
+# @id: The name or QOM path of the guest device
531
+#
532
+# Since: 2.12
533
+#
534
+# Example:
535
+#
536
+# -> { "execute": "blockdev-remove-medium",
537
+# "arguments": { "id": "ide0-1-0" } }
538
+#
539
+# <- { "error": { "class": "GenericError",
540
+# "desc": "Tray of device 'ide0-1-0' is not open" } }
541
+#
542
+# -> { "execute": "blockdev-open-tray",
543
+# "arguments": { "id": "ide0-1-0" } }
544
+#
545
+# <- { "timestamp": { "seconds": 1418751627,
546
+# "microseconds": 549958 },
547
+# "event": "DEVICE_TRAY_MOVED",
548
+# "data": { "device": "ide1-cd0",
549
+# "id": "ide0-1-0",
550
+# "tray-open": true } }
551
+#
552
+# <- { "return": {} }
553
+#
554
+# -> { "execute": "blockdev-remove-medium",
555
+# "arguments": { "id": "ide0-1-0" } }
556
+#
557
+# <- { "return": {} }
558
+#
559
+##
560
+{ 'command': 'blockdev-remove-medium',
561
+ 'data': { 'id': 'str' } }
562
+
563
+##
564
+# @blockdev-insert-medium:
565
+#
566
+# Inserts a medium (a block driver state tree) into a block device. That block
567
+# device's tray must currently be open (unless there is no attached guest
568
+# device) and there must be no medium inserted already.
569
+#
570
+# @id: The name or QOM path of the guest device
571
+#
572
+# @node-name: name of a node in the block driver state graph
573
+#
574
+# Since: 2.12
575
+#
576
+# Example:
577
+#
578
+# -> { "execute": "blockdev-add",
579
+# "arguments": {
580
+# "node-name": "node0",
581
+# "driver": "raw",
582
+# "file": { "driver": "file",
583
+# "filename": "fedora.iso" } } }
584
+# <- { "return": {} }
585
+#
586
+# -> { "execute": "blockdev-insert-medium",
587
+# "arguments": { "id": "ide0-1-0",
588
+# "node-name": "node0" } }
589
+#
590
+# <- { "return": {} }
591
+#
592
+##
593
+{ 'command': 'blockdev-insert-medium',
594
+ 'data': { 'id': 'str',
595
+ 'node-name': 'str'} }
596
+
597
+
598
+##
599
+# @BlockdevChangeReadOnlyMode:
600
+#
601
+# Specifies the new read-only mode of a block device subject to the
602
+# @blockdev-change-medium command.
603
+#
604
+# @retain: Retains the current read-only mode
605
+#
606
+# @read-only: Makes the device read-only
607
+#
608
+# @read-write: Makes the device writable
609
+#
610
+# Since: 2.3
611
+#
612
+##
613
+{ 'enum': 'BlockdevChangeReadOnlyMode',
614
+ 'data': ['retain', 'read-only', 'read-write'] }
615
+
616
+
617
+##
618
+# @blockdev-change-medium:
619
+#
620
+# Changes the medium inserted into a block device by ejecting the current medium
621
+# and loading a new image file which is inserted as the new medium (this command
622
+# combines blockdev-open-tray, blockdev-remove-medium, blockdev-insert-medium
623
+# and blockdev-close-tray).
624
+#
625
+# @device: Block device name (deprecated, use @id instead)
626
+#
627
+# @id: The name or QOM path of the guest device
628
+# (since: 2.8)
629
+#
630
+# @filename: filename of the new image to be loaded
631
+#
632
+# @format: format to open the new image with (defaults to
633
+# the probed format)
634
+#
635
+# @read-only-mode: change the read-only mode of the device; defaults
636
+# to 'retain'
637
+#
638
+# Since: 2.5
639
+#
640
+# Examples:
641
+#
642
+# 1. Change a removable medium
643
+#
644
+# -> { "execute": "blockdev-change-medium",
645
+# "arguments": { "id": "ide0-1-0",
646
+# "filename": "/srv/images/Fedora-12-x86_64-DVD.iso",
647
+# "format": "raw" } }
648
+# <- { "return": {} }
649
+#
650
+# 2. Load a read-only medium into a writable drive
651
+#
652
+# -> { "execute": "blockdev-change-medium",
653
+# "arguments": { "id": "floppyA",
654
+# "filename": "/srv/images/ro.img",
655
+# "format": "raw",
656
+# "read-only-mode": "retain" } }
657
+#
658
+# <- { "error":
659
+# { "class": "GenericError",
660
+# "desc": "Could not open '/srv/images/ro.img': Permission denied" } }
661
+#
662
+# -> { "execute": "blockdev-change-medium",
663
+# "arguments": { "id": "floppyA",
664
+# "filename": "/srv/images/ro.img",
665
+# "format": "raw",
666
+# "read-only-mode": "read-only" } }
667
+#
668
+# <- { "return": {} }
669
+#
670
+##
671
+{ 'command': 'blockdev-change-medium',
672
+ 'data': { '*device': 'str',
673
+ '*id': 'str',
674
+ 'filename': 'str',
675
+ '*format': 'str',
676
+ '*read-only-mode': 'BlockdevChangeReadOnlyMode' } }
677
+
678
+
679
##
680
# @DEVICE_TRAY_MOVED:
681
#
682
@@ -XXX,XX +XXX,XX @@
683
##
684
{ 'event': 'PR_MANAGER_STATUS_CHANGED',
685
'data': { 'id': 'str', 'connected': 'bool' } }
686
+
687
+##
688
+# @block_set_io_throttle:
689
+#
690
+# Change I/O throttle limits for a block drive.
691
+#
692
+# Since QEMU 2.4, each device with I/O limits is member of a throttle
693
+# group.
694
+#
695
+# If two or more devices are members of the same group, the limits
696
+# will apply to the combined I/O of the whole group in a round-robin
697
+# fashion. Therefore, setting new I/O limits to a device will affect
698
+# the whole group.
699
+#
700
+# The name of the group can be specified using the 'group' parameter.
701
+# If the parameter is unset, it is assumed to be the current group of
702
+# that device. If it's not in any group yet, the name of the device
703
+# will be used as the name for its group.
704
+#
705
+# The 'group' parameter can also be used to move a device to a
706
+# different group. In this case the limits specified in the parameters
707
+# will be applied to the new group only.
708
+#
709
+# I/O limits can be disabled by setting all of them to 0. In this case
710
+# the device will be removed from its group and the rest of its
711
+# members will not be affected. The 'group' parameter is ignored.
712
+#
713
+# Returns: - Nothing on success
714
+# - If @device is not a valid block device, DeviceNotFound
715
+#
716
+# Since: 1.1
717
+#
718
+# Example:
719
+#
720
+# -> { "execute": "block_set_io_throttle",
721
+# "arguments": { "id": "virtio-blk-pci0/virtio-backend",
722
+# "bps": 0,
723
+# "bps_rd": 0,
724
+# "bps_wr": 0,
725
+# "iops": 512,
726
+# "iops_rd": 0,
727
+# "iops_wr": 0,
728
+# "bps_max": 0,
729
+# "bps_rd_max": 0,
730
+# "bps_wr_max": 0,
731
+# "iops_max": 0,
732
+# "iops_rd_max": 0,
733
+# "iops_wr_max": 0,
734
+# "bps_max_length": 0,
735
+# "iops_size": 0 } }
736
+# <- { "return": {} }
737
+#
738
+# -> { "execute": "block_set_io_throttle",
739
+# "arguments": { "id": "ide0-1-0",
740
+# "bps": 1000000,
741
+# "bps_rd": 0,
742
+# "bps_wr": 0,
743
+# "iops": 0,
744
+# "iops_rd": 0,
745
+# "iops_wr": 0,
746
+# "bps_max": 8000000,
747
+# "bps_rd_max": 0,
748
+# "bps_wr_max": 0,
749
+# "iops_max": 0,
750
+# "iops_rd_max": 0,
751
+# "iops_wr_max": 0,
752
+# "bps_max_length": 60,
753
+# "iops_size": 0 } }
754
+# <- { "return": {} }
755
+##
756
+{ 'command': 'block_set_io_throttle', 'boxed': true,
757
+ 'data': 'BlockIOThrottle' }
758
+
759
+##
760
+# @block-latency-histogram-set:
761
+#
762
+# Manage read, write and flush latency histograms for the device.
763
+#
764
+# If only @id parameter is specified, remove all present latency histograms
765
+# for the device. Otherwise, add/reset some of (or all) latency histograms.
766
+#
767
+# @id: The name or QOM path of the guest device.
768
+#
769
+# @boundaries: list of interval boundary values (see description in
770
+# BlockLatencyHistogramInfo definition). If specified, all
771
+# latency histograms are removed, and empty ones created for all
772
+# io types with intervals corresponding to @boundaries (except for
773
+# io types, for which specific boundaries are set through the
774
+# following parameters).
775
+#
776
+# @boundaries-read: list of interval boundary values for read latency
777
+# histogram. If specified, old read latency histogram is
778
+# removed, and empty one created with intervals
779
+# corresponding to @boundaries-read. The parameter has higher
780
+# priority then @boundaries.
781
+#
782
+# @boundaries-write: list of interval boundary values for write latency
783
+# histogram.
784
+#
785
+# @boundaries-flush: list of interval boundary values for flush latency
786
+# histogram.
787
+#
788
+# Returns: error if device is not found or any boundary arrays are invalid.
789
+#
790
+# Since: 4.0
791
+#
792
+# Example: set new histograms for all io types with intervals
793
+# [0, 10), [10, 50), [50, 100), [100, +inf):
794
+#
795
+# -> { "execute": "block-latency-histogram-set",
796
+# "arguments": { "id": "drive0",
797
+# "boundaries": [10, 50, 100] } }
798
+# <- { "return": {} }
799
+#
800
+# Example: set new histogram only for write, other histograms will remain
801
+# not changed (or not created):
802
+#
803
+# -> { "execute": "block-latency-histogram-set",
804
+# "arguments": { "id": "drive0",
805
+# "boundaries-write": [10, 50, 100] } }
806
+# <- { "return": {} }
807
+#
808
+# Example: set new histograms with the following intervals:
809
+# read, flush: [0, 10), [10, 50), [50, 100), [100, +inf)
810
+# write: [0, 1000), [1000, 5000), [5000, +inf)
811
+#
812
+# -> { "execute": "block-latency-histogram-set",
813
+# "arguments": { "id": "drive0",
814
+# "boundaries": [10, 50, 100],
815
+# "boundaries-write": [1000, 5000] } }
816
+# <- { "return": {} }
817
+#
818
+# Example: remove all latency histograms:
819
+#
820
+# -> { "execute": "block-latency-histogram-set",
821
+# "arguments": { "id": "drive0" } }
822
+# <- { "return": {} }
823
+##
824
+{ 'command': 'block-latency-histogram-set',
825
+ 'data': {'id': 'str',
826
+ '*boundaries': ['uint64'],
827
+ '*boundaries-read': ['uint64'],
828
+ '*boundaries-write': ['uint64'],
829
+ '*boundaries-flush': ['uint64'] } }
830
diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
831
index XXXXXXX..XXXXXXX 100644
832
--- a/monitor/qmp-cmds.c
833
+++ b/monitor/qmp-cmds.c
834
@@ -XXX,XX +XXX,XX @@
835
#include "sysemu/blockdev.h"
836
#include "sysemu/block-backend.h"
837
#include "qapi/error.h"
838
-#include "qapi/qapi-commands-block-core.h"
839
+#include "qapi/qapi-commands-block.h"
840
#include "qapi/qapi-commands-control.h"
841
#include "qapi/qapi-commands-machine.h"
842
#include "qapi/qapi-commands-misc.h"
91
--
843
--
92
2.19.1
844
2.20.1
93
845
94
846
diff view generated by jsdifflib
1
If read-only=off, but auto-read-only=on is given, open the volume
1
This adds a --blockdev option to the storage daemon that works the same
2
read-write if we have the permissions, but instead of erroring out for
2
as the -blockdev option of the system emulator.
3
read-only volumes, just degrade to read-only.
3
4
In order to be able to link with blockdev.o, we also need to change
5
stream.o from common-obj to block-obj, which is where all other block
6
jobs already are.
7
8
In contrast to the system emulator, qemu-storage-daemon options will be
9
processed in the order they are given. The user needs to take care to
10
refer to other objects only after defining them.
4
11
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
13
Message-Id: <20200224143008.13362-7-kwolf@redhat.com>
14
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
16
---
8
block/iscsi.c | 8 +++++---
17
qemu-storage-daemon.c | 31 +++++++++++++++++++++++++++++++
9
1 file changed, 5 insertions(+), 3 deletions(-)
18
Makefile | 5 ++++-
19
Makefile.objs | 7 +++++++
20
block/Makefile.objs | 2 +-
21
4 files changed, 43 insertions(+), 2 deletions(-)
10
22
11
diff --git a/block/iscsi.c b/block/iscsi.c
23
diff --git a/qemu-storage-daemon.c b/qemu-storage-daemon.c
12
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
13
--- a/block/iscsi.c
25
--- a/qemu-storage-daemon.c
14
+++ b/block/iscsi.c
26
+++ b/qemu-storage-daemon.c
15
@@ -XXX,XX +XXX,XX @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
27
@@ -XXX,XX +XXX,XX @@
16
/* Check the write protect flag of the LUN if we want to write */
28
#include "crypto/init.h"
17
if (iscsilun->type == TYPE_DISK && (flags & BDRV_O_RDWR) &&
29
18
iscsilun->write_protected) {
30
#include "qapi/error.h"
19
- error_setg(errp, "Cannot open a write protected LUN as read-write");
31
+#include "qapi/qapi-visit-block-core.h"
20
- ret = -EACCES;
32
+#include "qapi/qapi-commands-block-core.h"
21
- goto out;
33
+#include "qapi/qobject-input-visitor.h"
22
+ ret = bdrv_apply_auto_read_only(bs, "LUN is write protected", errp);
34
+
23
+ if (ret < 0) {
35
#include "qemu-common.h"
24
+ goto out;
36
#include "qemu-version.h"
25
+ }
37
#include "qemu/config-file.h"
26
+ flags &= ~BDRV_O_RDWR;
38
@@ -XXX,XX +XXX,XX @@ static void help(void)
27
}
39
" specify tracing options\n"
28
40
" -V, --version output version information and exit\n"
29
iscsi_readcapacity_sync(iscsilun, &local_err);
41
"\n"
42
+" --blockdev [driver=]<driver>[,node-name=<N>][,discard=ignore|unmap]\n"
43
+" [,cache.direct=on|off][,cache.no-flush=on|off]\n"
44
+" [,read-only=on|off][,auto-read-only=on|off]\n"
45
+" [,force-share=on|off][,detect-zeroes=on|off|unmap]\n"
46
+" [,driver specific parameters...]\n"
47
+" configure a block backend\n"
48
+"\n"
49
QEMU_HELP_BOTTOM "\n",
50
error_get_progname());
51
}
52
53
+enum {
54
+ OPTION_BLOCKDEV = 256,
55
+};
56
+
57
static void process_options(int argc, char *argv[])
58
{
59
int c;
60
61
static const struct option long_options[] = {
62
+ {"blockdev", required_argument, NULL, OPTION_BLOCKDEV},
63
{"help", no_argument, NULL, 'h'},
64
{"trace", required_argument, NULL, 'T'},
65
{"version", no_argument, NULL, 'V'},
66
@@ -XXX,XX +XXX,XX @@ static void process_options(int argc, char *argv[])
67
printf("qemu-storage-daemon version "
68
QEMU_FULL_VERSION "\n" QEMU_COPYRIGHT "\n");
69
exit(EXIT_SUCCESS);
70
+ case OPTION_BLOCKDEV:
71
+ {
72
+ Visitor *v;
73
+ BlockdevOptions *options;
74
+
75
+ v = qobject_input_visitor_new_str(optarg, "driver",
76
+ &error_fatal);
77
+
78
+ visit_type_BlockdevOptions(v, NULL, &options, &error_fatal);
79
+ visit_free(v);
80
+
81
+ qmp_blockdev_add(options, &error_fatal);
82
+ qapi_free_BlockdevOptions(options);
83
+ break;
84
+ }
85
default:
86
g_assert_not_reached();
87
}
88
diff --git a/Makefile b/Makefile
89
index XXXXXXX..XXXXXXX 100644
90
--- a/Makefile
91
+++ b/Makefile
92
@@ -XXX,XX +XXX,XX @@ dummy := $(call unnest-vars,, \
93
qga-vss-dll-obj-y \
94
block-obj-y \
95
block-obj-m \
96
+ storage-daemon-obj-y \
97
+ storage-daemon-obj-m \
98
crypto-obj-y \
99
qom-obj-y \
100
io-obj-y \
101
@@ -XXX,XX +XXX,XX @@ TARGET_DIRS_RULES := $(foreach t, all fuzz clean install, $(addsuffix /$(t), $(T
102
SOFTMMU_ALL_RULES=$(filter %-softmmu/all, $(TARGET_DIRS_RULES))
103
$(SOFTMMU_ALL_RULES): $(authz-obj-y)
104
$(SOFTMMU_ALL_RULES): $(block-obj-y)
105
+$(SOFTMMU_ALL_RULES): $(storage-daemon-obj-y)
106
$(SOFTMMU_ALL_RULES): $(chardev-obj-y)
107
$(SOFTMMU_ALL_RULES): $(crypto-obj-y)
108
$(SOFTMMU_ALL_RULES): $(io-obj-y)
109
@@ -XXX,XX +XXX,XX @@ qemu-img.o: qemu-img-cmds.h
110
qemu-img$(EXESUF): qemu-img.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
111
qemu-nbd$(EXESUF): qemu-nbd.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
112
qemu-io$(EXESUF): qemu-io.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
113
-qemu-storage-daemon$(EXESUF): qemu-storage-daemon.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
114
+qemu-storage-daemon$(EXESUF): qemu-storage-daemon.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(storage-daemon-obj-y) $(COMMON_LDADDS)
115
116
qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o $(COMMON_LDADDS)
117
118
diff --git a/Makefile.objs b/Makefile.objs
119
index XXXXXXX..XXXXXXX 100644
120
--- a/Makefile.objs
121
+++ b/Makefile.objs
122
@@ -XXX,XX +XXX,XX @@ io-obj-y = io/
123
124
endif # CONFIG_SOFTMMU or CONFIG_TOOLS
125
126
+#######################################################################
127
+# storage-daemon-obj-y is code used by qemu-storage-daemon (these objects are
128
+# used for system emulation, too, but specified separately there)
129
+
130
+storage-daemon-obj-y = block/
131
+storage-daemon-obj-y += blockdev.o iothread.o
132
+
133
######################################################################
134
# Target independent part of system emulation. The long term path is to
135
# suppress *all* target specific code in case of system emulation, i.e. a
136
diff --git a/block/Makefile.objs b/block/Makefile.objs
137
index XXXXXXX..XXXXXXX 100644
138
--- a/block/Makefile.objs
139
+++ b/block/Makefile.objs
140
@@ -XXX,XX +XXX,XX @@ block-obj-y += aio_task.o
141
block-obj-y += backup-top.o
142
block-obj-y += filter-compress.o
143
144
-common-obj-y += stream.o
145
+block-obj-y += stream.o
146
147
common-obj-y += qapi-sysemu.o
148
30
--
149
--
31
2.19.1
150
2.20.1
32
151
33
152
diff view generated by jsdifflib
1
From: Peter Maydell <peter.maydell@linaro.org>
1
Mapping object-add to the command line as is doesn't result in nice
2
2
syntax because of the nesting introduced with 'props'. This becomes
3
Taking the address of a field in a packed struct is a bad idea, because
3
nicer and more consistent with device_add and netdev_add when we accept
4
it might not be actually aligned enough for that pointer type (and
4
properties for the object on the top level instead.
5
thus cause a crash on dereference on some host architectures). Newer
5
6
versions of clang warn about this. Avoid the bug by not using the
6
'props' is still accepted after this patch, but marked as deprecated.
7
"modify in place" byte swapping functions.
7
8
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
There are a few places where the in-place swap function is
9
Message-Id: <20200224143008.13362-8-kwolf@redhat.com>
10
used on something other than a packed struct field; we convert
10
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
11
those anyway, for consistency.
12
13
Patch produced with scripts/coccinelle/inplace-byteswaps.cocci.
14
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
---
12
---
19
block/vhdx.h | 12 ++---
13
qapi/qom.json | 12 +++++++---
20
block/vhdx-endian.c | 118 ++++++++++++++++++++++----------------------
14
docs/system/deprecated.rst | 5 ++++
21
block/vhdx-log.c | 4 +-
15
include/qom/object_interfaces.h | 7 ++++++
22
block/vhdx.c | 18 +++----
16
hw/block/xen-block.c | 11 ++++++++-
23
4 files changed, 76 insertions(+), 76 deletions(-)
17
monitor/misc.c | 2 ++
24
18
qom/qom-qmp-cmds.c | 42 +++++++++++++++++++++++++++------
25
diff --git a/block/vhdx.h b/block/vhdx.h
19
6 files changed, 68 insertions(+), 11 deletions(-)
26
index XXXXXXX..XXXXXXX 100644
20
27
--- a/block/vhdx.h
21
diff --git a/qapi/qom.json b/qapi/qom.json
28
+++ b/block/vhdx.h
22
index XXXXXXX..XXXXXXX 100644
29
@@ -XXX,XX +XXX,XX @@ int vhdx_log_write_and_flush(BlockDriverState *bs, BDRVVHDXState *s,
23
--- a/qapi/qom.json
30
24
+++ b/qapi/qom.json
31
static inline void leguid_to_cpus(MSGUID *guid)
25
@@ -XXX,XX +XXX,XX @@
26
#
27
# @id: the name of the new object
28
#
29
-# @props: a dictionary of properties to be passed to the backend
30
+# @props: a dictionary of properties to be passed to the backend. Deprecated
31
+# since 5.0, specify the properties on the top level instead. It is an
32
+# error to specify the same option both on the top level and in @props.
33
+#
34
+# Additional arguments depend on qom-type and are passed to the backend
35
+# unchanged.
36
#
37
# Returns: Nothing on success
38
# Error if @qom-type is not a valid class name
39
@@ -XXX,XX +XXX,XX @@
40
#
41
# -> { "execute": "object-add",
42
# "arguments": { "qom-type": "rng-random", "id": "rng1",
43
-# "props": { "filename": "/dev/hwrng" } } }
44
+# "filename": "/dev/hwrng" } }
45
# <- { "return": {} }
46
#
47
##
48
{ 'command': 'object-add',
49
- 'data': {'qom-type': 'str', 'id': 'str', '*props': 'any'} }
50
+ 'data': {'qom-type': 'str', 'id': 'str', '*props': 'any'},
51
+ 'gen': false } # so we can get the additional arguments
52
53
##
54
# @object-del:
55
diff --git a/docs/system/deprecated.rst b/docs/system/deprecated.rst
56
index XXXXXXX..XXXXXXX 100644
57
--- a/docs/system/deprecated.rst
58
+++ b/docs/system/deprecated.rst
59
@@ -XXX,XX +XXX,XX @@ Use ``migrate-set-parameters`` instead.
60
61
Use ``migrate-set-parameters`` and ``query-migrate-parameters`` instead.
62
63
+``object-add`` option ``props`` (since 5.0)
64
+'''''''''''''''''''''''''''''''''''''''''''
65
+
66
+Specify the properties for the object as top-level arguments instead.
67
+
68
``query-block`` result field ``dirty-bitmaps[i].status`` (since 4.0)
69
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
70
71
diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
72
index XXXXXXX..XXXXXXX 100644
73
--- a/include/qom/object_interfaces.h
74
+++ b/include/qom/object_interfaces.h
75
@@ -XXX,XX +XXX,XX @@ void user_creatable_del(const char *id, Error **errp);
76
*/
77
void user_creatable_cleanup(void);
78
79
+/**
80
+ * qmp_object_add:
81
+ *
82
+ * QMP command handler for object-add. See the QAPI schema for documentation.
83
+ */
84
+void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp);
85
+
86
#endif
87
diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/hw/block/xen-block.c
90
+++ b/hw/block/xen-block.c
91
@@ -XXX,XX +XXX,XX @@
92
#include "qapi/visitor.h"
93
#include "qapi/qmp/qdict.h"
94
#include "qapi/qmp/qstring.h"
95
+#include "qom/object_interfaces.h"
96
#include "hw/xen/xen_common.h"
97
#include "hw/block/xen_blkif.h"
98
#include "hw/qdev-properties.h"
99
@@ -XXX,XX +XXX,XX @@ static XenBlockIOThread *xen_block_iothread_create(const char *id,
32
{
100
{
33
- le32_to_cpus(&guid->data1);
101
XenBlockIOThread *iothread = g_new(XenBlockIOThread, 1);
34
- le16_to_cpus(&guid->data2);
102
Error *local_err = NULL;
35
- le16_to_cpus(&guid->data3);
103
+ QDict *opts;
36
+ guid->data1 = le32_to_cpu(guid->data1);
104
+ QObject *ret_data;
37
+ guid->data2 = le16_to_cpu(guid->data2);
105
38
+ guid->data3 = le16_to_cpu(guid->data3);
106
iothread->id = g_strdup(id);
107
108
- qmp_object_add(TYPE_IOTHREAD, id, false, NULL, &local_err);
109
+ opts = qdict_new();
110
+ qdict_put_str(opts, "qom-type", TYPE_IOTHREAD);
111
+ qdict_put_str(opts, "id", id);
112
+ qmp_object_add(opts, &ret_data, &local_err);
113
+ qobject_unref(opts);
114
+ qobject_unref(ret_data);
115
+
116
if (local_err) {
117
error_propagate(errp, local_err);
118
119
diff --git a/monitor/misc.c b/monitor/misc.c
120
index XXXXXXX..XXXXXXX 100644
121
--- a/monitor/misc.c
122
+++ b/monitor/misc.c
123
@@ -XXX,XX +XXX,XX @@ static void monitor_init_qmp_commands(void)
124
QCO_NO_OPTIONS);
125
qmp_register_command(&qmp_commands, "netdev_add", qmp_netdev_add,
126
QCO_NO_OPTIONS);
127
+ qmp_register_command(&qmp_commands, "object-add", qmp_object_add,
128
+ QCO_NO_OPTIONS);
129
130
QTAILQ_INIT(&qmp_cap_negotiation_commands);
131
qmp_register_command(&qmp_cap_negotiation_commands, "qmp_capabilities",
132
diff --git a/qom/qom-qmp-cmds.c b/qom/qom-qmp-cmds.c
133
index XXXXXXX..XXXXXXX 100644
134
--- a/qom/qom-qmp-cmds.c
135
+++ b/qom/qom-qmp-cmds.c
136
@@ -XXX,XX +XXX,XX @@
137
*/
138
139
#include "qemu/osdep.h"
140
+#include "block/qdict.h"
141
#include "hw/qdev-core.h"
142
#include "qapi/error.h"
143
#include "qapi/qapi-commands-qdev.h"
144
@@ -XXX,XX +XXX,XX @@ ObjectPropertyInfoList *qmp_qom_list_properties(const char *typename,
145
return prop_list;
39
}
146
}
40
147
41
static inline void cpu_to_leguids(MSGUID *guid)
148
-void qmp_object_add(const char *type, const char *id,
149
- bool has_props, QObject *props, Error **errp)
150
+void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp)
42
{
151
{
43
- cpu_to_le32s(&guid->data1);
152
+ QObject *props;
44
- cpu_to_le16s(&guid->data2);
153
QDict *pdict;
45
- cpu_to_le16s(&guid->data3);
154
Visitor *v;
46
+ guid->data1 = cpu_to_le32(guid->data1);
155
Object *obj;
47
+ guid->data2 = cpu_to_le16(guid->data2);
156
+ const char *type;
48
+ guid->data3 = cpu_to_le16(guid->data3);
157
+ const char *id;
158
159
+ type = qdict_get_try_str(qdict, "qom-type");
160
+ if (!type) {
161
+ error_setg(errp, QERR_MISSING_PARAMETER, "qom-type");
162
+ return;
163
+ } else {
164
+ type = g_strdup(type);
165
+ qdict_del(qdict, "qom-type");
166
+ }
167
+
168
+ id = qdict_get_try_str(qdict, "id");
169
+ if (!id) {
170
+ error_setg(errp, QERR_MISSING_PARAMETER, "id");
171
+ return;
172
+ } else {
173
+ id = g_strdup(id);
174
+ qdict_del(qdict, "id");
175
+ }
176
+
177
+ props = qdict_get(qdict, "props");
178
if (props) {
179
pdict = qobject_to(QDict, props);
180
if (!pdict) {
181
@@ -XXX,XX +XXX,XX @@ void qmp_object_add(const char *type, const char *id,
182
return;
183
}
184
qobject_ref(pdict);
185
- } else {
186
- pdict = qdict_new();
187
+ qdict_del(qdict, "props");
188
+ qdict_join(qdict, pdict, false);
189
+ if (qdict_size(pdict) != 0) {
190
+ error_setg(errp, "Option in 'props' conflicts with top level");
191
+ qobject_unref(pdict);
192
+ return;
193
+ }
194
+ qobject_unref(pdict);
195
}
196
197
- v = qobject_input_visitor_new(QOBJECT(pdict));
198
- obj = user_creatable_add_type(type, id, pdict, v, errp);
199
+ v = qobject_input_visitor_new(QOBJECT(qdict));
200
+ obj = user_creatable_add_type(type, id, qdict, v, errp);
201
visit_free(v);
202
if (obj) {
203
object_unref(obj);
204
}
205
- qobject_unref(pdict);
206
+ *ret_data = QOBJECT(qdict_new());
49
}
207
}
50
208
51
void vhdx_header_le_import(VHDXHeader *h);
209
void qmp_object_del(const char *id, Error **errp)
52
diff --git a/block/vhdx-endian.c b/block/vhdx-endian.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/block/vhdx-endian.c
55
+++ b/block/vhdx-endian.c
56
@@ -XXX,XX +XXX,XX @@ void vhdx_header_le_import(VHDXHeader *h)
57
{
58
assert(h != NULL);
59
60
- le32_to_cpus(&h->signature);
61
- le32_to_cpus(&h->checksum);
62
- le64_to_cpus(&h->sequence_number);
63
+ h->signature = le32_to_cpu(h->signature);
64
+ h->checksum = le32_to_cpu(h->checksum);
65
+ h->sequence_number = le64_to_cpu(h->sequence_number);
66
67
leguid_to_cpus(&h->file_write_guid);
68
leguid_to_cpus(&h->data_write_guid);
69
leguid_to_cpus(&h->log_guid);
70
71
- le16_to_cpus(&h->log_version);
72
- le16_to_cpus(&h->version);
73
- le32_to_cpus(&h->log_length);
74
- le64_to_cpus(&h->log_offset);
75
+ h->log_version = le16_to_cpu(h->log_version);
76
+ h->version = le16_to_cpu(h->version);
77
+ h->log_length = le32_to_cpu(h->log_length);
78
+ h->log_offset = le64_to_cpu(h->log_offset);
79
}
80
81
void vhdx_header_le_export(VHDXHeader *orig_h, VHDXHeader *new_h)
82
@@ -XXX,XX +XXX,XX @@ void vhdx_log_desc_le_import(VHDXLogDescriptor *d)
83
{
84
assert(d != NULL);
85
86
- le32_to_cpus(&d->signature);
87
- le64_to_cpus(&d->file_offset);
88
- le64_to_cpus(&d->sequence_number);
89
+ d->signature = le32_to_cpu(d->signature);
90
+ d->file_offset = le64_to_cpu(d->file_offset);
91
+ d->sequence_number = le64_to_cpu(d->sequence_number);
92
}
93
94
void vhdx_log_desc_le_export(VHDXLogDescriptor *d)
95
{
96
assert(d != NULL);
97
98
- cpu_to_le32s(&d->signature);
99
- cpu_to_le32s(&d->trailing_bytes);
100
- cpu_to_le64s(&d->leading_bytes);
101
- cpu_to_le64s(&d->file_offset);
102
- cpu_to_le64s(&d->sequence_number);
103
+ d->signature = cpu_to_le32(d->signature);
104
+ d->trailing_bytes = cpu_to_le32(d->trailing_bytes);
105
+ d->leading_bytes = cpu_to_le64(d->leading_bytes);
106
+ d->file_offset = cpu_to_le64(d->file_offset);
107
+ d->sequence_number = cpu_to_le64(d->sequence_number);
108
}
109
110
void vhdx_log_data_le_import(VHDXLogDataSector *d)
111
{
112
assert(d != NULL);
113
114
- le32_to_cpus(&d->data_signature);
115
- le32_to_cpus(&d->sequence_high);
116
- le32_to_cpus(&d->sequence_low);
117
+ d->data_signature = le32_to_cpu(d->data_signature);
118
+ d->sequence_high = le32_to_cpu(d->sequence_high);
119
+ d->sequence_low = le32_to_cpu(d->sequence_low);
120
}
121
122
void vhdx_log_data_le_export(VHDXLogDataSector *d)
123
{
124
assert(d != NULL);
125
126
- cpu_to_le32s(&d->data_signature);
127
- cpu_to_le32s(&d->sequence_high);
128
- cpu_to_le32s(&d->sequence_low);
129
+ d->data_signature = cpu_to_le32(d->data_signature);
130
+ d->sequence_high = cpu_to_le32(d->sequence_high);
131
+ d->sequence_low = cpu_to_le32(d->sequence_low);
132
}
133
134
void vhdx_log_entry_hdr_le_import(VHDXLogEntryHeader *hdr)
135
{
136
assert(hdr != NULL);
137
138
- le32_to_cpus(&hdr->signature);
139
- le32_to_cpus(&hdr->checksum);
140
- le32_to_cpus(&hdr->entry_length);
141
- le32_to_cpus(&hdr->tail);
142
- le64_to_cpus(&hdr->sequence_number);
143
- le32_to_cpus(&hdr->descriptor_count);
144
+ hdr->signature = le32_to_cpu(hdr->signature);
145
+ hdr->checksum = le32_to_cpu(hdr->checksum);
146
+ hdr->entry_length = le32_to_cpu(hdr->entry_length);
147
+ hdr->tail = le32_to_cpu(hdr->tail);
148
+ hdr->sequence_number = le64_to_cpu(hdr->sequence_number);
149
+ hdr->descriptor_count = le32_to_cpu(hdr->descriptor_count);
150
leguid_to_cpus(&hdr->log_guid);
151
- le64_to_cpus(&hdr->flushed_file_offset);
152
- le64_to_cpus(&hdr->last_file_offset);
153
+ hdr->flushed_file_offset = le64_to_cpu(hdr->flushed_file_offset);
154
+ hdr->last_file_offset = le64_to_cpu(hdr->last_file_offset);
155
}
156
157
void vhdx_log_entry_hdr_le_export(VHDXLogEntryHeader *hdr)
158
{
159
assert(hdr != NULL);
160
161
- cpu_to_le32s(&hdr->signature);
162
- cpu_to_le32s(&hdr->checksum);
163
- cpu_to_le32s(&hdr->entry_length);
164
- cpu_to_le32s(&hdr->tail);
165
- cpu_to_le64s(&hdr->sequence_number);
166
- cpu_to_le32s(&hdr->descriptor_count);
167
+ hdr->signature = cpu_to_le32(hdr->signature);
168
+ hdr->checksum = cpu_to_le32(hdr->checksum);
169
+ hdr->entry_length = cpu_to_le32(hdr->entry_length);
170
+ hdr->tail = cpu_to_le32(hdr->tail);
171
+ hdr->sequence_number = cpu_to_le64(hdr->sequence_number);
172
+ hdr->descriptor_count = cpu_to_le32(hdr->descriptor_count);
173
cpu_to_leguids(&hdr->log_guid);
174
- cpu_to_le64s(&hdr->flushed_file_offset);
175
- cpu_to_le64s(&hdr->last_file_offset);
176
+ hdr->flushed_file_offset = cpu_to_le64(hdr->flushed_file_offset);
177
+ hdr->last_file_offset = cpu_to_le64(hdr->last_file_offset);
178
}
179
180
181
@@ -XXX,XX +XXX,XX @@ void vhdx_region_header_le_import(VHDXRegionTableHeader *hdr)
182
{
183
assert(hdr != NULL);
184
185
- le32_to_cpus(&hdr->signature);
186
- le32_to_cpus(&hdr->checksum);
187
- le32_to_cpus(&hdr->entry_count);
188
+ hdr->signature = le32_to_cpu(hdr->signature);
189
+ hdr->checksum = le32_to_cpu(hdr->checksum);
190
+ hdr->entry_count = le32_to_cpu(hdr->entry_count);
191
}
192
193
void vhdx_region_header_le_export(VHDXRegionTableHeader *hdr)
194
{
195
assert(hdr != NULL);
196
197
- cpu_to_le32s(&hdr->signature);
198
- cpu_to_le32s(&hdr->checksum);
199
- cpu_to_le32s(&hdr->entry_count);
200
+ hdr->signature = cpu_to_le32(hdr->signature);
201
+ hdr->checksum = cpu_to_le32(hdr->checksum);
202
+ hdr->entry_count = cpu_to_le32(hdr->entry_count);
203
}
204
205
void vhdx_region_entry_le_import(VHDXRegionTableEntry *e)
206
@@ -XXX,XX +XXX,XX @@ void vhdx_region_entry_le_import(VHDXRegionTableEntry *e)
207
assert(e != NULL);
208
209
leguid_to_cpus(&e->guid);
210
- le64_to_cpus(&e->file_offset);
211
- le32_to_cpus(&e->length);
212
- le32_to_cpus(&e->data_bits);
213
+ e->file_offset = le64_to_cpu(e->file_offset);
214
+ e->length = le32_to_cpu(e->length);
215
+ e->data_bits = le32_to_cpu(e->data_bits);
216
}
217
218
void vhdx_region_entry_le_export(VHDXRegionTableEntry *e)
219
@@ -XXX,XX +XXX,XX @@ void vhdx_region_entry_le_export(VHDXRegionTableEntry *e)
220
assert(e != NULL);
221
222
cpu_to_leguids(&e->guid);
223
- cpu_to_le64s(&e->file_offset);
224
- cpu_to_le32s(&e->length);
225
- cpu_to_le32s(&e->data_bits);
226
+ e->file_offset = cpu_to_le64(e->file_offset);
227
+ e->length = cpu_to_le32(e->length);
228
+ e->data_bits = cpu_to_le32(e->data_bits);
229
}
230
231
232
@@ -XXX,XX +XXX,XX @@ void vhdx_metadata_header_le_import(VHDXMetadataTableHeader *hdr)
233
{
234
assert(hdr != NULL);
235
236
- le64_to_cpus(&hdr->signature);
237
- le16_to_cpus(&hdr->entry_count);
238
+ hdr->signature = le64_to_cpu(hdr->signature);
239
+ hdr->entry_count = le16_to_cpu(hdr->entry_count);
240
}
241
242
void vhdx_metadata_header_le_export(VHDXMetadataTableHeader *hdr)
243
{
244
assert(hdr != NULL);
245
246
- cpu_to_le64s(&hdr->signature);
247
- cpu_to_le16s(&hdr->entry_count);
248
+ hdr->signature = cpu_to_le64(hdr->signature);
249
+ hdr->entry_count = cpu_to_le16(hdr->entry_count);
250
}
251
252
void vhdx_metadata_entry_le_import(VHDXMetadataTableEntry *e)
253
@@ -XXX,XX +XXX,XX @@ void vhdx_metadata_entry_le_import(VHDXMetadataTableEntry *e)
254
assert(e != NULL);
255
256
leguid_to_cpus(&e->item_id);
257
- le32_to_cpus(&e->offset);
258
- le32_to_cpus(&e->length);
259
- le32_to_cpus(&e->data_bits);
260
+ e->offset = le32_to_cpu(e->offset);
261
+ e->length = le32_to_cpu(e->length);
262
+ e->data_bits = le32_to_cpu(e->data_bits);
263
}
264
void vhdx_metadata_entry_le_export(VHDXMetadataTableEntry *e)
265
{
266
assert(e != NULL);
267
268
cpu_to_leguids(&e->item_id);
269
- cpu_to_le32s(&e->offset);
270
- cpu_to_le32s(&e->length);
271
- cpu_to_le32s(&e->data_bits);
272
+ e->offset = cpu_to_le32(e->offset);
273
+ e->length = cpu_to_le32(e->length);
274
+ e->data_bits = cpu_to_le32(e->data_bits);
275
}
276
diff --git a/block/vhdx-log.c b/block/vhdx-log.c
277
index XXXXXXX..XXXXXXX 100644
278
--- a/block/vhdx-log.c
279
+++ b/block/vhdx-log.c
280
@@ -XXX,XX +XXX,XX @@ static void vhdx_log_raw_to_le_sector(VHDXLogDescriptor *desc,
281
/* 8 + 4084 + 4 = 4096, 1 log sector */
282
memcpy(&desc->leading_bytes, data, 8);
283
data += 8;
284
- cpu_to_le64s(&desc->leading_bytes);
285
+ desc->leading_bytes = cpu_to_le64(desc->leading_bytes);
286
memcpy(sector->data, data, 4084);
287
data += 4084;
288
memcpy(&desc->trailing_bytes, data, 4);
289
- cpu_to_le32s(&desc->trailing_bytes);
290
+ desc->trailing_bytes = cpu_to_le32(desc->trailing_bytes);
291
data += 4;
292
293
sector->sequence_high = (uint32_t) (seq >> 32);
294
diff --git a/block/vhdx.c b/block/vhdx.c
295
index XXXXXXX..XXXXXXX 100644
296
--- a/block/vhdx.c
297
+++ b/block/vhdx.c
298
@@ -XXX,XX +XXX,XX @@ uint32_t vhdx_update_checksum(uint8_t *buf, size_t size, int crc_offset)
299
300
memset(buf + crc_offset, 0, sizeof(crc));
301
crc = crc32c(0xffffffff, buf, size);
302
- cpu_to_le32s(&crc);
303
+ crc = cpu_to_le32(crc);
304
memcpy(buf + crc_offset, &crc, sizeof(crc));
305
306
return crc;
307
@@ -XXX,XX +XXX,XX @@ static int vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s)
308
goto exit;
309
}
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
--
210
--
359
2.19.1
211
2.20.1
360
212
361
213
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
Add a command line option to create user-creatable QOM objects.
2
2
3
This is a static function with only one caller, so there's no need to
3
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
keep it. Inlining the code in quorum_compare() makes it much simpler.
4
Message-Id: <20200224143008.13362-9-kwolf@redhat.com>
5
5
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
6
Signed-off-by: Alberto Garcia <berto@igalia.com>
7
Reported-by: Markus Armbruster <armbru@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
7
---
10
block/quorum.c | 24 +++++-------------------
8
qemu-storage-daemon.c | 47 +++++++++++++++++++++++++++++++++++++++++++
11
1 file changed, 5 insertions(+), 19 deletions(-)
9
Makefile.objs | 2 +-
10
qom/Makefile.objs | 1 +
11
3 files changed, 49 insertions(+), 1 deletion(-)
12
12
13
diff --git a/block/quorum.c b/block/quorum.c
13
diff --git a/qemu-storage-daemon.c b/qemu-storage-daemon.c
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/block/quorum.c
15
--- a/qemu-storage-daemon.c
16
+++ b/block/quorum.c
16
+++ b/qemu-storage-daemon.c
17
@@ -XXX,XX +XXX,XX @@ static bool quorum_iovec_compare(QEMUIOVector *a, QEMUIOVector *b)
17
@@ -XXX,XX +XXX,XX @@
18
return true;
18
#include "qapi/error.h"
19
#include "qapi/qapi-visit-block-core.h"
20
#include "qapi/qapi-commands-block-core.h"
21
+#include "qapi/qmp/qdict.h"
22
#include "qapi/qobject-input-visitor.h"
23
24
#include "qemu-common.h"
25
#include "qemu-version.h"
26
#include "qemu/config-file.h"
27
#include "qemu/error-report.h"
28
+#include "qemu/help_option.h"
29
#include "qemu/log.h"
30
#include "qemu/main-loop.h"
31
#include "qemu/module.h"
32
+#include "qemu/option.h"
33
+#include "qom/object_interfaces.h"
34
35
#include "trace/control.h"
36
37
@@ -XXX,XX +XXX,XX @@ static void help(void)
38
" [,driver specific parameters...]\n"
39
" configure a block backend\n"
40
"\n"
41
+" --object help list object types that can be added\n"
42
+" --object <type>,help list properties for the given object type\n"
43
+" --object <type>[,<property>=<value>...]\n"
44
+" create a new object of type <type>, setting\n"
45
+" properties in the order they are specified. Note\n"
46
+" that the 'id' property must be set.\n"
47
+" See the qemu(1) man page for documentation of the\n"
48
+" objects that can be added.\n"
49
+"\n"
50
QEMU_HELP_BOTTOM "\n",
51
error_get_progname());
19
}
52
}
20
53
21
-static void GCC_FMT_ATTR(2, 3) quorum_err(QuorumAIOCB *acb,
54
enum {
22
- const char *fmt, ...)
55
OPTION_BLOCKDEV = 256,
23
-{
56
+ OPTION_OBJECT,
24
- va_list ap;
57
+};
25
-
58
+
26
- va_start(ap, fmt);
59
+static QemuOptsList qemu_object_opts = {
27
- fprintf(stderr, "quorum: offset=%" PRIu64 " bytes=%" PRIu64 " ",
60
+ .name = "object",
28
- acb->offset, acb->bytes);
61
+ .implied_opt_name = "qom-type",
29
- vfprintf(stderr, fmt, ap);
62
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_object_opts.head),
30
- fprintf(stderr, "\n");
63
+ .desc = {
31
- va_end(ap);
64
+ { }
32
- exit(1);
65
+ },
33
-}
66
};
34
-
67
35
-static bool quorum_compare(QuorumAIOCB *acb,
68
static void process_options(int argc, char *argv[])
36
- QEMUIOVector *a,
69
@@ -XXX,XX +XXX,XX @@ static void process_options(int argc, char *argv[])
37
- QEMUIOVector *b)
70
static const struct option long_options[] = {
38
+static bool quorum_compare(QuorumAIOCB *acb, QEMUIOVector *a, QEMUIOVector *b)
71
{"blockdev", required_argument, NULL, OPTION_BLOCKDEV},
39
{
72
{"help", no_argument, NULL, 'h'},
40
BDRVQuorumState *s = acb->bs->opaque;
73
+ {"object", required_argument, NULL, OPTION_OBJECT},
41
ssize_t offset;
74
{"trace", required_argument, NULL, 'T'},
42
@@ -XXX,XX +XXX,XX @@ static bool quorum_compare(QuorumAIOCB *acb,
75
{"version", no_argument, NULL, 'V'},
43
if (s->is_blkverify) {
76
{0, 0, 0, 0}
44
offset = qemu_iovec_compare(a, b);
77
@@ -XXX,XX +XXX,XX @@ static void process_options(int argc, char *argv[])
45
if (offset != -1) {
78
qapi_free_BlockdevOptions(options);
46
- quorum_err(acb, "contents mismatch at offset %" PRIu64,
79
break;
47
- acb->offset + offset);
80
}
48
+ fprintf(stderr, "quorum: offset=%" PRIu64 " bytes=%" PRIu64
81
+ case OPTION_OBJECT:
49
+ " contents mismatch at offset %" PRIu64 "\n",
82
+ {
50
+ acb->offset, acb->bytes, acb->offset + offset);
83
+ QemuOpts *opts;
51
+ exit(1);
84
+ const char *type;
85
+ QDict *args;
86
+ QObject *ret_data = NULL;
87
+
88
+ /* FIXME The keyval parser rejects 'help' arguments, so we must
89
+ * unconditionall try QemuOpts first. */
90
+ opts = qemu_opts_parse(&qemu_object_opts,
91
+ optarg, true, &error_fatal);
92
+ type = qemu_opt_get(opts, "qom-type");
93
+ if (type && user_creatable_print_help(type, opts)) {
94
+ exit(EXIT_SUCCESS);
95
+ }
96
+ qemu_opts_del(opts);
97
+
98
+ args = keyval_parse(optarg, "qom-type", &error_fatal);
99
+ qmp_object_add(args, &ret_data, &error_fatal);
100
+ qobject_unref(args);
101
+ qobject_unref(ret_data);
102
+ break;
103
+ }
104
default:
105
g_assert_not_reached();
52
}
106
}
53
return true;
107
diff --git a/Makefile.objs b/Makefile.objs
54
}
108
index XXXXXXX..XXXXXXX 100644
109
--- a/Makefile.objs
110
+++ b/Makefile.objs
111
@@ -XXX,XX +XXX,XX @@ endif # CONFIG_SOFTMMU or CONFIG_TOOLS
112
# storage-daemon-obj-y is code used by qemu-storage-daemon (these objects are
113
# used for system emulation, too, but specified separately there)
114
115
-storage-daemon-obj-y = block/
116
+storage-daemon-obj-y = block/ qom/
117
storage-daemon-obj-y += blockdev.o iothread.o
118
119
######################################################################
120
diff --git a/qom/Makefile.objs b/qom/Makefile.objs
121
index XXXXXXX..XXXXXXX 100644
122
--- a/qom/Makefile.objs
123
+++ b/qom/Makefile.objs
124
@@ -XXX,XX +XXX,XX @@ qom-obj-y = object.o container.o qom-qobject.o
125
qom-obj-y += object_interfaces.o
126
127
common-obj-$(CONFIG_SOFTMMU) += qom-hmp-cmds.o qom-qmp-cmds.o
128
+storage-daemon-obj-y += qom-qmp-cmds.o
55
--
129
--
56
2.19.1
130
2.20.1
57
131
58
132
diff view generated by jsdifflib
1
If a management application builds the block graph node by node, the
1
Add a --nbd-server option to qemu-storage-daemon to start the built-in
2
protocol layer doesn't inherit its read-only option from the format
2
NBD server right away. It maps the arguments for nbd-server-start to the
3
layer any more, so it must be set explicitly.
3
command line, with the exception that it uses SocketAddress instead of
4
SocketAddressLegacy: New interfaces shouldn't use legacy types, and the
5
additional nesting would be nasty on the command line.
4
6
5
Backing files should work on read-only storage, but at the same time, a
7
Example (only with required options):
6
block job like commit should be able to reopen them read-write if they
7
are on read-write storage. However, without option inheritance, reopen
8
only changes the read-only option for the root node (typically the
9
format layer), but not the protocol layer, so reopening fails (the
10
format layer wants to get write permissions, but the protocol layer is
11
still read-only).
12
8
13
A simple workaround for the problem in the management tool would be to
9
--nbd-server addr.type=inet,addr.host=localhost,addr.port=10809
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
10
38
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
39
Reviewed-by: Eric Blake <eblake@redhat.com>
12
Message-Id: <20200224143008.13362-10-kwolf@redhat.com>
13
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
40
---
15
---
41
qapi/block-core.json | 7 +++++++
16
qapi/block-core.json | 24 ++++++++++++++++++++++++
42
include/block/block.h | 2 ++
17
include/block/nbd.h | 1 +
43
block.c | 17 +++++++++++++++++
18
blockdev-nbd.c | 5 +++++
44
block/vvfat.c | 1 +
19
qemu-storage-daemon.c | 26 +++++++++++++++++++++++++-
45
blockdev.c | 2 +-
20
Makefile.objs | 2 +-
46
5 files changed, 28 insertions(+), 1 deletion(-)
21
5 files changed, 56 insertions(+), 2 deletions(-)
47
22
48
diff --git a/qapi/block-core.json b/qapi/block-core.json
23
diff --git a/qapi/block-core.json b/qapi/block-core.json
49
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
50
--- a/qapi/block-core.json
25
--- a/qapi/block-core.json
51
+++ b/qapi/block-core.json
26
+++ b/qapi/block-core.json
52
@@ -XXX,XX +XXX,XX @@
27
@@ -XXX,XX +XXX,XX @@
53
# either generally or in certain configurations. In this case,
28
'iothread': 'StrOrNull',
54
# the default value does not work and the option must be
29
'*force': 'bool' } }
55
# specified explicitly.
30
56
+# @auto-read-only: if true and @read-only is false, QEMU may automatically
31
+##
57
+# decide not to open the image read-write as requested, but
32
+# @NbdServerOptions:
58
+# fall back to read-only instead (and switch between the modes
33
+#
59
+# later), e.g. depending on whether the image file is writable
34
+# @addr: Address on which to listen.
60
+# or whether a writing user is attached to the node
35
+# @tls-creds: ID of the TLS credentials object (since 2.6).
61
+# (default: false, since 3.1)
36
+# @tls-authz: ID of the QAuthZ authorization object used to validate
62
# @detect-zeroes: detect and optimize zero writes (Since 2.1)
37
+# the client's x509 distinguished name. This object is
63
# (default: off)
38
+# is only resolved at time of use, so can be deleted and
64
# @force-share: force share all permission on added nodes.
39
+# recreated on the fly while the NBD server is active.
40
+# If missing, it will default to denying access (since 4.0).
41
+#
42
+# Keep this type consistent with the nbd-server-start arguments. The only
43
+# intended difference is using SocketAddress instead of SocketAddressLegacy.
44
+#
45
+# Since: 4.2
46
+##
47
+{ 'struct': 'NbdServerOptions',
48
+ 'data': { 'addr': 'SocketAddress',
49
+ '*tls-creds': 'str',
50
+ '*tls-authz': 'str'} }
51
+
52
##
53
# @nbd-server-start:
54
#
65
@@ -XXX,XX +XXX,XX @@
55
@@ -XXX,XX +XXX,XX @@
66
'*discard': 'BlockdevDiscardOptions',
56
#
67
'*cache': 'BlockdevCacheOptions',
57
# Returns: error if the server is already running.
68
'*read-only': 'bool',
58
#
69
+ '*auto-read-only': 'bool',
59
+# Keep this type consistent with the NbdServerOptions type. The only intended
70
'*force-share': 'bool',
60
+# difference is using SocketAddressLegacy instead of SocketAddress.
71
'*detect-zeroes': 'BlockdevDetectZeroesOptions' },
61
+#
72
'discriminator': 'driver',
62
# Since: 1.3.0
73
diff --git a/include/block/block.h b/include/block/block.h
63
##
64
{ 'command': 'nbd-server-start',
65
diff --git a/include/block/nbd.h b/include/block/nbd.h
74
index XXXXXXX..XXXXXXX 100644
66
index XXXXXXX..XXXXXXX 100644
75
--- a/include/block/block.h
67
--- a/include/block/nbd.h
76
+++ b/include/block/block.h
68
+++ b/include/block/nbd.h
77
@@ -XXX,XX +XXX,XX @@ typedef struct HDGeometry {
69
@@ -XXX,XX +XXX,XX @@ void nbd_client_put(NBDClient *client);
78
select an appropriate protocol driver,
70
79
ignoring the format layer */
71
void nbd_server_start(SocketAddress *addr, const char *tls_creds,
80
#define BDRV_O_NO_IO 0x10000 /* don't initialize for I/O */
72
const char *tls_authz, Error **errp);
81
+#define BDRV_O_AUTO_RDONLY 0x20000 /* degrade to read-only if opening read-write fails */
73
+void nbd_server_start_options(NbdServerOptions *arg, Error **errp);
82
74
83
#define BDRV_O_CACHE_MASK (BDRV_O_NOCACHE | BDRV_O_NO_FLUSH)
75
/* nbd_read
84
76
* Reads @size bytes from @ioc. Returns 0 on success.
85
@@ -XXX,XX +XXX,XX @@ typedef struct HDGeometry {
77
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
86
#define BDRV_OPT_CACHE_DIRECT "cache.direct"
87
#define BDRV_OPT_CACHE_NO_FLUSH "cache.no-flush"
88
#define BDRV_OPT_READ_ONLY "read-only"
89
+#define BDRV_OPT_AUTO_READ_ONLY "auto-read-only"
90
#define BDRV_OPT_DISCARD "discard"
91
#define BDRV_OPT_FORCE_SHARE "force-share"
92
93
diff --git a/block.c b/block.c
94
index XXXXXXX..XXXXXXX 100644
78
index XXXXXXX..XXXXXXX 100644
95
--- a/block.c
79
--- a/blockdev-nbd.c
96
+++ b/block.c
80
+++ b/blockdev-nbd.c
97
@@ -XXX,XX +XXX,XX @@ static void bdrv_inherited_options(int *child_flags, QDict *child_options,
81
@@ -XXX,XX +XXX,XX @@ void nbd_server_start(SocketAddress *addr, const char *tls_creds,
98
82
nbd_server = NULL;
99
/* Inherit the read-only option from the parent if it's not set */
100
qdict_copy_default(child_options, parent_options, BDRV_OPT_READ_ONLY);
101
+ qdict_copy_default(child_options, parent_options, BDRV_OPT_AUTO_READ_ONLY);
102
103
/* Our block drivers take care to send flushes and respect unmap policy,
104
* so we can default to enable both on lower layers regardless of the
105
@@ -XXX,XX +XXX,XX @@ static void bdrv_backing_options(int *child_flags, QDict *child_options,
106
107
/* backing files always opened read-only */
108
qdict_set_default_str(child_options, BDRV_OPT_READ_ONLY, "on");
109
+ qdict_set_default_str(child_options, BDRV_OPT_AUTO_READ_ONLY, "off");
110
flags &= ~BDRV_O_COPY_ON_READ;
111
112
/* snapshot=on is handled on the top layer */
113
@@ -XXX,XX +XXX,XX @@ static void update_flags_from_options(int *flags, QemuOpts *opts)
114
*flags |= BDRV_O_RDWR;
115
}
116
117
+ assert(qemu_opt_find(opts, BDRV_OPT_AUTO_READ_ONLY));
118
+ if (qemu_opt_get_bool_del(opts, BDRV_OPT_AUTO_READ_ONLY, false)) {
119
+ *flags |= BDRV_O_AUTO_RDONLY;
120
+ }
121
}
83
}
122
84
123
static void update_options_from_flags(QDict *options, int flags)
85
+void nbd_server_start_options(NbdServerOptions *arg, Error **errp)
124
@@ -XXX,XX +XXX,XX @@ static void update_options_from_flags(QDict *options, int flags)
86
+{
125
if (!qdict_haskey(options, BDRV_OPT_READ_ONLY)) {
87
+ nbd_server_start(arg->addr, arg->tls_creds, arg->tls_authz, errp);
126
qdict_put_bool(options, BDRV_OPT_READ_ONLY, !(flags & BDRV_O_RDWR));
88
+}
127
}
128
+ if (!qdict_haskey(options, BDRV_OPT_AUTO_READ_ONLY)) {
129
+ qdict_put_bool(options, BDRV_OPT_AUTO_READ_ONLY,
130
+ flags & BDRV_O_AUTO_RDONLY);
131
+ }
132
}
133
134
static void bdrv_assign_node_name(BlockDriverState *bs,
135
@@ -XXX,XX +XXX,XX @@ QemuOptsList bdrv_runtime_opts = {
136
.type = QEMU_OPT_BOOL,
137
.help = "Node is opened in read-only mode",
138
},
139
+ {
140
+ .name = BDRV_OPT_AUTO_READ_ONLY,
141
+ .type = QEMU_OPT_BOOL,
142
+ .help = "Node can become read-only if opening read-write fails",
143
+ },
144
{
145
.name = "detect-zeroes",
146
.type = QEMU_OPT_STRING,
147
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp)
148
qdict_set_default_str(qdict, BDRV_OPT_CACHE_DIRECT, "off");
149
qdict_set_default_str(qdict, BDRV_OPT_CACHE_NO_FLUSH, "off");
150
qdict_set_default_str(qdict, BDRV_OPT_READ_ONLY, "off");
151
+ qdict_set_default_str(qdict, BDRV_OPT_AUTO_READ_ONLY, "off");
152
+
89
+
153
}
90
void qmp_nbd_server_start(SocketAddressLegacy *addr,
154
91
bool has_tls_creds, const char *tls_creds,
155
bs = bdrv_open_inherit(NULL, reference, qdict, 0, NULL, NULL, errp);
92
bool has_tls_authz, const char *tls_authz,
156
diff --git a/block/vvfat.c b/block/vvfat.c
93
diff --git a/qemu-storage-daemon.c b/qemu-storage-daemon.c
157
index XXXXXXX..XXXXXXX 100644
94
index XXXXXXX..XXXXXXX 100644
158
--- a/block/vvfat.c
95
--- a/qemu-storage-daemon.c
159
+++ b/block/vvfat.c
96
+++ b/qemu-storage-daemon.c
160
@@ -XXX,XX +XXX,XX @@ static void vvfat_qcow_options(int *child_flags, QDict *child_options,
97
@@ -XXX,XX +XXX,XX @@
161
int parent_flags, QDict *parent_options)
98
#include <getopt.h>
162
{
99
163
qdict_set_default_str(child_options, BDRV_OPT_READ_ONLY, "off");
100
#include "block/block.h"
164
+ qdict_set_default_str(child_options, BDRV_OPT_AUTO_READ_ONLY, "off");
101
+#include "block/nbd.h"
165
qdict_set_default_str(child_options, BDRV_OPT_CACHE_NO_FLUSH, "on");
102
#include "crypto/init.h"
166
}
103
167
104
#include "qapi/error.h"
168
diff --git a/blockdev.c b/blockdev.c
105
-#include "qapi/qapi-visit-block-core.h"
106
+#include "qapi/qapi-commands-block.h"
107
#include "qapi/qapi-commands-block-core.h"
108
+#include "qapi/qapi-visit-block.h"
109
+#include "qapi/qapi-visit-block-core.h"
110
#include "qapi/qmp/qdict.h"
111
#include "qapi/qobject-input-visitor.h"
112
113
@@ -XXX,XX +XXX,XX @@ static void help(void)
114
" [,driver specific parameters...]\n"
115
" configure a block backend\n"
116
"\n"
117
+" --nbd-server addr.type=inet,addr.host=<host>,addr.port=<port>\n"
118
+" [,tls-creds=<id>][,tls-authz=<id>]\n"
119
+" --nbd-server addr.type=unix,addr.path=<path>\n"
120
+" [,tls-creds=<id>][,tls-authz=<id>]\n"
121
+" start an NBD server for exporting block nodes\n"
122
+"\n"
123
" --object help list object types that can be added\n"
124
" --object <type>,help list properties for the given object type\n"
125
" --object <type>[,<property>=<value>...]\n"
126
@@ -XXX,XX +XXX,XX @@ QEMU_HELP_BOTTOM "\n",
127
128
enum {
129
OPTION_BLOCKDEV = 256,
130
+ OPTION_NBD_SERVER,
131
OPTION_OBJECT,
132
};
133
134
@@ -XXX,XX +XXX,XX @@ static void process_options(int argc, char *argv[])
135
static const struct option long_options[] = {
136
{"blockdev", required_argument, NULL, OPTION_BLOCKDEV},
137
{"help", no_argument, NULL, 'h'},
138
+ {"nbd-server", required_argument, NULL, OPTION_NBD_SERVER},
139
{"object", required_argument, NULL, OPTION_OBJECT},
140
{"trace", required_argument, NULL, 'T'},
141
{"version", no_argument, NULL, 'V'},
142
@@ -XXX,XX +XXX,XX @@ static void process_options(int argc, char *argv[])
143
qapi_free_BlockdevOptions(options);
144
break;
145
}
146
+ case OPTION_NBD_SERVER:
147
+ {
148
+ Visitor *v;
149
+ NbdServerOptions *options;
150
+
151
+ v = qobject_input_visitor_new_str(optarg, NULL, &error_fatal);
152
+ visit_type_NbdServerOptions(v, NULL, &options, &error_fatal);
153
+ visit_free(v);
154
+
155
+ nbd_server_start_options(options, &error_fatal);
156
+ qapi_free_NbdServerOptions(options);
157
+ break;
158
+ }
159
case OPTION_OBJECT:
160
{
161
QemuOpts *opts;
162
diff --git a/Makefile.objs b/Makefile.objs
169
index XXXXXXX..XXXXXXX 100644
163
index XXXXXXX..XXXXXXX 100644
170
--- a/blockdev.c
164
--- a/Makefile.objs
171
+++ b/blockdev.c
165
+++ b/Makefile.objs
172
@@ -XXX,XX +XXX,XX @@ void qmp_blockdev_change_medium(bool has_device, const char *device,
166
@@ -XXX,XX +XXX,XX @@ endif # CONFIG_SOFTMMU or CONFIG_TOOLS
173
167
# used for system emulation, too, but specified separately there)
174
bdrv_flags = blk_get_open_flags_from_root_state(blk);
168
175
bdrv_flags &= ~(BDRV_O_TEMPORARY | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING |
169
storage-daemon-obj-y = block/ qom/
176
- BDRV_O_PROTOCOL);
170
-storage-daemon-obj-y += blockdev.o iothread.o
177
+ BDRV_O_PROTOCOL | BDRV_O_AUTO_RDONLY);
171
+storage-daemon-obj-y += blockdev.o blockdev-nbd.o iothread.o
178
172
179
if (!has_read_only) {
173
######################################################################
180
read_only = BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN;
174
# Target independent part of system emulation. The long term path is to
181
--
175
--
182
2.19.1
176
2.20.1
183
177
184
178
diff view generated by jsdifflib
1
To fully change the read-only state of a node, we must not only change
1
Move the arguments of nbd-server-add to a new struct BlockExportNbd and
2
bs->read_only, but also update bs->open_flags.
2
convert the command to 'boxed': true. This makes it easier to share code
3
with the storage daemon.
3
4
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Eric Blake <eblake@redhat.com>
6
Message-Id: <20200224143008.13362-11-kwolf@redhat.com>
6
Reviewed-by: Alberto Garcia <berto@igalia.com>
7
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
9
---
8
block.c | 7 +++++++
10
qapi/block-core.json | 18 ++++++++++++++----
9
1 file changed, 7 insertions(+)
11
blockdev-nbd.c | 35 ++++++++++++++++-------------------
12
monitor/hmp-cmds.c | 21 +++++++++++++++++----
13
3 files changed, 47 insertions(+), 27 deletions(-)
10
14
11
diff --git a/block.c b/block.c
15
diff --git a/qapi/block-core.json b/qapi/block-core.json
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/block.c
17
--- a/qapi/block-core.json
14
+++ b/block.c
18
+++ b/qapi/block-core.json
15
@@ -XXX,XX +XXX,XX @@ int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
19
@@ -XXX,XX +XXX,XX @@
20
'*tls-authz': 'str'} }
21
22
##
23
-# @nbd-server-add:
24
+# @BlockExportNbd:
25
#
26
-# Export a block node to QEMU's embedded NBD server.
27
+# An NBD block export.
28
#
29
# @device: The device name or node name of the node to be exported
30
#
31
@@ -XXX,XX +XXX,XX @@
32
# NBD client can use NBD_OPT_SET_META_CONTEXT with
33
# "qemu:dirty-bitmap:NAME" to inspect the bitmap. (since 4.0)
34
#
35
+# Since: 5.0
36
+##
37
+{ 'struct': 'BlockExportNbd',
38
+ 'data': {'device': 'str', '*name': 'str', '*description': 'str',
39
+ '*writable': 'bool', '*bitmap': 'str' } }
40
+
41
+##
42
+# @nbd-server-add:
43
+#
44
+# Export a block node to QEMU's embedded NBD server.
45
+#
46
# Returns: error if the server is not running, or export with the same name
47
# already exists.
48
#
49
# Since: 1.3.0
50
##
51
{ 'command': 'nbd-server-add',
52
- 'data': {'device': 'str', '*name': 'str', '*description': 'str',
53
- '*writable': 'bool', '*bitmap': 'str' } }
54
+ 'data': 'BlockExportNbd', 'boxed': true }
55
56
##
57
# @NbdServerRemoveMode:
58
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/blockdev-nbd.c
61
+++ b/blockdev-nbd.c
62
@@ -XXX,XX +XXX,XX @@ void qmp_nbd_server_start(SocketAddressLegacy *addr,
63
qapi_free_SocketAddress(addr_flat);
64
}
65
66
-void qmp_nbd_server_add(const char *device, bool has_name, const char *name,
67
- bool has_description, const char *description,
68
- bool has_writable, bool writable,
69
- bool has_bitmap, const char *bitmap, Error **errp)
70
+void qmp_nbd_server_add(BlockExportNbd *arg, Error **errp)
71
{
72
BlockDriverState *bs = NULL;
73
BlockBackend *on_eject_blk;
74
@@ -XXX,XX +XXX,XX @@ void qmp_nbd_server_add(const char *device, bool has_name, const char *name,
75
return;
16
}
76
}
17
77
18
bs->read_only = read_only;
78
- if (!has_name) {
79
- name = device;
80
+ if (!arg->has_name) {
81
+ arg->name = arg->device;
82
}
83
84
- if (strlen(name) > NBD_MAX_STRING_SIZE) {
85
- error_setg(errp, "export name '%s' too long", name);
86
+ if (strlen(arg->name) > NBD_MAX_STRING_SIZE) {
87
+ error_setg(errp, "export name '%s' too long", arg->name);
88
return;
89
}
90
91
- if (has_description && strlen(description) > NBD_MAX_STRING_SIZE) {
92
- error_setg(errp, "description '%s' too long", description);
93
+ if (arg->description && strlen(arg->description) > NBD_MAX_STRING_SIZE) {
94
+ error_setg(errp, "description '%s' too long", arg->description);
95
return;
96
}
97
98
- if (nbd_export_find(name)) {
99
- error_setg(errp, "NBD server already has export named '%s'", name);
100
+ if (nbd_export_find(arg->name)) {
101
+ error_setg(errp, "NBD server already has export named '%s'", arg->name);
102
return;
103
}
104
105
- on_eject_blk = blk_by_name(device);
106
+ on_eject_blk = blk_by_name(arg->device);
107
108
- bs = bdrv_lookup_bs(device, device, errp);
109
+ bs = bdrv_lookup_bs(arg->device, arg->device, errp);
110
if (!bs) {
111
return;
112
}
113
@@ -XXX,XX +XXX,XX @@ void qmp_nbd_server_add(const char *device, bool has_name, const char *name,
114
goto out;
115
}
116
117
- if (!has_writable) {
118
- writable = false;
119
+ if (!arg->has_writable) {
120
+ arg->writable = false;
121
}
122
if (bdrv_is_read_only(bs)) {
123
- writable = false;
124
+ arg->writable = false;
125
}
126
127
- exp = nbd_export_new(bs, 0, len, name, description, bitmap,
128
- !writable, !writable,
129
+ exp = nbd_export_new(bs, 0, len, arg->name, arg->description, arg->bitmap,
130
+ !arg->writable, !arg->writable,
131
NULL, false, on_eject_blk, errp);
132
if (!exp) {
133
goto out;
134
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
135
index XXXXXXX..XXXXXXX 100644
136
--- a/monitor/hmp-cmds.c
137
+++ b/monitor/hmp-cmds.c
138
@@ -XXX,XX +XXX,XX @@ void hmp_nbd_server_start(Monitor *mon, const QDict *qdict)
139
Error *local_err = NULL;
140
BlockInfoList *block_list, *info;
141
SocketAddress *addr;
142
+ BlockExportNbd export;
143
144
if (writable && !all) {
145
error_setg(&local_err, "-w only valid together with -a");
146
@@ -XXX,XX +XXX,XX @@ void hmp_nbd_server_start(Monitor *mon, const QDict *qdict)
147
continue;
148
}
149
150
- qmp_nbd_server_add(info->value->device, false, NULL, false, NULL,
151
- true, writable, false, NULL, &local_err);
152
+ export = (BlockExportNbd) {
153
+ .device = info->value->device,
154
+ .has_writable = true,
155
+ .writable = writable,
156
+ };
19
+
157
+
20
+ if (read_only) {
158
+ qmp_nbd_server_add(&export, &local_err);
21
+ bs->open_flags &= ~BDRV_O_RDWR;
159
22
+ } else {
160
if (local_err != NULL) {
23
+ bs->open_flags |= BDRV_O_RDWR;
161
qmp_nbd_server_stop(NULL);
24
+ }
162
@@ -XXX,XX +XXX,XX @@ void hmp_nbd_server_add(Monitor *mon, const QDict *qdict)
163
bool writable = qdict_get_try_bool(qdict, "writable", false);
164
Error *local_err = NULL;
165
166
- qmp_nbd_server_add(device, !!name, name, false, NULL, true, writable,
167
- false, NULL, &local_err);
168
+ BlockExportNbd export = {
169
+ .device = (char *) device,
170
+ .has_name = !!name,
171
+ .name = (char *) name,
172
+ .has_writable = true,
173
+ .writable = writable,
174
+ };
25
+
175
+
26
return 0;
176
+ qmp_nbd_server_add(&export, &local_err);
177
hmp_handle_error(mon, local_err);
27
}
178
}
28
179
29
--
180
--
30
2.19.1
181
2.20.1
31
182
32
183
diff view generated by jsdifflib
1
If read-only=off, but auto-read-only=on is given, open the file
1
Add a --export option to qemu-storage-daemon to export a block node. For
2
read-write if we have the permissions, but instead of erroring out for
2
now, only NBD exports are implemented. Apart from the 'type' option
3
read-only files, just degrade to read-only.
3
(which is the implied key), it maps the arguments for nbd-server-add to
4
the command line. Example:
5
6
--export nbd,device=disk,name=test-export,writable=on
4
7
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Niels de Vos <ndevos@redhat.com>
9
Message-Id: <20200224143008.13362-12-kwolf@redhat.com>
10
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
12
---
8
block/gluster.c | 12 ++++++++++--
13
qapi/block-core.json | 27 +++++++++++++++++++++++++++
9
1 file changed, 10 insertions(+), 2 deletions(-)
14
qemu-storage-daemon.c | 31 +++++++++++++++++++++++++++++++
15
2 files changed, 58 insertions(+)
10
16
11
diff --git a/block/gluster.c b/block/gluster.c
17
diff --git a/qapi/block-core.json b/qapi/block-core.json
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/block/gluster.c
19
--- a/qapi/block-core.json
14
+++ b/block/gluster.c
20
+++ b/qapi/block-core.json
15
@@ -XXX,XX +XXX,XX @@ static int qemu_gluster_open(BlockDriverState *bs, QDict *options,
21
@@ -XXX,XX +XXX,XX @@
16
qemu_gluster_parse_flags(bdrv_flags, &open_flags);
22
##
17
23
{ 'command': 'nbd-server-stop' }
18
s->fd = glfs_open(s->glfs, gconf->path, open_flags);
24
19
- if (!s->fd) {
25
+##
20
- ret = -errno;
26
+# @BlockExportType:
21
+ ret = s->fd ? 0 : -errno;
27
+#
28
+# An enumeration of block export types
29
+#
30
+# @nbd: NBD export
31
+#
32
+# Since: 4.2
33
+##
34
+{ 'enum': 'BlockExportType',
35
+ 'data': [ 'nbd' ] }
22
+
36
+
23
+ if (ret == -EACCES || ret == -EROFS) {
37
+##
24
+ /* Try to degrade to read-only, but if it doesn't work, still use the
38
+# @BlockExport:
25
+ * normal error message. */
39
+#
26
+ if (bdrv_apply_auto_read_only(bs, NULL, NULL) == 0) {
40
+# Describes a block export, i.e. how single node should be exported on an
27
+ open_flags = (open_flags & ~O_RDWR) | O_RDONLY;
41
+# external interface.
28
+ s->fd = glfs_open(s->glfs, gconf->path, open_flags);
42
+#
29
+ ret = s->fd ? 0 : -errno;
43
+# Since: 4.2
30
+ }
44
+##
31
}
45
+{ 'union': 'BlockExport',
32
46
+ 'base': { 'type': 'BlockExportType' },
33
s->supports_seek_data = qemu_gluster_test_seek(s->fd);
47
+ 'discriminator': 'type',
48
+ 'data': {
49
+ 'nbd': 'BlockExportNbd'
50
+ } }
51
+
52
##
53
# @QuorumOpType:
54
#
55
diff --git a/qemu-storage-daemon.c b/qemu-storage-daemon.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/qemu-storage-daemon.c
58
+++ b/qemu-storage-daemon.c
59
@@ -XXX,XX +XXX,XX @@ static void help(void)
60
" [,driver specific parameters...]\n"
61
" configure a block backend\n"
62
"\n"
63
+" --export [type=]nbd,device=<node-name>[,name=<export-name>]\n"
64
+" [,writable=on|off][,bitmap=<name>]\n"
65
+" export the specified block node over NBD\n"
66
+" (requires --nbd-server)\n"
67
+"\n"
68
" --nbd-server addr.type=inet,addr.host=<host>,addr.port=<port>\n"
69
" [,tls-creds=<id>][,tls-authz=<id>]\n"
70
" --nbd-server addr.type=unix,addr.path=<path>\n"
71
@@ -XXX,XX +XXX,XX @@ QEMU_HELP_BOTTOM "\n",
72
73
enum {
74
OPTION_BLOCKDEV = 256,
75
+ OPTION_EXPORT,
76
OPTION_NBD_SERVER,
77
OPTION_OBJECT,
78
};
79
@@ -XXX,XX +XXX,XX @@ static QemuOptsList qemu_object_opts = {
80
},
81
};
82
83
+static void init_export(BlockExport *export, Error **errp)
84
+{
85
+ switch (export->type) {
86
+ case BLOCK_EXPORT_TYPE_NBD:
87
+ qmp_nbd_server_add(&export->u.nbd, errp);
88
+ break;
89
+ default:
90
+ g_assert_not_reached();
91
+ }
92
+}
93
+
94
static void process_options(int argc, char *argv[])
95
{
96
int c;
97
98
static const struct option long_options[] = {
99
{"blockdev", required_argument, NULL, OPTION_BLOCKDEV},
100
+ {"export", required_argument, NULL, OPTION_EXPORT},
101
{"help", no_argument, NULL, 'h'},
102
{"nbd-server", required_argument, NULL, OPTION_NBD_SERVER},
103
{"object", required_argument, NULL, OPTION_OBJECT},
104
@@ -XXX,XX +XXX,XX @@ static void process_options(int argc, char *argv[])
105
qapi_free_BlockdevOptions(options);
106
break;
107
}
108
+ case OPTION_EXPORT:
109
+ {
110
+ Visitor *v;
111
+ BlockExport *export;
112
+
113
+ v = qobject_input_visitor_new_str(optarg, "type", &error_fatal);
114
+ visit_type_BlockExport(v, NULL, &export, &error_fatal);
115
+ visit_free(v);
116
+
117
+ init_export(export, &error_fatal);
118
+ qapi_free_BlockExport(export);
119
+ break;
120
+ }
121
case OPTION_NBD_SERVER:
122
{
123
Visitor *v;
34
--
124
--
35
2.19.1
125
2.20.1
36
126
37
127
diff view generated by jsdifflib
1
If read-only=off, but auto-read-only=on is given, open the file
1
Instead of exiting after processing all command line options, start a
2
read-write if we have the permissions, but instead of erroring out for
2
main loop and keep processing events until exit is requested with a
3
read-only files, just degrade to read-only.
3
signal (e.g. SIGINT).
4
5
Now qemu-storage-daemon can be used as an alternative for qemu-nbd that
6
provides a few features that were previously only available from QMP,
7
such as access to options only available with -blockdev and the socket
8
types 'vsock' and 'fd'.
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>
11
Message-Id: <20200224143008.13362-13-kwolf@redhat.com>
12
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
14
---
8
block/file-posix.c | 19 ++++++++++++++++---
15
qemu-storage-daemon.c | 13 +++++++++++++
9
1 file changed, 16 insertions(+), 3 deletions(-)
16
Makefile.objs | 2 ++
17
2 files changed, 15 insertions(+)
10
18
11
diff --git a/block/file-posix.c b/block/file-posix.c
19
diff --git a/qemu-storage-daemon.c b/qemu-storage-daemon.c
12
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
13
--- a/block/file-posix.c
21
--- a/qemu-storage-daemon.c
14
+++ b/block/file-posix.c
22
+++ b/qemu-storage-daemon.c
15
@@ -XXX,XX +XXX,XX @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
23
@@ -XXX,XX +XXX,XX @@
16
24
#include "qemu/option.h"
17
s->fd = -1;
25
#include "qom/object_interfaces.h"
18
fd = qemu_open(filename, s->open_flags, 0644);
26
19
- if (fd < 0) {
27
+#include "sysemu/runstate.h"
20
- ret = -errno;
28
#include "trace/control.h"
21
- error_setg_errno(errp, errno, "Could not open '%s'", filename);
29
22
+ ret = fd < 0 ? -errno : 0;
30
+static volatile bool exit_requested = false;
23
+
31
+
24
+ if (ret == -EACCES || ret == -EROFS) {
32
+void qemu_system_killed(int signal, pid_t pid)
25
+ /* Try to degrade to read-only, but if it doesn't work, still use the
33
+{
26
+ * normal error message. */
34
+ exit_requested = true;
27
+ if (bdrv_apply_auto_read_only(bs, NULL, NULL) == 0) {
35
+}
28
+ bdrv_flags &= ~BDRV_O_RDWR;
36
+
29
+ raw_parse_flags(bdrv_flags, &s->open_flags);
37
static void help(void)
30
+ assert(!(s->open_flags & O_CREAT));
38
{
31
+ fd = qemu_open(filename, s->open_flags);
39
printf(
32
+ ret = fd < 0 ? -errno : 0;
40
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
33
+ }
41
42
error_init(argv[0]);
43
qemu_init_exec_dir(argv[0]);
44
+ os_setup_signal_handling();
45
46
module_call_init(MODULE_INIT_QOM);
47
module_call_init(MODULE_INIT_TRACE);
48
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
49
qemu_init_main_loop(&error_fatal);
50
process_options(argc, argv);
51
52
+ while (!exit_requested) {
53
+ main_loop_wait(false);
34
+ }
54
+ }
35
+
55
+
36
+ if (ret < 0) {
56
return EXIT_SUCCESS;
37
+ error_setg_errno(errp, -ret, "Could not open '%s'", filename);
57
}
38
if (ret == -EROFS) {
58
diff --git a/Makefile.objs b/Makefile.objs
39
ret = -EACCES;
59
index XXXXXXX..XXXXXXX 100644
40
}
60
--- a/Makefile.objs
61
+++ b/Makefile.objs
62
@@ -XXX,XX +XXX,XX @@ endif # CONFIG_SOFTMMU or CONFIG_TOOLS
63
64
storage-daemon-obj-y = block/ qom/
65
storage-daemon-obj-y += blockdev.o blockdev-nbd.o iothread.o
66
+storage-daemon-obj-$(CONFIG_WIN32) += os-win32.o
67
+storage-daemon-obj-$(CONFIG_POSIX) += os-posix.o
68
69
######################################################################
70
# Target independent part of system emulation. The long term path is to
41
--
71
--
42
2.19.1
72
2.20.1
43
73
44
74
diff view generated by jsdifflib
1
From: Cleber Rosa <crosa@redhat.com>
1
This adds a --chardev option to the storage daemon that works the same
2
as the -chardev option of the system emulator.
2
3
3
While testing the Python 3 changes which touch the 083 test, I noticed
4
The syntax of the --chardev option is still considered unstable. We want
4
that it would fail with qcow2. Expanding the testing, I noticed it
5
to QAPIfy it and will potentially make changes to its syntax while
5
had nothing to do with the Python 3 changes, and in fact, it would not
6
converting it. However, we haven't decided yet on a design for the
6
pass on anything but raw:
7
QAPIfication, so QemuOpts will have to do for now.
7
8
8
raw: pass
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
bochs: not generic
10
Message-Id: <20200224143008.13362-14-kwolf@redhat.com>
10
cloop: not generic
11
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
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>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
41
---
13
---
42
tests/qemu-iotests/083 | 2 +-
14
qemu-storage-daemon.c | 24 ++++++++++++++++++++++++
43
1 file changed, 1 insertion(+), 1 deletion(-)
15
Makefile | 2 +-
16
2 files changed, 25 insertions(+), 1 deletion(-)
44
17
45
diff --git a/tests/qemu-iotests/083 b/tests/qemu-iotests/083
18
diff --git a/qemu-storage-daemon.c b/qemu-storage-daemon.c
46
index XXXXXXX..XXXXXXX 100755
19
index XXXXXXX..XXXXXXX 100644
47
--- a/tests/qemu-iotests/083
20
--- a/qemu-storage-daemon.c
48
+++ b/tests/qemu-iotests/083
21
+++ b/qemu-storage-daemon.c
49
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
22
@@ -XXX,XX +XXX,XX @@
50
. ./common.rc
23
51
. ./common.filter
24
#include "block/block.h"
52
25
#include "block/nbd.h"
53
-_supported_fmt generic
26
+#include "chardev/char.h"
54
+_supported_fmt raw
27
#include "crypto/init.h"
55
_supported_proto nbd
28
56
_supported_os Linux
29
#include "qapi/error.h"
30
@@ -XXX,XX +XXX,XX @@ static void help(void)
31
" [,driver specific parameters...]\n"
32
" configure a block backend\n"
33
"\n"
34
+" --chardev <options> configure a character device backend\n"
35
+" (see the qemu(1) man page for possible options)\n"
36
+"\n"
37
" --export [type=]nbd,device=<node-name>[,name=<export-name>]\n"
38
" [,writable=on|off][,bitmap=<name>]\n"
39
" export the specified block node over NBD\n"
40
@@ -XXX,XX +XXX,XX @@ QEMU_HELP_BOTTOM "\n",
41
42
enum {
43
OPTION_BLOCKDEV = 256,
44
+ OPTION_CHARDEV,
45
OPTION_EXPORT,
46
OPTION_NBD_SERVER,
47
OPTION_OBJECT,
48
};
49
50
+extern QemuOptsList qemu_chardev_opts;
51
+
52
static QemuOptsList qemu_object_opts = {
53
.name = "object",
54
.implied_opt_name = "qom-type",
55
@@ -XXX,XX +XXX,XX @@ static void process_options(int argc, char *argv[])
56
57
static const struct option long_options[] = {
58
{"blockdev", required_argument, NULL, OPTION_BLOCKDEV},
59
+ {"chardev", required_argument, NULL, OPTION_CHARDEV},
60
{"export", required_argument, NULL, OPTION_EXPORT},
61
{"help", no_argument, NULL, 'h'},
62
{"nbd-server", required_argument, NULL, OPTION_NBD_SERVER},
63
@@ -XXX,XX +XXX,XX @@ static void process_options(int argc, char *argv[])
64
qapi_free_BlockdevOptions(options);
65
break;
66
}
67
+ case OPTION_CHARDEV:
68
+ {
69
+ /* TODO This interface is not stable until we QAPIfy it */
70
+ QemuOpts *opts = qemu_opts_parse_noisily(&qemu_chardev_opts,
71
+ optarg, true);
72
+ if (opts == NULL) {
73
+ exit(EXIT_FAILURE);
74
+ }
75
+
76
+ if (!qemu_chr_new_from_opts(opts, NULL, &error_fatal)) {
77
+ /* No error, but NULL returned means help was printed */
78
+ exit(EXIT_SUCCESS);
79
+ }
80
+ qemu_opts_del(opts);
81
+ break;
82
+ }
83
case OPTION_EXPORT:
84
{
85
Visitor *v;
86
diff --git a/Makefile b/Makefile
87
index XXXXXXX..XXXXXXX 100644
88
--- a/Makefile
89
+++ b/Makefile
90
@@ -XXX,XX +XXX,XX @@ qemu-img.o: qemu-img-cmds.h
91
qemu-img$(EXESUF): qemu-img.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
92
qemu-nbd$(EXESUF): qemu-nbd.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
93
qemu-io$(EXESUF): qemu-io.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
94
-qemu-storage-daemon$(EXESUF): qemu-storage-daemon.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(storage-daemon-obj-y) $(COMMON_LDADDS)
95
+qemu-storage-daemon$(EXESUF): qemu-storage-daemon.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(chardev-obj-y) $(io-obj-y) $(qom-obj-y) $(storage-daemon-obj-y) $(COMMON_LDADDS)
96
97
qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o $(COMMON_LDADDS)
57
98
58
--
99
--
59
2.19.1
100
2.20.1
60
101
61
102
diff view generated by jsdifflib
1
From: Peter Maydell <peter.maydell@linaro.org>
1
Before we can add the monitor to qemu-storage-daemon, we need to add a
2
stubs for monitor_fdsets_cleanup().
2
3
3
Taking the address of a field in a packed struct is a bad idea, because
4
We also need to make sure that stubs that are actually implemented in
4
it might not be actually aligned enough for that pointer type (and
5
the monitor core aren't linked to qemu-storage-daemon so that we don't
5
thus cause a crash on dereference on some host architectures). Newer
6
get linker errors because of duplicate symbols. This is achieved by
6
versions of clang warn about this. Avoid the bug by not using the
7
moving the stubs in question to a new file stubs/monitor-core.c.
7
"modify in place" byte swapping functions.
8
8
9
There are a few places where the in-place swap function is
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
used on something other than a packed struct field; we convert
10
Message-Id: <20200224143008.13362-15-kwolf@redhat.com>
11
those anyway, for consistency.
11
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
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>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
51
---
13
---
52
block/qcow2-bitmap.c | 24 ++++++++++++------------
14
stubs/monitor-core.c | 21 +++++++++++++++++++++
53
1 file changed, 12 insertions(+), 12 deletions(-)
15
stubs/monitor.c | 15 ++-------------
16
stubs/Makefile.objs | 1 +
17
3 files changed, 24 insertions(+), 13 deletions(-)
18
create mode 100644 stubs/monitor-core.c
54
19
55
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
20
diff --git a/stubs/monitor-core.c b/stubs/monitor-core.c
21
new file mode 100644
22
index XXXXXXX..XXXXXXX
23
--- /dev/null
24
+++ b/stubs/monitor-core.c
25
@@ -XXX,XX +XXX,XX @@
26
+#include "qemu/osdep.h"
27
+#include "monitor/monitor.h"
28
+#include "qemu-common.h"
29
+#include "qapi/qapi-emit-events.h"
30
+
31
+__thread Monitor *cur_mon;
32
+
33
+void monitor_init_qmp(Chardev *chr, bool pretty)
34
+{
35
+}
36
+
37
+void qapi_event_emit(QAPIEvent event, QDict *qdict)
38
+{
39
+}
40
+
41
+int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
42
+{
43
+ abort();
44
+}
45
+
46
+
47
diff --git a/stubs/monitor.c b/stubs/monitor.c
56
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
57
--- a/block/qcow2-bitmap.c
49
--- a/stubs/monitor.c
58
+++ b/block/qcow2-bitmap.c
50
+++ b/stubs/monitor.c
59
@@ -XXX,XX +XXX,XX @@ static inline void bitmap_table_to_be(uint64_t *bitmap_table, size_t size)
51
@@ -XXX,XX +XXX,XX @@
60
size_t i;
52
#include "qemu/osdep.h"
61
53
#include "qapi/error.h"
62
for (i = 0; i < size; ++i) {
54
-#include "qapi/qapi-emit-events.h"
63
- cpu_to_be64s(&bitmap_table[i]);
55
#include "monitor/monitor.h"
64
+ bitmap_table[i] = cpu_to_be64(bitmap_table[i]);
56
-
65
}
57
-__thread Monitor *cur_mon;
58
-
59
-int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
60
-{
61
- abort();
62
-}
63
+#include "../monitor/monitor-internal.h"
64
65
int monitor_get_fd(Monitor *mon, const char *name, Error **errp)
66
{
67
@@ -XXX,XX +XXX,XX @@ int monitor_get_fd(Monitor *mon, const char *name, Error **errp)
68
return -1;
66
}
69
}
67
70
68
@@ -XXX,XX +XXX,XX @@ static int bitmap_table_load(BlockDriverState *bs, Qcow2BitmapTable *tb,
71
-void monitor_init_qmp(Chardev *chr, bool pretty)
69
}
72
-{
70
73
-}
71
for (i = 0; i < tb->size; ++i) {
74
-
72
- be64_to_cpus(&table[i]);
75
void monitor_init_hmp(Chardev *chr, bool use_readline)
73
+ table[i] = be64_to_cpu(table[i]);
74
ret = check_table_entry(table[i], s->cluster_size);
75
if (ret < 0) {
76
goto fail;
77
@@ -XXX,XX +XXX,XX @@ fail:
78
79
static inline void bitmap_dir_entry_to_cpu(Qcow2BitmapDirEntry *entry)
80
{
76
{
81
- be64_to_cpus(&entry->bitmap_table_offset);
82
- be32_to_cpus(&entry->bitmap_table_size);
83
- be32_to_cpus(&entry->flags);
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
}
77
}
92
78
93
static inline void bitmap_dir_entry_to_be(Qcow2BitmapDirEntry *entry)
79
-void qapi_event_emit(QAPIEvent event, QDict *qdict)
80
+void monitor_fdsets_cleanup(void)
94
{
81
{
95
- cpu_to_be64s(&entry->bitmap_table_offset);
96
- cpu_to_be32s(&entry->bitmap_table_size);
97
- cpu_to_be32s(&entry->flags);
98
- cpu_to_be16s(&entry->name_size);
99
- cpu_to_be32s(&entry->extra_data_size);
100
+ entry->bitmap_table_offset = cpu_to_be64(entry->bitmap_table_offset);
101
+ entry->bitmap_table_size = cpu_to_be32(entry->bitmap_table_size);
102
+ entry->flags = cpu_to_be32(entry->flags);
103
+ entry->name_size = cpu_to_be16(entry->name_size);
104
+ entry->extra_data_size = cpu_to_be32(entry->extra_data_size);
105
}
82
}
106
83
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
107
static inline int calc_dir_entry_size(size_t name_size, size_t extra_data_size)
84
index XXXXXXX..XXXXXXX 100644
85
--- a/stubs/Makefile.objs
86
+++ b/stubs/Makefile.objs
87
@@ -XXX,XX +XXX,XX @@ stub-obj-y += machine-init-done.o
88
stub-obj-y += migr-blocker.o
89
stub-obj-y += change-state-handler.o
90
stub-obj-y += monitor.o
91
+stub-obj-y += monitor-core.o
92
stub-obj-y += notify-event.o
93
stub-obj-y += qtest.o
94
stub-obj-y += replay.o
108
--
95
--
109
2.19.1
96
2.20.1
110
97
111
98
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
Deleted patch
1
From: Alberto Garcia <berto@igalia.com>
2
1
3
This doesn't have any practical effect at the moment because the
4
values of BDRV_SECTOR_SIZE, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE and
5
QCRYPTO_BLOCK_QCOW_SECTOR_SIZE are all the same (512 bytes), but
6
future encryption methods could have different requirements.
7
8
Signed-off-by: Alberto Garcia <berto@igalia.com>
9
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
block/qcow2.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/block/qcow2.c b/block/qcow2.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/block/qcow2.c
18
+++ b/block/qcow2.c
19
@@ -XXX,XX +XXX,XX @@ static void qcow2_refresh_limits(BlockDriverState *bs, Error **errp)
20
21
if (bs->encrypted) {
22
/* Encryption works on a sector granularity */
23
- bs->bl.request_alignment = BDRV_SECTOR_SIZE;
24
+ bs->bl.request_alignment = qcrypto_block_get_sector_size(s->crypto);
25
}
26
bs->bl.pwrite_zeroes_alignment = s->cluster_size;
27
bs->bl.pdiscard_alignment = s->cluster_size;
28
--
29
2.19.1
30
31
diff view generated by jsdifflib
1
If read-only=off, but auto-read-only=on is given, just degrade to
1
We want to share the whitelists between the system emulator schema and
2
read-only.
2
the storage daemon schema, so move all the pragmas from the main schema
3
file into a separate file that can be included from both.
3
4
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Eric Blake <eblake@redhat.com>
6
Message-Id: <20200224143008.13362-16-kwolf@redhat.com>
7
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
---
9
---
7
block/curl.c | 8 ++++----
10
qapi/pragma.json | 24 ++++++++++++++++++++++++
8
1 file changed, 4 insertions(+), 4 deletions(-)
11
qapi/qapi-schema.json | 25 +------------------------
12
qapi/Makefile.objs | 2 +-
13
3 files changed, 26 insertions(+), 25 deletions(-)
14
create mode 100644 qapi/pragma.json
9
15
10
diff --git a/block/curl.c b/block/curl.c
16
diff --git a/qapi/pragma.json b/qapi/pragma.json
17
new file mode 100644
18
index XXXXXXX..XXXXXXX
19
--- /dev/null
20
+++ b/qapi/pragma.json
21
@@ -XXX,XX +XXX,XX @@
22
+{ 'pragma': { 'doc-required': true } }
23
+
24
+# Whitelists to permit QAPI rule violations; think twice before you
25
+# add to them!
26
+{ 'pragma': {
27
+ # Commands allowed to return a non-dictionary:
28
+ 'returns-whitelist': [
29
+ 'human-monitor-command',
30
+ 'qom-get',
31
+ 'query-migrate-cache-size',
32
+ 'query-tpm-models',
33
+ 'query-tpm-types',
34
+ 'ringbuf-read' ],
35
+ 'name-case-whitelist': [
36
+ 'ACPISlotType', # DIMM, visible through query-acpi-ospm-status
37
+ 'CpuInfoMIPS', # PC, visible through query-cpu
38
+ 'CpuInfoTricore', # PC, visible through query-cpu
39
+ 'BlockdevVmdkSubformat', # all members, to match VMDK spec spellings
40
+ 'BlockdevVmdkAdapterType', # legacyESX, to match VMDK spec spellings
41
+ 'QapiErrorClass', # all members, visible through errors
42
+ 'UuidInfo', # UUID, visible through query-uuid
43
+ 'X86CPURegister32', # all members, visible indirectly through qom-get
44
+ 'CpuInfo' # CPU, visible through query-cpu
45
+ ] } }
46
diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json
11
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
12
--- a/block/curl.c
48
--- a/qapi/qapi-schema.json
13
+++ b/block/curl.c
49
+++ b/qapi/qapi-schema.json
14
@@ -XXX,XX +XXX,XX @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
50
@@ -XXX,XX +XXX,XX @@
15
const char *protocol_delimiter;
51
#
16
int ret;
52
##
17
53
54
-{ 'pragma': { 'doc-required': true } }
18
-
55
-
19
- if (flags & BDRV_O_RDWR) {
56
-# Whitelists to permit QAPI rule violations; think twice before you
20
- error_setg(errp, "curl block device does not support writes");
57
-# add to them!
21
- return -EROFS;
58
-{ 'pragma': {
22
+ ret = bdrv_apply_auto_read_only(bs, "curl driver does not support writes",
59
- # Commands allowed to return a non-dictionary:
23
+ errp);
60
- 'returns-whitelist': [
24
+ if (ret < 0) {
61
- 'human-monitor-command',
25
+ return ret;
62
- 'qom-get',
26
}
63
- 'query-migrate-cache-size',
27
64
- 'query-tpm-models',
28
if (!libcurl_initialized) {
65
- 'query-tpm-types',
66
- 'ringbuf-read' ],
67
- 'name-case-whitelist': [
68
- 'ACPISlotType', # DIMM, visible through query-acpi-ospm-status
69
- 'CpuInfoMIPS', # PC, visible through query-cpu
70
- 'CpuInfoTricore', # PC, visible through query-cpu
71
- 'BlockdevVmdkSubformat', # all members, to match VMDK spec spellings
72
- 'BlockdevVmdkAdapterType', # legacyESX, to match VMDK spec spellings
73
- 'QapiErrorClass', # all members, visible through errors
74
- 'UuidInfo', # UUID, visible through query-uuid
75
- 'X86CPURegister32', # all members, visible indirectly through qom-get
76
- 'CpuInfo' # CPU, visible through query-cpu
77
- ] } }
78
+{ 'include': 'pragma.json' }
79
80
# Documentation generated with qapi-gen.py is in source order, with
81
# included sub-schemas inserted at the first include directive
82
diff --git a/qapi/Makefile.objs b/qapi/Makefile.objs
83
index XXXXXXX..XXXXXXX 100644
84
--- a/qapi/Makefile.objs
85
+++ b/qapi/Makefile.objs
86
@@ -XXX,XX +XXX,XX @@ util-obj-y += qapi-util.o
87
88
QAPI_COMMON_MODULES = audio authz block-core block char common control crypto
89
QAPI_COMMON_MODULES += dump error introspect job machine migration misc
90
-QAPI_COMMON_MODULES += net qdev qom rdma rocker run-state sockets tpm
91
+QAPI_COMMON_MODULES += net pragma qdev qom rdma rocker run-state sockets tpm
92
QAPI_COMMON_MODULES += trace transaction ui
93
QAPI_TARGET_MODULES = machine-target misc-target
94
QAPI_MODULES = $(QAPI_COMMON_MODULES) $(QAPI_TARGET_MODULES)
29
--
95
--
30
2.19.1
96
2.20.1
31
97
32
98
diff view generated by jsdifflib
1
From: Li Qiang <liq3ea@163.com>
1
This adds a new QAPI-based monitor_init() function. The existing
2
monitor_init_opts() is rewritten to simply put its QemuOpts parameter
3
into a visitor and pass the resulting QAPI object to monitor_init().
2
4
3
Signed-off-by: Li Qiang <liq3ea@163.com>
5
This will cause some change in those error messages for the monitor
4
Reviewed-by: Alberto Garcia <berto@igalia.com>
6
options in the system emulator that are now generated by the visitor
7
rather than explicitly checked in monitor_init_opts().
8
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Message-Id: <20200224143008.13362-17-kwolf@redhat.com>
11
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
---
13
---
7
include/sysemu/block-backend.h | 6 +++---
14
qapi/control.json | 36 ++++++++++++++++++
8
block/block-backend.c | 8 ++++----
15
include/monitor/monitor.h | 2 +
9
2 files changed, 7 insertions(+), 7 deletions(-)
16
monitor/monitor.c | 77 +++++++++++++++++++++------------------
17
3 files changed, 80 insertions(+), 35 deletions(-)
10
18
11
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
19
diff --git a/qapi/control.json b/qapi/control.json
12
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
13
--- a/include/sysemu/block-backend.h
21
--- a/qapi/control.json
14
+++ b/include/sysemu/block-backend.h
22
+++ b/qapi/control.json
15
@@ -XXX,XX +XXX,XX @@ BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
23
@@ -XXX,XX +XXX,XX @@
16
int error);
24
# <- { "return": {} }
17
void blk_error_action(BlockBackend *blk, BlockErrorAction action,
25
##
18
bool is_read, int error);
26
{ 'command': 'quit' }
19
-int blk_is_read_only(BlockBackend *blk);
27
+
20
-int blk_is_sg(BlockBackend *blk);
28
+##
21
-int blk_enable_write_cache(BlockBackend *blk);
29
+# @MonitorMode:
22
+bool blk_is_read_only(BlockBackend *blk);
30
+#
23
+bool blk_is_sg(BlockBackend *blk);
31
+# An enumeration of monitor modes.
24
+bool blk_enable_write_cache(BlockBackend *blk);
32
+#
25
void blk_set_enable_write_cache(BlockBackend *blk, bool wce);
33
+# @readline: HMP monitor (human-oriented command line interface)
26
void blk_invalidate_cache(BlockBackend *blk, Error **errp);
34
+#
27
bool blk_is_inserted(BlockBackend *blk);
35
+# @control: QMP monitor (JSON-based machine interface)
28
diff --git a/block/block-backend.c b/block/block-backend.c
36
+#
37
+# Since: 5.0
38
+##
39
+{ 'enum': 'MonitorMode', 'data': [ 'readline', 'control' ] }
40
+
41
+##
42
+# @MonitorOptions:
43
+#
44
+# Options to be used for adding a new monitor.
45
+#
46
+# @id: Name of the monitor
47
+#
48
+# @mode: Selects the monitor mode (default: readline)
49
+#
50
+# @pretty: Enables pretty printing (QMP only)
51
+#
52
+# @chardev: Name of a character device to expose the monitor on
53
+#
54
+# Since: 5.0
55
+##
56
+{ 'struct': 'MonitorOptions',
57
+ 'data': {
58
+ '*id': 'str',
59
+ '*mode': 'MonitorMode',
60
+ '*pretty': 'bool',
61
+ 'chardev': 'str'
62
+ } }
63
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
29
index XXXXXXX..XXXXXXX 100644
64
index XXXXXXX..XXXXXXX 100644
30
--- a/block/block-backend.c
65
--- a/include/monitor/monitor.h
31
+++ b/block/block-backend.c
66
+++ b/include/monitor/monitor.h
32
@@ -XXX,XX +XXX,XX @@ void blk_error_action(BlockBackend *blk, BlockErrorAction action,
67
@@ -XXX,XX +XXX,XX @@
68
69
extern __thread Monitor *cur_mon;
70
typedef struct MonitorHMP MonitorHMP;
71
+typedef struct MonitorOptions MonitorOptions;
72
73
#define QMP_REQ_QUEUE_LEN_MAX 8
74
75
@@ -XXX,XX +XXX,XX @@ void monitor_init_globals(void);
76
void monitor_init_globals_core(void);
77
void monitor_init_qmp(Chardev *chr, bool pretty);
78
void monitor_init_hmp(Chardev *chr, bool use_readline);
79
+int monitor_init(MonitorOptions *opts, Error **errp);
80
int monitor_init_opts(QemuOpts *opts, Error **errp);
81
void monitor_cleanup(void);
82
83
diff --git a/monitor/monitor.c b/monitor/monitor.c
84
index XXXXXXX..XXXXXXX 100644
85
--- a/monitor/monitor.c
86
+++ b/monitor/monitor.c
87
@@ -XXX,XX +XXX,XX @@
88
#include "qemu/osdep.h"
89
#include "monitor-internal.h"
90
#include "qapi/error.h"
91
+#include "qapi/opts-visitor.h"
92
#include "qapi/qapi-emit-events.h"
93
+#include "qapi/qapi-visit-control.h"
94
#include "qapi/qmp/qdict.h"
95
#include "qapi/qmp/qstring.h"
96
#include "qemu/error-report.h"
97
@@ -XXX,XX +XXX,XX @@ void monitor_init_globals_core(void)
98
NULL);
99
}
100
101
-int monitor_init_opts(QemuOpts *opts, Error **errp)
102
+int monitor_init(MonitorOptions *opts, Error **errp)
103
{
104
Chardev *chr;
105
- bool qmp;
106
- bool pretty = false;
107
- const char *chardev;
108
- const char *mode;
109
-
110
- mode = qemu_opt_get(opts, "mode");
111
- if (mode == NULL) {
112
- mode = "readline";
113
- }
114
- if (strcmp(mode, "readline") == 0) {
115
- qmp = false;
116
- } else if (strcmp(mode, "control") == 0) {
117
- qmp = true;
118
- } else {
119
- error_setg(errp, "unknown monitor mode \"%s\"", mode);
120
+
121
+ chr = qemu_chr_find(opts->chardev);
122
+ if (chr == NULL) {
123
+ error_setg(errp, "chardev \"%s\" not found", opts->chardev);
124
return -1;
33
}
125
}
34
}
126
35
127
- if (!qmp && qemu_opt_get(opts, "pretty")) {
36
-int blk_is_read_only(BlockBackend *blk)
128
- warn_report("'pretty' is deprecated for HMP monitors, it has no effect "
37
+bool blk_is_read_only(BlockBackend *blk)
129
- "and will be removed in future versions");
38
{
130
- }
39
BlockDriverState *bs = blk_bs(blk);
131
- if (qemu_opt_get_bool(opts, "pretty", 0)) {
40
132
- pretty = true;
41
@@ -XXX,XX +XXX,XX @@ int blk_is_read_only(BlockBackend *blk)
133
+ switch (opts->mode) {
134
+ case MONITOR_MODE_CONTROL:
135
+ monitor_init_qmp(chr, opts->pretty);
136
+ break;
137
+ case MONITOR_MODE_READLINE:
138
+ if (opts->pretty) {
139
+ warn_report("'pretty' is deprecated for HMP monitors, it has no "
140
+ "effect and will be removed in future versions");
141
+ }
142
+ monitor_init_hmp(chr, true);
143
+ break;
144
+ default:
145
+ g_assert_not_reached();
42
}
146
}
43
}
147
44
148
- chardev = qemu_opt_get(opts, "chardev");
45
-int blk_is_sg(BlockBackend *blk)
149
- if (!chardev) {
46
+bool blk_is_sg(BlockBackend *blk)
150
- error_report("chardev is required");
47
{
151
- exit(1);
48
BlockDriverState *bs = blk_bs(blk);
152
- }
49
153
- chr = qemu_chr_find(chardev);
50
if (!bs) {
154
- if (chr == NULL) {
51
- return 0;
155
- error_setg(errp, "chardev \"%s\" not found", chardev);
52
+ return false;
156
- return -1;
157
+ return 0;
158
+}
159
+
160
+int monitor_init_opts(QemuOpts *opts, Error **errp)
161
+{
162
+ Visitor *v;
163
+ MonitorOptions *options;
164
+ Error *local_err = NULL;
165
+
166
+ v = opts_visitor_new(opts);
167
+ visit_type_MonitorOptions(v, NULL, &options, &local_err);
168
+ visit_free(v);
169
+
170
+ if (local_err) {
171
+ goto out;
53
}
172
}
54
173
55
return bdrv_is_sg(bs);
174
- if (qmp) {
56
}
175
- monitor_init_qmp(chr, pretty);
57
176
- } else {
58
-int blk_enable_write_cache(BlockBackend *blk)
177
- monitor_init_hmp(chr, true);
59
+bool blk_enable_write_cache(BlockBackend *blk)
178
+ monitor_init(options, &local_err);
60
{
179
+ qapi_free_MonitorOptions(options);
61
return blk->enable_write_cache;
180
+
181
+out:
182
+ if (local_err) {
183
+ error_propagate(errp, local_err);
184
+ return -1;
185
}
186
return 0;
62
}
187
}
63
--
188
--
64
2.19.1
189
2.20.1
65
190
66
191
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
Deleted patch
1
From: Peter Maydell <peter.maydell@linaro.org>
2
1
3
Taking the address of a field in a packed struct is a bad idea, because
4
it might not be actually aligned enough for that pointer type (and
5
thus cause a crash on dereference on some host architectures). Newer
6
versions of clang warn about this. Avoid the bug by not using the
7
"modify in place" byte swapping functions.
8
9
There are a few places where the in-place swap function is
10
used on something other than a packed struct field; we convert
11
those anyway, for consistency.
12
13
Patch produced with scripts/coccinelle/inplace-byteswaps.cocci.
14
15
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>
22
---
23
block/vdi.c | 64 ++++++++++++++++++++++++++---------------------------
24
1 file changed, 32 insertions(+), 32 deletions(-)
25
26
diff --git a/block/vdi.c b/block/vdi.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/block/vdi.c
29
+++ b/block/vdi.c
30
@@ -XXX,XX +XXX,XX @@ typedef struct {
31
32
static void vdi_header_to_cpu(VdiHeader *header)
33
{
34
- le32_to_cpus(&header->signature);
35
- le32_to_cpus(&header->version);
36
- le32_to_cpus(&header->header_size);
37
- le32_to_cpus(&header->image_type);
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
--
109
2.19.1
110
111
diff view generated by jsdifflib
Deleted patch
1
From: Alberto Garcia <berto@igalia.com>
2
1
3
The blkverify mode of Quorum can only be enabled if the number of
4
children is exactly two and the value of vote-threshold is also two.
5
6
If the user tries to enable it but the other settings are incorrect
7
then QEMU simply prints an error message to stderr and carries on
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>
15
---
16
block/quorum.c | 13 ++++++-------
17
1 file changed, 6 insertions(+), 7 deletions(-)
18
19
diff --git a/block/quorum.c b/block/quorum.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/block/quorum.c
22
+++ b/block/quorum.c
23
@@ -XXX,XX +XXX,XX @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags,
24
s->read_pattern = ret;
25
26
if (s->read_pattern == QUORUM_READ_PATTERN_QUORUM) {
27
- /* is the driver in blkverify mode */
28
- if (qemu_opt_get_bool(opts, QUORUM_OPT_BLKVERIFY, false) &&
29
- s->num_children == 2 && s->threshold == 2) {
30
- s->is_blkverify = true;
31
- } else if (qemu_opt_get_bool(opts, QUORUM_OPT_BLKVERIFY, false)) {
32
- fprintf(stderr, "blkverify mode is set by setting blkverify=on "
33
- "and using two files with vote_threshold=2\n");
34
+ s->is_blkverify = qemu_opt_get_bool(opts, QUORUM_OPT_BLKVERIFY, false);
35
+ if (s->is_blkverify && (s->num_children != 2 || s->threshold != 2)) {
36
+ error_setg(&local_err, "blkverify=on can only be set if there are "
37
+ "exactly two files and vote-threshold is 2");
38
+ ret = -EINVAL;
39
+ goto exit;
40
}
41
42
s->rewrite_corrupted = qemu_opt_get_bool(opts, QUORUM_OPT_REWRITE,
43
--
44
2.19.1
45
46
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
Trying to attach a QMP monitor to a chardev that is already in use
2
results in a crash because monitor_init_qmp() passes &error_abort to
3
qemu_chr_fe_init():
2
4
3
This adds some whitespace into the option help (including indentation)
5
$ ./x86_64-softmmu/qemu-system-x86_64 --chardev stdio,id=foo --mon foo,mode=control --mon foo,mode=control
4
and puts angle brackets around the type names. Furthermore, the list
6
Unexpected error in qemu_chr_fe_init() at chardev/char-fe.c:220:
5
name is no longer printed as part of every line, but only once in
7
qemu-system-x86_64: --mon foo,mode=control: Device 'foo' is in use
6
advance, and only if the caller did not print a caption already.
8
Abgebrochen (Speicherabzug geschrieben)
7
9
8
This patch also restores the description alignment we had before commit
10
Fix this by allowing monitor_init_qmp() to return an error and passing
9
9cbef9d68ee1d8d0, just at 24 instead of 16 characters like we used to.
11
any error in qemu_chr_fe_init() to its caller instead of aborting.
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
12
17
Finally, this patch amends the reference output of iotest 082 to match
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
the changes (and thus makes it pass again).
14
Message-Id: <20200224143008.13362-18-kwolf@redhat.com>
19
15
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
20
Signed-off-by: Max Reitz <mreitz@redhat.com>
21
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
22
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
23
---
17
---
24
include/qemu/option.h | 2 +-
18
include/monitor/monitor.h | 2 +-
25
qemu-img.c | 4 +-
19
monitor/monitor.c | 7 ++++++-
26
util/qemu-option.c | 32 +-
20
monitor/qmp.c | 11 +++++++----
27
tests/qemu-iotests/082.out | 956 ++++++++++++++++++-------------------
21
stubs/monitor-core.c | 2 +-
28
4 files changed, 507 insertions(+), 487 deletions(-)
22
tests/test-util-sockets.c | 2 +-
23
5 files changed, 16 insertions(+), 8 deletions(-)
29
24
30
diff --git a/include/qemu/option.h b/include/qemu/option.h
25
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
31
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
32
--- a/include/qemu/option.h
27
--- a/include/monitor/monitor.h
33
+++ b/include/qemu/option.h
28
+++ b/include/monitor/monitor.h
34
@@ -XXX,XX +XXX,XX @@ typedef int (*qemu_opts_loopfunc)(void *opaque, QemuOpts *opts, Error **errp);
29
@@ -XXX,XX +XXX,XX @@ bool monitor_cur_is_qmp(void);
35
int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func,
30
36
void *opaque, Error **errp);
31
void monitor_init_globals(void);
37
void qemu_opts_print(QemuOpts *opts, const char *sep);
32
void monitor_init_globals_core(void);
38
-void qemu_opts_print_help(QemuOptsList *list);
33
-void monitor_init_qmp(Chardev *chr, bool pretty);
39
+void qemu_opts_print_help(QemuOptsList *list, bool print_caption);
34
+void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp);
40
void qemu_opts_free(QemuOptsList *list);
35
void monitor_init_hmp(Chardev *chr, bool use_readline);
41
QemuOptsList *qemu_opts_append(QemuOptsList *dst, QemuOptsList *list);
36
int monitor_init(MonitorOptions *opts, Error **errp);
42
37
int monitor_init_opts(QemuOpts *opts, Error **errp);
43
diff --git a/qemu-img.c b/qemu-img.c
38
diff --git a/monitor/monitor.c b/monitor/monitor.c
44
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
45
--- a/qemu-img.c
40
--- a/monitor/monitor.c
46
+++ b/qemu-img.c
41
+++ b/monitor/monitor.c
47
@@ -XXX,XX +XXX,XX @@ static int print_block_option_help(const char *filename, const char *fmt)
42
@@ -XXX,XX +XXX,XX @@ void monitor_init_globals_core(void)
43
int monitor_init(MonitorOptions *opts, Error **errp)
44
{
45
Chardev *chr;
46
+ Error *local_err = NULL;
47
48
chr = qemu_chr_find(opts->chardev);
49
if (chr == NULL) {
50
@@ -XXX,XX +XXX,XX @@ int monitor_init(MonitorOptions *opts, Error **errp)
51
52
switch (opts->mode) {
53
case MONITOR_MODE_CONTROL:
54
- monitor_init_qmp(chr, opts->pretty);
55
+ monitor_init_qmp(chr, opts->pretty, &local_err);
56
break;
57
case MONITOR_MODE_READLINE:
58
if (opts->pretty) {
59
@@ -XXX,XX +XXX,XX @@ int monitor_init(MonitorOptions *opts, Error **errp)
60
g_assert_not_reached();
48
}
61
}
49
62
50
printf("Supported options:\n");
63
+ if (local_err) {
51
- qemu_opts_print_help(create_opts);
64
+ error_propagate(errp, local_err);
52
+ qemu_opts_print_help(create_opts, false);
65
+ return -1;
53
qemu_opts_free(create_opts);
66
+ }
54
return 0;
67
return 0;
55
}
68
}
56
@@ -XXX,XX +XXX,XX @@ static int print_amend_option_help(const char *format)
69
57
assert(drv->create_opts);
70
diff --git a/monitor/qmp.c b/monitor/qmp.c
58
71
index XXXXXXX..XXXXXXX 100644
59
printf("Creation options for '%s':\n", format);
72
--- a/monitor/qmp.c
60
- qemu_opts_print_help(drv->create_opts);
73
+++ b/monitor/qmp.c
61
+ qemu_opts_print_help(drv->create_opts, false);
74
@@ -XXX,XX +XXX,XX @@ static void monitor_qmp_setup_handlers_bh(void *opaque)
62
printf("\nNote that not all of these options may be amendable.\n");
75
monitor_list_append(&mon->common);
63
return 0;
64
}
76
}
65
diff --git a/util/qemu-option.c b/util/qemu-option.c
77
78
-void monitor_init_qmp(Chardev *chr, bool pretty)
79
+void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp)
80
{
81
MonitorQMP *mon = g_new0(MonitorQMP, 1);
82
83
+ if (!qemu_chr_fe_init(&mon->common.chr, chr, errp)) {
84
+ g_free(mon);
85
+ return;
86
+ }
87
+ qemu_chr_fe_set_echo(&mon->common.chr, true);
88
+
89
/* Note: we run QMP monitor in I/O thread when @chr supports that */
90
monitor_data_init(&mon->common, true, false,
91
qemu_chr_has_feature(chr, QEMU_CHAR_FEATURE_GCONTEXT));
92
@@ -XXX,XX +XXX,XX @@ void monitor_init_qmp(Chardev *chr, bool pretty)
93
qemu_mutex_init(&mon->qmp_queue_lock);
94
mon->qmp_requests = g_queue_new();
95
96
- qemu_chr_fe_init(&mon->common.chr, chr, &error_abort);
97
- qemu_chr_fe_set_echo(&mon->common.chr, true);
98
-
99
json_message_parser_init(&mon->parser, handle_qmp_command, mon, NULL);
100
if (mon->common.use_io_thread) {
101
/*
102
diff --git a/stubs/monitor-core.c b/stubs/monitor-core.c
66
index XXXXXXX..XXXXXXX 100644
103
index XXXXXXX..XXXXXXX 100644
67
--- a/util/qemu-option.c
104
--- a/stubs/monitor-core.c
68
+++ b/util/qemu-option.c
105
+++ b/stubs/monitor-core.c
69
@@ -XXX,XX +XXX,XX @@ static const char *opt_type_to_string(enum QemuOptType type)
106
@@ -XXX,XX +XXX,XX @@
70
g_assert_not_reached();
107
108
__thread Monitor *cur_mon;
109
110
-void monitor_init_qmp(Chardev *chr, bool pretty)
111
+void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp)
112
{
71
}
113
}
72
114
73
-void qemu_opts_print_help(QemuOptsList *list)
115
diff --git a/tests/test-util-sockets.c b/tests/test-util-sockets.c
74
+/**
75
+ * Print the list of options available in the given list. If
76
+ * @print_caption is true, a caption (including the list name, if it
77
+ * exists) is printed. The options itself will be indented, so
78
+ * @print_caption should only be set to false if the caller prints its
79
+ * own custom caption (so that the indentation makes sense).
80
+ */
81
+void qemu_opts_print_help(QemuOptsList *list, bool print_caption)
82
{
83
QemuOptDesc *desc;
84
int i;
85
@@ -XXX,XX +XXX,XX @@ void qemu_opts_print_help(QemuOptsList *list)
86
desc = list->desc;
87
while (desc && desc->name) {
88
GString *str = g_string_new(NULL);
89
- if (list->name) {
90
- g_string_append_printf(str, "%s.", list->name);
91
- }
92
- g_string_append_printf(str, "%s=%s", desc->name,
93
+ g_string_append_printf(str, " %s=<%s>", desc->name,
94
opt_type_to_string(desc->type));
95
if (desc->help) {
96
+ if (str->len < 24) {
97
+ g_string_append_printf(str, "%*s", 24 - (int)str->len, "");
98
+ }
99
g_string_append_printf(str, " - %s", desc->help);
100
}
101
g_ptr_array_add(array, g_string_free(str, false));
102
@@ -XXX,XX +XXX,XX @@ void qemu_opts_print_help(QemuOptsList *list)
103
}
104
105
g_ptr_array_sort(array, (GCompareFunc)qemu_pstrcmp0);
106
+ if (print_caption && array->len > 0) {
107
+ if (list->name) {
108
+ printf("%s options:\n", list->name);
109
+ } else {
110
+ printf("Options:\n");
111
+ }
112
+ } else if (array->len == 0) {
113
+ if (list->name) {
114
+ printf("There are no options for %s.\n", list->name);
115
+ } else {
116
+ printf("No options available.\n");
117
+ }
118
+ }
119
for (i = 0; i < array->len; i++) {
120
printf("%s\n", (char *)array->pdata[i]);
121
}
122
@@ -XXX,XX +XXX,XX @@ QemuOpts *qemu_opts_parse_noisily(QemuOptsList *list, const char *params,
123
opts = opts_parse(list, params, permit_abbrev, false, &invalidp, &err);
124
if (err) {
125
if (invalidp && has_help_option(params)) {
126
- qemu_opts_print_help(list);
127
+ qemu_opts_print_help(list, true);
128
error_free(err);
129
} else {
130
error_report_err(err);
131
diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out
132
index XXXXXXX..XXXXXXX 100644
116
index XXXXXXX..XXXXXXX 100644
133
--- a/tests/qemu-iotests/082.out
117
--- a/tests/test-util-sockets.c
134
+++ b/tests/qemu-iotests/082.out
118
+++ b/tests/test-util-sockets.c
135
@@ -XXX,XX +XXX,XX @@ cluster_size: 8192
119
@@ -XXX,XX +XXX,XX @@ int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp)
136
120
*/
137
Testing: create -f qcow2 -o help TEST_DIR/t.qcow2 128M
121
__thread Monitor *cur_mon;
138
Supported options:
122
int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) { abort(); }
139
-size Virtual disk size
123
-void monitor_init_qmp(Chardev *chr, bool pretty) {}
140
-compat Compatibility level (0.10 or 1.1)
124
+void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp) {}
141
-backing_file File name of a base image
125
void monitor_init_hmp(Chardev *chr, bool use_readline) {}
142
-backing_fmt Image format of the base image
126
143
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
127
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
--
128
--
1222
2.19.1
129
2.20.1
1223
130
1224
131
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
Trying to attach a HMP monitor to a chardev that is already in use
2
results in a crash because monitor_init_hmp() passes &error_abort to
3
qemu_chr_fe_init():
2
4
3
Following the example of qemu_opts_print_help(), indent all entries in
5
$ ./x86_64-softmmu/qemu-system-x86_64 --chardev stdio,id=foo --mon foo --mon foo
4
the list of character devices.
6
QEMU 4.2.50 monitor - type 'help' for more information
7
(qemu) Unexpected error in qemu_chr_fe_init() at chardev/char-fe.c:220:
8
qemu-system-x86_64: --mon foo: Device 'foo' is in use
9
Abgebrochen (Speicherabzug geschrieben)
5
10
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
Fix this by allowing monitor_init_hmp() to return an error and passing
7
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
12
any error in qemu_chr_fe_init() to its caller instead of aborting.
13
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
Message-Id: <20200224143008.13362-19-kwolf@redhat.com>
16
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
18
---
10
chardev/char.c | 2 +-
19
include/monitor/monitor.h | 2 +-
11
1 file changed, 1 insertion(+), 1 deletion(-)
20
chardev/char.c | 8 +++++++-
21
gdbstub.c | 2 +-
22
monitor/hmp.c | 8 ++++++--
23
monitor/monitor.c | 2 +-
24
stubs/monitor.c | 2 +-
25
tests/test-util-sockets.c | 2 +-
26
7 files changed, 18 insertions(+), 8 deletions(-)
12
27
28
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/include/monitor/monitor.h
31
+++ b/include/monitor/monitor.h
32
@@ -XXX,XX +XXX,XX @@ bool monitor_cur_is_qmp(void);
33
void monitor_init_globals(void);
34
void monitor_init_globals_core(void);
35
void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp);
36
-void monitor_init_hmp(Chardev *chr, bool use_readline);
37
+void monitor_init_hmp(Chardev *chr, bool use_readline, Error **errp);
38
int monitor_init(MonitorOptions *opts, Error **errp);
39
int monitor_init_opts(QemuOpts *opts, Error **errp);
40
void monitor_cleanup(void);
13
diff --git a/chardev/char.c b/chardev/char.c
41
diff --git a/chardev/char.c b/chardev/char.c
14
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
15
--- a/chardev/char.c
43
--- a/chardev/char.c
16
+++ b/chardev/char.c
44
+++ b/chardev/char.c
17
@@ -XXX,XX +XXX,XX @@ help_string_append(const char *name, void *opaque)
45
@@ -XXX,XX +XXX,XX @@ Chardev *qemu_chr_new_noreplay(const char *label, const char *filename,
46
47
if (qemu_opt_get_bool(opts, "mux", 0)) {
48
assert(permit_mux_mon);
49
- monitor_init_hmp(chr, true);
50
+ monitor_init_hmp(chr, true, &err);
51
+ if (err) {
52
+ error_report_err(err);
53
+ object_unparent(OBJECT(chr));
54
+ chr = NULL;
55
+ goto out;
56
+ }
57
}
58
59
out:
60
diff --git a/gdbstub.c b/gdbstub.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/gdbstub.c
63
+++ b/gdbstub.c
64
@@ -XXX,XX +XXX,XX @@ int gdbserver_start(const char *device)
65
/* Initialize a monitor terminal for gdb */
66
mon_chr = qemu_chardev_new(NULL, TYPE_CHARDEV_GDB,
67
NULL, NULL, &error_abort);
68
- monitor_init_hmp(mon_chr, false);
69
+ monitor_init_hmp(mon_chr, false, &error_abort);
70
} else {
71
qemu_chr_fe_deinit(&s->chr, true);
72
mon_chr = s->mon_chr;
73
diff --git a/monitor/hmp.c b/monitor/hmp.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/monitor/hmp.c
76
+++ b/monitor/hmp.c
77
@@ -XXX,XX +XXX,XX @@ static void monitor_readline_flush(void *opaque)
78
monitor_flush(&mon->common);
79
}
80
81
-void monitor_init_hmp(Chardev *chr, bool use_readline)
82
+void monitor_init_hmp(Chardev *chr, bool use_readline, Error **errp)
18
{
83
{
19
GString *str = opaque;
84
MonitorHMP *mon = g_new0(MonitorHMP, 1);
20
85
21
- g_string_append_printf(str, "\n%s", name);
86
+ if (!qemu_chr_fe_init(&mon->common.chr, chr, errp)) {
22
+ g_string_append_printf(str, "\n %s", name);
87
+ g_free(mon);
88
+ return;
89
+ }
90
+
91
monitor_data_init(&mon->common, false, false, false);
92
- qemu_chr_fe_init(&mon->common.chr, chr, &error_abort);
93
94
mon->use_readline = use_readline;
95
if (mon->use_readline) {
96
diff --git a/monitor/monitor.c b/monitor/monitor.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/monitor/monitor.c
99
+++ b/monitor/monitor.c
100
@@ -XXX,XX +XXX,XX @@ int monitor_init(MonitorOptions *opts, Error **errp)
101
warn_report("'pretty' is deprecated for HMP monitors, it has no "
102
"effect and will be removed in future versions");
103
}
104
- monitor_init_hmp(chr, true);
105
+ monitor_init_hmp(chr, true, &local_err);
106
break;
107
default:
108
g_assert_not_reached();
109
diff --git a/stubs/monitor.c b/stubs/monitor.c
110
index XXXXXXX..XXXXXXX 100644
111
--- a/stubs/monitor.c
112
+++ b/stubs/monitor.c
113
@@ -XXX,XX +XXX,XX @@ int monitor_get_fd(Monitor *mon, const char *name, Error **errp)
114
return -1;
23
}
115
}
24
116
25
static const char *chardev_alias_translate(const char *name)
117
-void monitor_init_hmp(Chardev *chr, bool use_readline)
118
+void monitor_init_hmp(Chardev *chr, bool use_readline, Error **errp)
119
{
120
}
121
122
diff --git a/tests/test-util-sockets.c b/tests/test-util-sockets.c
123
index XXXXXXX..XXXXXXX 100644
124
--- a/tests/test-util-sockets.c
125
+++ b/tests/test-util-sockets.c
126
@@ -XXX,XX +XXX,XX @@ int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp)
127
__thread Monitor *cur_mon;
128
int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) { abort(); }
129
void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp) {}
130
-void monitor_init_hmp(Chardev *chr, bool use_readline) {}
131
+void monitor_init_hmp(Chardev *chr, bool use_readline, Error **errp) {}
132
133
134
static void test_socket_fd_pass_name_good(void)
26
--
135
--
27
2.19.1
136
2.20.1
28
137
29
138
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
Add a new parameter allow_hmp to monitor_init() so that the storage
2
daemon can disable HMP.
2
3
3
The blkverify mode of Quorum only works when the number of children is
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
exactly two, so any attempt to add a new one must return an error.
5
Message-Id: <20200224143008.13362-20-kwolf@redhat.com>
5
6
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
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>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
8
---
14
block/quorum.c | 8 ++++++++
9
qapi/control.json | 3 ++-
15
1 file changed, 8 insertions(+)
10
include/monitor/monitor.h | 2 +-
11
monitor/monitor.c | 12 ++++++++++--
12
3 files changed, 13 insertions(+), 4 deletions(-)
16
13
17
diff --git a/block/quorum.c b/block/quorum.c
14
diff --git a/qapi/control.json b/qapi/control.json
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/block/quorum.c
16
--- a/qapi/control.json
20
+++ b/block/quorum.c
17
+++ b/qapi/control.json
21
@@ -XXX,XX +XXX,XX @@ static void quorum_add_child(BlockDriverState *bs, BlockDriverState *child_bs,
18
@@ -XXX,XX +XXX,XX @@
22
char indexstr[32];
19
#
23
int ret;
20
# @id: Name of the monitor
24
21
#
25
+ if (s->is_blkverify) {
22
-# @mode: Selects the monitor mode (default: readline)
26
+ error_setg(errp, "Cannot add a child to a quorum in blkverify mode");
23
+# @mode: Selects the monitor mode (default: readline in the system
27
+ return;
24
+# emulator, control in qemu-storage-daemon)
25
#
26
# @pretty: Enables pretty printing (QMP only)
27
#
28
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/include/monitor/monitor.h
31
+++ b/include/monitor/monitor.h
32
@@ -XXX,XX +XXX,XX @@ void monitor_init_globals(void);
33
void monitor_init_globals_core(void);
34
void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp);
35
void monitor_init_hmp(Chardev *chr, bool use_readline, Error **errp);
36
-int monitor_init(MonitorOptions *opts, Error **errp);
37
+int monitor_init(MonitorOptions *opts, bool allow_hmp, Error **errp);
38
int monitor_init_opts(QemuOpts *opts, Error **errp);
39
void monitor_cleanup(void);
40
41
diff --git a/monitor/monitor.c b/monitor/monitor.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/monitor/monitor.c
44
+++ b/monitor/monitor.c
45
@@ -XXX,XX +XXX,XX @@ void monitor_init_globals_core(void)
46
NULL);
47
}
48
49
-int monitor_init(MonitorOptions *opts, Error **errp)
50
+int monitor_init(MonitorOptions *opts, bool allow_hmp, Error **errp)
51
{
52
Chardev *chr;
53
Error *local_err = NULL;
54
@@ -XXX,XX +XXX,XX @@ int monitor_init(MonitorOptions *opts, Error **errp)
55
return -1;
56
}
57
58
+ if (!opts->has_mode) {
59
+ opts->mode = allow_hmp ? MONITOR_MODE_READLINE : MONITOR_MODE_CONTROL;
28
+ }
60
+ }
29
+
61
+
30
assert(s->num_children <= INT_MAX / sizeof(BdrvChild *));
62
switch (opts->mode) {
31
if (s->num_children == INT_MAX / sizeof(BdrvChild *) ||
63
case MONITOR_MODE_CONTROL:
32
s->next_child_index == UINT_MAX) {
64
monitor_init_qmp(chr, opts->pretty, &local_err);
33
@@ -XXX,XX +XXX,XX @@ static void quorum_del_child(BlockDriverState *bs, BdrvChild *child,
65
break;
34
return;
66
case MONITOR_MODE_READLINE:
67
+ if (!allow_hmp) {
68
+ error_setg(errp, "Only QMP is supported");
69
+ return -1;
70
+ }
71
if (opts->pretty) {
72
warn_report("'pretty' is deprecated for HMP monitors, it has no "
73
"effect and will be removed in future versions");
74
@@ -XXX,XX +XXX,XX @@ int monitor_init_opts(QemuOpts *opts, Error **errp)
75
goto out;
35
}
76
}
36
77
37
+ /* We know now that num_children > threshold, so blkverify must be false */
78
- monitor_init(options, &local_err);
38
+ assert(!s->is_blkverify);
79
+ monitor_init(options, true, &local_err);
39
+
80
qapi_free_MonitorOptions(options);
40
bdrv_drained_begin(bs);
81
41
82
out:
42
/* We can safely remove this child now */
43
--
83
--
44
2.19.1
84
2.20.1
45
85
46
86
diff view generated by jsdifflib
1
This adds and parses the --monitor option, so that a QMP monitor can be
2
used in the storage daemon. The monitor offers commands defined in the
3
QAPI schema at storage-daemon/qapi/qapi-schema.json.
4
5
The --monitor options currently allows to create multiple monitors with
6
the same ID. This part of the interface is considered unstable. We will
7
reject such configurations as soon as we have a design for the monitor
8
subsystem to perform these checks. (In the system emulator, we depend on
9
QemuOpts rejecting duplicate IDs.)
10
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2
Reviewed-by: Eric Blake <eblake@redhat.com>
12
Message-Id: <20200224143008.13362-21-kwolf@redhat.com>
13
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
3
---
15
---
4
tests/qemu-iotests/232 | 147 +++++++++++++++++++++++++++++++++++++
16
qapi/transaction.json | 2 +-
5
tests/qemu-iotests/232.out | 59 +++++++++++++++
17
qemu-storage-daemon.c | 47 ++++++++++++++++++++++++++--
6
tests/qemu-iotests/group | 1 +
18
scripts/qapi/gen.py | 5 +++
7
3 files changed, 207 insertions(+)
19
Makefile | 33 +++++++++++++++++++
8
create mode 100755 tests/qemu-iotests/232
20
Makefile.objs | 4 +--
9
create mode 100644 tests/qemu-iotests/232.out
21
monitor/Makefile.objs | 2 ++
10
22
qapi/Makefile.objs | 5 +++
11
diff --git a/tests/qemu-iotests/232 b/tests/qemu-iotests/232
23
storage-daemon/Makefile.objs | 1 +
12
new file mode 100755
24
storage-daemon/qapi/Makefile.objs | 1 +
13
index XXXXXXX..XXXXXXX
25
storage-daemon/qapi/qapi-schema.json | 26 +++++++++++++++
14
--- /dev/null
26
10 files changed, 121 insertions(+), 5 deletions(-)
15
+++ b/tests/qemu-iotests/232
27
create mode 100644 storage-daemon/Makefile.objs
28
create mode 100644 storage-daemon/qapi/Makefile.objs
29
create mode 100644 storage-daemon/qapi/qapi-schema.json
30
31
diff --git a/qapi/transaction.json b/qapi/transaction.json
32
index XXXXXXX..XXXXXXX 100644
33
--- a/qapi/transaction.json
34
+++ b/qapi/transaction.json
16
@@ -XXX,XX +XXX,XX @@
35
@@ -XXX,XX +XXX,XX @@
17
+#!/bin/bash
36
# = Transactions
18
+#
37
##
19
+# Test for auto-read-only
38
20
+#
39
-{ 'include': 'block.json' }
21
+# Copyright (C) 2018 Red Hat, Inc.
40
+{ 'include': 'block-core.json' }
22
+#
41
23
+# This program is free software; you can redistribute it and/or modify
42
##
24
+# it under the terms of the GNU General Public License as published by
43
# @Abort:
25
+# the Free Software Foundation; either version 2 of the License, or
44
diff --git a/qemu-storage-daemon.c b/qemu-storage-daemon.c
26
+# (at your option) any later version.
45
index XXXXXXX..XXXXXXX 100644
27
+#
46
--- a/qemu-storage-daemon.c
28
+# This program is distributed in the hope that it will be useful,
47
+++ b/qemu-storage-daemon.c
29
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
48
@@ -XXX,XX +XXX,XX @@
30
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
49
#include "block/nbd.h"
31
+# GNU General Public License for more details.
50
#include "chardev/char.h"
32
+#
51
#include "crypto/init.h"
33
+# You should have received a copy of the GNU General Public License
52
+#include "monitor/monitor.h"
34
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53
+#include "monitor/monitor-internal.h"
35
+#
54
36
+
55
#include "qapi/error.h"
37
+# creator
56
-#include "qapi/qapi-commands-block.h"
38
+owner=kwolf@redhat.com
57
-#include "qapi/qapi-commands-block-core.h"
39
+
58
#include "qapi/qapi-visit-block.h"
40
+seq=`basename $0`
59
#include "qapi/qapi-visit-block-core.h"
41
+echo "QA output created by $seq"
60
+#include "qapi/qapi-visit-control.h"
42
+
61
#include "qapi/qmp/qdict.h"
43
+here=`pwd`
62
+#include "qapi/qmp/qstring.h"
44
+status=1    # failure is the default!
63
#include "qapi/qobject-input-visitor.h"
45
+
64
46
+_cleanup()
65
#include "qemu-common.h"
66
@@ -XXX,XX +XXX,XX @@
67
#include "qemu/option.h"
68
#include "qom/object_interfaces.h"
69
70
+#include "storage-daemon/qapi/qapi-commands.h"
71
+#include "storage-daemon/qapi/qapi-init-commands.h"
72
+
73
#include "sysemu/runstate.h"
74
#include "trace/control.h"
75
76
@@ -XXX,XX +XXX,XX @@ void qemu_system_killed(int signal, pid_t pid)
77
exit_requested = true;
78
}
79
80
+void qmp_quit(Error **errp)
47
+{
81
+{
48
+ _cleanup_test_img
82
+ exit_requested = true;
49
+ rm -f $TEST_IMG.snap
50
+}
83
+}
51
+trap "_cleanup; exit \$status" 0 1 2 3 15
84
+
52
+
85
static void help(void)
53
+# get standard environment, filters and checks
86
{
54
+. ./common.rc
87
printf(
55
+. ./common.filter
88
@@ -XXX,XX +XXX,XX @@ static void help(void)
56
+
89
" export the specified block node over NBD\n"
57
+_supported_fmt generic
90
" (requires --nbd-server)\n"
58
+_supported_proto file
91
"\n"
59
+_supported_os Linux
92
+" --monitor [chardev=]name[,mode=control][,pretty[=on|off]]\n"
60
+
93
+" configure a QMP monitor\n"
61
+function do_run_qemu()
94
+"\n"
95
" --nbd-server addr.type=inet,addr.host=<host>,addr.port=<port>\n"
96
" [,tls-creds=<id>][,tls-authz=<id>]\n"
97
" --nbd-server addr.type=unix,addr.path=<path>\n"
98
@@ -XXX,XX +XXX,XX @@ enum {
99
OPTION_BLOCKDEV = 256,
100
OPTION_CHARDEV,
101
OPTION_EXPORT,
102
+ OPTION_MONITOR,
103
OPTION_NBD_SERVER,
104
OPTION_OBJECT,
105
};
106
@@ -XXX,XX +XXX,XX @@ static QemuOptsList qemu_object_opts = {
107
},
108
};
109
110
+static void init_qmp_commands(void)
62
+{
111
+{
63
+ echo Testing: "$@"
112
+ qmp_init_marshal(&qmp_commands);
64
+ (
113
+ qmp_register_command(&qmp_commands, "query-qmp-schema",
65
+ if ! test -t 0; then
114
+ qmp_query_qmp_schema, QCO_ALLOW_PRECONFIG);
66
+ while read cmd; do
115
+
67
+ echo $cmd
116
+ QTAILQ_INIT(&qmp_cap_negotiation_commands);
68
+ done
117
+ qmp_register_command(&qmp_cap_negotiation_commands, "qmp_capabilities",
69
+ fi
118
+ qmp_marshal_qmp_capabilities, QCO_ALLOW_PRECONFIG);
70
+ echo quit
71
+ ) | $QEMU -nographic -monitor stdio -nodefaults "$@"
72
+ echo
73
+}
119
+}
74
+
120
+
75
+function run_qemu()
121
static void init_export(BlockExport *export, Error **errp)
76
+{
122
{
77
+ do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_hmp |
123
switch (export->type) {
78
+ _filter_generated_node_ids | _filter_imgfmt
124
@@ -XXX,XX +XXX,XX @@ static void process_options(int argc, char *argv[])
79
+}
125
{"chardev", required_argument, NULL, OPTION_CHARDEV},
80
+
126
{"export", required_argument, NULL, OPTION_EXPORT},
81
+function run_qemu_info_block()
127
{"help", no_argument, NULL, 'h'},
82
+{
128
+ {"monitor", required_argument, NULL, OPTION_MONITOR},
83
+ echo "info block -n" | run_qemu "$@" | grep -e "(file" -e "QEMU_PROG"
129
{"nbd-server", required_argument, NULL, OPTION_NBD_SERVER},
84
+}
130
{"object", required_argument, NULL, OPTION_OBJECT},
85
+
131
{"trace", required_argument, NULL, 'T'},
86
+size=128M
132
@@ -XXX,XX +XXX,XX @@ static void process_options(int argc, char *argv[])
87
+
133
qapi_free_BlockExport(export);
88
+_make_test_img $size
134
break;
89
+
135
}
90
+echo
136
+ case OPTION_MONITOR:
91
+echo "=== -drive with read-write image: read-only/auto-read-only combinations ==="
137
+ {
92
+echo
138
+ Visitor *v;
93
+
139
+ MonitorOptions *monitor;
94
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on,auto-read-only=off
140
+
95
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on,auto-read-only=on
141
+ v = qobject_input_visitor_new_str(optarg, "chardev",
96
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on
142
+ &error_fatal);
97
+echo
143
+ visit_type_MonitorOptions(v, NULL, &monitor, &error_fatal);
98
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off,auto-read-only=off
144
+ visit_free(v);
99
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off,auto-read-only=on
145
+
100
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off
146
+ /* TODO Catch duplicate monitor IDs */
101
+echo
147
+ monitor_init(monitor, false, &error_fatal);
102
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,auto-read-only=off
148
+ qapi_free_MonitorOptions(monitor);
103
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,auto-read-only=on
149
+ break;
104
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none
150
+ }
105
+
151
case OPTION_NBD_SERVER:
106
+echo
152
{
107
+echo "=== -drive with read-only image: read-only/auto-read-only combinations ==="
153
Visitor *v;
108
+echo
154
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
109
+
155
qemu_add_opts(&qemu_trace_opts);
110
+chmod a-w $TEST_IMG
156
qcrypto_init(&error_fatal);
111
+
157
bdrv_init();
112
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on,auto-read-only=off
158
+ monitor_init_globals_core();
113
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on,auto-read-only=on
159
+ init_qmp_commands();
114
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on
160
115
+echo
161
if (!trace_init_backends()) {
116
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off,auto-read-only=off
162
return EXIT_FAILURE;
117
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off,auto-read-only=on
163
diff --git a/scripts/qapi/gen.py b/scripts/qapi/gen.py
118
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off
164
index XXXXXXX..XXXXXXX 100644
119
+echo
165
--- a/scripts/qapi/gen.py
120
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,auto-read-only=off
166
+++ b/scripts/qapi/gen.py
121
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,auto-read-only=on
167
@@ -XXX,XX +XXX,XX @@ class QAPIGen:
122
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none
168
return ''
123
+
169
124
+echo
170
def write(self, output_dir):
125
+echo "=== -blockdev with read-write image: read-only/auto-read-only combinations ==="
171
+ # Include paths starting with ../ are used to reuse modules of the main
126
+echo
172
+ # schema in specialised schemas. Don't overwrite the files that are
127
+
173
+ # already generated for the main schema.
128
+chmod a+w $TEST_IMG
174
+ if self.fname.startswith('../'):
129
+
175
+ return
130
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on,auto-read-only=off
176
pathname = os.path.join(output_dir, self.fname)
131
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on,auto-read-only=on
177
odir = os.path.dirname(pathname)
132
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on
178
if odir:
133
+echo
179
diff --git a/Makefile b/Makefile
134
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off,auto-read-only=off
180
index XXXXXXX..XXXXXXX 100644
135
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off,auto-read-only=on
181
--- a/Makefile
136
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off
182
+++ b/Makefile
137
+echo
183
@@ -XXX,XX +XXX,XX @@ GENERATED_QAPI_FILES += $(QAPI_MODULES:%=qapi/qapi-events-%.c)
138
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,auto-read-only=off
184
GENERATED_QAPI_FILES += qapi/qapi-introspect.c qapi/qapi-introspect.h
139
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,auto-read-only=on
185
GENERATED_QAPI_FILES += qapi/qapi-doc.texi
140
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0
186
141
+
187
+# The following list considers only the storage daemon main module. All other
142
+echo
188
+# modules are currently shared with the main schema, so we don't actually
143
+echo "=== -blockdev with read-only image: read-only/auto-read-only combinations ==="
189
+# generate additional files.
144
+echo
190
+
145
+
191
+GENERATED_STORAGE_DAEMON_QAPI_FILES = storage-daemon/qapi/qapi-commands.h
146
+chmod a-w $TEST_IMG
192
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-commands.c
147
+
193
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-emit-events.h
148
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on,auto-read-only=off
194
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-emit-events.c
149
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on,auto-read-only=on
195
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-events.h
150
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on
196
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-events.c
151
+echo
197
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-init-commands.h
152
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off,auto-read-only=off
198
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-init-commands.c
153
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off,auto-read-only=on
199
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-introspect.h
154
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off
200
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-introspect.c
155
+echo
201
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-types.h
156
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,auto-read-only=off
202
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-types.c
157
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,auto-read-only=on
203
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-visit.h
158
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0
204
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-visit.c
159
+
205
+GENERATED_STORAGE_DAEMON_QAPI_FILES += storage-daemon/qapi/qapi-doc.texi
160
+# success, all done
206
+
161
+echo "*** done"
207
generated-files-y += $(GENERATED_QAPI_FILES)
162
+rm -f $seq.full
208
+generated-files-y += $(GENERATED_STORAGE_DAEMON_QAPI_FILES)
163
+status=0
209
164
diff --git a/tests/qemu-iotests/232.out b/tests/qemu-iotests/232.out
210
generated-files-y += trace/generated-tcg-tracers.h
211
212
@@ -XXX,XX +XXX,XX @@ qapi-gen-timestamp: $(qapi-modules) $(qapi-py)
213
        "GEN","$(@:%-timestamp=%)")
214
    @>$@
215
216
+qapi-modules-storage-daemon = \
217
+    $(SRC_PATH)/storage-daemon/qapi/qapi-schema.json \
218
+ $(QAPI_MODULES_STORAGE_DAEMON:%=$(SRC_PATH)/qapi/%.json)
219
+
220
+$(GENERATED_STORAGE_DAEMON_QAPI_FILES): storage-daemon/qapi/qapi-gen-timestamp ;
221
+storage-daemon/qapi/qapi-gen-timestamp: $(qapi-modules-storage-daemon) $(qapi-py)
222
+    $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-gen.py \
223
+        -o "storage-daemon/qapi" $<, \
224
+        "GEN","$(@:%-timestamp=%)")
225
+    @>$@
226
+
227
QGALIB_GEN=$(addprefix qga/qapi-generated/, qga-qapi-types.h qga-qapi-visit.h qga-qapi-commands.h qga-qapi-init-commands.h)
228
$(qga-obj-y): $(QGALIB_GEN)
229
230
@@ -XXX,XX +XXX,XX @@ clean: recurse-clean
231
    rm -f trace/generated-tracers-dtrace.h*
232
    rm -f $(foreach f,$(generated-files-y),$(f) $(f)-timestamp)
233
    rm -f qapi-gen-timestamp
234
+    rm -f storage-daemon/qapi/qapi-gen-timestamp
235
    rm -rf qga/qapi-generated
236
    rm -f config-all-devices.mak
237
238
diff --git a/Makefile.objs b/Makefile.objs
239
index XXXXXXX..XXXXXXX 100644
240
--- a/Makefile.objs
241
+++ b/Makefile.objs
242
@@ -XXX,XX +XXX,XX @@ endif # CONFIG_SOFTMMU or CONFIG_TOOLS
243
# storage-daemon-obj-y is code used by qemu-storage-daemon (these objects are
244
# used for system emulation, too, but specified separately there)
245
246
-storage-daemon-obj-y = block/ qom/
247
-storage-daemon-obj-y += blockdev.o blockdev-nbd.o iothread.o
248
+storage-daemon-obj-y = block/ monitor/ qapi/ qom/ storage-daemon/
249
+storage-daemon-obj-y += blockdev.o blockdev-nbd.o iothread.o job-qmp.o
250
storage-daemon-obj-$(CONFIG_WIN32) += os-win32.o
251
storage-daemon-obj-$(CONFIG_POSIX) += os-posix.o
252
253
diff --git a/monitor/Makefile.objs b/monitor/Makefile.objs
254
index XXXXXXX..XXXXXXX 100644
255
--- a/monitor/Makefile.objs
256
+++ b/monitor/Makefile.objs
257
@@ -XXX,XX +XXX,XX @@ obj-y += misc.o
258
common-obj-y += monitor.o qmp.o hmp.o
259
common-obj-y += qmp-cmds.o qmp-cmds-control.o
260
common-obj-y += hmp-cmds.o
261
+
262
+storage-daemon-obj-y += monitor.o qmp.o qmp-cmds-control.o
263
diff --git a/qapi/Makefile.objs b/qapi/Makefile.objs
264
index XXXXXXX..XXXXXXX 100644
265
--- a/qapi/Makefile.objs
266
+++ b/qapi/Makefile.objs
267
@@ -XXX,XX +XXX,XX @@ obj-y += qapi-events.o
268
obj-y += $(QAPI_TARGET_MODULES:%=qapi-commands-%.o)
269
obj-y += qapi-commands.o
270
obj-y += qapi-init-commands.o
271
+
272
+QAPI_MODULES_STORAGE_DAEMON = block-core char common control crypto
273
+QAPI_MODULES_STORAGE_DAEMON += introspect job qom sockets pragma transaction
274
+
275
+storage-daemon-obj-y += $(QAPI_MODULES_STORAGE_DAEMON:%=qapi-commands-%.o)
276
diff --git a/storage-daemon/Makefile.objs b/storage-daemon/Makefile.objs
165
new file mode 100644
277
new file mode 100644
166
index XXXXXXX..XXXXXXX
278
index XXXXXXX..XXXXXXX
167
--- /dev/null
279
--- /dev/null
168
+++ b/tests/qemu-iotests/232.out
280
+++ b/storage-daemon/Makefile.objs
281
@@ -0,0 +1 @@
282
+storage-daemon-obj-y += qapi/
283
diff --git a/storage-daemon/qapi/Makefile.objs b/storage-daemon/qapi/Makefile.objs
284
new file mode 100644
285
index XXXXXXX..XXXXXXX
286
--- /dev/null
287
+++ b/storage-daemon/qapi/Makefile.objs
288
@@ -0,0 +1 @@
289
+storage-daemon-obj-y += qapi-commands.o qapi-init-commands.o qapi-introspect.o
290
diff --git a/storage-daemon/qapi/qapi-schema.json b/storage-daemon/qapi/qapi-schema.json
291
new file mode 100644
292
index XXXXXXX..XXXXXXX
293
--- /dev/null
294
+++ b/storage-daemon/qapi/qapi-schema.json
169
@@ -XXX,XX +XXX,XX @@
295
@@ -XXX,XX +XXX,XX @@
170
+QA output created by 232
296
+# -*- Mode: Python -*-
171
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
297
+
172
+
298
+# Note that modules are shared with the QEMU main schema under the assumption
173
+=== -drive with read-write image: read-only/auto-read-only combinations ===
299
+# that the storage daemon schema is a subset of the main schema. For the shared
174
+
300
+# modules, no code is generated here, but we reuse the code files generated
175
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
301
+# from the main schema.
176
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
302
+#
177
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
303
+# If you wish to extend the storage daemon schema to contain things that are
178
+
304
+# not in the main schema, be aware that array types of types defined in shared
179
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
305
+# modules are only generated if an array of the respective type is already used
180
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
306
+# in the main schema. Therefore, if you use such arrays, you may need to define
181
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
307
+# the array type in the main schema, even if it is unused outside of the
182
+
308
+# storage daemon.
183
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
309
+
184
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
310
+{ 'include': '../../qapi/pragma.json' }
185
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
311
+
186
+
312
+{ 'include': '../../qapi/block-core.json' }
187
+=== -drive with read-only image: read-only/auto-read-only combinations ===
313
+{ 'include': '../../qapi/char.json' }
188
+
314
+{ 'include': '../../qapi/common.json' }
189
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
315
+{ 'include': '../../qapi/control.json' }
190
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
316
+{ 'include': '../../qapi/crypto.json' }
191
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
317
+{ 'include': '../../qapi/introspect.json' }
192
+
318
+{ 'include': '../../qapi/job.json' }
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
319
+{ 'include': '../../qapi/qom.json' }
194
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
320
+{ 'include': '../../qapi/sockets.json' }
195
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
321
+{ 'include': '../../qapi/transaction.json' }
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
230
index XXXXXXX..XXXXXXX 100644
231
--- a/tests/qemu-iotests/group
232
+++ b/tests/qemu-iotests/group
233
@@ -XXX,XX +XXX,XX @@
234
227 auto quick
235
229 auto quick
236
231 auto quick
237
+232 auto quick
238
--
322
--
239
2.19.1
323
2.20.1
240
324
241
325
diff view generated by jsdifflib
1
Commit e2b8247a322 introduced an error path in qemu_rbd_open() after
1
From: Florian Florensa <fflorensa@online.net>
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
2
6
This adds the missing rbd_close() call.
3
Starting from ceph Nautilus, RBD has support for namespaces, allowing
4
for finer grain ACLs on images inside a pool, and tenant isolation.
7
5
6
In the rbd cli tool documentation, the new image-spec and snap-spec are :
7
- [pool-name/[namespace-name/]]image-name
8
- [pool-name/[namespace-name/]]image-name@snap-name
9
10
When using an non namespace's enabled qemu, it complains about not
11
finding the image called namespace-name/image-name, thus we only need to
12
parse the image once again to find if there is a '/' in its name, and if
13
there is, use what is before it as the name of the namespace to later
14
pass it to rados_ioctx_set_namespace.
15
rados_ioctx_set_namespace if called with en empty string or a null
16
pointer as the namespace parameters pretty much does nothing, as it then
17
defaults to the default namespace.
18
19
The namespace is extracted inside qemu_rbd_parse_filename, stored in the
20
qdict, and used in qemu_rbd_connect to make it work with both qemu-img,
21
and qemu itself.
22
23
Signed-off-by: Florian Florensa <fflorensa@online.net>
24
Message-Id: <20200110111513.321728-2-fflorensa@online.net>
25
Reviewed-by: Jason Dillaman <dillaman@redhat.com>
26
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
27
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Reviewed-by: Eric Blake <eblake@redhat.com>
10
---
28
---
11
block/rbd.c | 1 +
29
qapi/block-core.json | 3 +++
12
1 file changed, 1 insertion(+)
30
block/rbd.c | 44 +++++++++++++++++++++++++++++++-------------
31
2 files changed, 34 insertions(+), 13 deletions(-)
13
32
33
diff --git a/qapi/block-core.json b/qapi/block-core.json
34
index XXXXXXX..XXXXXXX 100644
35
--- a/qapi/block-core.json
36
+++ b/qapi/block-core.json
37
@@ -XXX,XX +XXX,XX @@
38
#
39
# @pool: Ceph pool name.
40
#
41
+# @namespace: Rados namespace name in the Ceph pool. (Since 5.0)
42
+#
43
# @image: Image name in the Ceph pool.
44
#
45
# @conf: path to Ceph configuration file. Values
46
@@ -XXX,XX +XXX,XX @@
47
##
48
{ 'struct': 'BlockdevOptionsRbd',
49
'data': { 'pool': 'str',
50
+ '*namespace': 'str',
51
'image': 'str',
52
'*conf': 'str',
53
'*snapshot': 'str',
14
diff --git a/block/rbd.c b/block/rbd.c
54
diff --git a/block/rbd.c b/block/rbd.c
15
index XXXXXXX..XXXXXXX 100644
55
index XXXXXXX..XXXXXXX 100644
16
--- a/block/rbd.c
56
--- a/block/rbd.c
17
+++ b/block/rbd.c
57
+++ b/block/rbd.c
18
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
58
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVRBDState {
19
"automatically marking the image read-only.");
59
rbd_image_t image;
20
r = bdrv_set_read_only(bs, true, &local_err);
60
char *image_name;
21
if (r < 0) {
61
char *snap;
22
+ rbd_close(s->image);
62
+ char *namespace;
23
error_propagate(errp, local_err);
63
uint64_t image_size;
24
goto failed_open;
64
} BDRVRBDState;
25
}
65
66
@@ -XXX,XX +XXX,XX @@ static void qemu_rbd_parse_filename(const char *filename, QDict *options,
67
const char *start;
68
char *p, *buf;
69
QList *keypairs = NULL;
70
- char *found_str;
71
+ char *found_str, *image_name;
72
73
if (!strstart(filename, "rbd:", &start)) {
74
error_setg(errp, "File name must start with 'rbd:'");
75
@@ -XXX,XX +XXX,XX @@ static void qemu_rbd_parse_filename(const char *filename, QDict *options,
76
qdict_put_str(options, "pool", found_str);
77
78
if (strchr(p, '@')) {
79
- found_str = qemu_rbd_next_tok(p, '@', &p);
80
- qemu_rbd_unescape(found_str);
81
- qdict_put_str(options, "image", found_str);
82
+ image_name = qemu_rbd_next_tok(p, '@', &p);
83
84
found_str = qemu_rbd_next_tok(p, ':', &p);
85
qemu_rbd_unescape(found_str);
86
qdict_put_str(options, "snapshot", found_str);
87
} else {
88
- found_str = qemu_rbd_next_tok(p, ':', &p);
89
+ image_name = qemu_rbd_next_tok(p, ':', &p);
90
+ }
91
+ /* Check for namespace in the image_name */
92
+ if (strchr(image_name, '/')) {
93
+ found_str = qemu_rbd_next_tok(image_name, '/', &image_name);
94
qemu_rbd_unescape(found_str);
95
- qdict_put_str(options, "image", found_str);
96
+ qdict_put_str(options, "namespace", found_str);
97
+ } else {
98
+ qdict_put_str(options, "namespace", "");
99
}
100
+ qemu_rbd_unescape(image_name);
101
+ qdict_put_str(options, "image", image_name);
102
if (!p) {
103
goto done;
104
}
105
@@ -XXX,XX +XXX,XX @@ static QemuOptsList runtime_opts = {
106
.type = QEMU_OPT_STRING,
107
.help = "Rados pool name",
108
},
109
+ {
110
+ .name = "namespace",
111
+ .type = QEMU_OPT_STRING,
112
+ .help = "Rados namespace name in the pool",
113
+ },
114
{
115
.name = "image",
116
.type = QEMU_OPT_STRING,
117
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qemu_rbd_co_create_opts(const char *filename,
118
* schema, but when they come from -drive, they're all QString.
119
*/
120
loc = rbd_opts->location;
121
- loc->pool = g_strdup(qdict_get_try_str(options, "pool"));
122
- loc->conf = g_strdup(qdict_get_try_str(options, "conf"));
123
- loc->has_conf = !!loc->conf;
124
- loc->user = g_strdup(qdict_get_try_str(options, "user"));
125
- loc->has_user = !!loc->user;
126
- loc->image = g_strdup(qdict_get_try_str(options, "image"));
127
- keypairs = qdict_get_try_str(options, "=keyvalue-pairs");
128
+ loc->pool = g_strdup(qdict_get_try_str(options, "pool"));
129
+ loc->conf = g_strdup(qdict_get_try_str(options, "conf"));
130
+ loc->has_conf = !!loc->conf;
131
+ loc->user = g_strdup(qdict_get_try_str(options, "user"));
132
+ loc->has_user = !!loc->user;
133
+ loc->q_namespace = g_strdup(qdict_get_try_str(options, "namespace"));
134
+ loc->image = g_strdup(qdict_get_try_str(options, "image"));
135
+ keypairs = qdict_get_try_str(options, "=keyvalue-pairs");
136
137
ret = qemu_rbd_do_create(create_options, keypairs, password_secret, errp);
138
if (ret < 0) {
139
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
140
error_setg_errno(errp, -r, "error opening pool %s", opts->pool);
141
goto failed_shutdown;
142
}
143
+ /*
144
+ * Set the namespace after opening the io context on the pool,
145
+ * if nspace == NULL or if nspace == "", it is just as we did nothing
146
+ */
147
+ rados_ioctx_set_namespace(*io_ctx, opts->q_namespace);
148
149
return 0;
150
26
--
151
--
27
2.19.1
152
2.20.1
28
153
29
154
diff view generated by jsdifflib
1
If read-only=off, but auto-read-only=on is given, open a read-write NBD
1
We'll want to test more than one successful case in the future, so
2
connection if the server provides a read-write export, but instead of
2
prepare the test for that by a refactoring that runs each scenario in a
3
erroring out for read-only exports, just degrade to read-only.
3
separate VM.
4
5
test_iothreads_switch_{backing,overlay} currently produce errors, but
6
these are cases that should actually work, by switching either the
7
backing file node or the overlay node to the AioContext of the other
8
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>
11
Tested-by: Peter Krempa <pkrempa@redhat.com>
12
Message-Id: <20200306141413.30705-2-kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
14
---
8
block/nbd-client.c | 10 +++++-----
15
tests/qemu-iotests/245 | 47 ++++++++++++++++++++++++++++++--------
9
1 file changed, 5 insertions(+), 5 deletions(-)
16
tests/qemu-iotests/245.out | 4 ++--
17
2 files changed, 39 insertions(+), 12 deletions(-)
10
18
11
diff --git a/block/nbd-client.c b/block/nbd-client.c
19
diff --git a/tests/qemu-iotests/245 b/tests/qemu-iotests/245
20
index XXXXXXX..XXXXXXX 100755
21
--- a/tests/qemu-iotests/245
22
+++ b/tests/qemu-iotests/245
23
@@ -XXX,XX +XXX,XX @@ class TestBlockdevReopen(iotests.QMPTestCase):
24
self.assertEqual(self.get_node('hd1'), None)
25
self.assert_qmp(self.get_node('hd2'), 'ro', True)
26
27
- # We don't allow setting a backing file that uses a different AioContext
28
- def test_iothreads(self):
29
+ def run_test_iothreads(self, iothread_a, iothread_b, errmsg = None):
30
opts = hd_opts(0)
31
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts)
32
self.assert_qmp(result, 'return', {})
33
@@ -XXX,XX +XXX,XX @@ class TestBlockdevReopen(iotests.QMPTestCase):
34
result = self.vm.qmp('object-add', qom_type='iothread', id='iothread1')
35
self.assert_qmp(result, 'return', {})
36
37
- result = self.vm.qmp('x-blockdev-set-iothread', node_name='hd0', iothread='iothread0')
38
+ result = self.vm.qmp('device_add', driver='virtio-scsi', id='scsi0',
39
+ iothread=iothread_a)
40
self.assert_qmp(result, 'return', {})
41
42
- self.reopen(opts, {'backing': 'hd2'}, "Cannot use a new backing file with a different AioContext")
43
-
44
- result = self.vm.qmp('x-blockdev-set-iothread', node_name='hd2', iothread='iothread1')
45
+ result = self.vm.qmp('device_add', driver='virtio-scsi', id='scsi1',
46
+ iothread=iothread_b)
47
self.assert_qmp(result, 'return', {})
48
49
- self.reopen(opts, {'backing': 'hd2'}, "Cannot use a new backing file with a different AioContext")
50
+ if iothread_a:
51
+ result = self.vm.qmp('device_add', driver='scsi-hd', drive='hd0',
52
+ share_rw=True, bus="scsi0.0")
53
+ self.assert_qmp(result, 'return', {})
54
55
- result = self.vm.qmp('x-blockdev-set-iothread', node_name='hd2', iothread='iothread0')
56
- self.assert_qmp(result, 'return', {})
57
+ if iothread_b:
58
+ result = self.vm.qmp('device_add', driver='scsi-hd', drive='hd2',
59
+ share_rw=True, bus="scsi1.0")
60
+ self.assert_qmp(result, 'return', {})
61
62
- self.reopen(opts, {'backing': 'hd2'})
63
+ # Attaching the backing file may or may not work
64
+ self.reopen(opts, {'backing': 'hd2'}, errmsg)
65
+
66
+ # But removing the backing file should always work
67
+ self.reopen(opts, {'backing': None})
68
+
69
+ self.vm.shutdown()
70
+
71
+ # We don't allow setting a backing file that uses a different AioContext if
72
+ # neither of them can switch to the other AioContext
73
+ def test_iothreads_error(self):
74
+ self.run_test_iothreads('iothread0', 'iothread1',
75
+ "Cannot use a new backing file with a different AioContext")
76
+
77
+ def test_iothreads_compatible_users(self):
78
+ self.run_test_iothreads('iothread0', 'iothread0')
79
+
80
+ def test_iothreads_switch_backing(self):
81
+ self.run_test_iothreads('iothread0', None,
82
+ "Cannot use a new backing file with a different AioContext")
83
+
84
+ def test_iothreads_switch_overlay(self):
85
+ self.run_test_iothreads(None, 'iothread0',
86
+ "Cannot use a new backing file with a different AioContext")
87
88
if __name__ == '__main__':
89
iotests.main(supported_fmts=["qcow2"],
90
diff --git a/tests/qemu-iotests/245.out b/tests/qemu-iotests/245.out
12
index XXXXXXX..XXXXXXX 100644
91
index XXXXXXX..XXXXXXX 100644
13
--- a/block/nbd-client.c
92
--- a/tests/qemu-iotests/245.out
14
+++ b/block/nbd-client.c
93
+++ b/tests/qemu-iotests/245.out
15
@@ -XXX,XX +XXX,XX @@ int nbd_client_init(BlockDriverState *bs,
94
@@ -XXX,XX +XXX,XX @@
16
logout("Failed to negotiate with the NBD server\n");
95
-..................
17
return ret;
96
+.....................
18
}
97
----------------------------------------------------------------------
19
- if (client->info.flags & NBD_FLAG_READ_ONLY &&
98
-Ran 18 tests
20
- !bdrv_is_read_only(bs)) {
99
+Ran 21 tests
21
- error_setg(errp,
100
22
- "request for write access conflicts with read-only export");
101
OK
23
- return -EACCES;
102
{"execute": "job-finalize", "arguments": {"id": "commit0"}}
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
--
103
--
33
2.19.1
104
2.20.1
34
105
35
106
diff view generated by jsdifflib
1
Some block drivers have traditionally changed their node to read-only
1
This patch allows bdrv_reopen() (and therefore the x-blockdev-reopen QMP
2
mode without asking the user. This behaviour has been marked deprecated
2
command) to attach a node as the new backing file even if the node is in
3
since 2.11, expecting users to provide an explicit read-only=on option.
3
a different AioContext than the parent if one of both nodes can be moved
4
4
to the AioContext of the other node.
5
Now that we have auto-read-only=on, enable these drivers to make use of
6
the option.
7
8
This is the only use of bdrv_set_read_only(), so we can make it a bit
9
more specific and turn it into a bdrv_apply_auto_read_only() that is
10
more convenient for drivers to use.
11
5
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Reviewed-by: Eric Blake <eblake@redhat.com>
7
Tested-by: Peter Krempa <pkrempa@redhat.com>
8
Message-Id: <20200306141413.30705-3-kwolf@redhat.com>
9
Reviewed-by: Alberto Garcia <berto@igalia.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
11
---
15
include/block/block.h | 3 ++-
12
block.c | 32 ++++++++++++++++++++++++++------
16
block.c | 42 +++++++++++++++++++++++++++---------------
13
tests/qemu-iotests/245 | 8 +++-----
17
block/bochs.c | 17 ++++++-----------
14
2 files changed, 29 insertions(+), 11 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
15
24
diff --git a/include/block/block.h b/include/block/block.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/include/block/block.h
27
+++ b/include/block/block.h
28
@@ -XXX,XX +XXX,XX @@ int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
29
bool bdrv_is_read_only(BlockDriverState *bs);
30
int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
31
bool ignore_allow_rdw, Error **errp);
32
-int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp);
33
+int bdrv_apply_auto_read_only(BlockDriverState *bs, const char *errmsg,
34
+ Error **errp);
35
bool bdrv_is_writable(BlockDriverState *bs);
36
bool bdrv_is_sg(BlockDriverState *bs);
37
bool bdrv_is_inserted(BlockDriverState *bs);
38
diff --git a/block.c b/block.c
16
diff --git a/block.c b/block.c
39
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
40
--- a/block.c
18
--- a/block.c
41
+++ b/block.c
19
+++ b/block.c
42
@@ -XXX,XX +XXX,XX @@ int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
20
@@ -XXX,XX +XXX,XX @@ static void bdrv_reopen_perm(BlockReopenQueue *q, BlockDriverState *bs,
43
return 0;
21
*shared = cumulative_shared_perms;
44
}
22
}
45
23
46
-/* TODO Remove (deprecated since 2.11)
24
+static bool bdrv_reopen_can_attach(BlockDriverState *parent,
47
- * Block drivers are not supposed to automatically change bs->read_only.
25
+ BdrvChild *child,
48
- * Instead, they should just check whether they can provide what the user
26
+ BlockDriverState *new_child,
49
- * explicitly requested and error out if read-write is requested, but they can
27
+ Error **errp)
50
- * only provide read-only access. */
28
+{
51
-int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
29
+ AioContext *parent_ctx = bdrv_get_aio_context(parent);
52
+/*
30
+ AioContext *child_ctx = bdrv_get_aio_context(new_child);
53
+ * Called by a driver that can only provide a read-only image.
31
+ GSList *ignore;
54
+ *
32
+ bool ret;
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
{
65
int ret = 0;
66
67
- ret = bdrv_can_set_read_only(bs, read_only, false, errp);
68
- if (ret < 0) {
69
- return ret;
70
+ if (!(bs->open_flags & BDRV_O_RDWR)) {
71
+ return 0;
72
+ }
73
+ if (!(bs->open_flags & BDRV_O_AUTO_RDONLY)) {
74
+ goto fail;
75
}
76
77
- bs->read_only = read_only;
78
-
79
- if (read_only) {
80
- bs->open_flags &= ~BDRV_O_RDWR;
81
- } else {
82
- bs->open_flags |= BDRV_O_RDWR;
83
+ ret = bdrv_can_set_read_only(bs, true, false, NULL);
84
+ if (ret < 0) {
85
+ goto fail;
86
}
87
88
+ bs->read_only = true;
89
+ bs->open_flags &= ~BDRV_O_RDWR;
90
+
33
+
91
return 0;
34
+ ignore = g_slist_prepend(NULL, child);
92
+
35
+ ret = bdrv_can_set_aio_context(new_child, parent_ctx, &ignore, NULL);
93
+fail:
36
+ g_slist_free(ignore);
94
+ error_setg(errp, "%s", errmsg ?: "Image is read-only");
37
+ if (ret) {
95
+ return -EACCES;
96
}
97
98
void bdrv_get_full_backing_filename_from_filename(const char *backed,
99
diff --git a/block/bochs.c b/block/bochs.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/block/bochs.c
102
+++ b/block/bochs.c
103
@@ -XXX,XX +XXX,XX @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
104
struct bochs_header bochs;
105
int ret;
106
107
+ /* No write support yet */
108
+ ret = bdrv_apply_auto_read_only(bs, NULL, errp);
109
+ if (ret < 0) {
110
+ return ret;
38
+ return ret;
111
+ }
39
+ }
112
+
40
+
113
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
41
+ ignore = g_slist_prepend(NULL, child);
114
false, errp);
42
+ ret = bdrv_can_set_aio_context(parent, child_ctx, &ignore, errp);
115
if (!bs->file) {
43
+ g_slist_free(ignore);
116
return -EINVAL;
44
+ return ret;
45
+}
46
+
47
/*
48
* Take a BDRVReopenState and check if the value of 'backing' in the
49
* reopen_state->options QDict is valid or not.
50
@@ -XXX,XX +XXX,XX @@ static int bdrv_reopen_parse_backing(BDRVReopenState *reopen_state,
117
}
51
}
118
52
119
- if (!bdrv_is_read_only(bs)) {
53
/*
120
- error_report("Opening bochs images without an explicit read-only=on "
54
- * TODO: before removing the x- prefix from x-blockdev-reopen we
121
- "option is deprecated. Future versions will refuse to "
55
- * should move the new backing file into the right AioContext
122
- "open the image instead of automatically marking the "
56
- * instead of returning an error.
123
- "image read-only.");
57
+ * Check AioContext compatibility so that the bdrv_set_backing_hd() call in
124
- ret = bdrv_set_read_only(bs, true, errp); /* no write support yet */
58
+ * bdrv_reopen_commit() won't fail.
125
- if (ret < 0) {
59
*/
126
- return ret;
60
if (new_backing_bs) {
127
- }
61
- if (bdrv_get_aio_context(new_backing_bs) != bdrv_get_aio_context(bs)) {
128
- }
62
- error_setg(errp, "Cannot use a new backing file "
129
-
63
- "with a different AioContext");
130
ret = bdrv_pread(bs->file, 0, &bochs, sizeof(bochs));
64
+ if (!bdrv_reopen_can_attach(bs, bs->backing, new_backing_bs, errp)) {
131
if (ret < 0) {
65
return -EINVAL;
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
}
66
}
223
}
67
}
224
68
diff --git a/tests/qemu-iotests/245 b/tests/qemu-iotests/245
225
diff --git a/block/vvfat.c b/block/vvfat.c
69
index XXXXXXX..XXXXXXX 100755
226
index XXXXXXX..XXXXXXX 100644
70
--- a/tests/qemu-iotests/245
227
--- a/block/vvfat.c
71
+++ b/tests/qemu-iotests/245
228
+++ b/block/vvfat.c
72
@@ -XXX,XX +XXX,XX @@ class TestBlockdevReopen(iotests.QMPTestCase):
229
@@ -XXX,XX +XXX,XX @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
73
# neither of them can switch to the other AioContext
230
"Unable to set VVFAT to 'rw' when drive is read-only");
74
def test_iothreads_error(self):
231
goto fail;
75
self.run_test_iothreads('iothread0', 'iothread1',
232
}
76
- "Cannot use a new backing file with a different AioContext")
233
- } else if (!bdrv_is_read_only(bs)) {
77
+ "Cannot change iothread of active block backend")
234
- error_report("Opening non-rw vvfat images without an explicit "
78
235
- "read-only=on option is deprecated. Future versions "
79
def test_iothreads_compatible_users(self):
236
- "will refuse to open the image instead of "
80
self.run_test_iothreads('iothread0', 'iothread0')
237
- "automatically marking the image read-only.");
81
238
- /* read only is the default for safety */
82
def test_iothreads_switch_backing(self):
239
- ret = bdrv_set_read_only(bs, true, &local_err);
83
- self.run_test_iothreads('iothread0', None,
240
+ } else {
84
- "Cannot use a new backing file with a different AioContext")
241
+ ret = bdrv_apply_auto_read_only(bs, NULL, errp);
85
+ self.run_test_iothreads('iothread0', None)
242
if (ret < 0) {
86
243
- error_propagate(errp, local_err);
87
def test_iothreads_switch_overlay(self):
244
goto fail;
88
- self.run_test_iothreads(None, 'iothread0',
245
}
89
- "Cannot use a new backing file with a different AioContext")
246
}
90
+ self.run_test_iothreads(None, 'iothread0')
91
92
if __name__ == '__main__':
93
iotests.main(supported_fmts=["qcow2"],
247
--
94
--
248
2.19.1
95
2.20.1
249
96
250
97
diff view generated by jsdifflib