1
The following changes since commit f17783e706ab9c7b3a2b69cf48e4f0ba40664f54:
1
The following changes since commit db754f8ccaf2f073c9aed46a4389e9c0c2080399:
2
2
3
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20191220' into staging (2020-01-03 18:50:33 +0000)
3
Merge remote-tracking branch 'remotes/rth-gitlab/tags/pull-tcg-20210202' into staging (2021-02-03 19:35:57 +0000)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://github.com/XanClic/qemu.git tags/pull-block-2020-01-06
7
https://gitlab.com/stefanha/qemu.git tags/block-pull-request
8
8
9
for you to fetch changes up to 503ca1262bab2c11c533a4816d1ff4297d4f58a6:
9
for you to fetch changes up to abe42229db7b87caa11b3c02835ebf9d384e0bd4:
10
10
11
backup-top: Begin drain earlier (2020-01-06 14:26:23 +0100)
11
docs: fix Parallels Image "dirty bitmap" section (2021-02-04 15:17:10 +0000)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block patches:
14
Pull request
15
- Minor fixes and tests from the freeze period (too minor to be included
15
16
in 4.2)
16
v2:
17
- Allow many bash iotests to test qcow2's external data file feature
17
* Rebase to resolve memory_region_init_ram_from_file() conflict due to the new
18
- Add compress filter driver
18
offset argument that was added in qemu.git/master in the meantime [Peter]
19
- Fix Python iotests after 6f6e1698a6
20
- Fix for the backup job
21
19
22
----------------------------------------------------------------
20
----------------------------------------------------------------
23
Andrey Shinkevich (3):
24
block: introduce compress filter driver
25
qcow2: Allow writing compressed data of multiple clusters
26
tests/qemu-iotests: add case to write compressed data of multiple
27
clusters
28
21
29
Max Reitz (28):
22
Denis V. Lunev (1):
30
block: Add bdrv_qapi_perm_to_blk_perm()
23
docs: fix Parallels Image "dirty bitmap" section
31
block: Use bdrv_qapi_perm_to_blk_perm()
32
blkdebug: Allow taking/unsharing permissions
33
iotests: Add @error to wait_until_completed
34
iotests: Add test for failing mirror complete
35
iotests: s/qocw2/qcow2/
36
iotests/qcow2.py: Add dump-header-exts
37
iotests/qcow2.py: Split feature fields into bits
38
iotests: Add _filter_json_filename
39
iotests: Filter refcount_order in 036
40
iotests: Replace IMGOPTS by _unsupported_imgopts
41
iotests: Drop compat=1.1 in 050
42
iotests: Let _make_test_img parse its parameters
43
iotests: Add -o and --no-opts to _make_test_img
44
iotests: Inject space into -ocompat=0.10 in 051
45
iotests: Replace IMGOPTS= by -o
46
iotests: Replace IMGOPTS='' by --no-opts
47
iotests: Drop IMGOPTS use in 267
48
iotests: Avoid qemu-img create
49
iotests: Use _rm_test_img for deleting test images
50
iotests: Avoid cp/mv of test images
51
iotests: Make 091 work with data_file
52
iotests: Make 110 work with data_file
53
iotests: Make 137 work with data_file
54
iotests: Make 198 work with data_file
55
iotests: Disable data_file where it cannot be used
56
iotests: Allow check -o data_file
57
backup-top: Begin drain earlier
58
24
59
PanNengyuan (1):
25
Elena Ufimtseva (8):
60
throttle-groups: fix memory leak in throttle_group_set_limit:
26
multi-process: add configure and usage information
27
io: add qio_channel_writev_full_all helper
28
io: add qio_channel_readv_full_all_eof & qio_channel_readv_full_all
29
helpers
30
multi-process: define MPQemuMsg format and transmission functions
31
multi-process: introduce proxy object
32
multi-process: add proxy communication functions
33
multi-process: Forward PCI config space acceses to the remote process
34
multi-process: perform device reset in the remote process
61
35
62
Philippe Mathieu-Daudé (1):
36
Jagannathan Raman (11):
63
tests/qemu-iotests: Update tests to recent desugarized -accel option
37
memory: alloc RAM from file at offset
38
multi-process: Add config option for multi-process QEMU
39
multi-process: setup PCI host bridge for remote device
40
multi-process: setup a machine object for remote device process
41
multi-process: Initialize message handler in remote device
42
multi-process: Associate fd of a PCIDevice with its object
43
multi-process: setup memory manager for remote device
44
multi-process: PCI BAR read/write handling for proxy & remote
45
endpoints
46
multi-process: Synchronize remote memory
47
multi-process: create IOHUB object to handle irq
48
multi-process: Retrieve PCI info from remote process
64
49
65
Vladimir Sementsov-Ogievskiy (1):
50
John G Johnson (1):
66
qcow2-bitmaps: fix qcow2_can_store_new_dirty_bitmap
51
multi-process: add the concept description to
52
docs/devel/qemu-multiprocess
67
53
68
block.c | 47 +++++----
54
Stefan Hajnoczi (6):
69
block/Makefile.objs | 1 +
55
.github: point Repo Lockdown bot to GitLab repo
70
block/backup-top.c | 4 +-
56
gitmodules: use GitLab repos instead of qemu.org
71
block/blkdebug.c | 93 ++++++++++++++++-
57
gitlab-ci: remove redundant GitLab repo URL command
72
block/filter-compress.c | 168 +++++++++++++++++++++++++++++++
58
docs: update README to use GitLab repo URLs
73
block/qcow2-bitmap.c | 41 ++++----
59
pc-bios: update mirror URLs to GitLab
74
block/qcow2.c | 102 ++++++++++++++-----
60
get_maintainer: update repo URL to GitLab
75
block/throttle-groups.c | 4 +-
61
76
include/block/block.h | 1 +
62
MAINTAINERS | 24 +
77
qapi/block-core.json | 24 ++++-
63
README.rst | 4 +-
78
tests/qemu-iotests/007 | 5 +-
64
docs/devel/index.rst | 1 +
79
tests/qemu-iotests/014 | 2 +
65
docs/devel/multi-process.rst | 966 ++++++++++++++++++++++
80
tests/qemu-iotests/015 | 5 +-
66
docs/system/index.rst | 1 +
81
tests/qemu-iotests/019 | 6 +-
67
docs/system/multi-process.rst | 64 ++
82
tests/qemu-iotests/020 | 6 +-
68
docs/interop/parallels.txt | 2 +-
83
tests/qemu-iotests/024 | 10 +-
69
configure | 10 +
84
tests/qemu-iotests/026 | 5 +-
70
meson.build | 5 +-
85
tests/qemu-iotests/028 | 2 +-
71
hw/remote/trace.h | 1 +
86
tests/qemu-iotests/029 | 7 +-
72
include/exec/memory.h | 2 +
87
tests/qemu-iotests/031 | 9 +-
73
include/exec/ram_addr.h | 4 +-
88
tests/qemu-iotests/031.out | 36 +++----
74
include/hw/pci-host/remote.h | 30 +
89
tests/qemu-iotests/036 | 15 +--
75
include/hw/pci/pci_ids.h | 3 +
90
tests/qemu-iotests/036.out | 66 ++----------
76
include/hw/remote/iohub.h | 42 +
91
tests/qemu-iotests/039 | 27 ++---
77
include/hw/remote/machine.h | 38 +
92
tests/qemu-iotests/039.out | 22 ++--
78
include/hw/remote/memory.h | 19 +
93
tests/qemu-iotests/041 | 44 ++++++++
79
include/hw/remote/mpqemu-link.h | 99 +++
94
tests/qemu-iotests/041.out | 4 +-
80
include/hw/remote/proxy-memory-listener.h | 28 +
95
tests/qemu-iotests/043 | 4 +-
81
include/hw/remote/proxy.h | 48 ++
96
tests/qemu-iotests/046 | 2 +
82
include/io/channel.h | 78 ++
97
tests/qemu-iotests/048 | 4 +-
83
include/qemu/mmap-alloc.h | 4 +-
98
tests/qemu-iotests/050 | 8 +-
84
include/sysemu/iothread.h | 6 +
99
tests/qemu-iotests/051 | 7 +-
85
backends/hostmem-memfd.c | 2 +-
100
tests/qemu-iotests/053 | 4 +-
86
hw/misc/ivshmem.c | 3 +-
101
tests/qemu-iotests/058 | 7 +-
87
hw/pci-host/remote.c | 75 ++
102
tests/qemu-iotests/059 | 20 ++--
88
hw/remote/iohub.c | 119 +++
103
tests/qemu-iotests/060 | 14 +--
89
hw/remote/machine.c | 80 ++
104
tests/qemu-iotests/060.out | 20 ++--
90
hw/remote/memory.c | 65 ++
105
tests/qemu-iotests/061 | 63 ++++++------
91
hw/remote/message.c | 230 ++++++
106
tests/qemu-iotests/061.out | 72 ++++++-------
92
hw/remote/mpqemu-link.c | 267 ++++++
107
tests/qemu-iotests/062 | 5 +-
93
hw/remote/proxy-memory-listener.c | 227 +++++
108
tests/qemu-iotests/063 | 18 ++--
94
hw/remote/proxy.c | 379 +++++++++
109
tests/qemu-iotests/063.out | 3 +-
95
hw/remote/remote-obj.c | 203 +++++
110
tests/qemu-iotests/066 | 7 +-
96
io/channel.c | 116 ++-
111
tests/qemu-iotests/067 | 6 +-
97
iothread.c | 6 +
112
tests/qemu-iotests/068 | 6 +-
98
softmmu/memory.c | 3 +-
113
tests/qemu-iotests/069 | 2 +-
99
softmmu/physmem.c | 12 +-
114
tests/qemu-iotests/071 | 7 +-
100
util/mmap-alloc.c | 8 +-
115
tests/qemu-iotests/073 | 4 +
101
util/oslib-posix.c | 2 +-
116
tests/qemu-iotests/074 | 4 +-
102
.github/lockdown.yml | 8 +-
117
tests/qemu-iotests/079 | 3 +-
103
.gitlab-ci.yml | 1 -
118
tests/qemu-iotests/080 | 7 +-
104
.gitmodules | 44 +-
119
tests/qemu-iotests/081 | 6 +-
105
Kconfig.host | 4 +
120
tests/qemu-iotests/085 | 18 ++--
106
hw/Kconfig | 1 +
121
tests/qemu-iotests/085.out | 8 +-
107
hw/meson.build | 1 +
122
tests/qemu-iotests/088 | 2 +-
108
hw/pci-host/Kconfig | 3 +
123
tests/qemu-iotests/090 | 2 +
109
hw/pci-host/meson.build | 1 +
124
tests/qemu-iotests/091 | 2 +-
110
hw/remote/Kconfig | 4 +
125
tests/qemu-iotests/091.out | 2 -
111
hw/remote/meson.build | 13 +
126
tests/qemu-iotests/092 | 2 +-
112
hw/remote/trace-events | 4 +
127
tests/qemu-iotests/094 | 4 +-
113
pc-bios/README | 4 +-
128
tests/qemu-iotests/095 | 5 +-
114
scripts/get_maintainer.pl | 2 +-
129
tests/qemu-iotests/098 | 6 +-
115
53 files changed, 3296 insertions(+), 70 deletions(-)
130
tests/qemu-iotests/099 | 10 +-
116
create mode 100644 docs/devel/multi-process.rst
131
tests/qemu-iotests/103 | 5 +-
117
create mode 100644 docs/system/multi-process.rst
132
tests/qemu-iotests/106 | 2 +-
118
create mode 100644 hw/remote/trace.h
133
tests/qemu-iotests/108 | 10 +-
119
create mode 100644 include/hw/pci-host/remote.h
134
tests/qemu-iotests/109 | 4 +-
120
create mode 100644 include/hw/remote/iohub.h
135
tests/qemu-iotests/110 | 11 +-
121
create mode 100644 include/hw/remote/machine.h
136
tests/qemu-iotests/110.out | 4 +-
122
create mode 100644 include/hw/remote/memory.h
137
tests/qemu-iotests/111 | 3 +-
123
create mode 100644 include/hw/remote/mpqemu-link.h
138
tests/qemu-iotests/112 | 37 +++----
124
create mode 100644 include/hw/remote/proxy-memory-listener.h
139
tests/qemu-iotests/114 | 2 +
125
create mode 100644 include/hw/remote/proxy.h
140
tests/qemu-iotests/115 | 3 +-
126
create mode 100644 hw/pci-host/remote.c
141
tests/qemu-iotests/121 | 9 +-
127
create mode 100644 hw/remote/iohub.c
142
tests/qemu-iotests/122 | 6 +-
128
create mode 100644 hw/remote/machine.c
143
tests/qemu-iotests/123 | 4 +-
129
create mode 100644 hw/remote/memory.c
144
tests/qemu-iotests/125 | 2 +-
130
create mode 100644 hw/remote/message.c
145
tests/qemu-iotests/137 | 17 +++-
131
create mode 100644 hw/remote/mpqemu-link.c
146
tests/qemu-iotests/137.out | 6 +-
132
create mode 100644 hw/remote/proxy-memory-listener.c
147
tests/qemu-iotests/138 | 8 +-
133
create mode 100644 hw/remote/proxy.c
148
tests/qemu-iotests/141 | 4 +-
134
create mode 100644 hw/remote/remote-obj.c
149
tests/qemu-iotests/142 | 2 +-
135
create mode 100644 hw/remote/Kconfig
150
tests/qemu-iotests/144 | 4 +-
136
create mode 100644 hw/remote/meson.build
151
tests/qemu-iotests/153 | 12 +--
137
create mode 100644 hw/remote/trace-events
152
tests/qemu-iotests/156 | 10 +-
153
tests/qemu-iotests/159 | 2 +-
154
tests/qemu-iotests/160 | 3 +-
155
tests/qemu-iotests/161 | 4 +-
156
tests/qemu-iotests/170 | 2 +-
157
tests/qemu-iotests/172 | 6 +-
158
tests/qemu-iotests/173 | 3 +-
159
tests/qemu-iotests/174 | 2 +-
160
tests/qemu-iotests/175 | 2 +-
161
tests/qemu-iotests/176 | 7 +-
162
tests/qemu-iotests/178 | 6 +-
163
tests/qemu-iotests/182 | 2 +-
164
tests/qemu-iotests/183 | 2 +-
165
tests/qemu-iotests/185 | 4 +-
166
tests/qemu-iotests/187 | 6 +-
167
tests/qemu-iotests/190 | 4 +-
168
tests/qemu-iotests/191 | 11 +-
169
tests/qemu-iotests/195 | 2 +-
170
tests/qemu-iotests/197 | 6 +-
171
tests/qemu-iotests/198 | 6 +-
172
tests/qemu-iotests/198.out | 4 +-
173
tests/qemu-iotests/200 | 7 +-
174
tests/qemu-iotests/201 | 6 +-
175
tests/qemu-iotests/214 | 46 ++++++++-
176
tests/qemu-iotests/214.out | 14 +++
177
tests/qemu-iotests/215 | 6 +-
178
tests/qemu-iotests/217 | 3 +-
179
tests/qemu-iotests/220 | 5 +-
180
tests/qemu-iotests/225 | 2 +-
181
tests/qemu-iotests/229 | 3 +-
182
tests/qemu-iotests/232 | 4 +-
183
tests/qemu-iotests/235 | 2 +-
184
tests/qemu-iotests/243 | 10 +-
185
tests/qemu-iotests/244 | 15 +--
186
tests/qemu-iotests/247 | 4 +-
187
tests/qemu-iotests/249 | 4 +-
188
tests/qemu-iotests/250 | 5 +-
189
tests/qemu-iotests/252 | 2 +-
190
tests/qemu-iotests/261 | 5 +-
191
tests/qemu-iotests/265 | 2 +-
192
tests/qemu-iotests/267 | 17 ++--
193
tests/qemu-iotests/273 | 3 +
194
tests/qemu-iotests/check | 6 +-
195
tests/qemu-iotests/common.filter | 47 ++++++++-
196
tests/qemu-iotests/common.rc | 63 ++++++++++--
197
tests/qemu-iotests/iotests.py | 18 ++--
198
tests/qemu-iotests/qcow2.py | 23 ++++-
199
131 files changed, 1139 insertions(+), 552 deletions(-)
200
create mode 100644 block/filter-compress.c
201
138
202
--
139
--
203
2.24.1
140
2.29.2
204
141
205
diff view generated by jsdifflib
1
When dropping backup-top, we need to drain the node before freeing the
1
Use the GitLab repo URL as the main repo location in order to reduce
2
BlockCopyState. Otherwise, requests may still be in flight and then the
2
load on qemu.org.
3
assertion in shres_destroy() will fail.
4
3
5
(This becomes visible in intermittent failure of 056.)
4
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
5
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
6
Reviewed-by: Thomas Huth <thuth@redhat.com>
7
Message-id: 20210111115017.156802-2-stefanha@redhat.com
8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
---
10
.github/lockdown.yml | 8 ++++----
11
1 file changed, 4 insertions(+), 4 deletions(-)
6
12
7
Cc: qemu-stable@nongnu.org
13
diff --git a/.github/lockdown.yml b/.github/lockdown.yml
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
index XXXXXXX..XXXXXXX 100644
9
Message-id: 20191219182638.104621-1-mreitz@redhat.com
15
--- a/.github/lockdown.yml
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
16
+++ b/.github/lockdown.yml
11
---
17
@@ -XXX,XX +XXX,XX @@ issues:
12
block/backup-top.c | 4 ++--
18
comment: |
13
1 file changed, 2 insertions(+), 2 deletions(-)
19
Thank you for your interest in the QEMU project.
20
21
- This repository is a read-only mirror of the project's master
22
- repostories hosted on https://git.qemu.org/git/qemu.git.
23
+ This repository is a read-only mirror of the project's repostories hosted
24
+ at https://gitlab.com/qemu-project/qemu.git.
25
The project does not process issues filed on GitHub.
26
27
The project issues are tracked on Launchpad:
28
@@ -XXX,XX +XXX,XX @@ pulls:
29
comment: |
30
Thank you for your interest in the QEMU project.
31
32
- This repository is a read-only mirror of the project's master
33
- repostories hosted on https://git.qemu.org/git/qemu.git.
34
+ This repository is a read-only mirror of the project's repostories hosted
35
+ on https://gitlab.com/qemu-project/qemu.git.
36
The project does not process merge requests filed on GitHub.
37
38
QEMU welcomes contributions of code (either fixing bugs or adding new
39
--
40
2.29.2
14
41
15
diff --git a/block/backup-top.c b/block/backup-top.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/block/backup-top.c
18
+++ b/block/backup-top.c
19
@@ -XXX,XX +XXX,XX @@ void bdrv_backup_top_drop(BlockDriverState *bs)
20
BDRVBackupTopState *s = bs->opaque;
21
AioContext *aio_context = bdrv_get_aio_context(bs);
22
23
- block_copy_state_free(s->bcs);
24
-
25
aio_context_acquire(aio_context);
26
27
bdrv_drained_begin(bs);
28
29
+ block_copy_state_free(s->bcs);
30
+
31
s->active = false;
32
bdrv_child_refresh_perms(bs, bs->backing, &error_abort);
33
bdrv_replace_node(bs, backing_bs(bs), &error_abort);
34
--
35
2.24.1
36
37
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
qemu.org is running out of bandwidth and the QEMU project is moving
2
towards a gating CI on GitLab. Use the GitLab repos instead of qemu.org
3
(they will become mirrors).
2
4
3
Commit 6f6e1698a6 desugarized "-machine accel=" to a list
5
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
4
of "-accel" options. Since now "-machine accel" and "-accel"
6
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
5
became incompatible, update the iotests to the new format.
7
Reviewed-by: Thomas Huth <thuth@redhat.com>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20210111115017.156802-3-stefanha@redhat.com
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
11
---
12
.gitmodules | 44 ++++++++++++++++++++++----------------------
13
1 file changed, 22 insertions(+), 22 deletions(-)
6
14
7
Error reported here:
15
diff --git a/.gitmodules b/.gitmodules
8
https://gitlab.com/qemu-project/qemu/-/jobs/385801004#L3400
16
index XXXXXXX..XXXXXXX 100644
17
--- a/.gitmodules
18
+++ b/.gitmodules
19
@@ -XXX,XX +XXX,XX @@
20
[submodule "roms/seabios"]
21
    path = roms/seabios
22
-    url = https://git.qemu.org/git/seabios.git/
23
+    url = https://gitlab.com/qemu-project/seabios.git/
24
[submodule "roms/SLOF"]
25
    path = roms/SLOF
26
-    url = https://git.qemu.org/git/SLOF.git
27
+    url = https://gitlab.com/qemu-project/SLOF.git
28
[submodule "roms/ipxe"]
29
    path = roms/ipxe
30
-    url = https://git.qemu.org/git/ipxe.git
31
+    url = https://gitlab.com/qemu-project/ipxe.git
32
[submodule "roms/openbios"]
33
    path = roms/openbios
34
-    url = https://git.qemu.org/git/openbios.git
35
+    url = https://gitlab.com/qemu-project/openbios.git
36
[submodule "roms/qemu-palcode"]
37
    path = roms/qemu-palcode
38
-    url = https://git.qemu.org/git/qemu-palcode.git
39
+    url = https://gitlab.com/qemu-project/qemu-palcode.git
40
[submodule "roms/sgabios"]
41
    path = roms/sgabios
42
-    url = https://git.qemu.org/git/sgabios.git
43
+    url = https://gitlab.com/qemu-project/sgabios.git
44
[submodule "dtc"]
45
    path = dtc
46
-    url = https://git.qemu.org/git/dtc.git
47
+    url = https://gitlab.com/qemu-project/dtc.git
48
[submodule "roms/u-boot"]
49
    path = roms/u-boot
50
-    url = https://git.qemu.org/git/u-boot.git
51
+    url = https://gitlab.com/qemu-project/u-boot.git
52
[submodule "roms/skiboot"]
53
    path = roms/skiboot
54
-    url = https://git.qemu.org/git/skiboot.git
55
+    url = https://gitlab.com/qemu-project/skiboot.git
56
[submodule "roms/QemuMacDrivers"]
57
    path = roms/QemuMacDrivers
58
-    url = https://git.qemu.org/git/QemuMacDrivers.git
59
+    url = https://gitlab.com/qemu-project/QemuMacDrivers.git
60
[submodule "ui/keycodemapdb"]
61
    path = ui/keycodemapdb
62
-    url = https://git.qemu.org/git/keycodemapdb.git
63
+    url = https://gitlab.com/qemu-project/keycodemapdb.git
64
[submodule "capstone"]
65
    path = capstone
66
-    url = https://git.qemu.org/git/capstone.git
67
+    url = https://gitlab.com/qemu-project/capstone.git
68
[submodule "roms/seabios-hppa"]
69
    path = roms/seabios-hppa
70
-    url = https://git.qemu.org/git/seabios-hppa.git
71
+    url = https://gitlab.com/qemu-project/seabios-hppa.git
72
[submodule "roms/u-boot-sam460ex"]
73
    path = roms/u-boot-sam460ex
74
-    url = https://git.qemu.org/git/u-boot-sam460ex.git
75
+    url = https://gitlab.com/qemu-project/u-boot-sam460ex.git
76
[submodule "tests/fp/berkeley-testfloat-3"]
77
    path = tests/fp/berkeley-testfloat-3
78
-    url = https://git.qemu.org/git/berkeley-testfloat-3.git
79
+    url = https://gitlab.com/qemu-project/berkeley-testfloat-3.git
80
[submodule "tests/fp/berkeley-softfloat-3"]
81
    path = tests/fp/berkeley-softfloat-3
82
-    url = https://git.qemu.org/git/berkeley-softfloat-3.git
83
+    url = https://gitlab.com/qemu-project/berkeley-softfloat-3.git
84
[submodule "roms/edk2"]
85
    path = roms/edk2
86
-    url = https://git.qemu.org/git/edk2.git
87
+    url = https://gitlab.com/qemu-project/edk2.git
88
[submodule "slirp"]
89
    path = slirp
90
-    url = https://git.qemu.org/git/libslirp.git
91
+    url = https://gitlab.com/qemu-project/libslirp.git
92
[submodule "roms/opensbi"]
93
    path = roms/opensbi
94
-    url =     https://git.qemu.org/git/opensbi.git
95
+    url =     https://gitlab.com/qemu-project/opensbi.git
96
[submodule "roms/qboot"]
97
    path = roms/qboot
98
-    url = https://git.qemu.org/git/qboot.git
99
+    url = https://gitlab.com/qemu-project/qboot.git
100
[submodule "meson"]
101
    path = meson
102
-    url = https://git.qemu.org/git/meson.git
103
+    url = https://gitlab.com/qemu-project/meson.git
104
[submodule "roms/vbootrom"]
105
    path = roms/vbootrom
106
-    url = https://git.qemu.org/git/vbootrom.git
107
+    url = https://gitlab.com/qemu-project/vbootrom.git
108
--
109
2.29.2
9
110
10
Reported-by: GitLab CI
11
Fixes: 6f6e1698a6 (vl: configure accelerators from -accel options)
12
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
Message-id: 20200106130951.29873-1-philmd@redhat.com
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
15
---
16
tests/qemu-iotests/235 | 2 +-
17
tests/qemu-iotests/check | 6 +++---
18
2 files changed, 4 insertions(+), 4 deletions(-)
19
20
diff --git a/tests/qemu-iotests/235 b/tests/qemu-iotests/235
21
index XXXXXXX..XXXXXXX 100755
22
--- a/tests/qemu-iotests/235
23
+++ b/tests/qemu-iotests/235
24
@@ -XXX,XX +XXX,XX @@ qemu_img_create('-f', iotests.imgfmt, '-o', 'preallocation=metadata', disk,
25
str(size))
26
27
vm = QEMUMachine(iotests.qemu_prog)
28
-vm.add_args('-machine', 'accel=kvm:tcg')
29
+vm.add_args('-accel', 'kvm', '-accel', 'tcg')
30
if iotests.qemu_default_machine == 's390-ccw-virtio':
31
vm.add_args('-no-shutdown')
32
vm.add_args('-drive', 'id=src,file=' + disk)
33
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
34
index XXXXXXX..XXXXXXX 100755
35
--- a/tests/qemu-iotests/check
36
+++ b/tests/qemu-iotests/check
37
@@ -XXX,XX +XXX,XX @@ export QEMU_PROG="$(type -p "$QEMU_PROG")"
38
39
case "$QEMU_PROG" in
40
*qemu-system-arm|*qemu-system-aarch64)
41
- export QEMU_OPTIONS="-nodefaults -display none -machine virt,accel=qtest"
42
+ export QEMU_OPTIONS="-nodefaults -display none -machine virt -accel qtest"
43
;;
44
*qemu-system-tricore)
45
- export QEMU_OPTIONS="-nodefaults -display none -machine tricore_testboard,accel=qtest"
46
+ export QEMU_OPTIONS="-nodefaults -display none -machine tricore_testboard -accel qtest"
47
;;
48
*)
49
- export QEMU_OPTIONS="-nodefaults -display none -machine accel=qtest"
50
+ export QEMU_OPTIONS="-nodefaults -display none -accel qtest"
51
;;
52
esac
53
54
--
55
2.24.1
56
57
diff view generated by jsdifflib
1
From: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
1
It is no longer necessary to point .gitmodules at GitLab repos when
2
running in GitLab CI since they are now used all the time.
2
3
3
Add the case to the iotest #214 that checks possibility of writing
4
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
4
compressed data of more than one cluster size. The test case involves
5
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
5
the compress filter driver showing a sample usage of that.
6
Reviewed-by: Thomas Huth <thuth@redhat.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20210111115017.156802-4-stefanha@redhat.com
9
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
10
---
11
.gitlab-ci.yml | 1 -
12
1 file changed, 1 deletion(-)
6
13
7
Signed-off-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
14
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
8
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
15
index XXXXXXX..XXXXXXX 100644
9
Reviewed-by: Max Reitz <mreitz@redhat.com>
16
--- a/.gitlab-ci.yml
10
Message-id: 1575288906-551879-4-git-send-email-andrey.shinkevich@virtuozzo.com
17
+++ b/.gitlab-ci.yml
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
18
@@ -XXX,XX +XXX,XX @@ include:
12
---
19
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:latest
13
tests/qemu-iotests/214 | 43 ++++++++++++++++++++++++++++++++++++++
20
before_script:
14
tests/qemu-iotests/214.out | 14 +++++++++++++
21
- JOBS=$(expr $(nproc) + 1)
15
2 files changed, 57 insertions(+)
22
- - sed -i s,git.qemu.org/git,gitlab.com/qemu-project, .gitmodules
23
script:
24
- mkdir build
25
- cd build
26
--
27
2.29.2
16
28
17
diff --git a/tests/qemu-iotests/214 b/tests/qemu-iotests/214
18
index XXXXXXX..XXXXXXX 100755
19
--- a/tests/qemu-iotests/214
20
+++ b/tests/qemu-iotests/214
21
@@ -XXX,XX +XXX,XX @@ _check_test_img -r all
22
$QEMU_IO -c "read -P 0x11 0 4M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
23
$QEMU_IO -c "read -P 0x22 4M 4M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir
24
25
+echo
26
+echo "=== Write compressed data of multiple clusters ==="
27
+echo
28
+cluster_size=0x10000
29
+_make_test_img 2M -o cluster_size=$cluster_size
30
+
31
+echo "Write uncompressed data:"
32
+let data_size="8 * $cluster_size"
33
+$QEMU_IO -c "write -P 0xaa 0 $data_size" "$TEST_IMG" \
34
+ 2>&1 | _filter_qemu_io | _filter_testdir
35
+sizeA=$($QEMU_IMG info --output=json "$TEST_IMG" |
36
+ sed -n '/"actual-size":/ s/[^0-9]//gp')
37
+
38
+_make_test_img 2M -o cluster_size=$cluster_size
39
+echo "Write compressed data:"
40
+let data_size="3 * $cluster_size + $cluster_size / 2"
41
+# Set compress on. That will align the written data
42
+# by the cluster size and will write them compressed.
43
+QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT \
44
+$QEMU_IO -c "write -P 0xbb 0 $data_size" --image-opts \
45
+ "driver=compress,file.driver=$IMGFMT,file.file.driver=file,file.file.filename=$TEST_IMG" \
46
+ 2>&1 | _filter_qemu_io | _filter_testdir
47
+
48
+let offset="4 * $cluster_size + $cluster_size / 4"
49
+QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT \
50
+$QEMU_IO -c "write -P 0xcc $offset $data_size" "json:{\
51
+ 'driver': 'compress',
52
+ 'file': {'driver': '$IMGFMT',
53
+ 'file': {'driver': 'file',
54
+ 'filename': '$TEST_IMG'}}}" | \
55
+ _filter_qemu_io | _filter_testdir
56
+
57
+sizeB=$($QEMU_IMG info --output=json "$TEST_IMG" |
58
+ sed -n '/"actual-size":/ s/[^0-9]//gp')
59
+
60
+if [ $sizeA -le $sizeB ]
61
+then
62
+ echo "Compression ERROR"
63
+fi
64
+
65
+$QEMU_IMG check --output=json "$TEST_IMG" |
66
+ sed -n 's/,$//; /"compressed-clusters":/ s/^ *//p'
67
+
68
# success, all done
69
echo '*** done'
70
rm -f $seq.full
71
diff --git a/tests/qemu-iotests/214.out b/tests/qemu-iotests/214.out
72
index XXXXXXX..XXXXXXX 100644
73
--- a/tests/qemu-iotests/214.out
74
+++ b/tests/qemu-iotests/214.out
75
@@ -XXX,XX +XXX,XX @@ read 4194304/4194304 bytes at offset 0
76
4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
77
read 4194304/4194304 bytes at offset 4194304
78
4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
79
+
80
+=== Write compressed data of multiple clusters ===
81
+
82
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2097152
83
+Write uncompressed data:
84
+wrote 524288/524288 bytes at offset 0
85
+512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
86
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2097152
87
+Write compressed data:
88
+wrote 229376/229376 bytes at offset 0
89
+224 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
90
+wrote 229376/229376 bytes at offset 278528
91
+224 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
92
+"compressed-clusters": 8
93
*** done
94
--
95
2.24.1
96
97
diff view generated by jsdifflib
1
Use _make_test_img whenever possible. This way, we will not ignore
1
qemu.org is running out of bandwidth and the QEMU project is moving
2
user-specified image options.
2
towards a gating CI on GitLab. Use the GitLab repos instead of qemu.org
3
(they will become mirrors).
3
4
4
Signed-off-by: Max Reitz <mreitz@redhat.com>
5
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
5
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
6
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
6
Message-id: 20191107163708.833192-15-mreitz@redhat.com
7
Reviewed-by: Thomas Huth <thuth@redhat.com>
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20210111115017.156802-5-stefanha@redhat.com
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
8
---
11
---
9
tests/qemu-iotests/094 | 2 +-
12
README.rst | 4 ++--
10
tests/qemu-iotests/111 | 3 +--
13
1 file changed, 2 insertions(+), 2 deletions(-)
11
tests/qemu-iotests/123 | 2 +-
12
tests/qemu-iotests/153 | 2 +-
13
tests/qemu-iotests/200 | 4 ++--
14
5 files changed, 6 insertions(+), 7 deletions(-)
15
14
16
diff --git a/tests/qemu-iotests/094 b/tests/qemu-iotests/094
15
diff --git a/README.rst b/README.rst
17
index XXXXXXX..XXXXXXX 100755
16
index XXXXXXX..XXXXXXX 100644
18
--- a/tests/qemu-iotests/094
17
--- a/README.rst
19
+++ b/tests/qemu-iotests/094
18
+++ b/README.rst
20
@@ -XXX,XX +XXX,XX @@ _supported_proto nbd
19
@@ -XXX,XX +XXX,XX @@ The QEMU source code is maintained under the GIT version control system.
21
_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat"
20
22
21
.. code-block:: shell
23
_make_test_img 64M
22
24
-$QEMU_IMG create -f $IMGFMT "$TEST_DIR/source.$IMGFMT" 64M | _filter_img_create
23
- git clone https://git.qemu.org/git/qemu.git
25
+TEST_IMG_FILE="$TEST_DIR/source.$IMGFMT" IMGPROTO=file _make_test_img 64M
24
+ git clone https://gitlab.com/qemu-project/qemu.git
26
25
27
_launch_qemu -drive if=none,id=src,file="$TEST_DIR/source.$IMGFMT",format=raw \
26
When submitting patches, one common approach is to use 'git
28
-nodefaults
27
format-patch' and/or 'git send-email' to format & send the mail to the
29
diff --git a/tests/qemu-iotests/111 b/tests/qemu-iotests/111
28
@@ -XXX,XX +XXX,XX @@ The QEMU website is also maintained under source control.
30
index XXXXXXX..XXXXXXX 100755
29
31
--- a/tests/qemu-iotests/111
30
.. code-block:: shell
32
+++ b/tests/qemu-iotests/111
31
33
@@ -XXX,XX +XXX,XX @@ _supported_fmt qed qcow qcow2 vmdk
32
- git clone https://git.qemu.org/git/qemu-web.git
34
_supported_proto file
33
+ git clone https://gitlab.com/qemu-project/qemu-web.git
35
_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat"
34
36
35
* `<https://www.qemu.org/2017/02/04/the-new-qemu-website-is-up/>`_
37
-$QEMU_IMG create -f $IMGFMT -b "$TEST_IMG.inexistent" "$TEST_IMG" 2>&1 \
38
- | _filter_testdir | _filter_imgfmt
39
+_make_test_img -b "$TEST_IMG.inexistent"
40
41
# success, all done
42
echo '*** done'
43
diff --git a/tests/qemu-iotests/123 b/tests/qemu-iotests/123
44
index XXXXXXX..XXXXXXX 100755
45
--- a/tests/qemu-iotests/123
46
+++ b/tests/qemu-iotests/123
47
@@ -XXX,XX +XXX,XX @@ _supported_os Linux
48
SRC_IMG="$TEST_DIR/source.$IMGFMT"
49
50
_make_test_img 1M
51
-$QEMU_IMG create -f $IMGFMT "$SRC_IMG" 1M | _filter_img_create
52
+TEST_IMG_FILE=$SRC_IMG IMGPROTO=file _make_test_img 1M
53
54
$QEMU_IO -c 'write -P 42 0 1M' "$SRC_IMG" | _filter_qemu_io
55
56
diff --git a/tests/qemu-iotests/153 b/tests/qemu-iotests/153
57
index XXXXXXX..XXXXXXX 100755
58
--- a/tests/qemu-iotests/153
59
+++ b/tests/qemu-iotests/153
60
@@ -XXX,XX +XXX,XX @@ for opts1 in "" "read-only=on" "read-only=on,force-share=on"; do
61
62
echo
63
echo "== Creating test image =="
64
- $QEMU_IMG create -f $IMGFMT "${TEST_IMG}" -b ${TEST_IMG}.base | _filter_img_create
65
+ _make_test_img -b "${TEST_IMG}.base"
66
67
echo
68
echo "== Launching QEMU, opts: '$opts1' =="
69
diff --git a/tests/qemu-iotests/200 b/tests/qemu-iotests/200
70
index XXXXXXX..XXXXXXX 100755
71
--- a/tests/qemu-iotests/200
72
+++ b/tests/qemu-iotests/200
73
@@ -XXX,XX +XXX,XX @@ _supported_proto file
74
BACKING_IMG="${TEST_DIR}/backing.img"
75
TEST_IMG="${TEST_DIR}/test.img"
76
77
-${QEMU_IMG} create -f $IMGFMT "${BACKING_IMG}" 512M | _filter_img_create
78
-${QEMU_IMG} create -f $IMGFMT -F $IMGFMT "${TEST_IMG}" -b "${BACKING_IMG}" 512M | _filter_img_create
79
+TEST_IMG="$BACKING_IMG" _make_test_img 512M
80
+_make_test_img -F $IMGFMT -b "$BACKING_IMG" 512M
81
82
${QEMU_IO} -c "write -P 0xa5 512 300M" "${BACKING_IMG}" | _filter_qemu_io
83
36
84
--
37
--
85
2.24.1
38
2.29.2
86
39
87
diff view generated by jsdifflib
1
From: PanNengyuan <pannengyuan@huawei.com>
1
qemu.org is running out of bandwidth and the QEMU project is moving
2
towards a gating CI on GitLab. Use the GitLab repos instead of qemu.org
3
(they will become mirrors).
2
4
3
This avoid a memory leak when qom-set is called to set throttle_group
5
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
4
limits, here is an easy way to reproduce:
6
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
5
7
Reviewed-by: Thomas Huth <thuth@redhat.com>
6
1. run qemu-iotests as follow and check the result with asan:
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
./check -qcow2 184
9
Message-id: 20210111115017.156802-6-stefanha@redhat.com
8
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Following is the asan output backtrack:
10
Direct leak of 912 byte(s) in 3 object(s) allocated from:
11
#0 0xffff8d7ab3c3 in __interceptor_calloc (/lib64/libasan.so.4+0xd33c3)
12
#1 0xffff8d4c31cb in g_malloc0 (/lib64/libglib-2.0.so.0+0x571cb)
13
#2 0x190c857 in qobject_input_start_struct /mnt/sdc/qemu-master/qemu-4.2.0-rc0/qapi/qobject-input-visitor.c:295
14
#3 0x19070df in visit_start_struct /mnt/sdc/qemu-master/qemu-4.2.0-rc0/qapi/qapi-visit-core.c:49
15
#4 0x1948b87 in visit_type_ThrottleLimits qapi/qapi-visit-block-core.c:3759
16
#5 0x17e4aa3 in throttle_group_set_limits /mnt/sdc/qemu-master/qemu-4.2.0-rc0/block/throttle-groups.c:900
17
#6 0x1650eff in object_property_set /mnt/sdc/qemu-master/qemu-4.2.0-rc0/qom/object.c:1272
18
#7 0x1658517 in object_property_set_qobject /mnt/sdc/qemu-master/qemu-4.2.0-rc0/qom/qom-qobject.c:26
19
#8 0x15880bb in qmp_qom_set /mnt/sdc/qemu-master/qemu-4.2.0-rc0/qom/qom-qmp-cmds.c:74
20
#9 0x157e3e3 in qmp_marshal_qom_set qapi/qapi-commands-qom.c:154
21
22
Reported-by: Euler Robot <euler.robot@huawei.com>
23
Signed-off-by: PanNengyuan <pannengyuan@huawei.com>
24
Message-id: 1574835614-42028-1-git-send-email-pannengyuan@huawei.com
25
Signed-off-by: Max Reitz <mreitz@redhat.com>
26
---
11
---
27
block/throttle-groups.c | 4 ++--
12
pc-bios/README | 4 ++--
28
1 file changed, 2 insertions(+), 2 deletions(-)
13
1 file changed, 2 insertions(+), 2 deletions(-)
29
14
30
diff --git a/block/throttle-groups.c b/block/throttle-groups.c
15
diff --git a/pc-bios/README b/pc-bios/README
31
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
32
--- a/block/throttle-groups.c
17
--- a/pc-bios/README
33
+++ b/block/throttle-groups.c
18
+++ b/pc-bios/README
34
@@ -XXX,XX +XXX,XX @@ static void throttle_group_set_limits(Object *obj, Visitor *v,
19
@@ -XXX,XX +XXX,XX @@
35
{
20
legacy x86 software to communicate with an attached serial console as
36
ThrottleGroup *tg = THROTTLE_GROUP(obj);
21
if a video card were attached. The master sources reside in a subversion
37
ThrottleConfig cfg;
22
repository at http://sgabios.googlecode.com/svn/trunk. A git mirror is
38
- ThrottleLimits arg = { 0 };
23
- available at https://git.qemu.org/git/sgabios.git.
39
- ThrottleLimits *argp = &arg;
24
+ available at https://gitlab.com/qemu-project/sgabios.git.
40
+ ThrottleLimits *argp;
25
41
Error *local_err = NULL;
26
- The PXE roms come from the iPXE project. Built with BANNER_TIME 0.
42
27
Sources available at http://ipxe.org. Vendor:Device ID -> ROM mapping:
43
visit_type_ThrottleLimits(v, name, &argp, &local_err);
28
@@ -XXX,XX +XXX,XX @@
44
@@ -XXX,XX +XXX,XX @@ static void throttle_group_set_limits(Object *obj, Visitor *v,
29
45
unlock:
30
- The u-boot binary for e500 comes from the upstream denx u-boot project where
46
qemu_mutex_unlock(&tg->lock);
31
it was compiled using the qemu-ppce500 target.
47
ret:
32
- A git mirror is available at: https://git.qemu.org/git/u-boot.git
48
+ qapi_free_ThrottleLimits(argp);
33
+ A git mirror is available at: https://gitlab.com/qemu-project/u-boot.git
49
error_propagate(errp, local_err);
34
The hash used to compile the current version is: 2072e72
50
return;
35
51
}
36
- Skiboot (https://github.com/open-power/skiboot/) is an OPAL
52
--
37
--
53
2.24.1
38
2.29.2
54
39
55
diff view generated by jsdifflib
1
Signed-off-by: Max Reitz <mreitz@redhat.com>
1
qemu.org is running out of bandwidth and the QEMU project is moving
2
Message-id: 20191107163708.833192-22-mreitz@redhat.com
2
towards a gating CI on GitLab. Use the GitLab repos instead of qemu.org
3
[mreitz: Also disable 273]
3
(they will become mirrors).
4
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
5
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
6
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
7
Reviewed-by: Thomas Huth <thuth@redhat.com>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20210111115017.156802-7-stefanha@redhat.com
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
5
---
11
---
6
tests/qemu-iotests/007 | 5 +++--
12
scripts/get_maintainer.pl | 2 +-
7
tests/qemu-iotests/014 | 2 ++
13
1 file changed, 1 insertion(+), 1 deletion(-)
8
tests/qemu-iotests/015 | 5 +++--
9
tests/qemu-iotests/026 | 5 ++++-
10
tests/qemu-iotests/029 | 5 +++--
11
tests/qemu-iotests/031 | 6 +++---
12
tests/qemu-iotests/036 | 5 +++--
13
tests/qemu-iotests/039 | 3 +++
14
tests/qemu-iotests/046 | 2 ++
15
tests/qemu-iotests/048 | 2 ++
16
tests/qemu-iotests/051 | 5 +++--
17
tests/qemu-iotests/058 | 5 +++--
18
tests/qemu-iotests/060 | 6 ++++--
19
tests/qemu-iotests/061 | 6 ++++--
20
tests/qemu-iotests/062 | 2 +-
21
tests/qemu-iotests/066 | 4 +++-
22
tests/qemu-iotests/067 | 6 ++++--
23
tests/qemu-iotests/068 | 5 +++--
24
tests/qemu-iotests/071 | 3 +++
25
tests/qemu-iotests/073 | 4 ++++
26
tests/qemu-iotests/074 | 2 ++
27
tests/qemu-iotests/080 | 5 +++--
28
tests/qemu-iotests/090 | 2 ++
29
tests/qemu-iotests/098 | 6 ++++--
30
tests/qemu-iotests/099 | 3 ++-
31
tests/qemu-iotests/103 | 5 +++--
32
tests/qemu-iotests/108 | 6 ++++--
33
tests/qemu-iotests/112 | 5 +++--
34
tests/qemu-iotests/114 | 2 ++
35
tests/qemu-iotests/121 | 3 +++
36
tests/qemu-iotests/138 | 3 +++
37
tests/qemu-iotests/156 | 2 ++
38
tests/qemu-iotests/176 | 7 +++++--
39
tests/qemu-iotests/191 | 2 ++
40
tests/qemu-iotests/201 | 6 +++---
41
tests/qemu-iotests/214 | 3 ++-
42
tests/qemu-iotests/217 | 3 ++-
43
tests/qemu-iotests/220 | 5 +++--
44
tests/qemu-iotests/243 | 6 ++++--
45
tests/qemu-iotests/244 | 5 +++--
46
tests/qemu-iotests/250 | 2 ++
47
tests/qemu-iotests/261 | 3 ++-
48
tests/qemu-iotests/267 | 5 +++--
49
tests/qemu-iotests/273 | 3 +++
50
44 files changed, 127 insertions(+), 53 deletions(-)
51
14
52
diff --git a/tests/qemu-iotests/007 b/tests/qemu-iotests/007
15
diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl
53
index XXXXXXX..XXXXXXX 100755
16
index XXXXXXX..XXXXXXX 100755
54
--- a/tests/qemu-iotests/007
17
--- a/scripts/get_maintainer.pl
55
+++ b/tests/qemu-iotests/007
18
+++ b/scripts/get_maintainer.pl
56
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
19
@@ -XXX,XX +XXX,XX @@ sub vcs_exists {
57
_supported_fmt qcow2
20
    warn("$P: No supported VCS found. Add --nogit to options?\n");
58
_supported_proto generic
21
    warn("Using a git repository produces better results.\n");
59
# refcount_bits must be at least 4 so we can create ten internal snapshots
22
    warn("Try latest git repository using:\n");
60
-# (1 bit supports none, 2 bits support two, 4 bits support 14)
23
-    warn("git clone https://git.qemu.org/git/qemu.git\n");
61
-_unsupported_imgopts 'refcount_bits=\(1\|2\)[^0-9]'
24
+    warn("git clone https://gitlab.com/qemu-project/qemu.git\n");
62
+# (1 bit supports none, 2 bits support two, 4 bits support 14);
25
    $printed_novcs = 1;
63
+# snapshot are generally impossible with external data files
26
}
64
+_unsupported_imgopts 'refcount_bits=\(1\|2\)[^0-9]' data_file
27
return 0;
65
66
echo
67
echo "creating image"
68
diff --git a/tests/qemu-iotests/014 b/tests/qemu-iotests/014
69
index XXXXXXX..XXXXXXX 100755
70
--- a/tests/qemu-iotests/014
71
+++ b/tests/qemu-iotests/014
72
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
73
_supported_fmt qcow2
74
_supported_proto file
75
_supported_os Linux
76
+# Compression and snapshots do not work with external data files
77
+_unsupported_imgopts data_file
78
79
TEST_OFFSETS="0 4294967296"
80
TEST_OPS="writev read write readv"
81
diff --git a/tests/qemu-iotests/015 b/tests/qemu-iotests/015
82
index XXXXXXX..XXXXXXX 100755
83
--- a/tests/qemu-iotests/015
84
+++ b/tests/qemu-iotests/015
85
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
86
# actually any format that supports snapshots
87
_supported_fmt qcow2
88
_supported_proto generic
89
-# Internal snapshots are (currently) impossible with refcount_bits=1
90
-_unsupported_imgopts 'refcount_bits=1[^0-9]'
91
+# Internal snapshots are (currently) impossible with refcount_bits=1,
92
+# and generally impossible with external data files
93
+_unsupported_imgopts 'refcount_bits=1[^0-9]' data_file
94
95
echo
96
echo "creating image"
97
diff --git a/tests/qemu-iotests/026 b/tests/qemu-iotests/026
98
index XXXXXXX..XXXXXXX 100755
99
--- a/tests/qemu-iotests/026
100
+++ b/tests/qemu-iotests/026
101
@@ -XXX,XX +XXX,XX @@ _supported_cache_modes writethrough none
102
# 32 and 64 bits do not work either, however, due to different leaked cluster
103
# count on error.
104
# Thus, the only remaining option is refcount_bits=16.
105
-_unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)'
106
+#
107
+# As for data_file, none of the refcount tests can work for it.
108
+_unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)' \
109
+ data_file
110
111
echo "Errors while writing 128 kB"
112
echo
113
diff --git a/tests/qemu-iotests/029 b/tests/qemu-iotests/029
114
index XXXXXXX..XXXXXXX 100755
115
--- a/tests/qemu-iotests/029
116
+++ b/tests/qemu-iotests/029
117
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
118
_supported_fmt qcow2
119
_supported_proto generic
120
_unsupported_proto vxhs
121
-# Internal snapshots are (currently) impossible with refcount_bits=1
122
-_unsupported_imgopts 'refcount_bits=1[^0-9]'
123
+# Internal snapshots are (currently) impossible with refcount_bits=1,
124
+# and generally impossible with external data files
125
+_unsupported_imgopts 'refcount_bits=1[^0-9]' data_file
126
127
offset_size=24
128
offset_l1_size=36
129
diff --git a/tests/qemu-iotests/031 b/tests/qemu-iotests/031
130
index XXXXXXX..XXXXXXX 100755
131
--- a/tests/qemu-iotests/031
132
+++ b/tests/qemu-iotests/031
133
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
134
# This tests qcow2-specific low-level functionality
135
_supported_fmt qcow2
136
_supported_proto file
137
-# We want to test compat=0.10, which does not support refcount widths
138
-# other than 16
139
-_unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)'
140
+# We want to test compat=0.10, which does not support external data
141
+# files or refcount widths other than 16
142
+_unsupported_imgopts data_file 'refcount_bits=\([^1]\|.\([^6]\|$\)\)'
143
144
CLUSTER_SIZE=65536
145
146
diff --git a/tests/qemu-iotests/036 b/tests/qemu-iotests/036
147
index XXXXXXX..XXXXXXX 100755
148
--- a/tests/qemu-iotests/036
149
+++ b/tests/qemu-iotests/036
150
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
151
# This tests qcow2-specific low-level functionality
152
_supported_fmt qcow2
153
_supported_proto file
154
-# Only qcow2v3 and later supports feature bits
155
-_unsupported_imgopts 'compat=0.10'
156
+# Only qcow2v3 and later supports feature bits;
157
+# qcow2.py does not support external data files
158
+_unsupported_imgopts 'compat=0.10' data_file
159
160
echo
161
echo === Image with unknown incompatible feature bit ===
162
diff --git a/tests/qemu-iotests/039 b/tests/qemu-iotests/039
163
index XXXXXXX..XXXXXXX 100755
164
--- a/tests/qemu-iotests/039
165
+++ b/tests/qemu-iotests/039
166
@@ -XXX,XX +XXX,XX @@ _supported_proto file
167
_supported_os Linux
168
_default_cache_mode writethrough
169
_supported_cache_modes writethrough
170
+# Some of these test cases expect no external data file so that all
171
+# clusters are part of the qcow2 image and refcounted
172
+_unsupported_imgopts data_file
173
174
size=128M
175
176
diff --git a/tests/qemu-iotests/046 b/tests/qemu-iotests/046
177
index XXXXXXX..XXXXXXX 100755
178
--- a/tests/qemu-iotests/046
179
+++ b/tests/qemu-iotests/046
180
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
181
182
_supported_fmt qcow2
183
_supported_proto file
184
+# data_file does not support compressed clusters
185
+_unsupported_imgopts data_file
186
187
CLUSTER_SIZE=64k
188
size=128M
189
diff --git a/tests/qemu-iotests/048 b/tests/qemu-iotests/048
190
index XXXXXXX..XXXXXXX 100755
191
--- a/tests/qemu-iotests/048
192
+++ b/tests/qemu-iotests/048
193
@@ -XXX,XX +XXX,XX @@ _compare()
194
_supported_fmt raw qcow2 qed luks
195
_supported_proto file
196
_supported_os Linux
197
+# Using 'cp' is incompatible with external data files
198
+_unsupported_imgopts data_file
199
200
# Remove once all tests are fixed to use TEST_IMG_FILE
201
# correctly and common.rc sets it unconditionally
202
diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051
203
index XXXXXXX..XXXXXXX 100755
204
--- a/tests/qemu-iotests/051
205
+++ b/tests/qemu-iotests/051
206
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
207
_supported_fmt qcow2
208
_supported_proto file
209
# A compat=0.10 image is created in this test which does not support anything
210
-# other than refcount_bits=16
211
-_unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)'
212
+# other than refcount_bits=16;
213
+# it also will not support an external data file
214
+_unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)' data_file
215
_require_drivers nbd
216
217
do_run_qemu()
218
diff --git a/tests/qemu-iotests/058 b/tests/qemu-iotests/058
219
index XXXXXXX..XXXXXXX 100755
220
--- a/tests/qemu-iotests/058
221
+++ b/tests/qemu-iotests/058
222
@@ -XXX,XX +XXX,XX @@ _supported_fmt qcow2
223
_supported_proto file
224
_supported_os Linux
225
_require_command QEMU_NBD
226
-# Internal snapshots are (currently) impossible with refcount_bits=1
227
-_unsupported_imgopts 'refcount_bits=1[^0-9]'
228
+# Internal snapshots are (currently) impossible with refcount_bits=1,
229
+# and generally impossible with external data files
230
+_unsupported_imgopts 'refcount_bits=1[^0-9]' data_file
231
232
nbd_snapshot_img="nbd:unix:$nbd_unix_socket"
233
234
diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060
235
index XXXXXXX..XXXXXXX 100755
236
--- a/tests/qemu-iotests/060
237
+++ b/tests/qemu-iotests/060
238
@@ -XXX,XX +XXX,XX @@ _filter_io_error()
239
_supported_fmt qcow2
240
_supported_proto file
241
_supported_os Linux
242
-# These tests only work for compat=1.1 images with refcount_bits=16
243
-_unsupported_imgopts 'compat=0.10' 'refcount_bits=\([^1]\|.\([^6]\|$\)\)'
244
+# These tests only work for compat=1.1 images without an external
245
+# data file with refcount_bits=16
246
+_unsupported_imgopts 'compat=0.10' data_file \
247
+ 'refcount_bits=\([^1]\|.\([^6]\|$\)\)'
248
249
# The repair process will create a large file - so check for availability first
250
_require_large_file 64G
251
diff --git a/tests/qemu-iotests/061 b/tests/qemu-iotests/061
252
index XXXXXXX..XXXXXXX 100755
253
--- a/tests/qemu-iotests/061
254
+++ b/tests/qemu-iotests/061
255
@@ -XXX,XX +XXX,XX @@ _supported_fmt qcow2
256
_supported_proto file
257
_supported_os Linux
258
# Conversion between different compat versions can only really work
259
-# with refcount_bits=16
260
-_unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)'
261
+# with refcount_bits=16;
262
+# we have explicit tests for data_file here, but the whole test does
263
+# not work with it
264
+_unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)' data_file
265
266
echo
267
echo "=== Testing version downgrade with zero expansion ==="
268
diff --git a/tests/qemu-iotests/062 b/tests/qemu-iotests/062
269
index XXXXXXX..XXXXXXX 100755
270
--- a/tests/qemu-iotests/062
271
+++ b/tests/qemu-iotests/062
272
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
273
_supported_fmt qcow2
274
_supported_proto generic
275
# We need zero clusters and snapshots
276
-_unsupported_imgopts 'compat=0.10' 'refcount_bits=1[^0-9]'
277
+_unsupported_imgopts 'compat=0.10' 'refcount_bits=1[^0-9]' data_file
278
279
IMG_SIZE=64M
280
281
diff --git a/tests/qemu-iotests/066 b/tests/qemu-iotests/066
282
index XXXXXXX..XXXXXXX 100755
283
--- a/tests/qemu-iotests/066
284
+++ b/tests/qemu-iotests/066
285
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
286
_supported_fmt qcow2
287
_supported_proto generic
288
# We need zero clusters and snapshots
289
-_unsupported_imgopts 'compat=0.10' 'refcount_bits=1[^0-9]'
290
+# (TODO: Consider splitting the snapshot part into a separate test
291
+# file, so this one runs with refcount_bits=1 and data_file)
292
+_unsupported_imgopts 'compat=0.10' 'refcount_bits=1[^0-9]' data_file
293
294
# Intentionally create an unaligned image
295
IMG_SIZE=$((64 * 1024 * 1024 + 512))
296
diff --git a/tests/qemu-iotests/067 b/tests/qemu-iotests/067
297
index XXXXXXX..XXXXXXX 100755
298
--- a/tests/qemu-iotests/067
299
+++ b/tests/qemu-iotests/067
300
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
301
302
_supported_fmt qcow2
303
_supported_proto file
304
-# Because anything other than 16 would change the output of query-block
305
-_unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)'
306
+# Because anything other than 16 would change the output of query-block,
307
+# and external data files would change the output of
308
+# query-named-block-nodes
309
+_unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)' data_file
310
311
do_run_qemu()
312
{
313
diff --git a/tests/qemu-iotests/068 b/tests/qemu-iotests/068
314
index XXXXXXX..XXXXXXX 100755
315
--- a/tests/qemu-iotests/068
316
+++ b/tests/qemu-iotests/068
317
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
318
# This tests qcow2-specific low-level functionality
319
_supported_fmt qcow2
320
_supported_proto generic
321
-# Internal snapshots are (currently) impossible with refcount_bits=1
322
-_unsupported_imgopts 'compat=0.10' 'refcount_bits=1[^0-9]'
323
+# Internal snapshots are (currently) impossible with refcount_bits=1,
324
+# and generally impossible with external data files
325
+_unsupported_imgopts 'compat=0.10' 'refcount_bits=1[^0-9]' data_file
326
327
IMG_SIZE=128K
328
329
diff --git a/tests/qemu-iotests/071 b/tests/qemu-iotests/071
330
index XXXXXXX..XXXXXXX 100755
331
--- a/tests/qemu-iotests/071
332
+++ b/tests/qemu-iotests/071
333
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
334
_supported_fmt qcow2
335
_supported_proto file
336
_require_drivers blkdebug blkverify
337
+# blkdebug can only inject errors on bs->file, not on the data_file,
338
+# so thie test does not work with external data files
339
+_unsupported_imgopts data_file
340
341
do_run_qemu()
342
{
343
diff --git a/tests/qemu-iotests/073 b/tests/qemu-iotests/073
344
index XXXXXXX..XXXXXXX 100755
345
--- a/tests/qemu-iotests/073
346
+++ b/tests/qemu-iotests/073
347
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
348
_supported_fmt qcow2
349
_supported_proto generic
350
_unsupported_proto vxhs
351
+# External data files do not support compressed clusters
352
+# (TODO: Consider writing a version for external data files that does
353
+# not test compressed clusters)
354
+_unsupported_imgopts data_file
355
356
CLUSTER_SIZE=64k
357
size=128M
358
diff --git a/tests/qemu-iotests/074 b/tests/qemu-iotests/074
359
index XXXXXXX..XXXXXXX 100755
360
--- a/tests/qemu-iotests/074
361
+++ b/tests/qemu-iotests/074
362
@@ -XXX,XX +XXX,XX @@ _compare()
363
_supported_fmt qcow2
364
_supported_proto file
365
_supported_os Linux
366
+# blkdebug can only inject errors on bs->file
367
+_unsupported_imgopts data_file
368
369
# Setup test basic parameters
370
TEST_IMG2=$TEST_IMG.2
371
diff --git a/tests/qemu-iotests/080 b/tests/qemu-iotests/080
372
index XXXXXXX..XXXXXXX 100755
373
--- a/tests/qemu-iotests/080
374
+++ b/tests/qemu-iotests/080
375
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
376
_supported_fmt qcow2
377
_supported_proto file
378
_supported_os Linux
379
-# - Internal snapshots are (currently) impossible with refcount_bits=1
380
+# - Internal snapshots are (currently) impossible with refcount_bits=1,
381
+# and generally impossible with external data files
382
# - This is generally a test for compat=1.1 images
383
-_unsupported_imgopts 'refcount_bits=1[^0-9]' 'compat=0.10'
384
+_unsupported_imgopts 'refcount_bits=1[^0-9]' data_file 'compat=0.10'
385
386
header_size=104
387
388
diff --git a/tests/qemu-iotests/090 b/tests/qemu-iotests/090
389
index XXXXXXX..XXXXXXX 100755
390
--- a/tests/qemu-iotests/090
391
+++ b/tests/qemu-iotests/090
392
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
393
394
_supported_fmt qcow2
395
_supported_proto file nfs
396
+# External data files do not support compressed clusters
397
+_unsupported_imgopts data_file
398
399
IMG_SIZE=128K
400
401
diff --git a/tests/qemu-iotests/098 b/tests/qemu-iotests/098
402
index XXXXXXX..XXXXXXX 100755
403
--- a/tests/qemu-iotests/098
404
+++ b/tests/qemu-iotests/098
405
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
406
407
_supported_fmt qcow2
408
_supported_proto file
409
-# The code path we want to test here only works for compat=1.1 images
410
-_unsupported_imgopts 'compat=0.10'
411
+# The code path we want to test here only works for compat=1.1 images;
412
+# blkdebug can only inject errors on bs->file, so external data files
413
+# do not work with this test
414
+_unsupported_imgopts 'compat=0.10' data_file
415
416
for event in l1_update empty_image_prepare reftable_update refblock_alloc; do
417
418
diff --git a/tests/qemu-iotests/099 b/tests/qemu-iotests/099
419
index XXXXXXX..XXXXXXX 100755
420
--- a/tests/qemu-iotests/099
421
+++ b/tests/qemu-iotests/099
422
@@ -XXX,XX +XXX,XX @@ _supported_fmt qcow qcow2 qed vdi vhdx vmdk vpc
423
_supported_proto file
424
_supported_os Linux
425
_require_drivers blkdebug blkverify
426
+# data_file would change the json:{} filenames
427
_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat" \
428
- "subformat=twoGbMaxExtentSparse"
429
+ "subformat=twoGbMaxExtentSparse" data_file
430
431
do_run_qemu()
432
{
433
diff --git a/tests/qemu-iotests/103 b/tests/qemu-iotests/103
434
index XXXXXXX..XXXXXXX 100755
435
--- a/tests/qemu-iotests/103
436
+++ b/tests/qemu-iotests/103
437
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
438
439
_supported_fmt qcow2
440
_supported_proto file nfs
441
-# Internal snapshots are (currently) impossible with refcount_bits=1
442
-_unsupported_imgopts 'refcount_bits=1[^0-9]'
443
+# Internal snapshots are (currently) impossible with refcount_bits=1,
444
+# and generally impossible with external data files
445
+_unsupported_imgopts 'refcount_bits=1[^0-9]' data_file
446
447
IMG_SIZE=64K
448
449
diff --git a/tests/qemu-iotests/108 b/tests/qemu-iotests/108
450
index XXXXXXX..XXXXXXX 100755
451
--- a/tests/qemu-iotests/108
452
+++ b/tests/qemu-iotests/108
453
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
454
_supported_fmt qcow2
455
_supported_proto file
456
_supported_os Linux
457
-# This test directly modifies a refblock so it relies on refcount_bits being 16
458
-_unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)'
459
+# This test directly modifies a refblock so it relies on refcount_bits being 16;
460
+# and the low-level modification it performs are not tuned for external data
461
+# files
462
+_unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)' data_file
463
464
echo
465
echo '=== Repairing an image without any refcount table ==='
466
diff --git a/tests/qemu-iotests/112 b/tests/qemu-iotests/112
467
index XXXXXXX..XXXXXXX 100755
468
--- a/tests/qemu-iotests/112
469
+++ b/tests/qemu-iotests/112
470
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
471
_supported_fmt qcow2
472
_supported_proto file
473
# This test will set refcount_bits on its own which would conflict with the
474
-# manual setting; compat will be overridden as well
475
-_unsupported_imgopts refcount_bits 'compat=0.10'
476
+# manual setting; compat will be overridden as well;
477
+# and external data files do not work well with our refcount testing
478
+_unsupported_imgopts refcount_bits 'compat=0.10' data_file
479
480
print_refcount_bits()
481
{
482
diff --git a/tests/qemu-iotests/114 b/tests/qemu-iotests/114
483
index XXXXXXX..XXXXXXX 100755
484
--- a/tests/qemu-iotests/114
485
+++ b/tests/qemu-iotests/114
486
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
487
_supported_fmt qcow2
488
_supported_proto generic
489
_unsupported_proto vxhs
490
+# qcow2.py does not work too well with external data files
491
+_unsupported_imgopts data_file
492
493
494
TEST_IMG="$TEST_IMG.base" _make_test_img 64M
495
diff --git a/tests/qemu-iotests/121 b/tests/qemu-iotests/121
496
index XXXXXXX..XXXXXXX 100755
497
--- a/tests/qemu-iotests/121
498
+++ b/tests/qemu-iotests/121
499
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
500
_supported_fmt qcow2
501
_supported_proto file
502
_supported_os Linux
503
+# Refcount structures are used much differently with external data
504
+# files
505
+_unsupported_imgopts data_file
506
507
echo
508
echo '=== New refcount structures may not conflict with existing structures ==='
509
diff --git a/tests/qemu-iotests/138 b/tests/qemu-iotests/138
510
index XXXXXXX..XXXXXXX 100755
511
--- a/tests/qemu-iotests/138
512
+++ b/tests/qemu-iotests/138
513
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
514
_supported_fmt qcow2
515
_supported_proto file
516
_supported_os Linux
517
+# With an external data file, data clusters are not refcounted
518
+# (and so qemu-img check does not check their refcount)
519
+_unsupported_imgopts data_file
520
521
echo
522
echo '=== Check on an image with a multiple of 2^32 clusters ==='
523
diff --git a/tests/qemu-iotests/156 b/tests/qemu-iotests/156
524
index XXXXXXX..XXXXXXX 100755
525
--- a/tests/qemu-iotests/156
526
+++ b/tests/qemu-iotests/156
527
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
528
_supported_fmt qcow2 qed
529
_supported_proto generic
530
_unsupported_proto vxhs
531
+# Copying files around with cp does not work with external data files
532
+_unsupported_imgopts data_file
533
534
# Create source disk
535
TEST_IMG="$TEST_IMG.backing" _make_test_img 1M
536
diff --git a/tests/qemu-iotests/176 b/tests/qemu-iotests/176
537
index XXXXXXX..XXXXXXX 100755
538
--- a/tests/qemu-iotests/176
539
+++ b/tests/qemu-iotests/176
540
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
541
_supported_fmt qcow2
542
_supported_proto file
543
_supported_os Linux
544
-# Persistent dirty bitmaps require compat=1.1
545
-_unsupported_imgopts 'compat=0.10'
546
+# Persistent dirty bitmaps require compat=1.1;
547
+# Internal snapshots forbid using an external data file
548
+# (they work with refcount_bits=1 here, though, because there actually
549
+# is no data when creating the snapshot)
550
+_unsupported_imgopts 'compat=0.10' data_file
551
552
run_qemu()
553
{
554
diff --git a/tests/qemu-iotests/191 b/tests/qemu-iotests/191
555
index XXXXXXX..XXXXXXX 100755
556
--- a/tests/qemu-iotests/191
557
+++ b/tests/qemu-iotests/191
558
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
559
560
_supported_fmt qcow2
561
_supported_proto file
562
+# An external data file would change the query-named-block-nodes output
563
+_unsupported_imgopts data_file
564
565
size=64M
566
567
diff --git a/tests/qemu-iotests/201 b/tests/qemu-iotests/201
568
index XXXXXXX..XXXXXXX 100755
569
--- a/tests/qemu-iotests/201
570
+++ b/tests/qemu-iotests/201
571
@@ -XXX,XX +XXX,XX @@ _supported_fmt qcow2
572
_supported_proto generic
573
_supported_os Linux
574
575
-# Internal snapshots are (currently) impossible with refcount_bits=1
576
-# This was taken from test 080
577
-_unsupported_imgopts 'refcount_bits=1[^0-9]'
578
+# Internal snapshots are (currently) impossible with refcount_bits=1,
579
+# and generally impossible with external data files
580
+_unsupported_imgopts 'refcount_bits=1[^0-9]' data_file
581
582
size=64M
583
_make_test_img $size
584
diff --git a/tests/qemu-iotests/214 b/tests/qemu-iotests/214
585
index XXXXXXX..XXXXXXX 100755
586
--- a/tests/qemu-iotests/214
587
+++ b/tests/qemu-iotests/214
588
@@ -XXX,XX +XXX,XX @@ _supported_proto file
589
590
# Repairing the corrupted image requires qemu-img check to store a
591
# refcount up to 3, which requires at least two refcount bits.
592
-_unsupported_imgopts 'refcount_bits=1[^0-9]'
593
+# External data files do not support compressed clusters.
594
+_unsupported_imgopts 'refcount_bits=1[^0-9]' data_file
595
596
597
echo
598
diff --git a/tests/qemu-iotests/217 b/tests/qemu-iotests/217
599
index XXXXXXX..XXXXXXX 100755
600
--- a/tests/qemu-iotests/217
601
+++ b/tests/qemu-iotests/217
602
@@ -XXX,XX +XXX,XX @@ _supported_proto file
603
604
# This test needs clusters with at least a refcount of 2 so that
605
# OFLAG_COPIED is not set. refcount_bits=1 is therefore unsupported.
606
-_unsupported_imgopts 'refcount_bits=1[^0-9]'
607
+# (As are external data files.)
608
+_unsupported_imgopts 'refcount_bits=1[^0-9]' data_file
609
610
echo
611
echo '=== Simulating an I/O error during snapshot deletion ==='
612
diff --git a/tests/qemu-iotests/220 b/tests/qemu-iotests/220
613
index XXXXXXX..XXXXXXX 100755
614
--- a/tests/qemu-iotests/220
615
+++ b/tests/qemu-iotests/220
616
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
617
_supported_fmt qcow2
618
_supported_proto file
619
_supported_os Linux
620
-# To use a different refcount width but 16 bits we need compat=1.1
621
-_unsupported_imgopts 'compat=0.10'
622
+# To use a different refcount width but 16 bits we need compat=1.1,
623
+# and external data files do not support compressed clusters.
624
+_unsupported_imgopts 'compat=0.10' data_file
625
626
echo "== Creating huge file =="
627
628
diff --git a/tests/qemu-iotests/243 b/tests/qemu-iotests/243
629
index XXXXXXX..XXXXXXX 100755
630
--- a/tests/qemu-iotests/243
631
+++ b/tests/qemu-iotests/243
632
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
633
_supported_fmt qcow2
634
_supported_proto file
635
_supported_os Linux
636
-# External data files do not work with compat=0.10
637
-_unsupported_imgopts 'compat=0.10'
638
+# External data files do not work with compat=0.10, and because there
639
+# is an explicit case for external data files here, we cannot allow
640
+# the user to specify whether to use one
641
+_unsupported_imgopts 'compat=0.10' data_file
642
643
for mode in off metadata falloc full; do
644
645
diff --git a/tests/qemu-iotests/244 b/tests/qemu-iotests/244
646
index XXXXXXX..XXXXXXX 100755
647
--- a/tests/qemu-iotests/244
648
+++ b/tests/qemu-iotests/244
649
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
650
_supported_fmt qcow2
651
_supported_proto file
652
_supported_os Linux
653
-# External data files do not work with compat=0.10
654
-_unsupported_imgopts 'compat=0.10'
655
+# External data files do not work with compat=0.10, and because we use
656
+# our own external data file, we cannot let the user specify one
657
+_unsupported_imgopts 'compat=0.10' data_file
658
659
echo
660
echo "=== Create and open image with external data file ==="
661
diff --git a/tests/qemu-iotests/250 b/tests/qemu-iotests/250
662
index XXXXXXX..XXXXXXX 100755
663
--- a/tests/qemu-iotests/250
664
+++ b/tests/qemu-iotests/250
665
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
666
_supported_fmt qcow2
667
_supported_proto file
668
_supported_os Linux
669
+# This test does not make much sense with external data files
670
+_unsupported_imgopts data_file
671
672
# This test checks that qcow2_process_discards does not truncate a discard
673
# request > 2G.
674
diff --git a/tests/qemu-iotests/261 b/tests/qemu-iotests/261
675
index XXXXXXX..XXXXXXX 100755
676
--- a/tests/qemu-iotests/261
677
+++ b/tests/qemu-iotests/261
678
@@ -XXX,XX +XXX,XX @@ _supported_os Linux
679
# (1) We create a v2 image that supports nothing but refcount_bits=16
680
# (2) We do some refcount management on our own which expects
681
# refcount_bits=16
682
-_unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)'
683
+# As for data files, they do not support snapshots at all.
684
+_unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)' data_file
685
686
# Parameters:
687
# $1: image filename
688
diff --git a/tests/qemu-iotests/267 b/tests/qemu-iotests/267
689
index XXXXXXX..XXXXXXX 100755
690
--- a/tests/qemu-iotests/267
691
+++ b/tests/qemu-iotests/267
692
@@ -XXX,XX +XXX,XX @@ _supported_proto file
693
_supported_os Linux
694
_require_drivers copy-on-read
695
696
-# Internal snapshots are (currently) impossible with refcount_bits=1
697
-_unsupported_imgopts 'refcount_bits=1[^0-9]'
698
+# Internal snapshots are (currently) impossible with refcount_bits=1,
699
+# and generally impossible with external data files
700
+_unsupported_imgopts 'refcount_bits=1[^0-9]' data_file
701
702
do_run_qemu()
703
{
704
diff --git a/tests/qemu-iotests/273 b/tests/qemu-iotests/273
705
index XXXXXXX..XXXXXXX 100755
706
--- a/tests/qemu-iotests/273
707
+++ b/tests/qemu-iotests/273
708
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
709
_supported_fmt qcow2
710
_supported_proto file
711
_supported_os Linux
712
+# External data files would add nodes to the block graph, so it would
713
+# not match the reference output
714
+_unsupported_imgopts data_file
715
716
do_run_qemu()
717
{
718
--
28
--
719
2.24.1
29
2.29.2
720
30
721
diff view generated by jsdifflib
1
We do not care about the json:{} filenames here, so we can just filter
1
From: John G Johnson <john.g.johnson@oracle.com>
2
them out and thus make the test work both with and without external data
3
files.
4
2
5
Signed-off-by: Max Reitz <mreitz@redhat.com>
3
Signed-off-by: John G Johnson <john.g.johnson@oracle.com>
6
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
4
Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
7
Message-id: 20191107163708.833192-21-mreitz@redhat.com
5
Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
7
Message-id: 02a68adef99f5df6a380bf8fd7b90948777e411c.1611938319.git.jag.raman@oracle.com
8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
---
9
---
10
tests/qemu-iotests/198 | 6 ++++--
10
MAINTAINERS | 7 +
11
tests/qemu-iotests/198.out | 4 ++--
11
docs/devel/index.rst | 1 +
12
2 files changed, 6 insertions(+), 4 deletions(-)
12
docs/devel/multi-process.rst | 966 +++++++++++++++++++++++++++++++++++
13
3 files changed, 974 insertions(+)
14
create mode 100644 docs/devel/multi-process.rst
13
15
14
diff --git a/tests/qemu-iotests/198 b/tests/qemu-iotests/198
16
diff --git a/MAINTAINERS b/MAINTAINERS
15
index XXXXXXX..XXXXXXX 100755
16
--- a/tests/qemu-iotests/198
17
+++ b/tests/qemu-iotests/198
18
@@ -XXX,XX +XXX,XX @@ echo
19
echo "== checking image base =="
20
$QEMU_IMG info --image-opts $IMGSPECBASE | _filter_img_info --format-specific \
21
| sed -e "/^disk size:/ D" -e '/refcount bits:/ D' -e '/compat:/ D' \
22
- -e '/lazy refcounts:/ D' -e '/corrupt:/ D'
23
+ -e '/lazy refcounts:/ D' -e '/corrupt:/ D' -e '/^\s*data file/ D' \
24
+ | _filter_json_filename
25
26
echo
27
echo "== checking image layer =="
28
$QEMU_IMG info --image-opts $IMGSPECLAYER | _filter_img_info --format-specific \
29
| sed -e "/^disk size:/ D" -e '/refcount bits:/ D' -e '/compat:/ D' \
30
- -e '/lazy refcounts:/ D' -e '/corrupt:/ D'
31
+ -e '/lazy refcounts:/ D' -e '/corrupt:/ D' -e '/^\s*data file/ D' \
32
+ | _filter_json_filename
33
34
35
# success, all done
36
diff --git a/tests/qemu-iotests/198.out b/tests/qemu-iotests/198.out
37
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
38
--- a/tests/qemu-iotests/198.out
18
--- a/MAINTAINERS
39
+++ b/tests/qemu-iotests/198.out
19
+++ b/MAINTAINERS
40
@@ -XXX,XX +XXX,XX @@ read 16777216/16777216 bytes at offset 0
20
@@ -XXX,XX +XXX,XX @@ S: Maintained
41
16 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
21
F: hw/semihosting/
42
22
F: include/hw/semihosting/
43
== checking image base ==
23
44
-image: json:{"encrypt.key-secret": "sec0", "driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT.base"}}
24
+Multi-process QEMU
45
+image: json:{ /* filtered */ }
25
+M: Elena Ufimtseva <elena.ufimtseva@oracle.com>
46
file format: IMGFMT
26
+M: Jagannathan Raman <jag.raman@oracle.com>
47
virtual size: 16 MiB (16777216 bytes)
27
+M: John G Johnson <john.g.johnson@oracle.com>
48
Format specific information:
28
+S: Maintained
49
@@ -XXX,XX +XXX,XX @@ Format specific information:
29
+F: docs/devel/multi-process.rst
50
master key iters: 1024
30
+
51
31
Build and test automation
52
== checking image layer ==
32
-------------------------
53
-image: json:{"encrypt.key-secret": "sec1", "driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}}
33
Build and test automation
54
+image: json:{ /* filtered */ }
34
diff --git a/docs/devel/index.rst b/docs/devel/index.rst
55
file format: IMGFMT
35
index XXXXXXX..XXXXXXX 100644
56
virtual size: 16 MiB (16777216 bytes)
36
--- a/docs/devel/index.rst
57
backing file: TEST_DIR/t.IMGFMT.base
37
+++ b/docs/devel/index.rst
38
@@ -XXX,XX +XXX,XX @@ Contents:
39
clocks
40
qom
41
block-coroutine-wrapper
42
+ multi-process
43
diff --git a/docs/devel/multi-process.rst b/docs/devel/multi-process.rst
44
new file mode 100644
45
index XXXXXXX..XXXXXXX
46
--- /dev/null
47
+++ b/docs/devel/multi-process.rst
48
@@ -XXX,XX +XXX,XX @@
49
+This is the design document for multi-process QEMU. It does not
50
+necessarily reflect the status of the current implementation, which
51
+may lack features or be considerably different from what is described
52
+in this document. This document is still useful as a description of
53
+the goals and general direction of this feature.
54
+
55
+Please refer to the following wiki for latest details:
56
+https://wiki.qemu.org/Features/MultiProcessQEMU
57
+
58
+Multi-process QEMU
59
+===================
60
+
61
+QEMU is often used as the hypervisor for virtual machines running in the
62
+Oracle cloud. Since one of the advantages of cloud computing is the
63
+ability to run many VMs from different tenants in the same cloud
64
+infrastructure, a guest that compromised its hypervisor could
65
+potentially use the hypervisor's access privileges to access data it is
66
+not authorized for.
67
+
68
+QEMU can be susceptible to security attacks because it is a large,
69
+monolithic program that provides many features to the VMs it services.
70
+Many of these features can be configured out of QEMU, but even a reduced
71
+configuration QEMU has a large amount of code a guest can potentially
72
+attack. Separating QEMU reduces the attack surface by aiding to
73
+limit each component in the system to only access the resources that
74
+it needs to perform its job.
75
+
76
+QEMU services
77
+-------------
78
+
79
+QEMU can be broadly described as providing three main services. One is a
80
+VM control point, where VMs can be created, migrated, re-configured, and
81
+destroyed. A second is to emulate the CPU instructions within the VM,
82
+often accelerated by HW virtualization features such as Intel's VT
83
+extensions. Finally, it provides IO services to the VM by emulating HW
84
+IO devices, such as disk and network devices.
85
+
86
+A multi-process QEMU
87
+~~~~~~~~~~~~~~~~~~~~
88
+
89
+A multi-process QEMU involves separating QEMU services into separate
90
+host processes. Each of these processes can be given only the privileges
91
+it needs to provide its service, e.g., a disk service could be given
92
+access only to the disk images it provides, and not be allowed to
93
+access other files, or any network devices. An attacker who compromised
94
+this service would not be able to use this exploit to access files or
95
+devices beyond what the disk service was given access to.
96
+
97
+A QEMU control process would remain, but in multi-process mode, will
98
+have no direct interfaces to the VM. During VM execution, it would still
99
+provide the user interface to hot-plug devices or live migrate the VM.
100
+
101
+A first step in creating a multi-process QEMU is to separate IO services
102
+from the main QEMU program, which would continue to provide CPU
103
+emulation. i.e., the control process would also be the CPU emulation
104
+process. In a later phase, CPU emulation could be separated from the
105
+control process.
106
+
107
+Separating IO services
108
+----------------------
109
+
110
+Separating IO services into individual host processes is a good place to
111
+begin for a couple of reasons. One is the sheer number of IO devices QEMU
112
+can emulate provides a large surface of interfaces which could potentially
113
+be exploited, and, indeed, have been a source of exploits in the past.
114
+Another is the modular nature of QEMU device emulation code provides
115
+interface points where the QEMU functions that perform device emulation
116
+can be separated from the QEMU functions that manage the emulation of
117
+guest CPU instructions. The devices emulated in the separate process are
118
+referred to as remote devices.
119
+
120
+QEMU device emulation
121
+~~~~~~~~~~~~~~~~~~~~~
122
+
123
+QEMU uses an object oriented SW architecture for device emulation code.
124
+Configured objects are all compiled into the QEMU binary, then objects
125
+are instantiated by name when used by the guest VM. For example, the
126
+code to emulate a device named "foo" is always present in QEMU, but its
127
+instantiation code is only run when the device is included in the target
128
+VM. (e.g., via the QEMU command line as *-device foo*)
129
+
130
+The object model is hierarchical, so device emulation code names its
131
+parent object (such as "pci-device" for a PCI device) and QEMU will
132
+instantiate a parent object before calling the device's instantiation
133
+code.
134
+
135
+Current separation models
136
+~~~~~~~~~~~~~~~~~~~~~~~~~
137
+
138
+In order to separate the device emulation code from the CPU emulation
139
+code, the device object code must run in a different process. There are
140
+a couple of existing QEMU features that can run emulation code
141
+separately from the main QEMU process. These are examined below.
142
+
143
+vhost user model
144
+^^^^^^^^^^^^^^^^
145
+
146
+Virtio guest device drivers can be connected to vhost user applications
147
+in order to perform their IO operations. This model uses special virtio
148
+device drivers in the guest and vhost user device objects in QEMU, but
149
+once the QEMU vhost user code has configured the vhost user application,
150
+mission-mode IO is performed by the application. The vhost user
151
+application is a daemon process that can be contacted via a known UNIX
152
+domain socket.
153
+
154
+vhost socket
155
+''''''''''''
156
+
157
+As mentioned above, one of the tasks of the vhost device object within
158
+QEMU is to contact the vhost application and send it configuration
159
+information about this device instance. As part of the configuration
160
+process, the application can also be sent other file descriptors over
161
+the socket, which then can be used by the vhost user application in
162
+various ways, some of which are described below.
163
+
164
+vhost MMIO store acceleration
165
+'''''''''''''''''''''''''''''
166
+
167
+VMs are often run using HW virtualization features via the KVM kernel
168
+driver. This driver allows QEMU to accelerate the emulation of guest CPU
169
+instructions by running the guest in a virtual HW mode. When the guest
170
+executes instructions that cannot be executed by virtual HW mode,
171
+execution returns to the KVM driver so it can inform QEMU to emulate the
172
+instructions in SW.
173
+
174
+One of the events that can cause a return to QEMU is when a guest device
175
+driver accesses an IO location. QEMU then dispatches the memory
176
+operation to the corresponding QEMU device object. In the case of a
177
+vhost user device, the memory operation would need to be sent over a
178
+socket to the vhost application. This path is accelerated by the QEMU
179
+virtio code by setting up an eventfd file descriptor that the vhost
180
+application can directly receive MMIO store notifications from the KVM
181
+driver, instead of needing them to be sent to the QEMU process first.
182
+
183
+vhost interrupt acceleration
184
+''''''''''''''''''''''''''''
185
+
186
+Another optimization used by the vhost application is the ability to
187
+directly inject interrupts into the VM via the KVM driver, again,
188
+bypassing the need to send the interrupt back to the QEMU process first.
189
+The QEMU virtio setup code configures the KVM driver with an eventfd
190
+that triggers the device interrupt in the guest when the eventfd is
191
+written. This irqfd file descriptor is then passed to the vhost user
192
+application program.
193
+
194
+vhost access to guest memory
195
+''''''''''''''''''''''''''''
196
+
197
+The vhost application is also allowed to directly access guest memory,
198
+instead of needing to send the data as messages to QEMU. This is also
199
+done with file descriptors sent to the vhost user application by QEMU.
200
+These descriptors can be passed to ``mmap()`` by the vhost application
201
+to map the guest address space into the vhost application.
202
+
203
+IOMMUs introduce another level of complexity, since the address given to
204
+the guest virtio device to DMA to or from is not a guest physical
205
+address. This case is handled by having vhost code within QEMU register
206
+as a listener for IOMMU mapping changes. The vhost application maintains
207
+a cache of IOMMMU translations: sending translation requests back to
208
+QEMU on cache misses, and in turn receiving flush requests from QEMU
209
+when mappings are purged.
210
+
211
+applicability to device separation
212
+''''''''''''''''''''''''''''''''''
213
+
214
+Much of the vhost model can be re-used by separated device emulation. In
215
+particular, the ideas of using a socket between QEMU and the device
216
+emulation application, using a file descriptor to inject interrupts into
217
+the VM via KVM, and allowing the application to ``mmap()`` the guest
218
+should be re used.
219
+
220
+There are, however, some notable differences between how a vhost
221
+application works and the needs of separated device emulation. The most
222
+basic is that vhost uses custom virtio device drivers which always
223
+trigger IO with MMIO stores. A separated device emulation model must
224
+work with existing IO device models and guest device drivers. MMIO loads
225
+break vhost store acceleration since they are synchronous - guest
226
+progress cannot continue until the load has been emulated. By contrast,
227
+stores are asynchronous, the guest can continue after the store event
228
+has been sent to the vhost application.
229
+
230
+Another difference is that in the vhost user model, a single daemon can
231
+support multiple QEMU instances. This is contrary to the security regime
232
+desired, in which the emulation application should only be allowed to
233
+access the files or devices the VM it's running on behalf of can access.
234
+#### qemu-io model
235
+
236
+Qemu-io is a test harness used to test changes to the QEMU block backend
237
+object code. (e.g., the code that implements disk images for disk driver
238
+emulation) Qemu-io is not a device emulation application per se, but it
239
+does compile the QEMU block objects into a separate binary from the main
240
+QEMU one. This could be useful for disk device emulation, since its
241
+emulation applications will need to include the QEMU block objects.
242
+
243
+New separation model based on proxy objects
244
+-------------------------------------------
245
+
246
+A different model based on proxy objects in the QEMU program
247
+communicating with remote emulation programs could provide separation
248
+while minimizing the changes needed to the device emulation code. The
249
+rest of this section is a discussion of how a proxy object model would
250
+work.
251
+
252
+Remote emulation processes
253
+~~~~~~~~~~~~~~~~~~~~~~~~~~
254
+
255
+The remote emulation process will run the QEMU object hierarchy without
256
+modification. The device emulation objects will be also be based on the
257
+QEMU code, because for anything but the simplest device, it would not be
258
+a tractable to re-implement both the object model and the many device
259
+backends that QEMU has.
260
+
261
+The processes will communicate with the QEMU process over UNIX domain
262
+sockets. The processes can be executed either as standalone processes,
263
+or be executed by QEMU. In both cases, the host backends the emulation
264
+processes will provide are specified on its command line, as they would
265
+be for QEMU. For example:
266
+
267
+::
268
+
269
+ disk-proc -blockdev driver=file,node-name=file0,filename=disk-file0 \
270
+ -blockdev driver=qcow2,node-name=drive0,file=file0
271
+
272
+would indicate process *disk-proc* uses a qcow2 emulated disk named
273
+*file0* as its backend.
274
+
275
+Emulation processes may emulate more than one guest controller. A common
276
+configuration might be to put all controllers of the same device class
277
+(e.g., disk, network, etc.) in a single process, so that all backends of
278
+the same type can be managed by a single QMP monitor.
279
+
280
+communication with QEMU
281
+^^^^^^^^^^^^^^^^^^^^^^^
282
+
283
+The first argument to the remote emulation process will be a Unix domain
284
+socket that connects with the Proxy object. This is a required argument.
285
+
286
+::
287
+
288
+ disk-proc <socket number> <backend list>
289
+
290
+remote process QMP monitor
291
+^^^^^^^^^^^^^^^^^^^^^^^^^^
292
+
293
+Remote emulation processes can be monitored via QMP, similar to QEMU
294
+itself. The QMP monitor socket is specified the same as for a QEMU
295
+process:
296
+
297
+::
298
+
299
+ disk-proc -qmp unix:/tmp/disk-mon,server
300
+
301
+can be monitored over the UNIX socket path */tmp/disk-mon*.
302
+
303
+QEMU command line
304
+~~~~~~~~~~~~~~~~~
305
+
306
+Each remote device emulated in a remote process on the host is
307
+represented as a *-device* of type *pci-proxy-dev*. A socket
308
+sub-option to this option specifies the Unix socket that connects
309
+to the remote process. An *id* sub-option is required, and it should
310
+be the same id as used in the remote process.
311
+
312
+::
313
+
314
+ qemu-system-x86_64 ... -device pci-proxy-dev,id=lsi0,socket=3
315
+
316
+can be used to add a device emulated in a remote process
317
+
318
+
319
+QEMU management of remote processes
320
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
321
+
322
+QEMU is not aware of the type of type of the remote PCI device. It is
323
+a pass through device as far as QEMU is concerned.
324
+
325
+communication with emulation process
326
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
327
+
328
+primary channel
329
+'''''''''''''''
330
+
331
+The primary channel (referred to as com in the code) is used to bootstrap
332
+the remote process. It is also used to pass on device-agnostic commands
333
+like reset.
334
+
335
+per-device channels
336
+'''''''''''''''''''
337
+
338
+Each remote device communicates with QEMU using a dedicated communication
339
+channel. The proxy object sets up this channel using the primary
340
+channel during its initialization.
341
+
342
+QEMU device proxy objects
343
+~~~~~~~~~~~~~~~~~~~~~~~~~
344
+
345
+QEMU has an object model based on sub-classes inherited from the
346
+"object" super-class. The sub-classes that are of interest here are the
347
+"device" and "bus" sub-classes whose child sub-classes make up the
348
+device tree of a QEMU emulated system.
349
+
350
+The proxy object model will use device proxy objects to replace the
351
+device emulation code within the QEMU process. These objects will live
352
+in the same place in the object and bus hierarchies as the objects they
353
+replace. i.e., the proxy object for an LSI SCSI controller will be a
354
+sub-class of the "pci-device" class, and will have the same PCI bus
355
+parent and the same SCSI bus child objects as the LSI controller object
356
+it replaces.
357
+
358
+It is worth noting that the same proxy object is used to mediate with
359
+all types of remote PCI devices.
360
+
361
+object initialization
362
+^^^^^^^^^^^^^^^^^^^^^
363
+
364
+The Proxy device objects are initialized in the exact same manner in
365
+which any other QEMU device would be initialized.
366
+
367
+In addition, the Proxy objects perform the following two tasks:
368
+- Parses the "socket" sub option and connects to the remote process
369
+using this channel
370
+- Uses the "id" sub-option to connect to the emulated device on the
371
+separate process
372
+
373
+class\_init
374
+'''''''''''
375
+
376
+The ``class_init()`` method of a proxy object will, in general behave
377
+similarly to the object it replaces, including setting any static
378
+properties and methods needed by the proxy.
379
+
380
+instance\_init / realize
381
+''''''''''''''''''''''''
382
+
383
+The ``instance_init()`` and ``realize()`` functions would only need to
384
+perform tasks related to being a proxy, such are registering its own
385
+MMIO handlers, or creating a child bus that other proxy devices can be
386
+attached to later.
387
+
388
+Other tasks will be device-specific. For example, PCI device objects
389
+will initialize the PCI config space in order to make a valid PCI device
390
+tree within the QEMU process.
391
+
392
+address space registration
393
+^^^^^^^^^^^^^^^^^^^^^^^^^^
394
+
395
+Most devices are driven by guest device driver accesses to IO addresses
396
+or ports. The QEMU device emulation code uses QEMU's memory region
397
+function calls (such as ``memory_region_init_io()``) to add callback
398
+functions that QEMU will invoke when the guest accesses the device's
399
+areas of the IO address space. When a guest driver does access the
400
+device, the VM will exit HW virtualization mode and return to QEMU,
401
+which will then lookup and execute the corresponding callback function.
402
+
403
+A proxy object would need to mirror the memory region calls the actual
404
+device emulator would perform in its initialization code, but with its
405
+own callbacks. When invoked by QEMU as a result of a guest IO operation,
406
+they will forward the operation to the device emulation process.
407
+
408
+PCI config space
409
+^^^^^^^^^^^^^^^^
410
+
411
+PCI devices also have a configuration space that can be accessed by the
412
+guest driver. Guest accesses to this space is not handled by the device
413
+emulation object, but by its PCI parent object. Much of this space is
414
+read-only, but certain registers (especially BAR and MSI-related ones)
415
+need to be propagated to the emulation process.
416
+
417
+PCI parent proxy
418
+''''''''''''''''
419
+
420
+One way to propagate guest PCI config accesses is to create a
421
+"pci-device-proxy" class that can serve as the parent of a PCI device
422
+proxy object. This class's parent would be "pci-device" and it would
423
+override the PCI parent's ``config_read()`` and ``config_write()``
424
+methods with ones that forward these operations to the emulation
425
+program.
426
+
427
+interrupt receipt
428
+^^^^^^^^^^^^^^^^^
429
+
430
+A proxy for a device that generates interrupts will need to create a
431
+socket to receive interrupt indications from the emulation process. An
432
+incoming interrupt indication would then be sent up to its bus parent to
433
+be injected into the guest. For example, a PCI device object may use
434
+``pci_set_irq()``.
435
+
436
+live migration
437
+^^^^^^^^^^^^^^
438
+
439
+The proxy will register to save and restore any *vmstate* it needs over
440
+a live migration event. The device proxy does not need to manage the
441
+remote device's *vmstate*; that will be handled by the remote process
442
+proxy (see below).
443
+
444
+QEMU remote device operation
445
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
446
+
447
+Generic device operations, such as DMA, will be performed by the remote
448
+process proxy by sending messages to the remote process.
449
+
450
+DMA operations
451
+^^^^^^^^^^^^^^
452
+
453
+DMA operations would be handled much like vhost applications do. One of
454
+the initial messages sent to the emulation process is a guest memory
455
+table. Each entry in this table consists of a file descriptor and size
456
+that the emulation process can ``mmap()`` to directly access guest
457
+memory, similar to ``vhost_user_set_mem_table()``. Note guest memory
458
+must be backed by file descriptors, such as when QEMU is given the
459
+*-mem-path* command line option.
460
+
461
+IOMMU operations
462
+^^^^^^^^^^^^^^^^
463
+
464
+When the emulated system includes an IOMMU, the remote process proxy in
465
+QEMU will need to create a socket for IOMMU requests from the emulation
466
+process. It will handle those requests with an
467
+``address_space_get_iotlb_entry()`` call. In order to handle IOMMU
468
+unmaps, the remote process proxy will also register as a listener on the
469
+device's DMA address space. When an IOMMU memory region is created
470
+within the DMA address space, an IOMMU notifier for unmaps will be added
471
+to the memory region that will forward unmaps to the emulation process
472
+over the IOMMU socket.
473
+
474
+device hot-plug via QMP
475
+^^^^^^^^^^^^^^^^^^^^^^^
476
+
477
+An QMP "device\_add" command can add a device emulated by a remote
478
+process. It will also have "rid" option to the command, just as the
479
+*-device* command line option does. The remote process may either be one
480
+started at QEMU startup, or be one added by the "add-process" QMP
481
+command described above. In either case, the remote process proxy will
482
+forward the new device's JSON description to the corresponding emulation
483
+process.
484
+
485
+live migration
486
+^^^^^^^^^^^^^^
487
+
488
+The remote process proxy will also register for live migration
489
+notifications with ``vmstate_register()``. When called to save state,
490
+the proxy will send the remote process a secondary socket file
491
+descriptor to save the remote process's device *vmstate* over. The
492
+incoming byte stream length and data will be saved as the proxy's
493
+*vmstate*. When the proxy is resumed on its new host, this *vmstate*
494
+will be extracted, and a secondary socket file descriptor will be sent
495
+to the new remote process through which it receives the *vmstate* in
496
+order to restore the devices there.
497
+
498
+device emulation in remote process
499
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
500
+
501
+The parts of QEMU that the emulation program will need include the
502
+object model; the memory emulation objects; the device emulation objects
503
+of the targeted device, and any dependent devices; and, the device's
504
+backends. It will also need code to setup the machine environment,
505
+handle requests from the QEMU process, and route machine-level requests
506
+(such as interrupts or IOMMU mappings) back to the QEMU process.
507
+
508
+initialization
509
+^^^^^^^^^^^^^^
510
+
511
+The process initialization sequence will follow the same sequence
512
+followed by QEMU. It will first initialize the backend objects, then
513
+device emulation objects. The JSON descriptions sent by the QEMU process
514
+will drive which objects need to be created.
515
+
516
+- address spaces
517
+
518
+Before the device objects are created, the initial address spaces and
519
+memory regions must be configured with ``memory_map_init()``. This
520
+creates a RAM memory region object (*system\_memory*) and an IO memory
521
+region object (*system\_io*).
522
+
523
+- RAM
524
+
525
+RAM memory region creation will follow how ``pc_memory_init()`` creates
526
+them, but must use ``memory_region_init_ram_from_fd()`` instead of
527
+``memory_region_allocate_system_memory()``. The file descriptors needed
528
+will be supplied by the guest memory table from above. Those RAM regions
529
+would then be added to the *system\_memory* memory region with
530
+``memory_region_add_subregion()``.
531
+
532
+- PCI
533
+
534
+IO initialization will be driven by the JSON descriptions sent from the
535
+QEMU process. For a PCI device, a PCI bus will need to be created with
536
+``pci_root_bus_new()``, and a PCI memory region will need to be created
537
+and added to the *system\_memory* memory region with
538
+``memory_region_add_subregion_overlap()``. The overlap version is
539
+required for architectures where PCI memory overlaps with RAM memory.
540
+
541
+MMIO handling
542
+^^^^^^^^^^^^^
543
+
544
+The device emulation objects will use ``memory_region_init_io()`` to
545
+install their MMIO handlers, and ``pci_register_bar()`` to associate
546
+those handlers with a PCI BAR, as they do within QEMU currently.
547
+
548
+In order to use ``address_space_rw()`` in the emulation process to
549
+handle MMIO requests from QEMU, the PCI physical addresses must be the
550
+same in the QEMU process and the device emulation process. In order to
551
+accomplish that, guest BAR programming must also be forwarded from QEMU
552
+to the emulation process.
553
+
554
+interrupt injection
555
+^^^^^^^^^^^^^^^^^^^
556
+
557
+When device emulation wants to inject an interrupt into the VM, the
558
+request climbs the device's bus object hierarchy until the point where a
559
+bus object knows how to signal the interrupt to the guest. The details
560
+depend on the type of interrupt being raised.
561
+
562
+- PCI pin interrupts
563
+
564
+On x86 systems, there is an emulated IOAPIC object attached to the root
565
+PCI bus object, and the root PCI object forwards interrupt requests to
566
+it. The IOAPIC object, in turn, calls the KVM driver to inject the
567
+corresponding interrupt into the VM. The simplest way to handle this in
568
+an emulation process would be to setup the root PCI bus driver (via
569
+``pci_bus_irqs()``) to send a interrupt request back to the QEMU
570
+process, and have the device proxy object reflect it up the PCI tree
571
+there.
572
+
573
+- PCI MSI/X interrupts
574
+
575
+PCI MSI/X interrupts are implemented in HW as DMA writes to a
576
+CPU-specific PCI address. In QEMU on x86, a KVM APIC object receives
577
+these DMA writes, then calls into the KVM driver to inject the interrupt
578
+into the VM. A simple emulation process implementation would be to send
579
+the MSI DMA address from QEMU as a message at initialization, then
580
+install an address space handler at that address which forwards the MSI
581
+message back to QEMU.
582
+
583
+DMA operations
584
+^^^^^^^^^^^^^^
585
+
586
+When a emulation object wants to DMA into or out of guest memory, it
587
+first must use dma\_memory\_map() to convert the DMA address to a local
588
+virtual address. The emulation process memory region objects setup above
589
+will be used to translate the DMA address to a local virtual address the
590
+device emulation code can access.
591
+
592
+IOMMU
593
+^^^^^
594
+
595
+When an IOMMU is in use in QEMU, DMA translation uses IOMMU memory
596
+regions to translate the DMA address to a guest physical address before
597
+that physical address can be translated to a local virtual address. The
598
+emulation process will need similar functionality.
599
+
600
+- IOTLB cache
601
+
602
+The emulation process will maintain a cache of recent IOMMU translations
603
+(the IOTLB). When the translate() callback of an IOMMU memory region is
604
+invoked, the IOTLB cache will be searched for an entry that will map the
605
+DMA address to a guest PA. On a cache miss, a message will be sent back
606
+to QEMU requesting the corresponding translation entry, which be both be
607
+used to return a guest address and be added to the cache.
608
+
609
+- IOTLB purge
610
+
611
+The IOMMU emulation will also need to act on unmap requests from QEMU.
612
+These happen when the guest IOMMU driver purges an entry from the
613
+guest's translation table.
614
+
615
+live migration
616
+^^^^^^^^^^^^^^
617
+
618
+When a remote process receives a live migration indication from QEMU, it
619
+will set up a channel using the received file descriptor with
620
+``qio_channel_socket_new_fd()``. This channel will be used to create a
621
+*QEMUfile* that can be passed to ``qemu_save_device_state()`` to send
622
+the process's device state back to QEMU. This method will be reversed on
623
+restore - the channel will be passed to ``qemu_loadvm_state()`` to
624
+restore the device state.
625
+
626
+Accelerating device emulation
627
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
628
+
629
+The messages that are required to be sent between QEMU and the emulation
630
+process can add considerable latency to IO operations. The optimizations
631
+described below attempt to ameliorate this effect by allowing the
632
+emulation process to communicate directly with the kernel KVM driver.
633
+The KVM file descriptors created would be passed to the emulation process
634
+via initialization messages, much like the guest memory table is done.
635
+#### MMIO acceleration
636
+
637
+Vhost user applications can receive guest virtio driver stores directly
638
+from KVM. The issue with the eventfd mechanism used by vhost user is
639
+that it does not pass any data with the event indication, so it cannot
640
+handle guest loads or guest stores that carry store data. This concept
641
+could, however, be expanded to cover more cases.
642
+
643
+The expanded idea would require a new type of KVM device:
644
+*KVM\_DEV\_TYPE\_USER*. This device has two file descriptors: a master
645
+descriptor that QEMU can use for configuration, and a slave descriptor
646
+that the emulation process can use to receive MMIO notifications. QEMU
647
+would create both descriptors using the KVM driver, and pass the slave
648
+descriptor to the emulation process via an initialization message.
649
+
650
+data structures
651
+^^^^^^^^^^^^^^^
652
+
653
+- guest physical range
654
+
655
+The guest physical range structure describes the address range that a
656
+device will respond to. It includes the base and length of the range, as
657
+well as which bus the range resides on (e.g., on an x86machine, it can
658
+specify whether the range refers to memory or IO addresses).
659
+
660
+A device can have multiple physical address ranges it responds to (e.g.,
661
+a PCI device can have multiple BARs), so the structure will also include
662
+an enumerated identifier to specify which of the device's ranges is
663
+being referred to.
664
+
665
++--------+----------------------------+
666
+| Name | Description |
667
++========+============================+
668
+| addr | range base address |
669
++--------+----------------------------+
670
+| len | range length |
671
++--------+----------------------------+
672
+| bus | addr type (memory or IO) |
673
++--------+----------------------------+
674
+| id | range ID (e.g., PCI BAR) |
675
++--------+----------------------------+
676
+
677
+- MMIO request structure
678
+
679
+This structure describes an MMIO operation. It includes which guest
680
+physical range the MMIO was within, the offset within that range, the
681
+MMIO type (e.g., load or store), and its length and data. It also
682
+includes a sequence number that can be used to reply to the MMIO, and
683
+the CPU that issued the MMIO.
684
+
685
++----------+------------------------+
686
+| Name | Description |
687
++==========+========================+
688
+| rid | range MMIO is within |
689
++----------+------------------------+
690
+| offset | offset withing *rid* |
691
++----------+------------------------+
692
+| type | e.g., load or store |
693
++----------+------------------------+
694
+| len | MMIO length |
695
++----------+------------------------+
696
+| data | store data |
697
++----------+------------------------+
698
+| seq | sequence ID |
699
++----------+------------------------+
700
+
701
+- MMIO request queues
702
+
703
+MMIO request queues are FIFO arrays of MMIO request structures. There
704
+are two queues: pending queue is for MMIOs that haven't been read by the
705
+emulation program, and the sent queue is for MMIOs that haven't been
706
+acknowledged. The main use of the second queue is to validate MMIO
707
+replies from the emulation program.
708
+
709
+- scoreboard
710
+
711
+Each CPU in the VM is emulated in QEMU by a separate thread, so multiple
712
+MMIOs may be waiting to be consumed by an emulation program and multiple
713
+threads may be waiting for MMIO replies. The scoreboard would contain a
714
+wait queue and sequence number for the per-CPU threads, allowing them to
715
+be individually woken when the MMIO reply is received from the emulation
716
+program. It also tracks the number of posted MMIO stores to the device
717
+that haven't been replied to, in order to satisfy the PCI constraint
718
+that a load to a device will not complete until all previous stores to
719
+that device have been completed.
720
+
721
+- device shadow memory
722
+
723
+Some MMIO loads do not have device side-effects. These MMIOs can be
724
+completed without sending a MMIO request to the emulation program if the
725
+emulation program shares a shadow image of the device's memory image
726
+with the KVM driver.
727
+
728
+The emulation program will ask the KVM driver to allocate memory for the
729
+shadow image, and will then use ``mmap()`` to directly access it. The
730
+emulation program can control KVM access to the shadow image by sending
731
+KVM an access map telling it which areas of the image have no
732
+side-effects (and can be completed immediately), and which require a
733
+MMIO request to the emulation program. The access map can also inform
734
+the KVM drive which size accesses are allowed to the image.
735
+
736
+master descriptor
737
+^^^^^^^^^^^^^^^^^
738
+
739
+The master descriptor is used by QEMU to configure the new KVM device.
740
+The descriptor would be returned by the KVM driver when QEMU issues a
741
+*KVM\_CREATE\_DEVICE* ``ioctl()`` with a *KVM\_DEV\_TYPE\_USER* type.
742
+
743
+KVM\_DEV\_TYPE\_USER device ops
744
+
745
+
746
+The *KVM\_DEV\_TYPE\_USER* operations vector will be registered by a
747
+``kvm_register_device_ops()`` call when the KVM system in initialized by
748
+``kvm_init()``. These device ops are called by the KVM driver when QEMU
749
+executes certain ``ioctl()`` operations on its KVM file descriptor. They
750
+include:
751
+
752
+- create
753
+
754
+This routine is called when QEMU issues a *KVM\_CREATE\_DEVICE*
755
+``ioctl()`` on its per-VM file descriptor. It will allocate and
756
+initialize a KVM user device specific data structure, and assign the
757
+*kvm\_device* private field to it.
758
+
759
+- ioctl
760
+
761
+This routine is invoked when QEMU issues an ``ioctl()`` on the master
762
+descriptor. The ``ioctl()`` commands supported are defined by the KVM
763
+device type. *KVM\_DEV\_TYPE\_USER* ones will need several commands:
764
+
765
+*KVM\_DEV\_USER\_SLAVE\_FD* creates the slave file descriptor that will
766
+be passed to the device emulation program. Only one slave can be created
767
+by each master descriptor. The file operations performed by this
768
+descriptor are described below.
769
+
770
+The *KVM\_DEV\_USER\_PA\_RANGE* command configures a guest physical
771
+address range that the slave descriptor will receive MMIO notifications
772
+for. The range is specified by a guest physical range structure
773
+argument. For buses that assign addresses to devices dynamically, this
774
+command can be executed while the guest is running, such as the case
775
+when a guest changes a device's PCI BAR registers.
776
+
777
+*KVM\_DEV\_USER\_PA\_RANGE* will use ``kvm_io_bus_register_dev()`` to
778
+register *kvm\_io\_device\_ops* callbacks to be invoked when the guest
779
+performs a MMIO operation within the range. When a range is changed,
780
+``kvm_io_bus_unregister_dev()`` is used to remove the previous
781
+instantiation.
782
+
783
+*KVM\_DEV\_USER\_TIMEOUT* will configure a timeout value that specifies
784
+how long KVM will wait for the emulation process to respond to a MMIO
785
+indication.
786
+
787
+- destroy
788
+
789
+This routine is called when the VM instance is destroyed. It will need
790
+to destroy the slave descriptor; and free any memory allocated by the
791
+driver, as well as the *kvm\_device* structure itself.
792
+
793
+slave descriptor
794
+^^^^^^^^^^^^^^^^
795
+
796
+The slave descriptor will have its own file operations vector, which
797
+responds to system calls on the descriptor performed by the device
798
+emulation program.
799
+
800
+- read
801
+
802
+A read returns any pending MMIO requests from the KVM driver as MMIO
803
+request structures. Multiple structures can be returned if there are
804
+multiple MMIO operations pending. The MMIO requests are moved from the
805
+pending queue to the sent queue, and if there are threads waiting for
806
+space in the pending to add new MMIO operations, they will be woken
807
+here.
808
+
809
+- write
810
+
811
+A write also consists of a set of MMIO requests. They are compared to
812
+the MMIO requests in the sent queue. Matches are removed from the sent
813
+queue, and any threads waiting for the reply are woken. If a store is
814
+removed, then the number of posted stores in the per-CPU scoreboard is
815
+decremented. When the number is zero, and a non side-effect load was
816
+waiting for posted stores to complete, the load is continued.
817
+
818
+- ioctl
819
+
820
+There are several ioctl()s that can be performed on the slave
821
+descriptor.
822
+
823
+A *KVM\_DEV\_USER\_SHADOW\_SIZE* ``ioctl()`` causes the KVM driver to
824
+allocate memory for the shadow image. This memory can later be
825
+``mmap()``\ ed by the emulation process to share the emulation's view of
826
+device memory with the KVM driver.
827
+
828
+A *KVM\_DEV\_USER\_SHADOW\_CTRL* ``ioctl()`` controls access to the
829
+shadow image. It will send the KVM driver a shadow control map, which
830
+specifies which areas of the image can complete guest loads without
831
+sending the load request to the emulation program. It will also specify
832
+the size of load operations that are allowed.
833
+
834
+- poll
835
+
836
+An emulation program will use the ``poll()`` call with a *POLLIN* flag
837
+to determine if there are MMIO requests waiting to be read. It will
838
+return if the pending MMIO request queue is not empty.
839
+
840
+- mmap
841
+
842
+This call allows the emulation program to directly access the shadow
843
+image allocated by the KVM driver. As device emulation updates device
844
+memory, changes with no side-effects will be reflected in the shadow,
845
+and the KVM driver can satisfy guest loads from the shadow image without
846
+needing to wait for the emulation program.
847
+
848
+kvm\_io\_device ops
849
+^^^^^^^^^^^^^^^^^^^
850
+
851
+Each KVM per-CPU thread can handle MMIO operation on behalf of the guest
852
+VM. KVM will use the MMIO's guest physical address to search for a
853
+matching *kvm\_io\_device* to see if the MMIO can be handled by the KVM
854
+driver instead of exiting back to QEMU. If a match is found, the
855
+corresponding callback will be invoked.
856
+
857
+- read
858
+
859
+This callback is invoked when the guest performs a load to the device.
860
+Loads with side-effects must be handled synchronously, with the KVM
861
+driver putting the QEMU thread to sleep waiting for the emulation
862
+process reply before re-starting the guest. Loads that do not have
863
+side-effects may be optimized by satisfying them from the shadow image,
864
+if there are no outstanding stores to the device by this CPU. PCI memory
865
+ordering demands that a load cannot complete before all older stores to
866
+the same device have been completed.
867
+
868
+- write
869
+
870
+Stores can be handled asynchronously unless the pending MMIO request
871
+queue is full. In this case, the QEMU thread must sleep waiting for
872
+space in the queue. Stores will increment the number of posted stores in
873
+the per-CPU scoreboard, in order to implement the PCI ordering
874
+constraint above.
875
+
876
+interrupt acceleration
877
+^^^^^^^^^^^^^^^^^^^^^^
878
+
879
+This performance optimization would work much like a vhost user
880
+application does, where the QEMU process sets up *eventfds* that cause
881
+the device's corresponding interrupt to be triggered by the KVM driver.
882
+These irq file descriptors are sent to the emulation process at
883
+initialization, and are used when the emulation code raises a device
884
+interrupt.
885
+
886
+intx acceleration
887
+'''''''''''''''''
888
+
889
+Traditional PCI pin interrupts are level based, so, in addition to an
890
+irq file descriptor, a re-sampling file descriptor needs to be sent to
891
+the emulation program. This second file descriptor allows multiple
892
+devices sharing an irq to be notified when the interrupt has been
893
+acknowledged by the guest, so they can re-trigger the interrupt if their
894
+device has not de-asserted its interrupt.
895
+
896
+intx irq descriptor
897
+
898
+
899
+The irq descriptors are created by the proxy object
900
+``using event_notifier_init()`` to create the irq and re-sampling
901
+*eventds*, and ``kvm_vm_ioctl(KVM_IRQFD)`` to bind them to an interrupt.
902
+The interrupt route can be found with
903
+``pci_device_route_intx_to_irq()``.
904
+
905
+intx routing changes
906
+
907
+
908
+Intx routing can be changed when the guest programs the APIC the device
909
+pin is connected to. The proxy object in QEMU will use
910
+``pci_device_set_intx_routing_notifier()`` to be informed of any guest
911
+changes to the route. This handler will broadly follow the VFIO
912
+interrupt logic to change the route: de-assigning the existing irq
913
+descriptor from its route, then assigning it the new route. (see
914
+``vfio_intx_update()``)
915
+
916
+MSI/X acceleration
917
+''''''''''''''''''
918
+
919
+MSI/X interrupts are sent as DMA transactions to the host. The interrupt
920
+data contains a vector that is programmed by the guest, A device may have
921
+multiple MSI interrupts associated with it, so multiple irq descriptors
922
+may need to be sent to the emulation program.
923
+
924
+MSI/X irq descriptor
925
+
926
+
927
+This case will also follow the VFIO example. For each MSI/X interrupt,
928
+an *eventfd* is created, a virtual interrupt is allocated by
929
+``kvm_irqchip_add_msi_route()``, and the virtual interrupt is bound to
930
+the eventfd with ``kvm_irqchip_add_irqfd_notifier()``.
931
+
932
+MSI/X config space changes
933
+
934
+
935
+The guest may dynamically update several MSI-related tables in the
936
+device's PCI config space. These include per-MSI interrupt enables and
937
+vector data. Additionally, MSIX tables exist in device memory space, not
938
+config space. Much like the BAR case above, the proxy object must look
939
+at guest config space programming to keep the MSI interrupt state
940
+consistent between QEMU and the emulation program.
941
+
942
+--------------
943
+
944
+Disaggregated CPU emulation
945
+---------------------------
946
+
947
+After IO services have been disaggregated, a second phase would be to
948
+separate a process to handle CPU instruction emulation from the main
949
+QEMU control function. There are no object separation points for this
950
+code, so the first task would be to create one.
951
+
952
+Host access controls
953
+--------------------
954
+
955
+Separating QEMU relies on the host OS's access restriction mechanisms to
956
+enforce that the differing processes can only access the objects they
957
+are entitled to. There are a couple types of mechanisms usually provided
958
+by general purpose OSs.
959
+
960
+Discretionary access control
961
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
962
+
963
+Discretionary access control allows each user to control who can access
964
+their files. In Linux, this type of control is usually too coarse for
965
+QEMU separation, since it only provides three separate access controls:
966
+one for the same user ID, the second for users IDs with the same group
967
+ID, and the third for all other user IDs. Each device instance would
968
+need a separate user ID to provide access control, which is likely to be
969
+unwieldy for dynamically created VMs.
970
+
971
+Mandatory access control
972
+~~~~~~~~~~~~~~~~~~~~~~~~
973
+
974
+Mandatory access control allows the OS to add an additional set of
975
+controls on top of discretionary access for the OS to control. It also
976
+adds other attributes to processes and files such as types, roles, and
977
+categories, and can establish rules for how processes and files can
978
+interact.
979
+
980
+Type enforcement
981
+^^^^^^^^^^^^^^^^
982
+
983
+Type enforcement assigns a *type* attribute to processes and files, and
984
+allows rules to be written on what operations a process with a given
985
+type can perform on a file with a given type. QEMU separation could take
986
+advantage of type enforcement by running the emulation processes with
987
+different types, both from the main QEMU process, and from the emulation
988
+processes of different classes of devices.
989
+
990
+For example, guest disk images and disk emulation processes could have
991
+types separate from the main QEMU process and non-disk emulation
992
+processes, and the type rules could prevent processes other than disk
993
+emulation ones from accessing guest disk images. Similarly, network
994
+emulation processes can have a type separate from the main QEMU process
995
+and non-network emulation process, and only that type can access the
996
+host tun/tap device used to provide guest networking.
997
+
998
+Category enforcement
999
+^^^^^^^^^^^^^^^^^^^^
1000
+
1001
+Category enforcement assigns a set of numbers within a given range to
1002
+the process or file. The process is granted access to the file if the
1003
+process's set is a superset of the file's set. This enforcement can be
1004
+used to separate multiple instances of devices in the same class.
1005
+
1006
+For example, if there are multiple disk devices provides to a guest,
1007
+each device emulation process could be provisioned with a separate
1008
+category. The different device emulation processes would not be able to
1009
+access each other's backing disk images.
1010
+
1011
+Alternatively, categories could be used in lieu of the type enforcement
1012
+scheme described above. In this scenario, different categories would be
1013
+used to prevent device emulation processes in different classes from
1014
+accessing resources assigned to other classes.
58
--
1015
--
59
2.24.1
1016
2.29.2
60
1017
61
diff view generated by jsdifflib
1
When using an external data file, there are no refcounts for data
1
From: Elena Ufimtseva <elena.ufimtseva@oracle.com>
2
clusters. We thus have to adjust the corruption test in this patch to
3
not be based around a data cluster allocation, but the L2 table
4
allocation (L2 tables are still refcounted with external data files).
5
2
6
Furthermore, we should not print qcow2.py's list of incompatible
3
Adds documentation explaining the command-line arguments needed
7
features because it differs depending on whether there is an external
4
to use multi-process.
8
data file or not.
9
5
10
With those two changes, the test will work both with and without
6
Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
11
external data files (once that options works with the iotests at all).
7
Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
8
Signed-off-by: John G Johnson <john.g.johnson@oracle.com>
9
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
10
Message-id: 49f757a84e5dd6fae14b22544897d1124c5fdbad.1611938319.git.jag.raman@oracle.com
12
11
13
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
[Move orphan docs/multi-process.rst document into docs/system/ and add
14
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
13
it to index.rst to prevent Sphinx "document isn't included in any
15
Message-id: 20191107163708.833192-20-mreitz@redhat.com
14
toctree" error.
16
Signed-off-by: Max Reitz <mreitz@redhat.com>
15
--Stefan]
16
17
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
17
---
18
---
18
tests/qemu-iotests/137 | 15 +++++++++++----
19
MAINTAINERS | 1 +
19
tests/qemu-iotests/137.out | 6 ++----
20
docs/system/index.rst | 1 +
20
2 files changed, 13 insertions(+), 8 deletions(-)
21
docs/system/multi-process.rst | 64 +++++++++++++++++++++++++++++++++++
22
3 files changed, 66 insertions(+)
23
create mode 100644 docs/system/multi-process.rst
21
24
22
diff --git a/tests/qemu-iotests/137 b/tests/qemu-iotests/137
25
diff --git a/MAINTAINERS b/MAINTAINERS
23
index XXXXXXX..XXXXXXX 100755
24
--- a/tests/qemu-iotests/137
25
+++ b/tests/qemu-iotests/137
26
@@ -XXX,XX +XXX,XX @@ $QEMU_IO \
27
"$TEST_IMG" 2>&1 | _filter_qemu_io
28
29
# The dirty bit must not be set
30
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
31
+# (Filter the external data file bit)
32
+if $PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features \
33
+ | grep -q '\<0\>'
34
+then
35
+ echo 'ERROR: Dirty bit set'
36
+else
37
+ echo 'OK: Dirty bit not set'
38
+fi
39
40
# Similarly we can test whether corruption detection has been enabled:
41
-# Create L1/L2, overwrite first entry in refcount block, allocate something.
42
+# Create L1, overwrite refcounts, force allocation of L2 by writing
43
+# data.
44
# Disabling the checks should fail, so the corruption must be detected.
45
_make_test_img 64M
46
-$QEMU_IO -c "write 0 64k" "$TEST_IMG" | _filter_qemu_io
47
-poke_file "$TEST_IMG" "$((0x20000))" "\x00\x00"
48
+poke_file "$TEST_IMG" "$((0x20000))" "\x00\x00\x00\x00\x00\x00\x00\x00"
49
$QEMU_IO \
50
-c "reopen -o overlap-check=none,lazy-refcounts=42" \
51
-c "write 64k 64k" \
52
diff --git a/tests/qemu-iotests/137.out b/tests/qemu-iotests/137.out
53
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
54
--- a/tests/qemu-iotests/137.out
27
--- a/MAINTAINERS
55
+++ b/tests/qemu-iotests/137.out
28
+++ b/MAINTAINERS
56
@@ -XXX,XX +XXX,XX @@ qemu-io: Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are
29
@@ -XXX,XX +XXX,XX @@ M: Jagannathan Raman <jag.raman@oracle.com>
57
wrote 512/512 bytes at offset 0
30
M: John G Johnson <john.g.johnson@oracle.com>
58
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
31
S: Maintained
59
./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
32
F: docs/devel/multi-process.rst
60
-incompatible_features []
33
+F: docs/system/multi-process.rst
61
+OK: Dirty bit not set
34
62
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
35
Build and test automation
63
-wrote 65536/65536 bytes at offset 0
36
-------------------------
64
-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
37
diff --git a/docs/system/index.rst b/docs/system/index.rst
65
qemu-io: Parameter 'lazy-refcounts' expects 'on' or 'off'
38
index XXXXXXX..XXXXXXX 100644
66
-qcow2: Marking image as corrupt: Preventing invalid write on metadata (overlaps with qcow2_header); further corruption events will be suppressed
39
--- a/docs/system/index.rst
67
+qcow2: Marking image as corrupt: Preventing invalid allocation of L2 table at offset 0; further corruption events will be suppressed
40
+++ b/docs/system/index.rst
68
write failed: Input/output error
41
@@ -XXX,XX +XXX,XX @@ Contents:
69
*** done
42
pr-manager
43
targets
44
security
45
+ multi-process
46
deprecated
47
removed-features
48
build-platforms
49
diff --git a/docs/system/multi-process.rst b/docs/system/multi-process.rst
50
new file mode 100644
51
index XXXXXXX..XXXXXXX
52
--- /dev/null
53
+++ b/docs/system/multi-process.rst
54
@@ -XXX,XX +XXX,XX @@
55
+Multi-process QEMU
56
+==================
57
+
58
+This document describes how to configure and use multi-process qemu.
59
+For the design document refer to docs/devel/qemu-multiprocess.
60
+
61
+1) Configuration
62
+----------------
63
+
64
+multi-process is enabled by default for targets that enable KVM
65
+
66
+
67
+2) Usage
68
+--------
69
+
70
+Multi-process QEMU requires an orchestrator to launch.
71
+
72
+Following is a description of command-line used to launch mpqemu.
73
+
74
+* Orchestrator:
75
+
76
+ - The Orchestrator creates a unix socketpair
77
+
78
+ - It launches the remote process and passes one of the
79
+ sockets to it via command-line.
80
+
81
+ - It then launches QEMU and specifies the other socket as an option
82
+ to the Proxy device object
83
+
84
+* Remote Process:
85
+
86
+ - QEMU can enter remote process mode by using the "remote" machine
87
+ option.
88
+
89
+ - The orchestrator creates a "remote-object" with details about
90
+ the device and the file descriptor for the device
91
+
92
+ - The remaining options are no different from how one launches QEMU with
93
+ devices.
94
+
95
+ - Example command-line for the remote process is as follows:
96
+
97
+ /usr/bin/qemu-system-x86_64 \
98
+ -machine x-remote \
99
+ -device lsi53c895a,id=lsi0 \
100
+ -drive id=drive_image2,file=/build/ol7-nvme-test-1.qcow2 \
101
+ -device scsi-hd,id=drive2,drive=drive_image2,bus=lsi0.0,scsi-id=0 \
102
+ -object x-remote-object,id=robj1,devid=lsi1,fd=4,
103
+
104
+* QEMU:
105
+
106
+ - Since parts of the RAM are shared between QEMU & remote process, a
107
+ memory-backend-memfd is required to facilitate this, as follows:
108
+
109
+ -object memory-backend-memfd,id=mem,size=2G
110
+
111
+ - A "x-pci-proxy-dev" device is created for each of the PCI devices emulated
112
+ in the remote process. A "socket" sub-option specifies the other end of
113
+ unix channel created by orchestrator. The "id" sub-option must be specified
114
+ and should be the same as the "id" specified for the remote PCI device
115
+
116
+ - Example commandline for QEMU is as follows:
117
+
118
+ -device x-pci-proxy-dev,id=lsi0,socket=3
70
--
119
--
71
2.24.1
120
2.29.2
72
121
73
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
From: Jagannathan Raman <jag.raman@oracle.com>
2
2
3
qcow2_can_store_new_dirty_bitmap works wrong, as it considers only
3
Allow RAM MemoryRegion to be created from an offset in a file, instead
4
bitmaps already stored in the qcow2 image and ignores persistent
4
of allocating at offset of 0 by default. This is needed to synchronize
5
BdrvDirtyBitmap objects.
5
RAM between QEMU & remote process.
6
6
7
So, let's instead count persistent BdrvDirtyBitmaps. We load all qcow2
7
Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
8
bitmaps on open, so there should not be any bitmap in the image for
8
Signed-off-by: John G Johnson <john.g.johnson@oracle.com>
9
which we don't have BdrvDirtyBitmaps version. If it is - it's a kind of
9
Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
10
corruption, and no reason to check for corruptions here (open() and
10
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
11
close() are better places for it).
11
Message-id: 609996697ad8617e3b01df38accc5c208c24d74e.1611938319.git.jag.raman@oracle.com
12
12
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
14
Message-id: 20191014115126.15360-2-vsementsov@virtuozzo.com
15
Reviewed-by: Max Reitz <mreitz@redhat.com>
16
Cc: qemu-stable@nongnu.org
17
Signed-off-by: Max Reitz <mreitz@redhat.com>
18
---
13
---
19
block/qcow2-bitmap.c | 41 ++++++++++++++++++-----------------------
14
include/exec/memory.h | 2 ++
20
1 file changed, 18 insertions(+), 23 deletions(-)
15
include/exec/ram_addr.h | 4 ++--
21
16
include/qemu/mmap-alloc.h | 4 +++-
22
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
17
backends/hostmem-memfd.c | 2 +-
23
index XXXXXXX..XXXXXXX 100644
18
hw/misc/ivshmem.c | 3 ++-
24
--- a/block/qcow2-bitmap.c
19
softmmu/memory.c | 3 ++-
25
+++ b/block/qcow2-bitmap.c
20
softmmu/physmem.c | 12 +++++++-----
26
@@ -XXX,XX +XXX,XX @@ bool coroutine_fn qcow2_co_can_store_new_dirty_bitmap(BlockDriverState *bs,
21
util/mmap-alloc.c | 8 +++++---
27
Error **errp)
22
util/oslib-posix.c | 2 +-
28
{
23
9 files changed, 25 insertions(+), 15 deletions(-)
29
BDRVQcow2State *s = bs->opaque;
24
30
- bool found;
25
diff --git a/include/exec/memory.h b/include/exec/memory.h
31
- Qcow2BitmapList *bm_list;
26
index XXXXXXX..XXXXXXX 100644
32
+ BdrvDirtyBitmap *bitmap;
27
--- a/include/exec/memory.h
33
+ uint64_t bitmap_directory_size = 0;
28
+++ b/include/exec/memory.h
34
+ uint32_t nb_bitmaps = 0;
29
@@ -XXX,XX +XXX,XX @@ void memory_region_init_ram_from_file(MemoryRegion *mr,
35
+
30
* @size: size of the region.
36
+ if (bdrv_find_dirty_bitmap(bs, name)) {
31
* @share: %true if memory must be mmaped with the MAP_SHARED flag
37
+ error_setg(errp, "Bitmap already exists: %s", name);
32
* @fd: the fd to mmap.
38
+ return false;
33
+ * @offset: offset within the file referenced by fd
39
+ }
34
* @errp: pointer to Error*, to store an error if it happens.
40
35
*
41
if (s->qcow_version < 3) {
36
* Note that this function does not do anything to cause the data in the
42
/* Without autoclear_features, we would always have to assume
37
@@ -XXX,XX +XXX,XX @@ void memory_region_init_ram_from_fd(MemoryRegion *mr,
43
@@ -XXX,XX +XXX,XX @@ bool coroutine_fn qcow2_co_can_store_new_dirty_bitmap(BlockDriverState *bs,
38
uint64_t size,
44
goto fail;
39
bool share,
40
int fd,
41
+ ram_addr_t offset,
42
Error **errp);
43
#endif
44
45
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
46
index XXXXXXX..XXXXXXX 100644
47
--- a/include/exec/ram_addr.h
48
+++ b/include/exec/ram_addr.h
49
@@ -XXX,XX +XXX,XX @@ RAMBlock *qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
50
uint32_t ram_flags, const char *mem_path,
51
bool readonly, Error **errp);
52
RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr,
53
- uint32_t ram_flags, int fd, bool readonly,
54
- Error **errp);
55
+ uint32_t ram_flags, int fd, off_t offset,
56
+ bool readonly, Error **errp);
57
58
RAMBlock *qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
59
MemoryRegion *mr, Error **errp);
60
diff --git a/include/qemu/mmap-alloc.h b/include/qemu/mmap-alloc.h
61
index XXXXXXX..XXXXXXX 100644
62
--- a/include/qemu/mmap-alloc.h
63
+++ b/include/qemu/mmap-alloc.h
64
@@ -XXX,XX +XXX,XX @@ size_t qemu_mempath_getpagesize(const char *mem_path);
65
* @readonly: true for a read-only mapping, false for read/write.
66
* @shared: map has RAM_SHARED flag.
67
* @is_pmem: map has RAM_PMEM flag.
68
+ * @map_offset: map starts at offset of map_offset from the start of fd
69
*
70
* Return:
71
* On success, return a pointer to the mapped area.
72
@@ -XXX,XX +XXX,XX @@ void *qemu_ram_mmap(int fd,
73
size_t align,
74
bool readonly,
75
bool shared,
76
- bool is_pmem);
77
+ bool is_pmem,
78
+ off_t map_offset);
79
80
void qemu_ram_munmap(int fd, void *ptr, size_t size);
81
82
diff --git a/backends/hostmem-memfd.c b/backends/hostmem-memfd.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/backends/hostmem-memfd.c
85
+++ b/backends/hostmem-memfd.c
86
@@ -XXX,XX +XXX,XX @@ memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
87
name = host_memory_backend_get_name(backend);
88
memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend),
89
name, backend->size,
90
- backend->share, fd, errp);
91
+ backend->share, fd, 0, errp);
92
g_free(name);
93
}
94
95
diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
96
index XXXXXXX..XXXXXXX 100644
97
--- a/hw/misc/ivshmem.c
98
+++ b/hw/misc/ivshmem.c
99
@@ -XXX,XX +XXX,XX @@ static void process_msg_shmem(IVShmemState *s, int fd, Error **errp)
100
101
/* mmap the region and map into the BAR2 */
102
memory_region_init_ram_from_fd(&s->server_bar2, OBJECT(s),
103
- "ivshmem.bar2", size, true, fd, &local_err);
104
+ "ivshmem.bar2", size, true, fd, 0,
105
+ &local_err);
106
if (local_err) {
107
error_propagate(errp, local_err);
108
return;
109
diff --git a/softmmu/memory.c b/softmmu/memory.c
110
index XXXXXXX..XXXXXXX 100644
111
--- a/softmmu/memory.c
112
+++ b/softmmu/memory.c
113
@@ -XXX,XX +XXX,XX @@ void memory_region_init_ram_from_fd(MemoryRegion *mr,
114
uint64_t size,
115
bool share,
116
int fd,
117
+ ram_addr_t offset,
118
Error **errp)
119
{
120
Error *err = NULL;
121
@@ -XXX,XX +XXX,XX @@ void memory_region_init_ram_from_fd(MemoryRegion *mr,
122
mr->destructor = memory_region_destructor_ram;
123
mr->ram_block = qemu_ram_alloc_from_fd(size, mr,
124
share ? RAM_SHARED : 0,
125
- fd, false, &err);
126
+ fd, offset, false, &err);
127
if (err) {
128
mr->size = int128_zero();
129
object_unparent(OBJECT(mr));
130
diff --git a/softmmu/physmem.c b/softmmu/physmem.c
131
index XXXXXXX..XXXXXXX 100644
132
--- a/softmmu/physmem.c
133
+++ b/softmmu/physmem.c
134
@@ -XXX,XX +XXX,XX @@ static void *file_ram_alloc(RAMBlock *block,
135
int fd,
136
bool readonly,
137
bool truncate,
138
+ off_t offset,
139
Error **errp)
140
{
141
void *area;
142
@@ -XXX,XX +XXX,XX @@ static void *file_ram_alloc(RAMBlock *block,
45
}
143
}
46
144
47
- if (s->nb_bitmaps == 0) {
145
area = qemu_ram_mmap(fd, memory, block->mr->align, readonly,
48
- return true;
146
- block->flags & RAM_SHARED, block->flags & RAM_PMEM);
49
+ FOR_EACH_DIRTY_BITMAP(bs, bitmap) {
147
+ block->flags & RAM_SHARED, block->flags & RAM_PMEM,
50
+ if (bdrv_dirty_bitmap_get_persistence(bitmap)) {
148
+ offset);
51
+ nb_bitmaps++;
149
if (area == MAP_FAILED) {
52
+ bitmap_directory_size +=
150
error_setg_errno(errp, errno,
53
+ calc_dir_entry_size(strlen(bdrv_dirty_bitmap_name(bitmap)), 0);
151
"unable to map backing store for guest RAM");
54
+ }
152
@@ -XXX,XX +XXX,XX @@ static void ram_block_add(RAMBlock *new_block, Error **errp, bool shared)
153
154
#ifdef CONFIG_POSIX
155
RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr,
156
- uint32_t ram_flags, int fd, bool readonly,
157
- Error **errp)
158
+ uint32_t ram_flags, int fd, off_t offset,
159
+ bool readonly, Error **errp)
160
{
161
RAMBlock *new_block;
162
Error *local_err = NULL;
163
@@ -XXX,XX +XXX,XX @@ RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr,
164
new_block->max_length = size;
165
new_block->flags = ram_flags;
166
new_block->host = file_ram_alloc(new_block, size, fd, readonly,
167
- !file_size, errp);
168
+ !file_size, offset, errp);
169
if (!new_block->host) {
170
g_free(new_block);
171
return NULL;
172
@@ -XXX,XX +XXX,XX @@ RAMBlock *qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
173
return NULL;
55
}
174
}
56
+ nb_bitmaps++;
175
57
+ bitmap_directory_size += calc_dir_entry_size(strlen(name), 0);
176
- block = qemu_ram_alloc_from_fd(size, mr, ram_flags, fd, readonly, errp);
58
177
+ block = qemu_ram_alloc_from_fd(size, mr, ram_flags, fd, 0, readonly, errp);
59
- if (s->nb_bitmaps >= QCOW2_MAX_BITMAPS) {
178
if (!block) {
60
+ if (nb_bitmaps > QCOW2_MAX_BITMAPS) {
179
if (created) {
61
error_setg(errp,
180
unlink(mem_path);
62
"Maximum number of persistent bitmaps is already reached");
181
diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c
63
goto fail;
182
index XXXXXXX..XXXXXXX 100644
183
--- a/util/mmap-alloc.c
184
+++ b/util/mmap-alloc.c
185
@@ -XXX,XX +XXX,XX @@ void *qemu_ram_mmap(int fd,
186
size_t align,
187
bool readonly,
188
bool shared,
189
- bool is_pmem)
190
+ bool is_pmem,
191
+ off_t map_offset)
192
{
193
int prot;
194
int flags;
195
@@ -XXX,XX +XXX,XX @@ void *qemu_ram_mmap(int fd,
196
197
prot = PROT_READ | (readonly ? 0 : PROT_WRITE);
198
199
- ptr = mmap(guardptr + offset, size, prot, flags | map_sync_flags, fd, 0);
200
+ ptr = mmap(guardptr + offset, size, prot,
201
+ flags | map_sync_flags, fd, map_offset);
202
203
if (ptr == MAP_FAILED && map_sync_flags) {
204
if (errno == ENOTSUP) {
205
@@ -XXX,XX +XXX,XX @@ void *qemu_ram_mmap(int fd,
206
* if map failed with MAP_SHARED_VALIDATE | MAP_SYNC,
207
* we will remove these flags to handle compatibility.
208
*/
209
- ptr = mmap(guardptr + offset, size, prot, flags, fd, 0);
210
+ ptr = mmap(guardptr + offset, size, prot, flags, fd, map_offset);
64
}
211
}
65
212
66
- if (s->bitmap_directory_size + calc_dir_entry_size(strlen(name), 0) >
213
if (ptr == MAP_FAILED) {
67
- QCOW2_MAX_BITMAP_DIRECTORY_SIZE)
214
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
68
- {
215
index XXXXXXX..XXXXXXX 100644
69
+ if (bitmap_directory_size > QCOW2_MAX_BITMAP_DIRECTORY_SIZE) {
216
--- a/util/oslib-posix.c
70
error_setg(errp, "Not enough space in the bitmap directory");
217
+++ b/util/oslib-posix.c
71
goto fail;
218
@@ -XXX,XX +XXX,XX @@ void *qemu_memalign(size_t alignment, size_t size)
72
}
219
void *qemu_anon_ram_alloc(size_t size, uint64_t *alignment, bool shared)
73
220
{
74
- qemu_co_mutex_lock(&s->lock);
221
size_t align = QEMU_VMALLOC_ALIGN;
75
- bm_list = bitmap_list_load(bs, s->bitmap_directory_offset,
222
- void *ptr = qemu_ram_mmap(-1, size, align, false, shared, false);
76
- s->bitmap_directory_size, errp);
223
+ void *ptr = qemu_ram_mmap(-1, size, align, false, shared, false, 0);
77
- qemu_co_mutex_unlock(&s->lock);
224
78
- if (bm_list == NULL) {
225
if (ptr == MAP_FAILED) {
79
- goto fail;
226
return NULL;
80
- }
81
-
82
- found = find_bitmap_by_name(bm_list, name);
83
- bitmap_list_free(bm_list);
84
- if (found) {
85
- error_setg(errp, "Bitmap with the same name is already stored");
86
- goto fail;
87
- }
88
-
89
return true;
90
91
fail:
92
--
227
--
93
2.24.1
228
2.29.2
94
229
95
diff view generated by jsdifflib
1
The only difference is that the json:{} filename of the image looks
1
From: Jagannathan Raman <jag.raman@oracle.com>
2
different. We actually do not care about that filename in this test, we
3
are only interested in (1) that there is a json:{} filename, and (2)
4
whether the backing filename can be constructed.
5
2
6
So just filter out the json:{} data, thus making this test pass both
3
Add configuration options to enable or disable multiprocess QEMU code
7
with and without data_file.
8
4
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
5
Signed-off-by: John G Johnson <john.g.johnson@oracle.com>
10
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
6
Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
11
Message-id: 20191107163708.833192-19-mreitz@redhat.com
7
Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Message-id: 6cc37253e35418ebd7b675a31a3df6e3c7a12dc1.1611938319.git.jag.raman@oracle.com
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
---
11
---
14
tests/qemu-iotests/110 | 7 +++++--
12
configure | 10 ++++++++++
15
tests/qemu-iotests/110.out | 4 ++--
13
meson.build | 4 +++-
16
2 files changed, 7 insertions(+), 4 deletions(-)
14
Kconfig.host | 4 ++++
15
hw/Kconfig | 1 +
16
hw/remote/Kconfig | 3 +++
17
5 files changed, 21 insertions(+), 1 deletion(-)
18
create mode 100644 hw/remote/Kconfig
17
19
18
diff --git a/tests/qemu-iotests/110 b/tests/qemu-iotests/110
20
diff --git a/configure b/configure
19
index XXXXXXX..XXXXXXX 100755
21
index XXXXXXX..XXXXXXX 100755
20
--- a/tests/qemu-iotests/110
22
--- a/configure
21
+++ b/tests/qemu-iotests/110
23
+++ b/configure
22
@@ -XXX,XX +XXX,XX @@ echo
24
@@ -XXX,XX +XXX,XX @@ skip_meson=no
23
# Across blkdebug without a config file, you cannot reconstruct filenames, so
25
gettext="auto"
24
# qemu is incapable of knowing the directory of the top image from the filename
26
fuse="auto"
25
# alone. However, using bdrv_dirname(), it should still work.
27
fuse_lseek="auto"
26
+# (Filter out the json:{} filename so this test works with external data files)
28
+multiprocess="no"
27
TEST_IMG="json:{
29
28
'driver': '$IMGFMT',
30
malloc_trim="auto"
29
'file': {
31
30
@@ -XXX,XX +XXX,XX @@ TEST_IMG="json:{
32
@@ -XXX,XX +XXX,XX @@ Linux)
31
}
33
linux="yes"
32
]
34
linux_user="yes"
33
}
35
vhost_user=${default_feature:-yes}
34
-}" _img_info | _filter_img_info | grep -v 'backing file format'
36
+ multiprocess=${default_feature:-yes}
35
+}" _img_info | _filter_img_info | grep -v 'backing file format' \
37
;;
36
+ | _filter_json_filename
38
esac
37
39
38
echo
40
@@ -XXX,XX +XXX,XX @@ for opt do
39
echo '=== Backing name is always relative to the backed image ==='
41
;;
40
@@ -XXX,XX +XXX,XX @@ TEST_IMG="json:{
42
--disable-fuse-lseek) fuse_lseek="disabled"
41
}
43
;;
42
]
44
+ --enable-multiprocess) multiprocess="yes"
43
}
45
+ ;;
44
-}" _img_info | _filter_img_info | grep -v 'backing file format'
46
+ --disable-multiprocess) multiprocess="no"
45
+}" _img_info | _filter_img_info | grep -v 'backing file format' \
47
+ ;;
46
+ | _filter_json_filename
48
*)
47
49
echo "ERROR: unknown option $opt"
48
50
echo "Try '$0 --help' for more information"
49
# success, all done
51
@@ -XXX,XX +XXX,XX @@ disabled with --disable-FEATURE, default is enabled if available
50
diff --git a/tests/qemu-iotests/110.out b/tests/qemu-iotests/110.out
52
libdaxctl libdaxctl support
53
fuse FUSE block device export
54
fuse-lseek SEEK_HOLE/SEEK_DATA support for FUSE exports
55
+ multiprocess Multiprocess QEMU support
56
57
NOTE: The object files are built at the place where configure is launched
58
EOF
59
@@ -XXX,XX +XXX,XX @@ fi
60
if test "$have_mlockall" = "yes" ; then
61
echo "HAVE_MLOCKALL=y" >> $config_host_mak
62
fi
63
+if test "$multiprocess" = "yes" ; then
64
+ echo "CONFIG_MULTIPROCESS_ALLOWED=y" >> $config_host_mak
65
+fi
66
if test "$fuzzing" = "yes" ; then
67
# If LIB_FUZZING_ENGINE is set, assume we are running on OSS-Fuzz, and the
68
# needed CFLAGS have already been provided
69
diff --git a/meson.build b/meson.build
51
index XXXXXXX..XXXXXXX 100644
70
index XXXXXXX..XXXXXXX 100644
52
--- a/tests/qemu-iotests/110.out
71
--- a/meson.build
53
+++ b/tests/qemu-iotests/110.out
72
+++ b/meson.build
54
@@ -XXX,XX +XXX,XX @@ backing file: t.IMGFMT.base (actual path: TEST_DIR/t.IMGFMT.base)
73
@@ -XXX,XX +XXX,XX @@ host_kconfig = \
55
74
('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
56
=== Non-reconstructable filename ===
75
(have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
57
76
('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
58
-image: json:{"driver": "IMGFMT", "file": {"set-state.0.event": "read_aio", "image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug", "set-state.0.new_state": 42}}
77
- ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : [])
59
+image: json:{ /* filtered */ }
78
+ ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : []) + \
60
file format: IMGFMT
79
+ ('CONFIG_MULTIPROCESS_ALLOWED' in config_host ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : [])
61
virtual size: 64 MiB (67108864 bytes)
80
62
backing file: t.IMGFMT.base (actual path: TEST_DIR/t.IMGFMT.base)
81
ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
63
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=t.IMGFMT.b
82
64
83
@@ -XXX,XX +XXX,XX @@ summary_info += {'libpmem support': config_host.has_key('CONFIG_LIBPMEM')}
65
=== Nodes without a common directory ===
84
summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
66
85
summary_info += {'libudev': libudev.found()}
67
-image: json:{"driver": "IMGFMT", "file": {"children": [{"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, {"driver": "file", "filename": "TEST_DIR/t.IMGFMT.copy"}], "driver": "quorum", "vote-threshold": 1}}
86
summary_info += {'FUSE lseek': fuse_lseek.found()}
68
+image: json:{ /* filtered */ }
87
+summary_info += {'Multiprocess QEMU': config_host.has_key('CONFIG_MULTIPROCESS_ALLOWED')}
69
file format: IMGFMT
88
summary(summary_info, bool_yn: true, section: 'Dependencies')
70
virtual size: 64 MiB (67108864 bytes)
89
71
backing file: t.IMGFMT.base (cannot determine actual path)
90
if not supported_cpus.contains(cpu)
91
diff --git a/Kconfig.host b/Kconfig.host
92
index XXXXXXX..XXXXXXX 100644
93
--- a/Kconfig.host
94
+++ b/Kconfig.host
95
@@ -XXX,XX +XXX,XX @@ config VIRTFS
96
97
config PVRDMA
98
bool
99
+
100
+config MULTIPROCESS_ALLOWED
101
+ bool
102
+ imply MULTIPROCESS
103
diff --git a/hw/Kconfig b/hw/Kconfig
104
index XXXXXXX..XXXXXXX 100644
105
--- a/hw/Kconfig
106
+++ b/hw/Kconfig
107
@@ -XXX,XX +XXX,XX @@ source pci-host/Kconfig
108
source pcmcia/Kconfig
109
source pci/Kconfig
110
source rdma/Kconfig
111
+source remote/Kconfig
112
source rtc/Kconfig
113
source scsi/Kconfig
114
source sd/Kconfig
115
diff --git a/hw/remote/Kconfig b/hw/remote/Kconfig
116
new file mode 100644
117
index XXXXXXX..XXXXXXX
118
--- /dev/null
119
+++ b/hw/remote/Kconfig
120
@@ -XXX,XX +XXX,XX @@
121
+config MULTIPROCESS
122
+ bool
123
+ depends on PCI && KVM
72
--
124
--
73
2.24.1
125
2.29.2
74
126
75
diff view generated by jsdifflib
1
The image end offset as reported by qemu-img check is different when
1
From: Jagannathan Raman <jag.raman@oracle.com>
2
using an external data file; we do not care about its value here, so we
3
can just filter it. Incidentally, common.rc already has _check_test_img
4
for us which does exactly that.
5
2
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
3
PCI host bridge is setup for the remote device process. It is
7
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
4
implemented using remote-pcihost object. It is an extension of the PCI
8
Message-id: 20191107163708.833192-18-mreitz@redhat.com
5
host bridge setup by QEMU.
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
Remote-pcihost configures a PCI bus which could be used by the remote
7
PCI device to latch on to.
8
9
Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
10
Signed-off-by: John G Johnson <john.g.johnson@oracle.com>
11
Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
12
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
13
Message-id: 0871ba857abb2eafacde07e7fe66a3f12415bfb2.1611938319.git.jag.raman@oracle.com
14
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
10
---
15
---
11
tests/qemu-iotests/091 | 2 +-
16
MAINTAINERS | 2 +
12
tests/qemu-iotests/091.out | 2 --
17
include/hw/pci-host/remote.h | 29 ++++++++++++++
13
2 files changed, 1 insertion(+), 3 deletions(-)
18
hw/pci-host/remote.c | 75 ++++++++++++++++++++++++++++++++++++
19
hw/pci-host/Kconfig | 3 ++
20
hw/pci-host/meson.build | 1 +
21
hw/remote/Kconfig | 1 +
22
6 files changed, 111 insertions(+)
23
create mode 100644 include/hw/pci-host/remote.h
24
create mode 100644 hw/pci-host/remote.c
14
25
15
diff --git a/tests/qemu-iotests/091 b/tests/qemu-iotests/091
26
diff --git a/MAINTAINERS b/MAINTAINERS
16
index XXXXXXX..XXXXXXX 100755
17
--- a/tests/qemu-iotests/091
18
+++ b/tests/qemu-iotests/091
19
@@ -XXX,XX +XXX,XX @@ echo "Check image pattern"
20
${QEMU_IO} -c "read -P 0x22 0 4M" "${TEST_IMG}" | _filter_testdir | _filter_qemu_io
21
22
echo "Running 'qemu-img check -r all \$TEST_IMG'"
23
-"${QEMU_IMG}" check -r all "${TEST_IMG}" 2>&1 | _filter_testdir | _filter_qemu
24
+_check_test_img -r all
25
26
echo "*** done"
27
rm -f $seq.full
28
diff --git a/tests/qemu-iotests/091.out b/tests/qemu-iotests/091.out
29
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
30
--- a/tests/qemu-iotests/091.out
28
--- a/MAINTAINERS
31
+++ b/tests/qemu-iotests/091.out
29
+++ b/MAINTAINERS
32
@@ -XXX,XX +XXX,XX @@ read 4194304/4194304 bytes at offset 0
30
@@ -XXX,XX +XXX,XX @@ M: John G Johnson <john.g.johnson@oracle.com>
33
4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
31
S: Maintained
34
Running 'qemu-img check -r all $TEST_IMG'
32
F: docs/devel/multi-process.rst
35
No errors were found on the image.
33
F: docs/system/multi-process.rst
36
-80/16384 = 0.49% allocated, 0.00% fragmented, 0.00% compressed clusters
34
+F: hw/pci-host/remote.c
37
-Image end offset: 5570560
35
+F: include/hw/pci-host/remote.h
38
*** done
36
37
Build and test automation
38
-------------------------
39
diff --git a/include/hw/pci-host/remote.h b/include/hw/pci-host/remote.h
40
new file mode 100644
41
index XXXXXXX..XXXXXXX
42
--- /dev/null
43
+++ b/include/hw/pci-host/remote.h
44
@@ -XXX,XX +XXX,XX @@
45
+/*
46
+ * PCI Host for remote device
47
+ *
48
+ * Copyright © 2018, 2021 Oracle and/or its affiliates.
49
+ *
50
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
51
+ * See the COPYING file in the top-level directory.
52
+ *
53
+ */
54
+
55
+#ifndef REMOTE_PCIHOST_H
56
+#define REMOTE_PCIHOST_H
57
+
58
+#include "exec/memory.h"
59
+#include "hw/pci/pcie_host.h"
60
+
61
+#define TYPE_REMOTE_PCIHOST "remote-pcihost"
62
+OBJECT_DECLARE_SIMPLE_TYPE(RemotePCIHost, REMOTE_PCIHOST)
63
+
64
+struct RemotePCIHost {
65
+ /*< private >*/
66
+ PCIExpressHost parent_obj;
67
+ /*< public >*/
68
+
69
+ MemoryRegion *mr_pci_mem;
70
+ MemoryRegion *mr_sys_io;
71
+};
72
+
73
+#endif
74
diff --git a/hw/pci-host/remote.c b/hw/pci-host/remote.c
75
new file mode 100644
76
index XXXXXXX..XXXXXXX
77
--- /dev/null
78
+++ b/hw/pci-host/remote.c
79
@@ -XXX,XX +XXX,XX @@
80
+/*
81
+ * Remote PCI host device
82
+ *
83
+ * Unlike PCI host devices that model physical hardware, the purpose
84
+ * of this PCI host is to host multi-process QEMU devices.
85
+ *
86
+ * Multi-process QEMU extends the PCI host of a QEMU machine into a
87
+ * remote process. Any PCI device attached to the remote process is
88
+ * visible in the QEMU guest. This allows existing QEMU device models
89
+ * to be reused in the remote process.
90
+ *
91
+ * This PCI host is purely a container for PCI devices. It's fake in the
92
+ * sense that the guest never sees this PCI host and has no way of
93
+ * accessing it. Its job is just to provide the environment that QEMU
94
+ * PCI device models need when running in a remote process.
95
+ *
96
+ * Copyright © 2018, 2021 Oracle and/or its affiliates.
97
+ *
98
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
99
+ * See the COPYING file in the top-level directory.
100
+ *
101
+ */
102
+
103
+#include "qemu/osdep.h"
104
+#include "qemu-common.h"
105
+
106
+#include "hw/pci/pci.h"
107
+#include "hw/pci/pci_host.h"
108
+#include "hw/pci/pcie_host.h"
109
+#include "hw/qdev-properties.h"
110
+#include "hw/pci-host/remote.h"
111
+#include "exec/memory.h"
112
+
113
+static const char *remote_pcihost_root_bus_path(PCIHostState *host_bridge,
114
+ PCIBus *rootbus)
115
+{
116
+ return "0000:00";
117
+}
118
+
119
+static void remote_pcihost_realize(DeviceState *dev, Error **errp)
120
+{
121
+ PCIHostState *pci = PCI_HOST_BRIDGE(dev);
122
+ RemotePCIHost *s = REMOTE_PCIHOST(dev);
123
+
124
+ pci->bus = pci_root_bus_new(DEVICE(s), "remote-pci",
125
+ s->mr_pci_mem, s->mr_sys_io,
126
+ 0, TYPE_PCIE_BUS);
127
+}
128
+
129
+static void remote_pcihost_class_init(ObjectClass *klass, void *data)
130
+{
131
+ DeviceClass *dc = DEVICE_CLASS(klass);
132
+ PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass);
133
+
134
+ hc->root_bus_path = remote_pcihost_root_bus_path;
135
+ dc->realize = remote_pcihost_realize;
136
+
137
+ dc->user_creatable = false;
138
+ set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
139
+ dc->fw_name = "pci";
140
+}
141
+
142
+static const TypeInfo remote_pcihost_info = {
143
+ .name = TYPE_REMOTE_PCIHOST,
144
+ .parent = TYPE_PCIE_HOST_BRIDGE,
145
+ .instance_size = sizeof(RemotePCIHost),
146
+ .class_init = remote_pcihost_class_init,
147
+};
148
+
149
+static void remote_pcihost_register(void)
150
+{
151
+ type_register_static(&remote_pcihost_info);
152
+}
153
+
154
+type_init(remote_pcihost_register)
155
diff --git a/hw/pci-host/Kconfig b/hw/pci-host/Kconfig
156
index XXXXXXX..XXXXXXX 100644
157
--- a/hw/pci-host/Kconfig
158
+++ b/hw/pci-host/Kconfig
159
@@ -XXX,XX +XXX,XX @@ config PCI_POWERNV
160
select PCI_EXPRESS
161
select MSI_NONBROKEN
162
select PCIE_PORT
163
+
164
+config REMOTE_PCIHOST
165
+ bool
166
diff --git a/hw/pci-host/meson.build b/hw/pci-host/meson.build
167
index XXXXXXX..XXXXXXX 100644
168
--- a/hw/pci-host/meson.build
169
+++ b/hw/pci-host/meson.build
170
@@ -XXX,XX +XXX,XX @@ pci_ss.add(when: 'CONFIG_PCI_EXPRESS_XILINX', if_true: files('xilinx-pcie.c'))
171
pci_ss.add(when: 'CONFIG_PCI_I440FX', if_true: files('i440fx.c'))
172
pci_ss.add(when: 'CONFIG_PCI_SABRE', if_true: files('sabre.c'))
173
pci_ss.add(when: 'CONFIG_XEN_IGD_PASSTHROUGH', if_true: files('xen_igd_pt.c'))
174
+pci_ss.add(when: 'CONFIG_REMOTE_PCIHOST', if_true: files('remote.c'))
175
176
# PPC devices
177
pci_ss.add(when: 'CONFIG_PREP_PCI', if_true: files('prep.c'))
178
diff --git a/hw/remote/Kconfig b/hw/remote/Kconfig
179
index XXXXXXX..XXXXXXX 100644
180
--- a/hw/remote/Kconfig
181
+++ b/hw/remote/Kconfig
182
@@ -XXX,XX +XXX,XX @@
183
config MULTIPROCESS
184
bool
185
depends on PCI && KVM
186
+ select REMOTE_PCIHOST
39
--
187
--
40
2.24.1
188
2.29.2
41
189
42
diff view generated by jsdifflib
1
Just rm will not delete external data files. Use _rm_test_img every
1
From: Jagannathan Raman <jag.raman@oracle.com>
2
time we delete a test image.
3
2
4
(In the process, clean up the indentation of every _cleanup() this patch
3
x-remote-machine object sets up various subsystems of the remote
5
touches.)
4
device process. Instantiate PCI host bridge object and initialize RAM, IO &
5
PCI memory regions.
6
6
7
((Also, use quotes consistently. I am happy to see unquoted instances
7
Signed-off-by: John G Johnson <john.g.johnson@oracle.com>
8
like "rm -rf $TEST_DIR/..." go.))
8
Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
9
Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
10
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
11
Message-id: c537f38d17f90453ca610c6b70cf3480274e0ba1.1611938319.git.jag.raman@oracle.com
12
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
---
14
MAINTAINERS | 2 ++
15
include/hw/pci-host/remote.h | 1 +
16
include/hw/remote/machine.h | 27 ++++++++++++++
17
hw/remote/machine.c | 70 ++++++++++++++++++++++++++++++++++++
18
hw/meson.build | 1 +
19
hw/remote/meson.build | 5 +++
20
6 files changed, 106 insertions(+)
21
create mode 100644 include/hw/remote/machine.h
22
create mode 100644 hw/remote/machine.c
23
create mode 100644 hw/remote/meson.build
9
24
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
25
diff --git a/MAINTAINERS b/MAINTAINERS
11
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
26
index XXXXXXX..XXXXXXX 100644
12
Message-id: 20191107163708.833192-16-mreitz@redhat.com
27
--- a/MAINTAINERS
13
Signed-off-by: Max Reitz <mreitz@redhat.com>
28
+++ b/MAINTAINERS
14
---
29
@@ -XXX,XX +XXX,XX @@ F: docs/devel/multi-process.rst
15
tests/qemu-iotests/019 | 6 +++---
30
F: docs/system/multi-process.rst
16
tests/qemu-iotests/020 | 6 +++---
31
F: hw/pci-host/remote.c
17
tests/qemu-iotests/024 | 10 +++++-----
32
F: include/hw/pci-host/remote.h
18
tests/qemu-iotests/028 | 2 +-
33
+F: hw/remote/machine.c
19
tests/qemu-iotests/029 | 2 +-
34
+F: include/hw/remote/machine.h
20
tests/qemu-iotests/043 | 4 +++-
35
21
tests/qemu-iotests/048 | 2 +-
36
Build and test automation
22
tests/qemu-iotests/050 | 4 ++--
37
-------------------------
23
tests/qemu-iotests/053 | 4 ++--
38
diff --git a/include/hw/pci-host/remote.h b/include/hw/pci-host/remote.h
24
tests/qemu-iotests/058 | 2 +-
39
index XXXXXXX..XXXXXXX 100644
25
tests/qemu-iotests/059 | 2 +-
40
--- a/include/hw/pci-host/remote.h
26
tests/qemu-iotests/061 | 2 +-
41
+++ b/include/hw/pci-host/remote.h
27
tests/qemu-iotests/063 | 6 ++++--
42
@@ -XXX,XX +XXX,XX @@ struct RemotePCIHost {
28
tests/qemu-iotests/069 | 2 +-
43
29
tests/qemu-iotests/074 | 2 +-
44
MemoryRegion *mr_pci_mem;
30
tests/qemu-iotests/080 | 2 +-
45
MemoryRegion *mr_sys_io;
31
tests/qemu-iotests/081 | 6 +++---
46
+ MemoryRegion *mr_sys_mem;
32
tests/qemu-iotests/085 | 9 ++++++---
47
};
33
tests/qemu-iotests/088 | 2 +-
48
34
tests/qemu-iotests/092 | 2 +-
49
#endif
35
tests/qemu-iotests/094 | 2 +-
50
diff --git a/include/hw/remote/machine.h b/include/hw/remote/machine.h
36
tests/qemu-iotests/095 | 5 +++--
51
new file mode 100644
37
tests/qemu-iotests/099 | 7 ++++---
52
index XXXXXXX..XXXXXXX
38
tests/qemu-iotests/109 | 4 ++--
53
--- /dev/null
39
tests/qemu-iotests/110 | 4 ++--
54
+++ b/include/hw/remote/machine.h
40
tests/qemu-iotests/122 | 6 ++++--
55
@@ -XXX,XX +XXX,XX @@
41
tests/qemu-iotests/123 | 2 +-
56
+/*
42
tests/qemu-iotests/141 | 4 +++-
57
+ * Remote machine configuration
43
tests/qemu-iotests/142 | 2 +-
58
+ *
44
tests/qemu-iotests/144 | 4 +++-
59
+ * Copyright © 2018, 2021 Oracle and/or its affiliates.
45
tests/qemu-iotests/153 | 10 +++-------
60
+ *
46
tests/qemu-iotests/156 | 8 ++++++--
61
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
47
tests/qemu-iotests/159 | 2 +-
62
+ * See the COPYING file in the top-level directory.
48
tests/qemu-iotests/160 | 3 ++-
63
+ *
49
tests/qemu-iotests/161 | 4 ++--
64
+ */
50
tests/qemu-iotests/170 | 2 +-
65
+
51
tests/qemu-iotests/172 | 6 +++---
66
+#ifndef REMOTE_MACHINE_H
52
tests/qemu-iotests/173 | 3 ++-
67
+#define REMOTE_MACHINE_H
53
tests/qemu-iotests/178 | 2 +-
68
+
54
tests/qemu-iotests/182 | 2 +-
69
+#include "qom/object.h"
55
tests/qemu-iotests/183 | 2 +-
70
+#include "hw/boards.h"
56
tests/qemu-iotests/185 | 4 ++--
71
+#include "hw/pci-host/remote.h"
57
tests/qemu-iotests/187 | 6 +++---
72
+
58
tests/qemu-iotests/190 | 2 +-
73
+struct RemoteMachineState {
59
tests/qemu-iotests/191 | 6 +++---
74
+ MachineState parent_obj;
60
tests/qemu-iotests/195 | 2 +-
75
+
61
tests/qemu-iotests/197 | 2 +-
76
+ RemotePCIHost *host;
62
tests/qemu-iotests/200 | 3 ++-
77
+};
63
tests/qemu-iotests/215 | 2 +-
78
+
64
tests/qemu-iotests/225 | 2 +-
79
+#define TYPE_REMOTE_MACHINE "x-remote-machine"
65
tests/qemu-iotests/229 | 3 ++-
80
+OBJECT_DECLARE_SIMPLE_TYPE(RemoteMachineState, REMOTE_MACHINE)
66
tests/qemu-iotests/232 | 4 +++-
81
+
67
tests/qemu-iotests/243 | 2 +-
82
+#endif
68
tests/qemu-iotests/244 | 4 ++--
83
diff --git a/hw/remote/machine.c b/hw/remote/machine.c
69
tests/qemu-iotests/247 | 4 +++-
84
new file mode 100644
70
tests/qemu-iotests/249 | 4 ++--
85
index XXXXXXX..XXXXXXX
71
tests/qemu-iotests/252 | 2 +-
86
--- /dev/null
72
57 files changed, 118 insertions(+), 95 deletions(-)
87
+++ b/hw/remote/machine.c
88
@@ -XXX,XX +XXX,XX @@
89
+/*
90
+ * Machine for remote device
91
+ *
92
+ * This machine type is used by the remote device process in multi-process
93
+ * QEMU. QEMU device models depend on parent busses, interrupt controllers,
94
+ * memory regions, etc. The remote machine type offers this environment so
95
+ * that QEMU device models can be used as remote devices.
96
+ *
97
+ * Copyright © 2018, 2021 Oracle and/or its affiliates.
98
+ *
99
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
100
+ * See the COPYING file in the top-level directory.
101
+ *
102
+ */
103
+
104
+#include "qemu/osdep.h"
105
+#include "qemu-common.h"
106
+
107
+#include "hw/remote/machine.h"
108
+#include "exec/address-spaces.h"
109
+#include "exec/memory.h"
110
+#include "qapi/error.h"
111
+
112
+static void remote_machine_init(MachineState *machine)
113
+{
114
+ MemoryRegion *system_memory, *system_io, *pci_memory;
115
+ RemoteMachineState *s = REMOTE_MACHINE(machine);
116
+ RemotePCIHost *rem_host;
117
+
118
+ system_memory = get_system_memory();
119
+ system_io = get_system_io();
120
+
121
+ pci_memory = g_new(MemoryRegion, 1);
122
+ memory_region_init(pci_memory, NULL, "pci", UINT64_MAX);
123
+
124
+ rem_host = REMOTE_PCIHOST(qdev_new(TYPE_REMOTE_PCIHOST));
125
+
126
+ rem_host->mr_pci_mem = pci_memory;
127
+ rem_host->mr_sys_mem = system_memory;
128
+ rem_host->mr_sys_io = system_io;
129
+
130
+ s->host = rem_host;
131
+
132
+ object_property_add_child(OBJECT(s), "remote-pcihost", OBJECT(rem_host));
133
+ memory_region_add_subregion_overlap(system_memory, 0x0, pci_memory, -1);
134
+
135
+ qdev_realize(DEVICE(rem_host), sysbus_get_default(), &error_fatal);
136
+}
137
+
138
+static void remote_machine_class_init(ObjectClass *oc, void *data)
139
+{
140
+ MachineClass *mc = MACHINE_CLASS(oc);
141
+
142
+ mc->init = remote_machine_init;
143
+ mc->desc = "Experimental remote machine";
144
+}
145
+
146
+static const TypeInfo remote_machine = {
147
+ .name = TYPE_REMOTE_MACHINE,
148
+ .parent = TYPE_MACHINE,
149
+ .instance_size = sizeof(RemoteMachineState),
150
+ .class_init = remote_machine_class_init,
151
+};
152
+
153
+static void remote_machine_register_types(void)
154
+{
155
+ type_register_static(&remote_machine);
156
+}
157
+
158
+type_init(remote_machine_register_types);
159
diff --git a/hw/meson.build b/hw/meson.build
160
index XXXXXXX..XXXXXXX 100644
161
--- a/hw/meson.build
162
+++ b/hw/meson.build
163
@@ -XXX,XX +XXX,XX @@ subdir('moxie')
164
subdir('nios2')
165
subdir('openrisc')
166
subdir('ppc')
167
+subdir('remote')
168
subdir('riscv')
169
subdir('rx')
170
subdir('s390x')
171
diff --git a/hw/remote/meson.build b/hw/remote/meson.build
172
new file mode 100644
173
index XXXXXXX..XXXXXXX
174
--- /dev/null
175
+++ b/hw/remote/meson.build
176
@@ -XXX,XX +XXX,XX @@
177
+remote_ss = ss.source_set()
178
+
179
+remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('machine.c'))
180
+
181
+softmmu_ss.add_all(when: 'CONFIG_MULTIPROCESS', if_true: remote_ss)
182
--
183
2.29.2
73
184
74
diff --git a/tests/qemu-iotests/019 b/tests/qemu-iotests/019
75
index XXXXXXX..XXXXXXX 100755
76
--- a/tests/qemu-iotests/019
77
+++ b/tests/qemu-iotests/019
78
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
79
80
_cleanup()
81
{
82
-    _cleanup_test_img
83
- rm -f "$TEST_IMG.base"
84
- rm -f "$TEST_IMG.orig"
85
+ _cleanup_test_img
86
+ _rm_test_img "$TEST_IMG.base"
87
+ _rm_test_img "$TEST_IMG.orig"
88
}
89
trap "_cleanup; exit \$status" 0 1 2 3 15
90
91
diff --git a/tests/qemu-iotests/020 b/tests/qemu-iotests/020
92
index XXXXXXX..XXXXXXX 100755
93
--- a/tests/qemu-iotests/020
94
+++ b/tests/qemu-iotests/020
95
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
96
97
_cleanup()
98
{
99
-    _cleanup_test_img
100
- rm -f "$TEST_IMG.base"
101
- rm -f "$TEST_IMG.orig"
102
+ _cleanup_test_img
103
+ _rm_test_img "$TEST_IMG.base"
104
+ _rm_test_img "$TEST_IMG.orig"
105
}
106
trap "_cleanup; exit \$status" 0 1 2 3 15
107
108
diff --git a/tests/qemu-iotests/024 b/tests/qemu-iotests/024
109
index XXXXXXX..XXXXXXX 100755
110
--- a/tests/qemu-iotests/024
111
+++ b/tests/qemu-iotests/024
112
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
113
_cleanup()
114
{
115
_cleanup_test_img
116
- rm -f "$TEST_DIR/t.$IMGFMT.base_old"
117
- rm -f "$TEST_DIR/t.$IMGFMT.base_new"
118
+ _rm_test_img "$TEST_DIR/t.$IMGFMT.base_old"
119
+ _rm_test_img "$TEST_DIR/t.$IMGFMT.base_new"
120
121
- rm -f "$TEST_DIR/subdir/t.$IMGFMT"
122
- rm -f "$TEST_DIR/subdir/t.$IMGFMT.base_old"
123
- rm -f "$TEST_DIR/subdir/t.$IMGFMT.base_new"
124
+ _rm_test_img "$TEST_DIR/subdir/t.$IMGFMT"
125
+ _rm_test_img "$TEST_DIR/subdir/t.$IMGFMT.base_old"
126
+ _rm_test_img "$TEST_DIR/subdir/t.$IMGFMT.base_new"
127
rmdir "$TEST_DIR/subdir" 2> /dev/null
128
}
129
trap "_cleanup; exit \$status" 0 1 2 3 15
130
diff --git a/tests/qemu-iotests/028 b/tests/qemu-iotests/028
131
index XXXXXXX..XXXXXXX 100755
132
--- a/tests/qemu-iotests/028
133
+++ b/tests/qemu-iotests/028
134
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
135
_cleanup()
136
{
137
_cleanup_qemu
138
- rm -f "${TEST_IMG}.copy"
139
+ _rm_test_img "${TEST_IMG}.copy"
140
_cleanup_test_img
141
}
142
trap "_cleanup; exit \$status" 0 1 2 3 15
143
diff --git a/tests/qemu-iotests/029 b/tests/qemu-iotests/029
144
index XXXXXXX..XXXXXXX 100755
145
--- a/tests/qemu-iotests/029
146
+++ b/tests/qemu-iotests/029
147
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
148
149
_cleanup()
150
{
151
- rm -f $TEST_IMG.snap
152
+ _rm_test_img "$TEST_IMG.snap"
153
_cleanup_test_img
154
}
155
trap "_cleanup; exit \$status" 0 1 2 3 15
156
diff --git a/tests/qemu-iotests/043 b/tests/qemu-iotests/043
157
index XXXXXXX..XXXXXXX 100755
158
--- a/tests/qemu-iotests/043
159
+++ b/tests/qemu-iotests/043
160
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
161
_cleanup()
162
{
163
_cleanup_test_img
164
- rm -f "$TEST_IMG".[123].base
165
+ for img in "$TEST_IMG".[123].base; do
166
+ _rm_test_img "$img"
167
+ done
168
}
169
trap "_cleanup; exit \$status" 0 1 2 3 15
170
171
diff --git a/tests/qemu-iotests/048 b/tests/qemu-iotests/048
172
index XXXXXXX..XXXXXXX 100755
173
--- a/tests/qemu-iotests/048
174
+++ b/tests/qemu-iotests/048
175
@@ -XXX,XX +XXX,XX @@ _cleanup()
176
{
177
echo "Cleanup"
178
_cleanup_test_img
179
- rm "${TEST_IMG_FILE2}"
180
+ _rm_test_img "${TEST_IMG_FILE2}"
181
}
182
trap "_cleanup; exit \$status" 0 1 2 3 15
183
184
diff --git a/tests/qemu-iotests/050 b/tests/qemu-iotests/050
185
index XXXXXXX..XXXXXXX 100755
186
--- a/tests/qemu-iotests/050
187
+++ b/tests/qemu-iotests/050
188
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
189
_cleanup()
190
{
191
_cleanup_test_img
192
- rm -f "$TEST_IMG.old"
193
- rm -f "$TEST_IMG.new"
194
+ _rm_test_img "$TEST_IMG.old"
195
+ _rm_test_img "$TEST_IMG.new"
196
}
197
trap "_cleanup; exit \$status" 0 1 2 3 15
198
199
diff --git a/tests/qemu-iotests/053 b/tests/qemu-iotests/053
200
index XXXXXXX..XXXXXXX 100755
201
--- a/tests/qemu-iotests/053
202
+++ b/tests/qemu-iotests/053
203
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
204
205
_cleanup()
206
{
207
-    rm -f "$TEST_IMG.orig"
208
-    _cleanup_test_img
209
+ _rm_test_img "$TEST_IMG.orig"
210
+ _cleanup_test_img
211
}
212
trap "_cleanup; exit \$status" 0 1 2 3 15
213
214
diff --git a/tests/qemu-iotests/058 b/tests/qemu-iotests/058
215
index XXXXXXX..XXXXXXX 100755
216
--- a/tests/qemu-iotests/058
217
+++ b/tests/qemu-iotests/058
218
@@ -XXX,XX +XXX,XX @@ _cleanup()
219
{
220
nbd_server_stop
221
_cleanup_test_img
222
- rm -f "$converted_image"
223
+ _rm_test_img "$converted_image"
224
}
225
trap "_cleanup; exit \$status" 0 1 2 3 15
226
227
diff --git a/tests/qemu-iotests/059 b/tests/qemu-iotests/059
228
index XXXXXXX..XXXXXXX 100755
229
--- a/tests/qemu-iotests/059
230
+++ b/tests/qemu-iotests/059
231
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
232
_cleanup()
233
{
234
_cleanup_test_img
235
- rm -f "$TEST_IMG.qcow2"
236
+ IMGFMT=qcow2 _rm_test_img "$TEST_IMG.qcow2"
237
}
238
trap "_cleanup; exit \$status" 0 1 2 3 15
239
240
diff --git a/tests/qemu-iotests/061 b/tests/qemu-iotests/061
241
index XXXXXXX..XXXXXXX 100755
242
--- a/tests/qemu-iotests/061
243
+++ b/tests/qemu-iotests/061
244
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
245
_cleanup()
246
{
247
_cleanup_test_img
248
- rm -f $TEST_IMG.data
249
+ _rm_test_img "$TEST_IMG.data"
250
}
251
trap "_cleanup; exit \$status" 0 1 2 3 15
252
253
diff --git a/tests/qemu-iotests/063 b/tests/qemu-iotests/063
254
index XXXXXXX..XXXXXXX 100755
255
--- a/tests/qemu-iotests/063
256
+++ b/tests/qemu-iotests/063
257
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
258
259
_cleanup()
260
{
261
-    _cleanup_test_img
262
-    rm -f "$TEST_IMG.orig" "$TEST_IMG.raw1" "$TEST_IMG.raw2"
263
+ _cleanup_test_img
264
+ for img in "$TEST_IMG".{orig,raw1,raw2,target}; do
265
+ _rm_test_img "$img"
266
+ done
267
}
268
trap "_cleanup; exit \$status" 0 1 2 3 15
269
270
diff --git a/tests/qemu-iotests/069 b/tests/qemu-iotests/069
271
index XXXXXXX..XXXXXXX 100755
272
--- a/tests/qemu-iotests/069
273
+++ b/tests/qemu-iotests/069
274
@@ -XXX,XX +XXX,XX @@ echo "=== Creating an image with a backing file and deleting that file ==="
275
echo
276
TEST_IMG="$TEST_IMG.base" _make_test_img $IMG_SIZE
277
_make_test_img -b "$TEST_IMG.base" $IMG_SIZE
278
-rm -f "$TEST_IMG.base"
279
+_rm_test_img "$TEST_IMG.base"
280
# Just open the image and close it right again (this should print an error message)
281
$QEMU_IO -c quit "$TEST_IMG" 2>&1 | _filter_testdir | _filter_imgfmt
282
283
diff --git a/tests/qemu-iotests/074 b/tests/qemu-iotests/074
284
index XXXXXXX..XXXXXXX 100755
285
--- a/tests/qemu-iotests/074
286
+++ b/tests/qemu-iotests/074
287
@@ -XXX,XX +XXX,XX @@ _cleanup()
288
{
289
echo "Cleanup"
290
_cleanup_test_img
291
- rm "${TEST_IMG2}"
292
+ _rm_test_img "${TEST_IMG2}"
293
rm -f "$TEST_DIR/blkdebug.conf"
294
}
295
trap "_cleanup; exit \$status" 0 1 2 3 15
296
diff --git a/tests/qemu-iotests/080 b/tests/qemu-iotests/080
297
index XXXXXXX..XXXXXXX 100755
298
--- a/tests/qemu-iotests/080
299
+++ b/tests/qemu-iotests/080
300
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
301
302
_cleanup()
303
{
304
- rm -f $TEST_IMG.snap
305
+ _rm_test_img "$TEST_IMG.snap"
306
_cleanup_test_img
307
}
308
trap "_cleanup; exit \$status" 0 1 2 3 15
309
diff --git a/tests/qemu-iotests/081 b/tests/qemu-iotests/081
310
index XXXXXXX..XXXXXXX 100755
311
--- a/tests/qemu-iotests/081
312
+++ b/tests/qemu-iotests/081
313
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
314
315
_cleanup()
316
{
317
- rm -rf $TEST_DIR/1.raw
318
- rm -rf $TEST_DIR/2.raw
319
- rm -rf $TEST_DIR/3.raw
320
+ _rm_test_img "$TEST_DIR/1.raw"
321
+ _rm_test_img "$TEST_DIR/2.raw"
322
+ _rm_test_img "$TEST_DIR/3.raw"
323
}
324
trap "_cleanup; exit \$status" 0 1 2 3 15
325
326
diff --git a/tests/qemu-iotests/085 b/tests/qemu-iotests/085
327
index XXXXXXX..XXXXXXX 100755
328
--- a/tests/qemu-iotests/085
329
+++ b/tests/qemu-iotests/085
330
@@ -XXX,XX +XXX,XX @@ _cleanup()
331
_cleanup_qemu
332
for i in $(seq 1 ${SNAPSHOTS})
333
do
334
- rm -f "${TEST_DIR}/${i}-${snapshot_virt0}"
335
- rm -f "${TEST_DIR}/${i}-${snapshot_virt1}"
336
+ _rm_test_img "${TEST_DIR}/${i}-${snapshot_virt0}"
337
+ _rm_test_img "${TEST_DIR}/${i}-${snapshot_virt1}"
338
+ done
339
+ for img in "${TEST_IMG}".{1,2,base}
340
+ do
341
+ _rm_test_img "$img"
342
done
343
- rm -f "${TEST_IMG}" "${TEST_IMG}.1" "${TEST_IMG}.2" "${TEST_IMG}.base"
344
345
}
346
trap "_cleanup; exit \$status" 0 1 2 3 15
347
diff --git a/tests/qemu-iotests/088 b/tests/qemu-iotests/088
348
index XXXXXXX..XXXXXXX 100755
349
--- a/tests/qemu-iotests/088
350
+++ b/tests/qemu-iotests/088
351
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
352
353
_cleanup()
354
{
355
- rm -f $TEST_IMG.snap
356
+ _rm_test_img "$TEST_IMG.snap"
357
_cleanup_test_img
358
}
359
trap "_cleanup; exit \$status" 0 1 2 3 15
360
diff --git a/tests/qemu-iotests/092 b/tests/qemu-iotests/092
361
index XXXXXXX..XXXXXXX 100755
362
--- a/tests/qemu-iotests/092
363
+++ b/tests/qemu-iotests/092
364
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
365
366
_cleanup()
367
{
368
- rm -f $TEST_IMG.snap
369
+ _rm_test_img "$TEST_IMG.snap"
370
_cleanup_test_img
371
}
372
trap "_cleanup; exit \$status" 0 1 2 3 15
373
diff --git a/tests/qemu-iotests/094 b/tests/qemu-iotests/094
374
index XXXXXXX..XXXXXXX 100755
375
--- a/tests/qemu-iotests/094
376
+++ b/tests/qemu-iotests/094
377
@@ -XXX,XX +XXX,XX @@ _cleanup()
378
{
379
_cleanup_qemu
380
_cleanup_test_img
381
- rm -f "$TEST_DIR/source.$IMGFMT"
382
+ _rm_test_img "$TEST_DIR/source.$IMGFMT"
383
}
384
385
trap "_cleanup; exit \$status" 0 1 2 3 15
386
diff --git a/tests/qemu-iotests/095 b/tests/qemu-iotests/095
387
index XXXXXXX..XXXXXXX 100755
388
--- a/tests/qemu-iotests/095
389
+++ b/tests/qemu-iotests/095
390
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
391
_cleanup()
392
{
393
_cleanup_qemu
394
- rm -f "${TEST_IMG}.base" "${TEST_IMG}.snp1"
395
-    _cleanup_test_img
396
+ _rm_test_img "${TEST_IMG}.base"
397
+ _rm_test_img "${TEST_IMG}.snp1"
398
+ _cleanup_test_img
399
}
400
trap "_cleanup; exit \$status" 0 1 2 3 15
401
402
diff --git a/tests/qemu-iotests/099 b/tests/qemu-iotests/099
403
index XXXXXXX..XXXXXXX 100755
404
--- a/tests/qemu-iotests/099
405
+++ b/tests/qemu-iotests/099
406
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
407
408
_cleanup()
409
{
410
-    _cleanup_test_img
411
+ _cleanup_test_img
412
+ _rm_test_img "$TEST_IMG.compare"
413
+ rm -f "$TEST_DIR/blkdebug.conf"
414
+
415
}
416
trap "_cleanup; exit \$status" 0 1 2 3 15
417
418
@@ -XXX,XX +XXX,XX @@ echo
419
test_qemu "file.driver=blkdebug,file.image.filename=$TEST_IMG"
420
421
422
-rm -f "$TEST_IMG.compare" "$TEST_DIR/blkdebug.conf"
423
-
424
# success, all done
425
echo "*** done"
426
rm -f $seq.full
427
diff --git a/tests/qemu-iotests/109 b/tests/qemu-iotests/109
428
index XXXXXXX..XXXXXXX 100755
429
--- a/tests/qemu-iotests/109
430
+++ b/tests/qemu-iotests/109
431
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
432
_cleanup()
433
{
434
_cleanup_qemu
435
- rm -f $TEST_IMG.src
436
-    _cleanup_test_img
437
+ _rm_test_img "$TEST_IMG.src"
438
+ _cleanup_test_img
439
}
440
trap "_cleanup; exit \$status" 0 1 2 3 15
441
442
diff --git a/tests/qemu-iotests/110 b/tests/qemu-iotests/110
443
index XXXXXXX..XXXXXXX 100755
444
--- a/tests/qemu-iotests/110
445
+++ b/tests/qemu-iotests/110
446
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
447
448
_cleanup()
449
{
450
-    _cleanup_test_img
451
- rm -f "$TEST_IMG.copy"
452
+ _cleanup_test_img
453
+ _rm_test_img "$TEST_IMG.copy"
454
}
455
trap "_cleanup; exit \$status" 0 1 2 3 15
456
457
diff --git a/tests/qemu-iotests/122 b/tests/qemu-iotests/122
458
index XXXXXXX..XXXXXXX 100755
459
--- a/tests/qemu-iotests/122
460
+++ b/tests/qemu-iotests/122
461
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
462
463
_cleanup()
464
{
465
- rm -f "$TEST_IMG".[123]
466
-    _cleanup_test_img
467
+ for img in "$TEST_IMG".[123]; do
468
+ _rm_test_img "$img"
469
+ done
470
+ _cleanup_test_img
471
}
472
trap "_cleanup; exit \$status" 0 1 2 3 15
473
474
diff --git a/tests/qemu-iotests/123 b/tests/qemu-iotests/123
475
index XXXXXXX..XXXXXXX 100755
476
--- a/tests/qemu-iotests/123
477
+++ b/tests/qemu-iotests/123
478
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
479
_cleanup()
480
{
481
_cleanup_test_img
482
- rm -f "$SRC_IMG"
483
+ _rm_test_img "$SRC_IMG"
484
}
485
trap "_cleanup; exit \$status" 0 1 2 3 15
486
487
diff --git a/tests/qemu-iotests/141 b/tests/qemu-iotests/141
488
index XXXXXXX..XXXXXXX 100755
489
--- a/tests/qemu-iotests/141
490
+++ b/tests/qemu-iotests/141
491
@@ -XXX,XX +XXX,XX @@ _cleanup()
492
{
493
_cleanup_qemu
494
_cleanup_test_img
495
- rm -f "$TEST_DIR"/{b,m,o}.$IMGFMT
496
+ for img in "$TEST_DIR"/{b,m,o}.$IMGFMT; do
497
+ _rm_test_img "$img"
498
+ done
499
}
500
trap "_cleanup; exit \$status" 0 1 2 3 15
501
502
diff --git a/tests/qemu-iotests/142 b/tests/qemu-iotests/142
503
index XXXXXXX..XXXXXXX 100755
504
--- a/tests/qemu-iotests/142
505
+++ b/tests/qemu-iotests/142
506
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
507
_cleanup()
508
{
509
_cleanup_test_img
510
- rm -f $TEST_IMG.snap
511
+ _rm_test_img "$TEST_IMG.snap"
512
}
513
trap "_cleanup; exit \$status" 0 1 2 3 15
514
515
diff --git a/tests/qemu-iotests/144 b/tests/qemu-iotests/144
516
index XXXXXXX..XXXXXXX 100755
517
--- a/tests/qemu-iotests/144
518
+++ b/tests/qemu-iotests/144
519
@@ -XXX,XX +XXX,XX @@ TMP_SNAP2=${TEST_DIR}/tmp2.qcow2
520
_cleanup()
521
{
522
_cleanup_qemu
523
- rm -f "${TEST_IMG}" "${TMP_SNAP1}" "${TMP_SNAP2}"
524
+ for img in "${TEST_IMG}" "${TMP_SNAP1}" "${TMP_SNAP2}"; do
525
+ _rm_test_img "$img"
526
+ done
527
}
528
529
trap "_cleanup; exit \$status" 0 1 2 3 15
530
diff --git a/tests/qemu-iotests/153 b/tests/qemu-iotests/153
531
index XXXXXXX..XXXXXXX 100755
532
--- a/tests/qemu-iotests/153
533
+++ b/tests/qemu-iotests/153
534
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
535
_cleanup()
536
{
537
_cleanup_test_img
538
- rm -f "${TEST_IMG}.base"
539
- rm -f "${TEST_IMG}.overlay"
540
- rm -f "${TEST_IMG}.convert"
541
- rm -f "${TEST_IMG}.a"
542
- rm -f "${TEST_IMG}.b"
543
- rm -f "${TEST_IMG}.c"
544
- rm -f "${TEST_IMG}.lnk"
545
+ for img in "${TEST_IMG}".{base,overlay,convert,a,b,c,lnk}; do
546
+ _rm_test_img "$img"
547
+ done
548
}
549
trap "_cleanup; exit \$status" 0 1 2 3 15
550
551
diff --git a/tests/qemu-iotests/156 b/tests/qemu-iotests/156
552
index XXXXXXX..XXXXXXX 100755
553
--- a/tests/qemu-iotests/156
554
+++ b/tests/qemu-iotests/156
555
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
556
_cleanup()
557
{
558
_cleanup_qemu
559
- rm -f "$TEST_IMG"{,.target}{,.backing,.overlay}
560
+ for img in "$TEST_IMG"{,.target}{,.backing,.overlay}; do
561
+ _rm_test_img "$img"
562
+ done
563
}
564
trap "_cleanup; exit \$status" 0 1 2 3 15
565
566
@@ -XXX,XX +XXX,XX @@ _send_qemu_cmd $QEMU_HANDLE \
567
'"status": "null"'
568
569
# Remove the source images
570
-rm -f "$TEST_IMG{,.backing,.overlay}"
571
+for img in "$TEST_IMG{,.backing,.overlay}"; do
572
+ _rm_test_img "$img"
573
+done
574
575
echo
576
577
diff --git a/tests/qemu-iotests/159 b/tests/qemu-iotests/159
578
index XXXXXXX..XXXXXXX 100755
579
--- a/tests/qemu-iotests/159
580
+++ b/tests/qemu-iotests/159
581
@@ -XXX,XX +XXX,XX @@ status=1
582
_cleanup()
583
{
584
_cleanup_test_img
585
- rm -f "$TEST_IMG.out"
586
+ _rm_test_img "$TEST_IMG.out"
587
}
588
trap "_cleanup; exit \$status" 0 1 2 3 15
589
590
diff --git a/tests/qemu-iotests/160 b/tests/qemu-iotests/160
591
index XXXXXXX..XXXXXXX 100755
592
--- a/tests/qemu-iotests/160
593
+++ b/tests/qemu-iotests/160
594
@@ -XXX,XX +XXX,XX @@ status=1
595
_cleanup()
596
{
597
_cleanup_test_img
598
- rm -f "$TEST_IMG.out" "$TEST_IMG.out.dd"
599
+ _rm_test_img "$TEST_IMG.out"
600
+ _rm_test_img "$TEST_IMG.out.dd"
601
}
602
trap "_cleanup; exit \$status" 0 1 2 3 15
603
604
diff --git a/tests/qemu-iotests/161 b/tests/qemu-iotests/161
605
index XXXXXXX..XXXXXXX 100755
606
--- a/tests/qemu-iotests/161
607
+++ b/tests/qemu-iotests/161
608
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
609
_cleanup()
610
{
611
_cleanup_test_img
612
- rm -f "$TEST_IMG.base"
613
- rm -f "$TEST_IMG.int"
614
+ _rm_test_img "$TEST_IMG.base"
615
+ _rm_test_img "$TEST_IMG.int"
616
}
617
trap "_cleanup; exit \$status" 0 1 2 3 15
618
619
diff --git a/tests/qemu-iotests/170 b/tests/qemu-iotests/170
620
index XXXXXXX..XXXXXXX 100755
621
--- a/tests/qemu-iotests/170
622
+++ b/tests/qemu-iotests/170
623
@@ -XXX,XX +XXX,XX @@ status=1
624
_cleanup()
625
{
626
_cleanup_test_img
627
- rm -f "$TEST_IMG.out"
628
+ _rm_test_img "$TEST_IMG.out"
629
}
630
trap "_cleanup; exit \$status" 0 1 2 3 15
631
632
diff --git a/tests/qemu-iotests/172 b/tests/qemu-iotests/172
633
index XXXXXXX..XXXXXXX 100755
634
--- a/tests/qemu-iotests/172
635
+++ b/tests/qemu-iotests/172
636
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
637
638
_cleanup()
639
{
640
-    _cleanup_test_img
641
- rm -f "$TEST_IMG.2"
642
- rm -f "$TEST_IMG.3"
643
+ _cleanup_test_img
644
+ _rm_test_img "$TEST_IMG.2"
645
+ _rm_test_img "$TEST_IMG.3"
646
}
647
trap "_cleanup; exit \$status" 0 1 2 3 15
648
649
diff --git a/tests/qemu-iotests/173 b/tests/qemu-iotests/173
650
index XXXXXXX..XXXXXXX 100755
651
--- a/tests/qemu-iotests/173
652
+++ b/tests/qemu-iotests/173
653
@@ -XXX,XX +XXX,XX @@ status=1 # failure is the default!
654
_cleanup()
655
{
656
_cleanup_qemu
657
- rm -f "${QEMU_TEST_DIR}/image.base" "${QEMU_TEST_DIR}/image.snp1"
658
+ _rm_test_img "${TEST_DIR}/image.base"
659
+ _rm_test_img "${TEST_DIR}/image.snp1"
660
_cleanup_test_img
661
}
662
trap "_cleanup; exit \$status" 0 1 2 3 15
663
diff --git a/tests/qemu-iotests/178 b/tests/qemu-iotests/178
664
index XXXXXXX..XXXXXXX 100755
665
--- a/tests/qemu-iotests/178
666
+++ b/tests/qemu-iotests/178
667
@@ -XXX,XX +XXX,XX @@ status=1 # failure is the default!
668
_cleanup()
669
{
670
_cleanup_test_img
671
- rm -f "$TEST_IMG.converted"
672
+ _rm_test_img "$TEST_IMG.converted"
673
}
674
trap "_cleanup; exit \$status" 0 1 2 3 15
675
676
diff --git a/tests/qemu-iotests/182 b/tests/qemu-iotests/182
677
index XXXXXXX..XXXXXXX 100755
678
--- a/tests/qemu-iotests/182
679
+++ b/tests/qemu-iotests/182
680
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
681
_cleanup()
682
{
683
_cleanup_test_img
684
- rm -f "$TEST_IMG.overlay"
685
+ _rm_test_img "$TEST_IMG.overlay"
686
rm -f "$SOCK_DIR/nbd.socket"
687
}
688
trap "_cleanup; exit \$status" 0 1 2 3 15
689
diff --git a/tests/qemu-iotests/183 b/tests/qemu-iotests/183
690
index XXXXXXX..XXXXXXX 100755
691
--- a/tests/qemu-iotests/183
692
+++ b/tests/qemu-iotests/183
693
@@ -XXX,XX +XXX,XX @@ MIG_SOCKET="${SOCK_DIR}/migrate"
694
_cleanup()
695
{
696
rm -f "${MIG_SOCKET}"
697
- rm -f "${TEST_IMG}.dest"
698
+ _rm_test_img "${TEST_IMG}.dest"
699
_cleanup_test_img
700
_cleanup_qemu
701
}
702
diff --git a/tests/qemu-iotests/185 b/tests/qemu-iotests/185
703
index XXXXXXX..XXXXXXX 100755
704
--- a/tests/qemu-iotests/185
705
+++ b/tests/qemu-iotests/185
706
@@ -XXX,XX +XXX,XX @@ status=1 # failure is the default!
707
708
_cleanup()
709
{
710
- rm -f "${TEST_IMG}.mid"
711
- rm -f "${TEST_IMG}.copy"
712
+ _rm_test_img "${TEST_IMG}.mid"
713
+ _rm_test_img "${TEST_IMG}.copy"
714
_cleanup_test_img
715
_cleanup_qemu
716
}
717
diff --git a/tests/qemu-iotests/187 b/tests/qemu-iotests/187
718
index XXXXXXX..XXXXXXX 100755
719
--- a/tests/qemu-iotests/187
720
+++ b/tests/qemu-iotests/187
721
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
722
723
_cleanup()
724
{
725
-    _cleanup_test_img
726
- rm -f "$TEST_IMG.2"
727
- rm -f "$TEST_IMG.3"
728
+ _cleanup_test_img
729
+ _rm_test_img "$TEST_IMG.2"
730
+ _rm_test_img "$TEST_IMG.3"
731
}
732
trap "_cleanup; exit \$status" 0 1 2 3 15
733
734
diff --git a/tests/qemu-iotests/190 b/tests/qemu-iotests/190
735
index XXXXXXX..XXXXXXX 100755
736
--- a/tests/qemu-iotests/190
737
+++ b/tests/qemu-iotests/190
738
@@ -XXX,XX +XXX,XX @@ status=1 # failure is the default!
739
_cleanup()
740
{
741
_cleanup_test_img
742
- rm -f "$TEST_IMG.converted"
743
+ _rm_test_img "$TEST_IMG.converted"
744
}
745
trap "_cleanup; exit \$status" 0 1 2 3 15
746
747
diff --git a/tests/qemu-iotests/191 b/tests/qemu-iotests/191
748
index XXXXXXX..XXXXXXX 100755
749
--- a/tests/qemu-iotests/191
750
+++ b/tests/qemu-iotests/191
751
@@ -XXX,XX +XXX,XX @@ status=1 # failure is the default!
752
753
_cleanup()
754
{
755
- rm -f "${TEST_IMG}.mid"
756
- rm -f "${TEST_IMG}.ovl2"
757
- rm -f "${TEST_IMG}.ovl3"
758
+ _rm_test_img "${TEST_IMG}.mid"
759
+ _rm_test_img "${TEST_IMG}.ovl2"
760
+ _rm_test_img "${TEST_IMG}.ovl3"
761
_cleanup_test_img
762
_cleanup_qemu
763
}
764
diff --git a/tests/qemu-iotests/195 b/tests/qemu-iotests/195
765
index XXXXXXX..XXXXXXX 100755
766
--- a/tests/qemu-iotests/195
767
+++ b/tests/qemu-iotests/195
768
@@ -XXX,XX +XXX,XX @@ status=1 # failure is the default!
769
_cleanup()
770
{
771
_cleanup_test_img
772
- rm -f "$TEST_IMG.mid"
773
+ _rm_test_img "$TEST_IMG.mid"
774
}
775
trap "_cleanup; exit \$status" 0 1 2 3 15
776
777
diff --git a/tests/qemu-iotests/197 b/tests/qemu-iotests/197
778
index XXXXXXX..XXXXXXX 100755
779
--- a/tests/qemu-iotests/197
780
+++ b/tests/qemu-iotests/197
781
@@ -XXX,XX +XXX,XX @@ esac
782
_cleanup()
783
{
784
_cleanup_test_img
785
- rm -f "$TEST_WRAP"
786
+ _rm_test_img "$TEST_WRAP"
787
rm -f "$BLKDBG_CONF"
788
}
789
trap "_cleanup; exit \$status" 0 1 2 3 15
790
diff --git a/tests/qemu-iotests/200 b/tests/qemu-iotests/200
791
index XXXXXXX..XXXXXXX 100755
792
--- a/tests/qemu-iotests/200
793
+++ b/tests/qemu-iotests/200
794
@@ -XXX,XX +XXX,XX @@ status=1 # failure is the default!
795
_cleanup()
796
{
797
_cleanup_qemu
798
- rm -f "${TEST_IMG}" "${BACKING_IMG}"
799
+ _rm_test_img "${TEST_IMG}"
800
+ _rm_test_img "${BACKING_IMG}"
801
}
802
trap "_cleanup; exit \$status" 0 1 2 3 15
803
804
diff --git a/tests/qemu-iotests/215 b/tests/qemu-iotests/215
805
index XXXXXXX..XXXXXXX 100755
806
--- a/tests/qemu-iotests/215
807
+++ b/tests/qemu-iotests/215
808
@@ -XXX,XX +XXX,XX @@ esac
809
_cleanup()
810
{
811
_cleanup_test_img
812
- rm -f "$TEST_WRAP"
813
+ _rm_test_img "$TEST_WRAP"
814
rm -f "$BLKDBG_CONF"
815
}
816
trap "_cleanup; exit \$status" 0 1 2 3 15
817
diff --git a/tests/qemu-iotests/225 b/tests/qemu-iotests/225
818
index XXXXXXX..XXXXXXX 100755
819
--- a/tests/qemu-iotests/225
820
+++ b/tests/qemu-iotests/225
821
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
822
_cleanup()
823
{
824
_cleanup_test_img
825
- rm -f "$TEST_IMG.not_base"
826
+ _rm_test_img "$TEST_IMG.not_base"
827
}
828
trap "_cleanup; exit \$status" 0 1 2 3 15
829
830
diff --git a/tests/qemu-iotests/229 b/tests/qemu-iotests/229
831
index XXXXXXX..XXXXXXX 100755
832
--- a/tests/qemu-iotests/229
833
+++ b/tests/qemu-iotests/229
834
@@ -XXX,XX +XXX,XX @@ _cleanup()
835
{
836
_cleanup_qemu
837
_cleanup_test_img
838
- rm -f "$TEST_IMG" "$DEST_IMG"
839
+ _rm_test_img "$TEST_IMG"
840
+ _rm_test_img "$DEST_IMG"
841
}
842
trap "_cleanup; exit \$status" 0 1 2 3 15
843
844
diff --git a/tests/qemu-iotests/232 b/tests/qemu-iotests/232
845
index XXXXXXX..XXXXXXX 100755
846
--- a/tests/qemu-iotests/232
847
+++ b/tests/qemu-iotests/232
848
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
849
_cleanup()
850
{
851
_cleanup_test_img
852
- rm -f $TEST_IMG.[01234]
853
+ for img in "$TEST_IMG".[01234]; do
854
+ _rm_test_img "$img"
855
+ done
856
}
857
trap "_cleanup; exit \$status" 0 1 2 3 15
858
859
diff --git a/tests/qemu-iotests/243 b/tests/qemu-iotests/243
860
index XXXXXXX..XXXXXXX 100755
861
--- a/tests/qemu-iotests/243
862
+++ b/tests/qemu-iotests/243
863
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
864
_cleanup()
865
{
866
_cleanup_test_img
867
- rm -f $TEST_IMG.data
868
+ _rm_test_img "$TEST_IMG.data"
869
}
870
trap "_cleanup; exit \$status" 0 1 2 3 15
871
872
diff --git a/tests/qemu-iotests/244 b/tests/qemu-iotests/244
873
index XXXXXXX..XXXXXXX 100755
874
--- a/tests/qemu-iotests/244
875
+++ b/tests/qemu-iotests/244
876
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
877
_cleanup()
878
{
879
_cleanup_test_img
880
- rm -f $TEST_IMG.data
881
- rm -f $TEST_IMG.src
882
+ _rm_test_img "$TEST_IMG.data"
883
+ _rm_test_img "$TEST_IMG.src"
884
}
885
trap "_cleanup; exit \$status" 0 1 2 3 15
886
887
diff --git a/tests/qemu-iotests/247 b/tests/qemu-iotests/247
888
index XXXXXXX..XXXXXXX 100755
889
--- a/tests/qemu-iotests/247
890
+++ b/tests/qemu-iotests/247
891
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
892
_cleanup()
893
{
894
_cleanup_test_img
895
- rm -f $TEST_IMG.[01234]
896
+ for img in "$TEST_IMG".[01234]; do
897
+ _rm_test_img "$img"
898
+ done
899
}
900
trap "_cleanup; exit \$status" 0 1 2 3 15
901
902
diff --git a/tests/qemu-iotests/249 b/tests/qemu-iotests/249
903
index XXXXXXX..XXXXXXX 100755
904
--- a/tests/qemu-iotests/249
905
+++ b/tests/qemu-iotests/249
906
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
907
_cleanup()
908
{
909
_cleanup_test_img
910
- rm -f "$TEST_IMG.base"
911
- rm -f "$TEST_IMG.int"
912
+ _rm_test_img "$TEST_IMG.base"
913
+ _rm_test_img "$TEST_IMG.int"
914
}
915
trap "_cleanup; exit \$status" 0 1 2 3 15
916
917
diff --git a/tests/qemu-iotests/252 b/tests/qemu-iotests/252
918
index XXXXXXX..XXXXXXX 100755
919
--- a/tests/qemu-iotests/252
920
+++ b/tests/qemu-iotests/252
921
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
922
_cleanup()
923
{
924
_cleanup_test_img
925
- rm -f "$TEST_IMG.base_new"
926
+ _rm_test_img "$TEST_IMG.base_new"
927
}
928
trap "_cleanup; exit \$status" 0 1 2 3 15
929
930
--
931
2.24.1
932
933
diff view generated by jsdifflib
1
Signed-off-by: Max Reitz <mreitz@redhat.com>
1
From: Elena Ufimtseva <elena.ufimtseva@oracle.com>
2
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
2
3
Message-id: 20191107163708.833192-5-mreitz@redhat.com
3
Adds qio_channel_writev_full_all() to transmit both data and FDs.
4
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
Refactors existing code to use this helper.
5
6
Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
7
Signed-off-by: John G Johnson <john.g.johnson@oracle.com>
8
Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
9
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
10
Acked-by: Daniel P. Berrangé <berrange@redhat.com>
11
Message-id: 480fbf1fe4152495d60596c9b665124549b426a5.1611938319.git.jag.raman@oracle.com
12
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
5
---
13
---
6
tests/qemu-iotests/common.filter | 24 ++++++++++++++++++++++++
14
include/io/channel.h | 25 +++++++++++++++++++++++++
7
1 file changed, 24 insertions(+)
15
io/channel.c | 15 ++++++++++++++-
16
2 files changed, 39 insertions(+), 1 deletion(-)
8
17
9
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
18
diff --git a/include/io/channel.h b/include/io/channel.h
10
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
11
--- a/tests/qemu-iotests/common.filter
20
--- a/include/io/channel.h
12
+++ b/tests/qemu-iotests/common.filter
21
+++ b/include/io/channel.h
13
@@ -XXX,XX +XXX,XX @@ _filter_qmp_empty_return()
22
@@ -XXX,XX +XXX,XX @@ void qio_channel_set_aio_fd_handler(QIOChannel *ioc,
14
grep -v '{"return": {}}'
23
IOHandler *io_write,
15
}
24
void *opaque);
16
25
17
+_filter_json_filename()
26
+/**
27
+ * qio_channel_writev_full_all:
28
+ * @ioc: the channel object
29
+ * @iov: the array of memory regions to write data from
30
+ * @niov: the length of the @iov array
31
+ * @fds: an array of file handles to send
32
+ * @nfds: number of file handles in @fds
33
+ * @errp: pointer to a NULL-initialized error object
34
+ *
35
+ *
36
+ * Behaves like qio_channel_writev_full but will attempt
37
+ * to send all data passed (file handles and memory regions).
38
+ * The function will wait for all requested data
39
+ * to be written, yielding from the current coroutine
40
+ * if required.
41
+ *
42
+ * Returns: 0 if all bytes were written, or -1 on error
43
+ */
44
+
45
+int qio_channel_writev_full_all(QIOChannel *ioc,
46
+ const struct iovec *iov,
47
+ size_t niov,
48
+ int *fds, size_t nfds,
49
+ Error **errp);
50
+
51
#endif /* QIO_CHANNEL_H */
52
diff --git a/io/channel.c b/io/channel.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/io/channel.c
55
+++ b/io/channel.c
56
@@ -XXX,XX +XXX,XX @@ int qio_channel_writev_all(QIOChannel *ioc,
57
const struct iovec *iov,
58
size_t niov,
59
Error **errp)
18
+{
60
+{
19
+ $PYTHON -c 'import sys
61
+ return qio_channel_writev_full_all(ioc, iov, niov, NULL, 0, errp);
20
+result, *fnames = sys.stdin.read().split("json:{")
21
+depth = 0
22
+for fname in fnames:
23
+ depth += 1 # For the opening brace in the split separator
24
+ for chr_i, chr in enumerate(fname):
25
+ if chr == "{":
26
+ depth += 1
27
+ elif chr == "}":
28
+ depth -= 1
29
+ if depth == 0:
30
+ break
31
+
32
+ # json:{} filenames may be nested; filter out everything from
33
+ # inside the outermost one
34
+ if depth == 0:
35
+ chr_i += 1 # First character past the filename
36
+ result += "json:{ /* filtered */ }" + fname[chr_i:]
37
+
38
+sys.stdout.write(result)'
39
+}
62
+}
40
+
63
+
41
# make sure this script returns success
64
+int qio_channel_writev_full_all(QIOChannel *ioc,
42
true
65
+ const struct iovec *iov,
66
+ size_t niov,
67
+ int *fds, size_t nfds,
68
+ Error **errp)
69
{
70
int ret = -1;
71
struct iovec *local_iov = g_new(struct iovec, niov);
72
@@ -XXX,XX +XXX,XX @@ int qio_channel_writev_all(QIOChannel *ioc,
73
74
while (nlocal_iov > 0) {
75
ssize_t len;
76
- len = qio_channel_writev(ioc, local_iov, nlocal_iov, errp);
77
+ len = qio_channel_writev_full(ioc, local_iov, nlocal_iov, fds, nfds,
78
+ errp);
79
if (len == QIO_CHANNEL_ERR_BLOCK) {
80
if (qemu_in_coroutine()) {
81
qio_channel_yield(ioc, G_IO_OUT);
82
@@ -XXX,XX +XXX,XX @@ int qio_channel_writev_all(QIOChannel *ioc,
83
}
84
85
iov_discard_front(&local_iov, &nlocal_iov, len);
86
+
87
+ fds = NULL;
88
+ nfds = 0;
89
}
90
91
ret = 0;
43
--
92
--
44
2.24.1
93
2.29.2
45
94
46
diff view generated by jsdifflib
1
From: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
1
From: Elena Ufimtseva <elena.ufimtseva@oracle.com>
2
2
3
QEMU currently supports writing compressed data of the size equal to
3
Adds qio_channel_readv_full_all_eof() and qio_channel_readv_full_all()
4
one cluster. This patch allows writing QCOW2 compressed data that
4
to read both data and FDs. Refactors existing code to use these helpers.
5
exceed one cluster. Now, we split buffered data into separate clusters
5
6
and write them compressed using the block/aio_task API.
6
Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
7
7
Signed-off-by: John G Johnson <john.g.johnson@oracle.com>
8
Suggested-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
8
Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
9
Suggested-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
Acked-by: Daniel P. Berrangé <berrange@redhat.com>
10
Signed-off-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
10
Message-id: b059c4cc0fb741e794d644c144cc21372cad877d.1611938319.git.jag.raman@oracle.com
11
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
Reviewed-by: Max Reitz <mreitz@redhat.com>
13
Message-id: 1575288906-551879-3-git-send-email-andrey.shinkevich@virtuozzo.com
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
15
---
12
---
16
block/qcow2.c | 102 +++++++++++++++++++++++++++++++++++++-------------
13
include/io/channel.h | 53 +++++++++++++++++++++++
17
1 file changed, 75 insertions(+), 27 deletions(-)
14
io/channel.c | 101 ++++++++++++++++++++++++++++++++++---------
18
15
2 files changed, 134 insertions(+), 20 deletions(-)
19
diff --git a/block/qcow2.c b/block/qcow2.c
16
17
diff --git a/include/io/channel.h b/include/io/channel.h
20
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
21
--- a/block/qcow2.c
19
--- a/include/io/channel.h
22
+++ b/block/qcow2.c
20
+++ b/include/io/channel.h
23
@@ -XXX,XX +XXX,XX @@ fail:
21
@@ -XXX,XX +XXX,XX @@ void qio_channel_set_aio_fd_handler(QIOChannel *ioc,
22
IOHandler *io_write,
23
void *opaque);
24
25
+/**
26
+ * qio_channel_readv_full_all_eof:
27
+ * @ioc: the channel object
28
+ * @iov: the array of memory regions to read data to
29
+ * @niov: the length of the @iov array
30
+ * @fds: an array of file handles to read
31
+ * @nfds: number of file handles in @fds
32
+ * @errp: pointer to a NULL-initialized error object
33
+ *
34
+ *
35
+ * Performs same function as qio_channel_readv_all_eof.
36
+ * Additionally, attempts to read file descriptors shared
37
+ * over the channel. The function will wait for all
38
+ * requested data to be read, yielding from the current
39
+ * coroutine if required. data refers to both file
40
+ * descriptors and the iovs.
41
+ *
42
+ * Returns: 1 if all bytes were read, 0 if end-of-file
43
+ * occurs without data, or -1 on error
44
+ */
45
+
46
+int qio_channel_readv_full_all_eof(QIOChannel *ioc,
47
+ const struct iovec *iov,
48
+ size_t niov,
49
+ int **fds, size_t *nfds,
50
+ Error **errp);
51
+
52
+/**
53
+ * qio_channel_readv_full_all:
54
+ * @ioc: the channel object
55
+ * @iov: the array of memory regions to read data to
56
+ * @niov: the length of the @iov array
57
+ * @fds: an array of file handles to read
58
+ * @nfds: number of file handles in @fds
59
+ * @errp: pointer to a NULL-initialized error object
60
+ *
61
+ *
62
+ * Performs same function as qio_channel_readv_all_eof.
63
+ * Additionally, attempts to read file descriptors shared
64
+ * over the channel. The function will wait for all
65
+ * requested data to be read, yielding from the current
66
+ * coroutine if required. data refers to both file
67
+ * descriptors and the iovs.
68
+ *
69
+ * Returns: 0 if all bytes were read, or -1 on error
70
+ */
71
+
72
+int qio_channel_readv_full_all(QIOChannel *ioc,
73
+ const struct iovec *iov,
74
+ size_t niov,
75
+ int **fds, size_t *nfds,
76
+ Error **errp);
77
+
78
/**
79
* qio_channel_writev_full_all:
80
* @ioc: the channel object
81
diff --git a/io/channel.c b/io/channel.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/io/channel.c
84
+++ b/io/channel.c
85
@@ -XXX,XX +XXX,XX @@ int qio_channel_readv_all_eof(QIOChannel *ioc,
86
const struct iovec *iov,
87
size_t niov,
88
Error **errp)
89
+{
90
+ return qio_channel_readv_full_all_eof(ioc, iov, niov, NULL, NULL, errp);
91
+}
92
+
93
+int qio_channel_readv_all(QIOChannel *ioc,
94
+ const struct iovec *iov,
95
+ size_t niov,
96
+ Error **errp)
97
+{
98
+ return qio_channel_readv_full_all(ioc, iov, niov, NULL, NULL, errp);
99
+}
100
+
101
+int qio_channel_readv_full_all_eof(QIOChannel *ioc,
102
+ const struct iovec *iov,
103
+ size_t niov,
104
+ int **fds, size_t *nfds,
105
+ Error **errp)
106
{
107
int ret = -1;
108
struct iovec *local_iov = g_new(struct iovec, niov);
109
struct iovec *local_iov_head = local_iov;
110
unsigned int nlocal_iov = niov;
111
+ int **local_fds = fds;
112
+ size_t *local_nfds = nfds;
113
bool partial = false;
114
115
+ if (nfds) {
116
+ *nfds = 0;
117
+ }
118
+
119
+ if (fds) {
120
+ *fds = NULL;
121
+ }
122
+
123
nlocal_iov = iov_copy(local_iov, nlocal_iov,
124
iov, niov,
125
0, iov_size(iov, niov));
126
127
- while (nlocal_iov > 0) {
128
+ while ((nlocal_iov > 0) || local_fds) {
129
ssize_t len;
130
- len = qio_channel_readv(ioc, local_iov, nlocal_iov, errp);
131
+ len = qio_channel_readv_full(ioc, local_iov, nlocal_iov, local_fds,
132
+ local_nfds, errp);
133
if (len == QIO_CHANNEL_ERR_BLOCK) {
134
if (qemu_in_coroutine()) {
135
qio_channel_yield(ioc, G_IO_IN);
136
@@ -XXX,XX +XXX,XX @@ int qio_channel_readv_all_eof(QIOChannel *ioc,
137
qio_channel_wait(ioc, G_IO_IN);
138
}
139
continue;
140
- } else if (len < 0) {
141
- goto cleanup;
142
- } else if (len == 0) {
143
- if (partial) {
144
- error_setg(errp,
145
- "Unexpected end-of-file before all bytes were read");
146
- } else {
147
+ }
148
+
149
+ if (len == 0) {
150
+ if (local_nfds && *local_nfds) {
151
+ /*
152
+ * Got some FDs, but no data yet. This isn't an EOF
153
+ * scenario (yet), so carry on to try to read data
154
+ * on next loop iteration
155
+ */
156
+ goto next_iter;
157
+ } else if (!partial) {
158
+ /* No fds and no data - EOF before any data read */
159
ret = 0;
160
+ goto cleanup;
161
+ } else {
162
+ len = -1;
163
+ error_setg(errp,
164
+ "Unexpected end-of-file before all data were read");
165
+ /* Fallthrough into len < 0 handling */
166
+ }
167
+ }
168
+
169
+ if (len < 0) {
170
+ /* Close any FDs we previously received */
171
+ if (nfds && fds) {
172
+ size_t i;
173
+ for (i = 0; i < (*nfds); i++) {
174
+ close((*fds)[i]);
175
+ }
176
+ g_free(*fds);
177
+ *fds = NULL;
178
+ *nfds = 0;
179
}
180
goto cleanup;
181
}
182
183
+ if (nlocal_iov) {
184
+ iov_discard_front(&local_iov, &nlocal_iov, len);
185
+ }
186
+
187
+next_iter:
188
partial = true;
189
- iov_discard_front(&local_iov, &nlocal_iov, len);
190
+ local_fds = NULL;
191
+ local_nfds = NULL;
192
}
193
194
ret = 1;
195
@@ -XXX,XX +XXX,XX @@ int qio_channel_readv_all_eof(QIOChannel *ioc,
24
return ret;
196
return ret;
25
}
197
}
26
198
27
-/* XXX: put compressed sectors first, then all the cluster aligned
199
-int qio_channel_readv_all(QIOChannel *ioc,
28
- tables to avoid losing bytes in alignment */
200
- const struct iovec *iov,
29
static coroutine_fn int
201
- size_t niov,
30
-qcow2_co_pwritev_compressed_part(BlockDriverState *bs,
202
- Error **errp)
31
+qcow2_co_pwritev_compressed_task(BlockDriverState *bs,
203
+int qio_channel_readv_full_all(QIOChannel *ioc,
32
uint64_t offset, uint64_t bytes,
204
+ const struct iovec *iov,
33
QEMUIOVector *qiov, size_t qiov_offset)
205
+ size_t niov,
206
+ int **fds, size_t *nfds,
207
+ Error **errp)
34
{
208
{
35
@@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed_part(BlockDriverState *bs,
209
- int ret = qio_channel_readv_all_eof(ioc, iov, niov, errp);
36
uint8_t *buf, *out_buf;
210
+ int ret = qio_channel_readv_full_all_eof(ioc, iov, niov, fds, nfds, errp);
37
uint64_t cluster_offset;
211
38
212
if (ret == 0) {
39
- if (has_data_file(bs)) {
213
- ret = -1;
40
- return -ENOTSUP;
214
- error_setg(errp,
41
- }
215
- "Unexpected end-of-file before all bytes were read");
42
-
216
- } else if (ret == 1) {
43
- if (bytes == 0) {
217
- ret = 0;
44
- /* align end of file to a sector boundary to ease reading with
218
+ error_prepend(errp,
45
- sector based I/Os */
219
+ "Unexpected end-of-file before all data were read.");
46
- int64_t len = bdrv_getlength(bs->file->bs);
220
+ return -1;
47
- if (len < 0) {
48
- return len;
49
- }
50
- return bdrv_co_truncate(bs->file, len, false, PREALLOC_MODE_OFF, NULL);
51
- }
52
-
53
- if (offset_into_cluster(s, offset)) {
54
- return -EINVAL;
55
- }
56
+ assert(bytes == s->cluster_size || (bytes < s->cluster_size &&
57
+ (offset + bytes == bs->total_sectors << BDRV_SECTOR_BITS)));
58
59
buf = qemu_blockalign(bs, s->cluster_size);
60
- if (bytes != s->cluster_size) {
61
- if (bytes > s->cluster_size ||
62
- offset + bytes != bs->total_sectors << BDRV_SECTOR_BITS)
63
- {
64
- qemu_vfree(buf);
65
- return -EINVAL;
66
- }
67
+ if (bytes < s->cluster_size) {
68
/* Zero-pad last write if image size is not cluster aligned */
69
memset(buf + bytes, 0, s->cluster_size - bytes);
70
}
221
}
71
@@ -XXX,XX +XXX,XX @@ fail:
222
+ if (ret == 1) {
223
+ return 0;
224
+ }
225
+
72
return ret;
226
return ret;
73
}
227
}
74
228
75
+static coroutine_fn int qcow2_co_pwritev_compressed_task_entry(AioTask *task)
76
+{
77
+ Qcow2AioTask *t = container_of(task, Qcow2AioTask, task);
78
+
79
+ assert(!t->cluster_type && !t->l2meta);
80
+
81
+ return qcow2_co_pwritev_compressed_task(t->bs, t->offset, t->bytes, t->qiov,
82
+ t->qiov_offset);
83
+}
84
+
85
+/*
86
+ * XXX: put compressed sectors first, then all the cluster aligned
87
+ * tables to avoid losing bytes in alignment
88
+ */
89
+static coroutine_fn int
90
+qcow2_co_pwritev_compressed_part(BlockDriverState *bs,
91
+ uint64_t offset, uint64_t bytes,
92
+ QEMUIOVector *qiov, size_t qiov_offset)
93
+{
94
+ BDRVQcow2State *s = bs->opaque;
95
+ AioTaskPool *aio = NULL;
96
+ int ret = 0;
97
+
98
+ if (has_data_file(bs)) {
99
+ return -ENOTSUP;
100
+ }
101
+
102
+ if (bytes == 0) {
103
+ /*
104
+ * align end of file to a sector boundary to ease reading with
105
+ * sector based I/Os
106
+ */
107
+ int64_t len = bdrv_getlength(bs->file->bs);
108
+ if (len < 0) {
109
+ return len;
110
+ }
111
+ return bdrv_co_truncate(bs->file, len, false, PREALLOC_MODE_OFF, NULL);
112
+ }
113
+
114
+ if (offset_into_cluster(s, offset)) {
115
+ return -EINVAL;
116
+ }
117
+
118
+ while (bytes && aio_task_pool_status(aio) == 0) {
119
+ uint64_t chunk_size = MIN(bytes, s->cluster_size);
120
+
121
+ if (!aio && chunk_size != bytes) {
122
+ aio = aio_task_pool_new(QCOW2_MAX_WORKERS);
123
+ }
124
+
125
+ ret = qcow2_add_task(bs, aio, qcow2_co_pwritev_compressed_task_entry,
126
+ 0, 0, offset, chunk_size, qiov, qiov_offset, NULL);
127
+ if (ret < 0) {
128
+ break;
129
+ }
130
+ qiov_offset += chunk_size;
131
+ offset += chunk_size;
132
+ bytes -= chunk_size;
133
+ }
134
+
135
+ if (aio) {
136
+ aio_task_pool_wait_all(aio);
137
+ if (ret == 0) {
138
+ ret = aio_task_pool_status(aio);
139
+ }
140
+ g_free(aio);
141
+ }
142
+
143
+ return ret;
144
+}
145
+
146
static int coroutine_fn
147
qcow2_co_preadv_compressed(BlockDriverState *bs,
148
uint64_t file_cluster_offset,
149
--
229
--
150
2.24.1
230
2.29.2
151
231
152
diff view generated by jsdifflib
1
Tests should not overwrite all user-supplied image options, but only add
1
From: Elena Ufimtseva <elena.ufimtseva@oracle.com>
2
to it (which will effectively overwrite conflicting values). Accomplish
3
this by passing options to _make_test_img via -o instead of $IMGOPTS.
4
2
5
For some tests, there is no functional change because they already only
3
Defines MPQemuMsg, which is the message that is sent to the remote
6
appended options to IMGOPTS. For these, this patch is just a
4
process. This message is sent over QIOChannel and is used to
7
simplification.
5
command the remote process to perform various tasks.
6
Define transmission functions used by proxy and by remote.
8
7
9
For others, this is a change, so they now heed user-specified $IMGOPTS.
8
Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
10
Some of those tests do not work with all image options, though, so we
9
Signed-off-by: John G Johnson <john.g.johnson@oracle.com>
11
need to disable them accordingly.
10
Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
11
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
12
Message-id: 56ca8bcf95195b2b195b08f6b9565b6d7410bce5.1611938319.git.jag.raman@oracle.com
13
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
14
---
15
MAINTAINERS | 2 +
16
meson.build | 1 +
17
hw/remote/trace.h | 1 +
18
include/hw/remote/mpqemu-link.h | 63 ++++++++++
19
include/sysemu/iothread.h | 6 +
20
hw/remote/mpqemu-link.c | 205 ++++++++++++++++++++++++++++++++
21
iothread.c | 6 +
22
hw/remote/meson.build | 1 +
23
hw/remote/trace-events | 4 +
24
9 files changed, 289 insertions(+)
25
create mode 100644 hw/remote/trace.h
26
create mode 100644 include/hw/remote/mpqemu-link.h
27
create mode 100644 hw/remote/mpqemu-link.c
28
create mode 100644 hw/remote/trace-events
12
29
13
Signed-off-by: Max Reitz <mreitz@redhat.com>
30
diff --git a/MAINTAINERS b/MAINTAINERS
14
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
31
index XXXXXXX..XXXXXXX 100644
15
Message-id: 20191107163708.833192-12-mreitz@redhat.com
32
--- a/MAINTAINERS
16
Signed-off-by: Max Reitz <mreitz@redhat.com>
33
+++ b/MAINTAINERS
17
---
34
@@ -XXX,XX +XXX,XX @@ F: hw/pci-host/remote.c
18
tests/qemu-iotests/031 | 9 ++++---
35
F: include/hw/pci-host/remote.h
19
tests/qemu-iotests/039 | 24 ++++++------------
36
F: hw/remote/machine.c
20
tests/qemu-iotests/059 | 18 ++++++-------
37
F: include/hw/remote/machine.h
21
tests/qemu-iotests/060 | 6 ++---
38
+F: hw/remote/mpqemu-link.c
22
tests/qemu-iotests/061 | 57 ++++++++++++++++++++++--------------------
39
+F: include/hw/remote/mpqemu-link.h
23
tests/qemu-iotests/079 | 3 +--
40
24
tests/qemu-iotests/106 | 2 +-
41
Build and test automation
25
tests/qemu-iotests/108 | 2 +-
42
-------------------------
26
tests/qemu-iotests/112 | 32 ++++++++++++------------
43
diff --git a/meson.build b/meson.build
27
tests/qemu-iotests/115 | 3 +--
44
index XXXXXXX..XXXXXXX 100644
28
tests/qemu-iotests/121 | 6 ++---
45
--- a/meson.build
29
tests/qemu-iotests/125 | 2 +-
46
+++ b/meson.build
30
tests/qemu-iotests/137 | 2 +-
47
@@ -XXX,XX +XXX,XX @@ if have_system
31
tests/qemu-iotests/138 | 3 +--
48
'net',
32
tests/qemu-iotests/175 | 2 +-
49
'softmmu',
33
tests/qemu-iotests/190 | 2 +-
50
'ui',
34
tests/qemu-iotests/191 | 3 +--
51
+ 'hw/remote',
35
tests/qemu-iotests/220 | 4 ++-
52
]
36
tests/qemu-iotests/243 | 6 +++--
53
endif
37
tests/qemu-iotests/244 | 10 +++++---
54
trace_events_subdirs += [
38
tests/qemu-iotests/250 | 3 +--
55
diff --git a/hw/remote/trace.h b/hw/remote/trace.h
39
tests/qemu-iotests/265 | 2 +-
56
new file mode 100644
40
22 files changed, 100 insertions(+), 101 deletions(-)
57
index XXXXXXX..XXXXXXX
58
--- /dev/null
59
+++ b/hw/remote/trace.h
60
@@ -0,0 +1 @@
61
+#include "trace/trace-hw_remote.h"
62
diff --git a/include/hw/remote/mpqemu-link.h b/include/hw/remote/mpqemu-link.h
63
new file mode 100644
64
index XXXXXXX..XXXXXXX
65
--- /dev/null
66
+++ b/include/hw/remote/mpqemu-link.h
67
@@ -XXX,XX +XXX,XX @@
68
+/*
69
+ * Communication channel between QEMU and remote device process
70
+ *
71
+ * Copyright © 2018, 2021 Oracle and/or its affiliates.
72
+ *
73
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
74
+ * See the COPYING file in the top-level directory.
75
+ *
76
+ */
77
+
78
+#ifndef MPQEMU_LINK_H
79
+#define MPQEMU_LINK_H
80
+
81
+#include "qom/object.h"
82
+#include "qemu/thread.h"
83
+#include "io/channel.h"
84
+
85
+#define REMOTE_MAX_FDS 8
86
+
87
+#define MPQEMU_MSG_HDR_SIZE offsetof(MPQemuMsg, data.u64)
88
+
89
+/**
90
+ * MPQemuCmd:
91
+ *
92
+ * MPQemuCmd enum type to specify the command to be executed on the remote
93
+ * device.
94
+ *
95
+ * This uses a private protocol between QEMU and the remote process. vfio-user
96
+ * protocol would supersede this in the future.
97
+ *
98
+ */
99
+typedef enum {
100
+ MPQEMU_CMD_MAX,
101
+} MPQemuCmd;
102
+
103
+/**
104
+ * MPQemuMsg:
105
+ * @cmd: The remote command
106
+ * @size: Size of the data to be shared
107
+ * @data: Structured data
108
+ * @fds: File descriptors to be shared with remote device
109
+ *
110
+ * MPQemuMsg Format of the message sent to the remote device from QEMU.
111
+ *
112
+ */
113
+typedef struct {
114
+ int cmd;
115
+ size_t size;
116
+
117
+ union {
118
+ uint64_t u64;
119
+ } data;
120
+
121
+ int fds[REMOTE_MAX_FDS];
122
+ int num_fds;
123
+} MPQemuMsg;
124
+
125
+bool mpqemu_msg_send(MPQemuMsg *msg, QIOChannel *ioc, Error **errp);
126
+bool mpqemu_msg_recv(MPQemuMsg *msg, QIOChannel *ioc, Error **errp);
127
+
128
+bool mpqemu_msg_valid(MPQemuMsg *msg);
129
+
130
+#endif
131
diff --git a/include/sysemu/iothread.h b/include/sysemu/iothread.h
132
index XXXXXXX..XXXXXXX 100644
133
--- a/include/sysemu/iothread.h
134
+++ b/include/sysemu/iothread.h
135
@@ -XXX,XX +XXX,XX @@ IOThread *iothread_create(const char *id, Error **errp);
136
void iothread_stop(IOThread *iothread);
137
void iothread_destroy(IOThread *iothread);
138
139
+/*
140
+ * Returns true if executing withing IOThread context,
141
+ * false otherwise.
142
+ */
143
+bool qemu_in_iothread(void);
144
+
145
#endif /* IOTHREAD_H */
146
diff --git a/hw/remote/mpqemu-link.c b/hw/remote/mpqemu-link.c
147
new file mode 100644
148
index XXXXXXX..XXXXXXX
149
--- /dev/null
150
+++ b/hw/remote/mpqemu-link.c
151
@@ -XXX,XX +XXX,XX @@
152
+/*
153
+ * Communication channel between QEMU and remote device process
154
+ *
155
+ * Copyright © 2018, 2021 Oracle and/or its affiliates.
156
+ *
157
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
158
+ * See the COPYING file in the top-level directory.
159
+ *
160
+ */
161
+
162
+#include "qemu/osdep.h"
163
+#include "qemu-common.h"
164
+
165
+#include "qemu/module.h"
166
+#include "hw/remote/mpqemu-link.h"
167
+#include "qapi/error.h"
168
+#include "qemu/iov.h"
169
+#include "qemu/error-report.h"
170
+#include "qemu/main-loop.h"
171
+#include "io/channel.h"
172
+#include "sysemu/iothread.h"
173
+#include "trace.h"
174
+
175
+/*
176
+ * Send message over the ioc QIOChannel.
177
+ * This function is safe to call from:
178
+ * - main loop in co-routine context. Will block the main loop if not in
179
+ * co-routine context;
180
+ * - vCPU thread with no co-routine context and if the channel is not part
181
+ * of the main loop handling;
182
+ * - IOThread within co-routine context, outside of co-routine context
183
+ * will block IOThread;
184
+ * Returns true if no errors were encountered, false otherwise.
185
+ */
186
+bool mpqemu_msg_send(MPQemuMsg *msg, QIOChannel *ioc, Error **errp)
187
+{
188
+ ERRP_GUARD();
189
+ bool iolock = qemu_mutex_iothread_locked();
190
+ bool iothread = qemu_in_iothread();
191
+ struct iovec send[2] = {0};
192
+ int *fds = NULL;
193
+ size_t nfds = 0;
194
+ bool ret = false;
195
+
196
+ send[0].iov_base = msg;
197
+ send[0].iov_len = MPQEMU_MSG_HDR_SIZE;
198
+
199
+ send[1].iov_base = (void *)&msg->data;
200
+ send[1].iov_len = msg->size;
201
+
202
+ if (msg->num_fds) {
203
+ nfds = msg->num_fds;
204
+ fds = msg->fds;
205
+ }
206
+
207
+ /*
208
+ * Dont use in IOThread out of co-routine context as
209
+ * it will block IOThread.
210
+ */
211
+ assert(qemu_in_coroutine() || !iothread);
212
+
213
+ /*
214
+ * Skip unlocking/locking iothread lock when the IOThread is running
215
+ * in co-routine context. Co-routine context is asserted above
216
+ * for IOThread case.
217
+ * Also skip lock handling while in a co-routine in the main context.
218
+ */
219
+ if (iolock && !iothread && !qemu_in_coroutine()) {
220
+ qemu_mutex_unlock_iothread();
221
+ }
222
+
223
+ if (!qio_channel_writev_full_all(ioc, send, G_N_ELEMENTS(send),
224
+ fds, nfds, errp)) {
225
+ ret = true;
226
+ } else {
227
+ trace_mpqemu_send_io_error(msg->cmd, msg->size, nfds);
228
+ }
229
+
230
+ if (iolock && !iothread && !qemu_in_coroutine()) {
231
+ /* See above comment why skip locking here. */
232
+ qemu_mutex_lock_iothread();
233
+ }
234
+
235
+ return ret;
236
+}
237
+
238
+/*
239
+ * Read message from the ioc QIOChannel.
240
+ * This function is safe to call from:
241
+ * - From main loop in co-routine context. Will block the main loop if not in
242
+ * co-routine context;
243
+ * - From vCPU thread with no co-routine context and if the channel is not part
244
+ * of the main loop handling;
245
+ * - From IOThread within co-routine context, outside of co-routine context
246
+ * will block IOThread;
247
+ */
248
+static ssize_t mpqemu_read(QIOChannel *ioc, void *buf, size_t len, int **fds,
249
+ size_t *nfds, Error **errp)
250
+{
251
+ ERRP_GUARD();
252
+ struct iovec iov = { .iov_base = buf, .iov_len = len };
253
+ bool iolock = qemu_mutex_iothread_locked();
254
+ bool iothread = qemu_in_iothread();
255
+ int ret = -1;
256
+
257
+ /*
258
+ * Dont use in IOThread out of co-routine context as
259
+ * it will block IOThread.
260
+ */
261
+ assert(qemu_in_coroutine() || !iothread);
262
+
263
+ if (iolock && !iothread && !qemu_in_coroutine()) {
264
+ qemu_mutex_unlock_iothread();
265
+ }
266
+
267
+ ret = qio_channel_readv_full_all_eof(ioc, &iov, 1, fds, nfds, errp);
268
+
269
+ if (iolock && !iothread && !qemu_in_coroutine()) {
270
+ qemu_mutex_lock_iothread();
271
+ }
272
+
273
+ return (ret <= 0) ? ret : iov.iov_len;
274
+}
275
+
276
+bool mpqemu_msg_recv(MPQemuMsg *msg, QIOChannel *ioc, Error **errp)
277
+{
278
+ ERRP_GUARD();
279
+ g_autofree int *fds = NULL;
280
+ size_t nfds = 0;
281
+ ssize_t len;
282
+ bool ret = false;
283
+
284
+ len = mpqemu_read(ioc, msg, MPQEMU_MSG_HDR_SIZE, &fds, &nfds, errp);
285
+ if (len <= 0) {
286
+ goto fail;
287
+ } else if (len != MPQEMU_MSG_HDR_SIZE) {
288
+ error_setg(errp, "Message header corrupted");
289
+ goto fail;
290
+ }
291
+
292
+ if (msg->size > sizeof(msg->data)) {
293
+ error_setg(errp, "Invalid size for message");
294
+ goto fail;
295
+ }
296
+
297
+ if (!msg->size) {
298
+ goto copy_fds;
299
+ }
300
+
301
+ len = mpqemu_read(ioc, &msg->data, msg->size, NULL, NULL, errp);
302
+ if (len <= 0) {
303
+ goto fail;
304
+ }
305
+ if (len != msg->size) {
306
+ error_setg(errp, "Unable to read full message");
307
+ goto fail;
308
+ }
309
+
310
+copy_fds:
311
+ msg->num_fds = nfds;
312
+ if (nfds > G_N_ELEMENTS(msg->fds)) {
313
+ error_setg(errp,
314
+ "Overflow error: received %zu fds, more than max of %d fds",
315
+ nfds, REMOTE_MAX_FDS);
316
+ goto fail;
317
+ }
318
+ if (nfds) {
319
+ memcpy(msg->fds, fds, nfds * sizeof(int));
320
+ }
321
+
322
+ ret = true;
323
+
324
+fail:
325
+ if (*errp) {
326
+ trace_mpqemu_recv_io_error(msg->cmd, msg->size, nfds);
327
+ }
328
+ while (*errp && nfds) {
329
+ close(fds[nfds - 1]);
330
+ nfds--;
331
+ }
332
+
333
+ return ret;
334
+}
335
+
336
+bool mpqemu_msg_valid(MPQemuMsg *msg)
337
+{
338
+ if (msg->cmd >= MPQEMU_CMD_MAX && msg->cmd < 0) {
339
+ return false;
340
+ }
341
+
342
+ /* Verify FDs. */
343
+ if (msg->num_fds >= REMOTE_MAX_FDS) {
344
+ return false;
345
+ }
346
+
347
+ if (msg->num_fds > 0) {
348
+ for (int i = 0; i < msg->num_fds; i++) {
349
+ if (fcntl(msg->fds[i], F_GETFL) == -1) {
350
+ return false;
351
+ }
352
+ }
353
+ }
354
+
355
+ return true;
356
+}
357
diff --git a/iothread.c b/iothread.c
358
index XXXXXXX..XXXXXXX 100644
359
--- a/iothread.c
360
+++ b/iothread.c
361
@@ -XXX,XX +XXX,XX @@ IOThread *iothread_by_id(const char *id)
362
{
363
return IOTHREAD(object_resolve_path_type(id, TYPE_IOTHREAD, NULL));
364
}
365
+
366
+bool qemu_in_iothread(void)
367
+{
368
+ return qemu_get_current_aio_context() == qemu_get_aio_context() ?
369
+ false : true;
370
+}
371
diff --git a/hw/remote/meson.build b/hw/remote/meson.build
372
index XXXXXXX..XXXXXXX 100644
373
--- a/hw/remote/meson.build
374
+++ b/hw/remote/meson.build
375
@@ -XXX,XX +XXX,XX @@
376
remote_ss = ss.source_set()
377
378
remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('machine.c'))
379
+remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('mpqemu-link.c'))
380
381
softmmu_ss.add_all(when: 'CONFIG_MULTIPROCESS', if_true: remote_ss)
382
diff --git a/hw/remote/trace-events b/hw/remote/trace-events
383
new file mode 100644
384
index XXXXXXX..XXXXXXX
385
--- /dev/null
386
+++ b/hw/remote/trace-events
387
@@ -XXX,XX +XXX,XX @@
388
+# multi-process trace events
389
+
390
+mpqemu_send_io_error(int cmd, int size, int nfds) "send command %d size %d, %d file descriptors to remote process"
391
+mpqemu_recv_io_error(int cmd, int size, int nfds) "failed to receive %d size %d, %d file descriptors to remote process"
392
--
393
2.29.2
41
394
42
diff --git a/tests/qemu-iotests/031 b/tests/qemu-iotests/031
43
index XXXXXXX..XXXXXXX 100755
44
--- a/tests/qemu-iotests/031
45
+++ b/tests/qemu-iotests/031
46
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
47
# This tests qcow2-specific low-level functionality
48
_supported_fmt qcow2
49
_supported_proto file
50
+# We want to test compat=0.10, which does not support refcount widths
51
+# other than 16
52
+_unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)'
53
54
CLUSTER_SIZE=65536
55
56
# qcow2.py output depends on the exact options used, so override the command
57
# line here as an exception
58
-for IMGOPTS in "compat=0.10" "compat=1.1"; do
59
+for compat in "compat=0.10" "compat=1.1"; do
60
61
echo
62
- echo ===== Testing with -o $IMGOPTS =====
63
+ echo ===== Testing with -o $compat =====
64
echo
65
echo === Create image with unknown header extension ===
66
echo
67
- _make_test_img 64M
68
+ _make_test_img -o $compat 64M
69
$PYTHON qcow2.py "$TEST_IMG" add-header-ext 0x12345678 "This is a test header extension"
70
$PYTHON qcow2.py "$TEST_IMG" dump-header
71
_check_test_img
72
diff --git a/tests/qemu-iotests/039 b/tests/qemu-iotests/039
73
index XXXXXXX..XXXXXXX 100755
74
--- a/tests/qemu-iotests/039
75
+++ b/tests/qemu-iotests/039
76
@@ -XXX,XX +XXX,XX @@ size=128M
77
echo
78
echo "== Checking that image is clean on shutdown =="
79
80
-IMGOPTS="compat=1.1,lazy_refcounts=on"
81
-_make_test_img $size
82
+_make_test_img -o "compat=1.1,lazy_refcounts=on" $size
83
84
$QEMU_IO -c "write -P 0x5a 0 512" "$TEST_IMG" | _filter_qemu_io
85
86
@@ -XXX,XX +XXX,XX @@ _check_test_img
87
echo
88
echo "== Creating a dirty image file =="
89
90
-IMGOPTS="compat=1.1,lazy_refcounts=on"
91
-_make_test_img $size
92
+_make_test_img -o "compat=1.1,lazy_refcounts=on" $size
93
94
_NO_VALGRIND \
95
$QEMU_IO -c "write -P 0x5a 0 512" \
96
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c "read -P 0x5a 0 512" "$TEST_IMG" | _filter_qemu_io
97
echo
98
echo "== Opening a dirty image read/write should repair it =="
99
100
-IMGOPTS="compat=1.1,lazy_refcounts=on"
101
-_make_test_img $size
102
+_make_test_img -o "compat=1.1,lazy_refcounts=on" $size
103
104
_NO_VALGRIND \
105
$QEMU_IO -c "write -P 0x5a 0 512" \
106
@@ -XXX,XX +XXX,XX @@ $PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
107
echo
108
echo "== Creating an image file with lazy_refcounts=off =="
109
110
-IMGOPTS="compat=1.1,lazy_refcounts=off"
111
-_make_test_img $size
112
+_make_test_img -o "compat=1.1,lazy_refcounts=off" $size
113
114
_NO_VALGRIND \
115
$QEMU_IO -c "write -P 0x5a 0 512" \
116
@@ -XXX,XX +XXX,XX @@ _check_test_img
117
echo
118
echo "== Committing to a backing file with lazy_refcounts=on =="
119
120
-IMGOPTS="compat=1.1,lazy_refcounts=on"
121
-TEST_IMG="$TEST_IMG".base _make_test_img $size
122
+TEST_IMG="$TEST_IMG".base _make_test_img -o "compat=1.1,lazy_refcounts=on" $size
123
124
-IMGOPTS="compat=1.1,lazy_refcounts=on,backing_file=$TEST_IMG.base"
125
-_make_test_img $size
126
+_make_test_img -o "compat=1.1,lazy_refcounts=on,backing_file=$TEST_IMG.base" $size
127
128
$QEMU_IO -c "write 0 512" "$TEST_IMG" | _filter_qemu_io
129
$QEMU_IMG commit "$TEST_IMG"
130
@@ -XXX,XX +XXX,XX @@ TEST_IMG="$TEST_IMG".base _check_test_img
131
echo
132
echo "== Changing lazy_refcounts setting at runtime =="
133
134
-IMGOPTS="compat=1.1,lazy_refcounts=off"
135
-_make_test_img $size
136
+_make_test_img -o "compat=1.1,lazy_refcounts=off" $size
137
138
_NO_VALGRIND \
139
$QEMU_IO -c "reopen -o lazy-refcounts=on" \
140
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c "reopen -o lazy-refcounts=on" \
141
$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
142
_check_test_img
143
144
-IMGOPTS="compat=1.1,lazy_refcounts=on"
145
-_make_test_img $size
146
+_make_test_img -o "compat=1.1,lazy_refcounts=on" $size
147
148
_NO_VALGRIND \
149
$QEMU_IO -c "reopen -o lazy-refcounts=off" \
150
diff --git a/tests/qemu-iotests/059 b/tests/qemu-iotests/059
151
index XXXXXXX..XXXXXXX 100755
152
--- a/tests/qemu-iotests/059
153
+++ b/tests/qemu-iotests/059
154
@@ -XXX,XX +XXX,XX @@ poke_file "$TEST_IMG" "$grain_table_size_offset" "\x01\x00\x00\x00"
155
156
echo
157
echo "=== Testing monolithicFlat creation and opening ==="
158
-IMGOPTS="subformat=monolithicFlat" _make_test_img 2G
159
+_make_test_img -o "subformat=monolithicFlat" 2G
160
_img_info
161
_cleanup_test_img
162
163
echo
164
echo "=== Testing monolithicFlat with zeroed_grain ==="
165
-IMGOPTS="subformat=monolithicFlat,zeroed_grain=on" _make_test_img 2G
166
+_make_test_img -o "subformat=monolithicFlat,zeroed_grain=on" 2G
167
_cleanup_test_img
168
169
echo
170
echo "=== Testing big twoGbMaxExtentFlat ==="
171
-IMGOPTS="subformat=twoGbMaxExtentFlat" _make_test_img 1000G
172
+_make_test_img -o "subformat=twoGbMaxExtentFlat" 1000G
173
$QEMU_IMG info $TEST_IMG | _filter_testdir | sed -e 's/cid: [0-9]*/cid: XXXXXXXX/'
174
_cleanup_test_img
175
176
@@ -XXX,XX +XXX,XX @@ _img_info
177
178
echo
179
echo "=== Testing truncated sparse ==="
180
-IMGOPTS="subformat=monolithicSparse" _make_test_img 100G
181
+_make_test_img -o "subformat=monolithicSparse" 100G
182
truncate -s 10M $TEST_IMG
183
_img_info
184
185
echo
186
echo "=== Converting to streamOptimized from image with small cluster size==="
187
-TEST_IMG="$TEST_IMG.qcow2" IMGFMT=qcow2 IMGOPTS="cluster_size=4096" _make_test_img 1G
188
+TEST_IMG="$TEST_IMG.qcow2" IMGFMT=qcow2 _make_test_img -o "cluster_size=4096" 1G
189
$QEMU_IO -f qcow2 -c "write -P 0xa 0 512" "$TEST_IMG.qcow2" | _filter_qemu_io
190
$QEMU_IO -f qcow2 -c "write -P 0xb 10240 512" "$TEST_IMG.qcow2" | _filter_qemu_io
191
$QEMU_IMG convert -f qcow2 -O vmdk -o subformat=streamOptimized "$TEST_IMG.qcow2" "$TEST_IMG" 2>&1
192
@@ -XXX,XX +XXX,XX @@ echo "=== Testing monolithicFlat with internally generated JSON file name ==="
193
194
echo '--- blkdebug ---'
195
# Should work, because bdrv_dirname() works fine with blkdebug
196
-IMGOPTS="subformat=monolithicFlat" _make_test_img 64M
197
+_make_test_img -o "subformat=monolithicFlat" 64M
198
$QEMU_IO -c "open -o driver=$IMGFMT,file.driver=blkdebug,file.image.filename=$TEST_IMG,file.inject-error.0.event=read_aio" \
199
-c info \
200
2>&1 \
201
@@ -XXX,XX +XXX,XX @@ _cleanup_test_img
202
203
echo '--- quorum ---'
204
# Should not work, because bdrv_dirname() does not work with quorum
205
-IMGOPTS="subformat=monolithicFlat" _make_test_img 64M
206
+_make_test_img -o "subformat=monolithicFlat" 64M
207
cp "$TEST_IMG" "$TEST_IMG.orig"
208
209
filename="json:{
210
@@ -XXX,XX +XXX,XX @@ _cleanup_test_img
211
212
echo
213
echo "=== Testing 4TB monolithicFlat creation and IO ==="
214
-IMGOPTS="subformat=monolithicFlat" _make_test_img 4T
215
+_make_test_img -o "subformat=monolithicFlat" 4T
216
_img_info
217
$QEMU_IO -c "write -P 0xa 900G 512" "$TEST_IMG" | _filter_qemu_io
218
$QEMU_IO -c "read -v 900G 1024" "$TEST_IMG" | _filter_qemu_io
219
@@ -XXX,XX +XXX,XX @@ _cleanup_test_img
220
echo
221
echo "=== Testing qemu-img map on extents ==="
222
for fmt in monolithicSparse twoGbMaxExtentSparse; do
223
- IMGOPTS="subformat=$fmt" _make_test_img 31G
224
+ _make_test_img -o "subformat=$fmt" 31G
225
$QEMU_IO -c "write 65024 1k" "$TEST_IMG" | _filter_qemu_io
226
$QEMU_IO -c "write 2147483136 1k" "$TEST_IMG" | _filter_qemu_io
227
$QEMU_IO -c "write 5G 1k" "$TEST_IMG" | _filter_qemu_io
228
diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060
229
index XXXXXXX..XXXXXXX 100755
230
--- a/tests/qemu-iotests/060
231
+++ b/tests/qemu-iotests/060
232
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c 'write 0k 64k' "$BACKING_IMG" | _filter_qemu_io
233
# compat=0.10 is required in order to make the following discard actually
234
# unallocate the sector rather than make it a zero sector - we want COW, after
235
# all.
236
-IMGOPTS='compat=0.10' _make_test_img -b "$BACKING_IMG" 1G
237
+_make_test_img -o 'compat=0.10' -b "$BACKING_IMG" 1G
238
# Write two clusters, the second one enforces creation of an L2 table after
239
# the first data cluster.
240
$QEMU_IO -c 'write 0k 64k' -c 'write 512M 64k' "$TEST_IMG" | _filter_qemu_io
241
@@ -XXX,XX +XXX,XX @@ echo
242
echo "=== Discarding a non-covered in-bounds refblock ==="
243
echo
244
245
-IMGOPTS='refcount_bits=1' _make_test_img 64M
246
+_make_test_img -o 'refcount_bits=1' 64M
247
248
# Pretend there's a refblock somewhere where there is no refblock to
249
# cover it (but the covering refblock has a valid index in the
250
@@ -XXX,XX +XXX,XX @@ echo
251
echo "=== Discarding a refblock covered by an unaligned refblock ==="
252
echo
253
254
-IMGOPTS='refcount_bits=1' _make_test_img 64M
255
+_make_test_img -o 'refcount_bits=1' 64M
256
257
# Same as above
258
poke_file "$TEST_IMG" "$(($rt_offset+8))" "\x00\x00\x00\x10\x00\x00\x00\x00"
259
diff --git a/tests/qemu-iotests/061 b/tests/qemu-iotests/061
260
index XXXXXXX..XXXXXXX 100755
261
--- a/tests/qemu-iotests/061
262
+++ b/tests/qemu-iotests/061
263
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
264
_supported_fmt qcow2
265
_supported_proto file
266
_supported_os Linux
267
+# Conversion between different compat versions can only really work
268
+# with refcount_bits=16
269
+_unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)'
270
271
echo
272
echo "=== Testing version downgrade with zero expansion ==="
273
echo
274
-IMGOPTS="compat=1.1,lazy_refcounts=on" _make_test_img 64M
275
+_make_test_img -o "compat=1.1,lazy_refcounts=on" 64M
276
$QEMU_IO -c "write -z 0 128k" "$TEST_IMG" | _filter_qemu_io
277
$PYTHON qcow2.py "$TEST_IMG" dump-header
278
$QEMU_IMG amend -o "compat=0.10" "$TEST_IMG"
279
@@ -XXX,XX +XXX,XX @@ _check_test_img
280
echo
281
echo "=== Testing version downgrade with zero expansion and 4K cache entries ==="
282
echo
283
-IMGOPTS="compat=1.1,lazy_refcounts=on" _make_test_img 64M
284
+_make_test_img -o "compat=1.1,lazy_refcounts=on" 64M
285
$QEMU_IO -c "write -z 0 128k" "$TEST_IMG" | _filter_qemu_io
286
$QEMU_IO -c "write -z 32M 128k" "$TEST_IMG" | _filter_qemu_io
287
$QEMU_IO -c map "$TEST_IMG" | _filter_qemu_io
288
@@ -XXX,XX +XXX,XX @@ _check_test_img
289
echo
290
echo "=== Testing dirty version downgrade ==="
291
echo
292
-IMGOPTS="compat=1.1,lazy_refcounts=on" _make_test_img 64M
293
+_make_test_img -o "compat=1.1,lazy_refcounts=on" 64M
294
_NO_VALGRIND \
295
$QEMU_IO -c "write -P 0x2a 0 128k" -c flush \
296
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 | _filter_qemu_io
297
@@ -XXX,XX +XXX,XX @@ _check_test_img
298
echo
299
echo "=== Testing version downgrade with unknown compat/autoclear flags ==="
300
echo
301
-IMGOPTS="compat=1.1" _make_test_img 64M
302
+_make_test_img -o "compat=1.1" 64M
303
$PYTHON qcow2.py "$TEST_IMG" set-feature-bit compatible 42
304
$PYTHON qcow2.py "$TEST_IMG" set-feature-bit autoclear 42
305
$PYTHON qcow2.py "$TEST_IMG" dump-header
306
@@ -XXX,XX +XXX,XX @@ _check_test_img
307
echo
308
echo "=== Testing version upgrade and resize ==="
309
echo
310
-IMGOPTS="compat=0.10" _make_test_img 64M
311
+_make_test_img -o "compat=0.10" 64M
312
$QEMU_IO -c "write -P 0x2a 42M 64k" "$TEST_IMG" | _filter_qemu_io
313
$PYTHON qcow2.py "$TEST_IMG" dump-header
314
$QEMU_IMG amend -o "compat=1.1,lazy_refcounts=on,size=128M" "$TEST_IMG"
315
@@ -XXX,XX +XXX,XX @@ _check_test_img
316
echo
317
echo "=== Testing dirty lazy_refcounts=off ==="
318
echo
319
-IMGOPTS="compat=1.1,lazy_refcounts=on" _make_test_img 64M
320
+_make_test_img -o "compat=1.1,lazy_refcounts=on" 64M
321
_NO_VALGRIND \
322
$QEMU_IO -c "write -P 0x2a 0 128k" -c flush \
323
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 | _filter_qemu_io
324
@@ -XXX,XX +XXX,XX @@ _check_test_img
325
echo
326
echo "=== Testing backing file ==="
327
echo
328
-IMGOPTS="compat=1.1" _make_test_img 64M
329
-IMGOPTS="compat=1.1" TEST_IMG="$TEST_IMG.base" _make_test_img 64M
330
+_make_test_img -o "compat=1.1" 64M
331
+TEST_IMG="$TEST_IMG.base" _make_test_img -o "compat=1.1" 64M
332
$QEMU_IO -c "write -P 0x2a 0 128k" "$TEST_IMG.base" | _filter_qemu_io
333
$QEMU_IO -c "read -P 0 0 128k" "$TEST_IMG" | _filter_qemu_io
334
$QEMU_IMG amend -o "backing_file=$TEST_IMG.base,backing_fmt=qcow2" "$TEST_IMG"
335
@@ -XXX,XX +XXX,XX @@ _check_test_img
336
echo
337
echo "=== Testing invalid configurations ==="
338
echo
339
-IMGOPTS="compat=0.10" _make_test_img 64M
340
+_make_test_img -o "compat=0.10" 64M
341
$QEMU_IMG amend -o "lazy_refcounts=on" "$TEST_IMG"
342
$QEMU_IMG amend -o "compat=1.1" "$TEST_IMG" # actually valid
343
$QEMU_IMG amend -o "compat=0.10,lazy_refcounts=on" "$TEST_IMG"
344
@@ -XXX,XX +XXX,XX @@ $QEMU_IMG amend -o "preallocation=on" "$TEST_IMG"
345
echo
346
echo "=== Testing correct handling of unset value ==="
347
echo
348
-IMGOPTS="compat=1.1,cluster_size=1k" _make_test_img 64M
349
+_make_test_img -o "compat=1.1,cluster_size=1k" 64M
350
echo "Should work:"
351
$QEMU_IMG amend -o "lazy_refcounts=on" "$TEST_IMG"
352
echo "Should not work:" # Just to know which of these tests actually fails
353
@@ -XXX,XX +XXX,XX @@ $QEMU_IMG amend -o "cluster_size=64k" "$TEST_IMG"
354
echo
355
echo "=== Testing zero expansion on inactive clusters ==="
356
echo
357
-IMGOPTS="compat=1.1" _make_test_img 64M
358
+_make_test_img -o "compat=1.1" 64M
359
$QEMU_IO -c "write -z 0 128k" "$TEST_IMG" | _filter_qemu_io
360
$QEMU_IMG snapshot -c foo "$TEST_IMG"
361
$QEMU_IO -c "write -P 0x2a 0 128k" "$TEST_IMG" | _filter_qemu_io
362
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c "read -P 0 0 128k" "$TEST_IMG" | _filter_qemu_io
363
echo
364
echo "=== Testing zero expansion on shared L2 table ==="
365
echo
366
-IMGOPTS="compat=1.1" _make_test_img 64M
367
+_make_test_img -o "compat=1.1" 64M
368
$QEMU_IO -c "write -z 0 128k" "$TEST_IMG" | _filter_qemu_io
369
$QEMU_IMG snapshot -c foo "$TEST_IMG"
370
$QEMU_IMG amend -o "compat=0.10" "$TEST_IMG"
371
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c "read -P 0 0 128k" "$TEST_IMG" | _filter_qemu_io
372
echo
373
echo "=== Testing zero expansion on backed image ==="
374
echo
375
-IMGOPTS="compat=1.1" TEST_IMG="$TEST_IMG.base" _make_test_img 64M
376
+TEST_IMG="$TEST_IMG.base" _make_test_img -o "compat=1.1" 64M
377
$QEMU_IO -c "write -P 0x2a 0 128k" "$TEST_IMG.base" | _filter_qemu_io
378
-IMGOPTS="compat=1.1" _make_test_img -b "$TEST_IMG.base" 64M
379
+_make_test_img -o "compat=1.1" -b "$TEST_IMG.base" 64M
380
$QEMU_IO -c "read -P 0x2a 0 128k" -c "write -z 0 64k" "$TEST_IMG" | _filter_qemu_io
381
$QEMU_IMG amend -o "compat=0.10" "$TEST_IMG"
382
_check_test_img
383
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c "read -P 0 0 64k" -c "read -P 0x2a 64k 64k" "$TEST_IMG" | _filter_qe
384
echo
385
echo "=== Testing zero expansion on backed inactive clusters ==="
386
echo
387
-IMGOPTS="compat=1.1" TEST_IMG="$TEST_IMG.base" _make_test_img 64M
388
+TEST_IMG="$TEST_IMG.base" _make_test_img -o "compat=1.1" 64M
389
$QEMU_IO -c "write -P 0x2a 0 128k" "$TEST_IMG.base" | _filter_qemu_io
390
-IMGOPTS="compat=1.1" _make_test_img -b "$TEST_IMG.base" 64M
391
+_make_test_img -o "compat=1.1" -b "$TEST_IMG.base" 64M
392
$QEMU_IO -c "write -z 0 64k" "$TEST_IMG" | _filter_qemu_io
393
$QEMU_IMG snapshot -c foo "$TEST_IMG"
394
$QEMU_IO -c "write -P 0x42 0 128k" "$TEST_IMG" | _filter_qemu_io
395
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c "read -P 0 0 64k" -c "read -P 0x2a 64k 64k" "$TEST_IMG" | _filter_qe
396
echo
397
echo "=== Testing zero expansion on backed image with shared L2 table ==="
398
echo
399
-IMGOPTS="compat=1.1" TEST_IMG="$TEST_IMG.base" _make_test_img 64M
400
+TEST_IMG="$TEST_IMG.base" _make_test_img -o "compat=1.1" 64M
401
$QEMU_IO -c "write -P 0x2a 0 128k" "$TEST_IMG.base" | _filter_qemu_io
402
-IMGOPTS="compat=1.1" _make_test_img -b "$TEST_IMG.base" 64M
403
+_make_test_img -o "compat=1.1" -b "$TEST_IMG.base" 64M
404
$QEMU_IO -c "write -z 0 128k" "$TEST_IMG" | _filter_qemu_io
405
$QEMU_IMG snapshot -c foo "$TEST_IMG"
406
$QEMU_IMG amend -o "compat=0.10" "$TEST_IMG"
407
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c "read -P 0 0 128k" "$TEST_IMG" | _filter_qemu_io
408
echo
409
echo "=== Testing preallocated zero expansion on full image ==="
410
echo
411
-IMGOPTS="compat=1.1" TEST_IMG="$TEST_IMG" _make_test_img 64M
412
+TEST_IMG="$TEST_IMG" _make_test_img -o "compat=1.1" 64M
413
$QEMU_IO -c "write -P 0x2a 0 64M" "$TEST_IMG" -c "write -z 0 64M" | _filter_qemu_io
414
$QEMU_IMG amend -o "compat=0.10" "$TEST_IMG"
415
_check_test_img
416
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c "read -P 0 0 64M" "$TEST_IMG" | _filter_qemu_io
417
echo
418
echo "=== Testing progress report without snapshot ==="
419
echo
420
-IMGOPTS="compat=1.1" TEST_IMG="$TEST_IMG.base" _make_test_img 4G
421
-IMGOPTS="compat=1.1" _make_test_img -b "$TEST_IMG.base" 4G
422
+TEST_IMG="$TEST_IMG.base" _make_test_img -o "compat=1.1" 4G
423
+_make_test_img -o "compat=1.1" -b "$TEST_IMG.base" 4G
424
$QEMU_IO -c "write -z 0 64k" \
425
-c "write -z 1G 64k" \
426
-c "write -z 2G 64k" \
427
@@ -XXX,XX +XXX,XX @@ _check_test_img
428
echo
429
echo "=== Testing progress report with snapshot ==="
430
echo
431
-IMGOPTS="compat=1.1" TEST_IMG="$TEST_IMG.base" _make_test_img 4G
432
-IMGOPTS="compat=1.1" _make_test_img -b "$TEST_IMG.base" 4G
433
+TEST_IMG="$TEST_IMG.base" _make_test_img -o "compat=1.1" 4G
434
+_make_test_img -o "compat=1.1" -b "$TEST_IMG.base" 4G
435
$QEMU_IO -c "write -z 0 64k" \
436
-c "write -z 1G 64k" \
437
-c "write -z 2G 64k" \
438
@@ -XXX,XX +XXX,XX @@ _check_test_img
439
echo
440
echo "=== Testing version downgrade with external data file ==="
441
echo
442
-IMGOPTS="compat=1.1,data_file=$TEST_IMG.data" _make_test_img 64M
443
+_make_test_img -o "compat=1.1,data_file=$TEST_IMG.data" 64M
444
$QEMU_IMG amend -o "compat=0.10" "$TEST_IMG"
445
_img_info --format-specific
446
_check_test_img
447
@@ -XXX,XX +XXX,XX @@ _check_test_img
448
echo
449
echo "=== Try changing the external data file ==="
450
echo
451
-IMGOPTS="compat=1.1" _make_test_img 64M
452
+_make_test_img -o "compat=1.1" 64M
453
$QEMU_IMG amend -o "data_file=foo" "$TEST_IMG"
454
455
echo
456
-IMGOPTS="compat=1.1,data_file=$TEST_IMG.data" _make_test_img 64M
457
+_make_test_img -o "compat=1.1,data_file=$TEST_IMG.data" 64M
458
$QEMU_IMG amend -o "data_file=foo" "$TEST_IMG"
459
_img_info --format-specific
460
TEST_IMG="data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" _img_info --format-specific --image-opts
461
@@ -XXX,XX +XXX,XX @@ TEST_IMG="data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" _img_info -
462
echo
463
echo "=== Clearing and setting data-file-raw ==="
464
echo
465
-IMGOPTS="compat=1.1,data_file=$TEST_IMG.data,data_file_raw=on" _make_test_img 64M
466
+_make_test_img -o "compat=1.1,data_file=$TEST_IMG.data,data_file_raw=on" 64M
467
$QEMU_IMG amend -o "data_file_raw=on" "$TEST_IMG"
468
_img_info --format-specific
469
_check_test_img
470
diff --git a/tests/qemu-iotests/079 b/tests/qemu-iotests/079
471
index XXXXXXX..XXXXXXX 100755
472
--- a/tests/qemu-iotests/079
473
+++ b/tests/qemu-iotests/079
474
@@ -XXX,XX +XXX,XX @@ echo
475
cluster_sizes="16384 32768 65536 131072 262144 524288 1048576 2097152 4194304"
476
477
for s in $cluster_sizes; do
478
- IMGOPTS=$(_optstr_add "$IMGOPTS" "preallocation=metadata,cluster_size=$s") \
479
- _make_test_img 4G
480
+ _make_test_img -o "preallocation=metadata,cluster_size=$s" 4G
481
done
482
483
# success, all done
484
diff --git a/tests/qemu-iotests/106 b/tests/qemu-iotests/106
485
index XXXXXXX..XXXXXXX 100755
486
--- a/tests/qemu-iotests/106
487
+++ b/tests/qemu-iotests/106
488
@@ -XXX,XX +XXX,XX @@ for create_mode in off falloc full; do
489
echo
490
echo "--- create_mode=$create_mode growth_mode=$growth_mode ---"
491
492
- IMGOPTS="preallocation=$create_mode" _make_test_img ${CREATION_SIZE}K
493
+ _make_test_img -o "preallocation=$create_mode" ${CREATION_SIZE}K
494
$QEMU_IMG resize -f "$IMGFMT" --preallocation=$growth_mode "$TEST_IMG" +${GROWTH_SIZE}K
495
496
expected_size=0
497
diff --git a/tests/qemu-iotests/108 b/tests/qemu-iotests/108
498
index XXXXXXX..XXXXXXX 100755
499
--- a/tests/qemu-iotests/108
500
+++ b/tests/qemu-iotests/108
501
@@ -XXX,XX +XXX,XX @@ echo
502
echo '=== Repairing unreferenced data cluster in new refblock area ==='
503
echo
504
505
-IMGOPTS='cluster_size=512' _make_test_img 64M
506
+_make_test_img -o 'cluster_size=512' 64M
507
# Allocate the first 128 kB in the image (first refblock)
508
$QEMU_IO -c 'write 0 0x1b200' "$TEST_IMG" | _filter_qemu_io
509
# should be 131072 == 0x20000
510
diff --git a/tests/qemu-iotests/112 b/tests/qemu-iotests/112
511
index XXXXXXX..XXXXXXX 100755
512
--- a/tests/qemu-iotests/112
513
+++ b/tests/qemu-iotests/112
514
@@ -XXX,XX +XXX,XX @@ echo '=== refcount_bits limits ==='
515
echo
516
517
# Must be positive (non-zero)
518
-IMGOPTS="$IMGOPTS,refcount_bits=0" _make_test_img 64M
519
+_make_test_img -o "refcount_bits=0" 64M
520
# Must be positive (non-negative)
521
-IMGOPTS="$IMGOPTS,refcount_bits=-1" _make_test_img 64M
522
+_make_test_img -o "refcount_bits=-1" 64M
523
# May not exceed 64
524
-IMGOPTS="$IMGOPTS,refcount_bits=128" _make_test_img 64M
525
+_make_test_img -o "refcount_bits=128" 64M
526
# Must be a power of two
527
-IMGOPTS="$IMGOPTS,refcount_bits=42" _make_test_img 64M
528
+_make_test_img -o "refcount_bits=42" 64M
529
530
# 1 is the minimum
531
-IMGOPTS="$IMGOPTS,refcount_bits=1" _make_test_img 64M
532
+_make_test_img -o "refcount_bits=1" 64M
533
print_refcount_bits
534
535
# 64 is the maximum
536
-IMGOPTS="$IMGOPTS,refcount_bits=64" _make_test_img 64M
537
+_make_test_img -o "refcount_bits=64" 64M
538
print_refcount_bits
539
540
# 16 is the default
541
@@ -XXX,XX +XXX,XX @@ echo '=== refcount_bits and compat=0.10 ==='
542
echo
543
544
# Should work
545
-IMGOPTS="$IMGOPTS,compat=0.10,refcount_bits=16" _make_test_img 64M
546
+_make_test_img -o "compat=0.10,refcount_bits=16" 64M
547
print_refcount_bits
548
549
# Should not work
550
-IMGOPTS="$IMGOPTS,compat=0.10,refcount_bits=1" _make_test_img 64M
551
-IMGOPTS="$IMGOPTS,compat=0.10,refcount_bits=64" _make_test_img 64M
552
+_make_test_img -o "compat=0.10,refcount_bits=1" 64M
553
+_make_test_img -o "compat=0.10,refcount_bits=64" 64M
554
555
556
echo
557
echo '=== Snapshot limit on refcount_bits=1 ==='
558
echo
559
560
-IMGOPTS="$IMGOPTS,refcount_bits=1" _make_test_img 64M
561
+_make_test_img -o "refcount_bits=1" 64M
562
print_refcount_bits
563
564
$QEMU_IO -c 'write 0 512' "$TEST_IMG" | _filter_qemu_io
565
@@ -XXX,XX +XXX,XX @@ echo
566
echo '=== Snapshot limit on refcount_bits=2 ==='
567
echo
568
569
-IMGOPTS="$IMGOPTS,refcount_bits=2" _make_test_img 64M
570
+_make_test_img -o "refcount_bits=2" 64M
571
print_refcount_bits
572
573
$QEMU_IO -c 'write 0 512' "$TEST_IMG" | _filter_qemu_io
574
@@ -XXX,XX +XXX,XX @@ echo
575
echo '=== Compressed clusters with refcount_bits=1 ==='
576
echo
577
578
-IMGOPTS="$IMGOPTS,refcount_bits=1" _make_test_img 64M
579
+_make_test_img -o "refcount_bits=1" 64M
580
print_refcount_bits
581
582
# Both should fit into a single host cluster; instead of failing to increase the
583
@@ -XXX,XX +XXX,XX @@ echo
584
echo '=== MSb set in 64 bit refcount ==='
585
echo
586
587
-IMGOPTS="$IMGOPTS,refcount_bits=64" _make_test_img 64M
588
+_make_test_img -o "refcount_bits=64" 64M
589
print_refcount_bits
590
591
$QEMU_IO -c 'write 0 512' "$TEST_IMG" | _filter_qemu_io
592
@@ -XXX,XX +XXX,XX @@ echo
593
echo '=== Snapshot on maximum 64 bit refcount value ==='
594
echo
595
596
-IMGOPTS="$IMGOPTS,refcount_bits=64" _make_test_img 64M
597
+_make_test_img -o "refcount_bits=64" 64M
598
print_refcount_bits
599
600
$QEMU_IO -c 'write 0 512' "$TEST_IMG" | _filter_qemu_io
601
@@ -XXX,XX +XXX,XX @@ echo
602
echo '=== Testing too many references for check ==='
603
echo
604
605
-IMGOPTS="$IMGOPTS,refcount_bits=1" _make_test_img 64M
606
+_make_test_img -o "refcount_bits=1" 64M
607
print_refcount_bits
608
609
# This cluster should be created at 0x50000
610
@@ -XXX,XX +XXX,XX @@ echo
611
echo '=== Multiple walks necessary during amend ==='
612
echo
613
614
-IMGOPTS="$IMGOPTS,refcount_bits=1,cluster_size=512" _make_test_img 64k
615
+_make_test_img -o "refcount_bits=1,cluster_size=512" 64k
616
617
# Cluster 0 is the image header, clusters 1 to 4 are used by the L1 table, a
618
# single L2 table, the reftable and a single refblock. This creates 58 data
619
diff --git a/tests/qemu-iotests/115 b/tests/qemu-iotests/115
620
index XXXXXXX..XXXXXXX 100755
621
--- a/tests/qemu-iotests/115
622
+++ b/tests/qemu-iotests/115
623
@@ -XXX,XX +XXX,XX @@ echo
624
# least 256 MB. We can achieve that by using preallocation=metadata for an image
625
# which has a guest disk size of 256 MB.
626
627
-IMGOPTS="$IMGOPTS,refcount_bits=64,cluster_size=512,preallocation=metadata" \
628
- _make_test_img 256M
629
+_make_test_img -o "refcount_bits=64,cluster_size=512,preallocation=metadata" 256M
630
631
# We know for sure that the L1 and refcount tables do not overlap with any other
632
# structure because the metadata overlap checks would have caught that case.
633
diff --git a/tests/qemu-iotests/121 b/tests/qemu-iotests/121
634
index XXXXXXX..XXXXXXX 100755
635
--- a/tests/qemu-iotests/121
636
+++ b/tests/qemu-iotests/121
637
@@ -XXX,XX +XXX,XX @@ echo
638
# Preallocation speeds up the write operation, but preallocating everything will
639
# destroy the purpose of the write; so preallocate one KB less than what would
640
# cause a reftable growth...
641
-IMGOPTS='preallocation=metadata,cluster_size=1k' _make_test_img 64512K
642
+_make_test_img -o 'preallocation=metadata,cluster_size=1k' 64512K
643
# ...and make the image the desired size afterwards.
644
$QEMU_IMG resize "$TEST_IMG" 65M
645
646
@@ -XXX,XX +XXX,XX @@ echo
647
echo '--- Test 2 ---'
648
echo
649
650
-IMGOPTS='preallocation=metadata,cluster_size=1k' _make_test_img 64513K
651
+_make_test_img -o 'preallocation=metadata,cluster_size=1k' 64513K
652
# This results in an L1 table growth which in turn results in some clusters at
653
# the start of the image becoming free
654
$QEMU_IMG resize "$TEST_IMG" 65M
655
@@ -XXX,XX +XXX,XX @@ echo
656
echo '=== Allocating a new refcount block must not leave holes in the image ==='
657
echo
658
659
-IMGOPTS='cluster_size=512,refcount_bits=16' _make_test_img 1M
660
+_make_test_img -o 'cluster_size=512,refcount_bits=16' 1M
661
662
# This results in an image with 256 used clusters: the qcow2 header,
663
# the refcount table, one refcount block, the L1 table, four L2 tables
664
diff --git a/tests/qemu-iotests/125 b/tests/qemu-iotests/125
665
index XXXXXXX..XXXXXXX 100755
666
--- a/tests/qemu-iotests/125
667
+++ b/tests/qemu-iotests/125
668
@@ -XXX,XX +XXX,XX @@ for GROWTH_SIZE in 16 48 80; do
669
for growth_mode in off metadata falloc full; do
670
echo "--- cluster_size=$cluster_size growth_size=$GROWTH_SIZE create_mode=$create_mode growth_mode=$growth_mode ---"
671
672
- IMGOPTS="preallocation=$create_mode,cluster_size=$cluster_size" _make_test_img ${CREATION_SIZE}
673
+ _make_test_img -o "preallocation=$create_mode,cluster_size=$cluster_size" ${CREATION_SIZE}
674
$QEMU_IMG resize -f "$IMGFMT" --preallocation=$growth_mode "$TEST_IMG" +${GROWTH_SIZE}K
675
676
host_size_0=$(get_image_size_on_host)
677
diff --git a/tests/qemu-iotests/137 b/tests/qemu-iotests/137
678
index XXXXXXX..XXXXXXX 100755
679
--- a/tests/qemu-iotests/137
680
+++ b/tests/qemu-iotests/137
681
@@ -XXX,XX +XXX,XX @@ $QEMU_IO \
682
-c "reopen -o cache-clean-interval=-1" \
683
"$TEST_IMG" | _filter_qemu_io
684
685
-IMGOPTS="cluster_size=256k" _make_test_img 32P
686
+_make_test_img -o "cluster_size=256k" 32P
687
$QEMU_IO \
688
-c "reopen -o l2-cache-entry-size=512,l2-cache-size=1T" \
689
"$TEST_IMG" | _filter_qemu_io
690
diff --git a/tests/qemu-iotests/138 b/tests/qemu-iotests/138
691
index XXXXXXX..XXXXXXX 100755
692
--- a/tests/qemu-iotests/138
693
+++ b/tests/qemu-iotests/138
694
@@ -XXX,XX +XXX,XX @@ echo
695
echo '=== Check on an image with a multiple of 2^32 clusters ==='
696
echo
697
698
-IMGOPTS=$(_optstr_add "$IMGOPTS" "cluster_size=512") \
699
- _make_test_img 512
700
+_make_test_img -o "cluster_size=512" 512
701
702
# Allocate L2 table
703
$QEMU_IO -c 'write 0 512' "$TEST_IMG" | _filter_qemu_io
704
diff --git a/tests/qemu-iotests/175 b/tests/qemu-iotests/175
705
index XXXXXXX..XXXXXXX 100755
706
--- a/tests/qemu-iotests/175
707
+++ b/tests/qemu-iotests/175
708
@@ -XXX,XX +XXX,XX @@ stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $min_block
709
for mode in off full falloc; do
710
echo
711
echo "== creating image with preallocation $mode =="
712
- IMGOPTS=preallocation=$mode _make_test_img $size | _filter_imgfmt
713
+ _make_test_img -o preallocation=$mode $size | _filter_imgfmt
714
stat -c "size=%s, blocks=%b" $TEST_IMG | _filter_blocks $extra_blocks $min_blocks $size
715
done
716
717
diff --git a/tests/qemu-iotests/190 b/tests/qemu-iotests/190
718
index XXXXXXX..XXXXXXX 100755
719
--- a/tests/qemu-iotests/190
720
+++ b/tests/qemu-iotests/190
721
@@ -XXX,XX +XXX,XX @@ _supported_proto file
722
echo "== Huge file =="
723
echo
724
725
-IMGOPTS='cluster_size=2M' _make_test_img 2T
726
+_make_test_img -o 'cluster_size=2M' 2T
727
728
$QEMU_IMG measure -O raw -f qcow2 "$TEST_IMG"
729
$QEMU_IMG measure -O qcow2 -o cluster_size=64k -f qcow2 "$TEST_IMG"
730
diff --git a/tests/qemu-iotests/191 b/tests/qemu-iotests/191
731
index XXXXXXX..XXXXXXX 100755
732
--- a/tests/qemu-iotests/191
733
+++ b/tests/qemu-iotests/191
734
@@ -XXX,XX +XXX,XX @@ echo === Preparing and starting VM ===
735
echo
736
737
TEST_IMG="${TEST_IMG}.base" _make_test_img $size
738
-IMGOPTS=$(_optstr_add "$IMGOPTS" "backing_fmt=$IMGFMT") \
739
- TEST_IMG="${TEST_IMG}.mid" _make_test_img -b "${TEST_IMG}.base"
740
+TEST_IMG="${TEST_IMG}.mid" _make_test_img -o "backing_fmt=$IMGFMT" -b "${TEST_IMG}.base"
741
_make_test_img -b "${TEST_IMG}.mid"
742
TEST_IMG="${TEST_IMG}.ovl2" _make_test_img -b "${TEST_IMG}.mid"
743
744
diff --git a/tests/qemu-iotests/220 b/tests/qemu-iotests/220
745
index XXXXXXX..XXXXXXX 100755
746
--- a/tests/qemu-iotests/220
747
+++ b/tests/qemu-iotests/220
748
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
749
_supported_fmt qcow2
750
_supported_proto file
751
_supported_os Linux
752
+# To use a different refcount width but 16 bits we need compat=1.1
753
+_unsupported_imgopts 'compat=0.10'
754
755
echo "== Creating huge file =="
756
757
@@ -XXX,XX +XXX,XX @@ echo "== Creating huge file =="
758
# of a HUGE (but very sparse) file. tmpfs works, ext4 does not.
759
_require_large_file 513T
760
761
-IMGOPTS='cluster_size=2M,refcount_bits=1' _make_test_img 513T
762
+_make_test_img -o 'cluster_size=2M,refcount_bits=1' 513T
763
764
echo "== Populating refcounts =="
765
# We want an image with 256M refcounts * 2M clusters = 512T referenced.
766
diff --git a/tests/qemu-iotests/243 b/tests/qemu-iotests/243
767
index XXXXXXX..XXXXXXX 100755
768
--- a/tests/qemu-iotests/243
769
+++ b/tests/qemu-iotests/243
770
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
771
_supported_fmt qcow2
772
_supported_proto file
773
_supported_os Linux
774
+# External data files do not work with compat=0.10
775
+_unsupported_imgopts 'compat=0.10'
776
777
for mode in off metadata falloc full; do
778
779
@@ -XXX,XX +XXX,XX @@ for mode in off metadata falloc full; do
780
echo "=== preallocation=$mode ==="
781
echo
782
783
- IMGOPTS="preallocation=$mode" _make_test_img 64M
784
+ _make_test_img -o "preallocation=$mode" 64M
785
786
printf "File size: "
787
du -b $TEST_IMG | cut -f1
788
@@ -XXX,XX +XXX,XX @@ for mode in off metadata falloc full; do
789
echo "=== External data file: preallocation=$mode ==="
790
echo
791
792
- IMGOPTS="data_file=$TEST_IMG.data,preallocation=$mode" _make_test_img 64M
793
+ _make_test_img -o "data_file=$TEST_IMG.data,preallocation=$mode" 64M
794
795
echo -n "qcow2 file size: "
796
du -b $TEST_IMG | cut -f1
797
diff --git a/tests/qemu-iotests/244 b/tests/qemu-iotests/244
798
index XXXXXXX..XXXXXXX 100755
799
--- a/tests/qemu-iotests/244
800
+++ b/tests/qemu-iotests/244
801
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
802
_supported_fmt qcow2
803
_supported_proto file
804
_supported_os Linux
805
+# External data files do not work with compat=0.10
806
+_unsupported_imgopts 'compat=0.10'
807
808
echo
809
echo "=== Create and open image with external data file ==="
810
echo
811
812
echo "With data file name in the image:"
813
-IMGOPTS="data_file=$TEST_IMG.data" _make_test_img 64M
814
+_make_test_img -o "data_file=$TEST_IMG.data" 64M
815
_check_test_img
816
817
$QEMU_IO -c "open $TEST_IMG" -c "read -P 0 0 64k" 2>&1 | _filter_qemu_io | _filter_testdir
818
@@ -XXX,XX +XXX,XX @@ echo
819
echo "=== Standalone image with external data file (efficient) ==="
820
echo
821
822
-IMGOPTS="data_file=$TEST_IMG.data" _make_test_img 64M
823
+_make_test_img -o "data_file=$TEST_IMG.data" 64M
824
825
echo -n "qcow2 file size before I/O: "
826
du -b $TEST_IMG | cut -f1
827
@@ -XXX,XX +XXX,XX @@ echo
828
echo "=== Standalone image with external data file (valid raw) ==="
829
echo
830
831
-IMGOPTS="data_file=$TEST_IMG.data,data_file_raw=on" _make_test_img 64M
832
+_make_test_img -o "data_file=$TEST_IMG.data,data_file_raw=on" 64M
833
834
echo -n "qcow2 file size before I/O: "
835
du -b $TEST_IMG | cut -f1
836
@@ -XXX,XX +XXX,XX @@ echo
837
echo "=== bdrv_co_block_status test for file and offset=0 ==="
838
echo
839
840
-IMGOPTS="data_file=$TEST_IMG.data" _make_test_img 64M
841
+_make_test_img -o "data_file=$TEST_IMG.data" 64M
842
843
$QEMU_IO -c 'write -P 0x11 0 1M' -f $IMGFMT "$TEST_IMG" | _filter_qemu_io
844
$QEMU_IO -c 'read -P 0x11 0 1M' -f $IMGFMT "$TEST_IMG" | _filter_qemu_io
845
diff --git a/tests/qemu-iotests/250 b/tests/qemu-iotests/250
846
index XXXXXXX..XXXXXXX 100755
847
--- a/tests/qemu-iotests/250
848
+++ b/tests/qemu-iotests/250
849
@@ -XXX,XX +XXX,XX @@ disk_usage()
850
}
851
852
size=2100M
853
-IMGOPTS="cluster_size=1M,preallocation=metadata"
854
855
-_make_test_img $size
856
+_make_test_img -o "cluster_size=1M,preallocation=metadata" $size
857
$QEMU_IO -c 'discard 0 10M' -c 'discard 2090M 10M' \
858
-c 'write 2090M 10M' -c 'write 0 10M' "$TEST_IMG" | _filter_qemu_io
859
860
diff --git a/tests/qemu-iotests/265 b/tests/qemu-iotests/265
861
index XXXXXXX..XXXXXXX 100755
862
--- a/tests/qemu-iotests/265
863
+++ b/tests/qemu-iotests/265
864
@@ -XXX,XX +XXX,XX @@ _supported_os Linux
865
echo '--- Writing to the image ---'
866
867
# Reduce cluster size so we get more and quicker I/O
868
-IMGOPTS='cluster_size=4096' _make_test_img 1M
869
+_make_test_img -o 'cluster_size=4096' 1M
870
(for ((kb = 1024 - 4; kb >= 0; kb -= 4)); do \
871
echo "aio_write -P 42 $((kb + 1))k 2k"; \
872
done) \
873
--
874
2.24.1
875
876
diff view generated by jsdifflib
1
Blindly overriding IMGOPTS is suboptimal as this discards user-specified
1
From: Jagannathan Raman <jag.raman@oracle.com>
2
options. Whatever options the test needs should simply be appended.
3
2
4
Some tests do this (with IMGOPTS=$(_optstr_add "$IMGOPTS" "...")), but
3
Initializes the message handler function in the remote process. It is
5
that is cumbersome. It’s simpler to just give _make_test_img an -o
4
called whenever there's an event pending on QIOChannel that registers
6
parameter with which tests can add options.
5
this function.
7
6
8
Some tests actually must override the user-specified options, though,
7
Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
9
for example when creating an image in a different format than the test
8
Signed-off-by: John G Johnson <john.g.johnson@oracle.com>
10
$IMGFMT. For such cases, --no-opts allows clearing the current option
9
Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
11
list.
10
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
11
Message-id: 99d38d8b93753a6409ac2340e858858cda59ab1b.1611938319.git.jag.raman@oracle.com
12
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
---
14
MAINTAINERS | 1 +
15
include/hw/remote/machine.h | 9 ++++++
16
hw/remote/message.c | 57 +++++++++++++++++++++++++++++++++++++
17
hw/remote/meson.build | 1 +
18
4 files changed, 68 insertions(+)
19
create mode 100644 hw/remote/message.c
12
20
13
Signed-off-by: Max Reitz <mreitz@redhat.com>
21
diff --git a/MAINTAINERS b/MAINTAINERS
14
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
22
index XXXXXXX..XXXXXXX 100644
15
Message-id: 20191107163708.833192-10-mreitz@redhat.com
23
--- a/MAINTAINERS
16
Signed-off-by: Max Reitz <mreitz@redhat.com>
24
+++ b/MAINTAINERS
17
---
25
@@ -XXX,XX +XXX,XX @@ F: hw/remote/machine.c
18
tests/qemu-iotests/common.rc | 13 +++++++++++++
26
F: include/hw/remote/machine.h
19
1 file changed, 13 insertions(+)
27
F: hw/remote/mpqemu-link.c
28
F: include/hw/remote/mpqemu-link.h
29
+F: hw/remote/message.c
30
31
Build and test automation
32
-------------------------
33
diff --git a/include/hw/remote/machine.h b/include/hw/remote/machine.h
34
index XXXXXXX..XXXXXXX 100644
35
--- a/include/hw/remote/machine.h
36
+++ b/include/hw/remote/machine.h
37
@@ -XXX,XX +XXX,XX @@
38
#include "qom/object.h"
39
#include "hw/boards.h"
40
#include "hw/pci-host/remote.h"
41
+#include "io/channel.h"
42
43
struct RemoteMachineState {
44
MachineState parent_obj;
45
@@ -XXX,XX +XXX,XX @@ struct RemoteMachineState {
46
RemotePCIHost *host;
47
};
48
49
+/* Used to pass to co-routine device and ioc. */
50
+typedef struct RemoteCommDev {
51
+ PCIDevice *dev;
52
+ QIOChannel *ioc;
53
+} RemoteCommDev;
54
+
55
#define TYPE_REMOTE_MACHINE "x-remote-machine"
56
OBJECT_DECLARE_SIMPLE_TYPE(RemoteMachineState, REMOTE_MACHINE)
57
58
+void coroutine_fn mpqemu_remote_msg_loop_co(void *data);
59
+
60
#endif
61
diff --git a/hw/remote/message.c b/hw/remote/message.c
62
new file mode 100644
63
index XXXXXXX..XXXXXXX
64
--- /dev/null
65
+++ b/hw/remote/message.c
66
@@ -XXX,XX +XXX,XX @@
67
+/*
68
+ * Copyright © 2020, 2021 Oracle and/or its affiliates.
69
+ *
70
+ * This work is licensed under the terms of the GNU GPL-v2, version 2 or later.
71
+ *
72
+ * See the COPYING file in the top-level directory.
73
+ *
74
+ */
75
+
76
+#include "qemu/osdep.h"
77
+#include "qemu-common.h"
78
+
79
+#include "hw/remote/machine.h"
80
+#include "io/channel.h"
81
+#include "hw/remote/mpqemu-link.h"
82
+#include "qapi/error.h"
83
+#include "sysemu/runstate.h"
84
+
85
+void coroutine_fn mpqemu_remote_msg_loop_co(void *data)
86
+{
87
+ g_autofree RemoteCommDev *com = (RemoteCommDev *)data;
88
+ PCIDevice *pci_dev = NULL;
89
+ Error *local_err = NULL;
90
+
91
+ assert(com->ioc);
92
+
93
+ pci_dev = com->dev;
94
+ for (; !local_err;) {
95
+ MPQemuMsg msg = {0};
96
+
97
+ if (!mpqemu_msg_recv(&msg, com->ioc, &local_err)) {
98
+ break;
99
+ }
100
+
101
+ if (!mpqemu_msg_valid(&msg)) {
102
+ error_setg(&local_err, "Received invalid message from proxy"
103
+ "in remote process pid="FMT_pid"",
104
+ getpid());
105
+ break;
106
+ }
107
+
108
+ switch (msg.cmd) {
109
+ default:
110
+ error_setg(&local_err,
111
+ "Unknown command (%d) received for device %s"
112
+ " (pid="FMT_pid")",
113
+ msg.cmd, DEVICE(pci_dev)->id, getpid());
114
+ }
115
+ }
116
+
117
+ if (local_err) {
118
+ error_report_err(local_err);
119
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_ERROR);
120
+ } else {
121
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
122
+ }
123
+}
124
diff --git a/hw/remote/meson.build b/hw/remote/meson.build
125
index XXXXXXX..XXXXXXX 100644
126
--- a/hw/remote/meson.build
127
+++ b/hw/remote/meson.build
128
@@ -XXX,XX +XXX,XX @@ remote_ss = ss.source_set()
129
130
remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('machine.c'))
131
remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('mpqemu-link.c'))
132
+remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('message.c'))
133
134
softmmu_ss.add_all(when: 'CONFIG_MULTIPROCESS', if_true: remote_ss)
135
--
136
2.29.2
20
137
21
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
22
index XXXXXXX..XXXXXXX 100644
23
--- a/tests/qemu-iotests/common.rc
24
+++ b/tests/qemu-iotests/common.rc
25
@@ -XXX,XX +XXX,XX @@ _make_test_img()
26
local use_backing=0
27
local backing_file=""
28
local object_options=""
29
+ local opts_param=false
30
local misc_params=()
31
32
if [ -n "$TEST_IMG_FILE" ]; then
33
@@ -XXX,XX +XXX,XX @@ _make_test_img()
34
if [ "$use_backing" = "1" -a -z "$backing_file" ]; then
35
backing_file=$param
36
continue
37
+ elif $opts_param; then
38
+ optstr=$(_optstr_add "$optstr" "$param")
39
+ opts_param=false
40
+ continue
41
fi
42
43
case "$param" in
44
@@ -XXX,XX +XXX,XX @@ _make_test_img()
45
use_backing=1
46
;;
47
48
+ -o)
49
+ opts_param=true
50
+ ;;
51
+
52
+ --no-opts)
53
+ optstr=""
54
+ ;;
55
+
56
*)
57
misc_params=("${misc_params[@]}" "$param")
58
;;
59
--
60
2.24.1
61
62
diff view generated by jsdifflib
1
We need some way to correlate QAPI BlockPermission values with
1
From: Jagannathan Raman <jag.raman@oracle.com>
2
BLK_PERM_* flags. We could:
2
3
3
Associate the file descriptor for a PCIDevice in remote process with
4
(1) have the same order in the QAPI definition as the the BLK_PERM_*
4
DeviceState object.
5
flags are in LSb-first order. However, then there is no guarantee
5
6
that they actually match (e.g. when someone modifies the QAPI schema
6
Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
7
without thinking of the BLK_PERM_* definitions).
7
Signed-off-by: John G Johnson <john.g.johnson@oracle.com>
8
We could add static assertions, but these would break what’s good
8
Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
9
about this solution, namely its simplicity.
9
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
10
10
Message-id: f405a2ed5d7518b87bea7c59cfdf334d67e5ee51.1611938319.git.jag.raman@oracle.com
11
(2) define the BLK_PERM_* flags based on the BlockPermission values.
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
But this way whenever someone were to modify the QAPI order
13
(perfectly sensible in theory), the BLK_PERM_* values would change.
14
Because these values are used for file locking, this might break
15
file locking between different qemu versions.
16
17
Therefore, go the slightly more cumbersome way: Add a function to
18
translate from the QAPI constants to the BLK_PERM_* flags.
19
20
Signed-off-by: Max Reitz <mreitz@redhat.com>
21
Message-id: 20191108123455.39445-2-mreitz@redhat.com
22
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
23
Signed-off-by: Max Reitz <mreitz@redhat.com>
24
---
12
---
25
block.c | 18 ++++++++++++++++++
13
MAINTAINERS | 1 +
26
include/block/block.h | 1 +
14
hw/remote/remote-obj.c | 203 +++++++++++++++++++++++++++++++++++++++++
27
2 files changed, 19 insertions(+)
15
hw/remote/meson.build | 1 +
28
16
3 files changed, 205 insertions(+)
29
diff --git a/block.c b/block.c
17
create mode 100644 hw/remote/remote-obj.c
18
19
diff --git a/MAINTAINERS b/MAINTAINERS
30
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
31
--- a/block.c
21
--- a/MAINTAINERS
32
+++ b/block.c
22
+++ b/MAINTAINERS
33
@@ -XXX,XX +XXX,XX @@ void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
23
@@ -XXX,XX +XXX,XX @@ F: include/hw/remote/machine.h
34
*nshared = shared;
24
F: hw/remote/mpqemu-link.c
35
}
25
F: include/hw/remote/mpqemu-link.h
36
26
F: hw/remote/message.c
37
+uint64_t bdrv_qapi_perm_to_blk_perm(BlockPermission qapi_perm)
27
+F: hw/remote/remote-obj.c
38
+{
28
39
+ static const uint64_t permissions[] = {
29
Build and test automation
40
+ [BLOCK_PERMISSION_CONSISTENT_READ] = BLK_PERM_CONSISTENT_READ,
30
-------------------------
41
+ [BLOCK_PERMISSION_WRITE] = BLK_PERM_WRITE,
31
diff --git a/hw/remote/remote-obj.c b/hw/remote/remote-obj.c
42
+ [BLOCK_PERMISSION_WRITE_UNCHANGED] = BLK_PERM_WRITE_UNCHANGED,
32
new file mode 100644
43
+ [BLOCK_PERMISSION_RESIZE] = BLK_PERM_RESIZE,
33
index XXXXXXX..XXXXXXX
44
+ [BLOCK_PERMISSION_GRAPH_MOD] = BLK_PERM_GRAPH_MOD,
34
--- /dev/null
35
+++ b/hw/remote/remote-obj.c
36
@@ -XXX,XX +XXX,XX @@
37
+/*
38
+ * Copyright © 2020, 2021 Oracle and/or its affiliates.
39
+ *
40
+ * This work is licensed under the terms of the GNU GPL-v2, version 2 or later.
41
+ *
42
+ * See the COPYING file in the top-level directory.
43
+ *
44
+ */
45
+
46
+#include "qemu/osdep.h"
47
+#include "qemu-common.h"
48
+
49
+#include "qemu/error-report.h"
50
+#include "qemu/notify.h"
51
+#include "qom/object_interfaces.h"
52
+#include "hw/qdev-core.h"
53
+#include "io/channel.h"
54
+#include "hw/qdev-core.h"
55
+#include "hw/remote/machine.h"
56
+#include "io/channel-util.h"
57
+#include "qapi/error.h"
58
+#include "sysemu/sysemu.h"
59
+#include "hw/pci/pci.h"
60
+#include "qemu/sockets.h"
61
+#include "monitor/monitor.h"
62
+
63
+#define TYPE_REMOTE_OBJECT "x-remote-object"
64
+OBJECT_DECLARE_TYPE(RemoteObject, RemoteObjectClass, REMOTE_OBJECT)
65
+
66
+struct RemoteObjectClass {
67
+ ObjectClass parent_class;
68
+
69
+ unsigned int nr_devs;
70
+ unsigned int max_devs;
71
+};
72
+
73
+struct RemoteObject {
74
+ /* private */
75
+ Object parent;
76
+
77
+ Notifier machine_done;
78
+
79
+ int32_t fd;
80
+ char *devid;
81
+
82
+ QIOChannel *ioc;
83
+
84
+ DeviceState *dev;
85
+ DeviceListener listener;
86
+};
87
+
88
+static void remote_object_set_fd(Object *obj, const char *str, Error **errp)
89
+{
90
+ RemoteObject *o = REMOTE_OBJECT(obj);
91
+ int fd = -1;
92
+
93
+ fd = monitor_fd_param(monitor_cur(), str, errp);
94
+ if (fd == -1) {
95
+ error_prepend(errp, "Could not parse remote object fd %s:", str);
96
+ return;
97
+ }
98
+
99
+ if (!fd_is_socket(fd)) {
100
+ error_setg(errp, "File descriptor '%s' is not a socket", str);
101
+ close(fd);
102
+ return;
103
+ }
104
+
105
+ o->fd = fd;
106
+}
107
+
108
+static void remote_object_set_devid(Object *obj, const char *str, Error **errp)
109
+{
110
+ RemoteObject *o = REMOTE_OBJECT(obj);
111
+
112
+ g_free(o->devid);
113
+
114
+ o->devid = g_strdup(str);
115
+}
116
+
117
+static void remote_object_unrealize_listener(DeviceListener *listener,
118
+ DeviceState *dev)
119
+{
120
+ RemoteObject *o = container_of(listener, RemoteObject, listener);
121
+
122
+ if (o->dev == dev) {
123
+ object_unref(OBJECT(o));
124
+ }
125
+}
126
+
127
+static void remote_object_machine_done(Notifier *notifier, void *data)
128
+{
129
+ RemoteObject *o = container_of(notifier, RemoteObject, machine_done);
130
+ DeviceState *dev = NULL;
131
+ QIOChannel *ioc = NULL;
132
+ Coroutine *co = NULL;
133
+ RemoteCommDev *comdev = NULL;
134
+ Error *err = NULL;
135
+
136
+ dev = qdev_find_recursive(sysbus_get_default(), o->devid);
137
+ if (!dev || !object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
138
+ error_report("%s is not a PCI device", o->devid);
139
+ return;
140
+ }
141
+
142
+ ioc = qio_channel_new_fd(o->fd, &err);
143
+ if (!ioc) {
144
+ error_report_err(err);
145
+ return;
146
+ }
147
+ qio_channel_set_blocking(ioc, false, NULL);
148
+
149
+ o->dev = dev;
150
+
151
+ o->listener.unrealize = remote_object_unrealize_listener;
152
+ device_listener_register(&o->listener);
153
+
154
+ /* co-routine should free this. */
155
+ comdev = g_new0(RemoteCommDev, 1);
156
+ *comdev = (RemoteCommDev) {
157
+ .ioc = ioc,
158
+ .dev = PCI_DEVICE(dev),
45
+ };
159
+ };
46
+
160
+
47
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(permissions) != BLOCK_PERMISSION__MAX);
161
+ co = qemu_coroutine_create(mpqemu_remote_msg_loop_co, comdev);
48
+ QEMU_BUILD_BUG_ON(1UL << ARRAY_SIZE(permissions) != BLK_PERM_ALL + 1);
162
+ qemu_coroutine_enter(co);
49
+
163
+}
50
+ assert(qapi_perm < BLOCK_PERMISSION__MAX);
164
+
51
+
165
+static void remote_object_init(Object *obj)
52
+ return permissions[qapi_perm];
166
+{
53
+}
167
+ RemoteObjectClass *k = REMOTE_OBJECT_GET_CLASS(obj);
54
+
168
+ RemoteObject *o = REMOTE_OBJECT(obj);
55
static void bdrv_replace_child_noperm(BdrvChild *child,
169
+
56
BlockDriverState *new_bs)
170
+ if (k->nr_devs >= k->max_devs) {
57
{
171
+ error_report("Reached maximum number of devices: %u", k->max_devs);
58
diff --git a/include/block/block.h b/include/block/block.h
172
+ return;
173
+ }
174
+
175
+ o->ioc = NULL;
176
+ o->fd = -1;
177
+ o->devid = NULL;
178
+
179
+ k->nr_devs++;
180
+
181
+ o->machine_done.notify = remote_object_machine_done;
182
+ qemu_add_machine_init_done_notifier(&o->machine_done);
183
+}
184
+
185
+static void remote_object_finalize(Object *obj)
186
+{
187
+ RemoteObjectClass *k = REMOTE_OBJECT_GET_CLASS(obj);
188
+ RemoteObject *o = REMOTE_OBJECT(obj);
189
+
190
+ device_listener_unregister(&o->listener);
191
+
192
+ if (o->ioc) {
193
+ qio_channel_shutdown(o->ioc, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
194
+ qio_channel_close(o->ioc, NULL);
195
+ }
196
+
197
+ object_unref(OBJECT(o->ioc));
198
+
199
+ k->nr_devs--;
200
+ g_free(o->devid);
201
+}
202
+
203
+static void remote_object_class_init(ObjectClass *klass, void *data)
204
+{
205
+ RemoteObjectClass *k = REMOTE_OBJECT_CLASS(klass);
206
+
207
+ /*
208
+ * Limit number of supported devices to 1. This is done to avoid devices
209
+ * from one VM accessing the RAM of another VM. This is done until we
210
+ * start using separate address spaces for individual devices.
211
+ */
212
+ k->max_devs = 1;
213
+ k->nr_devs = 0;
214
+
215
+ object_class_property_add_str(klass, "fd", NULL, remote_object_set_fd);
216
+ object_class_property_add_str(klass, "devid", NULL,
217
+ remote_object_set_devid);
218
+}
219
+
220
+static const TypeInfo remote_object_info = {
221
+ .name = TYPE_REMOTE_OBJECT,
222
+ .parent = TYPE_OBJECT,
223
+ .instance_size = sizeof(RemoteObject),
224
+ .instance_init = remote_object_init,
225
+ .instance_finalize = remote_object_finalize,
226
+ .class_size = sizeof(RemoteObjectClass),
227
+ .class_init = remote_object_class_init,
228
+ .interfaces = (InterfaceInfo[]) {
229
+ { TYPE_USER_CREATABLE },
230
+ { }
231
+ }
232
+};
233
+
234
+static void register_types(void)
235
+{
236
+ type_register_static(&remote_object_info);
237
+}
238
+
239
+type_init(register_types);
240
diff --git a/hw/remote/meson.build b/hw/remote/meson.build
59
index XXXXXXX..XXXXXXX 100644
241
index XXXXXXX..XXXXXXX 100644
60
--- a/include/block/block.h
242
--- a/hw/remote/meson.build
61
+++ b/include/block/block.h
243
+++ b/hw/remote/meson.build
62
@@ -XXX,XX +XXX,XX @@ enum {
244
@@ -XXX,XX +XXX,XX @@ remote_ss = ss.source_set()
63
};
245
remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('machine.c'))
64
246
remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('mpqemu-link.c'))
65
char *bdrv_perm_names(uint64_t perm);
247
remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('message.c'))
66
+uint64_t bdrv_qapi_perm_to_blk_perm(BlockPermission qapi_perm);
248
+remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('remote-obj.c'))
67
249
68
/* disk I/O throttling */
250
softmmu_ss.add_all(when: 'CONFIG_MULTIPROCESS', if_true: remote_ss)
69
void bdrv_init(void);
70
--
251
--
71
2.24.1
252
2.29.2
72
253
73
diff view generated by jsdifflib
1
We can save some LoC in xdbg_graph_add_edge() by using
1
From: Jagannathan Raman <jag.raman@oracle.com>
2
bdrv_qapi_perm_to_blk_perm().
2
3
3
SyncSysMemMsg message format is defined. It is used to send
4
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
file descriptors of the RAM regions to remote device.
5
Message-id: 20191108123455.39445-3-mreitz@redhat.com
5
RAM on the remote device is configured with a set of file descriptors.
6
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
Old RAM regions are deleted and new regions, each with an fd, is
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
added to the RAM.
8
9
Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
10
Signed-off-by: John G Johnson <john.g.johnson@oracle.com>
11
Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
12
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
13
Message-id: 7d2d1831d812e85f681e7a8ab99e032cf4704689.1611938319.git.jag.raman@oracle.com
14
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
8
---
15
---
9
block.c | 29 ++++++++---------------------
16
MAINTAINERS | 2 +
10
1 file changed, 8 insertions(+), 21 deletions(-)
17
include/hw/remote/memory.h | 19 ++++++++++
11
18
include/hw/remote/mpqemu-link.h | 10 +++++
12
diff --git a/block.c b/block.c
19
hw/remote/memory.c | 65 +++++++++++++++++++++++++++++++++
13
index XXXXXXX..XXXXXXX 100644
20
hw/remote/mpqemu-link.c | 11 ++++++
14
--- a/block.c
21
hw/remote/meson.build | 2 +
15
+++ b/block.c
22
6 files changed, 109 insertions(+)
16
@@ -XXX,XX +XXX,XX @@ static void xdbg_graph_add_node(XDbgBlockGraphConstructor *gr, void *node,
23
create mode 100644 include/hw/remote/memory.h
17
static void xdbg_graph_add_edge(XDbgBlockGraphConstructor *gr, void *parent,
24
create mode 100644 hw/remote/memory.c
18
const BdrvChild *child)
25
19
{
26
diff --git a/MAINTAINERS b/MAINTAINERS
20
- typedef struct {
27
index XXXXXXX..XXXXXXX 100644
21
- unsigned int flag;
28
--- a/MAINTAINERS
22
- BlockPermission num;
29
+++ b/MAINTAINERS
23
- } PermissionMap;
30
@@ -XXX,XX +XXX,XX @@ F: hw/remote/mpqemu-link.c
24
-
31
F: include/hw/remote/mpqemu-link.h
25
- static const PermissionMap permissions[] = {
32
F: hw/remote/message.c
26
- { BLK_PERM_CONSISTENT_READ, BLOCK_PERMISSION_CONSISTENT_READ },
33
F: hw/remote/remote-obj.c
27
- { BLK_PERM_WRITE, BLOCK_PERMISSION_WRITE },
34
+F: include/hw/remote/memory.h
28
- { BLK_PERM_WRITE_UNCHANGED, BLOCK_PERMISSION_WRITE_UNCHANGED },
35
+F: hw/remote/memory.c
29
- { BLK_PERM_RESIZE, BLOCK_PERMISSION_RESIZE },
36
30
- { BLK_PERM_GRAPH_MOD, BLOCK_PERMISSION_GRAPH_MOD },
37
Build and test automation
31
- { 0, 0 }
38
-------------------------
32
- };
39
diff --git a/include/hw/remote/memory.h b/include/hw/remote/memory.h
33
- const PermissionMap *p;
40
new file mode 100644
34
+ BlockPermission qapi_perm;
41
index XXXXXXX..XXXXXXX
35
XDbgBlockGraphEdge *edge;
42
--- /dev/null
36
43
+++ b/include/hw/remote/memory.h
37
- QEMU_BUILD_BUG_ON(1UL << (ARRAY_SIZE(permissions) - 1) != BLK_PERM_ALL + 1);
44
@@ -XXX,XX +XXX,XX @@
38
-
45
+/*
39
edge = g_new0(XDbgBlockGraphEdge, 1);
46
+ * Memory manager for remote device
40
47
+ *
41
edge->parent = xdbg_graph_node_num(gr, parent);
48
+ * Copyright © 2018, 2021 Oracle and/or its affiliates.
42
edge->child = xdbg_graph_node_num(gr, child->bs);
49
+ *
43
edge->name = g_strdup(child->name);
50
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
44
51
+ * See the COPYING file in the top-level directory.
45
- for (p = permissions; p->flag; p++) {
52
+ *
46
- if (p->flag & child->perm) {
53
+ */
47
- QAPI_LIST_ADD(edge->perm, p->num);
54
+
48
+ for (qapi_perm = 0; qapi_perm < BLOCK_PERMISSION__MAX; qapi_perm++) {
55
+#ifndef REMOTE_MEMORY_H
49
+ uint64_t flag = bdrv_qapi_perm_to_blk_perm(qapi_perm);
56
+#define REMOTE_MEMORY_H
50
+
57
+
51
+ if (flag & child->perm) {
58
+#include "exec/hwaddr.h"
52
+ QAPI_LIST_ADD(edge->perm, qapi_perm);
59
+#include "hw/remote/mpqemu-link.h"
53
}
60
+
54
- if (p->flag & child->shared_perm) {
61
+void remote_sysmem_reconfig(MPQemuMsg *msg, Error **errp);
55
- QAPI_LIST_ADD(edge->shared_perm, p->num);
62
+
56
+ if (flag & child->shared_perm) {
63
+#endif
57
+ QAPI_LIST_ADD(edge->shared_perm, qapi_perm);
64
diff --git a/include/hw/remote/mpqemu-link.h b/include/hw/remote/mpqemu-link.h
65
index XXXXXXX..XXXXXXX 100644
66
--- a/include/hw/remote/mpqemu-link.h
67
+++ b/include/hw/remote/mpqemu-link.h
68
@@ -XXX,XX +XXX,XX @@
69
#include "qom/object.h"
70
#include "qemu/thread.h"
71
#include "io/channel.h"
72
+#include "exec/hwaddr.h"
73
74
#define REMOTE_MAX_FDS 8
75
76
@@ -XXX,XX +XXX,XX @@
77
*
78
*/
79
typedef enum {
80
+ MPQEMU_CMD_SYNC_SYSMEM,
81
MPQEMU_CMD_MAX,
82
} MPQemuCmd;
83
84
+typedef struct {
85
+ hwaddr gpas[REMOTE_MAX_FDS];
86
+ uint64_t sizes[REMOTE_MAX_FDS];
87
+ off_t offsets[REMOTE_MAX_FDS];
88
+} SyncSysmemMsg;
89
+
90
/**
91
* MPQemuMsg:
92
* @cmd: The remote command
93
@@ -XXX,XX +XXX,XX @@ typedef enum {
94
* MPQemuMsg Format of the message sent to the remote device from QEMU.
95
*
96
*/
97
+
98
typedef struct {
99
int cmd;
100
size_t size;
101
102
union {
103
uint64_t u64;
104
+ SyncSysmemMsg sync_sysmem;
105
} data;
106
107
int fds[REMOTE_MAX_FDS];
108
diff --git a/hw/remote/memory.c b/hw/remote/memory.c
109
new file mode 100644
110
index XXXXXXX..XXXXXXX
111
--- /dev/null
112
+++ b/hw/remote/memory.c
113
@@ -XXX,XX +XXX,XX @@
114
+/*
115
+ * Memory manager for remote device
116
+ *
117
+ * Copyright © 2018, 2021 Oracle and/or its affiliates.
118
+ *
119
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
120
+ * See the COPYING file in the top-level directory.
121
+ *
122
+ */
123
+
124
+#include "qemu/osdep.h"
125
+#include "qemu-common.h"
126
+
127
+#include "hw/remote/memory.h"
128
+#include "exec/address-spaces.h"
129
+#include "exec/ram_addr.h"
130
+#include "qapi/error.h"
131
+
132
+static void remote_sysmem_reset(void)
133
+{
134
+ MemoryRegion *sysmem, *subregion, *next;
135
+
136
+ sysmem = get_system_memory();
137
+
138
+ QTAILQ_FOREACH_SAFE(subregion, &sysmem->subregions, subregions_link, next) {
139
+ if (subregion->ram) {
140
+ memory_region_del_subregion(sysmem, subregion);
141
+ object_unparent(OBJECT(subregion));
142
+ }
143
+ }
144
+}
145
+
146
+void remote_sysmem_reconfig(MPQemuMsg *msg, Error **errp)
147
+{
148
+ ERRP_GUARD();
149
+ SyncSysmemMsg *sysmem_info = &msg->data.sync_sysmem;
150
+ MemoryRegion *sysmem, *subregion;
151
+ static unsigned int suffix;
152
+ int region;
153
+
154
+ sysmem = get_system_memory();
155
+
156
+ remote_sysmem_reset();
157
+
158
+ for (region = 0; region < msg->num_fds; region++) {
159
+ g_autofree char *name;
160
+ subregion = g_new(MemoryRegion, 1);
161
+ name = g_strdup_printf("remote-mem-%u", suffix++);
162
+ memory_region_init_ram_from_fd(subregion, NULL,
163
+ name, sysmem_info->sizes[region],
164
+ true, msg->fds[region],
165
+ sysmem_info->offsets[region],
166
+ errp);
167
+
168
+ if (*errp) {
169
+ g_free(subregion);
170
+ remote_sysmem_reset();
171
+ return;
172
+ }
173
+
174
+ memory_region_add_subregion(sysmem, sysmem_info->gpas[region],
175
+ subregion);
176
+
177
+ }
178
+}
179
diff --git a/hw/remote/mpqemu-link.c b/hw/remote/mpqemu-link.c
180
index XXXXXXX..XXXXXXX 100644
181
--- a/hw/remote/mpqemu-link.c
182
+++ b/hw/remote/mpqemu-link.c
183
@@ -XXX,XX +XXX,XX @@ bool mpqemu_msg_valid(MPQemuMsg *msg)
58
}
184
}
59
}
185
}
60
186
187
+ /* Verify message specific fields. */
188
+ switch (msg->cmd) {
189
+ case MPQEMU_CMD_SYNC_SYSMEM:
190
+ if (msg->num_fds == 0 || msg->size != sizeof(SyncSysmemMsg)) {
191
+ return false;
192
+ }
193
+ break;
194
+ default:
195
+ break;
196
+ }
197
+
198
return true;
199
}
200
diff --git a/hw/remote/meson.build b/hw/remote/meson.build
201
index XXXXXXX..XXXXXXX 100644
202
--- a/hw/remote/meson.build
203
+++ b/hw/remote/meson.build
204
@@ -XXX,XX +XXX,XX @@ remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('mpqemu-link.c'))
205
remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('message.c'))
206
remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('remote-obj.c'))
207
208
+specific_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('memory.c'))
209
+
210
softmmu_ss.add_all(when: 'CONFIG_MULTIPROCESS', if_true: remote_ss)
61
--
211
--
62
2.24.1
212
2.29.2
63
213
64
diff view generated by jsdifflib
1
From: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
1
From: Elena Ufimtseva <elena.ufimtseva@oracle.com>
2
2
3
Allow writing all the data compressed through the filter driver.
3
Defines a PCI Device proxy object as a child of TYPE_PCI_DEVICE.
4
The written data will be aligned by the cluster size.
5
Based on the QEMU current implementation, that data can be written to
6
unallocated clusters only. May be used for a backup job.
7
4
8
Suggested-by: Max Reitz <mreitz@redhat.com>
5
Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
9
Signed-off-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
6
Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
10
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Signed-off-by: John G Johnson <john.g.johnson@oracle.com>
11
Message-id: 1575288906-551879-2-git-send-email-andrey.shinkevich@virtuozzo.com
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
12
[mreitz: Replace NULL bdrv_get_format_name() by "(no format)"]
9
Message-id: b5186ebfedf8e557044d09a768846c59230ad3a7.1611938319.git.jag.raman@oracle.com
13
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
14
---
11
---
15
block/Makefile.objs | 1 +
12
MAINTAINERS | 2 +
16
block/filter-compress.c | 168 ++++++++++++++++++++++++++++++++++++++++
13
include/hw/remote/proxy.h | 33 +++++++++++++
17
qapi/block-core.json | 10 ++-
14
hw/remote/proxy.c | 99 +++++++++++++++++++++++++++++++++++++++
18
3 files changed, 175 insertions(+), 4 deletions(-)
15
hw/remote/meson.build | 1 +
19
create mode 100644 block/filter-compress.c
16
4 files changed, 135 insertions(+)
17
create mode 100644 include/hw/remote/proxy.h
18
create mode 100644 hw/remote/proxy.c
20
19
21
diff --git a/block/Makefile.objs b/block/Makefile.objs
20
diff --git a/MAINTAINERS b/MAINTAINERS
22
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
23
--- a/block/Makefile.objs
22
--- a/MAINTAINERS
24
+++ b/block/Makefile.objs
23
+++ b/MAINTAINERS
25
@@ -XXX,XX +XXX,XX @@ block-obj-y += crypto.o
24
@@ -XXX,XX +XXX,XX @@ F: hw/remote/message.c
26
25
F: hw/remote/remote-obj.c
27
block-obj-y += aio_task.o
26
F: include/hw/remote/memory.h
28
block-obj-y += backup-top.o
27
F: hw/remote/memory.c
29
+block-obj-y += filter-compress.o
28
+F: hw/remote/proxy.c
30
29
+F: include/hw/remote/proxy.h
31
common-obj-y += stream.o
30
32
31
Build and test automation
33
diff --git a/block/filter-compress.c b/block/filter-compress.c
32
-------------------------
33
diff --git a/include/hw/remote/proxy.h b/include/hw/remote/proxy.h
34
new file mode 100644
34
new file mode 100644
35
index XXXXXXX..XXXXXXX
35
index XXXXXXX..XXXXXXX
36
--- /dev/null
36
--- /dev/null
37
+++ b/block/filter-compress.c
37
+++ b/include/hw/remote/proxy.h
38
@@ -XXX,XX +XXX,XX @@
38
@@ -XXX,XX +XXX,XX @@
39
+/*
39
+/*
40
+ * Compress filter block driver
40
+ * Copyright © 2018, 2021 Oracle and/or its affiliates.
41
+ *
41
+ *
42
+ * Copyright (c) 2019 Virtuozzo International GmbH
42
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
43
+ * See the COPYING file in the top-level directory.
43
+ *
44
+ *
44
+ * Author:
45
+ */
45
+ * Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
46
+
46
+ * (based on block/copy-on-read.c by Max Reitz)
47
+#ifndef PROXY_H
48
+#define PROXY_H
49
+
50
+#include "hw/pci/pci.h"
51
+#include "io/channel.h"
52
+
53
+#define TYPE_PCI_PROXY_DEV "x-pci-proxy-dev"
54
+OBJECT_DECLARE_SIMPLE_TYPE(PCIProxyDev, PCI_PROXY_DEV)
55
+
56
+struct PCIProxyDev {
57
+ PCIDevice parent_dev;
58
+ char *fd;
59
+
60
+ /*
61
+ * Mutex used to protect the QIOChannel fd from
62
+ * the concurrent access by the VCPUs since proxy
63
+ * blocks while awaiting for the replies from the
64
+ * process remote.
65
+ */
66
+ QemuMutex io_mutex;
67
+ QIOChannel *ioc;
68
+ Error *migration_blocker;
69
+};
70
+
71
+#endif /* PROXY_H */
72
diff --git a/hw/remote/proxy.c b/hw/remote/proxy.c
73
new file mode 100644
74
index XXXXXXX..XXXXXXX
75
--- /dev/null
76
+++ b/hw/remote/proxy.c
77
@@ -XXX,XX +XXX,XX @@
78
+/*
79
+ * Copyright © 2018, 2021 Oracle and/or its affiliates.
47
+ *
80
+ *
48
+ * This program is free software; you can redistribute it and/or
81
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
49
+ * modify it under the terms of the GNU General Public License as
82
+ * See the COPYING file in the top-level directory.
50
+ * published by the Free Software Foundation; either version 2 or
51
+ * (at your option) any later version of the License.
52
+ *
83
+ *
53
+ * This program is distributed in the hope that it will be useful,
54
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
55
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
56
+ * GNU General Public License for more details.
57
+ *
58
+ * You should have received a copy of the GNU General Public License
59
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
60
+ */
84
+ */
61
+
85
+
62
+#include "qemu/osdep.h"
86
+#include "qemu/osdep.h"
63
+#include "block/block_int.h"
87
+#include "qemu-common.h"
64
+#include "qemu/module.h"
88
+
89
+#include "hw/remote/proxy.h"
90
+#include "hw/pci/pci.h"
65
+#include "qapi/error.h"
91
+#include "qapi/error.h"
92
+#include "io/channel-util.h"
93
+#include "hw/qdev-properties.h"
94
+#include "monitor/monitor.h"
95
+#include "migration/blocker.h"
96
+#include "qemu/sockets.h"
66
+
97
+
98
+static void pci_proxy_dev_realize(PCIDevice *device, Error **errp)
99
+{
100
+ ERRP_GUARD();
101
+ PCIProxyDev *dev = PCI_PROXY_DEV(device);
102
+ int fd;
67
+
103
+
68
+static int compress_open(BlockDriverState *bs, QDict *options, int flags,
104
+ if (!dev->fd) {
69
+ Error **errp)
105
+ error_setg(errp, "fd parameter not specified for %s",
70
+{
106
+ DEVICE(device)->id);
71
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, false,
72
+ errp);
73
+ if (!bs->file) {
74
+ return -EINVAL;
75
+ }
76
+
77
+ if (!bs->file->bs->drv || !block_driver_can_compress(bs->file->bs->drv)) {
78
+ error_setg(errp,
79
+ "Compression is not supported for underlying format: %s",
80
+ bdrv_get_format_name(bs->file->bs) ?: "(no format)");
81
+
82
+ return -ENOTSUP;
83
+ }
84
+
85
+ bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED |
86
+ (BDRV_REQ_FUA & bs->file->bs->supported_write_flags);
87
+
88
+ bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
89
+ ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) &
90
+ bs->file->bs->supported_zero_flags);
91
+
92
+ return 0;
93
+}
94
+
95
+
96
+static int64_t compress_getlength(BlockDriverState *bs)
97
+{
98
+ return bdrv_getlength(bs->file->bs);
99
+}
100
+
101
+
102
+static int coroutine_fn compress_co_preadv_part(BlockDriverState *bs,
103
+ uint64_t offset, uint64_t bytes,
104
+ QEMUIOVector *qiov,
105
+ size_t qiov_offset,
106
+ int flags)
107
+{
108
+ return bdrv_co_preadv_part(bs->file, offset, bytes, qiov, qiov_offset,
109
+ flags);
110
+}
111
+
112
+
113
+static int coroutine_fn compress_co_pwritev_part(BlockDriverState *bs,
114
+ uint64_t offset,
115
+ uint64_t bytes,
116
+ QEMUIOVector *qiov,
117
+ size_t qiov_offset, int flags)
118
+{
119
+ return bdrv_co_pwritev_part(bs->file, offset, bytes, qiov, qiov_offset,
120
+ flags | BDRV_REQ_WRITE_COMPRESSED);
121
+}
122
+
123
+
124
+static int coroutine_fn compress_co_pwrite_zeroes(BlockDriverState *bs,
125
+ int64_t offset, int bytes,
126
+ BdrvRequestFlags flags)
127
+{
128
+ return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
129
+}
130
+
131
+
132
+static int coroutine_fn compress_co_pdiscard(BlockDriverState *bs,
133
+ int64_t offset, int bytes)
134
+{
135
+ return bdrv_co_pdiscard(bs->file, offset, bytes);
136
+}
137
+
138
+
139
+static void compress_refresh_limits(BlockDriverState *bs, Error **errp)
140
+{
141
+ BlockDriverInfo bdi;
142
+ int ret;
143
+
144
+ if (!bs->file) {
145
+ return;
107
+ return;
146
+ }
108
+ }
147
+
109
+
148
+ ret = bdrv_get_info(bs->file->bs, &bdi);
110
+ fd = monitor_fd_param(monitor_cur(), dev->fd, errp);
149
+ if (ret < 0 || bdi.cluster_size == 0) {
111
+ if (fd == -1) {
112
+ error_prepend(errp, "proxy: unable to parse fd %s: ", dev->fd);
150
+ return;
113
+ return;
151
+ }
114
+ }
152
+
115
+
153
+ bs->bl.request_alignment = bdi.cluster_size;
116
+ if (!fd_is_socket(fd)) {
117
+ error_setg(errp, "proxy: fd %d is not a socket", fd);
118
+ close(fd);
119
+ return;
120
+ }
121
+
122
+ dev->ioc = qio_channel_new_fd(fd, errp);
123
+
124
+ error_setg(&dev->migration_blocker, "%s does not support migration",
125
+ TYPE_PCI_PROXY_DEV);
126
+ migrate_add_blocker(dev->migration_blocker, errp);
127
+
128
+ qemu_mutex_init(&dev->io_mutex);
129
+ qio_channel_set_blocking(dev->ioc, true, NULL);
154
+}
130
+}
155
+
131
+
132
+static void pci_proxy_dev_exit(PCIDevice *pdev)
133
+{
134
+ PCIProxyDev *dev = PCI_PROXY_DEV(pdev);
156
+
135
+
157
+static void compress_eject(BlockDriverState *bs, bool eject_flag)
136
+ if (dev->ioc) {
158
+{
137
+ qio_channel_close(dev->ioc, NULL);
159
+ bdrv_eject(bs->file->bs, eject_flag);
138
+ }
139
+
140
+ migrate_del_blocker(dev->migration_blocker);
141
+
142
+ error_free(dev->migration_blocker);
160
+}
143
+}
161
+
144
+
145
+static Property proxy_properties[] = {
146
+ DEFINE_PROP_STRING("fd", PCIProxyDev, fd),
147
+ DEFINE_PROP_END_OF_LIST(),
148
+};
162
+
149
+
163
+static void compress_lock_medium(BlockDriverState *bs, bool locked)
150
+static void pci_proxy_dev_class_init(ObjectClass *klass, void *data)
164
+{
151
+{
165
+ bdrv_lock_medium(bs->file->bs, locked);
152
+ DeviceClass *dc = DEVICE_CLASS(klass);
153
+ PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
154
+
155
+ k->realize = pci_proxy_dev_realize;
156
+ k->exit = pci_proxy_dev_exit;
157
+ device_class_set_props(dc, proxy_properties);
166
+}
158
+}
167
+
159
+
160
+static const TypeInfo pci_proxy_dev_type_info = {
161
+ .name = TYPE_PCI_PROXY_DEV,
162
+ .parent = TYPE_PCI_DEVICE,
163
+ .instance_size = sizeof(PCIProxyDev),
164
+ .class_init = pci_proxy_dev_class_init,
165
+ .interfaces = (InterfaceInfo[]) {
166
+ { INTERFACE_CONVENTIONAL_PCI_DEVICE },
167
+ { },
168
+ },
169
+};
168
+
170
+
169
+static bool compress_recurse_is_first_non_filter(BlockDriverState *bs,
171
+static void pci_proxy_dev_register_types(void)
170
+ BlockDriverState *candidate)
171
+{
172
+{
172
+ return bdrv_recurse_is_first_non_filter(bs->file->bs, candidate);
173
+ type_register_static(&pci_proxy_dev_type_info);
173
+}
174
+}
174
+
175
+
175
+
176
+type_init(pci_proxy_dev_register_types)
176
+static BlockDriver bdrv_compress = {
177
diff --git a/hw/remote/meson.build b/hw/remote/meson.build
177
+ .format_name = "compress",
178
+
179
+ .bdrv_open = compress_open,
180
+ .bdrv_child_perm = bdrv_filter_default_perms,
181
+
182
+ .bdrv_getlength = compress_getlength,
183
+
184
+ .bdrv_co_preadv_part = compress_co_preadv_part,
185
+ .bdrv_co_pwritev_part = compress_co_pwritev_part,
186
+ .bdrv_co_pwrite_zeroes = compress_co_pwrite_zeroes,
187
+ .bdrv_co_pdiscard = compress_co_pdiscard,
188
+ .bdrv_refresh_limits = compress_refresh_limits,
189
+
190
+ .bdrv_eject = compress_eject,
191
+ .bdrv_lock_medium = compress_lock_medium,
192
+
193
+ .bdrv_co_block_status = bdrv_co_block_status_from_file,
194
+
195
+ .bdrv_recurse_is_first_non_filter = compress_recurse_is_first_non_filter,
196
+
197
+ .has_variable_length = true,
198
+ .is_filter = true,
199
+};
200
+
201
+static void bdrv_compress_init(void)
202
+{
203
+ bdrv_register(&bdrv_compress);
204
+}
205
+
206
+block_init(bdrv_compress_init);
207
diff --git a/qapi/block-core.json b/qapi/block-core.json
208
index XXXXXXX..XXXXXXX 100644
178
index XXXXXXX..XXXXXXX 100644
209
--- a/qapi/block-core.json
179
--- a/hw/remote/meson.build
210
+++ b/qapi/block-core.json
180
+++ b/hw/remote/meson.build
211
@@ -XXX,XX +XXX,XX @@
181
@@ -XXX,XX +XXX,XX @@ remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('machine.c'))
212
# @copy-on-read: Since 3.0
182
remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('mpqemu-link.c'))
213
# @blklogwrites: Since 3.0
183
remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('message.c'))
214
# @blkreplay: Since 4.2
184
remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('remote-obj.c'))
215
+# @compress: Since 5.0
185
+remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('proxy.c'))
216
#
186
217
# Since: 2.9
187
specific_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('memory.c'))
218
##
188
219
{ 'enum': 'BlockdevDriver',
220
'data': [ 'blkdebug', 'blklogwrites', 'blkreplay', 'blkverify', 'bochs',
221
- 'cloop', 'copy-on-read', 'dmg', 'file', 'ftp', 'ftps', 'gluster',
222
- 'host_cdrom', 'host_device', 'http', 'https', 'iscsi', 'luks',
223
- 'nbd', 'nfs', 'null-aio', 'null-co', 'nvme', 'parallels', 'qcow',
224
- 'qcow2', 'qed', 'quorum', 'raw', 'rbd',
225
+ 'cloop', 'compress', 'copy-on-read', 'dmg', 'file', 'ftp', 'ftps',
226
+ 'gluster', 'host_cdrom', 'host_device', 'http', 'https', 'iscsi',
227
+ 'luks', 'nbd', 'nfs', 'null-aio', 'null-co', 'nvme', 'parallels',
228
+ 'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'rbd',
229
{ 'name': 'replication', 'if': 'defined(CONFIG_REPLICATION)' },
230
'sheepdog',
231
'ssh', 'throttle', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat', 'vxhs' ] }
232
@@ -XXX,XX +XXX,XX @@
233
'blkreplay': 'BlockdevOptionsBlkreplay',
234
'bochs': 'BlockdevOptionsGenericFormat',
235
'cloop': 'BlockdevOptionsGenericFormat',
236
+ 'compress': 'BlockdevOptionsGenericFormat',
237
'copy-on-read':'BlockdevOptionsGenericFormat',
238
'dmg': 'BlockdevOptionsGenericFormat',
239
'file': 'BlockdevOptionsFile',
240
--
189
--
241
2.24.1
190
2.29.2
242
191
243
diff view generated by jsdifflib
1
Sometimes it is useful to be able to add a node to the block graph that
1
From: Elena Ufimtseva <elena.ufimtseva@oracle.com>
2
takes or unshare a certain set of permissions for debugging purposes.
3
This patch adds this capability to blkdebug.
4
2
5
(Note that you cannot make blkdebug release or share permissions that it
3
Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
6
needs to take or cannot share, because this might result in assertion
4
Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
7
failures in the block layer. But if the blkdebug node has no parents,
5
Signed-off-by: John G Johnson <john.g.johnson@oracle.com>
8
it will not take any permissions and share everything by default, so you
6
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
can then freely choose what permissions to take and share.)
7
Message-id: d54edb4176361eed86b903e8f27058363b6c83b3.1611938319.git.jag.raman@oracle.com
8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
---
10
include/hw/remote/mpqemu-link.h | 4 ++++
11
hw/remote/mpqemu-link.c | 34 +++++++++++++++++++++++++++++++++
12
2 files changed, 38 insertions(+)
10
13
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
diff --git a/include/hw/remote/mpqemu-link.h b/include/hw/remote/mpqemu-link.h
12
Message-id: 20191108123455.39445-4-mreitz@redhat.com
13
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
15
---
16
block/blkdebug.c | 93 +++++++++++++++++++++++++++++++++++++++++++-
17
qapi/block-core.json | 14 ++++++-
18
2 files changed, 105 insertions(+), 2 deletions(-)
19
20
diff --git a/block/blkdebug.c b/block/blkdebug.c
21
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
22
--- a/block/blkdebug.c
16
--- a/include/hw/remote/mpqemu-link.h
23
+++ b/block/blkdebug.c
17
+++ b/include/hw/remote/mpqemu-link.h
24
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@
25
#include "qemu/cutils.h"
19
#include "qemu/thread.h"
26
#include "qemu/config-file.h"
20
#include "io/channel.h"
27
#include "block/block_int.h"
21
#include "exec/hwaddr.h"
28
+#include "block/qdict.h"
22
+#include "io/channel-socket.h"
29
#include "qemu/module.h"
23
+#include "hw/remote/proxy.h"
30
#include "qemu/option.h"
24
31
+#include "qapi/qapi-visit-block-core.h"
25
#define REMOTE_MAX_FDS 8
32
#include "qapi/qmp/qdict.h"
26
33
+#include "qapi/qmp/qlist.h"
27
@@ -XXX,XX +XXX,XX @@ typedef struct {
34
#include "qapi/qmp/qstring.h"
28
bool mpqemu_msg_send(MPQemuMsg *msg, QIOChannel *ioc, Error **errp);
35
+#include "qapi/qobject-input-visitor.h"
29
bool mpqemu_msg_recv(MPQemuMsg *msg, QIOChannel *ioc, Error **errp);
36
#include "sysemu/qtest.h"
30
37
31
+uint64_t mpqemu_msg_send_and_await_reply(MPQemuMsg *msg, PCIProxyDev *pdev,
38
typedef struct BDRVBlkdebugState {
32
+ Error **errp);
39
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVBlkdebugState {
33
bool mpqemu_msg_valid(MPQemuMsg *msg);
40
uint64_t opt_discard;
34
41
uint64_t max_discard;
35
#endif
42
36
diff --git a/hw/remote/mpqemu-link.c b/hw/remote/mpqemu-link.c
43
+ uint64_t take_child_perms;
37
index XXXXXXX..XXXXXXX 100644
44
+ uint64_t unshare_child_perms;
38
--- a/hw/remote/mpqemu-link.c
39
+++ b/hw/remote/mpqemu-link.c
40
@@ -XXX,XX +XXX,XX @@ fail:
41
return ret;
42
}
43
44
+/*
45
+ * Send msg and wait for a reply with command code RET_MSG.
46
+ * Returns the message received of size u64 or UINT64_MAX
47
+ * on error.
48
+ * Called from VCPU thread in non-coroutine context.
49
+ * Used by the Proxy object to communicate to remote processes.
50
+ */
51
+uint64_t mpqemu_msg_send_and_await_reply(MPQemuMsg *msg, PCIProxyDev *pdev,
52
+ Error **errp)
53
+{
54
+ ERRP_GUARD();
55
+ MPQemuMsg msg_reply = {0};
56
+ uint64_t ret = UINT64_MAX;
45
+
57
+
46
/* For blkdebug_refresh_filename() */
58
+ assert(!qemu_in_coroutine());
47
char *config_file;
48
49
@@ -XXX,XX +XXX,XX @@ static void blkdebug_parse_filename(const char *filename, QDict *options,
50
qdict_put_str(options, "x-image", filename);
51
}
52
53
+static int blkdebug_parse_perm_list(uint64_t *dest, QDict *options,
54
+ const char *prefix, Error **errp)
55
+{
56
+ int ret = 0;
57
+ QDict *subqdict = NULL;
58
+ QObject *crumpled_subqdict = NULL;
59
+ Visitor *v = NULL;
60
+ BlockPermissionList *perm_list = NULL, *element;
61
+ Error *local_err = NULL;
62
+
59
+
63
+ *dest = 0;
60
+ QEMU_LOCK_GUARD(&pdev->io_mutex);
64
+
61
+ if (!mpqemu_msg_send(msg, pdev->ioc, errp)) {
65
+ qdict_extract_subqdict(options, &subqdict, prefix);
66
+ if (!qdict_size(subqdict)) {
67
+ goto out;
68
+ }
69
+
70
+ crumpled_subqdict = qdict_crumple(subqdict, errp);
71
+ if (!crumpled_subqdict) {
72
+ ret = -EINVAL;
73
+ goto out;
74
+ }
75
+
76
+ v = qobject_input_visitor_new(crumpled_subqdict);
77
+ visit_type_BlockPermissionList(v, NULL, &perm_list, &local_err);
78
+ if (local_err) {
79
+ error_propagate(errp, local_err);
80
+ ret = -EINVAL;
81
+ goto out;
82
+ }
83
+
84
+ for (element = perm_list; element; element = element->next) {
85
+ *dest |= bdrv_qapi_perm_to_blk_perm(element->value);
86
+ }
87
+
88
+out:
89
+ qapi_free_BlockPermissionList(perm_list);
90
+ visit_free(v);
91
+ qobject_unref(subqdict);
92
+ qobject_unref(crumpled_subqdict);
93
+ return ret;
94
+}
95
+
96
+static int blkdebug_parse_perms(BDRVBlkdebugState *s, QDict *options,
97
+ Error **errp)
98
+{
99
+ int ret;
100
+
101
+ ret = blkdebug_parse_perm_list(&s->take_child_perms, options,
102
+ "take-child-perms.", errp);
103
+ if (ret < 0) {
104
+ return ret;
62
+ return ret;
105
+ }
63
+ }
106
+
64
+
107
+ ret = blkdebug_parse_perm_list(&s->unshare_child_perms, options,
65
+ if (!mpqemu_msg_recv(&msg_reply, pdev->ioc, errp)) {
108
+ "unshare-child-perms.", errp);
109
+ if (ret < 0) {
110
+ return ret;
66
+ return ret;
111
+ }
67
+ }
112
+
68
+
113
+ return 0;
69
+ if (!mpqemu_msg_valid(&msg_reply)) {
70
+ error_setg(errp, "ERROR: Invalid reply received for command %d",
71
+ msg->cmd);
72
+ return ret;
73
+ }
74
+
75
+ return msg_reply.data.u64;
114
+}
76
+}
115
+
77
+
116
static QemuOptsList runtime_opts = {
78
bool mpqemu_msg_valid(MPQemuMsg *msg)
117
.name = "blkdebug",
79
{
118
.head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
80
if (msg->cmd >= MPQEMU_CMD_MAX && msg->cmd < 0) {
119
@@ -XXX,XX +XXX,XX @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
120
/* Set initial state */
121
s->state = 1;
122
123
+ /* Parse permissions modifiers before opening the image file */
124
+ ret = blkdebug_parse_perms(s, options, errp);
125
+ if (ret < 0) {
126
+ goto out;
127
+ }
128
+
129
/* Open the image file */
130
bs->file = bdrv_open_child(qemu_opt_get(opts, "x-image"), options, "image",
131
bs, &child_file, false, &local_err);
132
@@ -XXX,XX +XXX,XX @@ static int blkdebug_reopen_prepare(BDRVReopenState *reopen_state,
133
return 0;
134
}
135
136
+static void blkdebug_child_perm(BlockDriverState *bs, BdrvChild *c,
137
+ const BdrvChildRole *role,
138
+ BlockReopenQueue *reopen_queue,
139
+ uint64_t perm, uint64_t shared,
140
+ uint64_t *nperm, uint64_t *nshared)
141
+{
142
+ BDRVBlkdebugState *s = bs->opaque;
143
+
144
+ bdrv_filter_default_perms(bs, c, role, reopen_queue, perm, shared,
145
+ nperm, nshared);
146
+
147
+ *nperm |= s->take_child_perms;
148
+ *nshared &= ~s->unshare_child_perms;
149
+}
150
+
151
static const char *const blkdebug_strong_runtime_opts[] = {
152
"config",
153
"inject-error.",
154
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_blkdebug = {
155
.bdrv_file_open = blkdebug_open,
156
.bdrv_close = blkdebug_close,
157
.bdrv_reopen_prepare = blkdebug_reopen_prepare,
158
- .bdrv_child_perm = bdrv_filter_default_perms,
159
+ .bdrv_child_perm = blkdebug_child_perm,
160
161
.bdrv_getlength = blkdebug_getlength,
162
.bdrv_refresh_filename = blkdebug_refresh_filename,
163
diff --git a/qapi/block-core.json b/qapi/block-core.json
164
index XXXXXXX..XXXXXXX 100644
165
--- a/qapi/block-core.json
166
+++ b/qapi/block-core.json
167
@@ -XXX,XX +XXX,XX @@
168
#
169
# @set-state: array of state-change descriptions
170
#
171
+# @take-child-perms: Permissions to take on @image in addition to what
172
+# is necessary anyway (which depends on how the
173
+# blkdebug node is used). Defaults to none.
174
+# (since 5.0)
175
+#
176
+# @unshare-child-perms: Permissions not to share on @image in addition
177
+# to what cannot be shared anyway (which depends
178
+# on how the blkdebug node is used). Defaults
179
+# to none. (since 5.0)
180
+#
181
# Since: 2.9
182
##
183
{ 'struct': 'BlockdevOptionsBlkdebug',
184
@@ -XXX,XX +XXX,XX @@
185
'*opt-write-zero': 'int32', '*max-write-zero': 'int32',
186
'*opt-discard': 'int32', '*max-discard': 'int32',
187
'*inject-error': ['BlkdebugInjectErrorOptions'],
188
- '*set-state': ['BlkdebugSetStateOptions'] } }
189
+ '*set-state': ['BlkdebugSetStateOptions'],
190
+ '*take-child-perms': ['BlockPermission'],
191
+ '*unshare-child-perms': ['BlockPermission'] } }
192
193
##
194
# @BlockdevOptionsBlklogwrites:
195
--
81
--
196
2.24.1
82
2.29.2
197
83
198
diff view generated by jsdifflib
Deleted patch
1
Callers can use this new parameter to expect failure during the
2
completion process.
3
1
4
Signed-off-by: Max Reitz <mreitz@redhat.com>
5
Reviewed-by: John Snow <jsnow@redhat.com>
6
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Message-id: 20191108123455.39445-5-mreitz@redhat.com
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
---
10
tests/qemu-iotests/iotests.py | 18 ++++++++++++------
11
1 file changed, 12 insertions(+), 6 deletions(-)
12
13
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
14
index XXXXXXX..XXXXXXX 100644
15
--- a/tests/qemu-iotests/iotests.py
16
+++ b/tests/qemu-iotests/iotests.py
17
@@ -XXX,XX +XXX,XX @@ class QMPTestCase(unittest.TestCase):
18
self.assert_no_active_block_jobs()
19
return result
20
21
- def wait_until_completed(self, drive='drive0', check_offset=True, wait=60.0):
22
+ def wait_until_completed(self, drive='drive0', check_offset=True, wait=60.0,
23
+ error=None):
24
'''Wait for a block job to finish, returning the event'''
25
while True:
26
for event in self.vm.get_qmp_events(wait=wait):
27
if event['event'] == 'BLOCK_JOB_COMPLETED':
28
self.assert_qmp(event, 'data/device', drive)
29
- self.assert_qmp_absent(event, 'data/error')
30
- if check_offset:
31
- self.assert_qmp(event, 'data/offset', event['data']['len'])
32
+ if error is None:
33
+ self.assert_qmp_absent(event, 'data/error')
34
+ if check_offset:
35
+ self.assert_qmp(event, 'data/offset',
36
+ event['data']['len'])
37
+ else:
38
+ self.assert_qmp(event, 'data/error', error)
39
self.assert_no_active_block_jobs()
40
return event
41
elif event['event'] == 'JOB_STATUS_CHANGE':
42
@@ -XXX,XX +XXX,XX @@ class QMPTestCase(unittest.TestCase):
43
self.assert_qmp(event, 'data/type', 'mirror')
44
self.assert_qmp(event, 'data/offset', event['data']['len'])
45
46
- def complete_and_wait(self, drive='drive0', wait_ready=True):
47
+ def complete_and_wait(self, drive='drive0', wait_ready=True,
48
+ completion_error=None):
49
'''Complete a block job and wait for it to finish'''
50
if wait_ready:
51
self.wait_ready(drive=drive)
52
@@ -XXX,XX +XXX,XX @@ class QMPTestCase(unittest.TestCase):
53
result = self.vm.qmp('block-job-complete', device=drive)
54
self.assert_qmp(result, 'return', {})
55
56
- event = self.wait_until_completed(drive=drive)
57
+ event = self.wait_until_completed(drive=drive, error=completion_error)
58
self.assert_qmp(event, 'data/type', 'mirror')
59
60
def pause_wait(self, job_id='job0'):
61
--
62
2.24.1
63
64
diff view generated by jsdifflib
Deleted patch
1
Signed-off-by: Max Reitz <mreitz@redhat.com>
2
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
3
Tested-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
4
Reviewed-by: John Snow <jsnow@redhat.com>
5
Message-id: 20191108123455.39445-6-mreitz@redhat.com
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
---
8
tests/qemu-iotests/041 | 44 ++++++++++++++++++++++++++++++++++++++
9
tests/qemu-iotests/041.out | 4 ++--
10
2 files changed, 46 insertions(+), 2 deletions(-)
11
1
12
diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
13
index XXXXXXX..XXXXXXX 100755
14
--- a/tests/qemu-iotests/041
15
+++ b/tests/qemu-iotests/041
16
@@ -XXX,XX +XXX,XX @@ class TestOrphanedSource(iotests.QMPTestCase):
17
target='dest-ro')
18
self.assert_qmp(result, 'error/class', 'GenericError')
19
20
+ def test_failing_permission_in_complete(self):
21
+ self.assert_no_active_block_jobs()
22
+
23
+ # Unshare consistent-read on the target
24
+ # (The mirror job does not care)
25
+ result = self.vm.qmp('blockdev-add',
26
+ driver='blkdebug',
27
+ node_name='dest-perm',
28
+ image='dest',
29
+ unshare_child_perms=['consistent-read'])
30
+ self.assert_qmp(result, 'return', {})
31
+
32
+ result = self.vm.qmp('blockdev-mirror', job_id='job', device='src',
33
+ sync='full', target='dest',
34
+ filter_node_name='mirror-filter')
35
+ self.assert_qmp(result, 'return', {})
36
+
37
+ # Require consistent-read on the source
38
+ # (We can only add this node once the job has started, or it
39
+ # will complain that it does not want to run on non-root nodes)
40
+ result = self.vm.qmp('blockdev-add',
41
+ driver='blkdebug',
42
+ node_name='src-perm',
43
+ image='src',
44
+ take_child_perms=['consistent-read'])
45
+ self.assert_qmp(result, 'return', {})
46
+
47
+ # While completing, mirror will attempt to replace src by
48
+ # dest, which must fail because src-perm requires
49
+ # consistent-read but dest-perm does not share it; thus
50
+ # aborting the job when it is supposed to complete
51
+ self.complete_and_wait('job',
52
+ completion_error='Operation not permitted')
53
+
54
+ # Assert that all of our nodes are still there (except for the
55
+ # mirror filter, which should be gone despite the failure)
56
+ nodes = self.vm.qmp('query-named-block-nodes')['return']
57
+ nodes = [node['node-name'] for node in nodes]
58
+
59
+ for expect in ('src', 'src-perm', 'dest', 'dest-perm'):
60
+ self.assertTrue(expect in nodes, '%s disappeared' % expect)
61
+ self.assertFalse('mirror-filter' in nodes,
62
+ 'Mirror filter node did not disappear')
63
+
64
if __name__ == '__main__':
65
iotests.main(supported_fmts=['qcow2', 'qed'],
66
supported_protocols=['file'])
67
diff --git a/tests/qemu-iotests/041.out b/tests/qemu-iotests/041.out
68
index XXXXXXX..XXXXXXX 100644
69
--- a/tests/qemu-iotests/041.out
70
+++ b/tests/qemu-iotests/041.out
71
@@ -XXX,XX +XXX,XX @@
72
-..........................................................................................
73
+...........................................................................................
74
----------------------------------------------------------------------
75
-Ran 90 tests
76
+Ran 91 tests
77
78
OK
79
--
80
2.24.1
81
82
diff view generated by jsdifflib
Deleted patch
1
Probably due to blind copy-pasting, we have several instances of "qocw2"
2
in our iotests. Fix them.
3
1
4
Reported-by: Maxim Levitsky <mlevitsk@redhat.com>
5
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
Message-id: 20191107163708.833192-2-mreitz@redhat.com
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
---
11
tests/qemu-iotests/060 | 2 +-
12
tests/qemu-iotests/061 | 2 +-
13
tests/qemu-iotests/062 | 2 +-
14
tests/qemu-iotests/066 | 2 +-
15
tests/qemu-iotests/068 | 2 +-
16
tests/qemu-iotests/108 | 2 +-
17
tests/qemu-iotests/138 | 2 +-
18
tests/qemu-iotests/261 | 2 +-
19
8 files changed, 8 insertions(+), 8 deletions(-)
20
21
diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060
22
index XXXXXXX..XXXXXXX 100755
23
--- a/tests/qemu-iotests/060
24
+++ b/tests/qemu-iotests/060
25
@@ -XXX,XX +XXX,XX @@ _filter_io_error()
26
. ./common.rc
27
. ./common.filter
28
29
-# This tests qocw2-specific low-level functionality
30
+# This tests qcow2-specific low-level functionality
31
_supported_fmt qcow2
32
_supported_proto file
33
_supported_os Linux
34
diff --git a/tests/qemu-iotests/061 b/tests/qemu-iotests/061
35
index XXXXXXX..XXXXXXX 100755
36
--- a/tests/qemu-iotests/061
37
+++ b/tests/qemu-iotests/061
38
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
39
. ./common.rc
40
. ./common.filter
41
42
-# This tests qocw2-specific low-level functionality
43
+# This tests qcow2-specific low-level functionality
44
_supported_fmt qcow2
45
_supported_proto file
46
_supported_os Linux
47
diff --git a/tests/qemu-iotests/062 b/tests/qemu-iotests/062
48
index XXXXXXX..XXXXXXX 100755
49
--- a/tests/qemu-iotests/062
50
+++ b/tests/qemu-iotests/062
51
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
52
. ./common.rc
53
. ./common.filter
54
55
-# This tests qocw2-specific low-level functionality
56
+# This tests qcow2-specific low-level functionality
57
_supported_fmt qcow2
58
_supported_proto generic
59
60
diff --git a/tests/qemu-iotests/066 b/tests/qemu-iotests/066
61
index XXXXXXX..XXXXXXX 100755
62
--- a/tests/qemu-iotests/066
63
+++ b/tests/qemu-iotests/066
64
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
65
. ./common.rc
66
. ./common.filter
67
68
-# This tests qocw2-specific low-level functionality
69
+# This tests qcow2-specific low-level functionality
70
_supported_fmt qcow2
71
_supported_proto generic
72
73
diff --git a/tests/qemu-iotests/068 b/tests/qemu-iotests/068
74
index XXXXXXX..XXXXXXX 100755
75
--- a/tests/qemu-iotests/068
76
+++ b/tests/qemu-iotests/068
77
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
78
. ./common.rc
79
. ./common.filter
80
81
-# This tests qocw2-specific low-level functionality
82
+# This tests qcow2-specific low-level functionality
83
_supported_fmt qcow2
84
_supported_proto generic
85
86
diff --git a/tests/qemu-iotests/108 b/tests/qemu-iotests/108
87
index XXXXXXX..XXXXXXX 100755
88
--- a/tests/qemu-iotests/108
89
+++ b/tests/qemu-iotests/108
90
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
91
. ./common.rc
92
. ./common.filter
93
94
-# This tests qocw2-specific low-level functionality
95
+# This tests qcow2-specific low-level functionality
96
_supported_fmt qcow2
97
_supported_proto file
98
_supported_os Linux
99
diff --git a/tests/qemu-iotests/138 b/tests/qemu-iotests/138
100
index XXXXXXX..XXXXXXX 100755
101
--- a/tests/qemu-iotests/138
102
+++ b/tests/qemu-iotests/138
103
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
104
. ./common.rc
105
. ./common.filter
106
107
-# This tests qocw2-specific low-level functionality
108
+# This tests qcow2-specific low-level functionality
109
_supported_fmt qcow2
110
_supported_proto file
111
_supported_os Linux
112
diff --git a/tests/qemu-iotests/261 b/tests/qemu-iotests/261
113
index XXXXXXX..XXXXXXX 100755
114
--- a/tests/qemu-iotests/261
115
+++ b/tests/qemu-iotests/261
116
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
117
. ./common.rc
118
. ./common.filter
119
120
-# This tests qocw2-specific low-level functionality
121
+# This tests qcow2-specific low-level functionality
122
_supported_fmt qcow2
123
_supported_proto file
124
_supported_os Linux
125
--
126
2.24.1
127
128
diff view generated by jsdifflib
Deleted patch
1
This is useful for tests that want to whitelist fields from dump-header
2
(with grep) but still print all header extensions.
3
1
4
Signed-off-by: Max Reitz <mreitz@redhat.com>
5
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
6
Message-id: 20191107163708.833192-3-mreitz@redhat.com
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
---
9
tests/qemu-iotests/qcow2.py | 5 +++++
10
1 file changed, 5 insertions(+)
11
12
diff --git a/tests/qemu-iotests/qcow2.py b/tests/qemu-iotests/qcow2.py
13
index XXXXXXX..XXXXXXX 100755
14
--- a/tests/qemu-iotests/qcow2.py
15
+++ b/tests/qemu-iotests/qcow2.py
16
@@ -XXX,XX +XXX,XX @@ def cmd_dump_header(fd):
17
h.dump()
18
h.dump_extensions()
19
20
+def cmd_dump_header_exts(fd):
21
+ h = QcowHeader(fd)
22
+ h.dump_extensions()
23
+
24
def cmd_set_header(fd, name, value):
25
try:
26
value = int(value, 0)
27
@@ -XXX,XX +XXX,XX @@ def cmd_set_feature_bit(fd, group, bit):
28
29
cmds = [
30
[ 'dump-header', cmd_dump_header, 0, 'Dump image header and header extensions' ],
31
+ [ 'dump-header-exts', cmd_dump_header_exts, 0, 'Dump image header extensions' ],
32
[ 'set-header', cmd_set_header, 2, 'Set a field in the header'],
33
[ 'add-header-ext', cmd_add_header_ext, 2, 'Add a header extension' ],
34
[ 'add-header-ext-stdio', cmd_add_header_ext_stdio, 1, 'Add a header extension, data from stdin' ],
35
--
36
2.24.1
37
38
diff view generated by jsdifflib
Deleted patch
1
Print the feature fields as a set of bits so that filtering is easier.
2
1
3
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
5
Message-id: 20191107163708.833192-4-mreitz@redhat.com
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
---
8
tests/qemu-iotests/031.out | 36 +++++++++----------
9
tests/qemu-iotests/036.out | 18 +++++-----
10
tests/qemu-iotests/039.out | 22 ++++++------
11
tests/qemu-iotests/060.out | 20 +++++------
12
tests/qemu-iotests/061.out | 72 ++++++++++++++++++-------------------
13
tests/qemu-iotests/137.out | 2 +-
14
tests/qemu-iotests/qcow2.py | 18 +++++++---
15
7 files changed, 99 insertions(+), 89 deletions(-)
16
17
diff --git a/tests/qemu-iotests/031.out b/tests/qemu-iotests/031.out
18
index XXXXXXX..XXXXXXX 100644
19
--- a/tests/qemu-iotests/031.out
20
+++ b/tests/qemu-iotests/031.out
21
@@ -XXX,XX +XXX,XX @@ refcount_table_offset 0x10000
22
refcount_table_clusters 1
23
nb_snapshots 0
24
snapshot_offset 0x0
25
-incompatible_features 0x0
26
-compatible_features 0x0
27
-autoclear_features 0x0
28
+incompatible_features []
29
+compatible_features []
30
+autoclear_features []
31
refcount_order 4
32
header_length 72
33
34
@@ -XXX,XX +XXX,XX @@ refcount_table_offset 0x10000
35
refcount_table_clusters 1
36
nb_snapshots 0
37
snapshot_offset 0x0
38
-incompatible_features 0x0
39
-compatible_features 0x0
40
-autoclear_features 0x0
41
+incompatible_features []
42
+compatible_features []
43
+autoclear_features []
44
refcount_order 4
45
header_length 72
46
47
@@ -XXX,XX +XXX,XX @@ refcount_table_offset 0x10000
48
refcount_table_clusters 1
49
nb_snapshots 0
50
snapshot_offset 0x0
51
-incompatible_features 0x0
52
-compatible_features 0x0
53
-autoclear_features 0x0
54
+incompatible_features []
55
+compatible_features []
56
+autoclear_features []
57
refcount_order 4
58
header_length 72
59
60
@@ -XXX,XX +XXX,XX @@ refcount_table_offset 0x10000
61
refcount_table_clusters 1
62
nb_snapshots 0
63
snapshot_offset 0x0
64
-incompatible_features 0x0
65
-compatible_features 0x0
66
-autoclear_features 0x0
67
+incompatible_features []
68
+compatible_features []
69
+autoclear_features []
70
refcount_order 4
71
header_length 104
72
73
@@ -XXX,XX +XXX,XX @@ refcount_table_offset 0x10000
74
refcount_table_clusters 1
75
nb_snapshots 0
76
snapshot_offset 0x0
77
-incompatible_features 0x0
78
-compatible_features 0x0
79
-autoclear_features 0x0
80
+incompatible_features []
81
+compatible_features []
82
+autoclear_features []
83
refcount_order 4
84
header_length 104
85
86
@@ -XXX,XX +XXX,XX @@ refcount_table_offset 0x10000
87
refcount_table_clusters 1
88
nb_snapshots 0
89
snapshot_offset 0x0
90
-incompatible_features 0x0
91
-compatible_features 0x0
92
-autoclear_features 0x0
93
+incompatible_features []
94
+compatible_features []
95
+autoclear_features []
96
refcount_order 4
97
header_length 104
98
99
diff --git a/tests/qemu-iotests/036.out b/tests/qemu-iotests/036.out
100
index XXXXXXX..XXXXXXX 100644
101
--- a/tests/qemu-iotests/036.out
102
+++ b/tests/qemu-iotests/036.out
103
@@ -XXX,XX +XXX,XX @@ refcount_table_offset 0x10000
104
refcount_table_clusters 1
105
nb_snapshots 0
106
snapshot_offset 0x0
107
-incompatible_features 0x8000000000000000
108
-compatible_features 0x0
109
-autoclear_features 0x0
110
+incompatible_features [63]
111
+compatible_features []
112
+autoclear_features []
113
refcount_order 4
114
header_length 104
115
116
@@ -XXX,XX +XXX,XX @@ refcount_table_offset 0x10000
117
refcount_table_clusters 1
118
nb_snapshots 0
119
snapshot_offset 0x0
120
-incompatible_features 0x0
121
-compatible_features 0x0
122
-autoclear_features 0x8000000000000000
123
+incompatible_features []
124
+compatible_features []
125
+autoclear_features [63]
126
refcount_order 4
127
header_length 104
128
129
@@ -XXX,XX +XXX,XX @@ refcount_table_offset 0x10000
130
refcount_table_clusters 1
131
nb_snapshots 0
132
snapshot_offset 0x0
133
-incompatible_features 0x0
134
-compatible_features 0x0
135
-autoclear_features 0x0
136
+incompatible_features []
137
+compatible_features []
138
+autoclear_features []
139
refcount_order 4
140
header_length 104
141
142
diff --git a/tests/qemu-iotests/039.out b/tests/qemu-iotests/039.out
143
index XXXXXXX..XXXXXXX 100644
144
--- a/tests/qemu-iotests/039.out
145
+++ b/tests/qemu-iotests/039.out
146
@@ -XXX,XX +XXX,XX @@ QA output created by 039
147
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
148
wrote 512/512 bytes at offset 0
149
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
150
-incompatible_features 0x0
151
+incompatible_features []
152
No errors were found on the image.
153
154
== Creating a dirty image file ==
155
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
156
wrote 512/512 bytes at offset 0
157
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
158
./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
159
-incompatible_features 0x1
160
+incompatible_features [0]
161
ERROR cluster 5 refcount=0 reference=1
162
ERROR OFLAG_COPIED data cluster: l2_entry=8000000000050000 refcount=0
163
164
@@ -XXX,XX +XXX,XX @@ Data may be corrupted, or further writes to the image may corrupt it.
165
== Read-only access must still work ==
166
read 512/512 bytes at offset 0
167
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
168
-incompatible_features 0x1
169
+incompatible_features [0]
170
171
== Repairing the image file must succeed ==
172
ERROR cluster 5 refcount=0 reference=1
173
@@ -XXX,XX +XXX,XX @@ The following inconsistencies were found and repaired:
174
175
Double checking the fixed image now...
176
No errors were found on the image.
177
-incompatible_features 0x0
178
+incompatible_features []
179
180
== Data should still be accessible after repair ==
181
read 512/512 bytes at offset 0
182
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
183
wrote 512/512 bytes at offset 0
184
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
185
./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
186
-incompatible_features 0x1
187
+incompatible_features [0]
188
ERROR cluster 5 refcount=0 reference=1
189
Rebuilding refcount structure
190
Repairing cluster 1 refcount=1 reference=0
191
Repairing cluster 2 refcount=1 reference=0
192
wrote 512/512 bytes at offset 0
193
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
194
-incompatible_features 0x0
195
+incompatible_features []
196
197
== Creating an image file with lazy_refcounts=off ==
198
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
199
wrote 512/512 bytes at offset 0
200
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
201
./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
202
-incompatible_features 0x0
203
+incompatible_features []
204
No errors were found on the image.
205
206
== Committing to a backing file with lazy_refcounts=on ==
207
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/
208
wrote 512/512 bytes at offset 0
209
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
210
Image committed.
211
-incompatible_features 0x0
212
-incompatible_features 0x0
213
+incompatible_features []
214
+incompatible_features []
215
No errors were found on the image.
216
No errors were found on the image.
217
218
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
219
wrote 512/512 bytes at offset 0
220
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
221
./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
222
-incompatible_features 0x1
223
+incompatible_features [0]
224
ERROR cluster 5 refcount=0 reference=1
225
ERROR OFLAG_COPIED data cluster: l2_entry=8000000000050000 refcount=0
226
227
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
228
wrote 512/512 bytes at offset 0
229
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
230
./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
231
-incompatible_features 0x0
232
+incompatible_features []
233
No errors were found on the image.
234
*** done
235
diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out
236
index XXXXXXX..XXXXXXX 100644
237
--- a/tests/qemu-iotests/060.out
238
+++ b/tests/qemu-iotests/060.out
239
@@ -XXX,XX +XXX,XX @@ ERROR cluster 3 refcount=1 reference=3
240
241
1 errors were found on the image.
242
Data may be corrupted, or further writes to the image may corrupt it.
243
-incompatible_features 0x0
244
+incompatible_features []
245
qcow2: Marking image as corrupt: Preventing invalid write on metadata (overlaps with active L1 table); further corruption events will be suppressed
246
write failed: Input/output error
247
-incompatible_features 0x2
248
+incompatible_features [1]
249
image: TEST_DIR/t.IMGFMT
250
file format: IMGFMT
251
virtual size: 64 MiB (67108864 bytes)
252
@@ -XXX,XX +XXX,XX @@ ERROR cluster 2 refcount=1 reference=2
253
254
2 errors were found on the image.
255
Data may be corrupted, or further writes to the image may corrupt it.
256
-incompatible_features 0x0
257
+incompatible_features []
258
qcow2: Marking image as corrupt: Preventing invalid write on metadata (overlaps with refcount block); further corruption events will be suppressed
259
write failed: Input/output error
260
-incompatible_features 0x2
261
+incompatible_features [1]
262
ERROR refcount block 0 refcount=2
263
ERROR cluster 2 refcount=1 reference=2
264
Rebuilding refcount structure
265
@@ -XXX,XX +XXX,XX @@ The following inconsistencies were found and repaired:
266
267
Double checking the fixed image now...
268
No errors were found on the image.
269
-incompatible_features 0x0
270
+incompatible_features []
271
wrote 512/512 bytes at offset 0
272
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
273
-incompatible_features 0x0
274
+incompatible_features []
275
276
=== Testing cluster data reference into inactive L2 table ===
277
278
@@ -XXX,XX +XXX,XX @@ Data may be corrupted, or further writes to the image may corrupt it.
279
280
1 leaked clusters were found on the image.
281
This means waste of disk space, but no harm to data.
282
-incompatible_features 0x0
283
+incompatible_features []
284
qcow2: Marking image as corrupt: Preventing invalid write on metadata (overlaps with inactive L2 table); further corruption events will be suppressed
285
write failed: Input/output error
286
-incompatible_features 0x2
287
+incompatible_features [1]
288
ERROR cluster 4 refcount=1 reference=2
289
Leaked cluster 9 refcount=1 reference=0
290
Repairing cluster 4 refcount=1 reference=2
291
@@ -XXX,XX +XXX,XX @@ The following inconsistencies were found and repaired:
292
293
Double checking the fixed image now...
294
No errors were found on the image.
295
-incompatible_features 0x0
296
+incompatible_features []
297
wrote 512/512 bytes at offset 0
298
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
299
-incompatible_features 0x0
300
+incompatible_features []
301
read 512/512 bytes at offset 0
302
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
303
No errors were found on the image.
304
diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out
305
index XXXXXXX..XXXXXXX 100644
306
--- a/tests/qemu-iotests/061.out
307
+++ b/tests/qemu-iotests/061.out
308
@@ -XXX,XX +XXX,XX @@ refcount_table_offset 0x10000
309
refcount_table_clusters 1
310
nb_snapshots 0
311
snapshot_offset 0x0
312
-incompatible_features 0x0
313
-compatible_features 0x1
314
-autoclear_features 0x0
315
+incompatible_features []
316
+compatible_features [0]
317
+autoclear_features []
318
refcount_order 4
319
header_length 104
320
321
@@ -XXX,XX +XXX,XX @@ refcount_table_offset 0x10000
322
refcount_table_clusters 1
323
nb_snapshots 0
324
snapshot_offset 0x0
325
-incompatible_features 0x0
326
-compatible_features 0x0
327
-autoclear_features 0x0
328
+incompatible_features []
329
+compatible_features []
330
+autoclear_features []
331
refcount_order 4
332
header_length 72
333
334
@@ -XXX,XX +XXX,XX @@ refcount_table_offset 0x10000
335
refcount_table_clusters 1
336
nb_snapshots 0
337
snapshot_offset 0x0
338
-incompatible_features 0x0
339
-compatible_features 0x1
340
-autoclear_features 0x0
341
+incompatible_features []
342
+compatible_features [0]
343
+autoclear_features []
344
refcount_order 4
345
header_length 104
346
347
@@ -XXX,XX +XXX,XX @@ refcount_table_offset 0x10000
348
refcount_table_clusters 1
349
nb_snapshots 0
350
snapshot_offset 0x0
351
-incompatible_features 0x0
352
-compatible_features 0x0
353
-autoclear_features 0x0
354
+incompatible_features []
355
+compatible_features []
356
+autoclear_features []
357
refcount_order 4
358
header_length 72
359
360
@@ -XXX,XX +XXX,XX @@ refcount_table_offset 0x10000
361
refcount_table_clusters 1
362
nb_snapshots 0
363
snapshot_offset 0x0
364
-incompatible_features 0x1
365
-compatible_features 0x1
366
-autoclear_features 0x0
367
+incompatible_features [0]
368
+compatible_features [0]
369
+autoclear_features []
370
refcount_order 4
371
header_length 104
372
373
@@ -XXX,XX +XXX,XX @@ refcount_table_offset 0x80000
374
refcount_table_clusters 1
375
nb_snapshots 0
376
snapshot_offset 0x0
377
-incompatible_features 0x0
378
-compatible_features 0x0
379
-autoclear_features 0x0
380
+incompatible_features []
381
+compatible_features []
382
+autoclear_features []
383
refcount_order 4
384
header_length 72
385
386
@@ -XXX,XX +XXX,XX @@ refcount_table_offset 0x10000
387
refcount_table_clusters 1
388
nb_snapshots 0
389
snapshot_offset 0x0
390
-incompatible_features 0x0
391
-compatible_features 0x40000000000
392
-autoclear_features 0x40000000000
393
+incompatible_features []
394
+compatible_features [42]
395
+autoclear_features [42]
396
refcount_order 4
397
header_length 104
398
399
@@ -XXX,XX +XXX,XX @@ refcount_table_offset 0x10000
400
refcount_table_clusters 1
401
nb_snapshots 0
402
snapshot_offset 0x0
403
-incompatible_features 0x0
404
-compatible_features 0x0
405
-autoclear_features 0x0
406
+incompatible_features []
407
+compatible_features []
408
+autoclear_features []
409
refcount_order 4
410
header_length 72
411
412
@@ -XXX,XX +XXX,XX @@ refcount_table_offset 0x10000
413
refcount_table_clusters 1
414
nb_snapshots 0
415
snapshot_offset 0x0
416
-incompatible_features 0x0
417
-compatible_features 0x0
418
-autoclear_features 0x0
419
+incompatible_features []
420
+compatible_features []
421
+autoclear_features []
422
refcount_order 4
423
header_length 72
424
425
@@ -XXX,XX +XXX,XX @@ refcount_table_offset 0x10000
426
refcount_table_clusters 1
427
nb_snapshots 0
428
snapshot_offset 0x0
429
-incompatible_features 0x0
430
-compatible_features 0x1
431
-autoclear_features 0x0
432
+incompatible_features []
433
+compatible_features [0]
434
+autoclear_features []
435
refcount_order 4
436
header_length 104
437
438
@@ -XXX,XX +XXX,XX @@ refcount_table_offset 0x10000
439
refcount_table_clusters 1
440
nb_snapshots 0
441
snapshot_offset 0x0
442
-incompatible_features 0x1
443
-compatible_features 0x1
444
-autoclear_features 0x0
445
+incompatible_features [0]
446
+compatible_features [0]
447
+autoclear_features []
448
refcount_order 4
449
header_length 104
450
451
@@ -XXX,XX +XXX,XX @@ refcount_table_offset 0x80000
452
refcount_table_clusters 1
453
nb_snapshots 0
454
snapshot_offset 0x0
455
-incompatible_features 0x0
456
-compatible_features 0x0
457
-autoclear_features 0x0
458
+incompatible_features []
459
+compatible_features []
460
+autoclear_features []
461
refcount_order 4
462
header_length 104
463
464
diff --git a/tests/qemu-iotests/137.out b/tests/qemu-iotests/137.out
465
index XXXXXXX..XXXXXXX 100644
466
--- a/tests/qemu-iotests/137.out
467
+++ b/tests/qemu-iotests/137.out
468
@@ -XXX,XX +XXX,XX @@ qemu-io: Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are
469
wrote 512/512 bytes at offset 0
470
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
471
./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
472
-incompatible_features 0x0
473
+incompatible_features []
474
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
475
wrote 65536/65536 bytes at offset 0
476
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
477
diff --git a/tests/qemu-iotests/qcow2.py b/tests/qemu-iotests/qcow2.py
478
index XXXXXXX..XXXXXXX 100755
479
--- a/tests/qemu-iotests/qcow2.py
480
+++ b/tests/qemu-iotests/qcow2.py
481
@@ -XXX,XX +XXX,XX @@ class QcowHeader:
482
[ uint64_t, '%#x', 'snapshot_offset' ],
483
484
# Version 3 header fields
485
- [ uint64_t, '%#x', 'incompatible_features' ],
486
- [ uint64_t, '%#x', 'compatible_features' ],
487
- [ uint64_t, '%#x', 'autoclear_features' ],
488
+ [ uint64_t, 'mask', 'incompatible_features' ],
489
+ [ uint64_t, 'mask', 'compatible_features' ],
490
+ [ uint64_t, 'mask', 'autoclear_features' ],
491
[ uint32_t, '%d', 'refcount_order' ],
492
[ uint32_t, '%d', 'header_length' ],
493
];
494
@@ -XXX,XX +XXX,XX @@ class QcowHeader:
495
496
def dump(self):
497
for f in QcowHeader.fields:
498
- print("%-25s" % f[2], f[1] % self.__dict__[f[2]])
499
+ value = self.__dict__[f[2]]
500
+ if f[1] == 'mask':
501
+ bits = []
502
+ for bit in range(64):
503
+ if value & (1 << bit):
504
+ bits.append(bit)
505
+ value_str = str(bits)
506
+ else:
507
+ value_str = f[1] % value
508
+
509
+ print("%-25s" % f[2], value_str)
510
print("")
511
512
def dump_extensions(self):
513
--
514
2.24.1
515
516
diff view generated by jsdifflib
Deleted patch
1
This test can run just fine with other values for refcount_bits, so we
2
should filter the value from qcow2.py's dump-header. In fact, we can
3
filter everything but the feature bits and header extensions, because
4
that is what the test is about.
5
1
6
(036 currently ignores user-specified image options, but that will be
7
fixed in the next patch.)
8
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
11
Message-id: 20191107163708.833192-6-mreitz@redhat.com
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
13
---
14
tests/qemu-iotests/036 | 9 ++++---
15
tests/qemu-iotests/036.out | 48 --------------------------------------
16
2 files changed, 6 insertions(+), 51 deletions(-)
17
18
diff --git a/tests/qemu-iotests/036 b/tests/qemu-iotests/036
19
index XXXXXXX..XXXXXXX 100755
20
--- a/tests/qemu-iotests/036
21
+++ b/tests/qemu-iotests/036
22
@@ -XXX,XX +XXX,XX @@ $PYTHON qcow2.py "$TEST_IMG" set-feature-bit incompatible 63
23
24
# Without feature table
25
$PYTHON qcow2.py "$TEST_IMG" del-header-ext 0x6803f857
26
-$PYTHON qcow2.py "$TEST_IMG" dump-header
27
+$PYTHON qcow2.py "$TEST_IMG" dump-header | grep features
28
+$PYTHON qcow2.py "$TEST_IMG" dump-header-exts
29
_img_info
30
31
# With feature table containing bit 63
32
@@ -XXX,XX +XXX,XX @@ echo === Create image with unknown autoclear feature bit ===
33
echo
34
_make_test_img 64M
35
$PYTHON qcow2.py "$TEST_IMG" set-feature-bit autoclear 63
36
-$PYTHON qcow2.py "$TEST_IMG" dump-header
37
+$PYTHON qcow2.py "$TEST_IMG" dump-header | grep features
38
+$PYTHON qcow2.py "$TEST_IMG" dump-header-exts
39
40
echo
41
echo === Repair image ===
42
echo
43
_check_test_img -r all
44
45
-$PYTHON qcow2.py "$TEST_IMG" dump-header
46
+$PYTHON qcow2.py "$TEST_IMG" dump-header | grep features
47
+$PYTHON qcow2.py "$TEST_IMG" dump-header-exts
48
49
# success, all done
50
echo "*** done"
51
diff --git a/tests/qemu-iotests/036.out b/tests/qemu-iotests/036.out
52
index XXXXXXX..XXXXXXX 100644
53
--- a/tests/qemu-iotests/036.out
54
+++ b/tests/qemu-iotests/036.out
55
@@ -XXX,XX +XXX,XX @@ QA output created by 036
56
=== Image with unknown incompatible feature bit ===
57
58
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
59
-magic 0x514649fb
60
-version 3
61
-backing_file_offset 0x0
62
-backing_file_size 0x0
63
-cluster_bits 16
64
-size 67108864
65
-crypt_method 0
66
-l1_size 1
67
-l1_table_offset 0x30000
68
-refcount_table_offset 0x10000
69
-refcount_table_clusters 1
70
-nb_snapshots 0
71
-snapshot_offset 0x0
72
incompatible_features [63]
73
compatible_features []
74
autoclear_features []
75
-refcount_order 4
76
-header_length 104
77
-
78
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Unsupported IMGFMT feature(s): Unknown incompatible feature: 8000000000000000
79
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Unsupported IMGFMT feature(s): Test feature
80
81
@@ -XXX,XX +XXX,XX @@ qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Unsupported IMGFMT feature(s): tes
82
=== Create image with unknown autoclear feature bit ===
83
84
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
85
-magic 0x514649fb
86
-version 3
87
-backing_file_offset 0x0
88
-backing_file_size 0x0
89
-cluster_bits 16
90
-size 67108864
91
-crypt_method 0
92
-l1_size 1
93
-l1_table_offset 0x30000
94
-refcount_table_offset 0x10000
95
-refcount_table_clusters 1
96
-nb_snapshots 0
97
-snapshot_offset 0x0
98
incompatible_features []
99
compatible_features []
100
autoclear_features [63]
101
-refcount_order 4
102
-header_length 104
103
-
104
Header extension:
105
magic 0x6803f857
106
length 192
107
@@ -XXX,XX +XXX,XX @@ data <binary>
108
=== Repair image ===
109
110
No errors were found on the image.
111
-magic 0x514649fb
112
-version 3
113
-backing_file_offset 0x0
114
-backing_file_size 0x0
115
-cluster_bits 16
116
-size 67108864
117
-crypt_method 0
118
-l1_size 1
119
-l1_table_offset 0x30000
120
-refcount_table_offset 0x10000
121
-refcount_table_clusters 1
122
-nb_snapshots 0
123
-snapshot_offset 0x0
124
incompatible_features []
125
compatible_features []
126
autoclear_features []
127
-refcount_order 4
128
-header_length 104
129
-
130
Header extension:
131
magic 0x6803f857
132
length 192
133
--
134
2.24.1
135
136
diff view generated by jsdifflib
Deleted patch
1
Some tests require compat=1.1 and thus set IMGOPTS='compat=1.1'
2
globally. That is not how it should be done; instead, they should
3
simply set _unsupported_imgopts to compat=0.10 (compat=1.1 is the
4
default anyway).
5
1
6
This makes the tests heed user-specified $IMGOPTS. Some do not work
7
with all image options, though, so we need to disable them accordingly.
8
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
Reviewed-by: Maxim Levitsky <mlevitsky@redhat.com>
11
Message-id: 20191107163708.833192-7-mreitz@redhat.com
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
13
---
14
tests/qemu-iotests/036 | 3 +--
15
tests/qemu-iotests/060 | 4 ++--
16
tests/qemu-iotests/062 | 3 ++-
17
tests/qemu-iotests/066 | 3 ++-
18
tests/qemu-iotests/068 | 3 ++-
19
tests/qemu-iotests/098 | 4 ++--
20
6 files changed, 11 insertions(+), 9 deletions(-)
21
22
diff --git a/tests/qemu-iotests/036 b/tests/qemu-iotests/036
23
index XXXXXXX..XXXXXXX 100755
24
--- a/tests/qemu-iotests/036
25
+++ b/tests/qemu-iotests/036
26
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
27
# This tests qcow2-specific low-level functionality
28
_supported_fmt qcow2
29
_supported_proto file
30
-
31
# Only qcow2v3 and later supports feature bits
32
-IMGOPTS="compat=1.1"
33
+_unsupported_imgopts 'compat=0.10'
34
35
echo
36
echo === Image with unknown incompatible feature bit ===
37
diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060
38
index XXXXXXX..XXXXXXX 100755
39
--- a/tests/qemu-iotests/060
40
+++ b/tests/qemu-iotests/060
41
@@ -XXX,XX +XXX,XX @@ _filter_io_error()
42
_supported_fmt qcow2
43
_supported_proto file
44
_supported_os Linux
45
+# These tests only work for compat=1.1 images with refcount_bits=16
46
+_unsupported_imgopts 'compat=0.10' 'refcount_bits=\([^1]\|.\([^6]\|$\)\)'
47
48
# The repair process will create a large file - so check for availability first
49
_require_large_file 64G
50
@@ -XXX,XX +XXX,XX @@ l1_offset=196608 # 0x30000 (XXX: just an assumption)
51
l2_offset=262144 # 0x40000 (XXX: just an assumption)
52
l2_offset_after_snapshot=524288 # 0x80000 (XXX: just an assumption)
53
54
-IMGOPTS="compat=1.1"
55
-
56
OPEN_RW="open -o overlap-check=all $TEST_IMG"
57
# Overlap checks are done before write operations only, therefore opening an
58
# image read-only makes the overlap-check option irrelevant
59
diff --git a/tests/qemu-iotests/062 b/tests/qemu-iotests/062
60
index XXXXXXX..XXXXXXX 100755
61
--- a/tests/qemu-iotests/062
62
+++ b/tests/qemu-iotests/062
63
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
64
# This tests qcow2-specific low-level functionality
65
_supported_fmt qcow2
66
_supported_proto generic
67
+# We need zero clusters and snapshots
68
+_unsupported_imgopts 'compat=0.10' 'refcount_bits=1[^0-9]'
69
70
-IMGOPTS="compat=1.1"
71
IMG_SIZE=64M
72
73
echo
74
diff --git a/tests/qemu-iotests/066 b/tests/qemu-iotests/066
75
index XXXXXXX..XXXXXXX 100755
76
--- a/tests/qemu-iotests/066
77
+++ b/tests/qemu-iotests/066
78
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
79
# This tests qcow2-specific low-level functionality
80
_supported_fmt qcow2
81
_supported_proto generic
82
+# We need zero clusters and snapshots
83
+_unsupported_imgopts 'compat=0.10' 'refcount_bits=1[^0-9]'
84
85
# Intentionally create an unaligned image
86
-IMGOPTS="compat=1.1"
87
IMG_SIZE=$((64 * 1024 * 1024 + 512))
88
89
echo
90
diff --git a/tests/qemu-iotests/068 b/tests/qemu-iotests/068
91
index XXXXXXX..XXXXXXX 100755
92
--- a/tests/qemu-iotests/068
93
+++ b/tests/qemu-iotests/068
94
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
95
# This tests qcow2-specific low-level functionality
96
_supported_fmt qcow2
97
_supported_proto generic
98
+# Internal snapshots are (currently) impossible with refcount_bits=1
99
+_unsupported_imgopts 'compat=0.10' 'refcount_bits=1[^0-9]'
100
101
-IMGOPTS="compat=1.1"
102
IMG_SIZE=128K
103
104
case "$QEMU_DEFAULT_MACHINE" in
105
diff --git a/tests/qemu-iotests/098 b/tests/qemu-iotests/098
106
index XXXXXXX..XXXXXXX 100755
107
--- a/tests/qemu-iotests/098
108
+++ b/tests/qemu-iotests/098
109
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
110
111
_supported_fmt qcow2
112
_supported_proto file
113
-
114
-IMGOPTS="compat=1.1"
115
+# The code path we want to test here only works for compat=1.1 images
116
+_unsupported_imgopts 'compat=0.10'
117
118
for event in l1_update empty_image_prepare reftable_update refblock_alloc; do
119
120
--
121
2.24.1
122
123
diff view generated by jsdifflib
1
This will allow us to add more options than just -b.
1
From: Elena Ufimtseva <elena.ufimtseva@oracle.com>
2
2
3
Signed-off-by: Max Reitz <mreitz@redhat.com>
3
The Proxy Object sends the PCI config space accesses as messages
4
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
4
to the remote process over the communication channel
5
Message-id: 20191107163708.833192-9-mreitz@redhat.com
5
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
7
Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
8
Signed-off-by: John G Johnson <john.g.johnson@oracle.com>
9
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
10
Message-id: d3c94f4618813234655356c60e6f0d0362ff42d6.1611938319.git.jag.raman@oracle.com
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
7
---
12
---
8
tests/qemu-iotests/common.rc | 28 ++++++++++++++++++++--------
13
include/hw/remote/mpqemu-link.h | 10 ++++++
9
1 file changed, 20 insertions(+), 8 deletions(-)
14
hw/remote/message.c | 60 +++++++++++++++++++++++++++++++++
10
15
hw/remote/mpqemu-link.c | 8 ++++-
11
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
16
hw/remote/proxy.c | 55 ++++++++++++++++++++++++++++++
12
index XXXXXXX..XXXXXXX 100644
17
4 files changed, 132 insertions(+), 1 deletion(-)
13
--- a/tests/qemu-iotests/common.rc
18
14
+++ b/tests/qemu-iotests/common.rc
19
diff --git a/include/hw/remote/mpqemu-link.h b/include/hw/remote/mpqemu-link.h
15
@@ -XXX,XX +XXX,XX @@ _make_test_img()
20
index XXXXXXX..XXXXXXX 100644
16
# extra qemu-img options can be added by tests
21
--- a/include/hw/remote/mpqemu-link.h
17
# at least one argument (the image size) needs to be added
22
+++ b/include/hw/remote/mpqemu-link.h
18
local extra_img_options=""
23
@@ -XXX,XX +XXX,XX @@
19
- local image_size=$*
24
*/
20
local optstr=""
25
typedef enum {
21
local img_name=""
26
MPQEMU_CMD_SYNC_SYSMEM,
22
local use_backing=0
27
+ MPQEMU_CMD_RET,
23
local backing_file=""
28
+ MPQEMU_CMD_PCI_CFGWRITE,
24
local object_options=""
29
+ MPQEMU_CMD_PCI_CFGREAD,
25
+ local misc_params=()
30
MPQEMU_CMD_MAX,
26
31
} MPQemuCmd;
27
if [ -n "$TEST_IMG_FILE" ]; then
32
28
img_name=$TEST_IMG_FILE
33
@@ -XXX,XX +XXX,XX @@ typedef struct {
29
@@ -XXX,XX +XXX,XX @@ _make_test_img()
34
off_t offsets[REMOTE_MAX_FDS];
30
optstr=$(_optstr_add "$optstr" "key-secret=keysec0")
35
} SyncSysmemMsg;
31
fi
36
32
37
+typedef struct {
33
- if [ "$1" = "-b" ]; then
38
+ uint32_t addr;
34
- use_backing=1
39
+ uint32_t val;
35
- backing_file=$2
40
+ int len;
36
- image_size=$3
41
+} PciConfDataMsg;
37
- fi
42
+
38
+ for param; do
43
/**
39
+ if [ "$use_backing" = "1" -a -z "$backing_file" ]; then
44
* MPQemuMsg:
40
+ backing_file=$param
45
* @cmd: The remote command
41
+ continue
46
@@ -XXX,XX +XXX,XX @@ typedef struct {
42
+ fi
47
43
+
48
union {
44
+ case "$param" in
49
uint64_t u64;
45
+ -b)
50
+ PciConfDataMsg pci_conf_data;
46
+ use_backing=1
51
SyncSysmemMsg sync_sysmem;
47
+ ;;
52
} data;
48
+
53
49
+ *)
54
diff --git a/hw/remote/message.c b/hw/remote/message.c
50
+ misc_params=("${misc_params[@]}" "$param")
55
index XXXXXXX..XXXXXXX 100644
51
+ ;;
56
--- a/hw/remote/message.c
52
+ esac
57
+++ b/hw/remote/message.c
53
+ done
58
@@ -XXX,XX +XXX,XX @@
54
+
59
#include "hw/remote/mpqemu-link.h"
55
if [ \( "$IMGFMT" = "qcow2" -o "$IMGFMT" = "qed" \) -a -n "$CLUSTER_SIZE" ]; then
60
#include "qapi/error.h"
56
optstr=$(_optstr_add "$optstr" "cluster_size=$CLUSTER_SIZE")
61
#include "sysemu/runstate.h"
57
fi
62
+#include "hw/pci/pci.h"
58
@@ -XXX,XX +XXX,XX @@ _make_test_img()
63
+
59
# XXX(hch): have global image options?
64
+static void process_config_write(QIOChannel *ioc, PCIDevice *dev,
60
(
65
+ MPQemuMsg *msg, Error **errp);
61
if [ $use_backing = 1 ]; then
66
+static void process_config_read(QIOChannel *ioc, PCIDevice *dev,
62
- $QEMU_IMG create $object_options -f $IMGFMT $extra_img_options -b "$backing_file" "$img_name" $image_size 2>&1
67
+ MPQemuMsg *msg, Error **errp);
63
+ $QEMU_IMG create $object_options -f $IMGFMT $extra_img_options -b "$backing_file" "$img_name" "${misc_params[@]}" 2>&1
68
64
else
69
void coroutine_fn mpqemu_remote_msg_loop_co(void *data)
65
- $QEMU_IMG create $object_options -f $IMGFMT $extra_img_options "$img_name" $image_size 2>&1
70
{
66
+ $QEMU_IMG create $object_options -f $IMGFMT $extra_img_options "$img_name" "${misc_params[@]}" 2>&1
71
@@ -XXX,XX +XXX,XX @@ void coroutine_fn mpqemu_remote_msg_loop_co(void *data)
67
fi
72
}
68
) | _filter_img_create
73
74
switch (msg.cmd) {
75
+ case MPQEMU_CMD_PCI_CFGWRITE:
76
+ process_config_write(com->ioc, pci_dev, &msg, &local_err);
77
+ break;
78
+ case MPQEMU_CMD_PCI_CFGREAD:
79
+ process_config_read(com->ioc, pci_dev, &msg, &local_err);
80
+ break;
81
default:
82
error_setg(&local_err,
83
"Unknown command (%d) received for device %s"
84
@@ -XXX,XX +XXX,XX @@ void coroutine_fn mpqemu_remote_msg_loop_co(void *data)
85
qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
86
}
87
}
88
+
89
+static void process_config_write(QIOChannel *ioc, PCIDevice *dev,
90
+ MPQemuMsg *msg, Error **errp)
91
+{
92
+ ERRP_GUARD();
93
+ PciConfDataMsg *conf = (PciConfDataMsg *)&msg->data.pci_conf_data;
94
+ MPQemuMsg ret = { 0 };
95
+
96
+ if ((conf->addr + sizeof(conf->val)) > pci_config_size(dev)) {
97
+ error_setg(errp, "Bad address for PCI config write, pid "FMT_pid".",
98
+ getpid());
99
+ ret.data.u64 = UINT64_MAX;
100
+ } else {
101
+ pci_default_write_config(dev, conf->addr, conf->val, conf->len);
102
+ }
103
+
104
+ ret.cmd = MPQEMU_CMD_RET;
105
+ ret.size = sizeof(ret.data.u64);
106
+
107
+ if (!mpqemu_msg_send(&ret, ioc, NULL)) {
108
+ error_prepend(errp, "Error returning code to proxy, pid "FMT_pid": ",
109
+ getpid());
110
+ }
111
+}
112
+
113
+static void process_config_read(QIOChannel *ioc, PCIDevice *dev,
114
+ MPQemuMsg *msg, Error **errp)
115
+{
116
+ ERRP_GUARD();
117
+ PciConfDataMsg *conf = (PciConfDataMsg *)&msg->data.pci_conf_data;
118
+ MPQemuMsg ret = { 0 };
119
+
120
+ if ((conf->addr + sizeof(conf->val)) > pci_config_size(dev)) {
121
+ error_setg(errp, "Bad address for PCI config read, pid "FMT_pid".",
122
+ getpid());
123
+ ret.data.u64 = UINT64_MAX;
124
+ } else {
125
+ ret.data.u64 = pci_default_read_config(dev, conf->addr, conf->len);
126
+ }
127
+
128
+ ret.cmd = MPQEMU_CMD_RET;
129
+ ret.size = sizeof(ret.data.u64);
130
+
131
+ if (!mpqemu_msg_send(&ret, ioc, NULL)) {
132
+ error_prepend(errp, "Error returning code to proxy, pid "FMT_pid": ",
133
+ getpid());
134
+ }
135
+}
136
diff --git a/hw/remote/mpqemu-link.c b/hw/remote/mpqemu-link.c
137
index XXXXXXX..XXXXXXX 100644
138
--- a/hw/remote/mpqemu-link.c
139
+++ b/hw/remote/mpqemu-link.c
140
@@ -XXX,XX +XXX,XX @@ uint64_t mpqemu_msg_send_and_await_reply(MPQemuMsg *msg, PCIProxyDev *pdev,
141
return ret;
142
}
143
144
- if (!mpqemu_msg_valid(&msg_reply)) {
145
+ if (!mpqemu_msg_valid(&msg_reply) || msg_reply.cmd != MPQEMU_CMD_RET) {
146
error_setg(errp, "ERROR: Invalid reply received for command %d",
147
msg->cmd);
148
return ret;
149
@@ -XXX,XX +XXX,XX @@ bool mpqemu_msg_valid(MPQemuMsg *msg)
150
return false;
151
}
152
break;
153
+ case MPQEMU_CMD_PCI_CFGWRITE:
154
+ case MPQEMU_CMD_PCI_CFGREAD:
155
+ if (msg->size != sizeof(PciConfDataMsg)) {
156
+ return false;
157
+ }
158
+ break;
159
default:
160
break;
161
}
162
diff --git a/hw/remote/proxy.c b/hw/remote/proxy.c
163
index XXXXXXX..XXXXXXX 100644
164
--- a/hw/remote/proxy.c
165
+++ b/hw/remote/proxy.c
166
@@ -XXX,XX +XXX,XX @@
167
#include "monitor/monitor.h"
168
#include "migration/blocker.h"
169
#include "qemu/sockets.h"
170
+#include "hw/remote/mpqemu-link.h"
171
+#include "qemu/error-report.h"
172
173
static void pci_proxy_dev_realize(PCIDevice *device, Error **errp)
174
{
175
@@ -XXX,XX +XXX,XX @@ static void pci_proxy_dev_exit(PCIDevice *pdev)
176
error_free(dev->migration_blocker);
177
}
178
179
+static void config_op_send(PCIProxyDev *pdev, uint32_t addr, uint32_t *val,
180
+ int len, unsigned int op)
181
+{
182
+ MPQemuMsg msg = { 0 };
183
+ uint64_t ret = -EINVAL;
184
+ Error *local_err = NULL;
185
+
186
+ msg.cmd = op;
187
+ msg.data.pci_conf_data.addr = addr;
188
+ msg.data.pci_conf_data.val = (op == MPQEMU_CMD_PCI_CFGWRITE) ? *val : 0;
189
+ msg.data.pci_conf_data.len = len;
190
+ msg.size = sizeof(PciConfDataMsg);
191
+
192
+ ret = mpqemu_msg_send_and_await_reply(&msg, pdev, &local_err);
193
+ if (local_err) {
194
+ error_report_err(local_err);
195
+ }
196
+
197
+ if (ret == UINT64_MAX) {
198
+ error_report("Failed to perform PCI config %s operation",
199
+ (op == MPQEMU_CMD_PCI_CFGREAD) ? "READ" : "WRITE");
200
+ }
201
+
202
+ if (op == MPQEMU_CMD_PCI_CFGREAD) {
203
+ *val = (uint32_t)ret;
204
+ }
205
+}
206
+
207
+static uint32_t pci_proxy_read_config(PCIDevice *d, uint32_t addr, int len)
208
+{
209
+ uint32_t val;
210
+
211
+ config_op_send(PCI_PROXY_DEV(d), addr, &val, len, MPQEMU_CMD_PCI_CFGREAD);
212
+
213
+ return val;
214
+}
215
+
216
+static void pci_proxy_write_config(PCIDevice *d, uint32_t addr, uint32_t val,
217
+ int len)
218
+{
219
+ /*
220
+ * Some of the functions access the copy of remote device's PCI config
221
+ * space which is cached in the proxy device. Therefore, maintain
222
+ * it updated.
223
+ */
224
+ pci_default_write_config(d, addr, val, len);
225
+
226
+ config_op_send(PCI_PROXY_DEV(d), addr, &val, len, MPQEMU_CMD_PCI_CFGWRITE);
227
+}
228
+
229
static Property proxy_properties[] = {
230
DEFINE_PROP_STRING("fd", PCIProxyDev, fd),
231
DEFINE_PROP_END_OF_LIST(),
232
@@ -XXX,XX +XXX,XX @@ static void pci_proxy_dev_class_init(ObjectClass *klass, void *data)
233
234
k->realize = pci_proxy_dev_realize;
235
k->exit = pci_proxy_dev_exit;
236
+ k->config_read = pci_proxy_read_config;
237
+ k->config_write = pci_proxy_write_config;
238
+
239
device_class_set_props(dc, proxy_properties);
240
}
69
241
70
--
242
--
71
2.24.1
243
2.29.2
72
244
73
diff view generated by jsdifflib
1
IMGOPTS can never be empty for qcow2, because the check scripts adds
1
From: Jagannathan Raman <jag.raman@oracle.com>
2
compat=1.1 unless the user specified any compat option themselves.
2
3
Thus, this block does not do anything and can be dropped.
3
Proxy device object implements handler for PCI BAR writes and reads.
4
4
The handler uses BAR_WRITE/BAR_READ message to communicate to the
5
Signed-off-by: Max Reitz <mreitz@redhat.com>
5
remote process with the BAR address and value to be written/read.
6
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
6
The remote process implements handler for BAR_WRITE/BAR_READ
7
Message-id: 20191107163708.833192-8-mreitz@redhat.com
7
message.
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
9
Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
10
Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
11
Signed-off-by: John G Johnson <john.g.johnson@oracle.com>
12
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
13
Message-id: a8b76714a9688be5552c4c92d089bc9e8a4707ff.1611938319.git.jag.raman@oracle.com
14
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
---
15
---
10
tests/qemu-iotests/050 | 4 ----
16
include/hw/remote/mpqemu-link.h | 10 ++++
11
1 file changed, 4 deletions(-)
17
include/hw/remote/proxy.h | 9 ++++
12
18
hw/remote/message.c | 83 +++++++++++++++++++++++++++++++++
13
diff --git a/tests/qemu-iotests/050 b/tests/qemu-iotests/050
19
hw/remote/mpqemu-link.c | 6 +++
14
index XXXXXXX..XXXXXXX 100755
20
hw/remote/proxy.c | 60 ++++++++++++++++++++++++
15
--- a/tests/qemu-iotests/050
21
5 files changed, 168 insertions(+)
16
+++ b/tests/qemu-iotests/050
22
17
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
23
diff --git a/include/hw/remote/mpqemu-link.h b/include/hw/remote/mpqemu-link.h
18
_supported_fmt qcow2 qed
24
index XXXXXXX..XXXXXXX 100644
19
_supported_proto file
25
--- a/include/hw/remote/mpqemu-link.h
20
26
+++ b/include/hw/remote/mpqemu-link.h
21
-if test "$IMGFMT" = qcow2 && test $IMGOPTS = ""; then
27
@@ -XXX,XX +XXX,XX @@ typedef enum {
22
- IMGOPTS=compat=1.1
28
MPQEMU_CMD_RET,
23
-fi
29
MPQEMU_CMD_PCI_CFGWRITE,
24
-
30
MPQEMU_CMD_PCI_CFGREAD,
25
echo
31
+ MPQEMU_CMD_BAR_WRITE,
26
echo "== Creating images =="
32
+ MPQEMU_CMD_BAR_READ,
27
33
MPQEMU_CMD_MAX,
34
} MPQemuCmd;
35
36
@@ -XXX,XX +XXX,XX @@ typedef struct {
37
int len;
38
} PciConfDataMsg;
39
40
+typedef struct {
41
+ hwaddr addr;
42
+ uint64_t val;
43
+ unsigned size;
44
+ bool memory;
45
+} BarAccessMsg;
46
+
47
/**
48
* MPQemuMsg:
49
* @cmd: The remote command
50
@@ -XXX,XX +XXX,XX @@ typedef struct {
51
uint64_t u64;
52
PciConfDataMsg pci_conf_data;
53
SyncSysmemMsg sync_sysmem;
54
+ BarAccessMsg bar_access;
55
} data;
56
57
int fds[REMOTE_MAX_FDS];
58
diff --git a/include/hw/remote/proxy.h b/include/hw/remote/proxy.h
59
index XXXXXXX..XXXXXXX 100644
60
--- a/include/hw/remote/proxy.h
61
+++ b/include/hw/remote/proxy.h
62
@@ -XXX,XX +XXX,XX @@
63
#define TYPE_PCI_PROXY_DEV "x-pci-proxy-dev"
64
OBJECT_DECLARE_SIMPLE_TYPE(PCIProxyDev, PCI_PROXY_DEV)
65
66
+typedef struct ProxyMemoryRegion {
67
+ PCIProxyDev *dev;
68
+ MemoryRegion mr;
69
+ bool memory;
70
+ bool present;
71
+ uint8_t type;
72
+} ProxyMemoryRegion;
73
+
74
struct PCIProxyDev {
75
PCIDevice parent_dev;
76
char *fd;
77
@@ -XXX,XX +XXX,XX @@ struct PCIProxyDev {
78
QemuMutex io_mutex;
79
QIOChannel *ioc;
80
Error *migration_blocker;
81
+ ProxyMemoryRegion region[PCI_NUM_REGIONS];
82
};
83
84
#endif /* PROXY_H */
85
diff --git a/hw/remote/message.c b/hw/remote/message.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/hw/remote/message.c
88
+++ b/hw/remote/message.c
89
@@ -XXX,XX +XXX,XX @@
90
#include "qapi/error.h"
91
#include "sysemu/runstate.h"
92
#include "hw/pci/pci.h"
93
+#include "exec/memattrs.h"
94
95
static void process_config_write(QIOChannel *ioc, PCIDevice *dev,
96
MPQemuMsg *msg, Error **errp);
97
static void process_config_read(QIOChannel *ioc, PCIDevice *dev,
98
MPQemuMsg *msg, Error **errp);
99
+static void process_bar_write(QIOChannel *ioc, MPQemuMsg *msg, Error **errp);
100
+static void process_bar_read(QIOChannel *ioc, MPQemuMsg *msg, Error **errp);
101
102
void coroutine_fn mpqemu_remote_msg_loop_co(void *data)
103
{
104
@@ -XXX,XX +XXX,XX @@ void coroutine_fn mpqemu_remote_msg_loop_co(void *data)
105
case MPQEMU_CMD_PCI_CFGREAD:
106
process_config_read(com->ioc, pci_dev, &msg, &local_err);
107
break;
108
+ case MPQEMU_CMD_BAR_WRITE:
109
+ process_bar_write(com->ioc, &msg, &local_err);
110
+ break;
111
+ case MPQEMU_CMD_BAR_READ:
112
+ process_bar_read(com->ioc, &msg, &local_err);
113
+ break;
114
default:
115
error_setg(&local_err,
116
"Unknown command (%d) received for device %s"
117
@@ -XXX,XX +XXX,XX @@ static void process_config_read(QIOChannel *ioc, PCIDevice *dev,
118
getpid());
119
}
120
}
121
+
122
+static void process_bar_write(QIOChannel *ioc, MPQemuMsg *msg, Error **errp)
123
+{
124
+ ERRP_GUARD();
125
+ BarAccessMsg *bar_access = &msg->data.bar_access;
126
+ AddressSpace *as =
127
+ bar_access->memory ? &address_space_memory : &address_space_io;
128
+ MPQemuMsg ret = { 0 };
129
+ MemTxResult res;
130
+ uint64_t val;
131
+
132
+ if (!is_power_of_2(bar_access->size) ||
133
+ (bar_access->size > sizeof(uint64_t))) {
134
+ ret.data.u64 = UINT64_MAX;
135
+ goto fail;
136
+ }
137
+
138
+ val = cpu_to_le64(bar_access->val);
139
+
140
+ res = address_space_rw(as, bar_access->addr, MEMTXATTRS_UNSPECIFIED,
141
+ (void *)&val, bar_access->size, true);
142
+
143
+ if (res != MEMTX_OK) {
144
+ error_setg(errp, "Bad address %"PRIx64" for mem write, pid "FMT_pid".",
145
+ bar_access->addr, getpid());
146
+ ret.data.u64 = -1;
147
+ }
148
+
149
+fail:
150
+ ret.cmd = MPQEMU_CMD_RET;
151
+ ret.size = sizeof(ret.data.u64);
152
+
153
+ if (!mpqemu_msg_send(&ret, ioc, NULL)) {
154
+ error_prepend(errp, "Error returning code to proxy, pid "FMT_pid": ",
155
+ getpid());
156
+ }
157
+}
158
+
159
+static void process_bar_read(QIOChannel *ioc, MPQemuMsg *msg, Error **errp)
160
+{
161
+ ERRP_GUARD();
162
+ BarAccessMsg *bar_access = &msg->data.bar_access;
163
+ MPQemuMsg ret = { 0 };
164
+ AddressSpace *as;
165
+ MemTxResult res;
166
+ uint64_t val = 0;
167
+
168
+ as = bar_access->memory ? &address_space_memory : &address_space_io;
169
+
170
+ if (!is_power_of_2(bar_access->size) ||
171
+ (bar_access->size > sizeof(uint64_t))) {
172
+ val = UINT64_MAX;
173
+ goto fail;
174
+ }
175
+
176
+ res = address_space_rw(as, bar_access->addr, MEMTXATTRS_UNSPECIFIED,
177
+ (void *)&val, bar_access->size, false);
178
+
179
+ if (res != MEMTX_OK) {
180
+ error_setg(errp, "Bad address %"PRIx64" for mem read, pid "FMT_pid".",
181
+ bar_access->addr, getpid());
182
+ val = UINT64_MAX;
183
+ }
184
+
185
+fail:
186
+ ret.cmd = MPQEMU_CMD_RET;
187
+ ret.data.u64 = le64_to_cpu(val);
188
+ ret.size = sizeof(ret.data.u64);
189
+
190
+ if (!mpqemu_msg_send(&ret, ioc, NULL)) {
191
+ error_prepend(errp, "Error returning code to proxy, pid "FMT_pid": ",
192
+ getpid());
193
+ }
194
+}
195
diff --git a/hw/remote/mpqemu-link.c b/hw/remote/mpqemu-link.c
196
index XXXXXXX..XXXXXXX 100644
197
--- a/hw/remote/mpqemu-link.c
198
+++ b/hw/remote/mpqemu-link.c
199
@@ -XXX,XX +XXX,XX @@ bool mpqemu_msg_valid(MPQemuMsg *msg)
200
return false;
201
}
202
break;
203
+ case MPQEMU_CMD_BAR_WRITE:
204
+ case MPQEMU_CMD_BAR_READ:
205
+ if ((msg->size != sizeof(BarAccessMsg)) || (msg->num_fds != 0)) {
206
+ return false;
207
+ }
208
+ break;
209
default:
210
break;
211
}
212
diff --git a/hw/remote/proxy.c b/hw/remote/proxy.c
213
index XXXXXXX..XXXXXXX 100644
214
--- a/hw/remote/proxy.c
215
+++ b/hw/remote/proxy.c
216
@@ -XXX,XX +XXX,XX @@ static void pci_proxy_dev_register_types(void)
217
}
218
219
type_init(pci_proxy_dev_register_types)
220
+
221
+static void send_bar_access_msg(PCIProxyDev *pdev, MemoryRegion *mr,
222
+ bool write, hwaddr addr, uint64_t *val,
223
+ unsigned size, bool memory)
224
+{
225
+ MPQemuMsg msg = { 0 };
226
+ long ret = -EINVAL;
227
+ Error *local_err = NULL;
228
+
229
+ msg.size = sizeof(BarAccessMsg);
230
+ msg.data.bar_access.addr = mr->addr + addr;
231
+ msg.data.bar_access.size = size;
232
+ msg.data.bar_access.memory = memory;
233
+
234
+ if (write) {
235
+ msg.cmd = MPQEMU_CMD_BAR_WRITE;
236
+ msg.data.bar_access.val = *val;
237
+ } else {
238
+ msg.cmd = MPQEMU_CMD_BAR_READ;
239
+ }
240
+
241
+ ret = mpqemu_msg_send_and_await_reply(&msg, pdev, &local_err);
242
+ if (local_err) {
243
+ error_report_err(local_err);
244
+ }
245
+
246
+ if (!write) {
247
+ *val = ret;
248
+ }
249
+}
250
+
251
+static void proxy_bar_write(void *opaque, hwaddr addr, uint64_t val,
252
+ unsigned size)
253
+{
254
+ ProxyMemoryRegion *pmr = opaque;
255
+
256
+ send_bar_access_msg(pmr->dev, &pmr->mr, true, addr, &val, size,
257
+ pmr->memory);
258
+}
259
+
260
+static uint64_t proxy_bar_read(void *opaque, hwaddr addr, unsigned size)
261
+{
262
+ ProxyMemoryRegion *pmr = opaque;
263
+ uint64_t val;
264
+
265
+ send_bar_access_msg(pmr->dev, &pmr->mr, false, addr, &val, size,
266
+ pmr->memory);
267
+
268
+ return val;
269
+}
270
+
271
+const MemoryRegionOps proxy_mr_ops = {
272
+ .read = proxy_bar_read,
273
+ .write = proxy_bar_write,
274
+ .endianness = DEVICE_NATIVE_ENDIAN,
275
+ .impl = {
276
+ .min_access_size = 1,
277
+ .max_access_size = 8,
278
+ },
279
+};
28
--
280
--
29
2.24.1
281
2.29.2
30
282
31
diff view generated by jsdifflib
1
This will not work with external data files, so try to get tests working
1
From: Jagannathan Raman <jag.raman@oracle.com>
2
without it as far as possible.
3
2
4
Signed-off-by: Max Reitz <mreitz@redhat.com>
3
Add ProxyMemoryListener object which is used to keep the view of the RAM
5
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
4
in sync between QEMU and remote process.
6
Message-id: 20191107163708.833192-17-mreitz@redhat.com
5
A MemoryListener is registered for system-memory AddressSpace. The
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
listener sends SYNC_SYSMEM message to the remote process when memory
7
listener commits the changes to memory, the remote process receives
8
the message and processes it in the handler for SYNC_SYSMEM message.
9
10
Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
11
Signed-off-by: John G Johnson <john.g.johnson@oracle.com>
12
Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
13
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
14
Message-id: 04fe4e6a9ca90d4f11ab6f59be7652f5b086a071.1611938319.git.jag.raman@oracle.com
15
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
8
---
16
---
9
tests/qemu-iotests/063 | 12 ++++--------
17
MAINTAINERS | 2 +
10
tests/qemu-iotests/063.out | 3 ++-
18
include/hw/remote/proxy-memory-listener.h | 28 +++
11
tests/qemu-iotests/085 | 9 +++------
19
include/hw/remote/proxy.h | 2 +
12
tests/qemu-iotests/085.out | 8 ++++----
20
hw/remote/message.c | 4 +
13
4 files changed, 13 insertions(+), 19 deletions(-)
21
hw/remote/proxy-memory-listener.c | 227 ++++++++++++++++++++++
22
hw/remote/proxy.c | 6 +
23
hw/remote/meson.build | 1 +
24
7 files changed, 270 insertions(+)
25
create mode 100644 include/hw/remote/proxy-memory-listener.h
26
create mode 100644 hw/remote/proxy-memory-listener.c
14
27
15
diff --git a/tests/qemu-iotests/063 b/tests/qemu-iotests/063
28
diff --git a/MAINTAINERS b/MAINTAINERS
16
index XXXXXXX..XXXXXXX 100755
29
index XXXXXXX..XXXXXXX 100644
17
--- a/tests/qemu-iotests/063
30
--- a/MAINTAINERS
18
+++ b/tests/qemu-iotests/063
31
+++ b/MAINTAINERS
19
@@ -XXX,XX +XXX,XX @@ _unsupported_imgopts "subformat=monolithicFlat" \
32
@@ -XXX,XX +XXX,XX @@ F: include/hw/remote/memory.h
20
_make_test_img 4M
33
F: hw/remote/memory.c
21
34
F: hw/remote/proxy.c
22
echo "== Testing conversion with -n fails with no target file =="
35
F: include/hw/remote/proxy.h
23
-# check .orig file does not exist
36
+F: hw/remote/proxy-memory-listener.c
24
-rm -f "$TEST_IMG.orig"
37
+F: include/hw/remote/proxy-memory-listener.h
25
if $QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n "$TEST_IMG" "$TEST_IMG.orig" >/dev/null 2>&1; then
38
26
exit 1
39
Build and test automation
27
fi
40
-------------------------
28
41
diff --git a/include/hw/remote/proxy-memory-listener.h b/include/hw/remote/proxy-memory-listener.h
29
echo "== Testing conversion with -n succeeds with a target file =="
42
new file mode 100644
30
-rm -f "$TEST_IMG.orig"
43
index XXXXXXX..XXXXXXX
31
-cp "$TEST_IMG" "$TEST_IMG.orig"
44
--- /dev/null
32
+_rm_test_img "$TEST_IMG.orig"
45
+++ b/include/hw/remote/proxy-memory-listener.h
33
+TEST_IMG="$TEST_IMG.orig" _make_test_img 4M
46
@@ -XXX,XX +XXX,XX @@
34
if ! $QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n "$TEST_IMG" "$TEST_IMG.orig" ; then
47
+/*
35
exit 1
48
+ * Copyright © 2018, 2021 Oracle and/or its affiliates.
36
fi
49
+ *
37
@@ -XXX,XX +XXX,XX @@ fi
50
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
38
_check_test_img
51
+ * See the COPYING file in the top-level directory.
39
52
+ *
40
echo "== Testing conversion to a smaller file fails =="
53
+ */
41
-rm -f "$TEST_IMG.orig"
54
+
42
-mv "$TEST_IMG" "$TEST_IMG.orig"
55
+#ifndef PROXY_MEMORY_LISTENER_H
43
-_make_test_img 2M
56
+#define PROXY_MEMORY_LISTENER_H
44
-if $QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n "$TEST_IMG.orig" "$TEST_IMG" >/dev/null 2>&1; then
57
+
45
+TEST_IMG="$TEST_IMG.target" _make_test_img 2M
58
+#include "exec/memory.h"
46
+if $QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n "$TEST_IMG" "$TEST_IMG.target" >/dev/null 2>&1; then
59
+#include "io/channel.h"
47
exit 1
60
+
48
fi
61
+typedef struct ProxyMemoryListener {
49
62
+ MemoryListener listener;
50
diff --git a/tests/qemu-iotests/063.out b/tests/qemu-iotests/063.out
63
+
51
index XXXXXXX..XXXXXXX 100644
64
+ int n_mr_sections;
52
--- a/tests/qemu-iotests/063.out
65
+ MemoryRegionSection *mr_sections;
53
+++ b/tests/qemu-iotests/063.out
66
+
54
@@ -XXX,XX +XXX,XX @@ QA output created by 063
67
+ QIOChannel *ioc;
55
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4194304
68
+} ProxyMemoryListener;
56
== Testing conversion with -n fails with no target file ==
69
+
57
== Testing conversion with -n succeeds with a target file ==
70
+void proxy_memory_listener_configure(ProxyMemoryListener *proxy_listener,
58
+Formatting 'TEST_DIR/t.IMGFMT.orig', fmt=IMGFMT size=4194304
71
+ QIOChannel *ioc);
59
== Testing conversion to raw is the same after conversion with -n ==
72
+void proxy_memory_listener_deconfigure(ProxyMemoryListener *proxy_listener);
60
== Testing conversion back to original format ==
73
+
61
No errors were found on the image.
74
+#endif
62
== Testing conversion to a smaller file fails ==
75
diff --git a/include/hw/remote/proxy.h b/include/hw/remote/proxy.h
63
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2097152
76
index XXXXXXX..XXXXXXX 100644
64
+Formatting 'TEST_DIR/t.IMGFMT.target', fmt=IMGFMT size=2097152
77
--- a/include/hw/remote/proxy.h
65
== Regression testing for copy offloading bug ==
78
+++ b/include/hw/remote/proxy.h
66
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
79
@@ -XXX,XX +XXX,XX @@
67
Formatting 'TEST_DIR/t.IMGFMT.target', fmt=IMGFMT size=1048576
80
68
diff --git a/tests/qemu-iotests/085 b/tests/qemu-iotests/085
81
#include "hw/pci/pci.h"
69
index XXXXXXX..XXXXXXX 100755
82
#include "io/channel.h"
70
--- a/tests/qemu-iotests/085
83
+#include "hw/remote/proxy-memory-listener.h"
71
+++ b/tests/qemu-iotests/085
84
72
@@ -XXX,XX +XXX,XX @@ add_snapshot_image()
85
#define TYPE_PCI_PROXY_DEV "x-pci-proxy-dev"
86
OBJECT_DECLARE_SIMPLE_TYPE(PCIProxyDev, PCI_PROXY_DEV)
87
@@ -XXX,XX +XXX,XX @@ struct PCIProxyDev {
88
QemuMutex io_mutex;
89
QIOChannel *ioc;
90
Error *migration_blocker;
91
+ ProxyMemoryListener proxy_listener;
92
ProxyMemoryRegion region[PCI_NUM_REGIONS];
93
};
94
95
diff --git a/hw/remote/message.c b/hw/remote/message.c
96
index XXXXXXX..XXXXXXX 100644
97
--- a/hw/remote/message.c
98
+++ b/hw/remote/message.c
99
@@ -XXX,XX +XXX,XX @@
100
#include "sysemu/runstate.h"
101
#include "hw/pci/pci.h"
102
#include "exec/memattrs.h"
103
+#include "hw/remote/memory.h"
104
105
static void process_config_write(QIOChannel *ioc, PCIDevice *dev,
106
MPQemuMsg *msg, Error **errp);
107
@@ -XXX,XX +XXX,XX @@ void coroutine_fn mpqemu_remote_msg_loop_co(void *data)
108
case MPQEMU_CMD_BAR_READ:
109
process_bar_read(com->ioc, &msg, &local_err);
110
break;
111
+ case MPQEMU_CMD_SYNC_SYSMEM:
112
+ remote_sysmem_reconfig(&msg, &local_err);
113
+ break;
114
default:
115
error_setg(&local_err,
116
"Unknown command (%d) received for device %s"
117
diff --git a/hw/remote/proxy-memory-listener.c b/hw/remote/proxy-memory-listener.c
118
new file mode 100644
119
index XXXXXXX..XXXXXXX
120
--- /dev/null
121
+++ b/hw/remote/proxy-memory-listener.c
122
@@ -XXX,XX +XXX,XX @@
123
+/*
124
+ * Copyright © 2018, 2021 Oracle and/or its affiliates.
125
+ *
126
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
127
+ * See the COPYING file in the top-level directory.
128
+ *
129
+ */
130
+
131
+#include "qemu/osdep.h"
132
+#include "qemu-common.h"
133
+
134
+#include "qemu/compiler.h"
135
+#include "qemu/int128.h"
136
+#include "qemu/range.h"
137
+#include "exec/memory.h"
138
+#include "exec/cpu-common.h"
139
+#include "cpu.h"
140
+#include "exec/ram_addr.h"
141
+#include "exec/address-spaces.h"
142
+#include "qapi/error.h"
143
+#include "hw/remote/mpqemu-link.h"
144
+#include "hw/remote/proxy-memory-listener.h"
145
+
146
+/*
147
+ * TODO: get_fd_from_hostaddr(), proxy_mrs_can_merge() and
148
+ * proxy_memory_listener_commit() defined below perform tasks similar to the
149
+ * functions defined in vhost-user.c. These functions are good candidates
150
+ * for refactoring.
151
+ *
152
+ */
153
+
154
+static void proxy_memory_listener_reset(MemoryListener *listener)
155
+{
156
+ ProxyMemoryListener *proxy_listener = container_of(listener,
157
+ ProxyMemoryListener,
158
+ listener);
159
+ int mrs;
160
+
161
+ for (mrs = 0; mrs < proxy_listener->n_mr_sections; mrs++) {
162
+ memory_region_unref(proxy_listener->mr_sections[mrs].mr);
163
+ }
164
+
165
+ g_free(proxy_listener->mr_sections);
166
+ proxy_listener->mr_sections = NULL;
167
+ proxy_listener->n_mr_sections = 0;
168
+}
169
+
170
+static int get_fd_from_hostaddr(uint64_t host, ram_addr_t *offset)
171
+{
172
+ MemoryRegion *mr;
173
+ ram_addr_t off;
174
+
175
+ /**
176
+ * Assumes that the host address is a valid address as it's
177
+ * coming from the MemoryListener system. In the case host
178
+ * address is not valid, the following call would return
179
+ * the default subregion of "system_memory" region, and
180
+ * not NULL. So it's not possible to check for NULL here.
181
+ */
182
+ mr = memory_region_from_host((void *)(uintptr_t)host, &off);
183
+
184
+ if (offset) {
185
+ *offset = off;
186
+ }
187
+
188
+ return memory_region_get_fd(mr);
189
+}
190
+
191
+static bool proxy_mrs_can_merge(uint64_t host, uint64_t prev_host, size_t size)
192
+{
193
+ if (((prev_host + size) != host)) {
194
+ return false;
195
+ }
196
+
197
+ if (get_fd_from_hostaddr(host, NULL) !=
198
+ get_fd_from_hostaddr(prev_host, NULL)) {
199
+ return false;
200
+ }
201
+
202
+ return true;
203
+}
204
+
205
+static bool try_merge(ProxyMemoryListener *proxy_listener,
206
+ MemoryRegionSection *section)
207
+{
208
+ uint64_t mrs_size, mrs_gpa, mrs_page;
209
+ MemoryRegionSection *prev_sec;
210
+ bool merged = false;
211
+ uintptr_t mrs_host;
212
+ RAMBlock *mrs_rb;
213
+
214
+ if (!proxy_listener->n_mr_sections) {
215
+ return false;
216
+ }
217
+
218
+ mrs_rb = section->mr->ram_block;
219
+ mrs_page = (uint64_t)qemu_ram_pagesize(mrs_rb);
220
+ mrs_size = int128_get64(section->size);
221
+ mrs_gpa = section->offset_within_address_space;
222
+ mrs_host = (uintptr_t)memory_region_get_ram_ptr(section->mr) +
223
+ section->offset_within_region;
224
+
225
+ if (get_fd_from_hostaddr(mrs_host, NULL) < 0) {
226
+ return true;
227
+ }
228
+
229
+ mrs_host = mrs_host & ~(mrs_page - 1);
230
+ mrs_gpa = mrs_gpa & ~(mrs_page - 1);
231
+ mrs_size = ROUND_UP(mrs_size, mrs_page);
232
+
233
+ prev_sec = proxy_listener->mr_sections +
234
+ (proxy_listener->n_mr_sections - 1);
235
+ uint64_t prev_gpa_start = prev_sec->offset_within_address_space;
236
+ uint64_t prev_size = int128_get64(prev_sec->size);
237
+ uint64_t prev_gpa_end = range_get_last(prev_gpa_start, prev_size);
238
+ uint64_t prev_host_start =
239
+ (uintptr_t)memory_region_get_ram_ptr(prev_sec->mr) +
240
+ prev_sec->offset_within_region;
241
+ uint64_t prev_host_end = range_get_last(prev_host_start, prev_size);
242
+
243
+ if (mrs_gpa <= (prev_gpa_end + 1)) {
244
+ g_assert(mrs_gpa > prev_gpa_start);
245
+
246
+ if ((section->mr == prev_sec->mr) &&
247
+ proxy_mrs_can_merge(mrs_host, prev_host_start,
248
+ (mrs_gpa - prev_gpa_start))) {
249
+ uint64_t max_end = MAX(prev_host_end, mrs_host + mrs_size);
250
+ merged = true;
251
+ prev_sec->offset_within_address_space =
252
+ MIN(prev_gpa_start, mrs_gpa);
253
+ prev_sec->offset_within_region =
254
+ MIN(prev_host_start, mrs_host) -
255
+ (uintptr_t)memory_region_get_ram_ptr(prev_sec->mr);
256
+ prev_sec->size = int128_make64(max_end - MIN(prev_host_start,
257
+ mrs_host));
258
+ }
259
+ }
260
+
261
+ return merged;
262
+}
263
+
264
+static void proxy_memory_listener_region_addnop(MemoryListener *listener,
265
+ MemoryRegionSection *section)
266
+{
267
+ ProxyMemoryListener *proxy_listener = container_of(listener,
268
+ ProxyMemoryListener,
269
+ listener);
270
+
271
+ if (!memory_region_is_ram(section->mr) ||
272
+ memory_region_is_rom(section->mr)) {
273
+ return;
274
+ }
275
+
276
+ if (try_merge(proxy_listener, section)) {
277
+ return;
278
+ }
279
+
280
+ ++proxy_listener->n_mr_sections;
281
+ proxy_listener->mr_sections = g_renew(MemoryRegionSection,
282
+ proxy_listener->mr_sections,
283
+ proxy_listener->n_mr_sections);
284
+ proxy_listener->mr_sections[proxy_listener->n_mr_sections - 1] = *section;
285
+ proxy_listener->mr_sections[proxy_listener->n_mr_sections - 1].fv = NULL;
286
+ memory_region_ref(section->mr);
287
+}
288
+
289
+static void proxy_memory_listener_commit(MemoryListener *listener)
290
+{
291
+ ProxyMemoryListener *proxy_listener = container_of(listener,
292
+ ProxyMemoryListener,
293
+ listener);
294
+ MPQemuMsg msg;
295
+ MemoryRegionSection *section;
296
+ ram_addr_t offset;
297
+ uintptr_t host_addr;
298
+ int region;
299
+ Error *local_err = NULL;
300
+
301
+ memset(&msg, 0, sizeof(MPQemuMsg));
302
+
303
+ msg.cmd = MPQEMU_CMD_SYNC_SYSMEM;
304
+ msg.num_fds = proxy_listener->n_mr_sections;
305
+ msg.size = sizeof(SyncSysmemMsg);
306
+ if (msg.num_fds > REMOTE_MAX_FDS) {
307
+ error_report("Number of fds is more than %d", REMOTE_MAX_FDS);
308
+ return;
309
+ }
310
+
311
+ for (region = 0; region < proxy_listener->n_mr_sections; region++) {
312
+ section = &proxy_listener->mr_sections[region];
313
+ msg.data.sync_sysmem.gpas[region] =
314
+ section->offset_within_address_space;
315
+ msg.data.sync_sysmem.sizes[region] = int128_get64(section->size);
316
+ host_addr = (uintptr_t)memory_region_get_ram_ptr(section->mr) +
317
+ section->offset_within_region;
318
+ msg.fds[region] = get_fd_from_hostaddr(host_addr, &offset);
319
+ msg.data.sync_sysmem.offsets[region] = offset;
320
+ }
321
+ if (!mpqemu_msg_send(&msg, proxy_listener->ioc, &local_err)) {
322
+ error_report_err(local_err);
323
+ }
324
+}
325
+
326
+void proxy_memory_listener_deconfigure(ProxyMemoryListener *proxy_listener)
327
+{
328
+ memory_listener_unregister(&proxy_listener->listener);
329
+
330
+ proxy_memory_listener_reset(&proxy_listener->listener);
331
+}
332
+
333
+void proxy_memory_listener_configure(ProxyMemoryListener *proxy_listener,
334
+ QIOChannel *ioc)
335
+{
336
+ proxy_listener->n_mr_sections = 0;
337
+ proxy_listener->mr_sections = NULL;
338
+
339
+ proxy_listener->ioc = ioc;
340
+
341
+ proxy_listener->listener.begin = proxy_memory_listener_reset;
342
+ proxy_listener->listener.commit = proxy_memory_listener_commit;
343
+ proxy_listener->listener.region_add = proxy_memory_listener_region_addnop;
344
+ proxy_listener->listener.region_nop = proxy_memory_listener_region_addnop;
345
+ proxy_listener->listener.priority = 10;
346
+
347
+ memory_listener_register(&proxy_listener->listener,
348
+ &address_space_memory);
349
+}
350
diff --git a/hw/remote/proxy.c b/hw/remote/proxy.c
351
index XXXXXXX..XXXXXXX 100644
352
--- a/hw/remote/proxy.c
353
+++ b/hw/remote/proxy.c
354
@@ -XXX,XX +XXX,XX @@
355
#include "qemu/sockets.h"
356
#include "hw/remote/mpqemu-link.h"
357
#include "qemu/error-report.h"
358
+#include "hw/remote/proxy-memory-listener.h"
359
+#include "qom/object.h"
360
361
static void pci_proxy_dev_realize(PCIDevice *device, Error **errp)
73
{
362
{
74
base_image="${TEST_DIR}/$((${1}-1))-${snapshot_virt0}"
363
@@ -XXX,XX +XXX,XX @@ static void pci_proxy_dev_realize(PCIDevice *device, Error **errp)
75
snapshot_file="${TEST_DIR}/${1}-${snapshot_virt0}"
364
76
- _make_test_img -u -b "${base_image}" "$size"
365
qemu_mutex_init(&dev->io_mutex);
77
- mv "${TEST_IMG}" "${snapshot_file}"
366
qio_channel_set_blocking(dev->ioc, true, NULL);
78
+ TEST_IMG=$snapshot_file _make_test_img -u -b "${base_image}" "$size"
367
+
79
do_blockdev_add "$1" "'backing': null, " "${snapshot_file}"
368
+ proxy_memory_listener_configure(&dev->proxy_listener, dev->ioc);
80
}
369
}
81
370
82
@@ -XXX,XX +XXX,XX @@ blockdev_snapshot()
371
static void pci_proxy_dev_exit(PCIDevice *pdev)
83
372
@@ -XXX,XX +XXX,XX @@ static void pci_proxy_dev_exit(PCIDevice *pdev)
84
size=128M
373
migrate_del_blocker(dev->migration_blocker);
85
374
86
-_make_test_img $size
375
error_free(dev->migration_blocker);
87
-mv "${TEST_IMG}" "${TEST_IMG}.1"
376
+
88
-_make_test_img $size
377
+ proxy_memory_listener_deconfigure(&dev->proxy_listener);
89
-mv "${TEST_IMG}" "${TEST_IMG}.2"
378
}
90
+TEST_IMG="$TEST_IMG.1" _make_test_img $size
379
91
+TEST_IMG="$TEST_IMG.2" _make_test_img $size
380
static void config_op_send(PCIProxyDev *pdev, uint32_t addr, uint32_t *val,
92
381
diff --git a/hw/remote/meson.build b/hw/remote/meson.build
93
echo
382
index XXXXXXX..XXXXXXX 100644
94
echo === Running QEMU ===
383
--- a/hw/remote/meson.build
95
diff --git a/tests/qemu-iotests/085.out b/tests/qemu-iotests/085.out
384
+++ b/hw/remote/meson.build
96
index XXXXXXX..XXXXXXX 100644
385
@@ -XXX,XX +XXX,XX @@ remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('remote-obj.c'))
97
--- a/tests/qemu-iotests/085.out
386
remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('proxy.c'))
98
+++ b/tests/qemu-iotests/085.out
387
99
@@ -XXX,XX +XXX,XX @@
388
specific_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('memory.c'))
100
QA output created by 085
389
+specific_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('proxy-memory-listener.c'))
101
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
390
102
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
391
softmmu_ss.add_all(when: 'CONFIG_MULTIPROCESS', if_true: remote_ss)
103
+Formatting 'TEST_DIR/t.IMGFMT.1', fmt=IMGFMT size=134217728
104
+Formatting 'TEST_DIR/t.IMGFMT.2', fmt=IMGFMT size=134217728
105
106
=== Running QEMU ===
107
108
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/10-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_fil
109
110
=== Create a couple of snapshots using blockdev-snapshot ===
111
112
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/10-snapshot-v0.IMGFMT
113
+Formatting 'TEST_DIR/11-snapshot-v0.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/10-snapshot-v0.IMGFMT
114
{ 'execute': 'blockdev-add', 'arguments': { 'driver': 'IMGFMT', 'node-name': 'snap_11', 'backing': null, 'file': { 'driver': 'file', 'filename': 'TEST_DIR/11-snapshot-v0.IMGFMT', 'node-name': 'file_11' } } }
115
{"return": {}}
116
{ 'execute': 'blockdev-snapshot', 'arguments': { 'node': 'virtio0', 'overlay':'snap_11' } }
117
{"return": {}}
118
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/11-snapshot-v0.IMGFMT
119
+Formatting 'TEST_DIR/12-snapshot-v0.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/11-snapshot-v0.IMGFMT
120
{ 'execute': 'blockdev-add', 'arguments': { 'driver': 'IMGFMT', 'node-name': 'snap_12', 'backing': null, 'file': { 'driver': 'file', 'filename': 'TEST_DIR/12-snapshot-v0.IMGFMT', 'node-name': 'file_12' } } }
121
{"return": {}}
122
{ 'execute': 'blockdev-snapshot', 'arguments': { 'node': 'virtio0', 'overlay':'snap_12' } }
123
--
392
--
124
2.24.1
393
2.29.2
125
394
126
diff view generated by jsdifflib
1
Overwriting IMGOPTS means ignoring all user-supplied options, which is
1
From: Jagannathan Raman <jag.raman@oracle.com>
2
not what we want. Replace the current IMGOPTS use by a new BACKING_FILE
3
variable.
4
2
5
Signed-off-by: Max Reitz <mreitz@redhat.com>
3
IOHUB object is added to manage PCI IRQs. It uses KVM_IRQFD
6
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
4
ioctl to create irqfd to injecting PCI interrupts to the guest.
7
Message-id: 20191107163708.833192-14-mreitz@redhat.com
5
IOHUB object forwards the irqfd to the remote process. Remote process
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
uses this fd to directly send interrupts to the guest, bypassing QEMU.
7
8
Signed-off-by: John G Johnson <john.g.johnson@oracle.com>
9
Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
10
Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
11
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
12
Message-id: 51d5c3d54e28a68b002e3875c59599c9f5a424a1.1611938319.git.jag.raman@oracle.com
13
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
---
14
---
10
tests/qemu-iotests/267 | 12 ++++++++----
15
MAINTAINERS | 2 +
11
1 file changed, 8 insertions(+), 4 deletions(-)
16
include/hw/pci/pci_ids.h | 3 +
17
include/hw/remote/iohub.h | 42 +++++++++++
18
include/hw/remote/machine.h | 2 +
19
include/hw/remote/mpqemu-link.h | 1 +
20
include/hw/remote/proxy.h | 4 ++
21
hw/remote/iohub.c | 119 ++++++++++++++++++++++++++++++++
22
hw/remote/machine.c | 10 +++
23
hw/remote/message.c | 4 ++
24
hw/remote/mpqemu-link.c | 5 ++
25
hw/remote/proxy.c | 56 +++++++++++++++
26
hw/remote/meson.build | 1 +
27
12 files changed, 249 insertions(+)
28
create mode 100644 include/hw/remote/iohub.h
29
create mode 100644 hw/remote/iohub.c
12
30
13
diff --git a/tests/qemu-iotests/267 b/tests/qemu-iotests/267
31
diff --git a/MAINTAINERS b/MAINTAINERS
14
index XXXXXXX..XXXXXXX 100755
32
index XXXXXXX..XXXXXXX 100644
15
--- a/tests/qemu-iotests/267
33
--- a/MAINTAINERS
16
+++ b/tests/qemu-iotests/267
34
+++ b/MAINTAINERS
17
@@ -XXX,XX +XXX,XX @@ size=128M
35
@@ -XXX,XX +XXX,XX @@ F: hw/remote/proxy.c
18
36
F: include/hw/remote/proxy.h
19
run_test()
37
F: hw/remote/proxy-memory-listener.c
38
F: include/hw/remote/proxy-memory-listener.h
39
+F: hw/remote/iohub.c
40
+F: include/hw/remote/iohub.h
41
42
Build and test automation
43
-------------------------
44
diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
45
index XXXXXXX..XXXXXXX 100644
46
--- a/include/hw/pci/pci_ids.h
47
+++ b/include/hw/pci/pci_ids.h
48
@@ -XXX,XX +XXX,XX @@
49
#define PCI_DEVICE_ID_SUN_SIMBA 0x5000
50
#define PCI_DEVICE_ID_SUN_SABRE 0xa000
51
52
+#define PCI_VENDOR_ID_ORACLE 0x108e
53
+#define PCI_DEVICE_ID_REMOTE_IOHUB 0xb000
54
+
55
#define PCI_VENDOR_ID_CMD 0x1095
56
#define PCI_DEVICE_ID_CMD_646 0x0646
57
58
diff --git a/include/hw/remote/iohub.h b/include/hw/remote/iohub.h
59
new file mode 100644
60
index XXXXXXX..XXXXXXX
61
--- /dev/null
62
+++ b/include/hw/remote/iohub.h
63
@@ -XXX,XX +XXX,XX @@
64
+/*
65
+ * IO Hub for remote device
66
+ *
67
+ * Copyright © 2018, 2021 Oracle and/or its affiliates.
68
+ *
69
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
70
+ * See the COPYING file in the top-level directory.
71
+ *
72
+ */
73
+
74
+#ifndef REMOTE_IOHUB_H
75
+#define REMOTE_IOHUB_H
76
+
77
+#include "hw/pci/pci.h"
78
+#include "qemu/event_notifier.h"
79
+#include "qemu/thread-posix.h"
80
+#include "hw/remote/mpqemu-link.h"
81
+
82
+#define REMOTE_IOHUB_NB_PIRQS PCI_DEVFN_MAX
83
+
84
+typedef struct ResampleToken {
85
+ void *iohub;
86
+ int pirq;
87
+} ResampleToken;
88
+
89
+typedef struct RemoteIOHubState {
90
+ PCIDevice d;
91
+ EventNotifier irqfds[REMOTE_IOHUB_NB_PIRQS];
92
+ EventNotifier resamplefds[REMOTE_IOHUB_NB_PIRQS];
93
+ unsigned int irq_level[REMOTE_IOHUB_NB_PIRQS];
94
+ ResampleToken token[REMOTE_IOHUB_NB_PIRQS];
95
+ QemuMutex irq_level_lock[REMOTE_IOHUB_NB_PIRQS];
96
+} RemoteIOHubState;
97
+
98
+int remote_iohub_map_irq(PCIDevice *pci_dev, int intx);
99
+void remote_iohub_set_irq(void *opaque, int pirq, int level);
100
+void process_set_irqfd_msg(PCIDevice *pci_dev, MPQemuMsg *msg);
101
+
102
+void remote_iohub_init(RemoteIOHubState *iohub);
103
+void remote_iohub_finalize(RemoteIOHubState *iohub);
104
+
105
+#endif
106
diff --git a/include/hw/remote/machine.h b/include/hw/remote/machine.h
107
index XXXXXXX..XXXXXXX 100644
108
--- a/include/hw/remote/machine.h
109
+++ b/include/hw/remote/machine.h
110
@@ -XXX,XX +XXX,XX @@
111
#include "hw/boards.h"
112
#include "hw/pci-host/remote.h"
113
#include "io/channel.h"
114
+#include "hw/remote/iohub.h"
115
116
struct RemoteMachineState {
117
MachineState parent_obj;
118
119
RemotePCIHost *host;
120
+ RemoteIOHubState iohub;
121
};
122
123
/* Used to pass to co-routine device and ioc. */
124
diff --git a/include/hw/remote/mpqemu-link.h b/include/hw/remote/mpqemu-link.h
125
index XXXXXXX..XXXXXXX 100644
126
--- a/include/hw/remote/mpqemu-link.h
127
+++ b/include/hw/remote/mpqemu-link.h
128
@@ -XXX,XX +XXX,XX @@ typedef enum {
129
MPQEMU_CMD_PCI_CFGREAD,
130
MPQEMU_CMD_BAR_WRITE,
131
MPQEMU_CMD_BAR_READ,
132
+ MPQEMU_CMD_SET_IRQFD,
133
MPQEMU_CMD_MAX,
134
} MPQemuCmd;
135
136
diff --git a/include/hw/remote/proxy.h b/include/hw/remote/proxy.h
137
index XXXXXXX..XXXXXXX 100644
138
--- a/include/hw/remote/proxy.h
139
+++ b/include/hw/remote/proxy.h
140
@@ -XXX,XX +XXX,XX @@
141
#include "hw/pci/pci.h"
142
#include "io/channel.h"
143
#include "hw/remote/proxy-memory-listener.h"
144
+#include "qemu/event_notifier.h"
145
146
#define TYPE_PCI_PROXY_DEV "x-pci-proxy-dev"
147
OBJECT_DECLARE_SIMPLE_TYPE(PCIProxyDev, PCI_PROXY_DEV)
148
@@ -XXX,XX +XXX,XX @@ struct PCIProxyDev {
149
QIOChannel *ioc;
150
Error *migration_blocker;
151
ProxyMemoryListener proxy_listener;
152
+ int virq;
153
+ EventNotifier intr;
154
+ EventNotifier resample;
155
ProxyMemoryRegion region[PCI_NUM_REGIONS];
156
};
157
158
diff --git a/hw/remote/iohub.c b/hw/remote/iohub.c
159
new file mode 100644
160
index XXXXXXX..XXXXXXX
161
--- /dev/null
162
+++ b/hw/remote/iohub.c
163
@@ -XXX,XX +XXX,XX @@
164
+/*
165
+ * Remote IO Hub
166
+ *
167
+ * Copyright © 2018, 2021 Oracle and/or its affiliates.
168
+ *
169
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
170
+ * See the COPYING file in the top-level directory.
171
+ *
172
+ */
173
+
174
+#include "qemu/osdep.h"
175
+#include "qemu-common.h"
176
+
177
+#include "hw/pci/pci.h"
178
+#include "hw/pci/pci_ids.h"
179
+#include "hw/pci/pci_bus.h"
180
+#include "qemu/thread.h"
181
+#include "hw/boards.h"
182
+#include "hw/remote/machine.h"
183
+#include "hw/remote/iohub.h"
184
+#include "qemu/main-loop.h"
185
+
186
+void remote_iohub_init(RemoteIOHubState *iohub)
187
+{
188
+ int pirq;
189
+
190
+ memset(&iohub->irqfds, 0, sizeof(iohub->irqfds));
191
+ memset(&iohub->resamplefds, 0, sizeof(iohub->resamplefds));
192
+
193
+ for (pirq = 0; pirq < REMOTE_IOHUB_NB_PIRQS; pirq++) {
194
+ qemu_mutex_init(&iohub->irq_level_lock[pirq]);
195
+ iohub->irq_level[pirq] = 0;
196
+ event_notifier_init_fd(&iohub->irqfds[pirq], -1);
197
+ event_notifier_init_fd(&iohub->resamplefds[pirq], -1);
198
+ }
199
+}
200
+
201
+void remote_iohub_finalize(RemoteIOHubState *iohub)
202
+{
203
+ int pirq;
204
+
205
+ for (pirq = 0; pirq < REMOTE_IOHUB_NB_PIRQS; pirq++) {
206
+ qemu_set_fd_handler(event_notifier_get_fd(&iohub->resamplefds[pirq]),
207
+ NULL, NULL, NULL);
208
+ event_notifier_cleanup(&iohub->irqfds[pirq]);
209
+ event_notifier_cleanup(&iohub->resamplefds[pirq]);
210
+ qemu_mutex_destroy(&iohub->irq_level_lock[pirq]);
211
+ }
212
+}
213
+
214
+int remote_iohub_map_irq(PCIDevice *pci_dev, int intx)
215
+{
216
+ return pci_dev->devfn;
217
+}
218
+
219
+void remote_iohub_set_irq(void *opaque, int pirq, int level)
220
+{
221
+ RemoteIOHubState *iohub = opaque;
222
+
223
+ assert(pirq >= 0);
224
+ assert(pirq < PCI_DEVFN_MAX);
225
+
226
+ QEMU_LOCK_GUARD(&iohub->irq_level_lock[pirq]);
227
+
228
+ if (level) {
229
+ if (++iohub->irq_level[pirq] == 1) {
230
+ event_notifier_set(&iohub->irqfds[pirq]);
231
+ }
232
+ } else if (iohub->irq_level[pirq] > 0) {
233
+ iohub->irq_level[pirq]--;
234
+ }
235
+}
236
+
237
+static void intr_resample_handler(void *opaque)
238
+{
239
+ ResampleToken *token = opaque;
240
+ RemoteIOHubState *iohub = token->iohub;
241
+ int pirq, s;
242
+
243
+ pirq = token->pirq;
244
+
245
+ s = event_notifier_test_and_clear(&iohub->resamplefds[pirq]);
246
+
247
+ assert(s >= 0);
248
+
249
+ QEMU_LOCK_GUARD(&iohub->irq_level_lock[pirq]);
250
+
251
+ if (iohub->irq_level[pirq]) {
252
+ event_notifier_set(&iohub->irqfds[pirq]);
253
+ }
254
+}
255
+
256
+void process_set_irqfd_msg(PCIDevice *pci_dev, MPQemuMsg *msg)
257
+{
258
+ RemoteMachineState *machine = REMOTE_MACHINE(current_machine);
259
+ RemoteIOHubState *iohub = &machine->iohub;
260
+ int pirq, intx;
261
+
262
+ intx = pci_get_byte(pci_dev->config + PCI_INTERRUPT_PIN) - 1;
263
+
264
+ pirq = remote_iohub_map_irq(pci_dev, intx);
265
+
266
+ if (event_notifier_get_fd(&iohub->irqfds[pirq]) != -1) {
267
+ qemu_set_fd_handler(event_notifier_get_fd(&iohub->resamplefds[pirq]),
268
+ NULL, NULL, NULL);
269
+ event_notifier_cleanup(&iohub->irqfds[pirq]);
270
+ event_notifier_cleanup(&iohub->resamplefds[pirq]);
271
+ memset(&iohub->token[pirq], 0, sizeof(ResampleToken));
272
+ }
273
+
274
+ event_notifier_init_fd(&iohub->irqfds[pirq], msg->fds[0]);
275
+ event_notifier_init_fd(&iohub->resamplefds[pirq], msg->fds[1]);
276
+
277
+ iohub->token[pirq].iohub = iohub;
278
+ iohub->token[pirq].pirq = pirq;
279
+
280
+ qemu_set_fd_handler(msg->fds[1], intr_resample_handler, NULL,
281
+ &iohub->token[pirq]);
282
+}
283
diff --git a/hw/remote/machine.c b/hw/remote/machine.c
284
index XXXXXXX..XXXXXXX 100644
285
--- a/hw/remote/machine.c
286
+++ b/hw/remote/machine.c
287
@@ -XXX,XX +XXX,XX @@
288
#include "exec/address-spaces.h"
289
#include "exec/memory.h"
290
#include "qapi/error.h"
291
+#include "hw/pci/pci_host.h"
292
+#include "hw/remote/iohub.h"
293
294
static void remote_machine_init(MachineState *machine)
20
{
295
{
21
- _make_test_img $size
296
MemoryRegion *system_memory, *system_io, *pci_memory;
22
+ if [ -n "$BACKING_FILE" ]; then
297
RemoteMachineState *s = REMOTE_MACHINE(machine);
23
+ _make_test_img -b "$BACKING_FILE" $size
298
RemotePCIHost *rem_host;
24
+ else
299
+ PCIHostState *pci_host;
25
+ _make_test_img $size
300
26
+ fi
301
system_memory = get_system_memory();
27
printf "savevm snap0\ninfo snapshots\nloadvm snap0\n" | run_qemu "$@" | _filter_date
302
system_io = get_system_io();
303
@@ -XXX,XX +XXX,XX @@ static void remote_machine_init(MachineState *machine)
304
memory_region_add_subregion_overlap(system_memory, 0x0, pci_memory, -1);
305
306
qdev_realize(DEVICE(rem_host), sysbus_get_default(), &error_fatal);
307
+
308
+ pci_host = PCI_HOST_BRIDGE(rem_host);
309
+
310
+ remote_iohub_init(&s->iohub);
311
+
312
+ pci_bus_irqs(pci_host->bus, remote_iohub_set_irq, remote_iohub_map_irq,
313
+ &s->iohub, REMOTE_IOHUB_NB_PIRQS);
28
}
314
}
29
315
30
@@ -XXX,XX +XXX,XX @@ echo
316
static void remote_machine_class_init(ObjectClass *oc, void *data)
31
317
diff --git a/hw/remote/message.c b/hw/remote/message.c
32
TEST_IMG="$TEST_IMG.base" _make_test_img $size
318
index XXXXXXX..XXXXXXX 100644
33
319
--- a/hw/remote/message.c
34
-IMGOPTS="backing_file=$TEST_IMG.base" \
320
+++ b/hw/remote/message.c
35
+BACKING_FILE="$TEST_IMG.base" \
321
@@ -XXX,XX +XXX,XX @@
36
run_test -blockdev driver=file,filename="$TEST_IMG.base",node-name=backing-file \
322
#include "hw/pci/pci.h"
37
-blockdev driver=file,filename="$TEST_IMG",node-name=file \
323
#include "exec/memattrs.h"
38
-blockdev driver=$IMGFMT,file=file,backing=backing-file,node-name=fmt
324
#include "hw/remote/memory.h"
39
325
+#include "hw/remote/iohub.h"
40
-IMGOPTS="backing_file=$TEST_IMG.base" \
326
41
+BACKING_FILE="$TEST_IMG.base" \
327
static void process_config_write(QIOChannel *ioc, PCIDevice *dev,
42
run_test -blockdev driver=file,filename="$TEST_IMG.base",node-name=backing-file \
328
MPQemuMsg *msg, Error **errp);
43
-blockdev driver=$IMGFMT,file=backing-file,node-name=backing-fmt \
329
@@ -XXX,XX +XXX,XX @@ void coroutine_fn mpqemu_remote_msg_loop_co(void *data)
44
-blockdev driver=file,filename="$TEST_IMG",node-name=file \
330
case MPQEMU_CMD_SYNC_SYSMEM:
45
@@ -XXX,XX +XXX,XX @@ echo
331
remote_sysmem_reconfig(&msg, &local_err);
46
echo "=== -blockdev with NBD server on the backing file ==="
332
break;
47
echo
333
+ case MPQEMU_CMD_SET_IRQFD:
48
334
+ process_set_irqfd_msg(pci_dev, &msg);
49
-IMGOPTS="backing_file=$TEST_IMG.base" _make_test_img $size
335
+ break;
50
+_make_test_img -b "$TEST_IMG.base" $size
336
default:
51
cat <<EOF |
337
error_setg(&local_err,
52
nbd_server_start unix:$SOCK_DIR/nbd
338
"Unknown command (%d) received for device %s"
53
nbd_server_add -w backing-fmt
339
diff --git a/hw/remote/mpqemu-link.c b/hw/remote/mpqemu-link.c
340
index XXXXXXX..XXXXXXX 100644
341
--- a/hw/remote/mpqemu-link.c
342
+++ b/hw/remote/mpqemu-link.c
343
@@ -XXX,XX +XXX,XX @@ bool mpqemu_msg_valid(MPQemuMsg *msg)
344
return false;
345
}
346
break;
347
+ case MPQEMU_CMD_SET_IRQFD:
348
+ if (msg->size || (msg->num_fds != 2)) {
349
+ return false;
350
+ }
351
+ break;
352
default:
353
break;
354
}
355
diff --git a/hw/remote/proxy.c b/hw/remote/proxy.c
356
index XXXXXXX..XXXXXXX 100644
357
--- a/hw/remote/proxy.c
358
+++ b/hw/remote/proxy.c
359
@@ -XXX,XX +XXX,XX @@
360
#include "qemu/error-report.h"
361
#include "hw/remote/proxy-memory-listener.h"
362
#include "qom/object.h"
363
+#include "qemu/event_notifier.h"
364
+#include "sysemu/kvm.h"
365
+#include "util/event_notifier-posix.c"
366
+
367
+static void proxy_intx_update(PCIDevice *pci_dev)
368
+{
369
+ PCIProxyDev *dev = PCI_PROXY_DEV(pci_dev);
370
+ PCIINTxRoute route;
371
+ int pin = pci_get_byte(pci_dev->config + PCI_INTERRUPT_PIN) - 1;
372
+
373
+ if (dev->virq != -1) {
374
+ kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, &dev->intr, dev->virq);
375
+ dev->virq = -1;
376
+ }
377
+
378
+ route = pci_device_route_intx_to_irq(pci_dev, pin);
379
+
380
+ dev->virq = route.irq;
381
+
382
+ if (dev->virq != -1) {
383
+ kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, &dev->intr,
384
+ &dev->resample, dev->virq);
385
+ }
386
+}
387
+
388
+static void setup_irqfd(PCIProxyDev *dev)
389
+{
390
+ PCIDevice *pci_dev = PCI_DEVICE(dev);
391
+ MPQemuMsg msg;
392
+ Error *local_err = NULL;
393
+
394
+ event_notifier_init(&dev->intr, 0);
395
+ event_notifier_init(&dev->resample, 0);
396
+
397
+ memset(&msg, 0, sizeof(MPQemuMsg));
398
+ msg.cmd = MPQEMU_CMD_SET_IRQFD;
399
+ msg.num_fds = 2;
400
+ msg.fds[0] = event_notifier_get_fd(&dev->intr);
401
+ msg.fds[1] = event_notifier_get_fd(&dev->resample);
402
+ msg.size = 0;
403
+
404
+ if (!mpqemu_msg_send(&msg, dev->ioc, &local_err)) {
405
+ error_report_err(local_err);
406
+ }
407
+
408
+ dev->virq = -1;
409
+
410
+ proxy_intx_update(pci_dev);
411
+
412
+ pci_device_set_intx_routing_notifier(pci_dev, proxy_intx_update);
413
+}
414
415
static void pci_proxy_dev_realize(PCIDevice *device, Error **errp)
416
{
417
@@ -XXX,XX +XXX,XX @@ static void pci_proxy_dev_realize(PCIDevice *device, Error **errp)
418
qio_channel_set_blocking(dev->ioc, true, NULL);
419
420
proxy_memory_listener_configure(&dev->proxy_listener, dev->ioc);
421
+
422
+ setup_irqfd(dev);
423
}
424
425
static void pci_proxy_dev_exit(PCIDevice *pdev)
426
@@ -XXX,XX +XXX,XX @@ static void pci_proxy_dev_exit(PCIDevice *pdev)
427
error_free(dev->migration_blocker);
428
429
proxy_memory_listener_deconfigure(&dev->proxy_listener);
430
+
431
+ event_notifier_cleanup(&dev->intr);
432
+ event_notifier_cleanup(&dev->resample);
433
}
434
435
static void config_op_send(PCIProxyDev *pdev, uint32_t addr, uint32_t *val,
436
diff --git a/hw/remote/meson.build b/hw/remote/meson.build
437
index XXXXXXX..XXXXXXX 100644
438
--- a/hw/remote/meson.build
439
+++ b/hw/remote/meson.build
440
@@ -XXX,XX +XXX,XX @@ remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('mpqemu-link.c'))
441
remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('message.c'))
442
remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('remote-obj.c'))
443
remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('proxy.c'))
444
+remote_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('iohub.c'))
445
446
specific_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('memory.c'))
447
specific_ss.add(when: 'CONFIG_MULTIPROCESS', if_true: files('proxy-memory-listener.c'))
54
--
448
--
55
2.24.1
449
2.29.2
56
450
57
diff view generated by jsdifflib
1
Signed-off-by: Max Reitz <mreitz@redhat.com>
1
From: Jagannathan Raman <jag.raman@oracle.com>
2
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
2
3
Message-id: 20191107163708.833192-13-mreitz@redhat.com
3
Retrieve PCI configuration info about the remote device and
4
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
configure the Proxy PCI object based on the returned information
5
6
Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
7
Signed-off-by: John G Johnson <john.g.johnson@oracle.com>
8
Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
9
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
10
Message-id: 85ee367bbb993aa23699b44cfedd83b4ea6d5221.1611938319.git.jag.raman@oracle.com
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
5
---
12
---
6
tests/qemu-iotests/071 | 4 ++--
13
hw/remote/proxy.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++
7
tests/qemu-iotests/174 | 2 +-
14
1 file changed, 84 insertions(+)
8
tests/qemu-iotests/178 | 4 ++--
9
tests/qemu-iotests/197 | 4 ++--
10
tests/qemu-iotests/215 | 4 ++--
11
5 files changed, 9 insertions(+), 9 deletions(-)
12
15
13
diff --git a/tests/qemu-iotests/071 b/tests/qemu-iotests/071
16
diff --git a/hw/remote/proxy.c b/hw/remote/proxy.c
14
index XXXXXXX..XXXXXXX 100755
17
index XXXXXXX..XXXXXXX 100644
15
--- a/tests/qemu-iotests/071
18
--- a/hw/remote/proxy.c
16
+++ b/tests/qemu-iotests/071
19
+++ b/hw/remote/proxy.c
17
@@ -XXX,XX +XXX,XX @@ echo
20
@@ -XXX,XX +XXX,XX @@
18
echo "=== Testing blkverify through filename ==="
21
#include "sysemu/kvm.h"
19
echo
22
#include "util/event_notifier-posix.c"
20
23
21
-TEST_IMG="$TEST_IMG.base" IMGOPTS="" IMGFMT="raw" _make_test_img $IMG_SIZE |\
24
+static void probe_pci_info(PCIDevice *dev, Error **errp);
22
+TEST_IMG="$TEST_IMG.base" IMGFMT="raw" _make_test_img --no-opts $IMG_SIZE |\
25
+
23
_filter_imgfmt
26
static void proxy_intx_update(PCIDevice *pci_dev)
24
_make_test_img $IMG_SIZE
27
{
25
$QEMU_IO -c "open -o driver=raw,file.driver=blkverify,file.raw.filename=$TEST_IMG.base $TEST_IMG" \
28
PCIProxyDev *dev = PCI_PROXY_DEV(pci_dev);
26
@@ -XXX,XX +XXX,XX @@ echo
29
@@ -XXX,XX +XXX,XX @@ static void pci_proxy_dev_realize(PCIDevice *device, Error **errp)
27
echo "=== Testing blkverify through file blockref ==="
30
{
28
echo
31
ERRP_GUARD();
29
32
PCIProxyDev *dev = PCI_PROXY_DEV(device);
30
-TEST_IMG="$TEST_IMG.base" IMGOPTS="" IMGFMT="raw" _make_test_img $IMG_SIZE |\
33
+ uint8_t *pci_conf = device->config;
31
+TEST_IMG="$TEST_IMG.base" IMGFMT="raw" _make_test_img --no-opts $IMG_SIZE |\
34
int fd;
32
_filter_imgfmt
35
33
_make_test_img $IMG_SIZE
36
if (!dev->fd) {
34
$QEMU_IO -c "open -o driver=raw,file.driver=blkverify,file.raw.filename=$TEST_IMG.base,file.test.driver=$IMGFMT,file.test.file.filename=$TEST_IMG" \
37
@@ -XXX,XX +XXX,XX @@ static void pci_proxy_dev_realize(PCIDevice *device, Error **errp)
35
diff --git a/tests/qemu-iotests/174 b/tests/qemu-iotests/174
38
qemu_mutex_init(&dev->io_mutex);
36
index XXXXXXX..XXXXXXX 100755
39
qio_channel_set_blocking(dev->ioc, true, NULL);
37
--- a/tests/qemu-iotests/174
40
38
+++ b/tests/qemu-iotests/174
41
+ pci_conf[PCI_LATENCY_TIMER] = 0xff;
39
@@ -XXX,XX +XXX,XX @@ _unsupported_fmt raw
42
+ pci_conf[PCI_INTERRUPT_PIN] = 0x01;
40
43
+
41
44
proxy_memory_listener_configure(&dev->proxy_listener, dev->ioc);
42
size=256K
45
43
-IMGFMT=raw IMGKEYSECRET= IMGOPTS= _make_test_img $size | _filter_imgfmt
46
setup_irqfd(dev);
44
+IMGFMT=raw IMGKEYSECRET= _make_test_img --no-opts $size | _filter_imgfmt
47
+
45
48
+ probe_pci_info(PCI_DEVICE(dev), errp);
46
echo
47
echo "== reading wrong format should fail =="
48
diff --git a/tests/qemu-iotests/178 b/tests/qemu-iotests/178
49
index XXXXXXX..XXXXXXX 100755
50
--- a/tests/qemu-iotests/178
51
+++ b/tests/qemu-iotests/178
52
@@ -XXX,XX +XXX,XX @@ $QEMU_IMG measure -O foo "$TEST_IMG" # unknown image file format
53
54
make_test_img_with_fmt() {
55
# Shadow global variables within this function
56
- local IMGFMT="$1" IMGOPTS=""
57
- _make_test_img "$2"
58
+ local IMGFMT="$1"
59
+ _make_test_img --no-opts "$2"
60
}
49
}
61
50
62
qemu_io_with_fmt() {
51
static void pci_proxy_dev_exit(PCIDevice *pdev)
63
diff --git a/tests/qemu-iotests/197 b/tests/qemu-iotests/197
52
@@ -XXX,XX +XXX,XX @@ const MemoryRegionOps proxy_mr_ops = {
64
index XXXXXXX..XXXXXXX 100755
53
.max_access_size = 8,
65
--- a/tests/qemu-iotests/197
54
},
66
+++ b/tests/qemu-iotests/197
55
};
67
@@ -XXX,XX +XXX,XX @@ if [ "$IMGFMT" = "vpc" ]; then
56
+
68
fi
57
+static void probe_pci_info(PCIDevice *dev, Error **errp)
69
_make_test_img 4G
58
+{
70
$QEMU_IO -c "write -P 55 3G 1k" "$TEST_IMG" | _filter_qemu_io
59
+ PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
71
-IMGPROTO=file IMGFMT=qcow2 IMGOPTS= TEST_IMG_FILE="$TEST_WRAP" \
60
+ uint32_t orig_val, new_val, base_class, val;
72
- _make_test_img -F "$IMGFMT" -b "$TEST_IMG" | _filter_img_create
61
+ PCIProxyDev *pdev = PCI_PROXY_DEV(dev);
73
+IMGPROTO=file IMGFMT=qcow2 TEST_IMG_FILE="$TEST_WRAP" \
62
+ DeviceClass *dc = DEVICE_CLASS(pc);
74
+ _make_test_img --no-opts -F "$IMGFMT" -b "$TEST_IMG" | _filter_img_create
63
+ uint8_t type;
75
$QEMU_IO -f qcow2 -c "write -z -u 1M 64k" "$TEST_WRAP" | _filter_qemu_io
64
+ int i, size;
76
65
+
77
# Ensure that a read of two clusters, but where one is already allocated,
66
+ config_op_send(pdev, PCI_VENDOR_ID, &val, 2, MPQEMU_CMD_PCI_CFGREAD);
78
diff --git a/tests/qemu-iotests/215 b/tests/qemu-iotests/215
67
+ pc->vendor_id = (uint16_t)val;
79
index XXXXXXX..XXXXXXX 100755
68
+
80
--- a/tests/qemu-iotests/215
69
+ config_op_send(pdev, PCI_DEVICE_ID, &val, 2, MPQEMU_CMD_PCI_CFGREAD);
81
+++ b/tests/qemu-iotests/215
70
+ pc->device_id = (uint16_t)val;
82
@@ -XXX,XX +XXX,XX @@ if [ "$IMGFMT" = "vpc" ]; then
71
+
83
fi
72
+ config_op_send(pdev, PCI_CLASS_DEVICE, &val, 2, MPQEMU_CMD_PCI_CFGREAD);
84
_make_test_img 4G
73
+ pc->class_id = (uint16_t)val;
85
$QEMU_IO -c "write -P 55 3G 1k" "$TEST_IMG" | _filter_qemu_io
74
+
86
-IMGPROTO=file IMGFMT=qcow2 IMGOPTS= TEST_IMG_FILE="$TEST_WRAP" \
75
+ config_op_send(pdev, PCI_SUBSYSTEM_ID, &val, 2, MPQEMU_CMD_PCI_CFGREAD);
87
- _make_test_img -F "$IMGFMT" -b "$TEST_IMG" | _filter_img_create
76
+ pc->subsystem_id = (uint16_t)val;
88
+IMGPROTO=file IMGFMT=qcow2 TEST_IMG_FILE="$TEST_WRAP" \
77
+
89
+ _make_test_img --no-opts -F "$IMGFMT" -b "$TEST_IMG" | _filter_img_create
78
+ base_class = pc->class_id >> 4;
90
$QEMU_IO -f qcow2 -c "write -z -u 1M 64k" "$TEST_WRAP" | _filter_qemu_io
79
+ switch (base_class) {
91
80
+ case PCI_BASE_CLASS_BRIDGE:
92
# Ensure that a read of two clusters, but where one is already allocated,
81
+ set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
82
+ break;
83
+ case PCI_BASE_CLASS_STORAGE:
84
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
85
+ break;
86
+ case PCI_BASE_CLASS_NETWORK:
87
+ set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
88
+ break;
89
+ case PCI_BASE_CLASS_INPUT:
90
+ set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
91
+ break;
92
+ case PCI_BASE_CLASS_DISPLAY:
93
+ set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
94
+ break;
95
+ case PCI_BASE_CLASS_PROCESSOR:
96
+ set_bit(DEVICE_CATEGORY_CPU, dc->categories);
97
+ break;
98
+ default:
99
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
100
+ break;
101
+ }
102
+
103
+ for (i = 0; i < PCI_NUM_REGIONS; i++) {
104
+ config_op_send(pdev, PCI_BASE_ADDRESS_0 + (4 * i), &orig_val, 4,
105
+ MPQEMU_CMD_PCI_CFGREAD);
106
+ new_val = 0xffffffff;
107
+ config_op_send(pdev, PCI_BASE_ADDRESS_0 + (4 * i), &new_val, 4,
108
+ MPQEMU_CMD_PCI_CFGWRITE);
109
+ config_op_send(pdev, PCI_BASE_ADDRESS_0 + (4 * i), &new_val, 4,
110
+ MPQEMU_CMD_PCI_CFGREAD);
111
+ size = (~(new_val & 0xFFFFFFF0)) + 1;
112
+ config_op_send(pdev, PCI_BASE_ADDRESS_0 + (4 * i), &orig_val, 4,
113
+ MPQEMU_CMD_PCI_CFGWRITE);
114
+ type = (new_val & 0x1) ?
115
+ PCI_BASE_ADDRESS_SPACE_IO : PCI_BASE_ADDRESS_SPACE_MEMORY;
116
+
117
+ if (size) {
118
+ g_autofree char *name;
119
+ pdev->region[i].dev = pdev;
120
+ pdev->region[i].present = true;
121
+ if (type == PCI_BASE_ADDRESS_SPACE_MEMORY) {
122
+ pdev->region[i].memory = true;
123
+ }
124
+ name = g_strdup_printf("bar-region-%d", i);
125
+ memory_region_init_io(&pdev->region[i].mr, OBJECT(pdev),
126
+ &proxy_mr_ops, &pdev->region[i],
127
+ name, size);
128
+ pci_register_bar(dev, i, type, &pdev->region[i].mr);
129
+ }
130
+ }
131
+}
93
--
132
--
94
2.24.1
133
2.29.2
95
134
96
diff view generated by jsdifflib
1
The problem with allowing the data_file option is that you want to use a
1
From: Elena Ufimtseva <elena.ufimtseva@oracle.com>
2
different data file per image used in the test. Therefore, we need to
3
allow patterns like -o data_file='$TEST_IMG.data_file'.
4
2
5
Then, we need to filter it out from qemu-img map, qemu-img create, and
3
Perform device reset in the remote process when QEMU performs
6
remove the data file in _rm_test_img.
4
device reset. This is required to reset the internal state
5
(like registers, etc...) of emulated devices
7
6
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com>
9
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
8
Signed-off-by: John G Johnson <john.g.johnson@oracle.com>
10
Message-id: 20191107163708.833192-23-mreitz@redhat.com
9
Signed-off-by: Jagannathan Raman <jag.raman@oracle.com>
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
11
Message-id: 7cb220a51f565dc0817bd76e2f540e89c2d2b850.1611938319.git.jag.raman@oracle.com
12
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
---
13
---
13
tests/qemu-iotests/common.filter | 23 +++++++++++++++++++++--
14
include/hw/remote/mpqemu-link.h | 1 +
14
tests/qemu-iotests/common.rc | 22 +++++++++++++++++++++-
15
hw/remote/message.c | 22 ++++++++++++++++++++++
15
2 files changed, 42 insertions(+), 3 deletions(-)
16
hw/remote/proxy.c | 19 +++++++++++++++++++
17
3 files changed, 42 insertions(+)
16
18
17
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
19
diff --git a/include/hw/remote/mpqemu-link.h b/include/hw/remote/mpqemu-link.h
18
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
19
--- a/tests/qemu-iotests/common.filter
21
--- a/include/hw/remote/mpqemu-link.h
20
+++ b/tests/qemu-iotests/common.filter
22
+++ b/include/hw/remote/mpqemu-link.h
21
@@ -XXX,XX +XXX,XX @@ _filter_actual_image_size()
23
@@ -XXX,XX +XXX,XX @@ typedef enum {
22
# replace driver-specific options in the "Formatting..." line
24
MPQEMU_CMD_BAR_WRITE,
23
_filter_img_create()
25
MPQEMU_CMD_BAR_READ,
26
MPQEMU_CMD_SET_IRQFD,
27
+ MPQEMU_CMD_DEVICE_RESET,
28
MPQEMU_CMD_MAX,
29
} MPQemuCmd;
30
31
diff --git a/hw/remote/message.c b/hw/remote/message.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/remote/message.c
34
+++ b/hw/remote/message.c
35
@@ -XXX,XX +XXX,XX @@
36
#include "exec/memattrs.h"
37
#include "hw/remote/memory.h"
38
#include "hw/remote/iohub.h"
39
+#include "sysemu/reset.h"
40
41
static void process_config_write(QIOChannel *ioc, PCIDevice *dev,
42
MPQemuMsg *msg, Error **errp);
43
@@ -XXX,XX +XXX,XX @@ static void process_config_read(QIOChannel *ioc, PCIDevice *dev,
44
MPQemuMsg *msg, Error **errp);
45
static void process_bar_write(QIOChannel *ioc, MPQemuMsg *msg, Error **errp);
46
static void process_bar_read(QIOChannel *ioc, MPQemuMsg *msg, Error **errp);
47
+static void process_device_reset_msg(QIOChannel *ioc, PCIDevice *dev,
48
+ Error **errp);
49
50
void coroutine_fn mpqemu_remote_msg_loop_co(void *data)
24
{
51
{
25
- $SED -e "s#$REMOTE_TEST_DIR#TEST_DIR#g" \
52
@@ -XXX,XX +XXX,XX @@ void coroutine_fn mpqemu_remote_msg_loop_co(void *data)
26
+ data_file_filter=()
53
case MPQEMU_CMD_SET_IRQFD:
27
+ if data_file=$(_get_data_file "$TEST_IMG"); then
54
process_set_irqfd_msg(pci_dev, &msg);
28
+ data_file_filter=(-e "s# data_file=$data_file##")
55
break;
29
+ fi
56
+ case MPQEMU_CMD_DEVICE_RESET:
57
+ process_device_reset_msg(com->ioc, pci_dev, &local_err);
58
+ break;
59
default:
60
error_setg(&local_err,
61
"Unknown command (%d) received for device %s"
62
@@ -XXX,XX +XXX,XX @@ fail:
63
getpid());
64
}
65
}
30
+
66
+
31
+ $SED "${data_file_filter[@]}" \
67
+static void process_device_reset_msg(QIOChannel *ioc, PCIDevice *dev,
32
+ -e "s#$REMOTE_TEST_DIR#TEST_DIR#g" \
68
+ Error **errp)
33
-e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \
69
+{
34
-e "s#$TEST_DIR#TEST_DIR#g" \
70
+ DeviceClass *dc = DEVICE_GET_CLASS(dev);
35
-e "s#$SOCK_DIR#SOCK_DIR#g" \
71
+ DeviceState *s = DEVICE(dev);
36
@@ -XXX,XX +XXX,XX @@ _filter_img_info()
72
+ MPQemuMsg ret = { 0 };
37
# human and json output
73
+
38
_filter_qemu_img_map()
74
+ if (dc->reset) {
75
+ dc->reset(s);
76
+ }
77
+
78
+ ret.cmd = MPQEMU_CMD_RET;
79
+
80
+ mpqemu_msg_send(&ret, ioc, errp);
81
+}
82
diff --git a/hw/remote/proxy.c b/hw/remote/proxy.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/hw/remote/proxy.c
85
+++ b/hw/remote/proxy.c
86
@@ -XXX,XX +XXX,XX @@
87
#include "util/event_notifier-posix.c"
88
89
static void probe_pci_info(PCIDevice *dev, Error **errp);
90
+static void proxy_device_reset(DeviceState *dev);
91
92
static void proxy_intx_update(PCIDevice *pci_dev)
39
{
93
{
40
+ # Assuming the data_file value in $IMGOPTS contains a '$TEST_IMG',
94
@@ -XXX,XX +XXX,XX @@ static void pci_proxy_dev_class_init(ObjectClass *klass, void *data)
41
+ # create a filter that replaces the data file name by $TEST_IMG.
95
k->config_read = pci_proxy_read_config;
42
+ # Example:
96
k->config_write = pci_proxy_write_config;
43
+ # In $IMGOPTS: 'data_file=$TEST_IMG.data_file'
97
44
+ # Then data_file_pattern == '\(.*\).data_file'
98
+ dc->reset = proxy_device_reset;
45
+ # And data_file_filter == -e 's#\(.*\).data_file#\1#
46
+ data_file_filter=()
47
+ if data_file_pattern=$(_get_data_file '\\(.*\\)'); then
48
+ data_file_filter=(-e "s#$data_file_pattern#\\1#")
49
+ fi
50
+
99
+
51
$SED -e 's/\([0-9a-fx]* *[0-9a-fx]* *\)[0-9a-fx]* */\1/g' \
100
device_class_set_props(dc, proxy_properties);
52
-e 's/"offset": [0-9]\+/"offset": OFFSET/g' \
53
- -e 's/Mapped to *//' | _filter_testdir | _filter_imgfmt
54
+ -e 's/Mapped to *//' \
55
+ "${data_file_filter[@]}" \
56
+ | _filter_testdir | _filter_imgfmt
57
}
101
}
58
102
59
_filter_nbd()
103
@@ -XXX,XX +XXX,XX @@ static void probe_pci_info(PCIDevice *dev, Error **errp)
60
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
104
}
61
index XXXXXXX..XXXXXXX 100644
105
}
62
--- a/tests/qemu-iotests/common.rc
63
+++ b/tests/qemu-iotests/common.rc
64
@@ -XXX,XX +XXX,XX @@ _stop_nbd_server()
65
fi
66
}
106
}
67
107
+
68
+# Gets the data_file value from IMGOPTS and replaces the '$TEST_IMG'
108
+static void proxy_device_reset(DeviceState *dev)
69
+# pattern by '$1'
70
+# Caution: The replacement is done with sed, so $1 must be escaped
71
+# properly. (The delimiter is '#'.)
72
+_get_data_file()
73
+{
109
+{
74
+ if ! echo "$IMGOPTS" | grep -q 'data_file='; then
110
+ PCIProxyDev *pdev = PCI_PROXY_DEV(dev);
75
+ return 1
111
+ MPQemuMsg msg = { 0 };
76
+ fi
112
+ Error *local_err = NULL;
77
+
113
+
78
+ echo "$IMGOPTS" | sed -e 's/.*data_file=\([^,]*\).*/\1/' \
114
+ msg.cmd = MPQEMU_CMD_DEVICE_RESET;
79
+ | sed -e "s#\\\$TEST_IMG#$1#"
115
+ msg.size = 0;
116
+
117
+ mpqemu_msg_send_and_await_reply(&msg, pdev, &local_err);
118
+ if (local_err) {
119
+ error_report_err(local_err);
120
+ }
121
+
80
+}
122
+}
81
+
82
_make_test_img()
83
{
84
# extra qemu-img options can be added by tests
85
@@ -XXX,XX +XXX,XX @@ _make_test_img()
86
fi
87
88
if [ -n "$IMGOPTS" ]; then
89
- optstr=$(_optstr_add "$optstr" "$IMGOPTS")
90
+ imgopts_expanded=$(echo "$IMGOPTS" | sed -e "s#\\\$TEST_IMG#$img_name#")
91
+ optstr=$(_optstr_add "$optstr" "$imgopts_expanded")
92
fi
93
if [ -n "$IMGKEYSECRET" ]; then
94
object_options="--object secret,id=keysec0,data=$IMGKEYSECRET"
95
@@ -XXX,XX +XXX,XX @@ _rm_test_img()
96
# Remove all the extents for vmdk
97
"$QEMU_IMG" info "$img" 2>/dev/null | grep 'filename:' | cut -f 2 -d: \
98
| xargs -I {} rm -f "{}"
99
+ elif [ "$IMGFMT" = "qcow2" ]; then
100
+ # Remove external data file
101
+ if data_file=$(_get_data_file "$img"); then
102
+ rm -f "$data_file"
103
+ fi
104
fi
105
rm -f "$img"
106
}
107
--
123
--
108
2.24.1
124
2.29.2
109
125
110
diff view generated by jsdifflib
1
It did not matter before, but now that _make_test_img understands -o, we
1
From: "Denis V. Lunev" <den@openvz.org>
2
should use it properly here.
3
2
4
Signed-off-by: Max Reitz <mreitz@redhat.com>
3
Original specification says that l1 table size if 64 * l1_size, which
5
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
4
is obviously wrong. The size of the l1 entry is 64 _bits_, not bytes.
6
Message-id: 20191107163708.833192-11-mreitz@redhat.com
5
Thus 64 is to be replaces with 8 as specification says about bytes.
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
7
There is also minor tweak, field name is renamed from l1 to l1_table,
8
which matches with the later text.
9
10
Signed-off-by: Denis V. Lunev <den@openvz.org>
11
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
12
Message-id: 20210128171313.2210947-1-den@openvz.org
13
CC: Stefan Hajnoczi <stefanha@redhat.com>
14
CC: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
15
16
[Replace the original commit message "docs: fix mistake in dirty bitmap
17
feature description" as suggested by Eric Blake.
18
--Stefan]
19
20
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
8
---
21
---
9
tests/qemu-iotests/051 | 2 +-
22
docs/interop/parallels.txt | 2 +-
10
1 file changed, 1 insertion(+), 1 deletion(-)
23
1 file changed, 1 insertion(+), 1 deletion(-)
11
24
12
diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051
25
diff --git a/docs/interop/parallels.txt b/docs/interop/parallels.txt
13
index XXXXXXX..XXXXXXX 100755
26
index XXXXXXX..XXXXXXX 100644
14
--- a/tests/qemu-iotests/051
27
--- a/docs/interop/parallels.txt
15
+++ b/tests/qemu-iotests/051
28
+++ b/docs/interop/parallels.txt
16
@@ -XXX,XX +XXX,XX @@ echo
29
@@ -XXX,XX +XXX,XX @@ of its data area are:
17
echo === With version 2 images enabling lazy refcounts must fail ===
30
28 - 31: l1_size
18
echo
31
The number of entries in the L1 table of the bitmap.
19
32
20
-_make_test_img -ocompat=0.10 $size
33
- variable: l1 (64 * l1_size bytes)
21
+_make_test_img -o compat=0.10 $size
34
+ variable: l1_table (8 * l1_size bytes)
22
35
L1 offset table (in bytes)
23
run_qemu -drive file="$TEST_IMG",format=qcow2,lazy-refcounts=on
36
24
run_qemu -drive file="$TEST_IMG",format=qcow2,lazy-refcounts=off
37
A dirty bitmap is stored using a one-level structure for the mapping to host
25
--
38
--
26
2.24.1
39
2.29.2
27
40
28
diff view generated by jsdifflib