[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