1
The following changes since commit b2f7a038bb4c4fc5ce6b8486e8513dfd97665e2a:
1
The following changes since commit 6c599282f8ab382fe59f03a6cae755b89561a7b3:
2
2
3
Merge remote-tracking branch 'remotes/rth/tags/pull-softfloat-20181104' into staging (2018-11-05 10:32:49 +0000)
3
Merge remote-tracking branch 'remotes/armbru/tags/pull-monitor-2020-02-15-v2' into staging (2020-02-17 13:32:25 +0000)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
git://repo.or.cz/qemu/kevin.git tags/for-upstream
7
git://repo.or.cz/qemu/kevin.git tags/for-upstream
8
8
9
for you to fetch changes up to 1240ac558d348f6c7a5752b1a57c1da58e4efe3e:
9
for you to fetch changes up to c45a88f4429d7a8f384b75f3fd3fed5138a6edca:
10
10
11
include: Add a comment to explain the origin of sizes' lookup table (2018-11-05 15:29:59 +0100)
11
iotests: Check that @replaces can replace filters (2020-02-18 14:52:16 +0100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block layer patches:
14
Block layer patches:
15
15
16
- auto-read-only option to fix commit job when used with -blockdev
16
- Fix check_to_replace_node()
17
- Fix help text related qemu-iotests failure (by improving the help text
17
- commit: Expose on-error option in QMP
18
and updating the reference output)
18
- qcow2: Fix qcow2_alloc_cluster_abort() for external data file
19
- quorum: Add missing checks when adding/removing child nodes
19
- mirror: Fix deadlock
20
- Don't take address of fields in packed structs
20
- vvfat: Fix segfault while closing read-write node
21
- vvfat: Fix crash when reporting error about too many files in directory
21
- Code cleanups
22
22
23
----------------------------------------------------------------
23
----------------------------------------------------------------
24
Alberto Garcia (7):
24
Alberto Garcia (1):
25
block: replace "discard" literal with BDRV_OPT_DISCARD macro
25
qcow2: Fix alignment checks in encrypted images
26
qcow2: Get the request alignment for encrypted images from QCryptoBlock
27
quorum: Remove quorum_err()
28
quorum: Return an error if the blkverify mode has invalid settings
29
iotest: Test the blkverify mode of the Quorum driver
30
quorum: Forbid adding children in blkverify mode
31
iotest: Test x-blockdev-change on a Quorum
32
26
33
Cleber Rosa (1):
27
Hikaru Nishida (1):
34
iotests: make 083 specific to raw
28
block/vvfat: Do not unref qcow on closing backing bdrv
35
36
Daniel P. Berrangé (1):
37
crypto: initialize sector size even when opening with no IO flag
38
29
39
Kevin Wolf (12):
30
Kevin Wolf (12):
40
vpc: Don't leak opts in vpc_open()
31
mirror: Store MirrorOp.co for debuggability
41
block: Update flags in bdrv_set_read_only()
32
mirror: Don't let an operation wait for itself
42
block: Add auto-read-only option
33
qcow2: update_refcount(): Reset old_table_index after qcow2_cache_put()
43
rbd: Close image in qemu_rbd_open() error path
34
qcow2: Fix qcow2_alloc_cluster_abort() for external data file
44
block: Require auto-read-only for existing fallbacks
35
iotests: Test copy offloading with external data file
45
nbd: Support auto-read-only option
36
qapi: Document meaning of 'ignore' BlockdevOnError for jobs
46
file-posix: Support auto-read-only option
37
commit: Remove unused bytes_written
47
curl: Support auto-read-only option
38
commit: Fix argument order for block_job_error_action()
48
gluster: Support auto-read-only option
39
commit: Inline commit_populate()
49
iscsi: Support auto-read-only option
40
commit: Fix is_read for block_job_error_action()
50
block: Make auto-read-only=on default for -drive
41
commit: Expose on-error option in QMP
51
qemu-iotests: Test auto-read-only with -drive and -blockdev
42
iotests: Test error handling policies with block-commit
52
43
53
Leonid Bloch (2):
44
Max Reitz (19):
54
vdi: Use a literal number of bytes for DEFAULT_CLUSTER_SIZE
45
blockdev: Allow external snapshots everywhere
55
include: Add a comment to explain the origin of sizes' lookup table
46
blockdev: Allow resizing everywhere
47
block: Drop bdrv_is_first_non_filter()
48
iotests: Let 041 use -blockdev for quorum children
49
quorum: Fix child permissions
50
block: Add bdrv_recurse_can_replace()
51
blkverify: Implement .bdrv_recurse_can_replace()
52
quorum: Implement .bdrv_recurse_can_replace()
53
block: Use bdrv_recurse_can_replace()
54
block: Remove bdrv_recurse_is_first_non_filter()
55
mirror: Double-check immediately before replacing
56
quorum: Stop marking it as a filter
57
iotests: Use complete_and_wait() in 155
58
iotests: Add VM.assert_block_path()
59
iotests/041: Drop superfluous shutdowns
60
iotests: Resolve TODOs in 041
61
iotests: Use self.image_len in TestRepairQuorum
62
iotests: Add tests for invalid Quorum @replaces
63
iotests: Check that @replaces can replace filters
56
64
57
Li Qiang (1):
65
Philippe Mathieu-Daudé (3):
58
block: change some function return type to bool
66
block/qcow2-bitmap: Remove unneeded variable assignment
67
block: Remove superfluous semicolons
68
block/io_uring: Remove superfluous semicolon
59
69
60
Max Reitz (5):
70
qapi/block-core.json | 9 +-
61
option: Make option help nicer to read
71
include/block/block.h | 5 -
62
chardev: Indent list of chardevs
72
include/block/block_int.h | 16 +--
63
qdev-monitor: Make device options help nicer
73
block.c | 89 ++++++-------
64
object: Make option help nicer to read
74
block/blkverify.c | 20 +--
65
fw_cfg: Drop newline in @file description
75
block/commit.c | 37 ++----
76
block/copy-on-read.c | 9 --
77
block/filter-compress.c | 9 --
78
block/io_uring.c | 2 +-
79
block/mirror.c | 37 ++++--
80
block/qcow2-bitmap.c | 1 -
81
block/qcow2-cluster.c | 7 +-
82
block/qcow2-refcount.c | 1 +
83
block/qcow2-threads.c | 12 +-
84
block/qcow2.c | 2 -
85
block/quorum.c | 70 +++++++++--
86
block/replication.c | 7 --
87
block/throttle.c | 8 --
88
block/vvfat.c | 7 --
89
blockdev.c | 18 +--
90
tests/qemu-iotests/iotests.py | 59 +++++++++
91
tests/qemu-iotests/040 | 283 ++++++++++++++++++++++++++++++++++++++++++
92
tests/qemu-iotests/040.out | 4 +-
93
tests/qemu-iotests/041 | 138 +++++++++++++++++---
94
tests/qemu-iotests/041.out | 4 +-
95
tests/qemu-iotests/155 | 7 +-
96
tests/qemu-iotests/244 | 14 +++
97
tests/qemu-iotests/244.out | 6 +
98
28 files changed, 675 insertions(+), 206 deletions(-)
66
99
67
Peter Maydell (5):
68
block/qcow2: Don't take address of fields in packed structs
69
block/qcow: Don't take address of fields in packed structs
70
block/qcow2-bitmap: Don't take address of fields in packed structs
71
block/vhdx: Don't take address of fields in packed structs
72
block/vdi: Don't take address of fields in packed structs
73
100
74
Stefan Weil (1):
75
qemu-io-cmds: Fix two format strings
76
77
Thomas Huth (1):
78
block/vvfat: Fix crash when reporting error about too many files in directory
79
80
qapi/block-core.json | 7 +
81
block/vhdx.h | 12 +-
82
include/block/block.h | 5 +-
83
include/qemu/option.h | 2 +-
84
include/qemu/units.h | 18 +
85
include/sysemu/block-backend.h | 6 +-
86
block.c | 60 ++-
87
block/block-backend.c | 8 +-
88
block/bochs.c | 17 +-
89
block/cloop.c | 16 +-
90
block/curl.c | 8 +-
91
block/dmg.c | 16 +-
92
block/file-posix.c | 19 +-
93
block/gluster.c | 12 +-
94
block/iscsi.c | 8 +-
95
block/nbd-client.c | 10 +-
96
block/qcow.c | 18 +-
97
block/qcow2-bitmap.c | 24 +-
98
block/qcow2.c | 66 +--
99
block/quorum.c | 45 +-
100
block/rbd.c | 14 +-
101
block/vdi.c | 68 +--
102
block/vhdx-endian.c | 118 ++---
103
block/vhdx-log.c | 4 +-
104
block/vhdx.c | 18 +-
105
block/vpc.c | 2 +
106
block/vvfat.c | 15 +-
107
blockdev.c | 3 +-
108
chardev/char.c | 2 +-
109
crypto/block-qcow.c | 2 +
110
qdev-monitor.c | 13 +-
111
qemu-img.c | 4 +-
112
qemu-io-cmds.c | 4 +-
113
util/qemu-option.c | 32 +-
114
vl.c | 15 +-
115
tests/qemu-iotests/081 | 116 +++++
116
tests/qemu-iotests/081.out | 70 +++
117
tests/qemu-iotests/082.out | 956 ++++++++++++++++++++---------------------
118
tests/qemu-iotests/083 | 2 +-
119
tests/qemu-iotests/232 | 147 +++++++
120
tests/qemu-iotests/232.out | 59 +++
121
tests/qemu-iotests/group | 1 +
122
42 files changed, 1266 insertions(+), 776 deletions(-)
123
create mode 100755 tests/qemu-iotests/232
124
create mode 100644 tests/qemu-iotests/232.out
125
diff view generated by jsdifflib
1
If read-only=off, but auto-read-only=on is given, just degrade to
1
If a coroutine is launched, but the coroutine pointer isn't stored
2
read-only.
2
anywhere, debugging any problems inside the coroutine is quite hard.
3
Let's store the coroutine pointer of a mirror operation in MirrorOp to
4
have it available in the debugger.
3
5
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Eric Blake <eblake@redhat.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
6
---
8
---
7
block/curl.c | 8 ++++----
9
block/mirror.c | 2 ++
8
1 file changed, 4 insertions(+), 4 deletions(-)
10
1 file changed, 2 insertions(+)
9
11
10
diff --git a/block/curl.c b/block/curl.c
12
diff --git a/block/mirror.c b/block/mirror.c
11
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
12
--- a/block/curl.c
14
--- a/block/mirror.c
13
+++ b/block/curl.c
15
+++ b/block/mirror.c
14
@@ -XXX,XX +XXX,XX @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
16
@@ -XXX,XX +XXX,XX @@ struct MirrorOp {
15
const char *protocol_delimiter;
17
bool is_pseudo_op;
16
int ret;
18
bool is_active_write;
17
19
CoQueue waiting_requests;
18
-
20
+ Coroutine *co;
19
- if (flags & BDRV_O_RDWR) {
21
20
- error_setg(errp, "curl block device does not support writes");
22
QTAILQ_ENTRY(MirrorOp) next;
21
- return -EROFS;
23
};
22
+ ret = bdrv_apply_auto_read_only(bs, "curl driver does not support writes",
24
@@ -XXX,XX +XXX,XX @@ static unsigned mirror_perform(MirrorBlockJob *s, int64_t offset,
23
+ errp);
25
default:
24
+ if (ret < 0) {
26
abort();
25
+ return ret;
26
}
27
}
27
28
+ op->co = co;
28
if (!libcurl_initialized) {
29
30
QTAILQ_INSERT_TAIL(&s->ops_in_flight, op, next);
31
qemu_coroutine_enter(co);
29
--
32
--
30
2.19.1
33
2.20.1
31
34
32
35
diff view generated by jsdifflib
1
If read-only=off, but auto-read-only=on is given, open the volume
1
mirror_wait_for_free_in_flight_slot() just picks a random operation to
2
read-write if we have the permissions, but instead of erroring out for
2
wait for. However, when mirror_co_read() waits for free slots, its
3
read-only volumes, just degrade to read-only.
3
MirrorOp is already in s->ops_in_flight, so if not enough slots are
4
immediately available, an operation can end up waiting for itself to
5
complete, which results in a hang.
4
6
7
Fix this by passing the current MirrorOp and skipping this operation
8
when picking an operation to wait for.
9
10
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1794692
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
12
Reviewed-by: Eric Blake <eblake@redhat.com>
7
---
13
---
8
block/iscsi.c | 8 +++++---
14
block/mirror.c | 21 ++++++++++++---------
9
1 file changed, 5 insertions(+), 3 deletions(-)
15
1 file changed, 12 insertions(+), 9 deletions(-)
10
16
11
diff --git a/block/iscsi.c b/block/iscsi.c
17
diff --git a/block/mirror.c b/block/mirror.c
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/block/iscsi.c
19
--- a/block/mirror.c
14
+++ b/block/iscsi.c
20
+++ b/block/mirror.c
15
@@ -XXX,XX +XXX,XX @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
21
@@ -XXX,XX +XXX,XX @@ static int mirror_cow_align(MirrorBlockJob *s, int64_t *offset,
16
/* Check the write protect flag of the LUN if we want to write */
22
}
17
if (iscsilun->type == TYPE_DISK && (flags & BDRV_O_RDWR) &&
23
18
iscsilun->write_protected) {
24
static inline void coroutine_fn
19
- error_setg(errp, "Cannot open a write protected LUN as read-write");
25
-mirror_wait_for_any_operation(MirrorBlockJob *s, bool active)
20
- ret = -EACCES;
26
+mirror_wait_for_any_operation(MirrorBlockJob *s, MirrorOp *self, bool active)
21
- goto out;
27
{
22
+ ret = bdrv_apply_auto_read_only(bs, "LUN is write protected", errp);
28
MirrorOp *op;
23
+ if (ret < 0) {
29
24
+ goto out;
30
QTAILQ_FOREACH(op, &s->ops_in_flight, next) {
31
+ if (self == op) {
32
+ continue;
25
+ }
33
+ }
26
+ flags &= ~BDRV_O_RDWR;
34
/* Do not wait on pseudo ops, because it may in turn wait on
35
* some other operation to start, which may in fact be the
36
* caller of this function. Since there is only one pseudo op
37
@@ -XXX,XX +XXX,XX @@ mirror_wait_for_any_operation(MirrorBlockJob *s, bool active)
38
}
39
40
static inline void coroutine_fn
41
-mirror_wait_for_free_in_flight_slot(MirrorBlockJob *s)
42
+mirror_wait_for_free_in_flight_slot(MirrorBlockJob *s, MirrorOp *self)
43
{
44
/* Only non-active operations use up in-flight slots */
45
- mirror_wait_for_any_operation(s, false);
46
+ mirror_wait_for_any_operation(s, self, false);
47
}
48
49
/* Perform a mirror copy operation.
50
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn mirror_co_read(void *opaque)
51
52
while (s->buf_free_count < nb_chunks) {
53
trace_mirror_yield_in_flight(s, op->offset, s->in_flight);
54
- mirror_wait_for_free_in_flight_slot(s);
55
+ mirror_wait_for_free_in_flight_slot(s, op);
27
}
56
}
28
57
29
iscsi_readcapacity_sync(iscsilun, &local_err);
58
/* Now make a QEMUIOVector taking enough granularity-sized chunks
59
@@ -XXX,XX +XXX,XX @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
60
61
while (s->in_flight >= MAX_IN_FLIGHT) {
62
trace_mirror_yield_in_flight(s, offset, s->in_flight);
63
- mirror_wait_for_free_in_flight_slot(s);
64
+ mirror_wait_for_free_in_flight_slot(s, pseudo_op);
65
}
66
67
if (s->ret < 0) {
68
@@ -XXX,XX +XXX,XX @@ static void mirror_free_init(MirrorBlockJob *s)
69
static void coroutine_fn mirror_wait_for_all_io(MirrorBlockJob *s)
70
{
71
while (s->in_flight > 0) {
72
- mirror_wait_for_free_in_flight_slot(s);
73
+ mirror_wait_for_free_in_flight_slot(s, NULL);
74
}
75
}
76
77
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
78
if (s->in_flight >= MAX_IN_FLIGHT) {
79
trace_mirror_yield(s, UINT64_MAX, s->buf_free_count,
80
s->in_flight);
81
- mirror_wait_for_free_in_flight_slot(s);
82
+ mirror_wait_for_free_in_flight_slot(s, NULL);
83
continue;
84
}
85
86
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
87
/* Do not start passive operations while there are active
88
* writes in progress */
89
while (s->in_active_write_counter) {
90
- mirror_wait_for_any_operation(s, true);
91
+ mirror_wait_for_any_operation(s, NULL, true);
92
}
93
94
if (s->ret < 0) {
95
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
96
if (s->in_flight >= MAX_IN_FLIGHT || s->buf_free_count == 0 ||
97
(cnt == 0 && s->in_flight > 0)) {
98
trace_mirror_yield(s, cnt, s->buf_free_count, s->in_flight);
99
- mirror_wait_for_free_in_flight_slot(s);
100
+ mirror_wait_for_free_in_flight_slot(s, NULL);
101
continue;
102
} else if (cnt != 0) {
103
delay_ns = mirror_iteration(s);
30
--
104
--
31
2.19.1
105
2.20.1
32
106
33
107
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Alberto Garcia <berto@igalia.com>
2
2
3
This doesn't have any practical effect at the moment because the
3
I/O requests to encrypted media should be aligned to the sector size
4
values of BDRV_SECTOR_SIZE, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE and
4
used by the underlying encryption method, not to BDRV_SECTOR_SIZE.
5
QCRYPTO_BLOCK_QCOW_SECTOR_SIZE are all the same (512 bytes), but
5
Fortunately this doesn't break anything at the moment because
6
future encryption methods could have different requirements.
6
both existing QCRYPTO_BLOCK_*_SECTOR_SIZE have the same value as
7
BDRV_SECTOR_SIZE.
8
9
The checks in qcow2_co_preadv_encrypted() are also unnecessary because
10
they are repeated immediately afterwards in qcow2_co_encdec().
7
11
8
Signed-off-by: Alberto Garcia <berto@igalia.com>
12
Signed-off-by: Alberto Garcia <berto@igalia.com>
13
Message-Id: <20200213171646.15876-1-berto@igalia.com>
9
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
14
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
16
---
12
block/qcow2.c | 2 +-
17
block/qcow2-threads.c | 12 ++++++++----
13
1 file changed, 1 insertion(+), 1 deletion(-)
18
block/qcow2.c | 2 --
19
2 files changed, 8 insertions(+), 6 deletions(-)
14
20
21
diff --git a/block/qcow2-threads.c b/block/qcow2-threads.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/block/qcow2-threads.c
24
+++ b/block/qcow2-threads.c
25
@@ -XXX,XX +XXX,XX @@ qcow2_co_encdec(BlockDriverState *bs, uint64_t host_offset,
26
.len = len,
27
.func = func,
28
};
29
+ uint64_t sector_size;
30
31
- assert(QEMU_IS_ALIGNED(guest_offset, BDRV_SECTOR_SIZE));
32
- assert(QEMU_IS_ALIGNED(host_offset, BDRV_SECTOR_SIZE));
33
- assert(QEMU_IS_ALIGNED(len, BDRV_SECTOR_SIZE));
34
assert(s->crypto);
35
36
+ sector_size = qcrypto_block_get_sector_size(s->crypto);
37
+ assert(QEMU_IS_ALIGNED(guest_offset, sector_size));
38
+ assert(QEMU_IS_ALIGNED(host_offset, sector_size));
39
+ assert(QEMU_IS_ALIGNED(len, sector_size));
40
+
41
return len == 0 ? 0 : qcow2_co_process(bs, qcow2_encdec_pool_func, &arg);
42
}
43
44
@@ -XXX,XX +XXX,XX @@ qcow2_co_encdec(BlockDriverState *bs, uint64_t host_offset,
45
* will be written to the underlying storage device at
46
* @host_offset
47
*
48
- * @len - length of the buffer (must be a BDRV_SECTOR_SIZE multiple)
49
+ * @len - length of the buffer (must be a multiple of the encryption
50
+ * sector size)
51
*
52
* Depending on the encryption method, @host_offset and/or @guest_offset
53
* may be used for generating the initialization vector for
15
diff --git a/block/qcow2.c b/block/qcow2.c
54
diff --git a/block/qcow2.c b/block/qcow2.c
16
index XXXXXXX..XXXXXXX 100644
55
index XXXXXXX..XXXXXXX 100644
17
--- a/block/qcow2.c
56
--- a/block/qcow2.c
18
+++ b/block/qcow2.c
57
+++ b/block/qcow2.c
19
@@ -XXX,XX +XXX,XX @@ static void qcow2_refresh_limits(BlockDriverState *bs, Error **errp)
58
@@ -XXX,XX +XXX,XX @@ qcow2_co_preadv_encrypted(BlockDriverState *bs,
20
59
goto fail;
21
if (bs->encrypted) {
22
/* Encryption works on a sector granularity */
23
- bs->bl.request_alignment = BDRV_SECTOR_SIZE;
24
+ bs->bl.request_alignment = qcrypto_block_get_sector_size(s->crypto);
25
}
60
}
26
bs->bl.pwrite_zeroes_alignment = s->cluster_size;
61
27
bs->bl.pdiscard_alignment = s->cluster_size;
62
- assert(QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE));
63
- assert(QEMU_IS_ALIGNED(bytes, BDRV_SECTOR_SIZE));
64
if (qcow2_co_decrypt(bs,
65
file_cluster_offset + offset_into_cluster(s, offset),
66
offset, buf, bytes) < 0)
28
--
67
--
29
2.19.1
68
2.20.1
30
69
31
70
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Hikaru Nishida <hikarupsp@gmail.com>
2
2
3
When using the vvfat driver with a directory that contains too many files,
3
Before this commit, BDRVVVFATState.qcow is unrefed in write_target_close
4
QEMU currently crashes. This can be triggered like this for example:
4
on closing backing bdrv of vvfat. However, qcow bdrv is opend as a child
5
of vvfat in enable_write_target() so it will be also unrefed on closing
6
vvfat itself. This causes use-after-free of qcow on freeing vvfat which
7
has backing bdrv and qcow bdrv as children in this order because
8
bdrv_close(vvfat) tries to free qcow bdrv after freeing backing bdrv
9
as QLIST_FOREACH_SAFE() loop keeps next pointer, but BdrvChild of qcow
10
is already freed in bdrv_close(backing bdrv).
5
11
6
mkdir /tmp/vvfattest
12
Signed-off-by: Hikaru Nishida <hikarupsp@gmail.com>
7
cd /tmp/vvfattest
13
Message-Id: <20200209175156.85748-1-hikarupsp@gmail.com>
8
for ((x=0;x<=513;x++)); do mkdir $x; done
9
qemu-system-x86_64 -drive \
10
file.driver=vvfat,file.dir=.,read-only=on,media=cdrom
11
12
Seems like read_directory() is changing the mapping->path variable. Make
13
sure we use the right pointer instead.
14
15
Signed-off-by: Thomas Huth <thuth@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
---
15
---
18
block/vvfat.c | 4 ++--
16
block/vvfat.c | 7 -------
19
1 file changed, 2 insertions(+), 2 deletions(-)
17
1 file changed, 7 deletions(-)
20
18
21
diff --git a/block/vvfat.c b/block/vvfat.c
19
diff --git a/block/vvfat.c b/block/vvfat.c
22
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
23
--- a/block/vvfat.c
21
--- a/block/vvfat.c
24
+++ b/block/vvfat.c
22
+++ b/block/vvfat.c
25
@@ -XXX,XX +XXX,XX @@ static int init_directories(BDRVVVFATState* s,
23
@@ -XXX,XX +XXX,XX @@ write_target_commit(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
26
mapping = array_get(&(s->mapping), i);
24
return ret;
27
25
}
28
if (mapping->mode & MODE_DIRECTORY) {
26
29
+ char *path = mapping->path;
27
-static void write_target_close(BlockDriverState *bs) {
30
mapping->begin = cluster;
28
- BDRVVVFATState* s = *((BDRVVVFATState**) bs->opaque);
31
if(read_directory(s, i)) {
29
- bdrv_unref_child(s->bs, s->qcow);
32
- error_setg(errp, "Could not read directory %s",
30
- g_free(s->qcow_filename);
33
- mapping->path);
31
-}
34
+ error_setg(errp, "Could not read directory %s", path);
32
-
35
return -1;
33
static BlockDriver vvfat_write_target = {
36
}
34
.format_name = "vvfat_write_target",
37
mapping = array_get(&(s->mapping), i);
35
.instance_size = sizeof(void*),
36
.bdrv_co_pwritev = write_target_commit,
37
- .bdrv_close = write_target_close,
38
};
39
40
static void vvfat_qcow_options(int *child_flags, QDict *child_options,
38
--
41
--
39
2.19.1
42
2.20.1
40
43
41
44
diff view generated by jsdifflib
1
From: Leonid Bloch <lbloch@janustech.com>
1
In the case that update_refcount() frees a refcount block, it evicts it
2
from the metadata cache. Before doing so, however, it returns the
3
currently used refcount block to the cache because it might be the same.
4
Returning the refcount block early means that we need to reset
5
old_table_index so that we reload the refcount block in the next
6
iteration if it is actually still in use.
2
7
3
The lookup table for power-of-two sizes was added in commit 540b8492618eb
8
Fixes: f71c08ea8e60f035485a512fd2af8908567592f0
4
for the purpose of having convenient shortcuts for these sizes in cases
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
when the literal number has to be present at compile time, and
10
Message-Id: <20200211094900.17315-2-kwolf@redhat.com>
6
expressions as '(1 * KiB)' can not be used. One such case is the
7
stringification of sizes. Beyond that, it is convenient to use these
8
shortcuts for all power-of-two sizes, even if they don't have to be
9
literal numbers.
10
11
Despite its convenience, this table introduced 55 lines of "dumb" code,
12
the purpose and origin of which are obscure without reading the message
13
of the commit which introduced it. This patch fixes that by adding a
14
comment to the code itself with a brief explanation for the reasoning
15
behind this table. This comment includes the short AWK script that
16
generated the table, so that anyone who's interested could make sure
17
that the values in it are correct (otherwise these values look as if
18
they were typed manually).
19
20
Signed-off-by: Leonid Bloch <lbloch@janustech.com>
21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
---
12
---
23
include/qemu/units.h | 18 ++++++++++++++++++
13
block/qcow2-refcount.c | 1 +
24
1 file changed, 18 insertions(+)
14
1 file changed, 1 insertion(+)
25
15
26
diff --git a/include/qemu/units.h b/include/qemu/units.h
16
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
27
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
28
--- a/include/qemu/units.h
18
--- a/block/qcow2-refcount.c
29
+++ b/include/qemu/units.h
19
+++ b/block/qcow2-refcount.c
30
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
31
#define PiB (INT64_C(1) << 50)
21
offset);
32
#define EiB (INT64_C(1) << 60)
22
if (table != NULL) {
33
23
qcow2_cache_put(s->refcount_block_cache, &refcount_block);
34
+/*
24
+ old_table_index = -1;
35
+ * The following lookup table is intended to be used when a literal string of
25
qcow2_cache_discard(s->refcount_block_cache, table);
36
+ * the number of bytes is required (for example if it needs to be stringified).
26
}
37
+ * It can also be used for generic shortcuts of power-of-two sizes.
27
38
+ * This table is generated using the AWK script below:
39
+ *
40
+ * BEGIN {
41
+ * suffix="KMGTPE";
42
+ * for(i=10; i<64; i++) {
43
+ * val=2**i;
44
+ * s=substr(suffix, int(i/10), 1);
45
+ * n=2**(i%10);
46
+ * pad=21-int(log(n)/log(10));
47
+ * printf("#define S_%d%siB %*d\n", n, s, pad, val);
48
+ * }
49
+ * }
50
+ */
51
+
52
#define S_1KiB 1024
53
#define S_2KiB 2048
54
#define S_4KiB 4096
55
--
28
--
56
2.19.1
29
2.20.1
57
30
58
31
diff view generated by jsdifflib
1
From: Peter Maydell <peter.maydell@linaro.org>
1
For external data file, cluster allocations return an offset in the data
2
file and are not refcounted. In this case, there is nothing to do for
3
qcow2_alloc_cluster_abort(). Freeing the same offset in the qcow2 file
4
is wrong and causes crashes in the better case or image corruption in
5
the worse case.
2
6
3
Taking the address of a field in a packed struct is a bad idea, because
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
it might not be actually aligned enough for that pointer type (and
8
Message-Id: <20200211094900.17315-3-kwolf@redhat.com>
5
thus cause a crash on dereference on some host architectures). Newer
6
versions of clang warn about this. Avoid the bug by not using the
7
"modify in place" byte swapping functions.
8
9
There are a few places where the in-place swap function is
10
used on something other than a packed struct field; we convert
11
those anyway, for consistency.
12
13
Patch produced with scripts/coccinelle/inplace-byteswaps.cocci.
14
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
---
10
---
19
block/vhdx.h | 12 ++---
11
block/qcow2-cluster.c | 7 +++++--
20
block/vhdx-endian.c | 118 ++++++++++++++++++++++----------------------
12
1 file changed, 5 insertions(+), 2 deletions(-)
21
block/vhdx-log.c | 4 +-
22
block/vhdx.c | 18 +++----
23
4 files changed, 76 insertions(+), 76 deletions(-)
24
13
25
diff --git a/block/vhdx.h b/block/vhdx.h
14
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
26
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
27
--- a/block/vhdx.h
16
--- a/block/qcow2-cluster.c
28
+++ b/block/vhdx.h
17
+++ b/block/qcow2-cluster.c
29
@@ -XXX,XX +XXX,XX @@ int vhdx_log_write_and_flush(BlockDriverState *bs, BDRVVHDXState *s,
18
@@ -XXX,XX +XXX,XX @@ err:
30
19
void qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m)
31
static inline void leguid_to_cpus(MSGUID *guid)
32
{
20
{
33
- le32_to_cpus(&guid->data1);
21
BDRVQcow2State *s = bs->opaque;
34
- le16_to_cpus(&guid->data2);
22
- qcow2_free_clusters(bs, m->alloc_offset, m->nb_clusters << s->cluster_bits,
35
- le16_to_cpus(&guid->data3);
23
- QCOW2_DISCARD_NEVER);
36
+ guid->data1 = le32_to_cpu(guid->data1);
24
+ if (!has_data_file(bs)) {
37
+ guid->data2 = le16_to_cpu(guid->data2);
25
+ qcow2_free_clusters(bs, m->alloc_offset,
38
+ guid->data3 = le16_to_cpu(guid->data3);
26
+ m->nb_clusters << s->cluster_bits,
27
+ QCOW2_DISCARD_NEVER);
28
+ }
39
}
29
}
40
30
41
static inline void cpu_to_leguids(MSGUID *guid)
31
/*
42
{
43
- cpu_to_le32s(&guid->data1);
44
- cpu_to_le16s(&guid->data2);
45
- cpu_to_le16s(&guid->data3);
46
+ guid->data1 = cpu_to_le32(guid->data1);
47
+ guid->data2 = cpu_to_le16(guid->data2);
48
+ guid->data3 = cpu_to_le16(guid->data3);
49
}
50
51
void vhdx_header_le_import(VHDXHeader *h);
52
diff --git a/block/vhdx-endian.c b/block/vhdx-endian.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/block/vhdx-endian.c
55
+++ b/block/vhdx-endian.c
56
@@ -XXX,XX +XXX,XX @@ void vhdx_header_le_import(VHDXHeader *h)
57
{
58
assert(h != NULL);
59
60
- le32_to_cpus(&h->signature);
61
- le32_to_cpus(&h->checksum);
62
- le64_to_cpus(&h->sequence_number);
63
+ h->signature = le32_to_cpu(h->signature);
64
+ h->checksum = le32_to_cpu(h->checksum);
65
+ h->sequence_number = le64_to_cpu(h->sequence_number);
66
67
leguid_to_cpus(&h->file_write_guid);
68
leguid_to_cpus(&h->data_write_guid);
69
leguid_to_cpus(&h->log_guid);
70
71
- le16_to_cpus(&h->log_version);
72
- le16_to_cpus(&h->version);
73
- le32_to_cpus(&h->log_length);
74
- le64_to_cpus(&h->log_offset);
75
+ h->log_version = le16_to_cpu(h->log_version);
76
+ h->version = le16_to_cpu(h->version);
77
+ h->log_length = le32_to_cpu(h->log_length);
78
+ h->log_offset = le64_to_cpu(h->log_offset);
79
}
80
81
void vhdx_header_le_export(VHDXHeader *orig_h, VHDXHeader *new_h)
82
@@ -XXX,XX +XXX,XX @@ void vhdx_log_desc_le_import(VHDXLogDescriptor *d)
83
{
84
assert(d != NULL);
85
86
- le32_to_cpus(&d->signature);
87
- le64_to_cpus(&d->file_offset);
88
- le64_to_cpus(&d->sequence_number);
89
+ d->signature = le32_to_cpu(d->signature);
90
+ d->file_offset = le64_to_cpu(d->file_offset);
91
+ d->sequence_number = le64_to_cpu(d->sequence_number);
92
}
93
94
void vhdx_log_desc_le_export(VHDXLogDescriptor *d)
95
{
96
assert(d != NULL);
97
98
- cpu_to_le32s(&d->signature);
99
- cpu_to_le32s(&d->trailing_bytes);
100
- cpu_to_le64s(&d->leading_bytes);
101
- cpu_to_le64s(&d->file_offset);
102
- cpu_to_le64s(&d->sequence_number);
103
+ d->signature = cpu_to_le32(d->signature);
104
+ d->trailing_bytes = cpu_to_le32(d->trailing_bytes);
105
+ d->leading_bytes = cpu_to_le64(d->leading_bytes);
106
+ d->file_offset = cpu_to_le64(d->file_offset);
107
+ d->sequence_number = cpu_to_le64(d->sequence_number);
108
}
109
110
void vhdx_log_data_le_import(VHDXLogDataSector *d)
111
{
112
assert(d != NULL);
113
114
- le32_to_cpus(&d->data_signature);
115
- le32_to_cpus(&d->sequence_high);
116
- le32_to_cpus(&d->sequence_low);
117
+ d->data_signature = le32_to_cpu(d->data_signature);
118
+ d->sequence_high = le32_to_cpu(d->sequence_high);
119
+ d->sequence_low = le32_to_cpu(d->sequence_low);
120
}
121
122
void vhdx_log_data_le_export(VHDXLogDataSector *d)
123
{
124
assert(d != NULL);
125
126
- cpu_to_le32s(&d->data_signature);
127
- cpu_to_le32s(&d->sequence_high);
128
- cpu_to_le32s(&d->sequence_low);
129
+ d->data_signature = cpu_to_le32(d->data_signature);
130
+ d->sequence_high = cpu_to_le32(d->sequence_high);
131
+ d->sequence_low = cpu_to_le32(d->sequence_low);
132
}
133
134
void vhdx_log_entry_hdr_le_import(VHDXLogEntryHeader *hdr)
135
{
136
assert(hdr != NULL);
137
138
- le32_to_cpus(&hdr->signature);
139
- le32_to_cpus(&hdr->checksum);
140
- le32_to_cpus(&hdr->entry_length);
141
- le32_to_cpus(&hdr->tail);
142
- le64_to_cpus(&hdr->sequence_number);
143
- le32_to_cpus(&hdr->descriptor_count);
144
+ hdr->signature = le32_to_cpu(hdr->signature);
145
+ hdr->checksum = le32_to_cpu(hdr->checksum);
146
+ hdr->entry_length = le32_to_cpu(hdr->entry_length);
147
+ hdr->tail = le32_to_cpu(hdr->tail);
148
+ hdr->sequence_number = le64_to_cpu(hdr->sequence_number);
149
+ hdr->descriptor_count = le32_to_cpu(hdr->descriptor_count);
150
leguid_to_cpus(&hdr->log_guid);
151
- le64_to_cpus(&hdr->flushed_file_offset);
152
- le64_to_cpus(&hdr->last_file_offset);
153
+ hdr->flushed_file_offset = le64_to_cpu(hdr->flushed_file_offset);
154
+ hdr->last_file_offset = le64_to_cpu(hdr->last_file_offset);
155
}
156
157
void vhdx_log_entry_hdr_le_export(VHDXLogEntryHeader *hdr)
158
{
159
assert(hdr != NULL);
160
161
- cpu_to_le32s(&hdr->signature);
162
- cpu_to_le32s(&hdr->checksum);
163
- cpu_to_le32s(&hdr->entry_length);
164
- cpu_to_le32s(&hdr->tail);
165
- cpu_to_le64s(&hdr->sequence_number);
166
- cpu_to_le32s(&hdr->descriptor_count);
167
+ hdr->signature = cpu_to_le32(hdr->signature);
168
+ hdr->checksum = cpu_to_le32(hdr->checksum);
169
+ hdr->entry_length = cpu_to_le32(hdr->entry_length);
170
+ hdr->tail = cpu_to_le32(hdr->tail);
171
+ hdr->sequence_number = cpu_to_le64(hdr->sequence_number);
172
+ hdr->descriptor_count = cpu_to_le32(hdr->descriptor_count);
173
cpu_to_leguids(&hdr->log_guid);
174
- cpu_to_le64s(&hdr->flushed_file_offset);
175
- cpu_to_le64s(&hdr->last_file_offset);
176
+ hdr->flushed_file_offset = cpu_to_le64(hdr->flushed_file_offset);
177
+ hdr->last_file_offset = cpu_to_le64(hdr->last_file_offset);
178
}
179
180
181
@@ -XXX,XX +XXX,XX @@ void vhdx_region_header_le_import(VHDXRegionTableHeader *hdr)
182
{
183
assert(hdr != NULL);
184
185
- le32_to_cpus(&hdr->signature);
186
- le32_to_cpus(&hdr->checksum);
187
- le32_to_cpus(&hdr->entry_count);
188
+ hdr->signature = le32_to_cpu(hdr->signature);
189
+ hdr->checksum = le32_to_cpu(hdr->checksum);
190
+ hdr->entry_count = le32_to_cpu(hdr->entry_count);
191
}
192
193
void vhdx_region_header_le_export(VHDXRegionTableHeader *hdr)
194
{
195
assert(hdr != NULL);
196
197
- cpu_to_le32s(&hdr->signature);
198
- cpu_to_le32s(&hdr->checksum);
199
- cpu_to_le32s(&hdr->entry_count);
200
+ hdr->signature = cpu_to_le32(hdr->signature);
201
+ hdr->checksum = cpu_to_le32(hdr->checksum);
202
+ hdr->entry_count = cpu_to_le32(hdr->entry_count);
203
}
204
205
void vhdx_region_entry_le_import(VHDXRegionTableEntry *e)
206
@@ -XXX,XX +XXX,XX @@ void vhdx_region_entry_le_import(VHDXRegionTableEntry *e)
207
assert(e != NULL);
208
209
leguid_to_cpus(&e->guid);
210
- le64_to_cpus(&e->file_offset);
211
- le32_to_cpus(&e->length);
212
- le32_to_cpus(&e->data_bits);
213
+ e->file_offset = le64_to_cpu(e->file_offset);
214
+ e->length = le32_to_cpu(e->length);
215
+ e->data_bits = le32_to_cpu(e->data_bits);
216
}
217
218
void vhdx_region_entry_le_export(VHDXRegionTableEntry *e)
219
@@ -XXX,XX +XXX,XX @@ void vhdx_region_entry_le_export(VHDXRegionTableEntry *e)
220
assert(e != NULL);
221
222
cpu_to_leguids(&e->guid);
223
- cpu_to_le64s(&e->file_offset);
224
- cpu_to_le32s(&e->length);
225
- cpu_to_le32s(&e->data_bits);
226
+ e->file_offset = cpu_to_le64(e->file_offset);
227
+ e->length = cpu_to_le32(e->length);
228
+ e->data_bits = cpu_to_le32(e->data_bits);
229
}
230
231
232
@@ -XXX,XX +XXX,XX @@ void vhdx_metadata_header_le_import(VHDXMetadataTableHeader *hdr)
233
{
234
assert(hdr != NULL);
235
236
- le64_to_cpus(&hdr->signature);
237
- le16_to_cpus(&hdr->entry_count);
238
+ hdr->signature = le64_to_cpu(hdr->signature);
239
+ hdr->entry_count = le16_to_cpu(hdr->entry_count);
240
}
241
242
void vhdx_metadata_header_le_export(VHDXMetadataTableHeader *hdr)
243
{
244
assert(hdr != NULL);
245
246
- cpu_to_le64s(&hdr->signature);
247
- cpu_to_le16s(&hdr->entry_count);
248
+ hdr->signature = cpu_to_le64(hdr->signature);
249
+ hdr->entry_count = cpu_to_le16(hdr->entry_count);
250
}
251
252
void vhdx_metadata_entry_le_import(VHDXMetadataTableEntry *e)
253
@@ -XXX,XX +XXX,XX @@ void vhdx_metadata_entry_le_import(VHDXMetadataTableEntry *e)
254
assert(e != NULL);
255
256
leguid_to_cpus(&e->item_id);
257
- le32_to_cpus(&e->offset);
258
- le32_to_cpus(&e->length);
259
- le32_to_cpus(&e->data_bits);
260
+ e->offset = le32_to_cpu(e->offset);
261
+ e->length = le32_to_cpu(e->length);
262
+ e->data_bits = le32_to_cpu(e->data_bits);
263
}
264
void vhdx_metadata_entry_le_export(VHDXMetadataTableEntry *e)
265
{
266
assert(e != NULL);
267
268
cpu_to_leguids(&e->item_id);
269
- cpu_to_le32s(&e->offset);
270
- cpu_to_le32s(&e->length);
271
- cpu_to_le32s(&e->data_bits);
272
+ e->offset = cpu_to_le32(e->offset);
273
+ e->length = cpu_to_le32(e->length);
274
+ e->data_bits = cpu_to_le32(e->data_bits);
275
}
276
diff --git a/block/vhdx-log.c b/block/vhdx-log.c
277
index XXXXXXX..XXXXXXX 100644
278
--- a/block/vhdx-log.c
279
+++ b/block/vhdx-log.c
280
@@ -XXX,XX +XXX,XX @@ static void vhdx_log_raw_to_le_sector(VHDXLogDescriptor *desc,
281
/* 8 + 4084 + 4 = 4096, 1 log sector */
282
memcpy(&desc->leading_bytes, data, 8);
283
data += 8;
284
- cpu_to_le64s(&desc->leading_bytes);
285
+ desc->leading_bytes = cpu_to_le64(desc->leading_bytes);
286
memcpy(sector->data, data, 4084);
287
data += 4084;
288
memcpy(&desc->trailing_bytes, data, 4);
289
- cpu_to_le32s(&desc->trailing_bytes);
290
+ desc->trailing_bytes = cpu_to_le32(desc->trailing_bytes);
291
data += 4;
292
293
sector->sequence_high = (uint32_t) (seq >> 32);
294
diff --git a/block/vhdx.c b/block/vhdx.c
295
index XXXXXXX..XXXXXXX 100644
296
--- a/block/vhdx.c
297
+++ b/block/vhdx.c
298
@@ -XXX,XX +XXX,XX @@ uint32_t vhdx_update_checksum(uint8_t *buf, size_t size, int crc_offset)
299
300
memset(buf + crc_offset, 0, sizeof(crc));
301
crc = crc32c(0xffffffff, buf, size);
302
- cpu_to_le32s(&crc);
303
+ crc = cpu_to_le32(crc);
304
memcpy(buf + crc_offset, &crc, sizeof(crc));
305
306
return crc;
307
@@ -XXX,XX +XXX,XX @@ static int vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s)
308
goto exit;
309
}
310
311
- le32_to_cpus(&s->params.block_size);
312
- le32_to_cpus(&s->params.data_bits);
313
+ s->params.block_size = le32_to_cpu(s->params.block_size);
314
+ s->params.data_bits = le32_to_cpu(s->params.data_bits);
315
316
317
/* We now have the file parameters, so we can tell if this is a
318
@@ -XXX,XX +XXX,XX @@ static int vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s)
319
goto exit;
320
}
321
322
- le64_to_cpus(&s->virtual_disk_size);
323
- le32_to_cpus(&s->logical_sector_size);
324
- le32_to_cpus(&s->physical_sector_size);
325
+ s->virtual_disk_size = le64_to_cpu(s->virtual_disk_size);
326
+ s->logical_sector_size = le32_to_cpu(s->logical_sector_size);
327
+ s->physical_sector_size = le32_to_cpu(s->physical_sector_size);
328
329
if (s->params.block_size < VHDX_BLOCK_SIZE_MIN ||
330
s->params.block_size > VHDX_BLOCK_SIZE_MAX) {
331
@@ -XXX,XX +XXX,XX @@ static int vhdx_open(BlockDriverState *bs, QDict *options, int flags,
332
/* endian convert, and verify populated BAT field file offsets against
333
* region table and log entries */
334
for (i = 0; i < s->bat_entries; i++) {
335
- le64_to_cpus(&s->bat[i]);
336
+ s->bat[i] = le64_to_cpu(s->bat[i]);
337
if (payblocks--) {
338
/* payload bat entries */
339
if ((s->bat[i] & VHDX_BAT_STATE_BIT_MASK) ==
340
@@ -XXX,XX +XXX,XX @@ static int vhdx_create_new_metadata(BlockBackend *blk,
341
mt_file_params->block_size = cpu_to_le32(block_size);
342
if (type == VHDX_TYPE_FIXED) {
343
mt_file_params->data_bits |= VHDX_PARAMS_LEAVE_BLOCKS_ALLOCED;
344
- cpu_to_le32s(&mt_file_params->data_bits);
345
+ mt_file_params->data_bits = cpu_to_le32(mt_file_params->data_bits);
346
}
347
348
vhdx_guid_generate(&mt_page83->page_83_data);
349
@@ -XXX,XX +XXX,XX @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
350
sinfo.file_offset = ROUND_UP(sinfo.file_offset, MiB);
351
vhdx_update_bat_table_entry(blk_bs(blk), s, &sinfo, &unused, &unused,
352
block_state);
353
- cpu_to_le64s(&s->bat[sinfo.bat_idx]);
354
+ s->bat[sinfo.bat_idx] = cpu_to_le64(s->bat[sinfo.bat_idx]);
355
sector_num += s->sectors_per_block;
356
}
357
ret = blk_pwrite(blk, file_offset, s->bat, length, 0);
358
--
32
--
359
2.19.1
33
2.20.1
360
34
361
35
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
This adds a test for 'qemu-img convert' with copy offloading where the
2
target image has an external data file. If the test hosts supports it,
3
it tests both the case where copy offloading is supported and the case
4
where it isn't (otherwise we just test unsupported twice).
2
5
3
Signed-off-by: Alberto Garcia <berto@igalia.com>
6
More specifically, the case with unsupported copy offloading tests
7
qcow2_alloc_cluster_abort() with external data files.
8
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Message-Id: <20200211094900.17315-4-kwolf@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
---
12
---
6
tests/qemu-iotests/081 | 30 ++++++++++++++++++++++++++++++
13
tests/qemu-iotests/244 | 14 ++++++++++++++
7
tests/qemu-iotests/081.out | 16 ++++++++++++++++
14
tests/qemu-iotests/244.out | 6 ++++++
8
2 files changed, 46 insertions(+)
15
2 files changed, 20 insertions(+)
9
16
10
diff --git a/tests/qemu-iotests/081 b/tests/qemu-iotests/081
17
diff --git a/tests/qemu-iotests/244 b/tests/qemu-iotests/244
11
index XXXXXXX..XXXXXXX 100755
18
index XXXXXXX..XXXXXXX 100755
12
--- a/tests/qemu-iotests/081
19
--- a/tests/qemu-iotests/244
13
+++ b/tests/qemu-iotests/081
20
+++ b/tests/qemu-iotests/244
14
@@ -XXX,XX +XXX,XX @@ echo "== checking that quorum is broken =="
21
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c 'read -P 0x11 0 1M' -f $IMGFMT "$TEST_IMG" | _filter_qemu_io
15
22
$QEMU_IMG map --output=human "$TEST_IMG" | _filter_testdir
16
$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
23
$QEMU_IMG map --output=json "$TEST_IMG"
17
24
18
+echo
25
+echo
19
+echo "== checking the blkverify mode with broken content =="
26
+echo "=== Copy offloading ==="
27
+echo
20
+
28
+
21
+quorum="driver=raw,file.driver=quorum,file.vote-threshold=2,file.blkverify=on"
29
+# Make use of copy offloading if the test host can provide it
22
+quorum="$quorum,file.children.0.file.filename=$TEST_DIR/1.raw"
30
+_make_test_img -o "data_file=$TEST_IMG.data" 64M
23
+quorum="$quorum,file.children.1.file.filename=$TEST_DIR/2.raw"
31
+$QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n -C "$TEST_IMG.src" "$TEST_IMG"
24
+quorum="$quorum,file.children.0.driver=raw"
32
+$QEMU_IMG compare -f $IMGFMT -F $IMGFMT "$TEST_IMG.src" "$TEST_IMG"
25
+quorum="$quorum,file.children.1.driver=raw"
26
+
33
+
27
+$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
34
+# blkdebug doesn't support copy offloading, so this tests the error path
28
+
35
+$QEMU_IMG amend -f $IMGFMT -o "data_file=blkdebug::$TEST_IMG.data" "$TEST_IMG"
29
+echo
36
+$QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n -C "$TEST_IMG.src" "$TEST_IMG"
30
+echo "== writing the same data to both files =="
37
+$QEMU_IMG compare -f $IMGFMT -F $IMGFMT "$TEST_IMG.src" "$TEST_IMG"
31
+
32
+$QEMU_IO -c "write -P 0x32 0 $size" "$TEST_DIR/1.raw" | _filter_qemu_io
33
+$QEMU_IO -c "write -P 0x32 0 $size" "$TEST_DIR/2.raw" | _filter_qemu_io
34
+
35
+echo
36
+echo "== checking the blkverify mode with valid content =="
37
+
38
+$QEMU_IO -c "open -o $quorum" -c "read -P 0x32 0 $size" | _filter_qemu_io
39
+
40
+echo
41
+echo "== checking the blkverify mode with invalid settings =="
42
+
43
+quorum="$quorum,file.children.2.file.filename=$TEST_DIR/3.raw"
44
+quorum="$quorum,file.children.2.driver=raw"
45
+
46
+$QEMU_IO -c "open -o $quorum" | _filter_qemu_io
47
+
38
+
48
# success, all done
39
# success, all done
49
echo "*** done"
40
echo "*** done"
50
rm -f $seq.full
41
rm -f $seq.full
51
diff --git a/tests/qemu-iotests/081.out b/tests/qemu-iotests/081.out
42
diff --git a/tests/qemu-iotests/244.out b/tests/qemu-iotests/244.out
52
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
53
--- a/tests/qemu-iotests/081.out
44
--- a/tests/qemu-iotests/244.out
54
+++ b/tests/qemu-iotests/081.out
45
+++ b/tests/qemu-iotests/244.out
55
@@ -XXX,XX +XXX,XX @@ wrote 10485760/10485760 bytes at offset 0
46
@@ -XXX,XX +XXX,XX @@ Offset Length Mapped to File
56
47
0 0x100000 0 TEST_DIR/t.qcow2.data
57
== checking that quorum is broken ==
48
[{ "start": 0, "length": 1048576, "depth": 0, "zero": false, "data": true, "offset": 0},
58
read failed: Input/output error
49
{ "start": 1048576, "length": 66060288, "depth": 0, "zero": true, "data": false}]
59
+
50
+
60
+== checking the blkverify mode with broken content ==
51
+=== Copy offloading ===
61
+quorum: offset=0 bytes=10485760 contents mismatch at offset 0
62
+
52
+
63
+== writing the same data to both files ==
53
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IMGFMT.data
64
+wrote 10485760/10485760 bytes at offset 0
54
+Images are identical.
65
+10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
55
+Images are identical.
66
+wrote 10485760/10485760 bytes at offset 0
67
+10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
68
+
69
+== checking the blkverify mode with valid content ==
70
+read 10485760/10485760 bytes at offset 0
71
+10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
72
+
73
+== checking the blkverify mode with invalid settings ==
74
+can't open: blkverify=on can only be set if there are exactly two files and vote-threshold is 2
75
*** done
56
*** done
76
--
57
--
77
2.19.1
58
2.20.1
78
59
79
60
diff view generated by jsdifflib
1
From: Peter Maydell <peter.maydell@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Taking the address of a field in a packed struct is a bad idea, because
3
Fix warning reported by Clang static code analyzer:
4
it might not be actually aligned enough for that pointer type (and
5
thus cause a crash on dereference on some host architectures). Newer
6
versions of clang warn about this. Avoid the bug by not using the
7
"modify in place" byte swapping functions.
8
4
9
There are a few places where the in-place swap function is
5
CC block/qcow2-bitmap.o
10
used on something other than a packed struct field; we convert
6
block/qcow2-bitmap.c:650:5: warning: Value stored to 'ret' is never read
11
those anyway, for consistency.
7
ret = -EINVAL;
8
^ ~~~~~~~
12
9
13
This patch was produced with the following spatch script:
10
Fixes: 88ddffae8
14
11
Reported-by: Clang Static Analyzer
15
@@
12
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
16
expression E;
13
Message-Id: <20200215161557.4077-2-philmd@redhat.com>
17
@@
18
-be16_to_cpus(&E);
19
+E = be16_to_cpu(E);
20
@@
21
expression E;
22
@@
23
-be32_to_cpus(&E);
24
+E = be32_to_cpu(E);
25
@@
26
expression E;
27
@@
28
-be64_to_cpus(&E);
29
+E = be64_to_cpu(E);
30
@@
31
expression E;
32
@@
33
-cpu_to_be16s(&E);
34
+E = cpu_to_be16(E);
35
@@
36
expression E;
37
@@
38
-cpu_to_be32s(&E);
39
+E = cpu_to_be32(E);
40
@@
41
expression E;
42
@@
43
-cpu_to_be64s(&E);
44
+E = cpu_to_be64(E);
45
46
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
47
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
48
Tested-by: John Snow <jsnow@redhat.com>
15
Reviewed-by: Ján Tomko <jtomko@redhat.com>
49
Reviewed-by: John Snow <jsnow@redhat.com>
16
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
50
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
51
---
18
---
52
block/qcow2-bitmap.c | 24 ++++++++++++------------
19
block/qcow2-bitmap.c | 1 -
53
1 file changed, 12 insertions(+), 12 deletions(-)
20
1 file changed, 1 deletion(-)
54
21
55
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
22
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
56
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
57
--- a/block/qcow2-bitmap.c
24
--- a/block/qcow2-bitmap.c
58
+++ b/block/qcow2-bitmap.c
25
+++ b/block/qcow2-bitmap.c
59
@@ -XXX,XX +XXX,XX @@ static inline void bitmap_table_to_be(uint64_t *bitmap_table, size_t size)
26
@@ -XXX,XX +XXX,XX @@ static Qcow2BitmapList *bitmap_list_load(BlockDriverState *bs, uint64_t offset,
60
size_t i;
27
return bm_list;
61
28
62
for (i = 0; i < size; ++i) {
29
broken_dir:
63
- cpu_to_be64s(&bitmap_table[i]);
30
- ret = -EINVAL;
64
+ bitmap_table[i] = cpu_to_be64(bitmap_table[i]);
31
error_setg(errp, "Broken bitmap directory");
65
}
32
66
}
33
fail:
67
68
@@ -XXX,XX +XXX,XX @@ static int bitmap_table_load(BlockDriverState *bs, Qcow2BitmapTable *tb,
69
}
70
71
for (i = 0; i < tb->size; ++i) {
72
- be64_to_cpus(&table[i]);
73
+ table[i] = be64_to_cpu(table[i]);
74
ret = check_table_entry(table[i], s->cluster_size);
75
if (ret < 0) {
76
goto fail;
77
@@ -XXX,XX +XXX,XX @@ fail:
78
79
static inline void bitmap_dir_entry_to_cpu(Qcow2BitmapDirEntry *entry)
80
{
81
- be64_to_cpus(&entry->bitmap_table_offset);
82
- be32_to_cpus(&entry->bitmap_table_size);
83
- be32_to_cpus(&entry->flags);
84
- be16_to_cpus(&entry->name_size);
85
- be32_to_cpus(&entry->extra_data_size);
86
+ entry->bitmap_table_offset = be64_to_cpu(entry->bitmap_table_offset);
87
+ entry->bitmap_table_size = be32_to_cpu(entry->bitmap_table_size);
88
+ entry->flags = be32_to_cpu(entry->flags);
89
+ entry->name_size = be16_to_cpu(entry->name_size);
90
+ entry->extra_data_size = be32_to_cpu(entry->extra_data_size);
91
}
92
93
static inline void bitmap_dir_entry_to_be(Qcow2BitmapDirEntry *entry)
94
{
95
- cpu_to_be64s(&entry->bitmap_table_offset);
96
- cpu_to_be32s(&entry->bitmap_table_size);
97
- cpu_to_be32s(&entry->flags);
98
- cpu_to_be16s(&entry->name_size);
99
- cpu_to_be32s(&entry->extra_data_size);
100
+ entry->bitmap_table_offset = cpu_to_be64(entry->bitmap_table_offset);
101
+ entry->bitmap_table_size = cpu_to_be32(entry->bitmap_table_size);
102
+ entry->flags = cpu_to_be32(entry->flags);
103
+ entry->name_size = cpu_to_be16(entry->name_size);
104
+ entry->extra_data_size = cpu_to_be32(entry->extra_data_size);
105
}
106
107
static inline int calc_dir_entry_size(size_t name_size, size_t extra_data_size)
108
--
34
--
109
2.19.1
35
2.20.1
110
36
111
37
diff view generated by jsdifflib
1
From: Leonid Bloch <lbloch@janustech.com>
1
It is not obvious what 'ignore' actually means for block jobs: It could
2
be continuing the job and returning success in the end despite the error
3
(no block job does this). It could also mean continuing and returning
4
failure in the end (this is what stream does). And it can mean retrying
5
the failed request later (this is what backup, commit and mirror do).
2
6
3
If an expression is used to define DEFAULT_CLUSTER_SIZE, when compiled,
7
This (somewhat inconsistent) behaviour was introduced and described for
4
it will be embedded as a literal expression in the binary (as the
8
stream and mirror in commit 32c81a4a6ec. backup and commit were
5
default value) because it is stringified to mark the size of the default
9
introduced later and use the same model as mirror.
6
value. Now this is fixed by using a defined number to define this value.
7
10
8
Signed-off-by: Leonid Bloch <lbloch@janustech.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Reviewed-by: Stefan Weil <sw@weilnetz.de>
12
Message-Id: <20200214200812.28180-2-kwolf@redhat.com>
13
Reviewed-by: Ján Tomko <jtomko@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
15
---
12
block/vdi.c | 4 ++--
16
qapi/block-core.json | 5 ++++-
13
1 file changed, 2 insertions(+), 2 deletions(-)
17
1 file changed, 4 insertions(+), 1 deletion(-)
14
18
15
diff --git a/block/vdi.c b/block/vdi.c
19
diff --git a/qapi/block-core.json b/qapi/block-core.json
16
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
17
--- a/block/vdi.c
21
--- a/qapi/block-core.json
18
+++ b/block/vdi.c
22
+++ b/qapi/block-core.json
19
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@
20
#define BLOCK_OPT_STATIC "static"
24
# for jobs, cancel the job
21
25
#
22
#define SECTOR_SIZE 512
26
# @ignore: ignore the error, only report a QMP event (BLOCK_IO_ERROR
23
-#define DEFAULT_CLUSTER_SIZE (1 * MiB)
27
-# or BLOCK_JOB_ERROR)
24
+#define DEFAULT_CLUSTER_SIZE S_1MiB
28
+# or BLOCK_JOB_ERROR). The backup, mirror and commit block jobs retry
25
29
+# the failing request later and may still complete successfully. The
26
#if defined(CONFIG_VDI_DEBUG)
30
+# stream block job continues to stream and will complete with an
27
#define VDI_DEBUG 1
31
+# error.
28
@@ -XXX,XX +XXX,XX @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
32
#
29
goto fail;
33
# @enospc: same as @stop on ENOSPC, same as @report otherwise.
30
} else if (header.block_size != DEFAULT_CLUSTER_SIZE) {
34
#
31
error_setg(errp, "unsupported VDI image (block size %" PRIu32
32
- " is not %" PRIu64 ")",
33
+ " is not %" PRIu32 ")",
34
header.block_size, DEFAULT_CLUSTER_SIZE);
35
ret = -ENOTSUP;
36
goto fail;
37
--
35
--
38
2.19.1
36
2.20.1
39
37
40
38
diff view generated by jsdifflib
1
If read-only=off, but auto-read-only=on is given, open the file
1
The bytes_written variable is only ever written to, it serves no
2
read-write if we have the permissions, but instead of erroring out for
2
purpose. This has actually been the case since the commit job was first
3
read-only files, just degrade to read-only.
3
introduced in commit 747ff602636.
4
4
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Niels de Vos <ndevos@redhat.com>
6
Message-Id: <20200214200812.28180-3-kwolf@redhat.com>
7
Reviewed-by: Ján Tomko <jtomko@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
9
---
8
block/gluster.c | 12 ++++++++++--
10
block/commit.c | 2 --
9
1 file changed, 10 insertions(+), 2 deletions(-)
11
1 file changed, 2 deletions(-)
10
12
11
diff --git a/block/gluster.c b/block/gluster.c
13
diff --git a/block/commit.c b/block/commit.c
12
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
13
--- a/block/gluster.c
15
--- a/block/commit.c
14
+++ b/block/gluster.c
16
+++ b/block/commit.c
15
@@ -XXX,XX +XXX,XX @@ static int qemu_gluster_open(BlockDriverState *bs, QDict *options,
17
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn commit_run(Job *job, Error **errp)
16
qemu_gluster_parse_flags(bdrv_flags, &open_flags);
18
int ret = 0;
17
19
int64_t n = 0; /* bytes */
18
s->fd = glfs_open(s->glfs, gconf->path, open_flags);
20
void *buf = NULL;
19
- if (!s->fd) {
21
- int bytes_written = 0;
20
- ret = -errno;
22
int64_t len, base_len;
21
+ ret = s->fd ? 0 : -errno;
23
22
+
24
ret = len = blk_getlength(s->top);
23
+ if (ret == -EACCES || ret == -EROFS) {
25
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn commit_run(Job *job, Error **errp)
24
+ /* Try to degrade to read-only, but if it doesn't work, still use the
26
trace_commit_one_iteration(s, offset, n, ret);
25
+ * normal error message. */
27
if (copy) {
26
+ if (bdrv_apply_auto_read_only(bs, NULL, NULL) == 0) {
28
ret = commit_populate(s->top, s->base, offset, n, buf);
27
+ open_flags = (open_flags & ~O_RDWR) | O_RDONLY;
29
- bytes_written += n;
28
+ s->fd = glfs_open(s->glfs, gconf->path, open_flags);
30
}
29
+ ret = s->fd ? 0 : -errno;
31
if (ret < 0) {
30
+ }
32
BlockErrorAction action =
31
}
32
33
s->supports_seek_data = qemu_gluster_test_seek(s->fd);
34
--
33
--
35
2.19.1
34
2.20.1
36
35
37
36
diff view generated by jsdifflib
1
Commit e2b8247a322 introduced an error path in qemu_rbd_open() after
1
The block_job_error_action() error call in the commit job gives the
2
calling rbd_open(), but neglected to close the image again in this error
2
on_err and is_read arguments in the wrong order. Fix this.
3
path. The error path should contain everything that the regular close
4
function qemu_rbd_close() contains.
5
3
6
This adds the missing rbd_close() call.
4
(Of course, hard-coded is_read = false is wrong, too, but that's a
5
separate problem for a separate patch.)
7
6
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Message-Id: <20200214200812.28180-4-kwolf@redhat.com>
9
Reviewed-by: Ján Tomko <jtomko@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
---
11
block/rbd.c | 1 +
12
block/commit.c | 2 +-
12
1 file changed, 1 insertion(+)
13
1 file changed, 1 insertion(+), 1 deletion(-)
13
14
14
diff --git a/block/rbd.c b/block/rbd.c
15
diff --git a/block/commit.c b/block/commit.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/block/rbd.c
17
--- a/block/commit.c
17
+++ b/block/rbd.c
18
+++ b/block/commit.c
18
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
19
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn commit_run(Job *job, Error **errp)
19
"automatically marking the image read-only.");
20
}
20
r = bdrv_set_read_only(bs, true, &local_err);
21
if (ret < 0) {
21
if (r < 0) {
22
BlockErrorAction action =
22
+ rbd_close(s->image);
23
- block_job_error_action(&s->common, false, s->on_error, -ret);
23
error_propagate(errp, local_err);
24
+ block_job_error_action(&s->common, s->on_error, false, -ret);
24
goto failed_open;
25
if (action == BLOCK_ERROR_ACTION_REPORT) {
25
}
26
goto out;
27
} else {
26
--
28
--
27
2.19.1
29
2.20.1
28
30
29
31
diff view generated by jsdifflib
1
If read-only=off, but auto-read-only=on is given, open the file
1
commit_populate() is a very short function and only called in a single
2
read-write if we have the permissions, but instead of erroring out for
2
place. Its return value doesn't tell us whether an error happened while
3
read-only files, just degrade to read-only.
3
reading or writing, which would be necessary for sending the right data
4
in the BLOCK_JOB_ERROR QMP event.
4
5
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
7
Message-Id: <20200214200812.28180-5-kwolf@redhat.com>
8
Reviewed-by: Ján Tomko <jtomko@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
10
---
8
block/file-posix.c | 19 ++++++++++++++++---
11
block/commit.c | 28 ++++++----------------------
9
1 file changed, 16 insertions(+), 3 deletions(-)
12
1 file changed, 6 insertions(+), 22 deletions(-)
10
13
11
diff --git a/block/file-posix.c b/block/file-posix.c
14
diff --git a/block/commit.c b/block/commit.c
12
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
13
--- a/block/file-posix.c
16
--- a/block/commit.c
14
+++ b/block/file-posix.c
17
+++ b/block/commit.c
15
@@ -XXX,XX +XXX,XX @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
18
@@ -XXX,XX +XXX,XX @@ typedef struct CommitBlockJob {
16
19
char *backing_file_str;
17
s->fd = -1;
20
} CommitBlockJob;
18
fd = qemu_open(filename, s->open_flags, 0644);
21
19
- if (fd < 0) {
22
-static int coroutine_fn commit_populate(BlockBackend *bs, BlockBackend *base,
20
- ret = -errno;
23
- int64_t offset, uint64_t bytes,
21
- error_setg_errno(errp, errno, "Could not open '%s'", filename);
24
- void *buf)
22
+ ret = fd < 0 ? -errno : 0;
25
-{
26
- int ret = 0;
27
-
28
- assert(bytes < SIZE_MAX);
29
-
30
- ret = blk_co_pread(bs, offset, bytes, buf, 0);
31
- if (ret < 0) {
32
- return ret;
33
- }
34
-
35
- ret = blk_co_pwrite(base, offset, bytes, buf, 0);
36
- if (ret < 0) {
37
- return ret;
38
- }
39
-
40
- return 0;
41
-}
42
-
43
static int commit_prepare(Job *job)
44
{
45
CommitBlockJob *s = container_of(job, CommitBlockJob, common.job);
46
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn commit_run(Job *job, Error **errp)
47
copy = (ret == 1);
48
trace_commit_one_iteration(s, offset, n, ret);
49
if (copy) {
50
- ret = commit_populate(s->top, s->base, offset, n, buf);
51
+ assert(n < SIZE_MAX);
23
+
52
+
24
+ if (ret == -EACCES || ret == -EROFS) {
53
+ ret = blk_co_pread(s->top, offset, n, buf, 0);
25
+ /* Try to degrade to read-only, but if it doesn't work, still use the
54
+ if (ret >= 0) {
26
+ * normal error message. */
55
+ ret = blk_co_pwrite(s->base, offset, n, buf, 0);
27
+ if (bdrv_apply_auto_read_only(bs, NULL, NULL) == 0) {
56
+ }
28
+ bdrv_flags &= ~BDRV_O_RDWR;
29
+ raw_parse_flags(bdrv_flags, &s->open_flags);
30
+ assert(!(s->open_flags & O_CREAT));
31
+ fd = qemu_open(filename, s->open_flags);
32
+ ret = fd < 0 ? -errno : 0;
33
+ }
34
+ }
35
+
36
+ if (ret < 0) {
37
+ error_setg_errno(errp, -ret, "Could not open '%s'", filename);
38
if (ret == -EROFS) {
39
ret = -EACCES;
40
}
57
}
58
if (ret < 0) {
59
BlockErrorAction action =
41
--
60
--
42
2.19.1
61
2.20.1
43
62
44
63
diff view generated by jsdifflib
1
If read-only=off, but auto-read-only=on is given, open a read-write NBD
1
block_job_error_action() needs to know if reading from the top node or
2
connection if the server provides a read-write export, but instead of
2
writing to the base node failed so that it can set the right 'operation'
3
erroring out for read-only exports, just degrade to read-only.
3
in the BLOCK_JOB_ERROR QMP event.
4
4
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
6
Message-Id: <20200214200812.28180-6-kwolf@redhat.com>
7
Reviewed-by: Ján Tomko <jtomko@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
9
---
8
block/nbd-client.c | 10 +++++-----
10
block/commit.c | 7 ++++++-
9
1 file changed, 5 insertions(+), 5 deletions(-)
11
1 file changed, 6 insertions(+), 1 deletion(-)
10
12
11
diff --git a/block/nbd-client.c b/block/nbd-client.c
13
diff --git a/block/commit.c b/block/commit.c
12
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
13
--- a/block/nbd-client.c
15
--- a/block/commit.c
14
+++ b/block/nbd-client.c
16
+++ b/block/commit.c
15
@@ -XXX,XX +XXX,XX @@ int nbd_client_init(BlockDriverState *bs,
17
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn commit_run(Job *job, Error **errp)
16
logout("Failed to negotiate with the NBD server\n");
18
17
return ret;
19
for (offset = 0; offset < len; offset += n) {
18
}
20
bool copy;
19
- if (client->info.flags & NBD_FLAG_READ_ONLY &&
21
+ bool error_in_source = true;
20
- !bdrv_is_read_only(bs)) {
22
21
- error_setg(errp,
23
/* Note that even when no rate limit is applied we need to yield
22
- "request for write access conflicts with read-only export");
24
* with no pending I/O here so that bdrv_drain_all() returns.
23
- return -EACCES;
25
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn commit_run(Job *job, Error **errp)
24
+ if (client->info.flags & NBD_FLAG_READ_ONLY) {
26
ret = blk_co_pread(s->top, offset, n, buf, 0);
25
+ ret = bdrv_apply_auto_read_only(bs, "NBD export is read-only", errp);
27
if (ret >= 0) {
26
+ if (ret < 0) {
28
ret = blk_co_pwrite(s->base, offset, n, buf, 0);
27
+ return ret;
29
+ if (ret < 0) {
28
+ }
30
+ error_in_source = false;
29
}
31
+ }
30
if (client->info.flags & NBD_FLAG_SEND_FUA) {
32
}
31
bs->supported_write_flags = BDRV_REQ_FUA;
33
}
34
if (ret < 0) {
35
BlockErrorAction action =
36
- block_job_error_action(&s->common, s->on_error, false, -ret);
37
+ block_job_error_action(&s->common, s->on_error,
38
+ error_in_source, -ret);
39
if (action == BLOCK_ERROR_ACTION_REPORT) {
40
goto out;
41
} else {
32
--
42
--
33
2.19.1
43
2.20.1
34
44
35
45
diff view generated by jsdifflib
1
If a management application builds the block graph node by node, the
1
Now that the error handling in the common block job is fixed, we can
2
protocol layer doesn't inherit its read-only option from the format
2
expose the on-error option in QMP instead of hard-coding it as 'report'
3
layer any more, so it must be set explicitly.
3
in qmp_block_commit().
4
4
5
Backing files should work on read-only storage, but at the same time, a
5
This fulfills the promise that the old comment in that function made,
6
block job like commit should be able to reopen them read-write if they
6
even if a bit later than expected: "This will be part of the QMP
7
are on read-write storage. However, without option inheritance, reopen
7
command, if/when the BlockdevOnError change for blkmirror makes it in".
8
only changes the read-only option for the root node (typically the
9
format layer), but not the protocol layer, so reopening fails (the
10
format layer wants to get write permissions, but the protocol layer is
11
still read-only).
12
13
A simple workaround for the problem in the management tool would be to
14
open the protocol layer always read-write and to make only the format
15
layer read-only for backing files. However, sometimes the file is
16
actually stored on read-only storage and we don't know whether the image
17
can be opened read-write (for example, for NBD it depends on the server
18
we're trying to connect to). This adds an option that makes QEMU try to
19
open the image read-write, but allows it to degrade to a read-only mode
20
without returning an error.
21
22
The documentation for this option is consciously phrased in a way that
23
allows QEMU to switch to a better model eventually: Instead of trying
24
when the image is first opened, making the read-only flag dynamic and
25
changing it automatically whenever the first BLK_PERM_WRITE user is
26
attached or the last one is detached would be much more useful
27
behaviour.
28
29
Unfortunately, this more useful behaviour is also a lot harder to
30
implement, and libvirt needs a solution now before it can switch to
31
-blockdev, so let's start with this easier approach for now.
32
33
Instead of adding a new auto-read-only option, turning the existing
34
read-only into an enum (with a bool alternate for compatibility) was
35
considered, but it complicated the implementation to the point that it
36
didn't seem to be worth it.
37
8
38
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
39
Reviewed-by: Eric Blake <eblake@redhat.com>
10
Message-Id: <20200214200812.28180-7-kwolf@redhat.com>
11
Reviewed-by: Ján Tomko <jtomko@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
40
---
13
---
41
qapi/block-core.json | 7 +++++++
14
qapi/block-core.json | 4 ++++
42
include/block/block.h | 2 ++
15
blockdev.c | 8 ++++----
43
block.c | 17 +++++++++++++++++
16
2 files changed, 8 insertions(+), 4 deletions(-)
44
block/vvfat.c | 1 +
45
blockdev.c | 2 +-
46
5 files changed, 28 insertions(+), 1 deletion(-)
47
17
48
diff --git a/qapi/block-core.json b/qapi/block-core.json
18
diff --git a/qapi/block-core.json b/qapi/block-core.json
49
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
50
--- a/qapi/block-core.json
20
--- a/qapi/block-core.json
51
+++ b/qapi/block-core.json
21
+++ b/qapi/block-core.json
52
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@
53
# either generally or in certain configurations. In this case,
23
#
54
# the default value does not work and the option must be
24
# @speed: the maximum speed, in bytes per second
55
# specified explicitly.
25
#
56
+# @auto-read-only: if true and @read-only is false, QEMU may automatically
26
+# @on-error: the action to take on an error. 'ignore' means that the request
57
+# decide not to open the image read-write as requested, but
27
+# should be retried. (default: report; Since: 5.0)
58
+# fall back to read-only instead (and switch between the modes
28
+#
59
+# later), e.g. depending on whether the image file is writable
29
# @filter-node-name: the node name that should be assigned to the
60
+# or whether a writing user is attached to the node
30
# filter driver that the commit job inserts into the graph
61
+# (default: false, since 3.1)
31
# above @top. If this option is not given, a node name is
62
# @detect-zeroes: detect and optimize zero writes (Since 2.1)
63
# (default: off)
64
# @force-share: force share all permission on added nodes.
65
@@ -XXX,XX +XXX,XX @@
32
@@ -XXX,XX +XXX,XX @@
66
'*discard': 'BlockdevDiscardOptions',
33
'data': { '*job-id': 'str', 'device': 'str', '*base-node': 'str',
67
'*cache': 'BlockdevCacheOptions',
34
'*base': 'str', '*top-node': 'str', '*top': 'str',
68
'*read-only': 'bool',
35
'*backing-file': 'str', '*speed': 'int',
69
+ '*auto-read-only': 'bool',
36
+ '*on-error': 'BlockdevOnError',
70
'*force-share': 'bool',
37
'*filter-node-name': 'str',
71
'*detect-zeroes': 'BlockdevDetectZeroesOptions' },
38
'*auto-finalize': 'bool', '*auto-dismiss': 'bool' } }
72
'discriminator': 'driver',
73
diff --git a/include/block/block.h b/include/block/block.h
74
index XXXXXXX..XXXXXXX 100644
75
--- a/include/block/block.h
76
+++ b/include/block/block.h
77
@@ -XXX,XX +XXX,XX @@ typedef struct HDGeometry {
78
select an appropriate protocol driver,
79
ignoring the format layer */
80
#define BDRV_O_NO_IO 0x10000 /* don't initialize for I/O */
81
+#define BDRV_O_AUTO_RDONLY 0x20000 /* degrade to read-only if opening read-write fails */
82
83
#define BDRV_O_CACHE_MASK (BDRV_O_NOCACHE | BDRV_O_NO_FLUSH)
84
85
@@ -XXX,XX +XXX,XX @@ typedef struct HDGeometry {
86
#define BDRV_OPT_CACHE_DIRECT "cache.direct"
87
#define BDRV_OPT_CACHE_NO_FLUSH "cache.no-flush"
88
#define BDRV_OPT_READ_ONLY "read-only"
89
+#define BDRV_OPT_AUTO_READ_ONLY "auto-read-only"
90
#define BDRV_OPT_DISCARD "discard"
91
#define BDRV_OPT_FORCE_SHARE "force-share"
92
93
diff --git a/block.c b/block.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/block.c
96
+++ b/block.c
97
@@ -XXX,XX +XXX,XX @@ static void bdrv_inherited_options(int *child_flags, QDict *child_options,
98
99
/* Inherit the read-only option from the parent if it's not set */
100
qdict_copy_default(child_options, parent_options, BDRV_OPT_READ_ONLY);
101
+ qdict_copy_default(child_options, parent_options, BDRV_OPT_AUTO_READ_ONLY);
102
103
/* Our block drivers take care to send flushes and respect unmap policy,
104
* so we can default to enable both on lower layers regardless of the
105
@@ -XXX,XX +XXX,XX @@ static void bdrv_backing_options(int *child_flags, QDict *child_options,
106
107
/* backing files always opened read-only */
108
qdict_set_default_str(child_options, BDRV_OPT_READ_ONLY, "on");
109
+ qdict_set_default_str(child_options, BDRV_OPT_AUTO_READ_ONLY, "off");
110
flags &= ~BDRV_O_COPY_ON_READ;
111
112
/* snapshot=on is handled on the top layer */
113
@@ -XXX,XX +XXX,XX @@ static void update_flags_from_options(int *flags, QemuOpts *opts)
114
*flags |= BDRV_O_RDWR;
115
}
116
117
+ assert(qemu_opt_find(opts, BDRV_OPT_AUTO_READ_ONLY));
118
+ if (qemu_opt_get_bool_del(opts, BDRV_OPT_AUTO_READ_ONLY, false)) {
119
+ *flags |= BDRV_O_AUTO_RDONLY;
120
+ }
121
}
122
123
static void update_options_from_flags(QDict *options, int flags)
124
@@ -XXX,XX +XXX,XX @@ static void update_options_from_flags(QDict *options, int flags)
125
if (!qdict_haskey(options, BDRV_OPT_READ_ONLY)) {
126
qdict_put_bool(options, BDRV_OPT_READ_ONLY, !(flags & BDRV_O_RDWR));
127
}
128
+ if (!qdict_haskey(options, BDRV_OPT_AUTO_READ_ONLY)) {
129
+ qdict_put_bool(options, BDRV_OPT_AUTO_READ_ONLY,
130
+ flags & BDRV_O_AUTO_RDONLY);
131
+ }
132
}
133
134
static void bdrv_assign_node_name(BlockDriverState *bs,
135
@@ -XXX,XX +XXX,XX @@ QemuOptsList bdrv_runtime_opts = {
136
.type = QEMU_OPT_BOOL,
137
.help = "Node is opened in read-only mode",
138
},
139
+ {
140
+ .name = BDRV_OPT_AUTO_READ_ONLY,
141
+ .type = QEMU_OPT_BOOL,
142
+ .help = "Node can become read-only if opening read-write fails",
143
+ },
144
{
145
.name = "detect-zeroes",
146
.type = QEMU_OPT_STRING,
147
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp)
148
qdict_set_default_str(qdict, BDRV_OPT_CACHE_DIRECT, "off");
149
qdict_set_default_str(qdict, BDRV_OPT_CACHE_NO_FLUSH, "off");
150
qdict_set_default_str(qdict, BDRV_OPT_READ_ONLY, "off");
151
+ qdict_set_default_str(qdict, BDRV_OPT_AUTO_READ_ONLY, "off");
152
+
153
}
154
155
bs = bdrv_open_inherit(NULL, reference, qdict, 0, NULL, NULL, errp);
156
diff --git a/block/vvfat.c b/block/vvfat.c
157
index XXXXXXX..XXXXXXX 100644
158
--- a/block/vvfat.c
159
+++ b/block/vvfat.c
160
@@ -XXX,XX +XXX,XX @@ static void vvfat_qcow_options(int *child_flags, QDict *child_options,
161
int parent_flags, QDict *parent_options)
162
{
163
qdict_set_default_str(child_options, BDRV_OPT_READ_ONLY, "off");
164
+ qdict_set_default_str(child_options, BDRV_OPT_AUTO_READ_ONLY, "off");
165
qdict_set_default_str(child_options, BDRV_OPT_CACHE_NO_FLUSH, "on");
166
}
167
39
168
diff --git a/blockdev.c b/blockdev.c
40
diff --git a/blockdev.c b/blockdev.c
169
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
170
--- a/blockdev.c
42
--- a/blockdev.c
171
+++ b/blockdev.c
43
+++ b/blockdev.c
172
@@ -XXX,XX +XXX,XX @@ void qmp_blockdev_change_medium(bool has_device, const char *device,
44
@@ -XXX,XX +XXX,XX @@ void qmp_block_commit(bool has_job_id, const char *job_id, const char *device,
173
45
bool has_top, const char *top,
174
bdrv_flags = blk_get_open_flags_from_root_state(blk);
46
bool has_backing_file, const char *backing_file,
175
bdrv_flags &= ~(BDRV_O_TEMPORARY | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING |
47
bool has_speed, int64_t speed,
176
- BDRV_O_PROTOCOL);
48
+ bool has_on_error, BlockdevOnError on_error,
177
+ BDRV_O_PROTOCOL | BDRV_O_AUTO_RDONLY);
49
bool has_filter_node_name, const char *filter_node_name,
178
50
bool has_auto_finalize, bool auto_finalize,
179
if (!has_read_only) {
51
bool has_auto_dismiss, bool auto_dismiss,
180
read_only = BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN;
52
@@ -XXX,XX +XXX,XX @@ void qmp_block_commit(bool has_job_id, const char *job_id, const char *device,
53
BlockDriverState *base_bs, *top_bs;
54
AioContext *aio_context;
55
Error *local_err = NULL;
56
- /* This will be part of the QMP command, if/when the
57
- * BlockdevOnError change for blkmirror makes it in
58
- */
59
- BlockdevOnError on_error = BLOCKDEV_ON_ERROR_REPORT;
60
int job_flags = JOB_DEFAULT;
61
62
if (!has_speed) {
63
speed = 0;
64
}
65
+ if (!has_on_error) {
66
+ on_error = BLOCKDEV_ON_ERROR_REPORT;
67
+ }
68
if (!has_filter_node_name) {
69
filter_node_name = NULL;
70
}
181
--
71
--
182
2.19.1
72
2.20.1
183
73
184
74
diff view generated by jsdifflib
1
From: Peter Maydell <peter.maydell@linaro.org>
1
This tests both read failure (from the top node) and write failure (to
2
2
the base node) for on-error=report/stop/ignore.
3
Taking the address of a field in a packed struct is a bad idea, because
3
4
it might not be actually aligned enough for that pointer type (and
4
As block-commit actually starts two different types of block jobs
5
thus cause a crash on dereference on some host architectures). Newer
5
(mirror.c for committing the active later, commit.c for intermediate
6
versions of clang warn about this. Avoid the bug by not using the
6
layers), all tests are run for both cases.
7
"modify in place" byte swapping functions.
7
8
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
There are a few places where the in-place swap function is
9
Message-Id: <20200214200812.28180-8-kwolf@redhat.com>
10
used on something other than a packed struct field; we convert
11
those anyway, for consistency.
12
13
Patch produced with scripts/coccinelle/inplace-byteswaps.cocci.
14
15
There are other places where we take the address of a packed member
16
in this file for other purposes than passing it to a byteswap
17
function (all the calls to qemu_uuid_*()); we leave those for now.
18
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
---
11
---
23
block/vdi.c | 64 ++++++++++++++++++++++++++---------------------------
12
tests/qemu-iotests/040 | 283 +++++++++++++++++++++++++++++++++++++
24
1 file changed, 32 insertions(+), 32 deletions(-)
13
tests/qemu-iotests/040.out | 4 +-
25
14
2 files changed, 285 insertions(+), 2 deletions(-)
26
diff --git a/block/vdi.c b/block/vdi.c
15
16
diff --git a/tests/qemu-iotests/040 b/tests/qemu-iotests/040
17
index XXXXXXX..XXXXXXX 100755
18
--- a/tests/qemu-iotests/040
19
+++ b/tests/qemu-iotests/040
20
@@ -XXX,XX +XXX,XX @@ class TestReopenOverlay(ImageCommitTestCase):
21
def test_reopen_overlay(self):
22
self.run_commit_test(self.img1, self.img0)
23
24
+class TestErrorHandling(iotests.QMPTestCase):
25
+ image_len = 2 * 1024 * 1024
26
+
27
+ def setUp(self):
28
+ iotests.create_image(backing_img, self.image_len)
29
+ qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, mid_img)
30
+ qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % mid_img, test_img)
31
+
32
+ qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0x11 0 512k', mid_img)
33
+ qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0x22 0 512k', test_img)
34
+
35
+ self.vm = iotests.VM()
36
+ self.vm.launch()
37
+
38
+ self.blkdebug_file = iotests.file_path("blkdebug.conf")
39
+
40
+ def tearDown(self):
41
+ self.vm.shutdown()
42
+ os.remove(test_img)
43
+ os.remove(mid_img)
44
+ os.remove(backing_img)
45
+
46
+ def blockdev_add(self, **kwargs):
47
+ result = self.vm.qmp('blockdev-add', **kwargs)
48
+ self.assert_qmp(result, 'return', {})
49
+
50
+ def add_block_nodes(self, base_debug=None, mid_debug=None, top_debug=None):
51
+ self.blockdev_add(node_name='base-file', driver='file',
52
+ filename=backing_img)
53
+ self.blockdev_add(node_name='mid-file', driver='file',
54
+ filename=mid_img)
55
+ self.blockdev_add(node_name='top-file', driver='file',
56
+ filename=test_img)
57
+
58
+ if base_debug:
59
+ self.blockdev_add(node_name='base-dbg', driver='blkdebug',
60
+ image='base-file', inject_error=base_debug)
61
+ if mid_debug:
62
+ self.blockdev_add(node_name='mid-dbg', driver='blkdebug',
63
+ image='mid-file', inject_error=mid_debug)
64
+ if top_debug:
65
+ self.blockdev_add(node_name='top-dbg', driver='blkdebug',
66
+ image='top-file', inject_error=top_debug)
67
+
68
+ self.blockdev_add(node_name='base-fmt', driver='raw',
69
+ file=('base-dbg' if base_debug else 'base-file'))
70
+ self.blockdev_add(node_name='mid-fmt', driver=iotests.imgfmt,
71
+ file=('mid-dbg' if mid_debug else 'mid-file'),
72
+ backing='base-fmt')
73
+ self.blockdev_add(node_name='top-fmt', driver=iotests.imgfmt,
74
+ file=('top-dbg' if top_debug else 'top-file'),
75
+ backing='mid-fmt')
76
+
77
+ def run_job(self, expected_events, error_pauses_job=False):
78
+ match_device = {'data': {'device': 'job0'}}
79
+ events = [
80
+ ('BLOCK_JOB_COMPLETED', match_device),
81
+ ('BLOCK_JOB_CANCELLED', match_device),
82
+ ('BLOCK_JOB_ERROR', match_device),
83
+ ('BLOCK_JOB_READY', match_device),
84
+ ]
85
+
86
+ completed = False
87
+ log = []
88
+ while not completed:
89
+ ev = self.vm.events_wait(events, timeout=5.0)
90
+ if ev['event'] == 'BLOCK_JOB_COMPLETED':
91
+ completed = True
92
+ elif ev['event'] == 'BLOCK_JOB_ERROR':
93
+ if error_pauses_job:
94
+ result = self.vm.qmp('block-job-resume', device='job0')
95
+ self.assert_qmp(result, 'return', {})
96
+ elif ev['event'] == 'BLOCK_JOB_READY':
97
+ result = self.vm.qmp('block-job-complete', device='job0')
98
+ self.assert_qmp(result, 'return', {})
99
+ else:
100
+ self.fail("Unexpected event: %s" % ev)
101
+ log.append(iotests.filter_qmp_event(ev))
102
+
103
+ self.maxDiff = None
104
+ self.assertEqual(expected_events, log)
105
+
106
+ def event_error(self, op, action):
107
+ return {
108
+ 'event': 'BLOCK_JOB_ERROR',
109
+ 'data': {'action': action, 'device': 'job0', 'operation': op},
110
+ 'timestamp': {'microseconds': 'USECS', 'seconds': 'SECS'}
111
+ }
112
+
113
+ def event_ready(self):
114
+ return {
115
+ 'event': 'BLOCK_JOB_READY',
116
+ 'data': {'device': 'job0',
117
+ 'len': 524288,
118
+ 'offset': 524288,
119
+ 'speed': 0,
120
+ 'type': 'commit'},
121
+ 'timestamp': {'microseconds': 'USECS', 'seconds': 'SECS'},
122
+ }
123
+
124
+ def event_completed(self, errmsg=None, active=True):
125
+ max_len = 524288 if active else self.image_len
126
+ data = {
127
+ 'device': 'job0',
128
+ 'len': max_len,
129
+ 'offset': 0 if errmsg else max_len,
130
+ 'speed': 0,
131
+ 'type': 'commit'
132
+ }
133
+ if errmsg:
134
+ data['error'] = errmsg
135
+
136
+ return {
137
+ 'event': 'BLOCK_JOB_COMPLETED',
138
+ 'data': data,
139
+ 'timestamp': {'microseconds': 'USECS', 'seconds': 'SECS'},
140
+ }
141
+
142
+ def blkdebug_event(self, event, is_raw=False):
143
+ if event:
144
+ return [{
145
+ 'event': event,
146
+ 'sector': 512 if is_raw else 1024,
147
+ 'once': True,
148
+ }]
149
+ return None
150
+
151
+ def prepare_and_start_job(self, on_error, active=True,
152
+ top_event=None, mid_event=None, base_event=None):
153
+
154
+ top_debug = self.blkdebug_event(top_event)
155
+ mid_debug = self.blkdebug_event(mid_event)
156
+ base_debug = self.blkdebug_event(base_event, True)
157
+
158
+ self.add_block_nodes(top_debug=top_debug, mid_debug=mid_debug,
159
+ base_debug=base_debug)
160
+
161
+ result = self.vm.qmp('block-commit', job_id='job0', device='top-fmt',
162
+ top_node='top-fmt' if active else 'mid-fmt',
163
+ base_node='mid-fmt' if active else 'base-fmt',
164
+ on_error=on_error)
165
+ self.assert_qmp(result, 'return', {})
166
+
167
+ def testActiveReadErrorReport(self):
168
+ self.prepare_and_start_job('report', top_event='read_aio')
169
+ self.run_job([
170
+ self.event_error('read', 'report'),
171
+ self.event_completed('Input/output error')
172
+ ])
173
+
174
+ self.vm.shutdown()
175
+ self.assertFalse(iotests.compare_images(test_img, mid_img),
176
+ 'target image matches source after error')
177
+
178
+ def testActiveReadErrorStop(self):
179
+ self.prepare_and_start_job('stop', top_event='read_aio')
180
+ self.run_job([
181
+ self.event_error('read', 'stop'),
182
+ self.event_ready(),
183
+ self.event_completed()
184
+ ], error_pauses_job=True)
185
+
186
+ self.vm.shutdown()
187
+ self.assertTrue(iotests.compare_images(test_img, mid_img),
188
+ 'target image does not match source after commit')
189
+
190
+ def testActiveReadErrorIgnore(self):
191
+ self.prepare_and_start_job('ignore', top_event='read_aio')
192
+ self.run_job([
193
+ self.event_error('read', 'ignore'),
194
+ self.event_ready(),
195
+ self.event_completed()
196
+ ])
197
+
198
+ # For commit, 'ignore' actually means retry, so this will succeed
199
+ self.vm.shutdown()
200
+ self.assertTrue(iotests.compare_images(test_img, mid_img),
201
+ 'target image does not match source after commit')
202
+
203
+ def testActiveWriteErrorReport(self):
204
+ self.prepare_and_start_job('report', mid_event='write_aio')
205
+ self.run_job([
206
+ self.event_error('write', 'report'),
207
+ self.event_completed('Input/output error')
208
+ ])
209
+
210
+ self.vm.shutdown()
211
+ self.assertFalse(iotests.compare_images(test_img, mid_img),
212
+ 'target image matches source after error')
213
+
214
+ def testActiveWriteErrorStop(self):
215
+ self.prepare_and_start_job('stop', mid_event='write_aio')
216
+ self.run_job([
217
+ self.event_error('write', 'stop'),
218
+ self.event_ready(),
219
+ self.event_completed()
220
+ ], error_pauses_job=True)
221
+
222
+ self.vm.shutdown()
223
+ self.assertTrue(iotests.compare_images(test_img, mid_img),
224
+ 'target image does not match source after commit')
225
+
226
+ def testActiveWriteErrorIgnore(self):
227
+ self.prepare_and_start_job('ignore', mid_event='write_aio')
228
+ self.run_job([
229
+ self.event_error('write', 'ignore'),
230
+ self.event_ready(),
231
+ self.event_completed()
232
+ ])
233
+
234
+ # For commit, 'ignore' actually means retry, so this will succeed
235
+ self.vm.shutdown()
236
+ self.assertTrue(iotests.compare_images(test_img, mid_img),
237
+ 'target image does not match source after commit')
238
+
239
+ def testIntermediateReadErrorReport(self):
240
+ self.prepare_and_start_job('report', active=False, mid_event='read_aio')
241
+ self.run_job([
242
+ self.event_error('read', 'report'),
243
+ self.event_completed('Input/output error', active=False)
244
+ ])
245
+
246
+ self.vm.shutdown()
247
+ self.assertFalse(iotests.compare_images(mid_img, backing_img, fmt2='raw'),
248
+ 'target image matches source after error')
249
+
250
+ def testIntermediateReadErrorStop(self):
251
+ self.prepare_and_start_job('stop', active=False, mid_event='read_aio')
252
+ self.run_job([
253
+ self.event_error('read', 'stop'),
254
+ self.event_completed(active=False)
255
+ ], error_pauses_job=True)
256
+
257
+ self.vm.shutdown()
258
+ self.assertTrue(iotests.compare_images(mid_img, backing_img, fmt2='raw'),
259
+ 'target image does not match source after commit')
260
+
261
+ def testIntermediateReadErrorIgnore(self):
262
+ self.prepare_and_start_job('ignore', active=False, mid_event='read_aio')
263
+ self.run_job([
264
+ self.event_error('read', 'ignore'),
265
+ self.event_completed(active=False)
266
+ ])
267
+
268
+ # For commit, 'ignore' actually means retry, so this will succeed
269
+ self.vm.shutdown()
270
+ self.assertTrue(iotests.compare_images(mid_img, backing_img, fmt2='raw'),
271
+ 'target image does not match source after commit')
272
+
273
+ def testIntermediateWriteErrorReport(self):
274
+ self.prepare_and_start_job('report', active=False, base_event='write_aio')
275
+ self.run_job([
276
+ self.event_error('write', 'report'),
277
+ self.event_completed('Input/output error', active=False)
278
+ ])
279
+
280
+ self.vm.shutdown()
281
+ self.assertFalse(iotests.compare_images(mid_img, backing_img, fmt2='raw'),
282
+ 'target image matches source after error')
283
+
284
+ def testIntermediateWriteErrorStop(self):
285
+ self.prepare_and_start_job('stop', active=False, base_event='write_aio')
286
+ self.run_job([
287
+ self.event_error('write', 'stop'),
288
+ self.event_completed(active=False)
289
+ ], error_pauses_job=True)
290
+
291
+ self.vm.shutdown()
292
+ self.assertTrue(iotests.compare_images(mid_img, backing_img, fmt2='raw'),
293
+ 'target image does not match source after commit')
294
+
295
+ def testIntermediateWriteErrorIgnore(self):
296
+ self.prepare_and_start_job('ignore', active=False, base_event='write_aio')
297
+ self.run_job([
298
+ self.event_error('write', 'ignore'),
299
+ self.event_completed(active=False)
300
+ ])
301
+
302
+ # For commit, 'ignore' actually means retry, so this will succeed
303
+ self.vm.shutdown()
304
+ self.assertTrue(iotests.compare_images(mid_img, backing_img, fmt2='raw'),
305
+ 'target image does not match source after commit')
306
+
307
if __name__ == '__main__':
308
iotests.main(supported_fmts=['qcow2', 'qed'],
309
supported_protocols=['file'])
310
diff --git a/tests/qemu-iotests/040.out b/tests/qemu-iotests/040.out
27
index XXXXXXX..XXXXXXX 100644
311
index XXXXXXX..XXXXXXX 100644
28
--- a/block/vdi.c
312
--- a/tests/qemu-iotests/040.out
29
+++ b/block/vdi.c
313
+++ b/tests/qemu-iotests/040.out
30
@@ -XXX,XX +XXX,XX @@ typedef struct {
314
@@ -XXX,XX +XXX,XX @@
31
315
-...............................................
32
static void vdi_header_to_cpu(VdiHeader *header)
316
+...........................................................
33
{
317
----------------------------------------------------------------------
34
- le32_to_cpus(&header->signature);
318
-Ran 47 tests
35
- le32_to_cpus(&header->version);
319
+Ran 59 tests
36
- le32_to_cpus(&header->header_size);
320
37
- le32_to_cpus(&header->image_type);
321
OK
38
- le32_to_cpus(&header->image_flags);
39
- le32_to_cpus(&header->offset_bmap);
40
- le32_to_cpus(&header->offset_data);
41
- le32_to_cpus(&header->cylinders);
42
- le32_to_cpus(&header->heads);
43
- le32_to_cpus(&header->sectors);
44
- le32_to_cpus(&header->sector_size);
45
- le64_to_cpus(&header->disk_size);
46
- le32_to_cpus(&header->block_size);
47
- le32_to_cpus(&header->block_extra);
48
- le32_to_cpus(&header->blocks_in_image);
49
- le32_to_cpus(&header->blocks_allocated);
50
+ header->signature = le32_to_cpu(header->signature);
51
+ header->version = le32_to_cpu(header->version);
52
+ header->header_size = le32_to_cpu(header->header_size);
53
+ header->image_type = le32_to_cpu(header->image_type);
54
+ header->image_flags = le32_to_cpu(header->image_flags);
55
+ header->offset_bmap = le32_to_cpu(header->offset_bmap);
56
+ header->offset_data = le32_to_cpu(header->offset_data);
57
+ header->cylinders = le32_to_cpu(header->cylinders);
58
+ header->heads = le32_to_cpu(header->heads);
59
+ header->sectors = le32_to_cpu(header->sectors);
60
+ header->sector_size = le32_to_cpu(header->sector_size);
61
+ header->disk_size = le64_to_cpu(header->disk_size);
62
+ header->block_size = le32_to_cpu(header->block_size);
63
+ header->block_extra = le32_to_cpu(header->block_extra);
64
+ header->blocks_in_image = le32_to_cpu(header->blocks_in_image);
65
+ header->blocks_allocated = le32_to_cpu(header->blocks_allocated);
66
qemu_uuid_bswap(&header->uuid_image);
67
qemu_uuid_bswap(&header->uuid_last_snap);
68
qemu_uuid_bswap(&header->uuid_link);
69
@@ -XXX,XX +XXX,XX @@ static void vdi_header_to_cpu(VdiHeader *header)
70
71
static void vdi_header_to_le(VdiHeader *header)
72
{
73
- cpu_to_le32s(&header->signature);
74
- cpu_to_le32s(&header->version);
75
- cpu_to_le32s(&header->header_size);
76
- cpu_to_le32s(&header->image_type);
77
- cpu_to_le32s(&header->image_flags);
78
- cpu_to_le32s(&header->offset_bmap);
79
- cpu_to_le32s(&header->offset_data);
80
- cpu_to_le32s(&header->cylinders);
81
- cpu_to_le32s(&header->heads);
82
- cpu_to_le32s(&header->sectors);
83
- cpu_to_le32s(&header->sector_size);
84
- cpu_to_le64s(&header->disk_size);
85
- cpu_to_le32s(&header->block_size);
86
- cpu_to_le32s(&header->block_extra);
87
- cpu_to_le32s(&header->blocks_in_image);
88
- cpu_to_le32s(&header->blocks_allocated);
89
+ header->signature = cpu_to_le32(header->signature);
90
+ header->version = cpu_to_le32(header->version);
91
+ header->header_size = cpu_to_le32(header->header_size);
92
+ header->image_type = cpu_to_le32(header->image_type);
93
+ header->image_flags = cpu_to_le32(header->image_flags);
94
+ header->offset_bmap = cpu_to_le32(header->offset_bmap);
95
+ header->offset_data = cpu_to_le32(header->offset_data);
96
+ header->cylinders = cpu_to_le32(header->cylinders);
97
+ header->heads = cpu_to_le32(header->heads);
98
+ header->sectors = cpu_to_le32(header->sectors);
99
+ header->sector_size = cpu_to_le32(header->sector_size);
100
+ header->disk_size = cpu_to_le64(header->disk_size);
101
+ header->block_size = cpu_to_le32(header->block_size);
102
+ header->block_extra = cpu_to_le32(header->block_extra);
103
+ header->blocks_in_image = cpu_to_le32(header->blocks_in_image);
104
+ header->blocks_allocated = cpu_to_le32(header->blocks_allocated);
105
qemu_uuid_bswap(&header->uuid_image);
106
qemu_uuid_bswap(&header->uuid_last_snap);
107
qemu_uuid_bswap(&header->uuid_link);
108
--
322
--
109
2.19.1
323
2.20.1
110
324
111
325
diff view generated by jsdifflib
1
From: Stefan Weil <sw@weilnetz.de>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Use %zu instead of %zd for unsigned numbers.
3
Fixes: 132ada80c4a
4
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
This fixes two error messages from the LSTM static code analyzer:
5
Message-Id: <20200218094402.26625-4-philmd@redhat.com>
6
7
This argument should be of type 'ssize_t' but is of type 'unsigned long'
8
9
Signed-off-by: Stefan Weil <sw@weilnetz.de>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
7
---
13
qemu-io-cmds.c | 4 ++--
8
block.c | 4 ++--
14
1 file changed, 2 insertions(+), 2 deletions(-)
9
1 file changed, 2 insertions(+), 2 deletions(-)
15
10
16
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
11
diff --git a/block.c b/block.c
17
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
18
--- a/qemu-io-cmds.c
13
--- a/block.c
19
+++ b/qemu-io-cmds.c
14
+++ b/block.c
20
@@ -XXX,XX +XXX,XX @@ static int readv_f(BlockBackend *blk, int argc, char **argv)
15
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
21
memset(cmp_buf, pattern, qiov.size);
16
if (bdrv_get_aio_context(child_bs) != ctx) {
22
if (memcmp(buf, cmp_buf, qiov.size)) {
17
ret = bdrv_try_set_aio_context(child_bs, ctx, &local_err);
23
printf("Pattern verification failed at offset %"
18
if (ret < 0 && child_role->can_set_aio_ctx) {
24
- PRId64 ", %zd bytes\n", offset, qiov.size);
19
- GSList *ignore = g_slist_prepend(NULL, child);;
25
+ PRId64 ", %zu bytes\n", offset, qiov.size);
20
+ GSList *ignore = g_slist_prepend(NULL, child);
26
ret = -EINVAL;
21
ctx = bdrv_get_aio_context(child_bs);
27
}
22
if (child_role->can_set_aio_ctx(child, ctx, &ignore, NULL)) {
28
g_free(cmp_buf);
23
error_free(local_err);
29
@@ -XXX,XX +XXX,XX @@ static void aio_read_done(void *opaque, int ret)
24
ret = 0;
30
memset(cmp_buf, ctx->pattern, ctx->qiov.size);
25
g_slist_free(ignore);
31
if (memcmp(ctx->buf, cmp_buf, ctx->qiov.size)) {
26
- ignore = g_slist_prepend(NULL, child);;
32
printf("Pattern verification failed at offset %"
27
+ ignore = g_slist_prepend(NULL, child);
33
- PRId64 ", %zd bytes\n", ctx->offset, ctx->qiov.size);
28
child_role->set_aio_ctx(child, ctx, &ignore);
34
+ PRId64 ", %zu bytes\n", ctx->offset, ctx->qiov.size);
29
}
35
}
30
g_slist_free(ignore);
36
g_free(cmp_buf);
37
}
38
--
31
--
39
2.19.1
32
2.20.1
40
33
41
34
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
3
Fixes: 6663a0a3376
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Message-Id: <20200218094402.26625-5-philmd@redhat.com>
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2
Reviewed-by: Alberto Garcia <berto@igalia.com>
3
---
7
---
4
block/vpc.c | 2 ++
8
block/io_uring.c | 2 +-
5
1 file changed, 2 insertions(+)
9
1 file changed, 1 insertion(+), 1 deletion(-)
6
10
7
diff --git a/block/vpc.c b/block/vpc.c
11
diff --git a/block/io_uring.c b/block/io_uring.c
8
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
9
--- a/block/vpc.c
13
--- a/block/io_uring.c
10
+++ b/block/vpc.c
14
+++ b/block/io_uring.c
11
@@ -XXX,XX +XXX,XX @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
15
@@ -XXX,XX +XXX,XX @@ static void luring_process_completions(LuringState *s)
12
}
16
ret = 0;
13
17
}
14
qemu_co_mutex_init(&s->lock);
18
} else {
15
+ qemu_opts_del(opts);
19
- ret = -ENOSPC;;
16
20
+ ret = -ENOSPC;
17
return 0;
21
}
18
22
}
19
fail:
23
end:
20
+ qemu_opts_del(opts);
21
qemu_vfree(s->pagetable);
22
#ifdef CACHE
23
g_free(s->pageentry_u8);
24
--
24
--
25
2.19.1
25
2.20.1
26
26
27
27
diff view generated by jsdifflib
1
From: Peter Maydell <peter.maydell@linaro.org>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
Taking the address of a field in a packed struct is a bad idea, because
3
There is no good reason why we would allow external snapshots only on
4
it might not be actually aligned enough for that pointer type (and
4
the first non-filter node in a chain. Parent BDSs should not care
5
thus cause a crash on dereference on some host architectures). Newer
5
whether their child is replaced by a snapshot. (If they do care, they
6
versions of clang warn about this. Avoid the bug by not using the
6
should announce that via freezing the chain, which is checked in
7
"modify in place" byte swapping functions.
7
bdrv_append() through bdrv_set_backing_hd().)
8
8
9
There are a few places where the in-place swap function is
9
Before we had bdrv_is_first_non_filter() here (since 212a5a8f095), there
10
used on something other than a packed struct field; we convert
10
was a special function bdrv_check_ext_snapshot() that allowed snapshots
11
those anyway, for consistency.
11
by default, but block drivers could override this. Only blkverify did
12
so, however.
12
13
13
This patch was produced with the following spatch script
14
It is not clear to me why blkverify would do so; maybe just so that the
14
(and hand-editing to fold a few resulting overlength lines):
15
testee block driver would not be replaced. The introducing commit
16
f6186f49e2c does not explain why. Maybe because 08b24cfe376 would have
17
been the correct solution? (Which adds a .supports_backing check.)
15
18
16
@@
19
Signed-off-by: Max Reitz <mreitz@redhat.com>
17
expression E;
20
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
18
@@
21
Message-Id: <20200218103454.296704-2-mreitz@redhat.com>
19
-be16_to_cpus(&E);
20
+E = be16_to_cpu(E);
21
@@
22
expression E;
23
@@
24
-be32_to_cpus(&E);
25
+E = be32_to_cpu(E);
26
@@
27
expression E;
28
@@
29
-be64_to_cpus(&E);
30
+E = be64_to_cpu(E);
31
@@
32
expression E;
33
@@
34
-cpu_to_be16s(&E);
35
+E = cpu_to_be16(E);
36
@@
37
expression E;
38
@@
39
-cpu_to_be32s(&E);
40
+E = cpu_to_be32(E);
41
@@
42
expression E;
43
@@
44
-cpu_to_be64s(&E);
45
+E = cpu_to_be64(E);
46
47
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
48
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
49
Tested-by: John Snow <jsnow@redhat.com>
50
Reviewed-by: John Snow <jsnow@redhat.com>
51
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
52
---
23
---
53
block/qcow2.c | 64 +++++++++++++++++++++++++++------------------------
24
blockdev.c | 5 -----
54
1 file changed, 34 insertions(+), 30 deletions(-)
25
1 file changed, 5 deletions(-)
55
26
56
diff --git a/block/qcow2.c b/block/qcow2.c
27
diff --git a/blockdev.c b/blockdev.c
57
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
58
--- a/block/qcow2.c
29
--- a/blockdev.c
59
+++ b/block/qcow2.c
30
+++ b/blockdev.c
60
@@ -XXX,XX +XXX,XX @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
31
@@ -XXX,XX +XXX,XX @@ static void external_snapshot_prepare(BlkActionState *common,
61
"pread fail from offset %" PRIu64, offset);
62
return 1;
63
}
64
- be32_to_cpus(&ext.magic);
65
- be32_to_cpus(&ext.len);
66
+ ext.magic = be32_to_cpu(ext.magic);
67
+ ext.len = be32_to_cpu(ext.len);
68
offset += sizeof(ext);
69
#ifdef DEBUG_EXT
70
printf("ext.magic = 0x%x\n", ext.magic);
71
@@ -XXX,XX +XXX,XX @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
72
"Unable to read CRYPTO header extension");
73
return ret;
74
}
75
- be64_to_cpus(&s->crypto_header.offset);
76
- be64_to_cpus(&s->crypto_header.length);
77
+ s->crypto_header.offset = be64_to_cpu(s->crypto_header.offset);
78
+ s->crypto_header.length = be64_to_cpu(s->crypto_header.length);
79
80
if ((s->crypto_header.offset % s->cluster_size) != 0) {
81
error_setg(errp, "Encryption header offset '%" PRIu64 "' is "
82
@@ -XXX,XX +XXX,XX @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
83
return -EINVAL;
84
}
85
86
- be32_to_cpus(&bitmaps_ext.nb_bitmaps);
87
- be64_to_cpus(&bitmaps_ext.bitmap_directory_size);
88
- be64_to_cpus(&bitmaps_ext.bitmap_directory_offset);
89
+ bitmaps_ext.nb_bitmaps = be32_to_cpu(bitmaps_ext.nb_bitmaps);
90
+ bitmaps_ext.bitmap_directory_size =
91
+ be64_to_cpu(bitmaps_ext.bitmap_directory_size);
92
+ bitmaps_ext.bitmap_directory_offset =
93
+ be64_to_cpu(bitmaps_ext.bitmap_directory_offset);
94
95
if (bitmaps_ext.nb_bitmaps > QCOW2_MAX_BITMAPS) {
96
error_setg(errp,
97
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
98
error_setg_errno(errp, -ret, "Could not read qcow2 header");
99
goto fail;
100
}
101
- be32_to_cpus(&header.magic);
102
- be32_to_cpus(&header.version);
103
- be64_to_cpus(&header.backing_file_offset);
104
- be32_to_cpus(&header.backing_file_size);
105
- be64_to_cpus(&header.size);
106
- be32_to_cpus(&header.cluster_bits);
107
- be32_to_cpus(&header.crypt_method);
108
- be64_to_cpus(&header.l1_table_offset);
109
- be32_to_cpus(&header.l1_size);
110
- be64_to_cpus(&header.refcount_table_offset);
111
- be32_to_cpus(&header.refcount_table_clusters);
112
- be64_to_cpus(&header.snapshots_offset);
113
- be32_to_cpus(&header.nb_snapshots);
114
+ header.magic = be32_to_cpu(header.magic);
115
+ header.version = be32_to_cpu(header.version);
116
+ header.backing_file_offset = be64_to_cpu(header.backing_file_offset);
117
+ header.backing_file_size = be32_to_cpu(header.backing_file_size);
118
+ header.size = be64_to_cpu(header.size);
119
+ header.cluster_bits = be32_to_cpu(header.cluster_bits);
120
+ header.crypt_method = be32_to_cpu(header.crypt_method);
121
+ header.l1_table_offset = be64_to_cpu(header.l1_table_offset);
122
+ header.l1_size = be32_to_cpu(header.l1_size);
123
+ header.refcount_table_offset = be64_to_cpu(header.refcount_table_offset);
124
+ header.refcount_table_clusters =
125
+ be32_to_cpu(header.refcount_table_clusters);
126
+ header.snapshots_offset = be64_to_cpu(header.snapshots_offset);
127
+ header.nb_snapshots = be32_to_cpu(header.nb_snapshots);
128
129
if (header.magic != QCOW_MAGIC) {
130
error_setg(errp, "Image is not in qcow2 format");
131
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
132
header.refcount_order = 4;
133
header.header_length = 72;
134
} else {
135
- be64_to_cpus(&header.incompatible_features);
136
- be64_to_cpus(&header.compatible_features);
137
- be64_to_cpus(&header.autoclear_features);
138
- be32_to_cpus(&header.refcount_order);
139
- be32_to_cpus(&header.header_length);
140
+ header.incompatible_features =
141
+ be64_to_cpu(header.incompatible_features);
142
+ header.compatible_features = be64_to_cpu(header.compatible_features);
143
+ header.autoclear_features = be64_to_cpu(header.autoclear_features);
144
+ header.refcount_order = be32_to_cpu(header.refcount_order);
145
+ header.header_length = be32_to_cpu(header.header_length);
146
147
if (header.header_length < 104) {
148
error_setg(errp, "qcow2 header too short");
149
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
150
goto fail;
151
}
152
for(i = 0;i < s->l1_size; i++) {
153
- be64_to_cpus(&s->l1_table[i]);
154
+ s->l1_table[i] = be64_to_cpu(s->l1_table[i]);
155
}
32
}
156
}
33
}
157
34
158
@@ -XXX,XX +XXX,XX @@ int qcow2_update_header(BlockDriverState *bs)
35
- if (!bdrv_is_first_non_filter(state->old_bs)) {
159
36
- error_setg(errp, QERR_FEATURE_DISABLED, "snapshot");
160
/* Full disk encryption header pointer extension */
37
- goto out;
161
if (s->crypto_header.offset != 0) {
38
- }
162
- cpu_to_be64s(&s->crypto_header.offset);
39
-
163
- cpu_to_be64s(&s->crypto_header.length);
40
if (action->type == TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC) {
164
+ s->crypto_header.offset = cpu_to_be64(s->crypto_header.offset);
41
BlockdevSnapshotSync *s = action->u.blockdev_snapshot_sync.data;
165
+ s->crypto_header.length = cpu_to_be64(s->crypto_header.length);
42
const char *format = s->has_format ? s->format : "qcow2";
166
ret = header_ext_add(buf, QCOW2_EXT_MAGIC_CRYPTO_HEADER,
167
&s->crypto_header, sizeof(s->crypto_header),
168
buflen);
169
- be64_to_cpus(&s->crypto_header.offset);
170
- be64_to_cpus(&s->crypto_header.length);
171
+ s->crypto_header.offset = be64_to_cpu(s->crypto_header.offset);
172
+ s->crypto_header.length = be64_to_cpu(s->crypto_header.length);
173
if (ret < 0) {
174
goto fail;
175
}
176
--
43
--
177
2.19.1
44
2.20.1
178
45
179
46
diff view generated by jsdifflib
1
While we want machine interfaces like -blockdev and QMP blockdev-add to
1
From: Max Reitz <mreitz@redhat.com>
2
add as little auto-detection as possible so that management tools are
3
explicit about their needs, -drive is a convenience option for human
4
users. Enabling auto-read-only=on by default there enables users to use
5
read-only images for read-only guest devices without having to specify
6
read-only=on explicitly. If they try to attach the image to a read-write
7
device, they will still get an error message.
8
2
3
Block nodes that do not allow resizing should not share BLK_PERM_RESIZE.
4
It does not matter whether they are the first non-filter in their chain
5
or not.
6
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
Message-Id: <20200218103454.296704-3-mreitz@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Reviewed-by: Eric Blake <eblake@redhat.com>
11
---
11
---
12
blockdev.c | 1 +
12
blockdev.c | 5 -----
13
1 file changed, 1 insertion(+)
13
1 file changed, 5 deletions(-)
14
14
15
diff --git a/blockdev.c b/blockdev.c
15
diff --git a/blockdev.c b/blockdev.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/blockdev.c
17
--- a/blockdev.c
18
+++ b/blockdev.c
18
+++ b/blockdev.c
19
@@ -XXX,XX +XXX,XX @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
19
@@ -XXX,XX +XXX,XX @@ void qmp_block_resize(bool has_device, const char *device,
20
qdict_set_default_str(bs_opts, BDRV_OPT_CACHE_NO_FLUSH, "off");
20
aio_context = bdrv_get_aio_context(bs);
21
qdict_set_default_str(bs_opts, BDRV_OPT_READ_ONLY,
21
aio_context_acquire(aio_context);
22
read_only ? "on" : "off");
22
23
+ qdict_set_default_str(bs_opts, BDRV_OPT_AUTO_READ_ONLY, "on");
23
- if (!bdrv_is_first_non_filter(bs)) {
24
assert((bdrv_flags & BDRV_O_CACHE_MASK) == 0);
24
- error_setg(errp, QERR_FEATURE_DISABLED, "resize");
25
25
- goto out;
26
if (runstate_check(RUN_STATE_INMIGRATE)) {
26
- }
27
-
28
if (size < 0) {
29
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "size", "a >0 size");
30
goto out;
27
--
31
--
28
2.19.1
32
2.20.1
29
33
30
34
diff view generated by jsdifflib
1
Some block drivers have traditionally changed their node to read-only
1
From: Max Reitz <mreitz@redhat.com>
2
mode without asking the user. This behaviour has been marked deprecated
3
since 2.11, expecting users to provide an explicit read-only=on option.
4
2
5
Now that we have auto-read-only=on, enable these drivers to make use of
3
It is unused now. (And it was ugly because it needed to explore all BDS
6
the option.
4
chains from the top.)
7
5
8
This is the only use of bdrv_set_read_only(), so we can make it a bit
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
more specific and turn it into a bdrv_apply_auto_read_only() that is
7
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
more convenient for drivers to use.
8
Message-Id: <20200218103454.296704-4-mreitz@redhat.com>
11
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Reviewed-by: Eric Blake <eblake@redhat.com>
14
---
10
---
15
include/block/block.h | 3 ++-
11
include/block/block.h | 1 -
16
block.c | 42 +++++++++++++++++++++++++++---------------
12
block.c | 26 --------------------------
17
block/bochs.c | 17 ++++++-----------
13
2 files changed, 27 deletions(-)
18
block/cloop.c | 16 +++++-----------
19
block/dmg.c | 16 +++++-----------
20
block/rbd.c | 15 ++++-----------
21
block/vvfat.c | 10 ++--------
22
7 files changed, 51 insertions(+), 68 deletions(-)
23
14
24
diff --git a/include/block/block.h b/include/block/block.h
15
diff --git a/include/block/block.h b/include/block/block.h
25
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
26
--- a/include/block/block.h
17
--- a/include/block/block.h
27
+++ b/include/block/block.h
18
+++ b/include/block/block.h
28
@@ -XXX,XX +XXX,XX @@ int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
19
@@ -XXX,XX +XXX,XX @@ int bdrv_amend_options(BlockDriverState *bs_new, QemuOpts *opts,
29
bool bdrv_is_read_only(BlockDriverState *bs);
20
/* external snapshots */
30
int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
21
bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs,
31
bool ignore_allow_rdw, Error **errp);
22
BlockDriverState *candidate);
32
-int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp);
23
-bool bdrv_is_first_non_filter(BlockDriverState *candidate);
33
+int bdrv_apply_auto_read_only(BlockDriverState *bs, const char *errmsg,
24
34
+ Error **errp);
25
/* check if a named node can be replaced when doing drive-mirror */
35
bool bdrv_is_writable(BlockDriverState *bs);
26
BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs,
36
bool bdrv_is_sg(BlockDriverState *bs);
37
bool bdrv_is_inserted(BlockDriverState *bs);
38
diff --git a/block.c b/block.c
27
diff --git a/block.c b/block.c
39
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
40
--- a/block.c
29
--- a/block.c
41
+++ b/block.c
30
+++ b/block.c
42
@@ -XXX,XX +XXX,XX @@ int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
31
@@ -XXX,XX +XXX,XX @@ bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs,
43
return 0;
32
return false;
44
}
33
}
45
34
46
-/* TODO Remove (deprecated since 2.11)
35
-/* This function checks if the candidate is the first non filter bs down it's
47
- * Block drivers are not supposed to automatically change bs->read_only.
36
- * bs chain. Since we don't have pointers to parents it explore all bs chains
48
- * Instead, they should just check whether they can provide what the user
37
- * from the top. Some filters can choose not to pass down the recursion.
49
- * explicitly requested and error out if read-write is requested, but they can
38
- */
50
- * only provide read-only access. */
39
-bool bdrv_is_first_non_filter(BlockDriverState *candidate)
51
-int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
40
-{
52
+/*
41
- BlockDriverState *bs;
53
+ * Called by a driver that can only provide a read-only image.
42
- BdrvNextIterator it;
54
+ *
55
+ * Returns 0 if the node is already read-only or it could switch the node to
56
+ * read-only because BDRV_O_AUTO_RDONLY is set.
57
+ *
58
+ * Returns -EACCES if the node is read-write and BDRV_O_AUTO_RDONLY is not set
59
+ * or bdrv_can_set_read_only() forbids making the node read-only. If @errmsg
60
+ * is not NULL, it is used as the error message for the Error object.
61
+ */
62
+int bdrv_apply_auto_read_only(BlockDriverState *bs, const char *errmsg,
63
+ Error **errp)
64
{
65
int ret = 0;
66
67
- ret = bdrv_can_set_read_only(bs, read_only, false, errp);
68
- if (ret < 0) {
69
- return ret;
70
+ if (!(bs->open_flags & BDRV_O_RDWR)) {
71
+ return 0;
72
+ }
73
+ if (!(bs->open_flags & BDRV_O_AUTO_RDONLY)) {
74
+ goto fail;
75
}
76
77
- bs->read_only = read_only;
78
-
43
-
79
- if (read_only) {
44
- /* walk down the bs forest recursively */
80
- bs->open_flags &= ~BDRV_O_RDWR;
45
- for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
81
- } else {
46
- bool perm;
82
- bs->open_flags |= BDRV_O_RDWR;
47
-
83
+ ret = bdrv_can_set_read_only(bs, true, false, NULL);
48
- /* try to recurse in this top level bs */
84
+ if (ret < 0) {
49
- perm = bdrv_recurse_is_first_non_filter(bs, candidate);
85
+ goto fail;
50
-
86
}
51
- /* candidate is the first non filter */
87
52
- if (perm) {
88
+ bs->read_only = true;
53
- bdrv_next_cleanup(&it);
89
+ bs->open_flags &= ~BDRV_O_RDWR;
54
- return true;
90
+
91
return 0;
92
+
93
+fail:
94
+ error_setg(errp, "%s", errmsg ?: "Image is read-only");
95
+ return -EACCES;
96
}
97
98
void bdrv_get_full_backing_filename_from_filename(const char *backed,
99
diff --git a/block/bochs.c b/block/bochs.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/block/bochs.c
102
+++ b/block/bochs.c
103
@@ -XXX,XX +XXX,XX @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
104
struct bochs_header bochs;
105
int ret;
106
107
+ /* No write support yet */
108
+ ret = bdrv_apply_auto_read_only(bs, NULL, errp);
109
+ if (ret < 0) {
110
+ return ret;
111
+ }
112
+
113
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
114
false, errp);
115
if (!bs->file) {
116
return -EINVAL;
117
}
118
119
- if (!bdrv_is_read_only(bs)) {
120
- error_report("Opening bochs images without an explicit read-only=on "
121
- "option is deprecated. Future versions will refuse to "
122
- "open the image instead of automatically marking the "
123
- "image read-only.");
124
- ret = bdrv_set_read_only(bs, true, errp); /* no write support yet */
125
- if (ret < 0) {
126
- return ret;
127
- }
55
- }
128
- }
56
- }
129
-
57
-
130
ret = bdrv_pread(bs->file, 0, &bochs, sizeof(bochs));
58
- return false;
131
if (ret < 0) {
59
-}
132
return ret;
133
diff --git a/block/cloop.c b/block/cloop.c
134
index XXXXXXX..XXXXXXX 100644
135
--- a/block/cloop.c
136
+++ b/block/cloop.c
137
@@ -XXX,XX +XXX,XX @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags,
138
uint32_t offsets_size, max_compressed_block_size = 1, i;
139
int ret;
140
141
+ ret = bdrv_apply_auto_read_only(bs, NULL, errp);
142
+ if (ret < 0) {
143
+ return ret;
144
+ }
145
+
146
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
147
false, errp);
148
if (!bs->file) {
149
return -EINVAL;
150
}
151
152
- if (!bdrv_is_read_only(bs)) {
153
- error_report("Opening cloop images without an explicit read-only=on "
154
- "option is deprecated. Future versions will refuse to "
155
- "open the image instead of automatically marking the "
156
- "image read-only.");
157
- ret = bdrv_set_read_only(bs, true, errp);
158
- if (ret < 0) {
159
- return ret;
160
- }
161
- }
162
-
60
-
163
/* read header */
61
BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs,
164
ret = bdrv_pread(bs->file, 128, &s->block_size, 4);
62
const char *node_name, Error **errp)
165
if (ret < 0) {
63
{
166
diff --git a/block/dmg.c b/block/dmg.c
167
index XXXXXXX..XXXXXXX 100644
168
--- a/block/dmg.c
169
+++ b/block/dmg.c
170
@@ -XXX,XX +XXX,XX @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
171
int64_t offset;
172
int ret;
173
174
+ ret = bdrv_apply_auto_read_only(bs, NULL, errp);
175
+ if (ret < 0) {
176
+ return ret;
177
+ }
178
+
179
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
180
false, errp);
181
if (!bs->file) {
182
return -EINVAL;
183
}
184
185
- if (!bdrv_is_read_only(bs)) {
186
- error_report("Opening dmg images without an explicit read-only=on "
187
- "option is deprecated. Future versions will refuse to "
188
- "open the image instead of automatically marking the "
189
- "image read-only.");
190
- ret = bdrv_set_read_only(bs, true, errp);
191
- if (ret < 0) {
192
- return ret;
193
- }
194
- }
195
-
196
block_module_load_one("dmg-bz2");
197
198
s->n_chunks = 0;
199
diff --git a/block/rbd.c b/block/rbd.c
200
index XXXXXXX..XXXXXXX 100644
201
--- a/block/rbd.c
202
+++ b/block/rbd.c
203
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
204
/* If we are using an rbd snapshot, we must be r/o, otherwise
205
* leave as-is */
206
if (s->snap != NULL) {
207
- if (!bdrv_is_read_only(bs)) {
208
- error_report("Opening rbd snapshots without an explicit "
209
- "read-only=on option is deprecated. Future versions "
210
- "will refuse to open the image instead of "
211
- "automatically marking the image read-only.");
212
- r = bdrv_set_read_only(bs, true, &local_err);
213
- if (r < 0) {
214
- rbd_close(s->image);
215
- error_propagate(errp, local_err);
216
- goto failed_open;
217
- }
218
+ r = bdrv_apply_auto_read_only(bs, "rbd snapshots are read-only", errp);
219
+ if (r < 0) {
220
+ rbd_close(s->image);
221
+ goto failed_open;
222
}
223
}
224
225
diff --git a/block/vvfat.c b/block/vvfat.c
226
index XXXXXXX..XXXXXXX 100644
227
--- a/block/vvfat.c
228
+++ b/block/vvfat.c
229
@@ -XXX,XX +XXX,XX @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
230
"Unable to set VVFAT to 'rw' when drive is read-only");
231
goto fail;
232
}
233
- } else if (!bdrv_is_read_only(bs)) {
234
- error_report("Opening non-rw vvfat images without an explicit "
235
- "read-only=on option is deprecated. Future versions "
236
- "will refuse to open the image instead of "
237
- "automatically marking the image read-only.");
238
- /* read only is the default for safety */
239
- ret = bdrv_set_read_only(bs, true, &local_err);
240
+ } else {
241
+ ret = bdrv_apply_auto_read_only(bs, NULL, errp);
242
if (ret < 0) {
243
- error_propagate(errp, local_err);
244
goto fail;
245
}
246
}
247
--
64
--
248
2.19.1
65
2.20.1
249
66
250
67
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
There is no good reason why there should be a newline in this
3
Using -drive with default options means that a virtio-blk drive will be
4
description, so remove it.
4
created that has write access to the to-be quorum children. Quorum
5
should have exclusive write access to them, so we should use -blockdev
6
instead.
5
7
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
10
Message-Id: <20200218103454.296704-5-mreitz@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
12
---
11
vl.c | 2 +-
13
tests/qemu-iotests/041 | 5 ++++-
12
1 file changed, 1 insertion(+), 1 deletion(-)
14
1 file changed, 4 insertions(+), 1 deletion(-)
13
15
14
diff --git a/vl.c b/vl.c
16
diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100755
16
--- a/vl.c
18
--- a/tests/qemu-iotests/041
17
+++ b/vl.c
19
+++ b/tests/qemu-iotests/041
18
@@ -XXX,XX +XXX,XX @@ static QemuOptsList qemu_fw_cfg_opts = {
20
@@ -XXX,XX +XXX,XX @@ class TestRepairQuorum(iotests.QMPTestCase):
19
}, {
21
# Assign a node name to each quorum image in order to manipulate
20
.name = "file",
22
# them
21
.type = QEMU_OPT_STRING,
23
opts = "node-name=img%i" % self.IMAGES.index(i)
22
- .help = "Sets the name of the file from which\n"
24
- self.vm = self.vm.add_drive(i, opts)
23
+ .help = "Sets the name of the file from which "
25
+ opts += ',driver=%s' % iotests.imgfmt
24
"the fw_cfg blob will be loaded",
26
+ opts += ',file.driver=file'
25
}, {
27
+ opts += ',file.filename=%s' % i
26
.name = "string",
28
+ self.vm = self.vm.add_blockdev(opts)
29
30
self.vm.launch()
31
27
--
32
--
28
2.19.1
33
2.20.1
29
34
30
35
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
This is a static function with only one caller, so there's no need to
3
Quorum cannot share WRITE or RESIZE on its children. Presumably, it
4
keep it. Inlining the code in quorum_compare() makes it much simpler.
4
only does so because as a filter, it seemed intuitively correct to point
5
its .bdrv_child_perm to bdrv_filter_default_perm().
5
6
6
Signed-off-by: Alberto Garcia <berto@igalia.com>
7
However, it is not really a filter, and bdrv_filter_default_perm() does
7
Reported-by: Markus Armbruster <armbru@redhat.com>
8
not work for it, so we have to provide a custom .bdrv_child_perm
9
implementation.
10
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
13
Message-Id: <20200218103454.296704-6-mreitz@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
15
---
10
block/quorum.c | 24 +++++-------------------
16
block/quorum.c | 19 ++++++++++++++++++-
11
1 file changed, 5 insertions(+), 19 deletions(-)
17
1 file changed, 18 insertions(+), 1 deletion(-)
12
18
13
diff --git a/block/quorum.c b/block/quorum.c
19
diff --git a/block/quorum.c b/block/quorum.c
14
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
15
--- a/block/quorum.c
21
--- a/block/quorum.c
16
+++ b/block/quorum.c
22
+++ b/block/quorum.c
17
@@ -XXX,XX +XXX,XX @@ static bool quorum_iovec_compare(QEMUIOVector *a, QEMUIOVector *b)
23
@@ -XXX,XX +XXX,XX @@ static char *quorum_dirname(BlockDriverState *bs, Error **errp)
18
return true;
24
return NULL;
19
}
25
}
20
26
21
-static void GCC_FMT_ATTR(2, 3) quorum_err(QuorumAIOCB *acb,
27
+static void quorum_child_perm(BlockDriverState *bs, BdrvChild *c,
22
- const char *fmt, ...)
28
+ const BdrvChildRole *role,
23
-{
29
+ BlockReopenQueue *reopen_queue,
24
- va_list ap;
30
+ uint64_t perm, uint64_t shared,
25
-
31
+ uint64_t *nperm, uint64_t *nshared)
26
- va_start(ap, fmt);
32
+{
27
- fprintf(stderr, "quorum: offset=%" PRIu64 " bytes=%" PRIu64 " ",
33
+ *nperm = perm & DEFAULT_PERM_PASSTHROUGH;
28
- acb->offset, acb->bytes);
34
+
29
- vfprintf(stderr, fmt, ap);
35
+ /*
30
- fprintf(stderr, "\n");
36
+ * We cannot share RESIZE or WRITE, as this would make the
31
- va_end(ap);
37
+ * children differ from each other.
32
- exit(1);
38
+ */
33
-}
39
+ *nshared = (shared & (BLK_PERM_CONSISTENT_READ |
34
-
40
+ BLK_PERM_WRITE_UNCHANGED))
35
-static bool quorum_compare(QuorumAIOCB *acb,
41
+ | DEFAULT_PERM_UNCHANGED;
36
- QEMUIOVector *a,
42
+}
37
- QEMUIOVector *b)
43
+
38
+static bool quorum_compare(QuorumAIOCB *acb, QEMUIOVector *a, QEMUIOVector *b)
44
static const char *const quorum_strong_runtime_opts[] = {
39
{
45
QUORUM_OPT_VOTE_THRESHOLD,
40
BDRVQuorumState *s = acb->bs->opaque;
46
QUORUM_OPT_BLKVERIFY,
41
ssize_t offset;
47
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_quorum = {
42
@@ -XXX,XX +XXX,XX @@ static bool quorum_compare(QuorumAIOCB *acb,
48
.bdrv_add_child = quorum_add_child,
43
if (s->is_blkverify) {
49
.bdrv_del_child = quorum_del_child,
44
offset = qemu_iovec_compare(a, b);
50
45
if (offset != -1) {
51
- .bdrv_child_perm = bdrv_filter_default_perms,
46
- quorum_err(acb, "contents mismatch at offset %" PRIu64,
52
+ .bdrv_child_perm = quorum_child_perm,
47
- acb->offset + offset);
53
48
+ fprintf(stderr, "quorum: offset=%" PRIu64 " bytes=%" PRIu64
54
.is_filter = true,
49
+ " contents mismatch at offset %" PRIu64 "\n",
55
.bdrv_recurse_is_first_non_filter = quorum_recurse_is_first_non_filter,
50
+ acb->offset, acb->bytes, acb->offset + offset);
51
+ exit(1);
52
}
53
return true;
54
}
55
--
56
--
56
2.19.1
57
2.20.1
57
58
58
59
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
2
3
After a couple of follow-up patches, this function will replace
4
bdrv_recurse_is_first_non_filter() in check_to_replace_node().
5
6
bdrv_recurse_is_first_non_filter() is both not sufficiently specific for
7
check_to_replace_node() (it allows cases that should not be allowed,
8
like replacing child nodes of quorum with dissenting data that have more
9
parents than just quorum), and it is too restrictive (it is perfectly
10
fine to replace filters).
11
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
13
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
14
Message-Id: <20200218103454.296704-7-mreitz@redhat.com>
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2
Reviewed-by: Eric Blake <eblake@redhat.com>
3
---
16
---
4
tests/qemu-iotests/232 | 147 +++++++++++++++++++++++++++++++++++++
17
include/block/block_int.h | 10 ++++++++++
5
tests/qemu-iotests/232.out | 59 +++++++++++++++
18
block.c | 38 ++++++++++++++++++++++++++++++++++++++
6
tests/qemu-iotests/group | 1 +
19
2 files changed, 48 insertions(+)
7
3 files changed, 207 insertions(+)
8
create mode 100755 tests/qemu-iotests/232
9
create mode 100644 tests/qemu-iotests/232.out
10
20
11
diff --git a/tests/qemu-iotests/232 b/tests/qemu-iotests/232
21
diff --git a/include/block/block_int.h b/include/block/block_int.h
12
new file mode 100755
22
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX
23
--- a/include/block/block_int.h
14
--- /dev/null
24
+++ b/include/block/block_int.h
15
+++ b/tests/qemu-iotests/232
25
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
16
@@ -XXX,XX +XXX,XX @@
26
*/
17
+#!/bin/bash
27
bool (*bdrv_recurse_is_first_non_filter)(BlockDriverState *bs,
18
+#
28
BlockDriverState *candidate);
19
+# Test for auto-read-only
29
+ /*
20
+#
30
+ * Return true if @to_replace can be replaced by a BDS with the
21
+# Copyright (C) 2018 Red Hat, Inc.
31
+ * same data as @bs without it affecting @bs's behavior (that is,
22
+#
32
+ * without it being visible to @bs's parents).
23
+# This program is free software; you can redistribute it and/or modify
33
+ */
24
+# it under the terms of the GNU General Public License as published by
34
+ bool (*bdrv_recurse_can_replace)(BlockDriverState *bs,
25
+# the Free Software Foundation; either version 2 of the License, or
35
+ BlockDriverState *to_replace);
26
+# (at your option) any later version.
36
27
+#
37
int (*bdrv_probe)(const uint8_t *buf, int buf_size, const char *filename);
28
+# This program is distributed in the hope that it will be useful,
38
int (*bdrv_probe_device)(const char *filename);
29
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
39
@@ -XXX,XX +XXX,XX @@ void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
30
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40
uint64_t perm, uint64_t shared,
31
+# GNU General Public License for more details.
41
uint64_t *nperm, uint64_t *nshared);
32
+#
42
33
+# You should have received a copy of the GNU General Public License
43
+bool bdrv_recurse_can_replace(BlockDriverState *bs,
34
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
44
+ BlockDriverState *to_replace);
35
+#
36
+
45
+
37
+# creator
46
/*
38
+owner=kwolf@redhat.com
47
* Default implementation for drivers to pass bdrv_co_block_status() to
48
* their file.
49
diff --git a/block.c b/block.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/block.c
52
+++ b/block.c
53
@@ -XXX,XX +XXX,XX @@ bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs,
54
return false;
55
}
56
57
+/*
58
+ * This function checks whether the given @to_replace is allowed to be
59
+ * replaced by a node that always shows the same data as @bs. This is
60
+ * used for example to verify whether the mirror job can replace
61
+ * @to_replace by the target mirrored from @bs.
62
+ * To be replaceable, @bs and @to_replace may either be guaranteed to
63
+ * always show the same data (because they are only connected through
64
+ * filters), or some driver may allow replacing one of its children
65
+ * because it can guarantee that this child's data is not visible at
66
+ * all (for example, for dissenting quorum children that have no other
67
+ * parents).
68
+ */
69
+bool bdrv_recurse_can_replace(BlockDriverState *bs,
70
+ BlockDriverState *to_replace)
71
+{
72
+ if (!bs || !bs->drv) {
73
+ return false;
74
+ }
39
+
75
+
40
+seq=`basename $0`
76
+ if (bs == to_replace) {
41
+echo "QA output created by $seq"
77
+ return true;
78
+ }
42
+
79
+
43
+here=`pwd`
80
+ /* See what the driver can do */
44
+status=1    # failure is the default!
81
+ if (bs->drv->bdrv_recurse_can_replace) {
82
+ return bs->drv->bdrv_recurse_can_replace(bs, to_replace);
83
+ }
45
+
84
+
46
+_cleanup()
85
+ /* For filters without an own implementation, we can recurse on our own */
47
+{
86
+ if (bs->drv->is_filter) {
48
+ _cleanup_test_img
87
+ BdrvChild *child = bs->file ?: bs->backing;
49
+ rm -f $TEST_IMG.snap
88
+ return bdrv_recurse_can_replace(child->bs, to_replace);
50
+}
89
+ }
51
+trap "_cleanup; exit \$status" 0 1 2 3 15
52
+
90
+
53
+# get standard environment, filters and checks
91
+ /* Safe default */
54
+. ./common.rc
92
+ return false;
55
+. ./common.filter
56
+
57
+_supported_fmt generic
58
+_supported_proto file
59
+_supported_os Linux
60
+
61
+function do_run_qemu()
62
+{
63
+ echo Testing: "$@"
64
+ (
65
+ if ! test -t 0; then
66
+ while read cmd; do
67
+ echo $cmd
68
+ done
69
+ fi
70
+ echo quit
71
+ ) | $QEMU -nographic -monitor stdio -nodefaults "$@"
72
+ echo
73
+}
93
+}
74
+
94
+
75
+function run_qemu()
95
BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs,
76
+{
96
const char *node_name, Error **errp)
77
+ do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_hmp |
97
{
78
+ _filter_generated_node_ids | _filter_imgfmt
79
+}
80
+
81
+function run_qemu_info_block()
82
+{
83
+ echo "info block -n" | run_qemu "$@" | grep -e "(file" -e "QEMU_PROG"
84
+}
85
+
86
+size=128M
87
+
88
+_make_test_img $size
89
+
90
+echo
91
+echo "=== -drive with read-write image: read-only/auto-read-only combinations ==="
92
+echo
93
+
94
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on,auto-read-only=off
95
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on,auto-read-only=on
96
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on
97
+echo
98
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off,auto-read-only=off
99
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off,auto-read-only=on
100
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off
101
+echo
102
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,auto-read-only=off
103
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,auto-read-only=on
104
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none
105
+
106
+echo
107
+echo "=== -drive with read-only image: read-only/auto-read-only combinations ==="
108
+echo
109
+
110
+chmod a-w $TEST_IMG
111
+
112
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on,auto-read-only=off
113
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on,auto-read-only=on
114
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=on
115
+echo
116
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off,auto-read-only=off
117
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off,auto-read-only=on
118
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,read-only=off
119
+echo
120
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,auto-read-only=off
121
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none,auto-read-only=on
122
+run_qemu_info_block -drive driver=file,file="$TEST_IMG",if=none
123
+
124
+echo
125
+echo "=== -blockdev with read-write image: read-only/auto-read-only combinations ==="
126
+echo
127
+
128
+chmod a+w $TEST_IMG
129
+
130
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on,auto-read-only=off
131
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on,auto-read-only=on
132
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on
133
+echo
134
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off,auto-read-only=off
135
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off,auto-read-only=on
136
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off
137
+echo
138
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,auto-read-only=off
139
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,auto-read-only=on
140
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0
141
+
142
+echo
143
+echo "=== -blockdev with read-only image: read-only/auto-read-only combinations ==="
144
+echo
145
+
146
+chmod a-w $TEST_IMG
147
+
148
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on,auto-read-only=off
149
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on,auto-read-only=on
150
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=on
151
+echo
152
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off,auto-read-only=off
153
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off,auto-read-only=on
154
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,read-only=off
155
+echo
156
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,auto-read-only=off
157
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0,auto-read-only=on
158
+run_qemu_info_block -blockdev driver=file,filename="$TEST_IMG",node-name=node0
159
+
160
+# success, all done
161
+echo "*** done"
162
+rm -f $seq.full
163
+status=0
164
diff --git a/tests/qemu-iotests/232.out b/tests/qemu-iotests/232.out
165
new file mode 100644
166
index XXXXXXX..XXXXXXX
167
--- /dev/null
168
+++ b/tests/qemu-iotests/232.out
169
@@ -XXX,XX +XXX,XX @@
170
+QA output created by 232
171
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
172
+
173
+=== -drive with read-write image: read-only/auto-read-only combinations ===
174
+
175
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
176
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
177
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
178
+
179
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
180
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
181
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
182
+
183
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
184
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
185
+NODE_NAME: TEST_DIR/t.IMGFMT (file)
186
+
187
+=== -drive with read-only image: read-only/auto-read-only combinations ===
188
+
189
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
190
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
191
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
192
+
193
+QEMU_PROG: -drive driver=file,file=TEST_DIR/t.IMGFMT,if=none,read-only=off,auto-read-only=off: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
194
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
195
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
196
+
197
+QEMU_PROG: -drive driver=file,file=TEST_DIR/t.IMGFMT,if=none,auto-read-only=off: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
198
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
199
+NODE_NAME: TEST_DIR/t.IMGFMT (file, read-only)
200
+
201
+=== -blockdev with read-write image: read-only/auto-read-only combinations ===
202
+
203
+node0: TEST_DIR/t.IMGFMT (file, read-only)
204
+node0: TEST_DIR/t.IMGFMT (file, read-only)
205
+node0: TEST_DIR/t.IMGFMT (file, read-only)
206
+
207
+node0: TEST_DIR/t.IMGFMT (file)
208
+node0: TEST_DIR/t.IMGFMT (file)
209
+node0: TEST_DIR/t.IMGFMT (file)
210
+
211
+node0: TEST_DIR/t.IMGFMT (file)
212
+node0: TEST_DIR/t.IMGFMT (file)
213
+node0: TEST_DIR/t.IMGFMT (file)
214
+
215
+=== -blockdev with read-only image: read-only/auto-read-only combinations ===
216
+
217
+node0: TEST_DIR/t.IMGFMT (file, read-only)
218
+node0: TEST_DIR/t.IMGFMT (file, read-only)
219
+node0: TEST_DIR/t.IMGFMT (file, read-only)
220
+
221
+QEMU_PROG: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0,read-only=off,auto-read-only=off: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
222
+node0: TEST_DIR/t.IMGFMT (file, read-only)
223
+QEMU_PROG: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0,read-only=off: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
224
+
225
+QEMU_PROG: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0,auto-read-only=off: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
226
+node0: TEST_DIR/t.IMGFMT (file, read-only)
227
+QEMU_PROG: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0: Could not open 'TEST_DIR/t.IMGFMT': Permission denied
228
+*** done
229
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
230
index XXXXXXX..XXXXXXX 100644
231
--- a/tests/qemu-iotests/group
232
+++ b/tests/qemu-iotests/group
233
@@ -XXX,XX +XXX,XX @@
234
227 auto quick
235
229 auto quick
236
231 auto quick
237
+232 auto quick
238
--
98
--
239
2.19.1
99
2.20.1
240
100
241
101
diff view generated by jsdifflib
1
From: Li Qiang <liq3ea@163.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
Signed-off-by: Li Qiang <liq3ea@163.com>
3
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
Reviewed-by: Alberto Garcia <berto@igalia.com>
4
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
5
Message-Id: <20200218103454.296704-8-mreitz@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
---
7
---
7
include/sysemu/block-backend.h | 6 +++---
8
block/blkverify.c | 15 +++++++++++++++
8
block/block-backend.c | 8 ++++----
9
1 file changed, 15 insertions(+)
9
2 files changed, 7 insertions(+), 7 deletions(-)
10
10
11
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
11
diff --git a/block/blkverify.c b/block/blkverify.c
12
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
13
--- a/include/sysemu/block-backend.h
13
--- a/block/blkverify.c
14
+++ b/include/sysemu/block-backend.h
14
+++ b/block/blkverify.c
15
@@ -XXX,XX +XXX,XX @@ BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
15
@@ -XXX,XX +XXX,XX @@ static bool blkverify_recurse_is_first_non_filter(BlockDriverState *bs,
16
int error);
16
return bdrv_recurse_is_first_non_filter(s->test_file->bs, candidate);
17
void blk_error_action(BlockBackend *blk, BlockErrorAction action,
18
bool is_read, int error);
19
-int blk_is_read_only(BlockBackend *blk);
20
-int blk_is_sg(BlockBackend *blk);
21
-int blk_enable_write_cache(BlockBackend *blk);
22
+bool blk_is_read_only(BlockBackend *blk);
23
+bool blk_is_sg(BlockBackend *blk);
24
+bool blk_enable_write_cache(BlockBackend *blk);
25
void blk_set_enable_write_cache(BlockBackend *blk, bool wce);
26
void blk_invalidate_cache(BlockBackend *blk, Error **errp);
27
bool blk_is_inserted(BlockBackend *blk);
28
diff --git a/block/block-backend.c b/block/block-backend.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/block/block-backend.c
31
+++ b/block/block-backend.c
32
@@ -XXX,XX +XXX,XX @@ void blk_error_action(BlockBackend *blk, BlockErrorAction action,
33
}
34
}
17
}
35
18
36
-int blk_is_read_only(BlockBackend *blk)
19
+static bool blkverify_recurse_can_replace(BlockDriverState *bs,
37
+bool blk_is_read_only(BlockBackend *blk)
20
+ BlockDriverState *to_replace)
21
+{
22
+ BDRVBlkverifyState *s = bs->opaque;
23
+
24
+ /*
25
+ * blkverify quits the whole qemu process if there is a mismatch
26
+ * between bs->file->bs and s->test_file->bs. Therefore, we know
27
+ * know that both must match bs and we can recurse down to either.
28
+ */
29
+ return bdrv_recurse_can_replace(bs->file->bs, to_replace) ||
30
+ bdrv_recurse_can_replace(s->test_file->bs, to_replace);
31
+}
32
+
33
static void blkverify_refresh_filename(BlockDriverState *bs)
38
{
34
{
39
BlockDriverState *bs = blk_bs(blk);
35
BDRVBlkverifyState *s = bs->opaque;
40
36
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_blkverify = {
41
@@ -XXX,XX +XXX,XX @@ int blk_is_read_only(BlockBackend *blk)
37
42
}
38
.is_filter = true,
43
}
39
.bdrv_recurse_is_first_non_filter = blkverify_recurse_is_first_non_filter,
44
40
+ .bdrv_recurse_can_replace = blkverify_recurse_can_replace,
45
-int blk_is_sg(BlockBackend *blk)
41
};
46
+bool blk_is_sg(BlockBackend *blk)
42
47
{
43
static void bdrv_blkverify_init(void)
48
BlockDriverState *bs = blk_bs(blk);
49
50
if (!bs) {
51
- return 0;
52
+ return false;
53
}
54
55
return bdrv_is_sg(bs);
56
}
57
58
-int blk_enable_write_cache(BlockBackend *blk)
59
+bool blk_enable_write_cache(BlockBackend *blk)
60
{
61
return blk->enable_write_cache;
62
}
63
--
44
--
64
2.19.1
45
2.20.1
65
46
66
47
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
The blkverify mode of Quorum only works when the number of children is
3
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
exactly two, so any attempt to add a new one must return an error.
4
Message-Id: <20200218103454.296704-9-mreitz@redhat.com>
5
6
quorum_del_child() on the other hand doesn't need any additional check
7
because decreasing the number of children would make it go under the
8
vote threshold.
9
10
Signed-off-by: Alberto Garcia <berto@igalia.com>
11
Reported-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
6
---
14
block/quorum.c | 8 ++++++++
7
block/quorum.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++
15
1 file changed, 8 insertions(+)
8
1 file changed, 54 insertions(+)
16
9
17
diff --git a/block/quorum.c b/block/quorum.c
10
diff --git a/block/quorum.c b/block/quorum.c
18
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
19
--- a/block/quorum.c
12
--- a/block/quorum.c
20
+++ b/block/quorum.c
13
+++ b/block/quorum.c
21
@@ -XXX,XX +XXX,XX @@ static void quorum_add_child(BlockDriverState *bs, BlockDriverState *child_bs,
14
@@ -XXX,XX +XXX,XX @@ static bool quorum_recurse_is_first_non_filter(BlockDriverState *bs,
22
char indexstr[32];
15
return false;
23
int ret;
16
}
24
17
25
+ if (s->is_blkverify) {
18
+static bool quorum_recurse_can_replace(BlockDriverState *bs,
26
+ error_setg(errp, "Cannot add a child to a quorum in blkverify mode");
19
+ BlockDriverState *to_replace)
27
+ return;
20
+{
21
+ BDRVQuorumState *s = bs->opaque;
22
+ int i;
23
+
24
+ for (i = 0; i < s->num_children; i++) {
25
+ /*
26
+ * We have no idea whether our children show the same data as
27
+ * this node (@bs). It is actually highly likely that
28
+ * @to_replace does not, because replacing a broken child is
29
+ * one of the main use cases here.
30
+ *
31
+ * We do know that the new BDS will match @bs, so replacing
32
+ * any of our children by it will be safe. It cannot change
33
+ * the data this quorum node presents to its parents.
34
+ *
35
+ * However, replacing @to_replace by @bs in any of our
36
+ * children's chains may change visible data somewhere in
37
+ * there. We therefore cannot recurse down those chains with
38
+ * bdrv_recurse_can_replace().
39
+ * (More formally, bdrv_recurse_can_replace() requires that
40
+ * @to_replace will be replaced by something matching the @bs
41
+ * passed to it. We cannot guarantee that.)
42
+ *
43
+ * Thus, we can only check whether any of our immediate
44
+ * children matches @to_replace.
45
+ *
46
+ * (In the future, we might add a function to recurse down a
47
+ * chain that checks that nothing there cares about a change
48
+ * in data from the respective child in question. For
49
+ * example, most filters do not care when their child's data
50
+ * suddenly changes, as long as their parents do not care.)
51
+ */
52
+ if (s->children[i]->bs == to_replace) {
53
+ /*
54
+ * We now have to ensure that there is no other parent
55
+ * that cares about replacing this child by a node with
56
+ * potentially different data.
57
+ * We do so by checking whether there are any other parents
58
+ * at all, which is stricter than necessary, but also very
59
+ * simple. (We may decide to implement something more
60
+ * complex and permissive when there is an actual need for
61
+ * it.)
62
+ */
63
+ return QLIST_FIRST(&to_replace->parents) == s->children[i] &&
64
+ QLIST_NEXT(s->children[i], next_parent) == NULL;
65
+ }
28
+ }
66
+ }
29
+
67
+
30
assert(s->num_children <= INT_MAX / sizeof(BdrvChild *));
68
+ return false;
31
if (s->num_children == INT_MAX / sizeof(BdrvChild *) ||
69
+}
32
s->next_child_index == UINT_MAX) {
33
@@ -XXX,XX +XXX,XX @@ static void quorum_del_child(BlockDriverState *bs, BdrvChild *child,
34
return;
35
}
36
37
+ /* We know now that num_children > threshold, so blkverify must be false */
38
+ assert(!s->is_blkverify);
39
+
70
+
40
bdrv_drained_begin(bs);
71
static int quorum_valid_threshold(int threshold, int num_children, Error **errp)
41
72
{
42
/* We can safely remove this child now */
73
74
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_quorum = {
75
76
.is_filter = true,
77
.bdrv_recurse_is_first_non_filter = quorum_recurse_is_first_non_filter,
78
+ .bdrv_recurse_can_replace = quorum_recurse_can_replace,
79
80
.strong_runtime_opts = quorum_strong_runtime_opts,
81
};
43
--
82
--
44
2.19.1
83
2.20.1
45
84
46
85
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
Signed-off-by: Alberto Garcia <berto@igalia.com>
3
Let check_to_replace_node() use the more specialized
4
bdrv_recurse_can_replace() instead of
5
bdrv_recurse_is_first_non_filter(), which is too restrictive (or, in the
6
case of quorum, sometimes not restrictive enough).
7
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Message-Id: <20200218103454.296704-10-mreitz@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
---
12
---
6
block.c | 6 +++---
13
block.c | 18 ++++++++++++++++--
7
1 file changed, 3 insertions(+), 3 deletions(-)
14
1 file changed, 16 insertions(+), 2 deletions(-)
8
15
9
diff --git a/block.c b/block.c
16
diff --git a/block.c b/block.c
10
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
11
--- a/block.c
18
--- a/block.c
12
+++ b/block.c
19
+++ b/block.c
13
@@ -XXX,XX +XXX,XX @@ QemuOptsList bdrv_runtime_opts = {
20
@@ -XXX,XX +XXX,XX @@ bool bdrv_recurse_can_replace(BlockDriverState *bs,
14
.help = "try to optimize zero writes (off, on, unmap)",
21
return false;
15
},
22
}
16
{
23
17
- .name = "discard",
24
+/*
18
+ .name = BDRV_OPT_DISCARD,
25
+ * Check whether the given @node_name can be replaced by a node that
19
.type = QEMU_OPT_STRING,
26
+ * has the same data as @parent_bs. If so, return @node_name's BDS;
20
.help = "discard operation (ignore/off, unmap/on)",
27
+ * NULL otherwise.
21
},
28
+ *
22
@@ -XXX,XX +XXX,XX @@ static int bdrv_open_common(BlockDriverState *bs, BlockBackend *file,
29
+ * @node_name must be a (recursive) *child of @parent_bs (or this
23
}
30
+ * function will return NULL).
31
+ *
32
+ * The result (whether the node can be replaced or not) is only valid
33
+ * for as long as no graph or permission changes occur.
34
+ */
35
BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs,
36
const char *node_name, Error **errp)
37
{
38
@@ -XXX,XX +XXX,XX @@ BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs,
39
* Another benefit is that this tests exclude backing files which are
40
* blocked by the backing blockers.
41
*/
42
- if (!bdrv_recurse_is_first_non_filter(parent_bs, to_replace_bs)) {
43
- error_setg(errp, "Only top most non filter can be replaced");
44
+ if (!bdrv_recurse_can_replace(parent_bs, to_replace_bs)) {
45
+ error_setg(errp, "Cannot replace '%s' by a node mirrored from '%s', "
46
+ "because it cannot be guaranteed that doing so would not "
47
+ "lead to an abrupt change of visible data",
48
+ node_name, parent_bs->node_name);
49
to_replace_bs = NULL;
50
goto out;
24
}
51
}
25
26
- discard = qemu_opt_get(opts, "discard");
27
+ discard = qemu_opt_get(opts, BDRV_OPT_DISCARD);
28
if (discard != NULL) {
29
if (bdrv_parse_discard_flags(discard, &bs->open_flags) != 0) {
30
error_setg(errp, "Invalid discard option");
31
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
32
33
update_flags_from_options(&reopen_state->flags, opts);
34
35
- discard = qemu_opt_get_del(opts, "discard");
36
+ discard = qemu_opt_get_del(opts, BDRV_OPT_DISCARD);
37
if (discard != NULL) {
38
if (bdrv_parse_discard_flags(discard, &reopen_state->flags) != 0) {
39
error_setg(errp, "Invalid discard option");
40
--
52
--
41
2.19.1
53
2.20.1
42
54
43
55
diff view generated by jsdifflib
1
To fully change the read-only state of a node, we must not only change
1
From: Max Reitz <mreitz@redhat.com>
2
bs->read_only, but also update bs->open_flags.
2
3
3
It no longer has any users.
4
5
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Message-Id: <20200218103454.296704-11-mreitz@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Eric Blake <eblake@redhat.com>
6
Reviewed-by: Alberto Garcia <berto@igalia.com>
7
---
9
---
8
block.c | 7 +++++++
10
include/block/block.h | 4 ----
9
1 file changed, 7 insertions(+)
11
include/block/block_int.h | 8 --------
10
12
block.c | 33 ---------------------------------
13
block/blkverify.c | 15 ---------------
14
block/copy-on-read.c | 9 ---------
15
block/filter-compress.c | 9 ---------
16
block/quorum.c | 18 ------------------
17
block/replication.c | 7 -------
18
block/throttle.c | 8 --------
19
9 files changed, 111 deletions(-)
20
21
diff --git a/include/block/block.h b/include/block/block.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/include/block/block.h
24
+++ b/include/block/block.h
25
@@ -XXX,XX +XXX,XX @@ int bdrv_amend_options(BlockDriverState *bs_new, QemuOpts *opts,
26
BlockDriverAmendStatusCB *status_cb, void *cb_opaque,
27
Error **errp);
28
29
-/* external snapshots */
30
-bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs,
31
- BlockDriverState *candidate);
32
-
33
/* check if a named node can be replaced when doing drive-mirror */
34
BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs,
35
const char *node_name, Error **errp);
36
diff --git a/include/block/block_int.h b/include/block/block_int.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/include/block/block_int.h
39
+++ b/include/block/block_int.h
40
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
41
* must implement them and return -ENOTSUP.
42
*/
43
bool is_filter;
44
- /* for snapshots block filter like Quorum can implement the
45
- * following recursive callback.
46
- * It's purpose is to recurse on the filter children while calling
47
- * bdrv_recurse_is_first_non_filter on them.
48
- * For a sample implementation look in the future Quorum block filter.
49
- */
50
- bool (*bdrv_recurse_is_first_non_filter)(BlockDriverState *bs,
51
- BlockDriverState *candidate);
52
/*
53
* Return true if @to_replace can be replaced by a BDS with the
54
* same data as @bs without it affecting @bs's behavior (that is,
11
diff --git a/block.c b/block.c
55
diff --git a/block.c b/block.c
12
index XXXXXXX..XXXXXXX 100644
56
index XXXXXXX..XXXXXXX 100644
13
--- a/block.c
57
--- a/block.c
14
+++ b/block.c
58
+++ b/block.c
15
@@ -XXX,XX +XXX,XX @@ int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
59
@@ -XXX,XX +XXX,XX @@ int bdrv_amend_options(BlockDriverState *bs, QemuOpts *opts,
16
}
60
return bs->drv->bdrv_amend_options(bs, opts, status_cb, cb_opaque, errp);
17
61
}
18
bs->read_only = read_only;
62
19
+
63
-/* This function will be called by the bdrv_recurse_is_first_non_filter method
20
+ if (read_only) {
64
- * of block filter and by bdrv_is_first_non_filter.
21
+ bs->open_flags &= ~BDRV_O_RDWR;
65
- * It is used to test if the given bs is the candidate or recurse more in the
22
+ } else {
66
- * node graph.
23
+ bs->open_flags |= BDRV_O_RDWR;
67
- */
24
+ }
68
-bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs,
25
+
69
- BlockDriverState *candidate)
26
return 0;
70
-{
27
}
71
- /* return false if basic checks fails */
72
- if (!bs || !bs->drv) {
73
- return false;
74
- }
75
-
76
- /* the code reached a non block filter driver -> check if the bs is
77
- * the same as the candidate. It's the recursion termination condition.
78
- */
79
- if (!bs->drv->is_filter) {
80
- return bs == candidate;
81
- }
82
- /* Down this path the driver is a block filter driver */
83
-
84
- /* If the block filter recursion method is defined use it to recurse down
85
- * the node graph.
86
- */
87
- if (bs->drv->bdrv_recurse_is_first_non_filter) {
88
- return bs->drv->bdrv_recurse_is_first_non_filter(bs, candidate);
89
- }
90
-
91
- /* the driver is a block filter but don't allow to recurse -> return false
92
- */
93
- return false;
94
-}
95
-
96
/*
97
* This function checks whether the given @to_replace is allowed to be
98
* replaced by a node that always shows the same data as @bs. This is
99
diff --git a/block/blkverify.c b/block/blkverify.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/block/blkverify.c
102
+++ b/block/blkverify.c
103
@@ -XXX,XX +XXX,XX @@ static int blkverify_co_flush(BlockDriverState *bs)
104
return bdrv_co_flush(s->test_file->bs);
105
}
106
107
-static bool blkverify_recurse_is_first_non_filter(BlockDriverState *bs,
108
- BlockDriverState *candidate)
109
-{
110
- BDRVBlkverifyState *s = bs->opaque;
111
-
112
- bool perm = bdrv_recurse_is_first_non_filter(bs->file->bs, candidate);
113
-
114
- if (perm) {
115
- return true;
116
- }
117
-
118
- return bdrv_recurse_is_first_non_filter(s->test_file->bs, candidate);
119
-}
120
-
121
static bool blkverify_recurse_can_replace(BlockDriverState *bs,
122
BlockDriverState *to_replace)
123
{
124
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_blkverify = {
125
.bdrv_co_flush = blkverify_co_flush,
126
127
.is_filter = true,
128
- .bdrv_recurse_is_first_non_filter = blkverify_recurse_is_first_non_filter,
129
.bdrv_recurse_can_replace = blkverify_recurse_can_replace,
130
};
131
132
diff --git a/block/copy-on-read.c b/block/copy-on-read.c
133
index XXXXXXX..XXXXXXX 100644
134
--- a/block/copy-on-read.c
135
+++ b/block/copy-on-read.c
136
@@ -XXX,XX +XXX,XX @@ static void cor_lock_medium(BlockDriverState *bs, bool locked)
137
}
138
139
140
-static bool cor_recurse_is_first_non_filter(BlockDriverState *bs,
141
- BlockDriverState *candidate)
142
-{
143
- return bdrv_recurse_is_first_non_filter(bs->file->bs, candidate);
144
-}
145
-
146
-
147
static BlockDriver bdrv_copy_on_read = {
148
.format_name = "copy-on-read",
149
150
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_copy_on_read = {
151
152
.bdrv_co_block_status = bdrv_co_block_status_from_file,
153
154
- .bdrv_recurse_is_first_non_filter = cor_recurse_is_first_non_filter,
155
-
156
.has_variable_length = true,
157
.is_filter = true,
158
};
159
diff --git a/block/filter-compress.c b/block/filter-compress.c
160
index XXXXXXX..XXXXXXX 100644
161
--- a/block/filter-compress.c
162
+++ b/block/filter-compress.c
163
@@ -XXX,XX +XXX,XX @@ static void compress_lock_medium(BlockDriverState *bs, bool locked)
164
}
165
166
167
-static bool compress_recurse_is_first_non_filter(BlockDriverState *bs,
168
- BlockDriverState *candidate)
169
-{
170
- return bdrv_recurse_is_first_non_filter(bs->file->bs, candidate);
171
-}
172
-
173
-
174
static BlockDriver bdrv_compress = {
175
.format_name = "compress",
176
177
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_compress = {
178
179
.bdrv_co_block_status = bdrv_co_block_status_from_file,
180
181
- .bdrv_recurse_is_first_non_filter = compress_recurse_is_first_non_filter,
182
-
183
.has_variable_length = true,
184
.is_filter = true,
185
};
186
diff --git a/block/quorum.c b/block/quorum.c
187
index XXXXXXX..XXXXXXX 100644
188
--- a/block/quorum.c
189
+++ b/block/quorum.c
190
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int quorum_co_flush(BlockDriverState *bs)
191
return result;
192
}
193
194
-static bool quorum_recurse_is_first_non_filter(BlockDriverState *bs,
195
- BlockDriverState *candidate)
196
-{
197
- BDRVQuorumState *s = bs->opaque;
198
- int i;
199
-
200
- for (i = 0; i < s->num_children; i++) {
201
- bool perm = bdrv_recurse_is_first_non_filter(s->children[i]->bs,
202
- candidate);
203
- if (perm) {
204
- return true;
205
- }
206
- }
207
-
208
- return false;
209
-}
210
-
211
static bool quorum_recurse_can_replace(BlockDriverState *bs,
212
BlockDriverState *to_replace)
213
{
214
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_quorum = {
215
.bdrv_child_perm = quorum_child_perm,
216
217
.is_filter = true,
218
- .bdrv_recurse_is_first_non_filter = quorum_recurse_is_first_non_filter,
219
.bdrv_recurse_can_replace = quorum_recurse_can_replace,
220
221
.strong_runtime_opts = quorum_strong_runtime_opts,
222
diff --git a/block/replication.c b/block/replication.c
223
index XXXXXXX..XXXXXXX 100644
224
--- a/block/replication.c
225
+++ b/block/replication.c
226
@@ -XXX,XX +XXX,XX @@ out:
227
return ret;
228
}
229
230
-static bool replication_recurse_is_first_non_filter(BlockDriverState *bs,
231
- BlockDriverState *candidate)
232
-{
233
- return bdrv_recurse_is_first_non_filter(bs->file->bs, candidate);
234
-}
235
-
236
static void secondary_do_checkpoint(BDRVReplicationState *s, Error **errp)
237
{
238
Error *local_err = NULL;
239
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_replication = {
240
.bdrv_co_writev = replication_co_writev,
241
242
.is_filter = true,
243
- .bdrv_recurse_is_first_non_filter = replication_recurse_is_first_non_filter,
244
245
.has_variable_length = true,
246
.strong_runtime_opts = replication_strong_runtime_opts,
247
diff --git a/block/throttle.c b/block/throttle.c
248
index XXXXXXX..XXXXXXX 100644
249
--- a/block/throttle.c
250
+++ b/block/throttle.c
251
@@ -XXX,XX +XXX,XX @@ static void throttle_reopen_abort(BDRVReopenState *reopen_state)
252
reopen_state->opaque = NULL;
253
}
254
255
-static bool throttle_recurse_is_first_non_filter(BlockDriverState *bs,
256
- BlockDriverState *candidate)
257
-{
258
- return bdrv_recurse_is_first_non_filter(bs->file->bs, candidate);
259
-}
260
-
261
static void coroutine_fn throttle_co_drain_begin(BlockDriverState *bs)
262
{
263
ThrottleGroupMember *tgm = bs->opaque;
264
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_throttle = {
265
.bdrv_co_pwrite_zeroes = throttle_co_pwrite_zeroes,
266
.bdrv_co_pdiscard = throttle_co_pdiscard,
267
268
- .bdrv_recurse_is_first_non_filter = throttle_recurse_is_first_non_filter,
269
-
270
.bdrv_attach_aio_context = throttle_attach_aio_context,
271
.bdrv_detach_aio_context = throttle_detach_aio_context,
28
272
29
--
273
--
30
2.19.1
274
2.20.1
31
275
32
276
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
Just like in qemu_opts_print_help(), print the object name as a caption
3
There is no guarantee that we can still replace the node we want to
4
instead of on every single line, indent all options, add angle brackets
4
replace at the end of the mirror job. Double-check by calling
5
around types, and align the descriptions after 24 characters.
5
bdrv_recurse_can_replace().
6
7
Also, indent every object name in the list of available objects.
8
6
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
8
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
Message-Id: <20200218103454.296704-12-mreitz@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
11
---
13
vl.c | 13 ++++++++++---
12
block/mirror.c | 14 +++++++++++++-
14
1 file changed, 10 insertions(+), 3 deletions(-)
13
1 file changed, 13 insertions(+), 1 deletion(-)
15
14
16
diff --git a/vl.c b/vl.c
15
diff --git a/block/mirror.c b/block/mirror.c
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/vl.c
17
--- a/block/mirror.c
19
+++ b/vl.c
18
+++ b/block/mirror.c
20
@@ -XXX,XX +XXX,XX @@ static bool object_create_initial(const char *type, QemuOpts *opts)
19
@@ -XXX,XX +XXX,XX @@ static int mirror_exit_common(Job *job)
21
list = object_class_get_list_sorted(TYPE_USER_CREATABLE, false);
20
* drain potential other users of the BDS before changing the graph. */
22
for (l = list; l != NULL; l = l->next) {
21
assert(s->in_drain);
23
ObjectClass *oc = OBJECT_CLASS(l->data);
22
bdrv_drained_begin(target_bs);
24
- printf("%s\n", object_class_get_name(oc));
23
- bdrv_replace_node(to_replace, target_bs, &local_err);
25
+ printf(" %s\n", object_class_get_name(oc));
24
+ /*
26
}
25
+ * Cannot use check_to_replace_node() here, because that would
27
g_slist_free(list);
26
+ * check for an op blocker on @to_replace, and we have our own
28
exit(0);
27
+ * there.
29
@@ -XXX,XX +XXX,XX @@ static bool object_create_initial(const char *type, QemuOpts *opts)
28
+ */
30
}
29
+ if (bdrv_recurse_can_replace(src, to_replace)) {
31
30
+ bdrv_replace_node(to_replace, target_bs, &local_err);
32
str = g_string_new(NULL);
33
- g_string_append_printf(str, "%s.%s=%s", type,
34
- prop->name, prop->type);
35
+ g_string_append_printf(str, " %s=<%s>", prop->name, prop->type);
36
if (prop->description) {
37
+ if (str->len < 24) {
38
+ g_string_append_printf(str, "%*s", 24 - (int)str->len, "");
39
+ }
40
g_string_append_printf(str, " - %s", prop->description);
41
}
42
g_ptr_array_add(array, g_string_free(str, false));
43
}
44
g_ptr_array_sort(array, (GCompareFunc)qemu_pstrcmp0);
45
+ if (array->len > 0) {
46
+ printf("%s options:\n", type);
47
+ } else {
31
+ } else {
48
+ printf("There are no options for %s.\n", type);
32
+ error_setg(&local_err, "Can no longer replace '%s' by '%s', "
33
+ "because it can no longer be guaranteed that doing so "
34
+ "would not lead to an abrupt change of visible data",
35
+ to_replace->node_name, target_bs->node_name);
49
+ }
36
+ }
50
for (i = 0; i < array->len; i++) {
37
bdrv_drained_end(target_bs);
51
printf("%s\n", (char *)array->pdata[i]);
38
if (local_err) {
52
}
39
error_report_err(local_err);
53
--
40
--
54
2.19.1
41
2.20.1
55
42
56
43
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
The blkverify mode of Quorum can only be enabled if the number of
3
Quorum is not a filter, for example because it cannot guarantee which of
4
children is exactly two and the value of vote-threshold is also two.
4
its children will serve the next request. Thus, any of its children may
5
differ from the data visible to quorum's parents.
5
6
6
If the user tries to enable it but the other settings are incorrect
7
We have other filters with multiple children, but they differ in this
7
then QEMU simply prints an error message to stderr and carries on
8
aspect:
8
disabling the blkverify setting.
9
9
10
This patch makes quorum_open() fail and return an error in this case.
10
- blkverify quits the whole qemu process if its children differ. As
11
such, we can always skip it when we want to skip it (as a filter node)
12
by going to any of its children. Both have the same data.
11
13
12
Signed-off-by: Alberto Garcia <berto@igalia.com>
14
- replication generally serves requests from bs->file, so this is its
13
Reported-by: Markus Armbruster <armbru@redhat.com>
15
only actually filtered child.
16
17
- Block job filters currently only have one child, but they will
18
probably get more children in the future. Still, they will always
19
have only one actually filtered child.
20
21
Having "filters" as a dedicated node category only makes sense if you
22
can skip them by going to a one fixed child that always shows the same
23
data as the filter node. Quorum cannot fulfill this, so it is not a
24
filter.
25
26
Signed-off-by: Max Reitz <mreitz@redhat.com>
27
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
28
Message-Id: <20200218103454.296704-13-mreitz@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
29
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
30
---
16
block/quorum.c | 13 ++++++-------
31
block/quorum.c | 1 -
17
1 file changed, 6 insertions(+), 7 deletions(-)
32
1 file changed, 1 deletion(-)
18
33
19
diff --git a/block/quorum.c b/block/quorum.c
34
diff --git a/block/quorum.c b/block/quorum.c
20
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
21
--- a/block/quorum.c
36
--- a/block/quorum.c
22
+++ b/block/quorum.c
37
+++ b/block/quorum.c
23
@@ -XXX,XX +XXX,XX @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags,
38
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_quorum = {
24
s->read_pattern = ret;
39
25
40
.bdrv_child_perm = quorum_child_perm,
26
if (s->read_pattern == QUORUM_READ_PATTERN_QUORUM) {
41
27
- /* is the driver in blkverify mode */
42
- .is_filter = true,
28
- if (qemu_opt_get_bool(opts, QUORUM_OPT_BLKVERIFY, false) &&
43
.bdrv_recurse_can_replace = quorum_recurse_can_replace,
29
- s->num_children == 2 && s->threshold == 2) {
44
30
- s->is_blkverify = true;
45
.strong_runtime_opts = quorum_strong_runtime_opts,
31
- } else if (qemu_opt_get_bool(opts, QUORUM_OPT_BLKVERIFY, false)) {
32
- fprintf(stderr, "blkverify mode is set by setting blkverify=on "
33
- "and using two files with vote_threshold=2\n");
34
+ s->is_blkverify = qemu_opt_get_bool(opts, QUORUM_OPT_BLKVERIFY, false);
35
+ if (s->is_blkverify && (s->num_children != 2 || s->threshold != 2)) {
36
+ error_setg(&local_err, "blkverify=on can only be set if there are "
37
+ "exactly two files and vote-threshold is 2");
38
+ ret = -EINVAL;
39
+ goto exit;
40
}
41
42
s->rewrite_corrupted = qemu_opt_get_bool(opts, QUORUM_OPT_REWRITE,
43
--
46
--
44
2.19.1
47
2.20.1
45
48
46
49
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
Just like in qemu_opts_print_help(), print the device name as a caption
3
This way, we get to see errors during the completion phase.
4
instead of on every single line, indent all options, add angle brackets
5
around types, and align the descriptions after 24 characters. Also,
6
separate the descriptions with " - " instead of putting them in
7
parentheses, because that is what we do everywhere else. This does look
8
a bit funny here because basically all bits have the description
9
"on/off", but funny does not mean it is less readable.
10
4
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
5
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
6
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Message-Id: <20200218103454.296704-14-mreitz@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
9
---
15
qdev-monitor.c | 13 +++++++++++--
10
tests/qemu-iotests/155 | 7 +------
16
1 file changed, 11 insertions(+), 2 deletions(-)
11
1 file changed, 1 insertion(+), 6 deletions(-)
17
12
18
diff --git a/qdev-monitor.c b/qdev-monitor.c
13
diff --git a/tests/qemu-iotests/155 b/tests/qemu-iotests/155
19
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100755
20
--- a/qdev-monitor.c
15
--- a/tests/qemu-iotests/155
21
+++ b/qdev-monitor.c
16
+++ b/tests/qemu-iotests/155
22
@@ -XXX,XX +XXX,XX @@ int qdev_device_help(QemuOpts *opts)
17
@@ -XXX,XX +XXX,XX @@ class MirrorBaseClass(BaseClass):
23
goto error;
18
24
}
19
self.assert_qmp(result, 'return', {})
25
20
26
+ if (prop_list) {
21
- self.vm.event_wait('BLOCK_JOB_READY')
27
+ out_printf("%s options:\n", driver);
22
-
28
+ } else {
23
- result = self.vm.qmp('block-job-complete', device='mirror-job')
29
+ out_printf("There are no options for %s.\n", driver);
24
- self.assert_qmp(result, 'return', {})
30
+ }
25
-
31
for (prop = prop_list; prop; prop = prop->next) {
26
- self.vm.event_wait('BLOCK_JOB_COMPLETED')
32
- out_printf("%s.%s=%s", driver, prop->value->name, prop->value->type);
27
+ self.complete_and_wait('mirror-job')
33
+ int len;
28
34
+ out_printf(" %s=<%s>%n", prop->value->name, prop->value->type, &len);
29
def testFull(self):
35
if (prop->value->has_description) {
30
self.runMirror('full')
36
- out_printf(" (%s)\n", prop->value->description);
37
+ if (len < 24) {
38
+ out_printf("%*s", 24 - len, "");
39
+ }
40
+ out_printf(" - %s\n", prop->value->description);
41
} else {
42
out_printf("\n");
43
}
44
--
31
--
45
2.19.1
32
2.20.1
46
33
47
34
diff view generated by jsdifflib
1
From: Cleber Rosa <crosa@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
While testing the Python 3 changes which touch the 083 test, I noticed
3
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
that it would fail with qcow2. Expanding the testing, I noticed it
4
Message-Id: <20200218103454.296704-15-mreitz@redhat.com>
5
had nothing to do with the Python 3 changes, and in fact, it would not
6
pass on anything but raw:
7
8
raw: pass
9
bochs: not generic
10
cloop: not generic
11
parallels: fail
12
qcow: fail
13
qcow2: fail
14
qed: fail
15
vdi: fail
16
vhdx: fail
17
vmdk: fail
18
vpc: fail
19
luks: fail
20
21
The errors are a mixture I/O and "image not in xxx format", such as:
22
23
=== Check disconnect before data ===
24
25
Unexpected end-of-file before all bytes were read
26
-read failed: Input/output error
27
+can't open device nbd+tcp://127.0.0.1:PORT/foo: Could not open 'nbd://127.0.0.1:PORT/foo': Input/output error
28
29
=== Check disconnect after data ===
30
31
-read 512/512 bytes at offset 0
32
-512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
33
+can't open device nbd+tcp://127.0.0.1:PORT/foo: Image not in qcow format
34
35
I'm not aware if there's a quick fix, so, for the time being, it looks
36
like the honest approach is to make the test known to work on raw
37
only.
38
39
Signed-off-by: Cleber Rosa <crosa@redhat.com>
40
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
41
---
6
---
42
tests/qemu-iotests/083 | 2 +-
7
tests/qemu-iotests/iotests.py | 59 +++++++++++++++++++++++++++++++++++
43
1 file changed, 1 insertion(+), 1 deletion(-)
8
1 file changed, 59 insertions(+)
44
9
45
diff --git a/tests/qemu-iotests/083 b/tests/qemu-iotests/083
10
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
46
index XXXXXXX..XXXXXXX 100755
11
index XXXXXXX..XXXXXXX 100644
47
--- a/tests/qemu-iotests/083
12
--- a/tests/qemu-iotests/iotests.py
48
+++ b/tests/qemu-iotests/083
13
+++ b/tests/qemu-iotests/iotests.py
49
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
14
@@ -XXX,XX +XXX,XX @@ class VM(qtest.QEMUQtestMachine):
50
. ./common.rc
15
51
. ./common.filter
16
return fields.items() <= ret.items()
52
17
53
-_supported_fmt generic
18
+ def assert_block_path(self, root, path, expected_node, graph=None):
54
+_supported_fmt raw
19
+ """
55
_supported_proto nbd
20
+ Check whether the node under the given path in the block graph
56
_supported_os Linux
21
+ is @expected_node.
22
+
23
+ @root is the node name of the node where the @path is rooted.
24
+
25
+ @path is a string that consists of child names separated by
26
+ slashes. It must begin with a slash.
27
+
28
+ Examples for @root + @path:
29
+ - root="qcow2-node", path="/backing/file"
30
+ - root="quorum-node", path="/children.2/file"
31
+
32
+ Hypothetically, @path could be empty, in which case it would
33
+ point to @root. However, in practice this case is not useful
34
+ and hence not allowed.
35
+
36
+ @expected_node may be None. (All elements of the path but the
37
+ leaf must still exist.)
38
+
39
+ @graph may be None or the result of an x-debug-query-block-graph
40
+ call that has already been performed.
41
+ """
42
+ if graph is None:
43
+ graph = self.qmp('x-debug-query-block-graph')['return']
44
+
45
+ iter_path = iter(path.split('/'))
46
+
47
+ # Must start with a /
48
+ assert next(iter_path) == ''
49
+
50
+ node = next((node for node in graph['nodes'] if node['name'] == root),
51
+ None)
52
+
53
+ # An empty @path is not allowed, so the root node must be present
54
+ assert node is not None, 'Root node %s not found' % root
55
+
56
+ for child_name in iter_path:
57
+ assert node is not None, 'Cannot follow path %s%s' % (root, path)
58
+
59
+ try:
60
+ node_id = next(edge['child'] for edge in graph['edges'] \
61
+ if edge['parent'] == node['id'] and
62
+ edge['name'] == child_name)
63
+
64
+ node = next(node for node in graph['nodes'] \
65
+ if node['id'] == node_id)
66
+ except StopIteration:
67
+ node = None
68
+
69
+ if node is None:
70
+ assert expected_node is None, \
71
+ 'No node found under %s (but expected %s)' % \
72
+ (path, expected_node)
73
+ else:
74
+ assert node['name'] == expected_node, \
75
+ 'Found node %s under %s (but expected %s)' % \
76
+ (node['name'], path, expected_node)
77
78
index_re = re.compile(r'([^\[]+)\[([^\]]+)\]')
57
79
58
--
80
--
59
2.19.1
81
2.20.1
60
82
61
83
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
This adds some whitespace into the option help (including indentation)
3
All tearDowns in 041 shutdown the VM. Thus, test cases do not need to
4
and puts angle brackets around the type names. Furthermore, the list
4
do it themselves (unless they need the VM to be down for some
5
name is no longer printed as part of every line, but only once in
5
post-operation check).
6
advance, and only if the caller did not print a caption already.
7
8
This patch also restores the description alignment we had before commit
9
9cbef9d68ee1d8d0, just at 24 instead of 16 characters like we used to.
10
This increase is because now we have the type and two spaces of
11
indentation before the description, and with a usual type name length of
12
three chracters, this sums up to eight additional characters -- which
13
means that we now need 24 characters to get the same amount of padding
14
for most options. Also, 24 is a third of 80, which makes it kind of a
15
round number in terminal terms.
16
17
Finally, this patch amends the reference output of iotest 082 to match
18
the changes (and thus makes it pass again).
19
6
20
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
21
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
8
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
Message-Id: <20200218103454.296704-16-mreitz@redhat.com>
22
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
23
---
11
---
24
include/qemu/option.h | 2 +-
12
tests/qemu-iotests/041 | 11 -----------
25
qemu-img.c | 4 +-
13
1 file changed, 11 deletions(-)
26
util/qemu-option.c | 32 +-
27
tests/qemu-iotests/082.out | 956 ++++++++++++++++++-------------------
28
4 files changed, 507 insertions(+), 487 deletions(-)
29
14
30
diff --git a/include/qemu/option.h b/include/qemu/option.h
15
diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
31
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100755
32
--- a/include/qemu/option.h
17
--- a/tests/qemu-iotests/041
33
+++ b/include/qemu/option.h
18
+++ b/tests/qemu-iotests/041
34
@@ -XXX,XX +XXX,XX @@ typedef int (*qemu_opts_loopfunc)(void *opaque, QemuOpts *opts, Error **errp);
19
@@ -XXX,XX +XXX,XX @@ class TestSingleDrive(iotests.QMPTestCase):
35
int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func,
20
self.cancel_and_wait(force=True)
36
void *opaque, Error **errp);
21
result = self.vm.qmp('query-block')
37
void qemu_opts_print(QemuOpts *opts, const char *sep);
22
self.assert_qmp(result, 'return[0]/inserted/file', test_img)
38
-void qemu_opts_print_help(QemuOptsList *list);
23
- self.vm.shutdown()
39
+void qemu_opts_print_help(QemuOptsList *list, bool print_caption);
24
40
void qemu_opts_free(QemuOptsList *list);
25
def test_cancel_after_ready(self):
41
QemuOptsList *qemu_opts_append(QemuOptsList *dst, QemuOptsList *list);
26
self.assert_no_active_block_jobs()
42
27
@@ -XXX,XX +XXX,XX @@ class TestSingleDrive(iotests.QMPTestCase):
43
diff --git a/qemu-img.c b/qemu-img.c
28
self.assert_qmp(result, 'return[0]/node-name', 'top')
44
index XXXXXXX..XXXXXXX 100644
29
self.assert_qmp(result, 'return[0]/backing/node-name', 'base')
45
--- a/qemu-img.c
30
46
+++ b/qemu-img.c
31
- self.vm.shutdown()
47
@@ -XXX,XX +XXX,XX @@ static int print_block_option_help(const char *filename, const char *fmt)
32
-
48
}
33
def test_medium_not_found(self):
49
34
if iotests.qemu_default_machine != 'pc':
50
printf("Supported options:\n");
35
return
51
- qemu_opts_print_help(create_opts);
36
@@ -XXX,XX +XXX,XX @@ new_state = "1"
52
+ qemu_opts_print_help(create_opts, false);
37
self.assert_qmp(event, 'data/id', 'drive0')
53
qemu_opts_free(create_opts);
38
54
return 0;
39
self.assert_no_active_block_jobs()
55
}
40
- self.vm.shutdown()
56
@@ -XXX,XX +XXX,XX @@ static int print_amend_option_help(const char *format)
41
57
assert(drv->create_opts);
42
def test_ignore_read(self):
58
43
self.assert_no_active_block_jobs()
59
printf("Creation options for '%s':\n", format);
44
@@ -XXX,XX +XXX,XX @@ new_state = "1"
60
- qemu_opts_print_help(drv->create_opts);
45
result = self.vm.qmp('query-block-jobs')
61
+ qemu_opts_print_help(drv->create_opts, false);
46
self.assert_qmp(result, 'return[0]/paused', False)
62
printf("\nNote that not all of these options may be amendable.\n");
47
self.complete_and_wait()
63
return 0;
48
- self.vm.shutdown()
64
}
49
65
diff --git a/util/qemu-option.c b/util/qemu-option.c
50
def test_large_cluster(self):
66
index XXXXXXX..XXXXXXX 100644
51
self.assert_no_active_block_jobs()
67
--- a/util/qemu-option.c
52
@@ -XXX,XX +XXX,XX @@ new_state = "1"
68
+++ b/util/qemu-option.c
53
69
@@ -XXX,XX +XXX,XX @@ static const char *opt_type_to_string(enum QemuOptType type)
54
self.complete_and_wait(wait_ready=False)
70
g_assert_not_reached();
55
self.assert_no_active_block_jobs()
71
}
56
- self.vm.shutdown()
72
57
73
-void qemu_opts_print_help(QemuOptsList *list)
58
class TestWriteErrors(iotests.QMPTestCase):
74
+/**
59
image_len = 2 * 1024 * 1024 # MB
75
+ * Print the list of options available in the given list. If
60
@@ -XXX,XX +XXX,XX @@ new_state = "1"
76
+ * @print_caption is true, a caption (including the list name, if it
61
completed = True
77
+ * exists) is printed. The options itself will be indented, so
62
78
+ * @print_caption should only be set to false if the caller prints its
63
self.assert_no_active_block_jobs()
79
+ * own custom caption (so that the indentation makes sense).
64
- self.vm.shutdown()
80
+ */
65
81
+void qemu_opts_print_help(QemuOptsList *list, bool print_caption)
66
def test_ignore_write(self):
82
{
67
self.assert_no_active_block_jobs()
83
QemuOptDesc *desc;
68
@@ -XXX,XX +XXX,XX @@ new_state = "1"
84
int i;
69
result = self.vm.qmp('query-block-jobs')
85
@@ -XXX,XX +XXX,XX @@ void qemu_opts_print_help(QemuOptsList *list)
70
self.assert_qmp(result, 'return[0]/paused', False)
86
desc = list->desc;
71
self.complete_and_wait()
87
while (desc && desc->name) {
72
- self.vm.shutdown()
88
GString *str = g_string_new(NULL);
73
89
- if (list->name) {
74
def test_stop_write(self):
90
- g_string_append_printf(str, "%s.", list->name);
75
self.assert_no_active_block_jobs()
91
- }
76
@@ -XXX,XX +XXX,XX @@ new_state = "1"
92
- g_string_append_printf(str, "%s=%s", desc->name,
77
93
+ g_string_append_printf(str, " %s=<%s>", desc->name,
78
self.complete_and_wait(wait_ready=False)
94
opt_type_to_string(desc->type));
79
self.assert_no_active_block_jobs()
95
if (desc->help) {
80
- self.vm.shutdown()
96
+ if (str->len < 24) {
81
97
+ g_string_append_printf(str, "%*s", 24 - (int)str->len, "");
82
class TestSetSpeed(iotests.QMPTestCase):
98
+ }
83
image_len = 80 * 1024 * 1024 # MB
99
g_string_append_printf(str, " - %s", desc->help);
84
@@ -XXX,XX +XXX,XX @@ class TestRepairQuorum(iotests.QMPTestCase):
100
}
85
# here we check that the last registered quorum file has not been
101
g_ptr_array_add(array, g_string_free(str, false));
86
# swapped out and unref
102
@@ -XXX,XX +XXX,XX @@ void qemu_opts_print_help(QemuOptsList *list)
87
self.assert_has_block_node(None, quorum_img3)
103
}
88
- self.vm.shutdown()
104
89
105
g_ptr_array_sort(array, (GCompareFunc)qemu_pstrcmp0);
90
def test_cancel_after_ready(self):
106
+ if (print_caption && array->len > 0) {
91
self.assert_no_active_block_jobs()
107
+ if (list->name) {
92
@@ -XXX,XX +XXX,XX @@ class TestRepairQuorum(iotests.QMPTestCase):
108
+ printf("%s options:\n", list->name);
93
self.assert_has_block_node("repair0", quorum_repair_img)
109
+ } else {
94
# TODO: a better test requiring some QEMU infrastructure will be added
110
+ printf("Options:\n");
95
# to check that this file is really driven by quorum
111
+ }
96
- self.vm.shutdown()
112
+ } else if (array->len == 0) {
97
113
+ if (list->name) {
98
# Test mirroring with a source that does not have any parents (not even a
114
+ printf("There are no options for %s.\n", list->name);
99
# BlockBackend)
115
+ } else {
116
+ printf("No options available.\n");
117
+ }
118
+ }
119
for (i = 0; i < array->len; i++) {
120
printf("%s\n", (char *)array->pdata[i]);
121
}
122
@@ -XXX,XX +XXX,XX @@ QemuOpts *qemu_opts_parse_noisily(QemuOptsList *list, const char *params,
123
opts = opts_parse(list, params, permit_abbrev, false, &invalidp, &err);
124
if (err) {
125
if (invalidp && has_help_option(params)) {
126
- qemu_opts_print_help(list);
127
+ qemu_opts_print_help(list, true);
128
error_free(err);
129
} else {
130
error_report_err(err);
131
diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out
132
index XXXXXXX..XXXXXXX 100644
133
--- a/tests/qemu-iotests/082.out
134
+++ b/tests/qemu-iotests/082.out
135
@@ -XXX,XX +XXX,XX @@ cluster_size: 8192
136
137
Testing: create -f qcow2 -o help TEST_DIR/t.qcow2 128M
138
Supported options:
139
-size Virtual disk size
140
-compat Compatibility level (0.10 or 1.1)
141
-backing_file File name of a base image
142
-backing_fmt Image format of the base image
143
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
144
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
145
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
146
-encrypt.cipher-alg Name of encryption cipher algorithm
147
-encrypt.cipher-mode Name of encryption cipher mode
148
-encrypt.ivgen-alg Name of IV generator algorithm
149
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
150
-encrypt.hash-alg Name of encryption hash algorithm
151
-encrypt.iter-time Time to spend in PBKDF in milliseconds
152
-cluster_size qcow2 cluster size
153
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
154
-lazy_refcounts Postpone refcount updates
155
-refcount_bits Width of a reference count entry in bits
156
-nocow Turn off copy-on-write (valid only on btrfs)
157
+ backing_file=<str> - File name of a base image
158
+ backing_fmt=<str> - Image format of the base image
159
+ cluster_size=<size> - qcow2 cluster size
160
+ compat=<str> - Compatibility level (0.10 or 1.1)
161
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
162
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
163
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
164
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
165
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
166
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
167
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
168
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
169
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
170
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
171
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
172
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
173
+ refcount_bits=<num> - Width of a reference count entry in bits
174
+ size=<size> - Virtual disk size
175
176
Testing: create -f qcow2 -o ? TEST_DIR/t.qcow2 128M
177
Supported options:
178
-size Virtual disk size
179
-compat Compatibility level (0.10 or 1.1)
180
-backing_file File name of a base image
181
-backing_fmt Image format of the base image
182
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
183
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
184
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
185
-encrypt.cipher-alg Name of encryption cipher algorithm
186
-encrypt.cipher-mode Name of encryption cipher mode
187
-encrypt.ivgen-alg Name of IV generator algorithm
188
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
189
-encrypt.hash-alg Name of encryption hash algorithm
190
-encrypt.iter-time Time to spend in PBKDF in milliseconds
191
-cluster_size qcow2 cluster size
192
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
193
-lazy_refcounts Postpone refcount updates
194
-refcount_bits Width of a reference count entry in bits
195
-nocow Turn off copy-on-write (valid only on btrfs)
196
+ backing_file=<str> - File name of a base image
197
+ backing_fmt=<str> - Image format of the base image
198
+ cluster_size=<size> - qcow2 cluster size
199
+ compat=<str> - Compatibility level (0.10 or 1.1)
200
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
201
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
202
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
203
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
204
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
205
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
206
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
207
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
208
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
209
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
210
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
211
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
212
+ refcount_bits=<num> - Width of a reference count entry in bits
213
+ size=<size> - Virtual disk size
214
215
Testing: create -f qcow2 -o cluster_size=4k,help TEST_DIR/t.qcow2 128M
216
Supported options:
217
-size Virtual disk size
218
-compat Compatibility level (0.10 or 1.1)
219
-backing_file File name of a base image
220
-backing_fmt Image format of the base image
221
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
222
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
223
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
224
-encrypt.cipher-alg Name of encryption cipher algorithm
225
-encrypt.cipher-mode Name of encryption cipher mode
226
-encrypt.ivgen-alg Name of IV generator algorithm
227
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
228
-encrypt.hash-alg Name of encryption hash algorithm
229
-encrypt.iter-time Time to spend in PBKDF in milliseconds
230
-cluster_size qcow2 cluster size
231
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
232
-lazy_refcounts Postpone refcount updates
233
-refcount_bits Width of a reference count entry in bits
234
-nocow Turn off copy-on-write (valid only on btrfs)
235
+ backing_file=<str> - File name of a base image
236
+ backing_fmt=<str> - Image format of the base image
237
+ cluster_size=<size> - qcow2 cluster size
238
+ compat=<str> - Compatibility level (0.10 or 1.1)
239
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
240
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
241
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
242
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
243
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
244
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
245
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
246
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
247
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
248
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
249
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
250
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
251
+ refcount_bits=<num> - Width of a reference count entry in bits
252
+ size=<size> - Virtual disk size
253
254
Testing: create -f qcow2 -o cluster_size=4k,? TEST_DIR/t.qcow2 128M
255
Supported options:
256
-size Virtual disk size
257
-compat Compatibility level (0.10 or 1.1)
258
-backing_file File name of a base image
259
-backing_fmt Image format of the base image
260
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
261
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
262
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
263
-encrypt.cipher-alg Name of encryption cipher algorithm
264
-encrypt.cipher-mode Name of encryption cipher mode
265
-encrypt.ivgen-alg Name of IV generator algorithm
266
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
267
-encrypt.hash-alg Name of encryption hash algorithm
268
-encrypt.iter-time Time to spend in PBKDF in milliseconds
269
-cluster_size qcow2 cluster size
270
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
271
-lazy_refcounts Postpone refcount updates
272
-refcount_bits Width of a reference count entry in bits
273
-nocow Turn off copy-on-write (valid only on btrfs)
274
+ backing_file=<str> - File name of a base image
275
+ backing_fmt=<str> - Image format of the base image
276
+ cluster_size=<size> - qcow2 cluster size
277
+ compat=<str> - Compatibility level (0.10 or 1.1)
278
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
279
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
280
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
281
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
282
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
283
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
284
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
285
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
286
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
287
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
288
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
289
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
290
+ refcount_bits=<num> - Width of a reference count entry in bits
291
+ size=<size> - Virtual disk size
292
293
Testing: create -f qcow2 -o help,cluster_size=4k TEST_DIR/t.qcow2 128M
294
Supported options:
295
-size Virtual disk size
296
-compat Compatibility level (0.10 or 1.1)
297
-backing_file File name of a base image
298
-backing_fmt Image format of the base image
299
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
300
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
301
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
302
-encrypt.cipher-alg Name of encryption cipher algorithm
303
-encrypt.cipher-mode Name of encryption cipher mode
304
-encrypt.ivgen-alg Name of IV generator algorithm
305
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
306
-encrypt.hash-alg Name of encryption hash algorithm
307
-encrypt.iter-time Time to spend in PBKDF in milliseconds
308
-cluster_size qcow2 cluster size
309
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
310
-lazy_refcounts Postpone refcount updates
311
-refcount_bits Width of a reference count entry in bits
312
-nocow Turn off copy-on-write (valid only on btrfs)
313
+ backing_file=<str> - File name of a base image
314
+ backing_fmt=<str> - Image format of the base image
315
+ cluster_size=<size> - qcow2 cluster size
316
+ compat=<str> - Compatibility level (0.10 or 1.1)
317
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
318
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
319
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
320
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
321
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
322
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
323
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
324
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
325
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
326
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
327
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
328
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
329
+ refcount_bits=<num> - Width of a reference count entry in bits
330
+ size=<size> - Virtual disk size
331
332
Testing: create -f qcow2 -o ?,cluster_size=4k TEST_DIR/t.qcow2 128M
333
Supported options:
334
-size Virtual disk size
335
-compat Compatibility level (0.10 or 1.1)
336
-backing_file File name of a base image
337
-backing_fmt Image format of the base image
338
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
339
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
340
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
341
-encrypt.cipher-alg Name of encryption cipher algorithm
342
-encrypt.cipher-mode Name of encryption cipher mode
343
-encrypt.ivgen-alg Name of IV generator algorithm
344
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
345
-encrypt.hash-alg Name of encryption hash algorithm
346
-encrypt.iter-time Time to spend in PBKDF in milliseconds
347
-cluster_size qcow2 cluster size
348
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
349
-lazy_refcounts Postpone refcount updates
350
-refcount_bits Width of a reference count entry in bits
351
-nocow Turn off copy-on-write (valid only on btrfs)
352
+ backing_file=<str> - File name of a base image
353
+ backing_fmt=<str> - Image format of the base image
354
+ cluster_size=<size> - qcow2 cluster size
355
+ compat=<str> - Compatibility level (0.10 or 1.1)
356
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
357
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
358
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
359
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
360
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
361
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
362
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
363
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
364
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
365
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
366
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
367
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
368
+ refcount_bits=<num> - Width of a reference count entry in bits
369
+ size=<size> - Virtual disk size
370
371
Testing: create -f qcow2 -o cluster_size=4k -o help TEST_DIR/t.qcow2 128M
372
Supported options:
373
-size Virtual disk size
374
-compat Compatibility level (0.10 or 1.1)
375
-backing_file File name of a base image
376
-backing_fmt Image format of the base image
377
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
378
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
379
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
380
-encrypt.cipher-alg Name of encryption cipher algorithm
381
-encrypt.cipher-mode Name of encryption cipher mode
382
-encrypt.ivgen-alg Name of IV generator algorithm
383
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
384
-encrypt.hash-alg Name of encryption hash algorithm
385
-encrypt.iter-time Time to spend in PBKDF in milliseconds
386
-cluster_size qcow2 cluster size
387
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
388
-lazy_refcounts Postpone refcount updates
389
-refcount_bits Width of a reference count entry in bits
390
-nocow Turn off copy-on-write (valid only on btrfs)
391
+ backing_file=<str> - File name of a base image
392
+ backing_fmt=<str> - Image format of the base image
393
+ cluster_size=<size> - qcow2 cluster size
394
+ compat=<str> - Compatibility level (0.10 or 1.1)
395
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
396
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
397
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
398
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
399
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
400
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
401
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
402
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
403
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
404
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
405
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
406
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
407
+ refcount_bits=<num> - Width of a reference count entry in bits
408
+ size=<size> - Virtual disk size
409
410
Testing: create -f qcow2 -o cluster_size=4k -o ? TEST_DIR/t.qcow2 128M
411
Supported options:
412
-size Virtual disk size
413
-compat Compatibility level (0.10 or 1.1)
414
-backing_file File name of a base image
415
-backing_fmt Image format of the base image
416
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
417
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
418
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
419
-encrypt.cipher-alg Name of encryption cipher algorithm
420
-encrypt.cipher-mode Name of encryption cipher mode
421
-encrypt.ivgen-alg Name of IV generator algorithm
422
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
423
-encrypt.hash-alg Name of encryption hash algorithm
424
-encrypt.iter-time Time to spend in PBKDF in milliseconds
425
-cluster_size qcow2 cluster size
426
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
427
-lazy_refcounts Postpone refcount updates
428
-refcount_bits Width of a reference count entry in bits
429
-nocow Turn off copy-on-write (valid only on btrfs)
430
+ backing_file=<str> - File name of a base image
431
+ backing_fmt=<str> - Image format of the base image
432
+ cluster_size=<size> - qcow2 cluster size
433
+ compat=<str> - Compatibility level (0.10 or 1.1)
434
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
435
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
436
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
437
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
438
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
439
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
440
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
441
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
442
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
443
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
444
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
445
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
446
+ refcount_bits=<num> - Width of a reference count entry in bits
447
+ size=<size> - Virtual disk size
448
449
Testing: create -f qcow2 -u -o backing_file=TEST_DIR/t.qcow2,,help TEST_DIR/t.qcow2 128M
450
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
451
@@ -XXX,XX +XXX,XX @@ qemu-img: Invalid option list: ,,
452
453
Testing: create -f qcow2 -o help
454
Supported options:
455
-size Virtual disk size
456
-compat Compatibility level (0.10 or 1.1)
457
-backing_file File name of a base image
458
-backing_fmt Image format of the base image
459
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
460
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
461
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
462
-encrypt.cipher-alg Name of encryption cipher algorithm
463
-encrypt.cipher-mode Name of encryption cipher mode
464
-encrypt.ivgen-alg Name of IV generator algorithm
465
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
466
-encrypt.hash-alg Name of encryption hash algorithm
467
-encrypt.iter-time Time to spend in PBKDF in milliseconds
468
-cluster_size qcow2 cluster size
469
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
470
-lazy_refcounts Postpone refcount updates
471
-refcount_bits Width of a reference count entry in bits
472
+ backing_file=<str> - File name of a base image
473
+ backing_fmt=<str> - Image format of the base image
474
+ cluster_size=<size> - qcow2 cluster size
475
+ compat=<str> - Compatibility level (0.10 or 1.1)
476
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
477
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
478
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
479
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
480
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
481
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
482
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
483
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
484
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
485
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
486
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
487
+ refcount_bits=<num> - Width of a reference count entry in bits
488
+ size=<size> - Virtual disk size
489
490
Testing: create -o help
491
Supported options:
492
-size Virtual disk size
493
+ size=<size> - Virtual disk size
494
495
Testing: create -f bochs -o help
496
qemu-img: Format driver 'bochs' does not support image creation
497
@@ -XXX,XX +XXX,XX @@ cluster_size: 8192
498
499
Testing: convert -O qcow2 -o help TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
500
Supported options:
501
-size Virtual disk size
502
-compat Compatibility level (0.10 or 1.1)
503
-backing_file File name of a base image
504
-backing_fmt Image format of the base image
505
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
506
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
507
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
508
-encrypt.cipher-alg Name of encryption cipher algorithm
509
-encrypt.cipher-mode Name of encryption cipher mode
510
-encrypt.ivgen-alg Name of IV generator algorithm
511
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
512
-encrypt.hash-alg Name of encryption hash algorithm
513
-encrypt.iter-time Time to spend in PBKDF in milliseconds
514
-cluster_size qcow2 cluster size
515
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
516
-lazy_refcounts Postpone refcount updates
517
-refcount_bits Width of a reference count entry in bits
518
-nocow Turn off copy-on-write (valid only on btrfs)
519
+ backing_file=<str> - File name of a base image
520
+ backing_fmt=<str> - Image format of the base image
521
+ cluster_size=<size> - qcow2 cluster size
522
+ compat=<str> - Compatibility level (0.10 or 1.1)
523
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
524
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
525
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
526
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
527
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
528
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
529
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
530
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
531
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
532
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
533
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
534
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
535
+ refcount_bits=<num> - Width of a reference count entry in bits
536
+ size=<size> - Virtual disk size
537
538
Testing: convert -O qcow2 -o ? TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
539
Supported options:
540
-size Virtual disk size
541
-compat Compatibility level (0.10 or 1.1)
542
-backing_file File name of a base image
543
-backing_fmt Image format of the base image
544
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
545
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
546
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
547
-encrypt.cipher-alg Name of encryption cipher algorithm
548
-encrypt.cipher-mode Name of encryption cipher mode
549
-encrypt.ivgen-alg Name of IV generator algorithm
550
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
551
-encrypt.hash-alg Name of encryption hash algorithm
552
-encrypt.iter-time Time to spend in PBKDF in milliseconds
553
-cluster_size qcow2 cluster size
554
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
555
-lazy_refcounts Postpone refcount updates
556
-refcount_bits Width of a reference count entry in bits
557
-nocow Turn off copy-on-write (valid only on btrfs)
558
+ backing_file=<str> - File name of a base image
559
+ backing_fmt=<str> - Image format of the base image
560
+ cluster_size=<size> - qcow2 cluster size
561
+ compat=<str> - Compatibility level (0.10 or 1.1)
562
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
563
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
564
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
565
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
566
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
567
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
568
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
569
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
570
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
571
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
572
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
573
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
574
+ refcount_bits=<num> - Width of a reference count entry in bits
575
+ size=<size> - Virtual disk size
576
577
Testing: convert -O qcow2 -o cluster_size=4k,help TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
578
Supported options:
579
-size Virtual disk size
580
-compat Compatibility level (0.10 or 1.1)
581
-backing_file File name of a base image
582
-backing_fmt Image format of the base image
583
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
584
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
585
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
586
-encrypt.cipher-alg Name of encryption cipher algorithm
587
-encrypt.cipher-mode Name of encryption cipher mode
588
-encrypt.ivgen-alg Name of IV generator algorithm
589
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
590
-encrypt.hash-alg Name of encryption hash algorithm
591
-encrypt.iter-time Time to spend in PBKDF in milliseconds
592
-cluster_size qcow2 cluster size
593
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
594
-lazy_refcounts Postpone refcount updates
595
-refcount_bits Width of a reference count entry in bits
596
-nocow Turn off copy-on-write (valid only on btrfs)
597
+ backing_file=<str> - File name of a base image
598
+ backing_fmt=<str> - Image format of the base image
599
+ cluster_size=<size> - qcow2 cluster size
600
+ compat=<str> - Compatibility level (0.10 or 1.1)
601
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
602
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
603
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
604
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
605
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
606
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
607
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
608
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
609
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
610
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
611
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
612
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
613
+ refcount_bits=<num> - Width of a reference count entry in bits
614
+ size=<size> - Virtual disk size
615
616
Testing: convert -O qcow2 -o cluster_size=4k,? TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
617
Supported options:
618
-size Virtual disk size
619
-compat Compatibility level (0.10 or 1.1)
620
-backing_file File name of a base image
621
-backing_fmt Image format of the base image
622
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
623
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
624
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
625
-encrypt.cipher-alg Name of encryption cipher algorithm
626
-encrypt.cipher-mode Name of encryption cipher mode
627
-encrypt.ivgen-alg Name of IV generator algorithm
628
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
629
-encrypt.hash-alg Name of encryption hash algorithm
630
-encrypt.iter-time Time to spend in PBKDF in milliseconds
631
-cluster_size qcow2 cluster size
632
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
633
-lazy_refcounts Postpone refcount updates
634
-refcount_bits Width of a reference count entry in bits
635
-nocow Turn off copy-on-write (valid only on btrfs)
636
+ backing_file=<str> - File name of a base image
637
+ backing_fmt=<str> - Image format of the base image
638
+ cluster_size=<size> - qcow2 cluster size
639
+ compat=<str> - Compatibility level (0.10 or 1.1)
640
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
641
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
642
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
643
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
644
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
645
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
646
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
647
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
648
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
649
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
650
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
651
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
652
+ refcount_bits=<num> - Width of a reference count entry in bits
653
+ size=<size> - Virtual disk size
654
655
Testing: convert -O qcow2 -o help,cluster_size=4k TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
656
Supported options:
657
-size Virtual disk size
658
-compat Compatibility level (0.10 or 1.1)
659
-backing_file File name of a base image
660
-backing_fmt Image format of the base image
661
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
662
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
663
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
664
-encrypt.cipher-alg Name of encryption cipher algorithm
665
-encrypt.cipher-mode Name of encryption cipher mode
666
-encrypt.ivgen-alg Name of IV generator algorithm
667
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
668
-encrypt.hash-alg Name of encryption hash algorithm
669
-encrypt.iter-time Time to spend in PBKDF in milliseconds
670
-cluster_size qcow2 cluster size
671
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
672
-lazy_refcounts Postpone refcount updates
673
-refcount_bits Width of a reference count entry in bits
674
-nocow Turn off copy-on-write (valid only on btrfs)
675
+ backing_file=<str> - File name of a base image
676
+ backing_fmt=<str> - Image format of the base image
677
+ cluster_size=<size> - qcow2 cluster size
678
+ compat=<str> - Compatibility level (0.10 or 1.1)
679
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
680
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
681
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
682
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
683
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
684
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
685
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
686
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
687
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
688
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
689
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
690
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
691
+ refcount_bits=<num> - Width of a reference count entry in bits
692
+ size=<size> - Virtual disk size
693
694
Testing: convert -O qcow2 -o ?,cluster_size=4k TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
695
Supported options:
696
-size Virtual disk size
697
-compat Compatibility level (0.10 or 1.1)
698
-backing_file File name of a base image
699
-backing_fmt Image format of the base image
700
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
701
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
702
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
703
-encrypt.cipher-alg Name of encryption cipher algorithm
704
-encrypt.cipher-mode Name of encryption cipher mode
705
-encrypt.ivgen-alg Name of IV generator algorithm
706
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
707
-encrypt.hash-alg Name of encryption hash algorithm
708
-encrypt.iter-time Time to spend in PBKDF in milliseconds
709
-cluster_size qcow2 cluster size
710
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
711
-lazy_refcounts Postpone refcount updates
712
-refcount_bits Width of a reference count entry in bits
713
-nocow Turn off copy-on-write (valid only on btrfs)
714
+ backing_file=<str> - File name of a base image
715
+ backing_fmt=<str> - Image format of the base image
716
+ cluster_size=<size> - qcow2 cluster size
717
+ compat=<str> - Compatibility level (0.10 or 1.1)
718
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
719
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
720
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
721
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
722
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
723
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
724
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
725
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
726
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
727
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
728
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
729
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
730
+ refcount_bits=<num> - Width of a reference count entry in bits
731
+ size=<size> - Virtual disk size
732
733
Testing: convert -O qcow2 -o cluster_size=4k -o help TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
734
Supported options:
735
-size Virtual disk size
736
-compat Compatibility level (0.10 or 1.1)
737
-backing_file File name of a base image
738
-backing_fmt Image format of the base image
739
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
740
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
741
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
742
-encrypt.cipher-alg Name of encryption cipher algorithm
743
-encrypt.cipher-mode Name of encryption cipher mode
744
-encrypt.ivgen-alg Name of IV generator algorithm
745
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
746
-encrypt.hash-alg Name of encryption hash algorithm
747
-encrypt.iter-time Time to spend in PBKDF in milliseconds
748
-cluster_size qcow2 cluster size
749
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
750
-lazy_refcounts Postpone refcount updates
751
-refcount_bits Width of a reference count entry in bits
752
-nocow Turn off copy-on-write (valid only on btrfs)
753
+ backing_file=<str> - File name of a base image
754
+ backing_fmt=<str> - Image format of the base image
755
+ cluster_size=<size> - qcow2 cluster size
756
+ compat=<str> - Compatibility level (0.10 or 1.1)
757
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
758
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
759
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
760
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
761
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
762
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
763
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
764
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
765
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
766
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
767
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
768
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
769
+ refcount_bits=<num> - Width of a reference count entry in bits
770
+ size=<size> - Virtual disk size
771
772
Testing: convert -O qcow2 -o cluster_size=4k -o ? TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
773
Supported options:
774
-size Virtual disk size
775
-compat Compatibility level (0.10 or 1.1)
776
-backing_file File name of a base image
777
-backing_fmt Image format of the base image
778
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
779
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
780
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
781
-encrypt.cipher-alg Name of encryption cipher algorithm
782
-encrypt.cipher-mode Name of encryption cipher mode
783
-encrypt.ivgen-alg Name of IV generator algorithm
784
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
785
-encrypt.hash-alg Name of encryption hash algorithm
786
-encrypt.iter-time Time to spend in PBKDF in milliseconds
787
-cluster_size qcow2 cluster size
788
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
789
-lazy_refcounts Postpone refcount updates
790
-refcount_bits Width of a reference count entry in bits
791
-nocow Turn off copy-on-write (valid only on btrfs)
792
+ backing_file=<str> - File name of a base image
793
+ backing_fmt=<str> - Image format of the base image
794
+ cluster_size=<size> - qcow2 cluster size
795
+ compat=<str> - Compatibility level (0.10 or 1.1)
796
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
797
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
798
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
799
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
800
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
801
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
802
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
803
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
804
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
805
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
806
+ nocow=<bool (on/off)> - Turn off copy-on-write (valid only on btrfs)
807
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
808
+ refcount_bits=<num> - Width of a reference count entry in bits
809
+ size=<size> - Virtual disk size
810
811
Testing: convert -O qcow2 -o backing_file=TEST_DIR/t.qcow2,,help TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
812
qemu-img: Could not open 'TEST_DIR/t.qcow2.base': Could not open backing file: Could not open 'TEST_DIR/t.qcow2,help': No such file or directory
813
@@ -XXX,XX +XXX,XX @@ qemu-img: Invalid option list: ,,
814
815
Testing: convert -O qcow2 -o help
816
Supported options:
817
-size Virtual disk size
818
-compat Compatibility level (0.10 or 1.1)
819
-backing_file File name of a base image
820
-backing_fmt Image format of the base image
821
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
822
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
823
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
824
-encrypt.cipher-alg Name of encryption cipher algorithm
825
-encrypt.cipher-mode Name of encryption cipher mode
826
-encrypt.ivgen-alg Name of IV generator algorithm
827
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
828
-encrypt.hash-alg Name of encryption hash algorithm
829
-encrypt.iter-time Time to spend in PBKDF in milliseconds
830
-cluster_size qcow2 cluster size
831
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
832
-lazy_refcounts Postpone refcount updates
833
-refcount_bits Width of a reference count entry in bits
834
+ backing_file=<str> - File name of a base image
835
+ backing_fmt=<str> - Image format of the base image
836
+ cluster_size=<size> - qcow2 cluster size
837
+ compat=<str> - Compatibility level (0.10 or 1.1)
838
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
839
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
840
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
841
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
842
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
843
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
844
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
845
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
846
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
847
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
848
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
849
+ refcount_bits=<num> - Width of a reference count entry in bits
850
+ size=<size> - Virtual disk size
851
852
Testing: convert -o help
853
Supported options:
854
-size Virtual disk size
855
+ size=<size> - Virtual disk size
856
857
Testing: convert -O bochs -o help
858
qemu-img: Format driver 'bochs' does not support image creation
859
@@ -XXX,XX +XXX,XX @@ cluster_size: 65536
860
861
Testing: amend -f qcow2 -o help TEST_DIR/t.qcow2
862
Creation options for 'qcow2':
863
-size Virtual disk size
864
-compat Compatibility level (0.10 or 1.1)
865
-backing_file File name of a base image
866
-backing_fmt Image format of the base image
867
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
868
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
869
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
870
-encrypt.cipher-alg Name of encryption cipher algorithm
871
-encrypt.cipher-mode Name of encryption cipher mode
872
-encrypt.ivgen-alg Name of IV generator algorithm
873
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
874
-encrypt.hash-alg Name of encryption hash algorithm
875
-encrypt.iter-time Time to spend in PBKDF in milliseconds
876
-cluster_size qcow2 cluster size
877
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
878
-lazy_refcounts Postpone refcount updates
879
-refcount_bits Width of a reference count entry in bits
880
+ backing_file=<str> - File name of a base image
881
+ backing_fmt=<str> - Image format of the base image
882
+ cluster_size=<size> - qcow2 cluster size
883
+ compat=<str> - Compatibility level (0.10 or 1.1)
884
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
885
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
886
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
887
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
888
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
889
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
890
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
891
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
892
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
893
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
894
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
895
+ refcount_bits=<num> - Width of a reference count entry in bits
896
+ size=<size> - Virtual disk size
897
898
Note that not all of these options may be amendable.
899
900
Testing: amend -f qcow2 -o ? TEST_DIR/t.qcow2
901
Creation options for 'qcow2':
902
-size Virtual disk size
903
-compat Compatibility level (0.10 or 1.1)
904
-backing_file File name of a base image
905
-backing_fmt Image format of the base image
906
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
907
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
908
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
909
-encrypt.cipher-alg Name of encryption cipher algorithm
910
-encrypt.cipher-mode Name of encryption cipher mode
911
-encrypt.ivgen-alg Name of IV generator algorithm
912
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
913
-encrypt.hash-alg Name of encryption hash algorithm
914
-encrypt.iter-time Time to spend in PBKDF in milliseconds
915
-cluster_size qcow2 cluster size
916
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
917
-lazy_refcounts Postpone refcount updates
918
-refcount_bits Width of a reference count entry in bits
919
+ backing_file=<str> - File name of a base image
920
+ backing_fmt=<str> - Image format of the base image
921
+ cluster_size=<size> - qcow2 cluster size
922
+ compat=<str> - Compatibility level (0.10 or 1.1)
923
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
924
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
925
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
926
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
927
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
928
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
929
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
930
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
931
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
932
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
933
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
934
+ refcount_bits=<num> - Width of a reference count entry in bits
935
+ size=<size> - Virtual disk size
936
937
Note that not all of these options may be amendable.
938
939
Testing: amend -f qcow2 -o cluster_size=4k,help TEST_DIR/t.qcow2
940
Creation options for 'qcow2':
941
-size Virtual disk size
942
-compat Compatibility level (0.10 or 1.1)
943
-backing_file File name of a base image
944
-backing_fmt Image format of the base image
945
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
946
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
947
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
948
-encrypt.cipher-alg Name of encryption cipher algorithm
949
-encrypt.cipher-mode Name of encryption cipher mode
950
-encrypt.ivgen-alg Name of IV generator algorithm
951
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
952
-encrypt.hash-alg Name of encryption hash algorithm
953
-encrypt.iter-time Time to spend in PBKDF in milliseconds
954
-cluster_size qcow2 cluster size
955
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
956
-lazy_refcounts Postpone refcount updates
957
-refcount_bits Width of a reference count entry in bits
958
+ backing_file=<str> - File name of a base image
959
+ backing_fmt=<str> - Image format of the base image
960
+ cluster_size=<size> - qcow2 cluster size
961
+ compat=<str> - Compatibility level (0.10 or 1.1)
962
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
963
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
964
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
965
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
966
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
967
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
968
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
969
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
970
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
971
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
972
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
973
+ refcount_bits=<num> - Width of a reference count entry in bits
974
+ size=<size> - Virtual disk size
975
976
Note that not all of these options may be amendable.
977
978
Testing: amend -f qcow2 -o cluster_size=4k,? TEST_DIR/t.qcow2
979
Creation options for 'qcow2':
980
-size Virtual disk size
981
-compat Compatibility level (0.10 or 1.1)
982
-backing_file File name of a base image
983
-backing_fmt Image format of the base image
984
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
985
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
986
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
987
-encrypt.cipher-alg Name of encryption cipher algorithm
988
-encrypt.cipher-mode Name of encryption cipher mode
989
-encrypt.ivgen-alg Name of IV generator algorithm
990
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
991
-encrypt.hash-alg Name of encryption hash algorithm
992
-encrypt.iter-time Time to spend in PBKDF in milliseconds
993
-cluster_size qcow2 cluster size
994
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
995
-lazy_refcounts Postpone refcount updates
996
-refcount_bits Width of a reference count entry in bits
997
+ backing_file=<str> - File name of a base image
998
+ backing_fmt=<str> - Image format of the base image
999
+ cluster_size=<size> - qcow2 cluster size
1000
+ compat=<str> - Compatibility level (0.10 or 1.1)
1001
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1002
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1003
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1004
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1005
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1006
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1007
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1008
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1009
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1010
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1011
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1012
+ refcount_bits=<num> - Width of a reference count entry in bits
1013
+ size=<size> - Virtual disk size
1014
1015
Note that not all of these options may be amendable.
1016
1017
Testing: amend -f qcow2 -o help,cluster_size=4k TEST_DIR/t.qcow2
1018
Creation options for 'qcow2':
1019
-size Virtual disk size
1020
-compat Compatibility level (0.10 or 1.1)
1021
-backing_file File name of a base image
1022
-backing_fmt Image format of the base image
1023
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1024
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
1025
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
1026
-encrypt.cipher-alg Name of encryption cipher algorithm
1027
-encrypt.cipher-mode Name of encryption cipher mode
1028
-encrypt.ivgen-alg Name of IV generator algorithm
1029
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
1030
-encrypt.hash-alg Name of encryption hash algorithm
1031
-encrypt.iter-time Time to spend in PBKDF in milliseconds
1032
-cluster_size qcow2 cluster size
1033
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
1034
-lazy_refcounts Postpone refcount updates
1035
-refcount_bits Width of a reference count entry in bits
1036
+ backing_file=<str> - File name of a base image
1037
+ backing_fmt=<str> - Image format of the base image
1038
+ cluster_size=<size> - qcow2 cluster size
1039
+ compat=<str> - Compatibility level (0.10 or 1.1)
1040
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1041
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1042
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1043
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1044
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1045
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1046
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1047
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1048
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1049
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1050
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1051
+ refcount_bits=<num> - Width of a reference count entry in bits
1052
+ size=<size> - Virtual disk size
1053
1054
Note that not all of these options may be amendable.
1055
1056
Testing: amend -f qcow2 -o ?,cluster_size=4k TEST_DIR/t.qcow2
1057
Creation options for 'qcow2':
1058
-size Virtual disk size
1059
-compat Compatibility level (0.10 or 1.1)
1060
-backing_file File name of a base image
1061
-backing_fmt Image format of the base image
1062
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1063
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
1064
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
1065
-encrypt.cipher-alg Name of encryption cipher algorithm
1066
-encrypt.cipher-mode Name of encryption cipher mode
1067
-encrypt.ivgen-alg Name of IV generator algorithm
1068
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
1069
-encrypt.hash-alg Name of encryption hash algorithm
1070
-encrypt.iter-time Time to spend in PBKDF in milliseconds
1071
-cluster_size qcow2 cluster size
1072
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
1073
-lazy_refcounts Postpone refcount updates
1074
-refcount_bits Width of a reference count entry in bits
1075
+ backing_file=<str> - File name of a base image
1076
+ backing_fmt=<str> - Image format of the base image
1077
+ cluster_size=<size> - qcow2 cluster size
1078
+ compat=<str> - Compatibility level (0.10 or 1.1)
1079
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1080
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1081
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1082
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1083
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1084
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1085
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1086
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1087
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1088
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1089
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1090
+ refcount_bits=<num> - Width of a reference count entry in bits
1091
+ size=<size> - Virtual disk size
1092
1093
Note that not all of these options may be amendable.
1094
1095
Testing: amend -f qcow2 -o cluster_size=4k -o help TEST_DIR/t.qcow2
1096
Creation options for 'qcow2':
1097
-size Virtual disk size
1098
-compat Compatibility level (0.10 or 1.1)
1099
-backing_file File name of a base image
1100
-backing_fmt Image format of the base image
1101
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1102
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
1103
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
1104
-encrypt.cipher-alg Name of encryption cipher algorithm
1105
-encrypt.cipher-mode Name of encryption cipher mode
1106
-encrypt.ivgen-alg Name of IV generator algorithm
1107
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
1108
-encrypt.hash-alg Name of encryption hash algorithm
1109
-encrypt.iter-time Time to spend in PBKDF in milliseconds
1110
-cluster_size qcow2 cluster size
1111
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
1112
-lazy_refcounts Postpone refcount updates
1113
-refcount_bits Width of a reference count entry in bits
1114
+ backing_file=<str> - File name of a base image
1115
+ backing_fmt=<str> - Image format of the base image
1116
+ cluster_size=<size> - qcow2 cluster size
1117
+ compat=<str> - Compatibility level (0.10 or 1.1)
1118
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1119
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1120
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1121
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1122
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1123
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1124
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1125
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1126
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1127
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1128
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1129
+ refcount_bits=<num> - Width of a reference count entry in bits
1130
+ size=<size> - Virtual disk size
1131
1132
Note that not all of these options may be amendable.
1133
1134
Testing: amend -f qcow2 -o cluster_size=4k -o ? TEST_DIR/t.qcow2
1135
Creation options for 'qcow2':
1136
-size Virtual disk size
1137
-compat Compatibility level (0.10 or 1.1)
1138
-backing_file File name of a base image
1139
-backing_fmt Image format of the base image
1140
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1141
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
1142
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
1143
-encrypt.cipher-alg Name of encryption cipher algorithm
1144
-encrypt.cipher-mode Name of encryption cipher mode
1145
-encrypt.ivgen-alg Name of IV generator algorithm
1146
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
1147
-encrypt.hash-alg Name of encryption hash algorithm
1148
-encrypt.iter-time Time to spend in PBKDF in milliseconds
1149
-cluster_size qcow2 cluster size
1150
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
1151
-lazy_refcounts Postpone refcount updates
1152
-refcount_bits Width of a reference count entry in bits
1153
+ backing_file=<str> - File name of a base image
1154
+ backing_fmt=<str> - Image format of the base image
1155
+ cluster_size=<size> - qcow2 cluster size
1156
+ compat=<str> - Compatibility level (0.10 or 1.1)
1157
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1158
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1159
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1160
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1161
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1162
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1163
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1164
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1165
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1166
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1167
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1168
+ refcount_bits=<num> - Width of a reference count entry in bits
1169
+ size=<size> - Virtual disk size
1170
1171
Note that not all of these options may be amendable.
1172
1173
@@ -XXX,XX +XXX,XX @@ qemu-img: Invalid option list: ,,
1174
1175
Testing: amend -f qcow2 -o help
1176
Creation options for 'qcow2':
1177
-size Virtual disk size
1178
-compat Compatibility level (0.10 or 1.1)
1179
-backing_file File name of a base image
1180
-backing_fmt Image format of the base image
1181
-encryption Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1182
-encrypt.format Encrypt the image, format choices: 'aes', 'luks'
1183
-encrypt.key-secret ID of secret providing qcow AES key or LUKS passphrase
1184
-encrypt.cipher-alg Name of encryption cipher algorithm
1185
-encrypt.cipher-mode Name of encryption cipher mode
1186
-encrypt.ivgen-alg Name of IV generator algorithm
1187
-encrypt.ivgen-hash-alg Name of IV generator hash algorithm
1188
-encrypt.hash-alg Name of encryption hash algorithm
1189
-encrypt.iter-time Time to spend in PBKDF in milliseconds
1190
-cluster_size qcow2 cluster size
1191
-preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
1192
-lazy_refcounts Postpone refcount updates
1193
-refcount_bits Width of a reference count entry in bits
1194
+ backing_file=<str> - File name of a base image
1195
+ backing_fmt=<str> - Image format of the base image
1196
+ cluster_size=<size> - qcow2 cluster size
1197
+ compat=<str> - Compatibility level (0.10 or 1.1)
1198
+ encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
1199
+ encrypt.cipher-mode=<str> - Name of encryption cipher mode
1200
+ encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
1201
+ encrypt.hash-alg=<str> - Name of encryption hash algorithm
1202
+ encrypt.iter-time=<num> - Time to spend in PBKDF in milliseconds
1203
+ encrypt.ivgen-alg=<str> - Name of IV generator algorithm
1204
+ encrypt.ivgen-hash-alg=<str> - Name of IV generator hash algorithm
1205
+ encrypt.key-secret=<str> - ID of secret providing qcow AES key or LUKS passphrase
1206
+ encryption=<bool (on/off)> - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes)
1207
+ lazy_refcounts=<bool (on/off)> - Postpone refcount updates
1208
+ preallocation=<str> - Preallocation mode (allowed values: off, metadata, falloc, full)
1209
+ refcount_bits=<num> - Width of a reference count entry in bits
1210
+ size=<size> - Virtual disk size
1211
1212
Note that not all of these options may be amendable.
1213
1214
Testing: convert -o help
1215
Supported options:
1216
-size Virtual disk size
1217
+ size=<size> - Virtual disk size
1218
1219
Testing: amend -f bochs -o help
1220
qemu-img: Format driver 'bochs' does not support option amendment
1221
--
100
--
1222
2.19.1
101
2.20.1
1223
102
1224
103
diff view generated by jsdifflib
1
From: Daniel P. Berrangé <berrange@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
The qcow2 block driver expects to see a valid sector size even when it
3
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
has opened the crypto layer with QCRYPTO_BLOCK_OPEN_NO_IO.
4
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
5
5
Message-Id: <20200218103454.296704-17-mreitz@redhat.com>
6
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
7
Reviewed-by: Alberto Garcia <berto@igalia.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
7
---
10
crypto/block-qcow.c | 2 ++
8
tests/qemu-iotests/041 | 6 ++----
11
1 file changed, 2 insertions(+)
9
1 file changed, 2 insertions(+), 4 deletions(-)
12
10
13
diff --git a/crypto/block-qcow.c b/crypto/block-qcow.c
11
diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
14
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100755
15
--- a/crypto/block-qcow.c
13
--- a/tests/qemu-iotests/041
16
+++ b/crypto/block-qcow.c
14
+++ b/tests/qemu-iotests/041
17
@@ -XXX,XX +XXX,XX @@ qcrypto_block_qcow_open(QCryptoBlock *block,
15
@@ -XXX,XX +XXX,XX @@ class TestRepairQuorum(iotests.QMPTestCase):
18
Error **errp)
16
19
{
17
self.complete_and_wait(drive="job0")
20
if (flags & QCRYPTO_BLOCK_OPEN_NO_IO) {
18
self.assert_has_block_node("repair0", quorum_repair_img)
21
+ block->sector_size = QCRYPTO_BLOCK_QCOW_SECTOR_SIZE;
19
- # TODO: a better test requiring some QEMU infrastructure will be added
22
+ block->payload_offset = 0;
20
- # to check that this file is really driven by quorum
23
return 0;
21
+ self.vm.assert_block_path('quorum0', '/children.1', 'repair0')
24
} else {
22
self.vm.shutdown()
25
if (!options->u.qcow.key_secret) {
23
self.assertTrue(iotests.compare_images(quorum_img2, quorum_repair_img),
24
'target image does not match source after mirroring')
25
@@ -XXX,XX +XXX,XX @@ class TestRepairQuorum(iotests.QMPTestCase):
26
27
self.complete_and_wait('job0')
28
self.assert_has_block_node("repair0", quorum_repair_img)
29
- # TODO: a better test requiring some QEMU infrastructure will be added
30
- # to check that this file is really driven by quorum
31
+ self.vm.assert_block_path('quorum0', '/children.1', 'repair0')
32
33
# Test mirroring with a source that does not have any parents (not even a
34
# BlockBackend)
26
--
35
--
27
2.19.1
36
2.20.1
28
37
29
38
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
Following the example of qemu_opts_print_help(), indent all entries in
3
041's TestRepairQuorum has its own image_len, no need to refer to
4
the list of character devices.
4
TestSingleDrive. (This patch allows commenting out TestSingleDrive to
5
speed up 041 during test testing.)
5
6
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
8
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
Message-Id: <20200218103454.296704-18-mreitz@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
11
---
10
chardev/char.c | 2 +-
12
tests/qemu-iotests/041 | 2 +-
11
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
12
14
13
diff --git a/chardev/char.c b/chardev/char.c
15
diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100755
15
--- a/chardev/char.c
17
--- a/tests/qemu-iotests/041
16
+++ b/chardev/char.c
18
+++ b/tests/qemu-iotests/041
17
@@ -XXX,XX +XXX,XX @@ help_string_append(const char *name, void *opaque)
19
@@ -XXX,XX +XXX,XX @@ class TestRepairQuorum(iotests.QMPTestCase):
18
{
20
# Add each individual quorum images
19
GString *str = opaque;
21
for i in self.IMAGES:
20
22
qemu_img('create', '-f', iotests.imgfmt, i,
21
- g_string_append_printf(str, "\n%s", name);
23
- str(TestSingleDrive.image_len))
22
+ g_string_append_printf(str, "\n %s", name);
24
+ str(self.image_len))
23
}
25
# Assign a node name to each quorum image in order to manipulate
24
26
# them
25
static const char *chardev_alias_translate(const char *name)
27
opts = "node-name=img%i" % self.IMAGES.index(i)
26
--
28
--
27
2.19.1
29
2.20.1
28
30
29
31
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
This patch tests that you can add and remove drives from a Quorum
3
Add two tests to see that you cannot replace a Quorum child with the
4
using the x-blockdev-change command.
4
mirror job while the child is in use by a different parent.
5
5
6
Signed-off-by: Alberto Garcia <berto@igalia.com>
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Message-Id: <20200218103454.296704-19-mreitz@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
10
---
9
tests/qemu-iotests/081 | 86 ++++++++++++++++++++++++++++++++++++++
11
tests/qemu-iotests/041 | 70 +++++++++++++++++++++++++++++++++++++-
10
tests/qemu-iotests/081.out | 54 ++++++++++++++++++++++++
12
tests/qemu-iotests/041.out | 4 +--
11
2 files changed, 140 insertions(+)
13
2 files changed, 71 insertions(+), 3 deletions(-)
12
14
13
diff --git a/tests/qemu-iotests/081 b/tests/qemu-iotests/081
15
diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
14
index XXXXXXX..XXXXXXX 100755
16
index XXXXXXX..XXXXXXX 100755
15
--- a/tests/qemu-iotests/081
17
--- a/tests/qemu-iotests/041
16
+++ b/tests/qemu-iotests/081
18
+++ b/tests/qemu-iotests/041
17
@@ -XXX,XX +XXX,XX @@ quorum="$quorum,file.children.2.driver=raw"
19
@@ -XXX,XX +XXX,XX @@
18
20
19
$QEMU_IO -c "open -o $quorum" | _filter_qemu_io
21
import time
20
22
import os
21
+echo
23
+import re
22
+echo "== dynamically adding a child to a quorum =="
24
import iotests
25
from iotests import qemu_img, qemu_io
26
27
@@ -XXX,XX +XXX,XX @@ quorum_img3 = os.path.join(iotests.test_dir, 'quorum3.img')
28
quorum_repair_img = os.path.join(iotests.test_dir, 'quorum_repair.img')
29
quorum_snapshot_file = os.path.join(iotests.test_dir, 'quorum_snapshot.img')
30
31
+nbd_sock_path = os.path.join(iotests.test_dir, 'nbd.sock')
23
+
32
+
24
+for verify in false true; do
33
class TestSingleDrive(iotests.QMPTestCase):
25
+ run_qemu <<EOF
34
image_len = 1 * 1024 * 1024 # MB
26
+ { "execute": "qmp_capabilities" }
35
qmp_cmd = 'drive-mirror'
27
+ { "execute": "blockdev-add",
36
@@ -XXX,XX +XXX,XX @@ class TestRepairQuorum(iotests.QMPTestCase):
28
+ "arguments": {
37
29
+ "driver": "quorum",
38
def tearDown(self):
30
+ "node-name": "drive0-quorum",
39
self.vm.shutdown()
31
+ "vote-threshold": 2,
40
- for i in self.IMAGES + [ quorum_repair_img, quorum_snapshot_file ]:
32
+ "blkverify": ${verify},
41
+ for i in self.IMAGES + [ quorum_repair_img, quorum_snapshot_file,
33
+ "children": [
42
+ nbd_sock_path ]:
34
+ {
43
# Do a try/except because the test may have deleted some images
35
+ "driver": "$IMGFMT",
44
try:
36
+ "file": {
45
os.remove(i)
37
+ "driver": "file",
46
@@ -XXX,XX +XXX,XX @@ class TestRepairQuorum(iotests.QMPTestCase):
38
+ "filename": "$TEST_DIR/1.raw"
47
self.assert_has_block_node("repair0", quorum_repair_img)
39
+ }
48
self.vm.assert_block_path('quorum0', '/children.1', 'repair0')
40
+ },
49
41
+ {
50
+ def test_with_other_parent(self):
42
+ "driver": "$IMGFMT",
51
+ """
43
+ "file": {
52
+ Check that we cannot replace a Quorum child when it has other
44
+ "driver": "file",
53
+ parents.
45
+ "filename": "$TEST_DIR/2.raw"
54
+ """
46
+ }
55
+ result = self.vm.qmp('nbd-server-start',
47
+ }
56
+ addr={
48
+ ]
57
+ 'type': 'unix',
49
+ }
58
+ 'data': {'path': nbd_sock_path}
50
+ }
59
+ })
51
+ { "execute": "blockdev-add",
60
+ self.assert_qmp(result, 'return', {})
52
+ "arguments": {
53
+ "node-name": "drive3",
54
+ "driver": "$IMGFMT",
55
+ "file": {
56
+ "driver": "file",
57
+ "filename": "$TEST_DIR/2.raw"
58
+ }
59
+ }
60
+ }
61
+ { "execute": "x-blockdev-change",
62
+ "arguments": { "parent": "drive0-quorum",
63
+ "node": "drive3" } }
64
+ { "execute": "quit" }
65
+EOF
66
+done
67
+
61
+
68
+echo
62
+ result = self.vm.qmp('nbd-server-add', device='img1')
69
+echo "== dynamically removing a child from a quorum =="
63
+ self.assert_qmp(result, 'return', {})
70
+
64
+
71
+for verify in false true; do
65
+ result = self.vm.qmp('drive-mirror', job_id='mirror', device='quorum0',
72
+ for vote_threshold in 1 2; do
66
+ sync='full', node_name='repair0', replaces='img1',
73
+ run_qemu <<EOF
67
+ target=quorum_repair_img, format=iotests.imgfmt)
74
+ { "execute": "qmp_capabilities" }
68
+ self.assert_qmp(result, 'error/desc',
75
+ { "execute": "blockdev-add",
69
+ "Cannot replace 'img1' by a node mirrored from "
76
+ "arguments": {
70
+ "'quorum0', because it cannot be guaranteed that doing "
77
+ "driver": "quorum",
71
+ "so would not lead to an abrupt change of visible data")
78
+ "node-name": "drive0-quorum",
79
+ "vote-threshold": ${vote_threshold},
80
+ "blkverify": ${verify},
81
+ "children": [
82
+ {
83
+ "driver": "$IMGFMT",
84
+ "file": {
85
+ "driver": "file",
86
+ "filename": "$TEST_DIR/1.raw"
87
+ }
88
+ },
89
+ {
90
+ "driver": "$IMGFMT",
91
+ "file": {
92
+ "driver": "file",
93
+ "filename": "$TEST_DIR/2.raw"
94
+ }
95
+ }
96
+ ]
97
+ }
98
+ }
99
+ { "execute": "x-blockdev-change",
100
+ "arguments": { "parent": "drive0-quorum",
101
+ "child": "children.1" } }
102
+ { "execute": "quit" }
103
+EOF
104
+ done
105
+done
106
+
72
+
107
# success, all done
73
+ def test_with_other_parents_after_mirror_start(self):
108
echo "*** done"
74
+ """
109
rm -f $seq.full
75
+ The same as test_with_other_parent(), but add the NBD server
110
diff --git a/tests/qemu-iotests/081.out b/tests/qemu-iotests/081.out
76
+ only when the mirror job is already running.
111
index XXXXXXX..XXXXXXX 100644
77
+ """
112
--- a/tests/qemu-iotests/081.out
78
+ result = self.vm.qmp('nbd-server-start',
113
+++ b/tests/qemu-iotests/081.out
79
+ addr={
114
@@ -XXX,XX +XXX,XX @@ read 10485760/10485760 bytes at offset 0
80
+ 'type': 'unix',
115
81
+ 'data': {'path': nbd_sock_path}
116
== checking the blkverify mode with invalid settings ==
82
+ })
117
can't open: blkverify=on can only be set if there are exactly two files and vote-threshold is 2
83
+ self.assert_qmp(result, 'return', {})
118
+
84
+
119
+== dynamically adding a child to a quorum ==
85
+ result = self.vm.qmp('drive-mirror', job_id='mirror', device='quorum0',
120
+Testing:
86
+ sync='full', node_name='repair0', replaces='img1',
121
+QMP_VERSION
87
+ target=quorum_repair_img, format=iotests.imgfmt)
122
+{"return": {}}
88
+ self.assert_qmp(result, 'return', {})
123
+{"return": {}}
124
+{"return": {}}
125
+{"return": {}}
126
+{"return": {}}
127
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
128
+
89
+
129
+Testing:
90
+ result = self.vm.qmp('nbd-server-add', device='img1')
130
+QMP_VERSION
91
+ self.assert_qmp(result, 'return', {})
131
+{"return": {}}
92
+
132
+{"return": {}}
93
+ # The full error message goes to stderr, we will check it later
133
+{"return": {}}
94
+ self.complete_and_wait('mirror',
134
+{"error": {"class": "GenericError", "desc": "Cannot add a child to a quorum in blkverify mode"}}
95
+ completion_error='Operation not permitted')
135
+{"return": {}}
96
+
136
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
97
+ # Should not have been replaced
98
+ self.vm.assert_block_path('quorum0', '/children.1', 'img1')
99
+
100
+ # Check the full error message now
101
+ self.vm.shutdown()
102
+ log = self.vm.get_log()
103
+ log = re.sub(r'^\[I \d+\.\d+\] OPENED\n', '', log)
104
+ log = re.sub(r'^Formatting.*\n', '', log)
105
+ log = re.sub(r'\n\[I \+\d+\.\d+\] CLOSED\n?$', '', log)
106
+ log = re.sub(r'^%s: ' % os.path.basename(iotests.qemu_prog), '', log)
107
+
108
+ self.assertEqual(log,
109
+ "Can no longer replace 'img1' by 'repair0', because " +
110
+ "it can no longer be guaranteed that doing so would " +
111
+ "not lead to an abrupt change of visible data")
137
+
112
+
138
+
113
+
139
+== dynamically removing a child from a quorum ==
114
# Test mirroring with a source that does not have any parents (not even a
140
+Testing:
115
# BlockBackend)
141
+QMP_VERSION
116
class TestOrphanedSource(iotests.QMPTestCase):
142
+{"return": {}}
117
diff --git a/tests/qemu-iotests/041.out b/tests/qemu-iotests/041.out
143
+{"return": {}}
118
index XXXXXXX..XXXXXXX 100644
144
+{"return": {}}
119
--- a/tests/qemu-iotests/041.out
145
+{"return": {}}
120
+++ b/tests/qemu-iotests/041.out
146
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
121
@@ -XXX,XX +XXX,XX @@
147
+
122
-...........................................................................................
148
+Testing:
123
+.............................................................................................
149
+QMP_VERSION
124
----------------------------------------------------------------------
150
+{"return": {}}
125
-Ran 91 tests
151
+{"return": {}}
126
+Ran 93 tests
152
+{"error": {"class": "GenericError", "desc": "The number of children cannot be lower than the vote threshold 2"}}
127
153
+{"return": {}}
128
OK
154
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
155
+
156
+Testing:
157
+QMP_VERSION
158
+{"return": {}}
159
+{"error": {"class": "GenericError", "desc": "blkverify=on can only be set if there are exactly two files and vote-threshold is 2"}}
160
+{"error": {"class": "GenericError", "desc": "Cannot find device=drive0-quorum nor node_name=drive0-quorum"}}
161
+{"return": {}}
162
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
163
+
164
+Testing:
165
+QMP_VERSION
166
+{"return": {}}
167
+{"return": {}}
168
+{"error": {"class": "GenericError", "desc": "The number of children cannot be lower than the vote threshold 2"}}
169
+{"return": {}}
170
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
171
+
172
*** done
173
--
129
--
174
2.19.1
130
2.20.1
175
131
176
132
diff view generated by jsdifflib
1
From: Peter Maydell <peter.maydell@linaro.org>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
Taking the address of a field in a packed struct is a bad idea, because
3
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
it might not be actually aligned enough for that pointer type (and
4
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
5
thus cause a crash on dereference on some host architectures). Newer
5
Message-Id: <20200218103454.296704-20-mreitz@redhat.com>
6
versions of clang warn about this. Avoid the bug by not using the
7
"modify in place" byte swapping functions.
8
9
There are a few places where the in-place swap function is
10
used on something other than a packed struct field; we convert
11
those anyway, for consistency.
12
13
This patch was produced with the following spatch script:
14
15
@@
16
expression E;
17
@@
18
-be16_to_cpus(&E);
19
+E = be16_to_cpu(E);
20
@@
21
expression E;
22
@@
23
-be32_to_cpus(&E);
24
+E = be32_to_cpu(E);
25
@@
26
expression E;
27
@@
28
-be64_to_cpus(&E);
29
+E = be64_to_cpu(E);
30
@@
31
expression E;
32
@@
33
-cpu_to_be16s(&E);
34
+E = cpu_to_be16(E);
35
@@
36
expression E;
37
@@
38
-cpu_to_be32s(&E);
39
+E = cpu_to_be32(E);
40
@@
41
expression E;
42
@@
43
-cpu_to_be64s(&E);
44
+E = cpu_to_be64(E);
45
46
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
47
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
48
Tested-by: John Snow <jsnow@redhat.com>
49
Reviewed-by: John Snow <jsnow@redhat.com>
50
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
51
---
7
---
52
block/qcow.c | 18 +++++++++---------
8
tests/qemu-iotests/041 | 46 ++++++++++++++++++++++++++++++++++++++
53
1 file changed, 9 insertions(+), 9 deletions(-)
9
tests/qemu-iotests/041.out | 4 ++--
10
2 files changed, 48 insertions(+), 2 deletions(-)
54
11
55
diff --git a/block/qcow.c b/block/qcow.c
12
diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
13
index XXXXXXX..XXXXXXX 100755
14
--- a/tests/qemu-iotests/041
15
+++ b/tests/qemu-iotests/041
16
@@ -XXX,XX +XXX,XX @@ class TestOrphanedSource(iotests.QMPTestCase):
17
self.assertFalse('mirror-filter' in nodes,
18
'Mirror filter node did not disappear')
19
20
+# Test cases for @replaces that do not necessarily involve Quorum
21
+class TestReplaces(iotests.QMPTestCase):
22
+ # Each of these test cases needs their own block graph, so do not
23
+ # create any nodes here
24
+ def setUp(self):
25
+ self.vm = iotests.VM()
26
+ self.vm.launch()
27
+
28
+ def tearDown(self):
29
+ self.vm.shutdown()
30
+ for img in (test_img, target_img):
31
+ try:
32
+ os.remove(img)
33
+ except OSError:
34
+ pass
35
+
36
+ @iotests.skip_if_unsupported(['copy-on-read'])
37
+ def test_replace_filter(self):
38
+ """
39
+ Check that we can replace filter nodes.
40
+ """
41
+ result = self.vm.qmp('blockdev-add', **{
42
+ 'driver': 'copy-on-read',
43
+ 'node-name': 'filter0',
44
+ 'file': {
45
+ 'driver': 'copy-on-read',
46
+ 'node-name': 'filter1',
47
+ 'file': {
48
+ 'driver': 'null-co'
49
+ }
50
+ }
51
+ })
52
+ self.assert_qmp(result, 'return', {})
53
+
54
+ result = self.vm.qmp('blockdev-add',
55
+ node_name='target', driver='null-co')
56
+ self.assert_qmp(result, 'return', {})
57
+
58
+ result = self.vm.qmp('blockdev-mirror', job_id='mirror', device='filter0',
59
+ target='target', sync='full', replaces='filter1')
60
+ self.assert_qmp(result, 'return', {})
61
+
62
+ self.complete_and_wait('mirror')
63
+
64
+ self.vm.assert_block_path('filter0', '/file', 'target')
65
+
66
if __name__ == '__main__':
67
iotests.main(supported_fmts=['qcow2', 'qed'],
68
supported_protocols=['file'],
69
diff --git a/tests/qemu-iotests/041.out b/tests/qemu-iotests/041.out
56
index XXXXXXX..XXXXXXX 100644
70
index XXXXXXX..XXXXXXX 100644
57
--- a/block/qcow.c
71
--- a/tests/qemu-iotests/041.out
58
+++ b/block/qcow.c
72
+++ b/tests/qemu-iotests/041.out
59
@@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
73
@@ -XXX,XX +XXX,XX @@
60
if (ret < 0) {
74
-.............................................................................................
61
goto fail;
75
+..............................................................................................
62
}
76
----------------------------------------------------------------------
63
- be32_to_cpus(&header.magic);
77
-Ran 93 tests
64
- be32_to_cpus(&header.version);
78
+Ran 94 tests
65
- be64_to_cpus(&header.backing_file_offset);
79
66
- be32_to_cpus(&header.backing_file_size);
80
OK
67
- be32_to_cpus(&header.mtime);
68
- be64_to_cpus(&header.size);
69
- be32_to_cpus(&header.crypt_method);
70
- be64_to_cpus(&header.l1_table_offset);
71
+ header.magic = be32_to_cpu(header.magic);
72
+ header.version = be32_to_cpu(header.version);
73
+ header.backing_file_offset = be64_to_cpu(header.backing_file_offset);
74
+ header.backing_file_size = be32_to_cpu(header.backing_file_size);
75
+ header.mtime = be32_to_cpu(header.mtime);
76
+ header.size = be64_to_cpu(header.size);
77
+ header.crypt_method = be32_to_cpu(header.crypt_method);
78
+ header.l1_table_offset = be64_to_cpu(header.l1_table_offset);
79
80
if (header.magic != QCOW_MAGIC) {
81
error_setg(errp, "Image not in qcow format");
82
@@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
83
}
84
85
for(i = 0;i < s->l1_size; i++) {
86
- be64_to_cpus(&s->l1_table[i]);
87
+ s->l1_table[i] = be64_to_cpu(s->l1_table[i]);
88
}
89
90
/* alloc L2 cache (max. 64k * 16 * 8 = 8 MB) */
91
--
81
--
92
2.19.1
82
2.20.1
93
83
94
84
diff view generated by jsdifflib