Commit 7cfadb6b authored by Wenchao Xia's avatar Wenchao Xia Committed by Luiz Capitulino
Browse files

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: default avatarWenchao Xia <wenchaoqemu@gmail.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Reviewed-by: default avatarEric Blake <eblake@redhat.com>
Signed-off-by: default avatarLuiz Capitulino <lcapitulino@redhat.com>
parent fb6ba0d5
Loading
Loading
Loading
Loading
+0 −62
Original line number Diff line number Diff line
@@ -80,65 +80,3 @@ Example:
{ "event": "QUORUM_REPORT_BAD",
     "data": { "node-name": "1.raw", "sector-num": 345435, "sector-count": 5 },
     "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}
}}
+0 −1
Original line number Diff line number Diff line
@@ -61,7 +61,6 @@ int inet_nonblocking_connect(const char *str,
                             void *opaque, Error **errp);

int inet_dgram_opts(QemuOpts *opts, Error **errp);
const char *inet_strfamily(int family);
NetworkAddressFamily inet_netfamily(int family);

int unix_listen_opts(QemuOpts *opts, Error **errp);
+55 −0
Original line number Diff line number Diff line
@@ -186,3 +186,58 @@
{ 'event': 'VNC_DISCONNECTED',
  'data': { 'server': 'VncServerInfo',
            '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' }
+36 −34
Original line number Diff line number Diff line
@@ -35,9 +35,9 @@
#include "qapi/qmp/qjson.h"
#include "qemu/notify.h"
#include "migration/migration.h"
#include "monitor/monitor.h"
#include "hw/hw.h"
#include "ui/spice-display.h"
#include "qapi-event.h"

/* 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];
    const char *family;

    getnameinfo(addr, len, host, sizeof(host), port, sizeof(port),
                NI_NUMERICHOST | NI_NUMERICSERV);
    family = inet_strfamily(addr->sa_family);

    qdict_put(dict, "host", qstring_from_str(host));
    qdict_put(dict, "port", qstring_from_str(port));
    qdict_put(dict, "family", qstring_from_str(family));
    info->host = g_strdup(host);
    info->port = g_strdup(port);
    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;

    qdict_put(dict, "connection-id", qint_from_int(info->connection_id));
    qdict_put(dict, "channel-type", qint_from_int(info->type));
    qdict_put(dict, "channel-id", qint_from_int(info->id));
    qdict_put(dict, "tls", qbool_from_int(tls));
    sc->connection_id = info->connection_id;
    sc->channel_type = info->type;
    sc->channel_id = info->id;
    sc->tls = !!tls;
}

static void channel_event(int event, SpiceChannelEventInfo *info)
{
    static const int qevent[] = {
        [ SPICE_CHANNEL_EVENT_CONNECTED    ] = QEVENT_SPICE_CONNECTED,
        [ SPICE_CHANNEL_EVENT_INITIALIZED  ] = QEVENT_SPICE_INITIALIZED,
        [ SPICE_CHANNEL_EVENT_DISCONNECTED ] = QEVENT_SPICE_DISCONNECTED,
    };
    QDict *server, *client;
    QObject *data;
    SpiceServerInfo *server = g_malloc0(sizeof(*server));
    SpiceChannel *client = g_malloc0(sizeof(*client));
    server->base = g_malloc0(sizeof(*server->base));
    client->base = g_malloc0(sizeof(*client->base));

    /*
     * 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();
    }

    client = qdict_new();
    server = qdict_new();

    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);
        add_addr_info(server, (struct sockaddr *)&info->laddr_ext,
        add_addr_info(server->base, (struct sockaddr *)&info->laddr_ext,
                      info->llen_ext);
    } else {
        error_report("spice: %s, extended address is expected",
                     __func__);
    }

    if (event == SPICE_CHANNEL_EVENT_INITIALIZED) {
        qdict_put(server, "auth", qstring_from_str(auth));
    switch (event) {
    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);
        channel_list_add(info);
    }
    if (event == SPICE_CHANNEL_EVENT_DISCONNECTED) {
        qapi_event_send_spice_initialized(server, client, &error_abort);
        break;
    case SPICE_CHANNEL_EVENT_DISCONNECTED:
        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) {
        qemu_mutex_unlock_iothread();
    }

    qapi_free_SpiceServerInfo(server);
    qapi_free_SpiceChannel(client);
}

static SpiceCoreInterface core_interface = {
@@ -305,7 +307,7 @@ static void migrate_connect_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;
}

+0 −10
Original line number Diff line number Diff line
@@ -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)
{
    switch (family) {