Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys Fix dlopen()/dlclose()+RUMP_USE_CTOR to not leave dangli...
details: https://anonhg.NetBSD.org/src/rev/44048bf21534
branches: trunk
changeset: 343011:44048bf21534
user: pooka <pooka%NetBSD.org@localhost>
date: Mon Jan 18 16:46:08 2016 +0000
description:
Fix dlopen()/dlclose()+RUMP_USE_CTOR to not leave dangling pointers around.
diffstat:
sys/rump/librump/rumpkern/rump.c | 25 ++++++++++++++++++++++---
sys/rump/librump/rumpkern/rump_private.h | 8 +++++++-
sys/sys/module.h | 29 ++++++++++++++++++++++++-----
sys/sys/sysctl.h | 25 +++++++++++++++++++------
4 files changed, 72 insertions(+), 15 deletions(-)
diffs (199 lines):
diff -r 52093118849d -r 44048bf21534 sys/rump/librump/rumpkern/rump.c
--- a/sys/rump/librump/rumpkern/rump.c Mon Jan 18 15:53:38 2016 +0000
+++ b/sys/rump/librump/rumpkern/rump.c Mon Jan 18 16:46:08 2016 +0000
@@ -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 @@
{
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 @@
{
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 @@
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)
{
diff -r 52093118849d -r 44048bf21534 sys/rump/librump/rumpkern/rump_private.h
--- a/sys/rump/librump/rumpkern/rump_private.h Mon Jan 18 15:53:38 2016 +0000
+++ b/sys/rump/librump/rumpkern/rump_private.h Mon Jan 18 16:46:08 2016 +0000
@@ -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) \
{ \
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 @@
#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);
diff -r 52093118849d -r 44048bf21534 sys/sys/module.h
--- a/sys/sys/module.h Mon Jan 18 15:53:38 2016 +0000
+++ b/sys/sys/module.h Mon Jan 18 16:46:08 2016 +0000
@@ -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 @@
#ifdef _KERNEL
+#include <sys/kernel.h>
#include <sys/mutex.h>
#include <prop/proplib.h>
@@ -105,6 +106,12 @@
* 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 @@
};
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 */
diff -r 52093118849d -r 44048bf21534 sys/sys/sysctl.h
--- a/sys/sys/sysctl.h Mon Jan 18 15:53:38 2016 +0000
+++ b/sys/sys/sysctl.h Mon Jan 18 16:46:08 2016 +0000
@@ -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 @@
};
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 */
Home |
Main Index |
Thread Index |
Old Index