From 4933a461a0e9137b9c40d76d6a61a1c1f1f1d737 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 18 Mar 2010 17:25:37 -0300 Subject: [PATCH 11/14] spice: send connect / disconnect monitor events RH-Author: Gerd Hoffmann Message-id: <1268933140-655-12-git-send-email-kraxel@redhat.com> Patchwork-id: 7905 O-Subject: [RHEL-6 kvm PATCH v3 11/14] spice: send connect / disconnect monitor events Bugzilla: 558957 RH-Acked-by: Daniel P. Berrange RH-Acked-by: Yonit Halperin RH-Acked-by: Juan Quintela Send QEVENT_SPICE_INITIALIZED and QEVENT_SPICE_DISCONNECTED events for spice, being aequivalent to the VNC counterparts. The events are sent on connects / disconnects of the main spice channel. [ v3: fix qobject allocation + refcounting ] [ v3: drop service from client+server dicts ] bugzilla: #558957 -- A QMP event notification on SPICE client connect/disconnect events Signed-off-by: Gerd Hoffmann --- monitor.c | 6 +++++ monitor.h | 2 + spice.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 76 insertions(+), 1 deletions(-) Signed-off-by: Eduardo Habkost --- monitor.c | 6 +++++ monitor.h | 2 + spice.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 76 insertions(+), 1 deletions(-) diff --git a/monitor.c b/monitor.c index 6a46906..2ecb9e1 100644 --- a/monitor.c +++ b/monitor.c @@ -371,6 +371,12 @@ void monitor_protocol_event(MonitorEvent event, QObject *data) case QEVENT_VNC_DISCONNECTED: event_name = "VNC_DISCONNECTED"; break; + case QEVENT_SPICE_INITIALIZED: + event_name = "SPICE_INITIALIZED"; + break; + case QEVENT_SPICE_DISCONNECTED: + event_name = "SPICE_DISCONNECTED"; + break; case QEVENT_BLOCK_IO_ERROR: event_name = "BLOCK_IO_ERROR"; break; diff --git a/monitor.h b/monitor.h index 2dc6d60..394b077 100644 --- a/monitor.h +++ b/monitor.h @@ -23,6 +23,8 @@ typedef enum MonitorEvent { QEVENT_VNC_CONNECTED, QEVENT_VNC_INITIALIZED, QEVENT_VNC_DISCONNECTED, + QEVENT_SPICE_INITIALIZED, + QEVENT_SPICE_DISCONNECTED, QEVENT_BLOCK_IO_ERROR, QEVENT_MAX, } MonitorEvent; diff --git a/spice.c b/spice.c index b342460..d347713 100644 --- a/spice.c +++ b/spice.c @@ -1,16 +1,19 @@ #include #include #include +#include #include #include "qemu-common.h" +#include "qemu_socket.h" #include "qemu-spice.h" #include "qemu-timer.h" #include "qemu-queue.h" #include "qemu-x509.h" #include "monitor.h" #include "qerror.h" +#include "qjson.h" #include "sysemu.h" #include "vnc.h" @@ -67,10 +70,74 @@ static void core_term_printf(CoreInterface *core, const char* format, ...) /* ignore */ } +static QDict *server, *client; + +static void spice_qmp_event_initialized(void) +{ + struct sockaddr_storage sa; + char addr[NI_MAXHOST], port[NI_MAXSERV]; + socklen_t salen; + QObject *data; + + QDECREF(server); + server = qdict_new(); + salen = sizeof(sa); + if (spice_server_get_sock_info(s, (struct sockaddr*)&sa, &salen) == 0) { + if (getnameinfo((struct sockaddr*)&sa, salen, + addr, sizeof(addr), port, sizeof(port), + NI_NUMERICHOST | NI_NUMERICSERV) == 0) { + qdict_put(server, "host", qstring_from_str(addr)); + qdict_put(server, "family", qstring_from_str(inet_strfamily(sa.ss_family))); + } + } + + QDECREF(client); + client = qdict_new(); + salen = sizeof(sa); + if (spice_server_get_peer_info(s, (struct sockaddr*)&sa, &salen) == 0) { + if (getnameinfo((struct sockaddr*)&sa, salen, + addr, sizeof(addr), port, sizeof(port), + NI_NUMERICHOST | NI_NUMERICSERV) == 0) { + qdict_put(client, "host", qstring_from_str(addr)); + qdict_put(client, "family", qstring_from_str(inet_strfamily(sa.ss_family))); + } + } + + data = qobject_from_jsonf("{ 'client': %p, 'server': %p }", + QOBJECT(client), QOBJECT(server)); + monitor_protocol_event(QEVENT_SPICE_INITIALIZED, data); + QINCREF(client); + QINCREF(server); + qobject_decref(data); +} + +static void spice_qmp_event_disconnect(void) +{ + QObject *data; + + /* + * Right now spice does (a) support one connection at a time only + * and (b) allways sends disconnects for the old client before the + * connect for new client. So we can simply reuse the server and + * client info collected on connect for the time being. + */ + data = qobject_from_jsonf("{ 'client': %p, 'server': %p }", + QOBJECT(client), QOBJECT(server)); + monitor_protocol_event(QEVENT_SPICE_DISCONNECTED, data); + qobject_decref(data); + server = NULL; + client = NULL; +} + static void core_log(CoreInterface *core, LogLevel level, const char* componnent, const char* format, ...) { - /* ignore */ + if (strcmp(format, "new user connection") == 0) { + spice_qmp_event_initialized(); + } + if (strcmp(format, "user disconnected") == 0) { + spice_qmp_event_disconnect(); + } } static CoreInterface core_interface = { -- 1.6.3.rc4.29.g8146