f1e9bac0ff
Also fixed a regression in the junction code (bz 2213669) Signed-off-by: Steve Dickson <steved@redhat.com>
511 lines
16 KiB
Diff
511 lines
16 KiB
Diff
diff --git a/configure.ac b/configure.ac
|
|
index 4ade528d..6fbcb974 100644
|
|
--- a/configure.ac
|
|
+++ b/configure.ac
|
|
@@ -335,42 +335,37 @@ AC_CHECK_HEADER(rpc/rpc.h, ,
|
|
AC_MSG_ERROR([Header file rpc/rpc.h not found - maybe try building with --enable-tirpc]))
|
|
CPPFLAGS="${nfsutils_save_CPPFLAGS}"
|
|
|
|
+AC_CHECK_HEADER(uuid/uuid.h, ,
|
|
+ AC_MSG_ERROR([Cannot find needed header file uuid/uuid.h. Install libuuid-devel]))
|
|
+
|
|
+dnl check for libevent libraries and headers
|
|
+AC_LIBEVENT
|
|
+
|
|
+dnl Check for sqlite3
|
|
+AC_SQLITE3_VERS
|
|
+
|
|
+case $libsqlite3_cv_is_recent in
|
|
+yes) ;;
|
|
+unknown)
|
|
+ dnl do not fail when cross-compiling
|
|
+ AC_MSG_WARN([assuming sqlite is at least v3.3]) ;;
|
|
+*)
|
|
+ AC_MSG_ERROR([nfsdcld requires sqlite-devel]) ;;
|
|
+esac
|
|
+
|
|
if test "$enable_nfsv4" = yes; then
|
|
- dnl check for libevent libraries and headers
|
|
- AC_LIBEVENT
|
|
|
|
dnl check for the keyutils libraries and headers
|
|
AC_KEYUTILS
|
|
|
|
- dnl Check for sqlite3
|
|
- AC_SQLITE3_VERS
|
|
-
|
|
if test "$enable_nfsdcld" = "yes"; then
|
|
AC_CHECK_HEADERS([libgen.h sys/inotify.h], ,
|
|
AC_MSG_ERROR([Cannot find header needed for nfsdcld]))
|
|
-
|
|
- case $libsqlite3_cv_is_recent in
|
|
- yes) ;;
|
|
- unknown)
|
|
- dnl do not fail when cross-compiling
|
|
- AC_MSG_WARN([assuming sqlite is at least v3.3]) ;;
|
|
- *)
|
|
- AC_MSG_ERROR([nfsdcld requires sqlite-devel]) ;;
|
|
- esac
|
|
fi
|
|
|
|
if test "$enable_nfsdcltrack" = "yes"; then
|
|
AC_CHECK_HEADERS([libgen.h sys/inotify.h], ,
|
|
AC_MSG_ERROR([Cannot find header needed for nfsdcltrack]))
|
|
-
|
|
- case $libsqlite3_cv_is_recent in
|
|
- yes) ;;
|
|
- unknown)
|
|
- dnl do not fail when cross-compiling
|
|
- AC_MSG_WARN([assuming sqlite is at least v3.3]) ;;
|
|
- *)
|
|
- AC_MSG_ERROR([nfsdcltrack requires sqlite-devel]) ;;
|
|
- esac
|
|
fi
|
|
|
|
else
|
|
diff --git a/support/include/version.h b/support/include/version.h
|
|
deleted file mode 120000
|
|
index b7db0bbb..00000000
|
|
--- a/support/include/version.h
|
|
+++ /dev/null
|
|
@@ -1 +0,0 @@
|
|
-../../utils/mount/version.h
|
|
\ No newline at end of file
|
|
diff --git a/support/include/version.h b/support/include/version.h
|
|
new file mode 100644
|
|
index 00000000..d7cf6802
|
|
--- /dev/null
|
|
+++ b/support/include/version.h
|
|
@@ -0,0 +1,53 @@
|
|
+/*
|
|
+ * version.h -- get running kernel version
|
|
+ *
|
|
+ * Copyright (C) 2008 Oracle. All rights reserved.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or
|
|
+ * modify it under the terms of the GNU General Public
|
|
+ * License as published by the Free Software Foundation; either
|
|
+ * version 2 of the License, or (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ * General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public
|
|
+ * License along with this program; if not, write to the
|
|
+ * Free Software Foundation, Inc.,
|
|
+ * 51 Franklin Street, Fifth Floor, Boston, MA 0211-1301 USA
|
|
+ *
|
|
+ */
|
|
+
|
|
+#ifndef _NFS_UTILS_MOUNT_VERSION_H
|
|
+#define _NFS_UTILS_MOUNT_VERSION_H
|
|
+
|
|
+#include <stdio.h>
|
|
+#include <limits.h>
|
|
+
|
|
+#include <sys/utsname.h>
|
|
+
|
|
+static inline unsigned int MAKE_VERSION(unsigned int p, unsigned int q,
|
|
+ unsigned int r)
|
|
+{
|
|
+ return (65536 * p) + (256 * q) + r;
|
|
+}
|
|
+
|
|
+static inline unsigned int linux_version_code(void)
|
|
+{
|
|
+ struct utsname my_utsname;
|
|
+ unsigned int p, q = 0, r = 0;
|
|
+
|
|
+ /* UINT_MAX as backward compatibility code should not be run */
|
|
+ if (uname(&my_utsname))
|
|
+ return UINT_MAX;
|
|
+
|
|
+ /* UINT_MAX as future versions might not start with an integer */
|
|
+ if (sscanf(my_utsname.release, "%u.%u.%u", &p, &q, &r) < 1)
|
|
+ return UINT_MAX;
|
|
+
|
|
+ return MAKE_VERSION(p, q, r);
|
|
+}
|
|
+
|
|
+#endif /* _NFS_UTILS_MOUNT_VERSION_H */
|
|
diff --git a/support/nfsidmap/libnfsidmap.c b/support/nfsidmap/libnfsidmap.c
|
|
index 0a912e52..f8c36480 100644
|
|
--- a/support/nfsidmap/libnfsidmap.c
|
|
+++ b/support/nfsidmap/libnfsidmap.c
|
|
@@ -219,10 +219,15 @@ static int domain_from_dns(char **domain)
|
|
|
|
if (gethostname(hname, sizeof(hname)) == -1)
|
|
return -1;
|
|
- if ((he = gethostbyname(hname)) == NULL)
|
|
- return -1;
|
|
- if ((c = strchr(he->h_name, '.')) == NULL || *++c == '\0')
|
|
- return -1;
|
|
+ if ((he = gethostbyname(hname)) == NULL) {
|
|
+ IDMAP_LOG(1, ("libnfsidmap: DNS lookup of hostname failed. Attempting to use domain from hostname as is."));
|
|
+ if ((c = strchr(hname, '.')) == NULL || *++c == '\0')
|
|
+ return -1;
|
|
+ }
|
|
+ else {
|
|
+ if ((c = strchr(he->h_name, '.')) == NULL || *++c == '\0')
|
|
+ return -1;
|
|
+ }
|
|
/*
|
|
* Query DNS to see if the _nfsv4idmapdomain TXT record exists
|
|
* If so use it...
|
|
@@ -387,7 +392,7 @@ int nfs4_init_name_mapping(char *conffile)
|
|
dflt = 1;
|
|
ret = domain_from_dns(&default_domain);
|
|
if (ret) {
|
|
- IDMAP_LOG(1, ("libnfsidmap: Unable to determine "
|
|
+ IDMAP_LOG(0, ("libnfsidmap: Unable to determine "
|
|
"the NFSv4 domain; Using '%s' as the NFSv4 domain "
|
|
"which means UIDs will be mapped to the 'Nobody-User' "
|
|
"user defined in %s",
|
|
diff --git a/support/reexport/fsidd.c b/support/reexport/fsidd.c
|
|
index 410b3a37..d4b245e8 100644
|
|
--- a/support/reexport/fsidd.c
|
|
+++ b/support/reexport/fsidd.c
|
|
@@ -3,7 +3,9 @@
|
|
#endif
|
|
|
|
#include <assert.h>
|
|
+#ifdef HAVE_DLFCN_H
|
|
#include <dlfcn.h>
|
|
+#endif
|
|
#include <event2/event.h>
|
|
#include <limits.h>
|
|
#include <stdint.h>
|
|
@@ -18,14 +20,18 @@
|
|
|
|
#include "conffile.h"
|
|
#include "reexport_backend.h"
|
|
+#include "reexport.h"
|
|
#include "xcommon.h"
|
|
#include "xlog.h"
|
|
|
|
-#define FSID_SOCKET_NAME "fsid.sock"
|
|
-
|
|
static struct event_base *evbase;
|
|
static struct reexpdb_backend_plugin *dbbackend = &sqlite_plug_ops;
|
|
|
|
+/* assert_safe() always evalutes it argument, as it might have
|
|
+ * a side-effect. assert() won't if compiled with NDEBUG
|
|
+ */
|
|
+#define assert_safe(__sideeffect) (__sideeffect ? 0 : ({assert(0) ; 0;}))
|
|
+
|
|
static void client_cb(evutil_socket_t cl, short ev, void *d)
|
|
{
|
|
struct event *me = d;
|
|
@@ -56,12 +62,11 @@ static void client_cb(evutil_socket_t cl, short ev, void *d)
|
|
|
|
if (dbbackend->fsidnum_by_path(req_path, &fsidnum, false, &found)) {
|
|
if (found)
|
|
- assert(asprintf(&answer, "+ %u", fsidnum) != -1);
|
|
+ assert_safe(asprintf(&answer, "+ %u", fsidnum) != -1);
|
|
else
|
|
- assert(asprintf(&answer, "+ ") != -1);
|
|
-
|
|
+ assert_safe(asprintf(&answer, "+ ") != -1);
|
|
} else {
|
|
- assert(asprintf(&answer, "- %s", "Command failed") != -1);
|
|
+ assert_safe(asprintf(&answer, "- %s", "Command failed") != -1);
|
|
}
|
|
|
|
(void)send(cl, answer, strlen(answer), 0);
|
|
@@ -78,13 +83,13 @@ static void client_cb(evutil_socket_t cl, short ev, void *d)
|
|
|
|
if (dbbackend->fsidnum_by_path(req_path, &fsidnum, true, &found)) {
|
|
if (found) {
|
|
- assert(asprintf(&answer, "+ %u", fsidnum) != -1);
|
|
+ assert_safe(asprintf(&answer, "+ %u", fsidnum) != -1);
|
|
} else {
|
|
- assert(asprintf(&answer, "+ ") != -1);
|
|
+ assert_safe(asprintf(&answer, "+ ") != -1);
|
|
}
|
|
|
|
} else {
|
|
- assert(asprintf(&answer, "- %s", "Command failed") != -1);
|
|
+ assert_safe(asprintf(&answer, "- %s", "Command failed") != -1);
|
|
}
|
|
|
|
(void)send(cl, answer, strlen(answer), 0);
|
|
@@ -106,15 +111,15 @@ static void client_cb(evutil_socket_t cl, short ev, void *d)
|
|
}
|
|
|
|
if (bad_input) {
|
|
- assert(asprintf(&answer, "- %s", "Command failed: Bad input") != -1);
|
|
+ assert_safe(asprintf(&answer, "- %s", "Command failed: Bad input") != -1);
|
|
} else {
|
|
if (dbbackend->path_by_fsidnum(fsidnum, &path, &found)) {
|
|
if (found)
|
|
- assert(asprintf(&answer, "+ %s", path) != -1);
|
|
+ assert_safe(asprintf(&answer, "+ %s", path) != -1);
|
|
else
|
|
- assert(asprintf(&answer, "+ ") != -1);
|
|
+ assert_safe(asprintf(&answer, "+ ") != -1);
|
|
} else {
|
|
- assert(asprintf(&answer, "+ ") != -1);
|
|
+ assert_safe(asprintf(&answer, "+ ") != -1);
|
|
}
|
|
}
|
|
|
|
@@ -129,7 +134,7 @@ static void client_cb(evutil_socket_t cl, short ev, void *d)
|
|
} else {
|
|
char *answer = NULL;
|
|
|
|
- assert(asprintf(&answer, "- bad command") != -1);
|
|
+ assert_safe(asprintf(&answer, "- bad command") != -1);
|
|
(void)send(cl, answer, strlen(answer), 0);
|
|
|
|
free(answer);
|
|
@@ -163,11 +168,14 @@ int main(void)
|
|
|
|
sock_file = conf_get_str_with_def("reexport", "fsidd_socket", FSID_SOCKET_NAME);
|
|
|
|
- unlink(sock_file);
|
|
-
|
|
memset(&addr, 0, sizeof(struct sockaddr_un));
|
|
addr.sun_family = AF_UNIX;
|
|
strncpy(addr.sun_path, sock_file, sizeof(addr.sun_path) - 1);
|
|
+ if (addr.sun_path[0] == '@')
|
|
+ /* "abstract" socket namespace */
|
|
+ addr.sun_path[0] = 0;
|
|
+ else
|
|
+ unlink(sock_file);
|
|
|
|
srv = socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK, 0);
|
|
if (srv == -1) {
|
|
diff --git a/support/reexport/reexport.c b/support/reexport/reexport.c
|
|
index eddc9bf4..d9a700af 100644
|
|
--- a/support/reexport/reexport.c
|
|
+++ b/support/reexport/reexport.c
|
|
@@ -2,7 +2,9 @@
|
|
#include <config.h>
|
|
#endif
|
|
|
|
+#ifdef HAVE_DLFCN_H
|
|
#include <dlfcn.h>
|
|
+#endif
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <sys/random.h>
|
|
@@ -38,6 +40,9 @@ static bool connect_fsid_service(void)
|
|
memset(&addr, 0, sizeof(struct sockaddr_un));
|
|
addr.sun_family = AF_UNIX;
|
|
strncpy(addr.sun_path, sock_file, sizeof(addr.sun_path) - 1);
|
|
+ if (addr.sun_path[0] == '@')
|
|
+ /* "abstract" socket namespace */
|
|
+ addr.sun_path[0] = 0;
|
|
|
|
s = socket(AF_UNIX, SOCK_SEQPACKET, 0);
|
|
if (s == -1) {
|
|
diff --git a/support/reexport/reexport.h b/support/reexport/reexport.h
|
|
index 3bed03a9..85fd59c1 100644
|
|
--- a/support/reexport/reexport.h
|
|
+++ b/support/reexport/reexport.h
|
|
@@ -1,6 +1,8 @@
|
|
#ifndef REEXPORT_H
|
|
#define REEXPORT_H
|
|
|
|
+#include "nfslib.h"
|
|
+
|
|
enum {
|
|
REEXP_NONE = 0,
|
|
REEXP_AUTO_FSIDNUM,
|
|
@@ -13,6 +15,6 @@ int reexpdb_fsidnum_by_path(char *path, uint32_t *fsidnum, int may_create);
|
|
int reexpdb_apply_reexport_settings(struct exportent *ep, char *flname, int flline);
|
|
void reexpdb_uncover_subvolume(uint32_t fsidnum);
|
|
|
|
-#define FSID_SOCKET_NAME "fsid.sock"
|
|
+#define FSID_SOCKET_NAME "@/run/fsid.sock"
|
|
|
|
#endif /* REEXPORT_H */
|
|
diff --git a/systemd/nfs-idmapd.service b/systemd/nfs-idmapd.service
|
|
index f38fe527..198ca87c 100644
|
|
--- a/systemd/nfs-idmapd.service
|
|
+++ b/systemd/nfs-idmapd.service
|
|
@@ -2,7 +2,8 @@
|
|
Description=NFSv4 ID-name mapping service
|
|
DefaultDependencies=no
|
|
Requires=rpc_pipefs.target
|
|
-After=rpc_pipefs.target local-fs.target
|
|
+After=rpc_pipefs.target local-fs.target network-online.target
|
|
+Wants=network-online.target
|
|
|
|
BindsTo=nfs-server.service
|
|
|
|
diff --git a/systemd/nfs.conf.man b/systemd/nfs.conf.man
|
|
index bfd3380f..866939aa 100644
|
|
--- a/systemd/nfs.conf.man
|
|
+++ b/systemd/nfs.conf.man
|
|
@@ -137,8 +137,9 @@ but on the server, this will resolve to the path
|
|
.TP
|
|
.B exportd
|
|
Recognized values:
|
|
+.BR manage-gids ,
|
|
.BR threads ,
|
|
-.BR cache-use-upaddr ,
|
|
+.BR cache-use-ipaddr ,
|
|
.BR ttl ,
|
|
.BR state-directory-path
|
|
|
|
@@ -204,7 +205,7 @@ Recognized values:
|
|
.BR port ,
|
|
.BR threads ,
|
|
.BR reverse-lookup ,
|
|
-.BR cache-use-upaddr ,
|
|
+.BR cache-use-ipaddr ,
|
|
.BR ttl ,
|
|
.BR state-directory-path ,
|
|
.BR ha-callout .
|
|
diff --git a/utils/mount/nfs.man b/utils/mount/nfs.man
|
|
index 7a410422..0b976731 100644
|
|
--- a/utils/mount/nfs.man
|
|
+++ b/utils/mount/nfs.man
|
|
@@ -94,31 +94,38 @@ This option is an alternative to the
|
|
option.
|
|
It is included for compatibility with other operating systems
|
|
.TP 1.5i
|
|
-.BR soft " / " hard
|
|
+.BR soft " / " softerr " / " hard
|
|
Determines the recovery behavior of the NFS client
|
|
after an NFS request times out.
|
|
-If neither option is specified (or if the
|
|
+If no option is specified (or if the
|
|
.B hard
|
|
option is specified), NFS requests are retried indefinitely.
|
|
-If the
|
|
-.B soft
|
|
+If either the
|
|
+.BR soft " or " softerr
|
|
option is specified, then the NFS client fails an NFS request
|
|
after
|
|
.B retrans
|
|
retransmissions have been sent,
|
|
-causing the NFS client to return an error
|
|
-to the calling application.
|
|
+causing the NFS client to return either the error
|
|
+.B EIO
|
|
+(for the
|
|
+.B soft
|
|
+option) or
|
|
+.B ETIMEDOUT
|
|
+(for the
|
|
+.B softerr
|
|
+option) to the calling application.
|
|
.IP
|
|
.I NB:
|
|
A so-called "soft" timeout can cause
|
|
silent data corruption in certain cases. As such, use the
|
|
-.B soft
|
|
+.BR soft " or " softerr
|
|
option only when client responsiveness
|
|
is more important than data integrity.
|
|
Using NFS over TCP or increasing the value of the
|
|
.B retrans
|
|
option may mitigate some of the risks of using the
|
|
-.B soft
|
|
+.BR soft " or " softerr
|
|
option.
|
|
.TP 1.5i
|
|
.BR softreval " / " nosoftreval
|
|
@@ -416,19 +423,6 @@ Note that the
|
|
option may also be used by some pNFS drivers to decide how many
|
|
connections to set up to the data servers.
|
|
.TP 1.5i
|
|
-.BR max_connect= n
|
|
-While
|
|
-.BR nconnect
|
|
-option sets a limit on the number of connections that can be established
|
|
-to a given server IP,
|
|
-.BR max_connect
|
|
-option allows the user to specify maximum number of connections to different
|
|
-server IPs that belong to the same NFSv4.1+ server (session trunkable
|
|
-connections) up to a limit of 16. When client discovers that it established
|
|
-a client ID to an already existing server, instead of dropping the newly
|
|
-created network transport, the client will add this new connection to the
|
|
-list of available transports for that RPC client.
|
|
-.TP 1.5i
|
|
.BR rdirplus " / " nordirplus
|
|
Selects whether to use NFS v3 or v4 READDIRPLUS requests.
|
|
If this option is not specified, the NFS client uses READDIRPLUS requests
|
|
@@ -607,6 +601,28 @@ option is not specified,
|
|
the default behavior depends on the kernel,
|
|
but is usually equivalent to
|
|
.BR "xprtsec=none" .
|
|
+.TP 1.5i
|
|
+.BI write= behavior
|
|
+Controls how the NFS client handles the
|
|
+.BR write (2)
|
|
+system call.
|
|
+.I behavior
|
|
+can be one of
|
|
+.BR lazy ,
|
|
+.BR eager ,
|
|
+or
|
|
+.BR wait .
|
|
+If
|
|
+.B lazy
|
|
+(the default) is specified, then the NFS client delays sending application
|
|
+writes to the NFS server as described in the DATA AND METADATA COHERENCE
|
|
+section. If
|
|
+.B eager
|
|
+is specified, then the NFS client sends off the write immediately as an
|
|
+unstable WRITE to the NFS server. If
|
|
+.B wait
|
|
+is specified, then the NFS client sends off the write immediately as an
|
|
+unstable WRITE to the NFS server and then waits for the reply.
|
|
.SS "Options for NFS versions 2 and 3 only"
|
|
Use these options, along with the options in the above subsection,
|
|
for NFS versions 2 and 3 only.
|
|
@@ -971,6 +987,32 @@ 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.
|
|
+.TP 1.5i
|
|
+.BR max_connect= n
|
|
+While
|
|
+.BR nconnect
|
|
+option sets a limit on the number of connections that can be established
|
|
+to a given server IP,
|
|
+.BR max_connect
|
|
+option allows the user to specify maximum number of connections to different
|
|
+server IPs that belong to the same NFSv4.1+ server (session trunkable
|
|
+connections) up to a limit of 16. When client discovers that it established
|
|
+a client ID to an already existing server, instead of dropping the newly
|
|
+created network transport, the client will add this new connection to the
|
|
+list of available transports for that RPC client.
|
|
+.TP 1.5i
|
|
+.BR trunkdiscovery " / " notrunkdiscovery
|
|
+When the client discovers a new filesystem on a NFSv4.1+ server, the
|
|
+.BR trunkdiscovery
|
|
+mount option will cause it to send a GETATTR for the fs_locations attribute.
|
|
+If is receives a non-zero length reply, it will iterate through the response,
|
|
+and for each server location it will establish a connection, send an
|
|
+EXCHANGE_ID, and test for session trunking. If the trunking test succeeds,
|
|
+the connection will be added to the existing set of transports for the server,
|
|
+subject to the limit specified by the
|
|
+.BR max_connect
|
|
+option. The default is
|
|
+.BR notrunkdiscovery .
|
|
.SH nfs4 FILE SYSTEM TYPE
|
|
The
|
|
.BR nfs4
|
|
diff --git a/utils/statd/start-statd b/utils/statd/start-statd
|
|
index 2baf73c3..b11a7d91 100755
|
|
--- a/utils/statd/start-statd
|
|
+++ b/utils/statd/start-statd
|
|
@@ -11,8 +11,8 @@ exec 9> /run/rpc.statd.lock
|
|
flock -e 9
|
|
|
|
if [ -s /run/rpc.statd.pid ] &&
|
|
- [ 1`cat /run/rpc.statd.pid` -gt 1 ] &&
|
|
- kill -0 `cat /run/rpc.statd.pid` > /dev/null 2>&1
|
|
+ [ "1$(cat /run/rpc.statd.pid)" -gt 1 ] &&
|
|
+ kill -0 "$(cat /run/rpc.statd.pid)" > /dev/null 2>&1
|
|
then
|
|
# statd already running - must have been slow to respond.
|
|
exit 0
|