diff options
author | zec <zec@FreeBSD.org> | 2010-05-03 16:08:24 +0000 |
---|---|---|
committer | zec <zec@FreeBSD.org> | 2010-05-03 16:08:24 +0000 |
commit | e50916c7a291f469ef1a4e154080873a81efcbc0 (patch) | |
tree | 6c6841ee409fa1cbd9f26fdcba43cbb38c1561e8 /sys | |
parent | 425dc5ab94cdbb6f198795a09b2c4330721536c0 (diff) | |
download | FreeBSD-src-e50916c7a291f469ef1a4e154080873a81efcbc0.zip FreeBSD-src-e50916c7a291f469ef1a4e154080873a81efcbc0.tar.gz |
When destroying a vnet, shut down all netgraph nodes tied to that vnet
before proceeding with dismantling other protocol domains.
This change only affects options VIMAGE builds.
Reviewed by: julian, bz
MFC after: 3 days
Diffstat (limited to 'sys')
-rw-r--r-- | sys/netgraph/ng_base.c | 52 |
1 files changed, 33 insertions, 19 deletions
diff --git a/sys/netgraph/ng_base.c b/sys/netgraph/ng_base.c index fdfe878..2a93e58 100644 --- a/sys/netgraph/ng_base.c +++ b/sys/netgraph/ng_base.c @@ -3067,28 +3067,42 @@ ng_mod_event(module_t mod, int event, void *data) static void vnet_netgraph_uninit(const void *unused __unused) { -#if 0 - node_p node, last_killed = NULL; - - /* XXXRW: utterly bogus. */ - while ((node = LIST_FIRST(&V_ng_allnodes)) != NULL) { - if (node == last_killed) { - /* This should never happen */ - node->nd_flags |= NGF_REALLY_DIE; - printf("netgraph node %s needs NGF_REALLY_DIE\n", - node->nd_name); + node_p node = NULL, last_killed = NULL; + int i; + + do { + /* Find a node to kill */ + mtx_lock(&ng_namehash_mtx); + for (i = 0; i < NG_NAME_HASH_SIZE; i++) { + LIST_FOREACH(node, &V_ng_name_hash[i], nd_nodes) { + if (node != &ng_deadnode) { + NG_NODE_REF(node); + break; + } + } + if (node != NULL) + break; + } + mtx_unlock(&ng_namehash_mtx); + + /* Attempt to kill it only if it is a regular node */ + if (node != NULL) { + if (node == last_killed) { + /* This should never happen */ + printf("ng node %s needs" + "NGF_REALLY_DIE\n", node->nd_name); + if (node->nd_flags & NGF_REALLY_DIE) + panic("ng node %s won't die", + node->nd_name); + node->nd_flags |= NGF_REALLY_DIE; + } ng_rmnode(node, NULL, NULL, 0); - /* This must never happen */ - if (node == LIST_FIRST(&V_ng_allnodes)) - panic("netgraph node %s won't die", - node->nd_name); + NG_NODE_UNREF(node); + last_killed = node; } - ng_rmnode(node, NULL, NULL, 0); - last_killed = node; - } -#endif + } while (node != NULL); } -VNET_SYSUNINIT(vnet_netgraph_uninit, SI_SUB_NETGRAPH, SI_ORDER_ANY, +VNET_SYSUNINIT(vnet_netgraph_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY, vnet_netgraph_uninit, NULL); #endif /* VIMAGE */ |