Removed nfs-utils-1.2.10-rc1.patch
Signed-off-by: Steve Dickson <steved@redhat.com>
This commit is contained in:
parent
99f53899a6
commit
d96c524fb3
@ -1,749 +0,0 @@
|
||||
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@UMICH.EDU>.
|
||||
+ Copyright (c) 2002 Andy Adamson <andros@UMICH.EDU>.
|
||||
+ Copyright (c) 2002 Marius Aamodt Eriksen <marius@UMICH.EDU>.
|
||||
+ Copyright (c) 2002 J. Bruce Fields <bfields@UMICH.EDU>.
|
||||
+ Copyright (c) 2013 Jeff Layton <jlayton@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,
|
Loading…
Reference in New Issue
Block a user