[Spice-devel] [PATCH spice-vdagent v7 1/3] file-xfer: Add support for sending detailed errors

Jakub Janků janku.jakub.jj at gmail.com
Sun Jun 4 20:25:54 UTC 2017


Generalize send_file_xfer_status() to send all file xfer statuses, not just
errors.

Change send_file_xfer_status() to support sending detailed file xfer status
messages with additional error data.
---
 configure.ac            |  2 +-
 src/vdagentd/vdagentd.c | 60 ++++++++++++++++++++++++++++++++-----------------
 2 files changed, 40 insertions(+), 22 deletions(-)

diff --git a/configure.ac b/configure.ac
index 0c2cfd8..f207240 100644
--- a/configure.ac
+++ b/configure.ac
@@ -79,7 +79,7 @@ AC_ARG_ENABLE([static-uinput],
 
 PKG_CHECK_MODULES([GLIB2], [glib-2.0 >= 2.28])
 PKG_CHECK_MODULES(X, [xfixes xrandr >= 1.3 xinerama x11])
-PKG_CHECK_MODULES(SPICE, [spice-protocol >= 0.12.8])
+PKG_CHECK_MODULES(SPICE, [spice-protocol >= 0.12.13])
 PKG_CHECK_MODULES(ALSA, [alsa >= 1.0.22])
 PKG_CHECK_MODULES([DBUS], [dbus-1])
 
diff --git a/src/vdagentd/vdagentd.c b/src/vdagentd/vdagentd.c
index f3ac606..64819d0 100644
--- a/src/vdagentd/vdagentd.c
+++ b/src/vdagentd/vdagentd.c
@@ -301,20 +301,38 @@ static void do_client_clipboard(struct vdagent_virtio_port *vport,
                 data, size);
 }
 
-/* To be used by vdagentd for failures in file-xfer such as when file-xfer was
- * cancelled or an error happened */
+/* Send file-xfer status to the client. In the case status is an error,
+ * optional data for the client and log message may be specified. */
 static void send_file_xfer_status(struct vdagent_virtio_port *vport,
-                                  const char *msg, uint32_t id, uint32_t xfer_status)
+                                  const char *msg, uint32_t id, uint32_t xfer_status,
+                                  const uint8_t *data, uint32_t data_size)
 {
-    VDAgentFileXferStatusMessage status = {
-        .id = GUINT32_TO_LE(id),
-        .result = GUINT32_TO_LE(xfer_status),
-    };
-    syslog(LOG_WARNING, msg, id);
+    VDAgentFileXferStatusMessage *status;
+
+    /* Replace new detailed errors with older generic VD_AGENT_FILE_XFER_STATUS_ERROR
+     * when not supported by client */
+    if (xfer_status > VD_AGENT_FILE_XFER_STATUS_SUCCESS &&
+        !VD_AGENT_HAS_CAPABILITY(capabilities, capabilities_size,
+                                 VD_AGENT_CAP_FILE_XFER_DETAILED_ERRORS)) {
+        xfer_status = VD_AGENT_FILE_XFER_STATUS_ERROR;
+        data_size = 0;
+    }
+
+    status = malloc(sizeof(*status) + data_size);
+    status->id = GUINT32_TO_LE(id);
+    status->result = GUINT32_TO_LE(xfer_status);
+    if (data)
+        memcpy(status->data, data, data_size);
+
+    if (msg)
+        syslog(LOG_WARNING, msg, id);
+
     if (vport)
         vdagent_virtio_port_write(vport, VDP_CLIENT_PORT,
                                   VD_AGENT_FILE_XFER_STATUS, 0,
-                                  (uint8_t *)&status, sizeof(status));
+                                  (uint8_t *)status, sizeof(*status) + data_size);
+
+    free(status);
 }
 
 static void do_client_file_xfer(struct vdagent_virtio_port *vport,
@@ -331,14 +349,14 @@ static void do_client_file_xfer(struct vdagent_virtio_port *vport,
             send_file_xfer_status(vport,
                "Could not find an agent connection belonging to the "
                "active session, cancelling client file-xfer request %u",
-               s->id, VD_AGENT_FILE_XFER_STATUS_CANCELLED);
+               s->id, VD_AGENT_FILE_XFER_STATUS_CANCELLED, NULL, 0);
             return;
         } else if (session_info_session_is_locked(session_info)) {
             syslog(LOG_DEBUG, "Session is locked, skipping file-xfer-start");
             send_file_xfer_status(vport,
                "User's session is locked and cannot start file transfer. "
                "Cancelling client file-xfer request %u",
-               s->id, VD_AGENT_FILE_XFER_STATUS_ERROR);
+               s->id, VD_AGENT_FILE_XFER_STATUS_ERROR, NULL, 0);
             return;
         }
         udscs_write(active_session_conn, VDAGENTD_FILE_XFER_START, 0, 0,
@@ -810,7 +828,7 @@ static gboolean remove_active_xfers(gpointer key, gpointer value, gpointer conn)
         send_file_xfer_status(virtio_port,
                               "Agent disc; cancelling file-xfer %u",
                               GPOINTER_TO_UINT(key),
-                              VD_AGENT_FILE_XFER_STATUS_CANCELLED);
+                              VD_AGENT_FILE_XFER_STATUS_CANCELLED, NULL, 0);
         return 1;
     } else
         return 0;
@@ -903,17 +921,17 @@ static void agent_read_complete(struct udscs_connection **connp,
         }
         break;
     case VDAGENTD_FILE_XFER_STATUS:{
-        VDAgentFileXferStatusMessage status;
-        status.id = GUINT32_TO_LE(header->arg1);
-        status.result = GUINT32_TO_LE(header->arg2);
-        vdagent_virtio_port_write(virtio_port, VDP_CLIENT_PORT,
-                                  VD_AGENT_FILE_XFER_STATUS, 0,
-                                  (uint8_t *)&status, sizeof(status));
-        if (status.result == VD_AGENT_FILE_XFER_STATUS_CAN_SEND_DATA)
-            g_hash_table_insert(active_xfers, GUINT_TO_POINTER(status.id),
+        /* header->arg1 = file xfer task id, header->arg2 = file xfer status */
+        switch (header->arg2) {
+            default:
+                send_file_xfer_status(virtio_port, NULL, header->arg1, header->arg2, NULL, 0);
+        }
+
+        if (header->arg2 == VD_AGENT_FILE_XFER_STATUS_CAN_SEND_DATA)
+            g_hash_table_insert(active_xfers, GUINT_TO_POINTER(GUINT32_TO_LE(header->arg1)),
                                 *connp);
         else
-            g_hash_table_remove(active_xfers, GUINT_TO_POINTER(status.id));
+            g_hash_table_remove(active_xfers, GUINT_TO_POINTER(GUINT32_TO_LE(header->arg1)));
         break;
     }
 
-- 
2.9.4



More information about the Spice-devel mailing list