mirror of https://github.com/xqemu/xqemu.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);
|
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
|
* monitor_protocol_event(): Generate a Monitor event
|
||||||
*
|
*
|
||||||
|
@ -435,68 +459,8 @@ void monitor_protocol_event(MonitorEvent event, QObject *data)
|
||||||
|
|
||||||
assert(event < QEVENT_MAX);
|
assert(event < QEVENT_MAX);
|
||||||
|
|
||||||
switch (event) {
|
event_name = monitor_event_names[event];
|
||||||
case QEVENT_SHUTDOWN:
|
assert(event_name != NULL);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
qmp = qdict_new();
|
qmp = qdict_new();
|
||||||
timestamp_put(qmp);
|
timestamp_put(qmp);
|
||||||
|
@ -738,6 +702,25 @@ CommandInfoList *qmp_query_commands(Error **errp)
|
||||||
return cmd_list;
|
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 */
|
/* set the current CPU defined by the user */
|
||||||
int monitor_set_cpu(int cpu_index)
|
int monitor_set_cpu(int cpu_index)
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,6 +41,10 @@ typedef enum MonitorEvent {
|
||||||
QEVENT_DEVICE_TRAY_MOVED,
|
QEVENT_DEVICE_TRAY_MOVED,
|
||||||
QEVENT_SUSPEND,
|
QEVENT_SUSPEND,
|
||||||
QEVENT_WAKEUP,
|
QEVENT_WAKEUP,
|
||||||
|
|
||||||
|
/* Add to 'monitor_event_names' array in monitor.c when
|
||||||
|
* defining new events here */
|
||||||
|
|
||||||
QEVENT_MAX,
|
QEVENT_MAX,
|
||||||
} MonitorEvent;
|
} MonitorEvent;
|
||||||
|
|
||||||
|
|
|
@ -227,6 +227,28 @@
|
||||||
##
|
##
|
||||||
{ 'command': 'query-commands', 'returns': ['CommandInfo'] }
|
{ '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
|
# @MigrationStats
|
||||||
#
|
#
|
||||||
|
|
|
@ -1208,6 +1208,43 @@ EQMP
|
||||||
.mhandler.cmd_new = qmp_marshal_input_query_commands,
|
.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
|
SQMP
|
||||||
query-chardev
|
query-chardev
|
||||||
-------------
|
-------------
|
||||||
|
|
Loading…
Reference in New Issue