Add an nfssvc() option to the kernel for the new NFS client

which dumps out the actual options being used by an NFS mount.
This will be used to implement a "-m" option for nfsstat(1).

Reviewed by:	alfred
MFC after:	2 weeks
This commit is contained in:
Rick Macklem 2012-12-02 01:16:04 +00:00
parent 5e184962dd
commit 99d2727d67
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=243782
5 changed files with 138 additions and 2 deletions

View File

@ -313,6 +313,7 @@ void nfsd_init(void);
int nfsd_checkrootexp(struct nfsrv_descript *);
/* nfs_clvfsops.c */
void nfscl_retopts(struct nfsmount *, char *, size_t);
/* nfs_commonport.c */
int nfsrv_checksockseqnum(struct socket *, tcp_seq);

View File

@ -1201,6 +1201,9 @@ nfssvc_nfscl(struct thread *td, struct nfssvc_args *uap)
struct nfscbd_args nfscbdarg;
struct nfsd_nfscbd_args nfscbdarg2;
int error;
struct nameidata nd;
struct nfscl_dumpmntopts dumpmntopts;
char *buf;
if (uap->flag & NFSSVC_CBADDSOCK) {
error = copyin(uap->argp, (caddr_t)&nfscbdarg, sizeof(nfscbdarg));
@ -1233,6 +1236,28 @@ nfssvc_nfscl(struct thread *td, struct nfssvc_args *uap)
if (error)
return (error);
error = nfscbd_nfsd(td, &nfscbdarg2);
} else if (uap->flag & NFSSVC_DUMPMNTOPTS) {
error = copyin(uap->argp, &dumpmntopts, sizeof(dumpmntopts));
if (error == 0 && (dumpmntopts.ndmnt_blen < 256 ||
dumpmntopts.ndmnt_blen > 1024))
error = EINVAL;
if (error == 0)
error = nfsrv_lookupfilename(&nd,
dumpmntopts.ndmnt_fname, td);
if (error == 0 && strcmp(nd.ni_vp->v_mount->mnt_vfc->vfc_name,
"nfs") != 0) {
vput(nd.ni_vp);
error = EINVAL;
}
if (error == 0) {
buf = malloc(dumpmntopts.ndmnt_blen, M_TEMP, M_WAITOK);
nfscl_retopts(VFSTONFS(nd.ni_vp->v_mount), buf,
dumpmntopts.ndmnt_blen);
vput(nd.ni_vp);
error = copyout(buf, dumpmntopts.ndmnt_buf,
dumpmntopts.ndmnt_blen);
free(buf, M_TEMP);
}
} else {
error = EINVAL;
}

View File

@ -1627,3 +1627,105 @@ nfs_getnlminfo(struct vnode *vp, uint8_t *fhp, size_t *fhlenp,
}
}
/*
* This function prints out an option name, based on the conditional
* argument.
*/
static __inline void nfscl_printopt(struct nfsmount *nmp, int testval,
char *opt, char **buf, size_t *blen)
{
int len;
if (testval != 0 && *blen > strlen(opt)) {
len = snprintf(*buf, *blen, "%s", opt);
if (len != strlen(opt))
printf("EEK!!\n");
*buf += len;
*blen -= len;
}
}
/*
* This function printf out an options integer value.
*/
static __inline void nfscl_printoptval(struct nfsmount *nmp, int optval,
char *opt, char **buf, size_t *blen)
{
int len;
if (*blen > strlen(opt) + 1) {
/* Could result in truncated output string. */
len = snprintf(*buf, *blen, "%s=%d", opt, optval);
if (len < *blen) {
*buf += len;
*blen -= len;
}
}
}
/*
* Load the option flags and values into the buffer.
*/
void nfscl_retopts(struct nfsmount *nmp, char *buffer, size_t buflen)
{
char *buf;
size_t blen;
buf = buffer;
blen = buflen;
nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NFSV4) != 0, "nfsv4", &buf,
&blen);
nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NFSV3) != 0, "nfsv3", &buf,
&blen);
nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0,
"nfsv2", &buf, &blen);
nfscl_printopt(nmp, nmp->nm_sotype == SOCK_STREAM, ",tcp", &buf, &blen);
nfscl_printopt(nmp, nmp->nm_sotype != SOCK_STREAM, ",udp", &buf, &blen);
nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_RESVPORT) != 0, ",resvport",
&buf, &blen);
nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCONN) != 0, ",noconn",
&buf, &blen);
nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_SOFT) == 0, ",hard", &buf,
&blen);
nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_SOFT) != 0, ",soft", &buf,
&blen);
nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_INT) != 0, ",intr", &buf,
&blen);
nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCTO) == 0, ",cto", &buf,
&blen);
nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCTO) != 0, ",nocto", &buf,
&blen);
nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_NOLOCKD | NFSMNT_NFSV4)) ==
0, ",lockd", &buf, &blen);
nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_NOLOCKD | NFSMNT_NFSV4)) ==
NFSMNT_NOLOCKD, ",nolockd", &buf, &blen);
nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_RDIRPLUS) != 0, ",rdirplus",
&buf, &blen);
nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_KERB) == 0, ",sec=sys",
&buf, &blen);
nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_KERB | NFSMNT_INTEGRITY |
NFSMNT_PRIVACY)) == NFSMNT_KERB, ",sec=krb5", &buf, &blen);
nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_KERB | NFSMNT_INTEGRITY |
NFSMNT_PRIVACY)) == (NFSMNT_KERB | NFSMNT_INTEGRITY), ",sec=krb5i",
&buf, &blen);
nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_KERB | NFSMNT_INTEGRITY |
NFSMNT_PRIVACY)) == (NFSMNT_KERB | NFSMNT_PRIVACY), ",sec=krb5p",
&buf, &blen);
nfscl_printoptval(nmp, nmp->nm_acdirmin, ",acdirmin", &buf, &blen);
nfscl_printoptval(nmp, nmp->nm_acdirmax, ",acdirmax", &buf, &blen);
nfscl_printoptval(nmp, nmp->nm_acregmin, ",acregmin", &buf, &blen);
nfscl_printoptval(nmp, nmp->nm_acregmax, ",acregmax", &buf, &blen);
nfscl_printoptval(nmp, nmp->nm_nametimeo, ",nametimeo", &buf, &blen);
nfscl_printoptval(nmp, nmp->nm_negnametimeo, ",negnametimeo", &buf,
&blen);
nfscl_printoptval(nmp, nmp->nm_rsize, ",rsize", &buf, &blen);
nfscl_printoptval(nmp, nmp->nm_wsize, ",wsize", &buf, &blen);
nfscl_printoptval(nmp, nmp->nm_readdirsize, ",readdirsize", &buf,
&blen);
nfscl_printoptval(nmp, nmp->nm_readahead, ",readahead", &buf, &blen);
nfscl_printoptval(nmp, nmp->nm_wcommitsize, ",wcommitsize", &buf,
&blen);
nfscl_printoptval(nmp, nmp->nm_timeo, ",timeout", &buf, &blen);
nfscl_printoptval(nmp, nmp->nm_retry, ",retrans", &buf, &blen);
}

View File

@ -91,8 +91,8 @@ sys_nfssvc(struct thread *td, struct nfssvc_args *uap)
if ((uap->flag & (NFSSVC_ADDSOCK | NFSSVC_OLDNFSD | NFSSVC_NFSD)) &&
nfsd_call_nfsserver != NULL)
error = (*nfsd_call_nfsserver)(td, uap);
else if ((uap->flag & (NFSSVC_CBADDSOCK | NFSSVC_NFSCBD)) &&
nfsd_call_nfscl != NULL)
else if ((uap->flag & (NFSSVC_CBADDSOCK | NFSSVC_NFSCBD |
NFSSVC_DUMPMNTOPTS)) && nfsd_call_nfscl != NULL)
error = (*nfsd_call_nfscl)(td, uap);
else if ((uap->flag & (NFSSVC_IDNAME | NFSSVC_GETSTATS |
NFSSVC_GSSDADDPORT | NFSSVC_GSSDADDFIRST | NFSSVC_GSSDDELETEALL |

View File

@ -68,5 +68,13 @@
#define NFSSVC_ZEROSRVSTATS 0x02000000 /* modifier for GETSTATS */
#define NFSSVC_SUSPENDNFSD 0x04000000
#define NFSSVC_RESUMENFSD 0x08000000
#define NFSSVC_DUMPMNTOPTS 0x10000000
/* Argument structure for NFSSVC_DUMPMNTOPTS. */
struct nfscl_dumpmntopts {
char *ndmnt_fname; /* File Name */
size_t ndmnt_blen; /* Size of buffer */
void *ndmnt_buf; /* and the buffer */
};
#endif /* _NFS_NFSSVC_H */