mirror of
https://github.com/gnif/LookingGlass.git
synced 2025-03-19 23:05:04 +00:00
[porthole] process all messages sent from qemu
This commit is contained in:
parent
4c424cdbdf
commit
4dde82c646
2 changed files with 114 additions and 89 deletions
|
@ -62,6 +62,9 @@ Mapping;
|
||||||
struct PortholeClient
|
struct PortholeClient
|
||||||
{
|
{
|
||||||
int socket;
|
int socket;
|
||||||
|
char rxbuf[1024];
|
||||||
|
int rxbuf_len;
|
||||||
|
|
||||||
PortholeMapEvent map_cb;
|
PortholeMapEvent map_cb;
|
||||||
PortholeUnmapEvent unmap_cb;
|
PortholeUnmapEvent unmap_cb;
|
||||||
PortholeDisconEvent discon_cb;
|
PortholeDisconEvent discon_cb;
|
||||||
|
@ -168,24 +171,26 @@ static void * porthole_socket_thread(void * opaque)
|
||||||
|
|
||||||
while(handle->running)
|
while(handle->running)
|
||||||
{
|
{
|
||||||
PHMsg msg;
|
|
||||||
struct iovec io =
|
struct iovec io =
|
||||||
{
|
{
|
||||||
.iov_base = &msg,
|
.iov_base = &handle->rxbuf[handle->rxbuf_len],
|
||||||
.iov_len = sizeof(msg)
|
.iov_len = sizeof(handle->rxbuf) - handle->rxbuf_len
|
||||||
};
|
};
|
||||||
|
|
||||||
char buffer[256] = {0};
|
char cbuffer[256] = {0};
|
||||||
struct msghdr msghdr =
|
struct msghdr msghdr =
|
||||||
{
|
{
|
||||||
.msg_iov = &io,
|
.msg_iov = &io,
|
||||||
.msg_iovlen = 1,
|
.msg_iovlen = 1,
|
||||||
.msg_control = &buffer,
|
.msg_control = &cbuffer,
|
||||||
.msg_controllen = sizeof(buffer)
|
.msg_controllen = sizeof(cbuffer)
|
||||||
};
|
};
|
||||||
|
|
||||||
if (recvmsg(handle->socket, &msghdr, 0) < 0)
|
handle->rxbuf_len = recvmsg(handle->socket, &msghdr, 0);
|
||||||
|
if (handle->rxbuf_len < 0)
|
||||||
{
|
{
|
||||||
|
handle->rxbuf_len = 0;
|
||||||
|
|
||||||
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -195,7 +200,20 @@ static void * porthole_socket_thread(void * opaque)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(msg.msg)
|
int pos = 0;
|
||||||
|
while(pos != handle->rxbuf_len)
|
||||||
|
{
|
||||||
|
PHMsg *msg = (PHMsg *)&handle->rxbuf[pos];
|
||||||
|
|
||||||
|
// check for an incomplete message
|
||||||
|
if (pos + msg->len > handle->rxbuf_len)
|
||||||
|
break;
|
||||||
|
|
||||||
|
assert(msg->len >= PH_MSG_BASE_SIZE);
|
||||||
|
pos += msg->len;
|
||||||
|
|
||||||
|
/* process the message */
|
||||||
|
switch(msg->msg)
|
||||||
{
|
{
|
||||||
case PH_MSG_MAP:
|
case PH_MSG_MAP:
|
||||||
if (handle->current)
|
if (handle->current)
|
||||||
|
@ -211,7 +229,7 @@ static void * porthole_socket_thread(void * opaque)
|
||||||
{
|
{
|
||||||
struct cmsghdr * cmsg = CMSG_FIRSTHDR(&msghdr);
|
struct cmsghdr * cmsg = CMSG_FIRSTHDR(&msghdr);
|
||||||
int * fds = (int *)CMSG_DATA(cmsg);
|
int * fds = (int *)CMSG_DATA(cmsg);
|
||||||
porthole_sharedfd_new(handle, msg.u.fd.id, fds[0]);
|
porthole_sharedfd_new(handle, msg->u.fd.id, fds[0]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,9 +241,9 @@ static void * porthole_socket_thread(void * opaque)
|
||||||
porthole_segment_new(
|
porthole_segment_new(
|
||||||
handle->fds,
|
handle->fds,
|
||||||
handle->current,
|
handle->current,
|
||||||
msg.u.segment.fd_id,
|
msg->u.segment.fd_id,
|
||||||
msg.u.segment.addr,
|
msg->u.segment.addr,
|
||||||
msg.u.segment.size
|
msg->u.segment.size
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -234,23 +252,23 @@ static void * porthole_socket_thread(void * opaque)
|
||||||
if (!handle->current)
|
if (!handle->current)
|
||||||
DEBUG_FATAL("Finished map before starting one");
|
DEBUG_FATAL("Finished map before starting one");
|
||||||
|
|
||||||
handle->current->id = msg.u.finish.id;
|
handle->current->id = msg->u.finish.id;
|
||||||
objectlist_push(handle->intmaps, handle->current);
|
objectlist_push(handle->intmaps, handle->current);
|
||||||
porthole_do_map(handle, handle->current, msg.u.finish.type);
|
porthole_do_map(handle, handle->current, msg->u.finish.type);
|
||||||
handle->current = NULL;
|
handle->current = NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PH_MSG_UNMAP:
|
case PH_MSG_UNMAP:
|
||||||
{
|
{
|
||||||
// notify the application of the unmap
|
// notify the application of the unmap
|
||||||
handle->unmap_cb(msg.u.unmap.id);
|
handle->unmap_cb(msg->u.unmap.id);
|
||||||
|
|
||||||
// remove the PortholeMap object
|
// remove the PortholeMap object
|
||||||
unsigned int count = objectlist_count(handle->maps);
|
unsigned int count = objectlist_count(handle->maps);
|
||||||
for(unsigned int i = 0; i < count; ++i)
|
for(unsigned int i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
PortholeMap *m = (PortholeMap *)objectlist_at(handle->maps, i);
|
PortholeMap *m = (PortholeMap *)objectlist_at(handle->maps, i);
|
||||||
if (m->id == msg.u.unmap.id)
|
if (m->id == msg->u.unmap.id)
|
||||||
{
|
{
|
||||||
objectlist_remove(handle->maps, i);
|
objectlist_remove(handle->maps, i);
|
||||||
break;
|
break;
|
||||||
|
@ -262,7 +280,7 @@ static void * porthole_socket_thread(void * opaque)
|
||||||
for(unsigned int i = 0; i < count; ++i)
|
for(unsigned int i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
Mapping *m = (Mapping *)objectlist_at(handle->intmaps, i);
|
Mapping *m = (Mapping *)objectlist_at(handle->intmaps, i);
|
||||||
if (m->id == msg.u.unmap.id)
|
if (m->id == msg->u.unmap.id)
|
||||||
{
|
{
|
||||||
objectlist_remove(handle->intmaps, i);
|
objectlist_remove(handle->intmaps, i);
|
||||||
break;
|
break;
|
||||||
|
@ -287,6 +305,11 @@ static void * porthole_socket_thread(void * opaque)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// save any remaining bytes for the next recv
|
||||||
|
handle->rxbuf_len -= pos;
|
||||||
|
memmove(handle->rxbuf, &handle->rxbuf[pos], handle->rxbuf_len);
|
||||||
|
}
|
||||||
|
|
||||||
handle->running = false;
|
handle->running = false;
|
||||||
DEBUG_INFO("Porthole socket thread stopped");
|
DEBUG_INFO("Porthole socket thread stopped");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -39,7 +39,8 @@ typedef struct {
|
||||||
} __attribute__ ((packed)) PHMsgUnmap;
|
} __attribute__ ((packed)) PHMsgUnmap;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t msg;
|
uint8_t len; // the message length
|
||||||
|
uint8_t msg; // the message ID
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
PHMsgFd fd;
|
PHMsgFd fd;
|
||||||
|
@ -55,8 +56,9 @@ typedef struct {
|
||||||
#define PH_MSG_FINISH 0x4 // finish of map sequence
|
#define PH_MSG_FINISH 0x4 // finish of map sequence
|
||||||
#define PH_MSG_UNMAP 0x5 // unmap a previous map
|
#define PH_MSG_UNMAP 0x5 // unmap a previous map
|
||||||
|
|
||||||
#define PH_MSG_MAP_SIZE (sizeof(uint32_t))
|
#define PH_MSG_BASE_SIZE (sizeof(uint8_t) + sizeof(uint8_t))
|
||||||
#define PH_MSG_FD_SIZE (sizeof(uint32_t) + sizeof(PHMsgFd))
|
#define PH_MSG_MAP_SIZE (PH_MSG_BASE_SIZE)
|
||||||
#define PH_MSG_SEGMENT_SIZE (sizeof(uint32_t) + sizeof(PHMsgSegment))
|
#define PH_MSG_FD_SIZE (PH_MSG_BASE_SIZE + sizeof(PHMsgFd))
|
||||||
#define PH_MSG_FINISH_SIZE (sizeof(uint32_t) + sizeof(PHMsgFinish))
|
#define PH_MSG_SEGMENT_SIZE (PH_MSG_BASE_SIZE + sizeof(PHMsgSegment))
|
||||||
#define PH_MSG_UNMAP_SIZE (sizeof(uint32_t) + sizeof(PHMsgUnmap))
|
#define PH_MSG_FINISH_SIZE (PH_MSG_BASE_SIZE + sizeof(PHMsgFinish))
|
||||||
|
#define PH_MSG_UNMAP_SIZE (PH_MSG_BASE_SIZE + sizeof(PHMsgUnmap))
|
Loading…
Add table
Reference in a new issue