1
The following changes since commit 22d96eac64877c4d96f9928babb6f2fcc68faacf:
1
The following changes since commit ccdf06c1db192152ac70a1dd974c624f566cb7d4:
2
2
3
Merge remote-tracking branch 'remotes/stefanha/tags/tracing-pull-request' into staging (2019-04-29 19:11:15 +0100)
3
Open 6.1 development tree (2021-04-30 11:15:40 +0100)
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 54277a2aab876aba7b55c7e88e2b372691849741:
9
for you to fetch changes up to 68bf7336533faa6aa90fdd4558edddbf5d8ef814:
10
10
11
block/qed: add missed coroutine_fn markers (2019-04-30 15:29:00 +0200)
11
vhost-user-blk: Fail gracefully on too large queue size (2021-04-30 12:27:48 +0200)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block layer patches:
14
Block layer patches
15
15
16
- iotests: Fix output of qemu-io related tests
16
- Fix permission update order problems with block graph changes
17
- Don't ignore bdrv_set_aio_context() for nodes with bs->drv = NUL
17
- qemu-img convert: Unshare write permission for source
18
- vmdk: Set vmdk parent backing_format to vmdk
18
- vhost-user-blk: Fail gracefully on too large queue size
19
- qcow2: Preallocation fixes (especially for external data files)
20
- Add linear-buffer-based APIs (as wrappers around qiov-based ones)
21
- Various code cleanups and small corner case fixes
22
19
23
----------------------------------------------------------------
20
----------------------------------------------------------------
24
Alberto Garcia (3):
21
Kevin Wolf (3):
25
qcow2: Fix error handling in the compression code
22
block: Add BDRV_O_NO_SHARE for blk_new_open()
26
commit: Make base read-only if there is an early failure
23
qemu-img convert: Unshare write permission for source
27
iotests: Check that images are in read-only mode after block-commit
24
vhost-user-blk: Fail gracefully on too large queue size
28
25
29
Eric Blake (2):
26
Vladimir Sementsov-Ogievskiy (36):
30
cutils: Fix size_to_str() on 32-bit platforms
27
tests/test-bdrv-graph-mod: add test_parallel_exclusive_write
31
qemu-img: Saner printing of large file sizes
28
tests/test-bdrv-graph-mod: add test_parallel_perm_update
29
tests/test-bdrv-graph-mod: add test_append_greedy_filter
30
block: bdrv_append(): don't consume reference
31
block: BdrvChildClass: add .get_parent_aio_context handler
32
block: drop ctx argument from bdrv_root_attach_child
33
block: make bdrv_reopen_{prepare,commit,abort} private
34
util: add transactions.c
35
block: bdrv_refresh_perms: check for parents permissions conflict
36
block: refactor bdrv_child* permission functions
37
block: rewrite bdrv_child_try_set_perm() using bdrv_refresh_perms()
38
block: inline bdrv_child_*() permission functions calls
39
block: use topological sort for permission update
40
block: add bdrv_drv_set_perm transaction action
41
block: add bdrv_list_* permission update functions
42
block: add bdrv_replace_child_safe() transaction action
43
block: fix bdrv_replace_node_common
44
block: add bdrv_attach_child_common() transaction action
45
block: add bdrv_attach_child_noperm() transaction action
46
block: split out bdrv_replace_node_noperm()
47
block: adapt bdrv_append() for inserting filters
48
block: add bdrv_remove_filter_or_cow transaction action
49
block: introduce bdrv_drop_filter()
50
block/backup-top: drop .active
51
block: drop ignore_children for permission update functions
52
block: make bdrv_unset_inherits_from to be a transaction action
53
block: make bdrv_refresh_limits() to be a transaction action
54
block: add bdrv_set_backing_noperm() transaction action
55
block: bdrv_reopen_multiple(): move bdrv_flush to separate pre-prepare
56
block: bdrv_reopen_multiple: refresh permissions on updated graph
57
block: drop unused permission update functions
58
block: inline bdrv_check_perm_common()
59
block: inline bdrv_replace_child()
60
block: refactor bdrv_child_set_perm_safe() transaction action
61
block: rename bdrv_replace_child_safe() to bdrv_replace_child()
62
block: refactor bdrv_node_check_perm()
32
63
33
Kevin Wolf (5):
64
include/block/block.h | 14 +-
34
block: Fix AioContext switch for bs->drv == NULL
65
include/block/block_int.h | 8 +-
35
qcow2: Avoid COW during metadata preallocation
66
include/qemu/transactions.h | 63 ++
36
qcow2: Add errp to preallocate_co()
67
block.c | 1329 ++++++++++++++++++++-------------
37
qcow2: Fix full preallocation with external data file
68
block/backup-top.c | 48 +-
38
qcow2: Fix qcow2_make_empty() with external data file
69
block/block-backend.c | 30 +-
70
block/commit.c | 1 +
71
block/file-posix.c | 91 +--
72
block/io.c | 31 +-
73
block/mirror.c | 3 -
74
blockdev.c | 4 -
75
blockjob.c | 11 +-
76
hw/block/vhost-user-blk.c | 5 +
77
qemu-img.c | 2 +-
78
tests/unit/test-bdrv-drain.c | 2 +-
79
tests/unit/test-bdrv-graph-mod.c | 209 +++++-
80
util/transactions.c | 96 +++
81
MAINTAINERS | 6 +
82
tests/qemu-iotests/245 | 2 +-
83
tests/qemu-iotests/283.out | 2 +-
84
tests/qemu-iotests/tests/qsd-jobs.out | 2 +-
85
util/meson.build | 1 +
86
22 files changed, 1280 insertions(+), 680 deletions(-)
87
create mode 100644 include/qemu/transactions.h
88
create mode 100644 util/transactions.c
39
89
40
Max Reitz (2):
41
iotests: Perform the correct test in 082
42
qemu-img: Make create hint at protocol options
43
90
44
Sam Eiderman (1):
45
vmdk: Set vmdk parent backing_format to vmdk
46
47
Stefano Garzarella (2):
48
block/vhdx: Remove redundant IEC binary prefixes definition
49
block/vhdx: Use IEC binary prefixes for size constants
50
51
Thomas Huth (1):
52
tests/qemu-iotests: Fix output of qemu-io related tests
53
54
Vladimir Sementsov-Ogievskiy (10):
55
block: introduce byte-based io helpers
56
block/qcow2: use buffer-based io
57
block/qcow: use buffer-based io
58
block/qed: use buffer-based io
59
block/parallels: use buffer-based io
60
block/backup: use buffer-based io
61
block/commit: use buffer-based io
62
block/stream: use buffer-based io
63
qemu-img: use buffer-based io
64
block/qed: add missed coroutine_fn markers
65
66
Zhengui li (1):
67
vpc: unlock Coroutine lock to make IO submit Concurrently
68
69
block/qed.h | 28 ++++---
70
block/vhdx.h | 16 ++--
71
include/block/block_int.h | 16 ++++
72
include/sysemu/block-backend.h | 19 +++++
73
block.c | 12 +--
74
block/backup.c | 14 ++--
75
block/commit.c | 8 +-
76
block/parallels.c | 14 ++--
77
block/qapi.c | 49 +++---------
78
block/qcow.c | 19 ++---
79
block/qcow2.c | 80 ++++++++++----------
80
block/qed-check.c | 4 +-
81
block/qed-table.c | 45 ++++++-----
82
block/qed.c | 11 ++-
83
block/stream.c | 4 +-
84
block/vhdx-log.c | 2 +-
85
block/vhdx.c | 7 +-
86
block/vmdk.c | 2 +
87
block/vpc.c | 4 +
88
qemu-img.c | 26 ++++---
89
util/cutils.c | 2 +-
90
tests/qemu-iotests/026.out | 168 ++++++++++++++++++++---------------------
91
tests/qemu-iotests/043.out | 6 +-
92
tests/qemu-iotests/053.out | 2 +-
93
tests/qemu-iotests/059.out | 10 +--
94
tests/qemu-iotests/060.out | 16 ++--
95
tests/qemu-iotests/061.out | 12 +--
96
tests/qemu-iotests/069.out | 2 +-
97
tests/qemu-iotests/070.out | 4 +-
98
tests/qemu-iotests/075.out | 14 ++--
99
tests/qemu-iotests/076.out | 6 +-
100
tests/qemu-iotests/078.out | 12 +--
101
tests/qemu-iotests/080.out | 40 +++++-----
102
tests/qemu-iotests/081.out | 2 +-
103
tests/qemu-iotests/082 | 5 +-
104
tests/qemu-iotests/082.out | 51 ++++++++-----
105
tests/qemu-iotests/084.out | 8 +-
106
tests/qemu-iotests/088.out | 12 +--
107
tests/qemu-iotests/089.out | 2 +-
108
tests/qemu-iotests/095.out | 4 +-
109
tests/qemu-iotests/103.out | 14 ++--
110
tests/qemu-iotests/104.out | 6 +-
111
tests/qemu-iotests/110.out | 6 +-
112
tests/qemu-iotests/114.out | 4 +-
113
tests/qemu-iotests/116.out | 14 ++--
114
tests/qemu-iotests/126.out | 4 +-
115
tests/qemu-iotests/130.out | 10 +--
116
tests/qemu-iotests/131.out | 2 +-
117
tests/qemu-iotests/133.out | 30 ++++----
118
tests/qemu-iotests/137.out | 28 +++----
119
tests/qemu-iotests/140.out | 2 +-
120
tests/qemu-iotests/143.out | 2 +-
121
tests/qemu-iotests/153.out | 32 ++++----
122
tests/qemu-iotests/187.out | 6 +-
123
tests/qemu-iotests/188.out | 2 +-
124
tests/qemu-iotests/191.out | 8 +-
125
tests/qemu-iotests/195.out | 4 +-
126
tests/qemu-iotests/197.out | 2 +-
127
tests/qemu-iotests/198.out | 4 +-
128
tests/qemu-iotests/205 | 2 +-
129
tests/qemu-iotests/206.out | 10 +--
130
tests/qemu-iotests/207.out | 12 +--
131
tests/qemu-iotests/210.out | 8 +-
132
tests/qemu-iotests/211.out | 10 +--
133
tests/qemu-iotests/212.out | 10 +--
134
tests/qemu-iotests/213.out | 10 +--
135
tests/qemu-iotests/215.out | 2 +-
136
tests/qemu-iotests/226.out | 16 ++--
137
tests/qemu-iotests/233.out | 4 +-
138
tests/qemu-iotests/237.out | 22 +++---
139
tests/qemu-iotests/242.out | 10 +--
140
tests/qemu-iotests/244.out | 10 +--
141
tests/qemu-iotests/249 | 115 ++++++++++++++++++++++++++++
142
tests/qemu-iotests/249.out | 35 +++++++++
143
tests/qemu-iotests/group | 1 +
144
75 files changed, 696 insertions(+), 519 deletions(-)
145
create mode 100755 tests/qemu-iotests/249
146
create mode 100644 tests/qemu-iotests/249.out
147
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
3
Add the test that shows that concept of ignore_children is incomplete.
4
Actually, when we want to update something, ignoring permission of some
5
existing BdrvChild, we should ignore also the propagated effect of this
6
child to the other children. But that's not done. Better approach
7
(update permissions on already updated graph) will be implemented
8
later.
9
10
Now the test fails, so it's added with -d argument to not break make
11
check.
12
13
Test fails with
14
15
"Conflicts with use by fl1 as 'backing', which does not allow 'write' on base"
16
17
because when updating permissions we can ignore original top->fl1
18
BdrvChild. But we don't ignore exclusive write permission in fl1->base
19
BdrvChild, which is propagated. Correct thing to do is make graph
20
change first and then do permission update from the top node.
21
22
To run test do
23
24
./test-bdrv-graph-mod -d -p /bdrv-graph-mod/parallel-exclusive-write
25
26
from <build-directory>/tests.
27
28
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
29
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
30
Message-Id: <20210428151804.439460-2-vsementsov@virtuozzo.com>
31
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
32
---
33
tests/unit/test-bdrv-graph-mod.c | 70 +++++++++++++++++++++++++++++++-
34
1 file changed, 69 insertions(+), 1 deletion(-)
35
36
diff --git a/tests/unit/test-bdrv-graph-mod.c b/tests/unit/test-bdrv-graph-mod.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/tests/unit/test-bdrv-graph-mod.c
39
+++ b/tests/unit/test-bdrv-graph-mod.c
40
@@ -XXX,XX +XXX,XX @@
41
/*
42
* Block node graph modifications tests
43
*
44
- * Copyright (c) 2019 Virtuozzo International GmbH. All rights reserved.
45
+ * Copyright (c) 2019-2021 Virtuozzo International GmbH. All rights reserved.
46
*
47
* This program is free software; you can redistribute it and/or modify
48
* it under the terms of the GNU General Public License as published by
49
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_no_perm = {
50
.bdrv_child_perm = no_perm_default_perms,
51
};
52
53
+static void exclusive_write_perms(BlockDriverState *bs, BdrvChild *c,
54
+ BdrvChildRole role,
55
+ BlockReopenQueue *reopen_queue,
56
+ uint64_t perm, uint64_t shared,
57
+ uint64_t *nperm, uint64_t *nshared)
58
+{
59
+ *nperm = BLK_PERM_WRITE;
60
+ *nshared = BLK_PERM_ALL & ~BLK_PERM_WRITE;
61
+}
62
+
63
+static BlockDriver bdrv_exclusive_writer = {
64
+ .format_name = "exclusive-writer",
65
+ .bdrv_child_perm = exclusive_write_perms,
66
+};
67
+
68
static BlockDriverState *no_perm_node(const char *name)
69
{
70
return bdrv_new_open_driver(&bdrv_no_perm, name, BDRV_O_RDWR, &error_abort);
71
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *pass_through_node(const char *name)
72
BDRV_O_RDWR, &error_abort);
73
}
74
75
+static BlockDriverState *exclusive_writer_node(const char *name)
76
+{
77
+ return bdrv_new_open_driver(&bdrv_exclusive_writer, name,
78
+ BDRV_O_RDWR, &error_abort);
79
+}
80
+
81
/*
82
* test_update_perm_tree
83
*
84
@@ -XXX,XX +XXX,XX @@ static void test_should_update_child(void)
85
blk_unref(root);
86
}
87
88
+/*
89
+ * test_parallel_exclusive_write
90
+ *
91
+ * Check that when we replace node, old permissions of the node being removed
92
+ * doesn't break the replacement.
93
+ */
94
+static void test_parallel_exclusive_write(void)
95
+{
96
+ BlockDriverState *top = exclusive_writer_node("top");
97
+ BlockDriverState *base = no_perm_node("base");
98
+ BlockDriverState *fl1 = pass_through_node("fl1");
99
+ BlockDriverState *fl2 = pass_through_node("fl2");
100
+
101
+ /*
102
+ * bdrv_attach_child() eats child bs reference, so we need two @base
103
+ * references for two filters:
104
+ */
105
+ bdrv_ref(base);
106
+
107
+ bdrv_attach_child(top, fl1, "backing", &child_of_bds, BDRV_CHILD_DATA,
108
+ &error_abort);
109
+ bdrv_attach_child(fl1, base, "backing", &child_of_bds, BDRV_CHILD_FILTERED,
110
+ &error_abort);
111
+ bdrv_attach_child(fl2, base, "backing", &child_of_bds, BDRV_CHILD_FILTERED,
112
+ &error_abort);
113
+
114
+ bdrv_replace_node(fl1, fl2, &error_abort);
115
+
116
+ bdrv_unref(fl2);
117
+ bdrv_unref(top);
118
+}
119
+
120
int main(int argc, char *argv[])
121
{
122
+ int i;
123
+ bool debug = false;
124
+
125
+ for (i = 1; i < argc; i++) {
126
+ if (!strcmp(argv[i], "-d")) {
127
+ debug = true;
128
+ break;
129
+ }
130
+ }
131
+
132
bdrv_init();
133
qemu_init_main_loop(&error_abort);
134
135
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
136
g_test_add_func("/bdrv-graph-mod/should-update-child",
137
test_should_update_child);
138
139
+ if (debug) {
140
+ g_test_add_func("/bdrv-graph-mod/parallel-exclusive-write",
141
+ test_parallel_exclusive_write);
142
+ }
143
+
144
return g_test_run();
145
}
146
--
147
2.30.2
148
149
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
3
Add test to show that simple DFS recursion order is not correct for
4
permission update. Correct order is topological-sort order, which will
5
be introduced later.
6
7
Consider the block driver which has two filter children: one active
8
with exclusive write access and one inactive with no specific
9
permissions.
10
11
And, these two children has a common base child, like this:
12
13
┌─────┐ ┌──────┐
14
│ fl2 │ ◀── │ top │
15
└─────┘ └──────┘
16
│ │
17
│ │ w
18
│ ▼
19
│ ┌──────┐
20
│ │ fl1 │
21
│ └──────┘
22
│ │
23
│ │ w
24
│ ▼
25
│ ┌──────┐
26
└───────▶ │ base │
27
└──────┘
28
29
So, exclusive write is propagated.
30
31
Assume, we want to make fl2 active instead of fl1.
32
So, we set some option for top driver and do permission update.
33
34
If permission update (remember, it's DFS) goes first through
35
top->fl1->base branch it will succeed: it firstly drop exclusive write
36
permissions and than apply them for another BdrvChildren.
37
But if permission update goes first through top->fl2->base branch it
38
will fail, as when we try to update fl2->base child, old not yet
39
updated fl1->base child will be in conflict.
40
41
Now test fails, so it runs only with -d flag. To run do
42
43
./test-bdrv-graph-mod -d -p /bdrv-graph-mod/parallel-perm-update
44
45
from <build-directory>/tests.
46
47
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
48
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
49
Message-Id: <20210428151804.439460-3-vsementsov@virtuozzo.com>
50
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
51
---
52
tests/unit/test-bdrv-graph-mod.c | 116 +++++++++++++++++++++++++++++++
53
1 file changed, 116 insertions(+)
54
55
diff --git a/tests/unit/test-bdrv-graph-mod.c b/tests/unit/test-bdrv-graph-mod.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/tests/unit/test-bdrv-graph-mod.c
58
+++ b/tests/unit/test-bdrv-graph-mod.c
59
@@ -XXX,XX +XXX,XX @@ static void test_parallel_exclusive_write(void)
60
bdrv_unref(top);
61
}
62
63
+static void write_to_file_perms(BlockDriverState *bs, BdrvChild *c,
64
+ BdrvChildRole role,
65
+ BlockReopenQueue *reopen_queue,
66
+ uint64_t perm, uint64_t shared,
67
+ uint64_t *nperm, uint64_t *nshared)
68
+{
69
+ if (bs->file && c == bs->file) {
70
+ *nperm = BLK_PERM_WRITE;
71
+ *nshared = BLK_PERM_ALL & ~BLK_PERM_WRITE;
72
+ } else {
73
+ *nperm = 0;
74
+ *nshared = BLK_PERM_ALL;
75
+ }
76
+}
77
+
78
+static BlockDriver bdrv_write_to_file = {
79
+ .format_name = "tricky-perm",
80
+ .bdrv_child_perm = write_to_file_perms,
81
+};
82
+
83
+
84
+/*
85
+ * The following test shows that topological-sort order is required for
86
+ * permission update, simple DFS is not enough.
87
+ *
88
+ * Consider the block driver which has two filter children: one active
89
+ * with exclusive write access and one inactive with no specific
90
+ * permissions.
91
+ *
92
+ * And, these two children has a common base child, like this:
93
+ *
94
+ * ┌─────┐ ┌──────┐
95
+ * │ fl2 │ ◀── │ top │
96
+ * └─────┘ └──────┘
97
+ * │ │
98
+ * │ │ w
99
+ * │ ▼
100
+ * │ ┌──────┐
101
+ * │ │ fl1 │
102
+ * │ └──────┘
103
+ * │ │
104
+ * │ │ w
105
+ * │ ▼
106
+ * │ ┌──────┐
107
+ * └───────▶ │ base │
108
+ * └──────┘
109
+ *
110
+ * So, exclusive write is propagated.
111
+ *
112
+ * Assume, we want to make fl2 active instead of fl1.
113
+ * So, we set some option for top driver and do permission update.
114
+ *
115
+ * With simple DFS, if permission update goes first through
116
+ * top->fl1->base branch it will succeed: it firstly drop exclusive write
117
+ * permissions and than apply them for another BdrvChildren.
118
+ * But if permission update goes first through top->fl2->base branch it
119
+ * will fail, as when we try to update fl2->base child, old not yet
120
+ * updated fl1->base child will be in conflict.
121
+ *
122
+ * With topological-sort order we always update parents before children, so fl1
123
+ * and fl2 are both updated when we update base and there is no conflict.
124
+ */
125
+static void test_parallel_perm_update(void)
126
+{
127
+ BlockDriverState *top = no_perm_node("top");
128
+ BlockDriverState *tricky =
129
+ bdrv_new_open_driver(&bdrv_write_to_file, "tricky", BDRV_O_RDWR,
130
+ &error_abort);
131
+ BlockDriverState *base = no_perm_node("base");
132
+ BlockDriverState *fl1 = pass_through_node("fl1");
133
+ BlockDriverState *fl2 = pass_through_node("fl2");
134
+ BdrvChild *c_fl1, *c_fl2;
135
+
136
+ /*
137
+ * bdrv_attach_child() eats child bs reference, so we need two @base
138
+ * references for two filters:
139
+ */
140
+ bdrv_ref(base);
141
+
142
+ bdrv_attach_child(top, tricky, "file", &child_of_bds, BDRV_CHILD_DATA,
143
+ &error_abort);
144
+ c_fl1 = bdrv_attach_child(tricky, fl1, "first", &child_of_bds,
145
+ BDRV_CHILD_FILTERED, &error_abort);
146
+ c_fl2 = bdrv_attach_child(tricky, fl2, "second", &child_of_bds,
147
+ BDRV_CHILD_FILTERED, &error_abort);
148
+ bdrv_attach_child(fl1, base, "backing", &child_of_bds, BDRV_CHILD_FILTERED,
149
+ &error_abort);
150
+ bdrv_attach_child(fl2, base, "backing", &child_of_bds, BDRV_CHILD_FILTERED,
151
+ &error_abort);
152
+
153
+ /* Select fl1 as first child to be active */
154
+ tricky->file = c_fl1;
155
+ bdrv_child_refresh_perms(top, top->children.lh_first, &error_abort);
156
+
157
+ assert(c_fl1->perm & BLK_PERM_WRITE);
158
+ assert(!(c_fl2->perm & BLK_PERM_WRITE));
159
+
160
+ /* Now, try to switch active child and update permissions */
161
+ tricky->file = c_fl2;
162
+ bdrv_child_refresh_perms(top, top->children.lh_first, &error_abort);
163
+
164
+ assert(c_fl2->perm & BLK_PERM_WRITE);
165
+ assert(!(c_fl1->perm & BLK_PERM_WRITE));
166
+
167
+ /* Switch once more, to not care about real child order in the list */
168
+ tricky->file = c_fl1;
169
+ bdrv_child_refresh_perms(top, top->children.lh_first, &error_abort);
170
+
171
+ assert(c_fl1->perm & BLK_PERM_WRITE);
172
+ assert(!(c_fl2->perm & BLK_PERM_WRITE));
173
+
174
+ bdrv_unref(top);
175
+}
176
+
177
int main(int argc, char *argv[])
178
{
179
int i;
180
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
181
if (debug) {
182
g_test_add_func("/bdrv-graph-mod/parallel-exclusive-write",
183
test_parallel_exclusive_write);
184
+ g_test_add_func("/bdrv-graph-mod/parallel-perm-update",
185
+ test_parallel_perm_update);
186
}
187
188
return g_test_run();
189
--
190
2.30.2
191
192
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
3
bdrv_append() is not quite good for inserting filters: it does extra
4
permission update in intermediate state, where filter get it filtered
5
child but is not yet replace it in a backing chain.
6
7
Some filters (for example backup-top) may want permissions even when
8
have no parents. And described intermediate state becomes invalid.
9
10
That's (half a) reason, why we need "inactive" state for backup-top
11
filter.
12
13
bdrv_append() will be improved later, now let's add a unit test.
14
15
Now test fails, so it runs only with -d flag. To run do
16
17
./test-bdrv-graph-mod -d -p /bdrv-graph-mod/append-greedy-filter
18
19
from <build-directory>/tests.
20
21
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
22
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
23
Message-Id: <20210428151804.439460-4-vsementsov@virtuozzo.com>
24
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
25
---
26
tests/unit/test-bdrv-graph-mod.c | 33 ++++++++++++++++++++++++++++++++
27
1 file changed, 33 insertions(+)
28
29
diff --git a/tests/unit/test-bdrv-graph-mod.c b/tests/unit/test-bdrv-graph-mod.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/tests/unit/test-bdrv-graph-mod.c
32
+++ b/tests/unit/test-bdrv-graph-mod.c
33
@@ -XXX,XX +XXX,XX @@ static void test_parallel_perm_update(void)
34
bdrv_unref(top);
35
}
36
37
+/*
38
+ * It's possible that filter required permissions allows to insert it to backing
39
+ * chain, like:
40
+ *
41
+ * 1. [top] -> [filter] -> [base]
42
+ *
43
+ * but doesn't allow to add it as a branch:
44
+ *
45
+ * 2. [filter] --\
46
+ * v
47
+ * [top] -> [base]
48
+ *
49
+ * So, inserting such filter should do all graph modifications and only then
50
+ * update permissions. If we try to go through intermediate state [2] and update
51
+ * permissions on it we'll fail.
52
+ *
53
+ * Let's check that bdrv_append() can append such a filter.
54
+ */
55
+static void test_append_greedy_filter(void)
56
+{
57
+ BlockDriverState *top = exclusive_writer_node("top");
58
+ BlockDriverState *base = no_perm_node("base");
59
+ BlockDriverState *fl = exclusive_writer_node("fl1");
60
+
61
+ bdrv_attach_child(top, base, "backing", &child_of_bds, BDRV_CHILD_COW,
62
+ &error_abort);
63
+
64
+ bdrv_append(fl, base, &error_abort);
65
+ bdrv_unref(top);
66
+}
67
+
68
int main(int argc, char *argv[])
69
{
70
int i;
71
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
72
test_parallel_exclusive_write);
73
g_test_add_func("/bdrv-graph-mod/parallel-perm-update",
74
test_parallel_perm_update);
75
+ g_test_add_func("/bdrv-graph-mod/append-greedy-filter",
76
+ test_append_greedy_filter);
77
}
78
79
return g_test_run();
80
--
81
2.30.2
82
83
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
You can reproduce this by passing an invalid filter-node-name (like
3
We have too much comments for this feature. It seems better just don't
4
"1234") to block-commit. In this case the base image is put in
4
do it. Most of real users (tests don't count) have to create additional
5
read-write mode but is never reset back to read-only.
5
reference.
6
6
7
Signed-off-by: Alberto Garcia <berto@igalia.com>
7
Drop also comment in external_snapshot_prepare:
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
8
- bdrv_append doesn't "remove" old bs in common sense, it sounds
9
strange
10
- the fact that bdrv_append can fail is obvious from the context
11
- the fact that we must rollback all changes in transaction abort is
12
known (it's the direct role of abort)
13
14
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
15
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
16
Message-Id: <20210428151804.439460-5-vsementsov@virtuozzo.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
18
---
11
block/commit.c | 3 +++
19
block.c | 25 +++----------------------
12
1 file changed, 3 insertions(+)
20
block/backup-top.c | 1 -
21
block/commit.c | 1 +
22
block/mirror.c | 3 ---
23
blockdev.c | 4 ----
24
tests/unit/test-bdrv-drain.c | 2 +-
25
tests/unit/test-bdrv-graph-mod.c | 3 +++
26
7 files changed, 8 insertions(+), 31 deletions(-)
13
27
28
diff --git a/block.c b/block.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/block.c
31
+++ b/block.c
32
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs,
33
goto out;
34
}
35
36
- /* bdrv_append() consumes a strong reference to bs_snapshot
37
- * (i.e. it will call bdrv_unref() on it) even on error, so in
38
- * order to be able to return one, we have to increase
39
- * bs_snapshot's refcount here */
40
- bdrv_ref(bs_snapshot);
41
ret = bdrv_append(bs_snapshot, bs, errp);
42
if (ret < 0) {
43
bs_snapshot = NULL;
44
@@ -XXX,XX +XXX,XX @@ int bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
45
* bs_new must not be attached to a BlockBackend.
46
*
47
* This function does not create any image files.
48
- *
49
- * bdrv_append() takes ownership of a bs_new reference and unrefs it because
50
- * that's what the callers commonly need. bs_new will be referenced by the old
51
- * parents of bs_top after bdrv_append() returns. If the caller needs to keep a
52
- * reference of its own, it must call bdrv_ref().
53
*/
54
int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
55
Error **errp)
56
{
57
int ret = bdrv_set_backing_hd(bs_new, bs_top, errp);
58
if (ret < 0) {
59
- goto out;
60
+ return ret;
61
}
62
63
ret = bdrv_replace_node(bs_top, bs_new, errp);
64
if (ret < 0) {
65
bdrv_set_backing_hd(bs_new, NULL, &error_abort);
66
- goto out;
67
+ return ret;
68
}
69
70
- ret = 0;
71
-
72
-out:
73
- /*
74
- * bs_new is now referenced by its new parents, we don't need the
75
- * additional reference any more.
76
- */
77
- bdrv_unref(bs_new);
78
-
79
- return ret;
80
+ return 0;
81
}
82
83
static void bdrv_delete(BlockDriverState *bs)
84
diff --git a/block/backup-top.c b/block/backup-top.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/block/backup-top.c
87
+++ b/block/backup-top.c
88
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_backup_top_append(BlockDriverState *source,
89
90
bdrv_drained_begin(source);
91
92
- bdrv_ref(top);
93
ret = bdrv_append(top, source, errp);
94
if (ret < 0) {
95
error_prepend(errp, "Cannot append backup-top filter: ");
14
diff --git a/block/commit.c b/block/commit.c
96
diff --git a/block/commit.c b/block/commit.c
15
index XXXXXXX..XXXXXXX 100644
97
index XXXXXXX..XXXXXXX 100644
16
--- a/block/commit.c
98
--- a/block/commit.c
17
+++ b/block/commit.c
99
+++ b/block/commit.c
18
@@ -XXX,XX +XXX,XX @@ fail:
100
@@ -XXX,XX +XXX,XX @@ void commit_start(const char *job_id, BlockDriverState *bs,
19
if (s->top) {
101
commit_top_bs->total_sectors = top->total_sectors;
20
blk_unref(s->top);
102
103
ret = bdrv_append(commit_top_bs, top, errp);
104
+ bdrv_unref(commit_top_bs); /* referenced by new parents or failed */
105
if (ret < 0) {
106
commit_top_bs = NULL;
107
goto fail;
108
diff --git a/block/mirror.c b/block/mirror.c
109
index XXXXXXX..XXXXXXX 100644
110
--- a/block/mirror.c
111
+++ b/block/mirror.c
112
@@ -XXX,XX +XXX,XX @@ static BlockJob *mirror_start_job(
113
114
bs_opaque->is_commit = target_is_backing;
115
116
- /* bdrv_append takes ownership of the mirror_top_bs reference, need to keep
117
- * it alive until block_job_create() succeeds even if bs has no parent. */
118
- bdrv_ref(mirror_top_bs);
119
bdrv_drained_begin(bs);
120
ret = bdrv_append(mirror_top_bs, bs, errp);
121
bdrv_drained_end(bs);
122
diff --git a/blockdev.c b/blockdev.c
123
index XXXXXXX..XXXXXXX 100644
124
--- a/blockdev.c
125
+++ b/blockdev.c
126
@@ -XXX,XX +XXX,XX @@ static void external_snapshot_prepare(BlkActionState *common,
127
goto out;
21
}
128
}
22
+ if (s->base_read_only) {
129
23
+ bdrv_reopen_set_read_only(base, true, NULL);
130
- /* This removes our old bs and adds the new bs. This is an operation that
24
+ }
131
- * can fail, so we need to do it in .prepare; undoing it for abort is
25
job_early_fail(&s->common.job);
132
- * always possible. */
26
/* commit_top_bs has to be replaced after deleting the block job,
133
- bdrv_ref(state->new_bs);
27
* otherwise this would fail because of lack of permissions. */
134
ret = bdrv_append(state->new_bs, state->old_bs, errp);
135
if (ret < 0) {
136
goto out;
137
diff --git a/tests/unit/test-bdrv-drain.c b/tests/unit/test-bdrv-drain.c
138
index XXXXXXX..XXXXXXX 100644
139
--- a/tests/unit/test-bdrv-drain.c
140
+++ b/tests/unit/test-bdrv-drain.c
141
@@ -XXX,XX +XXX,XX @@ static void test_append_to_drained(void)
142
g_assert_cmpint(base_s->drain_count, ==, 1);
143
g_assert_cmpint(base->in_flight, ==, 0);
144
145
- /* Takes ownership of overlay, so we don't have to unref it later */
146
bdrv_append(overlay, base, &error_abort);
147
g_assert_cmpint(base->in_flight, ==, 0);
148
g_assert_cmpint(overlay->in_flight, ==, 0);
149
@@ -XXX,XX +XXX,XX @@ static void test_append_to_drained(void)
150
g_assert_cmpint(overlay->quiesce_counter, ==, 0);
151
g_assert_cmpint(overlay_s->drain_count, ==, 0);
152
153
+ bdrv_unref(overlay);
154
bdrv_unref(base);
155
blk_unref(blk);
156
}
157
diff --git a/tests/unit/test-bdrv-graph-mod.c b/tests/unit/test-bdrv-graph-mod.c
158
index XXXXXXX..XXXXXXX 100644
159
--- a/tests/unit/test-bdrv-graph-mod.c
160
+++ b/tests/unit/test-bdrv-graph-mod.c
161
@@ -XXX,XX +XXX,XX @@ static void test_update_perm_tree(void)
162
ret = bdrv_append(filter, bs, NULL);
163
g_assert_cmpint(ret, <, 0);
164
165
+ bdrv_unref(filter);
166
blk_unref(root);
167
}
168
169
@@ -XXX,XX +XXX,XX @@ static void test_should_update_child(void)
170
bdrv_append(filter, bs, &error_abort);
171
g_assert(target->backing->bs == bs);
172
173
+ bdrv_unref(filter);
174
bdrv_unref(bs);
175
blk_unref(root);
176
}
177
@@ -XXX,XX +XXX,XX @@ static void test_append_greedy_filter(void)
178
&error_abort);
179
180
bdrv_append(fl, base, &error_abort);
181
+ bdrv_unref(fl);
182
bdrv_unref(top);
183
}
184
28
--
185
--
29
2.20.1
186
2.30.2
30
187
31
188
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
Add new handler to get aio context and implement it in all child
4
classes. Add corresponding public interface to be used soon.
5
3
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
4
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
7
Reviewed-by: Alberto Garcia <berto@igalia.com>
5
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
8
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Message-Id: <20210428151804.439460-6-vsementsov@virtuozzo.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
11
---
8
include/block/block_int.h | 16 ++++++++++++++++
12
include/block/block.h | 2 ++
9
include/sysemu/block-backend.h | 19 +++++++++++++++++++
13
include/block/block_int.h | 2 ++
10
2 files changed, 35 insertions(+)
14
block.c | 13 +++++++++++++
15
block/block-backend.c | 9 +++++++++
16
blockjob.c | 8 ++++++++
17
5 files changed, 34 insertions(+)
11
18
19
diff --git a/include/block/block.h b/include/block/block.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/block/block.h
22
+++ b/include/block/block.h
23
@@ -XXX,XX +XXX,XX @@ bool bdrv_child_can_set_aio_context(BdrvChild *c, AioContext *ctx,
24
GSList **ignore, Error **errp);
25
bool bdrv_can_set_aio_context(BlockDriverState *bs, AioContext *ctx,
26
GSList **ignore, Error **errp);
27
+AioContext *bdrv_child_get_parent_aio_context(BdrvChild *c);
28
+
29
int bdrv_probe_blocksizes(BlockDriverState *bs, BlockSizes *bsz);
30
int bdrv_probe_geometry(BlockDriverState *bs, HDGeometry *geo);
31
12
diff --git a/include/block/block_int.h b/include/block/block_int.h
32
diff --git a/include/block/block_int.h b/include/block/block_int.h
13
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
14
--- a/include/block/block_int.h
34
--- a/include/block/block_int.h
15
+++ b/include/block/block_int.h
35
+++ b/include/block/block_int.h
16
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
36
@@ -XXX,XX +XXX,XX @@ struct BdrvChildClass {
17
int64_t offset, unsigned int bytes, QEMUIOVector *qiov,
37
bool (*can_set_aio_ctx)(BdrvChild *child, AioContext *ctx,
18
BdrvRequestFlags flags);
38
GSList **ignore, Error **errp);
19
39
void (*set_aio_ctx)(BdrvChild *child, AioContext *ctx, GSList **ignore);
20
+static inline int coroutine_fn bdrv_co_pread(BdrvChild *child,
40
+
21
+ int64_t offset, unsigned int bytes, void *buf, BdrvRequestFlags flags)
41
+ AioContext *(*get_parent_aio_context)(BdrvChild *child);
42
};
43
44
extern const BdrvChildClass child_of_bds;
45
diff --git a/block.c b/block.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/block.c
48
+++ b/block.c
49
@@ -XXX,XX +XXX,XX @@ static int bdrv_child_cb_update_filename(BdrvChild *c, BlockDriverState *base,
50
return 0;
51
}
52
53
+static AioContext *bdrv_child_cb_get_parent_aio_context(BdrvChild *c)
22
+{
54
+{
23
+ QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
55
+ BlockDriverState *bs = c->opaque;
24
+
56
+
25
+ return bdrv_co_preadv(child, offset, bytes, &qiov, flags);
57
+ return bdrv_get_aio_context(bs);
26
+}
58
+}
27
+
59
+
28
+static inline int coroutine_fn bdrv_co_pwrite(BdrvChild *child,
60
const BdrvChildClass child_of_bds = {
29
+ int64_t offset, unsigned int bytes, void *buf, BdrvRequestFlags flags)
61
.parent_is_bds = true,
62
.get_parent_desc = bdrv_child_get_parent_desc,
63
@@ -XXX,XX +XXX,XX @@ const BdrvChildClass child_of_bds = {
64
.can_set_aio_ctx = bdrv_child_cb_can_set_aio_ctx,
65
.set_aio_ctx = bdrv_child_cb_set_aio_ctx,
66
.update_filename = bdrv_child_cb_update_filename,
67
+ .get_parent_aio_context = bdrv_child_cb_get_parent_aio_context,
68
};
69
70
+AioContext *bdrv_child_get_parent_aio_context(BdrvChild *c)
30
+{
71
+{
31
+ QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
72
+ return c->klass->get_parent_aio_context(c);
32
+
33
+ return bdrv_co_pwritev(child, offset, bytes, &qiov, flags);
34
+}
73
+}
35
+
74
+
36
extern unsigned int bdrv_drain_all_count;
75
static int bdrv_open_flags(BlockDriverState *bs, int flags)
37
void bdrv_apply_subtree_drain(BdrvChild *child, BlockDriverState *new_parent);
76
{
38
void bdrv_unapply_subtree_drain(BdrvChild *child, BlockDriverState *old_parent);
77
int open_flags = flags;
39
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
78
diff --git a/block/block-backend.c b/block/block-backend.c
40
index XXXXXXX..XXXXXXX 100644
79
index XXXXXXX..XXXXXXX 100644
41
--- a/include/sysemu/block-backend.h
80
--- a/block/block-backend.c
42
+++ b/include/sysemu/block-backend.h
81
+++ b/block/block-backend.c
43
@@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset,
82
@@ -XXX,XX +XXX,XX @@ static void blk_root_detach(BdrvChild *child)
44
int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset,
83
}
45
unsigned int bytes, QEMUIOVector *qiov,
84
}
46
BdrvRequestFlags flags);
85
86
+static AioContext *blk_root_get_parent_aio_context(BdrvChild *c)
87
+{
88
+ BlockBackend *blk = c->opaque;
47
+
89
+
48
+static inline int coroutine_fn blk_co_pread(BlockBackend *blk, int64_t offset,
90
+ return blk_get_aio_context(blk);
49
+ unsigned int bytes, void *buf,
50
+ BdrvRequestFlags flags)
51
+{
52
+ QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
53
+
54
+ return blk_co_preadv(blk, offset, bytes, &qiov, flags);
55
+}
91
+}
56
+
92
+
57
+static inline int coroutine_fn blk_co_pwrite(BlockBackend *blk, int64_t offset,
93
static const BdrvChildClass child_root = {
58
+ unsigned int bytes, void *buf,
94
.inherit_options = blk_root_inherit_options,
59
+ BdrvRequestFlags flags)
95
96
@@ -XXX,XX +XXX,XX @@ static const BdrvChildClass child_root = {
97
98
.can_set_aio_ctx = blk_root_can_set_aio_ctx,
99
.set_aio_ctx = blk_root_set_aio_ctx,
100
+
101
+ .get_parent_aio_context = blk_root_get_parent_aio_context,
102
};
103
104
/*
105
diff --git a/blockjob.c b/blockjob.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/blockjob.c
108
+++ b/blockjob.c
109
@@ -XXX,XX +XXX,XX @@ static void child_job_set_aio_ctx(BdrvChild *c, AioContext *ctx,
110
job->job.aio_context = ctx;
111
}
112
113
+static AioContext *child_job_get_parent_aio_context(BdrvChild *c)
60
+{
114
+{
61
+ QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
115
+ BlockJob *job = c->opaque;
62
+
116
+
63
+ return blk_co_pwritev(blk, offset, bytes, &qiov, flags);
117
+ return job->job.aio_context;
64
+}
118
+}
65
+
119
+
66
int blk_pwrite_zeroes(BlockBackend *blk, int64_t offset,
120
static const BdrvChildClass child_job = {
67
int bytes, BdrvRequestFlags flags);
121
.get_parent_desc = child_job_get_parent_desc,
68
BlockAIOCB *blk_aio_pwrite_zeroes(BlockBackend *blk, int64_t offset,
122
.drained_begin = child_job_drained_begin,
123
@@ -XXX,XX +XXX,XX @@ static const BdrvChildClass child_job = {
124
.can_set_aio_ctx = child_job_can_set_aio_ctx,
125
.set_aio_ctx = child_job_set_aio_ctx,
126
.stay_at_node = true,
127
+ .get_parent_aio_context = child_job_get_parent_aio_context,
128
};
129
130
void block_job_remove_all_bdrv(BlockJob *job)
69
--
131
--
70
2.20.1
132
2.30.2
71
133
72
134
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
3
Passing parent aio context is redundant, as child_class and parent
4
opaque pointer are enough to retrieve it. Drop the argument and use new
5
bdrv_child_get_parent_aio_context() interface.
6
7
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Reviewed-by: Alberto Garcia <berto@igalia.com>
9
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
10
Message-Id: <20210428151804.439460-7-vsementsov@virtuozzo.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
13
include/block/block_int.h | 1 -
14
block.c | 8 +++++---
15
block/block-backend.c | 4 ++--
16
blockjob.c | 3 +--
17
4 files changed, 8 insertions(+), 8 deletions(-)
18
19
diff --git a/include/block/block_int.h b/include/block/block_int.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/block/block_int.h
22
+++ b/include/block/block_int.h
23
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
24
const char *child_name,
25
const BdrvChildClass *child_class,
26
BdrvChildRole child_role,
27
- AioContext *ctx,
28
uint64_t perm, uint64_t shared_perm,
29
void *opaque, Error **errp);
30
void bdrv_root_unref_child(BdrvChild *child);
31
diff --git a/block.c b/block.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/block.c
34
+++ b/block.c
35
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
36
const char *child_name,
37
const BdrvChildClass *child_class,
38
BdrvChildRole child_role,
39
- AioContext *ctx,
40
uint64_t perm, uint64_t shared_perm,
41
void *opaque, Error **errp)
42
{
43
BdrvChild *child;
44
Error *local_err = NULL;
45
int ret;
46
+ AioContext *ctx;
47
48
ret = bdrv_check_update_perm(child_bs, NULL, perm, shared_perm, NULL, errp);
49
if (ret < 0) {
50
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
51
.opaque = opaque,
52
};
53
54
+ ctx = bdrv_child_get_parent_aio_context(child);
55
+
56
/* If the AioContexts don't match, first try to move the subtree of
57
* child_bs into the AioContext of the new parent. If this doesn't work,
58
* try moving the parent into the AioContext of child_bs instead. */
59
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
60
perm, shared_perm, &perm, &shared_perm);
61
62
child = bdrv_root_attach_child(child_bs, child_name, child_class,
63
- child_role, bdrv_get_aio_context(parent_bs),
64
- perm, shared_perm, parent_bs, errp);
65
+ child_role, perm, shared_perm, parent_bs,
66
+ errp);
67
if (child == NULL) {
68
return NULL;
69
}
70
diff --git a/block/block-backend.c b/block/block-backend.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/block/block-backend.c
73
+++ b/block/block-backend.c
74
@@ -XXX,XX +XXX,XX @@ BlockBackend *blk_new_open(const char *filename, const char *reference,
75
76
blk->root = bdrv_root_attach_child(bs, "root", &child_root,
77
BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
78
- blk->ctx, perm, BLK_PERM_ALL, blk, errp);
79
+ perm, BLK_PERM_ALL, blk, errp);
80
if (!blk->root) {
81
blk_unref(blk);
82
return NULL;
83
@@ -XXX,XX +XXX,XX @@ int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp)
84
bdrv_ref(bs);
85
blk->root = bdrv_root_attach_child(bs, "root", &child_root,
86
BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
87
- blk->ctx, blk->perm, blk->shared_perm,
88
+ blk->perm, blk->shared_perm,
89
blk, errp);
90
if (blk->root == NULL) {
91
return -EPERM;
92
diff --git a/blockjob.c b/blockjob.c
93
index XXXXXXX..XXXXXXX 100644
94
--- a/blockjob.c
95
+++ b/blockjob.c
96
@@ -XXX,XX +XXX,XX @@ int block_job_add_bdrv(BlockJob *job, const char *name, BlockDriverState *bs,
97
if (need_context_ops && job->job.aio_context != qemu_get_aio_context()) {
98
aio_context_release(job->job.aio_context);
99
}
100
- c = bdrv_root_attach_child(bs, name, &child_job, 0,
101
- job->job.aio_context, perm, shared_perm, job,
102
+ c = bdrv_root_attach_child(bs, name, &child_job, 0, perm, shared_perm, job,
103
errp);
104
if (need_context_ops && job->job.aio_context != qemu_get_aio_context()) {
105
aio_context_acquire(job->job.aio_context);
106
--
107
2.30.2
108
109
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
3
These functions are called only from bdrv_reopen_multiple() in block.c.
4
No reason to publish them.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Alberto Garcia <berto@igalia.com>
8
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Message-Id: <20210428151804.439460-8-vsementsov@virtuozzo.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
include/block/block.h | 4 ----
13
block.c | 13 +++++++++----
14
2 files changed, 9 insertions(+), 8 deletions(-)
15
16
diff --git a/include/block/block.h b/include/block/block.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/block/block.h
19
+++ b/include/block/block.h
20
@@ -XXX,XX +XXX,XX @@ BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
21
int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp);
22
int bdrv_reopen_set_read_only(BlockDriverState *bs, bool read_only,
23
Error **errp);
24
-int bdrv_reopen_prepare(BDRVReopenState *reopen_state,
25
- BlockReopenQueue *queue, Error **errp);
26
-void bdrv_reopen_commit(BDRVReopenState *reopen_state);
27
-void bdrv_reopen_abort(BDRVReopenState *reopen_state);
28
int bdrv_pwrite_zeroes(BdrvChild *child, int64_t offset,
29
int64_t bytes, BdrvRequestFlags flags);
30
int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags flags);
31
diff --git a/block.c b/block.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/block.c
34
+++ b/block.c
35
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
36
BdrvChildRole child_role,
37
Error **errp);
38
39
+static int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue
40
+ *queue, Error **errp);
41
+static void bdrv_reopen_commit(BDRVReopenState *reopen_state);
42
+static void bdrv_reopen_abort(BDRVReopenState *reopen_state);
43
+
44
/* If non-zero, use only whitelisted block drivers */
45
static int use_bdrv_whitelist;
46
47
@@ -XXX,XX +XXX,XX @@ static int bdrv_reopen_parse_backing(BDRVReopenState *reopen_state,
48
* commit() for any other BDS that have been left in a prepare() state
49
*
50
*/
51
-int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
52
- Error **errp)
53
+static int bdrv_reopen_prepare(BDRVReopenState *reopen_state,
54
+ BlockReopenQueue *queue, Error **errp)
55
{
56
int ret = -1;
57
int old_flags;
58
@@ -XXX,XX +XXX,XX @@ error:
59
* makes them final by swapping the staging BlockDriverState contents into
60
* the active BlockDriverState contents.
61
*/
62
-void bdrv_reopen_commit(BDRVReopenState *reopen_state)
63
+static void bdrv_reopen_commit(BDRVReopenState *reopen_state)
64
{
65
BlockDriver *drv;
66
BlockDriverState *bs;
67
@@ -XXX,XX +XXX,XX @@ void bdrv_reopen_commit(BDRVReopenState *reopen_state)
68
* Abort the reopen, and delete and free the staged changes in
69
* reopen_state
70
*/
71
-void bdrv_reopen_abort(BDRVReopenState *reopen_state)
72
+static void bdrv_reopen_abort(BDRVReopenState *reopen_state)
73
{
74
BlockDriver *drv;
75
76
--
77
2.30.2
78
79
diff view generated by jsdifflib
New patch
1
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
3
Add simple transaction API to use in further update of block graph
4
operations.
5
6
Supposed usage is:
7
8
- "prepare" is main function of the action and it should make the main
9
effect of the action to be visible for the following actions, keeping
10
possibility of roll-back, saving necessary things in action state,
11
which is prepended to the action list (to do that, prepare func
12
should call tran_add()). So, driver struct doesn't include "prepare"
13
field, as it is supposed to be called directly.
14
15
- commit/rollback is supposed to be called for the list of action
16
states, to commit/rollback all the actions in reverse order
17
18
- When possible "commit" should not make visible effect for other
19
actions, which make possible transparent logical interaction between
20
actions.
21
22
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
23
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
24
Message-Id: <20210428151804.439460-9-vsementsov@virtuozzo.com>
25
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
26
---
27
include/qemu/transactions.h | 63 ++++++++++++++++++++++++
28
util/transactions.c | 96 +++++++++++++++++++++++++++++++++++++
29
MAINTAINERS | 6 +++
30
util/meson.build | 1 +
31
4 files changed, 166 insertions(+)
32
create mode 100644 include/qemu/transactions.h
33
create mode 100644 util/transactions.c
34
35
diff --git a/include/qemu/transactions.h b/include/qemu/transactions.h
36
new file mode 100644
37
index XXXXXXX..XXXXXXX
38
--- /dev/null
39
+++ b/include/qemu/transactions.h
40
@@ -XXX,XX +XXX,XX @@
41
+/*
42
+ * Simple transactions API
43
+ *
44
+ * Copyright (c) 2021 Virtuozzo International GmbH.
45
+ *
46
+ * Author:
47
+ * Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
48
+ *
49
+ * This program is free software; you can redistribute it and/or modify
50
+ * it under the terms of the GNU General Public License as published by
51
+ * the Free Software Foundation; either version 2 of the License, or
52
+ * (at your option) any later version.
53
+ *
54
+ * This program is distributed in the hope that it will be useful,
55
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
56
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
57
+ * GNU General Public License for more details.
58
+ *
59
+ * You should have received a copy of the GNU General Public License
60
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
61
+ *
62
+ *
63
+ * = Generic transaction API =
64
+ *
65
+ * The intended usage is the following: you create "prepare" functions, which
66
+ * represents the actions. They will usually have Transaction* argument, and
67
+ * call tran_add() to register finalization callbacks. For finalization
68
+ * callbacks, prepare corresponding TransactionActionDrv structures.
69
+ *
70
+ * Then, when you need to make a transaction, create an empty Transaction by
71
+ * tran_create(), call your "prepare" functions on it, and finally call
72
+ * tran_abort() or tran_commit() to finalize the transaction by corresponding
73
+ * finalization actions in reverse order.
74
+ */
75
+
76
+#ifndef QEMU_TRANSACTIONS_H
77
+#define QEMU_TRANSACTIONS_H
78
+
79
+#include <gmodule.h>
80
+
81
+typedef struct TransactionActionDrv {
82
+ void (*abort)(void *opaque);
83
+ void (*commit)(void *opaque);
84
+ void (*clean)(void *opaque);
85
+} TransactionActionDrv;
86
+
87
+typedef struct Transaction Transaction;
88
+
89
+Transaction *tran_new(void);
90
+void tran_add(Transaction *tran, TransactionActionDrv *drv, void *opaque);
91
+void tran_abort(Transaction *tran);
92
+void tran_commit(Transaction *tran);
93
+
94
+static inline void tran_finalize(Transaction *tran, int ret)
95
+{
96
+ if (ret < 0) {
97
+ tran_abort(tran);
98
+ } else {
99
+ tran_commit(tran);
100
+ }
101
+}
102
+
103
+#endif /* QEMU_TRANSACTIONS_H */
104
diff --git a/util/transactions.c b/util/transactions.c
105
new file mode 100644
106
index XXXXXXX..XXXXXXX
107
--- /dev/null
108
+++ b/util/transactions.c
109
@@ -XXX,XX +XXX,XX @@
110
+/*
111
+ * Simple transactions API
112
+ *
113
+ * Copyright (c) 2021 Virtuozzo International GmbH.
114
+ *
115
+ * Author:
116
+ * Sementsov-Ogievskiy Vladimir <vsementsov@virtuozzo.com>
117
+ *
118
+ * This program is free software; you can redistribute it and/or modify
119
+ * it under the terms of the GNU General Public License as published by
120
+ * the Free Software Foundation; either version 2 of the License, or
121
+ * (at your option) any later version.
122
+ *
123
+ * This program is distributed in the hope that it will be useful,
124
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
125
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
126
+ * GNU General Public License for more details.
127
+ *
128
+ * You should have received a copy of the GNU General Public License
129
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
130
+ */
131
+
132
+#include "qemu/osdep.h"
133
+
134
+#include "qemu/transactions.h"
135
+#include "qemu/queue.h"
136
+
137
+typedef struct TransactionAction {
138
+ TransactionActionDrv *drv;
139
+ void *opaque;
140
+ QSLIST_ENTRY(TransactionAction) entry;
141
+} TransactionAction;
142
+
143
+struct Transaction {
144
+ QSLIST_HEAD(, TransactionAction) actions;
145
+};
146
+
147
+Transaction *tran_new(void)
148
+{
149
+ Transaction *tran = g_new(Transaction, 1);
150
+
151
+ QSLIST_INIT(&tran->actions);
152
+
153
+ return tran;
154
+}
155
+
156
+void tran_add(Transaction *tran, TransactionActionDrv *drv, void *opaque)
157
+{
158
+ TransactionAction *act;
159
+
160
+ act = g_new(TransactionAction, 1);
161
+ *act = (TransactionAction) {
162
+ .drv = drv,
163
+ .opaque = opaque
164
+ };
165
+
166
+ QSLIST_INSERT_HEAD(&tran->actions, act, entry);
167
+}
168
+
169
+void tran_abort(Transaction *tran)
170
+{
171
+ TransactionAction *act, *next;
172
+
173
+ QSLIST_FOREACH_SAFE(act, &tran->actions, entry, next) {
174
+ if (act->drv->abort) {
175
+ act->drv->abort(act->opaque);
176
+ }
177
+
178
+ if (act->drv->clean) {
179
+ act->drv->clean(act->opaque);
180
+ }
181
+
182
+ g_free(act);
183
+ }
184
+
185
+ g_free(tran);
186
+}
187
+
188
+void tran_commit(Transaction *tran)
189
+{
190
+ TransactionAction *act, *next;
191
+
192
+ QSLIST_FOREACH_SAFE(act, &tran->actions, entry, next) {
193
+ if (act->drv->commit) {
194
+ act->drv->commit(act->opaque);
195
+ }
196
+
197
+ if (act->drv->clean) {
198
+ act->drv->clean(act->opaque);
199
+ }
200
+
201
+ g_free(act);
202
+ }
203
+
204
+ g_free(tran);
205
+}
206
diff --git a/MAINTAINERS b/MAINTAINERS
207
index XXXXXXX..XXXXXXX 100644
208
--- a/MAINTAINERS
209
+++ b/MAINTAINERS
210
@@ -XXX,XX +XXX,XX @@ M: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
211
S: Maintained
212
F: scripts/simplebench/
213
214
+Transactions helper
215
+M: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
216
+S: Maintained
217
+F: include/qemu/transactions.h
218
+F: util/transactions.c
219
+
220
QAPI
221
M: Markus Armbruster <armbru@redhat.com>
222
M: Michael Roth <michael.roth@amd.com>
223
diff --git a/util/meson.build b/util/meson.build
224
index XXXXXXX..XXXXXXX 100644
225
--- a/util/meson.build
226
+++ b/util/meson.build
227
@@ -XXX,XX +XXX,XX @@ util_ss.add(files('qsp.c'))
228
util_ss.add(files('range.c'))
229
util_ss.add(files('stats64.c'))
230
util_ss.add(files('systemd.c'))
231
+util_ss.add(files('transactions.c'))
232
util_ss.add(when: 'CONFIG_POSIX', if_true: files('drm.c'))
233
util_ss.add(files('guest-random.c'))
234
util_ss.add(files('yank.c'))
235
--
236
2.30.2
237
238
diff view generated by jsdifflib
1
preallocate_co() already gave the data file the full size without
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
forwarding the requested preallocation mode to the protocol. When
3
bdrv_co_truncate() was called later with the preallocation mode, the
4
file didn't actually grow any more, so the data file stayed unallocated
5
even if full preallocation was requested.
6
2
7
Pass the right preallocation mode to preallocate_co() and remove the
3
Add additional check that node parents do not interfere with each
8
second bdrv_co_truncate() to fix this. As a side effect, the ugly
4
other. This should not hurt existing callers and allows in further
9
one-byte write in preallocate_co() is replaced with a truncate call,
5
patch use bdrv_refresh_perms() to update a subtree of changed
10
now leaving the last block unallocated on the protocol level as it
6
BdrvChild (check that change is correct).
11
should be.
12
7
13
Cc: qemu-stable@nongnu.org
8
New check will substitute bdrv_check_update_perm() in following
9
permissions refactoring, so keep error messages the same to avoid
10
unit test result changes.
11
12
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
13
Reviewed-by: Alberto Garcia <berto@igalia.com>
14
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
15
Message-Id: <20210428151804.439460-10-vsementsov@virtuozzo.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
Reviewed-by: Eric Blake <eblake@redhat.com>
16
---
17
---
17
block/qcow2.c | 41 +++++++++++++++++++++++------------------
18
block.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++---------
18
1 file changed, 23 insertions(+), 18 deletions(-)
19
1 file changed, 54 insertions(+), 9 deletions(-)
19
20
20
diff --git a/block/qcow2.c b/block/qcow2.c
21
diff --git a/block.c b/block.c
21
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
22
--- a/block/qcow2.c
23
--- a/block.c
23
+++ b/block/qcow2.c
24
+++ b/block.c
24
@@ -XXX,XX +XXX,XX @@ static int qcow2_set_up_encryption(BlockDriverState *bs,
25
@@ -XXX,XX +XXX,XX @@ bool bdrv_is_writable(BlockDriverState *bs)
25
* Returns: 0 on success, -errno on failure.
26
return bdrv_is_writable_after_reopen(bs, NULL);
26
*/
27
}
27
static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
28
28
- uint64_t new_length, Error **errp)
29
+static char *bdrv_child_user_desc(BdrvChild *c)
29
+ uint64_t new_length, PreallocMode mode,
30
+{
30
+ Error **errp)
31
+ if (c->klass->get_parent_desc) {
31
{
32
+ return c->klass->get_parent_desc(c);
32
BDRVQcow2State *s = bs->opaque;
33
uint64_t bytes;
34
uint64_t host_offset = 0;
35
+ int64_t file_length;
36
unsigned int cur_bytes;
37
int ret;
38
QCowL2Meta *meta;
39
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
40
* all of the allocated clusters (otherwise we get failing reads after
41
* EOF). Extend the image to the last allocated sector.
42
*/
43
- if (host_offset != 0) {
44
- uint8_t data = 0;
45
- ret = bdrv_pwrite(s->data_file, (host_offset + cur_bytes) - 1,
46
- &data, 1);
47
+ file_length = bdrv_getlength(s->data_file->bs);
48
+ if (file_length < 0) {
49
+ error_setg_errno(errp, -file_length, "Could not get file size");
50
+ return file_length;
51
+ }
33
+ }
52
+
34
+
53
+ if (host_offset + cur_bytes > file_length) {
35
+ return g_strdup("another user");
54
+ if (mode == PREALLOC_MODE_METADATA) {
36
+}
55
+ mode = PREALLOC_MODE_OFF;
37
+
56
+ }
38
+static bool bdrv_a_allow_b(BdrvChild *a, BdrvChild *b, Error **errp)
57
+ ret = bdrv_co_truncate(s->data_file, host_offset + cur_bytes, mode,
39
+{
58
+ errp);
40
+ g_autofree char *user = NULL;
59
if (ret < 0) {
41
+ g_autofree char *perm_names = NULL;
60
- error_setg_errno(errp, -ret, "Writing to EOF failed");
42
+
61
return ret;
43
+ if ((b->perm & a->shared_perm) == b->perm) {
62
}
44
+ return true;
63
}
45
+ }
64
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
46
+
65
47
+ perm_names = bdrv_perm_names(b->perm & ~a->shared_perm);
66
switch (prealloc) {
48
+ user = bdrv_child_user_desc(a);
67
case PREALLOC_MODE_OFF:
49
+ error_setg(errp, "Conflicts with use by %s as '%s', which does not "
68
+ if (has_data_file(bs)) {
50
+ "allow '%s' on %s",
69
+ ret = bdrv_co_truncate(s->data_file, offset, prealloc, errp);
51
+ user, a->name, perm_names, bdrv_get_node_name(b->bs));
70
+ if (ret < 0) {
52
+
71
+ goto fail;
53
+ return false;
54
+}
55
+
56
+static bool bdrv_parent_perms_conflict(BlockDriverState *bs, Error **errp)
57
+{
58
+ BdrvChild *a, *b;
59
+
60
+ /*
61
+ * During the loop we'll look at each pair twice. That's correct because
62
+ * bdrv_a_allow_b() is asymmetric and we should check each pair in both
63
+ * directions.
64
+ */
65
+ QLIST_FOREACH(a, &bs->parents, next_parent) {
66
+ QLIST_FOREACH(b, &bs->parents, next_parent) {
67
+ if (a == b) {
68
+ continue;
69
+ }
70
+
71
+ if (!bdrv_a_allow_b(a, b, errp)) {
72
+ return true;
72
+ }
73
+ }
73
+ }
74
+ }
74
break;
75
+ }
75
76
+
76
case PREALLOC_MODE_METADATA:
77
+ return false;
77
- ret = preallocate_co(bs, old_length, offset, errp);
78
+}
78
+ ret = preallocate_co(bs, old_length, offset, prealloc, errp);
79
+
79
if (ret < 0) {
80
static void bdrv_child_perm(BlockDriverState *bs, BlockDriverState *child_bs,
80
goto fail;
81
BdrvChild *c, BdrvChildRole role,
81
}
82
BlockReopenQueue *reopen_queue,
82
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
83
@@ -XXX,XX +XXX,XX @@ void bdrv_get_cumulative_perm(BlockDriverState *bs, uint64_t *perm,
83
/* With a data file, preallocation means just allocating the metadata
84
*shared_perm = cumulative_shared_perms;
84
* and forwarding the truncate request to the data file */
85
}
85
if (has_data_file(bs)) {
86
86
- ret = preallocate_co(bs, old_length, offset, errp);
87
-static char *bdrv_child_user_desc(BdrvChild *c)
87
+ ret = preallocate_co(bs, old_length, offset, prealloc, errp);
88
-{
88
if (ret < 0) {
89
- if (c->klass->get_parent_desc) {
89
goto fail;
90
- return c->klass->get_parent_desc(c);
90
}
91
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
92
93
bs->total_sectors = offset / BDRV_SECTOR_SIZE;
94
95
- if (has_data_file(bs)) {
96
- if (prealloc == PREALLOC_MODE_METADATA) {
97
- prealloc = PREALLOC_MODE_OFF;
98
- }
99
- ret = bdrv_co_truncate(s->data_file, offset, prealloc, errp);
100
- if (ret < 0) {
101
- goto fail;
102
- }
103
- }
91
- }
104
-
92
-
105
/* write updated header.size */
93
- return g_strdup("another user");
106
offset = cpu_to_be64(offset);
94
-}
107
ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, size),
95
-
96
char *bdrv_perm_names(uint64_t perm)
97
{
98
struct perm_name {
99
@@ -XXX,XX +XXX,XX @@ static int bdrv_refresh_perms(BlockDriverState *bs, Error **errp)
100
int ret;
101
uint64_t perm, shared_perm;
102
103
+ if (bdrv_parent_perms_conflict(bs, errp)) {
104
+ return -EPERM;
105
+ }
106
bdrv_get_cumulative_perm(bs, &perm, &shared_perm);
107
ret = bdrv_check_perm(bs, NULL, perm, shared_perm, NULL, errp);
108
if (ret < 0) {
108
--
109
--
109
2.20.1
110
2.30.2
110
111
111
112
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
qemu-img create allows giving just a format and "-o help" to get a list
3
Split out non-recursive parts, and refactor as block graph transaction
4
of the options supported by that format. Users may not realize that the
4
action.
5
protocol level may offer even more options, which they only get to see
6
by specifying a filename.
7
5
8
This patch adds a note to hint at that fact.
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
7
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
Message-Id: <20210428151804.439460-11-vsementsov@virtuozzo.com>
11
Reviewed-by: John Snow <jsnow@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
10
---
14
qemu-img.c | 13 ++++++++++++-
11
block.c | 79 ++++++++++++++++++++++++++++++++++++++++++---------------
15
tests/qemu-iotests/082.out | 20 ++++++++++++++++----
12
1 file changed, 59 insertions(+), 20 deletions(-)
16
2 files changed, 28 insertions(+), 5 deletions(-)
17
13
18
diff --git a/qemu-img.c b/qemu-img.c
14
diff --git a/block.c b/block.c
19
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
20
--- a/qemu-img.c
16
--- a/block.c
21
+++ b/qemu-img.c
17
+++ b/block.c
22
@@ -XXX,XX +XXX,XX @@ static int print_block_option_help(const char *filename, const char *fmt)
18
@@ -XXX,XX +XXX,XX @@
23
create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);
19
#include "qemu/timer.h"
20
#include "qemu/cutils.h"
21
#include "qemu/id.h"
22
+#include "qemu/transactions.h"
23
#include "block/coroutines.h"
24
25
#ifdef CONFIG_BSD
26
@@ -XXX,XX +XXX,XX @@ static void bdrv_child_perm(BlockDriverState *bs, BlockDriverState *child_bs,
24
}
27
}
25
28
}
26
- printf("Supported options:\n");
29
27
+ if (filename) {
30
+static void bdrv_child_set_perm_commit(void *opaque)
28
+ printf("Supported options:\n");
31
+{
29
+ } else {
32
+ BdrvChild *c = opaque;
30
+ printf("Supported %s options:\n", fmt);
33
+
34
+ c->has_backup_perm = false;
35
+}
36
+
37
+static void bdrv_child_set_perm_abort(void *opaque)
38
+{
39
+ BdrvChild *c = opaque;
40
+ /*
41
+ * We may have child->has_backup_perm unset at this point, as in case of
42
+ * _check_ stage of permission update failure we may _check_ not the whole
43
+ * subtree. Still, _abort_ is called on the whole subtree anyway.
44
+ */
45
+ if (c->has_backup_perm) {
46
+ c->perm = c->backup_perm;
47
+ c->shared_perm = c->backup_shared_perm;
48
+ c->has_backup_perm = false;
31
+ }
49
+ }
32
qemu_opts_print_help(create_opts, false);
50
+}
33
qemu_opts_free(create_opts);
34
+
51
+
35
+ if (!filename) {
52
+static TransactionActionDrv bdrv_child_set_pem_drv = {
36
+ printf("\n"
53
+ .abort = bdrv_child_set_perm_abort,
37
+ "The protocol level may support further options.\n"
54
+ .commit = bdrv_child_set_perm_commit,
38
+ "Specify the target filename to include those options.\n");
55
+};
56
+
57
+/*
58
+ * With tran=NULL needs to be followed by direct call to either
59
+ * bdrv_child_set_perm_commit() or bdrv_child_set_perm_abort().
60
+ *
61
+ * With non-NULL tran needs to be followed by tran_abort() or tran_commit()
62
+ * instead.
63
+ */
64
+static void bdrv_child_set_perm_safe(BdrvChild *c, uint64_t perm,
65
+ uint64_t shared, Transaction *tran)
66
+{
67
+ if (!c->has_backup_perm) {
68
+ c->has_backup_perm = true;
69
+ c->backup_perm = c->perm;
70
+ c->backup_shared_perm = c->shared_perm;
39
+ }
71
+ }
72
+ /*
73
+ * Note: it's OK if c->has_backup_perm was already set, as we can find the
74
+ * same c twice during check_perm procedure
75
+ */
40
+
76
+
77
+ c->perm = perm;
78
+ c->shared_perm = shared;
79
+
80
+ if (tran) {
81
+ tran_add(tran, &bdrv_child_set_pem_drv, c);
82
+ }
83
+}
84
+
85
/*
86
* Check whether permissions on this node can be changed in a way that
87
* @cumulative_perms and @cumulative_shared_perms are the new cumulative
88
@@ -XXX,XX +XXX,XX @@ static int bdrv_child_check_perm(BdrvChild *c, BlockReopenQueue *q,
89
return ret;
90
}
91
92
- if (!c->has_backup_perm) {
93
- c->has_backup_perm = true;
94
- c->backup_perm = c->perm;
95
- c->backup_shared_perm = c->shared_perm;
96
- }
97
- /*
98
- * Note: it's OK if c->has_backup_perm was already set, as we can find the
99
- * same child twice during check_perm procedure
100
- */
101
-
102
- c->perm = perm;
103
- c->shared_perm = shared;
104
+ bdrv_child_set_perm_safe(c, perm, shared, NULL);
105
41
return 0;
106
return 0;
42
}
107
}
43
108
44
diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out
109
static void bdrv_child_set_perm(BdrvChild *c)
45
index XXXXXXX..XXXXXXX 100644
110
{
46
--- a/tests/qemu-iotests/082.out
111
- c->has_backup_perm = false;
47
+++ b/tests/qemu-iotests/082.out
112
-
48
@@ -XXX,XX +XXX,XX @@ Testing: create -f qcow2 -o backing_file=TEST_DIR/t.qcow2 -o ,, -o help TEST_DIR
113
+ bdrv_child_set_perm_commit(c);
49
qemu-img: Invalid option list: ,,
114
bdrv_set_perm(c->bs);
50
115
}
51
Testing: create -f qcow2 -o help
116
52
-Supported options:
117
static void bdrv_child_abort_perm_update(BdrvChild *c)
53
+Supported qcow2 options:
118
{
54
backing_file=<str> - File name of a base image
119
- if (c->has_backup_perm) {
55
backing_fmt=<str> - Image format of the base image
120
- c->perm = c->backup_perm;
56
cluster_size=<size> - qcow2 cluster size
121
- c->shared_perm = c->backup_shared_perm;
57
@@ -XXX,XX +XXX,XX @@ Supported options:
122
- c->has_backup_perm = false;
58
refcount_bits=<num> - Width of a reference count entry in bits
123
- }
59
size=<size> - Virtual disk size
124
-
60
125
+ bdrv_child_set_perm_abort(c);
61
+The protocol level may support further options.
126
bdrv_abort_perm_update(c->bs);
62
+Specify the target filename to include those options.
127
}
63
+
64
Testing: create -o help
65
-Supported options:
66
+Supported raw options:
67
size=<size> - Virtual disk size
68
69
+The protocol level may support further options.
70
+Specify the target filename to include those options.
71
+
72
Testing: create -f bochs -o help
73
qemu-img: Format driver 'bochs' does not support image creation
74
75
@@ -XXX,XX +XXX,XX @@ Testing: convert -O qcow2 -o backing_file=TEST_DIR/t.qcow2 -o ,, -o help TEST_DI
76
qemu-img: Invalid option list: ,,
77
78
Testing: convert -O qcow2 -o help
79
-Supported options:
80
+Supported qcow2 options:
81
backing_file=<str> - File name of a base image
82
backing_fmt=<str> - Image format of the base image
83
cluster_size=<size> - qcow2 cluster size
84
@@ -XXX,XX +XXX,XX @@ Supported options:
85
refcount_bits=<num> - Width of a reference count entry in bits
86
size=<size> - Virtual disk size
87
88
+The protocol level may support further options.
89
+Specify the target filename to include those options.
90
+
91
Testing: convert -o help
92
-Supported options:
93
+Supported raw options:
94
size=<size> - Virtual disk size
95
96
+The protocol level may support further options.
97
+Specify the target filename to include those options.
98
+
99
Testing: convert -O bochs -o help
100
qemu-img: Format driver 'bochs' does not support image creation
101
128
102
--
129
--
103
2.20.1
130
2.30.2
104
131
105
132
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
3
We are going to drop recursive bdrv_child_* functions, so stop use them
4
in bdrv_child_try_set_perm() as a first step.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
8
Message-Id: <20210428151804.439460-12-vsementsov@virtuozzo.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
block.c | 14 ++++++++------
12
1 file changed, 8 insertions(+), 6 deletions(-)
13
14
diff --git a/block.c b/block.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/block.c
17
+++ b/block.c
18
@@ -XXX,XX +XXX,XX @@ int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
19
Error **errp)
20
{
21
Error *local_err = NULL;
22
+ Transaction *tran = tran_new();
23
int ret;
24
25
- ret = bdrv_child_check_perm(c, NULL, perm, shared, NULL, &local_err);
26
+ bdrv_child_set_perm_safe(c, perm, shared, tran);
27
+
28
+ ret = bdrv_refresh_perms(c->bs, &local_err);
29
+
30
+ tran_finalize(tran, ret);
31
+
32
if (ret < 0) {
33
- bdrv_child_abort_perm_update(c);
34
if ((perm & ~c->perm) || (c->shared_perm & ~shared)) {
35
/* tighten permissions */
36
error_propagate(errp, local_err);
37
@@ -XXX,XX +XXX,XX @@ int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
38
error_free(local_err);
39
ret = 0;
40
}
41
- return ret;
42
}
43
44
- bdrv_child_set_perm(c);
45
-
46
- return 0;
47
+ return ret;
48
}
49
50
int bdrv_child_refresh_perms(BlockDriverState *bs, BdrvChild *c, Error **errp)
51
--
52
2.30.2
53
54
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
Each of them has only one caller. Open-coding simplifies further
4
pemission-update system changes.
5
3
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
4
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
7
Reviewed-by: Alberto Garcia <berto@igalia.com>
5
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
8
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Message-Id: <20210428151804.439460-13-vsementsov@virtuozzo.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
11
---
8
qemu-img.c | 13 ++++---------
12
block.c | 59 +++++++++++++++++----------------------------------------
9
1 file changed, 4 insertions(+), 9 deletions(-)
13
1 file changed, 17 insertions(+), 42 deletions(-)
10
14
11
diff --git a/qemu-img.c b/qemu-img.c
15
diff --git a/block.c b/block.c
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/qemu-img.c
17
--- a/block.c
14
+++ b/qemu-img.c
18
+++ b/block.c
15
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn convert_co_read(ImgConvertState *s, int64_t sector_num,
19
@@ -XXX,XX +XXX,XX @@ static int bdrv_fill_options(QDict **options, const char *filename,
16
int nb_sectors, uint8_t *buf)
20
return 0;
17
{
21
}
18
int n, ret;
22
19
- QEMUIOVector qiov;
23
-static int bdrv_child_check_perm(BdrvChild *c, BlockReopenQueue *q,
20
24
- uint64_t perm, uint64_t shared,
21
assert(nb_sectors <= s->buf_sectors);
25
- GSList *ignore_children, Error **errp);
22
while (nb_sectors > 0) {
26
-static void bdrv_child_abort_perm_update(BdrvChild *c);
23
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn convert_co_read(ImgConvertState *s, int64_t sector_num,
27
-static void bdrv_child_set_perm(BdrvChild *c);
24
bs_sectors = s->src_sectors[src_cur];
28
+static int bdrv_check_update_perm(BlockDriverState *bs, BlockReopenQueue *q,
25
29
+ uint64_t new_used_perm,
26
n = MIN(nb_sectors, bs_sectors - (sector_num - src_cur_offset));
30
+ uint64_t new_shared_perm,
27
- qemu_iovec_init_buf(&qiov, buf, n << BDRV_SECTOR_BITS);
31
+ GSList *ignore_children,
28
32
+ Error **errp);
29
- ret = blk_co_preadv(
33
30
+ ret = blk_co_pread(
34
typedef struct BlockReopenQueueEntry {
31
blk, (sector_num - src_cur_offset) << BDRV_SECTOR_BITS,
35
bool prepared;
32
- n << BDRV_SECTOR_BITS, &qiov, 0);
36
@@ -XXX,XX +XXX,XX @@ static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
33
+ n << BDRV_SECTOR_BITS, buf, 0);
37
/* Check all children */
38
QLIST_FOREACH(c, &bs->children, next) {
39
uint64_t cur_perm, cur_shared;
40
+ GSList *cur_ignore_children;
41
42
bdrv_child_perm(bs, c->bs, c, c->role, q,
43
cumulative_perms, cumulative_shared_perms,
44
&cur_perm, &cur_shared);
45
- ret = bdrv_child_check_perm(c, q, cur_perm, cur_shared, ignore_children,
46
- errp);
47
+
48
+ cur_ignore_children = g_slist_prepend(g_slist_copy(ignore_children), c);
49
+ ret = bdrv_check_update_perm(c->bs, q, cur_perm, cur_shared,
50
+ cur_ignore_children, errp);
51
+ g_slist_free(cur_ignore_children);
34
if (ret < 0) {
52
if (ret < 0) {
35
return ret;
53
return ret;
36
}
54
}
37
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn convert_co_write(ImgConvertState *s, int64_t sector_num,
55
+
38
enum ImgConvertBlockStatus status)
56
+ bdrv_child_set_perm_safe(c, cur_perm, cur_shared, NULL);
57
}
58
59
return 0;
60
@@ -XXX,XX +XXX,XX @@ static void bdrv_abort_perm_update(BlockDriverState *bs)
61
}
62
63
QLIST_FOREACH(c, &bs->children, next) {
64
- bdrv_child_abort_perm_update(c);
65
+ bdrv_child_set_perm_abort(c);
66
+ bdrv_abort_perm_update(c->bs);
67
}
68
}
69
70
@@ -XXX,XX +XXX,XX @@ static void bdrv_set_perm(BlockDriverState *bs)
71
72
/* Update all children */
73
QLIST_FOREACH(c, &bs->children, next) {
74
- bdrv_child_set_perm(c);
75
+ bdrv_child_set_perm_commit(c);
76
+ bdrv_set_perm(c->bs);
77
}
78
}
79
80
@@ -XXX,XX +XXX,XX @@ static int bdrv_check_update_perm(BlockDriverState *bs, BlockReopenQueue *q,
81
ignore_children, errp);
82
}
83
84
-/* Needs to be followed by a call to either bdrv_child_set_perm() or
85
- * bdrv_child_abort_perm_update(). */
86
-static int bdrv_child_check_perm(BdrvChild *c, BlockReopenQueue *q,
87
- uint64_t perm, uint64_t shared,
88
- GSList *ignore_children, Error **errp)
89
-{
90
- int ret;
91
-
92
- ignore_children = g_slist_prepend(g_slist_copy(ignore_children), c);
93
- ret = bdrv_check_update_perm(c->bs, q, perm, shared, ignore_children, errp);
94
- g_slist_free(ignore_children);
95
-
96
- if (ret < 0) {
97
- return ret;
98
- }
99
-
100
- bdrv_child_set_perm_safe(c, perm, shared, NULL);
101
-
102
- return 0;
103
-}
104
-
105
-static void bdrv_child_set_perm(BdrvChild *c)
106
-{
107
- bdrv_child_set_perm_commit(c);
108
- bdrv_set_perm(c->bs);
109
-}
110
-
111
-static void bdrv_child_abort_perm_update(BdrvChild *c)
112
-{
113
- bdrv_child_set_perm_abort(c);
114
- bdrv_abort_perm_update(c->bs);
115
-}
116
-
117
static int bdrv_refresh_perms(BlockDriverState *bs, Error **errp)
39
{
118
{
40
int ret;
119
int ret;
41
- QEMUIOVector qiov;
42
43
while (nb_sectors > 0) {
44
int n = nb_sectors;
45
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn convert_co_write(ImgConvertState *s, int64_t sector_num,
46
(s->compressed &&
47
!buffer_is_zero(buf, n * BDRV_SECTOR_SIZE)))
48
{
49
- qemu_iovec_init_buf(&qiov, buf, n << BDRV_SECTOR_BITS);
50
-
51
- ret = blk_co_pwritev(s->target, sector_num << BDRV_SECTOR_BITS,
52
- n << BDRV_SECTOR_BITS, &qiov, flags);
53
+ ret = blk_co_pwrite(s->target, sector_num << BDRV_SECTOR_BITS,
54
+ n << BDRV_SECTOR_BITS, buf, flags);
55
if (ret < 0) {
56
return ret;
57
}
58
--
120
--
59
2.20.1
121
2.30.2
60
122
61
123
diff view generated by jsdifflib
New patch
1
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
3
Rewrite bdrv_check_perm(), bdrv_abort_perm_update() and bdrv_set_perm()
4
to update nodes in topological sort order instead of simple DFS. With
5
topologically sorted nodes, we update a node only when all its parents
6
already updated. With DFS it's not so.
7
8
Consider the following example:
9
10
A -+
11
| |
12
| v
13
| B
14
| |
15
v |
16
C<-+
17
18
A is parent for B and C, B is parent for C.
19
20
Obviously, to update permissions, we should go in order A B C, so, when
21
we update C, all parent permissions already updated. But with current
22
approach (simple recursion) we can update in sequence A C B C (C is
23
updated twice). On first update of C, we consider old B permissions, so
24
doing wrong thing. If it succeed, all is OK, on second C update we will
25
finish with correct graph. But if the wrong thing failed, we break the
26
whole process for no reason (it's possible that updated B permission
27
will be less strict, but we will never check it).
28
29
Also new approach gives a way to simultaneously and correctly update
30
several nodes, we just need to run bdrv_topological_dfs() several times
31
to add all nodes and their subtrees into one topologically sorted list
32
(next patch will update bdrv_replace_node() in this manner).
33
34
Test test_parallel_perm_update() is now passing, so move it out of
35
debugging "if".
36
37
We also need to support ignore_children in
38
bdrv_parent_perms_conflict()
39
40
For test 283 order of conflicting parents check is changed.
41
42
Note also that in bdrv_check_perm() we don't check for parents conflict
43
at root bs, as we may be in the middle of permission update in
44
bdrv_reopen_multiple(). bdrv_reopen_multiple() will be updated soon.
45
46
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
47
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
48
Message-Id: <20210428151804.439460-14-vsementsov@virtuozzo.com>
49
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
50
---
51
block.c | 116 +++++++++++++++++++++++++------
52
tests/unit/test-bdrv-graph-mod.c | 4 +-
53
tests/qemu-iotests/283.out | 2 +-
54
3 files changed, 99 insertions(+), 23 deletions(-)
55
56
diff --git a/block.c b/block.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/block.c
59
+++ b/block.c
60
@@ -XXX,XX +XXX,XX @@ static bool bdrv_a_allow_b(BdrvChild *a, BdrvChild *b, Error **errp)
61
return false;
62
}
63
64
-static bool bdrv_parent_perms_conflict(BlockDriverState *bs, Error **errp)
65
+static bool bdrv_parent_perms_conflict(BlockDriverState *bs,
66
+ GSList *ignore_children,
67
+ Error **errp)
68
{
69
BdrvChild *a, *b;
70
71
@@ -XXX,XX +XXX,XX @@ static bool bdrv_parent_perms_conflict(BlockDriverState *bs, Error **errp)
72
* directions.
73
*/
74
QLIST_FOREACH(a, &bs->parents, next_parent) {
75
+ if (g_slist_find(ignore_children, a)) {
76
+ continue;
77
+ }
78
+
79
QLIST_FOREACH(b, &bs->parents, next_parent) {
80
- if (a == b) {
81
+ if (a == b || g_slist_find(ignore_children, b)) {
82
continue;
83
}
84
85
@@ -XXX,XX +XXX,XX @@ static void bdrv_child_perm(BlockDriverState *bs, BlockDriverState *child_bs,
86
}
87
}
88
89
+/*
90
+ * Adds the whole subtree of @bs (including @bs itself) to the @list (except for
91
+ * nodes that are already in the @list, of course) so that final list is
92
+ * topologically sorted. Return the result (GSList @list object is updated, so
93
+ * don't use old reference after function call).
94
+ *
95
+ * On function start @list must be already topologically sorted and for any node
96
+ * in the @list the whole subtree of the node must be in the @list as well. The
97
+ * simplest way to satisfy this criteria: use only result of
98
+ * bdrv_topological_dfs() or NULL as @list parameter.
99
+ */
100
+static GSList *bdrv_topological_dfs(GSList *list, GHashTable *found,
101
+ BlockDriverState *bs)
102
+{
103
+ BdrvChild *child;
104
+ g_autoptr(GHashTable) local_found = NULL;
105
+
106
+ if (!found) {
107
+ assert(!list);
108
+ found = local_found = g_hash_table_new(NULL, NULL);
109
+ }
110
+
111
+ if (g_hash_table_contains(found, bs)) {
112
+ return list;
113
+ }
114
+ g_hash_table_add(found, bs);
115
+
116
+ QLIST_FOREACH(child, &bs->children, next) {
117
+ list = bdrv_topological_dfs(list, found, child->bs);
118
+ }
119
+
120
+ return g_slist_prepend(list, bs);
121
+}
122
+
123
static void bdrv_child_set_perm_commit(void *opaque)
124
{
125
BdrvChild *c = opaque;
126
@@ -XXX,XX +XXX,XX @@ static void bdrv_child_set_perm_safe(BdrvChild *c, uint64_t perm,
127
* A call to this function must always be followed by a call to bdrv_set_perm()
128
* or bdrv_abort_perm_update().
129
*/
130
-static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
131
- uint64_t cumulative_perms,
132
- uint64_t cumulative_shared_perms,
133
- GSList *ignore_children, Error **errp)
134
+static int bdrv_node_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
135
+ uint64_t cumulative_perms,
136
+ uint64_t cumulative_shared_perms,
137
+ GSList *ignore_children, Error **errp)
138
{
139
BlockDriver *drv = bs->drv;
140
BdrvChild *c;
141
@@ -XXX,XX +XXX,XX @@ static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
142
/* Check all children */
143
QLIST_FOREACH(c, &bs->children, next) {
144
uint64_t cur_perm, cur_shared;
145
- GSList *cur_ignore_children;
146
147
bdrv_child_perm(bs, c->bs, c, c->role, q,
148
cumulative_perms, cumulative_shared_perms,
149
&cur_perm, &cur_shared);
150
+ bdrv_child_set_perm_safe(c, cur_perm, cur_shared, NULL);
151
+ }
152
+
153
+ return 0;
154
+}
155
+
156
+static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
157
+ uint64_t cumulative_perms,
158
+ uint64_t cumulative_shared_perms,
159
+ GSList *ignore_children, Error **errp)
160
+{
161
+ int ret;
162
+ BlockDriverState *root = bs;
163
+ g_autoptr(GSList) list = bdrv_topological_dfs(NULL, NULL, root);
164
165
- cur_ignore_children = g_slist_prepend(g_slist_copy(ignore_children), c);
166
- ret = bdrv_check_update_perm(c->bs, q, cur_perm, cur_shared,
167
- cur_ignore_children, errp);
168
- g_slist_free(cur_ignore_children);
169
+ for ( ; list; list = list->next) {
170
+ bs = list->data;
171
+
172
+ if (bs != root) {
173
+ if (bdrv_parent_perms_conflict(bs, ignore_children, errp)) {
174
+ return -EINVAL;
175
+ }
176
+
177
+ bdrv_get_cumulative_perm(bs, &cumulative_perms,
178
+ &cumulative_shared_perms);
179
+ }
180
+
181
+ ret = bdrv_node_check_perm(bs, q, cumulative_perms,
182
+ cumulative_shared_perms,
183
+ ignore_children, errp);
184
if (ret < 0) {
185
return ret;
186
}
187
-
188
- bdrv_child_set_perm_safe(c, cur_perm, cur_shared, NULL);
189
}
190
191
return 0;
192
@@ -XXX,XX +XXX,XX @@ static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
193
* Notifies drivers that after a previous bdrv_check_perm() call, the
194
* permission update is not performed and any preparations made for it (e.g.
195
* taken file locks) need to be undone.
196
- *
197
- * This function recursively notifies all child nodes.
198
*/
199
-static void bdrv_abort_perm_update(BlockDriverState *bs)
200
+static void bdrv_node_abort_perm_update(BlockDriverState *bs)
201
{
202
BlockDriver *drv = bs->drv;
203
BdrvChild *c;
204
@@ -XXX,XX +XXX,XX @@ static void bdrv_abort_perm_update(BlockDriverState *bs)
205
206
QLIST_FOREACH(c, &bs->children, next) {
207
bdrv_child_set_perm_abort(c);
208
- bdrv_abort_perm_update(c->bs);
209
}
210
}
211
212
-static void bdrv_set_perm(BlockDriverState *bs)
213
+static void bdrv_abort_perm_update(BlockDriverState *bs)
214
+{
215
+ g_autoptr(GSList) list = bdrv_topological_dfs(NULL, NULL, bs);
216
+
217
+ for ( ; list; list = list->next) {
218
+ bdrv_node_abort_perm_update((BlockDriverState *)list->data);
219
+ }
220
+}
221
+
222
+static void bdrv_node_set_perm(BlockDriverState *bs)
223
{
224
uint64_t cumulative_perms, cumulative_shared_perms;
225
BlockDriver *drv = bs->drv;
226
@@ -XXX,XX +XXX,XX @@ static void bdrv_set_perm(BlockDriverState *bs)
227
/* Update all children */
228
QLIST_FOREACH(c, &bs->children, next) {
229
bdrv_child_set_perm_commit(c);
230
- bdrv_set_perm(c->bs);
231
+ }
232
+}
233
+
234
+static void bdrv_set_perm(BlockDriverState *bs)
235
+{
236
+ g_autoptr(GSList) list = bdrv_topological_dfs(NULL, NULL, bs);
237
+
238
+ for ( ; list; list = list->next) {
239
+ bdrv_node_set_perm((BlockDriverState *)list->data);
240
}
241
}
242
243
@@ -XXX,XX +XXX,XX @@ static int bdrv_refresh_perms(BlockDriverState *bs, Error **errp)
244
int ret;
245
uint64_t perm, shared_perm;
246
247
- if (bdrv_parent_perms_conflict(bs, errp)) {
248
+ if (bdrv_parent_perms_conflict(bs, NULL, errp)) {
249
return -EPERM;
250
}
251
bdrv_get_cumulative_perm(bs, &perm, &shared_perm);
252
diff --git a/tests/unit/test-bdrv-graph-mod.c b/tests/unit/test-bdrv-graph-mod.c
253
index XXXXXXX..XXXXXXX 100644
254
--- a/tests/unit/test-bdrv-graph-mod.c
255
+++ b/tests/unit/test-bdrv-graph-mod.c
256
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
257
g_test_add_func("/bdrv-graph-mod/update-perm-tree", test_update_perm_tree);
258
g_test_add_func("/bdrv-graph-mod/should-update-child",
259
test_should_update_child);
260
+ g_test_add_func("/bdrv-graph-mod/parallel-perm-update",
261
+ test_parallel_perm_update);
262
263
if (debug) {
264
g_test_add_func("/bdrv-graph-mod/parallel-exclusive-write",
265
test_parallel_exclusive_write);
266
- g_test_add_func("/bdrv-graph-mod/parallel-perm-update",
267
- test_parallel_perm_update);
268
g_test_add_func("/bdrv-graph-mod/append-greedy-filter",
269
test_append_greedy_filter);
270
}
271
diff --git a/tests/qemu-iotests/283.out b/tests/qemu-iotests/283.out
272
index XXXXXXX..XXXXXXX 100644
273
--- a/tests/qemu-iotests/283.out
274
+++ b/tests/qemu-iotests/283.out
275
@@ -XXX,XX +XXX,XX @@
276
{"execute": "blockdev-add", "arguments": {"driver": "blkdebug", "image": "base", "node-name": "other", "take-child-perms": ["write"]}}
277
{"return": {}}
278
{"execute": "blockdev-backup", "arguments": {"device": "source", "sync": "full", "target": "target"}}
279
-{"error": {"class": "GenericError", "desc": "Cannot set permissions for backup-top filter: Conflicts with use by other as 'image', which uses 'write' on base"}}
280
+{"error": {"class": "GenericError", "desc": "Cannot set permissions for backup-top filter: Conflicts with use by source as 'image', which does not allow 'write' on base"}}
281
282
=== backup-top should be gone after job-finalize ===
283
284
--
285
2.30.2
286
287
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
3
Refactor calling driver callbacks to a separate transaction action to
4
be used later.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
8
Message-Id: <20210428151804.439460-15-vsementsov@virtuozzo.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
block.c | 70 ++++++++++++++++++++++++++++++++++++++++++++-------------
12
1 file changed, 54 insertions(+), 16 deletions(-)
13
14
diff --git a/block.c b/block.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/block.c
17
+++ b/block.c
18
@@ -XXX,XX +XXX,XX @@ static void bdrv_child_set_perm_safe(BdrvChild *c, uint64_t perm,
19
}
20
}
21
22
+static void bdrv_drv_set_perm_commit(void *opaque)
23
+{
24
+ BlockDriverState *bs = opaque;
25
+ uint64_t cumulative_perms, cumulative_shared_perms;
26
+
27
+ if (bs->drv->bdrv_set_perm) {
28
+ bdrv_get_cumulative_perm(bs, &cumulative_perms,
29
+ &cumulative_shared_perms);
30
+ bs->drv->bdrv_set_perm(bs, cumulative_perms, cumulative_shared_perms);
31
+ }
32
+}
33
+
34
+static void bdrv_drv_set_perm_abort(void *opaque)
35
+{
36
+ BlockDriverState *bs = opaque;
37
+
38
+ if (bs->drv->bdrv_abort_perm_update) {
39
+ bs->drv->bdrv_abort_perm_update(bs);
40
+ }
41
+}
42
+
43
+TransactionActionDrv bdrv_drv_set_perm_drv = {
44
+ .abort = bdrv_drv_set_perm_abort,
45
+ .commit = bdrv_drv_set_perm_commit,
46
+};
47
+
48
+static int bdrv_drv_set_perm(BlockDriverState *bs, uint64_t perm,
49
+ uint64_t shared_perm, Transaction *tran,
50
+ Error **errp)
51
+{
52
+ if (!bs->drv) {
53
+ return 0;
54
+ }
55
+
56
+ if (bs->drv->bdrv_check_perm) {
57
+ int ret = bs->drv->bdrv_check_perm(bs, perm, shared_perm, errp);
58
+ if (ret < 0) {
59
+ return ret;
60
+ }
61
+ }
62
+
63
+ if (tran) {
64
+ tran_add(tran, &bdrv_drv_set_perm_drv, bs);
65
+ }
66
+
67
+ return 0;
68
+}
69
+
70
/*
71
* Check whether permissions on this node can be changed in a way that
72
* @cumulative_perms and @cumulative_shared_perms are the new cumulative
73
@@ -XXX,XX +XXX,XX @@ static int bdrv_node_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
74
return 0;
75
}
76
77
- if (drv->bdrv_check_perm) {
78
- ret = drv->bdrv_check_perm(bs, cumulative_perms,
79
- cumulative_shared_perms, errp);
80
- if (ret < 0) {
81
- return ret;
82
- }
83
+ ret = bdrv_drv_set_perm(bs, cumulative_perms, cumulative_shared_perms, NULL,
84
+ errp);
85
+ if (ret < 0) {
86
+ return ret;
87
}
88
89
/* Drivers that never have children can omit .bdrv_child_perm() */
90
@@ -XXX,XX +XXX,XX @@ static void bdrv_node_abort_perm_update(BlockDriverState *bs)
91
return;
92
}
93
94
- if (drv->bdrv_abort_perm_update) {
95
- drv->bdrv_abort_perm_update(bs);
96
- }
97
+ bdrv_drv_set_perm_abort(bs);
98
99
QLIST_FOREACH(c, &bs->children, next) {
100
bdrv_child_set_perm_abort(c);
101
@@ -XXX,XX +XXX,XX @@ static void bdrv_abort_perm_update(BlockDriverState *bs)
102
103
static void bdrv_node_set_perm(BlockDriverState *bs)
104
{
105
- uint64_t cumulative_perms, cumulative_shared_perms;
106
BlockDriver *drv = bs->drv;
107
BdrvChild *c;
108
109
@@ -XXX,XX +XXX,XX @@ static void bdrv_node_set_perm(BlockDriverState *bs)
110
return;
111
}
112
113
- bdrv_get_cumulative_perm(bs, &cumulative_perms, &cumulative_shared_perms);
114
-
115
- /* Update this node */
116
- if (drv->bdrv_set_perm) {
117
- drv->bdrv_set_perm(bs, cumulative_perms, cumulative_shared_perms);
118
- }
119
+ bdrv_drv_set_perm_commit(bs);
120
121
/* Drivers that never have children can omit .bdrv_child_perm() */
122
if (!drv->bdrv_child_perm) {
123
--
124
2.30.2
125
126
diff view generated by jsdifflib
New patch
1
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
3
Add new interface, allowing use of existing node list. It will be used
4
to fix bdrv_replace_node() in the further commit.
5
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
8
Message-Id: <20210428151804.439460-16-vsementsov@virtuozzo.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
block.c | 106 +++++++++++++++++++++++++++++++++++++-------------------
12
1 file changed, 71 insertions(+), 35 deletions(-)
13
14
diff --git a/block.c b/block.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/block.c
17
+++ b/block.c
18
@@ -XXX,XX +XXX,XX @@ static int bdrv_drv_set_perm(BlockDriverState *bs, uint64_t perm,
19
static int bdrv_node_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
20
uint64_t cumulative_perms,
21
uint64_t cumulative_shared_perms,
22
- GSList *ignore_children, Error **errp)
23
+ GSList *ignore_children,
24
+ Transaction *tran, Error **errp)
25
{
26
BlockDriver *drv = bs->drv;
27
BdrvChild *c;
28
@@ -XXX,XX +XXX,XX @@ static int bdrv_node_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
29
return 0;
30
}
31
32
- ret = bdrv_drv_set_perm(bs, cumulative_perms, cumulative_shared_perms, NULL,
33
+ ret = bdrv_drv_set_perm(bs, cumulative_perms, cumulative_shared_perms, tran,
34
errp);
35
if (ret < 0) {
36
return ret;
37
@@ -XXX,XX +XXX,XX @@ static int bdrv_node_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
38
bdrv_child_perm(bs, c->bs, c, c->role, q,
39
cumulative_perms, cumulative_shared_perms,
40
&cur_perm, &cur_shared);
41
- bdrv_child_set_perm_safe(c, cur_perm, cur_shared, NULL);
42
+ bdrv_child_set_perm_safe(c, cur_perm, cur_shared, tran);
43
}
44
45
return 0;
46
}
47
48
-static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
49
- uint64_t cumulative_perms,
50
- uint64_t cumulative_shared_perms,
51
- GSList *ignore_children, Error **errp)
52
+/*
53
+ * If use_cumulative_perms is true, use cumulative_perms and
54
+ * cumulative_shared_perms for first element of the list. Otherwise just refresh
55
+ * all permissions.
56
+ */
57
+static int bdrv_check_perm_common(GSList *list, BlockReopenQueue *q,
58
+ bool use_cumulative_perms,
59
+ uint64_t cumulative_perms,
60
+ uint64_t cumulative_shared_perms,
61
+ GSList *ignore_children,
62
+ Transaction *tran, Error **errp)
63
{
64
int ret;
65
- BlockDriverState *root = bs;
66
- g_autoptr(GSList) list = bdrv_topological_dfs(NULL, NULL, root);
67
+ BlockDriverState *bs;
68
69
- for ( ; list; list = list->next) {
70
+ if (use_cumulative_perms) {
71
bs = list->data;
72
73
- if (bs != root) {
74
- if (bdrv_parent_perms_conflict(bs, ignore_children, errp)) {
75
- return -EINVAL;
76
- }
77
+ ret = bdrv_node_check_perm(bs, q, cumulative_perms,
78
+ cumulative_shared_perms,
79
+ ignore_children, tran, errp);
80
+ if (ret < 0) {
81
+ return ret;
82
+ }
83
84
- bdrv_get_cumulative_perm(bs, &cumulative_perms,
85
- &cumulative_shared_perms);
86
+ list = list->next;
87
+ }
88
+
89
+ for ( ; list; list = list->next) {
90
+ bs = list->data;
91
+
92
+ if (bdrv_parent_perms_conflict(bs, ignore_children, errp)) {
93
+ return -EINVAL;
94
}
95
96
+ bdrv_get_cumulative_perm(bs, &cumulative_perms,
97
+ &cumulative_shared_perms);
98
+
99
ret = bdrv_node_check_perm(bs, q, cumulative_perms,
100
cumulative_shared_perms,
101
- ignore_children, errp);
102
+ ignore_children, tran, errp);
103
if (ret < 0) {
104
return ret;
105
}
106
@@ -XXX,XX +XXX,XX @@ static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
107
return 0;
108
}
109
110
+static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
111
+ uint64_t cumulative_perms,
112
+ uint64_t cumulative_shared_perms,
113
+ GSList *ignore_children, Error **errp)
114
+{
115
+ g_autoptr(GSList) list = bdrv_topological_dfs(NULL, NULL, bs);
116
+ return bdrv_check_perm_common(list, q, true, cumulative_perms,
117
+ cumulative_shared_perms, ignore_children,
118
+ NULL, errp);
119
+}
120
+
121
+static int bdrv_list_refresh_perms(GSList *list, BlockReopenQueue *q,
122
+ Transaction *tran, Error **errp)
123
+{
124
+ return bdrv_check_perm_common(list, q, false, 0, 0, NULL, tran, errp);
125
+}
126
+
127
/*
128
* Notifies drivers that after a previous bdrv_check_perm() call, the
129
* permission update is not performed and any preparations made for it (e.g.
130
@@ -XXX,XX +XXX,XX @@ static void bdrv_node_abort_perm_update(BlockDriverState *bs)
131
}
132
}
133
134
-static void bdrv_abort_perm_update(BlockDriverState *bs)
135
+static void bdrv_list_abort_perm_update(GSList *list)
136
{
137
- g_autoptr(GSList) list = bdrv_topological_dfs(NULL, NULL, bs);
138
-
139
for ( ; list; list = list->next) {
140
bdrv_node_abort_perm_update((BlockDriverState *)list->data);
141
}
142
}
143
144
+static void bdrv_abort_perm_update(BlockDriverState *bs)
145
+{
146
+ g_autoptr(GSList) list = bdrv_topological_dfs(NULL, NULL, bs);
147
+ return bdrv_list_abort_perm_update(list);
148
+}
149
+
150
static void bdrv_node_set_perm(BlockDriverState *bs)
151
{
152
BlockDriver *drv = bs->drv;
153
@@ -XXX,XX +XXX,XX @@ static void bdrv_node_set_perm(BlockDriverState *bs)
154
}
155
}
156
157
-static void bdrv_set_perm(BlockDriverState *bs)
158
+static void bdrv_list_set_perm(GSList *list)
159
{
160
- g_autoptr(GSList) list = bdrv_topological_dfs(NULL, NULL, bs);
161
-
162
for ( ; list; list = list->next) {
163
bdrv_node_set_perm((BlockDriverState *)list->data);
164
}
165
}
166
167
+static void bdrv_set_perm(BlockDriverState *bs)
168
+{
169
+ g_autoptr(GSList) list = bdrv_topological_dfs(NULL, NULL, bs);
170
+ return bdrv_list_set_perm(list);
171
+}
172
+
173
void bdrv_get_cumulative_perm(BlockDriverState *bs, uint64_t *perm,
174
uint64_t *shared_perm)
175
{
176
@@ -XXX,XX +XXX,XX @@ static int bdrv_check_update_perm(BlockDriverState *bs, BlockReopenQueue *q,
177
static int bdrv_refresh_perms(BlockDriverState *bs, Error **errp)
178
{
179
int ret;
180
- uint64_t perm, shared_perm;
181
+ Transaction *tran = tran_new();
182
+ g_autoptr(GSList) list = bdrv_topological_dfs(NULL, NULL, bs);
183
184
- if (bdrv_parent_perms_conflict(bs, NULL, errp)) {
185
- return -EPERM;
186
- }
187
- bdrv_get_cumulative_perm(bs, &perm, &shared_perm);
188
- ret = bdrv_check_perm(bs, NULL, perm, shared_perm, NULL, errp);
189
- if (ret < 0) {
190
- bdrv_abort_perm_update(bs);
191
- return ret;
192
- }
193
- bdrv_set_perm(bs);
194
+ ret = bdrv_list_refresh_perms(list, NULL, tran, errp);
195
+ tran_finalize(tran, ret);
196
197
- return 0;
198
+ return ret;
199
}
200
201
int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
202
--
203
2.30.2
204
205
diff view generated by jsdifflib
New patch
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
2
3
To be used in the following commit.
4
5
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
7
Message-Id: <20210428151804.439460-17-vsementsov@virtuozzo.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
10
block.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
11
1 file changed, 54 insertions(+)
12
13
diff --git a/block.c b/block.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/block.c
16
+++ b/block.c
17
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
18
BdrvChildRole child_role,
19
Error **errp);
20
21
+static void bdrv_replace_child_noperm(BdrvChild *child,
22
+ BlockDriverState *new_bs);
23
+
24
static int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue
25
*queue, Error **errp);
26
static void bdrv_reopen_commit(BDRVReopenState *reopen_state);
27
@@ -XXX,XX +XXX,XX @@ static int bdrv_drv_set_perm(BlockDriverState *bs, uint64_t perm,
28
return 0;
29
}
30
31
+typedef struct BdrvReplaceChildState {
32
+ BdrvChild *child;
33
+ BlockDriverState *old_bs;
34
+} BdrvReplaceChildState;
35
+
36
+static void bdrv_replace_child_commit(void *opaque)
37
+{
38
+ BdrvReplaceChildState *s = opaque;
39
+
40
+ bdrv_unref(s->old_bs);
41
+}
42
+
43
+static void bdrv_replace_child_abort(void *opaque)
44
+{
45
+ BdrvReplaceChildState *s = opaque;
46
+ BlockDriverState *new_bs = s->child->bs;
47
+
48
+ /* old_bs reference is transparently moved from @s to @s->child */
49
+ bdrv_replace_child_noperm(s->child, s->old_bs);
50
+ bdrv_unref(new_bs);
51
+}
52
+
53
+static TransactionActionDrv bdrv_replace_child_drv = {
54
+ .commit = bdrv_replace_child_commit,
55
+ .abort = bdrv_replace_child_abort,
56
+ .clean = g_free,
57
+};
58
+
59
+/*
60
+ * bdrv_replace_child_safe
61
+ *
62
+ * Note: real unref of old_bs is done only on commit.
63
+ */
64
+__attribute__((unused))
65
+static void bdrv_replace_child_safe(BdrvChild *child, BlockDriverState *new_bs,
66
+ Transaction *tran)
67
+{
68
+ BdrvReplaceChildState *s = g_new(BdrvReplaceChildState, 1);
69
+ *s = (BdrvReplaceChildState) {
70
+ .child = child,
71
+ .old_bs = child->bs,
72
+ };
73
+ tran_add(tran, &bdrv_replace_child_drv, s);
74
+
75
+ if (new_bs) {
76
+ bdrv_ref(new_bs);
77
+ }
78
+ bdrv_replace_child_noperm(child, new_bs);
79
+ /* old_bs reference is transparently moved from @child to @s */
80
+}
81
+
82
/*
83
* Check whether permissions on this node can be changed in a way that
84
* @cumulative_perms and @cumulative_shared_perms are the new cumulative
85
--
86
2.30.2
87
88
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
inore_children thing doesn't help to track all propagated permissions
4
of children we want to ignore. The simplest way to correctly update
5
permissions is update graph first and then do permission update. In
6
this case we just referesh permissions for the whole subgraph (in
7
topological-sort defined order) and everything is correctly calculated
8
automatically without any ignore_children.
9
10
So, refactor bdrv_replace_node_common to first do graph update and then
11
refresh the permissions.
12
13
Test test_parallel_exclusive_write() now pass, so move it out of
14
debugging "if".
15
3
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
16
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
4
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
17
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
18
Message-Id: <20210428151804.439460-18-vsementsov@virtuozzo.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
19
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
20
---
8
block/qcow2.c | 9 ++-------
21
block.c | 43 +++++++++++++-------------------
9
1 file changed, 2 insertions(+), 7 deletions(-)
22
tests/unit/test-bdrv-graph-mod.c | 4 +--
23
2 files changed, 20 insertions(+), 27 deletions(-)
10
24
11
diff --git a/block/qcow2.c b/block/qcow2.c
25
diff --git a/block.c b/block.c
12
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
13
--- a/block/qcow2.c
27
--- a/block.c
14
+++ b/block/qcow2.c
28
+++ b/block.c
15
@@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
29
@@ -XXX,XX +XXX,XX @@ static TransactionActionDrv bdrv_replace_child_drv = {
16
uint64_t bytes, QEMUIOVector *qiov)
30
*
31
* Note: real unref of old_bs is done only on commit.
32
*/
33
-__attribute__((unused))
34
static void bdrv_replace_child_safe(BdrvChild *child, BlockDriverState *new_bs,
35
Transaction *tran)
17
{
36
{
18
BDRVQcow2State *s = bs->opaque;
37
@@ -XXX,XX +XXX,XX @@ static int bdrv_replace_node_common(BlockDriverState *from,
19
- QEMUIOVector hd_qiov;
38
bool auto_skip, Error **errp)
39
{
40
BdrvChild *c, *next;
41
- GSList *list = NULL, *p;
42
- uint64_t perm = 0, shared = BLK_PERM_ALL;
43
+ Transaction *tran = tran_new();
44
+ g_autoptr(GHashTable) found = NULL;
45
+ g_autoptr(GSList) refresh_list = NULL;
20
int ret;
46
int ret;
21
ssize_t out_len;
47
22
uint8_t *buf, *out_buf;
48
/* Make sure that @from doesn't go away until we have successfully attached
23
@@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
49
@@ -XXX,XX +XXX,XX @@ static int bdrv_replace_node_common(BlockDriverState *from,
24
goto fail;
50
assert(bdrv_get_aio_context(from) == bdrv_get_aio_context(to));
51
bdrv_drained_begin(from);
52
53
- /* Put all parents into @list and calculate their cumulative permissions */
54
+ /*
55
+ * Do the replacement without permission update.
56
+ * Replacement may influence the permissions, we should calculate new
57
+ * permissions based on new graph. If we fail, we'll roll-back the
58
+ * replacement.
59
+ */
60
QLIST_FOREACH_SAFE(c, &from->parents, next_parent, next) {
61
assert(c->bs == from);
62
if (!should_update_child(c, to)) {
63
@@ -XXX,XX +XXX,XX @@ static int bdrv_replace_node_common(BlockDriverState *from,
64
c->name, from->node_name);
65
goto out;
66
}
67
- list = g_slist_prepend(list, c);
68
- perm |= c->perm;
69
- shared &= c->shared_perm;
70
+ bdrv_replace_child_safe(c, to, tran);
25
}
71
}
26
72
27
- qemu_iovec_init_buf(&hd_qiov, out_buf, out_len);
73
- /* Check whether the required permissions can be granted on @to, ignoring
74
- * all BdrvChild in @list so that they can't block themselves. */
75
- ret = bdrv_check_update_perm(to, NULL, perm, shared, list, errp);
76
- if (ret < 0) {
77
- bdrv_abort_perm_update(to);
78
- goto out;
79
- }
80
+ found = g_hash_table_new(NULL, NULL);
81
82
- /* Now actually perform the change. We performed the permission check for
83
- * all elements of @list at once, so set the permissions all at once at the
84
- * very end. */
85
- for (p = list; p != NULL; p = p->next) {
86
- c = p->data;
87
+ refresh_list = bdrv_topological_dfs(refresh_list, found, to);
88
+ refresh_list = bdrv_topological_dfs(refresh_list, found, from);
89
90
- bdrv_ref(to);
91
- bdrv_replace_child_noperm(c, to);
92
- bdrv_unref(from);
93
+ ret = bdrv_list_refresh_perms(refresh_list, NULL, tran, errp);
94
+ if (ret < 0) {
95
+ goto out;
96
}
97
98
- bdrv_set_perm(to);
28
-
99
-
29
BLKDBG_EVENT(s->data_file, BLKDBG_WRITE_COMPRESSED);
100
ret = 0;
30
- ret = bdrv_co_pwritev(s->data_file, cluster_offset, out_len, &hd_qiov, 0);
101
31
+ ret = bdrv_co_pwrite(s->data_file, cluster_offset, out_len, out_buf, 0);
102
out:
32
if (ret < 0) {
103
- g_slist_free(list);
33
goto fail;
104
+ tran_finalize(tran, ret);
34
}
105
+
35
@@ -XXX,XX +XXX,XX @@ qcow2_co_preadv_compressed(BlockDriverState *bs,
106
bdrv_drained_end(from);
36
int ret = 0, csize, nb_csectors;
107
bdrv_unref(from);
37
uint64_t coffset;
108
38
uint8_t *buf, *out_buf;
109
diff --git a/tests/unit/test-bdrv-graph-mod.c b/tests/unit/test-bdrv-graph-mod.c
39
- QEMUIOVector local_qiov;
110
index XXXXXXX..XXXXXXX 100644
40
int offset_in_cluster = offset_into_cluster(s, offset);
111
--- a/tests/unit/test-bdrv-graph-mod.c
41
112
+++ b/tests/unit/test-bdrv-graph-mod.c
42
coffset = file_cluster_offset & s->cluster_offset_mask;
113
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
43
@@ -XXX,XX +XXX,XX @@ qcow2_co_preadv_compressed(BlockDriverState *bs,
114
test_should_update_child);
44
if (!buf) {
115
g_test_add_func("/bdrv-graph-mod/parallel-perm-update",
45
return -ENOMEM;
116
test_parallel_perm_update);
46
}
117
+ g_test_add_func("/bdrv-graph-mod/parallel-exclusive-write",
47
- qemu_iovec_init_buf(&local_qiov, buf, csize);
118
+ test_parallel_exclusive_write);
48
119
49
out_buf = qemu_blockalign(bs, s->cluster_size);
120
if (debug) {
50
121
- g_test_add_func("/bdrv-graph-mod/parallel-exclusive-write",
51
BLKDBG_EVENT(bs->file, BLKDBG_READ_COMPRESSED);
122
- test_parallel_exclusive_write);
52
- ret = bdrv_co_preadv(bs->file, coffset, csize, &local_qiov, 0);
123
g_test_add_func("/bdrv-graph-mod/append-greedy-filter",
53
+ ret = bdrv_co_pread(bs->file, coffset, csize, buf, 0);
124
test_append_greedy_filter);
54
if (ret < 0) {
55
goto fail;
56
}
125
}
57
--
126
--
58
2.20.1
127
2.30.2
59
128
60
129
diff view generated by jsdifflib
New patch
1
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
3
Split out no-perm part of bdrv_root_attach_child() into separate
4
transaction action. bdrv_root_attach_child() now moves to new
5
permission update paradigm: first update graph relations then update
6
permissions.
7
8
qsd-jobs test output updated. Seems now permission update goes in
9
another order. Still, the test comment say that we only want to check
10
that command doesn't crash, and it's still so.
11
12
Error message is a bit misleading as it looks like job was added first.
13
But actually in new paradigm of graph update we can't distinguish such
14
things. We should update the error message, but let's not do it now.
15
16
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
17
Message-Id: <20210428151804.439460-19-vsementsov@virtuozzo.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
19
---
20
block.c | 190 ++++++++++++++++++--------
21
tests/qemu-iotests/tests/qsd-jobs.out | 2 +-
22
2 files changed, 137 insertions(+), 55 deletions(-)
23
24
diff --git a/block.c b/block.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/block.c
27
+++ b/block.c
28
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs)
29
}
30
}
31
32
-/*
33
- * This function steals the reference to child_bs from the caller.
34
- * That reference is later dropped by bdrv_root_unref_child().
35
- *
36
- * On failure NULL is returned, errp is set and the reference to
37
- * child_bs is also dropped.
38
- *
39
- * The caller must hold the AioContext lock @child_bs, but not that of @ctx
40
- * (unless @child_bs is already in @ctx).
41
- */
42
-BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
43
- const char *child_name,
44
- const BdrvChildClass *child_class,
45
- BdrvChildRole child_role,
46
- uint64_t perm, uint64_t shared_perm,
47
- void *opaque, Error **errp)
48
+static void bdrv_remove_empty_child(BdrvChild *child)
49
{
50
- BdrvChild *child;
51
- Error *local_err = NULL;
52
- int ret;
53
- AioContext *ctx;
54
+ assert(!child->bs);
55
+ QLIST_SAFE_REMOVE(child, next);
56
+ g_free(child->name);
57
+ g_free(child);
58
+}
59
60
- ret = bdrv_check_update_perm(child_bs, NULL, perm, shared_perm, NULL, errp);
61
- if (ret < 0) {
62
- bdrv_abort_perm_update(child_bs);
63
- bdrv_unref(child_bs);
64
- return NULL;
65
+typedef struct BdrvAttachChildCommonState {
66
+ BdrvChild **child;
67
+ AioContext *old_parent_ctx;
68
+ AioContext *old_child_ctx;
69
+} BdrvAttachChildCommonState;
70
+
71
+static void bdrv_attach_child_common_abort(void *opaque)
72
+{
73
+ BdrvAttachChildCommonState *s = opaque;
74
+ BdrvChild *child = *s->child;
75
+ BlockDriverState *bs = child->bs;
76
+
77
+ bdrv_replace_child_noperm(child, NULL);
78
+
79
+ if (bdrv_get_aio_context(bs) != s->old_child_ctx) {
80
+ bdrv_try_set_aio_context(bs, s->old_child_ctx, &error_abort);
81
}
82
83
- child = g_new(BdrvChild, 1);
84
- *child = (BdrvChild) {
85
+ if (bdrv_child_get_parent_aio_context(child) != s->old_parent_ctx) {
86
+ GSList *ignore = g_slist_prepend(NULL, child);
87
+
88
+ child->klass->can_set_aio_ctx(child, s->old_parent_ctx, &ignore,
89
+ &error_abort);
90
+ g_slist_free(ignore);
91
+ ignore = g_slist_prepend(NULL, child);
92
+ child->klass->set_aio_ctx(child, s->old_parent_ctx, &ignore);
93
+
94
+ g_slist_free(ignore);
95
+ }
96
+
97
+ bdrv_unref(bs);
98
+ bdrv_remove_empty_child(child);
99
+ *s->child = NULL;
100
+}
101
+
102
+static TransactionActionDrv bdrv_attach_child_common_drv = {
103
+ .abort = bdrv_attach_child_common_abort,
104
+ .clean = g_free,
105
+};
106
+
107
+/*
108
+ * Common part of attaching bdrv child to bs or to blk or to job
109
+ */
110
+static int bdrv_attach_child_common(BlockDriverState *child_bs,
111
+ const char *child_name,
112
+ const BdrvChildClass *child_class,
113
+ BdrvChildRole child_role,
114
+ uint64_t perm, uint64_t shared_perm,
115
+ void *opaque, BdrvChild **child,
116
+ Transaction *tran, Error **errp)
117
+{
118
+ BdrvChild *new_child;
119
+ AioContext *parent_ctx;
120
+ AioContext *child_ctx = bdrv_get_aio_context(child_bs);
121
+
122
+ assert(child);
123
+ assert(*child == NULL);
124
+
125
+ new_child = g_new(BdrvChild, 1);
126
+ *new_child = (BdrvChild) {
127
.bs = NULL,
128
.name = g_strdup(child_name),
129
.klass = child_class,
130
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
131
.opaque = opaque,
132
};
133
134
- ctx = bdrv_child_get_parent_aio_context(child);
135
-
136
- /* If the AioContexts don't match, first try to move the subtree of
137
+ /*
138
+ * If the AioContexts don't match, first try to move the subtree of
139
* child_bs into the AioContext of the new parent. If this doesn't work,
140
- * try moving the parent into the AioContext of child_bs instead. */
141
- if (bdrv_get_aio_context(child_bs) != ctx) {
142
- ret = bdrv_try_set_aio_context(child_bs, ctx, &local_err);
143
+ * try moving the parent into the AioContext of child_bs instead.
144
+ */
145
+ parent_ctx = bdrv_child_get_parent_aio_context(new_child);
146
+ if (child_ctx != parent_ctx) {
147
+ Error *local_err = NULL;
148
+ int ret = bdrv_try_set_aio_context(child_bs, parent_ctx, &local_err);
149
+
150
if (ret < 0 && child_class->can_set_aio_ctx) {
151
- GSList *ignore = g_slist_prepend(NULL, child);
152
- ctx = bdrv_get_aio_context(child_bs);
153
- if (child_class->can_set_aio_ctx(child, ctx, &ignore, NULL)) {
154
+ GSList *ignore = g_slist_prepend(NULL, new_child);
155
+ if (child_class->can_set_aio_ctx(new_child, child_ctx, &ignore,
156
+ NULL))
157
+ {
158
error_free(local_err);
159
ret = 0;
160
g_slist_free(ignore);
161
- ignore = g_slist_prepend(NULL, child);
162
- child_class->set_aio_ctx(child, ctx, &ignore);
163
+ ignore = g_slist_prepend(NULL, new_child);
164
+ child_class->set_aio_ctx(new_child, child_ctx, &ignore);
165
}
166
g_slist_free(ignore);
167
}
168
+
169
if (ret < 0) {
170
error_propagate(errp, local_err);
171
- g_free(child);
172
- bdrv_abort_perm_update(child_bs);
173
- bdrv_unref(child_bs);
174
- return NULL;
175
+ bdrv_remove_empty_child(new_child);
176
+ return ret;
177
}
178
}
179
180
- /* This performs the matching bdrv_set_perm() for the above check. */
181
- bdrv_replace_child(child, child_bs);
182
+ bdrv_ref(child_bs);
183
+ bdrv_replace_child_noperm(new_child, child_bs);
184
185
+ *child = new_child;
186
+
187
+ BdrvAttachChildCommonState *s = g_new(BdrvAttachChildCommonState, 1);
188
+ *s = (BdrvAttachChildCommonState) {
189
+ .child = child,
190
+ .old_parent_ctx = parent_ctx,
191
+ .old_child_ctx = child_ctx,
192
+ };
193
+ tran_add(tran, &bdrv_attach_child_common_drv, s);
194
+
195
+ return 0;
196
+}
197
+
198
+static void bdrv_detach_child(BdrvChild *child)
199
+{
200
+ bdrv_replace_child(child, NULL);
201
+ bdrv_remove_empty_child(child);
202
+}
203
+
204
+/*
205
+ * This function steals the reference to child_bs from the caller.
206
+ * That reference is later dropped by bdrv_root_unref_child().
207
+ *
208
+ * On failure NULL is returned, errp is set and the reference to
209
+ * child_bs is also dropped.
210
+ *
211
+ * The caller must hold the AioContext lock @child_bs, but not that of @ctx
212
+ * (unless @child_bs is already in @ctx).
213
+ */
214
+BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
215
+ const char *child_name,
216
+ const BdrvChildClass *child_class,
217
+ BdrvChildRole child_role,
218
+ uint64_t perm, uint64_t shared_perm,
219
+ void *opaque, Error **errp)
220
+{
221
+ int ret;
222
+ BdrvChild *child = NULL;
223
+ Transaction *tran = tran_new();
224
+
225
+ ret = bdrv_attach_child_common(child_bs, child_name, child_class,
226
+ child_role, perm, shared_perm, opaque,
227
+ &child, tran, errp);
228
+ if (ret < 0) {
229
+ bdrv_unref(child_bs);
230
+ return NULL;
231
+ }
232
+
233
+ ret = bdrv_refresh_perms(child_bs, errp);
234
+ tran_finalize(tran, ret);
235
+
236
+ bdrv_unref(child_bs);
237
return child;
238
}
239
240
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
241
return child;
242
}
243
244
-static void bdrv_detach_child(BdrvChild *child)
245
-{
246
- QLIST_SAFE_REMOVE(child, next);
247
-
248
- bdrv_replace_child(child, NULL);
249
-
250
- g_free(child->name);
251
- g_free(child);
252
-}
253
-
254
/* Callers must ensure that child->frozen is false. */
255
void bdrv_root_unref_child(BdrvChild *child)
256
{
257
diff --git a/tests/qemu-iotests/tests/qsd-jobs.out b/tests/qemu-iotests/tests/qsd-jobs.out
258
index XXXXXXX..XXXXXXX 100644
259
--- a/tests/qemu-iotests/tests/qsd-jobs.out
260
+++ b/tests/qemu-iotests/tests/qsd-jobs.out
261
@@ -XXX,XX +XXX,XX @@ QMP_VERSION
262
{"return": {}}
263
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
264
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
265
-{"error": {"class": "GenericError", "desc": "Conflicts with use by a block device as 'root', which uses 'write' on fmt_base"}}
266
+{"error": {"class": "GenericError", "desc": "Conflicts with use by stream job 'job0' as 'intermediate node', which does not allow 'write' on fmt_base"}}
267
{"return": {}}
268
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "export1"}}
269
*** done
270
--
271
2.30.2
272
273
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
This tests the fix from the previous patch.
3
Split no-perm part of bdrv_attach_child as separate transaction action.
4
It will be used in later commits.
4
5
5
Signed-off-by: Alberto Garcia <berto@igalia.com>
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
8
Message-Id: <20210428151804.439460-20-vsementsov@virtuozzo.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
10
---
8
tests/qemu-iotests/249 | 115 +++++++++++++++++++++++++++++++++++++
11
block.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++-----------
9
tests/qemu-iotests/249.out | 35 +++++++++++
12
1 file changed, 58 insertions(+), 13 deletions(-)
10
tests/qemu-iotests/group | 1 +
11
3 files changed, 151 insertions(+)
12
create mode 100755 tests/qemu-iotests/249
13
create mode 100644 tests/qemu-iotests/249.out
14
13
15
diff --git a/tests/qemu-iotests/249 b/tests/qemu-iotests/249
14
diff --git a/block.c b/block.c
16
new file mode 100755
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX
16
--- a/block.c
18
--- /dev/null
17
+++ b/block.c
19
+++ b/tests/qemu-iotests/249
18
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
20
@@ -XXX,XX +XXX,XX @@
19
21
+#!/usr/bin/env bash
20
static void bdrv_replace_child_noperm(BdrvChild *child,
22
+#
21
BlockDriverState *new_bs);
23
+# Test that a backing image is put back in read-only mode after
22
+static int bdrv_attach_child_noperm(BlockDriverState *parent_bs,
24
+# block-commit (both when it fails and when it succeeds).
23
+ BlockDriverState *child_bs,
25
+#
24
+ const char *child_name,
26
+# Copyright (C) 2019 Igalia, S.L.
25
+ const BdrvChildClass *child_class,
27
+#
26
+ BdrvChildRole child_role,
28
+# This program is free software; you can redistribute it and/or modify
27
+ BdrvChild **child,
29
+# it under the terms of the GNU General Public License as published by
28
+ Transaction *tran,
30
+# the Free Software Foundation; either version 2 of the License, or
29
+ Error **errp);
31
+# (at your option) any later version.
30
32
+#
31
static int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue
33
+# This program is distributed in the hope that it will be useful,
32
*queue, Error **errp);
34
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
33
@@ -XXX,XX +XXX,XX @@ static int bdrv_attach_child_common(BlockDriverState *child_bs,
35
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34
return 0;
36
+# GNU General Public License for more details.
35
}
37
+#
36
38
+# You should have received a copy of the GNU General Public License
37
+static int bdrv_attach_child_noperm(BlockDriverState *parent_bs,
39
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
38
+ BlockDriverState *child_bs,
40
+#
39
+ const char *child_name,
40
+ const BdrvChildClass *child_class,
41
+ BdrvChildRole child_role,
42
+ BdrvChild **child,
43
+ Transaction *tran,
44
+ Error **errp)
45
+{
46
+ int ret;
47
+ uint64_t perm, shared_perm;
41
+
48
+
42
+# creator
49
+ assert(parent_bs->drv);
43
+owner=berto@igalia.com
44
+
50
+
45
+seq="$(basename $0)"
51
+ bdrv_get_cumulative_perm(parent_bs, &perm, &shared_perm);
46
+echo "QA output created by $seq"
52
+ bdrv_child_perm(parent_bs, child_bs, NULL, child_role, NULL,
53
+ perm, shared_perm, &perm, &shared_perm);
47
+
54
+
48
+status=1    # failure is the default!
55
+ ret = bdrv_attach_child_common(child_bs, child_name, child_class,
56
+ child_role, perm, shared_perm, parent_bs,
57
+ child, tran, errp);
58
+ if (ret < 0) {
59
+ return ret;
60
+ }
49
+
61
+
50
+_cleanup()
62
+ QLIST_INSERT_HEAD(&parent_bs->children, *child, next);
51
+{
63
+ /*
52
+ _cleanup_test_img
64
+ * child is removed in bdrv_attach_child_common_abort(), so don't care to
53
+ rm -f "$TEST_IMG.base"
65
+ * abort this change separately.
54
+ rm -f "$TEST_IMG.int"
66
+ */
67
+
68
+ return 0;
55
+}
69
+}
56
+trap "_cleanup; exit \$status" 0 1 2 3 15
57
+
70
+
58
+# get standard environment, filters and checks
71
static void bdrv_detach_child(BdrvChild *child)
59
+. ./common.rc
72
{
60
+. ./common.filter
73
bdrv_replace_child(child, NULL);
61
+. ./common.qemu
74
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
75
BdrvChildRole child_role,
76
Error **errp)
77
{
78
- BdrvChild *child;
79
- uint64_t perm, shared_perm;
80
-
81
- bdrv_get_cumulative_perm(parent_bs, &perm, &shared_perm);
82
+ int ret;
83
+ BdrvChild *child = NULL;
84
+ Transaction *tran = tran_new();
85
86
- assert(parent_bs->drv);
87
- bdrv_child_perm(parent_bs, child_bs, NULL, child_role, NULL,
88
- perm, shared_perm, &perm, &shared_perm);
89
+ ret = bdrv_attach_child_noperm(parent_bs, child_bs, child_name, child_class,
90
+ child_role, &child, tran, errp);
91
+ if (ret < 0) {
92
+ goto out;
93
+ }
94
95
- child = bdrv_root_attach_child(child_bs, child_name, child_class,
96
- child_role, perm, shared_perm, parent_bs,
97
- errp);
98
- if (child == NULL) {
99
- return NULL;
100
+ ret = bdrv_refresh_perms(parent_bs, errp);
101
+ if (ret < 0) {
102
+ goto out;
103
}
104
105
- QLIST_INSERT_HEAD(&parent_bs->children, child, next);
106
+out:
107
+ tran_finalize(tran, ret);
62
+
108
+
63
+# Any format implementing BlockDriver.bdrv_change_backing_file
109
+ bdrv_unref(child_bs);
64
+_supported_fmt qcow2 qed
65
+_supported_proto file
66
+_supported_os Linux
67
+
110
+
68
+IMG_SIZE=1M
111
return child;
69
+
112
}
70
+# Create the images: base <- int <- active
113
71
+TEST_IMG="$TEST_IMG.base" _make_test_img $IMG_SIZE | _filter_imgfmt
72
+TEST_IMG="$TEST_IMG.int" _make_test_img -b "$TEST_IMG.base" | _filter_imgfmt
73
+_make_test_img -b "$TEST_IMG.int" | _filter_imgfmt
74
+
75
+# Launch QEMU with these two drives:
76
+# none0: base (read-only)
77
+# none1: base <- int <- active
78
+_launch_qemu -drive if=none,file="${TEST_IMG}.base",node-name=base,read-only=on \
79
+ -drive if=none,file="${TEST_IMG}",backing.node-name=int,backing.backing=base
80
+
81
+_send_qemu_cmd $QEMU_HANDLE \
82
+ "{ 'execute': 'qmp_capabilities' }" \
83
+ 'return'
84
+
85
+echo
86
+echo '=== Send a write command to a drive opened in read-only mode (1)'
87
+echo
88
+_send_qemu_cmd $QEMU_HANDLE \
89
+ "{ 'execute': 'human-monitor-command',
90
+ 'arguments': {'command-line': 'qemu-io none0 \"aio_write 0 2k\"'}}" \
91
+ 'return'
92
+
93
+echo
94
+echo '=== Run block-commit on base using an invalid filter node name'
95
+echo
96
+_send_qemu_cmd $QEMU_HANDLE \
97
+ "{ 'execute': 'block-commit',
98
+ 'arguments': {'job-id': 'job0', 'device': 'none1', 'top-node': 'int',
99
+ 'filter-node-name': '1234'}}" \
100
+ 'error'
101
+
102
+echo
103
+echo '=== Send a write command to a drive opened in read-only mode (2)'
104
+echo
105
+_send_qemu_cmd $QEMU_HANDLE \
106
+ "{ 'execute': 'human-monitor-command',
107
+ 'arguments': {'command-line': 'qemu-io none0 \"aio_write 0 2k\"'}}" \
108
+ 'return'
109
+
110
+echo
111
+echo '=== Run block-commit on base using the default filter node name'
112
+echo
113
+_send_qemu_cmd $QEMU_HANDLE \
114
+ "{ 'execute': 'block-commit',
115
+ 'arguments': {'job-id': 'job0', 'device': 'none1', 'top-node': 'int'}}" \
116
+ 'return'
117
+
118
+# Wait for block-commit to finish
119
+_send_qemu_cmd $QEMU_HANDLE '' \
120
+ '"status": "null"'
121
+
122
+echo
123
+echo '=== Send a write command to a drive opened in read-only mode (3)'
124
+echo
125
+_send_qemu_cmd $QEMU_HANDLE \
126
+ "{ 'execute': 'human-monitor-command',
127
+ 'arguments': {'command-line': 'qemu-io none0 \"aio_write 0 2k\"'}}" \
128
+ 'return'
129
+
130
+_cleanup_qemu
131
+
132
+# success, all done
133
+echo "*** done"
134
+rm -f $seq.full
135
+status=0
136
diff --git a/tests/qemu-iotests/249.out b/tests/qemu-iotests/249.out
137
new file mode 100644
138
index XXXXXXX..XXXXXXX
139
--- /dev/null
140
+++ b/tests/qemu-iotests/249.out
141
@@ -XXX,XX +XXX,XX @@
142
+QA output created by 249
143
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=1048576
144
+Formatting 'TEST_DIR/t.IMGFMT.int', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT.base
145
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT.int
146
+{"return": {}}
147
+
148
+=== Send a write command to a drive opened in read-only mode (1)
149
+
150
+{"return": "Block node is read-onlyrn"}
151
+
152
+=== Run block-commit on base using an invalid filter node name
153
+
154
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
155
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
156
+{"error": {"class": "GenericError", "desc": "Invalid node name"}}
157
+
158
+=== Send a write command to a drive opened in read-only mode (2)
159
+
160
+{"return": "Block node is read-onlyrn"}
161
+
162
+=== Run block-commit on base using the default filter node name
163
+
164
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
165
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
166
+{"return": {}}
167
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job0"}}
168
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job0"}}
169
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job0", "len": 1048576, "offset": 1048576, "speed": 0, "type": "commit"}}
170
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
171
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
172
+
173
+=== Send a write command to a drive opened in read-only mode (3)
174
+
175
+{"return": "Block node is read-onlyrn"}
176
+*** done
177
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
178
index XXXXXXX..XXXXXXX 100644
179
--- a/tests/qemu-iotests/group
180
+++ b/tests/qemu-iotests/group
181
@@ -XXX,XX +XXX,XX @@
182
246 rw auto quick
183
247 rw auto quick
184
248 rw auto quick
185
+249 rw auto quick
186
--
114
--
187
2.20.1
115
2.30.2
188
116
189
117
diff view generated by jsdifflib
1
make_completely_empty() is an optimisated path for bdrv_make_empty()
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
where completely new metadata is created inside the image file instead
3
of going through all clusters and discarding them. For an external data
4
file, however, we actually need to do discard operations on the data
5
file; just overwriting the qcow2 file doesn't get rid of the data.
6
2
7
The necessary slow path with an explicit discard operation already
3
Split part of bdrv_replace_node_common() to be used separately.
8
exists for other cases. Use it for external data files, too.
9
4
10
Cc: qemu-stable@nongnu.org
5
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
7
Message-Id: <20210428151804.439460-21-vsementsov@virtuozzo.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Reviewed-by: Eric Blake <eblake@redhat.com>
13
---
9
---
14
block/qcow2.c | 7 +++++--
10
block.c | 50 +++++++++++++++++++++++++++++++-------------------
15
1 file changed, 5 insertions(+), 2 deletions(-)
11
1 file changed, 31 insertions(+), 19 deletions(-)
16
12
17
diff --git a/block/qcow2.c b/block/qcow2.c
13
diff --git a/block.c b/block.c
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/block/qcow2.c
15
--- a/block.c
20
+++ b/block/qcow2.c
16
+++ b/block.c
21
@@ -XXX,XX +XXX,XX @@ static int qcow2_make_empty(BlockDriverState *bs)
17
@@ -XXX,XX +XXX,XX @@ static bool should_update_child(BdrvChild *c, BlockDriverState *to)
22
18
return ret;
23
if (s->qcow_version >= 3 && !s->snapshots && !s->nb_bitmaps &&
19
}
24
3 + l1_clusters <= s->refcount_block_size &&
20
25
- s->crypt_method_header != QCOW_CRYPT_LUKS) {
21
+static int bdrv_replace_node_noperm(BlockDriverState *from,
26
+ s->crypt_method_header != QCOW_CRYPT_LUKS &&
22
+ BlockDriverState *to,
27
+ !has_data_file(bs)) {
23
+ bool auto_skip, Transaction *tran,
28
/* The following function only works for qcow2 v3 images (it
24
+ Error **errp)
29
* requires the dirty flag) and only as long as there are no
25
+{
30
* features that reserve extra clusters (such as snapshots,
26
+ BdrvChild *c, *next;
31
* LUKS header, or persistent bitmaps), because it completely
27
+
32
* empties the image. Furthermore, the L1 table and three
28
+ QLIST_FOREACH_SAFE(c, &from->parents, next_parent, next) {
33
* additional clusters (image header, refcount table, one
29
+ assert(c->bs == from);
34
- * refcount block) have to fit inside one refcount block. */
30
+ if (!should_update_child(c, to)) {
35
+ * refcount block) have to fit inside one refcount block. It
31
+ if (auto_skip) {
36
+ * only resets the image file, i.e. does not work with an
32
+ continue;
37
+ * external data file. */
33
+ }
38
return make_completely_empty(bs);
34
+ error_setg(errp, "Should not change '%s' link to '%s'",
35
+ c->name, from->node_name);
36
+ return -EINVAL;
37
+ }
38
+ if (c->frozen) {
39
+ error_setg(errp, "Cannot change '%s' link to '%s'",
40
+ c->name, from->node_name);
41
+ return -EPERM;
42
+ }
43
+ bdrv_replace_child_safe(c, to, tran);
44
+ }
45
+
46
+ return 0;
47
+}
48
+
49
/*
50
* With auto_skip=true bdrv_replace_node_common skips updating from parents
51
* if it creates a parent-child relation loop or if parent is block-job.
52
@@ -XXX,XX +XXX,XX @@ static int bdrv_replace_node_common(BlockDriverState *from,
53
BlockDriverState *to,
54
bool auto_skip, Error **errp)
55
{
56
- BdrvChild *c, *next;
57
Transaction *tran = tran_new();
58
g_autoptr(GHashTable) found = NULL;
59
g_autoptr(GSList) refresh_list = NULL;
60
@@ -XXX,XX +XXX,XX @@ static int bdrv_replace_node_common(BlockDriverState *from,
61
* permissions based on new graph. If we fail, we'll roll-back the
62
* replacement.
63
*/
64
- QLIST_FOREACH_SAFE(c, &from->parents, next_parent, next) {
65
- assert(c->bs == from);
66
- if (!should_update_child(c, to)) {
67
- if (auto_skip) {
68
- continue;
69
- }
70
- ret = -EINVAL;
71
- error_setg(errp, "Should not change '%s' link to '%s'",
72
- c->name, from->node_name);
73
- goto out;
74
- }
75
- if (c->frozen) {
76
- ret = -EPERM;
77
- error_setg(errp, "Cannot change '%s' link to '%s'",
78
- c->name, from->node_name);
79
- goto out;
80
- }
81
- bdrv_replace_child_safe(c, to, tran);
82
+ ret = bdrv_replace_node_noperm(from, to, auto_skip, tran, errp);
83
+ if (ret < 0) {
84
+ goto out;
39
}
85
}
40
86
87
found = g_hash_table_new(NULL, NULL);
41
--
88
--
42
2.20.1
89
2.30.2
43
90
44
91
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
In the "amend" section of 082, we perform a single "convert" test
3
bdrv_append is not very good for inserting filters: it does extra
4
(namely "convert -o help"). That does not make sense, especially
4
permission update as part of bdrv_set_backing_hd(). During this update
5
because we have done exactly that "convert" test earlier in 082 already.
5
filter may conflict with other parents of top_bs.
6
6
7
Replacing "convert" by "amend" yields an error, which is correct because
7
Instead, let's first do all graph modifications and after it update
8
there is no point in "amend" having a default format. The user has to
8
permissions.
9
either specify the format, or give a file for qemu-img to probe.
10
9
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
append-greedy-filter test-case in test-bdrv-graph-mod is now works, so
12
Reviewed-by: John Snow <jsnow@redhat.com>
11
move it out of debug option.
12
13
Note: bdrv_append() is still only works for backing-child based
14
filters. It's something to improve later.
15
16
Note2: we use the fact that bdrv_append() is used to append new nodes,
17
without backing child, so we don't need frozen check and inherits_from
18
logic from bdrv_set_backing_hd().
19
20
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
21
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
22
Message-Id: <20210428151804.439460-22-vsementsov@virtuozzo.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
23
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
24
---
15
tests/qemu-iotests/082 | 5 ++++-
25
block.c | 27 ++++++++++++++++++++-------
16
tests/qemu-iotests/082.out | 5 ++---
26
tests/unit/test-bdrv-graph-mod.c | 17 ++---------------
17
2 files changed, 6 insertions(+), 4 deletions(-)
27
2 files changed, 22 insertions(+), 22 deletions(-)
18
28
19
diff --git a/tests/qemu-iotests/082 b/tests/qemu-iotests/082
29
diff --git a/block.c b/block.c
20
index XXXXXXX..XXXXXXX 100755
30
index XXXXXXX..XXXXXXX 100644
21
--- a/tests/qemu-iotests/082
31
--- a/block.c
22
+++ b/tests/qemu-iotests/082
32
+++ b/block.c
23
@@ -XXX,XX +XXX,XX @@ run_qemu_img amend -f $IMGFMT -o backing_file="$TEST_IMG" -o ,, -o help "$TEST_I
33
@@ -XXX,XX +XXX,XX @@ int bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
24
34
* This will modify the BlockDriverState fields, and swap contents
25
# Leave out everything that isn't needed
35
* between bs_new and bs_top. Both bs_new and bs_top are modified.
26
run_qemu_img amend -f $IMGFMT -o help
36
*
27
-run_qemu_img convert -o help
37
- * bs_new must not be attached to a BlockBackend.
38
+ * bs_new must not be attached to a BlockBackend and must not have backing
39
+ * child.
40
*
41
* This function does not create any image files.
42
*/
43
int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
44
Error **errp)
45
{
46
- int ret = bdrv_set_backing_hd(bs_new, bs_top, errp);
47
+ int ret;
48
+ Transaction *tran = tran_new();
28
+
49
+
29
+# amend requires specifying either a format explicitly, or a file
50
+ assert(!bs_new->backing);
30
+# which it can probe
51
+
31
+run_qemu_img amend -o help
52
+ ret = bdrv_attach_child_noperm(bs_new, bs_top, "backing",
32
53
+ &child_of_bds, bdrv_backing_role(bs_new),
33
# Try help option for a format that does not support amendment
54
+ &bs_new->backing, tran, errp);
34
run_qemu_img amend -f bochs -o help
55
if (ret < 0) {
35
diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out
56
- return ret;
57
+ goto out;
58
}
59
60
- ret = bdrv_replace_node(bs_top, bs_new, errp);
61
+ ret = bdrv_replace_node_noperm(bs_top, bs_new, true, tran, errp);
62
if (ret < 0) {
63
- bdrv_set_backing_hd(bs_new, NULL, &error_abort);
64
- return ret;
65
+ goto out;
66
}
67
68
- return 0;
69
+ ret = bdrv_refresh_perms(bs_new, errp);
70
+out:
71
+ tran_finalize(tran, ret);
72
+
73
+ bdrv_refresh_limits(bs_top, NULL);
74
+
75
+ return ret;
76
}
77
78
static void bdrv_delete(BlockDriverState *bs)
79
diff --git a/tests/unit/test-bdrv-graph-mod.c b/tests/unit/test-bdrv-graph-mod.c
36
index XXXXXXX..XXXXXXX 100644
80
index XXXXXXX..XXXXXXX 100644
37
--- a/tests/qemu-iotests/082.out
81
--- a/tests/unit/test-bdrv-graph-mod.c
38
+++ b/tests/qemu-iotests/082.out
82
+++ b/tests/unit/test-bdrv-graph-mod.c
39
@@ -XXX,XX +XXX,XX @@ Creation options for 'qcow2':
83
@@ -XXX,XX +XXX,XX @@ static void test_append_greedy_filter(void)
40
84
41
Note that not all of these options may be amendable.
85
int main(int argc, char *argv[])
42
86
{
43
-Testing: convert -o help
87
- int i;
44
-Supported options:
88
- bool debug = false;
45
- size=<size> - Virtual disk size
89
-
46
+Testing: amend -o help
90
- for (i = 1; i < argc; i++) {
47
+qemu-img: Expecting one image file name
91
- if (!strcmp(argv[i], "-d")) {
48
92
- debug = true;
49
Testing: amend -f bochs -o help
93
- break;
50
qemu-img: Format driver 'bochs' does not support option amendment
94
- }
95
- }
96
-
97
bdrv_init();
98
qemu_init_main_loop(&error_abort);
99
100
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
101
test_parallel_perm_update);
102
g_test_add_func("/bdrv-graph-mod/parallel-exclusive-write",
103
test_parallel_exclusive_write);
104
-
105
- if (debug) {
106
- g_test_add_func("/bdrv-graph-mod/append-greedy-filter",
107
- test_append_greedy_filter);
108
- }
109
+ g_test_add_func("/bdrv-graph-mod/append-greedy-filter",
110
+ test_append_greedy_filter);
111
112
return g_test_run();
113
}
51
--
114
--
52
2.20.1
115
2.30.2
53
116
54
117
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
3
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
4
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
4
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
5
Message-Id: <20210428151804.439460-23-vsementsov@virtuozzo.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
7
---
8
block/stream.c | 4 +---
8
block.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
9
1 file changed, 1 insertion(+), 3 deletions(-)
9
1 file changed, 82 insertions(+), 2 deletions(-)
10
10
11
diff --git a/block/stream.c b/block/stream.c
11
diff --git a/block.c b/block.c
12
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
13
--- a/block/stream.c
13
--- a/block.c
14
+++ b/block/stream.c
14
+++ b/block.c
15
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn stream_populate(BlockBackend *blk,
15
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs)
16
int64_t offset, uint64_t bytes,
16
}
17
void *buf)
17
}
18
19
+static void bdrv_child_free(void *opaque)
20
+{
21
+ BdrvChild *c = opaque;
22
+
23
+ g_free(c->name);
24
+ g_free(c);
25
+}
26
+
27
static void bdrv_remove_empty_child(BdrvChild *child)
18
{
28
{
19
- QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
29
assert(!child->bs);
20
-
30
QLIST_SAFE_REMOVE(child, next);
21
assert(bytes < SIZE_MAX);
31
- g_free(child->name);
22
32
- g_free(child);
23
/* Copy-on-read the unallocated clusters */
33
+ bdrv_child_free(child);
24
- return blk_co_preadv(blk, offset, qiov.size, &qiov, BDRV_REQ_COPY_ON_READ);
25
+ return blk_co_pread(blk, offset, bytes, buf, BDRV_REQ_COPY_ON_READ);
26
}
34
}
27
35
28
static void stream_abort(Job *job)
36
typedef struct BdrvAttachChildCommonState {
37
@@ -XXX,XX +XXX,XX @@ static bool should_update_child(BdrvChild *c, BlockDriverState *to)
38
return ret;
39
}
40
41
+typedef struct BdrvRemoveFilterOrCowChild {
42
+ BdrvChild *child;
43
+ bool is_backing;
44
+} BdrvRemoveFilterOrCowChild;
45
+
46
+static void bdrv_remove_filter_or_cow_child_abort(void *opaque)
47
+{
48
+ BdrvRemoveFilterOrCowChild *s = opaque;
49
+ BlockDriverState *parent_bs = s->child->opaque;
50
+
51
+ QLIST_INSERT_HEAD(&parent_bs->children, s->child, next);
52
+ if (s->is_backing) {
53
+ parent_bs->backing = s->child;
54
+ } else {
55
+ parent_bs->file = s->child;
56
+ }
57
+
58
+ /*
59
+ * We don't have to restore child->bs here to undo bdrv_replace_child()
60
+ * because that function is transactionable and it registered own completion
61
+ * entries in @tran, so .abort() for bdrv_replace_child_safe() will be
62
+ * called automatically.
63
+ */
64
+}
65
+
66
+static void bdrv_remove_filter_or_cow_child_commit(void *opaque)
67
+{
68
+ BdrvRemoveFilterOrCowChild *s = opaque;
69
+
70
+ bdrv_child_free(s->child);
71
+}
72
+
73
+static TransactionActionDrv bdrv_remove_filter_or_cow_child_drv = {
74
+ .abort = bdrv_remove_filter_or_cow_child_abort,
75
+ .commit = bdrv_remove_filter_or_cow_child_commit,
76
+ .clean = g_free,
77
+};
78
+
79
+/*
80
+ * A function to remove backing-chain child of @bs if exists: cow child for
81
+ * format nodes (always .backing) and filter child for filters (may be .file or
82
+ * .backing)
83
+ */
84
+__attribute__((unused))
85
+static void bdrv_remove_filter_or_cow_child(BlockDriverState *bs,
86
+ Transaction *tran)
87
+{
88
+ BdrvRemoveFilterOrCowChild *s;
89
+ BdrvChild *child = bdrv_filter_or_cow_child(bs);
90
+
91
+ if (!child) {
92
+ return;
93
+ }
94
+
95
+ if (child->bs) {
96
+ bdrv_replace_child_safe(child, NULL, tran);
97
+ }
98
+
99
+ s = g_new(BdrvRemoveFilterOrCowChild, 1);
100
+ *s = (BdrvRemoveFilterOrCowChild) {
101
+ .child = child,
102
+ .is_backing = (child == bs->backing),
103
+ };
104
+ tran_add(tran, &bdrv_remove_filter_or_cow_child_drv, s);
105
+
106
+ QLIST_SAFE_REMOVE(child, next);
107
+ if (s->is_backing) {
108
+ bs->backing = NULL;
109
+ } else {
110
+ bs->file = NULL;
111
+ }
112
+}
113
+
114
static int bdrv_replace_node_noperm(BlockDriverState *from,
115
BlockDriverState *to,
116
bool auto_skip, Transaction *tran,
29
--
117
--
30
2.20.1
118
2.30.2
31
119
32
120
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
Using bdrv_replace_node() for removing filter is not good enough: it
4
keeps child reference of the filter, which may conflict with original
5
top node during permission update.
6
7
Instead let's create new interface, which will do all graph
8
modifications first and then update permissions.
9
10
Let's modify bdrv_replace_node_common(), allowing it additionally drop
11
backing chain child link pointing to new node. This is quite
12
appropriate for bdrv_drop_intermediate() and makes possible to add
13
new bdrv_drop_filter() as a simple wrapper.
14
3
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
15
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
4
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
16
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
17
Message-Id: <20210428151804.439460-24-vsementsov@virtuozzo.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
19
---
8
block/backup.c | 14 ++++++--------
20
include/block/block.h | 1 +
9
1 file changed, 6 insertions(+), 8 deletions(-)
21
block.c | 43 +++++++++++++++++++++++++++++++++++++++----
22
2 files changed, 40 insertions(+), 4 deletions(-)
10
23
11
diff --git a/block/backup.c b/block/backup.c
24
diff --git a/include/block/block.h b/include/block/block.h
12
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
13
--- a/block/backup.c
26
--- a/include/block/block.h
14
+++ b/block/backup.c
27
+++ b/include/block/block.h
15
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job,
28
@@ -XXX,XX +XXX,XX @@ int bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
16
void **bounce_buffer)
29
Error **errp);
30
BlockDriverState *bdrv_insert_node(BlockDriverState *bs, QDict *node_options,
31
int flags, Error **errp);
32
+int bdrv_drop_filter(BlockDriverState *bs, Error **errp);
33
34
int bdrv_parse_aio(const char *mode, int *flags);
35
int bdrv_parse_cache_mode(const char *mode, int *flags, bool *writethrough);
36
diff --git a/block.c b/block.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/block.c
39
+++ b/block.c
40
@@ -XXX,XX +XXX,XX @@ static TransactionActionDrv bdrv_remove_filter_or_cow_child_drv = {
41
* format nodes (always .backing) and filter child for filters (may be .file or
42
* .backing)
43
*/
44
-__attribute__((unused))
45
static void bdrv_remove_filter_or_cow_child(BlockDriverState *bs,
46
Transaction *tran)
17
{
47
{
48
@@ -XXX,XX +XXX,XX @@ static int bdrv_replace_node_noperm(BlockDriverState *from,
49
*
50
* With auto_skip=false the error is returned if from has a parent which should
51
* not be updated.
52
+ *
53
+ * With @detach_subchain=true @to must be in a backing chain of @from. In this
54
+ * case backing link of the cow-parent of @to is removed.
55
*/
56
static int bdrv_replace_node_common(BlockDriverState *from,
57
BlockDriverState *to,
58
- bool auto_skip, Error **errp)
59
+ bool auto_skip, bool detach_subchain,
60
+ Error **errp)
61
{
62
Transaction *tran = tran_new();
63
g_autoptr(GHashTable) found = NULL;
64
g_autoptr(GSList) refresh_list = NULL;
65
+ BlockDriverState *to_cow_parent;
18
int ret;
66
int ret;
19
- QEMUIOVector qiov;
67
20
BlockBackend *blk = job->common.blk;
68
+ if (detach_subchain) {
21
int nbytes;
69
+ assert(bdrv_chain_contains(from, to));
22
int read_flags = is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0;
70
+ assert(from != to);
23
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job,
71
+ for (to_cow_parent = from;
24
if (!*bounce_buffer) {
72
+ bdrv_filter_or_cow_bs(to_cow_parent) != to;
25
*bounce_buffer = blk_blockalign(blk, job->cluster_size);
73
+ to_cow_parent = bdrv_filter_or_cow_bs(to_cow_parent))
74
+ {
75
+ ;
76
+ }
77
+ }
78
+
79
/* Make sure that @from doesn't go away until we have successfully attached
80
* all of its parents to @to. */
81
bdrv_ref(from);
82
@@ -XXX,XX +XXX,XX @@ static int bdrv_replace_node_common(BlockDriverState *from,
83
goto out;
26
}
84
}
27
- qemu_iovec_init_buf(&qiov, *bounce_buffer, nbytes);
85
28
86
+ if (detach_subchain) {
29
- ret = blk_co_preadv(blk, start, qiov.size, &qiov, read_flags);
87
+ bdrv_remove_filter_or_cow_child(to_cow_parent, tran);
30
+ ret = blk_co_pread(blk, start, nbytes, *bounce_buffer, read_flags);
88
+ }
31
if (ret < 0) {
89
+
32
trace_backup_do_cow_read_fail(job, start, ret);
90
found = g_hash_table_new(NULL, NULL);
33
if (error_is_read) {
91
34
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job,
92
refresh_list = bdrv_topological_dfs(refresh_list, found, to);
35
goto fail;
93
@@ -XXX,XX +XXX,XX @@ out:
94
int bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
95
Error **errp)
96
{
97
- return bdrv_replace_node_common(from, to, true, errp);
98
+ return bdrv_replace_node_common(from, to, true, false, errp);
99
+}
100
+
101
+int bdrv_drop_filter(BlockDriverState *bs, Error **errp)
102
+{
103
+ return bdrv_replace_node_common(bs, bdrv_filter_or_cow_bs(bs), true, true,
104
+ errp);
105
}
106
107
/*
108
@@ -XXX,XX +XXX,XX @@ int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base,
109
updated_children = g_slist_prepend(updated_children, c);
36
}
110
}
37
111
38
- if (qemu_iovec_is_zero(&qiov)) {
112
- bdrv_replace_node_common(top, base, false, &local_err);
39
+ if (buffer_is_zero(*bounce_buffer, nbytes)) {
113
+ /*
40
ret = blk_co_pwrite_zeroes(job->target, start,
114
+ * It seems correct to pass detach_subchain=true here, but it triggers
41
- qiov.size, write_flags | BDRV_REQ_MAY_UNMAP);
115
+ * one more yet not fixed bug, when due to nested aio_poll loop we switch to
42
+ nbytes, write_flags | BDRV_REQ_MAY_UNMAP);
116
+ * another drained section, which modify the graph (for example, removing
43
} else {
117
+ * the child, which we keep in updated_children list). So, it's a TODO.
44
- ret = blk_co_pwritev(job->target, start,
118
+ *
45
- qiov.size, &qiov, write_flags |
119
+ * Note, bug triggered if pass detach_subchain=true here and run
46
- (job->compress ? BDRV_REQ_WRITE_COMPRESSED : 0));
120
+ * test-bdrv-drain. test_drop_intermediate_poll() test-case will crash.
47
+ ret = blk_co_pwrite(job->target, start,
121
+ * That's a FIXME.
48
+ nbytes, *bounce_buffer, write_flags |
122
+ */
49
+ (job->compress ? BDRV_REQ_WRITE_COMPRESSED : 0));
123
+ bdrv_replace_node_common(top, base, false, false, &local_err);
50
}
124
if (local_err) {
51
if (ret < 0) {
125
error_report_err(local_err);
52
trace_backup_do_cow_write_fail(job, start, ret);
126
goto exit;
53
--
127
--
54
2.20.1
128
2.30.2
55
129
56
130
diff view generated by jsdifflib
1
From: Stefano Garzarella <sgarzare@redhat.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
IEC binary prefixes are already defined in "qemu/units.h",
3
We don't need this workaround anymore: bdrv_append is already smart
4
so we can remove redundant definitions in "block/vhdx.h".
4
enough and we can use new bdrv_drop_filter().
5
5
6
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
6
This commit efficiently reverts also recent 705dde27c6c53b73, which
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
checked .active on io path. Still it said that the problem should be
8
Reviewed-by: John Snow <jsnow@redhat.com>
8
theoretical. And the logic of filter removement is changed anyway.
9
10
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
11
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
12
Message-Id: <20210428151804.439460-25-vsementsov@virtuozzo.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
14
---
11
block/vhdx.h | 6 +-----
15
block/backup-top.c | 47 +-------------------------------------
12
block/vhdx.c | 3 ++-
16
tests/qemu-iotests/283.out | 2 +-
13
2 files changed, 3 insertions(+), 6 deletions(-)
17
2 files changed, 2 insertions(+), 47 deletions(-)
14
18
15
diff --git a/block/vhdx.h b/block/vhdx.h
19
diff --git a/block/backup-top.c b/block/backup-top.c
16
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
17
--- a/block/vhdx.h
21
--- a/block/backup-top.c
18
+++ b/block/vhdx.h
22
+++ b/block/backup-top.c
19
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@
20
24
typedef struct BDRVBackupTopState {
21
#ifndef BLOCK_VHDX_H
25
BlockCopyState *bcs;
22
#define BLOCK_VHDX_H
26
BdrvChild *target;
27
- bool active;
28
int64_t cluster_size;
29
} BDRVBackupTopState;
30
31
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int backup_top_co_preadv(
32
BlockDriverState *bs, uint64_t offset, uint64_t bytes,
33
QEMUIOVector *qiov, int flags)
34
{
35
- BDRVBackupTopState *s = bs->opaque;
23
-
36
-
24
-#define KiB (1 * 1024)
37
- if (!s->active) {
25
-#define MiB (KiB * 1024)
38
- return -EIO;
26
-#define GiB (MiB * 1024)
39
- }
27
-#define TiB ((uint64_t) GiB * 1024)
40
-
28
+#include "qemu/units.h"
41
return bdrv_co_preadv(bs->backing, offset, bytes, qiov, flags);
29
42
}
30
#define DEFAULT_LOG_SIZE 1048576 /* 1MiB */
43
31
/* Structures and fields present in the VHDX file */
44
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int backup_top_cbw(BlockDriverState *bs, uint64_t offset,
32
diff --git a/block/vhdx.c b/block/vhdx.c
45
BDRVBackupTopState *s = bs->opaque;
46
uint64_t off, end;
47
48
- if (!s->active) {
49
- return -EIO;
50
- }
51
-
52
if (flags & BDRV_REQ_WRITE_UNCHANGED) {
53
return 0;
54
}
55
@@ -XXX,XX +XXX,XX @@ static void backup_top_child_perm(BlockDriverState *bs, BdrvChild *c,
56
uint64_t perm, uint64_t shared,
57
uint64_t *nperm, uint64_t *nshared)
58
{
59
- BDRVBackupTopState *s = bs->opaque;
60
-
61
- if (!s->active) {
62
- /*
63
- * The filter node may be in process of bdrv_append(), which firstly do
64
- * bdrv_set_backing_hd() and then bdrv_replace_node(). This means that
65
- * we can't unshare BLK_PERM_WRITE during bdrv_append() operation. So,
66
- * let's require nothing during bdrv_append() and refresh permissions
67
- * after it (see bdrv_backup_top_append()).
68
- */
69
- *nperm = 0;
70
- *nshared = BLK_PERM_ALL;
71
- return;
72
- }
73
-
74
if (!(role & BDRV_CHILD_FILTERED)) {
75
/*
76
* Target child
77
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_backup_top_append(BlockDriverState *source,
78
}
79
appended = true;
80
81
- /*
82
- * bdrv_append() finished successfully, now we can require permissions
83
- * we want.
84
- */
85
- state->active = true;
86
- ret = bdrv_child_refresh_perms(top, top->backing, errp);
87
- if (ret < 0) {
88
- error_prepend(errp, "Cannot set permissions for backup-top filter: ");
89
- goto fail;
90
- }
91
-
92
state->cluster_size = cluster_size;
93
state->bcs = block_copy_state_new(top->backing, state->target,
94
cluster_size, perf->use_copy_range,
95
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_backup_top_append(BlockDriverState *source,
96
97
fail:
98
if (appended) {
99
- state->active = false;
100
bdrv_backup_top_drop(top);
101
} else {
102
bdrv_unref(top);
103
@@ -XXX,XX +XXX,XX @@ void bdrv_backup_top_drop(BlockDriverState *bs)
104
{
105
BDRVBackupTopState *s = bs->opaque;
106
107
- bdrv_drained_begin(bs);
108
+ bdrv_drop_filter(bs, &error_abort);
109
110
block_copy_state_free(s->bcs);
111
112
- s->active = false;
113
- bdrv_child_refresh_perms(bs, bs->backing, &error_abort);
114
- bdrv_replace_node(bs, bs->backing->bs, &error_abort);
115
- bdrv_set_backing_hd(bs, NULL, &error_abort);
116
-
117
- bdrv_drained_end(bs);
118
-
119
bdrv_unref(bs);
120
}
121
diff --git a/tests/qemu-iotests/283.out b/tests/qemu-iotests/283.out
33
index XXXXXXX..XXXXXXX 100644
122
index XXXXXXX..XXXXXXX 100644
34
--- a/block/vhdx.c
123
--- a/tests/qemu-iotests/283.out
35
+++ b/block/vhdx.c
124
+++ b/tests/qemu-iotests/283.out
36
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vhdx_co_create(BlockdevCreateOptions *opts,
125
@@ -XXX,XX +XXX,XX @@
37
return -EINVAL;
126
{"execute": "blockdev-add", "arguments": {"driver": "blkdebug", "image": "base", "node-name": "other", "take-child-perms": ["write"]}}
38
}
127
{"return": {}}
39
if (block_size > VHDX_BLOCK_SIZE_MAX) {
128
{"execute": "blockdev-backup", "arguments": {"device": "source", "sync": "full", "target": "target"}}
40
- error_setg(errp, "Block size must not exceed %d", VHDX_BLOCK_SIZE_MAX);
129
-{"error": {"class": "GenericError", "desc": "Cannot set permissions for backup-top filter: Conflicts with use by source as 'image', which does not allow 'write' on base"}}
41
+ error_setg(errp, "Block size must not exceed %" PRId64,
130
+{"error": {"class": "GenericError", "desc": "Cannot append backup-top filter: Conflicts with use by source as 'image', which does not allow 'write' on base"}}
42
+ VHDX_BLOCK_SIZE_MAX);
131
43
return -EINVAL;
132
=== backup-top should be gone after job-finalize ===
44
}
45
133
46
--
134
--
47
2.20.1
135
2.30.2
48
136
49
137
diff view generated by jsdifflib
1
We'll add a bdrv_co_truncate() call in the next patch which can return
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
an Error that we don't want to discard. So add an errp parameter to
3
preallocate_co().
4
2
5
Cc: qemu-stable@nongnu.org
3
This argument is always NULL. Drop it.
4
5
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
7
Message-Id: <20210428151804.439460-26-vsementsov@virtuozzo.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
---
9
---
9
block/qcow2.c | 11 ++++++-----
10
block.c | 38 +++++++++++---------------------------
10
1 file changed, 6 insertions(+), 5 deletions(-)
11
1 file changed, 11 insertions(+), 27 deletions(-)
11
12
12
diff --git a/block/qcow2.c b/block/qcow2.c
13
diff --git a/block.c b/block.c
13
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
14
--- a/block/qcow2.c
15
--- a/block.c
15
+++ b/block/qcow2.c
16
+++ b/block.c
16
@@ -XXX,XX +XXX,XX @@ static int qcow2_set_up_encryption(BlockDriverState *bs,
17
@@ -XXX,XX +XXX,XX @@ static int bdrv_fill_options(QDict **options, const char *filename,
17
* Returns: 0 on success, -errno on failure.
18
static int bdrv_check_update_perm(BlockDriverState *bs, BlockReopenQueue *q,
18
*/
19
uint64_t new_used_perm,
19
static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
20
uint64_t new_shared_perm,
20
- uint64_t new_length)
21
- GSList *ignore_children,
21
+ uint64_t new_length, Error **errp)
22
Error **errp);
23
24
typedef struct BlockReopenQueueEntry {
25
@@ -XXX,XX +XXX,XX @@ static bool bdrv_a_allow_b(BdrvChild *a, BdrvChild *b, Error **errp)
26
return false;
27
}
28
29
-static bool bdrv_parent_perms_conflict(BlockDriverState *bs,
30
- GSList *ignore_children,
31
- Error **errp)
32
+static bool bdrv_parent_perms_conflict(BlockDriverState *bs, Error **errp)
22
{
33
{
23
BDRVQcow2State *s = bs->opaque;
34
BdrvChild *a, *b;
24
uint64_t bytes;
35
25
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
36
@@ -XXX,XX +XXX,XX @@ static bool bdrv_parent_perms_conflict(BlockDriverState *bs,
26
ret = qcow2_alloc_cluster_offset(bs, offset, &cur_bytes,
37
* directions.
27
&host_offset, &meta);
38
*/
39
QLIST_FOREACH(a, &bs->parents, next_parent) {
40
- if (g_slist_find(ignore_children, a)) {
41
- continue;
42
- }
43
-
44
QLIST_FOREACH(b, &bs->parents, next_parent) {
45
- if (a == b || g_slist_find(ignore_children, b)) {
46
+ if (a == b) {
47
continue;
48
}
49
50
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_safe(BdrvChild *child, BlockDriverState *new_bs,
51
static int bdrv_node_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
52
uint64_t cumulative_perms,
53
uint64_t cumulative_shared_perms,
54
- GSList *ignore_children,
55
Transaction *tran, Error **errp)
56
{
57
BlockDriver *drv = bs->drv;
58
@@ -XXX,XX +XXX,XX @@ static int bdrv_check_perm_common(GSList *list, BlockReopenQueue *q,
59
bool use_cumulative_perms,
60
uint64_t cumulative_perms,
61
uint64_t cumulative_shared_perms,
62
- GSList *ignore_children,
63
Transaction *tran, Error **errp)
64
{
65
int ret;
66
@@ -XXX,XX +XXX,XX @@ static int bdrv_check_perm_common(GSList *list, BlockReopenQueue *q,
67
68
ret = bdrv_node_check_perm(bs, q, cumulative_perms,
69
cumulative_shared_perms,
70
- ignore_children, tran, errp);
71
+ tran, errp);
28
if (ret < 0) {
72
if (ret < 0) {
29
+ error_setg_errno(errp, -ret, "Allocating clusters failed");
30
return ret;
73
return ret;
31
}
74
}
32
75
@@ -XXX,XX +XXX,XX @@ static int bdrv_check_perm_common(GSList *list, BlockReopenQueue *q,
33
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
76
for ( ; list; list = list->next) {
34
77
bs = list->data;
35
ret = qcow2_alloc_cluster_link_l2(bs, meta);
78
36
if (ret < 0) {
79
- if (bdrv_parent_perms_conflict(bs, ignore_children, errp)) {
37
+ error_setg_errno(errp, -ret, "Mapping clusters failed");
80
+ if (bdrv_parent_perms_conflict(bs, errp)) {
38
qcow2_free_any_clusters(bs, meta->alloc_offset,
81
return -EINVAL;
39
meta->nb_clusters, QCOW2_DISCARD_NEVER);
82
}
40
return ret;
83
41
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
84
@@ -XXX,XX +XXX,XX @@ static int bdrv_check_perm_common(GSList *list, BlockReopenQueue *q,
42
ret = bdrv_pwrite(s->data_file, (host_offset + cur_bytes) - 1,
85
43
&data, 1);
86
ret = bdrv_node_check_perm(bs, q, cumulative_perms,
87
cumulative_shared_perms,
88
- ignore_children, tran, errp);
89
+ tran, errp);
44
if (ret < 0) {
90
if (ret < 0) {
45
+ error_setg_errno(errp, -ret, "Writing to EOF failed");
46
return ret;
91
return ret;
47
}
92
}
93
@@ -XXX,XX +XXX,XX @@ static int bdrv_check_perm_common(GSList *list, BlockReopenQueue *q,
94
95
static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
96
uint64_t cumulative_perms,
97
- uint64_t cumulative_shared_perms,
98
- GSList *ignore_children, Error **errp)
99
+ uint64_t cumulative_shared_perms, Error **errp)
100
{
101
g_autoptr(GSList) list = bdrv_topological_dfs(NULL, NULL, bs);
102
return bdrv_check_perm_common(list, q, true, cumulative_perms,
103
- cumulative_shared_perms, ignore_children,
104
- NULL, errp);
105
+ cumulative_shared_perms, NULL, errp);
106
}
107
108
static int bdrv_list_refresh_perms(GSList *list, BlockReopenQueue *q,
109
Transaction *tran, Error **errp)
110
{
111
- return bdrv_check_perm_common(list, q, false, 0, 0, NULL, tran, errp);
112
+ return bdrv_check_perm_common(list, q, false, 0, 0, tran, errp);
113
}
114
115
/*
116
@@ -XXX,XX +XXX,XX @@ char *bdrv_perm_names(uint64_t perm)
117
static int bdrv_check_update_perm(BlockDriverState *bs, BlockReopenQueue *q,
118
uint64_t new_used_perm,
119
uint64_t new_shared_perm,
120
- GSList *ignore_children,
121
Error **errp)
122
{
123
BdrvChild *c;
124
@@ -XXX,XX +XXX,XX @@ static int bdrv_check_update_perm(BlockDriverState *bs, BlockReopenQueue *q,
125
assert(new_shared_perm & BLK_PERM_WRITE_UNCHANGED);
126
127
QLIST_FOREACH(c, &bs->parents, next_parent) {
128
- if (g_slist_find(ignore_children, c)) {
129
- continue;
130
- }
131
-
132
if ((new_used_perm & c->shared_perm) != new_used_perm) {
133
char *user = bdrv_child_user_desc(c);
134
char *perm_names = bdrv_perm_names(new_used_perm & ~c->shared_perm);
135
@@ -XXX,XX +XXX,XX @@ static int bdrv_check_update_perm(BlockDriverState *bs, BlockReopenQueue *q,
48
}
136
}
49
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
137
50
break;
138
return bdrv_check_perm(bs, q, cumulative_perms, cumulative_shared_perms,
51
139
- ignore_children, errp);
52
case PREALLOC_MODE_METADATA:
140
+ errp);
53
- ret = preallocate_co(bs, old_length, offset);
141
}
54
+ ret = preallocate_co(bs, old_length, offset, errp);
142
143
static int bdrv_refresh_perms(BlockDriverState *bs, Error **errp)
144
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp)
145
QTAILQ_FOREACH(bs_entry, bs_queue, entry) {
146
BDRVReopenState *state = &bs_entry->state;
147
ret = bdrv_check_perm(state->bs, bs_queue, state->perm,
148
- state->shared_perm, NULL, errp);
149
+ state->shared_perm, errp);
55
if (ret < 0) {
150
if (ret < 0) {
56
- error_setg_errno(errp, -ret, "Preallocation failed");
151
goto cleanup_perm;
57
goto fail;
58
}
152
}
59
break;
153
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp)
60
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
154
bs_queue, state->perm, state->shared_perm,
61
/* With a data file, preallocation means just allocating the metadata
155
&nperm, &nshared);
62
* and forwarding the truncate request to the data file */
156
ret = bdrv_check_update_perm(state->new_backing_bs, NULL,
63
if (has_data_file(bs)) {
157
- nperm, nshared, NULL, errp);
64
- ret = preallocate_co(bs, old_length, offset);
158
+ nperm, nshared, errp);
65
+ ret = preallocate_co(bs, old_length, offset, errp);
66
if (ret < 0) {
159
if (ret < 0) {
67
- error_setg_errno(errp, -ret, "Preallocation failed");
160
goto cleanup_perm;
68
goto fail;
69
}
161
}
70
break;
71
--
162
--
72
2.20.1
163
2.30.2
73
164
74
165
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
To be used in the further commit.
4
3
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
5
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
4
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
6
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
7
Message-Id: <20210428151804.439460-27-vsementsov@virtuozzo.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
9
---
8
block/qcow.c | 19 ++++++-------------
10
block.c | 46 ++++++++++++++++++++++++++++++++++++++++++----
9
1 file changed, 6 insertions(+), 13 deletions(-)
11
1 file changed, 42 insertions(+), 4 deletions(-)
10
12
11
diff --git a/block/qcow.c b/block/qcow.c
13
diff --git a/block.c b/block.c
12
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
13
--- a/block/qcow.c
15
--- a/block.c
14
+++ b/block/qcow.c
16
+++ b/block.c
15
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, uint64_t offset,
17
@@ -XXX,XX +XXX,XX @@ void bdrv_root_unref_child(BdrvChild *child)
16
int offset_in_cluster;
18
bdrv_unref(child_bs);
17
int ret = 0, n;
19
}
18
uint64_t cluster_offset;
20
19
- QEMUIOVector hd_qiov;
21
+typedef struct BdrvSetInheritsFrom {
20
uint8_t *buf;
22
+ BlockDriverState *bs;
21
void *orig_buf;
23
+ BlockDriverState *old_inherits_from;
22
24
+} BdrvSetInheritsFrom;
23
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, uint64_t offset,
25
+
24
if (!cluster_offset) {
26
+static void bdrv_set_inherits_from_abort(void *opaque)
25
if (bs->backing) {
27
+{
26
/* read from the base image */
28
+ BdrvSetInheritsFrom *s = opaque;
27
- qemu_iovec_init_buf(&hd_qiov, buf, n);
29
+
28
qemu_co_mutex_unlock(&s->lock);
30
+ s->bs->inherits_from = s->old_inherits_from;
29
/* qcow2 emits this on bs->file instead of bs->backing */
31
+}
30
BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
32
+
31
- ret = bdrv_co_preadv(bs->backing, offset, n, &hd_qiov, 0);
33
+static TransactionActionDrv bdrv_set_inherits_from_drv = {
32
+ ret = bdrv_co_pread(bs->backing, offset, n, buf, 0);
34
+ .abort = bdrv_set_inherits_from_abort,
33
qemu_co_mutex_lock(&s->lock);
35
+ .clean = g_free,
34
if (ret < 0) {
36
+};
35
break;
37
+
36
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, uint64_t offset,
38
+/* @tran is allowed to be NULL. In this case no rollback is possible */
37
ret = -EIO;
39
+static void bdrv_set_inherits_from(BlockDriverState *bs,
38
break;
40
+ BlockDriverState *new_inherits_from,
39
}
41
+ Transaction *tran)
40
- qemu_iovec_init_buf(&hd_qiov, buf, n);
42
+{
41
qemu_co_mutex_unlock(&s->lock);
43
+ if (tran) {
42
BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
44
+ BdrvSetInheritsFrom *s = g_new(BdrvSetInheritsFrom, 1);
43
- ret = bdrv_co_preadv(bs->file, cluster_offset + offset_in_cluster,
45
+
44
- n, &hd_qiov, 0);
46
+ *s = (BdrvSetInheritsFrom) {
45
+ ret = bdrv_co_pread(bs->file, cluster_offset + offset_in_cluster,
47
+ .bs = bs,
46
+ n, buf, 0);
48
+ .old_inherits_from = bs->inherits_from,
47
qemu_co_mutex_lock(&s->lock);
49
+ };
48
if (ret < 0) {
50
+
49
break;
51
+ tran_add(tran, &bdrv_set_inherits_from_drv, s);
50
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_pwritev(BlockDriverState *bs, uint64_t offset,
52
+ }
51
int offset_in_cluster;
53
+
52
uint64_t cluster_offset;
54
+ bs->inherits_from = new_inherits_from;
53
int ret = 0, n;
55
+}
54
- QEMUIOVector hd_qiov;
56
+
55
uint8_t *buf;
57
/**
56
void *orig_buf;
58
* Clear all inherits_from pointers from children and grandchildren of
57
59
* @root that point to @root, where necessary.
58
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_pwritev(BlockDriverState *bs, uint64_t offset,
60
+ * @tran is allowed to be NULL. In this case no rollback is possible
61
*/
62
-static void bdrv_unset_inherits_from(BlockDriverState *root, BdrvChild *child)
63
+static void bdrv_unset_inherits_from(BlockDriverState *root, BdrvChild *child,
64
+ Transaction *tran)
65
{
66
BdrvChild *c;
67
68
@@ -XXX,XX +XXX,XX @@ static void bdrv_unset_inherits_from(BlockDriverState *root, BdrvChild *child)
59
}
69
}
60
}
70
}
61
71
if (c == NULL) {
62
- qemu_iovec_init_buf(&hd_qiov, buf, n);
72
- child->bs->inherits_from = NULL;
63
qemu_co_mutex_unlock(&s->lock);
73
+ bdrv_set_inherits_from(child->bs, NULL, tran);
64
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
74
}
65
- ret = bdrv_co_pwritev(bs->file, cluster_offset + offset_in_cluster,
66
- n, &hd_qiov, 0);
67
+ ret = bdrv_co_pwrite(bs->file, cluster_offset + offset_in_cluster,
68
+ n, buf, 0);
69
qemu_co_mutex_lock(&s->lock);
70
if (ret < 0) {
71
break;
72
@@ -XXX,XX +XXX,XX @@ qcow_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
73
uint64_t bytes, QEMUIOVector *qiov)
74
{
75
BDRVQcowState *s = bs->opaque;
76
- QEMUIOVector hd_qiov;
77
z_stream strm;
78
int ret, out_len;
79
uint8_t *buf, *out_buf;
80
@@ -XXX,XX +XXX,XX @@ qcow_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
81
}
75
}
82
cluster_offset &= s->cluster_offset_mask;
76
83
77
QLIST_FOREACH(c, &child->bs->children, next) {
84
- qemu_iovec_init_buf(&hd_qiov, out_buf, out_len);
78
- bdrv_unset_inherits_from(root, c);
85
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_COMPRESSED);
79
+ bdrv_unset_inherits_from(root, c, tran);
86
- ret = bdrv_co_pwritev(bs->file, cluster_offset, out_len, &hd_qiov, 0);
87
+ ret = bdrv_co_pwrite(bs->file, cluster_offset, out_len, out_buf, 0);
88
if (ret < 0) {
89
goto fail;
90
}
80
}
81
}
82
83
@@ -XXX,XX +XXX,XX @@ void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child)
84
return;
85
}
86
87
- bdrv_unset_inherits_from(parent, child);
88
+ bdrv_unset_inherits_from(parent, child, NULL);
89
bdrv_root_unref_child(child);
90
}
91
91
--
92
--
92
2.20.1
93
2.30.2
93
94
94
95
diff view generated by jsdifflib
1
From: Sam Eiderman <shmuel.eiderman@oracle.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
Commit b69864e5a ("vmdk: Support version=3 in VMDK descriptor files")
3
To be used in further commit.
4
fixed the probe function to correctly guess vmdk descriptors with
5
version=3.
6
4
7
This solves the issue where vmdk snapshot with parent vmdk descriptor
5
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
containing "version=3" would be treated as raw instead vmdk.
6
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
7
Message-Id: <20210428151804.439460-28-vsementsov@virtuozzo.com>
10
In the future case where a new vmdk version is introduced, we will again
11
experience this issue, even if the user will provide "-f vmdk" it will
12
only apply to the tip image and not to the underlying "misprobed" parent
13
image.
14
15
The code in vmdk.c already assumes that the backing file of vmdk must be
16
vmdk (see vmdk_is_cid_valid which returns 0 if backing file is not
17
vmdk).
18
19
So let's make it official by supplying the backing_format as vmdk.
20
21
Reviewed-by: Mark Kanda <mark.kanda@oracle.com>
22
Reviewed-By: Liran Alon <liran.alon@oracle.com>
23
Reviewed-by: Arbel Moshe <arbel.moshe@oracle.com>
24
Signed-off-by: Shmuel Eiderman <shmuel.eiderman@oracle.com>
25
Reviewed-by: Eric Blake <eblake@redhat.com>
26
Reviewed-by: Fam Zheng <fam@euphon.net>
27
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
28
---
9
---
29
block/vmdk.c | 2 ++
10
include/block/block.h | 3 ++-
30
1 file changed, 2 insertions(+)
11
block.c | 9 ++++-----
12
block/io.c | 31 +++++++++++++++++++++++++++++--
13
3 files changed, 35 insertions(+), 8 deletions(-)
31
14
32
diff --git a/block/vmdk.c b/block/vmdk.c
15
diff --git a/include/block/block.h b/include/block/block.h
33
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
34
--- a/block/vmdk.c
17
--- a/include/block/block.h
35
+++ b/block/vmdk.c
18
+++ b/include/block/block.h
36
@@ -XXX,XX +XXX,XX @@ static int vmdk_parent_open(BlockDriverState *bs)
19
@@ -XXX,XX +XXX,XX @@
37
pstrcpy(bs->auto_backing_file, end_name - p_name + 1, p_name);
20
#include "block/dirty-bitmap.h"
38
pstrcpy(bs->backing_file, sizeof(bs->backing_file),
21
#include "block/blockjob.h"
39
bs->auto_backing_file);
22
#include "qemu/hbitmap.h"
40
+ pstrcpy(bs->backing_format, sizeof(bs->backing_format),
23
+#include "qemu/transactions.h"
41
+ "vmdk");
24
25
/*
26
* generated_co_wrapper
27
@@ -XXX,XX +XXX,XX @@ int64_t bdrv_get_allocated_file_size(BlockDriverState *bs);
28
BlockMeasureInfo *bdrv_measure(BlockDriver *drv, QemuOpts *opts,
29
BlockDriverState *in_bs, Error **errp);
30
void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
31
-void bdrv_refresh_limits(BlockDriverState *bs, Error **errp);
32
+void bdrv_refresh_limits(BlockDriverState *bs, Transaction *tran, Error **errp);
33
int bdrv_commit(BlockDriverState *bs);
34
int bdrv_make_empty(BdrvChild *c, Error **errp);
35
int bdrv_change_backing_file(BlockDriverState *bs, const char *backing_file,
36
diff --git a/block.c b/block.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/block.c
39
+++ b/block.c
40
@@ -XXX,XX +XXX,XX @@
41
#include "qemu/timer.h"
42
#include "qemu/cutils.h"
43
#include "qemu/id.h"
44
-#include "qemu/transactions.h"
45
#include "block/coroutines.h"
46
47
#ifdef CONFIG_BSD
48
@@ -XXX,XX +XXX,XX @@ static int bdrv_open_driver(BlockDriverState *bs, BlockDriver *drv,
49
return ret;
42
}
50
}
43
51
52
- bdrv_refresh_limits(bs, &local_err);
53
+ bdrv_refresh_limits(bs, NULL, &local_err);
54
if (local_err) {
55
error_propagate(errp, local_err);
56
return -EINVAL;
57
@@ -XXX,XX +XXX,XX @@ int bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
58
}
59
44
out:
60
out:
61
- bdrv_refresh_limits(bs, NULL);
62
+ bdrv_refresh_limits(bs, NULL, NULL);
63
64
return ret;
65
}
66
@@ -XXX,XX +XXX,XX @@ static void bdrv_reopen_commit(BDRVReopenState *reopen_state)
67
bdrv_set_backing_hd(bs, reopen_state->new_backing_bs, &error_abort);
68
}
69
70
- bdrv_refresh_limits(bs, NULL);
71
+ bdrv_refresh_limits(bs, NULL, NULL);
72
}
73
74
/*
75
@@ -XXX,XX +XXX,XX @@ int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
76
out:
77
tran_finalize(tran, ret);
78
79
- bdrv_refresh_limits(bs_top, NULL);
80
+ bdrv_refresh_limits(bs_top, NULL, NULL);
81
82
return ret;
83
}
84
diff --git a/block/io.c b/block/io.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/block/io.c
87
+++ b/block/io.c
88
@@ -XXX,XX +XXX,XX @@ static void bdrv_merge_limits(BlockLimits *dst, const BlockLimits *src)
89
dst->max_iov = MIN_NON_ZERO(dst->max_iov, src->max_iov);
90
}
91
92
-void bdrv_refresh_limits(BlockDriverState *bs, Error **errp)
93
+typedef struct BdrvRefreshLimitsState {
94
+ BlockDriverState *bs;
95
+ BlockLimits old_bl;
96
+} BdrvRefreshLimitsState;
97
+
98
+static void bdrv_refresh_limits_abort(void *opaque)
99
+{
100
+ BdrvRefreshLimitsState *s = opaque;
101
+
102
+ s->bs->bl = s->old_bl;
103
+}
104
+
105
+static TransactionActionDrv bdrv_refresh_limits_drv = {
106
+ .abort = bdrv_refresh_limits_abort,
107
+ .clean = g_free,
108
+};
109
+
110
+/* @tran is allowed to be NULL, in this case no rollback is possible. */
111
+void bdrv_refresh_limits(BlockDriverState *bs, Transaction *tran, Error **errp)
112
{
113
ERRP_GUARD();
114
BlockDriver *drv = bs->drv;
115
BdrvChild *c;
116
bool have_limits;
117
118
+ if (tran) {
119
+ BdrvRefreshLimitsState *s = g_new(BdrvRefreshLimitsState, 1);
120
+ *s = (BdrvRefreshLimitsState) {
121
+ .bs = bs,
122
+ .old_bl = bs->bl,
123
+ };
124
+ tran_add(tran, &bdrv_refresh_limits_drv, s);
125
+ }
126
+
127
memset(&bs->bl, 0, sizeof(bs->bl));
128
129
if (!drv) {
130
@@ -XXX,XX +XXX,XX @@ void bdrv_refresh_limits(BlockDriverState *bs, Error **errp)
131
QLIST_FOREACH(c, &bs->children, next) {
132
if (c->role & (BDRV_CHILD_DATA | BDRV_CHILD_FILTERED | BDRV_CHILD_COW))
133
{
134
- bdrv_refresh_limits(c->bs, errp);
135
+ bdrv_refresh_limits(c->bs, tran, errp);
136
if (*errp) {
137
return;
138
}
45
--
139
--
46
2.20.1
140
2.30.2
47
141
48
142
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
Split out no-perm part of bdrv_set_backing_hd() as a separate
4
transaction action. Note the in case of existing BdrvChild we reuse it,
5
not recreate, just to do less actions.
6
7
We don't need to create extra reference to backing_hd as we don't lose
8
it in bdrv_attach_child().
9
3
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
4
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
11
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
12
Message-Id: <20210428151804.439460-29-vsementsov@virtuozzo.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
14
---
8
block/commit.c | 5 ++---
15
block.c | 54 +++++++++++++++++++++++++++++++++++++-----------------
9
1 file changed, 2 insertions(+), 3 deletions(-)
16
1 file changed, 37 insertions(+), 17 deletions(-)
10
17
11
diff --git a/block/commit.c b/block/commit.c
18
diff --git a/block.c b/block.c
12
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
13
--- a/block/commit.c
20
--- a/block.c
14
+++ b/block/commit.c
21
+++ b/block.c
15
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn commit_populate(BlockBackend *bs, BlockBackend *base,
22
@@ -XXX,XX +XXX,XX @@ static int bdrv_attach_child_noperm(BlockDriverState *parent_bs,
16
void *buf)
23
BdrvChild **child,
24
Transaction *tran,
25
Error **errp);
26
+static void bdrv_remove_filter_or_cow_child(BlockDriverState *bs,
27
+ Transaction *tran);
28
29
static int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue
30
*queue, Error **errp);
31
@@ -XXX,XX +XXX,XX @@ static BdrvChildRole bdrv_backing_role(BlockDriverState *bs)
32
* Sets the bs->backing link of a BDS. A new reference is created; callers
33
* which don't need their own reference any more must call bdrv_unref().
34
*/
35
-int bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
36
- Error **errp)
37
+static int bdrv_set_backing_noperm(BlockDriverState *bs,
38
+ BlockDriverState *backing_hd,
39
+ Transaction *tran, Error **errp)
17
{
40
{
18
int ret = 0;
41
int ret = 0;
19
- QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
42
bool update_inherits_from = bdrv_chain_contains(bs, backing_hd) &&
20
43
@@ -XXX,XX +XXX,XX @@ int bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
21
assert(bytes < SIZE_MAX);
44
return -EPERM;
22
23
- ret = blk_co_preadv(bs, offset, qiov.size, &qiov, 0);
24
+ ret = blk_co_pread(bs, offset, bytes, buf, 0);
25
if (ret < 0) {
26
return ret;
27
}
45
}
28
46
29
- ret = blk_co_pwritev(base, offset, qiov.size, &qiov, 0);
47
- if (backing_hd) {
30
+ ret = blk_co_pwrite(base, offset, bytes, buf, 0);
48
- bdrv_ref(backing_hd);
31
if (ret < 0) {
49
- }
32
return ret;
50
-
51
if (bs->backing) {
52
/* Cannot be frozen, we checked that above */
53
- bdrv_unref_child(bs, bs->backing);
54
- bs->backing = NULL;
55
+ bdrv_unset_inherits_from(bs, bs->backing, tran);
56
+ bdrv_remove_filter_or_cow_child(bs, tran);
33
}
57
}
58
59
if (!backing_hd) {
60
goto out;
61
}
62
63
- bs->backing = bdrv_attach_child(bs, backing_hd, "backing", &child_of_bds,
64
- bdrv_backing_role(bs), errp);
65
- if (!bs->backing) {
66
- ret = -EPERM;
67
- goto out;
68
+ ret = bdrv_attach_child_noperm(bs, backing_hd, "backing",
69
+ &child_of_bds, bdrv_backing_role(bs),
70
+ &bs->backing, tran, errp);
71
+ if (ret < 0) {
72
+ return ret;
73
}
74
75
- /* If backing_hd was already part of bs's backing chain, and
76
+
77
+ /*
78
+ * If backing_hd was already part of bs's backing chain, and
79
* inherits_from pointed recursively to bs then let's update it to
80
- * point directly to bs (else it will become NULL). */
81
+ * point directly to bs (else it will become NULL).
82
+ */
83
if (update_inherits_from) {
84
- backing_hd->inherits_from = bs;
85
+ bdrv_set_inherits_from(backing_hd, bs, tran);
86
}
87
88
out:
89
- bdrv_refresh_limits(bs, NULL, NULL);
90
+ bdrv_refresh_limits(bs, tran, NULL);
91
+
92
+ return 0;
93
+}
94
+
95
+int bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
96
+ Error **errp)
97
+{
98
+ int ret;
99
+ Transaction *tran = tran_new();
100
+
101
+ ret = bdrv_set_backing_noperm(bs, backing_hd, tran, errp);
102
+ if (ret < 0) {
103
+ goto out;
104
+ }
105
+
106
+ ret = bdrv_refresh_perms(bs, errp);
107
+out:
108
+ tran_finalize(tran, ret);
109
110
return ret;
111
}
34
--
112
--
35
2.20.1
113
2.30.2
36
114
37
115
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
When extracting a human-readable size formatter, we changed 'uint64_t
3
During reopen we may add backing bs from other aio context, which may
4
div' pre-patch to 'unsigned long div' post-patch. Which breaks on
4
lead to changing original context of top bs.
5
32-bit platforms, resulting in 'inf' instead of intended values larger
6
than 999GB.
7
5
8
Fixes: 22951aaa
6
We are going to move graph modification to prepare stage. So, it will
9
CC: qemu-stable@nongnu.org
7
be possible that bdrv_flush() in bdrv_reopen_prepare called on bs in
10
Reported-by: Max Reitz <mreitz@redhat.com>
8
non-original aio context, which we didn't aquire which leads to crash.
11
Signed-off-by: Eric Blake <eblake@redhat.com>
9
12
Reviewed-by: Max Reitz <mreitz@redhat.com>
10
To avoid this problem move bdrv_flush() to be a separate reopen stage
11
before bdrv_reopen_prepare().
12
13
This doesn't seem correct to acquire only one aio context and not all
14
contexts participating in reopen. But it's not obvious how to do it
15
correctly, keeping in mind:
16
17
1. rules of bdrv_set_aio_context_ignore() that requires new_context
18
lock not being held
19
20
2. possible deadlocks because of holding all (or several?) AioContext
21
locks
22
23
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
24
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
25
Message-Id: <20210428151804.439460-30-vsementsov@virtuozzo.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
26
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
27
---
15
util/cutils.c | 2 +-
28
block.c | 14 ++++++++------
16
1 file changed, 1 insertion(+), 1 deletion(-)
29
1 file changed, 8 insertions(+), 6 deletions(-)
17
30
18
diff --git a/util/cutils.c b/util/cutils.c
31
diff --git a/block.c b/block.c
19
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
20
--- a/util/cutils.c
33
--- a/block.c
21
+++ b/util/cutils.c
34
+++ b/block.c
22
@@ -XXX,XX +XXX,XX @@ const char *qemu_ether_ntoa(const MACAddr *mac)
35
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp)
23
char *size_to_str(uint64_t val)
36
24
{
37
assert(bs_queue != NULL);
25
static const char *suffixes[] = { "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei" };
38
26
- unsigned long div;
39
+ QTAILQ_FOREACH(bs_entry, bs_queue, entry) {
27
+ uint64_t div;
40
+ ret = bdrv_flush(bs_entry->state.bs);
28
int i;
41
+ if (ret < 0) {
29
42
+ error_setg_errno(errp, -ret, "Error flushing drive");
30
/*
43
+ goto cleanup;
44
+ }
45
+ }
46
+
47
QTAILQ_FOREACH(bs_entry, bs_queue, entry) {
48
assert(bs_entry->state.bs->quiesce_counter > 0);
49
if (bdrv_reopen_prepare(&bs_entry->state, bs_queue, errp)) {
50
@@ -XXX,XX +XXX,XX @@ static int bdrv_reopen_prepare(BDRVReopenState *reopen_state,
51
bdrv_reopen_perm(queue, reopen_state->bs,
52
&reopen_state->perm, &reopen_state->shared_perm);
53
54
- ret = bdrv_flush(reopen_state->bs);
55
- if (ret) {
56
- error_setg_errno(errp, -ret, "Error flushing drive");
57
- goto error;
58
- }
59
-
60
if (drv->bdrv_reopen_prepare) {
61
/*
62
* If a driver-specific option is missing, it means that we
31
--
63
--
32
2.20.1
64
2.30.2
33
65
34
66
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
qed_read_table and qed_write_table use coroutine-only interfaces but
3
Move bdrv_reopen_multiple to new paradigm of permission update:
4
are not marked coroutine_fn. Happily, they are called only from
4
first update graph relations, then do refresh the permissions.
5
coroutine context, so we only need to add missed markers.
6
5
7
Reported-by: Kevin Wolf <kwolf@redhat.com>
6
We have to modify reopen process in file-posix driver: with new scheme
7
we don't have prepared permissions in raw_reopen_prepare(), so we
8
should reconfigure fd in raw_check_perm(). Still this seems more native
9
and simple anyway.
10
8
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
11
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
12
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
13
Message-Id: <20210428151804.439460-31-vsementsov@virtuozzo.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
15
---
11
block/qed.h | 28 ++++++++++++++++------------
16
include/block/block.h | 3 +-
12
block/qed-check.c | 4 ++--
17
block.c | 187 ++++++++++++------------------------------
13
block/qed-table.c | 33 ++++++++++++++++++++-------------
18
block/file-posix.c | 91 +++++++-------------
14
block/qed.c | 5 +++--
19
3 files changed, 84 insertions(+), 197 deletions(-)
15
4 files changed, 41 insertions(+), 29 deletions(-)
16
20
17
diff --git a/block/qed.h b/block/qed.h
21
diff --git a/include/block/block.h b/include/block/block.h
18
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
19
--- a/block/qed.h
23
--- a/include/block/block.h
20
+++ b/block/qed.h
24
+++ b/include/block/block.h
21
@@ -XXX,XX +XXX,XX @@ void qed_commit_l2_cache_entry(L2TableCache *l2_cache, CachedL2Table *l2_table);
25
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVReopenState {
22
/**
26
BlockdevDetectZeroesOptions detect_zeroes;
23
* Table I/O functions
27
bool backing_missing;
24
*/
28
bool replace_backing_bs; /* new_backing_bs is ignored if this is false */
25
-int qed_read_l1_table_sync(BDRVQEDState *s);
29
- BlockDriverState *new_backing_bs; /* If NULL then detach the current bs */
26
-int qed_write_l1_table(BDRVQEDState *s, unsigned int index, unsigned int n);
30
- uint64_t perm, shared_perm;
27
-int qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index,
31
+ BlockDriverState *old_backing_bs; /* keep pointer for permissions update */
28
- unsigned int n);
32
QDict *options;
29
-int qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
33
QDict *explicit_options;
30
- uint64_t offset);
34
void *opaque;
31
-int qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset);
35
diff --git a/block.c b/block.c
32
-int qed_write_l2_table(BDRVQEDState *s, QEDRequest *request,
33
- unsigned int index, unsigned int n, bool flush);
34
-int qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
35
- unsigned int index, unsigned int n, bool flush);
36
+int coroutine_fn qed_read_l1_table_sync(BDRVQEDState *s);
37
+int coroutine_fn qed_write_l1_table(BDRVQEDState *s, unsigned int index,
38
+ unsigned int n);
39
+int coroutine_fn qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index,
40
+ unsigned int n);
41
+int coroutine_fn qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
42
+ uint64_t offset);
43
+int coroutine_fn qed_read_l2_table(BDRVQEDState *s, QEDRequest *request,
44
+ uint64_t offset);
45
+int coroutine_fn qed_write_l2_table(BDRVQEDState *s, QEDRequest *request,
46
+ unsigned int index, unsigned int n,
47
+ bool flush);
48
+int coroutine_fn qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
49
+ unsigned int index, unsigned int n,
50
+ bool flush);
51
52
/**
53
* Cluster functions
54
@@ -XXX,XX +XXX,XX @@ int coroutine_fn qed_find_cluster(BDRVQEDState *s, QEDRequest *request,
55
/**
56
* Consistency check
57
*/
58
-int qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix);
59
+int coroutine_fn qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix);
60
61
QEDTable *qed_alloc_table(BDRVQEDState *s);
62
63
diff --git a/block/qed-check.c b/block/qed-check.c
64
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
65
--- a/block/qed-check.c
37
--- a/block.c
66
+++ b/block/qed-check.c
38
+++ b/block.c
67
@@ -XXX,XX +XXX,XX @@ static unsigned int qed_check_l2_table(QEDCheck *check, QEDTable *table)
39
@@ -XXX,XX +XXX,XX @@ static int bdrv_attach_child_noperm(BlockDriverState *parent_bs,
68
/**
40
static void bdrv_remove_filter_or_cow_child(BlockDriverState *bs,
69
* Descend tables and check each cluster is referenced once only
41
Transaction *tran);
70
*/
42
71
-static int qed_check_l1_table(QEDCheck *check, QEDTable *table)
43
-static int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue
72
+static int coroutine_fn qed_check_l1_table(QEDCheck *check, QEDTable *table)
44
- *queue, Error **errp);
45
+static int bdrv_reopen_prepare(BDRVReopenState *reopen_state,
46
+ BlockReopenQueue *queue,
47
+ Transaction *set_backings_tran, Error **errp);
48
static void bdrv_reopen_commit(BDRVReopenState *reopen_state);
49
static void bdrv_reopen_abort(BDRVReopenState *reopen_state);
50
51
@@ -XXX,XX +XXX,XX @@ static void bdrv_list_abort_perm_update(GSList *list)
52
}
53
}
54
55
+__attribute__((unused))
56
static void bdrv_abort_perm_update(BlockDriverState *bs)
73
{
57
{
74
BDRVQEDState *s = check->s;
58
g_autoptr(GSList) list = bdrv_topological_dfs(NULL, NULL, bs);
75
unsigned int i, num_invalid_l1 = 0;
59
@@ -XXX,XX +XXX,XX @@ char *bdrv_perm_names(uint64_t perm)
76
@@ -XXX,XX +XXX,XX @@ static void qed_check_mark_clean(BDRVQEDState *s, BdrvCheckResult *result)
60
*
77
}
61
* Needs to be followed by a call to either bdrv_set_perm() or
78
62
* bdrv_abort_perm_update(). */
79
/* Called with table_lock held. */
63
+__attribute__((unused))
80
-int qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix)
64
static int bdrv_check_update_perm(BlockDriverState *bs, BlockReopenQueue *q,
81
+int coroutine_fn qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix)
65
uint64_t new_used_perm,
66
uint64_t new_shared_perm,
67
@@ -XXX,XX +XXX,XX @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
68
bs_entry->state.explicit_options = explicit_options;
69
bs_entry->state.flags = flags;
70
71
- /* This needs to be overwritten in bdrv_reopen_prepare() */
72
- bs_entry->state.perm = UINT64_MAX;
73
- bs_entry->state.shared_perm = 0;
74
-
75
/*
76
* If keep_old_opts is false then it means that unspecified
77
* options must be reset to their original value. We don't allow
78
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp)
82
{
79
{
83
QEDCheck check = {
80
int ret = -1;
84
.s = s,
81
BlockReopenQueueEntry *bs_entry, *next;
85
diff --git a/block/qed-table.c b/block/qed-table.c
82
+ Transaction *tran = tran_new();
86
index XXXXXXX..XXXXXXX 100644
83
+ g_autoptr(GHashTable) found = NULL;
87
--- a/block/qed-table.c
84
+ g_autoptr(GSList) refresh_list = NULL;
88
+++ b/block/qed-table.c
85
89
@@ -XXX,XX +XXX,XX @@
86
assert(bs_queue != NULL);
90
#include "qemu/bswap.h"
87
91
88
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp)
92
/* Called with table_lock held. */
89
93
-static int qed_read_table(BDRVQEDState *s, uint64_t offset, QEDTable *table)
90
QTAILQ_FOREACH(bs_entry, bs_queue, entry) {
94
+static int coroutine_fn qed_read_table(BDRVQEDState *s, uint64_t offset,
91
assert(bs_entry->state.bs->quiesce_counter > 0);
95
+ QEDTable *table)
92
- if (bdrv_reopen_prepare(&bs_entry->state, bs_queue, errp)) {
96
{
93
- goto cleanup;
97
unsigned int bytes = s->header.cluster_size * s->header.table_size;
94
+ ret = bdrv_reopen_prepare(&bs_entry->state, bs_queue, tran, errp);
98
95
+ if (ret < 0) {
99
@@ -XXX,XX +XXX,XX @@ out:
96
+ goto abort;
100
*
97
}
101
* Called with table_lock held.
98
bs_entry->prepared = true;
102
*/
99
}
103
-static int qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
100
104
- unsigned int index, unsigned int n, bool flush)
101
+ found = g_hash_table_new(NULL, NULL);
105
+static int coroutine_fn qed_write_table(BDRVQEDState *s, uint64_t offset,
102
QTAILQ_FOREACH(bs_entry, bs_queue, entry) {
106
+ QEDTable *table, unsigned int index,
103
BDRVReopenState *state = &bs_entry->state;
107
+ unsigned int n, bool flush)
104
- ret = bdrv_check_perm(state->bs, bs_queue, state->perm,
108
{
105
- state->shared_perm, errp);
109
unsigned int sector_mask = BDRV_SECTOR_SIZE / sizeof(uint64_t) - 1;
106
- if (ret < 0) {
110
unsigned int start, end, i;
107
- goto cleanup_perm;
111
@@ -XXX,XX +XXX,XX @@ out:
108
- }
109
- /* Check if new_backing_bs would accept the new permissions */
110
- if (state->replace_backing_bs && state->new_backing_bs) {
111
- uint64_t nperm, nshared;
112
- bdrv_child_perm(state->bs, state->new_backing_bs,
113
- NULL, bdrv_backing_role(state->bs),
114
- bs_queue, state->perm, state->shared_perm,
115
- &nperm, &nshared);
116
- ret = bdrv_check_update_perm(state->new_backing_bs, NULL,
117
- nperm, nshared, errp);
118
- if (ret < 0) {
119
- goto cleanup_perm;
120
- }
121
+
122
+ refresh_list = bdrv_topological_dfs(refresh_list, found, state->bs);
123
+ if (state->old_backing_bs) {
124
+ refresh_list = bdrv_topological_dfs(refresh_list, found,
125
+ state->old_backing_bs);
126
}
127
- bs_entry->perms_checked = true;
128
+ }
129
+
130
+ /*
131
+ * Note that file-posix driver rely on permission update done during reopen
132
+ * (even if no permission changed), because it wants "new" permissions for
133
+ * reconfiguring the fd and that's why it does it in raw_check_perm(), not
134
+ * in raw_reopen_prepare() which is called with "old" permissions.
135
+ */
136
+ ret = bdrv_list_refresh_perms(refresh_list, bs_queue, tran, errp);
137
+ if (ret < 0) {
138
+ goto abort;
139
}
140
141
/*
142
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp)
143
bdrv_reopen_commit(&bs_entry->state);
144
}
145
146
- ret = 0;
147
-cleanup_perm:
148
- QTAILQ_FOREACH_SAFE(bs_entry, bs_queue, entry, next) {
149
- BDRVReopenState *state = &bs_entry->state;
150
-
151
- if (!bs_entry->perms_checked) {
152
- continue;
153
- }
154
-
155
- if (ret == 0) {
156
- uint64_t perm, shared;
157
+ tran_commit(tran);
158
159
- bdrv_get_cumulative_perm(state->bs, &perm, &shared);
160
- assert(perm == state->perm);
161
- assert(shared == state->shared_perm);
162
+ QTAILQ_FOREACH_REVERSE(bs_entry, bs_queue, entry) {
163
+ BlockDriverState *bs = bs_entry->state.bs;
164
165
- bdrv_set_perm(state->bs);
166
- } else {
167
- bdrv_abort_perm_update(state->bs);
168
- if (state->replace_backing_bs && state->new_backing_bs) {
169
- bdrv_abort_perm_update(state->new_backing_bs);
170
- }
171
+ if (bs->drv->bdrv_reopen_commit_post) {
172
+ bs->drv->bdrv_reopen_commit_post(&bs_entry->state);
173
}
174
}
175
176
- if (ret == 0) {
177
- QTAILQ_FOREACH_REVERSE(bs_entry, bs_queue, entry) {
178
- BlockDriverState *bs = bs_entry->state.bs;
179
+ ret = 0;
180
+ goto cleanup;
181
182
- if (bs->drv->bdrv_reopen_commit_post)
183
- bs->drv->bdrv_reopen_commit_post(&bs_entry->state);
184
+abort:
185
+ tran_abort(tran);
186
+ QTAILQ_FOREACH_SAFE(bs_entry, bs_queue, entry, next) {
187
+ if (bs_entry->prepared) {
188
+ bdrv_reopen_abort(&bs_entry->state);
189
}
190
+ qobject_unref(bs_entry->state.explicit_options);
191
+ qobject_unref(bs_entry->state.options);
192
}
193
+
194
cleanup:
195
QTAILQ_FOREACH_SAFE(bs_entry, bs_queue, entry, next) {
196
- if (ret) {
197
- if (bs_entry->prepared) {
198
- bdrv_reopen_abort(&bs_entry->state);
199
- }
200
- qobject_unref(bs_entry->state.explicit_options);
201
- qobject_unref(bs_entry->state.options);
202
- }
203
- if (bs_entry->state.new_backing_bs) {
204
- bdrv_unref(bs_entry->state.new_backing_bs);
205
- }
206
g_free(bs_entry);
207
}
208
g_free(bs_queue);
209
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_set_read_only(BlockDriverState *bs, bool read_only,
112
return ret;
210
return ret;
113
}
211
}
114
212
115
-int qed_read_l1_table_sync(BDRVQEDState *s)
213
-static BlockReopenQueueEntry *find_parent_in_reopen_queue(BlockReopenQueue *q,
116
+int coroutine_fn qed_read_l1_table_sync(BDRVQEDState *s)
214
- BdrvChild *c)
215
-{
216
- BlockReopenQueueEntry *entry;
217
-
218
- QTAILQ_FOREACH(entry, q, entry) {
219
- BlockDriverState *bs = entry->state.bs;
220
- BdrvChild *child;
221
-
222
- QLIST_FOREACH(child, &bs->children, next) {
223
- if (child == c) {
224
- return entry;
225
- }
226
- }
227
- }
228
-
229
- return NULL;
230
-}
231
-
232
-static void bdrv_reopen_perm(BlockReopenQueue *q, BlockDriverState *bs,
233
- uint64_t *perm, uint64_t *shared)
234
-{
235
- BdrvChild *c;
236
- BlockReopenQueueEntry *parent;
237
- uint64_t cumulative_perms = 0;
238
- uint64_t cumulative_shared_perms = BLK_PERM_ALL;
239
-
240
- QLIST_FOREACH(c, &bs->parents, next_parent) {
241
- parent = find_parent_in_reopen_queue(q, c);
242
- if (!parent) {
243
- cumulative_perms |= c->perm;
244
- cumulative_shared_perms &= c->shared_perm;
245
- } else {
246
- uint64_t nperm, nshared;
247
-
248
- bdrv_child_perm(parent->state.bs, bs, c, c->role, q,
249
- parent->state.perm, parent->state.shared_perm,
250
- &nperm, &nshared);
251
-
252
- cumulative_perms |= nperm;
253
- cumulative_shared_perms &= nshared;
254
- }
255
- }
256
- *perm = cumulative_perms;
257
- *shared = cumulative_shared_perms;
258
-}
259
-
260
static bool bdrv_reopen_can_attach(BlockDriverState *parent,
261
BdrvChild *child,
262
BlockDriverState *new_child,
263
@@ -XXX,XX +XXX,XX @@ static bool bdrv_reopen_can_attach(BlockDriverState *parent,
264
* Return 0 on success, otherwise return < 0 and set @errp.
265
*/
266
static int bdrv_reopen_parse_backing(BDRVReopenState *reopen_state,
267
+ Transaction *set_backings_tran,
268
Error **errp)
117
{
269
{
118
return qed_read_table(s, s->header.l1_table_offset, s->l1_table);
270
BlockDriverState *bs = reopen_state->bs;
271
@@ -XXX,XX +XXX,XX @@ static int bdrv_reopen_parse_backing(BDRVReopenState *reopen_state,
272
273
/* If we want to replace the backing file we need some extra checks */
274
if (new_backing_bs != bdrv_filter_or_cow_bs(overlay_bs)) {
275
+ int ret;
276
+
277
/* Check for implicit nodes between bs and its backing file */
278
if (bs != overlay_bs) {
279
error_setg(errp, "Cannot change backing link if '%s' has "
280
@@ -XXX,XX +XXX,XX @@ static int bdrv_reopen_parse_backing(BDRVReopenState *reopen_state,
281
return -EPERM;
282
}
283
reopen_state->replace_backing_bs = true;
284
- if (new_backing_bs) {
285
- bdrv_ref(new_backing_bs);
286
- reopen_state->new_backing_bs = new_backing_bs;
287
+ reopen_state->old_backing_bs = bs->backing ? bs->backing->bs : NULL;
288
+ ret = bdrv_set_backing_noperm(bs, new_backing_bs, set_backings_tran,
289
+ errp);
290
+ if (ret < 0) {
291
+ return ret;
292
}
293
}
294
295
@@ -XXX,XX +XXX,XX @@ static int bdrv_reopen_parse_backing(BDRVReopenState *reopen_state,
296
*
297
*/
298
static int bdrv_reopen_prepare(BDRVReopenState *reopen_state,
299
- BlockReopenQueue *queue, Error **errp)
300
+ BlockReopenQueue *queue,
301
+ Transaction *set_backings_tran, Error **errp)
302
{
303
int ret = -1;
304
int old_flags;
305
@@ -XXX,XX +XXX,XX @@ static int bdrv_reopen_prepare(BDRVReopenState *reopen_state,
306
goto error;
307
}
308
309
- /* Calculate required permissions after reopening */
310
- bdrv_reopen_perm(queue, reopen_state->bs,
311
- &reopen_state->perm, &reopen_state->shared_perm);
312
-
313
if (drv->bdrv_reopen_prepare) {
314
/*
315
* If a driver-specific option is missing, it means that we
316
@@ -XXX,XX +XXX,XX @@ static int bdrv_reopen_prepare(BDRVReopenState *reopen_state,
317
* either a reference to an existing node (using its node name)
318
* or NULL to simply detach the current backing file.
319
*/
320
- ret = bdrv_reopen_parse_backing(reopen_state, errp);
321
+ ret = bdrv_reopen_parse_backing(reopen_state, set_backings_tran, errp);
322
if (ret < 0) {
323
goto error;
324
}
325
@@ -XXX,XX +XXX,XX @@ static void bdrv_reopen_commit(BDRVReopenState *reopen_state)
326
qdict_del(bs->explicit_options, child->name);
327
qdict_del(bs->options, child->name);
328
}
329
-
330
- /*
331
- * Change the backing file if a new one was specified. We do this
332
- * after updating bs->options, so bdrv_refresh_filename() (called
333
- * from bdrv_set_backing_hd()) has the new values.
334
- */
335
- if (reopen_state->replace_backing_bs) {
336
- BlockDriverState *old_backing_bs = child_bs(bs->backing);
337
- assert(!old_backing_bs || !old_backing_bs->implicit);
338
- /* Abort the permission update on the backing bs we're detaching */
339
- if (old_backing_bs) {
340
- bdrv_abort_perm_update(old_backing_bs);
341
- }
342
- bdrv_set_backing_hd(bs, reopen_state->new_backing_bs, &error_abort);
343
- }
344
-
345
bdrv_refresh_limits(bs, NULL, NULL);
119
}
346
}
120
347
121
/* Called with table_lock held. */
348
diff --git a/block/file-posix.c b/block/file-posix.c
122
-int qed_write_l1_table(BDRVQEDState *s, unsigned int index, unsigned int n)
349
index XXXXXXX..XXXXXXX 100644
123
+int coroutine_fn qed_write_l1_table(BDRVQEDState *s, unsigned int index,
350
--- a/block/file-posix.c
124
+ unsigned int n)
351
+++ b/block/file-posix.c
352
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVRawState {
353
} BDRVRawState;
354
355
typedef struct BDRVRawReopenState {
356
- int fd;
357
int open_flags;
358
bool drop_cache;
359
bool check_cache_dropped;
360
@@ -XXX,XX +XXX,XX @@ static int raw_reopen_prepare(BDRVReopenState *state,
361
BDRVRawReopenState *rs;
362
QemuOpts *opts;
363
int ret;
364
- Error *local_err = NULL;
365
366
assert(state != NULL);
367
assert(state->bs != NULL);
368
@@ -XXX,XX +XXX,XX @@ static int raw_reopen_prepare(BDRVReopenState *state,
369
* bdrv_reopen_prepare() will detect changes and complain. */
370
qemu_opts_to_qdict(opts, state->options);
371
372
- rs->fd = raw_reconfigure_getfd(state->bs, state->flags, &rs->open_flags,
373
- state->perm, true, &local_err);
374
- if (local_err) {
375
- error_propagate(errp, local_err);
376
- ret = -1;
377
- goto out;
378
- }
379
-
380
- /* Fail already reopen_prepare() if we can't get a working O_DIRECT
381
- * alignment with the new fd. */
382
- if (rs->fd != -1) {
383
- raw_probe_alignment(state->bs, rs->fd, &local_err);
384
- if (local_err) {
385
- error_propagate(errp, local_err);
386
- ret = -EINVAL;
387
- goto out_fd;
388
- }
389
- }
390
+ /*
391
+ * As part of reopen prepare we also want to create new fd by
392
+ * raw_reconfigure_getfd(). But it wants updated "perm", when in
393
+ * bdrv_reopen_multiple() .bdrv_reopen_prepare() callback called prior to
394
+ * permission update. Happily, permission update is always a part (a seprate
395
+ * stage) of bdrv_reopen_multiple() so we can rely on this fact and
396
+ * reconfigure fd in raw_check_perm().
397
+ */
398
399
s->reopen_state = state;
400
ret = 0;
401
-out_fd:
402
- if (ret < 0) {
403
- qemu_close(rs->fd);
404
- rs->fd = -1;
405
- }
406
+
407
out:
408
qemu_opts_del(opts);
409
return ret;
410
@@ -XXX,XX +XXX,XX @@ static void raw_reopen_commit(BDRVReopenState *state)
411
s->drop_cache = rs->drop_cache;
412
s->check_cache_dropped = rs->check_cache_dropped;
413
s->open_flags = rs->open_flags;
414
-
415
- qemu_close(s->fd);
416
- s->fd = rs->fd;
417
-
418
g_free(state->opaque);
419
state->opaque = NULL;
420
421
@@ -XXX,XX +XXX,XX @@ static void raw_reopen_abort(BDRVReopenState *state)
422
return;
423
}
424
425
- if (rs->fd >= 0) {
426
- qemu_close(rs->fd);
427
- rs->fd = -1;
428
- }
429
g_free(state->opaque);
430
state->opaque = NULL;
431
432
@@ -XXX,XX +XXX,XX @@ static int raw_check_perm(BlockDriverState *bs, uint64_t perm, uint64_t shared,
433
Error **errp)
125
{
434
{
126
BLKDBG_EVENT(s->bs->file, BLKDBG_L1_UPDATE);
435
BDRVRawState *s = bs->opaque;
127
return qed_write_table(s, s->header.l1_table_offset,
436
- BDRVRawReopenState *rs = NULL;
128
s->l1_table, index, n, false);
437
+ int input_flags = s->reopen_state ? s->reopen_state->flags : bs->open_flags;
129
}
438
int open_flags;
130
131
-int qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index,
132
- unsigned int n)
133
+int coroutine_fn qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index,
134
+ unsigned int n)
135
{
136
return qed_write_l1_table(s, index, n);
137
}
138
139
/* Called with table_lock held. */
140
-int qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset)
141
+int coroutine_fn qed_read_l2_table(BDRVQEDState *s, QEDRequest *request,
142
+ uint64_t offset)
143
{
144
int ret;
439
int ret;
145
440
146
@@ -XXX,XX +XXX,XX @@ int qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset)
441
- if (s->perm_change_fd) {
147
return ret;
442
+ /* We may need a new fd if auto-read-only switches the mode */
148
}
443
+ ret = raw_reconfigure_getfd(bs, input_flags, &open_flags, perm,
149
444
+ false, errp);
150
-int qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request, uint64_t offset)
445
+ if (ret < 0) {
151
+int coroutine_fn qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
446
+ return ret;
152
+ uint64_t offset)
447
+ } else if (ret != s->fd) {
153
{
448
+ Error *local_err = NULL;
154
return qed_read_l2_table(s, request, offset);
449
+
155
}
450
/*
156
451
- * In the context of reopen, this function may be called several times
157
/* Called with table_lock held. */
452
- * (directly and recursively while change permissions of the parent).
158
-int qed_write_l2_table(BDRVQEDState *s, QEDRequest *request,
453
- * This is even true for children that don't inherit from the original
159
- unsigned int index, unsigned int n, bool flush)
454
- * reopen node, so s->reopen_state is not set.
160
+int coroutine_fn qed_write_l2_table(BDRVQEDState *s, QEDRequest *request,
455
- *
161
+ unsigned int index, unsigned int n,
456
- * Ignore all but the first call.
162
+ bool flush)
457
+ * Fail already check_perm() if we can't get a working O_DIRECT
163
{
458
+ * alignment with the new fd.
164
BLKDBG_EVENT(s->bs->file, BLKDBG_L2_UPDATE);
459
*/
165
return qed_write_table(s, request->l2_table->offset,
460
- return 0;
166
request->l2_table->table, index, n, flush);
461
- }
167
}
462
-
168
463
- if (s->reopen_state) {
169
-int qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
464
- /* We already have a new file descriptor to set permissions for */
170
- unsigned int index, unsigned int n, bool flush)
465
- assert(s->reopen_state->perm == perm);
171
+int coroutine_fn qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
466
- assert(s->reopen_state->shared_perm == shared);
172
+ unsigned int index, unsigned int n,
467
- rs = s->reopen_state->opaque;
173
+ bool flush)
468
- s->perm_change_fd = rs->fd;
174
{
469
- s->perm_change_flags = rs->open_flags;
175
return qed_write_l2_table(s, request, index, n, flush);
470
- } else {
176
}
471
- /* We may need a new fd if auto-read-only switches the mode */
177
diff --git a/block/qed.c b/block/qed.c
472
- ret = raw_reconfigure_getfd(bs, bs->open_flags, &open_flags, perm,
178
index XXXXXXX..XXXXXXX 100644
473
- false, errp);
179
--- a/block/qed.c
474
- if (ret < 0) {
180
+++ b/block/qed.c
475
- return ret;
181
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_qed_co_invalidate_cache(BlockDriverState *bs,
476
- } else if (ret != s->fd) {
182
}
477
- s->perm_change_fd = ret;
183
}
478
- s->perm_change_flags = open_flags;
184
479
+ raw_probe_alignment(bs, ret, &local_err);
185
-static int bdrv_qed_co_check(BlockDriverState *bs, BdrvCheckResult *result,
480
+ if (local_err) {
186
- BdrvCheckMode fix)
481
+ error_propagate(errp, local_err);
187
+static int coroutine_fn bdrv_qed_co_check(BlockDriverState *bs,
482
+ return -EINVAL;
188
+ BdrvCheckResult *result,
483
}
189
+ BdrvCheckMode fix)
484
+
190
{
485
+ s->perm_change_fd = ret;
191
BDRVQEDState *s = bs->opaque;
486
+ s->perm_change_flags = open_flags;
192
int ret;
487
}
488
489
/* Prepare permissions on old fd to avoid conflicts between old and new,
490
@@ -XXX,XX +XXX,XX @@ static int raw_check_perm(BlockDriverState *bs, uint64_t perm, uint64_t shared,
491
return 0;
492
493
fail:
494
- if (s->perm_change_fd && !s->reopen_state) {
495
+ if (s->perm_change_fd) {
496
qemu_close(s->perm_change_fd);
497
}
498
s->perm_change_fd = 0;
499
@@ -XXX,XX +XXX,XX @@ static void raw_abort_perm_update(BlockDriverState *bs)
500
501
/* For reopen, .bdrv_reopen_abort is called afterwards and will close
502
* the file descriptor. */
503
- if (s->perm_change_fd && !s->reopen_state) {
504
+ if (s->perm_change_fd) {
505
qemu_close(s->perm_change_fd);
506
}
507
s->perm_change_fd = 0;
193
--
508
--
194
2.20.1
509
2.30.2
195
510
196
511
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
Disk sizes close to INT64_MAX cause overflow, for some pretty
3
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
4
ridiculous output:
4
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
5
Message-Id: <20210428151804.439460-32-vsementsov@virtuozzo.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
8
block.c | 103 --------------------------------------------------------
9
1 file changed, 103 deletions(-)
5
10
6
$ ./nbdkit -U - memory size=$((2**63 - 512)) --run 'qemu-img info $nbd'
11
diff --git a/block.c b/block.c
7
image: nbd+unix://?socket=/tmp/nbdkitHSAzNz/socket
8
file format: raw
9
virtual size: -8388607T (9223372036854775296 bytes)
10
disk size: unavailable
11
12
But there's no reason to have two separate implementations of integer
13
to human-readable abbreviation, where one has overflow and stops at
14
'T', while the other avoids overflow and goes all the way to 'E'. With
15
this patch, the output now claims 8EiB instead of -8388607T, which
16
really is the correct rounding of largest file size supported by qemu
17
(we could go 511 bytes larger if we used byte-accurate sizing instead
18
of rounding up to the next sector boundary, but that wouldn't change
19
the human-readable result).
20
21
Quite a few iotests need updates to expected output to match.
22
23
Reported-by: Richard W.M. Jones <rjones@redhat.com>
24
Signed-off-by: Eric Blake <eblake@redhat.com>
25
Tested-by: Richard W.M. Jones <rjones@redhat.com>
26
Reviewed-by: Alberto Garcia <berto@igalia.com>
27
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
28
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
29
Tested-by: Max Reitz <mreitz@redhat.com>
30
---
31
block/qapi.c | 49 +++++++++-----------------------------
32
tests/qemu-iotests/043.out | 6 ++---
33
tests/qemu-iotests/053.out | 2 +-
34
tests/qemu-iotests/059.out | 10 ++++----
35
tests/qemu-iotests/060.out | 10 ++++----
36
tests/qemu-iotests/061.out | 12 +++++-----
37
tests/qemu-iotests/070.out | 2 +-
38
tests/qemu-iotests/082.out | 26 ++++++++++----------
39
tests/qemu-iotests/084.out | 8 +++----
40
tests/qemu-iotests/089.out | 2 +-
41
tests/qemu-iotests/095.out | 4 ++--
42
tests/qemu-iotests/104.out | 6 ++---
43
tests/qemu-iotests/110.out | 6 ++---
44
tests/qemu-iotests/114.out | 2 +-
45
tests/qemu-iotests/126.out | 4 ++--
46
tests/qemu-iotests/130.out | 10 ++++----
47
tests/qemu-iotests/153.out | 2 +-
48
tests/qemu-iotests/191.out | 8 +++----
49
tests/qemu-iotests/195.out | 4 ++--
50
tests/qemu-iotests/198.out | 4 ++--
51
tests/qemu-iotests/206.out | 10 ++++----
52
tests/qemu-iotests/207.out | 12 +++++-----
53
tests/qemu-iotests/210.out | 8 +++----
54
tests/qemu-iotests/211.out | 10 ++++----
55
tests/qemu-iotests/212.out | 10 ++++----
56
tests/qemu-iotests/213.out | 10 ++++----
57
tests/qemu-iotests/233.out | 4 ++--
58
tests/qemu-iotests/237.out | 22 ++++++++---------
59
tests/qemu-iotests/242.out | 10 ++++----
60
29 files changed, 123 insertions(+), 150 deletions(-)
61
62
diff --git a/block/qapi.c b/block/qapi.c
63
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
64
--- a/block/qapi.c
13
--- a/block.c
65
+++ b/block/qapi.c
14
+++ b/block.c
66
@@ -XXX,XX +XXX,XX @@ BlockStatsList *qmp_query_blockstats(bool has_query_nodes,
15
@@ -XXX,XX +XXX,XX @@ static int bdrv_fill_options(QDict **options, const char *filename,
67
return head;
16
return 0;
68
}
17
}
69
18
70
-#define NB_SUFFIXES 4
19
-static int bdrv_check_update_perm(BlockDriverState *bs, BlockReopenQueue *q,
20
- uint64_t new_used_perm,
21
- uint64_t new_shared_perm,
22
- Error **errp);
71
-
23
-
72
-static char *get_human_readable_size(char *buf, int buf_size, int64_t size)
24
typedef struct BlockReopenQueueEntry {
25
bool prepared;
26
bool perms_checked;
27
@@ -XXX,XX +XXX,XX @@ static int bdrv_check_perm_common(GSList *list, BlockReopenQueue *q,
28
return 0;
29
}
30
31
-static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
32
- uint64_t cumulative_perms,
33
- uint64_t cumulative_shared_perms, Error **errp)
73
-{
34
-{
74
- static const char suffixes[NB_SUFFIXES] = {'K', 'M', 'G', 'T'};
35
- g_autoptr(GSList) list = bdrv_topological_dfs(NULL, NULL, bs);
75
- int64_t base;
36
- return bdrv_check_perm_common(list, q, true, cumulative_perms,
76
- int i;
37
- cumulative_shared_perms, NULL, errp);
77
-
78
- if (size <= 999) {
79
- snprintf(buf, buf_size, "%" PRId64, size);
80
- } else {
81
- base = 1024;
82
- for (i = 0; i < NB_SUFFIXES; i++) {
83
- if (size < (10 * base)) {
84
- snprintf(buf, buf_size, "%0.1f%c",
85
- (double)size / base,
86
- suffixes[i]);
87
- break;
88
- } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
89
- snprintf(buf, buf_size, "%" PRId64 "%c",
90
- ((size + (base >> 1)) / base),
91
- suffixes[i]);
92
- break;
93
- }
94
- base = base * 1024;
95
- }
96
- }
97
- return buf;
98
-}
38
-}
99
-
39
-
100
void bdrv_snapshot_dump(QEMUSnapshotInfo *sn)
40
static int bdrv_list_refresh_perms(GSList *list, BlockReopenQueue *q,
41
Transaction *tran, Error **errp)
101
{
42
{
102
- char buf1[128], date_buf[128], clock_buf[128];
43
return bdrv_check_perm_common(list, q, false, 0, 0, tran, errp);
103
+ char date_buf[128], clock_buf[128];
104
struct tm tm;
105
time_t ti;
106
int64_t secs;
107
+ char *sizing = NULL;
108
109
if (!sn) {
110
qemu_printf("%-10s%-20s%7s%20s%15s",
111
@@ -XXX,XX +XXX,XX @@ void bdrv_snapshot_dump(QEMUSnapshotInfo *sn)
112
(int)((secs / 60) % 60),
113
(int)(secs % 60),
114
(int)((sn->vm_clock_nsec / 1000000) % 1000));
115
+ sizing = size_to_str(sn->vm_state_size);
116
qemu_printf("%-10s%-20s%7s%20s%15s",
117
sn->id_str, sn->name,
118
- get_human_readable_size(buf1, sizeof(buf1),
119
- sn->vm_state_size),
120
+ sizing,
121
date_buf,
122
clock_buf);
123
}
124
+ g_free(sizing);
125
}
44
}
126
45
127
static void dump_qdict(int indentation, QDict *dict);
46
-/*
128
@@ -XXX,XX +XXX,XX @@ void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec)
47
- * Notifies drivers that after a previous bdrv_check_perm() call, the
129
48
- * permission update is not performed and any preparations made for it (e.g.
130
void bdrv_image_info_dump(ImageInfo *info)
49
- * taken file locks) need to be undone.
50
- */
51
-static void bdrv_node_abort_perm_update(BlockDriverState *bs)
52
-{
53
- BlockDriver *drv = bs->drv;
54
- BdrvChild *c;
55
-
56
- if (!drv) {
57
- return;
58
- }
59
-
60
- bdrv_drv_set_perm_abort(bs);
61
-
62
- QLIST_FOREACH(c, &bs->children, next) {
63
- bdrv_child_set_perm_abort(c);
64
- }
65
-}
66
-
67
-static void bdrv_list_abort_perm_update(GSList *list)
68
-{
69
- for ( ; list; list = list->next) {
70
- bdrv_node_abort_perm_update((BlockDriverState *)list->data);
71
- }
72
-}
73
-
74
-__attribute__((unused))
75
-static void bdrv_abort_perm_update(BlockDriverState *bs)
76
-{
77
- g_autoptr(GSList) list = bdrv_topological_dfs(NULL, NULL, bs);
78
- return bdrv_list_abort_perm_update(list);
79
-}
80
-
81
static void bdrv_node_set_perm(BlockDriverState *bs)
131
{
82
{
132
- char size_buf[128], dsize_buf[128];
83
BlockDriver *drv = bs->drv;
133
+ char *size_buf, *dsize_buf;
84
@@ -XXX,XX +XXX,XX @@ char *bdrv_perm_names(uint64_t perm)
134
if (!info->has_actual_size) {
85
return g_string_free(result, FALSE);
135
- snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
136
+ dsize_buf = g_strdup("unavailable");
137
} else {
138
- get_human_readable_size(dsize_buf, sizeof(dsize_buf),
139
- info->actual_size);
140
+ dsize_buf = size_to_str(info->actual_size);
141
}
142
- get_human_readable_size(size_buf, sizeof(size_buf), info->virtual_size);
143
+ size_buf = size_to_str(info->virtual_size);
144
qemu_printf("image: %s\n"
145
"file format: %s\n"
146
"virtual size: %s (%" PRId64 " bytes)\n"
147
@@ -XXX,XX +XXX,XX @@ void bdrv_image_info_dump(ImageInfo *info)
148
info->filename, info->format, size_buf,
149
info->virtual_size,
150
dsize_buf);
151
+ g_free(size_buf);
152
+ g_free(dsize_buf);
153
154
if (info->has_encrypted && info->encrypted) {
155
qemu_printf("encrypted: yes\n");
156
diff --git a/tests/qemu-iotests/043.out b/tests/qemu-iotests/043.out
157
index XXXXXXX..XXXXXXX 100644
158
--- a/tests/qemu-iotests/043.out
159
+++ b/tests/qemu-iotests/043.out
160
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/
161
== finite chain of length 3 (human) ==
162
image: TEST_DIR/t.IMGFMT
163
file format: IMGFMT
164
-virtual size: 128M (134217728 bytes)
165
+virtual size: 128 MiB (134217728 bytes)
166
cluster_size: 65536
167
backing file: TEST_DIR/t.IMGFMT.2.base
168
169
image: TEST_DIR/t.IMGFMT.2.base
170
file format: IMGFMT
171
-virtual size: 128M (134217728 bytes)
172
+virtual size: 128 MiB (134217728 bytes)
173
cluster_size: 65536
174
backing file: TEST_DIR/t.IMGFMT.1.base
175
176
image: TEST_DIR/t.IMGFMT.1.base
177
file format: IMGFMT
178
-virtual size: 128M (134217728 bytes)
179
+virtual size: 128 MiB (134217728 bytes)
180
cluster_size: 65536
181
182
== finite chain of length 3 (json) ==
183
diff --git a/tests/qemu-iotests/053.out b/tests/qemu-iotests/053.out
184
index XXXXXXX..XXXXXXX 100644
185
--- a/tests/qemu-iotests/053.out
186
+++ b/tests/qemu-iotests/053.out
187
@@ -XXX,XX +XXX,XX @@ wrote 512/512 bytes at offset 0
188
No errors were found on the image.
189
190
== Checking compressed image virtual disk size ==
191
-virtual size: 512 (512 bytes)
192
+virtual size: 512 B (512 bytes)
193
194
== Verifying the compressed image ==
195
read 512/512 bytes at offset 0
196
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
197
index XXXXXXX..XXXXXXX 100644
198
--- a/tests/qemu-iotests/059.out
199
+++ b/tests/qemu-iotests/059.out
200
@@ -XXX,XX +XXX,XX @@ can't open device TEST_DIR/t.vmdk: L1 size too big
201
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648 subformat=monolithicFlat
202
image: TEST_DIR/t.IMGFMT
203
file format: IMGFMT
204
-virtual size: 2.0G (2147483648 bytes)
205
+virtual size: 2 GiB (2147483648 bytes)
206
207
=== Testing monolithicFlat with zeroed_grain ===
208
qemu-img: TEST_DIR/t.IMGFMT: Flat image can't enable zeroed grain
209
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648 subformat=monolithicF
210
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824000 subformat=twoGbMaxExtentFlat
211
image: TEST_DIR/t.vmdk
212
file format: vmdk
213
-virtual size: 1.0T (1073741824000 bytes)
214
-disk size: 16K
215
+virtual size: 0.977 TiB (1073741824000 bytes)
216
+disk size: 16 KiB
217
Format specific information:
218
cid: XXXXXXXX
219
parent cid: XXXXXXXX
220
@@ -XXX,XX +XXX,XX @@ can't open: Cannot use relative extent paths with VMDK descriptor file 'json:{"i
221
=== Testing version 3 ===
222
image: TEST_DIR/iotest-version3.IMGFMT
223
file format: IMGFMT
224
-virtual size: 16G (17179869184 bytes)
225
+virtual size: 16 GiB (17179869184 bytes)
226
cluster_size: 65536
227
read 512/512 bytes at offset 0
228
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
229
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 64931328
230
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4398046511104 subformat=monolithicFlat
231
image: TEST_DIR/t.IMGFMT
232
file format: IMGFMT
233
-virtual size: 4.0T (4398046511104 bytes)
234
+virtual size: 4 TiB (4398046511104 bytes)
235
wrote 512/512 bytes at offset 966367641600
236
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
237
e100000000: 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a ................
238
diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out
239
index XXXXXXX..XXXXXXX 100644
240
--- a/tests/qemu-iotests/060.out
241
+++ b/tests/qemu-iotests/060.out
242
@@ -XXX,XX +XXX,XX @@ write failed: Input/output error
243
incompatible_features 0x2
244
image: TEST_DIR/t.IMGFMT
245
file format: IMGFMT
246
-virtual size: 64M (67108864 bytes)
247
+virtual size: 64 MiB (67108864 bytes)
248
cluster_size: 65536
249
Format specific information:
250
compat: 1.1
251
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
252
qcow2: Marking image as corrupt: Refblock at 0xffffff00000000 is not covered by the refcount structures; further corruption events will be suppressed
253
qemu-img: Failed to discard unused refblocks: Input/output error
254
--- Checking and retrying ---
255
-virtual size: 64M (67108864 bytes)
256
+virtual size: 64 MiB (67108864 bytes)
257
No errors were found on the image.
258
Image resized.
259
-virtual size: 32M (33554432 bytes)
260
+virtual size: 32 MiB (33554432 bytes)
261
262
=== Discarding a non-covered in-bounds refblock ===
263
264
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
265
qcow2: Marking image as corrupt: Refblock at 0x1000000000 is not covered by the refcount structures; further corruption events will be suppressed
266
qemu-img: Failed to discard unused refblocks: Input/output error
267
--- Checking and retrying ---
268
-virtual size: 64M (67108864 bytes)
269
+virtual size: 64 MiB (67108864 bytes)
270
No errors were found on the image.
271
Image resized.
272
-virtual size: 32M (33554432 bytes)
273
+virtual size: 32 MiB (33554432 bytes)
274
275
=== Discarding a refblock covered by an unaligned refblock ===
276
277
diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out
278
index XXXXXXX..XXXXXXX 100644
279
--- a/tests/qemu-iotests/061.out
280
+++ b/tests/qemu-iotests/061.out
281
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IM
282
qemu-img: Cannot downgrade an image with a data file
283
image: TEST_DIR/t.IMGFMT
284
file format: IMGFMT
285
-virtual size: 64M (67108864 bytes)
286
+virtual size: 64 MiB (67108864 bytes)
287
cluster_size: 65536
288
Format specific information:
289
compat: 1.1
290
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IM
291
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Could not open 'foo': No such file or directory
292
image: TEST_DIR/t.IMGFMT
293
file format: IMGFMT
294
-virtual size: 64M (67108864 bytes)
295
+virtual size: 64 MiB (67108864 bytes)
296
cluster_size: 65536
297
Format specific information:
298
compat: 1.1
299
@@ -XXX,XX +XXX,XX @@ Format specific information:
300
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'data-file' is required for this image
301
image: TEST_DIR/t.IMGFMT
302
file format: IMGFMT
303
-virtual size: 64M (67108864 bytes)
304
+virtual size: 64 MiB (67108864 bytes)
305
cluster_size: 65536
306
Format specific information:
307
compat: 1.1
308
@@ -XXX,XX +XXX,XX @@ Format specific information:
309
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IMGFMT.data data_file_raw=on
310
image: TEST_DIR/t.IMGFMT
311
file format: IMGFMT
312
-virtual size: 64M (67108864 bytes)
313
+virtual size: 64 MiB (67108864 bytes)
314
cluster_size: 65536
315
Format specific information:
316
compat: 1.1
317
@@ -XXX,XX +XXX,XX @@ Format specific information:
318
No errors were found on the image.
319
image: TEST_DIR/t.IMGFMT
320
file format: IMGFMT
321
-virtual size: 64M (67108864 bytes)
322
+virtual size: 64 MiB (67108864 bytes)
323
cluster_size: 65536
324
Format specific information:
325
compat: 1.1
326
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
327
qemu-img: data-file-raw cannot be set on existing images
328
image: TEST_DIR/t.IMGFMT
329
file format: IMGFMT
330
-virtual size: 64M (67108864 bytes)
331
+virtual size: 64 MiB (67108864 bytes)
332
cluster_size: 65536
333
Format specific information:
334
compat: 1.1
335
diff --git a/tests/qemu-iotests/070.out b/tests/qemu-iotests/070.out
336
index XXXXXXX..XXXXXXX 100644
337
--- a/tests/qemu-iotests/070.out
338
+++ b/tests/qemu-iotests/070.out
339
@@ -XXX,XX +XXX,XX @@ read 18874368/18874368 bytes at offset 0
340
=== Verify image created by Disk2VHD can be opened ===
341
image: TEST_DIR/test-disk2vhd.IMGFMT
342
file format: IMGFMT
343
-virtual size: 256M (268435456 bytes)
344
+virtual size: 256 MiB (268435456 bytes)
345
cluster_size: 2097152
346
*** done
347
diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out
348
index XXXXXXX..XXXXXXX 100644
349
--- a/tests/qemu-iotests/082.out
350
+++ b/tests/qemu-iotests/082.out
351
@@ -XXX,XX +XXX,XX @@ Testing: create -f foo -f qcow2 TEST_DIR/t.qcow2 128M
352
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16
353
image: TEST_DIR/t.IMGFMT
354
file format: IMGFMT
355
-virtual size: 128M (134217728 bytes)
356
+virtual size: 128 MiB (134217728 bytes)
357
cluster_size: 65536
358
359
Testing: create -f qcow2 -o cluster_size=4k -o lazy_refcounts=on TEST_DIR/t.qcow2 128M
360
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=4096 lazy_refcounts=on refcount_bits=16
361
image: TEST_DIR/t.IMGFMT
362
file format: IMGFMT
363
-virtual size: 128M (134217728 bytes)
364
+virtual size: 128 MiB (134217728 bytes)
365
cluster_size: 4096
366
Format specific information:
367
compat: 1.1
368
@@ -XXX,XX +XXX,XX @@ Testing: create -f qcow2 -o cluster_size=4k -o lazy_refcounts=on -o cluster_size
369
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=8192 lazy_refcounts=on refcount_bits=16
370
image: TEST_DIR/t.IMGFMT
371
file format: IMGFMT
372
-virtual size: 128M (134217728 bytes)
373
+virtual size: 128 MiB (134217728 bytes)
374
cluster_size: 8192
375
Format specific information:
376
compat: 1.1
377
@@ -XXX,XX +XXX,XX @@ Testing: create -f qcow2 -o cluster_size=4k,cluster_size=8k TEST_DIR/t.qcow2 128
378
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=8192 lazy_refcounts=off refcount_bits=16
379
image: TEST_DIR/t.IMGFMT
380
file format: IMGFMT
381
-virtual size: 128M (134217728 bytes)
382
+virtual size: 128 MiB (134217728 bytes)
383
cluster_size: 8192
384
385
=== create: help for -o ===
386
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_
387
Testing: convert -f foo -f qcow2 TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
388
image: TEST_DIR/t.IMGFMT.base
389
file format: raw
390
-virtual size: 128M (134217728 bytes)
391
+virtual size: 128 MiB (134217728 bytes)
392
393
Testing: convert -O foo -O qcow2 TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
394
image: TEST_DIR/t.IMGFMT.base
395
file format: IMGFMT
396
-virtual size: 128M (134217728 bytes)
397
+virtual size: 128 MiB (134217728 bytes)
398
cluster_size: 65536
399
400
Testing: convert -O qcow2 -o cluster_size=4k -o lazy_refcounts=on TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
401
image: TEST_DIR/t.IMGFMT.base
402
file format: IMGFMT
403
-virtual size: 128M (134217728 bytes)
404
+virtual size: 128 MiB (134217728 bytes)
405
cluster_size: 4096
406
Format specific information:
407
compat: 1.1
408
@@ -XXX,XX +XXX,XX @@ Format specific information:
409
Testing: convert -O qcow2 -o cluster_size=4k -o lazy_refcounts=on -o cluster_size=8k TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
410
image: TEST_DIR/t.IMGFMT.base
411
file format: IMGFMT
412
-virtual size: 128M (134217728 bytes)
413
+virtual size: 128 MiB (134217728 bytes)
414
cluster_size: 8192
415
Format specific information:
416
compat: 1.1
417
@@ -XXX,XX +XXX,XX @@ Format specific information:
418
Testing: convert -O qcow2 -o cluster_size=4k,cluster_size=8k TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
419
image: TEST_DIR/t.IMGFMT.base
420
file format: IMGFMT
421
-virtual size: 128M (134217728 bytes)
422
+virtual size: 128 MiB (134217728 bytes)
423
cluster_size: 8192
424
425
=== convert: help for -o ===
426
@@ -XXX,XX +XXX,XX @@ qemu-img: Cannot enable copy offloading when -c is used
427
Testing: amend -f foo -f qcow2 -o lazy_refcounts=on TEST_DIR/t.qcow2
428
image: TEST_DIR/t.IMGFMT
429
file format: IMGFMT
430
-virtual size: 128M (134217728 bytes)
431
+virtual size: 128 MiB (134217728 bytes)
432
cluster_size: 65536
433
Format specific information:
434
compat: 1.1
435
@@ -XXX,XX +XXX,XX @@ Format specific information:
436
Testing: amend -f qcow2 -o size=130M -o lazy_refcounts=off TEST_DIR/t.qcow2
437
image: TEST_DIR/t.IMGFMT
438
file format: IMGFMT
439
-virtual size: 130M (136314880 bytes)
440
+virtual size: 130 MiB (136314880 bytes)
441
cluster_size: 65536
442
Format specific information:
443
compat: 1.1
444
@@ -XXX,XX +XXX,XX @@ Format specific information:
445
Testing: amend -f qcow2 -o size=8M -o lazy_refcounts=on -o size=132M TEST_DIR/t.qcow2
446
image: TEST_DIR/t.IMGFMT
447
file format: IMGFMT
448
-virtual size: 132M (138412032 bytes)
449
+virtual size: 132 MiB (138412032 bytes)
450
cluster_size: 65536
451
Format specific information:
452
compat: 1.1
453
@@ -XXX,XX +XXX,XX @@ Format specific information:
454
Testing: amend -f qcow2 -o size=4M,size=148M TEST_DIR/t.qcow2
455
image: TEST_DIR/t.IMGFMT
456
file format: IMGFMT
457
-virtual size: 148M (155189248 bytes)
458
+virtual size: 148 MiB (155189248 bytes)
459
cluster_size: 65536
460
461
=== amend: help for -o ===
462
diff --git a/tests/qemu-iotests/084.out b/tests/qemu-iotests/084.out
463
index XXXXXXX..XXXXXXX 100644
464
--- a/tests/qemu-iotests/084.out
465
+++ b/tests/qemu-iotests/084.out
466
@@ -XXX,XX +XXX,XX @@ QA output created by 084
467
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
468
image: TEST_DIR/t.IMGFMT
469
file format: IMGFMT
470
-virtual size: 64M (67108864 bytes)
471
+virtual size: 64 MiB (67108864 bytes)
472
cluster_size: 1048576
473
disk image file size in bytes: 67109888
474
475
@@ -XXX,XX +XXX,XX @@ disk image file size in bytes: 67109888
476
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
477
image: TEST_DIR/t.IMGFMT
478
file format: IMGFMT
479
-virtual size: 64M (67108864 bytes)
480
+virtual size: 64 MiB (67108864 bytes)
481
cluster_size: 1048576
482
disk image file size in bytes: 1024
483
Test 1: Maximum size (512 TB - 128 MB):
484
image: TEST_DIR/t.IMGFMT
485
file format: IMGFMT
486
-virtual size: 512T (562949819203584 bytes)
487
+virtual size: 512 TiB (562949819203584 bytes)
488
cluster_size: 1048576
489
490
Test 2: Size too large (512 TB - 128 MB + 64 kB)
491
@@ -XXX,XX +XXX,XX @@ qemu-img: Could not open 'TEST_DIR/t.IMGFMT': unsupported VDI image (too many bl
492
Test 5: Valid Image: 64MB, Blocks In Image 64, Block Size 1MB
493
image: TEST_DIR/t.IMGFMT
494
file format: IMGFMT
495
-virtual size: 64M (67108864 bytes)
496
+virtual size: 64 MiB (67108864 bytes)
497
cluster_size: 1048576
498
499
Test 6: Block Size != 1MB; too small test (1MB - 1)
500
diff --git a/tests/qemu-iotests/089.out b/tests/qemu-iotests/089.out
501
index XXXXXXX..XXXXXXX 100644
502
--- a/tests/qemu-iotests/089.out
503
+++ b/tests/qemu-iotests/089.out
504
@@ -XXX,XX +XXX,XX @@ read failed: Input/output error
505
506
image: TEST_DIR/t.IMGFMT
507
file format: IMGFMT
508
-virtual size: 64M (67108864 bytes)
509
+virtual size: 64 MiB (67108864 bytes)
510
cluster_size: 65536
511
512
=== Testing option merging ===
513
diff --git a/tests/qemu-iotests/095.out b/tests/qemu-iotests/095.out
514
index XXXXXXX..XXXXXXX 100644
515
--- a/tests/qemu-iotests/095.out
516
+++ b/tests/qemu-iotests/095.out
517
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=104857600 backing_file=TEST_DIR/
518
=== Base image info before commit and resize ===
519
image: TEST_DIR/t.IMGFMT.base
520
file format: IMGFMT
521
-virtual size: 5.0M (5242880 bytes)
522
+virtual size: 5 MiB (5242880 bytes)
523
524
=== Running QEMU Live Commit Test ===
525
526
@@ -XXX,XX +XXX,XX @@ virtual size: 5.0M (5242880 bytes)
527
=== Base image info after commit and resize ===
528
image: TEST_DIR/t.IMGFMT.base
529
file format: IMGFMT
530
-virtual size: 100M (104857600 bytes)
531
+virtual size: 100 MiB (104857600 bytes)
532
*** done
533
diff --git a/tests/qemu-iotests/104.out b/tests/qemu-iotests/104.out
534
index XXXXXXX..XXXXXXX 100644
535
--- a/tests/qemu-iotests/104.out
536
+++ b/tests/qemu-iotests/104.out
537
@@ -XXX,XX +XXX,XX @@ QA output created by 104
538
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1024
539
image: TEST_DIR/t.IMGFMT
540
file format: IMGFMT
541
-virtual size: 1.0K (1024 bytes)
542
+virtual size: 1 KiB (1024 bytes)
543
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1234
544
image: TEST_DIR/t.IMGFMT
545
file format: IMGFMT
546
-virtual size: 1.5K (1536 bytes)
547
-***done
548
+virtual size: 1.5 KiB (1536 bytes)
549
+*** done
550
diff --git a/tests/qemu-iotests/110.out b/tests/qemu-iotests/110.out
551
index XXXXXXX..XXXXXXX 100644
552
--- a/tests/qemu-iotests/110.out
553
+++ b/tests/qemu-iotests/110.out
554
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
555
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=t.IMGFMT.base
556
image: TEST_DIR/t.IMGFMT
557
file format: IMGFMT
558
-virtual size: 64M (67108864 bytes)
559
+virtual size: 64 MiB (67108864 bytes)
560
backing file: t.IMGFMT.base (actual path: TEST_DIR/t.IMGFMT.base)
561
562
=== Non-reconstructable filename ===
563
564
image: json:{"driver": "IMGFMT", "file": {"set-state.0.event": "read_aio", "image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug", "set-state.0.new_state": 42}}
565
file format: IMGFMT
566
-virtual size: 64M (67108864 bytes)
567
+virtual size: 64 MiB (67108864 bytes)
568
backing file: t.IMGFMT.base (actual path: TEST_DIR/t.IMGFMT.base)
569
570
=== Backing name is always relative to the backed image ===
571
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=t.IMGFMT.b
572
573
image: json:{"driver": "IMGFMT", "file": {"children": [{"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, {"driver": "file", "filename": "TEST_DIR/t.IMGFMT.copy"}], "driver": "quorum", "vote-threshold": 1}}
574
file format: IMGFMT
575
-virtual size: 64M (67108864 bytes)
576
+virtual size: 64 MiB (67108864 bytes)
577
backing file: t.IMGFMT.base (cannot determine actual path)
578
*** done
579
diff --git a/tests/qemu-iotests/114.out b/tests/qemu-iotests/114.out
580
index XXXXXXX..XXXXXXX 100644
581
--- a/tests/qemu-iotests/114.out
582
+++ b/tests/qemu-iotests/114.out
583
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
584
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base
585
image: TEST_DIR/t.IMGFMT
586
file format: IMGFMT
587
-virtual size: 64M (67108864 bytes)
588
+virtual size: 64 MiB (67108864 bytes)
589
cluster_size: 65536
590
backing file: TEST_DIR/t.IMGFMT.base
591
backing file format: foo
592
diff --git a/tests/qemu-iotests/126.out b/tests/qemu-iotests/126.out
593
index XXXXXXX..XXXXXXX 100644
594
--- a/tests/qemu-iotests/126.out
595
+++ b/tests/qemu-iotests/126.out
596
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/image:base.IMGFMT', fmt=IMGFMT size=67108864
597
Formatting 'TEST_DIR/image:top.IMGFMT', fmt=IMGFMT size=67108864 backing_file=./image:base.IMGFMT
598
image: TEST_DIR/image:top.IMGFMT
599
file format: IMGFMT
600
-virtual size: 64M (67108864 bytes)
601
+virtual size: 64 MiB (67108864 bytes)
602
backing file: ./image:base.IMGFMT (actual path: TEST_DIR/./image:base.IMGFMT)
603
604
Formatting 'base.IMGFMT', fmt=IMGFMT size=67108864
605
Formatting 'file:image:top.IMGFMT', fmt=IMGFMT size=67108864 backing_file=base.IMGFMT
606
image: ./image:top.IMGFMT
607
file format: IMGFMT
608
-virtual size: 64M (67108864 bytes)
609
+virtual size: 64 MiB (67108864 bytes)
610
backing file: base.IMGFMT (actual path: ./base.IMGFMT)
611
*** done
612
diff --git a/tests/qemu-iotests/130.out b/tests/qemu-iotests/130.out
613
index XXXXXXX..XXXXXXX 100644
614
--- a/tests/qemu-iotests/130.out
615
+++ b/tests/qemu-iotests/130.out
616
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
617
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
618
image: TEST_DIR/t.IMGFMT
619
file format: IMGFMT
620
-virtual size: 64M (67108864 bytes)
621
+virtual size: 64 MiB (67108864 bytes)
622
623
=== HMP commit ===
624
625
@@ -XXX,XX +XXX,XX @@ QEMU X.Y.Z monitor - type 'help' for more information
626
(qemu)
627
image: TEST_DIR/t.IMGFMT
628
file format: IMGFMT
629
-virtual size: 64M (67108864 bytes)
630
+virtual size: 64 MiB (67108864 bytes)
631
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.orig backing_fmt=raw
632
QEMU X.Y.Z monitor - type 'help' for more information
633
(qemu) commit testdisk
634
(qemu)
635
image: TEST_DIR/t.IMGFMT
636
file format: IMGFMT
637
-virtual size: 64M (67108864 bytes)
638
+virtual size: 64 MiB (67108864 bytes)
639
backing file: TEST_DIR/t.IMGFMT.orig
640
backing file format: raw
641
642
@@ -XXX,XX +XXX,XX @@ wrote 4096/4096 bytes at offset 0
643
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
644
image: TEST_DIR/t.IMGFMT
645
file format: IMGFMT
646
-virtual size: 64M (67108864 bytes)
647
+virtual size: 64 MiB (67108864 bytes)
648
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.orig backing_fmt=raw
649
wrote 4096/4096 bytes at offset 0
650
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
651
image: TEST_DIR/t.IMGFMT
652
file format: IMGFMT
653
-virtual size: 64M (67108864 bytes)
654
+virtual size: 64 MiB (67108864 bytes)
655
backing file: TEST_DIR/t.IMGFMT.orig
656
backing file format: raw
657
*** done
658
diff --git a/tests/qemu-iotests/153.out b/tests/qemu-iotests/153.out
659
index XXXXXXX..XXXXXXX 100644
660
--- a/tests/qemu-iotests/153.out
661
+++ b/tests/qemu-iotests/153.out
662
@@ -XXX,XX +XXX,XX @@ _qemu_io_wrapper TEST_DIR/t.qcow2 -c write 0 512
663
No conflict:
664
image: null-co://
665
file format: null-co
666
-virtual size: 1.0G (1073741824 bytes)
667
+virtual size: 1 GiB (1073741824 bytes)
668
disk size: unavailable
669
670
Conflict:
671
diff --git a/tests/qemu-iotests/191.out b/tests/qemu-iotests/191.out
672
index XXXXXXX..XXXXXXX 100644
673
--- a/tests/qemu-iotests/191.out
674
+++ b/tests/qemu-iotests/191.out
675
@@ -XXX,XX +XXX,XX @@ wrote 65536/65536 bytes at offset 1048576
676
}
86
}
677
image: TEST_DIR/t.IMGFMT
87
678
file format: IMGFMT
88
-/*
679
-virtual size: 64M (67108864 bytes)
89
- * Checks whether a new reference to @bs can be added if the new user requires
680
+virtual size: 64 MiB (67108864 bytes)
90
- * @new_used_perm/@new_shared_perm as its permissions. If @ignore_children is
681
cluster_size: 65536
91
- * set, the BdrvChild objects in this list are ignored in the calculations;
682
backing file: TEST_DIR/t.IMGFMT.base
92
- * this allows checking permission updates for an existing reference.
683
backing file format: IMGFMT
93
- *
684
image: TEST_DIR/t.IMGFMT.ovl2
94
- * Needs to be followed by a call to either bdrv_set_perm() or
685
file format: IMGFMT
95
- * bdrv_abort_perm_update(). */
686
-virtual size: 64M (67108864 bytes)
96
-__attribute__((unused))
687
+virtual size: 64 MiB (67108864 bytes)
97
-static int bdrv_check_update_perm(BlockDriverState *bs, BlockReopenQueue *q,
688
cluster_size: 65536
98
- uint64_t new_used_perm,
689
backing file: TEST_DIR/t.IMGFMT.base
99
- uint64_t new_shared_perm,
690
backing file format: IMGFMT
100
- Error **errp)
691
@@ -XXX,XX +XXX,XX @@ wrote 65536/65536 bytes at offset 1048576
101
-{
692
}
102
- BdrvChild *c;
693
image: TEST_DIR/t.IMGFMT
103
- uint64_t cumulative_perms = new_used_perm;
694
file format: IMGFMT
104
- uint64_t cumulative_shared_perms = new_shared_perm;
695
-virtual size: 64M (67108864 bytes)
105
-
696
+virtual size: 64 MiB (67108864 bytes)
106
-
697
cluster_size: 65536
107
- /* There is no reason why anyone couldn't tolerate write_unchanged */
698
backing file: TEST_DIR/t.IMGFMT.base
108
- assert(new_shared_perm & BLK_PERM_WRITE_UNCHANGED);
699
backing file format: IMGFMT
109
-
700
image: TEST_DIR/t.IMGFMT.ovl2
110
- QLIST_FOREACH(c, &bs->parents, next_parent) {
701
file format: IMGFMT
111
- if ((new_used_perm & c->shared_perm) != new_used_perm) {
702
-virtual size: 64M (67108864 bytes)
112
- char *user = bdrv_child_user_desc(c);
703
+virtual size: 64 MiB (67108864 bytes)
113
- char *perm_names = bdrv_perm_names(new_used_perm & ~c->shared_perm);
704
cluster_size: 65536
114
-
705
backing file: TEST_DIR/t.IMGFMT.base
115
- error_setg(errp, "Conflicts with use by %s as '%s', which does not "
706
backing file format: IMGFMT
116
- "allow '%s' on %s",
707
diff --git a/tests/qemu-iotests/195.out b/tests/qemu-iotests/195.out
117
- user, c->name, perm_names, bdrv_get_node_name(c->bs));
708
index XXXXXXX..XXXXXXX 100644
118
- g_free(user);
709
--- a/tests/qemu-iotests/195.out
119
- g_free(perm_names);
710
+++ b/tests/qemu-iotests/195.out
120
- return -EPERM;
711
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,backing.node-name=mid
121
- }
712
122
-
713
image: TEST_DIR/t.IMGFMT.mid
123
- if ((c->perm & new_shared_perm) != c->perm) {
714
file format: IMGFMT
124
- char *user = bdrv_child_user_desc(c);
715
-virtual size: 64M (67108864 bytes)
125
- char *perm_names = bdrv_perm_names(c->perm & ~new_shared_perm);
716
+virtual size: 64 MiB (67108864 bytes)
126
-
717
cluster_size: 65536
127
- error_setg(errp, "Conflicts with use by %s as '%s', which uses "
718
backing file: /dev/null
128
- "'%s' on %s",
719
backing file format: IMGFMT
129
- user, c->name, perm_names, bdrv_get_node_name(c->bs));
720
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,node-name=top
130
- g_free(user);
721
131
- g_free(perm_names);
722
image: TEST_DIR/t.IMGFMT
132
- return -EPERM;
723
file format: IMGFMT
133
- }
724
-virtual size: 64M (67108864 bytes)
134
-
725
+virtual size: 64 MiB (67108864 bytes)
135
- cumulative_perms |= c->perm;
726
cluster_size: 65536
136
- cumulative_shared_perms &= c->shared_perm;
727
backing file: /dev/null
137
- }
728
backing file format: IMGFMT
138
-
729
diff --git a/tests/qemu-iotests/198.out b/tests/qemu-iotests/198.out
139
- return bdrv_check_perm(bs, q, cumulative_perms, cumulative_shared_perms,
730
index XXXXXXX..XXXXXXX 100644
140
- errp);
731
--- a/tests/qemu-iotests/198.out
141
-}
732
+++ b/tests/qemu-iotests/198.out
142
733
@@ -XXX,XX +XXX,XX @@ read 16777216/16777216 bytes at offset 0
143
static int bdrv_refresh_perms(BlockDriverState *bs, Error **errp)
734
== checking image base ==
144
{
735
image: json:{"encrypt.key-secret": "sec0", "driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT.base"}}
736
file format: IMGFMT
737
-virtual size: 16M (16777216 bytes)
738
+virtual size: 16 MiB (16777216 bytes)
739
Format specific information:
740
encrypt:
741
ivgen alg: plain64
742
@@ -XXX,XX +XXX,XX @@ Format specific information:
743
== checking image layer ==
744
image: json:{"encrypt.key-secret": "sec1", "driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}}
745
file format: IMGFMT
746
-virtual size: 16M (16777216 bytes)
747
+virtual size: 16 MiB (16777216 bytes)
748
backing file: TEST_DIR/t.IMGFMT.base
749
Format specific information:
750
encrypt:
751
diff --git a/tests/qemu-iotests/206.out b/tests/qemu-iotests/206.out
752
index XXXXXXX..XXXXXXX 100644
753
--- a/tests/qemu-iotests/206.out
754
+++ b/tests/qemu-iotests/206.out
755
@@ -XXX,XX +XXX,XX @@
756
757
image: TEST_IMG
758
file format: IMGFMT
759
-virtual size: 128M (134217728 bytes)
760
+virtual size: 128 MiB (134217728 bytes)
761
cluster_size: 65536
762
Format specific information:
763
compat: 1.1
764
@@ -XXX,XX +XXX,XX @@ Format specific information:
765
766
image: TEST_IMG
767
file format: IMGFMT
768
-virtual size: 64M (67108864 bytes)
769
+virtual size: 64 MiB (67108864 bytes)
770
cluster_size: 65536
771
Format specific information:
772
compat: 1.1
773
@@ -XXX,XX +XXX,XX @@ Format specific information:
774
775
image: TEST_IMG
776
file format: IMGFMT
777
-virtual size: 32M (33554432 bytes)
778
+virtual size: 32 MiB (33554432 bytes)
779
cluster_size: 2097152
780
Format specific information:
781
compat: 1.1
782
@@ -XXX,XX +XXX,XX @@ Format specific information:
783
784
image: TEST_IMG
785
file format: IMGFMT
786
-virtual size: 32M (33554432 bytes)
787
+virtual size: 32 MiB (33554432 bytes)
788
cluster_size: 512
789
backing file: TEST_IMG.base
790
backing file format: IMGFMT
791
@@ -XXX,XX +XXX,XX @@ Format specific information:
792
793
image: TEST_IMG
794
file format: IMGFMT
795
-virtual size: 32M (33554432 bytes)
796
+virtual size: 32 MiB (33554432 bytes)
797
encrypted: yes
798
cluster_size: 65536
799
Format specific information:
800
diff --git a/tests/qemu-iotests/207.out b/tests/qemu-iotests/207.out
801
index XXXXXXX..XXXXXXX 100644
802
--- a/tests/qemu-iotests/207.out
803
+++ b/tests/qemu-iotests/207.out
804
@@ -XXX,XX +XXX,XX @@
805
806
image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}}
807
file format: IMGFMT
808
-virtual size: 4.0M (4194304 bytes)
809
+virtual size: 4 MiB (4194304 bytes)
810
811
812
image: TEST_IMG
813
file format: IMGFMT
814
-virtual size: 4.0M (4194304 bytes)
815
+virtual size: 4 MiB (4194304 bytes)
816
817
=== Test host-key-check options ===
818
819
@@ -XXX,XX +XXX,XX @@ virtual size: 4.0M (4194304 bytes)
820
821
image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}}
822
file format: IMGFMT
823
-virtual size: 8.0M (8388608 bytes)
824
+virtual size: 8 MiB (8388608 bytes)
825
826
{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "ssh", "location": {"host-key-check": {"mode": "known_hosts"}, "path": "TEST_DIR/PID-t.img", "server": {"host": "127.0.0.1", "port": "22"}}, "size": 4194304}}}
827
{"return": {}}
828
@@ -XXX,XX +XXX,XX @@ virtual size: 8.0M (8388608 bytes)
829
830
image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}}
831
file format: IMGFMT
832
-virtual size: 4.0M (4194304 bytes)
833
+virtual size: 4 MiB (4194304 bytes)
834
835
{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "ssh", "location": {"host-key-check": {"hash": "wrong", "mode": "hash", "type": "md5"}, "path": "TEST_DIR/PID-t.img", "server": {"host": "127.0.0.1", "port": "22"}}, "size": 2097152}}}
836
{"return": {}}
837
@@ -XXX,XX +XXX,XX @@ Job failed: remote host key does not match host_key_check 'wrong'
838
839
image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}}
840
file format: IMGFMT
841
-virtual size: 8.0M (8388608 bytes)
842
+virtual size: 8 MiB (8388608 bytes)
843
844
{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "ssh", "location": {"host-key-check": {"hash": "wrong", "mode": "hash", "type": "sha1"}, "path": "TEST_DIR/PID-t.img", "server": {"host": "127.0.0.1", "port": "22"}}, "size": 2097152}}}
845
{"return": {}}
846
@@ -XXX,XX +XXX,XX @@ Job failed: remote host key does not match host_key_check 'wrong'
847
848
image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}}
849
file format: IMGFMT
850
-virtual size: 4.0M (4194304 bytes)
851
+virtual size: 4 MiB (4194304 bytes)
852
853
=== Invalid path and user ===
854
855
diff --git a/tests/qemu-iotests/210.out b/tests/qemu-iotests/210.out
856
index XXXXXXX..XXXXXXX 100644
857
--- a/tests/qemu-iotests/210.out
858
+++ b/tests/qemu-iotests/210.out
859
@@ -XXX,XX +XXX,XX @@
860
861
image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_IMG"}, "key-secret": "keysec0"}
862
file format: IMGFMT
863
-virtual size: 128M (134217728 bytes)
864
+virtual size: 128 MiB (134217728 bytes)
865
encrypted: yes
866
Format specific information:
867
ivgen alg: plain64
868
@@ -XXX,XX +XXX,XX @@ Format specific information:
869
870
image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_IMG"}, "key-secret": "keysec0"}
871
file format: IMGFMT
872
-virtual size: 64M (67108864 bytes)
873
+virtual size: 64 MiB (67108864 bytes)
874
encrypted: yes
875
Format specific information:
876
ivgen alg: plain64
877
@@ -XXX,XX +XXX,XX @@ Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exi
878
879
image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_IMG"}, "key-secret": "keysec0"}
880
file format: IMGFMT
881
-virtual size: 0 (0 bytes)
882
+virtual size: 0 B (0 bytes)
883
encrypted: yes
884
Format specific information:
885
ivgen alg: plain64
886
@@ -XXX,XX +XXX,XX @@ Job failed: The requested file size is too large
887
{"error": {"class": "GenericError", "desc": "Parameter 'size' expects a >0 size"}}
888
image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_IMG"}, "key-secret": "keysec0"}
889
file format: IMGFMT
890
-virtual size: 0 (0 bytes)
891
+virtual size: 0 B (0 bytes)
892
encrypted: yes
893
Format specific information:
894
ivgen alg: plain64
895
diff --git a/tests/qemu-iotests/211.out b/tests/qemu-iotests/211.out
896
index XXXXXXX..XXXXXXX 100644
897
--- a/tests/qemu-iotests/211.out
898
+++ b/tests/qemu-iotests/211.out
899
@@ -XXX,XX +XXX,XX @@
900
901
image: TEST_IMG
902
file format: IMGFMT
903
-virtual size: 128M (134217728 bytes)
904
+virtual size: 128 MiB (134217728 bytes)
905
cluster_size: 1048576
906
907
[{ "start": 0, "length": 134217728, "depth": 0, "zero": true, "data": false}]
908
@@ -XXX,XX +XXX,XX @@ cluster_size: 1048576
909
910
image: TEST_IMG
911
file format: IMGFMT
912
-virtual size: 64M (67108864 bytes)
913
+virtual size: 64 MiB (67108864 bytes)
914
cluster_size: 1048576
915
916
[{ "start": 0, "length": 67108864, "depth": 0, "zero": true, "data": false}]
917
@@ -XXX,XX +XXX,XX @@ cluster_size: 1048576
918
919
image: TEST_IMG
920
file format: IMGFMT
921
-virtual size: 32M (33554432 bytes)
922
+virtual size: 32 MiB (33554432 bytes)
923
cluster_size: 1048576
924
925
[{ "start": 0, "length": 3072, "depth": 0, "zero": false, "data": true, "offset": 1024},
926
@@ -XXX,XX +XXX,XX @@ Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exi
927
928
image: TEST_IMG
929
file format: IMGFMT
930
-virtual size: 0 (0 bytes)
931
+virtual size: 0 B (0 bytes)
932
cluster_size: 1048576
933
934
=== Maximum size ===
935
@@ -XXX,XX +XXX,XX @@ cluster_size: 1048576
936
937
image: TEST_IMG
938
file format: IMGFMT
939
-virtual size: 512T (562949819203584 bytes)
940
+virtual size: 512 TiB (562949819203584 bytes)
941
cluster_size: 1048576
942
943
=== Invalid sizes ===
944
diff --git a/tests/qemu-iotests/212.out b/tests/qemu-iotests/212.out
945
index XXXXXXX..XXXXXXX 100644
946
--- a/tests/qemu-iotests/212.out
947
+++ b/tests/qemu-iotests/212.out
948
@@ -XXX,XX +XXX,XX @@
949
950
image: TEST_IMG
951
file format: IMGFMT
952
-virtual size: 128M (134217728 bytes)
953
+virtual size: 128 MiB (134217728 bytes)
954
955
=== Successful image creation (explicit defaults) ===
956
957
@@ -XXX,XX +XXX,XX @@ virtual size: 128M (134217728 bytes)
958
959
image: TEST_IMG
960
file format: IMGFMT
961
-virtual size: 64M (67108864 bytes)
962
+virtual size: 64 MiB (67108864 bytes)
963
964
=== Successful image creation (with non-default options) ===
965
966
@@ -XXX,XX +XXX,XX @@ virtual size: 64M (67108864 bytes)
967
968
image: TEST_IMG
969
file format: IMGFMT
970
-virtual size: 32M (33554432 bytes)
971
+virtual size: 32 MiB (33554432 bytes)
972
973
=== Invalid BlockdevRef ===
974
975
@@ -XXX,XX +XXX,XX @@ Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exi
976
977
image: TEST_IMG
978
file format: IMGFMT
979
-virtual size: 0 (0 bytes)
980
+virtual size: 0 B (0 bytes)
981
982
=== Maximum size ===
983
984
@@ -XXX,XX +XXX,XX @@ virtual size: 0 (0 bytes)
985
986
image: TEST_IMG
987
file format: IMGFMT
988
-virtual size: 4096T (4503599627369984 bytes)
989
+virtual size: 4 PiB (4503599627369984 bytes)
990
991
=== Invalid sizes ===
992
993
diff --git a/tests/qemu-iotests/213.out b/tests/qemu-iotests/213.out
994
index XXXXXXX..XXXXXXX 100644
995
--- a/tests/qemu-iotests/213.out
996
+++ b/tests/qemu-iotests/213.out
997
@@ -XXX,XX +XXX,XX @@
998
999
image: TEST_IMG
1000
file format: IMGFMT
1001
-virtual size: 128M (134217728 bytes)
1002
+virtual size: 128 MiB (134217728 bytes)
1003
cluster_size: 8388608
1004
1005
=== Successful image creation (explicit defaults) ===
1006
@@ -XXX,XX +XXX,XX @@ cluster_size: 8388608
1007
1008
image: TEST_IMG
1009
file format: IMGFMT
1010
-virtual size: 64M (67108864 bytes)
1011
+virtual size: 64 MiB (67108864 bytes)
1012
cluster_size: 8388608
1013
1014
=== Successful image creation (with non-default options) ===
1015
@@ -XXX,XX +XXX,XX @@ cluster_size: 8388608
1016
1017
image: TEST_IMG
1018
file format: IMGFMT
1019
-virtual size: 32M (33554432 bytes)
1020
+virtual size: 32 MiB (33554432 bytes)
1021
cluster_size: 268435456
1022
1023
=== Invalid BlockdevRef ===
1024
@@ -XXX,XX +XXX,XX @@ Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exi
1025
1026
image: TEST_IMG
1027
file format: IMGFMT
1028
-virtual size: 0 (0 bytes)
1029
+virtual size: 0 B (0 bytes)
1030
cluster_size: 8388608
1031
1032
=== Maximum size ===
1033
@@ -XXX,XX +XXX,XX @@ cluster_size: 8388608
1034
1035
image: TEST_IMG
1036
file format: IMGFMT
1037
-virtual size: 64T (70368744177664 bytes)
1038
+virtual size: 64 TiB (70368744177664 bytes)
1039
cluster_size: 67108864
1040
1041
=== Invalid sizes ===
1042
diff --git a/tests/qemu-iotests/233.out b/tests/qemu-iotests/233.out
1043
index XXXXXXX..XXXXXXX 100644
1044
--- a/tests/qemu-iotests/233.out
1045
+++ b/tests/qemu-iotests/233.out
1046
@@ -XXX,XX +XXX,XX @@ server reported: Option 0x8 not permitted before TLS
1047
== check TLS works ==
1048
image: nbd://127.0.0.1:PORT
1049
file format: nbd
1050
-virtual size: 64M (67108864 bytes)
1051
+virtual size: 64 MiB (67108864 bytes)
1052
disk size: unavailable
1053
image: nbd://127.0.0.1:PORT
1054
file format: nbd
1055
-virtual size: 64M (67108864 bytes)
1056
+virtual size: 64 MiB (67108864 bytes)
1057
disk size: unavailable
1058
exports available: 1
1059
export: ''
1060
diff --git a/tests/qemu-iotests/237.out b/tests/qemu-iotests/237.out
1061
index XXXXXXX..XXXXXXX 100644
1062
--- a/tests/qemu-iotests/237.out
1063
+++ b/tests/qemu-iotests/237.out
1064
@@ -XXX,XX +XXX,XX @@
1065
1066
image: TEST_IMG
1067
file format: IMGFMT
1068
-virtual size: 5.0G (5368709120 bytes)
1069
+virtual size: 5 GiB (5368709120 bytes)
1070
cluster_size: 65536
1071
Format specific information:
1072
cid: XXXXXXXXXX
1073
@@ -XXX,XX +XXX,XX @@ Format specific information:
1074
1075
image: TEST_IMG
1076
file format: IMGFMT
1077
-virtual size: 64M (67108864 bytes)
1078
+virtual size: 64 MiB (67108864 bytes)
1079
cluster_size: 65536
1080
Format specific information:
1081
cid: XXXXXXXXXX
1082
@@ -XXX,XX +XXX,XX @@ Format specific information:
1083
1084
image: TEST_IMG
1085
file format: IMGFMT
1086
-virtual size: 32M (33554432 bytes)
1087
+virtual size: 32 MiB (33554432 bytes)
1088
cluster_size: 65536
1089
Format specific information:
1090
cid: XXXXXXXXXX
1091
@@ -XXX,XX +XXX,XX @@ Job failed: List of extents contains unused extents
1092
1093
image: TEST_IMG
1094
file format: IMGFMT
1095
-virtual size: 512 (512 bytes)
1096
+virtual size: 512 B (512 bytes)
1097
Format specific information:
1098
cid: XXXXXXXXXX
1099
parent cid: XXXXXXXXXX
1100
@@ -XXX,XX +XXX,XX @@ Format specific information:
1101
1102
image: TEST_IMG
1103
file format: IMGFMT
1104
-virtual size: 512 (512 bytes)
1105
+virtual size: 512 B (512 bytes)
1106
cluster_size: 65536
1107
Format specific information:
1108
cid: XXXXXXXXXX
1109
@@ -XXX,XX +XXX,XX @@ Format specific information:
1110
1111
image: TEST_IMG
1112
file format: IMGFMT
1113
-virtual size: 1.0G (1073741824 bytes)
1114
+virtual size: 1 GiB (1073741824 bytes)
1115
Format specific information:
1116
cid: XXXXXXXXXX
1117
parent cid: XXXXXXXXXX
1118
@@ -XXX,XX +XXX,XX @@ Format specific information:
1119
1120
image: TEST_IMG
1121
file format: IMGFMT
1122
-virtual size: 1.0G (1073741824 bytes)
1123
+virtual size: 1 GiB (1073741824 bytes)
1124
cluster_size: 65536
1125
Format specific information:
1126
cid: XXXXXXXXXX
1127
@@ -XXX,XX +XXX,XX @@ Format specific information:
1128
1129
image: TEST_IMG
1130
file format: IMGFMT
1131
-virtual size: 2.0G (2147483648 bytes)
1132
+virtual size: 2 GiB (2147483648 bytes)
1133
Format specific information:
1134
cid: XXXXXXXXXX
1135
parent cid: XXXXXXXXXX
1136
@@ -XXX,XX +XXX,XX @@ Format specific information:
1137
1138
image: TEST_IMG
1139
file format: IMGFMT
1140
-virtual size: 2.0G (2147483648 bytes)
1141
+virtual size: 2 GiB (2147483648 bytes)
1142
cluster_size: 65536
1143
Format specific information:
1144
cid: XXXXXXXXXX
1145
@@ -XXX,XX +XXX,XX @@ Format specific information:
1146
1147
image: TEST_IMG
1148
file format: IMGFMT
1149
-virtual size: 5.0G (5368709120 bytes)
1150
+virtual size: 5 GiB (5368709120 bytes)
1151
Format specific information:
1152
cid: XXXXXXXXXX
1153
parent cid: XXXXXXXXXX
1154
@@ -XXX,XX +XXX,XX @@ Format specific information:
1155
1156
image: TEST_IMG
1157
file format: IMGFMT
1158
-virtual size: 5.0G (5368709120 bytes)
1159
+virtual size: 5 GiB (5368709120 bytes)
1160
cluster_size: 65536
1161
Format specific information:
1162
cid: XXXXXXXXXX
1163
diff --git a/tests/qemu-iotests/242.out b/tests/qemu-iotests/242.out
1164
index XXXXXXX..XXXXXXX 100644
1165
--- a/tests/qemu-iotests/242.out
1166
+++ b/tests/qemu-iotests/242.out
1167
@@ -XXX,XX +XXX,XX @@ qemu-img info dump:
1168
1169
image: TEST_IMG
1170
file format: IMGFMT
1171
-virtual size: 1.0M (1048576 bytes)
1172
+virtual size: 1 MiB (1048576 bytes)
1173
cluster_size: 65536
1174
Format specific information:
1175
compat: 1.1
1176
@@ -XXX,XX +XXX,XX @@ qemu-img info dump:
1177
1178
image: TEST_IMG
1179
file format: IMGFMT
1180
-virtual size: 1.0M (1048576 bytes)
1181
+virtual size: 1 MiB (1048576 bytes)
1182
cluster_size: 65536
1183
Format specific information:
1184
compat: 1.1
1185
@@ -XXX,XX +XXX,XX @@ qemu-img info dump:
1186
1187
image: TEST_IMG
1188
file format: IMGFMT
1189
-virtual size: 1.0M (1048576 bytes)
1190
+virtual size: 1 MiB (1048576 bytes)
1191
cluster_size: 65536
1192
Format specific information:
1193
compat: 1.1
1194
@@ -XXX,XX +XXX,XX @@ qemu-img info dump:
1195
1196
image: TEST_IMG
1197
file format: IMGFMT
1198
-virtual size: 1.0M (1048576 bytes)
1199
+virtual size: 1 MiB (1048576 bytes)
1200
cluster_size: 65536
1201
Format specific information:
1202
compat: 1.1
1203
@@ -XXX,XX +XXX,XX @@ Unset the unknown bitmap flag '0x4' in the bitmap directory entry:
1204
1205
image: TEST_IMG
1206
file format: IMGFMT
1207
-virtual size: 1.0M (1048576 bytes)
1208
+virtual size: 1 MiB (1048576 bytes)
1209
cluster_size: 65536
1210
Format specific information:
1211
compat: 1.1
1212
--
145
--
1213
2.20.1
146
2.30.2
1214
147
1215
148
diff view generated by jsdifflib
1
From: Stefano Garzarella <sgarzare@redhat.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
Using IEC binary prefixes in order to make the code more readable,
3
bdrv_check_perm_common() has only one caller, so no more sense in
4
with the exception of DEFAULT_LOG_SIZE because it's passed to
4
"common".
5
stringify().
6
5
7
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Reviewed-by: John Snow <jsnow@redhat.com>
8
Message-Id: <20210428151804.439460-33-vsementsov@virtuozzo.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
10
---
12
block/vhdx.h | 10 ++++++----
11
block.c | 32 +++-----------------------------
13
block/vhdx-log.c | 2 +-
12
1 file changed, 3 insertions(+), 29 deletions(-)
14
block/vhdx.c | 4 ++--
15
3 files changed, 9 insertions(+), 7 deletions(-)
16
13
17
diff --git a/block/vhdx.h b/block/vhdx.h
14
diff --git a/block.c b/block.c
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/block/vhdx.h
16
--- a/block.c
20
+++ b/block/vhdx.h
17
+++ b/block.c
21
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static int bdrv_node_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
22
#include "qemu/units.h"
19
return 0;
23
20
}
24
#define DEFAULT_LOG_SIZE 1048576 /* 1MiB */
21
25
+/* Note: can't use 1 * MiB, because it's passed to stringify() */
22
-/*
26
+
23
- * If use_cumulative_perms is true, use cumulative_perms and
27
/* Structures and fields present in the VHDX file */
24
- * cumulative_shared_perms for first element of the list. Otherwise just refresh
28
25
- * all permissions.
29
/* The header section has the following blocks,
26
- */
30
@@ -XXX,XX +XXX,XX @@
27
-static int bdrv_check_perm_common(GSList *list, BlockReopenQueue *q,
31
* 0.........64KB...........128KB........192KB..........256KB................1MB
28
- bool use_cumulative_perms,
32
*/
29
- uint64_t cumulative_perms,
33
30
- uint64_t cumulative_shared_perms,
34
-#define VHDX_HEADER_BLOCK_SIZE (64 * 1024)
31
- Transaction *tran, Error **errp)
35
+#define VHDX_HEADER_BLOCK_SIZE (64 * KiB)
32
+static int bdrv_list_refresh_perms(GSList *list, BlockReopenQueue *q,
36
33
+ Transaction *tran, Error **errp)
37
#define VHDX_FILE_ID_OFFSET 0
34
{
38
#define VHDX_HEADER1_OFFSET (VHDX_HEADER_BLOCK_SIZE * 1)
35
int ret;
39
@@ -XXX,XX +XXX,XX @@ typedef struct QEMU_PACKED MSGUID {
36
+ uint64_t cumulative_perms, cumulative_shared_perms;
40
#define guid_eq(a, b) \
37
BlockDriverState *bs;
41
(memcmp(&(a), &(b), sizeof(MSGUID)) == 0)
38
42
39
- if (use_cumulative_perms) {
43
-#define VHDX_HEADER_SIZE (4 * 1024) /* although the vhdx_header struct in disk
40
- bs = list->data;
44
+#define VHDX_HEADER_SIZE (4 * KiB) /* although the vhdx_header struct in disk
41
-
45
is only 582 bytes, for purposes of crc
42
- ret = bdrv_node_check_perm(bs, q, cumulative_perms,
46
the header is the first 4KB of the 64KB
43
- cumulative_shared_perms,
47
block */
44
- tran, errp);
48
@@ -XXX,XX +XXX,XX @@ typedef struct QEMU_PACKED VHDXRegionTableEntry {
45
- if (ret < 0) {
49
46
- return ret;
50
47
- }
51
/* ---- LOG ENTRY STRUCTURES ---- */
48
-
52
-#define VHDX_LOG_MIN_SIZE (1024 * 1024)
49
- list = list->next;
53
-#define VHDX_LOG_SECTOR_SIZE 4096
50
- }
54
+#define VHDX_LOG_MIN_SIZE (1 * MiB)
51
-
55
+#define VHDX_LOG_SECTOR_SIZE (4 * KiB)
52
for ( ; list; list = list->next) {
56
#define VHDX_LOG_HDR_SIZE 64
53
bs = list->data;
57
#define VHDX_LOG_SIGNATURE 0x65676f6c
54
58
typedef struct QEMU_PACKED VHDXLogEntryHeader {
55
@@ -XXX,XX +XXX,XX @@ static int bdrv_check_perm_common(GSList *list, BlockReopenQueue *q,
59
diff --git a/block/vhdx-log.c b/block/vhdx-log.c
56
return 0;
60
index XXXXXXX..XXXXXXX 100644
57
}
61
--- a/block/vhdx-log.c
58
62
+++ b/block/vhdx-log.c
59
-static int bdrv_list_refresh_perms(GSList *list, BlockReopenQueue *q,
63
@@ -XXX,XX +XXX,XX @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s,
60
- Transaction *tran, Error **errp)
64
}
61
-{
65
if (file_length < desc_entries->hdr.last_file_offset) {
62
- return bdrv_check_perm_common(list, q, false, 0, 0, tran, errp);
66
new_file_size = desc_entries->hdr.last_file_offset;
63
-}
67
- if (new_file_size % (1024*1024)) {
64
-
68
+ if (new_file_size % (1 * MiB)) {
65
static void bdrv_node_set_perm(BlockDriverState *bs)
69
/* round up to nearest 1MB boundary */
66
{
70
new_file_size = QEMU_ALIGN_UP(new_file_size, MiB);
67
BlockDriver *drv = bs->drv;
71
if (new_file_size > INT64_MAX) {
72
diff --git a/block/vhdx.c b/block/vhdx.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/block/vhdx.c
75
+++ b/block/vhdx.c
76
@@ -XXX,XX +XXX,XX @@ static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s,
77
*new_offset = current_len;
78
79
/* per the spec, the address for a block is in units of 1MB */
80
- *new_offset = ROUND_UP(*new_offset, 1024 * 1024);
81
+ *new_offset = ROUND_UP(*new_offset, 1 * MiB);
82
if (*new_offset > INT64_MAX) {
83
return -EINVAL;
84
}
85
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int vhdx_co_writev(BlockDriverState *bs, int64_t sector_num,
86
case PAYLOAD_BLOCK_FULLY_PRESENT:
87
/* if the file offset address is in the header zone,
88
* there is a problem */
89
- if (sinfo.file_offset < (1024 * 1024)) {
90
+ if (sinfo.file_offset < (1 * MiB)) {
91
ret = -EFAULT;
92
goto error_bat_restore;
93
}
94
--
68
--
95
2.20.1
69
2.30.2
96
70
97
71
diff view generated by jsdifflib
1
Even for block nodes with bs->drv == NULL, we can't just ignore a
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
bdrv_set_aio_context() call. Leaving the node in its old context can
3
mean that it's still in an iothread context in bdrv_close_all() during
4
shutdown, resulting in an attempted unlock of the AioContext lock which
5
we don't hold.
6
2
7
This is an example stack trace of a related crash:
3
bdrv_replace_child() has only one caller, the second argument is
4
unused. Inline it now. This triggers deletion of some more unused
5
interfaces.
8
6
9
#0 0x00007ffff59da57f in raise () at /lib64/libc.so.6
7
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
#1 0x00007ffff59c4895 in abort () at /lib64/libc.so.6
8
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
11
#2 0x0000555555b97b1e in error_exit (err=<optimized out>, msg=msg@entry=0x555555d386d0 <__func__.19059> "qemu_mutex_unlock_impl") at util/qemu-thread-posix.c:36
9
Message-Id: <20210428151804.439460-34-vsementsov@virtuozzo.com>
12
#3 0x0000555555b97f7f in qemu_mutex_unlock_impl (mutex=mutex@entry=0x5555568002f0, file=file@entry=0x555555d378df "util/async.c", line=line@entry=507) at util/qemu-thread-posix.c:97
13
#4 0x0000555555b92f55 in aio_context_release (ctx=ctx@entry=0x555556800290) at util/async.c:507
14
#5 0x0000555555b05cf8 in bdrv_prwv_co (child=child@entry=0x7fffc80012f0, offset=offset@entry=131072, qiov=qiov@entry=0x7fffffffd4f0, is_write=is_write@entry=true, flags=flags@entry=0)
15
at block/io.c:833
16
#6 0x0000555555b060a9 in bdrv_pwritev (qiov=0x7fffffffd4f0, offset=131072, child=0x7fffc80012f0) at block/io.c:990
17
#7 0x0000555555b060a9 in bdrv_pwrite (child=0x7fffc80012f0, offset=131072, buf=<optimized out>, bytes=<optimized out>) at block/io.c:990
18
#8 0x0000555555ae172b in qcow2_cache_entry_flush (bs=bs@entry=0x555556810680, c=c@entry=0x5555568cc740, i=i@entry=0) at block/qcow2-cache.c:51
19
#9 0x0000555555ae18dd in qcow2_cache_write (bs=bs@entry=0x555556810680, c=0x5555568cc740) at block/qcow2-cache.c:248
20
#10 0x0000555555ae15de in qcow2_cache_flush (bs=0x555556810680, c=<optimized out>) at block/qcow2-cache.c:259
21
#11 0x0000555555ae16b1 in qcow2_cache_flush_dependency (c=0x5555568a1700, c=0x5555568a1700, bs=0x555556810680) at block/qcow2-cache.c:194
22
#12 0x0000555555ae16b1 in qcow2_cache_entry_flush (bs=bs@entry=0x555556810680, c=c@entry=0x5555568a1700, i=i@entry=0) at block/qcow2-cache.c:194
23
#13 0x0000555555ae18dd in qcow2_cache_write (bs=bs@entry=0x555556810680, c=0x5555568a1700) at block/qcow2-cache.c:248
24
#14 0x0000555555ae15de in qcow2_cache_flush (bs=bs@entry=0x555556810680, c=<optimized out>) at block/qcow2-cache.c:259
25
#15 0x0000555555ad242c in qcow2_inactivate (bs=bs@entry=0x555556810680) at block/qcow2.c:2124
26
#16 0x0000555555ad2590 in qcow2_close (bs=0x555556810680) at block/qcow2.c:2153
27
#17 0x0000555555ab0c62 in bdrv_close (bs=0x555556810680) at block.c:3358
28
#18 0x0000555555ab0c62 in bdrv_delete (bs=0x555556810680) at block.c:3542
29
#19 0x0000555555ab0c62 in bdrv_unref (bs=0x555556810680) at block.c:4598
30
#20 0x0000555555af4d72 in blk_remove_bs (blk=blk@entry=0x5555568103d0) at block/block-backend.c:785
31
#21 0x0000555555af4dbb in blk_remove_all_bs () at block/block-backend.c:483
32
#22 0x0000555555aae02f in bdrv_close_all () at block.c:3412
33
#23 0x00005555557f9796 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at vl.c:4776
34
35
The reproducer I used is a qcow2 image on gluster volume, where the
36
virtual disk size (4 GB) is larger than the gluster volume size (64M),
37
so we can easily trigger an ENOSPC. This backend is assigned to a
38
virtio-blk device using an iothread, and then from the guest a
39
'dd if=/dev/zero of=/dev/vda bs=1G count=1' causes the VM to stop
40
because of an I/O error. qemu_gluster_co_flush_to_disk() sets
41
bs->drv = NULL on error, so when virtio-blk stops the dataplane, the
42
block nodes stay in the iothread AioContext. A 'quit' monitor command
43
issued from this paused state crashes the process.
44
45
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1631227
46
Cc: qemu-stable@nongnu.org
47
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
48
Reviewed-by: Eric Blake <eblake@redhat.com>
49
Reviewed-by: Max Reitz <mreitz@redhat.com>
50
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
51
---
11
---
52
block.c | 12 ++----------
12
block.c | 101 ++++++++++----------------------------------------------
53
1 file changed, 2 insertions(+), 10 deletions(-)
13
1 file changed, 18 insertions(+), 83 deletions(-)
54
14
55
diff --git a/block.c b/block.c
15
diff --git a/block.c b/block.c
56
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
57
--- a/block.c
17
--- a/block.c
58
+++ b/block.c
18
+++ b/block.c
59
@@ -XXX,XX +XXX,XX @@ void bdrv_detach_aio_context(BlockDriverState *bs)
19
@@ -XXX,XX +XXX,XX @@ static int bdrv_list_refresh_perms(GSList *list, BlockReopenQueue *q,
60
BdrvAioNotifier *baf, *baf_tmp;
20
return 0;
61
BdrvChild *child;
21
}
62
22
63
- if (!bs->drv) {
23
-static void bdrv_node_set_perm(BlockDriverState *bs)
24
-{
25
- BlockDriver *drv = bs->drv;
26
- BdrvChild *c;
27
-
28
- if (!drv) {
64
- return;
29
- return;
65
- }
30
- }
66
-
31
-
67
assert(!bs->walking_aio_notifiers);
32
- bdrv_drv_set_perm_commit(bs);
68
bs->walking_aio_notifiers = true;
33
-
69
QLIST_FOREACH_SAFE(baf, &bs->aio_notifiers, list, baf_tmp) {
34
- /* Drivers that never have children can omit .bdrv_child_perm() */
70
@@ -XXX,XX +XXX,XX @@ void bdrv_detach_aio_context(BlockDriverState *bs)
35
- if (!drv->bdrv_child_perm) {
71
*/
36
- assert(QLIST_EMPTY(&bs->children));
72
bs->walking_aio_notifiers = false;
73
74
- if (bs->drv->bdrv_detach_aio_context) {
75
+ if (bs->drv && bs->drv->bdrv_detach_aio_context) {
76
bs->drv->bdrv_detach_aio_context(bs);
77
}
78
QLIST_FOREACH(child, &bs->children, next) {
79
@@ -XXX,XX +XXX,XX @@ void bdrv_attach_aio_context(BlockDriverState *bs,
80
BdrvAioNotifier *ban, *ban_tmp;
81
BdrvChild *child;
82
83
- if (!bs->drv) {
84
- return;
37
- return;
85
- }
38
- }
86
-
39
-
87
if (bs->quiesce_counter) {
40
- /* Update all children */
88
aio_disable_external(new_context);
41
- QLIST_FOREACH(c, &bs->children, next) {
42
- bdrv_child_set_perm_commit(c);
43
- }
44
-}
45
-
46
-static void bdrv_list_set_perm(GSList *list)
47
-{
48
- for ( ; list; list = list->next) {
49
- bdrv_node_set_perm((BlockDriverState *)list->data);
50
- }
51
-}
52
-
53
-static void bdrv_set_perm(BlockDriverState *bs)
54
-{
55
- g_autoptr(GSList) list = bdrv_topological_dfs(NULL, NULL, bs);
56
- return bdrv_list_set_perm(list);
57
-}
58
-
59
void bdrv_get_cumulative_perm(BlockDriverState *bs, uint64_t *perm,
60
uint64_t *shared_perm)
61
{
62
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_noperm(BdrvChild *child,
89
}
63
}
90
@@ -XXX,XX +XXX,XX @@ void bdrv_attach_aio_context(BlockDriverState *bs,
64
}
91
QLIST_FOREACH(child, &bs->children, next) {
65
92
bdrv_attach_aio_context(child->bs, new_context);
66
-/*
93
}
67
- * Updates @child to change its reference to point to @new_bs, including
94
- if (bs->drv->bdrv_attach_aio_context) {
68
- * checking and applying the necessary permission updates both to the old node
95
+ if (bs->drv && bs->drv->bdrv_attach_aio_context) {
69
- * and to @new_bs.
96
bs->drv->bdrv_attach_aio_context(bs, new_context);
70
- *
97
}
71
- * NULL is passed as @new_bs for removing the reference before freeing @child.
98
72
- *
73
- * If @new_bs is not NULL, bdrv_check_perm() must be called beforehand, as this
74
- * function uses bdrv_set_perm() to update the permissions according to the new
75
- * reference that @new_bs gets.
76
- *
77
- * Callers must ensure that child->frozen is false.
78
- */
79
-static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs)
80
-{
81
- BlockDriverState *old_bs = child->bs;
82
-
83
- /* Asserts that child->frozen == false */
84
- bdrv_replace_child_noperm(child, new_bs);
85
-
86
- /*
87
- * Start with the new node's permissions. If @new_bs is a (direct
88
- * or indirect) child of @old_bs, we must complete the permission
89
- * update on @new_bs before we loosen the restrictions on @old_bs.
90
- * Otherwise, bdrv_check_perm() on @old_bs would re-initiate
91
- * updating the permissions of @new_bs, and thus not purely loosen
92
- * restrictions.
93
- */
94
- if (new_bs) {
95
- bdrv_set_perm(new_bs);
96
- }
97
-
98
- if (old_bs) {
99
- /*
100
- * Update permissions for old node. We're just taking a parent away, so
101
- * we're loosening restrictions. Errors of permission update are not
102
- * fatal in this case, ignore them.
103
- */
104
- bdrv_refresh_perms(old_bs, NULL);
105
-
106
- /* When the parent requiring a non-default AioContext is removed, the
107
- * node moves back to the main AioContext */
108
- bdrv_try_set_aio_context(old_bs, qemu_get_aio_context(), NULL);
109
- }
110
-}
111
-
112
static void bdrv_child_free(void *opaque)
113
{
114
BdrvChild *c = opaque;
115
@@ -XXX,XX +XXX,XX @@ static int bdrv_attach_child_noperm(BlockDriverState *parent_bs,
116
117
static void bdrv_detach_child(BdrvChild *child)
118
{
119
- bdrv_replace_child(child, NULL);
120
+ BlockDriverState *old_bs = child->bs;
121
+
122
+ bdrv_replace_child_noperm(child, NULL);
123
bdrv_remove_empty_child(child);
124
+
125
+ if (old_bs) {
126
+ /*
127
+ * Update permissions for old node. We're just taking a parent away, so
128
+ * we're loosening restrictions. Errors of permission update are not
129
+ * fatal in this case, ignore them.
130
+ */
131
+ bdrv_refresh_perms(old_bs, NULL);
132
+
133
+ /*
134
+ * When the parent requiring a non-default AioContext is removed, the
135
+ * node moves back to the main AioContext
136
+ */
137
+ bdrv_try_set_aio_context(old_bs, qemu_get_aio_context(), NULL);
138
+ }
139
}
140
141
/*
99
--
142
--
100
2.20.1
143
2.30.2
101
144
102
145
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
Move to _co_ versions of io functions qed_read_table() and
3
Old interfaces dropped, nobody directly calls
4
qed_write_table(), as we use qemu_co_mutex_unlock()
4
bdrv_child_set_perm_abort() and bdrv_child_set_perm_commit(), so we can
5
anyway.
5
use personal state structure for the action and stop exploiting
6
BdrvChild structure. Also, drop "_safe" suffix which is redundant now.
6
7
7
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
10
Message-Id: <20210428151804.439460-35-vsementsov@virtuozzo.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
---
12
block/qed-table.c | 12 +++++-------
13
include/block/block_int.h | 5 ----
13
block/qed.c | 6 ++----
14
block.c | 63 ++++++++++++++-------------------------
14
2 files changed, 7 insertions(+), 11 deletions(-)
15
2 files changed, 22 insertions(+), 46 deletions(-)
15
16
16
diff --git a/block/qed-table.c b/block/qed-table.c
17
diff --git a/include/block/block_int.h b/include/block/block_int.h
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/block/qed-table.c
19
--- a/include/block/block_int.h
19
+++ b/block/qed-table.c
20
+++ b/include/block/block_int.h
20
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ struct BdrvChild {
21
/* Called with table_lock held. */
22
*/
22
static int qed_read_table(BDRVQEDState *s, uint64_t offset, QEDTable *table)
23
uint64_t shared_perm;
24
25
- /* backup of permissions during permission update procedure */
26
- bool has_backup_perm;
27
- uint64_t backup_perm;
28
- uint64_t backup_shared_perm;
29
-
30
/*
31
* This link is frozen: the child can neither be replaced nor
32
* detached from the parent.
33
diff --git a/block.c b/block.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/block.c
36
+++ b/block.c
37
@@ -XXX,XX +XXX,XX @@ static GSList *bdrv_topological_dfs(GSList *list, GHashTable *found,
38
return g_slist_prepend(list, bs);
39
}
40
41
-static void bdrv_child_set_perm_commit(void *opaque)
42
-{
43
- BdrvChild *c = opaque;
44
-
45
- c->has_backup_perm = false;
46
-}
47
+typedef struct BdrvChildSetPermState {
48
+ BdrvChild *child;
49
+ uint64_t old_perm;
50
+ uint64_t old_shared_perm;
51
+} BdrvChildSetPermState;
52
53
static void bdrv_child_set_perm_abort(void *opaque)
23
{
54
{
24
- QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(
55
- BdrvChild *c = opaque;
25
- qiov, table->offsets, s->header.cluster_size * s->header.table_size);
56
- /*
26
+ unsigned int bytes = s->header.cluster_size * s->header.table_size;
57
- * We may have child->has_backup_perm unset at this point, as in case of
58
- * _check_ stage of permission update failure we may _check_ not the whole
59
- * subtree. Still, _abort_ is called on the whole subtree anyway.
60
- */
61
- if (c->has_backup_perm) {
62
- c->perm = c->backup_perm;
63
- c->shared_perm = c->backup_shared_perm;
64
- c->has_backup_perm = false;
65
- }
66
+ BdrvChildSetPermState *s = opaque;
27
+
67
+
28
int noffsets;
68
+ s->child->perm = s->old_perm;
29
int i, ret;
69
+ s->child->shared_perm = s->old_shared_perm;
30
70
}
31
trace_qed_read_table(s, offset, table);
71
32
72
static TransactionActionDrv bdrv_child_set_pem_drv = {
33
qemu_co_mutex_unlock(&s->table_lock);
73
.abort = bdrv_child_set_perm_abort,
34
- ret = bdrv_preadv(s->bs->file, offset, &qiov);
74
- .commit = bdrv_child_set_perm_commit,
35
+ ret = bdrv_co_pread(s->bs->file, offset, bytes, table->offsets, 0);
75
+ .clean = g_free,
36
qemu_co_mutex_lock(&s->table_lock);
76
};
37
if (ret < 0) {
77
38
goto out;
78
-/*
79
- * With tran=NULL needs to be followed by direct call to either
80
- * bdrv_child_set_perm_commit() or bdrv_child_set_perm_abort().
81
- *
82
- * With non-NULL tran needs to be followed by tran_abort() or tran_commit()
83
- * instead.
84
- */
85
-static void bdrv_child_set_perm_safe(BdrvChild *c, uint64_t perm,
86
- uint64_t shared, Transaction *tran)
87
+static void bdrv_child_set_perm(BdrvChild *c, uint64_t perm,
88
+ uint64_t shared, Transaction *tran)
89
{
90
- if (!c->has_backup_perm) {
91
- c->has_backup_perm = true;
92
- c->backup_perm = c->perm;
93
- c->backup_shared_perm = c->shared_perm;
94
- }
95
- /*
96
- * Note: it's OK if c->has_backup_perm was already set, as we can find the
97
- * same c twice during check_perm procedure
98
- */
99
+ BdrvChildSetPermState *s = g_new(BdrvChildSetPermState, 1);
100
+
101
+ *s = (BdrvChildSetPermState) {
102
+ .child = c,
103
+ .old_perm = c->perm,
104
+ .old_shared_perm = c->shared_perm,
105
+ };
106
107
c->perm = perm;
108
c->shared_perm = shared;
109
110
- if (tran) {
111
- tran_add(tran, &bdrv_child_set_pem_drv, c);
112
- }
113
+ tran_add(tran, &bdrv_child_set_pem_drv, s);
114
}
115
116
static void bdrv_drv_set_perm_commit(void *opaque)
117
@@ -XXX,XX +XXX,XX @@ static int bdrv_node_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
118
bdrv_child_perm(bs, c->bs, c, c->role, q,
119
cumulative_perms, cumulative_shared_perms,
120
&cur_perm, &cur_shared);
121
- bdrv_child_set_perm_safe(c, cur_perm, cur_shared, tran);
122
+ bdrv_child_set_perm(c, cur_perm, cur_shared, tran);
39
}
123
}
40
124
41
/* Byteswap offsets */
125
return 0;
42
- noffsets = qiov.size / sizeof(uint64_t);
126
@@ -XXX,XX +XXX,XX @@ int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
43
+ noffsets = bytes / sizeof(uint64_t);
127
Transaction *tran = tran_new();
44
for (i = 0; i < noffsets; i++) {
45
table->offsets[i] = le64_to_cpu(table->offsets[i]);
46
}
47
@@ -XXX,XX +XXX,XX @@ static int qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
48
unsigned int sector_mask = BDRV_SECTOR_SIZE / sizeof(uint64_t) - 1;
49
unsigned int start, end, i;
50
QEDTable *new_table;
51
- QEMUIOVector qiov;
52
size_t len_bytes;
53
int ret;
128
int ret;
54
129
55
@@ -XXX,XX +XXX,XX @@ static int qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
130
- bdrv_child_set_perm_safe(c, perm, shared, tran);
56
len_bytes = (end - start) * sizeof(uint64_t);
131
+ bdrv_child_set_perm(c, perm, shared, tran);
57
132
58
new_table = qemu_blockalign(s->bs, len_bytes);
133
ret = bdrv_refresh_perms(c->bs, &local_err);
59
- qemu_iovec_init_buf(&qiov, new_table->offsets, len_bytes);
134
60
61
/* Byteswap table */
62
for (i = start; i < end; i++) {
63
@@ -XXX,XX +XXX,XX @@ static int qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
64
offset += start * sizeof(uint64_t);
65
66
qemu_co_mutex_unlock(&s->table_lock);
67
- ret = bdrv_pwritev(s->bs->file, offset, &qiov);
68
+ ret = bdrv_co_pwrite(s->bs->file, offset, len_bytes, new_table->offsets, 0);
69
qemu_co_mutex_lock(&s->table_lock);
70
trace_qed_write_table_cb(s, table, flush, ret);
71
if (ret < 0) {
72
diff --git a/block/qed.c b/block/qed.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/block/qed.c
75
+++ b/block/qed.c
76
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qed_write_header(BDRVQEDState *s)
77
int nsectors = DIV_ROUND_UP(sizeof(QEDHeader), BDRV_SECTOR_SIZE);
78
size_t len = nsectors * BDRV_SECTOR_SIZE;
79
uint8_t *buf;
80
- QEMUIOVector qiov;
81
int ret;
82
83
assert(s->allocating_acb || s->allocating_write_reqs_plugged);
84
85
buf = qemu_blockalign(s->bs, len);
86
- qemu_iovec_init_buf(&qiov, buf, len);
87
88
- ret = bdrv_co_preadv(s->bs->file, 0, qiov.size, &qiov, 0);
89
+ ret = bdrv_co_pread(s->bs->file, 0, len, buf, 0);
90
if (ret < 0) {
91
goto out;
92
}
93
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qed_write_header(BDRVQEDState *s)
94
/* Update header */
95
qed_header_cpu_to_le(&s->header, (QEDHeader *) buf);
96
97
- ret = bdrv_co_pwritev(s->bs->file, 0, qiov.size, &qiov, 0);
98
+ ret = bdrv_co_pwrite(s->bs->file, 0, len, buf, 0);
99
if (ret < 0) {
100
goto out;
101
}
102
--
135
--
103
2.20.1
136
2.30.2
104
137
105
138
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
This patch fixes a few things in the way error codes are handled in
3
We don't have bdrv_replace_child(), so it's time for
4
the qcow2 compression code:
4
bdrv_replace_child_safe() to take its place.
5
5
6
a) qcow2_co_pwritev_compressed() expects qcow2_co_compress() to only
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
return -1 or -2 on failure, but this is not correct. Since the
7
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
8
change from qcow2_compress() to qcow2_co_compress() in commit
8
Message-Id: <20210428151804.439460-36-vsementsov@virtuozzo.com>
9
ceb029cd6feccf9f7607 the new code can also return -EINVAL (although
10
there does not seem to exist any code path that would cause that
11
error in the current implementation).
12
13
b) -1 and -2 are ad-hoc error codes defined in qcow2_compress().
14
This patch replaces them with standard constants from errno.h.
15
16
c) Both qcow2_compress() and qcow2_co_do_compress() return a negative
17
value on failure, but qcow2_co_pwritev_compressed() stores the
18
value in an unsigned data type.
19
20
Signed-off-by: Alberto Garcia <berto@igalia.com>
21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
---
10
---
23
block/qcow2.c | 18 +++++++++---------
11
block.c | 10 +++++-----
24
1 file changed, 9 insertions(+), 9 deletions(-)
12
1 file changed, 5 insertions(+), 5 deletions(-)
25
13
26
diff --git a/block/qcow2.c b/block/qcow2.c
14
diff --git a/block.c b/block.c
27
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
28
--- a/block/qcow2.c
16
--- a/block.c
29
+++ b/block/qcow2.c
17
+++ b/block.c
30
@@ -XXX,XX +XXX,XX @@ fail:
18
@@ -XXX,XX +XXX,XX @@ static TransactionActionDrv bdrv_replace_child_drv = {
31
* @src - source buffer, @src_size bytes
19
};
20
21
/*
22
- * bdrv_replace_child_safe
23
+ * bdrv_replace_child
32
*
24
*
33
* Returns: compressed size on success
25
* Note: real unref of old_bs is done only on commit.
34
- * -1 destination buffer is not enough to store compressed data
35
- * -2 on any other error
36
+ * -ENOMEM destination buffer is not enough to store compressed data
37
+ * -EIO on any other error
38
*/
26
*/
39
static ssize_t qcow2_compress(void *dest, size_t dest_size,
27
-static void bdrv_replace_child_safe(BdrvChild *child, BlockDriverState *new_bs,
40
const void *src, size_t src_size)
28
- Transaction *tran)
41
@@ -XXX,XX +XXX,XX @@ static ssize_t qcow2_compress(void *dest, size_t dest_size,
29
+static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs,
42
ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
30
+ Transaction *tran)
43
-12, 9, Z_DEFAULT_STRATEGY);
31
{
44
if (ret != Z_OK) {
32
BdrvReplaceChildState *s = g_new(BdrvReplaceChildState, 1);
45
- return -2;
33
*s = (BdrvReplaceChildState) {
46
+ return -EIO;
34
@@ -XXX,XX +XXX,XX @@ static void bdrv_remove_filter_or_cow_child(BlockDriverState *bs,
47
}
35
}
48
36
49
/* strm.next_in is not const in old zlib versions, such as those used on
37
if (child->bs) {
50
@@ -XXX,XX +XXX,XX @@ static ssize_t qcow2_compress(void *dest, size_t dest_size,
38
- bdrv_replace_child_safe(child, NULL, tran);
51
if (ret == Z_STREAM_END) {
39
+ bdrv_replace_child(child, NULL, tran);
52
ret = dest_size - strm.avail_out;
53
} else {
54
- ret = (ret == Z_OK ? -1 : -2);
55
+ ret = (ret == Z_OK ? -ENOMEM : -EIO);
56
}
40
}
57
41
58
deflateEnd(&strm);
42
s = g_new(BdrvRemoveFilterOrCowChild, 1);
59
@@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
43
@@ -XXX,XX +XXX,XX @@ static int bdrv_replace_node_noperm(BlockDriverState *from,
60
BDRVQcow2State *s = bs->opaque;
44
c->name, from->node_name);
61
QEMUIOVector hd_qiov;
45
return -EPERM;
62
int ret;
63
- size_t out_len;
64
+ ssize_t out_len;
65
uint8_t *buf, *out_buf;
66
uint64_t cluster_offset;
67
68
@@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
69
70
out_len = qcow2_co_compress(bs, out_buf, s->cluster_size - 1,
71
buf, s->cluster_size);
72
- if (out_len == -2) {
73
- ret = -EINVAL;
74
- goto fail;
75
- } else if (out_len == -1) {
76
+ if (out_len == -ENOMEM) {
77
/* could not compress: write normal cluster */
78
ret = qcow2_co_pwritev(bs, offset, bytes, qiov, 0);
79
if (ret < 0) {
80
goto fail;
81
}
46
}
82
goto success;
47
- bdrv_replace_child_safe(c, to, tran);
83
+ } else if (out_len < 0) {
48
+ bdrv_replace_child(c, to, tran);
84
+ ret = -EINVAL;
85
+ goto fail;
86
}
49
}
87
50
88
qemu_co_mutex_lock(&s->lock);
51
return 0;
89
--
52
--
90
2.20.1
53
2.30.2
91
54
92
55
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
Now, bdrv_node_check_perm() is called only with fresh cumulative
4
permissions, so its actually "refresh_perm".
5
6
Move permission calculation to the function. Also, drop unreachable
7
error message and rewrite the remaining one to be more generic (as now
8
we don't know which node is added and which was already here).
9
10
Add also Virtuozzo copyright, as big work is done at this point.
11
3
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
12
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
4
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
13
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
5
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
14
Message-Id: <20210428151804.439460-37-vsementsov@virtuozzo.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
16
---
8
block/parallels.c | 14 ++++++--------
17
block.c | 38 +++++++++++---------------------------
9
1 file changed, 6 insertions(+), 8 deletions(-)
18
tests/qemu-iotests/245 | 2 +-
19
2 files changed, 12 insertions(+), 28 deletions(-)
10
20
11
diff --git a/block/parallels.c b/block/parallels.c
21
diff --git a/block.c b/block.c
12
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
13
--- a/block/parallels.c
23
--- a/block.c
14
+++ b/block/parallels.c
24
+++ b/block.c
15
@@ -XXX,XX +XXX,XX @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num,
25
@@ -XXX,XX +XXX,XX @@
16
if (bs->backing) {
26
* QEMU System Emulator block driver
17
int64_t nb_cow_sectors = to_allocate * s->tracks;
27
*
18
int64_t nb_cow_bytes = nb_cow_sectors << BDRV_SECTOR_BITS;
28
* Copyright (c) 2003 Fabrice Bellard
19
- QEMUIOVector qiov =
29
+ * Copyright (c) 2020 Virtuozzo International GmbH.
20
- QEMU_IOVEC_INIT_BUF(qiov, qemu_blockalign(bs, nb_cow_bytes),
30
*
21
- nb_cow_bytes);
31
* Permission is hereby granted, free of charge, to any person obtaining a copy
22
+ void *buf = qemu_blockalign(bs, nb_cow_bytes);
32
* of this software and associated documentation files (the "Software"), to deal
23
33
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs,
24
- ret = bdrv_co_preadv(bs->backing, idx * s->tracks * BDRV_SECTOR_SIZE,
34
}
25
- nb_cow_bytes, &qiov, 0);
35
26
+ ret = bdrv_co_pread(bs->backing, idx * s->tracks * BDRV_SECTOR_SIZE,
36
/*
27
+ nb_cow_bytes, buf, 0);
37
- * Check whether permissions on this node can be changed in a way that
28
if (ret < 0) {
38
- * @cumulative_perms and @cumulative_shared_perms are the new cumulative
29
- qemu_vfree(qemu_iovec_buf(&qiov));
39
- * permissions of all its parents. This involves checking whether all necessary
30
+ qemu_vfree(buf);
40
- * permission changes to child nodes can be performed.
31
return ret;
41
- *
42
- * A call to this function must always be followed by a call to bdrv_set_perm()
43
- * or bdrv_abort_perm_update().
44
+ * Refresh permissions in @bs subtree. The function is intended to be called
45
+ * after some graph modification that was done without permission update.
46
*/
47
-static int bdrv_node_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
48
- uint64_t cumulative_perms,
49
- uint64_t cumulative_shared_perms,
50
- Transaction *tran, Error **errp)
51
+static int bdrv_node_refresh_perm(BlockDriverState *bs, BlockReopenQueue *q,
52
+ Transaction *tran, Error **errp)
53
{
54
BlockDriver *drv = bs->drv;
55
BdrvChild *c;
56
int ret;
57
+ uint64_t cumulative_perms, cumulative_shared_perms;
58
+
59
+ bdrv_get_cumulative_perm(bs, &cumulative_perms, &cumulative_shared_perms);
60
61
/* Write permissions never work with read-only images */
62
if ((cumulative_perms & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED)) &&
63
@@ -XXX,XX +XXX,XX @@ static int bdrv_node_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
64
if (!bdrv_is_writable_after_reopen(bs, NULL)) {
65
error_setg(errp, "Block node is read-only");
66
} else {
67
- uint64_t current_perms, current_shared;
68
- bdrv_get_cumulative_perm(bs, &current_perms, &current_shared);
69
- if (current_perms & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED)) {
70
- error_setg(errp, "Cannot make block node read-only, there is "
71
- "a writer on it");
72
- } else {
73
- error_setg(errp, "Cannot make block node read-only and create "
74
- "a writer on it");
75
- }
76
+ error_setg(errp, "Read-only block node '%s' cannot support "
77
+ "read-write users", bdrv_get_node_name(bs));
32
}
78
}
33
79
34
ret = bdrv_co_pwritev(bs->file, s->data_end * BDRV_SECTOR_SIZE,
80
return -EPERM;
35
- nb_cow_bytes, &qiov, 0);
81
@@ -XXX,XX +XXX,XX @@ static int bdrv_list_refresh_perms(GSList *list, BlockReopenQueue *q,
36
- qemu_vfree(qemu_iovec_buf(&qiov));
82
Transaction *tran, Error **errp)
37
+ nb_cow_bytes, buf, 0);
83
{
38
+ qemu_vfree(buf);
84
int ret;
85
- uint64_t cumulative_perms, cumulative_shared_perms;
86
BlockDriverState *bs;
87
88
for ( ; list; list = list->next) {
89
@@ -XXX,XX +XXX,XX @@ static int bdrv_list_refresh_perms(GSList *list, BlockReopenQueue *q,
90
return -EINVAL;
91
}
92
93
- bdrv_get_cumulative_perm(bs, &cumulative_perms,
94
- &cumulative_shared_perms);
95
-
96
- ret = bdrv_node_check_perm(bs, q, cumulative_perms,
97
- cumulative_shared_perms,
98
- tran, errp);
99
+ ret = bdrv_node_refresh_perm(bs, q, tran, errp);
39
if (ret < 0) {
100
if (ret < 0) {
40
return ret;
101
return ret;
41
}
102
}
103
diff --git a/tests/qemu-iotests/245 b/tests/qemu-iotests/245
104
index XXXXXXX..XXXXXXX 100755
105
--- a/tests/qemu-iotests/245
106
+++ b/tests/qemu-iotests/245
107
@@ -XXX,XX +XXX,XX @@ class TestBlockdevReopen(iotests.QMPTestCase):
108
# We can't reopen hd1 to read-only, as block-stream requires it to be
109
# read-write
110
self.reopen(opts['backing'], {'read-only': True},
111
- "Cannot make block node read-only, there is a writer on it")
112
+ "Read-only block node 'hd1' cannot support read-write users")
113
114
# We can't remove hd2 while the stream job is ongoing
115
opts['backing']['backing'] = None
42
--
116
--
43
2.20.1
117
2.30.2
44
118
45
119
diff view generated by jsdifflib
1
From: Zhengui li <lizhengui@huawei.com>
1
Normally, blk_new_open() just shares all permissions. This was fine
2
originally when permissions only protected against uses in the same
3
process because no other part of the code would actually get to access
4
the block nodes opened with blk_new_open(). However, since we use it for
5
file locking now, unsharing permissions becomes desirable.
2
6
3
Concurrent IO becomes serial IO because of the qemu Coroutine lock,
7
Add a new BDRV_O_NO_SHARE flag that is used in blk_new_open() to unshare
4
which reduce IO performance severely.
8
any permissions that can be unshared.
5
9
6
So unlock Coroutine lock before bdrv_co_pwritev and
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
bdrv_co_preadv to fix it.
11
Message-Id: <20210422164344.283389-2-kwolf@redhat.com>
8
12
Reviewed-by: Eric Blake <eblake@redhat.com>
9
Signed-off-by: Zhengui li <lizhengui@huawei.com>
13
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
15
---
13
block/vpc.c | 4 ++++
16
include/block/block.h | 1 +
14
1 file changed, 4 insertions(+)
17
block/block-backend.c | 19 +++++++++++++------
18
2 files changed, 14 insertions(+), 6 deletions(-)
15
19
16
diff --git a/block/vpc.c b/block/vpc.c
20
diff --git a/include/block/block.h b/include/block/block.h
17
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
18
--- a/block/vpc.c
22
--- a/include/block/block.h
19
+++ b/block/vpc.c
23
+++ b/include/block/block.h
20
@@ -XXX,XX +XXX,XX @@ vpc_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
24
@@ -XXX,XX +XXX,XX @@ typedef struct HDGeometry {
21
qemu_iovec_reset(&local_qiov);
25
uint32_t cylinders;
22
qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);
26
} HDGeometry;
23
27
24
+ qemu_co_mutex_unlock(&s->lock);
28
+#define BDRV_O_NO_SHARE 0x0001 /* don't share permissions */
25
ret = bdrv_co_preadv(bs->file, image_offset, n_bytes,
29
#define BDRV_O_RDWR 0x0002
26
&local_qiov, 0);
30
#define BDRV_O_RESIZE 0x0004 /* request permission for resizing the node */
27
+ qemu_co_mutex_lock(&s->lock);
31
#define BDRV_O_SNAPSHOT 0x0008 /* open the file read only and save writes in a snapshot */
28
if (ret < 0) {
32
diff --git a/block/block-backend.c b/block/block-backend.c
29
goto fail;
33
index XXXXXXX..XXXXXXX 100644
30
}
34
--- a/block/block-backend.c
31
@@ -XXX,XX +XXX,XX @@ vpc_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
35
+++ b/block/block-backend.c
32
qemu_iovec_reset(&local_qiov);
36
@@ -XXX,XX +XXX,XX @@ BlockBackend *blk_new_open(const char *filename, const char *reference,
33
qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);
37
BlockBackend *blk;
34
38
BlockDriverState *bs;
35
+ qemu_co_mutex_unlock(&s->lock);
39
uint64_t perm = 0;
36
ret = bdrv_co_pwritev(bs->file, image_offset, n_bytes,
40
+ uint64_t shared = BLK_PERM_ALL;
37
&local_qiov, 0);
41
38
+ qemu_co_mutex_lock(&s->lock);
42
- /* blk_new_open() is mainly used in .bdrv_create implementations and the
39
if (ret < 0) {
43
- * tools where sharing isn't a concern because the BDS stays private, so we
40
goto fail;
44
- * just request permission according to the flags.
41
}
45
+ /*
46
+ * blk_new_open() is mainly used in .bdrv_create implementations and the
47
+ * tools where sharing isn't a major concern because the BDS stays private
48
+ * and the file is generally not supposed to be used by a second process,
49
+ * so we just request permission according to the flags.
50
*
51
* The exceptions are xen_disk and blockdev_init(); in these cases, the
52
* caller of blk_new_open() doesn't make use of the permissions, but they
53
* shouldn't hurt either. We can still share everything here because the
54
- * guest devices will add their own blockers if they can't share. */
55
+ * guest devices will add their own blockers if they can't share.
56
+ */
57
if ((flags & BDRV_O_NO_IO) == 0) {
58
perm |= BLK_PERM_CONSISTENT_READ;
59
if (flags & BDRV_O_RDWR) {
60
@@ -XXX,XX +XXX,XX @@ BlockBackend *blk_new_open(const char *filename, const char *reference,
61
if (flags & BDRV_O_RESIZE) {
62
perm |= BLK_PERM_RESIZE;
63
}
64
+ if (flags & BDRV_O_NO_SHARE) {
65
+ shared = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED;
66
+ }
67
68
- blk = blk_new(qemu_get_aio_context(), perm, BLK_PERM_ALL);
69
+ blk = blk_new(qemu_get_aio_context(), perm, shared);
70
bs = bdrv_open(filename, reference, options, flags, errp);
71
if (!bs) {
72
blk_unref(blk);
73
@@ -XXX,XX +XXX,XX @@ BlockBackend *blk_new_open(const char *filename, const char *reference,
74
75
blk->root = bdrv_root_attach_child(bs, "root", &child_root,
76
BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
77
- perm, BLK_PERM_ALL, blk, errp);
78
+ perm, shared, blk, errp);
79
if (!blk->root) {
80
blk_unref(blk);
81
return NULL;
42
--
82
--
43
2.20.1
83
2.30.2
44
84
45
85
diff view generated by jsdifflib
1
Limiting the allocation to INT_MAX bytes isn't particularly clever
1
For a successful conversion of an image, we must make sure that its
2
because it means that the final cluster will be a partial cluster which
2
content doesn't change during the conversion.
3
will be completed through a COW operation. This results in unnecessary
4
data read and write requests which lead to an unwanted non-sparse
5
filesystem block for metadata preallocation.
6
3
7
Align the maximum allocation size down to the cluster size to avoid this
4
A special case of this is using the same image file both as the source
8
situation.
5
and as the destination. If both input and output format are raw, the
6
operation would just be useless work, with other formats it is a sure
7
way to destroy the image. This will now fail because the image file
8
can't be opened a second time for the output when opening it for the
9
input has already acquired file locks to unshare BLK_PERM_WRITE.
9
10
10
Cc: qemu-stable@nongnu.org
11
Nevertheless, if there is some reason in a special case why it is
12
actually okay to allow writes to the image while it is being converted,
13
-U can still be used to force sharing all permissions.
14
15
Note that for most image formats, BLK_PERM_WRITE would already be
16
unshared by the format driver, so this only really makes a difference
17
for raw source images (but any output format).
18
19
Reported-by: Xueqiang Wei <xuwei@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
20
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Reviewed-by: Eric Blake <eblake@redhat.com>
21
Reviewed-by: Eric Blake <eblake@redhat.com>
22
Message-Id: <20210422164344.283389-3-kwolf@redhat.com>
23
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
24
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
25
---
14
block/qcow2.c | 2 +-
26
qemu-img.c | 2 +-
15
1 file changed, 1 insertion(+), 1 deletion(-)
27
1 file changed, 1 insertion(+), 1 deletion(-)
16
28
17
diff --git a/block/qcow2.c b/block/qcow2.c
29
diff --git a/qemu-img.c b/qemu-img.c
18
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
19
--- a/block/qcow2.c
31
--- a/qemu-img.c
20
+++ b/block/qcow2.c
32
+++ b/qemu-img.c
21
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
33
@@ -XXX,XX +XXX,XX @@ static void set_rate_limit(BlockBackend *blk, int64_t rate_limit)
22
bytes = new_length - offset;
34
23
35
static int img_convert(int argc, char **argv)
24
while (bytes) {
36
{
25
- cur_bytes = MIN(bytes, INT_MAX);
37
- int c, bs_i, flags, src_flags = 0;
26
+ cur_bytes = MIN(bytes, QEMU_ALIGN_DOWN(INT_MAX, s->cluster_size));
38
+ int c, bs_i, flags, src_flags = BDRV_O_NO_SHARE;
27
ret = qcow2_alloc_cluster_offset(bs, offset, &cur_bytes,
39
const char *fmt = NULL, *out_fmt = NULL, *cache = "unsafe",
28
&host_offset, &meta);
40
*src_cache = BDRV_DEFAULT_CACHE, *out_baseimg = NULL,
29
if (ret < 0) {
41
*out_filename, *out_baseimg_param, *snapshot_name = NULL;
30
--
42
--
31
2.20.1
43
2.30.2
32
44
33
45
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
virtio_add_queue() aborts when queue_size > VIRTQUEUE_MAX_SIZE, so
2
vhost_user_blk_device_realize() should check this before calling it.
2
3
3
One of the recent commits changed the way qemu-io prints out its
4
Simple reproducer:
4
errors and warnings - they are now prefixed with the program name.
5
We've got to adapt the iotests accordingly to prevent that they
6
are failing.
7
5
8
Fixes: 99e98d7c9fc1a1639fad ("qemu-io: Use error_[gs]et_progname()")
6
qemu-system-x86_64 \
9
Signed-off-by: Thomas Huth <thuth@redhat.com>
7
-chardev null,id=foo \
8
-device vhost-user-blk-pci,queue-size=4096,chardev=foo
9
10
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1935014
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Message-Id: <20210413165654.50810-1-kwolf@redhat.com>
13
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
14
Reviewed-by: Raphael Norwitz <raphael.norwitz@nutanix.com>
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
16
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
18
---
12
tests/qemu-iotests/026.out | 168 ++++++++++++++++++-------------------
19
hw/block/vhost-user-blk.c | 5 +++++
13
tests/qemu-iotests/060.out | 6 +-
20
1 file changed, 5 insertions(+)
14
tests/qemu-iotests/069.out | 2 +-
15
tests/qemu-iotests/070.out | 2 +-
16
tests/qemu-iotests/075.out | 14 ++--
17
tests/qemu-iotests/076.out | 6 +-
18
tests/qemu-iotests/078.out | 12 +--
19
tests/qemu-iotests/080.out | 40 ++++-----
20
tests/qemu-iotests/081.out | 2 +-
21
tests/qemu-iotests/088.out | 12 +--
22
tests/qemu-iotests/103.out | 14 ++--
23
tests/qemu-iotests/114.out | 2 +-
24
tests/qemu-iotests/116.out | 14 ++--
25
tests/qemu-iotests/131.out | 2 +-
26
tests/qemu-iotests/133.out | 30 +++----
27
tests/qemu-iotests/137.out | 28 +++----
28
tests/qemu-iotests/140.out | 2 +-
29
tests/qemu-iotests/143.out | 2 +-
30
tests/qemu-iotests/153.out | 30 +++----
31
tests/qemu-iotests/187.out | 6 +-
32
tests/qemu-iotests/188.out | 2 +-
33
tests/qemu-iotests/197.out | 2 +-
34
tests/qemu-iotests/205 | 2 +-
35
tests/qemu-iotests/215.out | 2 +-
36
tests/qemu-iotests/226.out | 16 ++--
37
tests/qemu-iotests/244.out | 10 +--
38
26 files changed, 214 insertions(+), 214 deletions(-)
39
21
40
diff --git a/tests/qemu-iotests/026.out b/tests/qemu-iotests/026.out
22
diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
41
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
42
--- a/tests/qemu-iotests/026.out
24
--- a/hw/block/vhost-user-blk.c
43
+++ b/tests/qemu-iotests/026.out
25
+++ b/hw/block/vhost-user-blk.c
44
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
26
@@ -XXX,XX +XXX,XX @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp)
45
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
27
error_setg(errp, "vhost-user-blk: queue size must be non-zero");
46
28
return;
47
Event: l1_update; errno: 5; imm: off; once: off; write
29
}
48
-Failed to flush the L2 table cache: Input/output error
30
+ if (s->queue_size > VIRTQUEUE_MAX_SIZE) {
49
-Failed to flush the refcount block cache: Input/output error
31
+ error_setg(errp, "vhost-user-blk: queue size must not exceed %d",
50
+qemu-io: Failed to flush the L2 table cache: Input/output error
32
+ VIRTQUEUE_MAX_SIZE);
51
+qemu-io: Failed to flush the refcount block cache: Input/output error
33
+ return;
52
write failed: Input/output error
34
+ }
53
35
54
1 leaked clusters were found on the image.
36
if (!vhost_user_init(&s->vhost_user, &s->chardev, errp)) {
55
@@ -XXX,XX +XXX,XX @@ This means waste of disk space, but no harm to data.
37
return;
56
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
57
58
Event: l1_update; errno: 5; imm: off; once: off; write -b
59
-Failed to flush the L2 table cache: Input/output error
60
-Failed to flush the refcount block cache: Input/output error
61
+qemu-io: Failed to flush the L2 table cache: Input/output error
62
+qemu-io: Failed to flush the refcount block cache: Input/output error
63
write failed: Input/output error
64
65
1 leaked clusters were found on the image.
66
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
67
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
68
69
Event: l1_update; errno: 28; imm: off; once: off; write
70
-Failed to flush the L2 table cache: No space left on device
71
-Failed to flush the refcount block cache: No space left on device
72
+qemu-io: Failed to flush the L2 table cache: No space left on device
73
+qemu-io: Failed to flush the refcount block cache: No space left on device
74
write failed: No space left on device
75
76
1 leaked clusters were found on the image.
77
@@ -XXX,XX +XXX,XX @@ This means waste of disk space, but no harm to data.
78
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
79
80
Event: l1_update; errno: 28; imm: off; once: off; write -b
81
-Failed to flush the L2 table cache: No space left on device
82
-Failed to flush the refcount block cache: No space left on device
83
+qemu-io: Failed to flush the L2 table cache: No space left on device
84
+qemu-io: Failed to flush the refcount block cache: No space left on device
85
write failed: No space left on device
86
87
1 leaked clusters were found on the image.
88
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
89
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
90
91
Event: l2_update; errno: 5; imm: off; once: off; write
92
-Failed to flush the L2 table cache: Input/output error
93
-Failed to flush the refcount block cache: Input/output error
94
+qemu-io: Failed to flush the L2 table cache: Input/output error
95
+qemu-io: Failed to flush the refcount block cache: Input/output error
96
write failed: Input/output error
97
98
127 leaked clusters were found on the image.
99
@@ -XXX,XX +XXX,XX @@ This means waste of disk space, but no harm to data.
100
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
101
102
Event: l2_update; errno: 5; imm: off; once: off; write -b
103
-Failed to flush the L2 table cache: Input/output error
104
-Failed to flush the refcount block cache: Input/output error
105
+qemu-io: Failed to flush the L2 table cache: Input/output error
106
+qemu-io: Failed to flush the refcount block cache: Input/output error
107
write failed: Input/output error
108
109
127 leaked clusters were found on the image.
110
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
111
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
112
113
Event: l2_update; errno: 28; imm: off; once: off; write
114
-Failed to flush the L2 table cache: No space left on device
115
-Failed to flush the refcount block cache: No space left on device
116
+qemu-io: Failed to flush the L2 table cache: No space left on device
117
+qemu-io: Failed to flush the refcount block cache: No space left on device
118
write failed: No space left on device
119
120
127 leaked clusters were found on the image.
121
@@ -XXX,XX +XXX,XX @@ This means waste of disk space, but no harm to data.
122
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
123
124
Event: l2_update; errno: 28; imm: off; once: off; write -b
125
-Failed to flush the L2 table cache: No space left on device
126
-Failed to flush the refcount block cache: No space left on device
127
+qemu-io: Failed to flush the L2 table cache: No space left on device
128
+qemu-io: Failed to flush the refcount block cache: No space left on device
129
write failed: No space left on device
130
131
127 leaked clusters were found on the image.
132
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
133
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
134
135
Event: l2_alloc_write; errno: 5; imm: off; once: off; write
136
-Failed to flush the L2 table cache: Input/output error
137
-Failed to flush the refcount block cache: Input/output error
138
+qemu-io: Failed to flush the L2 table cache: Input/output error
139
+qemu-io: Failed to flush the refcount block cache: Input/output error
140
write failed: Input/output error
141
No errors were found on the image.
142
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
143
144
Event: l2_alloc_write; errno: 5; imm: off; once: off; write -b
145
-Failed to flush the L2 table cache: Input/output error
146
-Failed to flush the refcount block cache: Input/output error
147
+qemu-io: Failed to flush the L2 table cache: Input/output error
148
+qemu-io: Failed to flush the refcount block cache: Input/output error
149
write failed: Input/output error
150
151
1 leaked clusters were found on the image.
152
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
153
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
154
155
Event: l2_alloc_write; errno: 28; imm: off; once: off; write
156
-Failed to flush the L2 table cache: No space left on device
157
-Failed to flush the refcount block cache: No space left on device
158
+qemu-io: Failed to flush the L2 table cache: No space left on device
159
+qemu-io: Failed to flush the refcount block cache: No space left on device
160
write failed: No space left on device
161
No errors were found on the image.
162
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
163
164
Event: l2_alloc_write; errno: 28; imm: off; once: off; write -b
165
-Failed to flush the L2 table cache: No space left on device
166
-Failed to flush the refcount block cache: No space left on device
167
+qemu-io: Failed to flush the L2 table cache: No space left on device
168
+qemu-io: Failed to flush the refcount block cache: No space left on device
169
write failed: No space left on device
170
171
1 leaked clusters were found on the image.
172
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
173
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
174
175
Event: write_aio; errno: 5; imm: off; once: off; write
176
-Failed to flush the L2 table cache: Input/output error
177
-Failed to flush the refcount block cache: Input/output error
178
+qemu-io: Failed to flush the L2 table cache: Input/output error
179
+qemu-io: Failed to flush the refcount block cache: Input/output error
180
write failed: Input/output error
181
No errors were found on the image.
182
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
183
184
Event: write_aio; errno: 5; imm: off; once: off; write -b
185
-Failed to flush the L2 table cache: Input/output error
186
-Failed to flush the refcount block cache: Input/output error
187
+qemu-io: Failed to flush the L2 table cache: Input/output error
188
+qemu-io: Failed to flush the refcount block cache: Input/output error
189
write failed: Input/output error
190
No errors were found on the image.
191
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
192
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
193
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
194
195
Event: write_aio; errno: 28; imm: off; once: off; write
196
-Failed to flush the L2 table cache: No space left on device
197
-Failed to flush the refcount block cache: No space left on device
198
+qemu-io: Failed to flush the L2 table cache: No space left on device
199
+qemu-io: Failed to flush the refcount block cache: No space left on device
200
write failed: No space left on device
201
No errors were found on the image.
202
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
203
204
Event: write_aio; errno: 28; imm: off; once: off; write -b
205
-Failed to flush the L2 table cache: No space left on device
206
-Failed to flush the refcount block cache: No space left on device
207
+qemu-io: Failed to flush the L2 table cache: No space left on device
208
+qemu-io: Failed to flush the refcount block cache: No space left on device
209
write failed: No space left on device
210
No errors were found on the image.
211
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
212
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
213
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
214
215
Event: refblock_load; errno: 5; imm: off; once: off; write
216
-Failed to flush the L2 table cache: Input/output error
217
-Failed to flush the refcount block cache: Input/output error
218
+qemu-io: Failed to flush the L2 table cache: Input/output error
219
+qemu-io: Failed to flush the refcount block cache: Input/output error
220
write failed: Input/output error
221
No errors were found on the image.
222
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
223
224
Event: refblock_load; errno: 5; imm: off; once: off; write -b
225
-Failed to flush the L2 table cache: Input/output error
226
-Failed to flush the refcount block cache: Input/output error
227
+qemu-io: Failed to flush the L2 table cache: Input/output error
228
+qemu-io: Failed to flush the refcount block cache: Input/output error
229
write failed: Input/output error
230
No errors were found on the image.
231
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
232
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
233
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
234
235
Event: refblock_load; errno: 28; imm: off; once: off; write
236
-Failed to flush the L2 table cache: No space left on device
237
-Failed to flush the refcount block cache: No space left on device
238
+qemu-io: Failed to flush the L2 table cache: No space left on device
239
+qemu-io: Failed to flush the refcount block cache: No space left on device
240
write failed: No space left on device
241
No errors were found on the image.
242
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
243
244
Event: refblock_load; errno: 28; imm: off; once: off; write -b
245
-Failed to flush the L2 table cache: No space left on device
246
-Failed to flush the refcount block cache: No space left on device
247
+qemu-io: Failed to flush the L2 table cache: No space left on device
248
+qemu-io: Failed to flush the refcount block cache: No space left on device
249
write failed: No space left on device
250
No errors were found on the image.
251
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
252
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
253
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
254
255
Event: refblock_update_part; errno: 5; imm: off; once: off; write
256
-Failed to flush the L2 table cache: Input/output error
257
-Failed to flush the refcount block cache: Input/output error
258
+qemu-io: Failed to flush the L2 table cache: Input/output error
259
+qemu-io: Failed to flush the refcount block cache: Input/output error
260
write failed: Input/output error
261
No errors were found on the image.
262
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
263
264
Event: refblock_update_part; errno: 5; imm: off; once: off; write -b
265
-Failed to flush the L2 table cache: Input/output error
266
-Failed to flush the refcount block cache: Input/output error
267
+qemu-io: Failed to flush the L2 table cache: Input/output error
268
+qemu-io: Failed to flush the refcount block cache: Input/output error
269
write failed: Input/output error
270
No errors were found on the image.
271
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
272
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
273
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
274
275
Event: refblock_update_part; errno: 28; imm: off; once: off; write
276
-Failed to flush the L2 table cache: No space left on device
277
-Failed to flush the refcount block cache: No space left on device
278
+qemu-io: Failed to flush the L2 table cache: No space left on device
279
+qemu-io: Failed to flush the refcount block cache: No space left on device
280
write failed: No space left on device
281
No errors were found on the image.
282
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
283
284
Event: refblock_update_part; errno: 28; imm: off; once: off; write -b
285
-Failed to flush the L2 table cache: No space left on device
286
-Failed to flush the refcount block cache: No space left on device
287
+qemu-io: Failed to flush the L2 table cache: No space left on device
288
+qemu-io: Failed to flush the refcount block cache: No space left on device
289
write failed: No space left on device
290
No errors were found on the image.
291
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
292
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
293
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
294
295
Event: refblock_alloc; errno: 5; imm: off; once: off; write
296
-Failed to flush the L2 table cache: Input/output error
297
-Failed to flush the refcount block cache: Input/output error
298
+qemu-io: Failed to flush the L2 table cache: Input/output error
299
+qemu-io: Failed to flush the refcount block cache: Input/output error
300
write failed: Input/output error
301
No errors were found on the image.
302
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
303
304
Event: refblock_alloc; errno: 5; imm: off; once: off; write -b
305
-Failed to flush the L2 table cache: Input/output error
306
-Failed to flush the refcount block cache: Input/output error
307
+qemu-io: Failed to flush the L2 table cache: Input/output error
308
+qemu-io: Failed to flush the refcount block cache: Input/output error
309
write failed: Input/output error
310
No errors were found on the image.
311
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
312
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
313
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
314
315
Event: refblock_alloc; errno: 28; imm: off; once: off; write
316
-Failed to flush the L2 table cache: No space left on device
317
-Failed to flush the refcount block cache: No space left on device
318
+qemu-io: Failed to flush the L2 table cache: No space left on device
319
+qemu-io: Failed to flush the refcount block cache: No space left on device
320
write failed: No space left on device
321
No errors were found on the image.
322
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
323
324
Event: refblock_alloc; errno: 28; imm: off; once: off; write -b
325
-Failed to flush the L2 table cache: No space left on device
326
-Failed to flush the refcount block cache: No space left on device
327
+qemu-io: Failed to flush the L2 table cache: No space left on device
328
+qemu-io: Failed to flush the refcount block cache: No space left on device
329
write failed: No space left on device
330
No errors were found on the image.
331
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
332
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
333
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
334
335
Event: refblock_alloc_hookup; errno: 28; imm: off; once: off; write
336
-Failed to flush the L2 table cache: No space left on device
337
-Failed to flush the refcount block cache: No space left on device
338
+qemu-io: Failed to flush the L2 table cache: No space left on device
339
+qemu-io: Failed to flush the refcount block cache: No space left on device
340
write failed: No space left on device
341
342
55 leaked clusters were found on the image.
343
@@ -XXX,XX +XXX,XX @@ This means waste of disk space, but no harm to data.
344
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
345
346
Event: refblock_alloc_hookup; errno: 28; imm: off; once: off; write -b
347
-Failed to flush the L2 table cache: No space left on device
348
-Failed to flush the refcount block cache: No space left on device
349
+qemu-io: Failed to flush the L2 table cache: No space left on device
350
+qemu-io: Failed to flush the refcount block cache: No space left on device
351
write failed: No space left on device
352
353
251 leaked clusters were found on the image.
354
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
355
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
356
357
Event: refblock_alloc_write; errno: 28; imm: off; once: off; write
358
-Failed to flush the L2 table cache: No space left on device
359
-Failed to flush the refcount block cache: No space left on device
360
+qemu-io: Failed to flush the L2 table cache: No space left on device
361
+qemu-io: Failed to flush the refcount block cache: No space left on device
362
write failed: No space left on device
363
No errors were found on the image.
364
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
365
366
Event: refblock_alloc_write; errno: 28; imm: off; once: off; write -b
367
-Failed to flush the L2 table cache: No space left on device
368
-Failed to flush the refcount block cache: No space left on device
369
+qemu-io: Failed to flush the L2 table cache: No space left on device
370
+qemu-io: Failed to flush the refcount block cache: No space left on device
371
write failed: No space left on device
372
No errors were found on the image.
373
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
374
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
375
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
376
377
Event: refblock_alloc_write_blocks; errno: 28; imm: off; once: off; write
378
-Failed to flush the L2 table cache: No space left on device
379
-Failed to flush the refcount block cache: No space left on device
380
+qemu-io: Failed to flush the L2 table cache: No space left on device
381
+qemu-io: Failed to flush the refcount block cache: No space left on device
382
write failed: No space left on device
383
384
10 leaked clusters were found on the image.
385
@@ -XXX,XX +XXX,XX @@ This means waste of disk space, but no harm to data.
386
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
387
388
Event: refblock_alloc_write_blocks; errno: 28; imm: off; once: off; write -b
389
-Failed to flush the L2 table cache: No space left on device
390
-Failed to flush the refcount block cache: No space left on device
391
+qemu-io: Failed to flush the L2 table cache: No space left on device
392
+qemu-io: Failed to flush the refcount block cache: No space left on device
393
write failed: No space left on device
394
395
23 leaked clusters were found on the image.
396
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
397
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
398
399
Event: refblock_alloc_write_table; errno: 28; imm: off; once: off; write
400
-Failed to flush the L2 table cache: No space left on device
401
-Failed to flush the refcount block cache: No space left on device
402
+qemu-io: Failed to flush the L2 table cache: No space left on device
403
+qemu-io: Failed to flush the refcount block cache: No space left on device
404
write failed: No space left on device
405
406
10 leaked clusters were found on the image.
407
@@ -XXX,XX +XXX,XX @@ This means waste of disk space, but no harm to data.
408
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
409
410
Event: refblock_alloc_write_table; errno: 28; imm: off; once: off; write -b
411
-Failed to flush the L2 table cache: No space left on device
412
-Failed to flush the refcount block cache: No space left on device
413
+qemu-io: Failed to flush the L2 table cache: No space left on device
414
+qemu-io: Failed to flush the refcount block cache: No space left on device
415
write failed: No space left on device
416
417
23 leaked clusters were found on the image.
418
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
419
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
420
421
Event: refblock_alloc_switch_table; errno: 28; imm: off; once: off; write
422
-Failed to flush the L2 table cache: No space left on device
423
-Failed to flush the refcount block cache: No space left on device
424
+qemu-io: Failed to flush the L2 table cache: No space left on device
425
+qemu-io: Failed to flush the refcount block cache: No space left on device
426
write failed: No space left on device
427
428
10 leaked clusters were found on the image.
429
@@ -XXX,XX +XXX,XX @@ This means waste of disk space, but no harm to data.
430
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
431
432
Event: refblock_alloc_switch_table; errno: 28; imm: off; once: off; write -b
433
-Failed to flush the L2 table cache: No space left on device
434
-Failed to flush the refcount block cache: No space left on device
435
+qemu-io: Failed to flush the L2 table cache: No space left on device
436
+qemu-io: Failed to flush the refcount block cache: No space left on device
437
write failed: No space left on device
438
439
23 leaked clusters were found on the image.
440
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
441
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
442
443
Event: l1_grow_write_table; errno: 5; imm: off; once: off
444
-Failed to flush the L2 table cache: Input/output error
445
-Failed to flush the refcount block cache: Input/output error
446
+qemu-io: Failed to flush the L2 table cache: Input/output error
447
+qemu-io: Failed to flush the refcount block cache: Input/output error
448
write failed: Input/output error
449
No errors were found on the image.
450
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
451
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
452
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
453
454
Event: l1_grow_write_table; errno: 28; imm: off; once: off
455
-Failed to flush the L2 table cache: No space left on device
456
-Failed to flush the refcount block cache: No space left on device
457
+qemu-io: Failed to flush the L2 table cache: No space left on device
458
+qemu-io: Failed to flush the refcount block cache: No space left on device
459
write failed: No space left on device
460
No errors were found on the image.
461
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
462
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
463
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
464
465
Event: l1_grow_activate_table; errno: 5; imm: off; once: off
466
-Failed to flush the L2 table cache: Input/output error
467
-Failed to flush the refcount block cache: Input/output error
468
+qemu-io: Failed to flush the L2 table cache: Input/output error
469
+qemu-io: Failed to flush the refcount block cache: Input/output error
470
write failed: Input/output error
471
472
96 leaked clusters were found on the image.
473
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
474
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
475
476
Event: l1_grow_activate_table; errno: 28; imm: off; once: off
477
-Failed to flush the L2 table cache: No space left on device
478
-Failed to flush the refcount block cache: No space left on device
479
+qemu-io: Failed to flush the L2 table cache: No space left on device
480
+qemu-io: Failed to flush the refcount block cache: No space left on device
481
write failed: No space left on device
482
483
96 leaked clusters were found on the image.
484
diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out
485
index XXXXXXX..XXXXXXX 100644
486
--- a/tests/qemu-iotests/060.out
487
+++ b/tests/qemu-iotests/060.out
488
@@ -XXX,XX +XXX,XX @@ Format specific information:
489
lazy refcounts: false
490
refcount bits: 16
491
corrupt: true
492
-can't open device TEST_DIR/t.IMGFMT: IMGFMT: Image is corrupt; cannot be opened read/write
493
+qemu-io: can't open device TEST_DIR/t.IMGFMT: IMGFMT: Image is corrupt; cannot be opened read/write
494
no file open, try 'help open'
495
read 512/512 bytes at offset 0
496
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
497
@@ -XXX,XX +XXX,XX @@ No errors were found on the image.
498
=== Testing zero refcount table size ===
499
500
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
501
-can't open device TEST_DIR/t.IMGFMT: Image does not contain a reference count table
502
+qemu-io: can't open device TEST_DIR/t.IMGFMT: Image does not contain a reference count table
503
ERROR cluster 0 refcount=0 reference=1
504
ERROR cluster 3 refcount=0 reference=1
505
Rebuilding refcount structure
506
@@ -XXX,XX +XXX,XX @@ Can't get refcount for cluster 2: Input/output error
507
Can't get refcount for cluster 3: Input/output error
508
Rebuilding refcount structure
509
Repairing cluster 1 refcount=1 reference=0
510
-can't open device TEST_DIR/t.IMGFMT: Could not repair dirty image: Input/output error
511
+qemu-io: can't open device TEST_DIR/t.IMGFMT: Could not repair dirty image: Input/output error
512
--- Repairing ---
513
Leaked cluster 1 refcount=1 reference=0
514
Repairing cluster 1 refcount=1 reference=0
515
diff --git a/tests/qemu-iotests/069.out b/tests/qemu-iotests/069.out
516
index XXXXXXX..XXXXXXX 100644
517
--- a/tests/qemu-iotests/069.out
518
+++ b/tests/qemu-iotests/069.out
519
@@ -XXX,XX +XXX,XX @@ QA output created by 069
520
521
Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=131072
522
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072 backing_file=TEST_DIR/t.IMGFMT.base
523
-can't open device TEST_DIR/t.IMGFMT: Could not open backing file: Could not open 'TEST_DIR/t.IMGFMT.base': No such file or directory
524
+qemu-io: can't open device TEST_DIR/t.IMGFMT: Could not open backing file: Could not open 'TEST_DIR/t.IMGFMT.base': No such file or directory
525
*** done
526
diff --git a/tests/qemu-iotests/070.out b/tests/qemu-iotests/070.out
527
index XXXXXXX..XXXXXXX 100644
528
--- a/tests/qemu-iotests/070.out
529
+++ b/tests/qemu-iotests/070.out
530
@@ -XXX,XX +XXX,XX @@
531
QA output created by 070
532
533
=== Verify open image read-only fails, due to dirty log ===
534
-can't open device TEST_DIR/iotest-dirtylog-10G-4M.vhdx: VHDX image file 'TEST_DIR/iotest-dirtylog-10G-4M.vhdx' opened read-only, but contains a log that needs to be replayed
535
+qemu-io: can't open device TEST_DIR/iotest-dirtylog-10G-4M.vhdx: VHDX image file 'TEST_DIR/iotest-dirtylog-10G-4M.vhdx' opened read-only, but contains a log that needs to be replayed
536
To replay the log, run:
537
qemu-img check -r all 'TEST_DIR/iotest-dirtylog-10G-4M.vhdx'
538
=== Verify open image replays log ===
539
diff --git a/tests/qemu-iotests/075.out b/tests/qemu-iotests/075.out
540
index XXXXXXX..XXXXXXX 100644
541
--- a/tests/qemu-iotests/075.out
542
+++ b/tests/qemu-iotests/075.out
543
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 1048064
544
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
545
546
== block_size must be a multiple of 512 ==
547
-can't open device TEST_DIR/simple-pattern.cloop: block_size 513 must be a multiple of 512
548
+qemu-io: can't open device TEST_DIR/simple-pattern.cloop: block_size 513 must be a multiple of 512
549
550
== block_size cannot be zero ==
551
-can't open device TEST_DIR/simple-pattern.cloop: block_size cannot be zero
552
+qemu-io: can't open device TEST_DIR/simple-pattern.cloop: block_size cannot be zero
553
554
== huge block_size ===
555
-can't open device TEST_DIR/simple-pattern.cloop: block_size 4294966784 must be 64 MB or less
556
+qemu-io: can't open device TEST_DIR/simple-pattern.cloop: block_size 4294966784 must be 64 MB or less
557
558
== offsets_size overflow ===
559
-can't open device TEST_DIR/simple-pattern.cloop: n_blocks 4294967295 must be 536870911 or less
560
+qemu-io: can't open device TEST_DIR/simple-pattern.cloop: n_blocks 4294967295 must be 536870911 or less
561
562
== refuse images that require too many offsets ===
563
-can't open device TEST_DIR/simple-pattern.cloop: image requires too many offsets, try increasing block size
564
+qemu-io: can't open device TEST_DIR/simple-pattern.cloop: image requires too many offsets, try increasing block size
565
566
== refuse images with non-monotonically increasing offsets ==
567
-can't open device TEST_DIR/simple-pattern.cloop: offsets not monotonically increasing at index 1, image file is corrupt
568
+qemu-io: can't open device TEST_DIR/simple-pattern.cloop: offsets not monotonically increasing at index 1, image file is corrupt
569
570
== refuse images with invalid compressed block size ==
571
-can't open device TEST_DIR/simple-pattern.cloop: invalid compressed block size at index 1, image file is corrupt
572
+qemu-io: can't open device TEST_DIR/simple-pattern.cloop: invalid compressed block size at index 1, image file is corrupt
573
*** done
574
diff --git a/tests/qemu-iotests/076.out b/tests/qemu-iotests/076.out
575
index XXXXXXX..XXXXXXX 100644
576
--- a/tests/qemu-iotests/076.out
577
+++ b/tests/qemu-iotests/076.out
578
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 0
579
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
580
581
== Negative catalog size ==
582
-can't open device TEST_DIR/parallels-v1: Catalog too large
583
+qemu-io: can't open device TEST_DIR/parallels-v1: Catalog too large
584
585
== Overflow in catalog allocation ==
586
-can't open device TEST_DIR/parallels-v1: Catalog too large
587
+qemu-io: can't open device TEST_DIR/parallels-v1: Catalog too large
588
589
== Zero sectors per track ==
590
-can't open device TEST_DIR/parallels-v1: Invalid image: Zero sectors per track
591
+qemu-io: can't open device TEST_DIR/parallels-v1: Invalid image: Zero sectors per track
592
593
== Read from a valid v2 image ==
594
read 65536/65536 bytes at offset 0
595
diff --git a/tests/qemu-iotests/078.out b/tests/qemu-iotests/078.out
596
index XXXXXXX..XXXXXXX 100644
597
--- a/tests/qemu-iotests/078.out
598
+++ b/tests/qemu-iotests/078.out
599
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 0
600
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
601
602
== Negative catalog size ==
603
-can't open device TEST_DIR/empty.bochs: Catalog size is too large
604
+qemu-io: can't open device TEST_DIR/empty.bochs: Catalog size is too large
605
606
== Overflow for catalog size * sizeof(uint32_t) ==
607
-can't open device TEST_DIR/empty.bochs: Catalog size is too large
608
+qemu-io: can't open device TEST_DIR/empty.bochs: Catalog size is too large
609
610
== Too small catalog bitmap for image size ==
611
-can't open device TEST_DIR/empty.bochs: Catalog size is too small for this disk size
612
-can't open device TEST_DIR/empty.bochs: Catalog size is too small for this disk size
613
+qemu-io: can't open device TEST_DIR/empty.bochs: Catalog size is too small for this disk size
614
+qemu-io: can't open device TEST_DIR/empty.bochs: Catalog size is too small for this disk size
615
616
== Negative extent size ==
617
-can't open device TEST_DIR/empty.bochs: Extent size 2147483648 is too large
618
+qemu-io: can't open device TEST_DIR/empty.bochs: Extent size 2147483648 is too large
619
620
== Zero extent size ==
621
-can't open device TEST_DIR/empty.bochs: Extent size must be at least 512
622
+qemu-io: can't open device TEST_DIR/empty.bochs: Extent size must be at least 512
623
*** done
624
diff --git a/tests/qemu-iotests/080.out b/tests/qemu-iotests/080.out
625
index XXXXXXX..XXXXXXX 100644
626
--- a/tests/qemu-iotests/080.out
627
+++ b/tests/qemu-iotests/080.out
628
@@ -XXX,XX +XXX,XX @@ QA output created by 080
629
630
== Huge header size ==
631
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
632
-can't open device TEST_DIR/t.qcow2: qcow2 header exceeds cluster size
633
-can't open device TEST_DIR/t.qcow2: qcow2 header exceeds cluster size
634
+qemu-io: can't open device TEST_DIR/t.qcow2: qcow2 header exceeds cluster size
635
+qemu-io: can't open device TEST_DIR/t.qcow2: qcow2 header exceeds cluster size
636
637
== Huge unknown header extension ==
638
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
639
-can't open device TEST_DIR/t.qcow2: Invalid backing file offset
640
-can't open device TEST_DIR/t.qcow2: Header extension too large
641
-can't open device TEST_DIR/t.qcow2: Header extension too large
642
+qemu-io: can't open device TEST_DIR/t.qcow2: Invalid backing file offset
643
+qemu-io: can't open device TEST_DIR/t.qcow2: Header extension too large
644
+qemu-io: can't open device TEST_DIR/t.qcow2: Header extension too large
645
646
== Huge refcount table size ==
647
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
648
-can't open device TEST_DIR/t.qcow2: Reference count table too large
649
-can't open device TEST_DIR/t.qcow2: Reference count table too large
650
+qemu-io: can't open device TEST_DIR/t.qcow2: Reference count table too large
651
+qemu-io: can't open device TEST_DIR/t.qcow2: Reference count table too large
652
653
== Misaligned refcount table ==
654
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
655
-can't open device TEST_DIR/t.qcow2: Reference count table offset invalid
656
+qemu-io: can't open device TEST_DIR/t.qcow2: Reference count table offset invalid
657
658
== Huge refcount offset ==
659
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
660
-can't open device TEST_DIR/t.qcow2: Reference count table offset invalid
661
+qemu-io: can't open device TEST_DIR/t.qcow2: Reference count table offset invalid
662
663
== Invalid snapshot table ==
664
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
665
-can't open device TEST_DIR/t.qcow2: Snapshot table too large
666
-can't open device TEST_DIR/t.qcow2: Snapshot table too large
667
-can't open device TEST_DIR/t.qcow2: Snapshot table offset invalid
668
-can't open device TEST_DIR/t.qcow2: Snapshot table offset invalid
669
+qemu-io: can't open device TEST_DIR/t.qcow2: Snapshot table too large
670
+qemu-io: can't open device TEST_DIR/t.qcow2: Snapshot table too large
671
+qemu-io: can't open device TEST_DIR/t.qcow2: Snapshot table offset invalid
672
+qemu-io: can't open device TEST_DIR/t.qcow2: Snapshot table offset invalid
673
674
== Hitting snapshot table size limit ==
675
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
676
@@ -XXX,XX +XXX,XX @@ read 512/512 bytes at offset 0
677
678
== Invalid L1 table ==
679
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
680
-can't open device TEST_DIR/t.qcow2: Active L1 table too large
681
-can't open device TEST_DIR/t.qcow2: Active L1 table too large
682
-can't open device TEST_DIR/t.qcow2: Active L1 table offset invalid
683
-can't open device TEST_DIR/t.qcow2: Active L1 table offset invalid
684
+qemu-io: can't open device TEST_DIR/t.qcow2: Active L1 table too large
685
+qemu-io: can't open device TEST_DIR/t.qcow2: Active L1 table too large
686
+qemu-io: can't open device TEST_DIR/t.qcow2: Active L1 table offset invalid
687
+qemu-io: can't open device TEST_DIR/t.qcow2: Active L1 table offset invalid
688
689
== Invalid L1 table (with internal snapshot in the image) ==
690
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
691
@@ -XXX,XX +XXX,XX @@ qemu-img: Could not open 'TEST_DIR/t.IMGFMT': L1 table is too small
692
693
== Invalid backing file size ==
694
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
695
-can't open device TEST_DIR/t.qcow2: Backing file name too long
696
+qemu-io: can't open device TEST_DIR/t.qcow2: Backing file name too long
697
698
== Invalid L2 entry (huge physical offset) ==
699
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
700
@@ -XXX,XX +XXX,XX @@ wrote 512/512 bytes at offset 0
701
qemu-img: Failed to load snapshot: Snapshot L1 table offset invalid
702
qemu-img: Snapshot L1 table offset invalid
703
qemu-img: Failed to turn zero into data clusters: Invalid argument
704
-Failed to flush the refcount block cache: Invalid argument
705
+qemu-io: Failed to flush the refcount block cache: Invalid argument
706
write failed: Invalid argument
707
qemu-img: Snapshot L1 table offset invalid
708
qemu-img: Could not apply snapshot 'test': Failed to load snapshot: Invalid argument
709
@@ -XXX,XX +XXX,XX @@ wrote 512/512 bytes at offset 0
710
qemu-img: Failed to load snapshot: Snapshot L1 table too large
711
qemu-img: Snapshot L1 table too large
712
qemu-img: Failed to turn zero into data clusters: File too large
713
-Failed to flush the refcount block cache: File too large
714
+qemu-io: Failed to flush the refcount block cache: File too large
715
write failed: File too large
716
qemu-img: Snapshot L1 table too large
717
qemu-img: Could not apply snapshot 'test': Failed to load snapshot: File too large
718
diff --git a/tests/qemu-iotests/081.out b/tests/qemu-iotests/081.out
719
index XXXXXXX..XXXXXXX 100644
720
--- a/tests/qemu-iotests/081.out
721
+++ b/tests/qemu-iotests/081.out
722
@@ -XXX,XX +XXX,XX @@ read 10485760/10485760 bytes at offset 0
723
10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
724
725
== checking the blkverify mode with invalid settings ==
726
-can't open: blkverify=on can only be set if there are exactly two files and vote-threshold is 2
727
+qemu-io: can't open: blkverify=on can only be set if there are exactly two files and vote-threshold is 2
728
729
== dynamically adding a child to a quorum ==
730
Testing:
731
diff --git a/tests/qemu-iotests/088.out b/tests/qemu-iotests/088.out
732
index XXXXXXX..XXXXXXX 100644
733
--- a/tests/qemu-iotests/088.out
734
+++ b/tests/qemu-iotests/088.out
735
@@ -XXX,XX +XXX,XX @@ QA output created by 088
736
737
== Invalid block size ==
738
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
739
-can't open device TEST_DIR/t.vpc: Invalid block size 0
740
-can't open device TEST_DIR/t.vpc: Invalid block size 0
741
-can't open device TEST_DIR/t.vpc: Invalid block size 128
742
-can't open device TEST_DIR/t.vpc: Invalid block size 128
743
-can't open device TEST_DIR/t.vpc: Invalid block size 305419896
744
-can't open device TEST_DIR/t.vpc: Invalid block size 305419896
745
+qemu-io: can't open device TEST_DIR/t.vpc: Invalid block size 0
746
+qemu-io: can't open device TEST_DIR/t.vpc: Invalid block size 0
747
+qemu-io: can't open device TEST_DIR/t.vpc: Invalid block size 128
748
+qemu-io: can't open device TEST_DIR/t.vpc: Invalid block size 128
749
+qemu-io: can't open device TEST_DIR/t.vpc: Invalid block size 305419896
750
+qemu-io: can't open device TEST_DIR/t.vpc: Invalid block size 305419896
751
*** done
752
diff --git a/tests/qemu-iotests/103.out b/tests/qemu-iotests/103.out
753
index XXXXXXX..XXXXXXX 100644
754
--- a/tests/qemu-iotests/103.out
755
+++ b/tests/qemu-iotests/103.out
756
@@ -XXX,XX +XXX,XX @@ wrote 65536/65536 bytes at offset 0
757
758
=== Testing invalid option combinations ===
759
760
-can't open device TEST_DIR/t.IMGFMT: cache-size, l2-cache-size and refcount-cache-size may not be set at the same time
761
-can't open device TEST_DIR/t.IMGFMT: l2-cache-size may not exceed cache-size
762
-can't open device TEST_DIR/t.IMGFMT: refcount-cache-size may not exceed cache-size
763
-can't open device TEST_DIR/t.IMGFMT: cache-size, l2-cache-size and refcount-cache-size may not be set at the same time
764
-can't open device TEST_DIR/t.IMGFMT: L2 cache entry size must be a power of two between 512 and the cluster size (65536)
765
-can't open device TEST_DIR/t.IMGFMT: L2 cache entry size must be a power of two between 512 and the cluster size (65536)
766
-can't open device TEST_DIR/t.IMGFMT: L2 cache entry size must be a power of two between 512 and the cluster size (65536)
767
+qemu-io: can't open device TEST_DIR/t.IMGFMT: cache-size, l2-cache-size and refcount-cache-size may not be set at the same time
768
+qemu-io: can't open device TEST_DIR/t.IMGFMT: l2-cache-size may not exceed cache-size
769
+qemu-io: can't open device TEST_DIR/t.IMGFMT: refcount-cache-size may not exceed cache-size
770
+qemu-io: can't open device TEST_DIR/t.IMGFMT: cache-size, l2-cache-size and refcount-cache-size may not be set at the same time
771
+qemu-io: can't open device TEST_DIR/t.IMGFMT: L2 cache entry size must be a power of two between 512 and the cluster size (65536)
772
+qemu-io: can't open device TEST_DIR/t.IMGFMT: L2 cache entry size must be a power of two between 512 and the cluster size (65536)
773
+qemu-io: can't open device TEST_DIR/t.IMGFMT: L2 cache entry size must be a power of two between 512 and the cluster size (65536)
774
775
=== Testing valid option combinations ===
776
777
diff --git a/tests/qemu-iotests/114.out b/tests/qemu-iotests/114.out
778
index XXXXXXX..XXXXXXX 100644
779
--- a/tests/qemu-iotests/114.out
780
+++ b/tests/qemu-iotests/114.out
781
@@ -XXX,XX +XXX,XX @@ virtual size: 64M (67108864 bytes)
782
cluster_size: 65536
783
backing file: TEST_DIR/t.IMGFMT.base
784
backing file format: foo
785
-can't open device TEST_DIR/t.qcow2: Could not open backing file: Unknown driver 'foo'
786
+qemu-io: can't open device TEST_DIR/t.qcow2: Could not open backing file: Unknown driver 'foo'
787
no file open, try 'help open'
788
read 4096/4096 bytes at offset 0
789
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
790
diff --git a/tests/qemu-iotests/116.out b/tests/qemu-iotests/116.out
791
index XXXXXXX..XXXXXXX 100644
792
--- a/tests/qemu-iotests/116.out
793
+++ b/tests/qemu-iotests/116.out
794
@@ -XXX,XX +XXX,XX @@ QA output created by 116
795
796
== truncated header cluster ==
797
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
798
-can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument
799
+qemu-io: can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument
800
801
== invalid header magic ==
802
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
803
-can't open device TEST_DIR/t.qed: Image not in QED format
804
+qemu-io: can't open device TEST_DIR/t.qed: Image not in QED format
805
806
== invalid cluster size ==
807
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
808
-can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument
809
+qemu-io: can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument
810
811
== invalid table size ==
812
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
813
-can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument
814
+qemu-io: can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument
815
816
== invalid header size ==
817
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
818
-can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument
819
+qemu-io: can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument
820
821
== invalid L1 table offset ==
822
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
823
-can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument
824
+qemu-io: can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument
825
826
== invalid image size ==
827
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
828
-can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument
829
+qemu-io: can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument
830
*** done
831
diff --git a/tests/qemu-iotests/131.out b/tests/qemu-iotests/131.out
832
index XXXXXXX..XXXXXXX 100644
833
--- a/tests/qemu-iotests/131.out
834
+++ b/tests/qemu-iotests/131.out
835
@@ -XXX,XX +XXX,XX @@ read 32768/32768 bytes at offset 163840
836
read 32768/32768 bytes at offset 0
837
32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
838
== Corrupt image ==
839
-can't open device TEST_DIR/t.parallels: parallels: Image was not closed correctly; cannot be opened read/write
840
+qemu-io: can't open device TEST_DIR/t.parallels: parallels: Image was not closed correctly; cannot be opened read/write
841
ERROR image was not closed correctly
842
843
1 errors were found on the image.
844
diff --git a/tests/qemu-iotests/133.out b/tests/qemu-iotests/133.out
845
index XXXXXXX..XXXXXXX 100644
846
--- a/tests/qemu-iotests/133.out
847
+++ b/tests/qemu-iotests/133.out
848
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t
849
850
=== Check that node-name can't be changed ===
851
852
-Cannot change the option 'node-name'
853
-Cannot change the option 'node-name'
854
-Cannot change the option 'node-name'
855
+qemu-io: Cannot change the option 'node-name'
856
+qemu-io: Cannot change the option 'node-name'
857
+qemu-io: Cannot change the option 'node-name'
858
859
=== Check that unchanged node-name is okay ===
860
861
862
=== Check that driver can't be changed ===
863
864
-Cannot change the option 'driver'
865
-Cannot change the option 'driver'
866
-Cannot change the option 'driver'
867
+qemu-io: Cannot change the option 'driver'
868
+qemu-io: Cannot change the option 'driver'
869
+qemu-io: Cannot change the option 'driver'
870
871
=== Check that unchanged driver is okay ===
872
873
@@ -XXX,XX +XXX,XX @@ format name: null-co
874
875
=== Check that mixing -c/-r/-w and their corresponding options is forbidden ===
876
877
-Cannot set both -r/-w and 'read-only'
878
-Cannot set both -r/-w and 'read-only'
879
-Cannot set both -c and the cache options
880
-Cannot set both -c and the cache options
881
-Cannot set both -c and the cache options
882
+qemu-io: Cannot set both -r/-w and 'read-only'
883
+qemu-io: Cannot set both -r/-w and 'read-only'
884
+qemu-io: Cannot set both -c and the cache options
885
+qemu-io: Cannot set both -c and the cache options
886
+qemu-io: Cannot set both -c and the cache options
887
888
=== Check that invalid options are handled correctly ===
889
890
-Parameter 'read-only' expects 'on' or 'off'
891
-Parameter 'cache.no-flush' expects 'on' or 'off'
892
-Parameter 'cache.direct' expects 'on' or 'off'
893
-Parameter 'auto-read-only' expects 'on' or 'off'
894
+qemu-io: Parameter 'read-only' expects 'on' or 'off'
895
+qemu-io: Parameter 'cache.no-flush' expects 'on' or 'off'
896
+qemu-io: Parameter 'cache.direct' expects 'on' or 'off'
897
+qemu-io: Parameter 'auto-read-only' expects 'on' or 'off'
898
*** done
899
diff --git a/tests/qemu-iotests/137.out b/tests/qemu-iotests/137.out
900
index XXXXXXX..XXXXXXX 100644
901
--- a/tests/qemu-iotests/137.out
902
+++ b/tests/qemu-iotests/137.out
903
@@ -XXX,XX +XXX,XX @@ read 33554432/33554432 bytes at offset 0
904
905
=== Try setting some invalid values ===
906
907
-Parameter 'lazy-refcounts' expects 'on' or 'off'
908
-cache-size, l2-cache-size and refcount-cache-size may not be set at the same time
909
-l2-cache-size may not exceed cache-size
910
-refcount-cache-size may not exceed cache-size
911
-L2 cache entry size must be a power of two between 512 and the cluster size (65536)
912
-L2 cache entry size must be a power of two between 512 and the cluster size (65536)
913
-Refcount cache size too big
914
-Conflicting values for qcow2 options 'overlap-check' ('constant') and 'overlap-check.template' ('all')
915
-Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of the following: none, constant, cached, all
916
-Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of the following: none, constant, cached, all
917
-Cache clean interval too big
918
+qemu-io: Parameter 'lazy-refcounts' expects 'on' or 'off'
919
+qemu-io: cache-size, l2-cache-size and refcount-cache-size may not be set at the same time
920
+qemu-io: l2-cache-size may not exceed cache-size
921
+qemu-io: refcount-cache-size may not exceed cache-size
922
+qemu-io: L2 cache entry size must be a power of two between 512 and the cluster size (65536)
923
+qemu-io: L2 cache entry size must be a power of two between 512 and the cluster size (65536)
924
+qemu-io: Refcount cache size too big
925
+qemu-io: Conflicting values for qcow2 options 'overlap-check' ('constant') and 'overlap-check.template' ('all')
926
+qemu-io: Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of the following: none, constant, cached, all
927
+qemu-io: Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of the following: none, constant, cached, all
928
+qemu-io: Cache clean interval too big
929
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=36028797018963968
930
-L2 cache size too big
931
+qemu-io: L2 cache size too big
932
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
933
934
=== Test transaction semantics ===
935
936
-Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of the following: none, constant, cached, all
937
+qemu-io: Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of the following: none, constant, cached, all
938
wrote 512/512 bytes at offset 0
939
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
940
./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
941
@@ -XXX,XX +XXX,XX @@ incompatible_features 0x0
942
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
943
wrote 65536/65536 bytes at offset 0
944
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
945
-Parameter 'lazy-refcounts' expects 'on' or 'off'
946
+qemu-io: Parameter 'lazy-refcounts' expects 'on' or 'off'
947
qcow2: Marking image as corrupt: Preventing invalid write on metadata (overlaps with qcow2_header); further corruption events will be suppressed
948
write failed: Input/output error
949
*** done
950
diff --git a/tests/qemu-iotests/140.out b/tests/qemu-iotests/140.out
951
index XXXXXXX..XXXXXXX 100644
952
--- a/tests/qemu-iotests/140.out
953
+++ b/tests/qemu-iotests/140.out
954
@@ -XXX,XX +XXX,XX @@ wrote 65536/65536 bytes at offset 0
955
read 65536/65536 bytes at offset 0
956
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
957
{"return": {}}
958
-can't open device nbd+unix:///drv?socket=TEST_DIR/nbd: Requested export not available
959
+qemu-io: can't open device nbd+unix:///drv?socket=TEST_DIR/nbd: Requested export not available
960
server reported: export 'drv' not present
961
{"return": {}}
962
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
963
diff --git a/tests/qemu-iotests/143.out b/tests/qemu-iotests/143.out
964
index XXXXXXX..XXXXXXX 100644
965
--- a/tests/qemu-iotests/143.out
966
+++ b/tests/qemu-iotests/143.out
967
@@ -XXX,XX +XXX,XX @@
968
QA output created by 143
969
{"return": {}}
970
{"return": {}}
971
-can't open device nbd+unix:///no_such_export?socket=TEST_DIR/nbd: Requested export not available
972
+qemu-io: can't open device nbd+unix:///no_such_export?socket=TEST_DIR/nbd: Requested export not available
973
server reported: export 'no_such_export' not present
974
{"return": {}}
975
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
976
diff --git a/tests/qemu-iotests/153.out b/tests/qemu-iotests/153.out
977
index XXXXXXX..XXXXXXX 100644
978
--- a/tests/qemu-iotests/153.out
979
+++ b/tests/qemu-iotests/153.out
980
@@ -XXX,XX +XXX,XX @@ Is another process using the image [TEST_DIR/t.qcow2]?
981
== Running utility commands ==
982
983
_qemu_io_wrapper -c read 0 512 TEST_DIR/t.qcow2
984
-can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
985
+qemu-io: can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
986
Is another process using the image [TEST_DIR/t.qcow2]?
987
988
_qemu_io_wrapper -r -c read 0 512 TEST_DIR/t.qcow2
989
-can't open device TEST_DIR/t.qcow2: Failed to get shared "write" lock
990
+qemu-io: can't open device TEST_DIR/t.qcow2: Failed to get shared "write" lock
991
Is another process using the image [TEST_DIR/t.qcow2]?
992
993
_qemu_io_wrapper -c open TEST_DIR/t.qcow2 -c read 0 512
994
-can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
995
+qemu-io: can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
996
Is another process using the image [TEST_DIR/t.qcow2]?
997
no file open, try 'help open'
998
999
_qemu_io_wrapper -c open -r TEST_DIR/t.qcow2 -c read 0 512
1000
-can't open device TEST_DIR/t.qcow2: Failed to get shared "write" lock
1001
+qemu-io: can't open device TEST_DIR/t.qcow2: Failed to get shared "write" lock
1002
Is another process using the image [TEST_DIR/t.qcow2]?
1003
no file open, try 'help open'
1004
1005
@@ -XXX,XX +XXX,XX @@ file format: IMGFMT
1006
== Running utility commands -U ==
1007
1008
_qemu_io_wrapper -U -c read 0 512 TEST_DIR/t.qcow2
1009
-can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
1010
+qemu-io: can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
1011
1012
_qemu_io_wrapper -U -r -c read 0 512 TEST_DIR/t.qcow2
1013
1014
_qemu_io_wrapper -c open -U TEST_DIR/t.qcow2 -c read 0 512
1015
-can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
1016
+qemu-io: can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
1017
no file open, try 'help open'
1018
1019
_qemu_io_wrapper -c open -r -U TEST_DIR/t.qcow2 -c read 0 512
1020
@@ -XXX,XX +XXX,XX @@ Is another process using the image [TEST_DIR/t.qcow2]?
1021
== Running utility commands ==
1022
1023
_qemu_io_wrapper -c read 0 512 TEST_DIR/t.qcow2
1024
-can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
1025
+qemu-io: can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
1026
Is another process using the image [TEST_DIR/t.qcow2]?
1027
1028
_qemu_io_wrapper -r -c read 0 512 TEST_DIR/t.qcow2
1029
1030
_qemu_io_wrapper -c open TEST_DIR/t.qcow2 -c read 0 512
1031
-can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
1032
+qemu-io: can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
1033
Is another process using the image [TEST_DIR/t.qcow2]?
1034
no file open, try 'help open'
1035
1036
@@ -XXX,XX +XXX,XX @@ file format: IMGFMT
1037
== Running utility commands -U ==
1038
1039
_qemu_io_wrapper -U -c read 0 512 TEST_DIR/t.qcow2
1040
-can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
1041
+qemu-io: can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
1042
1043
_qemu_io_wrapper -U -r -c read 0 512 TEST_DIR/t.qcow2
1044
1045
_qemu_io_wrapper -c open -U TEST_DIR/t.qcow2 -c read 0 512
1046
-can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
1047
+qemu-io: can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
1048
no file open, try 'help open'
1049
1050
_qemu_io_wrapper -c open -r -U TEST_DIR/t.qcow2 -c read 0 512
1051
@@ -XXX,XX +XXX,XX @@ file format: IMGFMT
1052
== Running utility commands -U ==
1053
1054
_qemu_io_wrapper -U -c read 0 512 TEST_DIR/t.qcow2
1055
-can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
1056
+qemu-io: can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
1057
1058
_qemu_io_wrapper -U -r -c read 0 512 TEST_DIR/t.qcow2
1059
1060
_qemu_io_wrapper -c open -U TEST_DIR/t.qcow2 -c read 0 512
1061
-can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
1062
+qemu-io: can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
1063
no file open, try 'help open'
1064
1065
_qemu_io_wrapper -c open -r -U TEST_DIR/t.qcow2 -c read 0 512
1066
@@ -XXX,XX +XXX,XX @@ Adding drive
1067
{"return": "OKrn"}
1068
1069
_qemu_io_wrapper TEST_DIR/t.qcow2 -c write 0 512
1070
-can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
1071
+qemu-io: can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
1072
Is another process using the image [TEST_DIR/t.qcow2]?
1073
Creating overlay with qemu-img when the guest is running should be allowed
1074
1075
@@ -XXX,XX +XXX,XX @@ _qemu_img_wrapper info TEST_DIR/t.qcow2
1076
{"return": ""}
1077
1078
_qemu_io_wrapper TEST_DIR/t.qcow2 -c write 0 512
1079
-can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
1080
+qemu-io: can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
1081
Is another process using the image [TEST_DIR/t.qcow2]?
1082
Closing the other
1083
{"return": ""}
1084
@@ -XXX,XX +XXX,XX @@ qemu-img: --force-share/-U conflicts with image options
1085
No conflict:
1086
1087
Conflict:
1088
--U conflicts with image options
1089
+qemu-io: -U conflicts with image options
1090
*** done
1091
diff --git a/tests/qemu-iotests/187.out b/tests/qemu-iotests/187.out
1092
index XXXXXXX..XXXXXXX 100644
1093
--- a/tests/qemu-iotests/187.out
1094
+++ b/tests/qemu-iotests/187.out
1095
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
1096
1097
Start from read-only
1098
1099
-Block node is read-only
1100
+qemu-io: Block node is read-only
1101
wrote 65536/65536 bytes at offset 0
1102
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1103
-Block node is read-only
1104
+qemu-io: Block node is read-only
1105
1106
Start from read-write
1107
1108
wrote 65536/65536 bytes at offset 0
1109
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1110
-Block node is read-only
1111
+qemu-io: Block node is read-only
1112
wrote 65536/65536 bytes at offset 0
1113
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1114
*** done
1115
diff --git a/tests/qemu-iotests/188.out b/tests/qemu-iotests/188.out
1116
index XXXXXXX..XXXXXXX 100644
1117
--- a/tests/qemu-iotests/188.out
1118
+++ b/tests/qemu-iotests/188.out
1119
@@ -XXX,XX +XXX,XX @@ read 16777216/16777216 bytes at offset 0
1120
16 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1121
1122
== verify open failure with wrong password ==
1123
-can't open: Invalid password, cannot unlock any keyslot
1124
+qemu-io: can't open: Invalid password, cannot unlock any keyslot
1125
*** done
1126
diff --git a/tests/qemu-iotests/197.out b/tests/qemu-iotests/197.out
1127
index XXXXXXX..XXXXXXX 100644
1128
--- a/tests/qemu-iotests/197.out
1129
+++ b/tests/qemu-iotests/197.out
1130
@@ -XXX,XX +XXX,XX @@ read 2147483136/2147483136 bytes at offset 1024
1131
2 GiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1132
read 1024/1024 bytes at offset 3221226496
1133
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1134
-can't open device TEST_DIR/t.wrap.qcow2: Can't use copy-on-read on read-only device
1135
+qemu-io: can't open device TEST_DIR/t.wrap.qcow2: Can't use copy-on-read on read-only device
1136
2 GiB (0x80010000) bytes allocated at offset 0 bytes (0x0)
1137
1023.938 MiB (0x3fff0000) bytes not allocated at offset 2 GiB (0x80010000)
1138
64 KiB (0x10000) bytes allocated at offset 3 GiB (0xc0000000)
1139
diff --git a/tests/qemu-iotests/205 b/tests/qemu-iotests/205
1140
index XXXXXXX..XXXXXXX 100755
1141
--- a/tests/qemu-iotests/205
1142
+++ b/tests/qemu-iotests/205
1143
@@ -XXX,XX +XXX,XX @@ class TestNbdServerRemove(iotests.QMPTestCase):
1144
1145
def assertConnectFailed(self, qemu_io_output):
1146
self.assertEqual(filter_qemu_io(qemu_io_output).strip(),
1147
- "can't open device " + nbd_uri +
1148
+ "qemu-io: can't open device " + nbd_uri +
1149
": Requested export not available\n"
1150
"server reported: export 'exp' not present")
1151
1152
diff --git a/tests/qemu-iotests/215.out b/tests/qemu-iotests/215.out
1153
index XXXXXXX..XXXXXXX 100644
1154
--- a/tests/qemu-iotests/215.out
1155
+++ b/tests/qemu-iotests/215.out
1156
@@ -XXX,XX +XXX,XX @@ read 2147483136/2147483136 bytes at offset 1024
1157
2 GiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1158
read 1024/1024 bytes at offset 3221226496
1159
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1160
-can't open device TEST_DIR/t.wrap.qcow2: Block node is read-only
1161
+qemu-io: can't open device TEST_DIR/t.wrap.qcow2: Block node is read-only
1162
2 GiB (0x80010000) bytes allocated at offset 0 bytes (0x0)
1163
1023.938 MiB (0x3fff0000) bytes not allocated at offset 2 GiB (0x80010000)
1164
64 KiB (0x10000) bytes allocated at offset 3 GiB (0xc0000000)
1165
diff --git a/tests/qemu-iotests/226.out b/tests/qemu-iotests/226.out
1166
index XXXXXXX..XXXXXXX 100644
1167
--- a/tests/qemu-iotests/226.out
1168
+++ b/tests/qemu-iotests/226.out
1169
@@ -XXX,XX +XXX,XX @@ QA output created by 226
1170
=== Testing with driver:file ===
1171
1172
== Testing RO ==
1173
-can't open: A regular file was expected by the 'file' driver, but something else was given
1174
-warning: Opening a character device as a file using the 'file' driver is deprecated
1175
+qemu-io: can't open: A regular file was expected by the 'file' driver, but something else was given
1176
+qemu-io: warning: Opening a character device as a file using the 'file' driver is deprecated
1177
== Testing RW ==
1178
-can't open: Could not open 'TEST_DIR/t.IMGFMT': Is a directory
1179
-warning: Opening a character device as a file using the 'file' driver is deprecated
1180
+qemu-io: can't open: Could not open 'TEST_DIR/t.IMGFMT': Is a directory
1181
+qemu-io: warning: Opening a character device as a file using the 'file' driver is deprecated
1182
1183
=== Testing with driver:host_device ===
1184
1185
== Testing RO ==
1186
-can't open: 'host_device' driver expects either a character or block device
1187
+qemu-io: can't open: 'host_device' driver expects either a character or block device
1188
== Testing RW ==
1189
-can't open: Could not open 'TEST_DIR/t.IMGFMT': Is a directory
1190
+qemu-io: can't open: Could not open 'TEST_DIR/t.IMGFMT': Is a directory
1191
1192
=== Testing with driver:host_cdrom ===
1193
1194
== Testing RO ==
1195
-can't open: 'host_cdrom' driver expects either a character or block device
1196
+qemu-io: can't open: 'host_cdrom' driver expects either a character or block device
1197
== Testing RW ==
1198
-can't open: Could not open 'TEST_DIR/t.IMGFMT': Is a directory
1199
+qemu-io: can't open: Could not open 'TEST_DIR/t.IMGFMT': Is a directory
1200
1201
*** done
1202
diff --git a/tests/qemu-iotests/244.out b/tests/qemu-iotests/244.out
1203
index XXXXXXX..XXXXXXX 100644
1204
--- a/tests/qemu-iotests/244.out
1205
+++ b/tests/qemu-iotests/244.out
1206
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 0
1207
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1208
read 65536/65536 bytes at offset 0
1209
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1210
-can't open device TEST_DIR/t.qcow2: Could not open 'inexistent': No such file or directory
1211
+qemu-io: can't open device TEST_DIR/t.qcow2: Could not open 'inexistent': No such file or directory
1212
no file open, try 'help open'
1213
1214
Data file required, but without data file name in the image:
1215
-can't open device TEST_DIR/t.qcow2: 'data-file' is required for this image
1216
+qemu-io: can't open device TEST_DIR/t.qcow2: 'data-file' is required for this image
1217
no file open, try 'help open'
1218
read 65536/65536 bytes at offset 0
1219
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
1220
-can't open device TEST_DIR/t.qcow2: Could not open 'inexistent': No such file or directory
1221
+qemu-io: can't open device TEST_DIR/t.qcow2: Could not open 'inexistent': No such file or directory
1222
no file open, try 'help open'
1223
1224
Setting data-file for an image with internal data:
1225
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
1226
-can't open device TEST_DIR/t.qcow2: 'data-file' can only be set for images with an external data file
1227
+qemu-io: can't open device TEST_DIR/t.qcow2: 'data-file' can only be set for images with an external data file
1228
no file open, try 'help open'
1229
-can't open device TEST_DIR/t.qcow2: Could not open 'inexistent': No such file or directory
1230
+qemu-io: can't open device TEST_DIR/t.qcow2: Could not open 'inexistent': No such file or directory
1231
no file open, try 'help open'
1232
1233
=== Conflicting features ===
1234
--
38
--
1235
2.20.1
39
2.30.2
1236
40
1237
41
diff view generated by jsdifflib