Module Name: src Committed By: pooka Date: Mon Jan 18 16:46:08 UTC 2016
Modified Files: src/sys/rump/librump/rumpkern: rump.c rump_private.h src/sys/sys: module.h sysctl.h Log Message: Fix dlopen()/dlclose()+RUMP_USE_CTOR to not leave dangling pointers around. To generate a diff of this commit: cvs rdiff -u -r1.325 -r1.326 src/sys/rump/librump/rumpkern/rump.c cvs rdiff -u -r1.92 -r1.93 src/sys/rump/librump/rumpkern/rump_private.h cvs rdiff -u -r1.39 -r1.40 src/sys/sys/module.h cvs rdiff -u -r1.217 -r1.218 src/sys/sys/sysctl.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/rump/librump/rumpkern/rump.c diff -u src/sys/rump/librump/rumpkern/rump.c:1.325 src/sys/rump/librump/rumpkern/rump.c:1.326 --- src/sys/rump/librump/rumpkern/rump.c:1.325 Mon Aug 31 07:38:48 2015 +++ src/sys/rump/librump/rumpkern/rump.c Mon Jan 18 16:46:08 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: rump.c,v 1.325 2015/08/31 07:38:48 ozaki-r Exp $ */ +/* $NetBSD: rump.c,v 1.326 2016/01/18 16:46:08 pooka Exp $ */ /* * Copyright (c) 2007-2011 Antti Kantee. All Rights Reserved. @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.325 2015/08/31 07:38:48 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.326 2016/01/18 16:46:08 pooka Exp $"); #include <sys/systm.h> #define ELFSIZE ARCH_ELFSIZE @@ -314,7 +314,8 @@ rump_init(void) { struct sysctl_setup_chain *ssc; - LIST_FOREACH(ssc, &sysctl_boot_chain, ssc_entries) { + while ((ssc = LIST_FIRST(&sysctl_boot_chain)) != NULL) { + LIST_REMOVE(ssc, ssc_entries); ssc->ssc_func(NULL); } } @@ -544,6 +545,10 @@ rump_component_load(const struct rump_co { struct rump_component *rc, *rc_iter; + /* time for rump component loading and unloading has passed */ + if (!cold) + return; + /* * XXX: this is ok since the "const" was removed from the * definition of RUMP_COMPONENT(). @@ -565,6 +570,20 @@ rump_component_load(const struct rump_co compcounter[rc->rc_type]++; } +void +rump_component_unload(struct rump_component *rc) +{ + + /* + * Checking for cold is enough because rump_init() both + * flips it and handles component loading. + */ + if (!cold) + return; + + LIST_REMOVE(rc, rc_entries); +} + int rump_component_count(enum rump_component_type type) { Index: src/sys/rump/librump/rumpkern/rump_private.h diff -u src/sys/rump/librump/rumpkern/rump_private.h:1.92 src/sys/rump/librump/rumpkern/rump_private.h:1.93 --- src/sys/rump/librump/rumpkern/rump_private.h:1.92 Wed Apr 22 17:38:33 2015 +++ src/sys/rump/librump/rumpkern/rump_private.h Mon Jan 18 16:46:08 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: rump_private.h,v 1.92 2015/04/22 17:38:33 pooka Exp $ */ +/* $NetBSD: rump_private.h,v 1.93 2016/01/18 16:46:08 pooka Exp $ */ /* * Copyright (c) 2007-2011 Antti Kantee. All Rights Reserved. @@ -90,6 +90,11 @@ static void rumpcomp_ctor##type(void) __ static void rumpcomp_ctor##type(void) \ { \ rump_component_load(&rumpcomp##type); \ +} \ +static void rumpcomp_dtor##type(void) __attribute__((destructor)); \ +static void rumpcomp_dtor##type(void) \ +{ \ + rump_component_unload(&rumpcomp##type); \ } #else /* RUMP_USE_CTOR */ @@ -130,6 +135,7 @@ struct rump_spctl { #define RUMP_SPVM2CTL(vm) (((struct rump_spctl *)vm)->spctl) void rump_component_load(const struct rump_component *); +void rump_component_unload(struct rump_component *); void rump_component_init(enum rump_component_type); int rump_component_count(enum rump_component_type); Index: src/sys/sys/module.h diff -u src/sys/sys/module.h:1.39 src/sys/sys/module.h:1.40 --- src/sys/sys/module.h:1.39 Wed Nov 4 04:28:58 2015 +++ src/sys/sys/module.h Mon Jan 18 16:46:08 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: module.h,v 1.39 2015/11/04 04:28:58 pgoyette Exp $ */ +/* $NetBSD: module.h,v 1.40 2016/01/18 16:46:08 pooka Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -65,6 +65,7 @@ typedef enum modcmd { #ifdef _KERNEL +#include <sys/kernel.h> #include <sys/mutex.h> #include <prop/proplib.h> @@ -105,6 +106,12 @@ typedef struct module { * Alternatively, in some environments rump kernels use * __attribute__((constructor)) due to link sets being * difficult (impossible?) to implement (e.g. GNU gold, OS X, etc.) + * If we're cold (read: rump_init() has not been called), we lob the + * module onto the list to be handled when rump_init() runs. + * nb. it's not possible to use in-kernel locking mechanisms here since + * the code runs before rump_init(). We solve the problem by decreeing + * that thou shalt not call dlopen()/dlclose() for rump kernel components + * from multiple threads before calling rump_init(). */ #ifdef RUMP_USE_CTOR @@ -114,14 +121,26 @@ struct modinfo_chain { }; LIST_HEAD(modinfo_boot_chain, modinfo_chain); #define _MODULE_REGISTER(name) \ +static struct modinfo_chain __CONCAT(mc,name) = { \ + .mc_info = &__CONCAT(name,_modinfo), \ +}; \ static void __CONCAT(modctor_,name)(void) __attribute__((__constructor__));\ static void __CONCAT(modctor_,name)(void) \ { \ - static struct modinfo_chain mc = { \ - .mc_info = &__CONCAT(name,_modinfo), \ - }; \ extern struct modinfo_boot_chain modinfo_boot_chain; \ - LIST_INSERT_HEAD(&modinfo_boot_chain, &mc, mc_entries); \ + if (cold) { \ + struct modinfo_chain *mc = &__CONCAT(mc,name); \ + LIST_INSERT_HEAD(&modinfo_boot_chain, mc, mc_entries); \ + } \ +} \ + \ +static void __CONCAT(moddtor_,name)(void) __attribute__((__destructor__));\ +static void __CONCAT(moddtor_,name)(void) \ +{ \ + struct modinfo_chain *mc = &__CONCAT(mc,name); \ + if (cold) { \ + LIST_REMOVE(mc, mc_entries); \ + } \ } #else /* RUMP_USE_CTOR */ Index: src/sys/sys/sysctl.h diff -u src/sys/sys/sysctl.h:1.217 src/sys/sys/sysctl.h:1.218 --- src/sys/sys/sysctl.h:1.217 Sat Sep 26 20:28:37 2015 +++ src/sys/sys/sysctl.h Mon Jan 18 16:46:08 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: sysctl.h,v 1.217 2015/09/26 20:28:37 christos Exp $ */ +/* $NetBSD: sysctl.h,v 1.218 2016/01/18 16:46:08 pooka Exp $ */ /* * Copyright (c) 1989, 1993 @@ -50,6 +50,8 @@ #include <sys/ucontext.h> #include <sys/mallocvar.h> #include <uvm/uvm_extern.h> + +#include <sys/kernel.h> #endif @@ -1154,14 +1156,25 @@ struct sysctl_setup_chain { }; LIST_HEAD(sysctl_boot_chain, sysctl_setup_chain); #define _SYSCTL_REGISTER(name) \ +static struct sysctl_setup_chain __CONCAT(ssc,name) = { \ + .ssc_func = name, \ +}; \ static void sysctlctor_##name(void) __attribute__((constructor)); \ static void sysctlctor_##name(void) \ { \ - static struct sysctl_setup_chain ssc = { \ - .ssc_func = name, \ - }; \ - extern struct sysctl_boot_chain sysctl_boot_chain; \ - LIST_INSERT_HEAD(&sysctl_boot_chain, &ssc, ssc_entries); \ + struct sysctl_setup_chain *ssc = &__CONCAT(ssc,name); \ + extern struct sysctl_boot_chain sysctl_boot_chain; \ + if (cold) { \ + LIST_INSERT_HEAD(&sysctl_boot_chain, ssc, ssc_entries); \ + } \ +} \ +static void sysctldtor_##name(void) __attribute__((destructor)); \ +static void sysctldtor_##name(void) \ +{ \ + struct sysctl_setup_chain *ssc = &__CONCAT(ssc,name); \ + if (cold) { \ + LIST_REMOVE(ssc, ssc_entries); \ + } \ } #else /* RUMP_USE_CTOR */