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 |