From: Antti Kantee Date: Wed, 22 Apr 2015 11:19:09 +0000 (+0000) Subject: Sketch out new interfaces for bootstrap/running programs. X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=3a5aff88bd1f878ed87d496184752a179ae804b7;p=people%2Fliuw%2Frumprun.git Sketch out new interfaces for bootstrap/running programs. The system is "booted" using rumprun_boot(). The opposite of rumprun_boot() is rumprun_reboot() (logically?) Between rumprun_boot() and rumprun_reboot() individual applications may be launched with rumprun() (async) and waited for with rumprun_wait(). Of course, bits for supporting >1 program are still missing, but at least the sketch is there. --- diff --git a/include/rumprun-base/netbsd_initfini.h b/include/rumprun-base/netbsd_initfini.h deleted file mode 100644 index 56f8ae6..0000000 --- a/include/rumprun-base/netbsd_initfini.h +++ /dev/null @@ -1,33 +0,0 @@ -/*- - * Copyright (c) 2014 Antti Kantee. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _BMK_BASE_NETBSD_INITFINI_H_ -#define _BMK_BASE_NETBSD_INITFINI_H_ - -void _netbsd_init(void); -void __dead _netbsd_fini(void); -void rumprun_lwp_init(void); - -#endif /* _BMK_BASE_NETBSD_INITFINI_H_ */ diff --git a/include/rumprun-base/rumprun.h b/include/rumprun-base/rumprun.h new file mode 100644 index 0000000..7e17739 --- /dev/null +++ b/include/rumprun-base/rumprun.h @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2015 Antti Kantee. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _RUMPRUN_BASE_RUMPRUN_H_ +#define _RUMPRUN_BASE_RUMPRUN_H_ + +void rumprun_boot(void); + +void * rumprun(int (*)(int, char *[]), int, char *[]); +int rumprun_wait(void *); +void * rumprun_get_finished(void); + +void rumprun_reboot(void) __dead; + +#endif /* _RUMPRUN_BASE_RUMPRUN_H_ */ diff --git a/lib/librumprun_base/Makefile b/lib/librumprun_base/Makefile index 7b300a5..d4cde20 100644 --- a/lib/librumprun_base/Makefile +++ b/lib/librumprun_base/Makefile @@ -5,7 +5,8 @@ DPSRCS+= ${CONFIG_MK} LIB= rumprun_base LIBISPRIVATE= # defined -SRCS= malloc.c netbsd_initfini.c signals.c syscall_misc.c +SRCS= rumprun.c +SRCS+= malloc.c netbsd_initfini.c signals.c syscall_misc.c SRCS+= __errno.c _lwp.c libc_stubs.c CPPFLAGS+= -I${.CURDIR}/../../include diff --git a/lib/librumprun_base/_lwp.c b/lib/librumprun_base/_lwp.c index 62fe7c8..e83f9e2 100644 --- a/lib/librumprun_base/_lwp.c +++ b/lib/librumprun_base/_lwp.c @@ -42,12 +42,13 @@ #include #include -#include -#include - #include #include +#include + +#include "rumprun-private.h" + #if 0 #define DPRINTF(x) printf x #else diff --git a/lib/librumprun_base/netbsd_initfini.c b/lib/librumprun_base/netbsd_initfini.c index 055c018..40bc1d3 100644 --- a/lib/librumprun_base/netbsd_initfini.c +++ b/lib/librumprun_base/netbsd_initfini.c @@ -33,14 +33,12 @@ #include #include -#include -#include - #include -#include #include +#include "rumprun-private.h" + static char *the_env[1] = { NULL } ; extern void *environ; void _libc_init(void); @@ -79,41 +77,23 @@ runfini(void) } void -_netbsd_init(void) +_netbsd_userlevel_init(void) { thestrings.ps_argvstr = (void *)((char *)&myaux - 2); __ps_strings = &thestrings; pthread__stacksize = 2*bmk_stacksize; - rump_boot_setsigmodel(RUMP_SIGMODEL_IGNORE); - rump_init(); - environ = the_env; - rumprun_lwp_init(); runinit(); _libc_init(); /* XXX: we should probably use csu, but this is quicker for now */ __progname = "rumprun"; - -#ifdef RUMP_SYSPROXY - rump_init_server("tcp://0:12345"); -#endif - _rumprun_config(); - - /* - * give all threads a chance to run, and ensure that the main - * thread has gone through a context switch - */ - sched_yield(); } -void __dead -_netbsd_fini(void) +void +_netbsd_userlevel_fini(void) { - _rumprun_deconfig(); - runfini(); - rump_sys_reboot(0, 0); - bmk_platform_halt("reboot returned"); + runfini(); } diff --git a/lib/librumprun_base/rumprun-private.h b/lib/librumprun_base/rumprun-private.h new file mode 100644 index 0000000..c58b6f0 --- /dev/null +++ b/lib/librumprun_base/rumprun-private.h @@ -0,0 +1,34 @@ +/*- + * Copyright (c) 2014 Antti Kantee. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _RUMPRUN_BASE_RUMPRUN_PRIVATE_H_ +#define _RUMPRUN_BASE_RUMPRUN_PRIVATE_H_ + +void _netbsd_userlevel_init(void); +void _netbsd_userlevel_fini(void); + +void rumprun_lwp_init(void); + +#endif /* _RUMPRUN_BASE_RUMPRUN_PRIVATE_H_ */ diff --git a/lib/librumprun_base/rumprun.c b/lib/librumprun_base/rumprun.c new file mode 100644 index 0000000..adac39a --- /dev/null +++ b/lib/librumprun_base/rumprun.c @@ -0,0 +1,206 @@ +/*- + * Copyright (c) 2015 Antti Kantee. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include + +#include "rumprun-private.h" + +static pthread_mutex_t w_mtx; +static pthread_cond_t w_cv; + +void +rumprun_boot(void) +{ + + rump_boot_setsigmodel(RUMP_SIGMODEL_IGNORE); + rump_init(); + + /* + * XXX: _netbsd_userlevel_init() should technically be called + * in mainbouncer() per process. However, there's currently no way + * to run it per process, and besides we need a fully functional + * libc to run sysproxy and rumprun_config(), so we just call it + * here for the time being. + * + * Eventually, we of course want bootstrap process which is + * rumprun() internally. + */ + rumprun_lwp_init(); + _netbsd_userlevel_init(); + +#ifdef RUMP_SYSPROXY + rump_init_server("tcp://0:12345"); +#endif + _rumprun_config(); + + /* + * give all threads a chance to run, and ensure that the main + * thread has gone through a context switch + */ + sched_yield(); + + pthread_mutex_init(&w_mtx, NULL); + pthread_cond_init(&w_cv, NULL); +} + +/* + * XXX: we have to use pthreads as the main threads for rumprunners + * because otherwise libpthread goes haywire because it doesn't understand + * the concept of multiple main threads (which is sort of understandable ...) + */ +struct rumprunner { + int (*rr_mainfun)(int, char *[]); + int rr_argc; + char **rr_argv; + + pthread_t rr_mainthread; + + int rr_done; + + LIST_ENTRY(rumprunner) rr_entries; +}; +static LIST_HEAD(,rumprunner) rumprunners = LIST_HEAD_INITIALIZER(&rumprunners); +static int rumprun_done; + +static void * +mainbouncer(void *arg) +{ + struct rumprunner *rr = arg; + const char *progname = rr->rr_argv[0]; + int rv; + + rump_pub_lwproc_rfork(RUMP_RFFDG); + + fprintf(stderr,"\n=== calling \"%s\" main() ===\n\n", progname); + rv = rr->rr_mainfun(rr->rr_argc, rr->rr_argv); + fprintf(stderr,"\n=== main() of \"%s\" returned %d ===\n", + progname, rv); + + /* + * XXX: missing _netbsd_userlevel_fini(). See comment in + * rumprun_boot() + */ + + /* XXX: does not yet nuke any pthread that mainfun creates */ + rr->rr_done = 1; + + pthread_mutex_lock(&w_mtx); + rumprun_done++; + pthread_cond_broadcast(&w_cv); + pthread_mutex_unlock(&w_mtx); + + /* exit() calls rumprun_pub_lwproc_releaselwp() (via _exit()) */ + exit(rv); +} + +void * +rumprun(int (*mainfun)(int, char *[]), int argc, char *argv[]) +{ + struct rumprunner *rr; + static int called; + + if (called) + bmk_platform_halt(">1 rumprun() calls not implemented yet"); + called = 1; + + rr = malloc(sizeof(*rr)); + + /* XXX: should we deep copy argc? */ + rr->rr_mainfun = mainfun; + rr->rr_argc = argc; + rr->rr_argv = argv; + rr->rr_done = 0; + + if (pthread_create(&rr->rr_mainthread, NULL, mainbouncer, rr) != 0) { + fprintf(stderr, "rumprun: running %s failed\n", argv[0]); + free(rr); + return NULL; + } + LIST_INSERT_HEAD(&rumprunners, rr, rr_entries); + + return rr; +} + +int +rumprun_wait(void *cookie) +{ + struct rumprunner *rr = cookie; + void *retval; + + pthread_join(rr->rr_mainthread, &retval); + assert(rumprun_done > 0); + rumprun_done--; + + return (int)(intptr_t)retval; +} + +void * +rumprun_get_finished(void) +{ + struct rumprunner *rr; + + if (LIST_EMPTY(&rumprunners)) + return NULL; + + pthread_mutex_lock(&w_mtx); + while (rumprun_done == 0) { + pthread_cond_wait(&w_cv, &w_mtx); + } + LIST_FOREACH(rr, &rumprunners, rr_entries) { + if (rr->rr_done) + break; + } + pthread_mutex_unlock(&w_mtx); + assert(rr); + + return rr; +} + +void __dead +rumprun_reboot(void) +{ + + _rumprun_deconfig(); + _netbsd_userlevel_fini(); + rump_sys_reboot(0, 0); + + bmk_platform_halt("reboot returned"); +} diff --git a/lib/librumprun_base/syscall_misc.c b/lib/librumprun_base/syscall_misc.c index b7d5c5c..34f741e 100644 --- a/lib/librumprun_base/syscall_misc.c +++ b/lib/librumprun_base/syscall_misc.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -45,8 +46,9 @@ #include #include +#include -#include +#include #ifdef RUMPRUN_MMAP_DEBUG #define MMAP_PRINTF(x) printf x @@ -133,10 +135,9 @@ _exit(int eval) } else { printf("\n=== _exit(%d) called ===\n", eval); } - /* XXX: work around the console being slow to attach */ - sleep(1); - _netbsd_fini(); + rump_pub_lwproc_releaselwp(); + pthread_exit((void *)(uintptr_t)eval); } /* XXX: manual proto. plug into libc internals some other day */ diff --git a/platform/baremetal/init.c b/platform/baremetal/init.c index bd92c6f..0347e91 100644 --- a/platform/baremetal/init.c +++ b/platform/baremetal/init.c @@ -29,19 +29,18 @@ #include -#include +#include void bmk_mainthread(void *notused) { char *argv[] = {"bmk_main", 0}; - int rv; + void *cookie; - _netbsd_init(); + rumprun_boot(); - printf("=== calling main() ===\n\n"); - rv = main(1, argv); - printf("=== main() returned %d ===\n\n", rv); + cookie = rumprun(main, 1, argv); + rumprun_wait(cookie); - _netbsd_fini(); + rumprun_reboot(); } diff --git a/platform/xen/callmain.c b/platform/xen/callmain.c index c89543a..352e571 100644 --- a/platform/xen/callmain.c +++ b/platform/xen/callmain.c @@ -23,16 +23,12 @@ * SUCH DAMAGE. */ -#include -#include -#include -#include - +#include #include -#include +#include -#include +#include extern int main(int argc, char **argv); @@ -83,27 +79,28 @@ static void parseargs(void *cmdline, int *nargs, char **outarray) { } } -int __default_app_main(start_info_t *); -int +void __default_app_main(start_info_t *); +void __default_app_main(start_info_t *si) { char argv0[] = "rumprun-xen"; - int nargs, r; + int nargs; char **argv; - - _netbsd_init(); + void *cookie; parseargs(si->cmd_line, &nargs, 0); - argv = malloc(sizeof(*argv) * (nargs+3)); + argv = bmk_xmalloc(sizeof(*argv) * (nargs+3)); argv[0] = argv0; parseargs(si->cmd_line, &nargs, argv+1); argv[nargs+1] = 0; argv[nargs+2] = 0; - fprintf(stderr,"=== calling main() ===\n\n"); - r = main(nargs+1, argv); - fprintf(stderr,"\n=== main() returned %d ===\n", r); - _exit(r); + rumprun_boot(); + + cookie = rumprun(main, nargs+1, argv); + rumprun_wait(cookie); + + rumprun_reboot(); } __weak_alias(app_main,__default_app_main)