1
The following changes since commit bae31bfa48b9caecee25da3d5333901a126a06b4:
1
The following changes since commit 804b30d25f8d70dc2dea951883ea92235274a50c:
2
2
3
Merge remote-tracking branch 'remotes/kraxel/tags/audio-20200619-pull-request' into staging (2020-06-19 22:56:59 +0100)
3
Merge remote-tracking branch 'remotes/legoater/tags/pull-ppc-20220130' into staging (2022-01-31 11:10:08 +0000)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://github.com/XanClic/qemu.git tags/pull-block-2020-06-22
7
https://gitlab.com/hreitz/qemu.git tags/pull-block-2022-02-01
8
8
9
for you to fetch changes up to 74c55e4142a7bb835c38d3770c74210cbb1e4fab:
9
for you to fetch changes up to 751486c18555169ca4baf59440275d5831140822:
10
10
11
iotests: don't test qcow2.py inside 291 (2020-06-22 16:05:23 +0200)
11
block.h: remove outdated comment (2022-02-01 13:28:53 +0100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block patches:
14
Block patches:
15
- Support modifying a LUKS-encrypted image's keyslots
15
- Add support to the iotests to test qcow2's zstd compression mode
16
- iotest fixes
16
- Fix post-migration block node permissions
17
- iotests fixes (051 and mirror-ready-cancel-error)
18
- Remove an outdated comment
17
19
18
----------------------------------------------------------------
20
----------------------------------------------------------------
19
Max Reitz (1):
21
Emanuele Giuseppe Esposito (1):
20
iotests: Make _filter_img_create more active
22
block.h: remove outdated comment
21
23
22
Maxim Levitsky (14):
24
Hanna Reitz (3):
23
iotests: filter few more luks specific create options
25
iotests/MRCE: Write data to source
24
qcrypto/core: add generic infrastructure for crypto options amendment
26
block-backend: Retain permissions after migration
25
qcrypto/luks: implement encryption key management
27
iotests/migration-permissions: New test
26
block/amend: add 'force' option
27
block/amend: separate amend and create options for qemu-img
28
block/amend: refactor qcow2 amend options
29
block/crypto: rename two functions
30
block/crypto: implement the encryption key management
31
block/qcow2: extend qemu-img amend interface with crypto options
32
iotests: qemu-img tests for luks key management
33
block/core: add generic infrastructure for x-blockdev-amend qmp
34
command
35
block/crypto: implement blockdev-amend
36
block/qcow2: implement blockdev-amend
37
iotests: add tests for blockdev-amend
38
28
39
Philippe Mathieu-Daudé (1):
29
Thomas Huth (1):
40
iotests: Fix 051 output after qdev_init_nofail() removal
30
tests/qemu-iotests: Fix 051 for binaries without 'lsi53c895a'
41
31
42
Vladimir Sementsov-Ogievskiy (2):
32
Vladimir Sementsov-Ogievskiy (19):
43
block/block-copy: block_copy_dirty_clusters: fix failure check
33
iotests.py: img_info_log(): rename imgopts argument
44
iotests: don't test qcow2.py inside 291
34
iotests.py: implement unsupported_imgopts
35
iotests: specify some unsupported_imgopts for python iotests
36
iotests.py: qemu_img*("create"): support
37
IMGOPTS='compression_type=zstd'
38
iotests: drop qemu_img_verbose() helper
39
iotests.py: rewrite default luks support in qemu_img
40
iotest 303: explicit compression type
41
iotest 065: explicit compression type
42
iotests.py: filter out successful output of qemu-img create
43
iotests.py: filter compression type out
44
iotest 302: use img_info_log() helper
45
qcow2: simple case support for downgrading of qcow2 images with zstd
46
iotests/common.rc: introduce _qcow2_dump_header helper
47
iotests: massive use _qcow2_dump_header
48
iotest 39: use _qcow2_dump_header
49
iotests: bash tests: filter compression type
50
iotests 60: more accurate set dirty bit in qcow2 header
51
iotest 214: explicit compression type
52
iotests: declare lack of support for compresion_type in IMGOPTS
45
53
46
docs/tools/qemu-img.rst | 5 +-
54
include/block/block.h | 1 -
47
qapi/block-core.json | 68 +++++
55
block/block-backend.c | 11 ++
48
qapi/crypto.json | 73 +++++-
56
block/qcow2.c | 58 +++++++++-
49
qapi/job.json | 4 +-
57
tests/qemu-iotests/031 | 11 +-
50
block/crypto.h | 37 +++
58
tests/qemu-iotests/036 | 6 +-
51
crypto/blockpriv.h | 8 +
59
tests/qemu-iotests/039 | 22 ++--
52
include/block/block.h | 1 +
60
tests/qemu-iotests/044 | 8 +-
53
include/block/block_int.h | 24 +-
61
tests/qemu-iotests/044.out | 1 +
54
include/crypto/block.h | 22 ++
62
tests/qemu-iotests/051 | 9 +-
55
block.c | 4 +-
63
tests/qemu-iotests/060 | 22 ++--
56
block/amend.c | 113 +++++++++
64
tests/qemu-iotests/060.out | 2 +-
57
block/block-copy.c | 4 +-
65
tests/qemu-iotests/061 | 42 ++++----
58
block/crypto.c | 206 +++++++++++++--
66
tests/qemu-iotests/061.out | 12 +--
59
block/qcow2.c | 332 +++++++++++++-----------
67
tests/qemu-iotests/065 | 19 ++--
60
crypto/block-luks.c | 416 ++++++++++++++++++++++++++++++-
68
tests/qemu-iotests/082.out | 14 +--
61
crypto/block.c | 29 +++
69
tests/qemu-iotests/112 | 3 +-
62
qemu-img.c | 44 +++-
70
tests/qemu-iotests/137 | 2 +-
63
block/Makefile.objs | 2 +-
71
tests/qemu-iotests/149.out | 21 ----
64
qemu-img-cmds.hx | 4 +-
72
tests/qemu-iotests/163 | 3 +-
65
tests/qemu-iotests/049.out | 102 ++++----
73
tests/qemu-iotests/165 | 3 +-
66
tests/qemu-iotests/051.pc.out | 4 +-
74
tests/qemu-iotests/196 | 3 +-
67
tests/qemu-iotests/061.out | 12 +-
75
tests/qemu-iotests/198.out | 4 +-
68
tests/qemu-iotests/082.out | 185 ++++----------
76
tests/qemu-iotests/206.out | 10 +-
69
tests/qemu-iotests/085.out | 38 +--
77
tests/qemu-iotests/209 | 7 +-
70
tests/qemu-iotests/087.out | 6 +-
78
tests/qemu-iotests/209.out | 2 +
71
tests/qemu-iotests/112.out | 2 +-
79
tests/qemu-iotests/210 | 8 +-
72
tests/qemu-iotests/134.out | 2 +-
80
tests/qemu-iotests/214 | 2 +-
73
tests/qemu-iotests/141 | 2 +-
81
tests/qemu-iotests/237.out | 3 -
74
tests/qemu-iotests/144.out | 4 +-
82
tests/qemu-iotests/242 | 3 +-
75
tests/qemu-iotests/153 | 9 +-
83
tests/qemu-iotests/242.out | 10 +-
76
tests/qemu-iotests/158.out | 4 +-
84
tests/qemu-iotests/246 | 3 +-
77
tests/qemu-iotests/182.out | 2 +-
85
tests/qemu-iotests/254 | 3 +-
78
tests/qemu-iotests/185.out | 8 +-
86
tests/qemu-iotests/255.out | 4 -
79
tests/qemu-iotests/188.out | 2 +-
87
tests/qemu-iotests/260 | 3 +-
80
tests/qemu-iotests/189.out | 4 +-
88
tests/qemu-iotests/274 | 3 +-
81
tests/qemu-iotests/198.out | 4 +-
89
tests/qemu-iotests/274.out | 39 +------
82
tests/qemu-iotests/255.out | 8 +-
90
tests/qemu-iotests/280.out | 1 -
83
tests/qemu-iotests/263.out | 4 +-
91
tests/qemu-iotests/281 | 3 +-
84
tests/qemu-iotests/274.out | 46 ++--
92
tests/qemu-iotests/287 | 8 +-
85
tests/qemu-iotests/280.out | 2 +-
93
tests/qemu-iotests/290 | 2 +-
86
tests/qemu-iotests/284.out | 6 +-
94
tests/qemu-iotests/296.out | 10 +-
87
tests/qemu-iotests/291 | 4 -
95
tests/qemu-iotests/302 | 4 +-
88
tests/qemu-iotests/291.out | 33 ---
96
tests/qemu-iotests/302.out | 7 +-
89
tests/qemu-iotests/293 | 207 +++++++++++++++
97
tests/qemu-iotests/303 | 26 +++--
90
tests/qemu-iotests/293.out | 99 ++++++++
98
tests/qemu-iotests/303.out | 30 +++++-
91
tests/qemu-iotests/294 | 90 +++++++
99
tests/qemu-iotests/common.filter | 8 ++
92
tests/qemu-iotests/294.out | 30 +++
100
tests/qemu-iotests/common.rc | 22 ++++
93
tests/qemu-iotests/295 | 279 +++++++++++++++++++++
101
tests/qemu-iotests/iotests.py | 99 +++++++++++------
94
tests/qemu-iotests/295.out | 40 +++
102
.../tests/migrate-bitmaps-postcopy-test | 3 +-
95
tests/qemu-iotests/296 | 234 +++++++++++++++++
103
tests/qemu-iotests/tests/migrate-bitmaps-test | 3 +-
96
tests/qemu-iotests/296.out | 33 +++
104
.../qemu-iotests/tests/migration-permissions | 101 ++++++++++++++++++
97
tests/qemu-iotests/common.filter | 93 +++++--
105
.../tests/migration-permissions.out | 5 +
98
tests/qemu-iotests/group | 4 +
106
.../tests/mirror-ready-cancel-error | 7 +-
99
53 files changed, 2482 insertions(+), 516 deletions(-)
107
.../tests/remove-bitmap-from-backing | 3 +-
100
create mode 100644 block/amend.c
108
54 files changed, 483 insertions(+), 236 deletions(-)
101
create mode 100755 tests/qemu-iotests/293
109
create mode 100755 tests/qemu-iotests/tests/migration-permissions
102
create mode 100644 tests/qemu-iotests/293.out
110
create mode 100644 tests/qemu-iotests/tests/migration-permissions.out
103
create mode 100755 tests/qemu-iotests/294
104
create mode 100644 tests/qemu-iotests/294.out
105
create mode 100755 tests/qemu-iotests/295
106
create mode 100644 tests/qemu-iotests/295.out
107
create mode 100755 tests/qemu-iotests/296
108
create mode 100644 tests/qemu-iotests/296.out
109
111
110
--
112
--
111
2.26.2
113
2.34.1
112
114
113
115
diff view generated by jsdifflib
New patch
1
From: Thomas Huth <thuth@redhat.com>
1
2
3
The lsi53c895a SCSI adaptor might not be enabled in each and every
4
x86 QEMU binary, e.g. it's disabled in the RHEL/CentOS build.
5
Thus let's add a check to the 051 test so that it does not fail if
6
this device is not available.
7
8
Signed-off-by: Thomas Huth <thuth@redhat.com>
9
Message-Id: <20211206143404.247032-1-thuth@redhat.com>
10
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
11
---
12
tests/qemu-iotests/051 | 4 ++++
13
1 file changed, 4 insertions(+)
14
15
diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051
16
index XXXXXXX..XXXXXXX 100755
17
--- a/tests/qemu-iotests/051
18
+++ b/tests/qemu-iotests/051
19
@@ -XXX,XX +XXX,XX @@ _supported_proto file
20
_unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)' data_file
21
_require_drivers nbd
22
23
+if [ "$QEMU_DEFAULT_MACHINE" = "pc" ]; then
24
+ _require_devices lsi53c895a
25
+fi
26
+
27
do_run_qemu()
28
{
29
echo Testing: "$@"
30
--
31
2.34.1
32
33
diff view generated by jsdifflib
New patch
1
This test assumes that mirror flushes the source when entering the READY
2
state, and that the format level will pass that flush on to the protocol
3
level (where we intercept it with blkdebug).
1
4
5
However, apparently that does not happen when using a VMDK image with
6
zeroed_grain=on, which actually is the default set by testenv.py. Right
7
now, Python tests ignore IMGOPTS, though, so this has no effect; but
8
Vladimir has a series that will change this, so we need to fix this test
9
before that series lands.
10
11
We can fix it by writing data to the source before we start the mirror
12
job; apparently that makes the (VMDK) format layer change its mind and
13
pass on the pre-READY flush to the protocol level, so the test passes
14
again. (I presume, without any data written, mirror just does a 64M
15
zero write on the target, which VMDK with zeroed_grain=on basically just
16
ignores.)
17
18
Without this, we do not get a flush, and so blkdebug only sees a single
19
flush at the end of the job instead of two, and therefore does not
20
inject an error, which makes the block job complete instead of raising
21
an error.
22
23
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
24
Message-Id: <20211223165308.103793-1-hreitz@redhat.com>
25
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
26
---
27
tests/qemu-iotests/tests/mirror-ready-cancel-error | 7 ++++++-
28
1 file changed, 6 insertions(+), 1 deletion(-)
29
30
diff --git a/tests/qemu-iotests/tests/mirror-ready-cancel-error b/tests/qemu-iotests/tests/mirror-ready-cancel-error
31
index XXXXXXX..XXXXXXX 100755
32
--- a/tests/qemu-iotests/tests/mirror-ready-cancel-error
33
+++ b/tests/qemu-iotests/tests/mirror-ready-cancel-error
34
@@ -XXX,XX +XXX,XX @@ class TestMirrorReadyCancelError(iotests.QMPTestCase):
35
assert iotests.qemu_img_create('-f', iotests.imgfmt, target,
36
str(image_size)) == 0
37
38
+ # Ensure that mirror will copy something before READY so the
39
+ # target format layer will forward the pre-READY flush to its
40
+ # file child
41
+ assert iotests.qemu_io_silent('-c', 'write -P 1 0 64k', source) == 0
42
+
43
self.vm = iotests.VM()
44
self.vm.launch()
45
46
@@ -XXX,XX +XXX,XX @@ class TestMirrorReadyCancelError(iotests.QMPTestCase):
47
# Write something so will not leave the job immediately, but
48
# flush first (which will fail, thanks to blkdebug)
49
res = self.vm.qmp('human-monitor-command',
50
- command_line='qemu-io mirror-top "write 0 64k"')
51
+ command_line='qemu-io mirror-top "write -P 2 0 64k"')
52
self.assert_qmp(res, 'return', '')
53
54
# Drain status change events
55
--
56
2.34.1
57
58
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
3
We are going to support IMGOPTS environment variable like in bash
4
tests. Corresponding global variable in iotests.py should be called
5
imgopts. So to not interfere with function argument, rename it in
6
advance.
7
8
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
Reviewed-by: Max Reitz <mreitz@redhat.com>
10
Message-Id: <20211223160144.1097696-2-vsementsov@virtuozzo.com>
11
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
12
---
13
tests/qemu-iotests/210 | 8 ++++----
14
tests/qemu-iotests/iotests.py | 5 +++--
15
2 files changed, 7 insertions(+), 6 deletions(-)
16
17
diff --git a/tests/qemu-iotests/210 b/tests/qemu-iotests/210
18
index XXXXXXX..XXXXXXX 100755
19
--- a/tests/qemu-iotests/210
20
+++ b/tests/qemu-iotests/210
21
@@ -XXX,XX +XXX,XX @@ with iotests.FilePath('t.luks') as disk_path, \
22
'driver=luks,file.driver=file,file.filename=%s,key-secret=keysec0' % (disk_path),
23
filter_path=disk_path,
24
extra_args=['--object', 'secret,id=keysec0,data=foo'],
25
- imgopts=True)
26
+ use_image_opts=True)
27
28
#
29
# Successful image creation (with non-default options)
30
@@ -XXX,XX +XXX,XX @@ with iotests.FilePath('t.luks') as disk_path, \
31
'driver=luks,file.driver=file,file.filename=%s,key-secret=keysec0' % (disk_path),
32
filter_path=disk_path,
33
extra_args=['--object', 'secret,id=keysec0,data=foo'],
34
- imgopts=True)
35
+ use_image_opts=True)
36
37
#
38
# Invalid BlockdevRef
39
@@ -XXX,XX +XXX,XX @@ with iotests.FilePath('t.luks') as disk_path, \
40
'driver=luks,file.driver=file,file.filename=%s,key-secret=keysec0' % (disk_path),
41
filter_path=disk_path,
42
extra_args=['--object', 'secret,id=keysec0,data=foo'],
43
- imgopts=True)
44
+ use_image_opts=True)
45
46
#
47
# Invalid sizes
48
@@ -XXX,XX +XXX,XX @@ with iotests.FilePath('t.luks') as disk_path, \
49
'driver=luks,file.driver=file,file.filename=%s,key-secret=keysec0' % (disk_path),
50
filter_path=disk_path,
51
extra_args=['--object', 'secret,id=keysec0,data=foo'],
52
- imgopts=True)
53
+ use_image_opts=True)
54
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
55
index XXXXXXX..XXXXXXX 100644
56
--- a/tests/qemu-iotests/iotests.py
57
+++ b/tests/qemu-iotests/iotests.py
58
@@ -XXX,XX +XXX,XX @@ def qemu_img_log(*args):
59
log(result, filters=[filter_testfiles])
60
return result
61
62
-def img_info_log(filename, filter_path=None, imgopts=False, extra_args=()):
63
+def img_info_log(filename, filter_path=None, use_image_opts=False,
64
+ extra_args=()):
65
args = ['info']
66
- if imgopts:
67
+ if use_image_opts:
68
args.append('--image-opts')
69
else:
70
args += ['-f', imgfmt]
71
--
72
2.34.1
73
74
diff view generated by jsdifflib
1
From: Maxim Levitsky <mlevitsk@redhat.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
This implements the encryption key management using the generic code in
3
We are going to support some addition IMGOPTS in python iotests like
4
qcrypto layer and exposes it to the user via qemu-img
4
in bash iotests. Similarly to bash iotests, we want a way to skip some
5
tests which can't work with specific IMGOPTS.
5
6
6
This code adds another 'write_func' because the initialization
7
Globally for python iotests we will not support things like
7
write_func works directly on the underlying file, and amend
8
'data_file=$TEST_IMG.ext_data_file' in IMGOPTS, so, forbid this
8
works on instance of luks device.
9
globally in iotests.py.
9
10
10
This commit also adds a 'hack/workaround' I and Kevin Wolf (thanks)
11
Suggested-by: Hanna Reitz <hreitz@redhat.com>
11
made to make the driver both support write sharing (to avoid breaking the users),
12
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
12
and be safe against concurrent metadata update (the keyslots)
13
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
14
Message-Id: <20211223160144.1097696-3-vsementsov@virtuozzo.com>
15
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
16
---
17
tests/qemu-iotests/iotests.py | 15 ++++++++++++++-
18
1 file changed, 14 insertions(+), 1 deletion(-)
13
19
14
Eventually the write sharing for luks driver will be deprecated
20
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
15
and removed together with this hack.
16
17
The hack is that we ask (as a format driver) for BLK_PERM_CONSISTENT_READ
18
and then when we want to update the keys, we unshare that permission.
19
So if someone else has the image open, even readonly, encryption
20
key update will fail gracefully.
21
22
Also thanks to Daniel Berrange for the idea of
23
unsharing read, rather that write permission which allows
24
to avoid cases when the other user had opened the image read-only.
25
26
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
27
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
28
Reviewed-by: Max Reitz <mreitz@redhat.com>
29
Message-Id: <20200608094030.670121-8-mlevitsk@redhat.com>
30
Signed-off-by: Max Reitz <mreitz@redhat.com>
31
---
32
block/crypto.h | 34 +++++++++++++
33
block/crypto.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++--
34
2 files changed, 161 insertions(+), 3 deletions(-)
35
36
diff --git a/block/crypto.h b/block/crypto.h
37
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
38
--- a/block/crypto.h
22
--- a/tests/qemu-iotests/iotests.py
39
+++ b/block/crypto.h
23
+++ b/tests/qemu-iotests/iotests.py
40
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@ def _verify_virtio_scsi_pci_or_ccw() -> None:
41
#define BLOCK_CRYPTO_OPT_LUKS_IVGEN_HASH_ALG "ivgen-hash-alg"
25
notrun('Missing virtio-scsi-pci or virtio-scsi-ccw in QEMU binary')
42
#define BLOCK_CRYPTO_OPT_LUKS_HASH_ALG "hash-alg"
26
43
#define BLOCK_CRYPTO_OPT_LUKS_ITER_TIME "iter-time"
27
44
+#define BLOCK_CRYPTO_OPT_LUKS_KEYSLOT "keyslot"
28
+def _verify_imgopts(unsupported: Sequence[str] = ()) -> None:
45
+#define BLOCK_CRYPTO_OPT_LUKS_STATE "state"
29
+ imgopts = os.environ.get('IMGOPTS')
46
+#define BLOCK_CRYPTO_OPT_LUKS_OLD_SECRET "old-secret"
30
+ # One of usage examples for IMGOPTS is "data_file=$TEST_IMG.ext_data_file"
47
+#define BLOCK_CRYPTO_OPT_LUKS_NEW_SECRET "new-secret"
31
+ # but it supported only for bash tests. We don't have a concept of global
48
+
32
+ # TEST_IMG in iotests.py, not saying about somehow parsing $variables.
49
33
+ # So, for simplicity let's just not support any IMGOPTS with '$' inside.
50
#define BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(prefix) \
34
+ unsup = list(unsupported) + ['$']
51
BLOCK_CRYPTO_OPT_DEF_KEY_SECRET(prefix, \
35
+ if imgopts and any(x in imgopts for x in unsup):
52
@@ -XXX,XX +XXX,XX @@
36
+ notrun(f'not suitable for this imgopts: {imgopts}')
53
.help = "Time to spend in PBKDF in milliseconds", \
54
}
55
56
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_STATE(prefix) \
57
+ { \
58
+ .name = prefix BLOCK_CRYPTO_OPT_LUKS_STATE, \
59
+ .type = QEMU_OPT_STRING, \
60
+ .help = "Select new state of affected keyslots (active/inactive)",\
61
+ }
62
+
63
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_KEYSLOT(prefix) \
64
+ { \
65
+ .name = prefix BLOCK_CRYPTO_OPT_LUKS_KEYSLOT, \
66
+ .type = QEMU_OPT_NUMBER, \
67
+ .help = "Select a single keyslot to modify explicitly",\
68
+ }
69
+
70
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_OLD_SECRET(prefix) \
71
+ { \
72
+ .name = prefix BLOCK_CRYPTO_OPT_LUKS_OLD_SECRET, \
73
+ .type = QEMU_OPT_STRING, \
74
+ .help = "Select all keyslots that match this password", \
75
+ }
76
+
77
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_NEW_SECRET(prefix) \
78
+ { \
79
+ .name = prefix BLOCK_CRYPTO_OPT_LUKS_NEW_SECRET, \
80
+ .type = QEMU_OPT_STRING, \
81
+ .help = "New secret to set in the matching keyslots. " \
82
+ "Empty string to erase", \
83
+ }
84
+
85
QCryptoBlockCreateOptions *
86
block_crypto_create_opts_init(QDict *opts, Error **errp);
87
88
diff --git a/block/crypto.c b/block/crypto.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/block/crypto.c
91
+++ b/block/crypto.c
92
@@ -XXX,XX +XXX,XX @@ typedef struct BlockCrypto BlockCrypto;
93
94
struct BlockCrypto {
95
QCryptoBlock *block;
96
+ bool updating_keys;
97
};
98
99
100
@@ -XXX,XX +XXX,XX @@ static ssize_t block_crypto_read_func(QCryptoBlock *block,
101
return ret;
102
}
103
104
+static ssize_t block_crypto_write_func(QCryptoBlock *block,
105
+ size_t offset,
106
+ const uint8_t *buf,
107
+ size_t buflen,
108
+ void *opaque,
109
+ Error **errp)
110
+{
111
+ BlockDriverState *bs = opaque;
112
+ ssize_t ret;
113
+
114
+ ret = bdrv_pwrite(bs->file, offset, buf, buflen);
115
+ if (ret < 0) {
116
+ error_setg_errno(errp, -ret, "Could not write encryption header");
117
+ return ret;
118
+ }
119
+ return ret;
120
+}
121
+
122
123
struct BlockCryptoCreateData {
124
BlockBackend *blk;
125
@@ -XXX,XX +XXX,XX @@ static QemuOptsList block_crypto_create_opts_luks = {
126
};
127
128
129
+static QemuOptsList block_crypto_amend_opts_luks = {
130
+ .name = "crypto",
131
+ .head = QTAILQ_HEAD_INITIALIZER(block_crypto_create_opts_luks.head),
132
+ .desc = {
133
+ BLOCK_CRYPTO_OPT_DEF_LUKS_STATE(""),
134
+ BLOCK_CRYPTO_OPT_DEF_LUKS_KEYSLOT(""),
135
+ BLOCK_CRYPTO_OPT_DEF_LUKS_OLD_SECRET(""),
136
+ BLOCK_CRYPTO_OPT_DEF_LUKS_NEW_SECRET(""),
137
+ BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME(""),
138
+ { /* end of list */ }
139
+ },
140
+};
141
+
142
QCryptoBlockOpenOptions *
143
block_crypto_open_opts_init(QDict *opts, Error **errp)
144
{
145
@@ -XXX,XX +XXX,XX @@ block_crypto_get_specific_info_luks(BlockDriverState *bs, Error **errp)
146
return spec_info;
147
}
148
149
+static int
150
+block_crypto_amend_options_luks(BlockDriverState *bs,
151
+ QemuOpts *opts,
152
+ BlockDriverAmendStatusCB *status_cb,
153
+ void *cb_opaque,
154
+ bool force,
155
+ Error **errp)
156
+{
157
+ BlockCrypto *crypto = bs->opaque;
158
+ QDict *cryptoopts = NULL;
159
+ QCryptoBlockAmendOptions *amend_options = NULL;
160
+ int ret;
161
+
162
+ assert(crypto);
163
+ assert(crypto->block);
164
+ crypto->updating_keys = true;
165
+
166
+ ret = bdrv_child_refresh_perms(bs, bs->file, errp);
167
+ if (ret < 0) {
168
+ goto cleanup;
169
+ }
170
+
171
+ cryptoopts = qemu_opts_to_qdict(opts, NULL);
172
+ qdict_put_str(cryptoopts, "format", "luks");
173
+ amend_options = block_crypto_amend_opts_init(cryptoopts, errp);
174
+ if (!amend_options) {
175
+ ret = -EINVAL;
176
+ goto cleanup;
177
+ }
178
+
179
+ ret = qcrypto_block_amend_options(crypto->block,
180
+ block_crypto_read_func,
181
+ block_crypto_write_func,
182
+ bs,
183
+ amend_options,
184
+ force,
185
+ errp);
186
+cleanup:
187
+ crypto->updating_keys = false;
188
+ bdrv_child_refresh_perms(bs, bs->file, errp);
189
+ qapi_free_QCryptoBlockAmendOptions(amend_options);
190
+ qobject_unref(cryptoopts);
191
+ return ret;
192
+}
193
+
37
+
194
+
38
+
195
+static void
39
def supports_quorum():
196
+block_crypto_child_perms(BlockDriverState *bs, BdrvChild *c,
40
return 'quorum' in qemu_img_pipe('--help')
197
+ const BdrvChildRole role,
41
198
+ BlockReopenQueue *reopen_queue,
42
@@ -XXX,XX +XXX,XX @@ def execute_setup_common(supported_fmts: Sequence[str] = (),
199
+ uint64_t perm, uint64_t shared,
43
unsupported_fmts: Sequence[str] = (),
200
+ uint64_t *nperm, uint64_t *nshared)
44
supported_protocols: Sequence[str] = (),
201
+{
45
unsupported_protocols: Sequence[str] = (),
202
+
46
- required_fmts: Sequence[str] = ()) -> bool:
203
+ BlockCrypto *crypto = bs->opaque;
47
+ required_fmts: Sequence[str] = (),
204
+
48
+ unsupported_imgopts: Sequence[str] = ()) -> bool:
205
+ bdrv_default_perms(bs, c, role, reopen_queue, perm, shared, nperm, nshared);
49
"""
206
+
50
Perform necessary setup for either script-style or unittest-style tests.
207
+ /*
51
208
+ * For backward compatibility, manually share the write
52
@@ -XXX,XX +XXX,XX @@ def execute_setup_common(supported_fmts: Sequence[str] = (),
209
+ * and resize permission
53
_verify_aio_mode(supported_aio_modes)
210
+ */
54
_verify_formats(required_fmts)
211
+ *nshared |= (BLK_PERM_WRITE | BLK_PERM_RESIZE);
55
_verify_virtio_blk()
212
+ /*
56
+ _verify_imgopts(unsupported_imgopts)
213
+ * Since we are not fully a format driver, don't always request
57
214
+ * the read/resize permission but only when explicitly
58
return debug
215
+ * requested
216
+ */
217
+ *nperm &= ~(BLK_PERM_WRITE | BLK_PERM_RESIZE);
218
+ *nperm |= perm & (BLK_PERM_WRITE | BLK_PERM_RESIZE);
219
+
220
+ /*
221
+ * This driver doesn't modify LUKS metadata except
222
+ * when updating the encryption slots.
223
+ * Thus unlike a proper format driver we don't ask for
224
+ * shared write/read permission. However we need it
225
+ * when we are updating the keys, to ensure that only we
226
+ * have access to the device.
227
+ *
228
+ * Encryption update will set the crypto->updating_keys
229
+ * during that period and refresh permissions
230
+ *
231
+ */
232
+ if (crypto->updating_keys) {
233
+ /* need exclusive write access for header update */
234
+ *nperm |= BLK_PERM_WRITE;
235
+ /* unshare read and write permission */
236
+ *nshared &= ~(BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE);
237
+ }
238
+}
239
+
240
+
241
static const char *const block_crypto_strong_runtime_opts[] = {
242
BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET,
243
244
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_crypto_luks = {
245
.bdrv_probe = block_crypto_probe_luks,
246
.bdrv_open = block_crypto_open_luks,
247
.bdrv_close = block_crypto_close,
248
- /* This driver doesn't modify LUKS metadata except when creating image.
249
- * Allow share-rw=on as a special case. */
250
- .bdrv_child_perm = bdrv_default_perms,
251
+ .bdrv_child_perm = block_crypto_child_perms,
252
.bdrv_co_create = block_crypto_co_create_luks,
253
.bdrv_co_create_opts = block_crypto_co_create_opts_luks,
254
.bdrv_co_truncate = block_crypto_co_truncate,
255
.create_opts = &block_crypto_create_opts_luks,
256
+ .amend_opts = &block_crypto_amend_opts_luks,
257
258
.bdrv_reopen_prepare = block_crypto_reopen_prepare,
259
.bdrv_refresh_limits = block_crypto_refresh_limits,
260
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_crypto_luks = {
261
.bdrv_measure = block_crypto_measure,
262
.bdrv_get_info = block_crypto_get_info_luks,
263
.bdrv_get_specific_info = block_crypto_get_specific_info_luks,
264
+ .bdrv_amend_options = block_crypto_amend_options_luks,
265
266
.is_format = true,
267
59
268
--
60
--
269
2.26.2
61
2.34.1
270
62
271
63
diff view generated by jsdifflib
New patch
1
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
3
We are going to support IMGOPTS for python iotests. Still some iotests
4
will not work with common IMGOPTS used with bash iotests like
5
specifying refcount_bits and compat qcow2 options. So we
6
should define corresponding unsupported_imgopts for now.
7
8
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
Message-Id: <20211223160144.1097696-4-vsementsov@virtuozzo.com>
10
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
11
---
12
tests/qemu-iotests/044 | 3 ++-
13
tests/qemu-iotests/065 | 3 ++-
14
tests/qemu-iotests/163 | 3 ++-
15
tests/qemu-iotests/165 | 3 ++-
16
tests/qemu-iotests/196 | 3 ++-
17
tests/qemu-iotests/242 | 3 ++-
18
tests/qemu-iotests/246 | 3 ++-
19
tests/qemu-iotests/254 | 3 ++-
20
tests/qemu-iotests/260 | 3 ++-
21
tests/qemu-iotests/274 | 3 ++-
22
tests/qemu-iotests/281 | 3 ++-
23
tests/qemu-iotests/303 | 3 ++-
24
tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test | 3 ++-
25
tests/qemu-iotests/tests/migrate-bitmaps-test | 3 ++-
26
tests/qemu-iotests/tests/remove-bitmap-from-backing | 3 ++-
27
15 files changed, 30 insertions(+), 15 deletions(-)
28
29
diff --git a/tests/qemu-iotests/044 b/tests/qemu-iotests/044
30
index XXXXXXX..XXXXXXX 100755
31
--- a/tests/qemu-iotests/044
32
+++ b/tests/qemu-iotests/044
33
@@ -XXX,XX +XXX,XX @@ class TestRefcountTableGrowth(iotests.QMPTestCase):
34
35
if __name__ == '__main__':
36
iotests.main(supported_fmts=['qcow2'],
37
- supported_protocols=['file'])
38
+ supported_protocols=['file'],
39
+ unsupported_imgopts=['refcount_bits'])
40
diff --git a/tests/qemu-iotests/065 b/tests/qemu-iotests/065
41
index XXXXXXX..XXXXXXX 100755
42
--- a/tests/qemu-iotests/065
43
+++ b/tests/qemu-iotests/065
44
@@ -XXX,XX +XXX,XX @@ TestQMP = None
45
46
if __name__ == '__main__':
47
iotests.main(supported_fmts=['qcow2'],
48
- supported_protocols=['file'])
49
+ supported_protocols=['file'],
50
+ unsupported_imgopts=['refcount_bits'])
51
diff --git a/tests/qemu-iotests/163 b/tests/qemu-iotests/163
52
index XXXXXXX..XXXXXXX 100755
53
--- a/tests/qemu-iotests/163
54
+++ b/tests/qemu-iotests/163
55
@@ -XXX,XX +XXX,XX @@ ShrinkBaseClass = None
56
57
if __name__ == '__main__':
58
iotests.main(supported_fmts=['raw', 'qcow2'],
59
- supported_protocols=['file'])
60
+ supported_protocols=['file'],
61
+ unsupported_imgopts=['compat'])
62
diff --git a/tests/qemu-iotests/165 b/tests/qemu-iotests/165
63
index XXXXXXX..XXXXXXX 100755
64
--- a/tests/qemu-iotests/165
65
+++ b/tests/qemu-iotests/165
66
@@ -XXX,XX +XXX,XX @@ class TestPersistentDirtyBitmap(iotests.QMPTestCase):
67
68
if __name__ == '__main__':
69
iotests.main(supported_fmts=['qcow2'],
70
- supported_protocols=['file'])
71
+ supported_protocols=['file'],
72
+ unsupported_imgopts=['compat'])
73
diff --git a/tests/qemu-iotests/196 b/tests/qemu-iotests/196
74
index XXXXXXX..XXXXXXX 100755
75
--- a/tests/qemu-iotests/196
76
+++ b/tests/qemu-iotests/196
77
@@ -XXX,XX +XXX,XX @@ class TestInvalidateAutoclear(iotests.QMPTestCase):
78
79
if __name__ == '__main__':
80
iotests.main(supported_fmts=['qcow2'],
81
- supported_protocols=['file'])
82
+ supported_protocols=['file'],
83
+ unsupported_imgopts=['compat'])
84
diff --git a/tests/qemu-iotests/242 b/tests/qemu-iotests/242
85
index XXXXXXX..XXXXXXX 100755
86
--- a/tests/qemu-iotests/242
87
+++ b/tests/qemu-iotests/242
88
@@ -XXX,XX +XXX,XX @@ from iotests import qemu_img_create, qemu_io, qemu_img_pipe, \
89
file_path, img_info_log, log, filter_qemu_io
90
91
iotests.script_initialize(supported_fmts=['qcow2'],
92
- supported_protocols=['file'])
93
+ supported_protocols=['file'],
94
+ unsupported_imgopts=['refcount_bits', 'compat'])
95
96
disk = file_path('disk')
97
chunk = 256 * 1024
98
diff --git a/tests/qemu-iotests/246 b/tests/qemu-iotests/246
99
index XXXXXXX..XXXXXXX 100755
100
--- a/tests/qemu-iotests/246
101
+++ b/tests/qemu-iotests/246
102
@@ -XXX,XX +XXX,XX @@
103
import iotests
104
from iotests import log
105
106
-iotests.script_initialize(supported_fmts=['qcow2'])
107
+iotests.script_initialize(supported_fmts=['qcow2'],
108
+ unsupported_imgopts=['compat'])
109
size = 64 * 1024 * 1024 * 1024
110
gran_small = 32 * 1024
111
gran_large = 128 * 1024
112
diff --git a/tests/qemu-iotests/254 b/tests/qemu-iotests/254
113
index XXXXXXX..XXXXXXX 100755
114
--- a/tests/qemu-iotests/254
115
+++ b/tests/qemu-iotests/254
116
@@ -XXX,XX +XXX,XX @@
117
import iotests
118
from iotests import qemu_img_create, file_path, log
119
120
-iotests.script_initialize(supported_fmts=['qcow2'])
121
+iotests.script_initialize(supported_fmts=['qcow2'],
122
+ unsupported_imgopts=['compat'])
123
124
disk, top = file_path('disk', 'top')
125
size = 1024 * 1024
126
diff --git a/tests/qemu-iotests/260 b/tests/qemu-iotests/260
127
index XXXXXXX..XXXXXXX 100755
128
--- a/tests/qemu-iotests/260
129
+++ b/tests/qemu-iotests/260
130
@@ -XXX,XX +XXX,XX @@ import iotests
131
from iotests import qemu_img_create, file_path, log, filter_qmp_event
132
133
iotests.script_initialize(
134
- supported_fmts=['qcow2']
135
+ supported_fmts=['qcow2'],
136
+ unsupported_imgopts=['compat']
137
)
138
139
base, top = file_path('base', 'top')
140
diff --git a/tests/qemu-iotests/274 b/tests/qemu-iotests/274
141
index XXXXXXX..XXXXXXX 100755
142
--- a/tests/qemu-iotests/274
143
+++ b/tests/qemu-iotests/274
144
@@ -XXX,XX +XXX,XX @@
145
import iotests
146
147
iotests.script_initialize(supported_fmts=['qcow2'],
148
- supported_platforms=['linux'])
149
+ supported_platforms=['linux'],
150
+ unsupported_imgopts=['refcount_bits', 'compat'])
151
152
size_short = 1 * 1024 * 1024
153
size_long = 2 * 1024 * 1024
154
diff --git a/tests/qemu-iotests/281 b/tests/qemu-iotests/281
155
index XXXXXXX..XXXXXXX 100755
156
--- a/tests/qemu-iotests/281
157
+++ b/tests/qemu-iotests/281
158
@@ -XXX,XX +XXX,XX @@ class TestBlockdevBackupAbort(iotests.QMPTestCase):
159
160
if __name__ == '__main__':
161
iotests.main(supported_fmts=['qcow2'],
162
- supported_protocols=['file'])
163
+ supported_protocols=['file'],
164
+ unsupported_imgopts=['compat'])
165
diff --git a/tests/qemu-iotests/303 b/tests/qemu-iotests/303
166
index XXXXXXX..XXXXXXX 100755
167
--- a/tests/qemu-iotests/303
168
+++ b/tests/qemu-iotests/303
169
@@ -XXX,XX +XXX,XX @@ import iotests
170
import subprocess
171
from iotests import qemu_img_create, qemu_io, file_path, log, filter_qemu_io
172
173
-iotests.script_initialize(supported_fmts=['qcow2'])
174
+iotests.script_initialize(supported_fmts=['qcow2'],
175
+ unsupported_imgopts=['refcount_bits', 'compat'])
176
177
disk = file_path('disk')
178
chunk = 1024 * 1024
179
diff --git a/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test b/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test
180
index XXXXXXX..XXXXXXX 100755
181
--- a/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test
182
+++ b/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test
183
@@ -XXX,XX +XXX,XX @@ class TestDirtyBitmapPostcopyMigration(iotests.QMPTestCase):
184
185
186
if __name__ == '__main__':
187
- iotests.main(supported_fmts=['qcow2'])
188
+ iotests.main(supported_fmts=['qcow2'],
189
+ unsupported_imgopts=['compat'])
190
diff --git a/tests/qemu-iotests/tests/migrate-bitmaps-test b/tests/qemu-iotests/tests/migrate-bitmaps-test
191
index XXXXXXX..XXXXXXX 100755
192
--- a/tests/qemu-iotests/tests/migrate-bitmaps-test
193
+++ b/tests/qemu-iotests/tests/migrate-bitmaps-test
194
@@ -XXX,XX +XXX,XX @@ def main() -> None:
195
196
iotests.main(
197
supported_fmts=['qcow2'],
198
- supported_protocols=['file']
199
+ supported_protocols=['file'],
200
+ unsupported_imgopts=['compat']
201
)
202
203
204
diff --git a/tests/qemu-iotests/tests/remove-bitmap-from-backing b/tests/qemu-iotests/tests/remove-bitmap-from-backing
205
index XXXXXXX..XXXXXXX 100755
206
--- a/tests/qemu-iotests/tests/remove-bitmap-from-backing
207
+++ b/tests/qemu-iotests/tests/remove-bitmap-from-backing
208
@@ -XXX,XX +XXX,XX @@
209
import iotests
210
from iotests import log, qemu_img_create, qemu_img, qemu_img_pipe
211
212
-iotests.script_initialize(supported_fmts=['qcow2'])
213
+iotests.script_initialize(supported_fmts=['qcow2'],
214
+ unsupported_imgopts=['compat'])
215
216
top, base = iotests.file_path('top', 'base')
217
size = '1M'
218
--
219
2.34.1
220
221
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
3
Adding support of IMGOPTS (like in bash tests) allows user to pass a
4
lot of different options. Still, some may require additional logic.
5
6
Now we want compression_type option, so add some smart logic around it:
7
ignore compression_type=zstd in IMGOPTS, if test want qcow2 in
8
compatibility mode. As well, ignore compression_type for non-qcow2
9
formats.
10
11
Note that we may instead add support only to qemu_img_create(), but
12
that works bad:
13
14
1. We'll have to update a lot of tests to use qemu_img_create instead
15
of qemu_img('create'). (still, we may want do it anyway, but no
16
reason to create a dependancy between task of supporting IMGOPTS and
17
updating a lot of tests)
18
19
2. Some tests use qemu_img_pipe('create', ..) - even more work on
20
updating
21
22
3. Even if we update all tests to go through qemu_img_create, we'll
23
need a way to avoid creating new tests using qemu_img*('create') -
24
add assertions.. That doesn't seem good.
25
26
So, let's add support of IMGOPTS to most generic
27
qemu_img_pipe_and_status().
28
29
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
30
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
31
Message-Id: <20211223160144.1097696-5-vsementsov@virtuozzo.com>
32
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
33
---
34
tests/qemu-iotests/iotests.py | 27 ++++++++++++++++++++++++++-
35
1 file changed, 26 insertions(+), 1 deletion(-)
36
37
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
38
index XXXXXXX..XXXXXXX 100644
39
--- a/tests/qemu-iotests/iotests.py
40
+++ b/tests/qemu-iotests/iotests.py
41
@@ -XXX,XX +XXX,XX @@
42
# along with this program. If not, see <http://www.gnu.org/licenses/>.
43
#
44
45
+import argparse
46
import atexit
47
import bz2
48
from collections import OrderedDict
49
@@ -XXX,XX +XXX,XX @@ def qemu_tool_pipe_and_status(tool: str, args: Sequence[str],
50
{-subp.returncode}: {cmd}\n')
51
return (output, subp.returncode)
52
53
+def qemu_img_create_prepare_args(args: List[str]) -> List[str]:
54
+ if not args or args[0] != 'create':
55
+ return list(args)
56
+ args = args[1:]
57
+
58
+ p = argparse.ArgumentParser(allow_abbrev=False)
59
+ p.add_argument('-f')
60
+ parsed, remaining = p.parse_known_args(args)
61
+
62
+ result = ['create']
63
+ if parsed.f is not None:
64
+ result += ['-f', parsed.f]
65
+
66
+ # IMGOPTS most probably contain options specific for the selected format,
67
+ # like extended_l2 or compression_type for qcow2. Test may want to create
68
+ # additional images in other formats that doesn't support these options.
69
+ # So, use IMGOPTS only for images created in imgfmt format.
70
+ if parsed.f == imgfmt and 'IMGOPTS' in os.environ:
71
+ result += ['-o', os.environ['IMGOPTS']]
72
+
73
+ result += remaining
74
+
75
+ return result
76
+
77
def qemu_img_pipe_and_status(*args: str) -> Tuple[str, int]:
78
"""
79
Run qemu-img and return both its output and its exit code
80
"""
81
- full_args = qemu_img_args + list(args)
82
+ full_args = qemu_img_args + qemu_img_create_prepare_args(list(args))
83
return qemu_tool_pipe_and_status('qemu-img', full_args)
84
85
def qemu_img(*args: str) -> int:
86
--
87
2.34.1
88
89
diff view generated by jsdifflib
1
From: Maxim Levitsky <mlevitsk@redhat.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
blockdev-amend will be used similiar to blockdev-create
3
qemu_img_verbose() has a drawback of not going through generic
4
to allow on the fly changes of the structure of the format based block devices.
4
qemu_img_pipe_and_status(). qemu_img_verbose() is not very popular, so
5
update the only two users to qemu_img_log() and drop qemu_img_verbose()
6
at all.
5
7
6
Current plan is to first support encryption keyslot management for luks
8
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
based formats (raw and embedded in qcow2)
9
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
10
Message-Id: <20211223160144.1097696-6-vsementsov@virtuozzo.com>
11
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
12
---
13
tests/qemu-iotests/044 | 5 +++--
14
tests/qemu-iotests/044.out | 1 +
15
tests/qemu-iotests/209 | 7 ++++---
16
tests/qemu-iotests/209.out | 2 ++
17
tests/qemu-iotests/iotests.py | 8 --------
18
5 files changed, 10 insertions(+), 13 deletions(-)
8
19
9
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
20
diff --git a/tests/qemu-iotests/044 b/tests/qemu-iotests/044
10
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
21
index XXXXXXX..XXXXXXX 100755
11
Message-Id: <20200608094030.670121-12-mlevitsk@redhat.com>
22
--- a/tests/qemu-iotests/044
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
23
+++ b/tests/qemu-iotests/044
13
---
24
@@ -XXX,XX +XXX,XX @@ import os
14
qapi/block-core.json | 42 ++++++++++++++
25
import qcow2
15
qapi/job.json | 4 +-
26
from qcow2 import QcowHeader
16
include/block/block_int.h | 21 +++++--
27
import iotests
17
block/amend.c | 113 ++++++++++++++++++++++++++++++++++++++
28
-from iotests import qemu_img, qemu_img_verbose, qemu_io
18
block/Makefile.objs | 2 +-
29
+from iotests import qemu_img, qemu_img_log, qemu_io
19
5 files changed, 174 insertions(+), 8 deletions(-)
30
import struct
20
create mode 100644 block/amend.c
31
import subprocess
21
32
import sys
22
diff --git a/qapi/block-core.json b/qapi/block-core.json
33
@@ -XXX,XX +XXX,XX @@ class TestRefcountTableGrowth(iotests.QMPTestCase):
34
35
def test_grow_refcount_table(self):
36
qemu_io('-c', 'write 3800M 1M', test_img)
37
- qemu_img_verbose('check' , test_img)
38
+ qemu_img_log('check' , test_img)
39
pass
40
41
if __name__ == '__main__':
42
+ iotests.activate_logging()
43
iotests.main(supported_fmts=['qcow2'],
44
supported_protocols=['file'],
45
unsupported_imgopts=['refcount_bits'])
46
diff --git a/tests/qemu-iotests/044.out b/tests/qemu-iotests/044.out
23
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
24
--- a/qapi/block-core.json
48
--- a/tests/qemu-iotests/044.out
25
+++ b/qapi/block-core.json
49
+++ b/tests/qemu-iotests/044.out
26
@@ -XXX,XX +XXX,XX @@
50
@@ -XXX,XX +XXX,XX @@
27
'data': { 'job-id': 'str',
51
No errors were found on the image.
28
'options': 'BlockdevCreateOptions' } }
52
7292415/33554432 = 21.73% allocated, 0.00% fragmented, 0.00% compressed clusters
29
53
Image end offset: 4296217088
30
+##
31
+# @BlockdevAmendOptions:
32
+#
33
+# Options for amending an image format
34
+#
35
+# @driver: Block driver of the node to amend.
36
+#
37
+# Since: 5.1
38
+##
39
+{ 'union': 'BlockdevAmendOptions',
40
+ 'base': {
41
+ 'driver': 'BlockdevDriver' },
42
+ 'discriminator': 'driver',
43
+ 'data': {
44
+ } }
45
+
54
+
46
+##
55
.
47
+# @x-blockdev-amend:
56
----------------------------------------------------------------------
48
+#
57
Ran 1 tests
49
+# Starts a job to amend format specific options of an existing open block device
58
diff --git a/tests/qemu-iotests/209 b/tests/qemu-iotests/209
50
+# The job is automatically finalized, but a manual job-dismiss is required.
59
index XXXXXXX..XXXXXXX 100755
51
+#
60
--- a/tests/qemu-iotests/209
52
+# @job-id: Identifier for the newly created job.
61
+++ b/tests/qemu-iotests/209
53
+#
54
+# @node-name: Name of the block node to work on
55
+#
56
+# @options: Options (driver specific)
57
+#
58
+# @force: Allow unsafe operations, format specific
59
+# For luks that allows erase of the last active keyslot
60
+# (permanent loss of data),
61
+# and replacement of an active keyslot
62
+# (possible loss of data if IO error happens)
63
+#
64
+# Since: 5.1
65
+##
66
+{ 'command': 'x-blockdev-amend',
67
+ 'data': { 'job-id': 'str',
68
+ 'node-name': 'str',
69
+ 'options': 'BlockdevAmendOptions',
70
+ '*force': 'bool' } }
71
+
72
##
73
# @BlockErrorAction:
74
#
75
diff --git a/qapi/job.json b/qapi/job.json
76
index XXXXXXX..XXXXXXX 100644
77
--- a/qapi/job.json
78
+++ b/qapi/job.json
79
@@ -XXX,XX +XXX,XX @@
62
@@ -XXX,XX +XXX,XX @@
80
#
63
#
81
# @create: image creation job type, see "blockdev-create" (since 3.0)
64
82
#
65
import iotests
83
+# @amend: image options amend job type, see "x-blockdev-amend" (since 5.1)
66
-from iotests import qemu_img_create, qemu_io, qemu_img_verbose, qemu_nbd, \
84
+#
67
- file_path
85
# Since: 1.7
68
+from iotests import qemu_img_create, qemu_io, qemu_img_log, qemu_nbd, \
86
##
69
+ file_path, log
87
{ 'enum': 'JobType',
70
88
- 'data': ['commit', 'stream', 'mirror', 'backup', 'create'] }
71
iotests.script_initialize(supported_fmts=['qcow2'])
89
+ 'data': ['commit', 'stream', 'mirror', 'backup', 'create', 'amend'] }
72
90
73
@@ -XXX,XX +XXX,XX @@ qemu_img_create('-f', iotests.imgfmt, disk, '1M')
91
##
74
qemu_io('-f', iotests.imgfmt, '-c', 'write 0 512K', disk)
92
# @JobStatus:
75
93
diff --git a/include/block/block_int.h b/include/block/block_int.h
76
qemu_nbd('-k', nbd_sock, '-x', 'exp', '-f', iotests.imgfmt, disk)
77
-qemu_img_verbose('map', '-f', 'raw', '--output=json', nbd_uri)
78
+qemu_img_log('map', '-f', 'raw', '--output=json', nbd_uri)
79
+log('done.') # avoid new line at the end of output file
80
diff --git a/tests/qemu-iotests/209.out b/tests/qemu-iotests/209.out
94
index XXXXXXX..XXXXXXX 100644
81
index XXXXXXX..XXXXXXX 100644
95
--- a/include/block/block_int.h
82
--- a/tests/qemu-iotests/209.out
96
+++ b/include/block/block_int.h
83
+++ b/tests/qemu-iotests/209.out
97
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
84
@@ -XXX,XX +XXX,XX @@
98
int (*bdrv_file_open)(BlockDriverState *bs, QDict *options, int flags,
85
[{ "start": 0, "length": 524288, "depth": 0, "present": true, "zero": false, "data": true, "offset": 0},
99
Error **errp);
86
{ "start": 524288, "length": 524288, "depth": 0, "present": true, "zero": true, "data": false, "offset": 524288}]
100
void (*bdrv_close)(BlockDriverState *bs);
101
+
87
+
102
+
88
+done.
103
int coroutine_fn (*bdrv_co_create)(BlockdevCreateOptions *opts,
89
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
104
Error **errp);
90
index XXXXXXX..XXXXXXX 100644
105
int coroutine_fn (*bdrv_co_create_opts)(BlockDriver *drv,
91
--- a/tests/qemu-iotests/iotests.py
106
const char *filename,
92
+++ b/tests/qemu-iotests/iotests.py
107
QemuOpts *opts,
93
@@ -XXX,XX +XXX,XX @@ def qemu_img_measure(*args):
108
Error **errp);
94
def qemu_img_check(*args):
109
+
95
return json.loads(qemu_img_pipe("check", "--output", "json", *args))
110
+ int coroutine_fn (*bdrv_co_amend)(BlockDriverState *bs,
96
111
+ BlockdevAmendOptions *opts,
97
-def qemu_img_verbose(*args):
112
+ bool force,
98
- '''Run qemu-img without suppressing its output and return the exit code'''
113
+ Error **errp);
99
- exitcode = subprocess.call(qemu_img_args + list(args))
114
+
100
- if exitcode < 0:
115
+ int (*bdrv_amend_options)(BlockDriverState *bs,
101
- sys.stderr.write('qemu-img received signal %i: %s\n'
116
+ QemuOpts *opts,
102
- % (-exitcode, ' '.join(qemu_img_args + list(args))))
117
+ BlockDriverAmendStatusCB *status_cb,
103
- return exitcode
118
+ void *cb_opaque,
119
+ bool force,
120
+ Error **errp);
121
+
122
int (*bdrv_make_empty)(BlockDriverState *bs);
123
124
/*
125
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
126
BdrvCheckResult *result,
127
BdrvCheckMode fix);
128
129
- int (*bdrv_amend_options)(BlockDriverState *bs, QemuOpts *opts,
130
- BlockDriverAmendStatusCB *status_cb,
131
- void *cb_opaque,
132
- bool force,
133
- Error **errp);
134
-
104
-
135
void (*bdrv_debug_event)(BlockDriverState *bs, BlkdebugEvent event);
105
def qemu_img_pipe(*args: str) -> str:
136
106
'''Run qemu-img and return its output'''
137
/* TODO Better pass a option string/QDict/QemuOpts to add any rule? */
107
return qemu_img_pipe_and_status(*args)[0]
138
diff --git a/block/amend.c b/block/amend.c
139
new file mode 100644
140
index XXXXXXX..XXXXXXX
141
--- /dev/null
142
+++ b/block/amend.c
143
@@ -XXX,XX +XXX,XX @@
144
+/*
145
+ * Block layer code related to image options amend
146
+ *
147
+ * Copyright (c) 2018 Kevin Wolf <kwolf@redhat.com>
148
+ * Copyright (c) 2020 Red Hat. Inc
149
+ *
150
+ * Heavily based on create.c
151
+ *
152
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
153
+ * of this software and associated documentation files (the "Software"), to deal
154
+ * in the Software without restriction, including without limitation the rights
155
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
156
+ * copies of the Software, and to permit persons to whom the Software is
157
+ * furnished to do so, subject to the following conditions:
158
+ *
159
+ * The above copyright notice and this permission notice shall be included in
160
+ * all copies or substantial portions of the Software.
161
+ *
162
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
163
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
164
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
165
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
166
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
167
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
168
+ * THE SOFTWARE.
169
+ */
170
+
171
+#include "qemu/osdep.h"
172
+#include "block/block_int.h"
173
+#include "qemu/job.h"
174
+#include "qemu/main-loop.h"
175
+#include "qapi/qapi-commands-block-core.h"
176
+#include "qapi/qapi-visit-block-core.h"
177
+#include "qapi/clone-visitor.h"
178
+#include "qapi/error.h"
179
+
180
+typedef struct BlockdevAmendJob {
181
+ Job common;
182
+ BlockdevAmendOptions *opts;
183
+ BlockDriverState *bs;
184
+ bool force;
185
+} BlockdevAmendJob;
186
+
187
+static int coroutine_fn blockdev_amend_run(Job *job, Error **errp)
188
+{
189
+ BlockdevAmendJob *s = container_of(job, BlockdevAmendJob, common);
190
+ int ret;
191
+
192
+ job_progress_set_remaining(&s->common, 1);
193
+ ret = s->bs->drv->bdrv_co_amend(s->bs, s->opts, s->force, errp);
194
+ job_progress_update(&s->common, 1);
195
+ qapi_free_BlockdevAmendOptions(s->opts);
196
+ return ret;
197
+}
198
+
199
+static const JobDriver blockdev_amend_job_driver = {
200
+ .instance_size = sizeof(BlockdevAmendJob),
201
+ .job_type = JOB_TYPE_AMEND,
202
+ .run = blockdev_amend_run,
203
+};
204
+
205
+void qmp_x_blockdev_amend(const char *job_id,
206
+ const char *node_name,
207
+ BlockdevAmendOptions *options,
208
+ bool has_force,
209
+ bool force,
210
+ Error **errp)
211
+{
212
+ BlockdevAmendJob *s;
213
+ const char *fmt = BlockdevDriver_str(options->driver);
214
+ BlockDriver *drv = bdrv_find_format(fmt);
215
+ BlockDriverState *bs = bdrv_find_node(node_name);
216
+
217
+
218
+ if (!drv) {
219
+ error_setg(errp, "Block driver '%s' not found or not supported", fmt);
220
+ return;
221
+ }
222
+
223
+ /*
224
+ * If the driver is in the schema, we know that it exists. But it may not
225
+ * be whitelisted.
226
+ */
227
+ if (bdrv_uses_whitelist() && !bdrv_is_whitelisted(drv, false)) {
228
+ error_setg(errp, "Driver is not whitelisted");
229
+ return;
230
+ }
231
+
232
+ if (bs->drv != drv) {
233
+ error_setg(errp,
234
+ "x-blockdev-amend doesn't support changing the block driver");
235
+ return;
236
+ }
237
+
238
+ /* Error out if the driver doesn't support .bdrv_co_amend */
239
+ if (!drv->bdrv_co_amend) {
240
+ error_setg(errp, "Driver does not support x-blockdev-amend");
241
+ return;
242
+ }
243
+
244
+ /* Create the block job */
245
+ s = job_create(job_id, &blockdev_amend_job_driver, NULL,
246
+ bdrv_get_aio_context(bs), JOB_DEFAULT | JOB_MANUAL_DISMISS,
247
+ NULL, NULL, errp);
248
+ if (!s) {
249
+ return;
250
+ }
251
+
252
+ s->bs = bs,
253
+ s->opts = QAPI_CLONE(BlockdevAmendOptions, options),
254
+ s->force = has_force ? force : false;
255
+ job_start(&s->common);
256
+}
257
diff --git a/block/Makefile.objs b/block/Makefile.objs
258
index XXXXXXX..XXXXXXX 100644
259
--- a/block/Makefile.objs
260
+++ b/block/Makefile.objs
261
@@ -XXX,XX +XXX,XX @@ block-obj-$(CONFIG_WIN32) += file-win32.o win32-aio.o
262
block-obj-$(CONFIG_POSIX) += file-posix.o
263
block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
264
block-obj-$(CONFIG_LINUX_IO_URING) += io_uring.o
265
-block-obj-y += null.o mirror.o commit.o io.o create.o
266
+block-obj-y += null.o mirror.o commit.o io.o create.o amend.o
267
block-obj-y += throttle-groups.o
268
block-obj-$(CONFIG_LINUX) += nvme.o
269
270
--
108
--
271
2.26.2
109
2.34.1
272
110
273
111
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
Commit 96927c744 replaced qdev_init_nofail() call by
3
Move the logic to more generic qemu_img_pipe_and_status(). Also behave
4
isa_realize_and_unref() which has a different error
4
better when we have several -o options. And reuse argument parser of
5
message. Update the test output accordingly.
5
course.
6
6
7
Gitlab CI error after merging b77b5b3dc7:
7
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
https://gitlab.com/qemu-project/qemu/-/jobs/597414772#L4375
8
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
9
Message-Id: <20211223160144.1097696-7-vsementsov@virtuozzo.com>
10
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
11
---
12
tests/qemu-iotests/iotests.py | 36 +++++++++++++++++------------------
13
1 file changed, 17 insertions(+), 19 deletions(-)
9
14
10
Reported-by: Thomas Huth <thuth@redhat.com>
15
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
11
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Message-Id: <20200616154949.6586-1-philmd@redhat.com>
13
Reviewed-by: Thomas Huth <thuth@redhat.com>
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
15
---
16
tests/qemu-iotests/051.pc.out | 4 ++--
17
1 file changed, 2 insertions(+), 2 deletions(-)
18
19
diff --git a/tests/qemu-iotests/051.pc.out b/tests/qemu-iotests/051.pc.out
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/tests/qemu-iotests/051.pc.out
17
--- a/tests/qemu-iotests/iotests.py
22
+++ b/tests/qemu-iotests/051.pc.out
18
+++ b/tests/qemu-iotests/iotests.py
23
@@ -XXX,XX +XXX,XX @@ QEMU X.Y.Z monitor - type 'help' for more information
19
@@ -XXX,XX +XXX,XX @@ def qemu_img_create_prepare_args(args: List[str]) -> List[str]:
24
20
args = args[1:]
25
Testing: -drive if=ide
21
26
QEMU X.Y.Z monitor - type 'help' for more information
22
p = argparse.ArgumentParser(allow_abbrev=False)
27
-(qemu) QEMU_PROG: Initialization of device ide-hd failed: Device needs media, but drive is empty
23
+ # -o option may be specified several times
28
+(qemu) QEMU_PROG: Device needs media, but drive is empty
24
+ p.add_argument('-o', action='append', default=[])
29
25
p.add_argument('-f')
30
Testing: -drive if=virtio
26
parsed, remaining = p.parse_known_args(args)
31
QEMU X.Y.Z monitor - type 'help' for more information
27
32
@@ -XXX,XX +XXX,XX @@ QEMU X.Y.Z monitor - type 'help' for more information
28
+ opts_list = parsed.o
33
29
+
34
Testing: -drive file=TEST_DIR/t.qcow2,if=ide,readonly=on
30
result = ['create']
35
QEMU X.Y.Z monitor - type 'help' for more information
31
if parsed.f is not None:
36
-(qemu) QEMU_PROG: Initialization of device ide-hd failed: Block node is read-only
32
result += ['-f', parsed.f]
37
+(qemu) QEMU_PROG: Block node is read-only
33
@@ -XXX,XX +XXX,XX @@ def qemu_img_create_prepare_args(args: List[str]) -> List[str]:
38
34
# like extended_l2 or compression_type for qcow2. Test may want to create
39
Testing: -drive file=TEST_DIR/t.qcow2,if=virtio,readonly=on
35
# additional images in other formats that doesn't support these options.
40
QEMU X.Y.Z monitor - type 'help' for more information
36
# So, use IMGOPTS only for images created in imgfmt format.
37
- if parsed.f == imgfmt and 'IMGOPTS' in os.environ:
38
- result += ['-o', os.environ['IMGOPTS']]
39
+ imgopts = os.environ.get('IMGOPTS')
40
+ if imgopts and parsed.f == imgfmt:
41
+ opts_list.insert(0, imgopts)
42
+
43
+ # default luks support
44
+ if parsed.f == 'luks' and \
45
+ all('key-secret' not in opts for opts in opts_list):
46
+ result += ['--object', luks_default_secret_object]
47
+ opts_list.append(luks_default_key_secret_opt)
48
+
49
+ for opts in opts_list:
50
+ result += ['-o', opts]
51
52
result += remaining
53
54
@@ -XXX,XX +XXX,XX @@ def ordered_qmp(qmsg, conv_keys=True):
55
return qmsg
56
57
def qemu_img_create(*args):
58
- args = list(args)
59
-
60
- # default luks support
61
- if '-f' in args and args[args.index('-f') + 1] == 'luks':
62
- if '-o' in args:
63
- i = args.index('-o')
64
- if 'key-secret' not in args[i + 1]:
65
- args[i + 1].append(luks_default_key_secret_opt)
66
- args.insert(i + 2, '--object')
67
- args.insert(i + 3, luks_default_secret_object)
68
- else:
69
- args = ['-o', luks_default_key_secret_opt,
70
- '--object', luks_default_secret_object] + args
71
-
72
- args.insert(0, 'create')
73
-
74
- return qemu_img(*args)
75
+ return qemu_img('create', *args)
76
77
def qemu_img_measure(*args):
78
return json.loads(qemu_img_pipe("measure", "--output", "json", *args))
41
--
79
--
42
2.26.2
80
2.34.1
43
81
44
82
diff view generated by jsdifflib
1
From: Maxim Levitsky <mlevitsk@redhat.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
This commit adds two tests, which test the new amend interface
3
The test prints qcow2 header fields which depends on chosen compression
4
of both luks raw images and qcow2 luks encrypted images.
4
type. So, let's be explicit in what compression type we want and
5
independent of IMGOPTS. Test both existing compression types.
5
6
6
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
7
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
8
Message-Id: <20200608094030.670121-11-mlevitsk@redhat.com>
9
Message-Id: <20211223160144.1097696-8-vsementsov@virtuozzo.com>
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
10
---
11
---
11
tests/qemu-iotests/293 | 207 +++++++++++++++++++++++++++++++++++++
12
tests/qemu-iotests/303 | 25 ++++++++++++++++---------
12
tests/qemu-iotests/293.out | 99 ++++++++++++++++++
13
tests/qemu-iotests/303.out | 30 +++++++++++++++++++++++++++++-
13
tests/qemu-iotests/294 | 90 ++++++++++++++++
14
2 files changed, 45 insertions(+), 10 deletions(-)
14
tests/qemu-iotests/294.out | 30 ++++++
15
tests/qemu-iotests/group | 2 +
16
5 files changed, 428 insertions(+)
17
create mode 100755 tests/qemu-iotests/293
18
create mode 100644 tests/qemu-iotests/293.out
19
create mode 100755 tests/qemu-iotests/294
20
create mode 100644 tests/qemu-iotests/294.out
21
15
22
diff --git a/tests/qemu-iotests/293 b/tests/qemu-iotests/293
16
diff --git a/tests/qemu-iotests/303 b/tests/qemu-iotests/303
23
new file mode 100755
17
index XXXXXXX..XXXXXXX 100755
24
index XXXXXXX..XXXXXXX
18
--- a/tests/qemu-iotests/303
25
--- /dev/null
19
+++ b/tests/qemu-iotests/303
26
+++ b/tests/qemu-iotests/293
20
@@ -XXX,XX +XXX,XX @@ def add_bitmap(num, begin, end, disabled):
27
@@ -XXX,XX +XXX,XX @@
21
log('')
28
+#!/usr/bin/env bash
22
29
+#
23
30
+# Test encryption key management with luks
24
-qemu_img_create('-f', iotests.imgfmt, disk, '10M')
31
+# Based on 134
25
-
32
+#
26
-add_bitmap(1, 0, 6, False)
33
+# Copyright (C) 2019 Red Hat, Inc.
27
-add_bitmap(2, 6, 8, True)
34
+#
28
-dump = ['./qcow2.py', disk, 'dump-header']
35
+# This program is free software; you can redistribute it and/or modify
29
-subprocess.run(dump)
36
+# it under the terms of the GNU General Public License as published by
30
-# Dump the metadata in JSON format
37
+# the Free Software Foundation; either version 2 of the License, or
31
-dump.append('-j')
38
+# (at your option) any later version.
32
-subprocess.run(dump)
39
+#
33
+def test(compression_type: str, json_output: bool) -> None:
40
+# This program is distributed in the hope that it will be useful,
34
+ qemu_img_create('-f', iotests.imgfmt,
41
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
35
+ '-o', f'compression_type={compression_type}',
42
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36
+ disk, '10M')
43
+# GNU General Public License for more details.
37
+ add_bitmap(1, 0, 6, False)
44
+#
38
+ add_bitmap(2, 6, 8, True)
45
+# You should have received a copy of the GNU General Public License
46
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
47
+#
48
+
39
+
49
+# creator
40
+ cmd = ['./qcow2.py', disk, 'dump-header']
50
+owner=mlevitsk@redhat.com
41
+ if json_output:
42
+ cmd.append('-j')
51
+
43
+
52
+seq=`basename $0`
44
+ subprocess.run(cmd)
53
+echo "QA output created by $seq"
54
+
55
+status=1    # failure is the default!
56
+
57
+_cleanup()
58
+{
59
+    _cleanup_test_img
60
+}
61
+trap "_cleanup; exit \$status" 0 1 2 3 15
62
+
63
+# get standard environment, filters and checks
64
+. ./common.rc
65
+. ./common.filter
66
+
67
+_supported_fmt qcow2 luks
68
+_supported_proto file #TODO
69
+
70
+QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT
71
+
72
+if [ "$IMGFMT" = "qcow2" ] ; then
73
+    PR="encrypt."
74
+    EXTRA_IMG_ARGS="-o encrypt.format=luks"
75
+fi
76
+
45
+
77
+
46
+
78
+# secrets: you are supposed to see the password as *******, see :-)
47
+test('zlib', False)
79
+S0="--object secret,id=sec0,data=hunter0"
48
+test('zstd', True)
80
+S1="--object secret,id=sec1,data=hunter1"
49
diff --git a/tests/qemu-iotests/303.out b/tests/qemu-iotests/303.out
81
+S2="--object secret,id=sec2,data=hunter2"
50
index XXXXXXX..XXXXXXX 100644
82
+S3="--object secret,id=sec3,data=hunter3"
51
--- a/tests/qemu-iotests/303.out
83
+S4="--object secret,id=sec4,data=hunter4"
52
+++ b/tests/qemu-iotests/303.out
84
+SECRETS="$S0 $S1 $S2 $S3 $S4"
53
@@ -XXX,XX +XXX,XX @@ extra_data_size 0
54
Bitmap table type size offset
55
0 all-zeroes 0 0
56
57
+Add bitmap 1
58
+wrote 1048576/1048576 bytes at offset 0
59
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
85
+
60
+
86
+# image with given secret
61
+wrote 1048576/1048576 bytes at offset 1048576
87
+IMGS0="--image-opts driver=$IMGFMT,file.filename=$TEST_IMG,${PR}key-secret=sec0"
62
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
88
+IMGS1="--image-opts driver=$IMGFMT,file.filename=$TEST_IMG,${PR}key-secret=sec1"
63
+
89
+IMGS2="--image-opts driver=$IMGFMT,file.filename=$TEST_IMG,${PR}key-secret=sec2"
64
+wrote 1048576/1048576 bytes at offset 2097152
90
+IMGS3="--image-opts driver=$IMGFMT,file.filename=$TEST_IMG,${PR}key-secret=sec3"
65
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
91
+IMGS4="--image-opts driver=$IMGFMT,file.filename=$TEST_IMG,${PR}key-secret=sec4"
66
+
67
+wrote 1048576/1048576 bytes at offset 3145728
68
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
69
+
70
+wrote 1048576/1048576 bytes at offset 4194304
71
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
72
+
73
+wrote 1048576/1048576 bytes at offset 5242880
74
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
92
+
75
+
93
+
76
+
94
+echo "== creating a test image =="
77
+Add bitmap 2
95
+_make_test_img $S0 $EXTRA_IMG_ARGS -o ${PR}key-secret=sec0,${PR}iter-time=10 32M
78
+wrote 1048576/1048576 bytes at offset 6291456
79
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
96
+
80
+
97
+echo
81
+wrote 1048576/1048576 bytes at offset 7340032
98
+echo "== test that key 0 opens the image =="
82
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
99
+$QEMU_IO $S0 -c "read 0 4096" $IMGS0 | _filter_qemu_io | _filter_testdir
100
+
101
+echo
102
+echo "== adding a password to slot 4 =="
103
+$QEMU_IMG amend $SECRETS $IMGS0 -o ${PR}state=active,${PR}new-secret=sec4,${PR}iter-time=10,${PR}keyslot=4
104
+echo "== adding a password to slot 1 =="
105
+$QEMU_IMG amend $SECRETS $IMGS0 -o ${PR}state=active,${PR}new-secret=sec1,${PR}iter-time=10
106
+echo "== adding a password to slot 3 =="
107
+$QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=active,${PR}new-secret=sec3,${PR}iter-time=10,${PR}keyslot=3
108
+
109
+echo "== adding a password to slot 2 =="
110
+$QEMU_IMG amend $SECRETS $IMGS3 -o ${PR}state=active,${PR}new-secret=sec2,${PR}iter-time=10
111
+
83
+
112
+
84
+
113
+echo "== erase slot 4 =="
85
{
114
+$QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}keyslot=4 | _filter_img_create
86
"magic": 1363560955,
115
+
87
"version": 3,
116
+
88
@@ -XXX,XX +XXX,XX @@ Bitmap table type size offset
117
+echo
89
"refcount_table_clusters": 1,
118
+echo "== all secrets should work =="
90
"nb_snapshots": 0,
119
+for IMG in "$IMGS0" "$IMGS1" "$IMGS2" "$IMGS3"; do
91
"snapshot_offset": 0,
120
+    $QEMU_IO $SECRETS -c "read 0 4096" $IMG | _filter_qemu_io | _filter_testdir
92
- "incompatible_features": 0,
121
+done
93
+ "incompatible_features": 8,
122
+
94
"compatible_features": 0,
123
+echo
95
"autoclear_features": 1,
124
+echo "== erase slot 0 and try it =="
96
"refcount_order": 4,
125
+$QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}old-secret=sec0 | _filter_img_create
126
+$QEMU_IO $SECRETS -c "read 0 4096" $IMGS0 | _filter_qemu_io | _filter_testdir
127
+
128
+echo
129
+echo "== erase slot 2 and try it =="
130
+$QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}keyslot=2 | _filter_img_create
131
+$QEMU_IO $SECRETS -c "read 0 4096" $IMGS2 | _filter_qemu_io | _filter_testdir
132
+
133
+
134
+# at this point slots 1 and 3 should be active
135
+
136
+echo
137
+echo "== filling 4 slots with secret 2 =="
138
+for i in $(seq 0 3) ; do
139
+    $QEMU_IMG amend $SECRETS $IMGS3 -o ${PR}state=active,${PR}new-secret=sec2,${PR}iter-time=10
140
+done
141
+
142
+echo
143
+echo "== adding secret 0 =="
144
+    $QEMU_IMG amend $SECRETS $IMGS3 -o ${PR}state=active,${PR}new-secret=sec0,${PR}iter-time=10
145
+
146
+echo
147
+echo "== adding secret 3 (last slot) =="
148
+    $QEMU_IMG amend $SECRETS $IMGS3 -o ${PR}state=active,${PR}new-secret=sec3,${PR}iter-time=10
149
+
150
+echo
151
+echo "== trying to add another slot (should fail) =="
152
+$QEMU_IMG amend $SECRETS $IMGS2 -o ${PR}state=active,${PR}new-secret=sec3,${PR}iter-time=10
153
+
154
+echo
155
+echo "== all secrets should work again =="
156
+for IMG in "$IMGS0" "$IMGS1" "$IMGS2" "$IMGS3"; do
157
+    $QEMU_IO $SECRETS -c "read 0 4096" $IMG | _filter_qemu_io | _filter_testdir
158
+done
159
+
160
+
161
+echo
162
+
163
+echo "== erase all keys of secret 2=="
164
+$QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}old-secret=sec2
165
+
166
+echo "== erase all keys of secret 1=="
167
+$QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}old-secret=sec1
168
+
169
+echo "== erase all keys of secret 0=="
170
+$QEMU_IMG amend $SECRETS $IMGS0 -o ${PR}state=inactive,${PR}old-secret=sec0
171
+
172
+echo "== erasing secret3 will fail now since it is the only secret (in 3 slots) =="
173
+$QEMU_IMG amend $SECRETS $IMGS3 -o ${PR}state=inactive,${PR}old-secret=sec3
174
+
175
+echo
176
+echo "== only secret3 should work now =="
177
+for IMG in "$IMGS0" "$IMGS1" "$IMGS2" "$IMGS3"; do
178
+    $QEMU_IO $SECRETS -c "read 0 4096" $IMG | _filter_qemu_io | _filter_testdir
179
+done
180
+
181
+echo
182
+echo "== add secret0 =="
183
+$QEMU_IMG amend $SECRETS $IMGS3 -o ${PR}state=active,${PR}new-secret=sec0,${PR}iter-time=10
184
+
185
+echo "== erase secret3 =="
186
+$QEMU_IMG amend $SECRETS $IMGS0 -o ${PR}state=inactive,${PR}old-secret=sec3
187
+
188
+echo
189
+echo "== only secret0 should work now =="
190
+for IMG in "$IMGS0" "$IMGS1" "$IMGS2" "$IMGS3"; do
191
+    $QEMU_IO $SECRETS -c "read 0 4096" $IMG | _filter_qemu_io | _filter_testdir
192
+done
193
+
194
+echo
195
+echo "== replace secret0 with secret1 (should fail) =="
196
+$QEMU_IMG amend $SECRETS $IMGS0 -o ${PR}state=active,${PR}new-secret=sec1,${PR}keyslot=0
197
+
198
+echo
199
+echo "== replace secret0 with secret1 with force (should work) =="
200
+$QEMU_IMG amend $SECRETS $IMGS0 -o ${PR}state=active,${PR}new-secret=sec1,${PR}iter-time=10,${PR}keyslot=0 --force
201
+
202
+echo
203
+echo "== only secret1 should work now =="
204
+for IMG in "$IMGS0" "$IMGS1" "$IMGS2" "$IMGS3"; do
205
+    $QEMU_IO $SECRETS -c "read 0 4096" $IMG | _filter_qemu_io | _filter_testdir
206
+done
207
+
208
+
209
+echo
210
+echo "== erase last secret (should fail) =="
211
+$QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}keyslot=0
212
+$QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}old-secret=sec1
213
+
214
+
215
+echo "== erase non existing secrets (should fail) =="
216
+$QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}old-secret=sec5 --force
217
+$QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}old-secret=sec0 --force
218
+$QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}keyslot=1 --force
219
+
220
+echo
221
+echo "== erase last secret with force by slot (should work) =="
222
+$QEMU_IMG amend $SECRETS $IMGS1 -o ${PR}state=inactive,${PR}keyslot=0 --force
223
+
224
+echo
225
+echo "== we have no secrets now, data is lost forever =="
226
+for IMG in "$IMGS0" "$IMGS1" "$IMGS2" "$IMGS3"; do
227
+    $QEMU_IO $SECRETS -c "read 0 4096" $IMG | _filter_qemu_io | _filter_testdir
228
+done
229
+
230
+# success, all done
231
+echo "*** done"
232
+rm -f $seq.full
233
+status=0
234
+
235
diff --git a/tests/qemu-iotests/293.out b/tests/qemu-iotests/293.out
236
new file mode 100644
237
index XXXXXXX..XXXXXXX
238
--- /dev/null
239
+++ b/tests/qemu-iotests/293.out
240
@@ -XXX,XX +XXX,XX @@
241
+QA output created by 293
242
+== creating a test image ==
243
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33554432
244
+
245
+== test that key 0 opens the image ==
246
+read 4096/4096 bytes at offset 0
247
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
248
+
249
+== adding a password to slot 4 ==
250
+== adding a password to slot 1 ==
251
+== adding a password to slot 3 ==
252
+== adding a password to slot 2 ==
253
+== erase slot 4 ==
254
+
255
+== all secrets should work ==
256
+read 4096/4096 bytes at offset 0
257
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
258
+read 4096/4096 bytes at offset 0
259
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
260
+read 4096/4096 bytes at offset 0
261
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
262
+read 4096/4096 bytes at offset 0
263
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
264
+
265
+== erase slot 0 and try it ==
266
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
267
+
268
+== erase slot 2 and try it ==
269
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
270
+
271
+== filling 4 slots with secret 2 ==
272
+
273
+== adding secret 0 ==
274
+
275
+== adding secret 3 (last slot) ==
276
+
277
+== trying to add another slot (should fail) ==
278
+qemu-img: Can't add a keyslot - all keyslots are in use
279
+
280
+== all secrets should work again ==
281
+read 4096/4096 bytes at offset 0
282
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
283
+read 4096/4096 bytes at offset 0
284
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
285
+read 4096/4096 bytes at offset 0
286
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
287
+read 4096/4096 bytes at offset 0
288
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
289
+
290
+== erase all keys of secret 2==
291
+== erase all keys of secret 1==
292
+== erase all keys of secret 0==
293
+== erasing secret3 will fail now since it is the only secret (in 3 slots) ==
294
+qemu-img: All the active keyslots match the (old) password that was given and erasing them will erase all the data in the image irreversibly - refusing operation
295
+
296
+== only secret3 should work now ==
297
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
298
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
299
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
300
+read 4096/4096 bytes at offset 0
301
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
302
+
303
+== add secret0 ==
304
+== erase secret3 ==
305
+
306
+== only secret0 should work now ==
307
+read 4096/4096 bytes at offset 0
308
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
309
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
310
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
311
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
312
+
313
+== replace secret0 with secret1 (should fail) ==
314
+qemu-img: Refusing to overwrite active keyslot 0 - please erase it first
315
+
316
+== replace secret0 with secret1 with force (should work) ==
317
+
318
+== only secret1 should work now ==
319
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
320
+read 4096/4096 bytes at offset 0
321
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
322
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
323
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
324
+
325
+== erase last secret (should fail) ==
326
+qemu-img: Attempt to erase the only active keyslot 0 which will erase all the data in the image irreversibly - refusing operation
327
+qemu-img: All the active keyslots match the (old) password that was given and erasing them will erase all the data in the image irreversibly - refusing operation
328
+== erase non existing secrets (should fail) ==
329
+qemu-img: No secret with id 'sec5'
330
+qemu-img: No keyslots match given (old) password for erase operation
331
+
332
+== erase last secret with force by slot (should work) ==
333
+
334
+== we have no secrets now, data is lost forever ==
335
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
336
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
337
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
338
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
339
+*** done
340
diff --git a/tests/qemu-iotests/294 b/tests/qemu-iotests/294
341
new file mode 100755
342
index XXXXXXX..XXXXXXX
343
--- /dev/null
344
+++ b/tests/qemu-iotests/294
345
@@ -XXX,XX +XXX,XX @@
346
+#
347
+# Copyright (C) 2019 Red Hat, Inc.
348
+#
349
+# This program is free software; you can redistribute it and/or modify
350
+# it under the terms of the GNU General Public License as published by
351
+# the Free Software Foundation; either version 2 of the License, or
352
+# (at your option) any later version.
353
+#
354
+# This program is distributed in the hope that it will be useful,
355
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
356
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
357
+# GNU General Public License for more details.
358
+#
359
+# You should have received a copy of the GNU General Public License
360
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
361
+#
362
+
363
+# creator
364
+owner=mlevitsk@redhat.com
365
+
366
+seq=`basename $0`
367
+echo "QA output created by $seq"
368
+
369
+status=1    # failure is the default!
370
+
371
+_cleanup()
372
+{
373
+    _cleanup_test_img
374
+}
375
+trap "_cleanup; exit \$status" 0 1 2 3 15
376
+
377
+# get standard environment, filters and checks
378
+. ./common.rc
379
+. ./common.filter
380
+
381
+_supported_fmt luks
382
+_supported_proto file #TODO
383
+
384
+QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT
385
+
386
+# you are supposed to see the password as *******, see :-)
387
+S0="--object secret,id=sec0,data=hunter0"
388
+S1="--object secret,id=sec1,data=hunter1"
389
+SECRETS="$S0 $S1"
390
+
391
+
392
+IMGS0="--image-opts driver=$IMGFMT,file.filename=$TEST_IMG,key-secret=sec0"
393
+IMGS1="--image-opts driver=$IMGFMT,file.filename=$TEST_IMG,key-secret=sec1"
394
+
395
+echo "== creating a test image =="
396
+_make_test_img $S0 -o "key-secret=sec0,iter-time=10" 32M
397
+
398
+echo
399
+echo "== test that key 0 opens the image =="
400
+$QEMU_IO $S0 -c "read 0 4096" $IMGS0 | _filter_qemu_io | _filter_testdir
401
+
402
+echo
403
+echo "== adding a password to slot 1 =="
404
+$QEMU_IMG amend $SECRETS $IMGS0 -o state=active,new-secret=sec1,keyslot=1,iter-time=10
405
+
406
+echo
407
+echo "== 'backup' the image header =="
408
+dd if=$TEST_IMG_FILE of=${TEST_IMG_FILE}.bk bs=4K skip=0 count=1
409
+
410
+echo
411
+echo "== erase slot 0 =="
412
+$QEMU_IMG amend $SECRETS $IMGS1 -o state=inactive,keyslot=0 | _filter_img_create
413
+
414
+echo
415
+echo "== test that key 0 doesn't open the image =="
416
+$QEMU_IO $S0 -c "read 0 4096" $IMGS0 | _filter_qemu_io | _filter_testdir
417
+
418
+echo
419
+echo "== 'restore' the image header =="
420
+dd if=${TEST_IMG_FILE}.bk of=${TEST_IMG_FILE} bs=4K skip=0 count=1 conv=notrunc
421
+
422
+echo
423
+echo "== test that key 0 still doesn't open the image (key material is erased) =="
424
+$QEMU_IO $SECRETS -c "read 0 4096" $IMGS0 | _filter_qemu_io | _filter_testdir
425
+
426
+echo
427
+echo "== test that key 1 still works =="
428
+$QEMU_IO $SECRETS -c "read 0 4096" $IMGS1 | _filter_qemu_io | _filter_testdir
429
+
430
+echo "*** done"
431
+rm -f $seq.full
432
+status=0
433
+
434
+
435
+exit 0
436
diff --git a/tests/qemu-iotests/294.out b/tests/qemu-iotests/294.out
437
new file mode 100644
438
index XXXXXXX..XXXXXXX
439
--- /dev/null
440
+++ b/tests/qemu-iotests/294.out
441
@@ -XXX,XX +XXX,XX @@
442
+QA output created by 294
443
+== creating a test image ==
444
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33554432
445
+
446
+== test that key 0 opens the image ==
447
+read 4096/4096 bytes at offset 0
448
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
449
+
450
+== adding a password to slot 1 ==
451
+
452
+== 'backup' the image header ==
453
+1+0 records in
454
+1+0 records out
455
+
456
+== erase slot 0 ==
457
+
458
+== test that key 0 doesn't open the image ==
459
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
460
+
461
+== 'restore' the image header ==
462
+1+0 records in
463
+1+0 records out
464
+
465
+== test that key 0 still doesn't open the image (key material is erased) ==
466
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
467
+
468
+== test that key 1 still works ==
469
+read 4096/4096 bytes at offset 0
470
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
471
+*** done
472
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
473
index XXXXXXX..XXXXXXX 100644
474
--- a/tests/qemu-iotests/group
475
+++ b/tests/qemu-iotests/group
476
@@ -XXX,XX +XXX,XX @@
477
290 rw auto quick
478
291 rw quick
479
292 rw auto quick
480
+293 rw auto
481
+294 rw auto quick
482
297 meta
483
--
97
--
484
2.26.2
98
2.34.1
485
99
486
100
diff view generated by jsdifflib
1
From: Maxim Levitsky <mlevitsk@redhat.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
Next few patches will expose that functionality to the user.
3
The test checks different options. It of course fails if set
4
IMGOPTS='compression_type=zstd'. So, let's be explicit in what
5
compression type we want and independent of IMGOPTS. Test both existing
6
compression types.
4
7
5
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
8
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
9
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
7
Message-Id: <20200608094030.670121-3-mlevitsk@redhat.com>
10
Message-Id: <20211223160144.1097696-9-vsementsov@virtuozzo.com>
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
9
---
12
---
10
qapi/crypto.json | 59 ++++++-
13
tests/qemu-iotests/065 | 16 ++++++++--------
11
crypto/block-luks.c | 416 +++++++++++++++++++++++++++++++++++++++++++-
14
1 file changed, 8 insertions(+), 8 deletions(-)
12
2 files changed, 469 insertions(+), 6 deletions(-)
13
15
14
diff --git a/qapi/crypto.json b/qapi/crypto.json
16
diff --git a/tests/qemu-iotests/065 b/tests/qemu-iotests/065
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100755
16
--- a/qapi/crypto.json
18
--- a/tests/qemu-iotests/065
17
+++ b/qapi/crypto.json
19
+++ b/tests/qemu-iotests/065
18
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ class TestQMP(TestImageInfoSpecific):
19
'uuid': 'str',
21
20
'slots': [ 'QCryptoBlockInfoLUKSSlot' ] }}
22
class TestQCow2(TestQemuImgInfo):
21
23
'''Testing a qcow2 version 2 image'''
22
-
24
- img_options = 'compat=0.10'
23
##
25
+ img_options = 'compat=0.10,compression_type=zlib'
24
# @QCryptoBlockInfo:
26
json_compare = { 'compat': '0.10', 'refcount-bits': 16,
25
#
27
'compression-type': 'zlib' }
26
@@ -XXX,XX +XXX,XX @@
28
human_compare = [ 'compat: 0.10', 'compression type: zlib',
27
'discriminator': 'format',
29
@@ -XXX,XX +XXX,XX @@ class TestQCow2(TestQemuImgInfo):
28
'data': { 'luks': 'QCryptoBlockInfoLUKS' } }
30
29
31
class TestQCow3NotLazy(TestQemuImgInfo):
30
+##
32
'''Testing a qcow2 version 3 image with lazy refcounts disabled'''
31
+# @QCryptoBlockLUKSKeyslotState:
33
- img_options = 'compat=1.1,lazy_refcounts=off'
32
+#
34
+ img_options = 'compat=1.1,lazy_refcounts=off,compression_type=zstd'
33
+# Defines state of keyslots that are affected by the update
35
json_compare = { 'compat': '1.1', 'lazy-refcounts': False,
34
+#
36
'refcount-bits': 16, 'corrupt': False,
35
+# @active: The slots contain the given password and marked as active
37
- 'compression-type': 'zlib', 'extended-l2': False }
36
+# @inactive: The slots are erased (contain garbage) and marked as inactive
38
- human_compare = [ 'compat: 1.1', 'compression type: zlib',
37
+#
39
+ 'compression-type': 'zstd', 'extended-l2': False }
38
+# Since: 5.1
40
+ human_compare = [ 'compat: 1.1', 'compression type: zstd',
39
+##
41
'lazy refcounts: false', 'refcount bits: 16',
40
+{ 'enum': 'QCryptoBlockLUKSKeyslotState',
42
'corrupt: false', 'extended l2: false' ]
41
+ 'data': [ 'active', 'inactive' ] }
43
42
+
44
class TestQCow3Lazy(TestQemuImgInfo):
43
45
'''Testing a qcow2 version 3 image with lazy refcounts enabled'''
44
+##
46
- img_options = 'compat=1.1,lazy_refcounts=on'
45
+# @QCryptoBlockAmendOptionsLUKS:
47
+ img_options = 'compat=1.1,lazy_refcounts=on,compression_type=zlib'
46
+#
48
json_compare = { 'compat': '1.1', 'lazy-refcounts': True,
47
+# This struct defines the update parameters that activate/de-activate set
49
'refcount-bits': 16, 'corrupt': False,
48
+# of keyslots
50
'compression-type': 'zlib', 'extended-l2': False }
49
+#
51
@@ -XXX,XX +XXX,XX @@ class TestQCow3Lazy(TestQemuImgInfo):
50
+# @state: the desired state of the keyslots
52
class TestQCow3NotLazyQMP(TestQMP):
51
+#
53
'''Testing a qcow2 version 3 image with lazy refcounts disabled, opening
52
+# @new-secret: The ID of a QCryptoSecret object providing the password to be
54
with lazy refcounts enabled'''
53
+# written into added active keyslots
55
- img_options = 'compat=1.1,lazy_refcounts=off'
54
+#
56
+ img_options = 'compat=1.1,lazy_refcounts=off,compression_type=zlib'
55
+# @old-secret: Optional (for deactivation only)
57
qemu_options = 'lazy-refcounts=on'
56
+# If given will deactive all keyslots that
58
compare = { 'compat': '1.1', 'lazy-refcounts': False,
57
+# match password located in QCryptoSecret with this ID
59
'refcount-bits': 16, 'corrupt': False,
58
+#
60
@@ -XXX,XX +XXX,XX @@ class TestQCow3NotLazyQMP(TestQMP):
59
+# @iter-time: Optional (for activation only)
61
class TestQCow3LazyQMP(TestQMP):
60
+# Number of milliseconds to spend in
62
'''Testing a qcow2 version 3 image with lazy refcounts enabled, opening
61
+# PBKDF passphrase processing for the newly activated keyslot.
63
with lazy refcounts disabled'''
62
+# Currently defaults to 2000.
64
- img_options = 'compat=1.1,lazy_refcounts=on'
63
+#
65
+ img_options = 'compat=1.1,lazy_refcounts=on,compression_type=zstd'
64
+# @keyslot: Optional. ID of the keyslot to activate/deactivate.
66
qemu_options = 'lazy-refcounts=off'
65
+# For keyslot activation, keyslot should not be active already
67
compare = { 'compat': '1.1', 'lazy-refcounts': True,
66
+# (this is unsafe to update an active keyslot),
68
'refcount-bits': 16, 'corrupt': False,
67
+# but possible if 'force' parameter is given.
69
- 'compression-type': 'zlib', 'extended-l2': False }
68
+# If keyslot is not given, first free keyslot will be written.
70
+ 'compression-type': 'zstd', 'extended-l2': False }
69
+#
71
70
+# For keyslot deactivation, this parameter specifies the exact
72
TestImageInfoSpecific = None
71
+# keyslot to deactivate
73
TestQemuImgInfo = None
72
+#
73
+# @secret: Optional. The ID of a QCryptoSecret object providing the
74
+# password to use to retrive current master key.
75
+# Defaults to the same secret that was used to open the image
76
+#
77
+#
78
+# Since 5.1
79
+##
80
+{ 'struct': 'QCryptoBlockAmendOptionsLUKS',
81
+ 'data': { 'state': 'QCryptoBlockLUKSKeyslotState',
82
+ '*new-secret': 'str',
83
+ '*old-secret': 'str',
84
+ '*keyslot': 'int',
85
+ '*iter-time': 'int',
86
+ '*secret': 'str' } }
87
88
##
89
# @QCryptoBlockAmendOptions:
90
@@ -XXX,XX +XXX,XX @@
91
'base': 'QCryptoBlockOptionsBase',
92
'discriminator': 'format',
93
'data': {
94
- } }
95
+ 'luks': 'QCryptoBlockAmendOptionsLUKS' } }
96
diff --git a/crypto/block-luks.c b/crypto/block-luks.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/crypto/block-luks.c
99
+++ b/crypto/block-luks.c
100
@@ -XXX,XX +XXX,XX @@
101
#include "qemu/uuid.h"
102
103
#include "qemu/coroutine.h"
104
+#include "qemu/bitmap.h"
105
106
/*
107
* Reference for the LUKS format implemented here is
108
@@ -XXX,XX +XXX,XX @@ typedef struct QCryptoBlockLUKSKeySlot QCryptoBlockLUKSKeySlot;
109
110
#define QCRYPTO_BLOCK_LUKS_SECTOR_SIZE 512LL
111
112
+#define QCRYPTO_BLOCK_LUKS_DEFAULT_ITER_TIME_MS 2000
113
+#define QCRYPTO_BLOCK_LUKS_ERASE_ITERATIONS 40
114
+
115
static const char qcrypto_block_luks_magic[QCRYPTO_BLOCK_LUKS_MAGIC_LEN] = {
116
'L', 'U', 'K', 'S', 0xBA, 0xBE
117
};
118
@@ -XXX,XX +XXX,XX @@ struct QCryptoBlockLUKS {
119
120
/* Hash algorithm used in pbkdf2 function */
121
QCryptoHashAlgorithm hash_alg;
122
+
123
+ /* Name of the secret that was used to open the image */
124
+ char *secret;
125
};
126
127
128
@@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_store_key(QCryptoBlock *block,
129
Error **errp)
130
{
131
QCryptoBlockLUKS *luks = block->opaque;
132
- QCryptoBlockLUKSKeySlot *slot = &luks->header.key_slots[slot_idx];
133
+ QCryptoBlockLUKSKeySlot *slot;
134
g_autofree uint8_t *splitkey = NULL;
135
size_t splitkeylen;
136
g_autofree uint8_t *slotkey = NULL;
137
@@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_store_key(QCryptoBlock *block,
138
uint64_t iters;
139
int ret = -1;
140
141
+ assert(slot_idx < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS);
142
+ slot = &luks->header.key_slots[slot_idx];
143
if (qcrypto_random_bytes(slot->salt,
144
QCRYPTO_BLOCK_LUKS_SALT_LEN,
145
errp) < 0) {
146
@@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_load_key(QCryptoBlock *block,
147
Error **errp)
148
{
149
QCryptoBlockLUKS *luks = block->opaque;
150
- const QCryptoBlockLUKSKeySlot *slot = &luks->header.key_slots[slot_idx];
151
+ const QCryptoBlockLUKSKeySlot *slot;
152
g_autofree uint8_t *splitkey = NULL;
153
size_t splitkeylen;
154
g_autofree uint8_t *possiblekey = NULL;
155
@@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_load_key(QCryptoBlock *block,
156
g_autoptr(QCryptoIVGen) ivgen = NULL;
157
size_t niv;
158
159
+ assert(slot_idx < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS);
160
+ slot = &luks->header.key_slots[slot_idx];
161
if (slot->active != QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED) {
162
return 0;
163
}
164
@@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_find_key(QCryptoBlock *block,
165
return -1;
166
}
167
168
+/*
169
+ * Returns true if a slot i is marked as active
170
+ * (contains encrypted copy of the master key)
171
+ */
172
+static bool
173
+qcrypto_block_luks_slot_active(const QCryptoBlockLUKS *luks,
174
+ unsigned int slot_idx)
175
+{
176
+ uint32_t val;
177
+
178
+ assert(slot_idx < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS);
179
+ val = luks->header.key_slots[slot_idx].active;
180
+ return val == QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED;
181
+}
182
+
183
+/*
184
+ * Returns the number of slots that are marked as active
185
+ * (slots that contain encrypted copy of the master key)
186
+ */
187
+static unsigned int
188
+qcrypto_block_luks_count_active_slots(const QCryptoBlockLUKS *luks)
189
+{
190
+ size_t i = 0;
191
+ unsigned int ret = 0;
192
+
193
+ for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) {
194
+ if (qcrypto_block_luks_slot_active(luks, i)) {
195
+ ret++;
196
+ }
197
+ }
198
+ return ret;
199
+}
200
+
201
+/*
202
+ * Finds first key slot which is not active
203
+ * Returns the key slot index, or -1 if it doesn't exist
204
+ */
205
+static int
206
+qcrypto_block_luks_find_free_keyslot(const QCryptoBlockLUKS *luks)
207
+{
208
+ size_t i;
209
+
210
+ for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) {
211
+ if (!qcrypto_block_luks_slot_active(luks, i)) {
212
+ return i;
213
+ }
214
+ }
215
+ return -1;
216
+}
217
+
218
+/*
219
+ * Erases an keyslot given its index
220
+ * Returns:
221
+ * 0 if the keyslot was erased successfully
222
+ * -1 if a error occurred while erasing the keyslot
223
+ *
224
+ */
225
+static int
226
+qcrypto_block_luks_erase_key(QCryptoBlock *block,
227
+ unsigned int slot_idx,
228
+ QCryptoBlockWriteFunc writefunc,
229
+ void *opaque,
230
+ Error **errp)
231
+{
232
+ QCryptoBlockLUKS *luks = block->opaque;
233
+ QCryptoBlockLUKSKeySlot *slot;
234
+ g_autofree uint8_t *garbagesplitkey = NULL;
235
+ size_t splitkeylen;
236
+ size_t i;
237
+ Error *local_err = NULL;
238
+ int ret;
239
+
240
+ assert(slot_idx < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS);
241
+ slot = &luks->header.key_slots[slot_idx];
242
+
243
+ splitkeylen = luks->header.master_key_len * slot->stripes;
244
+ assert(splitkeylen > 0);
245
+
246
+ garbagesplitkey = g_new0(uint8_t, splitkeylen);
247
+
248
+ /* Reset the key slot header */
249
+ memset(slot->salt, 0, QCRYPTO_BLOCK_LUKS_SALT_LEN);
250
+ slot->iterations = 0;
251
+ slot->active = QCRYPTO_BLOCK_LUKS_KEY_SLOT_DISABLED;
252
+
253
+ ret = qcrypto_block_luks_store_header(block, writefunc,
254
+ opaque, &local_err);
255
+
256
+ if (ret < 0) {
257
+ error_propagate(errp, local_err);
258
+ }
259
+ /*
260
+ * Now try to erase the key material, even if the header
261
+ * update failed
262
+ */
263
+ for (i = 0; i < QCRYPTO_BLOCK_LUKS_ERASE_ITERATIONS; i++) {
264
+ if (qcrypto_random_bytes(garbagesplitkey,
265
+ splitkeylen, &local_err) < 0) {
266
+ /*
267
+ * If we failed to get the random data, still write
268
+ * at least zeros to the key slot at least once
269
+ */
270
+ error_propagate(errp, local_err);
271
+
272
+ if (i > 0) {
273
+ return -1;
274
+ }
275
+ }
276
+ if (writefunc(block,
277
+ slot->key_offset_sector * QCRYPTO_BLOCK_LUKS_SECTOR_SIZE,
278
+ garbagesplitkey,
279
+ splitkeylen,
280
+ opaque,
281
+ &local_err) != splitkeylen) {
282
+ error_propagate(errp, local_err);
283
+ return -1;
284
+ }
285
+ }
286
+ return ret;
287
+}
288
289
static int
290
qcrypto_block_luks_open(QCryptoBlock *block,
291
@@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_open(QCryptoBlock *block,
292
293
luks = g_new0(QCryptoBlockLUKS, 1);
294
block->opaque = luks;
295
+ luks->secret = g_strdup(options->u.luks.key_secret);
296
297
if (qcrypto_block_luks_load_header(block, readfunc, opaque, errp) < 0) {
298
goto fail;
299
@@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_open(QCryptoBlock *block,
300
fail:
301
qcrypto_block_free_cipher(block);
302
qcrypto_ivgen_free(block->ivgen);
303
+ g_free(luks->secret);
304
g_free(luks);
305
return -1;
306
}
307
@@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_create(QCryptoBlock *block,
308
309
memcpy(&luks_opts, &options->u.luks, sizeof(luks_opts));
310
if (!luks_opts.has_iter_time) {
311
- luks_opts.iter_time = 2000;
312
+ luks_opts.iter_time = QCRYPTO_BLOCK_LUKS_DEFAULT_ITER_TIME_MS;
313
}
314
if (!luks_opts.has_cipher_alg) {
315
luks_opts.cipher_alg = QCRYPTO_CIPHER_ALG_AES_256;
316
@@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_create(QCryptoBlock *block,
317
optprefix ? optprefix : "");
318
goto error;
319
}
320
+ luks->secret = g_strdup(options->u.luks.key_secret);
321
+
322
password = qcrypto_secret_lookup_as_utf8(luks_opts.key_secret, errp);
323
if (!password) {
324
goto error;
325
@@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_create(QCryptoBlock *block,
326
qcrypto_block_free_cipher(block);
327
qcrypto_ivgen_free(block->ivgen);
328
329
+ g_free(luks->secret);
330
g_free(luks);
331
return -1;
332
}
333
334
+static int
335
+qcrypto_block_luks_amend_add_keyslot(QCryptoBlock *block,
336
+ QCryptoBlockReadFunc readfunc,
337
+ QCryptoBlockWriteFunc writefunc,
338
+ void *opaque,
339
+ QCryptoBlockAmendOptionsLUKS *opts_luks,
340
+ bool force,
341
+ Error **errp)
342
+{
343
+ QCryptoBlockLUKS *luks = block->opaque;
344
+ uint64_t iter_time = opts_luks->has_iter_time ?
345
+ opts_luks->iter_time :
346
+ QCRYPTO_BLOCK_LUKS_DEFAULT_ITER_TIME_MS;
347
+ int keyslot;
348
+ g_autofree char *old_password = NULL;
349
+ g_autofree char *new_password = NULL;
350
+ g_autofree uint8_t *master_key = NULL;
351
+
352
+ char *secret = opts_luks->has_secret ? opts_luks->secret : luks->secret;
353
+
354
+ if (!opts_luks->has_new_secret) {
355
+ error_setg(errp, "'new-secret' is required to activate a keyslot");
356
+ return -1;
357
+ }
358
+ if (opts_luks->has_old_secret) {
359
+ error_setg(errp,
360
+ "'old-secret' must not be given when activating keyslots");
361
+ return -1;
362
+ }
363
+
364
+ if (opts_luks->has_keyslot) {
365
+ keyslot = opts_luks->keyslot;
366
+ if (keyslot < 0 || keyslot >= QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS) {
367
+ error_setg(errp,
368
+ "Invalid keyslot %u specified, must be between 0 and %u",
369
+ keyslot, QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS - 1);
370
+ return -1;
371
+ }
372
+ } else {
373
+ keyslot = qcrypto_block_luks_find_free_keyslot(luks);
374
+ if (keyslot == -1) {
375
+ error_setg(errp,
376
+ "Can't add a keyslot - all keyslots are in use");
377
+ return -1;
378
+ }
379
+ }
380
+
381
+ if (!force && qcrypto_block_luks_slot_active(luks, keyslot)) {
382
+ error_setg(errp,
383
+ "Refusing to overwrite active keyslot %i - "
384
+ "please erase it first",
385
+ keyslot);
386
+ return -1;
387
+ }
388
+
389
+ /* Locate the password that will be used to retrieve the master key */
390
+ old_password = qcrypto_secret_lookup_as_utf8(secret, errp);
391
+ if (!old_password) {
392
+ return -1;
393
+ }
394
+
395
+ /* Retrieve the master key */
396
+ master_key = g_new0(uint8_t, luks->header.master_key_len);
397
+
398
+ if (qcrypto_block_luks_find_key(block, old_password, master_key,
399
+ readfunc, opaque, errp) < 0) {
400
+ error_append_hint(errp, "Failed to retrieve the master key");
401
+ return -1;
402
+ }
403
+
404
+ /* Locate the new password*/
405
+ new_password = qcrypto_secret_lookup_as_utf8(opts_luks->new_secret, errp);
406
+ if (!new_password) {
407
+ return -1;
408
+ }
409
+
410
+ /* Now set the new keyslots */
411
+ if (qcrypto_block_luks_store_key(block, keyslot, new_password, master_key,
412
+ iter_time, writefunc, opaque, errp)) {
413
+ error_append_hint(errp, "Failed to write to keyslot %i", keyslot);
414
+ return -1;
415
+ }
416
+ return 0;
417
+}
418
+
419
+static int
420
+qcrypto_block_luks_amend_erase_keyslots(QCryptoBlock *block,
421
+ QCryptoBlockReadFunc readfunc,
422
+ QCryptoBlockWriteFunc writefunc,
423
+ void *opaque,
424
+ QCryptoBlockAmendOptionsLUKS *opts_luks,
425
+ bool force,
426
+ Error **errp)
427
+{
428
+ QCryptoBlockLUKS *luks = block->opaque;
429
+ g_autofree uint8_t *tmpkey = NULL;
430
+ g_autofree char *old_password = NULL;
431
+
432
+ if (opts_luks->has_new_secret) {
433
+ error_setg(errp,
434
+ "'new-secret' must not be given when erasing keyslots");
435
+ return -1;
436
+ }
437
+ if (opts_luks->has_iter_time) {
438
+ error_setg(errp,
439
+ "'iter-time' must not be given when erasing keyslots");
440
+ return -1;
441
+ }
442
+ if (opts_luks->has_secret) {
443
+ error_setg(errp,
444
+ "'secret' must not be given when erasing keyslots");
445
+ return -1;
446
+ }
447
+
448
+ /* Load the old password if given */
449
+ if (opts_luks->has_old_secret) {
450
+ old_password = qcrypto_secret_lookup_as_utf8(opts_luks->old_secret,
451
+ errp);
452
+ if (!old_password) {
453
+ return -1;
454
+ }
455
+
456
+ /*
457
+ * Allocate a temporary key buffer that we will need when
458
+ * checking if slot matches the given old password
459
+ */
460
+ tmpkey = g_new0(uint8_t, luks->header.master_key_len);
461
+ }
462
+
463
+ /* Erase an explicitly given keyslot */
464
+ if (opts_luks->has_keyslot) {
465
+ int keyslot = opts_luks->keyslot;
466
+
467
+ if (keyslot < 0 || keyslot >= QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS) {
468
+ error_setg(errp,
469
+ "Invalid keyslot %i specified, must be between 0 and %i",
470
+ keyslot, QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS - 1);
471
+ return -1;
472
+ }
473
+
474
+ if (opts_luks->has_old_secret) {
475
+ int rv = qcrypto_block_luks_load_key(block,
476
+ keyslot,
477
+ old_password,
478
+ tmpkey,
479
+ readfunc,
480
+ opaque,
481
+ errp);
482
+ if (rv == -1) {
483
+ return -1;
484
+ } else if (rv == 0) {
485
+ error_setg(errp,
486
+ "Given keyslot %i doesn't contain the given "
487
+ "old password for erase operation",
488
+ keyslot);
489
+ return -1;
490
+ }
491
+ }
492
+
493
+ if (!force && !qcrypto_block_luks_slot_active(luks, keyslot)) {
494
+ error_setg(errp,
495
+ "Given keyslot %i is already erased (inactive) ",
496
+ keyslot);
497
+ return -1;
498
+ }
499
+
500
+ if (!force && qcrypto_block_luks_count_active_slots(luks) == 1) {
501
+ error_setg(errp,
502
+ "Attempt to erase the only active keyslot %i "
503
+ "which will erase all the data in the image "
504
+ "irreversibly - refusing operation",
505
+ keyslot);
506
+ return -1;
507
+ }
508
+
509
+ if (qcrypto_block_luks_erase_key(block, keyslot,
510
+ writefunc, opaque, errp)) {
511
+ error_append_hint(errp, "Failed to erase keyslot %i", keyslot);
512
+ return -1;
513
+ }
514
+
515
+ /* Erase all keyslots that match the given old password */
516
+ } else if (opts_luks->has_old_secret) {
517
+
518
+ unsigned long slots_to_erase_bitmap = 0;
519
+ size_t i;
520
+ int slot_count;
521
+
522
+ assert(QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS <=
523
+ sizeof(slots_to_erase_bitmap) * 8);
524
+
525
+ for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) {
526
+ int rv = qcrypto_block_luks_load_key(block,
527
+ i,
528
+ old_password,
529
+ tmpkey,
530
+ readfunc,
531
+ opaque,
532
+ errp);
533
+ if (rv == -1) {
534
+ return -1;
535
+ } else if (rv == 1) {
536
+ bitmap_set(&slots_to_erase_bitmap, i, 1);
537
+ }
538
+ }
539
+
540
+ slot_count = bitmap_count_one(&slots_to_erase_bitmap,
541
+ QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS);
542
+ if (slot_count == 0) {
543
+ error_setg(errp,
544
+ "No keyslots match given (old) password for erase operation");
545
+ return -1;
546
+ }
547
+
548
+ if (!force &&
549
+ slot_count == qcrypto_block_luks_count_active_slots(luks)) {
550
+ error_setg(errp,
551
+ "All the active keyslots match the (old) password that "
552
+ "was given and erasing them will erase all the data in "
553
+ "the image irreversibly - refusing operation");
554
+ return -1;
555
+ }
556
+
557
+ /* Now apply the update */
558
+ for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) {
559
+ if (!test_bit(i, &slots_to_erase_bitmap)) {
560
+ continue;
561
+ }
562
+ if (qcrypto_block_luks_erase_key(block, i, writefunc,
563
+ opaque, errp)) {
564
+ error_append_hint(errp, "Failed to erase keyslot %zu", i);
565
+ return -1;
566
+ }
567
+ }
568
+ } else {
569
+ error_setg(errp,
570
+ "To erase keyslot(s), either explicit keyslot index "
571
+ "or the password currently contained in them must be given");
572
+ return -1;
573
+ }
574
+ return 0;
575
+}
576
+
577
+static int
578
+qcrypto_block_luks_amend_options(QCryptoBlock *block,
579
+ QCryptoBlockReadFunc readfunc,
580
+ QCryptoBlockWriteFunc writefunc,
581
+ void *opaque,
582
+ QCryptoBlockAmendOptions *options,
583
+ bool force,
584
+ Error **errp)
585
+{
586
+ QCryptoBlockAmendOptionsLUKS *opts_luks = &options->u.luks;
587
+
588
+ switch (opts_luks->state) {
589
+ case Q_CRYPTO_BLOCKLUKS_KEYSLOT_STATE_ACTIVE:
590
+ return qcrypto_block_luks_amend_add_keyslot(block, readfunc,
591
+ writefunc, opaque,
592
+ opts_luks, force, errp);
593
+ case Q_CRYPTO_BLOCKLUKS_KEYSLOT_STATE_INACTIVE:
594
+ return qcrypto_block_luks_amend_erase_keyslots(block, readfunc,
595
+ writefunc, opaque,
596
+ opts_luks, force, errp);
597
+ default:
598
+ g_assert_not_reached();
599
+ }
600
+}
601
602
static int qcrypto_block_luks_get_info(QCryptoBlock *block,
603
QCryptoBlockInfo *info,
604
@@ -XXX,XX +XXX,XX @@ static int qcrypto_block_luks_get_info(QCryptoBlock *block,
605
606
static void qcrypto_block_luks_cleanup(QCryptoBlock *block)
607
{
608
- g_free(block->opaque);
609
+ QCryptoBlockLUKS *luks = block->opaque;
610
+ if (luks) {
611
+ g_free(luks->secret);
612
+ g_free(luks);
613
+ }
614
}
615
616
617
@@ -XXX,XX +XXX,XX @@ qcrypto_block_luks_encrypt(QCryptoBlock *block,
618
const QCryptoBlockDriver qcrypto_block_driver_luks = {
619
.open = qcrypto_block_luks_open,
620
.create = qcrypto_block_luks_create,
621
+ .amend = qcrypto_block_luks_amend_options,
622
.get_info = qcrypto_block_luks_get_info,
623
.cleanup = qcrypto_block_luks_cleanup,
624
.decrypt = qcrypto_block_luks_decrypt,
625
--
74
--
626
2.26.2
75
2.34.1
627
76
628
77
diff view generated by jsdifflib
1
From: Maxim Levitsky <mlevitsk@redhat.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
Some qcow2 create options can't be used for amend.
3
The only "feature" of this "Formatting ..." line is that we have to
4
Remove them from the qcow2 create options and add generic logic to detect
4
update it every time we add new option. Let's drop it.
5
such options in qemu-img
6
5
7
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
7
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
9
Message-Id: <20200608094030.670121-6-mlevitsk@redhat.com>
8
Message-Id: <20211223160144.1097696-10-vsementsov@virtuozzo.com>
10
[mreitz: Dropped some iotests reference output hunks that became
9
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
11
unnecessary thanks to
12
"iotests: Make _filter_img_create more active"]
13
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
---
10
---
15
block/qcow2.c | 138 +++++++++-----------------------
11
tests/qemu-iotests/149.out | 21 ---------------------
16
qemu-img.c | 18 ++++-
12
tests/qemu-iotests/237.out | 3 ---
17
tests/qemu-iotests/049.out | 102 ++++++++++++------------
13
tests/qemu-iotests/255.out | 4 ----
18
tests/qemu-iotests/061.out | 12 ++-
14
tests/qemu-iotests/274.out | 29 -----------------------------
19
tests/qemu-iotests/082.out | 158 ++++---------------------------------
15
tests/qemu-iotests/280.out | 1 -
20
tests/qemu-iotests/085.out | 38 ++++-----
16
tests/qemu-iotests/296.out | 10 +++-------
21
tests/qemu-iotests/144.out | 4 +-
17
tests/qemu-iotests/iotests.py | 10 ++++++++--
22
tests/qemu-iotests/182.out | 2 +-
18
7 files changed, 11 insertions(+), 67 deletions(-)
23
tests/qemu-iotests/185.out | 8 +-
24
tests/qemu-iotests/255.out | 8 +-
25
tests/qemu-iotests/274.out | 46 +++++------
26
tests/qemu-iotests/280.out | 2 +-
27
12 files changed, 183 insertions(+), 353 deletions(-)
28
19
29
diff --git a/block/qcow2.c b/block/qcow2.c
20
diff --git a/tests/qemu-iotests/149.out b/tests/qemu-iotests/149.out
30
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
31
--- a/block/qcow2.c
22
--- a/tests/qemu-iotests/149.out
32
+++ b/block/qcow2.c
23
+++ b/tests/qemu-iotests/149.out
33
@@ -XXX,XX +XXX,XX @@ static int qcow2_change_backing_file(BlockDriverState *bs,
24
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-xts-plain64-sha1.img
34
return qcow2_update_header(bs);
25
# ================= qemu-img aes-256-xts-plain64-sha1 =================
35
}
26
# Create image
36
27
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
37
-static int qcow2_crypt_method_from_format(const char *encryptfmt)
28
-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
38
-{
29
39
- if (g_str_equal(encryptfmt, "luks")) {
30
# Open dev
40
- return QCOW_CRYPT_LUKS;
31
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha1.img qiotest-145-aes-256-xts-plain64-sha1
41
- } else if (g_str_equal(encryptfmt, "aes")) {
32
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-twofish-256-xts-plain64-sha1.img
42
- return QCOW_CRYPT_AES;
33
# ================= qemu-img twofish-256-xts-plain64-sha1 =================
43
- } else {
34
# Create image
44
- return -EINVAL;
35
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
45
- }
36
-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
46
-}
37
47
-
38
# Open dev
48
static int qcow2_set_up_encryption(BlockDriverState *bs,
39
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-twofish-256-xts-plain64-sha1.img qiotest-145-twofish-256-xts-plain64-sha1
49
QCryptoBlockCreateOptions *cryptoopts,
40
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-serpent-256-xts-plain64-sha1.img
50
Error **errp)
41
# ================= qemu-img serpent-256-xts-plain64-sha1 =================
51
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
42
# Create image
52
bool lazy_refcounts = s->use_lazy_refcounts;
43
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
53
bool data_file_raw = data_file_is_raw(bs);
44
-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
54
const char *compat = NULL;
45
55
- uint64_t cluster_size = s->cluster_size;
46
# Open dev
56
- bool encrypt;
47
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-serpent-256-xts-plain64-sha1.img qiotest-145-serpent-256-xts-plain64-sha1
57
- int encformat;
48
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-cast5-128-cbc-plain64-sha1.img
58
int refcount_bits = s->refcount_bits;
49
# ================= qemu-img cast5-128-cbc-plain64-sha1 =================
59
int ret;
50
# Create image
60
QemuOptDesc *desc = opts->list->desc;
51
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
61
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
52
-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
62
error_setg(errp, "Unknown compatibility level %s", compat);
53
63
return -EINVAL;
54
# Open dev
64
}
55
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-cast5-128-cbc-plain64-sha1.img qiotest-145-cast5-128-cbc-plain64-sha1
65
- } else if (!strcmp(desc->name, BLOCK_OPT_PREALLOC)) {
56
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-cbc-plain-sha1.img
66
- error_setg(errp, "Cannot change preallocation mode");
57
# ================= qemu-img aes-256-cbc-plain-sha1 =================
67
- return -ENOTSUP;
58
# Create image
68
} else if (!strcmp(desc->name, BLOCK_OPT_SIZE)) {
59
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
69
new_size = qemu_opt_get_size(opts, BLOCK_OPT_SIZE, 0);
60
-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
70
} else if (!strcmp(desc->name, BLOCK_OPT_BACKING_FILE)) {
61
71
backing_file = qemu_opt_get(opts, BLOCK_OPT_BACKING_FILE);
62
# Open dev
72
} else if (!strcmp(desc->name, BLOCK_OPT_BACKING_FMT)) {
63
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-plain-sha1.img qiotest-145-aes-256-cbc-plain-sha1
73
backing_format = qemu_opt_get(opts, BLOCK_OPT_BACKING_FMT);
64
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-cbc-plain64-sha1.img
74
- } else if (!strcmp(desc->name, BLOCK_OPT_ENCRYPT)) {
65
# ================= qemu-img aes-256-cbc-plain64-sha1 =================
75
- encrypt = qemu_opt_get_bool(opts, BLOCK_OPT_ENCRYPT,
66
# Create image
76
- !!s->crypto);
67
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
77
-
68
-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
78
- if (encrypt != !!s->crypto) {
69
79
- error_setg(errp,
70
# Open dev
80
- "Changing the encryption flag is not supported");
71
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-plain64-sha1.img qiotest-145-aes-256-cbc-plain64-sha1
81
- return -ENOTSUP;
72
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-cbc-essiv-sha256-sha1.img
82
- }
73
# ================= qemu-img aes-256-cbc-essiv-sha256-sha1 =================
83
- } else if (!strcmp(desc->name, BLOCK_OPT_ENCRYPT_FORMAT)) {
74
# Create image
84
- encformat = qcow2_crypt_method_from_format(
75
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
85
- qemu_opt_get(opts, BLOCK_OPT_ENCRYPT_FORMAT));
76
-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
86
-
77
87
- if (encformat != s->crypt_method_header) {
78
# Open dev
88
- error_setg(errp,
79
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-essiv-sha256-sha1.img qiotest-145-aes-256-cbc-essiv-sha256-sha1
89
- "Changing the encryption format is not supported");
80
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-xts-essiv-sha256-sha1.img
90
- return -ENOTSUP;
81
# ================= qemu-img aes-256-xts-essiv-sha256-sha1 =================
91
- }
82
# Create image
92
- } else if (g_str_has_prefix(desc->name, "encrypt.")) {
83
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
93
- error_setg(errp,
84
-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
94
- "Changing the encryption parameters is not supported");
85
95
- return -ENOTSUP;
86
# Open dev
96
- } else if (!strcmp(desc->name, BLOCK_OPT_CLUSTER_SIZE)) {
87
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-essiv-sha256-sha1.img qiotest-145-aes-256-xts-essiv-sha256-sha1
97
- cluster_size = qemu_opt_get_size(opts, BLOCK_OPT_CLUSTER_SIZE,
88
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-128-xts-plain64-sha256-sha1.img
98
- cluster_size);
89
# ================= qemu-img aes-128-xts-plain64-sha256-sha1 =================
99
- if (cluster_size != s->cluster_size) {
90
# Create image
100
- error_setg(errp, "Changing the cluster size is not supported");
91
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
101
- return -ENOTSUP;
92
-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
102
- }
93
103
} else if (!strcmp(desc->name, BLOCK_OPT_LAZY_REFCOUNTS)) {
94
# Open dev
104
lazy_refcounts = qemu_opt_get_bool(opts, BLOCK_OPT_LAZY_REFCOUNTS,
95
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-128-xts-plain64-sha256-sha1.img qiotest-145-aes-128-xts-plain64-sha256-sha1
105
lazy_refcounts);
96
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-192-xts-plain64-sha256-sha1.img
106
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
97
# ================= qemu-img aes-192-xts-plain64-sha256-sha1 =================
107
"images");
98
# Create image
108
return -EINVAL;
99
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
109
}
100
-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
110
- } else if (!strcmp(desc->name, BLOCK_OPT_COMPRESSION_TYPE)) {
101
111
- const char *ct_name =
102
# Open dev
112
- qemu_opt_get(opts, BLOCK_OPT_COMPRESSION_TYPE);
103
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-192-xts-plain64-sha256-sha1.img qiotest-145-aes-192-xts-plain64-sha256-sha1
113
- int compression_type =
104
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-twofish-128-xts-plain64-sha1.img
114
- qapi_enum_parse(&Qcow2CompressionType_lookup, ct_name, -1,
105
# ================= qemu-img twofish-128-xts-plain64-sha1 =================
115
- NULL);
106
# Create image
116
- if (compression_type == -1) {
107
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
117
- error_setg(errp, "Unknown compression type: %s", ct_name);
108
-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
118
- return -ENOTSUP;
109
119
- }
110
# Open dev
120
-
111
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-twofish-128-xts-plain64-sha1.img qiotest-145-twofish-128-xts-plain64-sha1
121
- if (compression_type != s->compression_type) {
112
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-serpent-128-xts-plain64-sha1.img
122
- error_setg(errp, "Changing the compression type "
113
# ================= qemu-img serpent-128-xts-plain64-sha1 =================
123
- "is not supported");
114
# Create image
124
- return -ENOTSUP;
115
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
125
- }
116
-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
126
} else {
117
127
/* if this point is reached, this probably means a new option was
118
# Open dev
128
* added without having it covered here */
119
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-serpent-128-xts-plain64-sha1.img qiotest-145-serpent-128-xts-plain64-sha1
129
@@ -XXX,XX +XXX,XX @@ void qcow2_signal_corruption(BlockDriverState *bs, bool fatal, int64_t offset,
120
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-serpent-192-xts-plain64-sha1.img
130
.help = "The external data file must stay valid " \
121
# ================= qemu-img serpent-192-xts-plain64-sha1 =================
131
"as a raw image" \
122
# Create image
132
}, \
123
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
133
- { \
124
-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
134
- .name = BLOCK_OPT_ENCRYPT, \
125
135
- .type = QEMU_OPT_BOOL, \
126
# Open dev
136
- .help = "Encrypt the image with format 'aes'. (Deprecated " \
127
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-serpent-192-xts-plain64-sha1.img qiotest-145-serpent-192-xts-plain64-sha1
137
- "in favor of " BLOCK_OPT_ENCRYPT_FORMAT "=aes)", \
128
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-xts-plain64-sha224.img
138
- }, \
129
# ================= qemu-img aes-256-xts-plain64-sha224 =================
139
- { \
130
# Create image
140
- .name = BLOCK_OPT_ENCRYPT_FORMAT, \
131
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
141
- .type = QEMU_OPT_STRING, \
132
-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
142
- .help = "Encrypt the image, format choices: 'aes', 'luks'", \
133
143
- }, \
134
# Open dev
144
- BLOCK_CRYPTO_OPT_DEF_KEY_SECRET("encrypt.", \
135
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha224.img qiotest-145-aes-256-xts-plain64-sha224
145
- "ID of secret providing qcow AES key or LUKS passphrase"), \
136
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-xts-plain64-sha256.img
146
- BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG("encrypt."), \
137
# ================= qemu-img aes-256-xts-plain64-sha256 =================
147
- BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE("encrypt."), \
138
# Create image
148
- BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG("encrypt."), \
139
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
149
- BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG("encrypt."), \
140
-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
150
- BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG("encrypt."), \
141
151
- BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME("encrypt."), \
142
# Open dev
152
- { \
143
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha256.img qiotest-145-aes-256-xts-plain64-sha256
153
- .name = BLOCK_OPT_CLUSTER_SIZE, \
144
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-xts-plain64-sha384.img
154
- .type = QEMU_OPT_SIZE, \
145
# ================= qemu-img aes-256-xts-plain64-sha384 =================
155
- .help = "qcow2 cluster size", \
146
# Create image
156
- .def_value_str = stringify(DEFAULT_CLUSTER_SIZE) \
147
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
157
- }, \
148
-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
158
- { \
149
159
- .name = BLOCK_OPT_PREALLOC, \
150
# Open dev
160
- .type = QEMU_OPT_STRING, \
151
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha384.img qiotest-145-aes-256-xts-plain64-sha384
161
- .help = "Preallocation mode (allowed values: off, " \
152
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-xts-plain64-sha512.img
162
- "metadata, falloc, full)" \
153
# ================= qemu-img aes-256-xts-plain64-sha512 =================
163
- }, \
154
# Create image
164
{ \
155
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
165
.name = BLOCK_OPT_LAZY_REFCOUNTS, \
156
-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
166
.type = QEMU_OPT_BOOL, \
157
167
@@ -XXX,XX +XXX,XX @@ void qcow2_signal_corruption(BlockDriverState *bs, bool fatal, int64_t offset,
158
# Open dev
168
.type = QEMU_OPT_NUMBER, \
159
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-sha512.img qiotest-145-aes-256-xts-plain64-sha512
169
.help = "Width of a reference count entry in bits", \
160
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img
170
.def_value_str = "16" \
161
# ================= qemu-img aes-256-xts-plain64-ripemd160 =================
171
- }, \
162
# Create image
172
- { \
163
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
173
- .name = BLOCK_OPT_COMPRESSION_TYPE, \
164
-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
174
- .type = QEMU_OPT_STRING, \
165
175
- .help = "Compression method used for image cluster " \
166
# Open dev
176
- "compression", \
167
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain64-ripemd160.img qiotest-145-aes-256-xts-plain64-ripemd160
177
- .def_value_str = "zlib" \
168
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img
178
}
169
# ================= qemu-img aes-256-xts-plain-sha1-pwallslots =================
179
170
# Create image
180
static QemuOptsList qcow2_create_opts = {
171
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
181
.name = "qcow2-create-opts",
172
-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
182
.head = QTAILQ_HEAD_INITIALIZER(qcow2_create_opts.head),
173
183
.desc = {
174
# Open dev
184
+ { \
175
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-xts-plain-sha1-pwallslots.img qiotest-145-aes-256-xts-plain-sha1-pwallslots
185
+ .name = BLOCK_OPT_ENCRYPT, \
176
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img
186
+ .type = QEMU_OPT_BOOL, \
177
# ================= qemu-img aes-256-cbc-essiv-auto-sha1 =================
187
+ .help = "Encrypt the image with format 'aes'. (Deprecated " \
178
# Create image
188
+ "in favor of " BLOCK_OPT_ENCRYPT_FORMAT "=aes)", \
179
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
189
+ }, \
180
-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
190
+ { \
181
191
+ .name = BLOCK_OPT_ENCRYPT_FORMAT, \
182
# Open dev
192
+ .type = QEMU_OPT_STRING, \
183
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-essiv-auto-sha1.img qiotest-145-aes-256-cbc-essiv-auto-sha1
193
+ .help = "Encrypt the image, format choices: 'aes', 'luks'", \
184
@@ -XXX,XX +XXX,XX @@ unlink TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img
194
+ }, \
185
# ================= qemu-img aes-256-cbc-plain64-sha256-sha1 =================
195
+ BLOCK_CRYPTO_OPT_DEF_KEY_SECRET("encrypt.", \
186
# Create image
196
+ "ID of secret providing qcow AES key or LUKS passphrase"), \
187
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
197
+ BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG("encrypt."), \
188
-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
198
+ BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE("encrypt."), \
189
199
+ BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG("encrypt."), \
190
# Open dev
200
+ BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG("encrypt."), \
191
sudo cryptsetup -q -v luksOpen TEST_DIR/luks-aes-256-cbc-plain64-sha256-sha1.img qiotest-145-aes-256-cbc-plain64-sha256-sha1
201
+ BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG("encrypt."), \
192
diff --git a/tests/qemu-iotests/237.out b/tests/qemu-iotests/237.out
202
+ BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME("encrypt."), \
193
index XXXXXXX..XXXXXXX 100644
203
+ { \
194
--- a/tests/qemu-iotests/237.out
204
+ .name = BLOCK_OPT_CLUSTER_SIZE, \
195
+++ b/tests/qemu-iotests/237.out
205
+ .type = QEMU_OPT_SIZE, \
196
@@ -XXX,XX +XXX,XX @@ Job failed: Cannot find device='this doesn't exist' nor node-name='this doesn't
206
+ .help = "qcow2 cluster size", \
197
207
+ .def_value_str = stringify(DEFAULT_CLUSTER_SIZE) \
198
=== Other subformats ===
208
+ }, \
199
209
+ { \
200
-Formatting 'TEST_DIR/PID-t.vmdk.1', fmt=vmdk size=0 compat6=off hwversion=undefined
210
+ .name = BLOCK_OPT_PREALLOC, \
201
211
+ .type = QEMU_OPT_STRING, \
202
-Formatting 'TEST_DIR/PID-t.vmdk.2', fmt=vmdk size=0 compat6=off hwversion=undefined
212
+ .help = "Preallocation mode (allowed values: off, " \
203
213
+ "metadata, falloc, full)" \
204
-Formatting 'TEST_DIR/PID-t.vmdk.3', fmt=vmdk size=0 compat6=off hwversion=undefined
214
+ }, \
205
215
+ { \
206
== Missing extent ==
216
+ .name = BLOCK_OPT_COMPRESSION_TYPE, \
207
217
+ .type = QEMU_OPT_STRING, \
218
+ .help = "Compression method used for image cluster " \
219
+ "compression", \
220
+ .def_value_str = "zlib" \
221
+ },
222
QCOW_COMMON_OPTIONS,
223
{ /* end of list */ }
224
}
225
diff --git a/qemu-img.c b/qemu-img.c
226
index XXXXXXX..XXXXXXX 100644
227
--- a/qemu-img.c
228
+++ b/qemu-img.c
229
@@ -XXX,XX +XXX,XX @@ static int print_amend_option_help(const char *format)
230
/* Every driver supporting amendment must have amend_opts */
231
assert(drv->amend_opts);
232
233
- printf("Creation options for '%s':\n", format);
234
+ printf("Amend options for '%s':\n", format);
235
qemu_opts_print_help(drv->amend_opts, false);
236
- printf("\nNote that not all of these options may be amendable.\n");
237
return 0;
238
}
239
240
@@ -XXX,XX +XXX,XX @@ static int img_amend(int argc, char **argv)
241
amend_opts = qemu_opts_append(amend_opts, bs->drv->amend_opts);
242
opts = qemu_opts_create(amend_opts, NULL, 0, &error_abort);
243
qemu_opts_do_parse(opts, options, NULL, &err);
244
+
245
if (err) {
246
+ /* Try to parse options using the create options */
247
+ Error *err1 = NULL;
248
+ amend_opts = qemu_opts_append(amend_opts, bs->drv->create_opts);
249
+ qemu_opts_del(opts);
250
+ opts = qemu_opts_create(amend_opts, NULL, 0, &error_abort);
251
+ qemu_opts_do_parse(opts, options, NULL, &err1);
252
+
253
+ if (!err1) {
254
+ error_append_hint(&err,
255
+ "This option is only supported for image creation\n");
256
+ } else {
257
+ error_free(err1);
258
+ }
259
+
260
error_report_err(err);
261
ret = -1;
262
goto out;
263
diff --git a/tests/qemu-iotests/049.out b/tests/qemu-iotests/049.out
264
index XXXXXXX..XXXXXXX 100644
265
--- a/tests/qemu-iotests/049.out
266
+++ b/tests/qemu-iotests/049.out
267
@@ -XXX,XX +XXX,XX @@ QA output created by 049
268
== 1. Traditional size parameter ==
269
270
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024
271
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
272
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
273
274
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024b
275
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
276
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
277
278
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1k
279
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
280
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
281
282
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1K
283
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
284
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
285
286
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1M
287
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1048576 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
288
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1048576 lazy_refcounts=off refcount_bits=16
289
290
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1G
291
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1073741824 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
292
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1073741824 lazy_refcounts=off refcount_bits=16
293
294
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1T
295
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1099511627776 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
296
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1099511627776 lazy_refcounts=off refcount_bits=16
297
298
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024.0
299
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
300
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
301
302
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024.0b
303
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
304
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
305
306
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5k
307
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
308
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16
309
310
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5K
311
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
312
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16
313
314
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5M
315
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1572864 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
316
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1572864 lazy_refcounts=off refcount_bits=16
317
318
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5G
319
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1610612736 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
320
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1610612736 lazy_refcounts=off refcount_bits=16
321
322
qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5T
323
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1649267441664 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
324
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1649267441664 lazy_refcounts=off refcount_bits=16
325
326
== 2. Specifying size via -o ==
327
328
qemu-img create -f qcow2 -o size=1024 TEST_DIR/t.qcow2
329
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
330
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
331
332
qemu-img create -f qcow2 -o size=1024b TEST_DIR/t.qcow2
333
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
334
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
335
336
qemu-img create -f qcow2 -o size=1k TEST_DIR/t.qcow2
337
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
338
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
339
340
qemu-img create -f qcow2 -o size=1K TEST_DIR/t.qcow2
341
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
342
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
343
344
qemu-img create -f qcow2 -o size=1M TEST_DIR/t.qcow2
345
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1048576 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
346
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1048576 lazy_refcounts=off refcount_bits=16
347
348
qemu-img create -f qcow2 -o size=1G TEST_DIR/t.qcow2
349
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1073741824 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
350
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1073741824 lazy_refcounts=off refcount_bits=16
351
352
qemu-img create -f qcow2 -o size=1T TEST_DIR/t.qcow2
353
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1099511627776 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
354
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1099511627776 lazy_refcounts=off refcount_bits=16
355
356
qemu-img create -f qcow2 -o size=1024.0 TEST_DIR/t.qcow2
357
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
358
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
359
360
qemu-img create -f qcow2 -o size=1024.0b TEST_DIR/t.qcow2
361
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
362
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16
363
364
qemu-img create -f qcow2 -o size=1.5k TEST_DIR/t.qcow2
365
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
366
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16
367
368
qemu-img create -f qcow2 -o size=1.5K TEST_DIR/t.qcow2
369
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
370
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16
371
372
qemu-img create -f qcow2 -o size=1.5M TEST_DIR/t.qcow2
373
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1572864 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
374
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1572864 lazy_refcounts=off refcount_bits=16
375
376
qemu-img create -f qcow2 -o size=1.5G TEST_DIR/t.qcow2
377
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1610612736 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
378
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1610612736 lazy_refcounts=off refcount_bits=16
379
380
qemu-img create -f qcow2 -o size=1.5T TEST_DIR/t.qcow2
381
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1649267441664 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
382
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1649267441664 lazy_refcounts=off refcount_bits=16
383
384
== 3. Invalid sizes ==
385
386
@@ -XXX,XX +XXX,XX @@ qemu-img: TEST_DIR/t.qcow2: The image size must be specified only once
387
== Check correct interpretation of suffixes for cluster size ==
388
389
qemu-img create -f qcow2 -o cluster_size=1024 TEST_DIR/t.qcow2 64M
390
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16 compression_type=zlib
391
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
392
393
qemu-img create -f qcow2 -o cluster_size=1024b TEST_DIR/t.qcow2 64M
394
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16 compression_type=zlib
395
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
396
397
qemu-img create -f qcow2 -o cluster_size=1k TEST_DIR/t.qcow2 64M
398
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16 compression_type=zlib
399
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
400
401
qemu-img create -f qcow2 -o cluster_size=1K TEST_DIR/t.qcow2 64M
402
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16 compression_type=zlib
403
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
404
405
qemu-img create -f qcow2 -o cluster_size=1M TEST_DIR/t.qcow2 64M
406
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1048576 lazy_refcounts=off refcount_bits=16 compression_type=zlib
407
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1048576 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
408
409
qemu-img create -f qcow2 -o cluster_size=1024.0 TEST_DIR/t.qcow2 64M
410
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16 compression_type=zlib
411
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
412
413
qemu-img create -f qcow2 -o cluster_size=1024.0b TEST_DIR/t.qcow2 64M
414
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16 compression_type=zlib
415
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
416
417
qemu-img create -f qcow2 -o cluster_size=0.5k TEST_DIR/t.qcow2 64M
418
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=512 lazy_refcounts=off refcount_bits=16 compression_type=zlib
419
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=512 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
420
421
qemu-img create -f qcow2 -o cluster_size=0.5K TEST_DIR/t.qcow2 64M
422
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=512 lazy_refcounts=off refcount_bits=16 compression_type=zlib
423
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=512 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
424
425
qemu-img create -f qcow2 -o cluster_size=0.5M TEST_DIR/t.qcow2 64M
426
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=524288 lazy_refcounts=off refcount_bits=16 compression_type=zlib
427
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=524288 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
428
429
== Check compat level option ==
430
431
qemu-img create -f qcow2 -o compat=0.10 TEST_DIR/t.qcow2 64M
432
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.10 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
433
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 compat=0.10 lazy_refcounts=off refcount_bits=16
434
435
qemu-img create -f qcow2 -o compat=1.1 TEST_DIR/t.qcow2 64M
436
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=1.1 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
437
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 compat=1.1 lazy_refcounts=off refcount_bits=16
438
439
qemu-img create -f qcow2 -o compat=0.42 TEST_DIR/t.qcow2 64M
440
qemu-img: TEST_DIR/t.qcow2: Invalid parameter '0.42'
441
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.42 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
442
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 compat=0.42 lazy_refcounts=off refcount_bits=16
443
444
qemu-img create -f qcow2 -o compat=foobar TEST_DIR/t.qcow2 64M
445
qemu-img: TEST_DIR/t.qcow2: Invalid parameter 'foobar'
446
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=foobar cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
447
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 compat=foobar lazy_refcounts=off refcount_bits=16
448
449
== Check preallocation option ==
450
451
qemu-img create -f qcow2 -o preallocation=off TEST_DIR/t.qcow2 64M
452
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=65536 preallocation=off lazy_refcounts=off refcount_bits=16 compression_type=zlib
453
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 preallocation=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
454
455
qemu-img create -f qcow2 -o preallocation=metadata TEST_DIR/t.qcow2 64M
456
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=65536 preallocation=metadata lazy_refcounts=off refcount_bits=16 compression_type=zlib
457
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 preallocation=metadata compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
458
459
qemu-img create -f qcow2 -o preallocation=1234 TEST_DIR/t.qcow2 64M
460
qemu-img: TEST_DIR/t.qcow2: Invalid parameter '1234'
461
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=65536 preallocation=1234 lazy_refcounts=off refcount_bits=16 compression_type=zlib
462
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 preallocation=1234 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
463
464
== Check encryption option ==
465
466
qemu-img create -f qcow2 -o encryption=off TEST_DIR/t.qcow2 64M
467
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
468
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 encryption=off cluster_size=65536 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
469
470
qemu-img create -f qcow2 --object secret,id=sec0,data=123456 -o encryption=on,encrypt.key-secret=sec0 TEST_DIR/t.qcow2 64M
471
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=on encrypt.key-secret=sec0 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
472
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 encryption=on encrypt.key-secret=sec0 cluster_size=65536 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
473
474
== Check lazy_refcounts option (only with v3) ==
475
476
qemu-img create -f qcow2 -o compat=1.1,lazy_refcounts=off TEST_DIR/t.qcow2 64M
477
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=1.1 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
478
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 compat=1.1 lazy_refcounts=off refcount_bits=16
479
480
qemu-img create -f qcow2 -o compat=1.1,lazy_refcounts=on TEST_DIR/t.qcow2 64M
481
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=1.1 cluster_size=65536 lazy_refcounts=on refcount_bits=16 compression_type=zlib
482
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 compat=1.1 lazy_refcounts=on refcount_bits=16
483
484
qemu-img create -f qcow2 -o compat=0.10,lazy_refcounts=off TEST_DIR/t.qcow2 64M
485
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.10 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
486
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 compat=0.10 lazy_refcounts=off refcount_bits=16
487
488
qemu-img create -f qcow2 -o compat=0.10,lazy_refcounts=on TEST_DIR/t.qcow2 64M
489
qemu-img: TEST_DIR/t.qcow2: Lazy refcounts only supported with compatibility level 1.1 and above (use version=v3 or greater)
490
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.10 cluster_size=65536 lazy_refcounts=on refcount_bits=16 compression_type=zlib
491
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 compat=0.10 lazy_refcounts=on refcount_bits=16
492
493
*** done
494
diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out
495
index XXXXXXX..XXXXXXX 100644
496
--- a/tests/qemu-iotests/061.out
497
+++ b/tests/qemu-iotests/061.out
498
@@ -XXX,XX +XXX,XX @@ qemu-img: Lazy refcounts only supported with compatibility level 1.1 and above (
499
qemu-img: Lazy refcounts only supported with compatibility level 1.1 and above (use compat=1.1 or greater)
500
qemu-img: Unknown compatibility level 0.42
501
qemu-img: Invalid parameter 'foo'
502
-qemu-img: Changing the cluster size is not supported
503
-qemu-img: Changing the encryption flag is not supported
504
-qemu-img: Cannot change preallocation mode
505
+qemu-img: Invalid parameter 'cluster_size'
506
+This option is only supported for image creation
507
+qemu-img: Invalid parameter 'encryption'
508
+This option is only supported for image creation
509
+qemu-img: Invalid parameter 'preallocation'
510
+This option is only supported for image creation
511
512
=== Testing correct handling of unset value ===
513
514
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
515
Should work:
516
Should not work:
517
-qemu-img: Changing the cluster size is not supported
518
+qemu-img: Invalid parameter 'cluster_size'
519
+This option is only supported for image creation
520
521
=== Testing zero expansion on inactive clusters ===
522
523
diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out
524
index XXXXXXX..XXXXXXX 100644
525
--- a/tests/qemu-iotests/082.out
526
+++ b/tests/qemu-iotests/082.out
527
@@ -XXX,XX +XXX,XX @@ QA output created by 082
528
=== create: Options specified more than once ===
529
530
Testing: create -f foo -f qcow2 TEST_DIR/t.qcow2 128M
531
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
532
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
533
image: TEST_DIR/t.IMGFMT
534
file format: IMGFMT
535
virtual size: 128 MiB (134217728 bytes)
536
cluster_size: 65536
537
538
Testing: create -f qcow2 -o cluster_size=4k -o lazy_refcounts=on TEST_DIR/t.qcow2 128M
539
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=4096 lazy_refcounts=on refcount_bits=16 compression_type=zlib
540
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=4096 compression_type=zlib size=134217728 lazy_refcounts=on refcount_bits=16
541
image: TEST_DIR/t.IMGFMT
542
file format: IMGFMT
543
virtual size: 128 MiB (134217728 bytes)
544
@@ -XXX,XX +XXX,XX @@ Format specific information:
545
corrupt: false
546
547
Testing: create -f qcow2 -o cluster_size=4k -o lazy_refcounts=on -o cluster_size=8k TEST_DIR/t.qcow2 128M
548
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=8192 lazy_refcounts=on refcount_bits=16 compression_type=zlib
549
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=8192 compression_type=zlib size=134217728 lazy_refcounts=on refcount_bits=16
550
image: TEST_DIR/t.IMGFMT
551
file format: IMGFMT
552
virtual size: 128 MiB (134217728 bytes)
553
@@ -XXX,XX +XXX,XX @@ Format specific information:
554
corrupt: false
555
556
Testing: create -f qcow2 -o cluster_size=4k,cluster_size=8k TEST_DIR/t.qcow2 128M
557
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=8192 lazy_refcounts=off refcount_bits=16 compression_type=zlib
558
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=8192 compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
559
image: TEST_DIR/t.IMGFMT
560
file format: IMGFMT
561
virtual size: 128 MiB (134217728 bytes)
562
@@ -XXX,XX +XXX,XX @@ Supported options:
563
size=<size> - Virtual disk size
564
565
Testing: create -f qcow2 -u -o backing_file=TEST_DIR/t.qcow2,,help TEST_DIR/t.qcow2 128M
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 compression_type=zlib
567
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/t.qcow2,,help lazy_refcounts=off refcount_bits=16
568
569
Testing: create -f qcow2 -u -o backing_file=TEST_DIR/t.qcow2,,? TEST_DIR/t.qcow2 128M
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 compression_type=zlib
571
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/t.qcow2,,? lazy_refcounts=off refcount_bits=16
572
573
Testing: create -f qcow2 -o backing_file=TEST_DIR/t.qcow2, -o help TEST_DIR/t.qcow2 128M
574
qemu-img: Invalid option list: backing_file=TEST_DIR/t.qcow2,
575
@@ -XXX,XX +XXX,XX @@ qemu-img: Format driver 'bochs' does not support image creation
576
=== convert: Options specified more than once ===
577
578
Testing: create -f qcow2 TEST_DIR/t.qcow2 128M
579
-Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
580
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
581
582
Testing: convert -f foo -f qcow2 TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
583
image: TEST_DIR/t.IMGFMT.base
584
@@ -XXX,XX +XXX,XX @@ cluster_size: 65536
585
=== amend: help for -o ===
586
587
Testing: amend -f qcow2 -o help TEST_DIR/t.qcow2
588
-Creation options for 'qcow2':
589
+Amend options for 'qcow2':
590
backing_file=<str> - File name of a base image
591
backing_fmt=<str> - Image format of the base image
592
- cluster_size=<size> - qcow2 cluster size
593
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
594
- compression_type=<str> - Compression method used for image cluster compression
595
data_file=<str> - File name of an external data file
596
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
597
- encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
598
- encrypt.cipher-mode=<str> - Name of encryption cipher mode
599
- encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
600
- encrypt.hash-alg=<str> - Name of encryption hash algorithm
601
- encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
602
- encrypt.ivgen-alg=<str> - Name of IV generator algorithm
603
- encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
604
- encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
605
- encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
606
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
607
- preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
608
refcount_bits=<num> - Width of a reference count entry in bits
609
size=<size> - Virtual disk size
610
611
-Note that not all of these options may be amendable.
612
-
613
Testing: amend -f qcow2 -o ? TEST_DIR/t.qcow2
614
-Creation options for 'qcow2':
615
+Amend options for 'qcow2':
616
backing_file=<str> - File name of a base image
617
backing_fmt=<str> - Image format of the base image
618
- cluster_size=<size> - qcow2 cluster size
619
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
620
- compression_type=<str> - Compression method used for image cluster compression
621
data_file=<str> - File name of an external data file
622
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
623
- encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
624
- encrypt.cipher-mode=<str> - Name of encryption cipher mode
625
- encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
626
- encrypt.hash-alg=<str> - Name of encryption hash algorithm
627
- encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
628
- encrypt.ivgen-alg=<str> - Name of IV generator algorithm
629
- encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
630
- encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
631
- encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
632
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
633
- preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
634
refcount_bits=<num> - Width of a reference count entry in bits
635
size=<size> - Virtual disk size
636
637
-Note that not all of these options may be amendable.
638
-
639
Testing: amend -f qcow2 -o cluster_size=4k,help TEST_DIR/t.qcow2
640
-Creation options for 'qcow2':
641
+Amend options for 'qcow2':
642
backing_file=<str> - File name of a base image
643
backing_fmt=<str> - Image format of the base image
644
- cluster_size=<size> - qcow2 cluster size
645
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
646
- compression_type=<str> - Compression method used for image cluster compression
647
data_file=<str> - File name of an external data file
648
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
649
- encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
650
- encrypt.cipher-mode=<str> - Name of encryption cipher mode
651
- encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
652
- encrypt.hash-alg=<str> - Name of encryption hash algorithm
653
- encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
654
- encrypt.ivgen-alg=<str> - Name of IV generator algorithm
655
- encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
656
- encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
657
- encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
658
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
659
- preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
660
refcount_bits=<num> - Width of a reference count entry in bits
661
size=<size> - Virtual disk size
662
663
-Note that not all of these options may be amendable.
664
-
665
Testing: amend -f qcow2 -o cluster_size=4k,? TEST_DIR/t.qcow2
666
-Creation options for 'qcow2':
667
+Amend options for 'qcow2':
668
backing_file=<str> - File name of a base image
669
backing_fmt=<str> - Image format of the base image
670
- cluster_size=<size> - qcow2 cluster size
671
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
672
- compression_type=<str> - Compression method used for image cluster compression
673
data_file=<str> - File name of an external data file
674
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
675
- encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
676
- encrypt.cipher-mode=<str> - Name of encryption cipher mode
677
- encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
678
- encrypt.hash-alg=<str> - Name of encryption hash algorithm
679
- encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
680
- encrypt.ivgen-alg=<str> - Name of IV generator algorithm
681
- encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
682
- encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
683
- encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
684
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
685
- preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
686
refcount_bits=<num> - Width of a reference count entry in bits
687
size=<size> - Virtual disk size
688
689
-Note that not all of these options may be amendable.
690
-
691
Testing: amend -f qcow2 -o help,cluster_size=4k TEST_DIR/t.qcow2
692
-Creation options for 'qcow2':
693
+Amend options for 'qcow2':
694
backing_file=<str> - File name of a base image
695
backing_fmt=<str> - Image format of the base image
696
- cluster_size=<size> - qcow2 cluster size
697
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
698
- compression_type=<str> - Compression method used for image cluster compression
699
data_file=<str> - File name of an external data file
700
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
701
- encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
702
- encrypt.cipher-mode=<str> - Name of encryption cipher mode
703
- encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
704
- encrypt.hash-alg=<str> - Name of encryption hash algorithm
705
- encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
706
- encrypt.ivgen-alg=<str> - Name of IV generator algorithm
707
- encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
708
- encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
709
- encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
710
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
711
- preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
712
refcount_bits=<num> - Width of a reference count entry in bits
713
size=<size> - Virtual disk size
714
715
-Note that not all of these options may be amendable.
716
-
717
Testing: amend -f qcow2 -o ?,cluster_size=4k TEST_DIR/t.qcow2
718
-Creation options for 'qcow2':
719
+Amend options for 'qcow2':
720
backing_file=<str> - File name of a base image
721
backing_fmt=<str> - Image format of the base image
722
- cluster_size=<size> - qcow2 cluster size
723
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
724
- compression_type=<str> - Compression method used for image cluster compression
725
data_file=<str> - File name of an external data file
726
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
727
- encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
728
- encrypt.cipher-mode=<str> - Name of encryption cipher mode
729
- encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
730
- encrypt.hash-alg=<str> - Name of encryption hash algorithm
731
- encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
732
- encrypt.ivgen-alg=<str> - Name of IV generator algorithm
733
- encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
734
- encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
735
- encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
736
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
737
- preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
738
refcount_bits=<num> - Width of a reference count entry in bits
739
size=<size> - Virtual disk size
740
741
-Note that not all of these options may be amendable.
742
-
743
Testing: amend -f qcow2 -o cluster_size=4k -o help TEST_DIR/t.qcow2
744
-Creation options for 'qcow2':
745
+Amend options for 'qcow2':
746
backing_file=<str> - File name of a base image
747
backing_fmt=<str> - Image format of the base image
748
- cluster_size=<size> - qcow2 cluster size
749
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
750
- compression_type=<str> - Compression method used for image cluster compression
751
data_file=<str> - File name of an external data file
752
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
753
- encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
754
- encrypt.cipher-mode=<str> - Name of encryption cipher mode
755
- encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
756
- encrypt.hash-alg=<str> - Name of encryption hash algorithm
757
- encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
758
- encrypt.ivgen-alg=<str> - Name of IV generator algorithm
759
- encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
760
- encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
761
- encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
762
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
763
- preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
764
refcount_bits=<num> - Width of a reference count entry in bits
765
size=<size> - Virtual disk size
766
767
-Note that not all of these options may be amendable.
768
-
769
Testing: amend -f qcow2 -o cluster_size=4k -o ? TEST_DIR/t.qcow2
770
-Creation options for 'qcow2':
771
+Amend options for 'qcow2':
772
backing_file=<str> - File name of a base image
773
backing_fmt=<str> - Image format of the base image
774
- cluster_size=<size> - qcow2 cluster size
775
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
776
- compression_type=<str> - Compression method used for image cluster compression
777
data_file=<str> - File name of an external data file
778
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
779
- encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
780
- encrypt.cipher-mode=<str> - Name of encryption cipher mode
781
- encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
782
- encrypt.hash-alg=<str> - Name of encryption hash algorithm
783
- encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
784
- encrypt.ivgen-alg=<str> - Name of IV generator algorithm
785
- encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
786
- encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
787
- encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
788
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
789
- preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
790
refcount_bits=<num> - Width of a reference count entry in bits
791
size=<size> - Virtual disk size
792
793
-Note that not all of these options may be amendable.
794
-
795
Testing: amend -f qcow2 -o backing_file=TEST_DIR/t.qcow2,,help TEST_DIR/t.qcow2
796
797
Testing: rebase -u -b -f qcow2 TEST_DIR/t.qcow2
798
@@ -XXX,XX +XXX,XX @@ Testing: amend -f qcow2 -o backing_file=TEST_DIR/t.qcow2 -o ,, -o help TEST_DIR/
799
qemu-img: Invalid option list: ,,
800
801
Testing: amend -f qcow2 -o help
802
-Creation options for 'qcow2':
803
+Amend options for 'qcow2':
804
backing_file=<str> - File name of a base image
805
backing_fmt=<str> - Image format of the base image
806
- cluster_size=<size> - qcow2 cluster size
807
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
808
- compression_type=<str> - Compression method used for image cluster compression
809
data_file=<str> - File name of an external data file
810
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
811
- encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
812
- encrypt.cipher-mode=<str> - Name of encryption cipher mode
813
- encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
814
- encrypt.hash-alg=<str> - Name of encryption hash algorithm
815
- encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
816
- encrypt.ivgen-alg=<str> - Name of IV generator algorithm
817
- encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
818
- encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
819
- encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
820
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
821
- preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
822
refcount_bits=<num> - Width of a reference count entry in bits
823
size=<size> - Virtual disk size
824
825
-Note that not all of these options may be amendable.
826
-
827
Testing: amend -o help
828
qemu-img: Expecting one image file name
829
830
diff --git a/tests/qemu-iotests/085.out b/tests/qemu-iotests/085.out
831
index XXXXXXX..XXXXXXX 100644
832
--- a/tests/qemu-iotests/085.out
833
+++ b/tests/qemu-iotests/085.out
834
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT.2', fmt=IMGFMT size=134217728
835
=== Create a single snapshot on virtio0 ===
836
837
{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'virtio0', 'snapshot-file':'TEST_DIR/1-snapshot-v0.IMGFMT', 'format': 'IMGFMT' } }
838
-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 compression_type=zlib
839
+Formatting 'TEST_DIR/1-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/t.qcow2.1 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
840
{"return": {}}
841
842
=== Invalid command - missing device and nodename ===
843
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/1-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file
844
=== Create several transactional group snapshots ===
845
846
{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/2-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/2-snapshot-v1.IMGFMT' } } ] } }
847
-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 compression_type=zlib
848
-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 compression_type=zlib
849
+Formatting 'TEST_DIR/2-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/1-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
850
+Formatting 'TEST_DIR/2-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/t.qcow2.2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
851
{"return": {}}
852
{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/3-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/3-snapshot-v1.IMGFMT' } } ] } }
853
-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 compression_type=zlib
854
-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 compression_type=zlib
855
+Formatting 'TEST_DIR/3-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/2-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
856
+Formatting 'TEST_DIR/3-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/2-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
857
{"return": {}}
858
{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/4-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/4-snapshot-v1.IMGFMT' } } ] } }
859
-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 compression_type=zlib
860
-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 compression_type=zlib
861
+Formatting 'TEST_DIR/4-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/3-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
862
+Formatting 'TEST_DIR/4-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/3-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
863
{"return": {}}
864
{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/5-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/5-snapshot-v1.IMGFMT' } } ] } }
865
-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 compression_type=zlib
866
-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 compression_type=zlib
867
+Formatting 'TEST_DIR/5-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/4-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
868
+Formatting 'TEST_DIR/5-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/4-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
869
{"return": {}}
870
{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/6-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/6-snapshot-v1.IMGFMT' } } ] } }
871
-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 compression_type=zlib
872
-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 compression_type=zlib
873
+Formatting 'TEST_DIR/6-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/5-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
874
+Formatting 'TEST_DIR/6-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/5-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
875
{"return": {}}
876
{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/7-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/7-snapshot-v1.IMGFMT' } } ] } }
877
-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 compression_type=zlib
878
-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 compression_type=zlib
879
+Formatting 'TEST_DIR/7-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/6-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
880
+Formatting 'TEST_DIR/7-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/6-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
881
{"return": {}}
882
{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/8-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/8-snapshot-v1.IMGFMT' } } ] } }
883
-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 compression_type=zlib
884
-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 compression_type=zlib
885
+Formatting 'TEST_DIR/8-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/7-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
886
+Formatting 'TEST_DIR/8-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/7-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
887
{"return": {}}
888
{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/9-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/9-snapshot-v1.IMGFMT' } } ] } }
889
-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 compression_type=zlib
890
-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 compression_type=zlib
891
+Formatting 'TEST_DIR/9-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/8-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
892
+Formatting 'TEST_DIR/9-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/8-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
893
{"return": {}}
894
{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/10-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/10-snapshot-v1.IMGFMT' } } ] } }
895
-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 compression_type=zlib
896
-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 compression_type=zlib
897
+Formatting 'TEST_DIR/10-snapshot-v0.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/9-snapshot-v0.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
898
+Formatting 'TEST_DIR/10-snapshot-v1.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 backing_file=TEST_DIR/9-snapshot-v1.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
899
{"return": {}}
900
901
=== Create a couple of snapshots using blockdev-snapshot ===
902
diff --git a/tests/qemu-iotests/144.out b/tests/qemu-iotests/144.out
903
index XXXXXXX..XXXXXXX 100644
904
--- a/tests/qemu-iotests/144.out
905
+++ b/tests/qemu-iotests/144.out
906
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=536870912
907
{ 'execute': 'qmp_capabilities' }
908
{"return": {}}
909
{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'virtio0', 'snapshot-file':'TEST_DIR/tmp.IMGFMT', 'format': 'IMGFMT' } }
910
-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 compression_type=zlib
911
+Formatting 'TEST_DIR/tmp.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=536870912 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
912
{"return": {}}
913
914
=== Performing block-commit on active layer ===
915
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/tmp.qcow2', fmt=qcow2 size=536870912 backing_file=TEST_DIR/
916
=== Performing Live Snapshot 2 ===
917
918
{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'virtio0', 'snapshot-file':'TEST_DIR/tmp2.IMGFMT', 'format': 'IMGFMT' } }
919
-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 compression_type=zlib
920
+Formatting 'TEST_DIR/tmp2.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=536870912 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
921
{"return": {}}
922
*** done
923
diff --git a/tests/qemu-iotests/182.out b/tests/qemu-iotests/182.out
924
index XXXXXXX..XXXXXXX 100644
925
--- a/tests/qemu-iotests/182.out
926
+++ b/tests/qemu-iotests/182.out
927
@@ -XXX,XX +XXX,XX @@ Is another process using the image [TEST_DIR/t.qcow2]?
928
{'execute': 'blockdev-add', 'arguments': { 'node-name': 'node0', 'driver': 'file', 'filename': 'TEST_DIR/t.IMGFMT', 'locking': 'on' } }
929
{"return": {}}
930
{'execute': 'blockdev-snapshot-sync', 'arguments': { 'node-name': 'node0', 'snapshot-file': 'TEST_DIR/t.IMGFMT.overlay', 'snapshot-node-name': 'node1' } }
931
-Formatting 'TEST_DIR/t.qcow2.overlay', fmt=qcow2 size=197120 backing_file=TEST_DIR/t.qcow2 backing_fmt=file cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
932
+Formatting 'TEST_DIR/t.qcow2.overlay', fmt=qcow2 cluster_size=65536 compression_type=zlib size=197120 backing_file=TEST_DIR/t.qcow2 backing_fmt=file lazy_refcounts=off refcount_bits=16
933
{"return": {}}
934
{'execute': 'blockdev-add', 'arguments': { 'node-name': 'node1', 'driver': 'file', 'filename': 'TEST_DIR/t.IMGFMT', 'locking': 'on' } }
935
{"return": {}}
936
diff --git a/tests/qemu-iotests/185.out b/tests/qemu-iotests/185.out
937
index XXXXXXX..XXXXXXX 100644
938
--- a/tests/qemu-iotests/185.out
939
+++ b/tests/qemu-iotests/185.out
940
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
941
=== Creating backing chain ===
942
943
{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'disk', 'snapshot-file': 'TEST_DIR/t.IMGFMT.mid', 'format': 'IMGFMT', 'mode': 'absolute-paths' } }
944
-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 compression_type=zlib
945
+Formatting 'TEST_DIR/t.qcow2.mid', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 backing_file=TEST_DIR/t.qcow2.base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
946
{"return": {}}
947
{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io disk "write 0 4M"' } }
948
wrote 4194304/4194304 bytes at offset 0
949
4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
950
{"return": ""}
951
{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'disk', 'snapshot-file': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'absolute-paths' } }
952
-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 compression_type=zlib
953
+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 backing_file=TEST_DIR/t.qcow2.mid backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
954
{"return": {}}
955
956
=== Start commit job and exit qemu ===
957
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 backing_file=TEST_DIR/t.q
958
{ 'execute': 'qmp_capabilities' }
959
{"return": {}}
960
{ 'execute': 'drive-mirror', 'arguments': { 'device': 'disk', 'target': 'TEST_DIR/t.IMGFMT.copy', 'format': 'IMGFMT', 'sync': 'full', 'speed': 65536 } }
961
-Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 size=67108864 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
962
+Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
963
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "disk"}}
964
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}}
965
{"return": {}}
966
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 size=67108864 cluster_size=65536 l
967
{ 'execute': 'qmp_capabilities' }
968
{"return": {}}
969
{ 'execute': 'drive-backup', 'arguments': { 'device': 'disk', 'target': 'TEST_DIR/t.IMGFMT.copy', 'format': 'IMGFMT', 'sync': 'full', 'speed': 65536 } }
970
-Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 size=67108864 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
971
+Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
972
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "disk"}}
973
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}}
974
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "paused", "id": "disk"}}
975
diff --git a/tests/qemu-iotests/255.out b/tests/qemu-iotests/255.out
208
diff --git a/tests/qemu-iotests/255.out b/tests/qemu-iotests/255.out
976
index XXXXXXX..XXXXXXX 100644
209
index XXXXXXX..XXXXXXX 100644
977
--- a/tests/qemu-iotests/255.out
210
--- a/tests/qemu-iotests/255.out
978
+++ b/tests/qemu-iotests/255.out
211
+++ b/tests/qemu-iotests/255.out
979
@@ -XXX,XX +XXX,XX @@ Finishing a commit job with background reads
212
@@ -XXX,XX +XXX,XX @@ Finishing a commit job with background reads
980
213
981
=== Create backing chain and start VM ===
214
=== Create backing chain and start VM ===
982
215
983
-Formatting 'TEST_DIR/PID-t.qcow2.mid', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
216
-Formatting 'TEST_DIR/PID-t.qcow2.mid', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
984
+Formatting 'TEST_DIR/PID-t.qcow2.mid', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
217
985
218
-Formatting 'TEST_DIR/PID-t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
986
-Formatting 'TEST_DIR/PID-t.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
987
+Formatting 'TEST_DIR/PID-t.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
988
219
989
=== Start background read requests ===
220
=== Start background read requests ===
990
221
991
@@ -XXX,XX +XXX,XX @@ Closing the VM while a job is being cancelled
222
@@ -XXX,XX +XXX,XX @@ Closing the VM while a job is being cancelled
992
223
993
=== Create images and start VM ===
224
=== Create images and start VM ===
994
225
995
-Formatting 'TEST_DIR/PID-src.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
226
-Formatting 'TEST_DIR/PID-src.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
996
+Formatting 'TEST_DIR/PID-src.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
227
997
228
-Formatting 'TEST_DIR/PID-dst.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
998
-Formatting 'TEST_DIR/PID-dst.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
999
+Formatting 'TEST_DIR/PID-dst.qcow2', fmt=qcow2 cluster_size=65536 compression_type=zlib size=134217728 lazy_refcounts=off refcount_bits=16
1000
229
1001
wrote 1048576/1048576 bytes at offset 0
230
wrote 1048576/1048576 bytes at offset 0
1002
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
231
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1003
diff --git a/tests/qemu-iotests/274.out b/tests/qemu-iotests/274.out
232
diff --git a/tests/qemu-iotests/274.out b/tests/qemu-iotests/274.out
1004
index XXXXXXX..XXXXXXX 100644
233
index XXXXXXX..XXXXXXX 100644
1005
--- a/tests/qemu-iotests/274.out
234
--- a/tests/qemu-iotests/274.out
1006
+++ b/tests/qemu-iotests/274.out
235
+++ b/tests/qemu-iotests/274.out
1007
@@ -XXX,XX +XXX,XX @@
236
@@ -XXX,XX +XXX,XX @@
1008
== Commit tests ==
237
== Commit tests ==
1009
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
238
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=2097152 lazy_refcounts=off refcount_bits=16
1010
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=2097152 lazy_refcounts=off refcount_bits=16
239
1011
240
-Formatting 'TEST_DIR/PID-mid', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1048576 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
1012
-Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
241
1013
+Formatting 'TEST_DIR/PID-mid', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1048576 backing_file=TEST_DIR/PID-base lazy_refcounts=off refcount_bits=16
242
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=2097152 backing_file=TEST_DIR/PID-mid backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
1014
1015
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1016
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 compression_type=zlib size=2097152 backing_file=TEST_DIR/PID-mid lazy_refcounts=off refcount_bits=16
1017
243
1018
wrote 2097152/2097152 bytes at offset 0
244
wrote 2097152/2097152 bytes at offset 0
1019
2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
245
2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1020
@@ -XXX,XX +XXX,XX @@ read 1048576/1048576 bytes at offset 1048576
246
@@ -XXX,XX +XXX,XX @@ read 1048576/1048576 bytes at offset 1048576
1021
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
247
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1022
248
1023
=== Testing HMP commit (top -> mid) ===
249
=== Testing HMP commit (top -> mid) ===
1024
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
250
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=2097152 lazy_refcounts=off refcount_bits=16
1025
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=2097152 lazy_refcounts=off refcount_bits=16
251
1026
252
-Formatting 'TEST_DIR/PID-mid', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1048576 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
1027
-Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
253
1028
+Formatting 'TEST_DIR/PID-mid', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1048576 backing_file=TEST_DIR/PID-base lazy_refcounts=off refcount_bits=16
254
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=2097152 backing_file=TEST_DIR/PID-mid backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
1029
1030
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1031
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 compression_type=zlib size=2097152 backing_file=TEST_DIR/PID-mid lazy_refcounts=off refcount_bits=16
1032
255
1033
wrote 2097152/2097152 bytes at offset 0
256
wrote 2097152/2097152 bytes at offset 0
1034
2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
257
2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1035
@@ -XXX,XX +XXX,XX @@ read 1048576/1048576 bytes at offset 1048576
258
@@ -XXX,XX +XXX,XX @@ read 1048576/1048576 bytes at offset 1048576
1036
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
259
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1037
260
1038
=== Testing QMP active commit (top -> mid) ===
261
=== Testing QMP active commit (top -> mid) ===
1039
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
262
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=2097152 lazy_refcounts=off refcount_bits=16
1040
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=2097152 lazy_refcounts=off refcount_bits=16
263
1041
264
-Formatting 'TEST_DIR/PID-mid', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1048576 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
1042
-Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
265
1043
+Formatting 'TEST_DIR/PID-mid', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1048576 backing_file=TEST_DIR/PID-base lazy_refcounts=off refcount_bits=16
266
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=2097152 backing_file=TEST_DIR/PID-mid backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
1044
1045
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1046
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 compression_type=zlib size=2097152 backing_file=TEST_DIR/PID-mid lazy_refcounts=off refcount_bits=16
1047
267
1048
wrote 2097152/2097152 bytes at offset 0
268
wrote 2097152/2097152 bytes at offset 0
1049
2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
269
2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1050
@@ -XXX,XX +XXX,XX @@ read 1048576/1048576 bytes at offset 1048576
270
@@ -XXX,XX +XXX,XX @@ read 1048576/1048576 bytes at offset 1048576
271
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
272
273
=== Testing qemu-img commit (top -> base) ===
274
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=2097152 lazy_refcounts=off refcount_bits=16
275
276
-Formatting 'TEST_DIR/PID-mid', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1048576 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
277
278
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=2097152 backing_file=TEST_DIR/PID-mid backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
279
280
wrote 2097152/2097152 bytes at offset 0
281
2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
282
@@ -XXX,XX +XXX,XX @@ read 1048576/1048576 bytes at offset 1048576
283
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
284
285
=== Testing QMP active commit (top -> base) ===
286
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=2097152 lazy_refcounts=off refcount_bits=16
287
288
-Formatting 'TEST_DIR/PID-mid', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1048576 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
289
290
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=2097152 backing_file=TEST_DIR/PID-mid backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
291
292
wrote 2097152/2097152 bytes at offset 0
293
2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
294
@@ -XXX,XX +XXX,XX @@ read 1048576/1048576 bytes at offset 1048576
1051
295
1052
== Resize tests ==
296
== Resize tests ==
1053
=== preallocation=off ===
297
=== preallocation=off ===
1054
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=6442450944 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
298
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=6442450944 lazy_refcounts=off refcount_bits=16
1055
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=6442450944 lazy_refcounts=off refcount_bits=16
299
1056
300
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1073741824 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
1057
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=1073741824 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1058
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 compression_type=zlib size=1073741824 backing_file=TEST_DIR/PID-base lazy_refcounts=off refcount_bits=16
1059
301
1060
wrote 65536/65536 bytes at offset 5368709120
302
wrote 65536/65536 bytes at offset 5368709120
1061
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
303
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1062
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 5368709120
304
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 5368709120
1063
{ "start": 1073741824, "length": 7516192768, "depth": 0, "zero": true, "data": false}]
305
{ "start": 1073741824, "length": 7516192768, "depth": 0, "present": true, "zero": true, "data": false}]
1064
306
1065
=== preallocation=metadata ===
307
=== preallocation=metadata ===
1066
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=34359738368 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
308
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=34359738368 lazy_refcounts=off refcount_bits=16
1067
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=34359738368 lazy_refcounts=off refcount_bits=16
309
1068
310
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=32212254720 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
1069
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=32212254720 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1070
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 compression_type=zlib size=32212254720 backing_file=TEST_DIR/PID-base lazy_refcounts=off refcount_bits=16
1071
311
1072
wrote 65536/65536 bytes at offset 33285996544
312
wrote 65536/65536 bytes at offset 33285996544
1073
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
313
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1074
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 33285996544
314
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 33285996544
1075
{ "start": 34896609280, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 2685075456}]
315
{ "start": 34896609280, "length": 536870912, "depth": 0, "present": true, "zero": true, "data": false, "offset": 2685075456}]
1076
316
1077
=== preallocation=falloc ===
317
=== preallocation=falloc ===
1078
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=10485760 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
318
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=10485760 lazy_refcounts=off refcount_bits=16
1079
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=10485760 lazy_refcounts=off refcount_bits=16
319
1080
320
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=5242880 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
1081
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=5242880 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1082
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 compression_type=zlib size=5242880 backing_file=TEST_DIR/PID-base lazy_refcounts=off refcount_bits=16
1083
321
1084
wrote 65536/65536 bytes at offset 9437184
322
wrote 65536/65536 bytes at offset 9437184
1085
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
323
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1086
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 9437184
324
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 9437184
1087
{ "start": 5242880, "length": 10485760, "depth": 0, "zero": false, "data": true, "offset": 327680}]
325
{ "start": 5242880, "length": 10485760, "depth": 0, "present": true, "zero": false, "data": true, "offset": 327680}]
1088
326
1089
=== preallocation=full ===
327
=== preallocation=full ===
1090
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=16777216 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
328
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=16777216 lazy_refcounts=off refcount_bits=16
1091
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=16777216 lazy_refcounts=off refcount_bits=16
329
1092
330
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=8388608 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
1093
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=8388608 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1094
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 compression_type=zlib size=8388608 backing_file=TEST_DIR/PID-base lazy_refcounts=off refcount_bits=16
1095
331
1096
wrote 65536/65536 bytes at offset 11534336
332
wrote 65536/65536 bytes at offset 11534336
1097
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
333
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1098
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 11534336
334
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 11534336
1099
{ "start": 8388608, "length": 4194304, "depth": 0, "zero": false, "data": true, "offset": 327680}]
335
{ "start": 8388608, "length": 4194304, "depth": 0, "present": true, "zero": false, "data": true, "offset": 327680}]
1100
336
1101
=== preallocation=off ===
337
=== preallocation=off ===
1102
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=393216 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
338
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=393216 lazy_refcounts=off refcount_bits=16
1103
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=393216 lazy_refcounts=off refcount_bits=16
339
1104
340
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=259072 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
1105
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=259072 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1106
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 compression_type=zlib size=259072 backing_file=TEST_DIR/PID-base lazy_refcounts=off refcount_bits=16
1107
341
1108
wrote 65536/65536 bytes at offset 259072
342
wrote 65536/65536 bytes at offset 259072
1109
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
343
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1110
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 259072
344
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 259072
1111
{ "start": 262144, "length": 262144, "depth": 0, "zero": true, "data": false}]
345
{ "start": 262144, "length": 262144, "depth": 0, "present": true, "zero": true, "data": false}]
1112
346
1113
=== preallocation=off ===
347
=== preallocation=off ===
1114
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=409600 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
348
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=409600 lazy_refcounts=off refcount_bits=16
1115
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=409600 lazy_refcounts=off refcount_bits=16
349
1116
350
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=262144 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
1117
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=262144 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1118
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 compression_type=zlib size=262144 backing_file=TEST_DIR/PID-base lazy_refcounts=off refcount_bits=16
1119
351
1120
wrote 65536/65536 bytes at offset 344064
352
wrote 65536/65536 bytes at offset 344064
1121
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
353
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1122
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 344064
354
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 344064
1123
{ "start": 262144, "length": 262144, "depth": 0, "zero": true, "data": false}]
355
{ "start": 262144, "length": 262144, "depth": 0, "present": true, "zero": true, "data": false}]
1124
356
1125
=== preallocation=off ===
357
=== preallocation=off ===
1126
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=524288 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
358
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=524288 lazy_refcounts=off refcount_bits=16
1127
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=524288 lazy_refcounts=off refcount_bits=16
359
1128
360
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=262144 backing_file=TEST_DIR/PID-base backing_fmt=qcow2 lazy_refcounts=off refcount_bits=16
1129
-Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=262144 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
1130
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 cluster_size=65536 compression_type=zlib size=262144 backing_file=TEST_DIR/PID-base lazy_refcounts=off refcount_bits=16
1131
361
1132
wrote 65536/65536 bytes at offset 446464
362
wrote 65536/65536 bytes at offset 446464
1133
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
363
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1134
diff --git a/tests/qemu-iotests/280.out b/tests/qemu-iotests/280.out
364
diff --git a/tests/qemu-iotests/280.out b/tests/qemu-iotests/280.out
1135
index XXXXXXX..XXXXXXX 100644
365
index XXXXXXX..XXXXXXX 100644
1136
--- a/tests/qemu-iotests/280.out
366
--- a/tests/qemu-iotests/280.out
1137
+++ b/tests/qemu-iotests/280.out
367
+++ b/tests/qemu-iotests/280.out
1138
@@ -XXX,XX +XXX,XX @@
368
@@ -XXX,XX +XXX,XX @@
1139
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=67108864 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib
369
-Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
1140
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 cluster_size=65536 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16
1141
370
1142
=== Launch VM ===
371
=== Launch VM ===
1143
Enabling migration QMP events on VM...
372
Enabling migration QMP events on VM...
373
diff --git a/tests/qemu-iotests/296.out b/tests/qemu-iotests/296.out
374
index XXXXXXX..XXXXXXX 100644
375
--- a/tests/qemu-iotests/296.out
376
+++ b/tests/qemu-iotests/296.out
377
@@ -XXX,XX +XXX,XX @@
378
-Formatting 'TEST_DIR/test.img', fmt=luks size=1048576 key-secret=keysec0 iter-time=10
379
380
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
381
{"return": {}}
382
@@ -XXX,XX +XXX,XX @@ Job failed: Failed to get shared "consistent read" lock
383
qemu-img: Failed to get shared "consistent read" lock
384
Is another process using the image [TEST_DIR/test.img]?
385
386
-.Formatting 'TEST_DIR/test.img', fmt=luks size=1048576 key-secret=keysec0 iter-time=10
387
-
388
+.
389
Job failed: Block node is read-only
390
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
391
{"return": {}}
392
@@ -XXX,XX +XXX,XX @@ Job failed: Failed to get shared "consistent read" lock
393
{"return": {}}
394
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
395
{"return": {}}
396
-.Formatting 'TEST_DIR/test.img', fmt=luks size=1048576 key-secret=keysec0 iter-time=10
397
-
398
+.
399
{"return": {}}
400
{"error": {"class": "GenericError", "desc": "Failed to get \"write\" lock"}}
401
-.Formatting 'TEST_DIR/test.img', fmt=luks size=1048576 key-secret=keysec0 iter-time=10
402
-
403
+.
404
{"return": {}}
405
{"return": {}}
406
.
407
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
408
index XXXXXXX..XXXXXXX 100644
409
--- a/tests/qemu-iotests/iotests.py
410
+++ b/tests/qemu-iotests/iotests.py
411
@@ -XXX,XX +XXX,XX @@ def qemu_tool_popen(args: Sequence[str],
412
413
414
def qemu_tool_pipe_and_status(tool: str, args: Sequence[str],
415
- connect_stderr: bool = True) -> Tuple[str, int]:
416
+ connect_stderr: bool = True,
417
+ drop_successful_output: bool = False) \
418
+ -> Tuple[str, int]:
419
"""
420
Run a tool and return both its output and its exit code
421
"""
422
@@ -XXX,XX +XXX,XX @@ def qemu_tool_pipe_and_status(tool: str, args: Sequence[str],
423
cmd = ' '.join(args)
424
sys.stderr.write(f'{tool} received signal \
425
{-subp.returncode}: {cmd}\n')
426
+ if drop_successful_output and subp.returncode == 0:
427
+ output = ''
428
return (output, subp.returncode)
429
430
def qemu_img_create_prepare_args(args: List[str]) -> List[str]:
431
@@ -XXX,XX +XXX,XX @@ def qemu_img_pipe_and_status(*args: str) -> Tuple[str, int]:
432
"""
433
Run qemu-img and return both its output and its exit code
434
"""
435
+ is_create = bool(args and args[0] == 'create')
436
full_args = qemu_img_args + qemu_img_create_prepare_args(list(args))
437
- return qemu_tool_pipe_and_status('qemu-img', full_args)
438
+ return qemu_tool_pipe_and_status('qemu-img', full_args,
439
+ drop_successful_output=is_create)
440
441
def qemu_img(*args: str) -> int:
442
'''Run qemu-img and return the exit code'''
1144
--
443
--
1145
2.26.2
444
2.34.1
1146
445
1147
446
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
820c6bee534ec3b added testing of qcow2.py into 291, and it breaks 291
3
We want iotests pass with both the default zlib compression and with
4
with external data file. Actually, 291 is bad place for qcow2.py
4
IMGOPTS='compression_type=zstd'.
5
testing, better add a separate test.
6
5
7
For now, drop qcow2.py testing from 291 to fix the regression.
6
Actually the only test that is interested in real compression type in
7
test output is 287 (test for qcow2 compression type) and it's in bash.
8
So for now we can safely filter out compression type in all qcow2
9
tests.
8
10
9
Fixes: 820c6bee534ec3b
10
Reported-by: Max Reitz <mreitz@redhat.com>
11
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
11
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
12
Message-Id: <20200618154052.8629-1-vsementsov@virtuozzo.com>
12
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
13
Reviewed-by: Eric Blake <eblake@redhat.com>
13
Message-Id: <20211223160144.1097696-11-vsementsov@virtuozzo.com>
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
15
---
15
---
16
tests/qemu-iotests/291 | 4 ----
16
tests/qemu-iotests/206.out | 10 +++++-----
17
tests/qemu-iotests/291.out | 33 ---------------------------------
17
tests/qemu-iotests/242.out | 10 +++++-----
18
2 files changed, 37 deletions(-)
18
tests/qemu-iotests/274.out | 10 +++++-----
19
tests/qemu-iotests/iotests.py | 2 ++
20
4 files changed, 17 insertions(+), 15 deletions(-)
19
21
20
diff --git a/tests/qemu-iotests/291 b/tests/qemu-iotests/291
22
diff --git a/tests/qemu-iotests/206.out b/tests/qemu-iotests/206.out
21
index XXXXXXX..XXXXXXX 100755
22
--- a/tests/qemu-iotests/291
23
+++ b/tests/qemu-iotests/291
24
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c 'w 1M 1M' -f $IMGFMT "$TEST_IMG" | _filter_qemu_io
25
$QEMU_IMG bitmap --disable -f $IMGFMT "$TEST_IMG" b1
26
$QEMU_IMG bitmap --enable -f $IMGFMT "$TEST_IMG" b2
27
$QEMU_IO -c 'w 2M 1M' -f $IMGFMT "$TEST_IMG" | _filter_qemu_io
28
-echo "Check resulting qcow2 header extensions:"
29
-$PYTHON qcow2.py "$TEST_IMG" dump-header-exts
30
31
echo
32
echo "=== Bitmap preservation not possible to non-qcow2 ==="
33
@@ -XXX,XX +XXX,XX @@ $QEMU_IMG bitmap --merge tmp -f $IMGFMT "$TEST_IMG" b0
34
$QEMU_IMG bitmap --remove --image-opts \
35
driver=$IMGFMT,file.driver=file,file.filename="$TEST_IMG" tmp
36
_img_info --format-specific
37
-echo "Check resulting qcow2 header extensions:"
38
-$PYTHON qcow2.py "$TEST_IMG" dump-header-exts
39
40
echo
41
echo "=== Check bitmap contents ==="
42
diff --git a/tests/qemu-iotests/291.out b/tests/qemu-iotests/291.out
43
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
44
--- a/tests/qemu-iotests/291.out
24
--- a/tests/qemu-iotests/206.out
45
+++ b/tests/qemu-iotests/291.out
25
+++ b/tests/qemu-iotests/206.out
46
@@ -XXX,XX +XXX,XX @@ wrote 1048576/1048576 bytes at offset 1048576
26
@@ -XXX,XX +XXX,XX @@ virtual size: 128 MiB (134217728 bytes)
47
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
27
cluster_size: 65536
48
wrote 1048576/1048576 bytes at offset 2097152
28
Format specific information:
49
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
29
compat: 1.1
50
-Check resulting qcow2 header extensions:
30
- compression type: zlib
51
-Header extension:
31
+ compression type: COMPRESSION_TYPE
52
-magic 0xe2792aca (Backing format)
32
lazy refcounts: false
53
-length 5
54
-data 'qcow2'
55
-
56
-Header extension:
57
-magic 0x6803f857 (Feature table)
58
-length 336
59
-data <binary>
60
-
61
-Header extension:
62
-magic 0x23852875 (Bitmaps)
63
-length 24
64
-nb_bitmaps 2
65
-reserved32 0
66
-bitmap_directory_size 0x40
67
-bitmap_directory_offset 0x510000
68
-
69
70
=== Bitmap preservation not possible to non-qcow2 ===
71
72
@@ -XXX,XX +XXX,XX @@ Format specific information:
73
granularity: 65536
74
refcount bits: 16
33
refcount bits: 16
75
corrupt: false
34
corrupt: false
76
-Check resulting qcow2 header extensions:
35
@@ -XXX,XX +XXX,XX @@ virtual size: 64 MiB (67108864 bytes)
77
-Header extension:
36
cluster_size: 65536
78
-magic 0x6803f857 (Feature table)
37
Format specific information:
79
-length 336
38
compat: 1.1
80
-data <binary>
39
- compression type: zlib
81
-
40
+ compression type: COMPRESSION_TYPE
82
-Header extension:
41
lazy refcounts: false
83
-magic 0x23852875 (Bitmaps)
42
refcount bits: 16
84
-length 24
43
corrupt: false
85
-nb_bitmaps 3
44
@@ -XXX,XX +XXX,XX @@ virtual size: 32 MiB (33554432 bytes)
86
-reserved32 0
45
cluster_size: 2097152
87
-bitmap_directory_size 0x60
46
Format specific information:
88
-bitmap_directory_offset 0x520000
47
compat: 1.1
89
-
48
- compression type: zlib
90
49
+ compression type: COMPRESSION_TYPE
91
=== Check bitmap contents ===
50
lazy refcounts: true
51
refcount bits: 1
52
corrupt: false
53
@@ -XXX,XX +XXX,XX @@ backing file: TEST_IMG.base
54
backing file format: IMGFMT
55
Format specific information:
56
compat: 0.10
57
- compression type: zlib
58
+ compression type: COMPRESSION_TYPE
59
refcount bits: 16
60
61
=== Successful image creation (encrypted) ===
62
@@ -XXX,XX +XXX,XX @@ encrypted: yes
63
cluster_size: 65536
64
Format specific information:
65
compat: 1.1
66
- compression type: zlib
67
+ compression type: COMPRESSION_TYPE
68
lazy refcounts: false
69
refcount bits: 16
70
encrypt:
71
diff --git a/tests/qemu-iotests/242.out b/tests/qemu-iotests/242.out
72
index XXXXXXX..XXXXXXX 100644
73
--- a/tests/qemu-iotests/242.out
74
+++ b/tests/qemu-iotests/242.out
75
@@ -XXX,XX +XXX,XX @@ virtual size: 1 MiB (1048576 bytes)
76
cluster_size: 65536
77
Format specific information:
78
compat: 1.1
79
- compression type: zlib
80
+ compression type: COMPRESSION_TYPE
81
lazy refcounts: false
82
refcount bits: 16
83
corrupt: false
84
@@ -XXX,XX +XXX,XX @@ virtual size: 1 MiB (1048576 bytes)
85
cluster_size: 65536
86
Format specific information:
87
compat: 1.1
88
- compression type: zlib
89
+ compression type: COMPRESSION_TYPE
90
lazy refcounts: false
91
bitmaps:
92
[0]:
93
@@ -XXX,XX +XXX,XX @@ virtual size: 1 MiB (1048576 bytes)
94
cluster_size: 65536
95
Format specific information:
96
compat: 1.1
97
- compression type: zlib
98
+ compression type: COMPRESSION_TYPE
99
lazy refcounts: false
100
bitmaps:
101
[0]:
102
@@ -XXX,XX +XXX,XX @@ virtual size: 1 MiB (1048576 bytes)
103
cluster_size: 65536
104
Format specific information:
105
compat: 1.1
106
- compression type: zlib
107
+ compression type: COMPRESSION_TYPE
108
lazy refcounts: false
109
bitmaps:
110
[0]:
111
@@ -XXX,XX +XXX,XX @@ virtual size: 1 MiB (1048576 bytes)
112
cluster_size: 65536
113
Format specific information:
114
compat: 1.1
115
- compression type: zlib
116
+ compression type: COMPRESSION_TYPE
117
lazy refcounts: false
118
bitmaps:
119
[0]:
120
diff --git a/tests/qemu-iotests/274.out b/tests/qemu-iotests/274.out
121
index XXXXXXX..XXXXXXX 100644
122
--- a/tests/qemu-iotests/274.out
123
+++ b/tests/qemu-iotests/274.out
124
@@ -XXX,XX +XXX,XX @@ backing file: TEST_DIR/PID-base
125
backing file format: IMGFMT
126
Format specific information:
127
compat: 1.1
128
- compression type: zlib
129
+ compression type: COMPRESSION_TYPE
130
lazy refcounts: false
131
refcount bits: 16
132
corrupt: false
133
@@ -XXX,XX +XXX,XX @@ backing file: TEST_DIR/PID-base
134
backing file format: IMGFMT
135
Format specific information:
136
compat: 1.1
137
- compression type: zlib
138
+ compression type: COMPRESSION_TYPE
139
lazy refcounts: false
140
refcount bits: 16
141
corrupt: false
142
@@ -XXX,XX +XXX,XX @@ backing file: TEST_DIR/PID-base
143
backing file format: IMGFMT
144
Format specific information:
145
compat: 1.1
146
- compression type: zlib
147
+ compression type: COMPRESSION_TYPE
148
lazy refcounts: false
149
refcount bits: 16
150
corrupt: false
151
@@ -XXX,XX +XXX,XX @@ virtual size: 2 MiB (2097152 bytes)
152
cluster_size: 65536
153
Format specific information:
154
compat: 1.1
155
- compression type: zlib
156
+ compression type: COMPRESSION_TYPE
157
lazy refcounts: false
158
refcount bits: 16
159
corrupt: false
160
@@ -XXX,XX +XXX,XX @@ backing file: TEST_DIR/PID-base
161
backing file format: IMGFMT
162
Format specific information:
163
compat: 1.1
164
- compression type: zlib
165
+ compression type: COMPRESSION_TYPE
166
lazy refcounts: false
167
refcount bits: 16
168
corrupt: false
169
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
170
index XXXXXXX..XXXXXXX 100644
171
--- a/tests/qemu-iotests/iotests.py
172
+++ b/tests/qemu-iotests/iotests.py
173
@@ -XXX,XX +XXX,XX @@ def filter_img_info(output, filename):
174
'uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX',
175
line)
176
line = re.sub('cid: [0-9]+', 'cid: XXXXXXXXXX', line)
177
+ line = re.sub('(compression type: )(zlib|zstd)', r'\1COMPRESSION_TYPE',
178
+ line)
179
lines.append(line)
180
return '\n'.join(lines)
92
181
93
--
182
--
94
2.26.2
183
2.34.1
95
184
96
185
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
ret may be > 0 on success path at this point. Fix assertion, which may
3
Instead of qemu_img_log("info", ..) use generic helper img_info_log().
4
crash currently.
5
4
6
Fixes: 4ce5dd3e9b5ee0fac18625860eb3727399ee965e
5
img_info_log() has smarter logic. For example it use filter_img_info()
6
to filter output, which in turns filter a compression type. So it will
7
help us in future when we implement a possibility to use zstd
8
compression by default (with help of some runtime config file or maybe
9
build option). For now to test you should recompile qemu with a small
10
addition into block/qcow2.c before
11
"if (qcow2_opts->has_compression_type":
12
13
if (!qcow2_opts->has_compression_type && version >= 3) {
14
qcow2_opts->has_compression_type = true;
15
qcow2_opts->compression_type = QCOW2_COMPRESSION_TYPE_ZSTD;
16
}
17
7
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
18
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Message-Id: <20200526181347.489557-1-vsementsov@virtuozzo.com>
19
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
20
Message-Id: <20211223160144.1097696-12-vsementsov@virtuozzo.com>
21
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
10
---
22
---
11
block/block-copy.c | 4 +++-
23
tests/qemu-iotests/302 | 4 +++-
12
1 file changed, 3 insertions(+), 1 deletion(-)
24
tests/qemu-iotests/302.out | 7 +++----
25
2 files changed, 6 insertions(+), 5 deletions(-)
13
26
14
diff --git a/block/block-copy.c b/block/block-copy.c
27
diff --git a/tests/qemu-iotests/302 b/tests/qemu-iotests/302
28
index XXXXXXX..XXXXXXX 100755
29
--- a/tests/qemu-iotests/302
30
+++ b/tests/qemu-iotests/302
31
@@ -XXX,XX +XXX,XX @@ from iotests import (
32
qemu_img_measure,
33
qemu_io,
34
qemu_nbd_popen,
35
+ img_info_log,
36
)
37
38
iotests.script_initialize(supported_fmts=["qcow2"])
39
@@ -XXX,XX +XXX,XX @@ with tarfile.open(tar_file, "w") as tar:
40
tar_file):
41
42
iotests.log("=== Target image info ===")
43
+ # Not img_info_log as it enforces imgfmt, but now we print info on raw
44
qemu_img_log("info", nbd_uri)
45
46
qemu_img(
47
@@ -XXX,XX +XXX,XX @@ with tarfile.open(tar_file, "w") as tar:
48
nbd_uri)
49
50
iotests.log("=== Converted image info ===")
51
- qemu_img_log("info", nbd_uri)
52
+ img_info_log(nbd_uri)
53
54
iotests.log("=== Converted image check ===")
55
qemu_img_log("check", nbd_uri)
56
diff --git a/tests/qemu-iotests/302.out b/tests/qemu-iotests/302.out
15
index XXXXXXX..XXXXXXX 100644
57
index XXXXXXX..XXXXXXX 100644
16
--- a/block/block-copy.c
58
--- a/tests/qemu-iotests/302.out
17
+++ b/block/block-copy.c
59
+++ b/tests/qemu-iotests/302.out
18
@@ -XXX,XX +XXX,XX @@ out:
60
@@ -XXX,XX +XXX,XX @@ virtual size: 448 KiB (458752 bytes)
19
* block_copy_task_run. If it fails, it means some task already failed
61
disk size: unavailable
20
* for real reason, let's return first failure.
62
21
* Still, assert that we don't rewrite failure by success.
63
=== Converted image info ===
22
+ *
64
-image: nbd+unix:///exp?socket=SOCK_DIR/PID-nbd-sock
23
+ * Note: ret may be positive here because of block-status result.
65
-file format: qcow2
24
*/
66
+image: TEST_IMG
25
- assert(ret == 0 || aio_task_pool_status(aio) < 0);
67
+file format: IMGFMT
26
+ assert(ret >= 0 || aio_task_pool_status(aio) < 0);
68
virtual size: 1 GiB (1073741824 bytes)
27
ret = aio_task_pool_status(aio);
69
-disk size: unavailable
28
70
cluster_size: 65536
29
aio_task_pool_free(aio);
71
Format specific information:
72
compat: 1.1
73
- compression type: zlib
74
+ compression type: COMPRESSION_TYPE
75
lazy refcounts: false
76
refcount bits: 16
77
corrupt: false
30
--
78
--
31
2.26.2
79
2.34.1
32
80
33
81
diff view generated by jsdifflib
1
From: Maxim Levitsky <mlevitsk@redhat.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
Now that we have all the infrastructure in place,
3
If image doesn't have any compressed cluster we can easily switch to
4
wire it in the qcow2 driver and expose this to the user.
4
zlib compression, which may allow to downgrade the image.
5
5
6
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
6
That's mostly needed to support IMGOPTS='compression_type=zstd' in some
7
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
7
iotests which do qcow2 downgrade.
8
9
While being here also fix checkpatch complain against '#' in printf
10
formatting.
11
12
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
13
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
Message-Id: <20200608094030.670121-9-mlevitsk@redhat.com>
14
Message-Id: <20211223160144.1097696-13-vsementsov@virtuozzo.com>
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
15
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
11
---
16
---
12
block/qcow2.c | 71 +++++++++++++++++++++++++++++++++-----
17
block/qcow2.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++--
13
tests/qemu-iotests/082.out | 45 ++++++++++++++++++++++++
18
1 file changed, 56 insertions(+), 2 deletions(-)
14
2 files changed, 107 insertions(+), 9 deletions(-)
15
19
16
diff --git a/block/qcow2.c b/block/qcow2.c
20
diff --git a/block/qcow2.c b/block/qcow2.c
17
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
18
--- a/block/qcow2.c
22
--- a/block/qcow2.c
19
+++ b/block/qcow2.c
23
+++ b/block/qcow2.c
20
@@ -XXX,XX +XXX,XX @@ static ssize_t qcow2_crypto_hdr_write_func(QCryptoBlock *block, size_t offset,
24
@@ -XXX,XX +XXX,XX @@ static int qcow2_load_vmstate(BlockDriverState *bs, QEMUIOVector *qiov,
21
return ret;
25
return bs->drv->bdrv_co_preadv_part(bs, offset, qiov->size, qiov, 0, 0);
22
}
26
}
23
27
24
+static QDict*
28
+static int qcow2_has_compressed_clusters(BlockDriverState *bs)
25
+qcow2_extract_crypto_opts(QemuOpts *opts, const char *fmt, Error **errp)
26
+{
29
+{
27
+ QDict *cryptoopts_qdict;
30
+ int64_t offset = 0;
28
+ QDict *opts_qdict;
31
+ int64_t bytes = bdrv_getlength(bs);
29
+
32
+
30
+ /* Extract "encrypt." options into a qdict */
33
+ if (bytes < 0) {
31
+ opts_qdict = qemu_opts_to_qdict(opts, NULL);
34
+ return bytes;
32
+ qdict_extract_subqdict(opts_qdict, &cryptoopts_qdict, "encrypt.");
35
+ }
33
+ qobject_unref(opts_qdict);
34
+ qdict_put_str(cryptoopts_qdict, "format", fmt);
35
+ return cryptoopts_qdict;
36
+}
37
38
/*
39
* read qcow2 extension and fill bs
40
@@ -XXX,XX +XXX,XX @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
41
42
if (has_luks) {
43
g_autoptr(QCryptoBlockCreateOptions) create_opts = NULL;
44
- QDict *opts_qdict;
45
- QDict *cryptoopts;
46
+ QDict *cryptoopts = qcow2_extract_crypto_opts(opts, "luks", errp);
47
size_t headerlen;
48
49
- opts_qdict = qemu_opts_to_qdict(opts, NULL);
50
- qdict_extract_subqdict(opts_qdict, &cryptoopts, "encrypt.");
51
- qobject_unref(opts_qdict);
52
-
53
- qdict_put_str(cryptoopts, "format", "luks");
54
-
55
create_opts = block_crypto_create_opts_init(cryptoopts, errp);
56
qobject_unref(cryptoopts);
57
if (!create_opts) {
58
@@ -XXX,XX +XXX,XX @@ typedef enum Qcow2AmendOperation {
59
QCOW2_NO_OPERATION = 0,
60
61
QCOW2_UPGRADING,
62
+ QCOW2_UPDATING_ENCRYPTION,
63
QCOW2_CHANGING_REFCOUNT_ORDER,
64
QCOW2_DOWNGRADING,
65
} Qcow2AmendOperation;
66
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
67
int ret;
68
QemuOptDesc *desc = opts->list->desc;
69
Qcow2AmendHelperCBInfo helper_cb_info;
70
+ bool encryption_update = false;
71
72
while (desc && desc->name) {
73
if (!qemu_opt_find(opts, desc->name)) {
74
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
75
backing_file = qemu_opt_get(opts, BLOCK_OPT_BACKING_FILE);
76
} else if (!strcmp(desc->name, BLOCK_OPT_BACKING_FMT)) {
77
backing_format = qemu_opt_get(opts, BLOCK_OPT_BACKING_FMT);
78
+ } else if (g_str_has_prefix(desc->name, "encrypt.")) {
79
+ if (!s->crypto) {
80
+ error_setg(errp,
81
+ "Can't amend encryption options - encryption not present");
82
+ return -EINVAL;
83
+ }
84
+ if (s->crypt_method_header != QCOW_CRYPT_LUKS) {
85
+ error_setg(errp,
86
+ "Only LUKS encryption options can be amended");
87
+ return -ENOTSUP;
88
+ }
89
+ encryption_update = true;
90
} else if (!strcmp(desc->name, BLOCK_OPT_LAZY_REFCOUNTS)) {
91
lazy_refcounts = qemu_opt_get_bool(opts, BLOCK_OPT_LAZY_REFCOUNTS,
92
lazy_refcounts);
93
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
94
.original_status_cb = status_cb,
95
.original_cb_opaque = cb_opaque,
96
.total_operations = (new_version != old_version)
97
- + (s->refcount_bits != refcount_bits)
98
+ + (s->refcount_bits != refcount_bits) +
99
+ (encryption_update == true)
100
};
101
102
/* Upgrade first (some features may require compat=1.1) */
103
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
104
}
105
}
106
107
+ if (encryption_update) {
108
+ QDict *amend_opts_dict;
109
+ QCryptoBlockAmendOptions *amend_opts;
110
+
36
+
111
+ helper_cb_info.current_operation = QCOW2_UPDATING_ENCRYPTION;
37
+ while (bytes != 0) {
112
+ amend_opts_dict = qcow2_extract_crypto_opts(opts, "luks", errp);
38
+ int ret;
113
+ if (!amend_opts_dict) {
39
+ QCow2SubclusterType type;
114
+ return -EINVAL;
40
+ unsigned int cur_bytes = MIN(INT_MAX, bytes);
115
+ }
41
+ uint64_t host_offset;
116
+ amend_opts = block_crypto_amend_opts_init(amend_opts_dict, errp);
42
+
117
+ qobject_unref(amend_opts_dict);
43
+ ret = qcow2_get_host_offset(bs, offset, &cur_bytes, &host_offset,
118
+ if (!amend_opts) {
44
+ &type);
119
+ return -EINVAL;
120
+ }
121
+ ret = qcrypto_block_amend_options(s->crypto,
122
+ qcow2_crypto_hdr_read_func,
123
+ qcow2_crypto_hdr_write_func,
124
+ bs,
125
+ amend_opts,
126
+ force,
127
+ errp);
128
+ qapi_free_QCryptoBlockAmendOptions(amend_opts);
129
+ if (ret < 0) {
45
+ if (ret < 0) {
130
+ return ret;
46
+ return ret;
131
+ }
47
+ }
48
+
49
+ if (type == QCOW2_SUBCLUSTER_COMPRESSED) {
50
+ return 1;
51
+ }
52
+
53
+ offset += cur_bytes;
54
+ bytes -= cur_bytes;
132
+ }
55
+ }
133
+
56
+
134
if (s->refcount_bits != refcount_bits) {
57
+ return 0;
135
int refcount_order = ctz32(refcount_bits);
58
+}
136
59
+
137
@@ -XXX,XX +XXX,XX @@ static QemuOptsList qcow2_amend_opts = {
60
/*
138
.name = "qcow2-amend-opts",
61
* Downgrades an image's version. To achieve this, any incompatible features
139
.head = QTAILQ_HEAD_INITIALIZER(qcow2_amend_opts.head),
62
* have to be removed.
140
.desc = {
63
@@ -XXX,XX +XXX,XX @@ static int qcow2_downgrade(BlockDriverState *bs, int target_version,
141
+ BLOCK_CRYPTO_OPT_DEF_LUKS_STATE("encrypt."),
64
* the first place; if that happens nonetheless, returning -ENOTSUP is the
142
+ BLOCK_CRYPTO_OPT_DEF_LUKS_KEYSLOT("encrypt."),
65
* best thing to do anyway */
143
+ BLOCK_CRYPTO_OPT_DEF_LUKS_OLD_SECRET("encrypt."),
66
144
+ BLOCK_CRYPTO_OPT_DEF_LUKS_NEW_SECRET("encrypt."),
67
- if (s->incompatible_features) {
145
+ BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME("encrypt."),
68
+ if (s->incompatible_features & ~QCOW2_INCOMPAT_COMPRESSION) {
146
QCOW_COMMON_OPTIONS,
69
error_setg(errp, "Cannot downgrade an image with incompatible features "
147
{ /* end of list */ }
70
- "%#" PRIx64 " set", s->incompatible_features);
71
+ "0x%" PRIx64 " set",
72
+ s->incompatible_features & ~QCOW2_INCOMPAT_COMPRESSION);
73
return -ENOTSUP;
148
}
74
}
149
diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out
75
150
index XXXXXXX..XXXXXXX 100644
76
@@ -XXX,XX +XXX,XX @@ static int qcow2_downgrade(BlockDriverState *bs, int target_version,
151
--- a/tests/qemu-iotests/082.out
77
return ret;
152
+++ b/tests/qemu-iotests/082.out
78
}
153
@@ -XXX,XX +XXX,XX @@ Amend options for 'qcow2':
79
154
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
80
+ if (s->incompatible_features & QCOW2_INCOMPAT_COMPRESSION) {
155
data_file=<str> - File name of an external data file
81
+ ret = qcow2_has_compressed_clusters(bs);
156
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
82
+ if (ret < 0) {
157
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
83
+ error_setg(errp, "Failed to check block status");
158
+ encrypt.keyslot=<num> - Select a single keyslot to modify explicitly
84
+ return -EINVAL;
159
+ encrypt.new-secret=<str> - New secret to set in the matching keyslots. Empty string to erase
85
+ }
160
+ encrypt.old-secret=<str> - Select all keyslots that match this password
86
+ if (ret) {
161
+ encrypt.state=<str> - Select new state of affected keyslots (active/inactive)
87
+ error_setg(errp, "Cannot downgrade an image with zstd compression "
162
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
88
+ "type and existing compressed clusters");
163
refcount_bits=<num> - Width of a reference count entry in bits
89
+ return -ENOTSUP;
164
size=<size> - Virtual disk size
90
+ }
165
@@ -XXX,XX +XXX,XX @@ Amend options for 'qcow2':
91
+ /*
166
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
92
+ * No compressed clusters for now, so just chose default zlib
167
data_file=<str> - File name of an external data file
93
+ * compression.
168
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
94
+ */
169
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
95
+ s->incompatible_features &= ~QCOW2_INCOMPAT_COMPRESSION;
170
+ encrypt.keyslot=<num> - Select a single keyslot to modify explicitly
96
+ s->compression_type = QCOW2_COMPRESSION_TYPE_ZLIB;
171
+ encrypt.new-secret=<str> - New secret to set in the matching keyslots. Empty string to erase
97
+ }
172
+ encrypt.old-secret=<str> - Select all keyslots that match this password
98
+
173
+ encrypt.state=<str> - Select new state of affected keyslots (active/inactive)
99
+ assert(s->incompatible_features == 0);
174
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
100
+
175
refcount_bits=<num> - Width of a reference count entry in bits
101
s->qcow_version = target_version;
176
size=<size> - Virtual disk size
102
ret = qcow2_update_header(bs);
177
@@ -XXX,XX +XXX,XX @@ Amend options for 'qcow2':
103
if (ret < 0) {
178
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
179
data_file=<str> - File name of an external data file
180
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
181
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
182
+ encrypt.keyslot=<num> - Select a single keyslot to modify explicitly
183
+ encrypt.new-secret=<str> - New secret to set in the matching keyslots. Empty string to erase
184
+ encrypt.old-secret=<str> - Select all keyslots that match this password
185
+ encrypt.state=<str> - Select new state of affected keyslots (active/inactive)
186
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
187
refcount_bits=<num> - Width of a reference count entry in bits
188
size=<size> - Virtual disk size
189
@@ -XXX,XX +XXX,XX @@ Amend options for 'qcow2':
190
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
191
data_file=<str> - File name of an external data file
192
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
193
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
194
+ encrypt.keyslot=<num> - Select a single keyslot to modify explicitly
195
+ encrypt.new-secret=<str> - New secret to set in the matching keyslots. Empty string to erase
196
+ encrypt.old-secret=<str> - Select all keyslots that match this password
197
+ encrypt.state=<str> - Select new state of affected keyslots (active/inactive)
198
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
199
refcount_bits=<num> - Width of a reference count entry in bits
200
size=<size> - Virtual disk size
201
@@ -XXX,XX +XXX,XX @@ Amend options for 'qcow2':
202
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
203
data_file=<str> - File name of an external data file
204
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
205
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
206
+ encrypt.keyslot=<num> - Select a single keyslot to modify explicitly
207
+ encrypt.new-secret=<str> - New secret to set in the matching keyslots. Empty string to erase
208
+ encrypt.old-secret=<str> - Select all keyslots that match this password
209
+ encrypt.state=<str> - Select new state of affected keyslots (active/inactive)
210
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
211
refcount_bits=<num> - Width of a reference count entry in bits
212
size=<size> - Virtual disk size
213
@@ -XXX,XX +XXX,XX @@ Amend options for 'qcow2':
214
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
215
data_file=<str> - File name of an external data file
216
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
217
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
218
+ encrypt.keyslot=<num> - Select a single keyslot to modify explicitly
219
+ encrypt.new-secret=<str> - New secret to set in the matching keyslots. Empty string to erase
220
+ encrypt.old-secret=<str> - Select all keyslots that match this password
221
+ encrypt.state=<str> - Select new state of affected keyslots (active/inactive)
222
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
223
refcount_bits=<num> - Width of a reference count entry in bits
224
size=<size> - Virtual disk size
225
@@ -XXX,XX +XXX,XX @@ Amend options for 'qcow2':
226
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
227
data_file=<str> - File name of an external data file
228
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
229
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
230
+ encrypt.keyslot=<num> - Select a single keyslot to modify explicitly
231
+ encrypt.new-secret=<str> - New secret to set in the matching keyslots. Empty string to erase
232
+ encrypt.old-secret=<str> - Select all keyslots that match this password
233
+ encrypt.state=<str> - Select new state of affected keyslots (active/inactive)
234
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
235
refcount_bits=<num> - Width of a reference count entry in bits
236
size=<size> - Virtual disk size
237
@@ -XXX,XX +XXX,XX @@ Amend options for 'qcow2':
238
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
239
data_file=<str> - File name of an external data file
240
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
241
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
242
+ encrypt.keyslot=<num> - Select a single keyslot to modify explicitly
243
+ encrypt.new-secret=<str> - New secret to set in the matching keyslots. Empty string to erase
244
+ encrypt.old-secret=<str> - Select all keyslots that match this password
245
+ encrypt.state=<str> - Select new state of affected keyslots (active/inactive)
246
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
247
refcount_bits=<num> - Width of a reference count entry in bits
248
size=<size> - Virtual disk size
249
@@ -XXX,XX +XXX,XX @@ Amend options for 'qcow2':
250
compat=<str> - Compatibility level (v2 [0.10] or v3 [1.1])
251
data_file=<str> - File name of an external data file
252
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
253
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
254
+ encrypt.keyslot=<num> - Select a single keyslot to modify explicitly
255
+ encrypt.new-secret=<str> - New secret to set in the matching keyslots. Empty string to erase
256
+ encrypt.old-secret=<str> - Select all keyslots that match this password
257
+ encrypt.state=<str> - Select new state of affected keyslots (active/inactive)
258
lazy_refcounts=<bool (on/off)> - Postpone refcount updates
259
refcount_bits=<num> - Width of a reference count entry in bits
260
size=<size> - Virtual disk size
261
--
104
--
262
2.26.2
105
2.34.1
263
106
264
107
diff view generated by jsdifflib
1
From: Maxim Levitsky <mlevitsk@redhat.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
Currently the implementation only supports amending the encryption
3
We'll use it in tests instead of explicit qcow2.py. Then we are going
4
options, unlike the qemu-img version
4
to add some filtering in _qcow2_dump_header.
5
5
6
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
7
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
Message-Id: <20200608094030.670121-14-mlevitsk@redhat.com>
8
Message-Id: <20211223160144.1097696-14-vsementsov@virtuozzo.com>
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
11
---
10
---
12
qapi/block-core.json | 16 +++++++++++++++-
11
tests/qemu-iotests/common.rc | 10 ++++++++++
13
block/qcow2.c | 39 +++++++++++++++++++++++++++++++++++++++
12
1 file changed, 10 insertions(+)
14
2 files changed, 54 insertions(+), 1 deletion(-)
15
13
16
diff --git a/qapi/block-core.json b/qapi/block-core.json
14
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/qapi/block-core.json
16
--- a/tests/qemu-iotests/common.rc
19
+++ b/qapi/block-core.json
17
+++ b/tests/qemu-iotests/common.rc
20
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ _require_one_device_of()
21
'data': { }
19
_notrun "$* not available"
22
}
20
}
23
21
24
+##
22
+_qcow2_dump_header()
25
+# @BlockdevAmendOptionsQcow2:
23
+{
26
+#
24
+ img="$1"
27
+# Driver specific image amend options for qcow2.
25
+ if [ -z "$img" ]; then
28
+# For now, only encryption options can be amended
26
+ img="$TEST_IMG"
29
+#
27
+ fi
30
+# @encrypt Encryption options to be amended
31
+#
32
+# Since: 5.1
33
+##
34
+{ 'struct': 'BlockdevAmendOptionsQcow2',
35
+ 'data': { '*encrypt': 'QCryptoBlockAmendOptions' } }
36
+
28
+
37
##
29
+ $PYTHON qcow2.py "$img" dump-header
38
# @BlockdevAmendOptions:
39
#
40
@@ -XXX,XX +XXX,XX @@
41
'driver': 'BlockdevDriver' },
42
'discriminator': 'driver',
43
'data': {
44
- 'luks': 'BlockdevAmendOptionsLUKS' } }
45
+ 'luks': 'BlockdevAmendOptionsLUKS',
46
+ 'qcow2': 'BlockdevAmendOptionsQcow2' } }
47
48
##
49
# @x-blockdev-amend:
50
diff --git a/block/qcow2.c b/block/qcow2.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/block/qcow2.c
53
+++ b/block/qcow2.c
54
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
55
return 0;
56
}
57
58
+static int coroutine_fn qcow2_co_amend(BlockDriverState *bs,
59
+ BlockdevAmendOptions *opts,
60
+ bool force,
61
+ Error **errp)
62
+{
63
+ BlockdevAmendOptionsQcow2 *qopts = &opts->u.qcow2;
64
+ BDRVQcow2State *s = bs->opaque;
65
+ int ret = 0;
66
+
67
+ if (qopts->has_encrypt) {
68
+ if (!s->crypto) {
69
+ error_setg(errp, "image is not encrypted, can't amend");
70
+ return -EOPNOTSUPP;
71
+ }
72
+
73
+ if (qopts->encrypt->format != Q_CRYPTO_BLOCK_FORMAT_LUKS) {
74
+ error_setg(errp,
75
+ "Amend can't be used to change the qcow2 encryption format");
76
+ return -EOPNOTSUPP;
77
+ }
78
+
79
+ if (s->crypt_method_header != QCOW_CRYPT_LUKS) {
80
+ error_setg(errp,
81
+ "Only LUKS encryption options can be amended for qcow2 with blockdev-amend");
82
+ return -EOPNOTSUPP;
83
+ }
84
+
85
+ ret = qcrypto_block_amend_options(s->crypto,
86
+ qcow2_crypto_hdr_read_func,
87
+ qcow2_crypto_hdr_write_func,
88
+ bs,
89
+ qopts->encrypt,
90
+ force,
91
+ errp);
92
+ }
93
+ return ret;
94
+}
30
+}
95
+
31
+
96
/*
32
# make sure this script returns success
97
* If offset or size are negative, respectively, they will not be included in
33
true
98
* the BLOCK_IMAGE_CORRUPTED event emitted.
99
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_qcow2 = {
100
.mutable_opts = mutable_opts,
101
.bdrv_co_check = qcow2_co_check,
102
.bdrv_amend_options = qcow2_amend_options,
103
+ .bdrv_co_amend = qcow2_co_amend,
104
105
.bdrv_detach_aio_context = qcow2_detach_aio_context,
106
.bdrv_attach_aio_context = qcow2_attach_aio_context,
107
--
34
--
108
2.26.2
35
2.34.1
109
36
110
37
diff view generated by jsdifflib
New patch
1
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
3
We are going to add filtering in _qcow2_dump_header and want all tests
4
use it.
5
6
The patch is generated by commands:
7
cd tests/qemu-iotests
8
sed -ie 's/$PYTHON qcow2.py "$TEST_IMG" dump-header\($\| \)/_qcow2_dump_header\1/' ??? tests/*
9
10
(the difficulty is to avoid converting dump-header-exts)
11
12
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
13
Reviewed-by: Max Reitz <mreitz@redhat.com>
14
Message-Id: <20211223160144.1097696-15-vsementsov@virtuozzo.com>
15
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
16
---
17
tests/qemu-iotests/031 | 6 +++---
18
tests/qemu-iotests/036 | 6 +++---
19
tests/qemu-iotests/039 | 20 ++++++++++----------
20
tests/qemu-iotests/060 | 20 ++++++++++----------
21
tests/qemu-iotests/061 | 36 ++++++++++++++++++------------------
22
tests/qemu-iotests/137 | 2 +-
23
tests/qemu-iotests/287 | 8 ++++----
24
7 files changed, 49 insertions(+), 49 deletions(-)
25
26
diff --git a/tests/qemu-iotests/031 b/tests/qemu-iotests/031
27
index XXXXXXX..XXXXXXX 100755
28
--- a/tests/qemu-iotests/031
29
+++ b/tests/qemu-iotests/031
30
@@ -XXX,XX +XXX,XX @@ for compat in "compat=0.10" "compat=1.1"; do
31
echo
32
_make_test_img -o $compat 64M
33
$PYTHON qcow2.py "$TEST_IMG" add-header-ext 0x12345678 "This is a test header extension"
34
- $PYTHON qcow2.py "$TEST_IMG" dump-header
35
+ _qcow2_dump_header
36
_check_test_img
37
38
echo
39
echo === Rewrite header with no backing file ===
40
echo
41
$QEMU_IMG rebase -u -b "" "$TEST_IMG"
42
- $PYTHON qcow2.py "$TEST_IMG" dump-header
43
+ _qcow2_dump_header
44
_check_test_img
45
46
echo
47
echo === Add a backing file and format ===
48
echo
49
$QEMU_IMG rebase -u -b "/some/backing/file/path" -F host_device "$TEST_IMG"
50
- $PYTHON qcow2.py "$TEST_IMG" dump-header
51
+ _qcow2_dump_header
52
done
53
54
# success, all done
55
diff --git a/tests/qemu-iotests/036 b/tests/qemu-iotests/036
56
index XXXXXXX..XXXXXXX 100755
57
--- a/tests/qemu-iotests/036
58
+++ b/tests/qemu-iotests/036
59
@@ -XXX,XX +XXX,XX @@ $PYTHON qcow2.py "$TEST_IMG" set-feature-bit incompatible 63
60
61
# Without feature table
62
$PYTHON qcow2.py "$TEST_IMG" del-header-ext 0x6803f857
63
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep features
64
+_qcow2_dump_header | grep features
65
$PYTHON qcow2.py "$TEST_IMG" dump-header-exts
66
_img_info
67
68
@@ -XXX,XX +XXX,XX @@ echo === Create image with unknown autoclear feature bit ===
69
echo
70
_make_test_img 64M
71
$PYTHON qcow2.py "$TEST_IMG" set-feature-bit autoclear 63
72
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep features
73
+_qcow2_dump_header | grep features
74
$PYTHON qcow2.py "$TEST_IMG" dump-header-exts
75
76
echo
77
@@ -XXX,XX +XXX,XX @@ echo === Repair image ===
78
echo
79
_check_test_img -r all
80
81
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep features
82
+_qcow2_dump_header | grep features
83
$PYTHON qcow2.py "$TEST_IMG" dump-header-exts
84
85
# success, all done
86
diff --git a/tests/qemu-iotests/039 b/tests/qemu-iotests/039
87
index XXXXXXX..XXXXXXX 100755
88
--- a/tests/qemu-iotests/039
89
+++ b/tests/qemu-iotests/039
90
@@ -XXX,XX +XXX,XX @@ _make_test_img -o "compat=1.1,lazy_refcounts=on" $size
91
$QEMU_IO -c "write -P 0x5a 0 512" "$TEST_IMG" | _filter_qemu_io
92
93
# The dirty bit must not be set
94
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
95
+_qcow2_dump_header | grep incompatible_features
96
_check_test_img
97
98
echo
99
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c "write -P 0x5a 0 512" \
100
| _filter_qemu_io
101
102
# The dirty bit must be set
103
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
104
+_qcow2_dump_header | grep incompatible_features
105
_check_test_img
106
107
echo
108
@@ -XXX,XX +XXX,XX @@ echo "== Read-only access must still work =="
109
$QEMU_IO -r -c "read -P 0x5a 0 512" "$TEST_IMG" | _filter_qemu_io
110
111
# The dirty bit must be set
112
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
113
+_qcow2_dump_header | grep incompatible_features
114
115
echo
116
echo "== Repairing the image file must succeed =="
117
@@ -XXX,XX +XXX,XX @@ echo "== Repairing the image file must succeed =="
118
_check_test_img -r all
119
120
# The dirty bit must not be set
121
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
122
+_qcow2_dump_header | grep incompatible_features
123
124
echo
125
echo "== Data should still be accessible after repair =="
126
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c "write -P 0x5a 0 512" \
127
| _filter_qemu_io
128
129
# The dirty bit must be set
130
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
131
+_qcow2_dump_header | grep incompatible_features
132
133
$QEMU_IO -c "write 0 512" "$TEST_IMG" | _filter_qemu_io
134
135
# The dirty bit must not be set
136
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
137
+_qcow2_dump_header | grep incompatible_features
138
139
echo
140
echo "== Creating an image file with lazy_refcounts=off =="
141
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c "write -P 0x5a 0 512" \
142
| _filter_qemu_io
143
144
# The dirty bit must not be set since lazy_refcounts=off
145
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
146
+_qcow2_dump_header | grep incompatible_features
147
_check_test_img
148
149
echo
150
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c "write 0 512" "$TEST_IMG" | _filter_qemu_io
151
$QEMU_IMG commit "$TEST_IMG"
152
153
# The dirty bit must not be set
154
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
155
+_qcow2_dump_header | grep incompatible_features
156
$PYTHON qcow2.py "$TEST_IMG".base dump-header | grep incompatible_features
157
158
_check_test_img
159
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c "reopen -o lazy-refcounts=on" \
160
| _filter_qemu_io
161
162
# The dirty bit must be set
163
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
164
+_qcow2_dump_header | grep incompatible_features
165
_check_test_img
166
167
_make_test_img -o "compat=1.1,lazy_refcounts=on" $size
168
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c "reopen -o lazy-refcounts=off" \
169
| _filter_qemu_io
170
171
# The dirty bit must not be set
172
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
173
+_qcow2_dump_header | grep incompatible_features
174
_check_test_img
175
176
177
diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060
178
index XXXXXXX..XXXXXXX 100755
179
--- a/tests/qemu-iotests/060
180
+++ b/tests/qemu-iotests/060
181
@@ -XXX,XX +XXX,XX @@ poke_file "$TEST_IMG" "$l1_offset" "\x80\x00\x00\x00\x00\x03\x00\x00"
182
_check_test_img
183
184
# The corrupt bit should not be set anyway
185
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
186
+_qcow2_dump_header | grep incompatible_features
187
188
# Try to write something, thereby forcing the corrupt bit to be set
189
$QEMU_IO -c "$OPEN_RW" -c "write -P 0x2a 0 512" | _filter_qemu_io
190
191
# The corrupt bit must now be set
192
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
193
+_qcow2_dump_header | grep incompatible_features
194
195
# This information should be available through qemu-img info
196
_img_info --format-specific
197
@@ -XXX,XX +XXX,XX @@ poke_file "$TEST_IMG" "$(($rb_offset+8))" "\x00\x01"
198
# Redirect new data cluster onto refcount block
199
poke_file "$TEST_IMG" "$l2_offset" "\x80\x00\x00\x00\x00\x02\x00\x00"
200
_check_test_img
201
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
202
+_qcow2_dump_header | grep incompatible_features
203
$QEMU_IO -c "$OPEN_RW" -c "write -P 0x2a 0 512" | _filter_qemu_io
204
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
205
+_qcow2_dump_header | grep incompatible_features
206
207
# Try to fix it
208
_check_test_img -r all
209
210
# The corrupt bit should be cleared
211
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
212
+_qcow2_dump_header | grep incompatible_features
213
214
# Look if it's really really fixed
215
$QEMU_IO -c "$OPEN_RW" -c "write -P 0x2a 0 512" | _filter_qemu_io
216
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
217
+_qcow2_dump_header | grep incompatible_features
218
219
echo
220
echo "=== Testing cluster data reference into inactive L2 table ==="
221
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c "$OPEN_RW" -c "write -P 2 0 512" | _filter_qemu_io
222
poke_file "$TEST_IMG" "$l2_offset_after_snapshot" \
223
"\x80\x00\x00\x00\x00\x04\x00\x00"
224
_check_test_img
225
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
226
+_qcow2_dump_header | grep incompatible_features
227
$QEMU_IO -c "$OPEN_RW" -c "write -P 3 0 512" | _filter_qemu_io
228
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
229
+_qcow2_dump_header | grep incompatible_features
230
_check_test_img -r all
231
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
232
+_qcow2_dump_header | grep incompatible_features
233
$QEMU_IO -c "$OPEN_RW" -c "write -P 4 0 512" | _filter_qemu_io
234
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
235
+_qcow2_dump_header | grep incompatible_features
236
237
# Check data
238
$QEMU_IO -c "$OPEN_RO" -c "read -P 4 0 512" | _filter_qemu_io
239
diff --git a/tests/qemu-iotests/061 b/tests/qemu-iotests/061
240
index XXXXXXX..XXXXXXX 100755
241
--- a/tests/qemu-iotests/061
242
+++ b/tests/qemu-iotests/061
243
@@ -XXX,XX +XXX,XX @@ echo "=== Testing version downgrade with zero expansion ==="
244
echo
245
_make_test_img -o "compat=1.1,lazy_refcounts=on" 64M
246
$QEMU_IO -c "write -z 0 128k" "$TEST_IMG" | _filter_qemu_io
247
-$PYTHON qcow2.py "$TEST_IMG" dump-header
248
+_qcow2_dump_header
249
$QEMU_IMG amend -o "compat=0.10" "$TEST_IMG"
250
-$PYTHON qcow2.py "$TEST_IMG" dump-header
251
+_qcow2_dump_header
252
$QEMU_IO -c "read -P 0 0 128k" "$TEST_IMG" | _filter_qemu_io
253
_check_test_img
254
255
@@ -XXX,XX +XXX,XX @@ _make_test_img -o "compat=1.1,lazy_refcounts=on" 64M
256
$QEMU_IO -c "write -z 0 128k" "$TEST_IMG" | _filter_qemu_io
257
$QEMU_IO -c "write -z 32M 128k" "$TEST_IMG" | _filter_qemu_io
258
$QEMU_IO -c map "$TEST_IMG" | _filter_qemu_io
259
-$PYTHON qcow2.py "$TEST_IMG" dump-header
260
+_qcow2_dump_header
261
$QEMU_IMG amend -o "compat=0.10" --image-opts \
262
driver=qcow2,file.filename=$TEST_IMG,l2-cache-entry-size=4096
263
-$PYTHON qcow2.py "$TEST_IMG" dump-header
264
+_qcow2_dump_header
265
$QEMU_IO -c "read -P 0 0 128k" "$TEST_IMG" | _filter_qemu_io
266
$QEMU_IO -c "read -P 0 32M 128k" "$TEST_IMG" | _filter_qemu_io
267
$QEMU_IO -c map "$TEST_IMG" | _filter_qemu_io
268
@@ -XXX,XX +XXX,XX @@ _make_test_img -o "compat=1.1,lazy_refcounts=on" 64M
269
_NO_VALGRIND \
270
$QEMU_IO -c "write -P 0x2a 0 128k" -c flush \
271
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 | _filter_qemu_io
272
-$PYTHON qcow2.py "$TEST_IMG" dump-header
273
+_qcow2_dump_header
274
$QEMU_IMG amend -o "compat=0.10" "$TEST_IMG"
275
-$PYTHON qcow2.py "$TEST_IMG" dump-header
276
+_qcow2_dump_header
277
$QEMU_IO -c "read -P 0x2a 0 128k" "$TEST_IMG" | _filter_qemu_io
278
_check_test_img
279
280
@@ -XXX,XX +XXX,XX @@ echo
281
_make_test_img -o "compat=1.1" 64M
282
$PYTHON qcow2.py "$TEST_IMG" set-feature-bit compatible 42
283
$PYTHON qcow2.py "$TEST_IMG" set-feature-bit autoclear 42
284
-$PYTHON qcow2.py "$TEST_IMG" dump-header
285
+_qcow2_dump_header
286
$QEMU_IMG amend -o "compat=0.10" "$TEST_IMG"
287
-$PYTHON qcow2.py "$TEST_IMG" dump-header
288
+_qcow2_dump_header
289
_check_test_img
290
291
echo
292
@@ -XXX,XX +XXX,XX @@ echo "=== Testing version upgrade and resize ==="
293
echo
294
_make_test_img -o "compat=0.10" 64M
295
$QEMU_IO -c "write -P 0x2a 42M 64k" "$TEST_IMG" | _filter_qemu_io
296
-$PYTHON qcow2.py "$TEST_IMG" dump-header
297
+_qcow2_dump_header
298
$QEMU_IMG amend -o "compat=1.1,lazy_refcounts=on,size=128M" "$TEST_IMG"
299
-$PYTHON qcow2.py "$TEST_IMG" dump-header
300
+_qcow2_dump_header
301
$QEMU_IO -c "read -P 0x2a 42M 64k" "$TEST_IMG" | _filter_qemu_io
302
_check_test_img
303
304
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c "write -P 0x2a 24M 64k" "$TEST_IMG" | _filter_qemu_io
305
$QEMU_IMG snapshot -c foo "$TEST_IMG"
306
$QEMU_IMG resize "$TEST_IMG" 64M &&
307
echo "unexpected pass"
308
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep '^\(version\|size\|nb_snap\)'
309
+_qcow2_dump_header | grep '^\(version\|size\|nb_snap\)'
310
311
$QEMU_IMG amend -o "compat=1.1,size=128M" "$TEST_IMG" ||
312
echo "unexpected fail"
313
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep '^\(version\|size\|nb_snap\)'
314
+_qcow2_dump_header | grep '^\(version\|size\|nb_snap\)'
315
316
$QEMU_IMG snapshot -c bar "$TEST_IMG"
317
$QEMU_IMG resize --shrink "$TEST_IMG" 64M ||
318
echo "unexpected fail"
319
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep '^\(version\|size\|nb_snap\)'
320
+_qcow2_dump_header | grep '^\(version\|size\|nb_snap\)'
321
322
$QEMU_IMG amend -o "compat=0.10,size=32M" "$TEST_IMG" &&
323
echo "unexpected pass"
324
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep '^\(version\|size\|nb_snap\)'
325
+_qcow2_dump_header | grep '^\(version\|size\|nb_snap\)'
326
327
$QEMU_IMG snapshot -a bar "$TEST_IMG" ||
328
echo "unexpected fail"
329
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep '^\(version\|size\|nb_snap\)'
330
+_qcow2_dump_header | grep '^\(version\|size\|nb_snap\)'
331
332
$QEMU_IMG snapshot -d bar "$TEST_IMG"
333
$QEMU_IMG amend -o "compat=0.10,size=32M" "$TEST_IMG" ||
334
echo "unexpected fail"
335
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep '^\(version\|size\|nb_snap\)'
336
+_qcow2_dump_header | grep '^\(version\|size\|nb_snap\)'
337
338
_check_test_img
339
340
@@ -XXX,XX +XXX,XX @@ _make_test_img -o "compat=1.1,lazy_refcounts=on" 64M
341
_NO_VALGRIND \
342
$QEMU_IO -c "write -P 0x2a 0 128k" -c flush \
343
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 | _filter_qemu_io
344
-$PYTHON qcow2.py "$TEST_IMG" dump-header
345
+_qcow2_dump_header
346
$QEMU_IMG amend -o "lazy_refcounts=off" "$TEST_IMG"
347
-$PYTHON qcow2.py "$TEST_IMG" dump-header
348
+_qcow2_dump_header
349
$QEMU_IO -c "read -P 0x2a 0 128k" "$TEST_IMG" | _filter_qemu_io
350
_check_test_img
351
352
diff --git a/tests/qemu-iotests/137 b/tests/qemu-iotests/137
353
index XXXXXXX..XXXXXXX 100755
354
--- a/tests/qemu-iotests/137
355
+++ b/tests/qemu-iotests/137
356
@@ -XXX,XX +XXX,XX @@ $QEMU_IO \
357
358
# The dirty bit must not be set
359
# (Filter the external data file bit)
360
-if $PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features \
361
+if _qcow2_dump_header | grep incompatible_features \
362
| grep -q '\<0\>'
363
then
364
echo 'ERROR: Dirty bit set'
365
diff --git a/tests/qemu-iotests/287 b/tests/qemu-iotests/287
366
index XXXXXXX..XXXXXXX 100755
367
--- a/tests/qemu-iotests/287
368
+++ b/tests/qemu-iotests/287
369
@@ -XXX,XX +XXX,XX @@ echo
370
echo "=== Testing compression type incompatible bit setting for zlib ==="
371
echo
372
_make_test_img -o compression_type=zlib 64M
373
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
374
+_qcow2_dump_header | grep incompatible_features
375
376
echo
377
echo "=== Testing compression type incompatible bit setting for zstd ==="
378
echo
379
_make_test_img -o compression_type=zstd 64M
380
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
381
+_qcow2_dump_header | grep incompatible_features
382
383
echo
384
echo "=== Testing zlib with incompatible bit set ==="
385
@@ -XXX,XX +XXX,XX @@ echo
386
_make_test_img -o compression_type=zlib 64M
387
$PYTHON qcow2.py "$TEST_IMG" set-feature-bit incompatible 3
388
# to make sure the bit was actually set
389
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
390
+_qcow2_dump_header | grep incompatible_features
391
392
if $QEMU_IMG info "$TEST_IMG" >/dev/null 2>&1 ; then
393
echo "Error: The image opened successfully. The image must not be opened."
394
@@ -XXX,XX +XXX,XX @@ echo
395
_make_test_img -o compression_type=zstd 64M
396
$PYTHON qcow2.py "$TEST_IMG" set-header incompatible_features 0
397
# to make sure the bit was actually unset
398
-$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
399
+_qcow2_dump_header | grep incompatible_features
400
401
if $QEMU_IMG info "$TEST_IMG" >/dev/null 2>&1 ; then
402
echo "Error: The image opened successfully. The image must not be opened."
403
--
404
2.34.1
405
406
diff view generated by jsdifflib
1
From: Maxim Levitsky <mlevitsk@redhat.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
Some options are only useful for creation
3
_qcow2_dump_header has filter for compression type, so this change
4
(or hard to be amended, like cluster size for qcow2), while some other
4
makes test pass with IMGOPTS='compression_type=zstd'.
5
options are only useful for amend, like upcoming keyslot management
6
options for luks
7
5
8
Since currently only qcow2 supports amend, move all its options
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
to a common macro and then include it in each action option list.
7
Reviewed-by: Max Reitz <mreitz@redhat.com>
8
Message-Id: <20211223160144.1097696-16-vsementsov@virtuozzo.com>
9
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
10
---
11
tests/qemu-iotests/039 | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
10
13
11
In future it might be useful to remove some options which are
14
diff --git a/tests/qemu-iotests/039 b/tests/qemu-iotests/039
12
not supported anyway from amend list, which currently
15
index XXXXXXX..XXXXXXX 100755
13
cause an error message if amended.
16
--- a/tests/qemu-iotests/039
14
17
+++ b/tests/qemu-iotests/039
15
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
18
@@ -XXX,XX +XXX,XX @@ $QEMU_IMG commit "$TEST_IMG"
16
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
19
17
Reviewed-by: Max Reitz <mreitz@redhat.com>
20
# The dirty bit must not be set
18
Message-Id: <20200608094030.670121-5-mlevitsk@redhat.com>
21
_qcow2_dump_header | grep incompatible_features
19
Signed-off-by: Max Reitz <mreitz@redhat.com>
22
-$PYTHON qcow2.py "$TEST_IMG".base dump-header | grep incompatible_features
20
---
23
+_qcow2_dump_header "$TEST_IMG".base | grep incompatible_features
21
include/block/block_int.h | 4 +
24
22
block/qcow2.c | 173 +++++++++++++++++++++-----------------
25
_check_test_img
23
qemu-img.c | 18 ++--
26
TEST_IMG="$TEST_IMG".base _check_test_img
24
3 files changed, 107 insertions(+), 88 deletions(-)
25
26
diff --git a/include/block/block_int.h b/include/block/block_int.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/include/block/block_int.h
29
+++ b/include/block/block_int.h
30
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
31
32
/* List of options for creating images, terminated by name == NULL */
33
QemuOptsList *create_opts;
34
+
35
+ /* List of options for image amend */
36
+ QemuOptsList *amend_opts;
37
+
38
/*
39
* If this driver supports reopening images this contains a
40
* NULL-terminated list of the runtime options that can be
41
diff --git a/block/qcow2.c b/block/qcow2.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/block/qcow2.c
44
+++ b/block/qcow2.c
45
@@ -XXX,XX +XXX,XX @@ void qcow2_signal_corruption(BlockDriverState *bs, bool fatal, int64_t offset,
46
s->signaled_corruption = true;
47
}
48
49
+#define QCOW_COMMON_OPTIONS \
50
+ { \
51
+ .name = BLOCK_OPT_SIZE, \
52
+ .type = QEMU_OPT_SIZE, \
53
+ .help = "Virtual disk size" \
54
+ }, \
55
+ { \
56
+ .name = BLOCK_OPT_COMPAT_LEVEL, \
57
+ .type = QEMU_OPT_STRING, \
58
+ .help = "Compatibility level (v2 [0.10] or v3 [1.1])" \
59
+ }, \
60
+ { \
61
+ .name = BLOCK_OPT_BACKING_FILE, \
62
+ .type = QEMU_OPT_STRING, \
63
+ .help = "File name of a base image" \
64
+ }, \
65
+ { \
66
+ .name = BLOCK_OPT_BACKING_FMT, \
67
+ .type = QEMU_OPT_STRING, \
68
+ .help = "Image format of the base image" \
69
+ }, \
70
+ { \
71
+ .name = BLOCK_OPT_DATA_FILE, \
72
+ .type = QEMU_OPT_STRING, \
73
+ .help = "File name of an external data file" \
74
+ }, \
75
+ { \
76
+ .name = BLOCK_OPT_DATA_FILE_RAW, \
77
+ .type = QEMU_OPT_BOOL, \
78
+ .help = "The external data file must stay valid " \
79
+ "as a raw image" \
80
+ }, \
81
+ { \
82
+ .name = BLOCK_OPT_ENCRYPT, \
83
+ .type = QEMU_OPT_BOOL, \
84
+ .help = "Encrypt the image with format 'aes'. (Deprecated " \
85
+ "in favor of " BLOCK_OPT_ENCRYPT_FORMAT "=aes)", \
86
+ }, \
87
+ { \
88
+ .name = BLOCK_OPT_ENCRYPT_FORMAT, \
89
+ .type = QEMU_OPT_STRING, \
90
+ .help = "Encrypt the image, format choices: 'aes', 'luks'", \
91
+ }, \
92
+ BLOCK_CRYPTO_OPT_DEF_KEY_SECRET("encrypt.", \
93
+ "ID of secret providing qcow AES key or LUKS passphrase"), \
94
+ BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG("encrypt."), \
95
+ BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE("encrypt."), \
96
+ BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG("encrypt."), \
97
+ BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG("encrypt."), \
98
+ BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG("encrypt."), \
99
+ BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME("encrypt."), \
100
+ { \
101
+ .name = BLOCK_OPT_CLUSTER_SIZE, \
102
+ .type = QEMU_OPT_SIZE, \
103
+ .help = "qcow2 cluster size", \
104
+ .def_value_str = stringify(DEFAULT_CLUSTER_SIZE) \
105
+ }, \
106
+ { \
107
+ .name = BLOCK_OPT_PREALLOC, \
108
+ .type = QEMU_OPT_STRING, \
109
+ .help = "Preallocation mode (allowed values: off, " \
110
+ "metadata, falloc, full)" \
111
+ }, \
112
+ { \
113
+ .name = BLOCK_OPT_LAZY_REFCOUNTS, \
114
+ .type = QEMU_OPT_BOOL, \
115
+ .help = "Postpone refcount updates", \
116
+ .def_value_str = "off" \
117
+ }, \
118
+ { \
119
+ .name = BLOCK_OPT_REFCOUNT_BITS, \
120
+ .type = QEMU_OPT_NUMBER, \
121
+ .help = "Width of a reference count entry in bits", \
122
+ .def_value_str = "16" \
123
+ }, \
124
+ { \
125
+ .name = BLOCK_OPT_COMPRESSION_TYPE, \
126
+ .type = QEMU_OPT_STRING, \
127
+ .help = "Compression method used for image cluster " \
128
+ "compression", \
129
+ .def_value_str = "zlib" \
130
+ }
131
+
132
static QemuOptsList qcow2_create_opts = {
133
.name = "qcow2-create-opts",
134
.head = QTAILQ_HEAD_INITIALIZER(qcow2_create_opts.head),
135
.desc = {
136
- {
137
- .name = BLOCK_OPT_SIZE,
138
- .type = QEMU_OPT_SIZE,
139
- .help = "Virtual disk size"
140
- },
141
- {
142
- .name = BLOCK_OPT_COMPAT_LEVEL,
143
- .type = QEMU_OPT_STRING,
144
- .help = "Compatibility level (v2 [0.10] or v3 [1.1])"
145
- },
146
- {
147
- .name = BLOCK_OPT_BACKING_FILE,
148
- .type = QEMU_OPT_STRING,
149
- .help = "File name of a base image"
150
- },
151
- {
152
- .name = BLOCK_OPT_BACKING_FMT,
153
- .type = QEMU_OPT_STRING,
154
- .help = "Image format of the base image"
155
- },
156
- {
157
- .name = BLOCK_OPT_DATA_FILE,
158
- .type = QEMU_OPT_STRING,
159
- .help = "File name of an external data file"
160
- },
161
- {
162
- .name = BLOCK_OPT_DATA_FILE_RAW,
163
- .type = QEMU_OPT_BOOL,
164
- .help = "The external data file must stay valid as a raw image"
165
- },
166
- {
167
- .name = BLOCK_OPT_ENCRYPT,
168
- .type = QEMU_OPT_BOOL,
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', 'luks'",
176
- },
177
- BLOCK_CRYPTO_OPT_DEF_KEY_SECRET("encrypt.",
178
- "ID of secret providing qcow AES key or LUKS passphrase"),
179
- BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG("encrypt."),
180
- BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE("encrypt."),
181
- BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG("encrypt."),
182
- BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG("encrypt."),
183
- BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG("encrypt."),
184
- BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME("encrypt."),
185
- {
186
- .name = BLOCK_OPT_CLUSTER_SIZE,
187
- .type = QEMU_OPT_SIZE,
188
- .help = "qcow2 cluster size",
189
- .def_value_str = stringify(DEFAULT_CLUSTER_SIZE)
190
- },
191
- {
192
- .name = BLOCK_OPT_PREALLOC,
193
- .type = QEMU_OPT_STRING,
194
- .help = "Preallocation mode (allowed values: off, metadata, "
195
- "falloc, full)"
196
- },
197
- {
198
- .name = BLOCK_OPT_LAZY_REFCOUNTS,
199
- .type = QEMU_OPT_BOOL,
200
- .help = "Postpone refcount updates",
201
- .def_value_str = "off"
202
- },
203
- {
204
- .name = BLOCK_OPT_REFCOUNT_BITS,
205
- .type = QEMU_OPT_NUMBER,
206
- .help = "Width of a reference count entry in bits",
207
- .def_value_str = "16"
208
- },
209
- {
210
- .name = BLOCK_OPT_COMPRESSION_TYPE,
211
- .type = QEMU_OPT_STRING,
212
- .help = "Compression method used for image cluster compression",
213
- .def_value_str = "zlib"
214
- },
215
+ QCOW_COMMON_OPTIONS,
216
+ { /* end of list */ }
217
+ }
218
+};
219
+
220
+static QemuOptsList qcow2_amend_opts = {
221
+ .name = "qcow2-amend-opts",
222
+ .head = QTAILQ_HEAD_INITIALIZER(qcow2_amend_opts.head),
223
+ .desc = {
224
+ QCOW_COMMON_OPTIONS,
225
{ /* end of list */ }
226
}
227
};
228
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_qcow2 = {
229
.bdrv_inactivate = qcow2_inactivate,
230
231
.create_opts = &qcow2_create_opts,
232
+ .amend_opts = &qcow2_amend_opts,
233
.strong_runtime_opts = qcow2_strong_runtime_opts,
234
.mutable_opts = mutable_opts,
235
.bdrv_co_check = qcow2_co_check,
236
diff --git a/qemu-img.c b/qemu-img.c
237
index XXXXXXX..XXXXXXX 100644
238
--- a/qemu-img.c
239
+++ b/qemu-img.c
240
@@ -XXX,XX +XXX,XX @@ static int print_amend_option_help(const char *format)
241
return 1;
242
}
243
244
- /* Every driver supporting amendment must have create_opts */
245
- assert(drv->create_opts);
246
+ /* Every driver supporting amendment must have amend_opts */
247
+ assert(drv->amend_opts);
248
249
printf("Creation options for '%s':\n", format);
250
- qemu_opts_print_help(drv->create_opts, false);
251
+ qemu_opts_print_help(drv->amend_opts, false);
252
printf("\nNote that not all of these options may be amendable.\n");
253
return 0;
254
}
255
@@ -XXX,XX +XXX,XX @@ static int img_amend(int argc, char **argv)
256
Error *err = NULL;
257
int c, ret = 0;
258
char *options = NULL;
259
- QemuOptsList *create_opts = NULL;
260
+ QemuOptsList *amend_opts = NULL;
261
QemuOpts *opts = NULL;
262
const char *fmt = NULL, *filename, *cache;
263
int flags;
264
@@ -XXX,XX +XXX,XX @@ static int img_amend(int argc, char **argv)
265
goto out;
266
}
267
268
- /* Every driver supporting amendment must have create_opts */
269
- assert(bs->drv->create_opts);
270
+ /* Every driver supporting amendment must have amend_opts */
271
+ assert(bs->drv->amend_opts);
272
273
- create_opts = qemu_opts_append(create_opts, bs->drv->create_opts);
274
- opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
275
+ amend_opts = qemu_opts_append(amend_opts, bs->drv->amend_opts);
276
+ opts = qemu_opts_create(amend_opts, NULL, 0, &error_abort);
277
qemu_opts_do_parse(opts, options, NULL, &err);
278
if (err) {
279
error_report_err(err);
280
@@ -XXX,XX +XXX,XX @@ out:
281
out_no_progress:
282
blk_unref(blk);
283
qemu_opts_del(opts);
284
- qemu_opts_free(create_opts);
285
+ qemu_opts_free(amend_opts);
286
g_free(options);
287
288
if (ret) {
289
--
27
--
290
2.26.2
28
2.34.1
291
29
292
30
diff view generated by jsdifflib
1
From: Maxim Levitsky <mlevitsk@redhat.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
This allows more tests to be able to have same output on both qcow2 luks encrypted images
3
We want iotests pass with both the default zlib compression and with
4
and raw luks images
4
IMGOPTS='compression_type=zstd'.
5
5
6
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
6
Actually the only test that is interested in real compression type in
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
test output is 287 (test for qcow2 compression type), so implement
8
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
8
specific option for it.
9
Message-Id: <20200618150628.2169239-3-mreitz@redhat.com>
9
10
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
11
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
12
Message-Id: <20211223160144.1097696-17-vsementsov@virtuozzo.com>
13
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
10
---
14
---
11
tests/qemu-iotests/087.out | 6 +++---
15
tests/qemu-iotests/060.out | 2 +-
12
tests/qemu-iotests/134.out | 2 +-
16
tests/qemu-iotests/061.out | 12 ++++++------
13
tests/qemu-iotests/158.out | 4 ++--
17
tests/qemu-iotests/082.out | 14 +++++++-------
14
tests/qemu-iotests/188.out | 2 +-
18
tests/qemu-iotests/198.out | 4 ++--
15
tests/qemu-iotests/189.out | 4 ++--
19
tests/qemu-iotests/287 | 8 ++++----
16
tests/qemu-iotests/198.out | 4 ++--
20
tests/qemu-iotests/common.filter | 8 ++++++++
17
tests/qemu-iotests/263.out | 4 ++--
21
tests/qemu-iotests/common.rc | 14 +++++++++++++-
18
tests/qemu-iotests/284.out | 6 +++---
22
7 files changed, 41 insertions(+), 21 deletions(-)
19
tests/qemu-iotests/common.filter | 5 +----
23
20
9 files changed, 17 insertions(+), 20 deletions(-)
24
diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out
21
25
index XXXXXXX..XXXXXXX 100644
22
diff --git a/tests/qemu-iotests/087.out b/tests/qemu-iotests/087.out
26
--- a/tests/qemu-iotests/060.out
23
index XXXXXXX..XXXXXXX 100644
27
+++ b/tests/qemu-iotests/060.out
24
--- a/tests/qemu-iotests/087.out
28
@@ -XXX,XX +XXX,XX @@ virtual size: 64 MiB (67108864 bytes)
25
+++ b/tests/qemu-iotests/087.out
29
cluster_size: 65536
26
@@ -XXX,XX +XXX,XX @@ QMP_VERSION
30
Format specific information:
27
31
compat: 1.1
28
=== Encrypted image QCow ===
32
- compression type: zlib
29
33
+ compression type: COMPRESSION_TYPE
30
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on encrypt.key-secret=sec0
34
lazy refcounts: false
31
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on
35
refcount bits: 16
32
Testing:
36
corrupt: true
33
QMP_VERSION
37
diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out
34
{"return": {}}
38
index XXXXXXX..XXXXXXX 100644
35
@@ -XXX,XX +XXX,XX @@ QMP_VERSION
39
--- a/tests/qemu-iotests/061.out
36
40
+++ b/tests/qemu-iotests/061.out
37
=== Encrypted image LUKS ===
41
@@ -XXX,XX +XXX,XX @@ virtual size: 64 MiB (67108864 bytes)
38
42
cluster_size: 65536
39
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encrypt.format=luks encrypt.key-secret=sec0
43
Format specific information:
40
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
44
compat: 1.1
41
Testing:
45
- compression type: zlib
42
QMP_VERSION
46
+ compression type: COMPRESSION_TYPE
43
{"return": {}}
47
lazy refcounts: false
44
@@ -XXX,XX +XXX,XX @@ QMP_VERSION
48
refcount bits: 16
45
49
data file: TEST_DIR/t.IMGFMT.data
46
=== Missing driver ===
50
@@ -XXX,XX +XXX,XX @@ virtual size: 64 MiB (67108864 bytes)
47
51
cluster_size: 65536
48
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on encrypt.key-secret=sec0
52
Format specific information:
49
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on
53
compat: 1.1
50
Testing: -S
54
- compression type: zlib
51
QMP_VERSION
55
+ compression type: COMPRESSION_TYPE
52
{"return": {}}
56
lazy refcounts: false
53
diff --git a/tests/qemu-iotests/134.out b/tests/qemu-iotests/134.out
57
refcount bits: 16
54
index XXXXXXX..XXXXXXX 100644
58
data file: foo
55
--- a/tests/qemu-iotests/134.out
59
@@ -XXX,XX +XXX,XX @@ virtual size: 64 MiB (67108864 bytes)
56
+++ b/tests/qemu-iotests/134.out
60
cluster_size: 65536
57
@@ -XXX,XX +XXX,XX @@
61
Format specific information:
58
QA output created by 134
62
compat: 1.1
59
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on encrypt.key-secret=sec0
63
- compression type: zlib
60
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on
64
+ compression type: COMPRESSION_TYPE
61
65
lazy refcounts: false
62
== reading whole image ==
66
refcount bits: 16
63
read 134217728/134217728 bytes at offset 0
67
data file raw: false
64
diff --git a/tests/qemu-iotests/158.out b/tests/qemu-iotests/158.out
68
@@ -XXX,XX +XXX,XX @@ virtual size: 64 MiB (67108864 bytes)
65
index XXXXXXX..XXXXXXX 100644
69
cluster_size: 65536
66
--- a/tests/qemu-iotests/158.out
70
Format specific information:
67
+++ b/tests/qemu-iotests/158.out
71
compat: 1.1
68
@@ -XXX,XX +XXX,XX @@
72
- compression type: zlib
69
QA output created by 158
73
+ compression type: COMPRESSION_TYPE
70
== create base ==
74
lazy refcounts: false
71
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728 encryption=on encrypt.key-secret=sec0
75
refcount bits: 16
72
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728 encryption=on
76
data file: TEST_DIR/t.IMGFMT.data
73
77
@@ -XXX,XX +XXX,XX @@ virtual size: 64 MiB (67108864 bytes)
74
== writing whole image ==
78
cluster_size: 65536
75
wrote 134217728/134217728 bytes at offset 0
79
Format specific information:
76
@@ -XXX,XX +XXX,XX @@ wrote 134217728/134217728 bytes at offset 0
80
compat: 1.1
77
read 134217728/134217728 bytes at offset 0
81
- compression type: zlib
78
128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
82
+ compression type: COMPRESSION_TYPE
79
== create overlay ==
83
lazy refcounts: false
80
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base encryption=on encrypt.key-secret=sec0
84
refcount bits: 16
81
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base encryption=on
85
data file: TEST_DIR/t.IMGFMT.data
82
86
@@ -XXX,XX +XXX,XX @@ virtual size: 64 MiB (67108864 bytes)
83
== writing part of a cluster ==
87
cluster_size: 65536
84
wrote 1024/1024 bytes at offset 0
88
Format specific information:
85
diff --git a/tests/qemu-iotests/188.out b/tests/qemu-iotests/188.out
89
compat: 1.1
86
index XXXXXXX..XXXXXXX 100644
90
- compression type: zlib
87
--- a/tests/qemu-iotests/188.out
91
+ compression type: COMPRESSION_TYPE
88
+++ b/tests/qemu-iotests/188.out
92
lazy refcounts: false
89
@@ -XXX,XX +XXX,XX @@
93
refcount bits: 16
90
QA output created by 188
94
data file: TEST_DIR/t.IMGFMT.data
91
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=16777216 encrypt.format=luks encrypt.key-secret=sec0 encrypt.iter-time=10
95
diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out
92
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=16777216
96
index XXXXXXX..XXXXXXX 100644
93
97
--- a/tests/qemu-iotests/082.out
94
== reading whole image ==
98
+++ b/tests/qemu-iotests/082.out
95
read 16777216/16777216 bytes at offset 0
99
@@ -XXX,XX +XXX,XX @@ virtual size: 128 MiB (134217728 bytes)
96
diff --git a/tests/qemu-iotests/189.out b/tests/qemu-iotests/189.out
100
cluster_size: 4096
97
index XXXXXXX..XXXXXXX 100644
101
Format specific information:
98
--- a/tests/qemu-iotests/189.out
102
compat: 1.1
99
+++ b/tests/qemu-iotests/189.out
103
- compression type: zlib
100
@@ -XXX,XX +XXX,XX @@
104
+ compression type: COMPRESSION_TYPE
101
QA output created by 189
105
lazy refcounts: true
102
== create base ==
106
refcount bits: 16
103
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=16777216 encrypt.format=luks encrypt.key-secret=sec0 encrypt.iter-time=10
107
corrupt: false
104
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=16777216
108
@@ -XXX,XX +XXX,XX @@ virtual size: 128 MiB (134217728 bytes)
105
109
cluster_size: 8192
106
== writing whole image ==
110
Format specific information:
107
wrote 16777216/16777216 bytes at offset 0
111
compat: 1.1
108
@@ -XXX,XX +XXX,XX @@ wrote 16777216/16777216 bytes at offset 0
112
- compression type: zlib
109
read 16777216/16777216 bytes at offset 0
113
+ compression type: COMPRESSION_TYPE
110
16 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
114
lazy refcounts: true
111
== create overlay ==
115
refcount bits: 16
112
-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
116
corrupt: false
113
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=16777216 backing_file=TEST_DIR/t.IMGFMT.base
117
@@ -XXX,XX +XXX,XX @@ virtual size: 128 MiB (134217728 bytes)
114
118
cluster_size: 4096
115
== writing part of a cluster ==
119
Format specific information:
116
wrote 1024/1024 bytes at offset 0
120
compat: 1.1
121
- compression type: zlib
122
+ compression type: COMPRESSION_TYPE
123
lazy refcounts: true
124
refcount bits: 16
125
corrupt: false
126
@@ -XXX,XX +XXX,XX @@ virtual size: 128 MiB (134217728 bytes)
127
cluster_size: 8192
128
Format specific information:
129
compat: 1.1
130
- compression type: zlib
131
+ compression type: COMPRESSION_TYPE
132
lazy refcounts: true
133
refcount bits: 16
134
corrupt: false
135
@@ -XXX,XX +XXX,XX @@ virtual size: 128 MiB (134217728 bytes)
136
cluster_size: 65536
137
Format specific information:
138
compat: 1.1
139
- compression type: zlib
140
+ compression type: COMPRESSION_TYPE
141
lazy refcounts: true
142
refcount bits: 16
143
corrupt: false
144
@@ -XXX,XX +XXX,XX @@ virtual size: 130 MiB (136314880 bytes)
145
cluster_size: 65536
146
Format specific information:
147
compat: 1.1
148
- compression type: zlib
149
+ compression type: COMPRESSION_TYPE
150
lazy refcounts: false
151
refcount bits: 16
152
corrupt: false
153
@@ -XXX,XX +XXX,XX @@ virtual size: 132 MiB (138412032 bytes)
154
cluster_size: 65536
155
Format specific information:
156
compat: 1.1
157
- compression type: zlib
158
+ compression type: COMPRESSION_TYPE
159
lazy refcounts: true
160
refcount bits: 16
161
corrupt: false
117
diff --git a/tests/qemu-iotests/198.out b/tests/qemu-iotests/198.out
162
diff --git a/tests/qemu-iotests/198.out b/tests/qemu-iotests/198.out
118
index XXXXXXX..XXXXXXX 100644
163
index XXXXXXX..XXXXXXX 100644
119
--- a/tests/qemu-iotests/198.out
164
--- a/tests/qemu-iotests/198.out
120
+++ b/tests/qemu-iotests/198.out
165
+++ b/tests/qemu-iotests/198.out
121
@@ -XXX,XX +XXX,XX @@
166
@@ -XXX,XX +XXX,XX @@ image: json:{ /* filtered */ }
122
QA output created by 198
167
file format: IMGFMT
123
== create base ==
168
virtual size: 16 MiB (16777216 bytes)
124
-Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=16777216 encrypt.format=luks encrypt.key-secret=sec0 encrypt.iter-time=10
169
Format specific information:
125
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=16777216
170
- compression type: zlib
126
171
+ compression type: COMPRESSION_TYPE
127
== writing whole image base ==
172
encrypt:
128
wrote 16777216/16777216 bytes at offset 0
173
ivgen alg: plain64
129
16 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
174
hash alg: sha256
130
== create overlay ==
175
@@ -XXX,XX +XXX,XX @@ virtual size: 16 MiB (16777216 bytes)
131
-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
176
backing file: TEST_DIR/t.IMGFMT.base
132
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=16777216 backing_file=TEST_DIR/t.IMGFMT.base
177
backing file format: IMGFMT
133
178
Format specific information:
134
== writing whole image layer ==
179
- compression type: zlib
135
wrote 16777216/16777216 bytes at offset 0
180
+ compression type: COMPRESSION_TYPE
136
diff --git a/tests/qemu-iotests/263.out b/tests/qemu-iotests/263.out
181
encrypt:
137
index XXXXXXX..XXXXXXX 100644
182
ivgen alg: plain64
138
--- a/tests/qemu-iotests/263.out
183
hash alg: sha256
139
+++ b/tests/qemu-iotests/263.out
184
diff --git a/tests/qemu-iotests/287 b/tests/qemu-iotests/287
140
@@ -XXX,XX +XXX,XX @@ QA output created by 263
185
index XXXXXXX..XXXXXXX 100755
141
186
--- a/tests/qemu-iotests/287
142
testing LUKS qcow2 encryption
187
+++ b/tests/qemu-iotests/287
143
188
@@ -XXX,XX +XXX,XX @@ echo
144
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 encrypt.format=luks encrypt.key-secret=sec0 encrypt.iter-time=10
189
echo "=== Testing compression type incompatible bit setting for zlib ==="
145
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
190
echo
146
== reading the whole image ==
191
_make_test_img -o compression_type=zlib 64M
147
read 1048576/1048576 bytes at offset 0
192
-_qcow2_dump_header | grep incompatible_features
148
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
193
+_qcow2_dump_header --no-filter-compression | grep incompatible_features
149
@@ -XXX,XX +XXX,XX @@ read 982528/982528 bytes at offset 66048
194
150
195
echo
151
testing legacy AES qcow2 encryption
196
echo "=== Testing compression type incompatible bit setting for zstd ==="
152
197
echo
153
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 encrypt.format=aes encrypt.key-secret=sec0
198
_make_test_img -o compression_type=zstd 64M
154
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
199
-_qcow2_dump_header | grep incompatible_features
155
== reading the whole image ==
200
+_qcow2_dump_header --no-filter-compression | grep incompatible_features
156
read 1048576/1048576 bytes at offset 0
201
157
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
202
echo
158
diff --git a/tests/qemu-iotests/284.out b/tests/qemu-iotests/284.out
203
echo "=== Testing zlib with incompatible bit set ==="
159
index XXXXXXX..XXXXXXX 100644
204
@@ -XXX,XX +XXX,XX @@ echo
160
--- a/tests/qemu-iotests/284.out
205
_make_test_img -o compression_type=zlib 64M
161
+++ b/tests/qemu-iotests/284.out
206
$PYTHON qcow2.py "$TEST_IMG" set-feature-bit incompatible 3
162
@@ -XXX,XX +XXX,XX @@ QA output created by 284
207
# to make sure the bit was actually set
163
208
-_qcow2_dump_header | grep incompatible_features
164
testing LUKS qcow2 encryption
209
+_qcow2_dump_header --no-filter-compression | grep incompatible_features
165
210
166
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 encrypt.format=luks encrypt.key-secret=sec0 encrypt.iter-time=10
211
if $QEMU_IMG info "$TEST_IMG" >/dev/null 2>&1 ; then
167
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
212
echo "Error: The image opened successfully. The image must not be opened."
168
213
@@ -XXX,XX +XXX,XX @@ echo
169
== cluster size 512
214
_make_test_img -o compression_type=zstd 64M
170
== checking image refcounts ==
215
$PYTHON qcow2.py "$TEST_IMG" set-header incompatible_features 0
171
@@ -XXX,XX +XXX,XX @@ wrote 1/1 bytes at offset 512
216
# to make sure the bit was actually unset
172
217
-_qcow2_dump_header | grep incompatible_features
173
== rechecking image refcounts ==
218
+_qcow2_dump_header --no-filter-compression | grep incompatible_features
174
No errors were found on the image.
219
175
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 encrypt.format=luks encrypt.key-secret=sec0 encrypt.iter-time=10
220
if $QEMU_IMG info "$TEST_IMG" >/dev/null 2>&1 ; then
176
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
221
echo "Error: The image opened successfully. The image must not be opened."
177
178
== cluster size 2048
179
== checking image refcounts ==
180
@@ -XXX,XX +XXX,XX @@ wrote 1/1 bytes at offset 2048
181
182
== rechecking image refcounts ==
183
No errors were found on the image.
184
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 encrypt.format=luks encrypt.key-secret=sec0 encrypt.iter-time=10
185
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
186
187
== cluster size 32768
188
== checking image refcounts ==
189
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
222
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
190
index XXXXXXX..XXXXXXX 100644
223
index XXXXXXX..XXXXXXX 100644
191
--- a/tests/qemu-iotests/common.filter
224
--- a/tests/qemu-iotests/common.filter
192
+++ b/tests/qemu-iotests/common.filter
225
+++ b/tests/qemu-iotests/common.filter
193
@@ -XXX,XX +XXX,XX @@ _filter_img_create()
226
@@ -XXX,XX +XXX,XX @@ _filter_img_info()
194
echo "$options" \
227
-e "/block_state_zero: \\(on\\|off\\)/d" \
195
| tr '\n' '\0' \
228
-e "/log_size: [0-9]\\+/d" \
196
| $SED -e 's/\x0$//' -e 's/ \([a-z0-9_.-]*\)=/\n\1=/g' \
229
-e "s/iters: [0-9]\\+/iters: 1024/" \
197
- | grep -ae "^\(fmt\\|size\\|backing\\|preallocation\\|encrypt$grep_data_file\\)" \
230
+ -e 's/\(compression type: \)\(zlib\|zstd\)/\1COMPRESSION_TYPE/' \
198
+ | grep -ae "^\(fmt\\|size\\|backing\\|preallocation\\|encryption$grep_data_file\\)" \
231
-e "s/uuid: [-a-f0-9]\\+/uuid: 00000000-0000-0000-0000-000000000000/" | \
199
| $SED "${filename_filters[@]}" \
232
while IFS='' read -r line; do
200
-e 's/^\(fmt\)/0-\1/' \
233
if [[ $format_specific == 1 ]]; then
201
-e 's/^\(size\)/1-\1/' \
234
@@ -XXX,XX +XXX,XX @@ _filter_authz_check_tls()
202
-e 's/^\(backing\)/2-\1/' \
235
$SED -e 's/TLS x509 authz check for .* is denied/TLS x509 authz check for DISTINGUISHED-NAME is denied/'
203
-e 's/^\(data_file\)/3-\1/' \
236
}
204
-e 's/^\(encryption\)/4-\1/' \
237
205
- -e 's/^\(encrypt\.format\)/5-\1/' \
238
+_filter_qcow2_compression_type_bit()
206
- -e 's/^\(encrypt\.key-secret\)/6-\1/' \
239
+{
207
- -e 's/^\(encrypt\.iter-time\)/7-\1/' \
240
+ $SED -e 's/\(incompatible_features\s\+\)\[3\(, \)\?/\1[/' \
208
-e 's/^\(preallocation\)/8-\1/' \
241
+ -e 's/\(incompatible_features.*\), 3\]/\1]/' \
209
| sort \
242
+ -e 's/\(incompatible_features.*\), 3\(,.*\)/\1\2/'
210
| $SED -e 's/^[0-9]-//' \
243
+}
244
+
245
# make sure this script returns success
246
true
247
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
248
index XXXXXXX..XXXXXXX 100644
249
--- a/tests/qemu-iotests/common.rc
250
+++ b/tests/qemu-iotests/common.rc
251
@@ -XXX,XX +XXX,XX @@ _img_info()
252
-e "s#$TEST_DIR#TEST_DIR#g" \
253
-e "s#$SOCK_DIR/fuse-#TEST_DIR/#g" \
254
-e "s#$IMGFMT#IMGFMT#g" \
255
+ -e 's/\(compression type: \)\(zlib\|zstd\)/\1COMPRESSION_TYPE/' \
256
-e "/^disk size:/ D" \
257
-e "/actual-size/ D" | \
258
while IFS='' read -r line; do
259
@@ -XXX,XX +XXX,XX @@ _require_one_device_of()
260
261
_qcow2_dump_header()
262
{
263
+ if [[ "$1" == "--no-filter-compression" ]]; then
264
+ local filter_compression=0
265
+ shift
266
+ else
267
+ local filter_compression=1
268
+ fi
269
+
270
img="$1"
271
if [ -z "$img" ]; then
272
img="$TEST_IMG"
273
fi
274
275
- $PYTHON qcow2.py "$img" dump-header
276
+ if [[ $filter_compression == 0 ]]; then
277
+ $PYTHON qcow2.py "$img" dump-header
278
+ else
279
+ $PYTHON qcow2.py "$img" dump-header | _filter_qcow2_compression_type_bit
280
+ fi
281
}
282
283
# make sure this script returns success
211
--
284
--
212
2.26.2
285
2.34.1
213
286
214
287
diff view generated by jsdifflib
1
From: Maxim Levitsky <mlevitsk@redhat.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
3
Don't touch other incompatible bits, like compression-type. This makes
4
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
4
the test pass with IMGOPTS='compression_type=zstd'.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
5
Reviewed-by: Max Reitz <mreitz@redhat.com>
7
Reviewed-by: Max Reitz <mreitz@redhat.com>
6
Message-Id: <20200608094030.670121-13-mlevitsk@redhat.com>
8
Message-Id: <20211223160144.1097696-18-vsementsov@virtuozzo.com>
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
8
---
10
---
9
qapi/block-core.json | 14 ++++++++-
11
tests/qemu-iotests/060 | 2 +-
10
block/crypto.c | 72 ++++++++++++++++++++++++++++++++------------
12
1 file changed, 1 insertion(+), 1 deletion(-)
11
2 files changed, 66 insertions(+), 20 deletions(-)
12
13
13
diff --git a/qapi/block-core.json b/qapi/block-core.json
14
diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100755
15
--- a/qapi/block-core.json
16
--- a/tests/qemu-iotests/060
16
+++ b/qapi/block-core.json
17
+++ b/tests/qemu-iotests/060
17
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ _make_test_img 64M
18
'data': { 'job-id': 'str',
19
# Let the refblock appear unaligned
19
'options': 'BlockdevCreateOptions' } }
20
poke_file "$TEST_IMG" "$rt_offset" "\x00\x00\x00\x00\xff\xff\x2a\x00"
20
21
# Mark the image dirty, thus forcing an automatic check when opening it
21
+##
22
-poke_file "$TEST_IMG" 72 "\x00\x00\x00\x00\x00\x00\x00\x01"
22
+# @BlockdevAmendOptionsLUKS:
23
+$PYTHON qcow2.py "$TEST_IMG" set-feature-bit incompatible 0
23
+#
24
# Open the image (qemu should refuse to do so)
24
+# Driver specific image amend options for LUKS.
25
$QEMU_IO -c close "$TEST_IMG" 2>&1 | _filter_testdir | _filter_imgfmt
25
+#
26
+# Since: 5.1
27
+##
28
+{ 'struct': 'BlockdevAmendOptionsLUKS',
29
+ 'base': 'QCryptoBlockAmendOptionsLUKS',
30
+ 'data': { }
31
+}
32
+
33
##
34
# @BlockdevAmendOptions:
35
#
36
@@ -XXX,XX +XXX,XX @@
37
'driver': 'BlockdevDriver' },
38
'discriminator': 'driver',
39
'data': {
40
- } }
41
+ 'luks': 'BlockdevAmendOptionsLUKS' } }
42
43
##
44
# @x-blockdev-amend:
45
diff --git a/block/crypto.c b/block/crypto.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/block/crypto.c
48
+++ b/block/crypto.c
49
@@ -XXX,XX +XXX,XX @@ block_crypto_get_specific_info_luks(BlockDriverState *bs, Error **errp)
50
}
51
52
static int
53
-block_crypto_amend_options_luks(BlockDriverState *bs,
54
- QemuOpts *opts,
55
- BlockDriverAmendStatusCB *status_cb,
56
- void *cb_opaque,
57
- bool force,
58
- Error **errp)
59
+block_crypto_amend_options_generic_luks(BlockDriverState *bs,
60
+ QCryptoBlockAmendOptions *amend_options,
61
+ bool force,
62
+ Error **errp)
63
{
64
BlockCrypto *crypto = bs->opaque;
65
- QDict *cryptoopts = NULL;
66
- QCryptoBlockAmendOptions *amend_options = NULL;
67
int ret;
68
69
assert(crypto);
70
assert(crypto->block);
71
- crypto->updating_keys = true;
72
73
+ /* apply for exclusive read/write permissions to the underlying file*/
74
+ crypto->updating_keys = true;
75
ret = bdrv_child_refresh_perms(bs, bs->file, errp);
76
- if (ret < 0) {
77
- goto cleanup;
78
- }
79
-
80
- cryptoopts = qemu_opts_to_qdict(opts, NULL);
81
- qdict_put_str(cryptoopts, "format", "luks");
82
- amend_options = block_crypto_amend_opts_init(cryptoopts, errp);
83
- if (!amend_options) {
84
- ret = -EINVAL;
85
+ if (ret) {
86
goto cleanup;
87
}
88
89
@@ -XXX,XX +XXX,XX @@ block_crypto_amend_options_luks(BlockDriverState *bs,
90
force,
91
errp);
92
cleanup:
93
+ /* release exclusive read/write permissions to the underlying file*/
94
crypto->updating_keys = false;
95
bdrv_child_refresh_perms(bs, bs->file, errp);
96
- qapi_free_QCryptoBlockAmendOptions(amend_options);
97
+ return ret;
98
+}
99
+
100
+static int
101
+block_crypto_amend_options_luks(BlockDriverState *bs,
102
+ QemuOpts *opts,
103
+ BlockDriverAmendStatusCB *status_cb,
104
+ void *cb_opaque,
105
+ bool force,
106
+ Error **errp)
107
+{
108
+ BlockCrypto *crypto = bs->opaque;
109
+ QDict *cryptoopts = NULL;
110
+ QCryptoBlockAmendOptions *amend_options = NULL;
111
+ int ret = -EINVAL;
112
+
113
+ assert(crypto);
114
+ assert(crypto->block);
115
+
116
+ cryptoopts = qemu_opts_to_qdict(opts, NULL);
117
+ qdict_put_str(cryptoopts, "format", "luks");
118
+ amend_options = block_crypto_amend_opts_init(cryptoopts, errp);
119
qobject_unref(cryptoopts);
120
+ if (!amend_options) {
121
+ goto cleanup;
122
+ }
123
+ ret = block_crypto_amend_options_generic_luks(bs, amend_options,
124
+ force, errp);
125
+cleanup:
126
+ qapi_free_QCryptoBlockAmendOptions(amend_options);
127
return ret;
128
}
129
130
+static int
131
+coroutine_fn block_crypto_co_amend_luks(BlockDriverState *bs,
132
+ BlockdevAmendOptions *opts,
133
+ bool force,
134
+ Error **errp)
135
+{
136
+ QCryptoBlockAmendOptions amend_opts;
137
+
138
+ amend_opts = (QCryptoBlockAmendOptions) {
139
+ .format = Q_CRYPTO_BLOCK_FORMAT_LUKS,
140
+ .u.luks = *qapi_BlockdevAmendOptionsLUKS_base(&opts->u.luks),
141
+ };
142
+ return block_crypto_amend_options_generic_luks(bs, &amend_opts,
143
+ force, errp);
144
+}
145
146
static void
147
block_crypto_child_perms(BlockDriverState *bs, BdrvChild *c,
148
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_crypto_luks = {
149
.bdrv_get_info = block_crypto_get_info_luks,
150
.bdrv_get_specific_info = block_crypto_get_specific_info_luks,
151
.bdrv_amend_options = block_crypto_amend_options_luks,
152
+ .bdrv_co_amend = block_crypto_co_amend_luks,
153
154
.is_format = true,
155
26
156
--
27
--
157
2.26.2
28
2.34.1
158
29
159
30
diff view generated by jsdifflib
1
From: Maxim Levitsky <mlevitsk@redhat.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
rename the write_func to create_write_func, and init_func to create_init_func.
3
The test-case "Corrupted size field in compressed cluster descriptor"
4
This is preparation for other write_func that will be used to update the encryption keys.
4
heavily depends on zlib compression type. So, make it explicit. This
5
way test passes with IMGOPTS='compression_type=zstd'.
5
6
6
No functional changes
7
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
Message-Id: <20211223160144.1097696-19-vsementsov@virtuozzo.com>
10
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
11
---
12
tests/qemu-iotests/214 | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
7
14
8
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
15
diff --git a/tests/qemu-iotests/214 b/tests/qemu-iotests/214
9
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
16
index XXXXXXX..XXXXXXX 100755
10
Message-Id: <20200608094030.670121-7-mlevitsk@redhat.com>
17
--- a/tests/qemu-iotests/214
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
18
+++ b/tests/qemu-iotests/214
12
---
19
@@ -XXX,XX +XXX,XX @@ echo
13
block/crypto.c | 25 ++++++++++++-------------
20
# The L2 entries of the two compressed clusters are located at
14
1 file changed, 12 insertions(+), 13 deletions(-)
21
# 0x800000 and 0x800008, their original values are 0x4008000000a00000
15
22
# and 0x4008000000a00802 (5 sectors for compressed data each).
16
diff --git a/block/crypto.c b/block/crypto.c
23
-_make_test_img 8M -o cluster_size=2M
17
index XXXXXXX..XXXXXXX 100644
24
+_make_test_img 8M -o cluster_size=2M,compression_type=zlib
18
--- a/block/crypto.c
25
$QEMU_IO -c "write -c -P 0x11 0 2M" -c "write -c -P 0x11 2M 2M" "$TEST_IMG" \
19
+++ b/block/crypto.c
26
2>&1 | _filter_qemu_io | _filter_testdir
20
@@ -XXX,XX +XXX,XX @@ struct BlockCryptoCreateData {
21
};
22
23
24
-static ssize_t block_crypto_write_func(QCryptoBlock *block,
25
- size_t offset,
26
- const uint8_t *buf,
27
- size_t buflen,
28
- void *opaque,
29
- Error **errp)
30
+static ssize_t block_crypto_create_write_func(QCryptoBlock *block,
31
+ size_t offset,
32
+ const uint8_t *buf,
33
+ size_t buflen,
34
+ void *opaque,
35
+ Error **errp)
36
{
37
struct BlockCryptoCreateData *data = opaque;
38
ssize_t ret;
39
@@ -XXX,XX +XXX,XX @@ static ssize_t block_crypto_write_func(QCryptoBlock *block,
40
return ret;
41
}
42
43
-
44
-static ssize_t block_crypto_init_func(QCryptoBlock *block,
45
- size_t headerlen,
46
- void *opaque,
47
- Error **errp)
48
+static ssize_t block_crypto_create_init_func(QCryptoBlock *block,
49
+ size_t headerlen,
50
+ void *opaque,
51
+ Error **errp)
52
{
53
struct BlockCryptoCreateData *data = opaque;
54
Error *local_error = NULL;
55
@@ -XXX,XX +XXX,XX @@ static int block_crypto_co_create_generic(BlockDriverState *bs,
56
};
57
58
crypto = qcrypto_block_create(opts, NULL,
59
- block_crypto_init_func,
60
- block_crypto_write_func,
61
+ block_crypto_create_init_func,
62
+ block_crypto_create_write_func,
63
&data,
64
errp);
65
27
66
--
28
--
67
2.26.2
29
2.34.1
68
30
69
31
diff view generated by jsdifflib
1
Right now, _filter_img_create just filters out everything that looks
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
format-dependent, and applies some filename filters. That means that we
3
have to add another filter line every time some format gets a new
4
creation option. This can be avoided by instead discarding everything
5
and just keeping what we know is format-independent (format, size,
6
backing file, encryption information[1], preallocation) or just
7
interesting to have in the reference output (external data file path).
8
2
9
Furthermore, we probably want to sort these options. Format drivers are
3
compression_type can't be used if we want to create image with
10
not required to define them in any specific order, so the output is
4
compat=0.10. So, skip these tests, not many of them.
11
effectively random (although this has never bothered us until now). We
12
need a specific order for our reference outputs, though. Unfortunately,
13
just using a plain "sort" would change a lot of existing reference
14
outputs, so we have to pre-filter the option keys to keep our existing
15
order (fmt, size, backing*, data, encryption info, preallocation).
16
5
17
Finally, this makes it difficult for _filter_img_create to automagically
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
18
work for QMP output. Thus, this patch adds a separate
7
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
19
_filter_img_create_for_qmp function that echos every line verbatim that
8
Message-Id: <20211223160144.1097696-20-vsementsov@virtuozzo.com>
20
does not start with "Formatting", and pipes those "Formatting" lines to
9
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
21
_filter_img_create.
10
---
11
tests/qemu-iotests/031 | 5 +++--
12
tests/qemu-iotests/051 | 5 +++--
13
tests/qemu-iotests/061 | 6 +++++-
14
tests/qemu-iotests/112 | 3 ++-
15
tests/qemu-iotests/290 | 2 +-
16
5 files changed, 14 insertions(+), 7 deletions(-)
22
17
23
[1] Actually, the only thing that is really important is whether
18
diff --git a/tests/qemu-iotests/031 b/tests/qemu-iotests/031
24
encryption is enabled or not. A patch by Maxim thus removes all
25
other "encrypt.*" options from the output:
26
https://lists.nongnu.org/archive/html/qemu-block/2020-06/msg00339.html
27
But that patch needs to come later so we can get away with changing
28
as few reference outputs in this patch here as possible.
29
30
Signed-off-by: Max Reitz <mreitz@redhat.com>
31
Message-Id: <20200618150628.2169239-2-mreitz@redhat.com>
32
---
33
tests/qemu-iotests/112.out | 2 +-
34
tests/qemu-iotests/141 | 2 +-
35
tests/qemu-iotests/153 | 9 ++-
36
tests/qemu-iotests/common.filter | 96 ++++++++++++++++++++++++--------
37
4 files changed, 78 insertions(+), 31 deletions(-)
38
39
diff --git a/tests/qemu-iotests/112.out b/tests/qemu-iotests/112.out
40
index XXXXXXX..XXXXXXX 100644
41
--- a/tests/qemu-iotests/112.out
42
+++ b/tests/qemu-iotests/112.out
43
@@ -XXX,XX +XXX,XX @@ QA output created by 112
44
qemu-img: TEST_DIR/t.IMGFMT: Refcount width must be a power of two and may not exceed 64 bits
45
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
46
qemu-img: TEST_DIR/t.IMGFMT: Refcount width must be a power of two and may not exceed 64 bits
47
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 refcount_bits=-1
48
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
49
qemu-img: TEST_DIR/t.IMGFMT: Refcount width must be a power of two and may not exceed 64 bits
50
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
51
qemu-img: TEST_DIR/t.IMGFMT: Refcount width must be a power of two and may not exceed 64 bits
52
diff --git a/tests/qemu-iotests/141 b/tests/qemu-iotests/141
53
index XXXXXXX..XXXXXXX 100755
19
index XXXXXXX..XXXXXXX 100755
54
--- a/tests/qemu-iotests/141
20
--- a/tests/qemu-iotests/031
55
+++ b/tests/qemu-iotests/141
21
+++ b/tests/qemu-iotests/031
56
@@ -XXX,XX +XXX,XX @@ test_blockjob()
22
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
57
_send_qemu_cmd $QEMU_HANDLE \
23
_supported_fmt qcow2
58
"$1" \
24
_supported_proto file fuse
59
"$2" \
25
# We want to test compat=0.10, which does not support external data
60
- | _filter_img_create | _filter_qmp_empty_return
26
-# files or refcount widths other than 16
61
+ | _filter_img_create_in_qmp | _filter_qmp_empty_return
27
-_unsupported_imgopts data_file 'refcount_bits=\([^1]\|.\([^6]\|$\)\)'
62
28
+# files or refcount widths other than 16 or compression type
63
# We want this to return an error because the block job is still running
29
+_unsupported_imgopts data_file compression_type \
64
_send_qemu_cmd $QEMU_HANDLE \
30
+ 'refcount_bits=\([^1]\|.\([^6]\|$\)\)'
65
diff --git a/tests/qemu-iotests/153 b/tests/qemu-iotests/153
31
32
CLUSTER_SIZE=65536
33
34
diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051
66
index XXXXXXX..XXXXXXX 100755
35
index XXXXXXX..XXXXXXX 100755
67
--- a/tests/qemu-iotests/153
36
--- a/tests/qemu-iotests/051
68
+++ b/tests/qemu-iotests/153
37
+++ b/tests/qemu-iotests/051
69
@@ -XXX,XX +XXX,XX @@ done
38
@@ -XXX,XX +XXX,XX @@ _supported_fmt qcow2
39
_supported_proto file
40
# A compat=0.10 image is created in this test which does not support anything
41
# other than refcount_bits=16;
42
-# it also will not support an external data file
43
-_unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)' data_file
44
+# it also will not support an external data file and compression type
45
+_unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)' data_file \
46
+ compression_type
47
_require_drivers nbd
48
49
if [ "$QEMU_DEFAULT_MACHINE" = "pc" ]; then
50
diff --git a/tests/qemu-iotests/061 b/tests/qemu-iotests/061
51
index XXXXXXX..XXXXXXX 100755
52
--- a/tests/qemu-iotests/061
53
+++ b/tests/qemu-iotests/061
54
@@ -XXX,XX +XXX,XX @@ _supported_os Linux
55
# not work with it;
56
# we have explicit tests for various cluster sizes, the remaining tests
57
# require the default 64k cluster
58
-_unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)' data_file cluster_size
59
+# we don't have explicit tests for zstd qcow2 compression type, as zstd may be
60
+# not compiled in. And we can't create compat images with comression type
61
+# extension
62
+_unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)' data_file \
63
+ cluster_size compression_type
70
64
71
echo
65
echo
72
echo "== Creating ${TEST_IMG}.[abc] ==" | _filter_testdir
66
echo "=== Testing version downgrade with zero expansion ==="
73
-(
67
diff --git a/tests/qemu-iotests/112 b/tests/qemu-iotests/112
74
- $QEMU_IMG create -f qcow2 "${TEST_IMG}.a" -b "${TEST_IMG}"
68
index XXXXXXX..XXXXXXX 100755
75
- $QEMU_IMG create -f qcow2 "${TEST_IMG}.b" -b "${TEST_IMG}"
69
--- a/tests/qemu-iotests/112
76
- $QEMU_IMG create -f qcow2 "${TEST_IMG}.c" -b "${TEST_IMG}.b"
70
+++ b/tests/qemu-iotests/112
77
-) | _filter_img_create
71
@@ -XXX,XX +XXX,XX @@ _supported_proto file fuse
78
+$QEMU_IMG create -f qcow2 "${TEST_IMG}.a" -b "${TEST_IMG}" | _filter_img_create
72
# This test will set refcount_bits on its own which would conflict with the
79
+$QEMU_IMG create -f qcow2 "${TEST_IMG}.b" -b "${TEST_IMG}" | _filter_img_create
73
# manual setting; compat will be overridden as well;
80
+$QEMU_IMG create -f qcow2 "${TEST_IMG}.c" -b "${TEST_IMG}.b" \
74
# and external data files do not work well with our refcount testing
81
+ | _filter_img_create
75
-_unsupported_imgopts refcount_bits 'compat=0.10' data_file
76
+# also, compression type is not supported with compat=0.10 used in test
77
+_unsupported_imgopts refcount_bits 'compat=0.10' data_file compression_type
78
79
print_refcount_bits()
80
{
81
diff --git a/tests/qemu-iotests/290 b/tests/qemu-iotests/290
82
index XXXXXXX..XXXXXXX 100755
83
--- a/tests/qemu-iotests/290
84
+++ b/tests/qemu-iotests/290
85
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
86
_supported_fmt qcow2
87
_supported_proto file fuse
88
_supported_os Linux
89
-_unsupported_imgopts 'compat=0.10' refcount_bits data_file
90
+_unsupported_imgopts 'compat=0.10' refcount_bits data_file compression_type
82
91
83
echo
92
echo
84
echo "== Two devices sharing the same file in backing chain =="
93
echo "### Test 'qemu-io -c discard' on a QCOW2 image without a backing file"
85
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
86
index XXXXXXX..XXXXXXX 100644
87
--- a/tests/qemu-iotests/common.filter
88
+++ b/tests/qemu-iotests/common.filter
89
@@ -XXX,XX +XXX,XX @@ _filter_actual_image_size()
90
# replace driver-specific options in the "Formatting..." line
91
_filter_img_create()
92
{
93
- data_file_filter=()
94
- if data_file=$(_get_data_file "$TEST_IMG"); then
95
- data_file_filter=(-e "s# data_file=$data_file##")
96
+ # Split the line into the pre-options part ($filename_part, which
97
+ # precedes ", fmt=") and the options part ($options, which starts
98
+ # with "fmt=")
99
+ readarray -td '' formatting_line < <(sed -e 's/, fmt=/\x0/')
100
+
101
+ filename_part=${formatting_line[0]}
102
+ if [ -n "${formatting_line[1]}" ]; then
103
+ options="fmt=${formatting_line[1]}"
104
+ else
105
+ options=''
106
+ fi
107
+
108
+ # Set grep_data_file to '\|data_file' to keep it; make it empty
109
+ # to drop it.
110
+ # We want to drop it if it is part of the global $IMGOPTS, and we
111
+ # want to keep it otherwise (if the test specifically wants to
112
+ # test data files).
113
+ grep_data_file='\|data_file'
114
+ if _get_data_file "$TEST_IMG" > /dev/null; then
115
+ grep_data_file=''
116
fi
117
118
- $SED "${data_file_filter[@]}" \
119
+ filename_filters=(
120
-e "s#$REMOTE_TEST_DIR#TEST_DIR#g" \
121
-e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \
122
-e "s#$TEST_DIR#TEST_DIR#g" \
123
-e "s#$SOCK_DIR#SOCK_DIR#g" \
124
-e "s#$IMGFMT#IMGFMT#g" \
125
-e 's#nbd:127.0.0.1:[0-9]\\+#TEST_DIR/t.IMGFMT#g' \
126
- -e 's#nbd+unix:///\??socket=SOCK_DIR/nbd#TEST_DIR/t.IMGFMT#g' \
127
- -e "s# encryption=off##g" \
128
- -e "s# cluster_size=[0-9]\\+##g" \
129
- -e "s# table_size=[0-9]\\+##g" \
130
- -e "s# compat=[^ ]*##g" \
131
- -e "s# compat6=\\(on\\|off\\)##g" \
132
- -e "s# static=\\(on\\|off\\)##g" \
133
- -e "s# zeroed_grain=\\(on\\|off\\)##g" \
134
- -e "s# subformat=[^ ]*##g" \
135
- -e "s# adapter_type=[^ ]*##g" \
136
- -e "s# hwversion=[^ ]*##g" \
137
- -e "s# lazy_refcounts=\\(on\\|off\\)##g" \
138
- -e "s# block_size=[0-9]\\+##g" \
139
- -e "s# block_state_zero=\\(on\\|off\\)##g" \
140
- -e "s# log_size=[0-9]\\+##g" \
141
- -e "s# refcount_bits=[0-9]\\+##g" \
142
- -e "s# key-secret=[a-zA-Z0-9]\\+##g" \
143
- -e "s# iter-time=[0-9]\\+##g" \
144
- -e "s# force_size=\\(on\\|off\\)##g" \
145
- -e "s# compression_type=[a-zA-Z0-9]\\+##g"
146
+ -e 's#nbd+unix:///\??socket=SOCK_DIR/nbd#TEST_DIR/t.IMGFMT#g'
147
+ )
148
+
149
+ filename_part=$(echo "$filename_part" | $SED "${filename_filters[@]}")
150
+
151
+ # Break the option line before each option (preserving pre-existing
152
+ # line breaks by replacing them by \0 and restoring them at the end),
153
+ # then filter out the options we want to keep and sort them according
154
+ # to some order that all block drivers used at the time of writing
155
+ # this function.
156
+ options=$(
157
+ echo "$options" \
158
+ | tr '\n' '\0' \
159
+ | $SED -e 's/\x0$//' -e 's/ \([a-z0-9_.-]*\)=/\n\1=/g' \
160
+ | grep -ae "^\(fmt\\|size\\|backing\\|preallocation\\|encrypt$grep_data_file\\)" \
161
+ | $SED "${filename_filters[@]}" \
162
+ -e 's/^\(fmt\)/0-\1/' \
163
+ -e 's/^\(size\)/1-\1/' \
164
+ -e 's/^\(backing\)/2-\1/' \
165
+ -e 's/^\(data_file\)/3-\1/' \
166
+ -e 's/^\(encryption\)/4-\1/' \
167
+ -e 's/^\(encrypt\.format\)/5-\1/' \
168
+ -e 's/^\(encrypt\.key-secret\)/6-\1/' \
169
+ -e 's/^\(encrypt\.iter-time\)/7-\1/' \
170
+ -e 's/^\(preallocation\)/8-\1/' \
171
+ | sort \
172
+ | $SED -e 's/^[0-9]-//' \
173
+ | tr '\n\0' ' \n' \
174
+ | $SED -e 's/^ *$//' -e 's/ *$//'
175
+ )
176
+
177
+ if [ -n "$options" ]; then
178
+ echo "$filename_part, $options"
179
+ elif [ -n "$filename_part" ]; then
180
+ echo "$filename_part"
181
+ fi
182
+}
183
+
184
+# Filter the "Formatting..." line in QMP output (leaving the QMP output
185
+# untouched)
186
+# (In contrast to _filter_img_create(), this function does not support
187
+# multi-line Formatting output)
188
+_filter_img_create_in_qmp()
189
+{
190
+ while read -r line; do
191
+ if echo "$line" | grep -q '^Formatting'; then
192
+ echo "$line" | _filter_img_create
193
+ else
194
+ echo "$line"
195
+ fi
196
+ done
197
}
198
199
_filter_img_create_size()
200
--
94
--
201
2.26.2
95
2.34.1
202
96
203
97
diff view generated by jsdifflib
1
From: Maxim Levitsky <mlevitsk@redhat.com>
1
After migration, the permissions the guest device wants to impose on its
2
BlockBackend are stored in blk->perm and blk->shared_perm. In
3
blk_root_activate(), we take our permissions, but keep all shared
4
permissions open by calling `blk_set_perm(blk->perm, BLK_PERM_ALL)`.
2
5
3
This will be used first to implement luks keyslot management.
6
Only afterwards (immediately or later, depending on the runstate) do we
7
restrict the shared permissions by calling
8
`blk_set_perm(blk->perm, blk->shared_perm)`. Unfortunately, our first
9
call with shared_perm=BLK_PERM_ALL has overwritten blk->shared_perm to
10
be BLK_PERM_ALL, so this is a no-op and the set of shared permissions is
11
not restricted.
4
12
5
block_crypto_amend_opts_init will be used to convert
13
Fix this bug by saving the set of shared permissions before invoking
6
qemu-img cmdline to QCryptoBlockAmendOptions
14
blk_set_perm() with BLK_PERM_ALL and restoring it afterwards.
7
15
8
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
16
Fixes: 5f7772c4d0cf32f4e779fcd5a69ae4dae24aeebf
9
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
17
("block-backend: Defer shared_perm tightening migration
10
Message-Id: <20200608094030.670121-2-mlevitsk@redhat.com>
18
completion")
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
19
Reported-by: Peng Liang <liangpeng10@huawei.com>
20
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
21
Message-Id: <20211125135317.186576-2-hreitz@redhat.com>
22
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
23
Tested-by: Peng Liang <liangpeng10@huawei.com>
12
---
24
---
13
qapi/crypto.json | 16 ++++++++++++++++
25
block/block-backend.c | 11 +++++++++++
14
block/crypto.h | 3 +++
26
1 file changed, 11 insertions(+)
15
crypto/blockpriv.h | 8 ++++++++
16
include/crypto/block.h | 22 ++++++++++++++++++++++
17
block/crypto.c | 17 +++++++++++++++++
18
crypto/block.c | 29 +++++++++++++++++++++++++++++
19
6 files changed, 95 insertions(+)
20
27
21
diff --git a/qapi/crypto.json b/qapi/crypto.json
28
diff --git a/block/block-backend.c b/block/block-backend.c
22
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
23
--- a/qapi/crypto.json
30
--- a/block/block-backend.c
24
+++ b/qapi/crypto.json
31
+++ b/block/block-backend.c
25
@@ -XXX,XX +XXX,XX @@
32
@@ -XXX,XX +XXX,XX @@ static void blk_root_activate(BdrvChild *child, Error **errp)
26
'base': 'QCryptoBlockInfoBase',
33
{
27
'discriminator': 'format',
34
BlockBackend *blk = child->opaque;
28
'data': { 'luks': 'QCryptoBlockInfoLUKS' } }
35
Error *local_err = NULL;
36
+ uint64_t saved_shared_perm;
37
38
if (!blk->disable_perm) {
39
return;
40
@@ -XXX,XX +XXX,XX @@ static void blk_root_activate(BdrvChild *child, Error **errp)
41
42
blk->disable_perm = false;
43
44
+ /*
45
+ * blk->shared_perm contains the permissions we want to share once
46
+ * migration is really completely done. For now, we need to share
47
+ * all; but we also need to retain blk->shared_perm, which is
48
+ * overwritten by a successful blk_set_perm() call. Save it and
49
+ * restore it below.
50
+ */
51
+ saved_shared_perm = blk->shared_perm;
29
+
52
+
30
+
53
blk_set_perm(blk, blk->perm, BLK_PERM_ALL, &local_err);
31
+
54
if (local_err) {
32
+##
55
error_propagate(errp, local_err);
33
+# @QCryptoBlockAmendOptions:
56
blk->disable_perm = true;
34
+#
57
return;
35
+# The options that are available for all encryption formats
58
}
36
+# when amending encryption settings
59
+ blk->shared_perm = saved_shared_perm;
37
+#
60
38
+# Since: 5.1
61
if (runstate_check(RUN_STATE_INMIGRATE)) {
39
+##
62
/* Activation can happen when migration process is still active, for
40
+{ 'union': 'QCryptoBlockAmendOptions',
41
+ 'base': 'QCryptoBlockOptionsBase',
42
+ 'discriminator': 'format',
43
+ 'data': {
44
+ } }
45
diff --git a/block/crypto.h b/block/crypto.h
46
index XXXXXXX..XXXXXXX 100644
47
--- a/block/crypto.h
48
+++ b/block/crypto.h
49
@@ -XXX,XX +XXX,XX @@
50
QCryptoBlockCreateOptions *
51
block_crypto_create_opts_init(QDict *opts, Error **errp);
52
53
+QCryptoBlockAmendOptions *
54
+block_crypto_amend_opts_init(QDict *opts, Error **errp);
55
+
56
QCryptoBlockOpenOptions *
57
block_crypto_open_opts_init(QDict *opts, Error **errp);
58
59
diff --git a/crypto/blockpriv.h b/crypto/blockpriv.h
60
index XXXXXXX..XXXXXXX 100644
61
--- a/crypto/blockpriv.h
62
+++ b/crypto/blockpriv.h
63
@@ -XXX,XX +XXX,XX @@ struct QCryptoBlockDriver {
64
void *opaque,
65
Error **errp);
66
67
+ int (*amend)(QCryptoBlock *block,
68
+ QCryptoBlockReadFunc readfunc,
69
+ QCryptoBlockWriteFunc writefunc,
70
+ void *opaque,
71
+ QCryptoBlockAmendOptions *options,
72
+ bool force,
73
+ Error **errp);
74
+
75
int (*get_info)(QCryptoBlock *block,
76
QCryptoBlockInfo *info,
77
Error **errp);
78
diff --git a/include/crypto/block.h b/include/crypto/block.h
79
index XXXXXXX..XXXXXXX 100644
80
--- a/include/crypto/block.h
81
+++ b/include/crypto/block.h
82
@@ -XXX,XX +XXX,XX @@ QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options,
83
void *opaque,
84
Error **errp);
85
86
+/**
87
+ * qcrypto_block_amend_options:
88
+ * @block: the block encryption object
89
+ *
90
+ * @readfunc: callback for reading data from the volume header
91
+ * @writefunc: callback for writing data to the volume header
92
+ * @opaque: data to pass to @readfunc and @writefunc
93
+ * @options: the new/amended encryption options
94
+ * @force: hint for the driver to allow unsafe operation
95
+ * @errp: error pointer
96
+ *
97
+ * Changes the crypto options of the encryption format
98
+ *
99
+ */
100
+int qcrypto_block_amend_options(QCryptoBlock *block,
101
+ QCryptoBlockReadFunc readfunc,
102
+ QCryptoBlockWriteFunc writefunc,
103
+ void *opaque,
104
+ QCryptoBlockAmendOptions *options,
105
+ bool force,
106
+ Error **errp);
107
+
108
109
/**
110
* qcrypto_block_calculate_payload_offset:
111
diff --git a/block/crypto.c b/block/crypto.c
112
index XXXXXXX..XXXXXXX 100644
113
--- a/block/crypto.c
114
+++ b/block/crypto.c
115
@@ -XXX,XX +XXX,XX @@ block_crypto_create_opts_init(QDict *opts, Error **errp)
116
return ret;
117
}
118
119
+QCryptoBlockAmendOptions *
120
+block_crypto_amend_opts_init(QDict *opts, Error **errp)
121
+{
122
+ Visitor *v;
123
+ QCryptoBlockAmendOptions *ret;
124
+
125
+ v = qobject_input_visitor_new_flat_confused(opts, errp);
126
+ if (!v) {
127
+ return NULL;
128
+ }
129
+
130
+ visit_type_QCryptoBlockAmendOptions(v, NULL, &ret, errp);
131
+
132
+ visit_free(v);
133
+ return ret;
134
+}
135
+
136
137
static int block_crypto_open_generic(QCryptoBlockFormat format,
138
QemuOptsList *opts_spec,
139
diff --git a/crypto/block.c b/crypto/block.c
140
index XXXXXXX..XXXXXXX 100644
141
--- a/crypto/block.c
142
+++ b/crypto/block.c
143
@@ -XXX,XX +XXX,XX @@ qcrypto_block_calculate_payload_offset(QCryptoBlockCreateOptions *create_opts,
144
return crypto != NULL;
145
}
146
147
+int qcrypto_block_amend_options(QCryptoBlock *block,
148
+ QCryptoBlockReadFunc readfunc,
149
+ QCryptoBlockWriteFunc writefunc,
150
+ void *opaque,
151
+ QCryptoBlockAmendOptions *options,
152
+ bool force,
153
+ Error **errp)
154
+{
155
+ if (options->format != block->format) {
156
+ error_setg(errp,
157
+ "Cannot amend encryption format");
158
+ return -1;
159
+ }
160
+
161
+ if (!block->driver->amend) {
162
+ error_setg(errp,
163
+ "Crypto format %s doesn't support format options amendment",
164
+ QCryptoBlockFormat_str(block->format));
165
+ return -1;
166
+ }
167
+
168
+ return block->driver->amend(block,
169
+ readfunc,
170
+ writefunc,
171
+ opaque,
172
+ options,
173
+ force,
174
+ errp);
175
+}
176
177
QCryptoBlockInfo *qcrypto_block_get_info(QCryptoBlock *block,
178
Error **errp)
179
--
63
--
180
2.26.2
64
2.34.1
181
65
182
66
diff view generated by jsdifflib
1
From: Maxim Levitsky <mlevitsk@redhat.com>
1
This test checks that a raw image in use by a virtio-blk device does not
2
share the WRITE permission both before and after migration.
2
3
3
This commit adds two tests that cover the
4
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
4
new blockdev-amend functionality of luks and qcow2 driver
5
---
6
.../qemu-iotests/tests/migration-permissions | 101 ++++++++++++++++++
7
.../tests/migration-permissions.out | 5 +
8
2 files changed, 106 insertions(+)
9
create mode 100755 tests/qemu-iotests/tests/migration-permissions
10
create mode 100644 tests/qemu-iotests/tests/migration-permissions.out
5
11
6
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
12
diff --git a/tests/qemu-iotests/tests/migration-permissions b/tests/qemu-iotests/tests/migration-permissions
7
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
8
Message-Id: <20200608094030.670121-15-mlevitsk@redhat.com>
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
---
11
tests/qemu-iotests/295 | 279 +++++++++++++++++++++++++++++++++++++
12
tests/qemu-iotests/295.out | 40 ++++++
13
tests/qemu-iotests/296 | 234 +++++++++++++++++++++++++++++++
14
tests/qemu-iotests/296.out | 33 +++++
15
tests/qemu-iotests/group | 2 +
16
5 files changed, 588 insertions(+)
17
create mode 100755 tests/qemu-iotests/295
18
create mode 100644 tests/qemu-iotests/295.out
19
create mode 100755 tests/qemu-iotests/296
20
create mode 100644 tests/qemu-iotests/296.out
21
22
diff --git a/tests/qemu-iotests/295 b/tests/qemu-iotests/295
23
new file mode 100755
13
new file mode 100755
24
index XXXXXXX..XXXXXXX
14
index XXXXXXX..XXXXXXX
25
--- /dev/null
15
--- /dev/null
26
+++ b/tests/qemu-iotests/295
16
+++ b/tests/qemu-iotests/tests/migration-permissions
27
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@
28
+#!/usr/bin/env python3
18
+#!/usr/bin/env python3
19
+# group: migration
29
+#
20
+#
30
+# Test case QMP's encrypted key management
21
+# Copyright (C) 2021 Red Hat, Inc.
31
+#
32
+# Copyright (C) 2019 Red Hat, Inc.
33
+#
22
+#
34
+# This program is free software; you can redistribute it and/or modify
23
+# This program is free software; you can redistribute it and/or modify
35
+# it under the terms of the GNU General Public License as published by
24
+# it under the terms of the GNU General Public License as published by
36
+# the Free Software Foundation; either version 2 of the License, or
25
+# the Free Software Foundation; either version 2 of the License, or
37
+# (at your option) any later version.
26
+# (at your option) any later version.
...
...
43
+#
32
+#
44
+# You should have received a copy of the GNU General Public License
33
+# You should have received a copy of the GNU General Public License
45
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
34
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
46
+#
35
+#
47
+
36
+
37
+import os
48
+import iotests
38
+import iotests
49
+import os
39
+from iotests import imgfmt, qemu_img_create, qemu_io
50
+import time
40
+
51
+import json
52
+
41
+
53
+test_img = os.path.join(iotests.test_dir, 'test.img')
42
+test_img = os.path.join(iotests.test_dir, 'test.img')
43
+mig_sock = os.path.join(iotests.sock_dir, 'mig.sock')
54
+
44
+
55
+class Secret:
56
+ def __init__(self, index):
57
+ self._id = "keysec" + str(index)
58
+ # you are not supposed to see the password...
59
+ self._secret = "hunter" + str(index)
60
+
45
+
61
+ def id(self):
46
+class TestMigrationPermissions(iotests.QMPTestCase):
62
+ return self._id
47
+ def setUp(self):
48
+ qemu_img_create('-f', imgfmt, test_img, '1M')
63
+
49
+
64
+ def secret(self):
50
+ # Set up two VMs (source and destination) accessing the same raw
65
+ return self._secret
51
+ # image file with a virtio-blk device; prepare the destination for
52
+ # migration with .add_incoming() and enable migration events
53
+ vms = [None, None]
54
+ for i in range(2):
55
+ vms[i] = iotests.VM(path_suffix=f'{i}')
56
+ vms[i].add_blockdev(f'file,node-name=prot,filename={test_img}')
57
+ vms[i].add_blockdev(f'{imgfmt},node-name=fmt,file=prot')
58
+ vms[i].add_device('virtio-blk,drive=fmt')
66
+
59
+
67
+ def to_cmdline_object(self):
60
+ if i == 1:
68
+ return [ "secret,id=" + self._id + ",data=" + self._secret]
61
+ vms[i].add_incoming(f'unix:{mig_sock}')
69
+
62
+
70
+ def to_qmp_object(self):
63
+ vms[i].launch()
71
+ return { "qom_type" : "secret", "id": self.id(),
72
+ "props": { "data": self.secret() } }
73
+
64
+
74
+################################################################################
65
+ result = vms[i].qmp('migrate-set-capabilities',
75
+class EncryptionSetupTestCase(iotests.QMPTestCase):
66
+ capabilities=[
76
+
67
+ {'capability': 'events', 'state': True}
77
+ # test case startup
68
+ ])
78
+ def setUp(self):
79
+ # start the VM
80
+ self.vm = iotests.VM()
81
+ self.vm.launch()
82
+
83
+ # create the secrets and load 'em into the VM
84
+ self.secrets = [ Secret(i) for i in range(0, 6) ]
85
+ for secret in self.secrets:
86
+ result = self.vm.qmp("object-add", **secret.to_qmp_object())
87
+ self.assert_qmp(result, 'return', {})
69
+ self.assert_qmp(result, 'return', {})
88
+
70
+
89
+ if iotests.imgfmt == "qcow2":
71
+ self.vm_s = vms[0]
90
+ self.pfx = "encrypt."
72
+ self.vm_d = vms[1]
91
+ self.img_opts = [ '-o', "encrypt.format=luks" ]
92
+ else:
93
+ self.pfx = ""
94
+ self.img_opts = []
95
+
73
+
96
+ # test case shutdown
97
+ def tearDown(self):
74
+ def tearDown(self):
98
+ # stop the VM
75
+ self.vm_s.shutdown()
99
+ self.vm.shutdown()
76
+ self.vm_d.shutdown()
100
+
77
+ try:
101
+ ###########################################################################
78
+ os.remove(mig_sock)
102
+ # create the encrypted block device
79
+ except FileNotFoundError:
103
+ def createImg(self, file, secret):
80
+ pass
104
+
105
+ iotests.qemu_img(
106
+ 'create',
107
+ '--object', *secret.to_cmdline_object(),
108
+ '-f', iotests.imgfmt,
109
+ '-o', self.pfx + 'key-secret=' + secret.id(),
110
+ '-o', self.pfx + 'iter-time=10',
111
+ *self.img_opts,
112
+ file,
113
+ '1M')
114
+
115
+ ###########################################################################
116
+ # open an encrypted block device
117
+ def openImageQmp(self, id, file, secret, read_only = False):
118
+
119
+ encrypt_options = {
120
+ 'key-secret' : secret.id()
121
+ }
122
+
123
+ if iotests.imgfmt == "qcow2":
124
+ encrypt_options = {
125
+ 'encrypt': {
126
+ 'format':'luks',
127
+ **encrypt_options
128
+ }
129
+ }
130
+
131
+ result = self.vm.qmp('blockdev-add', **
132
+ {
133
+ 'driver': iotests.imgfmt,
134
+ 'node-name': id,
135
+ 'read-only': read_only,
136
+
137
+ **encrypt_options,
138
+
139
+ 'file': {
140
+ 'driver': 'file',
141
+ 'filename': test_img,
142
+ }
143
+ }
144
+ )
145
+ self.assert_qmp(result, 'return', {})
146
+
147
+ # close the encrypted block device
148
+ def closeImageQmp(self, id):
149
+ result = self.vm.qmp('blockdev-del', **{ 'node-name': id })
150
+ self.assert_qmp(result, 'return', {})
151
+
152
+ ###########################################################################
153
+ # add a key to an encrypted block device
154
+ def addKeyQmp(self, id, new_secret, secret = None,
155
+ slot = None, force = False):
156
+
157
+ crypt_options = {
158
+ 'state' : 'active',
159
+ 'new-secret' : new_secret.id(),
160
+ 'iter-time' : 10
161
+ }
162
+
163
+ if slot != None:
164
+ crypt_options['keyslot'] = slot
165
+
166
+
167
+ if secret != None:
168
+ crypt_options['secret'] = secret.id()
169
+
170
+ if iotests.imgfmt == "qcow2":
171
+ crypt_options['format'] = 'luks'
172
+ crypt_options = {
173
+ 'encrypt': crypt_options
174
+ }
175
+
176
+ args = {
177
+ 'node-name': id,
178
+ 'job-id' : 'job_add_key',
179
+ 'options' : {
180
+ 'driver' : iotests.imgfmt,
181
+ **crypt_options
182
+ },
183
+ }
184
+
185
+ if force == True:
186
+ args['force'] = True
187
+
188
+ #TODO: check what jobs return
189
+ result = self.vm.qmp('x-blockdev-amend', **args)
190
+ assert result['return'] == {}
191
+ self.vm.run_job('job_add_key')
192
+
193
+ # erase a key from an encrypted block device
194
+ def eraseKeyQmp(self, id, old_secret = None, slot = None, force = False):
195
+
196
+ crypt_options = {
197
+ 'state' : 'inactive',
198
+ }
199
+
200
+ if slot != None:
201
+ crypt_options['keyslot'] = slot
202
+ if old_secret != None:
203
+ crypt_options['old-secret'] = old_secret.id()
204
+
205
+ if iotests.imgfmt == "qcow2":
206
+ crypt_options['format'] = 'luks'
207
+ crypt_options = {
208
+ 'encrypt': crypt_options
209
+ }
210
+
211
+ args = {
212
+ 'node-name': id,
213
+ 'job-id' : 'job_erase_key',
214
+ 'options' : {
215
+ 'driver' : iotests.imgfmt,
216
+ **crypt_options
217
+ },
218
+ }
219
+
220
+ if force == True:
221
+ args['force'] = True
222
+
223
+ result = self.vm.qmp('x-blockdev-amend', **args)
224
+ assert result['return'] == {}
225
+ self.vm.run_job('job_erase_key')
226
+
227
+ ###########################################################################
228
+ # create image, and change its key
229
+ def testChangeKey(self):
230
+
231
+ # create the image with secret0 and open it
232
+ self.createImg(test_img, self.secrets[0]);
233
+ self.openImageQmp("testdev", test_img, self.secrets[0])
234
+
235
+ # add key to slot 1
236
+ self.addKeyQmp("testdev", new_secret = self.secrets[1])
237
+
238
+ # add key to slot 5
239
+ self.addKeyQmp("testdev", new_secret = self.secrets[2], slot=5)
240
+
241
+ # erase key from slot 0
242
+ self.eraseKeyQmp("testdev", old_secret = self.secrets[0])
243
+
244
+ #reopen the image with secret1
245
+ self.closeImageQmp("testdev")
246
+ self.openImageQmp("testdev", test_img, self.secrets[1])
247
+
248
+ # close and erase the image for good
249
+ self.closeImageQmp("testdev")
250
+ os.remove(test_img)
81
+ os.remove(test_img)
251
+
82
+
252
+ # test that if we erase the old password,
83
+ # Migrate an image in use by a virtio-blk device to another VM and
253
+ # we can still change the encryption keys using 'old-secret'
84
+ # verify that the WRITE permission is unshared both before and after
254
+ def testOldPassword(self):
85
+ # migration
86
+ def test_post_migration_permissions(self):
87
+ # Try to access the image R/W, which should fail because virtio-blk
88
+ # has not been configured with share-rw=on
89
+ log = qemu_io('-f', imgfmt, '-c', 'quit', test_img)
90
+ if not log.strip():
91
+ print('ERROR (pre-migration): qemu-io should not be able to '
92
+ 'access this image, but it reported no error')
93
+ else:
94
+ # This is the expected output
95
+ assert 'Is another process using the image' in log
255
+
96
+
256
+ # create the image with secret0 and open it
97
+ # Now migrate the VM
257
+ self.createImg(test_img, self.secrets[0]);
98
+ self.vm_s.qmp('migrate', uri=f'unix:{mig_sock}')
258
+ self.openImageQmp("testdev", test_img, self.secrets[0])
99
+ assert self.vm_s.wait_migration(None)
100
+ assert self.vm_d.wait_migration(None)
259
+
101
+
260
+ # add key to slot 1
102
+ # Try the same qemu-io access again, verifying that the WRITE
261
+ self.addKeyQmp("testdev", new_secret = self.secrets[1])
103
+ # permission remains unshared
262
+
104
+ log = qemu_io('-f', imgfmt, '-c', 'quit', test_img)
263
+ # erase key from slot 0
105
+ if not log.strip():
264
+ self.eraseKeyQmp("testdev", old_secret = self.secrets[0])
106
+ print('ERROR (post-migration): qemu-io should not be able to '
265
+
107
+ 'access this image, but it reported no error')
266
+ # this will fail as the old password is no longer valid
108
+ else:
267
+ self.addKeyQmp("testdev", new_secret = self.secrets[2])
109
+ # This is the expected output
268
+
110
+ assert 'Is another process using the image' in log
269
+ # this will work
270
+ self.addKeyQmp("testdev", new_secret = self.secrets[2], secret = self.secrets[1])
271
+
272
+ # close and erase the image for good
273
+ self.closeImageQmp("testdev")
274
+ os.remove(test_img)
275
+
276
+ def testUseForceLuke(self):
277
+
278
+ self.createImg(test_img, self.secrets[0]);
279
+ self.openImageQmp("testdev", test_img, self.secrets[0])
280
+
281
+ # Add bunch of secrets
282
+ self.addKeyQmp("testdev", new_secret = self.secrets[1], slot=4)
283
+ self.addKeyQmp("testdev", new_secret = self.secrets[4], slot=2)
284
+
285
+ # overwrite an active secret
286
+ self.addKeyQmp("testdev", new_secret = self.secrets[5], slot=2)
287
+ self.addKeyQmp("testdev", new_secret = self.secrets[5], slot=2, force=True)
288
+
289
+ self.addKeyQmp("testdev", new_secret = self.secrets[0])
290
+
291
+ # Now erase all the secrets
292
+ self.eraseKeyQmp("testdev", old_secret = self.secrets[5])
293
+ self.eraseKeyQmp("testdev", slot=4)
294
+
295
+ # erase last keyslot
296
+ self.eraseKeyQmp("testdev", old_secret = self.secrets[0])
297
+ self.eraseKeyQmp("testdev", old_secret = self.secrets[0], force=True)
298
+
299
+ self.closeImageQmp("testdev")
300
+ os.remove(test_img)
301
+
111
+
302
+
112
+
303
+if __name__ == '__main__':
113
+if __name__ == '__main__':
304
+ # Encrypted formats support
114
+ # Only works with raw images because we are testing the
305
+ iotests.activate_logging()
115
+ # BlockBackend permissions; image format drivers may additionally
306
+ iotests.main(supported_fmts = ['qcow2', 'luks'])
116
+ # unshare permissions and thus tamper with the result
307
diff --git a/tests/qemu-iotests/295.out b/tests/qemu-iotests/295.out
117
+ iotests.main(supported_fmts=['raw'],
118
+ supported_protocols=['file'])
119
diff --git a/tests/qemu-iotests/tests/migration-permissions.out b/tests/qemu-iotests/tests/migration-permissions.out
308
new file mode 100644
120
new file mode 100644
309
index XXXXXXX..XXXXXXX
121
index XXXXXXX..XXXXXXX
310
--- /dev/null
122
--- /dev/null
311
+++ b/tests/qemu-iotests/295.out
123
+++ b/tests/qemu-iotests/tests/migration-permissions.out
312
@@ -XXX,XX +XXX,XX @@
124
@@ -XXX,XX +XXX,XX @@
313
+{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
125
+.
314
+{"return": {}}
315
+{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
316
+{"return": {}}
317
+{"execute": "job-dismiss", "arguments": {"id": "job_erase_key"}}
318
+{"return": {}}
319
+{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
320
+{"return": {}}
321
+{"execute": "job-dismiss", "arguments": {"id": "job_erase_key"}}
322
+{"return": {}}
323
+Job failed: Invalid password, cannot unlock any keyslot
324
+{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
325
+{"return": {}}
326
+{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
327
+{"return": {}}
328
+{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
329
+{"return": {}}
330
+{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
331
+{"return": {}}
332
+Job failed: Refusing to overwrite active keyslot 2 - please erase it first
333
+{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
334
+{"return": {}}
335
+{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
336
+{"return": {}}
337
+{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
338
+{"return": {}}
339
+{"execute": "job-dismiss", "arguments": {"id": "job_erase_key"}}
340
+{"return": {}}
341
+{"execute": "job-dismiss", "arguments": {"id": "job_erase_key"}}
342
+{"return": {}}
343
+Job failed: All the active keyslots match the (old) password that was given and erasing them will erase all the data in the image irreversibly - refusing operation
344
+{"execute": "job-dismiss", "arguments": {"id": "job_erase_key"}}
345
+{"return": {}}
346
+{"execute": "job-dismiss", "arguments": {"id": "job_erase_key"}}
347
+{"return": {}}
348
+...
349
+----------------------------------------------------------------------
126
+----------------------------------------------------------------------
350
+Ran 3 tests
127
+Ran 1 tests
351
+
128
+
352
+OK
129
+OK
353
diff --git a/tests/qemu-iotests/296 b/tests/qemu-iotests/296
354
new file mode 100755
355
index XXXXXXX..XXXXXXX
356
--- /dev/null
357
+++ b/tests/qemu-iotests/296
358
@@ -XXX,XX +XXX,XX @@
359
+#!/usr/bin/env python3
360
+#
361
+# Test case for encryption key management versus image sharing
362
+#
363
+# Copyright (C) 2019 Red Hat, Inc.
364
+#
365
+# This program is free software; you can redistribute it and/or modify
366
+# it under the terms of the GNU General Public License as published by
367
+# the Free Software Foundation; either version 2 of the License, or
368
+# (at your option) any later version.
369
+#
370
+# This program is distributed in the hope that it will be useful,
371
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
372
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
373
+# GNU General Public License for more details.
374
+#
375
+# You should have received a copy of the GNU General Public License
376
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
377
+#
378
+
379
+import iotests
380
+import os
381
+import time
382
+import json
383
+
384
+test_img = os.path.join(iotests.test_dir, 'test.img')
385
+
386
+class Secret:
387
+ def __init__(self, index):
388
+ self._id = "keysec" + str(index)
389
+ # you are not supposed to see the password...
390
+ self._secret = "hunter" + str(index)
391
+
392
+ def id(self):
393
+ return self._id
394
+
395
+ def secret(self):
396
+ return self._secret
397
+
398
+ def to_cmdline_object(self):
399
+ return [ "secret,id=" + self._id + ",data=" + self._secret]
400
+
401
+ def to_qmp_object(self):
402
+ return { "qom_type" : "secret", "id": self.id(),
403
+ "props": { "data": self.secret() } }
404
+
405
+################################################################################
406
+
407
+class EncryptionSetupTestCase(iotests.QMPTestCase):
408
+
409
+ # test case startup
410
+ def setUp(self):
411
+
412
+ # start the VMs
413
+ self.vm1 = iotests.VM(path_suffix = 'VM1')
414
+ self.vm2 = iotests.VM(path_suffix = 'VM2')
415
+ self.vm1.launch()
416
+ self.vm2.launch()
417
+
418
+ # create the secrets and load 'em into the VMs
419
+ self.secrets = [ Secret(i) for i in range(0, 4) ]
420
+ for secret in self.secrets:
421
+ result = self.vm1.qmp("object-add", **secret.to_qmp_object())
422
+ self.assert_qmp(result, 'return', {})
423
+ result = self.vm2.qmp("object-add", **secret.to_qmp_object())
424
+ self.assert_qmp(result, 'return', {})
425
+
426
+ # test case shutdown
427
+ def tearDown(self):
428
+ # stop the VM
429
+ self.vm1.shutdown()
430
+ self.vm2.shutdown()
431
+
432
+ ###########################################################################
433
+ # create the encrypted block device using qemu-img
434
+ def createImg(self, file, secret):
435
+
436
+ output = iotests.qemu_img_pipe(
437
+ 'create',
438
+ '--object', *secret.to_cmdline_object(),
439
+ '-f', iotests.imgfmt,
440
+ '-o', 'key-secret=' + secret.id(),
441
+ '-o', 'iter-time=10',
442
+ file,
443
+ '1M')
444
+
445
+ iotests.log(output, filters=[iotests.filter_test_dir])
446
+
447
+ # attempts to add a key using qemu-img
448
+ def addKey(self, file, secret, new_secret):
449
+
450
+ image_options = {
451
+ 'key-secret' : secret.id(),
452
+ 'driver' : iotests.imgfmt,
453
+ 'file' : {
454
+ 'driver':'file',
455
+ 'filename': file,
456
+ }
457
+ }
458
+
459
+ output = iotests.qemu_img_pipe(
460
+ 'amend',
461
+ '--object', *secret.to_cmdline_object(),
462
+ '--object', *new_secret.to_cmdline_object(),
463
+
464
+ '-o', 'state=active',
465
+ '-o', 'new-secret=' + new_secret.id(),
466
+ '-o', 'iter-time=10',
467
+
468
+ "json:" + json.dumps(image_options)
469
+ )
470
+
471
+ iotests.log(output, filters=[iotests.filter_test_dir])
472
+
473
+ ###########################################################################
474
+ # open an encrypted block device
475
+ def openImageQmp(self, vm, id, file, secret,
476
+ readOnly = False, reOpen = False):
477
+
478
+ command = 'x-blockdev-reopen' if reOpen else 'blockdev-add'
479
+
480
+ result = vm.qmp(command, **
481
+ {
482
+ 'driver': iotests.imgfmt,
483
+ 'node-name': id,
484
+ 'read-only': readOnly,
485
+ 'key-secret' : secret.id(),
486
+ 'file': {
487
+ 'driver': 'file',
488
+ 'filename': test_img,
489
+ }
490
+ }
491
+ )
492
+ self.assert_qmp(result, 'return', {})
493
+
494
+ # close the encrypted block device
495
+ def closeImageQmp(self, vm, id):
496
+ result = vm.qmp('blockdev-del', **{ 'node-name': id })
497
+ self.assert_qmp(result, 'return', {})
498
+
499
+ ###########################################################################
500
+
501
+ # add a key to an encrypted block device
502
+ def addKeyQmp(self, vm, id, new_secret):
503
+
504
+ args = {
505
+ 'node-name': id,
506
+ 'job-id' : 'job0',
507
+ 'options' : {
508
+ 'state' : 'active',
509
+ 'driver' : iotests.imgfmt,
510
+ 'new-secret': new_secret.id(),
511
+ 'iter-time' : 10
512
+ },
513
+ }
514
+
515
+ result = vm.qmp('x-blockdev-amend', **args)
516
+ assert result['return'] == {}
517
+ vm.run_job('job0')
518
+
519
+ # test that when the image opened by two qemu processes,
520
+ # neither of them can update the image
521
+ def test1(self):
522
+ self.createImg(test_img, self.secrets[0]);
523
+
524
+ # VM1 opens the image and adds a key
525
+ self.openImageQmp(self.vm1, "testdev", test_img, self.secrets[0])
526
+ self.addKeyQmp(self.vm1, "testdev", new_secret = self.secrets[1])
527
+
528
+
529
+ # VM2 opens the image
530
+ self.openImageQmp(self.vm2, "testdev", test_img, self.secrets[0])
531
+
532
+
533
+ # neither VMs now should be able to add a key
534
+ self.addKeyQmp(self.vm1, "testdev", new_secret = self.secrets[2])
535
+ self.addKeyQmp(self.vm2, "testdev", new_secret = self.secrets[2])
536
+
537
+
538
+ # VM 1 closes the image
539
+ self.closeImageQmp(self.vm1, "testdev")
540
+
541
+
542
+ # now VM2 can add the key
543
+ self.addKeyQmp(self.vm2, "testdev", new_secret = self.secrets[2])
544
+
545
+
546
+ # qemu-img should also not be able to add a key
547
+ self.addKey(test_img, self.secrets[0], self.secrets[2])
548
+
549
+ # cleanup
550
+ self.closeImageQmp(self.vm2, "testdev")
551
+ os.remove(test_img)
552
+
553
+
554
+ def test2(self):
555
+ self.createImg(test_img, self.secrets[0]);
556
+
557
+ # VM1 opens the image readonly
558
+ self.openImageQmp(self.vm1, "testdev", test_img, self.secrets[0],
559
+ readOnly = True)
560
+
561
+ # VM2 opens the image
562
+ self.openImageQmp(self.vm2, "testdev", test_img, self.secrets[0])
563
+
564
+ # VM1 can't add a key since image is readonly
565
+ self.addKeyQmp(self.vm1, "testdev", new_secret = self.secrets[2])
566
+
567
+ # VM2 can't add a key since VM is has the image opened
568
+ self.addKeyQmp(self.vm2, "testdev", new_secret = self.secrets[2])
569
+
570
+
571
+ #VM1 reopens the image read-write
572
+ self.openImageQmp(self.vm1, "testdev", test_img, self.secrets[0],
573
+ reOpen = True, readOnly = False)
574
+
575
+ # VM1 still can't add the key
576
+ self.addKeyQmp(self.vm1, "testdev", new_secret = self.secrets[2])
577
+
578
+ # VM2 gets away
579
+ self.closeImageQmp(self.vm2, "testdev")
580
+
581
+ # VM1 now can add the key
582
+ self.addKeyQmp(self.vm1, "testdev", new_secret = self.secrets[2])
583
+
584
+ self.closeImageQmp(self.vm1, "testdev")
585
+ os.remove(test_img)
586
+
587
+
588
+if __name__ == '__main__':
589
+ # support only raw luks since luks encrypted qcow2 is a proper
590
+ # format driver which doesn't allow any sharing
591
+ iotests.activate_logging()
592
+ iotests.main(supported_fmts = ['luks'])
593
diff --git a/tests/qemu-iotests/296.out b/tests/qemu-iotests/296.out
594
new file mode 100644
595
index XXXXXXX..XXXXXXX
596
--- /dev/null
597
+++ b/tests/qemu-iotests/296.out
598
@@ -XXX,XX +XXX,XX @@
599
+Formatting 'TEST_DIR/test.img', fmt=luks size=1048576 key-secret=keysec0 iter-time=10
600
+
601
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
602
+{"return": {}}
603
+Job failed: Failed to get shared "consistent read" lock
604
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
605
+{"return": {}}
606
+Job failed: Failed to get shared "consistent read" lock
607
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
608
+{"return": {}}
609
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
610
+{"return": {}}
611
+qemu-img: Failed to get shared "consistent read" lock
612
+Is another process using the image [TEST_DIR/test.img]?
613
+
614
+Formatting 'TEST_DIR/test.img', fmt=luks size=1048576 key-secret=keysec0 iter-time=10
615
+
616
+Job failed: Block node is read-only
617
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
618
+{"return": {}}
619
+Job failed: Failed to get shared "consistent read" lock
620
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
621
+{"return": {}}
622
+Job failed: Failed to get shared "consistent read" lock
623
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
624
+{"return": {}}
625
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
626
+{"return": {}}
627
+..
628
+----------------------------------------------------------------------
629
+Ran 2 tests
630
+
631
+OK
632
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
633
index XXXXXXX..XXXXXXX 100644
634
--- a/tests/qemu-iotests/group
635
+++ b/tests/qemu-iotests/group
636
@@ -XXX,XX +XXX,XX @@
637
292 rw auto quick
638
293 rw auto
639
294 rw auto quick
640
+295 rw auto
641
+296 rw auto
642
297 meta
643
--
130
--
644
2.26.2
131
2.34.1
645
132
646
133
diff view generated by jsdifflib
1
From: Maxim Levitsky <mlevitsk@redhat.com>
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
2
2
3
'force' option will be used for some unsafe amend operations.
3
The comment "disk I/O throttling" doesn't make any sense at all
4
any more. It was added in commit 0563e191516 to describe
5
bdrv_io_limits_enable()/disable(), which were removed in commit
6
97148076, so the comment is just a forgotten leftover.
4
7
5
This includes things like erasing last keyslot in luks based formats
8
Suggested-by: Kevin Wolf <kwolf@redhat.com>
6
(which destroys the data, unless the master key is backed up
9
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
7
by external means), but that _might_ be desired result.
10
Message-Id: <20220131125615.74612-1-eesposit@redhat.com>
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
13
---
14
include/block/block.h | 1 -
15
1 file changed, 1 deletion(-)
8
16
9
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
10
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
11
Reviewed-by: Max Reitz <mreitz@redhat.com>
12
Message-Id: <20200608094030.670121-4-mlevitsk@redhat.com>
13
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
---
15
docs/tools/qemu-img.rst | 5 ++++-
16
include/block/block.h | 1 +
17
include/block/block_int.h | 1 +
18
block.c | 4 +++-
19
block/qcow2.c | 1 +
20
qemu-img.c | 8 +++++++-
21
qemu-img-cmds.hx | 4 ++--
22
7 files changed, 19 insertions(+), 5 deletions(-)
23
24
diff --git a/docs/tools/qemu-img.rst b/docs/tools/qemu-img.rst
25
index XXXXXXX..XXXXXXX 100644
26
--- a/docs/tools/qemu-img.rst
27
+++ b/docs/tools/qemu-img.rst
28
@@ -XXX,XX +XXX,XX @@ Command description:
29
30
.. program:: qemu-img-commands
31
32
-.. option:: amend [--object OBJECTDEF] [--image-opts] [-p] [-q] [-f FMT] [-t CACHE] -o OPTIONS FILENAME
33
+.. option:: amend [--object OBJECTDEF] [--image-opts] [-p] [-q] [-f FMT] [-t CACHE] [--force] -o OPTIONS FILENAME
34
35
Amends the image format specific *OPTIONS* for the image file
36
*FILENAME*. Not all file formats support this operation.
37
38
+ --force allows some unsafe operations. Currently for -f luks, it allows to
39
+ erase the last encryption key, and to overwrite an active encryption key.
40
+
41
.. option:: bench [-c COUNT] [-d DEPTH] [-f FMT] [--flush-interval=FLUSH_INTERVAL] [-i AIO] [-n] [--no-drain] [-o OFFSET] [--pattern=PATTERN] [-q] [-s BUFFER_SIZE] [-S STEP_SIZE] [-t CACHE] [-w] [-U] FILENAME
42
43
Run a simple sequential I/O benchmark on the specified image. If ``-w`` is
44
diff --git a/include/block/block.h b/include/block/block.h
17
diff --git a/include/block/block.h b/include/block/block.h
45
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
46
--- a/include/block/block.h
19
--- a/include/block/block.h
47
+++ b/include/block/block.h
20
+++ b/include/block/block.h
48
@@ -XXX,XX +XXX,XX @@ typedef void BlockDriverAmendStatusCB(BlockDriverState *bs, int64_t offset,
21
@@ -XXX,XX +XXX,XX @@ typedef unsigned int BdrvChildRole;
49
int64_t total_work_size, void *opaque);
22
char *bdrv_perm_names(uint64_t perm);
50
int bdrv_amend_options(BlockDriverState *bs_new, QemuOpts *opts,
23
uint64_t bdrv_qapi_perm_to_blk_perm(BlockPermission qapi_perm);
51
BlockDriverAmendStatusCB *status_cb, void *cb_opaque,
24
52
+ bool force,
25
-/* disk I/O throttling */
53
Error **errp);
26
void bdrv_init(void);
54
27
void bdrv_init_with_whitelist(void);
55
/* check if a named node can be replaced when doing drive-mirror */
28
bool bdrv_uses_whitelist(void);
56
diff --git a/include/block/block_int.h b/include/block/block_int.h
57
index XXXXXXX..XXXXXXX 100644
58
--- a/include/block/block_int.h
59
+++ b/include/block/block_int.h
60
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
61
int (*bdrv_amend_options)(BlockDriverState *bs, QemuOpts *opts,
62
BlockDriverAmendStatusCB *status_cb,
63
void *cb_opaque,
64
+ bool force,
65
Error **errp);
66
67
void (*bdrv_debug_event)(BlockDriverState *bs, BlkdebugEvent event);
68
diff --git a/block.c b/block.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/block.c
71
+++ b/block.c
72
@@ -XXX,XX +XXX,XX @@ void bdrv_remove_aio_context_notifier(BlockDriverState *bs,
73
74
int bdrv_amend_options(BlockDriverState *bs, QemuOpts *opts,
75
BlockDriverAmendStatusCB *status_cb, void *cb_opaque,
76
+ bool force,
77
Error **errp)
78
{
79
if (!bs->drv) {
80
@@ -XXX,XX +XXX,XX @@ int bdrv_amend_options(BlockDriverState *bs, QemuOpts *opts,
81
bs->drv->format_name);
82
return -ENOTSUP;
83
}
84
- return bs->drv->bdrv_amend_options(bs, opts, status_cb, cb_opaque, errp);
85
+ return bs->drv->bdrv_amend_options(bs, opts, status_cb,
86
+ cb_opaque, force, errp);
87
}
88
89
/*
90
diff --git a/block/qcow2.c b/block/qcow2.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/block/qcow2.c
93
+++ b/block/qcow2.c
94
@@ -XXX,XX +XXX,XX @@ static void qcow2_amend_helper_cb(BlockDriverState *bs,
95
static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
96
BlockDriverAmendStatusCB *status_cb,
97
void *cb_opaque,
98
+ bool force,
99
Error **errp)
100
{
101
BDRVQcow2State *s = bs->opaque;
102
diff --git a/qemu-img.c b/qemu-img.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/qemu-img.c
105
+++ b/qemu-img.c
106
@@ -XXX,XX +XXX,XX @@ enum {
107
OPTION_DISABLE = 273,
108
OPTION_MERGE = 274,
109
OPTION_BITMAPS = 275,
110
+ OPTION_FORCE = 276,
111
};
112
113
typedef enum OutputFormat {
114
@@ -XXX,XX +XXX,XX @@ static int img_amend(int argc, char **argv)
115
BlockBackend *blk = NULL;
116
BlockDriverState *bs = NULL;
117
bool image_opts = false;
118
+ bool force = false;
119
120
cache = BDRV_DEFAULT_CACHE;
121
for (;;) {
122
@@ -XXX,XX +XXX,XX @@ static int img_amend(int argc, char **argv)
123
{"help", no_argument, 0, 'h'},
124
{"object", required_argument, 0, OPTION_OBJECT},
125
{"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
126
+ {"force", no_argument, 0, OPTION_FORCE},
127
{0, 0, 0, 0}
128
};
129
c = getopt_long(argc, argv, ":ho:f:t:pq",
130
@@ -XXX,XX +XXX,XX @@ static int img_amend(int argc, char **argv)
131
case OPTION_IMAGE_OPTS:
132
image_opts = true;
133
break;
134
+ case OPTION_FORCE:
135
+ force = true;
136
+ break;
137
}
138
}
139
140
@@ -XXX,XX +XXX,XX @@ static int img_amend(int argc, char **argv)
141
142
/* In case the driver does not call amend_status_cb() */
143
qemu_progress_print(0.f, 0);
144
- ret = bdrv_amend_options(bs, opts, &amend_status_cb, NULL, &err);
145
+ ret = bdrv_amend_options(bs, opts, &amend_status_cb, NULL, force, &err);
146
qemu_progress_print(100.f, 0);
147
if (ret < 0) {
148
error_report_err(err);
149
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
150
index XXXXXXX..XXXXXXX 100644
151
--- a/qemu-img-cmds.hx
152
+++ b/qemu-img-cmds.hx
153
@@ -XXX,XX +XXX,XX @@ HXCOMM When amending the rST sections, please remember to copy the usage
154
HXCOMM over to the per-command sections in docs/tools/qemu-img.rst.
155
156
DEF("amend", img_amend,
157
- "amend [--object objectdef] [--image-opts] [-p] [-q] [-f fmt] [-t cache] -o options filename")
158
+ "amend [--object objectdef] [--image-opts] [-p] [-q] [-f fmt] [-t cache] [--force] -o options filename")
159
SRST
160
-.. option:: amend [--object OBJECTDEF] [--image-opts] [-p] [-q] [-f FMT] [-t CACHE] -o OPTIONS FILENAME
161
+.. option:: amend [--object OBJECTDEF] [--image-opts] [-p] [-q] [-f FMT] [-t CACHE] [--force] -o OPTIONS FILENAME
162
ERST
163
164
DEF("bench", img_bench,
165
--
29
--
166
2.26.2
30
2.34.1
167
31
168
32
diff view generated by jsdifflib