mirror of
https://github.com/hermitcore/libhermit.git
synced 2025-03-09 00:00:03 +01:00
increasing the readability
- restructure the code and test it within a VM
This commit is contained in:
parent
8a4ef8efd0
commit
954343128e
3 changed files with 199 additions and 198 deletions
324
tools/proxy.c
324
tools/proxy.c
|
@ -66,9 +66,9 @@
|
|||
#define PROXY_DEBUG(fmt, ...) {}
|
||||
#endif
|
||||
|
||||
static monitor_t monitor = BAREMETAL;
|
||||
static int sobufsize = 131072;
|
||||
static unsigned int isle_nr = 0;
|
||||
static unsigned int qemu = 0;
|
||||
static unsigned int port = HERMIT_PORT;
|
||||
static char pidname[] = "/tmp/hpid-XXXXXX";
|
||||
static char tmpname[] = "/tmp/hermit-XXXXXX";
|
||||
|
@ -78,16 +78,15 @@ extern char **environ;
|
|||
|
||||
static void stop_hermit(void);
|
||||
static void dump_log(void);
|
||||
static int init_multi(char *path);
|
||||
static int init_qemu(char *path);
|
||||
int init_uhyve(char *path);
|
||||
static int multi_init(char *path);
|
||||
static int qemu_init(char *path);
|
||||
|
||||
static void fini_qemu(void)
|
||||
static void qemu_fini(void)
|
||||
{
|
||||
FILE* fp = NULL;
|
||||
|
||||
// try to kill qemu
|
||||
if (qemu)
|
||||
if (monitor == QEMU)
|
||||
fp = fopen(pidname, "r");
|
||||
if (fp) {
|
||||
pid_t id = -1;
|
||||
|
@ -110,7 +109,7 @@ static void fini_qemu(void)
|
|||
unlink(tmpname);
|
||||
}
|
||||
|
||||
static void fini_multi(void)
|
||||
static void multi_fini(void)
|
||||
{
|
||||
dump_log();
|
||||
stop_hermit();
|
||||
|
@ -152,11 +151,10 @@ static char* cpufreq(void)
|
|||
return "-freq0";
|
||||
}
|
||||
|
||||
static int init_env(char *path)
|
||||
static int env_init(char *path)
|
||||
{
|
||||
char* str;
|
||||
struct sigaction sINT, sTERM;
|
||||
unsigned int uhyve = 0;
|
||||
|
||||
// define action for SIGINT
|
||||
sINT.sa_handler = exit_handler;
|
||||
|
@ -180,12 +178,10 @@ static int init_env(char *path)
|
|||
if (str)
|
||||
{
|
||||
if (strncmp(str, "qemu", 4) == 0) {
|
||||
qemu = 1;
|
||||
uhyve = 0;
|
||||
monitor = QEMU;
|
||||
isle_nr = 0;
|
||||
} else if (strncmp(str, "uhyve", 5) == 0) {
|
||||
uhyve = 1;
|
||||
qemu = 0;
|
||||
monitor = UHYVE;
|
||||
isle_nr = 0;
|
||||
} else {
|
||||
isle_nr = atoi(str);
|
||||
|
@ -202,14 +198,14 @@ static int init_env(char *path)
|
|||
port = HERMIT_PORT;
|
||||
}
|
||||
|
||||
if (qemu) {
|
||||
atexit(fini_qemu);
|
||||
return init_qemu(path);
|
||||
} else if (uhyve) {
|
||||
return init_uhyve(path);
|
||||
if (monitor == QEMU) {
|
||||
atexit(qemu_fini);
|
||||
return qemu_init(path);
|
||||
} else if (monitor == UHYVE) {
|
||||
return uhyve_init(path);
|
||||
} else {
|
||||
atexit(fini_multi);
|
||||
return init_multi(path);
|
||||
atexit(multi_fini);
|
||||
return multi_init(path);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -225,7 +221,7 @@ static int is_hermit_available(void)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
if (qemu) {
|
||||
if (monitor == QEMU) {
|
||||
file = fopen(tmpname, "r");
|
||||
if (!file) {
|
||||
PROXY_DEBUG("%s isn't available\n", tmpname);
|
||||
|
@ -271,7 +267,7 @@ static void wait_hermit_available(void)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
if (qemu)
|
||||
if (monitor == QEMU)
|
||||
wd = inotify_add_watch(fd, "/tmp", IN_MODIFY|IN_CREATE);
|
||||
else
|
||||
wd = inotify_add_watch(fd, "/sys/hermit", IN_MODIFY|IN_CREATE);
|
||||
|
@ -301,7 +297,7 @@ static void wait_hermit_available(void)
|
|||
close(fd);
|
||||
}
|
||||
|
||||
static int init_qemu(char *path)
|
||||
static int qemu_init(char *path)
|
||||
{
|
||||
int kvm, i = 0;
|
||||
char* str;
|
||||
|
@ -457,7 +453,7 @@ static int init_qemu(char *path)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int init_multi(char *path)
|
||||
static int multi_init(char *path)
|
||||
{
|
||||
int ret;
|
||||
char* str;
|
||||
|
@ -532,7 +528,7 @@ static void dump_log(void)
|
|||
if (!(str && (strcmp(str, "0") != 0)))
|
||||
return;
|
||||
|
||||
if (!qemu)
|
||||
if (monitor == BAREMETAL)
|
||||
{
|
||||
char isle_path[MAX_PATH];
|
||||
|
||||
|
@ -885,155 +881,163 @@ out:
|
|||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
int socket_loop(int argc, char **argv)
|
||||
{
|
||||
int i, j, ret, s;
|
||||
int32_t magic = HERMIT_MAGIC;
|
||||
struct sockaddr_in serv_name;
|
||||
|
||||
init_env(argv[1]);
|
||||
|
||||
// in case of uhyve, we will never reach this point
|
||||
// => we could now establish an IP connection to HermitCore
|
||||
|
||||
#if 0
|
||||
// check if mmnif interface is available
|
||||
if (!qemu) {
|
||||
struct ifreq ethreq;
|
||||
// check if mmnif interface is available
|
||||
if (!qemu) {
|
||||
struct ifreq ethreq;
|
||||
|
||||
memset(ðreq, 0, sizeof(ethreq));
|
||||
strncpy(ethreq.ifr_name, "mmnif", IFNAMSIZ);
|
||||
memset(ðreq, 0, sizeof(ethreq));
|
||||
strncpy(ethreq.ifr_name, "mmnif", IFNAMSIZ);
|
||||
|
||||
while(1) {
|
||||
/* this socket doesn't really matter, we just need a descriptor
|
||||
* to perform the ioctl on */
|
||||
s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
ioctl(s, SIOCGIFFLAGS, ðreq);
|
||||
close(s);
|
||||
while(1) {
|
||||
/* this socket doesn't really matter, we just need a descriptor
|
||||
* to perform the ioctl on */
|
||||
s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
ioctl(s, SIOCGIFFLAGS, ðreq);
|
||||
close(s);
|
||||
|
||||
if (ethreq.ifr_flags & (IFF_UP|IFF_RUNNING))
|
||||
break;
|
||||
if (ethreq.ifr_flags & (IFF_UP|IFF_RUNNING))
|
||||
break;
|
||||
}
|
||||
sched_yield();
|
||||
}
|
||||
sched_yield();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* create a socket */
|
||||
s = socket(PF_INET, SOCK_STREAM, 0);
|
||||
if (s < 0)
|
||||
{
|
||||
perror("Proxy: socket creation error");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
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));
|
||||
i = 0;
|
||||
setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char *) &i, sizeof(i));
|
||||
|
||||
/* server address */
|
||||
memset((char *) &serv_name, 0x00, sizeof(serv_name));
|
||||
serv_name.sin_family = AF_INET;
|
||||
if (qemu)
|
||||
serv_name.sin_addr = INADDR(127, 0, 0, 1);
|
||||
else
|
||||
serv_name.sin_addr = HERMIT_IP(isle_nr);
|
||||
serv_name.sin_port = htons(port);
|
||||
|
||||
i = 0;
|
||||
retry:
|
||||
ret = connect(s, (struct sockaddr*)&serv_name, sizeof(serv_name));
|
||||
if (ret < 0)
|
||||
{
|
||||
i++;
|
||||
if (i <= 10) {
|
||||
usleep(10000);
|
||||
goto retry;
|
||||
/* create a socket */
|
||||
s = socket(PF_INET, SOCK_STREAM, 0);
|
||||
if (s < 0)
|
||||
{
|
||||
perror("Proxy: socket creation error");
|
||||
exit(1);
|
||||
}
|
||||
perror("Proxy -- connection error");
|
||||
|
||||
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));
|
||||
i = 0;
|
||||
setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char *) &i, sizeof(i));
|
||||
|
||||
/* server address */
|
||||
memset((char *) &serv_name, 0x00, sizeof(serv_name));
|
||||
serv_name.sin_family = AF_INET;
|
||||
if (monitor == QEMU)
|
||||
serv_name.sin_addr = INADDR(127, 0, 0, 1);
|
||||
else
|
||||
serv_name.sin_addr = HERMIT_IP(isle_nr);
|
||||
serv_name.sin_port = htons(port);
|
||||
|
||||
i = 0;
|
||||
retry:
|
||||
ret = connect(s, (struct sockaddr*)&serv_name, sizeof(serv_name));
|
||||
if (ret < 0)
|
||||
{
|
||||
i++;
|
||||
if (i <= 10) {
|
||||
usleep(10000);
|
||||
goto retry;
|
||||
}
|
||||
perror("Proxy -- connection error");
|
||||
close(s);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ret = write(s, &magic, sizeof(magic));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
// forward program arguments to HermitCore
|
||||
// argv[0] is path of this proxy so we strip it
|
||||
|
||||
argv++;
|
||||
argc--;
|
||||
|
||||
ret = write(s, &argc, sizeof(argc));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
for(i=0; i<argc; i++)
|
||||
{
|
||||
int len = strlen(argv[i])+1;
|
||||
|
||||
j = 0;
|
||||
while (j < sizeof(len))
|
||||
{
|
||||
ret = write(s, ((char*)&len)+j, sizeof(len)-j);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
j += ret;
|
||||
}
|
||||
|
||||
j = 0;
|
||||
while (j < len)
|
||||
{
|
||||
ret = write(s, argv[i]+j, len-j);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
j += ret;
|
||||
}
|
||||
}
|
||||
|
||||
// send environment
|
||||
i = 0;
|
||||
while(environ[i])
|
||||
i++;
|
||||
|
||||
ret = write(s, &i, sizeof(i));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
for(i=0; environ[i] ;i++)
|
||||
{
|
||||
int len = strlen(environ[i])+1;
|
||||
|
||||
j = 0;
|
||||
while (j < sizeof(len))
|
||||
{
|
||||
ret = write(s, ((char*)&len)+j, sizeof(len)-j);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
j += ret;
|
||||
}
|
||||
|
||||
j = 0;
|
||||
while (j < len)
|
||||
{
|
||||
ret = write(s, environ[i]+j, len-j);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
j += ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = handle_syscalls(s);
|
||||
|
||||
close(s);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ret = write(s, &magic, sizeof(magic));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
return ret;
|
||||
|
||||
// forward program arguments to HermitCore
|
||||
// argv[0] is path of this proxy so we strip it
|
||||
|
||||
argv++;
|
||||
argc--;
|
||||
|
||||
ret = write(s, &argc, sizeof(argc));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
for(i=0; i<argc; i++)
|
||||
{
|
||||
int len = strlen(argv[i])+1;
|
||||
|
||||
j = 0;
|
||||
while (j < sizeof(len))
|
||||
{
|
||||
ret = write(s, ((char*)&len)+j, sizeof(len)-j);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
j += ret;
|
||||
}
|
||||
|
||||
j = 0;
|
||||
while (j < len)
|
||||
{
|
||||
ret = write(s, argv[i]+j, len-j);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
j += ret;
|
||||
}
|
||||
}
|
||||
|
||||
// send environment
|
||||
i = 0;
|
||||
while(environ[i])
|
||||
i++;
|
||||
|
||||
ret = write(s, &i, sizeof(i));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
for(i=0; environ[i] ;i++)
|
||||
{
|
||||
int len = strlen(environ[i])+1;
|
||||
|
||||
j = 0;
|
||||
while (j < sizeof(len))
|
||||
{
|
||||
ret = write(s, ((char*)&len)+j, sizeof(len)-j);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
j += ret;
|
||||
}
|
||||
|
||||
j = 0;
|
||||
while (j < len)
|
||||
{
|
||||
ret = write(s, environ[i]+j, len-j);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
j += ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = handle_syscalls(s);
|
||||
|
||||
close(s);
|
||||
|
||||
return ret;
|
||||
|
||||
out:
|
||||
perror("Proxy -- communication error");
|
||||
close(s);
|
||||
return 1;
|
||||
out:
|
||||
perror("Proxy -- communication error");
|
||||
close(s);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = env_init(argv[1]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (monitor != UHYVE)
|
||||
return socket_loop(argc, argv);
|
||||
return uhyve_loop();
|
||||
}
|
||||
|
|
|
@ -39,4 +39,13 @@
|
|||
#define __HERMIT_read 4
|
||||
#define __HERMIT_lseek 5
|
||||
|
||||
#endif
|
||||
typedef enum {
|
||||
BAREMETAL = 0,
|
||||
QEMU,
|
||||
UHYVE
|
||||
} monitor_t;
|
||||
|
||||
int uhyve_init(char *path);
|
||||
int uhyve_loop(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
* lkvm: http://github.com/clearlinux/kvmtool
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
* 15.1.2017: extend original version (https://github.com/Solo5/solo5)
|
||||
* for HermitCore
|
||||
*/
|
||||
|
@ -99,6 +99,7 @@ static size_t guest_size = 0x20000000ULL;
|
|||
static uint64_t elf_entry;
|
||||
//static pthread_t vcpu_thread;
|
||||
static volatile uint8_t done = 0;
|
||||
static __thread struct kvm_run *run = NULL;
|
||||
|
||||
typedef struct {
|
||||
int fd;
|
||||
|
@ -157,29 +158,23 @@ static void uhyve_exit(void)
|
|||
|
||||
static uint32_t get_cpufreq(void)
|
||||
{
|
||||
#if 1
|
||||
char line[2048];
|
||||
uint32_t freq = 0;
|
||||
|
||||
FILE* fp = fopen("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", "r");
|
||||
if (!fp) {
|
||||
perror("Unable to open /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq\n");
|
||||
return freq;
|
||||
}
|
||||
|
||||
if (fgets(line, 2048, fp))
|
||||
freq = atoi(line) / 1000;
|
||||
|
||||
return freq;
|
||||
#else
|
||||
uint32_t freq = 0;
|
||||
char line[2048];
|
||||
char* match;
|
||||
char* point;
|
||||
|
||||
FILE* fp = fopen("/proc/cpuinfo", "r");
|
||||
FILE* fp = fopen("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", "r");
|
||||
if (fp) {
|
||||
if (fgets(line, 2048, fp))
|
||||
freq = atoi(line) / 1000;
|
||||
fclose(fp);
|
||||
|
||||
return freq;
|
||||
}
|
||||
|
||||
fp = fopen("/proc/cpuinfo", "r");
|
||||
if (!fp)
|
||||
return freq;
|
||||
return freq;
|
||||
|
||||
while(fgets(line, 2048, fp)) {
|
||||
if ((match = strstr(line, "cpu MHz")) == NULL)
|
||||
|
@ -196,11 +191,10 @@ static uint32_t get_cpufreq(void)
|
|||
freq = atoi(match);
|
||||
fclose(fp);
|
||||
|
||||
return freq;
|
||||
return freq;
|
||||
}
|
||||
|
||||
return freq;
|
||||
#endif
|
||||
}
|
||||
|
||||
static ssize_t pread_in_full(int fd, void *buf, size_t count, off_t offset)
|
||||
|
@ -435,7 +429,7 @@ static void setup_cpuid(int kvm, int vcpufd)
|
|||
kvm_ioctl(vcpufd, KVM_SET_CPUID2, kvm_cpuid);
|
||||
}
|
||||
|
||||
static void* vcpu_loop(struct kvm_run *run)
|
||||
static int vcpu_loop(struct kvm_run *run)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -462,7 +456,7 @@ static void* vcpu_loop(struct kvm_run *run)
|
|||
switch (run->exit_reason) {
|
||||
case KVM_EXIT_HLT:
|
||||
fprintf(stderr, "Guest has halted the CPU, this is considered as a normal exit.\n");
|
||||
return NULL;
|
||||
return 0;
|
||||
|
||||
case KVM_EXIT_MMIO:
|
||||
err(1, "KVM: unhandled KVM_EXIT_MMIO at 0x%llx", run->mmio.phys_addr);
|
||||
|
@ -501,7 +495,7 @@ static void* vcpu_loop(struct kvm_run *run)
|
|||
|
||||
uhyve_open->ret = open((const char*)guest_mem+(size_t)uhyve_open->name, uhyve_open->flags, uhyve_open->mode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
case UHYVE_PORT_CLOSE: {
|
||||
unsigned data = *((unsigned*)((size_t)run+run->io.data_offset));
|
||||
|
@ -516,7 +510,7 @@ static void* vcpu_loop(struct kvm_run *run)
|
|||
unsigned data = *((unsigned*)((size_t)run+run->io.data_offset));
|
||||
uhyve_lseek_t* uhyve_lseek = (uhyve_lseek_t*) (guest_mem+data);
|
||||
|
||||
uhyve_lseek->offset = lseek(uhyve_lseek->fd, uhyve_lseek->offset, uhyve_lseek->whence);
|
||||
uhyve_lseek->offset = lseek(uhyve_lseek->fd, uhyve_lseek->offset, uhyve_lseek->whence);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -544,14 +538,12 @@ static void* vcpu_loop(struct kvm_run *run)
|
|||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void* uhyve_thread(void* arg)
|
||||
int uhyve_init(char *path)
|
||||
{
|
||||
char* path = (char*) arg;
|
||||
size_t mmap_size;
|
||||
struct kvm_run *run;
|
||||
|
||||
// register routine to close the VM
|
||||
atexit(uhyve_exit);
|
||||
|
@ -625,14 +617,10 @@ static void* uhyve_thread(void* arg)
|
|||
|
||||
setup_cpuid(kvm, vcpufd);
|
||||
|
||||
return vcpu_loop(run);
|
||||
}
|
||||
|
||||
int init_uhyve(char *path)
|
||||
{
|
||||
//pthread_create(&vcpu_thread, NULL, uhyve_thread, (void*)path);
|
||||
|
||||
uhyve_thread(path);
|
||||
exit(EXIT_SUCCESS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uhyve_loop(void)
|
||||
{
|
||||
return vcpu_loop(run);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue