Subject: Re: bug in NFS_V2_ONLY option
To: Ben Harris <bjh21@netbsd.org>
From: Christian Groessler <cpg@aladdin.de>
List: current-users
Date: 04/29/2001 02:18:35
On 04/28/2001 05:11:47 PM CET Ben Harris wrote:
>
>On 28 Apr 2001, Christian Groessler wrote:
>
>> Anyway, I think the cleaner approach would be if mount_nfs asks the
>> kernel what nfs it understands before contacting the nfs server.
>> How should this query be implemented? Additional syscall?
>
>sysctl(). vfs.nfs.max_version or similar.
OK, I've implemented this. This is my first excursion into this area so
please double-check it :-)
I've added code to sys/nfs/nfs_vfsops.c and
sbin/mount_nfs/mount_nfs.c.
Some things remain:
a,
If you look at my code in mount_nfs.c you'll see that I use an
immediate value for mib[1] (2 - VFS_NFS). I haven't found an existing
define for it...
b,
My patch as is works OK on i386, but when I tried it on alpha and
macppc, mount_nfs didn't compile because of mutiply defined "struct
pmap". This seems to happen because I include sysctl.h.
On alpha these 2 files are biting each other
/usr/include//rpc/pmap_prot.h:struct pmap {
/usr/include//alpha/pmap.h:struct pmap {
and on macppc these 2 files:
/usr/include//rpc/pmap_prot.h:struct pmap {
/usr/include//powerpc/pmap.h:struct pmap {
Hmm, I believe I'm innocent in this case...
regards,
chris
Index: sys/nfs/nfs.h
===================================================================
RCS file: /net/swamp/zeug/netbsd-rsync/main/syssrc/sys/nfs/nfs.h,v
retrieving revision 1.28
diff -u -r1.28 nfs.h
--- sys/nfs/nfs.h 2001/04/03 15:08:38 1.28
+++ sys/nfs/nfs.h 2001/04/28 21:49:24
@@ -259,12 +259,14 @@
*/
#define NFS_NFSSTATS 1 /* struct: struct nfsstats */
#define NFS_IOTHREADS 2 /* number of io threads */
-#define NFS_MAXID 3
+#define NFS_MAXVERSION 3 /* max. supported NFS version */
+#define NFS_MAXID 4
#define NFS_NAMES { \
{ 0, 0 }, \
{ "nfsstats", CTLTYPE_STRUCT }, \
{ "iothreads", CTLTYPE_INT }, \
+ { "max_version", CTLTYPE_INT }, \
}
/*
Index: sys/nfs/nfs_vfsops.c
===================================================================
RCS file: /net/swamp/zeug/netbsd-rsync/main/syssrc/sys/nfs/nfs_vfsops.c,v
retrieving revision 1.101
diff -u -r1.101 nfs_vfsops.c
--- sys/nfs/nfs_vfsops.c 2001/02/12 20:02:30 1.101
+++ sys/nfs/nfs_vfsops.c 2001/04/28 21:52:50
@@ -564,7 +564,9 @@
if (args.version != NFS_ARGSVERSION)
return (EPROGMISMATCH);
#ifdef NFS_V2_ONLY
- args.flags &= ~(NFSMNT_NFSV3 | NFSMNT_NQNFS);
+ if (args.flags & (NFSMNT_NFSV3 | NFSMNT_NQNFS)) {
+ return (EPROTONOSUPPORT);
+ }
#endif
if (mp->mnt_flag & MNT_UPDATE) {
struct nfsmount *nmp = VFSTONFS(mp);
@@ -960,7 +962,14 @@
nfs_getset_niothreads(1);
return rv;
-
+
+ case NFS_MAXVERSION:
+#ifndef NFS_V2_ONLY
+ return (sysctl_rdint(oldp, oldlenp, newp, 3));
+#else
+ return (sysctl_rdint(oldp, oldlenp, newp, 2));
+#endif
+
default:
return EOPNOTSUPP;
}
Index: sbin/mount_nfs/mount_nfs.c
===================================================================
RCS file: /net/swamp/zeug/netbsd-rsync/main/basesrc/sbin/mount_nfs/mount_nfs.c,v
retrieving revision 1.30
diff -u -r1.30 mount_nfs.c
--- sbin/mount_nfs/mount_nfs.c 2001/01/11 01:33:35 1.30
+++ sbin/mount_nfs/mount_nfs.c 2001/04/28 23:55:39
@@ -51,6 +51,7 @@
#endif /* not lint */
#include <sys/param.h>
+#include <sys/sysctl.h>
#include <sys/mount.h>
#include <sys/socket.h>
#include <sys/stat.h>
@@ -217,6 +218,8 @@
struct nfsd_cargs ncd;
int mntflags, altflags, i, nfssvc_flag, num;
char *name, *p, *spec, *ospec;
+ int ret, nfsver, len = sizeof(int);
+ int mib[3];
#ifdef NFSKERB
uid_t last_ruid;
@@ -436,6 +439,29 @@
}
argc -= optind;
argv += optind;
+
+ /*
+ * verify that kernel supports requested NFS version
+ */
+ if (! force2) {
+ mib[0] = CTL_VFS;
+ mib[1] = 2; /* VFS_NFS */
+ mib[2] = NFS_MAXVERSION;
+
+ ret = sysctl(mib, 3, &nfsver, &len, NULL, 0);
+ if (ret == -1) {
+ fprintf(stderr, "cannot query NFS version from kernel (%s)\n", strerror(errno));
+ fprintf(stderr, "coninuing anyway...\n");
+ }
+ else {
+ if (nfsver < 3 && force3)
+ errx(1, "NFSv3 requested, but kernel doesn't support v3!");
+ if (nfsver < 3) {
+ nfsargsp->flags &= ~NFSMNT_NFSV3;
+ force2 = 1; /* we don't support v3, so don't try to negotiate it. */
+ }
+ }
+ }
if (argc != 2)
usage();