1
0
Fork 0
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:
Stefan Lankes 2017-02-21 14:08:49 +01:00
parent 8a4ef8efd0
commit 954343128e
3 changed files with 199 additions and 198 deletions

View file

@ -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(&ethreq, 0, sizeof(ethreq));
strncpy(ethreq.ifr_name, "mmnif", IFNAMSIZ);
memset(&ethreq, 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, &ethreq);
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, &ethreq);
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();
}

View file

@ -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

View file

@ -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);
}