summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2013-03-06 15:34:23 +0100
committerHans de Goede <hdegoede@redhat.com>2013-03-06 16:22:15 +0100
commit36ae65709f3c733968d865122a468e2bc5e9746f (patch)
tree9d5193c8d692ca4ed12d5f4e3e918d9eec53f9dd
parent4b0748ddcc4f0c4fdc892aff63cbc88dc9e391df (diff)
downloadvd_agent-36ae65709f3c733968d865122a468e2bc5e9746f.tar.gz
vd_agent-36ae65709f3c733968d865122a468e2bc5e9746f.tar.xz
vd_agent-36ae65709f3c733968d865122a468e2bc5e9746f.zip
vdagent*: Handle VDAGENTD_CLIENT_DISCONNECTED messages
Also add some extra detection for the client having gone away for when running on an older spice-server which does not send VDAGENTD_CLIENT_DISCONNECTED on client disconnect. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-rw-r--r--src/vdagent.c6
-rw-r--r--src/vdagentd-proto-strings.h5
-rw-r--r--src/vdagentd-proto.h3
-rw-r--r--src/vdagentd.c38
4 files changed, 41 insertions, 11 deletions
diff --git a/src/vdagent.c b/src/vdagent.c
index 0161c7a..6f6b21d 100644
--- a/src/vdagent.c
+++ b/src/vdagent.c
@@ -1,6 +1,6 @@
/* vdagent.c xorg-client to vdagentd (daemon).
- Copyright 2010 Red Hat, Inc.
+ Copyright 2010-2013 Red Hat, Inc.
Red Hat Authors:
Hans de Goede <hdegoede@redhat.com>
@@ -99,6 +99,10 @@ void daemon_read_complete(struct udscs_connection **connp,
(VDAgentFileXferDataMessage *)data);
free(data);
break;
+ case VDAGENTD_CLIENT_DISCONNECTED:
+ vdagent_file_xfers_destroy(vdagent_file_xfers);
+ vdagent_file_xfers = vdagent_file_xfers_create(client, debug);
+ break;
default:
syslog(LOG_ERR, "Unknown message from vdagentd type: %d, ignoring",
header->type);
diff --git a/src/vdagentd-proto-strings.h b/src/vdagentd-proto-strings.h
index 112eced..e76cb3b 100644
--- a/src/vdagentd-proto-strings.h
+++ b/src/vdagentd-proto-strings.h
@@ -1,6 +1,6 @@
/* vdagentd-proto-strings.h header file
- Copyright 2010 Red Hat, Inc.
+ Copyright 2010-2013 Red Hat, Inc.
Red Hat Authors:
Hans de Goede <hdegoede@redhat.com>
@@ -33,6 +33,7 @@ static const char * const vdagentd_messages[] = {
"file xfer start",
"file xfer status",
"file xfer data",
-};
+ "client disconnected",
+};
#endif
diff --git a/src/vdagentd-proto.h b/src/vdagentd-proto.h
index 359f18e..25e6a36 100644
--- a/src/vdagentd-proto.h
+++ b/src/vdagentd-proto.h
@@ -1,7 +1,7 @@
/* vdagentd-proto.h header file for the protocol over the unix domain socket
between the vdagent process / xorg-client and the vdagentd (daemon).
- Copyright 2010 Red Hat, Inc.
+ Copyright 2010-2013 Red Hat, Inc.
Red Hat Authors:
Hans de Goede <hdegoede@redhat.com>
@@ -39,6 +39,7 @@ enum {
VDAGENTD_FILE_XFER_START,
VDAGENTD_FILE_XFER_STATUS,
VDAGENTD_FILE_XFER_DATA,
+ VDAGENTD_CLIENT_DISCONNECTED, /* daemon -> client */
VDAGENTD_NO_MESSAGES /* Must always be last */
};
diff --git a/src/vdagentd.c b/src/vdagentd.c
index 108755a..ee5ce5f 100644
--- a/src/vdagentd.c
+++ b/src/vdagentd.c
@@ -1,6 +1,6 @@
/* vdagentd.c vdagentd (daemon) code
- Copyright 2010-2012 Red Hat, Inc.
+ Copyright 2010-2013 Red Hat, Inc.
Red Hat Authors:
Hans de Goede <hdegoede@redhat.com>
@@ -76,6 +76,7 @@ static struct udscs_connection *active_session_conn = NULL;
static int agent_owns_clipboard[256] = { 0, };
static int quit = 0;
static int retval = 0;
+static int client_connected = 0;
/* utility functions */
/* vdagentd <-> spice-client communication handling */
@@ -106,6 +107,15 @@ static void send_capabilities(struct vdagent_virtio_port *vport,
free(caps);
}
+static void do_client_disconnect(void)
+{
+ if (client_connected) {
+ udscs_server_write_all(server, VDAGENTD_CLIENT_DISCONNECTED, 0, 0,
+ NULL, 0);
+ client_connected = 0;
+ }
+}
+
static void do_client_monitors(struct vdagent_virtio_port *vport, int port_nr,
VDAgentMessage *message_header, VDAgentMonitorsConfig *new_monitors)
{
@@ -162,8 +172,14 @@ static void do_client_capabilities(struct vdagent_virtio_port *vport,
}
}
memcpy(capabilities, caps->caps, capabilities_size * sizeof(uint32_t));
- if (caps->request)
+ if (caps->request) {
+ /* Report the previous client has disconneced. */
+ do_client_disconnect();
+ if (debug)
+ syslog(LOG_DEBUG, "New client connected");
+ client_connected = 1;
send_capabilities(vport, 0);
+ }
}
static void do_client_clipboard(struct vdagent_virtio_port *vport,
@@ -349,6 +365,10 @@ int virtio_port_read_complete(
case VD_AGENT_FILE_XFER_DATA:
do_client_file_xfer(vport, message_header, data);
break;
+ case VD_AGENT_CLIENT_DISCONNECTED:
+ vdagent_virtio_port_reset(vport, VDP_CLIENT_PORT);
+ do_client_disconnect();
+ break;
default:
syslog(LOG_WARNING, "unknown message type %d, ignoring",
message_header->type);
@@ -792,16 +812,20 @@ void main_loop(void)
if (virtio_port) {
vdagent_virtio_port_handle_fds(&virtio_port, &readfds, &writefds);
if (!virtio_port) {
+ int old_client_connected = client_connected;
syslog(LOG_CRIT,
"AIIEEE lost spice client connection, reconnecting");
virtio_port = vdagent_virtio_port_create(portdev,
virtio_port_read_complete,
NULL);
- }
- if (!virtio_port) {
- syslog(LOG_CRIT, "Fatal error opening vdagent virtio channel");
- retval = 1;
- break;
+ if (!virtio_port) {
+ syslog(LOG_CRIT,
+ "Fatal error opening vdagent virtio channel");
+ retval = 1;
+ break;
+ }
+ do_client_disconnect();
+ client_connected = old_client_connected;
}
}