mirror of https://github.com/xemu-project/xemu.git
qapi event: convert SPICE events
SPICE_INITIALIZED, SPICE_CONNECTED, SPICE_DISCONNECTED and SPICE_MIGRATE_COMPLETED are converted in one patch, since they use some common functions. inet_strfamily() is removed since no callers exist anymore. Note that there is no existing doc for SPICE_MIGRATE_COMPLETED in docs/qmp/qmp-events.txt before this patch. Signed-off-by: Wenchao Xia <wenchaoqemu@gmail.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
This commit is contained in:
parent
fb6ba0d525
commit
7cfadb6b52
|
@ -80,65 +80,3 @@ Example:
|
||||||
{ "event": "QUORUM_REPORT_BAD",
|
{ "event": "QUORUM_REPORT_BAD",
|
||||||
"data": { "node-name": "1.raw", "sector-num": 345435, "sector-count": 5 },
|
"data": { "node-name": "1.raw", "sector-num": 345435, "sector-count": 5 },
|
||||||
"timestamp": { "seconds": 1344522075, "microseconds": 745528 } }
|
"timestamp": { "seconds": 1344522075, "microseconds": 745528 } }
|
||||||
|
|
||||||
SPICE_CONNECTED, SPICE_DISCONNECTED
|
|
||||||
-----------------------------------
|
|
||||||
|
|
||||||
Emitted when a SPICE client connects or disconnects.
|
|
||||||
|
|
||||||
Data:
|
|
||||||
|
|
||||||
- "server": Server information (json-object)
|
|
||||||
- "host": IP address (json-string)
|
|
||||||
- "port": port number (json-string)
|
|
||||||
- "family": address family (json-string, "ipv4" or "ipv6")
|
|
||||||
- "client": Client information (json-object)
|
|
||||||
- "host": IP address (json-string)
|
|
||||||
- "port": port number (json-string)
|
|
||||||
- "family": address family (json-string, "ipv4" or "ipv6")
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
{ "timestamp": {"seconds": 1290688046, "microseconds": 388707},
|
|
||||||
"event": "SPICE_CONNECTED",
|
|
||||||
"data": {
|
|
||||||
"server": { "port": "5920", "family": "ipv4", "host": "127.0.0.1"},
|
|
||||||
"client": {"port": "52873", "family": "ipv4", "host": "127.0.0.1"}
|
|
||||||
}}
|
|
||||||
|
|
||||||
SPICE_INITIALIZED
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
Emitted after initial handshake and authentication takes place (if any)
|
|
||||||
and the SPICE channel is up'n'running
|
|
||||||
|
|
||||||
Data:
|
|
||||||
|
|
||||||
- "server": Server information (json-object)
|
|
||||||
- "host": IP address (json-string)
|
|
||||||
- "port": port number (json-string)
|
|
||||||
- "family": address family (json-string, "ipv4" or "ipv6")
|
|
||||||
- "auth": authentication method (json-string, optional)
|
|
||||||
- "client": Client information (json-object)
|
|
||||||
- "host": IP address (json-string)
|
|
||||||
- "port": port number (json-string)
|
|
||||||
- "family": address family (json-string, "ipv4" or "ipv6")
|
|
||||||
- "connection-id": spice connection id. All channels with the same id
|
|
||||||
belong to the same spice session (json-int)
|
|
||||||
- "channel-type": channel type. "1" is the main control channel, filter for
|
|
||||||
this one if you want track spice sessions only (json-int)
|
|
||||||
- "channel-id": channel id. Usually "0", might be different needed when
|
|
||||||
multiple channels of the same type exist, such as multiple
|
|
||||||
display channels in a multihead setup (json-int)
|
|
||||||
- "tls": whevener the channel is encrypted (json-bool)
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
{ "timestamp": {"seconds": 1290688046, "microseconds": 417172},
|
|
||||||
"event": "SPICE_INITIALIZED",
|
|
||||||
"data": {"server": {"auth": "spice", "port": "5921",
|
|
||||||
"family": "ipv4", "host": "127.0.0.1"},
|
|
||||||
"client": {"port": "49004", "family": "ipv4", "channel-type": 3,
|
|
||||||
"connection-id": 1804289383, "host": "127.0.0.1",
|
|
||||||
"channel-id": 0, "tls": true}
|
|
||||||
}}
|
|
||||||
|
|
|
@ -61,7 +61,6 @@ int inet_nonblocking_connect(const char *str,
|
||||||
void *opaque, Error **errp);
|
void *opaque, Error **errp);
|
||||||
|
|
||||||
int inet_dgram_opts(QemuOpts *opts, Error **errp);
|
int inet_dgram_opts(QemuOpts *opts, Error **errp);
|
||||||
const char *inet_strfamily(int family);
|
|
||||||
NetworkAddressFamily inet_netfamily(int family);
|
NetworkAddressFamily inet_netfamily(int family);
|
||||||
|
|
||||||
int unix_listen_opts(QemuOpts *opts, Error **errp);
|
int unix_listen_opts(QemuOpts *opts, Error **errp);
|
||||||
|
|
|
@ -186,3 +186,58 @@
|
||||||
{ 'event': 'VNC_DISCONNECTED',
|
{ 'event': 'VNC_DISCONNECTED',
|
||||||
'data': { 'server': 'VncServerInfo',
|
'data': { 'server': 'VncServerInfo',
|
||||||
'client': 'VncClientInfo' } }
|
'client': 'VncClientInfo' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @SPICE_CONNECTED
|
||||||
|
#
|
||||||
|
# Emitted when a SPICE client establishes a connection
|
||||||
|
#
|
||||||
|
# @server: server information
|
||||||
|
#
|
||||||
|
# @client: client information
|
||||||
|
#
|
||||||
|
# Since: 0.14.0
|
||||||
|
##
|
||||||
|
{ 'event': 'SPICE_CONNECTED',
|
||||||
|
'data': { 'server': 'SpiceBasicInfo',
|
||||||
|
'client': 'SpiceBasicInfo' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @SPICE_INITIALIZED
|
||||||
|
#
|
||||||
|
# Emitted after initial handshake and authentication takes place (if any)
|
||||||
|
# and the SPICE channel is up and running
|
||||||
|
#
|
||||||
|
# @server: server information
|
||||||
|
#
|
||||||
|
# @client: client information
|
||||||
|
#
|
||||||
|
# Since: 0.14.0
|
||||||
|
##
|
||||||
|
{ 'event': 'SPICE_INITIALIZED',
|
||||||
|
'data': { 'server': 'SpiceServerInfo',
|
||||||
|
'client': 'SpiceChannel' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @SPICE_DISCONNECTED
|
||||||
|
#
|
||||||
|
# Emitted when the SPICE connection is closed
|
||||||
|
#
|
||||||
|
# @server: server information
|
||||||
|
#
|
||||||
|
# @client: client information
|
||||||
|
#
|
||||||
|
# Since: 0.14.0
|
||||||
|
##
|
||||||
|
{ 'event': 'SPICE_DISCONNECTED',
|
||||||
|
'data': { 'server': 'SpiceBasicInfo',
|
||||||
|
'client': 'SpiceBasicInfo' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @SPICE_MIGRATE_COMPLETED
|
||||||
|
#
|
||||||
|
# Emitted when SPICE migration has completed
|
||||||
|
#
|
||||||
|
# Since: 1.3
|
||||||
|
##
|
||||||
|
{ 'event': 'SPICE_MIGRATE_COMPLETED' }
|
||||||
|
|
|
@ -35,9 +35,9 @@
|
||||||
#include "qapi/qmp/qjson.h"
|
#include "qapi/qmp/qjson.h"
|
||||||
#include "qemu/notify.h"
|
#include "qemu/notify.h"
|
||||||
#include "migration/migration.h"
|
#include "migration/migration.h"
|
||||||
#include "monitor/monitor.h"
|
|
||||||
#include "hw/hw.h"
|
#include "hw/hw.h"
|
||||||
#include "ui/spice-display.h"
|
#include "ui/spice-display.h"
|
||||||
|
#include "qapi-event.h"
|
||||||
|
|
||||||
/* core bits */
|
/* core bits */
|
||||||
|
|
||||||
|
@ -174,39 +174,34 @@ static void channel_list_del(SpiceChannelEventInfo *info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_addr_info(QDict *dict, struct sockaddr *addr, int len)
|
static void add_addr_info(SpiceBasicInfo *info, struct sockaddr *addr, int len)
|
||||||
{
|
{
|
||||||
char host[NI_MAXHOST], port[NI_MAXSERV];
|
char host[NI_MAXHOST], port[NI_MAXSERV];
|
||||||
const char *family;
|
|
||||||
|
|
||||||
getnameinfo(addr, len, host, sizeof(host), port, sizeof(port),
|
getnameinfo(addr, len, host, sizeof(host), port, sizeof(port),
|
||||||
NI_NUMERICHOST | NI_NUMERICSERV);
|
NI_NUMERICHOST | NI_NUMERICSERV);
|
||||||
family = inet_strfamily(addr->sa_family);
|
|
||||||
|
|
||||||
qdict_put(dict, "host", qstring_from_str(host));
|
info->host = g_strdup(host);
|
||||||
qdict_put(dict, "port", qstring_from_str(port));
|
info->port = g_strdup(port);
|
||||||
qdict_put(dict, "family", qstring_from_str(family));
|
info->family = inet_netfamily(addr->sa_family);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_channel_info(QDict *dict, SpiceChannelEventInfo *info)
|
static void add_channel_info(SpiceChannel *sc, SpiceChannelEventInfo *info)
|
||||||
{
|
{
|
||||||
int tls = info->flags & SPICE_CHANNEL_EVENT_FLAG_TLS;
|
int tls = info->flags & SPICE_CHANNEL_EVENT_FLAG_TLS;
|
||||||
|
|
||||||
qdict_put(dict, "connection-id", qint_from_int(info->connection_id));
|
sc->connection_id = info->connection_id;
|
||||||
qdict_put(dict, "channel-type", qint_from_int(info->type));
|
sc->channel_type = info->type;
|
||||||
qdict_put(dict, "channel-id", qint_from_int(info->id));
|
sc->channel_id = info->id;
|
||||||
qdict_put(dict, "tls", qbool_from_int(tls));
|
sc->tls = !!tls;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void channel_event(int event, SpiceChannelEventInfo *info)
|
static void channel_event(int event, SpiceChannelEventInfo *info)
|
||||||
{
|
{
|
||||||
static const int qevent[] = {
|
SpiceServerInfo *server = g_malloc0(sizeof(*server));
|
||||||
[ SPICE_CHANNEL_EVENT_CONNECTED ] = QEVENT_SPICE_CONNECTED,
|
SpiceChannel *client = g_malloc0(sizeof(*client));
|
||||||
[ SPICE_CHANNEL_EVENT_INITIALIZED ] = QEVENT_SPICE_INITIALIZED,
|
server->base = g_malloc0(sizeof(*server->base));
|
||||||
[ SPICE_CHANNEL_EVENT_DISCONNECTED ] = QEVENT_SPICE_DISCONNECTED,
|
client->base = g_malloc0(sizeof(*client->base));
|
||||||
};
|
|
||||||
QDict *server, *client;
|
|
||||||
QObject *data;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Spice server might have called us from spice worker thread
|
* Spice server might have called us from spice worker thread
|
||||||
|
@ -222,36 +217,43 @@ static void channel_event(int event, SpiceChannelEventInfo *info)
|
||||||
qemu_mutex_lock_iothread();
|
qemu_mutex_lock_iothread();
|
||||||
}
|
}
|
||||||
|
|
||||||
client = qdict_new();
|
|
||||||
server = qdict_new();
|
|
||||||
|
|
||||||
if (info->flags & SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT) {
|
if (info->flags & SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT) {
|
||||||
add_addr_info(client, (struct sockaddr *)&info->paddr_ext,
|
add_addr_info(client->base, (struct sockaddr *)&info->paddr_ext,
|
||||||
info->plen_ext);
|
info->plen_ext);
|
||||||
add_addr_info(server, (struct sockaddr *)&info->laddr_ext,
|
add_addr_info(server->base, (struct sockaddr *)&info->laddr_ext,
|
||||||
info->llen_ext);
|
info->llen_ext);
|
||||||
} else {
|
} else {
|
||||||
error_report("spice: %s, extended address is expected",
|
error_report("spice: %s, extended address is expected",
|
||||||
__func__);
|
__func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event == SPICE_CHANNEL_EVENT_INITIALIZED) {
|
switch (event) {
|
||||||
qdict_put(server, "auth", qstring_from_str(auth));
|
case SPICE_CHANNEL_EVENT_CONNECTED:
|
||||||
|
qapi_event_send_spice_connected(server->base, client->base, &error_abort);
|
||||||
|
break;
|
||||||
|
case SPICE_CHANNEL_EVENT_INITIALIZED:
|
||||||
|
if (auth) {
|
||||||
|
server->has_auth = true;
|
||||||
|
server->auth = g_strdup(auth);
|
||||||
|
}
|
||||||
add_channel_info(client, info);
|
add_channel_info(client, info);
|
||||||
channel_list_add(info);
|
channel_list_add(info);
|
||||||
}
|
qapi_event_send_spice_initialized(server, client, &error_abort);
|
||||||
if (event == SPICE_CHANNEL_EVENT_DISCONNECTED) {
|
break;
|
||||||
|
case SPICE_CHANNEL_EVENT_DISCONNECTED:
|
||||||
channel_list_del(info);
|
channel_list_del(info);
|
||||||
|
qapi_event_send_spice_disconnected(server->base, client->base, &error_abort);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = qobject_from_jsonf("{ 'client': %p, 'server': %p }",
|
|
||||||
QOBJECT(client), QOBJECT(server));
|
|
||||||
monitor_protocol_event(qevent[event], data);
|
|
||||||
qobject_decref(data);
|
|
||||||
|
|
||||||
if (need_lock) {
|
if (need_lock) {
|
||||||
qemu_mutex_unlock_iothread();
|
qemu_mutex_unlock_iothread();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qapi_free_SpiceServerInfo(server);
|
||||||
|
qapi_free_SpiceChannel(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SpiceCoreInterface core_interface = {
|
static SpiceCoreInterface core_interface = {
|
||||||
|
@ -305,7 +307,7 @@ static void migrate_connect_complete_cb(SpiceMigrateInstance *sin)
|
||||||
|
|
||||||
static void migrate_end_complete_cb(SpiceMigrateInstance *sin)
|
static void migrate_end_complete_cb(SpiceMigrateInstance *sin)
|
||||||
{
|
{
|
||||||
monitor_protocol_event(QEVENT_SPICE_MIGRATE_COMPLETED, NULL);
|
qapi_event_send_spice_migrate_completed(&error_abort);
|
||||||
spice_migration_completed = true;
|
spice_migration_completed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,16 +92,6 @@ static void inet_setport(struct addrinfo *e, int port)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *inet_strfamily(int family)
|
|
||||||
{
|
|
||||||
switch (family) {
|
|
||||||
case PF_INET6: return "ipv6";
|
|
||||||
case PF_INET: return "ipv4";
|
|
||||||
case PF_UNIX: return "unix";
|
|
||||||
}
|
|
||||||
return "unknown";
|
|
||||||
}
|
|
||||||
|
|
||||||
NetworkAddressFamily inet_netfamily(int family)
|
NetworkAddressFamily inet_netfamily(int family)
|
||||||
{
|
{
|
||||||
switch (family) {
|
switch (family) {
|
||||||
|
|
Loading…
Reference in New Issue