Commit ca89a010 authored by Jakub Janků's avatar Jakub Janků Committed by Victor Toso
Browse files

file-xfer: Add support for sending detailed errors



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.
Acked-by: Victor Toso's avatarVictor Toso <victortoso@redhat.com>
parent 9844732e
......@@ -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])
......
......@@ -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,
......@@ -812,7 +830,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;
......@@ -905,17 +923,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;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment