1 | The following changes since commit 29741be341d50e4311e42ca3199f9b0bcfd4f5d2: | 1 | The following changes since commit 0a301624c2f4ced3331ffd5bce85b4274fe132af: |
---|---|---|---|
2 | 2 | ||
3 | Merge remote-tracking branch 'remotes/awilliam/tags/vfio-updates-20170710.0' into staging (2017-07-11 13:47:28 +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://github.com/XanClic/qemu.git tags/pull-block-2017-07-11 | 7 | https://gitlab.com/kmwolf/qemu.git tags/for-upstream |
8 | 8 | ||
9 | for you to fetch changes up to ced14843229cd42c282f0ee4b43bbcdc324c923a: | 9 | for you to fetch changes up to fdb8541b2e4f6ff60f435fbb5a5e1df20c275a86: |
10 | 10 | ||
11 | iotests: Add preallocated growth test for qcow2 (2017-07-11 17:45:02 +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 | - Fix crash in blockdev-reopen with iothreads | ||
17 | - fdc-isa: Respect QOM properties when building AML | ||
18 | |||
16 | ---------------------------------------------------------------- | 19 | ---------------------------------------------------------------- |
17 | Daniel P. Berrange (25): | 20 | Bernhard Beschow (1): |
18 | block: expose crypto option names / defs to other drivers | 21 | hw/block/fdc-isa: Respect QOM properties when building AML |
19 | block: add ability to set a prefix for opt names | ||
20 | qcow: document another weakness of qcow AES encryption | ||
21 | qcow: require image size to be > 1 for new images | ||
22 | iotests: skip 042 with qcow which dosn't support zero sized images | ||
23 | iotests: skip 048 with qcow which doesn't support resize | ||
24 | block: deprecate "encryption=on" in favor of "encrypt.format=aes" | ||
25 | qcow: make encrypt_sectors encrypt in place | ||
26 | qcow: convert QCow to use QCryptoBlock for encryption | ||
27 | qcow2: make qcow2_encrypt_sectors encrypt in place | ||
28 | qcow2: convert QCow2 to use QCryptoBlock for encryption | ||
29 | qcow2: extend specification to cover LUKS encryption | ||
30 | qcow2: add support for LUKS encryption format | ||
31 | qcow2: add iotests to cover LUKS encryption support | ||
32 | iotests: enable tests 134 and 158 to work with qcow (v1) | ||
33 | block: rip out all traces of password prompting | ||
34 | block: remove all encryption handling APIs | ||
35 | block: pass option prefix down to crypto layer | ||
36 | qcow2: report encryption specific image information | ||
37 | docs: document encryption options for qcow, qcow2 and luks | ||
38 | iotests: skip 159 & 170 with luks format | ||
39 | iotests: fix remainining tests to work with LUKS | ||
40 | iotests: reduce PBKDF iterations when testing LUKS | ||
41 | iotests: add more LUKS hash combination tests | ||
42 | iotests: chown LUKS device before qemu-io launches | ||
43 | 22 | ||
44 | Eric Blake (1): | 23 | Kevin Wolf (2): |
45 | tests: Avoid non-portable 'echo -ARG' | 24 | block: Lock AioContext for drain_end in blockdev-reopen |
25 | iotests: Test blockdev-reopen with iothreads and throttling | ||
46 | 26 | ||
47 | Max Reitz (19): | 27 | blockdev.c | 11 ++++++++++- |
48 | iotests: 181 does not work for all formats | 28 | hw/block/fdc-isa.c | 11 +++++++---- |
49 | iotests: Use absolute paths for executables | 29 | tests/qemu-iotests/245 | 36 +++++++++++++++++++++++++++++++++--- |
50 | iotests: Add test for colon handling | 30 | tests/qemu-iotests/245.out | 4 ++-- |
51 | block: Add PreallocMode to BD.bdrv_truncate() | 31 | 4 files changed, 52 insertions(+), 10 deletions(-) |
52 | block: Add PreallocMode to bdrv_truncate() | ||
53 | block: Add PreallocMode to blk_truncate() | ||
54 | qemu-img: Expose PreallocMode for resizing | ||
55 | block/file-posix: Small fixes in raw_create() | ||
56 | block/file-posix: Extract raw_regular_truncate() | ||
57 | block/file-posix: Generalize raw_regular_truncate | ||
58 | block/file-posix: Preallocation for truncate | ||
59 | block/qcow2: Generalize preallocate() | ||
60 | block/qcow2: Lock s->lock in preallocate() | ||
61 | block/qcow2: Metadata preallocation for truncate | ||
62 | block/qcow2: Add qcow2_refcount_area() | ||
63 | block/qcow2: Rename "fail_block" to just "fail" | ||
64 | block/qcow2: falloc/full preallocating growth | ||
65 | iotests: Add preallocated resize test for raw | ||
66 | iotests: Add preallocated growth test for qcow2 | ||
67 | |||
68 | Stefan Hajnoczi (9): | ||
69 | block: add bdrv_measure() API | ||
70 | raw-format: add bdrv_measure() support | ||
71 | qcow2: extract preallocation calculation function | ||
72 | qcow2: make refcount size calculation conservative | ||
73 | qcow2: extract image creation option parsing | ||
74 | qcow2: add bdrv_measure() support | ||
75 | qemu-img: add measure subcommand | ||
76 | qemu-iotests: support per-format golden output files | ||
77 | iotests: add test 178 for qemu-img measure | ||
78 | |||
79 | Vladimir Sementsov-Ogievskiy (30): | ||
80 | specs/qcow2: fix bitmap granularity qemu-specific note | ||
81 | specs/qcow2: do not use wording 'bitmap header' | ||
82 | hbitmap: improve dirty iter | ||
83 | tests: add hbitmap iter test | ||
84 | block: fix bdrv_dirty_bitmap_granularity signature | ||
85 | block/dirty-bitmap: add deserialize_ones func | ||
86 | qcow2-refcount: rename inc_refcounts() and make it public | ||
87 | qcow2: add bitmaps extension | ||
88 | block/dirty-bitmap: fix comment for BlockDirtyBitmap.disabled field | ||
89 | block/dirty-bitmap: add readonly field to BdrvDirtyBitmap | ||
90 | qcow2: autoloading dirty bitmaps | ||
91 | block: refactor bdrv_reopen_commit | ||
92 | block: new bdrv_reopen_bitmaps_rw interface | ||
93 | qcow2: support .bdrv_reopen_bitmaps_rw | ||
94 | block/dirty-bitmap: add autoload field to BdrvDirtyBitmap | ||
95 | block: bdrv_close: release bitmaps after drv->bdrv_close | ||
96 | block: introduce persistent dirty bitmaps | ||
97 | block/dirty-bitmap: add bdrv_dirty_bitmap_next() | ||
98 | qcow2: add persistent dirty bitmaps support | ||
99 | qcow2: store bitmaps on reopening image as read-only | ||
100 | block: add bdrv_can_store_new_dirty_bitmap | ||
101 | qcow2: add .bdrv_can_store_new_dirty_bitmap | ||
102 | qmp: add persistent flag to block-dirty-bitmap-add | ||
103 | qmp: add autoload parameter to block-dirty-bitmap-add | ||
104 | qmp: add x-debug-block-dirty-bitmap-sha256 | ||
105 | iotests: test qcow2 persistent dirty bitmap | ||
106 | block/dirty-bitmap: add bdrv_remove_persistent_dirty_bitmap | ||
107 | qcow2: add .bdrv_remove_persistent_dirty_bitmap | ||
108 | qmp: block-dirty-bitmap-remove: remove persistent | ||
109 | block: release persistent bitmaps on inactivate | ||
110 | |||
111 | sochin.jiang (1): | ||
112 | mirror: Fix inconsistent backing AioContext for after mirroring | ||
113 | |||
114 | docs/interop/qcow2.txt | 111 ++- | ||
115 | block/Makefile.objs | 2 +- | ||
116 | tests/Makefile.include | 2 +- | ||
117 | tests/tcg/cris/Makefile | 8 +- | ||
118 | qapi-schema.json | 10 +- | ||
119 | qapi/block-core.json | 197 +++-- | ||
120 | qapi/common.json | 5 +- | ||
121 | block/crypto.h | 101 +++ | ||
122 | block/qcow2.h | 69 +- | ||
123 | crypto/blockpriv.h | 2 + | ||
124 | include/block/block.h | 11 +- | ||
125 | include/block/block_int.h | 22 +- | ||
126 | include/block/dirty-bitmap.h | 22 +- | ||
127 | include/crypto/block.h | 6 +- | ||
128 | include/monitor/monitor.h | 7 - | ||
129 | include/qapi/error.h | 1 - | ||
130 | include/qemu/hbitmap.h | 49 +- | ||
131 | include/qemu/osdep.h | 2 - | ||
132 | include/sysemu/block-backend.h | 3 +- | ||
133 | block.c | 183 ++--- | ||
134 | block/blkdebug.c | 5 +- | ||
135 | block/block-backend.c | 5 +- | ||
136 | block/commit.c | 4 +- | ||
137 | block/crypto.c | 101 +-- | ||
138 | block/dirty-bitmap.c | 154 +++- | ||
139 | block/file-posix.c | 201 ++++-- | ||
140 | block/file-win32.c | 9 +- | ||
141 | block/gluster.c | 8 +- | ||
142 | block/io.c | 8 + | ||
143 | block/iscsi.c | 9 +- | ||
144 | block/mirror.c | 3 +- | ||
145 | block/nfs.c | 9 +- | ||
146 | block/parallels.c | 13 +- | ||
147 | block/qapi.c | 2 +- | ||
148 | block/qcow.c | 277 +++---- | ||
149 | block/qcow2-bitmap.c | 1482 ++++++++++++++++++++++++++++++++++++++ | ||
150 | block/qcow2-cluster.c | 66 +- | ||
151 | block/qcow2-refcount.c | 346 ++++++--- | ||
152 | block/qcow2.c | 1231 ++++++++++++++++++++++++++----- | ||
153 | block/qed.c | 11 +- | ||
154 | block/raw-format.c | 31 +- | ||
155 | block/rbd.c | 9 +- | ||
156 | block/sheepdog.c | 11 +- | ||
157 | block/vdi.c | 3 +- | ||
158 | block/vhdx-log.c | 2 +- | ||
159 | block/vhdx.c | 8 +- | ||
160 | block/vmdk.c | 7 +- | ||
161 | block/vpc.c | 2 +- | ||
162 | blockdev.c | 112 ++- | ||
163 | crypto/block-luks.c | 8 +- | ||
164 | crypto/block-qcow.c | 8 +- | ||
165 | crypto/block.c | 6 +- | ||
166 | hmp.c | 31 - | ||
167 | monitor.c | 68 -- | ||
168 | qemu-img.c | 302 +++++++- | ||
169 | qemu-io-cmds.c | 2 +- | ||
170 | qemu-io.c | 20 - | ||
171 | qmp.c | 12 +- | ||
172 | tests/test-crypto-block.c | 8 +- | ||
173 | tests/test-hbitmap.c | 19 + | ||
174 | util/hbitmap.c | 51 +- | ||
175 | util/oslib-posix.c | 66 -- | ||
176 | util/oslib-win32.c | 24 - | ||
177 | hmp-commands.hx | 2 + | ||
178 | qemu-doc.texi | 123 +++- | ||
179 | qemu-img-cmds.hx | 6 + | ||
180 | qemu-img.texi | 56 +- | ||
181 | qemu-options.hx | 4 +- | ||
182 | tests/multiboot/run_test.sh | 10 +- | ||
183 | tests/qemu-iotests/033 | 12 +- | ||
184 | tests/qemu-iotests/042 | 2 +- | ||
185 | tests/qemu-iotests/044.out | 2 +- | ||
186 | tests/qemu-iotests/048 | 2 +- | ||
187 | tests/qemu-iotests/049 | 2 +- | ||
188 | tests/qemu-iotests/049.out | 102 +-- | ||
189 | tests/qemu-iotests/051 | 7 +- | ||
190 | tests/qemu-iotests/068 | 2 +- | ||
191 | tests/qemu-iotests/082.out | 284 +++++++- | ||
192 | tests/qemu-iotests/085.out | 38 +- | ||
193 | tests/qemu-iotests/087 | 39 +- | ||
194 | tests/qemu-iotests/087.out | 16 +- | ||
195 | tests/qemu-iotests/106 | 92 +++ | ||
196 | tests/qemu-iotests/106.out | 50 ++ | ||
197 | tests/qemu-iotests/120 | 1 + | ||
198 | tests/qemu-iotests/125 | 130 ++++ | ||
199 | tests/qemu-iotests/125.out | 386 ++++++++++ | ||
200 | tests/qemu-iotests/126 | 105 +++ | ||
201 | tests/qemu-iotests/126.out | 23 + | ||
202 | tests/qemu-iotests/134 | 20 +- | ||
203 | tests/qemu-iotests/134.out | 10 +- | ||
204 | tests/qemu-iotests/140 | 9 +- | ||
205 | tests/qemu-iotests/142 | 48 +- | ||
206 | tests/qemu-iotests/144.out | 4 +- | ||
207 | tests/qemu-iotests/145 | 19 +- | ||
208 | tests/qemu-iotests/149 | 25 +- | ||
209 | tests/qemu-iotests/149.out | 1002 +++++++++++++++++++------- | ||
210 | tests/qemu-iotests/157 | 17 +- | ||
211 | tests/qemu-iotests/157.out | 16 +- | ||
212 | tests/qemu-iotests/158 | 21 +- | ||
213 | tests/qemu-iotests/158.out | 14 +- | ||
214 | tests/qemu-iotests/159 | 1 + | ||
215 | tests/qemu-iotests/165 | 105 +++ | ||
216 | tests/qemu-iotests/165.out | 5 + | ||
217 | tests/qemu-iotests/170 | 1 + | ||
218 | tests/qemu-iotests/171 | 14 +- | ||
219 | tests/qemu-iotests/174 | 2 +- | ||
220 | tests/qemu-iotests/178 | 170 +++++ | ||
221 | tests/qemu-iotests/178.out.qcow2 | 286 ++++++++ | ||
222 | tests/qemu-iotests/178.out.raw | 158 ++++ | ||
223 | tests/qemu-iotests/181 | 23 +- | ||
224 | tests/qemu-iotests/185.out | 8 +- | ||
225 | tests/qemu-iotests/188 | 76 ++ | ||
226 | tests/qemu-iotests/188.out | 18 + | ||
227 | tests/qemu-iotests/189 | 86 +++ | ||
228 | tests/qemu-iotests/189.out | 26 + | ||
229 | tests/qemu-iotests/check | 23 +- | ||
230 | tests/qemu-iotests/common | 10 +- | ||
231 | tests/qemu-iotests/common.config | 11 + | ||
232 | tests/qemu-iotests/common.filter | 3 +- | ||
233 | tests/qemu-iotests/common.qemu | 9 +- | ||
234 | tests/qemu-iotests/common.rc | 3 + | ||
235 | tests/qemu-iotests/group | 7 + | ||
236 | tests/rocker/all | 10 +- | ||
237 | 123 files changed, 7616 insertions(+), 1707 deletions(-) | ||
238 | create mode 100644 block/crypto.h | ||
239 | create mode 100644 block/qcow2-bitmap.c | ||
240 | create mode 100755 tests/qemu-iotests/106 | ||
241 | create mode 100644 tests/qemu-iotests/106.out | ||
242 | create mode 100755 tests/qemu-iotests/125 | ||
243 | create mode 100644 tests/qemu-iotests/125.out | ||
244 | create mode 100755 tests/qemu-iotests/126 | ||
245 | create mode 100644 tests/qemu-iotests/126.out | ||
246 | create mode 100755 tests/qemu-iotests/165 | ||
247 | create mode 100644 tests/qemu-iotests/165.out | ||
248 | create mode 100755 tests/qemu-iotests/178 | ||
249 | create mode 100644 tests/qemu-iotests/178.out.qcow2 | ||
250 | create mode 100644 tests/qemu-iotests/178.out.raw | ||
251 | create mode 100755 tests/qemu-iotests/188 | ||
252 | create mode 100644 tests/qemu-iotests/188.out | ||
253 | create mode 100755 tests/qemu-iotests/189 | ||
254 | create mode 100644 tests/qemu-iotests/189.out | ||
255 | |||
256 | -- | ||
257 | 2.9.4 | ||
258 | 32 | ||
259 | 33 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | ||
2 | 1 | ||
3 | The block/crypto.c defines a set of QemuOpts that provide | ||
4 | parameters for encryption. This will also be needed by | ||
5 | the qcow/qcow2 integration, so expose the relevant pieces | ||
6 | in a new block/crypto.h header. Some helper methods taking | ||
7 | QemuOpts are changed to take QDict to simplify usage in | ||
8 | other places. | ||
9 | |||
10 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
11 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
12 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
13 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
14 | Message-id: 20170623162419.26068-2-berrange@redhat.com | ||
15 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
16 | --- | ||
17 | block/crypto.h | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||
18 | block/crypto.c | 82 +++++++++++++++++----------------------------------- | ||
19 | 2 files changed, 117 insertions(+), 56 deletions(-) | ||
20 | create mode 100644 block/crypto.h | ||
21 | |||
22 | diff --git a/block/crypto.h b/block/crypto.h | ||
23 | new file mode 100644 | ||
24 | index XXXXXXX..XXXXXXX | ||
25 | --- /dev/null | ||
26 | +++ b/block/crypto.h | ||
27 | @@ -XXX,XX +XXX,XX @@ | ||
28 | +/* | ||
29 | + * QEMU block full disk encryption | ||
30 | + * | ||
31 | + * Copyright (c) 2015-2017 Red Hat, Inc. | ||
32 | + * | ||
33 | + * This library is free software; you can redistribute it and/or | ||
34 | + * modify it under the terms of the GNU Lesser General Public | ||
35 | + * License as published by the Free Software Foundation; either | ||
36 | + * version 2 of the License, or (at your option) any later version. | ||
37 | + * | ||
38 | + * This library is distributed in the hope that it will be useful, | ||
39 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
40 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
41 | + * Lesser General Public License for more details. | ||
42 | + * | ||
43 | + * You should have received a copy of the GNU Lesser General Public | ||
44 | + * License along with this library; if not, see <http://www.gnu.org/licenses/>. | ||
45 | + * | ||
46 | + */ | ||
47 | + | ||
48 | +#ifndef BLOCK_CRYPTO_H__ | ||
49 | +#define BLOCK_CRYPTO_H__ | ||
50 | + | ||
51 | +#define BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET "key-secret" | ||
52 | +#define BLOCK_CRYPTO_OPT_LUKS_CIPHER_ALG "cipher-alg" | ||
53 | +#define BLOCK_CRYPTO_OPT_LUKS_CIPHER_MODE "cipher-mode" | ||
54 | +#define BLOCK_CRYPTO_OPT_LUKS_IVGEN_ALG "ivgen-alg" | ||
55 | +#define BLOCK_CRYPTO_OPT_LUKS_IVGEN_HASH_ALG "ivgen-hash-alg" | ||
56 | +#define BLOCK_CRYPTO_OPT_LUKS_HASH_ALG "hash-alg" | ||
57 | +#define BLOCK_CRYPTO_OPT_LUKS_ITER_TIME "iter-time" | ||
58 | + | ||
59 | +#define BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET \ | ||
60 | + { \ | ||
61 | + .name = BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET, \ | ||
62 | + .type = QEMU_OPT_STRING, \ | ||
63 | + .help = "ID of the secret that provides the keyslot passphrase", \ | ||
64 | + } | ||
65 | + | ||
66 | +#define BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG \ | ||
67 | + { \ | ||
68 | + .name = BLOCK_CRYPTO_OPT_LUKS_CIPHER_ALG, \ | ||
69 | + .type = QEMU_OPT_STRING, \ | ||
70 | + .help = "Name of encryption cipher algorithm", \ | ||
71 | + } | ||
72 | + | ||
73 | +#define BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE \ | ||
74 | + { \ | ||
75 | + .name = BLOCK_CRYPTO_OPT_LUKS_CIPHER_MODE, \ | ||
76 | + .type = QEMU_OPT_STRING, \ | ||
77 | + .help = "Name of encryption cipher mode", \ | ||
78 | + } | ||
79 | + | ||
80 | +#define BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG \ | ||
81 | + { \ | ||
82 | + .name = BLOCK_CRYPTO_OPT_LUKS_IVGEN_ALG, \ | ||
83 | + .type = QEMU_OPT_STRING, \ | ||
84 | + .help = "Name of IV generator algorithm", \ | ||
85 | + } | ||
86 | + | ||
87 | +#define BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG \ | ||
88 | + { \ | ||
89 | + .name = BLOCK_CRYPTO_OPT_LUKS_IVGEN_HASH_ALG, \ | ||
90 | + .type = QEMU_OPT_STRING, \ | ||
91 | + .help = "Name of IV generator hash algorithm", \ | ||
92 | + } | ||
93 | + | ||
94 | +#define BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG \ | ||
95 | + { \ | ||
96 | + .name = BLOCK_CRYPTO_OPT_LUKS_HASH_ALG, \ | ||
97 | + .type = QEMU_OPT_STRING, \ | ||
98 | + .help = "Name of encryption hash algorithm", \ | ||
99 | + } | ||
100 | + | ||
101 | +#define BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME \ | ||
102 | + { \ | ||
103 | + .name = BLOCK_CRYPTO_OPT_LUKS_ITER_TIME, \ | ||
104 | + .type = QEMU_OPT_NUMBER, \ | ||
105 | + .help = "Time to spend in PBKDF in milliseconds", \ | ||
106 | + } | ||
107 | + | ||
108 | +QCryptoBlockCreateOptions * | ||
109 | +block_crypto_create_opts_init(QCryptoBlockFormat format, | ||
110 | + QDict *opts, | ||
111 | + Error **errp); | ||
112 | + | ||
113 | +QCryptoBlockOpenOptions * | ||
114 | +block_crypto_open_opts_init(QCryptoBlockFormat format, | ||
115 | + QDict *opts, | ||
116 | + Error **errp); | ||
117 | + | ||
118 | +#endif /* BLOCK_CRYPTO_H__ */ | ||
119 | diff --git a/block/crypto.c b/block/crypto.c | ||
120 | index XXXXXXX..XXXXXXX 100644 | ||
121 | --- a/block/crypto.c | ||
122 | +++ b/block/crypto.c | ||
123 | @@ -XXX,XX +XXX,XX @@ | ||
124 | #include "sysemu/block-backend.h" | ||
125 | #include "crypto/block.h" | ||
126 | #include "qapi/opts-visitor.h" | ||
127 | +#include "qapi/qobject-input-visitor.h" | ||
128 | #include "qapi-visit.h" | ||
129 | #include "qapi/error.h" | ||
130 | - | ||
131 | -#define BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET "key-secret" | ||
132 | -#define BLOCK_CRYPTO_OPT_LUKS_CIPHER_ALG "cipher-alg" | ||
133 | -#define BLOCK_CRYPTO_OPT_LUKS_CIPHER_MODE "cipher-mode" | ||
134 | -#define BLOCK_CRYPTO_OPT_LUKS_IVGEN_ALG "ivgen-alg" | ||
135 | -#define BLOCK_CRYPTO_OPT_LUKS_IVGEN_HASH_ALG "ivgen-hash-alg" | ||
136 | -#define BLOCK_CRYPTO_OPT_LUKS_HASH_ALG "hash-alg" | ||
137 | -#define BLOCK_CRYPTO_OPT_LUKS_ITER_TIME "iter-time" | ||
138 | +#include "block/crypto.h" | ||
139 | |||
140 | typedef struct BlockCrypto BlockCrypto; | ||
141 | |||
142 | @@ -XXX,XX +XXX,XX @@ static QemuOptsList block_crypto_runtime_opts_luks = { | ||
143 | .name = "crypto", | ||
144 | .head = QTAILQ_HEAD_INITIALIZER(block_crypto_runtime_opts_luks.head), | ||
145 | .desc = { | ||
146 | - { | ||
147 | - .name = BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET, | ||
148 | - .type = QEMU_OPT_STRING, | ||
149 | - .help = "ID of the secret that provides the encryption key", | ||
150 | - }, | ||
151 | + BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET, | ||
152 | { /* end of list */ } | ||
153 | }, | ||
154 | }; | ||
155 | @@ -XXX,XX +XXX,XX @@ static QemuOptsList block_crypto_create_opts_luks = { | ||
156 | .type = QEMU_OPT_SIZE, | ||
157 | .help = "Virtual disk size" | ||
158 | }, | ||
159 | - { | ||
160 | - .name = BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET, | ||
161 | - .type = QEMU_OPT_STRING, | ||
162 | - .help = "ID of the secret that provides the encryption key", | ||
163 | - }, | ||
164 | - { | ||
165 | - .name = BLOCK_CRYPTO_OPT_LUKS_CIPHER_ALG, | ||
166 | - .type = QEMU_OPT_STRING, | ||
167 | - .help = "Name of encryption cipher algorithm", | ||
168 | - }, | ||
169 | - { | ||
170 | - .name = BLOCK_CRYPTO_OPT_LUKS_CIPHER_MODE, | ||
171 | - .type = QEMU_OPT_STRING, | ||
172 | - .help = "Name of encryption cipher mode", | ||
173 | - }, | ||
174 | - { | ||
175 | - .name = BLOCK_CRYPTO_OPT_LUKS_IVGEN_ALG, | ||
176 | - .type = QEMU_OPT_STRING, | ||
177 | - .help = "Name of IV generator algorithm", | ||
178 | - }, | ||
179 | - { | ||
180 | - .name = BLOCK_CRYPTO_OPT_LUKS_IVGEN_HASH_ALG, | ||
181 | - .type = QEMU_OPT_STRING, | ||
182 | - .help = "Name of IV generator hash algorithm", | ||
183 | - }, | ||
184 | - { | ||
185 | - .name = BLOCK_CRYPTO_OPT_LUKS_HASH_ALG, | ||
186 | - .type = QEMU_OPT_STRING, | ||
187 | - .help = "Name of encryption hash algorithm", | ||
188 | - }, | ||
189 | - { | ||
190 | - .name = BLOCK_CRYPTO_OPT_LUKS_ITER_TIME, | ||
191 | - .type = QEMU_OPT_NUMBER, | ||
192 | - .help = "Time to spend in PBKDF in milliseconds", | ||
193 | - }, | ||
194 | + BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET, | ||
195 | + BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG, | ||
196 | + BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE, | ||
197 | + BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG, | ||
198 | + BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG, | ||
199 | + BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG, | ||
200 | + BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME, | ||
201 | { /* end of list */ } | ||
202 | }, | ||
203 | }; | ||
204 | |||
205 | |||
206 | -static QCryptoBlockOpenOptions * | ||
207 | +QCryptoBlockOpenOptions * | ||
208 | block_crypto_open_opts_init(QCryptoBlockFormat format, | ||
209 | - QemuOpts *opts, | ||
210 | + QDict *opts, | ||
211 | Error **errp) | ||
212 | { | ||
213 | Visitor *v; | ||
214 | @@ -XXX,XX +XXX,XX @@ block_crypto_open_opts_init(QCryptoBlockFormat format, | ||
215 | ret = g_new0(QCryptoBlockOpenOptions, 1); | ||
216 | ret->format = format; | ||
217 | |||
218 | - v = opts_visitor_new(opts); | ||
219 | + v = qobject_input_visitor_new_keyval(QOBJECT(opts)); | ||
220 | |||
221 | visit_start_struct(v, NULL, NULL, 0, &local_err); | ||
222 | if (local_err) { | ||
223 | @@ -XXX,XX +XXX,XX @@ block_crypto_open_opts_init(QCryptoBlockFormat format, | ||
224 | } | ||
225 | |||
226 | |||
227 | -static QCryptoBlockCreateOptions * | ||
228 | +QCryptoBlockCreateOptions * | ||
229 | block_crypto_create_opts_init(QCryptoBlockFormat format, | ||
230 | - QemuOpts *opts, | ||
231 | + QDict *opts, | ||
232 | Error **errp) | ||
233 | { | ||
234 | Visitor *v; | ||
235 | @@ -XXX,XX +XXX,XX @@ block_crypto_create_opts_init(QCryptoBlockFormat format, | ||
236 | ret = g_new0(QCryptoBlockCreateOptions, 1); | ||
237 | ret->format = format; | ||
238 | |||
239 | - v = opts_visitor_new(opts); | ||
240 | + v = qobject_input_visitor_new_keyval(QOBJECT(opts)); | ||
241 | |||
242 | visit_start_struct(v, NULL, NULL, 0, &local_err); | ||
243 | if (local_err) { | ||
244 | @@ -XXX,XX +XXX,XX @@ static int block_crypto_open_generic(QCryptoBlockFormat format, | ||
245 | int ret = -EINVAL; | ||
246 | QCryptoBlockOpenOptions *open_opts = NULL; | ||
247 | unsigned int cflags = 0; | ||
248 | + QDict *cryptoopts = NULL; | ||
249 | |||
250 | bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, | ||
251 | false, errp); | ||
252 | @@ -XXX,XX +XXX,XX @@ static int block_crypto_open_generic(QCryptoBlockFormat format, | ||
253 | goto cleanup; | ||
254 | } | ||
255 | |||
256 | - open_opts = block_crypto_open_opts_init(format, opts, errp); | ||
257 | + cryptoopts = qemu_opts_to_qdict(opts, NULL); | ||
258 | + | ||
259 | + open_opts = block_crypto_open_opts_init(format, cryptoopts, errp); | ||
260 | if (!open_opts) { | ||
261 | goto cleanup; | ||
262 | } | ||
263 | @@ -XXX,XX +XXX,XX @@ static int block_crypto_open_generic(QCryptoBlockFormat format, | ||
264 | |||
265 | ret = 0; | ||
266 | cleanup: | ||
267 | + QDECREF(cryptoopts); | ||
268 | qapi_free_QCryptoBlockOpenOptions(open_opts); | ||
269 | return ret; | ||
270 | } | ||
271 | @@ -XXX,XX +XXX,XX @@ static int block_crypto_create_generic(QCryptoBlockFormat format, | ||
272 | .opts = opts, | ||
273 | .filename = filename, | ||
274 | }; | ||
275 | + QDict *cryptoopts; | ||
276 | + | ||
277 | + cryptoopts = qemu_opts_to_qdict(opts, NULL); | ||
278 | |||
279 | - create_opts = block_crypto_create_opts_init(format, opts, errp); | ||
280 | + create_opts = block_crypto_create_opts_init(format, cryptoopts, errp); | ||
281 | if (!create_opts) { | ||
282 | return -1; | ||
283 | } | ||
284 | @@ -XXX,XX +XXX,XX @@ static int block_crypto_create_generic(QCryptoBlockFormat format, | ||
285 | |||
286 | ret = 0; | ||
287 | cleanup: | ||
288 | + QDECREF(cryptoopts); | ||
289 | qcrypto_block_free(crypto); | ||
290 | blk_unref(data.blk); | ||
291 | qapi_free_QCryptoBlockCreateOptions(create_opts); | ||
292 | -- | ||
293 | 2.9.4 | ||
294 | |||
295 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | ||
2 | 1 | ||
3 | When integrating the crypto support with qcow/qcow2, we don't | ||
4 | want to use the bare LUKS option names "hash-alg", "key-secret", | ||
5 | etc. We need to namespace them to match the nested QAPI schema. | ||
6 | |||
7 | e.g. "encrypt.hash-alg", "encrypt.key-secret" | ||
8 | |||
9 | so that they don't clash with any general qcow options at a later | ||
10 | date. | ||
11 | |||
12 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
13 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
14 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
15 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
16 | Message-id: 20170623162419.26068-3-berrange@redhat.com | ||
17 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
18 | --- | ||
19 | block/crypto.h | 40 ++++++++++++++++++++-------------------- | ||
20 | block/crypto.c | 16 ++++++++-------- | ||
21 | 2 files changed, 28 insertions(+), 28 deletions(-) | ||
22 | |||
23 | diff --git a/block/crypto.h b/block/crypto.h | ||
24 | index XXXXXXX..XXXXXXX 100644 | ||
25 | --- a/block/crypto.h | ||
26 | +++ b/block/crypto.h | ||
27 | @@ -XXX,XX +XXX,XX @@ | ||
28 | #define BLOCK_CRYPTO_OPT_LUKS_HASH_ALG "hash-alg" | ||
29 | #define BLOCK_CRYPTO_OPT_LUKS_ITER_TIME "iter-time" | ||
30 | |||
31 | -#define BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET \ | ||
32 | +#define BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(prefix) \ | ||
33 | { \ | ||
34 | - .name = BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET, \ | ||
35 | + .name = prefix BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET, \ | ||
36 | .type = QEMU_OPT_STRING, \ | ||
37 | .help = "ID of the secret that provides the keyslot passphrase", \ | ||
38 | } | ||
39 | |||
40 | -#define BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG \ | ||
41 | +#define BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG(prefix) \ | ||
42 | { \ | ||
43 | - .name = BLOCK_CRYPTO_OPT_LUKS_CIPHER_ALG, \ | ||
44 | + .name = prefix BLOCK_CRYPTO_OPT_LUKS_CIPHER_ALG, \ | ||
45 | .type = QEMU_OPT_STRING, \ | ||
46 | .help = "Name of encryption cipher algorithm", \ | ||
47 | } | ||
48 | |||
49 | -#define BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE \ | ||
50 | - { \ | ||
51 | - .name = BLOCK_CRYPTO_OPT_LUKS_CIPHER_MODE, \ | ||
52 | - .type = QEMU_OPT_STRING, \ | ||
53 | - .help = "Name of encryption cipher mode", \ | ||
54 | +#define BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE(prefix) \ | ||
55 | + { \ | ||
56 | + .name = prefix BLOCK_CRYPTO_OPT_LUKS_CIPHER_MODE, \ | ||
57 | + .type = QEMU_OPT_STRING, \ | ||
58 | + .help = "Name of encryption cipher mode", \ | ||
59 | } | ||
60 | |||
61 | -#define BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG \ | ||
62 | - { \ | ||
63 | - .name = BLOCK_CRYPTO_OPT_LUKS_IVGEN_ALG, \ | ||
64 | - .type = QEMU_OPT_STRING, \ | ||
65 | - .help = "Name of IV generator algorithm", \ | ||
66 | +#define BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG(prefix) \ | ||
67 | + { \ | ||
68 | + .name = prefix BLOCK_CRYPTO_OPT_LUKS_IVGEN_ALG, \ | ||
69 | + .type = QEMU_OPT_STRING, \ | ||
70 | + .help = "Name of IV generator algorithm", \ | ||
71 | } | ||
72 | |||
73 | -#define BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG \ | ||
74 | +#define BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG(prefix) \ | ||
75 | { \ | ||
76 | - .name = BLOCK_CRYPTO_OPT_LUKS_IVGEN_HASH_ALG, \ | ||
77 | + .name = prefix BLOCK_CRYPTO_OPT_LUKS_IVGEN_HASH_ALG, \ | ||
78 | .type = QEMU_OPT_STRING, \ | ||
79 | .help = "Name of IV generator hash algorithm", \ | ||
80 | } | ||
81 | |||
82 | -#define BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG \ | ||
83 | +#define BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG(prefix) \ | ||
84 | { \ | ||
85 | - .name = BLOCK_CRYPTO_OPT_LUKS_HASH_ALG, \ | ||
86 | + .name = prefix BLOCK_CRYPTO_OPT_LUKS_HASH_ALG, \ | ||
87 | .type = QEMU_OPT_STRING, \ | ||
88 | .help = "Name of encryption hash algorithm", \ | ||
89 | } | ||
90 | |||
91 | -#define BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME \ | ||
92 | +#define BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME(prefix) \ | ||
93 | { \ | ||
94 | - .name = BLOCK_CRYPTO_OPT_LUKS_ITER_TIME, \ | ||
95 | + .name = prefix BLOCK_CRYPTO_OPT_LUKS_ITER_TIME, \ | ||
96 | .type = QEMU_OPT_NUMBER, \ | ||
97 | .help = "Time to spend in PBKDF in milliseconds", \ | ||
98 | } | ||
99 | diff --git a/block/crypto.c b/block/crypto.c | ||
100 | index XXXXXXX..XXXXXXX 100644 | ||
101 | --- a/block/crypto.c | ||
102 | +++ b/block/crypto.c | ||
103 | @@ -XXX,XX +XXX,XX @@ static QemuOptsList block_crypto_runtime_opts_luks = { | ||
104 | .name = "crypto", | ||
105 | .head = QTAILQ_HEAD_INITIALIZER(block_crypto_runtime_opts_luks.head), | ||
106 | .desc = { | ||
107 | - BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET, | ||
108 | + BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(""), | ||
109 | { /* end of list */ } | ||
110 | }, | ||
111 | }; | ||
112 | @@ -XXX,XX +XXX,XX @@ static QemuOptsList block_crypto_create_opts_luks = { | ||
113 | .type = QEMU_OPT_SIZE, | ||
114 | .help = "Virtual disk size" | ||
115 | }, | ||
116 | - BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET, | ||
117 | - BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG, | ||
118 | - BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE, | ||
119 | - BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG, | ||
120 | - BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG, | ||
121 | - BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG, | ||
122 | - BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME, | ||
123 | + BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(""), | ||
124 | + BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG(""), | ||
125 | + BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE(""), | ||
126 | + BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG(""), | ||
127 | + BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG(""), | ||
128 | + BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG(""), | ||
129 | + BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME(""), | ||
130 | { /* end of list */ } | ||
131 | }, | ||
132 | }; | ||
133 | -- | ||
134 | 2.9.4 | ||
135 | |||
136 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | ||
2 | 1 | ||
3 | Document that use of guest virtual sector numbers as the basis for | ||
4 | the initialization vectors is a potential weakness, when combined | ||
5 | with internal snapshots or multiple images using the same passphrase. | ||
6 | This fixes the formatting of the itemized list too. | ||
7 | |||
8 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
9 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
10 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
11 | Message-id: 20170623162419.26068-4-berrange@redhat.com | ||
12 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
13 | --- | ||
14 | qemu-img.texi | 19 ++++++++++++++++--- | ||
15 | 1 file changed, 16 insertions(+), 3 deletions(-) | ||
16 | |||
17 | diff --git a/qemu-img.texi b/qemu-img.texi | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/qemu-img.texi | ||
20 | +++ b/qemu-img.texi | ||
21 | @@ -XXX,XX +XXX,XX @@ The use of encryption in qcow and qcow2 images is considered to be flawed by | ||
22 | modern cryptography standards, suffering from a number of design problems: | ||
23 | |||
24 | @itemize @minus | ||
25 | -@item The AES-CBC cipher is used with predictable initialization vectors based | ||
26 | +@item | ||
27 | +The AES-CBC cipher is used with predictable initialization vectors based | ||
28 | on the sector number. This makes it vulnerable to chosen plaintext attacks | ||
29 | which can reveal the existence of encrypted data. | ||
30 | -@item The user passphrase is directly used as the encryption key. A poorly | ||
31 | +@item | ||
32 | +The user passphrase is directly used as the encryption key. A poorly | ||
33 | chosen or short passphrase will compromise the security of the encryption. | ||
34 | -@item In the event of the passphrase being compromised there is no way to | ||
35 | +@item | ||
36 | +In the event of the passphrase being compromised there is no way to | ||
37 | change the passphrase to protect data in any qcow images. The files must | ||
38 | be cloned, using a different encryption passphrase in the new file. The | ||
39 | original file must then be securely erased using a program like shred, | ||
40 | though even this is ineffective with many modern storage technologies. | ||
41 | +@item | ||
42 | +Initialization vectors used to encrypt sectors are based on the | ||
43 | +guest virtual sector number, instead of the host physical sector. When | ||
44 | +a disk image has multiple internal snapshots this means that data in | ||
45 | +multiple physical sectors is encrypted with the same initialization | ||
46 | +vector. With the CBC mode, this opens the possibility of watermarking | ||
47 | +attacks if the attack can collect multiple sectors encrypted with the | ||
48 | +same IV and some predictable data. Having multiple qcow2 images with | ||
49 | +the same passphrase also exposes this weakness since the passphrase | ||
50 | +is directly used as the key. | ||
51 | @end itemize | ||
52 | |||
53 | Use of qcow / qcow2 encryption is thus strongly discouraged. Users are | ||
54 | -- | ||
55 | 2.9.4 | ||
56 | |||
57 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | ||
2 | 1 | ||
3 | The qcow driver refuses to open images which are less than | ||
4 | 2 bytes in size, but will happily create such images. Add | ||
5 | a check in the create path to avoid this discrepancy. | ||
6 | |||
7 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
8 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
9 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
10 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
11 | Message-id: 20170623162419.26068-5-berrange@redhat.com | ||
12 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
13 | --- | ||
14 | block/qcow.c | 6 ++++++ | ||
15 | 1 file changed, 6 insertions(+) | ||
16 | |||
17 | diff --git a/block/qcow.c b/block/qcow.c | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/block/qcow.c | ||
20 | +++ b/block/qcow.c | ||
21 | @@ -XXX,XX +XXX,XX @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp) | ||
22 | /* Read out options */ | ||
23 | total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0), | ||
24 | BDRV_SECTOR_SIZE); | ||
25 | + if (total_size == 0) { | ||
26 | + error_setg(errp, "Image size is too small, cannot be zero length"); | ||
27 | + ret = -EINVAL; | ||
28 | + goto cleanup; | ||
29 | + } | ||
30 | + | ||
31 | backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE); | ||
32 | if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) { | ||
33 | flags |= BLOCK_FLAG_ENCRYPT; | ||
34 | -- | ||
35 | 2.9.4 | ||
36 | |||
37 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | ||
2 | 1 | ||
3 | Test 042 is designed to verify operation with zero sized images. | ||
4 | Such images are not supported with qcow (v1), so this test has | ||
5 | always failed. | ||
6 | |||
7 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
8 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
9 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
10 | Message-id: 20170623162419.26068-6-berrange@redhat.com | ||
11 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
12 | --- | ||
13 | tests/qemu-iotests/042 | 2 +- | ||
14 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
15 | |||
16 | diff --git a/tests/qemu-iotests/042 b/tests/qemu-iotests/042 | ||
17 | index XXXXXXX..XXXXXXX 100755 | ||
18 | --- a/tests/qemu-iotests/042 | ||
19 | +++ b/tests/qemu-iotests/042 | ||
20 | @@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15 | ||
21 | . ./common.rc | ||
22 | . ./common.filter | ||
23 | |||
24 | -_supported_fmt qcow2 qcow qed | ||
25 | +_supported_fmt qcow2 qed | ||
26 | _supported_proto file | ||
27 | _supported_os Linux | ||
28 | |||
29 | -- | ||
30 | 2.9.4 | ||
31 | |||
32 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | ||
2 | 1 | ||
3 | Test 048 is designed to verify data preservation during an | ||
4 | image resize. The qcow (v1) format impl has never supported | ||
5 | resize so always fails. | ||
6 | |||
7 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
8 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
9 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
10 | Message-id: 20170623162419.26068-7-berrange@redhat.com | ||
11 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
12 | --- | ||
13 | tests/qemu-iotests/048 | 2 +- | ||
14 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
15 | |||
16 | diff --git a/tests/qemu-iotests/048 b/tests/qemu-iotests/048 | ||
17 | index XXXXXXX..XXXXXXX 100755 | ||
18 | --- a/tests/qemu-iotests/048 | ||
19 | +++ b/tests/qemu-iotests/048 | ||
20 | @@ -XXX,XX +XXX,XX @@ _compare() | ||
21 | . ./common.filter | ||
22 | . ./common.pattern | ||
23 | |||
24 | -_supported_fmt raw qcow qcow2 qed luks | ||
25 | +_supported_fmt raw qcow2 qed luks | ||
26 | _supported_proto file | ||
27 | _supported_os Linux | ||
28 | |||
29 | -- | ||
30 | 2.9.4 | ||
31 | |||
32 | diff view generated by jsdifflib |
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | 1 | bdrv_subtree_drained_end() requires the caller to hold the AioContext |
---|---|---|---|
2 | lock for the drained node. Not doing this for nodes outside of the main | ||
3 | AioContext leads to crashes when AIO_WAIT_WHILE() needs to wait and | ||
4 | tries to temporarily release the lock. | ||
2 | 5 | ||
3 | Now that all encryption keys must be provided upfront via | 6 | Fixes: 3908b7a8994fa5ef7a89aa58cd5a02fc58141592 |
4 | the QCryptoSecret API and associated block driver properties | 7 | Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2046659 |
5 | there is no need for any explicit encryption handling APIs | 8 | Reported-by: Qing Wang <qinwang@redhat.com> |
6 | in the block layer. Encryption can be handled transparently | 9 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
7 | within the block driver. We only retain an API for querying | 10 | Message-Id: <20220203140534.36522-2-kwolf@redhat.com> |
8 | whether an image is encrypted or not, since that is a | 11 | Reviewed-by: Hanna Reitz <hreitz@redhat.com> |
9 | potentially useful piece of metadata to report to the user. | 12 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
13 | --- | ||
14 | blockdev.c | 11 ++++++++++- | ||
15 | 1 file changed, 10 insertions(+), 1 deletion(-) | ||
10 | 16 | ||
11 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
12 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
13 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
14 | Message-id: 20170623162419.26068-18-berrange@redhat.com | ||
15 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
16 | --- | ||
17 | qapi/block-core.json | 37 ++--------------------- | ||
18 | qapi/common.json | 5 +-- | ||
19 | include/block/block.h | 3 -- | ||
20 | include/block/block_int.h | 1 - | ||
21 | include/qapi/error.h | 1 - | ||
22 | block.c | 77 +---------------------------------------------- | ||
23 | block/crypto.c | 1 - | ||
24 | block/qapi.c | 2 +- | ||
25 | block/qcow.c | 8 ++++- | ||
26 | block/qcow2.c | 1 - | ||
27 | blockdev.c | 37 ++--------------------- | ||
28 | hmp-commands.hx | 2 ++ | ||
29 | 12 files changed, 16 insertions(+), 159 deletions(-) | ||
30 | |||
31 | diff --git a/qapi/block-core.json b/qapi/block-core.json | ||
32 | index XXXXXXX..XXXXXXX 100644 | ||
33 | --- a/qapi/block-core.json | ||
34 | +++ b/qapi/block-core.json | ||
35 | @@ -XXX,XX +XXX,XX @@ | ||
36 | # | ||
37 | # @encrypted: true if the backing device is encrypted | ||
38 | # | ||
39 | -# @encryption_key_missing: true if the backing device is encrypted but an | ||
40 | -# valid encryption key is missing | ||
41 | +# @encryption_key_missing: Deprecated; always false | ||
42 | # | ||
43 | # @detect_zeroes: detect and optimize zero writes (Since 2.1) | ||
44 | # | ||
45 | @@ -XXX,XX +XXX,XX @@ | ||
46 | # This command sets the password of a block device that has not been open | ||
47 | # with a password and requires one. | ||
48 | # | ||
49 | -# The two cases where this can happen are a block device is created through | ||
50 | -# QEMU's initial command line or a block device is changed through the legacy | ||
51 | -# @change interface. | ||
52 | -# | ||
53 | -# In the event that the block device is created through the initial command | ||
54 | -# line, the VM will start in the stopped state regardless of whether '-S' is | ||
55 | -# used. The intention is for a management tool to query the block devices to | ||
56 | -# determine which ones are encrypted, set the passwords with this command, and | ||
57 | -# then start the guest with the @cont command. | ||
58 | -# | ||
59 | -# Either @device or @node-name must be set but not both. | ||
60 | -# | ||
61 | -# @device: the name of the block backend device to set the password on | ||
62 | -# | ||
63 | -# @node-name: graph node name to set the password on (Since 2.0) | ||
64 | -# | ||
65 | -# @password: the password to use for the device | ||
66 | -# | ||
67 | -# Returns: nothing on success | ||
68 | -# If @device is not a valid block device, DeviceNotFound | ||
69 | -# If @device is not encrypted, DeviceNotEncrypted | ||
70 | -# | ||
71 | -# Notes: Not all block formats support encryption and some that do are not | ||
72 | -# able to validate that a password is correct. Disk corruption may | ||
73 | -# occur if an invalid password is specified. | ||
74 | -# | ||
75 | -# Since: 0.14.0 | ||
76 | -# | ||
77 | -# Example: | ||
78 | -# | ||
79 | -# -> { "execute": "block_passwd", "arguments": { "device": "ide0-hd0", | ||
80 | -# "password": "12345" } } | ||
81 | -# <- { "return": {} } | ||
82 | +# This command is now obsolete and will always return an error since 2.10 | ||
83 | # | ||
84 | ## | ||
85 | { 'command': 'block_passwd', 'data': {'*device': 'str', | ||
86 | diff --git a/qapi/common.json b/qapi/common.json | ||
87 | index XXXXXXX..XXXXXXX 100644 | ||
88 | --- a/qapi/common.json | ||
89 | +++ b/qapi/common.json | ||
90 | @@ -XXX,XX +XXX,XX @@ | ||
91 | # | ||
92 | # @CommandNotFound: the requested command has not been found | ||
93 | # | ||
94 | -# @DeviceEncrypted: the requested operation can't be fulfilled because the | ||
95 | -# selected device is encrypted | ||
96 | -# | ||
97 | # @DeviceNotActive: a device has failed to be become active | ||
98 | # | ||
99 | # @DeviceNotFound: the requested device has not been found | ||
100 | @@ -XXX,XX +XXX,XX @@ | ||
101 | ## | ||
102 | { 'enum': 'QapiErrorClass', | ||
103 | # Keep this in sync with ErrorClass in error.h | ||
104 | - 'data': [ 'GenericError', 'CommandNotFound', 'DeviceEncrypted', | ||
105 | + 'data': [ 'GenericError', 'CommandNotFound', | ||
106 | 'DeviceNotActive', 'DeviceNotFound', 'KVMMissingCap' ] } | ||
107 | |||
108 | ## | ||
109 | diff --git a/include/block/block.h b/include/block/block.h | ||
110 | index XXXXXXX..XXXXXXX 100644 | ||
111 | --- a/include/block/block.h | ||
112 | +++ b/include/block/block.h | ||
113 | @@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_next(BdrvNextIterator *it); | ||
114 | |||
115 | BlockDriverState *bdrv_next_monitor_owned(BlockDriverState *bs); | ||
116 | bool bdrv_is_encrypted(BlockDriverState *bs); | ||
117 | -bool bdrv_key_required(BlockDriverState *bs); | ||
118 | -int bdrv_set_key(BlockDriverState *bs, const char *key); | ||
119 | -void bdrv_add_key(BlockDriverState *bs, const char *key, Error **errp); | ||
120 | void bdrv_iterate_format(void (*it)(void *opaque, const char *name), | ||
121 | void *opaque); | ||
122 | const char *bdrv_get_node_name(const BlockDriverState *bs); | ||
123 | diff --git a/include/block/block_int.h b/include/block/block_int.h | ||
124 | index XXXXXXX..XXXXXXX 100644 | ||
125 | --- a/include/block/block_int.h | ||
126 | +++ b/include/block/block_int.h | ||
127 | @@ -XXX,XX +XXX,XX @@ struct BlockDriverState { | ||
128 | int open_flags; /* flags used to open the file, re-used for re-open */ | ||
129 | bool read_only; /* if true, the media is read only */ | ||
130 | bool encrypted; /* if true, the media is encrypted */ | ||
131 | - bool valid_key; /* if true, a valid encryption key has been set */ | ||
132 | bool sg; /* if true, the device is a /dev/sg* */ | ||
133 | bool probed; /* if true, format was probed rather than specified */ | ||
134 | bool force_share; /* if true, always allow all shared permissions */ | ||
135 | diff --git a/include/qapi/error.h b/include/qapi/error.h | ||
136 | index XXXXXXX..XXXXXXX 100644 | ||
137 | --- a/include/qapi/error.h | ||
138 | +++ b/include/qapi/error.h | ||
139 | @@ -XXX,XX +XXX,XX @@ | ||
140 | typedef enum ErrorClass { | ||
141 | ERROR_CLASS_GENERIC_ERROR = QAPI_ERROR_CLASS_GENERICERROR, | ||
142 | ERROR_CLASS_COMMAND_NOT_FOUND = QAPI_ERROR_CLASS_COMMANDNOTFOUND, | ||
143 | - ERROR_CLASS_DEVICE_ENCRYPTED = QAPI_ERROR_CLASS_DEVICEENCRYPTED, | ||
144 | ERROR_CLASS_DEVICE_NOT_ACTIVE = QAPI_ERROR_CLASS_DEVICENOTACTIVE, | ||
145 | ERROR_CLASS_DEVICE_NOT_FOUND = QAPI_ERROR_CLASS_DEVICENOTFOUND, | ||
146 | ERROR_CLASS_KVM_MISSING_CAP = QAPI_ERROR_CLASS_KVMMISSINGCAP, | ||
147 | diff --git a/block.c b/block.c | ||
148 | index XXXXXXX..XXXXXXX 100644 | ||
149 | --- a/block.c | ||
150 | +++ b/block.c | ||
151 | @@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_open_inherit(const char *filename, | ||
152 | goto close_and_fail; | ||
153 | } | ||
154 | |||
155 | - if (!bdrv_key_required(bs)) { | ||
156 | - bdrv_parent_cb_change_media(bs, true); | ||
157 | - } else if (!runstate_check(RUN_STATE_PRELAUNCH) | ||
158 | - && !runstate_check(RUN_STATE_INMIGRATE) | ||
159 | - && !runstate_check(RUN_STATE_PAUSED)) { /* HACK */ | ||
160 | - error_setg(errp, | ||
161 | - "Guest must be stopped for opening of encrypted image"); | ||
162 | - goto close_and_fail; | ||
163 | - } | ||
164 | + bdrv_parent_cb_change_media(bs, true); | ||
165 | |||
166 | QDECREF(options); | ||
167 | |||
168 | @@ -XXX,XX +XXX,XX @@ static void bdrv_close(BlockDriverState *bs) | ||
169 | bs->backing_format[0] = '\0'; | ||
170 | bs->total_sectors = 0; | ||
171 | bs->encrypted = false; | ||
172 | - bs->valid_key = false; | ||
173 | bs->sg = false; | ||
174 | QDECREF(bs->options); | ||
175 | QDECREF(bs->explicit_options); | ||
176 | @@ -XXX,XX +XXX,XX @@ bool bdrv_is_encrypted(BlockDriverState *bs) | ||
177 | return bs->encrypted; | ||
178 | } | ||
179 | |||
180 | -bool bdrv_key_required(BlockDriverState *bs) | ||
181 | -{ | ||
182 | - BdrvChild *backing = bs->backing; | ||
183 | - | ||
184 | - if (backing && backing->bs->encrypted && !backing->bs->valid_key) { | ||
185 | - return true; | ||
186 | - } | ||
187 | - return (bs->encrypted && !bs->valid_key); | ||
188 | -} | ||
189 | - | ||
190 | -int bdrv_set_key(BlockDriverState *bs, const char *key) | ||
191 | -{ | ||
192 | - int ret; | ||
193 | - if (bs->backing && bs->backing->bs->encrypted) { | ||
194 | - ret = bdrv_set_key(bs->backing->bs, key); | ||
195 | - if (ret < 0) | ||
196 | - return ret; | ||
197 | - if (!bs->encrypted) | ||
198 | - return 0; | ||
199 | - } | ||
200 | - if (!bs->encrypted) { | ||
201 | - return -EINVAL; | ||
202 | - } else if (!bs->drv || !bs->drv->bdrv_set_key) { | ||
203 | - return -ENOMEDIUM; | ||
204 | - } | ||
205 | - ret = bs->drv->bdrv_set_key(bs, key); | ||
206 | - if (ret < 0) { | ||
207 | - bs->valid_key = false; | ||
208 | - } else if (!bs->valid_key) { | ||
209 | - /* call the change callback now, we skipped it on open */ | ||
210 | - bs->valid_key = true; | ||
211 | - bdrv_parent_cb_change_media(bs, true); | ||
212 | - } | ||
213 | - return ret; | ||
214 | -} | ||
215 | - | ||
216 | -/* | ||
217 | - * Provide an encryption key for @bs. | ||
218 | - * If @key is non-null: | ||
219 | - * If @bs is not encrypted, fail. | ||
220 | - * Else if the key is invalid, fail. | ||
221 | - * Else set @bs's key to @key, replacing the existing key, if any. | ||
222 | - * If @key is null: | ||
223 | - * If @bs is encrypted and still lacks a key, fail. | ||
224 | - * Else do nothing. | ||
225 | - * On failure, store an error object through @errp if non-null. | ||
226 | - */ | ||
227 | -void bdrv_add_key(BlockDriverState *bs, const char *key, Error **errp) | ||
228 | -{ | ||
229 | - if (key) { | ||
230 | - if (!bdrv_is_encrypted(bs)) { | ||
231 | - error_setg(errp, "Node '%s' is not encrypted", | ||
232 | - bdrv_get_device_or_node_name(bs)); | ||
233 | - } else if (bdrv_set_key(bs, key) < 0) { | ||
234 | - error_setg(errp, QERR_INVALID_PASSWORD); | ||
235 | - } | ||
236 | - } else { | ||
237 | - if (bdrv_key_required(bs)) { | ||
238 | - error_set(errp, ERROR_CLASS_DEVICE_ENCRYPTED, | ||
239 | - "'%s' (%s) is encrypted", | ||
240 | - bdrv_get_device_or_node_name(bs), | ||
241 | - bdrv_get_encrypted_filename(bs)); | ||
242 | - } | ||
243 | - } | ||
244 | -} | ||
245 | - | ||
246 | const char *bdrv_get_format_name(BlockDriverState *bs) | ||
247 | { | ||
248 | return bs->drv ? bs->drv->format_name : NULL; | ||
249 | diff --git a/block/crypto.c b/block/crypto.c | ||
250 | index XXXXXXX..XXXXXXX 100644 | ||
251 | --- a/block/crypto.c | ||
252 | +++ b/block/crypto.c | ||
253 | @@ -XXX,XX +XXX,XX @@ static int block_crypto_open_generic(QCryptoBlockFormat format, | ||
254 | } | ||
255 | |||
256 | bs->encrypted = true; | ||
257 | - bs->valid_key = true; | ||
258 | |||
259 | ret = 0; | ||
260 | cleanup: | ||
261 | diff --git a/block/qapi.c b/block/qapi.c | ||
262 | index XXXXXXX..XXXXXXX 100644 | ||
263 | --- a/block/qapi.c | ||
264 | +++ b/block/qapi.c | ||
265 | @@ -XXX,XX +XXX,XX @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk, | ||
266 | info->ro = bs->read_only; | ||
267 | info->drv = g_strdup(bs->drv->format_name); | ||
268 | info->encrypted = bs->encrypted; | ||
269 | - info->encryption_key_missing = bdrv_key_required(bs); | ||
270 | + info->encryption_key_missing = false; | ||
271 | |||
272 | info->cache = g_new(BlockdevCacheInfo, 1); | ||
273 | *info->cache = (BlockdevCacheInfo) { | ||
274 | diff --git a/block/qcow.c b/block/qcow.c | ||
275 | index XXXXXXX..XXXXXXX 100644 | ||
276 | --- a/block/qcow.c | ||
277 | +++ b/block/qcow.c | ||
278 | @@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags, | ||
279 | goto fail; | ||
280 | } | ||
281 | bs->encrypted = true; | ||
282 | - bs->valid_key = true; | ||
283 | + } else { | ||
284 | + if (encryptfmt) { | ||
285 | + error_setg(errp, "No encryption in image header, but options " | ||
286 | + "specified format '%s'", encryptfmt); | ||
287 | + ret = -EINVAL; | ||
288 | + goto fail; | ||
289 | + } | ||
290 | } | ||
291 | s->cluster_bits = header.cluster_bits; | ||
292 | s->cluster_size = 1 << s->cluster_bits; | ||
293 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
294 | index XXXXXXX..XXXXXXX 100644 | ||
295 | --- a/block/qcow2.c | ||
296 | +++ b/block/qcow2.c | ||
297 | @@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags, | ||
298 | } | ||
299 | |||
300 | bs->encrypted = true; | ||
301 | - bs->valid_key = true; | ||
302 | } | ||
303 | |||
304 | s->l2_bits = s->cluster_bits - 3; /* L2 is always one cluster */ | ||
305 | diff --git a/blockdev.c b/blockdev.c | 17 | diff --git a/blockdev.c b/blockdev.c |
306 | index XXXXXXX..XXXXXXX 100644 | 18 | index XXXXXXX..XXXXXXX 100644 |
307 | --- a/blockdev.c | 19 | --- a/blockdev.c |
308 | +++ b/blockdev.c | 20 | +++ b/blockdev.c |
309 | @@ -XXX,XX +XXX,XX @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts, | 21 | @@ -XXX,XX +XXX,XX @@ void qmp_blockdev_reopen(BlockdevOptionsList *reopen_list, Error **errp) |
310 | |||
311 | bs->detect_zeroes = detect_zeroes; | ||
312 | |||
313 | - if (bdrv_key_required(bs)) { | ||
314 | - autostart = 0; | ||
315 | - } | ||
316 | - | ||
317 | block_acct_setup(blk_get_stats(blk), account_invalid, account_failed); | ||
318 | |||
319 | if (!parse_stats_intervals(blk_get_stats(blk), interval_list, errp)) { | ||
320 | @@ -XXX,XX +XXX,XX @@ void qmp_block_passwd(bool has_device, const char *device, | ||
321 | bool has_node_name, const char *node_name, | ||
322 | const char *password, Error **errp) | ||
323 | { | 22 | { |
324 | - Error *local_err = NULL; | 23 | BlockReopenQueue *queue = NULL; |
325 | - BlockDriverState *bs; | 24 | GSList *drained = NULL; |
326 | - AioContext *aio_context; | 25 | + GSList *p; |
327 | - | 26 | |
328 | - bs = bdrv_lookup_bs(has_device ? device : NULL, | 27 | /* Add each one of the BDS that we want to reopen to the queue */ |
329 | - has_node_name ? node_name : NULL, | 28 | for (; reopen_list != NULL; reopen_list = reopen_list->next) { |
330 | - &local_err); | 29 | @@ -XXX,XX +XXX,XX @@ void qmp_blockdev_reopen(BlockdevOptionsList *reopen_list, Error **errp) |
331 | - if (local_err) { | 30 | |
332 | - error_propagate(errp, local_err); | 31 | fail: |
333 | - return; | 32 | bdrv_reopen_queue_free(queue); |
334 | - } | 33 | - g_slist_free_full(drained, (GDestroyNotify) bdrv_subtree_drained_end); |
335 | - | 34 | + for (p = drained; p; p = p->next) { |
336 | - aio_context = bdrv_get_aio_context(bs); | 35 | + BlockDriverState *bs = p->data; |
337 | - aio_context_acquire(aio_context); | 36 | + AioContext *ctx = bdrv_get_aio_context(bs); |
338 | - | 37 | + |
339 | - bdrv_add_key(bs, password, errp); | 38 | + aio_context_acquire(ctx); |
340 | - | 39 | + bdrv_subtree_drained_end(bs); |
341 | - aio_context_release(aio_context); | 40 | + aio_context_release(ctx); |
342 | + error_setg(errp, | 41 | + } |
343 | + "Setting block passwords directly is no longer supported"); | 42 | + g_slist_free(drained); |
344 | } | 43 | } |
345 | 44 | ||
346 | /* | 45 | void qmp_blockdev_del(const char *node_name, Error **errp) |
347 | @@ -XXX,XX +XXX,XX @@ void qmp_blockdev_change_medium(bool has_device, const char *device, | ||
348 | goto fail; | ||
349 | } | ||
350 | |||
351 | - bdrv_add_key(medium_bs, NULL, &err); | ||
352 | - if (err) { | ||
353 | - error_propagate(errp, err); | ||
354 | - goto fail; | ||
355 | - } | ||
356 | - | ||
357 | rc = do_open_tray(has_device ? device : NULL, | ||
358 | has_id ? id : NULL, | ||
359 | false, &err); | ||
360 | @@ -XXX,XX +XXX,XX @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp) | ||
361 | |||
362 | QTAILQ_INSERT_TAIL(&monitor_bdrv_states, bs, monitor_list); | ||
363 | |||
364 | - if (bs && bdrv_key_required(bs)) { | ||
365 | - QTAILQ_REMOVE(&monitor_bdrv_states, bs, monitor_list); | ||
366 | - bdrv_unref(bs); | ||
367 | - error_setg(errp, "blockdev-add doesn't support encrypted devices"); | ||
368 | - goto fail; | ||
369 | - } | ||
370 | - | ||
371 | fail: | ||
372 | visit_free(v); | ||
373 | } | ||
374 | diff --git a/hmp-commands.hx b/hmp-commands.hx | ||
375 | index XXXXXXX..XXXXXXX 100644 | ||
376 | --- a/hmp-commands.hx | ||
377 | +++ b/hmp-commands.hx | ||
378 | @@ -XXX,XX +XXX,XX @@ STEXI | ||
379 | @item block_passwd @var{device} @var{password} | ||
380 | @findex block_passwd | ||
381 | Set the encrypted device @var{device} password to @var{password} | ||
382 | + | ||
383 | +This command is now obsolete and will always return an error since 2.10 | ||
384 | ETEXI | ||
385 | |||
386 | { | ||
387 | -- | 46 | -- |
388 | 2.9.4 | 47 | 2.34.1 |
389 | 48 | ||
390 | 49 | diff view generated by jsdifflib |
1 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 1 | The 'throttle' block driver implements .bdrv_co_drain_end, so |
---|---|---|---|
2 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | 2 | blockdev-reopen will have to wait for it to complete in the polling |
3 | Message-id: 20170613202107.10125-17-mreitz@redhat.com | 3 | loop at the end of qmp_blockdev_reopen(). This makes AIO_WAIT_WHILE() |
4 | Signed-off-by: Max Reitz <mreitz@redhat.com> | 4 | release the AioContext lock, which causes a crash if the lock hasn't |
5 | correctly been taken. | ||
6 | |||
7 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
8 | Message-Id: <20220203140534.36522-3-kwolf@redhat.com> | ||
9 | Reviewed-by: Hanna Reitz <hreitz@redhat.com> | ||
10 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
5 | --- | 11 | --- |
6 | tests/qemu-iotests/125 | 130 +++++++++++++++ | 12 | tests/qemu-iotests/245 | 36 +++++++++++++++++++++++++++++++++--- |
7 | tests/qemu-iotests/125.out | 386 +++++++++++++++++++++++++++++++++++++++++++++ | 13 | tests/qemu-iotests/245.out | 4 ++-- |
8 | tests/qemu-iotests/group | 1 + | 14 | 2 files changed, 35 insertions(+), 5 deletions(-) |
9 | 3 files changed, 517 insertions(+) | ||
10 | create mode 100755 tests/qemu-iotests/125 | ||
11 | create mode 100644 tests/qemu-iotests/125.out | ||
12 | 15 | ||
13 | diff --git a/tests/qemu-iotests/125 b/tests/qemu-iotests/125 | 16 | diff --git a/tests/qemu-iotests/245 b/tests/qemu-iotests/245 |
14 | new file mode 100755 | 17 | index XXXXXXX..XXXXXXX 100755 |
15 | index XXXXXXX..XXXXXXX | 18 | --- a/tests/qemu-iotests/245 |
16 | --- /dev/null | 19 | +++ b/tests/qemu-iotests/245 |
17 | +++ b/tests/qemu-iotests/125 | 20 | @@ -XXX,XX +XXX,XX @@ class TestBlockdevReopen(iotests.QMPTestCase): |
18 | @@ -XXX,XX +XXX,XX @@ | 21 | self.assertEqual(self.get_node('hd1'), None) |
19 | +#!/bin/bash | 22 | self.assert_qmp(self.get_node('hd2'), 'ro', True) |
20 | +# | 23 | |
21 | +# Test preallocated growth of qcow2 images | 24 | - def run_test_iothreads(self, iothread_a, iothread_b, errmsg = None): |
22 | +# | 25 | - opts = hd_opts(0) |
23 | +# Copyright (C) 2017 Red Hat, Inc. | 26 | + def run_test_iothreads(self, iothread_a, iothread_b, errmsg = None, |
24 | +# | 27 | + opts_a = None, opts_b = None): |
25 | +# This program is free software; you can redistribute it and/or modify | 28 | + opts = opts_a or hd_opts(0) |
26 | +# it under the terms of the GNU General Public License as published by | 29 | result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) |
27 | +# the Free Software Foundation; either version 2 of the License, or | 30 | self.assert_qmp(result, 'return', {}) |
28 | +# (at your option) any later version. | 31 | |
29 | +# | 32 | - opts2 = hd_opts(2) |
30 | +# This program is distributed in the hope that it will be useful, | 33 | + opts2 = opts_b or hd_opts(2) |
31 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | 34 | result = self.vm.qmp('blockdev-add', conv_keys = False, **opts2) |
32 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 35 | self.assert_qmp(result, 'return', {}) |
33 | +# GNU General Public License for more details. | 36 | |
34 | +# | 37 | @@ -XXX,XX +XXX,XX @@ class TestBlockdevReopen(iotests.QMPTestCase): |
35 | +# You should have received a copy of the GNU General Public License | 38 | def test_iothreads_switch_overlay(self): |
36 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | 39 | self.run_test_iothreads('', 'iothread0') |
37 | +# | 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', {}) | ||
38 | + | 47 | + |
39 | +# creator | 48 | + # Options with a throttle filter between format and protocol |
40 | +owner=mreitz@redhat.com | 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 | + ] | ||
41 | + | 66 | + |
42 | +seq=$(basename $0) | 67 | + self.run_test_iothreads('iothread0', 'iothread0', None, |
43 | +echo "QA output created by $seq" | 68 | + opts[0], opts[1]) |
44 | + | 69 | + |
45 | +here=$PWD | 70 | if __name__ == '__main__': |
46 | +status=1 # failure is the default! | 71 | iotests.activate_logging() |
47 | + | 72 | iotests.main(supported_fmts=["qcow2"], |
48 | +_cleanup() | 73 | diff --git a/tests/qemu-iotests/245.out b/tests/qemu-iotests/245.out |
49 | +{ | ||
50 | + _cleanup_test_img | ||
51 | +} | ||
52 | +trap "_cleanup; exit \$status" 0 1 2 3 15 | ||
53 | + | ||
54 | +get_image_size_on_host() | ||
55 | +{ | ||
56 | + $QEMU_IMG info -f "$IMGFMT" "$TEST_IMG" | grep "disk size" \ | ||
57 | + | sed -e 's/^[^0-9]*\([0-9]\+\).*$/\1/' | ||
58 | +} | ||
59 | + | ||
60 | +# get standard environment and filters | ||
61 | +. ./common.rc | ||
62 | +. ./common.filter | ||
63 | + | ||
64 | +_supported_fmt qcow2 | ||
65 | +_supported_proto file | ||
66 | +_supported_os Linux | ||
67 | + | ||
68 | +if [ -z "$TEST_IMG_FILE" ]; then | ||
69 | + TEST_IMG_FILE=$TEST_IMG | ||
70 | +fi | ||
71 | + | ||
72 | +# Generally, we create some image with or without existing preallocation and | ||
73 | +# then resize it. Then we write some data into the image and verify that its | ||
74 | +# size does not change if we have used preallocation. | ||
75 | + | ||
76 | +# With a cluster size of 512 B, one L2 table covers 64 * 512 B = 32 kB. | ||
77 | +# One cluster of the L1 table covers 64 * 32 kB = 2 MB. | ||
78 | +# There are multiple cases we want to test: | ||
79 | +# (1) Grow an image without having to allocate a new L2 table. | ||
80 | +# (2) Grow an image, having to allocate a new L2 table. | ||
81 | +# (3) Grow an image, having to grow the L1 table. | ||
82 | +# Therefore, we create an image that is 48 kB below 2 MB. Then: | ||
83 | +# (1) We resize it to 2 MB - 32 kB. (+ 16 kB) | ||
84 | +# (2) We resize it to 2 MB. (+ 48 kB) | ||
85 | +# (3) We resize it to 2 MB + 32 kB. (+ 80 kB) | ||
86 | + | ||
87 | +# in B | ||
88 | +CREATION_SIZE=$((2 * 1024 * 1024 - 48 * 1024)) | ||
89 | + | ||
90 | +# in kB | ||
91 | +for GROWTH_SIZE in 16 48 80; do | ||
92 | + for create_mode in off metadata falloc full; do | ||
93 | + for growth_mode in off metadata falloc full; do | ||
94 | + echo "--- growth_size=$GROWTH_SIZE create_mode=$create_mode growth_mode=$growth_mode ---" | ||
95 | + | ||
96 | + IMGOPTS="preallocation=$create_mode,cluster_size=512" _make_test_img ${CREATION_SIZE} | ||
97 | + $QEMU_IMG resize -f "$IMGFMT" --preallocation=$growth_mode "$TEST_IMG" +${GROWTH_SIZE}K | ||
98 | + | ||
99 | + host_size_0=$(get_image_size_on_host) | ||
100 | + file_length_0=$(stat -c '%s' "$TEST_IMG_FILE") | ||
101 | + | ||
102 | + $QEMU_IO -c "write 0 $CREATION_SIZE" "$TEST_IMG" | _filter_qemu_io | ||
103 | + | ||
104 | + host_size_1=$(get_image_size_on_host) | ||
105 | + file_length_1=$(stat -c '%s' "$TEST_IMG_FILE") | ||
106 | + | ||
107 | + $QEMU_IO -c "write $CREATION_SIZE ${GROWTH_SIZE}K" "$TEST_IMG" | _filter_qemu_io | ||
108 | + | ||
109 | + host_size_2=$(get_image_size_on_host) | ||
110 | + file_length_2=$(stat -c '%s' "$TEST_IMG_FILE") | ||
111 | + | ||
112 | + # Test creation preallocation: Compare #0 against #1 | ||
113 | + if [ $create_mode != off ]; then | ||
114 | + # The image length should not have grown | ||
115 | + if [ $file_length_1 -gt $file_length_0 ]; then | ||
116 | + echo "ERROR (create): Image length has grown from $file_length_0 to $file_length_1" | ||
117 | + fi | ||
118 | + if [ $create_mode != metadata ]; then | ||
119 | + # The host size should not have grown either | ||
120 | + if [ $host_size_1 -gt $host_size_0 ]; then | ||
121 | + echo "ERROR (create): Host size has grown from $host_size_0 to $host_size_1" | ||
122 | + fi | ||
123 | + fi | ||
124 | + fi | ||
125 | + | ||
126 | + # Test resize preallocation: Compare #2 against #1 | ||
127 | + if [ $growth_mode != off ]; then | ||
128 | + # The image length should not have grown | ||
129 | + if [ $file_length_2 -gt $file_length_1 ]; then | ||
130 | + echo "ERROR (grow): Image length has grown from $file_length_1 to $file_length_2" | ||
131 | + fi | ||
132 | + if [ $create_mode != metadata ]; then | ||
133 | + # The host size should not have grown either | ||
134 | + if [ $host_size_2 -gt $host_size_1 ]; then | ||
135 | + echo "ERROR (grow): Host size has grown from $host_size_1 to $host_size_2" | ||
136 | + fi | ||
137 | + fi | ||
138 | + fi | ||
139 | + | ||
140 | + echo | ||
141 | + done | ||
142 | + done | ||
143 | +done | ||
144 | + | ||
145 | +# success, all done | ||
146 | +echo '*** done' | ||
147 | +rm -f $seq.full | ||
148 | +status=0 | ||
149 | diff --git a/tests/qemu-iotests/125.out b/tests/qemu-iotests/125.out | ||
150 | new file mode 100644 | ||
151 | index XXXXXXX..XXXXXXX | ||
152 | --- /dev/null | ||
153 | +++ b/tests/qemu-iotests/125.out | ||
154 | @@ -XXX,XX +XXX,XX @@ | ||
155 | +QA output created by 125 | ||
156 | +--- growth_size=16 create_mode=off growth_mode=off --- | ||
157 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off | ||
158 | +Image resized. | ||
159 | +wrote 2048000/2048000 bytes at offset 0 | ||
160 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
161 | +wrote 16384/16384 bytes at offset 2048000 | ||
162 | +16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
163 | + | ||
164 | +--- growth_size=16 create_mode=off growth_mode=metadata --- | ||
165 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off | ||
166 | +Image resized. | ||
167 | +wrote 2048000/2048000 bytes at offset 0 | ||
168 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
169 | +wrote 16384/16384 bytes at offset 2048000 | ||
170 | +16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
171 | + | ||
172 | +--- growth_size=16 create_mode=off growth_mode=falloc --- | ||
173 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off | ||
174 | +Image resized. | ||
175 | +wrote 2048000/2048000 bytes at offset 0 | ||
176 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
177 | +wrote 16384/16384 bytes at offset 2048000 | ||
178 | +16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
179 | + | ||
180 | +--- growth_size=16 create_mode=off growth_mode=full --- | ||
181 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off | ||
182 | +Image resized. | ||
183 | +wrote 2048000/2048000 bytes at offset 0 | ||
184 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
185 | +wrote 16384/16384 bytes at offset 2048000 | ||
186 | +16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
187 | + | ||
188 | +--- growth_size=16 create_mode=metadata growth_mode=off --- | ||
189 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata | ||
190 | +Image resized. | ||
191 | +wrote 2048000/2048000 bytes at offset 0 | ||
192 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
193 | +wrote 16384/16384 bytes at offset 2048000 | ||
194 | +16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
195 | + | ||
196 | +--- growth_size=16 create_mode=metadata growth_mode=metadata --- | ||
197 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata | ||
198 | +Image resized. | ||
199 | +wrote 2048000/2048000 bytes at offset 0 | ||
200 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
201 | +wrote 16384/16384 bytes at offset 2048000 | ||
202 | +16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
203 | + | ||
204 | +--- growth_size=16 create_mode=metadata growth_mode=falloc --- | ||
205 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata | ||
206 | +Image resized. | ||
207 | +wrote 2048000/2048000 bytes at offset 0 | ||
208 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
209 | +wrote 16384/16384 bytes at offset 2048000 | ||
210 | +16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
211 | + | ||
212 | +--- growth_size=16 create_mode=metadata growth_mode=full --- | ||
213 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata | ||
214 | +Image resized. | ||
215 | +wrote 2048000/2048000 bytes at offset 0 | ||
216 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
217 | +wrote 16384/16384 bytes at offset 2048000 | ||
218 | +16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
219 | + | ||
220 | +--- growth_size=16 create_mode=falloc growth_mode=off --- | ||
221 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc | ||
222 | +Image resized. | ||
223 | +wrote 2048000/2048000 bytes at offset 0 | ||
224 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
225 | +wrote 16384/16384 bytes at offset 2048000 | ||
226 | +16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
227 | + | ||
228 | +--- growth_size=16 create_mode=falloc growth_mode=metadata --- | ||
229 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc | ||
230 | +Image resized. | ||
231 | +wrote 2048000/2048000 bytes at offset 0 | ||
232 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
233 | +wrote 16384/16384 bytes at offset 2048000 | ||
234 | +16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
235 | + | ||
236 | +--- growth_size=16 create_mode=falloc growth_mode=falloc --- | ||
237 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc | ||
238 | +Image resized. | ||
239 | +wrote 2048000/2048000 bytes at offset 0 | ||
240 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
241 | +wrote 16384/16384 bytes at offset 2048000 | ||
242 | +16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
243 | + | ||
244 | +--- growth_size=16 create_mode=falloc growth_mode=full --- | ||
245 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc | ||
246 | +Image resized. | ||
247 | +wrote 2048000/2048000 bytes at offset 0 | ||
248 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
249 | +wrote 16384/16384 bytes at offset 2048000 | ||
250 | +16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
251 | + | ||
252 | +--- growth_size=16 create_mode=full growth_mode=off --- | ||
253 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full | ||
254 | +Image resized. | ||
255 | +wrote 2048000/2048000 bytes at offset 0 | ||
256 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
257 | +wrote 16384/16384 bytes at offset 2048000 | ||
258 | +16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
259 | + | ||
260 | +--- growth_size=16 create_mode=full growth_mode=metadata --- | ||
261 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full | ||
262 | +Image resized. | ||
263 | +wrote 2048000/2048000 bytes at offset 0 | ||
264 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
265 | +wrote 16384/16384 bytes at offset 2048000 | ||
266 | +16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
267 | + | ||
268 | +--- growth_size=16 create_mode=full growth_mode=falloc --- | ||
269 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full | ||
270 | +Image resized. | ||
271 | +wrote 2048000/2048000 bytes at offset 0 | ||
272 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
273 | +wrote 16384/16384 bytes at offset 2048000 | ||
274 | +16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
275 | + | ||
276 | +--- growth_size=16 create_mode=full growth_mode=full --- | ||
277 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full | ||
278 | +Image resized. | ||
279 | +wrote 2048000/2048000 bytes at offset 0 | ||
280 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
281 | +wrote 16384/16384 bytes at offset 2048000 | ||
282 | +16 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
283 | + | ||
284 | +--- growth_size=48 create_mode=off growth_mode=off --- | ||
285 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off | ||
286 | +Image resized. | ||
287 | +wrote 2048000/2048000 bytes at offset 0 | ||
288 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
289 | +wrote 49152/49152 bytes at offset 2048000 | ||
290 | +48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
291 | + | ||
292 | +--- growth_size=48 create_mode=off growth_mode=metadata --- | ||
293 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off | ||
294 | +Image resized. | ||
295 | +wrote 2048000/2048000 bytes at offset 0 | ||
296 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
297 | +wrote 49152/49152 bytes at offset 2048000 | ||
298 | +48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
299 | + | ||
300 | +--- growth_size=48 create_mode=off growth_mode=falloc --- | ||
301 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off | ||
302 | +Image resized. | ||
303 | +wrote 2048000/2048000 bytes at offset 0 | ||
304 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
305 | +wrote 49152/49152 bytes at offset 2048000 | ||
306 | +48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
307 | + | ||
308 | +--- growth_size=48 create_mode=off growth_mode=full --- | ||
309 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off | ||
310 | +Image resized. | ||
311 | +wrote 2048000/2048000 bytes at offset 0 | ||
312 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
313 | +wrote 49152/49152 bytes at offset 2048000 | ||
314 | +48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
315 | + | ||
316 | +--- growth_size=48 create_mode=metadata growth_mode=off --- | ||
317 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata | ||
318 | +Image resized. | ||
319 | +wrote 2048000/2048000 bytes at offset 0 | ||
320 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
321 | +wrote 49152/49152 bytes at offset 2048000 | ||
322 | +48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
323 | + | ||
324 | +--- growth_size=48 create_mode=metadata growth_mode=metadata --- | ||
325 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata | ||
326 | +Image resized. | ||
327 | +wrote 2048000/2048000 bytes at offset 0 | ||
328 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
329 | +wrote 49152/49152 bytes at offset 2048000 | ||
330 | +48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
331 | + | ||
332 | +--- growth_size=48 create_mode=metadata growth_mode=falloc --- | ||
333 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata | ||
334 | +Image resized. | ||
335 | +wrote 2048000/2048000 bytes at offset 0 | ||
336 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
337 | +wrote 49152/49152 bytes at offset 2048000 | ||
338 | +48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
339 | + | ||
340 | +--- growth_size=48 create_mode=metadata growth_mode=full --- | ||
341 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata | ||
342 | +Image resized. | ||
343 | +wrote 2048000/2048000 bytes at offset 0 | ||
344 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
345 | +wrote 49152/49152 bytes at offset 2048000 | ||
346 | +48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
347 | + | ||
348 | +--- growth_size=48 create_mode=falloc growth_mode=off --- | ||
349 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc | ||
350 | +Image resized. | ||
351 | +wrote 2048000/2048000 bytes at offset 0 | ||
352 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
353 | +wrote 49152/49152 bytes at offset 2048000 | ||
354 | +48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
355 | + | ||
356 | +--- growth_size=48 create_mode=falloc growth_mode=metadata --- | ||
357 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc | ||
358 | +Image resized. | ||
359 | +wrote 2048000/2048000 bytes at offset 0 | ||
360 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
361 | +wrote 49152/49152 bytes at offset 2048000 | ||
362 | +48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
363 | + | ||
364 | +--- growth_size=48 create_mode=falloc growth_mode=falloc --- | ||
365 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc | ||
366 | +Image resized. | ||
367 | +wrote 2048000/2048000 bytes at offset 0 | ||
368 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
369 | +wrote 49152/49152 bytes at offset 2048000 | ||
370 | +48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
371 | + | ||
372 | +--- growth_size=48 create_mode=falloc growth_mode=full --- | ||
373 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc | ||
374 | +Image resized. | ||
375 | +wrote 2048000/2048000 bytes at offset 0 | ||
376 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
377 | +wrote 49152/49152 bytes at offset 2048000 | ||
378 | +48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
379 | + | ||
380 | +--- growth_size=48 create_mode=full growth_mode=off --- | ||
381 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full | ||
382 | +Image resized. | ||
383 | +wrote 2048000/2048000 bytes at offset 0 | ||
384 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
385 | +wrote 49152/49152 bytes at offset 2048000 | ||
386 | +48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
387 | + | ||
388 | +--- growth_size=48 create_mode=full growth_mode=metadata --- | ||
389 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full | ||
390 | +Image resized. | ||
391 | +wrote 2048000/2048000 bytes at offset 0 | ||
392 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
393 | +wrote 49152/49152 bytes at offset 2048000 | ||
394 | +48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
395 | + | ||
396 | +--- growth_size=48 create_mode=full growth_mode=falloc --- | ||
397 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full | ||
398 | +Image resized. | ||
399 | +wrote 2048000/2048000 bytes at offset 0 | ||
400 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
401 | +wrote 49152/49152 bytes at offset 2048000 | ||
402 | +48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
403 | + | ||
404 | +--- growth_size=48 create_mode=full growth_mode=full --- | ||
405 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full | ||
406 | +Image resized. | ||
407 | +wrote 2048000/2048000 bytes at offset 0 | ||
408 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
409 | +wrote 49152/49152 bytes at offset 2048000 | ||
410 | +48 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
411 | + | ||
412 | +--- growth_size=80 create_mode=off growth_mode=off --- | ||
413 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off | ||
414 | +Image resized. | ||
415 | +wrote 2048000/2048000 bytes at offset 0 | ||
416 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
417 | +wrote 81920/81920 bytes at offset 2048000 | ||
418 | +80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
419 | + | ||
420 | +--- growth_size=80 create_mode=off growth_mode=metadata --- | ||
421 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off | ||
422 | +Image resized. | ||
423 | +wrote 2048000/2048000 bytes at offset 0 | ||
424 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
425 | +wrote 81920/81920 bytes at offset 2048000 | ||
426 | +80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
427 | + | ||
428 | +--- growth_size=80 create_mode=off growth_mode=falloc --- | ||
429 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off | ||
430 | +Image resized. | ||
431 | +wrote 2048000/2048000 bytes at offset 0 | ||
432 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
433 | +wrote 81920/81920 bytes at offset 2048000 | ||
434 | +80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
435 | + | ||
436 | +--- growth_size=80 create_mode=off growth_mode=full --- | ||
437 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=off | ||
438 | +Image resized. | ||
439 | +wrote 2048000/2048000 bytes at offset 0 | ||
440 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
441 | +wrote 81920/81920 bytes at offset 2048000 | ||
442 | +80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
443 | + | ||
444 | +--- growth_size=80 create_mode=metadata growth_mode=off --- | ||
445 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata | ||
446 | +Image resized. | ||
447 | +wrote 2048000/2048000 bytes at offset 0 | ||
448 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
449 | +wrote 81920/81920 bytes at offset 2048000 | ||
450 | +80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
451 | + | ||
452 | +--- growth_size=80 create_mode=metadata growth_mode=metadata --- | ||
453 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata | ||
454 | +Image resized. | ||
455 | +wrote 2048000/2048000 bytes at offset 0 | ||
456 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
457 | +wrote 81920/81920 bytes at offset 2048000 | ||
458 | +80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
459 | + | ||
460 | +--- growth_size=80 create_mode=metadata growth_mode=falloc --- | ||
461 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata | ||
462 | +Image resized. | ||
463 | +wrote 2048000/2048000 bytes at offset 0 | ||
464 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
465 | +wrote 81920/81920 bytes at offset 2048000 | ||
466 | +80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
467 | + | ||
468 | +--- growth_size=80 create_mode=metadata growth_mode=full --- | ||
469 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=metadata | ||
470 | +Image resized. | ||
471 | +wrote 2048000/2048000 bytes at offset 0 | ||
472 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
473 | +wrote 81920/81920 bytes at offset 2048000 | ||
474 | +80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
475 | + | ||
476 | +--- growth_size=80 create_mode=falloc growth_mode=off --- | ||
477 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc | ||
478 | +Image resized. | ||
479 | +wrote 2048000/2048000 bytes at offset 0 | ||
480 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
481 | +wrote 81920/81920 bytes at offset 2048000 | ||
482 | +80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
483 | + | ||
484 | +--- growth_size=80 create_mode=falloc growth_mode=metadata --- | ||
485 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc | ||
486 | +Image resized. | ||
487 | +wrote 2048000/2048000 bytes at offset 0 | ||
488 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
489 | +wrote 81920/81920 bytes at offset 2048000 | ||
490 | +80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
491 | + | ||
492 | +--- growth_size=80 create_mode=falloc growth_mode=falloc --- | ||
493 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc | ||
494 | +Image resized. | ||
495 | +wrote 2048000/2048000 bytes at offset 0 | ||
496 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
497 | +wrote 81920/81920 bytes at offset 2048000 | ||
498 | +80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
499 | + | ||
500 | +--- growth_size=80 create_mode=falloc growth_mode=full --- | ||
501 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=falloc | ||
502 | +Image resized. | ||
503 | +wrote 2048000/2048000 bytes at offset 0 | ||
504 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
505 | +wrote 81920/81920 bytes at offset 2048000 | ||
506 | +80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
507 | + | ||
508 | +--- growth_size=80 create_mode=full growth_mode=off --- | ||
509 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full | ||
510 | +Image resized. | ||
511 | +wrote 2048000/2048000 bytes at offset 0 | ||
512 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
513 | +wrote 81920/81920 bytes at offset 2048000 | ||
514 | +80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
515 | + | ||
516 | +--- growth_size=80 create_mode=full growth_mode=metadata --- | ||
517 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full | ||
518 | +Image resized. | ||
519 | +wrote 2048000/2048000 bytes at offset 0 | ||
520 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
521 | +wrote 81920/81920 bytes at offset 2048000 | ||
522 | +80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
523 | + | ||
524 | +--- growth_size=80 create_mode=full growth_mode=falloc --- | ||
525 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full | ||
526 | +Image resized. | ||
527 | +wrote 2048000/2048000 bytes at offset 0 | ||
528 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
529 | +wrote 81920/81920 bytes at offset 2048000 | ||
530 | +80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
531 | + | ||
532 | +--- growth_size=80 create_mode=full growth_mode=full --- | ||
533 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2048000 preallocation=full | ||
534 | +Image resized. | ||
535 | +wrote 2048000/2048000 bytes at offset 0 | ||
536 | +1.953 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
537 | +wrote 81920/81920 bytes at offset 2048000 | ||
538 | +80 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
539 | + | ||
540 | +*** done | ||
541 | diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group | ||
542 | index XXXXXXX..XXXXXXX 100644 | 74 | index XXXXXXX..XXXXXXX 100644 |
543 | --- a/tests/qemu-iotests/group | 75 | --- a/tests/qemu-iotests/245.out |
544 | +++ b/tests/qemu-iotests/group | 76 | +++ b/tests/qemu-iotests/245.out |
545 | @@ -XXX,XX +XXX,XX @@ | 77 | @@ -XXX,XX +XXX,XX @@ read 1/1 bytes at offset 262152 |
546 | 122 rw auto | 78 | read 1/1 bytes at offset 262160 |
547 | 123 rw auto quick | 79 | 1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) |
548 | 124 rw auto backing | 80 | |
549 | +125 rw auto | 81 | -............... |
550 | 126 rw auto backing | 82 | +................ |
551 | 128 rw auto quick | 83 | ---------------------------------------------------------------------- |
552 | 129 rw auto quick | 84 | -Ran 25 tests |
85 | +Ran 26 tests | ||
86 | |||
87 | OK | ||
553 | -- | 88 | -- |
554 | 2.9.4 | 89 | 2.34.1 |
555 | 90 | ||
556 | 91 | diff view generated by jsdifflib |
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | 1 | From: Bernhard Beschow <shentey@gmail.com> |
---|---|---|---|
2 | 2 | ||
3 | Historically the qcow & qcow2 image formats supported a property | 3 | Other ISA devices such as serial-isa use the properties in their |
4 | "encryption=on" to enable their built-in AES encryption. We'll | 4 | build_aml functions. fdc-isa not using them is probably an oversight. |
5 | soon be supporting LUKS for qcow2, so need a more general purpose | ||
6 | way to enable encryption, with a choice of formats. | ||
7 | 5 | ||
8 | This introduces an "encrypt.format" option, which will later be | 6 | Signed-off-by: Bernhard Beschow <shentey@gmail.com> |
9 | joined by a number of other "encrypt.XXX" options. The use of | 7 | Message-Id: <20220209191558.30393-1-shentey@gmail.com> |
10 | a "encrypt." prefix instead of "encrypt-" is done to facilitate | 8 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> |
11 | mapping to a nested QAPI schema at later date. | 9 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
10 | --- | ||
11 | hw/block/fdc-isa.c | 11 +++++++---- | ||
12 | 1 file changed, 7 insertions(+), 4 deletions(-) | ||
12 | 13 | ||
13 | e.g. the preferred syntax is now | 14 | diff --git a/hw/block/fdc-isa.c b/hw/block/fdc-isa.c |
14 | |||
15 | qemu-img create -f qcow2 -o encrypt.format=aes demo.qcow2 | ||
16 | |||
17 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
18 | Message-id: 20170623162419.26068-8-berrange@redhat.com | ||
19 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
20 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
21 | --- | ||
22 | include/block/block_int.h | 2 +- | ||
23 | block/qcow.c | 31 ++++++++++++--- | ||
24 | block/qcow2.c | 34 ++++++++++++---- | ||
25 | qemu-img.c | 4 +- | ||
26 | tests/qemu-iotests/049.out | 98 +++++++++++++++++++++++----------------------- | ||
27 | tests/qemu-iotests/082.out | 95 ++++++++++++++++++++++++++++---------------- | ||
28 | tests/qemu-iotests/085.out | 38 +++++++++--------- | ||
29 | tests/qemu-iotests/144.out | 4 +- | ||
30 | tests/qemu-iotests/185.out | 8 ++-- | ||
31 | 9 files changed, 191 insertions(+), 123 deletions(-) | ||
32 | |||
33 | diff --git a/include/block/block_int.h b/include/block/block_int.h | ||
34 | index XXXXXXX..XXXXXXX 100644 | 15 | index XXXXXXX..XXXXXXX 100644 |
35 | --- a/include/block/block_int.h | 16 | --- a/hw/block/fdc-isa.c |
36 | +++ b/include/block/block_int.h | 17 | +++ b/hw/block/fdc-isa.c |
37 | @@ -XXX,XX +XXX,XX @@ | 18 | @@ -XXX,XX +XXX,XX @@ int cmos_get_fd_drive_type(FloppyDriveType fd0) |
38 | #include "qemu/main-loop.h" | 19 | |
39 | #include "qemu/throttle.h" | 20 | static void fdc_isa_build_aml(ISADevice *isadev, Aml *scope) |
40 | |||
41 | -#define BLOCK_FLAG_ENCRYPT 1 | ||
42 | #define BLOCK_FLAG_LAZY_REFCOUNTS 8 | ||
43 | |||
44 | #define BLOCK_OPT_SIZE "size" | ||
45 | #define BLOCK_OPT_ENCRYPT "encryption" | ||
46 | +#define BLOCK_OPT_ENCRYPT_FORMAT "encrypt.format" | ||
47 | #define BLOCK_OPT_COMPAT6 "compat6" | ||
48 | #define BLOCK_OPT_HWVERSION "hwversion" | ||
49 | #define BLOCK_OPT_BACKING_FILE "backing_file" | ||
50 | diff --git a/block/qcow.c b/block/qcow.c | ||
51 | index XXXXXXX..XXXXXXX 100644 | ||
52 | --- a/block/qcow.c | ||
53 | +++ b/block/qcow.c | ||
54 | @@ -XXX,XX +XXX,XX @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp) | ||
55 | uint8_t *tmp; | ||
56 | int64_t total_size = 0; | ||
57 | char *backing_file = NULL; | ||
58 | - int flags = 0; | ||
59 | Error *local_err = NULL; | ||
60 | int ret; | ||
61 | BlockBackend *qcow_blk; | ||
62 | + const char *encryptfmt = NULL; | ||
63 | |||
64 | /* Read out options */ | ||
65 | total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0), | ||
66 | @@ -XXX,XX +XXX,XX @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp) | ||
67 | } | ||
68 | |||
69 | backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE); | ||
70 | - if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) { | ||
71 | - flags |= BLOCK_FLAG_ENCRYPT; | ||
72 | + encryptfmt = qemu_opt_get_del(opts, BLOCK_OPT_ENCRYPT_FORMAT); | ||
73 | + if (encryptfmt) { | ||
74 | + if (qemu_opt_get(opts, BLOCK_OPT_ENCRYPT)) { | ||
75 | + error_setg(errp, "Options " BLOCK_OPT_ENCRYPT " and " | ||
76 | + BLOCK_OPT_ENCRYPT_FORMAT " are mutually exclusive"); | ||
77 | + ret = -EINVAL; | ||
78 | + goto cleanup; | ||
79 | + } | ||
80 | + } else if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) { | ||
81 | + encryptfmt = "aes"; | ||
82 | } | ||
83 | |||
84 | ret = bdrv_create_file(filename, opts, &local_err); | ||
85 | @@ -XXX,XX +XXX,XX @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp) | ||
86 | l1_size = (total_size + (1LL << shift) - 1) >> shift; | ||
87 | |||
88 | header.l1_table_offset = cpu_to_be64(header_size); | ||
89 | - if (flags & BLOCK_FLAG_ENCRYPT) { | ||
90 | + if (encryptfmt) { | ||
91 | + if (!g_str_equal(encryptfmt, "aes")) { | ||
92 | + error_setg(errp, "Unknown encryption format '%s', expected 'aes'", | ||
93 | + encryptfmt); | ||
94 | + ret = -EINVAL; | ||
95 | + goto exit; | ||
96 | + } | ||
97 | header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES); | ||
98 | } else { | ||
99 | header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE); | ||
100 | @@ -XXX,XX +XXX,XX @@ static QemuOptsList qcow_create_opts = { | ||
101 | { | ||
102 | .name = BLOCK_OPT_ENCRYPT, | ||
103 | .type = QEMU_OPT_BOOL, | ||
104 | - .help = "Encrypt the image", | ||
105 | - .def_value_str = "off" | ||
106 | + .help = "Encrypt the image with format 'aes'. (Deprecated " | ||
107 | + "in favor of " BLOCK_OPT_ENCRYPT_FORMAT "=aes)", | ||
108 | + }, | ||
109 | + { | ||
110 | + .name = BLOCK_OPT_ENCRYPT_FORMAT, | ||
111 | + .type = QEMU_OPT_STRING, | ||
112 | + .help = "Encrypt the image, format choices: 'aes'", | ||
113 | }, | ||
114 | { /* end of list */ } | ||
115 | } | ||
116 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
117 | index XXXXXXX..XXXXXXX 100644 | ||
118 | --- a/block/qcow2.c | ||
119 | +++ b/block/qcow2.c | ||
120 | @@ -XXX,XX +XXX,XX @@ static int qcow2_create2(const char *filename, int64_t total_size, | ||
121 | const char *backing_file, const char *backing_format, | ||
122 | int flags, size_t cluster_size, PreallocMode prealloc, | ||
123 | QemuOpts *opts, int version, int refcount_order, | ||
124 | - Error **errp) | ||
125 | + const char *encryptfmt, Error **errp) | ||
126 | { | 21 | { |
127 | int cluster_bits; | 22 | + FDCtrlISABus *isa = ISA_FDC(isadev); |
128 | QDict *options; | 23 | Aml *dev; |
129 | @@ -XXX,XX +XXX,XX @@ static int qcow2_create2(const char *filename, int64_t total_size, | 24 | Aml *crs; |
130 | .header_length = cpu_to_be32(sizeof(*header)), | 25 | int i; |
26 | @@ -XXX,XX +XXX,XX @@ static void fdc_isa_build_aml(ISADevice *isadev, Aml *scope) | ||
131 | }; | 27 | }; |
132 | 28 | ||
133 | - if (flags & BLOCK_FLAG_ENCRYPT) { | 29 | crs = aml_resource_template(); |
134 | + if (encryptfmt) { | 30 | - aml_append(crs, aml_io(AML_DECODE16, 0x03F2, 0x03F2, 0x00, 0x04)); |
135 | + if (!g_str_equal(encryptfmt, "aes")) { | 31 | - aml_append(crs, aml_io(AML_DECODE16, 0x03F7, 0x03F7, 0x00, 0x01)); |
136 | + error_setg(errp, "Unknown encryption format '%s', expected 'aes'", | 32 | - aml_append(crs, aml_irq_no_flags(6)); |
137 | + encryptfmt); | 33 | aml_append(crs, |
138 | + ret = -EINVAL; | 34 | - aml_dma(AML_COMPATIBILITY, AML_NOTBUSMASTER, AML_TRANSFER8, 2)); |
139 | + goto out; | 35 | + aml_io(AML_DECODE16, isa->iobase + 2, isa->iobase + 2, 0x00, 0x04)); |
140 | + } | 36 | + aml_append(crs, |
141 | header->crypt_method = cpu_to_be32(QCOW_CRYPT_AES); | 37 | + aml_io(AML_DECODE16, isa->iobase + 7, isa->iobase + 7, 0x00, 0x01)); |
142 | } else { | 38 | + aml_append(crs, aml_irq_no_flags(isa->irq)); |
143 | header->crypt_method = cpu_to_be32(QCOW_CRYPT_NONE); | 39 | + aml_append(crs, |
144 | @@ -XXX,XX +XXX,XX @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp) | 40 | + aml_dma(AML_COMPATIBILITY, AML_NOTBUSMASTER, AML_TRANSFER8, isa->dma)); |
145 | int version = 3; | 41 | |
146 | uint64_t refcount_bits = 16; | 42 | dev = aml_device("FDC0"); |
147 | int refcount_order; | 43 | aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0700"))); |
148 | + const char *encryptfmt = NULL; | ||
149 | Error *local_err = NULL; | ||
150 | int ret; | ||
151 | |||
152 | @@ -XXX,XX +XXX,XX @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp) | ||
153 | BDRV_SECTOR_SIZE); | ||
154 | backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE); | ||
155 | backing_fmt = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT); | ||
156 | - if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) { | ||
157 | - flags |= BLOCK_FLAG_ENCRYPT; | ||
158 | + encryptfmt = qemu_opt_get_del(opts, BLOCK_OPT_ENCRYPT_FORMAT); | ||
159 | + if (encryptfmt) { | ||
160 | + if (qemu_opt_get_del(opts, BLOCK_OPT_ENCRYPT)) { | ||
161 | + error_setg(errp, "Options " BLOCK_OPT_ENCRYPT " and " | ||
162 | + BLOCK_OPT_ENCRYPT_FORMAT " are mutually exclusive"); | ||
163 | + ret = -EINVAL; | ||
164 | + goto finish; | ||
165 | + } | ||
166 | + } else if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) { | ||
167 | + encryptfmt = "aes"; | ||
168 | } | ||
169 | cluster_size = qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE, | ||
170 | DEFAULT_CLUSTER_SIZE); | ||
171 | @@ -XXX,XX +XXX,XX @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp) | ||
172 | |||
173 | ret = qcow2_create2(filename, size, backing_file, backing_fmt, flags, | ||
174 | cluster_size, prealloc, opts, version, refcount_order, | ||
175 | - &local_err); | ||
176 | + encryptfmt, &local_err); | ||
177 | error_propagate(errp, local_err); | ||
178 | |||
179 | finish: | ||
180 | @@ -XXX,XX +XXX,XX @@ static QemuOptsList qcow2_create_opts = { | ||
181 | { | ||
182 | .name = BLOCK_OPT_ENCRYPT, | ||
183 | .type = QEMU_OPT_BOOL, | ||
184 | - .help = "Encrypt the image", | ||
185 | - .def_value_str = "off" | ||
186 | + .help = "Encrypt the image with format 'aes'. (Deprecated " | ||
187 | + "in favor of " BLOCK_OPT_ENCRYPT_FORMAT "=aes)", | ||
188 | + }, | ||
189 | + { | ||
190 | + .name = BLOCK_OPT_ENCRYPT_FORMAT, | ||
191 | + .type = QEMU_OPT_STRING, | ||
192 | + .help = "Encrypt the image, format choices: 'aes'", | ||
193 | }, | ||
194 | { | ||
195 | .name = BLOCK_OPT_CLUSTER_SIZE, | ||
196 | diff --git a/qemu-img.c b/qemu-img.c | ||
197 | index XXXXXXX..XXXXXXX 100644 | ||
198 | --- a/qemu-img.c | ||
199 | +++ b/qemu-img.c | ||
200 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
201 | if (s.compressed) { | ||
202 | bool encryption = | ||
203 | qemu_opt_get_bool(opts, BLOCK_OPT_ENCRYPT, false); | ||
204 | + const char *encryptfmt = | ||
205 | + qemu_opt_get(opts, BLOCK_OPT_ENCRYPT_FORMAT); | ||
206 | const char *preallocation = | ||
207 | qemu_opt_get(opts, BLOCK_OPT_PREALLOC); | ||
208 | |||
209 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
210 | goto out; | ||
211 | } | ||
212 | |||
213 | - if (encryption) { | ||
214 | + if (encryption || encryptfmt) { | ||
215 | error_report("Compression and encryption not supported at " | ||
216 | "the same time"); | ||
217 | ret = -1; | ||
218 | diff --git a/tests/qemu-iotests/049.out b/tests/qemu-iotests/049.out | ||
219 | index XXXXXXX..XXXXXXX 100644 | ||
220 | --- a/tests/qemu-iotests/049.out | ||
221 | +++ b/tests/qemu-iotests/049.out | ||
222 | @@ -XXX,XX +XXX,XX @@ QA output created by 049 | ||
223 | == 1. Traditional size parameter == | ||
224 | |||
225 | qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024 | ||
226 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
227 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
228 | |||
229 | qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024b | ||
230 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
231 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
232 | |||
233 | qemu-img create -f qcow2 TEST_DIR/t.qcow2 1k | ||
234 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
235 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
236 | |||
237 | qemu-img create -f qcow2 TEST_DIR/t.qcow2 1K | ||
238 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
239 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
240 | |||
241 | qemu-img create -f qcow2 TEST_DIR/t.qcow2 1M | ||
242 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1048576 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
243 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1048576 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
244 | |||
245 | qemu-img create -f qcow2 TEST_DIR/t.qcow2 1G | ||
246 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1073741824 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
247 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1073741824 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
248 | |||
249 | qemu-img create -f qcow2 TEST_DIR/t.qcow2 1T | ||
250 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1099511627776 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
251 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1099511627776 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
252 | |||
253 | qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024.0 | ||
254 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
255 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
256 | |||
257 | qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024.0b | ||
258 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
259 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
260 | |||
261 | qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5k | ||
262 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
263 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
264 | |||
265 | qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5K | ||
266 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
267 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
268 | |||
269 | qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5M | ||
270 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1572864 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
271 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1572864 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
272 | |||
273 | qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5G | ||
274 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1610612736 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
275 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1610612736 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
276 | |||
277 | qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5T | ||
278 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1649267441664 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
279 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1649267441664 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
280 | |||
281 | == 2. Specifying size via -o == | ||
282 | |||
283 | qemu-img create -f qcow2 -o size=1024 TEST_DIR/t.qcow2 | ||
284 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
285 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
286 | |||
287 | qemu-img create -f qcow2 -o size=1024b TEST_DIR/t.qcow2 | ||
288 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
289 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
290 | |||
291 | qemu-img create -f qcow2 -o size=1k TEST_DIR/t.qcow2 | ||
292 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
293 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
294 | |||
295 | qemu-img create -f qcow2 -o size=1K TEST_DIR/t.qcow2 | ||
296 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
297 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
298 | |||
299 | qemu-img create -f qcow2 -o size=1M TEST_DIR/t.qcow2 | ||
300 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1048576 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
301 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1048576 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
302 | |||
303 | qemu-img create -f qcow2 -o size=1G TEST_DIR/t.qcow2 | ||
304 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1073741824 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
305 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1073741824 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
306 | |||
307 | qemu-img create -f qcow2 -o size=1T TEST_DIR/t.qcow2 | ||
308 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1099511627776 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
309 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1099511627776 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
310 | |||
311 | qemu-img create -f qcow2 -o size=1024.0 TEST_DIR/t.qcow2 | ||
312 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
313 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
314 | |||
315 | qemu-img create -f qcow2 -o size=1024.0b TEST_DIR/t.qcow2 | ||
316 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
317 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
318 | |||
319 | qemu-img create -f qcow2 -o size=1.5k TEST_DIR/t.qcow2 | ||
320 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
321 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
322 | |||
323 | qemu-img create -f qcow2 -o size=1.5K TEST_DIR/t.qcow2 | ||
324 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
325 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
326 | |||
327 | qemu-img create -f qcow2 -o size=1.5M TEST_DIR/t.qcow2 | ||
328 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1572864 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
329 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1572864 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
330 | |||
331 | qemu-img create -f qcow2 -o size=1.5G TEST_DIR/t.qcow2 | ||
332 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1610612736 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
333 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1610612736 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
334 | |||
335 | qemu-img create -f qcow2 -o size=1.5T TEST_DIR/t.qcow2 | ||
336 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1649267441664 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
337 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1649267441664 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
338 | |||
339 | == 3. Invalid sizes == | ||
340 | |||
341 | @@ -XXX,XX +XXX,XX @@ qemu-img: TEST_DIR/t.qcow2: Invalid options for file format 'qcow2' | ||
342 | == Check correct interpretation of suffixes for cluster size == | ||
343 | |||
344 | qemu-img create -f qcow2 -o cluster_size=1024 TEST_DIR/t.qcow2 64M | ||
345 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=1024 lazy_refcounts=off refcount_bits=16 | ||
346 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16 | ||
347 | |||
348 | qemu-img create -f qcow2 -o cluster_size=1024b TEST_DIR/t.qcow2 64M | ||
349 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=1024 lazy_refcounts=off refcount_bits=16 | ||
350 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16 | ||
351 | |||
352 | qemu-img create -f qcow2 -o cluster_size=1k TEST_DIR/t.qcow2 64M | ||
353 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=1024 lazy_refcounts=off refcount_bits=16 | ||
354 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16 | ||
355 | |||
356 | qemu-img create -f qcow2 -o cluster_size=1K TEST_DIR/t.qcow2 64M | ||
357 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=1024 lazy_refcounts=off refcount_bits=16 | ||
358 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16 | ||
359 | |||
360 | qemu-img create -f qcow2 -o cluster_size=1M TEST_DIR/t.qcow2 64M | ||
361 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=1048576 lazy_refcounts=off refcount_bits=16 | ||
362 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1048576 lazy_refcounts=off refcount_bits=16 | ||
363 | |||
364 | qemu-img create -f qcow2 -o cluster_size=1024.0 TEST_DIR/t.qcow2 64M | ||
365 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=1024 lazy_refcounts=off refcount_bits=16 | ||
366 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16 | ||
367 | |||
368 | qemu-img create -f qcow2 -o cluster_size=1024.0b TEST_DIR/t.qcow2 64M | ||
369 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=1024 lazy_refcounts=off refcount_bits=16 | ||
370 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16 | ||
371 | |||
372 | qemu-img create -f qcow2 -o cluster_size=0.5k TEST_DIR/t.qcow2 64M | ||
373 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=512 lazy_refcounts=off refcount_bits=16 | ||
374 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=512 lazy_refcounts=off refcount_bits=16 | ||
375 | |||
376 | qemu-img create -f qcow2 -o cluster_size=0.5K TEST_DIR/t.qcow2 64M | ||
377 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=512 lazy_refcounts=off refcount_bits=16 | ||
378 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=512 lazy_refcounts=off refcount_bits=16 | ||
379 | |||
380 | qemu-img create -f qcow2 -o cluster_size=0.5M TEST_DIR/t.qcow2 64M | ||
381 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=524288 lazy_refcounts=off refcount_bits=16 | ||
382 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=524288 lazy_refcounts=off refcount_bits=16 | ||
383 | |||
384 | == Check compat level option == | ||
385 | |||
386 | qemu-img create -f qcow2 -o compat=0.10 TEST_DIR/t.qcow2 64M | ||
387 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.10 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
388 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.10 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
389 | |||
390 | qemu-img create -f qcow2 -o compat=1.1 TEST_DIR/t.qcow2 64M | ||
391 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=1.1 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
392 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=1.1 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
393 | |||
394 | qemu-img create -f qcow2 -o compat=0.42 TEST_DIR/t.qcow2 64M | ||
395 | qemu-img: TEST_DIR/t.qcow2: Invalid compatibility level: '0.42' | ||
396 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.42 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
397 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.42 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
398 | |||
399 | qemu-img create -f qcow2 -o compat=foobar TEST_DIR/t.qcow2 64M | ||
400 | qemu-img: TEST_DIR/t.qcow2: Invalid compatibility level: 'foobar' | ||
401 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=foobar encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
402 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=foobar cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
403 | |||
404 | == Check preallocation option == | ||
405 | |||
406 | qemu-img create -f qcow2 -o preallocation=off TEST_DIR/t.qcow2 64M | ||
407 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 preallocation=off lazy_refcounts=off refcount_bits=16 | ||
408 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=65536 preallocation=off lazy_refcounts=off refcount_bits=16 | ||
409 | |||
410 | qemu-img create -f qcow2 -o preallocation=metadata TEST_DIR/t.qcow2 64M | ||
411 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 preallocation=metadata lazy_refcounts=off refcount_bits=16 | ||
412 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=65536 preallocation=metadata lazy_refcounts=off refcount_bits=16 | ||
413 | |||
414 | qemu-img create -f qcow2 -o preallocation=1234 TEST_DIR/t.qcow2 64M | ||
415 | qemu-img: TEST_DIR/t.qcow2: invalid parameter value: 1234 | ||
416 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 preallocation=1234 lazy_refcounts=off refcount_bits=16 | ||
417 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=65536 preallocation=1234 lazy_refcounts=off refcount_bits=16 | ||
418 | |||
419 | == Check encryption option == | ||
420 | |||
421 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=on cluster_siz | ||
422 | == Check lazy_refcounts option (only with v3) == | ||
423 | |||
424 | qemu-img create -f qcow2 -o compat=1.1,lazy_refcounts=off TEST_DIR/t.qcow2 64M | ||
425 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=1.1 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
426 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=1.1 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
427 | |||
428 | qemu-img create -f qcow2 -o compat=1.1,lazy_refcounts=on TEST_DIR/t.qcow2 64M | ||
429 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=1.1 encryption=off cluster_size=65536 lazy_refcounts=on refcount_bits=16 | ||
430 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=1.1 cluster_size=65536 lazy_refcounts=on refcount_bits=16 | ||
431 | |||
432 | qemu-img create -f qcow2 -o compat=0.10,lazy_refcounts=off TEST_DIR/t.qcow2 64M | ||
433 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.10 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
434 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.10 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
435 | |||
436 | qemu-img create -f qcow2 -o compat=0.10,lazy_refcounts=on TEST_DIR/t.qcow2 64M | ||
437 | qemu-img: TEST_DIR/t.qcow2: Lazy refcounts only supported with compatibility level 1.1 and above (use compat=1.1 or greater) | ||
438 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.10 encryption=off cluster_size=65536 lazy_refcounts=on refcount_bits=16 | ||
439 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.10 cluster_size=65536 lazy_refcounts=on refcount_bits=16 | ||
440 | |||
441 | *** done | ||
442 | diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out | ||
443 | index XXXXXXX..XXXXXXX 100644 | ||
444 | --- a/tests/qemu-iotests/082.out | ||
445 | +++ b/tests/qemu-iotests/082.out | ||
446 | @@ -XXX,XX +XXX,XX @@ QA output created by 082 | ||
447 | === create: Options specified more than once === | ||
448 | |||
449 | Testing: create -f foo -f qcow2 TEST_DIR/t.qcow2 128M | ||
450 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
451 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
452 | image: TEST_DIR/t.IMGFMT | ||
453 | file format: IMGFMT | ||
454 | virtual size: 128M (134217728 bytes) | ||
455 | cluster_size: 65536 | ||
456 | |||
457 | Testing: create -f qcow2 -o cluster_size=4k -o lazy_refcounts=on TEST_DIR/t.qcow2 128M | ||
458 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 encryption=off cluster_size=4096 lazy_refcounts=on refcount_bits=16 | ||
459 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=4096 lazy_refcounts=on refcount_bits=16 | ||
460 | image: TEST_DIR/t.IMGFMT | ||
461 | file format: IMGFMT | ||
462 | virtual size: 128M (134217728 bytes) | ||
463 | @@ -XXX,XX +XXX,XX @@ Format specific information: | ||
464 | corrupt: false | ||
465 | |||
466 | Testing: create -f qcow2 -o cluster_size=4k -o lazy_refcounts=on -o cluster_size=8k TEST_DIR/t.qcow2 128M | ||
467 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 encryption=off cluster_size=8192 lazy_refcounts=on refcount_bits=16 | ||
468 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=8192 lazy_refcounts=on refcount_bits=16 | ||
469 | image: TEST_DIR/t.IMGFMT | ||
470 | file format: IMGFMT | ||
471 | virtual size: 128M (134217728 bytes) | ||
472 | @@ -XXX,XX +XXX,XX @@ Format specific information: | ||
473 | corrupt: false | ||
474 | |||
475 | Testing: create -f qcow2 -o cluster_size=4k,cluster_size=8k TEST_DIR/t.qcow2 128M | ||
476 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 encryption=off cluster_size=8192 lazy_refcounts=off refcount_bits=16 | ||
477 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=8192 lazy_refcounts=off refcount_bits=16 | ||
478 | image: TEST_DIR/t.IMGFMT | ||
479 | file format: IMGFMT | ||
480 | virtual size: 128M (134217728 bytes) | ||
481 | @@ -XXX,XX +XXX,XX @@ size Virtual disk size | ||
482 | compat Compatibility level (0.10 or 1.1) | ||
483 | backing_file File name of a base image | ||
484 | backing_fmt Image format of the base image | ||
485 | -encryption Encrypt the image | ||
486 | +encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
487 | +encrypt.format Encrypt the image, format choices: 'aes' | ||
488 | cluster_size qcow2 cluster size | ||
489 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
490 | lazy_refcounts Postpone refcount updates | ||
491 | @@ -XXX,XX +XXX,XX @@ size Virtual disk size | ||
492 | compat Compatibility level (0.10 or 1.1) | ||
493 | backing_file File name of a base image | ||
494 | backing_fmt Image format of the base image | ||
495 | -encryption Encrypt the image | ||
496 | +encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
497 | +encrypt.format Encrypt the image, format choices: 'aes' | ||
498 | cluster_size qcow2 cluster size | ||
499 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
500 | lazy_refcounts Postpone refcount updates | ||
501 | @@ -XXX,XX +XXX,XX @@ size Virtual disk size | ||
502 | compat Compatibility level (0.10 or 1.1) | ||
503 | backing_file File name of a base image | ||
504 | backing_fmt Image format of the base image | ||
505 | -encryption Encrypt the image | ||
506 | +encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
507 | +encrypt.format Encrypt the image, format choices: 'aes' | ||
508 | cluster_size qcow2 cluster size | ||
509 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
510 | lazy_refcounts Postpone refcount updates | ||
511 | @@ -XXX,XX +XXX,XX @@ size Virtual disk size | ||
512 | compat Compatibility level (0.10 or 1.1) | ||
513 | backing_file File name of a base image | ||
514 | backing_fmt Image format of the base image | ||
515 | -encryption Encrypt the image | ||
516 | +encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
517 | +encrypt.format Encrypt the image, format choices: 'aes' | ||
518 | cluster_size qcow2 cluster size | ||
519 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
520 | lazy_refcounts Postpone refcount updates | ||
521 | @@ -XXX,XX +XXX,XX @@ size Virtual disk size | ||
522 | compat Compatibility level (0.10 or 1.1) | ||
523 | backing_file File name of a base image | ||
524 | backing_fmt Image format of the base image | ||
525 | -encryption Encrypt the image | ||
526 | +encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
527 | +encrypt.format Encrypt the image, format choices: 'aes' | ||
528 | cluster_size qcow2 cluster size | ||
529 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
530 | lazy_refcounts Postpone refcount updates | ||
531 | @@ -XXX,XX +XXX,XX @@ size Virtual disk size | ||
532 | compat Compatibility level (0.10 or 1.1) | ||
533 | backing_file File name of a base image | ||
534 | backing_fmt Image format of the base image | ||
535 | -encryption Encrypt the image | ||
536 | +encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
537 | +encrypt.format Encrypt the image, format choices: 'aes' | ||
538 | cluster_size qcow2 cluster size | ||
539 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
540 | lazy_refcounts Postpone refcount updates | ||
541 | @@ -XXX,XX +XXX,XX @@ size Virtual disk size | ||
542 | compat Compatibility level (0.10 or 1.1) | ||
543 | backing_file File name of a base image | ||
544 | backing_fmt Image format of the base image | ||
545 | -encryption Encrypt the image | ||
546 | +encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
547 | +encrypt.format Encrypt the image, format choices: 'aes' | ||
548 | cluster_size qcow2 cluster size | ||
549 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
550 | lazy_refcounts Postpone refcount updates | ||
551 | @@ -XXX,XX +XXX,XX @@ size Virtual disk size | ||
552 | compat Compatibility level (0.10 or 1.1) | ||
553 | backing_file File name of a base image | ||
554 | backing_fmt Image format of the base image | ||
555 | -encryption Encrypt the image | ||
556 | +encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
557 | +encrypt.format Encrypt the image, format choices: 'aes' | ||
558 | cluster_size qcow2 cluster size | ||
559 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
560 | lazy_refcounts Postpone refcount updates | ||
561 | @@ -XXX,XX +XXX,XX @@ refcount_bits Width of a reference count entry in bits | ||
562 | nocow Turn off copy-on-write (valid only on btrfs) | ||
563 | |||
564 | Testing: create -f qcow2 -o backing_file=TEST_DIR/t.qcow2,,help TEST_DIR/t.qcow2 128M | ||
565 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2,,help encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
566 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2,,help cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
567 | |||
568 | Testing: create -f qcow2 -o backing_file=TEST_DIR/t.qcow2,,? TEST_DIR/t.qcow2 128M | ||
569 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2,,? encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
570 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2,,? cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
571 | |||
572 | Testing: create -f qcow2 -o backing_file=TEST_DIR/t.qcow2, -o help TEST_DIR/t.qcow2 128M | ||
573 | qemu-img: Invalid option list: backing_file=TEST_DIR/t.qcow2, | ||
574 | @@ -XXX,XX +XXX,XX @@ size Virtual disk size | ||
575 | compat Compatibility level (0.10 or 1.1) | ||
576 | backing_file File name of a base image | ||
577 | backing_fmt Image format of the base image | ||
578 | -encryption Encrypt the image | ||
579 | +encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
580 | +encrypt.format Encrypt the image, format choices: 'aes' | ||
581 | cluster_size qcow2 cluster size | ||
582 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
583 | lazy_refcounts Postpone refcount updates | ||
584 | @@ -XXX,XX +XXX,XX @@ size Virtual disk size | ||
585 | === convert: Options specified more than once === | ||
586 | |||
587 | Testing: create -f qcow2 TEST_DIR/t.qcow2 128M | ||
588 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
589 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
590 | |||
591 | Testing: convert -f foo -f qcow2 TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base | ||
592 | image: TEST_DIR/t.IMGFMT.base | ||
593 | @@ -XXX,XX +XXX,XX @@ size Virtual disk size | ||
594 | compat Compatibility level (0.10 or 1.1) | ||
595 | backing_file File name of a base image | ||
596 | backing_fmt Image format of the base image | ||
597 | -encryption Encrypt the image | ||
598 | +encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
599 | +encrypt.format Encrypt the image, format choices: 'aes' | ||
600 | cluster_size qcow2 cluster size | ||
601 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
602 | lazy_refcounts Postpone refcount updates | ||
603 | @@ -XXX,XX +XXX,XX @@ size Virtual disk size | ||
604 | compat Compatibility level (0.10 or 1.1) | ||
605 | backing_file File name of a base image | ||
606 | backing_fmt Image format of the base image | ||
607 | -encryption Encrypt the image | ||
608 | +encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
609 | +encrypt.format Encrypt the image, format choices: 'aes' | ||
610 | cluster_size qcow2 cluster size | ||
611 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
612 | lazy_refcounts Postpone refcount updates | ||
613 | @@ -XXX,XX +XXX,XX @@ size Virtual disk size | ||
614 | compat Compatibility level (0.10 or 1.1) | ||
615 | backing_file File name of a base image | ||
616 | backing_fmt Image format of the base image | ||
617 | -encryption Encrypt the image | ||
618 | +encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
619 | +encrypt.format Encrypt the image, format choices: 'aes' | ||
620 | cluster_size qcow2 cluster size | ||
621 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
622 | lazy_refcounts Postpone refcount updates | ||
623 | @@ -XXX,XX +XXX,XX @@ size Virtual disk size | ||
624 | compat Compatibility level (0.10 or 1.1) | ||
625 | backing_file File name of a base image | ||
626 | backing_fmt Image format of the base image | ||
627 | -encryption Encrypt the image | ||
628 | +encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
629 | +encrypt.format Encrypt the image, format choices: 'aes' | ||
630 | cluster_size qcow2 cluster size | ||
631 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
632 | lazy_refcounts Postpone refcount updates | ||
633 | @@ -XXX,XX +XXX,XX @@ size Virtual disk size | ||
634 | compat Compatibility level (0.10 or 1.1) | ||
635 | backing_file File name of a base image | ||
636 | backing_fmt Image format of the base image | ||
637 | -encryption Encrypt the image | ||
638 | +encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
639 | +encrypt.format Encrypt the image, format choices: 'aes' | ||
640 | cluster_size qcow2 cluster size | ||
641 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
642 | lazy_refcounts Postpone refcount updates | ||
643 | @@ -XXX,XX +XXX,XX @@ size Virtual disk size | ||
644 | compat Compatibility level (0.10 or 1.1) | ||
645 | backing_file File name of a base image | ||
646 | backing_fmt Image format of the base image | ||
647 | -encryption Encrypt the image | ||
648 | +encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
649 | +encrypt.format Encrypt the image, format choices: 'aes' | ||
650 | cluster_size qcow2 cluster size | ||
651 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
652 | lazy_refcounts Postpone refcount updates | ||
653 | @@ -XXX,XX +XXX,XX @@ size Virtual disk size | ||
654 | compat Compatibility level (0.10 or 1.1) | ||
655 | backing_file File name of a base image | ||
656 | backing_fmt Image format of the base image | ||
657 | -encryption Encrypt the image | ||
658 | +encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
659 | +encrypt.format Encrypt the image, format choices: 'aes' | ||
660 | cluster_size qcow2 cluster size | ||
661 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
662 | lazy_refcounts Postpone refcount updates | ||
663 | @@ -XXX,XX +XXX,XX @@ size Virtual disk size | ||
664 | compat Compatibility level (0.10 or 1.1) | ||
665 | backing_file File name of a base image | ||
666 | backing_fmt Image format of the base image | ||
667 | -encryption Encrypt the image | ||
668 | +encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
669 | +encrypt.format Encrypt the image, format choices: 'aes' | ||
670 | cluster_size qcow2 cluster size | ||
671 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
672 | lazy_refcounts Postpone refcount updates | ||
673 | @@ -XXX,XX +XXX,XX @@ size Virtual disk size | ||
674 | compat Compatibility level (0.10 or 1.1) | ||
675 | backing_file File name of a base image | ||
676 | backing_fmt Image format of the base image | ||
677 | -encryption Encrypt the image | ||
678 | +encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
679 | +encrypt.format Encrypt the image, format choices: 'aes' | ||
680 | cluster_size qcow2 cluster size | ||
681 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
682 | lazy_refcounts Postpone refcount updates | ||
683 | @@ -XXX,XX +XXX,XX @@ size Virtual disk size | ||
684 | compat Compatibility level (0.10 or 1.1) | ||
685 | backing_file File name of a base image | ||
686 | backing_fmt Image format of the base image | ||
687 | -encryption Encrypt the image | ||
688 | +encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
689 | +encrypt.format Encrypt the image, format choices: 'aes' | ||
690 | cluster_size qcow2 cluster size | ||
691 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
692 | lazy_refcounts Postpone refcount updates | ||
693 | @@ -XXX,XX +XXX,XX @@ size Virtual disk size | ||
694 | compat Compatibility level (0.10 or 1.1) | ||
695 | backing_file File name of a base image | ||
696 | backing_fmt Image format of the base image | ||
697 | -encryption Encrypt the image | ||
698 | +encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
699 | +encrypt.format Encrypt the image, format choices: 'aes' | ||
700 | cluster_size qcow2 cluster size | ||
701 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
702 | lazy_refcounts Postpone refcount updates | ||
703 | @@ -XXX,XX +XXX,XX @@ size Virtual disk size | ||
704 | compat Compatibility level (0.10 or 1.1) | ||
705 | backing_file File name of a base image | ||
706 | backing_fmt Image format of the base image | ||
707 | -encryption Encrypt the image | ||
708 | +encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
709 | +encrypt.format Encrypt the image, format choices: 'aes' | ||
710 | cluster_size qcow2 cluster size | ||
711 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
712 | lazy_refcounts Postpone refcount updates | ||
713 | @@ -XXX,XX +XXX,XX @@ size Virtual disk size | ||
714 | compat Compatibility level (0.10 or 1.1) | ||
715 | backing_file File name of a base image | ||
716 | backing_fmt Image format of the base image | ||
717 | -encryption Encrypt the image | ||
718 | +encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
719 | +encrypt.format Encrypt the image, format choices: 'aes' | ||
720 | cluster_size qcow2 cluster size | ||
721 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
722 | lazy_refcounts Postpone refcount updates | ||
723 | @@ -XXX,XX +XXX,XX @@ size Virtual disk size | ||
724 | compat Compatibility level (0.10 or 1.1) | ||
725 | backing_file File name of a base image | ||
726 | backing_fmt Image format of the base image | ||
727 | -encryption Encrypt the image | ||
728 | +encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
729 | +encrypt.format Encrypt the image, format choices: 'aes' | ||
730 | cluster_size qcow2 cluster size | ||
731 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
732 | lazy_refcounts Postpone refcount updates | ||
733 | @@ -XXX,XX +XXX,XX @@ size Virtual disk size | ||
734 | compat Compatibility level (0.10 or 1.1) | ||
735 | backing_file File name of a base image | ||
736 | backing_fmt Image format of the base image | ||
737 | -encryption Encrypt the image | ||
738 | +encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
739 | +encrypt.format Encrypt the image, format choices: 'aes' | ||
740 | cluster_size qcow2 cluster size | ||
741 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
742 | lazy_refcounts Postpone refcount updates | ||
743 | @@ -XXX,XX +XXX,XX @@ size Virtual disk size | ||
744 | compat Compatibility level (0.10 or 1.1) | ||
745 | backing_file File name of a base image | ||
746 | backing_fmt Image format of the base image | ||
747 | -encryption Encrypt the image | ||
748 | +encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
749 | +encrypt.format Encrypt the image, format choices: 'aes' | ||
750 | cluster_size qcow2 cluster size | ||
751 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
752 | lazy_refcounts Postpone refcount updates | ||
753 | @@ -XXX,XX +XXX,XX @@ size Virtual disk size | ||
754 | compat Compatibility level (0.10 or 1.1) | ||
755 | backing_file File name of a base image | ||
756 | backing_fmt Image format of the base image | ||
757 | -encryption Encrypt the image | ||
758 | +encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
759 | +encrypt.format Encrypt the image, format choices: 'aes' | ||
760 | cluster_size qcow2 cluster size | ||
761 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
762 | lazy_refcounts Postpone refcount updates | ||
763 | @@ -XXX,XX +XXX,XX @@ size Virtual disk size | ||
764 | compat Compatibility level (0.10 or 1.1) | ||
765 | backing_file File name of a base image | ||
766 | backing_fmt Image format of the base image | ||
767 | -encryption Encrypt the image | ||
768 | +encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
769 | +encrypt.format Encrypt the image, format choices: 'aes' | ||
770 | cluster_size qcow2 cluster size | ||
771 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
772 | lazy_refcounts Postpone refcount updates | ||
773 | diff --git a/tests/qemu-iotests/085.out b/tests/qemu-iotests/085.out | ||
774 | index XXXXXXX..XXXXXXX 100644 | ||
775 | --- a/tests/qemu-iotests/085.out | ||
776 | +++ b/tests/qemu-iotests/085.out | ||
777 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 | ||
778 | |||
779 | === Create a single snapshot on virtio0 === | ||
780 | |||
781 | -Formatting 'TEST_DIR/1-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2.1 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
782 | +Formatting 'TEST_DIR/1-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2.1 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
783 | {"return": {}} | ||
784 | |||
785 | === Invalid command - missing device and nodename === | ||
786 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/1-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file | ||
787 | |||
788 | === Create several transactional group snapshots === | ||
789 | |||
790 | -Formatting 'TEST_DIR/2-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/1-snapshot-v0.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
791 | -Formatting 'TEST_DIR/2-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2.2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
792 | +Formatting 'TEST_DIR/2-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/1-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
793 | +Formatting 'TEST_DIR/2-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2.2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
794 | {"return": {}} | ||
795 | -Formatting 'TEST_DIR/3-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/2-snapshot-v0.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
796 | -Formatting 'TEST_DIR/3-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/2-snapshot-v1.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
797 | +Formatting 'TEST_DIR/3-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/2-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
798 | +Formatting 'TEST_DIR/3-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/2-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
799 | {"return": {}} | ||
800 | -Formatting 'TEST_DIR/4-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/3-snapshot-v0.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
801 | -Formatting 'TEST_DIR/4-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/3-snapshot-v1.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
802 | +Formatting 'TEST_DIR/4-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/3-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
803 | +Formatting 'TEST_DIR/4-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/3-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
804 | {"return": {}} | ||
805 | -Formatting 'TEST_DIR/5-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/4-snapshot-v0.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
806 | -Formatting 'TEST_DIR/5-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/4-snapshot-v1.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
807 | +Formatting 'TEST_DIR/5-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/4-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
808 | +Formatting 'TEST_DIR/5-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/4-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
809 | {"return": {}} | ||
810 | -Formatting 'TEST_DIR/6-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/5-snapshot-v0.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
811 | -Formatting 'TEST_DIR/6-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/5-snapshot-v1.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
812 | +Formatting 'TEST_DIR/6-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/5-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
813 | +Formatting 'TEST_DIR/6-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/5-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
814 | {"return": {}} | ||
815 | -Formatting 'TEST_DIR/7-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/6-snapshot-v0.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
816 | -Formatting 'TEST_DIR/7-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/6-snapshot-v1.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
817 | +Formatting 'TEST_DIR/7-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/6-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
818 | +Formatting 'TEST_DIR/7-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/6-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
819 | {"return": {}} | ||
820 | -Formatting 'TEST_DIR/8-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/7-snapshot-v0.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
821 | -Formatting 'TEST_DIR/8-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/7-snapshot-v1.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
822 | +Formatting 'TEST_DIR/8-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/7-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
823 | +Formatting 'TEST_DIR/8-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/7-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
824 | {"return": {}} | ||
825 | -Formatting 'TEST_DIR/9-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/8-snapshot-v0.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
826 | -Formatting 'TEST_DIR/9-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/8-snapshot-v1.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
827 | +Formatting 'TEST_DIR/9-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/8-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
828 | +Formatting 'TEST_DIR/9-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/8-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
829 | {"return": {}} | ||
830 | -Formatting 'TEST_DIR/10-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/9-snapshot-v0.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
831 | -Formatting 'TEST_DIR/10-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/9-snapshot-v1.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
832 | +Formatting 'TEST_DIR/10-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/9-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
833 | +Formatting 'TEST_DIR/10-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/9-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
834 | {"return": {}} | ||
835 | |||
836 | === Create a couple of snapshots using blockdev-snapshot === | ||
837 | diff --git a/tests/qemu-iotests/144.out b/tests/qemu-iotests/144.out | ||
838 | index XXXXXXX..XXXXXXX 100644 | ||
839 | --- a/tests/qemu-iotests/144.out | ||
840 | +++ b/tests/qemu-iotests/144.out | ||
841 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=536870912 | ||
842 | === Performing Live Snapshot 1 === | ||
843 | |||
844 | {"return": {}} | ||
845 | -Formatting 'TEST_DIR/tmp.qcow2', fmt=qcow2 size=536870912 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
846 | +Formatting 'TEST_DIR/tmp.qcow2', fmt=qcow2 size=536870912 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
847 | {"return": {}} | ||
848 | |||
849 | === Performing block-commit on active layer === | ||
850 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/tmp.qcow2', fmt=qcow2 size=536870912 backing_file=TEST_DIR/ | ||
851 | |||
852 | === Performing Live Snapshot 2 === | ||
853 | |||
854 | -Formatting 'TEST_DIR/tmp2.qcow2', fmt=qcow2 size=536870912 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
855 | +Formatting 'TEST_DIR/tmp2.qcow2', fmt=qcow2 size=536870912 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
856 | {"return": {}} | ||
857 | *** done | ||
858 | diff --git a/tests/qemu-iotests/185.out b/tests/qemu-iotests/185.out | ||
859 | index XXXXXXX..XXXXXXX 100644 | ||
860 | --- a/tests/qemu-iotests/185.out | ||
861 | +++ b/tests/qemu-iotests/185.out | ||
862 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864 | ||
863 | |||
864 | === Creating backing chain === | ||
865 | |||
866 | -Formatting 'TEST_DIR/t.qcow2.mid', fmt=qcow2 size=67108864 backing_file=TEST_DIR/t.qcow2.base backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
867 | +Formatting 'TEST_DIR/t.qcow2.mid', fmt=qcow2 size=67108864 backing_file=TEST_DIR/t.qcow2.base backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
868 | {"return": {}} | ||
869 | wrote 4194304/4194304 bytes at offset 0 | ||
870 | 4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
871 | {"return": ""} | ||
872 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 backing_file=TEST_DIR/t.qcow2.mid backing_fmt=qcow2 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
873 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 backing_file=TEST_DIR/t.qcow2.mid backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
874 | {"return": {}} | ||
875 | |||
876 | === Start commit job and exit qemu === | ||
877 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 backing_file=TEST_DIR/t.q | ||
878 | === Start mirror job and exit qemu === | ||
879 | |||
880 | {"return": {}} | ||
881 | -Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
882 | +Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 size=67108864 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
883 | {"return": {}} | ||
884 | {"return": {}} | ||
885 | {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} | ||
886 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 size=67108864 encryption=off clust | ||
887 | === Start backup job and exit qemu === | ||
888 | |||
889 | {"return": {}} | ||
890 | -Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
891 | +Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 size=67108864 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
892 | {"return": {}} | ||
893 | {"return": {}} | ||
894 | {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} | ||
895 | -- | 44 | -- |
896 | 2.9.4 | 45 | 2.34.1 |
897 | 46 | ||
898 | 47 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | ||
2 | 1 | ||
3 | Instead of requiring separate input/output buffers for | ||
4 | encrypting data, change encrypt_sectors() to assume | ||
5 | use of a single buffer, encrypting in place. One current | ||
6 | caller uses the same buffer for input/output already | ||
7 | and the other two callers are easily converted to do so. | ||
8 | |||
9 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
10 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
11 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
12 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> | ||
13 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
14 | Message-id: 20170623162419.26068-9-berrange@redhat.com | ||
15 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
16 | --- | ||
17 | block/qcow.c | 45 +++++++++++++++------------------------------ | ||
18 | 1 file changed, 15 insertions(+), 30 deletions(-) | ||
19 | |||
20 | diff --git a/block/qcow.c b/block/qcow.c | ||
21 | index XXXXXXX..XXXXXXX 100644 | ||
22 | --- a/block/qcow.c | ||
23 | +++ b/block/qcow.c | ||
24 | @@ -XXX,XX +XXX,XX @@ static int qcow_set_key(BlockDriverState *bs, const char *key) | ||
25 | } | ||
26 | |||
27 | /* The crypt function is compatible with the linux cryptoloop | ||
28 | - algorithm for < 4 GB images. NOTE: out_buf == in_buf is | ||
29 | - supported */ | ||
30 | + algorithm for < 4 GB images. */ | ||
31 | static int encrypt_sectors(BDRVQcowState *s, int64_t sector_num, | ||
32 | - uint8_t *out_buf, const uint8_t *in_buf, | ||
33 | - int nb_sectors, bool enc, Error **errp) | ||
34 | + uint8_t *buf, int nb_sectors, bool enc, | ||
35 | + Error **errp) | ||
36 | { | ||
37 | union { | ||
38 | uint64_t ll[2]; | ||
39 | @@ -XXX,XX +XXX,XX @@ static int encrypt_sectors(BDRVQcowState *s, int64_t sector_num, | ||
40 | } | ||
41 | if (enc) { | ||
42 | ret = qcrypto_cipher_encrypt(s->cipher, | ||
43 | - in_buf, | ||
44 | - out_buf, | ||
45 | + buf, buf, | ||
46 | 512, | ||
47 | errp); | ||
48 | } else { | ||
49 | ret = qcrypto_cipher_decrypt(s->cipher, | ||
50 | - in_buf, | ||
51 | - out_buf, | ||
52 | + buf, buf, | ||
53 | 512, | ||
54 | errp); | ||
55 | } | ||
56 | @@ -XXX,XX +XXX,XX @@ static int encrypt_sectors(BDRVQcowState *s, int64_t sector_num, | ||
57 | return -1; | ||
58 | } | ||
59 | sector_num++; | ||
60 | - in_buf += 512; | ||
61 | - out_buf += 512; | ||
62 | + buf += 512; | ||
63 | } | ||
64 | return 0; | ||
65 | } | ||
66 | @@ -XXX,XX +XXX,XX @@ static uint64_t get_cluster_offset(BlockDriverState *bs, | ||
67 | uint64_t start_sect; | ||
68 | assert(s->cipher); | ||
69 | start_sect = (offset & ~(s->cluster_size - 1)) >> 9; | ||
70 | - memset(s->cluster_data + 512, 0x00, 512); | ||
71 | for(i = 0; i < s->cluster_sectors; i++) { | ||
72 | if (i < n_start || i >= n_end) { | ||
73 | Error *err = NULL; | ||
74 | + memset(s->cluster_data, 0x00, 512); | ||
75 | if (encrypt_sectors(s, start_sect + i, | ||
76 | - s->cluster_data, | ||
77 | - s->cluster_data + 512, 1, | ||
78 | + s->cluster_data, 1, | ||
79 | true, &err) < 0) { | ||
80 | error_free(err); | ||
81 | errno = EIO; | ||
82 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_readv(BlockDriverState *bs, int64_t sector_num, | ||
83 | } | ||
84 | if (bs->encrypted) { | ||
85 | assert(s->cipher); | ||
86 | - if (encrypt_sectors(s, sector_num, buf, buf, | ||
87 | + if (encrypt_sectors(s, sector_num, buf, | ||
88 | n, false, &err) < 0) { | ||
89 | goto fail; | ||
90 | } | ||
91 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_writev(BlockDriverState *bs, int64_t sector_num, | ||
92 | BDRVQcowState *s = bs->opaque; | ||
93 | int index_in_cluster; | ||
94 | uint64_t cluster_offset; | ||
95 | - const uint8_t *src_buf; | ||
96 | int ret = 0, n; | ||
97 | - uint8_t *cluster_data = NULL; | ||
98 | struct iovec hd_iov; | ||
99 | QEMUIOVector hd_qiov; | ||
100 | uint8_t *buf; | ||
101 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_writev(BlockDriverState *bs, int64_t sector_num, | ||
102 | |||
103 | s->cluster_cache_offset = -1; /* disable compressed cache */ | ||
104 | |||
105 | - if (qiov->niov > 1) { | ||
106 | + /* We must always copy the iov when encrypting, so we | ||
107 | + * don't modify the original data buffer during encryption */ | ||
108 | + if (bs->encrypted || qiov->niov > 1) { | ||
109 | buf = orig_buf = qemu_try_blockalign(bs, qiov->size); | ||
110 | if (buf == NULL) { | ||
111 | return -ENOMEM; | ||
112 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_writev(BlockDriverState *bs, int64_t sector_num, | ||
113 | if (bs->encrypted) { | ||
114 | Error *err = NULL; | ||
115 | assert(s->cipher); | ||
116 | - if (!cluster_data) { | ||
117 | - cluster_data = g_malloc0(s->cluster_size); | ||
118 | - } | ||
119 | - if (encrypt_sectors(s, sector_num, cluster_data, buf, | ||
120 | - n, true, &err) < 0) { | ||
121 | + if (encrypt_sectors(s, sector_num, buf, n, true, &err) < 0) { | ||
122 | error_free(err); | ||
123 | ret = -EIO; | ||
124 | break; | ||
125 | } | ||
126 | - src_buf = cluster_data; | ||
127 | - } else { | ||
128 | - src_buf = buf; | ||
129 | } | ||
130 | |||
131 | - hd_iov.iov_base = (void *)src_buf; | ||
132 | + hd_iov.iov_base = (void *)buf; | ||
133 | hd_iov.iov_len = n * 512; | ||
134 | qemu_iovec_init_external(&hd_qiov, &hd_iov, 1); | ||
135 | qemu_co_mutex_unlock(&s->lock); | ||
136 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_writev(BlockDriverState *bs, int64_t sector_num, | ||
137 | } | ||
138 | qemu_co_mutex_unlock(&s->lock); | ||
139 | |||
140 | - if (qiov->niov > 1) { | ||
141 | - qemu_vfree(orig_buf); | ||
142 | - } | ||
143 | - g_free(cluster_data); | ||
144 | + qemu_vfree(orig_buf); | ||
145 | |||
146 | return ret; | ||
147 | } | ||
148 | -- | ||
149 | 2.9.4 | ||
150 | |||
151 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | ||
2 | 1 | ||
3 | This converts the qcow driver to make use of the QCryptoBlock | ||
4 | APIs for encrypting image content. This is only wired up to | ||
5 | permit use of the legacy QCow encryption format. Users who wish | ||
6 | to have the strong LUKS format should switch to qcow2 instead. | ||
7 | |||
8 | With this change it is now required to use the QCryptoSecret | ||
9 | object for providing passwords, instead of the current block | ||
10 | password APIs / interactive prompting. | ||
11 | |||
12 | $QEMU \ | ||
13 | -object secret,id=sec0,file=/home/berrange/encrypted.pw \ | ||
14 | -drive file=/home/berrange/encrypted.qcow,encrypt.format=aes,\ | ||
15 | encrypt.key-secret=sec0 | ||
16 | |||
17 | Though note that running QEMU system emulators with the AES | ||
18 | encryption is no longer supported, so while the above syntax | ||
19 | is valid, QEMU will refuse to actually run the VM in this | ||
20 | particular example. | ||
21 | |||
22 | Likewise when creating images with the legacy AES-CBC format | ||
23 | |||
24 | qemu-img create -f qcow \ | ||
25 | --object secret,id=sec0,file=/home/berrange/encrypted.pw \ | ||
26 | -o encrypt.format=aes,encrypt.key-secret=sec0 \ | ||
27 | /home/berrange/encrypted.qcow 64M | ||
28 | |||
29 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
30 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
31 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
32 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
33 | Message-id: 20170623162419.26068-10-berrange@redhat.com | ||
34 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
35 | --- | ||
36 | qapi/block-core.json | 38 +++++++++- | ||
37 | block/crypto.h | 20 ++++-- | ||
38 | block/crypto.c | 10 +++ | ||
39 | block/qcow.c | 198 +++++++++++++++++++++++++-------------------------- | ||
40 | 4 files changed, 158 insertions(+), 108 deletions(-) | ||
41 | |||
42 | diff --git a/qapi/block-core.json b/qapi/block-core.json | ||
43 | index XXXXXXX..XXXXXXX 100644 | ||
44 | --- a/qapi/block-core.json | ||
45 | +++ b/qapi/block-core.json | ||
46 | @@ -XXX,XX +XXX,XX @@ | ||
47 | 'mode': 'Qcow2OverlapCheckMode' } } | ||
48 | |||
49 | ## | ||
50 | +# @BlockdevQcowEncryptionFormat: | ||
51 | +# | ||
52 | +# @aes: AES-CBC with plain64 initialization vectors | ||
53 | +# | ||
54 | +# Since: 2.10 | ||
55 | +## | ||
56 | +{ 'enum': 'BlockdevQcowEncryptionFormat', | ||
57 | + 'data': [ 'aes' ] } | ||
58 | + | ||
59 | +## | ||
60 | +# @BlockdevQcowEncryption: | ||
61 | +# | ||
62 | +# Since: 2.10 | ||
63 | +## | ||
64 | +{ 'union': 'BlockdevQcowEncryption', | ||
65 | + 'base': { 'format': 'BlockdevQcowEncryptionFormat' }, | ||
66 | + 'discriminator': 'format', | ||
67 | + 'data': { 'aes': 'QCryptoBlockOptionsQCow' } } | ||
68 | + | ||
69 | +## | ||
70 | +# @BlockdevOptionsQcow: | ||
71 | +# | ||
72 | +# Driver specific block device options for qcow. | ||
73 | +# | ||
74 | +# @encrypt: Image decryption options. Mandatory for | ||
75 | +# encrypted images, except when doing a metadata-only | ||
76 | +# probe of the image. | ||
77 | +# | ||
78 | +# Since: 2.10 | ||
79 | +## | ||
80 | +{ 'struct': 'BlockdevOptionsQcow', | ||
81 | + 'base': 'BlockdevOptionsGenericCOWFormat', | ||
82 | + 'data': { '*encrypt': 'BlockdevQcowEncryption' } } | ||
83 | + | ||
84 | + | ||
85 | +## | ||
86 | # @BlockdevOptionsQcow2: | ||
87 | # | ||
88 | # Driver specific block device options for qcow2. | ||
89 | @@ -XXX,XX +XXX,XX @@ | ||
90 | 'null-co': 'BlockdevOptionsNull', | ||
91 | 'parallels': 'BlockdevOptionsGenericFormat', | ||
92 | 'qcow2': 'BlockdevOptionsQcow2', | ||
93 | - 'qcow': 'BlockdevOptionsGenericCOWFormat', | ||
94 | + 'qcow': 'BlockdevOptionsQcow', | ||
95 | 'qed': 'BlockdevOptionsGenericCOWFormat', | ||
96 | 'quorum': 'BlockdevOptionsQuorum', | ||
97 | 'raw': 'BlockdevOptionsRaw', | ||
98 | diff --git a/block/crypto.h b/block/crypto.h | ||
99 | index XXXXXXX..XXXXXXX 100644 | ||
100 | --- a/block/crypto.h | ||
101 | +++ b/block/crypto.h | ||
102 | @@ -XXX,XX +XXX,XX @@ | ||
103 | #ifndef BLOCK_CRYPTO_H__ | ||
104 | #define BLOCK_CRYPTO_H__ | ||
105 | |||
106 | +#define BLOCK_CRYPTO_OPT_DEF_KEY_SECRET(prefix, helpstr) \ | ||
107 | + { \ | ||
108 | + .name = prefix BLOCK_CRYPTO_OPT_QCOW_KEY_SECRET, \ | ||
109 | + .type = QEMU_OPT_STRING, \ | ||
110 | + .help = helpstr, \ | ||
111 | + } | ||
112 | + | ||
113 | +#define BLOCK_CRYPTO_OPT_QCOW_KEY_SECRET "key-secret" | ||
114 | + | ||
115 | +#define BLOCK_CRYPTO_OPT_DEF_QCOW_KEY_SECRET(prefix) \ | ||
116 | + BLOCK_CRYPTO_OPT_DEF_KEY_SECRET(prefix, \ | ||
117 | + "ID of the secret that provides the AES encryption key") | ||
118 | + | ||
119 | #define BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET "key-secret" | ||
120 | #define BLOCK_CRYPTO_OPT_LUKS_CIPHER_ALG "cipher-alg" | ||
121 | #define BLOCK_CRYPTO_OPT_LUKS_CIPHER_MODE "cipher-mode" | ||
122 | @@ -XXX,XX +XXX,XX @@ | ||
123 | #define BLOCK_CRYPTO_OPT_LUKS_ITER_TIME "iter-time" | ||
124 | |||
125 | #define BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(prefix) \ | ||
126 | - { \ | ||
127 | - .name = prefix BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET, \ | ||
128 | - .type = QEMU_OPT_STRING, \ | ||
129 | - .help = "ID of the secret that provides the keyslot passphrase", \ | ||
130 | - } | ||
131 | + BLOCK_CRYPTO_OPT_DEF_KEY_SECRET(prefix, \ | ||
132 | + "ID of the secret that provides the keyslot passphrase") | ||
133 | |||
134 | #define BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG(prefix) \ | ||
135 | { \ | ||
136 | diff --git a/block/crypto.c b/block/crypto.c | ||
137 | index XXXXXXX..XXXXXXX 100644 | ||
138 | --- a/block/crypto.c | ||
139 | +++ b/block/crypto.c | ||
140 | @@ -XXX,XX +XXX,XX @@ block_crypto_open_opts_init(QCryptoBlockFormat format, | ||
141 | v, &ret->u.luks, &local_err); | ||
142 | break; | ||
143 | |||
144 | + case Q_CRYPTO_BLOCK_FORMAT_QCOW: | ||
145 | + visit_type_QCryptoBlockOptionsQCow_members( | ||
146 | + v, &ret->u.qcow, &local_err); | ||
147 | + break; | ||
148 | + | ||
149 | default: | ||
150 | error_setg(&local_err, "Unsupported block format %d", format); | ||
151 | break; | ||
152 | @@ -XXX,XX +XXX,XX @@ block_crypto_create_opts_init(QCryptoBlockFormat format, | ||
153 | v, &ret->u.luks, &local_err); | ||
154 | break; | ||
155 | |||
156 | + case Q_CRYPTO_BLOCK_FORMAT_QCOW: | ||
157 | + visit_type_QCryptoBlockOptionsQCow_members( | ||
158 | + v, &ret->u.qcow, &local_err); | ||
159 | + break; | ||
160 | + | ||
161 | default: | ||
162 | error_setg(&local_err, "Unsupported block format %d", format); | ||
163 | break; | ||
164 | diff --git a/block/qcow.c b/block/qcow.c | ||
165 | index XXXXXXX..XXXXXXX 100644 | ||
166 | --- a/block/qcow.c | ||
167 | +++ b/block/qcow.c | ||
168 | @@ -XXX,XX +XXX,XX @@ | ||
169 | #include "qemu/bswap.h" | ||
170 | #include <zlib.h> | ||
171 | #include "qapi/qmp/qerror.h" | ||
172 | -#include "crypto/cipher.h" | ||
173 | +#include "qapi/qmp/qstring.h" | ||
174 | +#include "crypto/block.h" | ||
175 | #include "migration/blocker.h" | ||
176 | +#include "block/crypto.h" | ||
177 | |||
178 | /**************************************************************/ | ||
179 | /* QEMU COW block driver with compression and encryption support */ | ||
180 | @@ -XXX,XX +XXX,XX @@ typedef struct BDRVQcowState { | ||
181 | uint8_t *cluster_cache; | ||
182 | uint8_t *cluster_data; | ||
183 | uint64_t cluster_cache_offset; | ||
184 | - QCryptoCipher *cipher; /* NULL if no key yet */ | ||
185 | + QCryptoBlock *crypto; /* Disk encryption format driver */ | ||
186 | uint32_t crypt_method_header; | ||
187 | CoMutex lock; | ||
188 | Error *migration_blocker; | ||
189 | @@ -XXX,XX +XXX,XX @@ static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename) | ||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | +static QemuOptsList qcow_runtime_opts = { | ||
194 | + .name = "qcow", | ||
195 | + .head = QTAILQ_HEAD_INITIALIZER(qcow_runtime_opts.head), | ||
196 | + .desc = { | ||
197 | + BLOCK_CRYPTO_OPT_DEF_QCOW_KEY_SECRET("encrypt."), | ||
198 | + { /* end of list */ } | ||
199 | + }, | ||
200 | +}; | ||
201 | + | ||
202 | static int qcow_open(BlockDriverState *bs, QDict *options, int flags, | ||
203 | Error **errp) | ||
204 | { | ||
205 | @@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags, | ||
206 | int ret; | ||
207 | QCowHeader header; | ||
208 | Error *local_err = NULL; | ||
209 | + QCryptoBlockOpenOptions *crypto_opts = NULL; | ||
210 | + unsigned int cflags = 0; | ||
211 | + QDict *encryptopts = NULL; | ||
212 | + const char *encryptfmt; | ||
213 | + | ||
214 | + qdict_extract_subqdict(options, &encryptopts, "encrypt."); | ||
215 | + encryptfmt = qdict_get_try_str(encryptopts, "format"); | ||
216 | |||
217 | bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, | ||
218 | false, errp); | ||
219 | if (!bs->file) { | ||
220 | - return -EINVAL; | ||
221 | + ret = -EINVAL; | ||
222 | + goto fail; | ||
223 | } | ||
224 | |||
225 | ret = bdrv_pread(bs->file, 0, &header, sizeof(header)); | ||
226 | @@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags, | ||
227 | goto fail; | ||
228 | } | ||
229 | |||
230 | - if (header.crypt_method > QCOW_CRYPT_AES) { | ||
231 | - error_setg(errp, "invalid encryption method in qcow header"); | ||
232 | - ret = -EINVAL; | ||
233 | - goto fail; | ||
234 | - } | ||
235 | - if (!qcrypto_cipher_supports(QCRYPTO_CIPHER_ALG_AES_128, | ||
236 | - QCRYPTO_CIPHER_MODE_CBC)) { | ||
237 | - error_setg(errp, "AES cipher not available"); | ||
238 | - ret = -EINVAL; | ||
239 | - goto fail; | ||
240 | - } | ||
241 | s->crypt_method_header = header.crypt_method; | ||
242 | if (s->crypt_method_header) { | ||
243 | if (bdrv_uses_whitelist() && | ||
244 | @@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags, | ||
245 | ret = -ENOSYS; | ||
246 | goto fail; | ||
247 | } | ||
248 | + if (s->crypt_method_header == QCOW_CRYPT_AES) { | ||
249 | + if (encryptfmt && !g_str_equal(encryptfmt, "aes")) { | ||
250 | + error_setg(errp, | ||
251 | + "Header reported 'aes' encryption format but " | ||
252 | + "options specify '%s'", encryptfmt); | ||
253 | + ret = -EINVAL; | ||
254 | + goto fail; | ||
255 | + } | ||
256 | + qdict_del(encryptopts, "format"); | ||
257 | + crypto_opts = block_crypto_open_opts_init( | ||
258 | + Q_CRYPTO_BLOCK_FORMAT_QCOW, encryptopts, errp); | ||
259 | + if (!crypto_opts) { | ||
260 | + ret = -EINVAL; | ||
261 | + goto fail; | ||
262 | + } | ||
263 | |||
264 | + if (flags & BDRV_O_NO_IO) { | ||
265 | + cflags |= QCRYPTO_BLOCK_OPEN_NO_IO; | ||
266 | + } | ||
267 | + s->crypto = qcrypto_block_open(crypto_opts, NULL, NULL, | ||
268 | + cflags, errp); | ||
269 | + if (!s->crypto) { | ||
270 | + ret = -EINVAL; | ||
271 | + goto fail; | ||
272 | + } | ||
273 | + } else { | ||
274 | + error_setg(errp, "invalid encryption method in qcow header"); | ||
275 | + ret = -EINVAL; | ||
276 | + goto fail; | ||
277 | + } | ||
278 | bs->encrypted = true; | ||
279 | + bs->valid_key = true; | ||
280 | } | ||
281 | s->cluster_bits = header.cluster_bits; | ||
282 | s->cluster_size = 1 << s->cluster_bits; | ||
283 | @@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags, | ||
284 | goto fail; | ||
285 | } | ||
286 | |||
287 | + QDECREF(encryptopts); | ||
288 | + qapi_free_QCryptoBlockOpenOptions(crypto_opts); | ||
289 | qemu_co_mutex_init(&s->lock); | ||
290 | return 0; | ||
291 | |||
292 | @@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags, | ||
293 | qemu_vfree(s->l2_cache); | ||
294 | g_free(s->cluster_cache); | ||
295 | g_free(s->cluster_data); | ||
296 | + qcrypto_block_free(s->crypto); | ||
297 | + QDECREF(encryptopts); | ||
298 | + qapi_free_QCryptoBlockOpenOptions(crypto_opts); | ||
299 | return ret; | ||
300 | } | ||
301 | |||
302 | @@ -XXX,XX +XXX,XX @@ static int qcow_reopen_prepare(BDRVReopenState *state, | ||
303 | return 0; | ||
304 | } | ||
305 | |||
306 | -static int qcow_set_key(BlockDriverState *bs, const char *key) | ||
307 | -{ | ||
308 | - BDRVQcowState *s = bs->opaque; | ||
309 | - uint8_t keybuf[16]; | ||
310 | - int len, i; | ||
311 | - Error *err; | ||
312 | - | ||
313 | - memset(keybuf, 0, 16); | ||
314 | - len = strlen(key); | ||
315 | - if (len > 16) | ||
316 | - len = 16; | ||
317 | - /* XXX: we could compress the chars to 7 bits to increase | ||
318 | - entropy */ | ||
319 | - for(i = 0;i < len;i++) { | ||
320 | - keybuf[i] = key[i]; | ||
321 | - } | ||
322 | - assert(bs->encrypted); | ||
323 | - | ||
324 | - qcrypto_cipher_free(s->cipher); | ||
325 | - s->cipher = qcrypto_cipher_new( | ||
326 | - QCRYPTO_CIPHER_ALG_AES_128, | ||
327 | - QCRYPTO_CIPHER_MODE_CBC, | ||
328 | - keybuf, G_N_ELEMENTS(keybuf), | ||
329 | - &err); | ||
330 | - | ||
331 | - if (!s->cipher) { | ||
332 | - /* XXX would be nice if errors in this method could | ||
333 | - * be properly propagate to the caller. Would need | ||
334 | - * the bdrv_set_key() API signature to be fixed. */ | ||
335 | - error_free(err); | ||
336 | - return -1; | ||
337 | - } | ||
338 | - return 0; | ||
339 | -} | ||
340 | - | ||
341 | -/* The crypt function is compatible with the linux cryptoloop | ||
342 | - algorithm for < 4 GB images. */ | ||
343 | -static int encrypt_sectors(BDRVQcowState *s, int64_t sector_num, | ||
344 | - uint8_t *buf, int nb_sectors, bool enc, | ||
345 | - Error **errp) | ||
346 | -{ | ||
347 | - union { | ||
348 | - uint64_t ll[2]; | ||
349 | - uint8_t b[16]; | ||
350 | - } ivec; | ||
351 | - int i; | ||
352 | - int ret; | ||
353 | - | ||
354 | - for(i = 0; i < nb_sectors; i++) { | ||
355 | - ivec.ll[0] = cpu_to_le64(sector_num); | ||
356 | - ivec.ll[1] = 0; | ||
357 | - if (qcrypto_cipher_setiv(s->cipher, | ||
358 | - ivec.b, G_N_ELEMENTS(ivec.b), | ||
359 | - errp) < 0) { | ||
360 | - return -1; | ||
361 | - } | ||
362 | - if (enc) { | ||
363 | - ret = qcrypto_cipher_encrypt(s->cipher, | ||
364 | - buf, buf, | ||
365 | - 512, | ||
366 | - errp); | ||
367 | - } else { | ||
368 | - ret = qcrypto_cipher_decrypt(s->cipher, | ||
369 | - buf, buf, | ||
370 | - 512, | ||
371 | - errp); | ||
372 | - } | ||
373 | - if (ret < 0) { | ||
374 | - return -1; | ||
375 | - } | ||
376 | - sector_num++; | ||
377 | - buf += 512; | ||
378 | - } | ||
379 | - return 0; | ||
380 | -} | ||
381 | |||
382 | /* 'allocate' is: | ||
383 | * | ||
384 | @@ -XXX,XX +XXX,XX @@ static uint64_t get_cluster_offset(BlockDriverState *bs, | ||
385 | if (bs->encrypted && | ||
386 | (n_end - n_start) < s->cluster_sectors) { | ||
387 | uint64_t start_sect; | ||
388 | - assert(s->cipher); | ||
389 | + assert(s->crypto); | ||
390 | start_sect = (offset & ~(s->cluster_size - 1)) >> 9; | ||
391 | for(i = 0; i < s->cluster_sectors; i++) { | ||
392 | if (i < n_start || i >= n_end) { | ||
393 | Error *err = NULL; | ||
394 | memset(s->cluster_data, 0x00, 512); | ||
395 | - if (encrypt_sectors(s, start_sect + i, | ||
396 | - s->cluster_data, 1, | ||
397 | - true, &err) < 0) { | ||
398 | + if (qcrypto_block_encrypt(s->crypto, start_sect + i, | ||
399 | + s->cluster_data, | ||
400 | + BDRV_SECTOR_SIZE, | ||
401 | + &err) < 0) { | ||
402 | error_free(err); | ||
403 | errno = EIO; | ||
404 | return -1; | ||
405 | @@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn qcow_co_get_block_status(BlockDriverState *bs, | ||
406 | if (!cluster_offset) { | ||
407 | return 0; | ||
408 | } | ||
409 | - if ((cluster_offset & QCOW_OFLAG_COMPRESSED) || s->cipher) { | ||
410 | + if ((cluster_offset & QCOW_OFLAG_COMPRESSED) || s->crypto) { | ||
411 | return BDRV_BLOCK_DATA; | ||
412 | } | ||
413 | cluster_offset |= (index_in_cluster << BDRV_SECTOR_BITS); | ||
414 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_readv(BlockDriverState *bs, int64_t sector_num, | ||
415 | break; | ||
416 | } | ||
417 | if (bs->encrypted) { | ||
418 | - assert(s->cipher); | ||
419 | - if (encrypt_sectors(s, sector_num, buf, | ||
420 | - n, false, &err) < 0) { | ||
421 | + assert(s->crypto); | ||
422 | + if (qcrypto_block_decrypt(s->crypto, sector_num, buf, | ||
423 | + n * BDRV_SECTOR_SIZE, &err) < 0) { | ||
424 | goto fail; | ||
425 | } | ||
426 | } | ||
427 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_writev(BlockDriverState *bs, int64_t sector_num, | ||
428 | } | ||
429 | if (bs->encrypted) { | ||
430 | Error *err = NULL; | ||
431 | - assert(s->cipher); | ||
432 | - if (encrypt_sectors(s, sector_num, buf, n, true, &err) < 0) { | ||
433 | + assert(s->crypto); | ||
434 | + if (qcrypto_block_encrypt(s->crypto, sector_num, buf, | ||
435 | + n * BDRV_SECTOR_SIZE, &err) < 0) { | ||
436 | error_free(err); | ||
437 | ret = -EIO; | ||
438 | break; | ||
439 | @@ -XXX,XX +XXX,XX @@ static void qcow_close(BlockDriverState *bs) | ||
440 | { | ||
441 | BDRVQcowState *s = bs->opaque; | ||
442 | |||
443 | - qcrypto_cipher_free(s->cipher); | ||
444 | - s->cipher = NULL; | ||
445 | + qcrypto_block_free(s->crypto); | ||
446 | + s->crypto = NULL; | ||
447 | g_free(s->l1_table); | ||
448 | qemu_vfree(s->l2_cache); | ||
449 | g_free(s->cluster_cache); | ||
450 | @@ -XXX,XX +XXX,XX @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp) | ||
451 | int ret; | ||
452 | BlockBackend *qcow_blk; | ||
453 | const char *encryptfmt = NULL; | ||
454 | + QDict *options; | ||
455 | + QDict *encryptopts = NULL; | ||
456 | + QCryptoBlockCreateOptions *crypto_opts = NULL; | ||
457 | + QCryptoBlock *crypto = NULL; | ||
458 | |||
459 | /* Read out options */ | ||
460 | total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0), | ||
461 | @@ -XXX,XX +XXX,XX @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp) | ||
462 | l1_size = (total_size + (1LL << shift) - 1) >> shift; | ||
463 | |||
464 | header.l1_table_offset = cpu_to_be64(header_size); | ||
465 | + | ||
466 | + options = qemu_opts_to_qdict(opts, NULL); | ||
467 | + qdict_extract_subqdict(options, &encryptopts, "encrypt."); | ||
468 | + QDECREF(options); | ||
469 | if (encryptfmt) { | ||
470 | if (!g_str_equal(encryptfmt, "aes")) { | ||
471 | error_setg(errp, "Unknown encryption format '%s', expected 'aes'", | ||
472 | @@ -XXX,XX +XXX,XX @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp) | ||
473 | goto exit; | ||
474 | } | ||
475 | header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES); | ||
476 | + | ||
477 | + crypto_opts = block_crypto_create_opts_init( | ||
478 | + Q_CRYPTO_BLOCK_FORMAT_QCOW, encryptopts, errp); | ||
479 | + if (!crypto_opts) { | ||
480 | + ret = -EINVAL; | ||
481 | + goto exit; | ||
482 | + } | ||
483 | + | ||
484 | + crypto = qcrypto_block_create(crypto_opts, NULL, NULL, NULL, errp); | ||
485 | + if (!crypto) { | ||
486 | + ret = -EINVAL; | ||
487 | + goto exit; | ||
488 | + } | ||
489 | } else { | ||
490 | header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE); | ||
491 | } | ||
492 | @@ -XXX,XX +XXX,XX @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp) | ||
493 | exit: | ||
494 | blk_unref(qcow_blk); | ||
495 | cleanup: | ||
496 | + QDECREF(encryptopts); | ||
497 | + qcrypto_block_free(crypto); | ||
498 | + qapi_free_QCryptoBlockCreateOptions(crypto_opts); | ||
499 | g_free(backing_file); | ||
500 | return ret; | ||
501 | } | ||
502 | @@ -XXX,XX +XXX,XX @@ static QemuOptsList qcow_create_opts = { | ||
503 | .type = QEMU_OPT_STRING, | ||
504 | .help = "Encrypt the image, format choices: 'aes'", | ||
505 | }, | ||
506 | + BLOCK_CRYPTO_OPT_DEF_QCOW_KEY_SECRET("encrypt."), | ||
507 | { /* end of list */ } | ||
508 | } | ||
509 | }; | ||
510 | @@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_qcow = { | ||
511 | .bdrv_co_writev = qcow_co_writev, | ||
512 | .bdrv_co_get_block_status = qcow_co_get_block_status, | ||
513 | |||
514 | - .bdrv_set_key = qcow_set_key, | ||
515 | .bdrv_make_empty = qcow_make_empty, | ||
516 | .bdrv_co_pwritev_compressed = qcow_co_pwritev_compressed, | ||
517 | .bdrv_get_info = qcow_get_info, | ||
518 | -- | ||
519 | 2.9.4 | ||
520 | |||
521 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | ||
2 | 1 | ||
3 | Instead of requiring separate input/output buffers for | ||
4 | encrypting data, change qcow2_encrypt_sectors() to assume | ||
5 | use of a single buffer, encrypting in place. The current | ||
6 | callers all used the same buffer for input/output already. | ||
7 | |||
8 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
9 | Message-id: 20170623162419.26068-11-berrange@redhat.com | ||
10 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
11 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
12 | --- | ||
13 | block/qcow2.h | 3 +-- | ||
14 | block/qcow2-cluster.c | 17 ++++++----------- | ||
15 | block/qcow2.c | 4 ++-- | ||
16 | 3 files changed, 9 insertions(+), 15 deletions(-) | ||
17 | |||
18 | diff --git a/block/qcow2.h b/block/qcow2.h | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/block/qcow2.h | ||
21 | +++ b/block/qcow2.h | ||
22 | @@ -XXX,XX +XXX,XX @@ int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size, | ||
23 | int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index); | ||
24 | int qcow2_decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset); | ||
25 | int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num, | ||
26 | - uint8_t *out_buf, const uint8_t *in_buf, | ||
27 | - int nb_sectors, bool enc, Error **errp); | ||
28 | + uint8_t *buf, int nb_sectors, bool enc, Error **errp); | ||
29 | |||
30 | int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset, | ||
31 | unsigned int *bytes, uint64_t *cluster_offset); | ||
32 | diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c | ||
33 | index XXXXXXX..XXXXXXX 100644 | ||
34 | --- a/block/qcow2-cluster.c | ||
35 | +++ b/block/qcow2-cluster.c | ||
36 | @@ -XXX,XX +XXX,XX @@ static int count_contiguous_clusters_unallocated(int nb_clusters, | ||
37 | } | ||
38 | |||
39 | /* The crypt function is compatible with the linux cryptoloop | ||
40 | - algorithm for < 4 GB images. NOTE: out_buf == in_buf is | ||
41 | - supported */ | ||
42 | + algorithm for < 4 GB images. */ | ||
43 | int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num, | ||
44 | - uint8_t *out_buf, const uint8_t *in_buf, | ||
45 | - int nb_sectors, bool enc, | ||
46 | + uint8_t *buf, int nb_sectors, bool enc, | ||
47 | Error **errp) | ||
48 | { | ||
49 | union { | ||
50 | @@ -XXX,XX +XXX,XX @@ int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num, | ||
51 | } | ||
52 | if (enc) { | ||
53 | ret = qcrypto_cipher_encrypt(s->cipher, | ||
54 | - in_buf, | ||
55 | - out_buf, | ||
56 | + buf, buf, | ||
57 | 512, | ||
58 | errp); | ||
59 | } else { | ||
60 | ret = qcrypto_cipher_decrypt(s->cipher, | ||
61 | - in_buf, | ||
62 | - out_buf, | ||
63 | + buf, buf, | ||
64 | 512, | ||
65 | errp); | ||
66 | } | ||
67 | @@ -XXX,XX +XXX,XX @@ int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num, | ||
68 | return -1; | ||
69 | } | ||
70 | sector_num++; | ||
71 | - in_buf += 512; | ||
72 | - out_buf += 512; | ||
73 | + buf += 512; | ||
74 | } | ||
75 | return 0; | ||
76 | } | ||
77 | @@ -XXX,XX +XXX,XX @@ static bool coroutine_fn do_perform_cow_encrypt(BlockDriverState *bs, | ||
78 | assert(s->cipher); | ||
79 | assert((offset_in_cluster & ~BDRV_SECTOR_MASK) == 0); | ||
80 | assert((bytes & ~BDRV_SECTOR_MASK) == 0); | ||
81 | - if (qcow2_encrypt_sectors(s, sector, buffer, buffer, | ||
82 | + if (qcow2_encrypt_sectors(s, sector, buffer, | ||
83 | bytes >> BDRV_SECTOR_BITS, true, NULL) < 0) { | ||
84 | return false; | ||
85 | } | ||
86 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
87 | index XXXXXXX..XXXXXXX 100644 | ||
88 | --- a/block/qcow2.c | ||
89 | +++ b/block/qcow2.c | ||
90 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset, | ||
91 | assert((cur_bytes & (BDRV_SECTOR_SIZE - 1)) == 0); | ||
92 | Error *err = NULL; | ||
93 | if (qcow2_encrypt_sectors(s, offset >> BDRV_SECTOR_BITS, | ||
94 | - cluster_data, cluster_data, | ||
95 | + cluster_data, | ||
96 | cur_bytes >> BDRV_SECTOR_BITS, | ||
97 | false, &err) < 0) { | ||
98 | error_free(err); | ||
99 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset, | ||
100 | qemu_iovec_to_buf(&hd_qiov, 0, cluster_data, hd_qiov.size); | ||
101 | |||
102 | if (qcow2_encrypt_sectors(s, offset >> BDRV_SECTOR_BITS, | ||
103 | - cluster_data, cluster_data, | ||
104 | + cluster_data, | ||
105 | cur_bytes >>BDRV_SECTOR_BITS, | ||
106 | true, &err) < 0) { | ||
107 | error_free(err); | ||
108 | -- | ||
109 | 2.9.4 | ||
110 | |||
111 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | ||
2 | 1 | ||
3 | This converts the qcow2 driver to make use of the QCryptoBlock | ||
4 | APIs for encrypting image content, using the legacy QCow2 AES | ||
5 | scheme. | ||
6 | |||
7 | With this change it is now required to use the QCryptoSecret | ||
8 | object for providing passwords, instead of the current block | ||
9 | password APIs / interactive prompting. | ||
10 | |||
11 | $QEMU \ | ||
12 | -object secret,id=sec0,file=/home/berrange/encrypted.pw \ | ||
13 | -drive file=/home/berrange/encrypted.qcow2,encrypt.key-secret=sec0 | ||
14 | |||
15 | The test 087 could be simplified since there is no longer a | ||
16 | difference in behaviour when using blockdev_add with encrypted | ||
17 | images for the running vs stopped CPU state. | ||
18 | |||
19 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
20 | Message-id: 20170623162419.26068-12-berrange@redhat.com | ||
21 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
22 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
23 | --- | ||
24 | qapi/block-core.json | 27 +++++- | ||
25 | block/qcow2.h | 5 +- | ||
26 | block/qcow2-cluster.c | 47 +--------- | ||
27 | block/qcow2.c | 226 ++++++++++++++++++++++++++++++--------------- | ||
28 | tests/qemu-iotests/049 | 2 +- | ||
29 | tests/qemu-iotests/049.out | 4 +- | ||
30 | tests/qemu-iotests/082.out | 27 ++++++ | ||
31 | tests/qemu-iotests/087 | 28 +++--- | ||
32 | tests/qemu-iotests/087.out | 12 +-- | ||
33 | tests/qemu-iotests/134 | 18 +++- | ||
34 | tests/qemu-iotests/134.out | 10 +- | ||
35 | tests/qemu-iotests/158 | 19 ++-- | ||
36 | tests/qemu-iotests/158.out | 14 +-- | ||
37 | tests/qemu-iotests/common | 10 +- | ||
38 | 14 files changed, 263 insertions(+), 186 deletions(-) | ||
39 | |||
40 | diff --git a/qapi/block-core.json b/qapi/block-core.json | ||
41 | index XXXXXXX..XXXXXXX 100644 | ||
42 | --- a/qapi/block-core.json | ||
43 | +++ b/qapi/block-core.json | ||
44 | @@ -XXX,XX +XXX,XX @@ | ||
45 | 'data': { '*encrypt': 'BlockdevQcowEncryption' } } | ||
46 | |||
47 | |||
48 | + | ||
49 | +## | ||
50 | +# @BlockdevQcow2EncryptionFormat: | ||
51 | +# @aes: AES-CBC with plain64 initialization venctors | ||
52 | +# | ||
53 | +# Since: 2.10 | ||
54 | +## | ||
55 | +{ 'enum': 'BlockdevQcow2EncryptionFormat', | ||
56 | + 'data': [ 'aes' ] } | ||
57 | + | ||
58 | +## | ||
59 | +# @BlockdevQcow2Encryption: | ||
60 | +# | ||
61 | +# Since: 2.10 | ||
62 | +## | ||
63 | +{ 'union': 'BlockdevQcow2Encryption', | ||
64 | + 'base': { 'format': 'BlockdevQcow2EncryptionFormat' }, | ||
65 | + 'discriminator': 'format', | ||
66 | + 'data': { 'aes': 'QCryptoBlockOptionsQCow' } } | ||
67 | + | ||
68 | ## | ||
69 | # @BlockdevOptionsQcow2: | ||
70 | # | ||
71 | @@ -XXX,XX +XXX,XX @@ | ||
72 | # @cache-clean-interval: clean unused entries in the L2 and refcount | ||
73 | # caches. The interval is in seconds. The default value | ||
74 | # is 0 and it disables this feature (since 2.5) | ||
75 | +# @encrypt: Image decryption options. Mandatory for | ||
76 | +# encrypted images, except when doing a metadata-only | ||
77 | +# probe of the image. (since 2.10) | ||
78 | # | ||
79 | # Since: 2.9 | ||
80 | ## | ||
81 | @@ -XXX,XX +XXX,XX @@ | ||
82 | '*cache-size': 'int', | ||
83 | '*l2-cache-size': 'int', | ||
84 | '*refcount-cache-size': 'int', | ||
85 | - '*cache-clean-interval': 'int' } } | ||
86 | - | ||
87 | + '*cache-clean-interval': 'int', | ||
88 | + '*encrypt': 'BlockdevQcow2Encryption' } } | ||
89 | |||
90 | ## | ||
91 | # @BlockdevOptionsSsh: | ||
92 | diff --git a/block/qcow2.h b/block/qcow2.h | ||
93 | index XXXXXXX..XXXXXXX 100644 | ||
94 | --- a/block/qcow2.h | ||
95 | +++ b/block/qcow2.h | ||
96 | @@ -XXX,XX +XXX,XX @@ | ||
97 | #ifndef BLOCK_QCOW2_H | ||
98 | #define BLOCK_QCOW2_H | ||
99 | |||
100 | -#include "crypto/cipher.h" | ||
101 | +#include "crypto/block.h" | ||
102 | #include "qemu/coroutine.h" | ||
103 | |||
104 | //#define DEBUG_ALLOC | ||
105 | @@ -XXX,XX +XXX,XX @@ typedef struct BDRVQcow2State { | ||
106 | |||
107 | CoMutex lock; | ||
108 | |||
109 | - QCryptoCipher *cipher; /* current cipher, NULL if no key yet */ | ||
110 | + QCryptoBlockOpenOptions *crypto_opts; /* Disk encryption runtime options */ | ||
111 | + QCryptoBlock *crypto; /* Disk encryption format driver */ | ||
112 | uint32_t crypt_method_header; | ||
113 | uint64_t snapshots_offset; | ||
114 | int snapshots_size; | ||
115 | diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c | ||
116 | index XXXXXXX..XXXXXXX 100644 | ||
117 | --- a/block/qcow2-cluster.c | ||
118 | +++ b/block/qcow2-cluster.c | ||
119 | @@ -XXX,XX +XXX,XX @@ static int count_contiguous_clusters_unallocated(int nb_clusters, | ||
120 | return i; | ||
121 | } | ||
122 | |||
123 | -/* The crypt function is compatible with the linux cryptoloop | ||
124 | - algorithm for < 4 GB images. */ | ||
125 | -int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num, | ||
126 | - uint8_t *buf, int nb_sectors, bool enc, | ||
127 | - Error **errp) | ||
128 | -{ | ||
129 | - union { | ||
130 | - uint64_t ll[2]; | ||
131 | - uint8_t b[16]; | ||
132 | - } ivec; | ||
133 | - int i; | ||
134 | - int ret; | ||
135 | - | ||
136 | - for(i = 0; i < nb_sectors; i++) { | ||
137 | - ivec.ll[0] = cpu_to_le64(sector_num); | ||
138 | - ivec.ll[1] = 0; | ||
139 | - if (qcrypto_cipher_setiv(s->cipher, | ||
140 | - ivec.b, G_N_ELEMENTS(ivec.b), | ||
141 | - errp) < 0) { | ||
142 | - return -1; | ||
143 | - } | ||
144 | - if (enc) { | ||
145 | - ret = qcrypto_cipher_encrypt(s->cipher, | ||
146 | - buf, buf, | ||
147 | - 512, | ||
148 | - errp); | ||
149 | - } else { | ||
150 | - ret = qcrypto_cipher_decrypt(s->cipher, | ||
151 | - buf, buf, | ||
152 | - 512, | ||
153 | - errp); | ||
154 | - } | ||
155 | - if (ret < 0) { | ||
156 | - return -1; | ||
157 | - } | ||
158 | - sector_num++; | ||
159 | - buf += 512; | ||
160 | - } | ||
161 | - return 0; | ||
162 | -} | ||
163 | - | ||
164 | static int coroutine_fn do_perform_cow_read(BlockDriverState *bs, | ||
165 | uint64_t src_cluster_offset, | ||
166 | unsigned offset_in_cluster, | ||
167 | @@ -XXX,XX +XXX,XX @@ static bool coroutine_fn do_perform_cow_encrypt(BlockDriverState *bs, | ||
168 | BDRVQcow2State *s = bs->opaque; | ||
169 | int64_t sector = (src_cluster_offset + offset_in_cluster) | ||
170 | >> BDRV_SECTOR_BITS; | ||
171 | - assert(s->cipher); | ||
172 | assert((offset_in_cluster & ~BDRV_SECTOR_MASK) == 0); | ||
173 | assert((bytes & ~BDRV_SECTOR_MASK) == 0); | ||
174 | - if (qcow2_encrypt_sectors(s, sector, buffer, | ||
175 | - bytes >> BDRV_SECTOR_BITS, true, NULL) < 0) { | ||
176 | + assert(s->crypto); | ||
177 | + if (qcrypto_block_encrypt(s->crypto, sector, buffer, | ||
178 | + bytes, NULL) < 0) { | ||
179 | return false; | ||
180 | } | ||
181 | } | ||
182 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
183 | index XXXXXXX..XXXXXXX 100644 | ||
184 | --- a/block/qcow2.c | ||
185 | +++ b/block/qcow2.c | ||
186 | @@ -XXX,XX +XXX,XX @@ | ||
187 | #include "qemu/option_int.h" | ||
188 | #include "qemu/cutils.h" | ||
189 | #include "qemu/bswap.h" | ||
190 | +#include "qapi/opts-visitor.h" | ||
191 | +#include "qapi-visit.h" | ||
192 | +#include "block/crypto.h" | ||
193 | |||
194 | /* | ||
195 | Differences with QCOW: | ||
196 | @@ -XXX,XX +XXX,XX @@ static QemuOptsList qcow2_runtime_opts = { | ||
197 | .type = QEMU_OPT_NUMBER, | ||
198 | .help = "Clean unused cache entries after this time (in seconds)", | ||
199 | }, | ||
200 | + BLOCK_CRYPTO_OPT_DEF_QCOW_KEY_SECRET("encrypt."), | ||
201 | { /* end of list */ } | ||
202 | }, | ||
203 | }; | ||
204 | @@ -XXX,XX +XXX,XX @@ typedef struct Qcow2ReopenState { | ||
205 | int overlap_check; | ||
206 | bool discard_passthrough[QCOW2_DISCARD_MAX]; | ||
207 | uint64_t cache_clean_interval; | ||
208 | + QCryptoBlockOpenOptions *crypto_opts; /* Disk encryption runtime options */ | ||
209 | } Qcow2ReopenState; | ||
210 | |||
211 | static int qcow2_update_options_prepare(BlockDriverState *bs, | ||
212 | @@ -XXX,XX +XXX,XX @@ static int qcow2_update_options_prepare(BlockDriverState *bs, | ||
213 | int overlap_check_template = 0; | ||
214 | uint64_t l2_cache_size, refcount_cache_size; | ||
215 | int i; | ||
216 | + const char *encryptfmt; | ||
217 | + QDict *encryptopts = NULL; | ||
218 | Error *local_err = NULL; | ||
219 | int ret; | ||
220 | |||
221 | + qdict_extract_subqdict(options, &encryptopts, "encrypt."); | ||
222 | + encryptfmt = qdict_get_try_str(encryptopts, "format"); | ||
223 | + | ||
224 | opts = qemu_opts_create(&qcow2_runtime_opts, NULL, 0, &error_abort); | ||
225 | qemu_opts_absorb_qdict(opts, options, &local_err); | ||
226 | if (local_err) { | ||
227 | @@ -XXX,XX +XXX,XX @@ static int qcow2_update_options_prepare(BlockDriverState *bs, | ||
228 | r->discard_passthrough[QCOW2_DISCARD_OTHER] = | ||
229 | qemu_opt_get_bool(opts, QCOW2_OPT_DISCARD_OTHER, false); | ||
230 | |||
231 | + switch (s->crypt_method_header) { | ||
232 | + case QCOW_CRYPT_NONE: | ||
233 | + if (encryptfmt) { | ||
234 | + error_setg(errp, "No encryption in image header, but options " | ||
235 | + "specified format '%s'", encryptfmt); | ||
236 | + ret = -EINVAL; | ||
237 | + goto fail; | ||
238 | + } | ||
239 | + break; | ||
240 | + | ||
241 | + case QCOW_CRYPT_AES: | ||
242 | + if (encryptfmt && !g_str_equal(encryptfmt, "aes")) { | ||
243 | + error_setg(errp, | ||
244 | + "Header reported 'aes' encryption format but " | ||
245 | + "options specify '%s'", encryptfmt); | ||
246 | + ret = -EINVAL; | ||
247 | + goto fail; | ||
248 | + } | ||
249 | + qdict_del(encryptopts, "format"); | ||
250 | + r->crypto_opts = block_crypto_open_opts_init( | ||
251 | + Q_CRYPTO_BLOCK_FORMAT_QCOW, encryptopts, errp); | ||
252 | + break; | ||
253 | + | ||
254 | + default: | ||
255 | + error_setg(errp, "Unsupported encryption method %d", | ||
256 | + s->crypt_method_header); | ||
257 | + break; | ||
258 | + } | ||
259 | + if (s->crypt_method_header != QCOW_CRYPT_NONE && !r->crypto_opts) { | ||
260 | + ret = -EINVAL; | ||
261 | + goto fail; | ||
262 | + } | ||
263 | + | ||
264 | ret = 0; | ||
265 | fail: | ||
266 | + QDECREF(encryptopts); | ||
267 | qemu_opts_del(opts); | ||
268 | opts = NULL; | ||
269 | return ret; | ||
270 | @@ -XXX,XX +XXX,XX @@ static void qcow2_update_options_commit(BlockDriverState *bs, | ||
271 | s->cache_clean_interval = r->cache_clean_interval; | ||
272 | cache_clean_timer_init(bs, bdrv_get_aio_context(bs)); | ||
273 | } | ||
274 | + | ||
275 | + qapi_free_QCryptoBlockOpenOptions(s->crypto_opts); | ||
276 | + s->crypto_opts = r->crypto_opts; | ||
277 | } | ||
278 | |||
279 | static void qcow2_update_options_abort(BlockDriverState *bs, | ||
280 | @@ -XXX,XX +XXX,XX @@ static void qcow2_update_options_abort(BlockDriverState *bs, | ||
281 | if (r->refcount_block_cache) { | ||
282 | qcow2_cache_destroy(bs, r->refcount_block_cache); | ||
283 | } | ||
284 | + qapi_free_QCryptoBlockOpenOptions(r->crypto_opts); | ||
285 | } | ||
286 | |||
287 | static int qcow2_update_options(BlockDriverState *bs, QDict *options, | ||
288 | @@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags, | ||
289 | ret = -EINVAL; | ||
290 | goto fail; | ||
291 | } | ||
292 | - if (!qcrypto_cipher_supports(QCRYPTO_CIPHER_ALG_AES_128, | ||
293 | - QCRYPTO_CIPHER_MODE_CBC)) { | ||
294 | - error_setg(errp, "AES cipher not available"); | ||
295 | - ret = -EINVAL; | ||
296 | - goto fail; | ||
297 | - } | ||
298 | s->crypt_method_header = header.crypt_method; | ||
299 | if (s->crypt_method_header) { | ||
300 | if (bdrv_uses_whitelist() && | ||
301 | @@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags, | ||
302 | } | ||
303 | |||
304 | bs->encrypted = true; | ||
305 | + bs->valid_key = true; | ||
306 | } | ||
307 | |||
308 | s->l2_bits = s->cluster_bits - 3; /* L2 is always one cluster */ | ||
309 | @@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags, | ||
310 | goto fail; | ||
311 | } | ||
312 | |||
313 | + if (s->crypt_method_header == QCOW_CRYPT_AES) { | ||
314 | + unsigned int cflags = 0; | ||
315 | + if (flags & BDRV_O_NO_IO) { | ||
316 | + cflags |= QCRYPTO_BLOCK_OPEN_NO_IO; | ||
317 | + } | ||
318 | + s->crypto = qcrypto_block_open(s->crypto_opts, NULL, NULL, | ||
319 | + cflags, errp); | ||
320 | + if (!s->crypto) { | ||
321 | + ret = -EINVAL; | ||
322 | + goto fail; | ||
323 | + } | ||
324 | + } | ||
325 | + | ||
326 | /* read the backing file name */ | ||
327 | if (header.backing_file_offset != 0) { | ||
328 | len = header.backing_file_size; | ||
329 | @@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags, | ||
330 | } | ||
331 | g_free(s->cluster_cache); | ||
332 | qemu_vfree(s->cluster_data); | ||
333 | + qcrypto_block_free(s->crypto); | ||
334 | + qapi_free_QCryptoBlockOpenOptions(s->crypto_opts); | ||
335 | return ret; | ||
336 | } | ||
337 | |||
338 | @@ -XXX,XX +XXX,XX @@ static void qcow2_refresh_limits(BlockDriverState *bs, Error **errp) | ||
339 | bs->bl.pdiscard_alignment = s->cluster_size; | ||
340 | } | ||
341 | |||
342 | -static int qcow2_set_key(BlockDriverState *bs, const char *key) | ||
343 | -{ | ||
344 | - BDRVQcow2State *s = bs->opaque; | ||
345 | - uint8_t keybuf[16]; | ||
346 | - int len, i; | ||
347 | - Error *err = NULL; | ||
348 | - | ||
349 | - memset(keybuf, 0, 16); | ||
350 | - len = strlen(key); | ||
351 | - if (len > 16) | ||
352 | - len = 16; | ||
353 | - /* XXX: we could compress the chars to 7 bits to increase | ||
354 | - entropy */ | ||
355 | - for(i = 0;i < len;i++) { | ||
356 | - keybuf[i] = key[i]; | ||
357 | - } | ||
358 | - assert(bs->encrypted); | ||
359 | - | ||
360 | - qcrypto_cipher_free(s->cipher); | ||
361 | - s->cipher = qcrypto_cipher_new( | ||
362 | - QCRYPTO_CIPHER_ALG_AES_128, | ||
363 | - QCRYPTO_CIPHER_MODE_CBC, | ||
364 | - keybuf, G_N_ELEMENTS(keybuf), | ||
365 | - &err); | ||
366 | - | ||
367 | - if (!s->cipher) { | ||
368 | - /* XXX would be nice if errors in this method could | ||
369 | - * be properly propagate to the caller. Would need | ||
370 | - * the bdrv_set_key() API signature to be fixed. */ | ||
371 | - error_free(err); | ||
372 | - return -1; | ||
373 | - } | ||
374 | - return 0; | ||
375 | -} | ||
376 | - | ||
377 | static int qcow2_reopen_prepare(BDRVReopenState *state, | ||
378 | BlockReopenQueue *queue, Error **errp) | ||
379 | { | ||
380 | @@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn qcow2_co_get_block_status(BlockDriverState *bs, | ||
381 | *pnum = bytes >> BDRV_SECTOR_BITS; | ||
382 | |||
383 | if (cluster_offset != 0 && ret != QCOW2_CLUSTER_COMPRESSED && | ||
384 | - !s->cipher) { | ||
385 | + !s->crypto) { | ||
386 | index_in_cluster = sector_num & (s->cluster_sectors - 1); | ||
387 | cluster_offset |= (index_in_cluster << BDRV_SECTOR_BITS); | ||
388 | *file = bs->file->bs; | ||
389 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset, | ||
390 | |||
391 | /* prepare next request */ | ||
392 | cur_bytes = MIN(bytes, INT_MAX); | ||
393 | - if (s->cipher) { | ||
394 | + if (s->crypto) { | ||
395 | cur_bytes = MIN(cur_bytes, | ||
396 | QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size); | ||
397 | } | ||
398 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset, | ||
399 | } | ||
400 | |||
401 | if (bs->encrypted) { | ||
402 | - assert(s->cipher); | ||
403 | + assert(s->crypto); | ||
404 | |||
405 | /* | ||
406 | * For encrypted images, read everything into a temporary | ||
407 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset, | ||
408 | goto fail; | ||
409 | } | ||
410 | if (bs->encrypted) { | ||
411 | - assert(s->cipher); | ||
412 | + assert(s->crypto); | ||
413 | assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0); | ||
414 | assert((cur_bytes & (BDRV_SECTOR_SIZE - 1)) == 0); | ||
415 | Error *err = NULL; | ||
416 | - if (qcow2_encrypt_sectors(s, offset >> BDRV_SECTOR_BITS, | ||
417 | + if (qcrypto_block_decrypt(s->crypto, | ||
418 | + offset >> BDRV_SECTOR_BITS, | ||
419 | cluster_data, | ||
420 | - cur_bytes >> BDRV_SECTOR_BITS, | ||
421 | - false, &err) < 0) { | ||
422 | + cur_bytes, | ||
423 | + &err) < 0) { | ||
424 | error_free(err); | ||
425 | ret = -EIO; | ||
426 | goto fail; | ||
427 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset, | ||
428 | |||
429 | if (bs->encrypted) { | ||
430 | Error *err = NULL; | ||
431 | - assert(s->cipher); | ||
432 | + assert(s->crypto); | ||
433 | if (!cluster_data) { | ||
434 | cluster_data = qemu_try_blockalign(bs->file->bs, | ||
435 | QCOW_MAX_CRYPT_CLUSTERS | ||
436 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset, | ||
437 | QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size); | ||
438 | qemu_iovec_to_buf(&hd_qiov, 0, cluster_data, hd_qiov.size); | ||
439 | |||
440 | - if (qcow2_encrypt_sectors(s, offset >> BDRV_SECTOR_BITS, | ||
441 | + if (qcrypto_block_encrypt(s->crypto, offset >> BDRV_SECTOR_BITS, | ||
442 | cluster_data, | ||
443 | - cur_bytes >>BDRV_SECTOR_BITS, | ||
444 | - true, &err) < 0) { | ||
445 | + cur_bytes, &err) < 0) { | ||
446 | error_free(err); | ||
447 | ret = -EIO; | ||
448 | goto fail; | ||
449 | @@ -XXX,XX +XXX,XX @@ static void qcow2_close(BlockDriverState *bs) | ||
450 | qcow2_cache_destroy(bs, s->l2_table_cache); | ||
451 | qcow2_cache_destroy(bs, s->refcount_block_cache); | ||
452 | |||
453 | - qcrypto_cipher_free(s->cipher); | ||
454 | - s->cipher = NULL; | ||
455 | + qcrypto_block_free(s->crypto); | ||
456 | + s->crypto = NULL; | ||
457 | |||
458 | g_free(s->unknown_header_fields); | ||
459 | cleanup_unknown_header_ext(bs); | ||
460 | @@ -XXX,XX +XXX,XX @@ static void qcow2_invalidate_cache(BlockDriverState *bs, Error **errp) | ||
461 | { | ||
462 | BDRVQcow2State *s = bs->opaque; | ||
463 | int flags = s->flags; | ||
464 | - QCryptoCipher *cipher = NULL; | ||
465 | + QCryptoBlock *crypto = NULL; | ||
466 | QDict *options; | ||
467 | Error *local_err = NULL; | ||
468 | int ret; | ||
469 | @@ -XXX,XX +XXX,XX @@ static void qcow2_invalidate_cache(BlockDriverState *bs, Error **errp) | ||
470 | * that means we don't have to worry about reopening them here. | ||
471 | */ | ||
472 | |||
473 | - cipher = s->cipher; | ||
474 | - s->cipher = NULL; | ||
475 | + crypto = s->crypto; | ||
476 | + s->crypto = NULL; | ||
477 | |||
478 | qcow2_close(bs); | ||
479 | |||
480 | @@ -XXX,XX +XXX,XX @@ static void qcow2_invalidate_cache(BlockDriverState *bs, Error **errp) | ||
481 | return; | ||
482 | } | ||
483 | |||
484 | - s->cipher = cipher; | ||
485 | + s->crypto = crypto; | ||
486 | } | ||
487 | |||
488 | static size_t header_ext_add(char *buf, uint32_t magic, const void *s, | ||
489 | @@ -XXX,XX +XXX,XX @@ static int qcow2_change_backing_file(BlockDriverState *bs, | ||
490 | return qcow2_update_header(bs); | ||
491 | } | ||
492 | |||
493 | + | ||
494 | +static int qcow2_set_up_encryption(BlockDriverState *bs, const char *encryptfmt, | ||
495 | + QemuOpts *opts, Error **errp) | ||
496 | +{ | ||
497 | + BDRVQcow2State *s = bs->opaque; | ||
498 | + QCryptoBlockCreateOptions *cryptoopts = NULL; | ||
499 | + QCryptoBlock *crypto = NULL; | ||
500 | + int ret = -EINVAL; | ||
501 | + QDict *options, *encryptopts; | ||
502 | + | ||
503 | + options = qemu_opts_to_qdict(opts, NULL); | ||
504 | + qdict_extract_subqdict(options, &encryptopts, "encrypt."); | ||
505 | + QDECREF(options); | ||
506 | + | ||
507 | + if (!g_str_equal(encryptfmt, "aes")) { | ||
508 | + error_setg(errp, "Unknown encryption format '%s', expected 'aes'", | ||
509 | + encryptfmt); | ||
510 | + ret = -EINVAL; | ||
511 | + goto out; | ||
512 | + } | ||
513 | + cryptoopts = block_crypto_create_opts_init( | ||
514 | + Q_CRYPTO_BLOCK_FORMAT_QCOW, encryptopts, errp); | ||
515 | + if (!cryptoopts) { | ||
516 | + ret = -EINVAL; | ||
517 | + goto out; | ||
518 | + } | ||
519 | + s->crypt_method_header = QCOW_CRYPT_AES; | ||
520 | + | ||
521 | + crypto = qcrypto_block_create(cryptoopts, | ||
522 | + NULL, NULL, | ||
523 | + bs, errp); | ||
524 | + if (!crypto) { | ||
525 | + ret = -EINVAL; | ||
526 | + goto out; | ||
527 | + } | ||
528 | + | ||
529 | + ret = qcow2_update_header(bs); | ||
530 | + if (ret < 0) { | ||
531 | + error_setg_errno(errp, -ret, "Could not write encryption header"); | ||
532 | + goto out; | ||
533 | + } | ||
534 | + | ||
535 | + out: | ||
536 | + QDECREF(encryptopts); | ||
537 | + qcrypto_block_free(crypto); | ||
538 | + qapi_free_QCryptoBlockCreateOptions(cryptoopts); | ||
539 | + return ret; | ||
540 | +} | ||
541 | + | ||
542 | + | ||
543 | static int preallocate(BlockDriverState *bs) | ||
544 | { | ||
545 | uint64_t bytes; | ||
546 | @@ -XXX,XX +XXX,XX @@ static int qcow2_create2(const char *filename, int64_t total_size, | ||
547 | .header_length = cpu_to_be32(sizeof(*header)), | ||
548 | }; | ||
549 | |||
550 | - if (encryptfmt) { | ||
551 | - if (!g_str_equal(encryptfmt, "aes")) { | ||
552 | - error_setg(errp, "Unknown encryption format '%s', expected 'aes'", | ||
553 | - encryptfmt); | ||
554 | - ret = -EINVAL; | ||
555 | - goto out; | ||
556 | - } | ||
557 | - header->crypt_method = cpu_to_be32(QCOW_CRYPT_AES); | ||
558 | - } else { | ||
559 | - header->crypt_method = cpu_to_be32(QCOW_CRYPT_NONE); | ||
560 | - } | ||
561 | + /* We'll update this to correct value later */ | ||
562 | + header->crypt_method = cpu_to_be32(QCOW_CRYPT_NONE); | ||
563 | |||
564 | if (flags & BLOCK_FLAG_LAZY_REFCOUNTS) { | ||
565 | header->compatible_features |= | ||
566 | @@ -XXX,XX +XXX,XX @@ static int qcow2_create2(const char *filename, int64_t total_size, | ||
567 | } | ||
568 | } | ||
569 | |||
570 | + /* Want encryption? There you go. */ | ||
571 | + if (encryptfmt) { | ||
572 | + ret = qcow2_set_up_encryption(blk_bs(blk), encryptfmt, opts, errp); | ||
573 | + if (ret < 0) { | ||
574 | + goto out; | ||
575 | + } | ||
576 | + } | ||
577 | + | ||
578 | /* And if we're supposed to preallocate metadata, do that now */ | ||
579 | if (prealloc != PREALLOC_MODE_OFF) { | ||
580 | BDRVQcow2State *s = blk_bs(blk)->opaque; | ||
581 | @@ -XXX,XX +XXX,XX @@ static int qcow2_create2(const char *filename, int64_t total_size, | ||
582 | blk_unref(blk); | ||
583 | blk = NULL; | ||
584 | |||
585 | - /* Reopen the image without BDRV_O_NO_FLUSH to flush it before returning */ | ||
586 | + /* Reopen the image without BDRV_O_NO_FLUSH to flush it before returning. | ||
587 | + * Using BDRV_O_NO_IO, since encryption is now setup we don't want to | ||
588 | + * have to setup decryption context. We're not doing any I/O on the top | ||
589 | + * level BlockDriverState, only lower layers, where BDRV_O_NO_IO does | ||
590 | + * not have effect. | ||
591 | + */ | ||
592 | options = qdict_new(); | ||
593 | qdict_put_str(options, "driver", "qcow2"); | ||
594 | blk = blk_new_open(filename, NULL, options, | ||
595 | - BDRV_O_RDWR | BDRV_O_NO_BACKING, &local_err); | ||
596 | + BDRV_O_RDWR | BDRV_O_NO_BACKING | BDRV_O_NO_IO, | ||
597 | + &local_err); | ||
598 | if (blk == NULL) { | ||
599 | error_propagate(errp, local_err); | ||
600 | ret = -EIO; | ||
601 | @@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts, | ||
602 | backing_format = qemu_opt_get(opts, BLOCK_OPT_BACKING_FMT); | ||
603 | } else if (!strcmp(desc->name, BLOCK_OPT_ENCRYPT)) { | ||
604 | encrypt = qemu_opt_get_bool(opts, BLOCK_OPT_ENCRYPT, | ||
605 | - !!s->cipher); | ||
606 | + !!s->crypto); | ||
607 | |||
608 | - if (encrypt != !!s->cipher) { | ||
609 | + if (encrypt != !!s->crypto) { | ||
610 | error_report("Changing the encryption flag is not supported"); | ||
611 | return -ENOTSUP; | ||
612 | } | ||
613 | @@ -XXX,XX +XXX,XX @@ static QemuOptsList qcow2_create_opts = { | ||
614 | .type = QEMU_OPT_STRING, | ||
615 | .help = "Encrypt the image, format choices: 'aes'", | ||
616 | }, | ||
617 | + BLOCK_CRYPTO_OPT_DEF_QCOW_KEY_SECRET("encrypt."), | ||
618 | { | ||
619 | .name = BLOCK_OPT_CLUSTER_SIZE, | ||
620 | .type = QEMU_OPT_SIZE, | ||
621 | @@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_qcow2 = { | ||
622 | .bdrv_create = qcow2_create, | ||
623 | .bdrv_has_zero_init = bdrv_has_zero_init_1, | ||
624 | .bdrv_co_get_block_status = qcow2_co_get_block_status, | ||
625 | - .bdrv_set_key = qcow2_set_key, | ||
626 | |||
627 | .bdrv_co_preadv = qcow2_co_preadv, | ||
628 | .bdrv_co_pwritev = qcow2_co_pwritev, | ||
629 | diff --git a/tests/qemu-iotests/049 b/tests/qemu-iotests/049 | ||
630 | index XXXXXXX..XXXXXXX 100755 | ||
631 | --- a/tests/qemu-iotests/049 | ||
632 | +++ b/tests/qemu-iotests/049 | ||
633 | @@ -XXX,XX +XXX,XX @@ test_qemu_img create -f $IMGFMT -o preallocation=1234 "$TEST_IMG" 64M | ||
634 | echo "== Check encryption option ==" | ||
635 | echo | ||
636 | test_qemu_img create -f $IMGFMT -o encryption=off "$TEST_IMG" 64M | ||
637 | -test_qemu_img create -f $IMGFMT -o encryption=on "$TEST_IMG" 64M | ||
638 | +test_qemu_img create -f $IMGFMT --object secret,id=sec0,data=123456 -o encryption=on,encrypt.key-secret=sec0 "$TEST_IMG" 64M | ||
639 | |||
640 | echo "== Check lazy_refcounts option (only with v3) ==" | ||
641 | echo | ||
642 | diff --git a/tests/qemu-iotests/049.out b/tests/qemu-iotests/049.out | ||
643 | index XXXXXXX..XXXXXXX 100644 | ||
644 | --- a/tests/qemu-iotests/049.out | ||
645 | +++ b/tests/qemu-iotests/049.out | ||
646 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=65536 preall | ||
647 | qemu-img create -f qcow2 -o encryption=off TEST_DIR/t.qcow2 64M | ||
648 | Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
649 | |||
650 | -qemu-img create -f qcow2 -o encryption=on TEST_DIR/t.qcow2 64M | ||
651 | -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=on cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
652 | +qemu-img create -f qcow2 --object secret,id=sec0,data=123456 -o encryption=on,encrypt.key-secret=sec0 TEST_DIR/t.qcow2 64M | ||
653 | +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=on encrypt.key-secret=sec0 cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
654 | |||
655 | == Check lazy_refcounts option (only with v3) == | ||
656 | |||
657 | diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out | ||
658 | index XXXXXXX..XXXXXXX 100644 | ||
659 | --- a/tests/qemu-iotests/082.out | ||
660 | +++ b/tests/qemu-iotests/082.out | ||
661 | @@ -XXX,XX +XXX,XX @@ backing_file File name of a base image | ||
662 | backing_fmt Image format of the base image | ||
663 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
664 | encrypt.format Encrypt the image, format choices: 'aes' | ||
665 | +encrypt.key-secret ID of the secret that provides the AES encryption key | ||
666 | cluster_size qcow2 cluster size | ||
667 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
668 | lazy_refcounts Postpone refcount updates | ||
669 | @@ -XXX,XX +XXX,XX @@ backing_file File name of a base image | ||
670 | backing_fmt Image format of the base image | ||
671 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
672 | encrypt.format Encrypt the image, format choices: 'aes' | ||
673 | +encrypt.key-secret ID of the secret that provides the AES encryption key | ||
674 | cluster_size qcow2 cluster size | ||
675 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
676 | lazy_refcounts Postpone refcount updates | ||
677 | @@ -XXX,XX +XXX,XX @@ backing_file File name of a base image | ||
678 | backing_fmt Image format of the base image | ||
679 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
680 | encrypt.format Encrypt the image, format choices: 'aes' | ||
681 | +encrypt.key-secret ID of the secret that provides the AES encryption key | ||
682 | cluster_size qcow2 cluster size | ||
683 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
684 | lazy_refcounts Postpone refcount updates | ||
685 | @@ -XXX,XX +XXX,XX @@ backing_file File name of a base image | ||
686 | backing_fmt Image format of the base image | ||
687 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
688 | encrypt.format Encrypt the image, format choices: 'aes' | ||
689 | +encrypt.key-secret ID of the secret that provides the AES encryption key | ||
690 | cluster_size qcow2 cluster size | ||
691 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
692 | lazy_refcounts Postpone refcount updates | ||
693 | @@ -XXX,XX +XXX,XX @@ backing_file File name of a base image | ||
694 | backing_fmt Image format of the base image | ||
695 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
696 | encrypt.format Encrypt the image, format choices: 'aes' | ||
697 | +encrypt.key-secret ID of the secret that provides the AES encryption key | ||
698 | cluster_size qcow2 cluster size | ||
699 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
700 | lazy_refcounts Postpone refcount updates | ||
701 | @@ -XXX,XX +XXX,XX @@ backing_file File name of a base image | ||
702 | backing_fmt Image format of the base image | ||
703 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
704 | encrypt.format Encrypt the image, format choices: 'aes' | ||
705 | +encrypt.key-secret ID of the secret that provides the AES encryption key | ||
706 | cluster_size qcow2 cluster size | ||
707 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
708 | lazy_refcounts Postpone refcount updates | ||
709 | @@ -XXX,XX +XXX,XX @@ backing_file File name of a base image | ||
710 | backing_fmt Image format of the base image | ||
711 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
712 | encrypt.format Encrypt the image, format choices: 'aes' | ||
713 | +encrypt.key-secret ID of the secret that provides the AES encryption key | ||
714 | cluster_size qcow2 cluster size | ||
715 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
716 | lazy_refcounts Postpone refcount updates | ||
717 | @@ -XXX,XX +XXX,XX @@ backing_file File name of a base image | ||
718 | backing_fmt Image format of the base image | ||
719 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
720 | encrypt.format Encrypt the image, format choices: 'aes' | ||
721 | +encrypt.key-secret ID of the secret that provides the AES encryption key | ||
722 | cluster_size qcow2 cluster size | ||
723 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
724 | lazy_refcounts Postpone refcount updates | ||
725 | @@ -XXX,XX +XXX,XX @@ backing_file File name of a base image | ||
726 | backing_fmt Image format of the base image | ||
727 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
728 | encrypt.format Encrypt the image, format choices: 'aes' | ||
729 | +encrypt.key-secret ID of the secret that provides the AES encryption key | ||
730 | cluster_size qcow2 cluster size | ||
731 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
732 | lazy_refcounts Postpone refcount updates | ||
733 | @@ -XXX,XX +XXX,XX @@ backing_file File name of a base image | ||
734 | backing_fmt Image format of the base image | ||
735 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
736 | encrypt.format Encrypt the image, format choices: 'aes' | ||
737 | +encrypt.key-secret ID of the secret that provides the AES encryption key | ||
738 | cluster_size qcow2 cluster size | ||
739 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
740 | lazy_refcounts Postpone refcount updates | ||
741 | @@ -XXX,XX +XXX,XX @@ backing_file File name of a base image | ||
742 | backing_fmt Image format of the base image | ||
743 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
744 | encrypt.format Encrypt the image, format choices: 'aes' | ||
745 | +encrypt.key-secret ID of the secret that provides the AES encryption key | ||
746 | cluster_size qcow2 cluster size | ||
747 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
748 | lazy_refcounts Postpone refcount updates | ||
749 | @@ -XXX,XX +XXX,XX @@ backing_file File name of a base image | ||
750 | backing_fmt Image format of the base image | ||
751 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
752 | encrypt.format Encrypt the image, format choices: 'aes' | ||
753 | +encrypt.key-secret ID of the secret that provides the AES encryption key | ||
754 | cluster_size qcow2 cluster size | ||
755 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
756 | lazy_refcounts Postpone refcount updates | ||
757 | @@ -XXX,XX +XXX,XX @@ backing_file File name of a base image | ||
758 | backing_fmt Image format of the base image | ||
759 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
760 | encrypt.format Encrypt the image, format choices: 'aes' | ||
761 | +encrypt.key-secret ID of the secret that provides the AES encryption key | ||
762 | cluster_size qcow2 cluster size | ||
763 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
764 | lazy_refcounts Postpone refcount updates | ||
765 | @@ -XXX,XX +XXX,XX @@ backing_file File name of a base image | ||
766 | backing_fmt Image format of the base image | ||
767 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
768 | encrypt.format Encrypt the image, format choices: 'aes' | ||
769 | +encrypt.key-secret ID of the secret that provides the AES encryption key | ||
770 | cluster_size qcow2 cluster size | ||
771 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
772 | lazy_refcounts Postpone refcount updates | ||
773 | @@ -XXX,XX +XXX,XX @@ backing_file File name of a base image | ||
774 | backing_fmt Image format of the base image | ||
775 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
776 | encrypt.format Encrypt the image, format choices: 'aes' | ||
777 | +encrypt.key-secret ID of the secret that provides the AES encryption key | ||
778 | cluster_size qcow2 cluster size | ||
779 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
780 | lazy_refcounts Postpone refcount updates | ||
781 | @@ -XXX,XX +XXX,XX @@ backing_file File name of a base image | ||
782 | backing_fmt Image format of the base image | ||
783 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
784 | encrypt.format Encrypt the image, format choices: 'aes' | ||
785 | +encrypt.key-secret ID of the secret that provides the AES encryption key | ||
786 | cluster_size qcow2 cluster size | ||
787 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
788 | lazy_refcounts Postpone refcount updates | ||
789 | @@ -XXX,XX +XXX,XX @@ backing_file File name of a base image | ||
790 | backing_fmt Image format of the base image | ||
791 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
792 | encrypt.format Encrypt the image, format choices: 'aes' | ||
793 | +encrypt.key-secret ID of the secret that provides the AES encryption key | ||
794 | cluster_size qcow2 cluster size | ||
795 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
796 | lazy_refcounts Postpone refcount updates | ||
797 | @@ -XXX,XX +XXX,XX @@ backing_file File name of a base image | ||
798 | backing_fmt Image format of the base image | ||
799 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
800 | encrypt.format Encrypt the image, format choices: 'aes' | ||
801 | +encrypt.key-secret ID of the secret that provides the AES encryption key | ||
802 | cluster_size qcow2 cluster size | ||
803 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
804 | lazy_refcounts Postpone refcount updates | ||
805 | @@ -XXX,XX +XXX,XX @@ backing_file File name of a base image | ||
806 | backing_fmt Image format of the base image | ||
807 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
808 | encrypt.format Encrypt the image, format choices: 'aes' | ||
809 | +encrypt.key-secret ID of the secret that provides the AES encryption key | ||
810 | cluster_size qcow2 cluster size | ||
811 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
812 | lazy_refcounts Postpone refcount updates | ||
813 | @@ -XXX,XX +XXX,XX @@ backing_file File name of a base image | ||
814 | backing_fmt Image format of the base image | ||
815 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
816 | encrypt.format Encrypt the image, format choices: 'aes' | ||
817 | +encrypt.key-secret ID of the secret that provides the AES encryption key | ||
818 | cluster_size qcow2 cluster size | ||
819 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
820 | lazy_refcounts Postpone refcount updates | ||
821 | @@ -XXX,XX +XXX,XX @@ backing_file File name of a base image | ||
822 | backing_fmt Image format of the base image | ||
823 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
824 | encrypt.format Encrypt the image, format choices: 'aes' | ||
825 | +encrypt.key-secret ID of the secret that provides the AES encryption key | ||
826 | cluster_size qcow2 cluster size | ||
827 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
828 | lazy_refcounts Postpone refcount updates | ||
829 | @@ -XXX,XX +XXX,XX @@ backing_file File name of a base image | ||
830 | backing_fmt Image format of the base image | ||
831 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
832 | encrypt.format Encrypt the image, format choices: 'aes' | ||
833 | +encrypt.key-secret ID of the secret that provides the AES encryption key | ||
834 | cluster_size qcow2 cluster size | ||
835 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
836 | lazy_refcounts Postpone refcount updates | ||
837 | @@ -XXX,XX +XXX,XX @@ backing_file File name of a base image | ||
838 | backing_fmt Image format of the base image | ||
839 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
840 | encrypt.format Encrypt the image, format choices: 'aes' | ||
841 | +encrypt.key-secret ID of the secret that provides the AES encryption key | ||
842 | cluster_size qcow2 cluster size | ||
843 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
844 | lazy_refcounts Postpone refcount updates | ||
845 | @@ -XXX,XX +XXX,XX @@ backing_file File name of a base image | ||
846 | backing_fmt Image format of the base image | ||
847 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
848 | encrypt.format Encrypt the image, format choices: 'aes' | ||
849 | +encrypt.key-secret ID of the secret that provides the AES encryption key | ||
850 | cluster_size qcow2 cluster size | ||
851 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
852 | lazy_refcounts Postpone refcount updates | ||
853 | @@ -XXX,XX +XXX,XX @@ backing_file File name of a base image | ||
854 | backing_fmt Image format of the base image | ||
855 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
856 | encrypt.format Encrypt the image, format choices: 'aes' | ||
857 | +encrypt.key-secret ID of the secret that provides the AES encryption key | ||
858 | cluster_size qcow2 cluster size | ||
859 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
860 | lazy_refcounts Postpone refcount updates | ||
861 | @@ -XXX,XX +XXX,XX @@ backing_file File name of a base image | ||
862 | backing_fmt Image format of the base image | ||
863 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
864 | encrypt.format Encrypt the image, format choices: 'aes' | ||
865 | +encrypt.key-secret ID of the secret that provides the AES encryption key | ||
866 | cluster_size qcow2 cluster size | ||
867 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
868 | lazy_refcounts Postpone refcount updates | ||
869 | @@ -XXX,XX +XXX,XX @@ backing_file File name of a base image | ||
870 | backing_fmt Image format of the base image | ||
871 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
872 | encrypt.format Encrypt the image, format choices: 'aes' | ||
873 | +encrypt.key-secret ID of the secret that provides the AES encryption key | ||
874 | cluster_size qcow2 cluster size | ||
875 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
876 | lazy_refcounts Postpone refcount updates | ||
877 | diff --git a/tests/qemu-iotests/087 b/tests/qemu-iotests/087 | ||
878 | index XXXXXXX..XXXXXXX 100755 | ||
879 | --- a/tests/qemu-iotests/087 | ||
880 | +++ b/tests/qemu-iotests/087 | ||
881 | @@ -XXX,XX +XXX,XX @@ echo | ||
882 | echo === Encrypted image === | ||
883 | echo | ||
884 | |||
885 | -_make_test_img -o encryption=on $size | ||
886 | -run_qemu -S <<EOF | ||
887 | +_make_test_img --object secret,id=sec0,data=123456 -o encryption=on,encrypt.key-secret=sec0 $size | ||
888 | +run_qemu <<EOF | ||
889 | { "execute": "qmp_capabilities" } | ||
890 | -{ "execute": "blockdev-add", | ||
891 | +{ "execute": "object-add", | ||
892 | "arguments": { | ||
893 | - "driver": "$IMGFMT", | ||
894 | - "node-name": "disk", | ||
895 | - "file": { | ||
896 | - "driver": "file", | ||
897 | - "filename": "$TEST_IMG" | ||
898 | + "qom-type": "secret", | ||
899 | + "id": "sec0", | ||
900 | + "props": { | ||
901 | + "data": "123456" | ||
902 | } | ||
903 | - } | ||
904 | } | ||
905 | -{ "execute": "quit" } | ||
906 | -EOF | ||
907 | - | ||
908 | -run_qemu <<EOF | ||
909 | -{ "execute": "qmp_capabilities" } | ||
910 | +} | ||
911 | { "execute": "blockdev-add", | ||
912 | "arguments": { | ||
913 | "driver": "$IMGFMT", | ||
914 | @@ -XXX,XX +XXX,XX @@ run_qemu <<EOF | ||
915 | "file": { | ||
916 | "driver": "file", | ||
917 | "filename": "$TEST_IMG" | ||
918 | + }, | ||
919 | + "encrypt": { | ||
920 | + "format": "aes", | ||
921 | + "key-secret": "sec0" | ||
922 | } | ||
923 | } | ||
924 | } | ||
925 | @@ -XXX,XX +XXX,XX @@ echo | ||
926 | echo === Missing driver === | ||
927 | echo | ||
928 | |||
929 | -_make_test_img -o encryption=on $size | ||
930 | +_make_test_img --object secret,id=sec0,data=123456 -o encryption=on,encrypt.key-secret=sec0 $size | ||
931 | run_qemu -S <<EOF | ||
932 | { "execute": "qmp_capabilities" } | ||
933 | { "execute": "blockdev-add", | ||
934 | diff --git a/tests/qemu-iotests/087.out b/tests/qemu-iotests/087.out | ||
935 | index XXXXXXX..XXXXXXX 100644 | ||
936 | --- a/tests/qemu-iotests/087.out | ||
937 | +++ b/tests/qemu-iotests/087.out | ||
938 | @@ -XXX,XX +XXX,XX @@ QMP_VERSION | ||
939 | |||
940 | === Encrypted image === | ||
941 | |||
942 | -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on | ||
943 | -Testing: -S | ||
944 | -QMP_VERSION | ||
945 | -{"return": {}} | ||
946 | -{"error": {"class": "GenericError", "desc": "Use of AES-CBC encrypted IMGFMT images is no longer supported in system emulators"}} | ||
947 | -{"return": {}} | ||
948 | -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} | ||
949 | - | ||
950 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on encrypt.key-secret=sec0 | ||
951 | Testing: | ||
952 | QMP_VERSION | ||
953 | {"return": {}} | ||
954 | +{"return": {}} | ||
955 | {"error": {"class": "GenericError", "desc": "Use of AES-CBC encrypted IMGFMT images is no longer supported in system emulators"}} | ||
956 | {"return": {}} | ||
957 | {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} | ||
958 | @@ -XXX,XX +XXX,XX @@ QMP_VERSION | ||
959 | |||
960 | === Missing driver === | ||
961 | |||
962 | -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on | ||
963 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on encrypt.key-secret=sec0 | ||
964 | Testing: -S | ||
965 | QMP_VERSION | ||
966 | {"return": {}} | ||
967 | diff --git a/tests/qemu-iotests/134 b/tests/qemu-iotests/134 | ||
968 | index XXXXXXX..XXXXXXX 100755 | ||
969 | --- a/tests/qemu-iotests/134 | ||
970 | +++ b/tests/qemu-iotests/134 | ||
971 | @@ -XXX,XX +XXX,XX @@ _supported_os Linux | ||
972 | |||
973 | |||
974 | size=128M | ||
975 | -IMGOPTS="encryption=on" _make_test_img $size | ||
976 | + | ||
977 | +SECRET="secret,id=sec0,data=astrochicken" | ||
978 | +SECRETALT="secret,id=sec0,data=platypus" | ||
979 | + | ||
980 | +_make_test_img --object $SECRET -o "encryption=on,encrypt.key-secret=sec0" $size | ||
981 | + | ||
982 | +IMGSPEC="driver=$IMGFMT,file.filename=$TEST_IMG,encrypt.key-secret=sec0" | ||
983 | + | ||
984 | +QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT | ||
985 | |||
986 | echo | ||
987 | echo "== reading whole image ==" | ||
988 | -echo "astrochicken" | $QEMU_IO -c "read 0 $size" "$TEST_IMG" | _filter_qemu_io | _filter_testdir | ||
989 | +$QEMU_IO --object $SECRET -c "read 0 $size" --image-opts $IMGSPEC | _filter_qemu_io | _filter_testdir | ||
990 | |||
991 | echo | ||
992 | echo "== rewriting whole image ==" | ||
993 | -echo "astrochicken" | $QEMU_IO -c "write -P 0xa 0 $size" "$TEST_IMG" | _filter_qemu_io | _filter_testdir | ||
994 | +$QEMU_IO --object $SECRET -c "write -P 0xa 0 $size" --image-opts $IMGSPEC | _filter_qemu_io | _filter_testdir | ||
995 | |||
996 | echo | ||
997 | echo "== verify pattern ==" | ||
998 | -echo "astrochicken" | $QEMU_IO -c "read -P 0xa 0 $size" "$TEST_IMG" | _filter_qemu_io | _filter_testdir | ||
999 | +$QEMU_IO --object $SECRET -c "read -P 0xa 0 $size" --image-opts $IMGSPEC | _filter_qemu_io | _filter_testdir | ||
1000 | |||
1001 | echo | ||
1002 | echo "== verify pattern failure with wrong password ==" | ||
1003 | -echo "platypus" | $QEMU_IO -c "read -P 0xa 0 $size" "$TEST_IMG" | _filter_qemu_io | _filter_testdir | ||
1004 | +$QEMU_IO --object $SECRETALT -c "read -P 0xa 0 $size" --image-opts $IMGSPEC | _filter_qemu_io | _filter_testdir | ||
1005 | |||
1006 | |||
1007 | # success, all done | ||
1008 | diff --git a/tests/qemu-iotests/134.out b/tests/qemu-iotests/134.out | ||
1009 | index XXXXXXX..XXXXXXX 100644 | ||
1010 | --- a/tests/qemu-iotests/134.out | ||
1011 | +++ b/tests/qemu-iotests/134.out | ||
1012 | @@ -XXX,XX +XXX,XX @@ | ||
1013 | QA output created by 134 | ||
1014 | -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on | ||
1015 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on encrypt.key-secret=sec0 | ||
1016 | |||
1017 | == reading whole image == | ||
1018 | -Disk image 'TEST_DIR/t.qcow2' is encrypted. | ||
1019 | -password: | ||
1020 | read 134217728/134217728 bytes at offset 0 | ||
1021 | 128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1022 | |||
1023 | == rewriting whole image == | ||
1024 | -Disk image 'TEST_DIR/t.qcow2' is encrypted. | ||
1025 | -password: | ||
1026 | wrote 134217728/134217728 bytes at offset 0 | ||
1027 | 128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1028 | |||
1029 | == verify pattern == | ||
1030 | -Disk image 'TEST_DIR/t.qcow2' is encrypted. | ||
1031 | -password: | ||
1032 | read 134217728/134217728 bytes at offset 0 | ||
1033 | 128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1034 | |||
1035 | == verify pattern failure with wrong password == | ||
1036 | -Disk image 'TEST_DIR/t.qcow2' is encrypted. | ||
1037 | -password: | ||
1038 | Pattern verification failed at offset 0, 134217728 bytes | ||
1039 | read 134217728/134217728 bytes at offset 0 | ||
1040 | 128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1041 | diff --git a/tests/qemu-iotests/158 b/tests/qemu-iotests/158 | ||
1042 | index XXXXXXX..XXXXXXX 100755 | ||
1043 | --- a/tests/qemu-iotests/158 | ||
1044 | +++ b/tests/qemu-iotests/158 | ||
1045 | @@ -XXX,XX +XXX,XX @@ _supported_os Linux | ||
1046 | |||
1047 | size=128M | ||
1048 | TEST_IMG_BASE=$TEST_IMG.base | ||
1049 | +SECRET="secret,id=sec0,data=astrochicken" | ||
1050 | |||
1051 | TEST_IMG_SAVE=$TEST_IMG | ||
1052 | TEST_IMG=$TEST_IMG_BASE | ||
1053 | echo "== create base ==" | ||
1054 | -IMGOPTS="encryption=on" _make_test_img $size | ||
1055 | +_make_test_img --object $SECRET -o "encryption=on,encrypt.key-secret=sec0" $size | ||
1056 | TEST_IMG=$TEST_IMG_SAVE | ||
1057 | |||
1058 | +IMGSPECBASE="driver=$IMGFMT,file.filename=$TEST_IMG_BASE,encrypt.key-secret=sec0" | ||
1059 | +IMGSPEC="driver=$IMGFMT,file.filename=$TEST_IMG,backing.driver=$IMGFMT,backing.file.filename=$TEST_IMG_BASE,backing.encrypt.key-secret=sec0,encrypt.key-secret=sec0" | ||
1060 | +QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT | ||
1061 | + | ||
1062 | echo | ||
1063 | echo "== writing whole image ==" | ||
1064 | -echo "astrochicken" | $QEMU_IO -c "write -P 0xa 0 $size" "$TEST_IMG_BASE" | _filter_qemu_io | _filter_testdir | ||
1065 | +$QEMU_IO --object $SECRET -c "write -P 0xa 0 $size" --image-opts $IMGSPECBASE | _filter_qemu_io | _filter_testdir | ||
1066 | |||
1067 | echo | ||
1068 | echo "== verify pattern ==" | ||
1069 | -echo "astrochicken" | $QEMU_IO -c "read -P 0xa 0 $size" "$TEST_IMG_BASE" | _filter_qemu_io | _filter_testdir | ||
1070 | +$QEMU_IO --object $SECRET -c "read -P 0xa 0 $size" --image-opts $IMGSPECBASE | _filter_qemu_io | _filter_testdir | ||
1071 | |||
1072 | echo "== create overlay ==" | ||
1073 | -IMGOPTS="encryption=on" _make_test_img -b "$TEST_IMG_BASE" $size | ||
1074 | +_make_test_img --object $SECRET -o "encryption=on,encrypt.key-secret=sec0" -b "$TEST_IMG_BASE" $size | ||
1075 | |||
1076 | echo | ||
1077 | echo "== writing part of a cluster ==" | ||
1078 | -echo "astrochicken" | $QEMU_IO -c "write -P 0xe 0 1024" "$TEST_IMG" | _filter_qemu_io | _filter_testdir | ||
1079 | +$QEMU_IO --object $SECRET -c "write -P 0xe 0 1024" --image-opts $IMGSPEC | _filter_qemu_io | _filter_testdir | ||
1080 | |||
1081 | echo | ||
1082 | echo "== verify pattern ==" | ||
1083 | -echo "astrochicken" | $QEMU_IO -c "read -P 0xe 0 1024" "$TEST_IMG" | _filter_qemu_io | _filter_testdir | ||
1084 | +$QEMU_IO --object $SECRET -c "read -P 0xe 0 1024" --image-opts $IMGSPEC | _filter_qemu_io | _filter_testdir | ||
1085 | echo | ||
1086 | echo "== verify pattern ==" | ||
1087 | -echo "astrochicken" | $QEMU_IO -c "read -P 0xa 1024 64512" "$TEST_IMG" | _filter_qemu_io | _filter_testdir | ||
1088 | +$QEMU_IO --object $SECRET -c "read -P 0xa 1024 64512" --image-opts $IMGSPEC | _filter_qemu_io | _filter_testdir | ||
1089 | |||
1090 | |||
1091 | # success, all done | ||
1092 | diff --git a/tests/qemu-iotests/158.out b/tests/qemu-iotests/158.out | ||
1093 | index XXXXXXX..XXXXXXX 100644 | ||
1094 | --- a/tests/qemu-iotests/158.out | ||
1095 | +++ b/tests/qemu-iotests/158.out | ||
1096 | @@ -XXX,XX +XXX,XX @@ | ||
1097 | QA output created by 158 | ||
1098 | == create base == | ||
1099 | -Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728 encryption=on | ||
1100 | +Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728 encryption=on encrypt.key-secret=sec0 | ||
1101 | |||
1102 | == writing whole image == | ||
1103 | -Disk image 'TEST_DIR/t.qcow2.base' is encrypted. | ||
1104 | -password: | ||
1105 | wrote 134217728/134217728 bytes at offset 0 | ||
1106 | 128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1107 | |||
1108 | == verify pattern == | ||
1109 | -Disk image 'TEST_DIR/t.qcow2.base' is encrypted. | ||
1110 | -password: | ||
1111 | read 134217728/134217728 bytes at offset 0 | ||
1112 | 128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1113 | == create overlay == | ||
1114 | -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base encryption=on | ||
1115 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base encryption=on encrypt.key-secret=sec0 | ||
1116 | |||
1117 | == writing part of a cluster == | ||
1118 | -Disk image 'TEST_DIR/t.qcow2' is encrypted. | ||
1119 | -password: | ||
1120 | wrote 1024/1024 bytes at offset 0 | ||
1121 | 1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1122 | |||
1123 | == verify pattern == | ||
1124 | -Disk image 'TEST_DIR/t.qcow2' is encrypted. | ||
1125 | -password: | ||
1126 | read 1024/1024 bytes at offset 0 | ||
1127 | 1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1128 | |||
1129 | == verify pattern == | ||
1130 | -Disk image 'TEST_DIR/t.qcow2' is encrypted. | ||
1131 | -password: | ||
1132 | read 64512/64512 bytes at offset 1024 | ||
1133 | 63 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1134 | *** done | ||
1135 | diff --git a/tests/qemu-iotests/common b/tests/qemu-iotests/common | ||
1136 | index XXXXXXX..XXXXXXX 100644 | ||
1137 | --- a/tests/qemu-iotests/common | ||
1138 | +++ b/tests/qemu-iotests/common | ||
1139 | @@ -XXX,XX +XXX,XX @@ export IMGPROTO=file | ||
1140 | export IMGOPTS="" | ||
1141 | export CACHEMODE="writeback" | ||
1142 | export QEMU_IO_OPTIONS="" | ||
1143 | +export QEMU_IO_OPTIONS_NO_FMT="" | ||
1144 | export CACHEMODE_IS_DEFAULT=true | ||
1145 | export QEMU_OPTIONS="-nodefaults -machine accel=qtest" | ||
1146 | export VALGRIND_QEMU= | ||
1147 | @@ -XXX,XX +XXX,XX @@ BEGIN { for (t='$start'; t<='$end'; t++) printf "%03d\n",t }' \ | ||
1148 | done | ||
1149 | |||
1150 | # Set qemu-io cache mode with $CACHEMODE we have | ||
1151 | -if [ "$IMGOPTSSYNTAX" = "true" ]; then | ||
1152 | - QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS --cache $CACHEMODE" | ||
1153 | -else | ||
1154 | - QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS -f $IMGFMT --cache $CACHEMODE" | ||
1155 | +QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS --cache $CACHEMODE" | ||
1156 | + | ||
1157 | +QEMU_IO_OPTIONS_NO_FMT="$QEMU_IO_OPTIONS" | ||
1158 | +if [ "$IMGOPTSSYNTAX" != "true" ]; then | ||
1159 | + QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS -f $IMGFMT" | ||
1160 | fi | ||
1161 | |||
1162 | # Set default options for qemu-img create -o if they were not specified | ||
1163 | -- | ||
1164 | 2.9.4 | ||
1165 | |||
1166 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | ||
2 | 1 | ||
3 | Update the qcow2 specification to describe how the LUKS header is | ||
4 | placed inside a qcow2 file, when using LUKS encryption for the | ||
5 | qcow2 payload instead of the legacy AES-CBC encryption | ||
6 | |||
7 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
8 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
9 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
10 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
11 | Message-id: 20170623162419.26068-13-berrange@redhat.com | ||
12 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
13 | --- | ||
14 | docs/interop/qcow2.txt | 103 +++++++++++++++++++++++++++++++++++++++++++++++++ | ||
15 | 1 file changed, 103 insertions(+) | ||
16 | |||
17 | diff --git a/docs/interop/qcow2.txt b/docs/interop/qcow2.txt | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/docs/interop/qcow2.txt | ||
20 | +++ b/docs/interop/qcow2.txt | ||
21 | @@ -XXX,XX +XXX,XX @@ The first cluster of a qcow2 image contains the file header: | ||
22 | 32 - 35: crypt_method | ||
23 | 0 for no encryption | ||
24 | 1 for AES encryption | ||
25 | + 2 for LUKS encryption | ||
26 | |||
27 | 36 - 39: l1_size | ||
28 | Number of entries in the active L1 table | ||
29 | @@ -XXX,XX +XXX,XX @@ be stored. Each extension has a structure like the following: | ||
30 | 0xE2792ACA - Backing file format name | ||
31 | 0x6803f857 - Feature name table | ||
32 | 0x23852875 - Bitmaps extension | ||
33 | + 0x0537be77 - Full disk encryption header pointer | ||
34 | other - Unknown header extension, can be safely | ||
35 | ignored | ||
36 | |||
37 | @@ -XXX,XX +XXX,XX @@ The fields of the bitmaps extension are: | ||
38 | Offset into the image file at which the bitmap directory | ||
39 | starts. Must be aligned to a cluster boundary. | ||
40 | |||
41 | +== Full disk encryption header pointer == | ||
42 | + | ||
43 | +The full disk encryption header must be present if, and only if, the | ||
44 | +'crypt_method' header requires metadata. Currently this is only true | ||
45 | +of the 'LUKS' crypt method. The header extension must be absent for | ||
46 | +other methods. | ||
47 | + | ||
48 | +This header provides the offset at which the crypt method can store | ||
49 | +its additional data, as well as the length of such data. | ||
50 | + | ||
51 | + Byte 0 - 7: Offset into the image file at which the encryption | ||
52 | + header starts in bytes. Must be aligned to a cluster | ||
53 | + boundary. | ||
54 | + Byte 8 - 15: Length of the written encryption header in bytes. | ||
55 | + Note actual space allocated in the qcow2 file may | ||
56 | + be larger than this value, since it will be rounded | ||
57 | + to the nearest multiple of the cluster size. Any | ||
58 | + unused bytes in the allocated space will be initialized | ||
59 | + to 0. | ||
60 | + | ||
61 | +For the LUKS crypt method, the encryption header works as follows. | ||
62 | + | ||
63 | +The first 592 bytes of the header clusters will contain the LUKS | ||
64 | +partition header. This is then followed by the key material data areas. | ||
65 | +The size of the key material data areas is determined by the number of | ||
66 | +stripes in the key slot and key size. Refer to the LUKS format | ||
67 | +specification ('docs/on-disk-format.pdf' in the cryptsetup source | ||
68 | +package) for details of the LUKS partition header format. | ||
69 | + | ||
70 | +In the LUKS partition header, the "payload-offset" field will be | ||
71 | +calculated as normal for the LUKS spec. ie the size of the LUKS | ||
72 | +header, plus key material regions, plus padding, relative to the | ||
73 | +start of the LUKS header. This offset value is not required to be | ||
74 | +qcow2 cluster aligned. Its value is currently never used in the | ||
75 | +context of qcow2, since the qcow2 file format itself defines where | ||
76 | +the real payload offset is, but none the less a valid payload offset | ||
77 | +should always be present. | ||
78 | + | ||
79 | +In the LUKS key slots header, the "key-material-offset" is relative | ||
80 | +to the start of the LUKS header clusters in the qcow2 container, | ||
81 | +not the start of the qcow2 file. | ||
82 | + | ||
83 | +Logically the layout looks like | ||
84 | + | ||
85 | + +-----------------------------+ | ||
86 | + | QCow2 header | | ||
87 | + | QCow2 header extension X | | ||
88 | + | QCow2 header extension FDE | | ||
89 | + | QCow2 header extension ... | | ||
90 | + | QCow2 header extension Z | | ||
91 | + +-----------------------------+ | ||
92 | + | ....other QCow2 tables.... | | ||
93 | + . . | ||
94 | + . . | ||
95 | + +-----------------------------+ | ||
96 | + | +-------------------------+ | | ||
97 | + | | LUKS partition header | | | ||
98 | + | +-------------------------+ | | ||
99 | + | | LUKS key material 1 | | | ||
100 | + | +-------------------------+ | | ||
101 | + | | LUKS key material 2 | | | ||
102 | + | +-------------------------+ | | ||
103 | + | | LUKS key material ... | | | ||
104 | + | +-------------------------+ | | ||
105 | + | | LUKS key material 8 | | | ||
106 | + | +-------------------------+ | | ||
107 | + +-----------------------------+ | ||
108 | + | QCow2 cluster payload | | ||
109 | + . . | ||
110 | + . . | ||
111 | + . . | ||
112 | + | | | ||
113 | + +-----------------------------+ | ||
114 | + | ||
115 | +== Data encryption == | ||
116 | + | ||
117 | +When an encryption method is requested in the header, the image payload | ||
118 | +data must be encrypted/decrypted on every write/read. The image headers | ||
119 | +and metadata are never encrypted. | ||
120 | + | ||
121 | +The algorithms used for encryption vary depending on the method | ||
122 | + | ||
123 | + - AES: | ||
124 | + | ||
125 | + The AES cipher, in CBC mode, with 256 bit keys. | ||
126 | + | ||
127 | + Initialization vectors generated using plain64 method, with | ||
128 | + the virtual disk sector as the input tweak. | ||
129 | + | ||
130 | + This format is no longer supported in QEMU system emulators, due | ||
131 | + to a number of design flaws affecting its security. It is only | ||
132 | + supported in the command line tools for the sake of back compatibility | ||
133 | + and data liberation. | ||
134 | + | ||
135 | + - LUKS: | ||
136 | + | ||
137 | + The algorithms are specified in the LUKS header. | ||
138 | + | ||
139 | + Initialization vectors generated using the method specified | ||
140 | + in the LUKS header, with the physical disk sector as the | ||
141 | + input tweak. | ||
142 | |||
143 | == Host cluster management == | ||
144 | |||
145 | -- | ||
146 | 2.9.4 | ||
147 | |||
148 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | ||
2 | 1 | ||
3 | This adds support for using LUKS as an encryption format | ||
4 | with the qcow2 file, using the new encrypt.format parameter | ||
5 | to request "luks" format. e.g. | ||
6 | |||
7 | # qemu-img create --object secret,data=123456,id=sec0 \ | ||
8 | -f qcow2 -o encrypt.format=luks,encrypt.key-secret=sec0 \ | ||
9 | test.qcow2 10G | ||
10 | |||
11 | The legacy "encryption=on" parameter still results in | ||
12 | creation of the old qcow2 AES format (and is equivalent | ||
13 | to the new 'encryption-format=aes'). e.g. the following are | ||
14 | equivalent: | ||
15 | |||
16 | # qemu-img create --object secret,data=123456,id=sec0 \ | ||
17 | -f qcow2 -o encryption=on,encrypt.key-secret=sec0 \ | ||
18 | test.qcow2 10G | ||
19 | |||
20 | # qemu-img create --object secret,data=123456,id=sec0 \ | ||
21 | -f qcow2 -o encryption-format=aes,encrypt.key-secret=sec0 \ | ||
22 | test.qcow2 10G | ||
23 | |||
24 | With the LUKS format it is necessary to store the LUKS | ||
25 | partition header and key material in the QCow2 file. This | ||
26 | data can be many MB in size, so cannot go into the QCow2 | ||
27 | header region directly. Thus the spec defines a FDE | ||
28 | (Full Disk Encryption) header extension that specifies | ||
29 | the offset of a set of clusters to hold the FDE headers, | ||
30 | as well as the length of that region. The LUKS header is | ||
31 | thus stored in these extra allocated clusters before the | ||
32 | main image payload. | ||
33 | |||
34 | Aside from all the cryptographic differences implied by | ||
35 | use of the LUKS format, there is one further key difference | ||
36 | between the use of legacy AES and LUKS encryption in qcow2. | ||
37 | For LUKS, the initialiazation vectors are generated using | ||
38 | the host physical sector as the input, rather than the | ||
39 | guest virtual sector. This guarantees unique initialization | ||
40 | vectors for all sectors when qcow2 internal snapshots are | ||
41 | used, thus giving stronger protection against watermarking | ||
42 | attacks. | ||
43 | |||
44 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
45 | Message-id: 20170623162419.26068-14-berrange@redhat.com | ||
46 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
47 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
48 | --- | ||
49 | qapi/block-core.json | 5 +- | ||
50 | block/qcow2.h | 9 ++ | ||
51 | block/qcow2-cluster.c | 14 ++- | ||
52 | block/qcow2-refcount.c | 10 ++ | ||
53 | block/qcow2.c | 268 ++++++++++++++++++++++++++++++++++++++------ | ||
54 | tests/qemu-iotests/082.out | 270 ++++++++++++++++++++++++++++++++++++--------- | ||
55 | 6 files changed, 484 insertions(+), 92 deletions(-) | ||
56 | |||
57 | diff --git a/qapi/block-core.json b/qapi/block-core.json | ||
58 | index XXXXXXX..XXXXXXX 100644 | ||
59 | --- a/qapi/block-core.json | ||
60 | +++ b/qapi/block-core.json | ||
61 | @@ -XXX,XX +XXX,XX @@ | ||
62 | # Since: 2.10 | ||
63 | ## | ||
64 | { 'enum': 'BlockdevQcow2EncryptionFormat', | ||
65 | - 'data': [ 'aes' ] } | ||
66 | + 'data': [ 'aes', 'luks' ] } | ||
67 | |||
68 | ## | ||
69 | # @BlockdevQcow2Encryption: | ||
70 | @@ -XXX,XX +XXX,XX @@ | ||
71 | { 'union': 'BlockdevQcow2Encryption', | ||
72 | 'base': { 'format': 'BlockdevQcow2EncryptionFormat' }, | ||
73 | 'discriminator': 'format', | ||
74 | - 'data': { 'aes': 'QCryptoBlockOptionsQCow' } } | ||
75 | + 'data': { 'aes': 'QCryptoBlockOptionsQCow', | ||
76 | + 'luks': 'QCryptoBlockOptionsLUKS'} } | ||
77 | |||
78 | ## | ||
79 | # @BlockdevOptionsQcow2: | ||
80 | diff --git a/block/qcow2.h b/block/qcow2.h | ||
81 | index XXXXXXX..XXXXXXX 100644 | ||
82 | --- a/block/qcow2.h | ||
83 | +++ b/block/qcow2.h | ||
84 | @@ -XXX,XX +XXX,XX @@ | ||
85 | |||
86 | #define QCOW_CRYPT_NONE 0 | ||
87 | #define QCOW_CRYPT_AES 1 | ||
88 | +#define QCOW_CRYPT_LUKS 2 | ||
89 | |||
90 | #define QCOW_MAX_CRYPT_CLUSTERS 32 | ||
91 | #define QCOW_MAX_SNAPSHOTS 65536 | ||
92 | @@ -XXX,XX +XXX,XX @@ typedef struct QCowSnapshot { | ||
93 | struct Qcow2Cache; | ||
94 | typedef struct Qcow2Cache Qcow2Cache; | ||
95 | |||
96 | +typedef struct Qcow2CryptoHeaderExtension { | ||
97 | + uint64_t offset; | ||
98 | + uint64_t length; | ||
99 | +} QEMU_PACKED Qcow2CryptoHeaderExtension; | ||
100 | + | ||
101 | typedef struct Qcow2UnknownHeaderExtension { | ||
102 | uint32_t magic; | ||
103 | uint32_t len; | ||
104 | @@ -XXX,XX +XXX,XX @@ typedef struct BDRVQcow2State { | ||
105 | |||
106 | CoMutex lock; | ||
107 | |||
108 | + Qcow2CryptoHeaderExtension crypto_header; /* QCow2 header extension */ | ||
109 | QCryptoBlockOpenOptions *crypto_opts; /* Disk encryption runtime options */ | ||
110 | QCryptoBlock *crypto; /* Disk encryption format driver */ | ||
111 | + bool crypt_physical_offset; /* Whether to use virtual or physical offset | ||
112 | + for encryption initialization vector tweak */ | ||
113 | uint32_t crypt_method_header; | ||
114 | uint64_t snapshots_offset; | ||
115 | int snapshots_size; | ||
116 | diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c | ||
117 | index XXXXXXX..XXXXXXX 100644 | ||
118 | --- a/block/qcow2-cluster.c | ||
119 | +++ b/block/qcow2-cluster.c | ||
120 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn do_perform_cow_read(BlockDriverState *bs, | ||
121 | |||
122 | static bool coroutine_fn do_perform_cow_encrypt(BlockDriverState *bs, | ||
123 | uint64_t src_cluster_offset, | ||
124 | + uint64_t cluster_offset, | ||
125 | unsigned offset_in_cluster, | ||
126 | uint8_t *buffer, | ||
127 | unsigned bytes) | ||
128 | { | ||
129 | if (bytes && bs->encrypted) { | ||
130 | BDRVQcow2State *s = bs->opaque; | ||
131 | - int64_t sector = (src_cluster_offset + offset_in_cluster) | ||
132 | + int64_t sector = (s->crypt_physical_offset ? | ||
133 | + (cluster_offset + offset_in_cluster) : | ||
134 | + (src_cluster_offset + offset_in_cluster)) | ||
135 | >> BDRV_SECTOR_BITS; | ||
136 | assert((offset_in_cluster & ~BDRV_SECTOR_MASK) == 0); | ||
137 | assert((bytes & ~BDRV_SECTOR_MASK) == 0); | ||
138 | @@ -XXX,XX +XXX,XX @@ static int perform_cow(BlockDriverState *bs, QCowL2Meta *m) | ||
139 | |||
140 | /* Encrypt the data if necessary before writing it */ | ||
141 | if (bs->encrypted) { | ||
142 | - if (!do_perform_cow_encrypt(bs, m->offset, start->offset, | ||
143 | - start_buffer, start->nb_bytes) || | ||
144 | - !do_perform_cow_encrypt(bs, m->offset, end->offset, | ||
145 | - end_buffer, end->nb_bytes)) { | ||
146 | + if (!do_perform_cow_encrypt(bs, m->offset, m->alloc_offset, | ||
147 | + start->offset, start_buffer, | ||
148 | + start->nb_bytes) || | ||
149 | + !do_perform_cow_encrypt(bs, m->offset, m->alloc_offset, | ||
150 | + end->offset, end_buffer, end->nb_bytes)) { | ||
151 | ret = -EIO; | ||
152 | goto fail; | ||
153 | } | ||
154 | diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c | ||
155 | index XXXXXXX..XXXXXXX 100644 | ||
156 | --- a/block/qcow2-refcount.c | ||
157 | +++ b/block/qcow2-refcount.c | ||
158 | @@ -XXX,XX +XXX,XX @@ static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res, | ||
159 | return ret; | ||
160 | } | ||
161 | |||
162 | + /* encryption */ | ||
163 | + if (s->crypto_header.length) { | ||
164 | + ret = inc_refcounts(bs, res, refcount_table, nb_clusters, | ||
165 | + s->crypto_header.offset, | ||
166 | + s->crypto_header.length); | ||
167 | + if (ret < 0) { | ||
168 | + return ret; | ||
169 | + } | ||
170 | + } | ||
171 | + | ||
172 | return check_refblocks(bs, res, fix, rebuild, refcount_table, nb_clusters); | ||
173 | } | ||
174 | |||
175 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
176 | index XXXXXXX..XXXXXXX 100644 | ||
177 | --- a/block/qcow2.c | ||
178 | +++ b/block/qcow2.c | ||
179 | @@ -XXX,XX +XXX,XX @@ typedef struct { | ||
180 | #define QCOW2_EXT_MAGIC_END 0 | ||
181 | #define QCOW2_EXT_MAGIC_BACKING_FORMAT 0xE2792ACA | ||
182 | #define QCOW2_EXT_MAGIC_FEATURE_TABLE 0x6803f857 | ||
183 | +#define QCOW2_EXT_MAGIC_CRYPTO_HEADER 0x0537be77 | ||
184 | |||
185 | static int qcow2_probe(const uint8_t *buf, int buf_size, const char *filename) | ||
186 | { | ||
187 | @@ -XXX,XX +XXX,XX @@ static int qcow2_probe(const uint8_t *buf, int buf_size, const char *filename) | ||
188 | } | ||
189 | |||
190 | |||
191 | +static ssize_t qcow2_crypto_hdr_read_func(QCryptoBlock *block, size_t offset, | ||
192 | + uint8_t *buf, size_t buflen, | ||
193 | + void *opaque, Error **errp) | ||
194 | +{ | ||
195 | + BlockDriverState *bs = opaque; | ||
196 | + BDRVQcow2State *s = bs->opaque; | ||
197 | + ssize_t ret; | ||
198 | + | ||
199 | + if ((offset + buflen) > s->crypto_header.length) { | ||
200 | + error_setg(errp, "Request for data outside of extension header"); | ||
201 | + return -1; | ||
202 | + } | ||
203 | + | ||
204 | + ret = bdrv_pread(bs->file, | ||
205 | + s->crypto_header.offset + offset, buf, buflen); | ||
206 | + if (ret < 0) { | ||
207 | + error_setg_errno(errp, -ret, "Could not read encryption header"); | ||
208 | + return -1; | ||
209 | + } | ||
210 | + return ret; | ||
211 | +} | ||
212 | + | ||
213 | + | ||
214 | +static ssize_t qcow2_crypto_hdr_init_func(QCryptoBlock *block, size_t headerlen, | ||
215 | + void *opaque, Error **errp) | ||
216 | +{ | ||
217 | + BlockDriverState *bs = opaque; | ||
218 | + BDRVQcow2State *s = bs->opaque; | ||
219 | + int64_t ret; | ||
220 | + int64_t clusterlen; | ||
221 | + | ||
222 | + ret = qcow2_alloc_clusters(bs, headerlen); | ||
223 | + if (ret < 0) { | ||
224 | + error_setg_errno(errp, -ret, | ||
225 | + "Cannot allocate cluster for LUKS header size %zu", | ||
226 | + headerlen); | ||
227 | + return -1; | ||
228 | + } | ||
229 | + | ||
230 | + s->crypto_header.length = headerlen; | ||
231 | + s->crypto_header.offset = ret; | ||
232 | + | ||
233 | + /* Zero fill remaining space in cluster so it has predictable | ||
234 | + * content in case of future spec changes */ | ||
235 | + clusterlen = size_to_clusters(s, headerlen) * s->cluster_size; | ||
236 | + ret = bdrv_pwrite_zeroes(bs->file, | ||
237 | + ret + headerlen, | ||
238 | + clusterlen - headerlen, 0); | ||
239 | + if (ret < 0) { | ||
240 | + error_setg_errno(errp, -ret, "Could not zero fill encryption header"); | ||
241 | + return -1; | ||
242 | + } | ||
243 | + | ||
244 | + return ret; | ||
245 | +} | ||
246 | + | ||
247 | + | ||
248 | +static ssize_t qcow2_crypto_hdr_write_func(QCryptoBlock *block, size_t offset, | ||
249 | + const uint8_t *buf, size_t buflen, | ||
250 | + void *opaque, Error **errp) | ||
251 | +{ | ||
252 | + BlockDriverState *bs = opaque; | ||
253 | + BDRVQcow2State *s = bs->opaque; | ||
254 | + ssize_t ret; | ||
255 | + | ||
256 | + if ((offset + buflen) > s->crypto_header.length) { | ||
257 | + error_setg(errp, "Request for data outside of extension header"); | ||
258 | + return -1; | ||
259 | + } | ||
260 | + | ||
261 | + ret = bdrv_pwrite(bs->file, | ||
262 | + s->crypto_header.offset + offset, buf, buflen); | ||
263 | + if (ret < 0) { | ||
264 | + error_setg_errno(errp, -ret, "Could not read encryption header"); | ||
265 | + return -1; | ||
266 | + } | ||
267 | + return ret; | ||
268 | +} | ||
269 | + | ||
270 | + | ||
271 | /* | ||
272 | * read qcow2 extension and fill bs | ||
273 | * start reading from start_offset | ||
274 | @@ -XXX,XX +XXX,XX @@ static int qcow2_probe(const uint8_t *buf, int buf_size, const char *filename) | ||
275 | */ | ||
276 | static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset, | ||
277 | uint64_t end_offset, void **p_feature_table, | ||
278 | - Error **errp) | ||
279 | + int flags, Error **errp) | ||
280 | { | ||
281 | BDRVQcow2State *s = bs->opaque; | ||
282 | QCowExtension ext; | ||
283 | @@ -XXX,XX +XXX,XX @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset, | ||
284 | } | ||
285 | break; | ||
286 | |||
287 | + case QCOW2_EXT_MAGIC_CRYPTO_HEADER: { | ||
288 | + unsigned int cflags = 0; | ||
289 | + if (s->crypt_method_header != QCOW_CRYPT_LUKS) { | ||
290 | + error_setg(errp, "CRYPTO header extension only " | ||
291 | + "expected with LUKS encryption method"); | ||
292 | + return -EINVAL; | ||
293 | + } | ||
294 | + if (ext.len != sizeof(Qcow2CryptoHeaderExtension)) { | ||
295 | + error_setg(errp, "CRYPTO header extension size %u, " | ||
296 | + "but expected size %zu", ext.len, | ||
297 | + sizeof(Qcow2CryptoHeaderExtension)); | ||
298 | + return -EINVAL; | ||
299 | + } | ||
300 | + | ||
301 | + ret = bdrv_pread(bs->file, offset, &s->crypto_header, ext.len); | ||
302 | + if (ret < 0) { | ||
303 | + error_setg_errno(errp, -ret, | ||
304 | + "Unable to read CRYPTO header extension"); | ||
305 | + return ret; | ||
306 | + } | ||
307 | + be64_to_cpus(&s->crypto_header.offset); | ||
308 | + be64_to_cpus(&s->crypto_header.length); | ||
309 | + | ||
310 | + if ((s->crypto_header.offset % s->cluster_size) != 0) { | ||
311 | + error_setg(errp, "Encryption header offset '%" PRIu64 "' is " | ||
312 | + "not a multiple of cluster size '%u'", | ||
313 | + s->crypto_header.offset, s->cluster_size); | ||
314 | + return -EINVAL; | ||
315 | + } | ||
316 | + | ||
317 | + if (flags & BDRV_O_NO_IO) { | ||
318 | + cflags |= QCRYPTO_BLOCK_OPEN_NO_IO; | ||
319 | + } | ||
320 | + s->crypto = qcrypto_block_open(s->crypto_opts, | ||
321 | + qcow2_crypto_hdr_read_func, | ||
322 | + bs, cflags, errp); | ||
323 | + if (!s->crypto) { | ||
324 | + return -EINVAL; | ||
325 | + } | ||
326 | + } break; | ||
327 | + | ||
328 | default: | ||
329 | /* unknown magic - save it in case we need to rewrite the header */ | ||
330 | { | ||
331 | @@ -XXX,XX +XXX,XX @@ static QemuOptsList qcow2_runtime_opts = { | ||
332 | .type = QEMU_OPT_NUMBER, | ||
333 | .help = "Clean unused cache entries after this time (in seconds)", | ||
334 | }, | ||
335 | - BLOCK_CRYPTO_OPT_DEF_QCOW_KEY_SECRET("encrypt."), | ||
336 | + BLOCK_CRYPTO_OPT_DEF_KEY_SECRET("encrypt.", | ||
337 | + "ID of secret providing qcow2 AES key or LUKS passphrase"), | ||
338 | { /* end of list */ } | ||
339 | }, | ||
340 | }; | ||
341 | @@ -XXX,XX +XXX,XX @@ static int qcow2_update_options_prepare(BlockDriverState *bs, | ||
342 | Q_CRYPTO_BLOCK_FORMAT_QCOW, encryptopts, errp); | ||
343 | break; | ||
344 | |||
345 | + case QCOW_CRYPT_LUKS: | ||
346 | + if (encryptfmt && !g_str_equal(encryptfmt, "luks")) { | ||
347 | + error_setg(errp, | ||
348 | + "Header reported 'luks' encryption format but " | ||
349 | + "options specify '%s'", encryptfmt); | ||
350 | + ret = -EINVAL; | ||
351 | + goto fail; | ||
352 | + } | ||
353 | + qdict_del(encryptopts, "format"); | ||
354 | + r->crypto_opts = block_crypto_open_opts_init( | ||
355 | + Q_CRYPTO_BLOCK_FORMAT_LUKS, encryptopts, errp); | ||
356 | + break; | ||
357 | + | ||
358 | default: | ||
359 | error_setg(errp, "Unsupported encryption method %d", | ||
360 | s->crypt_method_header); | ||
361 | @@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags, | ||
362 | if (s->incompatible_features & ~QCOW2_INCOMPAT_MASK) { | ||
363 | void *feature_table = NULL; | ||
364 | qcow2_read_extensions(bs, header.header_length, ext_end, | ||
365 | - &feature_table, NULL); | ||
366 | + &feature_table, flags, NULL); | ||
367 | report_unsupported_feature(errp, feature_table, | ||
368 | s->incompatible_features & | ||
369 | ~QCOW2_INCOMPAT_MASK); | ||
370 | @@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags, | ||
371 | s->refcount_max = UINT64_C(1) << (s->refcount_bits - 1); | ||
372 | s->refcount_max += s->refcount_max - 1; | ||
373 | |||
374 | - if (header.crypt_method > QCOW_CRYPT_AES) { | ||
375 | - error_setg(errp, "Unsupported encryption method: %" PRIu32, | ||
376 | - header.crypt_method); | ||
377 | - ret = -EINVAL; | ||
378 | - goto fail; | ||
379 | - } | ||
380 | s->crypt_method_header = header.crypt_method; | ||
381 | if (s->crypt_method_header) { | ||
382 | if (bdrv_uses_whitelist() && | ||
383 | @@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags, | ||
384 | goto fail; | ||
385 | } | ||
386 | |||
387 | + if (s->crypt_method_header == QCOW_CRYPT_AES) { | ||
388 | + s->crypt_physical_offset = false; | ||
389 | + } else { | ||
390 | + /* Assuming LUKS and any future crypt methods we | ||
391 | + * add will all use physical offsets, due to the | ||
392 | + * fact that the alternative is insecure... */ | ||
393 | + s->crypt_physical_offset = true; | ||
394 | + } | ||
395 | + | ||
396 | bs->encrypted = true; | ||
397 | bs->valid_key = true; | ||
398 | } | ||
399 | @@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags, | ||
400 | |||
401 | /* read qcow2 extensions */ | ||
402 | if (qcow2_read_extensions(bs, header.header_length, ext_end, NULL, | ||
403 | - &local_err)) { | ||
404 | + flags, &local_err)) { | ||
405 | error_propagate(errp, local_err); | ||
406 | ret = -EINVAL; | ||
407 | goto fail; | ||
408 | } | ||
409 | |||
410 | - if (s->crypt_method_header == QCOW_CRYPT_AES) { | ||
411 | - unsigned int cflags = 0; | ||
412 | - if (flags & BDRV_O_NO_IO) { | ||
413 | - cflags |= QCRYPTO_BLOCK_OPEN_NO_IO; | ||
414 | - } | ||
415 | - s->crypto = qcrypto_block_open(s->crypto_opts, NULL, NULL, | ||
416 | - cflags, errp); | ||
417 | - if (!s->crypto) { | ||
418 | + /* qcow2_read_extension may have set up the crypto context | ||
419 | + * if the crypt method needs a header region, some methods | ||
420 | + * don't need header extensions, so must check here | ||
421 | + */ | ||
422 | + if (s->crypt_method_header && !s->crypto) { | ||
423 | + if (s->crypt_method_header == QCOW_CRYPT_AES) { | ||
424 | + unsigned int cflags = 0; | ||
425 | + if (flags & BDRV_O_NO_IO) { | ||
426 | + cflags |= QCRYPTO_BLOCK_OPEN_NO_IO; | ||
427 | + } | ||
428 | + s->crypto = qcrypto_block_open(s->crypto_opts, NULL, NULL, | ||
429 | + cflags, errp); | ||
430 | + if (!s->crypto) { | ||
431 | + ret = -EINVAL; | ||
432 | + goto fail; | ||
433 | + } | ||
434 | + } else if (!(flags & BDRV_O_NO_IO)) { | ||
435 | + error_setg(errp, "Missing CRYPTO header for crypt method %d", | ||
436 | + s->crypt_method_header); | ||
437 | ret = -EINVAL; | ||
438 | goto fail; | ||
439 | } | ||
440 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset, | ||
441 | assert((cur_bytes & (BDRV_SECTOR_SIZE - 1)) == 0); | ||
442 | Error *err = NULL; | ||
443 | if (qcrypto_block_decrypt(s->crypto, | ||
444 | - offset >> BDRV_SECTOR_BITS, | ||
445 | + (s->crypt_physical_offset ? | ||
446 | + cluster_offset + offset_in_cluster : | ||
447 | + offset) >> BDRV_SECTOR_BITS, | ||
448 | cluster_data, | ||
449 | cur_bytes, | ||
450 | &err) < 0) { | ||
451 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset, | ||
452 | QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size); | ||
453 | qemu_iovec_to_buf(&hd_qiov, 0, cluster_data, hd_qiov.size); | ||
454 | |||
455 | - if (qcrypto_block_encrypt(s->crypto, offset >> BDRV_SECTOR_BITS, | ||
456 | + if (qcrypto_block_encrypt(s->crypto, | ||
457 | + (s->crypt_physical_offset ? | ||
458 | + cluster_offset + offset_in_cluster : | ||
459 | + offset) >> BDRV_SECTOR_BITS, | ||
460 | cluster_data, | ||
461 | cur_bytes, &err) < 0) { | ||
462 | error_free(err); | ||
463 | @@ -XXX,XX +XXX,XX @@ int qcow2_update_header(BlockDriverState *bs) | ||
464 | buflen -= ret; | ||
465 | } | ||
466 | |||
467 | + /* Full disk encryption header pointer extension */ | ||
468 | + if (s->crypto_header.offset != 0) { | ||
469 | + cpu_to_be64s(&s->crypto_header.offset); | ||
470 | + cpu_to_be64s(&s->crypto_header.length); | ||
471 | + ret = header_ext_add(buf, QCOW2_EXT_MAGIC_CRYPTO_HEADER, | ||
472 | + &s->crypto_header, sizeof(s->crypto_header), | ||
473 | + buflen); | ||
474 | + be64_to_cpus(&s->crypto_header.offset); | ||
475 | + be64_to_cpus(&s->crypto_header.length); | ||
476 | + if (ret < 0) { | ||
477 | + goto fail; | ||
478 | + } | ||
479 | + buf += ret; | ||
480 | + buflen -= ret; | ||
481 | + } | ||
482 | + | ||
483 | /* Feature table */ | ||
484 | if (s->qcow_version >= 3) { | ||
485 | Qcow2Feature features[] = { | ||
486 | @@ -XXX,XX +XXX,XX @@ static int qcow2_change_backing_file(BlockDriverState *bs, | ||
487 | return qcow2_update_header(bs); | ||
488 | } | ||
489 | |||
490 | +static int qcow2_crypt_method_from_format(const char *encryptfmt) | ||
491 | +{ | ||
492 | + if (g_str_equal(encryptfmt, "luks")) { | ||
493 | + return QCOW_CRYPT_LUKS; | ||
494 | + } else if (g_str_equal(encryptfmt, "aes")) { | ||
495 | + return QCOW_CRYPT_AES; | ||
496 | + } else { | ||
497 | + return -EINVAL; | ||
498 | + } | ||
499 | +} | ||
500 | |||
501 | static int qcow2_set_up_encryption(BlockDriverState *bs, const char *encryptfmt, | ||
502 | QemuOpts *opts, Error **errp) | ||
503 | @@ -XXX,XX +XXX,XX @@ static int qcow2_set_up_encryption(BlockDriverState *bs, const char *encryptfmt, | ||
504 | QCryptoBlock *crypto = NULL; | ||
505 | int ret = -EINVAL; | ||
506 | QDict *options, *encryptopts; | ||
507 | + int fmt; | ||
508 | |||
509 | options = qemu_opts_to_qdict(opts, NULL); | ||
510 | qdict_extract_subqdict(options, &encryptopts, "encrypt."); | ||
511 | QDECREF(options); | ||
512 | |||
513 | - if (!g_str_equal(encryptfmt, "aes")) { | ||
514 | - error_setg(errp, "Unknown encryption format '%s', expected 'aes'", | ||
515 | - encryptfmt); | ||
516 | - ret = -EINVAL; | ||
517 | - goto out; | ||
518 | + fmt = qcow2_crypt_method_from_format(encryptfmt); | ||
519 | + | ||
520 | + switch (fmt) { | ||
521 | + case QCOW_CRYPT_LUKS: | ||
522 | + cryptoopts = block_crypto_create_opts_init( | ||
523 | + Q_CRYPTO_BLOCK_FORMAT_LUKS, encryptopts, errp); | ||
524 | + break; | ||
525 | + case QCOW_CRYPT_AES: | ||
526 | + cryptoopts = block_crypto_create_opts_init( | ||
527 | + Q_CRYPTO_BLOCK_FORMAT_QCOW, encryptopts, errp); | ||
528 | + break; | ||
529 | + default: | ||
530 | + error_setg(errp, "Unknown encryption format '%s'", encryptfmt); | ||
531 | + break; | ||
532 | } | ||
533 | - cryptoopts = block_crypto_create_opts_init( | ||
534 | - Q_CRYPTO_BLOCK_FORMAT_QCOW, encryptopts, errp); | ||
535 | if (!cryptoopts) { | ||
536 | ret = -EINVAL; | ||
537 | goto out; | ||
538 | } | ||
539 | - s->crypt_method_header = QCOW_CRYPT_AES; | ||
540 | + s->crypt_method_header = fmt; | ||
541 | |||
542 | crypto = qcrypto_block_create(cryptoopts, | ||
543 | - NULL, NULL, | ||
544 | + qcow2_crypto_hdr_init_func, | ||
545 | + qcow2_crypto_hdr_write_func, | ||
546 | bs, errp); | ||
547 | if (!crypto) { | ||
548 | ret = -EINVAL; | ||
549 | @@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts, | ||
550 | const char *compat = NULL; | ||
551 | uint64_t cluster_size = s->cluster_size; | ||
552 | bool encrypt; | ||
553 | + int encformat; | ||
554 | int refcount_bits = s->refcount_bits; | ||
555 | Error *local_err = NULL; | ||
556 | int ret; | ||
557 | @@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts, | ||
558 | error_report("Changing the encryption flag is not supported"); | ||
559 | return -ENOTSUP; | ||
560 | } | ||
561 | + } else if (!strcmp(desc->name, BLOCK_OPT_ENCRYPT_FORMAT)) { | ||
562 | + encformat = qcow2_crypt_method_from_format( | ||
563 | + qemu_opt_get(opts, BLOCK_OPT_ENCRYPT_FORMAT)); | ||
564 | + | ||
565 | + if (encformat != s->crypt_method_header) { | ||
566 | + error_report("Changing the encryption format is not supported"); | ||
567 | + return -ENOTSUP; | ||
568 | + } | ||
569 | } else if (!strcmp(desc->name, BLOCK_OPT_CLUSTER_SIZE)) { | ||
570 | cluster_size = qemu_opt_get_size(opts, BLOCK_OPT_CLUSTER_SIZE, | ||
571 | cluster_size); | ||
572 | @@ -XXX,XX +XXX,XX @@ static QemuOptsList qcow2_create_opts = { | ||
573 | { | ||
574 | .name = BLOCK_OPT_ENCRYPT_FORMAT, | ||
575 | .type = QEMU_OPT_STRING, | ||
576 | - .help = "Encrypt the image, format choices: 'aes'", | ||
577 | + .help = "Encrypt the image, format choices: 'aes', 'luks'", | ||
578 | }, | ||
579 | - BLOCK_CRYPTO_OPT_DEF_QCOW_KEY_SECRET("encrypt."), | ||
580 | + BLOCK_CRYPTO_OPT_DEF_KEY_SECRET("encrypt.", | ||
581 | + "ID of secret providing qcow AES key or LUKS passphrase"), | ||
582 | + BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG("encrypt."), | ||
583 | + BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE("encrypt."), | ||
584 | + BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG("encrypt."), | ||
585 | + BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG("encrypt."), | ||
586 | + BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG("encrypt."), | ||
587 | + BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME("encrypt."), | ||
588 | { | ||
589 | .name = BLOCK_OPT_CLUSTER_SIZE, | ||
590 | .type = QEMU_OPT_SIZE, | ||
591 | diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out | ||
592 | index XXXXXXX..XXXXXXX 100644 | ||
593 | --- a/tests/qemu-iotests/082.out | ||
594 | +++ b/tests/qemu-iotests/082.out | ||
595 | @@ -XXX,XX +XXX,XX @@ compat Compatibility level (0.10 or 1.1) | ||
596 | backing_file File name of a base image | ||
597 | backing_fmt Image format of the base image | ||
598 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
599 | -encrypt.format Encrypt the image, format choices: 'aes' | ||
600 | -encrypt.key-secret ID of the secret that provides the AES encryption key | ||
601 | +encrypt.format Encrypt the image, format choices: 'aes', 'luks' | ||
602 | +encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase | ||
603 | +encrypt.cipher-alg Name of encryption cipher algorithm | ||
604 | +encrypt.cipher-mode Name of encryption cipher mode | ||
605 | +encrypt.ivgen-alg Name of IV generator algorithm | ||
606 | +encrypt.ivgen-hash-alg Name of IV generator hash algorithm | ||
607 | +encrypt.hash-alg Name of encryption hash algorithm | ||
608 | +encrypt.iter-time Time to spend in PBKDF in milliseconds | ||
609 | cluster_size qcow2 cluster size | ||
610 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
611 | lazy_refcounts Postpone refcount updates | ||
612 | @@ -XXX,XX +XXX,XX @@ compat Compatibility level (0.10 or 1.1) | ||
613 | backing_file File name of a base image | ||
614 | backing_fmt Image format of the base image | ||
615 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
616 | -encrypt.format Encrypt the image, format choices: 'aes' | ||
617 | -encrypt.key-secret ID of the secret that provides the AES encryption key | ||
618 | +encrypt.format Encrypt the image, format choices: 'aes', 'luks' | ||
619 | +encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase | ||
620 | +encrypt.cipher-alg Name of encryption cipher algorithm | ||
621 | +encrypt.cipher-mode Name of encryption cipher mode | ||
622 | +encrypt.ivgen-alg Name of IV generator algorithm | ||
623 | +encrypt.ivgen-hash-alg Name of IV generator hash algorithm | ||
624 | +encrypt.hash-alg Name of encryption hash algorithm | ||
625 | +encrypt.iter-time Time to spend in PBKDF in milliseconds | ||
626 | cluster_size qcow2 cluster size | ||
627 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
628 | lazy_refcounts Postpone refcount updates | ||
629 | @@ -XXX,XX +XXX,XX @@ compat Compatibility level (0.10 or 1.1) | ||
630 | backing_file File name of a base image | ||
631 | backing_fmt Image format of the base image | ||
632 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
633 | -encrypt.format Encrypt the image, format choices: 'aes' | ||
634 | -encrypt.key-secret ID of the secret that provides the AES encryption key | ||
635 | +encrypt.format Encrypt the image, format choices: 'aes', 'luks' | ||
636 | +encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase | ||
637 | +encrypt.cipher-alg Name of encryption cipher algorithm | ||
638 | +encrypt.cipher-mode Name of encryption cipher mode | ||
639 | +encrypt.ivgen-alg Name of IV generator algorithm | ||
640 | +encrypt.ivgen-hash-alg Name of IV generator hash algorithm | ||
641 | +encrypt.hash-alg Name of encryption hash algorithm | ||
642 | +encrypt.iter-time Time to spend in PBKDF in milliseconds | ||
643 | cluster_size qcow2 cluster size | ||
644 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
645 | lazy_refcounts Postpone refcount updates | ||
646 | @@ -XXX,XX +XXX,XX @@ compat Compatibility level (0.10 or 1.1) | ||
647 | backing_file File name of a base image | ||
648 | backing_fmt Image format of the base image | ||
649 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
650 | -encrypt.format Encrypt the image, format choices: 'aes' | ||
651 | -encrypt.key-secret ID of the secret that provides the AES encryption key | ||
652 | +encrypt.format Encrypt the image, format choices: 'aes', 'luks' | ||
653 | +encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase | ||
654 | +encrypt.cipher-alg Name of encryption cipher algorithm | ||
655 | +encrypt.cipher-mode Name of encryption cipher mode | ||
656 | +encrypt.ivgen-alg Name of IV generator algorithm | ||
657 | +encrypt.ivgen-hash-alg Name of IV generator hash algorithm | ||
658 | +encrypt.hash-alg Name of encryption hash algorithm | ||
659 | +encrypt.iter-time Time to spend in PBKDF in milliseconds | ||
660 | cluster_size qcow2 cluster size | ||
661 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
662 | lazy_refcounts Postpone refcount updates | ||
663 | @@ -XXX,XX +XXX,XX @@ compat Compatibility level (0.10 or 1.1) | ||
664 | backing_file File name of a base image | ||
665 | backing_fmt Image format of the base image | ||
666 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
667 | -encrypt.format Encrypt the image, format choices: 'aes' | ||
668 | -encrypt.key-secret ID of the secret that provides the AES encryption key | ||
669 | +encrypt.format Encrypt the image, format choices: 'aes', 'luks' | ||
670 | +encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase | ||
671 | +encrypt.cipher-alg Name of encryption cipher algorithm | ||
672 | +encrypt.cipher-mode Name of encryption cipher mode | ||
673 | +encrypt.ivgen-alg Name of IV generator algorithm | ||
674 | +encrypt.ivgen-hash-alg Name of IV generator hash algorithm | ||
675 | +encrypt.hash-alg Name of encryption hash algorithm | ||
676 | +encrypt.iter-time Time to spend in PBKDF in milliseconds | ||
677 | cluster_size qcow2 cluster size | ||
678 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
679 | lazy_refcounts Postpone refcount updates | ||
680 | @@ -XXX,XX +XXX,XX @@ compat Compatibility level (0.10 or 1.1) | ||
681 | backing_file File name of a base image | ||
682 | backing_fmt Image format of the base image | ||
683 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
684 | -encrypt.format Encrypt the image, format choices: 'aes' | ||
685 | -encrypt.key-secret ID of the secret that provides the AES encryption key | ||
686 | +encrypt.format Encrypt the image, format choices: 'aes', 'luks' | ||
687 | +encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase | ||
688 | +encrypt.cipher-alg Name of encryption cipher algorithm | ||
689 | +encrypt.cipher-mode Name of encryption cipher mode | ||
690 | +encrypt.ivgen-alg Name of IV generator algorithm | ||
691 | +encrypt.ivgen-hash-alg Name of IV generator hash algorithm | ||
692 | +encrypt.hash-alg Name of encryption hash algorithm | ||
693 | +encrypt.iter-time Time to spend in PBKDF in milliseconds | ||
694 | cluster_size qcow2 cluster size | ||
695 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
696 | lazy_refcounts Postpone refcount updates | ||
697 | @@ -XXX,XX +XXX,XX @@ compat Compatibility level (0.10 or 1.1) | ||
698 | backing_file File name of a base image | ||
699 | backing_fmt Image format of the base image | ||
700 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
701 | -encrypt.format Encrypt the image, format choices: 'aes' | ||
702 | -encrypt.key-secret ID of the secret that provides the AES encryption key | ||
703 | +encrypt.format Encrypt the image, format choices: 'aes', 'luks' | ||
704 | +encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase | ||
705 | +encrypt.cipher-alg Name of encryption cipher algorithm | ||
706 | +encrypt.cipher-mode Name of encryption cipher mode | ||
707 | +encrypt.ivgen-alg Name of IV generator algorithm | ||
708 | +encrypt.ivgen-hash-alg Name of IV generator hash algorithm | ||
709 | +encrypt.hash-alg Name of encryption hash algorithm | ||
710 | +encrypt.iter-time Time to spend in PBKDF in milliseconds | ||
711 | cluster_size qcow2 cluster size | ||
712 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
713 | lazy_refcounts Postpone refcount updates | ||
714 | @@ -XXX,XX +XXX,XX @@ compat Compatibility level (0.10 or 1.1) | ||
715 | backing_file File name of a base image | ||
716 | backing_fmt Image format of the base image | ||
717 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
718 | -encrypt.format Encrypt the image, format choices: 'aes' | ||
719 | -encrypt.key-secret ID of the secret that provides the AES encryption key | ||
720 | +encrypt.format Encrypt the image, format choices: 'aes', 'luks' | ||
721 | +encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase | ||
722 | +encrypt.cipher-alg Name of encryption cipher algorithm | ||
723 | +encrypt.cipher-mode Name of encryption cipher mode | ||
724 | +encrypt.ivgen-alg Name of IV generator algorithm | ||
725 | +encrypt.ivgen-hash-alg Name of IV generator hash algorithm | ||
726 | +encrypt.hash-alg Name of encryption hash algorithm | ||
727 | +encrypt.iter-time Time to spend in PBKDF in milliseconds | ||
728 | cluster_size qcow2 cluster size | ||
729 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
730 | lazy_refcounts Postpone refcount updates | ||
731 | @@ -XXX,XX +XXX,XX @@ compat Compatibility level (0.10 or 1.1) | ||
732 | backing_file File name of a base image | ||
733 | backing_fmt Image format of the base image | ||
734 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
735 | -encrypt.format Encrypt the image, format choices: 'aes' | ||
736 | -encrypt.key-secret ID of the secret that provides the AES encryption key | ||
737 | +encrypt.format Encrypt the image, format choices: 'aes', 'luks' | ||
738 | +encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase | ||
739 | +encrypt.cipher-alg Name of encryption cipher algorithm | ||
740 | +encrypt.cipher-mode Name of encryption cipher mode | ||
741 | +encrypt.ivgen-alg Name of IV generator algorithm | ||
742 | +encrypt.ivgen-hash-alg Name of IV generator hash algorithm | ||
743 | +encrypt.hash-alg Name of encryption hash algorithm | ||
744 | +encrypt.iter-time Time to spend in PBKDF in milliseconds | ||
745 | cluster_size qcow2 cluster size | ||
746 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
747 | lazy_refcounts Postpone refcount updates | ||
748 | @@ -XXX,XX +XXX,XX @@ compat Compatibility level (0.10 or 1.1) | ||
749 | backing_file File name of a base image | ||
750 | backing_fmt Image format of the base image | ||
751 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
752 | -encrypt.format Encrypt the image, format choices: 'aes' | ||
753 | -encrypt.key-secret ID of the secret that provides the AES encryption key | ||
754 | +encrypt.format Encrypt the image, format choices: 'aes', 'luks' | ||
755 | +encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase | ||
756 | +encrypt.cipher-alg Name of encryption cipher algorithm | ||
757 | +encrypt.cipher-mode Name of encryption cipher mode | ||
758 | +encrypt.ivgen-alg Name of IV generator algorithm | ||
759 | +encrypt.ivgen-hash-alg Name of IV generator hash algorithm | ||
760 | +encrypt.hash-alg Name of encryption hash algorithm | ||
761 | +encrypt.iter-time Time to spend in PBKDF in milliseconds | ||
762 | cluster_size qcow2 cluster size | ||
763 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
764 | lazy_refcounts Postpone refcount updates | ||
765 | @@ -XXX,XX +XXX,XX @@ compat Compatibility level (0.10 or 1.1) | ||
766 | backing_file File name of a base image | ||
767 | backing_fmt Image format of the base image | ||
768 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
769 | -encrypt.format Encrypt the image, format choices: 'aes' | ||
770 | -encrypt.key-secret ID of the secret that provides the AES encryption key | ||
771 | +encrypt.format Encrypt the image, format choices: 'aes', 'luks' | ||
772 | +encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase | ||
773 | +encrypt.cipher-alg Name of encryption cipher algorithm | ||
774 | +encrypt.cipher-mode Name of encryption cipher mode | ||
775 | +encrypt.ivgen-alg Name of IV generator algorithm | ||
776 | +encrypt.ivgen-hash-alg Name of IV generator hash algorithm | ||
777 | +encrypt.hash-alg Name of encryption hash algorithm | ||
778 | +encrypt.iter-time Time to spend in PBKDF in milliseconds | ||
779 | cluster_size qcow2 cluster size | ||
780 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
781 | lazy_refcounts Postpone refcount updates | ||
782 | @@ -XXX,XX +XXX,XX @@ compat Compatibility level (0.10 or 1.1) | ||
783 | backing_file File name of a base image | ||
784 | backing_fmt Image format of the base image | ||
785 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
786 | -encrypt.format Encrypt the image, format choices: 'aes' | ||
787 | -encrypt.key-secret ID of the secret that provides the AES encryption key | ||
788 | +encrypt.format Encrypt the image, format choices: 'aes', 'luks' | ||
789 | +encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase | ||
790 | +encrypt.cipher-alg Name of encryption cipher algorithm | ||
791 | +encrypt.cipher-mode Name of encryption cipher mode | ||
792 | +encrypt.ivgen-alg Name of IV generator algorithm | ||
793 | +encrypt.ivgen-hash-alg Name of IV generator hash algorithm | ||
794 | +encrypt.hash-alg Name of encryption hash algorithm | ||
795 | +encrypt.iter-time Time to spend in PBKDF in milliseconds | ||
796 | cluster_size qcow2 cluster size | ||
797 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
798 | lazy_refcounts Postpone refcount updates | ||
799 | @@ -XXX,XX +XXX,XX @@ compat Compatibility level (0.10 or 1.1) | ||
800 | backing_file File name of a base image | ||
801 | backing_fmt Image format of the base image | ||
802 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
803 | -encrypt.format Encrypt the image, format choices: 'aes' | ||
804 | -encrypt.key-secret ID of the secret that provides the AES encryption key | ||
805 | +encrypt.format Encrypt the image, format choices: 'aes', 'luks' | ||
806 | +encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase | ||
807 | +encrypt.cipher-alg Name of encryption cipher algorithm | ||
808 | +encrypt.cipher-mode Name of encryption cipher mode | ||
809 | +encrypt.ivgen-alg Name of IV generator algorithm | ||
810 | +encrypt.ivgen-hash-alg Name of IV generator hash algorithm | ||
811 | +encrypt.hash-alg Name of encryption hash algorithm | ||
812 | +encrypt.iter-time Time to spend in PBKDF in milliseconds | ||
813 | cluster_size qcow2 cluster size | ||
814 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
815 | lazy_refcounts Postpone refcount updates | ||
816 | @@ -XXX,XX +XXX,XX @@ compat Compatibility level (0.10 or 1.1) | ||
817 | backing_file File name of a base image | ||
818 | backing_fmt Image format of the base image | ||
819 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
820 | -encrypt.format Encrypt the image, format choices: 'aes' | ||
821 | -encrypt.key-secret ID of the secret that provides the AES encryption key | ||
822 | +encrypt.format Encrypt the image, format choices: 'aes', 'luks' | ||
823 | +encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase | ||
824 | +encrypt.cipher-alg Name of encryption cipher algorithm | ||
825 | +encrypt.cipher-mode Name of encryption cipher mode | ||
826 | +encrypt.ivgen-alg Name of IV generator algorithm | ||
827 | +encrypt.ivgen-hash-alg Name of IV generator hash algorithm | ||
828 | +encrypt.hash-alg Name of encryption hash algorithm | ||
829 | +encrypt.iter-time Time to spend in PBKDF in milliseconds | ||
830 | cluster_size qcow2 cluster size | ||
831 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
832 | lazy_refcounts Postpone refcount updates | ||
833 | @@ -XXX,XX +XXX,XX @@ compat Compatibility level (0.10 or 1.1) | ||
834 | backing_file File name of a base image | ||
835 | backing_fmt Image format of the base image | ||
836 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
837 | -encrypt.format Encrypt the image, format choices: 'aes' | ||
838 | -encrypt.key-secret ID of the secret that provides the AES encryption key | ||
839 | +encrypt.format Encrypt the image, format choices: 'aes', 'luks' | ||
840 | +encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase | ||
841 | +encrypt.cipher-alg Name of encryption cipher algorithm | ||
842 | +encrypt.cipher-mode Name of encryption cipher mode | ||
843 | +encrypt.ivgen-alg Name of IV generator algorithm | ||
844 | +encrypt.ivgen-hash-alg Name of IV generator hash algorithm | ||
845 | +encrypt.hash-alg Name of encryption hash algorithm | ||
846 | +encrypt.iter-time Time to spend in PBKDF in milliseconds | ||
847 | cluster_size qcow2 cluster size | ||
848 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
849 | lazy_refcounts Postpone refcount updates | ||
850 | @@ -XXX,XX +XXX,XX @@ compat Compatibility level (0.10 or 1.1) | ||
851 | backing_file File name of a base image | ||
852 | backing_fmt Image format of the base image | ||
853 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
854 | -encrypt.format Encrypt the image, format choices: 'aes' | ||
855 | -encrypt.key-secret ID of the secret that provides the AES encryption key | ||
856 | +encrypt.format Encrypt the image, format choices: 'aes', 'luks' | ||
857 | +encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase | ||
858 | +encrypt.cipher-alg Name of encryption cipher algorithm | ||
859 | +encrypt.cipher-mode Name of encryption cipher mode | ||
860 | +encrypt.ivgen-alg Name of IV generator algorithm | ||
861 | +encrypt.ivgen-hash-alg Name of IV generator hash algorithm | ||
862 | +encrypt.hash-alg Name of encryption hash algorithm | ||
863 | +encrypt.iter-time Time to spend in PBKDF in milliseconds | ||
864 | cluster_size qcow2 cluster size | ||
865 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
866 | lazy_refcounts Postpone refcount updates | ||
867 | @@ -XXX,XX +XXX,XX @@ compat Compatibility level (0.10 or 1.1) | ||
868 | backing_file File name of a base image | ||
869 | backing_fmt Image format of the base image | ||
870 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
871 | -encrypt.format Encrypt the image, format choices: 'aes' | ||
872 | -encrypt.key-secret ID of the secret that provides the AES encryption key | ||
873 | +encrypt.format Encrypt the image, format choices: 'aes', 'luks' | ||
874 | +encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase | ||
875 | +encrypt.cipher-alg Name of encryption cipher algorithm | ||
876 | +encrypt.cipher-mode Name of encryption cipher mode | ||
877 | +encrypt.ivgen-alg Name of IV generator algorithm | ||
878 | +encrypt.ivgen-hash-alg Name of IV generator hash algorithm | ||
879 | +encrypt.hash-alg Name of encryption hash algorithm | ||
880 | +encrypt.iter-time Time to spend in PBKDF in milliseconds | ||
881 | cluster_size qcow2 cluster size | ||
882 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
883 | lazy_refcounts Postpone refcount updates | ||
884 | @@ -XXX,XX +XXX,XX @@ compat Compatibility level (0.10 or 1.1) | ||
885 | backing_file File name of a base image | ||
886 | backing_fmt Image format of the base image | ||
887 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
888 | -encrypt.format Encrypt the image, format choices: 'aes' | ||
889 | -encrypt.key-secret ID of the secret that provides the AES encryption key | ||
890 | +encrypt.format Encrypt the image, format choices: 'aes', 'luks' | ||
891 | +encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase | ||
892 | +encrypt.cipher-alg Name of encryption cipher algorithm | ||
893 | +encrypt.cipher-mode Name of encryption cipher mode | ||
894 | +encrypt.ivgen-alg Name of IV generator algorithm | ||
895 | +encrypt.ivgen-hash-alg Name of IV generator hash algorithm | ||
896 | +encrypt.hash-alg Name of encryption hash algorithm | ||
897 | +encrypt.iter-time Time to spend in PBKDF in milliseconds | ||
898 | cluster_size qcow2 cluster size | ||
899 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
900 | lazy_refcounts Postpone refcount updates | ||
901 | @@ -XXX,XX +XXX,XX @@ compat Compatibility level (0.10 or 1.1) | ||
902 | backing_file File name of a base image | ||
903 | backing_fmt Image format of the base image | ||
904 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
905 | -encrypt.format Encrypt the image, format choices: 'aes' | ||
906 | -encrypt.key-secret ID of the secret that provides the AES encryption key | ||
907 | +encrypt.format Encrypt the image, format choices: 'aes', 'luks' | ||
908 | +encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase | ||
909 | +encrypt.cipher-alg Name of encryption cipher algorithm | ||
910 | +encrypt.cipher-mode Name of encryption cipher mode | ||
911 | +encrypt.ivgen-alg Name of IV generator algorithm | ||
912 | +encrypt.ivgen-hash-alg Name of IV generator hash algorithm | ||
913 | +encrypt.hash-alg Name of encryption hash algorithm | ||
914 | +encrypt.iter-time Time to spend in PBKDF in milliseconds | ||
915 | cluster_size qcow2 cluster size | ||
916 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
917 | lazy_refcounts Postpone refcount updates | ||
918 | @@ -XXX,XX +XXX,XX @@ compat Compatibility level (0.10 or 1.1) | ||
919 | backing_file File name of a base image | ||
920 | backing_fmt Image format of the base image | ||
921 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
922 | -encrypt.format Encrypt the image, format choices: 'aes' | ||
923 | -encrypt.key-secret ID of the secret that provides the AES encryption key | ||
924 | +encrypt.format Encrypt the image, format choices: 'aes', 'luks' | ||
925 | +encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase | ||
926 | +encrypt.cipher-alg Name of encryption cipher algorithm | ||
927 | +encrypt.cipher-mode Name of encryption cipher mode | ||
928 | +encrypt.ivgen-alg Name of IV generator algorithm | ||
929 | +encrypt.ivgen-hash-alg Name of IV generator hash algorithm | ||
930 | +encrypt.hash-alg Name of encryption hash algorithm | ||
931 | +encrypt.iter-time Time to spend in PBKDF in milliseconds | ||
932 | cluster_size qcow2 cluster size | ||
933 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
934 | lazy_refcounts Postpone refcount updates | ||
935 | @@ -XXX,XX +XXX,XX @@ compat Compatibility level (0.10 or 1.1) | ||
936 | backing_file File name of a base image | ||
937 | backing_fmt Image format of the base image | ||
938 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
939 | -encrypt.format Encrypt the image, format choices: 'aes' | ||
940 | -encrypt.key-secret ID of the secret that provides the AES encryption key | ||
941 | +encrypt.format Encrypt the image, format choices: 'aes', 'luks' | ||
942 | +encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase | ||
943 | +encrypt.cipher-alg Name of encryption cipher algorithm | ||
944 | +encrypt.cipher-mode Name of encryption cipher mode | ||
945 | +encrypt.ivgen-alg Name of IV generator algorithm | ||
946 | +encrypt.ivgen-hash-alg Name of IV generator hash algorithm | ||
947 | +encrypt.hash-alg Name of encryption hash algorithm | ||
948 | +encrypt.iter-time Time to spend in PBKDF in milliseconds | ||
949 | cluster_size qcow2 cluster size | ||
950 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
951 | lazy_refcounts Postpone refcount updates | ||
952 | @@ -XXX,XX +XXX,XX @@ compat Compatibility level (0.10 or 1.1) | ||
953 | backing_file File name of a base image | ||
954 | backing_fmt Image format of the base image | ||
955 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
956 | -encrypt.format Encrypt the image, format choices: 'aes' | ||
957 | -encrypt.key-secret ID of the secret that provides the AES encryption key | ||
958 | +encrypt.format Encrypt the image, format choices: 'aes', 'luks' | ||
959 | +encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase | ||
960 | +encrypt.cipher-alg Name of encryption cipher algorithm | ||
961 | +encrypt.cipher-mode Name of encryption cipher mode | ||
962 | +encrypt.ivgen-alg Name of IV generator algorithm | ||
963 | +encrypt.ivgen-hash-alg Name of IV generator hash algorithm | ||
964 | +encrypt.hash-alg Name of encryption hash algorithm | ||
965 | +encrypt.iter-time Time to spend in PBKDF in milliseconds | ||
966 | cluster_size qcow2 cluster size | ||
967 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
968 | lazy_refcounts Postpone refcount updates | ||
969 | @@ -XXX,XX +XXX,XX @@ compat Compatibility level (0.10 or 1.1) | ||
970 | backing_file File name of a base image | ||
971 | backing_fmt Image format of the base image | ||
972 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
973 | -encrypt.format Encrypt the image, format choices: 'aes' | ||
974 | -encrypt.key-secret ID of the secret that provides the AES encryption key | ||
975 | +encrypt.format Encrypt the image, format choices: 'aes', 'luks' | ||
976 | +encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase | ||
977 | +encrypt.cipher-alg Name of encryption cipher algorithm | ||
978 | +encrypt.cipher-mode Name of encryption cipher mode | ||
979 | +encrypt.ivgen-alg Name of IV generator algorithm | ||
980 | +encrypt.ivgen-hash-alg Name of IV generator hash algorithm | ||
981 | +encrypt.hash-alg Name of encryption hash algorithm | ||
982 | +encrypt.iter-time Time to spend in PBKDF in milliseconds | ||
983 | cluster_size qcow2 cluster size | ||
984 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
985 | lazy_refcounts Postpone refcount updates | ||
986 | @@ -XXX,XX +XXX,XX @@ compat Compatibility level (0.10 or 1.1) | ||
987 | backing_file File name of a base image | ||
988 | backing_fmt Image format of the base image | ||
989 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
990 | -encrypt.format Encrypt the image, format choices: 'aes' | ||
991 | -encrypt.key-secret ID of the secret that provides the AES encryption key | ||
992 | +encrypt.format Encrypt the image, format choices: 'aes', 'luks' | ||
993 | +encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase | ||
994 | +encrypt.cipher-alg Name of encryption cipher algorithm | ||
995 | +encrypt.cipher-mode Name of encryption cipher mode | ||
996 | +encrypt.ivgen-alg Name of IV generator algorithm | ||
997 | +encrypt.ivgen-hash-alg Name of IV generator hash algorithm | ||
998 | +encrypt.hash-alg Name of encryption hash algorithm | ||
999 | +encrypt.iter-time Time to spend in PBKDF in milliseconds | ||
1000 | cluster_size qcow2 cluster size | ||
1001 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
1002 | lazy_refcounts Postpone refcount updates | ||
1003 | @@ -XXX,XX +XXX,XX @@ compat Compatibility level (0.10 or 1.1) | ||
1004 | backing_file File name of a base image | ||
1005 | backing_fmt Image format of the base image | ||
1006 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
1007 | -encrypt.format Encrypt the image, format choices: 'aes' | ||
1008 | -encrypt.key-secret ID of the secret that provides the AES encryption key | ||
1009 | +encrypt.format Encrypt the image, format choices: 'aes', 'luks' | ||
1010 | +encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase | ||
1011 | +encrypt.cipher-alg Name of encryption cipher algorithm | ||
1012 | +encrypt.cipher-mode Name of encryption cipher mode | ||
1013 | +encrypt.ivgen-alg Name of IV generator algorithm | ||
1014 | +encrypt.ivgen-hash-alg Name of IV generator hash algorithm | ||
1015 | +encrypt.hash-alg Name of encryption hash algorithm | ||
1016 | +encrypt.iter-time Time to spend in PBKDF in milliseconds | ||
1017 | cluster_size qcow2 cluster size | ||
1018 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
1019 | lazy_refcounts Postpone refcount updates | ||
1020 | @@ -XXX,XX +XXX,XX @@ compat Compatibility level (0.10 or 1.1) | ||
1021 | backing_file File name of a base image | ||
1022 | backing_fmt Image format of the base image | ||
1023 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
1024 | -encrypt.format Encrypt the image, format choices: 'aes' | ||
1025 | -encrypt.key-secret ID of the secret that provides the AES encryption key | ||
1026 | +encrypt.format Encrypt the image, format choices: 'aes', 'luks' | ||
1027 | +encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase | ||
1028 | +encrypt.cipher-alg Name of encryption cipher algorithm | ||
1029 | +encrypt.cipher-mode Name of encryption cipher mode | ||
1030 | +encrypt.ivgen-alg Name of IV generator algorithm | ||
1031 | +encrypt.ivgen-hash-alg Name of IV generator hash algorithm | ||
1032 | +encrypt.hash-alg Name of encryption hash algorithm | ||
1033 | +encrypt.iter-time Time to spend in PBKDF in milliseconds | ||
1034 | cluster_size qcow2 cluster size | ||
1035 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
1036 | lazy_refcounts Postpone refcount updates | ||
1037 | @@ -XXX,XX +XXX,XX @@ compat Compatibility level (0.10 or 1.1) | ||
1038 | backing_file File name of a base image | ||
1039 | backing_fmt Image format of the base image | ||
1040 | encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) | ||
1041 | -encrypt.format Encrypt the image, format choices: 'aes' | ||
1042 | -encrypt.key-secret ID of the secret that provides the AES encryption key | ||
1043 | +encrypt.format Encrypt the image, format choices: 'aes', 'luks' | ||
1044 | +encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase | ||
1045 | +encrypt.cipher-alg Name of encryption cipher algorithm | ||
1046 | +encrypt.cipher-mode Name of encryption cipher mode | ||
1047 | +encrypt.ivgen-alg Name of IV generator algorithm | ||
1048 | +encrypt.ivgen-hash-alg Name of IV generator hash algorithm | ||
1049 | +encrypt.hash-alg Name of encryption hash algorithm | ||
1050 | +encrypt.iter-time Time to spend in PBKDF in milliseconds | ||
1051 | cluster_size qcow2 cluster size | ||
1052 | preallocation Preallocation mode (allowed values: off, metadata, falloc, full) | ||
1053 | lazy_refcounts Postpone refcount updates | ||
1054 | -- | ||
1055 | 2.9.4 | ||
1056 | |||
1057 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | ||
2 | 1 | ||
3 | This extends the 087 iotest to cover LUKS encryption when doing | ||
4 | blockdev-add. | ||
5 | |||
6 | Two further tests are added to validate read/write of LUKS | ||
7 | encrypted images with a single file and with a backing file. | ||
8 | |||
9 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
10 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
11 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
12 | Message-id: 20170623162419.26068-15-berrange@redhat.com | ||
13 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
14 | --- | ||
15 | tests/qemu-iotests/087 | 35 ++++++++++++++++++- | ||
16 | tests/qemu-iotests/087.out | 14 +++++++- | ||
17 | tests/qemu-iotests/188 | 76 ++++++++++++++++++++++++++++++++++++++++ | ||
18 | tests/qemu-iotests/188.out | 18 ++++++++++ | ||
19 | tests/qemu-iotests/189 | 86 ++++++++++++++++++++++++++++++++++++++++++++++ | ||
20 | tests/qemu-iotests/189.out | 26 ++++++++++++++ | ||
21 | tests/qemu-iotests/group | 2 ++ | ||
22 | 7 files changed, 255 insertions(+), 2 deletions(-) | ||
23 | create mode 100755 tests/qemu-iotests/188 | ||
24 | create mode 100644 tests/qemu-iotests/188.out | ||
25 | create mode 100755 tests/qemu-iotests/189 | ||
26 | create mode 100644 tests/qemu-iotests/189.out | ||
27 | |||
28 | diff --git a/tests/qemu-iotests/087 b/tests/qemu-iotests/087 | ||
29 | index XXXXXXX..XXXXXXX 100755 | ||
30 | --- a/tests/qemu-iotests/087 | ||
31 | +++ b/tests/qemu-iotests/087 | ||
32 | @@ -XXX,XX +XXX,XX @@ run_qemu <<EOF | ||
33 | EOF | ||
34 | |||
35 | echo | ||
36 | -echo === Encrypted image === | ||
37 | +echo === Encrypted image QCow === | ||
38 | echo | ||
39 | |||
40 | _make_test_img --object secret,id=sec0,data=123456 -o encryption=on,encrypt.key-secret=sec0 $size | ||
41 | @@ -XXX,XX +XXX,XX @@ run_qemu <<EOF | ||
42 | EOF | ||
43 | |||
44 | echo | ||
45 | +echo === Encrypted image LUKS === | ||
46 | +echo | ||
47 | + | ||
48 | +_make_test_img --object secret,id=sec0,data=123456 -o encrypt.format=luks,encrypt.key-secret=sec0 $size | ||
49 | +run_qemu <<EOF | ||
50 | +{ "execute": "qmp_capabilities" } | ||
51 | +{ "execute": "object-add", | ||
52 | + "arguments": { | ||
53 | + "qom-type": "secret", | ||
54 | + "id": "sec0", | ||
55 | + "props": { | ||
56 | + "data": "123456" | ||
57 | + } | ||
58 | + } | ||
59 | +} | ||
60 | +{ "execute": "blockdev-add", | ||
61 | + "arguments": { | ||
62 | + "driver": "$IMGFMT", | ||
63 | + "node-name": "disk", | ||
64 | + "file": { | ||
65 | + "driver": "file", | ||
66 | + "filename": "$TEST_IMG" | ||
67 | + }, | ||
68 | + "encrypt": { | ||
69 | + "format": "luks", | ||
70 | + "key-secret": "sec0" | ||
71 | + } | ||
72 | + } | ||
73 | + } | ||
74 | +{ "execute": "quit" } | ||
75 | +EOF | ||
76 | + | ||
77 | +echo | ||
78 | echo === Missing driver === | ||
79 | echo | ||
80 | |||
81 | diff --git a/tests/qemu-iotests/087.out b/tests/qemu-iotests/087.out | ||
82 | index XXXXXXX..XXXXXXX 100644 | ||
83 | --- a/tests/qemu-iotests/087.out | ||
84 | +++ b/tests/qemu-iotests/087.out | ||
85 | @@ -XXX,XX +XXX,XX @@ QMP_VERSION | ||
86 | {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} | ||
87 | |||
88 | |||
89 | -=== Encrypted image === | ||
90 | +=== Encrypted image QCow === | ||
91 | |||
92 | Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on encrypt.key-secret=sec0 | ||
93 | Testing: | ||
94 | @@ -XXX,XX +XXX,XX @@ QMP_VERSION | ||
95 | {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} | ||
96 | |||
97 | |||
98 | +=== Encrypted image LUKS === | ||
99 | + | ||
100 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encrypt.format=luks encrypt.key-secret=sec0 | ||
101 | +Testing: | ||
102 | +QMP_VERSION | ||
103 | +{"return": {}} | ||
104 | +{"return": {}} | ||
105 | +{"return": {}} | ||
106 | +{"return": {}} | ||
107 | +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} | ||
108 | + | ||
109 | + | ||
110 | === Missing driver === | ||
111 | |||
112 | Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on encrypt.key-secret=sec0 | ||
113 | diff --git a/tests/qemu-iotests/188 b/tests/qemu-iotests/188 | ||
114 | new file mode 100755 | ||
115 | index XXXXXXX..XXXXXXX | ||
116 | --- /dev/null | ||
117 | +++ b/tests/qemu-iotests/188 | ||
118 | @@ -XXX,XX +XXX,XX @@ | ||
119 | +#!/bin/bash | ||
120 | +# | ||
121 | +# Test encrypted read/write using plain bdrv_read/bdrv_write | ||
122 | +# | ||
123 | +# Copyright (C) 2017 Red Hat, Inc. | ||
124 | +# | ||
125 | +# This program is free software; you can redistribute it and/or modify | ||
126 | +# it under the terms of the GNU General Public License as published by | ||
127 | +# the Free Software Foundation; either version 2 of the License, or | ||
128 | +# (at your option) any later version. | ||
129 | +# | ||
130 | +# This program is distributed in the hope that it will be useful, | ||
131 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
132 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
133 | +# GNU General Public License for more details. | ||
134 | +# | ||
135 | +# You should have received a copy of the GNU General Public License | ||
136 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
137 | +# | ||
138 | + | ||
139 | +# creator | ||
140 | +owner=berrange@redhat.com | ||
141 | + | ||
142 | +seq=`basename $0` | ||
143 | +echo "QA output created by $seq" | ||
144 | + | ||
145 | +here=`pwd` | ||
146 | +status=1 # failure is the default! | ||
147 | + | ||
148 | +_cleanup() | ||
149 | +{ | ||
150 | + _cleanup_test_img | ||
151 | +} | ||
152 | +trap "_cleanup; exit \$status" 0 1 2 3 15 | ||
153 | + | ||
154 | +# get standard environment, filters and checks | ||
155 | +. ./common.rc | ||
156 | +. ./common.filter | ||
157 | + | ||
158 | +_supported_fmt qcow2 | ||
159 | +_supported_proto generic | ||
160 | +_supported_os Linux | ||
161 | + | ||
162 | + | ||
163 | +size=16M | ||
164 | + | ||
165 | +SECRET="secret,id=sec0,data=astrochicken" | ||
166 | +SECRETALT="secret,id=sec0,data=platypus" | ||
167 | + | ||
168 | +_make_test_img --object $SECRET -o "encrypt.format=luks,encrypt.key-secret=sec0,encrypt.iter-time=10" $size | ||
169 | + | ||
170 | +IMGSPEC="driver=$IMGFMT,file.filename=$TEST_IMG,encrypt.key-secret=sec0" | ||
171 | + | ||
172 | +QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT | ||
173 | + | ||
174 | +echo | ||
175 | +echo "== reading whole image ==" | ||
176 | +$QEMU_IO --object $SECRET -c "read -P 0 0 $size" --image-opts $IMGSPEC | _filter_qemu_io | _filter_testdir | ||
177 | + | ||
178 | +echo | ||
179 | +echo "== rewriting whole image ==" | ||
180 | +$QEMU_IO --object $SECRET -c "write -P 0xa 0 $size" --image-opts $IMGSPEC | _filter_qemu_io | _filter_testdir | ||
181 | + | ||
182 | +echo | ||
183 | +echo "== verify pattern ==" | ||
184 | +$QEMU_IO --object $SECRET -c "read -P 0xa 0 $size" --image-opts $IMGSPEC | _filter_qemu_io | _filter_testdir | ||
185 | + | ||
186 | +echo | ||
187 | +echo "== verify open failure with wrong password ==" | ||
188 | +$QEMU_IO --object $SECRETALT -c "read -P 0xa 0 $size" --image-opts $IMGSPEC | _filter_qemu_io | _filter_testdir | ||
189 | + | ||
190 | + | ||
191 | +# success, all done | ||
192 | +echo "*** done" | ||
193 | +rm -f $seq.full | ||
194 | +status=0 | ||
195 | diff --git a/tests/qemu-iotests/188.out b/tests/qemu-iotests/188.out | ||
196 | new file mode 100644 | ||
197 | index XXXXXXX..XXXXXXX | ||
198 | --- /dev/null | ||
199 | +++ b/tests/qemu-iotests/188.out | ||
200 | @@ -XXX,XX +XXX,XX @@ | ||
201 | +QA output created by 188 | ||
202 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=16777216 encrypt.format=luks encrypt.key-secret=sec0 encrypt.iter-time=10 | ||
203 | + | ||
204 | +== reading whole image == | ||
205 | +read 16777216/16777216 bytes at offset 0 | ||
206 | +16 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
207 | + | ||
208 | +== rewriting whole image == | ||
209 | +wrote 16777216/16777216 bytes at offset 0 | ||
210 | +16 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
211 | + | ||
212 | +== verify pattern == | ||
213 | +read 16777216/16777216 bytes at offset 0 | ||
214 | +16 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
215 | + | ||
216 | +== verify open failure with wrong password == | ||
217 | +can't open: Invalid password, cannot unlock any keyslot | ||
218 | +*** done | ||
219 | diff --git a/tests/qemu-iotests/189 b/tests/qemu-iotests/189 | ||
220 | new file mode 100755 | ||
221 | index XXXXXXX..XXXXXXX | ||
222 | --- /dev/null | ||
223 | +++ b/tests/qemu-iotests/189 | ||
224 | @@ -XXX,XX +XXX,XX @@ | ||
225 | +#!/bin/bash | ||
226 | +# | ||
227 | +# Test encrypted read/write using backing files | ||
228 | +# | ||
229 | +# Copyright (C) 2017 Red Hat, Inc. | ||
230 | +# | ||
231 | +# This program is free software; you can redistribute it and/or modify | ||
232 | +# it under the terms of the GNU General Public License as published by | ||
233 | +# the Free Software Foundation; either version 2 of the License, or | ||
234 | +# (at your option) any later version. | ||
235 | +# | ||
236 | +# This program is distributed in the hope that it will be useful, | ||
237 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
238 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
239 | +# GNU General Public License for more details. | ||
240 | +# | ||
241 | +# You should have received a copy of the GNU General Public License | ||
242 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
243 | +# | ||
244 | + | ||
245 | +# creator | ||
246 | +owner=berrange@redhat.com | ||
247 | + | ||
248 | +seq=`basename $0` | ||
249 | +echo "QA output created by $seq" | ||
250 | + | ||
251 | +here=`pwd` | ||
252 | +status=1 # failure is the default! | ||
253 | + | ||
254 | +_cleanup() | ||
255 | +{ | ||
256 | + _cleanup_test_img | ||
257 | +} | ||
258 | +trap "_cleanup; exit \$status" 0 1 2 3 15 | ||
259 | + | ||
260 | +# get standard environment, filters and checks | ||
261 | +. ./common.rc | ||
262 | +. ./common.filter | ||
263 | + | ||
264 | +_supported_fmt qcow2 | ||
265 | +_supported_proto generic | ||
266 | +_supported_os Linux | ||
267 | + | ||
268 | + | ||
269 | +size=16M | ||
270 | +TEST_IMG_BASE=$TEST_IMG.base | ||
271 | +SECRET0="secret,id=sec0,data=astrochicken" | ||
272 | +SECRET1="secret,id=sec1,data=furby" | ||
273 | + | ||
274 | +TEST_IMG_SAVE=$TEST_IMG | ||
275 | +TEST_IMG=$TEST_IMG_BASE | ||
276 | +echo "== create base ==" | ||
277 | +_make_test_img --object $SECRET0 -o "encrypt.format=luks,encrypt.key-secret=sec0,encrypt.iter-time=10" $size | ||
278 | +TEST_IMG=$TEST_IMG_SAVE | ||
279 | + | ||
280 | +IMGSPECBASE="driver=$IMGFMT,file.filename=$TEST_IMG_BASE,encrypt.key-secret=sec0" | ||
281 | +IMGSPEC="driver=$IMGFMT,file.filename=$TEST_IMG,backing.driver=$IMGFMT,backing.file.filename=$TEST_IMG_BASE,backing.encrypt.key-secret=sec0,encrypt.key-secret=sec1" | ||
282 | +QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT | ||
283 | + | ||
284 | +echo | ||
285 | +echo "== writing whole image ==" | ||
286 | +$QEMU_IO --object $SECRET0 -c "write -P 0xa 0 $size" --image-opts $IMGSPECBASE | _filter_qemu_io | _filter_testdir | ||
287 | + | ||
288 | +echo | ||
289 | +echo "== verify pattern ==" | ||
290 | +$QEMU_IO --object $SECRET0 -c "read -P 0xa 0 $size" --image-opts $IMGSPECBASE | _filter_qemu_io | _filter_testdir | ||
291 | + | ||
292 | +echo "== create overlay ==" | ||
293 | +_make_test_img --object $SECRET1 -o "encrypt.format=luks,encrypt.key-secret=sec1,encrypt.iter-time=10" -b "$TEST_IMG_BASE" $size | ||
294 | + | ||
295 | +echo | ||
296 | +echo "== writing part of a cluster ==" | ||
297 | +$QEMU_IO --object $SECRET0 --object $SECRET1 -c "write -P 0xe 0 1024" --image-opts $IMGSPEC | _filter_qemu_io | _filter_testdir | ||
298 | + | ||
299 | +echo | ||
300 | +echo "== verify pattern ==" | ||
301 | +$QEMU_IO --object $SECRET0 --object $SECRET1 -c "read -P 0xe 0 1024" --image-opts $IMGSPEC | _filter_qemu_io | _filter_testdir | ||
302 | +echo | ||
303 | +echo "== verify pattern ==" | ||
304 | +$QEMU_IO --object $SECRET0 --object $SECRET1 -c "read -P 0xa 1024 64512" --image-opts $IMGSPEC | _filter_qemu_io | _filter_testdir | ||
305 | + | ||
306 | + | ||
307 | +# success, all done | ||
308 | +echo "*** done" | ||
309 | +rm -f $seq.full | ||
310 | +status=0 | ||
311 | diff --git a/tests/qemu-iotests/189.out b/tests/qemu-iotests/189.out | ||
312 | new file mode 100644 | ||
313 | index XXXXXXX..XXXXXXX | ||
314 | --- /dev/null | ||
315 | +++ b/tests/qemu-iotests/189.out | ||
316 | @@ -XXX,XX +XXX,XX @@ | ||
317 | +QA output created by 189 | ||
318 | +== create base == | ||
319 | +Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=16777216 encrypt.format=luks encrypt.key-secret=sec0 encrypt.iter-time=10 | ||
320 | + | ||
321 | +== writing whole image == | ||
322 | +wrote 16777216/16777216 bytes at offset 0 | ||
323 | +16 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
324 | + | ||
325 | +== verify pattern == | ||
326 | +read 16777216/16777216 bytes at offset 0 | ||
327 | +16 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
328 | +== create overlay == | ||
329 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=16777216 backing_file=TEST_DIR/t.IMGFMT.base encrypt.format=luks encrypt.key-secret=sec1 encrypt.iter-time=10 | ||
330 | + | ||
331 | +== writing part of a cluster == | ||
332 | +wrote 1024/1024 bytes at offset 0 | ||
333 | +1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
334 | + | ||
335 | +== verify pattern == | ||
336 | +read 1024/1024 bytes at offset 0 | ||
337 | +1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
338 | + | ||
339 | +== verify pattern == | ||
340 | +read 64512/64512 bytes at offset 1024 | ||
341 | +63 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
342 | +*** done | ||
343 | diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group | ||
344 | index XXXXXXX..XXXXXXX 100644 | ||
345 | --- a/tests/qemu-iotests/group | ||
346 | +++ b/tests/qemu-iotests/group | ||
347 | @@ -XXX,XX +XXX,XX @@ | ||
348 | 182 rw auto quick | ||
349 | 183 rw auto migration | ||
350 | 185 rw auto | ||
351 | +188 rw auto quick | ||
352 | +189 rw auto quick | ||
353 | -- | ||
354 | 2.9.4 | ||
355 | |||
356 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | ||
2 | 1 | ||
3 | The 138 and 158 iotests exercise the legacy qcow2 aes encryption | ||
4 | code path and they work fine with qcow v1 too. | ||
5 | |||
6 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
7 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
8 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
9 | Message-id: 20170623162419.26068-16-berrange@redhat.com | ||
10 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
11 | --- | ||
12 | tests/qemu-iotests/134 | 2 +- | ||
13 | tests/qemu-iotests/158 | 2 +- | ||
14 | 2 files changed, 2 insertions(+), 2 deletions(-) | ||
15 | |||
16 | diff --git a/tests/qemu-iotests/134 b/tests/qemu-iotests/134 | ||
17 | index XXXXXXX..XXXXXXX 100755 | ||
18 | --- a/tests/qemu-iotests/134 | ||
19 | +++ b/tests/qemu-iotests/134 | ||
20 | @@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15 | ||
21 | . ./common.rc | ||
22 | . ./common.filter | ||
23 | |||
24 | -_supported_fmt qcow2 | ||
25 | +_supported_fmt qcow qcow2 | ||
26 | _supported_proto generic | ||
27 | _unsupported_proto vxhs | ||
28 | _supported_os Linux | ||
29 | diff --git a/tests/qemu-iotests/158 b/tests/qemu-iotests/158 | ||
30 | index XXXXXXX..XXXXXXX 100755 | ||
31 | --- a/tests/qemu-iotests/158 | ||
32 | +++ b/tests/qemu-iotests/158 | ||
33 | @@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15 | ||
34 | . ./common.rc | ||
35 | . ./common.filter | ||
36 | |||
37 | -_supported_fmt qcow2 | ||
38 | +_supported_fmt qcow qcow2 | ||
39 | _supported_proto generic | ||
40 | _unsupported_proto vxhs | ||
41 | _supported_os Linux | ||
42 | -- | ||
43 | 2.9.4 | ||
44 | |||
45 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | ||
2 | 1 | ||
3 | Now that qcow & qcow2 are wired up to get encryption keys | ||
4 | via the QCryptoSecret object, nothing is relying on the | ||
5 | interactive prompting for passwords. All the code related | ||
6 | to password prompting can thus be ripped out. | ||
7 | |||
8 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
9 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
10 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
11 | Message-id: 20170623162419.26068-17-berrange@redhat.com | ||
12 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
13 | --- | ||
14 | qapi-schema.json | 10 +------ | ||
15 | include/monitor/monitor.h | 7 ----- | ||
16 | include/qemu/osdep.h | 2 -- | ||
17 | hmp.c | 31 --------------------- | ||
18 | monitor.c | 68 ----------------------------------------------- | ||
19 | qemu-img.c | 31 --------------------- | ||
20 | qemu-io.c | 20 -------------- | ||
21 | qmp.c | 12 +-------- | ||
22 | util/oslib-posix.c | 66 --------------------------------------------- | ||
23 | util/oslib-win32.c | 24 ----------------- | ||
24 | 10 files changed, 2 insertions(+), 269 deletions(-) | ||
25 | |||
26 | diff --git a/qapi-schema.json b/qapi-schema.json | ||
27 | index XXXXXXX..XXXXXXX 100644 | ||
28 | --- a/qapi-schema.json | ||
29 | +++ b/qapi-schema.json | ||
30 | @@ -XXX,XX +XXX,XX @@ | ||
31 | # Since: 0.14.0 | ||
32 | # | ||
33 | # Returns: If successful, nothing | ||
34 | -# If QEMU was started with an encrypted block device and a key has | ||
35 | -# not yet been set, DeviceEncrypted. | ||
36 | # | ||
37 | # Notes: This command will succeed if the guest is currently running. It | ||
38 | # will also succeed if the guest is in the "inmigrate" state; in | ||
39 | @@ -XXX,XX +XXX,XX @@ | ||
40 | # * This command is stateless, this means that commands that depend | ||
41 | # on state information (such as getfd) might not work | ||
42 | # | ||
43 | -# * Commands that prompt the user for data (eg. 'cont' when the block | ||
44 | -# device is encrypted) don't currently work | ||
45 | +# * Commands that prompt the user for data don't currently work | ||
46 | # | ||
47 | # Example: | ||
48 | # | ||
49 | @@ -XXX,XX +XXX,XX @@ | ||
50 | # | ||
51 | # Returns: Nothing on success. | ||
52 | # If @device is not a valid block device, DeviceNotFound | ||
53 | -# If the new block device is encrypted, DeviceEncrypted. Note that | ||
54 | -# if this error is returned, the device has been opened successfully | ||
55 | -# and an additional call to @block_passwd is required to set the | ||
56 | -# device's password. The behavior of reads and writes to the block | ||
57 | -# device between when these calls are executed is undefined. | ||
58 | # | ||
59 | # Notes: This interface is deprecated, and it is strongly recommended that you | ||
60 | # avoid using it. For changing block devices, use | ||
61 | diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h | ||
62 | index XXXXXXX..XXXXXXX 100644 | ||
63 | --- a/include/monitor/monitor.h | ||
64 | +++ b/include/monitor/monitor.h | ||
65 | @@ -XXX,XX +XXX,XX @@ void monitor_cleanup(void); | ||
66 | int monitor_suspend(Monitor *mon); | ||
67 | void monitor_resume(Monitor *mon); | ||
68 | |||
69 | -int monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs, | ||
70 | - BlockCompletionFunc *completion_cb, | ||
71 | - void *opaque); | ||
72 | -int monitor_read_block_device_key(Monitor *mon, const char *device, | ||
73 | - BlockCompletionFunc *completion_cb, | ||
74 | - void *opaque); | ||
75 | - | ||
76 | int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp); | ||
77 | int monitor_fd_param(Monitor *mon, const char *fdname, Error **errp); | ||
78 | |||
79 | diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h | ||
80 | index XXXXXXX..XXXXXXX 100644 | ||
81 | --- a/include/qemu/osdep.h | ||
82 | +++ b/include/qemu/osdep.h | ||
83 | @@ -XXX,XX +XXX,XX @@ void qemu_set_tty_echo(int fd, bool echo); | ||
84 | void os_mem_prealloc(int fd, char *area, size_t sz, int smp_cpus, | ||
85 | Error **errp); | ||
86 | |||
87 | -int qemu_read_password(char *buf, int buf_size); | ||
88 | - | ||
89 | /** | ||
90 | * qemu_get_pid_name: | ||
91 | * @pid: pid of a process | ||
92 | diff --git a/hmp.c b/hmp.c | ||
93 | index XXXXXXX..XXXXXXX 100644 | ||
94 | --- a/hmp.c | ||
95 | +++ b/hmp.c | ||
96 | @@ -XXX,XX +XXX,XX @@ void hmp_ringbuf_read(Monitor *mon, const QDict *qdict) | ||
97 | g_free(data); | ||
98 | } | ||
99 | |||
100 | -static void hmp_cont_cb(void *opaque, int err) | ||
101 | -{ | ||
102 | - if (!err) { | ||
103 | - qmp_cont(NULL); | ||
104 | - } | ||
105 | -} | ||
106 | - | ||
107 | -static bool key_is_missing(const BlockInfo *bdev) | ||
108 | -{ | ||
109 | - return (bdev->inserted && bdev->inserted->encryption_key_missing); | ||
110 | -} | ||
111 | - | ||
112 | void hmp_cont(Monitor *mon, const QDict *qdict) | ||
113 | { | ||
114 | - BlockInfoList *bdev_list, *bdev; | ||
115 | Error *err = NULL; | ||
116 | |||
117 | - bdev_list = qmp_query_block(NULL); | ||
118 | - for (bdev = bdev_list; bdev; bdev = bdev->next) { | ||
119 | - if (key_is_missing(bdev->value)) { | ||
120 | - monitor_read_block_device_key(mon, bdev->value->device, | ||
121 | - hmp_cont_cb, NULL); | ||
122 | - goto out; | ||
123 | - } | ||
124 | - } | ||
125 | - | ||
126 | qmp_cont(&err); | ||
127 | hmp_handle_error(mon, &err); | ||
128 | - | ||
129 | -out: | ||
130 | - qapi_free_BlockInfoList(bdev_list); | ||
131 | } | ||
132 | |||
133 | void hmp_system_wakeup(Monitor *mon, const QDict *qdict) | ||
134 | @@ -XXX,XX +XXX,XX @@ void hmp_change(Monitor *mon, const QDict *qdict) | ||
135 | qmp_blockdev_change_medium(true, device, false, NULL, target, | ||
136 | !!arg, arg, !!read_only, read_only_mode, | ||
137 | &err); | ||
138 | - if (err && | ||
139 | - error_get_class(err) == ERROR_CLASS_DEVICE_ENCRYPTED) { | ||
140 | - error_free(err); | ||
141 | - monitor_read_block_device_key(mon, device, NULL, NULL); | ||
142 | - return; | ||
143 | - } | ||
144 | } | ||
145 | |||
146 | hmp_handle_error(mon, &err); | ||
147 | diff --git a/monitor.c b/monitor.c | ||
148 | index XXXXXXX..XXXXXXX 100644 | ||
149 | --- a/monitor.c | ||
150 | +++ b/monitor.c | ||
151 | @@ -XXX,XX +XXX,XX @@ void monitor_cleanup(void) | ||
152 | qemu_mutex_unlock(&monitor_lock); | ||
153 | } | ||
154 | |||
155 | -static void bdrv_password_cb(void *opaque, const char *password, | ||
156 | - void *readline_opaque) | ||
157 | -{ | ||
158 | - Monitor *mon = opaque; | ||
159 | - BlockDriverState *bs = readline_opaque; | ||
160 | - int ret = 0; | ||
161 | - Error *local_err = NULL; | ||
162 | - | ||
163 | - bdrv_add_key(bs, password, &local_err); | ||
164 | - if (local_err) { | ||
165 | - error_report_err(local_err); | ||
166 | - ret = -EPERM; | ||
167 | - } | ||
168 | - if (mon->password_completion_cb) | ||
169 | - mon->password_completion_cb(mon->password_opaque, ret); | ||
170 | - | ||
171 | - monitor_read_command(mon, 1); | ||
172 | -} | ||
173 | - | ||
174 | -int monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs, | ||
175 | - BlockCompletionFunc *completion_cb, | ||
176 | - void *opaque) | ||
177 | -{ | ||
178 | - int err; | ||
179 | - | ||
180 | - monitor_printf(mon, "%s (%s) is encrypted.\n", bdrv_get_device_name(bs), | ||
181 | - bdrv_get_encrypted_filename(bs)); | ||
182 | - | ||
183 | - mon->password_completion_cb = completion_cb; | ||
184 | - mon->password_opaque = opaque; | ||
185 | - | ||
186 | - err = monitor_read_password(mon, bdrv_password_cb, bs); | ||
187 | - | ||
188 | - if (err && completion_cb) | ||
189 | - completion_cb(opaque, err); | ||
190 | - | ||
191 | - return err; | ||
192 | -} | ||
193 | - | ||
194 | -int monitor_read_block_device_key(Monitor *mon, const char *device, | ||
195 | - BlockCompletionFunc *completion_cb, | ||
196 | - void *opaque) | ||
197 | -{ | ||
198 | - Error *err = NULL; | ||
199 | - BlockBackend *blk; | ||
200 | - | ||
201 | - blk = blk_by_name(device); | ||
202 | - if (!blk) { | ||
203 | - monitor_printf(mon, "Device not found %s\n", device); | ||
204 | - return -1; | ||
205 | - } | ||
206 | - if (!blk_bs(blk)) { | ||
207 | - monitor_printf(mon, "Device '%s' has no medium\n", device); | ||
208 | - return -1; | ||
209 | - } | ||
210 | - | ||
211 | - bdrv_add_key(blk_bs(blk), NULL, &err); | ||
212 | - if (err) { | ||
213 | - error_free(err); | ||
214 | - return monitor_read_bdrv_key_start(mon, blk_bs(blk), completion_cb, opaque); | ||
215 | - } | ||
216 | - | ||
217 | - if (completion_cb) { | ||
218 | - completion_cb(opaque, 0); | ||
219 | - } | ||
220 | - return 0; | ||
221 | -} | ||
222 | - | ||
223 | QemuOptsList qemu_mon_opts = { | ||
224 | .name = "mon", | ||
225 | .implied_opt_name = "chardev", | ||
226 | diff --git a/qemu-img.c b/qemu-img.c | ||
227 | index XXXXXXX..XXXXXXX 100644 | ||
228 | --- a/qemu-img.c | ||
229 | +++ b/qemu-img.c | ||
230 | @@ -XXX,XX +XXX,XX @@ static int print_block_option_help(const char *filename, const char *fmt) | ||
231 | } | ||
232 | |||
233 | |||
234 | -static int img_open_password(BlockBackend *blk, const char *filename, | ||
235 | - int flags, bool quiet) | ||
236 | -{ | ||
237 | - BlockDriverState *bs; | ||
238 | - char password[256]; | ||
239 | - | ||
240 | - bs = blk_bs(blk); | ||
241 | - if (bdrv_is_encrypted(bs) && bdrv_key_required(bs) && | ||
242 | - !(flags & BDRV_O_NO_IO)) { | ||
243 | - qprintf(quiet, "Disk image '%s' is encrypted.\n", filename); | ||
244 | - if (qemu_read_password(password, sizeof(password)) < 0) { | ||
245 | - error_report("No password given"); | ||
246 | - return -1; | ||
247 | - } | ||
248 | - if (bdrv_set_key(bs, password) < 0) { | ||
249 | - error_report("invalid password"); | ||
250 | - return -1; | ||
251 | - } | ||
252 | - } | ||
253 | - return 0; | ||
254 | -} | ||
255 | - | ||
256 | - | ||
257 | static BlockBackend *img_open_opts(const char *optstr, | ||
258 | QemuOpts *opts, int flags, bool writethrough, | ||
259 | bool quiet, bool force_share) | ||
260 | @@ -XXX,XX +XXX,XX @@ static BlockBackend *img_open_opts(const char *optstr, | ||
261 | } | ||
262 | blk_set_enable_write_cache(blk, !writethrough); | ||
263 | |||
264 | - if (img_open_password(blk, optstr, flags, quiet) < 0) { | ||
265 | - blk_unref(blk); | ||
266 | - return NULL; | ||
267 | - } | ||
268 | return blk; | ||
269 | } | ||
270 | |||
271 | @@ -XXX,XX +XXX,XX @@ static BlockBackend *img_open_file(const char *filename, | ||
272 | } | ||
273 | blk_set_enable_write_cache(blk, !writethrough); | ||
274 | |||
275 | - if (img_open_password(blk, filename, flags, quiet) < 0) { | ||
276 | - blk_unref(blk); | ||
277 | - return NULL; | ||
278 | - } | ||
279 | return blk; | ||
280 | } | ||
281 | |||
282 | diff --git a/qemu-io.c b/qemu-io.c | ||
283 | index XXXXXXX..XXXXXXX 100644 | ||
284 | --- a/qemu-io.c | ||
285 | +++ b/qemu-io.c | ||
286 | @@ -XXX,XX +XXX,XX @@ static int openfile(char *name, int flags, bool writethrough, bool force_share, | ||
287 | QDict *opts) | ||
288 | { | ||
289 | Error *local_err = NULL; | ||
290 | - BlockDriverState *bs; | ||
291 | |||
292 | if (qemuio_blk) { | ||
293 | error_report("file open already, try 'help close'"); | ||
294 | @@ -XXX,XX +XXX,XX @@ static int openfile(char *name, int flags, bool writethrough, bool force_share, | ||
295 | return 1; | ||
296 | } | ||
297 | |||
298 | - bs = blk_bs(qemuio_blk); | ||
299 | - if (bdrv_is_encrypted(bs) && bdrv_key_required(bs)) { | ||
300 | - char password[256]; | ||
301 | - printf("Disk image '%s' is encrypted.\n", name); | ||
302 | - if (qemu_read_password(password, sizeof(password)) < 0) { | ||
303 | - error_report("No password given"); | ||
304 | - goto error; | ||
305 | - } | ||
306 | - if (bdrv_set_key(bs, password) < 0) { | ||
307 | - error_report("invalid password"); | ||
308 | - goto error; | ||
309 | - } | ||
310 | - } | ||
311 | - | ||
312 | blk_set_enable_write_cache(qemuio_blk, !writethrough); | ||
313 | |||
314 | return 0; | ||
315 | - | ||
316 | - error: | ||
317 | - blk_unref(qemuio_blk); | ||
318 | - qemuio_blk = NULL; | ||
319 | - return 1; | ||
320 | } | ||
321 | |||
322 | static void open_help(void) | ||
323 | diff --git a/qmp.c b/qmp.c | ||
324 | index XXXXXXX..XXXXXXX 100644 | ||
325 | --- a/qmp.c | ||
326 | +++ b/qmp.c | ||
327 | @@ -XXX,XX +XXX,XX @@ SpiceInfo *qmp_query_spice(Error **errp) | ||
328 | |||
329 | void qmp_cont(Error **errp) | ||
330 | { | ||
331 | - Error *local_err = NULL; | ||
332 | BlockBackend *blk; | ||
333 | - BlockDriverState *bs; | ||
334 | - BdrvNextIterator it; | ||
335 | + Error *local_err = NULL; | ||
336 | |||
337 | /* if there is a dump in background, we should wait until the dump | ||
338 | * finished */ | ||
339 | @@ -XXX,XX +XXX,XX @@ void qmp_cont(Error **errp) | ||
340 | blk_iostatus_reset(blk); | ||
341 | } | ||
342 | |||
343 | - for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) { | ||
344 | - bdrv_add_key(bs, NULL, &local_err); | ||
345 | - if (local_err) { | ||
346 | - error_propagate(errp, local_err); | ||
347 | - return; | ||
348 | - } | ||
349 | - } | ||
350 | - | ||
351 | /* Continuing after completed migration. Images have been inactivated to | ||
352 | * allow the destination to take control. Need to get control back now. | ||
353 | * | ||
354 | diff --git a/util/oslib-posix.c b/util/oslib-posix.c | ||
355 | index XXXXXXX..XXXXXXX 100644 | ||
356 | --- a/util/oslib-posix.c | ||
357 | +++ b/util/oslib-posix.c | ||
358 | @@ -XXX,XX +XXX,XX @@ void os_mem_prealloc(int fd, char *area, size_t memory, int smp_cpus, | ||
359 | } | ||
360 | |||
361 | |||
362 | -static struct termios oldtty; | ||
363 | - | ||
364 | -static void term_exit(void) | ||
365 | -{ | ||
366 | - tcsetattr(0, TCSANOW, &oldtty); | ||
367 | -} | ||
368 | - | ||
369 | -static void term_init(void) | ||
370 | -{ | ||
371 | - struct termios tty; | ||
372 | - | ||
373 | - tcgetattr(0, &tty); | ||
374 | - oldtty = tty; | ||
375 | - | ||
376 | - tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP | ||
377 | - |INLCR|IGNCR|ICRNL|IXON); | ||
378 | - tty.c_oflag |= OPOST; | ||
379 | - tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN); | ||
380 | - tty.c_cflag &= ~(CSIZE|PARENB); | ||
381 | - tty.c_cflag |= CS8; | ||
382 | - tty.c_cc[VMIN] = 1; | ||
383 | - tty.c_cc[VTIME] = 0; | ||
384 | - | ||
385 | - tcsetattr(0, TCSANOW, &tty); | ||
386 | - | ||
387 | - atexit(term_exit); | ||
388 | -} | ||
389 | - | ||
390 | -int qemu_read_password(char *buf, int buf_size) | ||
391 | -{ | ||
392 | - uint8_t ch; | ||
393 | - int i, ret; | ||
394 | - | ||
395 | - printf("password: "); | ||
396 | - fflush(stdout); | ||
397 | - term_init(); | ||
398 | - i = 0; | ||
399 | - for (;;) { | ||
400 | - ret = read(0, &ch, 1); | ||
401 | - if (ret == -1) { | ||
402 | - if (errno == EAGAIN || errno == EINTR) { | ||
403 | - continue; | ||
404 | - } else { | ||
405 | - break; | ||
406 | - } | ||
407 | - } else if (ret == 0) { | ||
408 | - ret = -1; | ||
409 | - break; | ||
410 | - } else { | ||
411 | - if (ch == '\r' || | ||
412 | - ch == '\n') { | ||
413 | - ret = 0; | ||
414 | - break; | ||
415 | - } | ||
416 | - if (i < (buf_size - 1)) { | ||
417 | - buf[i++] = ch; | ||
418 | - } | ||
419 | - } | ||
420 | - } | ||
421 | - term_exit(); | ||
422 | - buf[i] = '\0'; | ||
423 | - printf("\n"); | ||
424 | - return ret; | ||
425 | -} | ||
426 | - | ||
427 | - | ||
428 | char *qemu_get_pid_name(pid_t pid) | ||
429 | { | ||
430 | char *name = NULL; | ||
431 | diff --git a/util/oslib-win32.c b/util/oslib-win32.c | ||
432 | index XXXXXXX..XXXXXXX 100644 | ||
433 | --- a/util/oslib-win32.c | ||
434 | +++ b/util/oslib-win32.c | ||
435 | @@ -XXX,XX +XXX,XX @@ void os_mem_prealloc(int fd, char *area, size_t memory, int smp_cpus, | ||
436 | } | ||
437 | |||
438 | |||
439 | -/* XXX: put correct support for win32 */ | ||
440 | -int qemu_read_password(char *buf, int buf_size) | ||
441 | -{ | ||
442 | - int c, i; | ||
443 | - | ||
444 | - printf("Password: "); | ||
445 | - fflush(stdout); | ||
446 | - i = 0; | ||
447 | - for (;;) { | ||
448 | - c = getchar(); | ||
449 | - if (c < 0) { | ||
450 | - buf[i] = '\0'; | ||
451 | - return -1; | ||
452 | - } else if (c == '\n') { | ||
453 | - break; | ||
454 | - } else if (i < (buf_size - 1)) { | ||
455 | - buf[i++] = c; | ||
456 | - } | ||
457 | - } | ||
458 | - buf[i] = '\0'; | ||
459 | - return 0; | ||
460 | -} | ||
461 | - | ||
462 | - | ||
463 | char *qemu_get_pid_name(pid_t pid) | ||
464 | { | ||
465 | /* XXX Implement me */ | ||
466 | -- | ||
467 | 2.9.4 | ||
468 | |||
469 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | ||
2 | 1 | ||
3 | While the crypto layer uses a fixed option name "key-secret", | ||
4 | the upper block layer may have a prefix on the options. e.g. | ||
5 | "encrypt.key-secret", in order to avoid clashes between crypto | ||
6 | option names & other block option names. To ensure the crypto | ||
7 | layer can report accurate error messages, we must tell it what | ||
8 | option name prefix was used. | ||
9 | |||
10 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
11 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
12 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
13 | Message-id: 20170623162419.26068-19-berrange@redhat.com | ||
14 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
15 | --- | ||
16 | crypto/blockpriv.h | 2 ++ | ||
17 | include/crypto/block.h | 6 +++++- | ||
18 | block/crypto.c | 4 ++-- | ||
19 | block/qcow.c | 7 ++++--- | ||
20 | block/qcow2.c | 8 ++++---- | ||
21 | crypto/block-luks.c | 8 ++++++-- | ||
22 | crypto/block-qcow.c | 8 ++++++-- | ||
23 | crypto/block.c | 6 ++++-- | ||
24 | tests/test-crypto-block.c | 8 ++++---- | ||
25 | 9 files changed, 37 insertions(+), 20 deletions(-) | ||
26 | |||
27 | diff --git a/crypto/blockpriv.h b/crypto/blockpriv.h | ||
28 | index XXXXXXX..XXXXXXX 100644 | ||
29 | --- a/crypto/blockpriv.h | ||
30 | +++ b/crypto/blockpriv.h | ||
31 | @@ -XXX,XX +XXX,XX @@ struct QCryptoBlock { | ||
32 | struct QCryptoBlockDriver { | ||
33 | int (*open)(QCryptoBlock *block, | ||
34 | QCryptoBlockOpenOptions *options, | ||
35 | + const char *optprefix, | ||
36 | QCryptoBlockReadFunc readfunc, | ||
37 | void *opaque, | ||
38 | unsigned int flags, | ||
39 | @@ -XXX,XX +XXX,XX @@ struct QCryptoBlockDriver { | ||
40 | |||
41 | int (*create)(QCryptoBlock *block, | ||
42 | QCryptoBlockCreateOptions *options, | ||
43 | + const char *optprefix, | ||
44 | QCryptoBlockInitFunc initfunc, | ||
45 | QCryptoBlockWriteFunc writefunc, | ||
46 | void *opaque, | ||
47 | diff --git a/include/crypto/block.h b/include/crypto/block.h | ||
48 | index XXXXXXX..XXXXXXX 100644 | ||
49 | --- a/include/crypto/block.h | ||
50 | +++ b/include/crypto/block.h | ||
51 | @@ -XXX,XX +XXX,XX @@ typedef enum { | ||
52 | /** | ||
53 | * qcrypto_block_open: | ||
54 | * @options: the encryption options | ||
55 | + * @optprefix: name prefix for options | ||
56 | * @readfunc: callback for reading data from the volume | ||
57 | * @opaque: data to pass to @readfunc | ||
58 | * @flags: bitmask of QCryptoBlockOpenFlags values | ||
59 | @@ -XXX,XX +XXX,XX @@ typedef enum { | ||
60 | * Returns: a block encryption format, or NULL on error | ||
61 | */ | ||
62 | QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options, | ||
63 | + const char *optprefix, | ||
64 | QCryptoBlockReadFunc readfunc, | ||
65 | void *opaque, | ||
66 | unsigned int flags, | ||
67 | @@ -XXX,XX +XXX,XX @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options, | ||
68 | |||
69 | /** | ||
70 | * qcrypto_block_create: | ||
71 | - * @format: the encryption format | ||
72 | + * @options: the encryption options | ||
73 | + * @optprefix: name prefix for options | ||
74 | * @initfunc: callback for initializing volume header | ||
75 | * @writefunc: callback for writing data to the volume header | ||
76 | * @opaque: data to pass to @initfunc and @writefunc | ||
77 | @@ -XXX,XX +XXX,XX @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options, | ||
78 | * Returns: a block encryption format, or NULL on error | ||
79 | */ | ||
80 | QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options, | ||
81 | + const char *optprefix, | ||
82 | QCryptoBlockInitFunc initfunc, | ||
83 | QCryptoBlockWriteFunc writefunc, | ||
84 | void *opaque, | ||
85 | diff --git a/block/crypto.c b/block/crypto.c | ||
86 | index XXXXXXX..XXXXXXX 100644 | ||
87 | --- a/block/crypto.c | ||
88 | +++ b/block/crypto.c | ||
89 | @@ -XXX,XX +XXX,XX @@ static int block_crypto_open_generic(QCryptoBlockFormat format, | ||
90 | if (flags & BDRV_O_NO_IO) { | ||
91 | cflags |= QCRYPTO_BLOCK_OPEN_NO_IO; | ||
92 | } | ||
93 | - crypto->block = qcrypto_block_open(open_opts, | ||
94 | + crypto->block = qcrypto_block_open(open_opts, NULL, | ||
95 | block_crypto_read_func, | ||
96 | bs, | ||
97 | cflags, | ||
98 | @@ -XXX,XX +XXX,XX @@ static int block_crypto_create_generic(QCryptoBlockFormat format, | ||
99 | return -1; | ||
100 | } | ||
101 | |||
102 | - crypto = qcrypto_block_create(create_opts, | ||
103 | + crypto = qcrypto_block_create(create_opts, NULL, | ||
104 | block_crypto_init_func, | ||
105 | block_crypto_write_func, | ||
106 | &data, | ||
107 | diff --git a/block/qcow.c b/block/qcow.c | ||
108 | index XXXXXXX..XXXXXXX 100644 | ||
109 | --- a/block/qcow.c | ||
110 | +++ b/block/qcow.c | ||
111 | @@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags, | ||
112 | if (flags & BDRV_O_NO_IO) { | ||
113 | cflags |= QCRYPTO_BLOCK_OPEN_NO_IO; | ||
114 | } | ||
115 | - s->crypto = qcrypto_block_open(crypto_opts, NULL, NULL, | ||
116 | - cflags, errp); | ||
117 | + s->crypto = qcrypto_block_open(crypto_opts, "encrypt.", | ||
118 | + NULL, NULL, cflags, errp); | ||
119 | if (!s->crypto) { | ||
120 | ret = -EINVAL; | ||
121 | goto fail; | ||
122 | @@ -XXX,XX +XXX,XX @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp) | ||
123 | goto exit; | ||
124 | } | ||
125 | |||
126 | - crypto = qcrypto_block_create(crypto_opts, NULL, NULL, NULL, errp); | ||
127 | + crypto = qcrypto_block_create(crypto_opts, "encrypt.", | ||
128 | + NULL, NULL, NULL, errp); | ||
129 | if (!crypto) { | ||
130 | ret = -EINVAL; | ||
131 | goto exit; | ||
132 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
133 | index XXXXXXX..XXXXXXX 100644 | ||
134 | --- a/block/qcow2.c | ||
135 | +++ b/block/qcow2.c | ||
136 | @@ -XXX,XX +XXX,XX @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset, | ||
137 | if (flags & BDRV_O_NO_IO) { | ||
138 | cflags |= QCRYPTO_BLOCK_OPEN_NO_IO; | ||
139 | } | ||
140 | - s->crypto = qcrypto_block_open(s->crypto_opts, | ||
141 | + s->crypto = qcrypto_block_open(s->crypto_opts, "encrypt.", | ||
142 | qcow2_crypto_hdr_read_func, | ||
143 | bs, cflags, errp); | ||
144 | if (!s->crypto) { | ||
145 | @@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags, | ||
146 | if (flags & BDRV_O_NO_IO) { | ||
147 | cflags |= QCRYPTO_BLOCK_OPEN_NO_IO; | ||
148 | } | ||
149 | - s->crypto = qcrypto_block_open(s->crypto_opts, NULL, NULL, | ||
150 | - cflags, errp); | ||
151 | + s->crypto = qcrypto_block_open(s->crypto_opts, "encrypt.", | ||
152 | + NULL, NULL, cflags, errp); | ||
153 | if (!s->crypto) { | ||
154 | ret = -EINVAL; | ||
155 | goto fail; | ||
156 | @@ -XXX,XX +XXX,XX @@ static int qcow2_set_up_encryption(BlockDriverState *bs, const char *encryptfmt, | ||
157 | } | ||
158 | s->crypt_method_header = fmt; | ||
159 | |||
160 | - crypto = qcrypto_block_create(cryptoopts, | ||
161 | + crypto = qcrypto_block_create(cryptoopts, "encrypt.", | ||
162 | qcow2_crypto_hdr_init_func, | ||
163 | qcow2_crypto_hdr_write_func, | ||
164 | bs, errp); | ||
165 | diff --git a/crypto/block-luks.c b/crypto/block-luks.c | ||
166 | index XXXXXXX..XXXXXXX 100644 | ||
167 | --- a/crypto/block-luks.c | ||
168 | +++ b/crypto/block-luks.c | ||
169 | @@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_find_key(QCryptoBlock *block, | ||
170 | static int | ||
171 | qcrypto_block_luks_open(QCryptoBlock *block, | ||
172 | QCryptoBlockOpenOptions *options, | ||
173 | + const char *optprefix, | ||
174 | QCryptoBlockReadFunc readfunc, | ||
175 | void *opaque, | ||
176 | unsigned int flags, | ||
177 | @@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_open(QCryptoBlock *block, | ||
178 | |||
179 | if (!(flags & QCRYPTO_BLOCK_OPEN_NO_IO)) { | ||
180 | if (!options->u.luks.key_secret) { | ||
181 | - error_setg(errp, "Parameter 'key-secret' is required for cipher"); | ||
182 | + error_setg(errp, "Parameter '%skey-secret' is required for cipher", | ||
183 | + optprefix ? optprefix : ""); | ||
184 | return -1; | ||
185 | } | ||
186 | password = qcrypto_secret_lookup_as_utf8( | ||
187 | @@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_uuid_gen(uint8_t *uuidstr) | ||
188 | static int | ||
189 | qcrypto_block_luks_create(QCryptoBlock *block, | ||
190 | QCryptoBlockCreateOptions *options, | ||
191 | + const char *optprefix, | ||
192 | QCryptoBlockInitFunc initfunc, | ||
193 | QCryptoBlockWriteFunc writefunc, | ||
194 | void *opaque, | ||
195 | @@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_create(QCryptoBlock *block, | ||
196 | * be silently ignored, for compatibility with dm-crypt */ | ||
197 | |||
198 | if (!options->u.luks.key_secret) { | ||
199 | - error_setg(errp, "Parameter 'key-secret' is required for cipher"); | ||
200 | + error_setg(errp, "Parameter '%skey-secret' is required for cipher", | ||
201 | + optprefix ? optprefix : ""); | ||
202 | return -1; | ||
203 | } | ||
204 | password = qcrypto_secret_lookup_as_utf8(luks_opts.key_secret, errp); | ||
205 | diff --git a/crypto/block-qcow.c b/crypto/block-qcow.c | ||
206 | index XXXXXXX..XXXXXXX 100644 | ||
207 | --- a/crypto/block-qcow.c | ||
208 | +++ b/crypto/block-qcow.c | ||
209 | @@ -XXX,XX +XXX,XX @@ qcrypto_block_qcow_init(QCryptoBlock *block, | ||
210 | static int | ||
211 | qcrypto_block_qcow_open(QCryptoBlock *block, | ||
212 | QCryptoBlockOpenOptions *options, | ||
213 | + const char *optprefix, | ||
214 | QCryptoBlockReadFunc readfunc G_GNUC_UNUSED, | ||
215 | void *opaque G_GNUC_UNUSED, | ||
216 | unsigned int flags, | ||
217 | @@ -XXX,XX +XXX,XX @@ qcrypto_block_qcow_open(QCryptoBlock *block, | ||
218 | } else { | ||
219 | if (!options->u.qcow.key_secret) { | ||
220 | error_setg(errp, | ||
221 | - "Parameter 'key-secret' is required for cipher"); | ||
222 | + "Parameter '%skey-secret' is required for cipher", | ||
223 | + optprefix ? optprefix : ""); | ||
224 | return -1; | ||
225 | } | ||
226 | return qcrypto_block_qcow_init(block, | ||
227 | @@ -XXX,XX +XXX,XX @@ qcrypto_block_qcow_open(QCryptoBlock *block, | ||
228 | static int | ||
229 | qcrypto_block_qcow_create(QCryptoBlock *block, | ||
230 | QCryptoBlockCreateOptions *options, | ||
231 | + const char *optprefix, | ||
232 | QCryptoBlockInitFunc initfunc G_GNUC_UNUSED, | ||
233 | QCryptoBlockWriteFunc writefunc G_GNUC_UNUSED, | ||
234 | void *opaque G_GNUC_UNUSED, | ||
235 | Error **errp) | ||
236 | { | ||
237 | if (!options->u.qcow.key_secret) { | ||
238 | - error_setg(errp, "Parameter 'key-secret' is required for cipher"); | ||
239 | + error_setg(errp, "Parameter '%skey-secret' is required for cipher", | ||
240 | + optprefix ? optprefix : ""); | ||
241 | return -1; | ||
242 | } | ||
243 | /* QCow2 has no special header, since everything is hardwired */ | ||
244 | diff --git a/crypto/block.c b/crypto/block.c | ||
245 | index XXXXXXX..XXXXXXX 100644 | ||
246 | --- a/crypto/block.c | ||
247 | +++ b/crypto/block.c | ||
248 | @@ -XXX,XX +XXX,XX @@ bool qcrypto_block_has_format(QCryptoBlockFormat format, | ||
249 | |||
250 | |||
251 | QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options, | ||
252 | + const char *optprefix, | ||
253 | QCryptoBlockReadFunc readfunc, | ||
254 | void *opaque, | ||
255 | unsigned int flags, | ||
256 | @@ -XXX,XX +XXX,XX @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options, | ||
257 | |||
258 | block->driver = qcrypto_block_drivers[options->format]; | ||
259 | |||
260 | - if (block->driver->open(block, options, | ||
261 | + if (block->driver->open(block, options, optprefix, | ||
262 | readfunc, opaque, flags, errp) < 0) { | ||
263 | g_free(block); | ||
264 | return NULL; | ||
265 | @@ -XXX,XX +XXX,XX @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options, | ||
266 | |||
267 | |||
268 | QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options, | ||
269 | + const char *optprefix, | ||
270 | QCryptoBlockInitFunc initfunc, | ||
271 | QCryptoBlockWriteFunc writefunc, | ||
272 | void *opaque, | ||
273 | @@ -XXX,XX +XXX,XX @@ QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options, | ||
274 | |||
275 | block->driver = qcrypto_block_drivers[options->format]; | ||
276 | |||
277 | - if (block->driver->create(block, options, initfunc, | ||
278 | + if (block->driver->create(block, options, optprefix, initfunc, | ||
279 | writefunc, opaque, errp) < 0) { | ||
280 | g_free(block); | ||
281 | return NULL; | ||
282 | diff --git a/tests/test-crypto-block.c b/tests/test-crypto-block.c | ||
283 | index XXXXXXX..XXXXXXX 100644 | ||
284 | --- a/tests/test-crypto-block.c | ||
285 | +++ b/tests/test-crypto-block.c | ||
286 | @@ -XXX,XX +XXX,XX @@ static void test_block(gconstpointer opaque) | ||
287 | memset(&header, 0, sizeof(header)); | ||
288 | buffer_init(&header, "header"); | ||
289 | |||
290 | - blk = qcrypto_block_create(data->create_opts, | ||
291 | + blk = qcrypto_block_create(data->create_opts, NULL, | ||
292 | test_block_init_func, | ||
293 | test_block_write_func, | ||
294 | &header, | ||
295 | @@ -XXX,XX +XXX,XX @@ static void test_block(gconstpointer opaque) | ||
296 | object_unparent(sec); | ||
297 | |||
298 | /* Ensure we can't open without the secret */ | ||
299 | - blk = qcrypto_block_open(data->open_opts, | ||
300 | + blk = qcrypto_block_open(data->open_opts, NULL, | ||
301 | test_block_read_func, | ||
302 | &header, | ||
303 | 0, | ||
304 | @@ -XXX,XX +XXX,XX @@ static void test_block(gconstpointer opaque) | ||
305 | g_assert(blk == NULL); | ||
306 | |||
307 | /* Ensure we can't open without the secret, unless NO_IO */ | ||
308 | - blk = qcrypto_block_open(data->open_opts, | ||
309 | + blk = qcrypto_block_open(data->open_opts, NULL, | ||
310 | test_block_read_func, | ||
311 | &header, | ||
312 | QCRYPTO_BLOCK_OPEN_NO_IO, | ||
313 | @@ -XXX,XX +XXX,XX @@ static void test_block(gconstpointer opaque) | ||
314 | |||
315 | /* Now open for real with secret */ | ||
316 | sec = test_block_secret(); | ||
317 | - blk = qcrypto_block_open(data->open_opts, | ||
318 | + blk = qcrypto_block_open(data->open_opts, NULL, | ||
319 | test_block_read_func, | ||
320 | &header, | ||
321 | 0, | ||
322 | -- | ||
323 | 2.9.4 | ||
324 | |||
325 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | ||
2 | 1 | ||
3 | Currently 'qemu-img info' reports a simple "encrypted: yes" | ||
4 | field. This is not very useful now that qcow2 can support | ||
5 | multiple encryption formats. Users want to know which format | ||
6 | is in use and some data related to it. | ||
7 | |||
8 | Wire up usage of the qcrypto_block_get_info() method so that | ||
9 | 'qemu-img info' can report about the encryption format | ||
10 | and parameters in use | ||
11 | |||
12 | $ qemu-img create \ | ||
13 | --object secret,id=sec0,data=123456 \ | ||
14 | -o encrypt.format=luks,encrypt.key-secret=sec0 \ | ||
15 | -f qcow2 demo.qcow2 1G | ||
16 | Formatting 'demo.qcow2', fmt=qcow2 size=1073741824 \ | ||
17 | encryption=off encrypt.format=luks encrypt.key-secret=sec0 \ | ||
18 | cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
19 | |||
20 | $ qemu-img info demo.qcow2 | ||
21 | image: demo.qcow2 | ||
22 | file format: qcow2 | ||
23 | virtual size: 1.0G (1073741824 bytes) | ||
24 | disk size: 480K | ||
25 | encrypted: yes | ||
26 | cluster_size: 65536 | ||
27 | Format specific information: | ||
28 | compat: 1.1 | ||
29 | lazy refcounts: false | ||
30 | refcount bits: 16 | ||
31 | encrypt: | ||
32 | ivgen alg: plain64 | ||
33 | hash alg: sha256 | ||
34 | cipher alg: aes-256 | ||
35 | uuid: 3fa930c4-58c8-4ef7-b3c5-314bb5af21f3 | ||
36 | format: luks | ||
37 | cipher mode: xts | ||
38 | slots: | ||
39 | [0]: | ||
40 | active: true | ||
41 | iters: 1839058 | ||
42 | key offset: 4096 | ||
43 | stripes: 4000 | ||
44 | [1]: | ||
45 | active: false | ||
46 | key offset: 262144 | ||
47 | [2]: | ||
48 | active: false | ||
49 | key offset: 520192 | ||
50 | [3]: | ||
51 | active: false | ||
52 | key offset: 778240 | ||
53 | [4]: | ||
54 | active: false | ||
55 | key offset: 1036288 | ||
56 | [5]: | ||
57 | active: false | ||
58 | key offset: 1294336 | ||
59 | [6]: | ||
60 | active: false | ||
61 | key offset: 1552384 | ||
62 | [7]: | ||
63 | active: false | ||
64 | key offset: 1810432 | ||
65 | payload offset: 2068480 | ||
66 | master key iters: 438487 | ||
67 | corrupt: false | ||
68 | |||
69 | With the legacy "AES" encryption we just report the format | ||
70 | name | ||
71 | |||
72 | $ qemu-img create \ | ||
73 | --object secret,id=sec0,data=123456 \ | ||
74 | -o encrypt.format=aes,encrypt.key-secret=sec0 \ | ||
75 | -f qcow2 demo.qcow2 1G | ||
76 | Formatting 'demo.qcow2', fmt=qcow2 size=1073741824 \ | ||
77 | encryption=off encrypt.format=aes encrypt.key-secret=sec0 \ | ||
78 | cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
79 | |||
80 | $ ./qemu-img info demo.qcow2 | ||
81 | image: demo.qcow2 | ||
82 | file format: qcow2 | ||
83 | virtual size: 1.0G (1073741824 bytes) | ||
84 | disk size: 196K | ||
85 | encrypted: yes | ||
86 | cluster_size: 65536 | ||
87 | Format specific information: | ||
88 | compat: 1.1 | ||
89 | lazy refcounts: false | ||
90 | refcount bits: 16 | ||
91 | encrypt: | ||
92 | format: aes | ||
93 | corrupt: false | ||
94 | |||
95 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
96 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
97 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
98 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
99 | Message-id: 20170623162419.26068-20-berrange@redhat.com | ||
100 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
101 | --- | ||
102 | qapi/block-core.json | 27 ++++++++++++++++++++++++++- | ||
103 | block/qcow2.c | 32 +++++++++++++++++++++++++++++++- | ||
104 | 2 files changed, 57 insertions(+), 2 deletions(-) | ||
105 | |||
106 | diff --git a/qapi/block-core.json b/qapi/block-core.json | ||
107 | index XXXXXXX..XXXXXXX 100644 | ||
108 | --- a/qapi/block-core.json | ||
109 | +++ b/qapi/block-core.json | ||
110 | @@ -XXX,XX +XXX,XX @@ | ||
111 | 'vm-clock-sec': 'int', 'vm-clock-nsec': 'int' } } | ||
112 | |||
113 | ## | ||
114 | +# @ImageInfoSpecificQCow2EncryptionBase: | ||
115 | +# | ||
116 | +# @format: The encryption format | ||
117 | +# | ||
118 | +# Since: 2.10 | ||
119 | +## | ||
120 | +{ 'struct': 'ImageInfoSpecificQCow2EncryptionBase', | ||
121 | + 'data': { 'format': 'BlockdevQcow2EncryptionFormat'}} | ||
122 | + | ||
123 | +## | ||
124 | +# @ImageInfoSpecificQCow2Encryption: | ||
125 | +# | ||
126 | +# Since: 2.10 | ||
127 | +## | ||
128 | +{ 'union': 'ImageInfoSpecificQCow2Encryption', | ||
129 | + 'base': 'ImageInfoSpecificQCow2EncryptionBase', | ||
130 | + 'discriminator': 'format', | ||
131 | + 'data': { 'aes': 'QCryptoBlockInfoQCow', | ||
132 | + 'luks': 'QCryptoBlockInfoLUKS' } } | ||
133 | + | ||
134 | +## | ||
135 | # @ImageInfoSpecificQCow2: | ||
136 | # | ||
137 | # @compat: compatibility level | ||
138 | @@ -XXX,XX +XXX,XX @@ | ||
139 | # | ||
140 | # @refcount-bits: width of a refcount entry in bits (since 2.3) | ||
141 | # | ||
142 | +# @encrypt: details about encryption parameters; only set if image | ||
143 | +# is encrypted (since 2.10) | ||
144 | +# | ||
145 | # Since: 1.7 | ||
146 | ## | ||
147 | { 'struct': 'ImageInfoSpecificQCow2', | ||
148 | @@ -XXX,XX +XXX,XX @@ | ||
149 | 'compat': 'str', | ||
150 | '*lazy-refcounts': 'bool', | ||
151 | '*corrupt': 'bool', | ||
152 | - 'refcount-bits': 'int' | ||
153 | + 'refcount-bits': 'int', | ||
154 | + '*encrypt': 'ImageInfoSpecificQCow2Encryption' | ||
155 | } } | ||
156 | |||
157 | ## | ||
158 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
159 | index XXXXXXX..XXXXXXX 100644 | ||
160 | --- a/block/qcow2.c | ||
161 | +++ b/block/qcow2.c | ||
162 | @@ -XXX,XX +XXX,XX @@ static int qcow2_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) | ||
163 | static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs) | ||
164 | { | ||
165 | BDRVQcow2State *s = bs->opaque; | ||
166 | - ImageInfoSpecific *spec_info = g_new(ImageInfoSpecific, 1); | ||
167 | + ImageInfoSpecific *spec_info; | ||
168 | + QCryptoBlockInfo *encrypt_info = NULL; | ||
169 | |||
170 | + if (s->crypto != NULL) { | ||
171 | + encrypt_info = qcrypto_block_get_info(s->crypto, &error_abort); | ||
172 | + } | ||
173 | + | ||
174 | + spec_info = g_new(ImageInfoSpecific, 1); | ||
175 | *spec_info = (ImageInfoSpecific){ | ||
176 | .type = IMAGE_INFO_SPECIFIC_KIND_QCOW2, | ||
177 | .u.qcow2.data = g_new(ImageInfoSpecificQCow2, 1), | ||
178 | @@ -XXX,XX +XXX,XX @@ static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs) | ||
179 | assert(false); | ||
180 | } | ||
181 | |||
182 | + if (encrypt_info) { | ||
183 | + ImageInfoSpecificQCow2Encryption *qencrypt = | ||
184 | + g_new(ImageInfoSpecificQCow2Encryption, 1); | ||
185 | + switch (encrypt_info->format) { | ||
186 | + case Q_CRYPTO_BLOCK_FORMAT_QCOW: | ||
187 | + qencrypt->format = BLOCKDEV_QCOW2_ENCRYPTION_FORMAT_AES; | ||
188 | + qencrypt->u.aes = encrypt_info->u.qcow; | ||
189 | + break; | ||
190 | + case Q_CRYPTO_BLOCK_FORMAT_LUKS: | ||
191 | + qencrypt->format = BLOCKDEV_QCOW2_ENCRYPTION_FORMAT_LUKS; | ||
192 | + qencrypt->u.luks = encrypt_info->u.luks; | ||
193 | + break; | ||
194 | + default: | ||
195 | + abort(); | ||
196 | + } | ||
197 | + /* Since we did shallow copy above, erase any pointers | ||
198 | + * in the original info */ | ||
199 | + memset(&encrypt_info->u, 0, sizeof(encrypt_info->u)); | ||
200 | + qapi_free_QCryptoBlockInfo(encrypt_info); | ||
201 | + | ||
202 | + spec_info->u.qcow2.data->has_encrypt = true; | ||
203 | + spec_info->u.qcow2.data->encrypt = qencrypt; | ||
204 | + } | ||
205 | + | ||
206 | return spec_info; | ||
207 | } | ||
208 | |||
209 | -- | ||
210 | 2.9.4 | ||
211 | |||
212 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | ||
2 | 1 | ||
3 | Expand the image format docs to cover the new options for | ||
4 | the qcow, qcow2 and luks disk image formats | ||
5 | |||
6 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
7 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
8 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
9 | Message-id: 20170623162419.26068-21-berrange@redhat.com | ||
10 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
11 | --- | ||
12 | qemu-doc.texi | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- | ||
13 | 1 file changed, 115 insertions(+), 8 deletions(-) | ||
14 | |||
15 | diff --git a/qemu-doc.texi b/qemu-doc.texi | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/qemu-doc.texi | ||
18 | +++ b/qemu-doc.texi | ||
19 | @@ -XXX,XX +XXX,XX @@ File name of a base image (see @option{create} subcommand) | ||
20 | @item backing_fmt | ||
21 | Image format of the base image | ||
22 | @item encryption | ||
23 | -If this option is set to @code{on}, the image is encrypted with 128-bit AES-CBC. | ||
24 | +This option is deprecated and equivalent to @code{encrypt.format=aes} | ||
25 | |||
26 | -The use of encryption in qcow and qcow2 images is considered to be flawed by | ||
27 | -modern cryptography standards, suffering from a number of design problems: | ||
28 | +@item encrypt.format | ||
29 | + | ||
30 | +If this is set to @code{luks}, it requests that the qcow2 payload (not | ||
31 | +qcow2 header) be encrypted using the LUKS format. The passphrase to | ||
32 | +use to unlock the LUKS key slot is given by the @code{encrypt.key-secret} | ||
33 | +parameter. LUKS encryption parameters can be tuned with the other | ||
34 | +@code{encrypt.*} parameters. | ||
35 | + | ||
36 | +If this is set to @code{aes}, the image is encrypted with 128-bit AES-CBC. | ||
37 | +The encryption key is given by the @code{encrypt.key-secret} parameter. | ||
38 | +This encryption format is considered to be flawed by modern cryptography | ||
39 | +standards, suffering from a number of design problems: | ||
40 | |||
41 | @itemize @minus | ||
42 | @item The AES-CBC cipher is used with predictable initialization vectors based | ||
43 | @@ -XXX,XX +XXX,XX @@ original file must then be securely erased using a program like shred, | ||
44 | though even this is ineffective with many modern storage technologies. | ||
45 | @end itemize | ||
46 | |||
47 | -Use of qcow / qcow2 encryption with QEMU is deprecated, and support for | ||
48 | -it will go away in a future release. Users are recommended to use an | ||
49 | -alternative encryption technology such as the Linux dm-crypt / LUKS | ||
50 | -system. | ||
51 | +The use of this is no longer supported in system emulators. Support only | ||
52 | +remains in the command line utilities, for the purposes of data liberation | ||
53 | +and interoperability with old versions of QEMU. The @code{luks} format | ||
54 | +should be used instead. | ||
55 | + | ||
56 | +@item encrypt.key-secret | ||
57 | + | ||
58 | +Provides the ID of a @code{secret} object that contains the passphrase | ||
59 | +(@code{encrypt.format=luks}) or encryption key (@code{encrypt.format=aes}). | ||
60 | + | ||
61 | +@item encrypt.cipher-alg | ||
62 | + | ||
63 | +Name of the cipher algorithm and key length. Currently defaults | ||
64 | +to @code{aes-256}. Only used when @code{encrypt.format=luks}. | ||
65 | + | ||
66 | +@item encrypt.cipher-mode | ||
67 | + | ||
68 | +Name of the encryption mode to use. Currently defaults to @code{xts}. | ||
69 | +Only used when @code{encrypt.format=luks}. | ||
70 | + | ||
71 | +@item encrypt.ivgen-alg | ||
72 | + | ||
73 | +Name of the initialization vector generator algorithm. Currently defaults | ||
74 | +to @code{plain64}. Only used when @code{encrypt.format=luks}. | ||
75 | + | ||
76 | +@item encrypt.ivgen-hash-alg | ||
77 | + | ||
78 | +Name of the hash algorithm to use with the initialization vector generator | ||
79 | +(if required). Defaults to @code{sha256}. Only used when @code{encrypt.format=luks}. | ||
80 | + | ||
81 | +@item encrypt.hash-alg | ||
82 | + | ||
83 | +Name of the hash algorithm to use for PBKDF algorithm | ||
84 | +Defaults to @code{sha256}. Only used when @code{encrypt.format=luks}. | ||
85 | + | ||
86 | +@item encrypt.iter-time | ||
87 | + | ||
88 | +Amount of time, in milliseconds, to use for PBKDF algorithm per key slot. | ||
89 | +Defaults to @code{2000}. Only used when @code{encrypt.format=luks}. | ||
90 | |||
91 | @item cluster_size | ||
92 | Changes the qcow2 cluster size (must be between 512 and 2M). Smaller cluster | ||
93 | @@ -XXX,XX +XXX,XX @@ Supported options: | ||
94 | @item backing_file | ||
95 | File name of a base image (see @option{create} subcommand) | ||
96 | @item encryption | ||
97 | -If this option is set to @code{on}, the image is encrypted. | ||
98 | +This option is deprecated and equivalent to @code{encrypt.format=aes} | ||
99 | + | ||
100 | +@item encrypt.format | ||
101 | +If this is set to @code{aes}, the image is encrypted with 128-bit AES-CBC. | ||
102 | +The encryption key is given by the @code{encrypt.key-secret} parameter. | ||
103 | +This encryption format is considered to be flawed by modern cryptography | ||
104 | +standards, suffering from a number of design problems enumerated previously | ||
105 | +against the @code{qcow2} image format. | ||
106 | + | ||
107 | +The use of this is no longer supported in system emulators. Support only | ||
108 | +remains in the command line utilities, for the purposes of data liberation | ||
109 | +and interoperability with old versions of QEMU. | ||
110 | + | ||
111 | +Users requiring native encryption should use the @code{qcow2} format | ||
112 | +instead with @code{encrypt.format=luks}. | ||
113 | + | ||
114 | +@item encrypt.key-secret | ||
115 | + | ||
116 | +Provides the ID of a @code{secret} object that contains the encryption | ||
117 | +key (@code{encrypt.format=aes}). | ||
118 | + | ||
119 | +@end table | ||
120 | + | ||
121 | +@item luks | ||
122 | + | ||
123 | +LUKS v1 encryption format, compatible with Linux dm-crypt/cryptsetup | ||
124 | + | ||
125 | +Supported options: | ||
126 | +@table @code | ||
127 | + | ||
128 | +@item key-secret | ||
129 | + | ||
130 | +Provides the ID of a @code{secret} object that contains the passphrase. | ||
131 | + | ||
132 | +@item cipher-alg | ||
133 | + | ||
134 | +Name of the cipher algorithm and key length. Currently defaults | ||
135 | +to @code{aes-256}. | ||
136 | + | ||
137 | +@item cipher-mode | ||
138 | + | ||
139 | +Name of the encryption mode to use. Currently defaults to @code{xts}. | ||
140 | + | ||
141 | +@item ivgen-alg | ||
142 | + | ||
143 | +Name of the initialization vector generator algorithm. Currently defaults | ||
144 | +to @code{plain64}. | ||
145 | + | ||
146 | +@item ivgen-hash-alg | ||
147 | + | ||
148 | +Name of the hash algorithm to use with the initialization vector generator | ||
149 | +(if required). Defaults to @code{sha256}. | ||
150 | + | ||
151 | +@item hash-alg | ||
152 | + | ||
153 | +Name of the hash algorithm to use for PBKDF algorithm | ||
154 | +Defaults to @code{sha256}. | ||
155 | + | ||
156 | +@item iter-time | ||
157 | + | ||
158 | +Amount of time, in milliseconds, to use for PBKDF algorithm per key slot. | ||
159 | +Defaults to @code{2000}. | ||
160 | + | ||
161 | @end table | ||
162 | |||
163 | @item vdi | ||
164 | -- | ||
165 | 2.9.4 | ||
166 | |||
167 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | Test 181 only works for formats which support live migration (naturally, | ||
2 | as it is a live migration test). Disable it for all formats which do | ||
3 | not. | ||
4 | 1 | ||
5 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
6 | Message-id: 20170621131157.16584-1-mreitz@redhat.com | ||
7 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
8 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
9 | --- | ||
10 | tests/qemu-iotests/181 | 2 ++ | ||
11 | 1 file changed, 2 insertions(+) | ||
12 | |||
13 | diff --git a/tests/qemu-iotests/181 b/tests/qemu-iotests/181 | ||
14 | index XXXXXXX..XXXXXXX 100755 | ||
15 | --- a/tests/qemu-iotests/181 | ||
16 | +++ b/tests/qemu-iotests/181 | ||
17 | @@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15 | ||
18 | . ./common.qemu | ||
19 | |||
20 | _supported_fmt generic | ||
21 | +# Formats that do not support live migration | ||
22 | +_unsupported_fmt qcow vdi vhdx vmdk vpc vvfat | ||
23 | _supported_proto generic | ||
24 | _supported_os Linux | ||
25 | |||
26 | -- | ||
27 | 2.9.4 | ||
28 | |||
29 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "sochin.jiang" <sochin.jiang@huawei.com> | ||
2 | 1 | ||
3 | mirror_complete opens the backing chain, which should have the same | ||
4 | AioContext as the top when using iothreads. Make the code guarantee | ||
5 | this, which fixes a failed assertion in bdrv_attach_child. | ||
6 | |||
7 | Signed-off-by: sochin.jiang <sochin.jiang@huawei.com> | ||
8 | Message-id: 1498475064-39816-1-git-send-email-sochin.jiang@huawei.com | ||
9 | [mreitz: Reworded commit message] | ||
10 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
11 | --- | ||
12 | block.c | 1 + | ||
13 | 1 file changed, 1 insertion(+) | ||
14 | |||
15 | diff --git a/block.c b/block.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/block.c | ||
18 | +++ b/block.c | ||
19 | @@ -XXX,XX +XXX,XX @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options, | ||
20 | ret = -EINVAL; | ||
21 | goto free_exit; | ||
22 | } | ||
23 | + bdrv_set_aio_context(backing_hd, bdrv_get_aio_context(bs)); | ||
24 | |||
25 | /* Hook up the backing file link; drop our reference, bs owns the | ||
26 | * backing_hd reference now */ | ||
27 | -- | ||
28 | 2.9.4 | ||
29 | |||
30 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
4 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
5 | Message-id: 20170628120530.31251-2-vsementsov@virtuozzo.com | ||
6 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
7 | --- | ||
8 | docs/interop/qcow2.txt | 3 +-- | ||
9 | 1 file changed, 1 insertion(+), 2 deletions(-) | ||
10 | |||
11 | diff --git a/docs/interop/qcow2.txt b/docs/interop/qcow2.txt | ||
12 | index XXXXXXX..XXXXXXX 100644 | ||
13 | --- a/docs/interop/qcow2.txt | ||
14 | +++ b/docs/interop/qcow2.txt | ||
15 | @@ -XXX,XX +XXX,XX @@ Structure of a bitmap directory entry: | ||
16 | 17: granularity_bits | ||
17 | Granularity bits. Valid values: 0 - 63. | ||
18 | |||
19 | - Note: Qemu currently doesn't support granularity_bits | ||
20 | - greater than 31. | ||
21 | + Note: Qemu currently supports only values 9 - 31. | ||
22 | |||
23 | Granularity is calculated as | ||
24 | granularity = 1 << granularity_bits | ||
25 | -- | ||
26 | 2.9.4 | ||
27 | |||
28 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | A bitmap directory entry is sometimes called a 'bitmap header'. This | ||
4 | patch leaves only one name - 'bitmap directory entry'. The name 'bitmap | ||
5 | header' creates misunderstandings with 'qcow2 header' and 'qcow2 bitmap | ||
6 | header extension' (which is extension of qcow2 header) | ||
7 | |||
8 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
9 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
10 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
11 | Message-id: 20170628120530.31251-3-vsementsov@virtuozzo.com | ||
12 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
13 | --- | ||
14 | docs/interop/qcow2.txt | 5 ++--- | ||
15 | 1 file changed, 2 insertions(+), 3 deletions(-) | ||
16 | |||
17 | diff --git a/docs/interop/qcow2.txt b/docs/interop/qcow2.txt | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/docs/interop/qcow2.txt | ||
20 | +++ b/docs/interop/qcow2.txt | ||
21 | @@ -XXX,XX +XXX,XX @@ The fields of the bitmaps extension are: | ||
22 | |||
23 | 8 - 15: bitmap_directory_size | ||
24 | Size of the bitmap directory in bytes. It is the cumulative | ||
25 | - size of all (nb_bitmaps) bitmap headers. | ||
26 | + size of all (nb_bitmaps) bitmap directory entries. | ||
27 | |||
28 | 16 - 23: bitmap_directory_offset | ||
29 | Offset into the image file at which the bitmap directory | ||
30 | @@ -XXX,XX +XXX,XX @@ Each bitmap saved in the image is described in a bitmap directory entry. The | ||
31 | bitmap directory is a contiguous area in the image file, whose starting offset | ||
32 | and length are given by the header extension fields bitmap_directory_offset and | ||
33 | bitmap_directory_size. The entries of the bitmap directory have variable | ||
34 | -length, depending on the lengths of the bitmap name and extra data. These | ||
35 | -entries are also called bitmap headers. | ||
36 | +length, depending on the lengths of the bitmap name and extra data. | ||
37 | |||
38 | Structure of a bitmap directory entry: | ||
39 | |||
40 | -- | ||
41 | 2.9.4 | ||
42 | |||
43 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | Make dirty iter resistant to resetting bits in corresponding HBitmap. | ||
4 | |||
5 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
6 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
7 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
8 | Message-id: 20170628120530.31251-4-vsementsov@virtuozzo.com | ||
9 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
10 | --- | ||
11 | include/qemu/hbitmap.h | 26 ++++---------------------- | ||
12 | util/hbitmap.c | 23 ++++++++++++++++++++++- | ||
13 | 2 files changed, 26 insertions(+), 23 deletions(-) | ||
14 | |||
15 | diff --git a/include/qemu/hbitmap.h b/include/qemu/hbitmap.h | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/include/qemu/hbitmap.h | ||
18 | +++ b/include/qemu/hbitmap.h | ||
19 | @@ -XXX,XX +XXX,XX @@ void hbitmap_free(HBitmap *hb); | ||
20 | * the lowest-numbered bit that is set in @hb, starting at @first. | ||
21 | * | ||
22 | * Concurrent setting of bits is acceptable, and will at worst cause the | ||
23 | - * iteration to miss some of those bits. Resetting bits before the current | ||
24 | - * position of the iterator is also okay. However, concurrent resetting of | ||
25 | - * bits can lead to unexpected behavior if the iterator has not yet reached | ||
26 | - * those bits. | ||
27 | + * iteration to miss some of those bits. | ||
28 | + * | ||
29 | + * The concurrent resetting of bits is OK. | ||
30 | */ | ||
31 | void hbitmap_iter_init(HBitmapIter *hbi, const HBitmap *hb, uint64_t first); | ||
32 | |||
33 | @@ -XXX,XX +XXX,XX @@ void hbitmap_free_meta(HBitmap *hb); | ||
34 | * Return the next bit that is set in @hbi's associated HBitmap, | ||
35 | * or -1 if all remaining bits are zero. | ||
36 | */ | ||
37 | -static inline int64_t hbitmap_iter_next(HBitmapIter *hbi) | ||
38 | -{ | ||
39 | - unsigned long cur = hbi->cur[HBITMAP_LEVELS - 1]; | ||
40 | - int64_t item; | ||
41 | - | ||
42 | - if (cur == 0) { | ||
43 | - cur = hbitmap_iter_skip_words(hbi); | ||
44 | - if (cur == 0) { | ||
45 | - return -1; | ||
46 | - } | ||
47 | - } | ||
48 | - | ||
49 | - /* The next call will resume work from the next bit. */ | ||
50 | - hbi->cur[HBITMAP_LEVELS - 1] = cur & (cur - 1); | ||
51 | - item = ((uint64_t)hbi->pos << BITS_PER_LEVEL) + ctzl(cur); | ||
52 | - | ||
53 | - return item << hbi->granularity; | ||
54 | -} | ||
55 | +int64_t hbitmap_iter_next(HBitmapIter *hbi); | ||
56 | |||
57 | /** | ||
58 | * hbitmap_iter_next_word: | ||
59 | diff --git a/util/hbitmap.c b/util/hbitmap.c | ||
60 | index XXXXXXX..XXXXXXX 100644 | ||
61 | --- a/util/hbitmap.c | ||
62 | +++ b/util/hbitmap.c | ||
63 | @@ -XXX,XX +XXX,XX @@ unsigned long hbitmap_iter_skip_words(HBitmapIter *hbi) | ||
64 | |||
65 | unsigned long cur; | ||
66 | do { | ||
67 | - cur = hbi->cur[--i]; | ||
68 | + i--; | ||
69 | pos >>= BITS_PER_LEVEL; | ||
70 | + cur = hbi->cur[i] & hb->levels[i][pos]; | ||
71 | } while (cur == 0); | ||
72 | |||
73 | /* Check for end of iteration. We always use fewer than BITS_PER_LONG | ||
74 | @@ -XXX,XX +XXX,XX @@ unsigned long hbitmap_iter_skip_words(HBitmapIter *hbi) | ||
75 | return cur; | ||
76 | } | ||
77 | |||
78 | +int64_t hbitmap_iter_next(HBitmapIter *hbi) | ||
79 | +{ | ||
80 | + unsigned long cur = hbi->cur[HBITMAP_LEVELS - 1] & | ||
81 | + hbi->hb->levels[HBITMAP_LEVELS - 1][hbi->pos]; | ||
82 | + int64_t item; | ||
83 | + | ||
84 | + if (cur == 0) { | ||
85 | + cur = hbitmap_iter_skip_words(hbi); | ||
86 | + if (cur == 0) { | ||
87 | + return -1; | ||
88 | + } | ||
89 | + } | ||
90 | + | ||
91 | + /* The next call will resume work from the next bit. */ | ||
92 | + hbi->cur[HBITMAP_LEVELS - 1] = cur & (cur - 1); | ||
93 | + item = ((uint64_t)hbi->pos << BITS_PER_LEVEL) + ctzl(cur); | ||
94 | + | ||
95 | + return item << hbi->granularity; | ||
96 | +} | ||
97 | + | ||
98 | void hbitmap_iter_init(HBitmapIter *hbi, const HBitmap *hb, uint64_t first) | ||
99 | { | ||
100 | unsigned i, bit; | ||
101 | -- | ||
102 | 2.9.4 | ||
103 | |||
104 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | Test that hbitmap iter is resistant to bitmap resetting. | ||
4 | |||
5 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
6 | Signed-off-by: Denis V. Lunev <den@openvz.org> | ||
7 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
8 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
9 | Message-id: 20170628120530.31251-5-vsementsov@virtuozzo.com | ||
10 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
11 | --- | ||
12 | tests/test-hbitmap.c | 19 +++++++++++++++++++ | ||
13 | 1 file changed, 19 insertions(+) | ||
14 | |||
15 | diff --git a/tests/test-hbitmap.c b/tests/test-hbitmap.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/tests/test-hbitmap.c | ||
18 | +++ b/tests/test-hbitmap.c | ||
19 | @@ -XXX,XX +XXX,XX @@ static void hbitmap_test_add(const char *testpath, | ||
20 | hbitmap_test_teardown); | ||
21 | } | ||
22 | |||
23 | +static void test_hbitmap_iter_and_reset(TestHBitmapData *data, | ||
24 | + const void *unused) | ||
25 | +{ | ||
26 | + HBitmapIter hbi; | ||
27 | + | ||
28 | + hbitmap_test_init(data, L1 * 2, 0); | ||
29 | + hbitmap_set(data->hb, 0, data->size); | ||
30 | + | ||
31 | + hbitmap_iter_init(&hbi, data->hb, BITS_PER_LONG - 1); | ||
32 | + | ||
33 | + hbitmap_iter_next(&hbi); | ||
34 | + | ||
35 | + hbitmap_reset_all(data->hb); | ||
36 | + hbitmap_iter_next(&hbi); | ||
37 | +} | ||
38 | + | ||
39 | int main(int argc, char **argv) | ||
40 | { | ||
41 | g_test_init(&argc, &argv, NULL); | ||
42 | @@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv) | ||
43 | test_hbitmap_serialize_part); | ||
44 | hbitmap_test_add("/hbitmap/serialize/zeroes", | ||
45 | test_hbitmap_serialize_zeroes); | ||
46 | + | ||
47 | + hbitmap_test_add("/hbitmap/iter/iter_and_reset", | ||
48 | + test_hbitmap_iter_and_reset); | ||
49 | g_test_run(); | ||
50 | |||
51 | return 0; | ||
52 | -- | ||
53 | 2.9.4 | ||
54 | |||
55 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | Make getter signature const-correct. This allows other functions with | ||
4 | const dirty bitmap parameter use bdrv_dirty_bitmap_granularity(). | ||
5 | |||
6 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
7 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
8 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
9 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> | ||
10 | Message-id: 20170628120530.31251-6-vsementsov@virtuozzo.com | ||
11 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
12 | --- | ||
13 | include/block/dirty-bitmap.h | 2 +- | ||
14 | block/dirty-bitmap.c | 2 +- | ||
15 | 2 files changed, 2 insertions(+), 2 deletions(-) | ||
16 | |||
17 | diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/include/block/dirty-bitmap.h | ||
20 | +++ b/include/block/dirty-bitmap.h | ||
21 | @@ -XXX,XX +XXX,XX @@ void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap); | ||
22 | void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap); | ||
23 | BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs); | ||
24 | uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs); | ||
25 | -uint32_t bdrv_dirty_bitmap_granularity(BdrvDirtyBitmap *bitmap); | ||
26 | +uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap); | ||
27 | uint32_t bdrv_dirty_bitmap_meta_granularity(BdrvDirtyBitmap *bitmap); | ||
28 | bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap *bitmap); | ||
29 | bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap); | ||
30 | diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c | ||
31 | index XXXXXXX..XXXXXXX 100644 | ||
32 | --- a/block/dirty-bitmap.c | ||
33 | +++ b/block/dirty-bitmap.c | ||
34 | @@ -XXX,XX +XXX,XX @@ uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs) | ||
35 | return granularity; | ||
36 | } | ||
37 | |||
38 | -uint32_t bdrv_dirty_bitmap_granularity(BdrvDirtyBitmap *bitmap) | ||
39 | +uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap) | ||
40 | { | ||
41 | return BDRV_SECTOR_SIZE << hbitmap_granularity(bitmap->bitmap); | ||
42 | } | ||
43 | -- | ||
44 | 2.9.4 | ||
45 | |||
46 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | Add bdrv_dirty_bitmap_deserialize_ones() function, which is needed for | ||
4 | qcow2 bitmap loading, to handle unallocated bitmap parts, marked as | ||
5 | all-ones. | ||
6 | |||
7 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
8 | Reviewed-by: Kevin Wolf <kwolf@redhat.com> | ||
9 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
10 | Message-id: 20170628120530.31251-7-vsementsov@virtuozzo.com | ||
11 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
12 | --- | ||
13 | include/block/dirty-bitmap.h | 3 +++ | ||
14 | include/qemu/hbitmap.h | 15 +++++++++++++++ | ||
15 | block/dirty-bitmap.c | 7 +++++++ | ||
16 | util/hbitmap.c | 17 +++++++++++++++++ | ||
17 | 4 files changed, 42 insertions(+) | ||
18 | |||
19 | diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h | ||
20 | index XXXXXXX..XXXXXXX 100644 | ||
21 | --- a/include/block/dirty-bitmap.h | ||
22 | +++ b/include/block/dirty-bitmap.h | ||
23 | @@ -XXX,XX +XXX,XX @@ void bdrv_dirty_bitmap_deserialize_part(BdrvDirtyBitmap *bitmap, | ||
24 | void bdrv_dirty_bitmap_deserialize_zeroes(BdrvDirtyBitmap *bitmap, | ||
25 | uint64_t start, uint64_t count, | ||
26 | bool finish); | ||
27 | +void bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap, | ||
28 | + uint64_t start, uint64_t count, | ||
29 | + bool finish); | ||
30 | void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap); | ||
31 | |||
32 | /* Functions that require manual locking. */ | ||
33 | diff --git a/include/qemu/hbitmap.h b/include/qemu/hbitmap.h | ||
34 | index XXXXXXX..XXXXXXX 100644 | ||
35 | --- a/include/qemu/hbitmap.h | ||
36 | +++ b/include/qemu/hbitmap.h | ||
37 | @@ -XXX,XX +XXX,XX @@ void hbitmap_deserialize_zeroes(HBitmap *hb, uint64_t start, uint64_t count, | ||
38 | bool finish); | ||
39 | |||
40 | /** | ||
41 | + * hbitmap_deserialize_ones | ||
42 | + * @hb: HBitmap to operate on. | ||
43 | + * @start: First bit to restore. | ||
44 | + * @count: Number of bits to restore. | ||
45 | + * @finish: Whether to call hbitmap_deserialize_finish automatically. | ||
46 | + * | ||
47 | + * Fills the bitmap with ones. | ||
48 | + * | ||
49 | + * If @finish is false, caller must call hbitmap_serialize_finish before using | ||
50 | + * the bitmap. | ||
51 | + */ | ||
52 | +void hbitmap_deserialize_ones(HBitmap *hb, uint64_t start, uint64_t count, | ||
53 | + bool finish); | ||
54 | + | ||
55 | +/** | ||
56 | * hbitmap_deserialize_finish | ||
57 | * @hb: HBitmap to operate on. | ||
58 | * | ||
59 | diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c | ||
60 | index XXXXXXX..XXXXXXX 100644 | ||
61 | --- a/block/dirty-bitmap.c | ||
62 | +++ b/block/dirty-bitmap.c | ||
63 | @@ -XXX,XX +XXX,XX @@ void bdrv_dirty_bitmap_deserialize_zeroes(BdrvDirtyBitmap *bitmap, | ||
64 | hbitmap_deserialize_zeroes(bitmap->bitmap, start, count, finish); | ||
65 | } | ||
66 | |||
67 | +void bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap, | ||
68 | + uint64_t start, uint64_t count, | ||
69 | + bool finish) | ||
70 | +{ | ||
71 | + hbitmap_deserialize_ones(bitmap->bitmap, start, count, finish); | ||
72 | +} | ||
73 | + | ||
74 | void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap) | ||
75 | { | ||
76 | hbitmap_deserialize_finish(bitmap->bitmap); | ||
77 | diff --git a/util/hbitmap.c b/util/hbitmap.c | ||
78 | index XXXXXXX..XXXXXXX 100644 | ||
79 | --- a/util/hbitmap.c | ||
80 | +++ b/util/hbitmap.c | ||
81 | @@ -XXX,XX +XXX,XX @@ void hbitmap_deserialize_zeroes(HBitmap *hb, uint64_t start, uint64_t count, | ||
82 | } | ||
83 | } | ||
84 | |||
85 | +void hbitmap_deserialize_ones(HBitmap *hb, uint64_t start, uint64_t count, | ||
86 | + bool finish) | ||
87 | +{ | ||
88 | + uint64_t el_count; | ||
89 | + unsigned long *first; | ||
90 | + | ||
91 | + if (!count) { | ||
92 | + return; | ||
93 | + } | ||
94 | + serialization_chunk(hb, start, count, &first, &el_count); | ||
95 | + | ||
96 | + memset(first, 0xff, el_count * sizeof(unsigned long)); | ||
97 | + if (finish) { | ||
98 | + hbitmap_deserialize_finish(hb); | ||
99 | + } | ||
100 | +} | ||
101 | + | ||
102 | void hbitmap_deserialize_finish(HBitmap *bitmap) | ||
103 | { | ||
104 | int64_t i, size, prev_size; | ||
105 | -- | ||
106 | 2.9.4 | ||
107 | |||
108 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | This is needed for the following patch, which will introduce refcounts | ||
4 | checking for qcow2 bitmaps. | ||
5 | |||
6 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
7 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
8 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
9 | Message-id: 20170628120530.31251-8-vsementsov@virtuozzo.com | ||
10 | [mreitz: s/inc_refcounts/qcow2_inc_refcounts_imrt/ in one more (new) | ||
11 | place] | ||
12 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
13 | --- | ||
14 | block/qcow2.h | 4 ++++ | ||
15 | block/qcow2-refcount.c | 59 ++++++++++++++++++++++++++------------------------ | ||
16 | 2 files changed, 35 insertions(+), 28 deletions(-) | ||
17 | |||
18 | diff --git a/block/qcow2.h b/block/qcow2.h | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/block/qcow2.h | ||
21 | +++ b/block/qcow2.h | ||
22 | @@ -XXX,XX +XXX,XX @@ int qcow2_check_metadata_overlap(BlockDriverState *bs, int ign, int64_t offset, | ||
23 | int64_t size); | ||
24 | int qcow2_pre_write_overlap_check(BlockDriverState *bs, int ign, int64_t offset, | ||
25 | int64_t size); | ||
26 | +int qcow2_inc_refcounts_imrt(BlockDriverState *bs, BdrvCheckResult *res, | ||
27 | + void **refcount_table, | ||
28 | + int64_t *refcount_table_size, | ||
29 | + int64_t offset, int64_t size); | ||
30 | |||
31 | int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order, | ||
32 | BlockDriverAmendStatusCB *status_cb, | ||
33 | diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c | ||
34 | index XXXXXXX..XXXXXXX 100644 | ||
35 | --- a/block/qcow2-refcount.c | ||
36 | +++ b/block/qcow2-refcount.c | ||
37 | @@ -XXX,XX +XXX,XX @@ static int realloc_refcount_array(BDRVQcow2State *s, void **array, | ||
38 | * | ||
39 | * Modifies the number of errors in res. | ||
40 | */ | ||
41 | -static int inc_refcounts(BlockDriverState *bs, | ||
42 | - BdrvCheckResult *res, | ||
43 | - void **refcount_table, | ||
44 | - int64_t *refcount_table_size, | ||
45 | - int64_t offset, int64_t size) | ||
46 | +int qcow2_inc_refcounts_imrt(BlockDriverState *bs, BdrvCheckResult *res, | ||
47 | + void **refcount_table, | ||
48 | + int64_t *refcount_table_size, | ||
49 | + int64_t offset, int64_t size) | ||
50 | { | ||
51 | BDRVQcow2State *s = bs->opaque; | ||
52 | uint64_t start, last, cluster_offset, k, refcount; | ||
53 | @@ -XXX,XX +XXX,XX @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res, | ||
54 | nb_csectors = ((l2_entry >> s->csize_shift) & | ||
55 | s->csize_mask) + 1; | ||
56 | l2_entry &= s->cluster_offset_mask; | ||
57 | - ret = inc_refcounts(bs, res, refcount_table, refcount_table_size, | ||
58 | - l2_entry & ~511, nb_csectors * 512); | ||
59 | + ret = qcow2_inc_refcounts_imrt(bs, res, | ||
60 | + refcount_table, refcount_table_size, | ||
61 | + l2_entry & ~511, nb_csectors * 512); | ||
62 | if (ret < 0) { | ||
63 | goto fail; | ||
64 | } | ||
65 | @@ -XXX,XX +XXX,XX @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res, | ||
66 | } | ||
67 | |||
68 | /* Mark cluster as used */ | ||
69 | - ret = inc_refcounts(bs, res, refcount_table, refcount_table_size, | ||
70 | - offset, s->cluster_size); | ||
71 | + ret = qcow2_inc_refcounts_imrt(bs, res, | ||
72 | + refcount_table, refcount_table_size, | ||
73 | + offset, s->cluster_size); | ||
74 | if (ret < 0) { | ||
75 | goto fail; | ||
76 | } | ||
77 | @@ -XXX,XX +XXX,XX @@ static int check_refcounts_l1(BlockDriverState *bs, | ||
78 | l1_size2 = l1_size * sizeof(uint64_t); | ||
79 | |||
80 | /* Mark L1 table as used */ | ||
81 | - ret = inc_refcounts(bs, res, refcount_table, refcount_table_size, | ||
82 | - l1_table_offset, l1_size2); | ||
83 | + ret = qcow2_inc_refcounts_imrt(bs, res, refcount_table, refcount_table_size, | ||
84 | + l1_table_offset, l1_size2); | ||
85 | if (ret < 0) { | ||
86 | goto fail; | ||
87 | } | ||
88 | @@ -XXX,XX +XXX,XX @@ static int check_refcounts_l1(BlockDriverState *bs, | ||
89 | if (l2_offset) { | ||
90 | /* Mark L2 table as used */ | ||
91 | l2_offset &= L1E_OFFSET_MASK; | ||
92 | - ret = inc_refcounts(bs, res, refcount_table, refcount_table_size, | ||
93 | - l2_offset, s->cluster_size); | ||
94 | + ret = qcow2_inc_refcounts_imrt(bs, res, | ||
95 | + refcount_table, refcount_table_size, | ||
96 | + l2_offset, s->cluster_size); | ||
97 | if (ret < 0) { | ||
98 | goto fail; | ||
99 | } | ||
100 | @@ -XXX,XX +XXX,XX @@ static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res, | ||
101 | } | ||
102 | |||
103 | res->corruptions_fixed++; | ||
104 | - ret = inc_refcounts(bs, res, refcount_table, nb_clusters, | ||
105 | - offset, s->cluster_size); | ||
106 | + ret = qcow2_inc_refcounts_imrt(bs, res, | ||
107 | + refcount_table, nb_clusters, | ||
108 | + offset, s->cluster_size); | ||
109 | if (ret < 0) { | ||
110 | return ret; | ||
111 | } | ||
112 | /* No need to check whether the refcount is now greater than 1: | ||
113 | * This area was just allocated and zeroed, so it can only be | ||
114 | - * exactly 1 after inc_refcounts() */ | ||
115 | + * exactly 1 after qcow2_inc_refcounts_imrt() */ | ||
116 | continue; | ||
117 | |||
118 | resize_fail: | ||
119 | @@ -XXX,XX +XXX,XX @@ resize_fail: | ||
120 | } | ||
121 | |||
122 | if (offset != 0) { | ||
123 | - ret = inc_refcounts(bs, res, refcount_table, nb_clusters, | ||
124 | - offset, s->cluster_size); | ||
125 | + ret = qcow2_inc_refcounts_imrt(bs, res, refcount_table, nb_clusters, | ||
126 | + offset, s->cluster_size); | ||
127 | if (ret < 0) { | ||
128 | return ret; | ||
129 | } | ||
130 | @@ -XXX,XX +XXX,XX @@ static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res, | ||
131 | } | ||
132 | |||
133 | /* header */ | ||
134 | - ret = inc_refcounts(bs, res, refcount_table, nb_clusters, | ||
135 | - 0, s->cluster_size); | ||
136 | + ret = qcow2_inc_refcounts_imrt(bs, res, refcount_table, nb_clusters, | ||
137 | + 0, s->cluster_size); | ||
138 | if (ret < 0) { | ||
139 | return ret; | ||
140 | } | ||
141 | @@ -XXX,XX +XXX,XX @@ static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res, | ||
142 | return ret; | ||
143 | } | ||
144 | } | ||
145 | - ret = inc_refcounts(bs, res, refcount_table, nb_clusters, | ||
146 | - s->snapshots_offset, s->snapshots_size); | ||
147 | + ret = qcow2_inc_refcounts_imrt(bs, res, refcount_table, nb_clusters, | ||
148 | + s->snapshots_offset, s->snapshots_size); | ||
149 | if (ret < 0) { | ||
150 | return ret; | ||
151 | } | ||
152 | |||
153 | /* refcount data */ | ||
154 | - ret = inc_refcounts(bs, res, refcount_table, nb_clusters, | ||
155 | - s->refcount_table_offset, | ||
156 | - s->refcount_table_size * sizeof(uint64_t)); | ||
157 | + ret = qcow2_inc_refcounts_imrt(bs, res, refcount_table, nb_clusters, | ||
158 | + s->refcount_table_offset, | ||
159 | + s->refcount_table_size * sizeof(uint64_t)); | ||
160 | if (ret < 0) { | ||
161 | return ret; | ||
162 | } | ||
163 | |||
164 | /* encryption */ | ||
165 | if (s->crypto_header.length) { | ||
166 | - ret = inc_refcounts(bs, res, refcount_table, nb_clusters, | ||
167 | - s->crypto_header.offset, | ||
168 | - s->crypto_header.length); | ||
169 | + ret = qcow2_inc_refcounts_imrt(bs, res, refcount_table, nb_clusters, | ||
170 | + s->crypto_header.offset, | ||
171 | + s->crypto_header.length); | ||
172 | if (ret < 0) { | ||
173 | return ret; | ||
174 | } | ||
175 | -- | ||
176 | 2.9.4 | ||
177 | |||
178 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | Add bitmap extension as specified in docs/specs/qcow2.txt. | ||
4 | For now, just mirror extension header into Qcow2 state and check | ||
5 | constraints. Also, calculate refcounts for qcow2 bitmaps, to not break | ||
6 | qemu-img check. | ||
7 | |||
8 | For now, disable image resize if it has bitmaps. It will be fixed later. | ||
9 | |||
10 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
11 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
12 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
13 | Message-id: 20170628120530.31251-9-vsementsov@virtuozzo.com | ||
14 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
15 | --- | ||
16 | block/Makefile.objs | 2 +- | ||
17 | block/qcow2.h | 27 +++ | ||
18 | block/qcow2-bitmap.c | 439 +++++++++++++++++++++++++++++++++++++++++++++++++ | ||
19 | block/qcow2-refcount.c | 6 + | ||
20 | block/qcow2.c | 125 +++++++++++++- | ||
21 | 5 files changed, 593 insertions(+), 6 deletions(-) | ||
22 | create mode 100644 block/qcow2-bitmap.c | ||
23 | |||
24 | diff --git a/block/Makefile.objs b/block/Makefile.objs | ||
25 | index XXXXXXX..XXXXXXX 100644 | ||
26 | --- a/block/Makefile.objs | ||
27 | +++ b/block/Makefile.objs | ||
28 | @@ -XXX,XX +XXX,XX @@ | ||
29 | block-obj-y += raw-format.o qcow.o vdi.o vmdk.o cloop.o bochs.o vpc.o vvfat.o dmg.o | ||
30 | -block-obj-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o qcow2-cache.o | ||
31 | +block-obj-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o qcow2-cache.o qcow2-bitmap.o | ||
32 | block-obj-y += qed.o qed-l2-cache.o qed-table.o qed-cluster.o | ||
33 | block-obj-y += qed-check.o | ||
34 | block-obj-y += vhdx.o vhdx-endian.o vhdx-log.o | ||
35 | diff --git a/block/qcow2.h b/block/qcow2.h | ||
36 | index XXXXXXX..XXXXXXX 100644 | ||
37 | --- a/block/qcow2.h | ||
38 | +++ b/block/qcow2.h | ||
39 | @@ -XXX,XX +XXX,XX @@ | ||
40 | * space for snapshot names and IDs */ | ||
41 | #define QCOW_MAX_SNAPSHOTS_SIZE (1024 * QCOW_MAX_SNAPSHOTS) | ||
42 | |||
43 | +/* Bitmap header extension constraints */ | ||
44 | +#define QCOW2_MAX_BITMAPS 65535 | ||
45 | +#define QCOW2_MAX_BITMAP_DIRECTORY_SIZE (1024 * QCOW2_MAX_BITMAPS) | ||
46 | + | ||
47 | /* indicate that the refcount of the referenced cluster is exactly one. */ | ||
48 | #define QCOW_OFLAG_COPIED (1ULL << 63) | ||
49 | /* indicate that the cluster is compressed (they never have the copied flag) */ | ||
50 | @@ -XXX,XX +XXX,XX @@ enum { | ||
51 | QCOW2_COMPAT_FEAT_MASK = QCOW2_COMPAT_LAZY_REFCOUNTS, | ||
52 | }; | ||
53 | |||
54 | +/* Autoclear feature bits */ | ||
55 | +enum { | ||
56 | + QCOW2_AUTOCLEAR_BITMAPS_BITNR = 0, | ||
57 | + QCOW2_AUTOCLEAR_BITMAPS = 1 << QCOW2_AUTOCLEAR_BITMAPS_BITNR, | ||
58 | + | ||
59 | + QCOW2_AUTOCLEAR_MASK = QCOW2_AUTOCLEAR_BITMAPS, | ||
60 | +}; | ||
61 | + | ||
62 | enum qcow2_discard_type { | ||
63 | QCOW2_DISCARD_NEVER = 0, | ||
64 | QCOW2_DISCARD_ALWAYS, | ||
65 | @@ -XXX,XX +XXX,XX @@ typedef uint64_t Qcow2GetRefcountFunc(const void *refcount_array, | ||
66 | typedef void Qcow2SetRefcountFunc(void *refcount_array, | ||
67 | uint64_t index, uint64_t value); | ||
68 | |||
69 | +typedef struct Qcow2BitmapHeaderExt { | ||
70 | + uint32_t nb_bitmaps; | ||
71 | + uint32_t reserved32; | ||
72 | + uint64_t bitmap_directory_size; | ||
73 | + uint64_t bitmap_directory_offset; | ||
74 | +} QEMU_PACKED Qcow2BitmapHeaderExt; | ||
75 | + | ||
76 | typedef struct BDRVQcow2State { | ||
77 | int cluster_bits; | ||
78 | int cluster_size; | ||
79 | @@ -XXX,XX +XXX,XX @@ typedef struct BDRVQcow2State { | ||
80 | unsigned int nb_snapshots; | ||
81 | QCowSnapshot *snapshots; | ||
82 | |||
83 | + uint32_t nb_bitmaps; | ||
84 | + uint64_t bitmap_directory_size; | ||
85 | + uint64_t bitmap_directory_offset; | ||
86 | + | ||
87 | int flags; | ||
88 | int qcow_version; | ||
89 | bool use_lazy_refcounts; | ||
90 | @@ -XXX,XX +XXX,XX @@ int qcow2_cache_get_empty(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset, | ||
91 | void **table); | ||
92 | void qcow2_cache_put(BlockDriverState *bs, Qcow2Cache *c, void **table); | ||
93 | |||
94 | +/* qcow2-bitmap.c functions */ | ||
95 | +int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res, | ||
96 | + void **refcount_table, | ||
97 | + int64_t *refcount_table_size); | ||
98 | #endif | ||
99 | diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c | ||
100 | new file mode 100644 | ||
101 | index XXXXXXX..XXXXXXX | ||
102 | --- /dev/null | ||
103 | +++ b/block/qcow2-bitmap.c | ||
104 | @@ -XXX,XX +XXX,XX @@ | ||
105 | +/* | ||
106 | + * Bitmaps for the QCOW version 2 format | ||
107 | + * | ||
108 | + * Copyright (c) 2014-2017 Vladimir Sementsov-Ogievskiy | ||
109 | + * | ||
110 | + * This file is derived from qcow2-snapshot.c, original copyright: | ||
111 | + * Copyright (c) 2004-2006 Fabrice Bellard | ||
112 | + * | ||
113 | + * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
114 | + * of this software and associated documentation files (the "Software"), to deal | ||
115 | + * in the Software without restriction, including without limitation the rights | ||
116 | + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
117 | + * copies of the Software, and to permit persons to whom the Software is | ||
118 | + * furnished to do so, subject to the following conditions: | ||
119 | + * | ||
120 | + * The above copyright notice and this permission notice shall be included in | ||
121 | + * all copies or substantial portions of the Software. | ||
122 | + * | ||
123 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
124 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
125 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
126 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
127 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
128 | + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
129 | + * THE SOFTWARE. | ||
130 | + */ | ||
131 | + | ||
132 | +#include "qemu/osdep.h" | ||
133 | +#include "qapi/error.h" | ||
134 | + | ||
135 | +#include "block/block_int.h" | ||
136 | +#include "block/qcow2.h" | ||
137 | + | ||
138 | +/* NOTICE: BME here means Bitmaps Extension and used as a namespace for | ||
139 | + * _internal_ constants. Please do not use this _internal_ abbreviation for | ||
140 | + * other needs and/or outside of this file. */ | ||
141 | + | ||
142 | +/* Bitmap directory entry constraints */ | ||
143 | +#define BME_MAX_TABLE_SIZE 0x8000000 | ||
144 | +#define BME_MAX_PHYS_SIZE 0x20000000 /* restrict BdrvDirtyBitmap size in RAM */ | ||
145 | +#define BME_MAX_GRANULARITY_BITS 31 | ||
146 | +#define BME_MIN_GRANULARITY_BITS 9 | ||
147 | +#define BME_MAX_NAME_SIZE 1023 | ||
148 | + | ||
149 | +/* Bitmap directory entry flags */ | ||
150 | +#define BME_RESERVED_FLAGS 0xfffffffcU | ||
151 | + | ||
152 | +/* bits [1, 8] U [56, 63] are reserved */ | ||
153 | +#define BME_TABLE_ENTRY_RESERVED_MASK 0xff000000000001feULL | ||
154 | +#define BME_TABLE_ENTRY_OFFSET_MASK 0x00fffffffffffe00ULL | ||
155 | +#define BME_TABLE_ENTRY_FLAG_ALL_ONES (1ULL << 0) | ||
156 | + | ||
157 | +typedef struct QEMU_PACKED Qcow2BitmapDirEntry { | ||
158 | + /* header is 8 byte aligned */ | ||
159 | + uint64_t bitmap_table_offset; | ||
160 | + | ||
161 | + uint32_t bitmap_table_size; | ||
162 | + uint32_t flags; | ||
163 | + | ||
164 | + uint8_t type; | ||
165 | + uint8_t granularity_bits; | ||
166 | + uint16_t name_size; | ||
167 | + uint32_t extra_data_size; | ||
168 | + /* extra data follows */ | ||
169 | + /* name follows */ | ||
170 | +} Qcow2BitmapDirEntry; | ||
171 | + | ||
172 | +typedef struct Qcow2BitmapTable { | ||
173 | + uint64_t offset; | ||
174 | + uint32_t size; /* number of 64bit entries */ | ||
175 | + QSIMPLEQ_ENTRY(Qcow2BitmapTable) entry; | ||
176 | +} Qcow2BitmapTable; | ||
177 | + | ||
178 | +typedef struct Qcow2Bitmap { | ||
179 | + Qcow2BitmapTable table; | ||
180 | + uint32_t flags; | ||
181 | + uint8_t granularity_bits; | ||
182 | + char *name; | ||
183 | + | ||
184 | + QSIMPLEQ_ENTRY(Qcow2Bitmap) entry; | ||
185 | +} Qcow2Bitmap; | ||
186 | +typedef QSIMPLEQ_HEAD(Qcow2BitmapList, Qcow2Bitmap) Qcow2BitmapList; | ||
187 | + | ||
188 | +typedef enum BitmapType { | ||
189 | + BT_DIRTY_TRACKING_BITMAP = 1 | ||
190 | +} BitmapType; | ||
191 | + | ||
192 | +static int check_table_entry(uint64_t entry, int cluster_size) | ||
193 | +{ | ||
194 | + uint64_t offset; | ||
195 | + | ||
196 | + if (entry & BME_TABLE_ENTRY_RESERVED_MASK) { | ||
197 | + return -EINVAL; | ||
198 | + } | ||
199 | + | ||
200 | + offset = entry & BME_TABLE_ENTRY_OFFSET_MASK; | ||
201 | + if (offset != 0) { | ||
202 | + /* if offset specified, bit 0 is reserved */ | ||
203 | + if (entry & BME_TABLE_ENTRY_FLAG_ALL_ONES) { | ||
204 | + return -EINVAL; | ||
205 | + } | ||
206 | + | ||
207 | + if (offset % cluster_size != 0) { | ||
208 | + return -EINVAL; | ||
209 | + } | ||
210 | + } | ||
211 | + | ||
212 | + return 0; | ||
213 | +} | ||
214 | + | ||
215 | +static int bitmap_table_load(BlockDriverState *bs, Qcow2BitmapTable *tb, | ||
216 | + uint64_t **bitmap_table) | ||
217 | +{ | ||
218 | + int ret; | ||
219 | + BDRVQcow2State *s = bs->opaque; | ||
220 | + uint32_t i; | ||
221 | + uint64_t *table; | ||
222 | + | ||
223 | + assert(tb->size != 0); | ||
224 | + table = g_try_new(uint64_t, tb->size); | ||
225 | + if (table == NULL) { | ||
226 | + return -ENOMEM; | ||
227 | + } | ||
228 | + | ||
229 | + assert(tb->size <= BME_MAX_TABLE_SIZE); | ||
230 | + ret = bdrv_pread(bs->file, tb->offset, | ||
231 | + table, tb->size * sizeof(uint64_t)); | ||
232 | + if (ret < 0) { | ||
233 | + goto fail; | ||
234 | + } | ||
235 | + | ||
236 | + for (i = 0; i < tb->size; ++i) { | ||
237 | + be64_to_cpus(&table[i]); | ||
238 | + ret = check_table_entry(table[i], s->cluster_size); | ||
239 | + if (ret < 0) { | ||
240 | + goto fail; | ||
241 | + } | ||
242 | + } | ||
243 | + | ||
244 | + *bitmap_table = table; | ||
245 | + return 0; | ||
246 | + | ||
247 | +fail: | ||
248 | + g_free(table); | ||
249 | + | ||
250 | + return ret; | ||
251 | +} | ||
252 | + | ||
253 | +/* | ||
254 | + * Bitmap List | ||
255 | + */ | ||
256 | + | ||
257 | +/* | ||
258 | + * Bitmap List private functions | ||
259 | + * Only Bitmap List knows about bitmap directory structure in Qcow2. | ||
260 | + */ | ||
261 | + | ||
262 | +static inline void bitmap_dir_entry_to_cpu(Qcow2BitmapDirEntry *entry) | ||
263 | +{ | ||
264 | + be64_to_cpus(&entry->bitmap_table_offset); | ||
265 | + be32_to_cpus(&entry->bitmap_table_size); | ||
266 | + be32_to_cpus(&entry->flags); | ||
267 | + be16_to_cpus(&entry->name_size); | ||
268 | + be32_to_cpus(&entry->extra_data_size); | ||
269 | +} | ||
270 | + | ||
271 | +static inline int calc_dir_entry_size(size_t name_size, size_t extra_data_size) | ||
272 | +{ | ||
273 | + return align_offset(sizeof(Qcow2BitmapDirEntry) + | ||
274 | + name_size + extra_data_size, 8); | ||
275 | +} | ||
276 | + | ||
277 | +static inline int dir_entry_size(Qcow2BitmapDirEntry *entry) | ||
278 | +{ | ||
279 | + return calc_dir_entry_size(entry->name_size, entry->extra_data_size); | ||
280 | +} | ||
281 | + | ||
282 | +static inline const char *dir_entry_name_field(Qcow2BitmapDirEntry *entry) | ||
283 | +{ | ||
284 | + return (const char *)(entry + 1) + entry->extra_data_size; | ||
285 | +} | ||
286 | + | ||
287 | +static inline char *dir_entry_copy_name(Qcow2BitmapDirEntry *entry) | ||
288 | +{ | ||
289 | + const char *name_field = dir_entry_name_field(entry); | ||
290 | + return g_strndup(name_field, entry->name_size); | ||
291 | +} | ||
292 | + | ||
293 | +static inline Qcow2BitmapDirEntry *next_dir_entry(Qcow2BitmapDirEntry *entry) | ||
294 | +{ | ||
295 | + return (Qcow2BitmapDirEntry *)((uint8_t *)entry + dir_entry_size(entry)); | ||
296 | +} | ||
297 | + | ||
298 | +static int check_dir_entry(BlockDriverState *bs, Qcow2BitmapDirEntry *entry) | ||
299 | +{ | ||
300 | + BDRVQcow2State *s = bs->opaque; | ||
301 | + uint64_t phys_bitmap_bytes; | ||
302 | + int64_t len; | ||
303 | + | ||
304 | + bool fail = (entry->bitmap_table_size == 0) || | ||
305 | + (entry->bitmap_table_offset == 0) || | ||
306 | + (entry->bitmap_table_offset % s->cluster_size) || | ||
307 | + (entry->bitmap_table_size > BME_MAX_TABLE_SIZE) || | ||
308 | + (entry->granularity_bits > BME_MAX_GRANULARITY_BITS) || | ||
309 | + (entry->granularity_bits < BME_MIN_GRANULARITY_BITS) || | ||
310 | + (entry->flags & BME_RESERVED_FLAGS) || | ||
311 | + (entry->name_size > BME_MAX_NAME_SIZE) || | ||
312 | + (entry->type != BT_DIRTY_TRACKING_BITMAP); | ||
313 | + | ||
314 | + if (fail) { | ||
315 | + return -EINVAL; | ||
316 | + } | ||
317 | + | ||
318 | + phys_bitmap_bytes = (uint64_t)entry->bitmap_table_size * s->cluster_size; | ||
319 | + len = bdrv_getlength(bs); | ||
320 | + | ||
321 | + if (len < 0) { | ||
322 | + return len; | ||
323 | + } | ||
324 | + | ||
325 | + fail = (phys_bitmap_bytes > BME_MAX_PHYS_SIZE) || | ||
326 | + (len > ((phys_bitmap_bytes * 8) << entry->granularity_bits)); | ||
327 | + | ||
328 | + return fail ? -EINVAL : 0; | ||
329 | +} | ||
330 | + | ||
331 | +/* | ||
332 | + * Bitmap List public functions | ||
333 | + */ | ||
334 | + | ||
335 | +static void bitmap_free(Qcow2Bitmap *bm) | ||
336 | +{ | ||
337 | + g_free(bm->name); | ||
338 | + g_free(bm); | ||
339 | +} | ||
340 | + | ||
341 | +static void bitmap_list_free(Qcow2BitmapList *bm_list) | ||
342 | +{ | ||
343 | + Qcow2Bitmap *bm; | ||
344 | + | ||
345 | + if (bm_list == NULL) { | ||
346 | + return; | ||
347 | + } | ||
348 | + | ||
349 | + while ((bm = QSIMPLEQ_FIRST(bm_list)) != NULL) { | ||
350 | + QSIMPLEQ_REMOVE_HEAD(bm_list, entry); | ||
351 | + bitmap_free(bm); | ||
352 | + } | ||
353 | + | ||
354 | + g_free(bm_list); | ||
355 | +} | ||
356 | + | ||
357 | +static Qcow2BitmapList *bitmap_list_new(void) | ||
358 | +{ | ||
359 | + Qcow2BitmapList *bm_list = g_new(Qcow2BitmapList, 1); | ||
360 | + QSIMPLEQ_INIT(bm_list); | ||
361 | + | ||
362 | + return bm_list; | ||
363 | +} | ||
364 | + | ||
365 | +/* bitmap_list_load | ||
366 | + * Get bitmap list from qcow2 image. Actually reads bitmap directory, | ||
367 | + * checks it and convert to bitmap list. | ||
368 | + */ | ||
369 | +static Qcow2BitmapList *bitmap_list_load(BlockDriverState *bs, uint64_t offset, | ||
370 | + uint64_t size, Error **errp) | ||
371 | +{ | ||
372 | + int ret; | ||
373 | + BDRVQcow2State *s = bs->opaque; | ||
374 | + uint8_t *dir, *dir_end; | ||
375 | + Qcow2BitmapDirEntry *e; | ||
376 | + uint32_t nb_dir_entries = 0; | ||
377 | + Qcow2BitmapList *bm_list = NULL; | ||
378 | + | ||
379 | + if (size == 0) { | ||
380 | + error_setg(errp, "Requested bitmap directory size is zero"); | ||
381 | + return NULL; | ||
382 | + } | ||
383 | + | ||
384 | + if (size > QCOW2_MAX_BITMAP_DIRECTORY_SIZE) { | ||
385 | + error_setg(errp, "Requested bitmap directory size is too big"); | ||
386 | + return NULL; | ||
387 | + } | ||
388 | + | ||
389 | + dir = g_try_malloc(size); | ||
390 | + if (dir == NULL) { | ||
391 | + error_setg(errp, "Failed to allocate space for bitmap directory"); | ||
392 | + return NULL; | ||
393 | + } | ||
394 | + dir_end = dir + size; | ||
395 | + | ||
396 | + ret = bdrv_pread(bs->file, offset, dir, size); | ||
397 | + if (ret < 0) { | ||
398 | + error_setg_errno(errp, -ret, "Failed to read bitmap directory"); | ||
399 | + goto fail; | ||
400 | + } | ||
401 | + | ||
402 | + bm_list = bitmap_list_new(); | ||
403 | + for (e = (Qcow2BitmapDirEntry *)dir; | ||
404 | + e < (Qcow2BitmapDirEntry *)dir_end; | ||
405 | + e = next_dir_entry(e)) | ||
406 | + { | ||
407 | + Qcow2Bitmap *bm; | ||
408 | + | ||
409 | + if ((uint8_t *)(e + 1) > dir_end) { | ||
410 | + goto broken_dir; | ||
411 | + } | ||
412 | + | ||
413 | + if (++nb_dir_entries > s->nb_bitmaps) { | ||
414 | + error_setg(errp, "More bitmaps found than specified in header" | ||
415 | + " extension"); | ||
416 | + goto fail; | ||
417 | + } | ||
418 | + bitmap_dir_entry_to_cpu(e); | ||
419 | + | ||
420 | + if ((uint8_t *)next_dir_entry(e) > dir_end) { | ||
421 | + goto broken_dir; | ||
422 | + } | ||
423 | + | ||
424 | + if (e->extra_data_size != 0) { | ||
425 | + error_setg(errp, "Bitmap extra data is not supported"); | ||
426 | + goto fail; | ||
427 | + } | ||
428 | + | ||
429 | + ret = check_dir_entry(bs, e); | ||
430 | + if (ret < 0) { | ||
431 | + error_setg(errp, "Bitmap '%.*s' doesn't satisfy the constraints", | ||
432 | + e->name_size, dir_entry_name_field(e)); | ||
433 | + goto fail; | ||
434 | + } | ||
435 | + | ||
436 | + bm = g_new(Qcow2Bitmap, 1); | ||
437 | + bm->table.offset = e->bitmap_table_offset; | ||
438 | + bm->table.size = e->bitmap_table_size; | ||
439 | + bm->flags = e->flags; | ||
440 | + bm->granularity_bits = e->granularity_bits; | ||
441 | + bm->name = dir_entry_copy_name(e); | ||
442 | + QSIMPLEQ_INSERT_TAIL(bm_list, bm, entry); | ||
443 | + } | ||
444 | + | ||
445 | + if (nb_dir_entries != s->nb_bitmaps) { | ||
446 | + error_setg(errp, "Less bitmaps found than specified in header" | ||
447 | + " extension"); | ||
448 | + goto fail; | ||
449 | + } | ||
450 | + | ||
451 | + if ((uint8_t *)e != dir_end) { | ||
452 | + goto broken_dir; | ||
453 | + } | ||
454 | + | ||
455 | + g_free(dir); | ||
456 | + return bm_list; | ||
457 | + | ||
458 | +broken_dir: | ||
459 | + ret = -EINVAL; | ||
460 | + error_setg(errp, "Broken bitmap directory"); | ||
461 | + | ||
462 | +fail: | ||
463 | + g_free(dir); | ||
464 | + bitmap_list_free(bm_list); | ||
465 | + | ||
466 | + return NULL; | ||
467 | +} | ||
468 | + | ||
469 | +int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res, | ||
470 | + void **refcount_table, | ||
471 | + int64_t *refcount_table_size) | ||
472 | +{ | ||
473 | + int ret; | ||
474 | + BDRVQcow2State *s = bs->opaque; | ||
475 | + Qcow2BitmapList *bm_list; | ||
476 | + Qcow2Bitmap *bm; | ||
477 | + | ||
478 | + if (s->nb_bitmaps == 0) { | ||
479 | + return 0; | ||
480 | + } | ||
481 | + | ||
482 | + ret = qcow2_inc_refcounts_imrt(bs, res, refcount_table, refcount_table_size, | ||
483 | + s->bitmap_directory_offset, | ||
484 | + s->bitmap_directory_size); | ||
485 | + if (ret < 0) { | ||
486 | + return ret; | ||
487 | + } | ||
488 | + | ||
489 | + bm_list = bitmap_list_load(bs, s->bitmap_directory_offset, | ||
490 | + s->bitmap_directory_size, NULL); | ||
491 | + if (bm_list == NULL) { | ||
492 | + res->corruptions++; | ||
493 | + return -EINVAL; | ||
494 | + } | ||
495 | + | ||
496 | + QSIMPLEQ_FOREACH(bm, bm_list, entry) { | ||
497 | + uint64_t *bitmap_table = NULL; | ||
498 | + int i; | ||
499 | + | ||
500 | + ret = qcow2_inc_refcounts_imrt(bs, res, | ||
501 | + refcount_table, refcount_table_size, | ||
502 | + bm->table.offset, | ||
503 | + bm->table.size * sizeof(uint64_t)); | ||
504 | + if (ret < 0) { | ||
505 | + goto out; | ||
506 | + } | ||
507 | + | ||
508 | + ret = bitmap_table_load(bs, &bm->table, &bitmap_table); | ||
509 | + if (ret < 0) { | ||
510 | + res->corruptions++; | ||
511 | + goto out; | ||
512 | + } | ||
513 | + | ||
514 | + for (i = 0; i < bm->table.size; ++i) { | ||
515 | + uint64_t entry = bitmap_table[i]; | ||
516 | + uint64_t offset = entry & BME_TABLE_ENTRY_OFFSET_MASK; | ||
517 | + | ||
518 | + if (check_table_entry(entry, s->cluster_size) < 0) { | ||
519 | + res->corruptions++; | ||
520 | + continue; | ||
521 | + } | ||
522 | + | ||
523 | + if (offset == 0) { | ||
524 | + continue; | ||
525 | + } | ||
526 | + | ||
527 | + ret = qcow2_inc_refcounts_imrt(bs, res, | ||
528 | + refcount_table, refcount_table_size, | ||
529 | + offset, s->cluster_size); | ||
530 | + if (ret < 0) { | ||
531 | + g_free(bitmap_table); | ||
532 | + goto out; | ||
533 | + } | ||
534 | + } | ||
535 | + | ||
536 | + g_free(bitmap_table); | ||
537 | + } | ||
538 | + | ||
539 | +out: | ||
540 | + bitmap_list_free(bm_list); | ||
541 | + | ||
542 | + return ret; | ||
543 | +} | ||
544 | diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c | ||
545 | index XXXXXXX..XXXXXXX 100644 | ||
546 | --- a/block/qcow2-refcount.c | ||
547 | +++ b/block/qcow2-refcount.c | ||
548 | @@ -XXX,XX +XXX,XX @@ static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res, | ||
549 | } | ||
550 | } | ||
551 | |||
552 | + /* bitmaps */ | ||
553 | + ret = qcow2_check_bitmaps_refcounts(bs, res, refcount_table, nb_clusters); | ||
554 | + if (ret < 0) { | ||
555 | + return ret; | ||
556 | + } | ||
557 | + | ||
558 | return check_refblocks(bs, res, fix, rebuild, refcount_table, nb_clusters); | ||
559 | } | ||
560 | |||
561 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
562 | index XXXXXXX..XXXXXXX 100644 | ||
563 | --- a/block/qcow2.c | ||
564 | +++ b/block/qcow2.c | ||
565 | @@ -XXX,XX +XXX,XX @@ typedef struct { | ||
566 | #define QCOW2_EXT_MAGIC_BACKING_FORMAT 0xE2792ACA | ||
567 | #define QCOW2_EXT_MAGIC_FEATURE_TABLE 0x6803f857 | ||
568 | #define QCOW2_EXT_MAGIC_CRYPTO_HEADER 0x0537be77 | ||
569 | +#define QCOW2_EXT_MAGIC_BITMAPS 0x23852875 | ||
570 | |||
571 | static int qcow2_probe(const uint8_t *buf, int buf_size, const char *filename) | ||
572 | { | ||
573 | @@ -XXX,XX +XXX,XX @@ static ssize_t qcow2_crypto_hdr_write_func(QCryptoBlock *block, size_t offset, | ||
574 | */ | ||
575 | static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset, | ||
576 | uint64_t end_offset, void **p_feature_table, | ||
577 | - int flags, Error **errp) | ||
578 | + int flags, bool *need_update_header, | ||
579 | + Error **errp) | ||
580 | { | ||
581 | BDRVQcow2State *s = bs->opaque; | ||
582 | QCowExtension ext; | ||
583 | uint64_t offset; | ||
584 | int ret; | ||
585 | + Qcow2BitmapHeaderExt bitmaps_ext; | ||
586 | + | ||
587 | + if (need_update_header != NULL) { | ||
588 | + *need_update_header = false; | ||
589 | + } | ||
590 | |||
591 | #ifdef DEBUG_EXT | ||
592 | printf("qcow2_read_extensions: start=%ld end=%ld\n", start_offset, end_offset); | ||
593 | @@ -XXX,XX +XXX,XX @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset, | ||
594 | } | ||
595 | } break; | ||
596 | |||
597 | + case QCOW2_EXT_MAGIC_BITMAPS: | ||
598 | + if (ext.len != sizeof(bitmaps_ext)) { | ||
599 | + error_setg_errno(errp, -ret, "bitmaps_ext: " | ||
600 | + "Invalid extension length"); | ||
601 | + return -EINVAL; | ||
602 | + } | ||
603 | + | ||
604 | + if (!(s->autoclear_features & QCOW2_AUTOCLEAR_BITMAPS)) { | ||
605 | + error_report("WARNING: a program lacking bitmap support " | ||
606 | + "modified this file, so all bitmaps are now " | ||
607 | + "considered inconsistent. Some clusters may be " | ||
608 | + "leaked, run 'qemu-img check -r' on the image " | ||
609 | + "file to fix."); | ||
610 | + if (need_update_header != NULL) { | ||
611 | + /* Updating is needed to drop invalid bitmap extension. */ | ||
612 | + *need_update_header = true; | ||
613 | + } | ||
614 | + break; | ||
615 | + } | ||
616 | + | ||
617 | + ret = bdrv_pread(bs->file, offset, &bitmaps_ext, ext.len); | ||
618 | + if (ret < 0) { | ||
619 | + error_setg_errno(errp, -ret, "bitmaps_ext: " | ||
620 | + "Could not read ext header"); | ||
621 | + return ret; | ||
622 | + } | ||
623 | + | ||
624 | + if (bitmaps_ext.reserved32 != 0) { | ||
625 | + error_setg_errno(errp, -ret, "bitmaps_ext: " | ||
626 | + "Reserved field is not zero"); | ||
627 | + return -EINVAL; | ||
628 | + } | ||
629 | + | ||
630 | + be32_to_cpus(&bitmaps_ext.nb_bitmaps); | ||
631 | + be64_to_cpus(&bitmaps_ext.bitmap_directory_size); | ||
632 | + be64_to_cpus(&bitmaps_ext.bitmap_directory_offset); | ||
633 | + | ||
634 | + if (bitmaps_ext.nb_bitmaps > QCOW2_MAX_BITMAPS) { | ||
635 | + error_setg(errp, | ||
636 | + "bitmaps_ext: Image has %" PRIu32 " bitmaps, " | ||
637 | + "exceeding the QEMU supported maximum of %d", | ||
638 | + bitmaps_ext.nb_bitmaps, QCOW2_MAX_BITMAPS); | ||
639 | + return -EINVAL; | ||
640 | + } | ||
641 | + | ||
642 | + if (bitmaps_ext.nb_bitmaps == 0) { | ||
643 | + error_setg(errp, "found bitmaps extension with zero bitmaps"); | ||
644 | + return -EINVAL; | ||
645 | + } | ||
646 | + | ||
647 | + if (bitmaps_ext.bitmap_directory_offset & (s->cluster_size - 1)) { | ||
648 | + error_setg(errp, "bitmaps_ext: " | ||
649 | + "invalid bitmap directory offset"); | ||
650 | + return -EINVAL; | ||
651 | + } | ||
652 | + | ||
653 | + if (bitmaps_ext.bitmap_directory_size > | ||
654 | + QCOW2_MAX_BITMAP_DIRECTORY_SIZE) { | ||
655 | + error_setg(errp, "bitmaps_ext: " | ||
656 | + "bitmap directory size (%" PRIu64 ") exceeds " | ||
657 | + "the maximum supported size (%d)", | ||
658 | + bitmaps_ext.bitmap_directory_size, | ||
659 | + QCOW2_MAX_BITMAP_DIRECTORY_SIZE); | ||
660 | + return -EINVAL; | ||
661 | + } | ||
662 | + | ||
663 | + s->nb_bitmaps = bitmaps_ext.nb_bitmaps; | ||
664 | + s->bitmap_directory_offset = | ||
665 | + bitmaps_ext.bitmap_directory_offset; | ||
666 | + s->bitmap_directory_size = | ||
667 | + bitmaps_ext.bitmap_directory_size; | ||
668 | + | ||
669 | +#ifdef DEBUG_EXT | ||
670 | + printf("Qcow2: Got bitmaps extension: " | ||
671 | + "offset=%" PRIu64 " nb_bitmaps=%" PRIu32 "\n", | ||
672 | + s->bitmap_directory_offset, s->nb_bitmaps); | ||
673 | +#endif | ||
674 | + break; | ||
675 | + | ||
676 | default: | ||
677 | /* unknown magic - save it in case we need to rewrite the header */ | ||
678 | { | ||
679 | @@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags, | ||
680 | Error *local_err = NULL; | ||
681 | uint64_t ext_end; | ||
682 | uint64_t l1_vm_state_index; | ||
683 | + bool update_header = false; | ||
684 | |||
685 | ret = bdrv_pread(bs->file, 0, &header, sizeof(header)); | ||
686 | if (ret < 0) { | ||
687 | @@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags, | ||
688 | if (s->incompatible_features & ~QCOW2_INCOMPAT_MASK) { | ||
689 | void *feature_table = NULL; | ||
690 | qcow2_read_extensions(bs, header.header_length, ext_end, | ||
691 | - &feature_table, flags, NULL); | ||
692 | + &feature_table, flags, NULL, NULL); | ||
693 | report_unsupported_feature(errp, feature_table, | ||
694 | s->incompatible_features & | ||
695 | ~QCOW2_INCOMPAT_MASK); | ||
696 | @@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags, | ||
697 | |||
698 | /* read qcow2 extensions */ | ||
699 | if (qcow2_read_extensions(bs, header.header_length, ext_end, NULL, | ||
700 | - flags, &local_err)) { | ||
701 | + flags, &update_header, &local_err)) { | ||
702 | error_propagate(errp, local_err); | ||
703 | ret = -EINVAL; | ||
704 | goto fail; | ||
705 | @@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags, | ||
706 | } | ||
707 | |||
708 | /* Clear unknown autoclear feature bits */ | ||
709 | - if (!bs->read_only && !(flags & BDRV_O_INACTIVE) && s->autoclear_features) { | ||
710 | - s->autoclear_features = 0; | ||
711 | + update_header |= s->autoclear_features & ~QCOW2_AUTOCLEAR_MASK; | ||
712 | + | ||
713 | + if (update_header && !bs->read_only && !(flags & BDRV_O_INACTIVE)) { | ||
714 | + s->autoclear_features &= QCOW2_AUTOCLEAR_MASK; | ||
715 | ret = qcow2_update_header(bs); | ||
716 | if (ret < 0) { | ||
717 | error_setg_errno(errp, -ret, "Could not update qcow2 header"); | ||
718 | @@ -XXX,XX +XXX,XX @@ int qcow2_update_header(BlockDriverState *bs) | ||
719 | buflen -= ret; | ||
720 | } | ||
721 | |||
722 | + /* Bitmap extension */ | ||
723 | + if (s->nb_bitmaps > 0) { | ||
724 | + Qcow2BitmapHeaderExt bitmaps_header = { | ||
725 | + .nb_bitmaps = cpu_to_be32(s->nb_bitmaps), | ||
726 | + .bitmap_directory_size = | ||
727 | + cpu_to_be64(s->bitmap_directory_size), | ||
728 | + .bitmap_directory_offset = | ||
729 | + cpu_to_be64(s->bitmap_directory_offset) | ||
730 | + }; | ||
731 | + ret = header_ext_add(buf, QCOW2_EXT_MAGIC_BITMAPS, | ||
732 | + &bitmaps_header, sizeof(bitmaps_header), | ||
733 | + buflen); | ||
734 | + if (ret < 0) { | ||
735 | + goto fail; | ||
736 | + } | ||
737 | + buf += ret; | ||
738 | + buflen -= ret; | ||
739 | + } | ||
740 | + | ||
741 | /* Keep unknown header extensions */ | ||
742 | QLIST_FOREACH(uext, &s->unknown_header_ext, next) { | ||
743 | ret = header_ext_add(buf, uext->magic, uext->data, uext->len, buflen); | ||
744 | @@ -XXX,XX +XXX,XX @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | ||
745 | return -ENOTSUP; | ||
746 | } | ||
747 | |||
748 | + /* cannot proceed if image has bitmaps */ | ||
749 | + if (s->nb_bitmaps) { | ||
750 | + /* TODO: resize bitmaps in the image */ | ||
751 | + error_setg(errp, "Can't resize an image which has bitmaps"); | ||
752 | + return -ENOTSUP; | ||
753 | + } | ||
754 | + | ||
755 | /* shrinking is currently not supported */ | ||
756 | if (offset < bs->total_sectors * 512) { | ||
757 | error_setg(errp, "qcow2 doesn't support shrinking images yet"); | ||
758 | -- | ||
759 | 2.9.4 | ||
760 | |||
761 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
4 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
5 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
6 | Message-id: 20170628120530.31251-10-vsementsov@virtuozzo.com | ||
7 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
8 | --- | ||
9 | block/dirty-bitmap.c | 3 ++- | ||
10 | 1 file changed, 2 insertions(+), 1 deletion(-) | ||
11 | |||
12 | diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/block/dirty-bitmap.c | ||
15 | +++ b/block/dirty-bitmap.c | ||
16 | @@ -XXX,XX +XXX,XX @@ struct BdrvDirtyBitmap { | ||
17 | BdrvDirtyBitmap *successor; /* Anonymous child; implies frozen status */ | ||
18 | char *name; /* Optional non-empty unique ID */ | ||
19 | int64_t size; /* Size of the bitmap (Number of sectors) */ | ||
20 | - bool disabled; /* Bitmap is read-only */ | ||
21 | + bool disabled; /* Bitmap is disabled. It ignores all writes to | ||
22 | + the device */ | ||
23 | int active_iterators; /* How many iterators are active */ | ||
24 | QLIST_ENTRY(BdrvDirtyBitmap) list; | ||
25 | }; | ||
26 | -- | ||
27 | 2.9.4 | ||
28 | |||
29 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | It will be needed in following commits for persistent bitmaps. | ||
4 | If bitmap is loaded from read-only storage (and we can't mark it | ||
5 | "in use" in this storage) corresponding BdrvDirtyBitmap should be | ||
6 | read-only. | ||
7 | |||
8 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
9 | Message-id: 20170628120530.31251-11-vsementsov@virtuozzo.com | ||
10 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
11 | --- | ||
12 | include/block/dirty-bitmap.h | 4 ++++ | ||
13 | block/dirty-bitmap.c | 36 ++++++++++++++++++++++++++++++++++++ | ||
14 | block/io.c | 8 ++++++++ | ||
15 | blockdev.c | 6 ++++++ | ||
16 | 4 files changed, 54 insertions(+) | ||
17 | |||
18 | diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/include/block/dirty-bitmap.h | ||
21 | +++ b/include/block/dirty-bitmap.h | ||
22 | @@ -XXX,XX +XXX,XX @@ void bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap, | ||
23 | bool finish); | ||
24 | void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap); | ||
25 | |||
26 | +void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap, bool value); | ||
27 | + | ||
28 | /* Functions that require manual locking. */ | ||
29 | void bdrv_dirty_bitmap_lock(BdrvDirtyBitmap *bitmap); | ||
30 | void bdrv_dirty_bitmap_unlock(BdrvDirtyBitmap *bitmap); | ||
31 | @@ -XXX,XX +XXX,XX @@ void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *hbi, int64_t sector_num); | ||
32 | int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap); | ||
33 | int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap); | ||
34 | void bdrv_dirty_bitmap_truncate(BlockDriverState *bs); | ||
35 | +bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap); | ||
36 | +bool bdrv_has_readonly_bitmaps(BlockDriverState *bs); | ||
37 | |||
38 | #endif | ||
39 | diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c | ||
40 | index XXXXXXX..XXXXXXX 100644 | ||
41 | --- a/block/dirty-bitmap.c | ||
42 | +++ b/block/dirty-bitmap.c | ||
43 | @@ -XXX,XX +XXX,XX @@ struct BdrvDirtyBitmap { | ||
44 | bool disabled; /* Bitmap is disabled. It ignores all writes to | ||
45 | the device */ | ||
46 | int active_iterators; /* How many iterators are active */ | ||
47 | + bool readonly; /* Bitmap is read-only. This field also | ||
48 | + prevents the respective image from being | ||
49 | + modified (i.e. blocks writes and discards). | ||
50 | + Such operations must fail and both the image | ||
51 | + and this bitmap must remain unchanged while | ||
52 | + this flag is set. */ | ||
53 | QLIST_ENTRY(BdrvDirtyBitmap) list; | ||
54 | }; | ||
55 | |||
56 | @@ -XXX,XX +XXX,XX @@ void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap, | ||
57 | int64_t cur_sector, int64_t nr_sectors) | ||
58 | { | ||
59 | assert(bdrv_dirty_bitmap_enabled(bitmap)); | ||
60 | + assert(!bdrv_dirty_bitmap_readonly(bitmap)); | ||
61 | hbitmap_set(bitmap->bitmap, cur_sector, nr_sectors); | ||
62 | } | ||
63 | |||
64 | @@ -XXX,XX +XXX,XX @@ void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap, | ||
65 | int64_t cur_sector, int64_t nr_sectors) | ||
66 | { | ||
67 | assert(bdrv_dirty_bitmap_enabled(bitmap)); | ||
68 | + assert(!bdrv_dirty_bitmap_readonly(bitmap)); | ||
69 | hbitmap_reset(bitmap->bitmap, cur_sector, nr_sectors); | ||
70 | } | ||
71 | |||
72 | @@ -XXX,XX +XXX,XX @@ void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap, | ||
73 | void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out) | ||
74 | { | ||
75 | assert(bdrv_dirty_bitmap_enabled(bitmap)); | ||
76 | + assert(!bdrv_dirty_bitmap_readonly(bitmap)); | ||
77 | bdrv_dirty_bitmap_lock(bitmap); | ||
78 | if (!out) { | ||
79 | hbitmap_reset_all(bitmap->bitmap); | ||
80 | @@ -XXX,XX +XXX,XX @@ void bdrv_undo_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *in) | ||
81 | { | ||
82 | HBitmap *tmp = bitmap->bitmap; | ||
83 | assert(bdrv_dirty_bitmap_enabled(bitmap)); | ||
84 | + assert(!bdrv_dirty_bitmap_readonly(bitmap)); | ||
85 | bitmap->bitmap = in; | ||
86 | hbitmap_free(tmp); | ||
87 | } | ||
88 | @@ -XXX,XX +XXX,XX @@ void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector, | ||
89 | if (!bdrv_dirty_bitmap_enabled(bitmap)) { | ||
90 | continue; | ||
91 | } | ||
92 | + assert(!bdrv_dirty_bitmap_readonly(bitmap)); | ||
93 | hbitmap_set(bitmap->bitmap, cur_sector, nr_sectors); | ||
94 | } | ||
95 | bdrv_dirty_bitmaps_unlock(bs); | ||
96 | @@ -XXX,XX +XXX,XX @@ int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap) | ||
97 | { | ||
98 | return hbitmap_count(bitmap->meta); | ||
99 | } | ||
100 | + | ||
101 | +bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap) | ||
102 | +{ | ||
103 | + return bitmap->readonly; | ||
104 | +} | ||
105 | + | ||
106 | +/* Called with BQL taken. */ | ||
107 | +void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap, bool value) | ||
108 | +{ | ||
109 | + qemu_mutex_lock(bitmap->mutex); | ||
110 | + bitmap->readonly = value; | ||
111 | + qemu_mutex_unlock(bitmap->mutex); | ||
112 | +} | ||
113 | + | ||
114 | +bool bdrv_has_readonly_bitmaps(BlockDriverState *bs) | ||
115 | +{ | ||
116 | + BdrvDirtyBitmap *bm; | ||
117 | + QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) { | ||
118 | + if (bm->readonly) { | ||
119 | + return true; | ||
120 | + } | ||
121 | + } | ||
122 | + | ||
123 | + return false; | ||
124 | +} | ||
125 | diff --git a/block/io.c b/block/io.c | ||
126 | index XXXXXXX..XXXXXXX 100644 | ||
127 | --- a/block/io.c | ||
128 | +++ b/block/io.c | ||
129 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child, | ||
130 | uint64_t bytes_remaining = bytes; | ||
131 | int max_transfer; | ||
132 | |||
133 | + if (bdrv_has_readonly_bitmaps(bs)) { | ||
134 | + return -EPERM; | ||
135 | + } | ||
136 | + | ||
137 | assert(is_power_of_2(align)); | ||
138 | assert((offset & (align - 1)) == 0); | ||
139 | assert((bytes & (align - 1)) == 0); | ||
140 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pdiscard(BlockDriverState *bs, int64_t offset, | ||
141 | return -ENOMEDIUM; | ||
142 | } | ||
143 | |||
144 | + if (bdrv_has_readonly_bitmaps(bs)) { | ||
145 | + return -EPERM; | ||
146 | + } | ||
147 | + | ||
148 | ret = bdrv_check_byte_request(bs, offset, bytes); | ||
149 | if (ret < 0) { | ||
150 | return ret; | ||
151 | diff --git a/blockdev.c b/blockdev.c | ||
152 | index XXXXXXX..XXXXXXX 100644 | ||
153 | --- a/blockdev.c | ||
154 | +++ b/blockdev.c | ||
155 | @@ -XXX,XX +XXX,XX @@ static void block_dirty_bitmap_clear_prepare(BlkActionState *common, | ||
156 | } else if (!bdrv_dirty_bitmap_enabled(state->bitmap)) { | ||
157 | error_setg(errp, "Cannot clear a disabled bitmap"); | ||
158 | return; | ||
159 | + } else if (bdrv_dirty_bitmap_readonly(state->bitmap)) { | ||
160 | + error_setg(errp, "Cannot clear a readonly bitmap"); | ||
161 | + return; | ||
162 | } | ||
163 | |||
164 | bdrv_clear_dirty_bitmap(state->bitmap, &state->backup); | ||
165 | @@ -XXX,XX +XXX,XX @@ void qmp_block_dirty_bitmap_clear(const char *node, const char *name, | ||
166 | "Bitmap '%s' is currently disabled and cannot be cleared", | ||
167 | name); | ||
168 | return; | ||
169 | + } else if (bdrv_dirty_bitmap_readonly(bitmap)) { | ||
170 | + error_setg(errp, "Bitmap '%s' is readonly and cannot be cleared", name); | ||
171 | + return; | ||
172 | } | ||
173 | |||
174 | bdrv_clear_dirty_bitmap(bitmap, NULL); | ||
175 | -- | ||
176 | 2.9.4 | ||
177 | |||
178 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | Auto loading bitmaps are bitmaps in Qcow2, with the AUTO flag set. They | ||
4 | are loaded when the image is opened and become BdrvDirtyBitmaps for the | ||
5 | corresponding drive. | ||
6 | |||
7 | Extra data in bitmaps is not supported for now. | ||
8 | |||
9 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
10 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
11 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
12 | Message-id: 20170628120530.31251-12-vsementsov@virtuozzo.com | ||
13 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
14 | --- | ||
15 | block/qcow2.h | 2 + | ||
16 | block/qcow2-bitmap.c | 389 +++++++++++++++++++++++++++++++++++++++++++++++++++ | ||
17 | block/qcow2.c | 17 ++- | ||
18 | 3 files changed, 406 insertions(+), 2 deletions(-) | ||
19 | |||
20 | diff --git a/block/qcow2.h b/block/qcow2.h | ||
21 | index XXXXXXX..XXXXXXX 100644 | ||
22 | --- a/block/qcow2.h | ||
23 | +++ b/block/qcow2.h | ||
24 | @@ -XXX,XX +XXX,XX @@ void qcow2_cache_put(BlockDriverState *bs, Qcow2Cache *c, void **table); | ||
25 | int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res, | ||
26 | void **refcount_table, | ||
27 | int64_t *refcount_table_size); | ||
28 | +bool qcow2_load_autoloading_dirty_bitmaps(BlockDriverState *bs, Error **errp); | ||
29 | + | ||
30 | #endif | ||
31 | diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c | ||
32 | index XXXXXXX..XXXXXXX 100644 | ||
33 | --- a/block/qcow2-bitmap.c | ||
34 | +++ b/block/qcow2-bitmap.c | ||
35 | @@ -XXX,XX +XXX,XX @@ | ||
36 | |||
37 | /* Bitmap directory entry flags */ | ||
38 | #define BME_RESERVED_FLAGS 0xfffffffcU | ||
39 | +#define BME_FLAG_IN_USE (1U << 0) | ||
40 | +#define BME_FLAG_AUTO (1U << 1) | ||
41 | |||
42 | /* bits [1, 8] U [56, 63] are reserved */ | ||
43 | #define BME_TABLE_ENTRY_RESERVED_MASK 0xff000000000001feULL | ||
44 | @@ -XXX,XX +XXX,XX @@ typedef enum BitmapType { | ||
45 | BT_DIRTY_TRACKING_BITMAP = 1 | ||
46 | } BitmapType; | ||
47 | |||
48 | +static inline bool can_write(BlockDriverState *bs) | ||
49 | +{ | ||
50 | + return !bdrv_is_read_only(bs) && !(bdrv_get_flags(bs) & BDRV_O_INACTIVE); | ||
51 | +} | ||
52 | + | ||
53 | +static int update_header_sync(BlockDriverState *bs) | ||
54 | +{ | ||
55 | + int ret; | ||
56 | + | ||
57 | + ret = qcow2_update_header(bs); | ||
58 | + if (ret < 0) { | ||
59 | + return ret; | ||
60 | + } | ||
61 | + | ||
62 | + return bdrv_flush(bs); | ||
63 | +} | ||
64 | + | ||
65 | static int check_table_entry(uint64_t entry, int cluster_size) | ||
66 | { | ||
67 | uint64_t offset; | ||
68 | @@ -XXX,XX +XXX,XX @@ fail: | ||
69 | return ret; | ||
70 | } | ||
71 | |||
72 | +/* This function returns the number of disk sectors covered by a single qcow2 | ||
73 | + * cluster of bitmap data. */ | ||
74 | +static uint64_t sectors_covered_by_bitmap_cluster(const BDRVQcow2State *s, | ||
75 | + const BdrvDirtyBitmap *bitmap) | ||
76 | +{ | ||
77 | + uint32_t sector_granularity = | ||
78 | + bdrv_dirty_bitmap_granularity(bitmap) >> BDRV_SECTOR_BITS; | ||
79 | + | ||
80 | + return (uint64_t)sector_granularity * (s->cluster_size << 3); | ||
81 | +} | ||
82 | + | ||
83 | +/* load_bitmap_data | ||
84 | + * @bitmap_table entries must satisfy specification constraints. | ||
85 | + * @bitmap must be cleared */ | ||
86 | +static int load_bitmap_data(BlockDriverState *bs, | ||
87 | + const uint64_t *bitmap_table, | ||
88 | + uint32_t bitmap_table_size, | ||
89 | + BdrvDirtyBitmap *bitmap) | ||
90 | +{ | ||
91 | + int ret = 0; | ||
92 | + BDRVQcow2State *s = bs->opaque; | ||
93 | + uint64_t sector, sbc; | ||
94 | + uint64_t bm_size = bdrv_dirty_bitmap_size(bitmap); | ||
95 | + uint8_t *buf = NULL; | ||
96 | + uint64_t i, tab_size = | ||
97 | + size_to_clusters(s, | ||
98 | + bdrv_dirty_bitmap_serialization_size(bitmap, 0, bm_size)); | ||
99 | + | ||
100 | + if (tab_size != bitmap_table_size || tab_size > BME_MAX_TABLE_SIZE) { | ||
101 | + return -EINVAL; | ||
102 | + } | ||
103 | + | ||
104 | + buf = g_malloc(s->cluster_size); | ||
105 | + sbc = sectors_covered_by_bitmap_cluster(s, bitmap); | ||
106 | + for (i = 0, sector = 0; i < tab_size; ++i, sector += sbc) { | ||
107 | + uint64_t count = MIN(bm_size - sector, sbc); | ||
108 | + uint64_t entry = bitmap_table[i]; | ||
109 | + uint64_t offset = entry & BME_TABLE_ENTRY_OFFSET_MASK; | ||
110 | + | ||
111 | + assert(check_table_entry(entry, s->cluster_size) == 0); | ||
112 | + | ||
113 | + if (offset == 0) { | ||
114 | + if (entry & BME_TABLE_ENTRY_FLAG_ALL_ONES) { | ||
115 | + bdrv_dirty_bitmap_deserialize_ones(bitmap, sector, count, | ||
116 | + false); | ||
117 | + } else { | ||
118 | + /* No need to deserialize zeros because the dirty bitmap is | ||
119 | + * already cleared */ | ||
120 | + } | ||
121 | + } else { | ||
122 | + ret = bdrv_pread(bs->file, offset, buf, s->cluster_size); | ||
123 | + if (ret < 0) { | ||
124 | + goto finish; | ||
125 | + } | ||
126 | + bdrv_dirty_bitmap_deserialize_part(bitmap, buf, sector, count, | ||
127 | + false); | ||
128 | + } | ||
129 | + } | ||
130 | + ret = 0; | ||
131 | + | ||
132 | + bdrv_dirty_bitmap_deserialize_finish(bitmap); | ||
133 | + | ||
134 | +finish: | ||
135 | + g_free(buf); | ||
136 | + | ||
137 | + return ret; | ||
138 | +} | ||
139 | + | ||
140 | +static BdrvDirtyBitmap *load_bitmap(BlockDriverState *bs, | ||
141 | + Qcow2Bitmap *bm, Error **errp) | ||
142 | +{ | ||
143 | + int ret; | ||
144 | + uint64_t *bitmap_table = NULL; | ||
145 | + uint32_t granularity; | ||
146 | + BdrvDirtyBitmap *bitmap = NULL; | ||
147 | + | ||
148 | + if (bm->flags & BME_FLAG_IN_USE) { | ||
149 | + error_setg(errp, "Bitmap '%s' is in use", bm->name); | ||
150 | + goto fail; | ||
151 | + } | ||
152 | + | ||
153 | + ret = bitmap_table_load(bs, &bm->table, &bitmap_table); | ||
154 | + if (ret < 0) { | ||
155 | + error_setg_errno(errp, -ret, | ||
156 | + "Could not read bitmap_table table from image for " | ||
157 | + "bitmap '%s'", bm->name); | ||
158 | + goto fail; | ||
159 | + } | ||
160 | + | ||
161 | + granularity = 1U << bm->granularity_bits; | ||
162 | + bitmap = bdrv_create_dirty_bitmap(bs, granularity, bm->name, errp); | ||
163 | + if (bitmap == NULL) { | ||
164 | + goto fail; | ||
165 | + } | ||
166 | + | ||
167 | + ret = load_bitmap_data(bs, bitmap_table, bm->table.size, bitmap); | ||
168 | + if (ret < 0) { | ||
169 | + error_setg_errno(errp, -ret, "Could not read bitmap '%s' from image", | ||
170 | + bm->name); | ||
171 | + goto fail; | ||
172 | + } | ||
173 | + | ||
174 | + g_free(bitmap_table); | ||
175 | + return bitmap; | ||
176 | + | ||
177 | +fail: | ||
178 | + g_free(bitmap_table); | ||
179 | + if (bitmap != NULL) { | ||
180 | + bdrv_release_dirty_bitmap(bs, bitmap); | ||
181 | + } | ||
182 | + | ||
183 | + return NULL; | ||
184 | +} | ||
185 | + | ||
186 | /* | ||
187 | * Bitmap List | ||
188 | */ | ||
189 | @@ -XXX,XX +XXX,XX @@ static inline void bitmap_dir_entry_to_cpu(Qcow2BitmapDirEntry *entry) | ||
190 | be32_to_cpus(&entry->extra_data_size); | ||
191 | } | ||
192 | |||
193 | +static inline void bitmap_dir_entry_to_be(Qcow2BitmapDirEntry *entry) | ||
194 | +{ | ||
195 | + cpu_to_be64s(&entry->bitmap_table_offset); | ||
196 | + cpu_to_be32s(&entry->bitmap_table_size); | ||
197 | + cpu_to_be32s(&entry->flags); | ||
198 | + cpu_to_be16s(&entry->name_size); | ||
199 | + cpu_to_be32s(&entry->extra_data_size); | ||
200 | +} | ||
201 | + | ||
202 | static inline int calc_dir_entry_size(size_t name_size, size_t extra_data_size) | ||
203 | { | ||
204 | return align_offset(sizeof(Qcow2BitmapDirEntry) + | ||
205 | @@ -XXX,XX +XXX,XX @@ static int check_dir_entry(BlockDriverState *bs, Qcow2BitmapDirEntry *entry) | ||
206 | return fail ? -EINVAL : 0; | ||
207 | } | ||
208 | |||
209 | +static inline void bitmap_directory_to_be(uint8_t *dir, size_t size) | ||
210 | +{ | ||
211 | + uint8_t *end = dir + size; | ||
212 | + while (dir < end) { | ||
213 | + Qcow2BitmapDirEntry *e = (Qcow2BitmapDirEntry *)dir; | ||
214 | + dir += dir_entry_size(e); | ||
215 | + | ||
216 | + bitmap_dir_entry_to_be(e); | ||
217 | + } | ||
218 | +} | ||
219 | + | ||
220 | /* | ||
221 | * Bitmap List public functions | ||
222 | */ | ||
223 | @@ -XXX,XX +XXX,XX @@ static Qcow2BitmapList *bitmap_list_new(void) | ||
224 | return bm_list; | ||
225 | } | ||
226 | |||
227 | +static uint32_t bitmap_list_count(Qcow2BitmapList *bm_list) | ||
228 | +{ | ||
229 | + Qcow2Bitmap *bm; | ||
230 | + uint32_t nb_bitmaps = 0; | ||
231 | + | ||
232 | + QSIMPLEQ_FOREACH(bm, bm_list, entry) { | ||
233 | + nb_bitmaps++; | ||
234 | + } | ||
235 | + | ||
236 | + return nb_bitmaps; | ||
237 | +} | ||
238 | + | ||
239 | /* bitmap_list_load | ||
240 | * Get bitmap list from qcow2 image. Actually reads bitmap directory, | ||
241 | * checks it and convert to bitmap list. | ||
242 | @@ -XXX,XX +XXX,XX @@ out: | ||
243 | |||
244 | return ret; | ||
245 | } | ||
246 | + | ||
247 | +/* bitmap_list_store | ||
248 | + * Store bitmap list to qcow2 image as a bitmap directory. | ||
249 | + * Everything is checked. | ||
250 | + */ | ||
251 | +static int bitmap_list_store(BlockDriverState *bs, Qcow2BitmapList *bm_list, | ||
252 | + uint64_t *offset, uint64_t *size, bool in_place) | ||
253 | +{ | ||
254 | + int ret; | ||
255 | + uint8_t *dir; | ||
256 | + int64_t dir_offset = 0; | ||
257 | + uint64_t dir_size = 0; | ||
258 | + Qcow2Bitmap *bm; | ||
259 | + Qcow2BitmapDirEntry *e; | ||
260 | + | ||
261 | + QSIMPLEQ_FOREACH(bm, bm_list, entry) { | ||
262 | + dir_size += calc_dir_entry_size(strlen(bm->name), 0); | ||
263 | + } | ||
264 | + | ||
265 | + if (dir_size == 0 || dir_size > QCOW2_MAX_BITMAP_DIRECTORY_SIZE) { | ||
266 | + return -EINVAL; | ||
267 | + } | ||
268 | + | ||
269 | + if (in_place) { | ||
270 | + if (*size != dir_size || *offset == 0) { | ||
271 | + return -EINVAL; | ||
272 | + } | ||
273 | + | ||
274 | + dir_offset = *offset; | ||
275 | + } | ||
276 | + | ||
277 | + dir = g_try_malloc(dir_size); | ||
278 | + if (dir == NULL) { | ||
279 | + return -ENOMEM; | ||
280 | + } | ||
281 | + | ||
282 | + e = (Qcow2BitmapDirEntry *)dir; | ||
283 | + QSIMPLEQ_FOREACH(bm, bm_list, entry) { | ||
284 | + e->bitmap_table_offset = bm->table.offset; | ||
285 | + e->bitmap_table_size = bm->table.size; | ||
286 | + e->flags = bm->flags; | ||
287 | + e->type = BT_DIRTY_TRACKING_BITMAP; | ||
288 | + e->granularity_bits = bm->granularity_bits; | ||
289 | + e->name_size = strlen(bm->name); | ||
290 | + e->extra_data_size = 0; | ||
291 | + memcpy(e + 1, bm->name, e->name_size); | ||
292 | + | ||
293 | + if (check_dir_entry(bs, e) < 0) { | ||
294 | + ret = -EINVAL; | ||
295 | + goto fail; | ||
296 | + } | ||
297 | + | ||
298 | + e = next_dir_entry(e); | ||
299 | + } | ||
300 | + | ||
301 | + bitmap_directory_to_be(dir, dir_size); | ||
302 | + | ||
303 | + if (!in_place) { | ||
304 | + dir_offset = qcow2_alloc_clusters(bs, dir_size); | ||
305 | + if (dir_offset < 0) { | ||
306 | + ret = dir_offset; | ||
307 | + goto fail; | ||
308 | + } | ||
309 | + } | ||
310 | + | ||
311 | + ret = qcow2_pre_write_overlap_check(bs, 0, dir_offset, dir_size); | ||
312 | + if (ret < 0) { | ||
313 | + goto fail; | ||
314 | + } | ||
315 | + | ||
316 | + ret = bdrv_pwrite(bs->file, dir_offset, dir, dir_size); | ||
317 | + if (ret < 0) { | ||
318 | + goto fail; | ||
319 | + } | ||
320 | + | ||
321 | + g_free(dir); | ||
322 | + | ||
323 | + if (!in_place) { | ||
324 | + *size = dir_size; | ||
325 | + *offset = dir_offset; | ||
326 | + } | ||
327 | + | ||
328 | + return 0; | ||
329 | + | ||
330 | +fail: | ||
331 | + g_free(dir); | ||
332 | + | ||
333 | + if (!in_place && dir_offset > 0) { | ||
334 | + qcow2_free_clusters(bs, dir_offset, dir_size, QCOW2_DISCARD_OTHER); | ||
335 | + } | ||
336 | + | ||
337 | + return ret; | ||
338 | +} | ||
339 | + | ||
340 | +/* | ||
341 | + * Bitmap List end | ||
342 | + */ | ||
343 | + | ||
344 | +static int update_ext_header_and_dir_in_place(BlockDriverState *bs, | ||
345 | + Qcow2BitmapList *bm_list) | ||
346 | +{ | ||
347 | + BDRVQcow2State *s = bs->opaque; | ||
348 | + int ret; | ||
349 | + | ||
350 | + if (!(s->autoclear_features & QCOW2_AUTOCLEAR_BITMAPS) || | ||
351 | + bm_list == NULL || QSIMPLEQ_EMPTY(bm_list) || | ||
352 | + bitmap_list_count(bm_list) != s->nb_bitmaps) | ||
353 | + { | ||
354 | + return -EINVAL; | ||
355 | + } | ||
356 | + | ||
357 | + s->autoclear_features &= ~(uint64_t)QCOW2_AUTOCLEAR_BITMAPS; | ||
358 | + ret = update_header_sync(bs); | ||
359 | + if (ret < 0) { | ||
360 | + /* Two variants are possible here: | ||
361 | + * 1. Autoclear flag is dropped, all bitmaps will be lost. | ||
362 | + * 2. Autoclear flag is not dropped, old state is left. | ||
363 | + */ | ||
364 | + return ret; | ||
365 | + } | ||
366 | + | ||
367 | + /* autoclear bit is not set, so we can safely update bitmap directory */ | ||
368 | + | ||
369 | + ret = bitmap_list_store(bs, bm_list, &s->bitmap_directory_offset, | ||
370 | + &s->bitmap_directory_size, true); | ||
371 | + if (ret < 0) { | ||
372 | + /* autoclear bit is cleared, so all leaked clusters would be removed on | ||
373 | + * qemu-img check */ | ||
374 | + return ret; | ||
375 | + } | ||
376 | + | ||
377 | + ret = update_header_sync(bs); | ||
378 | + if (ret < 0) { | ||
379 | + /* autoclear bit is cleared, so all leaked clusters would be removed on | ||
380 | + * qemu-img check */ | ||
381 | + return ret; | ||
382 | + } | ||
383 | + | ||
384 | + s->autoclear_features |= QCOW2_AUTOCLEAR_BITMAPS; | ||
385 | + return update_header_sync(bs); | ||
386 | + /* If final update_header_sync() fails, two variants are possible: | ||
387 | + * 1. Autoclear flag is not set, all bitmaps will be lost. | ||
388 | + * 2. Autoclear flag is set, header and directory are successfully updated. | ||
389 | + */ | ||
390 | +} | ||
391 | + | ||
392 | +/* for g_slist_foreach for GSList of BdrvDirtyBitmap* elements */ | ||
393 | +static void release_dirty_bitmap_helper(gpointer bitmap, | ||
394 | + gpointer bs) | ||
395 | +{ | ||
396 | + bdrv_release_dirty_bitmap(bs, bitmap); | ||
397 | +} | ||
398 | + | ||
399 | +/* for g_slist_foreach for GSList of BdrvDirtyBitmap* elements */ | ||
400 | +static void set_readonly_helper(gpointer bitmap, gpointer value) | ||
401 | +{ | ||
402 | + bdrv_dirty_bitmap_set_readonly(bitmap, (bool)value); | ||
403 | +} | ||
404 | + | ||
405 | +/* qcow2_load_autoloading_dirty_bitmaps() | ||
406 | + * Return value is a hint for caller: true means that the Qcow2 header was | ||
407 | + * updated. (false doesn't mean that the header should be updated by the | ||
408 | + * caller, it just means that updating was not needed or the image cannot be | ||
409 | + * written to). | ||
410 | + * On failure the function returns false. | ||
411 | + */ | ||
412 | +bool qcow2_load_autoloading_dirty_bitmaps(BlockDriverState *bs, Error **errp) | ||
413 | +{ | ||
414 | + BDRVQcow2State *s = bs->opaque; | ||
415 | + Qcow2BitmapList *bm_list; | ||
416 | + Qcow2Bitmap *bm; | ||
417 | + GSList *created_dirty_bitmaps = NULL; | ||
418 | + bool header_updated = false; | ||
419 | + | ||
420 | + if (s->nb_bitmaps == 0) { | ||
421 | + /* No bitmaps - nothing to do */ | ||
422 | + return false; | ||
423 | + } | ||
424 | + | ||
425 | + bm_list = bitmap_list_load(bs, s->bitmap_directory_offset, | ||
426 | + s->bitmap_directory_size, errp); | ||
427 | + if (bm_list == NULL) { | ||
428 | + return false; | ||
429 | + } | ||
430 | + | ||
431 | + QSIMPLEQ_FOREACH(bm, bm_list, entry) { | ||
432 | + if ((bm->flags & BME_FLAG_AUTO) && !(bm->flags & BME_FLAG_IN_USE)) { | ||
433 | + BdrvDirtyBitmap *bitmap = load_bitmap(bs, bm, errp); | ||
434 | + if (bitmap == NULL) { | ||
435 | + goto fail; | ||
436 | + } | ||
437 | + bm->flags |= BME_FLAG_IN_USE; | ||
438 | + created_dirty_bitmaps = | ||
439 | + g_slist_append(created_dirty_bitmaps, bitmap); | ||
440 | + } | ||
441 | + } | ||
442 | + | ||
443 | + if (created_dirty_bitmaps != NULL) { | ||
444 | + if (can_write(bs)) { | ||
445 | + /* in_use flags must be updated */ | ||
446 | + int ret = update_ext_header_and_dir_in_place(bs, bm_list); | ||
447 | + if (ret < 0) { | ||
448 | + error_setg_errno(errp, -ret, "Can't update bitmap directory"); | ||
449 | + goto fail; | ||
450 | + } | ||
451 | + header_updated = true; | ||
452 | + } else { | ||
453 | + g_slist_foreach(created_dirty_bitmaps, set_readonly_helper, | ||
454 | + (gpointer)true); | ||
455 | + } | ||
456 | + } | ||
457 | + | ||
458 | + g_slist_free(created_dirty_bitmaps); | ||
459 | + bitmap_list_free(bm_list); | ||
460 | + | ||
461 | + return header_updated; | ||
462 | + | ||
463 | +fail: | ||
464 | + g_slist_foreach(created_dirty_bitmaps, release_dirty_bitmap_helper, bs); | ||
465 | + g_slist_free(created_dirty_bitmaps); | ||
466 | + bitmap_list_free(bm_list); | ||
467 | + | ||
468 | + return false; | ||
469 | +} | ||
470 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
471 | index XXXXXXX..XXXXXXX 100644 | ||
472 | --- a/block/qcow2.c | ||
473 | +++ b/block/qcow2.c | ||
474 | @@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags, | ||
475 | |||
476 | /* Clear unknown autoclear feature bits */ | ||
477 | update_header |= s->autoclear_features & ~QCOW2_AUTOCLEAR_MASK; | ||
478 | - | ||
479 | - if (update_header && !bs->read_only && !(flags & BDRV_O_INACTIVE)) { | ||
480 | + update_header = | ||
481 | + update_header && !bs->read_only && !(flags & BDRV_O_INACTIVE); | ||
482 | + if (update_header) { | ||
483 | s->autoclear_features &= QCOW2_AUTOCLEAR_MASK; | ||
484 | + } | ||
485 | + | ||
486 | + if (qcow2_load_autoloading_dirty_bitmaps(bs, &local_err)) { | ||
487 | + update_header = false; | ||
488 | + } | ||
489 | + if (local_err != NULL) { | ||
490 | + error_propagate(errp, local_err); | ||
491 | + ret = -EINVAL; | ||
492 | + goto fail; | ||
493 | + } | ||
494 | + | ||
495 | + if (update_header) { | ||
496 | ret = qcow2_update_header(bs); | ||
497 | if (ret < 0) { | ||
498 | error_setg_errno(errp, -ret, "Could not update qcow2 header"); | ||
499 | -- | ||
500 | 2.9.4 | ||
501 | |||
502 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | Add bs local variable to simplify code. | ||
4 | |||
5 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
6 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
7 | Message-id: 20170628120530.31251-13-vsementsov@virtuozzo.com | ||
8 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
9 | --- | ||
10 | block.c | 14 ++++++++------ | ||
11 | 1 file changed, 8 insertions(+), 6 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 @@ error: | ||
18 | void bdrv_reopen_commit(BDRVReopenState *reopen_state) | ||
19 | { | ||
20 | BlockDriver *drv; | ||
21 | + BlockDriverState *bs; | ||
22 | |||
23 | assert(reopen_state != NULL); | ||
24 | - drv = reopen_state->bs->drv; | ||
25 | + bs = reopen_state->bs; | ||
26 | + drv = bs->drv; | ||
27 | assert(drv != NULL); | ||
28 | |||
29 | /* If there are any driver level actions to take */ | ||
30 | @@ -XXX,XX +XXX,XX @@ void bdrv_reopen_commit(BDRVReopenState *reopen_state) | ||
31 | } | ||
32 | |||
33 | /* set BDS specific flags now */ | ||
34 | - QDECREF(reopen_state->bs->explicit_options); | ||
35 | + QDECREF(bs->explicit_options); | ||
36 | |||
37 | - reopen_state->bs->explicit_options = reopen_state->explicit_options; | ||
38 | - reopen_state->bs->open_flags = reopen_state->flags; | ||
39 | - reopen_state->bs->read_only = !(reopen_state->flags & BDRV_O_RDWR); | ||
40 | + bs->explicit_options = reopen_state->explicit_options; | ||
41 | + bs->open_flags = reopen_state->flags; | ||
42 | + bs->read_only = !(reopen_state->flags & BDRV_O_RDWR); | ||
43 | |||
44 | - bdrv_refresh_limits(reopen_state->bs, NULL); | ||
45 | + bdrv_refresh_limits(bs, NULL); | ||
46 | } | ||
47 | |||
48 | /* | ||
49 | -- | ||
50 | 2.9.4 | ||
51 | |||
52 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | Add format driver handler, which should mark loaded read-only | ||
4 | bitmaps as 'IN_USE' in the image and unset read_only field in | ||
5 | corresponding BdrvDirtyBitmap's. | ||
6 | |||
7 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
8 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
9 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
10 | Message-id: 20170628120530.31251-14-vsementsov@virtuozzo.com | ||
11 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
12 | --- | ||
13 | include/block/block_int.h | 7 +++++++ | ||
14 | block.c | 19 +++++++++++++++++++ | ||
15 | 2 files changed, 26 insertions(+) | ||
16 | |||
17 | diff --git a/include/block/block_int.h b/include/block/block_int.h | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/include/block/block_int.h | ||
20 | +++ b/include/block/block_int.h | ||
21 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
22 | uint64_t parent_perm, uint64_t parent_shared, | ||
23 | uint64_t *nperm, uint64_t *nshared); | ||
24 | |||
25 | + /** | ||
26 | + * Bitmaps should be marked as 'IN_USE' in the image on reopening image | ||
27 | + * as rw. This handler should realize it. It also should unset readonly | ||
28 | + * field of BlockDirtyBitmap's in case of success. | ||
29 | + */ | ||
30 | + int (*bdrv_reopen_bitmaps_rw)(BlockDriverState *bs, Error **errp); | ||
31 | + | ||
32 | QLIST_ENTRY(BlockDriver) list; | ||
33 | }; | ||
34 | |||
35 | diff --git a/block.c b/block.c | ||
36 | index XXXXXXX..XXXXXXX 100644 | ||
37 | --- a/block.c | ||
38 | +++ b/block.c | ||
39 | @@ -XXX,XX +XXX,XX @@ void bdrv_reopen_commit(BDRVReopenState *reopen_state) | ||
40 | { | ||
41 | BlockDriver *drv; | ||
42 | BlockDriverState *bs; | ||
43 | + bool old_can_write, new_can_write; | ||
44 | |||
45 | assert(reopen_state != NULL); | ||
46 | bs = reopen_state->bs; | ||
47 | drv = bs->drv; | ||
48 | assert(drv != NULL); | ||
49 | |||
50 | + old_can_write = | ||
51 | + !bdrv_is_read_only(bs) && !(bdrv_get_flags(bs) & BDRV_O_INACTIVE); | ||
52 | + | ||
53 | /* If there are any driver level actions to take */ | ||
54 | if (drv->bdrv_reopen_commit) { | ||
55 | drv->bdrv_reopen_commit(reopen_state); | ||
56 | @@ -XXX,XX +XXX,XX @@ void bdrv_reopen_commit(BDRVReopenState *reopen_state) | ||
57 | bs->read_only = !(reopen_state->flags & BDRV_O_RDWR); | ||
58 | |||
59 | bdrv_refresh_limits(bs, NULL); | ||
60 | + | ||
61 | + new_can_write = | ||
62 | + !bdrv_is_read_only(bs) && !(bdrv_get_flags(bs) & BDRV_O_INACTIVE); | ||
63 | + if (!old_can_write && new_can_write && drv->bdrv_reopen_bitmaps_rw) { | ||
64 | + Error *local_err = NULL; | ||
65 | + if (drv->bdrv_reopen_bitmaps_rw(bs, &local_err) < 0) { | ||
66 | + /* This is not fatal, bitmaps just left read-only, so all following | ||
67 | + * writes will fail. User can remove read-only bitmaps to unblock | ||
68 | + * writes. | ||
69 | + */ | ||
70 | + error_reportf_err(local_err, | ||
71 | + "%s: Failed to make dirty bitmaps writable: ", | ||
72 | + bdrv_get_node_name(bs)); | ||
73 | + } | ||
74 | + } | ||
75 | } | ||
76 | |||
77 | /* | ||
78 | -- | ||
79 | 2.9.4 | ||
80 | |||
81 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | Realize bdrv_reopen_bitmaps_rw interface. | ||
4 | |||
5 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
6 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
7 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
8 | Message-id: 20170628120530.31251-15-vsementsov@virtuozzo.com | ||
9 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
10 | --- | ||
11 | block/qcow2.h | 1 + | ||
12 | block/qcow2-bitmap.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||
13 | block/qcow2.c | 2 ++ | ||
14 | 3 files changed, 64 insertions(+) | ||
15 | |||
16 | diff --git a/block/qcow2.h b/block/qcow2.h | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/block/qcow2.h | ||
19 | +++ b/block/qcow2.h | ||
20 | @@ -XXX,XX +XXX,XX @@ int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res, | ||
21 | void **refcount_table, | ||
22 | int64_t *refcount_table_size); | ||
23 | bool qcow2_load_autoloading_dirty_bitmaps(BlockDriverState *bs, Error **errp); | ||
24 | +int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp); | ||
25 | |||
26 | #endif | ||
27 | diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c | ||
28 | index XXXXXXX..XXXXXXX 100644 | ||
29 | --- a/block/qcow2-bitmap.c | ||
30 | +++ b/block/qcow2-bitmap.c | ||
31 | @@ -XXX,XX +XXX,XX @@ fail: | ||
32 | |||
33 | return false; | ||
34 | } | ||
35 | + | ||
36 | +int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp) | ||
37 | +{ | ||
38 | + BDRVQcow2State *s = bs->opaque; | ||
39 | + Qcow2BitmapList *bm_list; | ||
40 | + Qcow2Bitmap *bm; | ||
41 | + GSList *ro_dirty_bitmaps = NULL; | ||
42 | + int ret = 0; | ||
43 | + | ||
44 | + if (s->nb_bitmaps == 0) { | ||
45 | + /* No bitmaps - nothing to do */ | ||
46 | + return 0; | ||
47 | + } | ||
48 | + | ||
49 | + if (!can_write(bs)) { | ||
50 | + error_setg(errp, "Can't write to the image on reopening bitmaps rw"); | ||
51 | + return -EINVAL; | ||
52 | + } | ||
53 | + | ||
54 | + bm_list = bitmap_list_load(bs, s->bitmap_directory_offset, | ||
55 | + s->bitmap_directory_size, errp); | ||
56 | + if (bm_list == NULL) { | ||
57 | + return -EINVAL; | ||
58 | + } | ||
59 | + | ||
60 | + QSIMPLEQ_FOREACH(bm, bm_list, entry) { | ||
61 | + if (!(bm->flags & BME_FLAG_IN_USE)) { | ||
62 | + BdrvDirtyBitmap *bitmap = bdrv_find_dirty_bitmap(bs, bm->name); | ||
63 | + if (bitmap == NULL) { | ||
64 | + continue; | ||
65 | + } | ||
66 | + | ||
67 | + if (!bdrv_dirty_bitmap_readonly(bitmap)) { | ||
68 | + error_setg(errp, "Bitmap %s is not readonly but not marked" | ||
69 | + "'IN_USE' in the image. Something went wrong," | ||
70 | + "all the bitmaps may be corrupted", bm->name); | ||
71 | + ret = -EINVAL; | ||
72 | + goto out; | ||
73 | + } | ||
74 | + | ||
75 | + bm->flags |= BME_FLAG_IN_USE; | ||
76 | + ro_dirty_bitmaps = g_slist_append(ro_dirty_bitmaps, bitmap); | ||
77 | + } | ||
78 | + } | ||
79 | + | ||
80 | + if (ro_dirty_bitmaps != NULL) { | ||
81 | + /* in_use flags must be updated */ | ||
82 | + ret = update_ext_header_and_dir_in_place(bs, bm_list); | ||
83 | + if (ret < 0) { | ||
84 | + error_setg_errno(errp, -ret, "Can't update bitmap directory"); | ||
85 | + goto out; | ||
86 | + } | ||
87 | + g_slist_foreach(ro_dirty_bitmaps, set_readonly_helper, false); | ||
88 | + } | ||
89 | + | ||
90 | +out: | ||
91 | + g_slist_free(ro_dirty_bitmaps); | ||
92 | + bitmap_list_free(bm_list); | ||
93 | + | ||
94 | + return ret; | ||
95 | +} | ||
96 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
97 | index XXXXXXX..XXXXXXX 100644 | ||
98 | --- a/block/qcow2.c | ||
99 | +++ b/block/qcow2.c | ||
100 | @@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_qcow2 = { | ||
101 | |||
102 | .bdrv_detach_aio_context = qcow2_detach_aio_context, | ||
103 | .bdrv_attach_aio_context = qcow2_attach_aio_context, | ||
104 | + | ||
105 | + .bdrv_reopen_bitmaps_rw = qcow2_reopen_bitmaps_rw, | ||
106 | }; | ||
107 | |||
108 | static void bdrv_qcow2_init(void) | ||
109 | -- | ||
110 | 2.9.4 | ||
111 | |||
112 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | Mirror AUTO flag from Qcow2 bitmap in BdrvDirtyBitmap. This will be | ||
4 | needed in future, to save this flag back to Qcow2 for persistent | ||
5 | bitmaps. | ||
6 | |||
7 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
8 | Message-id: 20170628120530.31251-16-vsementsov@virtuozzo.com | ||
9 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
10 | --- | ||
11 | include/block/dirty-bitmap.h | 2 ++ | ||
12 | block/dirty-bitmap.c | 18 ++++++++++++++++++ | ||
13 | block/qcow2-bitmap.c | 2 ++ | ||
14 | 3 files changed, 22 insertions(+) | ||
15 | |||
16 | diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/include/block/dirty-bitmap.h | ||
19 | +++ b/include/block/dirty-bitmap.h | ||
20 | @@ -XXX,XX +XXX,XX @@ void bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap, | ||
21 | void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap); | ||
22 | |||
23 | void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap, bool value); | ||
24 | +void bdrv_dirty_bitmap_set_autoload(BdrvDirtyBitmap *bitmap, bool autoload); | ||
25 | |||
26 | /* Functions that require manual locking. */ | ||
27 | void bdrv_dirty_bitmap_lock(BdrvDirtyBitmap *bitmap); | ||
28 | @@ -XXX,XX +XXX,XX @@ int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap); | ||
29 | void bdrv_dirty_bitmap_truncate(BlockDriverState *bs); | ||
30 | bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap); | ||
31 | bool bdrv_has_readonly_bitmaps(BlockDriverState *bs); | ||
32 | +bool bdrv_dirty_bitmap_get_autoload(const BdrvDirtyBitmap *bitmap); | ||
33 | |||
34 | #endif | ||
35 | diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c | ||
36 | index XXXXXXX..XXXXXXX 100644 | ||
37 | --- a/block/dirty-bitmap.c | ||
38 | +++ b/block/dirty-bitmap.c | ||
39 | @@ -XXX,XX +XXX,XX @@ struct BdrvDirtyBitmap { | ||
40 | Such operations must fail and both the image | ||
41 | and this bitmap must remain unchanged while | ||
42 | this flag is set. */ | ||
43 | + bool autoload; /* For persistent bitmaps: bitmap must be | ||
44 | + autoloaded on image opening */ | ||
45 | QLIST_ENTRY(BdrvDirtyBitmap) list; | ||
46 | }; | ||
47 | |||
48 | @@ -XXX,XX +XXX,XX @@ void bdrv_dirty_bitmap_make_anon(BdrvDirtyBitmap *bitmap) | ||
49 | assert(!bdrv_dirty_bitmap_frozen(bitmap)); | ||
50 | g_free(bitmap->name); | ||
51 | bitmap->name = NULL; | ||
52 | + bitmap->autoload = false; | ||
53 | } | ||
54 | |||
55 | /* Called with BQL taken. */ | ||
56 | @@ -XXX,XX +XXX,XX @@ BdrvDirtyBitmap *bdrv_dirty_bitmap_abdicate(BlockDriverState *bs, | ||
57 | bitmap->name = NULL; | ||
58 | successor->name = name; | ||
59 | bitmap->successor = NULL; | ||
60 | + successor->autoload = bitmap->autoload; | ||
61 | + bitmap->autoload = false; | ||
62 | bdrv_release_dirty_bitmap(bs, bitmap); | ||
63 | |||
64 | return successor; | ||
65 | @@ -XXX,XX +XXX,XX @@ bool bdrv_has_readonly_bitmaps(BlockDriverState *bs) | ||
66 | |||
67 | return false; | ||
68 | } | ||
69 | + | ||
70 | +/* Called with BQL taken. */ | ||
71 | +void bdrv_dirty_bitmap_set_autoload(BdrvDirtyBitmap *bitmap, bool autoload) | ||
72 | +{ | ||
73 | + qemu_mutex_lock(bitmap->mutex); | ||
74 | + bitmap->autoload = autoload; | ||
75 | + qemu_mutex_unlock(bitmap->mutex); | ||
76 | +} | ||
77 | + | ||
78 | +bool bdrv_dirty_bitmap_get_autoload(const BdrvDirtyBitmap *bitmap) | ||
79 | +{ | ||
80 | + return bitmap->autoload; | ||
81 | +} | ||
82 | diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c | ||
83 | index XXXXXXX..XXXXXXX 100644 | ||
84 | --- a/block/qcow2-bitmap.c | ||
85 | +++ b/block/qcow2-bitmap.c | ||
86 | @@ -XXX,XX +XXX,XX @@ bool qcow2_load_autoloading_dirty_bitmaps(BlockDriverState *bs, Error **errp) | ||
87 | if (bitmap == NULL) { | ||
88 | goto fail; | ||
89 | } | ||
90 | + | ||
91 | + bdrv_dirty_bitmap_set_autoload(bitmap, true); | ||
92 | bm->flags |= BME_FLAG_IN_USE; | ||
93 | created_dirty_bitmaps = | ||
94 | g_slist_append(created_dirty_bitmaps, bitmap); | ||
95 | -- | ||
96 | 2.9.4 | ||
97 | |||
98 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | Release bitmaps after 'if (bs->drv) { ... }' block. This will allow | ||
4 | format driver to save persistent bitmaps, which will appear in following | ||
5 | commits. | ||
6 | |||
7 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
8 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
9 | Message-id: 20170628120530.31251-17-vsementsov@virtuozzo.com | ||
10 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
11 | --- | ||
12 | block.c | 6 +++--- | ||
13 | 1 file changed, 3 insertions(+), 3 deletions(-) | ||
14 | |||
15 | diff --git a/block.c b/block.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/block.c | ||
18 | +++ b/block.c | ||
19 | @@ -XXX,XX +XXX,XX @@ static void bdrv_close(BlockDriverState *bs) | ||
20 | bdrv_flush(bs); | ||
21 | bdrv_drain(bs); /* in case flush left pending I/O */ | ||
22 | |||
23 | - bdrv_release_named_dirty_bitmaps(bs); | ||
24 | - assert(QLIST_EMPTY(&bs->dirty_bitmaps)); | ||
25 | - | ||
26 | if (bs->drv) { | ||
27 | BdrvChild *child, *next; | ||
28 | |||
29 | @@ -XXX,XX +XXX,XX @@ static void bdrv_close(BlockDriverState *bs) | ||
30 | bs->full_open_options = NULL; | ||
31 | } | ||
32 | |||
33 | + bdrv_release_named_dirty_bitmaps(bs); | ||
34 | + assert(QLIST_EMPTY(&bs->dirty_bitmaps)); | ||
35 | + | ||
36 | QLIST_FOREACH_SAFE(ban, &bs->aio_notifiers, list, ban_next) { | ||
37 | g_free(ban); | ||
38 | } | ||
39 | -- | ||
40 | 2.9.4 | ||
41 | |||
42 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | New field BdrvDirtyBitmap.persistent means, that bitmap should be saved | ||
4 | by format driver in .bdrv_close and .bdrv_inactivate. No format driver | ||
5 | supports it for now. | ||
6 | |||
7 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
8 | Message-id: 20170628120530.31251-18-vsementsov@virtuozzo.com | ||
9 | [mreitz: Fixed indentation] | ||
10 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
11 | --- | ||
12 | include/block/dirty-bitmap.h | 4 ++++ | ||
13 | block/dirty-bitmap.c | 29 +++++++++++++++++++++++++++++ | ||
14 | block/qcow2-bitmap.c | 1 + | ||
15 | 3 files changed, 34 insertions(+) | ||
16 | |||
17 | diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/include/block/dirty-bitmap.h | ||
20 | +++ b/include/block/dirty-bitmap.h | ||
21 | @@ -XXX,XX +XXX,XX @@ void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap); | ||
22 | |||
23 | void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap, bool value); | ||
24 | void bdrv_dirty_bitmap_set_autoload(BdrvDirtyBitmap *bitmap, bool autoload); | ||
25 | +void bdrv_dirty_bitmap_set_persistance(BdrvDirtyBitmap *bitmap, | ||
26 | + bool persistent); | ||
27 | |||
28 | /* Functions that require manual locking. */ | ||
29 | void bdrv_dirty_bitmap_lock(BdrvDirtyBitmap *bitmap); | ||
30 | @@ -XXX,XX +XXX,XX @@ void bdrv_dirty_bitmap_truncate(BlockDriverState *bs); | ||
31 | bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap); | ||
32 | bool bdrv_has_readonly_bitmaps(BlockDriverState *bs); | ||
33 | bool bdrv_dirty_bitmap_get_autoload(const BdrvDirtyBitmap *bitmap); | ||
34 | +bool bdrv_dirty_bitmap_get_persistance(BdrvDirtyBitmap *bitmap); | ||
35 | +bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs); | ||
36 | |||
37 | #endif | ||
38 | diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c | ||
39 | index XXXXXXX..XXXXXXX 100644 | ||
40 | --- a/block/dirty-bitmap.c | ||
41 | +++ b/block/dirty-bitmap.c | ||
42 | @@ -XXX,XX +XXX,XX @@ struct BdrvDirtyBitmap { | ||
43 | this flag is set. */ | ||
44 | bool autoload; /* For persistent bitmaps: bitmap must be | ||
45 | autoloaded on image opening */ | ||
46 | + bool persistent; /* bitmap must be saved to owner disk image */ | ||
47 | QLIST_ENTRY(BdrvDirtyBitmap) list; | ||
48 | }; | ||
49 | |||
50 | @@ -XXX,XX +XXX,XX @@ void bdrv_dirty_bitmap_make_anon(BdrvDirtyBitmap *bitmap) | ||
51 | assert(!bdrv_dirty_bitmap_frozen(bitmap)); | ||
52 | g_free(bitmap->name); | ||
53 | bitmap->name = NULL; | ||
54 | + bitmap->persistent = false; | ||
55 | bitmap->autoload = false; | ||
56 | } | ||
57 | |||
58 | @@ -XXX,XX +XXX,XX @@ BdrvDirtyBitmap *bdrv_dirty_bitmap_abdicate(BlockDriverState *bs, | ||
59 | bitmap->name = NULL; | ||
60 | successor->name = name; | ||
61 | bitmap->successor = NULL; | ||
62 | + successor->persistent = bitmap->persistent; | ||
63 | + bitmap->persistent = false; | ||
64 | successor->autoload = bitmap->autoload; | ||
65 | bitmap->autoload = false; | ||
66 | bdrv_release_dirty_bitmap(bs, bitmap); | ||
67 | @@ -XXX,XX +XXX,XX @@ bool bdrv_dirty_bitmap_get_autoload(const BdrvDirtyBitmap *bitmap) | ||
68 | { | ||
69 | return bitmap->autoload; | ||
70 | } | ||
71 | + | ||
72 | +/* Called with BQL taken. */ | ||
73 | +void bdrv_dirty_bitmap_set_persistance(BdrvDirtyBitmap *bitmap, bool persistent) | ||
74 | +{ | ||
75 | + qemu_mutex_lock(bitmap->mutex); | ||
76 | + bitmap->persistent = persistent; | ||
77 | + qemu_mutex_unlock(bitmap->mutex); | ||
78 | +} | ||
79 | + | ||
80 | +bool bdrv_dirty_bitmap_get_persistance(BdrvDirtyBitmap *bitmap) | ||
81 | +{ | ||
82 | + return bitmap->persistent; | ||
83 | +} | ||
84 | + | ||
85 | +bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs) | ||
86 | +{ | ||
87 | + BdrvDirtyBitmap *bm; | ||
88 | + QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) { | ||
89 | + if (bm->persistent && !bm->readonly) { | ||
90 | + return true; | ||
91 | + } | ||
92 | + } | ||
93 | + | ||
94 | + return false; | ||
95 | +} | ||
96 | diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c | ||
97 | index XXXXXXX..XXXXXXX 100644 | ||
98 | --- a/block/qcow2-bitmap.c | ||
99 | +++ b/block/qcow2-bitmap.c | ||
100 | @@ -XXX,XX +XXX,XX @@ bool qcow2_load_autoloading_dirty_bitmaps(BlockDriverState *bs, Error **errp) | ||
101 | goto fail; | ||
102 | } | ||
103 | |||
104 | + bdrv_dirty_bitmap_set_persistance(bitmap, true); | ||
105 | bdrv_dirty_bitmap_set_autoload(bitmap, true); | ||
106 | bm->flags |= BME_FLAG_IN_USE; | ||
107 | created_dirty_bitmaps = | ||
108 | -- | ||
109 | 2.9.4 | ||
110 | |||
111 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
4 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
5 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
6 | Message-id: 20170628120530.31251-19-vsementsov@virtuozzo.com | ||
7 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
8 | --- | ||
9 | include/block/dirty-bitmap.h | 2 ++ | ||
10 | block/dirty-bitmap.c | 7 +++++++ | ||
11 | 2 files changed, 9 insertions(+) | ||
12 | |||
13 | diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h | ||
14 | index XXXXXXX..XXXXXXX 100644 | ||
15 | --- a/include/block/dirty-bitmap.h | ||
16 | +++ b/include/block/dirty-bitmap.h | ||
17 | @@ -XXX,XX +XXX,XX @@ bool bdrv_has_readonly_bitmaps(BlockDriverState *bs); | ||
18 | bool bdrv_dirty_bitmap_get_autoload(const BdrvDirtyBitmap *bitmap); | ||
19 | bool bdrv_dirty_bitmap_get_persistance(BdrvDirtyBitmap *bitmap); | ||
20 | bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs); | ||
21 | +BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs, | ||
22 | + BdrvDirtyBitmap *bitmap); | ||
23 | |||
24 | #endif | ||
25 | diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c | ||
26 | index XXXXXXX..XXXXXXX 100644 | ||
27 | --- a/block/dirty-bitmap.c | ||
28 | +++ b/block/dirty-bitmap.c | ||
29 | @@ -XXX,XX +XXX,XX @@ bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs) | ||
30 | |||
31 | return false; | ||
32 | } | ||
33 | + | ||
34 | +BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs, | ||
35 | + BdrvDirtyBitmap *bitmap) | ||
36 | +{ | ||
37 | + return bitmap == NULL ? QLIST_FIRST(&bs->dirty_bitmaps) : | ||
38 | + QLIST_NEXT(bitmap, list); | ||
39 | +} | ||
40 | -- | ||
41 | 2.9.4 | ||
42 | |||
43 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | Store persistent dirty bitmaps in qcow2 image. | ||
4 | |||
5 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
6 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
7 | Message-id: 20170628120530.31251-20-vsementsov@virtuozzo.com | ||
8 | [mreitz: Always assign ret in store_bitmap() in case of an error] | ||
9 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
10 | --- | ||
11 | block/qcow2.h | 1 + | ||
12 | block/qcow2-bitmap.c | 476 +++++++++++++++++++++++++++++++++++++++++++++++++++ | ||
13 | block/qcow2.c | 9 + | ||
14 | 3 files changed, 486 insertions(+) | ||
15 | |||
16 | diff --git a/block/qcow2.h b/block/qcow2.h | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/block/qcow2.h | ||
19 | +++ b/block/qcow2.h | ||
20 | @@ -XXX,XX +XXX,XX @@ int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res, | ||
21 | int64_t *refcount_table_size); | ||
22 | bool qcow2_load_autoloading_dirty_bitmaps(BlockDriverState *bs, Error **errp); | ||
23 | int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp); | ||
24 | +void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp); | ||
25 | |||
26 | #endif | ||
27 | diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c | ||
28 | index XXXXXXX..XXXXXXX 100644 | ||
29 | --- a/block/qcow2-bitmap.c | ||
30 | +++ b/block/qcow2-bitmap.c | ||
31 | @@ -XXX,XX +XXX,XX @@ | ||
32 | |||
33 | #include "qemu/osdep.h" | ||
34 | #include "qapi/error.h" | ||
35 | +#include "qemu/cutils.h" | ||
36 | |||
37 | #include "block/block_int.h" | ||
38 | #include "block/qcow2.h" | ||
39 | @@ -XXX,XX +XXX,XX @@ | ||
40 | #define BME_MIN_GRANULARITY_BITS 9 | ||
41 | #define BME_MAX_NAME_SIZE 1023 | ||
42 | |||
43 | +#if BME_MAX_TABLE_SIZE * 8ULL > INT_MAX | ||
44 | +#error In the code bitmap table physical size assumed to fit into int | ||
45 | +#endif | ||
46 | + | ||
47 | /* Bitmap directory entry flags */ | ||
48 | #define BME_RESERVED_FLAGS 0xfffffffcU | ||
49 | #define BME_FLAG_IN_USE (1U << 0) | ||
50 | @@ -XXX,XX +XXX,XX @@ typedef struct Qcow2BitmapTable { | ||
51 | uint32_t size; /* number of 64bit entries */ | ||
52 | QSIMPLEQ_ENTRY(Qcow2BitmapTable) entry; | ||
53 | } Qcow2BitmapTable; | ||
54 | +typedef QSIMPLEQ_HEAD(Qcow2BitmapTableList, Qcow2BitmapTable) | ||
55 | + Qcow2BitmapTableList; | ||
56 | |||
57 | typedef struct Qcow2Bitmap { | ||
58 | Qcow2BitmapTable table; | ||
59 | @@ -XXX,XX +XXX,XX @@ typedef struct Qcow2Bitmap { | ||
60 | uint8_t granularity_bits; | ||
61 | char *name; | ||
62 | |||
63 | + BdrvDirtyBitmap *dirty_bitmap; | ||
64 | + | ||
65 | QSIMPLEQ_ENTRY(Qcow2Bitmap) entry; | ||
66 | } Qcow2Bitmap; | ||
67 | typedef QSIMPLEQ_HEAD(Qcow2BitmapList, Qcow2Bitmap) Qcow2BitmapList; | ||
68 | @@ -XXX,XX +XXX,XX @@ static int update_header_sync(BlockDriverState *bs) | ||
69 | return bdrv_flush(bs); | ||
70 | } | ||
71 | |||
72 | +static inline void bitmap_table_to_be(uint64_t *bitmap_table, size_t size) | ||
73 | +{ | ||
74 | + size_t i; | ||
75 | + | ||
76 | + for (i = 0; i < size; ++i) { | ||
77 | + cpu_to_be64s(&bitmap_table[i]); | ||
78 | + } | ||
79 | +} | ||
80 | + | ||
81 | static int check_table_entry(uint64_t entry, int cluster_size) | ||
82 | { | ||
83 | uint64_t offset; | ||
84 | @@ -XXX,XX +XXX,XX @@ static int check_table_entry(uint64_t entry, int cluster_size) | ||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | +static int check_constraints_on_bitmap(BlockDriverState *bs, | ||
89 | + const char *name, | ||
90 | + uint32_t granularity, | ||
91 | + Error **errp) | ||
92 | +{ | ||
93 | + BDRVQcow2State *s = bs->opaque; | ||
94 | + int granularity_bits = ctz32(granularity); | ||
95 | + int64_t len = bdrv_getlength(bs); | ||
96 | + | ||
97 | + assert(granularity > 0); | ||
98 | + assert((granularity & (granularity - 1)) == 0); | ||
99 | + | ||
100 | + if (len < 0) { | ||
101 | + error_setg_errno(errp, -len, "Failed to get size of '%s'", | ||
102 | + bdrv_get_device_or_node_name(bs)); | ||
103 | + return len; | ||
104 | + } | ||
105 | + | ||
106 | + if (granularity_bits > BME_MAX_GRANULARITY_BITS) { | ||
107 | + error_setg(errp, "Granularity exceeds maximum (%llu bytes)", | ||
108 | + 1ULL << BME_MAX_GRANULARITY_BITS); | ||
109 | + return -EINVAL; | ||
110 | + } | ||
111 | + if (granularity_bits < BME_MIN_GRANULARITY_BITS) { | ||
112 | + error_setg(errp, "Granularity is under minimum (%llu bytes)", | ||
113 | + 1ULL << BME_MIN_GRANULARITY_BITS); | ||
114 | + return -EINVAL; | ||
115 | + } | ||
116 | + | ||
117 | + if ((len > (uint64_t)BME_MAX_PHYS_SIZE << granularity_bits) || | ||
118 | + (len > (uint64_t)BME_MAX_TABLE_SIZE * s->cluster_size << | ||
119 | + granularity_bits)) | ||
120 | + { | ||
121 | + error_setg(errp, "Too much space will be occupied by the bitmap. " | ||
122 | + "Use larger granularity"); | ||
123 | + return -EINVAL; | ||
124 | + } | ||
125 | + | ||
126 | + if (strlen(name) > BME_MAX_NAME_SIZE) { | ||
127 | + error_setg(errp, "Name length exceeds maximum (%u characters)", | ||
128 | + BME_MAX_NAME_SIZE); | ||
129 | + return -EINVAL; | ||
130 | + } | ||
131 | + | ||
132 | + return 0; | ||
133 | +} | ||
134 | + | ||
135 | +static void clear_bitmap_table(BlockDriverState *bs, uint64_t *bitmap_table, | ||
136 | + uint32_t bitmap_table_size) | ||
137 | +{ | ||
138 | + BDRVQcow2State *s = bs->opaque; | ||
139 | + int i; | ||
140 | + | ||
141 | + for (i = 0; i < bitmap_table_size; ++i) { | ||
142 | + uint64_t addr = bitmap_table[i] & BME_TABLE_ENTRY_OFFSET_MASK; | ||
143 | + if (!addr) { | ||
144 | + continue; | ||
145 | + } | ||
146 | + | ||
147 | + qcow2_free_clusters(bs, addr, s->cluster_size, QCOW2_DISCARD_OTHER); | ||
148 | + bitmap_table[i] = 0; | ||
149 | + } | ||
150 | +} | ||
151 | + | ||
152 | static int bitmap_table_load(BlockDriverState *bs, Qcow2BitmapTable *tb, | ||
153 | uint64_t **bitmap_table) | ||
154 | { | ||
155 | @@ -XXX,XX +XXX,XX @@ fail: | ||
156 | return ret; | ||
157 | } | ||
158 | |||
159 | +static int free_bitmap_clusters(BlockDriverState *bs, Qcow2BitmapTable *tb) | ||
160 | +{ | ||
161 | + int ret; | ||
162 | + uint64_t *bitmap_table; | ||
163 | + | ||
164 | + ret = bitmap_table_load(bs, tb, &bitmap_table); | ||
165 | + if (ret < 0) { | ||
166 | + assert(bitmap_table == NULL); | ||
167 | + return ret; | ||
168 | + } | ||
169 | + | ||
170 | + clear_bitmap_table(bs, bitmap_table, tb->size); | ||
171 | + qcow2_free_clusters(bs, tb->offset, tb->size * sizeof(uint64_t), | ||
172 | + QCOW2_DISCARD_OTHER); | ||
173 | + g_free(bitmap_table); | ||
174 | + | ||
175 | + tb->offset = 0; | ||
176 | + tb->size = 0; | ||
177 | + | ||
178 | + return 0; | ||
179 | +} | ||
180 | + | ||
181 | /* This function returns the number of disk sectors covered by a single qcow2 | ||
182 | * cluster of bitmap data. */ | ||
183 | static uint64_t sectors_covered_by_bitmap_cluster(const BDRVQcow2State *s, | ||
184 | @@ -XXX,XX +XXX,XX @@ static int update_ext_header_and_dir_in_place(BlockDriverState *bs, | ||
185 | */ | ||
186 | } | ||
187 | |||
188 | +static int update_ext_header_and_dir(BlockDriverState *bs, | ||
189 | + Qcow2BitmapList *bm_list) | ||
190 | +{ | ||
191 | + BDRVQcow2State *s = bs->opaque; | ||
192 | + int ret; | ||
193 | + uint64_t new_offset = 0; | ||
194 | + uint64_t new_size = 0; | ||
195 | + uint32_t new_nb_bitmaps = 0; | ||
196 | + uint64_t old_offset = s->bitmap_directory_offset; | ||
197 | + uint64_t old_size = s->bitmap_directory_size; | ||
198 | + uint32_t old_nb_bitmaps = s->nb_bitmaps; | ||
199 | + uint64_t old_autocl = s->autoclear_features; | ||
200 | + | ||
201 | + if (bm_list != NULL && !QSIMPLEQ_EMPTY(bm_list)) { | ||
202 | + new_nb_bitmaps = bitmap_list_count(bm_list); | ||
203 | + | ||
204 | + if (new_nb_bitmaps > QCOW2_MAX_BITMAPS) { | ||
205 | + return -EINVAL; | ||
206 | + } | ||
207 | + | ||
208 | + ret = bitmap_list_store(bs, bm_list, &new_offset, &new_size, false); | ||
209 | + if (ret < 0) { | ||
210 | + return ret; | ||
211 | + } | ||
212 | + | ||
213 | + ret = bdrv_flush(bs->file->bs); | ||
214 | + if (ret < 0) { | ||
215 | + goto fail; | ||
216 | + } | ||
217 | + | ||
218 | + s->autoclear_features |= QCOW2_AUTOCLEAR_BITMAPS; | ||
219 | + } else { | ||
220 | + s->autoclear_features &= ~(uint64_t)QCOW2_AUTOCLEAR_BITMAPS; | ||
221 | + } | ||
222 | + | ||
223 | + s->bitmap_directory_offset = new_offset; | ||
224 | + s->bitmap_directory_size = new_size; | ||
225 | + s->nb_bitmaps = new_nb_bitmaps; | ||
226 | + | ||
227 | + ret = update_header_sync(bs); | ||
228 | + if (ret < 0) { | ||
229 | + goto fail; | ||
230 | + } | ||
231 | + | ||
232 | + if (old_size > 0) { | ||
233 | + qcow2_free_clusters(bs, old_offset, old_size, QCOW2_DISCARD_OTHER); | ||
234 | + } | ||
235 | + | ||
236 | + return 0; | ||
237 | + | ||
238 | +fail: | ||
239 | + if (new_offset > 0) { | ||
240 | + qcow2_free_clusters(bs, new_offset, new_size, QCOW2_DISCARD_OTHER); | ||
241 | + } | ||
242 | + | ||
243 | + s->bitmap_directory_offset = old_offset; | ||
244 | + s->bitmap_directory_size = old_size; | ||
245 | + s->nb_bitmaps = old_nb_bitmaps; | ||
246 | + s->autoclear_features = old_autocl; | ||
247 | + | ||
248 | + return ret; | ||
249 | +} | ||
250 | + | ||
251 | /* for g_slist_foreach for GSList of BdrvDirtyBitmap* elements */ | ||
252 | static void release_dirty_bitmap_helper(gpointer bitmap, | ||
253 | gpointer bs) | ||
254 | @@ -XXX,XX +XXX,XX @@ out: | ||
255 | |||
256 | return ret; | ||
257 | } | ||
258 | + | ||
259 | +/* store_bitmap_data() | ||
260 | + * Store bitmap to image, filling bitmap table accordingly. | ||
261 | + */ | ||
262 | +static uint64_t *store_bitmap_data(BlockDriverState *bs, | ||
263 | + BdrvDirtyBitmap *bitmap, | ||
264 | + uint32_t *bitmap_table_size, Error **errp) | ||
265 | +{ | ||
266 | + int ret; | ||
267 | + BDRVQcow2State *s = bs->opaque; | ||
268 | + int64_t sector; | ||
269 | + uint64_t sbc; | ||
270 | + uint64_t bm_size = bdrv_dirty_bitmap_size(bitmap); | ||
271 | + const char *bm_name = bdrv_dirty_bitmap_name(bitmap); | ||
272 | + uint8_t *buf = NULL; | ||
273 | + BdrvDirtyBitmapIter *dbi; | ||
274 | + uint64_t *tb; | ||
275 | + uint64_t tb_size = | ||
276 | + size_to_clusters(s, | ||
277 | + bdrv_dirty_bitmap_serialization_size(bitmap, 0, bm_size)); | ||
278 | + | ||
279 | + if (tb_size > BME_MAX_TABLE_SIZE || | ||
280 | + tb_size * s->cluster_size > BME_MAX_PHYS_SIZE) | ||
281 | + { | ||
282 | + error_setg(errp, "Bitmap '%s' is too big", bm_name); | ||
283 | + return NULL; | ||
284 | + } | ||
285 | + | ||
286 | + tb = g_try_new0(uint64_t, tb_size); | ||
287 | + if (tb == NULL) { | ||
288 | + error_setg(errp, "No memory"); | ||
289 | + return NULL; | ||
290 | + } | ||
291 | + | ||
292 | + dbi = bdrv_dirty_iter_new(bitmap, 0); | ||
293 | + buf = g_malloc(s->cluster_size); | ||
294 | + sbc = sectors_covered_by_bitmap_cluster(s, bitmap); | ||
295 | + assert(DIV_ROUND_UP(bm_size, sbc) == tb_size); | ||
296 | + | ||
297 | + while ((sector = bdrv_dirty_iter_next(dbi)) != -1) { | ||
298 | + uint64_t cluster = sector / sbc; | ||
299 | + uint64_t end, write_size; | ||
300 | + int64_t off; | ||
301 | + | ||
302 | + sector = cluster * sbc; | ||
303 | + end = MIN(bm_size, sector + sbc); | ||
304 | + write_size = | ||
305 | + bdrv_dirty_bitmap_serialization_size(bitmap, sector, end - sector); | ||
306 | + assert(write_size <= s->cluster_size); | ||
307 | + | ||
308 | + off = qcow2_alloc_clusters(bs, s->cluster_size); | ||
309 | + if (off < 0) { | ||
310 | + error_setg_errno(errp, -off, | ||
311 | + "Failed to allocate clusters for bitmap '%s'", | ||
312 | + bm_name); | ||
313 | + goto fail; | ||
314 | + } | ||
315 | + tb[cluster] = off; | ||
316 | + | ||
317 | + bdrv_dirty_bitmap_serialize_part(bitmap, buf, sector, end - sector); | ||
318 | + if (write_size < s->cluster_size) { | ||
319 | + memset(buf + write_size, 0, s->cluster_size - write_size); | ||
320 | + } | ||
321 | + | ||
322 | + ret = qcow2_pre_write_overlap_check(bs, 0, off, s->cluster_size); | ||
323 | + if (ret < 0) { | ||
324 | + error_setg_errno(errp, -ret, "Qcow2 overlap check failed"); | ||
325 | + goto fail; | ||
326 | + } | ||
327 | + | ||
328 | + ret = bdrv_pwrite(bs->file, off, buf, s->cluster_size); | ||
329 | + if (ret < 0) { | ||
330 | + error_setg_errno(errp, -ret, "Failed to write bitmap '%s' to file", | ||
331 | + bm_name); | ||
332 | + goto fail; | ||
333 | + } | ||
334 | + | ||
335 | + if (end >= bm_size) { | ||
336 | + break; | ||
337 | + } | ||
338 | + | ||
339 | + bdrv_set_dirty_iter(dbi, end); | ||
340 | + } | ||
341 | + | ||
342 | + *bitmap_table_size = tb_size; | ||
343 | + g_free(buf); | ||
344 | + bdrv_dirty_iter_free(dbi); | ||
345 | + | ||
346 | + return tb; | ||
347 | + | ||
348 | +fail: | ||
349 | + clear_bitmap_table(bs, tb, tb_size); | ||
350 | + g_free(buf); | ||
351 | + bdrv_dirty_iter_free(dbi); | ||
352 | + g_free(tb); | ||
353 | + | ||
354 | + return NULL; | ||
355 | +} | ||
356 | + | ||
357 | +/* store_bitmap() | ||
358 | + * Store bm->dirty_bitmap to qcow2. | ||
359 | + * Set bm->table_offset and bm->table_size accordingly. | ||
360 | + */ | ||
361 | +static int store_bitmap(BlockDriverState *bs, Qcow2Bitmap *bm, Error **errp) | ||
362 | +{ | ||
363 | + int ret; | ||
364 | + uint64_t *tb; | ||
365 | + int64_t tb_offset; | ||
366 | + uint32_t tb_size; | ||
367 | + BdrvDirtyBitmap *bitmap = bm->dirty_bitmap; | ||
368 | + const char *bm_name; | ||
369 | + | ||
370 | + assert(bitmap != NULL); | ||
371 | + | ||
372 | + bm_name = bdrv_dirty_bitmap_name(bitmap); | ||
373 | + | ||
374 | + tb = store_bitmap_data(bs, bitmap, &tb_size, errp); | ||
375 | + if (tb == NULL) { | ||
376 | + return -EINVAL; | ||
377 | + } | ||
378 | + | ||
379 | + assert(tb_size <= BME_MAX_TABLE_SIZE); | ||
380 | + tb_offset = qcow2_alloc_clusters(bs, tb_size * sizeof(tb[0])); | ||
381 | + if (tb_offset < 0) { | ||
382 | + error_setg_errno(errp, -tb_offset, | ||
383 | + "Failed to allocate clusters for bitmap '%s'", | ||
384 | + bm_name); | ||
385 | + ret = tb_offset; | ||
386 | + goto fail; | ||
387 | + } | ||
388 | + | ||
389 | + ret = qcow2_pre_write_overlap_check(bs, 0, tb_offset, | ||
390 | + tb_size * sizeof(tb[0])); | ||
391 | + if (ret < 0) { | ||
392 | + error_setg_errno(errp, -ret, "Qcow2 overlap check failed"); | ||
393 | + goto fail; | ||
394 | + } | ||
395 | + | ||
396 | + bitmap_table_to_be(tb, tb_size); | ||
397 | + ret = bdrv_pwrite(bs->file, tb_offset, tb, tb_size * sizeof(tb[0])); | ||
398 | + if (ret < 0) { | ||
399 | + error_setg_errno(errp, -ret, "Failed to write bitmap '%s' to file", | ||
400 | + bm_name); | ||
401 | + goto fail; | ||
402 | + } | ||
403 | + | ||
404 | + g_free(tb); | ||
405 | + | ||
406 | + bm->table.offset = tb_offset; | ||
407 | + bm->table.size = tb_size; | ||
408 | + | ||
409 | + return 0; | ||
410 | + | ||
411 | +fail: | ||
412 | + clear_bitmap_table(bs, tb, tb_size); | ||
413 | + | ||
414 | + if (tb_offset > 0) { | ||
415 | + qcow2_free_clusters(bs, tb_offset, tb_size * sizeof(tb[0]), | ||
416 | + QCOW2_DISCARD_OTHER); | ||
417 | + } | ||
418 | + | ||
419 | + g_free(tb); | ||
420 | + | ||
421 | + return ret; | ||
422 | +} | ||
423 | + | ||
424 | +static Qcow2Bitmap *find_bitmap_by_name(Qcow2BitmapList *bm_list, | ||
425 | + const char *name) | ||
426 | +{ | ||
427 | + Qcow2Bitmap *bm; | ||
428 | + | ||
429 | + QSIMPLEQ_FOREACH(bm, bm_list, entry) { | ||
430 | + if (strcmp(name, bm->name) == 0) { | ||
431 | + return bm; | ||
432 | + } | ||
433 | + } | ||
434 | + | ||
435 | + return NULL; | ||
436 | +} | ||
437 | + | ||
438 | +void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp) | ||
439 | +{ | ||
440 | + BdrvDirtyBitmap *bitmap; | ||
441 | + BDRVQcow2State *s = bs->opaque; | ||
442 | + uint32_t new_nb_bitmaps = s->nb_bitmaps; | ||
443 | + uint64_t new_dir_size = s->bitmap_directory_size; | ||
444 | + int ret; | ||
445 | + Qcow2BitmapList *bm_list; | ||
446 | + Qcow2Bitmap *bm; | ||
447 | + Qcow2BitmapTableList drop_tables; | ||
448 | + Qcow2BitmapTable *tb, *tb_next; | ||
449 | + | ||
450 | + if (!bdrv_has_changed_persistent_bitmaps(bs)) { | ||
451 | + /* nothing to do */ | ||
452 | + return; | ||
453 | + } | ||
454 | + | ||
455 | + if (!can_write(bs)) { | ||
456 | + error_setg(errp, "No write access"); | ||
457 | + return; | ||
458 | + } | ||
459 | + | ||
460 | + QSIMPLEQ_INIT(&drop_tables); | ||
461 | + | ||
462 | + if (s->nb_bitmaps == 0) { | ||
463 | + bm_list = bitmap_list_new(); | ||
464 | + } else { | ||
465 | + bm_list = bitmap_list_load(bs, s->bitmap_directory_offset, | ||
466 | + s->bitmap_directory_size, errp); | ||
467 | + if (bm_list == NULL) { | ||
468 | + return; | ||
469 | + } | ||
470 | + } | ||
471 | + | ||
472 | + /* check constraints and names */ | ||
473 | + for (bitmap = bdrv_dirty_bitmap_next(bs, NULL); bitmap != NULL; | ||
474 | + bitmap = bdrv_dirty_bitmap_next(bs, bitmap)) | ||
475 | + { | ||
476 | + const char *name = bdrv_dirty_bitmap_name(bitmap); | ||
477 | + uint32_t granularity = bdrv_dirty_bitmap_granularity(bitmap); | ||
478 | + Qcow2Bitmap *bm; | ||
479 | + | ||
480 | + if (!bdrv_dirty_bitmap_get_persistance(bitmap) || | ||
481 | + bdrv_dirty_bitmap_readonly(bitmap)) | ||
482 | + { | ||
483 | + continue; | ||
484 | + } | ||
485 | + | ||
486 | + if (check_constraints_on_bitmap(bs, name, granularity, errp) < 0) { | ||
487 | + error_prepend(errp, "Bitmap '%s' doesn't satisfy the constraints: ", | ||
488 | + name); | ||
489 | + goto fail; | ||
490 | + } | ||
491 | + | ||
492 | + bm = find_bitmap_by_name(bm_list, name); | ||
493 | + if (bm == NULL) { | ||
494 | + if (++new_nb_bitmaps > QCOW2_MAX_BITMAPS) { | ||
495 | + error_setg(errp, "Too many persistent bitmaps"); | ||
496 | + goto fail; | ||
497 | + } | ||
498 | + | ||
499 | + new_dir_size += calc_dir_entry_size(strlen(name), 0); | ||
500 | + if (new_dir_size > QCOW2_MAX_BITMAP_DIRECTORY_SIZE) { | ||
501 | + error_setg(errp, "Bitmap directory is too large"); | ||
502 | + goto fail; | ||
503 | + } | ||
504 | + | ||
505 | + bm = g_new0(Qcow2Bitmap, 1); | ||
506 | + bm->name = g_strdup(name); | ||
507 | + QSIMPLEQ_INSERT_TAIL(bm_list, bm, entry); | ||
508 | + } else { | ||
509 | + if (!(bm->flags & BME_FLAG_IN_USE)) { | ||
510 | + error_setg(errp, "Bitmap '%s' already exists in the image", | ||
511 | + name); | ||
512 | + goto fail; | ||
513 | + } | ||
514 | + tb = g_memdup(&bm->table, sizeof(bm->table)); | ||
515 | + bm->table.offset = 0; | ||
516 | + bm->table.size = 0; | ||
517 | + QSIMPLEQ_INSERT_TAIL(&drop_tables, tb, entry); | ||
518 | + } | ||
519 | + bm->flags = bdrv_dirty_bitmap_get_autoload(bitmap) ? BME_FLAG_AUTO : 0; | ||
520 | + bm->granularity_bits = ctz32(bdrv_dirty_bitmap_granularity(bitmap)); | ||
521 | + bm->dirty_bitmap = bitmap; | ||
522 | + } | ||
523 | + | ||
524 | + /* allocate clusters and store bitmaps */ | ||
525 | + QSIMPLEQ_FOREACH(bm, bm_list, entry) { | ||
526 | + if (bm->dirty_bitmap == NULL) { | ||
527 | + continue; | ||
528 | + } | ||
529 | + | ||
530 | + ret = store_bitmap(bs, bm, errp); | ||
531 | + if (ret < 0) { | ||
532 | + goto fail; | ||
533 | + } | ||
534 | + } | ||
535 | + | ||
536 | + ret = update_ext_header_and_dir(bs, bm_list); | ||
537 | + if (ret < 0) { | ||
538 | + error_setg_errno(errp, -ret, "Failed to update bitmap extension"); | ||
539 | + goto fail; | ||
540 | + } | ||
541 | + | ||
542 | + /* Bitmap directory was successfully updated, so, old data can be dropped. | ||
543 | + * TODO it is better to reuse these clusters */ | ||
544 | + QSIMPLEQ_FOREACH_SAFE(tb, &drop_tables, entry, tb_next) { | ||
545 | + free_bitmap_clusters(bs, tb); | ||
546 | + g_free(tb); | ||
547 | + } | ||
548 | + | ||
549 | + bitmap_list_free(bm_list); | ||
550 | + return; | ||
551 | + | ||
552 | +fail: | ||
553 | + QSIMPLEQ_FOREACH(bm, bm_list, entry) { | ||
554 | + if (bm->dirty_bitmap == NULL || bm->table.offset == 0) { | ||
555 | + continue; | ||
556 | + } | ||
557 | + | ||
558 | + free_bitmap_clusters(bs, &bm->table); | ||
559 | + } | ||
560 | + | ||
561 | + QSIMPLEQ_FOREACH_SAFE(tb, &drop_tables, entry, tb_next) { | ||
562 | + g_free(tb); | ||
563 | + } | ||
564 | + | ||
565 | + bitmap_list_free(bm_list); | ||
566 | +} | ||
567 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
568 | index XXXXXXX..XXXXXXX 100644 | ||
569 | --- a/block/qcow2.c | ||
570 | +++ b/block/qcow2.c | ||
571 | @@ -XXX,XX +XXX,XX @@ static int qcow2_inactivate(BlockDriverState *bs) | ||
572 | { | ||
573 | BDRVQcow2State *s = bs->opaque; | ||
574 | int ret, result = 0; | ||
575 | + Error *local_err = NULL; | ||
576 | |||
577 | ret = qcow2_cache_flush(bs, s->l2_table_cache); | ||
578 | if (ret) { | ||
579 | @@ -XXX,XX +XXX,XX @@ static int qcow2_inactivate(BlockDriverState *bs) | ||
580 | strerror(-ret)); | ||
581 | } | ||
582 | |||
583 | + qcow2_store_persistent_dirty_bitmaps(bs, &local_err); | ||
584 | + if (local_err != NULL) { | ||
585 | + result = -EINVAL; | ||
586 | + error_report_err(local_err); | ||
587 | + error_report("Persistent bitmaps are lost for node '%s'", | ||
588 | + bdrv_get_device_or_node_name(bs)); | ||
589 | + } | ||
590 | + | ||
591 | if (result == 0) { | ||
592 | qcow2_mark_clean(bs); | ||
593 | } | ||
594 | -- | ||
595 | 2.9.4 | ||
596 | |||
597 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | Store bitmaps and mark them read-only on reopening image as read-only. | ||
4 | |||
5 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
6 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
7 | Message-id: 20170628120530.31251-21-vsementsov@virtuozzo.com | ||
8 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
9 | --- | ||
10 | block/qcow2.h | 1 + | ||
11 | block/qcow2-bitmap.c | 22 ++++++++++++++++++++++ | ||
12 | block/qcow2.c | 5 +++++ | ||
13 | 3 files changed, 28 insertions(+) | ||
14 | |||
15 | diff --git a/block/qcow2.h b/block/qcow2.h | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/block/qcow2.h | ||
18 | +++ b/block/qcow2.h | ||
19 | @@ -XXX,XX +XXX,XX @@ int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res, | ||
20 | bool qcow2_load_autoloading_dirty_bitmaps(BlockDriverState *bs, Error **errp); | ||
21 | int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp); | ||
22 | void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp); | ||
23 | +int qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp); | ||
24 | |||
25 | #endif | ||
26 | diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c | ||
27 | index XXXXXXX..XXXXXXX 100644 | ||
28 | --- a/block/qcow2-bitmap.c | ||
29 | +++ b/block/qcow2-bitmap.c | ||
30 | @@ -XXX,XX +XXX,XX @@ fail: | ||
31 | |||
32 | bitmap_list_free(bm_list); | ||
33 | } | ||
34 | + | ||
35 | +int qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp) | ||
36 | +{ | ||
37 | + BdrvDirtyBitmap *bitmap; | ||
38 | + Error *local_err = NULL; | ||
39 | + | ||
40 | + qcow2_store_persistent_dirty_bitmaps(bs, &local_err); | ||
41 | + if (local_err != NULL) { | ||
42 | + error_propagate(errp, local_err); | ||
43 | + return -EINVAL; | ||
44 | + } | ||
45 | + | ||
46 | + for (bitmap = bdrv_dirty_bitmap_next(bs, NULL); bitmap != NULL; | ||
47 | + bitmap = bdrv_dirty_bitmap_next(bs, bitmap)) | ||
48 | + { | ||
49 | + if (bdrv_dirty_bitmap_get_persistance(bitmap)) { | ||
50 | + bdrv_dirty_bitmap_set_readonly(bitmap, true); | ||
51 | + } | ||
52 | + } | ||
53 | + | ||
54 | + return 0; | ||
55 | +} | ||
56 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
57 | index XXXXXXX..XXXXXXX 100644 | ||
58 | --- a/block/qcow2.c | ||
59 | +++ b/block/qcow2.c | ||
60 | @@ -XXX,XX +XXX,XX @@ static int qcow2_reopen_prepare(BDRVReopenState *state, | ||
61 | |||
62 | /* We need to write out any unwritten data if we reopen read-only. */ | ||
63 | if ((state->flags & BDRV_O_RDWR) == 0) { | ||
64 | + ret = qcow2_reopen_bitmaps_ro(state->bs, errp); | ||
65 | + if (ret < 0) { | ||
66 | + goto fail; | ||
67 | + } | ||
68 | + | ||
69 | ret = bdrv_flush(state->bs); | ||
70 | if (ret < 0) { | ||
71 | goto fail; | ||
72 | -- | ||
73 | 2.9.4 | ||
74 | |||
75 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | This will be needed to check some restrictions before making bitmap | ||
4 | persistent in qmp-block-dirty-bitmap-add (this functionality will be | ||
5 | added by future patch) | ||
6 | |||
7 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
8 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
9 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
10 | Message-id: 20170628120530.31251-22-vsementsov@virtuozzo.com | ||
11 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
12 | --- | ||
13 | include/block/block.h | 3 +++ | ||
14 | include/block/block_int.h | 4 ++++ | ||
15 | block.c | 22 ++++++++++++++++++++++ | ||
16 | 3 files changed, 29 insertions(+) | ||
17 | |||
18 | diff --git a/include/block/block.h b/include/block/block.h | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/include/block/block.h | ||
21 | +++ b/include/block/block.h | ||
22 | @@ -XXX,XX +XXX,XX @@ void bdrv_add_child(BlockDriverState *parent, BlockDriverState *child, | ||
23 | Error **errp); | ||
24 | void bdrv_del_child(BlockDriverState *parent, BdrvChild *child, Error **errp); | ||
25 | |||
26 | +bool bdrv_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name, | ||
27 | + uint32_t granularity, Error **errp); | ||
28 | + | ||
29 | #endif | ||
30 | diff --git a/include/block/block_int.h b/include/block/block_int.h | ||
31 | index XXXXXXX..XXXXXXX 100644 | ||
32 | --- a/include/block/block_int.h | ||
33 | +++ b/include/block/block_int.h | ||
34 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
35 | * field of BlockDirtyBitmap's in case of success. | ||
36 | */ | ||
37 | int (*bdrv_reopen_bitmaps_rw)(BlockDriverState *bs, Error **errp); | ||
38 | + bool (*bdrv_can_store_new_dirty_bitmap)(BlockDriverState *bs, | ||
39 | + const char *name, | ||
40 | + uint32_t granularity, | ||
41 | + Error **errp); | ||
42 | |||
43 | QLIST_ENTRY(BlockDriver) list; | ||
44 | }; | ||
45 | diff --git a/block.c b/block.c | ||
46 | index XXXXXXX..XXXXXXX 100644 | ||
47 | --- a/block.c | ||
48 | +++ b/block.c | ||
49 | @@ -XXX,XX +XXX,XX @@ void bdrv_del_child(BlockDriverState *parent_bs, BdrvChild *child, Error **errp) | ||
50 | |||
51 | parent_bs->drv->bdrv_del_child(parent_bs, child, errp); | ||
52 | } | ||
53 | + | ||
54 | +bool bdrv_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name, | ||
55 | + uint32_t granularity, Error **errp) | ||
56 | +{ | ||
57 | + BlockDriver *drv = bs->drv; | ||
58 | + | ||
59 | + if (!drv) { | ||
60 | + error_setg_errno(errp, ENOMEDIUM, | ||
61 | + "Can't store persistent bitmaps to %s", | ||
62 | + bdrv_get_device_or_node_name(bs)); | ||
63 | + return false; | ||
64 | + } | ||
65 | + | ||
66 | + if (!drv->bdrv_can_store_new_dirty_bitmap) { | ||
67 | + error_setg_errno(errp, ENOTSUP, | ||
68 | + "Can't store persistent bitmaps to %s", | ||
69 | + bdrv_get_device_or_node_name(bs)); | ||
70 | + return false; | ||
71 | + } | ||
72 | + | ||
73 | + return drv->bdrv_can_store_new_dirty_bitmap(bs, name, granularity, errp); | ||
74 | +} | ||
75 | -- | ||
76 | 2.9.4 | ||
77 | |||
78 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | Realize .bdrv_can_store_new_dirty_bitmap interface. | ||
4 | |||
5 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
6 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
7 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
8 | Message-id: 20170628120530.31251-23-vsementsov@virtuozzo.com | ||
9 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
10 | --- | ||
11 | block/qcow2.h | 4 ++++ | ||
12 | block/qcow2-bitmap.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ | ||
13 | block/qcow2.c | 1 + | ||
14 | 3 files changed, 56 insertions(+) | ||
15 | |||
16 | diff --git a/block/qcow2.h b/block/qcow2.h | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/block/qcow2.h | ||
19 | +++ b/block/qcow2.h | ||
20 | @@ -XXX,XX +XXX,XX @@ bool qcow2_load_autoloading_dirty_bitmaps(BlockDriverState *bs, Error **errp); | ||
21 | int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp); | ||
22 | void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp); | ||
23 | int qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp); | ||
24 | +bool qcow2_can_store_new_dirty_bitmap(BlockDriverState *bs, | ||
25 | + const char *name, | ||
26 | + uint32_t granularity, | ||
27 | + Error **errp); | ||
28 | |||
29 | #endif | ||
30 | diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c | ||
31 | index XXXXXXX..XXXXXXX 100644 | ||
32 | --- a/block/qcow2-bitmap.c | ||
33 | +++ b/block/qcow2-bitmap.c | ||
34 | @@ -XXX,XX +XXX,XX @@ int qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp) | ||
35 | |||
36 | return 0; | ||
37 | } | ||
38 | + | ||
39 | +bool qcow2_can_store_new_dirty_bitmap(BlockDriverState *bs, | ||
40 | + const char *name, | ||
41 | + uint32_t granularity, | ||
42 | + Error **errp) | ||
43 | +{ | ||
44 | + BDRVQcow2State *s = bs->opaque; | ||
45 | + bool found; | ||
46 | + Qcow2BitmapList *bm_list; | ||
47 | + | ||
48 | + if (check_constraints_on_bitmap(bs, name, granularity, errp) != 0) { | ||
49 | + goto fail; | ||
50 | + } | ||
51 | + | ||
52 | + if (s->nb_bitmaps == 0) { | ||
53 | + return true; | ||
54 | + } | ||
55 | + | ||
56 | + if (s->nb_bitmaps >= QCOW2_MAX_BITMAPS) { | ||
57 | + error_setg(errp, | ||
58 | + "Maximum number of persistent bitmaps is already reached"); | ||
59 | + goto fail; | ||
60 | + } | ||
61 | + | ||
62 | + if (s->bitmap_directory_size + calc_dir_entry_size(strlen(name), 0) > | ||
63 | + QCOW2_MAX_BITMAP_DIRECTORY_SIZE) | ||
64 | + { | ||
65 | + error_setg(errp, "Not enough space in the bitmap directory"); | ||
66 | + goto fail; | ||
67 | + } | ||
68 | + | ||
69 | + bm_list = bitmap_list_load(bs, s->bitmap_directory_offset, | ||
70 | + s->bitmap_directory_size, errp); | ||
71 | + if (bm_list == NULL) { | ||
72 | + goto fail; | ||
73 | + } | ||
74 | + | ||
75 | + found = find_bitmap_by_name(bm_list, name); | ||
76 | + bitmap_list_free(bm_list); | ||
77 | + if (found) { | ||
78 | + error_setg(errp, "Bitmap with the same name is already stored"); | ||
79 | + goto fail; | ||
80 | + } | ||
81 | + | ||
82 | + return true; | ||
83 | + | ||
84 | +fail: | ||
85 | + error_prepend(errp, "Can't make bitmap '%s' persistent in '%s': ", | ||
86 | + name, bdrv_get_device_or_node_name(bs)); | ||
87 | + return false; | ||
88 | +} | ||
89 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
90 | index XXXXXXX..XXXXXXX 100644 | ||
91 | --- a/block/qcow2.c | ||
92 | +++ b/block/qcow2.c | ||
93 | @@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_qcow2 = { | ||
94 | .bdrv_attach_aio_context = qcow2_attach_aio_context, | ||
95 | |||
96 | .bdrv_reopen_bitmaps_rw = qcow2_reopen_bitmaps_rw, | ||
97 | + .bdrv_can_store_new_dirty_bitmap = qcow2_can_store_new_dirty_bitmap, | ||
98 | }; | ||
99 | |||
100 | static void bdrv_qcow2_init(void) | ||
101 | -- | ||
102 | 2.9.4 | ||
103 | |||
104 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | Add optional 'persistent' flag to qmp command block-dirty-bitmap-add. | ||
4 | Default is false. | ||
5 | |||
6 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
7 | Signed-off-by: Denis V. Lunev <den@openvz.org> | ||
8 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
9 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
10 | Message-id: 20170628120530.31251-24-vsementsov@virtuozzo.com | ||
11 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
12 | --- | ||
13 | qapi/block-core.json | 8 +++++++- | ||
14 | blockdev.c | 18 +++++++++++++++++- | ||
15 | 2 files changed, 24 insertions(+), 2 deletions(-) | ||
16 | |||
17 | diff --git a/qapi/block-core.json b/qapi/block-core.json | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/qapi/block-core.json | ||
20 | +++ b/qapi/block-core.json | ||
21 | @@ -XXX,XX +XXX,XX @@ | ||
22 | # @granularity: the bitmap granularity, default is 64k for | ||
23 | # block-dirty-bitmap-add | ||
24 | # | ||
25 | +# @persistent: the bitmap is persistent, i.e. it will be saved to the | ||
26 | +# corresponding block device image file on its close. For now only | ||
27 | +# Qcow2 disks support persistent bitmaps. Default is false for | ||
28 | +# block-dirty-bitmap-add. (Since: 2.10) | ||
29 | +# | ||
30 | # Since: 2.4 | ||
31 | ## | ||
32 | { 'struct': 'BlockDirtyBitmapAdd', | ||
33 | - 'data': { 'node': 'str', 'name': 'str', '*granularity': 'uint32' } } | ||
34 | + 'data': { 'node': 'str', 'name': 'str', '*granularity': 'uint32', | ||
35 | + '*persistent': 'bool' } } | ||
36 | |||
37 | ## | ||
38 | # @block-dirty-bitmap-add: | ||
39 | diff --git a/blockdev.c b/blockdev.c | ||
40 | index XXXXXXX..XXXXXXX 100644 | ||
41 | --- a/blockdev.c | ||
42 | +++ b/blockdev.c | ||
43 | @@ -XXX,XX +XXX,XX @@ static void block_dirty_bitmap_add_prepare(BlkActionState *common, | ||
44 | /* AIO context taken and released within qmp_block_dirty_bitmap_add */ | ||
45 | qmp_block_dirty_bitmap_add(action->node, action->name, | ||
46 | action->has_granularity, action->granularity, | ||
47 | + action->has_persistent, action->persistent, | ||
48 | &local_err); | ||
49 | |||
50 | if (!local_err) { | ||
51 | @@ -XXX,XX +XXX,XX @@ out: | ||
52 | |||
53 | void qmp_block_dirty_bitmap_add(const char *node, const char *name, | ||
54 | bool has_granularity, uint32_t granularity, | ||
55 | + bool has_persistent, bool persistent, | ||
56 | Error **errp) | ||
57 | { | ||
58 | BlockDriverState *bs; | ||
59 | + BdrvDirtyBitmap *bitmap; | ||
60 | |||
61 | if (!name || name[0] == '\0') { | ||
62 | error_setg(errp, "Bitmap name cannot be empty"); | ||
63 | @@ -XXX,XX +XXX,XX @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name, | ||
64 | granularity = bdrv_get_default_bitmap_granularity(bs); | ||
65 | } | ||
66 | |||
67 | - bdrv_create_dirty_bitmap(bs, granularity, name, errp); | ||
68 | + if (!has_persistent) { | ||
69 | + persistent = false; | ||
70 | + } | ||
71 | + | ||
72 | + if (persistent && | ||
73 | + !bdrv_can_store_new_dirty_bitmap(bs, name, granularity, errp)) | ||
74 | + { | ||
75 | + return; | ||
76 | + } | ||
77 | + | ||
78 | + bitmap = bdrv_create_dirty_bitmap(bs, granularity, name, errp); | ||
79 | + if (bitmap != NULL) { | ||
80 | + bdrv_dirty_bitmap_set_persistance(bitmap, persistent); | ||
81 | + } | ||
82 | } | ||
83 | |||
84 | void qmp_block_dirty_bitmap_remove(const char *node, const char *name, | ||
85 | -- | ||
86 | 2.9.4 | ||
87 | |||
88 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | Optional. Default is false. | ||
4 | |||
5 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
6 | Signed-off-by: Denis V. Lunev <den@openvz.org> | ||
7 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
8 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
9 | Message-id: 20170628120530.31251-25-vsementsov@virtuozzo.com | ||
10 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
11 | --- | ||
12 | qapi/block-core.json | 6 +++++- | ||
13 | blockdev.c | 18 ++++++++++++++++-- | ||
14 | 2 files changed, 21 insertions(+), 3 deletions(-) | ||
15 | |||
16 | diff --git a/qapi/block-core.json b/qapi/block-core.json | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/qapi/block-core.json | ||
19 | +++ b/qapi/block-core.json | ||
20 | @@ -XXX,XX +XXX,XX @@ | ||
21 | # Qcow2 disks support persistent bitmaps. Default is false for | ||
22 | # block-dirty-bitmap-add. (Since: 2.10) | ||
23 | # | ||
24 | +# @autoload: the bitmap will be automatically loaded when the image it is stored | ||
25 | +# in is opened. This flag may only be specified for persistent | ||
26 | +# bitmaps. Default is false for block-dirty-bitmap-add. (Since: 2.10) | ||
27 | +# | ||
28 | # Since: 2.4 | ||
29 | ## | ||
30 | { 'struct': 'BlockDirtyBitmapAdd', | ||
31 | 'data': { 'node': 'str', 'name': 'str', '*granularity': 'uint32', | ||
32 | - '*persistent': 'bool' } } | ||
33 | + '*persistent': 'bool', '*autoload': 'bool' } } | ||
34 | |||
35 | ## | ||
36 | # @block-dirty-bitmap-add: | ||
37 | diff --git a/blockdev.c b/blockdev.c | ||
38 | index XXXXXXX..XXXXXXX 100644 | ||
39 | --- a/blockdev.c | ||
40 | +++ b/blockdev.c | ||
41 | @@ -XXX,XX +XXX,XX @@ static void block_dirty_bitmap_add_prepare(BlkActionState *common, | ||
42 | qmp_block_dirty_bitmap_add(action->node, action->name, | ||
43 | action->has_granularity, action->granularity, | ||
44 | action->has_persistent, action->persistent, | ||
45 | + action->has_autoload, action->autoload, | ||
46 | &local_err); | ||
47 | |||
48 | if (!local_err) { | ||
49 | @@ -XXX,XX +XXX,XX @@ out: | ||
50 | void qmp_block_dirty_bitmap_add(const char *node, const char *name, | ||
51 | bool has_granularity, uint32_t granularity, | ||
52 | bool has_persistent, bool persistent, | ||
53 | + bool has_autoload, bool autoload, | ||
54 | Error **errp) | ||
55 | { | ||
56 | BlockDriverState *bs; | ||
57 | @@ -XXX,XX +XXX,XX @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name, | ||
58 | if (!has_persistent) { | ||
59 | persistent = false; | ||
60 | } | ||
61 | + if (!has_autoload) { | ||
62 | + autoload = false; | ||
63 | + } | ||
64 | + | ||
65 | + if (has_autoload && !persistent) { | ||
66 | + error_setg(errp, "Autoload flag must be used only for persistent " | ||
67 | + "bitmaps"); | ||
68 | + return; | ||
69 | + } | ||
70 | |||
71 | if (persistent && | ||
72 | !bdrv_can_store_new_dirty_bitmap(bs, name, granularity, errp)) | ||
73 | @@ -XXX,XX +XXX,XX @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name, | ||
74 | } | ||
75 | |||
76 | bitmap = bdrv_create_dirty_bitmap(bs, granularity, name, errp); | ||
77 | - if (bitmap != NULL) { | ||
78 | - bdrv_dirty_bitmap_set_persistance(bitmap, persistent); | ||
79 | + if (bitmap == NULL) { | ||
80 | + return; | ||
81 | } | ||
82 | + | ||
83 | + bdrv_dirty_bitmap_set_persistance(bitmap, persistent); | ||
84 | + bdrv_dirty_bitmap_set_autoload(bitmap, autoload); | ||
85 | } | ||
86 | |||
87 | void qmp_block_dirty_bitmap_remove(const char *node, const char *name, | ||
88 | -- | ||
89 | 2.9.4 | ||
90 | |||
91 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
4 | Message-id: 20170628120530.31251-26-vsementsov@virtuozzo.com | ||
5 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
6 | --- | ||
7 | tests/Makefile.include | 2 +- | ||
8 | qapi/block-core.json | 27 +++++++++++++++++++++++++++ | ||
9 | include/block/dirty-bitmap.h | 1 + | ||
10 | include/qemu/hbitmap.h | 8 ++++++++ | ||
11 | block/dirty-bitmap.c | 5 +++++ | ||
12 | blockdev.c | 25 +++++++++++++++++++++++++ | ||
13 | util/hbitmap.c | 11 +++++++++++ | ||
14 | 7 files changed, 78 insertions(+), 1 deletion(-) | ||
15 | |||
16 | diff --git a/tests/Makefile.include b/tests/Makefile.include | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/tests/Makefile.include | ||
19 | +++ b/tests/Makefile.include | ||
20 | @@ -XXX,XX +XXX,XX @@ tests/test-blockjob$(EXESUF): tests/test-blockjob.o $(test-block-obj-y) $(test-u | ||
21 | tests/test-blockjob-txn$(EXESUF): tests/test-blockjob-txn.o $(test-block-obj-y) $(test-util-obj-y) | ||
22 | tests/test-thread-pool$(EXESUF): tests/test-thread-pool.o $(test-block-obj-y) | ||
23 | tests/test-iov$(EXESUF): tests/test-iov.o $(test-util-obj-y) | ||
24 | -tests/test-hbitmap$(EXESUF): tests/test-hbitmap.o $(test-util-obj-y) | ||
25 | +tests/test-hbitmap$(EXESUF): tests/test-hbitmap.o $(test-util-obj-y) $(test-crypto-obj-y) | ||
26 | tests/test-x86-cpuid$(EXESUF): tests/test-x86-cpuid.o | ||
27 | tests/test-xbzrle$(EXESUF): tests/test-xbzrle.o migration/xbzrle.o migration/page_cache.o $(test-util-obj-y) | ||
28 | tests/test-cutils$(EXESUF): tests/test-cutils.o util/cutils.o | ||
29 | diff --git a/qapi/block-core.json b/qapi/block-core.json | ||
30 | index XXXXXXX..XXXXXXX 100644 | ||
31 | --- a/qapi/block-core.json | ||
32 | +++ b/qapi/block-core.json | ||
33 | @@ -XXX,XX +XXX,XX @@ | ||
34 | 'data': 'BlockDirtyBitmap' } | ||
35 | |||
36 | ## | ||
37 | +# @BlockDirtyBitmapSha256: | ||
38 | +# | ||
39 | +# SHA256 hash of dirty bitmap data | ||
40 | +# | ||
41 | +# @sha256: ASCII representation of SHA256 bitmap hash | ||
42 | +# | ||
43 | +# Since: 2.10 | ||
44 | +## | ||
45 | + { 'struct': 'BlockDirtyBitmapSha256', | ||
46 | + 'data': {'sha256': 'str'} } | ||
47 | + | ||
48 | +## | ||
49 | +# @x-debug-block-dirty-bitmap-sha256: | ||
50 | +# | ||
51 | +# Get bitmap SHA256 | ||
52 | +# | ||
53 | +# Returns: BlockDirtyBitmapSha256 on success | ||
54 | +# If @node is not a valid block device, DeviceNotFound | ||
55 | +# If @name is not found or if hashing has failed, GenericError with an | ||
56 | +# explanation | ||
57 | +# | ||
58 | +# Since: 2.10 | ||
59 | +## | ||
60 | + { 'command': 'x-debug-block-dirty-bitmap-sha256', | ||
61 | + 'data': 'BlockDirtyBitmap', 'returns': 'BlockDirtyBitmapSha256' } | ||
62 | + | ||
63 | +## | ||
64 | # @blockdev-mirror: | ||
65 | # | ||
66 | # Start mirroring a block device's writes to a new destination. | ||
67 | diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h | ||
68 | index XXXXXXX..XXXXXXX 100644 | ||
69 | --- a/include/block/dirty-bitmap.h | ||
70 | +++ b/include/block/dirty-bitmap.h | ||
71 | @@ -XXX,XX +XXX,XX @@ bool bdrv_dirty_bitmap_get_persistance(BdrvDirtyBitmap *bitmap); | ||
72 | bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs); | ||
73 | BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs, | ||
74 | BdrvDirtyBitmap *bitmap); | ||
75 | +char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp); | ||
76 | |||
77 | #endif | ||
78 | diff --git a/include/qemu/hbitmap.h b/include/qemu/hbitmap.h | ||
79 | index XXXXXXX..XXXXXXX 100644 | ||
80 | --- a/include/qemu/hbitmap.h | ||
81 | +++ b/include/qemu/hbitmap.h | ||
82 | @@ -XXX,XX +XXX,XX @@ void hbitmap_deserialize_ones(HBitmap *hb, uint64_t start, uint64_t count, | ||
83 | void hbitmap_deserialize_finish(HBitmap *hb); | ||
84 | |||
85 | /** | ||
86 | + * hbitmap_sha256: | ||
87 | + * @bitmap: HBitmap to operate on. | ||
88 | + * | ||
89 | + * Returns SHA256 hash of the last level. | ||
90 | + */ | ||
91 | +char *hbitmap_sha256(const HBitmap *bitmap, Error **errp); | ||
92 | + | ||
93 | +/** | ||
94 | * hbitmap_free: | ||
95 | * @hb: HBitmap to operate on. | ||
96 | * | ||
97 | diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c | ||
98 | index XXXXXXX..XXXXXXX 100644 | ||
99 | --- a/block/dirty-bitmap.c | ||
100 | +++ b/block/dirty-bitmap.c | ||
101 | @@ -XXX,XX +XXX,XX @@ BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs, | ||
102 | return bitmap == NULL ? QLIST_FIRST(&bs->dirty_bitmaps) : | ||
103 | QLIST_NEXT(bitmap, list); | ||
104 | } | ||
105 | + | ||
106 | +char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp) | ||
107 | +{ | ||
108 | + return hbitmap_sha256(bitmap->bitmap, errp); | ||
109 | +} | ||
110 | diff --git a/blockdev.c b/blockdev.c | ||
111 | index XXXXXXX..XXXXXXX 100644 | ||
112 | --- a/blockdev.c | ||
113 | +++ b/blockdev.c | ||
114 | @@ -XXX,XX +XXX,XX @@ void qmp_block_dirty_bitmap_clear(const char *node, const char *name, | ||
115 | bdrv_clear_dirty_bitmap(bitmap, NULL); | ||
116 | } | ||
117 | |||
118 | +BlockDirtyBitmapSha256 *qmp_x_debug_block_dirty_bitmap_sha256(const char *node, | ||
119 | + const char *name, | ||
120 | + Error **errp) | ||
121 | +{ | ||
122 | + BdrvDirtyBitmap *bitmap; | ||
123 | + BlockDriverState *bs; | ||
124 | + BlockDirtyBitmapSha256 *ret = NULL; | ||
125 | + char *sha256; | ||
126 | + | ||
127 | + bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp); | ||
128 | + if (!bitmap || !bs) { | ||
129 | + return NULL; | ||
130 | + } | ||
131 | + | ||
132 | + sha256 = bdrv_dirty_bitmap_sha256(bitmap, errp); | ||
133 | + if (sha256 == NULL) { | ||
134 | + return NULL; | ||
135 | + } | ||
136 | + | ||
137 | + ret = g_new(BlockDirtyBitmapSha256, 1); | ||
138 | + ret->sha256 = sha256; | ||
139 | + | ||
140 | + return ret; | ||
141 | +} | ||
142 | + | ||
143 | void hmp_drive_del(Monitor *mon, const QDict *qdict) | ||
144 | { | ||
145 | const char *id = qdict_get_str(qdict, "id"); | ||
146 | diff --git a/util/hbitmap.c b/util/hbitmap.c | ||
147 | index XXXXXXX..XXXXXXX 100644 | ||
148 | --- a/util/hbitmap.c | ||
149 | +++ b/util/hbitmap.c | ||
150 | @@ -XXX,XX +XXX,XX @@ | ||
151 | #include "qemu/hbitmap.h" | ||
152 | #include "qemu/host-utils.h" | ||
153 | #include "trace.h" | ||
154 | +#include "crypto/hash.h" | ||
155 | |||
156 | /* HBitmaps provides an array of bits. The bits are stored as usual in an | ||
157 | * array of unsigned longs, but HBitmap is also optimized to provide fast | ||
158 | @@ -XXX,XX +XXX,XX @@ void hbitmap_free_meta(HBitmap *hb) | ||
159 | hbitmap_free(hb->meta); | ||
160 | hb->meta = NULL; | ||
161 | } | ||
162 | + | ||
163 | +char *hbitmap_sha256(const HBitmap *bitmap, Error **errp) | ||
164 | +{ | ||
165 | + size_t size = bitmap->sizes[HBITMAP_LEVELS - 1] * sizeof(unsigned long); | ||
166 | + char *data = (char *)bitmap->levels[HBITMAP_LEVELS - 1]; | ||
167 | + char *hash = NULL; | ||
168 | + qcrypto_hash_digest(QCRYPTO_HASH_ALG_SHA256, data, size, &hash, errp); | ||
169 | + | ||
170 | + return hash; | ||
171 | +} | ||
172 | -- | ||
173 | 2.9.4 | ||
174 | |||
175 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
4 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
5 | Message-id: 20170628120530.31251-27-vsementsov@virtuozzo.com | ||
6 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
7 | --- | ||
8 | tests/qemu-iotests/165 | 105 +++++++++++++++++++++++++++++++++++++++++++++ | ||
9 | tests/qemu-iotests/165.out | 5 +++ | ||
10 | tests/qemu-iotests/group | 1 + | ||
11 | 3 files changed, 111 insertions(+) | ||
12 | create mode 100755 tests/qemu-iotests/165 | ||
13 | create mode 100644 tests/qemu-iotests/165.out | ||
14 | |||
15 | diff --git a/tests/qemu-iotests/165 b/tests/qemu-iotests/165 | ||
16 | new file mode 100755 | ||
17 | index XXXXXXX..XXXXXXX | ||
18 | --- /dev/null | ||
19 | +++ b/tests/qemu-iotests/165 | ||
20 | @@ -XXX,XX +XXX,XX @@ | ||
21 | +#!/usr/bin/env python | ||
22 | +# | ||
23 | +# Tests for persistent dirty bitmaps. | ||
24 | +# | ||
25 | +# Copyright: Vladimir Sementsov-Ogievskiy 2015-2017 | ||
26 | +# | ||
27 | +# This program is free software; you can redistribute it and/or modify | ||
28 | +# it under the terms of the GNU General Public License as published by | ||
29 | +# the Free Software Foundation; either version 2 of the License, or | ||
30 | +# (at your option) any later version. | ||
31 | +# | ||
32 | +# This program is distributed in the hope that it will be useful, | ||
33 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
34 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
35 | +# GNU General Public License for more details. | ||
36 | +# | ||
37 | +# You should have received a copy of the GNU General Public License | ||
38 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
39 | +# | ||
40 | + | ||
41 | +import os | ||
42 | +import re | ||
43 | +import iotests | ||
44 | +from iotests import qemu_img | ||
45 | + | ||
46 | +disk = os.path.join(iotests.test_dir, 'disk') | ||
47 | +disk_size = 0x40000000 # 1G | ||
48 | + | ||
49 | +# regions for qemu_io: (start, count) in bytes | ||
50 | +regions1 = ((0, 0x100000), | ||
51 | + (0x200000, 0x100000)) | ||
52 | + | ||
53 | +regions2 = ((0x10000000, 0x20000), | ||
54 | + (0x3fff0000, 0x10000)) | ||
55 | + | ||
56 | +class TestPersistentDirtyBitmap(iotests.QMPTestCase): | ||
57 | + | ||
58 | + def setUp(self): | ||
59 | + qemu_img('create', '-f', iotests.imgfmt, disk, str(disk_size)) | ||
60 | + | ||
61 | + def tearDown(self): | ||
62 | + os.remove(disk) | ||
63 | + | ||
64 | + def mkVm(self): | ||
65 | + return iotests.VM().add_drive(disk) | ||
66 | + | ||
67 | + def mkVmRo(self): | ||
68 | + return iotests.VM().add_drive(disk, opts='readonly=on') | ||
69 | + | ||
70 | + def getSha256(self): | ||
71 | + result = self.vm.qmp('x-debug-block-dirty-bitmap-sha256', | ||
72 | + node='drive0', name='bitmap0') | ||
73 | + return result['return']['sha256'] | ||
74 | + | ||
75 | + def checkBitmap(self, sha256): | ||
76 | + result = self.vm.qmp('x-debug-block-dirty-bitmap-sha256', | ||
77 | + node='drive0', name='bitmap0') | ||
78 | + self.assert_qmp(result, 'return/sha256', sha256); | ||
79 | + | ||
80 | + def writeRegions(self, regions): | ||
81 | + for r in regions: | ||
82 | + self.vm.hmp_qemu_io('drive0', | ||
83 | + 'write %d %d' % r) | ||
84 | + | ||
85 | + def qmpAddBitmap(self): | ||
86 | + self.vm.qmp('block-dirty-bitmap-add', node='drive0', | ||
87 | + name='bitmap0', persistent=True, autoload=True) | ||
88 | + | ||
89 | + def test_persistent(self): | ||
90 | + self.vm = self.mkVm() | ||
91 | + self.vm.launch() | ||
92 | + self.qmpAddBitmap() | ||
93 | + | ||
94 | + self.writeRegions(regions1) | ||
95 | + sha256 = self.getSha256() | ||
96 | + | ||
97 | + self.vm.shutdown() | ||
98 | + | ||
99 | + self.vm = self.mkVmRo() | ||
100 | + self.vm.launch() | ||
101 | + self.vm.shutdown() | ||
102 | + | ||
103 | + #catch 'Persistent bitmaps are lost' possible error | ||
104 | + log = self.vm.get_log() | ||
105 | + log = re.sub(r'^\[I \d+\.\d+\] OPENED\n', '', log) | ||
106 | + log = re.sub(r'\[I \+\d+\.\d+\] CLOSED\n?$', '', log) | ||
107 | + if log: | ||
108 | + print log | ||
109 | + | ||
110 | + self.vm = self.mkVm() | ||
111 | + self.vm.launch() | ||
112 | + | ||
113 | + self.checkBitmap(sha256) | ||
114 | + self.writeRegions(regions2) | ||
115 | + sha256 = self.getSha256() | ||
116 | + | ||
117 | + self.vm.shutdown() | ||
118 | + self.vm.launch() | ||
119 | + | ||
120 | + self.checkBitmap(sha256) | ||
121 | + | ||
122 | + self.vm.shutdown() | ||
123 | + | ||
124 | +if __name__ == '__main__': | ||
125 | + iotests.main(supported_fmts=['qcow2']) | ||
126 | diff --git a/tests/qemu-iotests/165.out b/tests/qemu-iotests/165.out | ||
127 | new file mode 100644 | ||
128 | index XXXXXXX..XXXXXXX | ||
129 | --- /dev/null | ||
130 | +++ b/tests/qemu-iotests/165.out | ||
131 | @@ -XXX,XX +XXX,XX @@ | ||
132 | +. | ||
133 | +---------------------------------------------------------------------- | ||
134 | +Ran 1 tests | ||
135 | + | ||
136 | +OK | ||
137 | diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group | ||
138 | index XXXXXXX..XXXXXXX 100644 | ||
139 | --- a/tests/qemu-iotests/group | ||
140 | +++ b/tests/qemu-iotests/group | ||
141 | @@ -XXX,XX +XXX,XX @@ | ||
142 | 159 rw auto quick | ||
143 | 160 rw auto quick | ||
144 | 162 auto quick | ||
145 | +165 rw auto quick | ||
146 | 170 rw auto quick | ||
147 | 171 rw auto quick | ||
148 | 172 auto | ||
149 | -- | ||
150 | 2.9.4 | ||
151 | |||
152 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | Interface for removing persistent bitmap from its storage. | ||
4 | |||
5 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
6 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
7 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
8 | Message-id: 20170628120530.31251-28-vsementsov@virtuozzo.com | ||
9 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
10 | --- | ||
11 | include/block/block_int.h | 3 +++ | ||
12 | include/block/dirty-bitmap.h | 3 +++ | ||
13 | block/dirty-bitmap.c | 18 ++++++++++++++++++ | ||
14 | 3 files changed, 24 insertions(+) | ||
15 | |||
16 | diff --git a/include/block/block_int.h b/include/block/block_int.h | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/include/block/block_int.h | ||
19 | +++ b/include/block/block_int.h | ||
20 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
21 | const char *name, | ||
22 | uint32_t granularity, | ||
23 | Error **errp); | ||
24 | + void (*bdrv_remove_persistent_dirty_bitmap)(BlockDriverState *bs, | ||
25 | + const char *name, | ||
26 | + Error **errp); | ||
27 | |||
28 | QLIST_ENTRY(BlockDriver) list; | ||
29 | }; | ||
30 | diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h | ||
31 | index XXXXXXX..XXXXXXX 100644 | ||
32 | --- a/include/block/dirty-bitmap.h | ||
33 | +++ b/include/block/dirty-bitmap.h | ||
34 | @@ -XXX,XX +XXX,XX @@ BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs, | ||
35 | void bdrv_dirty_bitmap_make_anon(BdrvDirtyBitmap *bitmap); | ||
36 | void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); | ||
37 | void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs); | ||
38 | +void bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs, | ||
39 | + const char *name, | ||
40 | + Error **errp); | ||
41 | void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap); | ||
42 | void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap); | ||
43 | BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs); | ||
44 | diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c | ||
45 | index XXXXXXX..XXXXXXX 100644 | ||
46 | --- a/block/dirty-bitmap.c | ||
47 | +++ b/block/dirty-bitmap.c | ||
48 | @@ -XXX,XX +XXX,XX @@ void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap) | ||
49 | /** | ||
50 | * Release all named dirty bitmaps attached to a BDS (for use in bdrv_close()). | ||
51 | * There must not be any frozen bitmaps attached. | ||
52 | + * This function does not remove persistent bitmaps from the storage. | ||
53 | * Called with BQL taken. | ||
54 | */ | ||
55 | void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs) | ||
56 | @@ -XXX,XX +XXX,XX @@ void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs) | ||
57 | bdrv_do_release_matching_dirty_bitmap(bs, NULL, true); | ||
58 | } | ||
59 | |||
60 | +/** | ||
61 | + * Remove persistent dirty bitmap from the storage if it exists. | ||
62 | + * Absence of bitmap is not an error, because we have the following scenario: | ||
63 | + * BdrvDirtyBitmap can have .persistent = true but not yet saved and have no | ||
64 | + * stored version. For such bitmap bdrv_remove_persistent_dirty_bitmap() should | ||
65 | + * not fail. | ||
66 | + * This function doesn't release corresponding BdrvDirtyBitmap. | ||
67 | + */ | ||
68 | +void bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs, | ||
69 | + const char *name, | ||
70 | + Error **errp) | ||
71 | +{ | ||
72 | + if (bs->drv && bs->drv->bdrv_remove_persistent_dirty_bitmap) { | ||
73 | + bs->drv->bdrv_remove_persistent_dirty_bitmap(bs, name, errp); | ||
74 | + } | ||
75 | +} | ||
76 | + | ||
77 | /* Called with BQL taken. */ | ||
78 | void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap) | ||
79 | { | ||
80 | -- | ||
81 | 2.9.4 | ||
82 | |||
83 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | Realize .bdrv_remove_persistent_dirty_bitmap interface. | ||
4 | |||
5 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
6 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
7 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
8 | Message-id: 20170628120530.31251-29-vsementsov@virtuozzo.com | ||
9 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
10 | --- | ||
11 | block/qcow2.h | 3 +++ | ||
12 | block/qcow2-bitmap.c | 41 +++++++++++++++++++++++++++++++++++++++++ | ||
13 | block/qcow2.c | 1 + | ||
14 | 3 files changed, 45 insertions(+) | ||
15 | |||
16 | diff --git a/block/qcow2.h b/block/qcow2.h | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/block/qcow2.h | ||
19 | +++ b/block/qcow2.h | ||
20 | @@ -XXX,XX +XXX,XX @@ bool qcow2_can_store_new_dirty_bitmap(BlockDriverState *bs, | ||
21 | const char *name, | ||
22 | uint32_t granularity, | ||
23 | Error **errp); | ||
24 | +void qcow2_remove_persistent_dirty_bitmap(BlockDriverState *bs, | ||
25 | + const char *name, | ||
26 | + Error **errp); | ||
27 | |||
28 | #endif | ||
29 | diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c | ||
30 | index XXXXXXX..XXXXXXX 100644 | ||
31 | --- a/block/qcow2-bitmap.c | ||
32 | +++ b/block/qcow2-bitmap.c | ||
33 | @@ -XXX,XX +XXX,XX @@ static Qcow2Bitmap *find_bitmap_by_name(Qcow2BitmapList *bm_list, | ||
34 | return NULL; | ||
35 | } | ||
36 | |||
37 | +void qcow2_remove_persistent_dirty_bitmap(BlockDriverState *bs, | ||
38 | + const char *name, | ||
39 | + Error **errp) | ||
40 | +{ | ||
41 | + int ret; | ||
42 | + BDRVQcow2State *s = bs->opaque; | ||
43 | + Qcow2Bitmap *bm; | ||
44 | + Qcow2BitmapList *bm_list; | ||
45 | + | ||
46 | + if (s->nb_bitmaps == 0) { | ||
47 | + /* Absence of the bitmap is not an error: see explanation above | ||
48 | + * bdrv_remove_persistent_dirty_bitmap() definition. */ | ||
49 | + return; | ||
50 | + } | ||
51 | + | ||
52 | + bm_list = bitmap_list_load(bs, s->bitmap_directory_offset, | ||
53 | + s->bitmap_directory_size, errp); | ||
54 | + if (bm_list == NULL) { | ||
55 | + return; | ||
56 | + } | ||
57 | + | ||
58 | + bm = find_bitmap_by_name(bm_list, name); | ||
59 | + if (bm == NULL) { | ||
60 | + goto fail; | ||
61 | + } | ||
62 | + | ||
63 | + QSIMPLEQ_REMOVE(bm_list, bm, Qcow2Bitmap, entry); | ||
64 | + | ||
65 | + ret = update_ext_header_and_dir(bs, bm_list); | ||
66 | + if (ret < 0) { | ||
67 | + error_setg_errno(errp, -ret, "Failed to update bitmap extension"); | ||
68 | + goto fail; | ||
69 | + } | ||
70 | + | ||
71 | + free_bitmap_clusters(bs, &bm->table); | ||
72 | + | ||
73 | +fail: | ||
74 | + bitmap_free(bm); | ||
75 | + bitmap_list_free(bm_list); | ||
76 | +} | ||
77 | + | ||
78 | void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp) | ||
79 | { | ||
80 | BdrvDirtyBitmap *bitmap; | ||
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 @@ BlockDriver bdrv_qcow2 = { | ||
86 | |||
87 | .bdrv_reopen_bitmaps_rw = qcow2_reopen_bitmaps_rw, | ||
88 | .bdrv_can_store_new_dirty_bitmap = qcow2_can_store_new_dirty_bitmap, | ||
89 | + .bdrv_remove_persistent_dirty_bitmap = qcow2_remove_persistent_dirty_bitmap, | ||
90 | }; | ||
91 | |||
92 | static void bdrv_qcow2_init(void) | ||
93 | -- | ||
94 | 2.9.4 | ||
95 | |||
96 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | Remove persistent bitmap from the storage on block-dirty-bitmap-remove. | ||
4 | |||
5 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
6 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
7 | Reviewed-by: John Snow <jsnow@redhat.com> | ||
8 | Message-id: 20170628120530.31251-30-vsementsov@virtuozzo.com | ||
9 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
10 | --- | ||
11 | qapi/block-core.json | 3 ++- | ||
12 | blockdev.c | 10 ++++++++++ | ||
13 | 2 files changed, 12 insertions(+), 1 deletion(-) | ||
14 | |||
15 | diff --git a/qapi/block-core.json b/qapi/block-core.json | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/qapi/block-core.json | ||
18 | +++ b/qapi/block-core.json | ||
19 | @@ -XXX,XX +XXX,XX @@ | ||
20 | # @block-dirty-bitmap-remove: | ||
21 | # | ||
22 | # Stop write tracking and remove the dirty bitmap that was created | ||
23 | -# with block-dirty-bitmap-add. | ||
24 | +# with block-dirty-bitmap-add. If the bitmap is persistent, remove it from its | ||
25 | +# storage too. | ||
26 | # | ||
27 | # Returns: nothing on success | ||
28 | # If @node is not a valid block device or node, DeviceNotFound | ||
29 | diff --git a/blockdev.c b/blockdev.c | ||
30 | index XXXXXXX..XXXXXXX 100644 | ||
31 | --- a/blockdev.c | ||
32 | +++ b/blockdev.c | ||
33 | @@ -XXX,XX +XXX,XX @@ void qmp_block_dirty_bitmap_remove(const char *node, const char *name, | ||
34 | { | ||
35 | BlockDriverState *bs; | ||
36 | BdrvDirtyBitmap *bitmap; | ||
37 | + Error *local_err = NULL; | ||
38 | |||
39 | bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp); | ||
40 | if (!bitmap || !bs) { | ||
41 | @@ -XXX,XX +XXX,XX @@ void qmp_block_dirty_bitmap_remove(const char *node, const char *name, | ||
42 | name); | ||
43 | return; | ||
44 | } | ||
45 | + | ||
46 | + if (bdrv_dirty_bitmap_get_persistance(bitmap)) { | ||
47 | + bdrv_remove_persistent_dirty_bitmap(bs, name, &local_err); | ||
48 | + if (local_err != NULL) { | ||
49 | + error_propagate(errp, local_err); | ||
50 | + return; | ||
51 | + } | ||
52 | + } | ||
53 | + | ||
54 | bdrv_dirty_bitmap_make_anon(bitmap); | ||
55 | bdrv_release_dirty_bitmap(bs, bitmap); | ||
56 | } | ||
57 | -- | ||
58 | 2.9.4 | ||
59 | |||
60 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
2 | 1 | ||
3 | We should release them here to reload on invalidate cache. | ||
4 | |||
5 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | ||
6 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
7 | Message-id: 20170628120530.31251-31-vsementsov@virtuozzo.com | ||
8 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
9 | --- | ||
10 | include/block/dirty-bitmap.h | 1 + | ||
11 | block.c | 4 ++++ | ||
12 | block/dirty-bitmap.c | 29 +++++++++++++++++++++++------ | ||
13 | 3 files changed, 28 insertions(+), 6 deletions(-) | ||
14 | |||
15 | diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/include/block/dirty-bitmap.h | ||
18 | +++ b/include/block/dirty-bitmap.h | ||
19 | @@ -XXX,XX +XXX,XX @@ BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs, | ||
20 | void bdrv_dirty_bitmap_make_anon(BdrvDirtyBitmap *bitmap); | ||
21 | void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); | ||
22 | void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs); | ||
23 | +void bdrv_release_persistent_dirty_bitmaps(BlockDriverState *bs); | ||
24 | void bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs, | ||
25 | const char *name, | ||
26 | Error **errp); | ||
27 | diff --git a/block.c b/block.c | ||
28 | index XXXXXXX..XXXXXXX 100644 | ||
29 | --- a/block.c | ||
30 | +++ b/block.c | ||
31 | @@ -XXX,XX +XXX,XX @@ static int bdrv_inactivate_recurse(BlockDriverState *bs, | ||
32 | } | ||
33 | } | ||
34 | |||
35 | + /* At this point persistent bitmaps should be already stored by the format | ||
36 | + * driver */ | ||
37 | + bdrv_release_persistent_dirty_bitmaps(bs); | ||
38 | + | ||
39 | return 0; | ||
40 | } | ||
41 | |||
42 | diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c | ||
43 | index XXXXXXX..XXXXXXX 100644 | ||
44 | --- a/block/dirty-bitmap.c | ||
45 | +++ b/block/dirty-bitmap.c | ||
46 | @@ -XXX,XX +XXX,XX @@ void bdrv_dirty_bitmap_truncate(BlockDriverState *bs) | ||
47 | bdrv_dirty_bitmaps_unlock(bs); | ||
48 | } | ||
49 | |||
50 | +static bool bdrv_dirty_bitmap_has_name(BdrvDirtyBitmap *bitmap) | ||
51 | +{ | ||
52 | + return !!bdrv_dirty_bitmap_name(bitmap); | ||
53 | +} | ||
54 | + | ||
55 | /* Called with BQL taken. */ | ||
56 | -static void bdrv_do_release_matching_dirty_bitmap(BlockDriverState *bs, | ||
57 | - BdrvDirtyBitmap *bitmap, | ||
58 | - bool only_named) | ||
59 | +static void bdrv_do_release_matching_dirty_bitmap( | ||
60 | + BlockDriverState *bs, BdrvDirtyBitmap *bitmap, | ||
61 | + bool (*cond)(BdrvDirtyBitmap *bitmap)) | ||
62 | { | ||
63 | BdrvDirtyBitmap *bm, *next; | ||
64 | bdrv_dirty_bitmaps_lock(bs); | ||
65 | QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) { | ||
66 | - if ((!bitmap || bm == bitmap) && (!only_named || bm->name)) { | ||
67 | + if ((!bitmap || bm == bitmap) && (!cond || cond(bm))) { | ||
68 | assert(!bm->active_iterators); | ||
69 | assert(!bdrv_dirty_bitmap_frozen(bm)); | ||
70 | assert(!bm->meta); | ||
71 | @@ -XXX,XX +XXX,XX @@ out: | ||
72 | /* Called with BQL taken. */ | ||
73 | void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap) | ||
74 | { | ||
75 | - bdrv_do_release_matching_dirty_bitmap(bs, bitmap, false); | ||
76 | + bdrv_do_release_matching_dirty_bitmap(bs, bitmap, NULL); | ||
77 | } | ||
78 | |||
79 | /** | ||
80 | @@ -XXX,XX +XXX,XX @@ void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap) | ||
81 | */ | ||
82 | void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs) | ||
83 | { | ||
84 | - bdrv_do_release_matching_dirty_bitmap(bs, NULL, true); | ||
85 | + bdrv_do_release_matching_dirty_bitmap(bs, NULL, bdrv_dirty_bitmap_has_name); | ||
86 | +} | ||
87 | + | ||
88 | +/** | ||
89 | + * Release all persistent dirty bitmaps attached to a BDS (for use in | ||
90 | + * bdrv_inactivate_recurse()). | ||
91 | + * There must not be any frozen bitmaps attached. | ||
92 | + * This function does not remove persistent bitmaps from the storage. | ||
93 | + */ | ||
94 | +void bdrv_release_persistent_dirty_bitmaps(BlockDriverState *bs) | ||
95 | +{ | ||
96 | + bdrv_do_release_matching_dirty_bitmap(bs, NULL, | ||
97 | + bdrv_dirty_bitmap_get_persistance); | ||
98 | } | ||
99 | |||
100 | /** | ||
101 | -- | ||
102 | 2.9.4 | ||
103 | |||
104 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | ||
2 | 1 | ||
3 | While the qemu-img dd command does accept --image-opts | ||
4 | this is not sufficient to make it work with the LUKS | ||
5 | image yet. This is because bdrv_create() still always | ||
6 | requires the non-image-opts syntax. | ||
7 | |||
8 | Thus we must skip 159/170 with luks for now | ||
9 | |||
10 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
11 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
12 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
13 | Message-id: 20170626123510.20134-2-berrange@redhat.com | ||
14 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
15 | --- | ||
16 | tests/qemu-iotests/159 | 1 + | ||
17 | tests/qemu-iotests/170 | 1 + | ||
18 | 2 files changed, 2 insertions(+) | ||
19 | |||
20 | diff --git a/tests/qemu-iotests/159 b/tests/qemu-iotests/159 | ||
21 | index XXXXXXX..XXXXXXX 100755 | ||
22 | --- a/tests/qemu-iotests/159 | ||
23 | +++ b/tests/qemu-iotests/159 | ||
24 | @@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15 | ||
25 | _supported_fmt generic | ||
26 | _supported_proto file | ||
27 | _supported_os Linux | ||
28 | +_unsupported_fmt luks | ||
29 | |||
30 | TEST_SIZES="5 512 1024 1999 1K 64K 1M" | ||
31 | |||
32 | diff --git a/tests/qemu-iotests/170 b/tests/qemu-iotests/170 | ||
33 | index XXXXXXX..XXXXXXX 100755 | ||
34 | --- a/tests/qemu-iotests/170 | ||
35 | +++ b/tests/qemu-iotests/170 | ||
36 | @@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15 | ||
37 | _supported_fmt generic | ||
38 | _supported_proto file | ||
39 | _supported_os Linux | ||
40 | +_unsupported_fmt luks | ||
41 | |||
42 | echo | ||
43 | echo "== Creating image ==" | ||
44 | -- | ||
45 | 2.9.4 | ||
46 | |||
47 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | ||
2 | 1 | ||
3 | The tests 033, 140, 145 and 157 were all broken | ||
4 | when run with LUKS, since they did not correctly use | ||
5 | the required image opts args syntax to specify the | ||
6 | decryption secret. Further, the 120 test simply does | ||
7 | not make sense to run with luks, as the scenario | ||
8 | exercised is not relevant. | ||
9 | |||
10 | The test 181 was broken when run with LUKS because | ||
11 | it didn't take account of fact that $TEST_IMG was | ||
12 | already in image opts syntax. The launch_qemu | ||
13 | helper also didn't register the secret object | ||
14 | providing the LUKS password. | ||
15 | |||
16 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
17 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
18 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
19 | Message-id: 20170626123510.20134-3-berrange@redhat.com | ||
20 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
21 | --- | ||
22 | tests/qemu-iotests/033 | 12 ++++++++++-- | ||
23 | tests/qemu-iotests/120 | 1 + | ||
24 | tests/qemu-iotests/140 | 9 ++++++++- | ||
25 | tests/qemu-iotests/145 | 19 +++++++++++++++++-- | ||
26 | tests/qemu-iotests/157 | 17 ++++++++++++++--- | ||
27 | tests/qemu-iotests/157.out | 16 ++++++++-------- | ||
28 | tests/qemu-iotests/174 | 2 +- | ||
29 | tests/qemu-iotests/181 | 21 ++++++++++++++++----- | ||
30 | tests/qemu-iotests/common.qemu | 9 +++++++-- | ||
31 | 9 files changed, 82 insertions(+), 24 deletions(-) | ||
32 | |||
33 | diff --git a/tests/qemu-iotests/033 b/tests/qemu-iotests/033 | ||
34 | index XXXXXXX..XXXXXXX 100755 | ||
35 | --- a/tests/qemu-iotests/033 | ||
36 | +++ b/tests/qemu-iotests/033 | ||
37 | @@ -XXX,XX +XXX,XX @@ do_test() | ||
38 | local align=$1 | ||
39 | local iocmd=$2 | ||
40 | local img=$3 | ||
41 | + if [ "$IMGOPTSSYNTAX" = "true" ] | ||
42 | + then | ||
43 | + IO_OPEN_ARG="$img" | ||
44 | + IO_EXTRA_ARGS="--image-opts" | ||
45 | + else | ||
46 | + IO_OPEN_ARG="-o driver=$IMGFMT,file.align=$align blkdebug::$img" | ||
47 | + IO_EXTRA_ARGS="" | ||
48 | + fi | ||
49 | { | ||
50 | - echo "open -o driver=$IMGFMT,file.align=$align blkdebug::$img" | ||
51 | + echo "open $IO_OPEN_ARG" | ||
52 | echo $iocmd | ||
53 | - } | $QEMU_IO | ||
54 | + } | $QEMU_IO $IO_EXTRA_ARGS | ||
55 | } | ||
56 | |||
57 | for write_zero_cmd in "write -z" "aio_write -z"; do | ||
58 | diff --git a/tests/qemu-iotests/120 b/tests/qemu-iotests/120 | ||
59 | index XXXXXXX..XXXXXXX 100755 | ||
60 | --- a/tests/qemu-iotests/120 | ||
61 | +++ b/tests/qemu-iotests/120 | ||
62 | @@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15 | ||
63 | _supported_fmt generic | ||
64 | _supported_proto file | ||
65 | _supported_os Linux | ||
66 | +_unsupported_fmt luks | ||
67 | |||
68 | _make_test_img 64M | ||
69 | |||
70 | diff --git a/tests/qemu-iotests/140 b/tests/qemu-iotests/140 | ||
71 | index XXXXXXX..XXXXXXX 100755 | ||
72 | --- a/tests/qemu-iotests/140 | ||
73 | +++ b/tests/qemu-iotests/140 | ||
74 | @@ -XXX,XX +XXX,XX @@ _make_test_img 64k | ||
75 | |||
76 | $QEMU_IO -c 'write -P 42 0 64k' "$TEST_IMG" | _filter_qemu_io | ||
77 | |||
78 | +if test "$IMGOPTSSYNTAX" = "true" | ||
79 | +then | ||
80 | + SYSEMU_DRIVE_ARG=if=none,media=cdrom,id=drv,"$TEST_IMG" | ||
81 | +else | ||
82 | + SYSEMU_DRIVE_ARG=if=none,media=cdrom,id=drv,file="$TEST_IMG",driver=$IMGFMT | ||
83 | +fi | ||
84 | + | ||
85 | keep_stderr=y \ | ||
86 | -_launch_qemu -drive if=none,media=cdrom,id=drv,file="$TEST_IMG",format=$IMGFMT \ | ||
87 | +_launch_qemu -drive $SYSEMU_DRIVE_ARG \ | ||
88 | 2> >(_filter_nbd) | ||
89 | |||
90 | _send_qemu_cmd $QEMU_HANDLE \ | ||
91 | diff --git a/tests/qemu-iotests/145 b/tests/qemu-iotests/145 | ||
92 | index XXXXXXX..XXXXXXX 100755 | ||
93 | --- a/tests/qemu-iotests/145 | ||
94 | +++ b/tests/qemu-iotests/145 | ||
95 | @@ -XXX,XX +XXX,XX @@ _supported_proto generic | ||
96 | _supported_os Linux | ||
97 | |||
98 | _make_test_img 1M | ||
99 | -echo quit | $QEMU -nographic -hda "$TEST_IMG" -incoming 'exec:true' -snapshot -serial none -monitor stdio | | ||
100 | - _filter_qemu | _filter_hmp | ||
101 | + | ||
102 | +if test "$IMGOPTSSYNTAX" = "true" | ||
103 | +then | ||
104 | + SYSEMU_DRIVE_ARG=if=none,$TEST_IMG | ||
105 | + SYSEMU_EXTRA_ARGS="" | ||
106 | + if [ -n "$IMGKEYSECRET" ]; then | ||
107 | + SECRET_ARG="secret,id=keysec0,data=$IMGKEYSECRET" | ||
108 | + SYSEMU_EXTRA_ARGS="-object $SECRET_ARG" | ||
109 | + fi | ||
110 | +else | ||
111 | + SYSEMU_DRIVE_ARG=if=none,file="$TEST_IMG",driver=$IMGFMT | ||
112 | + SYSEMU_EXTRA_ARGS="" | ||
113 | +fi | ||
114 | + | ||
115 | +echo quit | $QEMU -nographic $SYSEMU_EXTRA_ARGS -drive $SYSEMU_DRIVE_ARG \ | ||
116 | + -incoming 'exec:true' -snapshot -serial none -monitor stdio \ | ||
117 | + | _filter_qemu | _filter_hmp | ||
118 | |||
119 | # success, all done | ||
120 | echo "*** done" | ||
121 | diff --git a/tests/qemu-iotests/157 b/tests/qemu-iotests/157 | ||
122 | index XXXXXXX..XXXXXXX 100755 | ||
123 | --- a/tests/qemu-iotests/157 | ||
124 | +++ b/tests/qemu-iotests/157 | ||
125 | @@ -XXX,XX +XXX,XX @@ _supported_os Linux | ||
126 | |||
127 | function do_run_qemu() | ||
128 | { | ||
129 | - echo Testing: "$@" | ||
130 | ( | ||
131 | if ! test -t 0; then | ||
132 | while read cmd; do | ||
133 | @@ -XXX,XX +XXX,XX @@ function run_qemu() | ||
134 | |||
135 | |||
136 | size=128M | ||
137 | -drive="if=none,file=$TEST_IMG,driver=$IMGFMT" | ||
138 | +if test "$IMGOPTSSYNTAX" = "true" | ||
139 | +then | ||
140 | + SYSEMU_DRIVE_ARG=if=none,$TEST_IMG | ||
141 | + SYSEMU_EXTRA_ARGS="" | ||
142 | + if [ -n "$IMGKEYSECRET" ]; then | ||
143 | + SECRET_ARG="secret,id=keysec0,data=$IMGKEYSECRET" | ||
144 | + SYSEMU_EXTRA_ARGS="-object $SECRET_ARG" | ||
145 | + fi | ||
146 | +else | ||
147 | + SYSEMU_DRIVE_ARG=if=none,file="$TEST_IMG",driver=$IMGFMT | ||
148 | + SYSEMU_EXTRA_ARGS="" | ||
149 | +fi | ||
150 | |||
151 | _make_test_img $size | ||
152 | |||
153 | @@ -XXX,XX +XXX,XX @@ echo | ||
154 | |||
155 | for cache in "writeback" "writethrough"; do | ||
156 | for wce in "" ",write-cache=auto" ",write-cache=on" ",write-cache=off"; do | ||
157 | + echo "Testing: cache='$cache' wce='$wce'" | ||
158 | echo "info block" \ | ||
159 | - | run_qemu -drive "$drive,cache=$cache" \ | ||
160 | + | run_qemu $SYSEMU_EXTRA_ARGS -drive "$SYSEMU_DRIVE_ARG,cache=$cache" \ | ||
161 | -device "virtio-blk,drive=none0$wce" \ | ||
162 | | grep -e "Testing" -e "Cache mode" | ||
163 | done | ||
164 | diff --git a/tests/qemu-iotests/157.out b/tests/qemu-iotests/157.out | ||
165 | index XXXXXXX..XXXXXXX 100644 | ||
166 | --- a/tests/qemu-iotests/157.out | ||
167 | +++ b/tests/qemu-iotests/157.out | ||
168 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 | ||
169 | |||
170 | === Setting WCE with qdev and with manually created BB === | ||
171 | |||
172 | -Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,driver=IMGFMT,cache=writeback -device virtio-blk,drive=none0 | ||
173 | +Testing: cache='writeback' wce='' | ||
174 | Cache mode: writeback | ||
175 | -Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,driver=IMGFMT,cache=writeback -device virtio-blk,drive=none0,write-cache=auto | ||
176 | +Testing: cache='writeback' wce=',write-cache=auto' | ||
177 | Cache mode: writeback | ||
178 | -Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,driver=IMGFMT,cache=writeback -device virtio-blk,drive=none0,write-cache=on | ||
179 | +Testing: cache='writeback' wce=',write-cache=on' | ||
180 | Cache mode: writeback | ||
181 | -Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,driver=IMGFMT,cache=writeback -device virtio-blk,drive=none0,write-cache=off | ||
182 | +Testing: cache='writeback' wce=',write-cache=off' | ||
183 | Cache mode: writethrough | ||
184 | -Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,driver=IMGFMT,cache=writethrough -device virtio-blk,drive=none0 | ||
185 | +Testing: cache='writethrough' wce='' | ||
186 | Cache mode: writethrough | ||
187 | -Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,driver=IMGFMT,cache=writethrough -device virtio-blk,drive=none0,write-cache=auto | ||
188 | +Testing: cache='writethrough' wce=',write-cache=auto' | ||
189 | Cache mode: writethrough | ||
190 | -Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,driver=IMGFMT,cache=writethrough -device virtio-blk,drive=none0,write-cache=on | ||
191 | +Testing: cache='writethrough' wce=',write-cache=on' | ||
192 | Cache mode: writeback | ||
193 | -Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,driver=IMGFMT,cache=writethrough -device virtio-blk,drive=none0,write-cache=off | ||
194 | +Testing: cache='writethrough' wce=',write-cache=off' | ||
195 | Cache mode: writethrough | ||
196 | *** done | ||
197 | diff --git a/tests/qemu-iotests/174 b/tests/qemu-iotests/174 | ||
198 | index XXXXXXX..XXXXXXX 100755 | ||
199 | --- a/tests/qemu-iotests/174 | ||
200 | +++ b/tests/qemu-iotests/174 | ||
201 | @@ -XXX,XX +XXX,XX @@ _unsupported_fmt raw | ||
202 | |||
203 | |||
204 | size=256K | ||
205 | -IMGFMT=raw IMGOPTS= _make_test_img $size | _filter_imgfmt | ||
206 | +IMGFMT=raw IMGKEYSECRET= IMGOPTS= _make_test_img $size | _filter_imgfmt | ||
207 | |||
208 | echo | ||
209 | echo "== reading wrong format should fail ==" | ||
210 | diff --git a/tests/qemu-iotests/181 b/tests/qemu-iotests/181 | ||
211 | index XXXXXXX..XXXXXXX 100755 | ||
212 | --- a/tests/qemu-iotests/181 | ||
213 | +++ b/tests/qemu-iotests/181 | ||
214 | @@ -XXX,XX +XXX,XX @@ echo | ||
215 | |||
216 | qemu_comm_method="monitor" | ||
217 | |||
218 | -_launch_qemu \ | ||
219 | - -drive file="${TEST_IMG}",cache=${CACHEMODE},driver=$IMGFMT,id=disk | ||
220 | +if [ "$IMGOPTSSYNTAX" = "true" ]; then | ||
221 | + _launch_qemu \ | ||
222 | + -drive "${TEST_IMG}",cache=${CACHEMODE},id=disk | ||
223 | +else | ||
224 | + _launch_qemu \ | ||
225 | + -drive file="${TEST_IMG}",cache=${CACHEMODE},driver=$IMGFMT,id=disk | ||
226 | +fi | ||
227 | src=$QEMU_HANDLE | ||
228 | |||
229 | -_launch_qemu \ | ||
230 | - -drive file="${TEST_IMG}",cache=${CACHEMODE},driver=$IMGFMT,id=disk \ | ||
231 | - -incoming "unix:${MIG_SOCKET}" | ||
232 | +if [ "$IMGOPTSSYNTAX" = "true" ]; then | ||
233 | + _launch_qemu \ | ||
234 | + -drive "${TEST_IMG}",cache=${CACHEMODE},id=disk \ | ||
235 | + -incoming "unix:${MIG_SOCKET}" | ||
236 | +else | ||
237 | + _launch_qemu \ | ||
238 | + -drive file="${TEST_IMG}",cache=${CACHEMODE},driver=$IMGFMT,id=disk \ | ||
239 | + -incoming "unix:${MIG_SOCKET}" | ||
240 | +fi | ||
241 | dest=$QEMU_HANDLE | ||
242 | |||
243 | echo | ||
244 | diff --git a/tests/qemu-iotests/common.qemu b/tests/qemu-iotests/common.qemu | ||
245 | index XXXXXXX..XXXXXXX 100644 | ||
246 | --- a/tests/qemu-iotests/common.qemu | ||
247 | +++ b/tests/qemu-iotests/common.qemu | ||
248 | @@ -XXX,XX +XXX,XX @@ function _launch_qemu() | ||
249 | mkfifo "${fifo_out}" | ||
250 | mkfifo "${fifo_in}" | ||
251 | |||
252 | + object_options= | ||
253 | + if [ -n "$IMGKEYSECRET" ]; then | ||
254 | + object_options="--object secret,id=keysec0,data=$IMGKEYSECRET" | ||
255 | + fi | ||
256 | + | ||
257 | if [ -z "$keep_stderr" ]; then | ||
258 | QEMU_NEED_PID='y'\ | ||
259 | - ${QEMU} -nographic -serial none ${comm} "${@}" >"${fifo_out}" \ | ||
260 | + ${QEMU} ${object_options} -nographic -serial none ${comm} "${@}" >"${fifo_out}" \ | ||
261 | 2>&1 \ | ||
262 | <"${fifo_in}" & | ||
263 | elif [ "$keep_stderr" = "y" ]; then | ||
264 | QEMU_NEED_PID='y'\ | ||
265 | - ${QEMU} -nographic -serial none ${comm} "${@}" >"${fifo_out}" \ | ||
266 | + ${QEMU} ${object_options} -nographic -serial none ${comm} "${@}" >"${fifo_out}" \ | ||
267 | <"${fifo_in}" & | ||
268 | else | ||
269 | exit 1 | ||
270 | -- | ||
271 | 2.9.4 | ||
272 | |||
273 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | ||
2 | 1 | ||
3 | By default the PBKDF algorithm used with LUKS is tuned | ||
4 | based on the number of iterations to produce 1 second | ||
5 | of running time. This makes running the I/O test with | ||
6 | the LUKS format orders of magnitude slower than with | ||
7 | qcow2/raw formats. | ||
8 | |||
9 | When creating LUKS images, set the iteration time to | ||
10 | a 10ms to reduce the time overhead for LUKS, since | ||
11 | security does not matter in I/O tests. | ||
12 | |||
13 | Previously a full 'check -luks' would take | ||
14 | |||
15 | $ time ./check -luks | ||
16 | Passed all 22 tests | ||
17 | |||
18 | real 23m9.988s | ||
19 | user 21m46.223s | ||
20 | sys 0m22.841s | ||
21 | |||
22 | Now it takes | ||
23 | |||
24 | $ time ./check -luks | ||
25 | Passed all 22 tests | ||
26 | |||
27 | real 4m39.235s | ||
28 | user 3m29.590s | ||
29 | sys 0m24.234s | ||
30 | |||
31 | Still slow compared to qcow2/raw, but much improved | ||
32 | none the less. | ||
33 | |||
34 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
35 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
36 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
37 | Message-id: 20170626123510.20134-4-berrange@redhat.com | ||
38 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
39 | --- | ||
40 | tests/qemu-iotests/149 | 3 + | ||
41 | tests/qemu-iotests/149.out | 118 +++++++++++++++++++-------------------- | ||
42 | tests/qemu-iotests/common.filter | 3 +- | ||
43 | tests/qemu-iotests/common.rc | 3 + | ||
44 | 4 files changed, 67 insertions(+), 60 deletions(-) | ||
45 | |||
46 | diff --git a/tests/qemu-iotests/149 b/tests/qemu-iotests/149 | ||
47 | index XXXXXXX..XXXXXXX 100755 | ||
48 | --- a/tests/qemu-iotests/149 | ||
49 | +++ b/tests/qemu-iotests/149 | ||
50 | @@ -XXX,XX +XXX,XX @@ def cryptsetup_add_password(config, slot): | ||
51 | args = ["luksAddKey", config.image_path(), | ||
52 | "--key-slot", slot, | ||
53 | "--key-file", "-", | ||
54 | + "--iter-time", "10", | ||
55 | pwfile] | ||
56 | |||
57 | cryptsetup(args, password) | ||
58 | @@ -XXX,XX +XXX,XX @@ def cryptsetup_format(config): | ||
59 | args.extend(["--hash", config.hash]) | ||
60 | args.extend(["--key-slot", slot]) | ||
61 | args.extend(["--key-file", "-"]) | ||
62 | + args.extend(["--iter-time", "10"]) | ||
63 | args.append(config.image_path()) | ||
64 | |||
65 | cryptsetup(args, password) | ||
66 | @@ -XXX,XX +XXX,XX @@ def qemu_img_create(config, size_mb): | ||
67 | |||
68 | opts = [ | ||
69 | "key-secret=sec0", | ||
70 | + "iter-time=10", | ||
71 | "cipher-alg=%s-%d" % (config.cipher, config.keylen), | ||
72 | "cipher-mode=%s" % config.mode, | ||
73 | "ivgen-alg=%s" % config.ivgen, | ||
74 | diff --git a/tests/qemu-iotests/149.out b/tests/qemu-iotests/149.out | ||
75 | index XXXXXXX..XXXXXXX 100644 | ||
76 | --- a/tests/qemu-iotests/149.out | ||
77 | +++ b/tests/qemu-iotests/149.out | ||
78 | @@ -XXX,XX +XXX,XX @@ | ||
79 | # Create image | ||
80 | truncate TEST_DIR/luks-aes-256-xts-plain64-sha1.img --size 4194304MB | ||
81 | # Format image | ||
82 | -sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain64 --key-size 512 --hash sha1 --key-slot 0 --key-file - TEST_DIR/luks-aes-256-xts-plain64-sha1.img | ||
83 | +sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain64 --key-size 512 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain64-sha1.img | ||
84 | # Open dev | ||
85 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha1.img qiotest-145-aes-256-xts-plain64-sha1 | ||
86 | # Set dev owner | ||
87 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-xts-plain64-sha1.img | ||
88 | |||
89 | # ================= qemu-img aes-256-xts-plain64-sha1 ================= | ||
90 | # Create image | ||
91 | -qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,cipher-alg=aes-256,cipher-mode=xts,ivgen-alg=plain64,hash-alg=sha1 TEST_DIR/luks-aes-256-xts-plain64-sha1.img 4194304M | ||
92 | -Formatting 'TEST_DIR/luks-aes-256-xts-plain64-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=aes-256 cipher-mode=xts ivgen-alg=plain64 hash-alg=sha1 | ||
93 | +qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,iter-time=10,cipher-alg=aes-256,cipher-mode=xts,ivgen-alg=plain64,hash-alg=sha1 TEST_DIR/luks-aes-256-xts-plain64-sha1.img 4194304M | ||
94 | +Formatting 'TEST_DIR/luks-aes-256-xts-plain64-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=aes-256 cipher-mode=xts ivgen-alg=plain64 hash-alg=sha1 iter-time=10 | ||
95 | |||
96 | # Open dev | ||
97 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha1.img qiotest-145-aes-256-xts-plain64-sha1 | ||
98 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-xts-plain64-sha1.img | ||
99 | # Create image | ||
100 | truncate TEST_DIR/luks-twofish-256-xts-plain64-sha1.img --size 4194304MB | ||
101 | # Format image | ||
102 | -sudo cryptsetup -q -v luksFormat --cipher twofish-xts-plain64 --key-size 512 --hash sha1 --key-slot 0 --key-file - TEST_DIR/luks-twofish-256-xts-plain64-sha1.img | ||
103 | +sudo cryptsetup -q -v luksFormat --cipher twofish-xts-plain64 --key-size 512 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-twofish-256-xts-plain64-sha1.img | ||
104 | # Open dev | ||
105 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-twofish-256-xts-plain64-sha1.img qiotest-145-twofish-256-xts-plain64-sha1 | ||
106 | # Set dev owner | ||
107 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-twofish-256-xts-plain64-sha1.img | ||
108 | |||
109 | # ================= qemu-img twofish-256-xts-plain64-sha1 ================= | ||
110 | # Create image | ||
111 | -qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,cipher-alg=twofish-256,cipher-mode=xts,ivgen-alg=plain64,hash-alg=sha1 TEST_DIR/luks-twofish-256-xts-plain64-sha1.img 4194304M | ||
112 | -Formatting 'TEST_DIR/luks-twofish-256-xts-plain64-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=twofish-256 cipher-mode=xts ivgen-alg=plain64 hash-alg=sha1 | ||
113 | +qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,iter-time=10,cipher-alg=twofish-256,cipher-mode=xts,ivgen-alg=plain64,hash-alg=sha1 TEST_DIR/luks-twofish-256-xts-plain64-sha1.img 4194304M | ||
114 | +Formatting 'TEST_DIR/luks-twofish-256-xts-plain64-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=twofish-256 cipher-mode=xts ivgen-alg=plain64 hash-alg=sha1 iter-time=10 | ||
115 | |||
116 | # Open dev | ||
117 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-twofish-256-xts-plain64-sha1.img qiotest-145-twofish-256-xts-plain64-sha1 | ||
118 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-twofish-256-xts-plain64-sha1.img | ||
119 | # Create image | ||
120 | truncate TEST_DIR/luks-serpent-256-xts-plain64-sha1.img --size 4194304MB | ||
121 | # Format image | ||
122 | -sudo cryptsetup -q -v luksFormat --cipher serpent-xts-plain64 --key-size 512 --hash sha1 --key-slot 0 --key-file - TEST_DIR/luks-serpent-256-xts-plain64-sha1.img | ||
123 | +sudo cryptsetup -q -v luksFormat --cipher serpent-xts-plain64 --key-size 512 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-serpent-256-xts-plain64-sha1.img | ||
124 | # Open dev | ||
125 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-serpent-256-xts-plain64-sha1.img qiotest-145-serpent-256-xts-plain64-sha1 | ||
126 | # Set dev owner | ||
127 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-serpent-256-xts-plain64-sha1.img | ||
128 | |||
129 | # ================= qemu-img serpent-256-xts-plain64-sha1 ================= | ||
130 | # Create image | ||
131 | -qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,cipher-alg=serpent-256,cipher-mode=xts,ivgen-alg=plain64,hash-alg=sha1 TEST_DIR/luks-serpent-256-xts-plain64-sha1.img 4194304M | ||
132 | -Formatting 'TEST_DIR/luks-serpent-256-xts-plain64-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=serpent-256 cipher-mode=xts ivgen-alg=plain64 hash-alg=sha1 | ||
133 | +qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,iter-time=10,cipher-alg=serpent-256,cipher-mode=xts,ivgen-alg=plain64,hash-alg=sha1 TEST_DIR/luks-serpent-256-xts-plain64-sha1.img 4194304M | ||
134 | +Formatting 'TEST_DIR/luks-serpent-256-xts-plain64-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=serpent-256 cipher-mode=xts ivgen-alg=plain64 hash-alg=sha1 iter-time=10 | ||
135 | |||
136 | # Open dev | ||
137 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-serpent-256-xts-plain64-sha1.img qiotest-145-serpent-256-xts-plain64-sha1 | ||
138 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-serpent-256-xts-plain64-sha1.img | ||
139 | # Create image | ||
140 | truncate TEST_DIR/luks-cast5-128-cbc-plain64-sha1.img --size 4194304MB | ||
141 | # Format image | ||
142 | -sudo cryptsetup -q -v luksFormat --cipher cast5-cbc-plain64 --key-size 128 --hash sha1 --key-slot 0 --key-file - TEST_DIR/luks-cast5-128-cbc-plain64-sha1.img | ||
143 | +sudo cryptsetup -q -v luksFormat --cipher cast5-cbc-plain64 --key-size 128 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-cast5-128-cbc-plain64-sha1.img | ||
144 | # Open dev | ||
145 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-cast5-128-cbc-plain64-sha1.img qiotest-145-cast5-128-cbc-plain64-sha1 | ||
146 | # Set dev owner | ||
147 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-cast5-128-cbc-plain64-sha1.img | ||
148 | |||
149 | # ================= qemu-img cast5-128-cbc-plain64-sha1 ================= | ||
150 | # Create image | ||
151 | -qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,cipher-alg=cast5-128,cipher-mode=cbc,ivgen-alg=plain64,hash-alg=sha1 TEST_DIR/luks-cast5-128-cbc-plain64-sha1.img 4194304M | ||
152 | -Formatting 'TEST_DIR/luks-cast5-128-cbc-plain64-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=cast5-128 cipher-mode=cbc ivgen-alg=plain64 hash-alg=sha1 | ||
153 | +qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,iter-time=10,cipher-alg=cast5-128,cipher-mode=cbc,ivgen-alg=plain64,hash-alg=sha1 TEST_DIR/luks-cast5-128-cbc-plain64-sha1.img 4194304M | ||
154 | +Formatting 'TEST_DIR/luks-cast5-128-cbc-plain64-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=cast5-128 cipher-mode=cbc ivgen-alg=plain64 hash-alg=sha1 iter-time=10 | ||
155 | |||
156 | # Open dev | ||
157 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-cast5-128-cbc-plain64-sha1.img qiotest-145-cast5-128-cbc-plain64-sha1 | ||
158 | @@ -XXX,XX +XXX,XX @@ Skipping cast6-256-xts-plain64-sha1 in blacklist | ||
159 | # Create image | ||
160 | truncate TEST_DIR/luks-aes-256-cbc-plain-sha1.img --size 4194304MB | ||
161 | # Format image | ||
162 | -sudo cryptsetup -q -v luksFormat --cipher aes-cbc-plain --key-size 256 --hash sha1 --key-slot 0 --key-file - TEST_DIR/luks-aes-256-cbc-plain-sha1.img | ||
163 | +sudo cryptsetup -q -v luksFormat --cipher aes-cbc-plain --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-cbc-plain-sha1.img | ||
164 | # Open dev | ||
165 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-plain-sha1.img qiotest-145-aes-256-cbc-plain-sha1 | ||
166 | # Set dev owner | ||
167 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-cbc-plain-sha1.img | ||
168 | |||
169 | # ================= qemu-img aes-256-cbc-plain-sha1 ================= | ||
170 | # Create image | ||
171 | -qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,cipher-alg=aes-256,cipher-mode=cbc,ivgen-alg=plain,hash-alg=sha1 TEST_DIR/luks-aes-256-cbc-plain-sha1.img 4194304M | ||
172 | -Formatting 'TEST_DIR/luks-aes-256-cbc-plain-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=aes-256 cipher-mode=cbc ivgen-alg=plain hash-alg=sha1 | ||
173 | +qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,iter-time=10,cipher-alg=aes-256,cipher-mode=cbc,ivgen-alg=plain,hash-alg=sha1 TEST_DIR/luks-aes-256-cbc-plain-sha1.img 4194304M | ||
174 | +Formatting 'TEST_DIR/luks-aes-256-cbc-plain-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=aes-256 cipher-mode=cbc ivgen-alg=plain hash-alg=sha1 iter-time=10 | ||
175 | |||
176 | # Open dev | ||
177 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-plain-sha1.img qiotest-145-aes-256-cbc-plain-sha1 | ||
178 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-cbc-plain-sha1.img | ||
179 | # Create image | ||
180 | truncate TEST_DIR/luks-aes-256-cbc-plain64-sha1.img --size 4194304MB | ||
181 | # Format image | ||
182 | -sudo cryptsetup -q -v luksFormat --cipher aes-cbc-plain64 --key-size 256 --hash sha1 --key-slot 0 --key-file - TEST_DIR/luks-aes-256-cbc-plain64-sha1.img | ||
183 | +sudo cryptsetup -q -v luksFormat --cipher aes-cbc-plain64 --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-cbc-plain64-sha1.img | ||
184 | # Open dev | ||
185 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-plain64-sha1.img qiotest-145-aes-256-cbc-plain64-sha1 | ||
186 | # Set dev owner | ||
187 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-cbc-plain64-sha1.img | ||
188 | |||
189 | # ================= qemu-img aes-256-cbc-plain64-sha1 ================= | ||
190 | # Create image | ||
191 | -qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,cipher-alg=aes-256,cipher-mode=cbc,ivgen-alg=plain64,hash-alg=sha1 TEST_DIR/luks-aes-256-cbc-plain64-sha1.img 4194304M | ||
192 | -Formatting 'TEST_DIR/luks-aes-256-cbc-plain64-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=aes-256 cipher-mode=cbc ivgen-alg=plain64 hash-alg=sha1 | ||
193 | +qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,iter-time=10,cipher-alg=aes-256,cipher-mode=cbc,ivgen-alg=plain64,hash-alg=sha1 TEST_DIR/luks-aes-256-cbc-plain64-sha1.img 4194304M | ||
194 | +Formatting 'TEST_DIR/luks-aes-256-cbc-plain64-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=aes-256 cipher-mode=cbc ivgen-alg=plain64 hash-alg=sha1 iter-time=10 | ||
195 | |||
196 | # Open dev | ||
197 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-plain64-sha1.img qiotest-145-aes-256-cbc-plain64-sha1 | ||
198 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-cbc-plain64-sha1.img | ||
199 | # Create image | ||
200 | truncate TEST_DIR/luks-aes-256-cbc-essiv-sha256-sha1.img --size 4194304MB | ||
201 | # Format image | ||
202 | -sudo cryptsetup -q -v luksFormat --cipher aes-cbc-essiv:sha256 --key-size 256 --hash sha1 --key-slot 0 --key-file - TEST_DIR/luks-aes-256-cbc-essiv-sha256-sha1.img | ||
203 | +sudo cryptsetup -q -v luksFormat --cipher aes-cbc-essiv:sha256 --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-cbc-essiv-sha256-sha1.img | ||
204 | # Open dev | ||
205 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-essiv-sha256-sha1.img qiotest-145-aes-256-cbc-essiv-sha256-sha1 | ||
206 | # Set dev owner | ||
207 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-cbc-essiv-sha256-sha1.img | ||
208 | |||
209 | # ================= qemu-img aes-256-cbc-essiv-sha256-sha1 ================= | ||
210 | # Create image | ||
211 | -qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,cipher-alg=aes-256,cipher-mode=cbc,ivgen-alg=essiv,hash-alg=sha1,ivgen-hash-alg=sha256 TEST_DIR/luks-aes-256-cbc-essiv-sha256-sha1.img 4194304M | ||
212 | -Formatting 'TEST_DIR/luks-aes-256-cbc-essiv-sha256-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=aes-256 cipher-mode=cbc ivgen-alg=essiv ivgen-hash-alg=sha256 hash-alg=sha1 | ||
213 | +qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,iter-time=10,cipher-alg=aes-256,cipher-mode=cbc,ivgen-alg=essiv,hash-alg=sha1,ivgen-hash-alg=sha256 TEST_DIR/luks-aes-256-cbc-essiv-sha256-sha1.img 4194304M | ||
214 | +Formatting 'TEST_DIR/luks-aes-256-cbc-essiv-sha256-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=aes-256 cipher-mode=cbc ivgen-alg=essiv ivgen-hash-alg=sha256 hash-alg=sha1 iter-time=10 | ||
215 | |||
216 | # Open dev | ||
217 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-essiv-sha256-sha1.img qiotest-145-aes-256-cbc-essiv-sha256-sha1 | ||
218 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-cbc-essiv-sha256-sha1.img | ||
219 | # Create image | ||
220 | truncate TEST_DIR/luks-aes-256-xts-essiv-sha256-sha1.img --size 4194304MB | ||
221 | # Format image | ||
222 | -sudo cryptsetup -q -v luksFormat --cipher aes-xts-essiv:sha256 --key-size 512 --hash sha1 --key-slot 0 --key-file - TEST_DIR/luks-aes-256-xts-essiv-sha256-sha1.img | ||
223 | +sudo cryptsetup -q -v luksFormat --cipher aes-xts-essiv:sha256 --key-size 512 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-essiv-sha256-sha1.img | ||
224 | # Open dev | ||
225 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-essiv-sha256-sha1.img qiotest-145-aes-256-xts-essiv-sha256-sha1 | ||
226 | # Set dev owner | ||
227 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-xts-essiv-sha256-sha1.img | ||
228 | |||
229 | # ================= qemu-img aes-256-xts-essiv-sha256-sha1 ================= | ||
230 | # Create image | ||
231 | -qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,cipher-alg=aes-256,cipher-mode=xts,ivgen-alg=essiv,hash-alg=sha1,ivgen-hash-alg=sha256 TEST_DIR/luks-aes-256-xts-essiv-sha256-sha1.img 4194304M | ||
232 | -Formatting 'TEST_DIR/luks-aes-256-xts-essiv-sha256-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=aes-256 cipher-mode=xts ivgen-alg=essiv ivgen-hash-alg=sha256 hash-alg=sha1 | ||
233 | +qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,iter-time=10,cipher-alg=aes-256,cipher-mode=xts,ivgen-alg=essiv,hash-alg=sha1,ivgen-hash-alg=sha256 TEST_DIR/luks-aes-256-xts-essiv-sha256-sha1.img 4194304M | ||
234 | +Formatting 'TEST_DIR/luks-aes-256-xts-essiv-sha256-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=aes-256 cipher-mode=xts ivgen-alg=essiv ivgen-hash-alg=sha256 hash-alg=sha1 iter-time=10 | ||
235 | |||
236 | # Open dev | ||
237 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-essiv-sha256-sha1.img qiotest-145-aes-256-xts-essiv-sha256-sha1 | ||
238 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-xts-essiv-sha256-sha1.img | ||
239 | # Create image | ||
240 | truncate TEST_DIR/luks-aes-128-xts-plain64-sha256-sha1.img --size 4194304MB | ||
241 | # Format image | ||
242 | -sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain64 --key-size 256 --hash sha1 --key-slot 0 --key-file - TEST_DIR/luks-aes-128-xts-plain64-sha256-sha1.img | ||
243 | +sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain64 --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-128-xts-plain64-sha256-sha1.img | ||
244 | # Open dev | ||
245 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-128-xts-plain64-sha256-sha1.img qiotest-145-aes-128-xts-plain64-sha256-sha1 | ||
246 | # Set dev owner | ||
247 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-128-xts-plain64-sha256-sha1.img | ||
248 | |||
249 | # ================= qemu-img aes-128-xts-plain64-sha256-sha1 ================= | ||
250 | # Create image | ||
251 | -qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,cipher-alg=aes-128,cipher-mode=xts,ivgen-alg=plain64,hash-alg=sha1 TEST_DIR/luks-aes-128-xts-plain64-sha256-sha1.img 4194304M | ||
252 | -Formatting 'TEST_DIR/luks-aes-128-xts-plain64-sha256-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=aes-128 cipher-mode=xts ivgen-alg=plain64 hash-alg=sha1 | ||
253 | +qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,iter-time=10,cipher-alg=aes-128,cipher-mode=xts,ivgen-alg=plain64,hash-alg=sha1 TEST_DIR/luks-aes-128-xts-plain64-sha256-sha1.img 4194304M | ||
254 | +Formatting 'TEST_DIR/luks-aes-128-xts-plain64-sha256-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=aes-128 cipher-mode=xts ivgen-alg=plain64 hash-alg=sha1 iter-time=10 | ||
255 | |||
256 | # Open dev | ||
257 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-128-xts-plain64-sha256-sha1.img qiotest-145-aes-128-xts-plain64-sha256-sha1 | ||
258 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-128-xts-plain64-sha256-sha1.img | ||
259 | # Create image | ||
260 | truncate TEST_DIR/luks-aes-192-xts-plain64-sha256-sha1.img --size 4194304MB | ||
261 | # Format image | ||
262 | -sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain64 --key-size 384 --hash sha1 --key-slot 0 --key-file - TEST_DIR/luks-aes-192-xts-plain64-sha256-sha1.img | ||
263 | +sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain64 --key-size 384 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-192-xts-plain64-sha256-sha1.img | ||
264 | # Open dev | ||
265 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-192-xts-plain64-sha256-sha1.img qiotest-145-aes-192-xts-plain64-sha256-sha1 | ||
266 | # Set dev owner | ||
267 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-192-xts-plain64-sha256-sha1.img | ||
268 | |||
269 | # ================= qemu-img aes-192-xts-plain64-sha256-sha1 ================= | ||
270 | # Create image | ||
271 | -qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,cipher-alg=aes-192,cipher-mode=xts,ivgen-alg=plain64,hash-alg=sha1 TEST_DIR/luks-aes-192-xts-plain64-sha256-sha1.img 4194304M | ||
272 | -Formatting 'TEST_DIR/luks-aes-192-xts-plain64-sha256-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=aes-192 cipher-mode=xts ivgen-alg=plain64 hash-alg=sha1 | ||
273 | +qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,iter-time=10,cipher-alg=aes-192,cipher-mode=xts,ivgen-alg=plain64,hash-alg=sha1 TEST_DIR/luks-aes-192-xts-plain64-sha256-sha1.img 4194304M | ||
274 | +Formatting 'TEST_DIR/luks-aes-192-xts-plain64-sha256-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=aes-192 cipher-mode=xts ivgen-alg=plain64 hash-alg=sha1 iter-time=10 | ||
275 | |||
276 | # Open dev | ||
277 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-192-xts-plain64-sha256-sha1.img qiotest-145-aes-192-xts-plain64-sha256-sha1 | ||
278 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-192-xts-plain64-sha256-sha1.img | ||
279 | # Create image | ||
280 | truncate TEST_DIR/luks-twofish-128-xts-plain64-sha1.img --size 4194304MB | ||
281 | # Format image | ||
282 | -sudo cryptsetup -q -v luksFormat --cipher twofish-xts-plain64 --key-size 256 --hash sha1 --key-slot 0 --key-file - TEST_DIR/luks-twofish-128-xts-plain64-sha1.img | ||
283 | +sudo cryptsetup -q -v luksFormat --cipher twofish-xts-plain64 --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-twofish-128-xts-plain64-sha1.img | ||
284 | # Open dev | ||
285 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-twofish-128-xts-plain64-sha1.img qiotest-145-twofish-128-xts-plain64-sha1 | ||
286 | # Set dev owner | ||
287 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-twofish-128-xts-plain64-sha1.img | ||
288 | |||
289 | # ================= qemu-img twofish-128-xts-plain64-sha1 ================= | ||
290 | # Create image | ||
291 | -qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,cipher-alg=twofish-128,cipher-mode=xts,ivgen-alg=plain64,hash-alg=sha1 TEST_DIR/luks-twofish-128-xts-plain64-sha1.img 4194304M | ||
292 | -Formatting 'TEST_DIR/luks-twofish-128-xts-plain64-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=twofish-128 cipher-mode=xts ivgen-alg=plain64 hash-alg=sha1 | ||
293 | +qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,iter-time=10,cipher-alg=twofish-128,cipher-mode=xts,ivgen-alg=plain64,hash-alg=sha1 TEST_DIR/luks-twofish-128-xts-plain64-sha1.img 4194304M | ||
294 | +Formatting 'TEST_DIR/luks-twofish-128-xts-plain64-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=twofish-128 cipher-mode=xts ivgen-alg=plain64 hash-alg=sha1 iter-time=10 | ||
295 | |||
296 | # Open dev | ||
297 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-twofish-128-xts-plain64-sha1.img qiotest-145-twofish-128-xts-plain64-sha1 | ||
298 | @@ -XXX,XX +XXX,XX @@ Skipping twofish-192-xts-plain64-sha1 in blacklist | ||
299 | # Create image | ||
300 | truncate TEST_DIR/luks-serpent-128-xts-plain64-sha1.img --size 4194304MB | ||
301 | # Format image | ||
302 | -sudo cryptsetup -q -v luksFormat --cipher serpent-xts-plain64 --key-size 256 --hash sha1 --key-slot 0 --key-file - TEST_DIR/luks-serpent-128-xts-plain64-sha1.img | ||
303 | +sudo cryptsetup -q -v luksFormat --cipher serpent-xts-plain64 --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-serpent-128-xts-plain64-sha1.img | ||
304 | # Open dev | ||
305 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-serpent-128-xts-plain64-sha1.img qiotest-145-serpent-128-xts-plain64-sha1 | ||
306 | # Set dev owner | ||
307 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-serpent-128-xts-plain64-sha1.img | ||
308 | |||
309 | # ================= qemu-img serpent-128-xts-plain64-sha1 ================= | ||
310 | # Create image | ||
311 | -qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,cipher-alg=serpent-128,cipher-mode=xts,ivgen-alg=plain64,hash-alg=sha1 TEST_DIR/luks-serpent-128-xts-plain64-sha1.img 4194304M | ||
312 | -Formatting 'TEST_DIR/luks-serpent-128-xts-plain64-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=serpent-128 cipher-mode=xts ivgen-alg=plain64 hash-alg=sha1 | ||
313 | +qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,iter-time=10,cipher-alg=serpent-128,cipher-mode=xts,ivgen-alg=plain64,hash-alg=sha1 TEST_DIR/luks-serpent-128-xts-plain64-sha1.img 4194304M | ||
314 | +Formatting 'TEST_DIR/luks-serpent-128-xts-plain64-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=serpent-128 cipher-mode=xts ivgen-alg=plain64 hash-alg=sha1 iter-time=10 | ||
315 | |||
316 | # Open dev | ||
317 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-serpent-128-xts-plain64-sha1.img qiotest-145-serpent-128-xts-plain64-sha1 | ||
318 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-serpent-128-xts-plain64-sha1.img | ||
319 | # Create image | ||
320 | truncate TEST_DIR/luks-serpent-192-xts-plain64-sha1.img --size 4194304MB | ||
321 | # Format image | ||
322 | -sudo cryptsetup -q -v luksFormat --cipher serpent-xts-plain64 --key-size 384 --hash sha1 --key-slot 0 --key-file - TEST_DIR/luks-serpent-192-xts-plain64-sha1.img | ||
323 | +sudo cryptsetup -q -v luksFormat --cipher serpent-xts-plain64 --key-size 384 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-serpent-192-xts-plain64-sha1.img | ||
324 | # Open dev | ||
325 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-serpent-192-xts-plain64-sha1.img qiotest-145-serpent-192-xts-plain64-sha1 | ||
326 | # Set dev owner | ||
327 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-serpent-192-xts-plain64-sha1.img | ||
328 | |||
329 | # ================= qemu-img serpent-192-xts-plain64-sha1 ================= | ||
330 | # Create image | ||
331 | -qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,cipher-alg=serpent-192,cipher-mode=xts,ivgen-alg=plain64,hash-alg=sha1 TEST_DIR/luks-serpent-192-xts-plain64-sha1.img 4194304M | ||
332 | -Formatting 'TEST_DIR/luks-serpent-192-xts-plain64-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=serpent-192 cipher-mode=xts ivgen-alg=plain64 hash-alg=sha1 | ||
333 | +qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,iter-time=10,cipher-alg=serpent-192,cipher-mode=xts,ivgen-alg=plain64,hash-alg=sha1 TEST_DIR/luks-serpent-192-xts-plain64-sha1.img 4194304M | ||
334 | +Formatting 'TEST_DIR/luks-serpent-192-xts-plain64-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=serpent-192 cipher-mode=xts ivgen-alg=plain64 hash-alg=sha1 iter-time=10 | ||
335 | |||
336 | # Open dev | ||
337 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-serpent-192-xts-plain64-sha1.img qiotest-145-serpent-192-xts-plain64-sha1 | ||
338 | @@ -XXX,XX +XXX,XX @@ Skipping cast6-192-xts-plain64-sha1 in blacklist | ||
339 | # Create image | ||
340 | truncate TEST_DIR/luks-aes-256-xts-plain64-sha256.img --size 4194304MB | ||
341 | # Format image | ||
342 | -sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain64 --key-size 512 --hash sha256 --key-slot 0 --key-file - TEST_DIR/luks-aes-256-xts-plain64-sha256.img | ||
343 | +sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain64 --key-size 512 --hash sha256 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain64-sha256.img | ||
344 | # Open dev | ||
345 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha256.img qiotest-145-aes-256-xts-plain64-sha256 | ||
346 | # Set dev owner | ||
347 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-xts-plain64-sha256.img | ||
348 | |||
349 | # ================= qemu-img aes-256-xts-plain64-sha256 ================= | ||
350 | # Create image | ||
351 | -qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,cipher-alg=aes-256,cipher-mode=xts,ivgen-alg=plain64,hash-alg=sha256 TEST_DIR/luks-aes-256-xts-plain64-sha256.img 4194304M | ||
352 | -Formatting 'TEST_DIR/luks-aes-256-xts-plain64-sha256.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=aes-256 cipher-mode=xts ivgen-alg=plain64 hash-alg=sha256 | ||
353 | +qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,iter-time=10,cipher-alg=aes-256,cipher-mode=xts,ivgen-alg=plain64,hash-alg=sha256 TEST_DIR/luks-aes-256-xts-plain64-sha256.img 4194304M | ||
354 | +Formatting 'TEST_DIR/luks-aes-256-xts-plain64-sha256.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=aes-256 cipher-mode=xts ivgen-alg=plain64 hash-alg=sha256 iter-time=10 | ||
355 | |||
356 | # Open dev | ||
357 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha256.img qiotest-145-aes-256-xts-plain64-sha256 | ||
358 | @@ -XXX,XX +XXX,XX @@ Skipping aes-256-xts-plain64-ripemd160 in blacklist | ||
359 | # Create image | ||
360 | truncate TEST_DIR/luks-aes-256-xts-plain-sha1-pwslot3.img --size 4194304MB | ||
361 | # Format image | ||
362 | -sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain --key-size 512 --hash sha1 --key-slot 3 --key-file - TEST_DIR/luks-aes-256-xts-plain-sha1-pwslot3.img | ||
363 | +sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain --key-size 512 --hash sha1 --key-slot 3 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain-sha1-pwslot3.img | ||
364 | # Open dev | ||
365 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain-sha1-pwslot3.img qiotest-145-aes-256-xts-plain-sha1-pwslot3 | ||
366 | # Set dev owner | ||
367 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-xts-plain-sha1-pwslot3.img | ||
368 | # Create image | ||
369 | truncate TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img --size 4194304MB | ||
370 | # Format image | ||
371 | -sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain --key-size 512 --hash sha1 --key-slot 0 --key-file - TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img | ||
372 | +sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain --key-size 512 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img | ||
373 | # Add password slot 1 | ||
374 | -sudo cryptsetup -q -v luksAddKey TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img --key-slot 1 --key-file - TEST_DIR/passwd.txt | ||
375 | +sudo cryptsetup -q -v luksAddKey TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img --key-slot 1 --key-file - --iter-time 10 TEST_DIR/passwd.txt | ||
376 | # Add password slot 2 | ||
377 | -sudo cryptsetup -q -v luksAddKey TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img --key-slot 2 --key-file - TEST_DIR/passwd.txt | ||
378 | +sudo cryptsetup -q -v luksAddKey TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img --key-slot 2 --key-file - --iter-time 10 TEST_DIR/passwd.txt | ||
379 | # Add password slot 3 | ||
380 | -sudo cryptsetup -q -v luksAddKey TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img --key-slot 3 --key-file - TEST_DIR/passwd.txt | ||
381 | +sudo cryptsetup -q -v luksAddKey TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img --key-slot 3 --key-file - --iter-time 10 TEST_DIR/passwd.txt | ||
382 | # Add password slot 4 | ||
383 | -sudo cryptsetup -q -v luksAddKey TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img --key-slot 4 --key-file - TEST_DIR/passwd.txt | ||
384 | +sudo cryptsetup -q -v luksAddKey TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img --key-slot 4 --key-file - --iter-time 10 TEST_DIR/passwd.txt | ||
385 | # Add password slot 5 | ||
386 | -sudo cryptsetup -q -v luksAddKey TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img --key-slot 5 --key-file - TEST_DIR/passwd.txt | ||
387 | +sudo cryptsetup -q -v luksAddKey TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img --key-slot 5 --key-file - --iter-time 10 TEST_DIR/passwd.txt | ||
388 | # Add password slot 6 | ||
389 | -sudo cryptsetup -q -v luksAddKey TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img --key-slot 6 --key-file - TEST_DIR/passwd.txt | ||
390 | +sudo cryptsetup -q -v luksAddKey TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img --key-slot 6 --key-file - --iter-time 10 TEST_DIR/passwd.txt | ||
391 | # Add password slot 7 | ||
392 | -sudo cryptsetup -q -v luksAddKey TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img --key-slot 7 --key-file - TEST_DIR/passwd.txt | ||
393 | +sudo cryptsetup -q -v luksAddKey TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img --key-slot 7 --key-file - --iter-time 10 TEST_DIR/passwd.txt | ||
394 | # Open dev | ||
395 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img qiotest-145-aes-256-xts-plain-sha1-pwallslots | ||
396 | # Set dev owner | ||
397 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img | ||
398 | |||
399 | # ================= qemu-img aes-256-xts-plain-sha1-pwallslots ================= | ||
400 | # Create image | ||
401 | -qemu-img create -f luks --object secret,id=sec0,data=c2xvdDE=,format=base64 -o key-secret=sec0,cipher-alg=aes-256,cipher-mode=xts,ivgen-alg=plain,hash-alg=sha1 TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img 4194304M | ||
402 | -Formatting 'TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=aes-256 cipher-mode=xts ivgen-alg=plain hash-alg=sha1 | ||
403 | +qemu-img create -f luks --object secret,id=sec0,data=c2xvdDE=,format=base64 -o key-secret=sec0,iter-time=10,cipher-alg=aes-256,cipher-mode=xts,ivgen-alg=plain,hash-alg=sha1 TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img 4194304M | ||
404 | +Formatting 'TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=aes-256 cipher-mode=xts ivgen-alg=plain hash-alg=sha1 iter-time=10 | ||
405 | |||
406 | # Open dev | ||
407 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img qiotest-145-aes-256-xts-plain-sha1-pwallslots | ||
408 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img | ||
409 | # Create image | ||
410 | truncate TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img --size 4194304MB | ||
411 | # Format image | ||
412 | -sudo cryptsetup -q -v luksFormat --cipher aes-cbc-essiv:sha256 --key-size 256 --hash sha1 --key-slot 0 --key-file - TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img | ||
413 | +sudo cryptsetup -q -v luksFormat --cipher aes-cbc-essiv:sha256 --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img | ||
414 | # Open dev | ||
415 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img qiotest-145-aes-256-cbc-essiv-auto-sha1 | ||
416 | # Set dev owner | ||
417 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img | ||
418 | |||
419 | # ================= qemu-img aes-256-cbc-essiv-auto-sha1 ================= | ||
420 | # Create image | ||
421 | -qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,cipher-alg=aes-256,cipher-mode=cbc,ivgen-alg=essiv,hash-alg=sha1 TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img 4194304M | ||
422 | -Formatting 'TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=aes-256 cipher-mode=cbc ivgen-alg=essiv hash-alg=sha1 | ||
423 | +qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,iter-time=10,cipher-alg=aes-256,cipher-mode=cbc,ivgen-alg=essiv,hash-alg=sha1 TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img 4194304M | ||
424 | +Formatting 'TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=aes-256 cipher-mode=cbc ivgen-alg=essiv hash-alg=sha1 iter-time=10 | ||
425 | |||
426 | # Open dev | ||
427 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img qiotest-145-aes-256-cbc-essiv-auto-sha1 | ||
428 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img | ||
429 | # Create image | ||
430 | truncate TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img --size 4194304MB | ||
431 | # Format image | ||
432 | -sudo cryptsetup -q -v luksFormat --cipher aes-cbc-plain64:sha256 --key-size 256 --hash sha1 --key-slot 0 --key-file - TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img | ||
433 | +sudo cryptsetup -q -v luksFormat --cipher aes-cbc-plain64:sha256 --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img | ||
434 | # Open dev | ||
435 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img qiotest-145-aes-256-cbc-plain64-sha256-sha1 | ||
436 | # Set dev owner | ||
437 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img | ||
438 | |||
439 | # ================= qemu-img aes-256-cbc-plain64-sha256-sha1 ================= | ||
440 | # Create image | ||
441 | -qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,cipher-alg=aes-256,cipher-mode=cbc,ivgen-alg=plain64,hash-alg=sha1,ivgen-hash-alg=sha256 TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img 4194304M | ||
442 | -Formatting 'TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=aes-256 cipher-mode=cbc ivgen-alg=plain64 ivgen-hash-alg=sha256 hash-alg=sha1 | ||
443 | +qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,iter-time=10,cipher-alg=aes-256,cipher-mode=cbc,ivgen-alg=plain64,hash-alg=sha1,ivgen-hash-alg=sha256 TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img 4194304M | ||
444 | +Formatting 'TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=aes-256 cipher-mode=cbc ivgen-alg=plain64 ivgen-hash-alg=sha256 hash-alg=sha1 iter-time=10 | ||
445 | |||
446 | # Open dev | ||
447 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img qiotest-145-aes-256-cbc-plain64-sha256-sha1 | ||
448 | diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter | ||
449 | index XXXXXXX..XXXXXXX 100644 | ||
450 | --- a/tests/qemu-iotests/common.filter | ||
451 | +++ b/tests/qemu-iotests/common.filter | ||
452 | @@ -XXX,XX +XXX,XX @@ _filter_img_create() | ||
453 | -e "s# block_state_zero=\\(on\\|off\\)##g" \ | ||
454 | -e "s# log_size=[0-9]\\+##g" \ | ||
455 | -e "s# refcount_bits=[0-9]\\+##g" \ | ||
456 | - -e "s# key-secret=[a-zA-Z0-9]\\+##g" | ||
457 | + -e "s# key-secret=[a-zA-Z0-9]\\+##g" \ | ||
458 | + -e "s# iter-time=[0-9]\\+##g" | ||
459 | } | ||
460 | |||
461 | _filter_img_info() | ||
462 | diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc | ||
463 | index XXXXXXX..XXXXXXX 100644 | ||
464 | --- a/tests/qemu-iotests/common.rc | ||
465 | +++ b/tests/qemu-iotests/common.rc | ||
466 | @@ -XXX,XX +XXX,XX @@ _set_default_imgopts() | ||
467 | if [ "$IMGFMT" == "qcow2" ] && ! (echo "$IMGOPTS" | grep "compat=" > /dev/null); then | ||
468 | IMGOPTS=$(_optstr_add "$IMGOPTS" "compat=1.1") | ||
469 | fi | ||
470 | + if [ "$IMGFMT" == "luks" ] && ! (echo "$IMGOPTS" | grep "iter-time=" > /dev/null); then | ||
471 | + IMGOPTS=$(_optstr_add "$IMGOPTS" "iter-time=10") | ||
472 | + fi | ||
473 | } | ||
474 | |||
475 | _use_sample_img() | ||
476 | -- | ||
477 | 2.9.4 | ||
478 | |||
479 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | ||
2 | 1 | ||
3 | Add tests for sha224, sha512, sha384 and ripemd160 hash | ||
4 | algorithms. | ||
5 | |||
6 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
7 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
8 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
9 | Message-id: 20170626123510.20134-5-berrange@redhat.com | ||
10 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
11 | --- | ||
12 | tests/qemu-iotests/149 | 10 +- | ||
13 | tests/qemu-iotests/149.out | 482 ++++++++++++++++++++++++++++++++++++++++++++- | ||
14 | 2 files changed, 484 insertions(+), 8 deletions(-) | ||
15 | |||
16 | diff --git a/tests/qemu-iotests/149 b/tests/qemu-iotests/149 | ||
17 | index XXXXXXX..XXXXXXX 100755 | ||
18 | --- a/tests/qemu-iotests/149 | ||
19 | +++ b/tests/qemu-iotests/149 | ||
20 | @@ -XXX,XX +XXX,XX @@ configs = [ | ||
21 | |||
22 | |||
23 | # LUKS default but diff hash | ||
24 | + LUKSConfig("aes-256-xts-plain64-sha224", | ||
25 | + "aes", 256, "xts", "plain64", None, "sha224"), | ||
26 | LUKSConfig("aes-256-xts-plain64-sha256", | ||
27 | "aes", 256, "xts", "plain64", None, "sha256"), | ||
28 | + LUKSConfig("aes-256-xts-plain64-sha384", | ||
29 | + "aes", 256, "xts", "plain64", None, "sha384"), | ||
30 | LUKSConfig("aes-256-xts-plain64-sha512", | ||
31 | "aes", 256, "xts", "plain64", None, "sha512"), | ||
32 | LUKSConfig("aes-256-xts-plain64-ripemd160", | ||
33 | @@ -XXX,XX +XXX,XX @@ blacklist = [ | ||
34 | |||
35 | # GCrypt doesn't support Twofish with 192 bit key | ||
36 | "twofish-192-xts-plain64-sha1", | ||
37 | - | ||
38 | - # We don't have sha512 hash wired up yet | ||
39 | - "aes-256-xts-plain64-sha512", | ||
40 | - | ||
41 | - # We don't have ripemd160 hash wired up yet | ||
42 | - "aes-256-xts-plain64-ripemd160", | ||
43 | ] | ||
44 | |||
45 | whitelist = [] | ||
46 | diff --git a/tests/qemu-iotests/149.out b/tests/qemu-iotests/149.out | ||
47 | index XXXXXXX..XXXXXXX 100644 | ||
48 | --- a/tests/qemu-iotests/149.out | ||
49 | +++ b/tests/qemu-iotests/149.out | ||
50 | @@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-serpent-192-xts-plain64-sha1.img | ||
51 | |||
52 | Skipping cast6-128-xts-plain64-sha1 in blacklist | ||
53 | Skipping cast6-192-xts-plain64-sha1 in blacklist | ||
54 | +# ================= dm-crypt aes-256-xts-plain64-sha224 ================= | ||
55 | +# Create image | ||
56 | +truncate TEST_DIR/luks-aes-256-xts-plain64-sha224.img --size 4194304MB | ||
57 | +# Format image | ||
58 | +sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain64 --key-size 512 --hash sha224 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain64-sha224.img | ||
59 | +# Open dev | ||
60 | +sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha224.img qiotest-145-aes-256-xts-plain64-sha224 | ||
61 | +# Set dev owner | ||
62 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
63 | +# Write test pattern 0xa7 | ||
64 | +qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
65 | +wrote 10485760/10485760 bytes at offset 104857600 | ||
66 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
67 | + | ||
68 | +# Write test pattern 0x13 | ||
69 | +qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
70 | +wrote 10485760/10485760 bytes at offset 3298534883328 | ||
71 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
72 | + | ||
73 | +# Close dev | ||
74 | +sudo cryptsetup -q -v luksClose qiotest-145-aes-256-xts-plain64-sha224 | ||
75 | +# Read test pattern 0xa7 | ||
76 | +qemu-io -c read -P 0xa7 100M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-sha224.img | ||
77 | +read 10485760/10485760 bytes at offset 104857600 | ||
78 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
79 | + | ||
80 | +# Read test pattern 0x13 | ||
81 | +qemu-io -c read -P 0x13 3145728M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-sha224.img | ||
82 | +read 10485760/10485760 bytes at offset 3298534883328 | ||
83 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
84 | + | ||
85 | +# Write test pattern 0x91 | ||
86 | +qemu-io -c write -P 0x91 100M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-sha224.img | ||
87 | +wrote 10485760/10485760 bytes at offset 104857600 | ||
88 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
89 | + | ||
90 | +# Write test pattern 0x5e | ||
91 | +qemu-io -c write -P 0x5e 3145728M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-sha224.img | ||
92 | +wrote 10485760/10485760 bytes at offset 3298534883328 | ||
93 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
94 | + | ||
95 | +# Open dev | ||
96 | +sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha224.img qiotest-145-aes-256-xts-plain64-sha224 | ||
97 | +# Set dev owner | ||
98 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
99 | +# Read test pattern 0x91 | ||
100 | +qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
101 | +read 10485760/10485760 bytes at offset 104857600 | ||
102 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
103 | + | ||
104 | +# Read test pattern 0x5e | ||
105 | +qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
106 | +read 10485760/10485760 bytes at offset 3298534883328 | ||
107 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
108 | + | ||
109 | +# Close dev | ||
110 | +sudo cryptsetup -q -v luksClose qiotest-145-aes-256-xts-plain64-sha224 | ||
111 | +# Delete image | ||
112 | +unlink TEST_DIR/luks-aes-256-xts-plain64-sha224.img | ||
113 | + | ||
114 | +# ================= qemu-img aes-256-xts-plain64-sha224 ================= | ||
115 | +# Create image | ||
116 | +qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,iter-time=10,cipher-alg=aes-256,cipher-mode=xts,ivgen-alg=plain64,hash-alg=sha224 TEST_DIR/luks-aes-256-xts-plain64-sha224.img 4194304M | ||
117 | +Formatting 'TEST_DIR/luks-aes-256-xts-plain64-sha224.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=aes-256 cipher-mode=xts ivgen-alg=plain64 hash-alg=sha224 iter-time=10 | ||
118 | + | ||
119 | +# Open dev | ||
120 | +sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha224.img qiotest-145-aes-256-xts-plain64-sha224 | ||
121 | +# Set dev owner | ||
122 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
123 | +# Write test pattern 0xa7 | ||
124 | +qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
125 | +wrote 10485760/10485760 bytes at offset 104857600 | ||
126 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
127 | + | ||
128 | +# Write test pattern 0x13 | ||
129 | +qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
130 | +wrote 10485760/10485760 bytes at offset 3298534883328 | ||
131 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
132 | + | ||
133 | +# Close dev | ||
134 | +sudo cryptsetup -q -v luksClose qiotest-145-aes-256-xts-plain64-sha224 | ||
135 | +# Read test pattern 0xa7 | ||
136 | +qemu-io -c read -P 0xa7 100M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-sha224.img | ||
137 | +read 10485760/10485760 bytes at offset 104857600 | ||
138 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
139 | + | ||
140 | +# Read test pattern 0x13 | ||
141 | +qemu-io -c read -P 0x13 3145728M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-sha224.img | ||
142 | +read 10485760/10485760 bytes at offset 3298534883328 | ||
143 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
144 | + | ||
145 | +# Write test pattern 0x91 | ||
146 | +qemu-io -c write -P 0x91 100M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-sha224.img | ||
147 | +wrote 10485760/10485760 bytes at offset 104857600 | ||
148 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
149 | + | ||
150 | +# Write test pattern 0x5e | ||
151 | +qemu-io -c write -P 0x5e 3145728M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-sha224.img | ||
152 | +wrote 10485760/10485760 bytes at offset 3298534883328 | ||
153 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
154 | + | ||
155 | +# Open dev | ||
156 | +sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha224.img qiotest-145-aes-256-xts-plain64-sha224 | ||
157 | +# Set dev owner | ||
158 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
159 | +# Read test pattern 0x91 | ||
160 | +qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
161 | +read 10485760/10485760 bytes at offset 104857600 | ||
162 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
163 | + | ||
164 | +# Read test pattern 0x5e | ||
165 | +qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
166 | +read 10485760/10485760 bytes at offset 3298534883328 | ||
167 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
168 | + | ||
169 | +# Close dev | ||
170 | +sudo cryptsetup -q -v luksClose qiotest-145-aes-256-xts-plain64-sha224 | ||
171 | +# Delete image | ||
172 | +unlink TEST_DIR/luks-aes-256-xts-plain64-sha224.img | ||
173 | + | ||
174 | # ================= dm-crypt aes-256-xts-plain64-sha256 ================= | ||
175 | # Create image | ||
176 | truncate TEST_DIR/luks-aes-256-xts-plain64-sha256.img --size 4194304MB | ||
177 | @@ -XXX,XX +XXX,XX @@ sudo cryptsetup -q -v luksClose qiotest-145-aes-256-xts-plain64-sha256 | ||
178 | # Delete image | ||
179 | unlink TEST_DIR/luks-aes-256-xts-plain64-sha256.img | ||
180 | |||
181 | -Skipping aes-256-xts-plain64-sha512 in blacklist | ||
182 | -Skipping aes-256-xts-plain64-ripemd160 in blacklist | ||
183 | +# ================= dm-crypt aes-256-xts-plain64-sha384 ================= | ||
184 | +# Create image | ||
185 | +truncate TEST_DIR/luks-aes-256-xts-plain64-sha384.img --size 4194304MB | ||
186 | +# Format image | ||
187 | +sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain64 --key-size 512 --hash sha384 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain64-sha384.img | ||
188 | +# Open dev | ||
189 | +sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha384.img qiotest-145-aes-256-xts-plain64-sha384 | ||
190 | +# Set dev owner | ||
191 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
192 | +# Write test pattern 0xa7 | ||
193 | +qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
194 | +wrote 10485760/10485760 bytes at offset 104857600 | ||
195 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
196 | + | ||
197 | +# Write test pattern 0x13 | ||
198 | +qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
199 | +wrote 10485760/10485760 bytes at offset 3298534883328 | ||
200 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
201 | + | ||
202 | +# Close dev | ||
203 | +sudo cryptsetup -q -v luksClose qiotest-145-aes-256-xts-plain64-sha384 | ||
204 | +# Read test pattern 0xa7 | ||
205 | +qemu-io -c read -P 0xa7 100M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-sha384.img | ||
206 | +read 10485760/10485760 bytes at offset 104857600 | ||
207 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
208 | + | ||
209 | +# Read test pattern 0x13 | ||
210 | +qemu-io -c read -P 0x13 3145728M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-sha384.img | ||
211 | +read 10485760/10485760 bytes at offset 3298534883328 | ||
212 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
213 | + | ||
214 | +# Write test pattern 0x91 | ||
215 | +qemu-io -c write -P 0x91 100M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-sha384.img | ||
216 | +wrote 10485760/10485760 bytes at offset 104857600 | ||
217 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
218 | + | ||
219 | +# Write test pattern 0x5e | ||
220 | +qemu-io -c write -P 0x5e 3145728M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-sha384.img | ||
221 | +wrote 10485760/10485760 bytes at offset 3298534883328 | ||
222 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
223 | + | ||
224 | +# Open dev | ||
225 | +sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha384.img qiotest-145-aes-256-xts-plain64-sha384 | ||
226 | +# Set dev owner | ||
227 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
228 | +# Read test pattern 0x91 | ||
229 | +qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
230 | +read 10485760/10485760 bytes at offset 104857600 | ||
231 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
232 | + | ||
233 | +# Read test pattern 0x5e | ||
234 | +qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
235 | +read 10485760/10485760 bytes at offset 3298534883328 | ||
236 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
237 | + | ||
238 | +# Close dev | ||
239 | +sudo cryptsetup -q -v luksClose qiotest-145-aes-256-xts-plain64-sha384 | ||
240 | +# Delete image | ||
241 | +unlink TEST_DIR/luks-aes-256-xts-plain64-sha384.img | ||
242 | + | ||
243 | +# ================= qemu-img aes-256-xts-plain64-sha384 ================= | ||
244 | +# Create image | ||
245 | +qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,iter-time=10,cipher-alg=aes-256,cipher-mode=xts,ivgen-alg=plain64,hash-alg=sha384 TEST_DIR/luks-aes-256-xts-plain64-sha384.img 4194304M | ||
246 | +Formatting 'TEST_DIR/luks-aes-256-xts-plain64-sha384.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=aes-256 cipher-mode=xts ivgen-alg=plain64 hash-alg=sha384 iter-time=10 | ||
247 | + | ||
248 | +# Open dev | ||
249 | +sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha384.img qiotest-145-aes-256-xts-plain64-sha384 | ||
250 | +# Set dev owner | ||
251 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
252 | +# Write test pattern 0xa7 | ||
253 | +qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
254 | +wrote 10485760/10485760 bytes at offset 104857600 | ||
255 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
256 | + | ||
257 | +# Write test pattern 0x13 | ||
258 | +qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
259 | +wrote 10485760/10485760 bytes at offset 3298534883328 | ||
260 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
261 | + | ||
262 | +# Close dev | ||
263 | +sudo cryptsetup -q -v luksClose qiotest-145-aes-256-xts-plain64-sha384 | ||
264 | +# Read test pattern 0xa7 | ||
265 | +qemu-io -c read -P 0xa7 100M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-sha384.img | ||
266 | +read 10485760/10485760 bytes at offset 104857600 | ||
267 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
268 | + | ||
269 | +# Read test pattern 0x13 | ||
270 | +qemu-io -c read -P 0x13 3145728M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-sha384.img | ||
271 | +read 10485760/10485760 bytes at offset 3298534883328 | ||
272 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
273 | + | ||
274 | +# Write test pattern 0x91 | ||
275 | +qemu-io -c write -P 0x91 100M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-sha384.img | ||
276 | +wrote 10485760/10485760 bytes at offset 104857600 | ||
277 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
278 | + | ||
279 | +# Write test pattern 0x5e | ||
280 | +qemu-io -c write -P 0x5e 3145728M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-sha384.img | ||
281 | +wrote 10485760/10485760 bytes at offset 3298534883328 | ||
282 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
283 | + | ||
284 | +# Open dev | ||
285 | +sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha384.img qiotest-145-aes-256-xts-plain64-sha384 | ||
286 | +# Set dev owner | ||
287 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
288 | +# Read test pattern 0x91 | ||
289 | +qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
290 | +read 10485760/10485760 bytes at offset 104857600 | ||
291 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
292 | + | ||
293 | +# Read test pattern 0x5e | ||
294 | +qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
295 | +read 10485760/10485760 bytes at offset 3298534883328 | ||
296 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
297 | + | ||
298 | +# Close dev | ||
299 | +sudo cryptsetup -q -v luksClose qiotest-145-aes-256-xts-plain64-sha384 | ||
300 | +# Delete image | ||
301 | +unlink TEST_DIR/luks-aes-256-xts-plain64-sha384.img | ||
302 | + | ||
303 | +# ================= dm-crypt aes-256-xts-plain64-sha512 ================= | ||
304 | +# Create image | ||
305 | +truncate TEST_DIR/luks-aes-256-xts-plain64-sha512.img --size 4194304MB | ||
306 | +# Format image | ||
307 | +sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain64 --key-size 512 --hash sha512 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain64-sha512.img | ||
308 | +# Open dev | ||
309 | +sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha512.img qiotest-145-aes-256-xts-plain64-sha512 | ||
310 | +# Set dev owner | ||
311 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
312 | +# Write test pattern 0xa7 | ||
313 | +qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
314 | +wrote 10485760/10485760 bytes at offset 104857600 | ||
315 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
316 | + | ||
317 | +# Write test pattern 0x13 | ||
318 | +qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
319 | +wrote 10485760/10485760 bytes at offset 3298534883328 | ||
320 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
321 | + | ||
322 | +# Close dev | ||
323 | +sudo cryptsetup -q -v luksClose qiotest-145-aes-256-xts-plain64-sha512 | ||
324 | +# Read test pattern 0xa7 | ||
325 | +qemu-io -c read -P 0xa7 100M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-sha512.img | ||
326 | +read 10485760/10485760 bytes at offset 104857600 | ||
327 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
328 | + | ||
329 | +# Read test pattern 0x13 | ||
330 | +qemu-io -c read -P 0x13 3145728M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-sha512.img | ||
331 | +read 10485760/10485760 bytes at offset 3298534883328 | ||
332 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
333 | + | ||
334 | +# Write test pattern 0x91 | ||
335 | +qemu-io -c write -P 0x91 100M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-sha512.img | ||
336 | +wrote 10485760/10485760 bytes at offset 104857600 | ||
337 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
338 | + | ||
339 | +# Write test pattern 0x5e | ||
340 | +qemu-io -c write -P 0x5e 3145728M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-sha512.img | ||
341 | +wrote 10485760/10485760 bytes at offset 3298534883328 | ||
342 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
343 | + | ||
344 | +# Open dev | ||
345 | +sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha512.img qiotest-145-aes-256-xts-plain64-sha512 | ||
346 | +# Set dev owner | ||
347 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
348 | +# Read test pattern 0x91 | ||
349 | +qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
350 | +read 10485760/10485760 bytes at offset 104857600 | ||
351 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
352 | + | ||
353 | +# Read test pattern 0x5e | ||
354 | +qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
355 | +read 10485760/10485760 bytes at offset 3298534883328 | ||
356 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
357 | + | ||
358 | +# Close dev | ||
359 | +sudo cryptsetup -q -v luksClose qiotest-145-aes-256-xts-plain64-sha512 | ||
360 | +# Delete image | ||
361 | +unlink TEST_DIR/luks-aes-256-xts-plain64-sha512.img | ||
362 | + | ||
363 | +# ================= qemu-img aes-256-xts-plain64-sha512 ================= | ||
364 | +# Create image | ||
365 | +qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,iter-time=10,cipher-alg=aes-256,cipher-mode=xts,ivgen-alg=plain64,hash-alg=sha512 TEST_DIR/luks-aes-256-xts-plain64-sha512.img 4194304M | ||
366 | +Formatting 'TEST_DIR/luks-aes-256-xts-plain64-sha512.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=aes-256 cipher-mode=xts ivgen-alg=plain64 hash-alg=sha512 iter-time=10 | ||
367 | + | ||
368 | +# Open dev | ||
369 | +sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha512.img qiotest-145-aes-256-xts-plain64-sha512 | ||
370 | +# Set dev owner | ||
371 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
372 | +# Write test pattern 0xa7 | ||
373 | +qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
374 | +wrote 10485760/10485760 bytes at offset 104857600 | ||
375 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
376 | + | ||
377 | +# Write test pattern 0x13 | ||
378 | +qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
379 | +wrote 10485760/10485760 bytes at offset 3298534883328 | ||
380 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
381 | + | ||
382 | +# Close dev | ||
383 | +sudo cryptsetup -q -v luksClose qiotest-145-aes-256-xts-plain64-sha512 | ||
384 | +# Read test pattern 0xa7 | ||
385 | +qemu-io -c read -P 0xa7 100M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-sha512.img | ||
386 | +read 10485760/10485760 bytes at offset 104857600 | ||
387 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
388 | + | ||
389 | +# Read test pattern 0x13 | ||
390 | +qemu-io -c read -P 0x13 3145728M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-sha512.img | ||
391 | +read 10485760/10485760 bytes at offset 3298534883328 | ||
392 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
393 | + | ||
394 | +# Write test pattern 0x91 | ||
395 | +qemu-io -c write -P 0x91 100M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-sha512.img | ||
396 | +wrote 10485760/10485760 bytes at offset 104857600 | ||
397 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
398 | + | ||
399 | +# Write test pattern 0x5e | ||
400 | +qemu-io -c write -P 0x5e 3145728M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-sha512.img | ||
401 | +wrote 10485760/10485760 bytes at offset 3298534883328 | ||
402 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
403 | + | ||
404 | +# Open dev | ||
405 | +sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha512.img qiotest-145-aes-256-xts-plain64-sha512 | ||
406 | +# Set dev owner | ||
407 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
408 | +# Read test pattern 0x91 | ||
409 | +qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
410 | +read 10485760/10485760 bytes at offset 104857600 | ||
411 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
412 | + | ||
413 | +# Read test pattern 0x5e | ||
414 | +qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
415 | +read 10485760/10485760 bytes at offset 3298534883328 | ||
416 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
417 | + | ||
418 | +# Close dev | ||
419 | +sudo cryptsetup -q -v luksClose qiotest-145-aes-256-xts-plain64-sha512 | ||
420 | +# Delete image | ||
421 | +unlink TEST_DIR/luks-aes-256-xts-plain64-sha512.img | ||
422 | + | ||
423 | +# ================= dm-crypt aes-256-xts-plain64-ripemd160 ================= | ||
424 | +# Create image | ||
425 | +truncate TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img --size 4194304MB | ||
426 | +# Format image | ||
427 | +sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain64 --key-size 512 --hash ripemd160 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img | ||
428 | +# Open dev | ||
429 | +sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img qiotest-145-aes-256-xts-plain64-ripemd160 | ||
430 | +# Set dev owner | ||
431 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
432 | +# Write test pattern 0xa7 | ||
433 | +qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
434 | +wrote 10485760/10485760 bytes at offset 104857600 | ||
435 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
436 | + | ||
437 | +# Write test pattern 0x13 | ||
438 | +qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
439 | +wrote 10485760/10485760 bytes at offset 3298534883328 | ||
440 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
441 | + | ||
442 | +# Close dev | ||
443 | +sudo cryptsetup -q -v luksClose qiotest-145-aes-256-xts-plain64-ripemd160 | ||
444 | +# Read test pattern 0xa7 | ||
445 | +qemu-io -c read -P 0xa7 100M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img | ||
446 | +read 10485760/10485760 bytes at offset 104857600 | ||
447 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
448 | + | ||
449 | +# Read test pattern 0x13 | ||
450 | +qemu-io -c read -P 0x13 3145728M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img | ||
451 | +read 10485760/10485760 bytes at offset 3298534883328 | ||
452 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
453 | + | ||
454 | +# Write test pattern 0x91 | ||
455 | +qemu-io -c write -P 0x91 100M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img | ||
456 | +wrote 10485760/10485760 bytes at offset 104857600 | ||
457 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
458 | + | ||
459 | +# Write test pattern 0x5e | ||
460 | +qemu-io -c write -P 0x5e 3145728M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img | ||
461 | +wrote 10485760/10485760 bytes at offset 3298534883328 | ||
462 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
463 | + | ||
464 | +# Open dev | ||
465 | +sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img qiotest-145-aes-256-xts-plain64-ripemd160 | ||
466 | +# Set dev owner | ||
467 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
468 | +# Read test pattern 0x91 | ||
469 | +qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
470 | +read 10485760/10485760 bytes at offset 104857600 | ||
471 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
472 | + | ||
473 | +# Read test pattern 0x5e | ||
474 | +qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
475 | +read 10485760/10485760 bytes at offset 3298534883328 | ||
476 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
477 | + | ||
478 | +# Close dev | ||
479 | +sudo cryptsetup -q -v luksClose qiotest-145-aes-256-xts-plain64-ripemd160 | ||
480 | +# Delete image | ||
481 | +unlink TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img | ||
482 | + | ||
483 | +# ================= qemu-img aes-256-xts-plain64-ripemd160 ================= | ||
484 | +# Create image | ||
485 | +qemu-img create -f luks --object secret,id=sec0,data=MTIzNDU2,format=base64 -o key-secret=sec0,iter-time=10,cipher-alg=aes-256,cipher-mode=xts,ivgen-alg=plain64,hash-alg=ripemd160 TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img 4194304M | ||
486 | +Formatting 'TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img', fmt=luks size=4398046511104 key-secret=sec0 cipher-alg=aes-256 cipher-mode=xts ivgen-alg=plain64 hash-alg=ripemd160 iter-time=10 | ||
487 | + | ||
488 | +# Open dev | ||
489 | +sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img qiotest-145-aes-256-xts-plain64-ripemd160 | ||
490 | +# Set dev owner | ||
491 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
492 | +# Write test pattern 0xa7 | ||
493 | +qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
494 | +wrote 10485760/10485760 bytes at offset 104857600 | ||
495 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
496 | + | ||
497 | +# Write test pattern 0x13 | ||
498 | +qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
499 | +wrote 10485760/10485760 bytes at offset 3298534883328 | ||
500 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
501 | + | ||
502 | +# Close dev | ||
503 | +sudo cryptsetup -q -v luksClose qiotest-145-aes-256-xts-plain64-ripemd160 | ||
504 | +# Read test pattern 0xa7 | ||
505 | +qemu-io -c read -P 0xa7 100M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img | ||
506 | +read 10485760/10485760 bytes at offset 104857600 | ||
507 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
508 | + | ||
509 | +# Read test pattern 0x13 | ||
510 | +qemu-io -c read -P 0x13 3145728M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img | ||
511 | +read 10485760/10485760 bytes at offset 3298534883328 | ||
512 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
513 | + | ||
514 | +# Write test pattern 0x91 | ||
515 | +qemu-io -c write -P 0x91 100M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img | ||
516 | +wrote 10485760/10485760 bytes at offset 104857600 | ||
517 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
518 | + | ||
519 | +# Write test pattern 0x5e | ||
520 | +qemu-io -c write -P 0x5e 3145728M 10M --object secret,id=sec0,data=MTIzNDU2,format=base64 --image-opts driver=luks,key-secret=sec0,file.filename=TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img | ||
521 | +wrote 10485760/10485760 bytes at offset 3298534883328 | ||
522 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
523 | + | ||
524 | +# Open dev | ||
525 | +sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img qiotest-145-aes-256-xts-plain64-ripemd160 | ||
526 | +# Set dev owner | ||
527 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
528 | +# Read test pattern 0x91 | ||
529 | +qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
530 | +read 10485760/10485760 bytes at offset 104857600 | ||
531 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
532 | + | ||
533 | +# Read test pattern 0x5e | ||
534 | +qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
535 | +read 10485760/10485760 bytes at offset 3298534883328 | ||
536 | +10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
537 | + | ||
538 | +# Close dev | ||
539 | +sudo cryptsetup -q -v luksClose qiotest-145-aes-256-xts-plain64-ripemd160 | ||
540 | +# Delete image | ||
541 | +unlink TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img | ||
542 | + | ||
543 | # ================= dm-crypt aes-256-xts-plain-sha1-pwslot3 ================= | ||
544 | # Create image | ||
545 | truncate TEST_DIR/luks-aes-256-xts-plain-sha1-pwslot3.img --size 4194304MB | ||
546 | -- | ||
547 | 2.9.4 | ||
548 | |||
549 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | ||
2 | 1 | ||
3 | On some distros, whenever you close a block device file | ||
4 | descriptor there is a udev rule that resets the file | ||
5 | permissions. This can race with the test script when | ||
6 | we run qemu-io multiple times against the same block | ||
7 | device. Occasionally the second qemu-io invocation | ||
8 | will find udev has reset the permissions causing failure. | ||
9 | |||
10 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
11 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
12 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
13 | Message-id: 20170626123510.20134-6-berrange@redhat.com | ||
14 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
15 | --- | ||
16 | tests/qemu-iotests/149 | 12 +- | ||
17 | tests/qemu-iotests/149.out | 344 ++++++++++++++++++++++----------------------- | ||
18 | 2 files changed, 177 insertions(+), 179 deletions(-) | ||
19 | |||
20 | diff --git a/tests/qemu-iotests/149 b/tests/qemu-iotests/149 | ||
21 | index XXXXXXX..XXXXXXX 100755 | ||
22 | --- a/tests/qemu-iotests/149 | ||
23 | +++ b/tests/qemu-iotests/149 | ||
24 | @@ -XXX,XX +XXX,XX @@ def chown(config): | ||
25 | msg = proc.communicate()[0] | ||
26 | |||
27 | if proc.returncode != 0: | ||
28 | - raise Exception("Cannot change owner on %s" % path) | ||
29 | + raise Exception(msg) | ||
30 | |||
31 | |||
32 | def cryptsetup_open(config): | ||
33 | @@ -XXX,XX +XXX,XX @@ def qemu_io_image_args(config, dev=False): | ||
34 | def qemu_io_write_pattern(config, pattern, offset_mb, size_mb, dev=False): | ||
35 | """Write a pattern of data to a LUKS image or device""" | ||
36 | |||
37 | + if dev: | ||
38 | + chown(config) | ||
39 | args = ["-c", "write -P 0x%x %dM %dM" % (pattern, offset_mb, size_mb)] | ||
40 | args.extend(qemu_io_image_args(config, dev)) | ||
41 | iotests.log("qemu-io " + " ".join(args), filters=[iotests.filter_test_dir]) | ||
42 | @@ -XXX,XX +XXX,XX @@ def qemu_io_write_pattern(config, pattern, offset_mb, size_mb, dev=False): | ||
43 | def qemu_io_read_pattern(config, pattern, offset_mb, size_mb, dev=False): | ||
44 | """Read a pattern of data to a LUKS image or device""" | ||
45 | |||
46 | + if dev: | ||
47 | + chown(config) | ||
48 | args = ["-c", "read -P 0x%x %dM %dM" % (pattern, offset_mb, size_mb)] | ||
49 | args.extend(qemu_io_image_args(config, dev)) | ||
50 | iotests.log("qemu-io " + " ".join(args), filters=[iotests.filter_test_dir]) | ||
51 | @@ -XXX,XX +XXX,XX @@ def test_once(config, qemu_img=False): | ||
52 | cryptsetup_open(config) | ||
53 | |||
54 | try: | ||
55 | - iotests.log("# Set dev owner") | ||
56 | - chown(config) | ||
57 | - | ||
58 | iotests.log("# Write test pattern 0xa7") | ||
59 | qemu_io_write_pattern(config, 0xa7, lowOffsetMB, 10, dev=True) | ||
60 | iotests.log("# Write test pattern 0x13") | ||
61 | @@ -XXX,XX +XXX,XX @@ def test_once(config, qemu_img=False): | ||
62 | cryptsetup_open(config) | ||
63 | |||
64 | try: | ||
65 | - iotests.log("# Set dev owner") | ||
66 | - chown(config) | ||
67 | - | ||
68 | iotests.log("# Read test pattern 0x91") | ||
69 | qemu_io_read_pattern(config, 0x91, lowOffsetMB, 10, dev=True) | ||
70 | iotests.log("# Read test pattern 0x5e") | ||
71 | diff --git a/tests/qemu-iotests/149.out b/tests/qemu-iotests/149.out | ||
72 | index XXXXXXX..XXXXXXX 100644 | ||
73 | --- a/tests/qemu-iotests/149.out | ||
74 | +++ b/tests/qemu-iotests/149.out | ||
75 | @@ -XXX,XX +XXX,XX @@ truncate TEST_DIR/luks-aes-256-xts-plain64-sha1.img --size 4194304MB | ||
76 | sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain64 --key-size 512 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain64-sha1.img | ||
77 | # Open dev | ||
78 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha1.img qiotest-145-aes-256-xts-plain64-sha1 | ||
79 | -# Set dev owner | ||
80 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha1 | ||
81 | # Write test pattern 0xa7 | ||
82 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha1 | ||
83 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha1 | ||
84 | wrote 10485760/10485760 bytes at offset 104857600 | ||
85 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
86 | |||
87 | # Write test pattern 0x13 | ||
88 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha1 | ||
89 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha1 | ||
90 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
91 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
92 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
93 | |||
94 | # Open dev | ||
95 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha1.img qiotest-145-aes-256-xts-plain64-sha1 | ||
96 | -# Set dev owner | ||
97 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha1 | ||
98 | # Read test pattern 0x91 | ||
99 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha1 | ||
100 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha1 | ||
101 | read 10485760/10485760 bytes at offset 104857600 | ||
102 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
103 | |||
104 | # Read test pattern 0x5e | ||
105 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha1 | ||
106 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha1 | ||
107 | read 10485760/10485760 bytes at offset 3298534883328 | ||
108 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
109 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/luks-aes-256-xts-plain64-sha1.img', fmt=luks size=439804651 | ||
110 | |||
111 | # Open dev | ||
112 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha1.img qiotest-145-aes-256-xts-plain64-sha1 | ||
113 | -# Set dev owner | ||
114 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha1 | ||
115 | # Write test pattern 0xa7 | ||
116 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha1 | ||
117 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha1 | ||
118 | wrote 10485760/10485760 bytes at offset 104857600 | ||
119 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
120 | |||
121 | # Write test pattern 0x13 | ||
122 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha1 | ||
123 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha1 | ||
124 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
125 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
126 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
127 | |||
128 | # Open dev | ||
129 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha1.img qiotest-145-aes-256-xts-plain64-sha1 | ||
130 | -# Set dev owner | ||
131 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha1 | ||
132 | # Read test pattern 0x91 | ||
133 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha1 | ||
134 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha1 | ||
135 | read 10485760/10485760 bytes at offset 104857600 | ||
136 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
137 | |||
138 | # Read test pattern 0x5e | ||
139 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha1 | ||
140 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha1 | ||
141 | read 10485760/10485760 bytes at offset 3298534883328 | ||
142 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
143 | @@ -XXX,XX +XXX,XX @@ truncate TEST_DIR/luks-twofish-256-xts-plain64-sha1.img --size 4194304MB | ||
144 | sudo cryptsetup -q -v luksFormat --cipher twofish-xts-plain64 --key-size 512 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-twofish-256-xts-plain64-sha1.img | ||
145 | # Open dev | ||
146 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-twofish-256-xts-plain64-sha1.img qiotest-145-twofish-256-xts-plain64-sha1 | ||
147 | -# Set dev owner | ||
148 | -sudo chown UID:GID /dev/mapper/qiotest-145-twofish-256-xts-plain64-sha1 | ||
149 | # Write test pattern 0xa7 | ||
150 | +sudo chown UID:GID /dev/mapper/qiotest-145-twofish-256-xts-plain64-sha1 | ||
151 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-twofish-256-xts-plain64-sha1 | ||
152 | wrote 10485760/10485760 bytes at offset 104857600 | ||
153 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
154 | |||
155 | # Write test pattern 0x13 | ||
156 | +sudo chown UID:GID /dev/mapper/qiotest-145-twofish-256-xts-plain64-sha1 | ||
157 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-twofish-256-xts-plain64-sha1 | ||
158 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
159 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
160 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
161 | |||
162 | # Open dev | ||
163 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-twofish-256-xts-plain64-sha1.img qiotest-145-twofish-256-xts-plain64-sha1 | ||
164 | -# Set dev owner | ||
165 | -sudo chown UID:GID /dev/mapper/qiotest-145-twofish-256-xts-plain64-sha1 | ||
166 | # Read test pattern 0x91 | ||
167 | +sudo chown UID:GID /dev/mapper/qiotest-145-twofish-256-xts-plain64-sha1 | ||
168 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-twofish-256-xts-plain64-sha1 | ||
169 | read 10485760/10485760 bytes at offset 104857600 | ||
170 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
171 | |||
172 | # Read test pattern 0x5e | ||
173 | +sudo chown UID:GID /dev/mapper/qiotest-145-twofish-256-xts-plain64-sha1 | ||
174 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-twofish-256-xts-plain64-sha1 | ||
175 | read 10485760/10485760 bytes at offset 3298534883328 | ||
176 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
177 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/luks-twofish-256-xts-plain64-sha1.img', fmt=luks size=43980 | ||
178 | |||
179 | # Open dev | ||
180 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-twofish-256-xts-plain64-sha1.img qiotest-145-twofish-256-xts-plain64-sha1 | ||
181 | -# Set dev owner | ||
182 | -sudo chown UID:GID /dev/mapper/qiotest-145-twofish-256-xts-plain64-sha1 | ||
183 | # Write test pattern 0xa7 | ||
184 | +sudo chown UID:GID /dev/mapper/qiotest-145-twofish-256-xts-plain64-sha1 | ||
185 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-twofish-256-xts-plain64-sha1 | ||
186 | wrote 10485760/10485760 bytes at offset 104857600 | ||
187 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
188 | |||
189 | # Write test pattern 0x13 | ||
190 | +sudo chown UID:GID /dev/mapper/qiotest-145-twofish-256-xts-plain64-sha1 | ||
191 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-twofish-256-xts-plain64-sha1 | ||
192 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
193 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
194 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
195 | |||
196 | # Open dev | ||
197 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-twofish-256-xts-plain64-sha1.img qiotest-145-twofish-256-xts-plain64-sha1 | ||
198 | -# Set dev owner | ||
199 | -sudo chown UID:GID /dev/mapper/qiotest-145-twofish-256-xts-plain64-sha1 | ||
200 | # Read test pattern 0x91 | ||
201 | +sudo chown UID:GID /dev/mapper/qiotest-145-twofish-256-xts-plain64-sha1 | ||
202 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-twofish-256-xts-plain64-sha1 | ||
203 | read 10485760/10485760 bytes at offset 104857600 | ||
204 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
205 | |||
206 | # Read test pattern 0x5e | ||
207 | +sudo chown UID:GID /dev/mapper/qiotest-145-twofish-256-xts-plain64-sha1 | ||
208 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-twofish-256-xts-plain64-sha1 | ||
209 | read 10485760/10485760 bytes at offset 3298534883328 | ||
210 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
211 | @@ -XXX,XX +XXX,XX @@ truncate TEST_DIR/luks-serpent-256-xts-plain64-sha1.img --size 4194304MB | ||
212 | sudo cryptsetup -q -v luksFormat --cipher serpent-xts-plain64 --key-size 512 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-serpent-256-xts-plain64-sha1.img | ||
213 | # Open dev | ||
214 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-serpent-256-xts-plain64-sha1.img qiotest-145-serpent-256-xts-plain64-sha1 | ||
215 | -# Set dev owner | ||
216 | -sudo chown UID:GID /dev/mapper/qiotest-145-serpent-256-xts-plain64-sha1 | ||
217 | # Write test pattern 0xa7 | ||
218 | +sudo chown UID:GID /dev/mapper/qiotest-145-serpent-256-xts-plain64-sha1 | ||
219 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-serpent-256-xts-plain64-sha1 | ||
220 | wrote 10485760/10485760 bytes at offset 104857600 | ||
221 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
222 | |||
223 | # Write test pattern 0x13 | ||
224 | +sudo chown UID:GID /dev/mapper/qiotest-145-serpent-256-xts-plain64-sha1 | ||
225 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-serpent-256-xts-plain64-sha1 | ||
226 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
227 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
228 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
229 | |||
230 | # Open dev | ||
231 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-serpent-256-xts-plain64-sha1.img qiotest-145-serpent-256-xts-plain64-sha1 | ||
232 | -# Set dev owner | ||
233 | -sudo chown UID:GID /dev/mapper/qiotest-145-serpent-256-xts-plain64-sha1 | ||
234 | # Read test pattern 0x91 | ||
235 | +sudo chown UID:GID /dev/mapper/qiotest-145-serpent-256-xts-plain64-sha1 | ||
236 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-serpent-256-xts-plain64-sha1 | ||
237 | read 10485760/10485760 bytes at offset 104857600 | ||
238 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
239 | |||
240 | # Read test pattern 0x5e | ||
241 | +sudo chown UID:GID /dev/mapper/qiotest-145-serpent-256-xts-plain64-sha1 | ||
242 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-serpent-256-xts-plain64-sha1 | ||
243 | read 10485760/10485760 bytes at offset 3298534883328 | ||
244 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
245 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/luks-serpent-256-xts-plain64-sha1.img', fmt=luks size=43980 | ||
246 | |||
247 | # Open dev | ||
248 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-serpent-256-xts-plain64-sha1.img qiotest-145-serpent-256-xts-plain64-sha1 | ||
249 | -# Set dev owner | ||
250 | -sudo chown UID:GID /dev/mapper/qiotest-145-serpent-256-xts-plain64-sha1 | ||
251 | # Write test pattern 0xa7 | ||
252 | +sudo chown UID:GID /dev/mapper/qiotest-145-serpent-256-xts-plain64-sha1 | ||
253 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-serpent-256-xts-plain64-sha1 | ||
254 | wrote 10485760/10485760 bytes at offset 104857600 | ||
255 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
256 | |||
257 | # Write test pattern 0x13 | ||
258 | +sudo chown UID:GID /dev/mapper/qiotest-145-serpent-256-xts-plain64-sha1 | ||
259 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-serpent-256-xts-plain64-sha1 | ||
260 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
261 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
262 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
263 | |||
264 | # Open dev | ||
265 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-serpent-256-xts-plain64-sha1.img qiotest-145-serpent-256-xts-plain64-sha1 | ||
266 | -# Set dev owner | ||
267 | -sudo chown UID:GID /dev/mapper/qiotest-145-serpent-256-xts-plain64-sha1 | ||
268 | # Read test pattern 0x91 | ||
269 | +sudo chown UID:GID /dev/mapper/qiotest-145-serpent-256-xts-plain64-sha1 | ||
270 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-serpent-256-xts-plain64-sha1 | ||
271 | read 10485760/10485760 bytes at offset 104857600 | ||
272 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
273 | |||
274 | # Read test pattern 0x5e | ||
275 | +sudo chown UID:GID /dev/mapper/qiotest-145-serpent-256-xts-plain64-sha1 | ||
276 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-serpent-256-xts-plain64-sha1 | ||
277 | read 10485760/10485760 bytes at offset 3298534883328 | ||
278 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
279 | @@ -XXX,XX +XXX,XX @@ truncate TEST_DIR/luks-cast5-128-cbc-plain64-sha1.img --size 4194304MB | ||
280 | sudo cryptsetup -q -v luksFormat --cipher cast5-cbc-plain64 --key-size 128 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-cast5-128-cbc-plain64-sha1.img | ||
281 | # Open dev | ||
282 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-cast5-128-cbc-plain64-sha1.img qiotest-145-cast5-128-cbc-plain64-sha1 | ||
283 | -# Set dev owner | ||
284 | -sudo chown UID:GID /dev/mapper/qiotest-145-cast5-128-cbc-plain64-sha1 | ||
285 | # Write test pattern 0xa7 | ||
286 | +sudo chown UID:GID /dev/mapper/qiotest-145-cast5-128-cbc-plain64-sha1 | ||
287 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-cast5-128-cbc-plain64-sha1 | ||
288 | wrote 10485760/10485760 bytes at offset 104857600 | ||
289 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
290 | |||
291 | # Write test pattern 0x13 | ||
292 | +sudo chown UID:GID /dev/mapper/qiotest-145-cast5-128-cbc-plain64-sha1 | ||
293 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-cast5-128-cbc-plain64-sha1 | ||
294 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
295 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
296 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
297 | |||
298 | # Open dev | ||
299 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-cast5-128-cbc-plain64-sha1.img qiotest-145-cast5-128-cbc-plain64-sha1 | ||
300 | -# Set dev owner | ||
301 | -sudo chown UID:GID /dev/mapper/qiotest-145-cast5-128-cbc-plain64-sha1 | ||
302 | # Read test pattern 0x91 | ||
303 | +sudo chown UID:GID /dev/mapper/qiotest-145-cast5-128-cbc-plain64-sha1 | ||
304 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-cast5-128-cbc-plain64-sha1 | ||
305 | read 10485760/10485760 bytes at offset 104857600 | ||
306 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
307 | |||
308 | # Read test pattern 0x5e | ||
309 | +sudo chown UID:GID /dev/mapper/qiotest-145-cast5-128-cbc-plain64-sha1 | ||
310 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-cast5-128-cbc-plain64-sha1 | ||
311 | read 10485760/10485760 bytes at offset 3298534883328 | ||
312 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
313 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/luks-cast5-128-cbc-plain64-sha1.img', fmt=luks size=4398046 | ||
314 | |||
315 | # Open dev | ||
316 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-cast5-128-cbc-plain64-sha1.img qiotest-145-cast5-128-cbc-plain64-sha1 | ||
317 | -# Set dev owner | ||
318 | -sudo chown UID:GID /dev/mapper/qiotest-145-cast5-128-cbc-plain64-sha1 | ||
319 | # Write test pattern 0xa7 | ||
320 | +sudo chown UID:GID /dev/mapper/qiotest-145-cast5-128-cbc-plain64-sha1 | ||
321 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-cast5-128-cbc-plain64-sha1 | ||
322 | wrote 10485760/10485760 bytes at offset 104857600 | ||
323 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
324 | |||
325 | # Write test pattern 0x13 | ||
326 | +sudo chown UID:GID /dev/mapper/qiotest-145-cast5-128-cbc-plain64-sha1 | ||
327 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-cast5-128-cbc-plain64-sha1 | ||
328 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
329 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
330 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
331 | |||
332 | # Open dev | ||
333 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-cast5-128-cbc-plain64-sha1.img qiotest-145-cast5-128-cbc-plain64-sha1 | ||
334 | -# Set dev owner | ||
335 | -sudo chown UID:GID /dev/mapper/qiotest-145-cast5-128-cbc-plain64-sha1 | ||
336 | # Read test pattern 0x91 | ||
337 | +sudo chown UID:GID /dev/mapper/qiotest-145-cast5-128-cbc-plain64-sha1 | ||
338 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-cast5-128-cbc-plain64-sha1 | ||
339 | read 10485760/10485760 bytes at offset 104857600 | ||
340 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
341 | |||
342 | # Read test pattern 0x5e | ||
343 | +sudo chown UID:GID /dev/mapper/qiotest-145-cast5-128-cbc-plain64-sha1 | ||
344 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-cast5-128-cbc-plain64-sha1 | ||
345 | read 10485760/10485760 bytes at offset 3298534883328 | ||
346 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
347 | @@ -XXX,XX +XXX,XX @@ truncate TEST_DIR/luks-aes-256-cbc-plain-sha1.img --size 4194304MB | ||
348 | sudo cryptsetup -q -v luksFormat --cipher aes-cbc-plain --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-cbc-plain-sha1.img | ||
349 | # Open dev | ||
350 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-plain-sha1.img qiotest-145-aes-256-cbc-plain-sha1 | ||
351 | -# Set dev owner | ||
352 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain-sha1 | ||
353 | # Write test pattern 0xa7 | ||
354 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain-sha1 | ||
355 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain-sha1 | ||
356 | wrote 10485760/10485760 bytes at offset 104857600 | ||
357 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
358 | |||
359 | # Write test pattern 0x13 | ||
360 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain-sha1 | ||
361 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain-sha1 | ||
362 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
363 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
364 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
365 | |||
366 | # Open dev | ||
367 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-plain-sha1.img qiotest-145-aes-256-cbc-plain-sha1 | ||
368 | -# Set dev owner | ||
369 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain-sha1 | ||
370 | # Read test pattern 0x91 | ||
371 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain-sha1 | ||
372 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain-sha1 | ||
373 | read 10485760/10485760 bytes at offset 104857600 | ||
374 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
375 | |||
376 | # Read test pattern 0x5e | ||
377 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain-sha1 | ||
378 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain-sha1 | ||
379 | read 10485760/10485760 bytes at offset 3298534883328 | ||
380 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
381 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/luks-aes-256-cbc-plain-sha1.img', fmt=luks size=43980465111 | ||
382 | |||
383 | # Open dev | ||
384 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-plain-sha1.img qiotest-145-aes-256-cbc-plain-sha1 | ||
385 | -# Set dev owner | ||
386 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain-sha1 | ||
387 | # Write test pattern 0xa7 | ||
388 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain-sha1 | ||
389 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain-sha1 | ||
390 | wrote 10485760/10485760 bytes at offset 104857600 | ||
391 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
392 | |||
393 | # Write test pattern 0x13 | ||
394 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain-sha1 | ||
395 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain-sha1 | ||
396 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
397 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
398 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
399 | |||
400 | # Open dev | ||
401 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-plain-sha1.img qiotest-145-aes-256-cbc-plain-sha1 | ||
402 | -# Set dev owner | ||
403 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain-sha1 | ||
404 | # Read test pattern 0x91 | ||
405 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain-sha1 | ||
406 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain-sha1 | ||
407 | read 10485760/10485760 bytes at offset 104857600 | ||
408 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
409 | |||
410 | # Read test pattern 0x5e | ||
411 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain-sha1 | ||
412 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain-sha1 | ||
413 | read 10485760/10485760 bytes at offset 3298534883328 | ||
414 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
415 | @@ -XXX,XX +XXX,XX @@ truncate TEST_DIR/luks-aes-256-cbc-plain64-sha1.img --size 4194304MB | ||
416 | sudo cryptsetup -q -v luksFormat --cipher aes-cbc-plain64 --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-cbc-plain64-sha1.img | ||
417 | # Open dev | ||
418 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-plain64-sha1.img qiotest-145-aes-256-cbc-plain64-sha1 | ||
419 | -# Set dev owner | ||
420 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain64-sha1 | ||
421 | # Write test pattern 0xa7 | ||
422 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain64-sha1 | ||
423 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain64-sha1 | ||
424 | wrote 10485760/10485760 bytes at offset 104857600 | ||
425 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
426 | |||
427 | # Write test pattern 0x13 | ||
428 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain64-sha1 | ||
429 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain64-sha1 | ||
430 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
431 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
432 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
433 | |||
434 | # Open dev | ||
435 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-plain64-sha1.img qiotest-145-aes-256-cbc-plain64-sha1 | ||
436 | -# Set dev owner | ||
437 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain64-sha1 | ||
438 | # Read test pattern 0x91 | ||
439 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain64-sha1 | ||
440 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain64-sha1 | ||
441 | read 10485760/10485760 bytes at offset 104857600 | ||
442 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
443 | |||
444 | # Read test pattern 0x5e | ||
445 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain64-sha1 | ||
446 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain64-sha1 | ||
447 | read 10485760/10485760 bytes at offset 3298534883328 | ||
448 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
449 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/luks-aes-256-cbc-plain64-sha1.img', fmt=luks size=439804651 | ||
450 | |||
451 | # Open dev | ||
452 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-plain64-sha1.img qiotest-145-aes-256-cbc-plain64-sha1 | ||
453 | -# Set dev owner | ||
454 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain64-sha1 | ||
455 | # Write test pattern 0xa7 | ||
456 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain64-sha1 | ||
457 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain64-sha1 | ||
458 | wrote 10485760/10485760 bytes at offset 104857600 | ||
459 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
460 | |||
461 | # Write test pattern 0x13 | ||
462 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain64-sha1 | ||
463 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain64-sha1 | ||
464 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
465 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
466 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
467 | |||
468 | # Open dev | ||
469 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-plain64-sha1.img qiotest-145-aes-256-cbc-plain64-sha1 | ||
470 | -# Set dev owner | ||
471 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain64-sha1 | ||
472 | # Read test pattern 0x91 | ||
473 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain64-sha1 | ||
474 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain64-sha1 | ||
475 | read 10485760/10485760 bytes at offset 104857600 | ||
476 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
477 | |||
478 | # Read test pattern 0x5e | ||
479 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain64-sha1 | ||
480 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain64-sha1 | ||
481 | read 10485760/10485760 bytes at offset 3298534883328 | ||
482 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
483 | @@ -XXX,XX +XXX,XX @@ truncate TEST_DIR/luks-aes-256-cbc-essiv-sha256-sha1.img --size 4194304MB | ||
484 | sudo cryptsetup -q -v luksFormat --cipher aes-cbc-essiv:sha256 --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-cbc-essiv-sha256-sha1.img | ||
485 | # Open dev | ||
486 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-essiv-sha256-sha1.img qiotest-145-aes-256-cbc-essiv-sha256-sha1 | ||
487 | -# Set dev owner | ||
488 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-essiv-sha256-sha1 | ||
489 | # Write test pattern 0xa7 | ||
490 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-essiv-sha256-sha1 | ||
491 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-essiv-sha256-sha1 | ||
492 | wrote 10485760/10485760 bytes at offset 104857600 | ||
493 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
494 | |||
495 | # Write test pattern 0x13 | ||
496 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-essiv-sha256-sha1 | ||
497 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-essiv-sha256-sha1 | ||
498 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
499 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
500 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
501 | |||
502 | # Open dev | ||
503 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-essiv-sha256-sha1.img qiotest-145-aes-256-cbc-essiv-sha256-sha1 | ||
504 | -# Set dev owner | ||
505 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-essiv-sha256-sha1 | ||
506 | # Read test pattern 0x91 | ||
507 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-essiv-sha256-sha1 | ||
508 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-essiv-sha256-sha1 | ||
509 | read 10485760/10485760 bytes at offset 104857600 | ||
510 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
511 | |||
512 | # Read test pattern 0x5e | ||
513 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-essiv-sha256-sha1 | ||
514 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-essiv-sha256-sha1 | ||
515 | read 10485760/10485760 bytes at offset 3298534883328 | ||
516 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
517 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/luks-aes-256-cbc-essiv-sha256-sha1.img', fmt=luks size=4398 | ||
518 | |||
519 | # Open dev | ||
520 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-essiv-sha256-sha1.img qiotest-145-aes-256-cbc-essiv-sha256-sha1 | ||
521 | -# Set dev owner | ||
522 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-essiv-sha256-sha1 | ||
523 | # Write test pattern 0xa7 | ||
524 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-essiv-sha256-sha1 | ||
525 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-essiv-sha256-sha1 | ||
526 | wrote 10485760/10485760 bytes at offset 104857600 | ||
527 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
528 | |||
529 | # Write test pattern 0x13 | ||
530 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-essiv-sha256-sha1 | ||
531 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-essiv-sha256-sha1 | ||
532 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
533 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
534 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
535 | |||
536 | # Open dev | ||
537 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-essiv-sha256-sha1.img qiotest-145-aes-256-cbc-essiv-sha256-sha1 | ||
538 | -# Set dev owner | ||
539 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-essiv-sha256-sha1 | ||
540 | # Read test pattern 0x91 | ||
541 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-essiv-sha256-sha1 | ||
542 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-essiv-sha256-sha1 | ||
543 | read 10485760/10485760 bytes at offset 104857600 | ||
544 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
545 | |||
546 | # Read test pattern 0x5e | ||
547 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-essiv-sha256-sha1 | ||
548 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-essiv-sha256-sha1 | ||
549 | read 10485760/10485760 bytes at offset 3298534883328 | ||
550 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
551 | @@ -XXX,XX +XXX,XX @@ truncate TEST_DIR/luks-aes-256-xts-essiv-sha256-sha1.img --size 4194304MB | ||
552 | sudo cryptsetup -q -v luksFormat --cipher aes-xts-essiv:sha256 --key-size 512 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-essiv-sha256-sha1.img | ||
553 | # Open dev | ||
554 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-essiv-sha256-sha1.img qiotest-145-aes-256-xts-essiv-sha256-sha1 | ||
555 | -# Set dev owner | ||
556 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-essiv-sha256-sha1 | ||
557 | # Write test pattern 0xa7 | ||
558 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-essiv-sha256-sha1 | ||
559 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-essiv-sha256-sha1 | ||
560 | wrote 10485760/10485760 bytes at offset 104857600 | ||
561 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
562 | |||
563 | # Write test pattern 0x13 | ||
564 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-essiv-sha256-sha1 | ||
565 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-essiv-sha256-sha1 | ||
566 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
567 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
568 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
569 | |||
570 | # Open dev | ||
571 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-essiv-sha256-sha1.img qiotest-145-aes-256-xts-essiv-sha256-sha1 | ||
572 | -# Set dev owner | ||
573 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-essiv-sha256-sha1 | ||
574 | # Read test pattern 0x91 | ||
575 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-essiv-sha256-sha1 | ||
576 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-essiv-sha256-sha1 | ||
577 | read 10485760/10485760 bytes at offset 104857600 | ||
578 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
579 | |||
580 | # Read test pattern 0x5e | ||
581 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-essiv-sha256-sha1 | ||
582 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-essiv-sha256-sha1 | ||
583 | read 10485760/10485760 bytes at offset 3298534883328 | ||
584 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
585 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/luks-aes-256-xts-essiv-sha256-sha1.img', fmt=luks size=4398 | ||
586 | |||
587 | # Open dev | ||
588 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-essiv-sha256-sha1.img qiotest-145-aes-256-xts-essiv-sha256-sha1 | ||
589 | -# Set dev owner | ||
590 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-essiv-sha256-sha1 | ||
591 | # Write test pattern 0xa7 | ||
592 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-essiv-sha256-sha1 | ||
593 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-essiv-sha256-sha1 | ||
594 | wrote 10485760/10485760 bytes at offset 104857600 | ||
595 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
596 | |||
597 | # Write test pattern 0x13 | ||
598 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-essiv-sha256-sha1 | ||
599 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-essiv-sha256-sha1 | ||
600 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
601 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
602 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
603 | |||
604 | # Open dev | ||
605 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-essiv-sha256-sha1.img qiotest-145-aes-256-xts-essiv-sha256-sha1 | ||
606 | -# Set dev owner | ||
607 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-essiv-sha256-sha1 | ||
608 | # Read test pattern 0x91 | ||
609 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-essiv-sha256-sha1 | ||
610 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-essiv-sha256-sha1 | ||
611 | read 10485760/10485760 bytes at offset 104857600 | ||
612 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
613 | |||
614 | # Read test pattern 0x5e | ||
615 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-essiv-sha256-sha1 | ||
616 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-essiv-sha256-sha1 | ||
617 | read 10485760/10485760 bytes at offset 3298534883328 | ||
618 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
619 | @@ -XXX,XX +XXX,XX @@ truncate TEST_DIR/luks-aes-128-xts-plain64-sha256-sha1.img --size 4194304MB | ||
620 | sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain64 --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-128-xts-plain64-sha256-sha1.img | ||
621 | # Open dev | ||
622 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-128-xts-plain64-sha256-sha1.img qiotest-145-aes-128-xts-plain64-sha256-sha1 | ||
623 | -# Set dev owner | ||
624 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-128-xts-plain64-sha256-sha1 | ||
625 | # Write test pattern 0xa7 | ||
626 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-128-xts-plain64-sha256-sha1 | ||
627 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-128-xts-plain64-sha256-sha1 | ||
628 | wrote 10485760/10485760 bytes at offset 104857600 | ||
629 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
630 | |||
631 | # Write test pattern 0x13 | ||
632 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-128-xts-plain64-sha256-sha1 | ||
633 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-128-xts-plain64-sha256-sha1 | ||
634 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
635 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
636 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
637 | |||
638 | # Open dev | ||
639 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-128-xts-plain64-sha256-sha1.img qiotest-145-aes-128-xts-plain64-sha256-sha1 | ||
640 | -# Set dev owner | ||
641 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-128-xts-plain64-sha256-sha1 | ||
642 | # Read test pattern 0x91 | ||
643 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-128-xts-plain64-sha256-sha1 | ||
644 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-128-xts-plain64-sha256-sha1 | ||
645 | read 10485760/10485760 bytes at offset 104857600 | ||
646 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
647 | |||
648 | # Read test pattern 0x5e | ||
649 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-128-xts-plain64-sha256-sha1 | ||
650 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-128-xts-plain64-sha256-sha1 | ||
651 | read 10485760/10485760 bytes at offset 3298534883328 | ||
652 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
653 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/luks-aes-128-xts-plain64-sha256-sha1.img', fmt=luks size=43 | ||
654 | |||
655 | # Open dev | ||
656 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-128-xts-plain64-sha256-sha1.img qiotest-145-aes-128-xts-plain64-sha256-sha1 | ||
657 | -# Set dev owner | ||
658 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-128-xts-plain64-sha256-sha1 | ||
659 | # Write test pattern 0xa7 | ||
660 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-128-xts-plain64-sha256-sha1 | ||
661 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-128-xts-plain64-sha256-sha1 | ||
662 | wrote 10485760/10485760 bytes at offset 104857600 | ||
663 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
664 | |||
665 | # Write test pattern 0x13 | ||
666 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-128-xts-plain64-sha256-sha1 | ||
667 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-128-xts-plain64-sha256-sha1 | ||
668 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
669 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
670 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
671 | |||
672 | # Open dev | ||
673 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-128-xts-plain64-sha256-sha1.img qiotest-145-aes-128-xts-plain64-sha256-sha1 | ||
674 | -# Set dev owner | ||
675 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-128-xts-plain64-sha256-sha1 | ||
676 | # Read test pattern 0x91 | ||
677 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-128-xts-plain64-sha256-sha1 | ||
678 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-128-xts-plain64-sha256-sha1 | ||
679 | read 10485760/10485760 bytes at offset 104857600 | ||
680 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
681 | |||
682 | # Read test pattern 0x5e | ||
683 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-128-xts-plain64-sha256-sha1 | ||
684 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-128-xts-plain64-sha256-sha1 | ||
685 | read 10485760/10485760 bytes at offset 3298534883328 | ||
686 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
687 | @@ -XXX,XX +XXX,XX @@ truncate TEST_DIR/luks-aes-192-xts-plain64-sha256-sha1.img --size 4194304MB | ||
688 | sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain64 --key-size 384 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-192-xts-plain64-sha256-sha1.img | ||
689 | # Open dev | ||
690 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-192-xts-plain64-sha256-sha1.img qiotest-145-aes-192-xts-plain64-sha256-sha1 | ||
691 | -# Set dev owner | ||
692 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-192-xts-plain64-sha256-sha1 | ||
693 | # Write test pattern 0xa7 | ||
694 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-192-xts-plain64-sha256-sha1 | ||
695 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-192-xts-plain64-sha256-sha1 | ||
696 | wrote 10485760/10485760 bytes at offset 104857600 | ||
697 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
698 | |||
699 | # Write test pattern 0x13 | ||
700 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-192-xts-plain64-sha256-sha1 | ||
701 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-192-xts-plain64-sha256-sha1 | ||
702 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
703 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
704 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
705 | |||
706 | # Open dev | ||
707 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-192-xts-plain64-sha256-sha1.img qiotest-145-aes-192-xts-plain64-sha256-sha1 | ||
708 | -# Set dev owner | ||
709 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-192-xts-plain64-sha256-sha1 | ||
710 | # Read test pattern 0x91 | ||
711 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-192-xts-plain64-sha256-sha1 | ||
712 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-192-xts-plain64-sha256-sha1 | ||
713 | read 10485760/10485760 bytes at offset 104857600 | ||
714 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
715 | |||
716 | # Read test pattern 0x5e | ||
717 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-192-xts-plain64-sha256-sha1 | ||
718 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-192-xts-plain64-sha256-sha1 | ||
719 | read 10485760/10485760 bytes at offset 3298534883328 | ||
720 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
721 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/luks-aes-192-xts-plain64-sha256-sha1.img', fmt=luks size=43 | ||
722 | |||
723 | # Open dev | ||
724 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-192-xts-plain64-sha256-sha1.img qiotest-145-aes-192-xts-plain64-sha256-sha1 | ||
725 | -# Set dev owner | ||
726 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-192-xts-plain64-sha256-sha1 | ||
727 | # Write test pattern 0xa7 | ||
728 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-192-xts-plain64-sha256-sha1 | ||
729 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-192-xts-plain64-sha256-sha1 | ||
730 | wrote 10485760/10485760 bytes at offset 104857600 | ||
731 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
732 | |||
733 | # Write test pattern 0x13 | ||
734 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-192-xts-plain64-sha256-sha1 | ||
735 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-192-xts-plain64-sha256-sha1 | ||
736 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
737 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
738 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
739 | |||
740 | # Open dev | ||
741 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-192-xts-plain64-sha256-sha1.img qiotest-145-aes-192-xts-plain64-sha256-sha1 | ||
742 | -# Set dev owner | ||
743 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-192-xts-plain64-sha256-sha1 | ||
744 | # Read test pattern 0x91 | ||
745 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-192-xts-plain64-sha256-sha1 | ||
746 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-192-xts-plain64-sha256-sha1 | ||
747 | read 10485760/10485760 bytes at offset 104857600 | ||
748 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
749 | |||
750 | # Read test pattern 0x5e | ||
751 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-192-xts-plain64-sha256-sha1 | ||
752 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-192-xts-plain64-sha256-sha1 | ||
753 | read 10485760/10485760 bytes at offset 3298534883328 | ||
754 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
755 | @@ -XXX,XX +XXX,XX @@ truncate TEST_DIR/luks-twofish-128-xts-plain64-sha1.img --size 4194304MB | ||
756 | sudo cryptsetup -q -v luksFormat --cipher twofish-xts-plain64 --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-twofish-128-xts-plain64-sha1.img | ||
757 | # Open dev | ||
758 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-twofish-128-xts-plain64-sha1.img qiotest-145-twofish-128-xts-plain64-sha1 | ||
759 | -# Set dev owner | ||
760 | -sudo chown UID:GID /dev/mapper/qiotest-145-twofish-128-xts-plain64-sha1 | ||
761 | # Write test pattern 0xa7 | ||
762 | +sudo chown UID:GID /dev/mapper/qiotest-145-twofish-128-xts-plain64-sha1 | ||
763 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-twofish-128-xts-plain64-sha1 | ||
764 | wrote 10485760/10485760 bytes at offset 104857600 | ||
765 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
766 | |||
767 | # Write test pattern 0x13 | ||
768 | +sudo chown UID:GID /dev/mapper/qiotest-145-twofish-128-xts-plain64-sha1 | ||
769 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-twofish-128-xts-plain64-sha1 | ||
770 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
771 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
772 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
773 | |||
774 | # Open dev | ||
775 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-twofish-128-xts-plain64-sha1.img qiotest-145-twofish-128-xts-plain64-sha1 | ||
776 | -# Set dev owner | ||
777 | -sudo chown UID:GID /dev/mapper/qiotest-145-twofish-128-xts-plain64-sha1 | ||
778 | # Read test pattern 0x91 | ||
779 | +sudo chown UID:GID /dev/mapper/qiotest-145-twofish-128-xts-plain64-sha1 | ||
780 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-twofish-128-xts-plain64-sha1 | ||
781 | read 10485760/10485760 bytes at offset 104857600 | ||
782 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
783 | |||
784 | # Read test pattern 0x5e | ||
785 | +sudo chown UID:GID /dev/mapper/qiotest-145-twofish-128-xts-plain64-sha1 | ||
786 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-twofish-128-xts-plain64-sha1 | ||
787 | read 10485760/10485760 bytes at offset 3298534883328 | ||
788 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
789 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/luks-twofish-128-xts-plain64-sha1.img', fmt=luks size=43980 | ||
790 | |||
791 | # Open dev | ||
792 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-twofish-128-xts-plain64-sha1.img qiotest-145-twofish-128-xts-plain64-sha1 | ||
793 | -# Set dev owner | ||
794 | -sudo chown UID:GID /dev/mapper/qiotest-145-twofish-128-xts-plain64-sha1 | ||
795 | # Write test pattern 0xa7 | ||
796 | +sudo chown UID:GID /dev/mapper/qiotest-145-twofish-128-xts-plain64-sha1 | ||
797 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-twofish-128-xts-plain64-sha1 | ||
798 | wrote 10485760/10485760 bytes at offset 104857600 | ||
799 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
800 | |||
801 | # Write test pattern 0x13 | ||
802 | +sudo chown UID:GID /dev/mapper/qiotest-145-twofish-128-xts-plain64-sha1 | ||
803 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-twofish-128-xts-plain64-sha1 | ||
804 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
805 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
806 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
807 | |||
808 | # Open dev | ||
809 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-twofish-128-xts-plain64-sha1.img qiotest-145-twofish-128-xts-plain64-sha1 | ||
810 | -# Set dev owner | ||
811 | -sudo chown UID:GID /dev/mapper/qiotest-145-twofish-128-xts-plain64-sha1 | ||
812 | # Read test pattern 0x91 | ||
813 | +sudo chown UID:GID /dev/mapper/qiotest-145-twofish-128-xts-plain64-sha1 | ||
814 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-twofish-128-xts-plain64-sha1 | ||
815 | read 10485760/10485760 bytes at offset 104857600 | ||
816 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
817 | |||
818 | # Read test pattern 0x5e | ||
819 | +sudo chown UID:GID /dev/mapper/qiotest-145-twofish-128-xts-plain64-sha1 | ||
820 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-twofish-128-xts-plain64-sha1 | ||
821 | read 10485760/10485760 bytes at offset 3298534883328 | ||
822 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
823 | @@ -XXX,XX +XXX,XX @@ truncate TEST_DIR/luks-serpent-128-xts-plain64-sha1.img --size 4194304MB | ||
824 | sudo cryptsetup -q -v luksFormat --cipher serpent-xts-plain64 --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-serpent-128-xts-plain64-sha1.img | ||
825 | # Open dev | ||
826 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-serpent-128-xts-plain64-sha1.img qiotest-145-serpent-128-xts-plain64-sha1 | ||
827 | -# Set dev owner | ||
828 | -sudo chown UID:GID /dev/mapper/qiotest-145-serpent-128-xts-plain64-sha1 | ||
829 | # Write test pattern 0xa7 | ||
830 | +sudo chown UID:GID /dev/mapper/qiotest-145-serpent-128-xts-plain64-sha1 | ||
831 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-serpent-128-xts-plain64-sha1 | ||
832 | wrote 10485760/10485760 bytes at offset 104857600 | ||
833 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
834 | |||
835 | # Write test pattern 0x13 | ||
836 | +sudo chown UID:GID /dev/mapper/qiotest-145-serpent-128-xts-plain64-sha1 | ||
837 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-serpent-128-xts-plain64-sha1 | ||
838 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
839 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
840 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
841 | |||
842 | # Open dev | ||
843 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-serpent-128-xts-plain64-sha1.img qiotest-145-serpent-128-xts-plain64-sha1 | ||
844 | -# Set dev owner | ||
845 | -sudo chown UID:GID /dev/mapper/qiotest-145-serpent-128-xts-plain64-sha1 | ||
846 | # Read test pattern 0x91 | ||
847 | +sudo chown UID:GID /dev/mapper/qiotest-145-serpent-128-xts-plain64-sha1 | ||
848 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-serpent-128-xts-plain64-sha1 | ||
849 | read 10485760/10485760 bytes at offset 104857600 | ||
850 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
851 | |||
852 | # Read test pattern 0x5e | ||
853 | +sudo chown UID:GID /dev/mapper/qiotest-145-serpent-128-xts-plain64-sha1 | ||
854 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-serpent-128-xts-plain64-sha1 | ||
855 | read 10485760/10485760 bytes at offset 3298534883328 | ||
856 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
857 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/luks-serpent-128-xts-plain64-sha1.img', fmt=luks size=43980 | ||
858 | |||
859 | # Open dev | ||
860 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-serpent-128-xts-plain64-sha1.img qiotest-145-serpent-128-xts-plain64-sha1 | ||
861 | -# Set dev owner | ||
862 | -sudo chown UID:GID /dev/mapper/qiotest-145-serpent-128-xts-plain64-sha1 | ||
863 | # Write test pattern 0xa7 | ||
864 | +sudo chown UID:GID /dev/mapper/qiotest-145-serpent-128-xts-plain64-sha1 | ||
865 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-serpent-128-xts-plain64-sha1 | ||
866 | wrote 10485760/10485760 bytes at offset 104857600 | ||
867 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
868 | |||
869 | # Write test pattern 0x13 | ||
870 | +sudo chown UID:GID /dev/mapper/qiotest-145-serpent-128-xts-plain64-sha1 | ||
871 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-serpent-128-xts-plain64-sha1 | ||
872 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
873 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
874 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
875 | |||
876 | # Open dev | ||
877 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-serpent-128-xts-plain64-sha1.img qiotest-145-serpent-128-xts-plain64-sha1 | ||
878 | -# Set dev owner | ||
879 | -sudo chown UID:GID /dev/mapper/qiotest-145-serpent-128-xts-plain64-sha1 | ||
880 | # Read test pattern 0x91 | ||
881 | +sudo chown UID:GID /dev/mapper/qiotest-145-serpent-128-xts-plain64-sha1 | ||
882 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-serpent-128-xts-plain64-sha1 | ||
883 | read 10485760/10485760 bytes at offset 104857600 | ||
884 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
885 | |||
886 | # Read test pattern 0x5e | ||
887 | +sudo chown UID:GID /dev/mapper/qiotest-145-serpent-128-xts-plain64-sha1 | ||
888 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-serpent-128-xts-plain64-sha1 | ||
889 | read 10485760/10485760 bytes at offset 3298534883328 | ||
890 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
891 | @@ -XXX,XX +XXX,XX @@ truncate TEST_DIR/luks-serpent-192-xts-plain64-sha1.img --size 4194304MB | ||
892 | sudo cryptsetup -q -v luksFormat --cipher serpent-xts-plain64 --key-size 384 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-serpent-192-xts-plain64-sha1.img | ||
893 | # Open dev | ||
894 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-serpent-192-xts-plain64-sha1.img qiotest-145-serpent-192-xts-plain64-sha1 | ||
895 | -# Set dev owner | ||
896 | -sudo chown UID:GID /dev/mapper/qiotest-145-serpent-192-xts-plain64-sha1 | ||
897 | # Write test pattern 0xa7 | ||
898 | +sudo chown UID:GID /dev/mapper/qiotest-145-serpent-192-xts-plain64-sha1 | ||
899 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-serpent-192-xts-plain64-sha1 | ||
900 | wrote 10485760/10485760 bytes at offset 104857600 | ||
901 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
902 | |||
903 | # Write test pattern 0x13 | ||
904 | +sudo chown UID:GID /dev/mapper/qiotest-145-serpent-192-xts-plain64-sha1 | ||
905 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-serpent-192-xts-plain64-sha1 | ||
906 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
907 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
908 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
909 | |||
910 | # Open dev | ||
911 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-serpent-192-xts-plain64-sha1.img qiotest-145-serpent-192-xts-plain64-sha1 | ||
912 | -# Set dev owner | ||
913 | -sudo chown UID:GID /dev/mapper/qiotest-145-serpent-192-xts-plain64-sha1 | ||
914 | # Read test pattern 0x91 | ||
915 | +sudo chown UID:GID /dev/mapper/qiotest-145-serpent-192-xts-plain64-sha1 | ||
916 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-serpent-192-xts-plain64-sha1 | ||
917 | read 10485760/10485760 bytes at offset 104857600 | ||
918 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
919 | |||
920 | # Read test pattern 0x5e | ||
921 | +sudo chown UID:GID /dev/mapper/qiotest-145-serpent-192-xts-plain64-sha1 | ||
922 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-serpent-192-xts-plain64-sha1 | ||
923 | read 10485760/10485760 bytes at offset 3298534883328 | ||
924 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
925 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/luks-serpent-192-xts-plain64-sha1.img', fmt=luks size=43980 | ||
926 | |||
927 | # Open dev | ||
928 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-serpent-192-xts-plain64-sha1.img qiotest-145-serpent-192-xts-plain64-sha1 | ||
929 | -# Set dev owner | ||
930 | -sudo chown UID:GID /dev/mapper/qiotest-145-serpent-192-xts-plain64-sha1 | ||
931 | # Write test pattern 0xa7 | ||
932 | +sudo chown UID:GID /dev/mapper/qiotest-145-serpent-192-xts-plain64-sha1 | ||
933 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-serpent-192-xts-plain64-sha1 | ||
934 | wrote 10485760/10485760 bytes at offset 104857600 | ||
935 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
936 | |||
937 | # Write test pattern 0x13 | ||
938 | +sudo chown UID:GID /dev/mapper/qiotest-145-serpent-192-xts-plain64-sha1 | ||
939 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-serpent-192-xts-plain64-sha1 | ||
940 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
941 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
942 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
943 | |||
944 | # Open dev | ||
945 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-serpent-192-xts-plain64-sha1.img qiotest-145-serpent-192-xts-plain64-sha1 | ||
946 | -# Set dev owner | ||
947 | -sudo chown UID:GID /dev/mapper/qiotest-145-serpent-192-xts-plain64-sha1 | ||
948 | # Read test pattern 0x91 | ||
949 | +sudo chown UID:GID /dev/mapper/qiotest-145-serpent-192-xts-plain64-sha1 | ||
950 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-serpent-192-xts-plain64-sha1 | ||
951 | read 10485760/10485760 bytes at offset 104857600 | ||
952 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
953 | |||
954 | # Read test pattern 0x5e | ||
955 | +sudo chown UID:GID /dev/mapper/qiotest-145-serpent-192-xts-plain64-sha1 | ||
956 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-serpent-192-xts-plain64-sha1 | ||
957 | read 10485760/10485760 bytes at offset 3298534883328 | ||
958 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
959 | @@ -XXX,XX +XXX,XX @@ truncate TEST_DIR/luks-aes-256-xts-plain64-sha224.img --size 4194304MB | ||
960 | sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain64 --key-size 512 --hash sha224 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain64-sha224.img | ||
961 | # Open dev | ||
962 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha224.img qiotest-145-aes-256-xts-plain64-sha224 | ||
963 | -# Set dev owner | ||
964 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
965 | # Write test pattern 0xa7 | ||
966 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
967 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
968 | wrote 10485760/10485760 bytes at offset 104857600 | ||
969 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
970 | |||
971 | # Write test pattern 0x13 | ||
972 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
973 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
974 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
975 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
976 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
977 | |||
978 | # Open dev | ||
979 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha224.img qiotest-145-aes-256-xts-plain64-sha224 | ||
980 | -# Set dev owner | ||
981 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
982 | # Read test pattern 0x91 | ||
983 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
984 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
985 | read 10485760/10485760 bytes at offset 104857600 | ||
986 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
987 | |||
988 | # Read test pattern 0x5e | ||
989 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
990 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
991 | read 10485760/10485760 bytes at offset 3298534883328 | ||
992 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
993 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/luks-aes-256-xts-plain64-sha224.img', fmt=luks size=4398046 | ||
994 | |||
995 | # Open dev | ||
996 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha224.img qiotest-145-aes-256-xts-plain64-sha224 | ||
997 | -# Set dev owner | ||
998 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
999 | # Write test pattern 0xa7 | ||
1000 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
1001 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
1002 | wrote 10485760/10485760 bytes at offset 104857600 | ||
1003 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1004 | |||
1005 | # Write test pattern 0x13 | ||
1006 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
1007 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
1008 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1009 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1010 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1011 | |||
1012 | # Open dev | ||
1013 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha224.img qiotest-145-aes-256-xts-plain64-sha224 | ||
1014 | -# Set dev owner | ||
1015 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
1016 | # Read test pattern 0x91 | ||
1017 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
1018 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
1019 | read 10485760/10485760 bytes at offset 104857600 | ||
1020 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1021 | |||
1022 | # Read test pattern 0x5e | ||
1023 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
1024 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha224 | ||
1025 | read 10485760/10485760 bytes at offset 3298534883328 | ||
1026 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1027 | @@ -XXX,XX +XXX,XX @@ truncate TEST_DIR/luks-aes-256-xts-plain64-sha256.img --size 4194304MB | ||
1028 | sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain64 --key-size 512 --hash sha256 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain64-sha256.img | ||
1029 | # Open dev | ||
1030 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha256.img qiotest-145-aes-256-xts-plain64-sha256 | ||
1031 | -# Set dev owner | ||
1032 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha256 | ||
1033 | # Write test pattern 0xa7 | ||
1034 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha256 | ||
1035 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha256 | ||
1036 | wrote 10485760/10485760 bytes at offset 104857600 | ||
1037 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1038 | |||
1039 | # Write test pattern 0x13 | ||
1040 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha256 | ||
1041 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha256 | ||
1042 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1043 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1044 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1045 | |||
1046 | # Open dev | ||
1047 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha256.img qiotest-145-aes-256-xts-plain64-sha256 | ||
1048 | -# Set dev owner | ||
1049 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha256 | ||
1050 | # Read test pattern 0x91 | ||
1051 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha256 | ||
1052 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha256 | ||
1053 | read 10485760/10485760 bytes at offset 104857600 | ||
1054 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1055 | |||
1056 | # Read test pattern 0x5e | ||
1057 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha256 | ||
1058 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha256 | ||
1059 | read 10485760/10485760 bytes at offset 3298534883328 | ||
1060 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1061 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/luks-aes-256-xts-plain64-sha256.img', fmt=luks size=4398046 | ||
1062 | |||
1063 | # Open dev | ||
1064 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha256.img qiotest-145-aes-256-xts-plain64-sha256 | ||
1065 | -# Set dev owner | ||
1066 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha256 | ||
1067 | # Write test pattern 0xa7 | ||
1068 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha256 | ||
1069 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha256 | ||
1070 | wrote 10485760/10485760 bytes at offset 104857600 | ||
1071 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1072 | |||
1073 | # Write test pattern 0x13 | ||
1074 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha256 | ||
1075 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha256 | ||
1076 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1077 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1078 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1079 | |||
1080 | # Open dev | ||
1081 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha256.img qiotest-145-aes-256-xts-plain64-sha256 | ||
1082 | -# Set dev owner | ||
1083 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha256 | ||
1084 | # Read test pattern 0x91 | ||
1085 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha256 | ||
1086 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha256 | ||
1087 | read 10485760/10485760 bytes at offset 104857600 | ||
1088 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1089 | |||
1090 | # Read test pattern 0x5e | ||
1091 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha256 | ||
1092 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha256 | ||
1093 | read 10485760/10485760 bytes at offset 3298534883328 | ||
1094 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1095 | @@ -XXX,XX +XXX,XX @@ truncate TEST_DIR/luks-aes-256-xts-plain64-sha384.img --size 4194304MB | ||
1096 | sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain64 --key-size 512 --hash sha384 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain64-sha384.img | ||
1097 | # Open dev | ||
1098 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha384.img qiotest-145-aes-256-xts-plain64-sha384 | ||
1099 | -# Set dev owner | ||
1100 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
1101 | # Write test pattern 0xa7 | ||
1102 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
1103 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
1104 | wrote 10485760/10485760 bytes at offset 104857600 | ||
1105 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1106 | |||
1107 | # Write test pattern 0x13 | ||
1108 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
1109 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
1110 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1111 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1112 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1113 | |||
1114 | # Open dev | ||
1115 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha384.img qiotest-145-aes-256-xts-plain64-sha384 | ||
1116 | -# Set dev owner | ||
1117 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
1118 | # Read test pattern 0x91 | ||
1119 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
1120 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
1121 | read 10485760/10485760 bytes at offset 104857600 | ||
1122 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1123 | |||
1124 | # Read test pattern 0x5e | ||
1125 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
1126 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
1127 | read 10485760/10485760 bytes at offset 3298534883328 | ||
1128 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1129 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/luks-aes-256-xts-plain64-sha384.img', fmt=luks size=4398046 | ||
1130 | |||
1131 | # Open dev | ||
1132 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha384.img qiotest-145-aes-256-xts-plain64-sha384 | ||
1133 | -# Set dev owner | ||
1134 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
1135 | # Write test pattern 0xa7 | ||
1136 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
1137 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
1138 | wrote 10485760/10485760 bytes at offset 104857600 | ||
1139 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1140 | |||
1141 | # Write test pattern 0x13 | ||
1142 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
1143 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
1144 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1145 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1146 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1147 | |||
1148 | # Open dev | ||
1149 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha384.img qiotest-145-aes-256-xts-plain64-sha384 | ||
1150 | -# Set dev owner | ||
1151 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
1152 | # Read test pattern 0x91 | ||
1153 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
1154 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
1155 | read 10485760/10485760 bytes at offset 104857600 | ||
1156 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1157 | |||
1158 | # Read test pattern 0x5e | ||
1159 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
1160 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha384 | ||
1161 | read 10485760/10485760 bytes at offset 3298534883328 | ||
1162 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1163 | @@ -XXX,XX +XXX,XX @@ truncate TEST_DIR/luks-aes-256-xts-plain64-sha512.img --size 4194304MB | ||
1164 | sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain64 --key-size 512 --hash sha512 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain64-sha512.img | ||
1165 | # Open dev | ||
1166 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha512.img qiotest-145-aes-256-xts-plain64-sha512 | ||
1167 | -# Set dev owner | ||
1168 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
1169 | # Write test pattern 0xa7 | ||
1170 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
1171 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
1172 | wrote 10485760/10485760 bytes at offset 104857600 | ||
1173 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1174 | |||
1175 | # Write test pattern 0x13 | ||
1176 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
1177 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
1178 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1179 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1180 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1181 | |||
1182 | # Open dev | ||
1183 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha512.img qiotest-145-aes-256-xts-plain64-sha512 | ||
1184 | -# Set dev owner | ||
1185 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
1186 | # Read test pattern 0x91 | ||
1187 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
1188 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
1189 | read 10485760/10485760 bytes at offset 104857600 | ||
1190 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1191 | |||
1192 | # Read test pattern 0x5e | ||
1193 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
1194 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
1195 | read 10485760/10485760 bytes at offset 3298534883328 | ||
1196 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1197 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/luks-aes-256-xts-plain64-sha512.img', fmt=luks size=4398046 | ||
1198 | |||
1199 | # Open dev | ||
1200 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha512.img qiotest-145-aes-256-xts-plain64-sha512 | ||
1201 | -# Set dev owner | ||
1202 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
1203 | # Write test pattern 0xa7 | ||
1204 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
1205 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
1206 | wrote 10485760/10485760 bytes at offset 104857600 | ||
1207 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1208 | |||
1209 | # Write test pattern 0x13 | ||
1210 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
1211 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
1212 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1213 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1214 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1215 | |||
1216 | # Open dev | ||
1217 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha512.img qiotest-145-aes-256-xts-plain64-sha512 | ||
1218 | -# Set dev owner | ||
1219 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
1220 | # Read test pattern 0x91 | ||
1221 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
1222 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
1223 | read 10485760/10485760 bytes at offset 104857600 | ||
1224 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1225 | |||
1226 | # Read test pattern 0x5e | ||
1227 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
1228 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-sha512 | ||
1229 | read 10485760/10485760 bytes at offset 3298534883328 | ||
1230 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1231 | @@ -XXX,XX +XXX,XX @@ truncate TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img --size 4194304MB | ||
1232 | sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain64 --key-size 512 --hash ripemd160 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img | ||
1233 | # Open dev | ||
1234 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img qiotest-145-aes-256-xts-plain64-ripemd160 | ||
1235 | -# Set dev owner | ||
1236 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
1237 | # Write test pattern 0xa7 | ||
1238 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
1239 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
1240 | wrote 10485760/10485760 bytes at offset 104857600 | ||
1241 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1242 | |||
1243 | # Write test pattern 0x13 | ||
1244 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
1245 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
1246 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1247 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1248 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1249 | |||
1250 | # Open dev | ||
1251 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img qiotest-145-aes-256-xts-plain64-ripemd160 | ||
1252 | -# Set dev owner | ||
1253 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
1254 | # Read test pattern 0x91 | ||
1255 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
1256 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
1257 | read 10485760/10485760 bytes at offset 104857600 | ||
1258 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1259 | |||
1260 | # Read test pattern 0x5e | ||
1261 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
1262 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
1263 | read 10485760/10485760 bytes at offset 3298534883328 | ||
1264 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1265 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img', fmt=luks size=4398 | ||
1266 | |||
1267 | # Open dev | ||
1268 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img qiotest-145-aes-256-xts-plain64-ripemd160 | ||
1269 | -# Set dev owner | ||
1270 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
1271 | # Write test pattern 0xa7 | ||
1272 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
1273 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
1274 | wrote 10485760/10485760 bytes at offset 104857600 | ||
1275 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1276 | |||
1277 | # Write test pattern 0x13 | ||
1278 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
1279 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
1280 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1281 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1282 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1283 | |||
1284 | # Open dev | ||
1285 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img qiotest-145-aes-256-xts-plain64-ripemd160 | ||
1286 | -# Set dev owner | ||
1287 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
1288 | # Read test pattern 0x91 | ||
1289 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
1290 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
1291 | read 10485760/10485760 bytes at offset 104857600 | ||
1292 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1293 | |||
1294 | # Read test pattern 0x5e | ||
1295 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
1296 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain64-ripemd160 | ||
1297 | read 10485760/10485760 bytes at offset 3298534883328 | ||
1298 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1299 | @@ -XXX,XX +XXX,XX @@ truncate TEST_DIR/luks-aes-256-xts-plain-sha1-pwslot3.img --size 4194304MB | ||
1300 | sudo cryptsetup -q -v luksFormat --cipher aes-xts-plain --key-size 512 --hash sha1 --key-slot 3 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-xts-plain-sha1-pwslot3.img | ||
1301 | # Open dev | ||
1302 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain-sha1-pwslot3.img qiotest-145-aes-256-xts-plain-sha1-pwslot3 | ||
1303 | -# Set dev owner | ||
1304 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain-sha1-pwslot3 | ||
1305 | # Write test pattern 0xa7 | ||
1306 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain-sha1-pwslot3 | ||
1307 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain-sha1-pwslot3 | ||
1308 | wrote 10485760/10485760 bytes at offset 104857600 | ||
1309 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1310 | |||
1311 | # Write test pattern 0x13 | ||
1312 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain-sha1-pwslot3 | ||
1313 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain-sha1-pwslot3 | ||
1314 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1315 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1316 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1317 | |||
1318 | # Open dev | ||
1319 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain-sha1-pwslot3.img qiotest-145-aes-256-xts-plain-sha1-pwslot3 | ||
1320 | -# Set dev owner | ||
1321 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain-sha1-pwslot3 | ||
1322 | # Read test pattern 0x91 | ||
1323 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain-sha1-pwslot3 | ||
1324 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain-sha1-pwslot3 | ||
1325 | read 10485760/10485760 bytes at offset 104857600 | ||
1326 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1327 | |||
1328 | # Read test pattern 0x5e | ||
1329 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain-sha1-pwslot3 | ||
1330 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain-sha1-pwslot3 | ||
1331 | read 10485760/10485760 bytes at offset 3298534883328 | ||
1332 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1333 | @@ -XXX,XX +XXX,XX @@ sudo cryptsetup -q -v luksAddKey TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots | ||
1334 | sudo cryptsetup -q -v luksAddKey TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img --key-slot 7 --key-file - --iter-time 10 TEST_DIR/passwd.txt | ||
1335 | # Open dev | ||
1336 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img qiotest-145-aes-256-xts-plain-sha1-pwallslots | ||
1337 | -# Set dev owner | ||
1338 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain-sha1-pwallslots | ||
1339 | # Write test pattern 0xa7 | ||
1340 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain-sha1-pwallslots | ||
1341 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain-sha1-pwallslots | ||
1342 | wrote 10485760/10485760 bytes at offset 104857600 | ||
1343 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1344 | |||
1345 | # Write test pattern 0x13 | ||
1346 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain-sha1-pwallslots | ||
1347 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain-sha1-pwallslots | ||
1348 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1349 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1350 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1351 | |||
1352 | # Open dev | ||
1353 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img qiotest-145-aes-256-xts-plain-sha1-pwallslots | ||
1354 | -# Set dev owner | ||
1355 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain-sha1-pwallslots | ||
1356 | # Read test pattern 0x91 | ||
1357 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain-sha1-pwallslots | ||
1358 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain-sha1-pwallslots | ||
1359 | read 10485760/10485760 bytes at offset 104857600 | ||
1360 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1361 | |||
1362 | # Read test pattern 0x5e | ||
1363 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain-sha1-pwallslots | ||
1364 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain-sha1-pwallslots | ||
1365 | read 10485760/10485760 bytes at offset 3298534883328 | ||
1366 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1367 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img', fmt=luks size= | ||
1368 | |||
1369 | # Open dev | ||
1370 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img qiotest-145-aes-256-xts-plain-sha1-pwallslots | ||
1371 | -# Set dev owner | ||
1372 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain-sha1-pwallslots | ||
1373 | # Write test pattern 0xa7 | ||
1374 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain-sha1-pwallslots | ||
1375 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain-sha1-pwallslots | ||
1376 | wrote 10485760/10485760 bytes at offset 104857600 | ||
1377 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1378 | |||
1379 | # Write test pattern 0x13 | ||
1380 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain-sha1-pwallslots | ||
1381 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain-sha1-pwallslots | ||
1382 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1383 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1384 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1385 | |||
1386 | # Open dev | ||
1387 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img qiotest-145-aes-256-xts-plain-sha1-pwallslots | ||
1388 | -# Set dev owner | ||
1389 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain-sha1-pwallslots | ||
1390 | # Read test pattern 0x91 | ||
1391 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain-sha1-pwallslots | ||
1392 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain-sha1-pwallslots | ||
1393 | read 10485760/10485760 bytes at offset 104857600 | ||
1394 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1395 | |||
1396 | # Read test pattern 0x5e | ||
1397 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-xts-plain-sha1-pwallslots | ||
1398 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-xts-plain-sha1-pwallslots | ||
1399 | read 10485760/10485760 bytes at offset 3298534883328 | ||
1400 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1401 | @@ -XXX,XX +XXX,XX @@ truncate TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img --size 4194304MB | ||
1402 | sudo cryptsetup -q -v luksFormat --cipher aes-cbc-essiv:sha256 --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img | ||
1403 | # Open dev | ||
1404 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img qiotest-145-aes-256-cbc-essiv-auto-sha1 | ||
1405 | -# Set dev owner | ||
1406 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1 | ||
1407 | # Write test pattern 0xa7 | ||
1408 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1 | ||
1409 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1 | ||
1410 | wrote 10485760/10485760 bytes at offset 104857600 | ||
1411 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1412 | |||
1413 | # Write test pattern 0x13 | ||
1414 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1 | ||
1415 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1 | ||
1416 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1417 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1418 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1419 | |||
1420 | # Open dev | ||
1421 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img qiotest-145-aes-256-cbc-essiv-auto-sha1 | ||
1422 | -# Set dev owner | ||
1423 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1 | ||
1424 | # Read test pattern 0x91 | ||
1425 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1 | ||
1426 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1 | ||
1427 | read 10485760/10485760 bytes at offset 104857600 | ||
1428 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1429 | |||
1430 | # Read test pattern 0x5e | ||
1431 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1 | ||
1432 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1 | ||
1433 | read 10485760/10485760 bytes at offset 3298534883328 | ||
1434 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1435 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img', fmt=luks size=439804 | ||
1436 | |||
1437 | # Open dev | ||
1438 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img qiotest-145-aes-256-cbc-essiv-auto-sha1 | ||
1439 | -# Set dev owner | ||
1440 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1 | ||
1441 | # Write test pattern 0xa7 | ||
1442 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1 | ||
1443 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1 | ||
1444 | wrote 10485760/10485760 bytes at offset 104857600 | ||
1445 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1446 | |||
1447 | # Write test pattern 0x13 | ||
1448 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1 | ||
1449 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1 | ||
1450 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1451 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1452 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1453 | |||
1454 | # Open dev | ||
1455 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img qiotest-145-aes-256-cbc-essiv-auto-sha1 | ||
1456 | -# Set dev owner | ||
1457 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1 | ||
1458 | # Read test pattern 0x91 | ||
1459 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1 | ||
1460 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1 | ||
1461 | read 10485760/10485760 bytes at offset 104857600 | ||
1462 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1463 | |||
1464 | # Read test pattern 0x5e | ||
1465 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1 | ||
1466 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-essiv-auto-sha1 | ||
1467 | read 10485760/10485760 bytes at offset 3298534883328 | ||
1468 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1469 | @@ -XXX,XX +XXX,XX @@ truncate TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img --size 4194304MB | ||
1470 | sudo cryptsetup -q -v luksFormat --cipher aes-cbc-plain64:sha256 --key-size 256 --hash sha1 --key-slot 0 --key-file - --iter-time 10 TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img | ||
1471 | # Open dev | ||
1472 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img qiotest-145-aes-256-cbc-plain64-sha256-sha1 | ||
1473 | -# Set dev owner | ||
1474 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1 | ||
1475 | # Write test pattern 0xa7 | ||
1476 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1 | ||
1477 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1 | ||
1478 | wrote 10485760/10485760 bytes at offset 104857600 | ||
1479 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1480 | |||
1481 | # Write test pattern 0x13 | ||
1482 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1 | ||
1483 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1 | ||
1484 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1485 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1486 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1487 | |||
1488 | # Open dev | ||
1489 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img qiotest-145-aes-256-cbc-plain64-sha256-sha1 | ||
1490 | -# Set dev owner | ||
1491 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1 | ||
1492 | # Read test pattern 0x91 | ||
1493 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1 | ||
1494 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1 | ||
1495 | read 10485760/10485760 bytes at offset 104857600 | ||
1496 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1497 | |||
1498 | # Read test pattern 0x5e | ||
1499 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1 | ||
1500 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1 | ||
1501 | read 10485760/10485760 bytes at offset 3298534883328 | ||
1502 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1503 | @@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img', fmt=luks size=43 | ||
1504 | |||
1505 | # Open dev | ||
1506 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img qiotest-145-aes-256-cbc-plain64-sha256-sha1 | ||
1507 | -# Set dev owner | ||
1508 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1 | ||
1509 | # Write test pattern 0xa7 | ||
1510 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1 | ||
1511 | qemu-io -c write -P 0xa7 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1 | ||
1512 | wrote 10485760/10485760 bytes at offset 104857600 | ||
1513 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1514 | |||
1515 | # Write test pattern 0x13 | ||
1516 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1 | ||
1517 | qemu-io -c write -P 0x13 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1 | ||
1518 | wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1519 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1520 | @@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 3298534883328 | ||
1521 | |||
1522 | # Open dev | ||
1523 | sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img qiotest-145-aes-256-cbc-plain64-sha256-sha1 | ||
1524 | -# Set dev owner | ||
1525 | -sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1 | ||
1526 | # Read test pattern 0x91 | ||
1527 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1 | ||
1528 | qemu-io -c read -P 0x91 100M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1 | ||
1529 | read 10485760/10485760 bytes at offset 104857600 | ||
1530 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1531 | |||
1532 | # Read test pattern 0x5e | ||
1533 | +sudo chown UID:GID /dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1 | ||
1534 | qemu-io -c read -P 0x5e 3145728M 10M --image-opts driver=file,filename=/dev/mapper/qiotest-145-aes-256-cbc-plain64-sha256-sha1 | ||
1535 | read 10485760/10485760 bytes at offset 3298534883328 | ||
1536 | 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
1537 | -- | ||
1538 | 2.9.4 | ||
1539 | |||
1540 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | A user may specify a relative path for accessing qemu, qemu-img, etc. | ||
2 | through environment variables ($QEMU_PROG and friends) or a symlink. | ||
3 | 1 | ||
4 | If a test decides to change its working directory, relative paths will | ||
5 | cease to work, however. Work around this by making all of the paths to | ||
6 | programs that should undergo testing absolute. Besides "realpath", we | ||
7 | also have to use "type -p" to support programs in $PATH. | ||
8 | |||
9 | As a side effect, this fixes specifying these programs as symlinks for | ||
10 | out-of-tree builds: Before, you would have to create two symlinks, one | ||
11 | in the build and one in the source tree (the first one for common.config | ||
12 | to find, the second one for the iotest to use). Now it is sufficient to | ||
13 | create one in the build tree because common.config will resolve it. | ||
14 | |||
15 | Reported-by: Kevin Wolf <kwolf@redhat.com> | ||
16 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
17 | Message-id: 20170702150510.23276-2-mreitz@redhat.com | ||
18 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
19 | Tested-by: Eric Blake <eblake@redhat.com> | ||
20 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
21 | --- | ||
22 | tests/qemu-iotests/common.config | 11 +++++++++++ | ||
23 | 1 file changed, 11 insertions(+) | ||
24 | |||
25 | diff --git a/tests/qemu-iotests/common.config b/tests/qemu-iotests/common.config | ||
26 | index XXXXXXX..XXXXXXX 100644 | ||
27 | --- a/tests/qemu-iotests/common.config | ||
28 | +++ b/tests/qemu-iotests/common.config | ||
29 | @@ -XXX,XX +XXX,XX @@ if [ -z "$QEMU_VXHS_PROG" ]; then | ||
30 | export QEMU_VXHS_PROG="`set_prog_path qnio_server`" | ||
31 | fi | ||
32 | |||
33 | +export QEMU_PROG=$(realpath -- "$(type -p "$QEMU_PROG")") | ||
34 | +export QEMU_IMG_PROG=$(realpath -- "$(type -p "$QEMU_IMG_PROG")") | ||
35 | +export QEMU_IO_PROG=$(realpath -- "$(type -p "$QEMU_IO_PROG")") | ||
36 | +export QEMU_NBD_PROG=$(realpath -- "$(type -p "$QEMU_NBD_PROG")") | ||
37 | + | ||
38 | +# This program is not built as part of qemu but (possibly) provided by the | ||
39 | +# system, so it may not be present at all | ||
40 | +if [ -n "$QEMU_VXHS_PROG" ]; then | ||
41 | + export QEMU_VXHS_PROG=$(realpath -- "$(type -p "$QEMU_VXHS_PROG")") | ||
42 | +fi | ||
43 | + | ||
44 | _qemu_wrapper() | ||
45 | { | ||
46 | ( | ||
47 | -- | ||
48 | 2.9.4 | ||
49 | |||
50 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
2 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
3 | Message-id: 20170702150510.23276-3-mreitz@redhat.com | ||
4 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
5 | --- | ||
6 | tests/qemu-iotests/126 | 105 +++++++++++++++++++++++++++++++++++++++++++++ | ||
7 | tests/qemu-iotests/126.out | 23 ++++++++++ | ||
8 | tests/qemu-iotests/group | 1 + | ||
9 | 3 files changed, 129 insertions(+) | ||
10 | create mode 100755 tests/qemu-iotests/126 | ||
11 | create mode 100644 tests/qemu-iotests/126.out | ||
12 | 1 | ||
13 | diff --git a/tests/qemu-iotests/126 b/tests/qemu-iotests/126 | ||
14 | new file mode 100755 | ||
15 | index XXXXXXX..XXXXXXX | ||
16 | --- /dev/null | ||
17 | +++ b/tests/qemu-iotests/126 | ||
18 | @@ -XXX,XX +XXX,XX @@ | ||
19 | +#!/bin/bash | ||
20 | +# | ||
21 | +# Tests handling of colons in filenames (which may be confused with protocol | ||
22 | +# prefixes) | ||
23 | +# | ||
24 | +# Copyright (C) 2017 Red Hat, Inc. | ||
25 | +# | ||
26 | +# This program is free software; you can redistribute it and/or modify | ||
27 | +# it under the terms of the GNU General Public License as published by | ||
28 | +# the Free Software Foundation; either version 2 of the License, or | ||
29 | +# (at your option) any later version. | ||
30 | +# | ||
31 | +# This program is distributed in the hope that it will be useful, | ||
32 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
33 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
34 | +# GNU General Public License for more details. | ||
35 | +# | ||
36 | +# You should have received a copy of the GNU General Public License | ||
37 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
38 | +# | ||
39 | + | ||
40 | +# creator | ||
41 | +owner=mreitz@redhat.com | ||
42 | + | ||
43 | +seq="$(basename $0)" | ||
44 | +echo "QA output created by $seq" | ||
45 | + | ||
46 | +here="$PWD" | ||
47 | +status=1 # failure is the default! | ||
48 | + | ||
49 | +# get standard environment, filters and checks | ||
50 | +. ./common.rc | ||
51 | +. ./common.filter | ||
52 | + | ||
53 | +# Needs backing file support | ||
54 | +_supported_fmt qcow qcow2 qed vmdk | ||
55 | +# This is the default protocol (and we want to test the difference between | ||
56 | +# colons which separate a protocol prefix from the rest and colons which are | ||
57 | +# just part of the filename, so we cannot test protocols which require a prefix) | ||
58 | +_supported_proto file | ||
59 | +_supported_os Linux | ||
60 | + | ||
61 | +echo | ||
62 | +echo '=== Testing plain files ===' | ||
63 | +echo | ||
64 | + | ||
65 | +# A colon after a slash is not a protocol prefix separator | ||
66 | +TEST_IMG="$TEST_DIR/a:b.$IMGFMT" _make_test_img 64M | ||
67 | +_rm_test_img "$TEST_DIR/a:b.$IMGFMT" | ||
68 | + | ||
69 | +# But if you want to be really sure, you can do this | ||
70 | +TEST_IMG="file:$TEST_DIR/a:b.$IMGFMT" _make_test_img 64M | ||
71 | +_rm_test_img "$TEST_DIR/a:b.$IMGFMT" | ||
72 | + | ||
73 | + | ||
74 | +echo | ||
75 | +echo '=== Testing relative backing filename resolution ===' | ||
76 | +echo | ||
77 | + | ||
78 | +BASE_IMG="$TEST_DIR/image:base.$IMGFMT" | ||
79 | +TOP_IMG="$TEST_DIR/image:top.$IMGFMT" | ||
80 | + | ||
81 | +TEST_IMG=$BASE_IMG _make_test_img 64M | ||
82 | +TEST_IMG=$TOP_IMG _make_test_img -b ./image:base.$IMGFMT | ||
83 | + | ||
84 | +# The default cluster size depends on the image format | ||
85 | +TEST_IMG=$TOP_IMG _img_info | grep -v 'cluster_size' | ||
86 | + | ||
87 | +_rm_test_img "$BASE_IMG" | ||
88 | +_rm_test_img "$TOP_IMG" | ||
89 | + | ||
90 | + | ||
91 | +# Do another test where we access both top and base without any slash in them | ||
92 | +echo | ||
93 | +pushd "$TEST_DIR" >/dev/null | ||
94 | + | ||
95 | +BASE_IMG="base.$IMGFMT" | ||
96 | +TOP_IMG="file:image:top.$IMGFMT" | ||
97 | + | ||
98 | +TEST_IMG=$BASE_IMG _make_test_img 64M | ||
99 | +TEST_IMG=$TOP_IMG _make_test_img -b "$BASE_IMG" | ||
100 | + | ||
101 | +TEST_IMG=$TOP_IMG _img_info | grep -v 'cluster_size' | ||
102 | + | ||
103 | +_rm_test_img "$BASE_IMG" | ||
104 | +_rm_test_img "image:top.$IMGFMT" | ||
105 | + | ||
106 | +popd >/dev/null | ||
107 | + | ||
108 | +# Note that we could also do the same test with BASE_IMG=file:image:base.$IMGFMT | ||
109 | +# -- but behavior for that case is a bit strange. Protocol-prefixed paths are | ||
110 | +# in a sense always absolute paths, so such paths will never be combined with | ||
111 | +# the path of the overlay. But since "image:base.$IMGFMT" is actually a | ||
112 | +# relative path, it will always be evaluated relative to qemu's CWD (but not | ||
113 | +# relative to the overlay!). While this is more or less intended, it is still | ||
114 | +# pretty strange and thus not something that is tested here. | ||
115 | +# (The root of the issue is the use of a relative path with a protocol prefix. | ||
116 | +# This may always give you weird results because in one sense, qemu considers | ||
117 | +# such paths absolute, whereas in another, they are still relative.) | ||
118 | + | ||
119 | + | ||
120 | +# success, all done | ||
121 | +echo '*** done' | ||
122 | +rm -f $seq.full | ||
123 | +status=0 | ||
124 | diff --git a/tests/qemu-iotests/126.out b/tests/qemu-iotests/126.out | ||
125 | new file mode 100644 | ||
126 | index XXXXXXX..XXXXXXX | ||
127 | --- /dev/null | ||
128 | +++ b/tests/qemu-iotests/126.out | ||
129 | @@ -XXX,XX +XXX,XX @@ | ||
130 | +QA output created by 126 | ||
131 | + | ||
132 | +=== Testing plain files === | ||
133 | + | ||
134 | +Formatting 'TEST_DIR/a:b.IMGFMT', fmt=IMGFMT size=67108864 | ||
135 | +Formatting 'TEST_DIR/a:b.IMGFMT', fmt=IMGFMT size=67108864 | ||
136 | + | ||
137 | +=== Testing relative backing filename resolution === | ||
138 | + | ||
139 | +Formatting 'TEST_DIR/image:base.IMGFMT', fmt=IMGFMT size=67108864 | ||
140 | +Formatting 'TEST_DIR/image:top.IMGFMT', fmt=IMGFMT size=67108864 backing_file=./image:base.IMGFMT | ||
141 | +image: TEST_DIR/image:top.IMGFMT | ||
142 | +file format: IMGFMT | ||
143 | +virtual size: 64M (67108864 bytes) | ||
144 | +backing file: ./image:base.IMGFMT (actual path: TEST_DIR/./image:base.IMGFMT) | ||
145 | + | ||
146 | +Formatting 'base.IMGFMT', fmt=IMGFMT size=67108864 | ||
147 | +Formatting 'file:image:top.IMGFMT', fmt=IMGFMT size=67108864 backing_file=base.IMGFMT | ||
148 | +image: ./image:top.IMGFMT | ||
149 | +file format: IMGFMT | ||
150 | +virtual size: 64M (67108864 bytes) | ||
151 | +backing file: base.IMGFMT (actual path: ./base.IMGFMT) | ||
152 | +*** done | ||
153 | diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group | ||
154 | index XXXXXXX..XXXXXXX 100644 | ||
155 | --- a/tests/qemu-iotests/group | ||
156 | +++ b/tests/qemu-iotests/group | ||
157 | @@ -XXX,XX +XXX,XX @@ | ||
158 | 122 rw auto | ||
159 | 123 rw auto quick | ||
160 | 124 rw auto backing | ||
161 | +126 rw auto backing | ||
162 | 128 rw auto quick | ||
163 | 129 rw auto quick | ||
164 | 130 rw auto quick | ||
165 | -- | ||
166 | 2.9.4 | ||
167 | |||
168 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Eric Blake <eblake@redhat.com> | ||
2 | 1 | ||
3 | POSIX says that backslashes in the arguments to 'echo', as well as | ||
4 | any use of 'echo -n' and 'echo -e', are non-portable; it recommends | ||
5 | people should favor 'printf' instead. This is definitely true where | ||
6 | we do not control which shell is running (such as in makefile snippets | ||
7 | or in documentation examples). But even for scripts where we | ||
8 | require bash (and therefore, where echo does what we want by default), | ||
9 | it is still possible to use 'shopt -s xpg_echo' to change bash's | ||
10 | behavior of echo. And setting a good example never hurts when we are | ||
11 | not sure if a snippet will be copied from a bash-only script to a | ||
12 | general shell script (although I don't change the use of non-portable | ||
13 | \e for ESC when we know the running shell is bash). | ||
14 | |||
15 | Replace 'echo -n "..."' with 'printf %s "..."', and 'echo -e "..."' | ||
16 | with 'printf %b "...\n"', with the optimization that the %s/%b | ||
17 | argument can be omitted if the string being printed is a strict | ||
18 | literal with no '%', '$', or '`' (we could technically also make | ||
19 | this optimization when there are $ or `` substitutions but where | ||
20 | we can prove their results will not be problematic, but proving | ||
21 | that such substitutions are safe makes the patch less trivial | ||
22 | compared to just being consistent). | ||
23 | |||
24 | In the qemu-iotests check script, fix unusual shell quoting | ||
25 | that would result in word-splitting if 'date' outputs a space. | ||
26 | |||
27 | In test 051, take an opportunity to shorten the line. | ||
28 | |||
29 | In test 068, get rid of a pointless second invocation of bash. | ||
30 | |||
31 | CC: qemu-trivial@nongnu.org | ||
32 | Signed-off-by: Eric Blake <eblake@redhat.com> | ||
33 | Message-id: 20170703180950.9895-1-eblake@redhat.com | ||
34 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
35 | --- | ||
36 | tests/tcg/cris/Makefile | 8 ++++---- | ||
37 | qemu-options.hx | 4 ++-- | ||
38 | tests/multiboot/run_test.sh | 10 +++++----- | ||
39 | tests/qemu-iotests/051 | 7 ++++--- | ||
40 | tests/qemu-iotests/068 | 2 +- | ||
41 | tests/qemu-iotests/142 | 48 ++++++++++++++++++++++----------------------- | ||
42 | tests/qemu-iotests/171 | 14 ++++++------- | ||
43 | tests/qemu-iotests/check | 18 ++++++++--------- | ||
44 | tests/rocker/all | 10 +++++----- | ||
45 | 9 files changed, 61 insertions(+), 60 deletions(-) | ||
46 | |||
47 | diff --git a/tests/tcg/cris/Makefile b/tests/tcg/cris/Makefile | ||
48 | index XXXXXXX..XXXXXXX 100644 | ||
49 | --- a/tests/tcg/cris/Makefile | ||
50 | +++ b/tests/tcg/cris/Makefile | ||
51 | @@ -XXX,XX +XXX,XX @@ check_addcv17.tst: crtv10.o sysv10.o | ||
52 | build: $(CRT) $(SYS) $(TESTCASES) | ||
53 | |||
54 | check: $(CRT) $(SYS) $(TESTCASES) | ||
55 | - @echo -e "\nQEMU simulator." | ||
56 | + @printf "\nQEMU simulator.\n" | ||
57 | for case in $(TESTCASES); do \ | ||
58 | - echo -n "$$case "; \ | ||
59 | + printf %s "$$case "; \ | ||
60 | SIMARGS=; \ | ||
61 | case $$case in *v17*) SIMARGS="-cpu crisv17";; esac; \ | ||
62 | $(SIM) $$SIMARGS ./$$case; \ | ||
63 | done | ||
64 | check-g: $(CRT) $(SYS) $(TESTCASES) | ||
65 | - @echo -e "\nGDB simulator." | ||
66 | + @printf "\nGDB simulator.\n" | ||
67 | @for case in $(TESTCASES); do \ | ||
68 | - echo -n "$$case "; \ | ||
69 | + printf %s "$$case "; \ | ||
70 | $(SIMG) $$case; \ | ||
71 | done | ||
72 | |||
73 | diff --git a/qemu-options.hx b/qemu-options.hx | ||
74 | index XXXXXXX..XXXXXXX 100644 | ||
75 | --- a/qemu-options.hx | ||
76 | +++ b/qemu-options.hx | ||
77 | @@ -XXX,XX +XXX,XX @@ The simplest (insecure) usage is to provide the secret inline | ||
78 | |||
79 | The simplest secure usage is to provide the secret via a file | ||
80 | |||
81 | - # echo -n "letmein" > mypasswd.txt | ||
82 | + # printf "letmein" > mypasswd.txt | ||
83 | # $QEMU -object secret,id=sec0,file=mypasswd.txt,format=raw | ||
84 | |||
85 | For greater security, AES-256-CBC should be used. To illustrate usage, | ||
86 | @@ -XXX,XX +XXX,XX @@ telling openssl to base64 encode the result, but it could be left | ||
87 | as raw bytes if desired. | ||
88 | |||
89 | @example | ||
90 | - # SECRET=$(echo -n "letmein" | | ||
91 | + # SECRET=$(printf "letmein" | | ||
92 | openssl enc -aes-256-cbc -a -K $KEY -iv $IV) | ||
93 | @end example | ||
94 | |||
95 | diff --git a/tests/multiboot/run_test.sh b/tests/multiboot/run_test.sh | ||
96 | index XXXXXXX..XXXXXXX 100755 | ||
97 | --- a/tests/multiboot/run_test.sh | ||
98 | +++ b/tests/multiboot/run_test.sh | ||
99 | @@ -XXX,XX +XXX,XX @@ run_qemu() { | ||
100 | local kernel=$1 | ||
101 | shift | ||
102 | |||
103 | - echo -e "\n\n=== Running test case: $kernel $@ ===\n" >> test.log | ||
104 | + printf %b "\n\n=== Running test case: $kernel $@ ===\n\n" >> test.log | ||
105 | |||
106 | $QEMU \ | ||
107 | -kernel $kernel \ | ||
108 | @@ -XXX,XX +XXX,XX @@ for t in mmap modules; do | ||
109 | pass=1 | ||
110 | |||
111 | if [ $debugexit != 1 ]; then | ||
112 | - echo -e "\e[31m ?? \e[0m $t (no debugexit used, exit code $ret)" | ||
113 | + printf %b "\e[31m ?? \e[0m $t (no debugexit used, exit code $ret)\n" | ||
114 | pass=0 | ||
115 | elif [ $ret != 0 ]; then | ||
116 | - echo -e "\e[31mFAIL\e[0m $t (exit code $ret)" | ||
117 | + printf %b "\e[31mFAIL\e[0m $t (exit code $ret)\n" | ||
118 | pass=0 | ||
119 | fi | ||
120 | |||
121 | if ! diff $t.out test.log > /dev/null 2>&1; then | ||
122 | - echo -e "\e[31mFAIL\e[0m $t (output difference)" | ||
123 | + printf %b "\e[31mFAIL\e[0m $t (output difference)\n" | ||
124 | diff -u $t.out test.log | ||
125 | pass=0 | ||
126 | fi | ||
127 | |||
128 | if [ $pass == 1 ]; then | ||
129 | - echo -e "\e[32mPASS\e[0m $t" | ||
130 | + printf %b "\e[32mPASS\e[0m $t\n" | ||
131 | fi | ||
132 | |||
133 | done | ||
134 | diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051 | ||
135 | index XXXXXXX..XXXXXXX 100755 | ||
136 | --- a/tests/qemu-iotests/051 | ||
137 | +++ b/tests/qemu-iotests/051 | ||
138 | @@ -XXX,XX +XXX,XX @@ run_qemu -drive driver=null-co,cache=invalid_value | ||
139 | # Test 142 checks the direct=on cases | ||
140 | |||
141 | for cache in writeback writethrough unsafe invalid_value; do | ||
142 | - echo -e "info block\ninfo block file\ninfo block backing\ninfo block backing-file" | \ | ||
143 | + printf "info block %s\n" '' file backing backing-file | \ | ||
144 | run_qemu -drive file="$TEST_IMG",cache=$cache,backing.file.filename="$TEST_IMG.base",backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=$device_id -nodefaults | ||
145 | done | ||
146 | |||
147 | @@ -XXX,XX +XXX,XX @@ echo "qemu-io $device_id \"write -P 0x22 0 4k\"" | run_qemu -drive file="$TEST_I | ||
148 | |||
149 | $QEMU_IO -c "read -P 0x22 0 4k" "$TEST_IMG" | _filter_qemu_io | ||
150 | |||
151 | -echo -e "qemu-io $device_id \"write -P 0x33 0 4k\"\ncommit $device_id" | run_qemu -drive file="$TEST_IMG",snapshot=on,if=none,id=$device_id\ | ||
152 | - | _filter_qemu_io | ||
153 | +printf %b "qemu-io $device_id \"write -P 0x33 0 4k\"\ncommit $device_id\n" | | ||
154 | + run_qemu -drive file="$TEST_IMG",snapshot=on,if=none,id=$device_id | | ||
155 | + _filter_qemu_io | ||
156 | |||
157 | $QEMU_IO -c "read -P 0x33 0 4k" "$TEST_IMG" | _filter_qemu_io | ||
158 | |||
159 | diff --git a/tests/qemu-iotests/068 b/tests/qemu-iotests/068 | ||
160 | index XXXXXXX..XXXXXXX 100755 | ||
161 | --- a/tests/qemu-iotests/068 | ||
162 | +++ b/tests/qemu-iotests/068 | ||
163 | @@ -XXX,XX +XXX,XX @@ for extra_args in \ | ||
164 | _make_test_img $IMG_SIZE | ||
165 | |||
166 | # Give qemu some time to boot before saving the VM state | ||
167 | - bash -c 'sleep 1; echo -e "savevm 0\nquit"' | _qemu $extra_args | ||
168 | + { sleep 1; printf "savevm 0\nquit\n"; } | _qemu $extra_args | ||
169 | # Now try to continue from that VM state (this should just work) | ||
170 | echo quit | _qemu $extra_args -loadvm 0 | ||
171 | done | ||
172 | diff --git a/tests/qemu-iotests/142 b/tests/qemu-iotests/142 | ||
173 | index XXXXXXX..XXXXXXX 100755 | ||
174 | --- a/tests/qemu-iotests/142 | ||
175 | +++ b/tests/qemu-iotests/142 | ||
176 | @@ -XXX,XX +XXX,XX @@ function check_cache_all() | ||
177 | # cache.direct is supposed to be inherited by both bs->file and | ||
178 | # bs->backing | ||
179 | |||
180 | - echo -e "cache.direct=on on none0" | ||
181 | + printf "cache.direct=on on none0\n" | ||
182 | echo "$hmp_cmds" | run_qemu -drive "$files","$ids",cache.direct=on | grep -e "Cache" -e "[Cc]annot|[Cc]ould not|[Cc]an't" | ||
183 | - echo -e "\ncache.direct=on on file" | ||
184 | + printf "\ncache.direct=on on file\n" | ||
185 | echo "$hmp_cmds" | run_qemu -drive "$files","$ids",file.cache.direct=on | grep -e "Cache" -e "[Cc]annot|[Cc]ould not|[Cc]an't" | ||
186 | - echo -e "\ncache.direct=on on backing" | ||
187 | + printf "\ncache.direct=on on backing\n" | ||
188 | echo "$hmp_cmds" | run_qemu -drive "$files","$ids",backing.cache.direct=on | grep -e "Cache" -e "[Cc]annot|[Cc]ould not|[Cc]an't" | ||
189 | - echo -e "\ncache.direct=on on backing-file" | ||
190 | + printf "\ncache.direct=on on backing-file\n" | ||
191 | echo "$hmp_cmds" | run_qemu -drive "$files","$ids",backing.file.cache.direct=on | grep -e "Cache" -e "[Cc]annot|[Cc]ould not|[Cc]an't" | ||
192 | |||
193 | # cache.writeback is supposed to be inherited by bs->backing; bs->file | ||
194 | # always gets cache.writeback=on | ||
195 | |||
196 | - echo -e "\n\ncache.writeback=off on none0" | ||
197 | + printf "\n\ncache.writeback=off on none0\n" | ||
198 | echo "$hmp_cmds" | run_qemu -drive "$files","$ids",cache.writeback=off | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" | ||
199 | - echo -e "\ncache.writeback=off on file" | ||
200 | + printf "\ncache.writeback=off on file\n" | ||
201 | echo "$hmp_cmds" | run_qemu -drive "$files","$ids",file.cache.writeback=off | grep -e "doesn't" -e "does not" | ||
202 | - echo -e "\ncache.writeback=off on backing" | ||
203 | + printf "\ncache.writeback=off on backing\n" | ||
204 | echo "$hmp_cmds" | run_qemu -drive "$files","$ids",backing.cache.writeback=off | grep -e "doesn't" -e "does not" | ||
205 | - echo -e "\ncache.writeback=off on backing-file" | ||
206 | + printf "\ncache.writeback=off on backing-file\n" | ||
207 | echo "$hmp_cmds" | run_qemu -drive "$files","$ids",backing.file.cache.writeback=off | grep -e "doesn't" -e "does not" | ||
208 | |||
209 | # cache.no-flush is supposed to be inherited by both bs->file and bs->backing | ||
210 | |||
211 | - echo -e "\n\ncache.no-flush=on on none0" | ||
212 | + printf "\n\ncache.no-flush=on on none0\n" | ||
213 | echo "$hmp_cmds" | run_qemu -drive "$files","$ids",cache.no-flush=on | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" | ||
214 | - echo -e "\ncache.no-flush=on on file" | ||
215 | + printf "\ncache.no-flush=on on file\n" | ||
216 | echo "$hmp_cmds" | run_qemu -drive "$files","$ids",file.cache.no-flush=on | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" | ||
217 | - echo -e "\ncache.no-flush=on on backing" | ||
218 | + printf "\ncache.no-flush=on on backing\n" | ||
219 | echo "$hmp_cmds" | run_qemu -drive "$files","$ids",backing.cache.no-flush=on | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" | ||
220 | - echo -e "\ncache.no-flush=on on backing-file" | ||
221 | + printf "\ncache.no-flush=on on backing-file\n" | ||
222 | echo "$hmp_cmds" | run_qemu -drive "$files","$ids",backing.file.cache.no-flush=on | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" | ||
223 | } | ||
224 | |||
225 | @@ -XXX,XX +XXX,XX @@ function check_cache_all_separate() | ||
226 | { | ||
227 | # Check cache.direct | ||
228 | |||
229 | - echo -e "cache.direct=on on blk" | ||
230 | + printf "cache.direct=on on blk\n" | ||
231 | echo "$hmp_cmds" | run_qemu -drive "$drv_bkfile" -drive "$drv_bk" -drive "$drv_file" -drive "$drv_img",cache.direct=on | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" | ||
232 | - echo -e "\ncache.direct=on on file" | ||
233 | + printf "\ncache.direct=on on file\n" | ||
234 | echo "$hmp_cmds" | run_qemu -drive "$drv_bkfile" -drive "$drv_bk" -drive "$drv_file",cache.direct=on -drive "$drv_img" | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" | ||
235 | - echo -e "\ncache.direct=on on backing" | ||
236 | + printf "\ncache.direct=on on backing\n" | ||
237 | echo "$hmp_cmds" | run_qemu -drive "$drv_bkfile" -drive "$drv_bk",cache.direct=on -drive "$drv_file" -drive "$drv_img" | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" | ||
238 | - echo -e "\ncache.direct=on on backing-file" | ||
239 | + printf "\ncache.direct=on on backing-file\n" | ||
240 | echo "$hmp_cmds" | run_qemu -drive "$drv_bkfile",cache.direct=on -drive "$drv_bk" -drive "$drv_file" -drive "$drv_img" | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" | ||
241 | |||
242 | # Check cache.writeback | ||
243 | |||
244 | - echo -e "\n\ncache.writeback=off on blk" | ||
245 | + printf "\n\ncache.writeback=off on blk\n" | ||
246 | echo "$hmp_cmds" | run_qemu -drive "$drv_bkfile" -drive "$drv_bk" -drive "$drv_file" -drive "$drv_img",cache.writeback=off | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" | ||
247 | - echo -e "\ncache.writeback=off on file" | ||
248 | + printf "\ncache.writeback=off on file\n" | ||
249 | echo "$hmp_cmds" | run_qemu -drive "$drv_bkfile" -drive "$drv_bk" -drive "$drv_file",cache.writeback=off -drive "$drv_img" | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" | ||
250 | - echo -e "\ncache.writeback=off on backing" | ||
251 | + printf "\ncache.writeback=off on backing\n" | ||
252 | echo "$hmp_cmds" | run_qemu -drive "$drv_bkfile" -drive "$drv_bk",cache.writeback=off -drive "$drv_file" -drive "$drv_img" | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" | ||
253 | - echo -e "\ncache.writeback=off on backing-file" | ||
254 | + printf "\ncache.writeback=off on backing-file\n" | ||
255 | echo "$hmp_cmds" | run_qemu -drive "$drv_bkfile",cache.writeback=off -drive "$drv_bk" -drive "$drv_file" -drive "$drv_img" | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" | ||
256 | |||
257 | # Check cache.no-flush | ||
258 | |||
259 | - echo -e "\n\ncache.no-flush=on on blk" | ||
260 | + printf "\n\ncache.no-flush=on on blk\n" | ||
261 | echo "$hmp_cmds" | run_qemu -drive "$drv_bkfile" -drive "$drv_bk" -drive "$drv_file" -drive "$drv_img",cache.no-flush=on | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" | ||
262 | - echo -e "\ncache.no-flush=on on file" | ||
263 | + printf "\ncache.no-flush=on on file\n" | ||
264 | echo "$hmp_cmds" | run_qemu -drive "$drv_bkfile" -drive "$drv_bk" -drive "$drv_file",cache.no-flush=on -drive "$drv_img" | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" | ||
265 | - echo -e "\ncache.no-flush=on on backing" | ||
266 | + printf "\ncache.no-flush=on on backing\n" | ||
267 | echo "$hmp_cmds" | run_qemu -drive "$drv_bkfile" -drive "$drv_bk",cache.no-flush=on -drive "$drv_file" -drive "$drv_img" | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" | ||
268 | - echo -e "\ncache.no-flush=on on backing-file" | ||
269 | + printf "\ncache.no-flush=on on backing-file\n" | ||
270 | echo "$hmp_cmds" | run_qemu -drive "$drv_bkfile",cache.no-flush=on -drive "$drv_bk" -drive "$drv_file" -drive "$drv_img" | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't" | ||
271 | } | ||
272 | |||
273 | diff --git a/tests/qemu-iotests/171 b/tests/qemu-iotests/171 | ||
274 | index XXXXXXX..XXXXXXX 100755 | ||
275 | --- a/tests/qemu-iotests/171 | ||
276 | +++ b/tests/qemu-iotests/171 | ||
277 | @@ -XXX,XX +XXX,XX @@ _supported_os Linux | ||
278 | |||
279 | # Create JSON with options | ||
280 | img_json() { | ||
281 | - echo -n 'json:{"driver":"raw", ' | ||
282 | - echo -n "\"offset\":\"$img_offset\", " | ||
283 | + printf %s 'json:{"driver":"raw", ' | ||
284 | + printf %s "\"offset\":\"$img_offset\", " | ||
285 | if [ "$img_size" -ne -1 ] ; then | ||
286 | - echo -n "\"size\":\"$img_size\", " | ||
287 | + printf %s "\"size\":\"$img_size\", " | ||
288 | fi | ||
289 | - echo -n '"file": {' | ||
290 | - echo -n '"driver":"file", ' | ||
291 | - echo -n "\"filename\":\"$TEST_IMG\" " | ||
292 | - echo -n "} }" | ||
293 | + printf %s '"file": {' | ||
294 | + printf %s '"driver":"file", ' | ||
295 | + printf %s "\"filename\":\"$TEST_IMG\" " | ||
296 | + printf %s "} }" | ||
297 | } | ||
298 | |||
299 | do_general_test() { | ||
300 | diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check | ||
301 | index XXXXXXX..XXXXXXX 100755 | ||
302 | --- a/tests/qemu-iotests/check | ||
303 | +++ b/tests/qemu-iotests/check | ||
304 | @@ -XXX,XX +XXX,XX @@ _wallclock() | ||
305 | _timestamp() | ||
306 | { | ||
307 | now=`date "+%T"` | ||
308 | - echo -n " [$now]" | ||
309 | + printf %s " [$now]" | ||
310 | } | ||
311 | |||
312 | _wrapup() | ||
313 | @@ -XXX,XX +XXX,XX @@ seq="check" | ||
314 | for seq in $list | ||
315 | do | ||
316 | err=false | ||
317 | - echo -n "$seq" | ||
318 | + printf %s "$seq" | ||
319 | if [ -n "$TESTS_REMAINING_LOG" ] ; then | ||
320 | sed -e "s/$seq//" -e 's/ / /' -e 's/^ *//' $TESTS_REMAINING_LOG > $TESTS_REMAINING_LOG.tmp | ||
321 | mv $TESTS_REMAINING_LOG.tmp $TESTS_REMAINING_LOG | ||
322 | @@ -XXX,XX +XXX,XX @@ do | ||
323 | rm -f $seq.out.bad | ||
324 | lasttime=`sed -n -e "/^$seq /s/.* //p" <$TIMESTAMP_FILE` | ||
325 | if [ "X$lasttime" != X ]; then | ||
326 | - echo -n " ${lasttime}s ..." | ||
327 | + printf %s " ${lasttime}s ..." | ||
328 | else | ||
329 | - echo -n " " # prettier output with timestamps. | ||
330 | + printf " " # prettier output with timestamps. | ||
331 | fi | ||
332 | rm -f core $seq.notrun | ||
333 | |||
334 | @@ -XXX,XX +XXX,XX @@ do | ||
335 | echo "$seq" > "${TEST_DIR}"/check.sts | ||
336 | |||
337 | start=`_wallclock` | ||
338 | - $timestamp && echo -n " ["`date "+%T"`"]" | ||
339 | + $timestamp && printf %s " [$(date "+%T")]" | ||
340 | |||
341 | if [ "$(head -n 1 "$source_iotests/$seq")" == "#!/usr/bin/env python" ]; then | ||
342 | run_command="$PYTHON $seq" | ||
343 | @@ -XXX,XX +XXX,XX @@ do | ||
344 | |||
345 | if [ -f core ] | ||
346 | then | ||
347 | - echo -n " [dumped core]" | ||
348 | + printf " [dumped core]" | ||
349 | mv core $seq.core | ||
350 | err=true | ||
351 | fi | ||
352 | |||
353 | if [ -f $seq.notrun ] | ||
354 | then | ||
355 | - $timestamp || echo -n " [not run] " | ||
356 | - $timestamp && echo " [not run]" && echo -n " $seq -- " | ||
357 | + $timestamp || printf " [not run] " | ||
358 | + $timestamp && echo " [not run]" && printf %s " $seq -- " | ||
359 | cat $seq.notrun | ||
360 | notrun="$notrun $seq" | ||
361 | else | ||
362 | if [ $sts -ne 0 ] | ||
363 | then | ||
364 | - echo -n " [failed, exit status $sts]" | ||
365 | + printf %s " [failed, exit status $sts]" | ||
366 | err=true | ||
367 | fi | ||
368 | |||
369 | diff --git a/tests/rocker/all b/tests/rocker/all | ||
370 | index XXXXXXX..XXXXXXX 100755 | ||
371 | --- a/tests/rocker/all | ||
372 | +++ b/tests/rocker/all | ||
373 | @@ -XXX,XX +XXX,XX @@ | ||
374 | -echo -n "Running port test... " | ||
375 | +printf "Running port test... " | ||
376 | ./port | ||
377 | if [ $? -eq 0 ]; then echo "pass"; else echo "FAILED"; exit 1; fi | ||
378 | |||
379 | -echo -n "Running bridge test... " | ||
380 | +printf "Running bridge test... " | ||
381 | ./bridge | ||
382 | if [ $? -eq 0 ]; then echo "pass"; else echo "FAILED"; exit 1; fi | ||
383 | |||
384 | -echo -n "Running bridge STP test... " | ||
385 | +printf "Running bridge STP test... " | ||
386 | ./bridge-stp | ||
387 | if [ $? -eq 0 ]; then echo "pass"; else echo "FAILED"; exit 1; fi | ||
388 | |||
389 | -echo -n "Running bridge VLAN test... " | ||
390 | +printf "Running bridge VLAN test... " | ||
391 | ./bridge-vlan | ||
392 | if [ $? -eq 0 ]; then echo "pass"; else echo "FAILED"; exit 1; fi | ||
393 | |||
394 | -echo -n "Running bridge VLAN STP test... " | ||
395 | +printf "Running bridge VLAN STP test... " | ||
396 | ./bridge-vlan-stp | ||
397 | if [ $? -eq 0 ]; then echo "pass"; else echo "FAILED"; exit 1; fi | ||
398 | -- | ||
399 | 2.9.4 | ||
400 | |||
401 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Stefan Hajnoczi <stefanha@redhat.com> | ||
2 | 1 | ||
3 | bdrv_measure() provides a conservative maximum for the size of a new | ||
4 | image. This information is handy if storage needs to be allocated (e.g. | ||
5 | a SAN or an LVM volume) ahead of time. | ||
6 | |||
7 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
8 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
9 | Message-id: 20170705125738.8777-2-stefanha@redhat.com | ||
10 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
11 | --- | ||
12 | qapi/block-core.json | 25 +++++++++++++++++++++++++ | ||
13 | include/block/block.h | 2 ++ | ||
14 | include/block/block_int.h | 2 ++ | ||
15 | block.c | 35 +++++++++++++++++++++++++++++++++++ | ||
16 | 4 files changed, 64 insertions(+) | ||
17 | |||
18 | diff --git a/qapi/block-core.json b/qapi/block-core.json | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/qapi/block-core.json | ||
21 | +++ b/qapi/block-core.json | ||
22 | @@ -XXX,XX +XXX,XX @@ | ||
23 | '*dirty-bitmaps': ['BlockDirtyInfo'] } } | ||
24 | |||
25 | ## | ||
26 | +# @BlockMeasureInfo: | ||
27 | +# | ||
28 | +# Image file size calculation information. This structure describes the size | ||
29 | +# requirements for creating a new image file. | ||
30 | +# | ||
31 | +# The size requirements depend on the new image file format. File size always | ||
32 | +# equals virtual disk size for the 'raw' format, even for sparse POSIX files. | ||
33 | +# Compact formats such as 'qcow2' represent unallocated and zero regions | ||
34 | +# efficiently so file size may be smaller than virtual disk size. | ||
35 | +# | ||
36 | +# The values are upper bounds that are guaranteed to fit the new image file. | ||
37 | +# Subsequent modification, such as internal snapshot or bitmap creation, may | ||
38 | +# require additional space and is not covered here. | ||
39 | +# | ||
40 | +# @required: Size required for a new image file, in bytes. | ||
41 | +# | ||
42 | +# @fully-allocated: Image file size, in bytes, once data has been written | ||
43 | +# to all sectors. | ||
44 | +# | ||
45 | +# Since: 2.10 | ||
46 | +## | ||
47 | +{ 'struct': 'BlockMeasureInfo', | ||
48 | + 'data': {'required': 'int', 'fully-allocated': 'int'} } | ||
49 | + | ||
50 | +## | ||
51 | # @query-block: | ||
52 | # | ||
53 | # Get a list of BlockInfo for all virtual block devices. | ||
54 | diff --git a/include/block/block.h b/include/block/block.h | ||
55 | index XXXXXXX..XXXXXXX 100644 | ||
56 | --- a/include/block/block.h | ||
57 | +++ b/include/block/block.h | ||
58 | @@ -XXX,XX +XXX,XX @@ int bdrv_truncate(BdrvChild *child, int64_t offset, Error **errp); | ||
59 | int64_t bdrv_nb_sectors(BlockDriverState *bs); | ||
60 | int64_t bdrv_getlength(BlockDriverState *bs); | ||
61 | int64_t bdrv_get_allocated_file_size(BlockDriverState *bs); | ||
62 | +BlockMeasureInfo *bdrv_measure(BlockDriver *drv, QemuOpts *opts, | ||
63 | + BlockDriverState *in_bs, Error **errp); | ||
64 | void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr); | ||
65 | void bdrv_refresh_limits(BlockDriverState *bs, Error **errp); | ||
66 | int bdrv_commit(BlockDriverState *bs); | ||
67 | diff --git a/include/block/block_int.h b/include/block/block_int.h | ||
68 | index XXXXXXX..XXXXXXX 100644 | ||
69 | --- a/include/block/block_int.h | ||
70 | +++ b/include/block/block_int.h | ||
71 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
72 | int64_t (*bdrv_getlength)(BlockDriverState *bs); | ||
73 | bool has_variable_length; | ||
74 | int64_t (*bdrv_get_allocated_file_size)(BlockDriverState *bs); | ||
75 | + BlockMeasureInfo *(*bdrv_measure)(QemuOpts *opts, BlockDriverState *in_bs, | ||
76 | + Error **errp); | ||
77 | |||
78 | int coroutine_fn (*bdrv_co_pwritev_compressed)(BlockDriverState *bs, | ||
79 | uint64_t offset, uint64_t bytes, QEMUIOVector *qiov); | ||
80 | diff --git a/block.c b/block.c | ||
81 | index XXXXXXX..XXXXXXX 100644 | ||
82 | --- a/block.c | ||
83 | +++ b/block.c | ||
84 | @@ -XXX,XX +XXX,XX @@ int64_t bdrv_get_allocated_file_size(BlockDriverState *bs) | ||
85 | return -ENOTSUP; | ||
86 | } | ||
87 | |||
88 | +/* | ||
89 | + * bdrv_measure: | ||
90 | + * @drv: Format driver | ||
91 | + * @opts: Creation options for new image | ||
92 | + * @in_bs: Existing image containing data for new image (may be NULL) | ||
93 | + * @errp: Error object | ||
94 | + * Returns: A #BlockMeasureInfo (free using qapi_free_BlockMeasureInfo()) | ||
95 | + * or NULL on error | ||
96 | + * | ||
97 | + * Calculate file size required to create a new image. | ||
98 | + * | ||
99 | + * If @in_bs is given then space for allocated clusters and zero clusters | ||
100 | + * from that image are included in the calculation. If @opts contains a | ||
101 | + * backing file that is shared by @in_bs then backing clusters may be omitted | ||
102 | + * from the calculation. | ||
103 | + * | ||
104 | + * If @in_bs is NULL then the calculation includes no allocated clusters | ||
105 | + * unless a preallocation option is given in @opts. | ||
106 | + * | ||
107 | + * Note that @in_bs may use a different BlockDriver from @drv. | ||
108 | + * | ||
109 | + * If an error occurs the @errp pointer is set. | ||
110 | + */ | ||
111 | +BlockMeasureInfo *bdrv_measure(BlockDriver *drv, QemuOpts *opts, | ||
112 | + BlockDriverState *in_bs, Error **errp) | ||
113 | +{ | ||
114 | + if (!drv->bdrv_measure) { | ||
115 | + error_setg(errp, "Block driver '%s' does not support size measurement", | ||
116 | + drv->format_name); | ||
117 | + return NULL; | ||
118 | + } | ||
119 | + | ||
120 | + return drv->bdrv_measure(opts, in_bs, errp); | ||
121 | +} | ||
122 | + | ||
123 | /** | ||
124 | * Return number of sectors on success, -errno on error. | ||
125 | */ | ||
126 | -- | ||
127 | 2.9.4 | ||
128 | |||
129 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Stefan Hajnoczi <stefanha@redhat.com> | ||
2 | 1 | ||
3 | Maximum size calculation is trivial for the raw format: it's just the | ||
4 | requested image size (because there is no metadata). | ||
5 | |||
6 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
7 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
8 | Message-id: 20170705125738.8777-3-stefanha@redhat.com | ||
9 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
10 | --- | ||
11 | block/raw-format.c | 26 ++++++++++++++++++++++++++ | ||
12 | 1 file changed, 26 insertions(+) | ||
13 | |||
14 | diff --git a/block/raw-format.c b/block/raw-format.c | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/block/raw-format.c | ||
17 | +++ b/block/raw-format.c | ||
18 | @@ -XXX,XX +XXX,XX @@ static int64_t raw_getlength(BlockDriverState *bs) | ||
19 | return s->size; | ||
20 | } | ||
21 | |||
22 | +static BlockMeasureInfo *raw_measure(QemuOpts *opts, BlockDriverState *in_bs, | ||
23 | + Error **errp) | ||
24 | +{ | ||
25 | + BlockMeasureInfo *info; | ||
26 | + int64_t required; | ||
27 | + | ||
28 | + if (in_bs) { | ||
29 | + required = bdrv_getlength(in_bs); | ||
30 | + if (required < 0) { | ||
31 | + error_setg_errno(errp, -required, "Unable to get image size"); | ||
32 | + return NULL; | ||
33 | + } | ||
34 | + } else { | ||
35 | + required = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0), | ||
36 | + BDRV_SECTOR_SIZE); | ||
37 | + } | ||
38 | + | ||
39 | + info = g_new(BlockMeasureInfo, 1); | ||
40 | + info->required = required; | ||
41 | + | ||
42 | + /* Unallocated sectors count towards the file size in raw images */ | ||
43 | + info->fully_allocated = info->required; | ||
44 | + return info; | ||
45 | +} | ||
46 | + | ||
47 | static int raw_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) | ||
48 | { | ||
49 | return bdrv_get_info(bs->file->bs, bdi); | ||
50 | @@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_raw = { | ||
51 | .bdrv_truncate = &raw_truncate, | ||
52 | .bdrv_getlength = &raw_getlength, | ||
53 | .has_variable_length = true, | ||
54 | + .bdrv_measure = &raw_measure, | ||
55 | .bdrv_get_info = &raw_get_info, | ||
56 | .bdrv_refresh_limits = &raw_refresh_limits, | ||
57 | .bdrv_probe_blocksizes = &raw_probe_blocksizes, | ||
58 | -- | ||
59 | 2.9.4 | ||
60 | |||
61 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Stefan Hajnoczi <stefanha@redhat.com> | ||
2 | 1 | ||
3 | Calculating the preallocated image size will be needed to implement | ||
4 | .bdrv_measure(). Extract the code out into a separate function. | ||
5 | |||
6 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
7 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
8 | Message-id: 20170705125738.8777-4-stefanha@redhat.com | ||
9 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
10 | --- | ||
11 | block/qcow2.c | 136 +++++++++++++++++++++++++++++++++------------------------- | ||
12 | 1 file changed, 77 insertions(+), 59 deletions(-) | ||
13 | |||
14 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/block/qcow2.c | ||
17 | +++ b/block/qcow2.c | ||
18 | @@ -XXX,XX +XXX,XX @@ static int preallocate(BlockDriverState *bs) | ||
19 | return 0; | ||
20 | } | ||
21 | |||
22 | +/** | ||
23 | + * qcow2_calc_prealloc_size: | ||
24 | + * @total_size: virtual disk size in bytes | ||
25 | + * @cluster_size: cluster size in bytes | ||
26 | + * @refcount_order: refcount bits power-of-2 exponent | ||
27 | + * | ||
28 | + * Returns: Total number of bytes required for the fully allocated image | ||
29 | + * (including metadata). | ||
30 | + */ | ||
31 | +static int64_t qcow2_calc_prealloc_size(int64_t total_size, | ||
32 | + size_t cluster_size, | ||
33 | + int refcount_order) | ||
34 | +{ | ||
35 | + /* Note: The following calculation does not need to be exact; if it is a | ||
36 | + * bit off, either some bytes will be "leaked" (which is fine) or we | ||
37 | + * will need to increase the file size by some bytes (which is fine, | ||
38 | + * too, as long as the bulk is allocated here). Therefore, using | ||
39 | + * floating point arithmetic is fine. */ | ||
40 | + int64_t meta_size = 0; | ||
41 | + uint64_t nreftablee, nrefblocke, nl1e, nl2e, refblock_count; | ||
42 | + int64_t aligned_total_size = align_offset(total_size, cluster_size); | ||
43 | + int cluster_bits = ctz32(cluster_size); | ||
44 | + int refblock_bits, refblock_size; | ||
45 | + /* refcount entry size in bytes */ | ||
46 | + double rces = (1 << refcount_order) / 8.; | ||
47 | + | ||
48 | + /* see qcow2_open() */ | ||
49 | + refblock_bits = cluster_bits - (refcount_order - 3); | ||
50 | + refblock_size = 1 << refblock_bits; | ||
51 | + | ||
52 | + /* header: 1 cluster */ | ||
53 | + meta_size += cluster_size; | ||
54 | + | ||
55 | + /* total size of L2 tables */ | ||
56 | + nl2e = aligned_total_size / cluster_size; | ||
57 | + nl2e = align_offset(nl2e, cluster_size / sizeof(uint64_t)); | ||
58 | + meta_size += nl2e * sizeof(uint64_t); | ||
59 | + | ||
60 | + /* total size of L1 tables */ | ||
61 | + nl1e = nl2e * sizeof(uint64_t) / cluster_size; | ||
62 | + nl1e = align_offset(nl1e, cluster_size / sizeof(uint64_t)); | ||
63 | + meta_size += nl1e * sizeof(uint64_t); | ||
64 | + | ||
65 | + /* total size of refcount blocks | ||
66 | + * | ||
67 | + * note: every host cluster is reference-counted, including metadata | ||
68 | + * (even refcount blocks are recursively included). | ||
69 | + * Let: | ||
70 | + * a = total_size (this is the guest disk size) | ||
71 | + * m = meta size not including refcount blocks and refcount tables | ||
72 | + * c = cluster size | ||
73 | + * y1 = number of refcount blocks entries | ||
74 | + * y2 = meta size including everything | ||
75 | + * rces = refcount entry size in bytes | ||
76 | + * then, | ||
77 | + * y1 = (y2 + a)/c | ||
78 | + * y2 = y1 * rces + y1 * rces * sizeof(u64) / c + m | ||
79 | + * we can get y1: | ||
80 | + * y1 = (a + m) / (c - rces - rces * sizeof(u64) / c) | ||
81 | + */ | ||
82 | + nrefblocke = (aligned_total_size + meta_size + cluster_size) | ||
83 | + / (cluster_size - rces - rces * sizeof(uint64_t) | ||
84 | + / cluster_size); | ||
85 | + refblock_count = DIV_ROUND_UP(nrefblocke, refblock_size); | ||
86 | + meta_size += refblock_count * cluster_size; | ||
87 | + | ||
88 | + /* total size of refcount tables */ | ||
89 | + nreftablee = align_offset(refblock_count, | ||
90 | + cluster_size / sizeof(uint64_t)); | ||
91 | + meta_size += nreftablee * sizeof(uint64_t); | ||
92 | + | ||
93 | + return meta_size + aligned_total_size; | ||
94 | +} | ||
95 | + | ||
96 | static int qcow2_create2(const char *filename, int64_t total_size, | ||
97 | const char *backing_file, const char *backing_format, | ||
98 | int flags, size_t cluster_size, PreallocMode prealloc, | ||
99 | @@ -XXX,XX +XXX,XX @@ static int qcow2_create2(const char *filename, int64_t total_size, | ||
100 | int ret; | ||
101 | |||
102 | if (prealloc == PREALLOC_MODE_FULL || prealloc == PREALLOC_MODE_FALLOC) { | ||
103 | - /* Note: The following calculation does not need to be exact; if it is a | ||
104 | - * bit off, either some bytes will be "leaked" (which is fine) or we | ||
105 | - * will need to increase the file size by some bytes (which is fine, | ||
106 | - * too, as long as the bulk is allocated here). Therefore, using | ||
107 | - * floating point arithmetic is fine. */ | ||
108 | - int64_t meta_size = 0; | ||
109 | - uint64_t nreftablee, nrefblocke, nl1e, nl2e, refblock_count; | ||
110 | - int64_t aligned_total_size = align_offset(total_size, cluster_size); | ||
111 | - int refblock_bits, refblock_size; | ||
112 | - /* refcount entry size in bytes */ | ||
113 | - double rces = (1 << refcount_order) / 8.; | ||
114 | - | ||
115 | - /* see qcow2_open() */ | ||
116 | - refblock_bits = cluster_bits - (refcount_order - 3); | ||
117 | - refblock_size = 1 << refblock_bits; | ||
118 | - | ||
119 | - /* header: 1 cluster */ | ||
120 | - meta_size += cluster_size; | ||
121 | - | ||
122 | - /* total size of L2 tables */ | ||
123 | - nl2e = aligned_total_size / cluster_size; | ||
124 | - nl2e = align_offset(nl2e, cluster_size / sizeof(uint64_t)); | ||
125 | - meta_size += nl2e * sizeof(uint64_t); | ||
126 | - | ||
127 | - /* total size of L1 tables */ | ||
128 | - nl1e = nl2e * sizeof(uint64_t) / cluster_size; | ||
129 | - nl1e = align_offset(nl1e, cluster_size / sizeof(uint64_t)); | ||
130 | - meta_size += nl1e * sizeof(uint64_t); | ||
131 | - | ||
132 | - /* total size of refcount blocks | ||
133 | - * | ||
134 | - * note: every host cluster is reference-counted, including metadata | ||
135 | - * (even refcount blocks are recursively included). | ||
136 | - * Let: | ||
137 | - * a = total_size (this is the guest disk size) | ||
138 | - * m = meta size not including refcount blocks and refcount tables | ||
139 | - * c = cluster size | ||
140 | - * y1 = number of refcount blocks entries | ||
141 | - * y2 = meta size including everything | ||
142 | - * rces = refcount entry size in bytes | ||
143 | - * then, | ||
144 | - * y1 = (y2 + a)/c | ||
145 | - * y2 = y1 * rces + y1 * rces * sizeof(u64) / c + m | ||
146 | - * we can get y1: | ||
147 | - * y1 = (a + m) / (c - rces - rces * sizeof(u64) / c) | ||
148 | - */ | ||
149 | - nrefblocke = (aligned_total_size + meta_size + cluster_size) | ||
150 | - / (cluster_size - rces - rces * sizeof(uint64_t) | ||
151 | - / cluster_size); | ||
152 | - refblock_count = DIV_ROUND_UP(nrefblocke, refblock_size); | ||
153 | - meta_size += refblock_count * cluster_size; | ||
154 | - | ||
155 | - /* total size of refcount tables */ | ||
156 | - nreftablee = align_offset(refblock_count, | ||
157 | - cluster_size / sizeof(uint64_t)); | ||
158 | - meta_size += nreftablee * sizeof(uint64_t); | ||
159 | - | ||
160 | - qemu_opt_set_number(opts, BLOCK_OPT_SIZE, | ||
161 | - aligned_total_size + meta_size, &error_abort); | ||
162 | + int64_t prealloc_size = | ||
163 | + qcow2_calc_prealloc_size(total_size, cluster_size, refcount_order); | ||
164 | + qemu_opt_set_number(opts, BLOCK_OPT_SIZE, prealloc_size, &error_abort); | ||
165 | qemu_opt_set(opts, BLOCK_OPT_PREALLOC, PreallocMode_lookup[prealloc], | ||
166 | &error_abort); | ||
167 | } | ||
168 | -- | ||
169 | 2.9.4 | ||
170 | |||
171 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Stefan Hajnoczi <stefanha@redhat.com> | ||
2 | 1 | ||
3 | The refcount metadata size calculation is inaccurate and can produce | ||
4 | numbers that are too small. This is bad because we should calculate a | ||
5 | conservative number - one that is guaranteed to be large enough. | ||
6 | |||
7 | This patch switches the approach to a fixed point calculation because | ||
8 | the existing equation is hard to solve when inaccuracies are taken care | ||
9 | of. | ||
10 | |||
11 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
12 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
13 | Message-id: 20170705125738.8777-5-stefanha@redhat.com | ||
14 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
15 | --- | ||
16 | block/qcow2.c | 83 ++++++++++++++++++++++++++++++----------------------------- | ||
17 | 1 file changed, 42 insertions(+), 41 deletions(-) | ||
18 | |||
19 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
20 | index XXXXXXX..XXXXXXX 100644 | ||
21 | --- a/block/qcow2.c | ||
22 | +++ b/block/qcow2.c | ||
23 | @@ -XXX,XX +XXX,XX @@ static int preallocate(BlockDriverState *bs) | ||
24 | return 0; | ||
25 | } | ||
26 | |||
27 | +/* qcow2_refcount_metadata_size: | ||
28 | + * @clusters: number of clusters to refcount (including data and L1/L2 tables) | ||
29 | + * @cluster_size: size of a cluster, in bytes | ||
30 | + * @refcount_order: refcount bits power-of-2 exponent | ||
31 | + * | ||
32 | + * Returns: Number of bytes required for refcount blocks and table metadata. | ||
33 | + */ | ||
34 | +static int64_t qcow2_refcount_metadata_size(int64_t clusters, | ||
35 | + size_t cluster_size, | ||
36 | + int refcount_order) | ||
37 | +{ | ||
38 | + /* | ||
39 | + * Every host cluster is reference-counted, including metadata (even | ||
40 | + * refcount metadata is recursively included). | ||
41 | + * | ||
42 | + * An accurate formula for the size of refcount metadata size is difficult | ||
43 | + * to derive. An easier method of calculation is finding the fixed point | ||
44 | + * where no further refcount blocks or table clusters are required to | ||
45 | + * reference count every cluster. | ||
46 | + */ | ||
47 | + int64_t blocks_per_table_cluster = cluster_size / sizeof(uint64_t); | ||
48 | + int64_t refcounts_per_block = cluster_size * 8 / (1 << refcount_order); | ||
49 | + int64_t table = 0; /* number of refcount table clusters */ | ||
50 | + int64_t blocks = 0; /* number of refcount block clusters */ | ||
51 | + int64_t last; | ||
52 | + int64_t n = 0; | ||
53 | + | ||
54 | + do { | ||
55 | + last = n; | ||
56 | + blocks = DIV_ROUND_UP(clusters + table + blocks, refcounts_per_block); | ||
57 | + table = DIV_ROUND_UP(blocks, blocks_per_table_cluster); | ||
58 | + n = clusters + blocks + table; | ||
59 | + } while (n != last); | ||
60 | + | ||
61 | + return (blocks + table) * cluster_size; | ||
62 | +} | ||
63 | + | ||
64 | /** | ||
65 | * qcow2_calc_prealloc_size: | ||
66 | * @total_size: virtual disk size in bytes | ||
67 | @@ -XXX,XX +XXX,XX @@ static int64_t qcow2_calc_prealloc_size(int64_t total_size, | ||
68 | size_t cluster_size, | ||
69 | int refcount_order) | ||
70 | { | ||
71 | - /* Note: The following calculation does not need to be exact; if it is a | ||
72 | - * bit off, either some bytes will be "leaked" (which is fine) or we | ||
73 | - * will need to increase the file size by some bytes (which is fine, | ||
74 | - * too, as long as the bulk is allocated here). Therefore, using | ||
75 | - * floating point arithmetic is fine. */ | ||
76 | int64_t meta_size = 0; | ||
77 | - uint64_t nreftablee, nrefblocke, nl1e, nl2e, refblock_count; | ||
78 | + uint64_t nl1e, nl2e; | ||
79 | int64_t aligned_total_size = align_offset(total_size, cluster_size); | ||
80 | - int cluster_bits = ctz32(cluster_size); | ||
81 | - int refblock_bits, refblock_size; | ||
82 | - /* refcount entry size in bytes */ | ||
83 | - double rces = (1 << refcount_order) / 8.; | ||
84 | - | ||
85 | - /* see qcow2_open() */ | ||
86 | - refblock_bits = cluster_bits - (refcount_order - 3); | ||
87 | - refblock_size = 1 << refblock_bits; | ||
88 | |||
89 | /* header: 1 cluster */ | ||
90 | meta_size += cluster_size; | ||
91 | @@ -XXX,XX +XXX,XX @@ static int64_t qcow2_calc_prealloc_size(int64_t total_size, | ||
92 | nl1e = align_offset(nl1e, cluster_size / sizeof(uint64_t)); | ||
93 | meta_size += nl1e * sizeof(uint64_t); | ||
94 | |||
95 | - /* total size of refcount blocks | ||
96 | - * | ||
97 | - * note: every host cluster is reference-counted, including metadata | ||
98 | - * (even refcount blocks are recursively included). | ||
99 | - * Let: | ||
100 | - * a = total_size (this is the guest disk size) | ||
101 | - * m = meta size not including refcount blocks and refcount tables | ||
102 | - * c = cluster size | ||
103 | - * y1 = number of refcount blocks entries | ||
104 | - * y2 = meta size including everything | ||
105 | - * rces = refcount entry size in bytes | ||
106 | - * then, | ||
107 | - * y1 = (y2 + a)/c | ||
108 | - * y2 = y1 * rces + y1 * rces * sizeof(u64) / c + m | ||
109 | - * we can get y1: | ||
110 | - * y1 = (a + m) / (c - rces - rces * sizeof(u64) / c) | ||
111 | - */ | ||
112 | - nrefblocke = (aligned_total_size + meta_size + cluster_size) | ||
113 | - / (cluster_size - rces - rces * sizeof(uint64_t) | ||
114 | - / cluster_size); | ||
115 | - refblock_count = DIV_ROUND_UP(nrefblocke, refblock_size); | ||
116 | - meta_size += refblock_count * cluster_size; | ||
117 | - | ||
118 | - /* total size of refcount tables */ | ||
119 | - nreftablee = align_offset(refblock_count, | ||
120 | - cluster_size / sizeof(uint64_t)); | ||
121 | - meta_size += nreftablee * sizeof(uint64_t); | ||
122 | + /* total size of refcount table and blocks */ | ||
123 | + meta_size += qcow2_refcount_metadata_size( | ||
124 | + (meta_size + aligned_total_size) / cluster_size, | ||
125 | + cluster_size, refcount_order); | ||
126 | |||
127 | return meta_size + aligned_total_size; | ||
128 | } | ||
129 | -- | ||
130 | 2.9.4 | ||
131 | |||
132 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Stefan Hajnoczi <stefanha@redhat.com> | ||
2 | 1 | ||
3 | The image creation options parsed by qcow2_create() are also needed to | ||
4 | implement .bdrv_measure(). Extract the parsing code, including input | ||
5 | validation. | ||
6 | |||
7 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
8 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
9 | Message-id: 20170705125738.8777-6-stefanha@redhat.com | ||
10 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
11 | --- | ||
12 | block/qcow2.c | 109 +++++++++++++++++++++++++++++++++++++++------------------- | ||
13 | 1 file changed, 73 insertions(+), 36 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 int64_t qcow2_calc_prealloc_size(int64_t total_size, | ||
20 | return meta_size + aligned_total_size; | ||
21 | } | ||
22 | |||
23 | -static int qcow2_create2(const char *filename, int64_t total_size, | ||
24 | - const char *backing_file, const char *backing_format, | ||
25 | - int flags, size_t cluster_size, PreallocMode prealloc, | ||
26 | - QemuOpts *opts, int version, int refcount_order, | ||
27 | - const char *encryptfmt, Error **errp) | ||
28 | +static size_t qcow2_opt_get_cluster_size_del(QemuOpts *opts, Error **errp) | ||
29 | { | ||
30 | + size_t cluster_size; | ||
31 | int cluster_bits; | ||
32 | - QDict *options; | ||
33 | |||
34 | - /* Calculate cluster_bits */ | ||
35 | + cluster_size = qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE, | ||
36 | + DEFAULT_CLUSTER_SIZE); | ||
37 | cluster_bits = ctz32(cluster_size); | ||
38 | if (cluster_bits < MIN_CLUSTER_BITS || cluster_bits > MAX_CLUSTER_BITS || | ||
39 | (1 << cluster_bits) != cluster_size) | ||
40 | { | ||
41 | error_setg(errp, "Cluster size must be a power of two between %d and " | ||
42 | "%dk", 1 << MIN_CLUSTER_BITS, 1 << (MAX_CLUSTER_BITS - 10)); | ||
43 | - return -EINVAL; | ||
44 | + return 0; | ||
45 | + } | ||
46 | + return cluster_size; | ||
47 | +} | ||
48 | + | ||
49 | +static int qcow2_opt_get_version_del(QemuOpts *opts, Error **errp) | ||
50 | +{ | ||
51 | + char *buf; | ||
52 | + int ret; | ||
53 | + | ||
54 | + buf = qemu_opt_get_del(opts, BLOCK_OPT_COMPAT_LEVEL); | ||
55 | + if (!buf) { | ||
56 | + ret = 3; /* default */ | ||
57 | + } else if (!strcmp(buf, "0.10")) { | ||
58 | + ret = 2; | ||
59 | + } else if (!strcmp(buf, "1.1")) { | ||
60 | + ret = 3; | ||
61 | + } else { | ||
62 | + error_setg(errp, "Invalid compatibility level: '%s'", buf); | ||
63 | + ret = -EINVAL; | ||
64 | + } | ||
65 | + g_free(buf); | ||
66 | + return ret; | ||
67 | +} | ||
68 | + | ||
69 | +static uint64_t qcow2_opt_get_refcount_bits_del(QemuOpts *opts, int version, | ||
70 | + Error **errp) | ||
71 | +{ | ||
72 | + uint64_t refcount_bits; | ||
73 | + | ||
74 | + refcount_bits = qemu_opt_get_number_del(opts, BLOCK_OPT_REFCOUNT_BITS, 16); | ||
75 | + if (refcount_bits > 64 || !is_power_of_2(refcount_bits)) { | ||
76 | + error_setg(errp, "Refcount width must be a power of two and may not " | ||
77 | + "exceed 64 bits"); | ||
78 | + return 0; | ||
79 | + } | ||
80 | + | ||
81 | + if (version < 3 && refcount_bits != 16) { | ||
82 | + error_setg(errp, "Different refcount widths than 16 bits require " | ||
83 | + "compatibility level 1.1 or above (use compat=1.1 or " | ||
84 | + "greater)"); | ||
85 | + return 0; | ||
86 | } | ||
87 | |||
88 | + return refcount_bits; | ||
89 | +} | ||
90 | + | ||
91 | +static int qcow2_create2(const char *filename, int64_t total_size, | ||
92 | + const char *backing_file, const char *backing_format, | ||
93 | + int flags, size_t cluster_size, PreallocMode prealloc, | ||
94 | + QemuOpts *opts, int version, int refcount_order, | ||
95 | + const char *encryptfmt, Error **errp) | ||
96 | +{ | ||
97 | + QDict *options; | ||
98 | + | ||
99 | /* | ||
100 | * Open the image file and write a minimal qcow2 header. | ||
101 | * | ||
102 | @@ -XXX,XX +XXX,XX @@ static int qcow2_create2(const char *filename, int64_t total_size, | ||
103 | *header = (QCowHeader) { | ||
104 | .magic = cpu_to_be32(QCOW_MAGIC), | ||
105 | .version = cpu_to_be32(version), | ||
106 | - .cluster_bits = cpu_to_be32(cluster_bits), | ||
107 | + .cluster_bits = cpu_to_be32(ctz32(cluster_size)), | ||
108 | .size = cpu_to_be64(0), | ||
109 | .l1_table_offset = cpu_to_be64(0), | ||
110 | .l1_size = cpu_to_be32(0), | ||
111 | @@ -XXX,XX +XXX,XX @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp) | ||
112 | int flags = 0; | ||
113 | size_t cluster_size = DEFAULT_CLUSTER_SIZE; | ||
114 | PreallocMode prealloc; | ||
115 | - int version = 3; | ||
116 | - uint64_t refcount_bits = 16; | ||
117 | + int version; | ||
118 | + uint64_t refcount_bits; | ||
119 | int refcount_order; | ||
120 | const char *encryptfmt = NULL; | ||
121 | Error *local_err = NULL; | ||
122 | @@ -XXX,XX +XXX,XX @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp) | ||
123 | } else if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) { | ||
124 | encryptfmt = "aes"; | ||
125 | } | ||
126 | - cluster_size = qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE, | ||
127 | - DEFAULT_CLUSTER_SIZE); | ||
128 | + cluster_size = qcow2_opt_get_cluster_size_del(opts, &local_err); | ||
129 | + if (local_err) { | ||
130 | + error_propagate(errp, local_err); | ||
131 | + ret = -EINVAL; | ||
132 | + goto finish; | ||
133 | + } | ||
134 | buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); | ||
135 | prealloc = qapi_enum_parse(PreallocMode_lookup, buf, | ||
136 | PREALLOC_MODE__MAX, PREALLOC_MODE_OFF, | ||
137 | @@ -XXX,XX +XXX,XX @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp) | ||
138 | ret = -EINVAL; | ||
139 | goto finish; | ||
140 | } | ||
141 | - g_free(buf); | ||
142 | - buf = qemu_opt_get_del(opts, BLOCK_OPT_COMPAT_LEVEL); | ||
143 | - if (!buf) { | ||
144 | - /* keep the default */ | ||
145 | - } else if (!strcmp(buf, "0.10")) { | ||
146 | - version = 2; | ||
147 | - } else if (!strcmp(buf, "1.1")) { | ||
148 | - version = 3; | ||
149 | - } else { | ||
150 | - error_setg(errp, "Invalid compatibility level: '%s'", buf); | ||
151 | + | ||
152 | + version = qcow2_opt_get_version_del(opts, &local_err); | ||
153 | + if (local_err) { | ||
154 | + error_propagate(errp, local_err); | ||
155 | ret = -EINVAL; | ||
156 | goto finish; | ||
157 | } | ||
158 | @@ -XXX,XX +XXX,XX @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp) | ||
159 | goto finish; | ||
160 | } | ||
161 | |||
162 | - refcount_bits = qemu_opt_get_number_del(opts, BLOCK_OPT_REFCOUNT_BITS, | ||
163 | - refcount_bits); | ||
164 | - if (refcount_bits > 64 || !is_power_of_2(refcount_bits)) { | ||
165 | - error_setg(errp, "Refcount width must be a power of two and may not " | ||
166 | - "exceed 64 bits"); | ||
167 | - ret = -EINVAL; | ||
168 | - goto finish; | ||
169 | - } | ||
170 | - | ||
171 | - if (version < 3 && refcount_bits != 16) { | ||
172 | - error_setg(errp, "Different refcount widths than 16 bits require " | ||
173 | - "compatibility level 1.1 or above (use compat=1.1 or " | ||
174 | - "greater)"); | ||
175 | + refcount_bits = qcow2_opt_get_refcount_bits_del(opts, version, &local_err); | ||
176 | + if (local_err) { | ||
177 | + error_propagate(errp, local_err); | ||
178 | ret = -EINVAL; | ||
179 | goto finish; | ||
180 | } | ||
181 | -- | ||
182 | 2.9.4 | ||
183 | |||
184 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Stefan Hajnoczi <stefanha@redhat.com> | ||
2 | 1 | ||
3 | Use qcow2_calc_prealloc_size() to get the required file size. | ||
4 | |||
5 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
6 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
7 | Message-id: 20170705125738.8777-7-stefanha@redhat.com | ||
8 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
9 | --- | ||
10 | block/qcow2.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||
11 | 1 file changed, 137 insertions(+) | ||
12 | |||
13 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
14 | index XXXXXXX..XXXXXXX 100644 | ||
15 | --- a/block/qcow2.c | ||
16 | +++ b/block/qcow2.c | ||
17 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_flush_to_os(BlockDriverState *bs) | ||
18 | return 0; | ||
19 | } | ||
20 | |||
21 | +static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs, | ||
22 | + Error **errp) | ||
23 | +{ | ||
24 | + Error *local_err = NULL; | ||
25 | + BlockMeasureInfo *info; | ||
26 | + uint64_t required = 0; /* bytes that contribute to required size */ | ||
27 | + uint64_t virtual_size; /* disk size as seen by guest */ | ||
28 | + uint64_t refcount_bits; | ||
29 | + uint64_t l2_tables; | ||
30 | + size_t cluster_size; | ||
31 | + int version; | ||
32 | + char *optstr; | ||
33 | + PreallocMode prealloc; | ||
34 | + bool has_backing_file; | ||
35 | + | ||
36 | + /* Parse image creation options */ | ||
37 | + cluster_size = qcow2_opt_get_cluster_size_del(opts, &local_err); | ||
38 | + if (local_err) { | ||
39 | + goto err; | ||
40 | + } | ||
41 | + | ||
42 | + version = qcow2_opt_get_version_del(opts, &local_err); | ||
43 | + if (local_err) { | ||
44 | + goto err; | ||
45 | + } | ||
46 | + | ||
47 | + refcount_bits = qcow2_opt_get_refcount_bits_del(opts, version, &local_err); | ||
48 | + if (local_err) { | ||
49 | + goto err; | ||
50 | + } | ||
51 | + | ||
52 | + optstr = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); | ||
53 | + prealloc = qapi_enum_parse(PreallocMode_lookup, optstr, | ||
54 | + PREALLOC_MODE__MAX, PREALLOC_MODE_OFF, | ||
55 | + &local_err); | ||
56 | + g_free(optstr); | ||
57 | + if (local_err) { | ||
58 | + goto err; | ||
59 | + } | ||
60 | + | ||
61 | + optstr = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE); | ||
62 | + has_backing_file = !!optstr; | ||
63 | + g_free(optstr); | ||
64 | + | ||
65 | + virtual_size = align_offset(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0), | ||
66 | + cluster_size); | ||
67 | + | ||
68 | + /* Check that virtual disk size is valid */ | ||
69 | + l2_tables = DIV_ROUND_UP(virtual_size / cluster_size, | ||
70 | + cluster_size / sizeof(uint64_t)); | ||
71 | + if (l2_tables * sizeof(uint64_t) > QCOW_MAX_L1_SIZE) { | ||
72 | + error_setg(&local_err, "The image size is too large " | ||
73 | + "(try using a larger cluster size)"); | ||
74 | + goto err; | ||
75 | + } | ||
76 | + | ||
77 | + /* Account for input image */ | ||
78 | + if (in_bs) { | ||
79 | + int64_t ssize = bdrv_getlength(in_bs); | ||
80 | + if (ssize < 0) { | ||
81 | + error_setg_errno(&local_err, -ssize, | ||
82 | + "Unable to get image virtual_size"); | ||
83 | + goto err; | ||
84 | + } | ||
85 | + | ||
86 | + virtual_size = align_offset(ssize, cluster_size); | ||
87 | + | ||
88 | + if (has_backing_file) { | ||
89 | + /* We don't how much of the backing chain is shared by the input | ||
90 | + * image and the new image file. In the worst case the new image's | ||
91 | + * backing file has nothing in common with the input image. Be | ||
92 | + * conservative and assume all clusters need to be written. | ||
93 | + */ | ||
94 | + required = virtual_size; | ||
95 | + } else { | ||
96 | + int cluster_sectors = cluster_size / BDRV_SECTOR_SIZE; | ||
97 | + int64_t sector_num; | ||
98 | + int pnum = 0; | ||
99 | + | ||
100 | + for (sector_num = 0; | ||
101 | + sector_num < ssize / BDRV_SECTOR_SIZE; | ||
102 | + sector_num += pnum) { | ||
103 | + int nb_sectors = MAX(ssize / BDRV_SECTOR_SIZE - sector_num, | ||
104 | + INT_MAX); | ||
105 | + BlockDriverState *file; | ||
106 | + int64_t ret; | ||
107 | + | ||
108 | + ret = bdrv_get_block_status_above(in_bs, NULL, | ||
109 | + sector_num, nb_sectors, | ||
110 | + &pnum, &file); | ||
111 | + if (ret < 0) { | ||
112 | + error_setg_errno(&local_err, -ret, | ||
113 | + "Unable to get block status"); | ||
114 | + goto err; | ||
115 | + } | ||
116 | + | ||
117 | + if (ret & BDRV_BLOCK_ZERO) { | ||
118 | + /* Skip zero regions (safe with no backing file) */ | ||
119 | + } else if ((ret & (BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED)) == | ||
120 | + (BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED)) { | ||
121 | + /* Extend pnum to end of cluster for next iteration */ | ||
122 | + pnum = ROUND_UP(sector_num + pnum, cluster_sectors) - | ||
123 | + sector_num; | ||
124 | + | ||
125 | + /* Count clusters we've seen */ | ||
126 | + required += (sector_num % cluster_sectors + pnum) * | ||
127 | + BDRV_SECTOR_SIZE; | ||
128 | + } | ||
129 | + } | ||
130 | + } | ||
131 | + } | ||
132 | + | ||
133 | + /* Take into account preallocation. Nothing special is needed for | ||
134 | + * PREALLOC_MODE_METADATA since metadata is always counted. | ||
135 | + */ | ||
136 | + if (prealloc == PREALLOC_MODE_FULL || prealloc == PREALLOC_MODE_FALLOC) { | ||
137 | + required = virtual_size; | ||
138 | + } | ||
139 | + | ||
140 | + info = g_new(BlockMeasureInfo, 1); | ||
141 | + info->fully_allocated = | ||
142 | + qcow2_calc_prealloc_size(virtual_size, cluster_size, | ||
143 | + ctz32(refcount_bits)); | ||
144 | + | ||
145 | + /* Remove data clusters that are not required. This overestimates the | ||
146 | + * required size because metadata needed for the fully allocated file is | ||
147 | + * still counted. | ||
148 | + */ | ||
149 | + info->required = info->fully_allocated - virtual_size + required; | ||
150 | + return info; | ||
151 | + | ||
152 | +err: | ||
153 | + error_propagate(errp, local_err); | ||
154 | + return NULL; | ||
155 | +} | ||
156 | + | ||
157 | static int qcow2_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) | ||
158 | { | ||
159 | BDRVQcow2State *s = bs->opaque; | ||
160 | @@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_qcow2 = { | ||
161 | .bdrv_snapshot_delete = qcow2_snapshot_delete, | ||
162 | .bdrv_snapshot_list = qcow2_snapshot_list, | ||
163 | .bdrv_snapshot_load_tmp = qcow2_snapshot_load_tmp, | ||
164 | + .bdrv_measure = qcow2_measure, | ||
165 | .bdrv_get_info = qcow2_get_info, | ||
166 | .bdrv_get_specific_info = qcow2_get_specific_info, | ||
167 | |||
168 | -- | ||
169 | 2.9.4 | ||
170 | |||
171 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Stefan Hajnoczi <stefanha@redhat.com> | ||
2 | 1 | ||
3 | The measure subcommand calculates the size required by a new image file. | ||
4 | This can be used by users or management tools that need to allocate | ||
5 | space on an LVM volume, SAN LUN, etc before creating or converting an | ||
6 | image file. | ||
7 | |||
8 | Suggested-by: Maor Lipchuk <mlipchuk@redhat.com> | ||
9 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
10 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
11 | Message-id: 20170705125738.8777-8-stefanha@redhat.com | ||
12 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
13 | --- | ||
14 | qemu-img.c | 234 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||
15 | qemu-img-cmds.hx | 6 ++ | ||
16 | qemu-img.texi | 30 +++++++ | ||
17 | 3 files changed, 270 insertions(+) | ||
18 | |||
19 | diff --git a/qemu-img.c b/qemu-img.c | ||
20 | index XXXXXXX..XXXXXXX 100644 | ||
21 | --- a/qemu-img.c | ||
22 | +++ b/qemu-img.c | ||
23 | @@ -XXX,XX +XXX,XX @@ enum { | ||
24 | OPTION_FLUSH_INTERVAL = 261, | ||
25 | OPTION_NO_DRAIN = 262, | ||
26 | OPTION_TARGET_IMAGE_OPTS = 263, | ||
27 | + OPTION_SIZE = 264, | ||
28 | }; | ||
29 | |||
30 | typedef enum OutputFormat { | ||
31 | @@ -XXX,XX +XXX,XX @@ out: | ||
32 | return 0; | ||
33 | } | ||
34 | |||
35 | +static void dump_json_block_measure_info(BlockMeasureInfo *info) | ||
36 | +{ | ||
37 | + QString *str; | ||
38 | + QObject *obj; | ||
39 | + Visitor *v = qobject_output_visitor_new(&obj); | ||
40 | + | ||
41 | + visit_type_BlockMeasureInfo(v, NULL, &info, &error_abort); | ||
42 | + visit_complete(v, &obj); | ||
43 | + str = qobject_to_json_pretty(obj); | ||
44 | + assert(str != NULL); | ||
45 | + printf("%s\n", qstring_get_str(str)); | ||
46 | + qobject_decref(obj); | ||
47 | + visit_free(v); | ||
48 | + QDECREF(str); | ||
49 | +} | ||
50 | + | ||
51 | +static int img_measure(int argc, char **argv) | ||
52 | +{ | ||
53 | + static const struct option long_options[] = { | ||
54 | + {"help", no_argument, 0, 'h'}, | ||
55 | + {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS}, | ||
56 | + {"object", required_argument, 0, OPTION_OBJECT}, | ||
57 | + {"output", required_argument, 0, OPTION_OUTPUT}, | ||
58 | + {"size", required_argument, 0, OPTION_SIZE}, | ||
59 | + {"force-share", no_argument, 0, 'U'}, | ||
60 | + {0, 0, 0, 0} | ||
61 | + }; | ||
62 | + OutputFormat output_format = OFORMAT_HUMAN; | ||
63 | + BlockBackend *in_blk = NULL; | ||
64 | + BlockDriver *drv; | ||
65 | + const char *filename = NULL; | ||
66 | + const char *fmt = NULL; | ||
67 | + const char *out_fmt = "raw"; | ||
68 | + char *options = NULL; | ||
69 | + char *snapshot_name = NULL; | ||
70 | + bool force_share = false; | ||
71 | + QemuOpts *opts = NULL; | ||
72 | + QemuOpts *object_opts = NULL; | ||
73 | + QemuOpts *sn_opts = NULL; | ||
74 | + QemuOptsList *create_opts = NULL; | ||
75 | + bool image_opts = false; | ||
76 | + uint64_t img_size = UINT64_MAX; | ||
77 | + BlockMeasureInfo *info = NULL; | ||
78 | + Error *local_err = NULL; | ||
79 | + int ret = 1; | ||
80 | + int c; | ||
81 | + | ||
82 | + while ((c = getopt_long(argc, argv, "hf:O:o:l:U", | ||
83 | + long_options, NULL)) != -1) { | ||
84 | + switch (c) { | ||
85 | + case '?': | ||
86 | + case 'h': | ||
87 | + help(); | ||
88 | + break; | ||
89 | + case 'f': | ||
90 | + fmt = optarg; | ||
91 | + break; | ||
92 | + case 'O': | ||
93 | + out_fmt = optarg; | ||
94 | + break; | ||
95 | + case 'o': | ||
96 | + if (!is_valid_option_list(optarg)) { | ||
97 | + error_report("Invalid option list: %s", optarg); | ||
98 | + goto out; | ||
99 | + } | ||
100 | + if (!options) { | ||
101 | + options = g_strdup(optarg); | ||
102 | + } else { | ||
103 | + char *old_options = options; | ||
104 | + options = g_strdup_printf("%s,%s", options, optarg); | ||
105 | + g_free(old_options); | ||
106 | + } | ||
107 | + break; | ||
108 | + case 'l': | ||
109 | + if (strstart(optarg, SNAPSHOT_OPT_BASE, NULL)) { | ||
110 | + sn_opts = qemu_opts_parse_noisily(&internal_snapshot_opts, | ||
111 | + optarg, false); | ||
112 | + if (!sn_opts) { | ||
113 | + error_report("Failed in parsing snapshot param '%s'", | ||
114 | + optarg); | ||
115 | + goto out; | ||
116 | + } | ||
117 | + } else { | ||
118 | + snapshot_name = optarg; | ||
119 | + } | ||
120 | + break; | ||
121 | + case 'U': | ||
122 | + force_share = true; | ||
123 | + break; | ||
124 | + case OPTION_OBJECT: | ||
125 | + object_opts = qemu_opts_parse_noisily(&qemu_object_opts, | ||
126 | + optarg, true); | ||
127 | + if (!object_opts) { | ||
128 | + goto out; | ||
129 | + } | ||
130 | + break; | ||
131 | + case OPTION_IMAGE_OPTS: | ||
132 | + image_opts = true; | ||
133 | + break; | ||
134 | + case OPTION_OUTPUT: | ||
135 | + if (!strcmp(optarg, "json")) { | ||
136 | + output_format = OFORMAT_JSON; | ||
137 | + } else if (!strcmp(optarg, "human")) { | ||
138 | + output_format = OFORMAT_HUMAN; | ||
139 | + } else { | ||
140 | + error_report("--output must be used with human or json " | ||
141 | + "as argument."); | ||
142 | + goto out; | ||
143 | + } | ||
144 | + break; | ||
145 | + case OPTION_SIZE: | ||
146 | + { | ||
147 | + int64_t sval; | ||
148 | + | ||
149 | + sval = cvtnum(optarg); | ||
150 | + if (sval < 0) { | ||
151 | + if (sval == -ERANGE) { | ||
152 | + error_report("Image size must be less than 8 EiB!"); | ||
153 | + } else { | ||
154 | + error_report("Invalid image size specified! You may use " | ||
155 | + "k, M, G, T, P or E suffixes for "); | ||
156 | + error_report("kilobytes, megabytes, gigabytes, terabytes, " | ||
157 | + "petabytes and exabytes."); | ||
158 | + } | ||
159 | + goto out; | ||
160 | + } | ||
161 | + img_size = (uint64_t)sval; | ||
162 | + } | ||
163 | + break; | ||
164 | + } | ||
165 | + } | ||
166 | + | ||
167 | + if (qemu_opts_foreach(&qemu_object_opts, | ||
168 | + user_creatable_add_opts_foreach, | ||
169 | + NULL, NULL)) { | ||
170 | + goto out; | ||
171 | + } | ||
172 | + | ||
173 | + if (argc - optind > 1) { | ||
174 | + error_report("At most one filename argument is allowed."); | ||
175 | + goto out; | ||
176 | + } else if (argc - optind == 1) { | ||
177 | + filename = argv[optind]; | ||
178 | + } | ||
179 | + | ||
180 | + if (!filename && | ||
181 | + (object_opts || image_opts || fmt || snapshot_name || sn_opts)) { | ||
182 | + error_report("--object, --image-opts, -f, and -l " | ||
183 | + "require a filename argument."); | ||
184 | + goto out; | ||
185 | + } | ||
186 | + if (filename && img_size != UINT64_MAX) { | ||
187 | + error_report("--size N cannot be used together with a filename."); | ||
188 | + goto out; | ||
189 | + } | ||
190 | + if (!filename && img_size == UINT64_MAX) { | ||
191 | + error_report("Either --size N or one filename must be specified."); | ||
192 | + goto out; | ||
193 | + } | ||
194 | + | ||
195 | + if (filename) { | ||
196 | + in_blk = img_open(image_opts, filename, fmt, 0, | ||
197 | + false, false, force_share); | ||
198 | + if (!in_blk) { | ||
199 | + goto out; | ||
200 | + } | ||
201 | + | ||
202 | + if (sn_opts) { | ||
203 | + bdrv_snapshot_load_tmp(blk_bs(in_blk), | ||
204 | + qemu_opt_get(sn_opts, SNAPSHOT_OPT_ID), | ||
205 | + qemu_opt_get(sn_opts, SNAPSHOT_OPT_NAME), | ||
206 | + &local_err); | ||
207 | + } else if (snapshot_name != NULL) { | ||
208 | + bdrv_snapshot_load_tmp_by_id_or_name(blk_bs(in_blk), | ||
209 | + snapshot_name, &local_err); | ||
210 | + } | ||
211 | + if (local_err) { | ||
212 | + error_reportf_err(local_err, "Failed to load snapshot: "); | ||
213 | + goto out; | ||
214 | + } | ||
215 | + } | ||
216 | + | ||
217 | + drv = bdrv_find_format(out_fmt); | ||
218 | + if (!drv) { | ||
219 | + error_report("Unknown file format '%s'", out_fmt); | ||
220 | + goto out; | ||
221 | + } | ||
222 | + if (!drv->create_opts) { | ||
223 | + error_report("Format driver '%s' does not support image creation", | ||
224 | + drv->format_name); | ||
225 | + goto out; | ||
226 | + } | ||
227 | + | ||
228 | + create_opts = qemu_opts_append(create_opts, drv->create_opts); | ||
229 | + create_opts = qemu_opts_append(create_opts, bdrv_file.create_opts); | ||
230 | + opts = qemu_opts_create(create_opts, NULL, 0, &error_abort); | ||
231 | + if (options) { | ||
232 | + qemu_opts_do_parse(opts, options, NULL, &local_err); | ||
233 | + if (local_err) { | ||
234 | + error_report_err(local_err); | ||
235 | + error_report("Invalid options for file format '%s'", out_fmt); | ||
236 | + goto out; | ||
237 | + } | ||
238 | + } | ||
239 | + if (img_size != UINT64_MAX) { | ||
240 | + qemu_opt_set_number(opts, BLOCK_OPT_SIZE, img_size, &error_abort); | ||
241 | + } | ||
242 | + | ||
243 | + info = bdrv_measure(drv, opts, in_blk ? blk_bs(in_blk) : NULL, &local_err); | ||
244 | + if (local_err) { | ||
245 | + error_report_err(local_err); | ||
246 | + goto out; | ||
247 | + } | ||
248 | + | ||
249 | + if (output_format == OFORMAT_HUMAN) { | ||
250 | + printf("required size: %" PRIu64 "\n", info->required); | ||
251 | + printf("fully allocated size: %" PRIu64 "\n", info->fully_allocated); | ||
252 | + } else { | ||
253 | + dump_json_block_measure_info(info); | ||
254 | + } | ||
255 | + | ||
256 | + ret = 0; | ||
257 | + | ||
258 | +out: | ||
259 | + qapi_free_BlockMeasureInfo(info); | ||
260 | + qemu_opts_del(object_opts); | ||
261 | + qemu_opts_del(opts); | ||
262 | + qemu_opts_del(sn_opts); | ||
263 | + qemu_opts_free(create_opts); | ||
264 | + g_free(options); | ||
265 | + blk_unref(in_blk); | ||
266 | + return ret; | ||
267 | +} | ||
268 | |||
269 | static const img_cmd_t img_cmds[] = { | ||
270 | #define DEF(option, callback, arg_string) \ | ||
271 | diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx | ||
272 | index XXXXXXX..XXXXXXX 100644 | ||
273 | --- a/qemu-img-cmds.hx | ||
274 | +++ b/qemu-img-cmds.hx | ||
275 | @@ -XXX,XX +XXX,XX @@ STEXI | ||
276 | @item map [--object @var{objectdef}] [--image-opts] [-f @var{fmt}] [--output=@var{ofmt}] [-U] @var{filename} | ||
277 | ETEXI | ||
278 | |||
279 | +DEF("measure", img_measure, | ||
280 | +"measure [--output=ofmt] [-O output_fmt] [-o options] [--size N | [--object objectdef] [--image-opts] [-f fmt] [-l snapshot_param] filename]") | ||
281 | +STEXI | ||
282 | +@item measure [--output=@var{ofmt}] [-O @var{output_fmt}] [-o @var{options}] [--size @var{N} | [--object @var{objectdef}] [--image-opts] [-f @var{fmt}] [-l @var{snapshot_param}] @var{filename}] | ||
283 | +ETEXI | ||
284 | + | ||
285 | DEF("snapshot", img_snapshot, | ||
286 | "snapshot [--object objectdef] [--image-opts] [-U] [-q] [-l | -a snapshot | -c snapshot | -d snapshot] filename") | ||
287 | STEXI | ||
288 | diff --git a/qemu-img.texi b/qemu-img.texi | ||
289 | index XXXXXXX..XXXXXXX 100644 | ||
290 | --- a/qemu-img.texi | ||
291 | +++ b/qemu-img.texi | ||
292 | @@ -XXX,XX +XXX,XX @@ preallocated. | ||
293 | For more information, consult @file{include/block/block.h} in QEMU's | ||
294 | source code. | ||
295 | |||
296 | +@item measure [--output=@var{ofmt}] [-O @var{output_fmt}] [-o @var{options}] [--size @var{N} | [--object @var{objectdef}] [--image-opts] [-f @var{fmt}] [-l @var{snapshot_param}] @var{filename}] | ||
297 | + | ||
298 | +Calculate the file size required for a new image. This information can be used | ||
299 | +to size logical volumes or SAN LUNs appropriately for the image that will be | ||
300 | +placed in them. The values reported are guaranteed to be large enough to fit | ||
301 | +the image. The command can output in the format @var{ofmt} which is either | ||
302 | +@code{human} or @code{json}. | ||
303 | + | ||
304 | +If the size @var{N} is given then act as if creating a new empty image file | ||
305 | +using @command{qemu-img create}. If @var{filename} is given then act as if | ||
306 | +converting an existing image file using @command{qemu-img convert}. The format | ||
307 | +of the new file is given by @var{output_fmt} while the format of an existing | ||
308 | +file is given by @var{fmt}. | ||
309 | + | ||
310 | +A snapshot in an existing image can be specified using @var{snapshot_param}. | ||
311 | + | ||
312 | +The following fields are reported: | ||
313 | +@example | ||
314 | +required size: 524288 | ||
315 | +fully allocated size: 1074069504 | ||
316 | +@end example | ||
317 | + | ||
318 | +The @code{required size} is the file size of the new image. It may be smaller | ||
319 | +than the virtual disk size if the image format supports compact representation. | ||
320 | + | ||
321 | +The @code{fully allocated size} is the file size of the new image once data has | ||
322 | +been written to all sectors. This is the maximum size that the image file can | ||
323 | +occupy with the exception of internal snapshots, dirty bitmaps, vmstate data, | ||
324 | +and other advanced image format features. | ||
325 | + | ||
326 | @item snapshot [-l | -a @var{snapshot} | -c @var{snapshot} | -d @var{snapshot} ] @var{filename} | ||
327 | |||
328 | List, apply, create or delete snapshots in image @var{filename}. | ||
329 | -- | ||
330 | 2.9.4 | ||
331 | |||
332 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Stefan Hajnoczi <stefanha@redhat.com> | ||
2 | 1 | ||
3 | Some tests produce format-dependent output. Either the difference is | ||
4 | filtered out and ignored, or the test case is format-specific so we | ||
5 | don't need to worry about per-format output differences. | ||
6 | |||
7 | There is a third case: the test script is the same for all image formats | ||
8 | and the format-dependent output is relevant. An ugly workaround is to | ||
9 | copy-paste the test into multiple per-format test cases. This | ||
10 | duplicates code and is not maintainable. | ||
11 | |||
12 | This patch allows test cases to add per-format golden output files so a | ||
13 | single test case can work correctly when format-dependent output must be | ||
14 | checked: | ||
15 | |||
16 | 123.out.qcow2 | ||
17 | 123.out.raw | ||
18 | 123.out.vmdk | ||
19 | ... | ||
20 | |||
21 | This naming scheme is not composable with 123.out.nocache or 123.pc.out, | ||
22 | two other scenarios where output files are split. I don't think it | ||
23 | matters since few test cases need these features. | ||
24 | |||
25 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
26 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
27 | Message-id: 20170705125738.8777-9-stefanha@redhat.com | ||
28 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
29 | --- | ||
30 | tests/qemu-iotests/check | 5 +++++ | ||
31 | 1 file changed, 5 insertions(+) | ||
32 | |||
33 | diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check | ||
34 | index XXXXXXX..XXXXXXX 100755 | ||
35 | --- a/tests/qemu-iotests/check | ||
36 | +++ b/tests/qemu-iotests/check | ||
37 | @@ -XXX,XX +XXX,XX @@ do | ||
38 | reference="$reference_machine" | ||
39 | fi | ||
40 | |||
41 | + reference_format="$source_iotests/$seq.out.$IMGFMT" | ||
42 | + if [ -f "$reference_format" ]; then | ||
43 | + reference="$reference_format" | ||
44 | + fi | ||
45 | + | ||
46 | if [ "$CACHEMODE" = "none" ]; then | ||
47 | [ -f "$source_iotests/$seq.out.nocache" ] && reference="$source_iotests/$seq.out.nocache" | ||
48 | fi | ||
49 | -- | ||
50 | 2.9.4 | ||
51 | |||
52 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Stefan Hajnoczi <stefanha@redhat.com> | ||
2 | 1 | ||
3 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
4 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
5 | Message-id: 20170705125738.8777-10-stefanha@redhat.com | ||
6 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
7 | --- | ||
8 | tests/qemu-iotests/178 | 170 +++++++++++++++++++++++ | ||
9 | tests/qemu-iotests/178.out.qcow2 | 286 +++++++++++++++++++++++++++++++++++++++ | ||
10 | tests/qemu-iotests/178.out.raw | 158 +++++++++++++++++++++ | ||
11 | tests/qemu-iotests/group | 1 + | ||
12 | 4 files changed, 615 insertions(+) | ||
13 | create mode 100755 tests/qemu-iotests/178 | ||
14 | create mode 100644 tests/qemu-iotests/178.out.qcow2 | ||
15 | create mode 100644 tests/qemu-iotests/178.out.raw | ||
16 | |||
17 | diff --git a/tests/qemu-iotests/178 b/tests/qemu-iotests/178 | ||
18 | new file mode 100755 | ||
19 | index XXXXXXX..XXXXXXX | ||
20 | --- /dev/null | ||
21 | +++ b/tests/qemu-iotests/178 | ||
22 | @@ -XXX,XX +XXX,XX @@ | ||
23 | +#!/bin/bash | ||
24 | +# | ||
25 | +# qemu-img measure sub-command tests | ||
26 | +# | ||
27 | +# Copyright (C) 2017 Red Hat, Inc. | ||
28 | +# | ||
29 | +# This program is free software; you can redistribute it and/or modify | ||
30 | +# it under the terms of the GNU General Public License as published by | ||
31 | +# the Free Software Foundation; either version 2 of the License, or | ||
32 | +# (at your option) any later version. | ||
33 | +# | ||
34 | +# This program is distributed in the hope that it will be useful, | ||
35 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
36 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
37 | +# GNU General Public License for more details. | ||
38 | +# | ||
39 | +# You should have received a copy of the GNU General Public License | ||
40 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
41 | +# | ||
42 | + | ||
43 | +# creator | ||
44 | +owner=stefanha@redhat.com | ||
45 | + | ||
46 | +seq=`basename $0` | ||
47 | +echo "QA output created by $seq" | ||
48 | + | ||
49 | +here=`pwd` | ||
50 | +status=1 # failure is the default! | ||
51 | + | ||
52 | +_cleanup() | ||
53 | +{ | ||
54 | + _cleanup_test_img | ||
55 | + rm -f "$TEST_IMG.converted" | ||
56 | +} | ||
57 | +trap "_cleanup; exit \$status" 0 1 2 3 15 | ||
58 | + | ||
59 | +# get standard environment, filters and checks | ||
60 | +. ./common.rc | ||
61 | +. ./common.filter | ||
62 | +. ./common.pattern | ||
63 | + | ||
64 | +_supported_fmt raw qcow2 | ||
65 | +_supported_proto file | ||
66 | +_supported_os Linux | ||
67 | + | ||
68 | +echo "== Input validation ==" | ||
69 | +echo | ||
70 | + | ||
71 | +_make_test_img 1G | ||
72 | + | ||
73 | +$QEMU_IMG measure # missing arguments | ||
74 | +$QEMU_IMG measure --size 2G "$TEST_IMG" # only one allowed | ||
75 | +$QEMU_IMG measure "$TEST_IMG" a # only one filename allowed | ||
76 | +$QEMU_IMG measure --object secret,id=sec0,data=MTIzNDU2,format=base64 # missing filename | ||
77 | +$QEMU_IMG measure --image-opts # missing filename | ||
78 | +$QEMU_IMG measure -f qcow2 # missing filename | ||
79 | +$QEMU_IMG measure -l snap1 # missing filename | ||
80 | +$QEMU_IMG measure -o , # invalid option list | ||
81 | +$QEMU_IMG measure -l snapshot.foo # invalid snapshot option | ||
82 | +$QEMU_IMG measure --output foo # invalid output format | ||
83 | +$QEMU_IMG measure --size -1 # invalid image size | ||
84 | +$QEMU_IMG measure -O foo "$TEST_IMG" # unknown image file format | ||
85 | + | ||
86 | +make_test_img_with_fmt() { | ||
87 | + # Shadow global variables within this function | ||
88 | + local IMGFMT="$1" IMGOPTS="" | ||
89 | + _make_test_img "$2" | ||
90 | +} | ||
91 | + | ||
92 | +qemu_io_with_fmt() { | ||
93 | + # Shadow global variables within this function | ||
94 | + local QEMU_IO_OPTIONS=$(echo "$QEMU_IO_OPTIONS" | sed "s/-f $IMGFMT/-f $1/") | ||
95 | + shift | ||
96 | + $QEMU_IO "$@" | ||
97 | +} | ||
98 | + | ||
99 | +# The proof is in the pudding: converted image size cannot be larger than the | ||
100 | +# required size. | ||
101 | +# | ||
102 | +# Note: if a change to the image format code causes the file size to change, | ||
103 | +# then this test fails! This is good because it's a reminder to check that the | ||
104 | +# required size is still at least as big as the actual converted file size. | ||
105 | +convert_and_show_size() { | ||
106 | + local fmt="$1" | ||
107 | + shift | ||
108 | + $QEMU_IMG convert -f "$fmt" -O "$IMGFMT" "$TEST_IMG" "$@" "$TEST_IMG.converted" | ||
109 | + stat -c "converted image file size in bytes: %s" "$TEST_IMG.converted" | ||
110 | +} | ||
111 | + | ||
112 | +for ofmt in human json; do | ||
113 | + echo | ||
114 | + echo "== Size calculation for a new file ($ofmt) ==" | ||
115 | + echo | ||
116 | + | ||
117 | + # Try a few interesting sizes | ||
118 | + $QEMU_IMG measure --output=$ofmt -O "$IMGFMT" --size 0 | ||
119 | + $QEMU_IMG measure --output=$ofmt -O "$IMGFMT" --size 2G | ||
120 | + $QEMU_IMG measure --output=$ofmt -O "$IMGFMT" --size 64G | ||
121 | + $QEMU_IMG measure --output=$ofmt -O "$IMGFMT" --size 256G | ||
122 | + $QEMU_IMG measure --output=$ofmt -O "$IMGFMT" --size 1T | ||
123 | + $QEMU_IMG measure --output=$ofmt -O "$IMGFMT" --size 2P | ||
124 | + $QEMU_IMG measure --output=$ofmt -O "$IMGFMT" --size 7E | ||
125 | + | ||
126 | + # Always test the raw input files but also IMGFMT | ||
127 | + for fmt in $(echo -e "raw\n$IMGFMT\n" | sort -u); do | ||
128 | + echo | ||
129 | + echo "== Empty $fmt input image ($ofmt) ==" | ||
130 | + echo | ||
131 | + make_test_img_with_fmt "$fmt" 0 | ||
132 | + $QEMU_IMG measure --output=$ofmt -f "$fmt" -O "$IMGFMT" "$TEST_IMG" | ||
133 | + echo | ||
134 | + convert_and_show_size "$fmt" | ||
135 | + | ||
136 | + echo | ||
137 | + echo "== $fmt input image with data ($ofmt) ==" | ||
138 | + echo | ||
139 | + make_test_img_with_fmt "$fmt" 1G | ||
140 | + $QEMU_IMG measure --output=$ofmt -f "$fmt" -O "$IMGFMT" "$TEST_IMG" | ||
141 | + qemu_io_with_fmt "$fmt" -c "write 512 512" "$TEST_IMG" | _filter_qemu_io | ||
142 | + qemu_io_with_fmt "$fmt" -c "write 64K 64K" "$TEST_IMG" | _filter_qemu_io | ||
143 | + if [ "$fmt" = "qcow2" ]; then | ||
144 | + $QEMU_IMG snapshot -c snapshot1 "$TEST_IMG" | ||
145 | + fi | ||
146 | + qemu_io_with_fmt "$fmt" -c "write 128M 63K" "$TEST_IMG" | _filter_qemu_io | ||
147 | + $QEMU_IMG measure --output=$ofmt -f "$fmt" -O "$IMGFMT" "$TEST_IMG" | ||
148 | + echo | ||
149 | + convert_and_show_size "$fmt" | ||
150 | + | ||
151 | + if [ "$fmt" = "qcow2" ]; then | ||
152 | + echo | ||
153 | + echo "== $fmt input image with internal snapshot ($ofmt) ==" | ||
154 | + echo | ||
155 | + $QEMU_IMG measure --output=$ofmt -f "$fmt" -l snapshot1 \ | ||
156 | + -O "$IMGFMT" "$TEST_IMG" | ||
157 | + echo | ||
158 | + convert_and_show_size "$fmt" -l snapshot1 | ||
159 | + fi | ||
160 | + | ||
161 | + if [ "$IMGFMT" = "qcow2" ]; then | ||
162 | + echo | ||
163 | + echo "== $fmt input image and a backing file ($ofmt) ==" | ||
164 | + echo | ||
165 | + # The backing file doesn't need to exist :) | ||
166 | + $QEMU_IMG measure --output=$ofmt -o backing_file=x \ | ||
167 | + -f "$fmt" -O "$IMGFMT" "$TEST_IMG" | ||
168 | + fi | ||
169 | + | ||
170 | + echo | ||
171 | + echo "== $fmt input image and preallocation ($ofmt) ==" | ||
172 | + echo | ||
173 | + $QEMU_IMG measure --output=$ofmt -o preallocation=full \ | ||
174 | + -f "$fmt" -O "$IMGFMT" "$TEST_IMG" | ||
175 | + echo | ||
176 | + convert_and_show_size "$fmt" -o preallocation=full | ||
177 | + | ||
178 | + echo | ||
179 | + echo "== Fully-allocated $fmt input image ($ofmt) ==" | ||
180 | + echo | ||
181 | + make_test_img_with_fmt "$fmt" 8M | ||
182 | + qemu_io_with_fmt "$fmt" -c "write 0 8M" "$TEST_IMG" | _filter_qemu_io | ||
183 | + $QEMU_IMG measure --output=$ofmt -f "$fmt" -O "$IMGFMT" "$TEST_IMG" | ||
184 | + echo | ||
185 | + convert_and_show_size "$fmt" | ||
186 | + done | ||
187 | +done | ||
188 | + | ||
189 | +# success, all done | ||
190 | +echo "*** done" | ||
191 | +rm -f $seq.full | ||
192 | +status=0 | ||
193 | diff --git a/tests/qemu-iotests/178.out.qcow2 b/tests/qemu-iotests/178.out.qcow2 | ||
194 | new file mode 100644 | ||
195 | index XXXXXXX..XXXXXXX | ||
196 | --- /dev/null | ||
197 | +++ b/tests/qemu-iotests/178.out.qcow2 | ||
198 | @@ -XXX,XX +XXX,XX @@ | ||
199 | +QA output created by 178 | ||
200 | +== Input validation == | ||
201 | + | ||
202 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 | ||
203 | +qemu-img: Either --size N or one filename must be specified. | ||
204 | +qemu-img: --size N cannot be used together with a filename. | ||
205 | +qemu-img: At most one filename argument is allowed. | ||
206 | +qemu-img: --object, --image-opts, -f, and -l require a filename argument. | ||
207 | +qemu-img: --object, --image-opts, -f, and -l require a filename argument. | ||
208 | +qemu-img: --object, --image-opts, -f, and -l require a filename argument. | ||
209 | +qemu-img: --object, --image-opts, -f, and -l require a filename argument. | ||
210 | +qemu-img: Invalid option list: , | ||
211 | +qemu-img: Invalid parameter 'snapshot.foo' | ||
212 | +qemu-img: Failed in parsing snapshot param 'snapshot.foo' | ||
213 | +qemu-img: --output must be used with human or json as argument. | ||
214 | +qemu-img: Image size must be less than 8 EiB! | ||
215 | +qemu-img: Unknown file format 'foo' | ||
216 | + | ||
217 | +== Size calculation for a new file (human) == | ||
218 | + | ||
219 | +required size: 196608 | ||
220 | +fully allocated size: 196608 | ||
221 | +required size: 589824 | ||
222 | +fully allocated size: 2148073472 | ||
223 | +required size: 10747904 | ||
224 | +fully allocated size: 68730224640 | ||
225 | +required size: 42205184 | ||
226 | +fully allocated size: 274920112128 | ||
227 | +required size: 168034304 | ||
228 | +fully allocated size: 1099679662080 | ||
229 | +required size: 343650009088 | ||
230 | +fully allocated size: 2252143463694336 | ||
231 | +qemu-img: The image size is too large (try using a larger cluster size) | ||
232 | + | ||
233 | +== Empty qcow2 input image (human) == | ||
234 | + | ||
235 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=0 | ||
236 | +required size: 196608 | ||
237 | +fully allocated size: 196608 | ||
238 | + | ||
239 | +converted image file size in bytes: 196608 | ||
240 | + | ||
241 | +== qcow2 input image with data (human) == | ||
242 | + | ||
243 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 | ||
244 | +required size: 393216 | ||
245 | +fully allocated size: 1074135040 | ||
246 | +wrote 512/512 bytes at offset 512 | ||
247 | +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
248 | +wrote 65536/65536 bytes at offset 65536 | ||
249 | +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
250 | +wrote 64512/64512 bytes at offset 134217728 | ||
251 | +63 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
252 | +required size: 589824 | ||
253 | +fully allocated size: 1074135040 | ||
254 | + | ||
255 | +converted image file size in bytes: 524288 | ||
256 | + | ||
257 | +== qcow2 input image with internal snapshot (human) == | ||
258 | + | ||
259 | +required size: 524288 | ||
260 | +fully allocated size: 1074135040 | ||
261 | + | ||
262 | +converted image file size in bytes: 458752 | ||
263 | + | ||
264 | +== qcow2 input image and a backing file (human) == | ||
265 | + | ||
266 | +required size: 1074135040 | ||
267 | +fully allocated size: 1074135040 | ||
268 | + | ||
269 | +== qcow2 input image and preallocation (human) == | ||
270 | + | ||
271 | +required size: 1074135040 | ||
272 | +fully allocated size: 1074135040 | ||
273 | + | ||
274 | +converted image file size in bytes: 1074135040 | ||
275 | + | ||
276 | +== Fully-allocated qcow2 input image (human) == | ||
277 | + | ||
278 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=8388608 | ||
279 | +wrote 8388608/8388608 bytes at offset 0 | ||
280 | +8 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
281 | +required size: 8716288 | ||
282 | +fully allocated size: 8716288 | ||
283 | + | ||
284 | +converted image file size in bytes: 8716288 | ||
285 | + | ||
286 | +== Empty raw input image (human) == | ||
287 | + | ||
288 | +Formatting 'TEST_DIR/t.qcow2', fmt=IMGFMT size=0 | ||
289 | +required size: 196608 | ||
290 | +fully allocated size: 196608 | ||
291 | + | ||
292 | +converted image file size in bytes: 196608 | ||
293 | + | ||
294 | +== raw input image with data (human) == | ||
295 | + | ||
296 | +Formatting 'TEST_DIR/t.qcow2', fmt=IMGFMT size=1073741824 | ||
297 | +required size: 393216 | ||
298 | +fully allocated size: 1074135040 | ||
299 | +wrote 512/512 bytes at offset 512 | ||
300 | +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
301 | +wrote 65536/65536 bytes at offset 65536 | ||
302 | +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
303 | +wrote 64512/64512 bytes at offset 134217728 | ||
304 | +63 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
305 | +required size: 589824 | ||
306 | +fully allocated size: 1074135040 | ||
307 | + | ||
308 | +converted image file size in bytes: 524288 | ||
309 | + | ||
310 | +== raw input image and a backing file (human) == | ||
311 | + | ||
312 | +required size: 1074135040 | ||
313 | +fully allocated size: 1074135040 | ||
314 | + | ||
315 | +== raw input image and preallocation (human) == | ||
316 | + | ||
317 | +required size: 1074135040 | ||
318 | +fully allocated size: 1074135040 | ||
319 | + | ||
320 | +converted image file size in bytes: 1074135040 | ||
321 | + | ||
322 | +== Fully-allocated raw input image (human) == | ||
323 | + | ||
324 | +Formatting 'TEST_DIR/t.qcow2', fmt=IMGFMT size=8388608 | ||
325 | +wrote 8388608/8388608 bytes at offset 0 | ||
326 | +8 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
327 | +required size: 8716288 | ||
328 | +fully allocated size: 8716288 | ||
329 | + | ||
330 | +converted image file size in bytes: 8716288 | ||
331 | + | ||
332 | +== Size calculation for a new file (json) == | ||
333 | + | ||
334 | +{ | ||
335 | + "required": 196608, | ||
336 | + "fully-allocated": 196608 | ||
337 | +} | ||
338 | +{ | ||
339 | + "required": 589824, | ||
340 | + "fully-allocated": 2148073472 | ||
341 | +} | ||
342 | +{ | ||
343 | + "required": 10747904, | ||
344 | + "fully-allocated": 68730224640 | ||
345 | +} | ||
346 | +{ | ||
347 | + "required": 42205184, | ||
348 | + "fully-allocated": 274920112128 | ||
349 | +} | ||
350 | +{ | ||
351 | + "required": 168034304, | ||
352 | + "fully-allocated": 1099679662080 | ||
353 | +} | ||
354 | +{ | ||
355 | + "required": 343650009088, | ||
356 | + "fully-allocated": 2252143463694336 | ||
357 | +} | ||
358 | +qemu-img: The image size is too large (try using a larger cluster size) | ||
359 | + | ||
360 | +== Empty qcow2 input image (json) == | ||
361 | + | ||
362 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=0 | ||
363 | +{ | ||
364 | + "required": 196608, | ||
365 | + "fully-allocated": 196608 | ||
366 | +} | ||
367 | + | ||
368 | +converted image file size in bytes: 196608 | ||
369 | + | ||
370 | +== qcow2 input image with data (json) == | ||
371 | + | ||
372 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 | ||
373 | +{ | ||
374 | + "required": 393216, | ||
375 | + "fully-allocated": 1074135040 | ||
376 | +} | ||
377 | +wrote 512/512 bytes at offset 512 | ||
378 | +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
379 | +wrote 65536/65536 bytes at offset 65536 | ||
380 | +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
381 | +wrote 64512/64512 bytes at offset 134217728 | ||
382 | +63 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
383 | +{ | ||
384 | + "required": 589824, | ||
385 | + "fully-allocated": 1074135040 | ||
386 | +} | ||
387 | + | ||
388 | +converted image file size in bytes: 524288 | ||
389 | + | ||
390 | +== qcow2 input image with internal snapshot (json) == | ||
391 | + | ||
392 | +{ | ||
393 | + "required": 524288, | ||
394 | + "fully-allocated": 1074135040 | ||
395 | +} | ||
396 | + | ||
397 | +converted image file size in bytes: 458752 | ||
398 | + | ||
399 | +== qcow2 input image and a backing file (json) == | ||
400 | + | ||
401 | +{ | ||
402 | + "required": 1074135040, | ||
403 | + "fully-allocated": 1074135040 | ||
404 | +} | ||
405 | + | ||
406 | +== qcow2 input image and preallocation (json) == | ||
407 | + | ||
408 | +{ | ||
409 | + "required": 1074135040, | ||
410 | + "fully-allocated": 1074135040 | ||
411 | +} | ||
412 | + | ||
413 | +converted image file size in bytes: 1074135040 | ||
414 | + | ||
415 | +== Fully-allocated qcow2 input image (json) == | ||
416 | + | ||
417 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=8388608 | ||
418 | +wrote 8388608/8388608 bytes at offset 0 | ||
419 | +8 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
420 | +{ | ||
421 | + "required": 8716288, | ||
422 | + "fully-allocated": 8716288 | ||
423 | +} | ||
424 | + | ||
425 | +converted image file size in bytes: 8716288 | ||
426 | + | ||
427 | +== Empty raw input image (json) == | ||
428 | + | ||
429 | +Formatting 'TEST_DIR/t.qcow2', fmt=IMGFMT size=0 | ||
430 | +{ | ||
431 | + "required": 196608, | ||
432 | + "fully-allocated": 196608 | ||
433 | +} | ||
434 | + | ||
435 | +converted image file size in bytes: 196608 | ||
436 | + | ||
437 | +== raw input image with data (json) == | ||
438 | + | ||
439 | +Formatting 'TEST_DIR/t.qcow2', fmt=IMGFMT size=1073741824 | ||
440 | +{ | ||
441 | + "required": 393216, | ||
442 | + "fully-allocated": 1074135040 | ||
443 | +} | ||
444 | +wrote 512/512 bytes at offset 512 | ||
445 | +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
446 | +wrote 65536/65536 bytes at offset 65536 | ||
447 | +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
448 | +wrote 64512/64512 bytes at offset 134217728 | ||
449 | +63 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
450 | +{ | ||
451 | + "required": 589824, | ||
452 | + "fully-allocated": 1074135040 | ||
453 | +} | ||
454 | + | ||
455 | +converted image file size in bytes: 524288 | ||
456 | + | ||
457 | +== raw input image and a backing file (json) == | ||
458 | + | ||
459 | +{ | ||
460 | + "required": 1074135040, | ||
461 | + "fully-allocated": 1074135040 | ||
462 | +} | ||
463 | + | ||
464 | +== raw input image and preallocation (json) == | ||
465 | + | ||
466 | +{ | ||
467 | + "required": 1074135040, | ||
468 | + "fully-allocated": 1074135040 | ||
469 | +} | ||
470 | + | ||
471 | +converted image file size in bytes: 1074135040 | ||
472 | + | ||
473 | +== Fully-allocated raw input image (json) == | ||
474 | + | ||
475 | +Formatting 'TEST_DIR/t.qcow2', fmt=IMGFMT size=8388608 | ||
476 | +wrote 8388608/8388608 bytes at offset 0 | ||
477 | +8 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
478 | +{ | ||
479 | + "required": 8716288, | ||
480 | + "fully-allocated": 8716288 | ||
481 | +} | ||
482 | + | ||
483 | +converted image file size in bytes: 8716288 | ||
484 | +*** done | ||
485 | diff --git a/tests/qemu-iotests/178.out.raw b/tests/qemu-iotests/178.out.raw | ||
486 | new file mode 100644 | ||
487 | index XXXXXXX..XXXXXXX | ||
488 | --- /dev/null | ||
489 | +++ b/tests/qemu-iotests/178.out.raw | ||
490 | @@ -XXX,XX +XXX,XX @@ | ||
491 | +QA output created by 178 | ||
492 | +== Input validation == | ||
493 | + | ||
494 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 | ||
495 | +qemu-img: Either --size N or one filename must be specified. | ||
496 | +qemu-img: --size N cannot be used together with a filename. | ||
497 | +qemu-img: At most one filename argument is allowed. | ||
498 | +qemu-img: --object, --image-opts, -f, and -l require a filename argument. | ||
499 | +qemu-img: --object, --image-opts, -f, and -l require a filename argument. | ||
500 | +qemu-img: --object, --image-opts, -f, and -l require a filename argument. | ||
501 | +qemu-img: --object, --image-opts, -f, and -l require a filename argument. | ||
502 | +qemu-img: Invalid option list: , | ||
503 | +qemu-img: Invalid parameter 'snapshot.foo' | ||
504 | +qemu-img: Failed in parsing snapshot param 'snapshot.foo' | ||
505 | +qemu-img: --output must be used with human or json as argument. | ||
506 | +qemu-img: Image size must be less than 8 EiB! | ||
507 | +qemu-img: Unknown file format 'foo' | ||
508 | + | ||
509 | +== Size calculation for a new file (human) == | ||
510 | + | ||
511 | +required size: 0 | ||
512 | +fully allocated size: 0 | ||
513 | +required size: 2147483648 | ||
514 | +fully allocated size: 2147483648 | ||
515 | +required size: 68719476736 | ||
516 | +fully allocated size: 68719476736 | ||
517 | +required size: 274877906944 | ||
518 | +fully allocated size: 274877906944 | ||
519 | +required size: 1099511627776 | ||
520 | +fully allocated size: 1099511627776 | ||
521 | +required size: 2251799813685248 | ||
522 | +fully allocated size: 2251799813685248 | ||
523 | +required size: 8070450532247928832 | ||
524 | +fully allocated size: 8070450532247928832 | ||
525 | + | ||
526 | +== Empty raw input image (human) == | ||
527 | + | ||
528 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=0 | ||
529 | +required size: 0 | ||
530 | +fully allocated size: 0 | ||
531 | + | ||
532 | +converted image file size in bytes: 0 | ||
533 | + | ||
534 | +== raw input image with data (human) == | ||
535 | + | ||
536 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 | ||
537 | +required size: 1073741824 | ||
538 | +fully allocated size: 1073741824 | ||
539 | +wrote 512/512 bytes at offset 512 | ||
540 | +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
541 | +wrote 65536/65536 bytes at offset 65536 | ||
542 | +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
543 | +wrote 64512/64512 bytes at offset 134217728 | ||
544 | +63 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
545 | +required size: 1073741824 | ||
546 | +fully allocated size: 1073741824 | ||
547 | + | ||
548 | +converted image file size in bytes: 1073741824 | ||
549 | + | ||
550 | +== raw input image and preallocation (human) == | ||
551 | + | ||
552 | +required size: 1073741824 | ||
553 | +fully allocated size: 1073741824 | ||
554 | + | ||
555 | +converted image file size in bytes: 1073741824 | ||
556 | + | ||
557 | +== Fully-allocated raw input image (human) == | ||
558 | + | ||
559 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=8388608 | ||
560 | +wrote 8388608/8388608 bytes at offset 0 | ||
561 | +8 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
562 | +required size: 8388608 | ||
563 | +fully allocated size: 8388608 | ||
564 | + | ||
565 | +converted image file size in bytes: 8388608 | ||
566 | + | ||
567 | +== Size calculation for a new file (json) == | ||
568 | + | ||
569 | +{ | ||
570 | + "required": 0, | ||
571 | + "fully-allocated": 0 | ||
572 | +} | ||
573 | +{ | ||
574 | + "required": 2147483648, | ||
575 | + "fully-allocated": 2147483648 | ||
576 | +} | ||
577 | +{ | ||
578 | + "required": 68719476736, | ||
579 | + "fully-allocated": 68719476736 | ||
580 | +} | ||
581 | +{ | ||
582 | + "required": 274877906944, | ||
583 | + "fully-allocated": 274877906944 | ||
584 | +} | ||
585 | +{ | ||
586 | + "required": 1099511627776, | ||
587 | + "fully-allocated": 1099511627776 | ||
588 | +} | ||
589 | +{ | ||
590 | + "required": 2251799813685248, | ||
591 | + "fully-allocated": 2251799813685248 | ||
592 | +} | ||
593 | +{ | ||
594 | + "required": 8070450532247928832, | ||
595 | + "fully-allocated": 8070450532247928832 | ||
596 | +} | ||
597 | + | ||
598 | +== Empty raw input image (json) == | ||
599 | + | ||
600 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=0 | ||
601 | +{ | ||
602 | + "required": 0, | ||
603 | + "fully-allocated": 0 | ||
604 | +} | ||
605 | + | ||
606 | +converted image file size in bytes: 0 | ||
607 | + | ||
608 | +== raw input image with data (json) == | ||
609 | + | ||
610 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 | ||
611 | +{ | ||
612 | + "required": 1073741824, | ||
613 | + "fully-allocated": 1073741824 | ||
614 | +} | ||
615 | +wrote 512/512 bytes at offset 512 | ||
616 | +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
617 | +wrote 65536/65536 bytes at offset 65536 | ||
618 | +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
619 | +wrote 64512/64512 bytes at offset 134217728 | ||
620 | +63 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
621 | +{ | ||
622 | + "required": 1073741824, | ||
623 | + "fully-allocated": 1073741824 | ||
624 | +} | ||
625 | + | ||
626 | +converted image file size in bytes: 1073741824 | ||
627 | + | ||
628 | +== raw input image and preallocation (json) == | ||
629 | + | ||
630 | +{ | ||
631 | + "required": 1073741824, | ||
632 | + "fully-allocated": 1073741824 | ||
633 | +} | ||
634 | + | ||
635 | +converted image file size in bytes: 1073741824 | ||
636 | + | ||
637 | +== Fully-allocated raw input image (json) == | ||
638 | + | ||
639 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=8388608 | ||
640 | +wrote 8388608/8388608 bytes at offset 0 | ||
641 | +8 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
642 | +{ | ||
643 | + "required": 8388608, | ||
644 | + "fully-allocated": 8388608 | ||
645 | +} | ||
646 | + | ||
647 | +converted image file size in bytes: 8388608 | ||
648 | +*** done | ||
649 | diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group | ||
650 | index XXXXXXX..XXXXXXX 100644 | ||
651 | --- a/tests/qemu-iotests/group | ||
652 | +++ b/tests/qemu-iotests/group | ||
653 | @@ -XXX,XX +XXX,XX @@ | ||
654 | 175 auto quick | ||
655 | 176 rw auto backing | ||
656 | 177 rw auto quick | ||
657 | +178 auto quick | ||
658 | 179 rw auto quick | ||
659 | 181 rw auto migration | ||
660 | 182 rw auto quick | ||
661 | -- | ||
662 | 2.9.4 | ||
663 | |||
664 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | Add a PreallocMode parameter to the bdrv_truncate() function implemented | ||
2 | by each block driver. Currently, we always pass PREALLOC_MODE_OFF and no | ||
3 | driver accepts anything else. | ||
4 | 1 | ||
5 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
6 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
7 | Message-id: 20170613202107.10125-2-mreitz@redhat.com | ||
8 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
9 | --- | ||
10 | include/block/block_int.h | 3 ++- | ||
11 | block.c | 2 +- | ||
12 | block/blkdebug.c | 9 ++++++++- | ||
13 | block/crypto.c | 8 +++++++- | ||
14 | block/file-posix.c | 9 ++++++++- | ||
15 | block/file-win32.c | 9 ++++++++- | ||
16 | block/gluster.c | 8 +++++++- | ||
17 | block/iscsi.c | 9 ++++++++- | ||
18 | block/nfs.c | 9 ++++++++- | ||
19 | block/qcow2.c | 9 ++++++++- | ||
20 | block/qed.c | 9 ++++++++- | ||
21 | block/raw-format.c | 9 ++++++++- | ||
22 | block/rbd.c | 9 ++++++++- | ||
23 | block/sheepdog.c | 11 +++++++++-- | ||
24 | 14 files changed, 98 insertions(+), 15 deletions(-) | ||
25 | |||
26 | diff --git a/include/block/block_int.h b/include/block/block_int.h | ||
27 | index XXXXXXX..XXXXXXX 100644 | ||
28 | --- a/include/block/block_int.h | ||
29 | +++ b/include/block/block_int.h | ||
30 | @@ -XXX,XX +XXX,XX @@ struct BlockDriver { | ||
31 | int coroutine_fn (*bdrv_co_flush_to_os)(BlockDriverState *bs); | ||
32 | |||
33 | const char *protocol_name; | ||
34 | - int (*bdrv_truncate)(BlockDriverState *bs, int64_t offset, Error **errp); | ||
35 | + int (*bdrv_truncate)(BlockDriverState *bs, int64_t offset, | ||
36 | + PreallocMode prealloc, Error **errp); | ||
37 | |||
38 | int64_t (*bdrv_getlength)(BlockDriverState *bs); | ||
39 | bool has_variable_length; | ||
40 | diff --git a/block.c b/block.c | ||
41 | index XXXXXXX..XXXXXXX 100644 | ||
42 | --- a/block.c | ||
43 | +++ b/block.c | ||
44 | @@ -XXX,XX +XXX,XX @@ int bdrv_truncate(BdrvChild *child, int64_t offset, Error **errp) | ||
45 | |||
46 | assert(!(bs->open_flags & BDRV_O_INACTIVE)); | ||
47 | |||
48 | - ret = drv->bdrv_truncate(bs, offset, errp); | ||
49 | + ret = drv->bdrv_truncate(bs, offset, PREALLOC_MODE_OFF, errp); | ||
50 | if (ret == 0) { | ||
51 | ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS); | ||
52 | bdrv_dirty_bitmap_truncate(bs); | ||
53 | diff --git a/block/blkdebug.c b/block/blkdebug.c | ||
54 | index XXXXXXX..XXXXXXX 100644 | ||
55 | --- a/block/blkdebug.c | ||
56 | +++ b/block/blkdebug.c | ||
57 | @@ -XXX,XX +XXX,XX @@ static int64_t blkdebug_getlength(BlockDriverState *bs) | ||
58 | return bdrv_getlength(bs->file->bs); | ||
59 | } | ||
60 | |||
61 | -static int blkdebug_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | ||
62 | +static int blkdebug_truncate(BlockDriverState *bs, int64_t offset, | ||
63 | + PreallocMode prealloc, Error **errp) | ||
64 | { | ||
65 | + if (prealloc != PREALLOC_MODE_OFF) { | ||
66 | + error_setg(errp, "Unsupported preallocation mode '%s'", | ||
67 | + PreallocMode_lookup[prealloc]); | ||
68 | + return -ENOTSUP; | ||
69 | + } | ||
70 | + | ||
71 | return bdrv_truncate(bs->file, offset, errp); | ||
72 | } | ||
73 | |||
74 | diff --git a/block/crypto.c b/block/crypto.c | ||
75 | index XXXXXXX..XXXXXXX 100644 | ||
76 | --- a/block/crypto.c | ||
77 | +++ b/block/crypto.c | ||
78 | @@ -XXX,XX +XXX,XX @@ static int block_crypto_create_generic(QCryptoBlockFormat format, | ||
79 | } | ||
80 | |||
81 | static int block_crypto_truncate(BlockDriverState *bs, int64_t offset, | ||
82 | - Error **errp) | ||
83 | + PreallocMode prealloc, Error **errp) | ||
84 | { | ||
85 | BlockCrypto *crypto = bs->opaque; | ||
86 | size_t payload_offset = | ||
87 | qcrypto_block_get_payload_offset(crypto->block); | ||
88 | |||
89 | + if (prealloc != PREALLOC_MODE_OFF) { | ||
90 | + error_setg(errp, "Unsupported preallocation mode '%s'", | ||
91 | + PreallocMode_lookup[prealloc]); | ||
92 | + return -ENOTSUP; | ||
93 | + } | ||
94 | + | ||
95 | offset += payload_offset; | ||
96 | |||
97 | return bdrv_truncate(bs->file, offset, errp); | ||
98 | diff --git a/block/file-posix.c b/block/file-posix.c | ||
99 | index XXXXXXX..XXXXXXX 100644 | ||
100 | --- a/block/file-posix.c | ||
101 | +++ b/block/file-posix.c | ||
102 | @@ -XXX,XX +XXX,XX @@ static void raw_close(BlockDriverState *bs) | ||
103 | } | ||
104 | } | ||
105 | |||
106 | -static int raw_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | ||
107 | +static int raw_truncate(BlockDriverState *bs, int64_t offset, | ||
108 | + PreallocMode prealloc, Error **errp) | ||
109 | { | ||
110 | BDRVRawState *s = bs->opaque; | ||
111 | struct stat st; | ||
112 | int ret; | ||
113 | |||
114 | + if (prealloc != PREALLOC_MODE_OFF) { | ||
115 | + error_setg(errp, "Unsupported preallocation mode '%s'", | ||
116 | + PreallocMode_lookup[prealloc]); | ||
117 | + return -ENOTSUP; | ||
118 | + } | ||
119 | + | ||
120 | if (fstat(s->fd, &st)) { | ||
121 | ret = -errno; | ||
122 | error_setg_errno(errp, -ret, "Failed to fstat() the file"); | ||
123 | diff --git a/block/file-win32.c b/block/file-win32.c | ||
124 | index XXXXXXX..XXXXXXX 100644 | ||
125 | --- a/block/file-win32.c | ||
126 | +++ b/block/file-win32.c | ||
127 | @@ -XXX,XX +XXX,XX @@ static void raw_close(BlockDriverState *bs) | ||
128 | } | ||
129 | } | ||
130 | |||
131 | -static int raw_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | ||
132 | +static int raw_truncate(BlockDriverState *bs, int64_t offset, | ||
133 | + PreallocMode prealloc, Error **errp) | ||
134 | { | ||
135 | BDRVRawState *s = bs->opaque; | ||
136 | LONG low, high; | ||
137 | DWORD dwPtrLow; | ||
138 | |||
139 | + if (prealloc != PREALLOC_MODE_OFF) { | ||
140 | + error_setg(errp, "Unsupported preallocation mode '%s'", | ||
141 | + PreallocMode_lookup[prealloc]); | ||
142 | + return -ENOTSUP; | ||
143 | + } | ||
144 | + | ||
145 | low = offset; | ||
146 | high = offset >> 32; | ||
147 | |||
148 | diff --git a/block/gluster.c b/block/gluster.c | ||
149 | index XXXXXXX..XXXXXXX 100644 | ||
150 | --- a/block/gluster.c | ||
151 | +++ b/block/gluster.c | ||
152 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qemu_gluster_co_rw(BlockDriverState *bs, | ||
153 | } | ||
154 | |||
155 | static int qemu_gluster_truncate(BlockDriverState *bs, int64_t offset, | ||
156 | - Error **errp) | ||
157 | + PreallocMode prealloc, Error **errp) | ||
158 | { | ||
159 | int ret; | ||
160 | BDRVGlusterState *s = bs->opaque; | ||
161 | |||
162 | + if (prealloc != PREALLOC_MODE_OFF) { | ||
163 | + error_setg(errp, "Unsupported preallocation mode '%s'", | ||
164 | + PreallocMode_lookup[prealloc]); | ||
165 | + return -ENOTSUP; | ||
166 | + } | ||
167 | + | ||
168 | ret = glfs_ftruncate(s->fd, offset); | ||
169 | if (ret < 0) { | ||
170 | ret = -errno; | ||
171 | diff --git a/block/iscsi.c b/block/iscsi.c | ||
172 | index XXXXXXX..XXXXXXX 100644 | ||
173 | --- a/block/iscsi.c | ||
174 | +++ b/block/iscsi.c | ||
175 | @@ -XXX,XX +XXX,XX @@ static void iscsi_reopen_commit(BDRVReopenState *reopen_state) | ||
176 | } | ||
177 | } | ||
178 | |||
179 | -static int iscsi_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | ||
180 | +static int iscsi_truncate(BlockDriverState *bs, int64_t offset, | ||
181 | + PreallocMode prealloc, Error **errp) | ||
182 | { | ||
183 | IscsiLun *iscsilun = bs->opaque; | ||
184 | Error *local_err = NULL; | ||
185 | |||
186 | + if (prealloc != PREALLOC_MODE_OFF) { | ||
187 | + error_setg(errp, "Unsupported preallocation mode '%s'", | ||
188 | + PreallocMode_lookup[prealloc]); | ||
189 | + return -ENOTSUP; | ||
190 | + } | ||
191 | + | ||
192 | if (iscsilun->type != TYPE_DISK) { | ||
193 | error_setg(errp, "Cannot resize non-disk iSCSI devices"); | ||
194 | return -ENOTSUP; | ||
195 | diff --git a/block/nfs.c b/block/nfs.c | ||
196 | index XXXXXXX..XXXXXXX 100644 | ||
197 | --- a/block/nfs.c | ||
198 | +++ b/block/nfs.c | ||
199 | @@ -XXX,XX +XXX,XX @@ static int64_t nfs_get_allocated_file_size(BlockDriverState *bs) | ||
200 | return (task.ret < 0 ? task.ret : st.st_blocks * 512); | ||
201 | } | ||
202 | |||
203 | -static int nfs_file_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | ||
204 | +static int nfs_file_truncate(BlockDriverState *bs, int64_t offset, | ||
205 | + PreallocMode prealloc, Error **errp) | ||
206 | { | ||
207 | NFSClient *client = bs->opaque; | ||
208 | int ret; | ||
209 | |||
210 | + if (prealloc != PREALLOC_MODE_OFF) { | ||
211 | + error_setg(errp, "Unsupported preallocation mode '%s'", | ||
212 | + PreallocMode_lookup[prealloc]); | ||
213 | + return -ENOTSUP; | ||
214 | + } | ||
215 | + | ||
216 | ret = nfs_ftruncate(client->context, client->fh, offset); | ||
217 | if (ret < 0) { | ||
218 | error_setg_errno(errp, -ret, "Failed to truncate file"); | ||
219 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
220 | index XXXXXXX..XXXXXXX 100644 | ||
221 | --- a/block/qcow2.c | ||
222 | +++ b/block/qcow2.c | ||
223 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_pdiscard(BlockDriverState *bs, | ||
224 | return ret; | ||
225 | } | ||
226 | |||
227 | -static int qcow2_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | ||
228 | +static int qcow2_truncate(BlockDriverState *bs, int64_t offset, | ||
229 | + PreallocMode prealloc, Error **errp) | ||
230 | { | ||
231 | BDRVQcow2State *s = bs->opaque; | ||
232 | int64_t new_l1_size; | ||
233 | int ret; | ||
234 | |||
235 | + if (prealloc != PREALLOC_MODE_OFF) { | ||
236 | + error_setg(errp, "Unsupported preallocation mode '%s'", | ||
237 | + PreallocMode_lookup[prealloc]); | ||
238 | + return -ENOTSUP; | ||
239 | + } | ||
240 | + | ||
241 | if (offset & 511) { | ||
242 | error_setg(errp, "The new size must be a multiple of 512"); | ||
243 | return -EINVAL; | ||
244 | diff --git a/block/qed.c b/block/qed.c | ||
245 | index XXXXXXX..XXXXXXX 100644 | ||
246 | --- a/block/qed.c | ||
247 | +++ b/block/qed.c | ||
248 | @@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs, | ||
249 | QED_AIOCB_WRITE | QED_AIOCB_ZERO); | ||
250 | } | ||
251 | |||
252 | -static int bdrv_qed_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | ||
253 | +static int bdrv_qed_truncate(BlockDriverState *bs, int64_t offset, | ||
254 | + PreallocMode prealloc, Error **errp) | ||
255 | { | ||
256 | BDRVQEDState *s = bs->opaque; | ||
257 | uint64_t old_image_size; | ||
258 | int ret; | ||
259 | |||
260 | + if (prealloc != PREALLOC_MODE_OFF) { | ||
261 | + error_setg(errp, "Unsupported preallocation mode '%s'", | ||
262 | + PreallocMode_lookup[prealloc]); | ||
263 | + return -ENOTSUP; | ||
264 | + } | ||
265 | + | ||
266 | if (!qed_is_image_size_valid(offset, s->header.cluster_size, | ||
267 | s->header.table_size)) { | ||
268 | error_setg(errp, "Invalid image size specified"); | ||
269 | diff --git a/block/raw-format.c b/block/raw-format.c | ||
270 | index XXXXXXX..XXXXXXX 100644 | ||
271 | --- a/block/raw-format.c | ||
272 | +++ b/block/raw-format.c | ||
273 | @@ -XXX,XX +XXX,XX @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp) | ||
274 | } | ||
275 | } | ||
276 | |||
277 | -static int raw_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | ||
278 | +static int raw_truncate(BlockDriverState *bs, int64_t offset, | ||
279 | + PreallocMode prealloc, Error **errp) | ||
280 | { | ||
281 | BDRVRawState *s = bs->opaque; | ||
282 | |||
283 | + if (prealloc != PREALLOC_MODE_OFF) { | ||
284 | + error_setg(errp, "Unsupported preallocation mode '%s'", | ||
285 | + PreallocMode_lookup[prealloc]); | ||
286 | + return -ENOTSUP; | ||
287 | + } | ||
288 | + | ||
289 | if (s->has_size) { | ||
290 | error_setg(errp, "Cannot resize fixed-size raw disks"); | ||
291 | return -ENOTSUP; | ||
292 | diff --git a/block/rbd.c b/block/rbd.c | ||
293 | index XXXXXXX..XXXXXXX 100644 | ||
294 | --- a/block/rbd.c | ||
295 | +++ b/block/rbd.c | ||
296 | @@ -XXX,XX +XXX,XX @@ static int64_t qemu_rbd_getlength(BlockDriverState *bs) | ||
297 | return info.size; | ||
298 | } | ||
299 | |||
300 | -static int qemu_rbd_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | ||
301 | +static int qemu_rbd_truncate(BlockDriverState *bs, int64_t offset, | ||
302 | + PreallocMode prealloc, Error **errp) | ||
303 | { | ||
304 | BDRVRBDState *s = bs->opaque; | ||
305 | int r; | ||
306 | |||
307 | + if (prealloc != PREALLOC_MODE_OFF) { | ||
308 | + error_setg(errp, "Unsupported preallocation mode '%s'", | ||
309 | + PreallocMode_lookup[prealloc]); | ||
310 | + return -ENOTSUP; | ||
311 | + } | ||
312 | + | ||
313 | r = rbd_resize(s->image, offset); | ||
314 | if (r < 0) { | ||
315 | error_setg_errno(errp, -r, "Failed to resize file"); | ||
316 | diff --git a/block/sheepdog.c b/block/sheepdog.c | ||
317 | index XXXXXXX..XXXXXXX 100644 | ||
318 | --- a/block/sheepdog.c | ||
319 | +++ b/block/sheepdog.c | ||
320 | @@ -XXX,XX +XXX,XX @@ static int64_t sd_getlength(BlockDriverState *bs) | ||
321 | return s->inode.vdi_size; | ||
322 | } | ||
323 | |||
324 | -static int sd_truncate(BlockDriverState *bs, int64_t offset, Error **errp) | ||
325 | +static int sd_truncate(BlockDriverState *bs, int64_t offset, | ||
326 | + PreallocMode prealloc, Error **errp) | ||
327 | { | ||
328 | BDRVSheepdogState *s = bs->opaque; | ||
329 | int ret, fd; | ||
330 | unsigned int datalen; | ||
331 | uint64_t max_vdi_size; | ||
332 | |||
333 | + if (prealloc != PREALLOC_MODE_OFF) { | ||
334 | + error_setg(errp, "Unsupported preallocation mode '%s'", | ||
335 | + PreallocMode_lookup[prealloc]); | ||
336 | + return -ENOTSUP; | ||
337 | + } | ||
338 | + | ||
339 | max_vdi_size = (UINT64_C(1) << s->inode.block_size_shift) * MAX_DATA_OBJS; | ||
340 | if (offset < s->inode.vdi_size) { | ||
341 | error_setg(errp, "shrinking is not supported"); | ||
342 | @@ -XXX,XX +XXX,XX @@ static coroutine_fn int sd_co_writev(BlockDriverState *bs, int64_t sector_num, | ||
343 | BDRVSheepdogState *s = bs->opaque; | ||
344 | |||
345 | if (offset > s->inode.vdi_size) { | ||
346 | - ret = sd_truncate(bs, offset, NULL); | ||
347 | + ret = sd_truncate(bs, offset, PREALLOC_MODE_OFF, NULL); | ||
348 | if (ret < 0) { | ||
349 | return ret; | ||
350 | } | ||
351 | -- | ||
352 | 2.9.4 | ||
353 | |||
354 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | For block drivers that just pass a truncate request to the underlying | ||
2 | protocol, we can now pass the preallocation mode instead of aborting if | ||
3 | it is not PREALLOC_MODE_OFF. | ||
4 | 1 | ||
5 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
6 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
7 | Message-id: 20170613202107.10125-3-mreitz@redhat.com | ||
8 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
9 | --- | ||
10 | include/block/block.h | 3 ++- | ||
11 | block.c | 5 +++-- | ||
12 | block/blkdebug.c | 8 +------- | ||
13 | block/block-backend.c | 2 +- | ||
14 | block/crypto.c | 8 +------- | ||
15 | block/parallels.c | 11 +++++++---- | ||
16 | block/qcow.c | 6 ++++-- | ||
17 | block/qcow2-refcount.c | 2 +- | ||
18 | block/qcow2.c | 4 ++-- | ||
19 | block/raw-format.c | 8 +------- | ||
20 | block/vhdx-log.c | 2 +- | ||
21 | block/vhdx.c | 3 ++- | ||
22 | 12 files changed, 26 insertions(+), 36 deletions(-) | ||
23 | |||
24 | diff --git a/include/block/block.h b/include/block/block.h | ||
25 | index XXXXXXX..XXXXXXX 100644 | ||
26 | --- a/include/block/block.h | ||
27 | +++ b/include/block/block.h | ||
28 | @@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs, | ||
29 | const char *backing_file); | ||
30 | int bdrv_get_backing_file_depth(BlockDriverState *bs); | ||
31 | void bdrv_refresh_filename(BlockDriverState *bs); | ||
32 | -int bdrv_truncate(BdrvChild *child, int64_t offset, Error **errp); | ||
33 | +int bdrv_truncate(BdrvChild *child, int64_t offset, PreallocMode prealloc, | ||
34 | + Error **errp); | ||
35 | int64_t bdrv_nb_sectors(BlockDriverState *bs); | ||
36 | int64_t bdrv_getlength(BlockDriverState *bs); | ||
37 | int64_t bdrv_get_allocated_file_size(BlockDriverState *bs); | ||
38 | diff --git a/block.c b/block.c | ||
39 | index XXXXXXX..XXXXXXX 100644 | ||
40 | --- a/block.c | ||
41 | +++ b/block.c | ||
42 | @@ -XXX,XX +XXX,XX @@ exit: | ||
43 | /** | ||
44 | * Truncate file to 'offset' bytes (needed only for file protocols) | ||
45 | */ | ||
46 | -int bdrv_truncate(BdrvChild *child, int64_t offset, Error **errp) | ||
47 | +int bdrv_truncate(BdrvChild *child, int64_t offset, PreallocMode prealloc, | ||
48 | + Error **errp) | ||
49 | { | ||
50 | BlockDriverState *bs = child->bs; | ||
51 | BlockDriver *drv = bs->drv; | ||
52 | @@ -XXX,XX +XXX,XX @@ int bdrv_truncate(BdrvChild *child, int64_t offset, Error **errp) | ||
53 | |||
54 | assert(!(bs->open_flags & BDRV_O_INACTIVE)); | ||
55 | |||
56 | - ret = drv->bdrv_truncate(bs, offset, PREALLOC_MODE_OFF, errp); | ||
57 | + ret = drv->bdrv_truncate(bs, offset, prealloc, errp); | ||
58 | if (ret == 0) { | ||
59 | ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS); | ||
60 | bdrv_dirty_bitmap_truncate(bs); | ||
61 | diff --git a/block/blkdebug.c b/block/blkdebug.c | ||
62 | index XXXXXXX..XXXXXXX 100644 | ||
63 | --- a/block/blkdebug.c | ||
64 | +++ b/block/blkdebug.c | ||
65 | @@ -XXX,XX +XXX,XX @@ static int64_t blkdebug_getlength(BlockDriverState *bs) | ||
66 | static int blkdebug_truncate(BlockDriverState *bs, int64_t offset, | ||
67 | PreallocMode prealloc, Error **errp) | ||
68 | { | ||
69 | - if (prealloc != PREALLOC_MODE_OFF) { | ||
70 | - error_setg(errp, "Unsupported preallocation mode '%s'", | ||
71 | - PreallocMode_lookup[prealloc]); | ||
72 | - return -ENOTSUP; | ||
73 | - } | ||
74 | - | ||
75 | - return bdrv_truncate(bs->file, offset, errp); | ||
76 | + return bdrv_truncate(bs->file, offset, prealloc, errp); | ||
77 | } | ||
78 | |||
79 | static void blkdebug_refresh_filename(BlockDriverState *bs, QDict *options) | ||
80 | diff --git a/block/block-backend.c b/block/block-backend.c | ||
81 | index XXXXXXX..XXXXXXX 100644 | ||
82 | --- a/block/block-backend.c | ||
83 | +++ b/block/block-backend.c | ||
84 | @@ -XXX,XX +XXX,XX @@ int blk_truncate(BlockBackend *blk, int64_t offset, Error **errp) | ||
85 | return -ENOMEDIUM; | ||
86 | } | ||
87 | |||
88 | - return bdrv_truncate(blk->root, offset, errp); | ||
89 | + return bdrv_truncate(blk->root, offset, PREALLOC_MODE_OFF, errp); | ||
90 | } | ||
91 | |||
92 | static void blk_pdiscard_entry(void *opaque) | ||
93 | diff --git a/block/crypto.c b/block/crypto.c | ||
94 | index XXXXXXX..XXXXXXX 100644 | ||
95 | --- a/block/crypto.c | ||
96 | +++ b/block/crypto.c | ||
97 | @@ -XXX,XX +XXX,XX @@ static int block_crypto_truncate(BlockDriverState *bs, int64_t offset, | ||
98 | size_t payload_offset = | ||
99 | qcrypto_block_get_payload_offset(crypto->block); | ||
100 | |||
101 | - if (prealloc != PREALLOC_MODE_OFF) { | ||
102 | - error_setg(errp, "Unsupported preallocation mode '%s'", | ||
103 | - PreallocMode_lookup[prealloc]); | ||
104 | - return -ENOTSUP; | ||
105 | - } | ||
106 | - | ||
107 | offset += payload_offset; | ||
108 | |||
109 | - return bdrv_truncate(bs->file, offset, errp); | ||
110 | + return bdrv_truncate(bs->file, offset, prealloc, errp); | ||
111 | } | ||
112 | |||
113 | static void block_crypto_close(BlockDriverState *bs) | ||
114 | diff --git a/block/parallels.c b/block/parallels.c | ||
115 | index XXXXXXX..XXXXXXX 100644 | ||
116 | --- a/block/parallels.c | ||
117 | +++ b/block/parallels.c | ||
118 | @@ -XXX,XX +XXX,XX @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num, | ||
119 | } else { | ||
120 | ret = bdrv_truncate(bs->file, | ||
121 | (s->data_end + space) << BDRV_SECTOR_BITS, | ||
122 | - NULL); | ||
123 | + PREALLOC_MODE_OFF, NULL); | ||
124 | } | ||
125 | if (ret < 0) { | ||
126 | return ret; | ||
127 | @@ -XXX,XX +XXX,XX @@ static int parallels_check(BlockDriverState *bs, BdrvCheckResult *res, | ||
128 | res->leaks += count; | ||
129 | if (fix & BDRV_FIX_LEAKS) { | ||
130 | Error *local_err = NULL; | ||
131 | - ret = bdrv_truncate(bs->file, res->image_end_offset, &local_err); | ||
132 | + ret = bdrv_truncate(bs->file, res->image_end_offset, | ||
133 | + PREALLOC_MODE_OFF, &local_err); | ||
134 | if (ret < 0) { | ||
135 | error_report_err(local_err); | ||
136 | res->check_errors++; | ||
137 | @@ -XXX,XX +XXX,XX @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags, | ||
138 | } | ||
139 | |||
140 | if (!(flags & BDRV_O_RESIZE) || !bdrv_has_zero_init(bs->file->bs) || | ||
141 | - bdrv_truncate(bs->file, bdrv_getlength(bs->file->bs), NULL) != 0) { | ||
142 | + bdrv_truncate(bs->file, bdrv_getlength(bs->file->bs), | ||
143 | + PREALLOC_MODE_OFF, NULL) != 0) { | ||
144 | s->prealloc_mode = PRL_PREALLOC_MODE_FALLOCATE; | ||
145 | } | ||
146 | |||
147 | @@ -XXX,XX +XXX,XX @@ static void parallels_close(BlockDriverState *bs) | ||
148 | } | ||
149 | |||
150 | if (bs->open_flags & BDRV_O_RDWR) { | ||
151 | - bdrv_truncate(bs->file, s->data_end << BDRV_SECTOR_BITS, NULL); | ||
152 | + bdrv_truncate(bs->file, s->data_end << BDRV_SECTOR_BITS, | ||
153 | + PREALLOC_MODE_OFF, NULL); | ||
154 | } | ||
155 | |||
156 | g_free(s->bat_dirty_bmap); | ||
157 | diff --git a/block/qcow.c b/block/qcow.c | ||
158 | index XXXXXXX..XXXXXXX 100644 | ||
159 | --- a/block/qcow.c | ||
160 | +++ b/block/qcow.c | ||
161 | @@ -XXX,XX +XXX,XX @@ static uint64_t get_cluster_offset(BlockDriverState *bs, | ||
162 | /* round to cluster size */ | ||
163 | cluster_offset = (cluster_offset + s->cluster_size - 1) & | ||
164 | ~(s->cluster_size - 1); | ||
165 | - bdrv_truncate(bs->file, cluster_offset + s->cluster_size, NULL); | ||
166 | + bdrv_truncate(bs->file, cluster_offset + s->cluster_size, | ||
167 | + PREALLOC_MODE_OFF, NULL); | ||
168 | /* if encrypted, we must initialize the cluster | ||
169 | content which won't be written */ | ||
170 | if (bs->encrypted && | ||
171 | @@ -XXX,XX +XXX,XX @@ static int qcow_make_empty(BlockDriverState *bs) | ||
172 | if (bdrv_pwrite_sync(bs->file, s->l1_table_offset, s->l1_table, | ||
173 | l1_length) < 0) | ||
174 | return -1; | ||
175 | - ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length, NULL); | ||
176 | + ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length, | ||
177 | + PREALLOC_MODE_OFF, NULL); | ||
178 | if (ret < 0) | ||
179 | return ret; | ||
180 | |||
181 | diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c | ||
182 | index XXXXXXX..XXXXXXX 100644 | ||
183 | --- a/block/qcow2-refcount.c | ||
184 | +++ b/block/qcow2-refcount.c | ||
185 | @@ -XXX,XX +XXX,XX @@ static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res, | ||
186 | } | ||
187 | |||
188 | ret = bdrv_truncate(bs->file, offset + s->cluster_size, | ||
189 | - &local_err); | ||
190 | + PREALLOC_MODE_OFF, &local_err); | ||
191 | if (ret < 0) { | ||
192 | error_report_err(local_err); | ||
193 | goto resize_fail; | ||
194 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
195 | index XXXXXXX..XXXXXXX 100644 | ||
196 | --- a/block/qcow2.c | ||
197 | +++ b/block/qcow2.c | ||
198 | @@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset, | ||
199 | /* align end of file to a sector boundary to ease reading with | ||
200 | sector based I/Os */ | ||
201 | cluster_offset = bdrv_getlength(bs->file->bs); | ||
202 | - return bdrv_truncate(bs->file, cluster_offset, NULL); | ||
203 | + return bdrv_truncate(bs->file, cluster_offset, PREALLOC_MODE_OFF, NULL); | ||
204 | } | ||
205 | |||
206 | buf = qemu_blockalign(bs, s->cluster_size); | ||
207 | @@ -XXX,XX +XXX,XX @@ static int make_completely_empty(BlockDriverState *bs) | ||
208 | } | ||
209 | |||
210 | ret = bdrv_truncate(bs->file, (3 + l1_clusters) * s->cluster_size, | ||
211 | - &local_err); | ||
212 | + PREALLOC_MODE_OFF, &local_err); | ||
213 | if (ret < 0) { | ||
214 | error_report_err(local_err); | ||
215 | goto fail; | ||
216 | diff --git a/block/raw-format.c b/block/raw-format.c | ||
217 | index XXXXXXX..XXXXXXX 100644 | ||
218 | --- a/block/raw-format.c | ||
219 | +++ b/block/raw-format.c | ||
220 | @@ -XXX,XX +XXX,XX @@ static int raw_truncate(BlockDriverState *bs, int64_t offset, | ||
221 | { | ||
222 | BDRVRawState *s = bs->opaque; | ||
223 | |||
224 | - if (prealloc != PREALLOC_MODE_OFF) { | ||
225 | - error_setg(errp, "Unsupported preallocation mode '%s'", | ||
226 | - PreallocMode_lookup[prealloc]); | ||
227 | - return -ENOTSUP; | ||
228 | - } | ||
229 | - | ||
230 | if (s->has_size) { | ||
231 | error_setg(errp, "Cannot resize fixed-size raw disks"); | ||
232 | return -ENOTSUP; | ||
233 | @@ -XXX,XX +XXX,XX @@ static int raw_truncate(BlockDriverState *bs, int64_t offset, | ||
234 | |||
235 | s->size = offset; | ||
236 | offset += s->offset; | ||
237 | - return bdrv_truncate(bs->file, offset, errp); | ||
238 | + return bdrv_truncate(bs->file, offset, prealloc, errp); | ||
239 | } | ||
240 | |||
241 | static int raw_media_changed(BlockDriverState *bs) | ||
242 | diff --git a/block/vhdx-log.c b/block/vhdx-log.c | ||
243 | index XXXXXXX..XXXXXXX 100644 | ||
244 | --- a/block/vhdx-log.c | ||
245 | +++ b/block/vhdx-log.c | ||
246 | @@ -XXX,XX +XXX,XX @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s, | ||
247 | if (new_file_size % (1024*1024)) { | ||
248 | /* round up to nearest 1MB boundary */ | ||
249 | new_file_size = ((new_file_size >> 20) + 1) << 20; | ||
250 | - bdrv_truncate(bs->file, new_file_size, NULL); | ||
251 | + bdrv_truncate(bs->file, new_file_size, PREALLOC_MODE_OFF, NULL); | ||
252 | } | ||
253 | } | ||
254 | qemu_vfree(desc_entries); | ||
255 | diff --git a/block/vhdx.c b/block/vhdx.c | ||
256 | index XXXXXXX..XXXXXXX 100644 | ||
257 | --- a/block/vhdx.c | ||
258 | +++ b/block/vhdx.c | ||
259 | @@ -XXX,XX +XXX,XX @@ static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s, | ||
260 | /* per the spec, the address for a block is in units of 1MB */ | ||
261 | *new_offset = ROUND_UP(*new_offset, 1024 * 1024); | ||
262 | |||
263 | - return bdrv_truncate(bs->file, *new_offset + s->block_size, NULL); | ||
264 | + return bdrv_truncate(bs->file, *new_offset + s->block_size, | ||
265 | + PREALLOC_MODE_OFF, NULL); | ||
266 | } | ||
267 | |||
268 | /* | ||
269 | -- | ||
270 | 2.9.4 | ||
271 | |||
272 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | blk_truncate() itself will pass that value to bdrv_truncate(), and all | ||
2 | callers of blk_truncate() just set the parameter to PREALLOC_MODE_OFF | ||
3 | for now. | ||
4 | 1 | ||
5 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
6 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
7 | Message-id: 20170613202107.10125-4-mreitz@redhat.com | ||
8 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
9 | --- | ||
10 | include/sysemu/block-backend.h | 3 ++- | ||
11 | block/block-backend.c | 5 +++-- | ||
12 | block/commit.c | 4 ++-- | ||
13 | block/mirror.c | 3 ++- | ||
14 | block/parallels.c | 2 +- | ||
15 | block/qcow.c | 2 +- | ||
16 | block/qcow2.c | 4 ++-- | ||
17 | block/qed.c | 2 +- | ||
18 | block/vdi.c | 3 ++- | ||
19 | block/vhdx.c | 5 +++-- | ||
20 | block/vmdk.c | 7 ++++--- | ||
21 | block/vpc.c | 2 +- | ||
22 | blockdev.c | 2 +- | ||
23 | qemu-img.c | 2 +- | ||
24 | qemu-io-cmds.c | 2 +- | ||
25 | 15 files changed, 27 insertions(+), 21 deletions(-) | ||
26 | |||
27 | diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h | ||
28 | index XXXXXXX..XXXXXXX 100644 | ||
29 | --- a/include/sysemu/block-backend.h | ||
30 | +++ b/include/sysemu/block-backend.h | ||
31 | @@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset, | ||
32 | int bytes, BdrvRequestFlags flags); | ||
33 | int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf, | ||
34 | int bytes); | ||
35 | -int blk_truncate(BlockBackend *blk, int64_t offset, Error **errp); | ||
36 | +int blk_truncate(BlockBackend *blk, int64_t offset, PreallocMode prealloc, | ||
37 | + Error **errp); | ||
38 | int blk_pdiscard(BlockBackend *blk, int64_t offset, int bytes); | ||
39 | int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf, | ||
40 | int64_t pos, int size); | ||
41 | diff --git a/block/block-backend.c b/block/block-backend.c | ||
42 | index XXXXXXX..XXXXXXX 100644 | ||
43 | --- a/block/block-backend.c | ||
44 | +++ b/block/block-backend.c | ||
45 | @@ -XXX,XX +XXX,XX @@ int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf, | ||
46 | BDRV_REQ_WRITE_COMPRESSED); | ||
47 | } | ||
48 | |||
49 | -int blk_truncate(BlockBackend *blk, int64_t offset, Error **errp) | ||
50 | +int blk_truncate(BlockBackend *blk, int64_t offset, PreallocMode prealloc, | ||
51 | + Error **errp) | ||
52 | { | ||
53 | if (!blk_is_available(blk)) { | ||
54 | error_setg(errp, "No medium inserted"); | ||
55 | return -ENOMEDIUM; | ||
56 | } | ||
57 | |||
58 | - return bdrv_truncate(blk->root, offset, PREALLOC_MODE_OFF, errp); | ||
59 | + return bdrv_truncate(blk->root, offset, prealloc, errp); | ||
60 | } | ||
61 | |||
62 | static void blk_pdiscard_entry(void *opaque) | ||
63 | diff --git a/block/commit.c b/block/commit.c | ||
64 | index XXXXXXX..XXXXXXX 100644 | ||
65 | --- a/block/commit.c | ||
66 | +++ b/block/commit.c | ||
67 | @@ -XXX,XX +XXX,XX @@ static void coroutine_fn commit_run(void *opaque) | ||
68 | } | ||
69 | |||
70 | if (base_len < s->common.len) { | ||
71 | - ret = blk_truncate(s->base, s->common.len, NULL); | ||
72 | + ret = blk_truncate(s->base, s->common.len, PREALLOC_MODE_OFF, NULL); | ||
73 | if (ret) { | ||
74 | goto out; | ||
75 | } | ||
76 | @@ -XXX,XX +XXX,XX @@ int bdrv_commit(BlockDriverState *bs) | ||
77 | * grow the backing file image if possible. If not possible, | ||
78 | * we must return an error */ | ||
79 | if (length > backing_length) { | ||
80 | - ret = blk_truncate(backing, length, &local_err); | ||
81 | + ret = blk_truncate(backing, length, PREALLOC_MODE_OFF, &local_err); | ||
82 | if (ret < 0) { | ||
83 | error_report_err(local_err); | ||
84 | goto ro_cleanup; | ||
85 | diff --git a/block/mirror.c b/block/mirror.c | ||
86 | index XXXXXXX..XXXXXXX 100644 | ||
87 | --- a/block/mirror.c | ||
88 | +++ b/block/mirror.c | ||
89 | @@ -XXX,XX +XXX,XX @@ static void coroutine_fn mirror_run(void *opaque) | ||
90 | } | ||
91 | |||
92 | if (s->bdev_length > base_length) { | ||
93 | - ret = blk_truncate(s->target, s->bdev_length, NULL); | ||
94 | + ret = blk_truncate(s->target, s->bdev_length, PREALLOC_MODE_OFF, | ||
95 | + NULL); | ||
96 | if (ret < 0) { | ||
97 | goto immediate_exit; | ||
98 | } | ||
99 | diff --git a/block/parallels.c b/block/parallels.c | ||
100 | index XXXXXXX..XXXXXXX 100644 | ||
101 | --- a/block/parallels.c | ||
102 | +++ b/block/parallels.c | ||
103 | @@ -XXX,XX +XXX,XX @@ static int parallels_create(const char *filename, QemuOpts *opts, Error **errp) | ||
104 | |||
105 | blk_set_allow_write_beyond_eof(file, true); | ||
106 | |||
107 | - ret = blk_truncate(file, 0, errp); | ||
108 | + ret = blk_truncate(file, 0, PREALLOC_MODE_OFF, errp); | ||
109 | if (ret < 0) { | ||
110 | goto exit; | ||
111 | } | ||
112 | diff --git a/block/qcow.c b/block/qcow.c | ||
113 | index XXXXXXX..XXXXXXX 100644 | ||
114 | --- a/block/qcow.c | ||
115 | +++ b/block/qcow.c | ||
116 | @@ -XXX,XX +XXX,XX @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp) | ||
117 | |||
118 | blk_set_allow_write_beyond_eof(qcow_blk, true); | ||
119 | |||
120 | - ret = blk_truncate(qcow_blk, 0, errp); | ||
121 | + ret = blk_truncate(qcow_blk, 0, PREALLOC_MODE_OFF, errp); | ||
122 | if (ret < 0) { | ||
123 | goto exit; | ||
124 | } | ||
125 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
126 | index XXXXXXX..XXXXXXX 100644 | ||
127 | --- a/block/qcow2.c | ||
128 | +++ b/block/qcow2.c | ||
129 | @@ -XXX,XX +XXX,XX @@ static int qcow2_create2(const char *filename, int64_t total_size, | ||
130 | } | ||
131 | |||
132 | /* Okay, now that we have a valid image, let's give it the right size */ | ||
133 | - ret = blk_truncate(blk, total_size, errp); | ||
134 | + ret = blk_truncate(blk, total_size, PREALLOC_MODE_OFF, errp); | ||
135 | if (ret < 0) { | ||
136 | error_prepend(errp, "Could not resize image: "); | ||
137 | goto out; | ||
138 | @@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts, | ||
139 | return ret; | ||
140 | } | ||
141 | |||
142 | - ret = blk_truncate(blk, new_size, &local_err); | ||
143 | + ret = blk_truncate(blk, new_size, PREALLOC_MODE_OFF, &local_err); | ||
144 | blk_unref(blk); | ||
145 | if (ret < 0) { | ||
146 | error_report_err(local_err); | ||
147 | diff --git a/block/qed.c b/block/qed.c | ||
148 | index XXXXXXX..XXXXXXX 100644 | ||
149 | --- a/block/qed.c | ||
150 | +++ b/block/qed.c | ||
151 | @@ -XXX,XX +XXX,XX @@ static int qed_create(const char *filename, uint32_t cluster_size, | ||
152 | blk_set_allow_write_beyond_eof(blk, true); | ||
153 | |||
154 | /* File must start empty and grow, check truncate is supported */ | ||
155 | - ret = blk_truncate(blk, 0, errp); | ||
156 | + ret = blk_truncate(blk, 0, PREALLOC_MODE_OFF, errp); | ||
157 | if (ret < 0) { | ||
158 | goto out; | ||
159 | } | ||
160 | diff --git a/block/vdi.c b/block/vdi.c | ||
161 | index XXXXXXX..XXXXXXX 100644 | ||
162 | --- a/block/vdi.c | ||
163 | +++ b/block/vdi.c | ||
164 | @@ -XXX,XX +XXX,XX @@ static int vdi_create(const char *filename, QemuOpts *opts, Error **errp) | ||
165 | } | ||
166 | |||
167 | if (image_type == VDI_TYPE_STATIC) { | ||
168 | - ret = blk_truncate(blk, offset + blocks * block_size, errp); | ||
169 | + ret = blk_truncate(blk, offset + blocks * block_size, | ||
170 | + PREALLOC_MODE_OFF, errp); | ||
171 | if (ret < 0) { | ||
172 | error_prepend(errp, "Failed to statically allocate %s", filename); | ||
173 | goto exit; | ||
174 | diff --git a/block/vhdx.c b/block/vhdx.c | ||
175 | index XXXXXXX..XXXXXXX 100644 | ||
176 | --- a/block/vhdx.c | ||
177 | +++ b/block/vhdx.c | ||
178 | @@ -XXX,XX +XXX,XX @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s, | ||
179 | if (type == VHDX_TYPE_DYNAMIC) { | ||
180 | /* All zeroes, so we can just extend the file - the end of the BAT | ||
181 | * is the furthest thing we have written yet */ | ||
182 | - ret = blk_truncate(blk, data_file_offset, errp); | ||
183 | + ret = blk_truncate(blk, data_file_offset, PREALLOC_MODE_OFF, errp); | ||
184 | if (ret < 0) { | ||
185 | goto exit; | ||
186 | } | ||
187 | } else if (type == VHDX_TYPE_FIXED) { | ||
188 | - ret = blk_truncate(blk, data_file_offset + image_size, errp); | ||
189 | + ret = blk_truncate(blk, data_file_offset + image_size, | ||
190 | + PREALLOC_MODE_OFF, errp); | ||
191 | if (ret < 0) { | ||
192 | goto exit; | ||
193 | } | ||
194 | diff --git a/block/vmdk.c b/block/vmdk.c | ||
195 | index XXXXXXX..XXXXXXX 100644 | ||
196 | --- a/block/vmdk.c | ||
197 | +++ b/block/vmdk.c | ||
198 | @@ -XXX,XX +XXX,XX @@ static int vmdk_create_extent(const char *filename, int64_t filesize, | ||
199 | blk_set_allow_write_beyond_eof(blk, true); | ||
200 | |||
201 | if (flat) { | ||
202 | - ret = blk_truncate(blk, filesize, errp); | ||
203 | + ret = blk_truncate(blk, filesize, PREALLOC_MODE_OFF, errp); | ||
204 | goto exit; | ||
205 | } | ||
206 | magic = cpu_to_be32(VMDK4_MAGIC); | ||
207 | @@ -XXX,XX +XXX,XX @@ static int vmdk_create_extent(const char *filename, int64_t filesize, | ||
208 | goto exit; | ||
209 | } | ||
210 | |||
211 | - ret = blk_truncate(blk, le64_to_cpu(header.grain_offset) << 9, errp); | ||
212 | + ret = blk_truncate(blk, le64_to_cpu(header.grain_offset) << 9, | ||
213 | + PREALLOC_MODE_OFF, errp); | ||
214 | if (ret < 0) { | ||
215 | goto exit; | ||
216 | } | ||
217 | @@ -XXX,XX +XXX,XX @@ static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp) | ||
218 | /* bdrv_pwrite write padding zeros to align to sector, we don't need that | ||
219 | * for description file */ | ||
220 | if (desc_offset == 0) { | ||
221 | - ret = blk_truncate(new_blk, desc_len, errp); | ||
222 | + ret = blk_truncate(new_blk, desc_len, PREALLOC_MODE_OFF, errp); | ||
223 | } | ||
224 | exit: | ||
225 | if (new_blk) { | ||
226 | diff --git a/block/vpc.c b/block/vpc.c | ||
227 | index XXXXXXX..XXXXXXX 100644 | ||
228 | --- a/block/vpc.c | ||
229 | +++ b/block/vpc.c | ||
230 | @@ -XXX,XX +XXX,XX @@ static int create_fixed_disk(BlockBackend *blk, uint8_t *buf, | ||
231 | /* Add footer to total size */ | ||
232 | total_size += HEADER_SIZE; | ||
233 | |||
234 | - ret = blk_truncate(blk, total_size, errp); | ||
235 | + ret = blk_truncate(blk, total_size, PREALLOC_MODE_OFF, errp); | ||
236 | if (ret < 0) { | ||
237 | return ret; | ||
238 | } | ||
239 | diff --git a/blockdev.c b/blockdev.c | ||
240 | index XXXXXXX..XXXXXXX 100644 | ||
241 | --- a/blockdev.c | ||
242 | +++ b/blockdev.c | ||
243 | @@ -XXX,XX +XXX,XX @@ void qmp_block_resize(bool has_device, const char *device, | ||
244 | } | ||
245 | |||
246 | bdrv_drained_begin(bs); | ||
247 | - ret = blk_truncate(blk, size, errp); | ||
248 | + ret = blk_truncate(blk, size, PREALLOC_MODE_OFF, errp); | ||
249 | bdrv_drained_end(bs); | ||
250 | |||
251 | out: | ||
252 | diff --git a/qemu-img.c b/qemu-img.c | ||
253 | index XXXXXXX..XXXXXXX 100644 | ||
254 | --- a/qemu-img.c | ||
255 | +++ b/qemu-img.c | ||
256 | @@ -XXX,XX +XXX,XX @@ static int img_resize(int argc, char **argv) | ||
257 | goto out; | ||
258 | } | ||
259 | |||
260 | - ret = blk_truncate(blk, total_size, &err); | ||
261 | + ret = blk_truncate(blk, total_size, PREALLOC_MODE_OFF, &err); | ||
262 | if (!ret) { | ||
263 | qprintf(quiet, "Image resized.\n"); | ||
264 | } else { | ||
265 | diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c | ||
266 | index XXXXXXX..XXXXXXX 100644 | ||
267 | --- a/qemu-io-cmds.c | ||
268 | +++ b/qemu-io-cmds.c | ||
269 | @@ -XXX,XX +XXX,XX @@ static int truncate_f(BlockBackend *blk, int argc, char **argv) | ||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | - ret = blk_truncate(blk, offset, &local_err); | ||
274 | + ret = blk_truncate(blk, offset, PREALLOC_MODE_OFF, &local_err); | ||
275 | if (ret < 0) { | ||
276 | error_report_err(local_err); | ||
277 | return 0; | ||
278 | -- | ||
279 | 2.9.4 | ||
280 | |||
281 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | Add a --preallocation command line option to qemu-img resize which can | ||
2 | be used to set the PreallocMode parameter of blk_truncate(). | ||
3 | 1 | ||
4 | While touching this code, fix the fact that we did not handle errors | ||
5 | returned by blk_getlength(). | ||
6 | |||
7 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
8 | Message-id: 20170613202107.10125-5-mreitz@redhat.com | ||
9 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
10 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
11 | --- | ||
12 | qemu-img.c | 33 ++++++++++++++++++++++++++++++--- | ||
13 | qemu-img.texi | 7 ++++++- | ||
14 | 2 files changed, 36 insertions(+), 4 deletions(-) | ||
15 | |||
16 | diff --git a/qemu-img.c b/qemu-img.c | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/qemu-img.c | ||
19 | +++ b/qemu-img.c | ||
20 | @@ -XXX,XX +XXX,XX @@ | ||
21 | #include "qemu/osdep.h" | ||
22 | #include "qemu-version.h" | ||
23 | #include "qapi/error.h" | ||
24 | +#include "qapi/util.h" | ||
25 | #include "qapi-visit.h" | ||
26 | #include "qapi/qobject-output-visitor.h" | ||
27 | #include "qapi/qmp/qerror.h" | ||
28 | @@ -XXX,XX +XXX,XX @@ enum { | ||
29 | OPTION_NO_DRAIN = 262, | ||
30 | OPTION_TARGET_IMAGE_OPTS = 263, | ||
31 | OPTION_SIZE = 264, | ||
32 | + OPTION_PREALLOCATION = 265, | ||
33 | }; | ||
34 | |||
35 | typedef enum OutputFormat { | ||
36 | @@ -XXX,XX +XXX,XX @@ static int img_resize(int argc, char **argv) | ||
37 | Error *err = NULL; | ||
38 | int c, ret, relative; | ||
39 | const char *filename, *fmt, *size; | ||
40 | - int64_t n, total_size; | ||
41 | + int64_t n, total_size, current_size; | ||
42 | bool quiet = false; | ||
43 | BlockBackend *blk = NULL; | ||
44 | + PreallocMode prealloc = PREALLOC_MODE_OFF; | ||
45 | QemuOpts *param; | ||
46 | |||
47 | static QemuOptsList resize_options = { | ||
48 | @@ -XXX,XX +XXX,XX @@ static int img_resize(int argc, char **argv) | ||
49 | {"help", no_argument, 0, 'h'}, | ||
50 | {"object", required_argument, 0, OPTION_OBJECT}, | ||
51 | {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS}, | ||
52 | + {"preallocation", required_argument, 0, OPTION_PREALLOCATION}, | ||
53 | {0, 0, 0, 0} | ||
54 | }; | ||
55 | c = getopt_long(argc, argv, ":f:hq", | ||
56 | @@ -XXX,XX +XXX,XX @@ static int img_resize(int argc, char **argv) | ||
57 | case OPTION_IMAGE_OPTS: | ||
58 | image_opts = true; | ||
59 | break; | ||
60 | + case OPTION_PREALLOCATION: | ||
61 | + prealloc = qapi_enum_parse(PreallocMode_lookup, optarg, | ||
62 | + PREALLOC_MODE__MAX, PREALLOC_MODE__MAX, | ||
63 | + NULL); | ||
64 | + if (prealloc == PREALLOC_MODE__MAX) { | ||
65 | + error_report("Invalid preallocation mode '%s'", optarg); | ||
66 | + return 1; | ||
67 | + } | ||
68 | + break; | ||
69 | } | ||
70 | } | ||
71 | if (optind != argc - 1) { | ||
72 | @@ -XXX,XX +XXX,XX @@ static int img_resize(int argc, char **argv) | ||
73 | goto out; | ||
74 | } | ||
75 | |||
76 | + current_size = blk_getlength(blk); | ||
77 | + if (current_size < 0) { | ||
78 | + error_report("Failed to inquire current image length: %s", | ||
79 | + strerror(-current_size)); | ||
80 | + ret = -1; | ||
81 | + goto out; | ||
82 | + } | ||
83 | + | ||
84 | if (relative) { | ||
85 | - total_size = blk_getlength(blk) + n * relative; | ||
86 | + total_size = current_size + n * relative; | ||
87 | } else { | ||
88 | total_size = n; | ||
89 | } | ||
90 | @@ -XXX,XX +XXX,XX @@ static int img_resize(int argc, char **argv) | ||
91 | goto out; | ||
92 | } | ||
93 | |||
94 | - ret = blk_truncate(blk, total_size, PREALLOC_MODE_OFF, &err); | ||
95 | + if (total_size <= current_size && prealloc != PREALLOC_MODE_OFF) { | ||
96 | + error_report("Preallocation can only be used for growing images"); | ||
97 | + ret = -1; | ||
98 | + goto out; | ||
99 | + } | ||
100 | + | ||
101 | + ret = blk_truncate(blk, total_size, prealloc, &err); | ||
102 | if (!ret) { | ||
103 | qprintf(quiet, "Image resized.\n"); | ||
104 | } else { | ||
105 | diff --git a/qemu-img.texi b/qemu-img.texi | ||
106 | index XXXXXXX..XXXXXXX 100644 | ||
107 | --- a/qemu-img.texi | ||
108 | +++ b/qemu-img.texi | ||
109 | @@ -XXX,XX +XXX,XX @@ qemu-img rebase -b base.img diff.qcow2 | ||
110 | At this point, @code{modified.img} can be discarded, since | ||
111 | @code{base.img + diff.qcow2} contains the same information. | ||
112 | |||
113 | -@item resize @var{filename} [+ | -]@var{size} | ||
114 | +@item resize [--preallocation=@var{prealloc}] @var{filename} [+ | -]@var{size} | ||
115 | |||
116 | Change the disk image as if it had been created with @var{size}. | ||
117 | |||
118 | @@ -XXX,XX +XXX,XX @@ After using this command to grow a disk image, you must use file system and | ||
119 | partitioning tools inside the VM to actually begin using the new space on the | ||
120 | device. | ||
121 | |||
122 | +When growing an image, the @code{--preallocation} option may be used to specify | ||
123 | +how the additional image area should be allocated on the host. See the format | ||
124 | +description in the @code{NOTES} section which values are allowed. Using this | ||
125 | +option may result in slightly more data being allocated than necessary. | ||
126 | + | ||
127 | @item amend [-p] [-f @var{fmt}] [-t @var{cache}] -o @var{options} @var{filename} | ||
128 | |||
129 | Amends the image format specific @var{options} for the image file | ||
130 | -- | ||
131 | 2.9.4 | ||
132 | |||
133 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | Variables should be declared at the start of a block, and if a certain | ||
2 | parameter value is not supported it may be better to return -ENOTSUP | ||
3 | instead of -EINVAL. | ||
4 | 1 | ||
5 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
6 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
7 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | ||
8 | Message-id: 20170613202107.10125-6-mreitz@redhat.com | ||
9 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
10 | --- | ||
11 | block/file-posix.c | 5 +++-- | ||
12 | 1 file changed, 3 insertions(+), 2 deletions(-) | ||
13 | |||
14 | diff --git a/block/file-posix.c b/block/file-posix.c | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/block/file-posix.c | ||
17 | +++ b/block/file-posix.c | ||
18 | @@ -XXX,XX +XXX,XX @@ static int raw_create(const char *filename, QemuOpts *opts, Error **errp) | ||
19 | #endif | ||
20 | case PREALLOC_MODE_FULL: | ||
21 | { | ||
22 | + int64_t num = 0, left = total_size; | ||
23 | + | ||
24 | /* | ||
25 | * Knowing the final size from the beginning could allow the file | ||
26 | * system driver to do less allocations and possibly avoid | ||
27 | @@ -XXX,XX +XXX,XX @@ static int raw_create(const char *filename, QemuOpts *opts, Error **errp) | ||
28 | goto out_close; | ||
29 | } | ||
30 | |||
31 | - int64_t num = 0, left = total_size; | ||
32 | buf = g_malloc0(65536); | ||
33 | |||
34 | while (left > 0) { | ||
35 | @@ -XXX,XX +XXX,XX @@ static int raw_create(const char *filename, QemuOpts *opts, Error **errp) | ||
36 | } | ||
37 | break; | ||
38 | default: | ||
39 | - result = -EINVAL; | ||
40 | + result = -ENOTSUP; | ||
41 | error_setg(errp, "Unsupported preallocation mode: %s", | ||
42 | PreallocMode_lookup[prealloc]); | ||
43 | break; | ||
44 | -- | ||
45 | 2.9.4 | ||
46 | |||
47 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | This functionality is part of raw_create() which we will be able to | ||
2 | reuse nicely in raw_truncate(). | ||
3 | 1 | ||
4 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
5 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
6 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | ||
7 | Message-id: 20170613202107.10125-7-mreitz@redhat.com | ||
8 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
9 | --- | ||
10 | block/file-posix.c | 144 +++++++++++++++++++++++++++++------------------------ | ||
11 | 1 file changed, 78 insertions(+), 66 deletions(-) | ||
12 | |||
13 | diff --git a/block/file-posix.c b/block/file-posix.c | ||
14 | index XXXXXXX..XXXXXXX 100644 | ||
15 | --- a/block/file-posix.c | ||
16 | +++ b/block/file-posix.c | ||
17 | @@ -XXX,XX +XXX,XX @@ static void raw_close(BlockDriverState *bs) | ||
18 | } | ||
19 | } | ||
20 | |||
21 | +static int raw_regular_truncate(int fd, int64_t offset, PreallocMode prealloc, | ||
22 | + Error **errp) | ||
23 | +{ | ||
24 | + int result = 0; | ||
25 | + char *buf; | ||
26 | + | ||
27 | + switch (prealloc) { | ||
28 | +#ifdef CONFIG_POSIX_FALLOCATE | ||
29 | + case PREALLOC_MODE_FALLOC: | ||
30 | + /* | ||
31 | + * Truncating before posix_fallocate() makes it about twice slower on | ||
32 | + * file systems that do not support fallocate(), trying to check if a | ||
33 | + * block is allocated before allocating it, so don't do that here. | ||
34 | + */ | ||
35 | + result = -posix_fallocate(fd, 0, offset); | ||
36 | + if (result != 0) { | ||
37 | + /* posix_fallocate() doesn't set errno. */ | ||
38 | + error_setg_errno(errp, -result, | ||
39 | + "Could not preallocate data for the new file"); | ||
40 | + } | ||
41 | + return result; | ||
42 | +#endif | ||
43 | + case PREALLOC_MODE_FULL: | ||
44 | + { | ||
45 | + int64_t num = 0, left = offset; | ||
46 | + | ||
47 | + /* | ||
48 | + * Knowing the final size from the beginning could allow the file | ||
49 | + * system driver to do less allocations and possibly avoid | ||
50 | + * fragmentation of the file. | ||
51 | + */ | ||
52 | + if (ftruncate(fd, offset) != 0) { | ||
53 | + result = -errno; | ||
54 | + error_setg_errno(errp, -result, "Could not resize file"); | ||
55 | + return result; | ||
56 | + } | ||
57 | + | ||
58 | + buf = g_malloc0(65536); | ||
59 | + | ||
60 | + while (left > 0) { | ||
61 | + num = MIN(left, 65536); | ||
62 | + result = write(fd, buf, num); | ||
63 | + if (result < 0) { | ||
64 | + result = -errno; | ||
65 | + error_setg_errno(errp, -result, | ||
66 | + "Could not write to the new file"); | ||
67 | + break; | ||
68 | + } | ||
69 | + left -= result; | ||
70 | + } | ||
71 | + if (result >= 0) { | ||
72 | + result = fsync(fd); | ||
73 | + if (result < 0) { | ||
74 | + result = -errno; | ||
75 | + error_setg_errno(errp, -result, | ||
76 | + "Could not flush new file to disk"); | ||
77 | + } | ||
78 | + } | ||
79 | + g_free(buf); | ||
80 | + return result; | ||
81 | + } | ||
82 | + case PREALLOC_MODE_OFF: | ||
83 | + if (ftruncate(fd, offset) != 0) { | ||
84 | + result = -errno; | ||
85 | + error_setg_errno(errp, -result, "Could not resize file"); | ||
86 | + } | ||
87 | + return result; | ||
88 | + default: | ||
89 | + result = -ENOTSUP; | ||
90 | + error_setg(errp, "Unsupported preallocation mode: %s", | ||
91 | + PreallocMode_lookup[prealloc]); | ||
92 | + return result; | ||
93 | + } | ||
94 | +} | ||
95 | + | ||
96 | static int raw_truncate(BlockDriverState *bs, int64_t offset, | ||
97 | PreallocMode prealloc, Error **errp) | ||
98 | { | ||
99 | @@ -XXX,XX +XXX,XX @@ static int raw_create(const char *filename, QemuOpts *opts, Error **errp) | ||
100 | #endif | ||
101 | } | ||
102 | |||
103 | - switch (prealloc) { | ||
104 | -#ifdef CONFIG_POSIX_FALLOCATE | ||
105 | - case PREALLOC_MODE_FALLOC: | ||
106 | - /* | ||
107 | - * Truncating before posix_fallocate() makes it about twice slower on | ||
108 | - * file systems that do not support fallocate(), trying to check if a | ||
109 | - * block is allocated before allocating it, so don't do that here. | ||
110 | - */ | ||
111 | - result = -posix_fallocate(fd, 0, total_size); | ||
112 | - if (result != 0) { | ||
113 | - /* posix_fallocate() doesn't set errno. */ | ||
114 | - error_setg_errno(errp, -result, | ||
115 | - "Could not preallocate data for the new file"); | ||
116 | - } | ||
117 | - break; | ||
118 | -#endif | ||
119 | - case PREALLOC_MODE_FULL: | ||
120 | - { | ||
121 | - int64_t num = 0, left = total_size; | ||
122 | - | ||
123 | - /* | ||
124 | - * Knowing the final size from the beginning could allow the file | ||
125 | - * system driver to do less allocations and possibly avoid | ||
126 | - * fragmentation of the file. | ||
127 | - */ | ||
128 | - if (ftruncate(fd, total_size) != 0) { | ||
129 | - result = -errno; | ||
130 | - error_setg_errno(errp, -result, "Could not resize file"); | ||
131 | - goto out_close; | ||
132 | - } | ||
133 | - | ||
134 | - buf = g_malloc0(65536); | ||
135 | - | ||
136 | - while (left > 0) { | ||
137 | - num = MIN(left, 65536); | ||
138 | - result = write(fd, buf, num); | ||
139 | - if (result < 0) { | ||
140 | - result = -errno; | ||
141 | - error_setg_errno(errp, -result, | ||
142 | - "Could not write to the new file"); | ||
143 | - break; | ||
144 | - } | ||
145 | - left -= result; | ||
146 | - } | ||
147 | - if (result >= 0) { | ||
148 | - result = fsync(fd); | ||
149 | - if (result < 0) { | ||
150 | - result = -errno; | ||
151 | - error_setg_errno(errp, -result, | ||
152 | - "Could not flush new file to disk"); | ||
153 | - } | ||
154 | - } | ||
155 | - g_free(buf); | ||
156 | - break; | ||
157 | - } | ||
158 | - case PREALLOC_MODE_OFF: | ||
159 | - if (ftruncate(fd, total_size) != 0) { | ||
160 | - result = -errno; | ||
161 | - error_setg_errno(errp, -result, "Could not resize file"); | ||
162 | - } | ||
163 | - break; | ||
164 | - default: | ||
165 | - result = -ENOTSUP; | ||
166 | - error_setg(errp, "Unsupported preallocation mode: %s", | ||
167 | - PreallocMode_lookup[prealloc]); | ||
168 | - break; | ||
169 | + result = raw_regular_truncate(fd, total_size, prealloc, errp); | ||
170 | + if (result < 0) { | ||
171 | + goto out_close; | ||
172 | } | ||
173 | |||
174 | out_close: | ||
175 | -- | ||
176 | 2.9.4 | ||
177 | |||
178 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | Currently, raw_regular_truncate() is intended for setting the size of a | ||
2 | newly created file. However, we also want to use it for truncating an | ||
3 | existing file in which case only the newly added space (when growing) | ||
4 | should be preallocated. | ||
5 | 1 | ||
6 | This also means that if resizing failed, we should try to restore the | ||
7 | original file size. This is important when using preallocation. | ||
8 | |||
9 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
10 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> | ||
11 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
12 | Message-id: 20170613202107.10125-8-mreitz@redhat.com | ||
13 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
14 | --- | ||
15 | block/file-posix.c | 61 ++++++++++++++++++++++++++++++++++++++++++++---------- | ||
16 | 1 file changed, 50 insertions(+), 11 deletions(-) | ||
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 void raw_close(BlockDriverState *bs) | ||
23 | } | ||
24 | } | ||
25 | |||
26 | +/** | ||
27 | + * Truncates the given regular file @fd to @offset and, when growing, fills the | ||
28 | + * new space according to @prealloc. | ||
29 | + * | ||
30 | + * Returns: 0 on success, -errno on failure. | ||
31 | + */ | ||
32 | static int raw_regular_truncate(int fd, int64_t offset, PreallocMode prealloc, | ||
33 | Error **errp) | ||
34 | { | ||
35 | int result = 0; | ||
36 | - char *buf; | ||
37 | + int64_t current_length = 0; | ||
38 | + char *buf = NULL; | ||
39 | + struct stat st; | ||
40 | + | ||
41 | + if (fstat(fd, &st) < 0) { | ||
42 | + result = -errno; | ||
43 | + error_setg_errno(errp, -result, "Could not stat file"); | ||
44 | + return result; | ||
45 | + } | ||
46 | + | ||
47 | + current_length = st.st_size; | ||
48 | + if (current_length > offset && prealloc != PREALLOC_MODE_OFF) { | ||
49 | + error_setg(errp, "Cannot use preallocation for shrinking files"); | ||
50 | + return -ENOTSUP; | ||
51 | + } | ||
52 | |||
53 | switch (prealloc) { | ||
54 | #ifdef CONFIG_POSIX_FALLOCATE | ||
55 | @@ -XXX,XX +XXX,XX @@ static int raw_regular_truncate(int fd, int64_t offset, PreallocMode prealloc, | ||
56 | * file systems that do not support fallocate(), trying to check if a | ||
57 | * block is allocated before allocating it, so don't do that here. | ||
58 | */ | ||
59 | - result = -posix_fallocate(fd, 0, offset); | ||
60 | + result = -posix_fallocate(fd, current_length, offset - current_length); | ||
61 | if (result != 0) { | ||
62 | /* posix_fallocate() doesn't set errno. */ | ||
63 | error_setg_errno(errp, -result, | ||
64 | - "Could not preallocate data for the new file"); | ||
65 | + "Could not preallocate new data"); | ||
66 | } | ||
67 | - return result; | ||
68 | + goto out; | ||
69 | #endif | ||
70 | case PREALLOC_MODE_FULL: | ||
71 | { | ||
72 | - int64_t num = 0, left = offset; | ||
73 | + int64_t num = 0, left = offset - current_length; | ||
74 | |||
75 | /* | ||
76 | * Knowing the final size from the beginning could allow the file | ||
77 | @@ -XXX,XX +XXX,XX @@ static int raw_regular_truncate(int fd, int64_t offset, PreallocMode prealloc, | ||
78 | if (ftruncate(fd, offset) != 0) { | ||
79 | result = -errno; | ||
80 | error_setg_errno(errp, -result, "Could not resize file"); | ||
81 | - return result; | ||
82 | + goto out; | ||
83 | } | ||
84 | |||
85 | buf = g_malloc0(65536); | ||
86 | |||
87 | + result = lseek(fd, current_length, SEEK_SET); | ||
88 | + if (result < 0) { | ||
89 | + result = -errno; | ||
90 | + error_setg_errno(errp, -result, | ||
91 | + "Failed to seek to the old end of file"); | ||
92 | + goto out; | ||
93 | + } | ||
94 | + | ||
95 | while (left > 0) { | ||
96 | num = MIN(left, 65536); | ||
97 | result = write(fd, buf, num); | ||
98 | if (result < 0) { | ||
99 | result = -errno; | ||
100 | error_setg_errno(errp, -result, | ||
101 | - "Could not write to the new file"); | ||
102 | - break; | ||
103 | + "Could not write zeros for preallocation"); | ||
104 | + goto out; | ||
105 | } | ||
106 | left -= result; | ||
107 | } | ||
108 | @@ -XXX,XX +XXX,XX @@ static int raw_regular_truncate(int fd, int64_t offset, PreallocMode prealloc, | ||
109 | if (result < 0) { | ||
110 | result = -errno; | ||
111 | error_setg_errno(errp, -result, | ||
112 | - "Could not flush new file to disk"); | ||
113 | + "Could not flush file to disk"); | ||
114 | + goto out; | ||
115 | } | ||
116 | } | ||
117 | - g_free(buf); | ||
118 | - return result; | ||
119 | + goto out; | ||
120 | } | ||
121 | case PREALLOC_MODE_OFF: | ||
122 | if (ftruncate(fd, offset) != 0) { | ||
123 | @@ -XXX,XX +XXX,XX @@ static int raw_regular_truncate(int fd, int64_t offset, PreallocMode prealloc, | ||
124 | PreallocMode_lookup[prealloc]); | ||
125 | return result; | ||
126 | } | ||
127 | + | ||
128 | +out: | ||
129 | + if (result < 0) { | ||
130 | + if (ftruncate(fd, current_length) < 0) { | ||
131 | + error_report("Failed to restore old file length: %s", | ||
132 | + strerror(errno)); | ||
133 | + } | ||
134 | + } | ||
135 | + | ||
136 | + g_free(buf); | ||
137 | + return result; | ||
138 | } | ||
139 | |||
140 | static int raw_truncate(BlockDriverState *bs, int64_t offset, | ||
141 | -- | ||
142 | 2.9.4 | ||
143 | |||
144 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | By using raw_regular_truncate() in raw_truncate(), we can now easily | ||
2 | support preallocation. | ||
3 | 1 | ||
4 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
5 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
6 | Message-id: 20170613202107.10125-9-mreitz@redhat.com | ||
7 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
8 | --- | ||
9 | block/file-posix.c | 22 ++++++++++------------ | ||
10 | 1 file changed, 10 insertions(+), 12 deletions(-) | ||
11 | |||
12 | diff --git a/block/file-posix.c b/block/file-posix.c | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/block/file-posix.c | ||
15 | +++ b/block/file-posix.c | ||
16 | @@ -XXX,XX +XXX,XX @@ static int raw_truncate(BlockDriverState *bs, int64_t offset, | ||
17 | struct stat st; | ||
18 | int ret; | ||
19 | |||
20 | - if (prealloc != PREALLOC_MODE_OFF) { | ||
21 | - error_setg(errp, "Unsupported preallocation mode '%s'", | ||
22 | - PreallocMode_lookup[prealloc]); | ||
23 | - return -ENOTSUP; | ||
24 | - } | ||
25 | - | ||
26 | if (fstat(s->fd, &st)) { | ||
27 | ret = -errno; | ||
28 | error_setg_errno(errp, -ret, "Failed to fstat() the file"); | ||
29 | @@ -XXX,XX +XXX,XX @@ static int raw_truncate(BlockDriverState *bs, int64_t offset, | ||
30 | } | ||
31 | |||
32 | if (S_ISREG(st.st_mode)) { | ||
33 | - if (ftruncate(s->fd, offset) < 0) { | ||
34 | - ret = -errno; | ||
35 | - error_setg_errno(errp, -ret, "Failed to resize the file"); | ||
36 | - return ret; | ||
37 | - } | ||
38 | - } else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) { | ||
39 | + return raw_regular_truncate(s->fd, offset, prealloc, errp); | ||
40 | + } | ||
41 | + | ||
42 | + if (prealloc != PREALLOC_MODE_OFF) { | ||
43 | + error_setg(errp, "Preallocation mode '%s' unsupported for this " | ||
44 | + "non-regular file", PreallocMode_lookup[prealloc]); | ||
45 | + return -ENOTSUP; | ||
46 | + } | ||
47 | + | ||
48 | + if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) { | ||
49 | if (offset > raw_getlength(bs)) { | ||
50 | error_setg(errp, "Cannot grow device files"); | ||
51 | return -EINVAL; | ||
52 | -- | ||
53 | 2.9.4 | ||
54 | |||
55 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | This patch adds two new parameters to the preallocate() function so we | ||
2 | will be able to use it not just for preallocating a new image but also | ||
3 | for preallocated image growth. | ||
4 | 1 | ||
5 | The offset parameter allows the caller to specify a virtual offset from | ||
6 | which to start preallocating. For newly created images this is always 0, | ||
7 | but for preallocating growth this will be the old image length. | ||
8 | |||
9 | The new_length parameter specifies the supposed new length of the image | ||
10 | (basically the "end offset" for preallocation). During image truncation, | ||
11 | bdrv_getlength() will return the old image length so we cannot rely on | ||
12 | its return value then. | ||
13 | |||
14 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
15 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
16 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
17 | Message-id: 20170613202107.10125-10-mreitz@redhat.com | ||
18 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
19 | --- | ||
20 | block/qcow2.c | 17 ++++++++++++----- | ||
21 | 1 file changed, 12 insertions(+), 5 deletions(-) | ||
22 | |||
23 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
24 | index XXXXXXX..XXXXXXX 100644 | ||
25 | --- a/block/qcow2.c | ||
26 | +++ b/block/qcow2.c | ||
27 | @@ -XXX,XX +XXX,XX @@ static int qcow2_set_up_encryption(BlockDriverState *bs, const char *encryptfmt, | ||
28 | } | ||
29 | |||
30 | |||
31 | -static int preallocate(BlockDriverState *bs) | ||
32 | +/** | ||
33 | + * Preallocates metadata structures for data clusters between @offset (in the | ||
34 | + * guest disk) and @new_length (which is thus generally the new guest disk | ||
35 | + * size). | ||
36 | + * | ||
37 | + * Returns: 0 on success, -errno on failure. | ||
38 | + */ | ||
39 | +static int preallocate(BlockDriverState *bs, | ||
40 | + uint64_t offset, uint64_t new_length) | ||
41 | { | ||
42 | uint64_t bytes; | ||
43 | - uint64_t offset; | ||
44 | uint64_t host_offset = 0; | ||
45 | unsigned int cur_bytes; | ||
46 | int ret; | ||
47 | QCowL2Meta *meta; | ||
48 | |||
49 | - bytes = bdrv_getlength(bs); | ||
50 | - offset = 0; | ||
51 | + assert(offset <= new_length); | ||
52 | + bytes = new_length - offset; | ||
53 | |||
54 | while (bytes) { | ||
55 | cur_bytes = MIN(bytes, INT_MAX); | ||
56 | @@ -XXX,XX +XXX,XX @@ static int qcow2_create2(const char *filename, int64_t total_size, | ||
57 | if (prealloc != PREALLOC_MODE_OFF) { | ||
58 | BDRVQcow2State *s = blk_bs(blk)->opaque; | ||
59 | qemu_co_mutex_lock(&s->lock); | ||
60 | - ret = preallocate(blk_bs(blk)); | ||
61 | + ret = preallocate(blk_bs(blk), 0, total_size); | ||
62 | qemu_co_mutex_unlock(&s->lock); | ||
63 | if (ret < 0) { | ||
64 | error_setg_errno(errp, -ret, "Could not preallocate metadata"); | ||
65 | -- | ||
66 | 2.9.4 | ||
67 | |||
68 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | preallocate() is and will be called only from places that do not | ||
2 | otherwise need to lock s->lock: Currently that is qcow2_create2(), as of | ||
3 | a future patch it will be called from qcow2_truncate(), too. | ||
4 | 1 | ||
5 | It therefore makes sense to move locking that mutex into preallocate() | ||
6 | itself. | ||
7 | |||
8 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
9 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
10 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
11 | Message-id: 20170613202107.10125-11-mreitz@redhat.com | ||
12 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
13 | --- | ||
14 | block/qcow2.c | 22 +++++++++++++++------- | ||
15 | 1 file changed, 15 insertions(+), 7 deletions(-) | ||
16 | |||
17 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/block/qcow2.c | ||
20 | +++ b/block/qcow2.c | ||
21 | @@ -XXX,XX +XXX,XX @@ static int qcow2_set_up_encryption(BlockDriverState *bs, const char *encryptfmt, | ||
22 | static int preallocate(BlockDriverState *bs, | ||
23 | uint64_t offset, uint64_t new_length) | ||
24 | { | ||
25 | + BDRVQcow2State *s = bs->opaque; | ||
26 | uint64_t bytes; | ||
27 | uint64_t host_offset = 0; | ||
28 | unsigned int cur_bytes; | ||
29 | int ret; | ||
30 | QCowL2Meta *meta; | ||
31 | |||
32 | + if (qemu_in_coroutine()) { | ||
33 | + qemu_co_mutex_lock(&s->lock); | ||
34 | + } | ||
35 | + | ||
36 | assert(offset <= new_length); | ||
37 | bytes = new_length - offset; | ||
38 | |||
39 | @@ -XXX,XX +XXX,XX @@ static int preallocate(BlockDriverState *bs, | ||
40 | ret = qcow2_alloc_cluster_offset(bs, offset, &cur_bytes, | ||
41 | &host_offset, &meta); | ||
42 | if (ret < 0) { | ||
43 | - return ret; | ||
44 | + goto done; | ||
45 | } | ||
46 | |||
47 | while (meta) { | ||
48 | @@ -XXX,XX +XXX,XX @@ static int preallocate(BlockDriverState *bs, | ||
49 | if (ret < 0) { | ||
50 | qcow2_free_any_clusters(bs, meta->alloc_offset, | ||
51 | meta->nb_clusters, QCOW2_DISCARD_NEVER); | ||
52 | - return ret; | ||
53 | + goto done; | ||
54 | } | ||
55 | |||
56 | /* There are no dependent requests, but we need to remove our | ||
57 | @@ -XXX,XX +XXX,XX @@ static int preallocate(BlockDriverState *bs, | ||
58 | ret = bdrv_pwrite(bs->file, (host_offset + cur_bytes) - 1, | ||
59 | &data, 1); | ||
60 | if (ret < 0) { | ||
61 | - return ret; | ||
62 | + goto done; | ||
63 | } | ||
64 | } | ||
65 | |||
66 | - return 0; | ||
67 | + ret = 0; | ||
68 | + | ||
69 | +done: | ||
70 | + if (qemu_in_coroutine()) { | ||
71 | + qemu_co_mutex_unlock(&s->lock); | ||
72 | + } | ||
73 | + return ret; | ||
74 | } | ||
75 | |||
76 | /* qcow2_refcount_metadata_size: | ||
77 | @@ -XXX,XX +XXX,XX @@ static int qcow2_create2(const char *filename, int64_t total_size, | ||
78 | |||
79 | /* And if we're supposed to preallocate metadata, do that now */ | ||
80 | if (prealloc != PREALLOC_MODE_OFF) { | ||
81 | - BDRVQcow2State *s = blk_bs(blk)->opaque; | ||
82 | - qemu_co_mutex_lock(&s->lock); | ||
83 | ret = preallocate(blk_bs(blk), 0, total_size); | ||
84 | - qemu_co_mutex_unlock(&s->lock); | ||
85 | if (ret < 0) { | ||
86 | error_setg_errno(errp, -ret, "Could not preallocate metadata"); | ||
87 | goto out; | ||
88 | -- | ||
89 | 2.9.4 | ||
90 | |||
91 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | We can support PREALLOC_MODE_METADATA by invoking preallocate() in | ||
2 | qcow2_truncate(). | ||
3 | 1 | ||
4 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
5 | Message-id: 20170613202107.10125-12-mreitz@redhat.com | ||
6 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
7 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
8 | --- | ||
9 | block/qcow2.c | 33 +++++++++++++++++++++++++++++++-- | ||
10 | 1 file changed, 31 insertions(+), 2 deletions(-) | ||
11 | |||
12 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/block/qcow2.c | ||
15 | +++ b/block/qcow2.c | ||
16 | @@ -XXX,XX +XXX,XX @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset, | ||
17 | PreallocMode prealloc, Error **errp) | ||
18 | { | ||
19 | BDRVQcow2State *s = bs->opaque; | ||
20 | + uint64_t old_length; | ||
21 | int64_t new_l1_size; | ||
22 | int ret; | ||
23 | |||
24 | - if (prealloc != PREALLOC_MODE_OFF) { | ||
25 | + if (prealloc != PREALLOC_MODE_OFF && prealloc != PREALLOC_MODE_METADATA) { | ||
26 | error_setg(errp, "Unsupported preallocation mode '%s'", | ||
27 | PreallocMode_lookup[prealloc]); | ||
28 | return -ENOTSUP; | ||
29 | @@ -XXX,XX +XXX,XX @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset, | ||
30 | return -ENOTSUP; | ||
31 | } | ||
32 | |||
33 | + old_length = bs->total_sectors * 512; | ||
34 | + | ||
35 | /* shrinking is currently not supported */ | ||
36 | - if (offset < bs->total_sectors * 512) { | ||
37 | + if (offset < old_length) { | ||
38 | error_setg(errp, "qcow2 doesn't support shrinking images yet"); | ||
39 | return -ENOTSUP; | ||
40 | } | ||
41 | @@ -XXX,XX +XXX,XX @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset, | ||
42 | return ret; | ||
43 | } | ||
44 | |||
45 | + switch (prealloc) { | ||
46 | + case PREALLOC_MODE_OFF: | ||
47 | + break; | ||
48 | + | ||
49 | + case PREALLOC_MODE_METADATA: | ||
50 | + ret = preallocate(bs, old_length, offset); | ||
51 | + if (ret < 0) { | ||
52 | + error_setg_errno(errp, -ret, "Preallocation failed"); | ||
53 | + return ret; | ||
54 | + } | ||
55 | + break; | ||
56 | + | ||
57 | + default: | ||
58 | + g_assert_not_reached(); | ||
59 | + } | ||
60 | + | ||
61 | + if (prealloc != PREALLOC_MODE_OFF) { | ||
62 | + /* Flush metadata before actually changing the image size */ | ||
63 | + ret = bdrv_flush(bs); | ||
64 | + if (ret < 0) { | ||
65 | + error_setg_errno(errp, -ret, | ||
66 | + "Failed to flush the preallocated area to disk"); | ||
67 | + return ret; | ||
68 | + } | ||
69 | + } | ||
70 | + | ||
71 | /* write updated header.size */ | ||
72 | offset = cpu_to_be64(offset); | ||
73 | ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, size), | ||
74 | -- | ||
75 | 2.9.4 | ||
76 | |||
77 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | This function creates a collection of self-describing refcount | ||
2 | structures (including a new refcount table) at the end of a qcow2 image | ||
3 | file. Optionally, these structures can also describe a number of | ||
4 | additional clusters beyond themselves; this will be important for | ||
5 | preallocated truncation, which will place the data clusters and L2 | ||
6 | tables there. | ||
7 | 1 | ||
8 | For now, we can use this function to replace the part of | ||
9 | alloc_refcount_block() that grows the refcount table (from which it is | ||
10 | actually derived). | ||
11 | |||
12 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
13 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
14 | Message-id: 20170613202107.10125-13-mreitz@redhat.com | ||
15 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
16 | --- | ||
17 | block/qcow2.h | 4 + | ||
18 | block/qcow2-refcount.c | 267 +++++++++++++++++++++++++++++++-------------- | ||
19 | block/qcow2.c | 20 +++- | ||
20 | tests/qemu-iotests/044.out | 2 +- | ||
21 | 4 files changed, 204 insertions(+), 89 deletions(-) | ||
22 | |||
23 | diff --git a/block/qcow2.h b/block/qcow2.h | ||
24 | index XXXXXXX..XXXXXXX 100644 | ||
25 | --- a/block/qcow2.h | ||
26 | +++ b/block/qcow2.h | ||
27 | @@ -XXX,XX +XXX,XX @@ static inline uint64_t refcount_diff(uint64_t r1, uint64_t r2) | ||
28 | int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector *qiov, | ||
29 | int64_t sector_num, int nb_sectors); | ||
30 | |||
31 | +int64_t qcow2_refcount_metadata_size(int64_t clusters, size_t cluster_size, | ||
32 | + int refcount_order, bool generous_increase, | ||
33 | + uint64_t *refblock_count); | ||
34 | + | ||
35 | int qcow2_mark_dirty(BlockDriverState *bs); | ||
36 | int qcow2_mark_corrupt(BlockDriverState *bs); | ||
37 | int qcow2_mark_consistent(BlockDriverState *bs); | ||
38 | diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c | ||
39 | index XXXXXXX..XXXXXXX 100644 | ||
40 | --- a/block/qcow2-refcount.c | ||
41 | +++ b/block/qcow2-refcount.c | ||
42 | @@ -XXX,XX +XXX,XX @@ static int64_t alloc_clusters_noref(BlockDriverState *bs, uint64_t size); | ||
43 | static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs, | ||
44 | int64_t offset, int64_t length, uint64_t addend, | ||
45 | bool decrease, enum qcow2_discard_type type); | ||
46 | +static int64_t qcow2_refcount_area(BlockDriverState *bs, uint64_t offset, | ||
47 | + uint64_t additional_clusters, | ||
48 | + bool exact_size, int new_refblock_index, | ||
49 | + uint64_t new_refblock_offset); | ||
50 | |||
51 | static uint64_t get_refcount_ro0(const void *refcount_array, uint64_t index); | ||
52 | static uint64_t get_refcount_ro1(const void *refcount_array, uint64_t index); | ||
53 | @@ -XXX,XX +XXX,XX @@ int qcow2_get_refcount(BlockDriverState *bs, int64_t cluster_index, | ||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | -/* | ||
58 | - * Rounds the refcount table size up to avoid growing the table for each single | ||
59 | - * refcount block that is allocated. | ||
60 | - */ | ||
61 | -static unsigned int next_refcount_table_size(BDRVQcow2State *s, | ||
62 | - unsigned int min_size) | ||
63 | -{ | ||
64 | - unsigned int min_clusters = (min_size >> (s->cluster_bits - 3)) + 1; | ||
65 | - unsigned int refcount_table_clusters = | ||
66 | - MAX(1, s->refcount_table_size >> (s->cluster_bits - 3)); | ||
67 | - | ||
68 | - while (min_clusters > refcount_table_clusters) { | ||
69 | - refcount_table_clusters = (refcount_table_clusters * 3 + 1) / 2; | ||
70 | - } | ||
71 | - | ||
72 | - return refcount_table_clusters << (s->cluster_bits - 3); | ||
73 | -} | ||
74 | - | ||
75 | - | ||
76 | /* Checks if two offsets are described by the same refcount block */ | ||
77 | static int in_same_refcount_block(BDRVQcow2State *s, uint64_t offset_a, | ||
78 | uint64_t offset_b) | ||
79 | @@ -XXX,XX +XXX,XX @@ static int alloc_refcount_block(BlockDriverState *bs, | ||
80 | { | ||
81 | BDRVQcow2State *s = bs->opaque; | ||
82 | unsigned int refcount_table_index; | ||
83 | - int ret; | ||
84 | + int64_t ret; | ||
85 | |||
86 | BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC); | ||
87 | |||
88 | @@ -XXX,XX +XXX,XX @@ static int alloc_refcount_block(BlockDriverState *bs, | ||
89 | (new_block >> s->cluster_bits) + 1), | ||
90 | s->refcount_block_size); | ||
91 | |||
92 | - if (blocks_used > QCOW_MAX_REFTABLE_SIZE / sizeof(uint64_t)) { | ||
93 | - return -EFBIG; | ||
94 | + /* Create the new refcount table and blocks */ | ||
95 | + uint64_t meta_offset = (blocks_used * s->refcount_block_size) * | ||
96 | + s->cluster_size; | ||
97 | + | ||
98 | + ret = qcow2_refcount_area(bs, meta_offset, 0, false, | ||
99 | + refcount_table_index, new_block); | ||
100 | + if (ret < 0) { | ||
101 | + return ret; | ||
102 | } | ||
103 | |||
104 | - /* And now we need at least one block more for the new metadata */ | ||
105 | - uint64_t table_size = next_refcount_table_size(s, blocks_used + 1); | ||
106 | - uint64_t last_table_size; | ||
107 | - uint64_t blocks_clusters; | ||
108 | - do { | ||
109 | - uint64_t table_clusters = | ||
110 | - size_to_clusters(s, table_size * sizeof(uint64_t)); | ||
111 | - blocks_clusters = 1 + | ||
112 | - DIV_ROUND_UP(table_clusters, s->refcount_block_size); | ||
113 | - uint64_t meta_clusters = table_clusters + blocks_clusters; | ||
114 | + ret = load_refcount_block(bs, new_block, refcount_block); | ||
115 | + if (ret < 0) { | ||
116 | + return ret; | ||
117 | + } | ||
118 | + | ||
119 | + /* If we were trying to do the initial refcount update for some cluster | ||
120 | + * allocation, we might have used the same clusters to store newly | ||
121 | + * allocated metadata. Make the caller search some new space. */ | ||
122 | + return -EAGAIN; | ||
123 | + | ||
124 | +fail_block: | ||
125 | + if (*refcount_block != NULL) { | ||
126 | + qcow2_cache_put(bs, s->refcount_block_cache, refcount_block); | ||
127 | + } | ||
128 | + return ret; | ||
129 | +} | ||
130 | + | ||
131 | +/* | ||
132 | + * Starting at @start_offset, this function creates new self-covering refcount | ||
133 | + * structures: A new refcount table and refcount blocks which cover all of | ||
134 | + * themselves, and a number of @additional_clusters beyond their end. | ||
135 | + * @start_offset must be at the end of the image file, that is, there must be | ||
136 | + * only empty space beyond it. | ||
137 | + * If @exact_size is false, the refcount table will have 50 % more entries than | ||
138 | + * necessary so it will not need to grow again soon. | ||
139 | + * If @new_refblock_offset is not zero, it contains the offset of a refcount | ||
140 | + * block that should be entered into the new refcount table at index | ||
141 | + * @new_refblock_index. | ||
142 | + * | ||
143 | + * Returns: The offset after the new refcount structures (i.e. where the | ||
144 | + * @additional_clusters may be placed) on success, -errno on error. | ||
145 | + */ | ||
146 | +static int64_t qcow2_refcount_area(BlockDriverState *bs, uint64_t start_offset, | ||
147 | + uint64_t additional_clusters, | ||
148 | + bool exact_size, int new_refblock_index, | ||
149 | + uint64_t new_refblock_offset) | ||
150 | +{ | ||
151 | + BDRVQcow2State *s = bs->opaque; | ||
152 | + uint64_t total_refblock_count_u64, additional_refblock_count; | ||
153 | + int total_refblock_count, table_size, area_reftable_index, table_clusters; | ||
154 | + int i; | ||
155 | + uint64_t table_offset, block_offset, end_offset; | ||
156 | + int ret; | ||
157 | + uint64_t *new_table; | ||
158 | |||
159 | - last_table_size = table_size; | ||
160 | - table_size = next_refcount_table_size(s, blocks_used + | ||
161 | - DIV_ROUND_UP(meta_clusters, s->refcount_block_size)); | ||
162 | + assert(!(start_offset % s->cluster_size)); | ||
163 | |||
164 | - } while (last_table_size != table_size); | ||
165 | + qcow2_refcount_metadata_size(start_offset / s->cluster_size + | ||
166 | + additional_clusters, | ||
167 | + s->cluster_size, s->refcount_order, | ||
168 | + !exact_size, &total_refblock_count_u64); | ||
169 | + if (total_refblock_count_u64 > QCOW_MAX_REFTABLE_SIZE) { | ||
170 | + return -EFBIG; | ||
171 | + } | ||
172 | + total_refblock_count = total_refblock_count_u64; | ||
173 | |||
174 | -#ifdef DEBUG_ALLOC2 | ||
175 | - fprintf(stderr, "qcow2: Grow refcount table %" PRId32 " => %" PRId64 "\n", | ||
176 | - s->refcount_table_size, table_size); | ||
177 | -#endif | ||
178 | + /* Index in the refcount table of the first refcount block to cover the area | ||
179 | + * of refcount structures we are about to create; we know that | ||
180 | + * @total_refblock_count can cover @start_offset, so this will definitely | ||
181 | + * fit into an int. */ | ||
182 | + area_reftable_index = (start_offset / s->cluster_size) / | ||
183 | + s->refcount_block_size; | ||
184 | |||
185 | - /* Create the new refcount table and blocks */ | ||
186 | - uint64_t meta_offset = (blocks_used * s->refcount_block_size) * | ||
187 | - s->cluster_size; | ||
188 | - uint64_t table_offset = meta_offset + blocks_clusters * s->cluster_size; | ||
189 | - uint64_t *new_table = g_try_new0(uint64_t, table_size); | ||
190 | - void *new_blocks = g_try_malloc0(blocks_clusters * s->cluster_size); | ||
191 | + if (exact_size) { | ||
192 | + table_size = total_refblock_count; | ||
193 | + } else { | ||
194 | + table_size = total_refblock_count + | ||
195 | + DIV_ROUND_UP(total_refblock_count, 2); | ||
196 | + } | ||
197 | + /* The qcow2 file can only store the reftable size in number of clusters */ | ||
198 | + table_size = ROUND_UP(table_size, s->cluster_size / sizeof(uint64_t)); | ||
199 | + table_clusters = (table_size * sizeof(uint64_t)) / s->cluster_size; | ||
200 | |||
201 | - assert(table_size > 0 && blocks_clusters > 0); | ||
202 | - if (new_table == NULL || new_blocks == NULL) { | ||
203 | + if (table_size > QCOW_MAX_REFTABLE_SIZE) { | ||
204 | + return -EFBIG; | ||
205 | + } | ||
206 | + | ||
207 | + new_table = g_try_new0(uint64_t, table_size); | ||
208 | + | ||
209 | + assert(table_size > 0); | ||
210 | + if (new_table == NULL) { | ||
211 | ret = -ENOMEM; | ||
212 | - goto fail_table; | ||
213 | + goto fail; | ||
214 | } | ||
215 | |||
216 | /* Fill the new refcount table */ | ||
217 | - memcpy(new_table, s->refcount_table, | ||
218 | - s->refcount_table_size * sizeof(uint64_t)); | ||
219 | - new_table[refcount_table_index] = new_block; | ||
220 | + if (table_size > s->max_refcount_table_index) { | ||
221 | + /* We're actually growing the reftable */ | ||
222 | + memcpy(new_table, s->refcount_table, | ||
223 | + (s->max_refcount_table_index + 1) * sizeof(uint64_t)); | ||
224 | + } else { | ||
225 | + /* Improbable case: We're shrinking the reftable. However, the caller | ||
226 | + * has assured us that there is only empty space beyond @start_offset, | ||
227 | + * so we can simply drop all of the refblocks that won't fit into the | ||
228 | + * new reftable. */ | ||
229 | + memcpy(new_table, s->refcount_table, table_size * sizeof(uint64_t)); | ||
230 | + } | ||
231 | |||
232 | - int i; | ||
233 | - for (i = 0; i < blocks_clusters; i++) { | ||
234 | - new_table[blocks_used + i] = meta_offset + (i * s->cluster_size); | ||
235 | + if (new_refblock_offset) { | ||
236 | + assert(new_refblock_index < total_refblock_count); | ||
237 | + new_table[new_refblock_index] = new_refblock_offset; | ||
238 | } | ||
239 | |||
240 | - /* Fill the refcount blocks */ | ||
241 | - uint64_t table_clusters = size_to_clusters(s, table_size * sizeof(uint64_t)); | ||
242 | - int block = 0; | ||
243 | - for (i = 0; i < table_clusters + blocks_clusters; i++) { | ||
244 | - s->set_refcount(new_blocks, block++, 1); | ||
245 | + /* Count how many new refblocks we have to create */ | ||
246 | + additional_refblock_count = 0; | ||
247 | + for (i = area_reftable_index; i < total_refblock_count; i++) { | ||
248 | + if (!new_table[i]) { | ||
249 | + additional_refblock_count++; | ||
250 | + } | ||
251 | } | ||
252 | |||
253 | + table_offset = start_offset + additional_refblock_count * s->cluster_size; | ||
254 | + end_offset = table_offset + table_clusters * s->cluster_size; | ||
255 | + | ||
256 | + /* Fill the refcount blocks, and create new ones, if necessary */ | ||
257 | + block_offset = start_offset; | ||
258 | + for (i = area_reftable_index; i < total_refblock_count; i++) { | ||
259 | + void *refblock_data; | ||
260 | + uint64_t first_offset_covered; | ||
261 | + | ||
262 | + /* Reuse an existing refblock if possible, create a new one otherwise */ | ||
263 | + if (new_table[i]) { | ||
264 | + ret = qcow2_cache_get(bs, s->refcount_block_cache, new_table[i], | ||
265 | + &refblock_data); | ||
266 | + if (ret < 0) { | ||
267 | + goto fail; | ||
268 | + } | ||
269 | + } else { | ||
270 | + ret = qcow2_cache_get_empty(bs, s->refcount_block_cache, | ||
271 | + block_offset, &refblock_data); | ||
272 | + if (ret < 0) { | ||
273 | + goto fail; | ||
274 | + } | ||
275 | + memset(refblock_data, 0, s->cluster_size); | ||
276 | + qcow2_cache_entry_mark_dirty(bs, s->refcount_block_cache, | ||
277 | + refblock_data); | ||
278 | + | ||
279 | + new_table[i] = block_offset; | ||
280 | + block_offset += s->cluster_size; | ||
281 | + } | ||
282 | + | ||
283 | + /* First host offset covered by this refblock */ | ||
284 | + first_offset_covered = (uint64_t)i * s->refcount_block_size * | ||
285 | + s->cluster_size; | ||
286 | + if (first_offset_covered < end_offset) { | ||
287 | + int j, end_index; | ||
288 | + | ||
289 | + /* Set the refcount of all of the new refcount structures to 1 */ | ||
290 | + | ||
291 | + if (first_offset_covered < start_offset) { | ||
292 | + assert(i == area_reftable_index); | ||
293 | + j = (start_offset - first_offset_covered) / s->cluster_size; | ||
294 | + assert(j < s->refcount_block_size); | ||
295 | + } else { | ||
296 | + j = 0; | ||
297 | + } | ||
298 | + | ||
299 | + end_index = MIN((end_offset - first_offset_covered) / | ||
300 | + s->cluster_size, | ||
301 | + s->refcount_block_size); | ||
302 | + | ||
303 | + for (; j < end_index; j++) { | ||
304 | + /* The caller guaranteed us this space would be empty */ | ||
305 | + assert(s->get_refcount(refblock_data, j) == 0); | ||
306 | + s->set_refcount(refblock_data, j, 1); | ||
307 | + } | ||
308 | + | ||
309 | + qcow2_cache_entry_mark_dirty(bs, s->refcount_block_cache, | ||
310 | + refblock_data); | ||
311 | + } | ||
312 | + | ||
313 | + qcow2_cache_put(bs, s->refcount_block_cache, &refblock_data); | ||
314 | + } | ||
315 | + | ||
316 | + assert(block_offset == table_offset); | ||
317 | + | ||
318 | /* Write refcount blocks to disk */ | ||
319 | BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE_BLOCKS); | ||
320 | - ret = bdrv_pwrite_sync(bs->file, meta_offset, new_blocks, | ||
321 | - blocks_clusters * s->cluster_size); | ||
322 | - g_free(new_blocks); | ||
323 | - new_blocks = NULL; | ||
324 | + ret = qcow2_cache_flush(bs, s->refcount_block_cache); | ||
325 | if (ret < 0) { | ||
326 | - goto fail_table; | ||
327 | + goto fail; | ||
328 | } | ||
329 | |||
330 | /* Write refcount table to disk */ | ||
331 | - for(i = 0; i < table_size; i++) { | ||
332 | + for (i = 0; i < total_refblock_count; i++) { | ||
333 | cpu_to_be64s(&new_table[i]); | ||
334 | } | ||
335 | |||
336 | @@ -XXX,XX +XXX,XX @@ static int alloc_refcount_block(BlockDriverState *bs, | ||
337 | ret = bdrv_pwrite_sync(bs->file, table_offset, new_table, | ||
338 | table_size * sizeof(uint64_t)); | ||
339 | if (ret < 0) { | ||
340 | - goto fail_table; | ||
341 | + goto fail; | ||
342 | } | ||
343 | |||
344 | - for(i = 0; i < table_size; i++) { | ||
345 | + for (i = 0; i < total_refblock_count; i++) { | ||
346 | be64_to_cpus(&new_table[i]); | ||
347 | } | ||
348 | |||
349 | @@ -XXX,XX +XXX,XX @@ static int alloc_refcount_block(BlockDriverState *bs, | ||
350 | offsetof(QCowHeader, refcount_table_offset), | ||
351 | &data, sizeof(data)); | ||
352 | if (ret < 0) { | ||
353 | - goto fail_table; | ||
354 | + goto fail; | ||
355 | } | ||
356 | |||
357 | /* And switch it in memory */ | ||
358 | @@ -XXX,XX +XXX,XX @@ static int alloc_refcount_block(BlockDriverState *bs, | ||
359 | qcow2_free_clusters(bs, old_table_offset, old_table_size * sizeof(uint64_t), | ||
360 | QCOW2_DISCARD_OTHER); | ||
361 | |||
362 | - ret = load_refcount_block(bs, new_block, refcount_block); | ||
363 | - if (ret < 0) { | ||
364 | - return ret; | ||
365 | - } | ||
366 | - | ||
367 | - /* If we were trying to do the initial refcount update for some cluster | ||
368 | - * allocation, we might have used the same clusters to store newly | ||
369 | - * allocated metadata. Make the caller search some new space. */ | ||
370 | - return -EAGAIN; | ||
371 | + return end_offset; | ||
372 | |||
373 | -fail_table: | ||
374 | - g_free(new_blocks); | ||
375 | +fail: | ||
376 | g_free(new_table); | ||
377 | -fail_block: | ||
378 | - if (*refcount_block != NULL) { | ||
379 | - qcow2_cache_put(bs, s->refcount_block_cache, refcount_block); | ||
380 | - } | ||
381 | return ret; | ||
382 | } | ||
383 | |||
384 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
385 | index XXXXXXX..XXXXXXX 100644 | ||
386 | --- a/block/qcow2.c | ||
387 | +++ b/block/qcow2.c | ||
388 | @@ -XXX,XX +XXX,XX @@ done: | ||
389 | * @clusters: number of clusters to refcount (including data and L1/L2 tables) | ||
390 | * @cluster_size: size of a cluster, in bytes | ||
391 | * @refcount_order: refcount bits power-of-2 exponent | ||
392 | + * @generous_increase: allow for the refcount table to be 1.5x as large as it | ||
393 | + * needs to be | ||
394 | * | ||
395 | * Returns: Number of bytes required for refcount blocks and table metadata. | ||
396 | */ | ||
397 | -static int64_t qcow2_refcount_metadata_size(int64_t clusters, | ||
398 | - size_t cluster_size, | ||
399 | - int refcount_order) | ||
400 | +int64_t qcow2_refcount_metadata_size(int64_t clusters, size_t cluster_size, | ||
401 | + int refcount_order, bool generous_increase, | ||
402 | + uint64_t *refblock_count) | ||
403 | { | ||
404 | /* | ||
405 | * Every host cluster is reference-counted, including metadata (even | ||
406 | @@ -XXX,XX +XXX,XX @@ static int64_t qcow2_refcount_metadata_size(int64_t clusters, | ||
407 | blocks = DIV_ROUND_UP(clusters + table + blocks, refcounts_per_block); | ||
408 | table = DIV_ROUND_UP(blocks, blocks_per_table_cluster); | ||
409 | n = clusters + blocks + table; | ||
410 | + | ||
411 | + if (n == last && generous_increase) { | ||
412 | + clusters += DIV_ROUND_UP(table, 2); | ||
413 | + n = 0; /* force another loop */ | ||
414 | + generous_increase = false; | ||
415 | + } | ||
416 | } while (n != last); | ||
417 | |||
418 | + if (refblock_count) { | ||
419 | + *refblock_count = blocks; | ||
420 | + } | ||
421 | + | ||
422 | return (blocks + table) * cluster_size; | ||
423 | } | ||
424 | |||
425 | @@ -XXX,XX +XXX,XX @@ static int64_t qcow2_calc_prealloc_size(int64_t total_size, | ||
426 | /* total size of refcount table and blocks */ | ||
427 | meta_size += qcow2_refcount_metadata_size( | ||
428 | (meta_size + aligned_total_size) / cluster_size, | ||
429 | - cluster_size, refcount_order); | ||
430 | + cluster_size, refcount_order, false, NULL); | ||
431 | |||
432 | return meta_size + aligned_total_size; | ||
433 | } | ||
434 | diff --git a/tests/qemu-iotests/044.out b/tests/qemu-iotests/044.out | ||
435 | index XXXXXXX..XXXXXXX 100644 | ||
436 | --- a/tests/qemu-iotests/044.out | ||
437 | +++ b/tests/qemu-iotests/044.out | ||
438 | @@ -XXX,XX +XXX,XX @@ | ||
439 | No errors were found on the image. | ||
440 | 7292415/33554432 = 21.73% allocated, 0.00% fragmented, 0.00% compressed clusters | ||
441 | -Image end offset: 4296152064 | ||
442 | +Image end offset: 4296217088 | ||
443 | . | ||
444 | ---------------------------------------------------------------------- | ||
445 | Ran 1 tests | ||
446 | -- | ||
447 | 2.9.4 | ||
448 | |||
449 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | Now alloc_refcount_block() only contains a single fail label, so it | ||
2 | makes more sense to just name it "fail" instead of "fail_block". | ||
3 | 1 | ||
4 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
5 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
6 | Message-id: 20170613202107.10125-14-mreitz@redhat.com | ||
7 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
8 | --- | ||
9 | block/qcow2-refcount.c | 14 +++++++------- | ||
10 | 1 file changed, 7 insertions(+), 7 deletions(-) | ||
11 | |||
12 | diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/block/qcow2-refcount.c | ||
15 | +++ b/block/qcow2-refcount.c | ||
16 | @@ -XXX,XX +XXX,XX @@ static int alloc_refcount_block(BlockDriverState *bs, | ||
17 | ret = qcow2_cache_get_empty(bs, s->refcount_block_cache, new_block, | ||
18 | refcount_block); | ||
19 | if (ret < 0) { | ||
20 | - goto fail_block; | ||
21 | + goto fail; | ||
22 | } | ||
23 | |||
24 | memset(*refcount_block, 0, s->cluster_size); | ||
25 | @@ -XXX,XX +XXX,XX @@ static int alloc_refcount_block(BlockDriverState *bs, | ||
26 | ret = update_refcount(bs, new_block, s->cluster_size, 1, false, | ||
27 | QCOW2_DISCARD_NEVER); | ||
28 | if (ret < 0) { | ||
29 | - goto fail_block; | ||
30 | + goto fail; | ||
31 | } | ||
32 | |||
33 | ret = qcow2_cache_flush(bs, s->refcount_block_cache); | ||
34 | if (ret < 0) { | ||
35 | - goto fail_block; | ||
36 | + goto fail; | ||
37 | } | ||
38 | |||
39 | /* Initialize the new refcount block only after updating its refcount, | ||
40 | @@ -XXX,XX +XXX,XX @@ static int alloc_refcount_block(BlockDriverState *bs, | ||
41 | ret = qcow2_cache_get_empty(bs, s->refcount_block_cache, new_block, | ||
42 | refcount_block); | ||
43 | if (ret < 0) { | ||
44 | - goto fail_block; | ||
45 | + goto fail; | ||
46 | } | ||
47 | |||
48 | memset(*refcount_block, 0, s->cluster_size); | ||
49 | @@ -XXX,XX +XXX,XX @@ static int alloc_refcount_block(BlockDriverState *bs, | ||
50 | qcow2_cache_entry_mark_dirty(bs, s->refcount_block_cache, *refcount_block); | ||
51 | ret = qcow2_cache_flush(bs, s->refcount_block_cache); | ||
52 | if (ret < 0) { | ||
53 | - goto fail_block; | ||
54 | + goto fail; | ||
55 | } | ||
56 | |||
57 | /* If the refcount table is big enough, just hook the block up there */ | ||
58 | @@ -XXX,XX +XXX,XX @@ static int alloc_refcount_block(BlockDriverState *bs, | ||
59 | s->refcount_table_offset + refcount_table_index * sizeof(uint64_t), | ||
60 | &data64, sizeof(data64)); | ||
61 | if (ret < 0) { | ||
62 | - goto fail_block; | ||
63 | + goto fail; | ||
64 | } | ||
65 | |||
66 | s->refcount_table[refcount_table_index] = new_block; | ||
67 | @@ -XXX,XX +XXX,XX @@ static int alloc_refcount_block(BlockDriverState *bs, | ||
68 | * allocated metadata. Make the caller search some new space. */ | ||
69 | return -EAGAIN; | ||
70 | |||
71 | -fail_block: | ||
72 | +fail: | ||
73 | if (*refcount_block != NULL) { | ||
74 | qcow2_cache_put(bs, s->refcount_block_cache, refcount_block); | ||
75 | } | ||
76 | -- | ||
77 | 2.9.4 | ||
78 | |||
79 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | Implement the preallocation modes falloc and full for growing qcow2 | ||
2 | images. | ||
3 | 1 | ||
4 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
5 | Message-id: 20170613202107.10125-15-mreitz@redhat.com | ||
6 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
7 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
8 | --- | ||
9 | block/qcow2.h | 5 +++ | ||
10 | block/qcow2-refcount.c | 12 ++---- | ||
11 | block/qcow2.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++- | ||
12 | 3 files changed, 108 insertions(+), 9 deletions(-) | ||
13 | |||
14 | diff --git a/block/qcow2.h b/block/qcow2.h | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/block/qcow2.h | ||
17 | +++ b/block/qcow2.h | ||
18 | @@ -XXX,XX +XXX,XX @@ int qcow2_update_cluster_refcount(BlockDriverState *bs, int64_t cluster_index, | ||
19 | uint64_t addend, bool decrease, | ||
20 | enum qcow2_discard_type type); | ||
21 | |||
22 | +int64_t qcow2_refcount_area(BlockDriverState *bs, uint64_t offset, | ||
23 | + uint64_t additional_clusters, bool exact_size, | ||
24 | + int new_refblock_index, | ||
25 | + uint64_t new_refblock_offset); | ||
26 | + | ||
27 | int64_t qcow2_alloc_clusters(BlockDriverState *bs, uint64_t size); | ||
28 | int64_t qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offset, | ||
29 | int64_t nb_clusters); | ||
30 | diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c | ||
31 | index XXXXXXX..XXXXXXX 100644 | ||
32 | --- a/block/qcow2-refcount.c | ||
33 | +++ b/block/qcow2-refcount.c | ||
34 | @@ -XXX,XX +XXX,XX @@ static int64_t alloc_clusters_noref(BlockDriverState *bs, uint64_t size); | ||
35 | static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs, | ||
36 | int64_t offset, int64_t length, uint64_t addend, | ||
37 | bool decrease, enum qcow2_discard_type type); | ||
38 | -static int64_t qcow2_refcount_area(BlockDriverState *bs, uint64_t offset, | ||
39 | - uint64_t additional_clusters, | ||
40 | - bool exact_size, int new_refblock_index, | ||
41 | - uint64_t new_refblock_offset); | ||
42 | |||
43 | static uint64_t get_refcount_ro0(const void *refcount_array, uint64_t index); | ||
44 | static uint64_t get_refcount_ro1(const void *refcount_array, uint64_t index); | ||
45 | @@ -XXX,XX +XXX,XX @@ fail: | ||
46 | * Returns: The offset after the new refcount structures (i.e. where the | ||
47 | * @additional_clusters may be placed) on success, -errno on error. | ||
48 | */ | ||
49 | -static int64_t qcow2_refcount_area(BlockDriverState *bs, uint64_t start_offset, | ||
50 | - uint64_t additional_clusters, | ||
51 | - bool exact_size, int new_refblock_index, | ||
52 | - uint64_t new_refblock_offset) | ||
53 | +int64_t qcow2_refcount_area(BlockDriverState *bs, uint64_t start_offset, | ||
54 | + uint64_t additional_clusters, bool exact_size, | ||
55 | + int new_refblock_index, | ||
56 | + uint64_t new_refblock_offset) | ||
57 | { | ||
58 | BDRVQcow2State *s = bs->opaque; | ||
59 | uint64_t total_refblock_count_u64, additional_refblock_count; | ||
60 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
61 | index XXXXXXX..XXXXXXX 100644 | ||
62 | --- a/block/qcow2.c | ||
63 | +++ b/block/qcow2.c | ||
64 | @@ -XXX,XX +XXX,XX @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset, | ||
65 | int64_t new_l1_size; | ||
66 | int ret; | ||
67 | |||
68 | - if (prealloc != PREALLOC_MODE_OFF && prealloc != PREALLOC_MODE_METADATA) { | ||
69 | + if (prealloc != PREALLOC_MODE_OFF && prealloc != PREALLOC_MODE_METADATA && | ||
70 | + prealloc != PREALLOC_MODE_FALLOC && prealloc != PREALLOC_MODE_FULL) | ||
71 | + { | ||
72 | error_setg(errp, "Unsupported preallocation mode '%s'", | ||
73 | PreallocMode_lookup[prealloc]); | ||
74 | return -ENOTSUP; | ||
75 | @@ -XXX,XX +XXX,XX @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset, | ||
76 | } | ||
77 | break; | ||
78 | |||
79 | + case PREALLOC_MODE_FALLOC: | ||
80 | + case PREALLOC_MODE_FULL: | ||
81 | + { | ||
82 | + int64_t allocation_start, host_offset, guest_offset; | ||
83 | + int64_t clusters_allocated; | ||
84 | + int64_t old_file_size, new_file_size; | ||
85 | + uint64_t nb_new_data_clusters, nb_new_l2_tables; | ||
86 | + | ||
87 | + old_file_size = bdrv_getlength(bs->file->bs); | ||
88 | + if (old_file_size < 0) { | ||
89 | + error_setg_errno(errp, -old_file_size, | ||
90 | + "Failed to inquire current file length"); | ||
91 | + return ret; | ||
92 | + } | ||
93 | + | ||
94 | + nb_new_data_clusters = DIV_ROUND_UP(offset - old_length, | ||
95 | + s->cluster_size); | ||
96 | + | ||
97 | + /* This is an overestimation; we will not actually allocate space for | ||
98 | + * these in the file but just make sure the new refcount structures are | ||
99 | + * able to cover them so we will not have to allocate new refblocks | ||
100 | + * while entering the data blocks in the potentially new L2 tables. | ||
101 | + * (We do not actually care where the L2 tables are placed. Maybe they | ||
102 | + * are already allocated or they can be placed somewhere before | ||
103 | + * @old_file_size. It does not matter because they will be fully | ||
104 | + * allocated automatically, so they do not need to be covered by the | ||
105 | + * preallocation. All that matters is that we will not have to allocate | ||
106 | + * new refcount structures for them.) */ | ||
107 | + nb_new_l2_tables = DIV_ROUND_UP(nb_new_data_clusters, | ||
108 | + s->cluster_size / sizeof(uint64_t)); | ||
109 | + /* The cluster range may not be aligned to L2 boundaries, so add one L2 | ||
110 | + * table for a potential head/tail */ | ||
111 | + nb_new_l2_tables++; | ||
112 | + | ||
113 | + allocation_start = qcow2_refcount_area(bs, old_file_size, | ||
114 | + nb_new_data_clusters + | ||
115 | + nb_new_l2_tables, | ||
116 | + true, 0, 0); | ||
117 | + if (allocation_start < 0) { | ||
118 | + error_setg_errno(errp, -allocation_start, | ||
119 | + "Failed to resize refcount structures"); | ||
120 | + return -allocation_start; | ||
121 | + } | ||
122 | + | ||
123 | + clusters_allocated = qcow2_alloc_clusters_at(bs, allocation_start, | ||
124 | + nb_new_data_clusters); | ||
125 | + if (clusters_allocated < 0) { | ||
126 | + error_setg_errno(errp, -clusters_allocated, | ||
127 | + "Failed to allocate data clusters"); | ||
128 | + return -clusters_allocated; | ||
129 | + } | ||
130 | + | ||
131 | + assert(clusters_allocated == nb_new_data_clusters); | ||
132 | + | ||
133 | + /* Allocate the data area */ | ||
134 | + new_file_size = allocation_start + | ||
135 | + nb_new_data_clusters * s->cluster_size; | ||
136 | + ret = bdrv_truncate(bs->file, new_file_size, prealloc, errp); | ||
137 | + if (ret < 0) { | ||
138 | + error_prepend(errp, "Failed to resize underlying file: "); | ||
139 | + qcow2_free_clusters(bs, allocation_start, | ||
140 | + nb_new_data_clusters * s->cluster_size, | ||
141 | + QCOW2_DISCARD_OTHER); | ||
142 | + return ret; | ||
143 | + } | ||
144 | + | ||
145 | + /* Create the necessary L2 entries */ | ||
146 | + host_offset = allocation_start; | ||
147 | + guest_offset = old_length; | ||
148 | + while (nb_new_data_clusters) { | ||
149 | + int64_t guest_cluster = guest_offset >> s->cluster_bits; | ||
150 | + int64_t nb_clusters = MIN(nb_new_data_clusters, | ||
151 | + s->l2_size - guest_cluster % s->l2_size); | ||
152 | + QCowL2Meta allocation = { | ||
153 | + .offset = guest_offset, | ||
154 | + .alloc_offset = host_offset, | ||
155 | + .nb_clusters = nb_clusters, | ||
156 | + }; | ||
157 | + qemu_co_queue_init(&allocation.dependent_requests); | ||
158 | + | ||
159 | + ret = qcow2_alloc_cluster_link_l2(bs, &allocation); | ||
160 | + if (ret < 0) { | ||
161 | + error_setg_errno(errp, -ret, "Failed to update L2 tables"); | ||
162 | + qcow2_free_clusters(bs, host_offset, | ||
163 | + nb_new_data_clusters * s->cluster_size, | ||
164 | + QCOW2_DISCARD_OTHER); | ||
165 | + return ret; | ||
166 | + } | ||
167 | + | ||
168 | + guest_offset += nb_clusters * s->cluster_size; | ||
169 | + host_offset += nb_clusters * s->cluster_size; | ||
170 | + nb_new_data_clusters -= nb_clusters; | ||
171 | + } | ||
172 | + break; | ||
173 | + } | ||
174 | + | ||
175 | default: | ||
176 | g_assert_not_reached(); | ||
177 | } | ||
178 | -- | ||
179 | 2.9.4 | ||
180 | |||
181 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
2 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
3 | Message-id: 20170613202107.10125-16-mreitz@redhat.com | ||
4 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
5 | --- | ||
6 | tests/qemu-iotests/106 | 92 ++++++++++++++++++++++++++++++++++++++++++++++ | ||
7 | tests/qemu-iotests/106.out | 50 +++++++++++++++++++++++++ | ||
8 | tests/qemu-iotests/group | 1 + | ||
9 | 3 files changed, 143 insertions(+) | ||
10 | create mode 100755 tests/qemu-iotests/106 | ||
11 | create mode 100644 tests/qemu-iotests/106.out | ||
12 | 1 | ||
13 | diff --git a/tests/qemu-iotests/106 b/tests/qemu-iotests/106 | ||
14 | new file mode 100755 | ||
15 | index XXXXXXX..XXXXXXX | ||
16 | --- /dev/null | ||
17 | +++ b/tests/qemu-iotests/106 | ||
18 | @@ -XXX,XX +XXX,XX @@ | ||
19 | +#!/bin/bash | ||
20 | +# | ||
21 | +# Test preallocated resize of raw images | ||
22 | +# | ||
23 | +# Copyright (C) 2017 Red Hat, Inc. | ||
24 | +# | ||
25 | +# This program is free software; you can redistribute it and/or modify | ||
26 | +# it under the terms of the GNU General Public License as published by | ||
27 | +# the Free Software Foundation; either version 2 of the License, or | ||
28 | +# (at your option) any later version. | ||
29 | +# | ||
30 | +# This program is distributed in the hope that it will be useful, | ||
31 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
32 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
33 | +# GNU General Public License for more details. | ||
34 | +# | ||
35 | +# You should have received a copy of the GNU General Public License | ||
36 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
37 | +# | ||
38 | + | ||
39 | +# creator | ||
40 | +owner=mreitz@redhat.com | ||
41 | + | ||
42 | +seq=$(basename $0) | ||
43 | +echo "QA output created by $seq" | ||
44 | + | ||
45 | +here=$PWD | ||
46 | +status=1 # failure is the default! | ||
47 | + | ||
48 | +_cleanup() | ||
49 | +{ | ||
50 | + _cleanup_test_img | ||
51 | +} | ||
52 | +trap "_cleanup; exit \$status" 0 1 2 3 15 | ||
53 | + | ||
54 | +# get standard environment and filters | ||
55 | +. ./common.rc | ||
56 | +. ./common.filter | ||
57 | + | ||
58 | +_supported_fmt raw | ||
59 | +_supported_proto file | ||
60 | +_supported_os Linux | ||
61 | + | ||
62 | +# in kB | ||
63 | +CREATION_SIZE=128 | ||
64 | +GROWTH_SIZE=256 | ||
65 | + | ||
66 | +echo '=== Testing image growth ===' | ||
67 | + | ||
68 | +for create_mode in off falloc full; do | ||
69 | + for growth_mode in off falloc full; do | ||
70 | + echo | ||
71 | + echo "--- create_mode=$create_mode growth_mode=$growth_mode ---" | ||
72 | + | ||
73 | + IMGOPTS="preallocation=$create_mode" _make_test_img ${CREATION_SIZE}K | ||
74 | + $QEMU_IMG resize -f "$IMGFMT" --preallocation=$growth_mode "$TEST_IMG" +${GROWTH_SIZE}K | ||
75 | + | ||
76 | + expected_size=0 | ||
77 | + if [ $create_mode != off ]; then | ||
78 | + expected_size=$CREATION_SIZE | ||
79 | + fi | ||
80 | + if [ $growth_mode != off ]; then | ||
81 | + expected_size=$((expected_size + $GROWTH_SIZE)) | ||
82 | + fi | ||
83 | + | ||
84 | + actual_size=$($QEMU_IMG info -f "$IMGFMT" "$TEST_IMG" | grep 'disk size') | ||
85 | + actual_size=$(echo "$actual_size" | sed -e 's/^[^0-9]*\([0-9]\+\).*$/\1/') | ||
86 | + | ||
87 | + # The actual size may exceed the expected size, depending on the file | ||
88 | + # system. Therefore we just test that the actual size is at least what | ||
89 | + # we expect. | ||
90 | + if [ $actual_size -lt $expected_size ]; then | ||
91 | + echo "ERROR: Image should have at least ${expected_size}K, but has ${actual_size}K" | ||
92 | + fi | ||
93 | + done | ||
94 | +done | ||
95 | + | ||
96 | +echo | ||
97 | +echo '=== Testing image shrinking ===' | ||
98 | + | ||
99 | +# None of this should work except for "off", because other modes cannot be used | ||
100 | +# for shrinking | ||
101 | +for growth_mode in falloc full off; do | ||
102 | + echo | ||
103 | + echo "--- growth_mode=$growth_mode ---" | ||
104 | + $QEMU_IMG resize -f "$IMGFMT" --preallocation=$growth_mode "$TEST_IMG" -${GROWTH_SIZE}K | ||
105 | +done | ||
106 | + | ||
107 | +# success, all done | ||
108 | +echo '*** done' | ||
109 | +rm -f $seq.full | ||
110 | +status=0 | ||
111 | diff --git a/tests/qemu-iotests/106.out b/tests/qemu-iotests/106.out | ||
112 | new file mode 100644 | ||
113 | index XXXXXXX..XXXXXXX | ||
114 | --- /dev/null | ||
115 | +++ b/tests/qemu-iotests/106.out | ||
116 | @@ -XXX,XX +XXX,XX @@ | ||
117 | +QA output created by 106 | ||
118 | +=== Testing image growth === | ||
119 | + | ||
120 | +--- create_mode=off growth_mode=off --- | ||
121 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072 preallocation=off | ||
122 | +Image resized. | ||
123 | + | ||
124 | +--- create_mode=off growth_mode=falloc --- | ||
125 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072 preallocation=off | ||
126 | +Image resized. | ||
127 | + | ||
128 | +--- create_mode=off growth_mode=full --- | ||
129 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072 preallocation=off | ||
130 | +Image resized. | ||
131 | + | ||
132 | +--- create_mode=falloc growth_mode=off --- | ||
133 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072 preallocation=falloc | ||
134 | +Image resized. | ||
135 | + | ||
136 | +--- create_mode=falloc growth_mode=falloc --- | ||
137 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072 preallocation=falloc | ||
138 | +Image resized. | ||
139 | + | ||
140 | +--- create_mode=falloc growth_mode=full --- | ||
141 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072 preallocation=falloc | ||
142 | +Image resized. | ||
143 | + | ||
144 | +--- create_mode=full growth_mode=off --- | ||
145 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072 preallocation=full | ||
146 | +Image resized. | ||
147 | + | ||
148 | +--- create_mode=full growth_mode=falloc --- | ||
149 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072 preallocation=full | ||
150 | +Image resized. | ||
151 | + | ||
152 | +--- create_mode=full growth_mode=full --- | ||
153 | +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072 preallocation=full | ||
154 | +Image resized. | ||
155 | + | ||
156 | +=== Testing image shrinking === | ||
157 | + | ||
158 | +--- growth_mode=falloc --- | ||
159 | +qemu-img: Preallocation can only be used for growing images | ||
160 | + | ||
161 | +--- growth_mode=full --- | ||
162 | +qemu-img: Preallocation can only be used for growing images | ||
163 | + | ||
164 | +--- growth_mode=off --- | ||
165 | +Image resized. | ||
166 | +*** done | ||
167 | diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group | ||
168 | index XXXXXXX..XXXXXXX 100644 | ||
169 | --- a/tests/qemu-iotests/group | ||
170 | +++ b/tests/qemu-iotests/group | ||
171 | @@ -XXX,XX +XXX,XX @@ | ||
172 | 103 rw auto quick | ||
173 | 104 rw auto | ||
174 | 105 rw auto quick | ||
175 | +106 rw auto quick | ||
176 | 107 rw auto quick | ||
177 | 108 rw auto quick | ||
178 | 109 rw auto | ||
179 | -- | ||
180 | 2.9.4 | ||
181 | |||
182 | diff view generated by jsdifflib |