1
In vhost-user protocol we have VHOST_USER_BACKEND_CONFIG_CHANGE_MSG,
1
v3:
2
which backend may send to notify Qemu, that we should re-read the
2
02: add r-b by Markus
3
config, and notify the guest.
3
03: improve commit message
4
04: improve documentation, merge race-fix here (which was v2:05),
5
rebase on master (migration_is_running() now without arguments)
6
05: improve documentation
4
7
5
Still that's not always convenient: backend may not support this
8
Vladimir Sementsov-Ogievskiy (5):
6
message. Also, having QMP command to force config sync is more reliable
7
than waiting for notification from external program. It also may be
8
helpful for debug/restore: if we have changed disk size, but guest
9
doesn't see that, it's good to have a separate QMP command to trigger
10
resync of the config.
11
12
So, the series proposes two experimental APIs:
13
14
1. x-device-sync-config command, to trigger config synchronization
15
16
2. X_CONFIG_READ event, which notify management tool that guest read the
17
updated config. Of course, that can't guarantee that the guest correctly
18
handled the updated config, but it's still better than nothing: for sure
19
guest will not show new disk size until it read the updated config. So,
20
management tool may wait for this event to report success to the user.
21
22
23
The series is based on "[PATCH v8 0/4] pci hotplug tracking": it doesn't
24
depend on it, but just modify same files, so I just to avoid extra
25
conflicts.
26
Based-on: <20231005092926.56231-1-vsementsov@yandex-team.ru>
27
28
Vladimir Sementsov-Ogievskiy (4):
29
vhost-user-blk: simplify and fix vhost_user_blk_handle_config_change
9
vhost-user-blk: simplify and fix vhost_user_blk_handle_config_change
10
qdev-monitor: fix error message in find_device_state()
11
qdev-monitor: add option to report GenericError from find_device_state
30
qapi: introduce device-sync-config
12
qapi: introduce device-sync-config
31
qapi: device-sync-config: check runstate
32
qapi: introduce CONFIG_READ event
13
qapi: introduce CONFIG_READ event
33
14
34
hw/block/vhost-user-blk.c | 32 ++++++++++++++---------
15
hw/block/vhost-user-blk.c | 32 +++++++++++-------
35
hw/virtio/virtio-pci.c | 18 +++++++++++++
16
hw/virtio/virtio-pci.c | 18 ++++++++++
36
include/hw/qdev-core.h | 3 +++
17
include/hw/qdev-core.h | 3 ++
37
include/monitor/qdev.h | 1 +
18
include/monitor/qdev.h | 2 ++
38
include/sysemu/runstate.h | 1 +
19
include/sysemu/runstate.h | 1 +
39
monitor/monitor.c | 1 +
20
monitor/monitor.c | 1 +
40
qapi/qdev.json | 36 ++++++++++++++++++++++++++
21
qapi/qdev.json | 54 ++++++++++++++++++++++++++++++
41
softmmu/qdev-monitor.c | 53 +++++++++++++++++++++++++++++++++++++++
22
stubs/qdev.c | 6 ++++
42
softmmu/runstate.c | 5 ++++
23
system/qdev-monitor.c | 70 ++++++++++++++++++++++++++++++++++++---
43
9 files changed, 138 insertions(+), 12 deletions(-)
24
system/runstate.c | 5 +++
25
10 files changed, 175 insertions(+), 17 deletions(-)
44
26
45
--
27
--
46
2.34.1
28
2.34.1
diff view generated by jsdifflib
...
...
10
3. vhost-user-vsock reads the whole config
10
3. vhost-user-vsock reads the whole config
11
11
12
4. on realize we don't do any checks on retrieved config, so no reason
12
4. on realize we don't do any checks on retrieved config, so no reason
13
to care here
13
to care here
14
14
15
Comment "valid for resize only" exists since introduction the whole
16
hw/block/vhost-user-blk.c in commit
17
00343e4b54ba0685e9ebe928ec5713b0cf7f1d1c
18
"vhost-user-blk: introduce a new vhost-user-blk host device",
19
seems it was just an extra limitation.
20
15
Also, let's notify guest unconditionally:
21
Also, let's notify guest unconditionally:
16
22
17
1. So does vhost-user-vsock
23
1. So does vhost-user-vsock
18
24
19
2. We are going to reuse the functionality in new cases when we do want
25
2. We are going to reuse the functionality in new cases when we do want
20
to notify the guest unconditionally. So, no reason to create extra
26
to notify the guest unconditionally. So, no reason to create extra
21
branches in the logic.
27
branches in the logic.
22
28
23
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
29
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
30
Acked-by: Raphael Norwitz <raphael.norwitz@nutanix.com>
24
---
31
---
25
hw/block/vhost-user-blk.c | 11 +++--------
32
hw/block/vhost-user-blk.c | 11 +++--------
26
1 file changed, 3 insertions(+), 8 deletions(-)
33
1 file changed, 3 insertions(+), 8 deletions(-)
27
34
28
diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
35
diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
...
...
diff view generated by jsdifflib
New patch
1
This "hotpluggable" here is misleading. Actually we check is object a
2
device or not. Let's drop the word.
1
3
4
Suggested-by: Markus Armbruster <armbru@redhat.com>
5
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
6
Reviewed-by: Markus Armbruster <armbru@redhat.com>
7
---
8
system/qdev-monitor.c | 2 +-
9
1 file changed, 1 insertion(+), 1 deletion(-)
10
11
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/system/qdev-monitor.c
14
+++ b/system/qdev-monitor.c
15
@@ -XXX,XX +XXX,XX @@ static DeviceState *find_device_state(const char *id, Error **errp)
16
17
dev = (DeviceState *)object_dynamic_cast(obj, TYPE_DEVICE);
18
if (!dev) {
19
- error_setg(errp, "%s is not a hotpluggable device", id);
20
+ error_setg(errp, "%s is not a device", id);
21
return NULL;
22
}
23
24
--
25
2.34.1
diff view generated by jsdifflib
1
Command result is racy if allow it during migration. Let's allow the
1
Here we just prepare for the following patch, making possible to report
2
sync only in RUNNING state.
2
GenericError as recommended.
3
4
This patch doesn't aim to prevent further use of DeviceNotFound by
5
future interfaces:
6
7
- find_device_state() is used in blk_by_qdev_id() and qmp_get_blk()
8
functions, which may lead to spread of DeviceNotFound anyway
9
- also, nothing prevent simply copy-pasting find_device_state() calls
10
with false argument
3
11
4
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
12
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
5
---
13
---
6
include/sysemu/runstate.h | 1 +
14
system/qdev-monitor.c | 15 +++++++++++----
7
softmmu/qdev-monitor.c | 27 ++++++++++++++++++++++++++-
15
1 file changed, 11 insertions(+), 4 deletions(-)
8
softmmu/runstate.c | 5 +++++
9
3 files changed, 32 insertions(+), 1 deletion(-)
10
16
11
diff --git a/include/sysemu/runstate.h b/include/sysemu/runstate.h
17
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/include/sysemu/runstate.h
19
--- a/system/qdev-monitor.c
14
+++ b/include/sysemu/runstate.h
20
+++ b/system/qdev-monitor.c
15
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp)
16
#include "qemu/notify.h"
22
object_unref(OBJECT(dev));
17
23
}
18
bool runstate_check(RunState state);
24
19
+const char *current_run_state_str(void);
25
-static DeviceState *find_device_state(const char *id, Error **errp)
20
void runstate_set(RunState new_state);
26
+/*
21
RunState runstate_get(void);
27
+ * Note that creating new APIs using error classes other than GenericError is
22
bool runstate_is_running(void);
28
+ * not recommended. Set use_generic_error=true for new interfaces.
23
diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
29
+ */
24
index XXXXXXX..XXXXXXX 100644
30
+static DeviceState *find_device_state(const char *id, bool use_generic_error,
25
--- a/softmmu/qdev-monitor.c
31
+ Error **errp)
26
+++ b/softmmu/qdev-monitor.c
32
{
27
@@ -XXX,XX +XXX,XX @@
33
Object *obj = object_resolve_path_at(qdev_get_peripheral(), id);
28
#include "monitor/monitor.h"
34
DeviceState *dev;
29
#include "monitor/qdev.h"
35
30
#include "sysemu/arch_init.h"
36
if (!obj) {
31
+#include "sysemu/runstate.h"
37
- error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
32
#include "qapi/error.h"
38
+ error_set(errp,
33
#include "qapi/qapi-commands-qdev.h"
39
+ (use_generic_error ?
34
#include "qapi/qapi-events-qdev.h"
40
+ ERROR_CLASS_GENERIC_ERROR : ERROR_CLASS_DEVICE_NOT_FOUND),
35
@@ -XXX,XX +XXX,XX @@ int qdev_sync_config(DeviceState *dev, Error **errp)
41
"Device '%s' not found", id);
36
42
return NULL;
37
void qmp_x_device_sync_config(const char *id, Error **errp)
43
}
44
@@ -XXX,XX +XXX,XX @@ void qdev_unplug(DeviceState *dev, Error **errp)
45
46
void qmp_device_del(const char *id, Error **errp)
38
{
47
{
39
- DeviceState *dev = find_device_state(id, errp);
48
- DeviceState *dev = find_device_state(id, errp);
40
+ MigrationState *s = migrate_get_current();
49
+ DeviceState *dev = find_device_state(id, false, errp);
41
+ DeviceState *dev;
50
if (dev != NULL) {
42
+
51
if (dev->pending_deleted_event &&
43
+ /*
52
(dev->pending_deleted_expires_ms == 0 ||
44
+ * During migration there is a race between syncing`config and migrating it,
53
@@ -XXX,XX +XXX,XX @@ BlockBackend *blk_by_qdev_id(const char *id, Error **errp)
45
+ * so let's just not allow it.
54
46
+ *
55
GLOBAL_STATE_CODE();
47
+ * Moreover, let's not rely on setting up interrupts in paused state, which
56
48
+ * may be a part of migration process.
57
- dev = find_device_state(id, errp);
49
+ */
58
+ dev = find_device_state(id, false, errp);
50
+
59
if (dev == NULL) {
51
+ if (migration_is_running(s->state)) {
60
return NULL;
52
+ error_setg(errp, "Config synchronization is not allowed "
53
+ "during migration.");
54
+ return;
55
+ }
56
+
57
+ if (!runstate_is_running()) {
58
+ error_setg(errp, "Config synchronization allowed only in '%s' state, "
59
+ "current state is '%s'", RunState_str(RUN_STATE_RUNNING),
60
+ current_run_state_str());
61
+ return;
62
+ }
63
+
64
+ dev = find_device_state(id, errp);
65
if (!dev) {
66
return;
67
}
61
}
68
diff --git a/softmmu/runstate.c b/softmmu/runstate.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/softmmu/runstate.c
71
+++ b/softmmu/runstate.c
72
@@ -XXX,XX +XXX,XX @@ bool runstate_check(RunState state)
73
return current_run_state == state;
74
}
75
76
+const char *current_run_state_str(void)
77
+{
78
+ return RunState_str(current_run_state);
79
+}
80
+
81
static void runstate_init(void)
82
{
83
const RunStateTransition *p;
84
--
62
--
85
2.34.1
63
2.34.1
diff view generated by jsdifflib
1
Add command to sync config from vhost-user backend to the device. It
1
Add command to sync config from vhost-user backend to the device. It
2
may be helpful when VHOST_USER_SLAVE_CONFIG_CHANGE_MSG failed or not
2
may be helpful when VHOST_USER_SLAVE_CONFIG_CHANGE_MSG failed or not
3
triggered interrupt to the guest or just not available (not supported
3
triggered interrupt to the guest or just not available (not supported
4
by vhost-user server).
4
by vhost-user server).
5
5
6
Command result is racy if allow it during migration. Let's allow the
7
sync only in RUNNING state.
8
6
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
9
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
7
---
10
---
8
hw/block/vhost-user-blk.c | 27 ++++++++++++++++++++-------
11
hw/block/vhost-user-blk.c | 27 ++++++++++++++++------
9
hw/virtio/virtio-pci.c | 9 +++++++++
12
hw/virtio/virtio-pci.c | 9 ++++++++
10
include/hw/qdev-core.h | 3 +++
13
include/hw/qdev-core.h | 3 +++
11
qapi/qdev.json | 14 ++++++++++++++
14
include/sysemu/runstate.h | 1 +
12
softmmu/qdev-monitor.c | 23 +++++++++++++++++++++++
15
qapi/qdev.json | 21 +++++++++++++++++
13
5 files changed, 69 insertions(+), 7 deletions(-)
16
system/qdev-monitor.c | 47 +++++++++++++++++++++++++++++++++++++++
17
system/runstate.c | 5 +++++
18
7 files changed, 106 insertions(+), 7 deletions(-)
14
19
15
diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
20
diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
16
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/block/vhost-user-blk.c
22
--- a/hw/block/vhost-user-blk.c
18
+++ b/hw/block/vhost-user-blk.c
23
+++ b/hw/block/vhost-user-blk.c
...
...
124
void qdev_unplug(DeviceState *dev, Error **errp);
129
void qdev_unplug(DeviceState *dev, Error **errp);
125
+int qdev_sync_config(DeviceState *dev, Error **errp);
130
+int qdev_sync_config(DeviceState *dev, Error **errp);
126
void qdev_simple_device_unplug_cb(HotplugHandler *hotplug_dev,
131
void qdev_simple_device_unplug_cb(HotplugHandler *hotplug_dev,
127
DeviceState *dev, Error **errp);
132
DeviceState *dev, Error **errp);
128
void qdev_machine_creation_done(void);
133
void qdev_machine_creation_done(void);
134
diff --git a/include/sysemu/runstate.h b/include/sysemu/runstate.h
135
index XXXXXXX..XXXXXXX 100644
136
--- a/include/sysemu/runstate.h
137
+++ b/include/sysemu/runstate.h
138
@@ -XXX,XX +XXX,XX @@
139
#include "qemu/notify.h"
140
141
bool runstate_check(RunState state);
142
+const char *current_run_state_str(void);
143
void runstate_set(RunState new_state);
144
RunState runstate_get(void);
145
bool runstate_is_running(void);
129
diff --git a/qapi/qdev.json b/qapi/qdev.json
146
diff --git a/qapi/qdev.json b/qapi/qdev.json
130
index XXXXXXX..XXXXXXX 100644
147
index XXXXXXX..XXXXXXX 100644
131
--- a/qapi/qdev.json
148
--- a/qapi/qdev.json
132
+++ b/qapi/qdev.json
149
+++ b/qapi/qdev.json
133
@@ -XXX,XX +XXX,XX @@
150
@@ -XXX,XX +XXX,XX @@
134
# Since: 8.2
135
##
151
##
136
{ 'event': 'X_DEVICE_ON', 'data': 'DeviceAndPath' }
152
{ 'event': 'DEVICE_UNPLUG_GUEST_ERROR',
153
'data': { '*device': 'str', 'path': 'str' } }
137
+
154
+
138
+##
155
+##
139
+# @x-device-sync-config:
156
+# @device-sync-config:
140
+#
157
+#
141
+# Sync config from backend to the guest.
158
+# Synchronize config from backend to the guest. The command notifies
159
+# re-read the device config from the backend and notifies the guest
160
+# to re-read the config. The command may be used to notify the guest
161
+# about block device capcity change. Currently only vhost-user-blk
162
+# device supports this.
142
+#
163
+#
143
+# @id: the device's ID or QOM path
164
+# @id: the device's ID or QOM path
144
+#
165
+#
145
+# Returns: Nothing on success
166
+# Features:
146
+# If @id is not a valid device, DeviceNotFound
167
+#
147
+#
168
+# @unstable: The command is experimental.
148
+# Since: 8.2
169
+#
170
+# Since: 9.1
149
+##
171
+##
150
+{ 'command': 'x-device-sync-config', 'data': {'id': 'str'} }
172
+{ 'command': 'device-sync-config',
151
diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
173
+ 'features': [ 'unstable' ],
152
index XXXXXXX..XXXXXXX 100644
174
+ 'data': {'id': 'str'} }
153
--- a/softmmu/qdev-monitor.c
175
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
154
+++ b/softmmu/qdev-monitor.c
176
index XXXXXXX..XXXXXXX 100644
155
@@ -XXX,XX +XXX,XX @@ HotplugInfo *qmp_x_query_hotplug(const char *id, Error **errp)
177
--- a/system/qdev-monitor.c
156
return hotplug_handler_get_state(hotplug_ctrl, dev, errp);
178
+++ b/system/qdev-monitor.c
157
}
179
@@ -XXX,XX +XXX,XX @@
180
#include "monitor/monitor.h"
181
#include "monitor/qdev.h"
182
#include "sysemu/arch_init.h"
183
+#include "sysemu/runstate.h"
184
#include "qapi/error.h"
185
#include "qapi/qapi-commands-qdev.h"
186
#include "qapi/qmp/dispatch.h"
187
@@ -XXX,XX +XXX,XX @@ void qmp_device_del(const char *id, Error **errp)
188
}
189
}
158
190
159
+int qdev_sync_config(DeviceState *dev, Error **errp)
191
+int qdev_sync_config(DeviceState *dev, Error **errp)
160
+{
192
+{
161
+ DeviceClass *dc = DEVICE_GET_CLASS(dev);
193
+ DeviceClass *dc = DEVICE_GET_CLASS(dev);
162
+
194
+
...
...
167
+ }
199
+ }
168
+
200
+
169
+ return dc->sync_config(dev, errp);
201
+ return dc->sync_config(dev, errp);
170
+}
202
+}
171
+
203
+
172
+void qmp_x_device_sync_config(const char *id, Error **errp)
204
+void qmp_device_sync_config(const char *id, Error **errp)
173
+{
205
+{
174
+ DeviceState *dev = find_device_state(id, errp);
206
+ DeviceState *dev;
207
+
208
+ /*
209
+ * During migration there is a race between syncing`config and
210
+ * migrating it, so let's just not allow it.
211
+ *
212
+ * Moreover, let's not rely on setting up interrupts in paused
213
+ * state, which may be a part of migration process.
214
+ */
215
+
216
+ if (migration_is_running()) {
217
+ error_setg(errp, "Config synchronization is not allowed "
218
+ "during migration.");
219
+ return;
220
+ }
221
+
222
+ if (!runstate_is_running()) {
223
+ error_setg(errp, "Config synchronization allowed only in '%s' state, "
224
+ "current state is '%s'", RunState_str(RUN_STATE_RUNNING),
225
+ current_run_state_str());
226
+ return;
227
+ }
228
+
229
+ dev = find_device_state(id, true, errp);
175
+ if (!dev) {
230
+ if (!dev) {
176
+ return;
231
+ return;
177
+ }
232
+ }
178
+
233
+
179
+ qdev_sync_config(dev, errp);
234
+ qdev_sync_config(dev, errp);
180
+}
235
+}
181
+
236
+
182
void hmp_device_add(Monitor *mon, const QDict *qdict)
237
void hmp_device_add(Monitor *mon, const QDict *qdict)
183
{
238
{
184
Error *err = NULL;
239
Error *err = NULL;
240
diff --git a/system/runstate.c b/system/runstate.c
241
index XXXXXXX..XXXXXXX 100644
242
--- a/system/runstate.c
243
+++ b/system/runstate.c
244
@@ -XXX,XX +XXX,XX @@ bool runstate_check(RunState state)
245
return current_run_state == state;
246
}
247
248
+const char *current_run_state_str(void)
249
+{
250
+ return RunState_str(current_run_state);
251
+}
252
+
253
static void runstate_init(void)
254
{
255
const RunStateTransition *p;
185
--
256
--
186
2.34.1
257
2.34.1
diff view generated by jsdifflib
...
...
5
after resizing disk backend.
5
after resizing disk backend.
6
6
7
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
7
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
8
---
8
---
9
hw/virtio/virtio-pci.c | 9 +++++++++
9
hw/virtio/virtio-pci.c | 9 +++++++++
10
include/monitor/qdev.h | 1 +
10
include/monitor/qdev.h | 2 ++
11
monitor/monitor.c | 1 +
11
monitor/monitor.c | 1 +
12
qapi/qdev.json | 22 ++++++++++++++++++++++
12
qapi/qdev.json | 33 +++++++++++++++++++++++++++++++++
13
softmmu/qdev-monitor.c | 5 +++++
13
stubs/qdev.c | 6 ++++++
14
5 files changed, 38 insertions(+)
14
system/qdev-monitor.c | 6 ++++++
15
6 files changed, 57 insertions(+)
15
16
16
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
17
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/virtio/virtio-pci.c
19
--- a/hw/virtio/virtio-pci.c
19
+++ b/hw/virtio/virtio-pci.c
20
+++ b/hw/virtio/virtio-pci.c
...
...
28
@@ -XXX,XX +XXX,XX @@ static uint64_t virtio_pci_config_read(void *opaque, hwaddr addr,
29
@@ -XXX,XX +XXX,XX @@ static uint64_t virtio_pci_config_read(void *opaque, hwaddr addr,
29
}
30
}
30
addr -= config;
31
addr -= config;
31
32
32
+ if (vdev->generation > 0) {
33
+ if (vdev->generation > 0) {
33
+ qdev_config_read_event(DEVICE(proxy));
34
+ qdev_virtio_config_read_event(DEVICE(proxy));
34
+ }
35
+ }
35
+
36
+
36
switch (size) {
37
switch (size) {
37
case 1:
38
case 1:
38
val = virtio_config_readb(vdev, addr);
39
val = virtio_config_readb(vdev, addr);
39
@@ -XXX,XX +XXX,XX @@ static uint64_t virtio_pci_device_read(void *opaque, hwaddr addr,
40
@@ -XXX,XX +XXX,XX @@ static uint64_t virtio_pci_device_read(void *opaque, hwaddr addr,
40
return UINT64_MAX;
41
return UINT64_MAX;
41
}
42
}
42
43
43
+ if (vdev->generation > 0) {
44
+ if (vdev->generation > 0) {
44
+ qdev_config_read_event(DEVICE(proxy));
45
+ qdev_virtio_config_read_event(DEVICE(proxy));
45
+ }
46
+ }
46
+
47
+
47
switch (size) {
48
switch (size) {
48
case 1:
49
case 1:
49
val = virtio_config_modern_readb(vdev, addr);
50
val = virtio_config_modern_readb(vdev, addr);
50
diff --git a/include/monitor/qdev.h b/include/monitor/qdev.h
51
diff --git a/include/monitor/qdev.h b/include/monitor/qdev.h
51
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
52
--- a/include/monitor/qdev.h
53
--- a/include/monitor/qdev.h
53
+++ b/include/monitor/qdev.h
54
+++ b/include/monitor/qdev.h
54
@@ -XXX,XX +XXX,XX @@ DeviceState *qdev_device_add_from_qdict(const QDict *opts,
55
@@ -XXX,XX +XXX,XX @@ DeviceState *qdev_device_add_from_qdict(const QDict *opts,
56
*/
55
const char *qdev_set_id(DeviceState *dev, char *id, Error **errp);
57
const char *qdev_set_id(DeviceState *dev, char *id, Error **errp);
56
58
57
void qdev_hotplug_device_on_event(DeviceState *dev);
59
+void qdev_virtio_config_read_event(DeviceState *dev);
58
+void qdev_config_read_event(DeviceState *dev);
60
+
59
61
#endif
60
DeviceAndPath *qdev_new_device_and_path(DeviceState *dev);
61
62
diff --git a/monitor/monitor.c b/monitor/monitor.c
62
diff --git a/monitor/monitor.c b/monitor/monitor.c
63
index XXXXXXX..XXXXXXX 100644
63
index XXXXXXX..XXXXXXX 100644
64
--- a/monitor/monitor.c
64
--- a/monitor/monitor.c
65
+++ b/monitor/monitor.c
65
+++ b/monitor/monitor.c
66
@@ -XXX,XX +XXX,XX @@ static MonitorQAPIEventConf monitor_qapi_event_conf[QAPI_EVENT__MAX] = {
66
@@ -XXX,XX +XXX,XX @@ static MonitorQAPIEventConf monitor_qapi_event_conf[QAPI_EVENT__MAX] = {
67
[QAPI_EVENT_QUORUM_FAILURE] = { 1000 * SCALE_MS },
68
[QAPI_EVENT_VSERPORT_CHANGE] = { 1000 * SCALE_MS },
67
[QAPI_EVENT_VSERPORT_CHANGE] = { 1000 * SCALE_MS },
69
[QAPI_EVENT_MEMORY_DEVICE_SIZE_CHANGE] = { 1000 * SCALE_MS },
68
[QAPI_EVENT_MEMORY_DEVICE_SIZE_CHANGE] = { 1000 * SCALE_MS },
70
+ [QAPI_EVENT_X_CONFIG_READ] = { 300 * SCALE_MS },
69
[QAPI_EVENT_HV_BALLOON_STATUS_REPORT] = { 1000 * SCALE_MS },
70
+ [QAPI_EVENT_VIRTIO_CONFIG_READ] = { 300 * SCALE_MS },
71
};
71
};
72
72
73
/*
73
/*
74
diff --git a/qapi/qdev.json b/qapi/qdev.json
74
diff --git a/qapi/qdev.json b/qapi/qdev.json
75
index XXXXXXX..XXXXXXX 100644
75
index XXXXXXX..XXXXXXX 100644
76
--- a/qapi/qdev.json
76
--- a/qapi/qdev.json
77
+++ b/qapi/qdev.json
77
+++ b/qapi/qdev.json
78
@@ -XXX,XX +XXX,XX @@
78
@@ -XXX,XX +XXX,XX @@
79
# Since: 8.2
79
{ 'command': 'device-sync-config',
80
##
80
'features': [ 'unstable' ],
81
{ 'command': 'x-device-sync-config', 'data': {'id': 'str'} }
81
'data': {'id': 'str'} }
82
+
82
+
83
+##
83
+##
84
+# @X_CONFIG_READ:
84
+# @VIRTIO_CONFIG_READ:
85
+#
85
+#
86
+# Emitted whenever guest reads virtio device config after config change.
86
+# Emitted whenever guest reads virtio device configuration after
87
+# configuration change.
88
+#
89
+# The event may be used in pair with device-sync-config. It shows
90
+# that guest has re-read updated configuration. It doesn't
91
+# guarantee that guest successfully handled it and updated the
92
+# view of the device for the user, but still it's a kind of
93
+# success indicator.
87
+#
94
+#
88
+# @device: device name
95
+# @device: device name
89
+#
96
+#
90
+# @path: device path
97
+# @path: device path
91
+#
98
+#
92
+# Since: 5.0.1-24
99
+# Features:
100
+#
101
+# @unstable: The event is experimental.
102
+#
103
+# Since: 9.1
93
+#
104
+#
94
+# Example:
105
+# Example:
95
+#
106
+#
96
+# <- { "event": "X_CONFIG_READ",
107
+# <- { "event": "VIRTIO_CONFIG_READ",
97
+# "data": { "device": "virtio-net-pci-0",
108
+# "data": { "device": "virtio-net-pci-0",
98
+# "path": "/machine/peripheral/virtio-net-pci-0" },
109
+# "path": "/machine/peripheral/virtio-net-pci-0" },
99
+# "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
110
+# "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
100
+#
101
+##
111
+##
102
+{ 'event': 'X_CONFIG_READ',
112
+{ 'event': 'VIRTIO_CONFIG_READ',
113
+ 'features': [ 'unstable' ],
103
+ 'data': { '*device': 'str', 'path': 'str' } }
114
+ 'data': { '*device': 'str', 'path': 'str' } }
104
diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
115
diff --git a/stubs/qdev.c b/stubs/qdev.c
105
index XXXXXXX..XXXXXXX 100644
116
index XXXXXXX..XXXXXXX 100644
106
--- a/softmmu/qdev-monitor.c
117
--- a/stubs/qdev.c
107
+++ b/softmmu/qdev-monitor.c
118
+++ b/stubs/qdev.c
108
@@ -XXX,XX +XXX,XX @@ void qdev_hotplug_device_on_event(DeviceState *dev)
119
@@ -XXX,XX +XXX,XX @@ void qapi_event_send_device_unplug_guest_error(const char *device,
109
dev->device_on_event_sent = true;
120
{
110
qapi_event_send_x_device_on(dev->id, dev->canonical_path);
121
/* Nothing to do. */
111
}
122
}
112
+
123
+
113
+void qdev_config_read_event(DeviceState *dev)
124
+void qapi_event_send_virtio_config_read(const char *device,
125
+ const char *path)
114
+{
126
+{
115
+ qapi_event_send_x_config_read(dev->id, dev->canonical_path);
127
+ /* Nothing to do. */
128
+}
129
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
130
index XXXXXXX..XXXXXXX 100644
131
--- a/system/qdev-monitor.c
132
+++ b/system/qdev-monitor.c
133
@@ -XXX,XX +XXX,XX @@
134
#include "sysemu/runstate.h"
135
#include "qapi/error.h"
136
#include "qapi/qapi-commands-qdev.h"
137
+#include "qapi/qapi-events-qdev.h"
138
#include "qapi/qmp/dispatch.h"
139
#include "qapi/qmp/qdict.h"
140
#include "qapi/qmp/qerror.h"
141
@@ -XXX,XX +XXX,XX @@ bool qmp_command_available(const QmpCommand *cmd, Error **errp)
142
}
143
return true;
144
}
145
+
146
+void qdev_virtio_config_read_event(DeviceState *dev)
147
+{
148
+ qapi_event_send_virtio_config_read(dev->id, dev->canonical_path);
116
+}
149
+}
117
--
150
--
118
2.34.1
151
2.34.1
diff view generated by jsdifflib