mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-10 00:28:20 +00:00
[client] client is now opens shared memory from ivshmem passed fd
This commit is contained in:
parent
48facb3746
commit
3dd061b895
@ -9,13 +9,27 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
struct IVSHMEMServer
|
||||
{
|
||||
int64_t version;
|
||||
int64_t clientID;
|
||||
int sharedFD;
|
||||
};
|
||||
|
||||
struct IVSHMEM
|
||||
{
|
||||
bool connected;
|
||||
int socket;
|
||||
struct IVSHMEMServer server;
|
||||
|
||||
off_t mapSize;
|
||||
void * map;
|
||||
};
|
||||
|
||||
struct IVSHMEM ivshmem =
|
||||
@ -29,6 +43,7 @@ struct IVSHMEM ivshmem =
|
||||
|
||||
void ivshmem_cleanup();
|
||||
bool ivshmem_read(void * buffer, const ssize_t size);
|
||||
bool ivshmem_read_msg(int64_t * index, int *fd);
|
||||
|
||||
// ============================================================================
|
||||
|
||||
@ -54,46 +69,62 @@ bool ivshmem_connect(const char * unix_socket)
|
||||
|
||||
ivshmem.connected = true;
|
||||
|
||||
struct IVSHMEMInit init;
|
||||
if (!ivshmem_read(&init.version, sizeof(init.version)))
|
||||
if (!ivshmem_read(&ivshmem.server.version, sizeof(ivshmem.server.version)))
|
||||
{
|
||||
DEBUG_ERROR("read protocol version failed");
|
||||
ivshmem_cleanup();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (init.version != 0)
|
||||
if (ivshmem.server.version != 0)
|
||||
{
|
||||
DEBUG_ERROR("unsupported protocol version %ld", init.version);
|
||||
DEBUG_ERROR("unsupported protocol version %ld", ivshmem.server.version);
|
||||
ivshmem_cleanup();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ivshmem_read(&init.clientID, sizeof(init.clientID)))
|
||||
if (!ivshmem_read(&ivshmem.server.clientID, sizeof(ivshmem.server.clientID)))
|
||||
{
|
||||
DEBUG_ERROR("read client id failed");
|
||||
ivshmem_cleanup();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ivshmem_read(&init.unused, sizeof(init.unused)))
|
||||
DEBUG_PROTO("Protocol : %ld", ivshmem.server.version );
|
||||
DEBUG_PROTO("Client ID: %ld", ivshmem.server.clientID);
|
||||
|
||||
if (!ivshmem_read_msg(NULL, &ivshmem.server.sharedFD))
|
||||
{
|
||||
DEBUG_ERROR("read unused failed");
|
||||
DEBUG_ERROR("failed to read shared memory file descriptor");
|
||||
ivshmem_cleanup();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ivshmem_read(&init.sharedFD, sizeof(init.sharedFD)))
|
||||
struct stat stat;
|
||||
if (fstat(ivshmem.server.sharedFD, &stat) != 0)
|
||||
{
|
||||
DEBUG_ERROR("read shared memory file descriptor failed");
|
||||
DEBUG_ERROR("failed to stat shared FD");
|
||||
ivshmem_cleanup();
|
||||
return false;
|
||||
}
|
||||
|
||||
DEBUG_PROTO("Protocol : %ld", init.version );
|
||||
DEBUG_PROTO("Client ID: %ld", init.clientID);
|
||||
DEBUG_PROTO("Unused : %ld", init.unused );
|
||||
DEBUG_PROTO("Shared FD: %ld", init.sharedFD);
|
||||
ivshmem.mapSize = stat.st_size;
|
||||
|
||||
DEBUG_INFO("RAM Size : %ld", ivshmem.mapSize);
|
||||
ivshmem.map = mmap(
|
||||
NULL,
|
||||
stat.st_size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
ivshmem.server.sharedFD,
|
||||
0);
|
||||
|
||||
if (!ivshmem.map)
|
||||
{
|
||||
DEBUG_ERROR("failed to map memory");
|
||||
ivshmem_cleanup();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -102,6 +133,11 @@ bool ivshmem_connect(const char * unix_socket)
|
||||
|
||||
void ivshmem_cleanup()
|
||||
{
|
||||
if (ivshmem.map)
|
||||
munmap(ivshmem.map, ivshmem.mapSize);
|
||||
ivshmem.map = NULL;
|
||||
ivshmem.mapSize = 0;
|
||||
|
||||
if (ivshmem.socket >= 0)
|
||||
{
|
||||
close(ivshmem.socket);
|
||||
@ -143,3 +179,103 @@ bool ivshmem_read(void * buffer, const ssize_t size)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
||||
bool ivshmem_read_msg(int64_t * index, int * fd)
|
||||
{
|
||||
if (!ivshmem.connected)
|
||||
{
|
||||
DEBUG_ERROR("not connected");
|
||||
return false;
|
||||
}
|
||||
|
||||
struct msghdr msg;
|
||||
struct iovec iov[1];
|
||||
union {
|
||||
struct cmsghdr cmsg;
|
||||
char control[CMSG_SPACE(sizeof(int))];
|
||||
} msg_control;
|
||||
|
||||
int64_t tmp;
|
||||
if (!index)
|
||||
index = &tmp;
|
||||
|
||||
iov[0].iov_base = index;
|
||||
iov[0].iov_len = sizeof(*index);
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.msg_iov = iov;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_control = &msg_control;
|
||||
msg.msg_controllen = sizeof(msg_control);
|
||||
|
||||
int ret = recvmsg(ivshmem.socket, &msg, 0);
|
||||
if (ret < sizeof(*index))
|
||||
{
|
||||
DEBUG_ERROR("failed ot read message\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
DEBUG_ERROR("lost connetion to server\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!fd)
|
||||
return true;
|
||||
|
||||
struct cmsghdr *cmsg;
|
||||
for(cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
|
||||
{
|
||||
if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)) ||
|
||||
cmsg->cmsg_level != SOL_SOCKET ||
|
||||
cmsg->cmsg_type != SCM_RIGHTS)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy(fd, CMSG_DATA(cmsg), sizeof(*fd));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
||||
void * ivshmem_get_map()
|
||||
{
|
||||
if (!ivshmem.connected)
|
||||
{
|
||||
DEBUG_ERROR("not connected");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!ivshmem.map)
|
||||
{
|
||||
DEBUG_ERROR("not mapped");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ivshmem.map;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
||||
size_t ivshmem_get_map_size()
|
||||
{
|
||||
if (!ivshmem.connected)
|
||||
{
|
||||
DEBUG_ERROR("not connected");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ivshmem.map)
|
||||
{
|
||||
DEBUG_ERROR("not mapped");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ivshmem.mapSize;
|
||||
}
|
@ -1,13 +1,9 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct IVSHMEMInit
|
||||
{
|
||||
int64_t version;
|
||||
int64_t clientID;
|
||||
int64_t unused;
|
||||
int64_t sharedFD;
|
||||
};
|
||||
|
||||
bool ivshmem_connect(const char * unix_socket);
|
||||
void ivshmem_close();
|
||||
|
||||
void * ivshmem_get_map();
|
||||
size_t ivshmem_get_map_size();
|
BIN
client/main
BIN
client/main
Binary file not shown.
@ -1,8 +1,6 @@
|
||||
#include <SDL2/SDL.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
@ -16,6 +14,7 @@
|
||||
#define DEBUG
|
||||
#include "debug.h"
|
||||
#include "KVMGFXHeader.h"
|
||||
#include "ivshmem/ivshmem.h"
|
||||
#include "spice/spice.h"
|
||||
#include "kb.h"
|
||||
|
||||
@ -470,21 +469,16 @@ int main(int argc, char * argv[])
|
||||
|
||||
while(1)
|
||||
{
|
||||
umask(0);
|
||||
const mode_t mode =
|
||||
S_IRUSR | S_IWUSR |
|
||||
S_IRGRP | S_IWGRP |
|
||||
S_IROTH | S_IWOTH;
|
||||
|
||||
if ((shm_fd = shm_open("ivshmem", O_CREAT | O_RDWR, mode)) < 0)
|
||||
if (!ivshmem_connect("/tmp/ivshmem_socket"))
|
||||
{
|
||||
DEBUG_ERROR("failed to open shared memory: %d %s", errno, strerror(errno));
|
||||
DEBUG_ERROR("failed to connect to the ivshmem server");
|
||||
break;
|
||||
}
|
||||
|
||||
if (ftruncate(shm_fd, MAP_SIZE) != 0)
|
||||
state.shm = (struct KVMGFXHeader *)ivshmem_get_map();
|
||||
if (!state.shm)
|
||||
{
|
||||
DEBUG_ERROR("failed to truncate memory region");
|
||||
DEBUG_ERROR("Failed to map memory");
|
||||
break;
|
||||
}
|
||||
|
||||
@ -508,13 +502,6 @@ int main(int argc, char * argv[])
|
||||
break;
|
||||
}
|
||||
|
||||
state.shm = (struct KVMGFXHeader *)mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
|
||||
if (!state.shm)
|
||||
{
|
||||
DEBUG_ERROR("Failed to map memory");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(t_event = SDL_CreateThread(eventThread, "eventThread", NULL)))
|
||||
{
|
||||
DEBUG_ERROR("gpu create thread failed");
|
||||
@ -541,12 +528,8 @@ int main(int argc, char * argv[])
|
||||
if (state.window)
|
||||
SDL_DestroyWindow(state.window);
|
||||
|
||||
if (state.shm)
|
||||
munmap(state.shm, MAP_SIZE);
|
||||
|
||||
if (shm_fd)
|
||||
close(shm_fd);
|
||||
//shm_unlink("kvm-windows");
|
||||
|
||||
SDL_Quit();
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user