1
The following changes since commit df34fe314b5da628bc9a2664fb1b887bc0a6cc6d:
1
The following changes since commit 42f6c9179be4401974dd3a75ee72defd16b5092d:
2
2
3
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20190708' into staging (2019-07-08 14:23:32 +0100)
3
Merge tag 'pull-ppc-20211112' of https://github.com/legoater/qemu into staging (2021-11-12 12:28:25 +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 f7077c9860a438087c2d9a8cc27cb8438c98a748:
9
for you to fetch changes up to 7461272c5f6032436ef9032c091c0118539483e4:
10
10
11
qcow2: Allow -o compat=v3 during qemu-img amend (2019-07-08 16:00:31 +0200)
11
softmmu/qdev-monitor: fix use-after-free in qdev_set_id() (2021-11-15 15:49:46 +0100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block layer patches:
14
Block layer patches
15
15
16
- virtio-scsi: Fix request resubmission after I/O error with iothreads
16
- Fixes to image streaming job and block layer reconfiguration to make
17
- qcow2: Fix missing v2/v3 subformat aliases for amend
17
iotest 030 pass again
18
- qcow(1): More specific error message for wrong format version
18
- docs: Deprecate incorrectly typed device_add arguments
19
- MAINTAINERS: update RBD block maintainer
19
- file-posix: Fix alignment after reopen changing O_DIRECT
20
20
21
----------------------------------------------------------------
21
----------------------------------------------------------------
22
Eric Blake (1):
22
Hanna Reitz (10):
23
qcow2: Allow -o compat=v3 during qemu-img amend
23
stream: Traverse graph after modification
24
block: Manipulate children list in .attach/.detach
25
block: Unite remove_empty_child and child_free
26
block: Drop detached child from ignore list
27
block: Pass BdrvChild ** to replace_child_noperm
28
block: Restructure remove_file_or_backing_child()
29
transactions: Invoke clean() after everything else
30
block: Let replace_child_tran keep indirect pointer
31
block: Let replace_child_noperm free children
32
iotests/030: Unthrottle parallel jobs in reverse
24
33
25
Jason Dillaman (1):
34
Kevin Wolf (2):
26
MAINTAINERS: update RBD block maintainer
35
docs: Deprecate incorrectly typed device_add arguments
36
file-posix: Fix alignment after reopen changing O_DIRECT
27
37
28
John Snow (1):
38
Stefan Hajnoczi (1):
29
block/qcow: Improve error when opening qcow2 files as qcow
39
softmmu/qdev-monitor: fix use-after-free in qdev_set_id()
30
40
31
Stefan Hajnoczi (3):
41
docs/about/deprecated.rst | 14 +++
32
vl: add qemu_add_vm_change_state_handler_prio()
42
include/qemu/transactions.h | 3 +
33
qdev: add qdev_add_vm_change_state_handler()
43
block.c | 233 +++++++++++++++++++++++++++++++++-----------
34
virtio-scsi: restart DMA after iothread
44
block/file-posix.c | 20 +++-
45
block/stream.c | 7 +-
46
softmmu/qdev-monitor.c | 2 +-
47
util/transactions.c | 8 +-
48
tests/qemu-iotests/030 | 11 ++-
49
tests/qemu-iotests/142 | 22 +++++
50
tests/qemu-iotests/142.out | 15 +++
51
10 files changed, 269 insertions(+), 66 deletions(-)
35
52
36
include/hw/qdev-core.h | 5 ++++
37
include/sysemu/sysemu.h | 2 ++
38
block/qcow.c | 7 ++++-
39
block/qcow2.c | 6 ++--
40
hw/core/vm-change-state-handler.c | 61 +++++++++++++++++++++++++++++++++++++++
41
hw/scsi/scsi-bus.c | 4 +--
42
hw/virtio/virtio.c | 4 +--
43
vl.c | 59 +++++++++++++++++++++++++++++--------
44
MAINTAINERS | 2 +-
45
hw/core/Makefile.objs | 1 +
46
10 files changed, 130 insertions(+), 21 deletions(-)
47
create mode 100644 hw/core/vm-change-state-handler.c
48
53
diff view generated by jsdifflib
New patch
1
From: Hanna Reitz <hreitz@redhat.com>
1
2
3
bdrv_cor_filter_drop() modifies the block graph. That means that other
4
parties can also modify the block graph before it returns. Therefore,
5
we cannot assume that the result of a graph traversal we did before
6
remains valid afterwards.
7
8
We should thus fetch `base` and `unfiltered_base` afterwards instead of
9
before.
10
11
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
12
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
13
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
14
Message-Id: <20211111120829.81329-2-hreitz@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
---
17
block/stream.c | 7 +++++--
18
1 file changed, 5 insertions(+), 2 deletions(-)
19
20
diff --git a/block/stream.c b/block/stream.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/block/stream.c
23
+++ b/block/stream.c
24
@@ -XXX,XX +XXX,XX @@ static int stream_prepare(Job *job)
25
{
26
StreamBlockJob *s = container_of(job, StreamBlockJob, common.job);
27
BlockDriverState *unfiltered_bs = bdrv_skip_filters(s->target_bs);
28
- BlockDriverState *base = bdrv_filter_or_cow_bs(s->above_base);
29
- BlockDriverState *unfiltered_base = bdrv_skip_filters(base);
30
+ BlockDriverState *base;
31
+ BlockDriverState *unfiltered_base;
32
Error *local_err = NULL;
33
int ret = 0;
34
35
@@ -XXX,XX +XXX,XX @@ static int stream_prepare(Job *job)
36
bdrv_cor_filter_drop(s->cor_filter_bs);
37
s->cor_filter_bs = NULL;
38
39
+ base = bdrv_filter_or_cow_bs(s->above_base);
40
+ unfiltered_base = bdrv_skip_filters(base);
41
+
42
if (bdrv_cow_child(unfiltered_bs)) {
43
const char *base_id = NULL, *base_fmt = NULL;
44
if (unfiltered_base) {
45
--
46
2.31.1
47
48
diff view generated by jsdifflib
New patch
1
From: Hanna Reitz <hreitz@redhat.com>
1
2
3
The children list is specific to BDS parents. We should not modify it
4
in the general children modification code, but let BDS parents deal with
5
it in their .attach() and .detach() methods.
6
7
This also has the advantage that a BdrvChild is removed from the
8
children list before its .bs pointer can become NULL. BDS parents
9
generally assume that their children's .bs pointer is never NULL, so
10
this is actually a bug fix.
11
12
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
13
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
14
Message-Id: <20211111120829.81329-3-hreitz@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
---
17
block.c | 14 +++++---------
18
1 file changed, 5 insertions(+), 9 deletions(-)
19
20
diff --git a/block.c b/block.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/block.c
23
+++ b/block.c
24
@@ -XXX,XX +XXX,XX @@ static void bdrv_child_cb_attach(BdrvChild *child)
25
{
26
BlockDriverState *bs = child->opaque;
27
28
+ QLIST_INSERT_HEAD(&bs->children, child, next);
29
+
30
if (child->role & BDRV_CHILD_COW) {
31
bdrv_backing_attach(child);
32
}
33
@@ -XXX,XX +XXX,XX @@ static void bdrv_child_cb_detach(BdrvChild *child)
34
}
35
36
bdrv_unapply_subtree_drain(child, bs);
37
+
38
+ QLIST_REMOVE(child, next);
39
}
40
41
static int bdrv_child_cb_update_filename(BdrvChild *c, BlockDriverState *base,
42
@@ -XXX,XX +XXX,XX @@ static void bdrv_child_free(void *opaque)
43
static void bdrv_remove_empty_child(BdrvChild *child)
44
{
45
assert(!child->bs);
46
- QLIST_SAFE_REMOVE(child, next);
47
+ assert(!child->next.le_prev); /* not in children list */
48
bdrv_child_free(child);
49
}
50
51
@@ -XXX,XX +XXX,XX @@ static int bdrv_attach_child_noperm(BlockDriverState *parent_bs,
52
return ret;
53
}
54
55
- QLIST_INSERT_HEAD(&parent_bs->children, *child, next);
56
- /*
57
- * child is removed in bdrv_attach_child_common_abort(), so don't care to
58
- * abort this change separately.
59
- */
60
-
61
return 0;
62
}
63
64
@@ -XXX,XX +XXX,XX @@ static void bdrv_remove_filter_or_cow_child_abort(void *opaque)
65
BdrvRemoveFilterOrCowChild *s = opaque;
66
BlockDriverState *parent_bs = s->child->opaque;
67
68
- QLIST_INSERT_HEAD(&parent_bs->children, s->child, next);
69
if (s->is_backing) {
70
parent_bs->backing = s->child;
71
} else {
72
@@ -XXX,XX +XXX,XX @@ static void bdrv_remove_file_or_backing_child(BlockDriverState *bs,
73
};
74
tran_add(tran, &bdrv_remove_filter_or_cow_child_drv, s);
75
76
- QLIST_SAFE_REMOVE(child, next);
77
if (s->is_backing) {
78
bs->backing = NULL;
79
} else {
80
--
81
2.31.1
82
83
diff view generated by jsdifflib
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
From: Hanna Reitz <hreitz@redhat.com>
2
2
3
Add an API for registering vm change state handlers with a well-defined
3
Now that bdrv_remove_empty_child() no longer removes the child from the
4
ordering. This is necessary when handlers depend on each other.
4
parent's children list but only checks that it is not in such a list, it
5
is only a wrapper around bdrv_child_free() that checks that the child is
6
empty and unused. That should apply to all children that we free, so
7
put those checks into bdrv_child_free() and drop
8
bdrv_remove_empty_child().
5
9
6
Small coding style fixes are included to make checkpatch.pl happy.
10
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
7
11
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
13
Message-Id: <20211111120829.81329-4-hreitz@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
15
---
11
include/sysemu/sysemu.h | 2 ++
16
block.c | 26 +++++++++++++-------------
12
vl.c | 59 ++++++++++++++++++++++++++++++++---------
17
1 file changed, 13 insertions(+), 13 deletions(-)
13
2 files changed, 49 insertions(+), 12 deletions(-)
14
18
15
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
19
diff --git a/block.c b/block.c
16
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
17
--- a/include/sysemu/sysemu.h
21
--- a/block.c
18
+++ b/include/sysemu/sysemu.h
22
+++ b/block.c
19
@@ -XXX,XX +XXX,XX @@ typedef void VMChangeStateHandler(void *opaque, int running, RunState state);
23
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_noperm(BdrvChild *child,
20
21
VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
22
void *opaque);
23
+VMChangeStateEntry *qemu_add_vm_change_state_handler_prio(
24
+ VMChangeStateHandler *cb, void *opaque, int priority);
25
void qemu_del_vm_change_state_handler(VMChangeStateEntry *e);
26
void vm_state_notify(int running, RunState state);
27
28
diff --git a/vl.c b/vl.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/vl.c
31
+++ b/vl.c
32
@@ -XXX,XX +XXX,XX @@ static int machine_help_func(QemuOpts *opts, MachineState *machine)
33
struct vm_change_state_entry {
34
VMChangeStateHandler *cb;
35
void *opaque;
36
- QLIST_ENTRY (vm_change_state_entry) entries;
37
+ QTAILQ_ENTRY(vm_change_state_entry) entries;
38
+ int priority;
39
};
40
41
-static QLIST_HEAD(, vm_change_state_entry) vm_change_state_head;
42
+static QTAILQ_HEAD(, vm_change_state_entry) vm_change_state_head;
43
44
-VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
45
- void *opaque)
46
+/**
47
+ * qemu_add_vm_change_state_handler_prio:
48
+ * @cb: the callback to invoke
49
+ * @opaque: user data passed to the callback
50
+ * @priority: low priorities execute first when the vm runs and the reverse is
51
+ * true when the vm stops
52
+ *
53
+ * Register a callback function that is invoked when the vm starts or stops
54
+ * running.
55
+ *
56
+ * Returns: an entry to be freed using qemu_del_vm_change_state_handler()
57
+ */
58
+VMChangeStateEntry *qemu_add_vm_change_state_handler_prio(
59
+ VMChangeStateHandler *cb, void *opaque, int priority)
60
{
61
VMChangeStateEntry *e;
62
+ VMChangeStateEntry *other;
63
64
- e = g_malloc0(sizeof (*e));
65
-
66
+ e = g_malloc0(sizeof(*e));
67
e->cb = cb;
68
e->opaque = opaque;
69
- QLIST_INSERT_HEAD(&vm_change_state_head, e, entries);
70
+ e->priority = priority;
71
+
72
+ /* Keep list sorted in ascending priority order */
73
+ QTAILQ_FOREACH(other, &vm_change_state_head, entries) {
74
+ if (priority < other->priority) {
75
+ QTAILQ_INSERT_BEFORE(other, e, entries);
76
+ return e;
77
+ }
78
+ }
79
+
80
+ QTAILQ_INSERT_TAIL(&vm_change_state_head, e, entries);
81
return e;
82
}
83
84
+VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
85
+ void *opaque)
86
+{
87
+ return qemu_add_vm_change_state_handler_prio(cb, opaque, 0);
88
+}
89
+
90
void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
91
{
92
- QLIST_REMOVE (e, entries);
93
- g_free (e);
94
+ QTAILQ_REMOVE(&vm_change_state_head, e, entries);
95
+ g_free(e);
96
}
97
98
void vm_state_notify(int running, RunState state)
99
@@ -XXX,XX +XXX,XX @@ void vm_state_notify(int running, RunState state)
100
101
trace_vm_state_notify(running, state, RunState_str(state));
102
103
- QLIST_FOREACH_SAFE(e, &vm_change_state_head, entries, next) {
104
- e->cb(e->opaque, running, state);
105
+ if (running) {
106
+ QTAILQ_FOREACH_SAFE(e, &vm_change_state_head, entries, next) {
107
+ e->cb(e->opaque, running, state);
108
+ }
109
+ } else {
110
+ QTAILQ_FOREACH_REVERSE_SAFE(e, &vm_change_state_head, entries, next) {
111
+ e->cb(e->opaque, running, state);
112
+ }
113
}
24
}
114
}
25
}
115
26
116
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv, char **envp)
27
-static void bdrv_child_free(void *opaque)
117
exit(1);
28
-{
29
- BdrvChild *c = opaque;
30
-
31
- g_free(c->name);
32
- g_free(c);
33
-}
34
-
35
-static void bdrv_remove_empty_child(BdrvChild *child)
36
+/**
37
+ * Free the given @child.
38
+ *
39
+ * The child must be empty (i.e. `child->bs == NULL`) and it must be
40
+ * unused (i.e. not in a children list).
41
+ */
42
+static void bdrv_child_free(BdrvChild *child)
43
{
44
assert(!child->bs);
45
assert(!child->next.le_prev); /* not in children list */
46
- bdrv_child_free(child);
47
+
48
+ g_free(child->name);
49
+ g_free(child);
50
}
51
52
typedef struct BdrvAttachChildCommonState {
53
@@ -XXX,XX +XXX,XX @@ static void bdrv_attach_child_common_abort(void *opaque)
118
}
54
}
119
55
120
- QLIST_INIT (&vm_change_state_head);
56
bdrv_unref(bs);
121
+ QTAILQ_INIT(&vm_change_state_head);
57
- bdrv_remove_empty_child(child);
122
os_setup_early_signal_handling();
58
+ bdrv_child_free(child);
123
59
*s->child = NULL;
124
cpu_option = NULL;
60
}
61
62
@@ -XXX,XX +XXX,XX @@ static int bdrv_attach_child_common(BlockDriverState *child_bs,
63
64
if (ret < 0) {
65
error_propagate(errp, local_err);
66
- bdrv_remove_empty_child(new_child);
67
+ bdrv_child_free(new_child);
68
return ret;
69
}
70
}
71
@@ -XXX,XX +XXX,XX @@ static void bdrv_detach_child(BdrvChild *child)
72
BlockDriverState *old_bs = child->bs;
73
74
bdrv_replace_child_noperm(child, NULL);
75
- bdrv_remove_empty_child(child);
76
+ bdrv_child_free(child);
77
78
if (old_bs) {
79
/*
125
--
80
--
126
2.20.1
81
2.31.1
127
82
128
83
diff view generated by jsdifflib
New patch
1
From: Hanna Reitz <hreitz@redhat.com>
1
2
3
bdrv_attach_child_common_abort() restores the parent's AioContext. To
4
do so, the child (which was supposed to be attached, but is now detached
5
again by this abort handler) is added to the ignore list for the
6
AioContext changing functions.
7
8
However, since we modify a BDS's children list in the BdrvChildClass's
9
.attach and .detach handlers, the child is already effectively detached
10
from the parent by this point. We do not need to put it into the ignore
11
list.
12
13
Use this opportunity to clean up the empty line structure: Keep setting
14
the ignore list, invoking the AioContext function, and freeing the
15
ignore list in blocks separated by empty lines.
16
17
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
18
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
19
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
20
Message-Id: <20211111120829.81329-5-hreitz@redhat.com>
21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
---
23
block.c | 8 +++++---
24
1 file changed, 5 insertions(+), 3 deletions(-)
25
26
diff --git a/block.c b/block.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/block.c
29
+++ b/block.c
30
@@ -XXX,XX +XXX,XX @@ static void bdrv_attach_child_common_abort(void *opaque)
31
}
32
33
if (bdrv_child_get_parent_aio_context(child) != s->old_parent_ctx) {
34
- GSList *ignore = g_slist_prepend(NULL, child);
35
+ GSList *ignore;
36
37
+ /* No need to ignore `child`, because it has been detached already */
38
+ ignore = NULL;
39
child->klass->can_set_aio_ctx(child, s->old_parent_ctx, &ignore,
40
&error_abort);
41
g_slist_free(ignore);
42
- ignore = g_slist_prepend(NULL, child);
43
- child->klass->set_aio_ctx(child, s->old_parent_ctx, &ignore);
44
45
+ ignore = NULL;
46
+ child->klass->set_aio_ctx(child, s->old_parent_ctx, &ignore);
47
g_slist_free(ignore);
48
}
49
50
--
51
2.31.1
52
53
diff view generated by jsdifflib
New patch
1
From: Hanna Reitz <hreitz@redhat.com>
1
2
3
bdrv_replace_child_noperm() modifies BdrvChild.bs, and can potentially
4
set it to NULL. That is dangerous, because BDS parents generally assume
5
that their children's .bs pointer is never NULL. We therefore want to
6
let bdrv_replace_child_noperm() set the corresponding BdrvChild pointer
7
to NULL, too.
8
9
This patch lays the foundation for it by passing a BdrvChild ** pointer
10
to bdrv_replace_child_noperm() so that it can later use it to NULL the
11
BdrvChild pointer immediately after setting BdrvChild.bs to NULL.
12
13
(We will still need to undertake some intermediate steps, though.)
14
15
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
16
Message-Id: <20211111120829.81329-6-hreitz@redhat.com>
17
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
19
---
20
block.c | 23 ++++++++++++-----------
21
1 file changed, 12 insertions(+), 11 deletions(-)
22
23
diff --git a/block.c b/block.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/block.c
26
+++ b/block.c
27
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
28
static bool bdrv_recurse_has_child(BlockDriverState *bs,
29
BlockDriverState *child);
30
31
-static void bdrv_replace_child_noperm(BdrvChild *child,
32
+static void bdrv_replace_child_noperm(BdrvChild **child,
33
BlockDriverState *new_bs);
34
static void bdrv_remove_file_or_backing_child(BlockDriverState *bs,
35
BdrvChild *child,
36
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_abort(void *opaque)
37
BlockDriverState *new_bs = s->child->bs;
38
39
/* old_bs reference is transparently moved from @s to @s->child */
40
- bdrv_replace_child_noperm(s->child, s->old_bs);
41
+ bdrv_replace_child_noperm(&s->child, s->old_bs);
42
bdrv_unref(new_bs);
43
}
44
45
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_tran(BdrvChild *child, BlockDriverState *new_bs,
46
if (new_bs) {
47
bdrv_ref(new_bs);
48
}
49
- bdrv_replace_child_noperm(child, new_bs);
50
+ bdrv_replace_child_noperm(&child, new_bs);
51
/* old_bs reference is transparently moved from @child to @s */
52
}
53
54
@@ -XXX,XX +XXX,XX @@ uint64_t bdrv_qapi_perm_to_blk_perm(BlockPermission qapi_perm)
55
return permissions[qapi_perm];
56
}
57
58
-static void bdrv_replace_child_noperm(BdrvChild *child,
59
+static void bdrv_replace_child_noperm(BdrvChild **childp,
60
BlockDriverState *new_bs)
61
{
62
+ BdrvChild *child = *childp;
63
BlockDriverState *old_bs = child->bs;
64
int new_bs_quiesce_counter;
65
int drain_saldo;
66
@@ -XXX,XX +XXX,XX @@ static void bdrv_attach_child_common_abort(void *opaque)
67
BdrvChild *child = *s->child;
68
BlockDriverState *bs = child->bs;
69
70
- bdrv_replace_child_noperm(child, NULL);
71
+ bdrv_replace_child_noperm(s->child, NULL);
72
73
if (bdrv_get_aio_context(bs) != s->old_child_ctx) {
74
bdrv_try_set_aio_context(bs, s->old_child_ctx, &error_abort);
75
@@ -XXX,XX +XXX,XX @@ static int bdrv_attach_child_common(BlockDriverState *child_bs,
76
}
77
78
bdrv_ref(child_bs);
79
- bdrv_replace_child_noperm(new_child, child_bs);
80
+ bdrv_replace_child_noperm(&new_child, child_bs);
81
82
*child = new_child;
83
84
@@ -XXX,XX +XXX,XX @@ static int bdrv_attach_child_noperm(BlockDriverState *parent_bs,
85
return 0;
86
}
87
88
-static void bdrv_detach_child(BdrvChild *child)
89
+static void bdrv_detach_child(BdrvChild **childp)
90
{
91
- BlockDriverState *old_bs = child->bs;
92
+ BlockDriverState *old_bs = (*childp)->bs;
93
94
- bdrv_replace_child_noperm(child, NULL);
95
- bdrv_child_free(child);
96
+ bdrv_replace_child_noperm(childp, NULL);
97
+ bdrv_child_free(*childp);
98
99
if (old_bs) {
100
/*
101
@@ -XXX,XX +XXX,XX @@ void bdrv_root_unref_child(BdrvChild *child)
102
BlockDriverState *child_bs;
103
104
child_bs = child->bs;
105
- bdrv_detach_child(child);
106
+ bdrv_detach_child(&child);
107
bdrv_unref(child_bs);
108
}
109
110
--
111
2.31.1
112
113
diff view generated by jsdifflib
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
From: Hanna Reitz <hreitz@redhat.com>
2
2
3
When the 'cont' command resumes guest execution the vm change state
3
As of a future patch, bdrv_replace_child_tran() will take a BdrvChild **
4
handlers are invoked. Unfortunately there is no explicit ordering
4
pointer. Prepare for that by getting such a pointer and using it where
5
between classic qemu_add_vm_change_state_handler() callbacks. When two
5
applicable, and (dereferenced) as a parameter for
6
layers of code both use vm change state handlers, we don't control which
6
bdrv_replace_child_tran().
7
handler runs first.
8
7
9
virtio-scsi with iothreads hits a deadlock when a failed SCSI command is
8
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
10
restarted and completes before the iothread is re-initialized.
9
Message-Id: <20211111120829.81329-7-hreitz@redhat.com>
11
10
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
12
This patch uses the new qdev_add_vm_change_state_handler() API to
13
guarantee that virtio-scsi's virtio change state handler executes before
14
the SCSI bus children. This way DMA is restarted after the iothread has
15
re-initialized.
16
17
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
19
---
12
---
20
hw/scsi/scsi-bus.c | 4 ++--
13
block.c | 21 ++++++++++++---------
21
hw/virtio/virtio.c | 4 ++--
14
1 file changed, 12 insertions(+), 9 deletions(-)
22
2 files changed, 4 insertions(+), 4 deletions(-)
23
15
24
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
16
diff --git a/block.c b/block.c
25
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/scsi/scsi-bus.c
18
--- a/block.c
27
+++ b/hw/scsi/scsi-bus.c
19
+++ b/block.c
28
@@ -XXX,XX +XXX,XX @@ static void scsi_qdev_realize(DeviceState *qdev, Error **errp)
20
@@ -XXX,XX +XXX,XX @@ static void bdrv_remove_file_or_backing_child(BlockDriverState *bs,
29
error_propagate(errp, local_err);
21
BdrvChild *child,
22
Transaction *tran)
23
{
24
+ BdrvChild **childp;
25
BdrvRemoveFilterOrCowChild *s;
26
27
- assert(child == bs->backing || child == bs->file);
28
-
29
if (!child) {
30
return;
30
return;
31
}
31
}
32
- dev->vmsentry = qemu_add_vm_change_state_handler(scsi_dma_restart_cb,
32
33
- dev);
33
+ if (child == bs->backing) {
34
+ dev->vmsentry = qdev_add_vm_change_state_handler(DEVICE(dev),
34
+ childp = &bs->backing;
35
+ scsi_dma_restart_cb, dev);
35
+ } else if (child == bs->file) {
36
+ childp = &bs->file;
37
+ } else {
38
+ g_assert_not_reached();
39
+ }
40
+
41
if (child->bs) {
42
- bdrv_replace_child_tran(child, NULL, tran);
43
+ bdrv_replace_child_tran(*childp, NULL, tran);
44
}
45
46
s = g_new(BdrvRemoveFilterOrCowChild, 1);
47
*s = (BdrvRemoveFilterOrCowChild) {
48
.child = child,
49
- .is_backing = (child == bs->backing),
50
+ .is_backing = (childp == &bs->backing),
51
};
52
tran_add(tran, &bdrv_remove_filter_or_cow_child_drv, s);
53
54
- if (s->is_backing) {
55
- bs->backing = NULL;
56
- } else {
57
- bs->file = NULL;
58
- }
59
+ *childp = NULL;
36
}
60
}
37
61
38
static void scsi_qdev_unrealize(DeviceState *qdev, Error **errp)
62
/*
39
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/hw/virtio/virtio.c
42
+++ b/hw/virtio/virtio.c
43
@@ -XXX,XX +XXX,XX @@ void virtio_init(VirtIODevice *vdev, const char *name,
44
} else {
45
vdev->config = NULL;
46
}
47
- vdev->vmstate = qemu_add_vm_change_state_handler(virtio_vmstate_change,
48
- vdev);
49
+ vdev->vmstate = qdev_add_vm_change_state_handler(DEVICE(vdev),
50
+ virtio_vmstate_change, vdev);
51
vdev->device_endian = virtio_default_endian();
52
vdev->use_guest_notifier_mask = true;
53
}
54
--
63
--
55
2.20.1
64
2.31.1
56
65
57
66
diff view generated by jsdifflib
New patch
1
From: Hanna Reitz <hreitz@redhat.com>
1
2
3
Invoke the transaction drivers' .clean() methods only after all
4
.commit() or .abort() handlers are done.
5
6
This makes it easier to have nested transactions where the top-level
7
transactions pass objects to lower transactions that the latter can
8
still use throughout their commit/abort phases, while the top-level
9
transaction keeps a reference that is released in its .clean() method.
10
11
(Before this commit, that is also possible, but the top-level
12
transaction would need to take care to invoke tran_add() before the
13
lower-level transaction does. This commit makes the ordering
14
irrelevant, which is just a bit nicer.)
15
16
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
17
Message-Id: <20211111120829.81329-8-hreitz@redhat.com>
18
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
19
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
20
---
21
include/qemu/transactions.h | 3 +++
22
util/transactions.c | 8 ++++++--
23
2 files changed, 9 insertions(+), 2 deletions(-)
24
25
diff --git a/include/qemu/transactions.h b/include/qemu/transactions.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/include/qemu/transactions.h
28
+++ b/include/qemu/transactions.h
29
@@ -XXX,XX +XXX,XX @@
30
* tran_create(), call your "prepare" functions on it, and finally call
31
* tran_abort() or tran_commit() to finalize the transaction by corresponding
32
* finalization actions in reverse order.
33
+ *
34
+ * The clean() functions registered by the drivers in a transaction are called
35
+ * last, after all abort() or commit() functions have been called.
36
*/
37
38
#ifndef QEMU_TRANSACTIONS_H
39
diff --git a/util/transactions.c b/util/transactions.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/util/transactions.c
42
+++ b/util/transactions.c
43
@@ -XXX,XX +XXX,XX @@ void tran_abort(Transaction *tran)
44
{
45
TransactionAction *act, *next;
46
47
- QSLIST_FOREACH_SAFE(act, &tran->actions, entry, next) {
48
+ QSLIST_FOREACH(act, &tran->actions, entry) {
49
if (act->drv->abort) {
50
act->drv->abort(act->opaque);
51
}
52
+ }
53
54
+ QSLIST_FOREACH_SAFE(act, &tran->actions, entry, next) {
55
if (act->drv->clean) {
56
act->drv->clean(act->opaque);
57
}
58
@@ -XXX,XX +XXX,XX @@ void tran_commit(Transaction *tran)
59
{
60
TransactionAction *act, *next;
61
62
- QSLIST_FOREACH_SAFE(act, &tran->actions, entry, next) {
63
+ QSLIST_FOREACH(act, &tran->actions, entry) {
64
if (act->drv->commit) {
65
act->drv->commit(act->opaque);
66
}
67
+ }
68
69
+ QSLIST_FOREACH_SAFE(act, &tran->actions, entry, next) {
70
if (act->drv->clean) {
71
act->drv->clean(act->opaque);
72
}
73
--
74
2.31.1
75
76
diff view generated by jsdifflib
New patch
1
1
From: Hanna Reitz <hreitz@redhat.com>
2
3
As of a future commit, bdrv_replace_child_noperm() will clear the
4
indirect BdrvChild pointer passed to it if the new child BDS is NULL.
5
bdrv_replace_child_tran() will want to let it do that, but revert this
6
change in its abort handler. For that, we need to have it receive a
7
BdrvChild ** pointer, too, and keep it stored in the
8
BdrvReplaceChildState object that we attach to the transaction.
9
10
Note that we do not need to store it in the BdrvReplaceChildState when
11
new_bs is not NULL, because then there is nothing to revert. This is
12
important so that bdrv_replace_node_noperm() can pass a pointer to a
13
loop-local variable to bdrv_replace_child_tran() without worrying that
14
this pointer will outlive one loop iteration.
15
16
(Of course, for that to work, bdrv_replace_node_noperm() and in turn
17
bdrv_replace_node() and its relatives may not be called with a NULL @to
18
node. Luckily, they already are not, but now we should assert this.)
19
20
bdrv_remove_file_or_backing_child() on the other hand needs to ensure
21
that the indirect pointer it passes will stay valid for the duration of
22
the transaction. Ensure this by keeping a strong reference to the BDS
23
whose &bs->backing or &bs->file it passes to bdrv_replace_child_tran(),
24
and giving up that reference only in the transaction .clean() handler.
25
26
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
27
Message-Id: <20211111120829.81329-9-hreitz@redhat.com>
28
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
29
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
30
---
31
block.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
32
1 file changed, 73 insertions(+), 10 deletions(-)
33
34
diff --git a/block.c b/block.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/block.c
37
+++ b/block.c
38
@@ -XXX,XX +XXX,XX @@ static int bdrv_drv_set_perm(BlockDriverState *bs, uint64_t perm,
39
40
typedef struct BdrvReplaceChildState {
41
BdrvChild *child;
42
+ BdrvChild **childp;
43
BlockDriverState *old_bs;
44
} BdrvReplaceChildState;
45
46
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_abort(void *opaque)
47
BdrvReplaceChildState *s = opaque;
48
BlockDriverState *new_bs = s->child->bs;
49
50
- /* old_bs reference is transparently moved from @s to @s->child */
51
+ /*
52
+ * old_bs reference is transparently moved from @s to s->child.
53
+ *
54
+ * Pass &s->child here instead of s->childp, because:
55
+ * (1) s->old_bs must be non-NULL, so bdrv_replace_child_noperm() will not
56
+ * modify the BdrvChild * pointer we indirectly pass to it, i.e. it
57
+ * will not modify s->child. From that perspective, it does not matter
58
+ * whether we pass s->childp or &s->child.
59
+ * (TODO: Right now, bdrv_replace_child_noperm() never modifies that
60
+ * pointer anyway (though it will in the future), so at this point it
61
+ * absolutely does not matter whether we pass s->childp or &s->child.)
62
+ * (2) If new_bs is not NULL, s->childp will be NULL. We then cannot use
63
+ * it here.
64
+ * (3) If new_bs is NULL, *s->childp will have been NULLed by
65
+ * bdrv_replace_child_tran()'s bdrv_replace_child_noperm() call, and we
66
+ * must not pass a NULL *s->childp here.
67
+ * (TODO: In its current state, bdrv_replace_child_noperm() will not
68
+ * have NULLed *s->childp, so this does not apply yet. It will in the
69
+ * future.)
70
+ *
71
+ * So whether new_bs was NULL or not, we cannot pass s->childp here; and in
72
+ * any case, there is no reason to pass it anyway.
73
+ */
74
bdrv_replace_child_noperm(&s->child, s->old_bs);
75
bdrv_unref(new_bs);
76
}
77
@@ -XXX,XX +XXX,XX @@ static TransactionActionDrv bdrv_replace_child_drv = {
78
* Note: real unref of old_bs is done only on commit.
79
*
80
* The function doesn't update permissions, caller is responsible for this.
81
+ *
82
+ * Note that if new_bs == NULL, @childp is stored in a state object attached
83
+ * to @tran, so that the old child can be reinstated in the abort handler.
84
+ * Therefore, if @new_bs can be NULL, @childp must stay valid until the
85
+ * transaction is committed or aborted.
86
+ *
87
+ * (TODO: The reinstating does not happen yet, but it will once
88
+ * bdrv_replace_child_noperm() NULLs *childp when new_bs is NULL.)
89
*/
90
-static void bdrv_replace_child_tran(BdrvChild *child, BlockDriverState *new_bs,
91
+static void bdrv_replace_child_tran(BdrvChild **childp,
92
+ BlockDriverState *new_bs,
93
Transaction *tran)
94
{
95
BdrvReplaceChildState *s = g_new(BdrvReplaceChildState, 1);
96
*s = (BdrvReplaceChildState) {
97
- .child = child,
98
- .old_bs = child->bs,
99
+ .child = *childp,
100
+ .childp = new_bs == NULL ? childp : NULL,
101
+ .old_bs = (*childp)->bs,
102
};
103
tran_add(tran, &bdrv_replace_child_drv, s);
104
105
if (new_bs) {
106
bdrv_ref(new_bs);
107
}
108
- bdrv_replace_child_noperm(&child, new_bs);
109
- /* old_bs reference is transparently moved from @child to @s */
110
+ bdrv_replace_child_noperm(childp, new_bs);
111
+ /* old_bs reference is transparently moved from *childp to @s */
112
}
113
114
/*
115
@@ -XXX,XX +XXX,XX @@ static bool should_update_child(BdrvChild *c, BlockDriverState *to)
116
117
typedef struct BdrvRemoveFilterOrCowChild {
118
BdrvChild *child;
119
+ BlockDriverState *bs;
120
bool is_backing;
121
} BdrvRemoveFilterOrCowChild;
122
123
@@ -XXX,XX +XXX,XX @@ static void bdrv_remove_filter_or_cow_child_commit(void *opaque)
124
bdrv_child_free(s->child);
125
}
126
127
+static void bdrv_remove_filter_or_cow_child_clean(void *opaque)
128
+{
129
+ BdrvRemoveFilterOrCowChild *s = opaque;
130
+
131
+ /* Drop the bs reference after the transaction is done */
132
+ bdrv_unref(s->bs);
133
+ g_free(s);
134
+}
135
+
136
static TransactionActionDrv bdrv_remove_filter_or_cow_child_drv = {
137
.abort = bdrv_remove_filter_or_cow_child_abort,
138
.commit = bdrv_remove_filter_or_cow_child_commit,
139
- .clean = g_free,
140
+ .clean = bdrv_remove_filter_or_cow_child_clean,
141
};
142
143
/*
144
@@ -XXX,XX +XXX,XX @@ static void bdrv_remove_file_or_backing_child(BlockDriverState *bs,
145
return;
146
}
147
148
+ /*
149
+ * Keep a reference to @bs so @childp will stay valid throughout the
150
+ * transaction (required by bdrv_replace_child_tran())
151
+ */
152
+ bdrv_ref(bs);
153
if (child == bs->backing) {
154
childp = &bs->backing;
155
} else if (child == bs->file) {
156
@@ -XXX,XX +XXX,XX @@ static void bdrv_remove_file_or_backing_child(BlockDriverState *bs,
157
}
158
159
if (child->bs) {
160
- bdrv_replace_child_tran(*childp, NULL, tran);
161
+ bdrv_replace_child_tran(childp, NULL, tran);
162
}
163
164
s = g_new(BdrvRemoveFilterOrCowChild, 1);
165
*s = (BdrvRemoveFilterOrCowChild) {
166
.child = child,
167
+ .bs = bs,
168
.is_backing = (childp == &bs->backing),
169
};
170
tran_add(tran, &bdrv_remove_filter_or_cow_child_drv, s);
171
@@ -XXX,XX +XXX,XX @@ static int bdrv_replace_node_noperm(BlockDriverState *from,
172
{
173
BdrvChild *c, *next;
174
175
+ assert(to != NULL);
176
+
177
QLIST_FOREACH_SAFE(c, &from->parents, next_parent, next) {
178
assert(c->bs == from);
179
if (!should_update_child(c, to)) {
180
@@ -XXX,XX +XXX,XX @@ static int bdrv_replace_node_noperm(BlockDriverState *from,
181
c->name, from->node_name);
182
return -EPERM;
183
}
184
- bdrv_replace_child_tran(c, to, tran);
185
+
186
+ /*
187
+ * Passing a pointer to the local variable @c is fine here, because
188
+ * @to is not NULL, and so &c will not be attached to the transaction.
189
+ */
190
+ bdrv_replace_child_tran(&c, to, tran);
191
}
192
193
return 0;
194
@@ -XXX,XX +XXX,XX @@ static int bdrv_replace_node_noperm(BlockDriverState *from,
195
*
196
* With @detach_subchain=true @to must be in a backing chain of @from. In this
197
* case backing link of the cow-parent of @to is removed.
198
+ *
199
+ * @to must not be NULL.
200
*/
201
static int bdrv_replace_node_common(BlockDriverState *from,
202
BlockDriverState *to,
203
@@ -XXX,XX +XXX,XX @@ static int bdrv_replace_node_common(BlockDriverState *from,
204
BlockDriverState *to_cow_parent = NULL;
205
int ret;
206
207
+ assert(to != NULL);
208
+
209
if (detach_subchain) {
210
assert(bdrv_chain_contains(from, to));
211
assert(from != to);
212
@@ -XXX,XX +XXX,XX @@ out:
213
return ret;
214
}
215
216
+/**
217
+ * Replace node @from by @to (where neither may be NULL).
218
+ */
219
int bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
220
Error **errp)
221
{
222
@@ -XXX,XX +XXX,XX @@ int bdrv_replace_child_bs(BdrvChild *child, BlockDriverState *new_bs,
223
bdrv_drained_begin(old_bs);
224
bdrv_drained_begin(new_bs);
225
226
- bdrv_replace_child_tran(child, new_bs, tran);
227
+ bdrv_replace_child_tran(&child, new_bs, tran);
228
229
found = g_hash_table_new(NULL, NULL);
230
refresh_list = bdrv_topological_dfs(refresh_list, found, old_bs);
231
--
232
2.31.1
233
234
diff view generated by jsdifflib
New patch
1
1
From: Hanna Reitz <hreitz@redhat.com>
2
3
In most of the block layer, especially when traversing down from other
4
BlockDriverStates, we assume that BdrvChild.bs can never be NULL. When
5
it becomes NULL, it is expected that the corresponding BdrvChild pointer
6
also becomes NULL and the BdrvChild object is freed.
7
8
Therefore, once bdrv_replace_child_noperm() sets the BdrvChild.bs
9
pointer to NULL, it should also immediately set the corresponding
10
BdrvChild pointer (like bs->file or bs->backing) to NULL.
11
12
In that context, it also makes sense for this function to free the
13
child. Sometimes we cannot do so, though, because it is called in a
14
transactional context where the caller might still want to reinstate the
15
child in the abort branch (and free it only on commit), so this behavior
16
has to remain optional.
17
18
In bdrv_replace_child_tran()'s abort handler, we now rely on the fact
19
that the BdrvChild passed to bdrv_replace_child_tran() must have had a
20
non-NULL .bs pointer initially. Make a note of that and assert it.
21
22
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
23
Message-Id: <20211111120829.81329-10-hreitz@redhat.com>
24
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
25
---
26
block.c | 102 +++++++++++++++++++++++++++++++++++++++++++-------------
27
1 file changed, 79 insertions(+), 23 deletions(-)
28
29
diff --git a/block.c b/block.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/block.c
32
+++ b/block.c
33
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
34
static bool bdrv_recurse_has_child(BlockDriverState *bs,
35
BlockDriverState *child);
36
37
+static void bdrv_child_free(BdrvChild *child);
38
static void bdrv_replace_child_noperm(BdrvChild **child,
39
- BlockDriverState *new_bs);
40
+ BlockDriverState *new_bs,
41
+ bool free_empty_child);
42
static void bdrv_remove_file_or_backing_child(BlockDriverState *bs,
43
BdrvChild *child,
44
Transaction *tran);
45
@@ -XXX,XX +XXX,XX @@ typedef struct BdrvReplaceChildState {
46
BdrvChild *child;
47
BdrvChild **childp;
48
BlockDriverState *old_bs;
49
+ bool free_empty_child;
50
} BdrvReplaceChildState;
51
52
static void bdrv_replace_child_commit(void *opaque)
53
{
54
BdrvReplaceChildState *s = opaque;
55
56
+ if (s->free_empty_child && !s->child->bs) {
57
+ bdrv_child_free(s->child);
58
+ }
59
bdrv_unref(s->old_bs);
60
}
61
62
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_abort(void *opaque)
63
* modify the BdrvChild * pointer we indirectly pass to it, i.e. it
64
* will not modify s->child. From that perspective, it does not matter
65
* whether we pass s->childp or &s->child.
66
- * (TODO: Right now, bdrv_replace_child_noperm() never modifies that
67
- * pointer anyway (though it will in the future), so at this point it
68
- * absolutely does not matter whether we pass s->childp or &s->child.)
69
* (2) If new_bs is not NULL, s->childp will be NULL. We then cannot use
70
* it here.
71
* (3) If new_bs is NULL, *s->childp will have been NULLed by
72
* bdrv_replace_child_tran()'s bdrv_replace_child_noperm() call, and we
73
* must not pass a NULL *s->childp here.
74
- * (TODO: In its current state, bdrv_replace_child_noperm() will not
75
- * have NULLed *s->childp, so this does not apply yet. It will in the
76
- * future.)
77
*
78
* So whether new_bs was NULL or not, we cannot pass s->childp here; and in
79
* any case, there is no reason to pass it anyway.
80
*/
81
- bdrv_replace_child_noperm(&s->child, s->old_bs);
82
+ bdrv_replace_child_noperm(&s->child, s->old_bs, true);
83
+ /*
84
+ * The child was pre-existing, so s->old_bs must be non-NULL, and
85
+ * s->child thus must not have been freed
86
+ */
87
+ assert(s->child != NULL);
88
+ if (!new_bs) {
89
+ /* As described above, *s->childp was cleared, so restore it */
90
+ assert(s->childp != NULL);
91
+ *s->childp = s->child;
92
+ }
93
bdrv_unref(new_bs);
94
}
95
96
@@ -XXX,XX +XXX,XX @@ static TransactionActionDrv bdrv_replace_child_drv = {
97
*
98
* The function doesn't update permissions, caller is responsible for this.
99
*
100
+ * (*childp)->bs must not be NULL.
101
+ *
102
* Note that if new_bs == NULL, @childp is stored in a state object attached
103
* to @tran, so that the old child can be reinstated in the abort handler.
104
* Therefore, if @new_bs can be NULL, @childp must stay valid until the
105
* transaction is committed or aborted.
106
*
107
- * (TODO: The reinstating does not happen yet, but it will once
108
- * bdrv_replace_child_noperm() NULLs *childp when new_bs is NULL.)
109
+ * If @free_empty_child is true and @new_bs is NULL, the BdrvChild is
110
+ * freed (on commit). @free_empty_child should only be false if the
111
+ * caller will free the BDrvChild themselves (which may be important
112
+ * if this is in turn called in another transactional context).
113
*/
114
static void bdrv_replace_child_tran(BdrvChild **childp,
115
BlockDriverState *new_bs,
116
- Transaction *tran)
117
+ Transaction *tran,
118
+ bool free_empty_child)
119
{
120
BdrvReplaceChildState *s = g_new(BdrvReplaceChildState, 1);
121
*s = (BdrvReplaceChildState) {
122
.child = *childp,
123
.childp = new_bs == NULL ? childp : NULL,
124
.old_bs = (*childp)->bs,
125
+ .free_empty_child = free_empty_child,
126
};
127
tran_add(tran, &bdrv_replace_child_drv, s);
128
129
+ /* The abort handler relies on this */
130
+ assert(s->old_bs != NULL);
131
+
132
if (new_bs) {
133
bdrv_ref(new_bs);
134
}
135
- bdrv_replace_child_noperm(childp, new_bs);
136
+ /*
137
+ * Pass free_empty_child=false, we will free the child (if
138
+ * necessary) in bdrv_replace_child_commit() (if our
139
+ * @free_empty_child parameter was true).
140
+ */
141
+ bdrv_replace_child_noperm(childp, new_bs, false);
142
/* old_bs reference is transparently moved from *childp to @s */
143
}
144
145
@@ -XXX,XX +XXX,XX @@ uint64_t bdrv_qapi_perm_to_blk_perm(BlockPermission qapi_perm)
146
return permissions[qapi_perm];
147
}
148
149
+/**
150
+ * Replace (*childp)->bs by @new_bs.
151
+ *
152
+ * If @new_bs is NULL, *childp will be set to NULL, too: BDS parents
153
+ * generally cannot handle a BdrvChild with .bs == NULL, so clearing
154
+ * BdrvChild.bs should generally immediately be followed by the
155
+ * BdrvChild pointer being cleared as well.
156
+ *
157
+ * If @free_empty_child is true and @new_bs is NULL, the BdrvChild is
158
+ * freed. @free_empty_child should only be false if the caller will
159
+ * free the BdrvChild themselves (this may be important in a
160
+ * transactional context, where it may only be freed on commit).
161
+ */
162
static void bdrv_replace_child_noperm(BdrvChild **childp,
163
- BlockDriverState *new_bs)
164
+ BlockDriverState *new_bs,
165
+ bool free_empty_child)
166
{
167
BdrvChild *child = *childp;
168
BlockDriverState *old_bs = child->bs;
169
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_noperm(BdrvChild **childp,
170
}
171
172
child->bs = new_bs;
173
+ if (!new_bs) {
174
+ *childp = NULL;
175
+ }
176
177
if (new_bs) {
178
QLIST_INSERT_HEAD(&new_bs->parents, child, next_parent);
179
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_noperm(BdrvChild **childp,
180
bdrv_parent_drained_end_single(child);
181
drain_saldo++;
182
}
183
+
184
+ if (free_empty_child && !child->bs) {
185
+ bdrv_child_free(child);
186
+ }
187
}
188
189
/**
190
@@ -XXX,XX +XXX,XX @@ static void bdrv_attach_child_common_abort(void *opaque)
191
BdrvChild *child = *s->child;
192
BlockDriverState *bs = child->bs;
193
194
- bdrv_replace_child_noperm(s->child, NULL);
195
+ /*
196
+ * Pass free_empty_child=false, because we still need the child
197
+ * for the AioContext operations on the parent below; those
198
+ * BdrvChildClass methods all work on a BdrvChild object, so we
199
+ * need to keep it as an empty shell (after this function, it will
200
+ * not be attached to any parent, and it will not have a .bs).
201
+ */
202
+ bdrv_replace_child_noperm(s->child, NULL, false);
203
204
if (bdrv_get_aio_context(bs) != s->old_child_ctx) {
205
bdrv_try_set_aio_context(bs, s->old_child_ctx, &error_abort);
206
@@ -XXX,XX +XXX,XX @@ static void bdrv_attach_child_common_abort(void *opaque)
207
208
bdrv_unref(bs);
209
bdrv_child_free(child);
210
- *s->child = NULL;
211
}
212
213
static TransactionActionDrv bdrv_attach_child_common_drv = {
214
@@ -XXX,XX +XXX,XX @@ static int bdrv_attach_child_common(BlockDriverState *child_bs,
215
}
216
217
bdrv_ref(child_bs);
218
- bdrv_replace_child_noperm(&new_child, child_bs);
219
+ bdrv_replace_child_noperm(&new_child, child_bs, true);
220
+ /* child_bs was non-NULL, so new_child must not have been freed */
221
+ assert(new_child != NULL);
222
223
*child = new_child;
224
225
@@ -XXX,XX +XXX,XX @@ static void bdrv_detach_child(BdrvChild **childp)
226
{
227
BlockDriverState *old_bs = (*childp)->bs;
228
229
- bdrv_replace_child_noperm(childp, NULL);
230
- bdrv_child_free(*childp);
231
+ bdrv_replace_child_noperm(childp, NULL, true);
232
233
if (old_bs) {
234
/*
235
@@ -XXX,XX +XXX,XX @@ static void bdrv_remove_file_or_backing_child(BlockDriverState *bs,
236
}
237
238
if (child->bs) {
239
- bdrv_replace_child_tran(childp, NULL, tran);
240
+ /*
241
+ * Pass free_empty_child=false, we will free the child in
242
+ * bdrv_remove_filter_or_cow_child_commit()
243
+ */
244
+ bdrv_replace_child_tran(childp, NULL, tran, false);
245
}
246
247
s = g_new(BdrvRemoveFilterOrCowChild, 1);
248
@@ -XXX,XX +XXX,XX @@ static void bdrv_remove_file_or_backing_child(BlockDriverState *bs,
249
.is_backing = (childp == &bs->backing),
250
};
251
tran_add(tran, &bdrv_remove_filter_or_cow_child_drv, s);
252
-
253
- *childp = NULL;
254
}
255
256
/*
257
@@ -XXX,XX +XXX,XX @@ static int bdrv_replace_node_noperm(BlockDriverState *from,
258
* Passing a pointer to the local variable @c is fine here, because
259
* @to is not NULL, and so &c will not be attached to the transaction.
260
*/
261
- bdrv_replace_child_tran(&c, to, tran);
262
+ bdrv_replace_child_tran(&c, to, tran, true);
263
}
264
265
return 0;
266
@@ -XXX,XX +XXX,XX @@ int bdrv_replace_child_bs(BdrvChild *child, BlockDriverState *new_bs,
267
bdrv_drained_begin(old_bs);
268
bdrv_drained_begin(new_bs);
269
270
- bdrv_replace_child_tran(&child, new_bs, tran);
271
+ bdrv_replace_child_tran(&child, new_bs, tran, true);
272
+ /* @new_bs must have been non-NULL, so @child must not have been freed */
273
+ assert(child != NULL);
274
275
found = g_hash_table_new(NULL, NULL);
276
refresh_list = bdrv_topological_dfs(refresh_list, found, old_bs);
277
--
278
2.31.1
279
280
diff view generated by jsdifflib
1
From: Eric Blake <eblake@redhat.com>
1
From: Hanna Reitz <hreitz@redhat.com>
2
2
3
Commit b76b4f60 allowed '-o compat=v3' as an alias for the
3
See the comment for why this is necessary.
4
less-appealing '-o compat=1.1' for 'qemu-img create' since we want to
5
use the QMP form as much as possible, but forgot to do likewise for
6
qemu-img amend. Also, it doesn't help that '-o help' doesn't list our
7
new preferred spellings.
8
4
9
Signed-off-by: Eric Blake <eblake@redhat.com>
5
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
6
Message-Id: <20211111120829.81329-11-hreitz@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
8
---
12
block/qcow2.c | 6 +++---
9
tests/qemu-iotests/030 | 11 ++++++++++-
13
1 file changed, 3 insertions(+), 3 deletions(-)
10
1 file changed, 10 insertions(+), 1 deletion(-)
14
11
15
diff --git a/block/qcow2.c b/block/qcow2.c
12
diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030
16
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100755
17
--- a/block/qcow2.c
14
--- a/tests/qemu-iotests/030
18
+++ b/block/qcow2.c
15
+++ b/tests/qemu-iotests/030
19
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
16
@@ -XXX,XX +XXX,XX @@ class TestParallelOps(iotests.QMPTestCase):
20
compat = qemu_opt_get(opts, BLOCK_OPT_COMPAT_LEVEL);
17
speed=1024)
21
if (!compat) {
18
self.assert_qmp(result, 'return', {})
22
/* preserve default */
19
23
- } else if (!strcmp(compat, "0.10")) {
20
- for job in pending_jobs:
24
+ } else if (!strcmp(compat, "0.10") || !strcmp(compat, "v2")) {
21
+ # Do this in reverse: After unthrottling them, some jobs may finish
25
new_version = 2;
22
+ # before we have unthrottled all of them. This will drain their
26
- } else if (!strcmp(compat, "1.1")) {
23
+ # subgraph, and this will make jobs above them advance (despite those
27
+ } else if (!strcmp(compat, "1.1") || !strcmp(compat, "v3")) {
24
+ # jobs on top being throttled). In the worst case, all jobs below the
28
new_version = 3;
25
+ # top one are finished before we can unthrottle it, and this makes it
29
} else {
26
+ # advance so far that it completes before we can unthrottle it - which
30
error_setg(errp, "Unknown compatibility level %s", compat);
27
+ # results in an error.
31
@@ -XXX,XX +XXX,XX @@ static QemuOptsList qcow2_create_opts = {
28
+ # Starting from the top (i.e. in reverse) does not have this problem:
32
{
29
+ # When a job finishes, the ones below it are not advanced.
33
.name = BLOCK_OPT_COMPAT_LEVEL,
30
+ for job in reversed(pending_jobs):
34
.type = QEMU_OPT_STRING,
31
result = self.vm.qmp('block-job-set-speed', device=job, speed=0)
35
- .help = "Compatibility level (0.10 or 1.1)"
32
self.assert_qmp(result, 'return', {})
36
+ .help = "Compatibility level (v2 [0.10] or v3 [1.1])"
33
37
},
38
{
39
.name = BLOCK_OPT_BACKING_FILE,
40
--
34
--
41
2.20.1
35
2.31.1
42
36
43
37
diff view generated by jsdifflib
1
From: John Snow <jsnow@redhat.com>
1
While introducing a non-QemuOpts code path for device creation for JSON
2
-device, we noticed that QMP device_add doesn't check its input
3
correctly (accepting arguments that should have been rejected), and that
4
users may be relying on this behaviour (libvirt did until it was fixed
5
recently).
2
6
3
Reported-by: radmehrsaeed7@gmail.com
7
Let's use a deprecation period before we fix this bug in QEMU to avoid
4
Fixes: https://bugs.launchpad.net/bugs/1832914
8
nasty surprises for users.
5
Signed-off-by: John Snow <jsnow@redhat.com>
9
6
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
11
Message-Id: <20211111143530.18985-1-kwolf@redhat.com>
12
Reviewed-by: Markus Armbruster <armbru@redhat.com>
13
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
15
---
10
block/qcow.c | 7 ++++++-
16
docs/about/deprecated.rst | 14 ++++++++++++++
11
1 file changed, 6 insertions(+), 1 deletion(-)
17
1 file changed, 14 insertions(+)
12
18
13
diff --git a/block/qcow.c b/block/qcow.c
19
diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
14
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
15
--- a/block/qcow.c
21
--- a/docs/about/deprecated.rst
16
+++ b/block/qcow.c
22
+++ b/docs/about/deprecated.rst
17
@@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
23
@@ -XXX,XX +XXX,XX @@ options are removed in favor of using explicit ``blockdev-create`` and
18
goto fail;
24
``blockdev-add`` calls. See :doc:`/interop/live-block-operations` for
19
}
25
details.
20
if (header.version != QCOW_VERSION) {
26
21
- error_setg(errp, "Unsupported qcow version %" PRIu32, header.version);
27
+Incorrectly typed ``device_add`` arguments (since 6.2)
22
+ error_setg(errp, "qcow (v%d) does not support qcow version %" PRIu32,
28
+''''''''''''''''''''''''''''''''''''''''''''''''''''''
23
+ QCOW_VERSION, header.version);
24
+ if (header.version == 2 || header.version == 3) {
25
+ error_append_hint(errp, "Try the 'qcow2' driver instead.\n");
26
+ }
27
+
29
+
28
ret = -ENOTSUP;
30
+Due to shortcomings in the internal implementation of ``device_add``, QEMU
29
goto fail;
31
+incorrectly accepts certain invalid arguments: Any object or list arguments are
30
}
32
+silently ignored. Other argument types are not checked, but an implicit
33
+conversion happens, so that e.g. string values can be assigned to integer
34
+device properties or vice versa.
35
+
36
+This is a bug in QEMU that will be fixed in the future so that previously
37
+accepted incorrect commands will return an error. Users should make sure that
38
+all arguments passed to ``device_add`` are consistent with the documented
39
+property types.
40
+
41
System accelerators
42
-------------------
43
31
--
44
--
32
2.20.1
45
2.31.1
33
46
34
47
diff view generated by jsdifflib
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
At the end of a reopen, we already call bdrv_refresh_limits(), which
2
should update bs->request_alignment according to the new file
3
descriptor. However, raw_probe_alignment() relies on s->needs_alignment
4
and just uses 1 if it isn't set. We neglected to update this field, so
5
starting with cache=writeback and then reopening with cache=none means
6
that we get an incorrect bs->request_alignment == 1 and unaligned
7
requests fail instead of being automatically aligned.
2
8
3
Children sometimes depend on their parent's vm change state handler
9
Fix this by recalculating s->needs_alignment in raw_refresh_limits()
4
having completed. Add a vm change state handler API for devices that
10
before calling raw_probe_alignment().
5
guarantees tree depth ordering.
6
11
7
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Message-Id: <20211104113109.56336-1-kwolf@redhat.com>
14
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
15
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
17
---
10
include/hw/qdev-core.h | 5 +++
18
block/file-posix.c | 20 ++++++++++++++++----
11
hw/core/vm-change-state-handler.c | 61 +++++++++++++++++++++++++++++++
19
tests/qemu-iotests/142 | 22 ++++++++++++++++++++++
12
hw/core/Makefile.objs | 1 +
20
tests/qemu-iotests/142.out | 15 +++++++++++++++
13
3 files changed, 67 insertions(+)
21
3 files changed, 53 insertions(+), 4 deletions(-)
14
create mode 100644 hw/core/vm-change-state-handler.c
15
22
16
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
23
diff --git a/block/file-posix.c b/block/file-posix.c
17
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/qdev-core.h
25
--- a/block/file-posix.c
19
+++ b/include/hw/qdev-core.h
26
+++ b/block/file-posix.c
20
@@ -XXX,XX +XXX,XX @@
27
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVRawState {
21
#include "qom/object.h"
28
int page_cache_inconsistent; /* errno from fdatasync failure */
22
#include "hw/irq.h"
29
bool has_fallocate;
23
#include "hw/hotplug.h"
30
bool needs_alignment;
24
+#include "sysemu/sysemu.h"
31
+ bool force_alignment;
25
32
bool drop_cache;
26
enum {
33
bool check_cache_dropped;
27
DEV_NVECTORS_UNSPECIFIED = -1,
34
struct {
28
@@ -XXX,XX +XXX,XX @@ static inline bool qbus_is_hotpluggable(BusState *bus)
35
@@ -XXX,XX +XXX,XX @@ static bool dio_byte_aligned(int fd)
29
void device_listener_register(DeviceListener *listener);
36
return false;
30
void device_listener_unregister(DeviceListener *listener);
37
}
31
38
32
+VMChangeStateEntry *qdev_add_vm_change_state_handler(DeviceState *dev,
39
+static bool raw_needs_alignment(BlockDriverState *bs)
33
+ VMChangeStateHandler *cb,
40
+{
34
+ void *opaque);
41
+ BDRVRawState *s = bs->opaque;
35
+
42
+
36
#endif
43
+ if ((bs->open_flags & BDRV_O_NOCACHE) != 0 && !dio_byte_aligned(s->fd)) {
37
diff --git a/hw/core/vm-change-state-handler.c b/hw/core/vm-change-state-handler.c
44
+ return true;
38
new file mode 100644
39
index XXXXXXX..XXXXXXX
40
--- /dev/null
41
+++ b/hw/core/vm-change-state-handler.c
42
@@ -XXX,XX +XXX,XX @@
43
+/*
44
+ * qdev vm change state handlers
45
+ *
46
+ * This program is free software; you can redistribute it and/or modify
47
+ * it under the terms of the GNU General Public License as published by
48
+ * the Free Software Foundation; either version 2 of the License,
49
+ * or (at your option) any later version.
50
+ *
51
+ * This program is distributed in the hope that it will be useful,
52
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
53
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
54
+ * GNU General Public License for more details.
55
+ *
56
+ * You should have received a copy of the GNU General Public License
57
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
58
+ */
59
+
60
+#include "qemu/osdep.h"
61
+#include "hw/qdev.h"
62
+
63
+static int qdev_get_dev_tree_depth(DeviceState *dev)
64
+{
65
+ int depth;
66
+
67
+ for (depth = 0; dev; depth++) {
68
+ BusState *bus = dev->parent_bus;
69
+
70
+ if (!bus) {
71
+ break;
72
+ }
73
+
74
+ dev = bus->parent;
75
+ }
45
+ }
76
+
46
+
77
+ return depth;
47
+ return s->force_alignment;
78
+}
48
+}
79
+
49
+
80
+/**
50
/* Check if read is allowed with given memory buffer and length.
81
+ * qdev_add_vm_change_state_handler:
51
*
82
+ * @dev: the device that owns this handler
52
* This function is used to check O_DIRECT memory buffer and request alignment.
83
+ * @cb: the callback function to be invoked
53
@@ -XXX,XX +XXX,XX @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
84
+ * @opaque: user data passed to the callback function
54
85
+ *
55
s->has_discard = true;
86
+ * This function works like qemu_add_vm_change_state_handler() except callbacks
56
s->has_write_zeroes = true;
87
+ * are invoked in qdev tree depth order. Ordering is desirable when callbacks
57
- if ((bs->open_flags & BDRV_O_NOCACHE) != 0 && !dio_byte_aligned(s->fd)) {
88
+ * of children depend on their parent's callback having completed first.
58
- s->needs_alignment = true;
89
+ *
59
- }
90
+ * For example, when qdev_add_vm_change_state_handler() is used, a host
60
91
+ * controller's callback is invoked before the children on its bus when the VM
61
if (fstat(s->fd, &st) < 0) {
92
+ * starts running. The order is reversed when the VM stops running.
62
ret = -errno;
93
+ *
63
@@ -XXX,XX +XXX,XX @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
94
+ * Returns: an entry to be freed with qemu_del_vm_change_state_handler()
64
* so QEMU makes sure all IO operations on the device are aligned
95
+ */
65
* to sector size, or else FreeBSD will reject them with EINVAL.
96
+VMChangeStateEntry *qdev_add_vm_change_state_handler(DeviceState *dev,
66
*/
97
+ VMChangeStateHandler *cb,
67
- s->needs_alignment = true;
98
+ void *opaque)
68
+ s->force_alignment = true;
99
+{
69
}
100
+ int depth = qdev_get_dev_tree_depth(dev);
70
#endif
71
+ s->needs_alignment = raw_needs_alignment(bs);
72
73
#ifdef CONFIG_XFS
74
if (platform_test_xfs_fd(s->fd)) {
75
@@ -XXX,XX +XXX,XX @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
76
BDRVRawState *s = bs->opaque;
77
struct stat st;
78
79
+ s->needs_alignment = raw_needs_alignment(bs);
80
raw_probe_alignment(bs, s->fd, errp);
101
+
81
+
102
+ return qemu_add_vm_change_state_handler_prio(cb, opaque, depth);
82
bs->bl.min_mem_alignment = s->buf_align;
103
+}
83
bs->bl.opt_mem_alignment = MAX(s->buf_align, qemu_real_host_page_size);
104
diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
84
85
diff --git a/tests/qemu-iotests/142 b/tests/qemu-iotests/142
86
index XXXXXXX..XXXXXXX 100755
87
--- a/tests/qemu-iotests/142
88
+++ b/tests/qemu-iotests/142
89
@@ -XXX,XX +XXX,XX @@ info block backing-file"
90
91
echo "$hmp_cmds" | run_qemu -drive "$files","$ids" | grep "Cache"
92
93
+echo
94
+echo "--- Alignment after changing O_DIRECT ---"
95
+echo
96
+
97
+# Directly test the protocol level: Can unaligned requests succeed even if
98
+# O_DIRECT was only enabled through a reopen and vice versa?
99
+
100
+$QEMU_IO --cache=writeback -f file $TEST_IMG <<EOF | _filter_qemu_io
101
+read 42 42
102
+reopen -o cache.direct=on
103
+read 42 42
104
+reopen -o cache.direct=off
105
+read 42 42
106
+EOF
107
+$QEMU_IO --cache=none -f file $TEST_IMG <<EOF | _filter_qemu_io
108
+read 42 42
109
+reopen -o cache.direct=off
110
+read 42 42
111
+reopen -o cache.direct=on
112
+read 42 42
113
+EOF
114
+
115
# success, all done
116
echo "*** done"
117
rm -f $seq.full
118
diff --git a/tests/qemu-iotests/142.out b/tests/qemu-iotests/142.out
105
index XXXXXXX..XXXXXXX 100644
119
index XXXXXXX..XXXXXXX 100644
106
--- a/hw/core/Makefile.objs
120
--- a/tests/qemu-iotests/142.out
107
+++ b/hw/core/Makefile.objs
121
+++ b/tests/qemu-iotests/142.out
108
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_SOFTMMU) += fw-path-provider.o
122
@@ -XXX,XX +XXX,XX @@ cache.no-flush=on on backing-file
109
common-obj-y += irq.o
123
Cache mode: writeback
110
common-obj-y += hotplug.o
124
Cache mode: writeback, direct
111
common-obj-$(CONFIG_SOFTMMU) += nmi.o
125
Cache mode: writeback, ignore flushes
112
+common-obj-$(CONFIG_SOFTMMU) += vm-change-state-handler.o
126
+
113
127
+--- Alignment after changing O_DIRECT ---
114
common-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
128
+
115
common-obj-$(CONFIG_XILINX_AXI) += stream.o
129
+read 42/42 bytes at offset 42
130
+42 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
131
+read 42/42 bytes at offset 42
132
+42 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
133
+read 42/42 bytes at offset 42
134
+42 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
135
+read 42/42 bytes at offset 42
136
+42 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
137
+read 42/42 bytes at offset 42
138
+42 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
139
+read 42/42 bytes at offset 42
140
+42 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
141
*** done
116
--
142
--
117
2.20.1
143
2.31.1
118
144
119
145
diff view generated by jsdifflib
1
From: Jason Dillaman <dillaman@redhat.com>
1
From: Stefan Hajnoczi <stefanha@redhat.com>
2
2
3
Remove Josh as per his request since he is no longer the upstream RBD
3
Reported by Coverity (CID 1465222).
4
tech lead. Add myself as the maintainer since I am the current RBD tech
5
lead.
6
4
7
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
5
Fixes: 4a1d937796de0fecd8b22d7dbebf87f38e8282fd ("softmmu/qdev-monitor: add error handling in qdev_set_id")
8
Reviewed-by: Josh Durgin <jdurgin@redhat.com>
6
Cc: Damien Hedde <damien.hedde@greensocs.com>
7
Cc: Kevin Wolf <kwolf@redhat.com>
8
Cc: Michael S. Tsirkin <mst@redhat.com>
9
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
10
Message-Id: <20211102163342.31162-1-stefanha@redhat.com>
11
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
12
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
14
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
15
Reviewed-by: Damien Hedde <damien.hedde@greensocs.com>
16
Reviewed-by: Markus Armbruster <armbru@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
18
---
11
MAINTAINERS | 2 +-
19
softmmu/qdev-monitor.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
20
1 file changed, 1 insertion(+), 1 deletion(-)
13
21
14
diff --git a/MAINTAINERS b/MAINTAINERS
22
diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
15
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
16
--- a/MAINTAINERS
24
--- a/softmmu/qdev-monitor.c
17
+++ b/MAINTAINERS
25
+++ b/softmmu/qdev-monitor.c
18
@@ -XXX,XX +XXX,XX @@ S: Supported
26
@@ -XXX,XX +XXX,XX @@ const char *qdev_set_id(DeviceState *dev, char *id, Error **errp)
19
F: block/vmdk.c
27
if (prop) {
20
28
dev->id = id;
21
RBD
29
} else {
22
-M: Josh Durgin <jdurgin@redhat.com>
30
- g_free(id);
23
+M: Jason Dillaman <dillaman@redhat.com>
31
error_setg(errp, "Duplicate device ID '%s'", id);
24
L: qemu-block@nongnu.org
32
+ g_free(id);
25
S: Supported
33
return NULL;
26
F: block/rbd.c
34
}
35
} else {
27
--
36
--
28
2.20.1
37
2.31.1
29
38
30
39
diff view generated by jsdifflib