Page MenuHomeFreeBSD

D37956.diff
No OneTemporary

D37956.diff

diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -3322,6 +3322,10 @@
mtx_assert(&pr->pr_mtx, MA_NOTOWNED);
shm_remove_prison(pr);
(void)osd_jail_call(pr, PR_METHOD_REMOVE, NULL);
+#ifdef VIMAGE
+ if (pr->pr_vnet != pr->pr_parent->pr_vnet)
+ vnet_shutdown(pr->pr_vnet);
+#endif
}
/*
diff --git a/sys/net/vnet.h b/sys/net/vnet.h
--- a/sys/net/vnet.h
+++ b/sys/net/vnet.h
@@ -166,9 +166,10 @@
#define VNET_STOP (uintptr_t)&__stop_set_vnet
/*
- * Functions to allocate and destroy virtual network stacks.
+ * Functions to allocate, shutdown and destroy virtual network stacks.
*/
struct vnet *vnet_alloc(void);
+void vnet_shutdown(struct vnet *vnet);
void vnet_destroy(struct vnet *vnet);
/*
@@ -360,6 +361,20 @@
SYSUNINIT(vnet_uninit_ ## ident, subsystem, order, \
vnet_deregister_sysuninit, &ident ## _vnet_uninit)
+#define VNET_SHUTDOWN(ident, subsystem, order, func, arg) \
+ CTASSERT((subsystem) > SI_SUB_VNET && \
+ (subsystem) <= SI_SUB_VNET_DONE); \
+ static struct vnet_sysinit ident ## _vnet_shutdown = { \
+ subsystem, \
+ order, \
+ (sysinit_cfunc_t)(sysinit_nfunc_t)func, \
+ (arg) \
+ }; \
+ SYSINIT(vnet_shutdown_ ## ident, subsystem, order, \
+ vnet_register_shutdown, &ident ## _vnet_shutdown); \
+ SYSUNINIT(vnet_shutdown_ ## ident, subsystem, order, \
+ vnet_deregister_shutdown, &ident ## _vnet_shutdown)
+
/*
* Run per-vnet sysinits or sysuninits during vnet creation/destruction.
*/
@@ -367,11 +382,13 @@
void vnet_sysuninit(void);
/*
- * Interfaces for managing per-vnet constructors and destructors.
+ * Interfaces for managing per-vnet constructors, shutdown handlers and destructors.
*/
void vnet_register_sysinit(void *arg);
+void vnet_register_shutdown(void *arg);
void vnet_register_sysuninit(void *arg);
void vnet_deregister_sysinit(void *arg);
+void vnet_deregister_shutdown(void *arg);
void vnet_deregister_sysuninit(void *arg);
/*
@@ -449,7 +466,7 @@
SYSINIT(ident, subsystem, order, func, arg)
#define VNET_SYSUNINIT(ident, subsystem, order, func, arg) \
SYSUNINIT(ident, subsystem, order, func, arg)
-
+#define VNET_SHUTDOWN(ident, subsystem, order, func, arg)
/*
* Without VIMAGE revert to the default implementation.
*/
diff --git a/sys/net/vnet.c b/sys/net/vnet.c
--- a/sys/net/vnet.c
+++ b/sys/net/vnet.c
@@ -189,6 +189,8 @@
TAILQ_HEAD_INITIALIZER(vnet_constructors);
static TAILQ_HEAD(vnet_sysuninit_head, vnet_sysinit) vnet_destructors =
TAILQ_HEAD_INITIALIZER(vnet_destructors);
+static TAILQ_HEAD(vnet_shutdown_head, vnet_sysinit) vnet_shutdown_handlers =
+ TAILQ_HEAD_INITIALIZER(vnet_shutdown_handlers);
struct sx vnet_sysinit_sxlock;
@@ -215,6 +217,7 @@
"struct vnet *");
SDT_PROBE_DEFINE2(vnet, functions, vnet_alloc, return,
"int", "struct vnet *");
+// FIXME SDT_PROBE_DEFINE2 vnet_shutdown ?
SDT_PROBE_DEFINE2(vnet, functions, vnet_destroy, entry,
"int", "struct vnet *");
SDT_PROBE_DEFINE1(vnet, functions, vnet_destroy, return,
@@ -264,6 +267,27 @@
return (vnet);
}
+/*
+ * Shutdown a virtual network stack, prior to destroy.
+ */
+void
+vnet_shutdown(struct vnet *vnet)
+{
+ struct vnet_sysinit *vs;
+
+ /* Signal that VNET is being shutdown. */
+ vnet->vnet_shutdown = true;
+
+ CURVNET_SET_QUIET(vnet);
+ VNET_SYSINIT_RLOCK();
+ TAILQ_FOREACH_REVERSE(vs, &vnet_shutdown_handlers, vnet_shutdown_head,
+ link) {
+ vs->func(vs->arg);
+ }
+ VNET_SYSINIT_RUNLOCK();
+ CURVNET_RESTORE();
+}
+
/*
* Destroy a virtual network stack.
*/
@@ -279,9 +303,6 @@
LIST_REMOVE(vnet, vnet_le);
VNET_LIST_WUNLOCK();
- /* Signal that VNET is being shutdown. */
- vnet->vnet_shutdown = true;
-
CURVNET_SET_QUIET(vnet);
sx_xlock(&ifnet_detach_sxlock);
vnet_sysuninit();
@@ -520,6 +541,52 @@
VNET_SYSINIT_WUNLOCK();
}
+void
+vnet_register_shutdown(void *arg)
+{
+ struct vnet_sysinit *vs, *vs2;
+
+ vs = arg;
+
+ /* Add the shutdown handler to the global list of vnet shutdown handlers. */
+ VNET_SYSINIT_WLOCK();
+ TAILQ_FOREACH(vs2, &vnet_shutdown_handlers, link) {
+ if (vs2->subsystem > vs->subsystem)
+ break;
+ if (vs2->subsystem == vs->subsystem && vs2->order > vs->order)
+ break;
+ }
+ if (vs2 != NULL)
+ TAILQ_INSERT_BEFORE(vs2, vs, link);
+ else
+ TAILQ_INSERT_TAIL(&vnet_shutdown_handlers, vs, link);
+ VNET_SYSINIT_WUNLOCK();
+}
+
+void
+vnet_deregister_shutdown(void *arg)
+{
+ struct vnet_sysinit *vs;
+ struct vnet *vnet;
+
+ vs = arg;
+
+ /*
+ * Invoke the shutdown handler on all the existing vnets when it is
+ * deregistered.
+ */
+ VNET_SYSINIT_WLOCK();
+ VNET_FOREACH(vnet) {
+ CURVNET_SET_QUIET(vnet);
+ vs->func(vs->arg);
+ CURVNET_RESTORE();
+ }
+
+ /* Remove the destructor from the global list of vnet destructors. */
+ TAILQ_REMOVE(&vnet_shutdown_handlers, vs, link);
+ VNET_SYSINIT_WUNLOCK();
+}
+
void
vnet_register_sysuninit(void *arg)
{

File Metadata

Mime Type
text/plain
Expires
Fri, Aug 28, 9:13 PM (18 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37482917
Default Alt Text
D37956.diff (4 KB)

Event Timeline