mirror of https://gitee.com/openkylin/qemu.git
Add 'query-events' command to QMP to query async events
Sometimes it is neccessary for an application to determine whether a particular QMP event is available, so they can decide whether to use compatibility code instead. This introduces a new 'query-events' command to QMP to do just that { "execute": "query-events" } {"return": [{"name": "WAKEUP"}, {"name": "SUSPEND"}, {"name": "DEVICE_TRAY_MOVED"}, {"name": "BLOCK_JOB_CANCELLED"}, {"name": "BLOCK_JOB_COMPLETED"}, ...snip... {"name": "SHUTDOWN"}]} * monitor.c: Turn MonitorEvent -> string conversion into a lookup from a static table of constant strings. Add impl of qmp_query_events monitor command handler * qapi-schema.json, qmp-commands.hx: Define contract of query-events command Signed-off-by: Daniel P. Berrange <berrange@redhat.com> Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
This commit is contained in:
parent
5f96415527
commit
4860853d60
107
monitor.c
107
monitor.c
|
@ -422,6 +422,30 @@ static void timestamp_put(QDict *qdict)
|
|||
qdict_put_obj(qdict, "timestamp", obj);
|
||||
}
|
||||
|
||||
|
||||
static const char *monitor_event_names[] = {
|
||||
[QEVENT_SHUTDOWN] = "SHUTDOWN",
|
||||
[QEVENT_RESET] = "RESET",
|
||||
[QEVENT_POWERDOWN] = "POWERDOWN",
|
||||
[QEVENT_STOP] = "STOP",
|
||||
[QEVENT_RESUME] = "RESUME",
|
||||
[QEVENT_VNC_CONNECTED] = "VNC_CONNECTED",
|
||||
[QEVENT_VNC_INITIALIZED] = "VNC_INITIALIZED",
|
||||
[QEVENT_VNC_DISCONNECTED] = "VNC_DISCONNECTED",
|
||||
[QEVENT_BLOCK_IO_ERROR] = "BLOCK_IO_ERROR",
|
||||
[QEVENT_RTC_CHANGE] = "RTC_CHANGE",
|
||||
[QEVENT_WATCHDOG] = "WATCHDOG",
|
||||
[QEVENT_SPICE_CONNECTED] = "SPICE_CONNECTED",
|
||||
[QEVENT_SPICE_INITIALIZED] = "SPICE_INITIALIZED",
|
||||
[QEVENT_SPICE_DISCONNECTED] = "SPICE_DISCONNECTED",
|
||||
[QEVENT_BLOCK_JOB_COMPLETED] = "BLOCK_JOB_COMPLETED",
|
||||
[QEVENT_BLOCK_JOB_CANCELLED] = "BLOCK_JOB_CANCELLED",
|
||||
[QEVENT_DEVICE_TRAY_MOVED] = "DEVICE_TRAY_MOVED",
|
||||
[QEVENT_SUSPEND] = "SUSPEND",
|
||||
[QEVENT_WAKEUP] = "WAKEUP",
|
||||
};
|
||||
QEMU_BUILD_BUG_ON(ARRAY_SIZE(monitor_event_names) != QEVENT_MAX)
|
||||
|
||||
/**
|
||||
* monitor_protocol_event(): Generate a Monitor event
|
||||
*
|
||||
|
@ -435,68 +459,8 @@ void monitor_protocol_event(MonitorEvent event, QObject *data)
|
|||
|
||||
assert(event < QEVENT_MAX);
|
||||
|
||||
switch (event) {
|
||||
case QEVENT_SHUTDOWN:
|
||||
event_name = "SHUTDOWN";
|
||||
break;
|
||||
case QEVENT_RESET:
|
||||
event_name = "RESET";
|
||||
break;
|
||||
case QEVENT_POWERDOWN:
|
||||
event_name = "POWERDOWN";
|
||||
break;
|
||||
case QEVENT_STOP:
|
||||
event_name = "STOP";
|
||||
break;
|
||||
case QEVENT_RESUME:
|
||||
event_name = "RESUME";
|
||||
break;
|
||||
case QEVENT_VNC_CONNECTED:
|
||||
event_name = "VNC_CONNECTED";
|
||||
break;
|
||||
case QEVENT_VNC_INITIALIZED:
|
||||
event_name = "VNC_INITIALIZED";
|
||||
break;
|
||||
case QEVENT_VNC_DISCONNECTED:
|
||||
event_name = "VNC_DISCONNECTED";
|
||||
break;
|
||||
case QEVENT_BLOCK_IO_ERROR:
|
||||
event_name = "BLOCK_IO_ERROR";
|
||||
break;
|
||||
case QEVENT_RTC_CHANGE:
|
||||
event_name = "RTC_CHANGE";
|
||||
break;
|
||||
case QEVENT_WATCHDOG:
|
||||
event_name = "WATCHDOG";
|
||||
break;
|
||||
case QEVENT_SPICE_CONNECTED:
|
||||
event_name = "SPICE_CONNECTED";
|
||||
break;
|
||||
case QEVENT_SPICE_INITIALIZED:
|
||||
event_name = "SPICE_INITIALIZED";
|
||||
break;
|
||||
case QEVENT_SPICE_DISCONNECTED:
|
||||
event_name = "SPICE_DISCONNECTED";
|
||||
break;
|
||||
case QEVENT_BLOCK_JOB_COMPLETED:
|
||||
event_name = "BLOCK_JOB_COMPLETED";
|
||||
break;
|
||||
case QEVENT_BLOCK_JOB_CANCELLED:
|
||||
event_name = "BLOCK_JOB_CANCELLED";
|
||||
break;
|
||||
case QEVENT_DEVICE_TRAY_MOVED:
|
||||
event_name = "DEVICE_TRAY_MOVED";
|
||||
break;
|
||||
case QEVENT_SUSPEND:
|
||||
event_name = "SUSPEND";
|
||||
break;
|
||||
case QEVENT_WAKEUP:
|
||||
event_name = "WAKEUP";
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
break;
|
||||
}
|
||||
event_name = monitor_event_names[event];
|
||||
assert(event_name != NULL);
|
||||
|
||||
qmp = qdict_new();
|
||||
timestamp_put(qmp);
|
||||
|
@ -738,6 +702,25 @@ CommandInfoList *qmp_query_commands(Error **errp)
|
|||
return cmd_list;
|
||||
}
|
||||
|
||||
EventInfoList *qmp_query_events(Error **errp)
|
||||
{
|
||||
EventInfoList *info, *ev_list = NULL;
|
||||
MonitorEvent e;
|
||||
|
||||
for (e = 0 ; e < QEVENT_MAX ; e++) {
|
||||
const char *event_name = monitor_event_names[e];
|
||||
assert(event_name != NULL);
|
||||
info = g_malloc0(sizeof(*info));
|
||||
info->value = g_malloc0(sizeof(*info->value));
|
||||
info->value->name = g_strdup(event_name);
|
||||
|
||||
info->next = ev_list;
|
||||
ev_list = info;
|
||||
}
|
||||
|
||||
return ev_list;
|
||||
}
|
||||
|
||||
/* set the current CPU defined by the user */
|
||||
int monitor_set_cpu(int cpu_index)
|
||||
{
|
||||
|
|
|
@ -41,6 +41,10 @@ typedef enum MonitorEvent {
|
|||
QEVENT_DEVICE_TRAY_MOVED,
|
||||
QEVENT_SUSPEND,
|
||||
QEVENT_WAKEUP,
|
||||
|
||||
/* Add to 'monitor_event_names' array in monitor.c when
|
||||
* defining new events here */
|
||||
|
||||
QEVENT_MAX,
|
||||
} MonitorEvent;
|
||||
|
||||
|
|
|
@ -227,6 +227,28 @@
|
|||
##
|
||||
{ 'command': 'query-commands', 'returns': ['CommandInfo'] }
|
||||
|
||||
##
|
||||
# @EventInfo:
|
||||
#
|
||||
# Information about a QMP event
|
||||
#
|
||||
# @name: The event name
|
||||
#
|
||||
# Since: 1.2.0
|
||||
##
|
||||
{ 'type': 'EventInfo', 'data': {'name': 'str'} }
|
||||
|
||||
##
|
||||
# @query-events:
|
||||
#
|
||||
# Return a list of supported QMP events by this server
|
||||
#
|
||||
# Returns: A list of @EventInfo for all supported events
|
||||
#
|
||||
# Since: 1.2.0
|
||||
##
|
||||
{ 'command': 'query-events', 'returns': ['EventInfo'] }
|
||||
|
||||
##
|
||||
# @MigrationStats
|
||||
#
|
||||
|
|
|
@ -1208,6 +1208,43 @@ EQMP
|
|||
.mhandler.cmd_new = qmp_marshal_input_query_commands,
|
||||
},
|
||||
|
||||
SQMP
|
||||
query-events
|
||||
--------------
|
||||
|
||||
List QMP available events.
|
||||
|
||||
Each event is represented by a json-object, the returned value is a json-array
|
||||
of all events.
|
||||
|
||||
Each json-object contains:
|
||||
|
||||
- "name": event's name (json-string)
|
||||
|
||||
Example:
|
||||
|
||||
-> { "execute": "query-events" }
|
||||
<- {
|
||||
"return":[
|
||||
{
|
||||
"name":"SHUTDOWN"
|
||||
},
|
||||
{
|
||||
"name":"RESET"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Note: This example has been shortened as the real response is too long.
|
||||
|
||||
EQMP
|
||||
|
||||
{
|
||||
.name = "query-events",
|
||||
.args_type = "",
|
||||
.mhandler.cmd_new = qmp_marshal_input_query_events,
|
||||
},
|
||||
|
||||
SQMP
|
||||
query-chardev
|
||||
-------------
|
||||
|
|
Loading…
Reference in New Issue