[Spice-devel] [linux-vdagent PATCH 10/10] vdagent*: Handle VDAGENTD_CLIENT_DISCONNECTED messages

Hans de Goede hdegoede at redhat.com
Wed Mar 6 07:22:46 PST 2013


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 at redhat.com>
---
 src/vdagent.c                |  6 +++++-
 src/vdagentd-proto-strings.h |  5 +++--
 src/vdagentd-proto.h         |  3 ++-
 src/vdagentd.c               | 38 +++++++++++++++++++++++++++++++-------
 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 at 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 at 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 at 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 at 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;
             }
         }
 
-- 
1.8.1.4



More information about the Spice-devel mailing list