Author: rmacklem
Date: Sun Dec  2 01:16:04 2012
New Revision: 243782
URL: http://svnweb.freebsd.org/changeset/base/243782

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

Modified:
  head/sys/fs/nfs/nfs_var.h
  head/sys/fs/nfsclient/nfs_clport.c
  head/sys/fs/nfsclient/nfs_clvfsops.c
  head/sys/nfs/nfs_nfssvc.c
  head/sys/nfs/nfssvc.h

Modified: head/sys/fs/nfs/nfs_var.h
==============================================================================
--- head/sys/fs/nfs/nfs_var.h   Sun Dec  2 00:31:23 2012        (r243781)
+++ head/sys/fs/nfs/nfs_var.h   Sun Dec  2 01:16:04 2012        (r243782)
@@ -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);

Modified: head/sys/fs/nfsclient/nfs_clport.c
==============================================================================
--- head/sys/fs/nfsclient/nfs_clport.c  Sun Dec  2 00:31:23 2012        
(r243781)
+++ head/sys/fs/nfsclient/nfs_clport.c  Sun Dec  2 01:16:04 2012        
(r243782)
@@ -1201,6 +1201,9 @@ nfssvc_nfscl(struct thread *td, struct n
        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 n
                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;
        }

Modified: head/sys/fs/nfsclient/nfs_clvfsops.c
==============================================================================
--- head/sys/fs/nfsclient/nfs_clvfsops.c        Sun Dec  2 00:31:23 2012        
(r243781)
+++ head/sys/fs/nfsclient/nfs_clvfsops.c        Sun Dec  2 01:16:04 2012        
(r243782)
@@ -1627,3 +1627,105 @@ nfs_getnlminfo(struct vnode *vp, uint8_t
        }
 }
 
+/*
+ * 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);
+}
+

Modified: head/sys/nfs/nfs_nfssvc.c
==============================================================================
--- head/sys/nfs/nfs_nfssvc.c   Sun Dec  2 00:31:23 2012        (r243781)
+++ head/sys/nfs/nfs_nfssvc.c   Sun Dec  2 01:16:04 2012        (r243782)
@@ -91,8 +91,8 @@ sys_nfssvc(struct thread *td, struct nfs
        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 |

Modified: head/sys/nfs/nfssvc.h
==============================================================================
--- head/sys/nfs/nfssvc.h       Sun Dec  2 00:31:23 2012        (r243781)
+++ head/sys/nfs/nfssvc.h       Sun Dec  2 01:16:04 2012        (r243782)
@@ -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 */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to