mirror of
https://github.com/hermitcore/libhermit.git
synced 2025-03-09 00:00:03 +01:00
add support of remote read and lseek system calls
- reduce latency by disabling the Nagl algorithm
This commit is contained in:
parent
ba755badb5
commit
18727027cc
2 changed files with 241 additions and 51 deletions
|
@ -61,17 +61,21 @@ static void sys_yield(void)
|
|||
|
||||
void NORETURN do_exit(int arg);
|
||||
|
||||
typedef struct {
|
||||
int sysnr;
|
||||
int arg;
|
||||
} __attribute__((packed)) sys_exit_t;
|
||||
|
||||
/** @brief To be called by the systemcall to exit tasks */
|
||||
void NORETURN sys_exit(int arg)
|
||||
{
|
||||
task_t* task = per_core(current_task);
|
||||
int sysnr = __NR_exit;
|
||||
sys_exit_t sysargs = {__NR_exit, arg};
|
||||
|
||||
if (task->sd >= 0)
|
||||
{
|
||||
spinlock_lock(&lwip_lock);
|
||||
write(task->sd, &sysnr, sizeof(int));
|
||||
write(task->sd, &arg, sizeof(int));
|
||||
write(task->sd, &sysargs, sizeof(sysargs));
|
||||
spinlock_unlock(&lwip_lock);
|
||||
|
||||
closesocket(task->sd);
|
||||
|
@ -81,11 +85,58 @@ void NORETURN sys_exit(int arg)
|
|||
do_exit(arg);
|
||||
}
|
||||
|
||||
static int sys_write(int fd, const char* buf, size_t len)
|
||||
typedef struct {
|
||||
int sysnr;
|
||||
int fd;
|
||||
size_t len;
|
||||
} __attribute__((packed)) sys_read_t;
|
||||
|
||||
static ssize_t sys_read(int fd, char* buf, size_t len)
|
||||
{
|
||||
task_t* task = per_core(current_task);
|
||||
int ret, sysnr = __NR_write;
|
||||
size_t i;
|
||||
sys_read_t sysargs = {__NR_read, fd, len};
|
||||
ssize_t j, ret;
|
||||
|
||||
if (task->sd < 0)
|
||||
return -ENOSYS;
|
||||
|
||||
spinlock_lock(&lwip_lock);
|
||||
write(task->sd, &sysargs, sizeof(sysargs));
|
||||
|
||||
read(task->sd, &j, sizeof(j));
|
||||
if (j > 0)
|
||||
{
|
||||
ssize_t i = 0;
|
||||
|
||||
while(i < j)
|
||||
{
|
||||
ret = read(task->sd, buf+i, j-i);
|
||||
if (ret < 0) {
|
||||
spinlock_unlock(&lwip_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
i += ret;
|
||||
}
|
||||
}
|
||||
|
||||
spinlock_unlock(&lwip_lock);
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
int sysnr;
|
||||
int fd;
|
||||
size_t len;
|
||||
} __attribute__((packed)) sys_write_t;
|
||||
|
||||
static ssize_t sys_write(int fd, const char* buf, size_t len)
|
||||
{
|
||||
task_t* task = per_core(current_task);
|
||||
ssize_t i, ret;
|
||||
int flag;
|
||||
sys_write_t sysargs = {__NR_write, fd, len};
|
||||
|
||||
if (BUILTIN_EXPECT(!buf, 0))
|
||||
return -1;
|
||||
|
@ -100,33 +151,35 @@ static int sys_write(int fd, const char* buf, size_t len)
|
|||
|
||||
spinlock_lock(&lwip_lock);
|
||||
|
||||
ret = write(task->sd, &sysnr, sizeof(int));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
flag = 0;
|
||||
setsockopt(task->sd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(flag));
|
||||
|
||||
ret = write(task->sd, &fd, sizeof(int));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = write(task->sd, &len, sizeof(size_t));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
write(task->sd, &sysargs, sizeof(sysargs));
|
||||
|
||||
i=0;
|
||||
while(i<len)
|
||||
while(i < len)
|
||||
{
|
||||
ret = write(task->sd, (char*)buf+i, len-i);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
if (ret < 0) {
|
||||
spinlock_unlock(&lwip_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
i += ret;
|
||||
}
|
||||
|
||||
ret = len;
|
||||
flag = 1;
|
||||
setsockopt(task->sd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(flag));
|
||||
|
||||
if (fd > 2) {
|
||||
ret = read(task->sd, &i, sizeof(i));
|
||||
if (ret < 0)
|
||||
i = ret;
|
||||
} else i = len;
|
||||
|
||||
out:
|
||||
spinlock_unlock(&lwip_lock);
|
||||
|
||||
return ret;
|
||||
return i;
|
||||
}
|
||||
|
||||
static ssize_t sys_sbrk(int incr)
|
||||
|
@ -159,20 +212,23 @@ static int sys_open(const char* name, int flags, int mode)
|
|||
{
|
||||
task_t* task = per_core(current_task);
|
||||
int i, ret, sysnr = __NR_open;
|
||||
size_t len = strlen(name+1);
|
||||
size_t len;
|
||||
|
||||
if (task->sd < 0)
|
||||
return 0;
|
||||
|
||||
len = strlen(name+1);
|
||||
len = strlen(name)+1;
|
||||
|
||||
spinlock_lock(&lwip_lock);
|
||||
|
||||
ret = write(task->sd, &sysnr, sizeof(int));
|
||||
i = 0;
|
||||
setsockopt(task->sd, IPPROTO_TCP, TCP_NODELAY, (char *) &i, sizeof(i));
|
||||
|
||||
ret = write(task->sd, &sysnr, sizeof(sysnr));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = write(task->sd, &len, sizeof(size_t));
|
||||
ret = write(task->sd, &len, sizeof(len));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
|
@ -185,15 +241,18 @@ static int sys_open(const char* name, int flags, int mode)
|
|||
i += ret;
|
||||
}
|
||||
|
||||
ret = write(task->sd, &flags, sizeof(int));
|
||||
ret = write(task->sd, &flags, sizeof(flags));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = write(task->sd, &mode, sizeof(int));
|
||||
ret = write(task->sd, &mode, sizeof(mode));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
read(task->sd, &ret, sizeof(int));
|
||||
i = 1;
|
||||
setsockopt(task->sd, IPPROTO_TCP, TCP_NODELAY, (char *) &i, sizeof(i));
|
||||
|
||||
read(task->sd, &ret, sizeof(ret));
|
||||
|
||||
out:
|
||||
spinlock_unlock(&lwip_lock);
|
||||
|
@ -201,23 +260,26 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
int sysnr;
|
||||
int fd;
|
||||
} __attribute__((packed)) sys_close_t;
|
||||
|
||||
static int sys_close(int fd)
|
||||
{
|
||||
int ret;
|
||||
task_t* task = per_core(current_task);
|
||||
int ret, sysnr = __NR_close;
|
||||
sys_close_t sysargs = {__NR_close, fd};
|
||||
|
||||
if (task->sd < 0)
|
||||
return 0;
|
||||
|
||||
spinlock_lock(&lwip_lock);
|
||||
|
||||
ret = write(task->sd, &sysnr, sizeof(int));
|
||||
if (ret < 0)
|
||||
ret = write(task->sd, &sysargs, sizeof(sysargs));
|
||||
if (ret != sizeof(sysargs))
|
||||
goto out;
|
||||
ret = write(task->sd, &fd, sizeof(int));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
read(task->sd, &ret, sizeof(int));
|
||||
read(task->sd, &ret, sizeof(ret));
|
||||
|
||||
out:
|
||||
spinlock_unlock(&lwip_lock);
|
||||
|
@ -295,10 +357,42 @@ static int sys_clone(tid_t* id, void* ep, void* argv)
|
|||
return clone_task(id, ep, argv, per_core(current_task)->prio);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
int sysnr;
|
||||
int fd;
|
||||
off_t offset;
|
||||
int whence;
|
||||
} __attribute__((packed)) sys_lseek_t;
|
||||
|
||||
static off_t sys_lseek(int fd, off_t offset, int whence)
|
||||
{
|
||||
off_t off;
|
||||
task_t* task = per_core(current_task);
|
||||
sys_lseek_t sysargs = {__NR_lseek, fd, offset, whence};
|
||||
|
||||
if (task->sd < 0)
|
||||
return -ENOSYS;
|
||||
|
||||
spinlock_lock(&lwip_lock);
|
||||
|
||||
write(task->sd, &sysargs, sizeof(sysargs));
|
||||
read(task->sd, &off, sizeof(off));
|
||||
|
||||
spinlock_unlock(&lwip_lock);
|
||||
|
||||
return off;
|
||||
}
|
||||
|
||||
static int default_handler(void)
|
||||
{
|
||||
#if 0
|
||||
kprintf("Invalid system call\n");
|
||||
#else
|
||||
uint64_t rax;
|
||||
|
||||
asm volatile ("mov %%rax, %0" : "=m"(rax) :: "memory");
|
||||
kprintf("Invalid system call: %zd\n", rax);
|
||||
#endif
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
|
@ -307,8 +401,8 @@ size_t syscall_table[] = {
|
|||
(size_t) sys_write, /* __NR_write */
|
||||
(size_t) sys_open, /* __NR_open */
|
||||
(size_t) sys_close, /* __NR_close */
|
||||
(size_t) default_handler, /* __NR_read */
|
||||
(size_t) default_handler, /* __NR_lseek */
|
||||
(size_t) sys_read, /* __NR_read */
|
||||
(size_t) sys_lseek, /* __NR_lseek */
|
||||
(size_t) default_handler, /* __NR_unlink */
|
||||
(size_t) sys_getpid, /* __NR_getpid */
|
||||
(size_t) default_handler, /* __NR_kill */
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <linux/tcp.h>
|
||||
|
||||
#define HERMIT_PORT 0x494F
|
||||
#define HERMIT_MAGIC 0x7E317
|
||||
|
@ -44,6 +45,7 @@
|
|||
#define __HERMIT_open 2
|
||||
#define __HERMIT_close 3
|
||||
#define __HERMIT_read 4
|
||||
#define __HERMIT_lseek 5
|
||||
|
||||
static char saddr[16] = "192.168.28.2";
|
||||
static int sobufsize = 131072;
|
||||
|
@ -69,7 +71,7 @@ int handle_syscalls(int s)
|
|||
switch(sysnr)
|
||||
{
|
||||
case __HERMIT_exit: {
|
||||
int arg;
|
||||
int arg = 0;
|
||||
|
||||
ret = read(s, &arg, sizeof(arg));
|
||||
if (ret < 0)
|
||||
|
@ -80,7 +82,8 @@ int handle_syscalls(int s)
|
|||
}
|
||||
case __HERMIT_write: {
|
||||
int fd;
|
||||
size_t j, len;
|
||||
ssize_t j;
|
||||
size_t len;
|
||||
char* buff;
|
||||
|
||||
ret = read(s, &fd, sizeof(fd));
|
||||
|
@ -105,18 +108,52 @@ int handle_syscalls(int s)
|
|||
j += len;
|
||||
}
|
||||
|
||||
j=0;
|
||||
while(j < len)
|
||||
{
|
||||
ret = write(fd, buff+j, len-j);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
j += len;
|
||||
}
|
||||
j = write(fd, buff, len);
|
||||
if (fd > 2)
|
||||
write(s, &j, sizeof(j));
|
||||
|
||||
free(buff);
|
||||
break;
|
||||
}
|
||||
case __HERMIT_open: {
|
||||
size_t j, len;
|
||||
char* fname;
|
||||
int flags, mode;
|
||||
|
||||
ret = read(s, &len, sizeof(len));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
fname = malloc(len);
|
||||
if (!fname)
|
||||
goto out;
|
||||
|
||||
j = 0;
|
||||
while(j < len)
|
||||
{
|
||||
ret = read(s, fname+j, len-j);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
j += ret;
|
||||
}
|
||||
|
||||
ret = read(s, &flags, sizeof(flags));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = read(s, &mode, sizeof(mode));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
//printf("flags 0x%x, mode 0x%x\n", flags, mode);
|
||||
|
||||
ret = open(fname, flags, mode);
|
||||
write(s, &ret, sizeof(ret));
|
||||
|
||||
free(fname);
|
||||
break;
|
||||
}
|
||||
case __HERMIT_close: {
|
||||
int fd;
|
||||
|
||||
|
@ -134,6 +171,63 @@ int handle_syscalls(int s)
|
|||
goto out;
|
||||
break;
|
||||
}
|
||||
case __HERMIT_read: {
|
||||
int fd, flag;
|
||||
size_t len;
|
||||
ssize_t j;
|
||||
char* buff;
|
||||
|
||||
ret = read(s, &fd, sizeof(fd));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = read(s, &len, sizeof(len));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
buff = malloc(len);
|
||||
if (!buff)
|
||||
goto out;
|
||||
|
||||
j = read(fd, buff, len);
|
||||
|
||||
flag = 0;
|
||||
setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int));
|
||||
|
||||
write(s, &j, sizeof(j));
|
||||
|
||||
if (j > 0)
|
||||
{
|
||||
ssize_t i = 0;
|
||||
|
||||
while(i < j)
|
||||
{
|
||||
ret = write(s, buff+i, j-i);
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
i += ret;
|
||||
}
|
||||
}
|
||||
|
||||
flag = 1;
|
||||
setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int));
|
||||
|
||||
free(buff);
|
||||
break;
|
||||
}
|
||||
case __HERMIT_lseek: {
|
||||
int fd, whence;
|
||||
off_t offset;
|
||||
|
||||
read(s, &fd, sizeof(fd));
|
||||
read(s, &offset, sizeof(offset));
|
||||
read(s, &whence, sizeof(whence));
|
||||
|
||||
offset = lseek(fd, offset, whence);
|
||||
write(s, &offset, sizeof(offset));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
fprintf(stderr, "Proxy: invalid syscall number %d\n", sysnr);
|
||||
break;
|
||||
|
@ -141,7 +235,7 @@ int handle_syscalls(int s)
|
|||
}
|
||||
|
||||
out:
|
||||
perror("Proxy: communication error");
|
||||
perror("Proxy -- communication error");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -162,6 +256,8 @@ int main(int argc, char **argv)
|
|||
|
||||
setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *) &sobufsize, sizeof(sobufsize));
|
||||
setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *) &sobufsize, sizeof(sobufsize));
|
||||
i = 1;
|
||||
setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *) &i, sizeof(i));
|
||||
|
||||
/* server address */
|
||||
memset((char *) &serv_name, 0x00, sizeof(serv_name));
|
||||
|
@ -172,7 +268,7 @@ int main(int argc, char **argv)
|
|||
ret = connect(s, (struct sockaddr*)&serv_name, sizeof(serv_name));
|
||||
if (ret < 0)
|
||||
{
|
||||
perror("Proxy: connection error");
|
||||
perror("Proxy -- connection error");
|
||||
close(s);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -226,7 +322,7 @@ int main(int argc, char **argv)
|
|||
return ret;
|
||||
|
||||
out:
|
||||
perror("Proxy: communication error");
|
||||
perror("Proxy -- communication error");
|
||||
close(s);
|
||||
return 1;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue