Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F108595546
D37519.id113805.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
92 KB
Referenced Files
None
Subscribers
None
D37519.id113805.diff
View Options
diff --git a/sys/fs/nfs/nfs_commonport.c.vnetmnt b/sys/fs/nfs/nfs_commonport.c
--- a/sys/fs/nfs/nfs_commonport.c.vnetmnt
+++ b/sys/fs/nfs/nfs_commonport.c
@@ -61,7 +61,6 @@
extern void (*nfsd_call_recall)(struct vnode *, int, struct ucred *,
struct thread *);
extern int nfsrv_useacl;
-struct mount nfsv4root_mnt;
int newnfs_numnfsd = 0;
struct nfsstatsv1 nfsstatsv1;
int nfs_numnfscbd = 0;
@@ -76,6 +75,8 @@
vop_reclaim_t *nfs_reclaim_p = NULL;
uint32_t nfs_srvmaxio = NFS_SRVMAXIO;
+NFSDSTATSDEFINE(nfsstatsv1);
+
int nfs_pnfsio(task_fn_t *, void *);
static int nfs_realign_test;
@@ -447,8 +448,13 @@
struct {
int vers; /* Just the first field of nfsstats. */
} nfsstatver;
+ struct nfsstatsv1 *outstats;
if (uap->flag & NFSSVC_IDNAME) {
+ if (jailed(p->td_ucred)) {
+ error = EPERM;
+ goto out;
+ }
if ((uap->flag & NFSSVC_NEWSTRUCT) != 0)
error = copyin(uap->argp, &nid, sizeof(nid));
else {
@@ -470,90 +476,96 @@
error = nfssvc_idname(&nid);
goto out;
} else if (uap->flag & NFSSVC_GETSTATS) {
+#ifdef NFSD_VIMAGE
+ outstats = malloc(sizeof(*outstats), M_TEMP, M_WAITOK | M_ZERO);
+#else
+ outstats = &nfsstatsv1;
+#endif
+ nfsd_copy_vnetstats();
if ((uap->flag & NFSSVC_NEWSTRUCT) == 0) {
/* Copy fields to the old ext_nfsstat structure. */
oldnfsstats.attrcache_hits =
- nfsstatsv1.attrcache_hits;
+ outstats->attrcache_hits;
oldnfsstats.attrcache_misses =
- nfsstatsv1.attrcache_misses;
+ outstats->attrcache_misses;
oldnfsstats.lookupcache_hits =
- nfsstatsv1.lookupcache_hits;
+ outstats->lookupcache_hits;
oldnfsstats.lookupcache_misses =
- nfsstatsv1.lookupcache_misses;
+ outstats->lookupcache_misses;
oldnfsstats.direofcache_hits =
- nfsstatsv1.direofcache_hits;
+ outstats->direofcache_hits;
oldnfsstats.direofcache_misses =
- nfsstatsv1.direofcache_misses;
+ outstats->direofcache_misses;
oldnfsstats.accesscache_hits =
- nfsstatsv1.accesscache_hits;
+ outstats->accesscache_hits;
oldnfsstats.accesscache_misses =
- nfsstatsv1.accesscache_misses;
+ outstats->accesscache_misses;
oldnfsstats.biocache_reads =
- nfsstatsv1.biocache_reads;
+ outstats->biocache_reads;
oldnfsstats.read_bios =
- nfsstatsv1.read_bios;
+ outstats->read_bios;
oldnfsstats.read_physios =
- nfsstatsv1.read_physios;
+ outstats->read_physios;
oldnfsstats.biocache_writes =
- nfsstatsv1.biocache_writes;
+ outstats->biocache_writes;
oldnfsstats.write_bios =
- nfsstatsv1.write_bios;
+ outstats->write_bios;
oldnfsstats.write_physios =
- nfsstatsv1.write_physios;
+ outstats->write_physios;
oldnfsstats.biocache_readlinks =
- nfsstatsv1.biocache_readlinks;
+ outstats->biocache_readlinks;
oldnfsstats.readlink_bios =
- nfsstatsv1.readlink_bios;
+ outstats->readlink_bios;
oldnfsstats.biocache_readdirs =
- nfsstatsv1.biocache_readdirs;
+ outstats->biocache_readdirs;
oldnfsstats.readdir_bios =
- nfsstatsv1.readdir_bios;
+ outstats->readdir_bios;
for (i = 0; i < NFSV4_NPROCS; i++)
- oldnfsstats.rpccnt[i] = nfsstatsv1.rpccnt[i];
- oldnfsstats.rpcretries = nfsstatsv1.rpcretries;
+ oldnfsstats.rpccnt[i] = outstats->rpccnt[i];
+ oldnfsstats.rpcretries = outstats->rpcretries;
for (i = 0; i < NFSV4OP_NOPS; i++)
oldnfsstats.srvrpccnt[i] =
- nfsstatsv1.srvrpccnt[i];
+ outstats->srvrpccnt[i];
for (i = NFSV42_NOPS, j = NFSV4OP_NOPS;
i < NFSV42_NOPS + NFSV4OP_FAKENOPS; i++, j++)
oldnfsstats.srvrpccnt[j] =
- nfsstatsv1.srvrpccnt[i];
+ outstats->srvrpccnt[i];
oldnfsstats.reserved_0 = 0;
oldnfsstats.reserved_1 = 0;
- oldnfsstats.rpcrequests = nfsstatsv1.rpcrequests;
- oldnfsstats.rpctimeouts = nfsstatsv1.rpctimeouts;
- oldnfsstats.rpcunexpected = nfsstatsv1.rpcunexpected;
- oldnfsstats.rpcinvalid = nfsstatsv1.rpcinvalid;
+ oldnfsstats.rpcrequests = outstats->rpcrequests;
+ oldnfsstats.rpctimeouts = outstats->rpctimeouts;
+ oldnfsstats.rpcunexpected = outstats->rpcunexpected;
+ oldnfsstats.rpcinvalid = outstats->rpcinvalid;
oldnfsstats.srvcache_inproghits =
- nfsstatsv1.srvcache_inproghits;
+ outstats->srvcache_inproghits;
oldnfsstats.reserved_2 = 0;
oldnfsstats.srvcache_nonidemdonehits =
- nfsstatsv1.srvcache_nonidemdonehits;
+ outstats->srvcache_nonidemdonehits;
oldnfsstats.srvcache_misses =
- nfsstatsv1.srvcache_misses;
+ outstats->srvcache_misses;
oldnfsstats.srvcache_tcppeak =
- nfsstatsv1.srvcache_tcppeak;
- oldnfsstats.srvcache_size = nfsstatsv1.srvcache_size;
- oldnfsstats.srvclients = nfsstatsv1.srvclients;
- oldnfsstats.srvopenowners = nfsstatsv1.srvopenowners;
- oldnfsstats.srvopens = nfsstatsv1.srvopens;
- oldnfsstats.srvlockowners = nfsstatsv1.srvlockowners;
- oldnfsstats.srvlocks = nfsstatsv1.srvlocks;
- oldnfsstats.srvdelegates = nfsstatsv1.srvdelegates;
+ outstats->srvcache_tcppeak;
+ oldnfsstats.srvcache_size = outstats->srvcache_size;
+ oldnfsstats.srvclients = outstats->srvclients;
+ oldnfsstats.srvopenowners = outstats->srvopenowners;
+ oldnfsstats.srvopens = outstats->srvopens;
+ oldnfsstats.srvlockowners = outstats->srvlockowners;
+ oldnfsstats.srvlocks = outstats->srvlocks;
+ oldnfsstats.srvdelegates = outstats->srvdelegates;
for (i = 0; i < NFSV4OP_CBNOPS; i++)
oldnfsstats.cbrpccnt[i] =
- nfsstatsv1.cbrpccnt[i];
- oldnfsstats.clopenowners = nfsstatsv1.clopenowners;
- oldnfsstats.clopens = nfsstatsv1.clopens;
- oldnfsstats.cllockowners = nfsstatsv1.cllockowners;
- oldnfsstats.cllocks = nfsstatsv1.cllocks;
- oldnfsstats.cldelegates = nfsstatsv1.cldelegates;
+ outstats->cbrpccnt[i];
+ oldnfsstats.clopenowners = outstats->clopenowners;
+ oldnfsstats.clopens = outstats->clopens;
+ oldnfsstats.cllockowners = outstats->cllockowners;
+ oldnfsstats.cllocks = outstats->cllocks;
+ oldnfsstats.cldelegates = outstats->cldelegates;
oldnfsstats.cllocalopenowners =
- nfsstatsv1.cllocalopenowners;
- oldnfsstats.cllocalopens = nfsstatsv1.cllocalopens;
+ outstats->cllocalopenowners;
+ oldnfsstats.cllocalopens = outstats->cllocalopens;
oldnfsstats.cllocallockowners =
- nfsstatsv1.cllocallockowners;
- oldnfsstats.cllocallocks = nfsstatsv1.cllocallocks;
+ outstats->cllocallockowners;
+ oldnfsstats.cllocallocks = outstats->cllocallocks;
error = copyout(&oldnfsstats, uap->argp,
sizeof (oldnfsstats));
} else {
@@ -561,141 +573,142 @@
sizeof(nfsstatver));
if (error == 0) {
if (nfsstatver.vers == NFSSTATS_OV1) {
- /* Copy nfsstatsv1 to nfsstatsov1. */
+ /* Copy outstats to nfsstatsov1. */
nfsstatsov1.attrcache_hits =
- nfsstatsv1.attrcache_hits;
+ outstats->attrcache_hits;
nfsstatsov1.attrcache_misses =
- nfsstatsv1.attrcache_misses;
+ outstats->attrcache_misses;
nfsstatsov1.lookupcache_hits =
- nfsstatsv1.lookupcache_hits;
+ outstats->lookupcache_hits;
nfsstatsov1.lookupcache_misses =
- nfsstatsv1.lookupcache_misses;
+ outstats->lookupcache_misses;
nfsstatsov1.direofcache_hits =
- nfsstatsv1.direofcache_hits;
+ outstats->direofcache_hits;
nfsstatsov1.direofcache_misses =
- nfsstatsv1.direofcache_misses;
+ outstats->direofcache_misses;
nfsstatsov1.accesscache_hits =
- nfsstatsv1.accesscache_hits;
+ outstats->accesscache_hits;
nfsstatsov1.accesscache_misses =
- nfsstatsv1.accesscache_misses;
+ outstats->accesscache_misses;
nfsstatsov1.biocache_reads =
- nfsstatsv1.biocache_reads;
+ outstats->biocache_reads;
nfsstatsov1.read_bios =
- nfsstatsv1.read_bios;
+ outstats->read_bios;
nfsstatsov1.read_physios =
- nfsstatsv1.read_physios;
+ outstats->read_physios;
nfsstatsov1.biocache_writes =
- nfsstatsv1.biocache_writes;
+ outstats->biocache_writes;
nfsstatsov1.write_bios =
- nfsstatsv1.write_bios;
+ outstats->write_bios;
nfsstatsov1.write_physios =
- nfsstatsv1.write_physios;
+ outstats->write_physios;
nfsstatsov1.biocache_readlinks =
- nfsstatsv1.biocache_readlinks;
+ outstats->biocache_readlinks;
nfsstatsov1.readlink_bios =
- nfsstatsv1.readlink_bios;
+ outstats->readlink_bios;
nfsstatsov1.biocache_readdirs =
- nfsstatsv1.biocache_readdirs;
+ outstats->biocache_readdirs;
nfsstatsov1.readdir_bios =
- nfsstatsv1.readdir_bios;
+ outstats->readdir_bios;
for (i = 0; i < NFSV42_OLDNPROCS; i++)
nfsstatsov1.rpccnt[i] =
- nfsstatsv1.rpccnt[i];
+ outstats->rpccnt[i];
nfsstatsov1.rpcretries =
- nfsstatsv1.rpcretries;
+ outstats->rpcretries;
for (i = 0; i < NFSV42_PURENOPS; i++)
nfsstatsov1.srvrpccnt[i] =
- nfsstatsv1.srvrpccnt[i];
+ outstats->srvrpccnt[i];
for (i = NFSV42_NOPS,
j = NFSV42_PURENOPS;
i < NFSV42_NOPS + NFSV4OP_FAKENOPS;
i++, j++)
nfsstatsov1.srvrpccnt[j] =
- nfsstatsv1.srvrpccnt[i];
+ outstats->srvrpccnt[i];
nfsstatsov1.reserved_0 = 0;
nfsstatsov1.reserved_1 = 0;
nfsstatsov1.rpcrequests =
- nfsstatsv1.rpcrequests;
+ outstats->rpcrequests;
nfsstatsov1.rpctimeouts =
- nfsstatsv1.rpctimeouts;
+ outstats->rpctimeouts;
nfsstatsov1.rpcunexpected =
- nfsstatsv1.rpcunexpected;
+ outstats->rpcunexpected;
nfsstatsov1.rpcinvalid =
- nfsstatsv1.rpcinvalid;
+ outstats->rpcinvalid;
nfsstatsov1.srvcache_inproghits =
- nfsstatsv1.srvcache_inproghits;
+ outstats->srvcache_inproghits;
nfsstatsov1.reserved_2 = 0;
nfsstatsov1.srvcache_nonidemdonehits =
- nfsstatsv1.srvcache_nonidemdonehits;
+ outstats->srvcache_nonidemdonehits;
nfsstatsov1.srvcache_misses =
- nfsstatsv1.srvcache_misses;
+ outstats->srvcache_misses;
nfsstatsov1.srvcache_tcppeak =
- nfsstatsv1.srvcache_tcppeak;
+ outstats->srvcache_tcppeak;
nfsstatsov1.srvcache_size =
- nfsstatsv1.srvcache_size;
+ outstats->srvcache_size;
nfsstatsov1.srvclients =
- nfsstatsv1.srvclients;
+ outstats->srvclients;
nfsstatsov1.srvopenowners =
- nfsstatsv1.srvopenowners;
+ outstats->srvopenowners;
nfsstatsov1.srvopens =
- nfsstatsv1.srvopens;
+ outstats->srvopens;
nfsstatsov1.srvlockowners =
- nfsstatsv1.srvlockowners;
+ outstats->srvlockowners;
nfsstatsov1.srvlocks =
- nfsstatsv1.srvlocks;
+ outstats->srvlocks;
nfsstatsov1.srvdelegates =
- nfsstatsv1.srvdelegates;
+ outstats->srvdelegates;
for (i = 0; i < NFSV42_CBNOPS; i++)
nfsstatsov1.cbrpccnt[i] =
- nfsstatsv1.cbrpccnt[i];
+ outstats->cbrpccnt[i];
nfsstatsov1.clopenowners =
- nfsstatsv1.clopenowners;
+ outstats->clopenowners;
nfsstatsov1.clopens =
- nfsstatsv1.clopens;
+ outstats->clopens;
nfsstatsov1.cllockowners =
- nfsstatsv1.cllockowners;
+ outstats->cllockowners;
nfsstatsov1.cllocks =
- nfsstatsv1.cllocks;
+ outstats->cllocks;
nfsstatsov1.cldelegates =
- nfsstatsv1.cldelegates;
+ outstats->cldelegates;
nfsstatsov1.cllocalopenowners =
- nfsstatsv1.cllocalopenowners;
+ outstats->cllocalopenowners;
nfsstatsov1.cllocalopens =
- nfsstatsv1.cllocalopens;
+ outstats->cllocalopens;
nfsstatsov1.cllocallockowners =
- nfsstatsv1.cllocallockowners;
+ outstats->cllocallockowners;
nfsstatsov1.cllocallocks =
- nfsstatsv1.cllocallocks;
+ outstats->cllocallocks;
nfsstatsov1.srvstartcnt =
- nfsstatsv1.srvstartcnt;
+ outstats->srvstartcnt;
nfsstatsov1.srvdonecnt =
- nfsstatsv1.srvdonecnt;
+ outstats->srvdonecnt;
for (i = NFSV42_NOPS,
j = NFSV42_PURENOPS;
i < NFSV42_NOPS + NFSV4OP_FAKENOPS;
i++, j++) {
nfsstatsov1.srvbytes[j] =
- nfsstatsv1.srvbytes[i];
+ outstats->srvbytes[i];
nfsstatsov1.srvops[j] =
- nfsstatsv1.srvops[i];
+ outstats->srvops[i];
nfsstatsov1.srvduration[j] =
- nfsstatsv1.srvduration[i];
+ outstats->srvduration[i];
}
nfsstatsov1.busyfrom =
- nfsstatsv1.busyfrom;
+ outstats->busyfrom;
nfsstatsov1.busyfrom =
- nfsstatsv1.busyfrom;
+ outstats->busyfrom;
error = copyout(&nfsstatsov1, uap->argp,
sizeof(nfsstatsov1));
} else if (nfsstatver.vers != NFSSTATS_V1)
error = EPERM;
else
- error = copyout(&nfsstatsv1, uap->argp,
+ error = copyout(outstats, uap->argp,
sizeof(nfsstatsv1));
}
}
if (error == 0) {
if ((uap->flag & NFSSVC_ZEROCLTSTATS) != 0) {
+ nfsd_zero_vnetstats();
nfsstatsv1.attrcache_hits = 0;
nfsstatsv1.attrcache_misses = 0;
nfsstatsv1.lookupcache_hits = 0;
@@ -733,11 +746,18 @@
sizeof(nfsstatsv1.cbrpccnt));
}
}
+#ifdef NFSD_VIMAGE
+ free(outstats, M_TEMP);
+#endif
goto out;
} else if (uap->flag & NFSSVC_NFSUSERDPORT) {
u_short sockport;
struct nfsuserd_args nargs;
+ if (jailed(p->td_ucred)) {
+ error = EPERM;
+ goto out;
+ }
if ((uap->flag & NFSSVC_NEWSTRUCT) == 0) {
error = copyin(uap->argp, (caddr_t)&sockport,
sizeof (u_short));
@@ -755,6 +775,10 @@
if (!error)
error = nfsrv_nfsuserdport(&nargs, p);
} else if (uap->flag & NFSSVC_NFSUSERDDELPORT) {
+ if (jailed(p->td_ucred)) {
+ error = EPERM;
+ goto out;
+ }
nfsrv_nfsuserddelport();
error = 0;
}
diff --git a/sys/fs/nfs/nfs_commonsubs.c.vnet b/sys/fs/nfs/nfs_commonsubs.c
--- a/sys/fs/nfs/nfs_commonsubs.c.vnet
+++ b/sys/fs/nfs/nfs_commonsubs.c
@@ -3931,7 +3931,7 @@
cr->cr_uid = cr->cr_ruid = cr->cr_svuid = nidp->nid_uid;
crsetgroups(cr, nidp->nid_ngroup, grps);
cr->cr_rgid = cr->cr_svgid = cr->cr_groups[0];
- cr->cr_prison = &prison0;
+ cr->cr_prison = curthread->td_ucred->cr_prison;
prison_hold(cr->cr_prison);
#ifdef MAC
mac_cred_associate_nfsd(cr);
diff --git a/sys/fs/nfs/nfsdport.h.vnetdcl b/sys/fs/nfs/nfsdport.h
--- a/sys/fs/nfs/nfsdport.h.vnetdcl
+++ b/sys/fs/nfs/nfsdport.h
@@ -92,7 +92,7 @@
bcmp(&(f1)->fh_fid, &(f2)->fh_fid, sizeof(struct fid)) == 0)
#define NFSLOCKHASH(f) \
- (&nfslockhash[nfsrv_hashfh(f) % nfsrv_lockhashsize])
+ (&VNET(nfslockhash)[nfsrv_hashfh(f) % nfsrv_lockhashsize])
#define NFSFPVNODE(f) ((f)->f_vnode)
#define NFSFPCRED(f) ((f)->f_cred)
diff --git a/sys/fs/nfs/nfsport.h.vnetstats b/sys/fs/nfs/nfsport.h
--- a/sys/fs/nfs/nfsport.h.vnetstats
+++ b/sys/fs/nfs/nfsport.h
@@ -181,6 +181,116 @@
*/
#define NFSMUTEX_T struct mtx
+/* Macros for NFSD_VIMAGE. */
+#define NFSD_VIMAGE 1 /* For now, until it is a build option. */
+#ifdef NFSD_VIMAGE
+#define NFSDSTATS(s) VNET(nfsstatsv1_vnet)
+#define NFSDSTATSDECLARE(s) VNET_DECLARE(struct nfsstatsv1_vnet, nfsstatsv1_vnet)
+#define NFSDSTATSDEFINE(s) VNET_DEFINE(struct nfsstatsv1_vnet, nfsstatsv1_vnet)
+#define nfsd_copy_vnetstats() do { \
+ int iii; \
+ NFSBCOPY(&nfsstatsv1, outstats, sizeof(nfsstatsv1)); \
+ for (iii = 0; iii < NFSV42_NOPS + NFSV4OP_FAKENOPS; iii++) { \
+ outstats->srvrpccnt[iii] = VNET(nfsstatsv1_vnet).srvrpccnt[iii]; \
+ outstats->srvbytes[iii] = VNET(nfsstatsv1_vnet).srvbytes[iii]; \
+ outstats->srvops[iii] = VNET(nfsstatsv1_vnet).srvops[iii]; \
+ outstats->srvduration[iii] = VNET(nfsstatsv1_vnet).srvduration[iii]; \
+ } \
+ outstats->srvlayouts = VNET(nfsstatsv1_vnet).srvlayouts; \
+ outstats->srvcache_inproghits = VNET(nfsstatsv1_vnet).srvcache_inproghits; \
+ outstats->srvcache_nonidemdonehits = VNET(nfsstatsv1_vnet).srvcache_nonidemdonehits; \
+ outstats->srvcache_misses = VNET(nfsstatsv1_vnet).srvcache_misses; \
+ outstats->srvcache_tcppeak = VNET(nfsstatsv1_vnet).srvcache_tcppeak; \
+ outstats->srvcache_size = VNET(nfsstatsv1_vnet).srvcache_size; \
+ outstats->srvclients = VNET(nfsstatsv1_vnet).srvclients; \
+ outstats->srvopenowners = VNET(nfsstatsv1_vnet).srvopenowners; \
+ outstats->srvopens = VNET(nfsstatsv1_vnet).srvopens; \
+ outstats->srvlockowners = VNET(nfsstatsv1_vnet).srvlockowners; \
+ outstats->srvlocks = VNET(nfsstatsv1_vnet).srvlocks; \
+ outstats->srvdelegates = VNET(nfsstatsv1_vnet).srvdelegates; \
+ outstats->srvstartcnt = VNET(nfsstatsv1_vnet).srvstartcnt; \
+ outstats->srvdonecnt = VNET(nfsstatsv1_vnet).srvdonecnt; \
+ outstats->busyfrom = VNET(nfsstatsv1_vnet).busyfrom; \
+ outstats->busytime = VNET(nfsstatsv1_vnet).busytime; \
+ } while (0)
+#define nfsd_zero_vnetstats() do { \
+ int iii; \
+ for (iii = 0; iii < NFSV42_NOPS + NFSV4OP_FAKENOPS; iii++) { \
+ VNET(nfsstatsv1_vnet).srvrpccnt[iii] = 0; \
+ VNET(nfsstatsv1_vnet).srvbytes[iii] = 0; \
+ VNET(nfsstatsv1_vnet).srvops[iii] = 0; \
+ NFSBZERO(&VNET(nfsstatsv1_vnet).srvduration[iii], sizeof(struct bintime)); \
+ } \
+ VNET(nfsstatsv1_vnet).srvlayouts = 0; \
+ VNET(nfsstatsv1_vnet).srvcache_inproghits = 0; \
+ VNET(nfsstatsv1_vnet).srvcache_nonidemdonehits = 0; \
+ VNET(nfsstatsv1_vnet).srvcache_misses = 0; \
+ VNET(nfsstatsv1_vnet).srvcache_tcppeak = 0; \
+ VNET(nfsstatsv1_vnet).srvcache_size = 0; \
+ VNET(nfsstatsv1_vnet).srvclients = 0; \
+ VNET(nfsstatsv1_vnet).srvopenowners = 0; \
+ VNET(nfsstatsv1_vnet).srvopens = 0; \
+ VNET(nfsstatsv1_vnet).srvlockowners = 0; \
+ VNET(nfsstatsv1_vnet).srvlocks = 0; \
+ VNET(nfsstatsv1_vnet).srvdelegates = 0; \
+ VNET(nfsstatsv1_vnet).srvstartcnt = 0; \
+ VNET(nfsstatsv1_vnet).srvdonecnt = 0; \
+ NFSBZERO(&VNET(nfsstatsv1_vnet).busyfrom, sizeof(struct bintime)); \
+ NFSBZERO(&VNET(nfsstatsv1_vnet).busytime, sizeof(struct bintime)); \
+ } while (0)
+#else /* !NFSD_VIMAGE */
+#define NFSDSTATS(s) s
+#define NFSDSTATSDECLARE(s) extern struct s s
+#define NFSDSTATSDEFINE(s)
+#define nfsd_copy_vnetstats()
+#define nfsd_zero_vnetstats()
+
+#ifdef VIMAGE
+/* Disable vnet. Mostly cribbed from vnet.h. */
+#undef CURVNET_SET
+#undef CURVNET_RESTORE
+#define CURVNET_SET(arg)
+#define CURVNET_RESTORE()
+
+#undef IS_DEFAULT_VNET
+#undef CRED_TO_VNET
+#undef TD_TO_VNET
+#define IS_DEFAULT_VNET(arg) 1
+#define CRED_TO_VNET(cr) NULL
+#define TD_TO_VNET(td) NULL
+
+/*
+ * Versions of the VNET macros that compile to normal global variables and
+ * standard sysctl definitions.
+ */
+#undef VNET_NAME
+#undef VNET_DECLARE
+#undef VNET_DEFINE
+#undef VNET_DEFINE_STATIC
+#define VNET_NAME(n) n
+#define VNET_DECLARE(t, n) extern t n
+#define VNET_DEFINE(t, n) struct _hack; t n
+#define VNET_DEFINE_STATIC(t, n) static t n
+
+/*
+ * Virtualized global variable accessor macros.
+ */
+#undef VNET
+#define VNET(n) (n)
+
+/*
+ * When VIMAGE isn't compiled into the kernel, VNET_SYSINIT/VNET_SYSUNINIT
+ * map into normal sysinits, which have the same ordering properties.
+ */
+#undef VNET_SYSINIT
+#undef VNET_SYSUNINIT
+#define VNET_SYSINIT(ident, subsystem, order, func, arg) \
+ SYSINIT(ident, subsystem, order, func, arg)
+#define VNET_SYSUNINIT(ident, subsystem, order, func, arg) \
+ SYSUNINIT(ident, subsystem, order, func, arg)
+#endif /* VIMAGE */
+#endif /* NFSD_VIMAGE */
+
#endif /* _KERNEL */
/*
@@ -493,6 +603,33 @@
uint64_t cllocalopens;
uint64_t cllocallockowners;
uint64_t cllocallocks;
+ uint64_t srvstartcnt;
+ uint64_t srvdonecnt;
+ uint64_t srvbytes[NFSV42_NOPS + NFSV4OP_FAKENOPS + 15];
+ uint64_t srvops[NFSV42_NOPS + NFSV4OP_FAKENOPS + 15];
+ struct bintime srvduration[NFSV42_NOPS + NFSV4OP_FAKENOPS + 15];
+ struct bintime busyfrom;
+ struct bintime busytime;
+};
+
+/*
+ * Subset of above structure that needs to be vnet'd for the case
+ * of NFSD_VIMAGE.
+ */
+struct nfsstatsv1_vnet {
+ uint64_t srvrpccnt[NFSV42_NOPS + NFSV4OP_FAKENOPS + 15];
+ uint64_t srvlayouts;
+ uint64_t srvcache_inproghits;
+ uint64_t srvcache_nonidemdonehits;
+ uint64_t srvcache_misses;
+ uint64_t srvcache_tcppeak;
+ int srvcache_size; /* Updated by atomic_xx_int(). */
+ uint64_t srvclients;
+ uint64_t srvopenowners;
+ uint64_t srvopens;
+ uint64_t srvlockowners;
+ uint64_t srvlocks;
+ uint64_t srvdelegates;
uint64_t srvstartcnt;
uint64_t srvdonecnt;
uint64_t srvbytes[NFSV42_NOPS + NFSV4OP_FAKENOPS + 15];
diff --git a/sys/fs/nfs/nfsrvstate.h.vnetdcl b/sys/fs/nfs/nfsrvstate.h
--- a/sys/fs/nfs/nfsrvstate.h.vnetdcl
+++ b/sys/fs/nfs/nfsrvstate.h
@@ -58,7 +58,7 @@
TAILQ_HEAD(nfsuserhashhead, nfsusrgrp);
#define NFSCLIENTHASH(id) \
- (&nfsclienthash[(id).lval[1] % nfsrv_clienthashsize])
+ (&VNET(nfsclienthash)[(id).lval[1] % nfsrv_clienthashsize])
#define NFSSTATEHASH(clp, id) \
(&((clp)->lc_stateid[(id).other[2] % nfsrv_statehashsize]))
#define NFSUSERHASH(id) \
@@ -77,7 +77,7 @@
struct nfssessionhashhead list;
};
#define NFSSESSIONHASH(f) \
- (&nfssessionhash[nfsrv_hashsessionid(f) % nfsrv_sessionhashsize])
+ (&VNET(nfssessionhash)[nfsrv_hashsessionid(f) % nfsrv_sessionhashsize])
struct nfslayouthash {
struct mtx mtx;
diff --git a/sys/fs/nfsserver/nfs_fha_new.c.vnetdcl b/sys/fs/nfsserver/nfs_fha_new.c
--- a/sys/fs/nfsserver/nfs_fha_new.c.vnetdcl
+++ b/sys/fs/nfsserver/nfs_fha_new.c
@@ -61,8 +61,9 @@
SYSCTL_DECL(_vfs_nfsd);
extern int newnfs_nfsv3_procid[];
-extern SVCPOOL *nfsrvd_pool;
+VNET_DECLARE(SVCPOOL *, nfsrvd_pool);
+
SYSINIT(nfs_fhanew, SI_SUB_ROOT_CONF, SI_ORDER_ANY, fhanew_init, NULL);
SYSUNINIT(nfs_fhanew, SI_SUB_ROOT_CONF, SI_ORDER_ANY, fhanew_uninit, NULL);
@@ -79,7 +80,7 @@
snprintf(softc->server_name, sizeof(softc->server_name),
FHANEW_SERVER_NAME);
- softc->pool = &nfsrvd_pool;
+ softc->pool = &VNET(nfsrvd_pool);
/*
* Initialize the sysctl context list for the fha module.
diff --git a/sys/fs/nfsserver/nfs_nfsdcache.c.vnetdcl b/sys/fs/nfsserver/nfs_nfsdcache.c
--- a/sys/fs/nfsserver/nfs_nfsdcache.c.vnetdcl
+++ b/sys/fs/nfsserver/nfs_nfsdcache.c
@@ -160,12 +160,16 @@
*/
#include <fs/nfs/nfsport.h>
-extern struct nfsstatsv1 nfsstatsv1;
extern struct mtx nfsrc_udpmtx;
-extern struct nfsrchash_bucket nfsrchash_table[NFSRVCACHE_HASHSIZE];
-extern struct nfsrchash_bucket nfsrcahash_table[NFSRVCACHE_HASHSIZE];
-int nfsrc_floodlevel = NFSRVCACHE_FLOODLEVEL, nfsrc_tcpsavedreplies = 0;
+NFSDSTATSDECLARE(nfsstatsv1);
+
+VNET_DECLARE(struct nfsrchash_bucket, nfsrchash_table[NFSRVCACHE_HASHSIZE]);
+VNET_DECLARE(struct nfsrchash_bucket, nfsrcahash_table[NFSRVCACHE_HASHSIZE]);
+
+VNET_DEFINE(int, nfsrc_floodlevel) = NFSRVCACHE_FLOODLEVEL;
+VNET_DEFINE(int, nfsrc_tcpsavedreplies) = 0;
+
SYSCTL_DECL(_vfs_nfsd);
static u_int nfsrc_tcphighwater = 0;
@@ -180,8 +184,8 @@
return (error);
if (newhighwater < 0)
return (EINVAL);
- if (newhighwater >= nfsrc_floodlevel)
- nfsrc_floodlevel = newhighwater + newhighwater / 5;
+ if (newhighwater >= VNET(nfsrc_floodlevel))
+ VNET(nfsrc_floodlevel) = newhighwater + newhighwater / 5;
nfsrc_tcphighwater = newhighwater;
return (0);
}
@@ -202,9 +206,9 @@
&nfsrc_tcpnonidempotent, 0,
"Enable the DRC for NFS over TCP");
-static int nfsrc_udpcachesize = 0;
-static TAILQ_HEAD(, nfsrvcache) nfsrvudplru;
-static struct nfsrvhashhead nfsrvudphashtbl[NFSRVCACHE_HASHSIZE];
+VNET_DEFINE_STATIC(int, nfsrc_udpcachesize) = 0;
+VNET_DEFINE_STATIC(TAILQ_HEAD(, nfsrvcache), nfsrvudplru);
+VNET_DEFINE_STATIC(struct nfsrvhashhead, nfsrvudphashtbl[NFSRVCACHE_HASHSIZE]);
/*
* and the reverse mapping from generic to Version 2 procedure numbers
@@ -236,10 +240,10 @@
#define nfsrc_hash(xid) (((xid) + ((xid) >> 24)) % NFSRVCACHE_HASHSIZE)
#define NFSRCUDPHASH(xid) \
- (&nfsrvudphashtbl[nfsrc_hash(xid)])
+ (&VNET(nfsrvudphashtbl)[nfsrc_hash(xid)])
#define NFSRCHASH(xid) \
- (&nfsrchash_table[nfsrc_hash(xid)].tbl)
-#define NFSRCAHASH(xid) (&nfsrcahash_table[nfsrc_hash(xid)])
+ (&VNET(nfsrchash_table)[nfsrc_hash(xid)].tbl)
+#define NFSRCAHASH(xid) (&VNET(nfsrcahash_table)[nfsrc_hash(xid)])
#define TRUE 1
#define FALSE 0
#define NFSRVCACHE_CHECKLEN 100
@@ -295,7 +299,7 @@
if ((rp->rc_flag & RC_UDP) != 0)
return (&nfsrc_udpmtx);
- return (&nfsrchash_table[nfsrc_hash(rp->rc_xid)].mtx);
+ return (&VNET(nfsrchash_table)[nfsrc_hash(rp->rc_xid)].mtx);
}
/*
@@ -305,21 +309,21 @@
nfsrvd_initcache(void)
{
int i;
- static int inited = 0;
- if (inited)
- return;
- inited = 1;
for (i = 0; i < NFSRVCACHE_HASHSIZE; i++) {
- LIST_INIT(&nfsrvudphashtbl[i]);
- LIST_INIT(&nfsrchash_table[i].tbl);
- LIST_INIT(&nfsrcahash_table[i].tbl);
+ mtx_init(&VNET(nfsrchash_table)[i].mtx, "nfsrtc", NULL,
+ MTX_DEF);
+ mtx_init(&VNET(nfsrcahash_table)[i].mtx, "nfsrtca", NULL,
+ MTX_DEF);
}
- TAILQ_INIT(&nfsrvudplru);
- nfsrc_tcpsavedreplies = 0;
- nfsrc_udpcachesize = 0;
- nfsstatsv1.srvcache_tcppeak = 0;
- nfsstatsv1.srvcache_size = 0;
+ for (i = 0; i < NFSRVCACHE_HASHSIZE; i++) {
+ LIST_INIT(&VNET(nfsrvudphashtbl)[i]);
+ LIST_INIT(&VNET(nfsrchash_table)[i].tbl);
+ LIST_INIT(&VNET(nfsrcahash_table)[i].tbl);
+ }
+ TAILQ_INIT(&VNET(nfsrvudplru));
+ VNET(nfsrc_tcpsavedreplies) = 0;
+ VNET(nfsrc_udpcachesize) = 0;
}
/*
@@ -392,17 +396,17 @@
if (rp->rc_flag == 0)
panic("nfs udp cache0");
rp->rc_flag |= RC_LOCKED;
- TAILQ_REMOVE(&nfsrvudplru, rp, rc_lru);
- TAILQ_INSERT_TAIL(&nfsrvudplru, rp, rc_lru);
+ TAILQ_REMOVE(&VNET(nfsrvudplru), rp, rc_lru);
+ TAILQ_INSERT_TAIL(&VNET(nfsrvudplru), rp, rc_lru);
if (rp->rc_flag & RC_INPROG) {
- nfsstatsv1.srvcache_inproghits++;
+ NFSDSTATS(nfsstatsv1).srvcache_inproghits++;
mtx_unlock(mutex);
ret = RC_DROPIT;
} else if (rp->rc_flag & RC_REPSTATUS) {
/*
* V2 only.
*/
- nfsstatsv1.srvcache_nonidemdonehits++;
+ NFSDSTATS(nfsstatsv1).srvcache_nonidemdonehits++;
mtx_unlock(mutex);
nfsrvd_rephead(nd);
*(nd->nd_errp) = rp->rc_status;
@@ -410,7 +414,7 @@
rp->rc_timestamp = NFSD_MONOSEC +
NFSRVCACHE_UDPTIMEOUT;
} else if (rp->rc_flag & RC_REPMBUF) {
- nfsstatsv1.srvcache_nonidemdonehits++;
+ NFSDSTATS(nfsstatsv1).srvcache_nonidemdonehits++;
mtx_unlock(mutex);
nd->nd_mreq = m_copym(rp->rc_reply, 0,
M_COPYALL, M_WAITOK);
@@ -425,9 +429,9 @@
goto out;
}
}
- nfsstatsv1.srvcache_misses++;
- atomic_add_int(&nfsstatsv1.srvcache_size, 1);
- nfsrc_udpcachesize++;
+ NFSDSTATS(nfsstatsv1).srvcache_misses++;
+ atomic_add_int(&NFSDSTATS(nfsstatsv1).srvcache_size, 1);
+ VNET(nfsrc_udpcachesize)++;
newrp->rc_flag |= RC_INPROG;
saddr = NFSSOCKADDR(nd->nd_nam, struct sockaddr_in *);
@@ -440,7 +444,7 @@
newrp->rc_flag |= RC_INETIPV6;
}
LIST_INSERT_HEAD(hp, newrp, rc_hash);
- TAILQ_INSERT_TAIL(&nfsrvudplru, newrp, rc_lru);
+ TAILQ_INSERT_TAIL(&VNET(nfsrvudplru), newrp, rc_lru);
mtx_unlock(mutex);
nd->nd_rp = newrp;
ret = RC_DOIT;
@@ -472,15 +476,15 @@
panic("nfsrvd_updatecache not inprog");
rp->rc_flag &= ~RC_INPROG;
if (rp->rc_flag & RC_UDP) {
- TAILQ_REMOVE(&nfsrvudplru, rp, rc_lru);
- TAILQ_INSERT_TAIL(&nfsrvudplru, rp, rc_lru);
+ TAILQ_REMOVE(&VNET(nfsrvudplru), rp, rc_lru);
+ TAILQ_INSERT_TAIL(&VNET(nfsrvudplru), rp, rc_lru);
}
/*
* Reply from cache is a special case returned by nfsrv_checkseqid().
*/
if (nd->nd_repstat == NFSERR_REPLYFROMCACHE) {
- nfsstatsv1.srvcache_nonidemdonehits++;
+ NFSDSTATS(nfsstatsv1).srvcache_nonidemdonehits++;
mtx_unlock(mutex);
nd->nd_repstat = 0;
if (nd->nd_mreq)
@@ -503,7 +507,7 @@
(rp->rc_refcnt > 0 ||
((nd->nd_flag & ND_SAVEREPLY) && (rp->rc_flag & RC_UDP)) ||
((nd->nd_flag & ND_SAVEREPLY) && !(rp->rc_flag & RC_UDP) &&
- nfsrc_tcpsavedreplies <= nfsrc_floodlevel &&
+ VNET(nfsrc_tcpsavedreplies) <= VNET(nfsrc_floodlevel) &&
nfsrc_tcpnonidempotent))) {
if (rp->rc_refcnt > 0) {
if (!(rp->rc_flag & RC_NFSV4))
@@ -517,11 +521,11 @@
mtx_unlock(mutex);
} else {
if (!(rp->rc_flag & RC_UDP)) {
- atomic_add_int(&nfsrc_tcpsavedreplies, 1);
- if (nfsrc_tcpsavedreplies >
- nfsstatsv1.srvcache_tcppeak)
- nfsstatsv1.srvcache_tcppeak =
- nfsrc_tcpsavedreplies;
+ atomic_add_int(&VNET(nfsrc_tcpsavedreplies), 1);
+ if (VNET(nfsrc_tcpsavedreplies) >
+ NFSDSTATS(nfsstatsv1).srvcache_tcppeak)
+ NFSDSTATS(nfsstatsv1).srvcache_tcppeak =
+ VNET(nfsrc_tcpsavedreplies);
}
mtx_unlock(mutex);
m = m_copym(nd->nd_mreq, 0, M_COPYALL, M_WAITOK);
@@ -678,7 +682,7 @@
panic("nfs tcp cache0");
rp->rc_flag |= RC_LOCKED;
if (rp->rc_flag & RC_INPROG) {
- nfsstatsv1.srvcache_inproghits++;
+ NFSDSTATS(nfsstatsv1).srvcache_inproghits++;
mtx_unlock(mutex);
if (newrp->rc_sockref == rp->rc_sockref)
nfsrc_marksametcpconn(rp->rc_sockref);
@@ -687,7 +691,7 @@
/*
* V2 only.
*/
- nfsstatsv1.srvcache_nonidemdonehits++;
+ NFSDSTATS(nfsstatsv1).srvcache_nonidemdonehits++;
mtx_unlock(mutex);
if (newrp->rc_sockref == rp->rc_sockref)
nfsrc_marksametcpconn(rp->rc_sockref);
@@ -696,7 +700,7 @@
*(nd->nd_errp) = rp->rc_status;
rp->rc_timestamp = NFSD_MONOSEC + nfsrc_tcptimeout;
} else if (rp->rc_flag & RC_REPMBUF) {
- nfsstatsv1.srvcache_nonidemdonehits++;
+ NFSDSTATS(nfsstatsv1).srvcache_nonidemdonehits++;
mtx_unlock(mutex);
if (newrp->rc_sockref == rp->rc_sockref)
nfsrc_marksametcpconn(rp->rc_sockref);
@@ -711,8 +715,8 @@
free(newrp, M_NFSRVCACHE);
goto out;
}
- nfsstatsv1.srvcache_misses++;
- atomic_add_int(&nfsstatsv1.srvcache_size, 1);
+ NFSDSTATS(nfsstatsv1).srvcache_misses++;
+ atomic_add_int(&NFSDSTATS(nfsstatsv1).srvcache_size, 1);
/*
* For TCP, multiple entries for a key are allowed, so don't
@@ -785,8 +789,8 @@
LIST_REMOVE(rp, rc_hash);
if (rp->rc_flag & RC_UDP) {
- TAILQ_REMOVE(&nfsrvudplru, rp, rc_lru);
- nfsrc_udpcachesize--;
+ TAILQ_REMOVE(&VNET(nfsrvudplru), rp, rc_lru);
+ VNET(nfsrc_udpcachesize)--;
} else if (rp->rc_acked != RC_NO_SEQ) {
hbp = NFSRCAHASH(rp->rc_sockref);
mtx_lock(&hbp->mtx);
@@ -798,10 +802,10 @@
if (rp->rc_flag & RC_REPMBUF) {
m_freem(rp->rc_reply);
if (!(rp->rc_flag & RC_UDP))
- atomic_add_int(&nfsrc_tcpsavedreplies, -1);
+ atomic_add_int(&VNET(nfsrc_tcpsavedreplies), -1);
}
free(rp, M_NFSRVCACHE);
- atomic_add_int(&nfsstatsv1.srvcache_size, -1);
+ atomic_add_int(&NFSDSTATS(nfsstatsv1).srvcache_size, -1);
}
/*
@@ -814,20 +818,20 @@
int i;
for (i = 0; i < NFSRVCACHE_HASHSIZE; i++) {
- mtx_lock(&nfsrchash_table[i].mtx);
- LIST_FOREACH_SAFE(rp, &nfsrchash_table[i].tbl, rc_hash, nextrp)
+ mtx_lock(&VNET(nfsrchash_table)[i].mtx);
+ LIST_FOREACH_SAFE(rp, &VNET(nfsrchash_table)[i].tbl, rc_hash, nextrp)
nfsrc_freecache(rp);
- mtx_unlock(&nfsrchash_table[i].mtx);
+ mtx_unlock(&VNET(nfsrchash_table)[i].mtx);
}
mtx_lock(&nfsrc_udpmtx);
for (i = 0; i < NFSRVCACHE_HASHSIZE; i++) {
- LIST_FOREACH_SAFE(rp, &nfsrvudphashtbl[i], rc_hash, nextrp) {
+ LIST_FOREACH_SAFE(rp, &VNET(nfsrvudphashtbl)[i], rc_hash, nextrp) {
nfsrc_freecache(rp);
}
}
- nfsstatsv1.srvcache_size = 0;
+ NFSDSTATS(nfsstatsv1).srvcache_size = 0;
mtx_unlock(&nfsrc_udpmtx);
- nfsrc_tcpsavedreplies = 0;
+ VNET(nfsrc_tcpsavedreplies) = 0;
}
#define HISTSIZE 16
@@ -864,25 +868,25 @@
if (atomic_cmpset_acq_int(&onethread, 0, 1) == 0)
return;
if (NFSD_MONOSEC != udp_lasttrim ||
- nfsrc_udpcachesize >= (nfsrc_udphighwater +
+ VNET(nfsrc_udpcachesize) >= (nfsrc_udphighwater +
nfsrc_udphighwater / 2)) {
mtx_lock(&nfsrc_udpmtx);
udp_lasttrim = NFSD_MONOSEC;
- TAILQ_FOREACH_SAFE(rp, &nfsrvudplru, rc_lru, nextrp) {
+ TAILQ_FOREACH_SAFE(rp, &VNET(nfsrvudplru), rc_lru, nextrp) {
if (!(rp->rc_flag & (RC_INPROG|RC_LOCKED|RC_WANTED))
&& rp->rc_refcnt == 0
&& ((rp->rc_flag & RC_REFCNT) ||
udp_lasttrim > rp->rc_timestamp ||
- nfsrc_udpcachesize > nfsrc_udphighwater))
+ VNET(nfsrc_udpcachesize) > nfsrc_udphighwater))
nfsrc_freecache(rp);
}
mtx_unlock(&nfsrc_udpmtx);
}
if (NFSD_MONOSEC != tcp_lasttrim ||
- nfsrc_tcpsavedreplies >= nfsrc_tcphighwater) {
+ VNET(nfsrc_tcpsavedreplies) >= nfsrc_tcphighwater) {
force = nfsrc_tcphighwater / 4;
if (force > 0 &&
- nfsrc_tcpsavedreplies + force >= nfsrc_tcphighwater) {
+ VNET(nfsrc_tcpsavedreplies) + force >= nfsrc_tcphighwater) {
for (i = 0; i < HISTSIZE; i++)
time_histo[i] = 0;
i = 0;
@@ -901,8 +905,8 @@
tto = nfsrc_tcptimeout;
tcp_lasttrim = NFSD_MONOSEC;
for (; i <= lastslot; i++) {
- mtx_lock(&nfsrchash_table[i].mtx);
- LIST_FOREACH_SAFE(rp, &nfsrchash_table[i].tbl, rc_hash,
+ mtx_lock(&VNET(nfsrchash_table)[i].mtx);
+ LIST_FOREACH_SAFE(rp, &VNET(nfsrchash_table)[i].tbl, rc_hash,
nextrp) {
if (!(rp->rc_flag &
(RC_INPROG|RC_LOCKED|RC_WANTED))
@@ -932,7 +936,7 @@
time_histo[j]++;
}
}
- mtx_unlock(&nfsrchash_table[i].mtx);
+ mtx_unlock(&VNET(nfsrchash_table)[i].mtx);
}
if (force) {
/*
@@ -951,8 +955,8 @@
k = 1;
thisstamp = tcp_lasttrim + k;
for (i = 0; i < NFSRVCACHE_HASHSIZE; i++) {
- mtx_lock(&nfsrchash_table[i].mtx);
- LIST_FOREACH_SAFE(rp, &nfsrchash_table[i].tbl,
+ mtx_lock(&VNET(nfsrchash_table)[i].mtx);
+ LIST_FOREACH_SAFE(rp, &VNET(nfsrchash_table)[i].tbl,
rc_hash, nextrp) {
if (!(rp->rc_flag &
(RC_INPROG|RC_LOCKED|RC_WANTED))
@@ -962,7 +966,7 @@
rp->rc_acked == RC_ACK))
nfsrc_freecache(rp);
}
- mtx_unlock(&nfsrchash_table[i].mtx);
+ mtx_unlock(&VNET(nfsrchash_table)[i].mtx);
}
}
}
diff --git a/sys/fs/nfsserver/nfs_nfsdkrpc.c.vnetdcl b/sys/fs/nfsserver/nfs_nfsdkrpc.c
--- a/sys/fs/nfsserver/nfs_nfsdkrpc.c.vnetdcl
+++ b/sys/fs/nfsserver/nfs_nfsdkrpc.c
@@ -52,7 +52,6 @@
NFSDLOCKMUTEX;
NFSV4ROOTLOCKMUTEX;
-struct nfsv4lock nfsd_suspend_lock;
char *nfsrv_zeropnfsdat = NULL;
/*
@@ -85,32 +84,39 @@
SYSCTL_DECL(_vfs_nfsd);
-SVCPOOL *nfsrvd_pool;
-
-static int nfs_privport = 0;
-SYSCTL_INT(_vfs_nfsd, OID_AUTO, nfs_privport, CTLFLAG_RWTUN,
- &nfs_privport, 0,
+VNET_DEFINE_STATIC(int, nfs_privport) = 0;
+SYSCTL_INT(_vfs_nfsd, OID_AUTO, nfs_privport, CTLFLAG_VNET | CTLFLAG_RWTUN,
+ &VNET_NAME(nfs_privport), 0,
"Only allow clients using a privileged port for NFSv2, 3 and 4");
-static int nfs_minvers = NFS_VER2;
-SYSCTL_INT(_vfs_nfsd, OID_AUTO, server_min_nfsvers, CTLFLAG_RWTUN,
- &nfs_minvers, 0, "The lowest version of NFS handled by the server");
+VNET_DEFINE_STATIC(int, nfs_minvers) = NFS_VER2;
+SYSCTL_INT(_vfs_nfsd, OID_AUTO, server_min_nfsvers,
+ CTLFLAG_VNET | CTLFLAG_RWTUN, &VNET_NAME(nfs_minvers), 0,
+ "The lowest version of NFS handled by the server");
-static int nfs_maxvers = NFS_VER4;
-SYSCTL_INT(_vfs_nfsd, OID_AUTO, server_max_nfsvers, CTLFLAG_RWTUN,
- &nfs_maxvers, 0, "The highest version of NFS handled by the server");
+VNET_DEFINE_STATIC(int, nfs_maxvers) = NFS_VER4;
+SYSCTL_INT(_vfs_nfsd, OID_AUTO, server_max_nfsvers,
+ CTLFLAG_VNET | CTLFLAG_RWTUN, &VNET_NAME(nfs_maxvers), 0,
+ "The highest version of NFS handled by the server");
static int nfs_proc(struct nfsrv_descript *, u_int32_t, SVCXPRT *xprt,
struct nfsrvcache **);
extern u_long sb_max_adj;
extern int newnfs_numnfsd;
-extern struct proc *nfsd_master_proc;
extern time_t nfsdev_time;
extern int nfsrv_writerpc[NFS_NPROCS];
extern volatile int nfsrv_devidcnt;
extern struct nfsv4_opflag nfsv4_opflag[NFSV42_NOPS];
+VNET_DECLARE(struct proc *, nfsd_master_proc);
+
+VNET_DEFINE(SVCPOOL *, nfsrvd_pool);
+VNET_DEFINE(int, nfsrv_numnfsd) = 0;
+VNET_DEFINE(struct nfsv4lock, nfsd_suspend_lock);
+
+VNET_DEFINE_STATIC(bool, nfsrvd_inited) = false;
+
/*
* NFS server system calls
*/
@@ -125,6 +131,7 @@
u_int maxlen;
#endif
+ CURVNET_SET(TD_TO_VNET(curthread));
memset(&nd, 0, sizeof(nd));
if (rqst->rq_vers == NFS_VER2) {
if (rqst->rq_proc > NFSV2PROC_STATFS ||
@@ -169,7 +176,7 @@
nd.nd_mreq = NULL;
nd.nd_cred = NULL;
- if (nfs_privport != 0) {
+ if (VNET(nfs_privport) != 0) {
/* Check if source port is privileged */
u_short port;
struct sockaddr *nam = nd.nd_nam;
@@ -261,9 +268,9 @@
* nfsv4root exports by nfsvno_v4rootexport().
*/
NFSLOCKV4ROOTMUTEX();
- nfsv4_lock(&nfsd_suspend_lock, 0, NULL, NFSV4ROOTLOCKMUTEXPTR,
+ nfsv4_lock(&VNET(nfsd_suspend_lock), 0, NULL, NFSV4ROOTLOCKMUTEXPTR,
NULL);
- nfsv4_getref(&nfsd_suspend_lock, NULL, NFSV4ROOTLOCKMUTEXPTR,
+ nfsv4_getref(&VNET(nfsd_suspend_lock), NULL, NFSV4ROOTLOCKMUTEXPTR,
NULL);
NFSUNLOCKV4ROOTMUTEX();
@@ -271,7 +278,7 @@
nd.nd_repstat = nfsvno_v4rootexport(&nd);
if (nd.nd_repstat != 0) {
NFSLOCKV4ROOTMUTEX();
- nfsv4_relref(&nfsd_suspend_lock);
+ nfsv4_relref(&VNET(nfsd_suspend_lock));
NFSUNLOCKV4ROOTMUTEX();
svcerr_weakauth(rqst);
svc_freereq(rqst);
@@ -287,7 +294,7 @@
#endif
cacherep = nfs_proc(&nd, rqst->rq_xid, xprt, &rp);
NFSLOCKV4ROOTMUTEX();
- nfsv4_relref(&nfsd_suspend_lock);
+ nfsv4_relref(&VNET(nfsd_suspend_lock));
NFSUNLOCKV4ROOTMUTEX();
} else {
NFSMGET(nd.nd_mreq);
@@ -327,6 +334,7 @@
svc_freereq(rqst);
out:
+ CURVNET_RESTORE();
ast_kclear(curthread);
NFSEXITCODE(0);
}
@@ -467,26 +475,28 @@
* unexpectedly.
*/
if (so->so_type == SOCK_DGRAM)
- xprt = svc_dg_create(nfsrvd_pool, so, 0, 0);
+ xprt = svc_dg_create(VNET(nfsrvd_pool), so, 0, 0);
else
- xprt = svc_vc_create(nfsrvd_pool, so, 0, 0);
+ xprt = svc_vc_create(VNET(nfsrvd_pool), so, 0, 0);
if (xprt) {
fp->f_ops = &badfileops;
fp->f_data = NULL;
xprt->xp_sockref = ++sockref;
- if (nfs_minvers == NFS_VER2)
+ if (VNET(nfs_minvers) == NFS_VER2)
svc_reg(xprt, NFS_PROG, NFS_VER2, nfssvc_program,
NULL);
- if (nfs_minvers <= NFS_VER3 && nfs_maxvers >= NFS_VER3)
+ if (VNET(nfs_minvers) <= NFS_VER3 &&
+ VNET(nfs_maxvers) >= NFS_VER3)
svc_reg(xprt, NFS_PROG, NFS_VER3, nfssvc_program,
NULL);
- if (nfs_maxvers >= NFS_VER4)
+ if (VNET(nfs_maxvers) >= NFS_VER4)
svc_reg(xprt, NFS_PROG, NFS_VER4, nfssvc_program,
NULL);
if (so->so_type == SOCK_STREAM)
svc_loss_reg(xprt, nfssvc_loss);
SVC_RELEASE(xprt);
- }
+ } else
+ error = EPERM;
out:
NFSEXITCODE(error);
@@ -518,13 +528,15 @@
* use.
*/
NFSD_LOCK();
- if (newnfs_numnfsd == 0) {
+ if (VNET(nfsrv_numnfsd) == 0) {
+ nfsrvd_init(0);
nfsdev_time = time_second;
p = td->td_proc;
PROC_LOCK(p);
p->p_flag2 |= P2_AST_SU;
PROC_UNLOCK(p);
- newnfs_numnfsd++;
+ newnfs_numnfsd++; /* Total num for all vnets. */
+ VNET(nfsrv_numnfsd)++; /* Num for this vnet. */
NFSD_UNLOCK();
error = nfsrv_createdevids(args, td);
@@ -546,8 +558,8 @@
"nfsd: can't register svc name\n");
}
- nfsrvd_pool->sp_minthreads = args->minthreads;
- nfsrvd_pool->sp_maxthreads = args->maxthreads;
+ VNET(nfsrvd_pool)->sp_minthreads = args->minthreads;
+ VNET(nfsrvd_pool)->sp_maxthreads = args->maxthreads;
/*
* If this is a pNFS service, make Getattr do a
@@ -558,7 +570,7 @@
nfsv4_opflag[NFSV4OP_GETATTR].modifyfs = 1;
}
- svc_run(nfsrvd_pool);
+ svc_run(VNET(nfsrvd_pool));
/* Reset Getattr to not do a vn_start_write(). */
nfsrv_writerpc[NFSPROC_GETATTR] = 0;
@@ -572,6 +584,7 @@
}
NFSD_LOCK();
newnfs_numnfsd--;
+ VNET(nfsrv_numnfsd)--;
nfsrvd_init(1);
PROC_LOCK(p);
p->p_flag2 &= ~P2_AST_SU;
@@ -596,21 +609,28 @@
NFSD_LOCK_ASSERT();
if (terminating) {
- nfsd_master_proc = NULL;
+ VNET(nfsd_master_proc) = NULL;
NFSD_UNLOCK();
nfsrv_freealllayoutsanddevids();
nfsrv_freeallbackchannel_xprts();
- svcpool_close(nfsrvd_pool);
+ svcpool_close(VNET(nfsrvd_pool));
free(nfsrv_zeropnfsdat, M_TEMP);
nfsrv_zeropnfsdat = NULL;
NFSD_LOCK();
} else {
+ /* Initialize per-vnet globals once per vnet. */
+ if (VNET(nfsrvd_inited))
+ return;
+ VNET(nfsrvd_inited) = true;
NFSD_UNLOCK();
- nfsrvd_pool = svcpool_create("nfsd",
+ nfsrvd_initcache();
+ nfsd_init();
+ nfsd_mntinit();
+ VNET(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 = fhanew_nd_complete;
+ VNET(nfsrvd_pool)->sp_rcache = NULL;
+ VNET(nfsrvd_pool)->sp_assign = fhanew_assign;
+ VNET(nfsrvd_pool)->sp_done = fhanew_nd_complete;
NFSD_LOCK();
}
}
diff --git a/sys/fs/nfsserver/nfs_nfsdport.c.vnet b/sys/fs/nfsserver/nfs_nfsdport.c
--- a/sys/fs/nfsserver/nfs_nfsdport.c.vnet
+++ b/sys/fs/nfsserver/nfs_nfsdport.c
@@ -59,38 +59,35 @@
extern u_int32_t newnfs_true, newnfs_false, newnfs_xdrneg1;
extern int nfsrv_useacl;
extern int newnfs_numnfsd;
-extern struct mount nfsv4root_mnt;
-extern struct nfsrv_stablefirst nfsrv_stablefirst;
-extern SVCPOOL *nfsrvd_pool;
-extern struct nfsv4lock nfsd_suspend_lock;
-extern struct nfsclienthashhead *nfsclienthash;
-extern struct nfslockhashhead *nfslockhash;
-extern struct nfssessionhash *nfssessionhash;
extern int nfsrv_sessionhashsize;
-extern struct nfsstatsv1 nfsstatsv1;
extern struct nfslayouthash *nfslayouthash;
extern int nfsrv_layouthashsize;
extern struct mtx nfsrv_dslock_mtx;
extern int nfs_pnfsiothreads;
-extern struct nfsdontlisthead nfsrv_dontlisthead;
-extern volatile int nfsrv_dontlistlen;
extern volatile int nfsrv_devidcnt;
extern int nfsrv_maxpnfsmirror;
extern uint32_t nfs_srvmaxio;
extern int nfs_bufpackets;
extern u_long sb_max_adj;
-struct vfsoptlist nfsv4root_opt, nfsv4root_newopt;
+
+NFSDSTATSDECLARE(nfsstatsv1);
+
+VNET_DECLARE(int, nfsrv_numnfsd);
+VNET_DECLARE(struct nfsrv_stablefirst, nfsrv_stablefirst);
+VNET_DECLARE(SVCPOOL *, nfsrvd_pool);
+VNET_DECLARE(struct nfsclienthashhead *, nfsclienthash);
+VNET_DECLARE(struct nfslockhashhead *, nfslockhash);
+VNET_DECLARE(struct nfssessionhash *, nfssessionhash);
+VNET_DECLARE(struct nfsv4lock, nfsd_suspend_lock);
+
NFSDLOCKMUTEX;
NFSSTATESPINLOCK;
-struct nfsrchash_bucket nfsrchash_table[NFSRVCACHE_HASHSIZE];
-struct nfsrchash_bucket nfsrcahash_table[NFSRVCACHE_HASHSIZE];
struct mtx nfsrc_udpmtx;
struct mtx nfs_v4root_mutex;
struct mtx nfsrv_dontlistlock_mtx;
struct mtx nfsrv_recalllock_mtx;
-struct nfsrvfh nfs_rootfh, nfs_pubfh;
-int nfs_pubfhset = 0, nfs_rootfhset = 0;
-struct proc *nfsd_master_proc = NULL;
+struct nfsrvfh nfs_pubfh;
+int nfs_pubfhset = 0;
int nfsd_debuglevel = 0;
static pid_t nfsd_master_pid = (pid_t)-1;
static char nfsd_master_comm[MAXCOMLEN + 1];
@@ -99,6 +96,18 @@
static fhandle_t zerofh;
struct callout nfsd_callout;
+VNET_DEFINE(struct proc *, nfsd_master_proc) = NULL;
+VNET_DEFINE(struct nfsrchash_bucket, nfsrchash_table[NFSRVCACHE_HASHSIZE]);
+VNET_DEFINE(struct nfsrchash_bucket, nfsrcahash_table[NFSRVCACHE_HASHSIZE]);
+VNET_DEFINE(struct nfsrvfh, nfs_rootfh);
+VNET_DEFINE(int, nfs_rootfhset) = 0;
+
+VNET_DEFINE_STATIC(struct mount, nfsv4root_mnt);
+VNET_DEFINE_STATIC(struct vfsoptlist, nfsv4root_opt);
+VNET_DEFINE_STATIC(struct vfsoptlist, nfsv4root_newopt);
+VNET_DEFINE_STATIC(bool, nfsrv_suspend_nfsd) = false;
+VNET_DEFINE_STATIC(bool, nfsrv_mntinited) = false;
+
static int nfssvc_srvcall(struct thread *, struct nfssvc_args *,
struct ucred *);
static void nfsvno_updateds(struct vnode *, struct ucred *, struct thread *);
@@ -1026,7 +1035,7 @@
nh = nfsrv_sequential_heuristic(uiop, vp);
ioflag |= nh->nh_seqcount << IO_SEQSHIFT;
/* XXX KDM make this more systematic? */
- nfsstatsv1.srvbytes[NFSV4OP_READ] += uiop->uio_resid;
+ NFSDSTATS(nfsstatsv1).srvbytes[NFSV4OP_READ] += uiop->uio_resid;
error = VOP_READ(vp, uiop, IO_NODELOCKED | ioflag, cred);
free(iv, M_TEMP);
if (error) {
@@ -1151,7 +1160,7 @@
nh = nfsrv_sequential_heuristic(uiop, vp);
ioflags |= nh->nh_seqcount << IO_SEQSHIFT;
/* XXX KDM make this more systematic? */
- nfsstatsv1.srvbytes[NFSV4OP_WRITE] += uiop->uio_resid;
+ NFSDSTATS(nfsstatsv1).srvbytes[NFSV4OP_WRITE] += uiop->uio_resid;
error = VOP_WRITE(vp, uiop, ioflags, cred);
if (error == 0)
nh->nh_nextoff = uiop->uio_offset;
@@ -3255,7 +3264,7 @@
error = VFS_CHECKEXP(mp, nam, &exp->nes_exflag, credp,
&exp->nes_numsecflavor, exp->nes_secflavors);
if (error) {
- if (nfs_rootfhset) {
+ if (VNET(nfs_rootfhset)) {
exp->nes_exflag = 0;
exp->nes_numsecflavor = 0;
error = 0;
@@ -3290,7 +3299,7 @@
error = VFS_CHECKEXP(mp, nam, &exp->nes_exflag, credp,
&exp->nes_numsecflavor, exp->nes_secflavors);
if (error) {
- if (nfs_rootfhset) {
+ if (VNET(nfs_rootfhset)) {
exp->nes_exflag = 0;
exp->nes_numsecflavor = 0;
error = 0;
@@ -3458,9 +3467,9 @@
struct nameidata nd;
fhandle_t fh;
- error = vfs_export(&nfsv4root_mnt, &nfsexargp->export);
+ error = vfs_export(&VNET(nfsv4root_mnt), &nfsexargp->export);
if ((nfsexargp->export.ex_flags & MNT_DELEXPORT) != 0)
- nfs_rootfhset = 0;
+ VNET(nfs_rootfhset) = 0;
else if (error == 0) {
if (nfsexargp->fspec == NULL) {
error = EPERM;
@@ -3475,11 +3484,11 @@
error = nfsvno_getfh(nd.ni_vp, &fh, p);
vrele(nd.ni_vp);
if (!error) {
- nfs_rootfh.nfsrvfh_len = NFSX_MYFH;
+ VNET(nfs_rootfh).nfsrvfh_len = NFSX_MYFH;
NFSBCOPY((caddr_t)&fh,
- nfs_rootfh.nfsrvfh_data,
+ VNET(nfs_rootfh).nfsrvfh_data,
sizeof (fhandle_t));
- nfs_rootfhset = 1;
+ VNET(nfs_rootfhset) = 1;
}
}
@@ -3515,29 +3524,34 @@
void
nfsd_mntinit(void)
{
- static int inited = 0;
- if (inited)
+ if (VNET(nfsrv_mntinited))
return;
- inited = 1;
- nfsv4root_mnt.mnt_flag = (MNT_RDONLY | MNT_EXPORTED);
- TAILQ_INIT(&nfsv4root_mnt.mnt_nvnodelist);
- TAILQ_INIT(&nfsv4root_mnt.mnt_lazyvnodelist);
- nfsv4root_mnt.mnt_export = NULL;
- TAILQ_INIT(&nfsv4root_opt);
- TAILQ_INIT(&nfsv4root_newopt);
- nfsv4root_mnt.mnt_opt = &nfsv4root_opt;
- nfsv4root_mnt.mnt_optnew = &nfsv4root_newopt;
- nfsv4root_mnt.mnt_nvnodelistsize = 0;
- nfsv4root_mnt.mnt_lazyvnodelistsize = 0;
+ VNET(nfsrv_mntinited) = true;
+ VNET(nfsv4root_mnt).mnt_flag = (MNT_RDONLY | MNT_EXPORTED);
+ mtx_init(&VNET(nfsv4root_mnt).mnt_mtx, "nfs4mnt", NULL, MTX_DEF);
+ lockinit(&VNET(nfsv4root_mnt).mnt_explock, PVFS, "explock", 0, 0);
+ TAILQ_INIT(&VNET(nfsv4root_mnt).mnt_nvnodelist);
+ TAILQ_INIT(&VNET(nfsv4root_mnt).mnt_lazyvnodelist);
+ VNET(nfsv4root_mnt).mnt_export = NULL;
+ TAILQ_INIT(&VNET(nfsv4root_opt));
+ TAILQ_INIT(&VNET(nfsv4root_newopt));
+ VNET(nfsv4root_mnt).mnt_opt = &VNET(nfsv4root_opt);
+ VNET(nfsv4root_mnt).mnt_optnew = &VNET(nfsv4root_newopt);
+ VNET(nfsv4root_mnt).mnt_nvnodelistsize = 0;
+ VNET(nfsv4root_mnt).mnt_lazyvnodelistsize = 0;
}
static void
nfsd_timer(void *arg)
{
+ struct vnet *vnetp;
+ vnetp = (struct vnet *)arg;
+ CURVNET_SET(vnetp);
nfsrv_servertimer();
- callout_reset_sbt(&nfsd_callout, SBT_1S, SBT_1S, nfsd_timer, NULL, 0);
+ CURVNET_RESTORE();
+ callout_reset_sbt(&nfsd_callout, SBT_1S, SBT_1S, nfsd_timer, arg, 0);
}
/*
@@ -3619,7 +3633,7 @@
int error = 0, numsecflavor, secflavors[MAXSECFLAVORS], i;
uint64_t exflags;
- error = vfs_stdcheckexp(&nfsv4root_mnt, nd->nd_nam, &exflags,
+ error = vfs_stdcheckexp(&VNET(nfsv4root_mnt), nd->nd_nam, &exflags,
&credanon, &numsecflavor, secflavors);
if (error) {
error = NFSERR_PROGUNAVAIL;
@@ -3674,6 +3688,11 @@
char *buf, *cp, *cp2, *cp3;
char fname[PNFS_FILENAME_LEN + 1];
+ if (jailed(td->td_ucred) && !prison_check_nfsd(td->td_ucred)) {
+ error = EPERM;
+ goto out;
+ }
+ nfsd_mntinit();
if (uap->flag & NFSSVC_NFSDADDSOCK) {
error = copyin(uap->argp, (caddr_t)&sockarg, sizeof (sockarg));
if (error)
@@ -3781,7 +3800,7 @@
nfsdarg.mdspathlen = 0;
nfsdarg.mirrorcnt = 1;
}
- nfsd_timer(NULL);
+ nfsd_timer(TD_TO_VNET(td));
error = nfsrvd_nfsd(td, &nfsdarg);
free(nfsdarg.addr, M_TEMP);
free(nfsdarg.dnshost, M_TEMP);
@@ -3881,7 +3900,6 @@
int error = EINVAL, igotlock;
struct proc *procp;
gid_t *grps;
- static int suspend_nfsd = 0;
if (uap->flag & NFSSVC_PUBLICFH) {
NFSBZERO((caddr_t)&nfs_pubfh.nfsrvfh_data,
@@ -3965,10 +3983,10 @@
error = fp_getfvp(p, stablefd, &fp, &vp);
if (!error && (NFSFPFLAG(fp) & (FREAD | FWRITE)) != (FREAD | FWRITE))
error = EBADF;
- if (!error && newnfs_numnfsd != 0)
+ if (!error && VNET(nfsrv_numnfsd) != 0)
error = EPERM;
if (!error) {
- nfsrv_stablefirst.nsf_fp = fp;
+ VNET(nfsrv_stablefirst).nsf_fp = fp;
nfsrv_setupstable(p);
}
} else if (uap->flag & NFSSVC_ADMINREVOKE) {
@@ -4015,25 +4033,25 @@
nfsd_master_pid = procp->p_pid;
bcopy(procp->p_comm, nfsd_master_comm, MAXCOMLEN + 1);
nfsd_master_start = procp->p_stats->p_start;
- nfsd_master_proc = procp;
+ VNET(nfsd_master_proc) = procp;
PROC_UNLOCK(procp);
} else if ((uap->flag & NFSSVC_SUSPENDNFSD) != 0) {
NFSLOCKV4ROOTMUTEX();
- if (suspend_nfsd == 0) {
+ if (!VNET(nfsrv_suspend_nfsd)) {
/* Lock out all nfsd threads */
do {
- igotlock = nfsv4_lock(&nfsd_suspend_lock, 1,
+ igotlock = nfsv4_lock(&VNET(nfsd_suspend_lock), 1,
NULL, NFSV4ROOTLOCKMUTEXPTR, NULL);
- } while (igotlock == 0 && suspend_nfsd == 0);
- suspend_nfsd = 1;
+ } while (igotlock == 0 && !VNET(nfsrv_suspend_nfsd));
+ VNET(nfsrv_suspend_nfsd) = true;
}
NFSUNLOCKV4ROOTMUTEX();
error = 0;
} else if ((uap->flag & NFSSVC_RESUMENFSD) != 0) {
NFSLOCKV4ROOTMUTEX();
- if (suspend_nfsd != 0) {
- nfsv4_unlock(&nfsd_suspend_lock, 0);
- suspend_nfsd = 0;
+ if (VNET(nfsrv_suspend_nfsd)) {
+ nfsv4_unlock(&VNET(nfsd_suspend_lock), 0);
+ VNET(nfsrv_suspend_nfsd) = false;
}
NFSUNLOCKV4ROOTMUTEX();
error = 0;
@@ -4141,10 +4159,10 @@
{
struct proc *procp;
- if (nfsd_master_proc != NULL) {
+ if (VNET(nfsd_master_proc) != NULL) {
procp = pfind(nfsd_master_pid);
/* Try to make sure it is the correct process. */
- if (procp == nfsd_master_proc &&
+ if (procp == VNET(nfsd_master_proc) &&
procp->p_stats->p_start.tv_sec ==
nfsd_master_start.tv_sec &&
procp->p_stats->p_start.tv_usec ==
@@ -4152,7 +4170,7 @@
strcmp(procp->p_comm, nfsd_master_comm) == 0)
kern_psignal(procp, SIGUSR2);
else
- nfsd_master_proc = NULL;
+ VNET(nfsd_master_proc) = NULL;
if (procp != NULL)
PROC_UNLOCK(procp);
@@ -7079,24 +7097,13 @@
if (loaded)
goto out;
newnfs_portinit();
- for (i = 0; i < NFSRVCACHE_HASHSIZE; i++) {
- mtx_init(&nfsrchash_table[i].mtx, "nfsrtc", NULL,
- MTX_DEF);
- mtx_init(&nfsrcahash_table[i].mtx, "nfsrtca", NULL,
- MTX_DEF);
- }
mtx_init(&nfsrc_udpmtx, "nfsuc", NULL, MTX_DEF);
mtx_init(&nfs_v4root_mutex, "nfs4rt", NULL, MTX_DEF);
- mtx_init(&nfsv4root_mnt.mnt_mtx, "nfs4mnt", NULL, MTX_DEF);
mtx_init(&nfsrv_dontlistlock_mtx, "nfs4dnl", NULL, MTX_DEF);
mtx_init(&nfsrv_recalllock_mtx, "nfs4rec", NULL, MTX_DEF);
- lockinit(&nfsv4root_mnt.mnt_explock, PVFS, "explock", 0, 0);
callout_init(&nfsd_callout, 1);
- nfsrvd_initcache();
- nfsd_init();
- NFSD_LOCK();
- nfsrvd_init(0);
- NFSD_UNLOCK();
+ NFSDSTATS(nfsstatsv1).srvcache_tcppeak = 0;
+ NFSDSTATS(nfsstatsv1).srvcache_size = 0;
nfsd_mntinit();
#ifdef VV_DISABLEDELEG
vn_deleg_ops.vndeleg_recall = nfsd_recalldelegation;
@@ -7126,30 +7133,30 @@
nfsrvd_cleancache();
/* Free up the krpc server pool. */
- if (nfsrvd_pool != NULL)
- svcpool_destroy(nfsrvd_pool);
+ if (VNET(nfsrvd_pool) != NULL)
+ svcpool_destroy(VNET(nfsrvd_pool));
/* and get rid of the locks */
for (i = 0; i < NFSRVCACHE_HASHSIZE; i++) {
- mtx_destroy(&nfsrchash_table[i].mtx);
- mtx_destroy(&nfsrcahash_table[i].mtx);
+ mtx_destroy(&VNET(nfsrchash_table)[i].mtx);
+ mtx_destroy(&VNET(nfsrcahash_table)[i].mtx);
}
mtx_destroy(&nfsrc_udpmtx);
mtx_destroy(&nfs_v4root_mutex);
- mtx_destroy(&nfsv4root_mnt.mnt_mtx);
+ mtx_destroy(&VNET(nfsv4root_mnt).mnt_mtx);
mtx_destroy(&nfsrv_dontlistlock_mtx);
mtx_destroy(&nfsrv_recalllock_mtx);
for (i = 0; i < nfsrv_sessionhashsize; i++)
- mtx_destroy(&nfssessionhash[i].mtx);
+ mtx_destroy(&VNET(nfssessionhash)[i].mtx);
if (nfslayouthash != NULL) {
for (i = 0; i < nfsrv_layouthashsize; i++)
mtx_destroy(&nfslayouthash[i].mtx);
free(nfslayouthash, M_NFSDSESSION);
}
- lockdestroy(&nfsv4root_mnt.mnt_explock);
- free(nfsclienthash, M_NFSDCLIENT);
- free(nfslockhash, M_NFSDLOCKFILE);
- free(nfssessionhash, M_NFSDSESSION);
+ lockdestroy(&VNET(nfsv4root_mnt).mnt_explock);
+ free(VNET(nfsclienthash), M_NFSDCLIENT);
+ free(VNET(nfslockhash), M_NFSDLOCKFILE);
+ free(VNET(nfssessionhash), M_NFSDSESSION);
loaded = 0;
break;
default:
diff --git a/sys/fs/nfsserver/nfs_nfsdsocket.c.vnet b/sys/fs/nfsserver/nfs_nfsdsocket.c
--- a/sys/fs/nfsserver/nfs_nfsdsocket.c.vnet
+++ b/sys/fs/nfsserver/nfs_nfsdsocket.c
@@ -42,20 +42,25 @@
#include <fs/nfs/nfsport.h>
-extern struct nfsstatsv1 nfsstatsv1;
-extern struct nfsrvfh nfs_pubfh, nfs_rootfh;
-extern int nfs_pubfhset, nfs_rootfhset;
+extern struct nfsrvfh nfs_pubfh;
+extern int nfs_pubfhset;
extern struct nfsv4lock nfsv4rootfs_lock;
-extern struct nfsrv_stablefirst nfsrv_stablefirst;
-extern struct nfsclienthashhead *nfsclienthash;
extern int nfsrv_clienthashsize;
-extern int nfsrc_floodlevel, nfsrc_tcpsavedreplies;
extern int nfsd_debuglevel;
extern int nfsrv_layouthighwater;
extern volatile int nfsrv_layoutcnt;
NFSV4ROOTLOCKMUTEX;
NFSSTATESPINLOCK;
+NFSDSTATSDECLARE(nfsstatsv1);
+
+VNET_DECLARE(struct nfsrv_stablefirst, nfsrv_stablefirst);
+VNET_DECLARE(struct nfsclienthashhead *, nfsclienthash);
+VNET_DECLARE(int, nfsrc_floodlevel);
+VNET_DECLARE(int, nfsrc_tcpsavedreplies);
+VNET_DECLARE(struct nfsrvfh, nfs_rootfh);
+VNET_DECLARE(int, nfs_rootfhset);
+
int (*nfsrv3_procs0[NFS_V3NPROCS])(struct nfsrv_descript *,
int, vnode_t , struct nfsexstuff *) = {
(int (*)(struct nfsrv_descript *, int, vnode_t , struct nfsexstuff *))0,
@@ -471,15 +476,15 @@
}
mtx_lock(&nfsrvd_statmtx);
- if (nfsstatsv1.srvstartcnt == nfsstatsv1.srvdonecnt) {
+ if (NFSDSTATS(nfsstatsv1).srvstartcnt == NFSDSTATS(nfsstatsv1).srvdonecnt) {
if (now != NULL)
- nfsstatsv1.busyfrom = *now;
+ NFSDSTATS(nfsstatsv1).busyfrom = *now;
else
- binuptime(&nfsstatsv1.busyfrom);
+ binuptime(&NFSDSTATS(nfsstatsv1).busyfrom);
}
- nfsstatsv1.srvrpccnt[op]++;
- nfsstatsv1.srvstartcnt++;
+ NFSDSTATS(nfsstatsv1).srvrpccnt[op]++;
+ NFSDSTATS(nfsstatsv1).srvstartcnt++;
mtx_unlock(&nfsrvd_statmtx);
}
@@ -502,21 +507,21 @@
mtx_lock(&nfsrvd_statmtx);
- nfsstatsv1.srvbytes[op] += bytes;
- nfsstatsv1.srvops[op]++;
+ NFSDSTATS(nfsstatsv1).srvbytes[op] += bytes;
+ NFSDSTATS(nfsstatsv1).srvops[op]++;
if (then != NULL) {
dt = *now;
bintime_sub(&dt, then);
- bintime_add(&nfsstatsv1.srvduration[op], &dt);
+ bintime_add(&NFSDSTATS(nfsstatsv1).srvduration[op], &dt);
}
dt = *now;
- bintime_sub(&dt, &nfsstatsv1.busyfrom);
- bintime_add(&nfsstatsv1.busytime, &dt);
- nfsstatsv1.busyfrom = *now;
+ bintime_sub(&dt, &NFSDSTATS(nfsstatsv1).busyfrom);
+ bintime_add(&NFSDSTATS(nfsstatsv1).busytime, &dt);
+ NFSDSTATS(nfsstatsv1).busyfrom = *now;
- nfsstatsv1.srvdonecnt++;
+ NFSDSTATS(nfsstatsv1).srvdonecnt++;
mtx_unlock(&nfsrvd_statmtx);
}
@@ -753,7 +758,7 @@
*/
igotlock = 0;
NFSLOCKV4ROOTMUTEX();
- if (nfsrv_stablefirst.nsf_flags & NFSNSF_NEEDLOCK)
+ if (VNET(nfsrv_stablefirst).nsf_flags & NFSNSF_NEEDLOCK)
igotlock = nfsv4_lock(&nfsv4rootfs_lock, 1, NULL,
NFSV4ROOTLOCKMUTEXPTR, NULL);
else
@@ -766,8 +771,8 @@
* Done when the grace period is over or a client has long
* since expired.
*/
- nfsrv_stablefirst.nsf_flags &= ~NFSNSF_NEEDLOCK;
- if ((nfsrv_stablefirst.nsf_flags &
+ VNET(nfsrv_stablefirst).nsf_flags &= ~NFSNSF_NEEDLOCK;
+ if ((VNET(nfsrv_stablefirst).nsf_flags &
(NFSNSF_GRACEOVER | NFSNSF_UPDATEDONE)) == NFSNSF_GRACEOVER)
nfsrv_updatestable(p);
@@ -777,10 +782,10 @@
* stable storage file and then remove them from the client
* list.
*/
- if (nfsrv_stablefirst.nsf_flags & NFSNSF_EXPIREDCLIENT) {
- nfsrv_stablefirst.nsf_flags &= ~NFSNSF_EXPIREDCLIENT;
+ if (VNET(nfsrv_stablefirst).nsf_flags & NFSNSF_EXPIREDCLIENT) {
+ VNET(nfsrv_stablefirst).nsf_flags &= ~NFSNSF_EXPIREDCLIENT;
for (i = 0; i < nfsrv_clienthashsize; i++) {
- LIST_FOREACH_SAFE(clp, &nfsclienthash[i], lc_hash,
+ LIST_FOREACH_SAFE(clp, &VNET(nfsclienthash)[i], lc_hash,
nclp) {
if (clp->lc_flags & LCL_EXPIREIT) {
if (!LIST_EMPTY(&clp->lc_open) ||
@@ -814,7 +819,7 @@
* If flagged, search for open owners that haven't had any opens
* for a long time.
*/
- if (nfsrv_stablefirst.nsf_flags & NFSNSF_NOOPENS) {
+ if (VNET(nfsrv_stablefirst).nsf_flags & NFSNSF_NOOPENS) {
nfsrv_throwawayopens(p);
}
@@ -941,8 +946,8 @@
if (i == 0 && (nd->nd_rp == NULL ||
nd->nd_rp->rc_refcnt == 0) &&
(nfsrv_mallocmget_limit() ||
- nfsrc_tcpsavedreplies > nfsrc_floodlevel)) {
- if (nfsrc_tcpsavedreplies > nfsrc_floodlevel)
+ VNET(nfsrc_tcpsavedreplies) > VNET(nfsrc_floodlevel))) {
+ if (VNET(nfsrc_tcpsavedreplies) > VNET(nfsrc_floodlevel))
printf("nfsd server cache flooded, try "
"increasing vfs.nfsd.tcphighwater\n");
nd->nd_repstat = NFSERR_RESOURCE;
@@ -1033,7 +1038,7 @@
}
break;
case NFSV4OP_PUTROOTFH:
- if (nfs_rootfhset) {
+ if (VNET(nfs_rootfhset)) {
if ((nd->nd_flag & ND_LASTOP) == 0) {
/*
* Pre-parse the next op#. If it is
@@ -1054,7 +1059,7 @@
} while (nextop == NFSV4OP_SAVEFH &&
i < numops - 1);
}
- nfsd_fhtovp(nd, &nfs_rootfh, LK_SHARED, &nvp,
+ nfsd_fhtovp(nd, &VNET(nfs_rootfh), LK_SHARED, &nvp,
&nes, NULL, 0, nextop);
if (!nd->nd_repstat) {
if (vp)
diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c.vnetdcl b/sys/fs/nfsserver/nfs_nfsdstate.c
--- a/sys/fs/nfsserver/nfs_nfsdstate.c.vnetdcl
+++ b/sys/fs/nfsserver/nfs_nfsdstate.c
@@ -35,17 +35,19 @@
#include <sys/extattr.h>
#include <fs/nfs/nfsport.h>
-struct nfsrv_stablefirst nfsrv_stablefirst;
int nfsrv_issuedelegs = 0;
int nfsrv_dolocallocks = 0;
struct nfsv4lock nfsv4rootfs_lock;
time_t nfsdev_time = 0;
int nfsrv_layouthashsize;
volatile int nfsrv_layoutcnt = 0;
-extern uint32_t nfs_srvmaxio;
-extern int newnfs_numnfsd;
-extern struct nfsstatsv1 nfsstatsv1;
+VNET_DEFINE(struct nfsrv_stablefirst, nfsrv_stablefirst);
+
+VNET_DECLARE(int, nfsrv_numnfsd);
+VNET_DECLARE(struct nfsdontlisthead, nfsrv_dontlisthead);
+
+extern uint32_t nfs_srvmaxio;
extern int nfsrv_lease;
extern struct timeval nfsboottime;
extern u_int32_t newnfs_true, newnfs_false;
@@ -59,11 +61,12 @@
extern int nfsrv_maxpnfsmirror;
NFSV4ROOTLOCKMUTEX;
NFSSTATESPINLOCK;
-extern struct nfsdontlisthead nfsrv_dontlisthead;
extern volatile int nfsrv_devidcnt;
extern struct nfslayouthead nfsrv_recalllisthead;
extern char *nfsrv_zeropnfsdat;
+NFSDSTATSDECLARE(nfsstatsv1);
+
SYSCTL_DECL(_vfs_nfsd);
int nfsrv_statehashsize = NFSSTATEHASHSIZE;
SYSCTL_INT(_vfs_nfsd, OID_AUTO, statehashsize, CTLFLAG_RDTUN,
@@ -118,20 +121,22 @@
/*
* Hash lists for nfs V4.
*/
-struct nfsclienthashhead *nfsclienthash;
-struct nfslockhashhead *nfslockhash;
-struct nfssessionhash *nfssessionhash;
+VNET_DEFINE(struct nfsclienthashhead *, nfsclienthash);
+VNET_DEFINE(struct nfslockhashhead *, nfslockhash);
+VNET_DEFINE(struct nfssessionhash *, nfssessionhash);
+VNET_DEFINE(volatile int, nfsrv_dontlistlen) = 0;
+
struct nfslayouthash *nfslayouthash;
-volatile int nfsrv_dontlistlen = 0;
static u_int32_t nfsrv_openpluslock = 0, nfsrv_delegatecnt = 0;
-static time_t nfsrvboottime;
static int nfsrv_returnoldstateid = 0, nfsrv_clients = 0;
static int nfsrv_clienthighwater = NFSRV_CLIENTHIGHWATER;
static int nfsrv_nogsscallback = 0;
static volatile int nfsrv_writedelegcnt = 0;
static int nfsrv_faildscnt;
+VNET_DEFINE_STATIC(time_t, nfsrvboottime);
+
/* local functions */
static void nfsrv_dumpaclient(struct nfsclient *clp,
struct nfsd_dumpclients *dumpp);
@@ -298,7 +303,7 @@
*/
gotit = i = 0;
while (i < nfsrv_clienthashsize && !gotit) {
- LIST_FOREACH(clp, &nfsclienthash[i], lc_hash) {
+ LIST_FOREACH(clp, &VNET(nfsclienthash)[i], lc_hash) {
if (new_clp->lc_idlen == clp->lc_idlen &&
!NFSBCMP(new_clp->lc_id, clp->lc_id, clp->lc_idlen)) {
gotit = 1;
@@ -343,7 +348,7 @@
confirmp->qval = new_clp->lc_confirm.qval =
++confirm_index;
clientidp->lval[0] = new_clp->lc_clientid.lval[0] =
- (u_int32_t)nfsrvboottime;
+ VNET(nfsrvboottime);
clientidp->lval[1] = new_clp->lc_clientid.lval[1] =
nfsrv_nextclientindex();
new_clp->lc_stateindex = 0;
@@ -359,7 +364,7 @@
LIST_INIT(&new_clp->lc_stateid[i]);
LIST_INSERT_HEAD(NFSCLIENTHASH(new_clp->lc_clientid), new_clp,
lc_hash);
- nfsstatsv1.srvclients++;
+ NFSDSTATS(nfsstatsv1).srvclients++;
nfsrv_openpluslock++;
nfsrv_clients++;
NFSLOCKV4ROOTMUTEX();
@@ -457,7 +462,7 @@
confirmp->qval = new_clp->lc_confirm.qval =
++confirm_index;
clientidp->lval[0] = new_clp->lc_clientid.lval[0] =
- nfsrvboottime;
+ VNET(nfsrvboottime);
clientidp->lval[1] = new_clp->lc_clientid.lval[1] =
nfsrv_nextclientindex();
new_clp->lc_stateindex = 0;
@@ -488,7 +493,7 @@
LIST_INIT(&new_clp->lc_session);
LIST_INSERT_HEAD(NFSCLIENTHASH(new_clp->lc_clientid), new_clp,
lc_hash);
- nfsstatsv1.srvclients++;
+ NFSDSTATS(nfsstatsv1).srvclients++;
nfsrv_openpluslock++;
nfsrv_clients++;
NFSLOCKV4ROOTMUTEX();
@@ -553,7 +558,7 @@
LIST_INIT(&new_clp->lc_session);
LIST_INSERT_HEAD(NFSCLIENTHASH(new_clp->lc_clientid), new_clp,
lc_hash);
- nfsstatsv1.srvclients++;
+ NFSDSTATS(nfsstatsv1).srvclients++;
nfsrv_openpluslock++;
nfsrv_clients++;
}
@@ -604,7 +609,7 @@
if (clpp)
*clpp = NULL;
if ((nd == NULL || (nd->nd_flag & ND_NFSV41) == 0 ||
- opflags != CLOPS_RENEW) && nfsrvboottime != clientid.lval[0]) {
+ opflags != CLOPS_RENEW) && VNET(nfsrvboottime) != clientid.lval[0]) {
error = NFSERR_STALECLIENTID;
goto out;
}
@@ -820,7 +825,7 @@
struct nfsclienthashhead *hp;
int error = 0, i, igotlock;
- if (nfsrvboottime != clientid.lval[0]) {
+ if (VNET(nfsrvboottime) != clientid.lval[0]) {
error = NFSERR_STALECLIENTID;
goto out;
}
@@ -912,7 +917,7 @@
*/
gotit = i = 0;
while (i < nfsrv_clienthashsize && !gotit) {
- LIST_FOREACH(clp, &nfsclienthash[i], lc_hash) {
+ LIST_FOREACH(clp, &VNET(nfsclienthash)[i], lc_hash) {
if (revokep->nclid_idlen == clp->lc_idlen &&
!NFSBCMP(revokep->nclid_id, clp->lc_id, clp->lc_idlen)) {
gotit = 1;
@@ -974,8 +979,8 @@
* Rattle through the client lists until done.
*/
while (i < nfsrv_clienthashsize && cnt < maxcnt) {
- clp = LIST_FIRST(&nfsclienthash[i]);
- while (clp != LIST_END(&nfsclienthash[i]) && cnt < maxcnt) {
+ clp = LIST_FIRST(&VNET(nfsclienthash)[i]);
+ while (clp != LIST_END(&VNET(nfsclienthash)[i]) && cnt < maxcnt) {
nfsrv_dumpaclient(clp, &dumpp[cnt]);
cnt++;
clp = LIST_NEXT(clp, lc_hash);
@@ -1251,14 +1256,14 @@
* If server hasn't started yet, just return.
*/
NFSLOCKSTATE();
- if (nfsrv_stablefirst.nsf_eograce == 0) {
+ if (VNET(nfsrv_stablefirst).nsf_eograce == 0) {
NFSUNLOCKSTATE();
return;
}
- if (!(nfsrv_stablefirst.nsf_flags & NFSNSF_UPDATEDONE)) {
- if (!(nfsrv_stablefirst.nsf_flags & NFSNSF_GRACEOVER) &&
- NFSD_MONOSEC > nfsrv_stablefirst.nsf_eograce)
- nfsrv_stablefirst.nsf_flags |=
+ if (!(VNET(nfsrv_stablefirst).nsf_flags & NFSNSF_UPDATEDONE)) {
+ if (!(VNET(nfsrv_stablefirst).nsf_flags & NFSNSF_GRACEOVER) &&
+ NFSD_MONOSEC > VNET(nfsrv_stablefirst).nsf_eograce)
+ VNET(nfsrv_stablefirst).nsf_flags |=
(NFSNSF_GRACEOVER | NFSNSF_NEEDLOCK);
NFSUNLOCKSTATE();
return;
@@ -1281,8 +1286,8 @@
* For each client...
*/
for (i = 0; i < nfsrv_clienthashsize; i++) {
- clp = LIST_FIRST(&nfsclienthash[i]);
- while (clp != LIST_END(&nfsclienthash[i])) {
+ clp = LIST_FIRST(&VNET(nfsclienthash)[i]);
+ while (clp != LIST_END(&VNET(nfsclienthash)[i])) {
nclp = LIST_NEXT(clp, lc_hash);
if (!(clp->lc_flags & LCL_EXPIREIT)) {
if (((clp->lc_expiry + NFSRV_STALELEASE) < NFSD_MONOSEC
@@ -1313,7 +1318,7 @@
* by an nfsd sometime soon.
*/
clp->lc_flags |= LCL_EXPIREIT;
- nfsrv_stablefirst.nsf_flags |=
+ VNET(nfsrv_stablefirst).nsf_flags |=
(NFSNSF_NEEDLOCK | NFSNSF_EXPIREDCLIENT);
} else {
/*
@@ -1331,7 +1336,7 @@
if (stp->ls_noopens > NFSNOOPEN ||
(nfsrv_openpluslock * 2) >
nfsrv_v4statelimit)
- nfsrv_stablefirst.nsf_flags |=
+ VNET(nfsrv_stablefirst).nsf_flags |=
NFSNSF_NOOPENS;
} else {
stp->ls_noopens = 0;
@@ -1397,7 +1402,7 @@
free(clp->lc_stateid, M_NFSDCLIENT);
free(clp, M_NFSDCLIENT);
NFSLOCKSTATE();
- nfsstatsv1.srvclients--;
+ NFSDSTATS(nfsstatsv1).srvclients--;
nfsrv_openpluslock--;
nfsrv_clients--;
NFSUNLOCKSTATE();
@@ -1440,7 +1445,7 @@
nfsv4_testlock(&lfp->lf_locallock_lck) == 0)
nfsrv_freenfslockfile(lfp);
free(stp, M_NFSDSTATE);
- nfsstatsv1.srvdelegates--;
+ NFSDSTATS(nfsstatsv1).srvdelegates--;
nfsrv_openpluslock--;
nfsrv_delegatecnt--;
}
@@ -1466,7 +1471,7 @@
if (stp->ls_op)
nfsrvd_derefcache(stp->ls_op);
free(stp, M_NFSDSTATE);
- nfsstatsv1.srvopenowners--;
+ NFSDSTATS(nfsstatsv1).srvopenowners--;
nfsrv_openpluslock--;
}
@@ -1516,7 +1521,7 @@
if (cansleep != 0)
NFSUNLOCKSTATE();
free(stp, M_NFSDSTATE);
- nfsstatsv1.srvopens--;
+ NFSDSTATS(nfsstatsv1).srvopens--;
nfsrv_openpluslock--;
return (ret);
}
@@ -1535,7 +1540,7 @@
if (stp->ls_op)
nfsrvd_derefcache(stp->ls_op);
free(stp, M_NFSDSTATE);
- nfsstatsv1.srvlockowners--;
+ NFSDSTATS(nfsstatsv1).srvlockowners--;
nfsrv_openpluslock--;
}
@@ -1611,7 +1616,7 @@
if (lop->lo_lckfile.le_prev != NULL) {
LIST_REMOVE(lop, lo_lckfile);
- nfsstatsv1.srvlocks--;
+ NFSDSTATS(nfsstatsv1).srvlocks--;
nfsrv_openpluslock--;
}
LIST_REMOVE(lop, lo_lckowner);
@@ -2388,7 +2393,7 @@
LIST_INSERT_HEAD(&stp->ls_open, new_stp, ls_list);
*new_lopp = NULL;
*new_stpp = NULL;
- nfsstatsv1.srvlockowners++;
+ NFSDSTATS(nfsstatsv1).srvlockowners++;
nfsrv_openpluslock++;
}
if (filestruct_locked != 0) {
@@ -3040,12 +3045,12 @@
LIST_INSERT_HEAD(&new_stp->ls_open, new_open, ls_list);
LIST_INSERT_HEAD(&clp->lc_open, new_stp, ls_list);
*new_stpp = NULL;
- nfsstatsv1.srvopenowners++;
+ NFSDSTATS(nfsstatsv1).srvopenowners++;
nfsrv_openpluslock++;
}
openstp = new_open;
new_open = NULL;
- nfsstatsv1.srvopens++;
+ NFSDSTATS(nfsstatsv1).srvopens++;
nfsrv_openpluslock++;
break;
}
@@ -3106,7 +3111,7 @@
NFSRV_V4DELEGLIMIT(nfsrv_delegatecnt) ||
!NFSVNO_DELEGOK(vp))
*rflagsp |= NFSV4OPEN_RECALL;
- nfsstatsv1.srvdelegates++;
+ NFSDSTATS(nfsstatsv1).srvdelegates++;
nfsrv_openpluslock++;
nfsrv_delegatecnt++;
@@ -3146,12 +3151,12 @@
LIST_INSERT_HEAD(&new_stp->ls_open, new_open, ls_list);
LIST_INSERT_HEAD(&clp->lc_open, new_stp, ls_list);
*new_stpp = NULL;
- nfsstatsv1.srvopenowners++;
+ NFSDSTATS(nfsstatsv1).srvopenowners++;
nfsrv_openpluslock++;
}
openstp = new_open;
new_open = NULL;
- nfsstatsv1.srvopens++;
+ NFSDSTATS(nfsstatsv1).srvopens++;
nfsrv_openpluslock++;
} else {
error = NFSERR_RECLAIMCONFLICT;
@@ -3223,7 +3228,7 @@
new_deleg->ls_stateid), new_deleg, ls_hash);
LIST_INSERT_HEAD(&clp->lc_deleg, new_deleg, ls_list);
new_deleg = NULL;
- nfsstatsv1.srvdelegates++;
+ NFSDSTATS(nfsstatsv1).srvdelegates++;
nfsrv_openpluslock++;
nfsrv_delegatecnt++;
}
@@ -3245,7 +3250,7 @@
new_open, ls_hash);
openstp = new_open;
new_open = NULL;
- nfsstatsv1.srvopens++;
+ NFSDSTATS(nfsstatsv1).srvopens++;
nfsrv_openpluslock++;
/*
@@ -3293,7 +3298,7 @@
new_deleg->ls_stateid), new_deleg, ls_hash);
LIST_INSERT_HEAD(&clp->lc_deleg, new_deleg, ls_list);
new_deleg = NULL;
- nfsstatsv1.srvdelegates++;
+ NFSDSTATS(nfsstatsv1).srvdelegates++;
nfsrv_openpluslock++;
nfsrv_delegatecnt++;
}
@@ -3374,7 +3379,7 @@
LIST_INSERT_HEAD(&clp->lc_deleg, new_deleg,
ls_list);
new_deleg = NULL;
- nfsstatsv1.srvdelegates++;
+ NFSDSTATS(nfsstatsv1).srvdelegates++;
nfsrv_openpluslock++;
nfsrv_delegatecnt++;
}
@@ -3402,9 +3407,9 @@
openstp = new_open;
new_open = NULL;
*new_stpp = NULL;
- nfsstatsv1.srvopens++;
+ NFSDSTATS(nfsstatsv1).srvopens++;
nfsrv_openpluslock++;
- nfsstatsv1.srvopenowners++;
+ NFSDSTATS(nfsstatsv1).srvopenowners++;
nfsrv_openpluslock++;
}
if (!error) {
@@ -3880,7 +3885,7 @@
else
LIST_INSERT_AFTER(insert_lop, new_lop, lo_lckowner);
if (stp != NULL) {
- nfsstatsv1.srvlocks++;
+ NFSDSTATS(nfsstatsv1).srvlocks++;
nfsrv_openpluslock++;
}
}
@@ -4357,11 +4362,11 @@
*/
if (flags &
(NFSLCK_OPEN | NFSLCK_TEST | NFSLCK_RELEASE | NFSLCK_DELEGPURGE)) {
- if (clientid.lval[0] != nfsrvboottime) {
+ if (clientid.lval[0] != VNET(nfsrvboottime)) {
ret = NFSERR_STALECLIENTID;
goto out;
}
- } else if (stateidp->other[0] != nfsrvboottime &&
+ } else if (stateidp->other[0] != VNET(nfsrvboottime) &&
specialid == 0) {
ret = NFSERR_STALESTATEID;
goto out;
@@ -4394,25 +4399,25 @@
int error = 0, notreclaimed;
struct nfsrv_stable *sp;
- if ((nfsrv_stablefirst.nsf_flags & (NFSNSF_UPDATEDONE |
+ if ((VNET(nfsrv_stablefirst).nsf_flags & (NFSNSF_UPDATEDONE |
NFSNSF_GRACEOVER)) == 0) {
/*
* First, check to see if all of the clients have done a
* ReclaimComplete. If so, grace can end now.
*/
notreclaimed = 0;
- LIST_FOREACH(sp, &nfsrv_stablefirst.nsf_head, nst_list) {
+ LIST_FOREACH(sp, &VNET(nfsrv_stablefirst).nsf_head, nst_list) {
if ((sp->nst_flag & NFSNST_RECLAIMED) == 0) {
notreclaimed = 1;
break;
}
}
if (notreclaimed == 0)
- nfsrv_stablefirst.nsf_flags |= (NFSNSF_GRACEOVER |
+ VNET(nfsrv_stablefirst).nsf_flags |= (NFSNSF_GRACEOVER |
NFSNSF_NEEDLOCK);
}
- if ((nfsrv_stablefirst.nsf_flags & NFSNSF_GRACEOVER) != 0) {
+ if ((VNET(nfsrv_stablefirst).nsf_flags & NFSNSF_GRACEOVER) != 0) {
if (flags & NFSLCK_RECLAIM) {
error = NFSERR_NOGRACE;
goto out;
@@ -4434,8 +4439,8 @@
* extend grace a bit.
*/
if ((NFSD_MONOSEC + NFSRV_LEASEDELTA) >
- nfsrv_stablefirst.nsf_eograce)
- nfsrv_stablefirst.nsf_eograce = NFSD_MONOSEC +
+ VNET(nfsrv_stablefirst).nsf_eograce)
+ VNET(nfsrv_stablefirst).nsf_eograce = NFSD_MONOSEC +
NFSRV_LEASEDELTA;
}
@@ -4870,7 +4875,7 @@
void
nfsrv_setupstable(NFSPROC_T *p)
{
- struct nfsrv_stablefirst *sf = &nfsrv_stablefirst;
+ struct nfsrv_stablefirst *sf = &VNET(nfsrv_stablefirst);
struct nfsrv_stable *sp, *nsp;
struct nfst_rec *tsp;
int error, i, tryagain;
@@ -4886,7 +4891,7 @@
/*
* Set Grace over just until the file reads successfully.
*/
- nfsrvboottime = time_second;
+ VNET(nfsrvboottime) = time_second;
LIST_INIT(&sf->nsf_head);
sf->nsf_flags = (NFSNSF_GRACEOVER | NFSNSF_NEEDLOCK);
sf->nsf_eograce = NFSD_MONOSEC + NFSRV_LEASEDELTA;
@@ -4903,7 +4908,7 @@
* Now, read in the boottimes.
*/
sf->nsf_bootvals = (time_t *)malloc((sf->nsf_numboots + 1) *
- sizeof (time_t), M_TEMP, M_WAITOK);
+ sizeof(time_t), M_TEMP, M_WAITOK);
off = sizeof (struct nfsf_rec);
error = NFSD_RDWR(UIO_READ, NFSFPVNODE(sf->nsf_fp),
(caddr_t)sf->nsf_bootvals, sf->nsf_numboots * sizeof (time_t), off,
@@ -4921,8 +4926,8 @@
do {
tryagain = 0;
for (i = 0; i < sf->nsf_numboots; i++) {
- if (nfsrvboottime == sf->nsf_bootvals[i]) {
- nfsrvboottime++;
+ if (VNET(nfsrvboottime) == sf->nsf_bootvals[i]) {
+ VNET(nfsrvboottime)++;
tryagain = 1;
break;
}
@@ -5005,7 +5010,7 @@
void
nfsrv_updatestable(NFSPROC_T *p)
{
- struct nfsrv_stablefirst *sf = &nfsrv_stablefirst;
+ struct nfsrv_stablefirst *sf = &VNET(nfsrv_stablefirst);
struct nfsrv_stable *sp, *nsp;
int i;
struct nfsvattr nva;
@@ -5031,10 +5036,10 @@
sf->nsf_bootvals[i + 1] = sf->nsf_bootvals[i];
} else {
sf->nsf_numboots = 1;
- sf->nsf_bootvals = (time_t *)malloc(sizeof (time_t),
+ sf->nsf_bootvals = (time_t *)malloc(sizeof(time_t),
M_TEMP, M_WAITOK);
}
- sf->nsf_bootvals[0] = nfsrvboottime;
+ sf->nsf_bootvals[0] = VNET(nfsrvboottime);
sf->nsf_lease = nfsrv_lease;
NFSVNO_ATTRINIT(&nva);
NFSVNO_SETATTRVAL(&nva, size, 0);
@@ -5088,7 +5093,7 @@
void
nfsrv_writestable(u_char *client, int len, int flag, NFSPROC_T *p)
{
- struct nfsrv_stablefirst *sf = &nfsrv_stablefirst;
+ struct nfsrv_stablefirst *sf = &VNET(nfsrv_stablefirst);
struct nfst_rec *sp;
int error;
@@ -5121,12 +5126,12 @@
/*
* First find the client structure.
*/
- LIST_FOREACH(sp, &nfsrv_stablefirst.nsf_head, nst_list) {
+ LIST_FOREACH(sp, &VNET(nfsrv_stablefirst).nsf_head, nst_list) {
if (sp->nst_len == clp->lc_idlen &&
!NFSBCMP(sp->nst_client, clp->lc_id, sp->nst_len))
break;
}
- if (sp == LIST_END(&nfsrv_stablefirst.nsf_head))
+ if (sp == LIST_END(&VNET(nfsrv_stablefirst).nsf_head))
return;
/*
@@ -5148,12 +5153,12 @@
/*
* First find the client structure.
*/
- LIST_FOREACH(sp, &nfsrv_stablefirst.nsf_head, nst_list) {
+ LIST_FOREACH(sp, &VNET(nfsrv_stablefirst).nsf_head, nst_list) {
if (sp->nst_len == clp->lc_idlen &&
!NFSBCMP(sp->nst_client, clp->lc_id, sp->nst_len))
break;
}
- if (sp == LIST_END(&nfsrv_stablefirst.nsf_head))
+ if (sp == LIST_END(&VNET(nfsrv_stablefirst).nsf_head))
return;
/*
@@ -5174,7 +5179,7 @@
/*
* First, find the entry for the client.
*/
- LIST_FOREACH(sp, &nfsrv_stablefirst.nsf_head, nst_list) {
+ LIST_FOREACH(sp, &VNET(nfsrv_stablefirst).nsf_head, nst_list) {
if (sp->nst_len == clp->lc_idlen &&
!NFSBCMP(sp->nst_client, clp->lc_id, sp->nst_len))
break;
@@ -5184,9 +5189,9 @@
* If not in the list, state was revoked or no state was issued
* since the previous reboot, a reclaim is denied.
*/
- if (sp == LIST_END(&nfsrv_stablefirst.nsf_head) ||
+ if (sp == LIST_END(&VNET(nfsrv_stablefirst).nsf_head) ||
(sp->nst_flag & NFSNST_REVOKE) ||
- !(nfsrv_stablefirst.nsf_flags & NFSNSF_OK))
+ !(VNET(nfsrv_stablefirst).nsf_flags & NFSNSF_OK))
return (1);
return (0);
}
@@ -5214,7 +5219,7 @@
* If lease hasn't expired, we can't fix it.
*/
if (clp->lc_expiry >= NFSD_MONOSEC ||
- !(nfsrv_stablefirst.nsf_flags & NFSNSF_UPDATEDONE))
+ !(VNET(nfsrv_stablefirst).nsf_flags & NFSNSF_UPDATEDONE))
return (0);
if (*haslockp == 0) {
NFSUNLOCKSTATE();
@@ -5613,7 +5618,7 @@
* First, check to see if the server is currently running and it has
* been called for a regular file when issuing delegations.
*/
- if (newnfs_numnfsd == 0 || vp->v_type != VREG ||
+ if (VNET(nfsrv_numnfsd) == 0 || vp->v_type != VREG ||
nfsrv_issuedelegs == 0)
return;
@@ -5847,12 +5852,12 @@
int i;
NFSLOCKSTATE();
- nfsrv_stablefirst.nsf_flags &= ~NFSNSF_NOOPENS;
+ VNET(nfsrv_stablefirst).nsf_flags &= ~NFSNSF_NOOPENS;
/*
* For each client...
*/
for (i = 0; i < nfsrv_clienthashsize; i++) {
- LIST_FOREACH_SAFE(clp, &nfsclienthash[i], lc_hash, nclp) {
+ LIST_FOREACH_SAFE(clp, &VNET(nfsclienthash)[i], lc_hash, nclp) {
LIST_FOREACH_SAFE(stp, &clp->lc_open, ls_list, nstp) {
if (LIST_EMPTY(&stp->ls_open) &&
(stp->ls_noopens > NFSNOOPEN ||
@@ -5908,7 +5913,7 @@
nfsrv_leaseexpiry(void)
{
- if (nfsrv_stablefirst.nsf_eograce > NFSD_MONOSEC)
+ if (VNET(nfsrv_stablefirst).nsf_eograce > NFSD_MONOSEC)
return (NFSD_MONOSEC + 2 * (nfsrv_lease + NFSRV_LEASEDELTA));
return (NFSD_MONOSEC + nfsrv_lease + NFSRV_LEASEDELTA);
}
@@ -6229,7 +6234,7 @@
* For each client, clean out the state and then free the structure.
*/
for (i = 0; i < nfsrv_clienthashsize; i++) {
- LIST_FOREACH_SAFE(clp, &nfsclienthash[i], lc_hash, nclp) {
+ LIST_FOREACH_SAFE(clp, &VNET(nfsclienthash)[i], lc_hash, nclp) {
nfsrv_cleanclient(clp, p);
nfsrv_freedeleglist(&clp->lc_deleg);
nfsrv_freedeleglist(&clp->lc_olddeleg);
@@ -6242,7 +6247,7 @@
* Also, free up any remaining lock file structures.
*/
for (i = 0; i < nfsrv_lockhashsize; i++) {
- LIST_FOREACH_SAFE(lfp, &nfslockhash[i], lf_hash, nlfp) {
+ LIST_FOREACH_SAFE(lfp, &VNET(nfslockhash)[i], lf_hash, nlfp) {
printf("nfsd unload: fnd a lock file struct\n");
nfsrv_freenfslockfile(lfp);
}
@@ -6360,7 +6365,7 @@
sep = nfsrv_findsession(nd->nd_sessionid);
if (sep == NULL) {
NFSUNLOCKSESSION(shp);
- if ((nfsrv_stablefirst.nsf_flags & NFSNSF_GRACEOVER) != 0) {
+ if ((VNET(nfsrv_stablefirst).nsf_flags & NFSNSF_GRACEOVER) != 0) {
buf = malloc(INET6_ADDRSTRLEN, M_TEMP, M_WAITOK);
switch (nd->nd_nam->sa_family) {
#ifdef INET
@@ -6722,7 +6727,7 @@
int i;
for (i = 0; i < nfsrv_clienthashsize; i++) {
- LIST_FOREACH(clp, &nfsclienthash[i], lc_hash) {
+ LIST_FOREACH(clp, &VNET(nfsclienthash)[i], lc_hash) {
LIST_FOREACH(sep, &clp->lc_session, sess_list) {
xprt = sep->sess_cbsess.nfsess_xprt;
sep->sess_cbsess.nfsess_xprt = NULL;
@@ -7438,7 +7443,7 @@
/* Insert the new layout in the lists. */
*lypp = NULL;
atomic_add_int(&nfsrv_layoutcnt, 1);
- nfsstatsv1.srvlayouts++;
+ NFSDSTATS(nfsstatsv1).srvlayouts++;
NFSBCOPY(lyp->lay_xdr, layp, lyp->lay_layoutlen);
*layoutlenp = lyp->lay_layoutlen;
TAILQ_INSERT_HEAD(&lhyp->list, lyp, lay_list);
@@ -7531,7 +7536,7 @@
NFSD_DEBUG(4, "Freelayout=%p\n", lyp);
atomic_add_int(&nfsrv_layoutcnt, -1);
- nfsstatsv1.srvlayouts--;
+ NFSDSTATS(nfsstatsv1).srvlayouts--;
TAILQ_REMOVE(lhp, lyp, lay_list);
free(lyp, M_NFSDSTATE);
}
@@ -7586,10 +7591,10 @@
nfsrv_freealllayouts();
/* Get rid of any nfsdontlist entries. */
- LIST_FOREACH_SAFE(mrp, &nfsrv_dontlisthead, nfsmr_list, nmrp)
+ LIST_FOREACH_SAFE(mrp, &VNET(nfsrv_dontlisthead), nfsmr_list, nmrp)
free(mrp, M_NFSDSTATE);
- LIST_INIT(&nfsrv_dontlisthead);
- nfsrv_dontlistlen = 0;
+ LIST_INIT(&VNET(nfsrv_dontlisthead));
+ VNET(nfsrv_dontlistlen) = 0;
/* Free layouts in the recall list. */
TAILQ_FOREACH_SAFE(lyp, &nfsrv_recalllisthead, lay_list, nlyp)
@@ -8229,11 +8234,11 @@
struct nfsdontlist *mrp;
int ret;
- if (nfsrv_dontlistlen == 0)
+ if (VNET(nfsrv_dontlistlen) == 0)
return (0);
ret = 0;
NFSDDONTLISTLOCK();
- LIST_FOREACH(mrp, &nfsrv_dontlisthead, nfsmr_list) {
+ LIST_FOREACH(mrp, &VNET(nfsrv_dontlisthead), nfsmr_list) {
if (NFSBCMP(fhp, &mrp->nfsmr_fh, sizeof(*fhp)) == 0 &&
(mrp->nfsmr_flags & NFSMR_DONTLAYOUT) != 0) {
ret = 1;
@@ -8307,15 +8312,15 @@
nmrp->nfsmr_flags = NFSMR_DONTLAYOUT;
NFSBCOPY(&fh, &nmrp->nfsmr_fh, sizeof(fh));
NFSDDONTLISTLOCK();
- LIST_FOREACH(mrp, &nfsrv_dontlisthead, nfsmr_list) {
+ LIST_FOREACH(mrp, &VNET(nfsrv_dontlisthead), nfsmr_list) {
if (NFSBCMP(&fh, &mrp->nfsmr_fh, sizeof(fh)) == 0)
break;
}
if (mrp == NULL) {
- LIST_INSERT_HEAD(&nfsrv_dontlisthead, nmrp, nfsmr_list);
+ LIST_INSERT_HEAD(&VNET(nfsrv_dontlisthead), nmrp, nfsmr_list);
mrp = nmrp;
nmrp = NULL;
- nfsrv_dontlistlen++;
+ VNET(nfsrv_dontlistlen)++;
NFSD_DEBUG(4, "nfsrv_copymr: in dontlist\n");
} else {
NFSDDONTLISTUNLOCK();
diff --git a/sys/fs/nfsserver/nfs_nfsdsubs.c.vnetdcl b/sys/fs/nfsserver/nfs_nfsdsubs.c
--- a/sys/fs/nfsserver/nfs_nfsdsubs.c.vnetdcl
+++ b/sys/fs/nfsserver/nfs_nfsdsubs.c
@@ -44,20 +44,23 @@
#include <fs/nfs/nfsport.h>
extern u_int32_t newnfs_true, newnfs_false;
-extern int nfs_rootfhset;
extern int nfs_pubfhset;
-extern struct nfsclienthashhead *nfsclienthash;
extern int nfsrv_clienthashsize;
-extern struct nfslockhashhead *nfslockhash;
extern int nfsrv_lockhashsize;
-extern struct nfssessionhash *nfssessionhash;
extern int nfsrv_sessionhashsize;
extern int nfsrv_useacl;
extern uid_t nfsrv_defaultuid;
extern gid_t nfsrv_defaultgid;
+VNET_DECLARE(struct nfsclienthashhead *, nfsclienthash);
+VNET_DECLARE(struct nfslockhashhead *, nfslockhash);
+VNET_DECLARE(struct nfssessionhash *, nfssessionhash);
+VNET_DECLARE(int, nfs_rootfhset);
+
+VNET_DEFINE(struct nfsdontlisthead, nfsrv_dontlisthead);
+
+
char nfs_v2pubfh[NFSX_V2FH];
-struct nfsdontlisthead nfsrv_dontlisthead;
struct nfslayouthead nfsrv_recalllisthead;
static nfstype newnfsv2_type[9] = { NFNON, NFREG, NFDIR, NFBLK, NFCHR, NFLNK,
NFNON, NFCHR, NFNON };
@@ -2080,31 +2083,27 @@
nfsd_init(void)
{
int i;
- static int inited = 0;
- if (inited)
- return;
- inited = 1;
/*
* Initialize client queues. Don't free/reinitialize
* them when nfsds are restarted.
*/
- nfsclienthash = malloc(sizeof(struct nfsclienthashhead) *
+ VNET(nfsclienthash) = malloc(sizeof(struct nfsclienthashhead) *
nfsrv_clienthashsize, M_NFSDCLIENT, M_WAITOK | M_ZERO);
for (i = 0; i < nfsrv_clienthashsize; i++)
- LIST_INIT(&nfsclienthash[i]);
- nfslockhash = malloc(sizeof(struct nfslockhashhead) *
+ LIST_INIT(&VNET(nfsclienthash)[i]);
+ VNET(nfslockhash) = malloc(sizeof(struct nfslockhashhead) *
nfsrv_lockhashsize, M_NFSDLOCKFILE, M_WAITOK | M_ZERO);
for (i = 0; i < nfsrv_lockhashsize; i++)
- LIST_INIT(&nfslockhash[i]);
- nfssessionhash = malloc(sizeof(struct nfssessionhash) *
+ LIST_INIT(&VNET(nfslockhash)[i]);
+ VNET(nfssessionhash) = malloc(sizeof(struct nfssessionhash) *
nfsrv_sessionhashsize, M_NFSDSESSION, M_WAITOK | M_ZERO);
for (i = 0; i < nfsrv_sessionhashsize; i++) {
- mtx_init(&nfssessionhash[i].mtx, "nfssm", NULL, MTX_DEF);
- LIST_INIT(&nfssessionhash[i].list);
+ mtx_init(&VNET(nfssessionhash)[i].mtx, "nfssm", NULL, MTX_DEF);
+ LIST_INIT(&VNET(nfssessionhash)[i].list);
}
- LIST_INIT(&nfsrv_dontlisthead);
+ LIST_INIT(&VNET(nfsrv_dontlisthead));
TAILQ_INIT(&nfsrv_recalllisthead);
/* and the v2 pubfh should be all zeros */
@@ -2119,7 +2118,7 @@
nfsd_checkrootexp(struct nfsrv_descript *nd)
{
- if (nfs_rootfhset == 0)
+ if (VNET(nfs_rootfhset) == 0)
return (NFSERR_AUTHERR | AUTH_FAILED);
if ((nd->nd_flag & (ND_GSS | ND_EXAUTHSYS)) == ND_EXAUTHSYS)
goto checktls;
diff --git a/sys/kern/kern_jail.c.vnet b/sys/kern/kern_jail.c
--- a/sys/kern/kern_jail.c.vnet
+++ b/sys/kern/kern_jail.c
@@ -218,6 +218,7 @@
{"allow.unprivileged_proc_debug", "allow.nounprivileged_proc_debug",
PR_ALLOW_UNPRIV_DEBUG},
{"allow.suser", "allow.nosuser", PR_ALLOW_SUSER},
+ {"allow.nfsd", "allow.nonfsd", PR_ALLOW_NFSD},
};
static unsigned pr_allow_all = PR_ALLOW_ALL_STATIC;
const size_t pr_flag_allow_size = sizeof(pr_flag_allow);
@@ -3464,6 +3465,29 @@
}
/*
+ * For mountd/nfsd to run within a prison, it must be:
+ * - A vnet prison.
+ * - PR_ALLOW_NFSD must be set on it.
+ * - The root directory (pr_root) of the prison must be
+ * a file system mount point, so the mountd can hang
+ * export information on it.
+ */
+bool
+prison_check_nfsd(struct ucred *cred)
+{
+
+ if (!jailed(cred))
+ return (false);
+ if (jailed_without_vnet(cred))
+ return (false);
+ if (!prison_allow(cred, PR_ALLOW_NFSD))
+ return (false);
+ if ((cred->cr_prison->pr_root->v_vflag & VV_ROOT) == 0)
+ return (false);
+ return (true);
+}
+
+/*
* Return 1 if p2 is a child of p1, otherwise 0.
*/
int
@@ -3717,11 +3741,15 @@
* is only granted conditionally in the legacy jail case.
*/
switch (priv) {
-#ifdef notyet
/*
* NFS-specific privileges.
*/
case PRIV_NFS_DAEMON:
+ case PRIV_VFS_GETFH:
+ if ((cred->cr_prison->pr_allow & PR_ALLOW_NFSD) == 0 ||
+ (cred->cr_prison->pr_root->v_vflag & VV_ROOT) == 0)
+ return (EPERM);
+#ifdef notyet
case PRIV_NFS_LOCKD:
#endif
/*
@@ -4472,6 +4500,8 @@
"B", "Unprivileged processes may use process debugging facilities");
SYSCTL_JAIL_PARAM(_allow, suser, CTLTYPE_INT | CTLFLAG_RW,
"B", "Processes in jail with uid 0 have privilege");
+SYSCTL_JAIL_PARAM(_allow, nfsd, CTLTYPE_INT | CTLFLAG_RW,
+ "B", "mountd/nfsd may run in the jail");
SYSCTL_JAIL_PARAM_SUBNODE(allow, mount, "Jail mount/unmount permission flags");
SYSCTL_JAIL_PARAM(_allow_mount, , CTLTYPE_INT | CTLFLAG_RW,
diff --git a/sys/kern/vfs_mount.c.vnetmnt b/sys/kern/vfs_mount.c
--- a/sys/kern/vfs_mount.c.vnetmnt
+++ b/sys/kern/vfs_mount.c
@@ -924,7 +924,14 @@
fsflags |= MNT_SYNCHRONOUS;
else if (strcmp(opt->name, "union") == 0)
fsflags |= MNT_UNION;
- else if (strcmp(opt->name, "automounted") == 0) {
+ else if (strcmp(opt->name, "export") == 0) {
+ /*
+ * Set MNT_EXPORTED for the specific case of a
+ * vnet jailed call with the "export" option,
+ * so that mountd can run within that jail.
+ */
+ fsflags |= MNT_EXPORTED;
+ } else if (strcmp(opt->name, "automounted") == 0) {
fsflags |= MNT_AUTOMOUNTED;
do_freeopt = 1;
} else if (strcmp(opt->name, "nocover") == 0) {
@@ -1285,7 +1292,14 @@
* Only privileged root, or (if MNT_USER is set) the user that
* did the original mount is permitted to update it.
*/
- error = vfs_suser(mp, td);
+ if ((fsflags & MNT_EXPORTED) != 0 && prison_check_nfsd(td->td_ucred)) {
+ /* For mountd running in a prison, just check uid == 0. */
+ error = 0;
+ if (td->td_ucred->cr_uid != 0)
+ error = EPERM;
+ } else {
+ error = vfs_suser(mp, td);
+ }
if (error != 0) {
vput(vp);
return (error);
@@ -1330,7 +1344,9 @@
* XXX The final recipients of VFS_MOUNT just overwrite the ndp they
* get. No freeing of cn_pnbuf.
*/
- error = VFS_MOUNT(mp);
+ error = 0;
+ if ((fsflags & MNT_EXPORTED) == 0 || !prison_check_nfsd(td->td_ucred))
+ error = VFS_MOUNT(mp);
export_error = 0;
/* Process the export option. */
@@ -1485,18 +1501,31 @@
if (strlen(fstype) >= MFSNAMELEN || strlen(fspath) >= MNAMELEN)
return (ENAMETOOLONG);
- if (jailed(td->td_ucred) || usermount == 0) {
- if ((error = priv_check(td, PRIV_VFS_MOUNT)) != 0)
- return (error);
- }
-
/*
* Do not allow NFS export or MNT_SUIDDIR by unprivileged users.
*/
- if (fsflags & MNT_EXPORTED) {
- error = priv_check(td, PRIV_VFS_MOUNT_EXPORTED);
+ if ((fsflags & MNT_EXPORTED) != 0 && prison_check_nfsd(td->td_ucred)) {
+ error = priv_check(td, PRIV_NFS_DAEMON);
+printf("priv_nfs_daemon=%d\n", error);
if (error)
return (error);
+ } else {
+ if (jailed(td->td_ucred) || usermount == 0) {
+ if ((error = priv_check(td, PRIV_VFS_MOUNT)) != 0)
+ return (error);
+ }
+
+#ifdef notnow
+ /*
+ * This test was never done before the nfsd in a vnet
+ * prison patch, since MNT_EXPORTED was never set.
+ */
+ if (fsflags & MNT_EXPORTED) {
+ error = priv_check(td, PRIV_VFS_MOUNT_EXPORTED);
+ if (error)
+ return (error);
+ }
+#endif
}
if (fsflags & MNT_SUIDDIR) {
error = priv_check(td, PRIV_VFS_MOUNT_SUIDDIR);
diff --git a/sys/nfs/nfs_nfssvc.c.vnet b/sys/nfs/nfs_nfssvc.c
--- a/sys/nfs/nfs_nfssvc.c.vnet
+++ b/sys/nfs/nfs_nfssvc.c
@@ -43,6 +43,7 @@
#include <sys/sysproto.h>
#include <sys/kernel.h>
#include <sys/sysctl.h>
+#include <sys/jail.h>
#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/lock.h>
@@ -52,6 +53,8 @@
#include <sys/syscall.h>
#include <sys/sysproto.h>
+#include <net/vnet.h>
+
#include <security/audit/audit.h>
#include <nfs/nfssvc.h>
@@ -90,6 +93,9 @@
if (error != 0)
return (error);
}
+
+ CURVNET_SET(TD_TO_VNET(td));
+
error = EINVAL;
if ((uap->flag & (NFSSVC_ADDSOCK | NFSSVC_OLDNFSD | NFSSVC_NFSD)) &&
nfsd_call_nfsserver != NULL)
@@ -111,6 +117,7 @@
error = (*nfsd_call_nfsd)(td, uap);
if (error == EINTR || error == ERESTART)
error = 0;
+ CURVNET_RESTORE();
return (error);
}
diff --git a/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c.vnet b/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c
--- a/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c.vnet
+++ b/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c
@@ -478,7 +478,7 @@
cr->cr_uid = cr->cr_ruid = cr->cr_svuid = uc->uid;
cr->cr_rgid = cr->cr_svgid = uc->gid;
crsetgroups(cr, uc->gidlen, uc->gidlist);
- cr->cr_prison = &prison0;
+ cr->cr_prison = curthread->td_ucred->cr_prison;
prison_hold(cr->cr_prison);
*crp = crhold(cr);
diff --git a/sys/rpc/svc.c.vnetdcl b/sys/rpc/svc.c
--- a/sys/rpc/svc.c.vnetdcl
+++ b/sys/rpc/svc.c
@@ -125,53 +125,55 @@
pool->sp_space_high = (u_long)nmbclusters * MCLBYTES / 4;
pool->sp_space_low = (pool->sp_space_high / 3) * 2;
- sysctl_ctx_init(&pool->sp_sysctl);
- if (sysctl_base) {
- SYSCTL_ADD_PROC(&pool->sp_sysctl, sysctl_base, OID_AUTO,
- "minthreads", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
- pool, 0, svcpool_minthread_sysctl, "I",
- "Minimal number of threads");
- SYSCTL_ADD_PROC(&pool->sp_sysctl, sysctl_base, OID_AUTO,
- "maxthreads", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
- pool, 0, svcpool_maxthread_sysctl, "I",
- "Maximal number of threads");
- SYSCTL_ADD_PROC(&pool->sp_sysctl, sysctl_base, OID_AUTO,
- "threads", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE,
- pool, 0, svcpool_threads_sysctl, "I",
- "Current number of threads");
- SYSCTL_ADD_INT(&pool->sp_sysctl, sysctl_base, OID_AUTO,
- "groups", CTLFLAG_RD, &pool->sp_groupcount, 0,
- "Number of thread groups");
-
- SYSCTL_ADD_ULONG(&pool->sp_sysctl, sysctl_base, OID_AUTO,
- "request_space_used", CTLFLAG_RD,
- &pool->sp_space_used,
- "Space in parsed but not handled requests.");
-
- SYSCTL_ADD_ULONG(&pool->sp_sysctl, sysctl_base, OID_AUTO,
- "request_space_used_highest", CTLFLAG_RD,
- &pool->sp_space_used_highest,
- "Highest space used since reboot.");
-
- SYSCTL_ADD_ULONG(&pool->sp_sysctl, sysctl_base, OID_AUTO,
- "request_space_high", CTLFLAG_RW,
- &pool->sp_space_high,
- "Maximum space in parsed but not handled requests.");
-
- SYSCTL_ADD_ULONG(&pool->sp_sysctl, sysctl_base, OID_AUTO,
- "request_space_low", CTLFLAG_RW,
- &pool->sp_space_low,
- "Low water mark for request space.");
-
- SYSCTL_ADD_INT(&pool->sp_sysctl, sysctl_base, OID_AUTO,
- "request_space_throttled", CTLFLAG_RD,
- &pool->sp_space_throttled, 0,
- "Whether nfs requests are currently throttled");
-
- SYSCTL_ADD_INT(&pool->sp_sysctl, sysctl_base, OID_AUTO,
- "request_space_throttle_count", CTLFLAG_RD,
- &pool->sp_space_throttle_count, 0,
- "Count of times throttling based on request space has occurred");
+ if (IS_DEFAULT_VNET(curvnet)) {
+ sysctl_ctx_init(&pool->sp_sysctl);
+ if (sysctl_base) {
+ SYSCTL_ADD_PROC(&pool->sp_sysctl, sysctl_base, OID_AUTO,
+ "minthreads", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
+ pool, 0, svcpool_minthread_sysctl, "I",
+ "Minimal number of threads");
+ SYSCTL_ADD_PROC(&pool->sp_sysctl, sysctl_base, OID_AUTO,
+ "maxthreads", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
+ pool, 0, svcpool_maxthread_sysctl, "I",
+ "Maximal number of threads");
+ SYSCTL_ADD_PROC(&pool->sp_sysctl, sysctl_base, OID_AUTO,
+ "threads", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE,
+ pool, 0, svcpool_threads_sysctl, "I",
+ "Current number of threads");
+ SYSCTL_ADD_INT(&pool->sp_sysctl, sysctl_base, OID_AUTO,
+ "groups", CTLFLAG_RD, &pool->sp_groupcount, 0,
+ "Number of thread groups");
+
+ SYSCTL_ADD_ULONG(&pool->sp_sysctl, sysctl_base, OID_AUTO,
+ "request_space_used", CTLFLAG_RD,
+ &pool->sp_space_used,
+ "Space in parsed but not handled requests.");
+
+ SYSCTL_ADD_ULONG(&pool->sp_sysctl, sysctl_base, OID_AUTO,
+ "request_space_used_highest", CTLFLAG_RD,
+ &pool->sp_space_used_highest,
+ "Highest space used since reboot.");
+
+ SYSCTL_ADD_ULONG(&pool->sp_sysctl, sysctl_base, OID_AUTO,
+ "request_space_high", CTLFLAG_RW,
+ &pool->sp_space_high,
+ "Maximum space in parsed but not handled requests.");
+
+ SYSCTL_ADD_ULONG(&pool->sp_sysctl, sysctl_base, OID_AUTO,
+ "request_space_low", CTLFLAG_RW,
+ &pool->sp_space_low,
+ "Low water mark for request space.");
+
+ SYSCTL_ADD_INT(&pool->sp_sysctl, sysctl_base, OID_AUTO,
+ "request_space_throttled", CTLFLAG_RD,
+ &pool->sp_space_throttled, 0,
+ "Whether nfs requests are currently throttled");
+
+ SYSCTL_ADD_INT(&pool->sp_sysctl, sysctl_base, OID_AUTO,
+ "request_space_throttle_count", CTLFLAG_RD,
+ &pool->sp_space_throttle_count, 0,
+ "Count of times throttling based on request space has occurred");
+ }
}
return pool;
diff --git a/sys/rpc/svc_auth.c.vnet b/sys/rpc/svc_auth.c
--- a/sys/rpc/svc_auth.c.vnet
+++ b/sys/rpc/svc_auth.c
@@ -197,7 +197,7 @@
cr->cr_uid = cr->cr_ruid = cr->cr_svuid = xprt->xp_uid;
crsetgroups(cr, xprt->xp_ngrps, xprt->xp_gidp);
cr->cr_rgid = cr->cr_svgid = xprt->xp_gidp[0];
- cr->cr_prison = &prison0;
+ cr->cr_prison = curthread->td_ucred->cr_prison;
prison_hold(cr->cr_prison);
*crp = cr;
return (TRUE);
@@ -210,7 +210,7 @@
cr->cr_uid = cr->cr_ruid = cr->cr_svuid = xcr->cr_uid;
crsetgroups(cr, xcr->cr_ngroups, xcr->cr_groups);
cr->cr_rgid = cr->cr_svgid = cr->cr_groups[0];
- cr->cr_prison = &prison0;
+ cr->cr_prison = curthread->td_ucred->cr_prison;
prison_hold(cr->cr_prison);
*crp = cr;
return (TRUE);
diff --git a/sys/rpc/svc_dg.c.vnet b/sys/rpc/svc_dg.c
--- a/sys/rpc/svc_dg.c.vnet
+++ b/sys/rpc/svc_dg.c
@@ -45,6 +45,7 @@
*/
#include <sys/param.h>
+#include <sys/jail.h>
#include <sys/lock.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
@@ -104,6 +105,8 @@
struct sockaddr* sa;
int error;
+ if (jailed(curthread->td_ucred))
+ return (NULL);
if (!__rpc_socket2sockinfo(so, &si)) {
printf(svc_dg_str, svc_dg_err1);
return (NULL);
diff --git a/sys/sys/jail.h.vnet b/sys/sys/jail.h
--- a/sys/sys/jail.h.vnet
+++ b/sys/sys/jail.h
@@ -253,7 +253,8 @@
#define PR_ALLOW_SUSER 0x00000400
#define PR_ALLOW_RESERVED_PORTS 0x00008000
#define PR_ALLOW_KMEM_ACCESS 0x00010000 /* reserved, not used yet */
-#define PR_ALLOW_ALL_STATIC 0x000187ff
+#define PR_ALLOW_NFSD 0x00020000
+#define PR_ALLOW_ALL_STATIC 0x000387ff
/*
* PR_ALLOW_DIFFERENCES determines which flags are able to be
@@ -420,6 +421,7 @@
void prison0_init(void);
int prison_allow(struct ucred *, unsigned);
int prison_check(struct ucred *cred1, struct ucred *cred2);
+bool prison_check_nfsd(struct ucred *cred);
int prison_owns_vnet(struct ucred *);
int prison_canseemount(struct ucred *cred, struct mount *mp);
void prison_enforce_statfs(struct ucred *cred, struct mount *mp,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Jan 27, 6:27 PM (6 h, 55 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16204471
Default Alt Text
D37519.id113805.diff (92 KB)
Attached To
Mode
D37519: modify the nfsd so that it can be run in a vnet prison
Attached
Detach File
Event Timeline
Log In to Comment