walters / rpms / nfs-utils

Forked from rpms/nfs-utils 6 years ago
Clone
Blob Blame History Raw
diff --git a/configure.ac b/configure.ac
index 8e427e3..926b044 100644
--- a/configure.ac
+++ b/configure.ac
@@ -60,7 +60,6 @@ AC_ARG_WITH(systemd,
 	[AC_HELP_STRING([--with-systemd@<:@=unit-dir-path@:>@],
 			[install systemd unit files @<:@Default: no, and path defaults to /usr/lib/systemd/system if not given@:>@])],
 	test "$withval" = "no" && use_systemd=0 || unitdir=$withval use_systemd=1
-	use_systemd=0
 	)
 	AM_CONDITIONAL(INSTALL_SYSTEMD, [test "$use_systemd" = 1])
 	AC_SUBST(unitdir)
@@ -164,6 +163,8 @@ if test "$enable_mount" = yes; then
 				[Link mount.nfs with libmount @<:@default=no@:>@])],
 		enable_libmount=$enableval,
 		enable_libmount=no)
+else
+	enable_libmount=no
 fi
 
 AC_ARG_ENABLE(tirpc,
@@ -214,9 +215,16 @@ fi
 AC_ARG_ENABLE(nfsdcltrack,
 	[AC_HELP_STRING([--disable-nfsdcltrack],
 			[disable NFSv4 clientid tracking programs @<:@default=no@:>@])],
-	enable_nfsdctrack=$enableval,
+	enable_nfsdcltrack=$enableval,
 	enable_nfsdcltrack="yes")
 
+AC_ARG_ENABLE(osdlogin,
+	[AC_HELP_STRING([--enable-osdlogin],
+			[enable osd_login scripts @<:@default=no@:>@])],
+	enable_osdlogin=$enableval,
+	enable_osdlogin="no")
+	AM_CONDITIONAL(CONFIG_OSD_LOGIN, [test "$enable_osdlogin" = "yes" ])
+
 dnl Check for TI-RPC library and headers
 AC_LIBTIRPC
 
@@ -347,7 +355,7 @@ AC_SUBST(LIBBSD)
 AC_SUBST(LIBBLKID)
 AC_SUBST(LIBDL)
 
-if test "$enable_libmount" != no; then
+if test "$enable_libmount" = yes; then
    AC_CHECK_LIB(mount, mnt_context_do_mount, [LIBMOUNT="-lmount"], AC_MSG_ERROR([libmount needed]))
    AC_CHECK_HEADER(libmount/libmount.h, , AC_MSG_ERROR([Cannot find libmount header file libmount/libmount.h]))
 fi
diff --git a/support/include/nfs/export.h b/support/include/nfs/export.h
index 2f59e6a..1194255 100644
--- a/support/include/nfs/export.h
+++ b/support/include/nfs/export.h
@@ -26,6 +26,7 @@
 #define	NFSEXP_CROSSMOUNT	0x4000
 #define NFSEXP_NOACL		0x8000 /* reserved for possible ACL related use */
 #define NFSEXP_V4ROOT		0x10000
+#define NFSEXP_PNFS            0x20000
 /*
  * All flags supported by the kernel before addition of the
  * export_features interface:
diff --git a/support/nfs/exports.c b/support/nfs/exports.c
index eb782b9..0aea6f1 100644
--- a/support/nfs/exports.c
+++ b/support/nfs/exports.c
@@ -154,6 +154,7 @@ getexportent(int fromkernel, int fromexports)
 		}
 	}
 
+	xfree(ee.e_hostname);
 	ee = def_ee;
 
 	/* Check for default client */
@@ -176,7 +177,6 @@ getexportent(int fromkernel, int fromexports)
 		if (!has_default_opts)
 			xlog(L_WARNING, "No options for %s %s: suggest %s(sync) to avoid warning", ee.e_path, exp, exp);
 	}
-	xfree(ee.e_hostname);
 	ee.e_hostname = xstrdup(hostname);
 
 	if (parseopts(opt, &ee, fromexports && !has_default_subtree_opts, NULL) < 0)
@@ -275,6 +275,7 @@ putexportent(struct exportent *ep)
 		"no_" : "");
 	if (ep->e_flags & NFSEXP_NOREADDIRPLUS)
 		fprintf(fp, "nordirplus,");
+	fprintf(fp, "%spnfs,", (ep->e_flags & NFSEXP_PNFS)? "" : "no_");
 	if (ep->e_flags & NFSEXP_FSID) {
 		fprintf(fp, "fsid=%d,", ep->e_fsid);
 	}
@@ -407,7 +408,7 @@ int secinfo_addflavor(struct flav_info *flav, struct exportent *ep)
 	struct sec_entry *p;
 
 	for (p=ep->e_secinfo; p->flav; p++) {
-		if (p->flav == flav)
+		if (p->flav == flav || p->flav->fnum == flav->fnum)
 			return p - ep->e_secinfo;
 	}
 	if (p - ep->e_secinfo >= SECFLAVOR_COUNT) {
@@ -581,6 +582,10 @@ parseopts(char *cp, struct exportent *ep, int warn, int *had_subtree_opt_ptr)
 			clearflags(NFSEXP_NOACL, active, ep);
 		else if (strcmp(opt, "no_acl") == 0)
 			setflags(NFSEXP_NOACL, active, ep);
+		else if (!strcmp(opt, "pnfs"))
+			setflags(NFSEXP_PNFS, active, ep);
+		else if (!strcmp(opt, "no_pnfs"))
+			clearflags(NFSEXP_PNFS, active, ep);
 		else if (strncmp(opt, "anonuid=", 8) == 0) {
 			char *oe;
 			ep->e_anonuid = strtol(opt+8, &oe, 10);
diff --git a/systemd/Makefile.am b/systemd/Makefile.am
index 16cf5e6..fbcabb1 100644
--- a/systemd/Makefile.am
+++ b/systemd/Makefile.am
@@ -3,7 +3,6 @@
 MAINTAINERCLEANFILES = Makefile.in
 
 unit_files =  \
-    nfs-blkmap.target \
     nfs-client.target \
     \
     auth-rpcgss-module.service \
diff --git a/systemd/README b/systemd/README
index a2a5f06..bbd7790 100644
--- a/systemd/README
+++ b/systemd/README
@@ -24,7 +24,7 @@ by a suitable 'preset' setting:
     is started by /usr/sbin/start-statd which mount.nfs will run
     if statd is needed.
 
- nfs-blkmap.target
+ nfs-blkmap.service
     If enabled, then blkmapd will be run when nfs-client.target is
     started.
 
diff --git a/systemd/auth-rpcgss-module.service b/systemd/auth-rpcgss-module.service
index 0355e13..5241f7b 100644
--- a/systemd/auth-rpcgss-module.service
+++ b/systemd/auth-rpcgss-module.service
@@ -6,6 +6,7 @@
 # unit will fail.  But that's OK.)
 [Unit]
 Description=Kernel Module supporting RPCSEC_GSS
+DefaultDependencies=no
 Before=gssproxy.service rpc-svcgssd.service rpc-gssd.service
 Wants=gssproxy.service rpc-svcgssd.service rpc-gssd.service
 ConditionPathExists=/etc/krb5.keytab
diff --git a/systemd/nfs-blkmap.service b/systemd/nfs-blkmap.service
index f470e3d..ddbf4e9 100644
--- a/systemd/nfs-blkmap.service
+++ b/systemd/nfs-blkmap.service
@@ -5,12 +5,13 @@ Conflicts=umount.target
 After=var-lib-nfs-rpc_pipefs.mount
 Requires=var-lib-nfs-rpc_pipefs.mount
 
-Requisite=nfs-blkmap.target
-After=nfs-blkmap.target
-
 PartOf=nfs-utils.service
 
 [Service]
 Type=forking
 PIDFile=/var/run/blkmapd.pid
+EnvironmentFile=-/run/sysconfig/nfs-utils
 ExecStart=/usr/sbin/blkmapd $BLKMAPDARGS
+
+[Install]
+WantedBy=nfs-client.target
diff --git a/systemd/nfs-blkmap.target b/systemd/nfs-blkmap.target
deleted file mode 100644
index fbcc111..0000000
--- a/systemd/nfs-blkmap.target
+++ /dev/null
@@ -1,8 +0,0 @@
-[Unit]
-Description= PNFS blkmaping enablement.
-# If this target is enabled, then blkmapd will be started
-# as required.  If it is not enabled it won't.
-
-[Install]
-WantedBy=remote-fs.target
-WantedBy=multi-user.target
\ No newline at end of file
diff --git a/systemd/nfs-client.target b/systemd/nfs-client.target
index 9b792a3..8a8300a 100644
--- a/systemd/nfs-client.target
+++ b/systemd/nfs-client.target
@@ -5,8 +5,7 @@ Wants=remote-fs-pre.target
 
 # Note: we don't "Wants=rpc-statd.service" as "mount.nfs" will arrange to
 # start that on demand if needed.
-Wants=nfs-blkmap.service rpc-statd-notify.service
-After=nfs-blkmap.service
+Wants=rpc-statd-notify.service
 
 # GSS services dependencies and ordering
 Wants=auth-rpcgss-module.service
diff --git a/systemd/nfs-config.service b/systemd/nfs-config.service
index 64010e6..7f65305 100644
--- a/systemd/nfs-config.service
+++ b/systemd/nfs-config.service
@@ -1,5 +1,7 @@
 [Unit]
 Description=Preprocess NFS configuration
+After=local-fs.target
+DefaultDependencies=no
 
 [Service]
 Type=oneshot
diff --git a/systemd/nfs-idmapd.service b/systemd/nfs-idmapd.service
index e84f8c8..df3dd9d 100644
--- a/systemd/nfs-idmapd.service
+++ b/systemd/nfs-idmapd.service
@@ -1,7 +1,8 @@
 [Unit]
 Description=NFSv4 ID-name mapping service
+DefaultDependencies=no
 Requires=var-lib-nfs-rpc_pipefs.mount
-After=var-lib-nfs-rpc_pipefs.mount
+After=var-lib-nfs-rpc_pipefs.mount local-fs.target
 
 BindsTo=nfs-server.service
 
diff --git a/systemd/nfs-mountd.service b/systemd/nfs-mountd.service
index d908afe..8a39f3e 100644
--- a/systemd/nfs-mountd.service
+++ b/systemd/nfs-mountd.service
@@ -1,8 +1,9 @@
 [Unit]
 Description=NFS Mount Daemon
+DefaultDependencies=no
 Requires=proc-fs-nfsd.mount
 After=proc-fs-nfsd.mount
-After=network.target
+After=network.target local-fs.target
 BindsTo=nfs-server.service
 
 Wants=nfs-config.service
diff --git a/systemd/nfs-server.service b/systemd/nfs-server.service
index 8010aad..12b02f2 100644
--- a/systemd/nfs-server.service
+++ b/systemd/nfs-server.service
@@ -1,11 +1,13 @@
 [Unit]
 Description=NFS server and services
-Requires= network.target proc-fs-nfsd.mount rpcbind.target
+DefaultDependencies=no
+Requires= network.target proc-fs-nfsd.mount rpcbind.service
 Requires= nfs-mountd.service
 Wants=rpc-statd.service nfs-idmapd.service
 Wants=rpc-statd-notify.service
 
-After= network.target proc-fs-nfsd.mount rpcbind.target nfs-mountd.service
+After= local-fs.target
+After= network.target proc-fs-nfsd.mount rpcbind.service nfs-mountd.service
 After= nfs-idmapd.service rpc-statd.service
 Before= rpc-statd-notify.service
 
@@ -13,6 +15,9 @@ Before= rpc-statd-notify.service
 Wants=auth-rpcgss-module.service
 After=rpc-gssd.service gssproxy.service rpc-svcgssd.service
 
+# start/stop server before/after client
+Before=remote-fs-pre.target
+
 Wants=nfs-config.service
 After=nfs-config.service
 
diff --git a/systemd/rpc-statd-notify.service b/systemd/rpc-statd-notify.service
index 941afe5..89ba36c 100644
--- a/systemd/rpc-statd-notify.service
+++ b/systemd/rpc-statd-notify.service
@@ -1,7 +1,8 @@
 [Unit]
 Description=Notify NFS peers of a restart
-Requires=network-online.target
-After=network-online.target nss-lookup.target
+DefaultDependencies=no
+Requires=network.target
+After=local-fs.target network.target nss-lookup.target
 
 # if we run an nfs server, it needs to be running before we
 # tell clients that it has restarted.
diff --git a/systemd/rpc-svcgssd.service b/systemd/rpc-svcgssd.service
index f7424b0..41177b6 100644
--- a/systemd/rpc-svcgssd.service
+++ b/systemd/rpc-svcgssd.service
@@ -1,7 +1,8 @@
 [Unit]
 Description=RPC security service for NFS server
+DefaultDependencies=no
 Requires=var-lib-nfs-rpc_pipefs.mount
-After=var-lib-nfs-rpc_pipefs.mount
+After=var-lib-nfs-rpc_pipefs.mount local-fs.target
 PartOf=nfs-server.service
 PartOf=nfs-utils.service
 
diff --git a/systemd/var-lib-nfs-rpc_pipefs.mount b/systemd/var-lib-nfs-rpc_pipefs.mount
index 33c5db6..26d1c76 100644
--- a/systemd/var-lib-nfs-rpc_pipefs.mount
+++ b/systemd/var-lib-nfs-rpc_pipefs.mount
@@ -1,6 +1,7 @@
 [Unit]
 Description=RPC Pipe File System
 DefaultDependencies=no
+After=systemd-tmpfiles-setup.service
 Conflicts=umount.target
 
 [Mount]
diff --git a/tools/mountstats/mountstats.man b/tools/mountstats/mountstats.man
index bee3f86..a9df1e4 100644
--- a/tools/mountstats/mountstats.man
+++ b/tools/mountstats/mountstats.man
@@ -10,7 +10,7 @@ mountstats \- Displays various NFS client per-mount statistics
 .RB [ \-v | \-\-version ]
 .RB [ \-f | \-\-file
 .IR infile ]
-.RB [ \-s | \-\-since
+.RB [ \-S | \-\-since
 .IR sincefile ]
 .\" .RB [ \-n | \-\-nfs | \-r | \-\-rpc | \-R | \-\-raw ]
 .R [
@@ -27,7 +27,7 @@ mountstats \- Displays various NFS client per-mount statistics
 .RB [ \-v | \-\-version ]
 .RB [ \-f | \-\-file
 .IR infile ]
-.RB [ \-s | \-\-since
+.RB [ \-S | \-\-since
 .IR sincefile ]
 .RI [ interval ]
 .RI [ count ]
@@ -38,7 +38,7 @@ mountstats \- Displays various NFS client per-mount statistics
 .RB [ \-v | \-\-version ]
 .RB [ \-f | \-\-file
 .IR infile ]
-.RB [ \-s | \-\-since
+.RB [ \-S | \-\-since
 .IR sincefile ]
 .RB [ \-3 ]
 .RB [ \-4 ]
@@ -128,7 +128,7 @@ parameter is specified without the
 parameter, the command generates reports continuously.  This may not be used with the
 .BR \-f | \-\-file
 or
-.BR \-s | \-\-since 
+.BR \-S | \-\-since 
 options.
 .SS Options specific to the nfsstat sub-command
 .IP "\fB\-3\fP"
diff --git a/tools/mountstats/mountstats.py b/tools/mountstats/mountstats.py
index fd73feb..011bb42 100644
--- a/tools/mountstats/mountstats.py
+++ b/tools/mountstats/mountstats.py
@@ -474,7 +474,7 @@ class DeviceData:
         # authrefresh stats don't actually get captured in
         # /proc/self/mountstats, so we fudge it here
         authrefrsh = sends
-        return (sends, trans, authrefrsh)
+        return (sends, retrans, authrefrsh)
 
     def display_nfsstat_stats(self):
         """Pretty-print nfsstat-style stats
@@ -686,7 +686,7 @@ def mountstats_command(args):
     """Mountstats command
     """
     mountstats = parse_stats_file(args.infile)
-    mountpoints = args.mountpoints
+    mountpoints = [os.path.normpath(mp) for mp in args.mountpoints]
 
     # make certain devices contains only NFS mount points
     if len(mountpoints) > 0:
@@ -708,7 +708,7 @@ def mountstats_command(args):
                 mountpoints += [device]
     if len(mountpoints) == 0:
         print('No NFS mount points were found')
-        return
+        return 1
 
     if args.since:
         old_mountstats = parse_stats_file(args.since)
@@ -729,12 +729,13 @@ def mountstats_command(args):
     args.infile.close()
     if args.since:
         args.since.close()
+    return 0
 
 def nfsstat_command(args):
     """nfsstat-like command for NFS mount points
     """
     mountstats = parse_stats_file(args.infile)
-    mountpoints = args.mountpoints
+    mountpoints = [os.path.normpath(mp) for mp in args.mountpoints]
     v3stats = DeviceData()
     v3stats.setup_accumulator(Nfsv3ops)
     v4stats = DeviceData()
@@ -766,7 +767,7 @@ def nfsstat_command(args):
                 mountpoints += [device]
     if len(mountpoints) == 0:
         print('No NFS mount points were found')
-        return
+        return 1
 
     if args.since:
         old_mountstats = parse_stats_file(args.since)
@@ -803,6 +804,7 @@ def nfsstat_command(args):
     args.infile.close()
     if args.since:
         args.since.close()
+    return 0
 
 def print_iostat_summary(old, new, devices, time):
     for device in devices:
@@ -820,7 +822,7 @@ def iostat_command(args):
     """iostat-like command for NFS mount points
     """
     mountstats = parse_stats_file(args.infile)
-    devices = args.mountpoints
+    devices = [os.path.normpath(mp) for mp in args.mountpoints]
 
     if args.since:
         old_mountstats = parse_stats_file(args.since)
@@ -847,7 +849,7 @@ def iostat_command(args):
                 devices += [device]
     if len(devices) == 0:
         print('No NFS mount points were found')
-        return
+        return 1
 
     sample_time = 0
 
@@ -875,6 +877,7 @@ def iostat_command(args):
     args.infile.close()
     if args.since:
         args.since.close()
+    return 0
 
 class ICMAction(argparse.Action):
     """Custom action to deal with interval, count, and mountpoints.
@@ -986,7 +989,7 @@ try:
         sys.stdout.close()
         sys.stderr.close()
         sys.exit(res)
-except (SystemExit, KeyboardInterrupt, RuntimeError):
+except (KeyboardInterrupt, RuntimeError):
     sys.exit(1)
 except IOError:
     pass
diff --git a/utils/blkmapd/device-inq.c b/utils/blkmapd/device-inq.c
index eabc70c..c5bf71f 100644
--- a/utils/blkmapd/device-inq.c
+++ b/utils/blkmapd/device-inq.c
@@ -179,6 +179,7 @@ struct bl_serial *bldev_read_serial(int fd, const char *filename)
 	char *buffer;
 	struct bl_dev_id *dev_root, *dev_id;
 	unsigned int pos, len, current_id = 0;
+	size_t devid_len = sizeof(struct bl_dev_id) - sizeof(unsigned char);
 
 	status = bldev_inquire_pages(fd, 0x83, &buffer);
 	if (status)
@@ -189,7 +190,11 @@ struct bl_serial *bldev_read_serial(int fd, const char *filename)
 	pos = 0;
 	current_id = 0;
 	len = dev_root->len;
-	while (pos < (len - sizeof(struct bl_dev_id) + sizeof(unsigned char))) {
+
+	if (len < devid_len)
+		goto out;
+
+	while (pos < (len - devid_len)) {
 		dev_id = (struct bl_dev_id *)&(dev_root->data[pos]);
 		if ((dev_id->ids & 0xf) < current_id)
 			continue;
@@ -221,8 +226,7 @@ struct bl_serial *bldev_read_serial(int fd, const char *filename)
 		}
 		if (current_id == 3)
 			break;
-		pos += (dev_id->len + sizeof(struct bl_dev_id) -
-			sizeof(unsigned char));
+		pos += (dev_id->len + devid_len);
 	}
  out:
 	if (!serial_out)
diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c
index 48eac00..8758231 100644
--- a/utils/exportfs/exportfs.c
+++ b/utils/exportfs/exportfs.c
@@ -821,6 +821,8 @@ dump(int verbose, int export_format)
 				c = dumpopt(c, "nordirplus");
 			if (ep->e_flags & NFSEXP_NOACL)
 				c = dumpopt(c, "no_acl");
+			if (ep->e_flags & NFSEXP_PNFS)
+				c = dumpopt(c, "pnfs");
 			if (ep->e_flags & NFSEXP_FSID)
 				c = dumpopt(c, "fsid=%d", ep->e_fsid);
 			if (ep->e_uuid)
diff --git a/utils/exportfs/exports.man b/utils/exportfs/exports.man
index 3d974d9..9309246 100644
--- a/utils/exportfs/exports.man
+++ b/utils/exportfs/exports.man
@@ -218,16 +218,46 @@ This option can be very useful in some situations, but it should be
 used with due care, and only after confirming that the client system
 copes with the situation effectively.
 
-The option can be explicitly disabled with
+The option can be explicitly disabled for NFSv2 and NFSv3 with
 .IR hide .
+
+This option is not relevant when NFSv4 is use.  NFSv4 never hides
+subordinate filesystems.  Any filesystem that is exported will be
+visible where expected when using NFSv4.
 .TP
-.IR crossmnt
+.I crossmnt
 This option is similar to
 .I nohide
-but it makes it possible for clients to move from the filesystem marked
-with crossmnt to exported filesystems mounted on it.  Thus when a child
-filesystem "B" is mounted on a parent "A", setting crossmnt on "A" has
-the same effect as setting "nohide" on B.
+but it makes it possible for clients to access all filesystems mounted
+on a filesystem marked with
+.IR crossmnt .
+Thus when a child filesystem "B" is mounted on a parent "A", setting
+crossmnt on "A" has a similar effect to setting "nohide" on B.
+
+With
+.I nohide
+the child filesystem needs to be explicitly exported.  With
+.I crossmnt
+it need not.  If a child of a
+.I crossmnt
+file is not explicitly exported, then it will be implicitly exported
+with the same export options as the parent, except for
+.IR fsid= .
+This makes it impossible to
+.B not
+export a child of a
+.I crossmnt
+filesystem.  If some but not all subordinate filesystems of a parent
+are to be exported, then they must be explicitly exported and the
+parent should not have
+.I crossmnt
+set.
+
+The
+.I nocrossmnt
+option can explictly disable
+.I crossmnt
+if it was previously set.  This is rarely useful.
 .TP
 .IR no_subtree_check
 This option disables subtree checking, which has mild security
@@ -378,6 +408,15 @@ If the client asks for alternative locations for the export point, it
 will be given this list of alternatives. (Note that actual replication
 of the filesystem must be handled elsewhere.)
 
+.TP
+.IR pnfs
+This option allows enables the use of pNFS extension if protocol level
+is NFSv4.1 or higher, and the filesystem supports pNFS exports.  With
+pNFS clients can bypass the server and perform I/O directly to storage
+devices. The default can be explicitly requested with the
+.I no_pnfs
+option.
+
 .SS User ID Mapping
 .PP
 .B nfsd
diff --git a/utils/exportfs/nfsd.man b/utils/exportfs/nfsd.man
index 47b73be..0c516fa 100644
--- a/utils/exportfs/nfsd.man
+++ b/utils/exportfs/nfsd.man
@@ -196,6 +196,7 @@ classes of tracing to be enabled.  Consult the kernel header files to
 find out what number correspond to what tracing.
 
 .SH SEE ALSO
+.BR nfsd (8),
 .BR rpc.nfsd (8),
 .BR exports (5),
 .BR nfsstat (8),
diff --git a/utils/mount/error.c b/utils/mount/error.c
index e06f598..c9797fc 100644
--- a/utils/mount/error.c
+++ b/utils/mount/error.c
@@ -247,6 +247,9 @@ void mount_error(const char *spec, const char *mount_point, int error)
 		nfs_error(_("%s: please report the error to" PACKAGE_BUGREPORT),
 				progname);
 		break;
+	case EALREADY:
+		/* Error message has already been provided */
+		break;
 	default:
 		nfs_error(_("%s: %s"),
 			progname, strerror(error));
diff --git a/utils/mount/mount.nfs.man b/utils/mount/mount.nfs.man
index 1a4561b..0409c96 100644
--- a/utils/mount/mount.nfs.man
+++ b/utils/mount/mount.nfs.man
@@ -15,16 +15,20 @@ is meant to be used by the
 .BR mount (8)
 command for mounting NFS shares. This subcommand, however, can also be used as a standalone command with limited functionality.
 
-.BR mount.nfs4 
-is used for mounting NFSv4 file system, while 
-.BR mount.nfs 
-is used to mount NFS file systems versions 3 or 2.
 .I remotetarget 
 is a server share usually in the form of 
 .BR servername:/path/to/share.
 .I dir 
 is the directory on which the file system is to be mounted.
 
+Under Linux 2.6.32 and later kernel versions,
+.BR mount.nfs
+can mount all NFS file system versions.  Under earlier Linux kernel versions,
+.BR mount.nfs4
+must be used for mounting NFSv4 file systems while
+.BR mount.nfs
+must be used for NFSv3 and v2.
+
 .SH OPTIONS
 .TP
 .BI "\-r"
@@ -76,10 +80,13 @@ file system table
 .TP
 .I /etc/mtab
 table of mounted file systems
-
+.TP
+.I /etc/nfsmount.conf
+Configuration file for NFS mounts
 .PD
 .SH "SEE ALSO"
 .BR nfs (5),
+.BR nfsmount.conf (5),
 .BR mount (8),
 
 .SH "AUTHOR"
diff --git a/utils/mount/nfs.man b/utils/mount/nfs.man
index fe4f9b1..e541cdc 100644
--- a/utils/mount/nfs.man
+++ b/utils/mount/nfs.man
@@ -1706,6 +1706,9 @@ with the mount options already saved on disk for the NFS server mounted at /mnt.
 .TP 1.5i
 .I /etc/fstab
 file system table
+.TP 1.5i
+.I /etc/nfsmount.conf
+Configuration file for NFS mounts
 .SH BUGS
 Before 2.4.7, the Linux NFS client did not support NFS over TCP.
 .P
@@ -1735,6 +1738,7 @@ such as security negotiation, server referrals, and named attributes.
 .BR mount.nfs (5),
 .BR umount.nfs (5),
 .BR exports (5),
+.BR nfsmount.conf (5),
 .BR netconfig (5),
 .BR ipv6 (7),
 .BR nfsd (8),
diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c
index 76ecb32..c8f5a6d 100644
--- a/utils/mount/stropts.c
+++ b/utils/mount/stropts.c
@@ -108,12 +108,6 @@ static void nfs_default_version(struct nfsmount_info *mi)
 		return;
 	}
 
-	if (mi->version.v_mode == V_GENERAL &&
-		config_default_vers.v_mode == V_DEFAULT) {
-		mi->version.v_mode = V_SPECIFIC;
-		return;
-	}
-
 	if (mi->version.v_mode == V_DEFAULT &&
 		config_default_vers.v_mode != V_DEFAULT) {
 		mi->version.major = config_default_vers.major;
@@ -121,9 +115,9 @@ static void nfs_default_version(struct nfsmount_info *mi)
 		return;
 	}
 
-	if (mi->version.v_mode == V_GENERAL &&
-		config_default_vers.v_mode != V_DEFAULT) {
-		if (mi->version.major == config_default_vers.major)
+	if (mi->version.v_mode == V_GENERAL) {
+		if (config_default_vers.v_mode != V_DEFAULT &&
+		    mi->version.major == config_default_vers.major)
 			mi->version.minor = config_default_vers.minor;
 		return;
 	}
@@ -298,6 +292,7 @@ static int nfs_verify_lock_option(struct mount_options *options)
 			    "required for remote locking."), progname);
 		nfs_error(_("%s: Either use '-o nolock' to keep "
 			    "locks local, or start statd."), progname);
+		errno = EALREADY; /* Don't print further error message */
 		return 0;
 	}
 
@@ -742,8 +737,13 @@ static int nfs_do_mount_v4(struct nfsmount_info *mi,
 	}
 
 	if (mi->version.v_mode != V_SPECIFIC) {
-		snprintf(version_opt, sizeof(version_opt) - 1,
-			"vers=%lu.%lu", mi->version.major, mi->version.minor);
+		if (mi->version.v_mode == V_GENERAL)
+			snprintf(version_opt, sizeof(version_opt) - 1,
+				"vers=%lu", mi->version.major);
+		else
+			snprintf(version_opt, sizeof(version_opt) - 1,
+				"vers=%lu.%lu", mi->version.major,
+				mi->version.minor);
 
 		if (po_append(options, version_opt) == PO_FAILED) {
 			errno = EINVAL;
diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c
index c23d384..7d250f9 100644
--- a/utils/mountd/cache.c
+++ b/utils/mountd/cache.c
@@ -376,7 +376,7 @@ static char *next_mnt(void **v, char *p)
 		*v = f;
 	} else
 		f = *v;
-	while ((me = getmntent(f)) != NULL &&
+	while ((me = getmntent(f)) != NULL && l > 1 &&
 	       (strncmp(me->mnt_dir, p, l) != 0 ||
 		me->mnt_dir[l] != '/'))
 		;
diff --git a/utils/mountd/v4root.c b/utils/mountd/v4root.c
index 34d098a..d521725 100644
--- a/utils/mountd/v4root.c
+++ b/utils/mountd/v4root.c
@@ -26,6 +26,7 @@
 #include "nfslib.h"
 #include "misc.h"
 #include "v4root.h"
+#include "pseudoflavors.h"
 
 int v4root_needed;
 
@@ -56,22 +57,25 @@ static nfs_export pseudo_root = {
 };
 
 static void
-set_pseudofs_security(struct exportent *pseudo, struct exportent *source)
+set_pseudofs_security(struct exportent *pseudo, int flags)
 {
-	struct sec_entry *se;
+	struct flav_info *flav;
 	int i;
 
-	if (source->e_flags & NFSEXP_INSECURE_PORT)
+	if (flags & NFSEXP_INSECURE_PORT)
 		pseudo->e_flags |= NFSEXP_INSECURE_PORT;
-	if ((source->e_flags & NFSEXP_ROOTSQUASH) == 0)
+	if ((flags & NFSEXP_ROOTSQUASH) == 0)
 		pseudo->e_flags &= ~NFSEXP_ROOTSQUASH;
-	for (se = source->e_secinfo; se->flav; se++) {
+	for (flav = flav_map; flav < flav_map + flav_map_size; flav++) {
 		struct sec_entry *new;
 
-		i = secinfo_addflavor(se->flav, pseudo);
+		if (!flav->fnum)
+			continue;
+
+		i = secinfo_addflavor(flav, pseudo);
 		new = &pseudo->e_secinfo[i];
 
-		if (se->flags & NFSEXP_INSECURE_PORT)
+		if (flags & NFSEXP_INSECURE_PORT)
 			new->flags |= NFSEXP_INSECURE_PORT;
 	}
 }
@@ -91,7 +95,7 @@ v4root_create(char *path, nfs_export *export)
 	strncpy(eep.e_path, path, sizeof(eep.e_path));
 	if (strcmp(path, "/") != 0)
 		eep.e_flags &= ~NFSEXP_FSID;
-	set_pseudofs_security(&eep, curexp);
+	set_pseudofs_security(&eep, curexp->e_flags);
 	exp = export_create(&eep, 0);
 	if (exp == NULL)
 		return NULL;
@@ -139,7 +143,7 @@ pseudofs_update(char *hostname, char *path, nfs_export *source)
 		return 0;
 	}
 	/* Update an existing V4ROOT export: */
-	set_pseudofs_security(&exp->m_export, &source->m_export);
+	set_pseudofs_security(&exp->m_export, source->m_export.e_flags);
 	return 0;
 }
 
diff --git a/utils/nfsd/nfsd.man b/utils/nfsd/nfsd.man
index be21ed4..3ba847e 100644
--- a/utils/nfsd/nfsd.man
+++ b/utils/nfsd/nfsd.man
@@ -121,6 +121,7 @@ address family combinations that are marked visible in the
 database.
 
 .SH SEE ALSO
+.BR nfsd (7),
 .BR rpc.mountd (8),
 .BR exports (5),
 .BR exportfs (8),
diff --git a/utils/nfsidmap/nfsidmap.c b/utils/nfsidmap/nfsidmap.c
index 5d62078..1f5ba67 100644
--- a/utils/nfsidmap/nfsidmap.c
+++ b/utils/nfsidmap/nfsidmap.c
@@ -323,7 +323,10 @@ int main(int argc, char **argv)
 	}
 	type = strtok(arg, ":");
 	value = strtok(NULL, ":");
-
+    if (value == NULL) {
+		xlog_err("Error: Null uid/gid value.");
+		return 1;
+	}
 	if (verbose) {
 		xlog_warn("key: 0x%lx type: %s value: %s timeout %ld",
 			key, type, value, timeout);
diff --git a/utils/statd/rmtcall.c b/utils/statd/rmtcall.c
index fd576d9..66a6eeb 100644
--- a/utils/statd/rmtcall.c
+++ b/utils/statd/rmtcall.c
@@ -221,6 +221,9 @@ process_reply(FD_SET_TYPE *rfds)
 	if (sockfd == -1 || !FD_ISSET(sockfd, rfds))
 		return 0;
 
+	/* Should not be processed again. */
+	FD_CLR (sockfd, rfds);
+
 	if (!(lp = recv_rply(&port)))
 		return 1;
 
diff --git a/utils/statd/statd.c b/utils/statd/statd.c
index 60ce6d1..2b7a167 100644
--- a/utils/statd/statd.c
+++ b/utils/statd/statd.c
@@ -393,7 +393,7 @@ int main (int argc, char **argv)
 		simulator (--argc, ++argv);	/* simulator() does exit() */
 #endif
 
-	daemon_init(!(run_mode & MODE_NODAEMON));
+	daemon_init((run_mode & MODE_NODAEMON));
 
 	if (run_mode & MODE_LOG_STDERR) {
 		xlog_syslog(0);