[Midnightbsd-cvs] src [8471] trunk/sys: add two new options to the nfssvc(2) syscall that allow processes running as root to suspend and resume execution of nfsd

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sun Sep 18 18:25:22 EDT 2016


Revision: 8471
          http://svnweb.midnightbsd.org/src/?rev=8471
Author:   laffer1
Date:     2016-09-18 18:25:22 -0400 (Sun, 18 Sep 2016)
Log Message:
-----------
add two new options to the nfssvc(2) syscall that allow processes running as root to suspend and resume execution of nfsd

Modified Paths:
--------------
    trunk/sys/fs/nfsserver/nfs_nfsdkrpc.c
    trunk/sys/fs/nfsserver/nfs_nfsdport.c
    trunk/sys/nfs/nfs_nfssvc.c
    trunk/sys/nfs/nfssvc.h

Modified: trunk/sys/fs/nfsserver/nfs_nfsdkrpc.c
===================================================================
--- trunk/sys/fs/nfsserver/nfs_nfsdkrpc.c	2016-09-18 22:24:23 UTC (rev 8470)
+++ trunk/sys/fs/nfsserver/nfs_nfsdkrpc.c	2016-09-18 22:25:22 UTC (rev 8471)
@@ -45,6 +45,8 @@
 #include <security/mac/mac_framework.h>
 
 NFSDLOCKMUTEX;
+NFSV4ROOTLOCKMUTEX;
+struct nfsv4lock nfsd_suspend_lock;
 
 /*
  * Mapping of old NFS Version 2 RPC numbers to generic numbers.
@@ -221,9 +223,24 @@
 #ifdef MAC
 		mac_cred_associate_nfsd(nd.nd_cred);
 #endif
+		/*
+		 * Get a refcnt (shared lock) on nfsd_suspend_lock.
+		 * NFSSVC_SUSPENDNFSD will take an exclusive lock on
+		 * nfsd_suspend_lock to suspend these threads.
+		 * This must be done here, before the check of
+		 * nfsv4root exports by nfsvno_v4rootexport().
+		 */
+		NFSLOCKV4ROOTMUTEX();
+		nfsv4_getref(&nfsd_suspend_lock, NULL, NFSV4ROOTLOCKMUTEXPTR,
+		    NULL);
+		NFSUNLOCKV4ROOTMUTEX();
+
 		if ((nd.nd_flag & ND_NFSV4) != 0) {
 			nd.nd_repstat = nfsvno_v4rootexport(&nd);
 			if (nd.nd_repstat != 0) {
+				NFSLOCKV4ROOTMUTEX();
+				nfsv4_relref(&nfsd_suspend_lock);
+				NFSUNLOCKV4ROOTMUTEX();
 				svcerr_weakauth(rqst);
 				svc_freereq(rqst);
 				m_freem(nd.nd_mrep);
@@ -233,6 +250,9 @@
 
 		cacherep = nfs_proc(&nd, rqst->rq_xid, xprt->xp_socket,
 		    xprt->xp_sockref, &rp);
+		NFSLOCKV4ROOTMUTEX();
+		nfsv4_relref(&nfsd_suspend_lock);
+		NFSUNLOCKV4ROOTMUTEX();
 	} else {
 		NFSMGET(nd.nd_mreq);
 		nd.nd_mreq->m_len = 0;

Modified: trunk/sys/fs/nfsserver/nfs_nfsdport.c
===================================================================
--- trunk/sys/fs/nfsserver/nfs_nfsdport.c	2016-09-18 22:24:23 UTC (rev 8470)
+++ trunk/sys/fs/nfsserver/nfs_nfsdport.c	2016-09-18 22:25:22 UTC (rev 8471)
@@ -57,6 +57,7 @@
 extern struct nfsrv_stablefirst nfsrv_stablefirst;
 extern void (*nfsd_call_servertimer)(void);
 extern SVCPOOL	*nfsrvd_pool;
+extern struct nfsv4lock nfsd_suspend_lock;
 struct vfsoptlist nfsv4root_opt, nfsv4root_newopt;
 NFSDLOCKMUTEX;
 struct mtx nfs_cache_mutex;
@@ -3106,8 +3107,9 @@
 	struct nfsd_dumplocks *dumplocks;
 	struct nameidata nd;
 	vnode_t vp;
-	int error = EINVAL;
+	int error = EINVAL, igotlock;
 	struct proc *procp;
+	static int suspend_nfsd = 0;
 
 	if (uap->flag & NFSSVC_PUBLICFH) {
 		NFSBZERO((caddr_t)&nfs_pubfh.nfsrvfh_data,
@@ -3186,6 +3188,26 @@
 		nfsd_master_start = procp->p_stats->p_start;
 		nfsd_master_proc = procp;
 		PROC_UNLOCK(procp);
+	} else if ((uap->flag & NFSSVC_SUSPENDNFSD) != 0) {
+		NFSLOCKV4ROOTMUTEX();
+		if (suspend_nfsd == 0) {
+			/* Lock out all nfsd threads */
+			do {
+				igotlock = nfsv4_lock(&nfsd_suspend_lock, 1,
+				    NULL, NFSV4ROOTLOCKMUTEXPTR, NULL);
+			} while (igotlock == 0 && suspend_nfsd == 0);
+			suspend_nfsd = 1;
+		}
+		NFSUNLOCKV4ROOTMUTEX();
+		error = 0;
+	} else if ((uap->flag & NFSSVC_RESUMENFSD) != 0) {
+		NFSLOCKV4ROOTMUTEX();
+		if (suspend_nfsd != 0) {
+			nfsv4_unlock(&nfsd_suspend_lock, 0);
+			suspend_nfsd = 0;
+		}
+		NFSUNLOCKV4ROOTMUTEX();
+		error = 0;
 	}
 
 	NFSEXITCODE(error);

Modified: trunk/sys/nfs/nfs_nfssvc.c
===================================================================
--- trunk/sys/nfs/nfs_nfssvc.c	2016-09-18 22:24:23 UTC (rev 8470)
+++ trunk/sys/nfs/nfs_nfssvc.c	2016-09-18 22:25:22 UTC (rev 8471)
@@ -102,7 +102,8 @@
 	else if ((uap->flag & (NFSSVC_NFSDNFSD | NFSSVC_NFSDADDSOCK |
 	    NFSSVC_PUBLICFH | NFSSVC_V4ROOTEXPORT | NFSSVC_NOPUBLICFH |
 	    NFSSVC_STABLERESTART | NFSSVC_ADMINREVOKE |
-	    NFSSVC_DUMPCLIENTS | NFSSVC_DUMPLOCKS | NFSSVC_BACKUPSTABLE)) &&
+	    NFSSVC_DUMPCLIENTS | NFSSVC_DUMPLOCKS | NFSSVC_BACKUPSTABLE |
+	    NFSSVC_SUSPENDNFSD | NFSSVC_RESUMENFSD)) &&
 	    nfsd_call_nfsd != NULL)
 		error = (*nfsd_call_nfsd)(td, uap);
 	if (error == EINTR || error == ERESTART)

Modified: trunk/sys/nfs/nfssvc.h
===================================================================
--- trunk/sys/nfs/nfssvc.h	2016-09-18 22:24:23 UTC (rev 8470)
+++ trunk/sys/nfs/nfssvc.h	2016-09-18 22:25:22 UTC (rev 8471)
@@ -66,5 +66,7 @@
 #define	NFSSVC_BACKUPSTABLE	0x00800000
 #define	NFSSVC_ZEROCLTSTATS	0x01000000	/* modifier for GETSTATS */
 #define	NFSSVC_ZEROSRVSTATS	0x02000000	/* modifier for GETSTATS */
+#define	NFSSVC_SUSPENDNFSD	0x04000000
+#define	NFSSVC_RESUMENFSD	0x08000000
 
 #endif /* _NFS_NFSSVC_H */



More information about the Midnightbsd-cvs mailing list