svn commit: r313735 - in head/sys: fs/nfsserver rpc

Andriy Gapon avg at FreeBSD.org
Tue Feb 14 17:49:10 UTC 2017


Author: avg
Date: Tue Feb 14 17:49:08 2017
New Revision: 313735
URL: https://svnweb.freebsd.org/changeset/base/313735

Log:
  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

Modified:
  head/sys/fs/nfsserver/nfs_nfsdkrpc.c
  head/sys/rpc/svc.c
  head/sys/rpc/svc.h

Modified: head/sys/fs/nfsserver/nfs_nfsdkrpc.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdkrpc.c	Tue Feb 14 17:44:30 2017	(r313734)
+++ head/sys/fs/nfsserver/nfs_nfsdkrpc.c	Tue Feb 14 17:49:08 2017	(r313735)
@@ -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();
 }
 

Modified: head/sys/rpc/svc.c
==============================================================================
--- head/sys/rpc/svc.c	Tue Feb 14 17:44:30 2017	(r313734)
+++ head/sys/rpc/svc.c	Tue Feb 14 17:49:08 2017	(r313735)
@@ -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 
 	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];
@@ -226,6 +240,30 @@ svcpool_destroy(SVCPOOL *pool)
 }
 
 /*
+ * 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
  */
 static int

Modified: head/sys/rpc/svc.h
==============================================================================
--- head/sys/rpc/svc.h	Tue Feb 14 17:44:30 2017	(r313734)
+++ head/sys/rpc/svc.h	Tue Feb 14 17:49:08 2017	(r313735)
@@ -729,6 +729,12 @@ extern SVCPOOL* svcpool_create(const cha
 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.
  */
 extern int svc_create(SVCPOOL *, void (*)(struct svc_req *, SVCXPRT *),


More information about the svn-src-head mailing list