add svcpool_close to handle killed nfsd threads

This patch adds a new function to the server krpc called
svcpool_close().  It is similar to svcpool_destroy(), but does not free
the data structures, so that the pool can be used again.

This function is then used instead of svcpool_destroy(),
svcpool_create() when the nfsd threads are killed.

PR:		204340
Reported by:	Panzura
Approved by:	rmacklem
Obtained from:	rmacklem
MFC after:	1 week
This commit is contained in:
Andriy Gapon 2017-02-14 17:49:08 +00:00
parent a3f89e36ec
commit 90f90687b3
3 changed files with 55 additions and 13 deletions

View File

@ -551,18 +551,16 @@ nfsrvd_init(int terminating)
nfsd_master_proc = NULL;
NFSD_UNLOCK();
nfsrv_freeallbackchannel_xprts();
svcpool_destroy(nfsrvd_pool);
nfsrvd_pool = NULL;
svcpool_close(nfsrvd_pool);
NFSD_LOCK();
} else {
NFSD_UNLOCK();
nfsrvd_pool = svcpool_create("nfsd",
SYSCTL_STATIC_CHILDREN(_vfs_nfsd));
nfsrvd_pool->sp_rcache = NULL;
nfsrvd_pool->sp_assign = fhanew_assign;
nfsrvd_pool->sp_done = fha_nd_complete;
NFSD_LOCK();
}
NFSD_UNLOCK();
nfsrvd_pool = svcpool_create("nfsd", SYSCTL_STATIC_CHILDREN(_vfs_nfsd));
nfsrvd_pool->sp_rcache = NULL;
nfsrvd_pool->sp_assign = fhanew_assign;
nfsrvd_pool->sp_done = fha_nd_complete;
NFSD_LOCK();
}

View File

@ -75,6 +75,7 @@ static void svc_new_thread(SVCGROUP *grp);
static void xprt_unregister_locked(SVCXPRT *xprt);
static void svc_change_space_used(SVCPOOL *pool, long delta);
static bool_t svc_request_space_available(SVCPOOL *pool);
static void svcpool_cleanup(SVCPOOL *pool);
/* *************** SVCXPRT related stuff **************** */
@ -174,8 +175,12 @@ svcpool_create(const char *name, struct sysctl_oid_list *sysctl_base)
return pool;
}
void
svcpool_destroy(SVCPOOL *pool)
/*
* Code common to svcpool_destroy() and svcpool_close(), which cleans up
* the pool data structures.
*/
static void
svcpool_cleanup(SVCPOOL *pool)
{
SVCGROUP *grp;
SVCXPRT *xprt, *nxprt;
@ -211,6 +216,15 @@ svcpool_destroy(SVCPOOL *pool)
mtx_lock(&pool->sp_lock);
}
mtx_unlock(&pool->sp_lock);
}
void
svcpool_destroy(SVCPOOL *pool)
{
SVCGROUP *grp;
int g;
svcpool_cleanup(pool);
for (g = 0; g < SVC_MAXGROUPS; g++) {
grp = &pool->sp_groups[g];
@ -225,6 +239,30 @@ svcpool_destroy(SVCPOOL *pool)
free(pool, M_RPC);
}
/*
* Similar to svcpool_destroy(), except that it does not destroy the actual
* data structures. As such, "pool" may be used again.
*/
void
svcpool_close(SVCPOOL *pool)
{
SVCGROUP *grp;
int g;
svcpool_cleanup(pool);
/* Now, initialize the pool's state for a fresh svc_run() call. */
mtx_lock(&pool->sp_lock);
pool->sp_state = SVCPOOL_INIT;
mtx_unlock(&pool->sp_lock);
for (g = 0; g < SVC_MAXGROUPS; g++) {
grp = &pool->sp_groups[g];
mtx_lock(&grp->sg_lock);
grp->sg_state = SVCPOOL_ACTIVE;
mtx_unlock(&grp->sg_lock);
}
}
/*
* Sysctl handler to get the present thread count on a pool
*/

View File

@ -728,6 +728,12 @@ extern SVCPOOL* svcpool_create(const char *name,
*/
extern void svcpool_destroy(SVCPOOL *pool);
/*
* Close a service pool. Similar to svcpool_destroy(), but it does not
* free the data structures. As such, the pool can be used again.
*/
extern void svcpool_close(SVCPOOL *pool);
/*
* Transport independent svc_create routine.
*/