1 | The following changes since commit 07f426c35eddd79388a23d11cb278600d7e3831d: | 1 | The following changes since commit 0a301624c2f4ced3331ffd5bce85b4274fe132af: |
---|---|---|---|
2 | 2 | ||
3 | Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20180926' into staging (2018-09-28 18:56:09 +0100) | 3 | Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20220208' into staging (2022-02-08 11:40:08 +0000) |
4 | 4 | ||
5 | are available in the git repository at: | 5 | are available in the Git repository at: |
6 | 6 | ||
7 | git://repo.or.cz/qemu/kevin.git tags/for-upstream | 7 | https://gitlab.com/kmwolf/qemu.git tags/for-upstream |
8 | 8 | ||
9 | for you to fetch changes up to dd353157942a59c21da07da5ac8749a871f7c3ed: | 9 | for you to fetch changes up to fdb8541b2e4f6ff60f435fbb5a5e1df20c275a86: |
10 | 10 | ||
11 | tests/test-bdrv-drain: Fix too late qemu_event_reset() (2018-10-01 19:13:55 +0200) | 11 | hw/block/fdc-isa: Respect QOM properties when building AML (2022-02-11 17:37:26 +0100) |
12 | 12 | ||
13 | ---------------------------------------------------------------- | 13 | ---------------------------------------------------------------- |
14 | Block layer patches: | 14 | Block layer patches |
15 | 15 | ||
16 | - qcow2 cache option default changes (Linux: 32 MB maximum, limited by | 16 | - Fix crash in blockdev-reopen with iothreads |
17 | whatever cache size can be made use of with the specific image; | 17 | - fdc-isa: Respect QOM properties when building AML |
18 | default cache-clean-interval of 10 minutes) | ||
19 | - reopen: Allow specifying unchanged child node references, and changing | ||
20 | a few generic options (discard, detect-zeroes) | ||
21 | - Fix werror/rerror defaults for -device drive=<node-name> | ||
22 | - Test case fixes | ||
23 | 18 | ||
24 | ---------------------------------------------------------------- | 19 | ---------------------------------------------------------------- |
25 | Alberto Garcia (9): | 20 | Bernhard Beschow (1): |
26 | qemu-io: Fix writethrough check in reopen | 21 | hw/block/fdc-isa: Respect QOM properties when building AML |
27 | file-posix: x-check-cache-dropped should default to false on reopen | ||
28 | block: Remove child references from bs->{options,explicit_options} | ||
29 | block: Don't look for child references in append_open_options() | ||
30 | block: Allow child references on reopen | ||
31 | block: Forbid trying to change unsupported options during reopen | ||
32 | file-posix: Forbid trying to change unsupported options during reopen | ||
33 | block: Allow changing 'discard' on reopen | ||
34 | block: Allow changing 'detect-zeroes' on reopen | ||
35 | 22 | ||
36 | Fam Zheng (1): | 23 | Kevin Wolf (2): |
37 | file-posix: Include filename in locking error message | 24 | block: Lock AioContext for drain_end in blockdev-reopen |
25 | iotests: Test blockdev-reopen with iothreads and throttling | ||
38 | 26 | ||
39 | Kevin Wolf (3): | 27 | blockdev.c | 11 ++++++++++- |
40 | block-backend: Set werror/rerror defaults in blk_new() | 28 | hw/block/fdc-isa.c | 11 +++++++---- |
41 | test-replication: Lock AioContext around blk_unref() | 29 | tests/qemu-iotests/245 | 36 +++++++++++++++++++++++++++++++++--- |
42 | tests/test-bdrv-drain: Fix too late qemu_event_reset() | 30 | tests/qemu-iotests/245.out | 4 ++-- |
31 | 4 files changed, 52 insertions(+), 10 deletions(-) | ||
43 | 32 | ||
44 | Leonid Bloch (10): | ||
45 | qcow2: Options' documentation fixes | ||
46 | include: Add a lookup table of sizes | ||
47 | qcow2: Make sizes more humanly readable | ||
48 | qcow2: Avoid duplication in setting the refcount cache size | ||
49 | qcow2: Assign the L2 cache relatively to the image size | ||
50 | qcow2: Increase the default upper limit on the L2 cache size | ||
51 | qcow2: Resize the cache upon image resizing | ||
52 | qcow2: Set the default cache-clean-interval to 10 minutes | ||
53 | qcow2: Explicit number replaced by a constant | ||
54 | qcow2: Fix cache-clean-interval documentation | ||
55 | 33 | ||
56 | qapi/block-core.json | 4 +- | ||
57 | docs/qcow2-cache.txt | 59 ++++++++++++-------- | ||
58 | block/qcow2.h | 19 ++++--- | ||
59 | include/block/block.h | 1 + | ||
60 | include/qemu/units.h | 55 ++++++++++++++++++ | ||
61 | block.c | 135 +++++++++++++++++++++++++++++---------------- | ||
62 | block/block-backend.c | 3 + | ||
63 | block/file-posix.c | 19 +++++-- | ||
64 | block/qcow2.c | 43 +++++++++------ | ||
65 | qemu-io-cmds.c | 2 +- | ||
66 | tests/test-bdrv-drain.c | 4 +- | ||
67 | tests/test-replication.c | 11 ++++ | ||
68 | qemu-options.hx | 12 ++-- | ||
69 | tests/qemu-iotests/067.out | 1 + | ||
70 | tests/qemu-iotests/137 | 8 ++- | ||
71 | tests/qemu-iotests/137.out | 4 +- | ||
72 | tests/qemu-iotests/153.out | 76 ++++++++++++------------- | ||
73 | tests/qemu-iotests/182.out | 2 +- | ||
74 | 18 files changed, 307 insertions(+), 151 deletions(-) | ||
75 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Fam Zheng <famz@redhat.com> | ||
2 | 1 | ||
3 | Image locking errors happening at device initialization time doesn't say | ||
4 | which file cannot be locked, for instance, | ||
5 | |||
6 | -device scsi-disk,drive=drive-1: Failed to get shared "write" lock | ||
7 | Is another process using the image? | ||
8 | |||
9 | could refer to either the overlay image or its backing image. | ||
10 | |||
11 | Hoist the error_append_hint to the caller of raw_check_lock_bytes where | ||
12 | file name is known, and include it in the error hint. | ||
13 | |||
14 | Signed-off-by: Fam Zheng <famz@redhat.com> | ||
15 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
16 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
17 | --- | ||
18 | block/file-posix.c | 10 +++--- | ||
19 | tests/qemu-iotests/153.out | 76 +++++++++++++++++++++++----------------------- | ||
20 | tests/qemu-iotests/182.out | 2 +- | ||
21 | 3 files changed, 45 insertions(+), 43 deletions(-) | ||
22 | |||
23 | diff --git a/block/file-posix.c b/block/file-posix.c | ||
24 | index XXXXXXX..XXXXXXX 100644 | ||
25 | --- a/block/file-posix.c | ||
26 | +++ b/block/file-posix.c | ||
27 | @@ -XXX,XX +XXX,XX @@ static int raw_check_lock_bytes(int fd, uint64_t perm, uint64_t shared_perm, | ||
28 | "Failed to get \"%s\" lock", | ||
29 | perm_name); | ||
30 | g_free(perm_name); | ||
31 | - error_append_hint(errp, | ||
32 | - "Is another process using the image?\n"); | ||
33 | return ret; | ||
34 | } | ||
35 | } | ||
36 | @@ -XXX,XX +XXX,XX @@ static int raw_check_lock_bytes(int fd, uint64_t perm, uint64_t shared_perm, | ||
37 | "Failed to get shared \"%s\" lock", | ||
38 | perm_name); | ||
39 | g_free(perm_name); | ||
40 | - error_append_hint(errp, | ||
41 | - "Is another process using the image?\n"); | ||
42 | return ret; | ||
43 | } | ||
44 | } | ||
45 | @@ -XXX,XX +XXX,XX @@ static int raw_handle_perm_lock(BlockDriverState *bs, | ||
46 | if (!ret) { | ||
47 | return 0; | ||
48 | } | ||
49 | + error_append_hint(errp, | ||
50 | + "Is another process using the image [%s]?\n", | ||
51 | + bs->filename); | ||
52 | } | ||
53 | op = RAW_PL_ABORT; | ||
54 | /* fall through to unlock bytes. */ | ||
55 | @@ -XXX,XX +XXX,XX @@ raw_co_create(BlockdevCreateOptions *options, Error **errp) | ||
56 | /* Step two: Check that nobody else has taken conflicting locks */ | ||
57 | result = raw_check_lock_bytes(fd, perm, shared, errp); | ||
58 | if (result < 0) { | ||
59 | + error_append_hint(errp, | ||
60 | + "Is another process using the image [%s]?\n", | ||
61 | + file_opts->filename); | ||
62 | goto out_unlock; | ||
63 | } | ||
64 | |||
65 | diff --git a/tests/qemu-iotests/153.out b/tests/qemu-iotests/153.out | ||
66 | index XXXXXXX..XXXXXXX 100644 | ||
67 | --- a/tests/qemu-iotests/153.out | ||
68 | +++ b/tests/qemu-iotests/153.out | ||
69 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33554432 backing_file=TEST_DIR/t | ||
70 | |||
71 | == Launching another QEMU, opts: '' == | ||
72 | QEMU_PROG: -drive file=TEST_DIR/t.qcow2,if=none,: Failed to get "write" lock | ||
73 | -Is another process using the image? | ||
74 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
75 | |||
76 | == Launching another QEMU, opts: 'read-only=on' == | ||
77 | QEMU_PROG: -drive file=TEST_DIR/t.qcow2,if=none,read-only=on: Failed to get shared "write" lock | ||
78 | -Is another process using the image? | ||
79 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
80 | |||
81 | == Launching another QEMU, opts: 'read-only=on,force-share=on' == | ||
82 | |||
83 | @@ -XXX,XX +XXX,XX @@ Is another process using the image? | ||
84 | |||
85 | _qemu_io_wrapper -c read 0 512 TEST_DIR/t.qcow2 | ||
86 | can't open device TEST_DIR/t.qcow2: Failed to get "write" lock | ||
87 | -Is another process using the image? | ||
88 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
89 | |||
90 | _qemu_io_wrapper -r -c read 0 512 TEST_DIR/t.qcow2 | ||
91 | can't open device TEST_DIR/t.qcow2: Failed to get shared "write" lock | ||
92 | -Is another process using the image? | ||
93 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
94 | |||
95 | _qemu_io_wrapper -c open TEST_DIR/t.qcow2 -c read 0 512 | ||
96 | can't open device TEST_DIR/t.qcow2: Failed to get "write" lock | ||
97 | -Is another process using the image? | ||
98 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
99 | no file open, try 'help open' | ||
100 | |||
101 | _qemu_io_wrapper -c open -r TEST_DIR/t.qcow2 -c read 0 512 | ||
102 | can't open device TEST_DIR/t.qcow2: Failed to get shared "write" lock | ||
103 | -Is another process using the image? | ||
104 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
105 | no file open, try 'help open' | ||
106 | |||
107 | _qemu_img_wrapper info TEST_DIR/t.qcow2 | ||
108 | qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get shared "write" lock | ||
109 | -Is another process using the image? | ||
110 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
111 | |||
112 | _qemu_img_wrapper check TEST_DIR/t.qcow2 | ||
113 | qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get shared "write" lock | ||
114 | -Is another process using the image? | ||
115 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
116 | |||
117 | _qemu_img_wrapper compare TEST_DIR/t.qcow2 TEST_DIR/t.qcow2 | ||
118 | qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get shared "write" lock | ||
119 | -Is another process using the image? | ||
120 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
121 | |||
122 | _qemu_img_wrapper map TEST_DIR/t.qcow2 | ||
123 | qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get shared "write" lock | ||
124 | -Is another process using the image? | ||
125 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
126 | |||
127 | _qemu_img_wrapper amend -o TEST_DIR/t.qcow2 | ||
128 | qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get "write" lock | ||
129 | -Is another process using the image? | ||
130 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
131 | |||
132 | _qemu_img_wrapper commit TEST_DIR/t.qcow2 | ||
133 | qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get "write" lock | ||
134 | -Is another process using the image? | ||
135 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
136 | |||
137 | _qemu_img_wrapper resize TEST_DIR/t.qcow2 32M | ||
138 | qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get "write" lock | ||
139 | -Is another process using the image? | ||
140 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
141 | |||
142 | _qemu_img_wrapper rebase TEST_DIR/t.qcow2 -b TEST_DIR/t.qcow2.base | ||
143 | qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get "write" lock | ||
144 | -Is another process using the image? | ||
145 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
146 | |||
147 | _qemu_img_wrapper snapshot -l TEST_DIR/t.qcow2 | ||
148 | qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get shared "write" lock | ||
149 | -Is another process using the image? | ||
150 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
151 | |||
152 | _qemu_img_wrapper convert TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.convert | ||
153 | qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get shared "write" lock | ||
154 | -Is another process using the image? | ||
155 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
156 | |||
157 | _qemu_img_wrapper dd if=TEST_DIR/t.qcow2 of=TEST_DIR/t.qcow2.convert bs=512 count=1 | ||
158 | qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get shared "write" lock | ||
159 | -Is another process using the image? | ||
160 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
161 | |||
162 | _qemu_img_wrapper bench -c 1 TEST_DIR/t.qcow2 | ||
163 | qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get shared "write" lock | ||
164 | -Is another process using the image? | ||
165 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
166 | |||
167 | _qemu_img_wrapper bench -w -c 1 TEST_DIR/t.qcow2 | ||
168 | qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get "write" lock | ||
169 | -Is another process using the image? | ||
170 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
171 | |||
172 | _qemu_img_wrapper create -f qcow2 TEST_DIR/t.qcow2 -b TEST_DIR/t.qcow2.base | ||
173 | qemu-img: TEST_DIR/t.qcow2: Failed to get "write" lock | ||
174 | -Is another process using the image? | ||
175 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
176 | file format: IMGFMT | ||
177 | |||
178 | == Running utility commands -U == | ||
179 | @@ -XXX,XX +XXX,XX @@ Try 'qemu-img --help' for more information | ||
180 | |||
181 | _qemu_img_wrapper rebase -U TEST_DIR/t.qcow2 -b TEST_DIR/t.qcow2.base | ||
182 | qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get "write" lock | ||
183 | -Is another process using the image? | ||
184 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
185 | |||
186 | _qemu_img_wrapper snapshot -l -U TEST_DIR/t.qcow2 | ||
187 | |||
188 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33554432 backing_file=TEST_DIR/t | ||
189 | |||
190 | == Launching another QEMU, opts: '' == | ||
191 | QEMU_PROG: -drive file=TEST_DIR/t.qcow2,if=none,: Failed to get "write" lock | ||
192 | -Is another process using the image? | ||
193 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
194 | |||
195 | == Launching another QEMU, opts: 'read-only=on' == | ||
196 | |||
197 | @@ -XXX,XX +XXX,XX @@ Is another process using the image? | ||
198 | |||
199 | _qemu_io_wrapper -c read 0 512 TEST_DIR/t.qcow2 | ||
200 | can't open device TEST_DIR/t.qcow2: Failed to get "write" lock | ||
201 | -Is another process using the image? | ||
202 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
203 | |||
204 | _qemu_io_wrapper -r -c read 0 512 TEST_DIR/t.qcow2 | ||
205 | |||
206 | _qemu_io_wrapper -c open TEST_DIR/t.qcow2 -c read 0 512 | ||
207 | can't open device TEST_DIR/t.qcow2: Failed to get "write" lock | ||
208 | -Is another process using the image? | ||
209 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
210 | no file open, try 'help open' | ||
211 | |||
212 | _qemu_io_wrapper -c open -r TEST_DIR/t.qcow2 -c read 0 512 | ||
213 | @@ -XXX,XX +XXX,XX @@ _qemu_img_wrapper map TEST_DIR/t.qcow2 | ||
214 | |||
215 | _qemu_img_wrapper amend -o TEST_DIR/t.qcow2 | ||
216 | qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get "write" lock | ||
217 | -Is another process using the image? | ||
218 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
219 | |||
220 | _qemu_img_wrapper commit TEST_DIR/t.qcow2 | ||
221 | qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get "write" lock | ||
222 | -Is another process using the image? | ||
223 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
224 | |||
225 | _qemu_img_wrapper resize TEST_DIR/t.qcow2 32M | ||
226 | qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get "write" lock | ||
227 | -Is another process using the image? | ||
228 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
229 | |||
230 | _qemu_img_wrapper rebase TEST_DIR/t.qcow2 -b TEST_DIR/t.qcow2.base | ||
231 | qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get "write" lock | ||
232 | -Is another process using the image? | ||
233 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
234 | |||
235 | _qemu_img_wrapper snapshot -l TEST_DIR/t.qcow2 | ||
236 | |||
237 | @@ -XXX,XX +XXX,XX @@ _qemu_img_wrapper bench -c 1 TEST_DIR/t.qcow2 | ||
238 | |||
239 | _qemu_img_wrapper bench -w -c 1 TEST_DIR/t.qcow2 | ||
240 | qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get "write" lock | ||
241 | -Is another process using the image? | ||
242 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
243 | |||
244 | _qemu_img_wrapper create -f qcow2 TEST_DIR/t.qcow2 -b TEST_DIR/t.qcow2.base | ||
245 | qemu-img: TEST_DIR/t.qcow2: Failed to get "write" lock | ||
246 | -Is another process using the image? | ||
247 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
248 | file format: IMGFMT | ||
249 | |||
250 | == Running utility commands -U == | ||
251 | @@ -XXX,XX +XXX,XX @@ Try 'qemu-img --help' for more information | ||
252 | |||
253 | _qemu_img_wrapper rebase -U TEST_DIR/t.qcow2 -b TEST_DIR/t.qcow2.base | ||
254 | qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get "write" lock | ||
255 | -Is another process using the image? | ||
256 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
257 | |||
258 | _qemu_img_wrapper snapshot -l -U TEST_DIR/t.qcow2 | ||
259 | |||
260 | @@ -XXX,XX +XXX,XX @@ Round done | ||
261 | |||
262 | == Two devices with the same image (read-only=off - read-only=off) == | ||
263 | QEMU_PROG: -drive if=none,file=TEST_DIR/t.qcow2,read-only=off: Failed to get "write" lock | ||
264 | -Is another process using the image? | ||
265 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
266 | |||
267 | == Two devices with the same image (read-only=off - read-only=on) == | ||
268 | QEMU_PROG: -drive if=none,file=TEST_DIR/t.qcow2,read-only=on: Failed to get shared "write" lock | ||
269 | -Is another process using the image? | ||
270 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
271 | |||
272 | == Two devices with the same image (read-only=off - read-only=on,force-share=on) == | ||
273 | |||
274 | == Two devices with the same image (read-only=on - read-only=off) == | ||
275 | QEMU_PROG: -drive if=none,file=TEST_DIR/t.qcow2,read-only=off: Failed to get "write" lock | ||
276 | -Is another process using the image? | ||
277 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
278 | |||
279 | == Two devices with the same image (read-only=on - read-only=on) == | ||
280 | |||
281 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT.c', fmt=IMGFMT size=33554432 backing_file=TEST_DIR | ||
282 | |||
283 | == Backing image also as an active device == | ||
284 | QEMU_PROG: -drive if=none,file=TEST_DIR/t.qcow2: Failed to get "write" lock | ||
285 | -Is another process using the image? | ||
286 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
287 | |||
288 | == Backing image also as an active device (ro) == | ||
289 | |||
290 | == Symbolic link == | ||
291 | QEMU_PROG: -drive if=none,file=TEST_DIR/t.qcow2: Failed to get "write" lock | ||
292 | -Is another process using the image? | ||
293 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
294 | |||
295 | == Active commit to intermediate layer should work when base in use == | ||
296 | {"return": {}} | ||
297 | @@ -XXX,XX +XXX,XX @@ Adding drive | ||
298 | |||
299 | _qemu_io_wrapper TEST_DIR/t.qcow2 -c write 0 512 | ||
300 | can't open device TEST_DIR/t.qcow2: Failed to get "write" lock | ||
301 | -Is another process using the image? | ||
302 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
303 | Creating overlay with qemu-img when the guest is running should be allowed | ||
304 | |||
305 | _qemu_img_wrapper create -f qcow2 -b TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.overlay | ||
306 | @@ -XXX,XX +XXX,XX @@ _qemu_img_wrapper info TEST_DIR/t.qcow2 | ||
307 | |||
308 | _qemu_io_wrapper TEST_DIR/t.qcow2 -c write 0 512 | ||
309 | can't open device TEST_DIR/t.qcow2: Failed to get "write" lock | ||
310 | -Is another process using the image? | ||
311 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
312 | Closing the other | ||
313 | |||
314 | _qemu_io_wrapper TEST_DIR/t.qcow2 -c write 0 512 | ||
315 | diff --git a/tests/qemu-iotests/182.out b/tests/qemu-iotests/182.out | ||
316 | index XXXXXXX..XXXXXXX 100644 | ||
317 | --- a/tests/qemu-iotests/182.out | ||
318 | +++ b/tests/qemu-iotests/182.out | ||
319 | @@ -XXX,XX +XXX,XX @@ Starting QEMU | ||
320 | |||
321 | Starting a second QEMU using the same image should fail | ||
322 | QEMU_PROG: -drive file=TEST_DIR/t.qcow2,if=none,id=drive0,file.locking=on: Failed to get "write" lock | ||
323 | -Is another process using the image? | ||
324 | +Is another process using the image [TEST_DIR/t.qcow2]? | ||
325 | *** done | ||
326 | -- | ||
327 | 2.13.6 | ||
328 | |||
329 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Alberto Garcia <berto@igalia.com> | ||
2 | 1 | ||
3 | "qemu-io reopen" doesn't allow changing the writethrough setting of | ||
4 | the cache, but the check is wrong, causing an error even on a simple | ||
5 | reopen with the default parameters: | ||
6 | |||
7 | $ qemu-img create -f qcow2 hd.qcow2 1M | ||
8 | $ qemu-system-x86_64 -monitor stdio -drive if=virtio,file=hd.qcow2 | ||
9 | (qemu) qemu-io virtio0 reopen | ||
10 | Cannot change cache.writeback: Device attached | ||
11 | |||
12 | Signed-off-by: Alberto Garcia <berto@igalia.com> | ||
13 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
14 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
15 | --- | ||
16 | qemu-io-cmds.c | 2 +- | ||
17 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
18 | |||
19 | diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c | ||
20 | index XXXXXXX..XXXXXXX 100644 | ||
21 | --- a/qemu-io-cmds.c | ||
22 | +++ b/qemu-io-cmds.c | ||
23 | @@ -XXX,XX +XXX,XX @@ static int reopen_f(BlockBackend *blk, int argc, char **argv) | ||
24 | return -EINVAL; | ||
25 | } | ||
26 | |||
27 | - if (writethrough != blk_enable_write_cache(blk) && | ||
28 | + if (!writethrough != blk_enable_write_cache(blk) && | ||
29 | blk_get_attached_dev(blk)) | ||
30 | { | ||
31 | error_report("Cannot change cache.writeback: Device attached"); | ||
32 | -- | ||
33 | 2.13.6 | ||
34 | |||
35 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Alberto Garcia <berto@igalia.com> | ||
2 | 1 | ||
3 | The default value of x-check-cache-dropped is false. There's no reason | ||
4 | to use the previous value as a default in raw_reopen_prepare() because | ||
5 | bdrv_reopen_queue_child() already takes care of putting the old | ||
6 | options in the BDRVReopenState.options QDict. | ||
7 | |||
8 | If x-check-cache-dropped was previously set but is now missing from | ||
9 | the reopen QDict then it should be reset to false. | ||
10 | |||
11 | Signed-off-by: Alberto Garcia <berto@igalia.com> | ||
12 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
13 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
14 | --- | ||
15 | block/file-posix.c | 2 +- | ||
16 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
17 | |||
18 | diff --git a/block/file-posix.c b/block/file-posix.c | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/block/file-posix.c | ||
21 | +++ b/block/file-posix.c | ||
22 | @@ -XXX,XX +XXX,XX @@ static int raw_reopen_prepare(BDRVReopenState *state, | ||
23 | } | ||
24 | |||
25 | rs->check_cache_dropped = qemu_opt_get_bool(opts, "x-check-cache-dropped", | ||
26 | - s->check_cache_dropped); | ||
27 | + false); | ||
28 | |||
29 | if (s->type == FTYPE_CD) { | ||
30 | rs->open_flags |= O_NONBLOCK; | ||
31 | -- | ||
32 | 2.13.6 | ||
33 | |||
34 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Alberto Garcia <berto@igalia.com> | ||
2 | 1 | ||
3 | Block drivers allow opening their children using a reference to an | ||
4 | existing BlockDriverState. These references remain stored in the | ||
5 | 'options' and 'explicit_options' QDicts, but we don't need to keep | ||
6 | them once everything is open. | ||
7 | |||
8 | What is more important, these values can become wrong if the children | ||
9 | change: | ||
10 | |||
11 | $ qemu-img create -f qcow2 hd0.qcow2 10M | ||
12 | $ qemu-img create -f qcow2 hd1.qcow2 10M | ||
13 | $ qemu-img create -f qcow2 hd2.qcow2 10M | ||
14 | $ $QEMU -drive if=none,file=hd0.qcow2,node-name=hd0 \ | ||
15 | -drive if=none,file=hd1.qcow2,node-name=hd1,backing=hd0 \ | ||
16 | -drive file=hd2.qcow2,node-name=hd2,backing=hd1 | ||
17 | |||
18 | After this hd2 has hd1 as its backing file. Now let's remove it using | ||
19 | block_stream: | ||
20 | |||
21 | (qemu) block_stream hd2 0 hd0.qcow2 | ||
22 | |||
23 | Now hd0 is the backing file of hd2, but hd2's options QDicts still | ||
24 | contain backing=hd1. | ||
25 | |||
26 | Signed-off-by: Alberto Garcia <berto@igalia.com> | ||
27 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
28 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
29 | --- | ||
30 | block.c | 13 ++++++++++++- | ||
31 | 1 file changed, 12 insertions(+), 1 deletion(-) | ||
32 | |||
33 | diff --git a/block.c b/block.c | ||
34 | index XXXXXXX..XXXXXXX 100644 | ||
35 | --- a/block.c | ||
36 | +++ b/block.c | ||
37 | @@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_open_inherit(const char *filename, | ||
38 | } | ||
39 | } | ||
40 | |||
41 | - /* Remove all children options from bs->options and bs->explicit_options */ | ||
42 | + /* Remove all children options and references | ||
43 | + * from bs->options and bs->explicit_options */ | ||
44 | QLIST_FOREACH(child, &bs->children, next) { | ||
45 | char *child_key_dot; | ||
46 | child_key_dot = g_strdup_printf("%s.", child->name); | ||
47 | qdict_extract_subqdict(bs->explicit_options, NULL, child_key_dot); | ||
48 | qdict_extract_subqdict(bs->options, NULL, child_key_dot); | ||
49 | + qdict_del(bs->explicit_options, child->name); | ||
50 | + qdict_del(bs->options, child->name); | ||
51 | g_free(child_key_dot); | ||
52 | } | ||
53 | |||
54 | @@ -XXX,XX +XXX,XX @@ void bdrv_reopen_commit(BDRVReopenState *reopen_state) | ||
55 | { | ||
56 | BlockDriver *drv; | ||
57 | BlockDriverState *bs; | ||
58 | + BdrvChild *child; | ||
59 | bool old_can_write, new_can_write; | ||
60 | |||
61 | assert(reopen_state != NULL); | ||
62 | @@ -XXX,XX +XXX,XX @@ void bdrv_reopen_commit(BDRVReopenState *reopen_state) | ||
63 | bs->open_flags = reopen_state->flags; | ||
64 | bs->read_only = !(reopen_state->flags & BDRV_O_RDWR); | ||
65 | |||
66 | + /* Remove child references from bs->options and bs->explicit_options. | ||
67 | + * Child options were already removed in bdrv_reopen_queue_child() */ | ||
68 | + QLIST_FOREACH(child, &bs->children, next) { | ||
69 | + qdict_del(bs->explicit_options, child->name); | ||
70 | + qdict_del(bs->options, child->name); | ||
71 | + } | ||
72 | + | ||
73 | bdrv_refresh_limits(bs, NULL); | ||
74 | |||
75 | bdrv_set_perm(reopen_state->bs, reopen_state->perm, | ||
76 | -- | ||
77 | 2.13.6 | ||
78 | |||
79 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Alberto Garcia <berto@igalia.com> | ||
2 | 1 | ||
3 | In the previous patch we removed child references from bs->options, so | ||
4 | there's no need to look for them here anymore. | ||
5 | |||
6 | Signed-off-by: Alberto Garcia <berto@igalia.com> | ||
7 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
8 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
9 | --- | ||
10 | block.c | 13 +------------ | ||
11 | 1 file changed, 1 insertion(+), 12 deletions(-) | ||
12 | |||
13 | diff --git a/block.c b/block.c | ||
14 | index XXXXXXX..XXXXXXX 100644 | ||
15 | --- a/block.c | ||
16 | +++ b/block.c | ||
17 | @@ -XXX,XX +XXX,XX @@ static bool append_open_options(QDict *d, BlockDriverState *bs) | ||
18 | { | ||
19 | const QDictEntry *entry; | ||
20 | QemuOptDesc *desc; | ||
21 | - BdrvChild *child; | ||
22 | bool found_any = false; | ||
23 | |||
24 | for (entry = qdict_first(bs->options); entry; | ||
25 | entry = qdict_next(bs->options, entry)) | ||
26 | { | ||
27 | - /* Exclude node-name references to children */ | ||
28 | - QLIST_FOREACH(child, &bs->children, next) { | ||
29 | - if (!strcmp(entry->key, child->name)) { | ||
30 | - break; | ||
31 | - } | ||
32 | - } | ||
33 | - if (child) { | ||
34 | - continue; | ||
35 | - } | ||
36 | - | ||
37 | - /* And exclude all non-driver-specific options */ | ||
38 | + /* Exclude all non-driver-specific options */ | ||
39 | for (desc = bdrv_runtime_opts.desc; desc->name; desc++) { | ||
40 | if (!strcmp(qdict_entry_key(entry), desc->name)) { | ||
41 | break; | ||
42 | -- | ||
43 | 2.13.6 | ||
44 | |||
45 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Alberto Garcia <berto@igalia.com> | ||
2 | 1 | ||
3 | In the previous patches we removed all child references from | ||
4 | bs->{options,explicit_options} because keeping them is useless and | ||
5 | wrong. | ||
6 | |||
7 | Because of this, any attempt to reopen a BlockDriverState using a | ||
8 | child reference as one of its options would result in a failure, | ||
9 | because bdrv_reopen_prepare() would detect that there's a new option | ||
10 | (the child reference) that wasn't present in bs->options. | ||
11 | |||
12 | But passing child references on reopen can be useful. It's a way to | ||
13 | specify a BDS's child without having to pass recursively all of the | ||
14 | child's options, and if the reference points to a different BDS then | ||
15 | this can allow us to replace the child. | ||
16 | |||
17 | However, replacing the child is something that needs to be implemented | ||
18 | case by case and only when it makes sense. For now, this patch allows | ||
19 | passing a child reference as long as it points to the current child of | ||
20 | the BlockDriverState. | ||
21 | |||
22 | It's also important to remember that, as a consequence of the | ||
23 | previous patches, this child reference will be removed from | ||
24 | bs->{options,explicit_options} after the reopening has been completed. | ||
25 | |||
26 | Signed-off-by: Alberto Garcia <berto@igalia.com> | ||
27 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
28 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
29 | --- | ||
30 | block.c | 18 ++++++++++++++++++ | ||
31 | 1 file changed, 18 insertions(+) | ||
32 | |||
33 | diff --git a/block.c b/block.c | ||
34 | index XXXXXXX..XXXXXXX 100644 | ||
35 | --- a/block.c | ||
36 | +++ b/block.c | ||
37 | @@ -XXX,XX +XXX,XX @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue, | ||
38 | QObject *new = entry->value; | ||
39 | QObject *old = qdict_get(reopen_state->bs->options, entry->key); | ||
40 | |||
41 | + /* Allow child references (child_name=node_name) as long as they | ||
42 | + * point to the current child (i.e. everything stays the same). */ | ||
43 | + if (qobject_type(new) == QTYPE_QSTRING) { | ||
44 | + BdrvChild *child; | ||
45 | + QLIST_FOREACH(child, &reopen_state->bs->children, next) { | ||
46 | + if (!strcmp(child->name, entry->key)) { | ||
47 | + break; | ||
48 | + } | ||
49 | + } | ||
50 | + | ||
51 | + if (child) { | ||
52 | + const char *str = qobject_get_try_str(new); | ||
53 | + if (!strcmp(child->bs->node_name, str)) { | ||
54 | + continue; /* Found child with this name, skip option */ | ||
55 | + } | ||
56 | + } | ||
57 | + } | ||
58 | + | ||
59 | /* | ||
60 | * TODO: When using -drive to specify blockdev options, all values | ||
61 | * will be strings; however, when using -blockdev, blockdev-add or | ||
62 | -- | ||
63 | 2.13.6 | ||
64 | |||
65 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Alberto Garcia <berto@igalia.com> | ||
2 | 1 | ||
3 | The bdrv_reopen_prepare() function checks all options passed to each | ||
4 | BlockDriverState (in the reopen_state->options QDict) and makes all | ||
5 | necessary preparations to apply the option changes requested by the | ||
6 | user. | ||
7 | |||
8 | Options are removed from the QDict as they are processed, so at the | ||
9 | end of bdrv_reopen_prepare() only the options that can't be changed | ||
10 | are left. Then a loop goes over all remaining options and verifies | ||
11 | that the old and new values are identical, returning an error if | ||
12 | they're not. | ||
13 | |||
14 | The problem is that at the moment there are options that are removed | ||
15 | from the QDict although they can't be changed. The consequence of this | ||
16 | is any modification to any of those options is silently ignored: | ||
17 | |||
18 | (qemu) qemu-io virtio0 "reopen -o discard=on" | ||
19 | |||
20 | This happens when all options from bdrv_runtime_opts are removed | ||
21 | from the QDict but then only a few of them are processed. Since | ||
22 | it's especially important that "node-name" and "driver" are not | ||
23 | changed, the code puts them back into the QDict so they are checked | ||
24 | at the end of the function. Instead of putting only those two options | ||
25 | back into the QDict, this patch puts all unprocessed options using | ||
26 | qemu_opts_to_qdict(). | ||
27 | |||
28 | update_flags_from_options() also needs to be modified to prevent | ||
29 | BDRV_OPT_CACHE_NO_FLUSH, BDRV_OPT_CACHE_DIRECT and BDRV_OPT_READ_ONLY | ||
30 | from going back to the QDict. | ||
31 | |||
32 | Signed-off-by: Alberto Garcia <berto@igalia.com> | ||
33 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
34 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
35 | --- | ||
36 | block.c | 22 +++++++--------------- | ||
37 | 1 file changed, 7 insertions(+), 15 deletions(-) | ||
38 | |||
39 | diff --git a/block.c b/block.c | ||
40 | index XXXXXXX..XXXXXXX 100644 | ||
41 | --- a/block.c | ||
42 | +++ b/block.c | ||
43 | @@ -XXX,XX +XXX,XX @@ static void update_flags_from_options(int *flags, QemuOpts *opts) | ||
44 | *flags &= ~BDRV_O_CACHE_MASK; | ||
45 | |||
46 | assert(qemu_opt_find(opts, BDRV_OPT_CACHE_NO_FLUSH)); | ||
47 | - if (qemu_opt_get_bool(opts, BDRV_OPT_CACHE_NO_FLUSH, false)) { | ||
48 | + if (qemu_opt_get_bool_del(opts, BDRV_OPT_CACHE_NO_FLUSH, false)) { | ||
49 | *flags |= BDRV_O_NO_FLUSH; | ||
50 | } | ||
51 | |||
52 | assert(qemu_opt_find(opts, BDRV_OPT_CACHE_DIRECT)); | ||
53 | - if (qemu_opt_get_bool(opts, BDRV_OPT_CACHE_DIRECT, false)) { | ||
54 | + if (qemu_opt_get_bool_del(opts, BDRV_OPT_CACHE_DIRECT, false)) { | ||
55 | *flags |= BDRV_O_NOCACHE; | ||
56 | } | ||
57 | |||
58 | *flags &= ~BDRV_O_RDWR; | ||
59 | |||
60 | assert(qemu_opt_find(opts, BDRV_OPT_READ_ONLY)); | ||
61 | - if (!qemu_opt_get_bool(opts, BDRV_OPT_READ_ONLY, false)) { | ||
62 | + if (!qemu_opt_get_bool_del(opts, BDRV_OPT_READ_ONLY, false)) { | ||
63 | *flags |= BDRV_O_RDWR; | ||
64 | } | ||
65 | |||
66 | @@ -XXX,XX +XXX,XX @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue, | ||
67 | BlockDriver *drv; | ||
68 | QemuOpts *opts; | ||
69 | QDict *orig_reopen_opts; | ||
70 | - const char *value; | ||
71 | bool read_only; | ||
72 | |||
73 | assert(reopen_state != NULL); | ||
74 | @@ -XXX,XX +XXX,XX @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue, | ||
75 | |||
76 | update_flags_from_options(&reopen_state->flags, opts); | ||
77 | |||
78 | - /* node-name and driver must be unchanged. Put them back into the QDict, so | ||
79 | - * that they are checked at the end of this function. */ | ||
80 | - value = qemu_opt_get(opts, "node-name"); | ||
81 | - if (value) { | ||
82 | - qdict_put_str(reopen_state->options, "node-name", value); | ||
83 | - } | ||
84 | - | ||
85 | - value = qemu_opt_get(opts, "driver"); | ||
86 | - if (value) { | ||
87 | - qdict_put_str(reopen_state->options, "driver", value); | ||
88 | - } | ||
89 | + /* All other options (including node-name and driver) must be unchanged. | ||
90 | + * Put them back into the QDict, so that they are checked at the end | ||
91 | + * of this function. */ | ||
92 | + qemu_opts_to_qdict(opts, reopen_state->options); | ||
93 | |||
94 | /* If we are to stay read-only, do not allow permission change | ||
95 | * to r/w. Attempting to set to r/w may fail if either BDRV_O_ALLOW_RDWR is | ||
96 | -- | ||
97 | 2.13.6 | ||
98 | |||
99 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Alberto Garcia <berto@igalia.com> | ||
2 | 1 | ||
3 | The file-posix code is used for the "file", "host_device" and | ||
4 | "host_cdrom" drivers, and it allows reopening images. However the only | ||
5 | option that is actually processed is "x-check-cache-dropped", and | ||
6 | changes in all other options (e.g. "filename") are silently ignored: | ||
7 | |||
8 | (qemu) qemu-io virtio0 "reopen -o file.filename=no-such-file" | ||
9 | |||
10 | While we could allow changing some of the other options, let's keep | ||
11 | things as they are for now but return an error if the user tries to | ||
12 | change any of them. | ||
13 | |||
14 | Signed-off-by: Alberto Garcia <berto@igalia.com> | ||
15 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
16 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
17 | --- | ||
18 | block/file-posix.c | 9 +++++++-- | ||
19 | 1 file changed, 7 insertions(+), 2 deletions(-) | ||
20 | |||
21 | diff --git a/block/file-posix.c b/block/file-posix.c | ||
22 | index XXXXXXX..XXXXXXX 100644 | ||
23 | --- a/block/file-posix.c | ||
24 | +++ b/block/file-posix.c | ||
25 | @@ -XXX,XX +XXX,XX @@ static int raw_reopen_prepare(BDRVReopenState *state, | ||
26 | goto out; | ||
27 | } | ||
28 | |||
29 | - rs->check_cache_dropped = qemu_opt_get_bool(opts, "x-check-cache-dropped", | ||
30 | - false); | ||
31 | + rs->check_cache_dropped = | ||
32 | + qemu_opt_get_bool_del(opts, "x-check-cache-dropped", false); | ||
33 | + | ||
34 | + /* This driver's reopen function doesn't currently allow changing | ||
35 | + * other options, so let's put them back in the original QDict and | ||
36 | + * bdrv_reopen_prepare() will detect changes and complain. */ | ||
37 | + qemu_opts_to_qdict(opts, state->options); | ||
38 | |||
39 | if (s->type == FTYPE_CD) { | ||
40 | rs->open_flags |= O_NONBLOCK; | ||
41 | -- | ||
42 | 2.13.6 | ||
43 | |||
44 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Alberto Garcia <berto@igalia.com> | ||
2 | 1 | ||
3 | 'discard' is one of the basic BlockdevOptions available for all | ||
4 | drivers, but it's not handled by bdrv_reopen_prepare() so any attempt | ||
5 | to change it results in an error: | ||
6 | |||
7 | (qemu) qemu-io virtio0 "reopen -o discard=on" | ||
8 | Cannot change the option 'discard' | ||
9 | |||
10 | Since there's no reason why we shouldn't allow changing it and the | ||
11 | implementation is simple let's just do it. | ||
12 | |||
13 | Signed-off-by: Alberto Garcia <berto@igalia.com> | ||
14 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
15 | --- | ||
16 | block.c | 11 +++++++++++ | ||
17 | 1 file changed, 11 insertions(+) | ||
18 | |||
19 | diff --git a/block.c b/block.c | ||
20 | index XXXXXXX..XXXXXXX 100644 | ||
21 | --- a/block.c | ||
22 | +++ b/block.c | ||
23 | @@ -XXX,XX +XXX,XX @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue, | ||
24 | BlockDriver *drv; | ||
25 | QemuOpts *opts; | ||
26 | QDict *orig_reopen_opts; | ||
27 | + char *discard = NULL; | ||
28 | bool read_only; | ||
29 | |||
30 | assert(reopen_state != NULL); | ||
31 | @@ -XXX,XX +XXX,XX @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue, | ||
32 | |||
33 | update_flags_from_options(&reopen_state->flags, opts); | ||
34 | |||
35 | + discard = qemu_opt_get_del(opts, "discard"); | ||
36 | + if (discard != NULL) { | ||
37 | + if (bdrv_parse_discard_flags(discard, &reopen_state->flags) != 0) { | ||
38 | + error_setg(errp, "Invalid discard option"); | ||
39 | + ret = -EINVAL; | ||
40 | + goto error; | ||
41 | + } | ||
42 | + } | ||
43 | + | ||
44 | /* All other options (including node-name and driver) must be unchanged. | ||
45 | * Put them back into the QDict, so that they are checked at the end | ||
46 | * of this function. */ | ||
47 | @@ -XXX,XX +XXX,XX @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue, | ||
48 | error: | ||
49 | qemu_opts_del(opts); | ||
50 | qobject_unref(orig_reopen_opts); | ||
51 | + g_free(discard); | ||
52 | return ret; | ||
53 | } | ||
54 | |||
55 | -- | ||
56 | 2.13.6 | ||
57 | |||
58 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Alberto Garcia <berto@igalia.com> | ||
2 | 1 | ||
3 | 'detect-zeroes' is one of the basic BlockdevOptions available for all | ||
4 | drivers, but it's not handled by bdrv_reopen_prepare(), so any attempt | ||
5 | to change it results in an error: | ||
6 | |||
7 | (qemu) qemu-io virtio0 "reopen -o detect-zeroes=on" | ||
8 | Cannot change the option 'detect-zeroes' | ||
9 | |||
10 | Since there's no reason why we shouldn't allow changing it and the | ||
11 | implementation is simple let's just do it. | ||
12 | |||
13 | Signed-off-by: Alberto Garcia <berto@igalia.com> | ||
14 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
15 | --- | ||
16 | include/block/block.h | 1 + | ||
17 | block.c | 64 ++++++++++++++++++++++++++++++++------------------- | ||
18 | 2 files changed, 41 insertions(+), 24 deletions(-) | ||
19 | |||
20 | diff --git a/include/block/block.h b/include/block/block.h | ||
21 | index XXXXXXX..XXXXXXX 100644 | ||
22 | --- a/include/block/block.h | ||
23 | +++ b/include/block/block.h | ||
24 | @@ -XXX,XX +XXX,XX @@ typedef QSIMPLEQ_HEAD(BlockReopenQueue, BlockReopenQueueEntry) BlockReopenQueue; | ||
25 | typedef struct BDRVReopenState { | ||
26 | BlockDriverState *bs; | ||
27 | int flags; | ||
28 | + BlockdevDetectZeroesOptions detect_zeroes; | ||
29 | uint64_t perm, shared_perm; | ||
30 | QDict *options; | ||
31 | QDict *explicit_options; | ||
32 | diff --git a/block.c b/block.c | ||
33 | index XXXXXXX..XXXXXXX 100644 | ||
34 | --- a/block.c | ||
35 | +++ b/block.c | ||
36 | @@ -XXX,XX +XXX,XX @@ static void bdrv_join_options(BlockDriverState *bs, QDict *options, | ||
37 | } | ||
38 | } | ||
39 | |||
40 | +static BlockdevDetectZeroesOptions bdrv_parse_detect_zeroes(QemuOpts *opts, | ||
41 | + int open_flags, | ||
42 | + Error **errp) | ||
43 | +{ | ||
44 | + Error *local_err = NULL; | ||
45 | + char *value = qemu_opt_get_del(opts, "detect-zeroes"); | ||
46 | + BlockdevDetectZeroesOptions detect_zeroes = | ||
47 | + qapi_enum_parse(&BlockdevDetectZeroesOptions_lookup, value, | ||
48 | + BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF, &local_err); | ||
49 | + g_free(value); | ||
50 | + if (local_err) { | ||
51 | + error_propagate(errp, local_err); | ||
52 | + return detect_zeroes; | ||
53 | + } | ||
54 | + | ||
55 | + if (detect_zeroes == BLOCKDEV_DETECT_ZEROES_OPTIONS_UNMAP && | ||
56 | + !(open_flags & BDRV_O_UNMAP)) | ||
57 | + { | ||
58 | + error_setg(errp, "setting detect-zeroes to unmap is not allowed " | ||
59 | + "without setting discard operation to unmap"); | ||
60 | + } | ||
61 | + | ||
62 | + return detect_zeroes; | ||
63 | +} | ||
64 | + | ||
65 | /** | ||
66 | * Set open flags for a given discard mode | ||
67 | * | ||
68 | @@ -XXX,XX +XXX,XX @@ static int bdrv_open_common(BlockDriverState *bs, BlockBackend *file, | ||
69 | const char *driver_name = NULL; | ||
70 | const char *node_name = NULL; | ||
71 | const char *discard; | ||
72 | - const char *detect_zeroes; | ||
73 | QemuOpts *opts; | ||
74 | BlockDriver *drv; | ||
75 | Error *local_err = NULL; | ||
76 | @@ -XXX,XX +XXX,XX @@ static int bdrv_open_common(BlockDriverState *bs, BlockBackend *file, | ||
77 | } | ||
78 | } | ||
79 | |||
80 | - detect_zeroes = qemu_opt_get(opts, "detect-zeroes"); | ||
81 | - if (detect_zeroes) { | ||
82 | - BlockdevDetectZeroesOptions value = | ||
83 | - qapi_enum_parse(&BlockdevDetectZeroesOptions_lookup, | ||
84 | - detect_zeroes, | ||
85 | - BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF, | ||
86 | - &local_err); | ||
87 | - if (local_err) { | ||
88 | - error_propagate(errp, local_err); | ||
89 | - ret = -EINVAL; | ||
90 | - goto fail_opts; | ||
91 | - } | ||
92 | - | ||
93 | - if (value == BLOCKDEV_DETECT_ZEROES_OPTIONS_UNMAP && | ||
94 | - !(bs->open_flags & BDRV_O_UNMAP)) | ||
95 | - { | ||
96 | - error_setg(errp, "setting detect-zeroes to unmap is not allowed " | ||
97 | - "without setting discard operation to unmap"); | ||
98 | - ret = -EINVAL; | ||
99 | - goto fail_opts; | ||
100 | - } | ||
101 | - | ||
102 | - bs->detect_zeroes = value; | ||
103 | + bs->detect_zeroes = | ||
104 | + bdrv_parse_detect_zeroes(opts, bs->open_flags, &local_err); | ||
105 | + if (local_err) { | ||
106 | + error_propagate(errp, local_err); | ||
107 | + ret = -EINVAL; | ||
108 | + goto fail_opts; | ||
109 | } | ||
110 | |||
111 | if (filename != NULL) { | ||
112 | @@ -XXX,XX +XXX,XX @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue, | ||
113 | } | ||
114 | } | ||
115 | |||
116 | + reopen_state->detect_zeroes = | ||
117 | + bdrv_parse_detect_zeroes(opts, reopen_state->flags, &local_err); | ||
118 | + if (local_err) { | ||
119 | + error_propagate(errp, local_err); | ||
120 | + ret = -EINVAL; | ||
121 | + goto error; | ||
122 | + } | ||
123 | + | ||
124 | /* All other options (including node-name and driver) must be unchanged. | ||
125 | * Put them back into the QDict, so that they are checked at the end | ||
126 | * of this function. */ | ||
127 | @@ -XXX,XX +XXX,XX @@ void bdrv_reopen_commit(BDRVReopenState *reopen_state) | ||
128 | bs->options = reopen_state->options; | ||
129 | bs->open_flags = reopen_state->flags; | ||
130 | bs->read_only = !(reopen_state->flags & BDRV_O_RDWR); | ||
131 | + bs->detect_zeroes = reopen_state->detect_zeroes; | ||
132 | |||
133 | /* Remove child references from bs->options and bs->explicit_options. | ||
134 | * Child options were already removed in bdrv_reopen_queue_child() */ | ||
135 | -- | ||
136 | 2.13.6 | ||
137 | |||
138 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Leonid Bloch <lbloch@janustech.com> | ||
2 | 1 | ||
3 | Signed-off-by: Leonid Bloch <lbloch@janustech.com> | ||
4 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
5 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> | ||
6 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
7 | --- | ||
8 | docs/qcow2-cache.txt | 21 ++++++++++++++------- | ||
9 | qemu-options.hx | 9 ++++++--- | ||
10 | 2 files changed, 20 insertions(+), 10 deletions(-) | ||
11 | |||
12 | diff --git a/docs/qcow2-cache.txt b/docs/qcow2-cache.txt | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/docs/qcow2-cache.txt | ||
15 | +++ b/docs/qcow2-cache.txt | ||
16 | @@ -XXX,XX +XXX,XX @@ Choosing the right cache sizes | ||
17 | In order to choose the cache sizes we need to know how they relate to | ||
18 | the amount of allocated space. | ||
19 | |||
20 | -The amount of virtual disk that can be mapped by the L2 and refcount | ||
21 | +The part of the virtual disk that can be mapped by the L2 and refcount | ||
22 | caches (in bytes) is: | ||
23 | |||
24 | disk_size = l2_cache_size * cluster_size / 8 | ||
25 | disk_size = refcount_cache_size * cluster_size * 8 / refcount_bits | ||
26 | |||
27 | With the default values for cluster_size (64KB) and refcount_bits | ||
28 | -(16), that is | ||
29 | +(16), this becomes: | ||
30 | |||
31 | disk_size = l2_cache_size * 8192 | ||
32 | disk_size = refcount_cache_size * 32768 | ||
33 | @@ -XXX,XX +XXX,XX @@ need: | ||
34 | l2_cache_size = disk_size_GB * 131072 | ||
35 | refcount_cache_size = disk_size_GB * 32768 | ||
36 | |||
37 | -QEMU has a default L2 cache of 1MB (1048576 bytes) and a refcount | ||
38 | -cache of 256KB (262144 bytes), so using the formulas we've just seen | ||
39 | -we have | ||
40 | +For example, 1MB of L2 cache is needed to cover every 8 GB of the virtual | ||
41 | +image size (given that the default cluster size is used): | ||
42 | |||
43 | - 1048576 / 131072 = 8 GB of virtual disk covered by that cache | ||
44 | - 262144 / 32768 = 8 GB | ||
45 | + 8 GB / 8192 = 1 MB | ||
46 | + | ||
47 | +The refcount cache is 4 times the cluster size by default. With the default | ||
48 | +cluster size of 64 KB, it is 256 KB (262144 bytes). This is sufficient for | ||
49 | +8 GB of image size: | ||
50 | + | ||
51 | + 262144 * 32768 = 8 GB | ||
52 | |||
53 | |||
54 | How to configure the cache sizes | ||
55 | @@ -XXX,XX +XXX,XX @@ There are a few things that need to be taken into account: | ||
56 | memory as possible to the L2 cache before increasing the refcount | ||
57 | cache size. | ||
58 | |||
59 | + - At most two of "l2-cache-size", "refcount-cache-size", and "cache-size" | ||
60 | + can be set simultaneously. | ||
61 | + | ||
62 | Unlike L2 tables, refcount blocks are not used during normal I/O but | ||
63 | only during allocations and internal snapshots. In most cases they are | ||
64 | accessed sequentially (even during random guest I/O) so increasing the | ||
65 | diff --git a/qemu-options.hx b/qemu-options.hx | ||
66 | index XXXXXXX..XXXXXXX 100644 | ||
67 | --- a/qemu-options.hx | ||
68 | +++ b/qemu-options.hx | ||
69 | @@ -XXX,XX +XXX,XX @@ image file) | ||
70 | |||
71 | @item cache-size | ||
72 | The maximum total size of the L2 table and refcount block caches in bytes | ||
73 | -(default: 1048576 bytes or 8 clusters, whichever is larger) | ||
74 | +(default: the sum of l2-cache-size and refcount-cache-size) | ||
75 | |||
76 | @item l2-cache-size | ||
77 | The maximum size of the L2 table cache in bytes | ||
78 | -(default: 4/5 of the total cache size) | ||
79 | +(default: if cache-size is not defined - 1048576 bytes or 8 clusters, whichever | ||
80 | +is larger; otherwise, as large as possible or needed within the cache-size, | ||
81 | +while permitting the requested or the minimal refcount cache size) | ||
82 | |||
83 | @item refcount-cache-size | ||
84 | The maximum size of the refcount block cache in bytes | ||
85 | -(default: 1/5 of the total cache size) | ||
86 | +(default: 4 times the cluster size; or if cache-size is specified, the part of | ||
87 | +it which is not used for the L2 cache) | ||
88 | |||
89 | @item cache-clean-interval | ||
90 | Clean unused entries in the L2 and refcount caches. The interval is in seconds. | ||
91 | -- | ||
92 | 2.13.6 | ||
93 | |||
94 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Leonid Bloch <lbloch@janustech.com> | ||
2 | 1 | ||
3 | Adding a lookup table for the powers of two, with the appropriate size | ||
4 | prefixes. This is needed when a size has to be stringified, in which | ||
5 | case something like '(1 * KiB)' would become a literal '(1 * (1L << 10))' | ||
6 | string. Powers of two are used very often for sizes, so such a table | ||
7 | will also make it easier and more intuitive to write them. | ||
8 | |||
9 | This table is generatred using the following AWK script: | ||
10 | |||
11 | BEGIN { | ||
12 | suffix="KMGTPE"; | ||
13 | for(i=10; i<64; i++) { | ||
14 | val=2**i; | ||
15 | s=substr(suffix, int(i/10), 1); | ||
16 | n=2**(i%10); | ||
17 | pad=21-int(log(n)/log(10)); | ||
18 | printf("#define S_%d%siB %*d\n", n, s, pad, val); | ||
19 | } | ||
20 | } | ||
21 | |||
22 | Signed-off-by: Leonid Bloch <lbloch@janustech.com> | ||
23 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
24 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> | ||
25 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
26 | --- | ||
27 | include/qemu/units.h | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||
28 | 1 file changed, 55 insertions(+) | ||
29 | |||
30 | diff --git a/include/qemu/units.h b/include/qemu/units.h | ||
31 | index XXXXXXX..XXXXXXX 100644 | ||
32 | --- a/include/qemu/units.h | ||
33 | +++ b/include/qemu/units.h | ||
34 | @@ -XXX,XX +XXX,XX @@ | ||
35 | #define PiB (INT64_C(1) << 50) | ||
36 | #define EiB (INT64_C(1) << 60) | ||
37 | |||
38 | +#define S_1KiB 1024 | ||
39 | +#define S_2KiB 2048 | ||
40 | +#define S_4KiB 4096 | ||
41 | +#define S_8KiB 8192 | ||
42 | +#define S_16KiB 16384 | ||
43 | +#define S_32KiB 32768 | ||
44 | +#define S_64KiB 65536 | ||
45 | +#define S_128KiB 131072 | ||
46 | +#define S_256KiB 262144 | ||
47 | +#define S_512KiB 524288 | ||
48 | +#define S_1MiB 1048576 | ||
49 | +#define S_2MiB 2097152 | ||
50 | +#define S_4MiB 4194304 | ||
51 | +#define S_8MiB 8388608 | ||
52 | +#define S_16MiB 16777216 | ||
53 | +#define S_32MiB 33554432 | ||
54 | +#define S_64MiB 67108864 | ||
55 | +#define S_128MiB 134217728 | ||
56 | +#define S_256MiB 268435456 | ||
57 | +#define S_512MiB 536870912 | ||
58 | +#define S_1GiB 1073741824 | ||
59 | +#define S_2GiB 2147483648 | ||
60 | +#define S_4GiB 4294967296 | ||
61 | +#define S_8GiB 8589934592 | ||
62 | +#define S_16GiB 17179869184 | ||
63 | +#define S_32GiB 34359738368 | ||
64 | +#define S_64GiB 68719476736 | ||
65 | +#define S_128GiB 137438953472 | ||
66 | +#define S_256GiB 274877906944 | ||
67 | +#define S_512GiB 549755813888 | ||
68 | +#define S_1TiB 1099511627776 | ||
69 | +#define S_2TiB 2199023255552 | ||
70 | +#define S_4TiB 4398046511104 | ||
71 | +#define S_8TiB 8796093022208 | ||
72 | +#define S_16TiB 17592186044416 | ||
73 | +#define S_32TiB 35184372088832 | ||
74 | +#define S_64TiB 70368744177664 | ||
75 | +#define S_128TiB 140737488355328 | ||
76 | +#define S_256TiB 281474976710656 | ||
77 | +#define S_512TiB 562949953421312 | ||
78 | +#define S_1PiB 1125899906842624 | ||
79 | +#define S_2PiB 2251799813685248 | ||
80 | +#define S_4PiB 4503599627370496 | ||
81 | +#define S_8PiB 9007199254740992 | ||
82 | +#define S_16PiB 18014398509481984 | ||
83 | +#define S_32PiB 36028797018963968 | ||
84 | +#define S_64PiB 72057594037927936 | ||
85 | +#define S_128PiB 144115188075855872 | ||
86 | +#define S_256PiB 288230376151711744 | ||
87 | +#define S_512PiB 576460752303423488 | ||
88 | +#define S_1EiB 1152921504606846976 | ||
89 | +#define S_2EiB 2305843009213693952 | ||
90 | +#define S_4EiB 4611686018427387904 | ||
91 | +#define S_8EiB 9223372036854775808 | ||
92 | + | ||
93 | #endif | ||
94 | -- | ||
95 | 2.13.6 | ||
96 | |||
97 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Leonid Bloch <lbloch@janustech.com> | ||
2 | 1 | ||
3 | Signed-off-by: Leonid Bloch <lbloch@janustech.com> | ||
4 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
5 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> | ||
6 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
7 | --- | ||
8 | block/qcow2.h | 9 +++++---- | ||
9 | block/qcow2.c | 2 +- | ||
10 | 2 files changed, 6 insertions(+), 5 deletions(-) | ||
11 | |||
12 | diff --git a/block/qcow2.h b/block/qcow2.h | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/block/qcow2.h | ||
15 | +++ b/block/qcow2.h | ||
16 | @@ -XXX,XX +XXX,XX @@ | ||
17 | |||
18 | #include "crypto/block.h" | ||
19 | #include "qemu/coroutine.h" | ||
20 | +#include "qemu/units.h" | ||
21 | |||
22 | //#define DEBUG_ALLOC | ||
23 | //#define DEBUG_ALLOC2 | ||
24 | @@ -XXX,XX +XXX,XX @@ | ||
25 | |||
26 | /* 8 MB refcount table is enough for 2 PB images at 64k cluster size | ||
27 | * (128 GB for 512 byte clusters, 2 EB for 2 MB clusters) */ | ||
28 | -#define QCOW_MAX_REFTABLE_SIZE 0x800000 | ||
29 | +#define QCOW_MAX_REFTABLE_SIZE S_8MiB | ||
30 | |||
31 | /* 32 MB L1 table is enough for 2 PB images at 64k cluster size | ||
32 | * (128 GB for 512 byte clusters, 2 EB for 2 MB clusters) */ | ||
33 | -#define QCOW_MAX_L1_SIZE 0x2000000 | ||
34 | +#define QCOW_MAX_L1_SIZE S_32MiB | ||
35 | |||
36 | /* Allow for an average of 1k per snapshot table entry, should be plenty of | ||
37 | * space for snapshot names and IDs */ | ||
38 | @@ -XXX,XX +XXX,XX @@ | ||
39 | |||
40 | /* Whichever is more */ | ||
41 | #define DEFAULT_L2_CACHE_CLUSTERS 8 /* clusters */ | ||
42 | -#define DEFAULT_L2_CACHE_BYTE_SIZE 1048576 /* bytes */ | ||
43 | +#define DEFAULT_L2_CACHE_SIZE S_1MiB | ||
44 | |||
45 | -#define DEFAULT_CLUSTER_SIZE 65536 | ||
46 | +#define DEFAULT_CLUSTER_SIZE S_64KiB | ||
47 | |||
48 | |||
49 | #define QCOW2_OPT_LAZY_REFCOUNTS "lazy-refcounts" | ||
50 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
51 | index XXXXXXX..XXXXXXX 100644 | ||
52 | --- a/block/qcow2.c | ||
53 | +++ b/block/qcow2.c | ||
54 | @@ -XXX,XX +XXX,XX @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts, | ||
55 | } | ||
56 | } else { | ||
57 | if (!l2_cache_size_set) { | ||
58 | - *l2_cache_size = MAX(DEFAULT_L2_CACHE_BYTE_SIZE, | ||
59 | + *l2_cache_size = MAX(DEFAULT_L2_CACHE_SIZE, | ||
60 | (uint64_t)DEFAULT_L2_CACHE_CLUSTERS | ||
61 | * s->cluster_size); | ||
62 | } | ||
63 | -- | ||
64 | 2.13.6 | ||
65 | |||
66 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Leonid Bloch <lbloch@janustech.com> | ||
2 | 1 | ||
3 | The refcount cache size does not need to be set to its minimum value in | ||
4 | read_cache_sizes(), as it is set to at least its minimum value in | ||
5 | qcow2_update_options_prepare(). | ||
6 | |||
7 | Signed-off-by: Leonid Bloch <lbloch@janustech.com> | ||
8 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
9 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> | ||
10 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
11 | --- | ||
12 | block/qcow2.c | 5 ++--- | ||
13 | 1 file changed, 2 insertions(+), 3 deletions(-) | ||
14 | |||
15 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/block/qcow2.c | ||
18 | +++ b/block/qcow2.c | ||
19 | @@ -XXX,XX +XXX,XX @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts, | ||
20 | (uint64_t)DEFAULT_L2_CACHE_CLUSTERS | ||
21 | * s->cluster_size); | ||
22 | } | ||
23 | - if (!refcount_cache_size_set) { | ||
24 | - *refcount_cache_size = min_refcount_cache; | ||
25 | - } | ||
26 | } | ||
27 | + /* l2_cache_size and refcount_cache_size are ensured to have at least | ||
28 | + * their minimum values in qcow2_update_options_prepare() */ | ||
29 | |||
30 | if (*l2_cache_entry_size < (1 << MIN_CLUSTER_BITS) || | ||
31 | *l2_cache_entry_size > s->cluster_size || | ||
32 | -- | ||
33 | 2.13.6 | ||
34 | |||
35 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Leonid Bloch <lbloch@janustech.com> | ||
2 | 1 | ||
3 | Sufficient L2 cache can noticeably improve the performance when using | ||
4 | large images with frequent I/O. | ||
5 | |||
6 | Previously, unless 'cache-size' was specified and was large enough, the | ||
7 | L2 cache was set to a certain size without taking the virtual image size | ||
8 | into account. | ||
9 | |||
10 | Now, the L2 cache assignment is aware of the virtual size of the image, | ||
11 | and will cover the entire image, unless the cache size needed for that is | ||
12 | larger than a certain maximum. This maximum is set to 1 MB by default | ||
13 | (enough to cover an 8 GB image with the default cluster size) but can | ||
14 | be increased or decreased using the 'l2-cache-size' option. This option | ||
15 | was previously documented as the *maximum* L2 cache size, and this patch | ||
16 | makes it behave as such, instead of as a constant size. Also, the | ||
17 | existing option 'cache-size' can limit the sum of both L2 and refcount | ||
18 | caches, as previously. | ||
19 | |||
20 | Signed-off-by: Leonid Bloch <lbloch@janustech.com> | ||
21 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
22 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> | ||
23 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
24 | --- | ||
25 | docs/qcow2-cache.txt | 15 ++++++++++----- | ||
26 | block/qcow2.h | 4 +--- | ||
27 | block/qcow2.c | 21 +++++++++------------ | ||
28 | qemu-options.hx | 6 +++--- | ||
29 | tests/qemu-iotests/137 | 8 +++++++- | ||
30 | tests/qemu-iotests/137.out | 4 +++- | ||
31 | 6 files changed, 33 insertions(+), 25 deletions(-) | ||
32 | |||
33 | diff --git a/docs/qcow2-cache.txt b/docs/qcow2-cache.txt | ||
34 | index XXXXXXX..XXXXXXX 100644 | ||
35 | --- a/docs/qcow2-cache.txt | ||
36 | +++ b/docs/qcow2-cache.txt | ||
37 | @@ -XXX,XX +XXX,XX @@ There are a few things that need to be taken into account: | ||
38 | - Both caches must have a size that is a multiple of the cluster size | ||
39 | (or the cache entry size: see "Using smaller cache sizes" below). | ||
40 | |||
41 | - - The default L2 cache size is 8 clusters or 1MB (whichever is more), | ||
42 | - and the minimum is 2 clusters (or 2 cache entries, see below). | ||
43 | + - The maximum L2 cache size is 1 MB by default (enough for full coverage | ||
44 | + of 8 GB images, with the default cluster size). This value can be | ||
45 | + modified using the "l2-cache-size" option. QEMU will not use more memory | ||
46 | + than needed to hold all of the image's L2 tables, regardless of this max. | ||
47 | + value. The minimal L2 cache size is 2 clusters (or 2 cache entries, see | ||
48 | + below). | ||
49 | |||
50 | - The default (and minimum) refcount cache size is 4 clusters. | ||
51 | |||
52 | @@ -XXX,XX +XXX,XX @@ Some things to take into account: | ||
53 | always uses the cluster size as the entry size. | ||
54 | |||
55 | - If the L2 cache is big enough to hold all of the image's L2 tables | ||
56 | - (as explained in the "Choosing the right cache sizes" section | ||
57 | - earlier in this document) then none of this is necessary and you | ||
58 | - can omit the "l2-cache-entry-size" parameter altogether. | ||
59 | + (as explained in the "Choosing the right cache sizes" and "How to | ||
60 | + configure the cache sizes" sections in this document) then none of | ||
61 | + this is necessary and you can omit the "l2-cache-entry-size" | ||
62 | + parameter altogether. | ||
63 | |||
64 | |||
65 | Reducing the memory usage | ||
66 | diff --git a/block/qcow2.h b/block/qcow2.h | ||
67 | index XXXXXXX..XXXXXXX 100644 | ||
68 | --- a/block/qcow2.h | ||
69 | +++ b/block/qcow2.h | ||
70 | @@ -XXX,XX +XXX,XX @@ | ||
71 | /* Must be at least 4 to cover all cases of refcount table growth */ | ||
72 | #define MIN_REFCOUNT_CACHE_SIZE 4 /* clusters */ | ||
73 | |||
74 | -/* Whichever is more */ | ||
75 | -#define DEFAULT_L2_CACHE_CLUSTERS 8 /* clusters */ | ||
76 | -#define DEFAULT_L2_CACHE_SIZE S_1MiB | ||
77 | +#define DEFAULT_L2_CACHE_MAX_SIZE S_1MiB | ||
78 | |||
79 | #define DEFAULT_CLUSTER_SIZE S_64KiB | ||
80 | |||
81 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
82 | index XXXXXXX..XXXXXXX 100644 | ||
83 | --- a/block/qcow2.c | ||
84 | +++ b/block/qcow2.c | ||
85 | @@ -XXX,XX +XXX,XX @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts, | ||
86 | uint64_t *refcount_cache_size, Error **errp) | ||
87 | { | ||
88 | BDRVQcow2State *s = bs->opaque; | ||
89 | - uint64_t combined_cache_size; | ||
90 | + uint64_t combined_cache_size, l2_cache_max_setting; | ||
91 | bool l2_cache_size_set, refcount_cache_size_set, combined_cache_size_set; | ||
92 | int min_refcount_cache = MIN_REFCOUNT_CACHE_SIZE * s->cluster_size; | ||
93 | + uint64_t virtual_disk_size = bs->total_sectors * BDRV_SECTOR_SIZE; | ||
94 | + uint64_t max_l2_cache = virtual_disk_size / (s->cluster_size / 8); | ||
95 | |||
96 | combined_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_CACHE_SIZE); | ||
97 | l2_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_L2_CACHE_SIZE); | ||
98 | refcount_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_REFCOUNT_CACHE_SIZE); | ||
99 | |||
100 | combined_cache_size = qemu_opt_get_size(opts, QCOW2_OPT_CACHE_SIZE, 0); | ||
101 | - *l2_cache_size = qemu_opt_get_size(opts, QCOW2_OPT_L2_CACHE_SIZE, 0); | ||
102 | + l2_cache_max_setting = qemu_opt_get_size(opts, QCOW2_OPT_L2_CACHE_SIZE, | ||
103 | + DEFAULT_L2_CACHE_MAX_SIZE); | ||
104 | *refcount_cache_size = qemu_opt_get_size(opts, | ||
105 | QCOW2_OPT_REFCOUNT_CACHE_SIZE, 0); | ||
106 | |||
107 | *l2_cache_entry_size = qemu_opt_get_size( | ||
108 | opts, QCOW2_OPT_L2_CACHE_ENTRY_SIZE, s->cluster_size); | ||
109 | |||
110 | + *l2_cache_size = MIN(max_l2_cache, l2_cache_max_setting); | ||
111 | + | ||
112 | if (combined_cache_size_set) { | ||
113 | if (l2_cache_size_set && refcount_cache_size_set) { | ||
114 | error_setg(errp, QCOW2_OPT_CACHE_SIZE ", " QCOW2_OPT_L2_CACHE_SIZE | ||
115 | " and " QCOW2_OPT_REFCOUNT_CACHE_SIZE " may not be set " | ||
116 | "at the same time"); | ||
117 | return; | ||
118 | - } else if (*l2_cache_size > combined_cache_size) { | ||
119 | + } else if (l2_cache_size_set && | ||
120 | + (l2_cache_max_setting > combined_cache_size)) { | ||
121 | error_setg(errp, QCOW2_OPT_L2_CACHE_SIZE " may not exceed " | ||
122 | QCOW2_OPT_CACHE_SIZE); | ||
123 | return; | ||
124 | @@ -XXX,XX +XXX,XX @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts, | ||
125 | } else if (refcount_cache_size_set) { | ||
126 | *l2_cache_size = combined_cache_size - *refcount_cache_size; | ||
127 | } else { | ||
128 | - uint64_t virtual_disk_size = bs->total_sectors * BDRV_SECTOR_SIZE; | ||
129 | - uint64_t max_l2_cache = virtual_disk_size / (s->cluster_size / 8); | ||
130 | - | ||
131 | /* Assign as much memory as possible to the L2 cache, and | ||
132 | * use the remainder for the refcount cache */ | ||
133 | if (combined_cache_size >= max_l2_cache + min_refcount_cache) { | ||
134 | @@ -XXX,XX +XXX,XX @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts, | ||
135 | *l2_cache_size = combined_cache_size - *refcount_cache_size; | ||
136 | } | ||
137 | } | ||
138 | - } else { | ||
139 | - if (!l2_cache_size_set) { | ||
140 | - *l2_cache_size = MAX(DEFAULT_L2_CACHE_SIZE, | ||
141 | - (uint64_t)DEFAULT_L2_CACHE_CLUSTERS | ||
142 | - * s->cluster_size); | ||
143 | - } | ||
144 | } | ||
145 | /* l2_cache_size and refcount_cache_size are ensured to have at least | ||
146 | * their minimum values in qcow2_update_options_prepare() */ | ||
147 | diff --git a/qemu-options.hx b/qemu-options.hx | ||
148 | index XXXXXXX..XXXXXXX 100644 | ||
149 | --- a/qemu-options.hx | ||
150 | +++ b/qemu-options.hx | ||
151 | @@ -XXX,XX +XXX,XX @@ The maximum total size of the L2 table and refcount block caches in bytes | ||
152 | |||
153 | @item l2-cache-size | ||
154 | The maximum size of the L2 table cache in bytes | ||
155 | -(default: if cache-size is not defined - 1048576 bytes or 8 clusters, whichever | ||
156 | -is larger; otherwise, as large as possible or needed within the cache-size, | ||
157 | -while permitting the requested or the minimal refcount cache size) | ||
158 | +(default: if cache-size is not specified - 1M; otherwise, as large as possible | ||
159 | +within the cache-size, while permitting the requested or the minimal refcount | ||
160 | +cache size) | ||
161 | |||
162 | @item refcount-cache-size | ||
163 | The maximum size of the refcount block cache in bytes | ||
164 | diff --git a/tests/qemu-iotests/137 b/tests/qemu-iotests/137 | ||
165 | index XXXXXXX..XXXXXXX 100755 | ||
166 | --- a/tests/qemu-iotests/137 | ||
167 | +++ b/tests/qemu-iotests/137 | ||
168 | @@ -XXX,XX +XXX,XX @@ $QEMU_IO \ | ||
169 | -c "reopen -o cache-size=1M,l2-cache-size=64k,refcount-cache-size=64k" \ | ||
170 | -c "reopen -o cache-size=1M,l2-cache-size=2M" \ | ||
171 | -c "reopen -o cache-size=1M,refcount-cache-size=2M" \ | ||
172 | - -c "reopen -o l2-cache-size=256T" \ | ||
173 | -c "reopen -o l2-cache-entry-size=33k" \ | ||
174 | -c "reopen -o l2-cache-entry-size=128k" \ | ||
175 | -c "reopen -o refcount-cache-size=256T" \ | ||
176 | @@ -XXX,XX +XXX,XX @@ $QEMU_IO \ | ||
177 | -c "reopen -o cache-clean-interval=-1" \ | ||
178 | "$TEST_IMG" | _filter_qemu_io | ||
179 | |||
180 | +IMGOPTS="cluster_size=256k" _make_test_img 32P | ||
181 | +$QEMU_IO \ | ||
182 | + -c "reopen -o l2-cache-entry-size=512,l2-cache-size=1T" \ | ||
183 | + "$TEST_IMG" | _filter_qemu_io | ||
184 | + | ||
185 | +_make_test_img 64M | ||
186 | + | ||
187 | echo | ||
188 | echo === Test transaction semantics === | ||
189 | echo | ||
190 | diff --git a/tests/qemu-iotests/137.out b/tests/qemu-iotests/137.out | ||
191 | index XXXXXXX..XXXXXXX 100644 | ||
192 | --- a/tests/qemu-iotests/137.out | ||
193 | +++ b/tests/qemu-iotests/137.out | ||
194 | @@ -XXX,XX +XXX,XX @@ Parameter 'lazy-refcounts' expects 'on' or 'off' | ||
195 | cache-size, l2-cache-size and refcount-cache-size may not be set at the same time | ||
196 | l2-cache-size may not exceed cache-size | ||
197 | refcount-cache-size may not exceed cache-size | ||
198 | -L2 cache size too big | ||
199 | L2 cache entry size must be a power of two between 512 and the cluster size (65536) | ||
200 | L2 cache entry size must be a power of two between 512 and the cluster size (65536) | ||
201 | Refcount cache size too big | ||
202 | @@ -XXX,XX +XXX,XX @@ Conflicting values for qcow2 options 'overlap-check' ('constant') and 'overlap-c | ||
203 | Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of the following: none, constant, cached, all | ||
204 | Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of the following: none, constant, cached, all | ||
205 | Cache clean interval too big | ||
206 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=36028797018963968 | ||
207 | +L2 cache size too big | ||
208 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 | ||
209 | |||
210 | === Test transaction semantics === | ||
211 | |||
212 | -- | ||
213 | 2.13.6 | ||
214 | |||
215 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Leonid Bloch <lbloch@janustech.com> | ||
2 | 1 | ||
3 | The upper limit on the L2 cache size is increased from 1 MB to 32 MB | ||
4 | on Linux platforms, and to 8 MB on other platforms (this difference is | ||
5 | caused by the ability to set intervals for cache cleaning on Linux | ||
6 | platforms only). | ||
7 | |||
8 | This is done in order to allow default full coverage with the L2 cache | ||
9 | for images of up to 256 GB in size (was 8 GB). Note, that only the | ||
10 | needed amount to cover the full image is allocated. The value which is | ||
11 | changed here is just the upper limit on the L2 cache size, beyond which | ||
12 | it will not grow, even if the size of the image will require it to. | ||
13 | |||
14 | Signed-off-by: Leonid Bloch <lbloch@janustech.com> | ||
15 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
16 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> | ||
17 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
18 | --- | ||
19 | docs/qcow2-cache.txt | 15 +++++++++------ | ||
20 | block/qcow2.h | 6 +++++- | ||
21 | qemu-options.hx | 6 +++--- | ||
22 | 3 files changed, 17 insertions(+), 10 deletions(-) | ||
23 | |||
24 | diff --git a/docs/qcow2-cache.txt b/docs/qcow2-cache.txt | ||
25 | index XXXXXXX..XXXXXXX 100644 | ||
26 | --- a/docs/qcow2-cache.txt | ||
27 | +++ b/docs/qcow2-cache.txt | ||
28 | @@ -XXX,XX +XXX,XX @@ There are a few things that need to be taken into account: | ||
29 | - Both caches must have a size that is a multiple of the cluster size | ||
30 | (or the cache entry size: see "Using smaller cache sizes" below). | ||
31 | |||
32 | - - The maximum L2 cache size is 1 MB by default (enough for full coverage | ||
33 | - of 8 GB images, with the default cluster size). This value can be | ||
34 | - modified using the "l2-cache-size" option. QEMU will not use more memory | ||
35 | - than needed to hold all of the image's L2 tables, regardless of this max. | ||
36 | - value. The minimal L2 cache size is 2 clusters (or 2 cache entries, see | ||
37 | - below). | ||
38 | + - The maximum L2 cache size is 32 MB by default on Linux platforms (enough | ||
39 | + for full coverage of 256 GB images, with the default cluster size). This | ||
40 | + value can be modified using the "l2-cache-size" option. QEMU will not use | ||
41 | + more memory than needed to hold all of the image's L2 tables, regardless | ||
42 | + of this max. value. | ||
43 | + On non-Linux platforms the maximal value is smaller by default (8 MB) and | ||
44 | + this difference stems from the fact that on Linux the cache can be cleared | ||
45 | + periodically if needed, using the "cache-clean-interval" option (see below). | ||
46 | + The minimal L2 cache size is 2 clusters (or 2 cache entries, see below). | ||
47 | |||
48 | - The default (and minimum) refcount cache size is 4 clusters. | ||
49 | |||
50 | diff --git a/block/qcow2.h b/block/qcow2.h | ||
51 | index XXXXXXX..XXXXXXX 100644 | ||
52 | --- a/block/qcow2.h | ||
53 | +++ b/block/qcow2.h | ||
54 | @@ -XXX,XX +XXX,XX @@ | ||
55 | /* Must be at least 4 to cover all cases of refcount table growth */ | ||
56 | #define MIN_REFCOUNT_CACHE_SIZE 4 /* clusters */ | ||
57 | |||
58 | -#define DEFAULT_L2_CACHE_MAX_SIZE S_1MiB | ||
59 | +#ifdef CONFIG_LINUX | ||
60 | +#define DEFAULT_L2_CACHE_MAX_SIZE S_32MiB | ||
61 | +#else | ||
62 | +#define DEFAULT_L2_CACHE_MAX_SIZE S_8MiB | ||
63 | +#endif | ||
64 | |||
65 | #define DEFAULT_CLUSTER_SIZE S_64KiB | ||
66 | |||
67 | diff --git a/qemu-options.hx b/qemu-options.hx | ||
68 | index XXXXXXX..XXXXXXX 100644 | ||
69 | --- a/qemu-options.hx | ||
70 | +++ b/qemu-options.hx | ||
71 | @@ -XXX,XX +XXX,XX @@ The maximum total size of the L2 table and refcount block caches in bytes | ||
72 | |||
73 | @item l2-cache-size | ||
74 | The maximum size of the L2 table cache in bytes | ||
75 | -(default: if cache-size is not specified - 1M; otherwise, as large as possible | ||
76 | -within the cache-size, while permitting the requested or the minimal refcount | ||
77 | -cache size) | ||
78 | +(default: if cache-size is not specified - 32M on Linux platforms, and 8M on | ||
79 | +non-Linux platforms; otherwise, as large as possible within the cache-size, | ||
80 | +while permitting the requested or the minimal refcount cache size) | ||
81 | |||
82 | @item refcount-cache-size | ||
83 | The maximum size of the refcount block cache in bytes | ||
84 | -- | ||
85 | 2.13.6 | ||
86 | |||
87 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Leonid Bloch <lbloch@janustech.com> | ||
2 | 1 | ||
3 | The caches are now recalculated upon image resizing. This is done | ||
4 | because the new default behavior of assigning L2 cache relatively to | ||
5 | the image size, implies that the cache will be adapted accordingly | ||
6 | after an image resize. | ||
7 | |||
8 | Signed-off-by: Leonid Bloch <lbloch@janustech.com> | ||
9 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
10 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
11 | --- | ||
12 | block/qcow2.c | 11 +++++++++++ | ||
13 | 1 file changed, 11 insertions(+) | ||
14 | |||
15 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/block/qcow2.c | ||
18 | +++ b/block/qcow2.c | ||
19 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset, | ||
20 | uint64_t old_length; | ||
21 | int64_t new_l1_size; | ||
22 | int ret; | ||
23 | + QDict *options; | ||
24 | |||
25 | if (prealloc != PREALLOC_MODE_OFF && prealloc != PREALLOC_MODE_METADATA && | ||
26 | prealloc != PREALLOC_MODE_FALLOC && prealloc != PREALLOC_MODE_FULL) | ||
27 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset, | ||
28 | } | ||
29 | } | ||
30 | |||
31 | + bs->total_sectors = offset / BDRV_SECTOR_SIZE; | ||
32 | + | ||
33 | /* write updated header.size */ | ||
34 | offset = cpu_to_be64(offset); | ||
35 | ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, size), | ||
36 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset, | ||
37 | } | ||
38 | |||
39 | s->l1_vm_state_index = new_l1_size; | ||
40 | + | ||
41 | + /* Update cache sizes */ | ||
42 | + options = qdict_clone_shallow(bs->options); | ||
43 | + ret = qcow2_update_options(bs, options, s->flags, errp); | ||
44 | + qobject_unref(options); | ||
45 | + if (ret < 0) { | ||
46 | + goto fail; | ||
47 | + } | ||
48 | ret = 0; | ||
49 | fail: | ||
50 | qemu_co_mutex_unlock(&s->lock); | ||
51 | -- | ||
52 | 2.13.6 | ||
53 | |||
54 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Leonid Bloch <lbloch@janustech.com> | ||
2 | 1 | ||
3 | The default cache-clean-interval is set to 10 minutes, in order to lower | ||
4 | the overhead of the qcow2 caches (before the default was 0, i.e. | ||
5 | disabled). | ||
6 | |||
7 | * For non-Linux platforms the default is kept at 0, because | ||
8 | cache-clean-interval is not supported there yet. | ||
9 | |||
10 | Signed-off-by: Leonid Bloch <lbloch@janustech.com> | ||
11 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
12 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> | ||
13 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
14 | --- | ||
15 | qapi/block-core.json | 3 ++- | ||
16 | docs/qcow2-cache.txt | 4 ++-- | ||
17 | block/qcow2.h | 4 +++- | ||
18 | block/qcow2.c | 2 +- | ||
19 | qemu-options.hx | 2 +- | ||
20 | 5 files changed, 9 insertions(+), 6 deletions(-) | ||
21 | |||
22 | diff --git a/qapi/block-core.json b/qapi/block-core.json | ||
23 | index XXXXXXX..XXXXXXX 100644 | ||
24 | --- a/qapi/block-core.json | ||
25 | +++ b/qapi/block-core.json | ||
26 | @@ -XXX,XX +XXX,XX @@ | ||
27 | # | ||
28 | # @cache-clean-interval: clean unused entries in the L2 and refcount | ||
29 | # caches. The interval is in seconds. The default value | ||
30 | -# is 0 and it disables this feature (since 2.5) | ||
31 | +# is 600, and 0 disables this feature. (since 2.5) | ||
32 | +# | ||
33 | # @encrypt: Image decryption options. Mandatory for | ||
34 | # encrypted images, except when doing a metadata-only | ||
35 | # probe of the image. (since 2.10) | ||
36 | diff --git a/docs/qcow2-cache.txt b/docs/qcow2-cache.txt | ||
37 | index XXXXXXX..XXXXXXX 100644 | ||
38 | --- a/docs/qcow2-cache.txt | ||
39 | +++ b/docs/qcow2-cache.txt | ||
40 | @@ -XXX,XX +XXX,XX @@ This example removes all unused cache entries every 15 minutes: | ||
41 | |||
42 | -drive file=hd.qcow2,cache-clean-interval=900 | ||
43 | |||
44 | -If unset, the default value for this parameter is 0 and it disables | ||
45 | -this feature. | ||
46 | +If unset, the default value for this parameter is 600. Setting it to 0 | ||
47 | +disables this feature. | ||
48 | |||
49 | Note that this functionality currently relies on the MADV_DONTNEED | ||
50 | argument for madvise() to actually free the memory. This is a | ||
51 | diff --git a/block/qcow2.h b/block/qcow2.h | ||
52 | index XXXXXXX..XXXXXXX 100644 | ||
53 | --- a/block/qcow2.h | ||
54 | +++ b/block/qcow2.h | ||
55 | @@ -XXX,XX +XXX,XX @@ | ||
56 | |||
57 | #ifdef CONFIG_LINUX | ||
58 | #define DEFAULT_L2_CACHE_MAX_SIZE S_32MiB | ||
59 | +#define DEFAULT_CACHE_CLEAN_INTERVAL 600 /* seconds */ | ||
60 | #else | ||
61 | #define DEFAULT_L2_CACHE_MAX_SIZE S_8MiB | ||
62 | +/* Cache clean interval is currently available only on Linux, so must be 0 */ | ||
63 | +#define DEFAULT_CACHE_CLEAN_INTERVAL 0 | ||
64 | #endif | ||
65 | |||
66 | #define DEFAULT_CLUSTER_SIZE S_64KiB | ||
67 | |||
68 | - | ||
69 | #define QCOW2_OPT_LAZY_REFCOUNTS "lazy-refcounts" | ||
70 | #define QCOW2_OPT_DISCARD_REQUEST "pass-discard-request" | ||
71 | #define QCOW2_OPT_DISCARD_SNAPSHOT "pass-discard-snapshot" | ||
72 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
73 | index XXXXXXX..XXXXXXX 100644 | ||
74 | --- a/block/qcow2.c | ||
75 | +++ b/block/qcow2.c | ||
76 | @@ -XXX,XX +XXX,XX @@ static int qcow2_update_options_prepare(BlockDriverState *bs, | ||
77 | /* New interval for cache cleanup timer */ | ||
78 | r->cache_clean_interval = | ||
79 | qemu_opt_get_number(opts, QCOW2_OPT_CACHE_CLEAN_INTERVAL, | ||
80 | - s->cache_clean_interval); | ||
81 | + DEFAULT_CACHE_CLEAN_INTERVAL); | ||
82 | #ifndef CONFIG_LINUX | ||
83 | if (r->cache_clean_interval != 0) { | ||
84 | error_setg(errp, QCOW2_OPT_CACHE_CLEAN_INTERVAL | ||
85 | diff --git a/qemu-options.hx b/qemu-options.hx | ||
86 | index XXXXXXX..XXXXXXX 100644 | ||
87 | --- a/qemu-options.hx | ||
88 | +++ b/qemu-options.hx | ||
89 | @@ -XXX,XX +XXX,XX @@ it which is not used for the L2 cache) | ||
90 | |||
91 | @item cache-clean-interval | ||
92 | Clean unused entries in the L2 and refcount caches. The interval is in seconds. | ||
93 | -The default value is 0 and it disables this feature. | ||
94 | +The default value is 600. Setting it to 0 disables this feature. | ||
95 | |||
96 | @item pass-discard-request | ||
97 | Whether discard requests to the qcow2 device should be forwarded to the data | ||
98 | -- | ||
99 | 2.13.6 | ||
100 | |||
101 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Leonid Bloch <lbloch@janustech.com> | ||
2 | 1 | ||
3 | Signed-off-by: Leonid Bloch <lbloch@janustech.com> | ||
4 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
5 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> | ||
6 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
7 | --- | ||
8 | block/qcow2.c | 4 ++-- | ||
9 | 1 file changed, 2 insertions(+), 2 deletions(-) | ||
10 | |||
11 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
12 | index XXXXXXX..XXXXXXX 100644 | ||
13 | --- a/block/qcow2.c | ||
14 | +++ b/block/qcow2.c | ||
15 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options, | ||
16 | /* 2^(s->refcount_order - 3) is the refcount width in bytes */ | ||
17 | s->refcount_block_bits = s->cluster_bits - (s->refcount_order - 3); | ||
18 | s->refcount_block_size = 1 << s->refcount_block_bits; | ||
19 | - bs->total_sectors = header.size / 512; | ||
20 | + bs->total_sectors = header.size / BDRV_SECTOR_SIZE; | ||
21 | s->csize_shift = (62 - (s->cluster_bits - 8)); | ||
22 | s->csize_mask = (1 << (s->cluster_bits - 8)) - 1; | ||
23 | s->cluster_offset_mask = (1LL << s->csize_shift) - 1; | ||
24 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset, | ||
25 | goto fail; | ||
26 | } | ||
27 | |||
28 | - old_length = bs->total_sectors * 512; | ||
29 | + old_length = bs->total_sectors * BDRV_SECTOR_SIZE; | ||
30 | new_l1_size = size_to_l1(s, offset); | ||
31 | |||
32 | if (offset < old_length) { | ||
33 | -- | ||
34 | 2.13.6 | ||
35 | |||
36 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | Currently, the default values for werror and rerror have to be set | ||
2 | explicitly with blk_set_on_error() by the callers of blk_new(). The only | ||
3 | caller actually doing this is blockdev_init(), which is called for | ||
4 | BlockBackends created using -drive. | ||
5 | 1 | ||
6 | In particular, anonymous BlockBackends created with | ||
7 | -device ...,drive=<node-name> didn't get the correct default set and | ||
8 | instead defaulted to the integer value 0 (= BLOCKDEV_ON_ERROR_REPORT). | ||
9 | This is the intended default for rerror anyway, but the default for | ||
10 | werror should be BLOCKDEV_ON_ERROR_ENOSPC. | ||
11 | |||
12 | Set the defaults in blk_new() instead so that they apply no matter what | ||
13 | way the BlockBackend was created. | ||
14 | |||
15 | Cc: qemu-stable@nongnu.org | ||
16 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
17 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
18 | Reviewed-by: Fam Zheng <famz@redhat.com> | ||
19 | --- | ||
20 | block/block-backend.c | 3 +++ | ||
21 | tests/qemu-iotests/067.out | 1 + | ||
22 | 2 files changed, 4 insertions(+) | ||
23 | |||
24 | diff --git a/block/block-backend.c b/block/block-backend.c | ||
25 | index XXXXXXX..XXXXXXX 100644 | ||
26 | --- a/block/block-backend.c | ||
27 | +++ b/block/block-backend.c | ||
28 | @@ -XXX,XX +XXX,XX @@ BlockBackend *blk_new(uint64_t perm, uint64_t shared_perm) | ||
29 | blk->shared_perm = shared_perm; | ||
30 | blk_set_enable_write_cache(blk, true); | ||
31 | |||
32 | + blk->on_read_error = BLOCKDEV_ON_ERROR_REPORT; | ||
33 | + blk->on_write_error = BLOCKDEV_ON_ERROR_ENOSPC; | ||
34 | + | ||
35 | block_acct_init(&blk->stats); | ||
36 | |||
37 | notifier_list_init(&blk->remove_bs_notifiers); | ||
38 | diff --git a/tests/qemu-iotests/067.out b/tests/qemu-iotests/067.out | ||
39 | index XXXXXXX..XXXXXXX 100644 | ||
40 | --- a/tests/qemu-iotests/067.out | ||
41 | +++ b/tests/qemu-iotests/067.out | ||
42 | @@ -XXX,XX +XXX,XX @@ Testing: -device virtio-scsi -device scsi-cd,id=cd0 | ||
43 | { | ||
44 | "return": [ | ||
45 | { | ||
46 | + "io-status": "ok", | ||
47 | "device": "", | ||
48 | "locked": false, | ||
49 | "removable": true, | ||
50 | -- | ||
51 | 2.13.6 | ||
52 | |||
53 | diff view generated by jsdifflib |
1 | Recently, the test case has started failing because some job related | 1 | bdrv_subtree_drained_end() requires the caller to hold the AioContext |
---|---|---|---|
2 | functions want to drop the AioContext lock even though it hasn't been | 2 | lock for the drained node. Not doing this for nodes outside of the main |
3 | taken: | 3 | AioContext leads to crashes when AIO_WAIT_WHILE() needs to wait and |
4 | tries to temporarily release the lock. | ||
4 | 5 | ||
5 | (gdb) bt | 6 | Fixes: 3908b7a8994fa5ef7a89aa58cd5a02fc58141592 |
6 | #0 0x00007f51c067c9fb in raise () from /lib64/libc.so.6 | 7 | Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2046659 |
7 | #1 0x00007f51c067e77d in abort () from /lib64/libc.so.6 | 8 | Reported-by: Qing Wang <qinwang@redhat.com> |
8 | #2 0x0000558c9d5dde7b in error_exit (err=<optimized out>, msg=msg@entry=0x558c9d6fe120 <__func__.18373> "qemu_mutex_unlock_impl") at util/qemu-thread-posix.c:36 | 9 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
9 | #3 0x0000558c9d6b5263 in qemu_mutex_unlock_impl (mutex=mutex@entry=0x558c9f3999a0, file=file@entry=0x558c9d6fd36f "util/async.c", line=line@entry=516) at util/qemu-thread-posix.c:96 | 10 | Message-Id: <20220203140534.36522-2-kwolf@redhat.com> |
10 | #4 0x0000558c9d6b0565 in aio_context_release (ctx=ctx@entry=0x558c9f399940) at util/async.c:516 | 11 | Reviewed-by: Hanna Reitz <hreitz@redhat.com> |
11 | #5 0x0000558c9d5eb3da in job_completed_txn_abort (job=0x558c9f68e640) at job.c:738 | ||
12 | #6 0x0000558c9d5eb227 in job_finish_sync (job=0x558c9f68e640, finish=finish@entry=0x558c9d5eb8d0 <job_cancel_err>, errp=errp@entry=0x0) at job.c:986 | ||
13 | #7 0x0000558c9d5eb8ee in job_cancel_sync (job=<optimized out>) at job.c:941 | ||
14 | #8 0x0000558c9d64d853 in replication_close (bs=<optimized out>) at block/replication.c:148 | ||
15 | #9 0x0000558c9d5e5c9f in bdrv_close (bs=0x558c9f41b020) at block.c:3420 | ||
16 | #10 bdrv_delete (bs=0x558c9f41b020) at block.c:3629 | ||
17 | #11 bdrv_unref (bs=0x558c9f41b020) at block.c:4685 | ||
18 | #12 0x0000558c9d62a3f3 in blk_remove_bs (blk=blk@entry=0x558c9f42a7c0) at block/block-backend.c:783 | ||
19 | #13 0x0000558c9d62a667 in blk_delete (blk=0x558c9f42a7c0) at block/block-backend.c:402 | ||
20 | #14 blk_unref (blk=0x558c9f42a7c0) at block/block-backend.c:457 | ||
21 | #15 0x0000558c9d5dfcea in test_secondary_stop () at tests/test-replication.c:478 | ||
22 | #16 0x00007f51c1f13178 in g_test_run_suite_internal () from /lib64/libglib-2.0.so.0 | ||
23 | #17 0x00007f51c1f1337b in g_test_run_suite_internal () from /lib64/libglib-2.0.so.0 | ||
24 | #18 0x00007f51c1f1337b in g_test_run_suite_internal () from /lib64/libglib-2.0.so.0 | ||
25 | #19 0x00007f51c1f13552 in g_test_run_suite () from /lib64/libglib-2.0.so.0 | ||
26 | #20 0x00007f51c1f13571 in g_test_run () from /lib64/libglib-2.0.so.0 | ||
27 | #21 0x0000558c9d5de31f in main (argc=<optimized out>, argv=<optimized out>) at tests/test-replication.c:581 | ||
28 | |||
29 | It is yet unclear whether this should really be considered a bug in the | ||
30 | test case or whether blk_unref() should work for callers that haven't | ||
31 | taken the AioContext lock, but in order to fix the build tests quickly, | ||
32 | just take the AioContext lock around blk_unref(). | ||
33 | |||
34 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 12 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
35 | --- | 13 | --- |
36 | tests/test-replication.c | 11 +++++++++++ | 14 | blockdev.c | 11 ++++++++++- |
37 | 1 file changed, 11 insertions(+) | 15 | 1 file changed, 10 insertions(+), 1 deletion(-) |
38 | 16 | ||
39 | diff --git a/tests/test-replication.c b/tests/test-replication.c | 17 | diff --git a/blockdev.c b/blockdev.c |
40 | index XXXXXXX..XXXXXXX 100644 | 18 | index XXXXXXX..XXXXXXX 100644 |
41 | --- a/tests/test-replication.c | 19 | --- a/blockdev.c |
42 | +++ b/tests/test-replication.c | 20 | +++ b/blockdev.c |
43 | @@ -XXX,XX +XXX,XX @@ static BlockBackend *start_primary(void) | 21 | @@ -XXX,XX +XXX,XX @@ void qmp_blockdev_reopen(BlockdevOptionsList *reopen_list, Error **errp) |
44 | static void teardown_primary(void) | ||
45 | { | 22 | { |
46 | BlockBackend *blk; | 23 | BlockReopenQueue *queue = NULL; |
47 | + AioContext *ctx; | 24 | GSList *drained = NULL; |
48 | 25 | + GSList *p; | |
49 | /* remove P_ID */ | 26 | |
50 | blk = blk_by_name(P_ID); | 27 | /* Add each one of the BDS that we want to reopen to the queue */ |
51 | assert(blk); | 28 | for (; reopen_list != NULL; reopen_list = reopen_list->next) { |
52 | 29 | @@ -XXX,XX +XXX,XX @@ void qmp_blockdev_reopen(BlockdevOptionsList *reopen_list, Error **errp) | |
53 | + ctx = blk_get_aio_context(blk); | 30 | |
54 | + aio_context_acquire(ctx); | 31 | fail: |
55 | monitor_remove_blk(blk); | 32 | bdrv_reopen_queue_free(queue); |
56 | blk_unref(blk); | 33 | - g_slist_free_full(drained, (GDestroyNotify) bdrv_subtree_drained_end); |
57 | + aio_context_release(ctx); | 34 | + for (p = drained; p; p = p->next) { |
35 | + BlockDriverState *bs = p->data; | ||
36 | + AioContext *ctx = bdrv_get_aio_context(bs); | ||
37 | + | ||
38 | + aio_context_acquire(ctx); | ||
39 | + bdrv_subtree_drained_end(bs); | ||
40 | + aio_context_release(ctx); | ||
41 | + } | ||
42 | + g_slist_free(drained); | ||
58 | } | 43 | } |
59 | 44 | ||
60 | static void test_primary_read(void) | 45 | void qmp_blockdev_del(const char *node_name, Error **errp) |
61 | @@ -XXX,XX +XXX,XX @@ static void teardown_secondary(void) | ||
62 | { | ||
63 | /* only need to destroy two BBs */ | ||
64 | BlockBackend *blk; | ||
65 | + AioContext *ctx; | ||
66 | |||
67 | /* remove S_LOCAL_DISK_ID */ | ||
68 | blk = blk_by_name(S_LOCAL_DISK_ID); | ||
69 | assert(blk); | ||
70 | |||
71 | + ctx = blk_get_aio_context(blk); | ||
72 | + aio_context_acquire(ctx); | ||
73 | monitor_remove_blk(blk); | ||
74 | blk_unref(blk); | ||
75 | + aio_context_release(ctx); | ||
76 | |||
77 | /* remove S_ID */ | ||
78 | blk = blk_by_name(S_ID); | ||
79 | assert(blk); | ||
80 | |||
81 | + ctx = blk_get_aio_context(blk); | ||
82 | + aio_context_acquire(ctx); | ||
83 | monitor_remove_blk(blk); | ||
84 | blk_unref(blk); | ||
85 | + aio_context_release(ctx); | ||
86 | } | ||
87 | |||
88 | static void test_secondary_read(void) | ||
89 | -- | 46 | -- |
90 | 2.13.6 | 47 | 2.34.1 |
91 | 48 | ||
92 | 49 | diff view generated by jsdifflib |
1 | qemu_event_reset() must be called before the AIO request in a different | 1 | The 'throttle' block driver implements .bdrv_co_drain_end, so |
---|---|---|---|
2 | iothread is submitted. Otherwise the request could be completed before | 2 | blockdev-reopen will have to wait for it to complete in the polling |
3 | we do the qemu_event_reset() and the test would hang in | 3 | loop at the end of qmp_blockdev_reopen(). This makes AIO_WAIT_WHILE() |
4 | qemu_event_wait(). | 4 | release the AioContext lock, which causes a crash if the lock hasn't |
5 | correctly been taken. | ||
5 | 6 | ||
6 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 7 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
7 | Reviewed-by: Max Reitz <mreitz@redhat.com> | 8 | Message-Id: <20220203140534.36522-3-kwolf@redhat.com> |
8 | Tested-by: Max Reitz <mreitz@redhat.com> | 9 | Reviewed-by: Hanna Reitz <hreitz@redhat.com> |
10 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
9 | --- | 11 | --- |
10 | tests/test-bdrv-drain.c | 4 ++-- | 12 | tests/qemu-iotests/245 | 36 +++++++++++++++++++++++++++++++++--- |
11 | 1 file changed, 2 insertions(+), 2 deletions(-) | 13 | tests/qemu-iotests/245.out | 4 ++-- |
14 | 2 files changed, 35 insertions(+), 5 deletions(-) | ||
12 | 15 | ||
13 | diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c | 16 | diff --git a/tests/qemu-iotests/245 b/tests/qemu-iotests/245 |
17 | index XXXXXXX..XXXXXXX 100755 | ||
18 | --- a/tests/qemu-iotests/245 | ||
19 | +++ b/tests/qemu-iotests/245 | ||
20 | @@ -XXX,XX +XXX,XX @@ class TestBlockdevReopen(iotests.QMPTestCase): | ||
21 | self.assertEqual(self.get_node('hd1'), None) | ||
22 | self.assert_qmp(self.get_node('hd2'), 'ro', True) | ||
23 | |||
24 | - def run_test_iothreads(self, iothread_a, iothread_b, errmsg = None): | ||
25 | - opts = hd_opts(0) | ||
26 | + def run_test_iothreads(self, iothread_a, iothread_b, errmsg = None, | ||
27 | + opts_a = None, opts_b = None): | ||
28 | + opts = opts_a or hd_opts(0) | ||
29 | result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) | ||
30 | self.assert_qmp(result, 'return', {}) | ||
31 | |||
32 | - opts2 = hd_opts(2) | ||
33 | + opts2 = opts_b or hd_opts(2) | ||
34 | result = self.vm.qmp('blockdev-add', conv_keys = False, **opts2) | ||
35 | self.assert_qmp(result, 'return', {}) | ||
36 | |||
37 | @@ -XXX,XX +XXX,XX @@ class TestBlockdevReopen(iotests.QMPTestCase): | ||
38 | def test_iothreads_switch_overlay(self): | ||
39 | self.run_test_iothreads('', 'iothread0') | ||
40 | |||
41 | + def test_iothreads_with_throttling(self): | ||
42 | + # Create a throttle-group object | ||
43 | + opts = { 'qom-type': 'throttle-group', 'id': 'group0', | ||
44 | + 'limits': { 'iops-total': 1000 } } | ||
45 | + result = self.vm.qmp('object-add', conv_keys = False, **opts) | ||
46 | + self.assert_qmp(result, 'return', {}) | ||
47 | + | ||
48 | + # Options with a throttle filter between format and protocol | ||
49 | + opts = [ | ||
50 | + { | ||
51 | + 'driver': iotests.imgfmt, | ||
52 | + 'node-name': f'hd{idx}', | ||
53 | + 'file' : { | ||
54 | + 'node-name': f'hd{idx}-throttle', | ||
55 | + 'driver': 'throttle', | ||
56 | + 'throttle-group': 'group0', | ||
57 | + 'file': { | ||
58 | + 'driver': 'file', | ||
59 | + 'node-name': f'hd{idx}-file', | ||
60 | + 'filename': hd_path[idx], | ||
61 | + }, | ||
62 | + }, | ||
63 | + } | ||
64 | + for idx in (0, 2) | ||
65 | + ] | ||
66 | + | ||
67 | + self.run_test_iothreads('iothread0', 'iothread0', None, | ||
68 | + opts[0], opts[1]) | ||
69 | + | ||
70 | if __name__ == '__main__': | ||
71 | iotests.activate_logging() | ||
72 | iotests.main(supported_fmts=["qcow2"], | ||
73 | diff --git a/tests/qemu-iotests/245.out b/tests/qemu-iotests/245.out | ||
14 | index XXXXXXX..XXXXXXX 100644 | 74 | index XXXXXXX..XXXXXXX 100644 |
15 | --- a/tests/test-bdrv-drain.c | 75 | --- a/tests/qemu-iotests/245.out |
16 | +++ b/tests/test-bdrv-drain.c | 76 | +++ b/tests/qemu-iotests/245.out |
17 | @@ -XXX,XX +XXX,XX @@ static void test_iothread_common(enum drain_type drain_type, int drain_thread) | 77 | @@ -XXX,XX +XXX,XX @@ read 1/1 bytes at offset 262152 |
18 | s->bh_indirection_ctx = ctx_b; | 78 | read 1/1 bytes at offset 262160 |
19 | 79 | 1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | |
20 | aio_ret = -EINPROGRESS; | 80 | |
21 | + qemu_event_reset(&done_event); | 81 | -............... |
22 | + | 82 | +................ |
23 | if (drain_thread == 0) { | 83 | ---------------------------------------------------------------------- |
24 | acb = blk_aio_preadv(blk, 0, &qiov, 0, test_iothread_aio_cb, &aio_ret); | 84 | -Ran 25 tests |
25 | } else { | 85 | +Ran 26 tests |
26 | @@ -XXX,XX +XXX,XX @@ static void test_iothread_common(enum drain_type drain_type, int drain_thread) | 86 | |
27 | * but the drain in this thread can continue immediately after | 87 | OK |
28 | * bdrv_dec_in_flight() and aio_ret might be assigned only slightly | ||
29 | * later. */ | ||
30 | - qemu_event_reset(&done_event); | ||
31 | do_drain_begin(drain_type, bs); | ||
32 | g_assert_cmpint(bs->in_flight, ==, 0); | ||
33 | |||
34 | @@ -XXX,XX +XXX,XX @@ static void test_iothread_common(enum drain_type drain_type, int drain_thread) | ||
35 | } | ||
36 | break; | ||
37 | case 1: | ||
38 | - qemu_event_reset(&done_event); | ||
39 | aio_bh_schedule_oneshot(ctx_a, test_iothread_drain_entry, &data); | ||
40 | qemu_event_wait(&done_event); | ||
41 | break; | ||
42 | -- | 88 | -- |
43 | 2.13.6 | 89 | 2.34.1 |
44 | 90 | ||
45 | 91 | diff view generated by jsdifflib |
1 | From: Leonid Bloch <lbloch@janustech.com> | 1 | From: Bernhard Beschow <shentey@gmail.com> |
---|---|---|---|
2 | 2 | ||
3 | Fixing cache-clean-interval documentation following the recent change to | 3 | Other ISA devices such as serial-isa use the properties in their |
4 | a default of 600 seconds on supported plarforms (only Linux currently). | 4 | build_aml functions. fdc-isa not using them is probably an oversight. |
5 | 5 | ||
6 | Signed-off-by: Leonid Bloch <lbloch@janustech.com> | 6 | Signed-off-by: Bernhard Beschow <shentey@gmail.com> |
7 | Reviewed-by: Eric Blake <eblake@redhat.com> | 7 | Message-Id: <20220209191558.30393-1-shentey@gmail.com> |
8 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | ||
8 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | 9 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
9 | --- | 10 | --- |
10 | qapi/block-core.json | 3 ++- | 11 | hw/block/fdc-isa.c | 11 +++++++---- |
11 | docs/qcow2-cache.txt | 20 ++++++++++---------- | 12 | 1 file changed, 7 insertions(+), 4 deletions(-) |
12 | qemu-options.hx | 3 ++- | ||
13 | 3 files changed, 14 insertions(+), 12 deletions(-) | ||
14 | 13 | ||
15 | diff --git a/qapi/block-core.json b/qapi/block-core.json | 14 | diff --git a/hw/block/fdc-isa.c b/hw/block/fdc-isa.c |
16 | index XXXXXXX..XXXXXXX 100644 | 15 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/qapi/block-core.json | 16 | --- a/hw/block/fdc-isa.c |
18 | +++ b/qapi/block-core.json | 17 | +++ b/hw/block/fdc-isa.c |
19 | @@ -XXX,XX +XXX,XX @@ | 18 | @@ -XXX,XX +XXX,XX @@ int cmos_get_fd_drive_type(FloppyDriveType fd0) |
20 | # | 19 | |
21 | # @cache-clean-interval: clean unused entries in the L2 and refcount | 20 | static void fdc_isa_build_aml(ISADevice *isadev, Aml *scope) |
22 | # caches. The interval is in seconds. The default value | 21 | { |
23 | -# is 600, and 0 disables this feature. (since 2.5) | 22 | + FDCtrlISABus *isa = ISA_FDC(isadev); |
24 | +# is 600 on supporting platforms, and 0 on other | 23 | Aml *dev; |
25 | +# platforms. 0 disables this feature. (since 2.5) | 24 | Aml *crs; |
26 | # | 25 | int i; |
27 | # @encrypt: Image decryption options. Mandatory for | 26 | @@ -XXX,XX +XXX,XX @@ static void fdc_isa_build_aml(ISADevice *isadev, Aml *scope) |
28 | # encrypted images, except when doing a metadata-only | 27 | }; |
29 | diff --git a/docs/qcow2-cache.txt b/docs/qcow2-cache.txt | 28 | |
30 | index XXXXXXX..XXXXXXX 100644 | 29 | crs = aml_resource_template(); |
31 | --- a/docs/qcow2-cache.txt | 30 | - aml_append(crs, aml_io(AML_DECODE16, 0x03F2, 0x03F2, 0x00, 0x04)); |
32 | +++ b/docs/qcow2-cache.txt | 31 | - aml_append(crs, aml_io(AML_DECODE16, 0x03F7, 0x03F7, 0x00, 0x01)); |
33 | @@ -XXX,XX +XXX,XX @@ Reducing the memory usage | 32 | - aml_append(crs, aml_irq_no_flags(6)); |
34 | It is possible to clean unused cache entries in order to reduce the | 33 | aml_append(crs, |
35 | memory usage during periods of low I/O activity. | 34 | - aml_dma(AML_COMPATIBILITY, AML_NOTBUSMASTER, AML_TRANSFER8, 2)); |
36 | 35 | + aml_io(AML_DECODE16, isa->iobase + 2, isa->iobase + 2, 0x00, 0x04)); | |
37 | -The parameter "cache-clean-interval" defines an interval (in seconds). | 36 | + aml_append(crs, |
38 | -All cache entries that haven't been accessed during that interval are | 37 | + aml_io(AML_DECODE16, isa->iobase + 7, isa->iobase + 7, 0x00, 0x01)); |
39 | -removed from memory. | 38 | + aml_append(crs, aml_irq_no_flags(isa->irq)); |
40 | +The parameter "cache-clean-interval" defines an interval (in seconds), | 39 | + aml_append(crs, |
41 | +after which all the cache entries that haven't been accessed during the | 40 | + aml_dma(AML_COMPATIBILITY, AML_NOTBUSMASTER, AML_TRANSFER8, isa->dma)); |
42 | +interval are removed from memory. Setting this parameter to 0 disables this | 41 | |
43 | +feature. | 42 | dev = aml_device("FDC0"); |
44 | 43 | aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0700"))); | |
45 | -This example removes all unused cache entries every 15 minutes: | ||
46 | +The following example removes all unused cache entries every 15 minutes: | ||
47 | |||
48 | -drive file=hd.qcow2,cache-clean-interval=900 | ||
49 | |||
50 | -If unset, the default value for this parameter is 600. Setting it to 0 | ||
51 | -disables this feature. | ||
52 | +If unset, the default value for this parameter is 600 on platforms which | ||
53 | +support this functionality, and is 0 (disabled) on other platforms. | ||
54 | |||
55 | -Note that this functionality currently relies on the MADV_DONTNEED | ||
56 | -argument for madvise() to actually free the memory. This is a | ||
57 | -Linux-specific feature, so cache-clean-interval is not supported in | ||
58 | -other systems. | ||
59 | +This functionality currently relies on the MADV_DONTNEED argument for | ||
60 | +madvise() to actually free the memory. This is a Linux-specific feature, | ||
61 | +so cache-clean-interval is not supported on other systems. | ||
62 | diff --git a/qemu-options.hx b/qemu-options.hx | ||
63 | index XXXXXXX..XXXXXXX 100644 | ||
64 | --- a/qemu-options.hx | ||
65 | +++ b/qemu-options.hx | ||
66 | @@ -XXX,XX +XXX,XX @@ it which is not used for the L2 cache) | ||
67 | |||
68 | @item cache-clean-interval | ||
69 | Clean unused entries in the L2 and refcount caches. The interval is in seconds. | ||
70 | -The default value is 600. Setting it to 0 disables this feature. | ||
71 | +The default value is 600 on supporting platforms, and 0 on other platforms. | ||
72 | +Setting it to 0 disables this feature. | ||
73 | |||
74 | @item pass-discard-request | ||
75 | Whether discard requests to the qcow2 device should be forwarded to the data | ||
76 | -- | 44 | -- |
77 | 2.13.6 | 45 | 2.34.1 |
78 | 46 | ||
79 | 47 | diff view generated by jsdifflib |