1
The following changes since commit b11365867568ba954de667a0bfe0945b8f78d6bd:
1
The following changes since commit e1e44a9916b4318e943aecd669e096222cb3eaeb:
2
2
3
Merge remote-tracking branch 'remotes/borntraeger/tags/s390x-20170706' into staging (2017-07-06 11:42:59 +0100)
3
Merge remote-tracking branch 'remotes/xtensa/tags/20180316-xtensa' into staging (2018-03-17 14:15:03 +0000)
4
4
5
are available in the git repository at:
5
are available in the git repository at:
6
6
7
8
git://repo.or.cz/qemu/kevin.git tags/for-upstream
7
git://repo.or.cz/qemu/kevin.git tags/for-upstream
9
8
10
for you to fetch changes up to 7d982302db173616d011e07ee43be3b0aae872b1:
9
for you to fetch changes up to 63ca8406beac44aa59c389ed8578d0c7b3da3402:
11
10
12
Merge remote-tracking branch 'mreitz/tags/pull-block-2017-07-07' into queue-block (2017-07-07 18:11:41 +0200)
11
iotests: Avoid realpath, for CentOS 6 (2018-03-19 12:01:39 +0100)
13
12
14
----------------------------------------------------------------
13
----------------------------------------------------------------
15
16
Block layer patches
14
Block layer patches
17
15
18
----------------------------------------------------------------
16
----------------------------------------------------------------
19
Daniel P. Berrange (26):
17
Eric Blake (1):
20
qemu-img: drop -e and -6 options from the 'create' & 'convert' commands
18
iotests: Avoid realpath, for CentOS 6
21
block: expose crypto option names / defs to other drivers
22
block: add ability to set a prefix for opt names
23
qcow: document another weakness of qcow AES encryption
24
qcow: require image size to be > 1 for new images
25
iotests: skip 042 with qcow which dosn't support zero sized images
26
iotests: skip 048 with qcow which doesn't support resize
27
block: deprecate "encryption=on" in favor of "encrypt.format=aes"
28
qcow: make encrypt_sectors encrypt in place
29
qcow: convert QCow to use QCryptoBlock for encryption
30
qcow2: make qcow2_encrypt_sectors encrypt in place
31
qcow2: convert QCow2 to use QCryptoBlock for encryption
32
qcow2: extend specification to cover LUKS encryption
33
qcow2: add support for LUKS encryption format
34
qcow2: add iotests to cover LUKS encryption support
35
iotests: enable tests 134 and 158 to work with qcow (v1)
36
block: rip out all traces of password prompting
37
block: remove all encryption handling APIs
38
block: pass option prefix down to crypto layer
39
qcow2: report encryption specific image information
40
docs: document encryption options for qcow, qcow2 and luks
41
iotests: skip 159 & 170 with luks format
42
iotests: fix remainining tests to work with LUKS
43
iotests: reduce PBKDF iterations when testing LUKS
44
iotests: add more LUKS hash combination tests
45
iotests: chown LUKS device before qemu-io launches
46
19
47
Eric Blake (26):
20
Fam Zheng (4):
48
qemu-io: Don't die on second open
21
block: Fix flags in reopen queue
49
block: Guarantee that *file is set on bdrv_get_block_status()
22
iotests: Add regression test for commit base locking
50
block: Simplify use of BDRV_BLOCK_RAW
23
vvfat: Fix inherit_options flags
51
blkdebug: Support .bdrv_co_get_block_status
24
block: Fix leak of ignore_children in error path
52
blockjob: Track job ratelimits via bytes, not sectors
53
trace: Show blockjob actions via bytes, not sectors
54
stream: Switch stream_populate() to byte-based
55
stream: Drop reached_end for stream_complete()
56
stream: Switch stream_run() to byte-based
57
commit: Switch commit_populate() to byte-based
58
commit: Switch commit_run() to byte-based
59
mirror: Switch MirrorBlockJob to byte-based
60
mirror: Switch mirror_do_zero_or_discard() to byte-based
61
mirror: Update signature of mirror_clip_sectors()
62
mirror: Switch mirror_cow_align() to byte-based
63
mirror: Switch mirror_do_read() to byte-based
64
mirror: Switch mirror_iteration() to byte-based
65
block: Drop unused bdrv_round_sectors_to_clusters()
66
backup: Switch BackupBlockJob to byte-based
67
backup: Switch block_backup.h to byte-based
68
backup: Switch backup_do_cow() to byte-based
69
backup: Switch backup_run() to byte-based
70
block: Make bdrv_is_allocated() byte-based
71
block: Minimize raw use of bds->total_sectors
72
block: Make bdrv_is_allocated_above() byte-based
73
tests: Avoid non-portable 'echo -ARG'
74
25
75
Hervé Poussineau (13):
26
Jeff Cody (1):
76
vvfat: fix qemu-img map and qemu-img convert
27
block: fix iotest 146 output expectations
77
vvfat: replace tabs by 8 spaces
78
vvfat: fix typos
79
vvfat: rename useless enumeration values
80
vvfat: introduce offset_to_bootsector, offset_to_fat and offset_to_root_dir
81
vvfat: fix field names in FAT12/FAT16 and FAT32 boot sectors
82
vvfat: always create . and .. entries at first and in that order
83
vvfat: correctly create long names for non-ASCII filenames
84
vvfat: correctly create base short names for non-ASCII filenames
85
vvfat: correctly generate numeric-tail of short file names
86
vvfat: limit number of entries in root directory in FAT12/FAT16
87
vvfat: handle KANJI lead byte 0xe5
88
vvfat: change OEM name to 'MSWIN4.1'
89
28
90
Kevin Wolf (1):
29
John Snow (21):
91
Merge remote-tracking branch 'mreitz/tags/pull-block-2017-07-07' into queue-block
30
blockjobs: fix set-speed kick
31
blockjobs: model single jobs as transactions
32
Blockjobs: documentation touchup
33
blockjobs: add status enum
34
blockjobs: add state transition table
35
iotests: add pause_wait
36
blockjobs: add block_job_verb permission table
37
blockjobs: add ABORTING state
38
blockjobs: add CONCLUDED state
39
blockjobs: add NULL state
40
blockjobs: add block_job_dismiss
41
blockjobs: ensure abort is called for cancelled jobs
42
blockjobs: add commit, abort, clean helpers
43
blockjobs: add block_job_txn_apply function
44
blockjobs: add prepare callback
45
blockjobs: add waiting status
46
blockjobs: add PENDING status and event
47
blockjobs: add block-job-finalize
48
blockjobs: Expose manual property
49
iotests: test manual job dismissal
50
tests/test-blockjob: test cancellations
51
52
Kevin Wolf (14):
53
luks: Separate image file creation from formatting
54
luks: Create block_crypto_co_create_generic()
55
luks: Support .bdrv_co_create
56
luks: Turn invalid assertion into check
57
luks: Catch integer overflow for huge sizes
58
qemu-iotests: Test luks QMP image creation
59
parallels: Support .bdrv_co_create
60
qemu-iotests: Enable write tests for parallels
61
qcow: Support .bdrv_co_create
62
qed: Support .bdrv_co_create
63
vdi: Make comments consistent with other drivers
64
vhdx: Support .bdrv_co_create
65
vpc: Support .bdrv_co_create
66
vpc: Require aligned size in .bdrv_co_create
67
68
Liang Li (1):
69
block/mirror: change the semantic of 'force' of block-job-cancel
92
70
93
Max Reitz (3):
71
Max Reitz (3):
94
iotests: 181 does not work for all formats
72
vdi: Pull option parsing from vdi_co_create
95
iotests: Use absolute paths for executables
73
vdi: Move file creation to vdi_co_create_opts
96
iotests: Add test for colon handling
74
vdi: Implement .bdrv_co_create
97
75
98
Thomas Huth (1):
76
Paolo Bonzini (1):
99
blockdev: Print a warning for legacy drive options that belong to -device
77
iscsi: fix iSER compilation
100
78
101
Vladimir Sementsov-Ogievskiy (30):
79
qapi/block-core.json | 363 ++++++++++++++++++++++++++++++++++++++++--
102
specs/qcow2: fix bitmap granularity qemu-specific note
80
include/block/blockjob.h | 71 ++++++++-
103
specs/qcow2: do not use wording 'bitmap header'
81
include/block/blockjob_int.h | 17 +-
104
hbitmap: improve dirty iter
82
block.c | 10 +-
105
tests: add hbitmap iter test
83
block/backup.c | 5 +-
106
block: fix bdrv_dirty_bitmap_granularity signature
84
block/commit.c | 2 +-
107
block/dirty-bitmap: add deserialize_ones func
85
block/crypto.c | 150 ++++++++++++-----
108
qcow2-refcount: rename inc_refcounts() and make it public
86
block/iscsi.c | 2 +-
109
qcow2: add bitmaps extension
87
block/mirror.c | 12 +-
110
block/dirty-bitmap: fix comment for BlockDirtyBitmap.disabled field
88
block/parallels.c | 199 +++++++++++++++++------
111
block/dirty-bitmap: add readonly field to BdrvDirtyBitmap
89
block/qcow.c | 196 +++++++++++++++--------
112
qcow2: autoloading dirty bitmaps
90
block/qed.c | 204 ++++++++++++++++--------
113
block: refactor bdrv_reopen_commit
91
block/stream.c | 2 +-
114
block: new bdrv_reopen_bitmaps_rw interface
92
block/vdi.c | 147 +++++++++++++----
115
qcow2: support .bdrv_reopen_bitmaps_rw
93
block/vhdx.c | 216 +++++++++++++++++++------
116
block/dirty-bitmap: add autoload field to BdrvDirtyBitmap
94
block/vpc.c | 241 +++++++++++++++++++++-------
117
block: bdrv_close: release bitmaps after drv->bdrv_close
95
block/vvfat.c | 2 +-
118
block: introduce persistent dirty bitmaps
96
blockdev.c | 71 +++++++--
119
block/dirty-bitmap: add bdrv_dirty_bitmap_next()
97
blockjob.c | 358 +++++++++++++++++++++++++++++++++++------
120
qcow2: add persistent dirty bitmaps support
98
tests/test-bdrv-drain.c | 5 +-
121
qcow2: store bitmaps on reopening image as read-only
99
tests/test-blockjob-txn.c | 27 ++--
122
block: add bdrv_can_store_new_dirty_bitmap
100
tests/test-blockjob.c | 233 ++++++++++++++++++++++++++-
123
qcow2: add .bdrv_can_store_new_dirty_bitmap
101
block/trace-events | 7 +
124
qmp: add persistent flag to block-dirty-bitmap-add
102
hmp-commands.hx | 3 +-
125
qmp: add autoload parameter to block-dirty-bitmap-add
103
tests/qemu-iotests/030 | 6 +-
126
qmp: add x-debug-block-dirty-bitmap-sha256
104
tests/qemu-iotests/055 | 17 +-
127
iotests: test qcow2 persistent dirty bitmap
105
tests/qemu-iotests/056 | 187 ++++++++++++++++++++++
128
block/dirty-bitmap: add bdrv_remove_persistent_dirty_bitmap
106
tests/qemu-iotests/056.out | 4 +-
129
qcow2: add .bdrv_remove_persistent_dirty_bitmap
107
tests/qemu-iotests/109.out | 24 +--
130
qmp: block-dirty-bitmap-remove: remove persistent
108
tests/qemu-iotests/146.out | 2 +-
131
block: release persistent bitmaps on inactivate
109
tests/qemu-iotests/153 | 12 ++
110
tests/qemu-iotests/153.out | 5 +
111
tests/qemu-iotests/181 | 2 +-
112
tests/qemu-iotests/210 | 210 ++++++++++++++++++++++++
113
tests/qemu-iotests/210.out | 136 ++++++++++++++++
114
tests/qemu-iotests/check | 13 +-
115
tests/qemu-iotests/common.rc | 2 +-
116
tests/qemu-iotests/group | 1 +
117
tests/qemu-iotests/iotests.py | 12 +-
118
39 files changed, 2652 insertions(+), 524 deletions(-)
119
create mode 100755 tests/qemu-iotests/210
120
create mode 100644 tests/qemu-iotests/210.out
132
121
133
sochin.jiang (1):
134
mirror: Fix inconsistent backing AioContext for after mirroring
135
136
block.c | 143 +--
137
block/Makefile.objs | 2 +-
138
block/backup.c | 128 +--
139
block/blkdebug.c | 11 +
140
block/commit.c | 56 +-
141
block/crypto.c | 97 +-
142
block/crypto.h | 101 ++
143
block/dirty-bitmap.c | 154 ++-
144
block/io.c | 110 +-
145
block/mirror.c | 310 ++---
146
block/qapi.c | 2 +-
147
block/qcow.c | 269 ++---
148
block/qcow2-bitmap.c | 1481 ++++++++++++++++++++++++
149
block/qcow2-cluster.c | 66 +-
150
block/qcow2-refcount.c | 69 +-
151
block/qcow2.c | 653 +++++++++--
152
block/qcow2.h | 60 +-
153
block/raw-format.c | 2 +-
154
block/replication.c | 29 +-
155
block/stream.c | 37 +-
156
block/trace-events | 14 +-
157
block/vpc.c | 2 +-
158
block/vvfat.c | 2336 ++++++++++++++++++++------------------
159
blockdev.c | 124 +-
160
crypto/block-luks.c | 8 +-
161
crypto/block-qcow.c | 8 +-
162
crypto/block.c | 6 +-
163
crypto/blockpriv.h | 2 +
164
docs/interop/qcow2.txt | 111 +-
165
hmp-commands.hx | 2 +
166
hmp.c | 31 -
167
include/block/block.h | 22 +-
168
include/block/block_backup.h | 11 +-
169
include/block/block_int.h | 17 +-
170
include/block/dirty-bitmap.h | 22 +-
171
include/crypto/block.h | 6 +-
172
include/monitor/monitor.h | 7 -
173
include/qapi/error.h | 1 -
174
include/qemu/hbitmap.h | 49 +-
175
include/qemu/osdep.h | 2 -
176
include/qemu/ratelimit.h | 3 +-
177
migration/block.c | 16 +-
178
monitor.c | 68 --
179
qapi-schema.json | 10 +-
180
qapi/block-core.json | 172 ++-
181
qapi/common.json | 5 +-
182
qemu-doc.texi | 123 +-
183
qemu-img.c | 76 +-
184
qemu-img.texi | 19 +-
185
qemu-io-cmds.c | 70 +-
186
qemu-io.c | 27 +-
187
qemu-options.hx | 13 +-
188
qmp.c | 12 +-
189
tests/Makefile.include | 2 +-
190
tests/multiboot/run_test.sh | 10 +-
191
tests/qemu-iotests/033 | 12 +-
192
tests/qemu-iotests/042 | 2 +-
193
tests/qemu-iotests/048 | 2 +-
194
tests/qemu-iotests/049 | 2 +-
195
tests/qemu-iotests/049.out | 102 +-
196
tests/qemu-iotests/051 | 7 +-
197
tests/qemu-iotests/060.out | 1 +
198
tests/qemu-iotests/068 | 2 +-
199
tests/qemu-iotests/082.out | 284 ++++-
200
tests/qemu-iotests/085.out | 38 +-
201
tests/qemu-iotests/087 | 39 +-
202
tests/qemu-iotests/087.out | 16 +-
203
tests/qemu-iotests/114.out | 5 +-
204
tests/qemu-iotests/120 | 1 +
205
tests/qemu-iotests/126 | 105 ++
206
tests/qemu-iotests/126.out | 23 +
207
tests/qemu-iotests/134 | 20 +-
208
tests/qemu-iotests/134.out | 10 +-
209
tests/qemu-iotests/140 | 9 +-
210
tests/qemu-iotests/142 | 48 +-
211
tests/qemu-iotests/144.out | 4 +-
212
tests/qemu-iotests/145 | 19 +-
213
tests/qemu-iotests/149 | 25 +-
214
tests/qemu-iotests/149.out | 1002 +++++++++++-----
215
tests/qemu-iotests/153.out | 6 +
216
tests/qemu-iotests/157 | 17 +-
217
tests/qemu-iotests/157.out | 16 +-
218
tests/qemu-iotests/158 | 21 +-
219
tests/qemu-iotests/158.out | 14 +-
220
tests/qemu-iotests/159 | 1 +
221
tests/qemu-iotests/165 | 105 ++
222
tests/qemu-iotests/165.out | 5 +
223
tests/qemu-iotests/170 | 1 +
224
tests/qemu-iotests/171 | 14 +-
225
tests/qemu-iotests/174 | 2 +-
226
tests/qemu-iotests/177 | 3 +
227
tests/qemu-iotests/177.out | 5 +
228
tests/qemu-iotests/181 | 23 +-
229
tests/qemu-iotests/185.out | 8 +-
230
tests/qemu-iotests/188 | 76 ++
231
tests/qemu-iotests/188.out | 18 +
232
tests/qemu-iotests/189 | 86 ++
233
tests/qemu-iotests/189.out | 26 +
234
tests/qemu-iotests/check | 18 +-
235
tests/qemu-iotests/common | 10 +-
236
tests/qemu-iotests/common.config | 11 +
237
tests/qemu-iotests/common.filter | 3 +-
238
tests/qemu-iotests/common.qemu | 9 +-
239
tests/qemu-iotests/common.rc | 3 +
240
tests/qemu-iotests/group | 4 +
241
tests/rocker/all | 10 +-
242
tests/tcg/cris/Makefile | 8 +-
243
tests/test-crypto-block.c | 8 +-
244
tests/test-hbitmap.c | 19 +
245
util/hbitmap.c | 51 +-
246
util/oslib-posix.c | 66 --
247
util/oslib-win32.c | 24 -
248
112 files changed, 6714 insertions(+), 2942 deletions(-)
249
create mode 100644 block/crypto.h
250
create mode 100644 block/qcow2-bitmap.c
251
create mode 100755 tests/qemu-iotests/126
252
create mode 100644 tests/qemu-iotests/126.out
253
create mode 100755 tests/qemu-iotests/165
254
create mode 100644 tests/qemu-iotests/165.out
255
create mode 100755 tests/qemu-iotests/188
256
create mode 100644 tests/qemu-iotests/188.out
257
create mode 100755 tests/qemu-iotests/189
258
create mode 100644 tests/qemu-iotests/189.out
259
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
Most callback commands in qemu-io return 0 to keep the interpreter
4
loop running, or 1 to quit immediately. However, open_f() just
5
passed through the return value of openfile(), which has different
6
semantics of returning 0 if a file was opened, or 1 on any failure.
7
8
As a result of mixing the return semantics, we are forcing the
9
qemu-io interpreter to exit early on any failures, which is rather
10
annoying when some of the failures are obviously trying to give
11
the user a hint of how to proceed (if we didn't then kill qemu-io
12
out from under the user's feet):
13
14
$ qemu-io
15
qemu-io> open foo
16
qemu-io> open foo
17
file open already, try 'help close'
18
$ echo $?
19
0
20
21
In general, we WANT openfile() to report failures, since it is the
22
function used in the form 'qemu-io -c "$something" no_such_file'
23
for performing one or more -c options on a single file, and it is
24
not worth attempting $something if the file itself cannot be opened.
25
So the solution is to fix open_f() to always return 0 (when we are
26
in interactive mode, even failure to open should not end the
27
session), and save the return value of openfile() for command line
28
use in main().
29
30
Note, however, that we do have some qemu-iotests that do 'qemu-io
31
-c "open file" -c "$something"'; such tests will now proceed to
32
attempt $something whether or not the open succeeded, the same way
33
as if the two commands had been attempted in interactive mode. As
34
such, the expected output for those tests has to be modified. But it
35
also means that it is now possible to use -c close and have a single
36
qemu-io command line operate on more than one file even without
37
using interactive mode. Although the '-c open' action is a subtle
38
change in behavior, remember that qemu-io is for debugging purposes,
39
so as long as it serves the needs of qemu-iotests while still being
40
reasonable for interactive use, it should not be a problem that we
41
are changing tests to the new behavior.
42
43
This has been awkward since at least as far back as commit
44
e3aff4f, in 2009.
45
46
Signed-off-by: Eric Blake <eblake@redhat.com>
47
Reviewed-by: Fam Zheng <famz@redhat.com>
48
Reviewed-by: John Snow <jsnow@redhat.com>
49
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
50
---
51
qemu-io.c | 7 ++++---
52
tests/qemu-iotests/060.out | 1 +
53
tests/qemu-iotests/114.out | 5 +++--
54
tests/qemu-iotests/153.out | 6 ++++++
55
4 files changed, 14 insertions(+), 5 deletions(-)
56
57
diff --git a/qemu-io.c b/qemu-io.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/qemu-io.c
60
+++ b/qemu-io.c
61
@@ -XXX,XX +XXX,XX @@ static int open_f(BlockBackend *blk, int argc, char **argv)
62
qemu_opts_reset(&empty_opts);
63
64
if (optind == argc - 1) {
65
- return openfile(argv[optind], flags, writethrough, force_share, opts);
66
+ openfile(argv[optind], flags, writethrough, force_share, opts);
67
} else if (optind == argc) {
68
- return openfile(NULL, flags, writethrough, force_share, opts);
69
+ openfile(NULL, flags, writethrough, force_share, opts);
70
} else {
71
QDECREF(opts);
72
- return qemuio_command_usage(&open_cmd);
73
+ qemuio_command_usage(&open_cmd);
74
}
75
+ return 0;
76
}
77
78
static int quit_f(BlockBackend *blk, int argc, char **argv)
79
diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out
80
index XXXXXXX..XXXXXXX 100644
81
--- a/tests/qemu-iotests/060.out
82
+++ b/tests/qemu-iotests/060.out
83
@@ -XXX,XX +XXX,XX @@ Format specific information:
84
refcount bits: 16
85
corrupt: true
86
can't open device TEST_DIR/t.IMGFMT: IMGFMT: Image is corrupt; cannot be opened read/write
87
+no file open, try 'help open'
88
read 512/512 bytes at offset 0
89
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
90
91
diff --git a/tests/qemu-iotests/114.out b/tests/qemu-iotests/114.out
92
index XXXXXXX..XXXXXXX 100644
93
--- a/tests/qemu-iotests/114.out
94
+++ b/tests/qemu-iotests/114.out
95
@@ -XXX,XX +XXX,XX @@
96
QA output created by 114
97
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
98
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base
99
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
100
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base
101
image: TEST_DIR/t.IMGFMT
102
file format: IMGFMT
103
virtual size: 64M (67108864 bytes)
104
@@ -XXX,XX +XXX,XX @@ cluster_size: 65536
105
backing file: TEST_DIR/t.IMGFMT.base
106
backing file format: foo
107
can't open device TEST_DIR/t.qcow2: Could not open backing file: Unknown driver 'foo'
108
+no file open, try 'help open'
109
read 4096/4096 bytes at offset 0
110
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
111
*** done
112
diff --git a/tests/qemu-iotests/153.out b/tests/qemu-iotests/153.out
113
index XXXXXXX..XXXXXXX 100644
114
--- a/tests/qemu-iotests/153.out
115
+++ b/tests/qemu-iotests/153.out
116
@@ -XXX,XX +XXX,XX @@ Is another process using the image?
117
_qemu_io_wrapper -c open TEST_DIR/t.qcow2 -c read 0 512
118
can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
119
Is another process using the image?
120
+no file open, try 'help open'
121
122
_qemu_io_wrapper -c open -r TEST_DIR/t.qcow2 -c read 0 512
123
can't open device TEST_DIR/t.qcow2: Failed to get shared "write" lock
124
Is another process using the image?
125
+no file open, try 'help open'
126
127
_qemu_img_wrapper info TEST_DIR/t.qcow2
128
qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get shared "write" lock
129
@@ -XXX,XX +XXX,XX @@ _qemu_io_wrapper -U -r -c read 0 512 TEST_DIR/t.qcow2
130
131
_qemu_io_wrapper -c open -U TEST_DIR/t.qcow2 -c read 0 512
132
can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
133
+no file open, try 'help open'
134
135
_qemu_io_wrapper -c open -r -U TEST_DIR/t.qcow2 -c read 0 512
136
137
@@ -XXX,XX +XXX,XX @@ _qemu_io_wrapper -r -c read 0 512 TEST_DIR/t.qcow2
138
_qemu_io_wrapper -c open TEST_DIR/t.qcow2 -c read 0 512
139
can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
140
Is another process using the image?
141
+no file open, try 'help open'
142
143
_qemu_io_wrapper -c open -r TEST_DIR/t.qcow2 -c read 0 512
144
145
@@ -XXX,XX +XXX,XX @@ _qemu_io_wrapper -U -r -c read 0 512 TEST_DIR/t.qcow2
146
147
_qemu_io_wrapper -c open -U TEST_DIR/t.qcow2 -c read 0 512
148
can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
149
+no file open, try 'help open'
150
151
_qemu_io_wrapper -c open -r -U TEST_DIR/t.qcow2 -c read 0 512
152
153
@@ -XXX,XX +XXX,XX @@ _qemu_io_wrapper -U -r -c read 0 512 TEST_DIR/t.qcow2
154
155
_qemu_io_wrapper -c open -U TEST_DIR/t.qcow2 -c read 0 512
156
can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
157
+no file open, try 'help open'
158
159
_qemu_io_wrapper -c open -r -U TEST_DIR/t.qcow2 -c read 0 512
160
161
--
162
1.8.3.1
163
164
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
We document that *file is valid if the return is not an error and
4
includes BDRV_BLOCK_OFFSET_VALID, but forgot to obey this contract
5
when a driver (such as blkdebug) lacks a callback. Messed up in
6
commit 67a0fd2 (v2.6), when we added the file parameter.
7
8
Enhance qemu-iotest 177 to cover this, using a sequence that would
9
print garbage or even SEGV, because it was dererefencing through
10
uninitialized memory. [The resulting test output shows that we
11
have less-than-ideal block status from the blkdebug driver, but
12
that's a separate fix coming up soon.]
13
14
Setting *file on all paths that return BDRV_BLOCK_OFFSET_VALID is
15
enough to fix the crash, but we can go one step further: always
16
setting *file, even on error, means that a broken caller that
17
blindly dereferences file without checking for error is now more
18
likely to get a reliable SEGV instead of randomly acting on garbage,
19
making it easier to diagnose such buggy callers. Adding an
20
assertion that file is set where expected doesn't hurt either.
21
22
CC: qemu-stable@nongnu.org
23
Signed-off-by: Eric Blake <eblake@redhat.com>
24
Reviewed-by: Fam Zheng <famz@redhat.com>
25
Reviewed-by: Max Reitz <mreitz@redhat.com>
26
Reviewed-by: John Snow <jsnow@redhat.com>
27
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
28
---
29
block/io.c | 5 +++--
30
tests/qemu-iotests/177 | 3 +++
31
tests/qemu-iotests/177.out | 2 ++
32
3 files changed, 8 insertions(+), 2 deletions(-)
33
34
diff --git a/block/io.c b/block/io.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/block/io.c
37
+++ b/block/io.c
38
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
39
int64_t n;
40
int64_t ret, ret2;
41
42
+ *file = NULL;
43
total_sectors = bdrv_nb_sectors(bs);
44
if (total_sectors < 0) {
45
return total_sectors;
46
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
47
}
48
if (bs->drv->protocol_name) {
49
ret |= BDRV_BLOCK_OFFSET_VALID | (sector_num * BDRV_SECTOR_SIZE);
50
+ *file = bs;
51
}
52
return ret;
53
}
54
55
- *file = NULL;
56
bdrv_inc_in_flight(bs);
57
ret = bs->drv->bdrv_co_get_block_status(bs, sector_num, nb_sectors, pnum,
58
file);
59
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
60
}
61
62
if (ret & BDRV_BLOCK_RAW) {
63
- assert(ret & BDRV_BLOCK_OFFSET_VALID);
64
+ assert(ret & BDRV_BLOCK_OFFSET_VALID && *file);
65
ret = bdrv_co_get_block_status(*file, ret >> BDRV_SECTOR_BITS,
66
*pnum, pnum, file);
67
goto out;
68
diff --git a/tests/qemu-iotests/177 b/tests/qemu-iotests/177
69
index XXXXXXX..XXXXXXX 100755
70
--- a/tests/qemu-iotests/177
71
+++ b/tests/qemu-iotests/177
72
@@ -XXX,XX +XXX,XX @@ _supported_proto file
73
CLUSTER_SIZE=1M
74
size=128M
75
options=driver=blkdebug,image.driver=qcow2
76
+nested_opts=image.file.driver=file,image.file.filename=$TEST_IMG
77
78
echo
79
echo "== setting up files =="
80
@@ -XXX,XX +XXX,XX @@ function verify_io()
81
}
82
83
verify_io | $QEMU_IO -r "$TEST_IMG" | _filter_qemu_io
84
+$QEMU_IMG map --image-opts "$options,$nested_opts,align=4k" \
85
+ | _filter_qemu_img_map
86
87
_check_test_img
88
89
diff --git a/tests/qemu-iotests/177.out b/tests/qemu-iotests/177.out
90
index XXXXXXX..XXXXXXX 100644
91
--- a/tests/qemu-iotests/177.out
92
+++ b/tests/qemu-iotests/177.out
93
@@ -XXX,XX +XXX,XX @@ read 30408704/30408704 bytes at offset 80740352
94
29 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
95
read 23068672/23068672 bytes at offset 111149056
96
22 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
97
+Offset Length File
98
+0 0x8000000 json:{"image": {"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}}, "driver": "blkdebug", "align": "4k"}
99
No errors were found on the image.
100
*** done
101
--
102
1.8.3.1
103
104
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
The lone caller that cares about a return of BDRV_BLOCK_RAW
4
(namely, io.c:bdrv_co_get_block_status) completely replaces the
5
return value, so there is no point in passing BDRV_BLOCK_DATA.
6
7
Signed-off-by: Eric Blake <eblake@redhat.com>
8
Reviewed-by: Fam Zheng <famz@redhat.com>
9
Reviewed-by: John Snow <jsnow@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
block/commit.c | 2 +-
13
block/mirror.c | 2 +-
14
block/raw-format.c | 2 +-
15
block/vpc.c | 2 +-
16
include/block/block.h | 6 +++---
17
5 files changed, 7 insertions(+), 7 deletions(-)
18
19
diff --git a/block/commit.c b/block/commit.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/block/commit.c
22
+++ b/block/commit.c
23
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn bdrv_commit_top_get_block_status(
24
{
25
*pnum = nb_sectors;
26
*file = bs->backing->bs;
27
- return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID | BDRV_BLOCK_DATA |
28
+ return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID |
29
(sector_num << BDRV_SECTOR_BITS);
30
}
31
32
diff --git a/block/mirror.c b/block/mirror.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/block/mirror.c
35
+++ b/block/mirror.c
36
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn bdrv_mirror_top_get_block_status(
37
{
38
*pnum = nb_sectors;
39
*file = bs->backing->bs;
40
- return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID | BDRV_BLOCK_DATA |
41
+ return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID |
42
(sector_num << BDRV_SECTOR_BITS);
43
}
44
45
diff --git a/block/raw-format.c b/block/raw-format.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/block/raw-format.c
48
+++ b/block/raw-format.c
49
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs,
50
*pnum = nb_sectors;
51
*file = bs->file->bs;
52
sector_num += s->offset / BDRV_SECTOR_SIZE;
53
- return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID | BDRV_BLOCK_DATA |
54
+ return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID |
55
(sector_num << BDRV_SECTOR_BITS);
56
}
57
58
diff --git a/block/vpc.c b/block/vpc.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/block/vpc.c
61
+++ b/block/vpc.c
62
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn vpc_co_get_block_status(BlockDriverState *bs,
63
if (be32_to_cpu(footer->type) == VHD_FIXED) {
64
*pnum = nb_sectors;
65
*file = bs->file->bs;
66
- return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID | BDRV_BLOCK_DATA |
67
+ return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID |
68
(sector_num << BDRV_SECTOR_BITS);
69
}
70
71
diff --git a/include/block/block.h b/include/block/block.h
72
index XXXXXXX..XXXXXXX 100644
73
--- a/include/block/block.h
74
+++ b/include/block/block.h
75
@@ -XXX,XX +XXX,XX @@ typedef struct HDGeometry {
76
* BDRV_BLOCK_EOF: the returned pnum covers through end of file for this layer
77
*
78
* Internal flag:
79
- * BDRV_BLOCK_RAW: used internally to indicate that the request was
80
- * answered by a passthrough driver such as raw and that the
81
- * block layer should recompute the answer from bs->file.
82
+ * BDRV_BLOCK_RAW: for use by passthrough drivers, such as raw, to request
83
+ * that the block layer recompute the answer from the returned
84
+ * BDS; must be accompanied by just BDRV_BLOCK_OFFSET_VALID.
85
*
86
* If BDRV_BLOCK_OFFSET_VALID is set, bits 9-62 (BDRV_BLOCK_OFFSET_MASK)
87
* represent the offset in the returned BDS that is allocated for the
88
--
89
1.8.3.1
90
91
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
Without a passthrough status of BDRV_BLOCK_RAW, anything wrapped by
4
blkdebug appears 100% allocated as data. Better is treating it the
5
same as the underlying file being wrapped.
6
7
Update iotest 177 for the new expected output.
8
9
Signed-off-by: Eric Blake <eblake@redhat.com>
10
Reviewed-by: Fam Zheng <famz@redhat.com>
11
Reviewed-by: Max Reitz <mreitz@redhat.com>
12
Reviewed-by: John Snow <jsnow@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
15
block/blkdebug.c | 11 +++++++++++
16
tests/qemu-iotests/177.out | 5 ++++-
17
2 files changed, 15 insertions(+), 1 deletion(-)
18
19
diff --git a/block/blkdebug.c b/block/blkdebug.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/block/blkdebug.c
22
+++ b/block/blkdebug.c
23
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn blkdebug_co_pdiscard(BlockDriverState *bs,
24
return bdrv_co_pdiscard(bs->file->bs, offset, bytes);
25
}
26
27
+static int64_t coroutine_fn blkdebug_co_get_block_status(
28
+ BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum,
29
+ BlockDriverState **file)
30
+{
31
+ *pnum = nb_sectors;
32
+ *file = bs->file->bs;
33
+ return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID |
34
+ (sector_num << BDRV_SECTOR_BITS);
35
+}
36
+
37
static void blkdebug_close(BlockDriverState *bs)
38
{
39
BDRVBlkdebugState *s = bs->opaque;
40
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_blkdebug = {
41
.bdrv_co_flush_to_disk = blkdebug_co_flush,
42
.bdrv_co_pwrite_zeroes = blkdebug_co_pwrite_zeroes,
43
.bdrv_co_pdiscard = blkdebug_co_pdiscard,
44
+ .bdrv_co_get_block_status = blkdebug_co_get_block_status,
45
46
.bdrv_debug_event = blkdebug_debug_event,
47
.bdrv_debug_breakpoint = blkdebug_debug_breakpoint,
48
diff --git a/tests/qemu-iotests/177.out b/tests/qemu-iotests/177.out
49
index XXXXXXX..XXXXXXX 100644
50
--- a/tests/qemu-iotests/177.out
51
+++ b/tests/qemu-iotests/177.out
52
@@ -XXX,XX +XXX,XX @@ read 30408704/30408704 bytes at offset 80740352
53
read 23068672/23068672 bytes at offset 111149056
54
22 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
55
Offset Length File
56
-0 0x8000000 json:{"image": {"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}}, "driver": "blkdebug", "align": "4k"}
57
+0 0x800000 TEST_DIR/t.IMGFMT
58
+0x900000 0x2400000 TEST_DIR/t.IMGFMT
59
+0x3c00000 0x1100000 TEST_DIR/t.IMGFMT
60
+0x6a00000 0x1600000 TEST_DIR/t.IMGFMT
61
No errors were found on the image.
62
*** done
63
--
64
1.8.3.1
65
66
diff view generated by jsdifflib
Deleted patch
1
From: Hervé Poussineau <hpoussin@reactos.org>
2
1
3
- bs->total_sectors is the number of sectors of the whole disk
4
- s->sector_count is the number of sectors of the FAT partition
5
6
This fixes the following assert in qemu-img map:
7
qemu-img.c:2641: get_block_status: Assertion `nb_sectors' failed.
8
9
This also fixes an infinite loop in qemu-img convert.
10
11
Fixes: 4480e0f924a42e1db8b8cfcac4d0634dd1bb27a0
12
Fixes: https://bugs.launchpad.net/qemu/+bug/1599539
13
Cc: qemu-stable@nongnu.org
14
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
15
Reviewed-by: Eric Blake <eblake@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
---
18
block/vvfat.c | 3 +--
19
1 file changed, 1 insertion(+), 2 deletions(-)
20
21
diff --git a/block/vvfat.c b/block/vvfat.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/block/vvfat.c
24
+++ b/block/vvfat.c
25
@@ -XXX,XX +XXX,XX @@ vvfat_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
26
static int64_t coroutine_fn vvfat_co_get_block_status(BlockDriverState *bs,
27
    int64_t sector_num, int nb_sectors, int *n, BlockDriverState **file)
28
{
29
- BDRVVVFATState* s = bs->opaque;
30
- *n = s->sector_count - sector_num;
31
+ *n = bs->total_sectors - sector_num;
32
if (*n > nb_sectors) {
33
*n = nb_sectors;
34
} else if (*n < 0) {
35
--
36
1.8.3.1
37
38
diff view generated by jsdifflib
Deleted patch
1
From: Hervé Poussineau <hpoussin@reactos.org>
2
1
3
This was a complete mess. On 2299 indented lines:
4
- 1329 were with spaces only
5
- 617 with tabulations only
6
- 353 with spaces and tabulations
7
8
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
block/vvfat.c | 2054 ++++++++++++++++++++++++++++-----------------------------
12
1 file changed, 1027 insertions(+), 1027 deletions(-)
13
14
diff --git a/block/vvfat.c b/block/vvfat.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/block/vvfat.c
17
+++ b/block/vvfat.c
18
@@ -XXX,XX +XXX,XX @@ static inline void* array_get(array_t* array,unsigned int index) {
19
static inline int array_ensure_allocated(array_t* array, int index)
20
{
21
if((index + 1) * array->item_size > array->size) {
22
-    int new_size = (index + 32) * array->item_size;
23
-    array->pointer = g_realloc(array->pointer, new_size);
24
-    if (!array->pointer)
25
-     return -1;
26
-    array->size = new_size;
27
-    array->next = index + 1;
28
+ int new_size = (index + 32) * array->item_size;
29
+ array->pointer = g_realloc(array->pointer, new_size);
30
+ if (!array->pointer)
31
+ return -1;
32
+ array->size = new_size;
33
+ array->next = index + 1;
34
}
35
36
return 0;
37
@@ -XXX,XX +XXX,XX @@ static inline void* array_get_next(array_t* array) {
38
unsigned int next = array->next;
39
40
if (array_ensure_allocated(array, next) < 0)
41
-    return NULL;
42
+ return NULL;
43
44
array->next = next + 1;
45
return array_get(array, next);
46
@@ -XXX,XX +XXX,XX @@ static inline void* array_get_next(array_t* array) {
47
48
static inline void* array_insert(array_t* array,unsigned int index,unsigned int count) {
49
if((array->next+count)*array->item_size>array->size) {
50
-    int increment=count*array->item_size;
51
-    array->pointer=g_realloc(array->pointer,array->size+increment);
52
-    if(!array->pointer)
53
+ int increment=count*array->item_size;
54
+ array->pointer=g_realloc(array->pointer,array->size+increment);
55
+ if(!array->pointer)
56
return NULL;
57
-    array->size+=increment;
58
+ array->size+=increment;
59
}
60
memmove(array->pointer+(index+count)*array->item_size,
61
-        array->pointer+index*array->item_size,
62
-        (array->next-index)*array->item_size);
63
+ array->pointer+index*array->item_size,
64
+ (array->next-index)*array->item_size);
65
array->next+=count;
66
return array->pointer+index*array->item_size;
67
}
68
@@ -XXX,XX +XXX,XX @@ static inline int array_roll(array_t* array,int index_to,int index_from,int coun
69
int is;
70
71
if(!array ||
72
-     index_to<0 || index_to>=array->next ||
73
-     index_from<0 || index_from>=array->next)
74
-    return -1;
75
+ index_to<0 || index_to>=array->next ||
76
+ index_from<0 || index_from>=array->next)
77
+ return -1;
78
79
if(index_to==index_from)
80
-    return 0;
81
+ return 0;
82
83
is=array->item_size;
84
from=array->pointer+index_from*is;
85
@@ -XXX,XX +XXX,XX @@ static inline int array_roll(array_t* array,int index_to,int index_from,int coun
86
memcpy(buf,from,is*count);
87
88
if(index_to<index_from)
89
-    memmove(to+is*count,to,from-to);
90
+ memmove(to+is*count,to,from-to);
91
else
92
-    memmove(from,from+is*count,to-from);
93
+ memmove(from,from+is*count,to-from);
94
95
memcpy(to,buf,is*count);
96
97
@@ -XXX,XX +XXX,XX @@ static inline int array_remove_slice(array_t* array,int index, int count)
98
assert(count > 0);
99
assert(index + count <= array->next);
100
if(array_roll(array,array->next-1,index,count))
101
-    return -1;
102
+ return -1;
103
array->next -= count;
104
return 0;
105
}
106
@@ -XXX,XX +XXX,XX @@ typedef struct bootsector_t {
107
uint32_t total_sectors;
108
union {
109
struct {
110
-     uint8_t drive_number;
111
-     uint8_t current_head;
112
-     uint8_t signature;
113
-     uint32_t id;
114
-     uint8_t volume_label[11];
115
-    } QEMU_PACKED fat16;
116
-    struct {
117
-     uint32_t sectors_per_fat;
118
-     uint16_t flags;
119
-     uint8_t major,minor;
120
-     uint32_t first_cluster_of_root_directory;
121
-     uint16_t info_sector;
122
-     uint16_t backup_boot_sector;
123
-     uint16_t ignored;
124
-    } QEMU_PACKED fat32;
125
+ uint8_t drive_number;
126
+ uint8_t current_head;
127
+ uint8_t signature;
128
+ uint32_t id;
129
+ uint8_t volume_label[11];
130
+ } QEMU_PACKED fat16;
131
+ struct {
132
+ uint32_t sectors_per_fat;
133
+ uint16_t flags;
134
+ uint8_t major,minor;
135
+ uint32_t first_cluster_of_root_directory;
136
+ uint16_t info_sector;
137
+ uint16_t backup_boot_sector;
138
+ uint16_t ignored;
139
+ } QEMU_PACKED fat32;
140
} u;
141
uint8_t fat_type[8];
142
uint8_t ignored[0x1c0];
143
@@ -XXX,XX +XXX,XX @@ typedef struct mapping_t {
144
/* the clusters of a file may be in any order; this points to the first */
145
int first_mapping_index;
146
union {
147
-    /* offset is
148
-     * - the offset in the file (in clusters) for a file, or
149
-     * - the next cluster of the directory for a directory, and
150
-     * - the address of the buffer for a faked entry
151
-     */
152
-    struct {
153
-     uint32_t offset;
154
-    } file;
155
-    struct {
156
-     int parent_mapping_index;
157
-     int first_dir_index;
158
-    } dir;
159
+ /* offset is
160
+ * - the offset in the file (in clusters) for a file, or
161
+ * - the next cluster of the directory for a directory, and
162
+ * - the address of the buffer for a faked entry
163
+ */
164
+ struct {
165
+ uint32_t offset;
166
+ } file;
167
+ struct {
168
+ int parent_mapping_index;
169
+ int first_dir_index;
170
+ } dir;
171
} info;
172
/* path contains the full path, i.e. it always starts with s->path */
173
char* path;
174
175
enum { MODE_UNDEFINED = 0, MODE_NORMAL = 1, MODE_MODIFIED = 2,
176
-    MODE_DIRECTORY = 4, MODE_FAKED = 8,
177
-    MODE_DELETED = 16, MODE_RENAMED = 32 } mode;
178
+ MODE_DIRECTORY = 4, MODE_FAKED = 8,
179
+ MODE_DELETED = 16, MODE_RENAMED = 32 } mode;
180
int read_only;
181
} mapping_t;
182
183
@@ -XXX,XX +XXX,XX @@ static inline int short2long_name(char* dest,const char* src)
184
int len;
185
for(i=0;i<129 && src[i];i++) {
186
dest[2*i]=src[i];
187
-    dest[2*i+1]=0;
188
+ dest[2*i+1]=0;
189
}
190
len=2*i;
191
dest[2*i]=dest[2*i+1]=0;
192
for(i=2*i+2;(i%26);i++)
193
-    dest[i]=0xff;
194
+ dest[i]=0xff;
195
return len;
196
}
197
198
@@ -XXX,XX +XXX,XX @@ static inline direntry_t* create_long_filename(BDRVVVFATState* s,const char* fil
199
direntry_t* entry;
200
201
for(i=0;i<number_of_entries;i++) {
202
-    entry=array_get_next(&(s->directory));
203
-    entry->attributes=0xf;
204
-    entry->reserved[0]=0;
205
-    entry->begin=0;
206
-    entry->name[0]=(number_of_entries-i)|(i==0?0x40:0);
207
+ entry=array_get_next(&(s->directory));
208
+ entry->attributes=0xf;
209
+ entry->reserved[0]=0;
210
+ entry->begin=0;
211
+ entry->name[0]=(number_of_entries-i)|(i==0?0x40:0);
212
}
213
for(i=0;i<26*number_of_entries;i++) {
214
-    int offset=(i%26);
215
-    if(offset<10) offset=1+offset;
216
-    else if(offset<22) offset=14+offset-10;
217
-    else offset=28+offset-22;
218
-    entry=array_get(&(s->directory),s->directory.next-1-(i/26));
219
-    entry->name[offset]=buffer[i];
220
+ int offset=(i%26);
221
+ if(offset<10) offset=1+offset;
222
+ else if(offset<22) offset=14+offset-10;
223
+ else offset=28+offset-22;
224
+ entry=array_get(&(s->directory),s->directory.next-1-(i/26));
225
+ entry->name[offset]=buffer[i];
226
}
227
return array_get(&(s->directory),s->directory.next-number_of_entries);
228
}
229
@@ -XXX,XX +XXX,XX @@ static char is_long_name(const direntry_t* direntry)
230
static char is_short_name(const direntry_t* direntry)
231
{
232
return !is_volume_label(direntry) && !is_long_name(direntry)
233
-    && !is_free(direntry);
234
+ && !is_free(direntry);
235
}
236
237
static char is_directory(const direntry_t* direntry)
238
@@ -XXX,XX +XXX,XX @@ static uint16_t fat_datetime(time_t time,int return_time) {
239
t = &t1;
240
localtime_r(&time,t);
241
if(return_time)
242
-    return cpu_to_le16((t->tm_sec/2)|(t->tm_min<<5)|(t->tm_hour<<11));
243
+ return cpu_to_le16((t->tm_sec/2)|(t->tm_min<<5)|(t->tm_hour<<11));
244
return cpu_to_le16((t->tm_mday)|((t->tm_mon+1)<<5)|((t->tm_year-80)<<9));
245
}
246
247
static inline void fat_set(BDRVVVFATState* s,unsigned int cluster,uint32_t value)
248
{
249
if(s->fat_type==32) {
250
-    uint32_t* entry=array_get(&(s->fat),cluster);
251
-    *entry=cpu_to_le32(value);
252
+ uint32_t* entry=array_get(&(s->fat),cluster);
253
+ *entry=cpu_to_le32(value);
254
} else if(s->fat_type==16) {
255
-    uint16_t* entry=array_get(&(s->fat),cluster);
256
-    *entry=cpu_to_le16(value&0xffff);
257
+ uint16_t* entry=array_get(&(s->fat),cluster);
258
+ *entry=cpu_to_le16(value&0xffff);
259
} else {
260
-    int offset = (cluster*3/2);
261
-    unsigned char* p = array_get(&(s->fat), offset);
262
+ int offset = (cluster*3/2);
263
+ unsigned char* p = array_get(&(s->fat), offset);
264
switch (cluster&1) {
265
-    case 0:
266
-        p[0] = value&0xff;
267
-        p[1] = (p[1]&0xf0) | ((value>>8)&0xf);
268
-        break;
269
-    case 1:
270
-        p[0] = (p[0]&0xf) | ((value&0xf)<<4);
271
-        p[1] = (value>>4);
272
-        break;
273
-    }
274
+ case 0:
275
+ p[0] = value&0xff;
276
+ p[1] = (p[1]&0xf0) | ((value>>8)&0xf);
277
+ break;
278
+ case 1:
279
+ p[0] = (p[0]&0xf) | ((value&0xf)<<4);
280
+ p[1] = (value>>4);
281
+ break;
282
+ }
283
}
284
}
285
286
static inline uint32_t fat_get(BDRVVVFATState* s,unsigned int cluster)
287
{
288
if(s->fat_type==32) {
289
-    uint32_t* entry=array_get(&(s->fat),cluster);
290
-    return le32_to_cpu(*entry);
291
+ uint32_t* entry=array_get(&(s->fat),cluster);
292
+ return le32_to_cpu(*entry);
293
} else if(s->fat_type==16) {
294
-    uint16_t* entry=array_get(&(s->fat),cluster);
295
-    return le16_to_cpu(*entry);
296
+ uint16_t* entry=array_get(&(s->fat),cluster);
297
+ return le16_to_cpu(*entry);
298
} else {
299
-    const uint8_t* x=(uint8_t*)(s->fat.pointer)+cluster*3/2;
300
-    return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
301
+ const uint8_t* x=(uint8_t*)(s->fat.pointer)+cluster*3/2;
302
+ return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
303
}
304
}
305
306
static inline int fat_eof(BDRVVVFATState* s,uint32_t fat_entry)
307
{
308
if(fat_entry>s->max_fat_value-8)
309
-    return -1;
310
+ return -1;
311
return 0;
312
}
313
314
static inline void init_fat(BDRVVVFATState* s)
315
{
316
if (s->fat_type == 12) {
317
-    array_init(&(s->fat),1);
318
-    array_ensure_allocated(&(s->fat),
319
-        s->sectors_per_fat * 0x200 * 3 / 2 - 1);
320
+ array_init(&(s->fat),1);
321
+ array_ensure_allocated(&(s->fat),
322
+ s->sectors_per_fat * 0x200 * 3 / 2 - 1);
323
} else {
324
-    array_init(&(s->fat),(s->fat_type==32?4:2));
325
-    array_ensure_allocated(&(s->fat),
326
-        s->sectors_per_fat * 0x200 / s->fat.item_size - 1);
327
+ array_init(&(s->fat),(s->fat_type==32?4:2));
328
+ array_ensure_allocated(&(s->fat),
329
+ s->sectors_per_fat * 0x200 / s->fat.item_size - 1);
330
}
331
memset(s->fat.pointer,0,s->fat.size);
332
333
switch(s->fat_type) {
334
-    case 12: s->max_fat_value=0xfff; break;
335
-    case 16: s->max_fat_value=0xffff; break;
336
-    case 32: s->max_fat_value=0x0fffffff; break;
337
-    default: s->max_fat_value=0; /* error... */
338
+ case 12: s->max_fat_value=0xfff; break;
339
+ case 16: s->max_fat_value=0xffff; break;
340
+ case 32: s->max_fat_value=0x0fffffff; break;
341
+ default: s->max_fat_value=0; /* error... */
342
}
343
344
}
345
@@ -XXX,XX +XXX,XX @@ static inline void init_fat(BDRVVVFATState* s)
346
/* TODO: in create_short_filename, 0xe5->0x05 is not yet handled! */
347
/* TODO: in parse_short_filename, 0x05->0xe5 is not yet handled! */
348
static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s,
349
-    unsigned int directory_start, const char* filename, int is_dot)
350
+ unsigned int directory_start, const char* filename, int is_dot)
351
{
352
int i,j,long_index=s->directory.next;
353
direntry_t* entry = NULL;
354
direntry_t* entry_long = NULL;
355
356
if(is_dot) {
357
-    entry=array_get_next(&(s->directory));
358
+ entry=array_get_next(&(s->directory));
359
memset(entry->name, 0x20, sizeof(entry->name));
360
-    memcpy(entry->name,filename,strlen(filename));
361
-    return entry;
362
+ memcpy(entry->name,filename,strlen(filename));
363
+ return entry;
364
}
365
366
entry_long=create_long_filename(s,filename);
367
@@ -XXX,XX +XXX,XX @@ static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s,
368
i = strlen(filename);
369
for(j = i - 1; j>0 && filename[j]!='.';j--);
370
if (j > 0)
371
-    i = (j > 8 ? 8 : j);
372
+ i = (j > 8 ? 8 : j);
373
else if (i > 8)
374
-    i = 8;
375
+ i = 8;
376
377
entry=array_get_next(&(s->directory));
378
memset(entry->name, 0x20, sizeof(entry->name));
379
@@ -XXX,XX +XXX,XX @@ static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s,
380
381
/* upcase & remove unwanted characters */
382
for(i=10;i>=0;i--) {
383
-    if(i==10 || i==7) for(;i>0 && entry->name[i]==' ';i--);
384
-    if(entry->name[i]<=' ' || entry->name[i]>0x7f
385
-        || strchr(".*?<>|\":/\\[];,+='",entry->name[i]))
386
-     entry->name[i]='_';
387
+ if(i==10 || i==7) for(;i>0 && entry->name[i]==' ';i--);
388
+ if(entry->name[i]<=' ' || entry->name[i]>0x7f
389
+ || strchr(".*?<>|\":/\\[];,+='",entry->name[i]))
390
+ entry->name[i]='_';
391
else if(entry->name[i]>='a' && entry->name[i]<='z')
392
entry->name[i]+='A'-'a';
393
}
394
395
/* mangle duplicates */
396
while(1) {
397
-    direntry_t* entry1=array_get(&(s->directory),directory_start);
398
-    int j;
399
-
400
-    for(;entry1<entry;entry1++)
401
-     if(!is_long_name(entry1) && !memcmp(entry1->name,entry->name,11))
402
-        break; /* found dupe */
403
-    if(entry1==entry) /* no dupe found */
404
-     break;
405
-
406
-    /* use all 8 characters of name */
407
-    if(entry->name[7]==' ') {
408
-     int j;
409
-     for(j=6;j>0 && entry->name[j]==' ';j--)
410
-        entry->name[j]='~';
411
-    }
412
-
413
-    /* increment number */
414
-    for(j=7;j>0 && entry->name[j]=='9';j--)
415
-     entry->name[j]='0';
416
-    if(j>0) {
417
-     if(entry->name[j]<'0' || entry->name[j]>'9')
418
-     entry->name[j]='0';
419
-     else
420
-     entry->name[j]++;
421
-    }
422
+ direntry_t* entry1=array_get(&(s->directory),directory_start);
423
+ int j;
424
+
425
+ for(;entry1<entry;entry1++)
426
+ if(!is_long_name(entry1) && !memcmp(entry1->name,entry->name,11))
427
+ break; /* found dupe */
428
+ if(entry1==entry) /* no dupe found */
429
+ break;
430
+
431
+ /* use all 8 characters of name */
432
+ if(entry->name[7]==' ') {
433
+ int j;
434
+ for(j=6;j>0 && entry->name[j]==' ';j--)
435
+ entry->name[j]='~';
436
+ }
437
+
438
+ /* increment number */
439
+ for(j=7;j>0 && entry->name[j]=='9';j--)
440
+ entry->name[j]='0';
441
+ if(j>0) {
442
+ if(entry->name[j]<'0' || entry->name[j]>'9')
443
+ entry->name[j]='0';
444
+ else
445
+ entry->name[j]++;
446
+ }
447
}
448
449
/* calculate checksum; propagate to long name */
450
if(entry_long) {
451
uint8_t chksum=fat_chksum(entry);
452
453
-    /* calculate anew, because realloc could have taken place */
454
-    entry_long=array_get(&(s->directory),long_index);
455
-    while(entry_long<entry && is_long_name(entry_long)) {
456
-     entry_long->reserved[1]=chksum;
457
-     entry_long++;
458
-    }
459
+ /* calculate anew, because realloc could have taken place */
460
+ entry_long=array_get(&(s->directory),long_index);
461
+ while(entry_long<entry && is_long_name(entry_long)) {
462
+ entry_long->reserved[1]=chksum;
463
+ entry_long++;
464
+ }
465
}
466
467
return entry;
468
@@ -XXX,XX +XXX,XX @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
469
assert(mapping->mode & MODE_DIRECTORY);
470
471
if(!dir) {
472
-    mapping->end = mapping->begin;
473
-    return -1;
474
+ mapping->end = mapping->begin;
475
+ return -1;
476
}
477
478
i = mapping->info.dir.first_dir_index =
479
-     first_cluster == 0 ? 0 : s->directory.next;
480
+ first_cluster == 0 ? 0 : s->directory.next;
481
482
/* actually read the directory, and allocate the mappings */
483
while((entry=readdir(dir))) {
484
-    unsigned int length=strlen(dirname)+2+strlen(entry->d_name);
485
+ unsigned int length=strlen(dirname)+2+strlen(entry->d_name);
486
char* buffer;
487
-    direntry_t* direntry;
488
+ direntry_t* direntry;
489
struct stat st;
490
-    int is_dot=!strcmp(entry->d_name,".");
491
-    int is_dotdot=!strcmp(entry->d_name,"..");
492
+ int is_dot=!strcmp(entry->d_name,".");
493
+ int is_dotdot=!strcmp(entry->d_name,"..");
494
495
-    if(first_cluster == 0 && (is_dotdot || is_dot))
496
-     continue;
497
+ if(first_cluster == 0 && (is_dotdot || is_dot))
498
+ continue;
499
500
-    buffer = g_malloc(length);
501
-    snprintf(buffer,length,"%s/%s",dirname,entry->d_name);
502
+ buffer = g_malloc(length);
503
+ snprintf(buffer,length,"%s/%s",dirname,entry->d_name);
504
505
-    if(stat(buffer,&st)<0) {
506
+ if(stat(buffer,&st)<0) {
507
g_free(buffer);
508
continue;
509
-    }
510
-
511
-    /* create directory entry for this file */
512
-    direntry=create_short_and_long_name(s, i, entry->d_name,
513
-        is_dot || is_dotdot);
514
-    direntry->attributes=(S_ISDIR(st.st_mode)?0x10:0x20);
515
-    direntry->reserved[0]=direntry->reserved[1]=0;
516
-    direntry->ctime=fat_datetime(st.st_ctime,1);
517
-    direntry->cdate=fat_datetime(st.st_ctime,0);
518
-    direntry->adate=fat_datetime(st.st_atime,0);
519
-    direntry->begin_hi=0;
520
-    direntry->mtime=fat_datetime(st.st_mtime,1);
521
-    direntry->mdate=fat_datetime(st.st_mtime,0);
522
-    if(is_dotdot)
523
-     set_begin_of_direntry(direntry, first_cluster_of_parent);
524
-    else if(is_dot)
525
-     set_begin_of_direntry(direntry, first_cluster);
526
-    else
527
-     direntry->begin=0; /* do that later */
528
+ }
529
+
530
+ /* create directory entry for this file */
531
+ direntry=create_short_and_long_name(s, i, entry->d_name,
532
+ is_dot || is_dotdot);
533
+ direntry->attributes=(S_ISDIR(st.st_mode)?0x10:0x20);
534
+ direntry->reserved[0]=direntry->reserved[1]=0;
535
+ direntry->ctime=fat_datetime(st.st_ctime,1);
536
+ direntry->cdate=fat_datetime(st.st_ctime,0);
537
+ direntry->adate=fat_datetime(st.st_atime,0);
538
+ direntry->begin_hi=0;
539
+ direntry->mtime=fat_datetime(st.st_mtime,1);
540
+ direntry->mdate=fat_datetime(st.st_mtime,0);
541
+ if(is_dotdot)
542
+ set_begin_of_direntry(direntry, first_cluster_of_parent);
543
+ else if(is_dot)
544
+ set_begin_of_direntry(direntry, first_cluster);
545
+ else
546
+ direntry->begin=0; /* do that later */
547
if (st.st_size > 0x7fffffff) {
548
-     fprintf(stderr, "File %s is larger than 2GB\n", buffer);
549
+ fprintf(stderr, "File %s is larger than 2GB\n", buffer);
550
g_free(buffer);
551
closedir(dir);
552
-     return -2;
553
+ return -2;
554
}
555
-    direntry->size=cpu_to_le32(S_ISDIR(st.st_mode)?0:st.st_size);
556
-
557
-    /* create mapping for this file */
558
-    if(!is_dot && !is_dotdot && (S_ISDIR(st.st_mode) || st.st_size)) {
559
-     s->current_mapping = array_get_next(&(s->mapping));
560
-     s->current_mapping->begin=0;
561
-     s->current_mapping->end=st.st_size;
562
-     /*
563
-     * we get the direntry of the most recent direntry, which
564
-     * contains the short name and all the relevant information.
565
-     */
566
-     s->current_mapping->dir_index=s->directory.next-1;
567
-     s->current_mapping->first_mapping_index = -1;
568
-     if (S_ISDIR(st.st_mode)) {
569
-        s->current_mapping->mode = MODE_DIRECTORY;
570
-        s->current_mapping->info.dir.parent_mapping_index =
571
-         mapping_index;
572
-     } else {
573
-        s->current_mapping->mode = MODE_UNDEFINED;
574
-        s->current_mapping->info.file.offset = 0;
575
-     }
576
-     s->current_mapping->path=buffer;
577
-     s->current_mapping->read_only =
578
-        (st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)) == 0;
579
+ direntry->size=cpu_to_le32(S_ISDIR(st.st_mode)?0:st.st_size);
580
+
581
+ /* create mapping for this file */
582
+ if(!is_dot && !is_dotdot && (S_ISDIR(st.st_mode) || st.st_size)) {
583
+ s->current_mapping = array_get_next(&(s->mapping));
584
+ s->current_mapping->begin=0;
585
+ s->current_mapping->end=st.st_size;
586
+ /*
587
+ * we get the direntry of the most recent direntry, which
588
+ * contains the short name and all the relevant information.
589
+ */
590
+ s->current_mapping->dir_index=s->directory.next-1;
591
+ s->current_mapping->first_mapping_index = -1;
592
+ if (S_ISDIR(st.st_mode)) {
593
+ s->current_mapping->mode = MODE_DIRECTORY;
594
+ s->current_mapping->info.dir.parent_mapping_index =
595
+ mapping_index;
596
+ } else {
597
+ s->current_mapping->mode = MODE_UNDEFINED;
598
+ s->current_mapping->info.file.offset = 0;
599
+ }
600
+ s->current_mapping->path=buffer;
601
+ s->current_mapping->read_only =
602
+ (st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)) == 0;
603
} else {
604
g_free(buffer);
605
}
606
@@ -XXX,XX +XXX,XX @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
607
608
/* fill with zeroes up to the end of the cluster */
609
while(s->directory.next%(0x10*s->sectors_per_cluster)) {
610
-    direntry_t* direntry=array_get_next(&(s->directory));
611
-    memset(direntry,0,sizeof(direntry_t));
612
+ direntry_t* direntry=array_get_next(&(s->directory));
613
+ memset(direntry,0,sizeof(direntry_t));
614
}
615
616
/* TODO: if there are more entries, bootsector has to be adjusted! */
617
#define ROOT_ENTRIES (0x02 * 0x10 * s->sectors_per_cluster)
618
if (mapping_index == 0 && s->directory.next < ROOT_ENTRIES) {
619
-    /* root directory */
620
-    int cur = s->directory.next;
621
-    array_ensure_allocated(&(s->directory), ROOT_ENTRIES - 1);
622
-    s->directory.next = ROOT_ENTRIES;
623
-    memset(array_get(&(s->directory), cur), 0,
624
-        (ROOT_ENTRIES - cur) * sizeof(direntry_t));
625
+ /* root directory */
626
+ int cur = s->directory.next;
627
+ array_ensure_allocated(&(s->directory), ROOT_ENTRIES - 1);
628
+ s->directory.next = ROOT_ENTRIES;
629
+ memset(array_get(&(s->directory), cur), 0,
630
+ (ROOT_ENTRIES - cur) * sizeof(direntry_t));
631
}
632
633
/* reget the mapping, since s->mapping was possibly realloc()ed */
634
mapping = array_get(&(s->mapping), mapping_index);
635
first_cluster += (s->directory.next - mapping->info.dir.first_dir_index)
636
-    * 0x20 / s->cluster_size;
637
+ * 0x20 / s->cluster_size;
638
mapping->end = first_cluster;
639
640
direntry = array_get(&(s->directory), mapping->dir_index);
641
@@ -XXX,XX +XXX,XX @@ static int init_directories(BDRVVVFATState* s,
642
643
/* add volume label */
644
{
645
-    direntry_t* entry=array_get_next(&(s->directory));
646
-    entry->attributes=0x28; /* archive | volume label */
647
+ direntry_t* entry=array_get_next(&(s->directory));
648
+ entry->attributes=0x28; /* archive | volume label */
649
memcpy(entry->name, s->volume_label, sizeof(entry->name));
650
}
651
652
@@ -XXX,XX +XXX,XX @@ static int init_directories(BDRVVVFATState* s,
653
mapping->path = g_strdup(dirname);
654
i = strlen(mapping->path);
655
if (i > 0 && mapping->path[i - 1] == '/')
656
-    mapping->path[i - 1] = '\0';
657
+ mapping->path[i - 1] = '\0';
658
mapping->mode = MODE_DIRECTORY;
659
mapping->read_only = 0;
660
s->path = mapping->path;
661
662
for (i = 0, cluster = 0; i < s->mapping.next; i++) {
663
-    /* MS-DOS expects the FAT to be 0 for the root directory
664
-     * (except for the media byte). */
665
-    /* LATER TODO: still true for FAT32? */
666
-    int fix_fat = (i != 0);
667
-    mapping = array_get(&(s->mapping), i);
668
+ /* MS-DOS expects the FAT to be 0 for the root directory
669
+ * (except for the media byte). */
670
+ /* LATER TODO: still true for FAT32? */
671
+ int fix_fat = (i != 0);
672
+ mapping = array_get(&(s->mapping), i);
673
674
if (mapping->mode & MODE_DIRECTORY) {
675
-     mapping->begin = cluster;
676
-     if(read_directory(s, i)) {
677
+ mapping->begin = cluster;
678
+ if(read_directory(s, i)) {
679
error_setg(errp, "Could not read directory %s",
680
mapping->path);
681
-        return -1;
682
-     }
683
-     mapping = array_get(&(s->mapping), i);
684
-    } else {
685
-     assert(mapping->mode == MODE_UNDEFINED);
686
-     mapping->mode=MODE_NORMAL;
687
-     mapping->begin = cluster;
688
-     if (mapping->end > 0) {
689
-        direntry_t* direntry = array_get(&(s->directory),
690
-            mapping->dir_index);
691
-
692
-        mapping->end = cluster + 1 + (mapping->end-1)/s->cluster_size;
693
-        set_begin_of_direntry(direntry, mapping->begin);
694
-     } else {
695
-        mapping->end = cluster + 1;
696
-        fix_fat = 0;
697
-     }
698
-    }
699
-
700
-    assert(mapping->begin < mapping->end);
701
-
702
-    /* next free cluster */
703
-    cluster = mapping->end;
704
-
705
-    if(cluster > s->cluster_count) {
706
+ return -1;
707
+ }
708
+ mapping = array_get(&(s->mapping), i);
709
+ } else {
710
+ assert(mapping->mode == MODE_UNDEFINED);
711
+ mapping->mode=MODE_NORMAL;
712
+ mapping->begin = cluster;
713
+ if (mapping->end > 0) {
714
+ direntry_t* direntry = array_get(&(s->directory),
715
+ mapping->dir_index);
716
+
717
+ mapping->end = cluster + 1 + (mapping->end-1)/s->cluster_size;
718
+ set_begin_of_direntry(direntry, mapping->begin);
719
+ } else {
720
+ mapping->end = cluster + 1;
721
+ fix_fat = 0;
722
+ }
723
+ }
724
+
725
+ assert(mapping->begin < mapping->end);
726
+
727
+ /* next free cluster */
728
+ cluster = mapping->end;
729
+
730
+ if(cluster > s->cluster_count) {
731
error_setg(errp,
732
"Directory does not fit in FAT%d (capacity %.2f MB)",
733
s->fat_type, s->sector_count / 2000.0);
734
return -1;
735
-    }
736
+ }
737
738
-    /* fix fat for entry */
739
-    if (fix_fat) {
740
-     int j;
741
-     for(j = mapping->begin; j < mapping->end - 1; j++)
742
-        fat_set(s, j, j+1);
743
-     fat_set(s, mapping->end - 1, s->max_fat_value);
744
-    }
745
+ /* fix fat for entry */
746
+ if (fix_fat) {
747
+ int j;
748
+ for(j = mapping->begin; j < mapping->end - 1; j++)
749
+ fat_set(s, j, j+1);
750
+ fat_set(s, mapping->end - 1, s->max_fat_value);
751
+ }
752
}
753
754
mapping = array_get(&(s->mapping), 0);
755
@@ -XXX,XX +XXX,XX @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
756
757
switch (s->fat_type) {
758
case 32:
759
-     fprintf(stderr, "Big fat greek warning: FAT32 has not been tested. "
760
+ fprintf(stderr, "Big fat greek warning: FAT32 has not been tested. "
761
"You are welcome to do so!\n");
762
break;
763
case 16:
764
@@ -XXX,XX +XXX,XX @@ static void vvfat_refresh_limits(BlockDriverState *bs, Error **errp)
765
static inline void vvfat_close_current_file(BDRVVVFATState *s)
766
{
767
if(s->current_mapping) {
768
-    s->current_mapping = NULL;
769
-    if (s->current_fd) {
770
-        qemu_close(s->current_fd);
771
-        s->current_fd = 0;
772
-    }
773
+ s->current_mapping = NULL;
774
+ if (s->current_fd) {
775
+ qemu_close(s->current_fd);
776
+ s->current_fd = 0;
777
+ }
778
}
779
s->current_cluster = -1;
780
}
781
@@ -XXX,XX +XXX,XX @@ static inline int find_mapping_for_cluster_aux(BDRVVVFATState* s,int cluster_num
782
{
783
while(1) {
784
int index3;
785
-    mapping_t* mapping;
786
-    index3=(index1+index2)/2;
787
-    mapping=array_get(&(s->mapping),index3);
788
-    assert(mapping->begin < mapping->end);
789
-    if(mapping->begin>=cluster_num) {
790
-     assert(index2!=index3 || index2==0);
791
-     if(index2==index3)
792
-        return index1;
793
-     index2=index3;
794
-    } else {
795
-     if(index1==index3)
796
-        return mapping->end<=cluster_num ? index2 : index1;
797
-     index1=index3;
798
-    }
799
-    assert(index1<=index2);
800
-    DLOG(mapping=array_get(&(s->mapping),index1);
801
-    assert(mapping->begin<=cluster_num);
802
-    assert(index2 >= s->mapping.next ||
803
-        ((mapping = array_get(&(s->mapping),index2)) &&
804
-        mapping->end>cluster_num)));
805
+ mapping_t* mapping;
806
+ index3=(index1+index2)/2;
807
+ mapping=array_get(&(s->mapping),index3);
808
+ assert(mapping->begin < mapping->end);
809
+ if(mapping->begin>=cluster_num) {
810
+ assert(index2!=index3 || index2==0);
811
+ if(index2==index3)
812
+ return index1;
813
+ index2=index3;
814
+ } else {
815
+ if(index1==index3)
816
+ return mapping->end<=cluster_num ? index2 : index1;
817
+ index1=index3;
818
+ }
819
+ assert(index1<=index2);
820
+ DLOG(mapping=array_get(&(s->mapping),index1);
821
+ assert(mapping->begin<=cluster_num);
822
+ assert(index2 >= s->mapping.next ||
823
+ ((mapping = array_get(&(s->mapping),index2)) &&
824
+ mapping->end>cluster_num)));
825
}
826
}
827
828
@@ -XXX,XX +XXX,XX @@ static inline mapping_t* find_mapping_for_cluster(BDRVVVFATState* s,int cluster_
829
static int open_file(BDRVVVFATState* s,mapping_t* mapping)
830
{
831
if(!mapping)
832
-    return -1;
833
+ return -1;
834
if(!s->current_mapping ||
835
-     strcmp(s->current_mapping->path,mapping->path)) {
836
-    /* open file */
837
-    int fd = qemu_open(mapping->path, O_RDONLY | O_BINARY | O_LARGEFILE);
838
-    if(fd<0)
839
-     return -1;
840
-    vvfat_close_current_file(s);
841
-    s->current_fd = fd;
842
-    s->current_mapping = mapping;
843
+ strcmp(s->current_mapping->path,mapping->path)) {
844
+ /* open file */
845
+ int fd = qemu_open(mapping->path, O_RDONLY | O_BINARY | O_LARGEFILE);
846
+ if(fd<0)
847
+ return -1;
848
+ vvfat_close_current_file(s);
849
+ s->current_fd = fd;
850
+ s->current_mapping = mapping;
851
}
852
return 0;
853
}
854
@@ -XXX,XX +XXX,XX @@ static int open_file(BDRVVVFATState* s,mapping_t* mapping)
855
static inline int read_cluster(BDRVVVFATState *s,int cluster_num)
856
{
857
if(s->current_cluster != cluster_num) {
858
-    int result=0;
859
-    off_t offset;
860
-    assert(!s->current_mapping || s->current_fd || (s->current_mapping->mode & MODE_DIRECTORY));
861
-    if(!s->current_mapping
862
-        || s->current_mapping->begin>cluster_num
863
-        || s->current_mapping->end<=cluster_num) {
864
-     /* binary search of mappings for file */
865
-     mapping_t* mapping=find_mapping_for_cluster(s,cluster_num);
866
-
867
-     assert(!mapping || (cluster_num>=mapping->begin && cluster_num<mapping->end));
868
-
869
-     if (mapping && mapping->mode & MODE_DIRECTORY) {
870
-        vvfat_close_current_file(s);
871
-        s->current_mapping = mapping;
872
+ int result=0;
873
+ off_t offset;
874
+ assert(!s->current_mapping || s->current_fd || (s->current_mapping->mode & MODE_DIRECTORY));
875
+ if(!s->current_mapping
876
+ || s->current_mapping->begin>cluster_num
877
+ || s->current_mapping->end<=cluster_num) {
878
+ /* binary search of mappings for file */
879
+ mapping_t* mapping=find_mapping_for_cluster(s,cluster_num);
880
+
881
+ assert(!mapping || (cluster_num>=mapping->begin && cluster_num<mapping->end));
882
+
883
+ if (mapping && mapping->mode & MODE_DIRECTORY) {
884
+ vvfat_close_current_file(s);
885
+ s->current_mapping = mapping;
886
read_cluster_directory:
887
-        offset = s->cluster_size*(cluster_num-s->current_mapping->begin);
888
-        s->cluster = (unsigned char*)s->directory.pointer+offset
889
-            + 0x20*s->current_mapping->info.dir.first_dir_index;
890
-        assert(((s->cluster-(unsigned char*)s->directory.pointer)%s->cluster_size)==0);
891
-        assert((char*)s->cluster+s->cluster_size <= s->directory.pointer+s->directory.next*s->directory.item_size);
892
-        s->current_cluster = cluster_num;
893
-        return 0;
894
-     }
895
-
896
-     if(open_file(s,mapping))
897
-        return -2;
898
-    } else if (s->current_mapping->mode & MODE_DIRECTORY)
899
-     goto read_cluster_directory;
900
-
901
-    assert(s->current_fd);
902
-
903
-    offset=s->cluster_size*(cluster_num-s->current_mapping->begin)+s->current_mapping->info.file.offset;
904
-    if(lseek(s->current_fd, offset, SEEK_SET)!=offset)
905
-     return -3;
906
-    s->cluster=s->cluster_buffer;
907
-    result=read(s->current_fd,s->cluster,s->cluster_size);
908
-    if(result<0) {
909
-     s->current_cluster = -1;
910
-     return -1;
911
-    }
912
-    s->current_cluster = cluster_num;
913
+ offset = s->cluster_size*(cluster_num-s->current_mapping->begin);
914
+ s->cluster = (unsigned char*)s->directory.pointer+offset
915
+ + 0x20*s->current_mapping->info.dir.first_dir_index;
916
+ assert(((s->cluster-(unsigned char*)s->directory.pointer)%s->cluster_size)==0);
917
+ assert((char*)s->cluster+s->cluster_size <= s->directory.pointer+s->directory.next*s->directory.item_size);
918
+ s->current_cluster = cluster_num;
919
+ return 0;
920
+ }
921
+
922
+ if(open_file(s,mapping))
923
+ return -2;
924
+ } else if (s->current_mapping->mode & MODE_DIRECTORY)
925
+ goto read_cluster_directory;
926
+
927
+ assert(s->current_fd);
928
+
929
+ offset=s->cluster_size*(cluster_num-s->current_mapping->begin)+s->current_mapping->info.file.offset;
930
+ if(lseek(s->current_fd, offset, SEEK_SET)!=offset)
931
+ return -3;
932
+ s->cluster=s->cluster_buffer;
933
+ result=read(s->current_fd,s->cluster,s->cluster_size);
934
+ if(result<0) {
935
+ s->current_cluster = -1;
936
+ return -1;
937
+ }
938
+ s->current_cluster = cluster_num;
939
}
940
return 0;
941
}
942
@@ -XXX,XX +XXX,XX @@ static void print_direntry(const direntry_t* direntry)
943
944
fprintf(stderr, "direntry %p: ", direntry);
945
if(!direntry)
946
-    return;
947
+ return;
948
if(is_long_name(direntry)) {
949
-    unsigned char* c=(unsigned char*)direntry;
950
-    int i;
951
-    for(i=1;i<11 && c[i] && c[i]!=0xff;i+=2)
952
+ unsigned char* c=(unsigned char*)direntry;
953
+ int i;
954
+ for(i=1;i<11 && c[i] && c[i]!=0xff;i+=2)
955
#define ADD_CHAR(c) {buffer[j] = (c); if (buffer[j] < ' ') buffer[j] = 0xb0; j++;}
956
-     ADD_CHAR(c[i]);
957
-    for(i=14;i<26 && c[i] && c[i]!=0xff;i+=2)
958
-     ADD_CHAR(c[i]);
959
-    for(i=28;i<32 && c[i] && c[i]!=0xff;i+=2)
960
-     ADD_CHAR(c[i]);
961
-    buffer[j] = 0;
962
-    fprintf(stderr, "%s\n", buffer);
963
+ ADD_CHAR(c[i]);
964
+ for(i=14;i<26 && c[i] && c[i]!=0xff;i+=2)
965
+ ADD_CHAR(c[i]);
966
+ for(i=28;i<32 && c[i] && c[i]!=0xff;i+=2)
967
+ ADD_CHAR(c[i]);
968
+ buffer[j] = 0;
969
+ fprintf(stderr, "%s\n", buffer);
970
} else {
971
-    int i;
972
-    for(i=0;i<11;i++)
973
-     ADD_CHAR(direntry->name[i]);
974
-    buffer[j] = 0;
975
-    fprintf(stderr,"%s attributes=0x%02x begin=%d size=%d\n",
976
-        buffer,
977
-        direntry->attributes,
978
-        begin_of_direntry(direntry),le32_to_cpu(direntry->size));
979
+ int i;
980
+ for(i=0;i<11;i++)
981
+ ADD_CHAR(direntry->name[i]);
982
+ buffer[j] = 0;
983
+ fprintf(stderr,"%s attributes=0x%02x begin=%d size=%d\n",
984
+ buffer,
985
+ direntry->attributes,
986
+ begin_of_direntry(direntry),le32_to_cpu(direntry->size));
987
}
988
}
989
990
@@ -XXX,XX +XXX,XX @@ static void print_mapping(const mapping_t* mapping)
991
mapping->first_mapping_index, mapping->path, mapping->mode);
992
993
if (mapping->mode & MODE_DIRECTORY)
994
-    fprintf(stderr, "parent_mapping_index = %d, first_dir_index = %d\n", mapping->info.dir.parent_mapping_index, mapping->info.dir.first_dir_index);
995
+ fprintf(stderr, "parent_mapping_index = %d, first_dir_index = %d\n", mapping->info.dir.parent_mapping_index, mapping->info.dir.first_dir_index);
996
else
997
-    fprintf(stderr, "offset = %d\n", mapping->info.file.offset);
998
+ fprintf(stderr, "offset = %d\n", mapping->info.file.offset);
999
}
1000
#endif
1001
1002
@@ -XXX,XX +XXX,XX @@ static int vvfat_read(BlockDriverState *bs, int64_t sector_num,
1003
int i;
1004
1005
for(i=0;i<nb_sectors;i++,sector_num++) {
1006
-    if (sector_num >= bs->total_sectors)
1007
-     return -1;
1008
-    if (s->qcow) {
1009
-     int n;
1010
+ if (sector_num >= bs->total_sectors)
1011
+ return -1;
1012
+ if (s->qcow) {
1013
+ int n;
1014
int ret;
1015
ret = bdrv_is_allocated(s->qcow->bs, sector_num,
1016
nb_sectors - i, &n);
1017
@@ -XXX,XX +XXX,XX @@ static int vvfat_read(BlockDriverState *bs, int64_t sector_num,
1018
continue;
1019
}
1020
DLOG(fprintf(stderr, "sector %d not allocated\n", (int)sector_num));
1021
-    }
1022
-    if(sector_num<s->faked_sectors) {
1023
-     if(sector_num<s->first_sectors_number)
1024
-        memcpy(buf+i*0x200,&(s->first_sectors[sector_num*0x200]),0x200);
1025
-     else if(sector_num-s->first_sectors_number<s->sectors_per_fat)
1026
-        memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number)*0x200]),0x200);
1027
-     else if(sector_num-s->first_sectors_number-s->sectors_per_fat<s->sectors_per_fat)
1028
-        memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number-s->sectors_per_fat)*0x200]),0x200);
1029
-    } else {
1030
-     uint32_t sector=sector_num-s->faked_sectors,
1031
-     sector_offset_in_cluster=(sector%s->sectors_per_cluster),
1032
-     cluster_num=sector/s->sectors_per_cluster;
1033
-     if(cluster_num > s->cluster_count || read_cluster(s, cluster_num) != 0) {
1034
-        /* LATER TODO: strict: return -1; */
1035
-        memset(buf+i*0x200,0,0x200);
1036
-        continue;
1037
-     }
1038
-     memcpy(buf+i*0x200,s->cluster+sector_offset_in_cluster*0x200,0x200);
1039
-    }
1040
+ }
1041
+ if(sector_num<s->faked_sectors) {
1042
+ if(sector_num<s->first_sectors_number)
1043
+ memcpy(buf+i*0x200,&(s->first_sectors[sector_num*0x200]),0x200);
1044
+ else if(sector_num-s->first_sectors_number<s->sectors_per_fat)
1045
+ memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number)*0x200]),0x200);
1046
+ else if(sector_num-s->first_sectors_number-s->sectors_per_fat<s->sectors_per_fat)
1047
+ memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number-s->sectors_per_fat)*0x200]),0x200);
1048
+ } else {
1049
+ uint32_t sector=sector_num-s->faked_sectors,
1050
+ sector_offset_in_cluster=(sector%s->sectors_per_cluster),
1051
+ cluster_num=sector/s->sectors_per_cluster;
1052
+ if(cluster_num > s->cluster_count || read_cluster(s, cluster_num) != 0) {
1053
+ /* LATER TODO: strict: return -1; */
1054
+ memset(buf+i*0x200,0,0x200);
1055
+ continue;
1056
+ }
1057
+ memcpy(buf+i*0x200,s->cluster+sector_offset_in_cluster*0x200,0x200);
1058
+ }
1059
}
1060
return 0;
1061
}
1062
@@ -XXX,XX +XXX,XX @@ vvfat_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
1063
typedef struct commit_t {
1064
char* path;
1065
union {
1066
-    struct { uint32_t cluster; } rename;
1067
-    struct { int dir_index; uint32_t modified_offset; } writeout;
1068
-    struct { uint32_t first_cluster; } new_file;
1069
-    struct { uint32_t cluster; } mkdir;
1070
+ struct { uint32_t cluster; } rename;
1071
+ struct { int dir_index; uint32_t modified_offset; } writeout;
1072
+ struct { uint32_t first_cluster; } new_file;
1073
+ struct { uint32_t cluster; } mkdir;
1074
} param;
1075
/* DELETEs and RMDIRs are handled differently: see handle_deletes() */
1076
enum {
1077
-    ACTION_RENAME, ACTION_WRITEOUT, ACTION_NEW_FILE, ACTION_MKDIR
1078
+ ACTION_RENAME, ACTION_WRITEOUT, ACTION_NEW_FILE, ACTION_MKDIR
1079
} action;
1080
} commit_t;
1081
1082
@@ -XXX,XX +XXX,XX @@ static void clear_commits(BDRVVVFATState* s)
1083
int i;
1084
DLOG(fprintf(stderr, "clear_commits (%d commits)\n", s->commits.next));
1085
for (i = 0; i < s->commits.next; i++) {
1086
-    commit_t* commit = array_get(&(s->commits), i);
1087
-    assert(commit->path || commit->action == ACTION_WRITEOUT);
1088
-    if (commit->action != ACTION_WRITEOUT) {
1089
-     assert(commit->path);
1090
+ commit_t* commit = array_get(&(s->commits), i);
1091
+ assert(commit->path || commit->action == ACTION_WRITEOUT);
1092
+ if (commit->action != ACTION_WRITEOUT) {
1093
+ assert(commit->path);
1094
g_free(commit->path);
1095
-    } else
1096
-     assert(commit->path == NULL);
1097
+ } else
1098
+ assert(commit->path == NULL);
1099
}
1100
s->commits.next = 0;
1101
}
1102
1103
static void schedule_rename(BDRVVVFATState* s,
1104
-    uint32_t cluster, char* new_path)
1105
+ uint32_t cluster, char* new_path)
1106
{
1107
commit_t* commit = array_get_next(&(s->commits));
1108
commit->path = new_path;
1109
@@ -XXX,XX +XXX,XX @@ static void schedule_rename(BDRVVVFATState* s,
1110
}
1111
1112
static void schedule_writeout(BDRVVVFATState* s,
1113
-    int dir_index, uint32_t modified_offset)
1114
+ int dir_index, uint32_t modified_offset)
1115
{
1116
commit_t* commit = array_get_next(&(s->commits));
1117
commit->path = NULL;
1118
@@ -XXX,XX +XXX,XX @@ static void schedule_writeout(BDRVVVFATState* s,
1119
}
1120
1121
static void schedule_new_file(BDRVVVFATState* s,
1122
-    char* path, uint32_t first_cluster)
1123
+ char* path, uint32_t first_cluster)
1124
{
1125
commit_t* commit = array_get_next(&(s->commits));
1126
commit->path = path;
1127
@@ -XXX,XX +XXX,XX @@ static void lfn_init(long_file_name* lfn)
1128
1129
/* return 0 if parsed successfully, > 0 if no long name, < 0 if error */
1130
static int parse_long_name(long_file_name* lfn,
1131
-    const direntry_t* direntry)
1132
+ const direntry_t* direntry)
1133
{
1134
int i, j, offset;
1135
const unsigned char* pointer = (const unsigned char*)direntry;
1136
1137
if (!is_long_name(direntry))
1138
-    return 1;
1139
+ return 1;
1140
1141
if (pointer[0] & 0x40) {
1142
-    lfn->sequence_number = pointer[0] & 0x3f;
1143
-    lfn->checksum = pointer[13];
1144
-    lfn->name[0] = 0;
1145
-    lfn->name[lfn->sequence_number * 13] = 0;
1146
+ lfn->sequence_number = pointer[0] & 0x3f;
1147
+ lfn->checksum = pointer[13];
1148
+ lfn->name[0] = 0;
1149
+ lfn->name[lfn->sequence_number * 13] = 0;
1150
} else if ((pointer[0] & 0x3f) != --lfn->sequence_number)
1151
-    return -1;
1152
+ return -1;
1153
else if (pointer[13] != lfn->checksum)
1154
-    return -2;
1155
+ return -2;
1156
else if (pointer[12] || pointer[26] || pointer[27])
1157
-    return -3;
1158
+ return -3;
1159
1160
offset = 13 * (lfn->sequence_number - 1);
1161
for (i = 0, j = 1; i < 13; i++, j+=2) {
1162
-    if (j == 11)
1163
-     j = 14;
1164
-    else if (j == 26)
1165
-     j = 28;
1166
+ if (j == 11)
1167
+ j = 14;
1168
+ else if (j == 26)
1169
+ j = 28;
1170
1171
-    if (pointer[j+1] == 0)
1172
-     lfn->name[offset + i] = pointer[j];
1173
-    else if (pointer[j+1] != 0xff || (pointer[0] & 0x40) == 0)
1174
-     return -4;
1175
-    else
1176
-     lfn->name[offset + i] = 0;
1177
+ if (pointer[j+1] == 0)
1178
+ lfn->name[offset + i] = pointer[j];
1179
+ else if (pointer[j+1] != 0xff || (pointer[0] & 0x40) == 0)
1180
+ return -4;
1181
+ else
1182
+ lfn->name[offset + i] = 0;
1183
}
1184
1185
if (pointer[0] & 0x40)
1186
-    lfn->len = offset + strlen((char*)lfn->name + offset);
1187
+ lfn->len = offset + strlen((char*)lfn->name + offset);
1188
1189
return 0;
1190
}
1191
1192
/* returns 0 if successful, >0 if no short_name, and <0 on error */
1193
static int parse_short_name(BDRVVVFATState* s,
1194
-    long_file_name* lfn, direntry_t* direntry)
1195
+ long_file_name* lfn, direntry_t* direntry)
1196
{
1197
int i, j;
1198
1199
if (!is_short_name(direntry))
1200
-    return 1;
1201
+ return 1;
1202
1203
for (j = 7; j >= 0 && direntry->name[j] == ' '; j--);
1204
for (i = 0; i <= j; i++) {
1205
-    if (direntry->name[i] <= ' ' || direntry->name[i] > 0x7f)
1206
-     return -1;
1207
-    else if (s->downcase_short_names)
1208
-     lfn->name[i] = qemu_tolower(direntry->name[i]);
1209
-    else
1210
-     lfn->name[i] = direntry->name[i];
1211
+ if (direntry->name[i] <= ' ' || direntry->name[i] > 0x7f)
1212
+ return -1;
1213
+ else if (s->downcase_short_names)
1214
+ lfn->name[i] = qemu_tolower(direntry->name[i]);
1215
+ else
1216
+ lfn->name[i] = direntry->name[i];
1217
}
1218
1219
for (j = 2; j >= 0 && direntry->name[8 + j] == ' '; j--) {
1220
}
1221
if (j >= 0) {
1222
-    lfn->name[i++] = '.';
1223
-    lfn->name[i + j + 1] = '\0';
1224
-    for (;j >= 0; j--) {
1225
+ lfn->name[i++] = '.';
1226
+ lfn->name[i + j + 1] = '\0';
1227
+ for (;j >= 0; j--) {
1228
uint8_t c = direntry->name[8 + j];
1229
if (c <= ' ' || c > 0x7f) {
1230
return -2;
1231
@@ -XXX,XX +XXX,XX @@ static int parse_short_name(BDRVVVFATState* s,
1232
} else {
1233
lfn->name[i + j] = c;
1234
}
1235
-    }
1236
+ }
1237
} else
1238
-    lfn->name[i + j + 1] = '\0';
1239
+ lfn->name[i + j + 1] = '\0';
1240
1241
lfn->len = strlen((char*)lfn->name);
1242
1243
@@ -XXX,XX +XXX,XX @@ static int parse_short_name(BDRVVVFATState* s,
1244
}
1245
1246
static inline uint32_t modified_fat_get(BDRVVVFATState* s,
1247
-    unsigned int cluster)
1248
+ unsigned int cluster)
1249
{
1250
if (cluster < s->last_cluster_of_root_directory) {
1251
-    if (cluster + 1 == s->last_cluster_of_root_directory)
1252
-     return s->max_fat_value;
1253
-    else
1254
-     return cluster + 1;
1255
+ if (cluster + 1 == s->last_cluster_of_root_directory)
1256
+ return s->max_fat_value;
1257
+ else
1258
+ return cluster + 1;
1259
}
1260
1261
if (s->fat_type==32) {
1262
@@ -XXX,XX +XXX,XX @@ static const char* get_basename(const char* path)
1263
{
1264
char* basename = strrchr(path, '/');
1265
if (basename == NULL)
1266
-    return path;
1267
+ return path;
1268
else
1269
-    return basename + 1; /* strip '/' */
1270
+ return basename + 1; /* strip '/' */
1271
}
1272
1273
/*
1274
@@ -XXX,XX +XXX,XX @@ typedef enum {
1275
* assumed to be *not* deleted (and *only* those).
1276
*/
1277
static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s,
1278
-    direntry_t* direntry, const char* path)
1279
+ direntry_t* direntry, const char* path)
1280
{
1281
/*
1282
* This is a little bit tricky:
1283
@@ -XXX,XX +XXX,XX @@ static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s,
1284
1285
/* the root directory */
1286
if (cluster_num == 0)
1287
-    return 0;
1288
+ return 0;
1289
1290
/* write support */
1291
if (s->qcow) {
1292
-    basename2 = get_basename(path);
1293
+ basename2 = get_basename(path);
1294
1295
-    mapping = find_mapping_for_cluster(s, cluster_num);
1296
+ mapping = find_mapping_for_cluster(s, cluster_num);
1297
1298
-    if (mapping) {
1299
-     const char* basename;
1300
+ if (mapping) {
1301
+ const char* basename;
1302
1303
-     assert(mapping->mode & MODE_DELETED);
1304
-     mapping->mode &= ~MODE_DELETED;
1305
+ assert(mapping->mode & MODE_DELETED);
1306
+ mapping->mode &= ~MODE_DELETED;
1307
1308
-     basename = get_basename(mapping->path);
1309
+ basename = get_basename(mapping->path);
1310
1311
-     assert(mapping->mode & MODE_NORMAL);
1312
+ assert(mapping->mode & MODE_NORMAL);
1313
1314
-     /* rename */
1315
-     if (strcmp(basename, basename2))
1316
-        schedule_rename(s, cluster_num, g_strdup(path));
1317
-    } else if (is_file(direntry))
1318
-     /* new file */
1319
-     schedule_new_file(s, g_strdup(path), cluster_num);
1320
-    else {
1321
+ /* rename */
1322
+ if (strcmp(basename, basename2))
1323
+ schedule_rename(s, cluster_num, g_strdup(path));
1324
+ } else if (is_file(direntry))
1325
+ /* new file */
1326
+ schedule_new_file(s, g_strdup(path), cluster_num);
1327
+ else {
1328
abort();
1329
-     return 0;
1330
-    }
1331
+ return 0;
1332
+ }
1333
}
1334
1335
while(1) {
1336
-    if (s->qcow) {
1337
-     if (!copy_it && cluster_was_modified(s, cluster_num)) {
1338
-        if (mapping == NULL ||
1339
-            mapping->begin > cluster_num ||
1340
-            mapping->end <= cluster_num)
1341
-        mapping = find_mapping_for_cluster(s, cluster_num);
1342
+ if (s->qcow) {
1343
+ if (!copy_it && cluster_was_modified(s, cluster_num)) {
1344
+ if (mapping == NULL ||
1345
+ mapping->begin > cluster_num ||
1346
+ mapping->end <= cluster_num)
1347
+ mapping = find_mapping_for_cluster(s, cluster_num);
1348
1349
1350
-        if (mapping &&
1351
-            (mapping->mode & MODE_DIRECTORY) == 0) {
1352
+ if (mapping &&
1353
+ (mapping->mode & MODE_DIRECTORY) == 0) {
1354
1355
-         /* was modified in qcow */
1356
-         if (offset != mapping->info.file.offset + s->cluster_size
1357
-             * (cluster_num - mapping->begin)) {
1358
-            /* offset of this cluster in file chain has changed */
1359
+ /* was modified in qcow */
1360
+ if (offset != mapping->info.file.offset + s->cluster_size
1361
+ * (cluster_num - mapping->begin)) {
1362
+ /* offset of this cluster in file chain has changed */
1363
abort();
1364
-            copy_it = 1;
1365
-         } else if (offset == 0) {
1366
-            const char* basename = get_basename(mapping->path);
1367
+ copy_it = 1;
1368
+ } else if (offset == 0) {
1369
+ const char* basename = get_basename(mapping->path);
1370
1371
-            if (strcmp(basename, basename2))
1372
-             copy_it = 1;
1373
-            first_mapping_index = array_index(&(s->mapping), mapping);
1374
-         }
1375
+ if (strcmp(basename, basename2))
1376
+ copy_it = 1;
1377
+ first_mapping_index = array_index(&(s->mapping), mapping);
1378
+ }
1379
1380
-         if (mapping->first_mapping_index != first_mapping_index
1381
-             && mapping->info.file.offset > 0) {
1382
+ if (mapping->first_mapping_index != first_mapping_index
1383
+ && mapping->info.file.offset > 0) {
1384
abort();
1385
-            copy_it = 1;
1386
-         }
1387
-
1388
-         /* need to write out? */
1389
-         if (!was_modified && is_file(direntry)) {
1390
-            was_modified = 1;
1391
-            schedule_writeout(s, mapping->dir_index, offset);
1392
-         }
1393
-        }
1394
-     }
1395
-
1396
-     if (copy_it) {
1397
-        int i, dummy;
1398
-        /*
1399
-         * This is horribly inefficient, but that is okay, since
1400
-         * it is rarely executed, if at all.
1401
-         */
1402
-        int64_t offset = cluster2sector(s, cluster_num);
1403
-
1404
-        vvfat_close_current_file(s);
1405
+ copy_it = 1;
1406
+ }
1407
+
1408
+ /* need to write out? */
1409
+ if (!was_modified && is_file(direntry)) {
1410
+ was_modified = 1;
1411
+ schedule_writeout(s, mapping->dir_index, offset);
1412
+ }
1413
+ }
1414
+ }
1415
+
1416
+ if (copy_it) {
1417
+ int i, dummy;
1418
+ /*
1419
+ * This is horribly inefficient, but that is okay, since
1420
+ * it is rarely executed, if at all.
1421
+ */
1422
+ int64_t offset = cluster2sector(s, cluster_num);
1423
+
1424
+ vvfat_close_current_file(s);
1425
for (i = 0; i < s->sectors_per_cluster; i++) {
1426
int res;
1427
1428
@@ -XXX,XX +XXX,XX @@ static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s,
1429
}
1430
}
1431
}
1432
-     }
1433
-    }
1434
+ }
1435
+ }
1436
1437
-    ret++;
1438
-    if (s->used_clusters[cluster_num] & USED_ANY)
1439
-     return 0;
1440
-    s->used_clusters[cluster_num] = USED_FILE;
1441
+ ret++;
1442
+ if (s->used_clusters[cluster_num] & USED_ANY)
1443
+ return 0;
1444
+ s->used_clusters[cluster_num] = USED_FILE;
1445
1446
-    cluster_num = modified_fat_get(s, cluster_num);
1447
+ cluster_num = modified_fat_get(s, cluster_num);
1448
1449
-    if (fat_eof(s, cluster_num))
1450
-     return ret;
1451
-    else if (cluster_num < 2 || cluster_num > s->max_fat_value - 16)
1452
-     return -1;
1453
+ if (fat_eof(s, cluster_num))
1454
+ return ret;
1455
+ else if (cluster_num < 2 || cluster_num > s->max_fat_value - 16)
1456
+ return -1;
1457
1458
-    offset += s->cluster_size;
1459
+ offset += s->cluster_size;
1460
}
1461
}
1462
1463
@@ -XXX,XX +XXX,XX @@ static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s,
1464
* used by the directory, its subdirectories and their files.
1465
*/
1466
static int check_directory_consistency(BDRVVVFATState *s,
1467
-    int cluster_num, const char* path)
1468
+ int cluster_num, const char* path)
1469
{
1470
int ret = 0;
1471
unsigned char* cluster = g_malloc(s->cluster_size);
1472
@@ -XXX,XX +XXX,XX @@ static int check_directory_consistency(BDRVVVFATState *s,
1473
path2[path_len + 1] = '\0';
1474
1475
if (mapping) {
1476
-    const char* basename = get_basename(mapping->path);
1477
-    const char* basename2 = get_basename(path);
1478
+ const char* basename = get_basename(mapping->path);
1479
+ const char* basename2 = get_basename(path);
1480
1481
-    assert(mapping->mode & MODE_DIRECTORY);
1482
+ assert(mapping->mode & MODE_DIRECTORY);
1483
1484
-    assert(mapping->mode & MODE_DELETED);
1485
-    mapping->mode &= ~MODE_DELETED;
1486
+ assert(mapping->mode & MODE_DELETED);
1487
+ mapping->mode &= ~MODE_DELETED;
1488
1489
-    if (strcmp(basename, basename2))
1490
-     schedule_rename(s, cluster_num, g_strdup(path));
1491
+ if (strcmp(basename, basename2))
1492
+ schedule_rename(s, cluster_num, g_strdup(path));
1493
} else
1494
-    /* new directory */
1495
-    schedule_mkdir(s, cluster_num, g_strdup(path));
1496
+ /* new directory */
1497
+ schedule_mkdir(s, cluster_num, g_strdup(path));
1498
1499
lfn_init(&lfn);
1500
do {
1501
-    int i;
1502
-    int subret = 0;
1503
+ int i;
1504
+ int subret = 0;
1505
1506
-    ret++;
1507
+ ret++;
1508
1509
-    if (s->used_clusters[cluster_num] & USED_ANY) {
1510
-     fprintf(stderr, "cluster %d used more than once\n", (int)cluster_num);
1511
+ if (s->used_clusters[cluster_num] & USED_ANY) {
1512
+ fprintf(stderr, "cluster %d used more than once\n", (int)cluster_num);
1513
goto fail;
1514
-    }
1515
-    s->used_clusters[cluster_num] = USED_DIRECTORY;
1516
+ }
1517
+ s->used_clusters[cluster_num] = USED_DIRECTORY;
1518
1519
DLOG(fprintf(stderr, "read cluster %d (sector %d)\n", (int)cluster_num, (int)cluster2sector(s, cluster_num)));
1520
-    subret = vvfat_read(s->bs, cluster2sector(s, cluster_num), cluster,
1521
-        s->sectors_per_cluster);
1522
-    if (subret) {
1523
-     fprintf(stderr, "Error fetching direntries\n");
1524
-    fail:
1525
+ subret = vvfat_read(s->bs, cluster2sector(s, cluster_num), cluster,
1526
+ s->sectors_per_cluster);
1527
+ if (subret) {
1528
+ fprintf(stderr, "Error fetching direntries\n");
1529
+ fail:
1530
g_free(cluster);
1531
-     return 0;
1532
-    }
1533
+ return 0;
1534
+ }
1535
1536
-    for (i = 0; i < 0x10 * s->sectors_per_cluster; i++) {
1537
-     int cluster_count = 0;
1538
+ for (i = 0; i < 0x10 * s->sectors_per_cluster; i++) {
1539
+ int cluster_count = 0;
1540
1541
DLOG(fprintf(stderr, "check direntry %d:\n", i); print_direntry(direntries + i));
1542
-     if (is_volume_label(direntries + i) || is_dot(direntries + i) ||
1543
-         is_free(direntries + i))
1544
-        continue;
1545
-
1546
-     subret = parse_long_name(&lfn, direntries + i);
1547
-     if (subret < 0) {
1548
-        fprintf(stderr, "Error in long name\n");
1549
-        goto fail;
1550
-     }
1551
-     if (subret == 0 || is_free(direntries + i))
1552
-        continue;
1553
-
1554
-     if (fat_chksum(direntries+i) != lfn.checksum) {
1555
-        subret = parse_short_name(s, &lfn, direntries + i);
1556
-        if (subret < 0) {
1557
-         fprintf(stderr, "Error in short name (%d)\n", subret);
1558
-         goto fail;
1559
-        }
1560
-        if (subret > 0 || !strcmp((char*)lfn.name, ".")
1561
-            || !strcmp((char*)lfn.name, ".."))
1562
-         continue;
1563
-     }
1564
-     lfn.checksum = 0x100; /* cannot use long name twice */
1565
-
1566
-     if (path_len + 1 + lfn.len >= PATH_MAX) {
1567
-        fprintf(stderr, "Name too long: %s/%s\n", path, lfn.name);
1568
-        goto fail;
1569
-     }
1570
+ if (is_volume_label(direntries + i) || is_dot(direntries + i) ||
1571
+ is_free(direntries + i))
1572
+ continue;
1573
+
1574
+ subret = parse_long_name(&lfn, direntries + i);
1575
+ if (subret < 0) {
1576
+ fprintf(stderr, "Error in long name\n");
1577
+ goto fail;
1578
+ }
1579
+ if (subret == 0 || is_free(direntries + i))
1580
+ continue;
1581
+
1582
+ if (fat_chksum(direntries+i) != lfn.checksum) {
1583
+ subret = parse_short_name(s, &lfn, direntries + i);
1584
+ if (subret < 0) {
1585
+ fprintf(stderr, "Error in short name (%d)\n", subret);
1586
+ goto fail;
1587
+ }
1588
+ if (subret > 0 || !strcmp((char*)lfn.name, ".")
1589
+ || !strcmp((char*)lfn.name, ".."))
1590
+ continue;
1591
+ }
1592
+ lfn.checksum = 0x100; /* cannot use long name twice */
1593
+
1594
+ if (path_len + 1 + lfn.len >= PATH_MAX) {
1595
+ fprintf(stderr, "Name too long: %s/%s\n", path, lfn.name);
1596
+ goto fail;
1597
+ }
1598
pstrcpy(path2 + path_len + 1, sizeof(path2) - path_len - 1,
1599
(char*)lfn.name);
1600
1601
-     if (is_directory(direntries + i)) {
1602
-        if (begin_of_direntry(direntries + i) == 0) {
1603
-         DLOG(fprintf(stderr, "invalid begin for directory: %s\n", path2); print_direntry(direntries + i));
1604
-         goto fail;
1605
-        }
1606
-        cluster_count = check_directory_consistency(s,
1607
-            begin_of_direntry(direntries + i), path2);
1608
-        if (cluster_count == 0) {
1609
-         DLOG(fprintf(stderr, "problem in directory %s:\n", path2); print_direntry(direntries + i));
1610
-         goto fail;
1611
-        }
1612
-     } else if (is_file(direntries + i)) {
1613
-        /* check file size with FAT */
1614
-        cluster_count = get_cluster_count_for_direntry(s, direntries + i, path2);
1615
-        if (cluster_count !=
1616
+ if (is_directory(direntries + i)) {
1617
+ if (begin_of_direntry(direntries + i) == 0) {
1618
+ DLOG(fprintf(stderr, "invalid begin for directory: %s\n", path2); print_direntry(direntries + i));
1619
+ goto fail;
1620
+ }
1621
+ cluster_count = check_directory_consistency(s,
1622
+ begin_of_direntry(direntries + i), path2);
1623
+ if (cluster_count == 0) {
1624
+ DLOG(fprintf(stderr, "problem in directory %s:\n", path2); print_direntry(direntries + i));
1625
+ goto fail;
1626
+ }
1627
+ } else if (is_file(direntries + i)) {
1628
+ /* check file size with FAT */
1629
+ cluster_count = get_cluster_count_for_direntry(s, direntries + i, path2);
1630
+ if (cluster_count !=
1631
DIV_ROUND_UP(le32_to_cpu(direntries[i].size), s->cluster_size)) {
1632
-         DLOG(fprintf(stderr, "Cluster count mismatch\n"));
1633
-         goto fail;
1634
-        }
1635
-     } else
1636
+ DLOG(fprintf(stderr, "Cluster count mismatch\n"));
1637
+ goto fail;
1638
+ }
1639
+ } else
1640
abort(); /* cluster_count = 0; */
1641
1642
-     ret += cluster_count;
1643
-    }
1644
+ ret += cluster_count;
1645
+ }
1646
1647
-    cluster_num = modified_fat_get(s, cluster_num);
1648
+ cluster_num = modified_fat_get(s, cluster_num);
1649
} while(!fat_eof(s, cluster_num));
1650
1651
g_free(cluster);
1652
@@ -XXX,XX +XXX,XX @@ DLOG(checkpoint());
1653
* - if all is fine, return number of used clusters
1654
*/
1655
if (s->fat2 == NULL) {
1656
-    int size = 0x200 * s->sectors_per_fat;
1657
-    s->fat2 = g_malloc(size);
1658
-    memcpy(s->fat2, s->fat.pointer, size);
1659
+ int size = 0x200 * s->sectors_per_fat;
1660
+ s->fat2 = g_malloc(size);
1661
+ memcpy(s->fat2, s->fat.pointer, size);
1662
}
1663
check = vvfat_read(s->bs,
1664
-     s->first_sectors_number, s->fat2, s->sectors_per_fat);
1665
+ s->first_sectors_number, s->fat2, s->sectors_per_fat);
1666
if (check) {
1667
-    fprintf(stderr, "Could not copy fat\n");
1668
-    return 0;
1669
+ fprintf(stderr, "Could not copy fat\n");
1670
+ return 0;
1671
}
1672
assert (s->used_clusters);
1673
for (i = 0; i < sector2cluster(s, s->sector_count); i++)
1674
-    s->used_clusters[i] &= ~USED_ANY;
1675
+ s->used_clusters[i] &= ~USED_ANY;
1676
1677
clear_commits(s);
1678
1679
/* mark every mapped file/directory as deleted.
1680
* (check_directory_consistency() will unmark those still present). */
1681
if (s->qcow)
1682
-    for (i = 0; i < s->mapping.next; i++) {
1683
-     mapping_t* mapping = array_get(&(s->mapping), i);
1684
-     if (mapping->first_mapping_index < 0)
1685
-        mapping->mode |= MODE_DELETED;
1686
-    }
1687
+ for (i = 0; i < s->mapping.next; i++) {
1688
+ mapping_t* mapping = array_get(&(s->mapping), i);
1689
+ if (mapping->first_mapping_index < 0)
1690
+ mapping->mode |= MODE_DELETED;
1691
+ }
1692
1693
used_clusters_count = check_directory_consistency(s, 0, s->path);
1694
if (used_clusters_count <= 0) {
1695
-    DLOG(fprintf(stderr, "problem in directory\n"));
1696
-    return 0;
1697
+ DLOG(fprintf(stderr, "problem in directory\n"));
1698
+ return 0;
1699
}
1700
1701
check = s->last_cluster_of_root_directory;
1702
for (i = check; i < sector2cluster(s, s->sector_count); i++) {
1703
-    if (modified_fat_get(s, i)) {
1704
-     if(!s->used_clusters[i]) {
1705
-        DLOG(fprintf(stderr, "FAT was modified (%d), but cluster is not used?\n", i));
1706
-        return 0;
1707
-     }
1708
-     check++;
1709
-    }
1710
+ if (modified_fat_get(s, i)) {
1711
+ if(!s->used_clusters[i]) {
1712
+ DLOG(fprintf(stderr, "FAT was modified (%d), but cluster is not used?\n", i));
1713
+ return 0;
1714
+ }
1715
+ check++;
1716
+ }
1717
1718
-    if (s->used_clusters[i] == USED_ALLOCATED) {
1719
-     /* allocated, but not used... */
1720
-     DLOG(fprintf(stderr, "unused, modified cluster: %d\n", i));
1721
-     return 0;
1722
-    }
1723
+ if (s->used_clusters[i] == USED_ALLOCATED) {
1724
+ /* allocated, but not used... */
1725
+ DLOG(fprintf(stderr, "unused, modified cluster: %d\n", i));
1726
+ return 0;
1727
+ }
1728
}
1729
1730
if (check != used_clusters_count)
1731
-    return 0;
1732
+ return 0;
1733
1734
return used_clusters_count;
1735
}
1736
1737
static inline void adjust_mapping_indices(BDRVVVFATState* s,
1738
-    int offset, int adjust)
1739
+ int offset, int adjust)
1740
{
1741
int i;
1742
1743
for (i = 0; i < s->mapping.next; i++) {
1744
-    mapping_t* mapping = array_get(&(s->mapping), i);
1745
+ mapping_t* mapping = array_get(&(s->mapping), i);
1746
1747
#define ADJUST_MAPPING_INDEX(name) \
1748
-    if (mapping->name >= offset) \
1749
-     mapping->name += adjust
1750
+ if (mapping->name >= offset) \
1751
+ mapping->name += adjust
1752
1753
-    ADJUST_MAPPING_INDEX(first_mapping_index);
1754
-    if (mapping->mode & MODE_DIRECTORY)
1755
-     ADJUST_MAPPING_INDEX(info.dir.parent_mapping_index);
1756
+ ADJUST_MAPPING_INDEX(first_mapping_index);
1757
+ if (mapping->mode & MODE_DIRECTORY)
1758
+ ADJUST_MAPPING_INDEX(info.dir.parent_mapping_index);
1759
}
1760
}
1761
1762
/* insert or update mapping */
1763
static mapping_t* insert_mapping(BDRVVVFATState* s,
1764
-    uint32_t begin, uint32_t end)
1765
+ uint32_t begin, uint32_t end)
1766
{
1767
/*
1768
* - find mapping where mapping->begin >= begin,
1769
@@ -XXX,XX +XXX,XX @@ static mapping_t* insert_mapping(BDRVVVFATState* s,
1770
mapping_t* first_mapping = array_get(&(s->mapping), 0);
1771
1772
if (index < s->mapping.next && (mapping = array_get(&(s->mapping), index))
1773
-     && mapping->begin < begin) {
1774
-    mapping->end = begin;
1775
-    index++;
1776
-    mapping = array_get(&(s->mapping), index);
1777
+ && mapping->begin < begin) {
1778
+ mapping->end = begin;
1779
+ index++;
1780
+ mapping = array_get(&(s->mapping), index);
1781
}
1782
if (index >= s->mapping.next || mapping->begin > begin) {
1783
-    mapping = array_insert(&(s->mapping), index, 1);
1784
-    mapping->path = NULL;
1785
-    adjust_mapping_indices(s, index, +1);
1786
+ mapping = array_insert(&(s->mapping), index, 1);
1787
+ mapping->path = NULL;
1788
+ adjust_mapping_indices(s, index, +1);
1789
}
1790
1791
mapping->begin = begin;
1792
@@ -XXX,XX +XXX,XX @@ assert(index + 1 >= s->mapping.next ||
1793
next_mapping->begin >= end)));
1794
1795
if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer)
1796
-    s->current_mapping = array_get(&(s->mapping),
1797
-        s->current_mapping - first_mapping);
1798
+ s->current_mapping = array_get(&(s->mapping),
1799
+ s->current_mapping - first_mapping);
1800
1801
return mapping;
1802
}
1803
@@ -XXX,XX +XXX,XX @@ static int remove_mapping(BDRVVVFATState* s, int mapping_index)
1804
adjust_mapping_indices(s, mapping_index, -1);
1805
1806
if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer)
1807
-    s->current_mapping = array_get(&(s->mapping),
1808
-        s->current_mapping - first_mapping);
1809
+ s->current_mapping = array_get(&(s->mapping),
1810
+ s->current_mapping - first_mapping);
1811
1812
return 0;
1813
}
1814
@@ -XXX,XX +XXX,XX @@ static void adjust_dirindices(BDRVVVFATState* s, int offset, int adjust)
1815
{
1816
int i;
1817
for (i = 0; i < s->mapping.next; i++) {
1818
-    mapping_t* mapping = array_get(&(s->mapping), i);
1819
-    if (mapping->dir_index >= offset)
1820
-     mapping->dir_index += adjust;
1821
-    if ((mapping->mode & MODE_DIRECTORY) &&
1822
-        mapping->info.dir.first_dir_index >= offset)
1823
-     mapping->info.dir.first_dir_index += adjust;
1824
+ mapping_t* mapping = array_get(&(s->mapping), i);
1825
+ if (mapping->dir_index >= offset)
1826
+ mapping->dir_index += adjust;
1827
+ if ((mapping->mode & MODE_DIRECTORY) &&
1828
+ mapping->info.dir.first_dir_index >= offset)
1829
+ mapping->info.dir.first_dir_index += adjust;
1830
}
1831
}
1832
1833
static direntry_t* insert_direntries(BDRVVVFATState* s,
1834
-    int dir_index, int count)
1835
+ int dir_index, int count)
1836
{
1837
/*
1838
* make room in s->directory,
1839
@@ -XXX,XX +XXX,XX @@ static direntry_t* insert_direntries(BDRVVVFATState* s,
1840
*/
1841
direntry_t* result = array_insert(&(s->directory), dir_index, count);
1842
if (result == NULL)
1843
-    return NULL;
1844
+ return NULL;
1845
adjust_dirindices(s, dir_index, count);
1846
return result;
1847
}
1848
@@ -XXX,XX +XXX,XX @@ static int remove_direntries(BDRVVVFATState* s, int dir_index, int count)
1849
{
1850
int ret = array_remove_slice(&(s->directory), dir_index, count);
1851
if (ret)
1852
-    return ret;
1853
+ return ret;
1854
adjust_dirindices(s, dir_index, -count);
1855
return 0;
1856
}
1857
@@ -XXX,XX +XXX,XX @@ static int remove_direntries(BDRVVVFATState* s, int dir_index, int count)
1858
* adjusted)
1859
*/
1860
static int commit_mappings(BDRVVVFATState* s,
1861
-    uint32_t first_cluster, int dir_index)
1862
+ uint32_t first_cluster, int dir_index)
1863
{
1864
mapping_t* mapping = find_mapping_for_cluster(s, first_cluster);
1865
direntry_t* direntry = array_get(&(s->directory), dir_index);
1866
@@ -XXX,XX +XXX,XX @@ static int commit_mappings(BDRVVVFATState* s,
1867
mapping->first_mapping_index = -1;
1868
mapping->dir_index = dir_index;
1869
mapping->mode = (dir_index <= 0 || is_directory(direntry)) ?
1870
-    MODE_DIRECTORY : MODE_NORMAL;
1871
+ MODE_DIRECTORY : MODE_NORMAL;
1872
1873
while (!fat_eof(s, cluster)) {
1874
-    uint32_t c, c1;
1875
-
1876
-    for (c = cluster, c1 = modified_fat_get(s, c); c + 1 == c1;
1877
-        c = c1, c1 = modified_fat_get(s, c1));
1878
-
1879
-    c++;
1880
-    if (c > mapping->end) {
1881
-     int index = array_index(&(s->mapping), mapping);
1882
-     int i, max_i = s->mapping.next - index;
1883
-     for (i = 1; i < max_i && mapping[i].begin < c; i++);
1884
-     while (--i > 0)
1885
-        remove_mapping(s, index + 1);
1886
-    }
1887
-    assert(mapping == array_get(&(s->mapping), s->mapping.next - 1)
1888
-        || mapping[1].begin >= c);
1889
-    mapping->end = c;
1890
-
1891
-    if (!fat_eof(s, c1)) {
1892
-     int i = find_mapping_for_cluster_aux(s, c1, 0, s->mapping.next);
1893
-     mapping_t* next_mapping = i >= s->mapping.next ? NULL :
1894
-        array_get(&(s->mapping), i);
1895
-
1896
-     if (next_mapping == NULL || next_mapping->begin > c1) {
1897
-        int i1 = array_index(&(s->mapping), mapping);
1898
-
1899
-        next_mapping = insert_mapping(s, c1, c1+1);
1900
-
1901
-        if (c1 < c)
1902
-         i1++;
1903
-        mapping = array_get(&(s->mapping), i1);
1904
-     }
1905
-
1906
-     next_mapping->dir_index = mapping->dir_index;
1907
-     next_mapping->first_mapping_index =
1908
-        mapping->first_mapping_index < 0 ?
1909
-        array_index(&(s->mapping), mapping) :
1910
-        mapping->first_mapping_index;
1911
-     next_mapping->path = mapping->path;
1912
-     next_mapping->mode = mapping->mode;
1913
-     next_mapping->read_only = mapping->read_only;
1914
-     if (mapping->mode & MODE_DIRECTORY) {
1915
-        next_mapping->info.dir.parent_mapping_index =
1916
-            mapping->info.dir.parent_mapping_index;
1917
-        next_mapping->info.dir.first_dir_index =
1918
-            mapping->info.dir.first_dir_index +
1919
-            0x10 * s->sectors_per_cluster *
1920
-            (mapping->end - mapping->begin);
1921
-     } else
1922
-        next_mapping->info.file.offset = mapping->info.file.offset +
1923
-            mapping->end - mapping->begin;
1924
-
1925
-     mapping = next_mapping;
1926
-    }
1927
-
1928
-    cluster = c1;
1929
+ uint32_t c, c1;
1930
+
1931
+ for (c = cluster, c1 = modified_fat_get(s, c); c + 1 == c1;
1932
+ c = c1, c1 = modified_fat_get(s, c1));
1933
+
1934
+ c++;
1935
+ if (c > mapping->end) {
1936
+ int index = array_index(&(s->mapping), mapping);
1937
+ int i, max_i = s->mapping.next - index;
1938
+ for (i = 1; i < max_i && mapping[i].begin < c; i++);
1939
+ while (--i > 0)
1940
+ remove_mapping(s, index + 1);
1941
+ }
1942
+ assert(mapping == array_get(&(s->mapping), s->mapping.next - 1)
1943
+ || mapping[1].begin >= c);
1944
+ mapping->end = c;
1945
+
1946
+ if (!fat_eof(s, c1)) {
1947
+ int i = find_mapping_for_cluster_aux(s, c1, 0, s->mapping.next);
1948
+ mapping_t* next_mapping = i >= s->mapping.next ? NULL :
1949
+ array_get(&(s->mapping), i);
1950
+
1951
+ if (next_mapping == NULL || next_mapping->begin > c1) {
1952
+ int i1 = array_index(&(s->mapping), mapping);
1953
+
1954
+ next_mapping = insert_mapping(s, c1, c1+1);
1955
+
1956
+ if (c1 < c)
1957
+ i1++;
1958
+ mapping = array_get(&(s->mapping), i1);
1959
+ }
1960
+
1961
+ next_mapping->dir_index = mapping->dir_index;
1962
+ next_mapping->first_mapping_index =
1963
+ mapping->first_mapping_index < 0 ?
1964
+ array_index(&(s->mapping), mapping) :
1965
+ mapping->first_mapping_index;
1966
+ next_mapping->path = mapping->path;
1967
+ next_mapping->mode = mapping->mode;
1968
+ next_mapping->read_only = mapping->read_only;
1969
+ if (mapping->mode & MODE_DIRECTORY) {
1970
+ next_mapping->info.dir.parent_mapping_index =
1971
+ mapping->info.dir.parent_mapping_index;
1972
+ next_mapping->info.dir.first_dir_index =
1973
+ mapping->info.dir.first_dir_index +
1974
+ 0x10 * s->sectors_per_cluster *
1975
+ (mapping->end - mapping->begin);
1976
+ } else
1977
+ next_mapping->info.file.offset = mapping->info.file.offset +
1978
+ mapping->end - mapping->begin;
1979
+
1980
+ mapping = next_mapping;
1981
+ }
1982
+
1983
+ cluster = c1;
1984
}
1985
1986
return 0;
1987
}
1988
1989
static int commit_direntries(BDRVVVFATState* s,
1990
-    int dir_index, int parent_mapping_index)
1991
+ int dir_index, int parent_mapping_index)
1992
{
1993
direntry_t* direntry = array_get(&(s->directory), dir_index);
1994
uint32_t first_cluster = dir_index == 0 ? 0 : begin_of_direntry(direntry);
1995
@@ -XXX,XX +XXX,XX @@ DLOG(fprintf(stderr, "commit_direntries for %s, parent_mapping_index %d\n", mapp
1996
mapping->info.dir.parent_mapping_index = parent_mapping_index;
1997
1998
if (first_cluster == 0) {
1999
-    old_cluster_count = new_cluster_count =
2000
-     s->last_cluster_of_root_directory;
2001
+ old_cluster_count = new_cluster_count =
2002
+ s->last_cluster_of_root_directory;
2003
} else {
2004
-    for (old_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
2005
-        c = fat_get(s, c))
2006
-     old_cluster_count++;
2007
+ for (old_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
2008
+ c = fat_get(s, c))
2009
+ old_cluster_count++;
2010
2011
-    for (new_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
2012
-        c = modified_fat_get(s, c))
2013
-     new_cluster_count++;
2014
+ for (new_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
2015
+ c = modified_fat_get(s, c))
2016
+ new_cluster_count++;
2017
}
2018
2019
if (new_cluster_count > old_cluster_count) {
2020
-    if (insert_direntries(s,
2021
-        current_dir_index + factor * old_cluster_count,
2022
-        factor * (new_cluster_count - old_cluster_count)) == NULL)
2023
-     return -1;
2024
+ if (insert_direntries(s,
2025
+ current_dir_index + factor * old_cluster_count,
2026
+ factor * (new_cluster_count - old_cluster_count)) == NULL)
2027
+ return -1;
2028
} else if (new_cluster_count < old_cluster_count)
2029
-    remove_direntries(s,
2030
-        current_dir_index + factor * new_cluster_count,
2031
-        factor * (old_cluster_count - new_cluster_count));
2032
+ remove_direntries(s,
2033
+ current_dir_index + factor * new_cluster_count,
2034
+ factor * (old_cluster_count - new_cluster_count));
2035
2036
for (c = first_cluster; !fat_eof(s, c); c = modified_fat_get(s, c)) {
2037
direntry_t *first_direntry;
2038
-    void* direntry = array_get(&(s->directory), current_dir_index);
2039
-    int ret = vvfat_read(s->bs, cluster2sector(s, c), direntry,
2040
-        s->sectors_per_cluster);
2041
-    if (ret)
2042
-     return ret;
2043
+ void* direntry = array_get(&(s->directory), current_dir_index);
2044
+ int ret = vvfat_read(s->bs, cluster2sector(s, c), direntry,
2045
+ s->sectors_per_cluster);
2046
+ if (ret)
2047
+ return ret;
2048
2049
/* The first directory entry on the filesystem is the volume name */
2050
first_direntry = (direntry_t*) s->directory.pointer;
2051
assert(!memcmp(first_direntry->name, s->volume_label, 11));
2052
2053
-    current_dir_index += factor;
2054
+ current_dir_index += factor;
2055
}
2056
2057
ret = commit_mappings(s, first_cluster, dir_index);
2058
if (ret)
2059
-    return ret;
2060
+ return ret;
2061
2062
/* recurse */
2063
for (i = 0; i < factor * new_cluster_count; i++) {
2064
-    direntry = array_get(&(s->directory), first_dir_index + i);
2065
-    if (is_directory(direntry) && !is_dot(direntry)) {
2066
-     mapping = find_mapping_for_cluster(s, first_cluster);
2067
-     assert(mapping->mode & MODE_DIRECTORY);
2068
-     ret = commit_direntries(s, first_dir_index + i,
2069
-        array_index(&(s->mapping), mapping));
2070
-     if (ret)
2071
-        return ret;
2072
-    }
2073
+ direntry = array_get(&(s->directory), first_dir_index + i);
2074
+ if (is_directory(direntry) && !is_dot(direntry)) {
2075
+ mapping = find_mapping_for_cluster(s, first_cluster);
2076
+ assert(mapping->mode & MODE_DIRECTORY);
2077
+ ret = commit_direntries(s, first_dir_index + i,
2078
+ array_index(&(s->mapping), mapping));
2079
+ if (ret)
2080
+ return ret;
2081
+ }
2082
}
2083
2084
return 0;
2085
@@ -XXX,XX +XXX,XX @@ DLOG(fprintf(stderr, "commit_direntries for %s, parent_mapping_index %d\n", mapp
2086
/* commit one file (adjust contents, adjust mapping),
2087
return first_mapping_index */
2088
static int commit_one_file(BDRVVVFATState* s,
2089
-    int dir_index, uint32_t offset)
2090
+ int dir_index, uint32_t offset)
2091
{
2092
direntry_t* direntry = array_get(&(s->directory), dir_index);
2093
uint32_t c = begin_of_direntry(direntry);
2094
@@ -XXX,XX +XXX,XX @@ static int commit_one_file(BDRVVVFATState* s,
2095
assert((offset % s->cluster_size) == 0);
2096
2097
for (i = s->cluster_size; i < offset; i += s->cluster_size)
2098
-    c = modified_fat_get(s, c);
2099
+ c = modified_fat_get(s, c);
2100
2101
fd = qemu_open(mapping->path, O_RDWR | O_CREAT | O_BINARY, 0666);
2102
if (fd < 0) {
2103
-    fprintf(stderr, "Could not open %s... (%s, %d)\n", mapping->path,
2104
-        strerror(errno), errno);
2105
+ fprintf(stderr, "Could not open %s... (%s, %d)\n", mapping->path,
2106
+ strerror(errno), errno);
2107
g_free(cluster);
2108
-    return fd;
2109
+ return fd;
2110
}
2111
if (offset > 0) {
2112
if (lseek(fd, offset, SEEK_SET) != offset) {
2113
@@ -XXX,XX +XXX,XX @@ static int commit_one_file(BDRVVVFATState* s,
2114
}
2115
2116
while (offset < size) {
2117
-    uint32_t c1;
2118
-    int rest_size = (size - offset > s->cluster_size ?
2119
-        s->cluster_size : size - offset);
2120
-    int ret;
2121
+ uint32_t c1;
2122
+ int rest_size = (size - offset > s->cluster_size ?
2123
+ s->cluster_size : size - offset);
2124
+ int ret;
2125
2126
-    c1 = modified_fat_get(s, c);
2127
+ c1 = modified_fat_get(s, c);
2128
2129
-    assert((size - offset == 0 && fat_eof(s, c)) ||
2130
-        (size > offset && c >=2 && !fat_eof(s, c)));
2131
+ assert((size - offset == 0 && fat_eof(s, c)) ||
2132
+ (size > offset && c >=2 && !fat_eof(s, c)));
2133
2134
-    ret = vvfat_read(s->bs, cluster2sector(s, c),
2135
-     (uint8_t*)cluster, (rest_size + 0x1ff) / 0x200);
2136
+ ret = vvfat_read(s->bs, cluster2sector(s, c),
2137
+ (uint8_t*)cluster, (rest_size + 0x1ff) / 0x200);
2138
2139
if (ret < 0) {
2140
qemu_close(fd);
2141
@@ -XXX,XX +XXX,XX @@ static int commit_one_file(BDRVVVFATState* s,
2142
return -2;
2143
}
2144
2145
-    offset += rest_size;
2146
-    c = c1;
2147
+ offset += rest_size;
2148
+ c = c1;
2149
}
2150
2151
if (ftruncate(fd, size)) {
2152
@@ -XXX,XX +XXX,XX @@ static void check1(BDRVVVFATState* s)
2153
{
2154
int i;
2155
for (i = 0; i < s->mapping.next; i++) {
2156
-    mapping_t* mapping = array_get(&(s->mapping), i);
2157
-    if (mapping->mode & MODE_DELETED) {
2158
-     fprintf(stderr, "deleted\n");
2159
-     continue;
2160
-    }
2161
-    assert(mapping->dir_index < s->directory.next);
2162
-    direntry_t* direntry = array_get(&(s->directory), mapping->dir_index);
2163
-    assert(mapping->begin == begin_of_direntry(direntry) || mapping->first_mapping_index >= 0);
2164
-    if (mapping->mode & MODE_DIRECTORY) {
2165
-     assert(mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster * (mapping->end - mapping->begin) <= s->directory.next);
2166
-     assert((mapping->info.dir.first_dir_index % (0x10 * s->sectors_per_cluster)) == 0);
2167
-    }
2168
+ mapping_t* mapping = array_get(&(s->mapping), i);
2169
+ if (mapping->mode & MODE_DELETED) {
2170
+ fprintf(stderr, "deleted\n");
2171
+ continue;
2172
+ }
2173
+ assert(mapping->dir_index < s->directory.next);
2174
+ direntry_t* direntry = array_get(&(s->directory), mapping->dir_index);
2175
+ assert(mapping->begin == begin_of_direntry(direntry) || mapping->first_mapping_index >= 0);
2176
+ if (mapping->mode & MODE_DIRECTORY) {
2177
+ assert(mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster * (mapping->end - mapping->begin) <= s->directory.next);
2178
+ assert((mapping->info.dir.first_dir_index % (0x10 * s->sectors_per_cluster)) == 0);
2179
+ }
2180
}
2181
}
2182
2183
@@ -XXX,XX +XXX,XX @@ static void check2(BDRVVVFATState* s)
2184
int first_mapping = -1;
2185
2186
for (i = 0; i < s->directory.next; i++) {
2187
-    direntry_t* direntry = array_get(&(s->directory), i);
2188
-
2189
-    if (is_short_name(direntry) && begin_of_direntry(direntry)) {
2190
-     mapping_t* mapping = find_mapping_for_cluster(s, begin_of_direntry(direntry));
2191
-     assert(mapping);
2192
-     assert(mapping->dir_index == i || is_dot(direntry));
2193
-     assert(mapping->begin == begin_of_direntry(direntry) || is_dot(direntry));
2194
-    }
2195
-
2196
-    if ((i % (0x10 * s->sectors_per_cluster)) == 0) {
2197
-     /* cluster start */
2198
-     int j, count = 0;
2199
-
2200
-     for (j = 0; j < s->mapping.next; j++) {
2201
-        mapping_t* mapping = array_get(&(s->mapping), j);
2202
-        if (mapping->mode & MODE_DELETED)
2203
-         continue;
2204
-        if (mapping->mode & MODE_DIRECTORY) {
2205
-         if (mapping->info.dir.first_dir_index <= i && mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster > i) {
2206
-            assert(++count == 1);
2207
-            if (mapping->first_mapping_index == -1)
2208
-             first_mapping = array_index(&(s->mapping), mapping);
2209
-            else
2210
-             assert(first_mapping == mapping->first_mapping_index);
2211
-            if (mapping->info.dir.parent_mapping_index < 0)
2212
-             assert(j == 0);
2213
-            else {
2214
-             mapping_t* parent = array_get(&(s->mapping), mapping->info.dir.parent_mapping_index);
2215
-             assert(parent->mode & MODE_DIRECTORY);
2216
-             assert(parent->info.dir.first_dir_index < mapping->info.dir.first_dir_index);
2217
-            }
2218
-         }
2219
-        }
2220
-     }
2221
-     if (count == 0)
2222
-        first_mapping = -1;
2223
-    }
2224
+ direntry_t* direntry = array_get(&(s->directory), i);
2225
+
2226
+ if (is_short_name(direntry) && begin_of_direntry(direntry)) {
2227
+ mapping_t* mapping = find_mapping_for_cluster(s, begin_of_direntry(direntry));
2228
+ assert(mapping);
2229
+ assert(mapping->dir_index == i || is_dot(direntry));
2230
+ assert(mapping->begin == begin_of_direntry(direntry) || is_dot(direntry));
2231
+ }
2232
+
2233
+ if ((i % (0x10 * s->sectors_per_cluster)) == 0) {
2234
+ /* cluster start */
2235
+ int j, count = 0;
2236
+
2237
+ for (j = 0; j < s->mapping.next; j++) {
2238
+ mapping_t* mapping = array_get(&(s->mapping), j);
2239
+ if (mapping->mode & MODE_DELETED)
2240
+ continue;
2241
+ if (mapping->mode & MODE_DIRECTORY) {
2242
+ if (mapping->info.dir.first_dir_index <= i && mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster > i) {
2243
+ assert(++count == 1);
2244
+ if (mapping->first_mapping_index == -1)
2245
+ first_mapping = array_index(&(s->mapping), mapping);
2246
+ else
2247
+ assert(first_mapping == mapping->first_mapping_index);
2248
+ if (mapping->info.dir.parent_mapping_index < 0)
2249
+ assert(j == 0);
2250
+ else {
2251
+ mapping_t* parent = array_get(&(s->mapping), mapping->info.dir.parent_mapping_index);
2252
+ assert(parent->mode & MODE_DIRECTORY);
2253
+ assert(parent->info.dir.first_dir_index < mapping->info.dir.first_dir_index);
2254
+ }
2255
+ }
2256
+ }
2257
+ }
2258
+ if (count == 0)
2259
+ first_mapping = -1;
2260
+ }
2261
}
2262
}
2263
#endif
2264
@@ -XXX,XX +XXX,XX @@ static int handle_renames_and_mkdirs(BDRVVVFATState* s)
2265
#ifdef DEBUG
2266
fprintf(stderr, "handle_renames\n");
2267
for (i = 0; i < s->commits.next; i++) {
2268
-    commit_t* commit = array_get(&(s->commits), i);
2269
-    fprintf(stderr, "%d, %s (%d, %d)\n", i, commit->path ? commit->path : "(null)", commit->param.rename.cluster, commit->action);
2270
+ commit_t* commit = array_get(&(s->commits), i);
2271
+ fprintf(stderr, "%d, %s (%d, %d)\n", i, commit->path ? commit->path : "(null)", commit->param.rename.cluster, commit->action);
2272
}
2273
#endif
2274
2275
for (i = 0; i < s->commits.next;) {
2276
-    commit_t* commit = array_get(&(s->commits), i);
2277
-    if (commit->action == ACTION_RENAME) {
2278
-     mapping_t* mapping = find_mapping_for_cluster(s,
2279
-         commit->param.rename.cluster);
2280
-     char* old_path = mapping->path;
2281
-
2282
-     assert(commit->path);
2283
-     mapping->path = commit->path;
2284
-     if (rename(old_path, mapping->path))
2285
-        return -2;
2286
-
2287
-     if (mapping->mode & MODE_DIRECTORY) {
2288
-        int l1 = strlen(mapping->path);
2289
-        int l2 = strlen(old_path);
2290
-        int diff = l1 - l2;
2291
-        direntry_t* direntry = array_get(&(s->directory),
2292
-            mapping->info.dir.first_dir_index);
2293
-        uint32_t c = mapping->begin;
2294
-        int i = 0;
2295
-
2296
-        /* recurse */
2297
-        while (!fat_eof(s, c)) {
2298
-         do {
2299
-            direntry_t* d = direntry + i;
2300
-
2301
-            if (is_file(d) || (is_directory(d) && !is_dot(d))) {
2302
-             mapping_t* m = find_mapping_for_cluster(s,
2303
-                 begin_of_direntry(d));
2304
-             int l = strlen(m->path);
2305
-             char* new_path = g_malloc(l + diff + 1);
2306
-
2307
-             assert(!strncmp(m->path, mapping->path, l2));
2308
+ commit_t* commit = array_get(&(s->commits), i);
2309
+ if (commit->action == ACTION_RENAME) {
2310
+ mapping_t* mapping = find_mapping_for_cluster(s,
2311
+ commit->param.rename.cluster);
2312
+ char* old_path = mapping->path;
2313
+
2314
+ assert(commit->path);
2315
+ mapping->path = commit->path;
2316
+ if (rename(old_path, mapping->path))
2317
+ return -2;
2318
+
2319
+ if (mapping->mode & MODE_DIRECTORY) {
2320
+ int l1 = strlen(mapping->path);
2321
+ int l2 = strlen(old_path);
2322
+ int diff = l1 - l2;
2323
+ direntry_t* direntry = array_get(&(s->directory),
2324
+ mapping->info.dir.first_dir_index);
2325
+ uint32_t c = mapping->begin;
2326
+ int i = 0;
2327
+
2328
+ /* recurse */
2329
+ while (!fat_eof(s, c)) {
2330
+ do {
2331
+ direntry_t* d = direntry + i;
2332
+
2333
+ if (is_file(d) || (is_directory(d) && !is_dot(d))) {
2334
+ mapping_t* m = find_mapping_for_cluster(s,
2335
+ begin_of_direntry(d));
2336
+ int l = strlen(m->path);
2337
+ char* new_path = g_malloc(l + diff + 1);
2338
+
2339
+ assert(!strncmp(m->path, mapping->path, l2));
2340
2341
pstrcpy(new_path, l + diff + 1, mapping->path);
2342
pstrcpy(new_path + l1, l + diff + 1 - l1,
2343
m->path + l2);
2344
2345
-             schedule_rename(s, m->begin, new_path);
2346
-            }
2347
-            i++;
2348
-         } while((i % (0x10 * s->sectors_per_cluster)) != 0);
2349
-         c = fat_get(s, c);
2350
-        }
2351
-     }
2352
+ schedule_rename(s, m->begin, new_path);
2353
+ }
2354
+ i++;
2355
+ } while((i % (0x10 * s->sectors_per_cluster)) != 0);
2356
+ c = fat_get(s, c);
2357
+ }
2358
+ }
2359
2360
g_free(old_path);
2361
-     array_remove(&(s->commits), i);
2362
-     continue;
2363
-    } else if (commit->action == ACTION_MKDIR) {
2364
-     mapping_t* mapping;
2365
-     int j, parent_path_len;
2366
+ array_remove(&(s->commits), i);
2367
+ continue;
2368
+ } else if (commit->action == ACTION_MKDIR) {
2369
+ mapping_t* mapping;
2370
+ int j, parent_path_len;
2371
2372
#ifdef __MINGW32__
2373
if (mkdir(commit->path))
2374
@@ -XXX,XX +XXX,XX @@ static int handle_renames_and_mkdirs(BDRVVVFATState* s)
2375
return -5;
2376
#endif
2377
2378
-     mapping = insert_mapping(s, commit->param.mkdir.cluster,
2379
-         commit->param.mkdir.cluster + 1);
2380
-     if (mapping == NULL)
2381
-        return -6;
2382
-
2383
-     mapping->mode = MODE_DIRECTORY;
2384
-     mapping->read_only = 0;
2385
-     mapping->path = commit->path;
2386
-     j = s->directory.next;
2387
-     assert(j);
2388
-     insert_direntries(s, s->directory.next,
2389
-         0x10 * s->sectors_per_cluster);
2390
-     mapping->info.dir.first_dir_index = j;
2391
-
2392
-     parent_path_len = strlen(commit->path)
2393
-        - strlen(get_basename(commit->path)) - 1;
2394
-     for (j = 0; j < s->mapping.next; j++) {
2395
-        mapping_t* m = array_get(&(s->mapping), j);
2396
-        if (m->first_mapping_index < 0 && m != mapping &&
2397
-            !strncmp(m->path, mapping->path, parent_path_len) &&
2398
-            strlen(m->path) == parent_path_len)
2399
-         break;
2400
-     }
2401
-     assert(j < s->mapping.next);
2402
-     mapping->info.dir.parent_mapping_index = j;
2403
-
2404
-     array_remove(&(s->commits), i);
2405
-     continue;
2406
-    }
2407
-
2408
-    i++;
2409
+ mapping = insert_mapping(s, commit->param.mkdir.cluster,
2410
+ commit->param.mkdir.cluster + 1);
2411
+ if (mapping == NULL)
2412
+ return -6;
2413
+
2414
+ mapping->mode = MODE_DIRECTORY;
2415
+ mapping->read_only = 0;
2416
+ mapping->path = commit->path;
2417
+ j = s->directory.next;
2418
+ assert(j);
2419
+ insert_direntries(s, s->directory.next,
2420
+ 0x10 * s->sectors_per_cluster);
2421
+ mapping->info.dir.first_dir_index = j;
2422
+
2423
+ parent_path_len = strlen(commit->path)
2424
+ - strlen(get_basename(commit->path)) - 1;
2425
+ for (j = 0; j < s->mapping.next; j++) {
2426
+ mapping_t* m = array_get(&(s->mapping), j);
2427
+ if (m->first_mapping_index < 0 && m != mapping &&
2428
+ !strncmp(m->path, mapping->path, parent_path_len) &&
2429
+ strlen(m->path) == parent_path_len)
2430
+ break;
2431
+ }
2432
+ assert(j < s->mapping.next);
2433
+ mapping->info.dir.parent_mapping_index = j;
2434
+
2435
+ array_remove(&(s->commits), i);
2436
+ continue;
2437
+ }
2438
+
2439
+ i++;
2440
}
2441
return 0;
2442
}
2443
@@ -XXX,XX +XXX,XX @@ static int handle_commits(BDRVVVFATState* s)
2444
vvfat_close_current_file(s);
2445
2446
for (i = 0; !fail && i < s->commits.next; i++) {
2447
-    commit_t* commit = array_get(&(s->commits), i);
2448
-    switch(commit->action) {
2449
-    case ACTION_RENAME: case ACTION_MKDIR:
2450
+ commit_t* commit = array_get(&(s->commits), i);
2451
+ switch(commit->action) {
2452
+ case ACTION_RENAME: case ACTION_MKDIR:
2453
abort();
2454
-     fail = -2;
2455
-     break;
2456
-    case ACTION_WRITEOUT: {
2457
+ fail = -2;
2458
+ break;
2459
+ case ACTION_WRITEOUT: {
2460
#ifndef NDEBUG
2461
/* these variables are only used by assert() below */
2462
-     direntry_t* entry = array_get(&(s->directory),
2463
-         commit->param.writeout.dir_index);
2464
-     uint32_t begin = begin_of_direntry(entry);
2465
-     mapping_t* mapping = find_mapping_for_cluster(s, begin);
2466
+ direntry_t* entry = array_get(&(s->directory),
2467
+ commit->param.writeout.dir_index);
2468
+ uint32_t begin = begin_of_direntry(entry);
2469
+ mapping_t* mapping = find_mapping_for_cluster(s, begin);
2470
#endif
2471
2472
-     assert(mapping);
2473
-     assert(mapping->begin == begin);
2474
-     assert(commit->path == NULL);
2475
-
2476
-     if (commit_one_file(s, commit->param.writeout.dir_index,
2477
-            commit->param.writeout.modified_offset))
2478
-        fail = -3;
2479
-
2480
-     break;
2481
-    }
2482
-    case ACTION_NEW_FILE: {
2483
-     int begin = commit->param.new_file.first_cluster;
2484
-     mapping_t* mapping = find_mapping_for_cluster(s, begin);
2485
-     direntry_t* entry;
2486
-     int i;
2487
-
2488
-     /* find direntry */
2489
-     for (i = 0; i < s->directory.next; i++) {
2490
-        entry = array_get(&(s->directory), i);
2491
-        if (is_file(entry) && begin_of_direntry(entry) == begin)
2492
-         break;
2493
-     }
2494
-
2495
-     if (i >= s->directory.next) {
2496
-        fail = -6;
2497
-        continue;
2498
-     }
2499
-
2500
-     /* make sure there exists an initial mapping */
2501
-     if (mapping && mapping->begin != begin) {
2502
-        mapping->end = begin;
2503
-        mapping = NULL;
2504
-     }
2505
-     if (mapping == NULL) {
2506
-        mapping = insert_mapping(s, begin, begin+1);
2507
-     }
2508
-     /* most members will be fixed in commit_mappings() */
2509
-     assert(commit->path);
2510
-     mapping->path = commit->path;
2511
-     mapping->read_only = 0;
2512
-     mapping->mode = MODE_NORMAL;
2513
-     mapping->info.file.offset = 0;
2514
-
2515
-     if (commit_one_file(s, i, 0))
2516
-        fail = -7;
2517
-
2518
-     break;
2519
-    }
2520
-    default:
2521
+ assert(mapping);
2522
+ assert(mapping->begin == begin);
2523
+ assert(commit->path == NULL);
2524
+
2525
+ if (commit_one_file(s, commit->param.writeout.dir_index,
2526
+ commit->param.writeout.modified_offset))
2527
+ fail = -3;
2528
+
2529
+ break;
2530
+ }
2531
+ case ACTION_NEW_FILE: {
2532
+ int begin = commit->param.new_file.first_cluster;
2533
+ mapping_t* mapping = find_mapping_for_cluster(s, begin);
2534
+ direntry_t* entry;
2535
+ int i;
2536
+
2537
+ /* find direntry */
2538
+ for (i = 0; i < s->directory.next; i++) {
2539
+ entry = array_get(&(s->directory), i);
2540
+ if (is_file(entry) && begin_of_direntry(entry) == begin)
2541
+ break;
2542
+ }
2543
+
2544
+ if (i >= s->directory.next) {
2545
+ fail = -6;
2546
+ continue;
2547
+ }
2548
+
2549
+ /* make sure there exists an initial mapping */
2550
+ if (mapping && mapping->begin != begin) {
2551
+ mapping->end = begin;
2552
+ mapping = NULL;
2553
+ }
2554
+ if (mapping == NULL) {
2555
+ mapping = insert_mapping(s, begin, begin+1);
2556
+ }
2557
+ /* most members will be fixed in commit_mappings() */
2558
+ assert(commit->path);
2559
+ mapping->path = commit->path;
2560
+ mapping->read_only = 0;
2561
+ mapping->mode = MODE_NORMAL;
2562
+ mapping->info.file.offset = 0;
2563
+
2564
+ if (commit_one_file(s, i, 0))
2565
+ fail = -7;
2566
+
2567
+ break;
2568
+ }
2569
+ default:
2570
abort();
2571
-    }
2572
+ }
2573
}
2574
if (i > 0 && array_remove_slice(&(s->commits), 0, i))
2575
-    return -1;
2576
+ return -1;
2577
return fail;
2578
}
2579
2580
@@ -XXX,XX +XXX,XX @@ static int handle_deletes(BDRVVVFATState* s)
2581
/* delete files corresponding to mappings marked as deleted */
2582
/* handle DELETEs and unused mappings (modified_fat_get(s, mapping->begin) == 0) */
2583
while (deferred && deleted) {
2584
-    deferred = 0;
2585
-    deleted = 0;
2586
-
2587
-    for (i = 1; i < s->mapping.next; i++) {
2588
-     mapping_t* mapping = array_get(&(s->mapping), i);
2589
-     if (mapping->mode & MODE_DELETED) {
2590
-        direntry_t* entry = array_get(&(s->directory),
2591
-            mapping->dir_index);
2592
-
2593
-        if (is_free(entry)) {
2594
-         /* remove file/directory */
2595
-         if (mapping->mode & MODE_DIRECTORY) {
2596
-            int j, next_dir_index = s->directory.next,
2597
-            first_dir_index = mapping->info.dir.first_dir_index;
2598
-
2599
-            if (rmdir(mapping->path) < 0) {
2600
-             if (errno == ENOTEMPTY) {
2601
-                deferred++;
2602
-                continue;
2603
-             } else
2604
-                return -5;
2605
-            }
2606
-
2607
-            for (j = 1; j < s->mapping.next; j++) {
2608
-             mapping_t* m = array_get(&(s->mapping), j);
2609
-             if (m->mode & MODE_DIRECTORY &&
2610
-                 m->info.dir.first_dir_index >
2611
-                 first_dir_index &&
2612
-                 m->info.dir.first_dir_index <
2613
-                 next_dir_index)
2614
-                next_dir_index =
2615
-                 m->info.dir.first_dir_index;
2616
-            }
2617
-            remove_direntries(s, first_dir_index,
2618
-                next_dir_index - first_dir_index);
2619
-
2620
-            deleted++;
2621
-         }
2622
-        } else {
2623
-         if (unlink(mapping->path))
2624
-            return -4;
2625
-         deleted++;
2626
-        }
2627
-        DLOG(fprintf(stderr, "DELETE (%d)\n", i); print_mapping(mapping); print_direntry(entry));
2628
-        remove_mapping(s, i);
2629
-     }
2630
-    }
2631
+ deferred = 0;
2632
+ deleted = 0;
2633
+
2634
+ for (i = 1; i < s->mapping.next; i++) {
2635
+ mapping_t* mapping = array_get(&(s->mapping), i);
2636
+ if (mapping->mode & MODE_DELETED) {
2637
+ direntry_t* entry = array_get(&(s->directory),
2638
+ mapping->dir_index);
2639
+
2640
+ if (is_free(entry)) {
2641
+ /* remove file/directory */
2642
+ if (mapping->mode & MODE_DIRECTORY) {
2643
+ int j, next_dir_index = s->directory.next,
2644
+ first_dir_index = mapping->info.dir.first_dir_index;
2645
+
2646
+ if (rmdir(mapping->path) < 0) {
2647
+ if (errno == ENOTEMPTY) {
2648
+ deferred++;
2649
+ continue;
2650
+ } else
2651
+ return -5;
2652
+ }
2653
+
2654
+ for (j = 1; j < s->mapping.next; j++) {
2655
+ mapping_t* m = array_get(&(s->mapping), j);
2656
+ if (m->mode & MODE_DIRECTORY &&
2657
+ m->info.dir.first_dir_index >
2658
+ first_dir_index &&
2659
+ m->info.dir.first_dir_index <
2660
+ next_dir_index)
2661
+ next_dir_index =
2662
+ m->info.dir.first_dir_index;
2663
+ }
2664
+ remove_direntries(s, first_dir_index,
2665
+ next_dir_index - first_dir_index);
2666
+
2667
+ deleted++;
2668
+ }
2669
+ } else {
2670
+ if (unlink(mapping->path))
2671
+ return -4;
2672
+ deleted++;
2673
+ }
2674
+ DLOG(fprintf(stderr, "DELETE (%d)\n", i); print_mapping(mapping); print_direntry(entry));
2675
+ remove_mapping(s, i);
2676
+ }
2677
+ }
2678
}
2679
2680
return 0;
2681
@@ -XXX,XX +XXX,XX @@ static int do_commit(BDRVVVFATState* s)
2682
2683
/* the real meat are the commits. Nothing to do? Move along! */
2684
if (s->commits.next == 0)
2685
-    return 0;
2686
+ return 0;
2687
2688
vvfat_close_current_file(s);
2689
2690
ret = handle_renames_and_mkdirs(s);
2691
if (ret) {
2692
-    fprintf(stderr, "Error handling renames (%d)\n", ret);
2693
+ fprintf(stderr, "Error handling renames (%d)\n", ret);
2694
abort();
2695
-    return ret;
2696
+ return ret;
2697
}
2698
2699
/* copy FAT (with bdrv_read) */
2700
@@ -XXX,XX +XXX,XX @@ static int do_commit(BDRVVVFATState* s)
2701
/* recurse direntries from root (using bs->bdrv_read) */
2702
ret = commit_direntries(s, 0, -1);
2703
if (ret) {
2704
-    fprintf(stderr, "Fatal: error while committing (%d)\n", ret);
2705
+ fprintf(stderr, "Fatal: error while committing (%d)\n", ret);
2706
abort();
2707
-    return ret;
2708
+ return ret;
2709
}
2710
2711
ret = handle_commits(s);
2712
if (ret) {
2713
-    fprintf(stderr, "Error handling commits (%d)\n", ret);
2714
+ fprintf(stderr, "Error handling commits (%d)\n", ret);
2715
abort();
2716
-    return ret;
2717
+ return ret;
2718
}
2719
2720
ret = handle_deletes(s);
2721
if (ret) {
2722
-    fprintf(stderr, "Error deleting\n");
2723
+ fprintf(stderr, "Error deleting\n");
2724
abort();
2725
-    return ret;
2726
+ return ret;
2727
}
2728
2729
if (s->qcow->bs->drv->bdrv_make_empty) {
2730
@@ -XXX,XX +XXX,XX @@ static int try_commit(BDRVVVFATState* s)
2731
vvfat_close_current_file(s);
2732
DLOG(checkpoint());
2733
if(!is_consistent(s))
2734
-    return -1;
2735
+ return -1;
2736
return do_commit(s);
2737
}
2738
2739
@@ -XXX,XX +XXX,XX @@ DLOG(checkpoint());
2740
*/
2741
2742
if (sector_num < s->first_sectors_number)
2743
-    return -1;
2744
+ return -1;
2745
2746
for (i = sector2cluster(s, sector_num);
2747
-     i <= sector2cluster(s, sector_num + nb_sectors - 1);) {
2748
-    mapping_t* mapping = find_mapping_for_cluster(s, i);
2749
-    if (mapping) {
2750
-     if (mapping->read_only) {
2751
-        fprintf(stderr, "Tried to write to write-protected file %s\n",
2752
-            mapping->path);
2753
-        return -1;
2754
-     }
2755
-
2756
-     if (mapping->mode & MODE_DIRECTORY) {
2757
-        int begin = cluster2sector(s, i);
2758
-        int end = begin + s->sectors_per_cluster, k;
2759
-        int dir_index;
2760
-        const direntry_t* direntries;
2761
-        long_file_name lfn;
2762
-
2763
-        lfn_init(&lfn);
2764
-
2765
-        if (begin < sector_num)
2766
-         begin = sector_num;
2767
-        if (end > sector_num + nb_sectors)
2768
-         end = sector_num + nb_sectors;
2769
-        dir_index = mapping->dir_index +
2770
-         0x10 * (begin - mapping->begin * s->sectors_per_cluster);
2771
-        direntries = (direntry_t*)(buf + 0x200 * (begin - sector_num));
2772
-
2773
-        for (k = 0; k < (end - begin) * 0x10; k++) {
2774
-         /* do not allow non-ASCII filenames */
2775
-         if (parse_long_name(&lfn, direntries + k) < 0) {
2776
-            fprintf(stderr, "Warning: non-ASCII filename\n");
2777
-            return -1;
2778
-         }
2779
-         /* no access to the direntry of a read-only file */
2780
-         else if (is_short_name(direntries+k) &&
2781
-             (direntries[k].attributes & 1)) {
2782
-            if (memcmp(direntries + k,
2783
-                 array_get(&(s->directory), dir_index + k),
2784
-                 sizeof(direntry_t))) {
2785
-             fprintf(stderr, "Warning: tried to write to write-protected file\n");
2786
-             return -1;
2787
-            }
2788
-         }
2789
-        }
2790
-     }
2791
-     i = mapping->end;
2792
-    } else
2793
-     i++;
2794
+ i <= sector2cluster(s, sector_num + nb_sectors - 1);) {
2795
+ mapping_t* mapping = find_mapping_for_cluster(s, i);
2796
+ if (mapping) {
2797
+ if (mapping->read_only) {
2798
+ fprintf(stderr, "Tried to write to write-protected file %s\n",
2799
+ mapping->path);
2800
+ return -1;
2801
+ }
2802
+
2803
+ if (mapping->mode & MODE_DIRECTORY) {
2804
+ int begin = cluster2sector(s, i);
2805
+ int end = begin + s->sectors_per_cluster, k;
2806
+ int dir_index;
2807
+ const direntry_t* direntries;
2808
+ long_file_name lfn;
2809
+
2810
+ lfn_init(&lfn);
2811
+
2812
+ if (begin < sector_num)
2813
+ begin = sector_num;
2814
+ if (end > sector_num + nb_sectors)
2815
+ end = sector_num + nb_sectors;
2816
+ dir_index = mapping->dir_index +
2817
+ 0x10 * (begin - mapping->begin * s->sectors_per_cluster);
2818
+ direntries = (direntry_t*)(buf + 0x200 * (begin - sector_num));
2819
+
2820
+ for (k = 0; k < (end - begin) * 0x10; k++) {
2821
+ /* do not allow non-ASCII filenames */
2822
+ if (parse_long_name(&lfn, direntries + k) < 0) {
2823
+ fprintf(stderr, "Warning: non-ASCII filename\n");
2824
+ return -1;
2825
+ }
2826
+ /* no access to the direntry of a read-only file */
2827
+ else if (is_short_name(direntries+k) &&
2828
+ (direntries[k].attributes & 1)) {
2829
+ if (memcmp(direntries + k,
2830
+ array_get(&(s->directory), dir_index + k),
2831
+ sizeof(direntry_t))) {
2832
+ fprintf(stderr, "Warning: tried to write to write-protected file\n");
2833
+ return -1;
2834
+ }
2835
+ }
2836
+ }
2837
+ }
2838
+ i = mapping->end;
2839
+ } else
2840
+ i++;
2841
}
2842
2843
/*
2844
@@ -XXX,XX +XXX,XX @@ DLOG(checkpoint());
2845
DLOG(fprintf(stderr, "Write to qcow backend: %d + %d\n", (int)sector_num, nb_sectors));
2846
ret = bdrv_write(s->qcow, sector_num, buf, nb_sectors);
2847
if (ret < 0) {
2848
-    fprintf(stderr, "Error writing to qcow backend\n");
2849
-    return ret;
2850
+ fprintf(stderr, "Error writing to qcow backend\n");
2851
+ return ret;
2852
}
2853
2854
for (i = sector2cluster(s, sector_num);
2855
-     i <= sector2cluster(s, sector_num + nb_sectors - 1); i++)
2856
-    if (i >= 0)
2857
-     s->used_clusters[i] |= USED_ALLOCATED;
2858
+ i <= sector2cluster(s, sector_num + nb_sectors - 1); i++)
2859
+ if (i >= 0)
2860
+ s->used_clusters[i] |= USED_ALLOCATED;
2861
2862
DLOG(checkpoint());
2863
/* TODO: add timeout */
2864
@@ -XXX,XX +XXX,XX @@ vvfat_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
2865
}
2866
2867
static int64_t coroutine_fn vvfat_co_get_block_status(BlockDriverState *bs,
2868
-    int64_t sector_num, int nb_sectors, int *n, BlockDriverState **file)
2869
+ int64_t sector_num, int nb_sectors, int *n, BlockDriverState **file)
2870
{
2871
*n = bs->total_sectors - sector_num;
2872
if (*n > nb_sectors) {
2873
@@ -XXX,XX +XXX,XX @@ static void checkpoint(void) {
2874
assert(!vvv->current_mapping || vvv->current_fd || (vvv->current_mapping->mode & MODE_DIRECTORY));
2875
#if 0
2876
if (((direntry_t*)vvv->directory.pointer)[1].attributes != 0xf)
2877
-    fprintf(stderr, "Nonono!\n");
2878
+ fprintf(stderr, "Nonono!\n");
2879
mapping_t* mapping;
2880
direntry_t* direntry;
2881
assert(vvv->mapping.size >= vvv->mapping.item_size * vvv->mapping.next);
2882
assert(vvv->directory.size >= vvv->directory.item_size * vvv->directory.next);
2883
if (vvv->mapping.next<47)
2884
-    return;
2885
+ return;
2886
assert((mapping = array_get(&(vvv->mapping), 47)));
2887
assert(mapping->dir_index < vvv->directory.next);
2888
direntry = array_get(&(vvv->directory), mapping->dir_index);
2889
--
2890
1.8.3.1
2891
2892
diff view generated by jsdifflib
Deleted patch
1
From: Hervé Poussineau <hpoussin@reactos.org>
2
1
3
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
---
6
block/vvfat.c | 8 ++++----
7
1 file changed, 4 insertions(+), 4 deletions(-)
8
9
diff --git a/block/vvfat.c b/block/vvfat.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/block/vvfat.c
12
+++ b/block/vvfat.c
13
@@ -XXX,XX +XXX,XX @@ static void init_mbr(BDRVVVFATState *s, int cyls, int heads, int secs)
14
/* FAT12/FAT16/FAT32 */
15
/* DOS uses different types when partition is LBA,
16
probably to prevent older versions from using CHS on them */
17
- partition->fs_type= s->fat_type==12 ? 0x1:
18
- s->fat_type==16 ? (lba?0xe:0x06):
19
- /*fat_tyoe==32*/ (lba?0xc:0x0b);
20
+ partition->fs_type = s->fat_type == 12 ? 0x1 :
21
+ s->fat_type == 16 ? (lba ? 0xe : 0x06) :
22
+ /*s->fat_type == 32*/ (lba ? 0xc : 0x0b);
23
24
real_mbr->magic[0]=0x55; real_mbr->magic[1]=0xaa;
25
}
26
@@ -XXX,XX +XXX,XX @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
27
(ROOT_ENTRIES - cur) * sizeof(direntry_t));
28
}
29
30
- /* reget the mapping, since s->mapping was possibly realloc()ed */
31
+ /* re-get the mapping, since s->mapping was possibly realloc()ed */
32
mapping = array_get(&(s->mapping), mapping_index);
33
first_cluster += (s->directory.next - mapping->info.dir.first_dir_index)
34
* 0x20 / s->cluster_size;
35
--
36
1.8.3.1
37
38
diff view generated by jsdifflib
Deleted patch
1
From: Hervé Poussineau <hpoussin@reactos.org>
2
1
3
MODE_FAKED and MODE_RENAMED are not and were never used.
4
5
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
8
block/vvfat.c | 13 ++++++++-----
9
1 file changed, 8 insertions(+), 5 deletions(-)
10
11
diff --git a/block/vvfat.c b/block/vvfat.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/block/vvfat.c
14
+++ b/block/vvfat.c
15
@@ -XXX,XX +XXX,XX @@ typedef struct mapping_t {
16
union {
17
/* offset is
18
* - the offset in the file (in clusters) for a file, or
19
- * - the next cluster of the directory for a directory, and
20
- * - the address of the buffer for a faked entry
21
+ * - the next cluster of the directory for a directory
22
*/
23
struct {
24
uint32_t offset;
25
@@ -XXX,XX +XXX,XX @@ typedef struct mapping_t {
26
/* path contains the full path, i.e. it always starts with s->path */
27
char* path;
28
29
- enum { MODE_UNDEFINED = 0, MODE_NORMAL = 1, MODE_MODIFIED = 2,
30
- MODE_DIRECTORY = 4, MODE_FAKED = 8,
31
- MODE_DELETED = 16, MODE_RENAMED = 32 } mode;
32
+ enum {
33
+ MODE_UNDEFINED = 0,
34
+ MODE_NORMAL = 1,
35
+ MODE_MODIFIED = 2,
36
+ MODE_DIRECTORY = 4,
37
+ MODE_DELETED = 8,
38
+ } mode;
39
int read_only;
40
} mapping_t;
41
42
--
43
1.8.3.1
44
45
diff view generated by jsdifflib
Deleted patch
1
From: Hervé Poussineau <hpoussin@reactos.org>
2
1
3
- offset_to_bootsector is the number of sectors up to FAT bootsector
4
- offset_to_fat is the number of sectors up to first File Allocation Table
5
- offset_to_root_dir is the number of sectors up to root directory sector
6
7
Replace first_sectors_number - 1 by offset_to_bootsector.
8
Replace first_sectors_number by offset_to_fat.
9
Replace faked_sectors by offset_to_rootdir.
10
11
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
14
block/vvfat.c | 70 ++++++++++++++++++++++++++++++++++++-----------------------
15
1 file changed, 43 insertions(+), 27 deletions(-)
16
17
diff --git a/block/vvfat.c b/block/vvfat.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block/vvfat.c
20
+++ b/block/vvfat.c
21
@@ -XXX,XX +XXX,XX @@ static void print_mapping(const struct mapping_t* mapping);
22
typedef struct BDRVVVFATState {
23
CoMutex lock;
24
BlockDriverState* bs; /* pointer to parent */
25
- unsigned int first_sectors_number; /* 1 for a single partition, 0x40 for a disk with partition table */
26
unsigned char first_sectors[0x40*0x200];
27
28
int fat_type; /* 16 or 32 */
29
array_t fat,directory,mapping;
30
char volume_label[11];
31
32
+ uint32_t offset_to_bootsector; /* 0 for floppy, 0x3f for disk */
33
+
34
unsigned int cluster_size;
35
unsigned int sectors_per_cluster;
36
unsigned int sectors_per_fat;
37
unsigned int sectors_of_root_directory;
38
uint32_t last_cluster_of_root_directory;
39
- unsigned int faked_sectors; /* how many sectors are faked before file data */
40
uint32_t sector_count; /* total number of sectors of the partition */
41
uint32_t cluster_count; /* total number of clusters of this partition */
42
uint32_t max_fat_value;
43
+ uint32_t offset_to_fat;
44
+ uint32_t offset_to_root_dir;
45
46
int current_fd;
47
mapping_t* current_mapping;
48
@@ -XXX,XX +XXX,XX @@ static void init_mbr(BDRVVVFATState *s, int cyls, int heads, int secs)
49
partition->attributes=0x80; /* bootable */
50
51
/* LBA is used when partition is outside the CHS geometry */
52
- lba = sector2CHS(&partition->start_CHS, s->first_sectors_number - 1,
53
+ lba = sector2CHS(&partition->start_CHS, s->offset_to_bootsector,
54
cyls, heads, secs);
55
lba |= sector2CHS(&partition->end_CHS, s->bs->total_sectors - 1,
56
cyls, heads, secs);
57
58
/*LBA partitions are identified only by start/length_sector_long not by CHS*/
59
- partition->start_sector_long = cpu_to_le32(s->first_sectors_number - 1);
60
+ partition->start_sector_long = cpu_to_le32(s->offset_to_bootsector);
61
partition->length_sector_long = cpu_to_le32(s->bs->total_sectors
62
- - s->first_sectors_number + 1);
63
+ - s->offset_to_bootsector);
64
65
/* FAT12/FAT16/FAT32 */
66
/* DOS uses different types when partition is LBA,
67
@@ -XXX,XX +XXX,XX @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
68
69
static inline uint32_t sector2cluster(BDRVVVFATState* s,off_t sector_num)
70
{
71
- return (sector_num-s->faked_sectors)/s->sectors_per_cluster;
72
+ return (sector_num - s->offset_to_root_dir) / s->sectors_per_cluster;
73
}
74
75
static inline off_t cluster2sector(BDRVVVFATState* s, uint32_t cluster_num)
76
{
77
- return s->faked_sectors + s->sectors_per_cluster * cluster_num;
78
+ return s->offset_to_root_dir + s->sectors_per_cluster * cluster_num;
79
}
80
81
static int init_directories(BDRVVVFATState* s,
82
@@ -XXX,XX +XXX,XX @@ static int init_directories(BDRVVVFATState* s,
83
i = 1+s->sectors_per_cluster*0x200*8/s->fat_type;
84
s->sectors_per_fat=(s->sector_count+i)/i; /* round up */
85
86
+ s->offset_to_fat = s->offset_to_bootsector + 1;
87
+ s->offset_to_root_dir = s->offset_to_fat + s->sectors_per_fat * 2;
88
+
89
array_init(&(s->mapping),sizeof(mapping_t));
90
array_init(&(s->directory),sizeof(direntry_t));
91
92
@@ -XXX,XX +XXX,XX @@ static int init_directories(BDRVVVFATState* s,
93
/* Now build FAT, and write back information into directory */
94
init_fat(s);
95
96
- s->faked_sectors=s->first_sectors_number+s->sectors_per_fat*2;
97
s->cluster_count=sector2cluster(s, s->sector_count);
98
99
mapping = array_get_next(&(s->mapping));
100
@@ -XXX,XX +XXX,XX @@ static int init_directories(BDRVVVFATState* s,
101
102
s->current_mapping = NULL;
103
104
- bootsector=(bootsector_t*)(s->first_sectors+(s->first_sectors_number-1)*0x200);
105
+ bootsector = (bootsector_t *)(s->first_sectors
106
+ + s->offset_to_bootsector * 0x200);
107
bootsector->jump[0]=0xeb;
108
bootsector->jump[1]=0x3e;
109
bootsector->jump[2]=0x90;
110
@@ -XXX,XX +XXX,XX @@ static int init_directories(BDRVVVFATState* s,
111
bootsector->number_of_fats=0x2; /* number of FATs */
112
bootsector->root_entries=cpu_to_le16(s->sectors_of_root_directory*0x10);
113
bootsector->total_sectors16=s->sector_count>0xffff?0:cpu_to_le16(s->sector_count);
114
- bootsector->media_type=(s->first_sectors_number>1?0xf8:0xf0); /* media descriptor (f8=hd, f0=3.5 fd)*/
115
+ /* media descriptor: hard disk=0xf8, floppy=0xf0 */
116
+ bootsector->media_type = (s->offset_to_bootsector > 0 ? 0xf8 : 0xf0);
117
s->fat.pointer[0] = bootsector->media_type;
118
bootsector->sectors_per_fat=cpu_to_le16(s->sectors_per_fat);
119
bootsector->sectors_per_track = cpu_to_le16(secs);
120
bootsector->number_of_heads = cpu_to_le16(heads);
121
- bootsector->hidden_sectors=cpu_to_le32(s->first_sectors_number==1?0:0x3f);
122
+ bootsector->hidden_sectors = cpu_to_le32(s->offset_to_bootsector);
123
bootsector->total_sectors=cpu_to_le32(s->sector_count>0xffff?s->sector_count:0);
124
125
/* LATER TODO: if FAT32, this is wrong */
126
- bootsector->u.fat16.drive_number=s->first_sectors_number==1?0:0x80; /* fda=0, hda=0x80 */
127
+ /* drive_number: fda=0, hda=0x80 */
128
+ bootsector->u.fat16.drive_number = s->offset_to_bootsector == 0 ? 0 : 0x80;
129
bootsector->u.fat16.current_head=0;
130
bootsector->u.fat16.signature=0x29;
131
bootsector->u.fat16.id=cpu_to_le32(0xfabe1afd);
132
@@ -XXX,XX +XXX,XX @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
133
secs = s->fat_type == 12 ? 18 : 36;
134
s->sectors_per_cluster = 1;
135
}
136
- s->first_sectors_number = 1;
137
cyls = 80;
138
heads = 2;
139
} else {
140
@@ -XXX,XX +XXX,XX @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
141
if (!s->fat_type) {
142
s->fat_type = 16;
143
}
144
- s->first_sectors_number = 0x40;
145
+ s->offset_to_bootsector = 0x3f;
146
cyls = s->fat_type == 12 ? 64 : 1024;
147
heads = 16;
148
secs = 63;
149
@@ -XXX,XX +XXX,XX @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
150
fprintf(stderr, "vvfat %s chs %d,%d,%d\n",
151
dirname, cyls, heads, secs);
152
153
- s->sector_count = cyls * heads * secs - (s->first_sectors_number - 1);
154
+ s->sector_count = cyls * heads * secs - s->offset_to_bootsector;
155
156
if (qemu_opt_get_bool(opts, "rw", false)) {
157
if (!bdrv_is_read_only(bs)) {
158
@@ -XXX,XX +XXX,XX @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
159
goto fail;
160
}
161
162
- s->sector_count = s->faked_sectors + s->sectors_per_cluster*s->cluster_count;
163
+ s->sector_count = s->offset_to_root_dir
164
+ + s->sectors_per_cluster * s->cluster_count;
165
166
/* Disable migration when vvfat is used rw */
167
if (s->qcow) {
168
@@ -XXX,XX +XXX,XX @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
169
}
170
}
171
172
- if (s->first_sectors_number == 0x40) {
173
+ if (s->offset_to_bootsector > 0) {
174
init_mbr(s, cyls, heads, secs);
175
}
176
177
@@ -XXX,XX +XXX,XX @@ static int vvfat_read(BlockDriverState *bs, int64_t sector_num,
178
}
179
DLOG(fprintf(stderr, "sector %d not allocated\n", (int)sector_num));
180
}
181
- if(sector_num<s->faked_sectors) {
182
- if(sector_num<s->first_sectors_number)
183
- memcpy(buf+i*0x200,&(s->first_sectors[sector_num*0x200]),0x200);
184
- else if(sector_num-s->first_sectors_number<s->sectors_per_fat)
185
- memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number)*0x200]),0x200);
186
- else if(sector_num-s->first_sectors_number-s->sectors_per_fat<s->sectors_per_fat)
187
- memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number-s->sectors_per_fat)*0x200]),0x200);
188
+ if (sector_num < s->offset_to_root_dir) {
189
+ if (sector_num < s->offset_to_fat) {
190
+ memcpy(buf + i * 0x200,
191
+ &(s->first_sectors[sector_num * 0x200]),
192
+ 0x200);
193
+ } else if (sector_num < s->offset_to_fat + s->sectors_per_fat) {
194
+ memcpy(buf + i * 0x200,
195
+ &(s->fat.pointer[(sector_num
196
+ - s->offset_to_fat) * 0x200]),
197
+ 0x200);
198
+ } else if (sector_num < s->offset_to_root_dir) {
199
+ memcpy(buf + i * 0x200,
200
+ &(s->fat.pointer[(sector_num - s->offset_to_fat
201
+ - s->sectors_per_fat) * 0x200]),
202
+ 0x200);
203
+ }
204
} else {
205
- uint32_t sector=sector_num-s->faked_sectors,
206
+ uint32_t sector = sector_num - s->offset_to_root_dir,
207
sector_offset_in_cluster=(sector%s->sectors_per_cluster),
208
cluster_num=sector/s->sectors_per_cluster;
209
if(cluster_num > s->cluster_count || read_cluster(s, cluster_num) != 0) {
210
@@ -XXX,XX +XXX,XX @@ DLOG(checkpoint());
211
memcpy(s->fat2, s->fat.pointer, size);
212
}
213
check = vvfat_read(s->bs,
214
- s->first_sectors_number, s->fat2, s->sectors_per_fat);
215
+ s->offset_to_fat, s->fat2, s->sectors_per_fat);
216
if (check) {
217
fprintf(stderr, "Could not copy fat\n");
218
return 0;
219
@@ -XXX,XX +XXX,XX @@ DLOG(checkpoint());
220
* - do not allow to write non-ASCII filenames
221
*/
222
223
- if (sector_num < s->first_sectors_number)
224
+ if (sector_num < s->offset_to_fat)
225
return -1;
226
227
for (i = sector2cluster(s, sector_num);
228
--
229
1.8.3.1
230
231
diff view generated by jsdifflib
Deleted patch
1
From: Hervé Poussineau <hpoussin@reactos.org>
2
1
3
Specification: "FAT: General overview of on-disk format" v1.03, pages 11-13
4
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
---
7
block/vvfat.c | 21 ++++++++++++++-------
8
1 file changed, 14 insertions(+), 7 deletions(-)
9
10
diff --git a/block/vvfat.c b/block/vvfat.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/block/vvfat.c
13
+++ b/block/vvfat.c
14
@@ -XXX,XX +XXX,XX @@ typedef struct bootsector_t {
15
union {
16
struct {
17
uint8_t drive_number;
18
- uint8_t current_head;
19
+ uint8_t reserved1;
20
uint8_t signature;
21
uint32_t id;
22
uint8_t volume_label[11];
23
+ uint8_t fat_type[8];
24
+ uint8_t ignored[0x1c0];
25
} QEMU_PACKED fat16;
26
struct {
27
uint32_t sectors_per_fat;
28
uint16_t flags;
29
uint8_t major,minor;
30
- uint32_t first_cluster_of_root_directory;
31
+ uint32_t first_cluster_of_root_dir;
32
uint16_t info_sector;
33
uint16_t backup_boot_sector;
34
- uint16_t ignored;
35
+ uint8_t reserved[12];
36
+ uint8_t drive_number;
37
+ uint8_t reserved1;
38
+ uint8_t signature;
39
+ uint32_t id;
40
+ uint8_t volume_label[11];
41
+ uint8_t fat_type[8];
42
+ uint8_t ignored[0x1a4];
43
} QEMU_PACKED fat32;
44
} u;
45
- uint8_t fat_type[8];
46
- uint8_t ignored[0x1c0];
47
uint8_t magic[2];
48
} QEMU_PACKED bootsector_t;
49
50
@@ -XXX,XX +XXX,XX @@ static int init_directories(BDRVVVFATState* s,
51
/* LATER TODO: if FAT32, this is wrong */
52
/* drive_number: fda=0, hda=0x80 */
53
bootsector->u.fat16.drive_number = s->offset_to_bootsector == 0 ? 0 : 0x80;
54
- bootsector->u.fat16.current_head=0;
55
bootsector->u.fat16.signature=0x29;
56
bootsector->u.fat16.id=cpu_to_le32(0xfabe1afd);
57
58
memcpy(bootsector->u.fat16.volume_label, s->volume_label,
59
sizeof(bootsector->u.fat16.volume_label));
60
- memcpy(bootsector->fat_type,(s->fat_type==12?"FAT12 ":s->fat_type==16?"FAT16 ":"FAT32 "),8);
61
+ memcpy(bootsector->u.fat16.fat_type,
62
+ s->fat_type == 12 ? "FAT12 " : "FAT16 ", 8);
63
bootsector->magic[0]=0x55; bootsector->magic[1]=0xaa;
64
65
return 0;
66
--
67
1.8.3.1
68
69
diff view generated by jsdifflib
Deleted patch
1
From: Hervé Poussineau <hpoussin@reactos.org>
2
1
3
readdir() doesn't always return . and .. entries at first and in that order.
4
This leads to not creating them at first in the directory, which raises some
5
errors on file system checking utilities like MS-DOS Scandisk.
6
7
Specification: "FAT: General overview of on-disk format" v1.03, page 25
8
9
Fixes: https://bugs.launchpad.net/qemu/+bug/1599539
10
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
13
block/vvfat.c | 13 +++++++++++--
14
1 file changed, 11 insertions(+), 2 deletions(-)
15
16
diff --git a/block/vvfat.c b/block/vvfat.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/vvfat.c
19
+++ b/block/vvfat.c
20
@@ -XXX,XX +XXX,XX @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
21
i = mapping->info.dir.first_dir_index =
22
first_cluster == 0 ? 0 : s->directory.next;
23
24
+ if (first_cluster != 0) {
25
+ /* create the top entries of a subdirectory */
26
+ (void)create_short_and_long_name(s, i, ".", 1);
27
+ (void)create_short_and_long_name(s, i, "..", 1);
28
+ }
29
+
30
/* actually read the directory, and allocate the mappings */
31
while((entry=readdir(dir))) {
32
unsigned int length=strlen(dirname)+2+strlen(entry->d_name);
33
@@ -XXX,XX +XXX,XX @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
34
}
35
36
/* create directory entry for this file */
37
- direntry=create_short_and_long_name(s, i, entry->d_name,
38
- is_dot || is_dotdot);
39
+ if (!is_dot && !is_dotdot) {
40
+ direntry = create_short_and_long_name(s, i, entry->d_name, 0);
41
+ } else {
42
+ direntry = array_get(&(s->directory), is_dot ? i : i + 1);
43
+ }
44
direntry->attributes=(S_ISDIR(st.st_mode)?0x10:0x20);
45
direntry->reserved[0]=direntry->reserved[1]=0;
46
direntry->ctime=fat_datetime(st.st_ctime,1);
47
--
48
1.8.3.1
49
50
diff view generated by jsdifflib
Deleted patch
1
From: Hervé Poussineau <hpoussin@reactos.org>
2
1
3
Assume that input filename is encoded as UTF-8, so correctly create UTF-16 encoding.
4
5
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
8
block/vvfat.c | 38 ++++++++++++++++++--------------------
9
1 file changed, 18 insertions(+), 20 deletions(-)
10
11
diff --git a/block/vvfat.c b/block/vvfat.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/block/vvfat.c
14
+++ b/block/vvfat.c
15
@@ -XXX,XX +XXX,XX @@ static void init_mbr(BDRVVVFATState *s, int cyls, int heads, int secs)
16
17
/* direntry functions */
18
19
-/* dest is assumed to hold 258 bytes, and pads with 0xffff up to next multiple of 26 */
20
-static inline int short2long_name(char* dest,const char* src)
21
+static direntry_t *create_long_filename(BDRVVVFATState *s, const char *filename)
22
{
23
- int i;
24
- int len;
25
- for(i=0;i<129 && src[i];i++) {
26
- dest[2*i]=src[i];
27
- dest[2*i+1]=0;
28
+ int number_of_entries, i;
29
+ glong length;
30
+ direntry_t *entry;
31
+
32
+ gunichar2 *longname = g_utf8_to_utf16(filename, -1, NULL, &length, NULL);
33
+ if (!longname) {
34
+ fprintf(stderr, "vvfat: invalid UTF-8 name: %s\n", filename);
35
+ return NULL;
36
}
37
- len=2*i;
38
- dest[2*i]=dest[2*i+1]=0;
39
- for(i=2*i+2;(i%26);i++)
40
- dest[i]=0xff;
41
- return len;
42
-}
43
44
-static inline direntry_t* create_long_filename(BDRVVVFATState* s,const char* filename)
45
-{
46
- char buffer[258];
47
- int length=short2long_name(buffer,filename),
48
- number_of_entries=(length+25)/26,i;
49
- direntry_t* entry;
50
+ number_of_entries = (length * 2 + 25) / 26;
51
52
for(i=0;i<number_of_entries;i++) {
53
entry=array_get_next(&(s->directory));
54
@@ -XXX,XX +XXX,XX @@ static inline direntry_t* create_long_filename(BDRVVVFATState* s,const char* fil
55
else if(offset<22) offset=14+offset-10;
56
else offset=28+offset-22;
57
entry=array_get(&(s->directory),s->directory.next-1-(i/26));
58
- entry->name[offset]=buffer[i];
59
+ if (i >= 2 * length + 2) {
60
+ entry->name[offset] = 0xff;
61
+ } else if (i % 2 == 0) {
62
+ entry->name[offset] = longname[i / 2] & 0xff;
63
+ } else {
64
+ entry->name[offset] = longname[i / 2] >> 8;
65
+ }
66
}
67
+ g_free(longname);
68
return array_get(&(s->directory),s->directory.next-number_of_entries);
69
}
70
71
--
72
1.8.3.1
73
74
diff view generated by jsdifflib
Deleted patch
1
From: Hervé Poussineau <hpoussin@reactos.org>
2
1
3
More specifically, create short name from filename and change blacklist of
4
invalid chars to whitelist of valid chars.
5
6
Windows 9x also now correctly see long file names of filenames containing a space,
7
but Scandisk still complains about mismatch between SFN and LFN.
8
9
[kwolf: Build fix for this intermediate patch (it included declarations
10
for variables that are only used in the next patch) ]
11
12
Specification: "FAT: General overview of on-disk format" v1.03, pages 30-31
13
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
16
block/vvfat.c | 104 ++++++++++++++++++++++++++++++++++++++++++----------------
17
1 file changed, 76 insertions(+), 28 deletions(-)
18
19
diff --git a/block/vvfat.c b/block/vvfat.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/block/vvfat.c
22
+++ b/block/vvfat.c
23
@@ -XXX,XX +XXX,XX @@ static void set_begin_of_direntry(direntry_t* direntry, uint32_t begin)
24
direntry->begin_hi = cpu_to_le16((begin >> 16) & 0xffff);
25
}
26
27
+static uint8_t to_valid_short_char(gunichar c)
28
+{
29
+ c = g_unichar_toupper(c);
30
+ if ((c >= '0' && c <= '9') ||
31
+ (c >= 'A' && c <= 'Z') ||
32
+ strchr("$%'-_@~`!(){}^#&", c) != 0) {
33
+ return c;
34
+ } else {
35
+ return 0;
36
+ }
37
+}
38
+
39
+static direntry_t *create_short_filename(BDRVVVFATState *s,
40
+ const char *filename)
41
+{
42
+ int j = 0;
43
+ direntry_t *entry = array_get_next(&(s->directory));
44
+ const gchar *p, *last_dot = NULL;
45
+ gunichar c;
46
+ bool lossy_conversion = false;
47
+
48
+ if (!entry) {
49
+ return NULL;
50
+ }
51
+ memset(entry->name, 0x20, sizeof(entry->name));
52
+
53
+ /* copy filename and search last dot */
54
+ for (p = filename; ; p = g_utf8_next_char(p)) {
55
+ c = g_utf8_get_char(p);
56
+ if (c == '\0') {
57
+ break;
58
+ } else if (c == '.') {
59
+ if (j == 0) {
60
+ /* '.' at start of filename */
61
+ lossy_conversion = true;
62
+ } else {
63
+ if (last_dot) {
64
+ lossy_conversion = true;
65
+ }
66
+ last_dot = p;
67
+ }
68
+ } else if (!last_dot) {
69
+ /* first part of the name; copy it */
70
+ uint8_t v = to_valid_short_char(c);
71
+ if (j < 8 && v) {
72
+ entry->name[j++] = v;
73
+ } else {
74
+ lossy_conversion = true;
75
+ }
76
+ }
77
+ }
78
+
79
+ /* copy extension (if any) */
80
+ if (last_dot) {
81
+ j = 0;
82
+ for (p = g_utf8_next_char(last_dot); ; p = g_utf8_next_char(p)) {
83
+ c = g_utf8_get_char(p);
84
+ if (c == '\0') {
85
+ break;
86
+ } else {
87
+ /* extension; copy it */
88
+ uint8_t v = to_valid_short_char(c);
89
+ if (j < 3 && v) {
90
+ entry->name[8 + (j++)] = v;
91
+ } else {
92
+ lossy_conversion = true;
93
+ }
94
+ }
95
+ }
96
+ }
97
+ (void)lossy_conversion;
98
+ return entry;
99
+}
100
+
101
/* fat functions */
102
103
static inline uint8_t fat_chksum(const direntry_t* entry)
104
@@ -XXX,XX +XXX,XX @@ static inline void init_fat(BDRVVVFATState* s)
105
static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s,
106
unsigned int directory_start, const char* filename, int is_dot)
107
{
108
- int i,j,long_index=s->directory.next;
109
+ int long_index = s->directory.next;
110
direntry_t* entry = NULL;
111
direntry_t* entry_long = NULL;
112
113
@@ -XXX,XX +XXX,XX @@ static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s,
114
}
115
116
entry_long=create_long_filename(s,filename);
117
-
118
- i = strlen(filename);
119
- for(j = i - 1; j>0 && filename[j]!='.';j--);
120
- if (j > 0)
121
- i = (j > 8 ? 8 : j);
122
- else if (i > 8)
123
- i = 8;
124
-
125
- entry=array_get_next(&(s->directory));
126
- memset(entry->name, 0x20, sizeof(entry->name));
127
- memcpy(entry->name, filename, i);
128
-
129
- if (j > 0) {
130
- for (i = 0; i < 3 && filename[j + 1 + i]; i++) {
131
- entry->name[8 + i] = filename[j + 1 + i];
132
- }
133
- }
134
-
135
- /* upcase & remove unwanted characters */
136
- for(i=10;i>=0;i--) {
137
- if(i==10 || i==7) for(;i>0 && entry->name[i]==' ';i--);
138
- if(entry->name[i]<=' ' || entry->name[i]>0x7f
139
- || strchr(".*?<>|\":/\\[];,+='",entry->name[i]))
140
- entry->name[i]='_';
141
- else if(entry->name[i]>='a' && entry->name[i]<='z')
142
- entry->name[i]+='A'-'a';
143
- }
144
+ entry = create_short_filename(s, filename);
145
146
/* mangle duplicates */
147
while(1) {
148
--
149
1.8.3.1
150
151
diff view generated by jsdifflib
Deleted patch
1
From: Hervé Poussineau <hpoussin@reactos.org>
2
1
3
More specifically:
4
- try without numeric-tail only if LFN didn't have invalid short chars
5
- start at ~1 (instead of ~0)
6
- handle case if numeric tail is more than one char (ie > 10)
7
8
Windows 9x Scandisk doesn't see anymore mismatches between short file names and
9
long file names for non-ASCII filenames.
10
11
Specification: "FAT: General overview of on-disk format" v1.03, page 31
12
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
15
block/vvfat.c | 65 ++++++++++++++++++++++++++++-------------------------------
16
1 file changed, 31 insertions(+), 34 deletions(-)
17
18
diff --git a/block/vvfat.c b/block/vvfat.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/block/vvfat.c
21
+++ b/block/vvfat.c
22
@@ -XXX,XX +XXX,XX @@ static uint8_t to_valid_short_char(gunichar c)
23
}
24
25
static direntry_t *create_short_filename(BDRVVVFATState *s,
26
- const char *filename)
27
+ const char *filename,
28
+ unsigned int directory_start)
29
{
30
- int j = 0;
31
+ int i, j = 0;
32
direntry_t *entry = array_get_next(&(s->directory));
33
const gchar *p, *last_dot = NULL;
34
gunichar c;
35
bool lossy_conversion = false;
36
+ char tail[11];
37
38
if (!entry) {
39
return NULL;
40
@@ -XXX,XX +XXX,XX @@ static direntry_t *create_short_filename(BDRVVVFATState *s,
41
}
42
}
43
}
44
- (void)lossy_conversion;
45
- return entry;
46
+
47
+ /* numeric-tail generation */
48
+ for (j = 0; j < 8; j++) {
49
+ if (entry->name[j] == ' ') {
50
+ break;
51
+ }
52
+ }
53
+ for (i = lossy_conversion ? 1 : 0; i < 999999; i++) {
54
+ direntry_t *entry1;
55
+ if (i > 0) {
56
+ int len = sprintf(tail, "~%d", i);
57
+ memcpy(entry->name + MIN(j, 8 - len), tail, len);
58
+ }
59
+ for (entry1 = array_get(&(s->directory), directory_start);
60
+ entry1 < entry; entry1++) {
61
+ if (!is_long_name(entry1) &&
62
+ !memcmp(entry1->name, entry->name, 11)) {
63
+ break; /* found dupe */
64
+ }
65
+ }
66
+ if (entry1 == entry) {
67
+ /* no dupe found */
68
+ return entry;
69
+ }
70
+ }
71
+ return NULL;
72
}
73
74
/* fat functions */
75
@@ -XXX,XX +XXX,XX @@ static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s,
76
}
77
78
entry_long=create_long_filename(s,filename);
79
- entry = create_short_filename(s, filename);
80
-
81
- /* mangle duplicates */
82
- while(1) {
83
- direntry_t* entry1=array_get(&(s->directory),directory_start);
84
- int j;
85
-
86
- for(;entry1<entry;entry1++)
87
- if(!is_long_name(entry1) && !memcmp(entry1->name,entry->name,11))
88
- break; /* found dupe */
89
- if(entry1==entry) /* no dupe found */
90
- break;
91
-
92
- /* use all 8 characters of name */
93
- if(entry->name[7]==' ') {
94
- int j;
95
- for(j=6;j>0 && entry->name[j]==' ';j--)
96
- entry->name[j]='~';
97
- }
98
-
99
- /* increment number */
100
- for(j=7;j>0 && entry->name[j]=='9';j--)
101
- entry->name[j]='0';
102
- if(j>0) {
103
- if(entry->name[j]<'0' || entry->name[j]>'9')
104
- entry->name[j]='0';
105
- else
106
- entry->name[j]++;
107
- }
108
- }
109
+ entry = create_short_filename(s, filename, directory_start);
110
111
/* calculate checksum; propagate to long name */
112
if(entry_long) {
113
--
114
1.8.3.1
115
116
diff view generated by jsdifflib
Deleted patch
1
From: Hervé Poussineau <hpoussin@reactos.org>
2
1
3
FAT12/FAT16 root directory is two sectors in size, which allows only 512 directory entries.
4
Prevent QEMU startup if too much files exist, instead of overflowing root directory.
5
6
Also introduce variable root_entries, which will be required for FAT32.
7
8
Fixes: https://bugs.launchpad.net/qemu/+bug/1599539/comments/4
9
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
block/vvfat.c | 26 +++++++++++++++++---------
13
1 file changed, 17 insertions(+), 9 deletions(-)
14
15
diff --git a/block/vvfat.c b/block/vvfat.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/block/vvfat.c
18
+++ b/block/vvfat.c
19
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVVVFATState {
20
unsigned int cluster_size;
21
unsigned int sectors_per_cluster;
22
unsigned int sectors_per_fat;
23
- unsigned int sectors_of_root_directory;
24
uint32_t last_cluster_of_root_directory;
25
+ /* how many entries are available in root directory (0 for FAT32) */
26
+ uint16_t root_entries;
27
uint32_t sector_count; /* total number of sectors of the partition */
28
uint32_t cluster_count; /* total number of clusters of this partition */
29
uint32_t max_fat_value;
30
@@ -XXX,XX +XXX,XX @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
31
int is_dot=!strcmp(entry->d_name,".");
32
int is_dotdot=!strcmp(entry->d_name,"..");
33
34
+ if (first_cluster == 0 && s->directory.next >= s->root_entries - 1) {
35
+ fprintf(stderr, "Too many entries in root directory\n");
36
+ closedir(dir);
37
+ return -2;
38
+ }
39
+
40
if(first_cluster == 0 && (is_dotdot || is_dot))
41
continue;
42
43
@@ -XXX,XX +XXX,XX @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
44
memset(direntry,0,sizeof(direntry_t));
45
}
46
47
-/* TODO: if there are more entries, bootsector has to be adjusted! */
48
-#define ROOT_ENTRIES (0x02 * 0x10 * s->sectors_per_cluster)
49
- if (mapping_index == 0 && s->directory.next < ROOT_ENTRIES) {
50
+ if (s->fat_type != 32 &&
51
+ mapping_index == 0 &&
52
+ s->directory.next < s->root_entries) {
53
/* root directory */
54
int cur = s->directory.next;
55
- array_ensure_allocated(&(s->directory), ROOT_ENTRIES - 1);
56
- s->directory.next = ROOT_ENTRIES;
57
+ array_ensure_allocated(&(s->directory), s->root_entries - 1);
58
+ s->directory.next = s->root_entries;
59
memset(array_get(&(s->directory), cur), 0,
60
- (ROOT_ENTRIES - cur) * sizeof(direntry_t));
61
+ (s->root_entries - cur) * sizeof(direntry_t));
62
}
63
64
/* re-get the mapping, since s->mapping was possibly realloc()ed */
65
@@ -XXX,XX +XXX,XX @@ static int init_directories(BDRVVVFATState* s,
66
/* Now build FAT, and write back information into directory */
67
init_fat(s);
68
69
+ /* TODO: if there are more entries, bootsector has to be adjusted! */
70
+ s->root_entries = 0x02 * 0x10 * s->sectors_per_cluster;
71
s->cluster_count=sector2cluster(s, s->sector_count);
72
73
mapping = array_get_next(&(s->mapping));
74
@@ -XXX,XX +XXX,XX @@ static int init_directories(BDRVVVFATState* s,
75
}
76
77
mapping = array_get(&(s->mapping), 0);
78
- s->sectors_of_root_directory = mapping->end * s->sectors_per_cluster;
79
s->last_cluster_of_root_directory = mapping->end;
80
81
/* the FAT signature */
82
@@ -XXX,XX +XXX,XX @@ static int init_directories(BDRVVVFATState* s,
83
bootsector->sectors_per_cluster=s->sectors_per_cluster;
84
bootsector->reserved_sectors=cpu_to_le16(1);
85
bootsector->number_of_fats=0x2; /* number of FATs */
86
- bootsector->root_entries=cpu_to_le16(s->sectors_of_root_directory*0x10);
87
+ bootsector->root_entries = cpu_to_le16(s->root_entries);
88
bootsector->total_sectors16=s->sector_count>0xffff?0:cpu_to_le16(s->sector_count);
89
/* media descriptor: hard disk=0xf8, floppy=0xf0 */
90
bootsector->media_type = (s->offset_to_bootsector > 0 ? 0xf8 : 0xf0);
91
--
92
1.8.3.1
93
94
diff view generated by jsdifflib
Deleted patch
1
From: Hervé Poussineau <hpoussin@reactos.org>
2
1
3
Specification: "FAT: General overview of on-disk format" v1.03, page 23
4
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
---
7
block/vvfat.c | 9 +++++++--
8
1 file changed, 7 insertions(+), 2 deletions(-)
9
10
diff --git a/block/vvfat.c b/block/vvfat.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/block/vvfat.c
13
+++ b/block/vvfat.c
14
@@ -XXX,XX +XXX,XX @@ static direntry_t *create_short_filename(BDRVVVFATState *s,
15
}
16
}
17
18
+ if (entry->name[0] == 0xe5) {
19
+ entry->name[0] = 0x05;
20
+ }
21
+
22
/* numeric-tail generation */
23
for (j = 0; j < 8; j++) {
24
if (entry->name[j] == ' ') {
25
@@ -XXX,XX +XXX,XX @@ static inline void init_fat(BDRVVVFATState* s)
26
27
}
28
29
-/* TODO: in create_short_filename, 0xe5->0x05 is not yet handled! */
30
-/* TODO: in parse_short_filename, 0x05->0xe5 is not yet handled! */
31
static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s,
32
unsigned int directory_start, const char* filename, int is_dot)
33
{
34
@@ -XXX,XX +XXX,XX @@ static int parse_short_name(BDRVVVFATState* s,
35
} else
36
lfn->name[i + j + 1] = '\0';
37
38
+ if (lfn->name[0] == 0x05) {
39
+ lfn->name[0] = 0xe5;
40
+ }
41
lfn->len = strlen((char*)lfn->name);
42
43
return 0;
44
--
45
1.8.3.1
46
47
diff view generated by jsdifflib
Deleted patch
1
From: Hervé Poussineau <hpoussin@reactos.org>
2
1
3
According to specification:
4
"'MSWIN4.1' is the recommanded setting, because it is the setting least likely
5
to cause compatibility problems. If you want to put something else in here,
6
that is your option, but the result may be that some FAT drivers might not
7
recognize the volume."
8
9
Specification: "FAT: General overview of on-disk format" v1.03, page 9
10
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
14
block/vvfat.c | 2 +-
15
1 file changed, 1 insertion(+), 1 deletion(-)
16
17
diff --git a/block/vvfat.c b/block/vvfat.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block/vvfat.c
20
+++ b/block/vvfat.c
21
@@ -XXX,XX +XXX,XX @@ static int init_directories(BDRVVVFATState* s,
22
bootsector->jump[0]=0xeb;
23
bootsector->jump[1]=0x3e;
24
bootsector->jump[2]=0x90;
25
- memcpy(bootsector->name,"QEMU ",8);
26
+ memcpy(bootsector->name, "MSWIN4.1", 8);
27
bootsector->sector_size=cpu_to_le16(0x200);
28
bootsector->sectors_per_cluster=s->sectors_per_cluster;
29
bootsector->reserved_sectors=cpu_to_le16(1);
30
--
31
1.8.3.1
32
33
diff view generated by jsdifflib
Deleted patch
1
From: "Daniel P. Berrange" <berrange@redhat.com>
2
1
3
The '-e' and '-6' options to the 'create' & 'convert' commands were
4
"deprecated" in favour of the more generic '-o' option many years ago:
5
6
commit eec77d9e712bd4157a4e1c0b5a9249d168add738
7
Author: Jes Sorensen <Jes.Sorensen@redhat.com>
8
Date: Tue Dec 7 17:44:34 2010 +0100
9
10
qemu-img: Deprecate obsolete -6 and -e options
11
12
Except this was never actually a deprecation, which would imply giving
13
the user a warning while the functionality continues to work for a
14
number of releases before eventual removal. Instead the options were
15
immediately turned into an error + exit. Given that the functionality
16
is already broken, there's no point in keeping these psuedo-deprecation
17
messages around any longer.
18
19
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
20
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
21
---
22
qemu-img.c | 20 ++------------------
23
1 file changed, 2 insertions(+), 18 deletions(-)
24
25
diff --git a/qemu-img.c b/qemu-img.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/qemu-img.c
28
+++ b/qemu-img.c
29
@@ -XXX,XX +XXX,XX @@ static int img_create(int argc, char **argv)
30
{"object", required_argument, 0, OPTION_OBJECT},
31
{0, 0, 0, 0}
32
};
33
- c = getopt_long(argc, argv, ":F:b:f:he6o:q",
34
+ c = getopt_long(argc, argv, ":F:b:f:ho:q",
35
long_options, NULL);
36
if (c == -1) {
37
break;
38
@@ -XXX,XX +XXX,XX @@ static int img_create(int argc, char **argv)
39
case 'f':
40
fmt = optarg;
41
break;
42
- case 'e':
43
- error_report("option -e is deprecated, please use \'-o "
44
- "encryption\' instead!");
45
- goto fail;
46
- case '6':
47
- error_report("option -6 is deprecated, please use \'-o "
48
- "compat6\' instead!");
49
- goto fail;
50
case 'o':
51
if (!is_valid_option_list(optarg)) {
52
error_report("Invalid option list: %s", optarg);
53
@@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv)
54
{"target-image-opts", no_argument, 0, OPTION_TARGET_IMAGE_OPTS},
55
{0, 0, 0, 0}
56
};
57
- c = getopt_long(argc, argv, ":hf:O:B:ce6o:s:l:S:pt:T:qnm:WU",
58
+ c = getopt_long(argc, argv, ":hf:O:B:co:s:l:S:pt:T:qnm:WU",
59
long_options, NULL);
60
if (c == -1) {
61
break;
62
@@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv)
63
case 'c':
64
s.compressed = true;
65
break;
66
- case 'e':
67
- error_report("option -e is deprecated, please use \'-o "
68
- "encryption\' instead!");
69
- goto fail_getopt;
70
- case '6':
71
- error_report("option -6 is deprecated, please use \'-o "
72
- "compat6\' instead!");
73
- goto fail_getopt;
74
case 'o':
75
if (!is_valid_option_list(optarg)) {
76
error_report("Invalid option list: %s", optarg);
77
--
78
1.8.3.1
79
80
diff view generated by jsdifflib
Deleted patch
1
From: Thomas Huth <thuth@redhat.com>
2
1
3
We likely do not want to carry these legacy -drive options along forever.
4
Let's emit a deprecation warning for the -drive options that have a
5
replacement with the -device option, so that the (hopefully few) remaining
6
users are aware of this and can adapt their scripts / behaviour accordingly.
7
8
Signed-off-by: Thomas Huth <thuth@redhat.com>
9
Reviewed-by: Markus Armbruster <armbru@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
blockdev.c | 14 ++++++++++++++
13
qemu-options.hx | 9 +++++++--
14
2 files changed, 21 insertions(+), 2 deletions(-)
15
16
diff --git a/blockdev.c b/blockdev.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/blockdev.c
19
+++ b/blockdev.c
20
@@ -XXX,XX +XXX,XX @@
21
#include "qmp-commands.h"
22
#include "block/trace.h"
23
#include "sysemu/arch_init.h"
24
+#include "sysemu/qtest.h"
25
#include "qemu/cutils.h"
26
#include "qemu/help_option.h"
27
#include "qemu/throttle-options.h"
28
@@ -XXX,XX +XXX,XX @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
29
const char *filename;
30
Error *local_err = NULL;
31
int i;
32
+ const char *deprecated[] = {
33
+ "serial", "trans", "secs", "heads", "cyls", "addr"
34
+ };
35
36
/* Change legacy command line options into QMP ones */
37
static const struct {
38
@@ -XXX,XX +XXX,XX @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
39
"update your scripts.\n");
40
}
41
42
+ /* Other deprecated options */
43
+ if (!qtest_enabled()) {
44
+ for (i = 0; i < ARRAY_SIZE(deprecated); i++) {
45
+ if (qemu_opt_get(legacy_opts, deprecated[i]) != NULL) {
46
+ error_report("'%s' is deprecated, please use the corresponding "
47
+ "option of '-device' instead", deprecated[i]);
48
+ }
49
+ }
50
+ }
51
+
52
/* Media type */
53
value = qemu_opt_get(legacy_opts, "media");
54
if (value) {
55
diff --git a/qemu-options.hx b/qemu-options.hx
56
index XXXXXXX..XXXXXXX 100644
57
--- a/qemu-options.hx
58
+++ b/qemu-options.hx
59
@@ -XXX,XX +XXX,XX @@ of available connectors of a given interface type.
60
This option defines the type of the media: disk or cdrom.
61
@item cyls=@var{c},heads=@var{h},secs=@var{s}[,trans=@var{t}]
62
These options have the same definition as they have in @option{-hdachs}.
63
+These parameters are deprecated, use the corresponding parameters
64
+of @code{-device} instead.
65
@item snapshot=@var{snapshot}
66
@var{snapshot} is "on" or "off" and controls snapshot mode for the given drive
67
(see @option{-snapshot}).
68
@@ -XXX,XX +XXX,XX @@ Specify which disk @var{format} will be used rather than detecting
69
the format. Can be used to specify format=raw to avoid interpreting
70
an untrusted format header.
71
@item serial=@var{serial}
72
-This option specifies the serial number to assign to the device.
73
+This option specifies the serial number to assign to the device. This
74
+parameter is deprecated, use the corresponding parameter of @code{-device}
75
+instead.
76
@item addr=@var{addr}
77
-Specify the controller's PCI address (if=virtio only).
78
+Specify the controller's PCI address (if=virtio only). This parameter is
79
+deprecated, use the corresponding parameter of @code{-device} instead.
80
@item werror=@var{action},rerror=@var{action}
81
Specify which @var{action} to take on write and read errors. Valid actions are:
82
"ignore" (ignore the error and try to continue), "stop" (pause QEMU),
83
--
84
1.8.3.1
85
86
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
The user interface specifies job rate limits in bytes/second.
4
It's pointless to have our internal representation track things
5
in sectors/second, particularly since we want to move away from
6
sector-based interfaces.
7
8
Fix up a doc typo found while verifying that the ratelimit
9
code handles the scaling difference.
10
11
Repetition of expressions like 'n * BDRV_SECTOR_SIZE' will be
12
cleaned up later when functions are converted to iterate over
13
images by bytes rather than by sectors.
14
15
Signed-off-by: Eric Blake <eblake@redhat.com>
16
Reviewed-by: John Snow <jsnow@redhat.com>
17
Reviewed-by: Jeff Cody <jcody@redhat.com>
18
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
19
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
20
---
21
block/backup.c | 5 +++--
22
block/commit.c | 5 +++--
23
block/mirror.c | 13 +++++++------
24
block/stream.c | 5 +++--
25
include/qemu/ratelimit.h | 3 ++-
26
5 files changed, 18 insertions(+), 13 deletions(-)
27
28
diff --git a/block/backup.c b/block/backup.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/block/backup.c
31
+++ b/block/backup.c
32
@@ -XXX,XX +XXX,XX @@ static void backup_set_speed(BlockJob *job, int64_t speed, Error **errp)
33
error_setg(errp, QERR_INVALID_PARAMETER, "speed");
34
return;
35
}
36
- ratelimit_set_speed(&s->limit, speed / BDRV_SECTOR_SIZE, SLICE_TIME);
37
+ ratelimit_set_speed(&s->limit, speed, SLICE_TIME);
38
}
39
40
static void backup_cleanup_sync_bitmap(BackupBlockJob *job, int ret)
41
@@ -XXX,XX +XXX,XX @@ static bool coroutine_fn yield_and_check(BackupBlockJob *job)
42
*/
43
if (job->common.speed) {
44
uint64_t delay_ns = ratelimit_calculate_delay(&job->limit,
45
- job->sectors_read);
46
+ job->sectors_read *
47
+ BDRV_SECTOR_SIZE);
48
job->sectors_read = 0;
49
block_job_sleep_ns(&job->common, QEMU_CLOCK_REALTIME, delay_ns);
50
} else {
51
diff --git a/block/commit.c b/block/commit.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/block/commit.c
54
+++ b/block/commit.c
55
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn commit_run(void *opaque)
56
s->common.offset += n * BDRV_SECTOR_SIZE;
57
58
if (copy && s->common.speed) {
59
- delay_ns = ratelimit_calculate_delay(&s->limit, n);
60
+ delay_ns = ratelimit_calculate_delay(&s->limit,
61
+ n * BDRV_SECTOR_SIZE);
62
}
63
}
64
65
@@ -XXX,XX +XXX,XX @@ static void commit_set_speed(BlockJob *job, int64_t speed, Error **errp)
66
error_setg(errp, QERR_INVALID_PARAMETER, "speed");
67
return;
68
}
69
- ratelimit_set_speed(&s->limit, speed / BDRV_SECTOR_SIZE, SLICE_TIME);
70
+ ratelimit_set_speed(&s->limit, speed, SLICE_TIME);
71
}
72
73
static const BlockJobDriver commit_job_driver = {
74
diff --git a/block/mirror.c b/block/mirror.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/block/mirror.c
77
+++ b/block/mirror.c
78
@@ -XXX,XX +XXX,XX @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
79
bitmap_set(s->in_flight_bitmap, sector_num / sectors_per_chunk, nb_chunks);
80
while (nb_chunks > 0 && sector_num < end) {
81
int64_t ret;
82
- int io_sectors, io_sectors_acct;
83
+ int io_sectors;
84
+ int64_t io_bytes_acct;
85
BlockDriverState *file;
86
enum MirrorMethod {
87
MIRROR_METHOD_COPY,
88
@@ -XXX,XX +XXX,XX @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
89
switch (mirror_method) {
90
case MIRROR_METHOD_COPY:
91
io_sectors = mirror_do_read(s, sector_num, io_sectors);
92
- io_sectors_acct = io_sectors;
93
+ io_bytes_acct = io_sectors * BDRV_SECTOR_SIZE;
94
break;
95
case MIRROR_METHOD_ZERO:
96
case MIRROR_METHOD_DISCARD:
97
mirror_do_zero_or_discard(s, sector_num, io_sectors,
98
mirror_method == MIRROR_METHOD_DISCARD);
99
if (write_zeroes_ok) {
100
- io_sectors_acct = 0;
101
+ io_bytes_acct = 0;
102
} else {
103
- io_sectors_acct = io_sectors;
104
+ io_bytes_acct = io_sectors * BDRV_SECTOR_SIZE;
105
}
106
break;
107
default:
108
@@ -XXX,XX +XXX,XX @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
109
sector_num += io_sectors;
110
nb_chunks -= DIV_ROUND_UP(io_sectors, sectors_per_chunk);
111
if (s->common.speed) {
112
- delay_ns = ratelimit_calculate_delay(&s->limit, io_sectors_acct);
113
+ delay_ns = ratelimit_calculate_delay(&s->limit, io_bytes_acct);
114
}
115
}
116
return delay_ns;
117
@@ -XXX,XX +XXX,XX @@ static void mirror_set_speed(BlockJob *job, int64_t speed, Error **errp)
118
error_setg(errp, QERR_INVALID_PARAMETER, "speed");
119
return;
120
}
121
- ratelimit_set_speed(&s->limit, speed / BDRV_SECTOR_SIZE, SLICE_TIME);
122
+ ratelimit_set_speed(&s->limit, speed, SLICE_TIME);
123
}
124
125
static void mirror_complete(BlockJob *job, Error **errp)
126
diff --git a/block/stream.c b/block/stream.c
127
index XXXXXXX..XXXXXXX 100644
128
--- a/block/stream.c
129
+++ b/block/stream.c
130
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn stream_run(void *opaque)
131
/* Publish progress */
132
s->common.offset += n * BDRV_SECTOR_SIZE;
133
if (copy && s->common.speed) {
134
- delay_ns = ratelimit_calculate_delay(&s->limit, n);
135
+ delay_ns = ratelimit_calculate_delay(&s->limit,
136
+ n * BDRV_SECTOR_SIZE);
137
}
138
}
139
140
@@ -XXX,XX +XXX,XX @@ static void stream_set_speed(BlockJob *job, int64_t speed, Error **errp)
141
error_setg(errp, QERR_INVALID_PARAMETER, "speed");
142
return;
143
}
144
- ratelimit_set_speed(&s->limit, speed / BDRV_SECTOR_SIZE, SLICE_TIME);
145
+ ratelimit_set_speed(&s->limit, speed, SLICE_TIME);
146
}
147
148
static const BlockJobDriver stream_job_driver = {
149
diff --git a/include/qemu/ratelimit.h b/include/qemu/ratelimit.h
150
index XXXXXXX..XXXXXXX 100644
151
--- a/include/qemu/ratelimit.h
152
+++ b/include/qemu/ratelimit.h
153
@@ -XXX,XX +XXX,XX @@ typedef struct {
154
155
/** Calculate and return delay for next request in ns
156
*
157
- * Record that we sent @p n data units. If we may send more data units
158
+ * Record that we sent @n data units (where @n matches the scale chosen
159
+ * during ratelimit_set_speed). If we may send more data units
160
* in the current time slice, return 0 (i.e. no delay). Otherwise
161
* return the amount of time (in ns) until the start of the next time
162
* slice that will permit sending the next chunk of data.
163
--
164
1.8.3.1
165
166
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
Upcoming patches are going to switch to byte-based interfaces
4
instead of sector-based. Even worse, trace_backup_do_cow_enter()
5
had a weird mix of cluster and sector indices.
6
7
The trace interface is low enough that there are no stability
8
guarantees, and therefore nothing wrong with changing our units,
9
even in cases like trace_backup_do_cow_skip() where we are not
10
changing the trace output. So make the tracing uniformly use
11
bytes.
12
13
Signed-off-by: Eric Blake <eblake@redhat.com>
14
Reviewed-by: John Snow <jsnow@redhat.com>
15
Reviewed-by: Jeff Cody <jcody@redhat.com>
16
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
---
19
block/backup.c | 16 ++++++++++------
20
block/commit.c | 3 ++-
21
block/mirror.c | 26 +++++++++++++++++---------
22
block/stream.c | 3 ++-
23
block/trace-events | 14 +++++++-------
24
5 files changed, 38 insertions(+), 24 deletions(-)
25
26
diff --git a/block/backup.c b/block/backup.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/block/backup.c
29
+++ b/block/backup.c
30
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job,
31
void *bounce_buffer = NULL;
32
int ret = 0;
33
int64_t sectors_per_cluster = cluster_size_sectors(job);
34
+ int64_t bytes_per_cluster = sectors_per_cluster * BDRV_SECTOR_SIZE;
35
int64_t start, end;
36
int n;
37
38
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job,
39
start = sector_num / sectors_per_cluster;
40
end = DIV_ROUND_UP(sector_num + nb_sectors, sectors_per_cluster);
41
42
- trace_backup_do_cow_enter(job, start, sector_num, nb_sectors);
43
+ trace_backup_do_cow_enter(job, start * bytes_per_cluster,
44
+ sector_num * BDRV_SECTOR_SIZE,
45
+ nb_sectors * BDRV_SECTOR_SIZE);
46
47
wait_for_overlapping_requests(job, start, end);
48
cow_request_begin(&cow_request, job, start, end);
49
50
for (; start < end; start++) {
51
if (test_bit(start, job->done_bitmap)) {
52
- trace_backup_do_cow_skip(job, start);
53
+ trace_backup_do_cow_skip(job, start * bytes_per_cluster);
54
continue; /* already copied */
55
}
56
57
- trace_backup_do_cow_process(job, start);
58
+ trace_backup_do_cow_process(job, start * bytes_per_cluster);
59
60
n = MIN(sectors_per_cluster,
61
job->common.len / BDRV_SECTOR_SIZE -
62
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job,
63
bounce_qiov.size, &bounce_qiov,
64
is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0);
65
if (ret < 0) {
66
- trace_backup_do_cow_read_fail(job, start, ret);
67
+ trace_backup_do_cow_read_fail(job, start * bytes_per_cluster, ret);
68
if (error_is_read) {
69
*error_is_read = true;
70
}
71
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job,
72
job->compress ? BDRV_REQ_WRITE_COMPRESSED : 0);
73
}
74
if (ret < 0) {
75
- trace_backup_do_cow_write_fail(job, start, ret);
76
+ trace_backup_do_cow_write_fail(job, start * bytes_per_cluster, ret);
77
if (error_is_read) {
78
*error_is_read = false;
79
}
80
@@ -XXX,XX +XXX,XX @@ out:
81
82
cow_request_end(&cow_request);
83
84
- trace_backup_do_cow_return(job, sector_num, nb_sectors, ret);
85
+ trace_backup_do_cow_return(job, sector_num * BDRV_SECTOR_SIZE,
86
+ nb_sectors * BDRV_SECTOR_SIZE, ret);
87
88
qemu_co_rwlock_unlock(&job->flush_rwlock);
89
90
diff --git a/block/commit.c b/block/commit.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/block/commit.c
93
+++ b/block/commit.c
94
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn commit_run(void *opaque)
95
COMMIT_BUFFER_SIZE / BDRV_SECTOR_SIZE,
96
&n);
97
copy = (ret == 1);
98
- trace_commit_one_iteration(s, sector_num, n, ret);
99
+ trace_commit_one_iteration(s, sector_num * BDRV_SECTOR_SIZE,
100
+ n * BDRV_SECTOR_SIZE, ret);
101
if (copy) {
102
ret = commit_populate(s->top, s->base, sector_num, n, buf);
103
bytes_written += n * BDRV_SECTOR_SIZE;
104
diff --git a/block/mirror.c b/block/mirror.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/block/mirror.c
107
+++ b/block/mirror.c
108
@@ -XXX,XX +XXX,XX @@ static void mirror_iteration_done(MirrorOp *op, int ret)
109
int64_t chunk_num;
110
int i, nb_chunks, sectors_per_chunk;
111
112
- trace_mirror_iteration_done(s, op->sector_num, op->nb_sectors, ret);
113
+ trace_mirror_iteration_done(s, op->sector_num * BDRV_SECTOR_SIZE,
114
+ op->nb_sectors * BDRV_SECTOR_SIZE, ret);
115
116
s->in_flight--;
117
s->sectors_in_flight -= op->nb_sectors;
118
@@ -XXX,XX +XXX,XX @@ static int mirror_do_read(MirrorBlockJob *s, int64_t sector_num,
119
nb_chunks = DIV_ROUND_UP(nb_sectors, sectors_per_chunk);
120
121
while (s->buf_free_count < nb_chunks) {
122
- trace_mirror_yield_in_flight(s, sector_num, s->in_flight);
123
+ trace_mirror_yield_in_flight(s, sector_num * BDRV_SECTOR_SIZE,
124
+ s->in_flight);
125
mirror_wait_for_io(s);
126
}
127
128
@@ -XXX,XX +XXX,XX @@ static int mirror_do_read(MirrorBlockJob *s, int64_t sector_num,
129
/* Copy the dirty cluster. */
130
s->in_flight++;
131
s->sectors_in_flight += nb_sectors;
132
- trace_mirror_one_iteration(s, sector_num, nb_sectors);
133
+ trace_mirror_one_iteration(s, sector_num * BDRV_SECTOR_SIZE,
134
+ nb_sectors * BDRV_SECTOR_SIZE);
135
136
blk_aio_preadv(source, sector_num * BDRV_SECTOR_SIZE, &op->qiov, 0,
137
mirror_read_complete, op);
138
@@ -XXX,XX +XXX,XX @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
139
if (sector_num < 0) {
140
bdrv_set_dirty_iter(s->dbi, 0);
141
sector_num = bdrv_dirty_iter_next(s->dbi);
142
- trace_mirror_restart_iter(s, bdrv_get_dirty_count(s->dirty_bitmap));
143
+ trace_mirror_restart_iter(s, bdrv_get_dirty_count(s->dirty_bitmap) *
144
+ BDRV_SECTOR_SIZE);
145
assert(sector_num >= 0);
146
}
147
bdrv_dirty_bitmap_unlock(s->dirty_bitmap);
148
149
first_chunk = sector_num / sectors_per_chunk;
150
while (test_bit(first_chunk, s->in_flight_bitmap)) {
151
- trace_mirror_yield_in_flight(s, sector_num, s->in_flight);
152
+ trace_mirror_yield_in_flight(s, sector_num * BDRV_SECTOR_SIZE,
153
+ s->in_flight);
154
mirror_wait_for_io(s);
155
}
156
157
@@ -XXX,XX +XXX,XX @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
158
}
159
160
while (s->in_flight >= MAX_IN_FLIGHT) {
161
- trace_mirror_yield_in_flight(s, sector_num, s->in_flight);
162
+ trace_mirror_yield_in_flight(s, sector_num * BDRV_SECTOR_SIZE,
163
+ s->in_flight);
164
mirror_wait_for_io(s);
165
}
166
167
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn mirror_run(void *opaque)
168
s->common.iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
169
if (s->in_flight >= MAX_IN_FLIGHT || s->buf_free_count == 0 ||
170
(cnt == 0 && s->in_flight > 0)) {
171
- trace_mirror_yield(s, cnt, s->buf_free_count, s->in_flight);
172
+ trace_mirror_yield(s, cnt * BDRV_SECTOR_SIZE,
173
+ s->buf_free_count, s->in_flight);
174
mirror_wait_for_io(s);
175
continue;
176
} else if (cnt != 0) {
177
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn mirror_run(void *opaque)
178
* whether to switch to target check one last time if I/O has
179
* come in the meanwhile, and if not flush the data to disk.
180
*/
181
- trace_mirror_before_drain(s, cnt);
182
+ trace_mirror_before_drain(s, cnt * BDRV_SECTOR_SIZE);
183
184
bdrv_drained_begin(bs);
185
cnt = bdrv_get_dirty_count(s->dirty_bitmap);
186
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn mirror_run(void *opaque)
187
}
188
189
ret = 0;
190
- trace_mirror_before_sleep(s, cnt, s->synced, delay_ns);
191
+ trace_mirror_before_sleep(s, cnt * BDRV_SECTOR_SIZE,
192
+ s->synced, delay_ns);
193
if (!s->synced) {
194
block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, delay_ns);
195
if (block_job_is_cancelled(&s->common)) {
196
diff --git a/block/stream.c b/block/stream.c
197
index XXXXXXX..XXXXXXX 100644
198
--- a/block/stream.c
199
+++ b/block/stream.c
200
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn stream_run(void *opaque)
201
202
copy = (ret == 1);
203
}
204
- trace_stream_one_iteration(s, sector_num, n, ret);
205
+ trace_stream_one_iteration(s, sector_num * BDRV_SECTOR_SIZE,
206
+ n * BDRV_SECTOR_SIZE, ret);
207
if (copy) {
208
ret = stream_populate(blk, sector_num, n, buf);
209
}
210
diff --git a/block/trace-events b/block/trace-events
211
index XXXXXXX..XXXXXXX 100644
212
--- a/block/trace-events
213
+++ b/block/trace-events
214
@@ -XXX,XX +XXX,XX @@ bdrv_co_pwrite_zeroes(void *bs, int64_t offset, int count, int flags) "bs %p off
215
bdrv_co_do_copy_on_readv(void *bs, int64_t offset, unsigned int bytes, int64_t cluster_offset, unsigned int cluster_bytes) "bs %p offset %"PRId64" bytes %u cluster_offset %"PRId64" cluster_bytes %u"
216
217
# block/stream.c
218
-stream_one_iteration(void *s, int64_t sector_num, int nb_sectors, int is_allocated) "s %p sector_num %"PRId64" nb_sectors %d is_allocated %d"
219
+stream_one_iteration(void *s, int64_t offset, uint64_t bytes, int is_allocated) "s %p offset %" PRId64 " bytes %" PRIu64 " is_allocated %d"
220
stream_start(void *bs, void *base, void *s) "bs %p base %p s %p"
221
222
# block/commit.c
223
-commit_one_iteration(void *s, int64_t sector_num, int nb_sectors, int is_allocated) "s %p sector_num %"PRId64" nb_sectors %d is_allocated %d"
224
+commit_one_iteration(void *s, int64_t offset, uint64_t bytes, int is_allocated) "s %p offset %" PRId64 " bytes %" PRIu64 " is_allocated %d"
225
commit_start(void *bs, void *base, void *top, void *s) "bs %p base %p top %p s %p"
226
227
# block/mirror.c
228
@@ -XXX,XX +XXX,XX @@ mirror_restart_iter(void *s, int64_t cnt) "s %p dirty count %"PRId64
229
mirror_before_flush(void *s) "s %p"
230
mirror_before_drain(void *s, int64_t cnt) "s %p dirty count %"PRId64
231
mirror_before_sleep(void *s, int64_t cnt, int synced, uint64_t delay_ns) "s %p dirty count %"PRId64" synced %d delay %"PRIu64"ns"
232
-mirror_one_iteration(void *s, int64_t sector_num, int nb_sectors) "s %p sector_num %"PRId64" nb_sectors %d"
233
-mirror_iteration_done(void *s, int64_t sector_num, int nb_sectors, int ret) "s %p sector_num %"PRId64" nb_sectors %d ret %d"
234
+mirror_one_iteration(void *s, int64_t offset, uint64_t bytes) "s %p offset %" PRId64 " bytes %" PRIu64
235
+mirror_iteration_done(void *s, int64_t offset, uint64_t bytes, int ret) "s %p offset %" PRId64 " bytes %" PRIu64 " ret %d"
236
mirror_yield(void *s, int64_t cnt, int buf_free_count, int in_flight) "s %p dirty count %"PRId64" free buffers %d in_flight %d"
237
-mirror_yield_in_flight(void *s, int64_t sector_num, int in_flight) "s %p sector_num %"PRId64" in_flight %d"
238
+mirror_yield_in_flight(void *s, int64_t offset, int in_flight) "s %p offset %" PRId64 " in_flight %d"
239
240
# block/backup.c
241
-backup_do_cow_enter(void *job, int64_t start, int64_t sector_num, int nb_sectors) "job %p start %"PRId64" sector_num %"PRId64" nb_sectors %d"
242
-backup_do_cow_return(void *job, int64_t sector_num, int nb_sectors, int ret) "job %p sector_num %"PRId64" nb_sectors %d ret %d"
243
+backup_do_cow_enter(void *job, int64_t start, int64_t offset, uint64_t bytes) "job %p start %" PRId64 " offset %" PRId64 " bytes %" PRIu64
244
+backup_do_cow_return(void *job, int64_t offset, uint64_t bytes, int ret) "job %p offset %" PRId64 " bytes %" PRIu64 " ret %d"
245
backup_do_cow_skip(void *job, int64_t start) "job %p start %"PRId64
246
backup_do_cow_process(void *job, int64_t start) "job %p start %"PRId64
247
backup_do_cow_read_fail(void *job, int64_t start, int ret) "job %p start %"PRId64" ret %d"
248
--
249
1.8.3.1
250
251
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
We are gradually converting to byte-based interfaces, as they are
4
easier to reason about than sector-based. Start by converting an
5
internal function (no semantic change).
6
7
Signed-off-by: Eric Blake <eblake@redhat.com>
8
Reviewed-by: John Snow <jsnow@redhat.com>
9
Reviewed-by: Jeff Cody <jcody@redhat.com>
10
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
13
block/stream.c | 11 ++++++-----
14
1 file changed, 6 insertions(+), 5 deletions(-)
15
16
diff --git a/block/stream.c b/block/stream.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/stream.c
19
+++ b/block/stream.c
20
@@ -XXX,XX +XXX,XX @@ typedef struct StreamBlockJob {
21
} StreamBlockJob;
22
23
static int coroutine_fn stream_populate(BlockBackend *blk,
24
- int64_t sector_num, int nb_sectors,
25
+ int64_t offset, uint64_t bytes,
26
void *buf)
27
{
28
struct iovec iov = {
29
.iov_base = buf,
30
- .iov_len = nb_sectors * BDRV_SECTOR_SIZE,
31
+ .iov_len = bytes,
32
};
33
QEMUIOVector qiov;
34
35
+ assert(bytes < SIZE_MAX);
36
qemu_iovec_init_external(&qiov, &iov, 1);
37
38
/* Copy-on-read the unallocated clusters */
39
- return blk_co_preadv(blk, sector_num * BDRV_SECTOR_SIZE, qiov.size, &qiov,
40
- BDRV_REQ_COPY_ON_READ);
41
+ return blk_co_preadv(blk, offset, qiov.size, &qiov, BDRV_REQ_COPY_ON_READ);
42
}
43
44
typedef struct {
45
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn stream_run(void *opaque)
46
trace_stream_one_iteration(s, sector_num * BDRV_SECTOR_SIZE,
47
n * BDRV_SECTOR_SIZE, ret);
48
if (copy) {
49
- ret = stream_populate(blk, sector_num, n, buf);
50
+ ret = stream_populate(blk, sector_num * BDRV_SECTOR_SIZE,
51
+ n * BDRV_SECTOR_SIZE, buf);
52
}
53
if (ret < 0) {
54
BlockErrorAction action =
55
--
56
1.8.3.1
57
58
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
stream_complete() skips the work of rewriting the backing file if
4
the job was cancelled, if data->reached_end is false, or if there
5
was an error detected (non-zero data->ret) during the streaming.
6
But note that in stream_run(), data->reached_end is only set if the
7
loop ran to completion, and data->ret is only 0 in two cases:
8
either the loop ran to completion (possibly by cancellation, but
9
stream_complete checks for that), or we took an early goto out
10
because there is no bs->backing. Thus, we can preserve the same
11
semantics without the use of reached_end, by merely checking for
12
bs->backing (and logically, if there was no backing file, streaming
13
is a no-op, so there is no backing file to rewrite).
14
15
Suggested-by: Kevin Wolf <kwolf@redhat.com>
16
Signed-off-by: Eric Blake <eblake@redhat.com>
17
Reviewed-by: John Snow <jsnow@redhat.com>
18
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
19
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
20
---
21
block/stream.c | 4 +---
22
1 file changed, 1 insertion(+), 3 deletions(-)
23
24
diff --git a/block/stream.c b/block/stream.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/block/stream.c
27
+++ b/block/stream.c
28
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn stream_populate(BlockBackend *blk,
29
30
typedef struct {
31
int ret;
32
- bool reached_end;
33
} StreamCompleteData;
34
35
static void stream_complete(BlockJob *job, void *opaque)
36
@@ -XXX,XX +XXX,XX @@ static void stream_complete(BlockJob *job, void *opaque)
37
BlockDriverState *base = s->base;
38
Error *local_err = NULL;
39
40
- if (!block_job_is_cancelled(&s->common) && data->reached_end &&
41
+ if (!block_job_is_cancelled(&s->common) && bs->backing &&
42
data->ret == 0) {
43
const char *base_id = NULL, *base_fmt = NULL;
44
if (base) {
45
@@ -XXX,XX +XXX,XX @@ out:
46
/* Modify backing chain and close BDSes in main loop */
47
data = g_malloc(sizeof(*data));
48
data->ret = ret;
49
- data->reached_end = sector_num == end;
50
block_job_defer_to_main_loop(&s->common, stream_complete, data);
51
}
52
53
--
54
1.8.3.1
55
56
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
We are gradually converting to byte-based interfaces, as they are
4
easier to reason about than sector-based. Change the internal
5
loop iteration of streaming to track by bytes instead of sectors
6
(although we are still guaranteed that we iterate by steps that
7
are sector-aligned).
8
9
Signed-off-by: Eric Blake <eblake@redhat.com>
10
Reviewed-by: John Snow <jsnow@redhat.com>
11
Reviewed-by: Jeff Cody <jcody@redhat.com>
12
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
15
block/stream.c | 22 +++++++++-------------
16
1 file changed, 9 insertions(+), 13 deletions(-)
17
18
diff --git a/block/stream.c b/block/stream.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/block/stream.c
21
+++ b/block/stream.c
22
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn stream_run(void *opaque)
23
BlockBackend *blk = s->common.blk;
24
BlockDriverState *bs = blk_bs(blk);
25
BlockDriverState *base = s->base;
26
- int64_t sector_num = 0;
27
- int64_t end = -1;
28
+ int64_t offset = 0;
29
uint64_t delay_ns = 0;
30
int error = 0;
31
int ret = 0;
32
- int n = 0;
33
+ int n = 0; /* sectors */
34
void *buf;
35
36
if (!bs->backing) {
37
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn stream_run(void *opaque)
38
goto out;
39
}
40
41
- end = s->common.len >> BDRV_SECTOR_BITS;
42
buf = qemu_blockalign(bs, STREAM_BUFFER_SIZE);
43
44
/* Turn on copy-on-read for the whole block device so that guest read
45
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn stream_run(void *opaque)
46
bdrv_enable_copy_on_read(bs);
47
}
48
49
- for (sector_num = 0; sector_num < end; sector_num += n) {
50
+ for ( ; offset < s->common.len; offset += n * BDRV_SECTOR_SIZE) {
51
bool copy;
52
53
/* Note that even when no rate limit is applied we need to yield
54
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn stream_run(void *opaque)
55
56
copy = false;
57
58
- ret = bdrv_is_allocated(bs, sector_num,
59
+ ret = bdrv_is_allocated(bs, offset / BDRV_SECTOR_SIZE,
60
STREAM_BUFFER_SIZE / BDRV_SECTOR_SIZE, &n);
61
if (ret == 1) {
62
/* Allocated in the top, no need to copy. */
63
} else if (ret >= 0) {
64
/* Copy if allocated in the intermediate images. Limit to the
65
- * known-unallocated area [sector_num, sector_num+n). */
66
+ * known-unallocated area [offset, offset+n*BDRV_SECTOR_SIZE). */
67
ret = bdrv_is_allocated_above(backing_bs(bs), base,
68
- sector_num, n, &n);
69
+ offset / BDRV_SECTOR_SIZE, n, &n);
70
71
/* Finish early if end of backing file has been reached */
72
if (ret == 0 && n == 0) {
73
- n = end - sector_num;
74
+ n = (s->common.len - offset) / BDRV_SECTOR_SIZE;
75
}
76
77
copy = (ret == 1);
78
}
79
- trace_stream_one_iteration(s, sector_num * BDRV_SECTOR_SIZE,
80
- n * BDRV_SECTOR_SIZE, ret);
81
+ trace_stream_one_iteration(s, offset, n * BDRV_SECTOR_SIZE, ret);
82
if (copy) {
83
- ret = stream_populate(blk, sector_num * BDRV_SECTOR_SIZE,
84
- n * BDRV_SECTOR_SIZE, buf);
85
+ ret = stream_populate(blk, offset, n * BDRV_SECTOR_SIZE, buf);
86
}
87
if (ret < 0) {
88
BlockErrorAction action =
89
--
90
1.8.3.1
91
92
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
We are gradually converting to byte-based interfaces, as they are
4
easier to reason about than sector-based. Start by converting an
5
internal function (no semantic change).
6
7
Signed-off-by: Eric Blake <eblake@redhat.com>
8
Reviewed-by: John Snow <jsnow@redhat.com>
9
Reviewed-by: Jeff Cody <jcody@redhat.com>
10
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
13
block/commit.c | 15 ++++++++-------
14
1 file changed, 8 insertions(+), 7 deletions(-)
15
16
diff --git a/block/commit.c b/block/commit.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/commit.c
19
+++ b/block/commit.c
20
@@ -XXX,XX +XXX,XX @@ typedef struct CommitBlockJob {
21
} CommitBlockJob;
22
23
static int coroutine_fn commit_populate(BlockBackend *bs, BlockBackend *base,
24
- int64_t sector_num, int nb_sectors,
25
+ int64_t offset, uint64_t bytes,
26
void *buf)
27
{
28
int ret = 0;
29
QEMUIOVector qiov;
30
struct iovec iov = {
31
.iov_base = buf,
32
- .iov_len = nb_sectors * BDRV_SECTOR_SIZE,
33
+ .iov_len = bytes,
34
};
35
36
+ assert(bytes < SIZE_MAX);
37
qemu_iovec_init_external(&qiov, &iov, 1);
38
39
- ret = blk_co_preadv(bs, sector_num * BDRV_SECTOR_SIZE,
40
- qiov.size, &qiov, 0);
41
+ ret = blk_co_preadv(bs, offset, qiov.size, &qiov, 0);
42
if (ret < 0) {
43
return ret;
44
}
45
46
- ret = blk_co_pwritev(base, sector_num * BDRV_SECTOR_SIZE,
47
- qiov.size, &qiov, 0);
48
+ ret = blk_co_pwritev(base, offset, qiov.size, &qiov, 0);
49
if (ret < 0) {
50
return ret;
51
}
52
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn commit_run(void *opaque)
53
trace_commit_one_iteration(s, sector_num * BDRV_SECTOR_SIZE,
54
n * BDRV_SECTOR_SIZE, ret);
55
if (copy) {
56
- ret = commit_populate(s->top, s->base, sector_num, n, buf);
57
+ ret = commit_populate(s->top, s->base,
58
+ sector_num * BDRV_SECTOR_SIZE,
59
+ n * BDRV_SECTOR_SIZE, buf);
60
bytes_written += n * BDRV_SECTOR_SIZE;
61
}
62
if (ret < 0) {
63
--
64
1.8.3.1
65
66
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
We are gradually converting to byte-based interfaces, as they are
4
easier to reason about than sector-based. Change the internal
5
loop iteration of committing to track by bytes instead of sectors
6
(although we are still guaranteed that we iterate by steps that
7
are sector-aligned).
8
9
Signed-off-by: Eric Blake <eblake@redhat.com>
10
Reviewed-by: John Snow <jsnow@redhat.com>
11
Reviewed-by: Jeff Cody <jcody@redhat.com>
12
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
15
block/commit.c | 16 ++++++----------
16
1 file changed, 6 insertions(+), 10 deletions(-)
17
18
diff --git a/block/commit.c b/block/commit.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/block/commit.c
21
+++ b/block/commit.c
22
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn commit_run(void *opaque)
23
{
24
CommitBlockJob *s = opaque;
25
CommitCompleteData *data;
26
- int64_t sector_num, end;
27
+ int64_t offset;
28
uint64_t delay_ns = 0;
29
int ret = 0;
30
- int n = 0;
31
+ int n = 0; /* sectors */
32
void *buf = NULL;
33
int bytes_written = 0;
34
int64_t base_len;
35
36
ret = s->common.len = blk_getlength(s->top);
37
38
-
39
if (s->common.len < 0) {
40
goto out;
41
}
42
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn commit_run(void *opaque)
43
}
44
}
45
46
- end = s->common.len >> BDRV_SECTOR_BITS;
47
buf = blk_blockalign(s->top, COMMIT_BUFFER_SIZE);
48
49
- for (sector_num = 0; sector_num < end; sector_num += n) {
50
+ for (offset = 0; offset < s->common.len; offset += n * BDRV_SECTOR_SIZE) {
51
bool copy;
52
53
/* Note that even when no rate limit is applied we need to yield
54
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn commit_run(void *opaque)
55
}
56
/* Copy if allocated above the base */
57
ret = bdrv_is_allocated_above(blk_bs(s->top), blk_bs(s->base),
58
- sector_num,
59
+ offset / BDRV_SECTOR_SIZE,
60
COMMIT_BUFFER_SIZE / BDRV_SECTOR_SIZE,
61
&n);
62
copy = (ret == 1);
63
- trace_commit_one_iteration(s, sector_num * BDRV_SECTOR_SIZE,
64
- n * BDRV_SECTOR_SIZE, ret);
65
+ trace_commit_one_iteration(s, offset, n * BDRV_SECTOR_SIZE, ret);
66
if (copy) {
67
- ret = commit_populate(s->top, s->base,
68
- sector_num * BDRV_SECTOR_SIZE,
69
+ ret = commit_populate(s->top, s->base, offset,
70
n * BDRV_SECTOR_SIZE, buf);
71
bytes_written += n * BDRV_SECTOR_SIZE;
72
}
73
--
74
1.8.3.1
75
76
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
We are gradually converting to byte-based interfaces, as they are
4
easier to reason about than sector-based. Continue by converting an
5
internal structure (no semantic change), and all references to the
6
buffer size.
7
8
Add an assertion that our use of s->granularity >> BDRV_SECTOR_BITS
9
(necessary for interaction with sector-based dirty bitmaps, until
10
a later patch converts those to be byte-based) does not suffer from
11
truncation problems.
12
13
[checkpatch has a false positive on use of MIN() in this patch]
14
15
Signed-off-by: Eric Blake <eblake@redhat.com>
16
Reviewed-by: John Snow <jsnow@redhat.com>
17
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
19
---
20
block/mirror.c | 84 +++++++++++++++++++++++++++++-----------------------------
21
1 file changed, 42 insertions(+), 42 deletions(-)
22
23
diff --git a/block/mirror.c b/block/mirror.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/block/mirror.c
26
+++ b/block/mirror.c
27
@@ -XXX,XX +XXX,XX @@
28
29
#define SLICE_TIME 100000000ULL /* ns */
30
#define MAX_IN_FLIGHT 16
31
-#define MAX_IO_SECTORS ((1 << 20) >> BDRV_SECTOR_BITS) /* 1 Mb */
32
-#define DEFAULT_MIRROR_BUF_SIZE \
33
- (MAX_IN_FLIGHT * MAX_IO_SECTORS * BDRV_SECTOR_SIZE)
34
+#define MAX_IO_BYTES (1 << 20) /* 1 Mb */
35
+#define DEFAULT_MIRROR_BUF_SIZE (MAX_IN_FLIGHT * MAX_IO_BYTES)
36
37
/* The mirroring buffer is a list of granularity-sized chunks.
38
* Free chunks are organized in a list.
39
@@ -XXX,XX +XXX,XX @@ typedef struct MirrorBlockJob {
40
uint64_t last_pause_ns;
41
unsigned long *in_flight_bitmap;
42
int in_flight;
43
- int64_t sectors_in_flight;
44
+ int64_t bytes_in_flight;
45
int ret;
46
bool unmap;
47
bool waiting_for_io;
48
- int target_cluster_sectors;
49
+ int target_cluster_size;
50
int max_iov;
51
bool initial_zeroing_ongoing;
52
} MirrorBlockJob;
53
@@ -XXX,XX +XXX,XX @@ typedef struct MirrorBlockJob {
54
typedef struct MirrorOp {
55
MirrorBlockJob *s;
56
QEMUIOVector qiov;
57
- int64_t sector_num;
58
- int nb_sectors;
59
+ int64_t offset;
60
+ uint64_t bytes;
61
} MirrorOp;
62
63
static BlockErrorAction mirror_error_action(MirrorBlockJob *s, bool read,
64
@@ -XXX,XX +XXX,XX @@ static void mirror_iteration_done(MirrorOp *op, int ret)
65
MirrorBlockJob *s = op->s;
66
struct iovec *iov;
67
int64_t chunk_num;
68
- int i, nb_chunks, sectors_per_chunk;
69
+ int i, nb_chunks;
70
71
- trace_mirror_iteration_done(s, op->sector_num * BDRV_SECTOR_SIZE,
72
- op->nb_sectors * BDRV_SECTOR_SIZE, ret);
73
+ trace_mirror_iteration_done(s, op->offset, op->bytes, ret);
74
75
s->in_flight--;
76
- s->sectors_in_flight -= op->nb_sectors;
77
+ s->bytes_in_flight -= op->bytes;
78
iov = op->qiov.iov;
79
for (i = 0; i < op->qiov.niov; i++) {
80
MirrorBuffer *buf = (MirrorBuffer *) iov[i].iov_base;
81
@@ -XXX,XX +XXX,XX @@ static void mirror_iteration_done(MirrorOp *op, int ret)
82
s->buf_free_count++;
83
}
84
85
- sectors_per_chunk = s->granularity >> BDRV_SECTOR_BITS;
86
- chunk_num = op->sector_num / sectors_per_chunk;
87
- nb_chunks = DIV_ROUND_UP(op->nb_sectors, sectors_per_chunk);
88
+ chunk_num = op->offset / s->granularity;
89
+ nb_chunks = DIV_ROUND_UP(op->bytes, s->granularity);
90
bitmap_clear(s->in_flight_bitmap, chunk_num, nb_chunks);
91
if (ret >= 0) {
92
if (s->cow_bitmap) {
93
bitmap_set(s->cow_bitmap, chunk_num, nb_chunks);
94
}
95
if (!s->initial_zeroing_ongoing) {
96
- s->common.offset += (uint64_t)op->nb_sectors * BDRV_SECTOR_SIZE;
97
+ s->common.offset += op->bytes;
98
}
99
}
100
qemu_iovec_destroy(&op->qiov);
101
@@ -XXX,XX +XXX,XX @@ static void mirror_write_complete(void *opaque, int ret)
102
if (ret < 0) {
103
BlockErrorAction action;
104
105
- bdrv_set_dirty_bitmap(s->dirty_bitmap, op->sector_num, op->nb_sectors);
106
+ bdrv_set_dirty_bitmap(s->dirty_bitmap, op->offset >> BDRV_SECTOR_BITS,
107
+ op->bytes >> BDRV_SECTOR_BITS);
108
action = mirror_error_action(s, false, -ret);
109
if (action == BLOCK_ERROR_ACTION_REPORT && s->ret >= 0) {
110
s->ret = ret;
111
@@ -XXX,XX +XXX,XX @@ static void mirror_read_complete(void *opaque, int ret)
112
if (ret < 0) {
113
BlockErrorAction action;
114
115
- bdrv_set_dirty_bitmap(s->dirty_bitmap, op->sector_num, op->nb_sectors);
116
+ bdrv_set_dirty_bitmap(s->dirty_bitmap, op->offset >> BDRV_SECTOR_BITS,
117
+ op->bytes >> BDRV_SECTOR_BITS);
118
action = mirror_error_action(s, true, -ret);
119
if (action == BLOCK_ERROR_ACTION_REPORT && s->ret >= 0) {
120
s->ret = ret;
121
@@ -XXX,XX +XXX,XX @@ static void mirror_read_complete(void *opaque, int ret)
122
123
mirror_iteration_done(op, ret);
124
} else {
125
- blk_aio_pwritev(s->target, op->sector_num * BDRV_SECTOR_SIZE, &op->qiov,
126
+ blk_aio_pwritev(s->target, op->offset, &op->qiov,
127
0, mirror_write_complete, op);
128
}
129
aio_context_release(blk_get_aio_context(s->common.blk));
130
@@ -XXX,XX +XXX,XX @@ static int mirror_cow_align(MirrorBlockJob *s,
131
align_nb_sectors = max_sectors;
132
if (need_cow) {
133
align_nb_sectors = QEMU_ALIGN_DOWN(align_nb_sectors,
134
- s->target_cluster_sectors);
135
+ s->target_cluster_size >>
136
+ BDRV_SECTOR_BITS);
137
}
138
}
139
/* Clipping may result in align_nb_sectors unaligned to chunk boundary, but
140
@@ -XXX,XX +XXX,XX @@ static int mirror_do_read(MirrorBlockJob *s, int64_t sector_num,
141
/* Allocate a MirrorOp that is used as an AIO callback. */
142
op = g_new(MirrorOp, 1);
143
op->s = s;
144
- op->sector_num = sector_num;
145
- op->nb_sectors = nb_sectors;
146
+ op->offset = sector_num * BDRV_SECTOR_SIZE;
147
+ op->bytes = nb_sectors * BDRV_SECTOR_SIZE;
148
149
/* Now make a QEMUIOVector taking enough granularity-sized chunks
150
* from s->buf_free.
151
@@ -XXX,XX +XXX,XX @@ static int mirror_do_read(MirrorBlockJob *s, int64_t sector_num,
152
153
/* Copy the dirty cluster. */
154
s->in_flight++;
155
- s->sectors_in_flight += nb_sectors;
156
+ s->bytes_in_flight += nb_sectors * BDRV_SECTOR_SIZE;
157
trace_mirror_one_iteration(s, sector_num * BDRV_SECTOR_SIZE,
158
nb_sectors * BDRV_SECTOR_SIZE);
159
160
@@ -XXX,XX +XXX,XX @@ static void mirror_do_zero_or_discard(MirrorBlockJob *s,
161
* so the freeing in mirror_iteration_done is nop. */
162
op = g_new0(MirrorOp, 1);
163
op->s = s;
164
- op->sector_num = sector_num;
165
- op->nb_sectors = nb_sectors;
166
+ op->offset = sector_num * BDRV_SECTOR_SIZE;
167
+ op->bytes = nb_sectors * BDRV_SECTOR_SIZE;
168
169
s->in_flight++;
170
- s->sectors_in_flight += nb_sectors;
171
+ s->bytes_in_flight += nb_sectors * BDRV_SECTOR_SIZE;
172
if (is_discard) {
173
blk_aio_pdiscard(s->target, sector_num << BDRV_SECTOR_BITS,
174
- op->nb_sectors << BDRV_SECTOR_BITS,
175
- mirror_write_complete, op);
176
+ op->bytes, mirror_write_complete, op);
177
} else {
178
blk_aio_pwrite_zeroes(s->target, sector_num * BDRV_SECTOR_SIZE,
179
- op->nb_sectors * BDRV_SECTOR_SIZE,
180
- s->unmap ? BDRV_REQ_MAY_UNMAP : 0,
181
+ op->bytes, s->unmap ? BDRV_REQ_MAY_UNMAP : 0,
182
mirror_write_complete, op);
183
}
184
}
185
@@ -XXX,XX +XXX,XX @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
186
int64_t end = s->bdev_length / BDRV_SECTOR_SIZE;
187
int sectors_per_chunk = s->granularity >> BDRV_SECTOR_BITS;
188
bool write_zeroes_ok = bdrv_can_write_zeroes_with_unmap(blk_bs(s->target));
189
- int max_io_sectors = MAX((s->buf_size >> BDRV_SECTOR_BITS) / MAX_IN_FLIGHT,
190
- MAX_IO_SECTORS);
191
+ int max_io_bytes = MAX(s->buf_size / MAX_IN_FLIGHT, MAX_IO_BYTES);
192
193
bdrv_dirty_bitmap_lock(s->dirty_bitmap);
194
sector_num = bdrv_dirty_iter_next(s->dbi);
195
@@ -XXX,XX +XXX,XX @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
196
nb_chunks * sectors_per_chunk,
197
&io_sectors, &file);
198
if (ret < 0) {
199
- io_sectors = MIN(nb_chunks * sectors_per_chunk, max_io_sectors);
200
+ io_sectors = MIN(nb_chunks * sectors_per_chunk,
201
+ max_io_bytes >> BDRV_SECTOR_BITS);
202
} else if (ret & BDRV_BLOCK_DATA) {
203
- io_sectors = MIN(io_sectors, max_io_sectors);
204
+ io_sectors = MIN(io_sectors, max_io_bytes >> BDRV_SECTOR_BITS);
205
}
206
207
io_sectors -= io_sectors % sectors_per_chunk;
208
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn mirror_run(void *opaque)
209
char backing_filename[2]; /* we only need 2 characters because we are only
210
checking for a NULL string */
211
int ret = 0;
212
- int target_cluster_size = BDRV_SECTOR_SIZE;
213
214
if (block_job_is_cancelled(&s->common)) {
215
goto immediate_exit;
216
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn mirror_run(void *opaque)
217
bdrv_get_backing_filename(target_bs, backing_filename,
218
sizeof(backing_filename));
219
if (!bdrv_get_info(target_bs, &bdi) && bdi.cluster_size) {
220
- target_cluster_size = bdi.cluster_size;
221
+ s->target_cluster_size = bdi.cluster_size;
222
+ } else {
223
+ s->target_cluster_size = BDRV_SECTOR_SIZE;
224
}
225
- if (backing_filename[0] && !target_bs->backing
226
- && s->granularity < target_cluster_size) {
227
- s->buf_size = MAX(s->buf_size, target_cluster_size);
228
+ if (backing_filename[0] && !target_bs->backing &&
229
+ s->granularity < s->target_cluster_size) {
230
+ s->buf_size = MAX(s->buf_size, s->target_cluster_size);
231
s->cow_bitmap = bitmap_new(length);
232
}
233
- s->target_cluster_sectors = target_cluster_size >> BDRV_SECTOR_BITS;
234
s->max_iov = MIN(bs->bl.max_iov, target_bs->bl.max_iov);
235
236
s->buf = qemu_try_blockalign(bs, s->buf_size);
237
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn mirror_run(void *opaque)
238
cnt = bdrv_get_dirty_count(s->dirty_bitmap);
239
/* s->common.offset contains the number of bytes already processed so
240
* far, cnt is the number of dirty sectors remaining and
241
- * s->sectors_in_flight is the number of sectors currently being
242
+ * s->bytes_in_flight is the number of bytes currently being
243
* processed; together those are the current total operation length */
244
- s->common.len = s->common.offset +
245
- (cnt + s->sectors_in_flight) * BDRV_SECTOR_SIZE;
246
+ s->common.len = s->common.offset + s->bytes_in_flight +
247
+ cnt * BDRV_SECTOR_SIZE;
248
249
/* Note that even when no rate limit is applied we need to yield
250
* periodically with no pending I/O so that bdrv_drain_all() returns.
251
@@ -XXX,XX +XXX,XX @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
252
}
253
254
assert ((granularity & (granularity - 1)) == 0);
255
+ /* Granularity must be large enough for sector-based dirty bitmap */
256
+ assert(granularity >= BDRV_SECTOR_SIZE);
257
258
if (buf_size < 0) {
259
error_setg(errp, "Invalid parameter 'buf-size'");
260
--
261
1.8.3.1
262
263
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
We are gradually converting to byte-based interfaces, as they are
4
easier to reason about than sector-based. Convert another internal
5
function (no semantic change).
6
7
Signed-off-by: Eric Blake <eblake@redhat.com>
8
Reviewed-by: John Snow <jsnow@redhat.com>
9
Reviewed-by: Jeff Cody <jcody@redhat.com>
10
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
13
block/mirror.c | 20 +++++++++++---------
14
1 file changed, 11 insertions(+), 9 deletions(-)
15
16
diff --git a/block/mirror.c b/block/mirror.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/mirror.c
19
+++ b/block/mirror.c
20
@@ -XXX,XX +XXX,XX @@ static int mirror_do_read(MirrorBlockJob *s, int64_t sector_num,
21
}
22
23
static void mirror_do_zero_or_discard(MirrorBlockJob *s,
24
- int64_t sector_num,
25
- int nb_sectors,
26
+ int64_t offset,
27
+ uint64_t bytes,
28
bool is_discard)
29
{
30
MirrorOp *op;
31
@@ -XXX,XX +XXX,XX @@ static void mirror_do_zero_or_discard(MirrorBlockJob *s,
32
* so the freeing in mirror_iteration_done is nop. */
33
op = g_new0(MirrorOp, 1);
34
op->s = s;
35
- op->offset = sector_num * BDRV_SECTOR_SIZE;
36
- op->bytes = nb_sectors * BDRV_SECTOR_SIZE;
37
+ op->offset = offset;
38
+ op->bytes = bytes;
39
40
s->in_flight++;
41
- s->bytes_in_flight += nb_sectors * BDRV_SECTOR_SIZE;
42
+ s->bytes_in_flight += bytes;
43
if (is_discard) {
44
- blk_aio_pdiscard(s->target, sector_num << BDRV_SECTOR_BITS,
45
+ blk_aio_pdiscard(s->target, offset,
46
op->bytes, mirror_write_complete, op);
47
} else {
48
- blk_aio_pwrite_zeroes(s->target, sector_num * BDRV_SECTOR_SIZE,
49
+ blk_aio_pwrite_zeroes(s->target, offset,
50
op->bytes, s->unmap ? BDRV_REQ_MAY_UNMAP : 0,
51
mirror_write_complete, op);
52
}
53
@@ -XXX,XX +XXX,XX @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
54
break;
55
case MIRROR_METHOD_ZERO:
56
case MIRROR_METHOD_DISCARD:
57
- mirror_do_zero_or_discard(s, sector_num, io_sectors,
58
+ mirror_do_zero_or_discard(s, sector_num * BDRV_SECTOR_SIZE,
59
+ io_sectors * BDRV_SECTOR_SIZE,
60
mirror_method == MIRROR_METHOD_DISCARD);
61
if (write_zeroes_ok) {
62
io_bytes_acct = 0;
63
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
64
continue;
65
}
66
67
- mirror_do_zero_or_discard(s, sector_num, nb_sectors, false);
68
+ mirror_do_zero_or_discard(s, sector_num * BDRV_SECTOR_SIZE,
69
+ nb_sectors * BDRV_SECTOR_SIZE, false);
70
sector_num += nb_sectors;
71
}
72
73
--
74
1.8.3.1
75
76
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
Rather than having a void function that modifies its input
4
in-place as the output, change the signature to reduce a layer
5
of indirection and return the result.
6
7
Suggested-by: John Snow <jsnow@redhat.com>
8
Signed-off-by: Eric Blake <eblake@redhat.com>
9
Reviewed-by: John Snow <jsnow@redhat.com>
10
Reviewed-by: Jeff Cody <jcody@redhat.com>
11
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
14
block/mirror.c | 15 ++++++++-------
15
1 file changed, 8 insertions(+), 7 deletions(-)
16
17
diff --git a/block/mirror.c b/block/mirror.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block/mirror.c
20
+++ b/block/mirror.c
21
@@ -XXX,XX +XXX,XX @@ static void mirror_read_complete(void *opaque, int ret)
22
aio_context_release(blk_get_aio_context(s->common.blk));
23
}
24
25
-static inline void mirror_clip_sectors(MirrorBlockJob *s,
26
- int64_t sector_num,
27
- int *nb_sectors)
28
+static inline int mirror_clip_sectors(MirrorBlockJob *s,
29
+ int64_t sector_num,
30
+ int nb_sectors)
31
{
32
- *nb_sectors = MIN(*nb_sectors,
33
- s->bdev_length / BDRV_SECTOR_SIZE - sector_num);
34
+ return MIN(nb_sectors,
35
+ s->bdev_length / BDRV_SECTOR_SIZE - sector_num);
36
}
37
38
/* Round sector_num and/or nb_sectors to target cluster if COW is needed, and
39
@@ -XXX,XX +XXX,XX @@ static int mirror_cow_align(MirrorBlockJob *s,
40
}
41
/* Clipping may result in align_nb_sectors unaligned to chunk boundary, but
42
* that doesn't matter because it's already the end of source image. */
43
- mirror_clip_sectors(s, align_sector_num, &align_nb_sectors);
44
+ align_nb_sectors = mirror_clip_sectors(s, align_sector_num,
45
+ align_nb_sectors);
46
47
ret = align_sector_num + align_nb_sectors - (*sector_num + *nb_sectors);
48
*sector_num = align_sector_num;
49
@@ -XXX,XX +XXX,XX @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
50
return 0;
51
}
52
53
- mirror_clip_sectors(s, sector_num, &io_sectors);
54
+ io_sectors = mirror_clip_sectors(s, sector_num, io_sectors);
55
switch (mirror_method) {
56
case MIRROR_METHOD_COPY:
57
io_sectors = mirror_do_read(s, sector_num, io_sectors);
58
--
59
1.8.3.1
60
61
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
We are gradually converting to byte-based interfaces, as they are
4
easier to reason about than sector-based. Convert another internal
5
function (no semantic change), and add mirror_clip_bytes() as a
6
counterpart to mirror_clip_sectors(). Some of the conversion is
7
a bit tricky, requiring temporaries to convert between units; it
8
will be cleared up in a following patch.
9
10
Signed-off-by: Eric Blake <eblake@redhat.com>
11
Reviewed-by: John Snow <jsnow@redhat.com>
12
Reviewed-by: Jeff Cody <jcody@redhat.com>
13
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
16
block/mirror.c | 63 ++++++++++++++++++++++++++++++++++------------------------
17
1 file changed, 37 insertions(+), 26 deletions(-)
18
19
diff --git a/block/mirror.c b/block/mirror.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/block/mirror.c
22
+++ b/block/mirror.c
23
@@ -XXX,XX +XXX,XX @@ static void mirror_read_complete(void *opaque, int ret)
24
aio_context_release(blk_get_aio_context(s->common.blk));
25
}
26
27
+/* Clip bytes relative to offset to not exceed end-of-file */
28
+static inline int64_t mirror_clip_bytes(MirrorBlockJob *s,
29
+ int64_t offset,
30
+ int64_t bytes)
31
+{
32
+ return MIN(bytes, s->bdev_length - offset);
33
+}
34
+
35
+/* Clip nb_sectors relative to sector_num to not exceed end-of-file */
36
static inline int mirror_clip_sectors(MirrorBlockJob *s,
37
int64_t sector_num,
38
int nb_sectors)
39
@@ -XXX,XX +XXX,XX @@ static inline int mirror_clip_sectors(MirrorBlockJob *s,
40
s->bdev_length / BDRV_SECTOR_SIZE - sector_num);
41
}
42
43
-/* Round sector_num and/or nb_sectors to target cluster if COW is needed, and
44
- * return the offset of the adjusted tail sector against original. */
45
-static int mirror_cow_align(MirrorBlockJob *s,
46
- int64_t *sector_num,
47
- int *nb_sectors)
48
+/* Round offset and/or bytes to target cluster if COW is needed, and
49
+ * return the offset of the adjusted tail against original. */
50
+static int mirror_cow_align(MirrorBlockJob *s, int64_t *offset,
51
+ unsigned int *bytes)
52
{
53
bool need_cow;
54
int ret = 0;
55
- int chunk_sectors = s->granularity >> BDRV_SECTOR_BITS;
56
- int64_t align_sector_num = *sector_num;
57
- int align_nb_sectors = *nb_sectors;
58
- int max_sectors = chunk_sectors * s->max_iov;
59
+ int64_t align_offset = *offset;
60
+ unsigned int align_bytes = *bytes;
61
+ int max_bytes = s->granularity * s->max_iov;
62
63
- need_cow = !test_bit(*sector_num / chunk_sectors, s->cow_bitmap);
64
- need_cow |= !test_bit((*sector_num + *nb_sectors - 1) / chunk_sectors,
65
+ need_cow = !test_bit(*offset / s->granularity, s->cow_bitmap);
66
+ need_cow |= !test_bit((*offset + *bytes - 1) / s->granularity,
67
s->cow_bitmap);
68
if (need_cow) {
69
- bdrv_round_sectors_to_clusters(blk_bs(s->target), *sector_num,
70
- *nb_sectors, &align_sector_num,
71
- &align_nb_sectors);
72
+ bdrv_round_to_clusters(blk_bs(s->target), *offset, *bytes,
73
+ &align_offset, &align_bytes);
74
}
75
76
- if (align_nb_sectors > max_sectors) {
77
- align_nb_sectors = max_sectors;
78
+ if (align_bytes > max_bytes) {
79
+ align_bytes = max_bytes;
80
if (need_cow) {
81
- align_nb_sectors = QEMU_ALIGN_DOWN(align_nb_sectors,
82
- s->target_cluster_size >>
83
- BDRV_SECTOR_BITS);
84
+ align_bytes = QEMU_ALIGN_DOWN(align_bytes, s->target_cluster_size);
85
}
86
}
87
- /* Clipping may result in align_nb_sectors unaligned to chunk boundary, but
88
+ /* Clipping may result in align_bytes unaligned to chunk boundary, but
89
* that doesn't matter because it's already the end of source image. */
90
- align_nb_sectors = mirror_clip_sectors(s, align_sector_num,
91
- align_nb_sectors);
92
+ align_bytes = mirror_clip_bytes(s, align_offset, align_bytes);
93
94
- ret = align_sector_num + align_nb_sectors - (*sector_num + *nb_sectors);
95
- *sector_num = align_sector_num;
96
- *nb_sectors = align_nb_sectors;
97
+ ret = align_offset + align_bytes - (*offset + *bytes);
98
+ *offset = align_offset;
99
+ *bytes = align_bytes;
100
assert(ret >= 0);
101
return ret;
102
}
103
@@ -XXX,XX +XXX,XX @@ static int mirror_do_read(MirrorBlockJob *s, int64_t sector_num,
104
nb_sectors = MIN(s->buf_size >> BDRV_SECTOR_BITS, nb_sectors);
105
nb_sectors = MIN(max_sectors, nb_sectors);
106
assert(nb_sectors);
107
+ assert(nb_sectors < BDRV_REQUEST_MAX_SECTORS);
108
ret = nb_sectors;
109
110
if (s->cow_bitmap) {
111
- ret += mirror_cow_align(s, &sector_num, &nb_sectors);
112
+ int64_t offset = sector_num * BDRV_SECTOR_SIZE;
113
+ unsigned int bytes = nb_sectors * BDRV_SECTOR_SIZE;
114
+ int gap;
115
+
116
+ gap = mirror_cow_align(s, &offset, &bytes);
117
+ sector_num = offset / BDRV_SECTOR_SIZE;
118
+ nb_sectors = bytes / BDRV_SECTOR_SIZE;
119
+ ret += gap / BDRV_SECTOR_SIZE;
120
}
121
assert(nb_sectors << BDRV_SECTOR_BITS <= s->buf_size);
122
/* The sector range must meet granularity because:
123
--
124
1.8.3.1
125
126
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
We are gradually converting to byte-based interfaces, as they are
4
easier to reason about than sector-based. Convert another internal
5
function, preserving all existing semantics, and adding one more
6
assertion that things are still sector-aligned (so that conversions
7
to sectors in mirror_read_complete don't need to round).
8
9
Signed-off-by: Eric Blake <eblake@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
block/mirror.c | 74 ++++++++++++++++++++++++++--------------------------------
13
1 file changed, 33 insertions(+), 41 deletions(-)
14
15
diff --git a/block/mirror.c b/block/mirror.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/block/mirror.c
18
+++ b/block/mirror.c
19
@@ -XXX,XX +XXX,XX @@ static inline int mirror_clip_sectors(MirrorBlockJob *s,
20
/* Round offset and/or bytes to target cluster if COW is needed, and
21
* return the offset of the adjusted tail against original. */
22
static int mirror_cow_align(MirrorBlockJob *s, int64_t *offset,
23
- unsigned int *bytes)
24
+ uint64_t *bytes)
25
{
26
bool need_cow;
27
int ret = 0;
28
@@ -XXX,XX +XXX,XX @@ static int mirror_cow_align(MirrorBlockJob *s, int64_t *offset,
29
unsigned int align_bytes = *bytes;
30
int max_bytes = s->granularity * s->max_iov;
31
32
+ assert(*bytes < INT_MAX);
33
need_cow = !test_bit(*offset / s->granularity, s->cow_bitmap);
34
need_cow |= !test_bit((*offset + *bytes - 1) / s->granularity,
35
s->cow_bitmap);
36
@@ -XXX,XX +XXX,XX @@ static inline void mirror_wait_for_io(MirrorBlockJob *s)
37
}
38
39
/* Submit async read while handling COW.
40
- * Returns: The number of sectors copied after and including sector_num,
41
- * excluding any sectors copied prior to sector_num due to alignment.
42
- * This will be nb_sectors if no alignment is necessary, or
43
- * (new_end - sector_num) if tail is rounded up or down due to
44
+ * Returns: The number of bytes copied after and including offset,
45
+ * excluding any bytes copied prior to offset due to alignment.
46
+ * This will be @bytes if no alignment is necessary, or
47
+ * (new_end - offset) if tail is rounded up or down due to
48
* alignment or buffer limit.
49
*/
50
-static int mirror_do_read(MirrorBlockJob *s, int64_t sector_num,
51
- int nb_sectors)
52
+static uint64_t mirror_do_read(MirrorBlockJob *s, int64_t offset,
53
+ uint64_t bytes)
54
{
55
BlockBackend *source = s->common.blk;
56
- int sectors_per_chunk, nb_chunks;
57
- int ret;
58
+ int nb_chunks;
59
+ uint64_t ret;
60
MirrorOp *op;
61
- int max_sectors;
62
+ uint64_t max_bytes;
63
64
- sectors_per_chunk = s->granularity >> BDRV_SECTOR_BITS;
65
- max_sectors = sectors_per_chunk * s->max_iov;
66
+ max_bytes = s->granularity * s->max_iov;
67
68
/* We can only handle as much as buf_size at a time. */
69
- nb_sectors = MIN(s->buf_size >> BDRV_SECTOR_BITS, nb_sectors);
70
- nb_sectors = MIN(max_sectors, nb_sectors);
71
- assert(nb_sectors);
72
- assert(nb_sectors < BDRV_REQUEST_MAX_SECTORS);
73
- ret = nb_sectors;
74
+ bytes = MIN(s->buf_size, MIN(max_bytes, bytes));
75
+ assert(bytes);
76
+ assert(bytes < BDRV_REQUEST_MAX_BYTES);
77
+ ret = bytes;
78
79
if (s->cow_bitmap) {
80
- int64_t offset = sector_num * BDRV_SECTOR_SIZE;
81
- unsigned int bytes = nb_sectors * BDRV_SECTOR_SIZE;
82
- int gap;
83
-
84
- gap = mirror_cow_align(s, &offset, &bytes);
85
- sector_num = offset / BDRV_SECTOR_SIZE;
86
- nb_sectors = bytes / BDRV_SECTOR_SIZE;
87
- ret += gap / BDRV_SECTOR_SIZE;
88
+ ret += mirror_cow_align(s, &offset, &bytes);
89
}
90
- assert(nb_sectors << BDRV_SECTOR_BITS <= s->buf_size);
91
- /* The sector range must meet granularity because:
92
+ assert(bytes <= s->buf_size);
93
+ /* The offset is granularity-aligned because:
94
* 1) Caller passes in aligned values;
95
* 2) mirror_cow_align is used only when target cluster is larger. */
96
- assert(!(sector_num % sectors_per_chunk));
97
- nb_chunks = DIV_ROUND_UP(nb_sectors, sectors_per_chunk);
98
+ assert(QEMU_IS_ALIGNED(offset, s->granularity));
99
+ /* The range is sector-aligned, since bdrv_getlength() rounds up. */
100
+ assert(QEMU_IS_ALIGNED(bytes, BDRV_SECTOR_SIZE));
101
+ nb_chunks = DIV_ROUND_UP(bytes, s->granularity);
102
103
while (s->buf_free_count < nb_chunks) {
104
- trace_mirror_yield_in_flight(s, sector_num * BDRV_SECTOR_SIZE,
105
- s->in_flight);
106
+ trace_mirror_yield_in_flight(s, offset, s->in_flight);
107
mirror_wait_for_io(s);
108
}
109
110
/* Allocate a MirrorOp that is used as an AIO callback. */
111
op = g_new(MirrorOp, 1);
112
op->s = s;
113
- op->offset = sector_num * BDRV_SECTOR_SIZE;
114
- op->bytes = nb_sectors * BDRV_SECTOR_SIZE;
115
+ op->offset = offset;
116
+ op->bytes = bytes;
117
118
/* Now make a QEMUIOVector taking enough granularity-sized chunks
119
* from s->buf_free.
120
@@ -XXX,XX +XXX,XX @@ static int mirror_do_read(MirrorBlockJob *s, int64_t sector_num,
121
qemu_iovec_init(&op->qiov, nb_chunks);
122
while (nb_chunks-- > 0) {
123
MirrorBuffer *buf = QSIMPLEQ_FIRST(&s->buf_free);
124
- size_t remaining = nb_sectors * BDRV_SECTOR_SIZE - op->qiov.size;
125
+ size_t remaining = bytes - op->qiov.size;
126
127
QSIMPLEQ_REMOVE_HEAD(&s->buf_free, next);
128
s->buf_free_count--;
129
@@ -XXX,XX +XXX,XX @@ static int mirror_do_read(MirrorBlockJob *s, int64_t sector_num,
130
131
/* Copy the dirty cluster. */
132
s->in_flight++;
133
- s->bytes_in_flight += nb_sectors * BDRV_SECTOR_SIZE;
134
- trace_mirror_one_iteration(s, sector_num * BDRV_SECTOR_SIZE,
135
- nb_sectors * BDRV_SECTOR_SIZE);
136
+ s->bytes_in_flight += bytes;
137
+ trace_mirror_one_iteration(s, offset, bytes);
138
139
- blk_aio_preadv(source, sector_num * BDRV_SECTOR_SIZE, &op->qiov, 0,
140
- mirror_read_complete, op);
141
+ blk_aio_preadv(source, offset, &op->qiov, 0, mirror_read_complete, op);
142
return ret;
143
}
144
145
@@ -XXX,XX +XXX,XX @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
146
io_sectors = mirror_clip_sectors(s, sector_num, io_sectors);
147
switch (mirror_method) {
148
case MIRROR_METHOD_COPY:
149
- io_sectors = mirror_do_read(s, sector_num, io_sectors);
150
- io_bytes_acct = io_sectors * BDRV_SECTOR_SIZE;
151
+ io_bytes_acct = mirror_do_read(s, sector_num * BDRV_SECTOR_SIZE,
152
+ io_sectors * BDRV_SECTOR_SIZE);
153
+ io_sectors = io_bytes_acct / BDRV_SECTOR_SIZE;
154
break;
155
case MIRROR_METHOD_ZERO:
156
case MIRROR_METHOD_DISCARD:
157
--
158
1.8.3.1
159
160
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
We are gradually converting to byte-based interfaces, as they are
4
easier to reason about than sector-based. Change the internal
5
loop iteration of mirroring to track by bytes instead of sectors
6
(although we are still guaranteed that we iterate by steps that
7
are both sector-aligned and multiples of the granularity). Drop
8
the now-unused mirror_clip_sectors().
9
10
Signed-off-by: Eric Blake <eblake@redhat.com>
11
Reviewed-by: John Snow <jsnow@redhat.com>
12
Reviewed-by: Jeff Cody <jcody@redhat.com>
13
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
16
block/mirror.c | 105 +++++++++++++++++++++++++--------------------------------
17
1 file changed, 46 insertions(+), 59 deletions(-)
18
19
diff --git a/block/mirror.c b/block/mirror.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/block/mirror.c
22
+++ b/block/mirror.c
23
@@ -XXX,XX +XXX,XX @@ static inline int64_t mirror_clip_bytes(MirrorBlockJob *s,
24
return MIN(bytes, s->bdev_length - offset);
25
}
26
27
-/* Clip nb_sectors relative to sector_num to not exceed end-of-file */
28
-static inline int mirror_clip_sectors(MirrorBlockJob *s,
29
- int64_t sector_num,
30
- int nb_sectors)
31
-{
32
- return MIN(nb_sectors,
33
- s->bdev_length / BDRV_SECTOR_SIZE - sector_num);
34
-}
35
-
36
/* Round offset and/or bytes to target cluster if COW is needed, and
37
* return the offset of the adjusted tail against original. */
38
static int mirror_cow_align(MirrorBlockJob *s, int64_t *offset,
39
@@ -XXX,XX +XXX,XX @@ static void mirror_do_zero_or_discard(MirrorBlockJob *s,
40
static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
41
{
42
BlockDriverState *source = s->source;
43
- int64_t sector_num, first_chunk;
44
+ int64_t offset, first_chunk;
45
uint64_t delay_ns = 0;
46
/* At least the first dirty chunk is mirrored in one iteration. */
47
int nb_chunks = 1;
48
- int64_t end = s->bdev_length / BDRV_SECTOR_SIZE;
49
int sectors_per_chunk = s->granularity >> BDRV_SECTOR_BITS;
50
bool write_zeroes_ok = bdrv_can_write_zeroes_with_unmap(blk_bs(s->target));
51
int max_io_bytes = MAX(s->buf_size / MAX_IN_FLIGHT, MAX_IO_BYTES);
52
53
bdrv_dirty_bitmap_lock(s->dirty_bitmap);
54
- sector_num = bdrv_dirty_iter_next(s->dbi);
55
- if (sector_num < 0) {
56
+ offset = bdrv_dirty_iter_next(s->dbi) * BDRV_SECTOR_SIZE;
57
+ if (offset < 0) {
58
bdrv_set_dirty_iter(s->dbi, 0);
59
- sector_num = bdrv_dirty_iter_next(s->dbi);
60
+ offset = bdrv_dirty_iter_next(s->dbi) * BDRV_SECTOR_SIZE;
61
trace_mirror_restart_iter(s, bdrv_get_dirty_count(s->dirty_bitmap) *
62
BDRV_SECTOR_SIZE);
63
- assert(sector_num >= 0);
64
+ assert(offset >= 0);
65
}
66
bdrv_dirty_bitmap_unlock(s->dirty_bitmap);
67
68
- first_chunk = sector_num / sectors_per_chunk;
69
+ first_chunk = offset / s->granularity;
70
while (test_bit(first_chunk, s->in_flight_bitmap)) {
71
- trace_mirror_yield_in_flight(s, sector_num * BDRV_SECTOR_SIZE,
72
- s->in_flight);
73
+ trace_mirror_yield_in_flight(s, offset, s->in_flight);
74
mirror_wait_for_io(s);
75
}
76
77
@@ -XXX,XX +XXX,XX @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
78
/* Find the number of consective dirty chunks following the first dirty
79
* one, and wait for in flight requests in them. */
80
bdrv_dirty_bitmap_lock(s->dirty_bitmap);
81
- while (nb_chunks * sectors_per_chunk < (s->buf_size >> BDRV_SECTOR_BITS)) {
82
+ while (nb_chunks * s->granularity < s->buf_size) {
83
int64_t next_dirty;
84
- int64_t next_sector = sector_num + nb_chunks * sectors_per_chunk;
85
- int64_t next_chunk = next_sector / sectors_per_chunk;
86
- if (next_sector >= end ||
87
- !bdrv_get_dirty_locked(source, s->dirty_bitmap, next_sector)) {
88
+ int64_t next_offset = offset + nb_chunks * s->granularity;
89
+ int64_t next_chunk = next_offset / s->granularity;
90
+ if (next_offset >= s->bdev_length ||
91
+ !bdrv_get_dirty_locked(source, s->dirty_bitmap,
92
+ next_offset >> BDRV_SECTOR_BITS)) {
93
break;
94
}
95
if (test_bit(next_chunk, s->in_flight_bitmap)) {
96
break;
97
}
98
99
- next_dirty = bdrv_dirty_iter_next(s->dbi);
100
- if (next_dirty > next_sector || next_dirty < 0) {
101
+ next_dirty = bdrv_dirty_iter_next(s->dbi) * BDRV_SECTOR_SIZE;
102
+ if (next_dirty > next_offset || next_dirty < 0) {
103
/* The bitmap iterator's cache is stale, refresh it */
104
- bdrv_set_dirty_iter(s->dbi, next_sector);
105
- next_dirty = bdrv_dirty_iter_next(s->dbi);
106
+ bdrv_set_dirty_iter(s->dbi, next_offset >> BDRV_SECTOR_BITS);
107
+ next_dirty = bdrv_dirty_iter_next(s->dbi) * BDRV_SECTOR_SIZE;
108
}
109
- assert(next_dirty == next_sector);
110
+ assert(next_dirty == next_offset);
111
nb_chunks++;
112
}
113
114
@@ -XXX,XX +XXX,XX @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
115
* calling bdrv_get_block_status_above could yield - if some blocks are
116
* marked dirty in this window, we need to know.
117
*/
118
- bdrv_reset_dirty_bitmap_locked(s->dirty_bitmap, sector_num,
119
- nb_chunks * sectors_per_chunk);
120
+ bdrv_reset_dirty_bitmap_locked(s->dirty_bitmap, offset >> BDRV_SECTOR_BITS,
121
+ nb_chunks * sectors_per_chunk);
122
bdrv_dirty_bitmap_unlock(s->dirty_bitmap);
123
124
- bitmap_set(s->in_flight_bitmap, sector_num / sectors_per_chunk, nb_chunks);
125
- while (nb_chunks > 0 && sector_num < end) {
126
+ bitmap_set(s->in_flight_bitmap, offset / s->granularity, nb_chunks);
127
+ while (nb_chunks > 0 && offset < s->bdev_length) {
128
int64_t ret;
129
int io_sectors;
130
+ unsigned int io_bytes;
131
int64_t io_bytes_acct;
132
BlockDriverState *file;
133
enum MirrorMethod {
134
@@ -XXX,XX +XXX,XX @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
135
MIRROR_METHOD_DISCARD
136
} mirror_method = MIRROR_METHOD_COPY;
137
138
- assert(!(sector_num % sectors_per_chunk));
139
- ret = bdrv_get_block_status_above(source, NULL, sector_num,
140
+ assert(!(offset % s->granularity));
141
+ ret = bdrv_get_block_status_above(source, NULL,
142
+ offset >> BDRV_SECTOR_BITS,
143
nb_chunks * sectors_per_chunk,
144
&io_sectors, &file);
145
+ io_bytes = io_sectors * BDRV_SECTOR_SIZE;
146
if (ret < 0) {
147
- io_sectors = MIN(nb_chunks * sectors_per_chunk,
148
- max_io_bytes >> BDRV_SECTOR_BITS);
149
+ io_bytes = MIN(nb_chunks * s->granularity, max_io_bytes);
150
} else if (ret & BDRV_BLOCK_DATA) {
151
- io_sectors = MIN(io_sectors, max_io_bytes >> BDRV_SECTOR_BITS);
152
+ io_bytes = MIN(io_bytes, max_io_bytes);
153
}
154
155
- io_sectors -= io_sectors % sectors_per_chunk;
156
- if (io_sectors < sectors_per_chunk) {
157
- io_sectors = sectors_per_chunk;
158
+ io_bytes -= io_bytes % s->granularity;
159
+ if (io_bytes < s->granularity) {
160
+ io_bytes = s->granularity;
161
} else if (ret >= 0 && !(ret & BDRV_BLOCK_DATA)) {
162
- int64_t target_sector_num;
163
- int target_nb_sectors;
164
- bdrv_round_sectors_to_clusters(blk_bs(s->target), sector_num,
165
- io_sectors, &target_sector_num,
166
- &target_nb_sectors);
167
- if (target_sector_num == sector_num &&
168
- target_nb_sectors == io_sectors) {
169
+ int64_t target_offset;
170
+ unsigned int target_bytes;
171
+ bdrv_round_to_clusters(blk_bs(s->target), offset, io_bytes,
172
+ &target_offset, &target_bytes);
173
+ if (target_offset == offset &&
174
+ target_bytes == io_bytes) {
175
mirror_method = ret & BDRV_BLOCK_ZERO ?
176
MIRROR_METHOD_ZERO :
177
MIRROR_METHOD_DISCARD;
178
@@ -XXX,XX +XXX,XX @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
179
}
180
181
while (s->in_flight >= MAX_IN_FLIGHT) {
182
- trace_mirror_yield_in_flight(s, sector_num * BDRV_SECTOR_SIZE,
183
- s->in_flight);
184
+ trace_mirror_yield_in_flight(s, offset, s->in_flight);
185
mirror_wait_for_io(s);
186
}
187
188
@@ -XXX,XX +XXX,XX @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
189
return 0;
190
}
191
192
- io_sectors = mirror_clip_sectors(s, sector_num, io_sectors);
193
+ io_bytes = mirror_clip_bytes(s, offset, io_bytes);
194
switch (mirror_method) {
195
case MIRROR_METHOD_COPY:
196
- io_bytes_acct = mirror_do_read(s, sector_num * BDRV_SECTOR_SIZE,
197
- io_sectors * BDRV_SECTOR_SIZE);
198
- io_sectors = io_bytes_acct / BDRV_SECTOR_SIZE;
199
+ io_bytes = io_bytes_acct = mirror_do_read(s, offset, io_bytes);
200
break;
201
case MIRROR_METHOD_ZERO:
202
case MIRROR_METHOD_DISCARD:
203
- mirror_do_zero_or_discard(s, sector_num * BDRV_SECTOR_SIZE,
204
- io_sectors * BDRV_SECTOR_SIZE,
205
+ mirror_do_zero_or_discard(s, offset, io_bytes,
206
mirror_method == MIRROR_METHOD_DISCARD);
207
if (write_zeroes_ok) {
208
io_bytes_acct = 0;
209
} else {
210
- io_bytes_acct = io_sectors * BDRV_SECTOR_SIZE;
211
+ io_bytes_acct = io_bytes;
212
}
213
break;
214
default:
215
abort();
216
}
217
- assert(io_sectors);
218
- sector_num += io_sectors;
219
- nb_chunks -= DIV_ROUND_UP(io_sectors, sectors_per_chunk);
220
+ assert(io_bytes);
221
+ offset += io_bytes;
222
+ nb_chunks -= DIV_ROUND_UP(io_bytes, s->granularity);
223
if (s->common.speed) {
224
delay_ns = ratelimit_calculate_delay(&s->limit, io_bytes_acct);
225
}
226
--
227
1.8.3.1
228
229
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
Now that the last user [mirror_iteration()] has converted to using
4
bytes, we no longer need a function to round sectors to clusters.
5
6
Signed-off-by: Eric Blake <eblake@redhat.com>
7
Reviewed-by: John Snow <jsnow@redhat.com>
8
Reviewed-by: Jeff Cody <jcody@redhat.com>
9
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
block/io.c | 21 ---------------------
13
include/block/block.h | 4 ----
14
2 files changed, 25 deletions(-)
15
16
diff --git a/block/io.c b/block/io.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/io.c
19
+++ b/block/io.c
20
@@ -XXX,XX +XXX,XX @@ static void mark_request_serialising(BdrvTrackedRequest *req, uint64_t align)
21
}
22
23
/**
24
- * Round a region to cluster boundaries (sector-based)
25
- */
26
-void bdrv_round_sectors_to_clusters(BlockDriverState *bs,
27
- int64_t sector_num, int nb_sectors,
28
- int64_t *cluster_sector_num,
29
- int *cluster_nb_sectors)
30
-{
31
- BlockDriverInfo bdi;
32
-
33
- if (bdrv_get_info(bs, &bdi) < 0 || bdi.cluster_size == 0) {
34
- *cluster_sector_num = sector_num;
35
- *cluster_nb_sectors = nb_sectors;
36
- } else {
37
- int64_t c = bdi.cluster_size / BDRV_SECTOR_SIZE;
38
- *cluster_sector_num = QEMU_ALIGN_DOWN(sector_num, c);
39
- *cluster_nb_sectors = QEMU_ALIGN_UP(sector_num - *cluster_sector_num +
40
- nb_sectors, c);
41
- }
42
-}
43
-
44
-/**
45
* Round a region to cluster boundaries
46
*/
47
void bdrv_round_to_clusters(BlockDriverState *bs,
48
diff --git a/include/block/block.h b/include/block/block.h
49
index XXXXXXX..XXXXXXX 100644
50
--- a/include/block/block.h
51
+++ b/include/block/block.h
52
@@ -XXX,XX +XXX,XX @@ const char *bdrv_get_device_or_node_name(const BlockDriverState *bs);
53
int bdrv_get_flags(BlockDriverState *bs);
54
int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
55
ImageInfoSpecific *bdrv_get_specific_info(BlockDriverState *bs);
56
-void bdrv_round_sectors_to_clusters(BlockDriverState *bs,
57
- int64_t sector_num, int nb_sectors,
58
- int64_t *cluster_sector_num,
59
- int *cluster_nb_sectors);
60
void bdrv_round_to_clusters(BlockDriverState *bs,
61
int64_t offset, unsigned int bytes,
62
int64_t *cluster_offset,
63
--
64
1.8.3.1
65
66
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
We are gradually converting to byte-based interfaces, as they are
4
easier to reason about than sector-based. Continue by converting an
5
internal structure (no semantic change), and all references to
6
tracking progress. Drop a redundant local variable bytes_per_cluster.
7
8
Signed-off-by: Eric Blake <eblake@redhat.com>
9
Reviewed-by: John Snow <jsnow@redhat.com>
10
Reviewed-by: Jeff Cody <jcody@redhat.com>
11
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
14
block/backup.c | 33 +++++++++++++++------------------
15
1 file changed, 15 insertions(+), 18 deletions(-)
16
17
diff --git a/block/backup.c b/block/backup.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block/backup.c
20
+++ b/block/backup.c
21
@@ -XXX,XX +XXX,XX @@ typedef struct BackupBlockJob {
22
BlockdevOnError on_source_error;
23
BlockdevOnError on_target_error;
24
CoRwlock flush_rwlock;
25
- uint64_t sectors_read;
26
+ uint64_t bytes_read;
27
unsigned long *done_bitmap;
28
int64_t cluster_size;
29
bool compress;
30
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job,
31
void *bounce_buffer = NULL;
32
int ret = 0;
33
int64_t sectors_per_cluster = cluster_size_sectors(job);
34
- int64_t bytes_per_cluster = sectors_per_cluster * BDRV_SECTOR_SIZE;
35
- int64_t start, end;
36
- int n;
37
+ int64_t start, end; /* clusters */
38
+ int n; /* bytes */
39
40
qemu_co_rwlock_rdlock(&job->flush_rwlock);
41
42
start = sector_num / sectors_per_cluster;
43
end = DIV_ROUND_UP(sector_num + nb_sectors, sectors_per_cluster);
44
45
- trace_backup_do_cow_enter(job, start * bytes_per_cluster,
46
+ trace_backup_do_cow_enter(job, start * job->cluster_size,
47
sector_num * BDRV_SECTOR_SIZE,
48
nb_sectors * BDRV_SECTOR_SIZE);
49
50
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job,
51
52
for (; start < end; start++) {
53
if (test_bit(start, job->done_bitmap)) {
54
- trace_backup_do_cow_skip(job, start * bytes_per_cluster);
55
+ trace_backup_do_cow_skip(job, start * job->cluster_size);
56
continue; /* already copied */
57
}
58
59
- trace_backup_do_cow_process(job, start * bytes_per_cluster);
60
+ trace_backup_do_cow_process(job, start * job->cluster_size);
61
62
- n = MIN(sectors_per_cluster,
63
- job->common.len / BDRV_SECTOR_SIZE -
64
- start * sectors_per_cluster);
65
+ n = MIN(job->cluster_size,
66
+ job->common.len - start * job->cluster_size);
67
68
if (!bounce_buffer) {
69
bounce_buffer = blk_blockalign(blk, job->cluster_size);
70
}
71
iov.iov_base = bounce_buffer;
72
- iov.iov_len = n * BDRV_SECTOR_SIZE;
73
+ iov.iov_len = n;
74
qemu_iovec_init_external(&bounce_qiov, &iov, 1);
75
76
ret = blk_co_preadv(blk, start * job->cluster_size,
77
bounce_qiov.size, &bounce_qiov,
78
is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0);
79
if (ret < 0) {
80
- trace_backup_do_cow_read_fail(job, start * bytes_per_cluster, ret);
81
+ trace_backup_do_cow_read_fail(job, start * job->cluster_size, ret);
82
if (error_is_read) {
83
*error_is_read = true;
84
}
85
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job,
86
job->compress ? BDRV_REQ_WRITE_COMPRESSED : 0);
87
}
88
if (ret < 0) {
89
- trace_backup_do_cow_write_fail(job, start * bytes_per_cluster, ret);
90
+ trace_backup_do_cow_write_fail(job, start * job->cluster_size, ret);
91
if (error_is_read) {
92
*error_is_read = false;
93
}
94
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job,
95
/* Publish progress, guest I/O counts as progress too. Note that the
96
* offset field is an opaque progress value, it is not a disk offset.
97
*/
98
- job->sectors_read += n;
99
- job->common.offset += n * BDRV_SECTOR_SIZE;
100
+ job->bytes_read += n;
101
+ job->common.offset += n;
102
}
103
104
out:
105
@@ -XXX,XX +XXX,XX @@ static bool coroutine_fn yield_and_check(BackupBlockJob *job)
106
*/
107
if (job->common.speed) {
108
uint64_t delay_ns = ratelimit_calculate_delay(&job->limit,
109
- job->sectors_read *
110
- BDRV_SECTOR_SIZE);
111
- job->sectors_read = 0;
112
+ job->bytes_read);
113
+ job->bytes_read = 0;
114
block_job_sleep_ns(&job->common, QEMU_CLOCK_REALTIME, delay_ns);
115
} else {
116
block_job_sleep_ns(&job->common, QEMU_CLOCK_REALTIME, 0);
117
--
118
1.8.3.1
119
120
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
We are gradually converting to byte-based interfaces, as they are
4
easier to reason about than sector-based. Continue by converting
5
the public interface to backup jobs (no semantic change), including
6
a change to CowRequest to track by bytes instead of cluster indices.
7
8
Note that this does not change the difference between the public
9
interface (starting point, and size of the subsequent range) and
10
the internal interface (starting and end points).
11
12
Signed-off-by: Eric Blake <eblake@redhat.com>
13
Reviewed-by: John Snow <jsnow@redhat.com>
14
Reviewed-by: Xie Changlong <xiechanglong@cmss.chinamobile.com>
15
Reviewed-by: Jeff Cody <jcody@redhat.com>
16
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
---
19
block/backup.c | 31 +++++++++++++++----------------
20
block/replication.c | 12 ++++++++----
21
include/block/block_backup.h | 11 +++++------
22
3 files changed, 28 insertions(+), 26 deletions(-)
23
24
diff --git a/block/backup.c b/block/backup.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/block/backup.c
27
+++ b/block/backup.c
28
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn wait_for_overlapping_requests(BackupBlockJob *job,
29
do {
30
retry = false;
31
QLIST_FOREACH(req, &job->inflight_reqs, list) {
32
- if (end > req->start && start < req->end) {
33
+ if (end > req->start_byte && start < req->end_byte) {
34
qemu_co_queue_wait(&req->wait_queue, NULL);
35
retry = true;
36
break;
37
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn wait_for_overlapping_requests(BackupBlockJob *job,
38
39
/* Keep track of an in-flight request */
40
static void cow_request_begin(CowRequest *req, BackupBlockJob *job,
41
- int64_t start, int64_t end)
42
+ int64_t start, int64_t end)
43
{
44
- req->start = start;
45
- req->end = end;
46
+ req->start_byte = start;
47
+ req->end_byte = end;
48
qemu_co_queue_init(&req->wait_queue);
49
QLIST_INSERT_HEAD(&job->inflight_reqs, req, list);
50
}
51
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job,
52
sector_num * BDRV_SECTOR_SIZE,
53
nb_sectors * BDRV_SECTOR_SIZE);
54
55
- wait_for_overlapping_requests(job, start, end);
56
- cow_request_begin(&cow_request, job, start, end);
57
+ wait_for_overlapping_requests(job, start * job->cluster_size,
58
+ end * job->cluster_size);
59
+ cow_request_begin(&cow_request, job, start * job->cluster_size,
60
+ end * job->cluster_size);
61
62
for (; start < end; start++) {
63
if (test_bit(start, job->done_bitmap)) {
64
@@ -XXX,XX +XXX,XX @@ void backup_do_checkpoint(BlockJob *job, Error **errp)
65
bitmap_zero(backup_job->done_bitmap, len);
66
}
67
68
-void backup_wait_for_overlapping_requests(BlockJob *job, int64_t sector_num,
69
- int nb_sectors)
70
+void backup_wait_for_overlapping_requests(BlockJob *job, int64_t offset,
71
+ uint64_t bytes)
72
{
73
BackupBlockJob *backup_job = container_of(job, BackupBlockJob, common);
74
- int64_t sectors_per_cluster = cluster_size_sectors(backup_job);
75
int64_t start, end;
76
77
assert(job->driver->job_type == BLOCK_JOB_TYPE_BACKUP);
78
79
- start = sector_num / sectors_per_cluster;
80
- end = DIV_ROUND_UP(sector_num + nb_sectors, sectors_per_cluster);
81
+ start = QEMU_ALIGN_DOWN(offset, backup_job->cluster_size);
82
+ end = QEMU_ALIGN_UP(offset + bytes, backup_job->cluster_size);
83
wait_for_overlapping_requests(backup_job, start, end);
84
}
85
86
void backup_cow_request_begin(CowRequest *req, BlockJob *job,
87
- int64_t sector_num,
88
- int nb_sectors)
89
+ int64_t offset, uint64_t bytes)
90
{
91
BackupBlockJob *backup_job = container_of(job, BackupBlockJob, common);
92
- int64_t sectors_per_cluster = cluster_size_sectors(backup_job);
93
int64_t start, end;
94
95
assert(job->driver->job_type == BLOCK_JOB_TYPE_BACKUP);
96
97
- start = sector_num / sectors_per_cluster;
98
- end = DIV_ROUND_UP(sector_num + nb_sectors, sectors_per_cluster);
99
+ start = QEMU_ALIGN_DOWN(offset, backup_job->cluster_size);
100
+ end = QEMU_ALIGN_UP(offset + bytes, backup_job->cluster_size);
101
cow_request_begin(req, backup_job, start, end);
102
}
103
104
diff --git a/block/replication.c b/block/replication.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/block/replication.c
107
+++ b/block/replication.c
108
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int replication_co_readv(BlockDriverState *bs,
109
}
110
111
if (job) {
112
- backup_wait_for_overlapping_requests(child->bs->job, sector_num,
113
- remaining_sectors);
114
- backup_cow_request_begin(&req, child->bs->job, sector_num,
115
- remaining_sectors);
116
+ uint64_t remaining_bytes = remaining_sectors * BDRV_SECTOR_SIZE;
117
+
118
+ backup_wait_for_overlapping_requests(child->bs->job,
119
+ sector_num * BDRV_SECTOR_SIZE,
120
+ remaining_bytes);
121
+ backup_cow_request_begin(&req, child->bs->job,
122
+ sector_num * BDRV_SECTOR_SIZE,
123
+ remaining_bytes);
124
ret = bdrv_co_readv(bs->file, sector_num, remaining_sectors,
125
qiov);
126
backup_cow_request_end(&req);
127
diff --git a/include/block/block_backup.h b/include/block/block_backup.h
128
index XXXXXXX..XXXXXXX 100644
129
--- a/include/block/block_backup.h
130
+++ b/include/block/block_backup.h
131
@@ -XXX,XX +XXX,XX @@
132
#include "block/block_int.h"
133
134
typedef struct CowRequest {
135
- int64_t start;
136
- int64_t end;
137
+ int64_t start_byte;
138
+ int64_t end_byte;
139
QLIST_ENTRY(CowRequest) list;
140
CoQueue wait_queue; /* coroutines blocked on this request */
141
} CowRequest;
142
143
-void backup_wait_for_overlapping_requests(BlockJob *job, int64_t sector_num,
144
- int nb_sectors);
145
+void backup_wait_for_overlapping_requests(BlockJob *job, int64_t offset,
146
+ uint64_t bytes);
147
void backup_cow_request_begin(CowRequest *req, BlockJob *job,
148
- int64_t sector_num,
149
- int nb_sectors);
150
+ int64_t offset, uint64_t bytes);
151
void backup_cow_request_end(CowRequest *req);
152
153
void backup_do_checkpoint(BlockJob *job, Error **errp);
154
--
155
1.8.3.1
156
157
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
We are gradually converting to byte-based interfaces, as they are
4
easier to reason about than sector-based. Convert another internal
5
function (no semantic change).
6
7
Signed-off-by: Eric Blake <eblake@redhat.com>
8
Reviewed-by: John Snow <jsnow@redhat.com>
9
Reviewed-by: Jeff Cody <jcody@redhat.com>
10
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
13
block/backup.c | 62 ++++++++++++++++++++++++----------------------------------
14
1 file changed, 26 insertions(+), 36 deletions(-)
15
16
diff --git a/block/backup.c b/block/backup.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/backup.c
19
+++ b/block/backup.c
20
@@ -XXX,XX +XXX,XX @@ static void cow_request_end(CowRequest *req)
21
}
22
23
static int coroutine_fn backup_do_cow(BackupBlockJob *job,
24
- int64_t sector_num, int nb_sectors,
25
+ int64_t offset, uint64_t bytes,
26
bool *error_is_read,
27
bool is_write_notifier)
28
{
29
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job,
30
QEMUIOVector bounce_qiov;
31
void *bounce_buffer = NULL;
32
int ret = 0;
33
- int64_t sectors_per_cluster = cluster_size_sectors(job);
34
- int64_t start, end; /* clusters */
35
+ int64_t start, end; /* bytes */
36
int n; /* bytes */
37
38
qemu_co_rwlock_rdlock(&job->flush_rwlock);
39
40
- start = sector_num / sectors_per_cluster;
41
- end = DIV_ROUND_UP(sector_num + nb_sectors, sectors_per_cluster);
42
+ start = QEMU_ALIGN_DOWN(offset, job->cluster_size);
43
+ end = QEMU_ALIGN_UP(bytes + offset, job->cluster_size);
44
45
- trace_backup_do_cow_enter(job, start * job->cluster_size,
46
- sector_num * BDRV_SECTOR_SIZE,
47
- nb_sectors * BDRV_SECTOR_SIZE);
48
+ trace_backup_do_cow_enter(job, start, offset, bytes);
49
50
- wait_for_overlapping_requests(job, start * job->cluster_size,
51
- end * job->cluster_size);
52
- cow_request_begin(&cow_request, job, start * job->cluster_size,
53
- end * job->cluster_size);
54
+ wait_for_overlapping_requests(job, start, end);
55
+ cow_request_begin(&cow_request, job, start, end);
56
57
- for (; start < end; start++) {
58
- if (test_bit(start, job->done_bitmap)) {
59
- trace_backup_do_cow_skip(job, start * job->cluster_size);
60
+ for (; start < end; start += job->cluster_size) {
61
+ if (test_bit(start / job->cluster_size, job->done_bitmap)) {
62
+ trace_backup_do_cow_skip(job, start);
63
continue; /* already copied */
64
}
65
66
- trace_backup_do_cow_process(job, start * job->cluster_size);
67
+ trace_backup_do_cow_process(job, start);
68
69
- n = MIN(job->cluster_size,
70
- job->common.len - start * job->cluster_size);
71
+ n = MIN(job->cluster_size, job->common.len - start);
72
73
if (!bounce_buffer) {
74
bounce_buffer = blk_blockalign(blk, job->cluster_size);
75
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job,
76
iov.iov_len = n;
77
qemu_iovec_init_external(&bounce_qiov, &iov, 1);
78
79
- ret = blk_co_preadv(blk, start * job->cluster_size,
80
- bounce_qiov.size, &bounce_qiov,
81
+ ret = blk_co_preadv(blk, start, bounce_qiov.size, &bounce_qiov,
82
is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0);
83
if (ret < 0) {
84
- trace_backup_do_cow_read_fail(job, start * job->cluster_size, ret);
85
+ trace_backup_do_cow_read_fail(job, start, ret);
86
if (error_is_read) {
87
*error_is_read = true;
88
}
89
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job,
90
}
91
92
if (buffer_is_zero(iov.iov_base, iov.iov_len)) {
93
- ret = blk_co_pwrite_zeroes(job->target, start * job->cluster_size,
94
+ ret = blk_co_pwrite_zeroes(job->target, start,
95
bounce_qiov.size, BDRV_REQ_MAY_UNMAP);
96
} else {
97
- ret = blk_co_pwritev(job->target, start * job->cluster_size,
98
+ ret = blk_co_pwritev(job->target, start,
99
bounce_qiov.size, &bounce_qiov,
100
job->compress ? BDRV_REQ_WRITE_COMPRESSED : 0);
101
}
102
if (ret < 0) {
103
- trace_backup_do_cow_write_fail(job, start * job->cluster_size, ret);
104
+ trace_backup_do_cow_write_fail(job, start, ret);
105
if (error_is_read) {
106
*error_is_read = false;
107
}
108
goto out;
109
}
110
111
- set_bit(start, job->done_bitmap);
112
+ set_bit(start / job->cluster_size, job->done_bitmap);
113
114
/* Publish progress, guest I/O counts as progress too. Note that the
115
* offset field is an opaque progress value, it is not a disk offset.
116
@@ -XXX,XX +XXX,XX @@ out:
117
118
cow_request_end(&cow_request);
119
120
- trace_backup_do_cow_return(job, sector_num * BDRV_SECTOR_SIZE,
121
- nb_sectors * BDRV_SECTOR_SIZE, ret);
122
+ trace_backup_do_cow_return(job, offset, bytes, ret);
123
124
qemu_co_rwlock_unlock(&job->flush_rwlock);
125
126
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_before_write_notify(
127
{
128
BackupBlockJob *job = container_of(notifier, BackupBlockJob, before_write);
129
BdrvTrackedRequest *req = opaque;
130
- int64_t sector_num = req->offset >> BDRV_SECTOR_BITS;
131
- int nb_sectors = req->bytes >> BDRV_SECTOR_BITS;
132
133
assert(req->bs == blk_bs(job->common.blk));
134
- assert((req->offset & (BDRV_SECTOR_SIZE - 1)) == 0);
135
- assert((req->bytes & (BDRV_SECTOR_SIZE - 1)) == 0);
136
+ assert(QEMU_IS_ALIGNED(req->offset, BDRV_SECTOR_SIZE));
137
+ assert(QEMU_IS_ALIGNED(req->bytes, BDRV_SECTOR_SIZE));
138
139
- return backup_do_cow(job, sector_num, nb_sectors, NULL, true);
140
+ return backup_do_cow(job, req->offset, req->bytes, NULL, true);
141
}
142
143
static void backup_set_speed(BlockJob *job, int64_t speed, Error **errp)
144
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_run_incremental(BackupBlockJob *job)
145
if (yield_and_check(job)) {
146
goto out;
147
}
148
- ret = backup_do_cow(job, cluster * sectors_per_cluster,
149
- sectors_per_cluster, &error_is_read,
150
+ ret = backup_do_cow(job, cluster * job->cluster_size,
151
+ job->cluster_size, &error_is_read,
152
false);
153
if ((ret < 0) &&
154
backup_error_action(job, error_is_read, -ret) ==
155
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn backup_run(void *opaque)
156
if (alloced < 0) {
157
ret = alloced;
158
} else {
159
- ret = backup_do_cow(job, start * sectors_per_cluster,
160
- sectors_per_cluster, &error_is_read,
161
+ ret = backup_do_cow(job, start * job->cluster_size,
162
+ job->cluster_size, &error_is_read,
163
false);
164
}
165
if (ret < 0) {
166
--
167
1.8.3.1
168
169
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
We are gradually converting to byte-based interfaces, as they are
4
easier to reason about than sector-based. Change the internal
5
loop iteration of backups to track by bytes instead of sectors
6
(although we are still guaranteed that we iterate by steps that
7
are cluster-aligned).
8
9
Signed-off-by: Eric Blake <eblake@redhat.com>
10
Reviewed-by: John Snow <jsnow@redhat.com>
11
Reviewed-by: Jeff Cody <jcody@redhat.com>
12
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
15
block/backup.c | 32 +++++++++++++++-----------------
16
1 file changed, 15 insertions(+), 17 deletions(-)
17
18
diff --git a/block/backup.c b/block/backup.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/block/backup.c
21
+++ b/block/backup.c
22
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_run_incremental(BackupBlockJob *job)
23
int ret = 0;
24
int clusters_per_iter;
25
uint32_t granularity;
26
- int64_t sector;
27
+ int64_t offset;
28
int64_t cluster;
29
int64_t end;
30
int64_t last_cluster = -1;
31
- int64_t sectors_per_cluster = cluster_size_sectors(job);
32
BdrvDirtyBitmapIter *dbi;
33
34
granularity = bdrv_dirty_bitmap_granularity(job->sync_bitmap);
35
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_run_incremental(BackupBlockJob *job)
36
dbi = bdrv_dirty_iter_new(job->sync_bitmap, 0);
37
38
/* Find the next dirty sector(s) */
39
- while ((sector = bdrv_dirty_iter_next(dbi)) != -1) {
40
- cluster = sector / sectors_per_cluster;
41
+ while ((offset = bdrv_dirty_iter_next(dbi) * BDRV_SECTOR_SIZE) >= 0) {
42
+ cluster = offset / job->cluster_size;
43
44
/* Fake progress updates for any clusters we skipped */
45
if (cluster != last_cluster + 1) {
46
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_run_incremental(BackupBlockJob *job)
47
/* If the bitmap granularity is smaller than the backup granularity,
48
* we need to advance the iterator pointer to the next cluster. */
49
if (granularity < job->cluster_size) {
50
- bdrv_set_dirty_iter(dbi, cluster * sectors_per_cluster);
51
+ bdrv_set_dirty_iter(dbi,
52
+ cluster * job->cluster_size / BDRV_SECTOR_SIZE);
53
}
54
55
last_cluster = cluster - 1;
56
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn backup_run(void *opaque)
57
BackupBlockJob *job = opaque;
58
BackupCompleteData *data;
59
BlockDriverState *bs = blk_bs(job->common.blk);
60
- int64_t start, end;
61
+ int64_t offset;
62
int64_t sectors_per_cluster = cluster_size_sectors(job);
63
int ret = 0;
64
65
QLIST_INIT(&job->inflight_reqs);
66
qemu_co_rwlock_init(&job->flush_rwlock);
67
68
- start = 0;
69
- end = DIV_ROUND_UP(job->common.len, job->cluster_size);
70
-
71
- job->done_bitmap = bitmap_new(end);
72
+ job->done_bitmap = bitmap_new(DIV_ROUND_UP(job->common.len,
73
+ job->cluster_size));
74
75
job->before_write.notify = backup_before_write_notify;
76
bdrv_add_before_write_notifier(bs, &job->before_write);
77
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn backup_run(void *opaque)
78
ret = backup_run_incremental(job);
79
} else {
80
/* Both FULL and TOP SYNC_MODE's require copying.. */
81
- for (; start < end; start++) {
82
+ for (offset = 0; offset < job->common.len;
83
+ offset += job->cluster_size) {
84
bool error_is_read;
85
int alloced = 0;
86
87
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn backup_run(void *opaque)
88
* needed but at some point that is always the case. */
89
alloced =
90
bdrv_is_allocated(bs,
91
- start * sectors_per_cluster + i,
92
- sectors_per_cluster - i, &n);
93
+ (offset >> BDRV_SECTOR_BITS) + i,
94
+ sectors_per_cluster - i, &n);
95
i += n;
96
97
if (alloced || n == 0) {
98
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn backup_run(void *opaque)
99
if (alloced < 0) {
100
ret = alloced;
101
} else {
102
- ret = backup_do_cow(job, start * job->cluster_size,
103
- job->cluster_size, &error_is_read,
104
- false);
105
+ ret = backup_do_cow(job, offset, job->cluster_size,
106
+ &error_is_read, false);
107
}
108
if (ret < 0) {
109
/* Depending on error action, fail now or retry cluster */
110
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn backup_run(void *opaque)
111
if (action == BLOCK_ERROR_ACTION_REPORT) {
112
break;
113
} else {
114
- start--;
115
+ offset -= job->cluster_size;
116
continue;
117
}
118
}
119
--
120
1.8.3.1
121
122
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
We are gradually moving away from sector-based interfaces, towards
4
byte-based. In the common case, allocation is unlikely to ever use
5
values that are not naturally sector-aligned, but it is possible
6
that byte-based values will let us be more precise about allocation
7
at the end of an unaligned file that can do byte-based access.
8
9
Changing the signature of the function to use int64_t *pnum ensures
10
that the compiler enforces that all callers are updated. For now,
11
the io.c layer still assert()s that all callers are sector-aligned
12
on input and that *pnum is sector-aligned on return to the caller,
13
but that can be relaxed when a later patch implements byte-based
14
block status. Therefore, this code adds usages like
15
DIV_ROUND_UP(,BDRV_SECTOR_SIZE) to callers that still want aligned
16
values, where the call might reasonbly give non-aligned results
17
in the future; on the other hand, no rounding is needed for callers
18
that should just continue to work with byte alignment.
19
20
For the most part this patch is just the addition of scaling at the
21
callers followed by inverse scaling at bdrv_is_allocated(). But
22
some code, particularly bdrv_commit(), gets a lot simpler because it
23
no longer has to mess with sectors; also, it is now possible to pass
24
NULL if the caller does not care how much of the image is allocated
25
beyond the initial offset. Leave comments where we can further
26
simplify once a later patch eliminates the need for sector-aligned
27
requests through bdrv_is_allocated().
28
29
For ease of review, bdrv_is_allocated_above() will be tackled
30
separately.
31
32
Signed-off-by: Eric Blake <eblake@redhat.com>
33
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
34
---
35
block/backup.c | 17 ++++---------
36
block/commit.c | 21 +++++++---------
37
block/io.c | 54 ++++++++++++++++++++++++++-------------
38
block/stream.c | 7 ++++--
39
block/vvfat.c | 34 ++++++++++++++-----------
40
include/block/block.h | 4 +--
41
migration/block.c | 16 +++++++-----
42
qemu-img.c | 8 +++++-
43
qemu-io-cmds.c | 70 +++++++++++++++++++++++----------------------------
44
9 files changed, 126 insertions(+), 105 deletions(-)
45
46
diff --git a/block/backup.c b/block/backup.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/block/backup.c
49
+++ b/block/backup.c
50
@@ -XXX,XX +XXX,XX @@ typedef struct BackupBlockJob {
51
QLIST_HEAD(, CowRequest) inflight_reqs;
52
} BackupBlockJob;
53
54
-/* Size of a cluster in sectors, instead of bytes. */
55
-static inline int64_t cluster_size_sectors(BackupBlockJob *job)
56
-{
57
- return job->cluster_size / BDRV_SECTOR_SIZE;
58
-}
59
-
60
/* See if in-flight requests overlap and wait for them to complete */
61
static void coroutine_fn wait_for_overlapping_requests(BackupBlockJob *job,
62
int64_t start,
63
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn backup_run(void *opaque)
64
BackupCompleteData *data;
65
BlockDriverState *bs = blk_bs(job->common.blk);
66
int64_t offset;
67
- int64_t sectors_per_cluster = cluster_size_sectors(job);
68
int ret = 0;
69
70
QLIST_INIT(&job->inflight_reqs);
71
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn backup_run(void *opaque)
72
}
73
74
if (job->sync_mode == MIRROR_SYNC_MODE_TOP) {
75
- int i, n;
76
+ int i;
77
+ int64_t n;
78
79
/* Check to see if these blocks are already in the
80
* backing file. */
81
82
- for (i = 0; i < sectors_per_cluster;) {
83
+ for (i = 0; i < job->cluster_size;) {
84
/* bdrv_is_allocated() only returns true/false based
85
* on the first set of sectors it comes across that
86
* are are all in the same state.
87
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn backup_run(void *opaque)
88
* backup cluster length. We end up copying more than
89
* needed but at some point that is always the case. */
90
alloced =
91
- bdrv_is_allocated(bs,
92
- (offset >> BDRV_SECTOR_BITS) + i,
93
- sectors_per_cluster - i, &n);
94
+ bdrv_is_allocated(bs, offset + i,
95
+ job->cluster_size - i, &n);
96
i += n;
97
98
if (alloced || n == 0) {
99
diff --git a/block/commit.c b/block/commit.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/block/commit.c
102
+++ b/block/commit.c
103
@@ -XXX,XX +XXX,XX @@ fail:
104
}
105
106
107
-#define COMMIT_BUF_SECTORS 2048
108
+#define COMMIT_BUF_SIZE (2048 * BDRV_SECTOR_SIZE)
109
110
/* commit COW file into the raw image */
111
int bdrv_commit(BlockDriverState *bs)
112
@@ -XXX,XX +XXX,XX @@ int bdrv_commit(BlockDriverState *bs)
113
BlockDriverState *backing_file_bs = NULL;
114
BlockDriverState *commit_top_bs = NULL;
115
BlockDriver *drv = bs->drv;
116
- int64_t sector, total_sectors, length, backing_length;
117
- int n, ro, open_flags;
118
+ int64_t offset, length, backing_length;
119
+ int ro, open_flags;
120
+ int64_t n;
121
int ret = 0;
122
uint8_t *buf = NULL;
123
Error *local_err = NULL;
124
@@ -XXX,XX +XXX,XX @@ int bdrv_commit(BlockDriverState *bs)
125
}
126
}
127
128
- total_sectors = length >> BDRV_SECTOR_BITS;
129
-
130
/* blk_try_blockalign() for src will choose an alignment that works for
131
* backing as well, so no need to compare the alignment manually. */
132
- buf = blk_try_blockalign(src, COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE);
133
+ buf = blk_try_blockalign(src, COMMIT_BUF_SIZE);
134
if (buf == NULL) {
135
ret = -ENOMEM;
136
goto ro_cleanup;
137
}
138
139
- for (sector = 0; sector < total_sectors; sector += n) {
140
- ret = bdrv_is_allocated(bs, sector, COMMIT_BUF_SECTORS, &n);
141
+ for (offset = 0; offset < length; offset += n) {
142
+ ret = bdrv_is_allocated(bs, offset, COMMIT_BUF_SIZE, &n);
143
if (ret < 0) {
144
goto ro_cleanup;
145
}
146
if (ret) {
147
- ret = blk_pread(src, sector * BDRV_SECTOR_SIZE, buf,
148
- n * BDRV_SECTOR_SIZE);
149
+ ret = blk_pread(src, offset, buf, n);
150
if (ret < 0) {
151
goto ro_cleanup;
152
}
153
154
- ret = blk_pwrite(backing, sector * BDRV_SECTOR_SIZE, buf,
155
- n * BDRV_SECTOR_SIZE, 0);
156
+ ret = blk_pwrite(backing, offset, buf, n, 0);
157
if (ret < 0) {
158
goto ro_cleanup;
159
}
160
diff --git a/block/io.c b/block/io.c
161
index XXXXXXX..XXXXXXX 100644
162
--- a/block/io.c
163
+++ b/block/io.c
164
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_aligned_preadv(BdrvChild *child,
165
}
166
167
if (flags & BDRV_REQ_COPY_ON_READ) {
168
- int64_t start_sector = offset >> BDRV_SECTOR_BITS;
169
- int64_t end_sector = DIV_ROUND_UP(offset + bytes, BDRV_SECTOR_SIZE);
170
- unsigned int nb_sectors = end_sector - start_sector;
171
- int pnum;
172
+ /* TODO: Simplify further once bdrv_is_allocated no longer
173
+ * requires sector alignment */
174
+ int64_t start = QEMU_ALIGN_DOWN(offset, BDRV_SECTOR_SIZE);
175
+ int64_t end = QEMU_ALIGN_UP(offset + bytes, BDRV_SECTOR_SIZE);
176
+ int64_t pnum;
177
178
- ret = bdrv_is_allocated(bs, start_sector, nb_sectors, &pnum);
179
+ ret = bdrv_is_allocated(bs, start, end - start, &pnum);
180
if (ret < 0) {
181
goto out;
182
}
183
184
- if (!ret || pnum != nb_sectors) {
185
+ if (!ret || pnum != end - start) {
186
ret = bdrv_co_do_copy_on_readv(child, offset, bytes, qiov);
187
goto out;
188
}
189
@@ -XXX,XX +XXX,XX @@ int64_t bdrv_get_block_status(BlockDriverState *bs,
190
sector_num, nb_sectors, pnum, file);
191
}
192
193
-int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num,
194
- int nb_sectors, int *pnum)
195
+int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t offset,
196
+ int64_t bytes, int64_t *pnum)
197
{
198
BlockDriverState *file;
199
- int64_t ret = bdrv_get_block_status(bs, sector_num, nb_sectors, pnum,
200
- &file);
201
+ int64_t sector_num = offset >> BDRV_SECTOR_BITS;
202
+ int nb_sectors = bytes >> BDRV_SECTOR_BITS;
203
+ int64_t ret;
204
+ int psectors;
205
+
206
+ assert(QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE));
207
+ assert(QEMU_IS_ALIGNED(bytes, BDRV_SECTOR_SIZE) && bytes < INT_MAX);
208
+ ret = bdrv_get_block_status(bs, sector_num, nb_sectors, &psectors,
209
+ &file);
210
if (ret < 0) {
211
return ret;
212
}
213
+ if (pnum) {
214
+ *pnum = psectors * BDRV_SECTOR_SIZE;
215
+ }
216
return !!(ret & BDRV_BLOCK_ALLOCATED);
217
}
218
219
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num,
220
*
221
* Return true if the given sector is allocated in any image between
222
* BASE and TOP (inclusive). BASE can be NULL to check if the given
223
- * sector is allocated in any image of the chain. Return false otherwise.
224
+ * sector is allocated in any image of the chain. Return false otherwise,
225
+ * or negative errno on failure.
226
*
227
* 'pnum' is set to the number of sectors (including and immediately following
228
* the specified sector) that are known to be in the same
229
@@ -XXX,XX +XXX,XX @@ int bdrv_is_allocated_above(BlockDriverState *top,
230
231
intermediate = top;
232
while (intermediate && intermediate != base) {
233
- int pnum_inter;
234
- ret = bdrv_is_allocated(intermediate, sector_num, nb_sectors,
235
+ int64_t pnum_inter;
236
+ int psectors_inter;
237
+
238
+ ret = bdrv_is_allocated(intermediate, sector_num * BDRV_SECTOR_SIZE,
239
+ nb_sectors * BDRV_SECTOR_SIZE,
240
&pnum_inter);
241
if (ret < 0) {
242
return ret;
243
- } else if (ret) {
244
- *pnum = pnum_inter;
245
+ }
246
+ assert(pnum_inter < INT_MAX * BDRV_SECTOR_SIZE);
247
+ psectors_inter = pnum_inter >> BDRV_SECTOR_BITS;
248
+ if (ret) {
249
+ *pnum = psectors_inter;
250
return 1;
251
}
252
253
@@ -XXX,XX +XXX,XX @@ int bdrv_is_allocated_above(BlockDriverState *top,
254
*
255
* [sector_num+x, nr_sectors] allocated.
256
*/
257
- if (n > pnum_inter &&
258
+ if (n > psectors_inter &&
259
(intermediate == top ||
260
- sector_num + pnum_inter < intermediate->total_sectors)) {
261
- n = pnum_inter;
262
+ sector_num + psectors_inter < intermediate->total_sectors)) {
263
+ n = psectors_inter;
264
}
265
266
intermediate = backing_bs(intermediate);
267
diff --git a/block/stream.c b/block/stream.c
268
index XXXXXXX..XXXXXXX 100644
269
--- a/block/stream.c
270
+++ b/block/stream.c
271
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn stream_run(void *opaque)
272
273
for ( ; offset < s->common.len; offset += n * BDRV_SECTOR_SIZE) {
274
bool copy;
275
+ int64_t count = 0;
276
277
/* Note that even when no rate limit is applied we need to yield
278
* with no pending I/O here so that bdrv_drain_all() returns.
279
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn stream_run(void *opaque)
280
281
copy = false;
282
283
- ret = bdrv_is_allocated(bs, offset / BDRV_SECTOR_SIZE,
284
- STREAM_BUFFER_SIZE / BDRV_SECTOR_SIZE, &n);
285
+ ret = bdrv_is_allocated(bs, offset, STREAM_BUFFER_SIZE, &count);
286
+ /* TODO relax this once bdrv_is_allocated does not enforce sectors */
287
+ assert(QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE));
288
+ n = count >> BDRV_SECTOR_BITS;
289
if (ret == 1) {
290
/* Allocated in the top, no need to copy. */
291
} else if (ret >= 0) {
292
diff --git a/block/vvfat.c b/block/vvfat.c
293
index XXXXXXX..XXXXXXX 100644
294
--- a/block/vvfat.c
295
+++ b/block/vvfat.c
296
@@ -XXX,XX +XXX,XX @@ static int vvfat_read(BlockDriverState *bs, int64_t sector_num,
297
if (sector_num >= bs->total_sectors)
298
return -1;
299
if (s->qcow) {
300
- int n;
301
+ int64_t n;
302
int ret;
303
- ret = bdrv_is_allocated(s->qcow->bs, sector_num,
304
- nb_sectors - i, &n);
305
+ ret = bdrv_is_allocated(s->qcow->bs, sector_num * BDRV_SECTOR_SIZE,
306
+ (nb_sectors - i) * BDRV_SECTOR_SIZE, &n);
307
if (ret < 0) {
308
return ret;
309
}
310
if (ret) {
311
- DLOG(fprintf(stderr, "sectors %d+%d allocated\n",
312
- (int)sector_num, n));
313
- if (bdrv_read(s->qcow, sector_num, buf + i * 0x200, n)) {
314
+ DLOG(fprintf(stderr, "sectors %" PRId64 "+%" PRId64
315
+ " allocated\n", sector_num,
316
+ n >> BDRV_SECTOR_BITS));
317
+ if (bdrv_read(s->qcow, sector_num, buf + i * 0x200,
318
+ n >> BDRV_SECTOR_BITS)) {
319
return -1;
320
}
321
- i += n - 1;
322
- sector_num += n - 1;
323
+ i += (n >> BDRV_SECTOR_BITS) - 1;
324
+ sector_num += (n >> BDRV_SECTOR_BITS) - 1;
325
continue;
326
}
327
-DLOG(fprintf(stderr, "sector %d not allocated\n", (int)sector_num));
328
+ DLOG(fprintf(stderr, "sector %" PRId64 " not allocated\n",
329
+ sector_num));
330
}
331
if (sector_num < s->offset_to_root_dir) {
332
if (sector_num < s->offset_to_fat) {
333
@@ -XXX,XX +XXX,XX @@ static inline bool cluster_was_modified(BDRVVVFATState *s,
334
uint32_t cluster_num)
335
{
336
int was_modified = 0;
337
- int i, dummy;
338
+ int i;
339
340
if (s->qcow == NULL) {
341
return 0;
342
@@ -XXX,XX +XXX,XX @@ static inline bool cluster_was_modified(BDRVVVFATState *s,
343
344
for (i = 0; !was_modified && i < s->sectors_per_cluster; i++) {
345
was_modified = bdrv_is_allocated(s->qcow->bs,
346
- cluster2sector(s, cluster_num) + i,
347
- 1, &dummy);
348
+ (cluster2sector(s, cluster_num) +
349
+ i) * BDRV_SECTOR_SIZE,
350
+ BDRV_SECTOR_SIZE, NULL);
351
}
352
353
/*
354
@@ -XXX,XX +XXX,XX @@ static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s,
355
}
356
357
if (copy_it) {
358
- int i, dummy;
359
+ int i;
360
/*
361
* This is horribly inefficient, but that is okay, since
362
* it is rarely executed, if at all.
363
@@ -XXX,XX +XXX,XX @@ static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s,
364
for (i = 0; i < s->sectors_per_cluster; i++) {
365
int res;
366
367
- res = bdrv_is_allocated(s->qcow->bs, offset + i, 1, &dummy);
368
+ res = bdrv_is_allocated(s->qcow->bs,
369
+ (offset + i) * BDRV_SECTOR_SIZE,
370
+ BDRV_SECTOR_SIZE, NULL);
371
if (res < 0) {
372
return -1;
373
}
374
diff --git a/include/block/block.h b/include/block/block.h
375
index XXXXXXX..XXXXXXX 100644
376
--- a/include/block/block.h
377
+++ b/include/block/block.h
378
@@ -XXX,XX +XXX,XX @@ int64_t bdrv_get_block_status_above(BlockDriverState *bs,
379
int64_t sector_num,
380
int nb_sectors, int *pnum,
381
BlockDriverState **file);
382
-int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
383
- int *pnum);
384
+int bdrv_is_allocated(BlockDriverState *bs, int64_t offset, int64_t bytes,
385
+ int64_t *pnum);
386
int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
387
int64_t sector_num, int nb_sectors, int *pnum);
388
389
diff --git a/migration/block.c b/migration/block.c
390
index XXXXXXX..XXXXXXX 100644
391
--- a/migration/block.c
392
+++ b/migration/block.c
393
@@ -XXX,XX +XXX,XX @@
394
#define BLK_MIG_FLAG_PROGRESS 0x04
395
#define BLK_MIG_FLAG_ZERO_BLOCK 0x08
396
397
-#define MAX_IS_ALLOCATED_SEARCH 65536
398
+#define MAX_IS_ALLOCATED_SEARCH (65536 * BDRV_SECTOR_SIZE)
399
400
#define MAX_INFLIGHT_IO 512
401
402
@@ -XXX,XX +XXX,XX @@ static int mig_save_device_bulk(QEMUFile *f, BlkMigDevState *bmds)
403
BlockBackend *bb = bmds->blk;
404
BlkMigBlock *blk;
405
int nr_sectors;
406
+ int64_t count;
407
408
if (bmds->shared_base) {
409
qemu_mutex_lock_iothread();
410
aio_context_acquire(blk_get_aio_context(bb));
411
- /* Skip unallocated sectors; intentionally treats failure as
412
- * an allocated sector */
413
+ /* Skip unallocated sectors; intentionally treats failure or
414
+ * partial sector as an allocated sector */
415
while (cur_sector < total_sectors &&
416
- !bdrv_is_allocated(blk_bs(bb), cur_sector,
417
- MAX_IS_ALLOCATED_SEARCH, &nr_sectors)) {
418
- cur_sector += nr_sectors;
419
+ !bdrv_is_allocated(blk_bs(bb), cur_sector * BDRV_SECTOR_SIZE,
420
+ MAX_IS_ALLOCATED_SEARCH, &count)) {
421
+ if (count < BDRV_SECTOR_SIZE) {
422
+ break;
423
+ }
424
+ cur_sector += count >> BDRV_SECTOR_BITS;
425
}
426
aio_context_release(blk_get_aio_context(bb));
427
qemu_mutex_unlock_iothread();
428
diff --git a/qemu-img.c b/qemu-img.c
429
index XXXXXXX..XXXXXXX 100644
430
--- a/qemu-img.c
431
+++ b/qemu-img.c
432
@@ -XXX,XX +XXX,XX @@ static int img_rebase(int argc, char **argv)
433
int64_t new_backing_num_sectors = 0;
434
uint64_t sector;
435
int n;
436
+ int64_t count;
437
float local_progress = 0;
438
439
buf_old = blk_blockalign(blk, IO_BUF_SIZE);
440
@@ -XXX,XX +XXX,XX @@ static int img_rebase(int argc, char **argv)
441
}
442
443
/* If the cluster is allocated, we don't need to take action */
444
- ret = bdrv_is_allocated(bs, sector, n, &n);
445
+ ret = bdrv_is_allocated(bs, sector << BDRV_SECTOR_BITS,
446
+ n << BDRV_SECTOR_BITS, &count);
447
if (ret < 0) {
448
error_report("error while reading image metadata: %s",
449
strerror(-ret));
450
goto out;
451
}
452
+ /* TODO relax this once bdrv_is_allocated does not enforce
453
+ * sector alignment */
454
+ assert(QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE));
455
+ n = count >> BDRV_SECTOR_BITS;
456
if (ret) {
457
continue;
458
}
459
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
460
index XXXXXXX..XXXXXXX 100644
461
--- a/qemu-io-cmds.c
462
+++ b/qemu-io-cmds.c
463
@@ -XXX,XX +XXX,XX @@ out:
464
static int alloc_f(BlockBackend *blk, int argc, char **argv)
465
{
466
BlockDriverState *bs = blk_bs(blk);
467
- int64_t offset, sector_num, nb_sectors, remaining, count;
468
+ int64_t offset, start, remaining, count;
469
char s1[64];
470
- int num, ret;
471
- int64_t sum_alloc;
472
+ int ret;
473
+ int64_t num, sum_alloc;
474
475
- offset = cvtnum(argv[1]);
476
+ start = offset = cvtnum(argv[1]);
477
if (offset < 0) {
478
print_cvtnum_err(offset, argv[1]);
479
return 0;
480
@@ -XXX,XX +XXX,XX @@ static int alloc_f(BlockBackend *blk, int argc, char **argv)
481
count);
482
return 0;
483
}
484
- nb_sectors = count >> BDRV_SECTOR_BITS;
485
486
- remaining = nb_sectors;
487
+ remaining = count;
488
sum_alloc = 0;
489
- sector_num = offset >> 9;
490
while (remaining) {
491
- ret = bdrv_is_allocated(bs, sector_num, remaining, &num);
492
+ ret = bdrv_is_allocated(bs, offset, remaining, &num);
493
if (ret < 0) {
494
printf("is_allocated failed: %s\n", strerror(-ret));
495
return 0;
496
}
497
- sector_num += num;
498
+ offset += num;
499
remaining -= num;
500
if (ret) {
501
sum_alloc += num;
502
}
503
if (num == 0) {
504
- nb_sectors -= remaining;
505
+ count -= remaining;
506
remaining = 0;
507
}
508
}
509
510
- cvtstr(offset, s1, sizeof(s1));
511
+ cvtstr(start, s1, sizeof(s1));
512
513
printf("%"PRId64"/%"PRId64" bytes allocated at offset %s\n",
514
- sum_alloc << BDRV_SECTOR_BITS, nb_sectors << BDRV_SECTOR_BITS, s1);
515
+ sum_alloc, count, s1);
516
return 0;
517
}
518
519
@@ -XXX,XX +XXX,XX @@ static const cmdinfo_t alloc_cmd = {
520
};
521
522
523
-static int map_is_allocated(BlockDriverState *bs, int64_t sector_num,
524
- int64_t nb_sectors, int64_t *pnum)
525
+static int map_is_allocated(BlockDriverState *bs, int64_t offset,
526
+ int64_t bytes, int64_t *pnum)
527
{
528
- int num, num_checked;
529
+ int64_t num;
530
+ int num_checked;
531
int ret, firstret;
532
533
- num_checked = MIN(nb_sectors, INT_MAX);
534
- ret = bdrv_is_allocated(bs, sector_num, num_checked, &num);
535
+ num_checked = MIN(bytes, BDRV_REQUEST_MAX_BYTES);
536
+ ret = bdrv_is_allocated(bs, offset, num_checked, &num);
537
if (ret < 0) {
538
return ret;
539
}
540
@@ -XXX,XX +XXX,XX @@ static int map_is_allocated(BlockDriverState *bs, int64_t sector_num,
541
firstret = ret;
542
*pnum = num;
543
544
- while (nb_sectors > 0 && ret == firstret) {
545
- sector_num += num;
546
- nb_sectors -= num;
547
+ while (bytes > 0 && ret == firstret) {
548
+ offset += num;
549
+ bytes -= num;
550
551
- num_checked = MIN(nb_sectors, INT_MAX);
552
- ret = bdrv_is_allocated(bs, sector_num, num_checked, &num);
553
+ num_checked = MIN(bytes, BDRV_REQUEST_MAX_BYTES);
554
+ ret = bdrv_is_allocated(bs, offset, num_checked, &num);
555
if (ret == firstret && num) {
556
*pnum += num;
557
} else {
558
@@ -XXX,XX +XXX,XX @@ static int map_is_allocated(BlockDriverState *bs, int64_t sector_num,
559
560
static int map_f(BlockBackend *blk, int argc, char **argv)
561
{
562
- int64_t offset;
563
- int64_t nb_sectors, total_sectors;
564
+ int64_t offset, bytes;
565
char s1[64], s2[64];
566
int64_t num;
567
int ret;
568
const char *retstr;
569
570
offset = 0;
571
- total_sectors = blk_nb_sectors(blk);
572
- if (total_sectors < 0) {
573
- error_report("Failed to query image length: %s",
574
- strerror(-total_sectors));
575
+ bytes = blk_getlength(blk);
576
+ if (bytes < 0) {
577
+ error_report("Failed to query image length: %s", strerror(-bytes));
578
return 0;
579
}
580
581
- nb_sectors = total_sectors;
582
-
583
- do {
584
- ret = map_is_allocated(blk_bs(blk), offset, nb_sectors, &num);
585
+ while (bytes) {
586
+ ret = map_is_allocated(blk_bs(blk), offset, bytes, &num);
587
if (ret < 0) {
588
error_report("Failed to get allocation status: %s", strerror(-ret));
589
return 0;
590
@@ -XXX,XX +XXX,XX @@ static int map_f(BlockBackend *blk, int argc, char **argv)
591
}
592
593
retstr = ret ? " allocated" : "not allocated";
594
- cvtstr(num << BDRV_SECTOR_BITS, s1, sizeof(s1));
595
- cvtstr(offset << BDRV_SECTOR_BITS, s2, sizeof(s2));
596
+ cvtstr(num, s1, sizeof(s1));
597
+ cvtstr(offset, s2, sizeof(s2));
598
printf("%s (0x%" PRIx64 ") bytes %s at offset %s (0x%" PRIx64 ")\n",
599
- s1, num << BDRV_SECTOR_BITS, retstr,
600
- s2, offset << BDRV_SECTOR_BITS);
601
+ s1, num, retstr, s2, offset);
602
603
offset += num;
604
- nb_sectors -= num;
605
- } while (offset < total_sectors);
606
+ bytes -= num;
607
+ }
608
609
return 0;
610
}
611
--
612
1.8.3.1
613
614
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
bdrv_is_allocated_above() was relying on intermediate->total_sectors,
4
which is a field that can have stale contents depending on the value
5
of intermediate->has_variable_length. An audit shows that we are safe
6
(we were first calling through bdrv_co_get_block_status() which in
7
turn calls bdrv_nb_sectors() and therefore just refreshed the current
8
length), but it's nicer to favor our accessor functions to avoid having
9
to repeat such an audit, even if it means refresh_total_sectors() is
10
called more frequently.
11
12
Suggested-by: John Snow <jsnow@redhat.com>
13
Signed-off-by: Eric Blake <eblake@redhat.com>
14
Reviewed-by: Manos Pitsidianakis <el13635@mail.ntua.gr>
15
Reviewed-by: Jeff Cody <jcody@redhat.com>
16
Reviewed-by: John Snow <jsnow@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
---
19
block/io.c | 14 ++++++--------
20
1 file changed, 6 insertions(+), 8 deletions(-)
21
22
diff --git a/block/io.c b/block/io.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/block/io.c
25
+++ b/block/io.c
26
@@ -XXX,XX +XXX,XX @@ int bdrv_is_allocated_above(BlockDriverState *top,
27
intermediate = top;
28
while (intermediate && intermediate != base) {
29
int64_t pnum_inter;
30
+ int64_t size_inter;
31
int psectors_inter;
32
33
ret = bdrv_is_allocated(intermediate, sector_num * BDRV_SECTOR_SIZE,
34
@@ -XXX,XX +XXX,XX @@ int bdrv_is_allocated_above(BlockDriverState *top,
35
return 1;
36
}
37
38
- /*
39
- * [sector_num, nb_sectors] is unallocated on top but intermediate
40
- * might have
41
- *
42
- * [sector_num+x, nr_sectors] allocated.
43
- */
44
+ size_inter = bdrv_nb_sectors(intermediate);
45
+ if (size_inter < 0) {
46
+ return size_inter;
47
+ }
48
if (n > psectors_inter &&
49
- (intermediate == top ||
50
- sector_num + psectors_inter < intermediate->total_sectors)) {
51
+ (intermediate == top || sector_num + psectors_inter < size_inter)) {
52
n = psectors_inter;
53
}
54
55
--
56
1.8.3.1
57
58
diff view generated by jsdifflib
Deleted patch
1
From: Eric Blake <eblake@redhat.com>
2
1
3
We are gradually moving away from sector-based interfaces, towards
4
byte-based. In the common case, allocation is unlikely to ever use
5
values that are not naturally sector-aligned, but it is possible
6
that byte-based values will let us be more precise about allocation
7
at the end of an unaligned file that can do byte-based access.
8
9
Changing the signature of the function to use int64_t *pnum ensures
10
that the compiler enforces that all callers are updated. For now,
11
the io.c layer still assert()s that all callers are sector-aligned,
12
but that can be relaxed when a later patch implements byte-based
13
block status. Therefore, for the most part this patch is just the
14
addition of scaling at the callers followed by inverse scaling at
15
bdrv_is_allocated(). But some code, particularly stream_run(),
16
gets a lot simpler because it no longer has to mess with sectors.
17
Leave comments where we can further simplify by switching to
18
byte-based iterations, once later patches eliminate the need for
19
sector-aligned operations.
20
21
For ease of review, bdrv_is_allocated() was tackled separately.
22
23
Signed-off-by: Eric Blake <eblake@redhat.com>
24
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
25
---
26
block/commit.c | 20 ++++++++------------
27
block/io.c | 38 ++++++++++++++++++--------------------
28
block/mirror.c | 8 +++++++-
29
block/replication.c | 17 ++++++++++++-----
30
block/stream.c | 23 +++++++++--------------
31
include/block/block.h | 2 +-
32
qemu-img.c | 13 ++++++++++---
33
7 files changed, 65 insertions(+), 56 deletions(-)
34
35
diff --git a/block/commit.c b/block/commit.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/block/commit.c
38
+++ b/block/commit.c
39
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn commit_run(void *opaque)
40
int64_t offset;
41
uint64_t delay_ns = 0;
42
int ret = 0;
43
- int n = 0; /* sectors */
44
+ int64_t n = 0; /* bytes */
45
void *buf = NULL;
46
int bytes_written = 0;
47
int64_t base_len;
48
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn commit_run(void *opaque)
49
50
buf = blk_blockalign(s->top, COMMIT_BUFFER_SIZE);
51
52
- for (offset = 0; offset < s->common.len; offset += n * BDRV_SECTOR_SIZE) {
53
+ for (offset = 0; offset < s->common.len; offset += n) {
54
bool copy;
55
56
/* Note that even when no rate limit is applied we need to yield
57
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn commit_run(void *opaque)
58
}
59
/* Copy if allocated above the base */
60
ret = bdrv_is_allocated_above(blk_bs(s->top), blk_bs(s->base),
61
- offset / BDRV_SECTOR_SIZE,
62
- COMMIT_BUFFER_SIZE / BDRV_SECTOR_SIZE,
63
- &n);
64
+ offset, COMMIT_BUFFER_SIZE, &n);
65
copy = (ret == 1);
66
- trace_commit_one_iteration(s, offset, n * BDRV_SECTOR_SIZE, ret);
67
+ trace_commit_one_iteration(s, offset, n, ret);
68
if (copy) {
69
- ret = commit_populate(s->top, s->base, offset,
70
- n * BDRV_SECTOR_SIZE, buf);
71
- bytes_written += n * BDRV_SECTOR_SIZE;
72
+ ret = commit_populate(s->top, s->base, offset, n, buf);
73
+ bytes_written += n;
74
}
75
if (ret < 0) {
76
BlockErrorAction action =
77
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn commit_run(void *opaque)
78
}
79
}
80
/* Publish progress */
81
- s->common.offset += n * BDRV_SECTOR_SIZE;
82
+ s->common.offset += n;
83
84
if (copy && s->common.speed) {
85
- delay_ns = ratelimit_calculate_delay(&s->limit,
86
- n * BDRV_SECTOR_SIZE);
87
+ delay_ns = ratelimit_calculate_delay(&s->limit, n);
88
}
89
}
90
91
diff --git a/block/io.c b/block/io.c
92
index XXXXXXX..XXXXXXX 100644
93
--- a/block/io.c
94
+++ b/block/io.c
95
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t offset,
96
/*
97
* Given an image chain: ... -> [BASE] -> [INTER1] -> [INTER2] -> [TOP]
98
*
99
- * Return true if the given sector is allocated in any image between
100
- * BASE and TOP (inclusive). BASE can be NULL to check if the given
101
- * sector is allocated in any image of the chain. Return false otherwise,
102
+ * Return true if (a prefix of) the given range is allocated in any image
103
+ * between BASE and TOP (inclusive). BASE can be NULL to check if the given
104
+ * offset is allocated in any image of the chain. Return false otherwise,
105
* or negative errno on failure.
106
*
107
- * 'pnum' is set to the number of sectors (including and immediately following
108
- * the specified sector) that are known to be in the same
109
- * allocated/unallocated state.
110
+ * 'pnum' is set to the number of bytes (including and immediately
111
+ * following the specified offset) that are known to be in the same
112
+ * allocated/unallocated state. Note that a subsequent call starting
113
+ * at 'offset + *pnum' may return the same allocation status (in other
114
+ * words, the result is not necessarily the maximum possible range);
115
+ * but 'pnum' will only be 0 when end of file is reached.
116
*
117
*/
118
int bdrv_is_allocated_above(BlockDriverState *top,
119
BlockDriverState *base,
120
- int64_t sector_num,
121
- int nb_sectors, int *pnum)
122
+ int64_t offset, int64_t bytes, int64_t *pnum)
123
{
124
BlockDriverState *intermediate;
125
- int ret, n = nb_sectors;
126
+ int ret;
127
+ int64_t n = bytes;
128
129
intermediate = top;
130
while (intermediate && intermediate != base) {
131
int64_t pnum_inter;
132
int64_t size_inter;
133
- int psectors_inter;
134
135
- ret = bdrv_is_allocated(intermediate, sector_num * BDRV_SECTOR_SIZE,
136
- nb_sectors * BDRV_SECTOR_SIZE,
137
- &pnum_inter);
138
+ ret = bdrv_is_allocated(intermediate, offset, bytes, &pnum_inter);
139
if (ret < 0) {
140
return ret;
141
}
142
- assert(pnum_inter < INT_MAX * BDRV_SECTOR_SIZE);
143
- psectors_inter = pnum_inter >> BDRV_SECTOR_BITS;
144
if (ret) {
145
- *pnum = psectors_inter;
146
+ *pnum = pnum_inter;
147
return 1;
148
}
149
150
- size_inter = bdrv_nb_sectors(intermediate);
151
+ size_inter = bdrv_getlength(intermediate);
152
if (size_inter < 0) {
153
return size_inter;
154
}
155
- if (n > psectors_inter &&
156
- (intermediate == top || sector_num + psectors_inter < size_inter)) {
157
- n = psectors_inter;
158
+ if (n > pnum_inter &&
159
+ (intermediate == top || offset + pnum_inter < size_inter)) {
160
+ n = pnum_inter;
161
}
162
163
intermediate = backing_bs(intermediate);
164
diff --git a/block/mirror.c b/block/mirror.c
165
index XXXXXXX..XXXXXXX 100644
166
--- a/block/mirror.c
167
+++ b/block/mirror.c
168
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
169
BlockDriverState *bs = s->source;
170
BlockDriverState *target_bs = blk_bs(s->target);
171
int ret, n;
172
+ int64_t count;
173
174
end = s->bdev_length / BDRV_SECTOR_SIZE;
175
176
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
177
return 0;
178
}
179
180
- ret = bdrv_is_allocated_above(bs, base, sector_num, nb_sectors, &n);
181
+ ret = bdrv_is_allocated_above(bs, base, sector_num * BDRV_SECTOR_SIZE,
182
+ nb_sectors * BDRV_SECTOR_SIZE, &count);
183
if (ret < 0) {
184
return ret;
185
}
186
187
+ /* TODO: Relax this once bdrv_is_allocated_above and dirty
188
+ * bitmaps no longer require sector alignment. */
189
+ assert(QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE));
190
+ n = count >> BDRV_SECTOR_BITS;
191
assert(n > 0);
192
if (ret == 1) {
193
bdrv_set_dirty_bitmap(s->dirty_bitmap, sector_num, n);
194
diff --git a/block/replication.c b/block/replication.c
195
index XXXXXXX..XXXXXXX 100644
196
--- a/block/replication.c
197
+++ b/block/replication.c
198
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int replication_co_writev(BlockDriverState *bs,
199
BdrvChild *top = bs->file;
200
BdrvChild *base = s->secondary_disk;
201
BdrvChild *target;
202
- int ret, n;
203
+ int ret;
204
+ int64_t n;
205
206
ret = replication_get_io_status(s);
207
if (ret < 0) {
208
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int replication_co_writev(BlockDriverState *bs,
209
*/
210
qemu_iovec_init(&hd_qiov, qiov->niov);
211
while (remaining_sectors > 0) {
212
- ret = bdrv_is_allocated_above(top->bs, base->bs, sector_num,
213
- remaining_sectors, &n);
214
+ int64_t count;
215
+
216
+ ret = bdrv_is_allocated_above(top->bs, base->bs,
217
+ sector_num * BDRV_SECTOR_SIZE,
218
+ remaining_sectors * BDRV_SECTOR_SIZE,
219
+ &count);
220
if (ret < 0) {
221
goto out1;
222
}
223
224
+ assert(QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE));
225
+ n = count >> BDRV_SECTOR_BITS;
226
qemu_iovec_reset(&hd_qiov);
227
- qemu_iovec_concat(&hd_qiov, qiov, bytes_done, n * BDRV_SECTOR_SIZE);
228
+ qemu_iovec_concat(&hd_qiov, qiov, bytes_done, count);
229
230
target = ret ? top : base;
231
ret = bdrv_co_writev(target, sector_num, n, &hd_qiov);
232
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int replication_co_writev(BlockDriverState *bs,
233
234
remaining_sectors -= n;
235
sector_num += n;
236
- bytes_done += n * BDRV_SECTOR_SIZE;
237
+ bytes_done += count;
238
}
239
240
out1:
241
diff --git a/block/stream.c b/block/stream.c
242
index XXXXXXX..XXXXXXX 100644
243
--- a/block/stream.c
244
+++ b/block/stream.c
245
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn stream_run(void *opaque)
246
uint64_t delay_ns = 0;
247
int error = 0;
248
int ret = 0;
249
- int n = 0; /* sectors */
250
+ int64_t n = 0; /* bytes */
251
void *buf;
252
253
if (!bs->backing) {
254
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn stream_run(void *opaque)
255
bdrv_enable_copy_on_read(bs);
256
}
257
258
- for ( ; offset < s->common.len; offset += n * BDRV_SECTOR_SIZE) {
259
+ for ( ; offset < s->common.len; offset += n) {
260
bool copy;
261
- int64_t count = 0;
262
263
/* Note that even when no rate limit is applied we need to yield
264
* with no pending I/O here so that bdrv_drain_all() returns.
265
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn stream_run(void *opaque)
266
267
copy = false;
268
269
- ret = bdrv_is_allocated(bs, offset, STREAM_BUFFER_SIZE, &count);
270
- /* TODO relax this once bdrv_is_allocated does not enforce sectors */
271
- assert(QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE));
272
- n = count >> BDRV_SECTOR_BITS;
273
+ ret = bdrv_is_allocated(bs, offset, STREAM_BUFFER_SIZE, &n);
274
if (ret == 1) {
275
/* Allocated in the top, no need to copy. */
276
} else if (ret >= 0) {
277
/* Copy if allocated in the intermediate images. Limit to the
278
* known-unallocated area [offset, offset+n*BDRV_SECTOR_SIZE). */
279
ret = bdrv_is_allocated_above(backing_bs(bs), base,
280
- offset / BDRV_SECTOR_SIZE, n, &n);
281
+ offset, n, &n);
282
283
/* Finish early if end of backing file has been reached */
284
if (ret == 0 && n == 0) {
285
- n = (s->common.len - offset) / BDRV_SECTOR_SIZE;
286
+ n = s->common.len - offset;
287
}
288
289
copy = (ret == 1);
290
}
291
- trace_stream_one_iteration(s, offset, n * BDRV_SECTOR_SIZE, ret);
292
+ trace_stream_one_iteration(s, offset, n, ret);
293
if (copy) {
294
- ret = stream_populate(blk, offset, n * BDRV_SECTOR_SIZE, buf);
295
+ ret = stream_populate(blk, offset, n, buf);
296
}
297
if (ret < 0) {
298
BlockErrorAction action =
299
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn stream_run(void *opaque)
300
ret = 0;
301
302
/* Publish progress */
303
- s->common.offset += n * BDRV_SECTOR_SIZE;
304
+ s->common.offset += n;
305
if (copy && s->common.speed) {
306
- delay_ns = ratelimit_calculate_delay(&s->limit,
307
- n * BDRV_SECTOR_SIZE);
308
+ delay_ns = ratelimit_calculate_delay(&s->limit, n);
309
}
310
}
311
312
diff --git a/include/block/block.h b/include/block/block.h
313
index XXXXXXX..XXXXXXX 100644
314
--- a/include/block/block.h
315
+++ b/include/block/block.h
316
@@ -XXX,XX +XXX,XX @@ int64_t bdrv_get_block_status_above(BlockDriverState *bs,
317
int bdrv_is_allocated(BlockDriverState *bs, int64_t offset, int64_t bytes,
318
int64_t *pnum);
319
int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
320
- int64_t sector_num, int nb_sectors, int *pnum);
321
+ int64_t offset, int64_t bytes, int64_t *pnum);
322
323
bool bdrv_is_read_only(BlockDriverState *bs);
324
bool bdrv_is_writable(BlockDriverState *bs);
325
diff --git a/qemu-img.c b/qemu-img.c
326
index XXXXXXX..XXXXXXX 100644
327
--- a/qemu-img.c
328
+++ b/qemu-img.c
329
@@ -XXX,XX +XXX,XX @@ static int img_compare(int argc, char **argv)
330
}
331
332
for (;;) {
333
+ int64_t count;
334
+
335
nb_sectors = sectors_to_process(total_sectors_over, sector_num);
336
if (nb_sectors <= 0) {
337
break;
338
}
339
- ret = bdrv_is_allocated_above(blk_bs(blk_over), NULL, sector_num,
340
- nb_sectors, &pnum);
341
+ ret = bdrv_is_allocated_above(blk_bs(blk_over), NULL,
342
+ sector_num * BDRV_SECTOR_SIZE,
343
+ nb_sectors * BDRV_SECTOR_SIZE,
344
+ &count);
345
if (ret < 0) {
346
ret = 3;
347
error_report("Sector allocation test failed for %s",
348
@@ -XXX,XX +XXX,XX @@ static int img_compare(int argc, char **argv)
349
goto out;
350
351
}
352
- nb_sectors = pnum;
353
+ /* TODO relax this once bdrv_is_allocated_above does not enforce
354
+ * sector alignment */
355
+ assert(QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE));
356
+ nb_sectors = count >> BDRV_SECTOR_BITS;
357
if (ret) {
358
ret = check_empty_sectors(blk_over, sector_num, nb_sectors,
359
filename_over, buf1, quiet);
360
--
361
1.8.3.1
362
363
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.c | 82 +++++++++++++++++-----------------------------------
18
block/crypto.h | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
19
2 files changed, 117 insertions(+), 56 deletions(-)
20
create mode 100644 block/crypto.h
21
22
diff --git a/block/crypto.c b/block/crypto.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/block/crypto.c
25
+++ b/block/crypto.c
26
@@ -XXX,XX +XXX,XX @@
27
#include "sysemu/block-backend.h"
28
#include "crypto/block.h"
29
#include "qapi/opts-visitor.h"
30
+#include "qapi/qobject-input-visitor.h"
31
#include "qapi-visit.h"
32
#include "qapi/error.h"
33
-
34
-#define BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET "key-secret"
35
-#define BLOCK_CRYPTO_OPT_LUKS_CIPHER_ALG "cipher-alg"
36
-#define BLOCK_CRYPTO_OPT_LUKS_CIPHER_MODE "cipher-mode"
37
-#define BLOCK_CRYPTO_OPT_LUKS_IVGEN_ALG "ivgen-alg"
38
-#define BLOCK_CRYPTO_OPT_LUKS_IVGEN_HASH_ALG "ivgen-hash-alg"
39
-#define BLOCK_CRYPTO_OPT_LUKS_HASH_ALG "hash-alg"
40
-#define BLOCK_CRYPTO_OPT_LUKS_ITER_TIME "iter-time"
41
+#include "block/crypto.h"
42
43
typedef struct BlockCrypto BlockCrypto;
44
45
@@ -XXX,XX +XXX,XX @@ static QemuOptsList block_crypto_runtime_opts_luks = {
46
.name = "crypto",
47
.head = QTAILQ_HEAD_INITIALIZER(block_crypto_runtime_opts_luks.head),
48
.desc = {
49
- {
50
- .name = BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET,
51
- .type = QEMU_OPT_STRING,
52
- .help = "ID of the secret that provides the encryption key",
53
- },
54
+ BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET,
55
{ /* end of list */ }
56
},
57
};
58
@@ -XXX,XX +XXX,XX @@ static QemuOptsList block_crypto_create_opts_luks = {
59
.type = QEMU_OPT_SIZE,
60
.help = "Virtual disk size"
61
},
62
- {
63
- .name = BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET,
64
- .type = QEMU_OPT_STRING,
65
- .help = "ID of the secret that provides the encryption key",
66
- },
67
- {
68
- .name = BLOCK_CRYPTO_OPT_LUKS_CIPHER_ALG,
69
- .type = QEMU_OPT_STRING,
70
- .help = "Name of encryption cipher algorithm",
71
- },
72
- {
73
- .name = BLOCK_CRYPTO_OPT_LUKS_CIPHER_MODE,
74
- .type = QEMU_OPT_STRING,
75
- .help = "Name of encryption cipher mode",
76
- },
77
- {
78
- .name = BLOCK_CRYPTO_OPT_LUKS_IVGEN_ALG,
79
- .type = QEMU_OPT_STRING,
80
- .help = "Name of IV generator algorithm",
81
- },
82
- {
83
- .name = BLOCK_CRYPTO_OPT_LUKS_IVGEN_HASH_ALG,
84
- .type = QEMU_OPT_STRING,
85
- .help = "Name of IV generator hash algorithm",
86
- },
87
- {
88
- .name = BLOCK_CRYPTO_OPT_LUKS_HASH_ALG,
89
- .type = QEMU_OPT_STRING,
90
- .help = "Name of encryption hash algorithm",
91
- },
92
- {
93
- .name = BLOCK_CRYPTO_OPT_LUKS_ITER_TIME,
94
- .type = QEMU_OPT_NUMBER,
95
- .help = "Time to spend in PBKDF in milliseconds",
96
- },
97
+ BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET,
98
+ BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG,
99
+ BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE,
100
+ BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG,
101
+ BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG,
102
+ BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG,
103
+ BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME,
104
{ /* end of list */ }
105
},
106
};
107
108
109
-static QCryptoBlockOpenOptions *
110
+QCryptoBlockOpenOptions *
111
block_crypto_open_opts_init(QCryptoBlockFormat format,
112
- QemuOpts *opts,
113
+ QDict *opts,
114
Error **errp)
115
{
116
Visitor *v;
117
@@ -XXX,XX +XXX,XX @@ block_crypto_open_opts_init(QCryptoBlockFormat format,
118
ret = g_new0(QCryptoBlockOpenOptions, 1);
119
ret->format = format;
120
121
- v = opts_visitor_new(opts);
122
+ v = qobject_input_visitor_new_keyval(QOBJECT(opts));
123
124
visit_start_struct(v, NULL, NULL, 0, &local_err);
125
if (local_err) {
126
@@ -XXX,XX +XXX,XX @@ block_crypto_open_opts_init(QCryptoBlockFormat format,
127
}
128
129
130
-static QCryptoBlockCreateOptions *
131
+QCryptoBlockCreateOptions *
132
block_crypto_create_opts_init(QCryptoBlockFormat format,
133
- QemuOpts *opts,
134
+ QDict *opts,
135
Error **errp)
136
{
137
Visitor *v;
138
@@ -XXX,XX +XXX,XX @@ block_crypto_create_opts_init(QCryptoBlockFormat format,
139
ret = g_new0(QCryptoBlockCreateOptions, 1);
140
ret->format = format;
141
142
- v = opts_visitor_new(opts);
143
+ v = qobject_input_visitor_new_keyval(QOBJECT(opts));
144
145
visit_start_struct(v, NULL, NULL, 0, &local_err);
146
if (local_err) {
147
@@ -XXX,XX +XXX,XX @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
148
int ret = -EINVAL;
149
QCryptoBlockOpenOptions *open_opts = NULL;
150
unsigned int cflags = 0;
151
+ QDict *cryptoopts = NULL;
152
153
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
154
false, errp);
155
@@ -XXX,XX +XXX,XX @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
156
goto cleanup;
157
}
158
159
- open_opts = block_crypto_open_opts_init(format, opts, errp);
160
+ cryptoopts = qemu_opts_to_qdict(opts, NULL);
161
+
162
+ open_opts = block_crypto_open_opts_init(format, cryptoopts, errp);
163
if (!open_opts) {
164
goto cleanup;
165
}
166
@@ -XXX,XX +XXX,XX @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
167
168
ret = 0;
169
cleanup:
170
+ QDECREF(cryptoopts);
171
qapi_free_QCryptoBlockOpenOptions(open_opts);
172
return ret;
173
}
174
@@ -XXX,XX +XXX,XX @@ static int block_crypto_create_generic(QCryptoBlockFormat format,
175
.opts = opts,
176
.filename = filename,
177
};
178
+ QDict *cryptoopts;
179
+
180
+ cryptoopts = qemu_opts_to_qdict(opts, NULL);
181
182
- create_opts = block_crypto_create_opts_init(format, opts, errp);
183
+ create_opts = block_crypto_create_opts_init(format, cryptoopts, errp);
184
if (!create_opts) {
185
return -1;
186
}
187
@@ -XXX,XX +XXX,XX @@ static int block_crypto_create_generic(QCryptoBlockFormat format,
188
189
ret = 0;
190
cleanup:
191
+ QDECREF(cryptoopts);
192
qcrypto_block_free(crypto);
193
blk_unref(data.blk);
194
qapi_free_QCryptoBlockCreateOptions(create_opts);
195
diff --git a/block/crypto.h b/block/crypto.h
196
new file mode 100644
197
index XXXXXXX..XXXXXXX
198
--- /dev/null
199
+++ b/block/crypto.h
200
@@ -XXX,XX +XXX,XX @@
201
+/*
202
+ * QEMU block full disk encryption
203
+ *
204
+ * Copyright (c) 2015-2017 Red Hat, Inc.
205
+ *
206
+ * This library is free software; you can redistribute it and/or
207
+ * modify it under the terms of the GNU Lesser General Public
208
+ * License as published by the Free Software Foundation; either
209
+ * version 2 of the License, or (at your option) any later version.
210
+ *
211
+ * This library is distributed in the hope that it will be useful,
212
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
213
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
214
+ * Lesser General Public License for more details.
215
+ *
216
+ * You should have received a copy of the GNU Lesser General Public
217
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
218
+ *
219
+ */
220
+
221
+#ifndef BLOCK_CRYPTO_H__
222
+#define BLOCK_CRYPTO_H__
223
+
224
+#define BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET "key-secret"
225
+#define BLOCK_CRYPTO_OPT_LUKS_CIPHER_ALG "cipher-alg"
226
+#define BLOCK_CRYPTO_OPT_LUKS_CIPHER_MODE "cipher-mode"
227
+#define BLOCK_CRYPTO_OPT_LUKS_IVGEN_ALG "ivgen-alg"
228
+#define BLOCK_CRYPTO_OPT_LUKS_IVGEN_HASH_ALG "ivgen-hash-alg"
229
+#define BLOCK_CRYPTO_OPT_LUKS_HASH_ALG "hash-alg"
230
+#define BLOCK_CRYPTO_OPT_LUKS_ITER_TIME "iter-time"
231
+
232
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET \
233
+ { \
234
+ .name = BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET, \
235
+ .type = QEMU_OPT_STRING, \
236
+ .help = "ID of the secret that provides the keyslot passphrase", \
237
+ }
238
+
239
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG \
240
+ { \
241
+ .name = BLOCK_CRYPTO_OPT_LUKS_CIPHER_ALG, \
242
+ .type = QEMU_OPT_STRING, \
243
+ .help = "Name of encryption cipher algorithm", \
244
+ }
245
+
246
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE \
247
+ { \
248
+ .name = BLOCK_CRYPTO_OPT_LUKS_CIPHER_MODE, \
249
+ .type = QEMU_OPT_STRING, \
250
+ .help = "Name of encryption cipher mode", \
251
+ }
252
+
253
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG \
254
+ { \
255
+ .name = BLOCK_CRYPTO_OPT_LUKS_IVGEN_ALG, \
256
+ .type = QEMU_OPT_STRING, \
257
+ .help = "Name of IV generator algorithm", \
258
+ }
259
+
260
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG \
261
+ { \
262
+ .name = BLOCK_CRYPTO_OPT_LUKS_IVGEN_HASH_ALG, \
263
+ .type = QEMU_OPT_STRING, \
264
+ .help = "Name of IV generator hash algorithm", \
265
+ }
266
+
267
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG \
268
+ { \
269
+ .name = BLOCK_CRYPTO_OPT_LUKS_HASH_ALG, \
270
+ .type = QEMU_OPT_STRING, \
271
+ .help = "Name of encryption hash algorithm", \
272
+ }
273
+
274
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME \
275
+ { \
276
+ .name = BLOCK_CRYPTO_OPT_LUKS_ITER_TIME, \
277
+ .type = QEMU_OPT_NUMBER, \
278
+ .help = "Time to spend in PBKDF in milliseconds", \
279
+ }
280
+
281
+QCryptoBlockCreateOptions *
282
+block_crypto_create_opts_init(QCryptoBlockFormat format,
283
+ QDict *opts,
284
+ Error **errp);
285
+
286
+QCryptoBlockOpenOptions *
287
+block_crypto_open_opts_init(QCryptoBlockFormat format,
288
+ QDict *opts,
289
+ Error **errp);
290
+
291
+#endif /* BLOCK_CRYPTO_H__ */
292
--
293
1.8.3.1
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.c | 16 ++++++++--------
20
block/crypto.h | 40 ++++++++++++++++++++--------------------
21
2 files changed, 28 insertions(+), 28 deletions(-)
22
23
diff --git a/block/crypto.c b/block/crypto.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/block/crypto.c
26
+++ b/block/crypto.c
27
@@ -XXX,XX +XXX,XX @@ static QemuOptsList block_crypto_runtime_opts_luks = {
28
.name = "crypto",
29
.head = QTAILQ_HEAD_INITIALIZER(block_crypto_runtime_opts_luks.head),
30
.desc = {
31
- BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET,
32
+ BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(""),
33
{ /* end of list */ }
34
},
35
};
36
@@ -XXX,XX +XXX,XX @@ static QemuOptsList block_crypto_create_opts_luks = {
37
.type = QEMU_OPT_SIZE,
38
.help = "Virtual disk size"
39
},
40
- BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET,
41
- BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG,
42
- BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE,
43
- BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG,
44
- BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG,
45
- BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG,
46
- BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME,
47
+ BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(""),
48
+ BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG(""),
49
+ BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE(""),
50
+ BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG(""),
51
+ BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG(""),
52
+ BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG(""),
53
+ BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME(""),
54
{ /* end of list */ }
55
},
56
};
57
diff --git a/block/crypto.h b/block/crypto.h
58
index XXXXXXX..XXXXXXX 100644
59
--- a/block/crypto.h
60
+++ b/block/crypto.h
61
@@ -XXX,XX +XXX,XX @@
62
#define BLOCK_CRYPTO_OPT_LUKS_HASH_ALG "hash-alg"
63
#define BLOCK_CRYPTO_OPT_LUKS_ITER_TIME "iter-time"
64
65
-#define BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET \
66
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(prefix) \
67
{ \
68
- .name = BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET, \
69
+ .name = prefix BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET, \
70
.type = QEMU_OPT_STRING, \
71
.help = "ID of the secret that provides the keyslot passphrase", \
72
}
73
74
-#define BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG \
75
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG(prefix) \
76
{ \
77
- .name = BLOCK_CRYPTO_OPT_LUKS_CIPHER_ALG, \
78
+ .name = prefix BLOCK_CRYPTO_OPT_LUKS_CIPHER_ALG, \
79
.type = QEMU_OPT_STRING, \
80
.help = "Name of encryption cipher algorithm", \
81
}
82
83
-#define BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE \
84
- { \
85
- .name = BLOCK_CRYPTO_OPT_LUKS_CIPHER_MODE, \
86
- .type = QEMU_OPT_STRING, \
87
- .help = "Name of encryption cipher mode", \
88
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE(prefix) \
89
+ { \
90
+ .name = prefix BLOCK_CRYPTO_OPT_LUKS_CIPHER_MODE, \
91
+ .type = QEMU_OPT_STRING, \
92
+ .help = "Name of encryption cipher mode", \
93
}
94
95
-#define BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG \
96
- { \
97
- .name = BLOCK_CRYPTO_OPT_LUKS_IVGEN_ALG, \
98
- .type = QEMU_OPT_STRING, \
99
- .help = "Name of IV generator algorithm", \
100
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG(prefix) \
101
+ { \
102
+ .name = prefix BLOCK_CRYPTO_OPT_LUKS_IVGEN_ALG, \
103
+ .type = QEMU_OPT_STRING, \
104
+ .help = "Name of IV generator algorithm", \
105
}
106
107
-#define BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG \
108
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG(prefix) \
109
{ \
110
- .name = BLOCK_CRYPTO_OPT_LUKS_IVGEN_HASH_ALG, \
111
+ .name = prefix BLOCK_CRYPTO_OPT_LUKS_IVGEN_HASH_ALG, \
112
.type = QEMU_OPT_STRING, \
113
.help = "Name of IV generator hash algorithm", \
114
}
115
116
-#define BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG \
117
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG(prefix) \
118
{ \
119
- .name = BLOCK_CRYPTO_OPT_LUKS_HASH_ALG, \
120
+ .name = prefix BLOCK_CRYPTO_OPT_LUKS_HASH_ALG, \
121
.type = QEMU_OPT_STRING, \
122
.help = "Name of encryption hash algorithm", \
123
}
124
125
-#define BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME \
126
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME(prefix) \
127
{ \
128
- .name = BLOCK_CRYPTO_OPT_LUKS_ITER_TIME, \
129
+ .name = prefix BLOCK_CRYPTO_OPT_LUKS_ITER_TIME, \
130
.type = QEMU_OPT_NUMBER, \
131
.help = "Time to spend in PBKDF in milliseconds", \
132
}
133
--
134
1.8.3.1
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
1.8.3.1
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
1.8.3.1
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
1.8.3.1
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
1.8.3.1
31
32
diff view generated by jsdifflib
Deleted patch
1
From: "Daniel P. Berrange" <berrange@redhat.com>
2
1
3
Historically the qcow & qcow2 image formats supported a property
4
"encryption=on" to enable their built-in AES encryption. We'll
5
soon be supporting LUKS for qcow2, so need a more general purpose
6
way to enable encryption, with a choice of formats.
7
8
This introduces an "encrypt.format" option, which will later be
9
joined by a number of other "encrypt.XXX" options. The use of
10
a "encrypt." prefix instead of "encrypt-" is done to facilitate
11
mapping to a nested QAPI schema at later date.
12
13
e.g. the preferred syntax is now
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
block/qcow.c | 31 ++++++++++++---
23
block/qcow2.c | 34 ++++++++++++----
24
include/block/block_int.h | 2 +-
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/block/qcow.c b/block/qcow.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/block/qcow.c
36
+++ b/block/qcow.c
37
@@ -XXX,XX +XXX,XX @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp)
38
uint8_t *tmp;
39
int64_t total_size = 0;
40
char *backing_file = NULL;
41
- int flags = 0;
42
Error *local_err = NULL;
43
int ret;
44
BlockBackend *qcow_blk;
45
+ const char *encryptfmt = NULL;
46
47
/* Read out options */
48
total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
49
@@ -XXX,XX +XXX,XX @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp)
50
}
51
52
backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
53
- if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) {
54
- flags |= BLOCK_FLAG_ENCRYPT;
55
+ encryptfmt = qemu_opt_get_del(opts, BLOCK_OPT_ENCRYPT_FORMAT);
56
+ if (encryptfmt) {
57
+ if (qemu_opt_get(opts, BLOCK_OPT_ENCRYPT)) {
58
+ error_setg(errp, "Options " BLOCK_OPT_ENCRYPT " and "
59
+ BLOCK_OPT_ENCRYPT_FORMAT " are mutually exclusive");
60
+ ret = -EINVAL;
61
+ goto cleanup;
62
+ }
63
+ } else if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) {
64
+ encryptfmt = "aes";
65
}
66
67
ret = bdrv_create_file(filename, opts, &local_err);
68
@@ -XXX,XX +XXX,XX @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp)
69
l1_size = (total_size + (1LL << shift) - 1) >> shift;
70
71
header.l1_table_offset = cpu_to_be64(header_size);
72
- if (flags & BLOCK_FLAG_ENCRYPT) {
73
+ if (encryptfmt) {
74
+ if (!g_str_equal(encryptfmt, "aes")) {
75
+ error_setg(errp, "Unknown encryption format '%s', expected 'aes'",
76
+ encryptfmt);
77
+ ret = -EINVAL;
78
+ goto exit;
79
+ }
80
header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
81
} else {
82
header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
83
@@ -XXX,XX +XXX,XX @@ static QemuOptsList qcow_create_opts = {
84
{
85
.name = BLOCK_OPT_ENCRYPT,
86
.type = QEMU_OPT_BOOL,
87
- .help = "Encrypt the image",
88
- .def_value_str = "off"
89
+ .help = "Encrypt the image with format 'aes'. (Deprecated "
90
+ "in favor of " BLOCK_OPT_ENCRYPT_FORMAT "=aes)",
91
+ },
92
+ {
93
+ .name = BLOCK_OPT_ENCRYPT_FORMAT,
94
+ .type = QEMU_OPT_STRING,
95
+ .help = "Encrypt the image, format choices: 'aes'",
96
},
97
{ /* end of list */ }
98
}
99
diff --git a/block/qcow2.c b/block/qcow2.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/block/qcow2.c
102
+++ b/block/qcow2.c
103
@@ -XXX,XX +XXX,XX @@ static int qcow2_create2(const char *filename, int64_t total_size,
104
const char *backing_file, const char *backing_format,
105
int flags, size_t cluster_size, PreallocMode prealloc,
106
QemuOpts *opts, int version, int refcount_order,
107
- Error **errp)
108
+ const char *encryptfmt, Error **errp)
109
{
110
int cluster_bits;
111
QDict *options;
112
@@ -XXX,XX +XXX,XX @@ static int qcow2_create2(const char *filename, int64_t total_size,
113
.header_length = cpu_to_be32(sizeof(*header)),
114
};
115
116
- if (flags & BLOCK_FLAG_ENCRYPT) {
117
+ if (encryptfmt) {
118
+ if (!g_str_equal(encryptfmt, "aes")) {
119
+ error_setg(errp, "Unknown encryption format '%s', expected 'aes'",
120
+ encryptfmt);
121
+ ret = -EINVAL;
122
+ goto out;
123
+ }
124
header->crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
125
} else {
126
header->crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
127
@@ -XXX,XX +XXX,XX @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp)
128
int version = 3;
129
uint64_t refcount_bits = 16;
130
int refcount_order;
131
+ const char *encryptfmt = NULL;
132
Error *local_err = NULL;
133
int ret;
134
135
@@ -XXX,XX +XXX,XX @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp)
136
BDRV_SECTOR_SIZE);
137
backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
138
backing_fmt = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT);
139
- if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) {
140
- flags |= BLOCK_FLAG_ENCRYPT;
141
+ encryptfmt = qemu_opt_get_del(opts, BLOCK_OPT_ENCRYPT_FORMAT);
142
+ if (encryptfmt) {
143
+ if (qemu_opt_get_del(opts, BLOCK_OPT_ENCRYPT)) {
144
+ error_setg(errp, "Options " BLOCK_OPT_ENCRYPT " and "
145
+ BLOCK_OPT_ENCRYPT_FORMAT " are mutually exclusive");
146
+ ret = -EINVAL;
147
+ goto finish;
148
+ }
149
+ } else if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) {
150
+ encryptfmt = "aes";
151
}
152
cluster_size = qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE,
153
DEFAULT_CLUSTER_SIZE);
154
@@ -XXX,XX +XXX,XX @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp)
155
156
ret = qcow2_create2(filename, size, backing_file, backing_fmt, flags,
157
cluster_size, prealloc, opts, version, refcount_order,
158
- &local_err);
159
+ encryptfmt, &local_err);
160
error_propagate(errp, local_err);
161
162
finish:
163
@@ -XXX,XX +XXX,XX @@ static QemuOptsList qcow2_create_opts = {
164
{
165
.name = BLOCK_OPT_ENCRYPT,
166
.type = QEMU_OPT_BOOL,
167
- .help = "Encrypt the image",
168
- .def_value_str = "off"
169
+ .help = "Encrypt the image with format 'aes'. (Deprecated "
170
+ "in favor of " BLOCK_OPT_ENCRYPT_FORMAT "=aes)",
171
+ },
172
+ {
173
+ .name = BLOCK_OPT_ENCRYPT_FORMAT,
174
+ .type = QEMU_OPT_STRING,
175
+ .help = "Encrypt the image, format choices: 'aes'",
176
},
177
{
178
.name = BLOCK_OPT_CLUSTER_SIZE,
179
diff --git a/include/block/block_int.h b/include/block/block_int.h
180
index XXXXXXX..XXXXXXX 100644
181
--- a/include/block/block_int.h
182
+++ b/include/block/block_int.h
183
@@ -XXX,XX +XXX,XX @@
184
#include "qemu/main-loop.h"
185
#include "qemu/throttle.h"
186
187
-#define BLOCK_FLAG_ENCRYPT 1
188
#define BLOCK_FLAG_LAZY_REFCOUNTS 8
189
190
#define BLOCK_OPT_SIZE "size"
191
#define BLOCK_OPT_ENCRYPT "encryption"
192
+#define BLOCK_OPT_ENCRYPT_FORMAT "encrypt.format"
193
#define BLOCK_OPT_COMPAT6 "compat6"
194
#define BLOCK_OPT_HWVERSION "hwversion"
195
#define BLOCK_OPT_BACKING_FILE "backing_file"
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
--
896
1.8.3.1
897
898
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
1.8.3.1
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
block/crypto.c | 10 +++
37
block/crypto.h | 20 ++++--
38
block/qcow.c | 198 +++++++++++++++++++++++++--------------------------
39
qapi/block-core.json | 38 +++++++++-
40
4 files changed, 158 insertions(+), 108 deletions(-)
41
42
diff --git a/block/crypto.c b/block/crypto.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/block/crypto.c
45
+++ b/block/crypto.c
46
@@ -XXX,XX +XXX,XX @@ block_crypto_open_opts_init(QCryptoBlockFormat format,
47
v, &ret->u.luks, &local_err);
48
break;
49
50
+ case Q_CRYPTO_BLOCK_FORMAT_QCOW:
51
+ visit_type_QCryptoBlockOptionsQCow_members(
52
+ v, &ret->u.qcow, &local_err);
53
+ break;
54
+
55
default:
56
error_setg(&local_err, "Unsupported block format %d", format);
57
break;
58
@@ -XXX,XX +XXX,XX @@ block_crypto_create_opts_init(QCryptoBlockFormat format,
59
v, &ret->u.luks, &local_err);
60
break;
61
62
+ case Q_CRYPTO_BLOCK_FORMAT_QCOW:
63
+ visit_type_QCryptoBlockOptionsQCow_members(
64
+ v, &ret->u.qcow, &local_err);
65
+ break;
66
+
67
default:
68
error_setg(&local_err, "Unsupported block format %d", format);
69
break;
70
diff --git a/block/crypto.h b/block/crypto.h
71
index XXXXXXX..XXXXXXX 100644
72
--- a/block/crypto.h
73
+++ b/block/crypto.h
74
@@ -XXX,XX +XXX,XX @@
75
#ifndef BLOCK_CRYPTO_H__
76
#define BLOCK_CRYPTO_H__
77
78
+#define BLOCK_CRYPTO_OPT_DEF_KEY_SECRET(prefix, helpstr) \
79
+ { \
80
+ .name = prefix BLOCK_CRYPTO_OPT_QCOW_KEY_SECRET, \
81
+ .type = QEMU_OPT_STRING, \
82
+ .help = helpstr, \
83
+ }
84
+
85
+#define BLOCK_CRYPTO_OPT_QCOW_KEY_SECRET "key-secret"
86
+
87
+#define BLOCK_CRYPTO_OPT_DEF_QCOW_KEY_SECRET(prefix) \
88
+ BLOCK_CRYPTO_OPT_DEF_KEY_SECRET(prefix, \
89
+ "ID of the secret that provides the AES encryption key")
90
+
91
#define BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET "key-secret"
92
#define BLOCK_CRYPTO_OPT_LUKS_CIPHER_ALG "cipher-alg"
93
#define BLOCK_CRYPTO_OPT_LUKS_CIPHER_MODE "cipher-mode"
94
@@ -XXX,XX +XXX,XX @@
95
#define BLOCK_CRYPTO_OPT_LUKS_ITER_TIME "iter-time"
96
97
#define BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(prefix) \
98
- { \
99
- .name = prefix BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET, \
100
- .type = QEMU_OPT_STRING, \
101
- .help = "ID of the secret that provides the keyslot passphrase", \
102
- }
103
+ BLOCK_CRYPTO_OPT_DEF_KEY_SECRET(prefix, \
104
+ "ID of the secret that provides the keyslot passphrase")
105
106
#define BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG(prefix) \
107
{ \
108
diff --git a/block/qcow.c b/block/qcow.c
109
index XXXXXXX..XXXXXXX 100644
110
--- a/block/qcow.c
111
+++ b/block/qcow.c
112
@@ -XXX,XX +XXX,XX @@
113
#include "qemu/bswap.h"
114
#include <zlib.h>
115
#include "qapi/qmp/qerror.h"
116
-#include "crypto/cipher.h"
117
+#include "qapi/qmp/qstring.h"
118
+#include "crypto/block.h"
119
#include "migration/blocker.h"
120
+#include "block/crypto.h"
121
122
/**************************************************************/
123
/* QEMU COW block driver with compression and encryption support */
124
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVQcowState {
125
uint8_t *cluster_cache;
126
uint8_t *cluster_data;
127
uint64_t cluster_cache_offset;
128
- QCryptoCipher *cipher; /* NULL if no key yet */
129
+ QCryptoBlock *crypto; /* Disk encryption format driver */
130
uint32_t crypt_method_header;
131
CoMutex lock;
132
Error *migration_blocker;
133
@@ -XXX,XX +XXX,XX @@ static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
134
return 0;
135
}
136
137
+static QemuOptsList qcow_runtime_opts = {
138
+ .name = "qcow",
139
+ .head = QTAILQ_HEAD_INITIALIZER(qcow_runtime_opts.head),
140
+ .desc = {
141
+ BLOCK_CRYPTO_OPT_DEF_QCOW_KEY_SECRET("encrypt."),
142
+ { /* end of list */ }
143
+ },
144
+};
145
+
146
static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
147
Error **errp)
148
{
149
@@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
150
int ret;
151
QCowHeader header;
152
Error *local_err = NULL;
153
+ QCryptoBlockOpenOptions *crypto_opts = NULL;
154
+ unsigned int cflags = 0;
155
+ QDict *encryptopts = NULL;
156
+ const char *encryptfmt;
157
+
158
+ qdict_extract_subqdict(options, &encryptopts, "encrypt.");
159
+ encryptfmt = qdict_get_try_str(encryptopts, "format");
160
161
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
162
false, errp);
163
if (!bs->file) {
164
- return -EINVAL;
165
+ ret = -EINVAL;
166
+ goto fail;
167
}
168
169
ret = bdrv_pread(bs->file, 0, &header, sizeof(header));
170
@@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
171
goto fail;
172
}
173
174
- if (header.crypt_method > QCOW_CRYPT_AES) {
175
- error_setg(errp, "invalid encryption method in qcow header");
176
- ret = -EINVAL;
177
- goto fail;
178
- }
179
- if (!qcrypto_cipher_supports(QCRYPTO_CIPHER_ALG_AES_128,
180
- QCRYPTO_CIPHER_MODE_CBC)) {
181
- error_setg(errp, "AES cipher not available");
182
- ret = -EINVAL;
183
- goto fail;
184
- }
185
s->crypt_method_header = header.crypt_method;
186
if (s->crypt_method_header) {
187
if (bdrv_uses_whitelist() &&
188
@@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
189
ret = -ENOSYS;
190
goto fail;
191
}
192
+ if (s->crypt_method_header == QCOW_CRYPT_AES) {
193
+ if (encryptfmt && !g_str_equal(encryptfmt, "aes")) {
194
+ error_setg(errp,
195
+ "Header reported 'aes' encryption format but "
196
+ "options specify '%s'", encryptfmt);
197
+ ret = -EINVAL;
198
+ goto fail;
199
+ }
200
+ qdict_del(encryptopts, "format");
201
+ crypto_opts = block_crypto_open_opts_init(
202
+ Q_CRYPTO_BLOCK_FORMAT_QCOW, encryptopts, errp);
203
+ if (!crypto_opts) {
204
+ ret = -EINVAL;
205
+ goto fail;
206
+ }
207
208
+ if (flags & BDRV_O_NO_IO) {
209
+ cflags |= QCRYPTO_BLOCK_OPEN_NO_IO;
210
+ }
211
+ s->crypto = qcrypto_block_open(crypto_opts, NULL, NULL,
212
+ cflags, errp);
213
+ if (!s->crypto) {
214
+ ret = -EINVAL;
215
+ goto fail;
216
+ }
217
+ } else {
218
+ error_setg(errp, "invalid encryption method in qcow header");
219
+ ret = -EINVAL;
220
+ goto fail;
221
+ }
222
bs->encrypted = true;
223
+ bs->valid_key = true;
224
}
225
s->cluster_bits = header.cluster_bits;
226
s->cluster_size = 1 << s->cluster_bits;
227
@@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
228
goto fail;
229
}
230
231
+ QDECREF(encryptopts);
232
+ qapi_free_QCryptoBlockOpenOptions(crypto_opts);
233
qemu_co_mutex_init(&s->lock);
234
return 0;
235
236
@@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
237
qemu_vfree(s->l2_cache);
238
g_free(s->cluster_cache);
239
g_free(s->cluster_data);
240
+ qcrypto_block_free(s->crypto);
241
+ QDECREF(encryptopts);
242
+ qapi_free_QCryptoBlockOpenOptions(crypto_opts);
243
return ret;
244
}
245
246
@@ -XXX,XX +XXX,XX @@ static int qcow_reopen_prepare(BDRVReopenState *state,
247
return 0;
248
}
249
250
-static int qcow_set_key(BlockDriverState *bs, const char *key)
251
-{
252
- BDRVQcowState *s = bs->opaque;
253
- uint8_t keybuf[16];
254
- int len, i;
255
- Error *err;
256
-
257
- memset(keybuf, 0, 16);
258
- len = strlen(key);
259
- if (len > 16)
260
- len = 16;
261
- /* XXX: we could compress the chars to 7 bits to increase
262
- entropy */
263
- for(i = 0;i < len;i++) {
264
- keybuf[i] = key[i];
265
- }
266
- assert(bs->encrypted);
267
-
268
- qcrypto_cipher_free(s->cipher);
269
- s->cipher = qcrypto_cipher_new(
270
- QCRYPTO_CIPHER_ALG_AES_128,
271
- QCRYPTO_CIPHER_MODE_CBC,
272
- keybuf, G_N_ELEMENTS(keybuf),
273
- &err);
274
-
275
- if (!s->cipher) {
276
- /* XXX would be nice if errors in this method could
277
- * be properly propagate to the caller. Would need
278
- * the bdrv_set_key() API signature to be fixed. */
279
- error_free(err);
280
- return -1;
281
- }
282
- return 0;
283
-}
284
-
285
-/* The crypt function is compatible with the linux cryptoloop
286
- algorithm for < 4 GB images. */
287
-static int encrypt_sectors(BDRVQcowState *s, int64_t sector_num,
288
- uint8_t *buf, int nb_sectors, bool enc,
289
- Error **errp)
290
-{
291
- union {
292
- uint64_t ll[2];
293
- uint8_t b[16];
294
- } ivec;
295
- int i;
296
- int ret;
297
-
298
- for(i = 0; i < nb_sectors; i++) {
299
- ivec.ll[0] = cpu_to_le64(sector_num);
300
- ivec.ll[1] = 0;
301
- if (qcrypto_cipher_setiv(s->cipher,
302
- ivec.b, G_N_ELEMENTS(ivec.b),
303
- errp) < 0) {
304
- return -1;
305
- }
306
- if (enc) {
307
- ret = qcrypto_cipher_encrypt(s->cipher,
308
- buf, buf,
309
- 512,
310
- errp);
311
- } else {
312
- ret = qcrypto_cipher_decrypt(s->cipher,
313
- buf, buf,
314
- 512,
315
- errp);
316
- }
317
- if (ret < 0) {
318
- return -1;
319
- }
320
- sector_num++;
321
- buf += 512;
322
- }
323
- return 0;
324
-}
325
326
/* 'allocate' is:
327
*
328
@@ -XXX,XX +XXX,XX @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
329
if (bs->encrypted &&
330
(n_end - n_start) < s->cluster_sectors) {
331
uint64_t start_sect;
332
- assert(s->cipher);
333
+ assert(s->crypto);
334
start_sect = (offset & ~(s->cluster_size - 1)) >> 9;
335
for(i = 0; i < s->cluster_sectors; i++) {
336
if (i < n_start || i >= n_end) {
337
Error *err = NULL;
338
memset(s->cluster_data, 0x00, 512);
339
- if (encrypt_sectors(s, start_sect + i,
340
- s->cluster_data, 1,
341
- true, &err) < 0) {
342
+ if (qcrypto_block_encrypt(s->crypto, start_sect + i,
343
+ s->cluster_data,
344
+ BDRV_SECTOR_SIZE,
345
+ &err) < 0) {
346
error_free(err);
347
errno = EIO;
348
return -1;
349
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn qcow_co_get_block_status(BlockDriverState *bs,
350
if (!cluster_offset) {
351
return 0;
352
}
353
- if ((cluster_offset & QCOW_OFLAG_COMPRESSED) || s->cipher) {
354
+ if ((cluster_offset & QCOW_OFLAG_COMPRESSED) || s->crypto) {
355
return BDRV_BLOCK_DATA;
356
}
357
cluster_offset |= (index_in_cluster << BDRV_SECTOR_BITS);
358
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_readv(BlockDriverState *bs, int64_t sector_num,
359
break;
360
}
361
if (bs->encrypted) {
362
- assert(s->cipher);
363
- if (encrypt_sectors(s, sector_num, buf,
364
- n, false, &err) < 0) {
365
+ assert(s->crypto);
366
+ if (qcrypto_block_decrypt(s->crypto, sector_num, buf,
367
+ n * BDRV_SECTOR_SIZE, &err) < 0) {
368
goto fail;
369
}
370
}
371
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_writev(BlockDriverState *bs, int64_t sector_num,
372
}
373
if (bs->encrypted) {
374
Error *err = NULL;
375
- assert(s->cipher);
376
- if (encrypt_sectors(s, sector_num, buf, n, true, &err) < 0) {
377
+ assert(s->crypto);
378
+ if (qcrypto_block_encrypt(s->crypto, sector_num, buf,
379
+ n * BDRV_SECTOR_SIZE, &err) < 0) {
380
error_free(err);
381
ret = -EIO;
382
break;
383
@@ -XXX,XX +XXX,XX @@ static void qcow_close(BlockDriverState *bs)
384
{
385
BDRVQcowState *s = bs->opaque;
386
387
- qcrypto_cipher_free(s->cipher);
388
- s->cipher = NULL;
389
+ qcrypto_block_free(s->crypto);
390
+ s->crypto = NULL;
391
g_free(s->l1_table);
392
qemu_vfree(s->l2_cache);
393
g_free(s->cluster_cache);
394
@@ -XXX,XX +XXX,XX @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp)
395
int ret;
396
BlockBackend *qcow_blk;
397
const char *encryptfmt = NULL;
398
+ QDict *options;
399
+ QDict *encryptopts = NULL;
400
+ QCryptoBlockCreateOptions *crypto_opts = NULL;
401
+ QCryptoBlock *crypto = NULL;
402
403
/* Read out options */
404
total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
405
@@ -XXX,XX +XXX,XX @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp)
406
l1_size = (total_size + (1LL << shift) - 1) >> shift;
407
408
header.l1_table_offset = cpu_to_be64(header_size);
409
+
410
+ options = qemu_opts_to_qdict(opts, NULL);
411
+ qdict_extract_subqdict(options, &encryptopts, "encrypt.");
412
+ QDECREF(options);
413
if (encryptfmt) {
414
if (!g_str_equal(encryptfmt, "aes")) {
415
error_setg(errp, "Unknown encryption format '%s', expected 'aes'",
416
@@ -XXX,XX +XXX,XX @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp)
417
goto exit;
418
}
419
header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
420
+
421
+ crypto_opts = block_crypto_create_opts_init(
422
+ Q_CRYPTO_BLOCK_FORMAT_QCOW, encryptopts, errp);
423
+ if (!crypto_opts) {
424
+ ret = -EINVAL;
425
+ goto exit;
426
+ }
427
+
428
+ crypto = qcrypto_block_create(crypto_opts, NULL, NULL, NULL, errp);
429
+ if (!crypto) {
430
+ ret = -EINVAL;
431
+ goto exit;
432
+ }
433
} else {
434
header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
435
}
436
@@ -XXX,XX +XXX,XX @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp)
437
exit:
438
blk_unref(qcow_blk);
439
cleanup:
440
+ QDECREF(encryptopts);
441
+ qcrypto_block_free(crypto);
442
+ qapi_free_QCryptoBlockCreateOptions(crypto_opts);
443
g_free(backing_file);
444
return ret;
445
}
446
@@ -XXX,XX +XXX,XX @@ static QemuOptsList qcow_create_opts = {
447
.type = QEMU_OPT_STRING,
448
.help = "Encrypt the image, format choices: 'aes'",
449
},
450
+ BLOCK_CRYPTO_OPT_DEF_QCOW_KEY_SECRET("encrypt."),
451
{ /* end of list */ }
452
}
453
};
454
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_qcow = {
455
.bdrv_co_writev = qcow_co_writev,
456
.bdrv_co_get_block_status = qcow_co_get_block_status,
457
458
- .bdrv_set_key = qcow_set_key,
459
.bdrv_make_empty = qcow_make_empty,
460
.bdrv_co_pwritev_compressed = qcow_co_pwritev_compressed,
461
.bdrv_get_info = qcow_get_info,
462
diff --git a/qapi/block-core.json b/qapi/block-core.json
463
index XXXXXXX..XXXXXXX 100644
464
--- a/qapi/block-core.json
465
+++ b/qapi/block-core.json
466
@@ -XXX,XX +XXX,XX @@
467
'mode': 'Qcow2OverlapCheckMode' } }
468
469
##
470
+# @BlockdevQcowEncryptionFormat:
471
+#
472
+# @aes: AES-CBC with plain64 initialization vectors
473
+#
474
+# Since: 2.10
475
+##
476
+{ 'enum': 'BlockdevQcowEncryptionFormat',
477
+ 'data': [ 'aes' ] }
478
+
479
+##
480
+# @BlockdevQcowEncryption:
481
+#
482
+# Since: 2.10
483
+##
484
+{ 'union': 'BlockdevQcowEncryption',
485
+ 'base': { 'format': 'BlockdevQcowEncryptionFormat' },
486
+ 'discriminator': 'format',
487
+ 'data': { 'aes': 'QCryptoBlockOptionsQCow' } }
488
+
489
+##
490
+# @BlockdevOptionsQcow:
491
+#
492
+# Driver specific block device options for qcow.
493
+#
494
+# @encrypt: Image decryption options. Mandatory for
495
+# encrypted images, except when doing a metadata-only
496
+# probe of the image.
497
+#
498
+# Since: 2.10
499
+##
500
+{ 'struct': 'BlockdevOptionsQcow',
501
+ 'base': 'BlockdevOptionsGenericCOWFormat',
502
+ 'data': { '*encrypt': 'BlockdevQcowEncryption' } }
503
+
504
+
505
+##
506
# @BlockdevOptionsQcow2:
507
#
508
# Driver specific block device options for qcow2.
509
@@ -XXX,XX +XXX,XX @@
510
'null-co': 'BlockdevOptionsNull',
511
'parallels': 'BlockdevOptionsGenericFormat',
512
'qcow2': 'BlockdevOptionsQcow2',
513
- 'qcow': 'BlockdevOptionsGenericCOWFormat',
514
+ 'qcow': 'BlockdevOptionsQcow',
515
'qed': 'BlockdevOptionsGenericCOWFormat',
516
'quorum': 'BlockdevOptionsQuorum',
517
'raw': 'BlockdevOptionsRaw',
518
--
519
1.8.3.1
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-cluster.c | 17 ++++++-----------
14
block/qcow2.c | 4 ++--
15
block/qcow2.h | 3 +--
16
3 files changed, 9 insertions(+), 15 deletions(-)
17
18
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/block/qcow2-cluster.c
21
+++ b/block/qcow2-cluster.c
22
@@ -XXX,XX +XXX,XX @@ static int count_contiguous_clusters_unallocated(int nb_clusters,
23
}
24
25
/* The crypt function is compatible with the linux cryptoloop
26
- algorithm for < 4 GB images. NOTE: out_buf == in_buf is
27
- supported */
28
+ algorithm for < 4 GB images. */
29
int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num,
30
- uint8_t *out_buf, const uint8_t *in_buf,
31
- int nb_sectors, bool enc,
32
+ uint8_t *buf, int nb_sectors, bool enc,
33
Error **errp)
34
{
35
union {
36
@@ -XXX,XX +XXX,XX @@ int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num,
37
}
38
if (enc) {
39
ret = qcrypto_cipher_encrypt(s->cipher,
40
- in_buf,
41
- out_buf,
42
+ buf, buf,
43
512,
44
errp);
45
} else {
46
ret = qcrypto_cipher_decrypt(s->cipher,
47
- in_buf,
48
- out_buf,
49
+ buf, buf,
50
512,
51
errp);
52
}
53
@@ -XXX,XX +XXX,XX @@ int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num,
54
return -1;
55
}
56
sector_num++;
57
- in_buf += 512;
58
- out_buf += 512;
59
+ buf += 512;
60
}
61
return 0;
62
}
63
@@ -XXX,XX +XXX,XX @@ static bool coroutine_fn do_perform_cow_encrypt(BlockDriverState *bs,
64
assert(s->cipher);
65
assert((offset_in_cluster & ~BDRV_SECTOR_MASK) == 0);
66
assert((bytes & ~BDRV_SECTOR_MASK) == 0);
67
- if (qcow2_encrypt_sectors(s, sector, buffer, buffer,
68
+ if (qcow2_encrypt_sectors(s, sector, buffer,
69
bytes >> BDRV_SECTOR_BITS, true, NULL) < 0) {
70
return false;
71
}
72
diff --git a/block/qcow2.c b/block/qcow2.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/block/qcow2.c
75
+++ b/block/qcow2.c
76
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
77
assert((cur_bytes & (BDRV_SECTOR_SIZE - 1)) == 0);
78
Error *err = NULL;
79
if (qcow2_encrypt_sectors(s, offset >> BDRV_SECTOR_BITS,
80
- cluster_data, cluster_data,
81
+ cluster_data,
82
cur_bytes >> BDRV_SECTOR_BITS,
83
false, &err) < 0) {
84
error_free(err);
85
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset,
86
qemu_iovec_to_buf(&hd_qiov, 0, cluster_data, hd_qiov.size);
87
88
if (qcow2_encrypt_sectors(s, offset >> BDRV_SECTOR_BITS,
89
- cluster_data, cluster_data,
90
+ cluster_data,
91
cur_bytes >>BDRV_SECTOR_BITS,
92
true, &err) < 0) {
93
error_free(err);
94
diff --git a/block/qcow2.h b/block/qcow2.h
95
index XXXXXXX..XXXXXXX 100644
96
--- a/block/qcow2.h
97
+++ b/block/qcow2.h
98
@@ -XXX,XX +XXX,XX @@ int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
99
int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index);
100
int qcow2_decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset);
101
int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num,
102
- uint8_t *out_buf, const uint8_t *in_buf,
103
- int nb_sectors, bool enc, Error **errp);
104
+ uint8_t *buf, int nb_sectors, bool enc, Error **errp);
105
106
int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
107
unsigned int *bytes, uint64_t *cluster_offset);
108
--
109
1.8.3.1
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
block/qcow2-cluster.c | 47 +---------
25
block/qcow2.c | 226 ++++++++++++++++++++++++++++++---------------
26
block/qcow2.h | 5 +-
27
qapi/block-core.json | 27 +++++-
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/block/qcow2-cluster.c b/block/qcow2-cluster.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/block/qcow2-cluster.c
43
+++ b/block/qcow2-cluster.c
44
@@ -XXX,XX +XXX,XX @@ static int count_contiguous_clusters_unallocated(int nb_clusters,
45
return i;
46
}
47
48
-/* The crypt function is compatible with the linux cryptoloop
49
- algorithm for < 4 GB images. */
50
-int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num,
51
- uint8_t *buf, int nb_sectors, bool enc,
52
- Error **errp)
53
-{
54
- union {
55
- uint64_t ll[2];
56
- uint8_t b[16];
57
- } ivec;
58
- int i;
59
- int ret;
60
-
61
- for(i = 0; i < nb_sectors; i++) {
62
- ivec.ll[0] = cpu_to_le64(sector_num);
63
- ivec.ll[1] = 0;
64
- if (qcrypto_cipher_setiv(s->cipher,
65
- ivec.b, G_N_ELEMENTS(ivec.b),
66
- errp) < 0) {
67
- return -1;
68
- }
69
- if (enc) {
70
- ret = qcrypto_cipher_encrypt(s->cipher,
71
- buf, buf,
72
- 512,
73
- errp);
74
- } else {
75
- ret = qcrypto_cipher_decrypt(s->cipher,
76
- buf, buf,
77
- 512,
78
- errp);
79
- }
80
- if (ret < 0) {
81
- return -1;
82
- }
83
- sector_num++;
84
- buf += 512;
85
- }
86
- return 0;
87
-}
88
-
89
static int coroutine_fn do_perform_cow_read(BlockDriverState *bs,
90
uint64_t src_cluster_offset,
91
unsigned offset_in_cluster,
92
@@ -XXX,XX +XXX,XX @@ static bool coroutine_fn do_perform_cow_encrypt(BlockDriverState *bs,
93
BDRVQcow2State *s = bs->opaque;
94
int64_t sector = (src_cluster_offset + offset_in_cluster)
95
>> BDRV_SECTOR_BITS;
96
- assert(s->cipher);
97
assert((offset_in_cluster & ~BDRV_SECTOR_MASK) == 0);
98
assert((bytes & ~BDRV_SECTOR_MASK) == 0);
99
- if (qcow2_encrypt_sectors(s, sector, buffer,
100
- bytes >> BDRV_SECTOR_BITS, true, NULL) < 0) {
101
+ assert(s->crypto);
102
+ if (qcrypto_block_encrypt(s->crypto, sector, buffer,
103
+ bytes, NULL) < 0) {
104
return false;
105
}
106
}
107
diff --git a/block/qcow2.c b/block/qcow2.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/block/qcow2.c
110
+++ b/block/qcow2.c
111
@@ -XXX,XX +XXX,XX @@
112
#include "qemu/option_int.h"
113
#include "qemu/cutils.h"
114
#include "qemu/bswap.h"
115
+#include "qapi/opts-visitor.h"
116
+#include "qapi-visit.h"
117
+#include "block/crypto.h"
118
119
/*
120
Differences with QCOW:
121
@@ -XXX,XX +XXX,XX @@ static QemuOptsList qcow2_runtime_opts = {
122
.type = QEMU_OPT_NUMBER,
123
.help = "Clean unused cache entries after this time (in seconds)",
124
},
125
+ BLOCK_CRYPTO_OPT_DEF_QCOW_KEY_SECRET("encrypt."),
126
{ /* end of list */ }
127
},
128
};
129
@@ -XXX,XX +XXX,XX @@ typedef struct Qcow2ReopenState {
130
int overlap_check;
131
bool discard_passthrough[QCOW2_DISCARD_MAX];
132
uint64_t cache_clean_interval;
133
+ QCryptoBlockOpenOptions *crypto_opts; /* Disk encryption runtime options */
134
} Qcow2ReopenState;
135
136
static int qcow2_update_options_prepare(BlockDriverState *bs,
137
@@ -XXX,XX +XXX,XX @@ static int qcow2_update_options_prepare(BlockDriverState *bs,
138
int overlap_check_template = 0;
139
uint64_t l2_cache_size, refcount_cache_size;
140
int i;
141
+ const char *encryptfmt;
142
+ QDict *encryptopts = NULL;
143
Error *local_err = NULL;
144
int ret;
145
146
+ qdict_extract_subqdict(options, &encryptopts, "encrypt.");
147
+ encryptfmt = qdict_get_try_str(encryptopts, "format");
148
+
149
opts = qemu_opts_create(&qcow2_runtime_opts, NULL, 0, &error_abort);
150
qemu_opts_absorb_qdict(opts, options, &local_err);
151
if (local_err) {
152
@@ -XXX,XX +XXX,XX @@ static int qcow2_update_options_prepare(BlockDriverState *bs,
153
r->discard_passthrough[QCOW2_DISCARD_OTHER] =
154
qemu_opt_get_bool(opts, QCOW2_OPT_DISCARD_OTHER, false);
155
156
+ switch (s->crypt_method_header) {
157
+ case QCOW_CRYPT_NONE:
158
+ if (encryptfmt) {
159
+ error_setg(errp, "No encryption in image header, but options "
160
+ "specified format '%s'", encryptfmt);
161
+ ret = -EINVAL;
162
+ goto fail;
163
+ }
164
+ break;
165
+
166
+ case QCOW_CRYPT_AES:
167
+ if (encryptfmt && !g_str_equal(encryptfmt, "aes")) {
168
+ error_setg(errp,
169
+ "Header reported 'aes' encryption format but "
170
+ "options specify '%s'", encryptfmt);
171
+ ret = -EINVAL;
172
+ goto fail;
173
+ }
174
+ qdict_del(encryptopts, "format");
175
+ r->crypto_opts = block_crypto_open_opts_init(
176
+ Q_CRYPTO_BLOCK_FORMAT_QCOW, encryptopts, errp);
177
+ break;
178
+
179
+ default:
180
+ error_setg(errp, "Unsupported encryption method %d",
181
+ s->crypt_method_header);
182
+ break;
183
+ }
184
+ if (s->crypt_method_header != QCOW_CRYPT_NONE && !r->crypto_opts) {
185
+ ret = -EINVAL;
186
+ goto fail;
187
+ }
188
+
189
ret = 0;
190
fail:
191
+ QDECREF(encryptopts);
192
qemu_opts_del(opts);
193
opts = NULL;
194
return ret;
195
@@ -XXX,XX +XXX,XX @@ static void qcow2_update_options_commit(BlockDriverState *bs,
196
s->cache_clean_interval = r->cache_clean_interval;
197
cache_clean_timer_init(bs, bdrv_get_aio_context(bs));
198
}
199
+
200
+ qapi_free_QCryptoBlockOpenOptions(s->crypto_opts);
201
+ s->crypto_opts = r->crypto_opts;
202
}
203
204
static void qcow2_update_options_abort(BlockDriverState *bs,
205
@@ -XXX,XX +XXX,XX @@ static void qcow2_update_options_abort(BlockDriverState *bs,
206
if (r->refcount_block_cache) {
207
qcow2_cache_destroy(bs, r->refcount_block_cache);
208
}
209
+ qapi_free_QCryptoBlockOpenOptions(r->crypto_opts);
210
}
211
212
static int qcow2_update_options(BlockDriverState *bs, QDict *options,
213
@@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
214
ret = -EINVAL;
215
goto fail;
216
}
217
- if (!qcrypto_cipher_supports(QCRYPTO_CIPHER_ALG_AES_128,
218
- QCRYPTO_CIPHER_MODE_CBC)) {
219
- error_setg(errp, "AES cipher not available");
220
- ret = -EINVAL;
221
- goto fail;
222
- }
223
s->crypt_method_header = header.crypt_method;
224
if (s->crypt_method_header) {
225
if (bdrv_uses_whitelist() &&
226
@@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
227
}
228
229
bs->encrypted = true;
230
+ bs->valid_key = true;
231
}
232
233
s->l2_bits = s->cluster_bits - 3; /* L2 is always one cluster */
234
@@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
235
goto fail;
236
}
237
238
+ if (s->crypt_method_header == QCOW_CRYPT_AES) {
239
+ unsigned int cflags = 0;
240
+ if (flags & BDRV_O_NO_IO) {
241
+ cflags |= QCRYPTO_BLOCK_OPEN_NO_IO;
242
+ }
243
+ s->crypto = qcrypto_block_open(s->crypto_opts, NULL, NULL,
244
+ cflags, errp);
245
+ if (!s->crypto) {
246
+ ret = -EINVAL;
247
+ goto fail;
248
+ }
249
+ }
250
+
251
/* read the backing file name */
252
if (header.backing_file_offset != 0) {
253
len = header.backing_file_size;
254
@@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
255
}
256
g_free(s->cluster_cache);
257
qemu_vfree(s->cluster_data);
258
+ qcrypto_block_free(s->crypto);
259
+ qapi_free_QCryptoBlockOpenOptions(s->crypto_opts);
260
return ret;
261
}
262
263
@@ -XXX,XX +XXX,XX @@ static void qcow2_refresh_limits(BlockDriverState *bs, Error **errp)
264
bs->bl.pdiscard_alignment = s->cluster_size;
265
}
266
267
-static int qcow2_set_key(BlockDriverState *bs, const char *key)
268
-{
269
- BDRVQcow2State *s = bs->opaque;
270
- uint8_t keybuf[16];
271
- int len, i;
272
- Error *err = NULL;
273
-
274
- memset(keybuf, 0, 16);
275
- len = strlen(key);
276
- if (len > 16)
277
- len = 16;
278
- /* XXX: we could compress the chars to 7 bits to increase
279
- entropy */
280
- for(i = 0;i < len;i++) {
281
- keybuf[i] = key[i];
282
- }
283
- assert(bs->encrypted);
284
-
285
- qcrypto_cipher_free(s->cipher);
286
- s->cipher = qcrypto_cipher_new(
287
- QCRYPTO_CIPHER_ALG_AES_128,
288
- QCRYPTO_CIPHER_MODE_CBC,
289
- keybuf, G_N_ELEMENTS(keybuf),
290
- &err);
291
-
292
- if (!s->cipher) {
293
- /* XXX would be nice if errors in this method could
294
- * be properly propagate to the caller. Would need
295
- * the bdrv_set_key() API signature to be fixed. */
296
- error_free(err);
297
- return -1;
298
- }
299
- return 0;
300
-}
301
-
302
static int qcow2_reopen_prepare(BDRVReopenState *state,
303
BlockReopenQueue *queue, Error **errp)
304
{
305
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn qcow2_co_get_block_status(BlockDriverState *bs,
306
*pnum = bytes >> BDRV_SECTOR_BITS;
307
308
if (cluster_offset != 0 && ret != QCOW2_CLUSTER_COMPRESSED &&
309
- !s->cipher) {
310
+ !s->crypto) {
311
index_in_cluster = sector_num & (s->cluster_sectors - 1);
312
cluster_offset |= (index_in_cluster << BDRV_SECTOR_BITS);
313
*file = bs->file->bs;
314
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
315
316
/* prepare next request */
317
cur_bytes = MIN(bytes, INT_MAX);
318
- if (s->cipher) {
319
+ if (s->crypto) {
320
cur_bytes = MIN(cur_bytes,
321
QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
322
}
323
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
324
}
325
326
if (bs->encrypted) {
327
- assert(s->cipher);
328
+ assert(s->crypto);
329
330
/*
331
* For encrypted images, read everything into a temporary
332
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
333
goto fail;
334
}
335
if (bs->encrypted) {
336
- assert(s->cipher);
337
+ assert(s->crypto);
338
assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0);
339
assert((cur_bytes & (BDRV_SECTOR_SIZE - 1)) == 0);
340
Error *err = NULL;
341
- if (qcow2_encrypt_sectors(s, offset >> BDRV_SECTOR_BITS,
342
+ if (qcrypto_block_decrypt(s->crypto,
343
+ offset >> BDRV_SECTOR_BITS,
344
cluster_data,
345
- cur_bytes >> BDRV_SECTOR_BITS,
346
- false, &err) < 0) {
347
+ cur_bytes,
348
+ &err) < 0) {
349
error_free(err);
350
ret = -EIO;
351
goto fail;
352
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset,
353
354
if (bs->encrypted) {
355
Error *err = NULL;
356
- assert(s->cipher);
357
+ assert(s->crypto);
358
if (!cluster_data) {
359
cluster_data = qemu_try_blockalign(bs->file->bs,
360
QCOW_MAX_CRYPT_CLUSTERS
361
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset,
362
QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
363
qemu_iovec_to_buf(&hd_qiov, 0, cluster_data, hd_qiov.size);
364
365
- if (qcow2_encrypt_sectors(s, offset >> BDRV_SECTOR_BITS,
366
+ if (qcrypto_block_encrypt(s->crypto, offset >> BDRV_SECTOR_BITS,
367
cluster_data,
368
- cur_bytes >>BDRV_SECTOR_BITS,
369
- true, &err) < 0) {
370
+ cur_bytes, &err) < 0) {
371
error_free(err);
372
ret = -EIO;
373
goto fail;
374
@@ -XXX,XX +XXX,XX @@ static void qcow2_close(BlockDriverState *bs)
375
qcow2_cache_destroy(bs, s->l2_table_cache);
376
qcow2_cache_destroy(bs, s->refcount_block_cache);
377
378
- qcrypto_cipher_free(s->cipher);
379
- s->cipher = NULL;
380
+ qcrypto_block_free(s->crypto);
381
+ s->crypto = NULL;
382
383
g_free(s->unknown_header_fields);
384
cleanup_unknown_header_ext(bs);
385
@@ -XXX,XX +XXX,XX @@ static void qcow2_invalidate_cache(BlockDriverState *bs, Error **errp)
386
{
387
BDRVQcow2State *s = bs->opaque;
388
int flags = s->flags;
389
- QCryptoCipher *cipher = NULL;
390
+ QCryptoBlock *crypto = NULL;
391
QDict *options;
392
Error *local_err = NULL;
393
int ret;
394
@@ -XXX,XX +XXX,XX @@ static void qcow2_invalidate_cache(BlockDriverState *bs, Error **errp)
395
* that means we don't have to worry about reopening them here.
396
*/
397
398
- cipher = s->cipher;
399
- s->cipher = NULL;
400
+ crypto = s->crypto;
401
+ s->crypto = NULL;
402
403
qcow2_close(bs);
404
405
@@ -XXX,XX +XXX,XX @@ static void qcow2_invalidate_cache(BlockDriverState *bs, Error **errp)
406
return;
407
}
408
409
- s->cipher = cipher;
410
+ s->crypto = crypto;
411
}
412
413
static size_t header_ext_add(char *buf, uint32_t magic, const void *s,
414
@@ -XXX,XX +XXX,XX @@ static int qcow2_change_backing_file(BlockDriverState *bs,
415
return qcow2_update_header(bs);
416
}
417
418
+
419
+static int qcow2_set_up_encryption(BlockDriverState *bs, const char *encryptfmt,
420
+ QemuOpts *opts, Error **errp)
421
+{
422
+ BDRVQcow2State *s = bs->opaque;
423
+ QCryptoBlockCreateOptions *cryptoopts = NULL;
424
+ QCryptoBlock *crypto = NULL;
425
+ int ret = -EINVAL;
426
+ QDict *options, *encryptopts;
427
+
428
+ options = qemu_opts_to_qdict(opts, NULL);
429
+ qdict_extract_subqdict(options, &encryptopts, "encrypt.");
430
+ QDECREF(options);
431
+
432
+ if (!g_str_equal(encryptfmt, "aes")) {
433
+ error_setg(errp, "Unknown encryption format '%s', expected 'aes'",
434
+ encryptfmt);
435
+ ret = -EINVAL;
436
+ goto out;
437
+ }
438
+ cryptoopts = block_crypto_create_opts_init(
439
+ Q_CRYPTO_BLOCK_FORMAT_QCOW, encryptopts, errp);
440
+ if (!cryptoopts) {
441
+ ret = -EINVAL;
442
+ goto out;
443
+ }
444
+ s->crypt_method_header = QCOW_CRYPT_AES;
445
+
446
+ crypto = qcrypto_block_create(cryptoopts,
447
+ NULL, NULL,
448
+ bs, errp);
449
+ if (!crypto) {
450
+ ret = -EINVAL;
451
+ goto out;
452
+ }
453
+
454
+ ret = qcow2_update_header(bs);
455
+ if (ret < 0) {
456
+ error_setg_errno(errp, -ret, "Could not write encryption header");
457
+ goto out;
458
+ }
459
+
460
+ out:
461
+ QDECREF(encryptopts);
462
+ qcrypto_block_free(crypto);
463
+ qapi_free_QCryptoBlockCreateOptions(cryptoopts);
464
+ return ret;
465
+}
466
+
467
+
468
static int preallocate(BlockDriverState *bs)
469
{
470
uint64_t bytes;
471
@@ -XXX,XX +XXX,XX @@ static int qcow2_create2(const char *filename, int64_t total_size,
472
.header_length = cpu_to_be32(sizeof(*header)),
473
};
474
475
- if (encryptfmt) {
476
- if (!g_str_equal(encryptfmt, "aes")) {
477
- error_setg(errp, "Unknown encryption format '%s', expected 'aes'",
478
- encryptfmt);
479
- ret = -EINVAL;
480
- goto out;
481
- }
482
- header->crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
483
- } else {
484
- header->crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
485
- }
486
+ /* We'll update this to correct value later */
487
+ header->crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
488
489
if (flags & BLOCK_FLAG_LAZY_REFCOUNTS) {
490
header->compatible_features |=
491
@@ -XXX,XX +XXX,XX @@ static int qcow2_create2(const char *filename, int64_t total_size,
492
}
493
}
494
495
+ /* Want encryption? There you go. */
496
+ if (encryptfmt) {
497
+ ret = qcow2_set_up_encryption(blk_bs(blk), encryptfmt, opts, errp);
498
+ if (ret < 0) {
499
+ goto out;
500
+ }
501
+ }
502
+
503
/* And if we're supposed to preallocate metadata, do that now */
504
if (prealloc != PREALLOC_MODE_OFF) {
505
BDRVQcow2State *s = blk_bs(blk)->opaque;
506
@@ -XXX,XX +XXX,XX @@ static int qcow2_create2(const char *filename, int64_t total_size,
507
blk_unref(blk);
508
blk = NULL;
509
510
- /* Reopen the image without BDRV_O_NO_FLUSH to flush it before returning */
511
+ /* Reopen the image without BDRV_O_NO_FLUSH to flush it before returning.
512
+ * Using BDRV_O_NO_IO, since encryption is now setup we don't want to
513
+ * have to setup decryption context. We're not doing any I/O on the top
514
+ * level BlockDriverState, only lower layers, where BDRV_O_NO_IO does
515
+ * not have effect.
516
+ */
517
options = qdict_new();
518
qdict_put_str(options, "driver", "qcow2");
519
blk = blk_new_open(filename, NULL, options,
520
- BDRV_O_RDWR | BDRV_O_NO_BACKING, &local_err);
521
+ BDRV_O_RDWR | BDRV_O_NO_BACKING | BDRV_O_NO_IO,
522
+ &local_err);
523
if (blk == NULL) {
524
error_propagate(errp, local_err);
525
ret = -EIO;
526
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
527
backing_format = qemu_opt_get(opts, BLOCK_OPT_BACKING_FMT);
528
} else if (!strcmp(desc->name, BLOCK_OPT_ENCRYPT)) {
529
encrypt = qemu_opt_get_bool(opts, BLOCK_OPT_ENCRYPT,
530
- !!s->cipher);
531
+ !!s->crypto);
532
533
- if (encrypt != !!s->cipher) {
534
+ if (encrypt != !!s->crypto) {
535
error_report("Changing the encryption flag is not supported");
536
return -ENOTSUP;
537
}
538
@@ -XXX,XX +XXX,XX @@ static QemuOptsList qcow2_create_opts = {
539
.type = QEMU_OPT_STRING,
540
.help = "Encrypt the image, format choices: 'aes'",
541
},
542
+ BLOCK_CRYPTO_OPT_DEF_QCOW_KEY_SECRET("encrypt."),
543
{
544
.name = BLOCK_OPT_CLUSTER_SIZE,
545
.type = QEMU_OPT_SIZE,
546
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_qcow2 = {
547
.bdrv_create = qcow2_create,
548
.bdrv_has_zero_init = bdrv_has_zero_init_1,
549
.bdrv_co_get_block_status = qcow2_co_get_block_status,
550
- .bdrv_set_key = qcow2_set_key,
551
552
.bdrv_co_preadv = qcow2_co_preadv,
553
.bdrv_co_pwritev = qcow2_co_pwritev,
554
diff --git a/block/qcow2.h b/block/qcow2.h
555
index XXXXXXX..XXXXXXX 100644
556
--- a/block/qcow2.h
557
+++ b/block/qcow2.h
558
@@ -XXX,XX +XXX,XX @@
559
#ifndef BLOCK_QCOW2_H
560
#define BLOCK_QCOW2_H
561
562
-#include "crypto/cipher.h"
563
+#include "crypto/block.h"
564
#include "qemu/coroutine.h"
565
566
//#define DEBUG_ALLOC
567
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVQcow2State {
568
569
CoMutex lock;
570
571
- QCryptoCipher *cipher; /* current cipher, NULL if no key yet */
572
+ QCryptoBlockOpenOptions *crypto_opts; /* Disk encryption runtime options */
573
+ QCryptoBlock *crypto; /* Disk encryption format driver */
574
uint32_t crypt_method_header;
575
uint64_t snapshots_offset;
576
int snapshots_size;
577
diff --git a/qapi/block-core.json b/qapi/block-core.json
578
index XXXXXXX..XXXXXXX 100644
579
--- a/qapi/block-core.json
580
+++ b/qapi/block-core.json
581
@@ -XXX,XX +XXX,XX @@
582
'data': { '*encrypt': 'BlockdevQcowEncryption' } }
583
584
585
+
586
+##
587
+# @BlockdevQcow2EncryptionFormat:
588
+# @aes: AES-CBC with plain64 initialization venctors
589
+#
590
+# Since: 2.10
591
+##
592
+{ 'enum': 'BlockdevQcow2EncryptionFormat',
593
+ 'data': [ 'aes' ] }
594
+
595
+##
596
+# @BlockdevQcow2Encryption:
597
+#
598
+# Since: 2.10
599
+##
600
+{ 'union': 'BlockdevQcow2Encryption',
601
+ 'base': { 'format': 'BlockdevQcow2EncryptionFormat' },
602
+ 'discriminator': 'format',
603
+ 'data': { 'aes': 'QCryptoBlockOptionsQCow' } }
604
+
605
##
606
# @BlockdevOptionsQcow2:
607
#
608
@@ -XXX,XX +XXX,XX @@
609
# @cache-clean-interval: clean unused entries in the L2 and refcount
610
# caches. The interval is in seconds. The default value
611
# is 0 and it disables this feature (since 2.5)
612
+# @encrypt: Image decryption options. Mandatory for
613
+# encrypted images, except when doing a metadata-only
614
+# probe of the image. (since 2.10)
615
#
616
# Since: 2.9
617
##
618
@@ -XXX,XX +XXX,XX @@
619
'*cache-size': 'int',
620
'*l2-cache-size': 'int',
621
'*refcount-cache-size': 'int',
622
- '*cache-clean-interval': 'int' } }
623
-
624
+ '*cache-clean-interval': 'int',
625
+ '*encrypt': 'BlockdevQcow2Encryption' } }
626
627
##
628
# @BlockdevOptionsSsh:
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
1.8.3.1
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
1.8.3.1
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
block/qcow2-cluster.c | 14 ++-
50
block/qcow2-refcount.c | 10 ++
51
block/qcow2.c | 268 ++++++++++++++++++++++++++++++++++++++------
52
block/qcow2.h | 9 ++
53
qapi/block-core.json | 5 +-
54
tests/qemu-iotests/082.out | 270 ++++++++++++++++++++++++++++++++++++---------
55
6 files changed, 484 insertions(+), 92 deletions(-)
56
57
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/block/qcow2-cluster.c
60
+++ b/block/qcow2-cluster.c
61
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn do_perform_cow_read(BlockDriverState *bs,
62
63
static bool coroutine_fn do_perform_cow_encrypt(BlockDriverState *bs,
64
uint64_t src_cluster_offset,
65
+ uint64_t cluster_offset,
66
unsigned offset_in_cluster,
67
uint8_t *buffer,
68
unsigned bytes)
69
{
70
if (bytes && bs->encrypted) {
71
BDRVQcow2State *s = bs->opaque;
72
- int64_t sector = (src_cluster_offset + offset_in_cluster)
73
+ int64_t sector = (s->crypt_physical_offset ?
74
+ (cluster_offset + offset_in_cluster) :
75
+ (src_cluster_offset + offset_in_cluster))
76
>> BDRV_SECTOR_BITS;
77
assert((offset_in_cluster & ~BDRV_SECTOR_MASK) == 0);
78
assert((bytes & ~BDRV_SECTOR_MASK) == 0);
79
@@ -XXX,XX +XXX,XX @@ static int perform_cow(BlockDriverState *bs, QCowL2Meta *m)
80
81
/* Encrypt the data if necessary before writing it */
82
if (bs->encrypted) {
83
- if (!do_perform_cow_encrypt(bs, m->offset, start->offset,
84
- start_buffer, start->nb_bytes) ||
85
- !do_perform_cow_encrypt(bs, m->offset, end->offset,
86
- end_buffer, end->nb_bytes)) {
87
+ if (!do_perform_cow_encrypt(bs, m->offset, m->alloc_offset,
88
+ start->offset, start_buffer,
89
+ start->nb_bytes) ||
90
+ !do_perform_cow_encrypt(bs, m->offset, m->alloc_offset,
91
+ end->offset, end_buffer, end->nb_bytes)) {
92
ret = -EIO;
93
goto fail;
94
}
95
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
96
index XXXXXXX..XXXXXXX 100644
97
--- a/block/qcow2-refcount.c
98
+++ b/block/qcow2-refcount.c
99
@@ -XXX,XX +XXX,XX @@ static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
100
return ret;
101
}
102
103
+ /* encryption */
104
+ if (s->crypto_header.length) {
105
+ ret = inc_refcounts(bs, res, refcount_table, nb_clusters,
106
+ s->crypto_header.offset,
107
+ s->crypto_header.length);
108
+ if (ret < 0) {
109
+ return ret;
110
+ }
111
+ }
112
+
113
return check_refblocks(bs, res, fix, rebuild, refcount_table, nb_clusters);
114
}
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 @@ typedef struct {
121
#define QCOW2_EXT_MAGIC_END 0
122
#define QCOW2_EXT_MAGIC_BACKING_FORMAT 0xE2792ACA
123
#define QCOW2_EXT_MAGIC_FEATURE_TABLE 0x6803f857
124
+#define QCOW2_EXT_MAGIC_CRYPTO_HEADER 0x0537be77
125
126
static int qcow2_probe(const uint8_t *buf, int buf_size, const char *filename)
127
{
128
@@ -XXX,XX +XXX,XX @@ static int qcow2_probe(const uint8_t *buf, int buf_size, const char *filename)
129
}
130
131
132
+static ssize_t qcow2_crypto_hdr_read_func(QCryptoBlock *block, size_t offset,
133
+ uint8_t *buf, size_t buflen,
134
+ void *opaque, Error **errp)
135
+{
136
+ BlockDriverState *bs = opaque;
137
+ BDRVQcow2State *s = bs->opaque;
138
+ ssize_t ret;
139
+
140
+ if ((offset + buflen) > s->crypto_header.length) {
141
+ error_setg(errp, "Request for data outside of extension header");
142
+ return -1;
143
+ }
144
+
145
+ ret = bdrv_pread(bs->file,
146
+ s->crypto_header.offset + offset, buf, buflen);
147
+ if (ret < 0) {
148
+ error_setg_errno(errp, -ret, "Could not read encryption header");
149
+ return -1;
150
+ }
151
+ return ret;
152
+}
153
+
154
+
155
+static ssize_t qcow2_crypto_hdr_init_func(QCryptoBlock *block, size_t headerlen,
156
+ void *opaque, Error **errp)
157
+{
158
+ BlockDriverState *bs = opaque;
159
+ BDRVQcow2State *s = bs->opaque;
160
+ int64_t ret;
161
+ int64_t clusterlen;
162
+
163
+ ret = qcow2_alloc_clusters(bs, headerlen);
164
+ if (ret < 0) {
165
+ error_setg_errno(errp, -ret,
166
+ "Cannot allocate cluster for LUKS header size %zu",
167
+ headerlen);
168
+ return -1;
169
+ }
170
+
171
+ s->crypto_header.length = headerlen;
172
+ s->crypto_header.offset = ret;
173
+
174
+ /* Zero fill remaining space in cluster so it has predictable
175
+ * content in case of future spec changes */
176
+ clusterlen = size_to_clusters(s, headerlen) * s->cluster_size;
177
+ ret = bdrv_pwrite_zeroes(bs->file,
178
+ ret + headerlen,
179
+ clusterlen - headerlen, 0);
180
+ if (ret < 0) {
181
+ error_setg_errno(errp, -ret, "Could not zero fill encryption header");
182
+ return -1;
183
+ }
184
+
185
+ return ret;
186
+}
187
+
188
+
189
+static ssize_t qcow2_crypto_hdr_write_func(QCryptoBlock *block, size_t offset,
190
+ const uint8_t *buf, size_t buflen,
191
+ void *opaque, Error **errp)
192
+{
193
+ BlockDriverState *bs = opaque;
194
+ BDRVQcow2State *s = bs->opaque;
195
+ ssize_t ret;
196
+
197
+ if ((offset + buflen) > s->crypto_header.length) {
198
+ error_setg(errp, "Request for data outside of extension header");
199
+ return -1;
200
+ }
201
+
202
+ ret = bdrv_pwrite(bs->file,
203
+ s->crypto_header.offset + offset, buf, buflen);
204
+ if (ret < 0) {
205
+ error_setg_errno(errp, -ret, "Could not read encryption header");
206
+ return -1;
207
+ }
208
+ return ret;
209
+}
210
+
211
+
212
/*
213
* read qcow2 extension and fill bs
214
* start reading from start_offset
215
@@ -XXX,XX +XXX,XX @@ static int qcow2_probe(const uint8_t *buf, int buf_size, const char *filename)
216
*/
217
static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
218
uint64_t end_offset, void **p_feature_table,
219
- Error **errp)
220
+ int flags, Error **errp)
221
{
222
BDRVQcow2State *s = bs->opaque;
223
QCowExtension ext;
224
@@ -XXX,XX +XXX,XX @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
225
}
226
break;
227
228
+ case QCOW2_EXT_MAGIC_CRYPTO_HEADER: {
229
+ unsigned int cflags = 0;
230
+ if (s->crypt_method_header != QCOW_CRYPT_LUKS) {
231
+ error_setg(errp, "CRYPTO header extension only "
232
+ "expected with LUKS encryption method");
233
+ return -EINVAL;
234
+ }
235
+ if (ext.len != sizeof(Qcow2CryptoHeaderExtension)) {
236
+ error_setg(errp, "CRYPTO header extension size %u, "
237
+ "but expected size %zu", ext.len,
238
+ sizeof(Qcow2CryptoHeaderExtension));
239
+ return -EINVAL;
240
+ }
241
+
242
+ ret = bdrv_pread(bs->file, offset, &s->crypto_header, ext.len);
243
+ if (ret < 0) {
244
+ error_setg_errno(errp, -ret,
245
+ "Unable to read CRYPTO header extension");
246
+ return ret;
247
+ }
248
+ be64_to_cpus(&s->crypto_header.offset);
249
+ be64_to_cpus(&s->crypto_header.length);
250
+
251
+ if ((s->crypto_header.offset % s->cluster_size) != 0) {
252
+ error_setg(errp, "Encryption header offset '%" PRIu64 "' is "
253
+ "not a multiple of cluster size '%u'",
254
+ s->crypto_header.offset, s->cluster_size);
255
+ return -EINVAL;
256
+ }
257
+
258
+ if (flags & BDRV_O_NO_IO) {
259
+ cflags |= QCRYPTO_BLOCK_OPEN_NO_IO;
260
+ }
261
+ s->crypto = qcrypto_block_open(s->crypto_opts,
262
+ qcow2_crypto_hdr_read_func,
263
+ bs, cflags, errp);
264
+ if (!s->crypto) {
265
+ return -EINVAL;
266
+ }
267
+ } break;
268
+
269
default:
270
/* unknown magic - save it in case we need to rewrite the header */
271
{
272
@@ -XXX,XX +XXX,XX @@ static QemuOptsList qcow2_runtime_opts = {
273
.type = QEMU_OPT_NUMBER,
274
.help = "Clean unused cache entries after this time (in seconds)",
275
},
276
- BLOCK_CRYPTO_OPT_DEF_QCOW_KEY_SECRET("encrypt."),
277
+ BLOCK_CRYPTO_OPT_DEF_KEY_SECRET("encrypt.",
278
+ "ID of secret providing qcow2 AES key or LUKS passphrase"),
279
{ /* end of list */ }
280
},
281
};
282
@@ -XXX,XX +XXX,XX @@ static int qcow2_update_options_prepare(BlockDriverState *bs,
283
Q_CRYPTO_BLOCK_FORMAT_QCOW, encryptopts, errp);
284
break;
285
286
+ case QCOW_CRYPT_LUKS:
287
+ if (encryptfmt && !g_str_equal(encryptfmt, "luks")) {
288
+ error_setg(errp,
289
+ "Header reported 'luks' encryption format but "
290
+ "options specify '%s'", encryptfmt);
291
+ ret = -EINVAL;
292
+ goto fail;
293
+ }
294
+ qdict_del(encryptopts, "format");
295
+ r->crypto_opts = block_crypto_open_opts_init(
296
+ Q_CRYPTO_BLOCK_FORMAT_LUKS, encryptopts, errp);
297
+ break;
298
+
299
default:
300
error_setg(errp, "Unsupported encryption method %d",
301
s->crypt_method_header);
302
@@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
303
if (s->incompatible_features & ~QCOW2_INCOMPAT_MASK) {
304
void *feature_table = NULL;
305
qcow2_read_extensions(bs, header.header_length, ext_end,
306
- &feature_table, NULL);
307
+ &feature_table, flags, NULL);
308
report_unsupported_feature(errp, feature_table,
309
s->incompatible_features &
310
~QCOW2_INCOMPAT_MASK);
311
@@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
312
s->refcount_max = UINT64_C(1) << (s->refcount_bits - 1);
313
s->refcount_max += s->refcount_max - 1;
314
315
- if (header.crypt_method > QCOW_CRYPT_AES) {
316
- error_setg(errp, "Unsupported encryption method: %" PRIu32,
317
- header.crypt_method);
318
- ret = -EINVAL;
319
- goto fail;
320
- }
321
s->crypt_method_header = header.crypt_method;
322
if (s->crypt_method_header) {
323
if (bdrv_uses_whitelist() &&
324
@@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
325
goto fail;
326
}
327
328
+ if (s->crypt_method_header == QCOW_CRYPT_AES) {
329
+ s->crypt_physical_offset = false;
330
+ } else {
331
+ /* Assuming LUKS and any future crypt methods we
332
+ * add will all use physical offsets, due to the
333
+ * fact that the alternative is insecure... */
334
+ s->crypt_physical_offset = true;
335
+ }
336
+
337
bs->encrypted = true;
338
bs->valid_key = true;
339
}
340
@@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
341
342
/* read qcow2 extensions */
343
if (qcow2_read_extensions(bs, header.header_length, ext_end, NULL,
344
- &local_err)) {
345
+ flags, &local_err)) {
346
error_propagate(errp, local_err);
347
ret = -EINVAL;
348
goto fail;
349
}
350
351
- if (s->crypt_method_header == QCOW_CRYPT_AES) {
352
- unsigned int cflags = 0;
353
- if (flags & BDRV_O_NO_IO) {
354
- cflags |= QCRYPTO_BLOCK_OPEN_NO_IO;
355
- }
356
- s->crypto = qcrypto_block_open(s->crypto_opts, NULL, NULL,
357
- cflags, errp);
358
- if (!s->crypto) {
359
+ /* qcow2_read_extension may have set up the crypto context
360
+ * if the crypt method needs a header region, some methods
361
+ * don't need header extensions, so must check here
362
+ */
363
+ if (s->crypt_method_header && !s->crypto) {
364
+ if (s->crypt_method_header == QCOW_CRYPT_AES) {
365
+ unsigned int cflags = 0;
366
+ if (flags & BDRV_O_NO_IO) {
367
+ cflags |= QCRYPTO_BLOCK_OPEN_NO_IO;
368
+ }
369
+ s->crypto = qcrypto_block_open(s->crypto_opts, NULL, NULL,
370
+ cflags, errp);
371
+ if (!s->crypto) {
372
+ ret = -EINVAL;
373
+ goto fail;
374
+ }
375
+ } else if (!(flags & BDRV_O_NO_IO)) {
376
+ error_setg(errp, "Missing CRYPTO header for crypt method %d",
377
+ s->crypt_method_header);
378
ret = -EINVAL;
379
goto fail;
380
}
381
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
382
assert((cur_bytes & (BDRV_SECTOR_SIZE - 1)) == 0);
383
Error *err = NULL;
384
if (qcrypto_block_decrypt(s->crypto,
385
- offset >> BDRV_SECTOR_BITS,
386
+ (s->crypt_physical_offset ?
387
+ cluster_offset + offset_in_cluster :
388
+ offset) >> BDRV_SECTOR_BITS,
389
cluster_data,
390
cur_bytes,
391
&err) < 0) {
392
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset,
393
QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
394
qemu_iovec_to_buf(&hd_qiov, 0, cluster_data, hd_qiov.size);
395
396
- if (qcrypto_block_encrypt(s->crypto, offset >> BDRV_SECTOR_BITS,
397
+ if (qcrypto_block_encrypt(s->crypto,
398
+ (s->crypt_physical_offset ?
399
+ cluster_offset + offset_in_cluster :
400
+ offset) >> BDRV_SECTOR_BITS,
401
cluster_data,
402
cur_bytes, &err) < 0) {
403
error_free(err);
404
@@ -XXX,XX +XXX,XX @@ int qcow2_update_header(BlockDriverState *bs)
405
buflen -= ret;
406
}
407
408
+ /* Full disk encryption header pointer extension */
409
+ if (s->crypto_header.offset != 0) {
410
+ cpu_to_be64s(&s->crypto_header.offset);
411
+ cpu_to_be64s(&s->crypto_header.length);
412
+ ret = header_ext_add(buf, QCOW2_EXT_MAGIC_CRYPTO_HEADER,
413
+ &s->crypto_header, sizeof(s->crypto_header),
414
+ buflen);
415
+ be64_to_cpus(&s->crypto_header.offset);
416
+ be64_to_cpus(&s->crypto_header.length);
417
+ if (ret < 0) {
418
+ goto fail;
419
+ }
420
+ buf += ret;
421
+ buflen -= ret;
422
+ }
423
+
424
/* Feature table */
425
if (s->qcow_version >= 3) {
426
Qcow2Feature features[] = {
427
@@ -XXX,XX +XXX,XX @@ static int qcow2_change_backing_file(BlockDriverState *bs,
428
return qcow2_update_header(bs);
429
}
430
431
+static int qcow2_crypt_method_from_format(const char *encryptfmt)
432
+{
433
+ if (g_str_equal(encryptfmt, "luks")) {
434
+ return QCOW_CRYPT_LUKS;
435
+ } else if (g_str_equal(encryptfmt, "aes")) {
436
+ return QCOW_CRYPT_AES;
437
+ } else {
438
+ return -EINVAL;
439
+ }
440
+}
441
442
static int qcow2_set_up_encryption(BlockDriverState *bs, const char *encryptfmt,
443
QemuOpts *opts, Error **errp)
444
@@ -XXX,XX +XXX,XX @@ static int qcow2_set_up_encryption(BlockDriverState *bs, const char *encryptfmt,
445
QCryptoBlock *crypto = NULL;
446
int ret = -EINVAL;
447
QDict *options, *encryptopts;
448
+ int fmt;
449
450
options = qemu_opts_to_qdict(opts, NULL);
451
qdict_extract_subqdict(options, &encryptopts, "encrypt.");
452
QDECREF(options);
453
454
- if (!g_str_equal(encryptfmt, "aes")) {
455
- error_setg(errp, "Unknown encryption format '%s', expected 'aes'",
456
- encryptfmt);
457
- ret = -EINVAL;
458
- goto out;
459
+ fmt = qcow2_crypt_method_from_format(encryptfmt);
460
+
461
+ switch (fmt) {
462
+ case QCOW_CRYPT_LUKS:
463
+ cryptoopts = block_crypto_create_opts_init(
464
+ Q_CRYPTO_BLOCK_FORMAT_LUKS, encryptopts, errp);
465
+ break;
466
+ case QCOW_CRYPT_AES:
467
+ cryptoopts = block_crypto_create_opts_init(
468
+ Q_CRYPTO_BLOCK_FORMAT_QCOW, encryptopts, errp);
469
+ break;
470
+ default:
471
+ error_setg(errp, "Unknown encryption format '%s'", encryptfmt);
472
+ break;
473
}
474
- cryptoopts = block_crypto_create_opts_init(
475
- Q_CRYPTO_BLOCK_FORMAT_QCOW, encryptopts, errp);
476
if (!cryptoopts) {
477
ret = -EINVAL;
478
goto out;
479
}
480
- s->crypt_method_header = QCOW_CRYPT_AES;
481
+ s->crypt_method_header = fmt;
482
483
crypto = qcrypto_block_create(cryptoopts,
484
- NULL, NULL,
485
+ qcow2_crypto_hdr_init_func,
486
+ qcow2_crypto_hdr_write_func,
487
bs, errp);
488
if (!crypto) {
489
ret = -EINVAL;
490
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
491
const char *compat = NULL;
492
uint64_t cluster_size = s->cluster_size;
493
bool encrypt;
494
+ int encformat;
495
int refcount_bits = s->refcount_bits;
496
Error *local_err = NULL;
497
int ret;
498
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
499
error_report("Changing the encryption flag is not supported");
500
return -ENOTSUP;
501
}
502
+ } else if (!strcmp(desc->name, BLOCK_OPT_ENCRYPT_FORMAT)) {
503
+ encformat = qcow2_crypt_method_from_format(
504
+ qemu_opt_get(opts, BLOCK_OPT_ENCRYPT_FORMAT));
505
+
506
+ if (encformat != s->crypt_method_header) {
507
+ error_report("Changing the encryption format is not supported");
508
+ return -ENOTSUP;
509
+ }
510
} else if (!strcmp(desc->name, BLOCK_OPT_CLUSTER_SIZE)) {
511
cluster_size = qemu_opt_get_size(opts, BLOCK_OPT_CLUSTER_SIZE,
512
cluster_size);
513
@@ -XXX,XX +XXX,XX @@ static QemuOptsList qcow2_create_opts = {
514
{
515
.name = BLOCK_OPT_ENCRYPT_FORMAT,
516
.type = QEMU_OPT_STRING,
517
- .help = "Encrypt the image, format choices: 'aes'",
518
+ .help = "Encrypt the image, format choices: 'aes', 'luks'",
519
},
520
- BLOCK_CRYPTO_OPT_DEF_QCOW_KEY_SECRET("encrypt."),
521
+ BLOCK_CRYPTO_OPT_DEF_KEY_SECRET("encrypt.",
522
+ "ID of secret providing qcow AES key or LUKS passphrase"),
523
+ BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG("encrypt."),
524
+ BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE("encrypt."),
525
+ BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG("encrypt."),
526
+ BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG("encrypt."),
527
+ BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG("encrypt."),
528
+ BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME("encrypt."),
529
{
530
.name = BLOCK_OPT_CLUSTER_SIZE,
531
.type = QEMU_OPT_SIZE,
532
diff --git a/block/qcow2.h b/block/qcow2.h
533
index XXXXXXX..XXXXXXX 100644
534
--- a/block/qcow2.h
535
+++ b/block/qcow2.h
536
@@ -XXX,XX +XXX,XX @@
537
538
#define QCOW_CRYPT_NONE 0
539
#define QCOW_CRYPT_AES 1
540
+#define QCOW_CRYPT_LUKS 2
541
542
#define QCOW_MAX_CRYPT_CLUSTERS 32
543
#define QCOW_MAX_SNAPSHOTS 65536
544
@@ -XXX,XX +XXX,XX @@ typedef struct QCowSnapshot {
545
struct Qcow2Cache;
546
typedef struct Qcow2Cache Qcow2Cache;
547
548
+typedef struct Qcow2CryptoHeaderExtension {
549
+ uint64_t offset;
550
+ uint64_t length;
551
+} QEMU_PACKED Qcow2CryptoHeaderExtension;
552
+
553
typedef struct Qcow2UnknownHeaderExtension {
554
uint32_t magic;
555
uint32_t len;
556
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVQcow2State {
557
558
CoMutex lock;
559
560
+ Qcow2CryptoHeaderExtension crypto_header; /* QCow2 header extension */
561
QCryptoBlockOpenOptions *crypto_opts; /* Disk encryption runtime options */
562
QCryptoBlock *crypto; /* Disk encryption format driver */
563
+ bool crypt_physical_offset; /* Whether to use virtual or physical offset
564
+ for encryption initialization vector tweak */
565
uint32_t crypt_method_header;
566
uint64_t snapshots_offset;
567
int snapshots_size;
568
diff --git a/qapi/block-core.json b/qapi/block-core.json
569
index XXXXXXX..XXXXXXX 100644
570
--- a/qapi/block-core.json
571
+++ b/qapi/block-core.json
572
@@ -XXX,XX +XXX,XX @@
573
# Since: 2.10
574
##
575
{ 'enum': 'BlockdevQcow2EncryptionFormat',
576
- 'data': [ 'aes' ] }
577
+ 'data': [ 'aes', 'luks' ] }
578
579
##
580
# @BlockdevQcow2Encryption:
581
@@ -XXX,XX +XXX,XX @@
582
{ 'union': 'BlockdevQcow2Encryption',
583
'base': { 'format': 'BlockdevQcow2EncryptionFormat' },
584
'discriminator': 'format',
585
- 'data': { 'aes': 'QCryptoBlockOptionsQCow' } }
586
+ 'data': { 'aes': 'QCryptoBlockOptionsQCow',
587
+ 'luks': 'QCryptoBlockOptionsLUKS'} }
588
589
##
590
# @BlockdevOptionsQcow2:
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
1.8.3.1
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
1.8.3.1
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
1.8.3.1
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
hmp.c | 31 ---------------------
15
include/monitor/monitor.h | 7 -----
16
include/qemu/osdep.h | 2 --
17
monitor.c | 68 -----------------------------------------------
18
qapi-schema.json | 10 +------
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/hmp.c b/hmp.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hmp.c
29
+++ b/hmp.c
30
@@ -XXX,XX +XXX,XX @@ void hmp_ringbuf_read(Monitor *mon, const QDict *qdict)
31
g_free(data);
32
}
33
34
-static void hmp_cont_cb(void *opaque, int err)
35
-{
36
- if (!err) {
37
- qmp_cont(NULL);
38
- }
39
-}
40
-
41
-static bool key_is_missing(const BlockInfo *bdev)
42
-{
43
- return (bdev->inserted && bdev->inserted->encryption_key_missing);
44
-}
45
-
46
void hmp_cont(Monitor *mon, const QDict *qdict)
47
{
48
- BlockInfoList *bdev_list, *bdev;
49
Error *err = NULL;
50
51
- bdev_list = qmp_query_block(NULL);
52
- for (bdev = bdev_list; bdev; bdev = bdev->next) {
53
- if (key_is_missing(bdev->value)) {
54
- monitor_read_block_device_key(mon, bdev->value->device,
55
- hmp_cont_cb, NULL);
56
- goto out;
57
- }
58
- }
59
-
60
qmp_cont(&err);
61
hmp_handle_error(mon, &err);
62
-
63
-out:
64
- qapi_free_BlockInfoList(bdev_list);
65
}
66
67
void hmp_system_wakeup(Monitor *mon, const QDict *qdict)
68
@@ -XXX,XX +XXX,XX @@ void hmp_change(Monitor *mon, const QDict *qdict)
69
qmp_blockdev_change_medium(true, device, false, NULL, target,
70
!!arg, arg, !!read_only, read_only_mode,
71
&err);
72
- if (err &&
73
- error_get_class(err) == ERROR_CLASS_DEVICE_ENCRYPTED) {
74
- error_free(err);
75
- monitor_read_block_device_key(mon, device, NULL, NULL);
76
- return;
77
- }
78
}
79
80
hmp_handle_error(mon, &err);
81
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
82
index XXXXXXX..XXXXXXX 100644
83
--- a/include/monitor/monitor.h
84
+++ b/include/monitor/monitor.h
85
@@ -XXX,XX +XXX,XX @@ void monitor_cleanup(void);
86
int monitor_suspend(Monitor *mon);
87
void monitor_resume(Monitor *mon);
88
89
-int monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs,
90
- BlockCompletionFunc *completion_cb,
91
- void *opaque);
92
-int monitor_read_block_device_key(Monitor *mon, const char *device,
93
- BlockCompletionFunc *completion_cb,
94
- void *opaque);
95
-
96
int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp);
97
int monitor_fd_param(Monitor *mon, const char *fdname, Error **errp);
98
99
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
100
index XXXXXXX..XXXXXXX 100644
101
--- a/include/qemu/osdep.h
102
+++ b/include/qemu/osdep.h
103
@@ -XXX,XX +XXX,XX @@ void qemu_set_tty_echo(int fd, bool echo);
104
void os_mem_prealloc(int fd, char *area, size_t sz, int smp_cpus,
105
Error **errp);
106
107
-int qemu_read_password(char *buf, int buf_size);
108
-
109
/**
110
* qemu_get_pid_name:
111
* @pid: pid of a process
112
diff --git a/monitor.c b/monitor.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/monitor.c
115
+++ b/monitor.c
116
@@ -XXX,XX +XXX,XX @@ void monitor_cleanup(void)
117
qemu_mutex_unlock(&monitor_lock);
118
}
119
120
-static void bdrv_password_cb(void *opaque, const char *password,
121
- void *readline_opaque)
122
-{
123
- Monitor *mon = opaque;
124
- BlockDriverState *bs = readline_opaque;
125
- int ret = 0;
126
- Error *local_err = NULL;
127
-
128
- bdrv_add_key(bs, password, &local_err);
129
- if (local_err) {
130
- error_report_err(local_err);
131
- ret = -EPERM;
132
- }
133
- if (mon->password_completion_cb)
134
- mon->password_completion_cb(mon->password_opaque, ret);
135
-
136
- monitor_read_command(mon, 1);
137
-}
138
-
139
-int monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs,
140
- BlockCompletionFunc *completion_cb,
141
- void *opaque)
142
-{
143
- int err;
144
-
145
- monitor_printf(mon, "%s (%s) is encrypted.\n", bdrv_get_device_name(bs),
146
- bdrv_get_encrypted_filename(bs));
147
-
148
- mon->password_completion_cb = completion_cb;
149
- mon->password_opaque = opaque;
150
-
151
- err = monitor_read_password(mon, bdrv_password_cb, bs);
152
-
153
- if (err && completion_cb)
154
- completion_cb(opaque, err);
155
-
156
- return err;
157
-}
158
-
159
-int monitor_read_block_device_key(Monitor *mon, const char *device,
160
- BlockCompletionFunc *completion_cb,
161
- void *opaque)
162
-{
163
- Error *err = NULL;
164
- BlockBackend *blk;
165
-
166
- blk = blk_by_name(device);
167
- if (!blk) {
168
- monitor_printf(mon, "Device not found %s\n", device);
169
- return -1;
170
- }
171
- if (!blk_bs(blk)) {
172
- monitor_printf(mon, "Device '%s' has no medium\n", device);
173
- return -1;
174
- }
175
-
176
- bdrv_add_key(blk_bs(blk), NULL, &err);
177
- if (err) {
178
- error_free(err);
179
- return monitor_read_bdrv_key_start(mon, blk_bs(blk), completion_cb, opaque);
180
- }
181
-
182
- if (completion_cb) {
183
- completion_cb(opaque, 0);
184
- }
185
- return 0;
186
-}
187
-
188
QemuOptsList qemu_mon_opts = {
189
.name = "mon",
190
.implied_opt_name = "chardev",
191
diff --git a/qapi-schema.json b/qapi-schema.json
192
index XXXXXXX..XXXXXXX 100644
193
--- a/qapi-schema.json
194
+++ b/qapi-schema.json
195
@@ -XXX,XX +XXX,XX @@
196
# Since: 0.14.0
197
#
198
# Returns: If successful, nothing
199
-# If QEMU was started with an encrypted block device and a key has
200
-# not yet been set, DeviceEncrypted.
201
#
202
# Notes: This command will succeed if the guest is currently running. It
203
# will also succeed if the guest is in the "inmigrate" state; in
204
@@ -XXX,XX +XXX,XX @@
205
# * This command is stateless, this means that commands that depend
206
# on state information (such as getfd) might not work
207
#
208
-# * Commands that prompt the user for data (eg. 'cont' when the block
209
-# device is encrypted) don't currently work
210
+# * Commands that prompt the user for data don't currently work
211
#
212
# Example:
213
#
214
@@ -XXX,XX +XXX,XX @@
215
#
216
# Returns: Nothing on success.
217
# If @device is not a valid block device, DeviceNotFound
218
-# If the new block device is encrypted, DeviceEncrypted. Note that
219
-# if this error is returned, the device has been opened successfully
220
-# and an additional call to @block_passwd is required to set the
221
-# device's password. The behavior of reads and writes to the block
222
-# device between when these calls are executed is undefined.
223
#
224
# Notes: This interface is deprecated, and it is strongly recommended that you
225
# avoid using it. For changing block devices, use
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
1.8.3.1
468
469
diff view generated by jsdifflib
Deleted patch
1
From: "Daniel P. Berrange" <berrange@redhat.com>
2
1
3
Now that all encryption keys must be provided upfront via
4
the QCryptoSecret API and associated block driver properties
5
there is no need for any explicit encryption handling APIs
6
in the block layer. Encryption can be handled transparently
7
within the block driver. We only retain an API for querying
8
whether an image is encrypted or not, since that is a
9
potentially useful piece of metadata to report to the user.
10
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
block.c | 77 +----------------------------------------------
18
block/crypto.c | 1 -
19
block/qapi.c | 2 +-
20
block/qcow.c | 8 ++++-
21
block/qcow2.c | 1 -
22
blockdev.c | 37 ++---------------------
23
hmp-commands.hx | 2 ++
24
include/block/block.h | 3 --
25
include/block/block_int.h | 1 -
26
include/qapi/error.h | 1 -
27
qapi/block-core.json | 37 ++---------------------
28
qapi/common.json | 5 +--
29
12 files changed, 16 insertions(+), 159 deletions(-)
30
31
diff --git a/block.c b/block.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/block.c
34
+++ b/block.c
35
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
36
goto close_and_fail;
37
}
38
39
- if (!bdrv_key_required(bs)) {
40
- bdrv_parent_cb_change_media(bs, true);
41
- } else if (!runstate_check(RUN_STATE_PRELAUNCH)
42
- && !runstate_check(RUN_STATE_INMIGRATE)
43
- && !runstate_check(RUN_STATE_PAUSED)) { /* HACK */
44
- error_setg(errp,
45
- "Guest must be stopped for opening of encrypted image");
46
- goto close_and_fail;
47
- }
48
+ bdrv_parent_cb_change_media(bs, true);
49
50
QDECREF(options);
51
52
@@ -XXX,XX +XXX,XX @@ static void bdrv_close(BlockDriverState *bs)
53
bs->backing_format[0] = '\0';
54
bs->total_sectors = 0;
55
bs->encrypted = false;
56
- bs->valid_key = false;
57
bs->sg = false;
58
QDECREF(bs->options);
59
QDECREF(bs->explicit_options);
60
@@ -XXX,XX +XXX,XX @@ bool bdrv_is_encrypted(BlockDriverState *bs)
61
return bs->encrypted;
62
}
63
64
-bool bdrv_key_required(BlockDriverState *bs)
65
-{
66
- BdrvChild *backing = bs->backing;
67
-
68
- if (backing && backing->bs->encrypted && !backing->bs->valid_key) {
69
- return true;
70
- }
71
- return (bs->encrypted && !bs->valid_key);
72
-}
73
-
74
-int bdrv_set_key(BlockDriverState *bs, const char *key)
75
-{
76
- int ret;
77
- if (bs->backing && bs->backing->bs->encrypted) {
78
- ret = bdrv_set_key(bs->backing->bs, key);
79
- if (ret < 0)
80
- return ret;
81
- if (!bs->encrypted)
82
- return 0;
83
- }
84
- if (!bs->encrypted) {
85
- return -EINVAL;
86
- } else if (!bs->drv || !bs->drv->bdrv_set_key) {
87
- return -ENOMEDIUM;
88
- }
89
- ret = bs->drv->bdrv_set_key(bs, key);
90
- if (ret < 0) {
91
- bs->valid_key = false;
92
- } else if (!bs->valid_key) {
93
- /* call the change callback now, we skipped it on open */
94
- bs->valid_key = true;
95
- bdrv_parent_cb_change_media(bs, true);
96
- }
97
- return ret;
98
-}
99
-
100
-/*
101
- * Provide an encryption key for @bs.
102
- * If @key is non-null:
103
- * If @bs is not encrypted, fail.
104
- * Else if the key is invalid, fail.
105
- * Else set @bs's key to @key, replacing the existing key, if any.
106
- * If @key is null:
107
- * If @bs is encrypted and still lacks a key, fail.
108
- * Else do nothing.
109
- * On failure, store an error object through @errp if non-null.
110
- */
111
-void bdrv_add_key(BlockDriverState *bs, const char *key, Error **errp)
112
-{
113
- if (key) {
114
- if (!bdrv_is_encrypted(bs)) {
115
- error_setg(errp, "Node '%s' is not encrypted",
116
- bdrv_get_device_or_node_name(bs));
117
- } else if (bdrv_set_key(bs, key) < 0) {
118
- error_setg(errp, QERR_INVALID_PASSWORD);
119
- }
120
- } else {
121
- if (bdrv_key_required(bs)) {
122
- error_set(errp, ERROR_CLASS_DEVICE_ENCRYPTED,
123
- "'%s' (%s) is encrypted",
124
- bdrv_get_device_or_node_name(bs),
125
- bdrv_get_encrypted_filename(bs));
126
- }
127
- }
128
-}
129
-
130
const char *bdrv_get_format_name(BlockDriverState *bs)
131
{
132
return bs->drv ? bs->drv->format_name : NULL;
133
diff --git a/block/crypto.c b/block/crypto.c
134
index XXXXXXX..XXXXXXX 100644
135
--- a/block/crypto.c
136
+++ b/block/crypto.c
137
@@ -XXX,XX +XXX,XX @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
138
}
139
140
bs->encrypted = true;
141
- bs->valid_key = true;
142
143
ret = 0;
144
cleanup:
145
diff --git a/block/qapi.c b/block/qapi.c
146
index XXXXXXX..XXXXXXX 100644
147
--- a/block/qapi.c
148
+++ b/block/qapi.c
149
@@ -XXX,XX +XXX,XX @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
150
info->ro = bs->read_only;
151
info->drv = g_strdup(bs->drv->format_name);
152
info->encrypted = bs->encrypted;
153
- info->encryption_key_missing = bdrv_key_required(bs);
154
+ info->encryption_key_missing = false;
155
156
info->cache = g_new(BlockdevCacheInfo, 1);
157
*info->cache = (BlockdevCacheInfo) {
158
diff --git a/block/qcow.c b/block/qcow.c
159
index XXXXXXX..XXXXXXX 100644
160
--- a/block/qcow.c
161
+++ b/block/qcow.c
162
@@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
163
goto fail;
164
}
165
bs->encrypted = true;
166
- bs->valid_key = true;
167
+ } else {
168
+ if (encryptfmt) {
169
+ error_setg(errp, "No encryption in image header, but options "
170
+ "specified format '%s'", encryptfmt);
171
+ ret = -EINVAL;
172
+ goto fail;
173
+ }
174
}
175
s->cluster_bits = header.cluster_bits;
176
s->cluster_size = 1 << s->cluster_bits;
177
diff --git a/block/qcow2.c b/block/qcow2.c
178
index XXXXXXX..XXXXXXX 100644
179
--- a/block/qcow2.c
180
+++ b/block/qcow2.c
181
@@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
182
}
183
184
bs->encrypted = true;
185
- bs->valid_key = true;
186
}
187
188
s->l2_bits = s->cluster_bits - 3; /* L2 is always one cluster */
189
diff --git a/blockdev.c b/blockdev.c
190
index XXXXXXX..XXXXXXX 100644
191
--- a/blockdev.c
192
+++ b/blockdev.c
193
@@ -XXX,XX +XXX,XX @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
194
195
bs->detect_zeroes = detect_zeroes;
196
197
- if (bdrv_key_required(bs)) {
198
- autostart = 0;
199
- }
200
-
201
block_acct_setup(blk_get_stats(blk), account_invalid, account_failed);
202
203
if (!parse_stats_intervals(blk_get_stats(blk), interval_list, errp)) {
204
@@ -XXX,XX +XXX,XX @@ void qmp_block_passwd(bool has_device, const char *device,
205
bool has_node_name, const char *node_name,
206
const char *password, Error **errp)
207
{
208
- Error *local_err = NULL;
209
- BlockDriverState *bs;
210
- AioContext *aio_context;
211
-
212
- bs = bdrv_lookup_bs(has_device ? device : NULL,
213
- has_node_name ? node_name : NULL,
214
- &local_err);
215
- if (local_err) {
216
- error_propagate(errp, local_err);
217
- return;
218
- }
219
-
220
- aio_context = bdrv_get_aio_context(bs);
221
- aio_context_acquire(aio_context);
222
-
223
- bdrv_add_key(bs, password, errp);
224
-
225
- aio_context_release(aio_context);
226
+ error_setg(errp,
227
+ "Setting block passwords directly is no longer supported");
228
}
229
230
/*
231
@@ -XXX,XX +XXX,XX @@ void qmp_blockdev_change_medium(bool has_device, const char *device,
232
goto fail;
233
}
234
235
- bdrv_add_key(medium_bs, NULL, &err);
236
- if (err) {
237
- error_propagate(errp, err);
238
- goto fail;
239
- }
240
-
241
rc = do_open_tray(has_device ? device : NULL,
242
has_id ? id : NULL,
243
false, &err);
244
@@ -XXX,XX +XXX,XX @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
245
246
QTAILQ_INSERT_TAIL(&monitor_bdrv_states, bs, monitor_list);
247
248
- if (bs && bdrv_key_required(bs)) {
249
- QTAILQ_REMOVE(&monitor_bdrv_states, bs, monitor_list);
250
- bdrv_unref(bs);
251
- error_setg(errp, "blockdev-add doesn't support encrypted devices");
252
- goto fail;
253
- }
254
-
255
fail:
256
visit_free(v);
257
}
258
diff --git a/hmp-commands.hx b/hmp-commands.hx
259
index XXXXXXX..XXXXXXX 100644
260
--- a/hmp-commands.hx
261
+++ b/hmp-commands.hx
262
@@ -XXX,XX +XXX,XX @@ STEXI
263
@item block_passwd @var{device} @var{password}
264
@findex block_passwd
265
Set the encrypted device @var{device} password to @var{password}
266
+
267
+This command is now obsolete and will always return an error since 2.10
268
ETEXI
269
270
{
271
diff --git a/include/block/block.h b/include/block/block.h
272
index XXXXXXX..XXXXXXX 100644
273
--- a/include/block/block.h
274
+++ b/include/block/block.h
275
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_next(BdrvNextIterator *it);
276
277
BlockDriverState *bdrv_next_monitor_owned(BlockDriverState *bs);
278
bool bdrv_is_encrypted(BlockDriverState *bs);
279
-bool bdrv_key_required(BlockDriverState *bs);
280
-int bdrv_set_key(BlockDriverState *bs, const char *key);
281
-void bdrv_add_key(BlockDriverState *bs, const char *key, Error **errp);
282
void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
283
void *opaque);
284
const char *bdrv_get_node_name(const BlockDriverState *bs);
285
diff --git a/include/block/block_int.h b/include/block/block_int.h
286
index XXXXXXX..XXXXXXX 100644
287
--- a/include/block/block_int.h
288
+++ b/include/block/block_int.h
289
@@ -XXX,XX +XXX,XX @@ struct BlockDriverState {
290
int open_flags; /* flags used to open the file, re-used for re-open */
291
bool read_only; /* if true, the media is read only */
292
bool encrypted; /* if true, the media is encrypted */
293
- bool valid_key; /* if true, a valid encryption key has been set */
294
bool sg; /* if true, the device is a /dev/sg* */
295
bool probed; /* if true, format was probed rather than specified */
296
bool force_share; /* if true, always allow all shared permissions */
297
diff --git a/include/qapi/error.h b/include/qapi/error.h
298
index XXXXXXX..XXXXXXX 100644
299
--- a/include/qapi/error.h
300
+++ b/include/qapi/error.h
301
@@ -XXX,XX +XXX,XX @@
302
typedef enum ErrorClass {
303
ERROR_CLASS_GENERIC_ERROR = QAPI_ERROR_CLASS_GENERICERROR,
304
ERROR_CLASS_COMMAND_NOT_FOUND = QAPI_ERROR_CLASS_COMMANDNOTFOUND,
305
- ERROR_CLASS_DEVICE_ENCRYPTED = QAPI_ERROR_CLASS_DEVICEENCRYPTED,
306
ERROR_CLASS_DEVICE_NOT_ACTIVE = QAPI_ERROR_CLASS_DEVICENOTACTIVE,
307
ERROR_CLASS_DEVICE_NOT_FOUND = QAPI_ERROR_CLASS_DEVICENOTFOUND,
308
ERROR_CLASS_KVM_MISSING_CAP = QAPI_ERROR_CLASS_KVMMISSINGCAP,
309
diff --git a/qapi/block-core.json b/qapi/block-core.json
310
index XXXXXXX..XXXXXXX 100644
311
--- a/qapi/block-core.json
312
+++ b/qapi/block-core.json
313
@@ -XXX,XX +XXX,XX @@
314
#
315
# @encrypted: true if the backing device is encrypted
316
#
317
-# @encryption_key_missing: true if the backing device is encrypted but an
318
-# valid encryption key is missing
319
+# @encryption_key_missing: Deprecated; always false
320
#
321
# @detect_zeroes: detect and optimize zero writes (Since 2.1)
322
#
323
@@ -XXX,XX +XXX,XX @@
324
# This command sets the password of a block device that has not been open
325
# with a password and requires one.
326
#
327
-# The two cases where this can happen are a block device is created through
328
-# QEMU's initial command line or a block device is changed through the legacy
329
-# @change interface.
330
-#
331
-# In the event that the block device is created through the initial command
332
-# line, the VM will start in the stopped state regardless of whether '-S' is
333
-# used. The intention is for a management tool to query the block devices to
334
-# determine which ones are encrypted, set the passwords with this command, and
335
-# then start the guest with the @cont command.
336
-#
337
-# Either @device or @node-name must be set but not both.
338
-#
339
-# @device: the name of the block backend device to set the password on
340
-#
341
-# @node-name: graph node name to set the password on (Since 2.0)
342
-#
343
-# @password: the password to use for the device
344
-#
345
-# Returns: nothing on success
346
-# If @device is not a valid block device, DeviceNotFound
347
-# If @device is not encrypted, DeviceNotEncrypted
348
-#
349
-# Notes: Not all block formats support encryption and some that do are not
350
-# able to validate that a password is correct. Disk corruption may
351
-# occur if an invalid password is specified.
352
-#
353
-# Since: 0.14.0
354
-#
355
-# Example:
356
-#
357
-# -> { "execute": "block_passwd", "arguments": { "device": "ide0-hd0",
358
-# "password": "12345" } }
359
-# <- { "return": {} }
360
+# This command is now obsolete and will always return an error since 2.10
361
#
362
##
363
{ 'command': 'block_passwd', 'data': {'*device': 'str',
364
diff --git a/qapi/common.json b/qapi/common.json
365
index XXXXXXX..XXXXXXX 100644
366
--- a/qapi/common.json
367
+++ b/qapi/common.json
368
@@ -XXX,XX +XXX,XX @@
369
#
370
# @CommandNotFound: the requested command has not been found
371
#
372
-# @DeviceEncrypted: the requested operation can't be fulfilled because the
373
-# selected device is encrypted
374
-#
375
# @DeviceNotActive: a device has failed to be become active
376
#
377
# @DeviceNotFound: the requested device has not been found
378
@@ -XXX,XX +XXX,XX @@
379
##
380
{ 'enum': 'QapiErrorClass',
381
# Keep this in sync with ErrorClass in error.h
382
- 'data': [ 'GenericError', 'CommandNotFound', 'DeviceEncrypted',
383
+ 'data': [ 'GenericError', 'CommandNotFound',
384
'DeviceNotActive', 'DeviceNotFound', 'KVMMissingCap' ] }
385
386
##
387
--
388
1.8.3.1
389
390
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
block/crypto.c | 4 ++--
17
block/qcow.c | 7 ++++---
18
block/qcow2.c | 8 ++++----
19
crypto/block-luks.c | 8 ++++++--
20
crypto/block-qcow.c | 8 ++++++--
21
crypto/block.c | 6 ++++--
22
crypto/blockpriv.h | 2 ++
23
include/crypto/block.h | 6 +++++-
24
tests/test-crypto-block.c | 8 ++++----
25
9 files changed, 37 insertions(+), 20 deletions(-)
26
27
diff --git a/block/crypto.c b/block/crypto.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/block/crypto.c
30
+++ b/block/crypto.c
31
@@ -XXX,XX +XXX,XX @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
32
if (flags & BDRV_O_NO_IO) {
33
cflags |= QCRYPTO_BLOCK_OPEN_NO_IO;
34
}
35
- crypto->block = qcrypto_block_open(open_opts,
36
+ crypto->block = qcrypto_block_open(open_opts, NULL,
37
block_crypto_read_func,
38
bs,
39
cflags,
40
@@ -XXX,XX +XXX,XX @@ static int block_crypto_create_generic(QCryptoBlockFormat format,
41
return -1;
42
}
43
44
- crypto = qcrypto_block_create(create_opts,
45
+ crypto = qcrypto_block_create(create_opts, NULL,
46
block_crypto_init_func,
47
block_crypto_write_func,
48
&data,
49
diff --git a/block/qcow.c b/block/qcow.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/block/qcow.c
52
+++ b/block/qcow.c
53
@@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
54
if (flags & BDRV_O_NO_IO) {
55
cflags |= QCRYPTO_BLOCK_OPEN_NO_IO;
56
}
57
- s->crypto = qcrypto_block_open(crypto_opts, NULL, NULL,
58
- cflags, errp);
59
+ s->crypto = qcrypto_block_open(crypto_opts, "encrypt.",
60
+ NULL, NULL, cflags, errp);
61
if (!s->crypto) {
62
ret = -EINVAL;
63
goto fail;
64
@@ -XXX,XX +XXX,XX @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp)
65
goto exit;
66
}
67
68
- crypto = qcrypto_block_create(crypto_opts, NULL, NULL, NULL, errp);
69
+ crypto = qcrypto_block_create(crypto_opts, "encrypt.",
70
+ NULL, NULL, NULL, errp);
71
if (!crypto) {
72
ret = -EINVAL;
73
goto exit;
74
diff --git a/block/qcow2.c b/block/qcow2.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/block/qcow2.c
77
+++ b/block/qcow2.c
78
@@ -XXX,XX +XXX,XX @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
79
if (flags & BDRV_O_NO_IO) {
80
cflags |= QCRYPTO_BLOCK_OPEN_NO_IO;
81
}
82
- s->crypto = qcrypto_block_open(s->crypto_opts,
83
+ s->crypto = qcrypto_block_open(s->crypto_opts, "encrypt.",
84
qcow2_crypto_hdr_read_func,
85
bs, cflags, errp);
86
if (!s->crypto) {
87
@@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
88
if (flags & BDRV_O_NO_IO) {
89
cflags |= QCRYPTO_BLOCK_OPEN_NO_IO;
90
}
91
- s->crypto = qcrypto_block_open(s->crypto_opts, NULL, NULL,
92
- cflags, errp);
93
+ s->crypto = qcrypto_block_open(s->crypto_opts, "encrypt.",
94
+ NULL, NULL, cflags, errp);
95
if (!s->crypto) {
96
ret = -EINVAL;
97
goto fail;
98
@@ -XXX,XX +XXX,XX @@ static int qcow2_set_up_encryption(BlockDriverState *bs, const char *encryptfmt,
99
}
100
s->crypt_method_header = fmt;
101
102
- crypto = qcrypto_block_create(cryptoopts,
103
+ crypto = qcrypto_block_create(cryptoopts, "encrypt.",
104
qcow2_crypto_hdr_init_func,
105
qcow2_crypto_hdr_write_func,
106
bs, errp);
107
diff --git a/crypto/block-luks.c b/crypto/block-luks.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/crypto/block-luks.c
110
+++ b/crypto/block-luks.c
111
@@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_find_key(QCryptoBlock *block,
112
static int
113
qcrypto_block_luks_open(QCryptoBlock *block,
114
QCryptoBlockOpenOptions *options,
115
+ const char *optprefix,
116
QCryptoBlockReadFunc readfunc,
117
void *opaque,
118
unsigned int flags,
119
@@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_open(QCryptoBlock *block,
120
121
if (!(flags & QCRYPTO_BLOCK_OPEN_NO_IO)) {
122
if (!options->u.luks.key_secret) {
123
- error_setg(errp, "Parameter 'key-secret' is required for cipher");
124
+ error_setg(errp, "Parameter '%skey-secret' is required for cipher",
125
+ optprefix ? optprefix : "");
126
return -1;
127
}
128
password = qcrypto_secret_lookup_as_utf8(
129
@@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_uuid_gen(uint8_t *uuidstr)
130
static int
131
qcrypto_block_luks_create(QCryptoBlock *block,
132
QCryptoBlockCreateOptions *options,
133
+ const char *optprefix,
134
QCryptoBlockInitFunc initfunc,
135
QCryptoBlockWriteFunc writefunc,
136
void *opaque,
137
@@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_create(QCryptoBlock *block,
138
* be silently ignored, for compatibility with dm-crypt */
139
140
if (!options->u.luks.key_secret) {
141
- error_setg(errp, "Parameter 'key-secret' is required for cipher");
142
+ error_setg(errp, "Parameter '%skey-secret' is required for cipher",
143
+ optprefix ? optprefix : "");
144
return -1;
145
}
146
password = qcrypto_secret_lookup_as_utf8(luks_opts.key_secret, errp);
147
diff --git a/crypto/block-qcow.c b/crypto/block-qcow.c
148
index XXXXXXX..XXXXXXX 100644
149
--- a/crypto/block-qcow.c
150
+++ b/crypto/block-qcow.c
151
@@ -XXX,XX +XXX,XX @@ qcrypto_block_qcow_init(QCryptoBlock *block,
152
static int
153
qcrypto_block_qcow_open(QCryptoBlock *block,
154
QCryptoBlockOpenOptions *options,
155
+ const char *optprefix,
156
QCryptoBlockReadFunc readfunc G_GNUC_UNUSED,
157
void *opaque G_GNUC_UNUSED,
158
unsigned int flags,
159
@@ -XXX,XX +XXX,XX @@ qcrypto_block_qcow_open(QCryptoBlock *block,
160
} else {
161
if (!options->u.qcow.key_secret) {
162
error_setg(errp,
163
- "Parameter 'key-secret' is required for cipher");
164
+ "Parameter '%skey-secret' is required for cipher",
165
+ optprefix ? optprefix : "");
166
return -1;
167
}
168
return qcrypto_block_qcow_init(block,
169
@@ -XXX,XX +XXX,XX @@ qcrypto_block_qcow_open(QCryptoBlock *block,
170
static int
171
qcrypto_block_qcow_create(QCryptoBlock *block,
172
QCryptoBlockCreateOptions *options,
173
+ const char *optprefix,
174
QCryptoBlockInitFunc initfunc G_GNUC_UNUSED,
175
QCryptoBlockWriteFunc writefunc G_GNUC_UNUSED,
176
void *opaque G_GNUC_UNUSED,
177
Error **errp)
178
{
179
if (!options->u.qcow.key_secret) {
180
- error_setg(errp, "Parameter 'key-secret' is required for cipher");
181
+ error_setg(errp, "Parameter '%skey-secret' is required for cipher",
182
+ optprefix ? optprefix : "");
183
return -1;
184
}
185
/* QCow2 has no special header, since everything is hardwired */
186
diff --git a/crypto/block.c b/crypto/block.c
187
index XXXXXXX..XXXXXXX 100644
188
--- a/crypto/block.c
189
+++ b/crypto/block.c
190
@@ -XXX,XX +XXX,XX @@ bool qcrypto_block_has_format(QCryptoBlockFormat format,
191
192
193
QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options,
194
+ const char *optprefix,
195
QCryptoBlockReadFunc readfunc,
196
void *opaque,
197
unsigned int flags,
198
@@ -XXX,XX +XXX,XX @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options,
199
200
block->driver = qcrypto_block_drivers[options->format];
201
202
- if (block->driver->open(block, options,
203
+ if (block->driver->open(block, options, optprefix,
204
readfunc, opaque, flags, errp) < 0) {
205
g_free(block);
206
return NULL;
207
@@ -XXX,XX +XXX,XX @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options,
208
209
210
QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options,
211
+ const char *optprefix,
212
QCryptoBlockInitFunc initfunc,
213
QCryptoBlockWriteFunc writefunc,
214
void *opaque,
215
@@ -XXX,XX +XXX,XX @@ QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options,
216
217
block->driver = qcrypto_block_drivers[options->format];
218
219
- if (block->driver->create(block, options, initfunc,
220
+ if (block->driver->create(block, options, optprefix, initfunc,
221
writefunc, opaque, errp) < 0) {
222
g_free(block);
223
return NULL;
224
diff --git a/crypto/blockpriv.h b/crypto/blockpriv.h
225
index XXXXXXX..XXXXXXX 100644
226
--- a/crypto/blockpriv.h
227
+++ b/crypto/blockpriv.h
228
@@ -XXX,XX +XXX,XX @@ struct QCryptoBlock {
229
struct QCryptoBlockDriver {
230
int (*open)(QCryptoBlock *block,
231
QCryptoBlockOpenOptions *options,
232
+ const char *optprefix,
233
QCryptoBlockReadFunc readfunc,
234
void *opaque,
235
unsigned int flags,
236
@@ -XXX,XX +XXX,XX @@ struct QCryptoBlockDriver {
237
238
int (*create)(QCryptoBlock *block,
239
QCryptoBlockCreateOptions *options,
240
+ const char *optprefix,
241
QCryptoBlockInitFunc initfunc,
242
QCryptoBlockWriteFunc writefunc,
243
void *opaque,
244
diff --git a/include/crypto/block.h b/include/crypto/block.h
245
index XXXXXXX..XXXXXXX 100644
246
--- a/include/crypto/block.h
247
+++ b/include/crypto/block.h
248
@@ -XXX,XX +XXX,XX @@ typedef enum {
249
/**
250
* qcrypto_block_open:
251
* @options: the encryption options
252
+ * @optprefix: name prefix for options
253
* @readfunc: callback for reading data from the volume
254
* @opaque: data to pass to @readfunc
255
* @flags: bitmask of QCryptoBlockOpenFlags values
256
@@ -XXX,XX +XXX,XX @@ typedef enum {
257
* Returns: a block encryption format, or NULL on error
258
*/
259
QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options,
260
+ const char *optprefix,
261
QCryptoBlockReadFunc readfunc,
262
void *opaque,
263
unsigned int flags,
264
@@ -XXX,XX +XXX,XX @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options,
265
266
/**
267
* qcrypto_block_create:
268
- * @format: the encryption format
269
+ * @options: the encryption options
270
+ * @optprefix: name prefix for options
271
* @initfunc: callback for initializing volume header
272
* @writefunc: callback for writing data to the volume header
273
* @opaque: data to pass to @initfunc and @writefunc
274
@@ -XXX,XX +XXX,XX @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options,
275
* Returns: a block encryption format, or NULL on error
276
*/
277
QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options,
278
+ const char *optprefix,
279
QCryptoBlockInitFunc initfunc,
280
QCryptoBlockWriteFunc writefunc,
281
void *opaque,
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
1.8.3.1
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
block/qcow2.c | 32 +++++++++++++++++++++++++++++++-
103
qapi/block-core.json | 27 ++++++++++++++++++++++++++-
104
2 files changed, 57 insertions(+), 2 deletions(-)
105
106
diff --git a/block/qcow2.c b/block/qcow2.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/block/qcow2.c
109
+++ b/block/qcow2.c
110
@@ -XXX,XX +XXX,XX @@ static int qcow2_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
111
static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs)
112
{
113
BDRVQcow2State *s = bs->opaque;
114
- ImageInfoSpecific *spec_info = g_new(ImageInfoSpecific, 1);
115
+ ImageInfoSpecific *spec_info;
116
+ QCryptoBlockInfo *encrypt_info = NULL;
117
118
+ if (s->crypto != NULL) {
119
+ encrypt_info = qcrypto_block_get_info(s->crypto, &error_abort);
120
+ }
121
+
122
+ spec_info = g_new(ImageInfoSpecific, 1);
123
*spec_info = (ImageInfoSpecific){
124
.type = IMAGE_INFO_SPECIFIC_KIND_QCOW2,
125
.u.qcow2.data = g_new(ImageInfoSpecificQCow2, 1),
126
@@ -XXX,XX +XXX,XX @@ static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs)
127
assert(false);
128
}
129
130
+ if (encrypt_info) {
131
+ ImageInfoSpecificQCow2Encryption *qencrypt =
132
+ g_new(ImageInfoSpecificQCow2Encryption, 1);
133
+ switch (encrypt_info->format) {
134
+ case Q_CRYPTO_BLOCK_FORMAT_QCOW:
135
+ qencrypt->format = BLOCKDEV_QCOW2_ENCRYPTION_FORMAT_AES;
136
+ qencrypt->u.aes = encrypt_info->u.qcow;
137
+ break;
138
+ case Q_CRYPTO_BLOCK_FORMAT_LUKS:
139
+ qencrypt->format = BLOCKDEV_QCOW2_ENCRYPTION_FORMAT_LUKS;
140
+ qencrypt->u.luks = encrypt_info->u.luks;
141
+ break;
142
+ default:
143
+ abort();
144
+ }
145
+ /* Since we did shallow copy above, erase any pointers
146
+ * in the original info */
147
+ memset(&encrypt_info->u, 0, sizeof(encrypt_info->u));
148
+ qapi_free_QCryptoBlockInfo(encrypt_info);
149
+
150
+ spec_info->u.qcow2.data->has_encrypt = true;
151
+ spec_info->u.qcow2.data->encrypt = qencrypt;
152
+ }
153
+
154
return spec_info;
155
}
156
157
diff --git a/qapi/block-core.json b/qapi/block-core.json
158
index XXXXXXX..XXXXXXX 100644
159
--- a/qapi/block-core.json
160
+++ b/qapi/block-core.json
161
@@ -XXX,XX +XXX,XX @@
162
'vm-clock-sec': 'int', 'vm-clock-nsec': 'int' } }
163
164
##
165
+# @ImageInfoSpecificQCow2EncryptionBase:
166
+#
167
+# @format: The encryption format
168
+#
169
+# Since: 2.10
170
+##
171
+{ 'struct': 'ImageInfoSpecificQCow2EncryptionBase',
172
+ 'data': { 'format': 'BlockdevQcow2EncryptionFormat'}}
173
+
174
+##
175
+# @ImageInfoSpecificQCow2Encryption:
176
+#
177
+# Since: 2.10
178
+##
179
+{ 'union': 'ImageInfoSpecificQCow2Encryption',
180
+ 'base': 'ImageInfoSpecificQCow2EncryptionBase',
181
+ 'discriminator': 'format',
182
+ 'data': { 'aes': 'QCryptoBlockInfoQCow',
183
+ 'luks': 'QCryptoBlockInfoLUKS' } }
184
+
185
+##
186
# @ImageInfoSpecificQCow2:
187
#
188
# @compat: compatibility level
189
@@ -XXX,XX +XXX,XX @@
190
#
191
# @refcount-bits: width of a refcount entry in bits (since 2.3)
192
#
193
+# @encrypt: details about encryption parameters; only set if image
194
+# is encrypted (since 2.10)
195
+#
196
# Since: 1.7
197
##
198
{ 'struct': 'ImageInfoSpecificQCow2',
199
@@ -XXX,XX +XXX,XX @@
200
'compat': 'str',
201
'*lazy-refcounts': 'bool',
202
'*corrupt': 'bool',
203
- 'refcount-bits': 'int'
204
+ 'refcount-bits': 'int',
205
+ '*encrypt': 'ImageInfoSpecificQCow2Encryption'
206
} }
207
208
##
209
--
210
1.8.3.1
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
1.8.3.1
166
167
diff view generated by jsdifflib
Deleted patch
1
From: Max Reitz <mreitz@redhat.com>
2
1
3
Test 181 only works for formats which support live migration (naturally,
4
as it is a live migration test). Disable it for all formats which do
5
not.
6
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
Message-id: 20170621131157.16584-1-mreitz@redhat.com
9
Reviewed-by: John Snow <jsnow@redhat.com>
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
---
12
tests/qemu-iotests/181 | 2 ++
13
1 file changed, 2 insertions(+)
14
15
diff --git a/tests/qemu-iotests/181 b/tests/qemu-iotests/181
16
index XXXXXXX..XXXXXXX 100755
17
--- a/tests/qemu-iotests/181
18
+++ b/tests/qemu-iotests/181
19
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
20
. ./common.qemu
21
22
_supported_fmt generic
23
+# Formats that do not support live migration
24
+_unsupported_fmt qcow vdi vhdx vmdk vpc vvfat
25
_supported_proto generic
26
_supported_os Linux
27
28
--
29
1.8.3.1
30
31
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
1.8.3.1
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
1.8.3.1
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
1.8.3.1
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
1.8.3.1
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
1.8.3.1
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
block/dirty-bitmap.c | 2 +-
14
include/block/dirty-bitmap.h | 2 +-
15
2 files changed, 2 insertions(+), 2 deletions(-)
16
17
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block/dirty-bitmap.c
20
+++ b/block/dirty-bitmap.c
21
@@ -XXX,XX +XXX,XX @@ uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs)
22
return granularity;
23
}
24
25
-uint32_t bdrv_dirty_bitmap_granularity(BdrvDirtyBitmap *bitmap)
26
+uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap)
27
{
28
return BDRV_SECTOR_SIZE << hbitmap_granularity(bitmap->bitmap);
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 @@ void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap);
35
void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap);
36
BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs);
37
uint32_t bdrv_get_default_bitmap_granularity(BlockDriverState *bs);
38
-uint32_t bdrv_dirty_bitmap_granularity(BdrvDirtyBitmap *bitmap);
39
+uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap);
40
uint32_t bdrv_dirty_bitmap_meta_granularity(BdrvDirtyBitmap *bitmap);
41
bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap *bitmap);
42
bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap);
43
--
44
1.8.3.1
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
block/dirty-bitmap.c | 7 +++++++
14
include/block/dirty-bitmap.h | 3 +++
15
include/qemu/hbitmap.h | 15 +++++++++++++++
16
util/hbitmap.c | 17 +++++++++++++++++
17
4 files changed, 42 insertions(+)
18
19
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/block/dirty-bitmap.c
22
+++ b/block/dirty-bitmap.c
23
@@ -XXX,XX +XXX,XX @@ void bdrv_dirty_bitmap_deserialize_zeroes(BdrvDirtyBitmap *bitmap,
24
hbitmap_deserialize_zeroes(bitmap->bitmap, start, count, finish);
25
}
26
27
+void bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap,
28
+ uint64_t start, uint64_t count,
29
+ bool finish)
30
+{
31
+ hbitmap_deserialize_ones(bitmap->bitmap, start, count, finish);
32
+}
33
+
34
void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap)
35
{
36
hbitmap_deserialize_finish(bitmap->bitmap);
37
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
38
index XXXXXXX..XXXXXXX 100644
39
--- a/include/block/dirty-bitmap.h
40
+++ b/include/block/dirty-bitmap.h
41
@@ -XXX,XX +XXX,XX @@ void bdrv_dirty_bitmap_deserialize_part(BdrvDirtyBitmap *bitmap,
42
void bdrv_dirty_bitmap_deserialize_zeroes(BdrvDirtyBitmap *bitmap,
43
uint64_t start, uint64_t count,
44
bool finish);
45
+void bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap,
46
+ uint64_t start, uint64_t count,
47
+ bool finish);
48
void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap);
49
50
/* Functions that require manual locking. */
51
diff --git a/include/qemu/hbitmap.h b/include/qemu/hbitmap.h
52
index XXXXXXX..XXXXXXX 100644
53
--- a/include/qemu/hbitmap.h
54
+++ b/include/qemu/hbitmap.h
55
@@ -XXX,XX +XXX,XX @@ void hbitmap_deserialize_zeroes(HBitmap *hb, uint64_t start, uint64_t count,
56
bool finish);
57
58
/**
59
+ * hbitmap_deserialize_ones
60
+ * @hb: HBitmap to operate on.
61
+ * @start: First bit to restore.
62
+ * @count: Number of bits to restore.
63
+ * @finish: Whether to call hbitmap_deserialize_finish automatically.
64
+ *
65
+ * Fills the bitmap with ones.
66
+ *
67
+ * If @finish is false, caller must call hbitmap_serialize_finish before using
68
+ * the bitmap.
69
+ */
70
+void hbitmap_deserialize_ones(HBitmap *hb, uint64_t start, uint64_t count,
71
+ bool finish);
72
+
73
+/**
74
* hbitmap_deserialize_finish
75
* @hb: HBitmap to operate on.
76
*
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
1.8.3.1
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-refcount.c | 59 ++++++++++++++++++++++++++------------------------
15
block/qcow2.h | 4 ++++
16
2 files changed, 35 insertions(+), 28 deletions(-)
17
18
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/block/qcow2-refcount.c
21
+++ b/block/qcow2-refcount.c
22
@@ -XXX,XX +XXX,XX @@ static int realloc_refcount_array(BDRVQcow2State *s, void **array,
23
*
24
* Modifies the number of errors in res.
25
*/
26
-static int inc_refcounts(BlockDriverState *bs,
27
- BdrvCheckResult *res,
28
- void **refcount_table,
29
- int64_t *refcount_table_size,
30
- int64_t offset, int64_t size)
31
+int qcow2_inc_refcounts_imrt(BlockDriverState *bs, BdrvCheckResult *res,
32
+ void **refcount_table,
33
+ int64_t *refcount_table_size,
34
+ int64_t offset, int64_t size)
35
{
36
BDRVQcow2State *s = bs->opaque;
37
uint64_t start, last, cluster_offset, k, refcount;
38
@@ -XXX,XX +XXX,XX @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
39
nb_csectors = ((l2_entry >> s->csize_shift) &
40
s->csize_mask) + 1;
41
l2_entry &= s->cluster_offset_mask;
42
- ret = inc_refcounts(bs, res, refcount_table, refcount_table_size,
43
- l2_entry & ~511, nb_csectors * 512);
44
+ ret = qcow2_inc_refcounts_imrt(bs, res,
45
+ refcount_table, refcount_table_size,
46
+ l2_entry & ~511, nb_csectors * 512);
47
if (ret < 0) {
48
goto fail;
49
}
50
@@ -XXX,XX +XXX,XX @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
51
}
52
53
/* Mark cluster as used */
54
- ret = inc_refcounts(bs, res, refcount_table, refcount_table_size,
55
- offset, s->cluster_size);
56
+ ret = qcow2_inc_refcounts_imrt(bs, res,
57
+ refcount_table, refcount_table_size,
58
+ offset, s->cluster_size);
59
if (ret < 0) {
60
goto fail;
61
}
62
@@ -XXX,XX +XXX,XX @@ static int check_refcounts_l1(BlockDriverState *bs,
63
l1_size2 = l1_size * sizeof(uint64_t);
64
65
/* Mark L1 table as used */
66
- ret = inc_refcounts(bs, res, refcount_table, refcount_table_size,
67
- l1_table_offset, l1_size2);
68
+ ret = qcow2_inc_refcounts_imrt(bs, res, refcount_table, refcount_table_size,
69
+ l1_table_offset, l1_size2);
70
if (ret < 0) {
71
goto fail;
72
}
73
@@ -XXX,XX +XXX,XX @@ static int check_refcounts_l1(BlockDriverState *bs,
74
if (l2_offset) {
75
/* Mark L2 table as used */
76
l2_offset &= L1E_OFFSET_MASK;
77
- ret = inc_refcounts(bs, res, refcount_table, refcount_table_size,
78
- l2_offset, s->cluster_size);
79
+ ret = qcow2_inc_refcounts_imrt(bs, res,
80
+ refcount_table, refcount_table_size,
81
+ l2_offset, s->cluster_size);
82
if (ret < 0) {
83
goto fail;
84
}
85
@@ -XXX,XX +XXX,XX @@ static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res,
86
}
87
88
res->corruptions_fixed++;
89
- ret = inc_refcounts(bs, res, refcount_table, nb_clusters,
90
- offset, s->cluster_size);
91
+ ret = qcow2_inc_refcounts_imrt(bs, res,
92
+ refcount_table, nb_clusters,
93
+ offset, s->cluster_size);
94
if (ret < 0) {
95
return ret;
96
}
97
/* No need to check whether the refcount is now greater than 1:
98
* This area was just allocated and zeroed, so it can only be
99
- * exactly 1 after inc_refcounts() */
100
+ * exactly 1 after qcow2_inc_refcounts_imrt() */
101
continue;
102
103
resize_fail:
104
@@ -XXX,XX +XXX,XX @@ resize_fail:
105
}
106
107
if (offset != 0) {
108
- ret = inc_refcounts(bs, res, refcount_table, nb_clusters,
109
- offset, s->cluster_size);
110
+ ret = qcow2_inc_refcounts_imrt(bs, res, refcount_table, nb_clusters,
111
+ offset, s->cluster_size);
112
if (ret < 0) {
113
return ret;
114
}
115
@@ -XXX,XX +XXX,XX @@ static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
116
}
117
118
/* header */
119
- ret = inc_refcounts(bs, res, refcount_table, nb_clusters,
120
- 0, s->cluster_size);
121
+ ret = qcow2_inc_refcounts_imrt(bs, res, refcount_table, nb_clusters,
122
+ 0, s->cluster_size);
123
if (ret < 0) {
124
return ret;
125
}
126
@@ -XXX,XX +XXX,XX @@ static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
127
return ret;
128
}
129
}
130
- ret = inc_refcounts(bs, res, refcount_table, nb_clusters,
131
- s->snapshots_offset, s->snapshots_size);
132
+ ret = qcow2_inc_refcounts_imrt(bs, res, refcount_table, nb_clusters,
133
+ s->snapshots_offset, s->snapshots_size);
134
if (ret < 0) {
135
return ret;
136
}
137
138
/* refcount data */
139
- ret = inc_refcounts(bs, res, refcount_table, nb_clusters,
140
- s->refcount_table_offset,
141
- s->refcount_table_size * sizeof(uint64_t));
142
+ ret = qcow2_inc_refcounts_imrt(bs, res, refcount_table, nb_clusters,
143
+ s->refcount_table_offset,
144
+ s->refcount_table_size * sizeof(uint64_t));
145
if (ret < 0) {
146
return ret;
147
}
148
149
/* encryption */
150
if (s->crypto_header.length) {
151
- ret = inc_refcounts(bs, res, refcount_table, nb_clusters,
152
- s->crypto_header.offset,
153
- s->crypto_header.length);
154
+ ret = qcow2_inc_refcounts_imrt(bs, res, refcount_table, nb_clusters,
155
+ s->crypto_header.offset,
156
+ s->crypto_header.length);
157
if (ret < 0) {
158
return ret;
159
}
160
diff --git a/block/qcow2.h b/block/qcow2.h
161
index XXXXXXX..XXXXXXX 100644
162
--- a/block/qcow2.h
163
+++ b/block/qcow2.h
164
@@ -XXX,XX +XXX,XX @@ int qcow2_check_metadata_overlap(BlockDriverState *bs, int ign, int64_t offset,
165
int64_t size);
166
int qcow2_pre_write_overlap_check(BlockDriverState *bs, int ign, int64_t offset,
167
int64_t size);
168
+int qcow2_inc_refcounts_imrt(BlockDriverState *bs, BdrvCheckResult *res,
169
+ void **refcount_table,
170
+ int64_t *refcount_table_size,
171
+ int64_t offset, int64_t size);
172
173
int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order,
174
BlockDriverAmendStatusCB *status_cb,
175
--
176
1.8.3.1
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-bitmap.c | 439 +++++++++++++++++++++++++++++++++++++++++++++++++
18
block/qcow2-refcount.c | 6 +
19
block/qcow2.c | 125 +++++++++++++-
20
block/qcow2.h | 27 +++
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-bitmap.c b/block/qcow2-bitmap.c
36
new file mode 100644
37
index XXXXXXX..XXXXXXX
38
--- /dev/null
39
+++ b/block/qcow2-bitmap.c
40
@@ -XXX,XX +XXX,XX @@
41
+/*
42
+ * Bitmaps for the QCOW version 2 format
43
+ *
44
+ * Copyright (c) 2014-2017 Vladimir Sementsov-Ogievskiy
45
+ *
46
+ * This file is derived from qcow2-snapshot.c, original copyright:
47
+ * Copyright (c) 2004-2006 Fabrice Bellard
48
+ *
49
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
50
+ * of this software and associated documentation files (the "Software"), to deal
51
+ * in the Software without restriction, including without limitation the rights
52
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
53
+ * copies of the Software, and to permit persons to whom the Software is
54
+ * furnished to do so, subject to the following conditions:
55
+ *
56
+ * The above copyright notice and this permission notice shall be included in
57
+ * all copies or substantial portions of the Software.
58
+ *
59
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
60
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
61
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
62
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
63
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
64
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
65
+ * THE SOFTWARE.
66
+ */
67
+
68
+#include "qemu/osdep.h"
69
+#include "qapi/error.h"
70
+
71
+#include "block/block_int.h"
72
+#include "block/qcow2.h"
73
+
74
+/* NOTICE: BME here means Bitmaps Extension and used as a namespace for
75
+ * _internal_ constants. Please do not use this _internal_ abbreviation for
76
+ * other needs and/or outside of this file. */
77
+
78
+/* Bitmap directory entry constraints */
79
+#define BME_MAX_TABLE_SIZE 0x8000000
80
+#define BME_MAX_PHYS_SIZE 0x20000000 /* restrict BdrvDirtyBitmap size in RAM */
81
+#define BME_MAX_GRANULARITY_BITS 31
82
+#define BME_MIN_GRANULARITY_BITS 9
83
+#define BME_MAX_NAME_SIZE 1023
84
+
85
+/* Bitmap directory entry flags */
86
+#define BME_RESERVED_FLAGS 0xfffffffcU
87
+
88
+/* bits [1, 8] U [56, 63] are reserved */
89
+#define BME_TABLE_ENTRY_RESERVED_MASK 0xff000000000001feULL
90
+#define BME_TABLE_ENTRY_OFFSET_MASK 0x00fffffffffffe00ULL
91
+#define BME_TABLE_ENTRY_FLAG_ALL_ONES (1ULL << 0)
92
+
93
+typedef struct QEMU_PACKED Qcow2BitmapDirEntry {
94
+ /* header is 8 byte aligned */
95
+ uint64_t bitmap_table_offset;
96
+
97
+ uint32_t bitmap_table_size;
98
+ uint32_t flags;
99
+
100
+ uint8_t type;
101
+ uint8_t granularity_bits;
102
+ uint16_t name_size;
103
+ uint32_t extra_data_size;
104
+ /* extra data follows */
105
+ /* name follows */
106
+} Qcow2BitmapDirEntry;
107
+
108
+typedef struct Qcow2BitmapTable {
109
+ uint64_t offset;
110
+ uint32_t size; /* number of 64bit entries */
111
+ QSIMPLEQ_ENTRY(Qcow2BitmapTable) entry;
112
+} Qcow2BitmapTable;
113
+
114
+typedef struct Qcow2Bitmap {
115
+ Qcow2BitmapTable table;
116
+ uint32_t flags;
117
+ uint8_t granularity_bits;
118
+ char *name;
119
+
120
+ QSIMPLEQ_ENTRY(Qcow2Bitmap) entry;
121
+} Qcow2Bitmap;
122
+typedef QSIMPLEQ_HEAD(Qcow2BitmapList, Qcow2Bitmap) Qcow2BitmapList;
123
+
124
+typedef enum BitmapType {
125
+ BT_DIRTY_TRACKING_BITMAP = 1
126
+} BitmapType;
127
+
128
+static int check_table_entry(uint64_t entry, int cluster_size)
129
+{
130
+ uint64_t offset;
131
+
132
+ if (entry & BME_TABLE_ENTRY_RESERVED_MASK) {
133
+ return -EINVAL;
134
+ }
135
+
136
+ offset = entry & BME_TABLE_ENTRY_OFFSET_MASK;
137
+ if (offset != 0) {
138
+ /* if offset specified, bit 0 is reserved */
139
+ if (entry & BME_TABLE_ENTRY_FLAG_ALL_ONES) {
140
+ return -EINVAL;
141
+ }
142
+
143
+ if (offset % cluster_size != 0) {
144
+ return -EINVAL;
145
+ }
146
+ }
147
+
148
+ return 0;
149
+}
150
+
151
+static int bitmap_table_load(BlockDriverState *bs, Qcow2BitmapTable *tb,
152
+ uint64_t **bitmap_table)
153
+{
154
+ int ret;
155
+ BDRVQcow2State *s = bs->opaque;
156
+ uint32_t i;
157
+ uint64_t *table;
158
+
159
+ assert(tb->size != 0);
160
+ table = g_try_new(uint64_t, tb->size);
161
+ if (table == NULL) {
162
+ return -ENOMEM;
163
+ }
164
+
165
+ assert(tb->size <= BME_MAX_TABLE_SIZE);
166
+ ret = bdrv_pread(bs->file, tb->offset,
167
+ table, tb->size * sizeof(uint64_t));
168
+ if (ret < 0) {
169
+ goto fail;
170
+ }
171
+
172
+ for (i = 0; i < tb->size; ++i) {
173
+ be64_to_cpus(&table[i]);
174
+ ret = check_table_entry(table[i], s->cluster_size);
175
+ if (ret < 0) {
176
+ goto fail;
177
+ }
178
+ }
179
+
180
+ *bitmap_table = table;
181
+ return 0;
182
+
183
+fail:
184
+ g_free(table);
185
+
186
+ return ret;
187
+}
188
+
189
+/*
190
+ * Bitmap List
191
+ */
192
+
193
+/*
194
+ * Bitmap List private functions
195
+ * Only Bitmap List knows about bitmap directory structure in Qcow2.
196
+ */
197
+
198
+static inline void bitmap_dir_entry_to_cpu(Qcow2BitmapDirEntry *entry)
199
+{
200
+ be64_to_cpus(&entry->bitmap_table_offset);
201
+ be32_to_cpus(&entry->bitmap_table_size);
202
+ be32_to_cpus(&entry->flags);
203
+ be16_to_cpus(&entry->name_size);
204
+ be32_to_cpus(&entry->extra_data_size);
205
+}
206
+
207
+static inline int calc_dir_entry_size(size_t name_size, size_t extra_data_size)
208
+{
209
+ return align_offset(sizeof(Qcow2BitmapDirEntry) +
210
+ name_size + extra_data_size, 8);
211
+}
212
+
213
+static inline int dir_entry_size(Qcow2BitmapDirEntry *entry)
214
+{
215
+ return calc_dir_entry_size(entry->name_size, entry->extra_data_size);
216
+}
217
+
218
+static inline const char *dir_entry_name_field(Qcow2BitmapDirEntry *entry)
219
+{
220
+ return (const char *)(entry + 1) + entry->extra_data_size;
221
+}
222
+
223
+static inline char *dir_entry_copy_name(Qcow2BitmapDirEntry *entry)
224
+{
225
+ const char *name_field = dir_entry_name_field(entry);
226
+ return g_strndup(name_field, entry->name_size);
227
+}
228
+
229
+static inline Qcow2BitmapDirEntry *next_dir_entry(Qcow2BitmapDirEntry *entry)
230
+{
231
+ return (Qcow2BitmapDirEntry *)((uint8_t *)entry + dir_entry_size(entry));
232
+}
233
+
234
+static int check_dir_entry(BlockDriverState *bs, Qcow2BitmapDirEntry *entry)
235
+{
236
+ BDRVQcow2State *s = bs->opaque;
237
+ uint64_t phys_bitmap_bytes;
238
+ int64_t len;
239
+
240
+ bool fail = (entry->bitmap_table_size == 0) ||
241
+ (entry->bitmap_table_offset == 0) ||
242
+ (entry->bitmap_table_offset % s->cluster_size) ||
243
+ (entry->bitmap_table_size > BME_MAX_TABLE_SIZE) ||
244
+ (entry->granularity_bits > BME_MAX_GRANULARITY_BITS) ||
245
+ (entry->granularity_bits < BME_MIN_GRANULARITY_BITS) ||
246
+ (entry->flags & BME_RESERVED_FLAGS) ||
247
+ (entry->name_size > BME_MAX_NAME_SIZE) ||
248
+ (entry->type != BT_DIRTY_TRACKING_BITMAP);
249
+
250
+ if (fail) {
251
+ return -EINVAL;
252
+ }
253
+
254
+ phys_bitmap_bytes = (uint64_t)entry->bitmap_table_size * s->cluster_size;
255
+ len = bdrv_getlength(bs);
256
+
257
+ if (len < 0) {
258
+ return len;
259
+ }
260
+
261
+ fail = (phys_bitmap_bytes > BME_MAX_PHYS_SIZE) ||
262
+ (len > ((phys_bitmap_bytes * 8) << entry->granularity_bits));
263
+
264
+ return fail ? -EINVAL : 0;
265
+}
266
+
267
+/*
268
+ * Bitmap List public functions
269
+ */
270
+
271
+static void bitmap_free(Qcow2Bitmap *bm)
272
+{
273
+ g_free(bm->name);
274
+ g_free(bm);
275
+}
276
+
277
+static void bitmap_list_free(Qcow2BitmapList *bm_list)
278
+{
279
+ Qcow2Bitmap *bm;
280
+
281
+ if (bm_list == NULL) {
282
+ return;
283
+ }
284
+
285
+ while ((bm = QSIMPLEQ_FIRST(bm_list)) != NULL) {
286
+ QSIMPLEQ_REMOVE_HEAD(bm_list, entry);
287
+ bitmap_free(bm);
288
+ }
289
+
290
+ g_free(bm_list);
291
+}
292
+
293
+static Qcow2BitmapList *bitmap_list_new(void)
294
+{
295
+ Qcow2BitmapList *bm_list = g_new(Qcow2BitmapList, 1);
296
+ QSIMPLEQ_INIT(bm_list);
297
+
298
+ return bm_list;
299
+}
300
+
301
+/* bitmap_list_load
302
+ * Get bitmap list from qcow2 image. Actually reads bitmap directory,
303
+ * checks it and convert to bitmap list.
304
+ */
305
+static Qcow2BitmapList *bitmap_list_load(BlockDriverState *bs, uint64_t offset,
306
+ uint64_t size, Error **errp)
307
+{
308
+ int ret;
309
+ BDRVQcow2State *s = bs->opaque;
310
+ uint8_t *dir, *dir_end;
311
+ Qcow2BitmapDirEntry *e;
312
+ uint32_t nb_dir_entries = 0;
313
+ Qcow2BitmapList *bm_list = NULL;
314
+
315
+ if (size == 0) {
316
+ error_setg(errp, "Requested bitmap directory size is zero");
317
+ return NULL;
318
+ }
319
+
320
+ if (size > QCOW2_MAX_BITMAP_DIRECTORY_SIZE) {
321
+ error_setg(errp, "Requested bitmap directory size is too big");
322
+ return NULL;
323
+ }
324
+
325
+ dir = g_try_malloc(size);
326
+ if (dir == NULL) {
327
+ error_setg(errp, "Failed to allocate space for bitmap directory");
328
+ return NULL;
329
+ }
330
+ dir_end = dir + size;
331
+
332
+ ret = bdrv_pread(bs->file, offset, dir, size);
333
+ if (ret < 0) {
334
+ error_setg_errno(errp, -ret, "Failed to read bitmap directory");
335
+ goto fail;
336
+ }
337
+
338
+ bm_list = bitmap_list_new();
339
+ for (e = (Qcow2BitmapDirEntry *)dir;
340
+ e < (Qcow2BitmapDirEntry *)dir_end;
341
+ e = next_dir_entry(e))
342
+ {
343
+ Qcow2Bitmap *bm;
344
+
345
+ if ((uint8_t *)(e + 1) > dir_end) {
346
+ goto broken_dir;
347
+ }
348
+
349
+ if (++nb_dir_entries > s->nb_bitmaps) {
350
+ error_setg(errp, "More bitmaps found than specified in header"
351
+ " extension");
352
+ goto fail;
353
+ }
354
+ bitmap_dir_entry_to_cpu(e);
355
+
356
+ if ((uint8_t *)next_dir_entry(e) > dir_end) {
357
+ goto broken_dir;
358
+ }
359
+
360
+ if (e->extra_data_size != 0) {
361
+ error_setg(errp, "Bitmap extra data is not supported");
362
+ goto fail;
363
+ }
364
+
365
+ ret = check_dir_entry(bs, e);
366
+ if (ret < 0) {
367
+ error_setg(errp, "Bitmap '%.*s' doesn't satisfy the constraints",
368
+ e->name_size, dir_entry_name_field(e));
369
+ goto fail;
370
+ }
371
+
372
+ bm = g_new(Qcow2Bitmap, 1);
373
+ bm->table.offset = e->bitmap_table_offset;
374
+ bm->table.size = e->bitmap_table_size;
375
+ bm->flags = e->flags;
376
+ bm->granularity_bits = e->granularity_bits;
377
+ bm->name = dir_entry_copy_name(e);
378
+ QSIMPLEQ_INSERT_TAIL(bm_list, bm, entry);
379
+ }
380
+
381
+ if (nb_dir_entries != s->nb_bitmaps) {
382
+ error_setg(errp, "Less bitmaps found than specified in header"
383
+ " extension");
384
+ goto fail;
385
+ }
386
+
387
+ if ((uint8_t *)e != dir_end) {
388
+ goto broken_dir;
389
+ }
390
+
391
+ g_free(dir);
392
+ return bm_list;
393
+
394
+broken_dir:
395
+ ret = -EINVAL;
396
+ error_setg(errp, "Broken bitmap directory");
397
+
398
+fail:
399
+ g_free(dir);
400
+ bitmap_list_free(bm_list);
401
+
402
+ return NULL;
403
+}
404
+
405
+int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
406
+ void **refcount_table,
407
+ int64_t *refcount_table_size)
408
+{
409
+ int ret;
410
+ BDRVQcow2State *s = bs->opaque;
411
+ Qcow2BitmapList *bm_list;
412
+ Qcow2Bitmap *bm;
413
+
414
+ if (s->nb_bitmaps == 0) {
415
+ return 0;
416
+ }
417
+
418
+ ret = qcow2_inc_refcounts_imrt(bs, res, refcount_table, refcount_table_size,
419
+ s->bitmap_directory_offset,
420
+ s->bitmap_directory_size);
421
+ if (ret < 0) {
422
+ return ret;
423
+ }
424
+
425
+ bm_list = bitmap_list_load(bs, s->bitmap_directory_offset,
426
+ s->bitmap_directory_size, NULL);
427
+ if (bm_list == NULL) {
428
+ res->corruptions++;
429
+ return -EINVAL;
430
+ }
431
+
432
+ QSIMPLEQ_FOREACH(bm, bm_list, entry) {
433
+ uint64_t *bitmap_table = NULL;
434
+ int i;
435
+
436
+ ret = qcow2_inc_refcounts_imrt(bs, res,
437
+ refcount_table, refcount_table_size,
438
+ bm->table.offset,
439
+ bm->table.size * sizeof(uint64_t));
440
+ if (ret < 0) {
441
+ goto out;
442
+ }
443
+
444
+ ret = bitmap_table_load(bs, &bm->table, &bitmap_table);
445
+ if (ret < 0) {
446
+ res->corruptions++;
447
+ goto out;
448
+ }
449
+
450
+ for (i = 0; i < bm->table.size; ++i) {
451
+ uint64_t entry = bitmap_table[i];
452
+ uint64_t offset = entry & BME_TABLE_ENTRY_OFFSET_MASK;
453
+
454
+ if (check_table_entry(entry, s->cluster_size) < 0) {
455
+ res->corruptions++;
456
+ continue;
457
+ }
458
+
459
+ if (offset == 0) {
460
+ continue;
461
+ }
462
+
463
+ ret = qcow2_inc_refcounts_imrt(bs, res,
464
+ refcount_table, refcount_table_size,
465
+ offset, s->cluster_size);
466
+ if (ret < 0) {
467
+ g_free(bitmap_table);
468
+ goto out;
469
+ }
470
+ }
471
+
472
+ g_free(bitmap_table);
473
+ }
474
+
475
+out:
476
+ bitmap_list_free(bm_list);
477
+
478
+ return ret;
479
+}
480
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
481
index XXXXXXX..XXXXXXX 100644
482
--- a/block/qcow2-refcount.c
483
+++ b/block/qcow2-refcount.c
484
@@ -XXX,XX +XXX,XX @@ static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
485
}
486
}
487
488
+ /* bitmaps */
489
+ ret = qcow2_check_bitmaps_refcounts(bs, res, refcount_table, nb_clusters);
490
+ if (ret < 0) {
491
+ return ret;
492
+ }
493
+
494
return check_refblocks(bs, res, fix, rebuild, refcount_table, nb_clusters);
495
}
496
497
diff --git a/block/qcow2.c b/block/qcow2.c
498
index XXXXXXX..XXXXXXX 100644
499
--- a/block/qcow2.c
500
+++ b/block/qcow2.c
501
@@ -XXX,XX +XXX,XX @@ typedef struct {
502
#define QCOW2_EXT_MAGIC_BACKING_FORMAT 0xE2792ACA
503
#define QCOW2_EXT_MAGIC_FEATURE_TABLE 0x6803f857
504
#define QCOW2_EXT_MAGIC_CRYPTO_HEADER 0x0537be77
505
+#define QCOW2_EXT_MAGIC_BITMAPS 0x23852875
506
507
static int qcow2_probe(const uint8_t *buf, int buf_size, const char *filename)
508
{
509
@@ -XXX,XX +XXX,XX @@ static ssize_t qcow2_crypto_hdr_write_func(QCryptoBlock *block, size_t offset,
510
*/
511
static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
512
uint64_t end_offset, void **p_feature_table,
513
- int flags, Error **errp)
514
+ int flags, bool *need_update_header,
515
+ Error **errp)
516
{
517
BDRVQcow2State *s = bs->opaque;
518
QCowExtension ext;
519
uint64_t offset;
520
int ret;
521
+ Qcow2BitmapHeaderExt bitmaps_ext;
522
+
523
+ if (need_update_header != NULL) {
524
+ *need_update_header = false;
525
+ }
526
527
#ifdef DEBUG_EXT
528
printf("qcow2_read_extensions: start=%ld end=%ld\n", start_offset, end_offset);
529
@@ -XXX,XX +XXX,XX @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
530
}
531
} break;
532
533
+ case QCOW2_EXT_MAGIC_BITMAPS:
534
+ if (ext.len != sizeof(bitmaps_ext)) {
535
+ error_setg_errno(errp, -ret, "bitmaps_ext: "
536
+ "Invalid extension length");
537
+ return -EINVAL;
538
+ }
539
+
540
+ if (!(s->autoclear_features & QCOW2_AUTOCLEAR_BITMAPS)) {
541
+ error_report("WARNING: a program lacking bitmap support "
542
+ "modified this file, so all bitmaps are now "
543
+ "considered inconsistent. Some clusters may be "
544
+ "leaked, run 'qemu-img check -r' on the image "
545
+ "file to fix.");
546
+ if (need_update_header != NULL) {
547
+ /* Updating is needed to drop invalid bitmap extension. */
548
+ *need_update_header = true;
549
+ }
550
+ break;
551
+ }
552
+
553
+ ret = bdrv_pread(bs->file, offset, &bitmaps_ext, ext.len);
554
+ if (ret < 0) {
555
+ error_setg_errno(errp, -ret, "bitmaps_ext: "
556
+ "Could not read ext header");
557
+ return ret;
558
+ }
559
+
560
+ if (bitmaps_ext.reserved32 != 0) {
561
+ error_setg_errno(errp, -ret, "bitmaps_ext: "
562
+ "Reserved field is not zero");
563
+ return -EINVAL;
564
+ }
565
+
566
+ be32_to_cpus(&bitmaps_ext.nb_bitmaps);
567
+ be64_to_cpus(&bitmaps_ext.bitmap_directory_size);
568
+ be64_to_cpus(&bitmaps_ext.bitmap_directory_offset);
569
+
570
+ if (bitmaps_ext.nb_bitmaps > QCOW2_MAX_BITMAPS) {
571
+ error_setg(errp,
572
+ "bitmaps_ext: Image has %" PRIu32 " bitmaps, "
573
+ "exceeding the QEMU supported maximum of %d",
574
+ bitmaps_ext.nb_bitmaps, QCOW2_MAX_BITMAPS);
575
+ return -EINVAL;
576
+ }
577
+
578
+ if (bitmaps_ext.nb_bitmaps == 0) {
579
+ error_setg(errp, "found bitmaps extension with zero bitmaps");
580
+ return -EINVAL;
581
+ }
582
+
583
+ if (bitmaps_ext.bitmap_directory_offset & (s->cluster_size - 1)) {
584
+ error_setg(errp, "bitmaps_ext: "
585
+ "invalid bitmap directory offset");
586
+ return -EINVAL;
587
+ }
588
+
589
+ if (bitmaps_ext.bitmap_directory_size >
590
+ QCOW2_MAX_BITMAP_DIRECTORY_SIZE) {
591
+ error_setg(errp, "bitmaps_ext: "
592
+ "bitmap directory size (%" PRIu64 ") exceeds "
593
+ "the maximum supported size (%d)",
594
+ bitmaps_ext.bitmap_directory_size,
595
+ QCOW2_MAX_BITMAP_DIRECTORY_SIZE);
596
+ return -EINVAL;
597
+ }
598
+
599
+ s->nb_bitmaps = bitmaps_ext.nb_bitmaps;
600
+ s->bitmap_directory_offset =
601
+ bitmaps_ext.bitmap_directory_offset;
602
+ s->bitmap_directory_size =
603
+ bitmaps_ext.bitmap_directory_size;
604
+
605
+#ifdef DEBUG_EXT
606
+ printf("Qcow2: Got bitmaps extension: "
607
+ "offset=%" PRIu64 " nb_bitmaps=%" PRIu32 "\n",
608
+ s->bitmap_directory_offset, s->nb_bitmaps);
609
+#endif
610
+ break;
611
+
612
default:
613
/* unknown magic - save it in case we need to rewrite the header */
614
{
615
@@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
616
Error *local_err = NULL;
617
uint64_t ext_end;
618
uint64_t l1_vm_state_index;
619
+ bool update_header = false;
620
621
ret = bdrv_pread(bs->file, 0, &header, sizeof(header));
622
if (ret < 0) {
623
@@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
624
if (s->incompatible_features & ~QCOW2_INCOMPAT_MASK) {
625
void *feature_table = NULL;
626
qcow2_read_extensions(bs, header.header_length, ext_end,
627
- &feature_table, flags, NULL);
628
+ &feature_table, flags, NULL, NULL);
629
report_unsupported_feature(errp, feature_table,
630
s->incompatible_features &
631
~QCOW2_INCOMPAT_MASK);
632
@@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
633
634
/* read qcow2 extensions */
635
if (qcow2_read_extensions(bs, header.header_length, ext_end, NULL,
636
- flags, &local_err)) {
637
+ flags, &update_header, &local_err)) {
638
error_propagate(errp, local_err);
639
ret = -EINVAL;
640
goto fail;
641
@@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
642
}
643
644
/* Clear unknown autoclear feature bits */
645
- if (!bs->read_only && !(flags & BDRV_O_INACTIVE) && s->autoclear_features) {
646
- s->autoclear_features = 0;
647
+ update_header |= s->autoclear_features & ~QCOW2_AUTOCLEAR_MASK;
648
+
649
+ if (update_header && !bs->read_only && !(flags & BDRV_O_INACTIVE)) {
650
+ s->autoclear_features &= QCOW2_AUTOCLEAR_MASK;
651
ret = qcow2_update_header(bs);
652
if (ret < 0) {
653
error_setg_errno(errp, -ret, "Could not update qcow2 header");
654
@@ -XXX,XX +XXX,XX @@ int qcow2_update_header(BlockDriverState *bs)
655
buflen -= ret;
656
}
657
658
+ /* Bitmap extension */
659
+ if (s->nb_bitmaps > 0) {
660
+ Qcow2BitmapHeaderExt bitmaps_header = {
661
+ .nb_bitmaps = cpu_to_be32(s->nb_bitmaps),
662
+ .bitmap_directory_size =
663
+ cpu_to_be64(s->bitmap_directory_size),
664
+ .bitmap_directory_offset =
665
+ cpu_to_be64(s->bitmap_directory_offset)
666
+ };
667
+ ret = header_ext_add(buf, QCOW2_EXT_MAGIC_BITMAPS,
668
+ &bitmaps_header, sizeof(bitmaps_header),
669
+ buflen);
670
+ if (ret < 0) {
671
+ goto fail;
672
+ }
673
+ buf += ret;
674
+ buflen -= ret;
675
+ }
676
+
677
/* Keep unknown header extensions */
678
QLIST_FOREACH(uext, &s->unknown_header_ext, next) {
679
ret = header_ext_add(buf, uext->magic, uext->data, uext->len, buflen);
680
@@ -XXX,XX +XXX,XX @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset, Error **errp)
681
return -ENOTSUP;
682
}
683
684
+ /* cannot proceed if image has bitmaps */
685
+ if (s->nb_bitmaps) {
686
+ /* TODO: resize bitmaps in the image */
687
+ error_setg(errp, "Can't resize an image which has bitmaps");
688
+ return -ENOTSUP;
689
+ }
690
+
691
/* shrinking is currently not supported */
692
if (offset < bs->total_sectors * 512) {
693
error_setg(errp, "qcow2 doesn't support shrinking images yet");
694
diff --git a/block/qcow2.h b/block/qcow2.h
695
index XXXXXXX..XXXXXXX 100644
696
--- a/block/qcow2.h
697
+++ b/block/qcow2.h
698
@@ -XXX,XX +XXX,XX @@
699
* space for snapshot names and IDs */
700
#define QCOW_MAX_SNAPSHOTS_SIZE (1024 * QCOW_MAX_SNAPSHOTS)
701
702
+/* Bitmap header extension constraints */
703
+#define QCOW2_MAX_BITMAPS 65535
704
+#define QCOW2_MAX_BITMAP_DIRECTORY_SIZE (1024 * QCOW2_MAX_BITMAPS)
705
+
706
/* indicate that the refcount of the referenced cluster is exactly one. */
707
#define QCOW_OFLAG_COPIED (1ULL << 63)
708
/* indicate that the cluster is compressed (they never have the copied flag) */
709
@@ -XXX,XX +XXX,XX @@ enum {
710
QCOW2_COMPAT_FEAT_MASK = QCOW2_COMPAT_LAZY_REFCOUNTS,
711
};
712
713
+/* Autoclear feature bits */
714
+enum {
715
+ QCOW2_AUTOCLEAR_BITMAPS_BITNR = 0,
716
+ QCOW2_AUTOCLEAR_BITMAPS = 1 << QCOW2_AUTOCLEAR_BITMAPS_BITNR,
717
+
718
+ QCOW2_AUTOCLEAR_MASK = QCOW2_AUTOCLEAR_BITMAPS,
719
+};
720
+
721
enum qcow2_discard_type {
722
QCOW2_DISCARD_NEVER = 0,
723
QCOW2_DISCARD_ALWAYS,
724
@@ -XXX,XX +XXX,XX @@ typedef uint64_t Qcow2GetRefcountFunc(const void *refcount_array,
725
typedef void Qcow2SetRefcountFunc(void *refcount_array,
726
uint64_t index, uint64_t value);
727
728
+typedef struct Qcow2BitmapHeaderExt {
729
+ uint32_t nb_bitmaps;
730
+ uint32_t reserved32;
731
+ uint64_t bitmap_directory_size;
732
+ uint64_t bitmap_directory_offset;
733
+} QEMU_PACKED Qcow2BitmapHeaderExt;
734
+
735
typedef struct BDRVQcow2State {
736
int cluster_bits;
737
int cluster_size;
738
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVQcow2State {
739
unsigned int nb_snapshots;
740
QCowSnapshot *snapshots;
741
742
+ uint32_t nb_bitmaps;
743
+ uint64_t bitmap_directory_size;
744
+ uint64_t bitmap_directory_offset;
745
+
746
int flags;
747
int qcow_version;
748
bool use_lazy_refcounts;
749
@@ -XXX,XX +XXX,XX @@ int qcow2_cache_get_empty(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset,
750
void **table);
751
void qcow2_cache_put(BlockDriverState *bs, Qcow2Cache *c, void **table);
752
753
+/* qcow2-bitmap.c functions */
754
+int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
755
+ void **refcount_table,
756
+ int64_t *refcount_table_size);
757
#endif
758
--
759
1.8.3.1
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
1.8.3.1
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
block/dirty-bitmap.c | 36 ++++++++++++++++++++++++++++++++++++
13
block/io.c | 8 ++++++++
14
blockdev.c | 6 ++++++
15
include/block/dirty-bitmap.h | 4 ++++
16
4 files changed, 54 insertions(+)
17
18
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/block/dirty-bitmap.c
21
+++ b/block/dirty-bitmap.c
22
@@ -XXX,XX +XXX,XX @@ struct BdrvDirtyBitmap {
23
bool disabled; /* Bitmap is disabled. It ignores all writes to
24
the device */
25
int active_iterators; /* How many iterators are active */
26
+ bool readonly; /* Bitmap is read-only. This field also
27
+ prevents the respective image from being
28
+ modified (i.e. blocks writes and discards).
29
+ Such operations must fail and both the image
30
+ and this bitmap must remain unchanged while
31
+ this flag is set. */
32
QLIST_ENTRY(BdrvDirtyBitmap) list;
33
};
34
35
@@ -XXX,XX +XXX,XX @@ void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
36
int64_t cur_sector, int64_t nr_sectors)
37
{
38
assert(bdrv_dirty_bitmap_enabled(bitmap));
39
+ assert(!bdrv_dirty_bitmap_readonly(bitmap));
40
hbitmap_set(bitmap->bitmap, cur_sector, nr_sectors);
41
}
42
43
@@ -XXX,XX +XXX,XX @@ void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
44
int64_t cur_sector, int64_t nr_sectors)
45
{
46
assert(bdrv_dirty_bitmap_enabled(bitmap));
47
+ assert(!bdrv_dirty_bitmap_readonly(bitmap));
48
hbitmap_reset(bitmap->bitmap, cur_sector, nr_sectors);
49
}
50
51
@@ -XXX,XX +XXX,XX @@ void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
52
void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out)
53
{
54
assert(bdrv_dirty_bitmap_enabled(bitmap));
55
+ assert(!bdrv_dirty_bitmap_readonly(bitmap));
56
bdrv_dirty_bitmap_lock(bitmap);
57
if (!out) {
58
hbitmap_reset_all(bitmap->bitmap);
59
@@ -XXX,XX +XXX,XX @@ void bdrv_undo_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *in)
60
{
61
HBitmap *tmp = bitmap->bitmap;
62
assert(bdrv_dirty_bitmap_enabled(bitmap));
63
+ assert(!bdrv_dirty_bitmap_readonly(bitmap));
64
bitmap->bitmap = in;
65
hbitmap_free(tmp);
66
}
67
@@ -XXX,XX +XXX,XX @@ void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector,
68
if (!bdrv_dirty_bitmap_enabled(bitmap)) {
69
continue;
70
}
71
+ assert(!bdrv_dirty_bitmap_readonly(bitmap));
72
hbitmap_set(bitmap->bitmap, cur_sector, nr_sectors);
73
}
74
bdrv_dirty_bitmaps_unlock(bs);
75
@@ -XXX,XX +XXX,XX @@ int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap)
76
{
77
return hbitmap_count(bitmap->meta);
78
}
79
+
80
+bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap)
81
+{
82
+ return bitmap->readonly;
83
+}
84
+
85
+/* Called with BQL taken. */
86
+void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap, bool value)
87
+{
88
+ qemu_mutex_lock(bitmap->mutex);
89
+ bitmap->readonly = value;
90
+ qemu_mutex_unlock(bitmap->mutex);
91
+}
92
+
93
+bool bdrv_has_readonly_bitmaps(BlockDriverState *bs)
94
+{
95
+ BdrvDirtyBitmap *bm;
96
+ QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
97
+ if (bm->readonly) {
98
+ return true;
99
+ }
100
+ }
101
+
102
+ return false;
103
+}
104
diff --git a/block/io.c b/block/io.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/block/io.c
107
+++ b/block/io.c
108
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child,
109
uint64_t bytes_remaining = bytes;
110
int max_transfer;
111
112
+ if (bdrv_has_readonly_bitmaps(bs)) {
113
+ return -EPERM;
114
+ }
115
+
116
assert(is_power_of_2(align));
117
assert((offset & (align - 1)) == 0);
118
assert((bytes & (align - 1)) == 0);
119
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pdiscard(BlockDriverState *bs, int64_t offset,
120
return -ENOMEDIUM;
121
}
122
123
+ if (bdrv_has_readonly_bitmaps(bs)) {
124
+ return -EPERM;
125
+ }
126
+
127
ret = bdrv_check_byte_request(bs, offset, bytes);
128
if (ret < 0) {
129
return ret;
130
diff --git a/blockdev.c b/blockdev.c
131
index XXXXXXX..XXXXXXX 100644
132
--- a/blockdev.c
133
+++ b/blockdev.c
134
@@ -XXX,XX +XXX,XX @@ static void block_dirty_bitmap_clear_prepare(BlkActionState *common,
135
} else if (!bdrv_dirty_bitmap_enabled(state->bitmap)) {
136
error_setg(errp, "Cannot clear a disabled bitmap");
137
return;
138
+ } else if (bdrv_dirty_bitmap_readonly(state->bitmap)) {
139
+ error_setg(errp, "Cannot clear a readonly bitmap");
140
+ return;
141
}
142
143
bdrv_clear_dirty_bitmap(state->bitmap, &state->backup);
144
@@ -XXX,XX +XXX,XX @@ void qmp_block_dirty_bitmap_clear(const char *node, const char *name,
145
"Bitmap '%s' is currently disabled and cannot be cleared",
146
name);
147
return;
148
+ } else if (bdrv_dirty_bitmap_readonly(bitmap)) {
149
+ error_setg(errp, "Bitmap '%s' is readonly and cannot be cleared", name);
150
+ return;
151
}
152
153
bdrv_clear_dirty_bitmap(bitmap, NULL);
154
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
155
index XXXXXXX..XXXXXXX 100644
156
--- a/include/block/dirty-bitmap.h
157
+++ b/include/block/dirty-bitmap.h
158
@@ -XXX,XX +XXX,XX @@ void bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap,
159
bool finish);
160
void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap);
161
162
+void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap, bool value);
163
+
164
/* Functions that require manual locking. */
165
void bdrv_dirty_bitmap_lock(BdrvDirtyBitmap *bitmap);
166
void bdrv_dirty_bitmap_unlock(BdrvDirtyBitmap *bitmap);
167
@@ -XXX,XX +XXX,XX @@ void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *hbi, int64_t sector_num);
168
int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap);
169
int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap);
170
void bdrv_dirty_bitmap_truncate(BlockDriverState *bs);
171
+bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap);
172
+bool bdrv_has_readonly_bitmaps(BlockDriverState *bs);
173
174
#endif
175
--
176
1.8.3.1
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-bitmap.c | 389 +++++++++++++++++++++++++++++++++++++++++++++++++++
16
block/qcow2.c | 17 ++-
17
block/qcow2.h | 2 +
18
3 files changed, 406 insertions(+), 2 deletions(-)
19
20
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/block/qcow2-bitmap.c
23
+++ b/block/qcow2-bitmap.c
24
@@ -XXX,XX +XXX,XX @@
25
26
/* Bitmap directory entry flags */
27
#define BME_RESERVED_FLAGS 0xfffffffcU
28
+#define BME_FLAG_IN_USE (1U << 0)
29
+#define BME_FLAG_AUTO (1U << 1)
30
31
/* bits [1, 8] U [56, 63] are reserved */
32
#define BME_TABLE_ENTRY_RESERVED_MASK 0xff000000000001feULL
33
@@ -XXX,XX +XXX,XX @@ typedef enum BitmapType {
34
BT_DIRTY_TRACKING_BITMAP = 1
35
} BitmapType;
36
37
+static inline bool can_write(BlockDriverState *bs)
38
+{
39
+ return !bdrv_is_read_only(bs) && !(bdrv_get_flags(bs) & BDRV_O_INACTIVE);
40
+}
41
+
42
+static int update_header_sync(BlockDriverState *bs)
43
+{
44
+ int ret;
45
+
46
+ ret = qcow2_update_header(bs);
47
+ if (ret < 0) {
48
+ return ret;
49
+ }
50
+
51
+ return bdrv_flush(bs);
52
+}
53
+
54
static int check_table_entry(uint64_t entry, int cluster_size)
55
{
56
uint64_t offset;
57
@@ -XXX,XX +XXX,XX @@ fail:
58
return ret;
59
}
60
61
+/* This function returns the number of disk sectors covered by a single qcow2
62
+ * cluster of bitmap data. */
63
+static uint64_t sectors_covered_by_bitmap_cluster(const BDRVQcow2State *s,
64
+ const BdrvDirtyBitmap *bitmap)
65
+{
66
+ uint32_t sector_granularity =
67
+ bdrv_dirty_bitmap_granularity(bitmap) >> BDRV_SECTOR_BITS;
68
+
69
+ return (uint64_t)sector_granularity * (s->cluster_size << 3);
70
+}
71
+
72
+/* load_bitmap_data
73
+ * @bitmap_table entries must satisfy specification constraints.
74
+ * @bitmap must be cleared */
75
+static int load_bitmap_data(BlockDriverState *bs,
76
+ const uint64_t *bitmap_table,
77
+ uint32_t bitmap_table_size,
78
+ BdrvDirtyBitmap *bitmap)
79
+{
80
+ int ret = 0;
81
+ BDRVQcow2State *s = bs->opaque;
82
+ uint64_t sector, sbc;
83
+ uint64_t bm_size = bdrv_dirty_bitmap_size(bitmap);
84
+ uint8_t *buf = NULL;
85
+ uint64_t i, tab_size =
86
+ size_to_clusters(s,
87
+ bdrv_dirty_bitmap_serialization_size(bitmap, 0, bm_size));
88
+
89
+ if (tab_size != bitmap_table_size || tab_size > BME_MAX_TABLE_SIZE) {
90
+ return -EINVAL;
91
+ }
92
+
93
+ buf = g_malloc(s->cluster_size);
94
+ sbc = sectors_covered_by_bitmap_cluster(s, bitmap);
95
+ for (i = 0, sector = 0; i < tab_size; ++i, sector += sbc) {
96
+ uint64_t count = MIN(bm_size - sector, sbc);
97
+ uint64_t entry = bitmap_table[i];
98
+ uint64_t offset = entry & BME_TABLE_ENTRY_OFFSET_MASK;
99
+
100
+ assert(check_table_entry(entry, s->cluster_size) == 0);
101
+
102
+ if (offset == 0) {
103
+ if (entry & BME_TABLE_ENTRY_FLAG_ALL_ONES) {
104
+ bdrv_dirty_bitmap_deserialize_ones(bitmap, sector, count,
105
+ false);
106
+ } else {
107
+ /* No need to deserialize zeros because the dirty bitmap is
108
+ * already cleared */
109
+ }
110
+ } else {
111
+ ret = bdrv_pread(bs->file, offset, buf, s->cluster_size);
112
+ if (ret < 0) {
113
+ goto finish;
114
+ }
115
+ bdrv_dirty_bitmap_deserialize_part(bitmap, buf, sector, count,
116
+ false);
117
+ }
118
+ }
119
+ ret = 0;
120
+
121
+ bdrv_dirty_bitmap_deserialize_finish(bitmap);
122
+
123
+finish:
124
+ g_free(buf);
125
+
126
+ return ret;
127
+}
128
+
129
+static BdrvDirtyBitmap *load_bitmap(BlockDriverState *bs,
130
+ Qcow2Bitmap *bm, Error **errp)
131
+{
132
+ int ret;
133
+ uint64_t *bitmap_table = NULL;
134
+ uint32_t granularity;
135
+ BdrvDirtyBitmap *bitmap = NULL;
136
+
137
+ if (bm->flags & BME_FLAG_IN_USE) {
138
+ error_setg(errp, "Bitmap '%s' is in use", bm->name);
139
+ goto fail;
140
+ }
141
+
142
+ ret = bitmap_table_load(bs, &bm->table, &bitmap_table);
143
+ if (ret < 0) {
144
+ error_setg_errno(errp, -ret,
145
+ "Could not read bitmap_table table from image for "
146
+ "bitmap '%s'", bm->name);
147
+ goto fail;
148
+ }
149
+
150
+ granularity = 1U << bm->granularity_bits;
151
+ bitmap = bdrv_create_dirty_bitmap(bs, granularity, bm->name, errp);
152
+ if (bitmap == NULL) {
153
+ goto fail;
154
+ }
155
+
156
+ ret = load_bitmap_data(bs, bitmap_table, bm->table.size, bitmap);
157
+ if (ret < 0) {
158
+ error_setg_errno(errp, -ret, "Could not read bitmap '%s' from image",
159
+ bm->name);
160
+ goto fail;
161
+ }
162
+
163
+ g_free(bitmap_table);
164
+ return bitmap;
165
+
166
+fail:
167
+ g_free(bitmap_table);
168
+ if (bitmap != NULL) {
169
+ bdrv_release_dirty_bitmap(bs, bitmap);
170
+ }
171
+
172
+ return NULL;
173
+}
174
+
175
/*
176
* Bitmap List
177
*/
178
@@ -XXX,XX +XXX,XX @@ static inline void bitmap_dir_entry_to_cpu(Qcow2BitmapDirEntry *entry)
179
be32_to_cpus(&entry->extra_data_size);
180
}
181
182
+static inline void bitmap_dir_entry_to_be(Qcow2BitmapDirEntry *entry)
183
+{
184
+ cpu_to_be64s(&entry->bitmap_table_offset);
185
+ cpu_to_be32s(&entry->bitmap_table_size);
186
+ cpu_to_be32s(&entry->flags);
187
+ cpu_to_be16s(&entry->name_size);
188
+ cpu_to_be32s(&entry->extra_data_size);
189
+}
190
+
191
static inline int calc_dir_entry_size(size_t name_size, size_t extra_data_size)
192
{
193
return align_offset(sizeof(Qcow2BitmapDirEntry) +
194
@@ -XXX,XX +XXX,XX @@ static int check_dir_entry(BlockDriverState *bs, Qcow2BitmapDirEntry *entry)
195
return fail ? -EINVAL : 0;
196
}
197
198
+static inline void bitmap_directory_to_be(uint8_t *dir, size_t size)
199
+{
200
+ uint8_t *end = dir + size;
201
+ while (dir < end) {
202
+ Qcow2BitmapDirEntry *e = (Qcow2BitmapDirEntry *)dir;
203
+ dir += dir_entry_size(e);
204
+
205
+ bitmap_dir_entry_to_be(e);
206
+ }
207
+}
208
+
209
/*
210
* Bitmap List public functions
211
*/
212
@@ -XXX,XX +XXX,XX @@ static Qcow2BitmapList *bitmap_list_new(void)
213
return bm_list;
214
}
215
216
+static uint32_t bitmap_list_count(Qcow2BitmapList *bm_list)
217
+{
218
+ Qcow2Bitmap *bm;
219
+ uint32_t nb_bitmaps = 0;
220
+
221
+ QSIMPLEQ_FOREACH(bm, bm_list, entry) {
222
+ nb_bitmaps++;
223
+ }
224
+
225
+ return nb_bitmaps;
226
+}
227
+
228
/* bitmap_list_load
229
* Get bitmap list from qcow2 image. Actually reads bitmap directory,
230
* checks it and convert to bitmap list.
231
@@ -XXX,XX +XXX,XX @@ out:
232
233
return ret;
234
}
235
+
236
+/* bitmap_list_store
237
+ * Store bitmap list to qcow2 image as a bitmap directory.
238
+ * Everything is checked.
239
+ */
240
+static int bitmap_list_store(BlockDriverState *bs, Qcow2BitmapList *bm_list,
241
+ uint64_t *offset, uint64_t *size, bool in_place)
242
+{
243
+ int ret;
244
+ uint8_t *dir;
245
+ int64_t dir_offset = 0;
246
+ uint64_t dir_size = 0;
247
+ Qcow2Bitmap *bm;
248
+ Qcow2BitmapDirEntry *e;
249
+
250
+ QSIMPLEQ_FOREACH(bm, bm_list, entry) {
251
+ dir_size += calc_dir_entry_size(strlen(bm->name), 0);
252
+ }
253
+
254
+ if (dir_size == 0 || dir_size > QCOW2_MAX_BITMAP_DIRECTORY_SIZE) {
255
+ return -EINVAL;
256
+ }
257
+
258
+ if (in_place) {
259
+ if (*size != dir_size || *offset == 0) {
260
+ return -EINVAL;
261
+ }
262
+
263
+ dir_offset = *offset;
264
+ }
265
+
266
+ dir = g_try_malloc(dir_size);
267
+ if (dir == NULL) {
268
+ return -ENOMEM;
269
+ }
270
+
271
+ e = (Qcow2BitmapDirEntry *)dir;
272
+ QSIMPLEQ_FOREACH(bm, bm_list, entry) {
273
+ e->bitmap_table_offset = bm->table.offset;
274
+ e->bitmap_table_size = bm->table.size;
275
+ e->flags = bm->flags;
276
+ e->type = BT_DIRTY_TRACKING_BITMAP;
277
+ e->granularity_bits = bm->granularity_bits;
278
+ e->name_size = strlen(bm->name);
279
+ e->extra_data_size = 0;
280
+ memcpy(e + 1, bm->name, e->name_size);
281
+
282
+ if (check_dir_entry(bs, e) < 0) {
283
+ ret = -EINVAL;
284
+ goto fail;
285
+ }
286
+
287
+ e = next_dir_entry(e);
288
+ }
289
+
290
+ bitmap_directory_to_be(dir, dir_size);
291
+
292
+ if (!in_place) {
293
+ dir_offset = qcow2_alloc_clusters(bs, dir_size);
294
+ if (dir_offset < 0) {
295
+ ret = dir_offset;
296
+ goto fail;
297
+ }
298
+ }
299
+
300
+ ret = qcow2_pre_write_overlap_check(bs, 0, dir_offset, dir_size);
301
+ if (ret < 0) {
302
+ goto fail;
303
+ }
304
+
305
+ ret = bdrv_pwrite(bs->file, dir_offset, dir, dir_size);
306
+ if (ret < 0) {
307
+ goto fail;
308
+ }
309
+
310
+ g_free(dir);
311
+
312
+ if (!in_place) {
313
+ *size = dir_size;
314
+ *offset = dir_offset;
315
+ }
316
+
317
+ return 0;
318
+
319
+fail:
320
+ g_free(dir);
321
+
322
+ if (!in_place && dir_offset > 0) {
323
+ qcow2_free_clusters(bs, dir_offset, dir_size, QCOW2_DISCARD_OTHER);
324
+ }
325
+
326
+ return ret;
327
+}
328
+
329
+/*
330
+ * Bitmap List end
331
+ */
332
+
333
+static int update_ext_header_and_dir_in_place(BlockDriverState *bs,
334
+ Qcow2BitmapList *bm_list)
335
+{
336
+ BDRVQcow2State *s = bs->opaque;
337
+ int ret;
338
+
339
+ if (!(s->autoclear_features & QCOW2_AUTOCLEAR_BITMAPS) ||
340
+ bm_list == NULL || QSIMPLEQ_EMPTY(bm_list) ||
341
+ bitmap_list_count(bm_list) != s->nb_bitmaps)
342
+ {
343
+ return -EINVAL;
344
+ }
345
+
346
+ s->autoclear_features &= ~(uint64_t)QCOW2_AUTOCLEAR_BITMAPS;
347
+ ret = update_header_sync(bs);
348
+ if (ret < 0) {
349
+ /* Two variants are possible here:
350
+ * 1. Autoclear flag is dropped, all bitmaps will be lost.
351
+ * 2. Autoclear flag is not dropped, old state is left.
352
+ */
353
+ return ret;
354
+ }
355
+
356
+ /* autoclear bit is not set, so we can safely update bitmap directory */
357
+
358
+ ret = bitmap_list_store(bs, bm_list, &s->bitmap_directory_offset,
359
+ &s->bitmap_directory_size, true);
360
+ if (ret < 0) {
361
+ /* autoclear bit is cleared, so all leaked clusters would be removed on
362
+ * qemu-img check */
363
+ return ret;
364
+ }
365
+
366
+ ret = update_header_sync(bs);
367
+ if (ret < 0) {
368
+ /* autoclear bit is cleared, so all leaked clusters would be removed on
369
+ * qemu-img check */
370
+ return ret;
371
+ }
372
+
373
+ s->autoclear_features |= QCOW2_AUTOCLEAR_BITMAPS;
374
+ return update_header_sync(bs);
375
+ /* If final update_header_sync() fails, two variants are possible:
376
+ * 1. Autoclear flag is not set, all bitmaps will be lost.
377
+ * 2. Autoclear flag is set, header and directory are successfully updated.
378
+ */
379
+}
380
+
381
+/* for g_slist_foreach for GSList of BdrvDirtyBitmap* elements */
382
+static void release_dirty_bitmap_helper(gpointer bitmap,
383
+ gpointer bs)
384
+{
385
+ bdrv_release_dirty_bitmap(bs, bitmap);
386
+}
387
+
388
+/* for g_slist_foreach for GSList of BdrvDirtyBitmap* elements */
389
+static void set_readonly_helper(gpointer bitmap, gpointer value)
390
+{
391
+ bdrv_dirty_bitmap_set_readonly(bitmap, (bool)value);
392
+}
393
+
394
+/* qcow2_load_autoloading_dirty_bitmaps()
395
+ * Return value is a hint for caller: true means that the Qcow2 header was
396
+ * updated. (false doesn't mean that the header should be updated by the
397
+ * caller, it just means that updating was not needed or the image cannot be
398
+ * written to).
399
+ * On failure the function returns false.
400
+ */
401
+bool qcow2_load_autoloading_dirty_bitmaps(BlockDriverState *bs, Error **errp)
402
+{
403
+ BDRVQcow2State *s = bs->opaque;
404
+ Qcow2BitmapList *bm_list;
405
+ Qcow2Bitmap *bm;
406
+ GSList *created_dirty_bitmaps = NULL;
407
+ bool header_updated = false;
408
+
409
+ if (s->nb_bitmaps == 0) {
410
+ /* No bitmaps - nothing to do */
411
+ return false;
412
+ }
413
+
414
+ bm_list = bitmap_list_load(bs, s->bitmap_directory_offset,
415
+ s->bitmap_directory_size, errp);
416
+ if (bm_list == NULL) {
417
+ return false;
418
+ }
419
+
420
+ QSIMPLEQ_FOREACH(bm, bm_list, entry) {
421
+ if ((bm->flags & BME_FLAG_AUTO) && !(bm->flags & BME_FLAG_IN_USE)) {
422
+ BdrvDirtyBitmap *bitmap = load_bitmap(bs, bm, errp);
423
+ if (bitmap == NULL) {
424
+ goto fail;
425
+ }
426
+ bm->flags |= BME_FLAG_IN_USE;
427
+ created_dirty_bitmaps =
428
+ g_slist_append(created_dirty_bitmaps, bitmap);
429
+ }
430
+ }
431
+
432
+ if (created_dirty_bitmaps != NULL) {
433
+ if (can_write(bs)) {
434
+ /* in_use flags must be updated */
435
+ int ret = update_ext_header_and_dir_in_place(bs, bm_list);
436
+ if (ret < 0) {
437
+ error_setg_errno(errp, -ret, "Can't update bitmap directory");
438
+ goto fail;
439
+ }
440
+ header_updated = true;
441
+ } else {
442
+ g_slist_foreach(created_dirty_bitmaps, set_readonly_helper,
443
+ (gpointer)true);
444
+ }
445
+ }
446
+
447
+ g_slist_free(created_dirty_bitmaps);
448
+ bitmap_list_free(bm_list);
449
+
450
+ return header_updated;
451
+
452
+fail:
453
+ g_slist_foreach(created_dirty_bitmaps, release_dirty_bitmap_helper, bs);
454
+ g_slist_free(created_dirty_bitmaps);
455
+ bitmap_list_free(bm_list);
456
+
457
+ return false;
458
+}
459
diff --git a/block/qcow2.c b/block/qcow2.c
460
index XXXXXXX..XXXXXXX 100644
461
--- a/block/qcow2.c
462
+++ b/block/qcow2.c
463
@@ -XXX,XX +XXX,XX @@ static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
464
465
/* Clear unknown autoclear feature bits */
466
update_header |= s->autoclear_features & ~QCOW2_AUTOCLEAR_MASK;
467
-
468
- if (update_header && !bs->read_only && !(flags & BDRV_O_INACTIVE)) {
469
+ update_header =
470
+ update_header && !bs->read_only && !(flags & BDRV_O_INACTIVE);
471
+ if (update_header) {
472
s->autoclear_features &= QCOW2_AUTOCLEAR_MASK;
473
+ }
474
+
475
+ if (qcow2_load_autoloading_dirty_bitmaps(bs, &local_err)) {
476
+ update_header = false;
477
+ }
478
+ if (local_err != NULL) {
479
+ error_propagate(errp, local_err);
480
+ ret = -EINVAL;
481
+ goto fail;
482
+ }
483
+
484
+ if (update_header) {
485
ret = qcow2_update_header(bs);
486
if (ret < 0) {
487
error_setg_errno(errp, -ret, "Could not update qcow2 header");
488
diff --git a/block/qcow2.h b/block/qcow2.h
489
index XXXXXXX..XXXXXXX 100644
490
--- a/block/qcow2.h
491
+++ b/block/qcow2.h
492
@@ -XXX,XX +XXX,XX @@ void qcow2_cache_put(BlockDriverState *bs, Qcow2Cache *c, void **table);
493
int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
494
void **refcount_table,
495
int64_t *refcount_table_size);
496
+bool qcow2_load_autoloading_dirty_bitmaps(BlockDriverState *bs, Error **errp);
497
+
498
#endif
499
--
500
1.8.3.1
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
1.8.3.1
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
block.c | 19 +++++++++++++++++++
14
include/block/block_int.h | 7 +++++++
15
2 files changed, 26 insertions(+)
16
17
diff --git a/block.c b/block.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block.c
20
+++ b/block.c
21
@@ -XXX,XX +XXX,XX @@ void bdrv_reopen_commit(BDRVReopenState *reopen_state)
22
{
23
BlockDriver *drv;
24
BlockDriverState *bs;
25
+ bool old_can_write, new_can_write;
26
27
assert(reopen_state != NULL);
28
bs = reopen_state->bs;
29
drv = bs->drv;
30
assert(drv != NULL);
31
32
+ old_can_write =
33
+ !bdrv_is_read_only(bs) && !(bdrv_get_flags(bs) & BDRV_O_INACTIVE);
34
+
35
/* If there are any driver level actions to take */
36
if (drv->bdrv_reopen_commit) {
37
drv->bdrv_reopen_commit(reopen_state);
38
@@ -XXX,XX +XXX,XX @@ void bdrv_reopen_commit(BDRVReopenState *reopen_state)
39
bs->read_only = !(reopen_state->flags & BDRV_O_RDWR);
40
41
bdrv_refresh_limits(bs, NULL);
42
+
43
+ new_can_write =
44
+ !bdrv_is_read_only(bs) && !(bdrv_get_flags(bs) & BDRV_O_INACTIVE);
45
+ if (!old_can_write && new_can_write && drv->bdrv_reopen_bitmaps_rw) {
46
+ Error *local_err = NULL;
47
+ if (drv->bdrv_reopen_bitmaps_rw(bs, &local_err) < 0) {
48
+ /* This is not fatal, bitmaps just left read-only, so all following
49
+ * writes will fail. User can remove read-only bitmaps to unblock
50
+ * writes.
51
+ */
52
+ error_reportf_err(local_err,
53
+ "%s: Failed to make dirty bitmaps writable: ",
54
+ bdrv_get_node_name(bs));
55
+ }
56
+ }
57
}
58
59
/*
60
diff --git a/include/block/block_int.h b/include/block/block_int.h
61
index XXXXXXX..XXXXXXX 100644
62
--- a/include/block/block_int.h
63
+++ b/include/block/block_int.h
64
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
65
uint64_t parent_perm, uint64_t parent_shared,
66
uint64_t *nperm, uint64_t *nshared);
67
68
+ /**
69
+ * Bitmaps should be marked as 'IN_USE' in the image on reopening image
70
+ * as rw. This handler should realize it. It also should unset readonly
71
+ * field of BlockDirtyBitmap's in case of success.
72
+ */
73
+ int (*bdrv_reopen_bitmaps_rw)(BlockDriverState *bs, Error **errp);
74
+
75
QLIST_ENTRY(BlockDriver) list;
76
};
77
78
--
79
1.8.3.1
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-bitmap.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++
12
block/qcow2.c | 2 ++
13
block/qcow2.h | 1 +
14
3 files changed, 64 insertions(+)
15
16
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/qcow2-bitmap.c
19
+++ b/block/qcow2-bitmap.c
20
@@ -XXX,XX +XXX,XX @@ fail:
21
22
return false;
23
}
24
+
25
+int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp)
26
+{
27
+ BDRVQcow2State *s = bs->opaque;
28
+ Qcow2BitmapList *bm_list;
29
+ Qcow2Bitmap *bm;
30
+ GSList *ro_dirty_bitmaps = NULL;
31
+ int ret = 0;
32
+
33
+ if (s->nb_bitmaps == 0) {
34
+ /* No bitmaps - nothing to do */
35
+ return 0;
36
+ }
37
+
38
+ if (!can_write(bs)) {
39
+ error_setg(errp, "Can't write to the image on reopening bitmaps rw");
40
+ return -EINVAL;
41
+ }
42
+
43
+ bm_list = bitmap_list_load(bs, s->bitmap_directory_offset,
44
+ s->bitmap_directory_size, errp);
45
+ if (bm_list == NULL) {
46
+ return -EINVAL;
47
+ }
48
+
49
+ QSIMPLEQ_FOREACH(bm, bm_list, entry) {
50
+ if (!(bm->flags & BME_FLAG_IN_USE)) {
51
+ BdrvDirtyBitmap *bitmap = bdrv_find_dirty_bitmap(bs, bm->name);
52
+ if (bitmap == NULL) {
53
+ continue;
54
+ }
55
+
56
+ if (!bdrv_dirty_bitmap_readonly(bitmap)) {
57
+ error_setg(errp, "Bitmap %s is not readonly but not marked"
58
+ "'IN_USE' in the image. Something went wrong,"
59
+ "all the bitmaps may be corrupted", bm->name);
60
+ ret = -EINVAL;
61
+ goto out;
62
+ }
63
+
64
+ bm->flags |= BME_FLAG_IN_USE;
65
+ ro_dirty_bitmaps = g_slist_append(ro_dirty_bitmaps, bitmap);
66
+ }
67
+ }
68
+
69
+ if (ro_dirty_bitmaps != NULL) {
70
+ /* in_use flags must be updated */
71
+ ret = update_ext_header_and_dir_in_place(bs, bm_list);
72
+ if (ret < 0) {
73
+ error_setg_errno(errp, -ret, "Can't update bitmap directory");
74
+ goto out;
75
+ }
76
+ g_slist_foreach(ro_dirty_bitmaps, set_readonly_helper, false);
77
+ }
78
+
79
+out:
80
+ g_slist_free(ro_dirty_bitmaps);
81
+ bitmap_list_free(bm_list);
82
+
83
+ return ret;
84
+}
85
diff --git a/block/qcow2.c b/block/qcow2.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/block/qcow2.c
88
+++ b/block/qcow2.c
89
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_qcow2 = {
90
91
.bdrv_detach_aio_context = qcow2_detach_aio_context,
92
.bdrv_attach_aio_context = qcow2_attach_aio_context,
93
+
94
+ .bdrv_reopen_bitmaps_rw = qcow2_reopen_bitmaps_rw,
95
};
96
97
static void bdrv_qcow2_init(void)
98
diff --git a/block/qcow2.h b/block/qcow2.h
99
index XXXXXXX..XXXXXXX 100644
100
--- a/block/qcow2.h
101
+++ b/block/qcow2.h
102
@@ -XXX,XX +XXX,XX @@ int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
103
void **refcount_table,
104
int64_t *refcount_table_size);
105
bool qcow2_load_autoloading_dirty_bitmaps(BlockDriverState *bs, Error **errp);
106
+int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp);
107
108
#endif
109
--
110
1.8.3.1
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
block/dirty-bitmap.c | 18 ++++++++++++++++++
12
block/qcow2-bitmap.c | 2 ++
13
include/block/dirty-bitmap.h | 2 ++
14
3 files changed, 22 insertions(+)
15
16
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/dirty-bitmap.c
19
+++ b/block/dirty-bitmap.c
20
@@ -XXX,XX +XXX,XX @@ struct BdrvDirtyBitmap {
21
Such operations must fail and both the image
22
and this bitmap must remain unchanged while
23
this flag is set. */
24
+ bool autoload; /* For persistent bitmaps: bitmap must be
25
+ autoloaded on image opening */
26
QLIST_ENTRY(BdrvDirtyBitmap) list;
27
};
28
29
@@ -XXX,XX +XXX,XX @@ void bdrv_dirty_bitmap_make_anon(BdrvDirtyBitmap *bitmap)
30
assert(!bdrv_dirty_bitmap_frozen(bitmap));
31
g_free(bitmap->name);
32
bitmap->name = NULL;
33
+ bitmap->autoload = false;
34
}
35
36
/* Called with BQL taken. */
37
@@ -XXX,XX +XXX,XX @@ BdrvDirtyBitmap *bdrv_dirty_bitmap_abdicate(BlockDriverState *bs,
38
bitmap->name = NULL;
39
successor->name = name;
40
bitmap->successor = NULL;
41
+ successor->autoload = bitmap->autoload;
42
+ bitmap->autoload = false;
43
bdrv_release_dirty_bitmap(bs, bitmap);
44
45
return successor;
46
@@ -XXX,XX +XXX,XX @@ bool bdrv_has_readonly_bitmaps(BlockDriverState *bs)
47
48
return false;
49
}
50
+
51
+/* Called with BQL taken. */
52
+void bdrv_dirty_bitmap_set_autoload(BdrvDirtyBitmap *bitmap, bool autoload)
53
+{
54
+ qemu_mutex_lock(bitmap->mutex);
55
+ bitmap->autoload = autoload;
56
+ qemu_mutex_unlock(bitmap->mutex);
57
+}
58
+
59
+bool bdrv_dirty_bitmap_get_autoload(const BdrvDirtyBitmap *bitmap)
60
+{
61
+ return bitmap->autoload;
62
+}
63
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/block/qcow2-bitmap.c
66
+++ b/block/qcow2-bitmap.c
67
@@ -XXX,XX +XXX,XX @@ bool qcow2_load_autoloading_dirty_bitmaps(BlockDriverState *bs, Error **errp)
68
if (bitmap == NULL) {
69
goto fail;
70
}
71
+
72
+ bdrv_dirty_bitmap_set_autoload(bitmap, true);
73
bm->flags |= BME_FLAG_IN_USE;
74
created_dirty_bitmaps =
75
g_slist_append(created_dirty_bitmaps, bitmap);
76
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
77
index XXXXXXX..XXXXXXX 100644
78
--- a/include/block/dirty-bitmap.h
79
+++ b/include/block/dirty-bitmap.h
80
@@ -XXX,XX +XXX,XX @@ void bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap,
81
void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap);
82
83
void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap, bool value);
84
+void bdrv_dirty_bitmap_set_autoload(BdrvDirtyBitmap *bitmap, bool autoload);
85
86
/* Functions that require manual locking. */
87
void bdrv_dirty_bitmap_lock(BdrvDirtyBitmap *bitmap);
88
@@ -XXX,XX +XXX,XX @@ int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap);
89
void bdrv_dirty_bitmap_truncate(BlockDriverState *bs);
90
bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap);
91
bool bdrv_has_readonly_bitmaps(BlockDriverState *bs);
92
+bool bdrv_dirty_bitmap_get_autoload(const BdrvDirtyBitmap *bitmap);
93
94
#endif
95
--
96
1.8.3.1
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
1.8.3.1
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
block/dirty-bitmap.c | 29 +++++++++++++++++++++++++++++
13
block/qcow2-bitmap.c | 1 +
14
include/block/dirty-bitmap.h | 4 ++++
15
3 files changed, 34 insertions(+)
16
17
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block/dirty-bitmap.c
20
+++ b/block/dirty-bitmap.c
21
@@ -XXX,XX +XXX,XX @@ struct BdrvDirtyBitmap {
22
this flag is set. */
23
bool autoload; /* For persistent bitmaps: bitmap must be
24
autoloaded on image opening */
25
+ bool persistent; /* bitmap must be saved to owner disk image */
26
QLIST_ENTRY(BdrvDirtyBitmap) list;
27
};
28
29
@@ -XXX,XX +XXX,XX @@ void bdrv_dirty_bitmap_make_anon(BdrvDirtyBitmap *bitmap)
30
assert(!bdrv_dirty_bitmap_frozen(bitmap));
31
g_free(bitmap->name);
32
bitmap->name = NULL;
33
+ bitmap->persistent = false;
34
bitmap->autoload = false;
35
}
36
37
@@ -XXX,XX +XXX,XX @@ BdrvDirtyBitmap *bdrv_dirty_bitmap_abdicate(BlockDriverState *bs,
38
bitmap->name = NULL;
39
successor->name = name;
40
bitmap->successor = NULL;
41
+ successor->persistent = bitmap->persistent;
42
+ bitmap->persistent = false;
43
successor->autoload = bitmap->autoload;
44
bitmap->autoload = false;
45
bdrv_release_dirty_bitmap(bs, bitmap);
46
@@ -XXX,XX +XXX,XX @@ bool bdrv_dirty_bitmap_get_autoload(const BdrvDirtyBitmap *bitmap)
47
{
48
return bitmap->autoload;
49
}
50
+
51
+/* Called with BQL taken. */
52
+void bdrv_dirty_bitmap_set_persistance(BdrvDirtyBitmap *bitmap, bool persistent)
53
+{
54
+ qemu_mutex_lock(bitmap->mutex);
55
+ bitmap->persistent = persistent;
56
+ qemu_mutex_unlock(bitmap->mutex);
57
+}
58
+
59
+bool bdrv_dirty_bitmap_get_persistance(BdrvDirtyBitmap *bitmap)
60
+{
61
+ return bitmap->persistent;
62
+}
63
+
64
+bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs)
65
+{
66
+ BdrvDirtyBitmap *bm;
67
+ QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
68
+ if (bm->persistent && !bm->readonly) {
69
+ return true;
70
+ }
71
+ }
72
+
73
+ return false;
74
+}
75
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/block/qcow2-bitmap.c
78
+++ b/block/qcow2-bitmap.c
79
@@ -XXX,XX +XXX,XX @@ bool qcow2_load_autoloading_dirty_bitmaps(BlockDriverState *bs, Error **errp)
80
goto fail;
81
}
82
83
+ bdrv_dirty_bitmap_set_persistance(bitmap, true);
84
bdrv_dirty_bitmap_set_autoload(bitmap, true);
85
bm->flags |= BME_FLAG_IN_USE;
86
created_dirty_bitmaps =
87
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
88
index XXXXXXX..XXXXXXX 100644
89
--- a/include/block/dirty-bitmap.h
90
+++ b/include/block/dirty-bitmap.h
91
@@ -XXX,XX +XXX,XX @@ void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap);
92
93
void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap, bool value);
94
void bdrv_dirty_bitmap_set_autoload(BdrvDirtyBitmap *bitmap, bool autoload);
95
+void bdrv_dirty_bitmap_set_persistance(BdrvDirtyBitmap *bitmap,
96
+ bool persistent);
97
98
/* Functions that require manual locking. */
99
void bdrv_dirty_bitmap_lock(BdrvDirtyBitmap *bitmap);
100
@@ -XXX,XX +XXX,XX @@ void bdrv_dirty_bitmap_truncate(BlockDriverState *bs);
101
bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap);
102
bool bdrv_has_readonly_bitmaps(BlockDriverState *bs);
103
bool bdrv_dirty_bitmap_get_autoload(const BdrvDirtyBitmap *bitmap);
104
+bool bdrv_dirty_bitmap_get_persistance(BdrvDirtyBitmap *bitmap);
105
+bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs);
106
107
#endif
108
--
109
1.8.3.1
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
block/dirty-bitmap.c | 7 +++++++
10
include/block/dirty-bitmap.h | 2 ++
11
2 files changed, 9 insertions(+)
12
13
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/block/dirty-bitmap.c
16
+++ b/block/dirty-bitmap.c
17
@@ -XXX,XX +XXX,XX @@ bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs)
18
19
return false;
20
}
21
+
22
+BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs,
23
+ BdrvDirtyBitmap *bitmap)
24
+{
25
+ return bitmap == NULL ? QLIST_FIRST(&bs->dirty_bitmaps) :
26
+ QLIST_NEXT(bitmap, list);
27
+}
28
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/include/block/dirty-bitmap.h
31
+++ b/include/block/dirty-bitmap.h
32
@@ -XXX,XX +XXX,XX @@ 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
+BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs,
37
+ BdrvDirtyBitmap *bitmap);
38
39
#endif
40
--
41
1.8.3.1
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
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
---
10
block/qcow2-bitmap.c | 475 +++++++++++++++++++++++++++++++++++++++++++++++++++
11
block/qcow2.c | 9 +
12
block/qcow2.h | 1 +
13
3 files changed, 485 insertions(+)
14
15
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/block/qcow2-bitmap.c
18
+++ b/block/qcow2-bitmap.c
19
@@ -XXX,XX +XXX,XX @@
20
21
#include "qemu/osdep.h"
22
#include "qapi/error.h"
23
+#include "qemu/cutils.h"
24
25
#include "block/block_int.h"
26
#include "block/qcow2.h"
27
@@ -XXX,XX +XXX,XX @@
28
#define BME_MIN_GRANULARITY_BITS 9
29
#define BME_MAX_NAME_SIZE 1023
30
31
+#if BME_MAX_TABLE_SIZE * 8ULL > INT_MAX
32
+#error In the code bitmap table physical size assumed to fit into int
33
+#endif
34
+
35
/* Bitmap directory entry flags */
36
#define BME_RESERVED_FLAGS 0xfffffffcU
37
#define BME_FLAG_IN_USE (1U << 0)
38
@@ -XXX,XX +XXX,XX @@ typedef struct Qcow2BitmapTable {
39
uint32_t size; /* number of 64bit entries */
40
QSIMPLEQ_ENTRY(Qcow2BitmapTable) entry;
41
} Qcow2BitmapTable;
42
+typedef QSIMPLEQ_HEAD(Qcow2BitmapTableList, Qcow2BitmapTable)
43
+ Qcow2BitmapTableList;
44
45
typedef struct Qcow2Bitmap {
46
Qcow2BitmapTable table;
47
@@ -XXX,XX +XXX,XX @@ typedef struct Qcow2Bitmap {
48
uint8_t granularity_bits;
49
char *name;
50
51
+ BdrvDirtyBitmap *dirty_bitmap;
52
+
53
QSIMPLEQ_ENTRY(Qcow2Bitmap) entry;
54
} Qcow2Bitmap;
55
typedef QSIMPLEQ_HEAD(Qcow2BitmapList, Qcow2Bitmap) Qcow2BitmapList;
56
@@ -XXX,XX +XXX,XX @@ static int update_header_sync(BlockDriverState *bs)
57
return bdrv_flush(bs);
58
}
59
60
+static inline void bitmap_table_to_be(uint64_t *bitmap_table, size_t size)
61
+{
62
+ size_t i;
63
+
64
+ for (i = 0; i < size; ++i) {
65
+ cpu_to_be64s(&bitmap_table[i]);
66
+ }
67
+}
68
+
69
static int check_table_entry(uint64_t entry, int cluster_size)
70
{
71
uint64_t offset;
72
@@ -XXX,XX +XXX,XX @@ static int check_table_entry(uint64_t entry, int cluster_size)
73
return 0;
74
}
75
76
+static int check_constraints_on_bitmap(BlockDriverState *bs,
77
+ const char *name,
78
+ uint32_t granularity,
79
+ Error **errp)
80
+{
81
+ BDRVQcow2State *s = bs->opaque;
82
+ int granularity_bits = ctz32(granularity);
83
+ int64_t len = bdrv_getlength(bs);
84
+
85
+ assert(granularity > 0);
86
+ assert((granularity & (granularity - 1)) == 0);
87
+
88
+ if (len < 0) {
89
+ error_setg_errno(errp, -len, "Failed to get size of '%s'",
90
+ bdrv_get_device_or_node_name(bs));
91
+ return len;
92
+ }
93
+
94
+ if (granularity_bits > BME_MAX_GRANULARITY_BITS) {
95
+ error_setg(errp, "Granularity exceeds maximum (%llu bytes)",
96
+ 1ULL << BME_MAX_GRANULARITY_BITS);
97
+ return -EINVAL;
98
+ }
99
+ if (granularity_bits < BME_MIN_GRANULARITY_BITS) {
100
+ error_setg(errp, "Granularity is under minimum (%llu bytes)",
101
+ 1ULL << BME_MIN_GRANULARITY_BITS);
102
+ return -EINVAL;
103
+ }
104
+
105
+ if ((len > (uint64_t)BME_MAX_PHYS_SIZE << granularity_bits) ||
106
+ (len > (uint64_t)BME_MAX_TABLE_SIZE * s->cluster_size <<
107
+ granularity_bits))
108
+ {
109
+ error_setg(errp, "Too much space will be occupied by the bitmap. "
110
+ "Use larger granularity");
111
+ return -EINVAL;
112
+ }
113
+
114
+ if (strlen(name) > BME_MAX_NAME_SIZE) {
115
+ error_setg(errp, "Name length exceeds maximum (%u characters)",
116
+ BME_MAX_NAME_SIZE);
117
+ return -EINVAL;
118
+ }
119
+
120
+ return 0;
121
+}
122
+
123
+static void clear_bitmap_table(BlockDriverState *bs, uint64_t *bitmap_table,
124
+ uint32_t bitmap_table_size)
125
+{
126
+ BDRVQcow2State *s = bs->opaque;
127
+ int i;
128
+
129
+ for (i = 0; i < bitmap_table_size; ++i) {
130
+ uint64_t addr = bitmap_table[i] & BME_TABLE_ENTRY_OFFSET_MASK;
131
+ if (!addr) {
132
+ continue;
133
+ }
134
+
135
+ qcow2_free_clusters(bs, addr, s->cluster_size, QCOW2_DISCARD_OTHER);
136
+ bitmap_table[i] = 0;
137
+ }
138
+}
139
+
140
static int bitmap_table_load(BlockDriverState *bs, Qcow2BitmapTable *tb,
141
uint64_t **bitmap_table)
142
{
143
@@ -XXX,XX +XXX,XX @@ fail:
144
return ret;
145
}
146
147
+static int free_bitmap_clusters(BlockDriverState *bs, Qcow2BitmapTable *tb)
148
+{
149
+ int ret;
150
+ uint64_t *bitmap_table;
151
+
152
+ ret = bitmap_table_load(bs, tb, &bitmap_table);
153
+ if (ret < 0) {
154
+ assert(bitmap_table == NULL);
155
+ return ret;
156
+ }
157
+
158
+ clear_bitmap_table(bs, bitmap_table, tb->size);
159
+ qcow2_free_clusters(bs, tb->offset, tb->size * sizeof(uint64_t),
160
+ QCOW2_DISCARD_OTHER);
161
+ g_free(bitmap_table);
162
+
163
+ tb->offset = 0;
164
+ tb->size = 0;
165
+
166
+ return 0;
167
+}
168
+
169
/* This function returns the number of disk sectors covered by a single qcow2
170
* cluster of bitmap data. */
171
static uint64_t sectors_covered_by_bitmap_cluster(const BDRVQcow2State *s,
172
@@ -XXX,XX +XXX,XX @@ static int update_ext_header_and_dir_in_place(BlockDriverState *bs,
173
*/
174
}
175
176
+static int update_ext_header_and_dir(BlockDriverState *bs,
177
+ Qcow2BitmapList *bm_list)
178
+{
179
+ BDRVQcow2State *s = bs->opaque;
180
+ int ret;
181
+ uint64_t new_offset = 0;
182
+ uint64_t new_size = 0;
183
+ uint32_t new_nb_bitmaps = 0;
184
+ uint64_t old_offset = s->bitmap_directory_offset;
185
+ uint64_t old_size = s->bitmap_directory_size;
186
+ uint32_t old_nb_bitmaps = s->nb_bitmaps;
187
+ uint64_t old_autocl = s->autoclear_features;
188
+
189
+ if (bm_list != NULL && !QSIMPLEQ_EMPTY(bm_list)) {
190
+ new_nb_bitmaps = bitmap_list_count(bm_list);
191
+
192
+ if (new_nb_bitmaps > QCOW2_MAX_BITMAPS) {
193
+ return -EINVAL;
194
+ }
195
+
196
+ ret = bitmap_list_store(bs, bm_list, &new_offset, &new_size, false);
197
+ if (ret < 0) {
198
+ return ret;
199
+ }
200
+
201
+ ret = bdrv_flush(bs->file->bs);
202
+ if (ret < 0) {
203
+ goto fail;
204
+ }
205
+
206
+ s->autoclear_features |= QCOW2_AUTOCLEAR_BITMAPS;
207
+ } else {
208
+ s->autoclear_features &= ~(uint64_t)QCOW2_AUTOCLEAR_BITMAPS;
209
+ }
210
+
211
+ s->bitmap_directory_offset = new_offset;
212
+ s->bitmap_directory_size = new_size;
213
+ s->nb_bitmaps = new_nb_bitmaps;
214
+
215
+ ret = update_header_sync(bs);
216
+ if (ret < 0) {
217
+ goto fail;
218
+ }
219
+
220
+ if (old_size > 0) {
221
+ qcow2_free_clusters(bs, old_offset, old_size, QCOW2_DISCARD_OTHER);
222
+ }
223
+
224
+ return 0;
225
+
226
+fail:
227
+ if (new_offset > 0) {
228
+ qcow2_free_clusters(bs, new_offset, new_size, QCOW2_DISCARD_OTHER);
229
+ }
230
+
231
+ s->bitmap_directory_offset = old_offset;
232
+ s->bitmap_directory_size = old_size;
233
+ s->nb_bitmaps = old_nb_bitmaps;
234
+ s->autoclear_features = old_autocl;
235
+
236
+ return ret;
237
+}
238
+
239
/* for g_slist_foreach for GSList of BdrvDirtyBitmap* elements */
240
static void release_dirty_bitmap_helper(gpointer bitmap,
241
gpointer bs)
242
@@ -XXX,XX +XXX,XX @@ out:
243
244
return ret;
245
}
246
+
247
+/* store_bitmap_data()
248
+ * Store bitmap to image, filling bitmap table accordingly.
249
+ */
250
+static uint64_t *store_bitmap_data(BlockDriverState *bs,
251
+ BdrvDirtyBitmap *bitmap,
252
+ uint32_t *bitmap_table_size, Error **errp)
253
+{
254
+ int ret;
255
+ BDRVQcow2State *s = bs->opaque;
256
+ int64_t sector;
257
+ uint64_t sbc;
258
+ uint64_t bm_size = bdrv_dirty_bitmap_size(bitmap);
259
+ const char *bm_name = bdrv_dirty_bitmap_name(bitmap);
260
+ uint8_t *buf = NULL;
261
+ BdrvDirtyBitmapIter *dbi;
262
+ uint64_t *tb;
263
+ uint64_t tb_size =
264
+ size_to_clusters(s,
265
+ bdrv_dirty_bitmap_serialization_size(bitmap, 0, bm_size));
266
+
267
+ if (tb_size > BME_MAX_TABLE_SIZE ||
268
+ tb_size * s->cluster_size > BME_MAX_PHYS_SIZE)
269
+ {
270
+ error_setg(errp, "Bitmap '%s' is too big", bm_name);
271
+ return NULL;
272
+ }
273
+
274
+ tb = g_try_new0(uint64_t, tb_size);
275
+ if (tb == NULL) {
276
+ error_setg(errp, "No memory");
277
+ return NULL;
278
+ }
279
+
280
+ dbi = bdrv_dirty_iter_new(bitmap, 0);
281
+ buf = g_malloc(s->cluster_size);
282
+ sbc = sectors_covered_by_bitmap_cluster(s, bitmap);
283
+ assert(DIV_ROUND_UP(bm_size, sbc) == tb_size);
284
+
285
+ while ((sector = bdrv_dirty_iter_next(dbi)) != -1) {
286
+ uint64_t cluster = sector / sbc;
287
+ uint64_t end, write_size;
288
+ int64_t off;
289
+
290
+ sector = cluster * sbc;
291
+ end = MIN(bm_size, sector + sbc);
292
+ write_size =
293
+ bdrv_dirty_bitmap_serialization_size(bitmap, sector, end - sector);
294
+ assert(write_size <= s->cluster_size);
295
+
296
+ off = qcow2_alloc_clusters(bs, s->cluster_size);
297
+ if (off < 0) {
298
+ error_setg_errno(errp, -off,
299
+ "Failed to allocate clusters for bitmap '%s'",
300
+ bm_name);
301
+ goto fail;
302
+ }
303
+ tb[cluster] = off;
304
+
305
+ bdrv_dirty_bitmap_serialize_part(bitmap, buf, sector, end - sector);
306
+ if (write_size < s->cluster_size) {
307
+ memset(buf + write_size, 0, s->cluster_size - write_size);
308
+ }
309
+
310
+ ret = qcow2_pre_write_overlap_check(bs, 0, off, s->cluster_size);
311
+ if (ret < 0) {
312
+ error_setg_errno(errp, -ret, "Qcow2 overlap check failed");
313
+ goto fail;
314
+ }
315
+
316
+ ret = bdrv_pwrite(bs->file, off, buf, s->cluster_size);
317
+ if (ret < 0) {
318
+ error_setg_errno(errp, -ret, "Failed to write bitmap '%s' to file",
319
+ bm_name);
320
+ goto fail;
321
+ }
322
+
323
+ if (end >= bm_size) {
324
+ break;
325
+ }
326
+
327
+ bdrv_set_dirty_iter(dbi, end);
328
+ }
329
+
330
+ *bitmap_table_size = tb_size;
331
+ g_free(buf);
332
+ bdrv_dirty_iter_free(dbi);
333
+
334
+ return tb;
335
+
336
+fail:
337
+ clear_bitmap_table(bs, tb, tb_size);
338
+ g_free(buf);
339
+ bdrv_dirty_iter_free(dbi);
340
+ g_free(tb);
341
+
342
+ return NULL;
343
+}
344
+
345
+/* store_bitmap()
346
+ * Store bm->dirty_bitmap to qcow2.
347
+ * Set bm->table_offset and bm->table_size accordingly.
348
+ */
349
+static int store_bitmap(BlockDriverState *bs, Qcow2Bitmap *bm, Error **errp)
350
+{
351
+ int ret;
352
+ uint64_t *tb;
353
+ int64_t tb_offset;
354
+ uint32_t tb_size;
355
+ BdrvDirtyBitmap *bitmap = bm->dirty_bitmap;
356
+ const char *bm_name;
357
+
358
+ assert(bitmap != NULL);
359
+
360
+ bm_name = bdrv_dirty_bitmap_name(bitmap);
361
+
362
+ tb = store_bitmap_data(bs, bitmap, &tb_size, errp);
363
+ if (tb == NULL) {
364
+ return -EINVAL;
365
+ }
366
+
367
+ assert(tb_size <= BME_MAX_TABLE_SIZE);
368
+ tb_offset = qcow2_alloc_clusters(bs, tb_size * sizeof(tb[0]));
369
+ if (tb_offset < 0) {
370
+ error_setg_errno(errp, -tb_offset,
371
+ "Failed to allocate clusters for bitmap '%s'",
372
+ bm_name);
373
+ goto fail;
374
+ }
375
+
376
+ ret = qcow2_pre_write_overlap_check(bs, 0, tb_offset,
377
+ tb_size * sizeof(tb[0]));
378
+ if (ret < 0) {
379
+ error_setg_errno(errp, -ret, "Qcow2 overlap check failed");
380
+ goto fail;
381
+ }
382
+
383
+ bitmap_table_to_be(tb, tb_size);
384
+ ret = bdrv_pwrite(bs->file, tb_offset, tb, tb_size * sizeof(tb[0]));
385
+ if (ret < 0) {
386
+ error_setg_errno(errp, -ret, "Failed to write bitmap '%s' to file",
387
+ bm_name);
388
+ goto fail;
389
+ }
390
+
391
+ g_free(tb);
392
+
393
+ bm->table.offset = tb_offset;
394
+ bm->table.size = tb_size;
395
+
396
+ return 0;
397
+
398
+fail:
399
+ clear_bitmap_table(bs, tb, tb_size);
400
+
401
+ if (tb_offset > 0) {
402
+ qcow2_free_clusters(bs, tb_offset, tb_size * sizeof(tb[0]),
403
+ QCOW2_DISCARD_OTHER);
404
+ }
405
+
406
+ g_free(tb);
407
+
408
+ return ret;
409
+}
410
+
411
+static Qcow2Bitmap *find_bitmap_by_name(Qcow2BitmapList *bm_list,
412
+ const char *name)
413
+{
414
+ Qcow2Bitmap *bm;
415
+
416
+ QSIMPLEQ_FOREACH(bm, bm_list, entry) {
417
+ if (strcmp(name, bm->name) == 0) {
418
+ return bm;
419
+ }
420
+ }
421
+
422
+ return NULL;
423
+}
424
+
425
+void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp)
426
+{
427
+ BdrvDirtyBitmap *bitmap;
428
+ BDRVQcow2State *s = bs->opaque;
429
+ uint32_t new_nb_bitmaps = s->nb_bitmaps;
430
+ uint64_t new_dir_size = s->bitmap_directory_size;
431
+ int ret;
432
+ Qcow2BitmapList *bm_list;
433
+ Qcow2Bitmap *bm;
434
+ Qcow2BitmapTableList drop_tables;
435
+ Qcow2BitmapTable *tb, *tb_next;
436
+
437
+ if (!bdrv_has_changed_persistent_bitmaps(bs)) {
438
+ /* nothing to do */
439
+ return;
440
+ }
441
+
442
+ if (!can_write(bs)) {
443
+ error_setg(errp, "No write access");
444
+ return;
445
+ }
446
+
447
+ QSIMPLEQ_INIT(&drop_tables);
448
+
449
+ if (s->nb_bitmaps == 0) {
450
+ bm_list = bitmap_list_new();
451
+ } else {
452
+ bm_list = bitmap_list_load(bs, s->bitmap_directory_offset,
453
+ s->bitmap_directory_size, errp);
454
+ if (bm_list == NULL) {
455
+ return;
456
+ }
457
+ }
458
+
459
+ /* check constraints and names */
460
+ for (bitmap = bdrv_dirty_bitmap_next(bs, NULL); bitmap != NULL;
461
+ bitmap = bdrv_dirty_bitmap_next(bs, bitmap))
462
+ {
463
+ const char *name = bdrv_dirty_bitmap_name(bitmap);
464
+ uint32_t granularity = bdrv_dirty_bitmap_granularity(bitmap);
465
+ Qcow2Bitmap *bm;
466
+
467
+ if (!bdrv_dirty_bitmap_get_persistance(bitmap) ||
468
+ bdrv_dirty_bitmap_readonly(bitmap))
469
+ {
470
+ continue;
471
+ }
472
+
473
+ if (check_constraints_on_bitmap(bs, name, granularity, errp) < 0) {
474
+ error_prepend(errp, "Bitmap '%s' doesn't satisfy the constraints: ",
475
+ name);
476
+ goto fail;
477
+ }
478
+
479
+ bm = find_bitmap_by_name(bm_list, name);
480
+ if (bm == NULL) {
481
+ if (++new_nb_bitmaps > QCOW2_MAX_BITMAPS) {
482
+ error_setg(errp, "Too many persistent bitmaps");
483
+ goto fail;
484
+ }
485
+
486
+ new_dir_size += calc_dir_entry_size(strlen(name), 0);
487
+ if (new_dir_size > QCOW2_MAX_BITMAP_DIRECTORY_SIZE) {
488
+ error_setg(errp, "Bitmap directory is too large");
489
+ goto fail;
490
+ }
491
+
492
+ bm = g_new0(Qcow2Bitmap, 1);
493
+ bm->name = g_strdup(name);
494
+ QSIMPLEQ_INSERT_TAIL(bm_list, bm, entry);
495
+ } else {
496
+ if (!(bm->flags & BME_FLAG_IN_USE)) {
497
+ error_setg(errp, "Bitmap '%s' already exists in the image",
498
+ name);
499
+ goto fail;
500
+ }
501
+ tb = g_memdup(&bm->table, sizeof(bm->table));
502
+ bm->table.offset = 0;
503
+ bm->table.size = 0;
504
+ QSIMPLEQ_INSERT_TAIL(&drop_tables, tb, entry);
505
+ }
506
+ bm->flags = bdrv_dirty_bitmap_get_autoload(bitmap) ? BME_FLAG_AUTO : 0;
507
+ bm->granularity_bits = ctz32(bdrv_dirty_bitmap_granularity(bitmap));
508
+ bm->dirty_bitmap = bitmap;
509
+ }
510
+
511
+ /* allocate clusters and store bitmaps */
512
+ QSIMPLEQ_FOREACH(bm, bm_list, entry) {
513
+ if (bm->dirty_bitmap == NULL) {
514
+ continue;
515
+ }
516
+
517
+ ret = store_bitmap(bs, bm, errp);
518
+ if (ret < 0) {
519
+ goto fail;
520
+ }
521
+ }
522
+
523
+ ret = update_ext_header_and_dir(bs, bm_list);
524
+ if (ret < 0) {
525
+ error_setg_errno(errp, -ret, "Failed to update bitmap extension");
526
+ goto fail;
527
+ }
528
+
529
+ /* Bitmap directory was successfully updated, so, old data can be dropped.
530
+ * TODO it is better to reuse these clusters */
531
+ QSIMPLEQ_FOREACH_SAFE(tb, &drop_tables, entry, tb_next) {
532
+ free_bitmap_clusters(bs, tb);
533
+ g_free(tb);
534
+ }
535
+
536
+ bitmap_list_free(bm_list);
537
+ return;
538
+
539
+fail:
540
+ QSIMPLEQ_FOREACH(bm, bm_list, entry) {
541
+ if (bm->dirty_bitmap == NULL || bm->table.offset == 0) {
542
+ continue;
543
+ }
544
+
545
+ free_bitmap_clusters(bs, &bm->table);
546
+ }
547
+
548
+ QSIMPLEQ_FOREACH_SAFE(tb, &drop_tables, entry, tb_next) {
549
+ g_free(tb);
550
+ }
551
+
552
+ bitmap_list_free(bm_list);
553
+}
554
diff --git a/block/qcow2.c b/block/qcow2.c
555
index XXXXXXX..XXXXXXX 100644
556
--- a/block/qcow2.c
557
+++ b/block/qcow2.c
558
@@ -XXX,XX +XXX,XX @@ static int qcow2_inactivate(BlockDriverState *bs)
559
{
560
BDRVQcow2State *s = bs->opaque;
561
int ret, result = 0;
562
+ Error *local_err = NULL;
563
564
ret = qcow2_cache_flush(bs, s->l2_table_cache);
565
if (ret) {
566
@@ -XXX,XX +XXX,XX @@ static int qcow2_inactivate(BlockDriverState *bs)
567
strerror(-ret));
568
}
569
570
+ qcow2_store_persistent_dirty_bitmaps(bs, &local_err);
571
+ if (local_err != NULL) {
572
+ result = -EINVAL;
573
+ error_report_err(local_err);
574
+ error_report("Persistent bitmaps are lost for node '%s'",
575
+ bdrv_get_device_or_node_name(bs));
576
+ }
577
+
578
if (result == 0) {
579
qcow2_mark_clean(bs);
580
}
581
diff --git a/block/qcow2.h b/block/qcow2.h
582
index XXXXXXX..XXXXXXX 100644
583
--- a/block/qcow2.h
584
+++ b/block/qcow2.h
585
@@ -XXX,XX +XXX,XX @@ int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
586
int64_t *refcount_table_size);
587
bool qcow2_load_autoloading_dirty_bitmaps(BlockDriverState *bs, Error **errp);
588
int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp);
589
+void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp);
590
591
#endif
592
--
593
1.8.3.1
594
595
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-bitmap.c | 22 ++++++++++++++++++++++
11
block/qcow2.c | 5 +++++
12
block/qcow2.h | 1 +
13
3 files changed, 28 insertions(+)
14
15
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/block/qcow2-bitmap.c
18
+++ b/block/qcow2-bitmap.c
19
@@ -XXX,XX +XXX,XX @@ fail:
20
21
bitmap_list_free(bm_list);
22
}
23
+
24
+int qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp)
25
+{
26
+ BdrvDirtyBitmap *bitmap;
27
+ Error *local_err = NULL;
28
+
29
+ qcow2_store_persistent_dirty_bitmaps(bs, &local_err);
30
+ if (local_err != NULL) {
31
+ error_propagate(errp, local_err);
32
+ return -EINVAL;
33
+ }
34
+
35
+ for (bitmap = bdrv_dirty_bitmap_next(bs, NULL); bitmap != NULL;
36
+ bitmap = bdrv_dirty_bitmap_next(bs, bitmap))
37
+ {
38
+ if (bdrv_dirty_bitmap_get_persistance(bitmap)) {
39
+ bdrv_dirty_bitmap_set_readonly(bitmap, true);
40
+ }
41
+ }
42
+
43
+ return 0;
44
+}
45
diff --git a/block/qcow2.c b/block/qcow2.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/block/qcow2.c
48
+++ b/block/qcow2.c
49
@@ -XXX,XX +XXX,XX @@ static int qcow2_reopen_prepare(BDRVReopenState *state,
50
51
/* We need to write out any unwritten data if we reopen read-only. */
52
if ((state->flags & BDRV_O_RDWR) == 0) {
53
+ ret = qcow2_reopen_bitmaps_ro(state->bs, errp);
54
+ if (ret < 0) {
55
+ goto fail;
56
+ }
57
+
58
ret = bdrv_flush(state->bs);
59
if (ret < 0) {
60
goto fail;
61
diff --git a/block/qcow2.h b/block/qcow2.h
62
index XXXXXXX..XXXXXXX 100644
63
--- a/block/qcow2.h
64
+++ b/block/qcow2.h
65
@@ -XXX,XX +XXX,XX @@ int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
66
bool qcow2_load_autoloading_dirty_bitmaps(BlockDriverState *bs, Error **errp);
67
int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp);
68
void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp);
69
+int qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp);
70
71
#endif
72
--
73
1.8.3.1
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
block.c | 22 ++++++++++++++++++++++
14
include/block/block.h | 3 +++
15
include/block/block_int.h | 4 ++++
16
3 files changed, 29 insertions(+)
17
18
diff --git a/block.c b/block.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/block.c
21
+++ b/block.c
22
@@ -XXX,XX +XXX,XX @@ void bdrv_del_child(BlockDriverState *parent_bs, BdrvChild *child, Error **errp)
23
24
parent_bs->drv->bdrv_del_child(parent_bs, child, errp);
25
}
26
+
27
+bool bdrv_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
28
+ uint32_t granularity, Error **errp)
29
+{
30
+ BlockDriver *drv = bs->drv;
31
+
32
+ if (!drv) {
33
+ error_setg_errno(errp, ENOMEDIUM,
34
+ "Can't store persistent bitmaps to %s",
35
+ bdrv_get_device_or_node_name(bs));
36
+ return false;
37
+ }
38
+
39
+ if (!drv->bdrv_can_store_new_dirty_bitmap) {
40
+ error_setg_errno(errp, ENOTSUP,
41
+ "Can't store persistent bitmaps to %s",
42
+ bdrv_get_device_or_node_name(bs));
43
+ return false;
44
+ }
45
+
46
+ return drv->bdrv_can_store_new_dirty_bitmap(bs, name, granularity, errp);
47
+}
48
diff --git a/include/block/block.h b/include/block/block.h
49
index XXXXXXX..XXXXXXX 100644
50
--- a/include/block/block.h
51
+++ b/include/block/block.h
52
@@ -XXX,XX +XXX,XX @@ void bdrv_add_child(BlockDriverState *parent, BlockDriverState *child,
53
Error **errp);
54
void bdrv_del_child(BlockDriverState *parent, BdrvChild *child, Error **errp);
55
56
+bool bdrv_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
57
+ uint32_t granularity, Error **errp);
58
+
59
#endif
60
diff --git a/include/block/block_int.h b/include/block/block_int.h
61
index XXXXXXX..XXXXXXX 100644
62
--- a/include/block/block_int.h
63
+++ b/include/block/block_int.h
64
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
65
* field of BlockDirtyBitmap's in case of success.
66
*/
67
int (*bdrv_reopen_bitmaps_rw)(BlockDriverState *bs, Error **errp);
68
+ bool (*bdrv_can_store_new_dirty_bitmap)(BlockDriverState *bs,
69
+ const char *name,
70
+ uint32_t granularity,
71
+ Error **errp);
72
73
QLIST_ENTRY(BlockDriver) list;
74
};
75
--
76
1.8.3.1
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-bitmap.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
12
block/qcow2.c | 1 +
13
block/qcow2.h | 4 ++++
14
3 files changed, 56 insertions(+)
15
16
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/qcow2-bitmap.c
19
+++ b/block/qcow2-bitmap.c
20
@@ -XXX,XX +XXX,XX @@ int qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp)
21
22
return 0;
23
}
24
+
25
+bool qcow2_can_store_new_dirty_bitmap(BlockDriverState *bs,
26
+ const char *name,
27
+ uint32_t granularity,
28
+ Error **errp)
29
+{
30
+ BDRVQcow2State *s = bs->opaque;
31
+ bool found;
32
+ Qcow2BitmapList *bm_list;
33
+
34
+ if (check_constraints_on_bitmap(bs, name, granularity, errp) != 0) {
35
+ goto fail;
36
+ }
37
+
38
+ if (s->nb_bitmaps == 0) {
39
+ return true;
40
+ }
41
+
42
+ if (s->nb_bitmaps >= QCOW2_MAX_BITMAPS) {
43
+ error_setg(errp,
44
+ "Maximum number of persistent bitmaps is already reached");
45
+ goto fail;
46
+ }
47
+
48
+ if (s->bitmap_directory_size + calc_dir_entry_size(strlen(name), 0) >
49
+ QCOW2_MAX_BITMAP_DIRECTORY_SIZE)
50
+ {
51
+ error_setg(errp, "Not enough space in the bitmap directory");
52
+ goto fail;
53
+ }
54
+
55
+ bm_list = bitmap_list_load(bs, s->bitmap_directory_offset,
56
+ s->bitmap_directory_size, errp);
57
+ if (bm_list == NULL) {
58
+ goto fail;
59
+ }
60
+
61
+ found = find_bitmap_by_name(bm_list, name);
62
+ bitmap_list_free(bm_list);
63
+ if (found) {
64
+ error_setg(errp, "Bitmap with the same name is already stored");
65
+ goto fail;
66
+ }
67
+
68
+ return true;
69
+
70
+fail:
71
+ error_prepend(errp, "Can't make bitmap '%s' persistent in '%s': ",
72
+ name, bdrv_get_device_or_node_name(bs));
73
+ return false;
74
+}
75
diff --git a/block/qcow2.c b/block/qcow2.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/block/qcow2.c
78
+++ b/block/qcow2.c
79
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_qcow2 = {
80
.bdrv_attach_aio_context = qcow2_attach_aio_context,
81
82
.bdrv_reopen_bitmaps_rw = qcow2_reopen_bitmaps_rw,
83
+ .bdrv_can_store_new_dirty_bitmap = qcow2_can_store_new_dirty_bitmap,
84
};
85
86
static void bdrv_qcow2_init(void)
87
diff --git a/block/qcow2.h b/block/qcow2.h
88
index XXXXXXX..XXXXXXX 100644
89
--- a/block/qcow2.h
90
+++ b/block/qcow2.h
91
@@ -XXX,XX +XXX,XX @@ bool qcow2_load_autoloading_dirty_bitmaps(BlockDriverState *bs, Error **errp);
92
int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp);
93
void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp);
94
int qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp);
95
+bool qcow2_can_store_new_dirty_bitmap(BlockDriverState *bs,
96
+ const char *name,
97
+ uint32_t granularity,
98
+ Error **errp);
99
100
#endif
101
--
102
1.8.3.1
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
blockdev.c | 18 +++++++++++++++++-
14
qapi/block-core.json | 8 +++++++-
15
2 files changed, 24 insertions(+), 2 deletions(-)
16
17
diff --git a/blockdev.c b/blockdev.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/blockdev.c
20
+++ b/blockdev.c
21
@@ -XXX,XX +XXX,XX @@ static void block_dirty_bitmap_add_prepare(BlkActionState *common,
22
/* AIO context taken and released within qmp_block_dirty_bitmap_add */
23
qmp_block_dirty_bitmap_add(action->node, action->name,
24
action->has_granularity, action->granularity,
25
+ action->has_persistent, action->persistent,
26
&local_err);
27
28
if (!local_err) {
29
@@ -XXX,XX +XXX,XX @@ out:
30
31
void qmp_block_dirty_bitmap_add(const char *node, const char *name,
32
bool has_granularity, uint32_t granularity,
33
+ bool has_persistent, bool persistent,
34
Error **errp)
35
{
36
BlockDriverState *bs;
37
+ BdrvDirtyBitmap *bitmap;
38
39
if (!name || name[0] == '\0') {
40
error_setg(errp, "Bitmap name cannot be empty");
41
@@ -XXX,XX +XXX,XX @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name,
42
granularity = bdrv_get_default_bitmap_granularity(bs);
43
}
44
45
- bdrv_create_dirty_bitmap(bs, granularity, name, errp);
46
+ if (!has_persistent) {
47
+ persistent = false;
48
+ }
49
+
50
+ if (persistent &&
51
+ !bdrv_can_store_new_dirty_bitmap(bs, name, granularity, errp))
52
+ {
53
+ return;
54
+ }
55
+
56
+ bitmap = bdrv_create_dirty_bitmap(bs, granularity, name, errp);
57
+ if (bitmap != NULL) {
58
+ bdrv_dirty_bitmap_set_persistance(bitmap, persistent);
59
+ }
60
}
61
62
void qmp_block_dirty_bitmap_remove(const char *node, const char *name,
63
diff --git a/qapi/block-core.json b/qapi/block-core.json
64
index XXXXXXX..XXXXXXX 100644
65
--- a/qapi/block-core.json
66
+++ b/qapi/block-core.json
67
@@ -XXX,XX +XXX,XX @@
68
# @granularity: the bitmap granularity, default is 64k for
69
# block-dirty-bitmap-add
70
#
71
+# @persistent: the bitmap is persistent, i.e. it will be saved to the
72
+# corresponding block device image file on its close. For now only
73
+# Qcow2 disks support persistent bitmaps. Default is false for
74
+# block-dirty-bitmap-add. (Since: 2.10)
75
+#
76
# Since: 2.4
77
##
78
{ 'struct': 'BlockDirtyBitmapAdd',
79
- 'data': { 'node': 'str', 'name': 'str', '*granularity': 'uint32' } }
80
+ 'data': { 'node': 'str', 'name': 'str', '*granularity': 'uint32',
81
+ '*persistent': 'bool' } }
82
83
##
84
# @block-dirty-bitmap-add:
85
--
86
1.8.3.1
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
blockdev.c | 18 ++++++++++++++++--
13
qapi/block-core.json | 6 +++++-
14
2 files changed, 21 insertions(+), 3 deletions(-)
15
16
diff --git a/blockdev.c b/blockdev.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/blockdev.c
19
+++ b/blockdev.c
20
@@ -XXX,XX +XXX,XX @@ static void block_dirty_bitmap_add_prepare(BlkActionState *common,
21
qmp_block_dirty_bitmap_add(action->node, action->name,
22
action->has_granularity, action->granularity,
23
action->has_persistent, action->persistent,
24
+ action->has_autoload, action->autoload,
25
&local_err);
26
27
if (!local_err) {
28
@@ -XXX,XX +XXX,XX @@ out:
29
void qmp_block_dirty_bitmap_add(const char *node, const char *name,
30
bool has_granularity, uint32_t granularity,
31
bool has_persistent, bool persistent,
32
+ bool has_autoload, bool autoload,
33
Error **errp)
34
{
35
BlockDriverState *bs;
36
@@ -XXX,XX +XXX,XX @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name,
37
if (!has_persistent) {
38
persistent = false;
39
}
40
+ if (!has_autoload) {
41
+ autoload = false;
42
+ }
43
+
44
+ if (has_autoload && !persistent) {
45
+ error_setg(errp, "Autoload flag must be used only for persistent "
46
+ "bitmaps");
47
+ return;
48
+ }
49
50
if (persistent &&
51
!bdrv_can_store_new_dirty_bitmap(bs, name, granularity, errp))
52
@@ -XXX,XX +XXX,XX @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name,
53
}
54
55
bitmap = bdrv_create_dirty_bitmap(bs, granularity, name, errp);
56
- if (bitmap != NULL) {
57
- bdrv_dirty_bitmap_set_persistance(bitmap, persistent);
58
+ if (bitmap == NULL) {
59
+ return;
60
}
61
+
62
+ bdrv_dirty_bitmap_set_persistance(bitmap, persistent);
63
+ bdrv_dirty_bitmap_set_autoload(bitmap, autoload);
64
}
65
66
void qmp_block_dirty_bitmap_remove(const char *node, const char *name,
67
diff --git a/qapi/block-core.json b/qapi/block-core.json
68
index XXXXXXX..XXXXXXX 100644
69
--- a/qapi/block-core.json
70
+++ b/qapi/block-core.json
71
@@ -XXX,XX +XXX,XX @@
72
# Qcow2 disks support persistent bitmaps. Default is false for
73
# block-dirty-bitmap-add. (Since: 2.10)
74
#
75
+# @autoload: the bitmap will be automatically loaded when the image it is stored
76
+# in is opened. This flag may only be specified for persistent
77
+# bitmaps. Default is false for block-dirty-bitmap-add. (Since: 2.10)
78
+#
79
# Since: 2.4
80
##
81
{ 'struct': 'BlockDirtyBitmapAdd',
82
'data': { 'node': 'str', 'name': 'str', '*granularity': 'uint32',
83
- '*persistent': 'bool' } }
84
+ '*persistent': 'bool', '*autoload': 'bool' } }
85
86
##
87
# @block-dirty-bitmap-add:
88
--
89
1.8.3.1
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
block/dirty-bitmap.c | 5 +++++
8
blockdev.c | 25 +++++++++++++++++++++++++
9
include/block/dirty-bitmap.h | 1 +
10
include/qemu/hbitmap.h | 8 ++++++++
11
qapi/block-core.json | 27 +++++++++++++++++++++++++++
12
tests/Makefile.include | 2 +-
13
util/hbitmap.c | 11 +++++++++++
14
7 files changed, 78 insertions(+), 1 deletion(-)
15
16
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/dirty-bitmap.c
19
+++ b/block/dirty-bitmap.c
20
@@ -XXX,XX +XXX,XX @@ BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs,
21
return bitmap == NULL ? QLIST_FIRST(&bs->dirty_bitmaps) :
22
QLIST_NEXT(bitmap, list);
23
}
24
+
25
+char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp)
26
+{
27
+ return hbitmap_sha256(bitmap->bitmap, errp);
28
+}
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_clear(const char *node, const char *name,
34
bdrv_clear_dirty_bitmap(bitmap, NULL);
35
}
36
37
+BlockDirtyBitmapSha256 *qmp_x_debug_block_dirty_bitmap_sha256(const char *node,
38
+ const char *name,
39
+ Error **errp)
40
+{
41
+ BdrvDirtyBitmap *bitmap;
42
+ BlockDriverState *bs;
43
+ BlockDirtyBitmapSha256 *ret = NULL;
44
+ char *sha256;
45
+
46
+ bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp);
47
+ if (!bitmap || !bs) {
48
+ return NULL;
49
+ }
50
+
51
+ sha256 = bdrv_dirty_bitmap_sha256(bitmap, errp);
52
+ if (sha256 == NULL) {
53
+ return NULL;
54
+ }
55
+
56
+ ret = g_new(BlockDirtyBitmapSha256, 1);
57
+ ret->sha256 = sha256;
58
+
59
+ return ret;
60
+}
61
+
62
void hmp_drive_del(Monitor *mon, const QDict *qdict)
63
{
64
const char *id = qdict_get_str(qdict, "id");
65
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
66
index XXXXXXX..XXXXXXX 100644
67
--- a/include/block/dirty-bitmap.h
68
+++ b/include/block/dirty-bitmap.h
69
@@ -XXX,XX +XXX,XX @@ bool bdrv_dirty_bitmap_get_persistance(BdrvDirtyBitmap *bitmap);
70
bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs);
71
BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs,
72
BdrvDirtyBitmap *bitmap);
73
+char *bdrv_dirty_bitmap_sha256(const BdrvDirtyBitmap *bitmap, Error **errp);
74
75
#endif
76
diff --git a/include/qemu/hbitmap.h b/include/qemu/hbitmap.h
77
index XXXXXXX..XXXXXXX 100644
78
--- a/include/qemu/hbitmap.h
79
+++ b/include/qemu/hbitmap.h
80
@@ -XXX,XX +XXX,XX @@ void hbitmap_deserialize_ones(HBitmap *hb, uint64_t start, uint64_t count,
81
void hbitmap_deserialize_finish(HBitmap *hb);
82
83
/**
84
+ * hbitmap_sha256:
85
+ * @bitmap: HBitmap to operate on.
86
+ *
87
+ * Returns SHA256 hash of the last level.
88
+ */
89
+char *hbitmap_sha256(const HBitmap *bitmap, Error **errp);
90
+
91
+/**
92
* hbitmap_free:
93
* @hb: HBitmap to operate on.
94
*
95
diff --git a/qapi/block-core.json b/qapi/block-core.json
96
index XXXXXXX..XXXXXXX 100644
97
--- a/qapi/block-core.json
98
+++ b/qapi/block-core.json
99
@@ -XXX,XX +XXX,XX @@
100
'data': 'BlockDirtyBitmap' }
101
102
##
103
+# @BlockDirtyBitmapSha256:
104
+#
105
+# SHA256 hash of dirty bitmap data
106
+#
107
+# @sha256: ASCII representation of SHA256 bitmap hash
108
+#
109
+# Since: 2.10
110
+##
111
+ { 'struct': 'BlockDirtyBitmapSha256',
112
+ 'data': {'sha256': 'str'} }
113
+
114
+##
115
+# @x-debug-block-dirty-bitmap-sha256:
116
+#
117
+# Get bitmap SHA256
118
+#
119
+# Returns: BlockDirtyBitmapSha256 on success
120
+# If @node is not a valid block device, DeviceNotFound
121
+# If @name is not found or if hashing has failed, GenericError with an
122
+# explanation
123
+#
124
+# Since: 2.10
125
+##
126
+ { 'command': 'x-debug-block-dirty-bitmap-sha256',
127
+ 'data': 'BlockDirtyBitmap', 'returns': 'BlockDirtyBitmapSha256' }
128
+
129
+##
130
# @blockdev-mirror:
131
#
132
# Start mirroring a block device's writes to a new destination.
133
diff --git a/tests/Makefile.include b/tests/Makefile.include
134
index XXXXXXX..XXXXXXX 100644
135
--- a/tests/Makefile.include
136
+++ b/tests/Makefile.include
137
@@ -XXX,XX +XXX,XX @@ tests/test-blockjob$(EXESUF): tests/test-blockjob.o $(test-block-obj-y) $(test-u
138
tests/test-blockjob-txn$(EXESUF): tests/test-blockjob-txn.o $(test-block-obj-y) $(test-util-obj-y)
139
tests/test-thread-pool$(EXESUF): tests/test-thread-pool.o $(test-block-obj-y)
140
tests/test-iov$(EXESUF): tests/test-iov.o $(test-util-obj-y)
141
-tests/test-hbitmap$(EXESUF): tests/test-hbitmap.o $(test-util-obj-y)
142
+tests/test-hbitmap$(EXESUF): tests/test-hbitmap.o $(test-util-obj-y) $(test-crypto-obj-y)
143
tests/test-x86-cpuid$(EXESUF): tests/test-x86-cpuid.o
144
tests/test-xbzrle$(EXESUF): tests/test-xbzrle.o migration/xbzrle.o migration/page_cache.o $(test-util-obj-y)
145
tests/test-cutils$(EXESUF): tests/test-cutils.o util/cutils.o
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
1.8.3.1
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
1.8.3.1
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
block/dirty-bitmap.c | 18 ++++++++++++++++++
12
include/block/block_int.h | 3 +++
13
include/block/dirty-bitmap.h | 3 +++
14
3 files changed, 24 insertions(+)
15
16
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/dirty-bitmap.c
19
+++ b/block/dirty-bitmap.c
20
@@ -XXX,XX +XXX,XX @@ void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap)
21
/**
22
* Release all named dirty bitmaps attached to a BDS (for use in bdrv_close()).
23
* There must not be any frozen bitmaps attached.
24
+ * This function does not remove persistent bitmaps from the storage.
25
* Called with BQL taken.
26
*/
27
void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs)
28
@@ -XXX,XX +XXX,XX @@ void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs)
29
bdrv_do_release_matching_dirty_bitmap(bs, NULL, true);
30
}
31
32
+/**
33
+ * Remove persistent dirty bitmap from the storage if it exists.
34
+ * Absence of bitmap is not an error, because we have the following scenario:
35
+ * BdrvDirtyBitmap can have .persistent = true but not yet saved and have no
36
+ * stored version. For such bitmap bdrv_remove_persistent_dirty_bitmap() should
37
+ * not fail.
38
+ * This function doesn't release corresponding BdrvDirtyBitmap.
39
+ */
40
+void bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs,
41
+ const char *name,
42
+ Error **errp)
43
+{
44
+ if (bs->drv && bs->drv->bdrv_remove_persistent_dirty_bitmap) {
45
+ bs->drv->bdrv_remove_persistent_dirty_bitmap(bs, name, errp);
46
+ }
47
+}
48
+
49
/* Called with BQL taken. */
50
void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
51
{
52
diff --git a/include/block/block_int.h b/include/block/block_int.h
53
index XXXXXXX..XXXXXXX 100644
54
--- a/include/block/block_int.h
55
+++ b/include/block/block_int.h
56
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
57
const char *name,
58
uint32_t granularity,
59
Error **errp);
60
+ void (*bdrv_remove_persistent_dirty_bitmap)(BlockDriverState *bs,
61
+ const char *name,
62
+ Error **errp);
63
64
QLIST_ENTRY(BlockDriver) list;
65
};
66
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
67
index XXXXXXX..XXXXXXX 100644
68
--- a/include/block/dirty-bitmap.h
69
+++ b/include/block/dirty-bitmap.h
70
@@ -XXX,XX +XXX,XX @@ BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs,
71
void bdrv_dirty_bitmap_make_anon(BdrvDirtyBitmap *bitmap);
72
void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap);
73
void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs);
74
+void bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs,
75
+ const char *name,
76
+ Error **errp);
77
void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap);
78
void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap);
79
BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs);
80
--
81
1.8.3.1
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-bitmap.c | 41 +++++++++++++++++++++++++++++++++++++++++
12
block/qcow2.c | 1 +
13
block/qcow2.h | 3 +++
14
3 files changed, 45 insertions(+)
15
16
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/qcow2-bitmap.c
19
+++ b/block/qcow2-bitmap.c
20
@@ -XXX,XX +XXX,XX @@ static Qcow2Bitmap *find_bitmap_by_name(Qcow2BitmapList *bm_list,
21
return NULL;
22
}
23
24
+void qcow2_remove_persistent_dirty_bitmap(BlockDriverState *bs,
25
+ const char *name,
26
+ Error **errp)
27
+{
28
+ int ret;
29
+ BDRVQcow2State *s = bs->opaque;
30
+ Qcow2Bitmap *bm;
31
+ Qcow2BitmapList *bm_list;
32
+
33
+ if (s->nb_bitmaps == 0) {
34
+ /* Absence of the bitmap is not an error: see explanation above
35
+ * bdrv_remove_persistent_dirty_bitmap() definition. */
36
+ return;
37
+ }
38
+
39
+ bm_list = bitmap_list_load(bs, s->bitmap_directory_offset,
40
+ s->bitmap_directory_size, errp);
41
+ if (bm_list == NULL) {
42
+ return;
43
+ }
44
+
45
+ bm = find_bitmap_by_name(bm_list, name);
46
+ if (bm == NULL) {
47
+ goto fail;
48
+ }
49
+
50
+ QSIMPLEQ_REMOVE(bm_list, bm, Qcow2Bitmap, entry);
51
+
52
+ ret = update_ext_header_and_dir(bs, bm_list);
53
+ if (ret < 0) {
54
+ error_setg_errno(errp, -ret, "Failed to update bitmap extension");
55
+ goto fail;
56
+ }
57
+
58
+ free_bitmap_clusters(bs, &bm->table);
59
+
60
+fail:
61
+ bitmap_free(bm);
62
+ bitmap_list_free(bm_list);
63
+}
64
+
65
void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp)
66
{
67
BdrvDirtyBitmap *bitmap;
68
diff --git a/block/qcow2.c b/block/qcow2.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/block/qcow2.c
71
+++ b/block/qcow2.c
72
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_qcow2 = {
73
74
.bdrv_reopen_bitmaps_rw = qcow2_reopen_bitmaps_rw,
75
.bdrv_can_store_new_dirty_bitmap = qcow2_can_store_new_dirty_bitmap,
76
+ .bdrv_remove_persistent_dirty_bitmap = qcow2_remove_persistent_dirty_bitmap,
77
};
78
79
static void bdrv_qcow2_init(void)
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 @@ bool qcow2_can_store_new_dirty_bitmap(BlockDriverState *bs,
85
const char *name,
86
uint32_t granularity,
87
Error **errp);
88
+void qcow2_remove_persistent_dirty_bitmap(BlockDriverState *bs,
89
+ const char *name,
90
+ Error **errp);
91
92
#endif
93
--
94
1.8.3.1
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
blockdev.c | 10 ++++++++++
12
qapi/block-core.json | 3 ++-
13
2 files changed, 12 insertions(+), 1 deletion(-)
14
15
diff --git a/blockdev.c b/blockdev.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/blockdev.c
18
+++ b/blockdev.c
19
@@ -XXX,XX +XXX,XX @@ void qmp_block_dirty_bitmap_remove(const char *node, const char *name,
20
{
21
BlockDriverState *bs;
22
BdrvDirtyBitmap *bitmap;
23
+ Error *local_err = NULL;
24
25
bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp);
26
if (!bitmap || !bs) {
27
@@ -XXX,XX +XXX,XX @@ void qmp_block_dirty_bitmap_remove(const char *node, const char *name,
28
name);
29
return;
30
}
31
+
32
+ if (bdrv_dirty_bitmap_get_persistance(bitmap)) {
33
+ bdrv_remove_persistent_dirty_bitmap(bs, name, &local_err);
34
+ if (local_err != NULL) {
35
+ error_propagate(errp, local_err);
36
+ return;
37
+ }
38
+ }
39
+
40
bdrv_dirty_bitmap_make_anon(bitmap);
41
bdrv_release_dirty_bitmap(bs, bitmap);
42
}
43
diff --git a/qapi/block-core.json b/qapi/block-core.json
44
index XXXXXXX..XXXXXXX 100644
45
--- a/qapi/block-core.json
46
+++ b/qapi/block-core.json
47
@@ -XXX,XX +XXX,XX @@
48
# @block-dirty-bitmap-remove:
49
#
50
# Stop write tracking and remove the dirty bitmap that was created
51
-# with block-dirty-bitmap-add.
52
+# with block-dirty-bitmap-add. If the bitmap is persistent, remove it from its
53
+# storage too.
54
#
55
# Returns: nothing on success
56
# If @node is not a valid block device or node, DeviceNotFound
57
--
58
1.8.3.1
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
block.c | 4 ++++
11
block/dirty-bitmap.c | 29 +++++++++++++++++++++++------
12
include/block/dirty-bitmap.h | 1 +
13
3 files changed, 28 insertions(+), 6 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 int bdrv_inactivate_recurse(BlockDriverState *bs,
20
}
21
}
22
23
+ /* At this point persistent bitmaps should be already stored by the format
24
+ * driver */
25
+ bdrv_release_persistent_dirty_bitmaps(bs);
26
+
27
return 0;
28
}
29
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 @@ void bdrv_dirty_bitmap_truncate(BlockDriverState *bs)
35
bdrv_dirty_bitmaps_unlock(bs);
36
}
37
38
+static bool bdrv_dirty_bitmap_has_name(BdrvDirtyBitmap *bitmap)
39
+{
40
+ return !!bdrv_dirty_bitmap_name(bitmap);
41
+}
42
+
43
/* Called with BQL taken. */
44
-static void bdrv_do_release_matching_dirty_bitmap(BlockDriverState *bs,
45
- BdrvDirtyBitmap *bitmap,
46
- bool only_named)
47
+static void bdrv_do_release_matching_dirty_bitmap(
48
+ BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
49
+ bool (*cond)(BdrvDirtyBitmap *bitmap))
50
{
51
BdrvDirtyBitmap *bm, *next;
52
bdrv_dirty_bitmaps_lock(bs);
53
QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) {
54
- if ((!bitmap || bm == bitmap) && (!only_named || bm->name)) {
55
+ if ((!bitmap || bm == bitmap) && (!cond || cond(bm))) {
56
assert(!bm->active_iterators);
57
assert(!bdrv_dirty_bitmap_frozen(bm));
58
assert(!bm->meta);
59
@@ -XXX,XX +XXX,XX @@ out:
60
/* Called with BQL taken. */
61
void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap)
62
{
63
- bdrv_do_release_matching_dirty_bitmap(bs, bitmap, false);
64
+ bdrv_do_release_matching_dirty_bitmap(bs, bitmap, NULL);
65
}
66
67
/**
68
@@ -XXX,XX +XXX,XX @@ void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap)
69
*/
70
void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs)
71
{
72
- bdrv_do_release_matching_dirty_bitmap(bs, NULL, true);
73
+ bdrv_do_release_matching_dirty_bitmap(bs, NULL, bdrv_dirty_bitmap_has_name);
74
+}
75
+
76
+/**
77
+ * Release all persistent dirty bitmaps attached to a BDS (for use in
78
+ * bdrv_inactivate_recurse()).
79
+ * There must not be any frozen bitmaps attached.
80
+ * This function does not remove persistent bitmaps from the storage.
81
+ */
82
+void bdrv_release_persistent_dirty_bitmaps(BlockDriverState *bs)
83
+{
84
+ bdrv_do_release_matching_dirty_bitmap(bs, NULL,
85
+ bdrv_dirty_bitmap_get_persistance);
86
}
87
88
/**
89
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
90
index XXXXXXX..XXXXXXX 100644
91
--- a/include/block/dirty-bitmap.h
92
+++ b/include/block/dirty-bitmap.h
93
@@ -XXX,XX +XXX,XX @@ BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs,
94
void bdrv_dirty_bitmap_make_anon(BdrvDirtyBitmap *bitmap);
95
void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap);
96
void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs);
97
+void bdrv_release_persistent_dirty_bitmaps(BlockDriverState *bs);
98
void bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs,
99
const char *name,
100
Error **errp);
101
--
102
1.8.3.1
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
1.8.3.1
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
1.8.3.1
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
1.8.3.1
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
1.8.3.1
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
1.8.3.1
1539
1540
diff view generated by jsdifflib
Deleted patch
1
From: Max Reitz <mreitz@redhat.com>
2
1
3
A user may specify a relative path for accessing qemu, qemu-img, etc.
4
through environment variables ($QEMU_PROG and friends) or a symlink.
5
6
If a test decides to change its working directory, relative paths will
7
cease to work, however. Work around this by making all of the paths to
8
programs that should undergo testing absolute. Besides "realpath", we
9
also have to use "type -p" to support programs in $PATH.
10
11
As a side effect, this fixes specifying these programs as symlinks for
12
out-of-tree builds: Before, you would have to create two symlinks, one
13
in the build and one in the source tree (the first one for common.config
14
to find, the second one for the iotest to use). Now it is sufficient to
15
create one in the build tree because common.config will resolve it.
16
17
Reported-by: Kevin Wolf <kwolf@redhat.com>
18
Signed-off-by: Max Reitz <mreitz@redhat.com>
19
Message-id: 20170702150510.23276-2-mreitz@redhat.com
20
Reviewed-by: Eric Blake <eblake@redhat.com>
21
Tested-by: Eric Blake <eblake@redhat.com>
22
Signed-off-by: Max Reitz <mreitz@redhat.com>
23
---
24
tests/qemu-iotests/common.config | 11 +++++++++++
25
1 file changed, 11 insertions(+)
26
27
diff --git a/tests/qemu-iotests/common.config b/tests/qemu-iotests/common.config
28
index XXXXXXX..XXXXXXX 100644
29
--- a/tests/qemu-iotests/common.config
30
+++ b/tests/qemu-iotests/common.config
31
@@ -XXX,XX +XXX,XX @@ if [ -z "$QEMU_VXHS_PROG" ]; then
32
export QEMU_VXHS_PROG="`set_prog_path qnio_server`"
33
fi
34
35
+export QEMU_PROG=$(realpath -- "$(type -p "$QEMU_PROG")")
36
+export QEMU_IMG_PROG=$(realpath -- "$(type -p "$QEMU_IMG_PROG")")
37
+export QEMU_IO_PROG=$(realpath -- "$(type -p "$QEMU_IO_PROG")")
38
+export QEMU_NBD_PROG=$(realpath -- "$(type -p "$QEMU_NBD_PROG")")
39
+
40
+# This program is not built as part of qemu but (possibly) provided by the
41
+# system, so it may not be present at all
42
+if [ -n "$QEMU_VXHS_PROG" ]; then
43
+ export QEMU_VXHS_PROG=$(realpath -- "$(type -p "$QEMU_VXHS_PROG")")
44
+fi
45
+
46
_qemu_wrapper()
47
{
48
(
49
--
50
1.8.3.1
51
52
diff view generated by jsdifflib
Deleted patch
1
From: Max Reitz <mreitz@redhat.com>
2
1
3
Reviewed-by: Eric Blake <eblake@redhat.com>
4
Signed-off-by: Max Reitz <mreitz@redhat.com>
5
Message-id: 20170702150510.23276-3-mreitz@redhat.com
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
---
8
tests/qemu-iotests/126 | 105 +++++++++++++++++++++++++++++++++++++++++++++
9
tests/qemu-iotests/126.out | 23 ++++++++++
10
tests/qemu-iotests/group | 1 +
11
3 files changed, 129 insertions(+)
12
create mode 100755 tests/qemu-iotests/126
13
create mode 100644 tests/qemu-iotests/126.out
14
15
diff --git a/tests/qemu-iotests/126 b/tests/qemu-iotests/126
16
new file mode 100755
17
index XXXXXXX..XXXXXXX
18
--- /dev/null
19
+++ b/tests/qemu-iotests/126
20
@@ -XXX,XX +XXX,XX @@
21
+#!/bin/bash
22
+#
23
+# Tests handling of colons in filenames (which may be confused with protocol
24
+# prefixes)
25
+#
26
+# Copyright (C) 2017 Red Hat, Inc.
27
+#
28
+# This program is free software; you can redistribute it and/or modify
29
+# it under the terms of the GNU General Public License as published by
30
+# the Free Software Foundation; either version 2 of the License, or
31
+# (at your option) any later version.
32
+#
33
+# This program is distributed in the hope that it will be useful,
34
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
35
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36
+# GNU General Public License for more details.
37
+#
38
+# You should have received a copy of the GNU General Public License
39
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
40
+#
41
+
42
+# creator
43
+owner=mreitz@redhat.com
44
+
45
+seq="$(basename $0)"
46
+echo "QA output created by $seq"
47
+
48
+here="$PWD"
49
+status=1    # failure is the default!
50
+
51
+# get standard environment, filters and checks
52
+. ./common.rc
53
+. ./common.filter
54
+
55
+# Needs backing file support
56
+_supported_fmt qcow qcow2 qed vmdk
57
+# This is the default protocol (and we want to test the difference between
58
+# colons which separate a protocol prefix from the rest and colons which are
59
+# just part of the filename, so we cannot test protocols which require a prefix)
60
+_supported_proto file
61
+_supported_os Linux
62
+
63
+echo
64
+echo '=== Testing plain files ==='
65
+echo
66
+
67
+# A colon after a slash is not a protocol prefix separator
68
+TEST_IMG="$TEST_DIR/a:b.$IMGFMT" _make_test_img 64M
69
+_rm_test_img "$TEST_DIR/a:b.$IMGFMT"
70
+
71
+# But if you want to be really sure, you can do this
72
+TEST_IMG="file:$TEST_DIR/a:b.$IMGFMT" _make_test_img 64M
73
+_rm_test_img "$TEST_DIR/a:b.$IMGFMT"
74
+
75
+
76
+echo
77
+echo '=== Testing relative backing filename resolution ==='
78
+echo
79
+
80
+BASE_IMG="$TEST_DIR/image:base.$IMGFMT"
81
+TOP_IMG="$TEST_DIR/image:top.$IMGFMT"
82
+
83
+TEST_IMG=$BASE_IMG _make_test_img 64M
84
+TEST_IMG=$TOP_IMG _make_test_img -b ./image:base.$IMGFMT
85
+
86
+# The default cluster size depends on the image format
87
+TEST_IMG=$TOP_IMG _img_info | grep -v 'cluster_size'
88
+
89
+_rm_test_img "$BASE_IMG"
90
+_rm_test_img "$TOP_IMG"
91
+
92
+
93
+# Do another test where we access both top and base without any slash in them
94
+echo
95
+pushd "$TEST_DIR" >/dev/null
96
+
97
+BASE_IMG="base.$IMGFMT"
98
+TOP_IMG="file:image:top.$IMGFMT"
99
+
100
+TEST_IMG=$BASE_IMG _make_test_img 64M
101
+TEST_IMG=$TOP_IMG _make_test_img -b "$BASE_IMG"
102
+
103
+TEST_IMG=$TOP_IMG _img_info | grep -v 'cluster_size'
104
+
105
+_rm_test_img "$BASE_IMG"
106
+_rm_test_img "image:top.$IMGFMT"
107
+
108
+popd >/dev/null
109
+
110
+# Note that we could also do the same test with BASE_IMG=file:image:base.$IMGFMT
111
+# -- but behavior for that case is a bit strange. Protocol-prefixed paths are
112
+# in a sense always absolute paths, so such paths will never be combined with
113
+# the path of the overlay. But since "image:base.$IMGFMT" is actually a
114
+# relative path, it will always be evaluated relative to qemu's CWD (but not
115
+# relative to the overlay!). While this is more or less intended, it is still
116
+# pretty strange and thus not something that is tested here.
117
+# (The root of the issue is the use of a relative path with a protocol prefix.
118
+# This may always give you weird results because in one sense, qemu considers
119
+# such paths absolute, whereas in another, they are still relative.)
120
+
121
+
122
+# success, all done
123
+echo '*** done'
124
+rm -f $seq.full
125
+status=0
126
diff --git a/tests/qemu-iotests/126.out b/tests/qemu-iotests/126.out
127
new file mode 100644
128
index XXXXXXX..XXXXXXX
129
--- /dev/null
130
+++ b/tests/qemu-iotests/126.out
131
@@ -XXX,XX +XXX,XX @@
132
+QA output created by 126
133
+
134
+=== Testing plain files ===
135
+
136
+Formatting 'TEST_DIR/a:b.IMGFMT', fmt=IMGFMT size=67108864
137
+Formatting 'TEST_DIR/a:b.IMGFMT', fmt=IMGFMT size=67108864
138
+
139
+=== Testing relative backing filename resolution ===
140
+
141
+Formatting 'TEST_DIR/image:base.IMGFMT', fmt=IMGFMT size=67108864
142
+Formatting 'TEST_DIR/image:top.IMGFMT', fmt=IMGFMT size=67108864 backing_file=./image:base.IMGFMT
143
+image: TEST_DIR/image:top.IMGFMT
144
+file format: IMGFMT
145
+virtual size: 64M (67108864 bytes)
146
+backing file: ./image:base.IMGFMT (actual path: TEST_DIR/./image:base.IMGFMT)
147
+
148
+Formatting 'base.IMGFMT', fmt=IMGFMT size=67108864
149
+Formatting 'file:image:top.IMGFMT', fmt=IMGFMT size=67108864 backing_file=base.IMGFMT
150
+image: ./image:top.IMGFMT
151
+file format: IMGFMT
152
+virtual size: 64M (67108864 bytes)
153
+backing file: base.IMGFMT (actual path: ./base.IMGFMT)
154
+*** done
155
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
156
index XXXXXXX..XXXXXXX 100644
157
--- a/tests/qemu-iotests/group
158
+++ b/tests/qemu-iotests/group
159
@@ -XXX,XX +XXX,XX @@
160
122 rw auto
161
123 rw auto quick
162
124 rw auto backing
163
+126 rw auto backing
164
128 rw auto quick
165
129 rw auto quick
166
130 rw auto quick
167
--
168
1.8.3.1
169
170
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
qemu-options.hx | 4 ++--
37
tests/multiboot/run_test.sh | 10 +++++-----
38
tests/qemu-iotests/051 | 7 ++++---
39
tests/qemu-iotests/068 | 2 +-
40
tests/qemu-iotests/142 | 48 ++++++++++++++++++++++-----------------------
41
tests/qemu-iotests/171 | 14 ++++++-------
42
tests/qemu-iotests/check | 18 ++++++++---------
43
tests/rocker/all | 10 +++++-----
44
tests/tcg/cris/Makefile | 8 ++++----
45
9 files changed, 61 insertions(+), 60 deletions(-)
46
47
diff --git a/qemu-options.hx b/qemu-options.hx
48
index XXXXXXX..XXXXXXX 100644
49
--- a/qemu-options.hx
50
+++ b/qemu-options.hx
51
@@ -XXX,XX +XXX,XX @@ The simplest (insecure) usage is to provide the secret inline
52
53
The simplest secure usage is to provide the secret via a file
54
55
- # echo -n "letmein" > mypasswd.txt
56
+ # printf "letmein" > mypasswd.txt
57
# $QEMU -object secret,id=sec0,file=mypasswd.txt,format=raw
58
59
For greater security, AES-256-CBC should be used. To illustrate usage,
60
@@ -XXX,XX +XXX,XX @@ telling openssl to base64 encode the result, but it could be left
61
as raw bytes if desired.
62
63
@example
64
- # SECRET=$(echo -n "letmein" |
65
+ # SECRET=$(printf "letmein" |
66
openssl enc -aes-256-cbc -a -K $KEY -iv $IV)
67
@end example
68
69
diff --git a/tests/multiboot/run_test.sh b/tests/multiboot/run_test.sh
70
index XXXXXXX..XXXXXXX 100755
71
--- a/tests/multiboot/run_test.sh
72
+++ b/tests/multiboot/run_test.sh
73
@@ -XXX,XX +XXX,XX @@ run_qemu() {
74
local kernel=$1
75
shift
76
77
- echo -e "\n\n=== Running test case: $kernel $@ ===\n" >> test.log
78
+ printf %b "\n\n=== Running test case: $kernel $@ ===\n\n" >> test.log
79
80
$QEMU \
81
-kernel $kernel \
82
@@ -XXX,XX +XXX,XX @@ for t in mmap modules; do
83
pass=1
84
85
if [ $debugexit != 1 ]; then
86
- echo -e "\e[31m ?? \e[0m $t (no debugexit used, exit code $ret)"
87
+ printf %b "\e[31m ?? \e[0m $t (no debugexit used, exit code $ret)\n"
88
pass=0
89
elif [ $ret != 0 ]; then
90
- echo -e "\e[31mFAIL\e[0m $t (exit code $ret)"
91
+ printf %b "\e[31mFAIL\e[0m $t (exit code $ret)\n"
92
pass=0
93
fi
94
95
if ! diff $t.out test.log > /dev/null 2>&1; then
96
- echo -e "\e[31mFAIL\e[0m $t (output difference)"
97
+ printf %b "\e[31mFAIL\e[0m $t (output difference)\n"
98
diff -u $t.out test.log
99
pass=0
100
fi
101
102
if [ $pass == 1 ]; then
103
- echo -e "\e[32mPASS\e[0m $t"
104
+ printf %b "\e[32mPASS\e[0m $t\n"
105
fi
106
107
done
108
diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051
109
index XXXXXXX..XXXXXXX 100755
110
--- a/tests/qemu-iotests/051
111
+++ b/tests/qemu-iotests/051
112
@@ -XXX,XX +XXX,XX @@ run_qemu -drive driver=null-co,cache=invalid_value
113
# Test 142 checks the direct=on cases
114
115
for cache in writeback writethrough unsafe invalid_value; do
116
- echo -e "info block\ninfo block file\ninfo block backing\ninfo block backing-file" | \
117
+ printf "info block %s\n" '' file backing backing-file | \
118
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
119
done
120
121
@@ -XXX,XX +XXX,XX @@ echo "qemu-io $device_id \"write -P 0x22 0 4k\"" | run_qemu -drive file="$TEST_I
122
123
$QEMU_IO -c "read -P 0x22 0 4k" "$TEST_IMG" | _filter_qemu_io
124
125
-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\
126
- | _filter_qemu_io
127
+printf %b "qemu-io $device_id \"write -P 0x33 0 4k\"\ncommit $device_id\n" |
128
+ run_qemu -drive file="$TEST_IMG",snapshot=on,if=none,id=$device_id |
129
+ _filter_qemu_io
130
131
$QEMU_IO -c "read -P 0x33 0 4k" "$TEST_IMG" | _filter_qemu_io
132
133
diff --git a/tests/qemu-iotests/068 b/tests/qemu-iotests/068
134
index XXXXXXX..XXXXXXX 100755
135
--- a/tests/qemu-iotests/068
136
+++ b/tests/qemu-iotests/068
137
@@ -XXX,XX +XXX,XX @@ for extra_args in \
138
_make_test_img $IMG_SIZE
139
140
# Give qemu some time to boot before saving the VM state
141
- bash -c 'sleep 1; echo -e "savevm 0\nquit"' | _qemu $extra_args
142
+ { sleep 1; printf "savevm 0\nquit\n"; } | _qemu $extra_args
143
# Now try to continue from that VM state (this should just work)
144
echo quit | _qemu $extra_args -loadvm 0
145
done
146
diff --git a/tests/qemu-iotests/142 b/tests/qemu-iotests/142
147
index XXXXXXX..XXXXXXX 100755
148
--- a/tests/qemu-iotests/142
149
+++ b/tests/qemu-iotests/142
150
@@ -XXX,XX +XXX,XX @@ function check_cache_all()
151
# cache.direct is supposed to be inherited by both bs->file and
152
# bs->backing
153
154
- echo -e "cache.direct=on on none0"
155
+ printf "cache.direct=on on none0\n"
156
echo "$hmp_cmds" | run_qemu -drive "$files","$ids",cache.direct=on | grep -e "Cache" -e "[Cc]annot|[Cc]ould not|[Cc]an't"
157
- echo -e "\ncache.direct=on on file"
158
+ printf "\ncache.direct=on on file\n"
159
echo "$hmp_cmds" | run_qemu -drive "$files","$ids",file.cache.direct=on | grep -e "Cache" -e "[Cc]annot|[Cc]ould not|[Cc]an't"
160
- echo -e "\ncache.direct=on on backing"
161
+ printf "\ncache.direct=on on backing\n"
162
echo "$hmp_cmds" | run_qemu -drive "$files","$ids",backing.cache.direct=on | grep -e "Cache" -e "[Cc]annot|[Cc]ould not|[Cc]an't"
163
- echo -e "\ncache.direct=on on backing-file"
164
+ printf "\ncache.direct=on on backing-file\n"
165
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"
166
167
# cache.writeback is supposed to be inherited by bs->backing; bs->file
168
# always gets cache.writeback=on
169
170
- echo -e "\n\ncache.writeback=off on none0"
171
+ printf "\n\ncache.writeback=off on none0\n"
172
echo "$hmp_cmds" | run_qemu -drive "$files","$ids",cache.writeback=off | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't"
173
- echo -e "\ncache.writeback=off on file"
174
+ printf "\ncache.writeback=off on file\n"
175
echo "$hmp_cmds" | run_qemu -drive "$files","$ids",file.cache.writeback=off | grep -e "doesn't" -e "does not"
176
- echo -e "\ncache.writeback=off on backing"
177
+ printf "\ncache.writeback=off on backing\n"
178
echo "$hmp_cmds" | run_qemu -drive "$files","$ids",backing.cache.writeback=off | grep -e "doesn't" -e "does not"
179
- echo -e "\ncache.writeback=off on backing-file"
180
+ printf "\ncache.writeback=off on backing-file\n"
181
echo "$hmp_cmds" | run_qemu -drive "$files","$ids",backing.file.cache.writeback=off | grep -e "doesn't" -e "does not"
182
183
# cache.no-flush is supposed to be inherited by both bs->file and bs->backing
184
185
- echo -e "\n\ncache.no-flush=on on none0"
186
+ printf "\n\ncache.no-flush=on on none0\n"
187
echo "$hmp_cmds" | run_qemu -drive "$files","$ids",cache.no-flush=on | grep -e "Cache" -e "[Cc]annot\|[Cc]ould not\|[Cc]an't"
188
- echo -e "\ncache.no-flush=on on file"
189
+ printf "\ncache.no-flush=on on file\n"
190
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"
191
- echo -e "\ncache.no-flush=on on backing"
192
+ printf "\ncache.no-flush=on on backing\n"
193
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"
194
- echo -e "\ncache.no-flush=on on backing-file"
195
+ printf "\ncache.no-flush=on on backing-file\n"
196
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"
197
}
198
199
@@ -XXX,XX +XXX,XX @@ function check_cache_all_separate()
200
{
201
# Check cache.direct
202
203
- echo -e "cache.direct=on on blk"
204
+ printf "cache.direct=on on blk\n"
205
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"
206
- echo -e "\ncache.direct=on on file"
207
+ printf "\ncache.direct=on on file\n"
208
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"
209
- echo -e "\ncache.direct=on on backing"
210
+ printf "\ncache.direct=on on backing\n"
211
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"
212
- echo -e "\ncache.direct=on on backing-file"
213
+ printf "\ncache.direct=on on backing-file\n"
214
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"
215
216
# Check cache.writeback
217
218
- echo -e "\n\ncache.writeback=off on blk"
219
+ printf "\n\ncache.writeback=off on blk\n"
220
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"
221
- echo -e "\ncache.writeback=off on file"
222
+ printf "\ncache.writeback=off on file\n"
223
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"
224
- echo -e "\ncache.writeback=off on backing"
225
+ printf "\ncache.writeback=off on backing\n"
226
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"
227
- echo -e "\ncache.writeback=off on backing-file"
228
+ printf "\ncache.writeback=off on backing-file\n"
229
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"
230
231
# Check cache.no-flush
232
233
- echo -e "\n\ncache.no-flush=on on blk"
234
+ printf "\n\ncache.no-flush=on on blk\n"
235
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"
236
- echo -e "\ncache.no-flush=on on file"
237
+ printf "\ncache.no-flush=on on file\n"
238
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"
239
- echo -e "\ncache.no-flush=on on backing"
240
+ printf "\ncache.no-flush=on on backing\n"
241
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"
242
- echo -e "\ncache.no-flush=on on backing-file"
243
+ printf "\ncache.no-flush=on on backing-file\n"
244
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"
245
}
246
247
diff --git a/tests/qemu-iotests/171 b/tests/qemu-iotests/171
248
index XXXXXXX..XXXXXXX 100755
249
--- a/tests/qemu-iotests/171
250
+++ b/tests/qemu-iotests/171
251
@@ -XXX,XX +XXX,XX @@ _supported_os Linux
252
253
# Create JSON with options
254
img_json() {
255
- echo -n 'json:{"driver":"raw", '
256
- echo -n "\"offset\":\"$img_offset\", "
257
+ printf %s 'json:{"driver":"raw", '
258
+ printf %s "\"offset\":\"$img_offset\", "
259
if [ "$img_size" -ne -1 ] ; then
260
- echo -n "\"size\":\"$img_size\", "
261
+ printf %s "\"size\":\"$img_size\", "
262
fi
263
- echo -n '"file": {'
264
- echo -n '"driver":"file", '
265
- echo -n "\"filename\":\"$TEST_IMG\" "
266
- echo -n "} }"
267
+ printf %s '"file": {'
268
+ printf %s '"driver":"file", '
269
+ printf %s "\"filename\":\"$TEST_IMG\" "
270
+ printf %s "} }"
271
}
272
273
do_general_test() {
274
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
275
index XXXXXXX..XXXXXXX 100755
276
--- a/tests/qemu-iotests/check
277
+++ b/tests/qemu-iotests/check
278
@@ -XXX,XX +XXX,XX @@ _wallclock()
279
_timestamp()
280
{
281
now=`date "+%T"`
282
- echo -n " [$now]"
283
+ printf %s " [$now]"
284
}
285
286
_wrapup()
287
@@ -XXX,XX +XXX,XX @@ seq="check"
288
for seq in $list
289
do
290
err=false
291
- echo -n "$seq"
292
+ printf %s "$seq"
293
if [ -n "$TESTS_REMAINING_LOG" ] ; then
294
sed -e "s/$seq//" -e 's/ / /' -e 's/^ *//' $TESTS_REMAINING_LOG > $TESTS_REMAINING_LOG.tmp
295
mv $TESTS_REMAINING_LOG.tmp $TESTS_REMAINING_LOG
296
@@ -XXX,XX +XXX,XX @@ do
297
rm -f $seq.out.bad
298
lasttime=`sed -n -e "/^$seq /s/.* //p" <$TIMESTAMP_FILE`
299
if [ "X$lasttime" != X ]; then
300
- echo -n " ${lasttime}s ..."
301
+ printf %s " ${lasttime}s ..."
302
else
303
- echo -n " " # prettier output with timestamps.
304
+ printf " " # prettier output with timestamps.
305
fi
306
rm -f core $seq.notrun
307
308
@@ -XXX,XX +XXX,XX @@ do
309
echo "$seq" > "${TEST_DIR}"/check.sts
310
311
start=`_wallclock`
312
- $timestamp && echo -n " ["`date "+%T"`"]"
313
+ $timestamp && printf %s " [$(date "+%T")]"
314
315
if [ "$(head -n 1 "$source_iotests/$seq")" == "#!/usr/bin/env python" ]; then
316
run_command="$PYTHON $seq"
317
@@ -XXX,XX +XXX,XX @@ do
318
319
if [ -f core ]
320
then
321
- echo -n " [dumped core]"
322
+ printf " [dumped core]"
323
mv core $seq.core
324
err=true
325
fi
326
327
if [ -f $seq.notrun ]
328
then
329
- $timestamp || echo -n " [not run] "
330
- $timestamp && echo " [not run]" && echo -n " $seq -- "
331
+ $timestamp || printf " [not run] "
332
+ $timestamp && echo " [not run]" && printf %s " $seq -- "
333
cat $seq.notrun
334
notrun="$notrun $seq"
335
else
336
if [ $sts -ne 0 ]
337
then
338
- echo -n " [failed, exit status $sts]"
339
+ printf %s " [failed, exit status $sts]"
340
err=true
341
fi
342
343
diff --git a/tests/rocker/all b/tests/rocker/all
344
index XXXXXXX..XXXXXXX 100755
345
--- a/tests/rocker/all
346
+++ b/tests/rocker/all
347
@@ -XXX,XX +XXX,XX @@
348
-echo -n "Running port test... "
349
+printf "Running port test... "
350
./port
351
if [ $? -eq 0 ]; then echo "pass"; else echo "FAILED"; exit 1; fi
352
353
-echo -n "Running bridge test... "
354
+printf "Running bridge test... "
355
./bridge
356
if [ $? -eq 0 ]; then echo "pass"; else echo "FAILED"; exit 1; fi
357
358
-echo -n "Running bridge STP test... "
359
+printf "Running bridge STP test... "
360
./bridge-stp
361
if [ $? -eq 0 ]; then echo "pass"; else echo "FAILED"; exit 1; fi
362
363
-echo -n "Running bridge VLAN test... "
364
+printf "Running bridge VLAN test... "
365
./bridge-vlan
366
if [ $? -eq 0 ]; then echo "pass"; else echo "FAILED"; exit 1; fi
367
368
-echo -n "Running bridge VLAN STP test... "
369
+printf "Running bridge VLAN STP test... "
370
./bridge-vlan-stp
371
if [ $? -eq 0 ]; then echo "pass"; else echo "FAILED"; exit 1; fi
372
diff --git a/tests/tcg/cris/Makefile b/tests/tcg/cris/Makefile
373
index XXXXXXX..XXXXXXX 100644
374
--- a/tests/tcg/cris/Makefile
375
+++ b/tests/tcg/cris/Makefile
376
@@ -XXX,XX +XXX,XX @@ check_addcv17.tst: crtv10.o sysv10.o
377
build: $(CRT) $(SYS) $(TESTCASES)
378
379
check: $(CRT) $(SYS) $(TESTCASES)
380
-    @echo -e "\nQEMU simulator."
381
+    @printf "\nQEMU simulator.\n"
382
    for case in $(TESTCASES); do \
383
-        echo -n "$$case "; \
384
+        printf %s "$$case "; \
385
        SIMARGS=; \
386
        case $$case in *v17*) SIMARGS="-cpu crisv17";; esac; \
387
        $(SIM) $$SIMARGS ./$$case; \
388
    done
389
check-g: $(CRT) $(SYS) $(TESTCASES)
390
-    @echo -e "\nGDB simulator."
391
+    @printf "\nGDB simulator.\n"
392
    @for case in $(TESTCASES); do \
393
-        echo -n "$$case "; \
394
+        printf %s "$$case "; \
395
        $(SIMG) $$case; \
396
    done
397
398
--
399
1.8.3.1
400
401
diff view generated by jsdifflib