[nfs-utils] Updated to latest upstream RC release: nfs-utils-1-2-10-rc1

Steve Dickson steved at fedoraproject.org
Wed Nov 20 21:33:16 UTC 2013


commit 1ac09434bb97f73a0aaea723bb3faaf418876f2f
Author: Steve Dickson <steved at redhat.com>
Date:   Wed Nov 20 16:31:47 2013 -0500

    Updated to latest upstream RC release: nfs-utils-1-2-10-rc1
    
    Signed-off-by: Steve Dickson <steved at redhat.com>

 nfs-utils-1.2.10-rc1.patch |  749 ++++++++++++++++++++++++++++++++++++++++++++
 nfs-utils.spec             |    9 +-
 2 files changed, 757 insertions(+), 1 deletions(-)
---
diff --git a/nfs-utils-1.2.10-rc1.patch b/nfs-utils-1.2.10-rc1.patch
new file mode 100644
index 0000000..883fd50
--- /dev/null
+++ b/nfs-utils-1.2.10-rc1.patch
@@ -0,0 +1,749 @@
+diff --git a/support/include/nfslib.h b/support/include/nfslib.h
+index f210a06..ce4b14b 100644
+--- a/support/include/nfslib.h
++++ b/support/include/nfslib.h
+@@ -128,6 +128,10 @@ void			fputrmtabent(FILE *fp, struct rmtabent *xep, long *pos);
+ void			fendrmtabent(FILE *fp);
+ void			frewindrmtabent(FILE *fp);
+ 
++/* mydaemon */
++void mydaemon(int nochdir, int noclose, int *pipefds);
++void release_parent(int *pipefds);
++
+ /*
+  * wildmat borrowed from INN
+  */
+diff --git a/support/nfs/Makefile.am b/support/nfs/Makefile.am
+index 05c2fc4..fb9b8c1 100644
+--- a/support/nfs/Makefile.am
++++ b/support/nfs/Makefile.am
+@@ -2,7 +2,7 @@
+ 
+ noinst_LIBRARIES = libnfs.a
+ libnfs_a_SOURCES = exports.c rmtab.c xio.c rpcmisc.c rpcdispatch.c \
+-		   xlog.c xcommon.c wildmat.c nfsclient.c \
++		   xlog.c xcommon.c wildmat.c mydaemon.c nfsclient.c \
+ 		   nfsexport.c getfh.c nfsctl.c rpc_socket.c getport.c \
+ 		   svc_socket.c cacheio.c closeall.c nfs_mntent.c conffile.c \
+ 		   svc_create.c atomicio.c strlcpy.c strlcat.c
+diff --git a/support/nfs/mydaemon.c b/support/nfs/mydaemon.c
+new file mode 100644
+index 0000000..e885d60
+--- /dev/null
++++ b/support/nfs/mydaemon.c
+@@ -0,0 +1,148 @@
++/*
++  mydaemon.c
++
++  Copyright (c) 2000 The Regents of the University of Michigan.
++  All rights reserved.
++
++  Copyright (c) 2000 Dug Song <dugsong at UMICH.EDU>.
++  Copyright (c) 2002 Andy Adamson <andros at UMICH.EDU>.
++  Copyright (c) 2002 Marius Aamodt Eriksen <marius at UMICH.EDU>.
++  Copyright (c) 2002 J. Bruce Fields <bfields at UMICH.EDU>.
++  Copyright (c) 2013 Jeff Layton <jlayton at redhat.com>
++
++  All rights reserved, all wrongs reversed.
++
++  Redistribution and use in source and binary forms, with or without
++  modification, are permitted provided that the following conditions
++  are met:
++
++  1. Redistributions of source code must retain the above copyright
++     notice, this list of conditions and the following disclaimer.
++  2. Redistributions in binary form must reproduce the above copyright
++     notice, this list of conditions and the following disclaimer in the
++     documentation and/or other materials provided with the distribution.
++  3. Neither the name of the University nor the names of its
++     contributors may be used to endorse or promote products derived
++     from this software without specific prior written permission.
++
++  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
++  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
++  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
++  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
++  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
++  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
++  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
++  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++
++*/
++
++#include <sys/param.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++#include <errno.h>
++#include <unistd.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <xlog.h>
++
++/**
++ * mydaemon - daemonize, but have parent wait to exit
++ * @nochdir:	skip chdir()'ing the child to / after forking if true
++ * @noclose:	skip closing stdin/stdout/stderr if true
++ * @pipefds:	pointer to 2 element array of pipefds
++ *
++ * This function is like daemon(), but with our own special sauce to delay
++ * the exit of the parent until the child is set up properly. A pipe is created
++ * between parent and child. The parent process will wait to exit until the
++ * child dies or writes a '1' on the pipe signaling that it started
++ * successfully.
++ */
++void
++mydaemon(int nochdir, int noclose, int *pipefds)
++{
++	int pid, status, tempfd;
++
++	if (pipe(pipefds) < 0) {
++		xlog_err("mydaemon: pipe() failed: errno %d (%s)\n",
++			 errno, strerror(errno));
++		exit(1);
++	}
++	if ((pid = fork ()) < 0) {
++		xlog_err("mydaemon: fork() failed: errno %d (%s)\n",
++			 errno, strerror(errno));
++		exit(1);
++	}
++
++	if (pid != 0) {
++		/*
++		 * Parent. Wait for status from child.
++		 */
++		close(pipefds[1]);
++		if (read(pipefds[0], &status, 1) != 1)
++			exit(1);
++		exit (0);
++	}
++	/* Child.	*/
++	close(pipefds[0]);
++	setsid ();
++	if (nochdir == 0) {
++		if (chdir ("/") == -1) {
++			xlog_err("mydaemon: chdir() failed: errno %d (%s)\n",
++				 errno, strerror(errno));
++			exit(1);
++		}
++	}
++
++	while (pipefds[1] <= 2) {
++		pipefds[1] = dup(pipefds[1]);
++		if (pipefds[1] < 0) {
++			xlog_err("mydaemon: dup() failed: errno %d (%s)\n",
++				 errno, strerror(errno));
++			exit(1);
++		}
++	}
++
++	if (noclose == 0) {
++		tempfd = open("/dev/null", O_RDWR);
++		if (tempfd >= 0) {
++			dup2(tempfd, 0);
++			dup2(tempfd, 1);
++			dup2(tempfd, 2);
++			close(tempfd);
++		} else {
++			xlog_err("mydaemon: can't open /dev/null: errno %d "
++				 "(%s)\n", errno, strerror(errno));
++			exit(1);
++		}
++	}
++
++	return;
++}
++
++/**
++ * release_parent - tell the parent that it can exit now
++ * @pipefds:	pipefd array that was previously passed to mydaemon()
++ *
++ * This function tells the parent process of mydaemon() that it's now clear
++ * to exit(0).
++ */
++void
++release_parent(int *pipefds)
++{
++	int status;
++
++	if (pipefds[1] > 0) {
++		if (write(pipefds[1], &status, 1) != 1) {
++			xlog_err("WARN: writing to parent pipe failed: errno "
++				 "%d (%s)\n", errno, strerror(errno));
++		}
++		close(pipefds[1]);
++		pipefds[1] = -1;
++	}
++}
++
+diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c
+index da5fe21..00667e9 100644
+--- a/utils/exportfs/exportfs.c
++++ b/utils/exportfs/exportfs.c
+@@ -27,6 +27,10 @@
+ #include <netdb.h>
+ #include <errno.h>
+ #include <dirent.h>
++#include <limits.h>
++#include <time.h>
++
++#define INT_TO_LONG_THRESHOLD_SECS (INT_MAX - (60 * 60 * 24))
+ 
+ #include "sockaddr.h"
+ #include "misc.h"
+@@ -406,17 +410,33 @@ unexportfs(char *arg, int verbose)
+ 
+ static int can_test(void)
+ {
++	char buf[1024];
+ 	int fd;
+ 	int n;
+-	char *setup = "nfsd 0.0.0.0 2147483647 -test-client-\n";
++
+ 	fd = open("/proc/net/rpc/auth.unix.ip/channel", O_WRONLY);
+-	if ( fd < 0) return 0;
+-	n = write(fd, setup, strlen(setup));
++	if (fd < 0)
++		return 0;
++
++	/*
++	 * We introduce tolerance of 1 day to ensure that we use a
++	 * LONG_MAX for the expiry timestamp before it is actually
++	 * needed. To use LONG_MAX, the kernel code must have 
++	 * commit 2f74f972  (sunrpc: prepare NFS for 2038).
++	 */
++	if (time(NULL) > INT_TO_LONG_THRESHOLD_SECS)
++		sprintf(buf, "nfsd 0.0.0.0 %ld -test-client-\n", LONG_MAX);
++	else
++		sprintf(buf, "nfsd 0.0.0.0 %d -test-client-\n", INT_MAX);
++
++	n = write(fd, buf, strlen(buf));
+ 	close(fd);
+ 	if (n < 0)
+ 		return 0;
++
+ 	fd = open("/proc/net/rpc/nfsd.export/channel", O_WRONLY);
+-	if ( fd < 0) return 0;
++	if (fd < 0)
++		return 0;
+ 	close(fd);
+ 	return 1;
+ }
+diff --git a/utils/gssd/gssd.c b/utils/gssd/gssd.c
+index 8ee478b..fdad153 100644
+--- a/utils/gssd/gssd.c
++++ b/utils/gssd/gssd.c
+@@ -54,6 +54,7 @@
+ #include "err_util.h"
+ #include "gss_util.h"
+ #include "krb5_util.h"
++#include "nfslib.h"
+ 
+ char pipefs_dir[PATH_MAX] = GSSD_PIPEFS_DIR;
+ char keytabfile[PATH_MAX] = GSSD_DEFAULT_KEYTAB_FILE;
+@@ -63,6 +64,7 @@ int  use_memcache = 0;
+ int  root_uses_machine_creds = 1;
+ unsigned int  context_timeout = 0;
+ char *preferred_realm = NULL;
++int pipefds[2] = { -1, -1 };
+ 
+ void
+ sig_die(int signal)
+@@ -187,8 +189,8 @@ main(int argc, char *argv[])
+ 	if (gssd_check_mechs() != 0)
+ 		errx(1, "Problem with gssapi library");
+ 
+-	if (!fg && daemon(0, 0) < 0)
+-		errx(1, "fork");
++	if (!fg)
++		mydaemon(0, 0, pipefds);
+ 
+ 	signal(SIGINT, sig_die);
+ 	signal(SIGTERM, sig_die);
+diff --git a/utils/gssd/gssd.h b/utils/gssd/gssd.h
+index 86472a1..56a18d6 100644
+--- a/utils/gssd/gssd.h
++++ b/utils/gssd/gssd.h
+@@ -67,12 +67,14 @@ extern int			use_memcache;
+ extern int			root_uses_machine_creds;
+ extern unsigned int 		context_timeout;
+ extern char			*preferred_realm;
++extern int			pipefds[2];
+ 
+ TAILQ_HEAD(clnt_list_head, clnt_info) clnt_list;
+ 
+ struct clnt_info {
+ 	TAILQ_ENTRY(clnt_info)	list;
+ 	char			*dirname;
++	char			*pdir;
+ 	int			dir_fd;
+ 	char			*servicename;
+ 	char			*servername;
+diff --git a/utils/gssd/gssd_main_loop.c b/utils/gssd/gssd_main_loop.c
+index ccf7fe5..9970028 100644
+--- a/utils/gssd/gssd_main_loop.c
++++ b/utils/gssd/gssd_main_loop.c
+@@ -53,6 +53,7 @@
+ 
+ #include "gssd.h"
+ #include "err_util.h"
++#include "nfslib.h"
+ 
+ extern struct pollfd *pollarray;
+ extern unsigned long pollsize;
+@@ -245,6 +246,9 @@ gssd_run()
+ 				/* Error msg is already printed */
+ 				exit(1);
+ 			}
++
++			/* release the parent after the initial dir scan */
++			release_parent(pipefds);
+ 		}
+ 		gssd_poll(pollarray, pollsize);
+ 	}
+diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c
+index b48d163..2a6ea97 100644
+--- a/utils/gssd/gssd_proc.c
++++ b/utils/gssd/gssd_proc.c
+@@ -256,6 +256,7 @@ read_service_info(char *info_file_name, char **servicename, char **servername,
+ 	if ((nbytes = read(fd, buf, INFOBUFLEN)) == -1)
+ 		goto fail;
+ 	close(fd);
++	fd = -1;
+ 	buf[nbytes] = '\0';
+ 
+ 	numfields = sscanf(buf,"RPC server: %127s\n"
+@@ -322,6 +323,7 @@ destroy_client(struct clnt_info *clp)
+ 	if (clp->krb5_fd != -1) close(clp->krb5_fd);
+ 	if (clp->gssd_fd != -1) close(clp->gssd_fd);
+ 	free(clp->dirname);
++	free(clp->pdir);
+ 	free(clp->servicename);
+ 	free(clp->servername);
+ 	free(clp->protocol);
+@@ -403,11 +405,10 @@ process_clnt_dir_files(struct clnt_info * clp)
+ 		return -1;
+ 	snprintf(info_file_name, sizeof(info_file_name), "%s/info",
+ 			clp->dirname);
+-	if ((clp->servicename == NULL) &&
+-	     read_service_info(info_file_name, &clp->servicename,
+-				&clp->servername, &clp->prog, &clp->vers,
+-				&clp->protocol, (struct sockaddr *) &clp->addr))
+-		return -1;
++	if (clp->prog == 0)
++		read_service_info(info_file_name, &clp->servicename,
++				  &clp->servername, &clp->prog, &clp->vers,
++				  &clp->protocol, (struct sockaddr *) &clp->addr);
+ 	return 0;
+ }
+ 
+@@ -463,6 +464,9 @@ process_clnt_dir(char *dir, char *pdir)
+ 	if (!(clp = insert_new_clnt()))
+ 		goto fail_destroy_client;
+ 
++	if (!(clp->pdir = strdup(pdir)))
++		goto fail_destroy_client;
++
+ 	/* An extra for the '/', and an extra for the null */
+ 	if (!(clp->dirname = calloc(strlen(dir) + strlen(pdir) + 2, 1))) {
+ 		goto fail_destroy_client;
+@@ -527,7 +531,7 @@ update_old_clients(struct dirent **namelist, int size, char *pdir)
+ 		/* only compare entries in the global list that are from the
+ 		 * same pipefs parent directory as "pdir"
+ 		 */
+-		if (strcmp(clp->dirname, pdir) != 0) continue;
++		if (strcmp(clp->pdir, pdir) != 0) continue;
+ 
+ 		stillhere = 0;
+ 		for (i=0; i < size; i++) {
+@@ -1040,7 +1044,10 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname,
+ 		return;
+ 	default:
+ 		/* Parent: just wait on child to exit and return */
+-		wait(&err);
++		do {
++			pid = wait(&err);
++		} while(pid == -1 && errno != -ECHILD);
++
+ 		if (WIFSIGNALED(err))
+ 			printerr(0, "WARNING: forked child was killed with signal %d\n",
+ 					WTERMSIG(err));
+@@ -1320,11 +1327,14 @@ handle_gssd_upcall(struct clnt_info *clp)
+ 		}
+ 	}
+ 
+-	if (strcmp(mech, "krb5") == 0)
++	if (strcmp(mech, "krb5") == 0 && clp->servername)
+ 		process_krb5_upcall(clp, uid, clp->gssd_fd, target, service);
+-	else
+-		printerr(0, "WARNING: handle_gssd_upcall: "
+-			    "received unknown gss mech '%s'\n", mech);
++	else {
++		if (clp->servername)
++			printerr(0, "WARNING: handle_gssd_upcall: "
++				 "received unknown gss mech '%s'\n", mech);
++		do_error_downcall(clp->gssd_fd, uid, -EACCES);
++	}
+ 
+ out:
+ 	free(lbuf);
+diff --git a/utils/gssd/svcgssd.c b/utils/gssd/svcgssd.c
+index 8aee3b2..0385725 100644
+--- a/utils/gssd/svcgssd.c
++++ b/utils/gssd/svcgssd.c
+@@ -62,91 +62,7 @@
+ #include "gss_util.h"
+ #include "err_util.h"
+ 
+-/*
+- * mydaemon creates a pipe between the partent and child
+- * process. The parent process will wait until the
+- * child dies or writes a '1' on the pipe signaling
+- * that it started successfully.
+- */
+-int pipefds[2] = { -1, -1};
+-
+-static void
+-mydaemon(int nochdir, int noclose)
+-{
+-	int pid, status, tempfd;
+-
+-	if (pipe(pipefds) < 0) {
+-		printerr(1, "mydaemon: pipe() failed: errno %d (%s)\n",
+-			errno, strerror(errno));
+-		exit(1);
+-	}
+-	if ((pid = fork ()) < 0) {
+-		printerr(1, "mydaemon: fork() failed: errno %d (%s)\n",
+-			errno, strerror(errno));
+-		exit(1);
+-	}
+-
+-	if (pid != 0) {
+-		/*
+-		 * Parent. Wait for status from child.
+-		 */
+-		close(pipefds[1]);
+-		if (read(pipefds[0], &status, 1) != 1)
+-			exit(1);
+-		exit (0);
+-	}
+-	/* Child.	*/
+-	close(pipefds[0]);
+-	setsid ();
+-	if (nochdir == 0) {
+-		if (chdir ("/") == -1) {
+-			printerr(1, "mydaemon: chdir() failed: errno %d (%s)\n",
+-				errno, strerror(errno));
+-			exit(1);
+-		}
+-	}
+-
+-	while (pipefds[1] <= 2) {
+-		pipefds[1] = dup(pipefds[1]);
+-		if (pipefds[1] < 0) {
+-			printerr(1, "mydaemon: dup() failed: errno %d (%s)\n",
+-				errno, strerror(errno));
+-			exit(1);
+-		}
+-	}
+-
+-	if (noclose == 0) {
+-		tempfd = open("/dev/null", O_RDWR);
+-		if (tempfd >= 0) {
+-			dup2(tempfd, 0);
+-			dup2(tempfd, 1);
+-			dup2(tempfd, 2);
+-			close(tempfd);
+-		} else {
+-			printerr(1, "mydaemon: can't open /dev/null: errno %d "
+-				    "(%s)\n", errno, strerror(errno));
+-			exit(1);
+-		}
+-	}
+-
+-	return;
+-}
+-
+-static void
+-release_parent(void)
+-{
+-	int status;
+-
+-	if (pipefds[1] > 0) {
+-		if (write(pipefds[1], &status, 1) != 1) {
+-			printerr(1, 
+-				"WARN: writing to parent pipe failed: errno %d (%s)\n",
+-				errno, strerror(errno));
+-		}
+-		close(pipefds[1]);
+-		pipefds[1] = -1;
+-	}
+-}
++static int pipefds[2] = { -1, -1 };
+ 
+ void
+ sig_die(int signal)
+@@ -242,7 +158,7 @@ main(int argc, char *argv[])
+ 	}
+ 
+ 	if (!fg)
+-		mydaemon(0, 0);
++		mydaemon(0, 0, pipefds);
+ 
+ 	signal(SIGINT, sig_die);
+ 	signal(SIGTERM, sig_die);
+@@ -272,7 +188,7 @@ main(int argc, char *argv[])
+ 	}
+ 
+ 	if (!fg)
+-		release_parent();
++		release_parent(pipefds);
+ 
+ 	nfs4_init_name_mapping(NULL); /* XXX: should only do this once */
+ 	gssd_run();
+diff --git a/utils/idmapd/idmapd.c b/utils/idmapd/idmapd.c
+index b6c6231..c02849b 100644
+--- a/utils/idmapd/idmapd.c
++++ b/utils/idmapd/idmapd.c
+@@ -157,9 +157,6 @@ static int nfsdopenone(struct idmap_client *);
+ static void nfsdreopen_one(struct idmap_client *);
+ static void nfsdreopen(void);
+ 
+-void    mydaemon(int, int);
+-void    release_parent(void);
+-
+ static int verbose = 0;
+ #define DEFAULT_IDMAP_CACHE_EXPIRY 600 /* seconds */
+ static int cache_entry_expiration = 0;
+@@ -167,6 +164,7 @@ static char pipefsdir[PATH_MAX];
+ static char *nobodyuser, *nobodygroup;
+ static uid_t nobodyuid;
+ static gid_t nobodygid;
++static int pipefds[2] = { -1, -1 };
+ 
+ /* Used by conffile.c in libnfs.a */
+ char *conf_path;
+@@ -305,7 +303,7 @@ main(int argc, char **argv)
+ 		errx(1, "Unable to create name to user id mappings.");
+ 
+ 	if (!fg)
+-		mydaemon(0, 0);
++		mydaemon(0, 0, pipefds);
+ 
+ 	event_init();
+ 
+@@ -382,7 +380,7 @@ main(int argc, char **argv)
+ 	if (nfsdret != 0 && fd == 0)
+ 		xlog_err("main: Neither NFS client nor NFSd found");
+ 
+-	release_parent();
++	release_parent(pipefds);
+ 
+ 	if (event_dispatch() < 0)
+ 		xlog_err("main: event_dispatch returns errno %d (%s)",
+@@ -929,77 +927,3 @@ getfield(char **bpp, char *fld, size_t fldsz)
+ 
+ 	return (0);
+ }
+-/*
+- * mydaemon creates a pipe between the partent and child
+- * process. The parent process will wait until the
+- * child dies or writes a '1' on the pipe signaling
+- * that it started successfully.
+- */
+-int pipefds[2] = { -1, -1};
+-
+-void
+-mydaemon(int nochdir, int noclose)
+-{
+-	int pid, status, tempfd;
+-
+-	if (pipe(pipefds) < 0)
+-		err(1, "mydaemon: pipe() failed: errno %d", errno);
+-
+-	if ((pid = fork ()) < 0)
+-		err(1, "mydaemon: fork() failed: errno %d", errno);
+-
+-	if (pid != 0) {
+-		/*
+-		 * Parent. Wait for status from child.
+-		 */
+-		close(pipefds[1]);
+-		if (read(pipefds[0], &status, 1) != 1)
+-			exit(1);
+-		exit (0);
+-	}
+-	/* Child.	*/
+-	close(pipefds[0]);
+-	setsid ();
+-	if (nochdir == 0) {
+-		if (chdir ("/") == -1)
+-			err(1, "mydaemon: chdir() failed: errno %d", errno);
+-	}
+-
+-	while (pipefds[1] <= 2) {
+-		pipefds[1] = dup(pipefds[1]);
+-		if (pipefds[1] < 0)
+-			err(1, "mydaemon: dup() failed: errno %d", errno);
+-	}
+-
+-	if (noclose == 0) {
+-		tempfd = open("/dev/null", O_RDWR);
+-		if (tempfd < 0)
+-			tempfd = open("/", O_RDONLY);
+-		if (tempfd >= 0) {
+-			dup2(tempfd, 0);
+-			dup2(tempfd, 1);
+-			dup2(tempfd, 2);
+-			close(tempfd);
+-		} else {
+-			err(1, "mydaemon: can't open /dev/null: errno %d",
+-			       errno);
+-			exit(1);
+-		}
+-	}
+-
+-	return;
+-}
+-void
+-release_parent(void)
+-{
+-	int status;
+-
+-	if (pipefds[1] > 0) {
+-		if (write(pipefds[1], &status, 1) != 1) {
+-			err(1, "Writing to parent pipe failed: errno %d (%s)\n",
+-				errno, strerror(errno));
+-		}
+-		close(pipefds[1]);
+-		pipefds[1] = -1;
+-	}
+-}
+diff --git a/utils/mount/network.c b/utils/mount/network.c
+index e8e55a5..2853d00 100644
+--- a/utils/mount/network.c
++++ b/utils/mount/network.c
+@@ -92,6 +92,9 @@ static const char *nfs_version_opttbl[] = {
+ 	"v4",
+ 	"vers",
+ 	"nfsvers",
++	"v4.0",
++	"v4.1",
++	"v4.2",
+ 	NULL,
+ };
+ 
+@@ -1269,6 +1272,11 @@ nfs_nfs_version(struct mount_options *options, unsigned long *version)
+ 					progname);
+ 			return 0;
+ 		}
++	case 5: /* v4.0 */
++	case 6: /* v4.1 */
++	case 7: /* v4.2 */
++		*version = 4;
++		return 1;
+ 	}
+ 
+ 	/*
+diff --git a/utils/mount/nfs.man b/utils/mount/nfs.man
+index 67031b5..ecc5f64 100644
+--- a/utils/mount/nfs.man
++++ b/utils/mount/nfs.man
+@@ -856,6 +856,26 @@ In the presence of multiple client network interfaces,
+ special routing policies,
+ or atypical network topologies,
+ the exact address to use for callbacks may be nontrivial to determine.
++.TP 1.5i
++.BR migration " / " nomigration
++Selects whether the client uses an identification string that is compatible
++with NFSv4 Transparent State Migration (TSM).
++If the mounted server supports NFSv4 migration with TSM, specify the
++.B migration
++option.
++.IP
++Some server features misbehave in the face of a migration-compatible
++identification string.
++The
++.B nomigration
++option retains the use of a traditional client indentification string
++which is compatible with legacy NFS servers.
++This is also the behavior if neither option is specified.
++A client's open and lock state cannot be migrated transparently
++when it identifies itself via a traditional identification string.
++.IP
++This mount option has no effect with NFSv4 minor versions newer than zero,
++which always use TSM-compatible client identification strings.
+ .SH nfs4 FILE SYSTEM TYPE
+ The
+ .BR nfs4
+@@ -1227,6 +1247,65 @@ If absolute cache coherence among clients is required,
+ applications should use file locking. Alternatively, applications
+ can also open their files with the O_DIRECT flag
+ to disable data caching entirely.
++.SS "File timestamp maintainence"
++NFS servers are responsible for managing file and directory timestamps
++.RB ( atime ,
++.BR ctime ", and"
++.BR mtime ).
++When a file is accessed or updated on an NFS server,
++the file's timestamps are updated just like they would be on a filesystem
++local to an application.
++.P
++NFS clients cache file attributes, including timestamps.
++A file's timestamps are updated on NFS clients when its attributes
++are retrieved from the NFS server.
++Thus there may be some delay before timestamp updates
++on an NFS server appear to applications on NFS clients.
++.P
++To comply with the POSIX filesystem standard, the Linux NFS client
++relies on NFS servers to keep a file's
++.B mtime
++and
++.B ctime
++timestamps properly up to date.
++It does this by flushing local data changes to the server
++before reporting
++.B mtime
++to applications via system calls such as
++.BR stat (2).
++.P
++The Linux client handles
++.B atime
++updates more loosely, however.
++NFS clients maintain good performance by caching data,
++but that means that application reads, which normally update
++.BR atime ,
++are not reflected to the server where a file's
++.B atime
++is actually maintained.
++.P
++Because of this caching behavior,
++the Linux NFS client does not support generic atime-related mount options.
++See
++.BR mount (8)
++for details on these options.
++.P
++In particular, the
++.BR atime / noatime ,
++.BR diratime / nodiratime ,
++.BR relatime / norelatime ,
++and
++.BR strictatime / nostrictatime
++mount options have no effect on NFS mounts.
++.P
++.I /proc/mounts
++may report that the
++.B relatime
++mount option is set on NFS mounts, but in fact the
++.B atime
++semantics are always as described here, and are not like
++.B relatime
++semantics.
+ .SS "Directory entry caching"
+ The Linux NFS client caches the result of all NFS LOOKUP requests.
+ If the requested directory entry exists on the server,
diff --git a/nfs-utils.spec b/nfs-utils.spec
index 0ad6900..51fc852 100644
--- a/nfs-utils.spec
+++ b/nfs-utils.spec
@@ -2,7 +2,7 @@ Summary: NFS utilities and supporting clients and daemons for the kernel NFS ser
 Name: nfs-utils
 URL: http://sourceforge.net/projects/nfs
 Version: 1.2.9
-Release: 0.0%{?dist}
+Release: 1.0%{?dist}
 Epoch: 1
 
 # group all 32bit related archs
@@ -36,6 +36,8 @@ Source51: nfs-server.preconfig
 Source52: nfs-server.postconfig
 %define nfs_configs %{SOURCE50} %{SOURCE51} %{SOURCE52} 
 
+Patch001: nfs-utils-1.2.10-rc1.patch
+
 Patch100: nfs-utils-1.2.1-statdpath-man.patch
 Patch101: nfs-utils-1.2.1-exp-subtree-warn-off.patch
 Patch102: nfs-utils-1.2.3-sm-notify-res_init.patch
@@ -92,6 +94,8 @@ This package also contains the mount.nfs and umount.nfs program.
 %prep
 %setup -q
 
+%patch001 -p1
+
 %patch100 -p1
 %patch101 -p1
 %patch102 -p1
@@ -307,6 +311,9 @@ fi
 /sbin/umount.nfs4
 
 %changelog
+* Wed Nov 20 2013 Steve Dickson <steved at redhat.com> 1.2.9-1.0
+- Updated to latest upstream RC release: nfs-utils-1-2-10-rc1
+
 * Tue Nov  5 2013 Steve Dickson <steved at redhat.com> 1.2.9-0.0
 - Updated to latest upstream Release: nfs-utils-1-2-9
 


More information about the scm-commits mailing list