mirror of
https://github.com/hermitcore/libhermit.git
synced 2025-03-09 00:00:03 +01:00
Support for forwarding command line parameters and environment variables
to uhyve
This commit is contained in:
parent
3ee4a48728
commit
cfd208d266
10 changed files with 173 additions and 4 deletions
|
@ -36,6 +36,9 @@ foreach(MODULE ${KERNEL_MODULES})
|
|||
target_compile_definitions(${MODULE}
|
||||
PRIVATE -D__KERNEL__)
|
||||
|
||||
target_compile_definitions(${MODULE}
|
||||
PRIVATE -DMAX_ARGC_ENVC=${MAX_ARGC_ENVC})
|
||||
|
||||
target_compile_options(${MODULE}
|
||||
PRIVATE ${HERMIT_KERNEL_FLAGS})
|
||||
|
||||
|
|
|
@ -19,6 +19,10 @@ set(KERNEL_STACK_SIZE 8192 CACHE STRING
|
|||
set(DEFAULT_STACK_SIZE 262144 CACHE STRING
|
||||
"Task stack size in bytes")
|
||||
|
||||
set(MAX_ARGC_ENVC 128 CACHE STRING
|
||||
"Maximum number of command line parameters and enviroment variables
|
||||
forwarded to uhyve")
|
||||
|
||||
option(DYNAMIC_TICKS
|
||||
"Don't use a periodic timer event to keep track of time" ON)
|
||||
|
||||
|
|
|
@ -99,6 +99,7 @@ function(build_external NAME PATH DEPENDS)
|
|||
-DLOCAL_PREFIX_BASE_DIR=${LOCAL_PREFIX_BASE_DIR}
|
||||
-DCMAKE_INSTALL_MESSAGE=NEVER
|
||||
-DCMAKE_EXPORT_COMPILE_COMMANDS=true
|
||||
-DMAX_ARGC_ENVC=${MAX_ARGC_ENVC}
|
||||
--no-warn-unused-cli
|
||||
${DO_PROFILING}
|
||||
${CMD_VARS}
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include <asm/page.h>
|
||||
#include <asm/uart.h>
|
||||
#include <asm/multiboot.h>
|
||||
#include <asm/uhyve.h>
|
||||
|
||||
#include <lwip/init.h>
|
||||
#include <lwip/sys.h>
|
||||
|
@ -65,6 +66,22 @@
|
|||
#define HERMIT_PORT 0x494E
|
||||
#define HERMIT_MAGIC 0x7E317
|
||||
|
||||
/* Ports and data structures for command line args + envp forwarding to uhyve */
|
||||
#define UHYVE_PORT_CMDSIZE 0x509
|
||||
#define UHYVE_PORT_CMDVAL 0x510
|
||||
|
||||
typedef struct {
|
||||
int argc;
|
||||
int argsz[MAX_ARGC_ENVC];
|
||||
int envc;
|
||||
int envsz[MAX_ARGC_ENVC];
|
||||
} __attribute__ ((packed)) uhyve_cmdsize_t;
|
||||
|
||||
typedef struct {
|
||||
char **argv;
|
||||
char **envp;
|
||||
} __attribute__ ((packed)) uhyve_cmdval_t;
|
||||
|
||||
static struct netif default_netif;
|
||||
static const int sobufsize = 131072;
|
||||
|
||||
|
@ -370,6 +387,37 @@ static int initd(void* arg)
|
|||
// initialize network
|
||||
err = init_netifs();
|
||||
|
||||
if(is_uhyve()) {
|
||||
int i;
|
||||
uhyve_cmdsize_t uhyve_cmdsize;
|
||||
uhyve_cmdval_t uhyve_cmdval;
|
||||
|
||||
uhyve_send(UHYVE_PORT_CMDSIZE,
|
||||
(unsigned)virt_to_phys((size_t)&uhyve_cmdsize));
|
||||
|
||||
uhyve_cmdval.argv = kmalloc(uhyve_cmdsize.argc * sizeof(char *));
|
||||
for(i=0; i<uhyve_cmdsize.argc; i++)
|
||||
uhyve_cmdval.argv[i] = kmalloc(uhyve_cmdsize.argsz[i] * sizeof(char));
|
||||
uhyve_cmdval.envp = kmalloc(uhyve_cmdsize.envc * sizeof(char *));
|
||||
for(i=0; i<uhyve_cmdsize.envc; i++)
|
||||
uhyve_cmdval.envp[i] = kmalloc(uhyve_cmdsize.envsz[i] * sizeof(char));
|
||||
|
||||
uhyve_send(UHYVE_PORT_CMDVAL,
|
||||
(unsigned)virt_to_phys((size_t)&uhyve_cmdval));
|
||||
|
||||
LOG_INFO("Boot time: %d ms\n", (get_clock_tick() * 1000) / TIMER_FREQ);
|
||||
libc_start(uhyve_cmdsize.argc, uhyve_cmdval.argv, uhyve_cmdval.envp);
|
||||
|
||||
for(i=0; i<argc; i++)
|
||||
kfree(uhyve_cmdval.argv[i]);
|
||||
kfree(uhyve_cmdval.argv);
|
||||
for(i=0; i<envc; i++)
|
||||
kfree(uhyve_cmdval.envp[i]);
|
||||
kfree(uhyve_cmdval.envp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((err != 0) || !is_proxy())
|
||||
{
|
||||
char* dummy[] = {"app_name", NULL};
|
||||
|
|
|
@ -7,6 +7,7 @@ add_compile_options(-std=c99)
|
|||
|
||||
add_executable(proxy proxy.c utils.c uhyve.c uhyve-net.c)
|
||||
target_compile_options(proxy PUBLIC -pthread)
|
||||
target_compile_options(proxy PUBLIC -DMAX_ARGC_ENVC=${MAX_ARGC_ENVC})
|
||||
target_link_libraries(proxy -pthread)
|
||||
|
||||
install(TARGETS proxy
|
||||
|
|
|
@ -1028,7 +1028,7 @@ int main(int argc, char **argv)
|
|||
|
||||
switch(monitor) {
|
||||
case UHYVE:
|
||||
return uhyve_loop();
|
||||
return uhyve_loop(argc, argv);
|
||||
|
||||
case BAREMETAL:
|
||||
case QEMU:
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#define __HERMIT_lseek 5
|
||||
|
||||
int uhyve_init(char *path);
|
||||
int uhyve_loop(void);
|
||||
int uhyve_loop(int argc, char **argv);
|
||||
|
||||
// define some helper functions
|
||||
uint32_t get_cpufreq(void);
|
||||
|
|
|
@ -190,6 +190,29 @@ static __thread struct kvm_run *run = NULL;
|
|||
static __thread int vcpufd = -1;
|
||||
static __thread uint32_t cpuid = 0;
|
||||
|
||||
int uhyve_argc = -1;
|
||||
int uhyve_envc = -1;
|
||||
char **uhyve_argv = NULL;
|
||||
extern char **environ;
|
||||
char **uhyve_envp = NULL;
|
||||
|
||||
/* Ports and data structures for uhyve command line arguments and envp
|
||||
* forwarding */
|
||||
#define UHYVE_PORT_CMDSIZE 0x509
|
||||
#define UHYVE_PORT_CMDVAL 0x510
|
||||
|
||||
typedef struct {
|
||||
int argc;
|
||||
int argsz[128];
|
||||
int envc;
|
||||
int envsz[128];
|
||||
} __attribute__ ((packed)) uhyve_cmdsize_t;
|
||||
|
||||
typedef struct {
|
||||
char **argv;
|
||||
char **envp;
|
||||
} __attribute__ ((packed)) uhyve_cmdval_t;
|
||||
|
||||
static uint64_t memparse(const char *ptr)
|
||||
{
|
||||
// local pointer to end of parsed string
|
||||
|
@ -894,6 +917,65 @@ static int vcpu_loop(void)
|
|||
break;
|
||||
}
|
||||
|
||||
case UHYVE_PORT_CMDSIZE: {
|
||||
int i;
|
||||
unsigned data = *((unsigned*)((size_t)run+run->io.data_offset));
|
||||
uhyve_cmdsize_t *val = (uhyve_cmdsize_t *) (guest_mem+data);
|
||||
|
||||
val->argc = uhyve_argc;
|
||||
for(i=0; i<uhyve_argc; i++)
|
||||
val->argsz[i] = strlen(uhyve_argv[i]);
|
||||
|
||||
val->envc = uhyve_envc;
|
||||
for(i=0; i<uhyve_envc; i++)
|
||||
val->envsz[i] = strlen(uhyve_envp[i]);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case UHYVE_PORT_CMDVAL: {
|
||||
int i;
|
||||
char **argv_ptr, **env_ptr;
|
||||
struct kvm_translation kt;
|
||||
unsigned data = *((unsigned*)((size_t)run+run->io.data_offset));
|
||||
uhyve_cmdval_t *val = (uhyve_cmdval_t *) (guest_mem+data);
|
||||
|
||||
/* buffers inside uhyve_cmdval are not directlty mapped
|
||||
* (they are allocated through kmalloc) so we cannot
|
||||
* used a simple offset as the guest to host, we have to
|
||||
* walk the guest page table to find the physical address,
|
||||
* then we can use the offset
|
||||
*/
|
||||
|
||||
/* argv */
|
||||
kt.linear_address = (unsigned long long)val->argv;
|
||||
kvm_ioctl(vcpufd, KVM_TRANSLATE, &kt);
|
||||
argv_ptr = (char **)(guest_mem +
|
||||
(size_t)kt.physical_address);
|
||||
|
||||
for(i=0; i<uhyve_argc; i++) {
|
||||
kt.linear_address = (unsigned long long)argv_ptr[i];
|
||||
kvm_ioctl(vcpufd, KVM_TRANSLATE, &kt);
|
||||
strcpy(guest_mem + (size_t)kt.physical_address,
|
||||
uhyve_argv[i]);
|
||||
}
|
||||
|
||||
/* env */
|
||||
kt.linear_address = (unsigned long long)val->envp;
|
||||
kvm_ioctl(vcpufd, KVM_TRANSLATE, &kt);
|
||||
env_ptr = (char **)(guest_mem +
|
||||
(size_t)kt.physical_address);
|
||||
|
||||
for(i=0; i<uhyve_envc; i++) {
|
||||
kt.linear_address = (unsigned long long)env_ptr[i];
|
||||
kvm_ioctl(vcpufd, KVM_TRANSLATE, &kt);
|
||||
strcpy(guest_mem + (size_t)kt.physical_address,
|
||||
uhyve_envp[i]);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
err(1, "KVM: unhandled KVM_EXIT_IO at port 0x%x, direction %d\n", run->io.port, run->io.direction);
|
||||
break;
|
||||
|
@ -1510,10 +1592,18 @@ nextslot:
|
|||
no_checkpoint++;
|
||||
}
|
||||
|
||||
int uhyve_loop(void)
|
||||
int uhyve_loop(int argc, char **argv)
|
||||
{
|
||||
const char* hermit_check = getenv("HERMIT_CHECKPOINT");
|
||||
int ts = 0;
|
||||
int ts = 0, i = 0;
|
||||
|
||||
/* argv[0] is 'proxy', do not count it */
|
||||
uhyve_argc = argc-1;
|
||||
uhyve_argv = &argv[1];
|
||||
uhyve_envp = environ;
|
||||
while(uhyve_envp[i] != NULL)
|
||||
i++;
|
||||
uhyve_envc = i;
|
||||
|
||||
if (hermit_check)
|
||||
ts = atoi(hermit_check);
|
||||
|
|
|
@ -5,6 +5,7 @@ project(hermit_tests C CXX Fortran Go)
|
|||
|
||||
add_executable(hello hello.c)
|
||||
add_executable(jacobi jacobi.c)
|
||||
add_executable(argv_envp argv_envp.c)
|
||||
add_executable(hello++ hello++.cpp)
|
||||
add_executable(hellof hellof.f90)
|
||||
add_executable(pi pi.go)
|
||||
|
|
21
usr/tests/argv_envp.c
Normal file
21
usr/tests/argv_envp.c
Normal file
|
@ -0,0 +1,21 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern char **environ;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int i;
|
||||
|
||||
printf("argc: %d\n", argc);
|
||||
for(i=0; i<argc; i++) {
|
||||
printf(" argv[%d]: %s\n", i, argv[i]);
|
||||
}
|
||||
|
||||
printf("environ: %x\n", environ);
|
||||
i = 0;
|
||||
while(environ[i] != NULL)
|
||||
printf("%s\n", environ[i++]);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Reference in a new issue