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 <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
|
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
struct IVSHMEMServer
|
||||||
|
{
|
||||||
|
int64_t version;
|
||||||
|
int64_t clientID;
|
||||||
|
int sharedFD;
|
||||||
|
};
|
||||||
|
|
||||||
struct IVSHMEM
|
struct IVSHMEM
|
||||||
{
|
{
|
||||||
bool connected;
|
bool connected;
|
||||||
int socket;
|
int socket;
|
||||||
|
struct IVSHMEMServer server;
|
||||||
|
|
||||||
|
off_t mapSize;
|
||||||
|
void * map;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IVSHMEM ivshmem =
|
struct IVSHMEM ivshmem =
|
||||||
@ -29,6 +43,7 @@ struct IVSHMEM ivshmem =
|
|||||||
|
|
||||||
void ivshmem_cleanup();
|
void ivshmem_cleanup();
|
||||||
bool ivshmem_read(void * buffer, const ssize_t size);
|
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;
|
ivshmem.connected = true;
|
||||||
|
|
||||||
struct IVSHMEMInit init;
|
if (!ivshmem_read(&ivshmem.server.version, sizeof(ivshmem.server.version)))
|
||||||
if (!ivshmem_read(&init.version, sizeof(init.version)))
|
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("read protocol version failed");
|
DEBUG_ERROR("read protocol version failed");
|
||||||
ivshmem_cleanup();
|
ivshmem_cleanup();
|
||||||
return false;
|
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();
|
ivshmem_cleanup();
|
||||||
return false;
|
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");
|
DEBUG_ERROR("read client id failed");
|
||||||
ivshmem_cleanup();
|
ivshmem_cleanup();
|
||||||
return false;
|
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();
|
ivshmem_cleanup();
|
||||||
return false;
|
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();
|
ivshmem_cleanup();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_PROTO("Protocol : %ld", init.version );
|
ivshmem.mapSize = stat.st_size;
|
||||||
DEBUG_PROTO("Client ID: %ld", init.clientID);
|
|
||||||
DEBUG_PROTO("Unused : %ld", init.unused );
|
DEBUG_INFO("RAM Size : %ld", ivshmem.mapSize);
|
||||||
DEBUG_PROTO("Shared FD: %ld", init.sharedFD);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
@ -102,6 +133,11 @@ bool ivshmem_connect(const char * unix_socket)
|
|||||||
|
|
||||||
void ivshmem_cleanup()
|
void ivshmem_cleanup()
|
||||||
{
|
{
|
||||||
|
if (ivshmem.map)
|
||||||
|
munmap(ivshmem.map, ivshmem.mapSize);
|
||||||
|
ivshmem.map = NULL;
|
||||||
|
ivshmem.mapSize = 0;
|
||||||
|
|
||||||
if (ivshmem.socket >= 0)
|
if (ivshmem.socket >= 0)
|
||||||
{
|
{
|
||||||
close(ivshmem.socket);
|
close(ivshmem.socket);
|
||||||
@ -142,4 +178,104 @@ bool ivshmem_read(void * buffer, const ssize_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
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 <stdint.h>
|
||||||
#include <stdbool.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);
|
bool ivshmem_connect(const char * unix_socket);
|
||||||
void ivshmem_close();
|
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 <SDL2/SDL.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@ -16,6 +14,7 @@
|
|||||||
#define DEBUG
|
#define DEBUG
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "KVMGFXHeader.h"
|
#include "KVMGFXHeader.h"
|
||||||
|
#include "ivshmem/ivshmem.h"
|
||||||
#include "spice/spice.h"
|
#include "spice/spice.h"
|
||||||
#include "kb.h"
|
#include "kb.h"
|
||||||
|
|
||||||
@ -470,21 +469,16 @@ int main(int argc, char * argv[])
|
|||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
umask(0);
|
if (!ivshmem_connect("/tmp/ivshmem_socket"))
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("failed to open shared memory: %d %s", errno, strerror(errno));
|
DEBUG_ERROR("failed to connect to the ivshmem server");
|
||||||
break;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -508,13 +502,6 @@ int main(int argc, char * argv[])
|
|||||||
break;
|
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)))
|
if (!(t_event = SDL_CreateThread(eventThread, "eventThread", NULL)))
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("gpu create thread failed");
|
DEBUG_ERROR("gpu create thread failed");
|
||||||
@ -541,12 +528,8 @@ int main(int argc, char * argv[])
|
|||||||
if (state.window)
|
if (state.window)
|
||||||
SDL_DestroyWindow(state.window);
|
SDL_DestroyWindow(state.window);
|
||||||
|
|
||||||
if (state.shm)
|
|
||||||
munmap(state.shm, MAP_SIZE);
|
|
||||||
|
|
||||||
if (shm_fd)
|
if (shm_fd)
|
||||||
close(shm_fd);
|
close(shm_fd);
|
||||||
//shm_unlink("kvm-windows");
|
|
||||||
|
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user